Skip to content

Add stellar token transfer for SEP-41 and Stellar Asset Contracts#2644

Merged
fnando merged 7 commits into
mainfrom
token-transfer
Jul 15, 2026
Merged

Add stellar token transfer for SEP-41 and Stellar Asset Contracts#2644
fnando merged 7 commits into
mainfrom
token-transfer

Conversation

@fnando

@fnando fnando commented Jul 13, 2026

Copy link
Copy Markdown
Member

What

Adds stellar token, starting with the transfer subcommand — a typed SEP-41 / Stellar Asset Contract (SAC) transfer that wraps the existing contract invoke pipeline. It resolves a token target from --id (native → native SAC, CODE:ISSUER → that asset's SAC, or a C… contract id / alias), builds a transfer(from, to, amount) invocation, and runs it through the full pipeline (simulate → auth-sign → sign → fee-bump → submit → poll). --from names the sending account (required; it signs and authorizes), --to is the destination, and --amount is the raw stroop amount. There are no caller-supplied fee/sequence flags — sane defaults are used. With --output json the command returns a machine-readable receipt { "tx_hash", "result" }; in JSON mode the pipeline runs quietly so stdout stays clean. Missing SACs return a structured error pointing at contract asset deploy.

To surface the transaction hash, contract invoke gains a minimal execute_with_receipt returning { tx_hash, output }; its existing execute/invoke entry points are unchanged.

$ $stellar token transfer --id foo --from dist --to fnando --amount 10000000
ℹ️ Simulating transaction…
ℹ️ Signing transaction: 0b18bae5f344e223e79576e58ec8a5b3f27bb447b42e87f2d09c493fae7b642c
🌎 Sending transaction…
✅ Transaction submitted successfully!
📅 CDF7U4HZVRRONHY7IADHAQPMH2LX2CJHEA7S3IGAPETIJ7DXP7IVIFYF - Success - Event: TransferWithAmountOnly (transfer), from: "GAZVY4EBCVZB2Q622J7OKGR3YYC524PPKREYPYAPHGAUOOUMDLVTNJXP", to: "GAF4UUODFGAAMYRTF5QKUZCCZPXF3S4PRU5NS2BBRVJGX4WLRVI4ZI4Z", amount: "10000000"
0b18bae5f344e223e79576e58ec8a5b3f27bb447b42e87f2d09c493fae7b642c

$ $stellar token transfer --id foo --from dist --to fnando --amount 10000000 --output=json-formatted
{
  "tx_hash": "9339aecba00925b701e36fba5ab5352c0e8e0f594cb59558f4c211aec040a8c2",
  "result": null
}

Why

Part of #2620 (the "Improve Agent UX for Wallets" epic). Agents and wallets need an ergonomic, typed way to move tokens and get back a decoded receipt with a tx hash, instead of hand-crafting contract invoke slop and scraping stderr. This lands the transfer slice plus the shared token module foundation (target resolution + output format) that the remaining subcommands will reuse.

Known limitations

  • Amounts are raw stroops (i128); decimal-aware parsing is not included.
  • Only transfer is implemented; balance, allowance, approve, burn, mint, and the SAC-admin subcommands are follow-ups.
  • JSON-clean output is achieved by running the invoke pipeline quietly; migrating contract invoke itself to the Output system is a separate follow-up.
  • Transferring to an account that has no trustline for the asset fails, as it should, but we don't wrap it in a custom "missing trustline" error. The SAC reports this only as a generic Error(Contract, #13); the human-readable reason ("trustline entry is missing for account G…") comes through the transaction's diagnostic events, which the command already prints. We rely on that diagnostic rather than matching on #13, since that number is the SAC contract's internal error enum — not a stable API — and hard-coding it would break silently if it ever changed.
$ stellar token transfer --id foo --from dist --to fnando --amount 10000000
❌ error: transaction simulation failed: HostError: Error(Contract, #13)

  Event log (newest first):
     0: [Diagnostic Event] contract:CDF7U4HZVRRONHY7IADHAQPMH2LX2CJHEA7S3IGAPETIJ7DXP7IVIFYF, topics:[error, Error(Contract, #13)], data:["trustline entry is missing for account", GAF4UUODFGAAMYRTF5QKUZCCZPXF3S4PRU5NS2BBRVJGX4WLRVI4ZI4Z]
     1: [Diagnostic Event] topics:[fn_call, CDF7U4HZVRRONHY7IADHAQPMH2LX2CJHEA7S3IGAPETIJ7DXP7IVIFYF, transfer], data:[GAZVY4EBCVZB2Q622J7OKGR3YYC524PPKREYPYAPHGAUOOUMDLVTNJXP, GAF4UUODFGAAMYRTF5QKUZCCZPXF3S4PRU5NS2BBRVJGX4WLRVI4ZI4Z, 10000000]

Copilot AI review requested due to automatic review settings July 13, 2026 18:37
@github-project-automation github-project-automation Bot moved this to Backlog (Not Ready) in DevX Jul 13, 2026
@fnando fnando self-assigned this Jul 13, 2026
@fnando fnando moved this from Backlog (Not Ready) to Needs Review in DevX Jul 13, 2026

Copilot AI 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.

Pull request overview

Adds a new stellar token command group (starting with transfer) that provides a typed SEP-41 / Stellar Asset Contract transfer wrapper over the existing contract invoke pipeline, including a receipt that surfaces the submitted transaction hash.

Changes:

  • Introduces stellar token transfer with token target resolution (native, CODE:ISSUER, or C…/alias) and JSON/text output selection.
  • Extends contract invoke with execute_with_receipt to return { tx_hash, output } while keeping existing execute behavior stable.
  • Adds soroban-test integration coverage for native + issued-asset transfers and key failure modes.

Reviewed changes

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

Show a summary per file
File Description
FULL_HELP_DOCS.md Documents the new stellar token command and transfer subcommand usage/options.
cmd/soroban-cli/src/commands/token/transfer.rs Implements token transfer command: target resolution, invoke orchestration, and receipt formatting.
cmd/soroban-cli/src/commands/token/mod.rs Wires token command group and its error routing.
cmd/soroban-cli/src/commands/token/args.rs Adds shared token target parsing/resolution and shared output format enum.
cmd/soroban-cli/src/commands/mod.rs Registers the new token subcommand in the root command enum and error enum.
cmd/soroban-cli/src/commands/contract/invoke.rs Adds execute_with_receipt and InvokeReceipt (tx hash + decoded output).
cmd/soroban-cli/src/cli.rs Enables JSON error envelope rendering for token transfer based on its --output selection.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rs Adds integration tests for token transfer success and failure scenarios.
cmd/crates/soroban-test/tests/it/integration/token/mod.rs Adds integration helpers for SAC deploy, trustlines, balances, and issuer payments.
cmd/crates/soroban-test/tests/it/integration.rs Registers the new token integration test module.

Comment thread cmd/soroban-cli/src/commands/token/transfer.rs Outdated
Comment thread cmd/soroban-cli/src/commands/token/transfer.rs
Comment thread cmd/crates/soroban-test/tests/it/integration/token/transfer.rs
Comment thread cmd/soroban-cli/src/commands/token/args.rs Outdated
Comment thread cmd/soroban-cli/src/commands/token/transfer.rs Outdated
Comment thread cmd/soroban-cli/src/commands/token/transfer.rs
Comment thread cmd/soroban-cli/src/commands/token/transfer.rs
Comment thread cmd/crates/soroban-test/tests/it/integration/token/mod.rs
@fnando fnando merged commit f4765c7 into main Jul 15, 2026
227 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Review to Done in DevX Jul 15, 2026
@fnando fnando deleted the token-transfer branch July 15, 2026 19:56
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.

3 participants