Verifiable Intent
Attach a Mastercard-aligned Verifiable Intent (VI) L1→L3 chain to your x402 payments so every request your agent makes is automatically run through the XRPL Facilitator's risk service.
What is Verifiable Intent?
Verifiable Intent (VI) is a cryptographic proof, carried alongside an x402 payment, that answers three questions a risk engine needs before it trusts an autonomous payment: who authorized it, under what limits, and for exactly which transaction. It follows the Mastercard Agentic / Verifiable Intent standard and is expressed as a three-link chain of SD-JWT credentials (L1 → L2 → L3).
VI is optional and additive. A plain x402 payment still works exactly as before. But when your payment carries a valid L1→L3 chain, the XRPL Facilitator forwards it to Trustline for verification and your transaction is gated by a real risk decision — turning an anonymous, irreversible XRPL payment into one with an accountable, machine-checkable intent behind it.
The deal in one line: sign L1→L3 and bundle it into your x402 request, and the Facilitator's risk service is applied to every payment — no extra API calls, no separate integration.
Official references
- verifiableintent.dev — the Verifiable Intent standard site
- Mastercard — Verifiable Intent — the official announcement
The three layers (L1 → L2 → L3)
Each layer is signed by a different party and cryptographically binds the one above it, so the chain cannot be re-assembled or replayed for a different payment.
Issuer credential — signed by Trustline
Trustline issues a credential that binds the owner's public key plus the allowed chains, allowed assets, and a spending ceiling. Your backend mints it by calling Trustline /issue-l1 with your Issuer Secret. L1 says: "Trustline vouches that this owner key is provisioned for these limits."
Owner delegation — signed by the owner
The wallet owner signs a delegation that authorizes a specific agent key to act on their behalf, under constraints (per-transaction max, allowed chains/assets). It binds L1 by hash. L2 says: "I, the owner, let this agent spend within these constraints."
Final action — signed by the agent
At payment time the agent signs the terminal action, binding the exact payment: the invoiceId and a hash of the payment requirements. It binds L2 by hash and is single-use. L3 says: "This agent commits to exactly this payment, right now."
Who holds which key
As the developer you operate two key pairs locally and hold one secret from the Trustline Portal:
- Owner key (P-256) — represents the wallet owner; signs L2. Created/derived in your client.
- Agent key (P-256) — represents the acting agent; signs L3. Created in your client.
- Issuer Secret — authenticates your backend's
/issue-l1call so Trustline signs L1 for your organization. Obtained once from the Trustline Portal.
Trustline holds the L1 signing key (selected by your Issuer Secret) and never sees your owner/agent private keys. The XRPL Facilitator relays the chain to Trustline for verification and enforces the decision; it is custody-blind to your keys.
Why attaching VI earns the risk service
VI is soft-compat by design. When a payment carries a chain, the Facilitator's /verify and /settle calls forward it to Trustline, which verifies L1→L3 and feeds the verdict into its risk engine as a trust signal. Trustline returns a decision — allow, deny, or review — and the Facilitator gates settlement on it. A verified chain is a strong positive signal; an elevated-risk wallet can still be denied even with a valid chain (the chain proves intent, the risk engine still decides).
No chain means an ordinary x402 payment with no risk call. So attaching L1→L3 is exactly how you opt your agent into the risk service.
How the chain rides in the payment
The chain travels inside the x402 PAYMENT-SIGNATURE header — the same header that carries your presigned XRPL payment — under extensions.x402Secure.verifiableIntentChain. The header value is base64-encoded JSON of this shape:
{
"x402_version": 2,
"accepted": { /* the payment requirements you are paying */ },
"payload": { "signedTxBlob": "...", "invoiceId": "..." },
"extensions": {
"x402Secure": {
"verifiableIntentChain": {
"l1Credential": { "format": "sd+jwt", "sdJwt": "<L1 — issued by Trustline>" },
"l2Delegation": { "format": "kb-sd-jwt+kb", "sdJwt": "<L2 — signed by the owner>" },
"l3FinalAction": { "format": "kb-sd-jwt", "sdJwt": "<L3 — signed by the agent>" }
}
}
}
}You do not assemble this by hand — the x402-xrpl SDK builds and attaches it for you from a verifiable_intent_provider. The next page walks through the full agent integration.
Next Step
Ready to add VI to your agent? Follow the step-by-step integration guide.
Go to the Agent Integration Guide