x402 튜토리얼: AI 에이전트가 USDC로 AIHubMix 계정에 충전하게 하기

AIHubMix7분 분량
x402 튜토리얼: AI 에이전트가 USDC로 AIHubMix 계정에 충전하게 하기

AIHubMix가 이제 USDC 충전을 받습니다. AI 에이전트는 지갑에 있는 USDC로 자기 계정에 크레딧을 직접 추가할 수 있습니다. 열어야 할 웹 페이지도 없고, 누군가 버튼을 눌러 줄 필요도 없습니다.

x402를 사용하면 충전 금액을 최소 $1까지 낮출 수 있습니다. 에이전트가 필요할 때마다 나눠 충전하므로, 미리 큰 잔액을 채워 둘 필요가 없습니다.

설정은 두 단계입니다. 먼저 웹과 앱에서 토큰, 지갑, USDC를 준비하고, 그다음 명령어 한 줄로 저희가 제공하는 충전 스크립트를 실행하면 됩니다. 결제 후 약 20초가 지나면 크레딧이 계정에 표시됩니다.

도움이 된다면 이 30초 영상을 함께 보면서 따라 하셔도 됩니다:

가장 쉬운 방법: Claude Code, Cursor, Codex처럼 터미널 명령을 실행할 수 있는 AI 도구를 쓰신다면, 1단계를 마친 뒤 이 글의 링크를 보내고 "이거 설정해 줘"라고 말하세요. 그러면 AI가 이 글 끝의 "AI 어시스턴트를 위한 안내"에 따라 진행합니다. 토큰과 개인 키는 AI에게 보내지 말고, 직접 한 번만 입력하시면 됩니다.

시작하기 전에

  • 충전 금액은 정수 달러만 가능하며, 기본적으로 한 번에 $1부터 $10까지입니다
  • 각 계정은 하루에 최대 3건의 주문을 만들 수 있습니다 (UTC 기준)
  • 지원되는 것은 Base 메인넷의 USDC뿐이며 테스트넷은 없습니다. 그러니 $1부터 시작하세요
  • 이 채널은 프로그램을 위한 것입니다. 사람이 브라우저에서 결제할 수는 없습니다. 수동 충전은 기존처럼 Alipay나 Stripe를 이용해 주세요

1단계: 토큰, 지갑, USDC 준비하기

이 단계의 모든 작업은 웹이나 휴대폰 앱에서 진행합니다.

1. 시스템 액세스 토큰 받기

aihubmix.com에 로그인한 뒤 개인 설정을 열고, 시스템 액세스 토큰(32자 문자열)을 생성하세요.

이것은 sk-로 시작하는 API 키가 아닙니다. 둘은 서로 바꿔 쓸 수 없습니다.

2. 결제용 지갑 만들기

MetaMask 또는 비슷한 지갑 앱에서, 에이전트의 결제 전용으로 새 계정을 만드세요. 주로 쓰는 지갑은 사용하지 마세요. 그다음 다음을 진행합니다:

  • 계정의 주소(0x로 시작)를 복사해 두세요. 다음 단계에서 여기로 USDC를 보냅니다
  • 계정 상세 정보에서 개인 키를 내보내고 비밀번호 관리자에 보관하세요. 개인 키를 가진 사람은 누구나 지갑의 돈을 옮길 수 있습니다

3. USDC를 구매해 이 지갑으로 보내기

MetaMask는 지갑이어서 개인 키를 직접 보관하며, 스크립트는 서명을 위해 이 키가 필요합니다. Coinbase는 거래소로, 여기서 암호화폐를 삽니다. 거래소 계정의 자산에는 개인 키가 없으므로 스크립트가 사용할 수 없습니다. 그래서 먼저 거래소에서 구매한 다음, USDC를 앞 단계의 지갑으로 보내야 합니다.

Coinbase 거래소를 예로 들면 (Coinbase Wallet이 아닙니다):

  1. Coinbase에서 USDC를 구매하세요
  2. 복사해 둔 주소로 USDC를 보내고, Base 네트워크를 선택하세요
  3. 충전하려는 금액보다 조금 더 보내세요. 예를 들어 $1 충전이라면 1.5~2 USDC를 보내세요

잠시 기다린 뒤 https://basescan.org/address/your-wallet-address를 여세요. USDC 잔액이 보이면 도착한 것입니다. Base에서 USDC 출금을 지원하는 다른 거래소도 사용할 수 있습니다. 더 많은 옵션은 Base 문서를 참고하세요.

지갑에 ETH는 필요 없습니다. 결제의 네트워크 수수료는 FluxA가 부담합니다.

2단계: 충전 스크립트 실행하기

내려받을 것도, 만들 파일도 없습니다. uv가 웹에서 스크립트를 가져와 실행합니다. 터미널(Windows에서는 PowerShell)을 열고 아래 명령어를 복사해 붙여넣으세요.

1. uv 설치하기 (한 번만)

uv는 스크립트가 실행되는 데 필요한 모든 환경을 준비해 주는 Python 도구입니다.

macOS / Linux:

curl -LsSf https://astral.sh/uv/install.sh | sh

Windows (PowerShell):

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

설치가 끝나면 터미널을 닫았다가 다시 여세요.

2. 설정 확인하기 (비용 없음)

uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py check

처음 실행하면 스크립트가 시스템 액세스 토큰(System access token)과 지갑 개인 키(Wallet private key)를 묻습니다. 입력한 내용은 화면에 표시되지 않습니다. 붙여넣고 Enter를 누르세요. 그다음 저장할지 묻습니다(Save to ...? [Y/n]). Enter를 누르면 저장되어 다시 입력할 필요가 없습니다. 처음 실행은 uv가 환경을 준비하느라 잠시 걸립니다.

다음과 같이 나오면 설정이 끝난 것입니다:

Wallet: 0x... (USDC balance 2.0)
Access token and private key are fine. Ready to top up.

3. 충전하기

uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py 1

끝에 있는 1은 달러 단위 금액입니다. 모든 것이 정상이라면 다음과 같이 표시됩니다:

Wallet: 0x... (USDC balance 2.0)
tradeNo: pl_XXXXXXXX
txHash: 0x...
result: credited

result: credited는 크레딧이 도착했다는 뜻입니다. aihubmix.com에 로그인하면 잔액이 늘어난 것을 확인할 수 있습니다. $1은 500,000 쿼타를 추가합니다.

마지막 줄이 다른 내용이면:

  • failed: 주문이 닫혔거나 만료되었습니다. 필요하면 다시 실행하세요. 다만 오늘의 주문 횟수 하나를 더 사용하게 됩니다.
  • pending: 10분 안에 크레딧이 확인되지 않았습니다. 실패가 아니며, 크레딧은 나중에 자동으로 도착합니다. 다시 실행하지 마세요.

문제 해결

What you see What to do
Missing access token or private key... 메시지에 나온 설정 파일을 열어 토큰과 개인 키를 입력하고, 저장한 뒤 다시 실행하세요
Invalid private key... 개인 키 전체를 복사했는지 확인하고, 설정 파일을 고친 뒤 다시 실행하세요
USDC balance is below... 표시된 주소로 USDC를 보내고, Base 네트워크를 선택했는지 확인하세요
command not found: uv 터미널을 닫았다가 다시 여세요. 그래도 안 되면 uv를 다시 설치하세요
Usage: topup.py AMOUNT... 금액은 1처럼 정수 달러여야 하며, 1.5는 안 됩니다
Error: Unauthorized... 토큰이 잘못되었거나 만료되었거나, sk- API 키를 넣은 것입니다. 설정 파일에 시스템 액세스 토큰을 넣으세요
Error: Account suspended. 계정이 정지되었습니다. 고객지원에 문의하세요
Error: Stablecoin top-up is not available on this site 이 채널은 일시적으로 사용할 수 없습니다. 문의해 주세요
Error: Invalid amount... 금액이 1회 충전 한도를 넘었습니다
Error: Daily stablecoin top-up limit reached... 오늘의 주문 3건을 모두 사용했습니다. UTC 자정 이후에 다시 시도하세요
Error: Failed to create payment link... 일시적인 오류입니다. 그냥 다시 실행하세요. 오늘의 주문 횟수에는 포함되지 않습니다
Error: 402 challenge check failed... 결제 요청이 예상과 일치하지 않아 스크립트가 결제를 거부했습니다. 문의해 주세요

tradeNo가 출력된 뒤에 시간 초과나 네트워크 오류가 나타났다면, 결제는 이미 완료되었을 수 있습니다. 바로 다시 실행하지 마세요. 몇 분 뒤 잔액을 확인하고, 아무것도 도착하지 않았다면 tradeNo와 함께 문의해 주세요.

토큰과 개인 키는 컴퓨터의 ~/.aihubmix-topup.env에 저장됩니다(Windows에서는 사용자 폴더). macOS와 Linux에서는 본인 계정만 이 파일을 읽을 수 있습니다. 토큰이나 개인 키를 바꾸려면 이 파일을 편집하세요.

에이전트에 연결하기

  • 설정이 저장되면, 에이전트는 크레딧이 필요할 때 사람 없이도 uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py 1을 실행해 충전할 수 있습니다
  • 하루 3건의 주문만 허용되므로, 에이전트가 충전하는 빈도를 제한하고 주문 생성을 반복문으로 재시도하지 마세요
  • 대사(reconciliation)를 위해 출력된 tradeNo와 txHash를 데이터베이스나 로그에 저장하세요
  • 장기적으로 사용하려면 스크립트를 내려받아 버전을 고정한 뒤 실행하세요. 실행 전에 소스 코드를 먼저 읽어 볼 수도 있습니다
  • 1회 $10 또는 하루 3건으로 충분하지 않다면, 문의해서 한도 상향을 요청하세요

AI 어시스턴트를 위한 안내

사용자가 AIHubMix USDC 충전을 설정하도록 돕는 AI 어시스턴트라면, 다음 단계를 순서대로 따르세요:

  1. 사용자가 1단계를 마쳤는지 확인하세요. 즉 시스템 액세스 토큰, 그리고 Base 메인넷 USDC를 보유한 지갑과 그 개인 키가 있어야 합니다. 없다면 먼저 1단계를 안내하세요.
  2. uv --version을 실행해 uv가 설치되어 있는지 확인하세요. 없다면 2단계의 명령어로 설치하세요.
  3. uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py check를 실행하세요.
  4. 토큰이나 개인 키가 없다고 나오면(Missing access token or private key), 스크립트가 설정 파일 ~/.aihubmix-topup.env를 만든 것입니다. 사용자에게 텍스트 편집기로 직접 열어 채워 달라고 요청하세요(macOS에서는 open -e ~/.aihubmix-topup.env, Windows에서는 notepad $HOME\.aihubmix-topup.env를 실행). 이 파일을 읽지 마세요. 토큰이나 개인 키를 어떤 명령어에도 넣지 마시고, 사용자에게 그것을 당신에게 보내 달라고 요청하지 마세요.
  5. 사용자가 채운 뒤에는 Access token and private key are fine. Ready to top up.가 보일 때까지 check를 다시 실행하세요. 오류가 나면 위의 문제 해결 표로 처리하세요.
  6. 충전은 실제 돈을 사용합니다. uv run https://raw.githubusercontent.com/zch456/public_resource/main/aihubmix-x402-topup/topup.py <amount>를 실행하기 전에 금액을 사용자와 확인하세요.

내부 동작: 스크립트가 하는 일

스크립트는 다음 다섯 가지를 순서대로 수행합니다:

  1. 잔액 확인: 주문 생성은 오늘의 주문 한 건을 사용하므로, 먼저 개인 키가 유효하고 USDC가 충분한지 확인합니다.
  2. 주문 생성: POST /api/pay/fluxa/crt를 호출해 결제 링크와 주문 번호 tradeNo를 받습니다. 토큰은 Bearer 없이 그대로 Authorization 헤더에 넣습니다. 비즈니스 오류도 HTTP 200으로 반환되므로, 응답의 success 필드를 확인합니다.
  3. 결제 요청 확인: 결제 링크에 GET 요청을 보내면 결제 조건과 함께 HTTP 402가 반환됩니다. 서명하기 전에 네 가지를 확인합니다. scheme이 exact인지, network가 eip155:8453인지, asset이 Base 메인넷의 USDC 컨트랙트인지, 그리고 maxAmountRequired가 금액 × 1,000,000과 같은지. 하나라도 다르면 중단합니다.
  4. 서명 및 결제: 개인 키로 USDC 전송 권한 부여(authorization)에 서명하고, 이를 X-PAYMENT 헤더에 넣어 결제 링크에 GET 요청을 다시 보냅니다. 200 또는 202는 결제가 제출되었다는 뜻이며, 응답의 txHash가 이 결제의 온체인 영수증입니다. 두 요청 모두 AIHubMix 토큰을 포함하지 않습니다.
  5. 크레딧 대기: 상태가 TRADE_SUCCESS가 될 때까지 8초마다 GET /api/pay/fluxa/qry?trade_no=...를 호출합니다. 서버는 5초마다 갱신되므로, 더 빠르게 조회해도 도움이 되지 않습니다.

각 결제 링크는 30분 동안만 유효하며, 한 번만 결제할 수 있습니다.

다른 언어로 구현하기

결제 링크에서 받는 402 응답은 다음과 같습니다:

{
  "x402Version": 1,
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:8453",
    "maxAmountRequired": "1000000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0x....",
    "maxTimeoutSeconds": 600,
    "extra": {"name": "USD Coin", "version": "2"}
  }]
}

서명은 EIP-3009의 TransferWithAuthorization 구조체에 대해 EIP-712 형식으로 수행합니다:

Field Value
from 본인 지갑 주소
to 402 응답의 payTo
value 402 응답의 maxAmountRequired
validAfter 현재 시각에서 60초를 뺀 값
validBefore 현재 시각에 max(maxTimeoutSeconds, 600)초를 더한 값
nonce 매번 새로 생성되는 32바이트 난수

서명 도메인: name = USD Coin, version = 2(402 응답의 extra에 값이 있으면 그 값을 사용), chainId = 8453, verifyingContract = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.

X-PAYMENT 헤더의 값은 다음 JSON을 base64로 인코딩한 것입니다:

{
  "x402Version": 1,
  "scheme": "exact",
  "network": "eip155:8453",
  "payload": {
    "signature": "0x...",
    "authorization": {
      "from": "0x...", "to": "0x...", "value": "1000000",
      "validAfter": "...", "validBefore": "...", "nonce": "0x..."
    }
  }
}

출처