> ## Documentation Index
> Fetch the complete documentation index at: https://daehan-base.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 에이전트 지갑 설정

> AI 에이전트에게 Base에서 자금 보유, 결제 전송, 메시지 서명, 온체인 프로토콜과의 안전한 상호작용을 위한 전용 지갑을 제공합니다.

export const WalletSetupDemo = () => {
  const mono = "ui-monospace,'Cascadia Code','Source Code Pro',Menlo,Monaco,Consolas,monospace";
  const col = {
    dim: "#3f3f46",
    muted: "#52525b",
    active: "#60a5fa",
    success: "#34d399",
    code: "#d4d4d8"
  };
  const flows = {
    cdp: [{
      delay: 400,
      left: [{
        t: "> npx skills add coinbase/agentic-wallet-skills",
        c: "active"
      }],
      right: [{
        t: "── wallet.config.json ──────────────────",
        c: "dim"
      }, {
        t: "{",
        c: "code"
      }]
    }, {
      delay: 600,
      left: [{
        t: "  ✓ skill installed",
        c: "success"
      }],
      right: [{
        t: '  "provider": "coinbase",',
        c: "code"
      }, {
        t: '  "network": "base",',
        c: "code"
      }, {
        t: '  "skills": ["agentic-wallet"]',
        c: "code"
      }, {
        t: "}",
        c: "code"
      }]
    }, {
      delay: 500,
      left: [{
        t: "> Sign in to my wallet with you@email.com",
        c: "active"
      }],
      right: []
    }, {
      delay: 700,
      left: [{
        t: "  ← OTP sent · checking...",
        c: "muted"
      }],
      right: []
    }, {
      delay: 650,
      left: [{
        t: "  ✓ CDP wallet connected   0x4a3f...b7c1",
        c: "success"
      }],
      right: [{
        t: "",
        c: "dim"
      }, {
        t: "  address: 0x4a3f...b7c1",
        c: "success"
      }, {
        t: "  network: base-mainnet",
        c: "success"
      }, {
        t: "  status:  ready",
        c: "success"
      }]
    }],
    sponge: [{
      delay: 400,
      left: [{
        t: "> curl -X POST https://api.wallet.paysponge.com/...",
        c: "active"
      }],
      right: [{
        t: "── POST /api/agents/register ───────────",
        c: "dim"
      }, {
        t: "Host: api.wallet.paysponge.com",
        c: "muted"
      }, {
        t: "Content-Type: application/json",
        c: "muted"
      }]
    }, {
      delay: 750,
      left: [{
        t: '  ← {"apiKey": "sponge_live_..."}',
        c: "muted"
      }],
      right: [{
        t: "",
        c: "dim"
      }, {
        t: "── 200 OK ──────────────────────────────",
        c: "dim"
      }, {
        t: "{",
        c: "code"
      }, {
        t: '  "apiKey": "sponge_live_abc...xyz",',
        c: "code"
      }, {
        t: '  "walletId": "wlt_a1b2c3d4"',
        c: "code"
      }, {
        t: "}",
        c: "code"
      }]
    }, {
      delay: 450,
      left: [{
        t: "> export SPONGE_API_KEY=sponge_live_...",
        c: "active"
      }],
      right: []
    }, {
      delay: 400,
      left: [{
        t: "  ✓ Sponge wallet ready",
        c: "success"
      }],
      right: [{
        t: "",
        c: "dim"
      }, {
        t: "  chains: base, ethereum, solana",
        c: "success"
      }, {
        t: "  x402:   enabled",
        c: "success"
      }]
    }],
    bankr: [{
      delay: 400,
      left: [{
        t: "> install bankr skill from github.com/BankrBot/skills",
        c: "active"
      }],
      right: [{
        t: "── github.com/BankrBot/skills ──────────",
        c: "dim"
      }, {
        t: "GET /releases/latest",
        c: "muted"
      }]
    }, {
      delay: 700,
      left: [{
        t: "  ✓ Bankr skill installed",
        c: "success"
      }],
      right: [{
        t: "",
        c: "dim"
      }, {
        t: "  tag: bankr-wallet-v2.1.0",
        c: "success"
      }, {
        t: "  size: 142 KB",
        c: "muted"
      }]
    }, {
      delay: 500,
      left: [{
        t: "  ✓ Bankr wallet connected   wlt_bankr_...",
        c: "success"
      }],
      right: [{
        t: "",
        c: "dim"
      }, {
        t: "  chains: base, eth, solana, polygon",
        c: "success"
      }, {
        t: "  gas:    sponsored",
        c: "success"
      }, {
        t: "  swaps:  built-in",
        c: "success"
      }]
    }]
  };
  const [choice, setChoice] = useState(null);
  const [leftLines, setLeftLines] = useState([]);
  const [rightLines, setRightLines] = useState([]);
  const [running, setRunning] = useState(false);
  const [done, setDone] = useState(false);
  const [blink, setBlink] = useState(true);
  const leftRef = useRef(null);
  const rightRef = useRef(null);
  useEffect(() => {
    const t = setInterval(() => setBlink(b => !b), 530);
    return () => clearInterval(t);
  }, []);
  useEffect(() => {
    if (leftRef.current) leftRef.current.scrollTop = leftRef.current.scrollHeight;
  }, [leftLines]);
  const reset = () => {
    setChoice(null);
    setLeftLines([{
      t: "> Choose a wallet provider:",
      c: "muted"
    }]);
    setRightLines([]);
    setRunning(false);
    setDone(false);
  };
  useEffect(() => {
    reset();
  }, []);
  const animateFlow = key => {
    const steps = flows[key];
    if (!steps) return;
    setRunning(true);
    setDone(false);
    let i = 0;
    const next = () => {
      if (i >= steps.length) {
        setRunning(false);
        setDone(true);
        return;
      }
      const s = steps[i];
      setTimeout(() => {
        if (s.left && s.left.length) setLeftLines(prev => [...prev, ...s.left]);
        if (s.right && s.right.length) setRightLines(prev => [...prev, ...s.right]);
        i++;
        next();
      }, s.delay);
    };
    next();
  };
  const pick = w => {
    if (choice) return;
    setChoice(w);
    const label = w === "cdp" ? "CDP" : w === "sponge" ? "Sponge" : "Bankr";
    setLeftLines(prev => [...prev, {
      t: "  [" + label + "]",
      c: "active"
    }]);
    setTimeout(() => animateFlow(w), 150);
  };
  const renderLine = (item, i) => {
    if (!item.t) return <div key={i} style={{
      height: 6
    }} />;
    return <div key={i} style={{
      fontFamily: mono,
      fontSize: 12,
      lineHeight: "20px",
      color: col[item.c] || col.code,
      fontWeight: item.bold ? 600 : 400,
      whiteSpace: "pre"
    }}>{item.t}</div>;
  };
  const btnBase = {
    fontFamily: mono,
    fontSize: 12,
    color: "#60a5fa",
    background: "transparent",
    border: "1px solid #27272a",
    borderRadius: 4,
    cursor: "pointer",
    padding: "1px 8px",
    marginRight: 6,
    lineHeight: "20px"
  };
  const onEnter = e => {
    e.currentTarget.style.color = "#e4e4e7";
    e.currentTarget.style.background = "#1c1c1e";
    e.currentTarget.style.borderColor = "#3f3f46";
  };
  const onLeave = e => {
    e.currentTarget.style.color = "#60a5fa";
    e.currentTarget.style.background = "transparent";
    e.currentTarget.style.borderColor = "#27272a";
  };
  return <div style={{
    margin: "28px 0",
    borderRadius: 12,
    overflow: "hidden",
    border: "1px solid #27272a",
    background: "#09090b"
  }}>
      {}
      <div style={{
    display: "flex",
    alignItems: "center",
    padding: "8px 12px",
    background: "#111113",
    borderBottom: "1px solid #27272a"
  }}>
        <div style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: 28,
    height: 24,
    borderRadius: 6,
    background: "#1e1e20",
    border: "1px solid #27272a",
    marginRight: 10,
    flexShrink: 0
  }}>
          <span style={{
    fontFamily: mono,
    fontSize: 11,
    color: "#71717a",
    userSelect: "none"
  }}>{">"}_</span>
        </div>
        <span style={{
    fontFamily: mono,
    fontSize: 12,
    color: "#52525b"
  }}>Wallet Setup</span>
        <div style={{
    flex: 1
  }} />
        <button onClick={reset} title="Reset" style={{
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: 28,
    height: 24,
    borderRadius: 6,
    background: "transparent",
    border: "1px solid transparent",
    cursor: "pointer",
    color: "#3f3f46",
    fontSize: 15,
    lineHeight: 1
  }} onMouseEnter={e => {
    e.currentTarget.style.color = "#a1a1aa";
    e.currentTarget.style.background = "#1e1e20";
    e.currentTarget.style.borderColor = "#27272a";
  }} onMouseLeave={e => {
    e.currentTarget.style.color = "#3f3f46";
    e.currentTarget.style.background = "transparent";
    e.currentTarget.style.borderColor = "transparent";
  }}>
          {"\u21ba"}
        </button>
      </div>

      {}
      <div style={{
    height: 250,
    borderBottom: "1px solid #27272a",
    overflow: "hidden",
    display: "flex",
    flexDirection: "column"
  }}>
        <div style={{
    padding: "7px 16px 5px",
    borderBottom: "1px solid #1c1c1e"
  }}>
          <span style={{
    fontFamily: mono,
    fontSize: 10,
    fontWeight: 600,
    letterSpacing: "0.1em",
    textTransform: "uppercase",
    color: "#3f3f46"
  }}>Agent</span>
        </div>
        <div ref={leftRef} style={{
    flex: 1,
    overflowY: "hidden",
    padding: "12px 16px"
  }}>
          {leftLines.map(renderLine)}
          {!choice && leftLines.length > 0 && <div style={{
    marginTop: 6,
    display: "flex",
    flexWrap: "wrap",
    alignItems: "center"
  }}>
              <span style={{
    fontFamily: mono,
    fontSize: 12,
    color: "#52525b",
    marginRight: 6
  }}>  pick:</span>
              <button style={btnBase} onMouseEnter={onEnter} onMouseLeave={onLeave} onClick={() => pick("cdp")}>CDP</button>
              <button style={btnBase} onMouseEnter={onEnter} onMouseLeave={onLeave} onClick={() => pick("sponge")}>Sponge</button>
              <button style={btnBase} onMouseEnter={onEnter} onMouseLeave={onLeave} onClick={() => pick("bankr")}>Bankr</button>
            </div>}
          {running && <div style={{
    fontFamily: mono,
    fontSize: 12,
    lineHeight: "20px",
    color: "#60a5fa",
    opacity: blink ? 1 : 0
  }}>{"▋"}</div>}
        </div>
      </div>

      {}
      <div style={{
    padding: "8px 16px",
    display: "flex",
    justifyContent: "center",
    minHeight: 37,
    alignItems: "center"
  }}>
        {done && <button onClick={reset} style={{
    fontFamily: mono,
    fontSize: 11,
    color: "#52525b",
    background: "none",
    border: "none",
    cursor: "pointer",
    padding: "4px 10px",
    borderRadius: 4
  }} onMouseEnter={e => {
    e.currentTarget.style.color = "#a1a1aa";
    e.currentTarget.style.background = "#18181b";
  }} onMouseLeave={e => {
    e.currentTarget.style.color = "#52525b";
    e.currentTarget.style.background = "none";
  }}>
            {"\u21ba"} Play again
          </button>}
      </div>
    </div>;
};

온체인 지갑은 에이전트가 자금을 보유하고, 트랜잭션을 승인하고, 메시지에 서명할 수 있는 능력을 부여합니다. 지갑 없이는 에이전트가 데이터를 읽을 수는 있지만 서비스 비용 지불, 결제 수락, 신원 증명이 불가능합니다.

## 모의 데모

<WalletSetupDemo />

## 에이전트에게 전용 지갑이 필요한 이유

AI 에이전트는 프롬프트를 통해 임의의 개인 키를 생성하는 방식으로 자체 지갑을 만들 수 있지만, 이는 안전하지 않습니다:

* 개인 키가 에이전트의 대화 컨텍스트에 나타나며, 미들웨어에 의해 로그되거나 캐시되거나 유출될 수 있습니다
* 에이전트의 프롬프트 기록에 접근할 수 있는 모든 시스템이 키를 추출할 수 있습니다
* 키가 탈취되면 지갑의 모든 자금이 영구적으로 손실됩니다

전용 지갑 서비스는 에이전트의 런타임과 분리된 안전한 인프라에서 키를 관리함으로써 이 문제를 해결합니다. 에이전트는 개인 키를 직접 보지 않고 트랜잭션을 요청합니다.

## 지갑 선택

<AccordionGroup>
  <Accordion title="Bankr">
    모든 Bankr 에이전트는 Base, Ethereum, Solana, Polygon, Unichain에서 크로스체인 지갑을 제공받습니다. 지원 체인에서는 가스가 스폰서됩니다. 내장된 스왑 도구가 있어 트레이딩 에이전트에 이상적입니다.

    에이전트 채팅에서 Bankr 스킬을 설치합니다:

    ```text theme={null}
    install the bankr skill from https://github.com/BankrBot/skills
    ```

    [bankr.bot](https://bankr.bot)에서 전용 계정을 생성하고 [bankr.bot/api](https://bankr.bot/api)에서 API 키를 발급받으세요. 개인 Bankr 계정을 사용하지 마세요 — 에이전트의 지갑은 별도로 유지하세요.

    [Bankr 문서 →](https://docs.bankr.bot)
  </Accordion>

  <Accordion title="CDP Agentic Wallet">
    AI 에이전트를 위한 Coinbase의 독립형 지갑입니다. 인증은 이메일 OTP 방식 — 에이전트에 API 키가 필요하지 않습니다. 개인 키는 Coinbase의 안전한 인프라에 보관됩니다. 기본 x402 결제 지원이 내장되어 있습니다.

    사전 구축된 지갑 스킬을 설치합니다:

    ```bash Terminal theme={null}
    npx skills add coinbase/agentic-wallet-skills
    ```

    그런 다음 에이전트에게 인증을 요청합니다:

    ```text theme={null}
    Sign in to my wallet with your@email.com
    ```

    스킬에는 `authenticate-wallet`, `fund`, `send-usdc`, `trade`, `pay-for-service`, `monetize-service` 등이 포함됩니다. Base에서 운영됩니다.

    [CDP Agentic Wallet 문서 →](https://docs.cdp.coinbase.com/agentic-wallet/welcome)
  </Accordion>

  <Accordion title="Sponge Wallet">
    기본 x402 결제 처리, 내장된 토큰 스왑, Base, Ethereum, Solana에 걸친 크로스체인 브릿지를 갖춘 멀티체인 에이전트 지갑입니다. Sponge의 x402 프록시가 검색, 결제, 재시도를 자동으로 처리합니다.

    에이전트를 등록하면 즉시 지갑을 받을 수 있습니다:

    ```bash Terminal theme={null}
    curl -X POST https://api.wallet.paysponge.com/api/agents/register \
      -H "Sponge-Version: 0.2.1" \
      -H "Content-Type: application/json" \
      -d '{"name": "my-agent", "agentFirst": true}'
    ```

    반환된 `apiKey`를 저장합니다:

    ```bash Terminal theme={null}
    export SPONGE_API_KEY=sponge_live_...
    ```

    [Sponge Wallet 문서 →](https://wallet.paysponge.com/skill.md)
  </Accordion>
</AccordionGroup>

<Tip>
  **Claude Code, Codex, OpenCode 사용자** — 위의 지갑 스킬은 스킬을 지원하는 모든 AI 코딩 도구에서 작동합니다. 코딩 도구 내에서 동일한 `npx skills add` 명령을 실행하면 동일한 온체인 기능을 사용할 수 있습니다.
</Tip>

## 지갑으로 에이전트가 할 수 있는 것

에이전트에 지갑이 생기면 다음과 같은 작업이 가능합니다:

* **<Tooltip tip="미국 달러와 같은 안정적인 자산에 페깅된 암호화폐 (예: USDC). 1 USDC는 항상 $1과 동일하도록 설계됩니다.">스테이블코인</Tooltip> 보유**: USDC 또는 기타 토큰을 수신 및 저장
* **결제 전송 및 수신**: 다른 지갑으로 자금 이체, API 접근 비용 지불, 서비스에 대한 결제 수신
* **메시지 서명**: 메시지나 요청이 에이전트에서 왔음을 암호학적으로 증명 (신원 검증에 사용)
* **프로토콜과 상호작용**: <Tooltip tip="조건이 충족되면 자동으로 실행되는 온체인 배포 프로그램입니다. 토큰 스왑부터 대출까지 모든 것을 지원합니다.">스마트 컨트랙트</Tooltip>를 호출하여 토큰 스왑, 유동성 제공, 또는 기타 온체인 서비스 이용

<iframe className="w-full aspect-video rounded-xl" src="https://www.youtube.com/embed/G3yn8g4mf-s?si=jRsLzFPS_cui9-gF" title="Base의 에이전트 지갑" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />

## 다음 단계

<Card title="에이전트 등록" icon="arrow-right" href="/ai-agents/setup/agent-registration">
  검색 가능성과 신원 검증을 위해 에이전트를 등록합니다.
</Card>
