Docs Técnicas
Spending Vaults And Card Authorization
TREA models card-like spending as a contract-controlled authorization, not as a card key controlling the user's main wallet.
TREA models card-like spending as a contract-controlled authorization, not as a card key controlling the user's main wallet.
The pattern is:
owner/cardholder -> configures contract limits
card key -> signs a PaymentIntentV1
acquirer/gateway -> validates, simulates, submits the contract call
contract -> enforces balance, limits, expiry, merchant policy, nonceDeposited Spending Vault
std.asset.SpendingVault[Asset] holds a deposited balance. The card can only spend what the owner has put into the vault.
Important storage:
| Field | Meaning | |-------|---------| | owner | Wallet that can deposit, withdraw, pause, rotate or revoke the card | | card_pubkey / card_curve | Card verification key and curve (secp256k1 or p256) | | token_id | Ledger asset this vault can spend | | balance: Balance[Asset] | Tracked vault position | | max_per_tx, daily_limit | Spending limits | | used_nonces | Replay protection | | allowed_merchants | Optional allowlist |
pay(merchant, amount, nonce, signed_intent) verifies:
- vault is not paused;
- card is not revoked or expired;
- amount is non-zero and within per-tx and daily limits;
- vault balance is sufficient;
- nonce was not used;
- merchant is allowed when the allowlist is enabled;
ctx.assetmatchestoken_id;- the card signature matches the canonical
PaymentIntentV1bytes.
The card key never moves the owner's wallet balance directly. It authorizes only the constrained contract action.
Authorized Spending Vault
std.asset.AuthorizedSpendingVault[Asset] keeps the same card-style signature and policy model but can debit the owner path directly instead of requiring a pre-funded contract balance. This is higher risk and should be presented as direct spending authority in wallets and audits.
Use it when capital lock-up is unacceptable and the owner explicitly accepts that the contract can move funds under a signed card intent.
Credit Card Vault
std.asset.CreditCardVault[Asset] models issuer-funded credit. Merchant payments come from the issuer side, while the cardholder's outstanding debt is tracked as Balance[CREDIT].
Key entrypoints:
@construct
def initialize(issuer, cardholder, card_pubkey, card_curve, token_id,
credit_limit, max_per_tx, daily_limit, expires_at)
@tx
def pay(merchant, amount, nonce, signed_intent)
@tx
def repay(amount)
@tx
def bind_lineage(parent_template_id, origin_request_id, approved_terms_hash)bind_lineage is used when the vault is created as a child of a ProductTemplate. It is set once by the issuer and lets explorer, wallet, and AI Audit prove where the child contract came from.
PaymentIntentV1
The card signs SHA-256(message) where:
"PAYMENT_INTENT_V1\0"
vault_id "\0"
token_id "\0"
amount (u64 BE)
merchant "\0"
nonce (u64 BE)
expires_at (i64 BE)Supported curves are secp256k1 and p256. The signature is DER-encoded ECDSA as hex. Gateways can pre-validate this with the operational interop endpoint, but the contract still verifies the same bytes before posting effects.