feat: generate TypeScript contract bindings with CI sync check#530
Merged
sanmipaul merged 4 commits intoMay 30, 2026
Merged
Conversation
Add scripts/gen-bindings.sh, which builds each contract to WASM and runs `stellar contract bindings typescript` to produce TypeScript clients/types, writing them to frontend/src/generated/<contract>.ts. Commit the generated bindings for invoice and credit_score plus a namespaced barrel, and exclude the generated directory from ESLint/Prettier. pool is wired into the script by default but not generated yet: its PoolError enum exceeds Soroban's 50-case contract-spec limit, so the contract does not compile. Re-enable it once that build is fixed.
…ed bindings contracts.ts now imports the generated Errors maps and re-exports the generated contract clients and raw ABI types (Invoice/InvoiceStatus/InvoiceMetadata). Adds getContractErrorByCode(), which resolves a numeric contract error code to a friendly message using the generated bindings as the source of truth, so the error catalogue tracks the contract source automatically.
Add a generate-bindings job to the Soroban contracts workflow that installs a pinned stellar-cli (22.6.0), regenerates the TypeScript bindings via scripts/gen-bindings.sh, and runs `git diff --exit-code frontend/src/generated/` so CI fails if the committed bindings drift from the contract source. pool is omitted from the regeneration list until its build is fixed.
Add a 'Regenerating Contract Bindings' section covering when/how to regenerate, the pinned stellar-cli version, the CI sync check, and the pool build caveat.
|
@distributed-nerd Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #427
Summary
Adds automated TypeScript binding generation from the Soroban contract ABI so SDK authors and frontend developers no longer have to read the Rust source to understand the API, and so the bindings can't silently go stale.
Changes
scripts/gen-bindings.sh— builds each contract to WASM and runsstellar contract bindings typescript, writing the generated module tofrontend/src/generated/<contract>.ts. Defaults to all contracts; accepts a subset as args.frontend/src/generated/(invoice.ts,credit_score.ts) plus a namespacedindex.tsbarrel. Excluded from ESLint/Prettier so they stay byte-for-byte identical to the tool output.generate-bindingsjob in.github/workflows/contracts.ymlinstalls a pinnedstellar-cli(22.6.0), regenerates the bindings, and runsgit diff --exit-code frontend/src/generated/, failing CI if the committed bindings drift from the contract source.frontend/lib/contracts.ts— now imports the generatedErrorsmaps, re-exports the generated contract clients and raw ABI types (InvoiceAbi/InvoiceStatusAbi/InvoiceMetadataAbi), and addsgetContractErrorByCode()resolving numeric contract error codes to friendly messages using the generated bindings as the source of truth.CONTRIBUTING.md— new "Regenerating Contract Bindings" section documenting when/how to regenerate, the pinned CLI version, the CI sync check, and thepoolcaveat below.Acceptance criteria
stellar contract bindings typescriptstep added to CIfrontend/src/generated/git diff --exit-code)contracts.tsupdated to import from generated bindingsCONTRIBUTING.mddocuments how to regenerate bindings locallyNotes
stellarCLI (22.6.0) emits a package directory via--output-dirrather than the single--output …invoice.tsfile shown in the issue (that was the oldersorobanCLI). The script bridges this by copying the generatedsrc/index.tsinto the exactfrontend/src/generated/<contract>.tslayout the issue specifies.poolis intentionally excluded for now. The pool contract currently does not compile: itsPoolErrorenum has 52 variants, but Soroban caps contract-spec error enums at 50 (VecM<ScSpecUdtErrorEnumCaseV0, 50>), so#[contracterror]panics withLengthExceedsMaxand no WASM/spec can be produced. This is a pre-existing build failure unrelated to bindings and deserves its own fix.poolis already wired intoscripts/gen-bindings.shand documented, so re-enabling it is a one-line change once the contract builds.Testing
./scripts/gen-bindings.sh invoice credit_scoreis deterministic — re-running produces nogit diff(the CI sync check passes).npm run lintpasses (0 errors); generated files are correctly ignored.tscerrors (pre-existing errors onmainare in unrelated files).