Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

solana-escrow-app

Web UI for the AR.IO ario-ant-escrow program — trustless multi-protocol escrow for ANTs, ARIO tokens, and time-locked vaults (Arweave RSA-PSS-4096 / Ethereum ECDSA secp256k1).

Forked from the AR.IO Solana registration app. Same wallet plumbing (Phantom, Solflare, Wander, MetaMask, WalletConnect), Vite build, and visual identity. The migration registration app sunsets after cutover; this fork repurposes that codebase as the long-lived multi-protocol ANT-escrow UI.

Pages

/#/                    Landing — explainer + links to flows
/#/deposit             Deposit ANT into escrow
/#/deposit-tokens      Deposit liquid ARIO tokens into escrow
/#/deposit-vault       Deposit a time-locked vault into escrow
/#/claim?ant=…         Recipient flow (verify + sign + claim ANT/tokens/vault)
/#/manage?ant=…        Depositor management (update_recipient + cancel)
/#/lookup?ant=…        Read-only escrow inspector (no wallet needed)

The shell, routing, wallet adapters, and signing components are all in place. The on-chain submit handlers are stubbed ("devnet wiring pending") until the program ships to devnet (Phase 8 of docs/ANT_ESCROW_IMPLEMENTATION_PLAN.md).

Dev

yarn install
yarn dev      # vite, port 5173
yarn build    # tsc + vite build → dist/

yarn dev reads the RPC URL from VITE_SOLANA_RPC_URL (defaults to mainnet-beta). Point at devnet for testing:

VITE_SOLANA_RPC_URL=https://api.devnet.solana.com yarn dev

Attestor URL (Arweave claims)

Arweave-recipient claim flows POST the user's RSA-PSS signature to the off-chain AR.IO attestor service, which re-signs the canonical claim message with Ed25519. The on-chain program then verifies the cheap Ed25519 signature via Solana's native sigverify program. Without an attestor URL, Arweave claims fail at submit time with a clear error. Ethereum claims do not require the attestor (they verify directly on-chain via secp256k1_recover).

VITE_ATTESTOR_URL=http://localhost:3030 yarn dev

The page calls the attestor's /health once before issuing an attestation and refuses to proceed if health.network doesn't match the network the page was loaded with. See migration/attestor/README.md for the service contract and docs/DECISIONS.md ADR-017 for the architecture rationale.

Token and Vault Flows

The Deposit Tokens page transfers liquid ARIO tokens from the depositor's wallet into an escrow-owned token account. The Deposit Vault page escrows a time-locked vault position from ario-core.

Vault claim behavior: When a claimant claims an active vault (lock not yet expired), the app builds a transaction containing both the escrow claim_vault_* instruction and a sibling ario_core::vaulted_transfer instruction. The escrow program verifies the sibling instruction via sysvar::instructions introspection (same pattern as Solana's Ed25519 precompile). Tokens transfer to the payer's ATA first, then the vaulted_transfer creates a time-locked vault for the claimant. Expired vaults are claimed as liquid SPL transfers (no vaulted_transfer needed).

Components inherited from the registration app

These already do exactly what the escrow app needs — zero changes:

Component What it gives us
SolanaWalletConnect Phantom / Solflare / Wander connect; depositor + claimant tx submission
ArweaveWalletConnect Wander / ArConnect; Arweave-recipient claim signing
EthereumWalletConnect MetaMask / WalletConnect; Ethereum-recipient claim signing
SourceAddressSigner Multi-protocol signing dispatcher (abstracts per-wallet APIs)
SourceWalletConnect Wallet selection UI
WalletIcons Branding

What was stripped

  • useTurboAttestation, useAttestationStatus, useAOAssetLookup — Turbo bundler integration is registration-specific.
  • RegistrationProgress, ExistingRegistrationCheck, CountdownTimer — registration-window UX.
  • ao-asset-lookup.ts — AO process lookups (the escrow app reads only Solana state).
  • RegisterPage, StatusPage — replaced by Deposit / Deposit Tokens / Deposit Vault / Claim / Manage / Lookup.

Wiring the SDK call paths (Phase 8 follow-up)

Each page has a stubbed submit button labelled "(devnet wiring pending)". To wire it up against a deployed devnet program:

  1. Bump the @ar.io/sdk dep to the version that exports ANTEscrow from @ar.io/sdk/solana (it ships in the same PR as the program).
  2. Per page, instantiate the client:
    import { ANTEscrow } from '@ar.io/sdk/solana';
    const escrow = ANTEscrow.init({ rpc, rpcSubscriptions, signer });
  3. Replace the stub <button disabled> with the real call:
    await escrow.deposit({
      antMint,
      recipient: { protocol, publicKey },
    });
  4. For the claim page, fetch escrow state first to drive the signing flow:
    const state = await escrow.get(antMint);
    const message = canonicalMessage({
      network: 'solana-mainnet',
      antMint,
      claimant,
      nonce: state.nonce,
    });
    const signature = state.recipientProtocol === 'arweave'
      ? await arweaveWallet.signMessage(message)
      : await ethereumWallet.signMessage(message);
    await escrow.claimArweave({ antMint, claimant, signature, saltLen: 32 });

Stack

  • React 18 + TypeScript + Vite (same as solana-registration-app)
  • @ar.io/sdk — escrow client + canonical-message helper
  • @solana/kit — tx pipeline
  • @solana/wallet-adapter-* — Solana wallet connection
  • arweave-wallet-kit (via SourceWalletConnect) — Arweave wallet
  • ethers — Ethereum signing & address derivation

License: AGPL-3.0-or-later (matches the rest of the repo).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages