Saltar al contenido principal
En resumen
La API de Firma de Blockradar te permite firmar criptográficamente mensajes de texto plano, datos estructurados (datos tipados) y transacciones en crudo usando las claves privadas de tu billetera. Firma mensajes para demostrar la propiedad de la billetera. Firma transacciones construidas externamente (por ejemplo, swaps de Jupiter en Solana) sin exponer claves privadas, y opcionalmente transmítelas en cadena.

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.

Firma de Transacciones

Firma transacciones en crudo construidas externamente. Construye un swap en Jupiter, una llamada a contrato con ethers.js, o una transferencia con TronWeb, luego envía la transacción sin firmar y obtén la firma sin exponer claves privadas.

Broadcast de Transacciones

Firma y transmite una transacción en crudo en un solo paso. Blockradar firma la transacción y la envía en cadena mediante una cola confiable con reintentos automáticos.

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
  • Ejecución de swaps externos: Construye un swap de Jupiter en Solana, fírmalo con Blockradar y transmítelo en cadena
  • Interacciones con contratos personalizados: Construye cualquier transacción externamente y haz que Blockradar la firme y/o la envíe

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
Firmar TransacciónPOST /v1/wallets/{walletId}/signing/transactionPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/transaction
Firmar + BroadcastPOST /v1/wallets/{walletId}/signing/broadcastPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/broadcast

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, datos tipados, transacciones o realiza broadcast usando una dirección hija específica en lugar de la billetera principal. Las cuatro operaciones de firma están disponibles para direcciones hijas:
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.successFirma completada exitosamente. Para firma de mensajes/datos tipados/transacciones, se dispara inmediatamente. Para broadcast, se dispara después de la confirmación en cadena.
signed.failedEl broadcast de la transacción falló después de agotar todos los reintentos. Solo aplica al endpoint /broadcast.

Payload del Webhook (Firma de Mensaje o Datos Tipados)

{
  "event": "signed.success",
  "data": {
    "id": "770f9100-7338-4823-b1ce-3658fc67db09",
    "reference": "iron-verification-001",
    "senderAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "recipientAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "hash": "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e21335aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b31b",
    "confirmed": true,
    "status": "SUCCESS",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Message signed",
    "network": "testnet",
    "chainId": 11155111,
    "metadata": {
      "provider": "iron",
      "purpose": "wallet-verification"
    },
    "signedTransaction": {
      "r": "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e2133",
      "s": "0x5aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b3",
      "v": 27,
      "signature": "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e21335aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b31b"
    },
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2025-03-02T19:00:52.000Z",
    "updatedAt": "2025-03-02T19:00:52.000Z",
    "wallet": {
      "id": "d236a191-c1d4-423c-a439-54ce6542ca41",
      "name": "Ethereum Master Wallet",
      "address": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "85ffc132-3972-4c9e-99a5-5cf0ccb688bf",
      "name": "ethereum",
      "symbol": "eth",
      "slug": "ethereum",
      "isEvmCompatible": true,
      "tokenStandard": "ERC20"
    },
    "beneficiary": null
  }
}

Payload del Webhook (Firma de Transacción)

Para la firma de transacciones, el campo signedTransaction es un string (no un objeto). El formato depende de la cadena.
{
  "event": "signed.success",
  "data": {
    "id": "782942da-48b0-416b-924b-8f657ae637a7",
    "reference": "52TQawmiqYpNiWD2Ks0P",
    "senderAddress": "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446",
    "recipientAddress": "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446",
    "hash": "0xac4c73ca084608ac6b981e54db948dc80c15b4ea3ffd0c9f5781f3af7ad6fe51",
    "confirmed": true,
    "status": "SUCCESS",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Transaction signed",
    "network": "testnet",
    "chainId": 11155111,
    "metadata": null,
    "signedTransaction": "0x02f87383aa36a763843b9aca008459682f0082520894000000000000000000000000000000000000dead865af3107a400080c080a0b760...",
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2026-03-19T13:34:24.937Z",
    "updatedAt": "2026-03-19T13:34:24.937Z",
    "wallet": {
      "id": "3f9aca5c-38ee-4e1d-ab67-c084a2e37bb2",
      "name": "Ethereum Wallet",
      "address": "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "85ffc132-3972-4c9e-99a5-5cf0ccb688bf",
      "name": "ethereum",
      "symbol": "eth",
      "slug": "ethereum",
      "isEvmCompatible": true,
      "tokenStandard": "ERC20"
    },
    "beneficiary": null
  }
}

Payload del Webhook (Broadcast Exitoso)

Después de que la cola de broadcast confirma la transacción en cadena, recibes este webhook. El campo hash se actualiza al hash de transacción en cadena y confirmed cambia a true.
{
  "event": "signed.success",
  "data": {
    "id": "f3efdbaa-a1f8-4365-b3b4-768413c9a92b",
    "reference": "docs-test-broadcast",
    "senderAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "recipientAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "hash": "5bKNw9RX8aXkrK1VEHg5aPa1xtckpShPyenSRET4mUBXh5uCkWLFV5MhGRi4cMACDJvFn6VfkoKb75Pk4KYw6xtw",
    "confirmed": true,
    "status": "SUCCESS",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Transaction signed and broadcast",
    "network": "testnet",
    "chainId": 103,
    "metadata": null,
    "signedTransaction": "AeWpW65y80rSu+TU0CSrcvFNovyDiybKRjSskCpfffAFLM0GIYzx...",
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2026-03-19T13:35:09.921Z",
    "updatedAt": "2026-03-19T13:35:09.921Z",
    "wallet": {
      "id": "c72a6f21-6ab5-48ad-9f99-fd90a2d6d311",
      "name": "Solana Testnet Wallet",
      "address": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "196badf5-380f-4480-ab4a-d0e4304e91f0",
      "name": "solana",
      "symbol": "sol",
      "slug": "solana",
      "isEvmCompatible": false,
      "tokenStandard": null
    },
    "beneficiary": null
  }
}

Payload del Webhook (Broadcast Fallido)

Si el broadcast falla permanentemente después de todos los intentos de reintento, recibes este webhook. El status es FAILED y confirmed permanece en false.
{
  "event": "signed.failed",
  "data": {
    "id": "f3efdbaa-a1f8-4365-b3b4-768413c9a92b",
    "reference": "docs-test-broadcast",
    "senderAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "recipientAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "hash": "5bKNw9RX8aXkrK1VEHg5aPa1xtckpShPyenSRET4mUBXh5uCkWLFV5MhGRi4cMACDJvFn6VfkoKb75Pk4KYw6xtw",
    "confirmed": false,
    "status": "FAILED",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Transaction broadcast failed",
    "network": "testnet",
    "chainId": 103,
    "metadata": null,
    "signedTransaction": "AeWpW65y80rSu+TU0CSrcvFNovyDiybKRjSskCpfffAFLM0GIYzx...",
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2026-03-19T13:35:09.921Z",
    "updatedAt": "2026-03-19T13:35:09.921Z",
    "wallet": {
      "id": "c72a6f21-6ab5-48ad-9f99-fd90a2d6d311",
      "name": "Solana Testnet Wallet",
      "address": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "196badf5-380f-4480-ab4a-d0e4304e91f0",
      "name": "solana",
      "symbol": "sol",
      "slug": "solana",
      "isEvmCompatible": false,
      "tokenStandard": null
    },
    "beneficiary": null
  }
}

Firma de Transacciones

Firma una transacción en crudo sin firmar, construida externamente. Tú construyes la transacción usando cualquier SDK (ethers.js, TronWeb, Solana web3.js, Jupiter API), luego envías la transacción serializada sin firmar a Blockradar. Blockradar la firma con la clave privada de la billetera y devuelve la transacción firmada sin exponer jamás la clave a tu aplicación.

Blockchains y Formatos Compatibles

BlockchainFormato del campo transactionCómo construirla
SolanaBase64 de VersionedTransaction.serialize()Respuesta /swap de Jupiter API, o @solana/web3.js TransactionMessage
EVMJSON string de {to, value, data, nonce, chainId, gasLimit, maxFeePerGas, ...}ethers.js populateTransaction()
TronJSON string del objeto de transacción TronWeb {txID, raw_data, raw_data_hex}tronWeb.transactionBuilder.triggerSmartContract()

Parámetros de Solicitud

ParámetroTipoRequeridoDescripción
transactionstringLa transacción serializada sin firmar. El formato depende de la blockchain.
referencestringNoTu ID de seguimiento interno.
metadataobjectNoPares clave-valor personalizados almacenados con el registro de transacción.

Ejemplo de Firma de Transacción (Solana + Jupiter)

import { Connection, PublicKey, VersionedTransaction } from '@solana/web3.js';

// Paso 1: Construir la transacción de swap via Jupiter API
const quoteResponse = await fetch(
  'https://quote-api.jup.ag/v6/quote?inputMint=SOL&outputMint=USDC&amount=1000000&slippageBps=50'
).then(r => r.json());

const swapResponse = await fetch('https://quote-api.jup.ag/v6/swap', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    quoteResponse,
    userPublicKey: walletAddress, // Your Blockradar wallet's Solana address
    wrapAndUnwrapSol: true,
  })
}).then(r => r.json());

// Paso 2: Enviar la transacción sin firmar a Blockradar para firma
const signResponse = await fetch(
  `https://api.blockradar.co/v1/wallets/${walletId}/signing/transaction`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': apiKey
    },
    body: JSON.stringify({
      transaction: swapResponse.swapTransaction, // Base64 VersionedTransaction
      reference: 'jupiter-swap-001'
    })
  }
).then(r => r.json());

console.log('Signed tx:', signResponse.data.signedTransaction);
console.log('Hash:', signResponse.data.hash);

Ejemplo de Firma de Transacción (EVM)

import { ethers } from 'ethers';

// Paso 1: Construir la transacción sin firmar
const provider = new ethers.providers.JsonRpcProvider('https://rpc.sepolia.org');
const nonce = await provider.getTransactionCount(walletAddress);
const feeData = await provider.getFeeData();

const unsignedTx = JSON.stringify({
  to: '0xRecipientAddress',
  value: ethers.utils.parseEther('0.01').toHexString(),
  nonce,
  chainId: 11155111, // Sepolia
  gasLimit: ethers.utils.hexlify(21000),
  maxFeePerGas: feeData.maxFeePerGas.toHexString(),
  maxPriorityFeePerGas: feeData.maxPriorityFeePerGas.toHexString(),
  type: 2,
});

// Paso 2: Enviar a Blockradar para firma
const signResponse = await fetch(
  `https://api.blockradar.co/v1/wallets/${walletId}/signing/transaction`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': apiKey
    },
    body: JSON.stringify({
      transaction: unsignedTx,
      reference: 'eth-transfer-001'
    })
  }
).then(r => r.json());

// La transacción firmada se puede transmitir via cualquier RPC
// await provider.sendTransaction(signResponse.data.signedTransaction);

Respuesta Solo Firma (EVM)

{
  "statusCode": 200,
  "message": "Transaction signed successfully",
  "data": {
    "id": "782942da-48b0-416b-924b-8f657ae637a7",
    "reference": "52TQawmiqYpNiWD2Ks0P",
    "senderAddress": "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446",
    "recipientAddress": "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446",
    "hash": "0xac4c73ca084608ac6b981e54db948dc80c15b4ea3ffd0c9f5781f3af7ad6fe51",
    "confirmed": true,
    "status": "SUCCESS",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Transaction signed",
    "network": "testnet",
    "chainId": 11155111,
    "metadata": null,
    "signedTransaction": "0x02f87383aa36a763843b9aca008459682f0082520894000000000000000000000000000000000000dead865af3107a400080c080a0b760...",
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2026-03-19T13:34:24.937Z",
    "updatedAt": "2026-03-19T13:34:24.937Z",
    "wallet": {
      "id": "3f9aca5c-38ee-4e1d-ab67-c084a2e37bb2",
      "name": "Ethereum Wallet",
      "address": "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "85ffc132-3972-4c9e-99a5-5cf0ccb688bf",
      "name": "ethereum",
      "symbol": "eth",
      "slug": "ethereum",
      "isEvmCompatible": true,
      "tokenStandard": "ERC20"
    },
    "beneficiary": null
  }
}

Respuesta Solo Firma (Solana)

{
  "statusCode": 200,
  "message": "Transaction signed successfully",
  "data": {
    "id": "02f404a5-d13e-4bcf-8ad5-c5f51c04fa49",
    "reference": "qZmQqDiIp9owMzQJcDbv",
    "senderAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "recipientAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "hash": "TjphHHAzjhRBn8t1qhhTRWpUxvkATBnzeRBB8fonWkYpR1gDh4t99rmgah3hrwoCbD3L9Ex1a7SYjjX2TePio3s",
    "confirmed": true,
    "status": "SUCCESS",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Transaction signed",
    "network": "testnet",
    "chainId": 103,
    "metadata": null,
    "signedTransaction": "ARcO4DT2IYg/wemCZy4iYXVRzlGruYHUTGqIcbWI/uWeWet6MNZKVVvUF4yT5GQjRqrb1QD1TaAoflyXXatxzAaAAQABA...",
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2026-03-19T13:38:45.326Z",
    "updatedAt": "2026-03-19T13:38:45.326Z",
    "wallet": {
      "id": "c72a6f21-6ab5-48ad-9f99-fd90a2d6d311",
      "name": "Solana Testnet Wallet",
      "address": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "196badf5-380f-4480-ab4a-d0e4304e91f0",
      "name": "solana",
      "symbol": "sol",
      "slug": "solana",
      "isEvmCompatible": false,
      "tokenStandard": null
    },
    "beneficiary": null
  }
}

Respuesta Solo Firma (Tron)

{
  "statusCode": 200,
  "message": "Transaction signed successfully",
  "data": {
    "id": "af44218f-d38b-472b-9834-49f461a20fd4",
    "reference": "J6RugzxXI6cdpeMXrhh",
    "senderAddress": "TMUZSkS3aF1pZxnTokWikUQH7SYt3bNb6G",
    "recipientAddress": "TMUZSkS3aF1pZxnTokWikUQH7SYt3bNb6G",
    "hash": "3180f971f692a78f62050278149d746abd946fbd1797a414f5ad0d5ed45c902b",
    "confirmed": true,
    "status": "SUCCESS",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Transaction signed",
    "network": "testnet",
    "chainId": 3448148188,
    "metadata": null,
    "signedTransaction": "{\"visible\":false,\"txID\":\"3180f971f692a78f...\",\"raw_data\":{\"contract\":[{\"parameter\":{\"value\":{\"to_address\":\"418840e6c55b9ada...\",\"owner_address\":\"417e3682ec8f5b98...\",\"amount\":1000000},\"type_url\":\"type.googleapis.com/protocol.TransferContract\"},\"type\":\"TransferContract\"}],\"ref_block_bytes\":\"513f\",\"ref_block_hash\":\"08c7d5da0ddd12fb\",\"expiration\":1773927585000,\"timestamp\":1773927525000},\"signature\":[\"d5adac23f23414083ef4f93b995a4a18...\"]}",
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2026-03-19T13:38:47.096Z",
    "updatedAt": "2026-03-19T13:38:47.096Z",
    "wallet": {
      "id": "c4bbebea-6cec-4021-b842-ffead75fd0f1",
      "name": "Tron Wallet",
      "address": "TMUZSkS3aF1pZxnTokWikUQH7SYt3bNb6G",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "fa91a922-3838-45f6-8a88-a4c771e1443a",
      "name": "tron",
      "symbol": "trx",
      "slug": "tron",
      "isEvmCompatible": false,
      "tokenStandard": "TRC20"
    },
    "beneficiary": null
  }
}
Para la firma de transacciones, signedTransaction es un string, no un objeto. Esto es diferente de la firma de mensajes donde devuelve un objeto con componentes de firma como r, s, v.

Formato de signedTransaction por Cadena

CadenaTipoFormatoQué hacer con él
SolanastringBytes codificados en Base64 de la VersionedTransaction firmadaDecodifica a bytes y pasa a connection.sendRawTransaction()
EVMstringCadena hexadecimal que comienza con 0x conteniendo la transacción firmada codificada en RLPPasa directamente a eth_sendRawTransaction o provider.sendTransaction()
TronstringJSON string del objeto de transacción firmada conteniendo un array signatureParsea con JSON.parse() y pasa a tronWeb.trx.sendRawTransaction()

Campo hash por Cadena

CadenaFormatoCómo se deriva
SolanaCadena Base58Primera firma de la transacción firmada
EVMCadena hexadecimal que comienza con 0xHash Keccak256 de los bytes de la transacción firmada
TronCadena hexadecimalEl campo txID del objeto de transacción, calculado durante la construcción de la transacción

Broadcast de Transacciones

Firma y transmite una transacción en crudo en un solo paso. Blockradar firma la transacción, luego la envía en cadena mediante una cola confiable con reintentos automáticos. La API responde inmediatamente con estado PENDING. Recibirás un webhook signed.success o signed.failed cuando el resultado en cadena sea confirmado.
El broadcast requiere fondos de testnet/mainnet en la billetera para pagar las comisiones de gas. La transacción debe ser válida y no estar expirada (los blockhashes de Solana expiran en ~90 segundos).

Solicitud

Mismos parámetros que la firma de transacciones:
ParámetroTipoRequeridoDescripción
transactionstringLa transacción serializada sin firmar.
referencestringNoTu ID de seguimiento interno.
metadataobjectNoPares clave-valor personalizados.

Ejemplo de Broadcast

// Construir la tx sin firmar (igual que los ejemplos de solo firma anteriores)
const unsignedTx = swapResponse.swapTransaction; // Jupiter base64 tx

// Firmar + broadcast en una sola llamada
const broadcastResponse = await fetch(
  `https://api.blockradar.co/v1/wallets/${walletId}/signing/broadcast`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': apiKey
    },
    body: JSON.stringify({
      transaction: unsignedTx,
      reference: 'jupiter-swap-broadcast-001'
    })
  }
).then(r => r.json());

console.log('Status:', broadcastResponse.data.status); // "PENDING"
console.log('Transaction ID:', broadcastResponse.data.id);
// Esperar webhook: signed.success o signed.failed

Respuesta de Broadcast (Ejemplo Solana, inmediata)

{
  "statusCode": 200,
  "message": "Transaction signed and broadcast initiated",
  "data": {
    "id": "f3efdbaa-a1f8-4365-b3b4-768413c9a92b",
    "reference": "docs-test-broadcast",
    "senderAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "recipientAddress": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
    "hash": "5bKNw9RX8aXkrK1VEHg5aPa1xtckpShPyenSRET4mUBXh5uCkWLFV5MhGRi4cMACDJvFn6VfkoKb75Pk4KYw6xtw",
    "confirmed": false,
    "status": "PENDING",
    "type": "SIGNED",
    "createdChannel": "api",
    "reason": "Transaction signed and broadcast",
    "network": "testnet",
    "chainId": 103,
    "metadata": null,
    "signedTransaction": "AeWpW65y80rSu+TU0CSrcvFNovyDiybKRjSskCpfffAFLM0GIYzx...",
    "amount": null,
    "amountUSD": "0.00",
    "fee": null,
    "feeUSD": null,
    "currency": "USD",
    "createdAt": "2026-03-19T13:35:09.921Z",
    "updatedAt": "2026-03-19T13:35:09.921Z",
    "wallet": {
      "id": "c72a6f21-6ab5-48ad-9f99-fd90a2d6d311",
      "name": "Solana Testnet Wallet",
      "address": "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw",
      "isActive": true,
      "status": "ACTIVE",
      "network": "testnet"
    },
    "asset": null,
    "blockchain": {
      "id": "196badf5-380f-4480-ab4a-d0e4304e91f0",
      "name": "solana",
      "symbol": "sol",
      "slug": "solana",
      "isEvmCompatible": false,
      "tokenStandard": null
    },
    "beneficiary": null
  }
}

Ciclo de Vida del Broadcast

La transacción pasa por estos estados:
EstadoSignificado
PENDINGTransacción firmada, broadcast en cola. Recibes esto en la respuesta HTTP.
SUCCESSTransacción confirmada en cadena. Se envía el webhook signed.success.
FAILEDEl broadcast falló después de agotar todos los reintentos. Se envía el webhook signed.failed.
La cola de broadcast reintenta hasta 10 veces con intervalos de 5 minutos. Para Solana, si el blockhash expira, los reintentos no ayudarán. Necesitarás reconstruir la transacción con un blockhash fresco.

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.
{
  "message": "Invalid transaction format: expected a base64-encoded Solana VersionedTransaction",
  "statusCode": 400
}
El campo transaction no es base64 válido, o los bytes decodificados no son una VersionedTransaction de Solana válida.
{
  "message": "Invalid transaction format: expected a JSON string",
  "statusCode": 400
}
El campo transaction no es JSON válido. Las transacciones EVM y Tron deben ser objetos serializados como JSON string.

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

Firma de Transacciones

  • Construye la transacción con el remitente correcto: La transacción sin firmar debe usar la clave pública de la billetera o dirección hija como el pagador de comisiones (Solana) o remitente (EVM/Tron). Si la clave no coincide, la firma fallará.
  • Los blockhashes de Solana expiran rápido: Los blockhashes de Solana son válidos por aproximadamente 60 a 90 segundos. Construye la transacción y llama al endpoint de firma rápidamente. Si usas broadcast, los reintentos de la cola no ayudarán una vez que el blockhash expire.
  • Gestión de nonce en EVM: Configura el nonce correctamente. Si el nonce ya fue usado, el broadcast fallará. Consulta el nonce desde la cadena inmediatamente antes de construir la transacción.
  • Expiración en Tron: Las transacciones de Tron tienen una ventana de expiración de 24 horas configurada durante la construcción. Esto da tiempo suficiente para la firma y el broadcast.
  • Solo firma vs broadcast: Usa /signing/transaction cuando quieras transmitir la transacción tú mismo o a través de otro servicio. Usa /signing/broadcast cuando quieras que Blockradar maneje el envío con reintentos automáticos.

Referencia de API

Endpoints de Billetera Principal

EndpointDescripción
Firmar MensajeFirma un mensaje de texto plano
Firmar Datos TipadosFirma datos estructurados EIP-712
Firmar TransacciónFirma una transacción en crudo
Broadcast de TransacciónFirma y transmite una transacción en crudo

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
Firmar TransacciónFirma una transacción en crudo desde una dirección hija
Broadcast de TransacciónFirma y transmite una transacción en crudo desde una dirección hija