> ## 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.

# 시장 데이터 페칭

> x402를 사용하여 CoinGecko, Alchemy 등의 소스에서 실시간 시장 데이터에 접근 — API 키 관리 불필요

export const DataFetchingDemo = () => {
  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 steps = [{
    delay: 350,
    left: [{
      t: "> Discover price feed service...",
      c: "active"
    }],
    right: [{
      t: "── Service Discovery ───────────────────",
      c: "dim"
    }, {
      t: "GET /api/discover?query=price+feed",
      c: "code"
    }, {
      t: "Host: api.wallet.paysponge.com",
      c: "muted"
    }]
  }, {
    delay: 700,
    left: [{
      t: "  ← found: api.coingecko.com · 0.001 USDC",
      c: "muted"
    }],
    right: [{
      t: "",
      c: "dim"
    }, {
      t: '{"id":"coingecko-price",',
      c: "code"
    }, {
      t: '  "baseUrl":"api.coingecko.com",',
      c: "code"
    }, {
      t: '  "price":"0.001 USDC/req"}',
      c: "code"
    }]
  }, {
    delay: 500,
    left: [{
      t: "> Fetch ETH price...",
      c: "active"
    }],
    right: [{
      t: "",
      c: "dim"
    }, {
      t: "── API Request ─────────────────────────",
      c: "dim"
    }, {
      t: "GET /api/v3/simple/price?ids=ethereum",
      c: "code"
    }]
  }, {
    delay: 600,
    left: [{
      t: "  ← 402 · paying 0.001 USDC...",
      c: "muted"
    }],
    right: [{
      t: "",
      c: "dim"
    }, {
      t: "HTTP/1.1 402 Payment Required",
      c: "muted"
    }, {
      t: "X-Payment-Sig: pending...",
      c: "muted"
    }]
  }, {
    delay: 700,
    left: [{
      t: "  ✓ payment sent · retrying...",
      c: "success"
    }],
    right: [{
      t: "",
      c: "dim"
    }, {
      t: "── API Response ────────────────────────",
      c: "dim"
    }, {
      t: "HTTP/1.1 200 OK",
      c: "success"
    }]
  }, {
    delay: 500,
    left: [{
      t: "  ← 200 OK · data returned",
      c: "success"
    }],
    right: [{
      t: '{"ethereum":{',
      c: "code"
    }, {
      t: '  "usd": 2847.32,',
      c: "code"
    }, {
      t: '  "usd_24h_change": 2.31',
      c: "code"
    }, {
      t: "} }",
      c: "code"
    }]
  }, {
    delay: 350,
    left: [{
      t: "  ETH  $2,847.32  ↑ 2.3%",
      c: "code",
      bold: true
    }],
    right: []
  }];
  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 play = () => {
    setLeftLines([]);
    setRightLines([]);
    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();
  };
  useEffect(() => {
    setTimeout(play, 350);
  }, []);
  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>;
  };
  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"
  }}>Data Fetching</span>
        <div style={{
    flex: 1
  }} />
        <button onClick={play} 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)}
          {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={play} 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>;
};

x402는 트레이딩 데이터에 매우 적합합니다: 에이전트가 USDC로 호출별 결제를 처리하며 API 키 등록, 구독 관리, 속도 제한 티어 협상이 필요하지 않습니다. 에이전트가 데이터를 받고, 공급자가 결제를 받습니다 — 이것이 전부입니다.

## 모의 데모

<DataFetchingDemo />

## 시장 데이터에 x402를 사용하는 이유

* **API 키 관리 불필요** — 에이전트가 온디맨드로 결제; 교체하거나 안전하게 저장할 자격증명 없음
* **사용한 만큼만 결제** — 항상 필요하지 않을 수 있는 데이터에 대한 월 구독 없음
* **모든 지갑에서 작동** — [Sponge Wallet의](https://www.paysponge.com) x402 프록시, [CDP Agentic Wallet](https://docs.cdp.coinbase.com/agentic-wallet/) 스킬, `x402-axios` 모두 결제를 자동으로 처리
* **구성 가능** — 에이전트가 동일한 세션에서 여러 데이터 공급자를 호출하고 각각 별도로 결제 가능

## x402 호환 엔드포인트 검색

x402 호환 서비스는 `/.well-known/x402.json`에 검색 문서를 게시합니다. Bazaar 카탈로그에서 x402 데이터 공급자의 큐레이션 목록을 탐색할 수도 있습니다.

<Tabs>
  <Tab title="CDP Agentic Wallet">
    [`search-for-service`](https://docs.cdp.coinbase.com/agentic-wallet/skills/search-for-service) 스킬로 x402 Bazaar를 검색합니다:

    ```bash Terminal theme={null}
    npx awal@latest x402 bazaar search "price feed"
    ```

    이용 가능한 모든 리소스를 탐색하려면:

    ```bash Terminal theme={null}
    npx awal@latest x402 bazaar list --network base
    ```
  </Tab>

  <Tab title="Sponge Wallet">
    ```bash Terminal theme={null}
    curl "https://api.wallet.paysponge.com/api/discover?query=price+feed" \
      -H "Authorization: Bearer $SPONGE_API_KEY" \
      -H "Sponge-Version: 0.2.1"
    ```
  </Tab>
</Tabs>

## x402 데이터 소스 예시

### CoinGecko — 가격 피드

CoinGecko는 x402 지원 엔드포인트를 통해 암호화폐 가격 피드, 시가 총액 데이터, 역사적 OHLCV를 제공합니다.

현재 ETH 가격 조회:

<Tabs>
  <Tab title="CDP Agentic Wallet">
    [`pay-for-service`](https://docs.cdp.coinbase.com/agentic-wallet/skills/pay-for-service) 스킬을 사용합니다:

    ```bash Terminal theme={null}
    npx awal@latest x402 pay "https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd"
    ```
  </Tab>

  <Tab title="Sponge Wallet">
    ```bash Terminal theme={null}
    curl -X POST "https://api.wallet.paysponge.com/api/x402/fetch" \
      -H "Authorization: Bearer $SPONGE_API_KEY" \
      -H "Sponge-Version: 0.2.1" \
      -H "Content-Type: application/json" \
      -d '{
        "url": "https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd",
        "method": "GET",
        "preferred_chain": "base"
      }'
    ```
  </Tab>
</Tabs>

### Alchemy — 온체인 데이터

Alchemy는 `https://x402.alchemy.com`의 [Agentic Gateway](https://github.com/alchemyplatform/skills/tree/main/skills/agentic-gateway)를 통해 온체인 데이터를 위한 향상된 API를 제공합니다 — 토큰 잔액, NFT 메타데이터, 멤풀 가시성, 디코딩된 트랜잭션 기록.

<Note>
  Alchemy의 x402 게이트웨이는 자체 [`@alchemy/x402`](https://github.com/alchemyplatform/skills/tree/main/skills/agentic-gateway) CLI를 통한 SIWE 지갑 인증을 사용합니다 — 일반 x402 bazaar 엔드포인트가 아닙니다. 요청하기 전에 아래 설정 단계를 따르세요.
</Note>

**1단계 — 지갑 설치 및 설정:**

```bash Terminal theme={null}
npx @alchemy/x402 wallet generate
```

**2단계 — SIWE 인증 토큰 생성:**

```bash Terminal theme={null}
npx @alchemy/x402 sign --private-key ./wallet-key.txt > siwe-token.txt
```

**3단계 — Base에서 토큰 잔액 조회:**

<Tabs>
  <Tab title="토큰 잔액 (JSON-RPC)">
    ```bash Terminal theme={null}
    TOKEN=$(cat siwe-token.txt)

    curl -s -X POST "https://x402.alchemy.com/base-mainnet/v2" \
      -H "Content-Type: application/json" \
      -H "Authorization: SIWE $TOKEN" \
      -d '{
        "jsonrpc": "2.0",
        "id": 1,
        "method": "alchemy_getTokenBalances",
        "params": ["0xYourAddress"]
      }'
    ```
  </Tab>

  <Tab title="포트폴리오 (멀티체인)">
    ```bash Terminal theme={null}
    TOKEN=$(cat siwe-token.txt)

    curl -s -X POST "https://x402.alchemy.com/data/v1/assets/tokens/by-address" \
      -H "Content-Type: application/json" \
      -H "Authorization: SIWE $TOKEN" \
      -d '{"addresses": ["0xYourAddress"], "withMetadata": true}'
    ```
  </Tab>

  <Tab title="토큰 가격">
    ```bash Terminal theme={null}
    TOKEN=$(cat siwe-token.txt)

    curl -s -G "https://x402.alchemy.com/prices/v1/tokens/by-symbol" \
      --data-urlencode "symbols=ETH" \
      --data-urlencode "symbols=USDC" \
      -H "Authorization: SIWE $TOKEN"
    ```
  </Tab>
</Tabs>

게이트웨이가 `402`를 반환하면 CLI로 결제를 처리하고 재시도합니다:

```bash Terminal theme={null}
PAYMENT_SIG=$(npx @alchemy/x402 pay --private-key ./wallet-key.txt --payment-required "$PAYMENT_REQUIRED")
```

지갑 부트스트랩, 결제 처리, SDK 통합에 대한 전체 내용은 [Alchemy Agentic Gateway 스킬](https://github.com/alchemyplatform/skills/tree/main/skills/agentic-gateway)을 참조하세요.

## OpenClaw 에이전트에서 데이터 호출

[Sponge Wallet](https://www.paysponge.com) 스킬 또는 [CDP Agentic Wallet](https://docs.cdp.coinbase.com/agentic-wallet/) 스킬을 설치한 다음 에이전트에게 직접 프롬프트합니다:

```text theme={null}
Get the current prices of ETH, BTC, and SOL from a paid data source
```

```text theme={null}
Check the token balances at 0xYourWatchAddress on Base
```

에이전트가 서비스 검색, 결제, 데이터 추출을 처리합니다. `x402-axios`를 사용한 커스텀 구현의 경우:

```bash Terminal theme={null}
npm install x402-axios axios
```

```typescript TypeScript theme={null}
import { withPaymentInterceptor } from "x402-axios";
import axios from "axios";

// walletClient는 viem 호환 WalletClient여야 합니다
const client = withPaymentInterceptor(axios.create(), walletClient);

// 엔드포인트가 402를 반환하면 인터셉터가 자동으로 결제하고 재시도합니다
const response = await client.get("https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd");
console.log(response.data);
```

인터셉터가 전체 402 → 결제 → 재시도 흐름을 처리합니다. viem `WalletClient`를 설정에 연결하는 방법은 [x402 클라이언트 문서](https://docs.cdp.coinbase.com/x402/docs/client-server-model)를 참조하세요.

## 관련 항목

<CardGroup cols={2}>
  <Card title="트레이드 실행" icon="chart-line" href="/ai-agents/trading/trade-execution">
    Flashblocks 타이밍과 Base 수수료 조정을 사용한 스왑 실행입니다.
  </Card>

  <Card title="x402 프로토콜" icon="bolt" href="/ai-agents/payments/pay-for-services-with-x402">
    전체 x402 흐름, 지원 네트워크, 오류 처리입니다.
  </Card>
</CardGroup>
