# Ekx Coinbase Cdp

> Coinbase Developer Platform and OnchainKit — CDP server wallets for agent-controlled keys, AgentKit with LangChain for onchain AI agents, OnchainKit React components (Wallet, Swap, Checkout, Identity), and Base App / Farcaster miniapp integration. Use when an agent rather than a person must hold a key, or when building with OnchainKit components.

- Skill: `ekinoxis-evm/ekx-coinbase-cdp` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ekinoxis-evm/ekx-coinbase-cdp`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ekinoxis-evm/ekx-coinbase-cdp/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: Ekinoxis-evm (https://skillmd.com/u/ekinoxis-evm)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ekinoxis-evm/ekx-coinbase-cdp

---


# Coinbase CDP + OnchainKit

Two distinct things from the same vendor:

- **CDP Server Wallets** — keys held by our backend, so an *agent* can transact.
- **OnchainKit** — React components for Base dApps.

Portal: https://portal.cdp.coinbase.com · Docs: https://docs.cdp.coinbase.com

---

## When CDP instead of Privy

| Need | Use |
|---|---|
| A *person* logs in and gets a wallet | **Privy** ([skill](../ekx-privy/SKILL.md)) |
| An *agent/backend* signs autonomously | **CDP server wallet** |
| Base-native UI components | **OnchainKit** (works alongside either) |

An agent app needs CDP when its LangGraph agent books and moves USDC without
a human clicking. That is the only justification for a server-held key — if a human is
in the loop, use Privy.

---

## Environment

```bash
CDP_API_KEY_ID=                 # SECRET
CDP_API_KEY_SECRET=             # SECRET
NEXT_PUBLIC_CDP_PROJECT_ID=     # public
AGENT_WALLET_ID=                # SECRET — the persisted wallet id
```

---

## Server wallets

```ts
import { CdpClient } from "@coinbase/cdp-sdk";

const cdp = new CdpClient({
  apiKeyId: process.env.CDP_API_KEY_ID!,
  apiKeySecret: process.env.CDP_API_KEY_SECRET!,
});

const account = await cdp.evm.getOrCreateAccount({ name: "rental-agent" });

const { transactionHash } = await cdp.evm.sendTransaction({
  address: account.address,
  network: "base-sepolia",
  transaction: { to: USDC, data: encodedTransfer, value: 0n },
});
```

**Persist the wallet id.** A server wallet that is re-created on each deploy is a new
address with no funds and no history — and the old one's balance is stranded. Store
`AGENT_WALLET_ID` in the environment and look it up, never create blindly.

**Fund the agent wallet with a float, not a treasury.** It signs without human
approval by definition; cap the blast radius.

---

## AgentKit

`@coinbase/agentkit` + `@coinbase/agentkit-langchain` expose onchain actions as LLM
tools, driven by `@langchain/langgraph`.

```ts
const agentkit = await AgentKit.from({ walletProvider });
const tools = await getLangChainTools(agentkit);
const agent = createReactAgent({ llm, tools, checkpointSaver: memory });
```

Note this is the **one place in the portfolio using LangChain and OpenAI** — inherited
from the AgentKit starter. Everything else is the Anthropic SDK directly
([skill](../ekx-anthropic-sdk/SKILL.md)). On a rebuild, prefer Claude with
native tool use over the LangChain layer; the abstraction earns little here.

**Constrain the tool set.** AgentKit ships transfer and trade actions by default. An
agent with an unbounded `transfer` tool and a funded wallet is one prompt-injection
away from being drained. Register only the actions the product needs.

---

## OnchainKit

```tsx
import { OnchainKitProvider } from "@coinbase/onchainkit";
import { base } from "viem/chains";

<OnchainKitProvider apiKey={process.env.NEXT_PUBLIC_CDP_PROJECT_ID} chain={base}>
  {children}
</OnchainKitProvider>
```

Components worth using rather than rebuilding: `<Wallet />` (connect + dropdown),
`<Identity />` / `<Name />` / `<Avatar />` (ENS + Basename resolution),
`<Swap />`, `<Checkout />`, `<Transaction />` (handles the receipt-waiting and status
UI we otherwise hand-roll).

Add `@farcaster/miniapp-wagmi-connector` to run as a Base App /
Farcaster miniapp — the connector replaces the normal wallet connection when the app
is embedded in a Farcaster client.

**OnchainKit needs its own stylesheet:** `import "@coinbase/onchainkit/styles.css"`.
Missing it renders unstyled components, which reads as broken rather than unstyled.

---

## Gotchas

1. **Re-created server wallets strand funds.** Persist the id.
2. **Unbounded agent tools + funded wallet = drainable.** Constrain.
3. **`styles.css`** import for OnchainKit.
4. **Identity components need an L1 RPC** for ENS. Basenames resolve on Base; `.eth` does not.
5. **CDP network names are strings** (`"base-sepolia"`), not chain ids.

