프로그래밍 방식 회원가입: Agent 및 CI를 위한 지갑 로그인과 API Key 생성
AI 에이전트, 스크립트 및 CI 워크플로를 위해 브라우저 없이 이더리움 지갑 서명(EIP-191)을 사용하여 프로그래밍 방식으로 가입하고 API key를 생성하세요.
브라우저 없이 실행되는 자율 AI 에이전트, CI 파이프라인 및 자동화 스크립트를 위해 BlockVectra는 이더리움 지갑 서명(EIP-4361 / EIP-191) 기반의 프로그래밍 방식 로그인 및 계정 개설 워크플로를 제공합니다.
Key security
개인키, 세션 토큰 또는 API key를 AI와의 대화에 붙여넣거나 MCP 툴 인수로 전달하지 마세요.
가입하기 전에 먼저 키가 필요 없는 공개 엔드포인트 https://api.blockvectra.com/v1/robinhood_mainnet/public을 사용해 볼 수 있습니다(지갑용 JSON-RPC 메서드 전용, Data API는 키 필요, 메서드 및 한도는 /v1/chains 기준). 할당량이 부족한 경우 계정에 가입하세요.
워크플로 개요
프로그래밍 방식 등록 및 키 발급 흐름은 다음 4단계로 구성됩니다:
- 챌린지 요청:
POST /auth/siwe/challenge로 요청을 전송하여 서버가 생성한 로그인 메시지를 받습니다. - 메시지 서명: EIP-191(
personal_sign)을 사용하여 이더리움 EOA 지갑으로 해당 메시지에 정확히 서명합니다. - 로그인 / 계정 개설: 원본 메시지와 서명을
POST /auth/siwe/login에 제출합니다. 지갑의 첫 로그인 시 계정이 자동으로 생성됩니다(account_created: true). 신규 계정 가입 시 30,000,000 CU 무료 제공 — 신용카드 불필요. - API key 생성: 세션 토큰을 사용하여
POST /keys를 호출하고 API key를 생성합니다.
실행 가능한 전체 예제
여기서 시작하세요: 로컬 이더리움 EOA 서명기를 사용해 키를 생성하고 eth_blockNumber로 검증합니다. Bash 예제의 경우 curl, jq 및 Foundry cast가 필요합니다. 지갑 자격 증명은 로컬 서명 환경에 보관하세요.
전체 스타터 템플릿: blockvectra/agent-quickstart
다음 스크립트는 지갑 자격 증명을 읽고, 챌린지 및 로그인 과정을 완료하며, API key를 발급하고, 환경 변수 설정을 위해 export BLOCKVECTRA_API_KEY=...를 내보내거나 출력한 뒤 검증용 eth_blockNumber 요청을 보냅니다:
새 키가 활성화되는 데 몇 초 정도 걸릴 수 있으며, 아래 예제는 자동으로 재시도합니다.
BASE=https://console-api.blockvectra.com/v1
# $ADDR: Ethereum wallet address (0x...)
# $PK: wallet private key, loaded from a secrets manager (never hardcode in scripts)
# 1. Fetch server-generated SIWE message (omit Origin header)
curl -s "$BASE/auth/siwe/challenge" -H 'Content-Type: application/json' \
-d "{\"address\":\"$ADDR\",\"purpose\":\"login\"}" > challenge.json
jq -r .message challenge.json > msg.txt
# 2. Sign the exact message with EIP-191 personal_sign
SIG=$(cast wallet sign --private-key "$PK" "$(cat msg.txt)")
# 3. Submit verbatim message and signature (omit Origin header) to log in (ref is optional)
jq -n --rawfile m msg.txt --arg s "$SIG" '{message: ($m | rtrimstr("\n")), signature: $s, ref: "docs-signup"}' |
curl -s "$BASE/auth/siwe/login" -H 'Content-Type: application/json' -d @- > session.json
TOKEN=$(jq -r .session.token session.json)
# 4. Create an API key (the secret is returned only once)
KEY_RESP=$(curl -s "$BASE/keys" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"label":"agent-key"}')
export BLOCKVECTRA_API_KEY=$(echo "$KEY_RESP" | jq -r .api_key)
# 5. Call JSON-RPC with the key in the x-api-key request header
RPC_DEADLINE=$((SECONDS + 10))
while true; do
RPC_TIMEOUT=$((RPC_DEADLINE - SECONDS))
if ((RPC_TIMEOUT <= 0)); then
printf '%s' "${RPC_BODY:-}"
break
fi
RPC_RESP=$(curl -s --max-time "$RPC_TIMEOUT" -w '\n%{http_code}' "https://api.blockvectra.com/v1/robinhood_mainnet" \
-H "x-api-key: $BLOCKVECTRA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}') || { rc=$?; echo "request failed (curl exit $rc)" >&2; exit $rc; }
RPC_STATUS=${RPC_RESP##*$'\n'}
RPC_BODY=${RPC_RESP%$'\n'*}
if ((SECONDS + 2 < RPC_DEADLINE)) &&
printf '%s' "$RPC_BODY" | jq -e --arg status "$RPC_STATUS" '
($status == "401" and .error.data.reason == "invalid_api_key") or
($status == "503" and .error.code == -32021)
' >/dev/null 2>&1; then
sleep 2
else
printf '%s' "$RPC_BODY"
break
fi
done기본 URL 및 프로그래밍 모드
모든 인증 및 키 관리 엔드포인트는 공식 기본 URL을 사용합니다:
https://console-api.blockvectra.com/v1Origin 헤더 생략
프로그래밍 방식 요청은 프로그래밍 모드로 작동합니다:
- 챌린지(
POST /auth/siwe/challenge) 및 로그인(POST /auth/siwe/login) 요청 모두Origin헤더를 포함해서는 안 됩니다(curl및 표준 HTTP 클라이언트는 이 헤더를 기본적으로 생략하므로 수동으로 추가하지 마세요). Origin헤더를 전송했지만 구성된 웹 콘솔 도메인이 아닌 경우(빈 문자열 또는null포함), 챌린지 요청은 HTTP 400invalid_request를 반환합니다.- 로그인 시 모드가 챌린지 모드와 일치하지 않는 경우(예:
Origin없이 프로그래밍 방식 챌린지를 요청한 후Origin헤더를 포함하여 로그인을 제출하거나 그 반대의 경우), 로그인 요청은reason: domain_mismatch와 함께 HTTP 400siwe_invalid를 반환합니다.
메시지 무결성 및 지갑 요구사항
- 메시지 원본 서명 및 제출: 클라이언트는 챌린지 엔드포인트가 반환한 메시지 텍스트를 있는 그대로 정확히 서명하고 제출해야 합니다. 공백, 도메인, 체인 ID 또는 기타 필드를 변경하지 마세요. 어떠한 수정이라도 가해지면
reason: signature와 함께 HTTP 400siwe_invalid가 발생합니다. - 지원되는 지갑: Ethereum 메인넷(Chain ID 1) EOA(Externally Owned Accounts). 서명은 65바이트 ECDSA 서명(
personal_sign)이어야 합니다. 컨트랙트 지갑(EIP-1271) 및 스마트 계정은 지원되지 않습니다. - 챌린지 유효 기간: 각 챌린지 nonce는 일회용이며 5분 후 만료됩니다.
요청 본문 및 가입 귀속 (선택 사항)
POST /auth/siwe/login 요청 본문은 필수 인증 파라미터와 선택 사항인 가입 귀속(attribution) 필드를 받습니다:
- 필수 필드:
message: 챌린지 엔드포인트에서 획득한 완전한 SIWE 메시지 문자열.signature: 이더리움 지갑으로 EIP-191을 통해message에 서명하여 생성된 65바이트 16진수 서명(0x접두사 포함).
- 선택 귀속 필드 (새 계정이 생성될 때 한 번만 저장되며, 이후 로그인에서는 무시됨):
ref:^[a-z0-9._-]{1,64}$정규식과 일치하는 소문자 채널 토큰(소문자 ASCII 영문, 숫자,.,_,-, 1~64자). 예를 들어 자율 에이전트는 프레임워크나 런타임 식별자(예:my-agent.v1)로 설정할 수 있습니다. 규격을 준수하지 않는 값(대문자, 빈 문자열, 길이 초과 또는 지원되지 않는 문자 포함)은 대소문자 변환 없이 HTTP 400invalid_request를 반환하며 계정 생성을 차단합니다. 해당 사항이 없으면 생략하거나null을 전달하세요.referrer: 유입 출처 URL 또는 호스트 이름 문자열. 문자열이 아닌 타입만 HTTP 400을 반환합니다.
signup_method와 같이 정의되지 않은 필드를 전송하면 HTTP 400 invalid_request가 반환됩니다.
세션 토큰 및 API Key
세션 토큰 수명 주기
- 형식:
rgs_뒤에 64자의 소문자 16진수 문자가 붙습니다. - 유효 기간: 절대 수명 7일, 24시간 동안 유휴 상태일 경우 자동 만료.
- 리프레시 토큰 없음: 세션 토큰이 만료되면 새로운 챌린지 및 로그인 흐름을 시작해야 합니다.
- 헤더:
Authorization: Bearer rgs_...요청 헤더에 세션 토큰을 전달합니다.
API Key 생성
- 세션 토큰과 함께
POST /keys를 호출하여 API key를 생성합니다(rgw_뒤에 64자의 16진수 문자가 붙음). - 계정당 해지되지 않고 만료되지 않은 키(
active+disabled)는 최대 20개까지 가능하며, 만료된 키는 계산에 포함되지 않습니다. 이를 초과하면reason: active_keys및limit: 20과 함께 HTTP 409key_limit_reached가 반환되므로 기존 키를 먼저 해지해야 합니다. 이 상한은 계정의 모든 ID, 세션 및 체인 전체에 적용됩니다. 키 생성 및 순환도 24시간당 20개로 제한되며, 초과 시Retry-After: 3600과 함께 HTTP 429rate_limited가 반환됩니다. - 선택적 상한 및 만료:
cu_cap(키의 누적 수명 CU 상한, 소프트 캡)과 만료 시간(expires_in_secs또는expires_at, 키 정책에서 허용하는 최대 일수까지)을 지정할 수 있습니다. 만료되거나 상한이 소진되면 서버는 403(JSON-RPC-32025, reasonkey_expired또는key_cap_exhausted)을 반환합니다. - 보안 secret인
api_key는 생성 시 단 한 번만 반환됩니다. 즉시 시크릿 관리자나 환경 변수에 안전하게 저장하세요. - 하나의 API key로 JSON-RPC 및 Data API가 지원하는 모든 체인에서 사용할 수 있습니다.
세션이나 API Key를 분실했나요?
BlockVectra에서 에이전트의 계정 식별자는 가입 시 사용한 이더리움 지갑 주소에 바인딩됩니다. 세션 토큰이 만료되었거나 API key를 분실 또는 유출한 경우, 해당 지갑만을 사용하여 완전한 제어권을 복구할 수 있습니다:
- 동일한 지갑으로 재인증: 챌린지를 요청하고, 동일한 지갑으로 서명한 뒤, 로그인 요청(
POST /auth/siwe/login)을 제출합니다. 서버가 서명을 검증하고,account_created: false로 기존 계정에 로그인하며 새 세션 토큰을 발급합니다. - 새 API Key 생성: 새 세션 토큰을 사용하여
{"label": "..."}및Authorization: Bearer <token>헤더와 함께POST /keys를 호출합니다. 엔드포인트는key에 생성된 키 세부 정보와api_key에 일회용 시크릿을 담아 HTTP 201을 반환합니다. 즉시 이 키를 환경 변수나 시크릿 관리자에 저장하세요. - 계정의 모든 키 목록 조회:
- 엔드포인트:
GET /keys - 헤더:
Authorization: Bearer <token> - 쿼리 파라미터: 선택적
include_revoked=true(true인 경우 해지된 키 포함, 기본값은 활성/비활성화 키만 반환). - 응답:
{"items": [...]}JSON과 함께 HTTP 200.items배열의 각 요소에는 다음이 포함됩니다:key_id: 고유 키 식별자 (string)label: 키 라벨 (string 또는null)status: 상태 ("active","disabled", 또는"revoked")created_at: 생성 타임스탬프 (ISO 8601 문자열)revoked_at: 해지 타임스탬프 (문자열, 해지되지 않은 경우null)
- 엔드포인트:
- 미사용 또는 유출된 키 해지:
- 엔드포인트:
POST /keys/{key_id}/revoke(참고: 경로에 대상key_id를 포함하는POST사용, 빈 요청 본문) - 헤더:
Authorization: Bearer <token> - 동작: 멱등성 보장.
active또는disabled상태의 키 모두 해지 가능합니다. 이미 해지된 경우 변경 없이 HTTP 200을 반환합니다. 해지된 후 해당 키를 사용하는 요청은 거부됩니다. - 응답: 해지된 키 객체를 반환하는 HTTP 200(필드는 위의 키 객체와 일치하며
status: "revoked"및revoked_at타임스탬프 포함).
- 엔드포인트:
Key and secret security
지갑 개인키와 API key는 환경 변수나 시크릿 관리자에 보관하세요. 코드 저장소에 커밋하거나, 로그에 기록하거나, AI 채팅 대화에 붙여넣지 마세요.
보안 권장사항
- 단기 키 사용 및 작업 완료 후 해지: 자동화되거나 일시적인 작업의 경우
expires_in_secs로 수명이 짧은 키를 생성하고, 작업이 완료되면POST /keys/{key_id}/revoke를 통해 즉시 해지하세요.
가입 속도 제한 (signup_rate_limited)
계정 생성에는 가입 속도 제한이 적용됩니다. IP별 토큰 버킷 용량은 100개 계정이며, IPv4 주소 또는 IPv6 /64 프리픽스당 시간당 100개 계정 비율로 채워집니다. 이는 SIWE와 OAuth 가입이 공유합니다:
- 가입 제한을 초과하면
POST /auth/siwe/login은 대기할 시간(초)을 나타내는Retry-After헤더와 함께 HTTP 429signup_rate_limited를 반환합니다. reason필드는 제한 범위를 구분합니다:per_ip: 요청한 IP 프리픽스의 등록 예산이 소진되었습니다.global: 플랫폼 전체 통합 가입 한도가 소진되었습니다.
- 가입 속도 제한은 신규 계정 등록 시에만 평가됩니다. 기존 계정의 로그인은 가입 속도 제한으로 차단되지 않습니다.
관련 리소스
- 키 없는 MCP 서버 및 기계 판독 가능한 컨텍스트 파일에 대해 알아보려면 AI 에이전트 연동 가이드를 확인하세요.
- 다국어 클라이언트 예제는 빠른 시작을 참조하세요.
- 전체 오류 코드, 원인 및 자동 복구 조치는 오류 레퍼런스를 검토하세요.
다음 단계
x-api-key: $BLOCKVECTRA_API_KEY를 포함하여 첫 번째 JSON-RPC 또는 Data API 호출을 전송하세요.GET /v1/account를 사용하여 계정 잔액 및 한도 확인을 진행하세요.- 잔액 유지를 위해 Agent 프로그래밍 방식 충전 가이드를 따르세요.
최종 수정일: