Skip to content

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

Merged
quietbits merged 11 commits into
mainfrom
issue-1166
Jul 6, 2026
Merged

Handle built-in Stellar Asset Contracts (SACs) in contract.Client.from#1501
quietbits merged 11 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",
});
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think it's more accurate to say that the contract instance wasn't found, but the previous message used hash. Not sure if it's important to keep the same message. What do you think, @Ryang-21 ? 🙏

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is OK. Something we could consider for the next release is to move away from error messages all together and create custom error objects that extend from the generic.

@Ryang-21 Ryang-21 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I left a comment for the dynamic import but everything else looks good

Comment thread src/contract/client.ts
Comment thread src/contract/client.ts
…1502)

* Add rpc.Server.queryContract for one-line read-only contract calls

* Sanitize method name

* Check only contract methods before invoking

* e2e test happy path

* Make contract.Client factories generic for typed runtime clients (#1504)

* Make contract.Client factories generic for typed runtime clients

* Add `rpc.Server.getContractMethods` for contract method discovery (#1505)

* Add rpc.Server.getContractMethods for contract method discovery

* Document queryContract and getContractMethods in the invoke-a-contract guide

* Type the contract.Client examples in the invoke and auth guides
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@quietbits
quietbits merged commit 6a7898e into main Jul 6, 2026
11 checks passed
@quietbits
quietbits deleted the issue-1166 branch July 6, 2026 17:30
@github-project-automation github-project-automation Bot moved this from Backlog (Not Ready) to Done in DevX Jul 6, 2026
@oceans404 oceans404 added this to the v17.0.0 milestone Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

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

4 participants