The escrow program
trench_escrow is an Anchor program on devnet. Every checkout creates and funds an escrow account in one buyer-signed transaction; the API verifies the account before it marks the order paid. The program is built and tested in CI.
- Cluster
- devnet
- Program id
- Dbrq2sACPk98FGzLihajJd4r2Q4jdKNn62GSURndv2kw
- PDA seeds
- escrow + order id
- Escrow window
- 48 hours
Accounts
The escrow account is a PDA seeded with the byte string escrow and the 16-byte order id. It stores the buyer, seller, resolver, and the buyback, AI verification, ops, and safety pubkeys, plus status, disputed_from, price, deposit, fee and rebate basis points, the four split basis points, expires_at, escrow_until, and the bump.
Instructions
- initialize
Buyer creates the escrow PDA and stores the seller, resolver, buckets, price, and fee.
- fund
Buyer transfers the quoted total into the escrow account. Status becomes paid.
- release
After escrow_until, price goes to the seller and the net fee is split to the four buckets.
- expire
After expires_at, an unpaid order becomes expired. No funds have been deposited.
- open_dispute
Buyer moves paid or released to disputed and stores the previous status.
- refund
Resolver returns the deposit to the buyer, and only when the dispute started from paid.
- reject_dispute
Resolver restores the order to paid or released.
States
Refunded and expired are terminal. Release and expire on the program are permissionless once the clock allows them. The buyer signs initialize, fund, and open_dispute.
- pending → paid
- pending → expired
- paid → released
- paid → disputed
- released → disputed
- disputed → paid
- disputed → released
- disputed → refunded
Resolver
The resolver pubkey is stored at initialize. Refund and reject_dispute require that pubkey as a signer. Refund pays the deposit back only when disputed_from is paid, because a release has already moved the lamports out of the account. The API holds the resolver key: its cron sends release after escrow_until, and resolving a dispute sends refund or reject_dispute. Release only moves funds out of paid, so a disputed escrow cannot be released. A refund after release is funded from the creator bond and then the safety bucket. Release pays every bucket directly, so each bucket wallet must already hold the rent-exempt minimum.