Soroban Forge is a library of reusable Soroban smart-contract foundations and developer tooling for the Stellar ecosystem — escrow, vesting, multi- signature wallets, DAO governance, subscription payments, and marketplace royalties, plus a developer CLI and TypeScript bindings.
The escrow contract is deployed and verified on Stellar testnet. Every
step below was executed live; run bash scripts/demo-testnet.sh to reproduce
(step-by-step walkthrough with expected output).
| Artifact | Value |
|---|---|
| Network | Stellar Testnet (Test SDF Network ; September 2015) |
| Escrow contract | CC227UDF6WBLRTOKKVRIJN7BGSBK67ZGV6IDARJ2AMATGSQ7UZNBZHSB |
| WASM sha256 | ccbb6603cce6d194407b822df110c91324939cea92ba21937a6d9f1e2c9e48b9 |
| soroban-sdk | 28.0.0 · macros 27.0.6 · stable Rust · wasm32v1-none · 18,054 bytes |
| Demo token (SAC) | CBJQ53EOHB5MWSS7CETN523WILLNVS7NQAQQAQIS5QAYTPRCZSGKL23O (credit asset) |
| Roles | buyer GCTEIX…VSGF · seller GCGPZ3…4SFS · arbiter GCR7CB…GJTQ |
| Round | Flow | Transaction |
|---|---|---|
| 1 | create → deposit → release (seller paid 500) | create 817950c8… · deposit · release |
| 2 | create → deposit → dispute(buyer) → resolve for seller | dispute + resolve transactions |
| 3 | create → deposit → dispute(seller) → resolve for buyer | dispute + resolve transactions |
After all three rounds: buyer 500 + seller 1000 = 1500 credit minted; the
contract holds zero — the on-chain conservation property (deposited == paid out) verified on a live network, matching the in-repo property test.
The token-transfer event from round 1's deposit is visible in the transaction
linked above: 500 credit moved buyer → contract.
Before any deploy flow, reviewers can inspect a local WASM artifact and compare its SHA-256 without signing or network access:
soroban-forge inspect --dry-run \
--wasm target/wasm32v1-none/release/soroban_forge_escrow.wasm \
--expected <sha256>This is a local, read-only dry run intended for artifact and provenance review; it does not invoke the network or require a source account.
The maintained smoke flow is scripts/demo-testnet.sh. It builds the locked escrow WASM, verifies its SHA-256 against docs/testnet/escrow-wasm.sha256, and writes a machine-readable receipt. It never creates, funds, prints, or commits keys.
Run the credential-free check on a clean machine:
bash scripts/demo-testnet.sh --help
bash scripts/demo-testnet.sh --dry-run --receipt artifacts/escrow-smoke-receipt.jsonFor a live create_escrow → deposit → release check, provide existing Stellar
CLI identities and explicit ESCROW_ID and TOKEN_ID values. The live flow
asserts Completed, verifies successful transaction receipts contain the
expected lifecycle events, checks buyer/seller/contract conservation, and
records transaction hashes in the JSON receipt. See the
reviewer walkthrough for the complete command.
Honest notes: testnet only (no mainnet deployment); the smoke harness uses caller-provided CLI identities and never manages private keys; two-auth escrow creation was deliberately rejected as a design — a live
TxBadAuthon every standard signing path during this demo motivated the buyer-only creation flow. See docs/KNOWN-LIMITATIONS.md.
The goal is simple: stop rewriting the same contracts for every project. Pick a well-documented foundation, audit it for your use case, and ship.
Status: This project is under active development. The contracts are not independently audited and should not be treated as production-ready without your own security review. The escrow contract is the flagship: it holds and moves real SEP-41 tokens end-to-end and is verified by a conservation property test. Marketplace royalties, multi-sig, and vesting have since gained real settlement too, DAO governance settles a SEP-41 proposal bond (pulled at
propose, refunded or forfeited at a terminal transition), and subscriptions now bill each due period with a real subscriber → provider transfer with past-due retry — see the Feature Status Matrix and Known Limitations for exactly what is and is not done.
| Contract | Description | Status |
|---|---|---|
| Escrow | Three-party escrow for real SEP-41 tokens: create → deposit → release_partial / release / refund / dispute → resolve / cancel; partial-release accounting, arbiter dispute flow, lifecycle events, persistent storage and TTL |
✅ Flagship · 85 tests · conservation property verified |
| Vesting | Time-locked token release with cliff and linear release (create_schedule → claim / claimable) — claim settles through a real SEP-41 transfer |
✅ Settlement · 27 tests |
| Multi-Sig Wallet | Multi-owner wallet with threshold-gated opaque and typed calls, optional transaction expiry, withdrawals with rolling limits, and owner/threshold governance; transaction records in persistent storage with TTL | ✅ State machine · 155 tests |
| DAO Governance | On-chain proposals with weighted voting and deadlines; SEP-41 bonds are pulled at propose and refunded or forfeited at terminal transitions; approved actions dispatch on-chain; proposer cooldown limits concurrent proposals |
✅ Bond settlement · 85+ tests |
| Subscription Payments | Recurring billing with provider opt-in (subscribe / subscribe_on_behalf_of → charge / pause / resume / cancel) — charge executes a real subscriber → provider SEP-41 transfer with past-due retry and auto-cancel |
✅ Settlement · 57 tests |
| Marketplace Royalties | Configurable royalty splits with real SEP-41 settlement: settle_sale pays the seller and recipient, and settle_sales atomically batches up to 20 sales |
✅ Settlement |
Implementation work is tracked as scoped, labeled issues.
The Next.js example can be deployed to Vercel directly from this repository; see the Vercel deployment guide. The local SDK is built as part of the deployment, so npm publication is optional.
flowchart LR
subgraph Contracts["Contract crates"]
escrow[escrow]
vesting[vesting]
multisig[multi-sig-wallet]
dao[dao-governance]
subs[subscription-payments]
royalties[marketplace-royalties]
end
shared[shared-utils<br/>errors · types · storage patterns]
testutils[test-utils<br/>Env harness · mock accounts]
sdk[soroban-sdk 28.0.0 / macros 27.0.6]
cli[cli<br/>build · lint · test · deploy · new · verify · invoke · events]
ts[typescript-sdk]
net[(Stellar network)]
Contracts --> shared
Contracts --> testutils
shared --> sdk
Contracts --> sdk
cli --> Contracts
ts --> Contracts
Contracts --> net
The workspace is a virtual Cargo workspace: each contract is its own crate so
it can be deployed and upgraded independently, while shared-utils and
test-utils keep error handling, storage patterns, and test harnesses DRY.
stateDiagram-v2
[*] --> Pending: create_escrow
Pending --> Funded: deposit
Funded --> Funded: release_partial (partial)
Funded --> Completed: release_partial (final) / release
Funded --> Refunded: refund (remaining balance)
Pending --> Cancelled: cancel
Funded --> Disputed: dispute (remaining frozen)
Disputed --> Completed: resolve (seller wins)
Disputed --> Refunded: resolve (buyer wins)
soroban-forge/
├── crates/ # Rust smart contracts and libraries
│ ├── shared-utils/ # ForgeError, storage patterns, shared types
│ ├── test-utils/ # Soroban Env test harness and mock accounts
│ ├── cli/ # Developer CLI (build / lint / test / deploy / new / verify / invoke / events)
│ ├── escrow/ # ✅ implemented
│ ├── vesting/ # ✅ implemented
│ ├── multi-sig-wallet/
│ ├── dao-governance/
│ ├── subscription-payments/
│ └── marketplace-royalties/
├── packages/ # Language bindings and example apps
│ ├── typescript-sdk/ # @soroban-forge/escrow-client (generated from the deployed escrow ABI)
│ ├── vesting-client/ # @soroban-forge/vesting-client (generated)
│ ├── multi-sig-wallet-client/ # @soroban-forge/multi-sig-wallet-client (generated)
│ ├── subscription-payments-client/ # @soroban-forge/subscription-payments-client (generated)
│ ├── marketplace-royalties-client/ # @soroban-forge/marketplace-royalties-client (generated)
│ ├── dao-governance-client/ # @soroban-forge/dao-governance-client (generated)
│ ├── nextjs-example/ # Next.js testnet escrow demo (Freighter wallet)
│ └── deployment-templates/ # Docker and deployment templates
├── docs/ # Architecture, tutorials, best practices
├── templates/ # Contract scaffolding templates
└── scripts/ # Maintainer tooling (labels, issue creation)
Tests live inside each contract crate as Soroban Env-based test modules and
run through cargo test --workspace.
The workspace pins stable Rust and builds contracts for the
wasm32v1-none target required by soroban-sdk 28.x.
rustup target add wasm32v1-none # needed to build contracts to WASM
cargo install soroban-cli # optional: for deploymentgit clone https://github.com/Meet-hybrid/soroban-forge.git
cd soroban-forge
cargo build --workspace --all-targets --locked # compile everything
cargo test --workspace --all-targets --locked # run the contract test suite
make lint # fmt + clippy gatescargo build --release --target wasm32v1-none -p soroban-forge-escrow
# → target/wasm32v1-none/release/soroban_forge_escrow.wasmcargo run -p soroban-forge-cli -- --help
cargo run -p soroban-forge-cli -- build --release
cargo run -p soroban-forge-cli -- test --package soroban-forge-escrow
cargo run -p soroban-forge-cli -- scaffold-validate crates/my-contract
# New commands for contract interaction
cargo run -p soroban-forge-cli -- invoke --contract <CONTRACT_ID> --function balance --network testnet
cargo run -p soroban-forge-cli -- events --contract <CONTRACT_ID> --since <LEDGER> --network testnet
# Stream events in JSONL format for machine processing
cargo run -p soroban-forge-cli -- events --contract <CONTRACT_ID> --network testnet --jsonlstellar contract deploy \
--wasm target/wasm32v1-none/release/soroban_forge_escrow.wasm \
--source-account <YOUR_KEYPAIR_NAME> \
--network testnetThen exercise the deployed contract with stellar contract invoke — e.g.
create_escrow(buyer, seller, arbiter, token, amount, timeout), then
deposit (moves real tokens), release, refund, dispute + resolve,
or cancel per the lifecycle above.
make build # cargo build --workspace --all-targets
make test # cargo test --workspace --all-targets
make format # cargo fmt --all
make lint # cargo clippy --workspace --all-targets -- -D warnings
make audit # cargo audit (requires cargo-audit)
make doc # open rustdocThe six packages/*-client directories are generated bindings produced from
each contract's WASM. Regenerate them all from a clean local build with:
bash scripts/generate-clients.shThis builds every contract for wasm32v1-none and runs the pinned Stellar
CLI's stellar contract bindings typescript --wasm for each one, wiping and
rewriting each package directory. Then build the packages:
(cd packages/typescript-sdk && npm install && npm run build)
(cd packages/nextjs-example && npm install && npm run build)CI (.github/workflows/ci.yml) enforces: Rustfmt · Clippy (-D warnings) ·
Build · Test · Security Audit · WASM Size Check, with --locked for
reproducible builds and a per-contract WASM size budget.
- Getting Started
- Writing Your First Contract
- Architecture
- Contract Overview
- Feature Status Matrix
- Known Limitations
- Storage Patterns
- Smart Contract Security
- Testing Strategy
We welcome contributions! Please read CONTRIBUTING.md for our code of conduct and contribution process. Contributor-facing work is scoped as labeled issues.
Contributions are fork-first: fork the repository, work on a branch in your
fork, and open a pull request against main. Each issue lists its acceptance
criteria and verification commands.
Please read SECURITY.md for how to report vulnerabilities.
Licensed under either of
at your option.
Built for the Stellar developer community.