Solana
USDC with a memo per payment, and the dial_escrow program for people not on Dial yet.
What runs on Solana
- Payments move USDC with the SPL Token transferChecked instruction. The operator's treasury pays every fee and any token account rent, so Dial wallets never hold SOL.
- Every transfer carries its payment id (pi_…) in a Memo instruction, so each ledger row matches one transaction.
- Pay pages (/@handle) give a Solana Pay link (solana:…?spl-token=…) that any Solana wallet opens as a filled-in transfer.
- Every pay page is also a Solana Action, so a /@handle link unfurls as a Blink that any Solana wallet can pay.
- New accounts get a small drop of test USDC on Solana when they sign up.
Try it
Test money only. Solana is switched on here, so this settles on Solana devnet.
Text it
1 · Text hi and reply with a name. That's the signup.
Text hisend @handle $1 on solanaOn a laptop? Scan to open it on your phone
Swap @handle for anyone on Dial, or for a phone number. The operator texts back a 6-digit code; reply with it, and the receipt links the transaction.
Watch it settle
The newest payment on Solana devnet, from the ledger. Checks again every 30 seconds.
From an agent
send_payment {"to":"@handle","amountUsd":"1","chain":"solana"}The tool returns awaiting_approval, and the person who pays approves it by text. Setup is on /agents.
solana:<wallet>?amount=1&spl-token=4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU&label=Dial%20%C2%B7%20%40handleEvery pay page (/@handle) shows this link with the person's own address in place of <wallet>.
Built for Solana
What Solana lets the operator do beyond sending money, each with a demo you can use here. The demos only read: they send no texts and move no money.
On-chain escrow
Money for someone not on Dial waits in a program, not with Dial.
- dial_escrow, an Anchor program, holds money sent to a phone number that isn't on Dial yet. Only the operator's attestor key can release it, and only before it expires. The operator signs the release once the recipient replies with the code texted to that phone.
- After expiry anyone can call refund, and the money can only go back to the sender. Dial doesn't have to be up for it.
- Each escrow sits at an address derived from SHA-256 of the payment id, so anyone with the id from a receipt can find it on-chain.
Sender funds the vault
The payment moves into a vault the program owns, at an address derived from the payment id.
Recipient claims on attestation
Before expiry, the attestor key signs the claim once the recipient replies with the code texted to their phone.
Refund after expiry
From expiry on, anyone can send the refund, and the money can only go back to the sender.
Escrow program · on-chain
The program's explorer page lists every escrow it has opened, claimed and refunded.
Wallet pay links
Anyone can pay a Dial pay link from their own wallet.
- GET /api/actions/pay/<handle> describes the payment: who is paid, $1, $5 and $10 buttons, and a custom amount up to the per-payment limit. POST builds the USDC transfer for the payer's wallet to sign. /actions.json maps /@handle pages to it.
- Each transaction carries a fresh reference key. The operator finds the payment on-chain by that key, records it on the ledger once and texts the recipient a receipt.
- The payer needs no Dial account: any Solana wallet or Blink client can pay.
On the ledger
Read from the ledger on every visit. A chain is marked Live only once a payment has settled on it.
Recent payments · Solana devnet
Check it on-chain
Code
- Solana adapter
src/lib/settlement/solana.ts - dial_escrow program
solana/programs/dial_escrow/src/lib.rs - Program README
solana/README.md - Escrow client
src/lib/settlement/solana-escrow.ts - Program tests (LiteSVM)
tests/settlement/escrow-program.test.ts - Chain registry
src/lib/settlement/registry.ts - Pay links
src/lib/pay-links.ts