Escrow

Trustless P2P token swaps with PDA-based escrow vaults

Deployed Anchor 0.32
Program ID FKz12mj5HcA9wJRTmpEN2mstdat7KVrwJyy1QULaVi4J
Binary Size 315K
Cluster Devnet

Instructions

IX make_offer

Creates a new escrow offer, depositing tokens into a PDA vault.

ParameterTypeDescription
seedu64Unique seed for deriving the escrow PDA
offer_amountu64Amount of token A to offer
want_amountu64Amount of token B desired in return
IX take_offer

Accepts an existing escrow offer, completing the token swap between both parties.

ParameterTypeDescription
No parameters
IX cancel_offer

Cancels the escrow and returns deposited tokens to the maker.

ParameterTypeDescription
No parameters

Accounts

Escrow

FieldTypeDescription
makerPubkeyThe wallet that created the escrow offer
mint_aPubkeyMint address of the offered token
mint_bPubkeyMint address of the desired token
offer_amountu64Amount of token A offered
want_amountu64Amount of token B requested
seedu64Unique seed for PDA derivation
bumpu8PDA bump seed

PDA Derivation

escrow
seeds = [b"escrow", maker, seed.to_le_bytes()]
vault
seeds = [b"vault", escrow]

Error Codes

InvalidAmount The offer or want amount must be greater than zero
OfferExpired The escrow offer has expired and can no longer be taken

Usage Example

import { Program, AnchorProvider } from "@coral-xyz/anchor";
import { PublicKey } from "@solana/web3.js";
import { getAssociatedTokenAddress } from "@solana/spl-token";

const seed = new BN(1);
const offerAmount = new BN(1_000_000);
const wantAmount = new BN(500_000);

// Derive the escrow PDA
const [escrowPda] = PublicKey.findProgramAddressSync(
  [Buffer.from("escrow"), maker.publicKey.toBuffer(), seed.toArrayLike(Buffer, "le", 8)],
  program.programId
);

// Create the escrow offer
await program.methods
  .makeOffer(seed, offerAmount, wantAmount)
  .accounts({
    maker: maker.publicKey,
    mintA,
    mintB,
    escrow: escrowPda,
  })
  .signers([maker])
  .rpc();