プログラムによる登録:エージェントと 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 つのステップで構成されます:
- challenge のリクエスト:
POST /auth/siwe/challengeにリクエストを送信し、サーバーが生成したサインインメッセージを取得します。 - メッセージへの署名:イーサリアム EOA ウォレットを使用して、EIP-191(
personal_sign)でメッセージ本文にそのまま署名します。 - ログイン / アカウント作成:メッセージ本文と署名を
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
以下のスクリプトは、ウォレットの認証情報を読み取り、challenge とログインのシーケンスを完了し、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
doneBase URL とプログラムモード
すべての認証およびキー管理エンドポイントは、公式のベース URL を使用します:
https://console-api.blockvectra.com/v1Origin ヘッダーの省略
プログラムによるリクエストはプログラムモードで動作します:
- challenge(
POST /auth/siwe/challenge)と login(POST /auth/siwe/login)の両方のリクエストで、Originヘッダーを含めてはなりません(curlや標準的な HTTP クライアントはデフォルトでこのヘッダーを省略します。手動で追加しないでください)。 Originヘッダーが送信され、それが設定済みの Web コンソールドメインでない場合(空文字列やnullを含む)、challenge リクエストは HTTP 400invalid_requestを返します。- ログイン時のモードが challenge 時のモードと一致しない場合(例えば、
Originなしでプログラム用 challenge をリクエストした後にOriginヘッダー付きでログインを送信した場合、またはその逆)、login リクエストは HTTP 400siwe_invalid(reason: domain_mismatch)を返します。
メッセージの完全性とウォレットの要件
- メッセージの改変禁止とそのままの送信:クライアントは、challenge エンドポイントから返されたメッセージテキストをそのまま署名し送信する必要があります。空白、ドメイン、チェーン ID、その他のフィールドを一切変更しないでください。変更を加えると、HTTP 400
siwe_invalid(reason: signature)が返されます。 - 対応ウォレット:イーサリアムメインネット(チェーン ID 1)の EOA(Externally Owned Account)。署名は 65 バイトの ECDSA 署名(
personal_sign)である必要があります。コントラクトウォレット(EIP-1271)およびスマートアカウントはサポートされていません。 - challenge の有効期間:各 challenge の nonce は 1 回限り有効で、5 分後に失効します。
リクエストボディと登録時のアトリビューション(任意)
POST /auth/siwe/login のリクエストボディには、必須の認証パラメーターと任意の登録アトリビューションフィールドを指定できます:
- 必須フィールド:
message:challenge エンドポイントから取得した完全な SIWE メッセージ文字列。signature:イーサリアムウォレットで EIP-191 を用いてmessageに署名して生成された、65 バイトの 16 進数署名(0xプレフィックス付き)。
- 任意のアトリビューションフィールド(新規アカウント作成時に 1 回のみ保存され、それ以降のログインでは無視されます):
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 時間アイドル状態が続くと自動的に失効します。
- リフレッシュトークンなし:セッショントークンが失効した場合は、新しい challenge とログインフローを開始してください。
- ヘッダー:リクエストヘッダー
Authorization: Bearer rgs_...でセッショントークンを渡します。
API key の作成
- セッショントークンを指定して
POST /keysを呼び出し、API key(rgw_に続く 64 文字の 16 進数文字列)を作成します。 - 1 つのアカウントにつき、失効しておらず有効期限内のキー(
active+disabled)は最大 20 個まで保持できます。期限切れのキーはカウントされません。これを超えると、HTTP 409key_limit_reached(reason: active_keys、limit: 20)が返されます。先に不要なキーを失効させてください。この上限は、そのアカウントのすべての識別子、セッション、チェーンに適用されます。キーの作成とローテーションも 24 時間あたり最大 20 回に制限されており、これを超えると HTTP 429rate_limited(Retry-After: 3600)が返されます。 - 任意の上限と有効期限:
cu_cap(キーのライフタイム CU 上限、ソフトキャップ)および有効期限(expires_in_secsまたはexpires_at、キーポリシーで許可されている最大日数まで)を指定できます。有効期限が切れるか上限に達すると、サーバーは 403(JSON-RPC-32025、理由key_expiredまたはkey_cap_exhausted)を返します。 - シークレットである
api_keyは作成時に 1 度だけ返されます。シークレットマネージャーや環境変数に直ちに安全に保管してください。 - 1 つの API key は、JSON-RPC および Data API において、サポートされているすべてのチェーンで共通して利用できます。
セッションまたは API key を紛失した場合
BlockVectra では、エージェントのアカウント識別子は登録時に使用したイーサリアムウォレットアドレスに紐付けられます。セッショントークンが失効した場合や、API key が紛失・漏洩した場合でも、そのウォレットのみを使用して完全な制御を回復できます:
- 同じウォレットで再認証する:challenge をリクエストし、同じウォレットで署名して、ログインリクエスト(
POST /auth/siwe/login)を送信します。サーバーは署名を検証し、account_created: falseで既存のアカウントにログインして、新しいセッショントークンを発行します。 - 新しい API key を作成する:新しいセッショントークンを使用し、
Authorization: Bearer <token>ヘッダーを付けてPOST /keysに{"label": "..."}を送信します。エンドポイントは HTTP 201 を返し、作成されたキーの詳細がkeyに、一度限りのシークレットがapi_keyに含まれます。このキーを直ちに環境変数またはシークレットマネージャーに保存してください。 - アカウントのすべてのキーを一覧表示する:
- エンドポイント:
GET /keys - ヘッダー:
Authorization: Bearer <token> - クエリパラメーター:任意の
include_revoked=true(trueの場合、失効したキーを含めます。デフォルトは active / disabled のキーのみ)。 - レスポンス:HTTP 200 と JSON
{"items": [...]}。items配列の各要素には以下が含まれます:key_id:一意のキー識別子(文字列)label:キーのラベル(文字列または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 プレフィックスごとに 1 時間あたり 100 アカウントの割合で補充され、SIWE と OAuth の登録で共有されます:
- 登録制限を超過した場合、
POST /auth/siwe/loginは HTTP 429signup_rate_limitedを返し、Retry-Afterヘッダーで待機秒数を示します。 reasonフィールドによって制限の適用範囲が区別されます:per_ip:リクエスト元の IP プレフィックスに対する登録枠が使い果たされた場合。global:プラットフォーム全体の登録上限が使い果たされた場合。
- 登録レート制限は新規アカウントの登録時のみ評価されます。既存アカウントのログインが登録レート制限によってブロックされることはありません。
関連リソース
- キー不要の MCP サーバーや機械可読なコンテキストファイルについては、AI エージェント連携ガイドを参照してください。
- 複数言語によるクライアントの例については、クイックスタートを確認してください。
- すべてのエラーコード、理由、および自動復旧アクションについては、エラーリファレンスを参照してください。
次のステップ
x-api-key: $BLOCKVECTRA_API_KEYを指定して、最初の JSON-RPC または Data API コールを送信します。GET /v1/accountを使用して、アカウント残高と制限を確認します。- 残高を維持するには、Agent プログラムによるチャージガイドに従ってください。
最終更新: