Copy Trading
Add non-custodial copy trading to your wallet, terminal or app. One REST API and a typed TypeScript SDK (@zifrovoy-wallet/copy-trading) 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.
Start with perps if you want the shortest path: one signature loop, no gas, no smart-account infrastructure. Spot requires an ERC-7579 wallet stack β see Venues.
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 '@zifrovoy-wallet/copy-trading'
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.
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.
To integrate, email hi@unhosted.ai β you'll get a scoped API key and a sandbox in paper mode (real leader data, full activation flow, no funds at risk), then flip to live execution once your flows are proven.