← Overview
PROTOCOL SPEC
F·01 – F·06 · Full transaction lifecycle · Open specification · ward-protocol v0.1.1
PyPI ward-protocol==0.1.1 ALTNET TXNS 5 confirmed TEST COVERAGE 95/95 SPEC XRPLF #474
Core Principle
1
Institution integrates Ward SDK
2
Ward builds unsigned XRPL transaction
3
Institution signs with own wallet
4
XRPL enforces outcome — automatically
Ward stops here. Ward never holds keys. Ward never submits transactions.
Institution Wallet
Ward SDK
XRPL Ledger
ward_signed = False — always
$ pip install ward-protocol==0.1.1
F·01
Vault Registration
Registers an XLS-66 vault in the Ward Protocol XLS-80 compliance domain
XLS-66 LIVE POST /api/v1/vaults/register
Institution Wallet
register_vault()
Institution's wallet — Ward never holds keys
Ward SDK
unsigned VaultCreate (XLS-66) unsigned AccountSet (XLS-80 domain) ward_signed = False
Ward stops here — institution signs externally
XRPL Ledger
VaultCreate confirmed Vault in XLS-80 domain registry PolicyNFTTaxon = 282 CredentialNFTTaxon = 282
Result: Vault active on XRPL. Emits XLS-66 events immediately. Signer: Institution wallet only. Ward's server is now irrelevant to the vault's existence.
↓ F·02
F·02
Credential Issuance
XLS-70 on-chain KYC hash anchoring · No raw PII on-chain · sha256(kyc_document) only
XLS-70 LIVE POST /api/v1/credentials/issue commit 65cba10
Institution performs KYC off-chain using existing provider. Ward derives sha256(kyc_document) and anchors it on-chain via XLS-70 NFT. Raw PII never leaves the institution's systems. v2: XLS-96 confidential balances + MPT selective disclosure — XRPL native, zero breaking changes.
Institution
KYC off-chain (existing provider)
issue_credential(kyc_hash)
Signs NFTokenMint with institution wallet
Ward SDK
build_kyc_hash(depositor, inst, ledger_time)
unsigned NFTokenMint taxon = 282 · non-transferable URI: kyc_hash + expiry_ledger + kyc_type ward_signed = False
XRPL Ledger
Credential NFT confirmed Non-transferable on-chain sha256 hash permanent
Raw KYC data never on-chain
Result: Subject address credentialed for vault interaction. Credential NFT (taxon=282) in institution account. Expiry enforced by XLS-70 ledger object. Ward never held the KYC data.
↓ F·03
F·03
Policy Purchase
XLS-20 policy NFT · Coverage terms immutably encoded in URI · Burns atomically on settlement
XLS-20 LIVE POST /api/v1/policies/purchase
Depositor purchases a policy certificate for a specific vault. Coverage terms — amount, expiry, vault, premium — are immutably encoded in the NFT URI at mint time. tfBurnable only, not transferable. Burns atomically with EscrowFinish in F·06, making replay structurally impossible.
Depositor
purchase_coverage(vault_id, coverage_drops, duration_days)
Holds policy NFT in own wallet after mint
Ward SDK
validate: XLS-70 valid, vault active, no duplicate
unsigned NFTokenMint taxon = 281 · TF_BURNABLE URI: coverage_drops | expiry_ledger | vault_id | premium_bps ward_signed = False
XRPL Ledger
Policy NFT confirmed Terms immutable on-chain Non-transferable (no tfTransferable) Replay-protected on burn
Result: Policy NFT (taxon=281, tfBurnable) in depositor wallet. Coverage active immediately. Errors: DuplicatePolicyError · VaultCapExceededError · CredentialExpiredError.
↓ F·04
F·04
Default Detection
VaultMonitor runs in institution's infrastructure · Ward provides detection logic · 3 ledger closes required
XLS-66 WebSocket LIVE
WardMonitor subscribes to XLS-66 vault events. When health_ratio < 1.5, it requires 3 consecutive ledger closes before firing a verified default event — preventing single-block manipulation, flash crashes, and oracle noise.
XRPL Ledger
LoanManage tx stream
⚡ tfLoanDefault flag set
Ledger stream event via WebSocket
WardMonitor (institution infra)
⏱ Confirmation 1 / 3 ⏱ Confirmation 2 / 3 ✓ Confirmation 3 / 3
3 closes ≈ 12 seconds — anti-manipulation guarantee
Institution Handler
on_verified_default()
DefaultEvent → F·05 ClaimValidator
Institution owns execution — Ward only detects
Note: WardMonitor runs in the institution's own infrastructure, not Ward's servers. Ward provides the open-source detection algorithm. No transaction is produced — this is detection only.
↓ F·05
F·05
Claim Validation
9 deterministic checks · All query XRPL directly · No oracle · No off-chain data · Any failure rejects
ClaimValidator · 9 checks LIVE POST /api/v1/claims/file
No oracle. No off-chain data. No human judgment. All 9 checks query live XRPL state. All 9 must pass → unsigned EscrowCreate returned. Any failure → ClaimRejectedError with reason code and failed check index.
ClaimValidator (Ward SDK)
01
NFT exists, owned by claimant
XRPL account_nfts query · Error: NFT_NOT_FOUND
02
Policy not expired
current_ledger_index < expiry_ledger (from NFT URI) · Error: POLICY_EXPIRED
03
Vault address matches NFT URI
Prevents cross-vault attacks · Error: VAULT_MISMATCH
04
Default confirmed (3 ledger closes)
lsfLoanDefault across 3 closes · Error: DEFAULT_NOT_CONFIRMED
05
Health ratio provably breached
collateral_value / loan_value < 1.5 · Error: COLLATERAL_SUFFICIENT
06
No active escrow pending
Prevents double-settlement · Error: ESCROW_ALREADY_PENDING
07
KYC credential valid and unexpired
XLS-70 query · Error: KYC_CREDENTIAL_INVALID
08
Domain credential valid
XLS-80 registry · Error: DOMAIN_NOT_AUTHORIZED
09
Rate limit clear
No duplicate claim in window · Error: RATE_LIMIT_EXCEEDED
XRPL Ledger (live queries)
account_nfts server_info → current_ledger_index parse NFT URI hex → vault_id + expiry ledger_entry → XLS-66 Vault object Vault.health_ratio field LoanManage tx history (3 closes) ledger_entry → XLS-70 Credential XLS-80 domain registry account_nfts (absence check)
Steps 4–5 require XLS-66 on mainnet. Validated with mock fixtures (95/95 passing).
All 9 pass → unsigned EscrowCreate returned. ward_signed = False. Any step fails → ClaimRejectedError(reason_code, failed_check). No off-chain data source required or permitted at any step.
↓ F·06
F·06
Settlement
PREIMAGE-SHA-256 escrow · 48h dispute window · Policy NFT burns atomically · Ward server irrelevant after EscrowCreate
PREIMAGE-SHA-256 LIVE POST /api/v1/settlement/escrow
No custodian. No intermediary. XRPL is the settlement engine. Once EscrowCreate is confirmed on-chain, Ward's operational status is entirely irrelevant. EscrowFinish is permissionless — the XRPL ledger enforces payout automatically at FinishAfter.
Claimant
generate preimage (offline, secret)
Ward never sees the preimage — only the condition_hex
submit EscrowFinish + fulfillment_hex
+ NFTokenBurn (atomic)
After FinishAfter (+48h) — permissionless
Institution Wallet
create_escrow(condition_hex)
unsigned EscrowCreate Condition: SHA256(preimage) FinishAfter: now + 172800s (+48h) CancelAfter: now + 259200s (+72h) ward_signed = False
Institution signs and submits. Ward's role ends here.
XRPL Ledger
EscrowObject on-chain Funds locked — cryptographic condition ⏱ FinishAfter enforced by ledger
Payout released to claimant Policy NFT burned atomically Replay structurally impossible
Ward server irrelevant after EscrowCreate — ledger settles automatically
Key guarantee: Once EscrowCreate is on-chain, Ward's operational status is irrelevant. The XRP Ledger enforces payout at FinishAfter. EscrowFinish is permissionless — anyone can submit after maturity. CancelAfter (+72h) returns funds to institution if claimant never acts.
State Summary — All Transitions Are XRPL Native Transactions
Phase XRPL State Change Transaction Signer Ward Signs?
Vault registeredXLS-66 vault object + XLS-80 domain entryVaultCreate + AccountSetInstitutionNever
Credential issuedXLS-70 credential NFT (taxon=282) in depositor accountNFTokenMintInstitutionNever
Policy activePolicy NFT (taxon=281, tfBurnable) in depositor walletNFTokenMintInstitutionNever
Default confirmedDetection only — no state change requiredWebSocket eventNever
Claim validated9 on-chain reads — no writeRead-only queriesNever
Escrow createdEscrowObject on-chain, funds locked 48hEscrowCreateInstitutionNever
Claim settledXRP transferred to claimant, EscrowObject removedEscrowFinishClaimantNever
Policy burnedNFT absent from account_nfts — replay impossibleNFTokenBurnClaimant (atomic)Never
All state transitions are XRPL native transactions. No off-chain state is authoritative. Ward never signs. ward_signed = False — throughout.
API Reference → Protocol Architecture → ← Overview Brand →Brand → XRPLF #474 ↗ GitHub ↗
$ ward-protocol · transaction trace
Click to expand · F·01–F·06 live output