What a ChimpDAO card signs, in one place. Every authorisation is bound to one exact call: the contract, the function and its arguments (asset, amount, destination), the network, a nonce and an expiration.
LAST UPDATED ·
Two kinds of signature
KINDUSED FORWHAT THE CHIP SIGNSREPLAY STOPS AT
Account authorisation
USED FOREvery payment and account operation, from the Main account or a card's wallet
WHAT THE CHIP SIGNSThe Stellar network's authorisation payload for the exact call
REPLAY STOPS ATNetwork nonce and expiration ledger
Presence attestation
USED FORCard registration only
WHAT THE CHIP SIGNSA digest of the registry call with a per-card nonce
An authorisation entry with the Protocol 28 credentials (sorobanCredentialsAddressV2) signs HashIdPreimageSorobanAuthorizationWithAddress instead: the same fields plus the authorising address. The client hashes the variant the entry carries and never converts it.
From a card's wallet, the chip's signature is placed in the entry as it is. From the Main account, it is wrapped as AccountAuth { key, auth }, which names the card that signed; the account checks the signature against that card's stored key. Nothing is hashed on top of the network's payload, and the contracts keep no nonce of their own: the network enforces the nonce and the expiration.
The domain string is specific to the card registry, so an attestation cannot be reused by another contract family. The arguments are the card's public key and the terms it is registered under.
Intents and their bound fields
Every intent signed by a card also binds the network, a nonce and an expiration ledger. Amounts are exact integers in the asset's smallest unit (7 decimal places on Stellar).
INTENTCALL SIGNEDBOUND FIELDSSTATUS
Transfer (send, move)
CALL SIGNEDtransfer(from, to, amount) on the asset contract
BOUND FIELDSAsset contract · amount · source (Main account or a card's wallet) · destination (G, C or M address)
STATUSLive on testnet
Swap (Soroswap)
CALL SIGNEDswap_exact_tokens_for_tokens(amount_in, min_out, path, to, deadline) on the router
BOUND FIELDSRouter contract · asset in and asset out (path) · amount in · minimum amount out, the "at least" figure shown · recipient, the signing account · deadline, 5 minutes · sub-call: transfer of the amount in to the pool pair
STATUSPlanned
Deposit into a DeFindex vault
CALL SIGNEDdeposit([amount], [min amount], from, invest = true) on the vault
BOUND FIELDSVault contract · amount (minimum = amount, single-asset vault) · depositor · sub-call: transfer of the amount to the vault. The vault's asset is checked before signing.
STATUSPlanned
Withdrawal from a DeFindex vault
CALL SIGNEDwithdraw(shares, [min amount out], from) on the vault
BOUND FIELDSVault contract · shares · minimum amount out (expected amount minus 0.5%) · account. Nothing is pulled from the signer.
STATUSPlanned
Card registration
CALL SIGNEDmint(attestation, public key, terms, nonce) on the registry
BOUND FIELDSRegistry contract · the card's public key and terms · per-card nonce (presence attestation)
STATUSLive on testnet
Funding a card from an external wallet
CALL SIGNEDtransfer(from, to, amount) on the XLM asset contract
BOUND FIELDSSigned by the sender's wallet, not by a card · source (the sender's address) · destination (a ChimpDAO Main account or card wallet, checked by the Fund page) · amount
STATUSLive on testnet
Swap, deposit and withdrawal are implemented in ChimpDAO's reference payment terminal on testnet. The iOS app does not sign them yet.
Who signs, and when
AUTHORISERORDERWHY
A card's wallet
ORDERDeclare, sign, then simulate. The client builds the authorisation itself; the chip signs it before any simulation.
WHYA recording simulation cannot run for a card's wallet that follows the shared code version (Protocol 28, CAP-85). A wrong declaration fails in simulation, and a signed authorisation can never cover more than it declares.
The Main account
ORDERSimulate, then sign. The simulation returns the entry the account must authorise; the chip signs it.
WHYThe entry is checked before the card signs (below).
The app's verification rule
Live on testnet
Before a card signs from the Main account, the iOS app checks that the entry returned by the simulation is exactly the requested call: same contract, same function, same arguments, no sub-call, and a single entry to sign for this account. Otherwise nothing is signed. An entry for another address is refused before any signature.
From a card's wallet the app builds the entry itself, so it is the requested call by construction. In both cases the review screen shows the network, the exact amount and the recipient before the card is tapped.
Test vectors
Planned
Published test vectors will show each refusal below. None exists yet.
CASEREFUSED BYTEST VECTOR
Modified amount
REFUSED BYThe iOS app (exact-call check) and the signature itself
TEST VECTORPlanned
Modified asset
REFUSED BYThe iOS app (exact-call check) and the signature itself
TEST VECTORPlanned
Modified destination
REFUSED BYThe iOS app (exact-call check) and the signature itself
TEST VECTORPlanned
Wrong target contract
REFUSED BYThe iOS app (exact-call check) and the signature itself
TEST VECTORPlanned
Replayed nonce
REFUSED BYThe Stellar network
TEST VECTORPlanned
Expired payload
REFUSED BYThe Stellar network
TEST VECTORPlanned
Already tested: the contracts refuse another card and a signature over another payload; the iOS app refuses an entry for another address and builds the same bytes as the reference implementation.