Registro mediante código: inicio de sesión con billetera y creación de API keys para agentes y CI

Regístrate y crea una API key mediante código con una firma de billetera Ethereum (EIP-191), sin navegador, para agentes de IA, scripts y flujos de CI.

Para agentes de IA autónomos, pipelines de CI y scripts automatizados que se ejecutan sin navegador, BlockVectra ofrece un flujo de inicio de sesión y apertura de cuenta mediante código basado en firmas de billeteras Ethereum (EIP-4361 / EIP-191).

Seguridad de las API keys

Nunca pegues claves privadas, tokens de sesión ni API keys en conversaciones con IA, ni los envíes como argumentos de herramientas MCP.

Antes de registrarte, puedes probar el endpoint público sin API key https://api.blockvectra.com/v1/robinhood_mainnet/public (solo métodos JSON-RPC de billetera; la Data API requiere una API key; los métodos y límites dependen de /v1/chains); regístrate si la cuota no es suficiente.

Resumen del flujo

El flujo de registro y aprovisionamiento de API keys mediante código consta de cuatro pasos:

  1. Solicita el desafío: Envía una solicitud a POST /auth/siwe/challenge para obtener un mensaje de inicio de sesión generado por el servidor.
  2. Firma el mensaje: Firma el mensaje exacto con una billetera EOA de Ethereum mediante EIP-191 (personal_sign).
  3. Inicia sesión / abre una cuenta: Envía el mensaje sin cambios y la firma a POST /auth/siwe/login. En el primer inicio de sesión de una billetera, se crea una cuenta automáticamente (account_created: true). Las cuentas nuevas reciben 30,000,000 CU al registrarse — sin tarjeta de crédito.
  4. Crea una API key: Usa el token de sesión para llamar a POST /keys y crear una API key.

Ejemplos completos ejecutables

Empieza aquí: usa un firmante EOA de Ethereum local, crea una API key y compruébala con eth_blockNumber. Para el ejemplo en Bash, necesitas curl, jq y Foundry cast. Mantén las credenciales de la billetera en tu entorno local de firma.

Plantilla inicial completa: blockvectra/agent-quickstart

Los siguientes scripts leen las credenciales de la billetera, completan la secuencia de desafío e inicio de sesión, crean una API key, exportan o imprimen export BLOCKVECTRA_API_KEY=... para configurar el entorno y envían una solicitud de verificación eth_blockNumber:

Las nuevas API keys tardan unos segundos en activarse; estos ejemplos reintentan automáticamente.

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 base y modo programático

Todos los endpoints de autenticación y gestión de API keys usan la URL base oficial:

https://console-api.blockvectra.com/v1

Omisión de la cabecera Origin

Las solicitudes mediante código funcionan en modo programático:

  • Tanto las solicitudes de desafío (POST /auth/siwe/challenge) como las de inicio de sesión (POST /auth/siwe/login) deben omitir la cabecera Origin (curl y los clientes HTTP estándar la omiten de forma predeterminada; no la añadas manualmente).
  • Si se envía una cabecera Origin que no corresponde a un dominio configurado de la consola web (incluidas una cadena vacía o null), la solicitud de desafío devuelve HTTP 400 invalid_request.
  • Si el modo de inicio de sesión no coincide con el modo del desafío (por ejemplo, se solicita un desafío programático sin Origin y luego se envía el inicio de sesión con una cabecera Origin, o viceversa), la solicitud de inicio de sesión devuelve HTTP 400 siwe_invalid con reason: domain_mismatch.

Integridad del mensaje y requisitos de la billetera

  • Firma y envío sin cambios: Los clientes deben firmar y enviar el texto del mensaje exactamente como lo devuelve el endpoint de desafío. No cambies los espacios en blanco, el dominio, el Chain ID ni ningún campo. Cualquier modificación produce HTTP 400 siwe_invalid con reason: signature.
  • Billeteras compatibles: Cuentas de propiedad externa (EOA) de Ethereum mainnet (Chain ID 1). La firma debe ser una firma ECDSA de 65 bytes (personal_sign). No se admiten billeteras de contrato (EIP-1271) ni cuentas inteligentes.
  • Validez del desafío: El nonce de cada desafío es de un solo uso y caduca a los 5 minutos.

Cuerpo de la solicitud y atribución del registro (opcional)

El cuerpo de la solicitud POST /auth/siwe/login acepta parámetros obligatorios de autenticación y campos opcionales de atribución del registro:

  • Campos obligatorios:
    • message: La cadena completa del mensaje SIWE obtenida del endpoint de desafío.
    • signature: La firma hexadecimal de 65 bytes (con prefijo 0x) producida al firmar message mediante EIP-191 con una billetera Ethereum.
  • Campos opcionales de atribución (se guardan solo una vez al crear una cuenta; se ignoran en los siguientes inicios de sesión):
    • ref: Un token de canal en minúsculas que coincida con ^[a-z0-9._-]{1,64}$ (letras ASCII minúsculas, dígitos, ., _, -, de 1–64 caracteres). Por ejemplo, los agentes autónomos pueden establecerlo como el identificador de su framework o entorno de ejecución (p. ej., my-agent.v1). Los valores no válidos (incluidas mayúsculas, cadenas vacías, longitud excesiva o caracteres no admitidos) devuelven HTTP 400 invalid_request sin convertir mayúsculas a minúsculas e impiden crear la cuenta; omítelo o envía null cuando no corresponda.
    • referrer: Una cadena con la URL o el nombre de host de origen; solo los tipos que no sean cadenas devuelven HTTP 400.

Enviar campos no definidos, como signup_method, devuelve HTTP 400 invalid_request.

Tokens de sesión y API keys

Ciclo de vida del token de sesión

  • Formato: rgs_ seguido de 64 caracteres hexadecimales en minúsculas.
  • Validez: Duración máxima de 7 días; caduca automáticamente tras 24 horas de inactividad.
  • Sin token de renovación: Cuando caduque un token de sesión, inicia un nuevo flujo de desafío e inicio de sesión.
  • Cabecera: Envía el token de sesión en la cabecera de solicitud Authorization: Bearer rgs_....

Creación de API keys

  • Llama a POST /keys con el token de sesión para crear una API key (rgw_ seguido de 64 caracteres hexadecimales).
  • Cada cuenta puede tener hasta 20 API keys sin revocar ni caducar (active + disabled); las API keys caducadas no cuentan. Superar este límite devuelve HTTP 409 key_limit_reached con reason: active_keys y limit: 20; revoca primero una API key. El límite se aplica a todas las identidades, sesiones y cadenas de la cuenta. La creación y rotación de API keys también están limitadas a 20 por cada 24 horas; superar este límite devuelve HTTP 429 rate_limited con Retry-After: 3600.
  • Límite y caducidad opcionales: puedes proporcionar cu_cap (límite de CU durante toda la vida de la API key, de aplicación flexible) y una caducidad (expires_in_secs o expires_at, hasta el máximo de días permitido por la política de API keys); cuando caduque o se agote el límite, el servidor devuelve 403 (JSON-RPC -32025, motivo key_expired o key_cap_exhausted).
  • El secreto api_key se devuelve solo una vez, al crearlo. Guárdalo inmediatamente de forma segura en tu gestor de secretos o variables de entorno.
  • Una API key funciona en todas las cadenas compatibles con JSON-RPC y la Data API.

¿Perdiste tu sesión o API key?

En BlockVectra, la identidad de la cuenta de un agente está vinculada a la dirección de la billetera Ethereum usada durante el registro. Si tu token de sesión caduca o una API key se pierde o se filtra, puedes recuperar el control completo usando solo esa billetera:

  1. Vuelve a autenticarte con la misma billetera: Solicita un desafío, fírmalo con la misma billetera y envía la solicitud de inicio de sesión (POST /auth/siwe/login). El servidor verifica la firma, inicia sesión en la cuenta existente con account_created: false y emite un nuevo token de sesión.
  2. Crea una nueva API key: Con el nuevo token de sesión, llama a POST /keys con {"label": "..."} y la cabecera Authorization: Bearer <token>. El endpoint devuelve HTTP 201 con los detalles de la API key creada en key y el secreto de un solo uso en api_key. Guarda esta API key inmediatamente en tus variables de entorno o gestor de secretos.
  3. Lista todas las API keys de la cuenta:
    • Endpoint: GET /keys
    • Cabecera: Authorization: Bearer <token>
    • Parámetro de consulta: include_revoked=true opcional (cuando es true, incluye las API keys revocadas; de forma predeterminada, solo las activas/deshabilitadas).
    • Respuesta: HTTP 200 con JSON {"items": [...]}. Cada elemento de la matriz items incluye:
      • key_id: identificador único de la API key (cadena)
      • label: etiqueta de la API key (cadena o null)
      • status: estado ("active", "disabled" o "revoked")
      • created_at: fecha y hora de creación (cadena ISO 8601)
      • revoked_at: fecha y hora de revocación (cadena o null si no se ha revocado)
  4. Revoca las API keys sin uso o comprometidas:
    • Endpoint: POST /keys/{key_id}/revoke (nota: usa POST con el key_id de destino en la ruta; cuerpo de solicitud vacío)
    • Cabecera: Authorization: Bearer <token>
    • Comportamiento: idempotente; se pueden revocar API keys con estado active o disabled. Si ya está revocada, devuelve HTTP 200 sin cambios. Tras la revocación, se rechazan las solicitudes que usen esa API key.
    • Respuesta: HTTP 200 con el objeto de la API key revocada (los campos coinciden con el objeto anterior, con status: "revoked" y una fecha y hora en revoked_at).

Seguridad de las API keys y los secretos

Guarda las claves privadas de las billeteras y las API keys en variables de entorno o en un gestor de secretos. Nunca las incluyas en repositorios de código, las escribas en logs ni las pegues en conversaciones de chat con IA.

Recomendaciones de seguridad

  • Usa API keys de corta duración y revócalas al terminar: Para tareas automatizadas o efímeras, crea API keys de corta duración con expires_in_secs y revócalas inmediatamente mediante POST /keys/{key_id}/revoke cuando termines el trabajo.

Límites de frecuencia de registro (signup_rate_limited)

La creación de cuentas está sujeta a límites de frecuencia de registro. El depósito de tokens por IP tiene capacidad para 100 cuentas y se repone a 100 cuentas/hora por dirección IPv4 o prefijo IPv6 /64, compartido entre los registros SIWE y OAuth:

  • Al superar los límites de registro, POST /auth/siwe/login devuelve HTTP 429 signup_rate_limited con una cabecera Retry-After que indica los segundos de espera.
  • El campo reason distingue el ámbito del límite:
    • per_ip: se ha agotado el cupo de registros del prefijo IP de la solicitud.
    • global: se ha agotado el límite total de registros de la plataforma.
  • Los límites de frecuencia de registro solo evalúan el registro de nuevas cuentas. Los inicios de sesión de cuentas existentes no quedan bloqueados por estos límites.

Recursos relacionados

Próximos pasos

Última actualización:

En esta página