Docs

Smart contracts

The three Noir Soroban contracts on Stellar Testnet: IDs, functions, error codes and call order.

Stellar Testnet deployment

RPC https://soroban-testnet.stellar.org · passphrase Test SDF Network ; September 2015. Every redeploy mints new IDs; the SDK’s TESTNET constant and GET /v1/network always carry the current ones.

Call order

  1. device_registry.register — owner binds the card hash.
  2. agent_registry.register_agent — owner sets the policy.
  3. payment_escrow.fund_escrow — owner pre-funds the card.
  4. payment_escrow.authorize — on tap, the agent pays the merchant.
  5. payment_escrow.claim — the merchant collects in batch.
  6. To unlink: revoke_agent, then sweep_on_revoke returns the escrow. Never device_registry.revoke while escrow is above zero — it strands funds.

device_registry

Binds the SHA-256 hash of an NFC tag to the wallet that owns it.

FunctionAuth
register(wallet, device_hash, agent)wallet
revoke(wallet, device_hash)wallet
get_owner(device_hash) → Addressread
get_device(device_hash) → DeviceInforead
wallet_device_count(wallet) → u32read
wallet_device_at(wallet, index) → BytesN<32>read

Errors: 1 AlreadyInitialized · 2 DeviceNotFound · 3 NotOwner · 4 AlreadyRegistered

agent_registry

Stores each device’s agent policy: which key may spend, which asset, how much per payment, until when.

FunctionAuth
register_agent(wallet, device_hash, agent, max_amount, asset, expires_at)wallet
revoke_agent(wallet, device_hash)wallet
get_policy(device_hash) → AgentPolicyread
is_auth(device_hash, agent) → boolread
check_payment(device_hash, agent, asset, amount) → boolread

Errors: 1 AlreadyInitialized · 2 AgentNotFound · 3 AlreadyRegistered · 4 InvalidPolicy

payment_escrow

Holds each device’s pre-funded balance; authorizes taps within policy and lets merchants claim in batch.

FunctionAuth
fund_escrow(token, wallet, device_hash, amount)wallet
authorize(agent, device_hash, merchant, asset, amount, nonce)agent
claim(token, merchant)merchant
defund_escrow(token, device_hash, amount)device owner
sweep_on_revoke(token, device_hash, agent) → i128device owner
balance_of(device_hash) → i128read
pending_balance(merchant) → i128read

Errors: 1 AlreadyInitialized · 2 InsufficientBalance · 3 AgentNotAuthorized · 4 NotDeviceOwner · 5 NothingToClaim · 6 DuplicateAuth · 7 AgentStillActive · 8 DeviceNotRegistered

From the Stellar CLI

bash
stellar contract invoke --network testnet --source alice \
  --id CBTDMJVCFQDIVWZBKAKZ2FQ3UEJNAAUFYCTJ3E4ON2MYXPLPSIXQ25JZ -- \
  get_policy --device_hash ab12…   # 64 hex chars

Rust source and tests: backend/contracts.