Skip to content

feat(dx): implement contract ABI codegen pipeline — auto-generate TypeScript types and SDK client methods from Soroban contract metadata, eliminating manual type sync #577

Description

@devJaja

Background

LinkoraClient (packages/sdk/src/index.ts) is manually maintained in sync with the Rust contract ABI. This has already caused bugs (PR #520 fixed a desync where Profile had non-existent fields). The problem will worsen as the contract grows. The fix is to auto-generate TypeScript types and client methods from the contract's compiled WASM metadata.

What needs to be designed and built

Phase 1 — Codegen pipeline (packages/codegen/)

  1. Implement packages/codegen/generate.ts:
    • Runs stellar contract inspect --wasm <path.wasm> --output json to extract the ABI as JSON.
    • Parses the ABI to extract: all function signatures, all #[contracttype] structs/enums, all #[contractevent] types.
    • Generates:
      • packages/sdk/src/generated/types.ts — TypeScript interfaces for every contract type, using Soroban-to-TS type mappings (u32→number, i128→bigint, Address→string, BytesN<32>→Uint8Array, Option<T>→T|null).
      • packages/sdk/src/generated/client.ts — typed GeneratedLinkoraClient class with one method per contract function.
      • packages/sdk/src/generated/events.ts — typed event parser for every #[contractevent].
  2. Add pnpm codegen script: builds contract WASM, runs generate.ts, writes output files.
  3. Add CI step (codegen-check) that runs pnpm codegen and fails if generated files differ from what's committed (git diff --exit-code packages/sdk/src/generated/).

Phase 2 — Migration of existing SDK

  1. Replace all manually written types in packages/sdk/src/types.ts with imports from packages/sdk/src/generated/types.ts.
  2. Replace manually written client methods with a thin wrapper around GeneratedLinkoraClient that adds connection management, error handling, and the optimistic/queue layer.

Phase 3 — Shared types package

  1. Create packages/types/ — a zero-dependency package re-exporting from packages/sdk/src/generated/types.ts.
  2. Update apps/web and apps/mobile to import shared types from @linkora/types rather than duplicating type definitions.
  3. Update pnpm-workspace.yaml and turbo.json to include the new package.

Tests

  • Run pnpm codegen; verify generated files are valid TypeScript (tsc --noEmit).
  • Add a test calling every generated method and verifying the return type matches the contract ABI.
  • Verify CI codegen-check fails when a contract function is added but codegen is not re-run.

Acceptance Criteria

  • pnpm codegen generates valid TypeScript from compiled contract WASM
  • CI fails if generated files are out of sync with the contract
  • All manually written SDK types replaced with generated ones
  • packages/types/ shared package created and consumed by apps/web and apps/mobile
  • All existing SDK, web, and mobile tests pass with the new types

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official Campaigndeveloper experienceImproves contributor workflow or local setuphardsdk

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions