Skip to content

Handle built-in Stellar Asset Contracts (SACs) in contract.Client.from#1501

Open
quietbits wants to merge 8 commits into
mainfrom
issue-1166
Open

Handle built-in Stellar Asset Contracts (SACs) in contract.Client.from#1501
quietbits wants to merge 8 commits into
mainfrom
issue-1166

Conversation

@quietbits

@quietbits quietbits commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Updates

  • Client.from now supports SACs. It fetches the contract instance, and when the executable is StellarAsset it builds the client from the embedded SAC spec; otherwise it loads the Wasm and parses the spec as before. This mirrors what BindingGenerator.fromContractId and stellar-cli already do.
  • Extracted Server.getContractInstance(contractId). A new public method that fetches the contract instance ledger entry and returns its xdr.ScContractInstance. Both Client.from and getContractWasmByContractId branch off it, so the historical { code: 404, message } rejection for a missing instance lives in exactly one place. This preserves the pre-existing error shape for consumers that inspect err.code (no behavioral change on failure paths).
  • Server.getContractWasmByContractId now throws a clear error for a SAC (which has no Wasm bytecode), pointing callers to Client.from, instead of the cryptic XDR crash. Otherwise unchanged and non-breaking.
  • Lazy-load the embedded SAC spec. Client.from loads the ~9.5 KB SAC_SPEC via dynamic import() inside the SAC branch, so bundlers can code-split it out of the common contract/client path; it's only fetched when a SAC is actually built.
  • Build: set inlineDynamicImports: true on the UMD dist outputs in rollup.config.mjs so the lazily-imported SAC spec stays in a single bundle (explicit guarantee against Rollup's default behavior; bundles are byte-identical).

Backward compatibility

  • Success path unchanged.
  • Failure paths preserve the existing { code: 404, message } rejection shape (missing instance / missing Wasm) and the same invalid-contract-id behavior.
  • New behavior is limited to (a) SACs now succeeding instead of crashing, and (b) a direct call to getContractWasmByContractId on a SAC now throwing a descriptive error.

Testing

  • New test/unit/contract/client_from.test.ts: a Wasm baseline plus a SAC case. The SAC case reproduced the exact issue error before the fix and is green after. Fixtures are built in-memory (pure Buffer ops) so the file runs under both the node and browser unit environments.
  • New SAC-guard case in test/unit/server/soroban/get_contract_wasm.test.ts.

Copilot AI review requested due to automatic review settings June 29, 2026 19:35
@github-project-automation github-project-automation Bot moved this to Backlog (Not Ready) in DevX Jun 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Soroban contract client creation and RPC Wasm fetching behavior by correctly handling built-in Stellar Asset Contracts (SACs), which do not have on-chain Wasm bytecode.

Changes:

  • Updated contract.Client.from to detect SAC instances and build clients from the embedded SAC_SPEC instead of attempting to fetch Wasm.
  • Updated Server#getContractWasmByContractId to fail fast for SACs with a clear, actionable error message.
  • Added/updated unit tests to cover SAC handling for both Client.from and getContractWasmByContractId, plus updated generated reference docs accordingly.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/contract/client.ts Routes SAC contracts through embedded SAC_SPEC instead of Wasm download logic.
src/rpc/server.ts Adds SAC guard + clearer error for getContractWasmByContractId.
test/unit/contract/client_from.test.ts New unit coverage for Client.from (Wasm baseline + SAC case).
test/unit/server/soroban/get_contract_wasm.test.ts Adds SAC-specific failure-mode test for Wasm fetching by contract ID.
docs/reference/contracts-client.md Updates generated reference to document SAC behavior in Client.from.
docs/reference/network-rpc.md Updates generated reference to document SAC limitation in getContractWasmByContractId.
.gitignore Ignores scratch/ directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/contract/client.ts Outdated
Comment thread src/contract/client.ts Outdated
Comment thread src/rpc/server.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 332c637ed5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/contract/client.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Comment thread src/rpc/server.ts
Comment thread test/unit/contract/client_from.test.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 1 comment.

Comment thread src/rpc/server.ts
Comment on lines +551 to +556
if (!response.entries.length || !response.entries[0]?.val) {
return Promise.reject({
code: 404,
message: "Could not obtain contract instance from server",
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Add contract.Client#fromContractID that also handles built-in contracts (SAC)

2 participants