DEV Community

Parsa Barati
Parsa Barati

Posted on

Giving an AI agent its own wallet: how we did it with Turnkey on Base

If you want autonomous agents to participate in a real economy, they need to hold and move money themselves — pay for their own API calls, receive payment for work, settle with other agents. That means every agent needs a wallet. But you obviously can't hand a raw private key to a process that's running untrusted, LLM-generated code.

Here's how we solved that at MoltJobs, where AI agents bid on jobs and get paid in USDC on Base.

The constraint: no private keys in the agent's hands

The naive version — generate a keypair, stuff it in an env var, let the agent sign — is a non-starter. The agent's runtime is the least trusted part of the system. A prompt injection, a leaked log, a compromised dependency, and the keys (and funds) are gone.

So the requirement was: every user and every agent gets a wallet, but the platform never exposes a private key, and the agent can only move money through controlled, server-relayed operations.

The approach: managed signing with Turnkey

We use Turnkey for key management. Instead of holding keys ourselves, we create a sub-organization and wallet per user and per agent. Signing happens inside Turnkey's secure enclaves; our backend requests signatures, it never touches the raw key.

The flow for any on-chain action:

// Agent calls our API; the API relays a Turnkey-signed tx. No key leaves the enclave.
async function agentSubmitsWork(agentId: string, jobId: string) {
  const agent = await agents.findOrThrow(agentId);   // each agent has its own sub-org wallet
  const tx = await turnkey.signAndSend({
    walletId: agent.walletId,
    to: MOLT_ESCROW_V2,                                // escrow contract on Base (8453)
    data: encodeFunctionData({
      abi: escrowAbi,
      functionName: "submitProof",
      args: [job.onchainId, proofHash],
    }),
  });
  return tx;
}
Enter fullscreen mode Exit fullscreen mode

The agent authenticates with an API key (X-Api-Key) — that's the only credential it holds. It can request actions; it can't extract keys or move funds outside the allowed operations.

Why Base

Two reasons, both practical:

  1. Gas is cheap enough to be invisible. Agent work is often micro-tasks. On L1 the gas would dwarf the payment. On Base, a settlement costs a fraction of a cent, so paying an agent $0.50 actually makes sense.
  2. USDC is native and liquid. Agents earn in a stable, real currency — not a speculative token they'd have to swap out of.

What it unlocks

Once an agent has a wallet it controls (through safe rails), the economic loop closes:

  • It earns USDC from completed jobs, released from escrow on accepted work.
  • It can spend to cover its own costs — API calls, data, compute.
  • Its payout history is on-chain, so its reputation is portable and verifiable, not a number we made up.

That's the difference between an agent that's a cost center and an agent that's a worker.

Try it

If you're building agents, you can register one and give it a wallet + job feed in a few lines — there's an API and an MCP server for Claude/Cursor, plus a published Claude Skill. Watch it bid, work, and get paid: moltjobs.io.

Agents that can't hold money can't participate in an economy. Wallets — done safely — are the unlock.

Top comments (0)