Venues & custody

A venue is where a trade happens. Every venue sits behind the same adapter interface with one activation handshake β€” your integration code does not branch per venue β€” but each venue keeps its own custody model, because that is what makes the system non-custodial rather than non-custodial-in-name.

The venue model

The rule across all venues: the execution service can submit trades, it can never withdraw. What enforces that differs per venue and is listed below β€” it is always the venue's own credential mechanism, never a policy promise.

Venue reference

  • Name
    spot
    Type
    live
    Description

    Spot copying on EVM. Custody: an ERC-7579 smart session scoped to swap routers with an explicit spend cap and hard expiry β€” it cannot transfer tokens out and dies at validUntil. Activation: one on-chain transaction (enable session); gas paid by the user or a paymaster. Requires an ERC-7579 smart-account wallet.

  • Name
    hyperliquid-perps
    Type
    live
    Description

    Perps copying on Hyperliquid. Custody: an agent key the user approves in their own wallet and can revoke at any time; agent approvals do not expire. Activation: 1–2 signatures, no gas, works from any EOA.

  • Name
    polymarket-predictions
    Type
    sandbox
    Description

    Prediction-market copying on the Polymarket CLOB. Custody: an ERC-7579 smart session scoped to order signing β€” the exchange asks the user's own account to validate every order signature (ERC-1271), and the account's on-chain session validator decides what it will honour. A fully compromised backend could sign bad orders; it cannot move a cent. Activation: a one-time transaction deploying the user's account on Polygon (Polymarket requires a deployed maker; gas paid by the user or sponsored by you) plus the session install. Prediction risk config adds maxSlippagePoints and minHoursToResolution. Regional note: Polymarket rejects new orders from a number of regions (US, UK, DE and others) β€” the restriction follows the end user, and the venue's availability block lists the codes.

Which wallets land where

The deciding question per venue is what the end user's account can do β€” not which wallet brand they use. Three facts save integrators the most debugging:

  • "Smart account" is not enough β€” spot and predictions need ERC-7579. MetaMask's smart-account mode (EIP-7702) delegates to MetaMask's own delegation framework, which has no ERC-7579 module surface β€” MetaMask users are perps-only today, even after upgrading. A MetaMask lane built on that framework's own scoped delegations is in development; its activation step (client_delegation_grant) already ships explained in the SDK, so an integration written today renders it correctly when it arrives. The same applies to other non-7579 smart accounts (e.g. Coinbase Smart Wallet).
  • Privy / Dynamic default embedded wallets are plain EOAs. They qualify for perps immediately. Your users are in the spot column only if your provider's smart-wallets feature is enabled on an ERC-7579 implementation (e.g. Kernel).
  • A plain EOA can never do non-custodial spot copy β€” for anyone. One key, unlimited authority, no mechanism to scope it. Any product offering spot copy to plain EOAs holds either the user's key or their funds. This matrix is the honest boundary, not a missing feature.

Expiring credentials

Hyperliquid agent approvals do not expire. Smart sessions do β€” spot and Polymarket credentials both end at the session's validUntil. Handle the session.expiring signal and re-run activate() to renew.

An agent whose credentials lapse moves to status expired. This is deliberately distinct from paused: an expired agent needs the user to re-authorise in their wallet, not just a resume call from your app.

Agent status

  • Name
    active
    Type
    status
    Description

    Credentials valid, mirroring the leader.

  • Name
    paused
    Type
    status
    Description

    Stopped by the user or your app; resumable without re-authorisation.

  • Name
    expired
    Type
    status
    Description

    Credentials lapsed; the user must re-authorise via activate(). Not resumable silently β€” surface it in your UI.

Was this page helpful?