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/)
- 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].
- Add
pnpm codegen script: builds contract WASM, runs generate.ts, writes output files.
- 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
- Replace all manually written types in
packages/sdk/src/types.ts with imports from packages/sdk/src/generated/types.ts.
- 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
- Create
packages/types/ — a zero-dependency package re-exporting from packages/sdk/src/generated/types.ts.
- Update
apps/web and apps/mobile to import shared types from @linkora/types rather than duplicating type definitions.
- 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
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 whereProfilehad 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/)packages/codegen/generate.ts:stellar contract inspect --wasm <path.wasm> --output jsonto extract the ABI as JSON.#[contracttype]structs/enums, all#[contractevent]types.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— typedGeneratedLinkoraClientclass with one method per contract function.packages/sdk/src/generated/events.ts— typed event parser for every#[contractevent].pnpm codegenscript: builds contract WASM, runsgenerate.ts, writes output files.codegen-check) that runspnpm codegenand fails if generated files differ from what's committed (git diff --exit-code packages/sdk/src/generated/).Phase 2 — Migration of existing SDK
packages/sdk/src/types.tswith imports frompackages/sdk/src/generated/types.ts.GeneratedLinkoraClientthat adds connection management, error handling, and the optimistic/queue layer.Phase 3 — Shared types package
packages/types/— a zero-dependency package re-exporting frompackages/sdk/src/generated/types.ts.apps/webandapps/mobileto import shared types from@linkora/typesrather than duplicating type definitions.pnpm-workspace.yamlandturbo.jsonto include the new package.Tests
pnpm codegen; verify generated files are valid TypeScript (tsc --noEmit).codegen-checkfails when a contract function is added but codegen is not re-run.Acceptance Criteria
pnpm codegengenerates valid TypeScript from compiled contract WASMpackages/types/shared package created and consumed byapps/webandapps/mobile