Secondary market for XRPL-native institutional credit. Principal/interest tokenisation (STRIPS) of XLS-66 positions, built entirely on XRP Ledger native primitives.
Live demo: wiftfinance.vercel.app | App
XRPL Hackathon, April 2026.
XRPL has activated on-chain credit via XLS-65 (SingleAssetVault) and XLS-66 (Lending Protocol). Institutional issuers can now originate fixed-term loans on-chain with identity verified via Credentials.
One critical piece is missing: the secondary market.
A depositor who funds a LoanBroker is locked until maturity. No early exit. No price discovery on issuer quality. No risk transfer. No yield curve.
US Treasury STRIPS solved this in 1985: splitting a bond into principal + coupons. That primitive generated a multi-trillion dollar market. Pendle applied it to DeFi on EVM and reached $5B+ TVL.
Wift brings STRIPS to XRPL.
A wrapper that takes one SingleAssetVault share and splits it into two tradable tokens:
| Token | Represents | Redemption at maturity T |
|---|---|---|
| PT (Principal Token) | Right to the vault principal | min(1, NAV_T) per PT |
| YT (Yield Token) | Right to the yield accrued | max(0, NAV_T − 1) per YT |
PT and YT trade on the native XRPL DEX (OfferCreate order book). The PT price is the implied fixed rate. Multiple brokers x multiple maturities = a full credit curve.
┌──────────────────────────────────────────────────────────────┐
│ XRPL L1 │
│ │
│ ┌────────────────┐ ┌──────────────────┐ │
│ │ SingleAsset │ │ LoanBroker │ │
│ │ Vault (XLS-65) │────▶│ (XLS-66) │ │
│ │ shares = MPT │ │ originate loans │ │
│ │ NAV ++ │ │ collect repays │ │
│ └────┬───────────┘ └──────────────────┘ │
│ │ share MPT │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ Wift Wrapper │ │
│ │ (pseudo-account, 3/5 multisig) │ │
│ │ │ │
│ │ lock share → mint PT + YT (IOU) │ │
│ │ burn PT+YT → release share │ │
│ └────┬──────────────────┬────────────────┘ │
│ │ PT (IOU) │ YT (IOU) │
│ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ │
│ │ DEX PT/ │ │ DEX YT/ │ │
│ │ XRP │ │ XRP │ │
│ │ (native) │ │ (native) │ │
│ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │
└─────────┼──────────────────┼─────────────────────────────────┘
│ │
▼ ▼
Price discovery Leveraged yield
Fixed-rate lock Credit speculation
Zero smart contracts. Zero sidechain. Zero third-party oracles.
| Component | Role | Tech |
|---|---|---|
| Local rippled | Standalone node with XLS-65/66 via [features] trick |
rippleci/rippled:develop Docker |
| Wrapper | 3/5 multisig pseudo-account, enforces PT/YT mint/burn | XRPL SignerListSet + MPT |
| Seeder | 3 brokers x 3 maturities = 9 series | Python + xrpl-py |
| Indexer + API | Polls ledger state, serves REST API for the dashboard | FastAPI + Postgres |
| Arb bot | Walks PT prices to maintain credit curves | Python, continuous loop |
| Dashboard | Full trading UI: markets, trade, mint, redeem, portfolio, explorer | Next.js 16 + Tailwind v4 |
| Landing | Product page with animations | Next.js 16 + Framer Motion |
- 9 live series across 3 credit profiles (safe / medium / risky) x 3 maturities (30 / 90 / 180 days)
- Reactive order book polling every 1.5s from the native XRPL DEX
- Market + limit orders with IOC flag for market orders, resting book for limits
- Buy and sell PT/YT with proper OfferCreate flag handling
- Wallet extensions: GemWallet, Crossmark support + seed-based demo wallets
- Real balance: extension wallets query their actual network (devnet/testnet/mainnet)
- Credit curve: implied YTM per broker, reconstructed from live PT prices
- Explorer: lookup any tx hash or account, view open orders
- Invariant enforcement:
shares_locked == PT_supply == YT_supplychecked on every poll cycle
The ledger/wift-node/ directory contains a complete WASM smart contract (Rust, Bedrock SDK) that replaces the multisig wrapper with on-chain enforcement:
split()— lock shares + mint PT/YT in a single atomic call, invariant enforced by the ledgerredeem()— burn PT/YT at maturity, payout computed on-chain from vault NAVregister_series()— admin: register new broker/maturity seriesget_state()— read-only: query invariant status
Status: written but not deployed. The current Bedrock runtime does not support XLS-65/66 amendments alongside XLS-101d. Once a unified rippled build is available, the contract deploys as a drop-in replacement — same pseudo-account, same PT/YT IOUs, zero breaking change for existing holders. Trust assumption goes from 3/5 signers to zero.
See ledger/wift-node/README.md for details.
# 1. Boot the full stack (Docker + Postgres + rippled + seeder + API)
scripts/demo-up.sh
# 2. Run the dashboard
cd frontend/app && npm install && npm run dev
# 3. Run the landing page
cd frontend/landing && pnpm install && pnpm devThe app runs on localhost:3001, landing on localhost:3000, API on localhost:8000.
- Frontend: Vercel (see
docs/DEPLOY.md) - Backend: Cloudflare tunnel or Railway (Dockerfile provided)
- Rippled: Local standalone Docker container
VaultCreate/VaultDeposit(XLS-65)LoanBrokerSet(XLS-66)SignerListSet+ multisigPayment(3/5 quorum)MPTokenIssuanceCreate/MPTokenAuthorize(XLS-33, for vault shares)TrustSet+ IOUPayment(for PT/YT tokens)OfferCreatewithTF_IMMEDIATE_OR_CANCEL/TF_SELLflags (native DEX)
At maturity T:
- 1 PT redeems
min(1, NAV_T)— full principal if NAV >= 1 - 1 YT redeems
max(0, NAV_T − 1)— pure yield, profit only when NAV > 1 - 1 PT + 1 YT always redeems exactly 1 vault share (market-neutral)
Default waterfall: PT absorbs principal loss, YT goes to zero. Senior/junior risk tranching built into the PT/YT split.
v1 (current): 3-of-5 multisig pseudo-account. Relayers enforce public, deterministic issuance rules.
v2 (post XLS-101d): enforcement moves on-chain via native WASM smart contracts. Trust assumption drops to zero. No breaking change for existing PT/YT holders.
Building on bleeding-edge XRPL amendments meant navigating uncharted territory:
Amendment availability: XLS-65 (SingleAssetVault) and XLS-66 (LendingProtocol) were not yet enabled on devnet or alphanet at the time of the hackathon. We proposed activation to validators but couldn't wait — we pivoted to a local standalone rippled (rippleci/rippled:develop) with a [features] config trick that bypasses amendment voting by injecting features directly into the Rules presets.
AMM incompatibility with IOUs: our initial design used the native XRPL AMM for PT/YT price discovery. AMMCreate returned temDISABLED on our local build despite the AMM feature being listed. We pivoted to OfferCreate (native DEX order book) — this actually proved superior for a STRIPS market since limit orders better model institutional credit trading.
MPT rejection in AMM: PT and YT were initially designed as MPTs (Multi-Purpose Tokens). AMMCreate rejected MPT amounts with "Amount can not be MPT". We pivoted to IOU trustlines — functionally equivalent, with the bonus of being compatible with the full DEX infrastructure.
Smart contract runtime gap: the XLS-101d Bedrock runtime doesn't support XLS-65/66 amendments. We wrote the full trustless smart contract (see ledger/wift-node/) but couldn't deploy it alongside our vault infrastructure. The multisig wrapper serves as the functional v1 with a clear migration path.
Standalone rippled quirks: submit_and_wait hangs on standalone mode because ledgers don't auto-advance. We built a submit_local helper that spawns a background thread to call ledger_accept in a loop during submission.
Each pivot narrowed the design but kept everything on native XRPL primitives — no sidechains, no oracles, no off-chain workarounds.
Built by skar8848 and Abaresks24 at the XRPL Hackathon, April 2026.
- US Treasury STRIPS (1985)
- Pendle Finance — PT/YT on EVM
- Morpho Blue — minimal composable primitives