ar.io Logoar.io Documentation

Escrow

Trustless, multi-protocol escrow for handing an asset to a recipient identified by an Arweave or Ethereum address, claimable once they hold a Solana wallet. Backed by the ario-ant-escrow program. Two clients:

  • TokenEscrow — escrow liquid ARIO (SPL) or a time-locked vault.
  • ANTEscrow — escrow an ANT (Metaplex Core NFT).

Each supports deposit → claim → cancel/refund → update-recipient. Claims work three ways: Arweave-attested (an off-chain attestor re-signs the canonical claim with Ed25519, verified on-chain), Ethereum (on-chain secp256k1_recover

  • EIP-191), and vault (instruction introspection that preserves the remaining lock).
import { TokenEscrow, canonicalMessageV2 } from '@ar.io/sdk';

const escrow = new TokenEscrow({
  rpc,
  rpcSubscriptions,
  signer,
  programId,
  coreProgram,
});

// deposit 50 ARIO to an Ethereum recipient
await escrow.depositTokens({
  assetId, // 32-byte client-supplied id
  amount: 50_000_000n,
  arioMint,
  depositorTokenAccount,
  recipient: { protocol: 'ethereum', publicKey: ethAddress20 },
});

// the recipient claims (Ethereum path) once they have a Solana wallet
await escrow.claimTokensEthereum({
  depositor,
  assetId,
  claimant,
  claimantTokenAccount,
  escrowTokenAccount,
  signature, // recipient's EIP-191 signature over canonicalMessageV2(...)
});

Build the exact bytes a recipient signs with canonicalMessage / canonicalMessageV2 — byte-identical to the on-chain program (and the off-chain attestor). See the contracts repo's escrow design + protocol spec for the full flow and the cross-language canonical-message vectors.

How is this guide?