Live demo · Solana devnet

Two phones, one escrow.

Alice signs a payment with no internet; Bob settles it on devnet later. Bluetooth is simulated in the browser; signing and settlement are real devnet transactions.

Start the demo ↓ How Mora works
3 instructions · create · settle · close 84-byte voucher · Ed25519 signed No wallet needed · test SOL included

On-chain is small. Offline is a signature.

The program never sees Bluetooth. It only sees an Ed25519 verify ix, then settle.

Alice create_escrow Lock SOL in PDA
Offline sign voucher 84 bytes, no RPC
Relayer verify + settle Receipt PDA = nonce
Alice close_escrow After expiry

PDAs

escrow ← ["escrow", authority, seed]

receipt ← ["receipt", escrow, nonce] — init makes replay fail.

Voucher layout

MORAescrow 32nonce 8payee 32amount 8

Signer must be escrow.authority. Payee is in the bytes, not a settle signer.

Settle tx

Ix 0: Ed25519 native (self-contained). Ix 1: settle reads instructions sysvar, checks previous ix.

Demo only

BT bus is BroadcastChannel. Hash chain lives in localStorage. Neither is in the program.

1 · Open escrow → 2 · Go offline → 3 · Sign voucher → 4 · Settle → 5 · Close
press Run scenario to begin
Alice · Pay

Mora Pay

— not connected — Idle
🔌
Connect your wallet
Any Solana wallet on devnet. Tap the button up top.
Bob · POS

Mora POS

— receiver pending — Idle
🔌
Connect your wallet
Same wallet acts as the relayer — pays receipt rent + tx fee.
Technical notes for judges
  1. Press Run scenario. No wallet needed: the demo funds its in-browser test keys with devnet SOL. A wallet (Solflare, Phantom, Backpack…) is optional. If the demo faucet is ever empty, use faucet.solana.com.
  2. Open escrow: Alice locks SOL into a PDA (authority, seed). Real create_escrow.
  3. Sign voucher: 84-byte message "MORA" | escrow | nonce | payee | amount, Ed25519 locally. No RPC.
  4. Settle: Ed25519 native verify + settle. Receipt PDA makes the nonce unreplayable.
  5. Close: After expiry, close_escrow returns rent + remainder.