Saltar al contenido principal
En resumen
La API de Firma de Blockradar te permite firmar criptográficamente mensajes de texto plano y datos estructurados (datos tipados) usando las claves privadas de tu billetera. Las firmas demuestran la propiedad de la billetera ante servicios de terceros sin mover fondos ni pagar comisiones de red (gas).

Requisitos Previos

Antes de usar la API de Firma, asegúrate de tener:
1

Clave API

Obtén tu clave API desde el Panel de Blockradar. Navega a Developers para generar una.
2

Billetera Creada

Crea una billetera principal desde el Panel de Blockradar. Navega a Wallets y crea una para tu blockchain objetivo. Necesitarás el walletId para las operaciones de firma.
3

Entorno

Elige entre Testnet (para desarrollo) o Mainnet (para producción). Las billeteras están aisladas por entorno.

Cómo Funciona

La API de Firma produce una firma criptográfica que demuestra que controlas una dirección de billetera específica. La salida firmada puede ser verificada por cualquier tercero sin acceder a tus claves privadas.

Firma de Mensajes

Firma mensajes de texto plano para demostrar la propiedad de la billetera. Funciona en todas las blockchains compatibles: EVM, Tron y Solana.

Firma de Datos Tipados

Firma datos estructurados siguiendo el estándar EIP-712. Se usa para aprobaciones sin gas (EIP-2612 Permit) y transferencias autorizadas (EIP-3009). Solo EVM.

Casos de uso comunes

  • Registro con proveedores de terceros — Demuestra que posees una dirección al registrarte con servicios como Iron, Circle u otros protocolos DeFi
  • Aprobaciones de tokens sin gas — Firma mensajes EIP-2612 Permit para autorizar el gasto de tokens sin una transacción en cadena
  • Transferencias autorizadas — Firma mensajes EIP-3009 TransferWithAuthorization para transferencias delegadas
  • Atestaciones fuera de cadena — Crea pruebas verificables de intención o acuerdo vinculadas a una dirección de billetera

Billetera Principal vs Dirección Hija

La API de Firma está disponible en dos niveles:

Billetera Principal

Firma usando las claves de la billetera principal. Ideal para operaciones a nivel de tesorería e integraciones con proveedores.

Dirección Hija

Firma usando las claves de una dirección hija específica. Úsalo cuando el tercero requiera una firma desde una dirección de depósito.

Endpoints

OperaciónBilletera PrincipalDirección Hija
Firmar MensajePOST /v1/wallets/{walletId}/signing/messagePOST /v1/wallets/{walletId}/addresses/{addressId}/signing/message
Firmar Datos TipadosPOST /v1/wallets/{walletId}/signing/typed-dataPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/typed-data

Firma de Mensajes

Firma un mensaje de texto plano con la clave privada de tu billetera. La API firma el mensaje, verifica que la firma coincida con la dirección de la billetera y devuelve tanto la firma como un registro de transacción.

Blockchains Compatibles

BlockchainEstándar de FirmaFormato de Firma
EVM (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo)EIP-191 (personal_sign)Codificada en hexadecimal con componentes r, s, v
TronTronWeb signMessageV2Cadena codificada en hexadecimal
SolanaEd25519Cadena codificada en Base58

Parámetros de Solicitud

ParámetroTipoRequeridoDescripción
messagestringEl mensaje de texto plano a firmar. Máximo 4,096 caracteres.
referencestringNoTu ID de seguimiento interno. Úsalo para idempotencia — las referencias duplicadas son rechazadas.
metadataobjectNoPares clave-valor personalizados almacenados con el registro de transacción.

Ejemplo de Firma de Mensaje

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/signing/message \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "message": "Please sign this message to verify your wallet ownership for Iron provider registration.",
    "reference": "iron-verification-001",
    "metadata": {
      "provider": "iron",
      "purpose": "wallet-verification"
    }
  }'

Respuesta EVM

{
  "message": "Message signed successfully",
  "statusCode": 200,
  "data": {
    "id": "770f9100-7338-4823-b1ce-3658fc67db09",
    "hash": "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e21335aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b31b",
    "status": "SUCCESS",
    "type": "SIGNED",
    "senderAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "recipientAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "signedTransaction": {
      "r": "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e2133",
      "s": "0x5aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b3",
      "v": 27,
      "signature": "0xdb095e6cbf...b31b"
    },
    "reference": "iron-verification-001",
    "metadata": {
      "provider": "iron",
      "purpose": "wallet-verification"
    },
    "confirmed": true,
    "createdAt": "2025-03-02T19:00:52.000Z"
  }
}

Respuesta Tron / Solana

Para Tron y Solana, el objeto signedTransaction contiene solo el campo signature (sin componentes r, s, v):
{
  "message": "Message signed successfully",
  "statusCode": 200,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "hash": "3xYkZ9...",
    "status": "SUCCESS",
    "type": "SIGNED",
    "senderAddress": "TJRabPrwbZy45sbavfcjinPJC18kjpRT9Y",
    "recipientAddress": "TJRabPrwbZy45sbavfcjinPJC18kjpRT9Y",
    "signedTransaction": {
      "signature": "3xYkZ9..."
    },
    "reference": "tron-verification-001",
    "confirmed": true,
    "createdAt": "2025-03-02T19:00:52.000Z"
  }
}

Campos de Respuesta

CampoDescripción
idID de transacción único para el registro de firma
hashLa firma criptográfica. Para EVM: cadena hexadecimal. Para Tron: cadena hexadecimal. Para Solana: cadena base58.
statusSiempre SUCCESS para firmas completadas
typeSiempre SIGNED para transacciones de firma
senderAddressLa dirección de billetera que produjo la firma
signedTransactionComponentes de la firma. EVM incluye r, s, v y la signature completa. Tron y Solana incluyen solo signature.
referenceTu cadena de referencia proporcionada (si la hay)
metadataTu objeto de metadata proporcionado (si lo hay)

Firma de Datos Tipados (Solo EVM)

Firma datos estructurados siguiendo el estándar EIP-712. Esto se usa para aprobaciones sin gas, transferencias delegadas y otros flujos de autorización en cadena que requieren una firma estructurada.
La firma de datos tipados solo está disponible para blockchains compatibles con EVM (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo). Tron y Solana no soportan EIP-712.

Estándares Compatibles

EstándarCaso de Uso
EIP-712Firma genérica de datos estructurados
EIP-2612 (Permit)Aprobaciones de tokens sin gas — aprueba el gasto sin una transacción en cadena
EIP-3009 (TransferWithAuthorization)Transferencias delegadas — autoriza una transferencia que un tercero envía

Parámetros de Solicitud

ParámetroTipoRequeridoDescripción
domainobjectSeparador de dominio EIP-712. Incluye name, version, chainId y verifyingContract.
typesobjectDefiniciones de tipos para los datos estructurados.
messageobjectLos datos a firmar, conforme a las definiciones de tipos.

Ejemplo de EIP-2612 Permit

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/signing/typed-data \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "domain": {
      "name": "USD Coin",
      "version": "2",
      "chainId": 11155111,
      "verifyingContract": "0xa0b86a33e6441b8c4c8c0c077bcdd28571685701"
    },
    "types": {
      "Permit": [
        { "name": "owner", "type": "address" },
        { "name": "spender", "type": "address" },
        { "name": "value", "type": "uint256" },
        { "name": "nonce", "type": "uint256" },
        { "name": "deadline", "type": "uint256" }
      ]
    },
    "message": {
      "owner": "0x742d35cc6634c0532925a3b8d4c9db96c4b4d8b6",
      "spender": "0x8ba1f109551bd432803012645aac136c4c8c8c0c",
      "value": "1000000000",
      "nonce": "0",
      "deadline": "1641081600"
    }
  }'

Respuesta de Datos Tipados

{
  "message": "Typed data signed successfully",
  "statusCode": 200,
  "data": {
    "id": "770f9100-7338-4823-b1ce-3658fc67db09",
    "hash": "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e21335aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b31b",
    "status": "SUCCESS",
    "type": "SIGNED",
    "senderAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "recipientAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "signedTransaction": {
      "r": "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e2133",
      "s": "0x5aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b3",
      "v": 27,
      "signature": "0xdb095e6cbf...b31b"
    },
    "confirmed": true,
    "createdAt": "2025-03-02T19:00:52.000Z"
  }
}

Campos del Objeto Domain

CampoTipoRequeridoDescripción
namestringEl nombre del dominio de firma (ej., el nombre del token o de la dApp)
versionstringLa versión del dominio
chainIdnumberEl ID de cadena. Debe coincidir con la red blockchain de la billetera.
verifyingContractstringLa dirección del contrato que verificará la firma
saltstringNoSalt de dominio opcional para EIP-712 v4
Validación de Chain ID
El chainId en tu objeto domain debe coincidir con el ID de cadena de la red blockchain de la billetera. Si no coinciden, la API devuelve un error 400 Chain ID mismatch.

Firma con Dirección Hija

Firma mensajes o datos tipados usando una dirección hija específica en lugar de la billetera principal:
curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/signing/message \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "message": "Verify ownership of deposit address for provider onboarding.",
    "reference": "address-verify-001"
  }'
La firma con dirección hija sigue el mismo formato de solicitud y respuesta que la firma con billetera principal. La única diferencia es la URL del endpoint, que incluye el addressId.

Eventos de Webhook

Las operaciones de firma activan un webhook con el registro de transacción:
EventoDescripción
signed.successMensaje o datos tipados firmados y verificados

Payload del Webhook

{
  "event": "signed.success",
  "data": {
    "id": "770f9100-7338-4823-b1ce-3658fc67db09",
    "hash": "0xdb095e6cbf...b31b",
    "status": "SUCCESS",
    "type": "SIGNED",
    "senderAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "recipientAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "signedTransaction": {
      "r": "0xdb095e6cbf...2133",
      "s": "0x5aa3918399...89b3",
      "v": 27,
      "signature": "0xdb095e6cbf...b31b"
    },
    "reference": "iron-verification-001",
    "metadata": {
      "provider": "iron",
      "purpose": "wallet-verification"
    },
    "wallet": {
      "id": "d236a191-c1d4-423c-a439-54ce6542ca41",
      "name": "Ethereum Master Wallet"
    },
    "blockchain": {
      "name": "ethereum",
      "network": "testnet"
    },
    "confirmed": true,
    "createdAt": "2025-03-02T19:00:52.000Z"
  }
}

Ejemplo de Flujo Completo

Aquí tienes una implementación completa para firmar un mensaje y enviar la firma a un proveedor de terceros:
async function signAndVerifyWithProvider(walletId, providerMessage) {
  const apiKey = process.env.BLOCKRADAR_API_KEY;
  const baseUrl = 'https://api.blockradar.co/v1';

  // Paso 1: Firmar el mensaje
  const signResponse = await fetch(
    `${baseUrl}/wallets/${walletId}/signing/message`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        message: providerMessage,
        reference: `provider-verify-${Date.now()}`
      })
    }
  ).then(r => r.json());

  if (signResponse.statusCode !== 200) {
    throw new Error(`Signing failed: ${signResponse.message}`);
  }

  const { hash, senderAddress } = signResponse.data;

  // Paso 2: Enviar la firma al proveedor de terceros
  // El proveedor puede verificar que la firma coincide con la dirección de la billetera
  // sin acceder a tus claves privadas
  return {
    address: senderAddress,
    signature: hash,
    message: providerMessage
  };
}

// Uso
signAndVerifyWithProvider(
  'wallet-uuid',
  'I authorize Iron to manage assets on my behalf.'
);

Respuestas de Error

{
  "message": "Wallet not found",
  "statusCode": 404
}
El walletId no existe o no pertenece a tu negocio.
{
  "message": "Address not found",
  "statusCode": 404
}
El addressId no existe o no está asociado con la billetera especificada.
{
  "message": "Typed data signing is only supported for EVM blockchains",
  "statusCode": 400
}
La firma de datos tipados (EIP-712) solo está disponible en cadenas compatibles con EVM. Usa la firma de mensajes para Tron y Solana.
{
  "message": "Chain ID mismatch",
  "statusCode": 400
}
El chainId en tu objeto domain de datos tipados no coincide con la red blockchain de la billetera.
{
  "message": "Signature verification failed",
  "statusCode": 400
}
La verificación de ida y vuelta interna falló. Esto indica un error del sistema — contacta a soporte.

Mejores Prácticas

Seguridad

  • Usa referencias — Rastrea las operaciones de firma con IDs de referencia únicos para auditoría e idempotencia
  • Verifica el mensaje — Antes de firmar, confirma que el contenido del mensaje coincida con lo que espera el servicio de terceros
  • Limita la longitud del mensaje — Los mensajes están limitados a 4,096 caracteres. Mantén los mensajes concisos y específicos

Integración

  • Sin comisiones de gas — Las operaciones de firma son fuera de cadena y no requieren saldo de token nativo
  • Respuesta inmediata — Las firmas se generan de forma síncrona. No se necesita polling ni esperar webhooks para la firma en sí
  • Escucha los webhooks — Usa webhooks para mantener un registro de auditoría de todos los eventos de firma

Datos Tipados

  • Coincide los chain IDs — El chainId en tu domain debe coincidir con la red de la billetera. Usa chain IDs de sandbox (testnet) para pruebas y chain IDs de producción (mainnet) para operaciones en vivo
  • Verifica el contrato — El verifyingContract debe ser el contrato que verificará la firma en cadena

Referencia de API

Endpoints de Billetera Principal

EndpointDescripción
Firmar MensajeFirma un mensaje de texto plano
Firmar Datos TipadosFirma datos estructurados EIP-712

Endpoints de Dirección Hija

EndpointDescripción
Firmar MensajeFirma un mensaje de texto plano desde una dirección hija
Firmar Datos TipadosFirma datos estructurados EIP-712 desde una dirección hija