Copy Trading
Add non-custodial copy trading to your wallet, terminal or app. One REST API and a typed TypeScript SDK (copytrading) let your users mirror proven traders on spot and Hyperliquid perps — through credentials they approve in their own wallet and can revoke at any time.
These are the same rails Unhosted runs in production: the Alpha Terminal and the Unhosted Wallet both integrate through the same public SDK described here.
How custody works
The execution service can submit trades; it can never withdraw. This is enforced by the venue's own credential model, not by policy:
- Spot runs through an ERC-7579 smart session — a scoped, expiring permission that lets the backend's session key call swap routers on the user's account and nothing else. It carries an explicit spend cap, cannot transfer tokens out, and stops working on its own at
validUntil. - Hyperliquid perps run through an agent key the user approves in their own wallet and can revoke at any time. Works from any EOA — no smart-account stack required.
- Polymarket predictions run through the same ERC-7579 smart session, scoped to order signing: the exchange asks the user's own account to validate every order (ERC-1271), so the session key can sign orders and nothing else. Currently executes in sandbox while order signing finishes review.
Start with perps if you want the shortest path: one signature loop, no gas, no smart-account infrastructure — any EOA your users already have. Spot and predictions require an ERC-7579 wallet stack; note that MetaMask’s smart-account mode is not ERC-7579 (a MetaMask lane is in development) and Privy/Dynamic default embedded wallets are plain EOAs unless smart wallets are enabled — see Venues for who lands where.
Authentication
Every owner-scoped call carries two credentials, because two different parties are involved:
- Name
Authorization- Type
- Bearer key_live_…
- Description
Your partner API key — identifies your app and is what gets billed. Keys are SHA-256 hashed at rest, shown exactly once at creation, and scoped with per-venue entitlements.
- Name
X-Wallet-Signature- Type
- header set
- Description
The end user's wallet signature (with
X-Wallet-AddressandX-Auth-Timestamp) — identifies whose funds move. An EIP-191personal_signover a canonical message naming the HTTP method and path, so a captured signature cannot be replayed against another route. Expires after 5 minutes.
Neither credential alone is sufficient. Do not hand-roll the signed message — the address must be EIP-55 checksummed, and a lowercase address signs a different message and returns a bare 401. Use the SDK helper:
import { CopyTradingClient, createWalletAuthHeaders } from 'copytrading'
const client = new CopyTradingClient({
baseUrl: API_URL,
apiKey: PARTNER_KEY,
// Build this ONCE and reuse it — it holds the monotonic timestamp counter
// that prevents replay rejections.
getAuthHeaders: createWalletAuthHeaders({
address: userAddress,
signer: { signMessage: (message) => wallet.signMessage(message) },
}),
})
Leaders
listLeaders is not the venue's leaderboard. It is the leaderboard after copyability gates — a much shorter list. On one live Polymarket screen, 2 of the top 12 by monthly PnL survived the gates; the rest were market makers whose fills a follower crossing the spread cannot reproduce.
Each leader carries an assessment with plain-language reasons. Render them — the reasons are the product — and assessment.evidence tells you whether the verdict rests on real trade history or only on the venue's own figures.
Venue spot has no venue leaderboard at all, so its board is our own discovery: wallets repeatedly among the first buyers of tokens that later pumped, admitted only if a delayed-copier simulation over their recorded entries stays net-positive after costs and they clear an independent trader-quality gate — being early is a signal, being copyable at your follower's delay is the bar. assessment.evidence reads delay-simulation there, rows carry a disclosure field naming the hindsight in the simulated numbers (surface it), and the gate's own forward record serves at /v1/traders/track-record?source=spot-leader-gate. An empty spot board is a state, not an error — it means nothing currently clears the gates.
Skipped copies are normal and first-class: a mirror that would have been worse than not trading is recorded with status: 'skipped' and a machine-readable skipReason (slippage_exceeded, edge_exhausted, too_close_to_resolution, …). Show them in your feed — a silent gap reads as a bug to your users.
See it live
- unhosted.ai/alpha/copytrade — our consumer copy-trading surface: leader grading, activation and the execution feed, running on this API.
- unhosted.com — the Unhosted smart-account wallet; its mobile app integrates through this SDK, and its ERC-7579 stack is what the spot custody model is built on.
Integration is free and self-serve: sign up at unhosted.ai/partners and you have a scoped API key against the paper-mode sandbox in minutes (real leader data, full activation flow, no funds at risk), then flip to live execution once your flows are proven. Prefer to talk it through first? Book an integration call.