This document explains how TrustLink automatically generates and maintains TypeScript bindings from the contract ABI.
TypeScript bindings are automatically generated from the compiled WASM contract using the Stellar CLI. This ensures bindings are always in sync with the contract interface and prevents manual maintenance errors.
src/lib.rs (Rust contract)
↓
cargo build --target wasm32-unknown-unknown --release
↓
target/wasm32-unknown-unknown/release/trustlink.wasm
↓
stellar contract bindings typescript
↓
bindings/typescript/src/
├── client.ts (Generated contract client)
├── types.ts (Generated type definitions)
└── index.ts (Exports)
Generates TypeScript bindings from the compiled WASM:
make bindingsThis target:
- Builds the contract in release mode
- Runs
stellar contract bindings typescriptto generate bindings - Outputs to
bindings/typescript/src/
Verifies that committed bindings are up-to-date with the current contract:
make check-bindingsThis target:
- Regenerates bindings
- Compares with committed versions
- Fails if any differences are found
Used in CI to prevent stale bindings from being merged.
The .github/workflows/ci.yml includes a bindings job that:
- Checks out the repository
- Installs Rust and Stellar CLI
- Builds the contract WASM
- Generates TypeScript bindings
- Fails if bindings are out of date
bindings:
name: TypeScript Bindings
runs-on: ubuntu-latest
needs: ci
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
run: rustup show
- name: Install Stellar CLI
run: cargo install --locked stellar-cli --features opt
- name: Build WASM
run: cargo build --target wasm32-unknown-unknown --release
- name: Generate TypeScript bindings
run: make bindings
- name: Fail if bindings are out of date
run: |
git diff --exit-code bindings/typescript/ || (
echo "TypeScript bindings are out of date."
echo "Run 'make bindings' locally and commit the updated bindings/typescript/ directory."
exit 1
)When you modify the contract interface:
- Make changes to
src/lib.rs - Build and test locally:
cargo test - Generate updated bindings:
make bindings
- Commit both contract changes and updated bindings:
git add src/lib.rs bindings/typescript/ git commit -m "feat(contract): add new function and update bindings"
When a PR is submitted:
- CI builds the contract
- CI generates bindings
- CI compares generated bindings with committed versions
- If they differ, CI fails with a message directing the developer to run
make bindings
This prevents:
- Stale bindings from being merged
- Manual binding maintenance errors
- Inconsistencies between contract and bindings
Contains the Client class with methods for all contract functions:
export class Client {
constructor(options: ClientOptions);
// Contract methods
initialize(options: MethodOptions): Promise<Result<void>>;
register_issuer(options: MethodOptions): Promise<Result<void>>;
create_attestation(options: MethodOptions): Promise<Result<string>>;
has_valid_claim(options: MethodOptions): Promise<Result<boolean>>;
// ... more methods
}Contains TypeScript type definitions for all contract types:
export interface Attestation {
id: string;
issuer: string;
subject: string;
claim_type: string;
timestamp: u64;
expiration: Option<u64>;
revoked: boolean;
metadata: Option<string>;
// ... more fields
}
export interface ContractConfig {
admin: string;
paused: boolean;
// ... more fields
}Exports all types and the client:
export * from "./client";
export * from "./types";import { Client, Attestation } from "@trustlink/bindings";
const client = new Client({
rpcUrl: "https://soroban-testnet.stellar.org",
contractId: "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCN8",
});
// Call contract functions with full type safety
const result = await client.has_valid_claim({
subject: "GBRPYHIL...",
claim_type: "KYC_PASSED",
});
if (result.isOk()) {
console.log("User has valid KYC:", result.value);
}If CI fails with "TypeScript bindings are out of date":
- Pull the latest changes
- Run
make bindingslocally - Commit the updated
bindings/typescript/directory - Push the changes
If you see type mismatches between bindings and contract:
- Ensure you're using the latest bindings:
make bindings
- Rebuild your TypeScript project:
npm install npm run build
- Check for any recent contract changes you might have missed
If make bindings fails with "stellar: command not found":
cargo install --locked stellar-cli --features opt-
Always regenerate bindings after contract changes
make bindings
-
Commit bindings with contract changes
git add src/lib.rs bindings/typescript/ git commit -m "feat(contract): ..." -
Keep bindings in sync with main
- Don't manually edit generated files
- Always use
make bindingsto update
-
Review binding changes in PRs
- Check that generated types match your contract changes
- Ensure no unexpected changes were introduced
Potential enhancements to the bindings system:
- Publish bindings to npm registry
- Generate bindings for other languages (Python, Go, Rust)
- Add binding version compatibility checks
- Automate binding updates in CI
- Generate API documentation from bindings