How do AI agents trade on Solana non-custodially?¶
An AI agent trades non-custodially on Solana when it never holds a private key. It calls a service that builds an unsigned transaction; a policy gate stack enforces the wallet owner's limits before that transaction is even built; and a signer the platform never controls — the human's own wallet, or a key the agent process holds outside the platform — signs and broadcasts it. Crank implements this pattern end-to-end over MCP, with a paper-trading mode so an agent (or the person running it) can prove the flow works before anything is signed for real.
This page walks through the three parts of that answer: the unsigned-tx flow, the gate stack that runs before a transaction is built, and the paper-first path onto it.
The unsigned-transaction flow¶
Every value-bearing Crank tool call follows the same shape:
- The agent asserts a public key. The caller passes
wallet_address— a public key only — as a top-level argument. It is never inferred from anywhere else in the call. - The gate stack runs. See below. Nothing is built or charged until the call clears every layer.
- Crank builds the transaction and returns it unsigned. The response contains a base64-encoded, unsigned transaction (or, for a venue-custodied perps venue, a signing payload) — never a signature, never a private key.
- The caller signs locally. Signing happens in the caller's own process, with a key Crank has never seen.
- The caller broadcasts it (directly, or by passing
signed_transactionback to Crank to relay).
result = await client.call_tool("jupiter_swap", {
"input_token": "So11111111111111111111111111111111111111112",
"output_token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"amount": 100_000_000,
"wallet_address": "<YOUR_AGENT_PUBLIC_KEY>",
"caller_id": "my-agent",
})
if result["ok"]:
unsigned_tx = result["transaction"] # base64, unsigned
# sign locally with YOUR key, then broadcast (or pass back as signed_transaction)
No code path transmits, stores, or logs a private key or seed phrase. That is not a configuration option — it is the only path a value-bearing tool has. Full walkthrough: Quickstart; every transport that carries this same call shape: Integration guide.
The policy gate stack¶
Before step 3 above — before a transaction is even constructed, and before any fee is charged — every value-bearing call passes a six-layer gate:
| Layer | What it checks |
|---|---|
| Rate limit | Caller isn't exceeding its call budget. |
| Global kill switch | Platform-wide emergency stop is not engaged. |
| Wallet policy | The action is inside limits the wallet owner set: max trade size, daily spending limit, token allowlist/banlist, position limit, drawdown limit, per-wallet kill switch. |
| Launch guard | Pre-mainnet rollout controls (soft-launch gating) permit the action. |
| x402 payment | The technology service fee, if owed past the daily free tier, has a valid payment attached. |
| Transaction verification | The constructed transaction only touches programs on a known-good allow-list, with anti-drainer checks. |
The wallet policy layer is what makes this useful for an autonomous agent
specifically: a human sets max_trade_size, daily_limit, approved_tokens,
position_limit, drawdown_limit, and a kill_switch once, on a wallet they
still fully control, and every subsequent agent-initiated action is checked
against it server-side — before the agent's own decision-making even reaches a
transaction. An action a policy would refuse is never billed: the gate order
puts wallet policy ahead of the payment step.
Full detail on wallet provisioning and the gate's error codes: Authentication & x402.
Paper-first: prove the flow before you sign anything¶
An agent (or the person building it) does not have to trust this description — Crank exposes an identical tool surface in paper mode: real mainnet quotes, simulated fills, the same gate stack, the same journal. A strategy or an agent graduates from paper to live execution without any code change — same tool names, same arguments, same response shape. Live execution still requires the owner's own key to sign every transaction; nothing about paper mode changes the non-custodial contract, it only changes whether a fill is simulated.
Why the unsigned-tx flow plus the gate stack matters¶
A common alternative pattern for giving an LLM on-chain capability is handing the agent process a raw private key — often directly in an environment variable — with no server-side check on what it is allowed to do with that key. That pattern is simple to wire up, and it works, but every layer of protection then lives inside the same process the agent is running in: if the key leaks or the agent's logic misfires, there is no independent check that runs before a transaction goes out. Crank's model keeps the two things structurally separate: the platform never has a key to leak, and the policy gate is enforced somewhere the agent's own reasoning cannot bypass it, on a wallet the owner never gives up control of. See how this compares point-by-point against specific toolkits: Compare. That same trade-off applies to managed wallets too: an autonomous agent can run on a Turnkey TEE-managed signer instead of self-signing, giving up key portability in exchange for unattended autonomy — see Agent wallet provisioning for the full choice and how to opt in.
Next¶
- Quickstart — call your first tool in a few minutes.
- Authentication & x402 — wallet binding, the payment gate, and managed-wallet policy provisioning in full.
- Fee schedule — what a value-bearing action costs.
- Compare — Crank against Solana Agent Kit, GOAT SDK, and Coinbase AgentKit.
- FAQ — install, cost, custody, and venue coverage in short form.