> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blockradar.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Firmar

> Firma mensajes, datos tipados y transacciones en crudo con las claves de tu billetera

<Note>
  En resumen<br />
  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.
</Note>

## Requisitos Previos

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

<Steps>
  <Step title="Clave API">
    Obtén tu clave API desde el [Panel de Blockradar](https://dashboard.blockradar.co). Navega a **Developers** para generar una.
  </Step>

  <Step title="Billetera Creada">
    Crea una billetera principal desde el [Panel de Blockradar](https://dashboard.blockradar.co). Navega a **Wallets** y crea una para tu blockchain objetivo. Necesitarás el `walletId` para las operaciones de firma.
  </Step>

  <Step title="Entorno">
    Elige entre **Testnet** (para desarrollo) o **Mainnet** (para producción). Las billeteras están aisladas por entorno.
  </Step>
</Steps>

## 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.

<CardGroup cols={2}>
  <Card title="Firma de Mensajes" icon="pen">
    Firma mensajes de texto plano para demostrar la propiedad de la billetera. Funciona en todas las blockchains compatibles: EVM, Tron y Solana.
  </Card>

  <Card title="Firma de Datos Tipados" icon="file-signature">
    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.
  </Card>

  <Card title="Firma de Transacciones" icon="file-contract">
    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.
  </Card>

  <Card title="Broadcast de Transacciones" icon="tower-broadcast">
    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.
  </Card>
</CardGroup>

### 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:

<CardGroup cols={2}>
  <Card title="Billetera Principal" icon="wallet">
    Firma usando las claves de la billetera principal. Ideal para operaciones a nivel de tesorería e integraciones con proveedores.
  </Card>

  <Card title="Dirección Hija" icon="address-card">
    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.
  </Card>
</CardGroup>

### Endpoints

| Operación            | Billetera Principal                               | Dirección Hija                                                          |
| -------------------- | ------------------------------------------------- | ----------------------------------------------------------------------- |
| Firmar Mensaje       | `POST /v1/wallets/{walletId}/signing/message`     | `POST /v1/wallets/{walletId}/addresses/{addressId}/signing/message`     |
| Firmar Datos Tipados | `POST /v1/wallets/{walletId}/signing/typed-data`  | `POST /v1/wallets/{walletId}/addresses/{addressId}/signing/typed-data`  |
| Firmar Transacción   | `POST /v1/wallets/{walletId}/signing/transaction` | `POST /v1/wallets/{walletId}/addresses/{addressId}/signing/transaction` |
| Firmar + Broadcast   | `POST /v1/wallets/{walletId}/signing/broadcast`   | `POST /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

| Blockchain                                                   | Estándar de Firma        | Formato de Firma                                        |
| ------------------------------------------------------------ | ------------------------ | ------------------------------------------------------- |
| EVM (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo) | EIP-191 (personal\_sign) | Codificada en hexadecimal con componentes `r`, `s`, `v` |
| Tron                                                         | TronWeb signMessageV2    | Cadena codificada en hexadecimal                        |
| Solana                                                       | Ed25519                  | Cadena codificada en Base58                             |

### Parámetros de Solicitud

| Parámetro   | Tipo   | Requerido | Descripción                                                                                       |
| ----------- | ------ | --------- | ------------------------------------------------------------------------------------------------- |
| `message`   | string | Sí        | El mensaje de texto plano a firmar. Máximo 4,096 caracteres.                                      |
| `reference` | string | No        | Tu ID de seguimiento interno. Úsalo para idempotencia. Las referencias duplicadas son rechazadas. |
| `metadata`  | object | No        | Pares clave-valor personalizados almacenados con el registro de transacción.                      |

### Ejemplo de Firma de Mensaje

<CodeGroup>
  ```bash Curl theme={null}
  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"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    `https://api.blockradar.co/v1/wallets/${walletId}/signing/message`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        message: 'Please sign this message to verify your wallet ownership for Iron provider registration.',
        reference: 'iron-verification-001',
        metadata: {
          provider: 'iron',
          purpose: 'wallet-verification'
        }
      })
    }
  ).then(r => r.json());

  console.log('Signature:', response.data.hash);
  console.log('Signed transaction:', response.data.signedTransaction);
  ```

  ```php PHP theme={null}
  <?php

  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.blockradar.co/v1/wallets/{walletId}/signing/message",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode([
      "message" => "Please sign this message to verify your wallet ownership for Iron provider registration.",
      "reference" => "iron-verification-001",
      "metadata" => [
        "provider" => "iron",
        "purpose" => "wallet-verification"
      ]
    ]),
    CURLOPT_HTTPHEADER => [
      "Content-Type: application/json",
      "x-api-key: <api-key>"
    ],
  ]);

  $response = curl_exec($curl);
  curl_close($curl);

  echo $response;
  ```
</CodeGroup>

### Respuesta EVM

```json theme={null}
{
  "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`):

```json theme={null}
{
  "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

| Campo               | Descripción                                                                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `id`                | ID de transacción único para el registro de firma                                                                      |
| `hash`              | La firma criptográfica. Para EVM: cadena hexadecimal. Para Tron: cadena hexadecimal. Para Solana: cadena base58.       |
| `status`            | Siempre `SUCCESS` para firmas completadas                                                                              |
| `type`              | Siempre `SIGNED` para transacciones de firma                                                                           |
| `senderAddress`     | La dirección de billetera que produjo la firma                                                                         |
| `signedTransaction` | Componentes de la firma. EVM incluye `r`, `s`, `v` y la `signature` completa. Tron y Solana incluyen solo `signature`. |
| `reference`         | Tu cadena de referencia proporcionada (si la hay)                                                                      |
| `metadata`          | Tu 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.

<Warning>
  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.
</Warning>

### Estándares Compatibles

| Estándar                             | Caso de Uso                                                                    |
| ------------------------------------ | ------------------------------------------------------------------------------ |
| EIP-712                              | Firma 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ámetro | Tipo   | Requerido | Descripción                                                                               |
| --------- | ------ | --------- | ----------------------------------------------------------------------------------------- |
| `domain`  | object | Sí        | Separador de dominio EIP-712. Incluye `name`, `version`, `chainId` y `verifyingContract`. |
| `types`   | object | Sí        | Definiciones de tipos para los datos estructurados.                                       |
| `message` | object | Sí        | Los datos a firmar, conforme a las definiciones de tipos.                                 |

### Ejemplo de EIP-2612 Permit

<CodeGroup>
  ```bash Curl theme={null}
  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"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    `https://api.blockradar.co/v1/wallets/${walletId}/signing/typed-data`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        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'
        }
      })
    }
  ).then(r => r.json());

  console.log('Signature:', response.data.hash);
  console.log('r:', response.data.signedTransaction.r);
  console.log('s:', response.data.signedTransaction.s);
  console.log('v:', response.data.signedTransaction.v);
  ```
</CodeGroup>

### Respuesta de Datos Tipados

```json theme={null}
{
  "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

| Campo               | Tipo   | Requerido | Descripción                                                            |
| ------------------- | ------ | --------- | ---------------------------------------------------------------------- |
| `name`              | string | Sí        | El nombre del dominio de firma (ej., el nombre del token o de la dApp) |
| `version`           | string | Sí        | La versión del dominio                                                 |
| `chainId`           | number | Sí        | El ID de cadena. Debe coincidir con la red blockchain de la billetera. |
| `verifyingContract` | string | Sí        | La dirección del contrato que verificará la firma                      |
| `salt`              | string | No        | Salt de dominio opcional para EIP-712 v4                               |

<Warning>
  Validación de Chain ID<br />
  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`.
</Warning>

***

## 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:

<CodeGroup>
  ```bash Curl theme={null}
  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"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    `https://api.blockradar.co/v1/wallets/${walletId}/addresses/${addressId}/signing/message`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        message: 'Verify ownership of deposit address for provider onboarding.',
        reference: 'address-verify-001'
      })
    }
  ).then(r => r.json());

  console.log('Signature:', response.data.hash);
  ```
</CodeGroup>

<Tip>
  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`.
</Tip>

***

## Eventos de Webhook

Las operaciones de firma activan un webhook con el registro de transacción:

| Evento           | Descripción                                                                                                                                                                    |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `signed.success` | Firma 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.failed`  | El 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)

```json theme={null}
{
  "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.

```json theme={null}
{
  "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`.

```json theme={null}
{
  "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`.

```json theme={null}
{
  "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 para su firma y/o transmisión, sin necesidad de construir o gestionar tu propia infraestructura o nodos blockchain.

### Blockchains y Formatos Compatibles

| Blockchain | Formato del campo `transaction`                                                 | Cómo construirla                                                         |
| ---------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Solana     | Base64 de `VersionedTransaction.serialize()`                                    | Respuesta `/swap` de Jupiter API, o `@solana/web3.js` TransactionMessage |
| EVM        | JSON string de `{to, value, data, nonce, chainId, gasLimit, maxFeePerGas, ...}` | `ethers.js` populateTransaction()                                        |
| Tron       | JSON string del objeto de transacción TronWeb `{txID, raw_data, raw_data_hex}`  | `tronWeb.transactionBuilder.triggerSmartContract()`                      |

### Parámetros de Solicitud

| Parámetro     | Tipo   | Requerido | Descripción                                                                  |
| ------------- | ------ | --------- | ---------------------------------------------------------------------------- |
| `transaction` | string | Sí        | La transacción serializada sin firmar. El formato depende de la blockchain.  |
| `reference`   | string | No        | Tu ID de seguimiento interno.                                                |
| `metadata`    | object | No        | Pares clave-valor personalizados almacenados con el registro de transacción. |

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

<CodeGroup>
  ```javascript JavaScript theme={null}
  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);
  ```

  ```bash Curl theme={null}
  curl --request POST \
    --url https://api.blockradar.co/v1/wallets/{walletId}/signing/transaction \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: <api-key>' \
    --data '{
      "transaction": "<base64 unsigned VersionedTransaction>",
      "reference": "jupiter-swap-001"
    }'
  ```
</CodeGroup>

### Ejemplo de Firma de Transacción (EVM)

<CodeGroup>
  ```javascript JavaScript theme={null}
  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);
  ```

  ```bash Curl theme={null}
  curl --request POST \
    --url https://api.blockradar.co/v1/wallets/{walletId}/signing/transaction \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: <api-key>' \
    --data '{
      "transaction": "{\"to\":\"0xRecipient\",\"value\":\"0x2386F26FC10000\",\"nonce\":0,\"chainId\":11155111,\"gasLimit\":\"0x5208\",\"maxFeePerGas\":\"0x59682F00\",\"maxPriorityFeePerGas\":\"0x3B9ACA00\",\"type\":2}",
      "reference": "eth-transfer-001"
    }'
  ```
</CodeGroup>

### Respuesta Solo Firma (EVM)

```json theme={null}
{
  "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)

```json theme={null}
{
  "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)

```json theme={null}
{
  "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
  }
}
```

<Note>
  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`.
</Note>

### Formato de `signedTransaction` por Cadena

| Cadena | Tipo   | Formato                                                                                       | Qué hacer con él                                                            |
| ------ | ------ | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Solana | string | Bytes codificados en Base64 de la VersionedTransaction firmada                                | Decodifica a bytes y pasa a `connection.sendRawTransaction()`               |
| EVM    | string | Cadena hexadecimal que comienza con `0x` conteniendo la transacción firmada codificada en RLP | Pasa directamente a `eth_sendRawTransaction` o `provider.sendTransaction()` |
| Tron   | string | JSON string del objeto de transacción firmada conteniendo un array `signature`                | Parsea con `JSON.parse()` y pasa a `tronWeb.trx.sendRawTransaction()`       |

### Campo `hash` por Cadena

| Cadena | Formato                                  | Cómo se deriva                                                                                 |
| ------ | ---------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Solana | Cadena Base58                            | Primera firma de la transacción firmada                                                        |
| EVM    | Cadena hexadecimal que comienza con `0x` | Hash Keccak256 de los bytes de la transacción firmada                                          |
| Tron   | Cadena hexadecimal                       | El 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.

<Warning>
  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).
</Warning>

### Solicitud

Mismos parámetros que la firma de transacciones:

| Parámetro     | Tipo   | Requerido | Descripción                            |
| ------------- | ------ | --------- | -------------------------------------- |
| `transaction` | string | Sí        | La transacción serializada sin firmar. |
| `reference`   | string | No        | Tu ID de seguimiento interno.          |
| `metadata`    | object | No        | Pares clave-valor personalizados.      |

### Ejemplo de Broadcast

<CodeGroup>
  ```javascript JavaScript theme={null}
  // 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
  ```

  ```bash Curl theme={null}
  curl --request POST \
    --url https://api.blockradar.co/v1/wallets/{walletId}/signing/broadcast \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: <api-key>' \
    --data '{
      "transaction": "<base64 unsigned VersionedTransaction>",
      "reference": "jupiter-swap-broadcast-001"
    }'
  ```
</CodeGroup>

### Respuesta de Broadcast (Ejemplo Solana, inmediata)

```json theme={null}
{
  "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:

| Estado    | Significado                                                                                     |
| --------- | ----------------------------------------------------------------------------------------------- |
| `PENDING` | Transacción firmada, broadcast en cola. Recibes esto en la respuesta HTTP.                      |
| `SUCCESS` | Transacción confirmada en cadena. Se envía el webhook `signed.success`.                         |
| `FAILED`  | El broadcast falló después de agotar todos los reintentos. Se envía el webhook `signed.failed`. |

<Tip>
  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.
</Tip>

***

## Ejemplo de Flujo Completo

Aquí tienes una implementación completa para firmar un mensaje y enviar la firma a un proveedor de terceros:

```javascript theme={null}
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

<AccordionGroup>
  <Accordion title="Billetera No Encontrada">
    ```json theme={null}
    {
      "message": "Wallet not found",
      "statusCode": 404
    }
    ```

    El `walletId` no existe o no pertenece a tu negocio.
  </Accordion>

  <Accordion title="Dirección No Encontrada">
    ```json theme={null}
    {
      "message": "Address not found",
      "statusCode": 404
    }
    ```

    El `addressId` no existe o no está asociado con la billetera especificada.
  </Accordion>

  <Accordion title="Blockchain No Soportada (Datos Tipados)">
    ```json theme={null}
    {
      "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.
  </Accordion>

  <Accordion title="Chain ID No Coincide">
    ```json theme={null}
    {
      "message": "Chain ID mismatch",
      "statusCode": 400
    }
    ```

    El `chainId` en tu objeto domain de datos tipados no coincide con la red blockchain de la billetera.
  </Accordion>

  <Accordion title="Verificación de Firma Fallida">
    ```json theme={null}
    {
      "message": "Signature verification failed",
      "statusCode": 400
    }
    ```

    La verificación de ida y vuelta interna falló. Esto indica un error del sistema. Contacta a soporte.
  </Accordion>

  <Accordion title="Formato de Transacción Inválido (Solana)">
    ```json theme={null}
    {
      "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.
  </Accordion>

  <Accordion title="Formato de Transacción Inválido (EVM/Tron)">
    ```json theme={null}
    {
      "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.
  </Accordion>
</AccordionGroup>

***

## 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

| Endpoint                                                                                  | Descripción                                |
| ----------------------------------------------------------------------------------------- | ------------------------------------------ |
| [Firmar Mensaje](/es/api-reference/signing/master-wallet-sign-message)                    | Firma un mensaje de texto plano            |
| [Firmar Datos Tipados](/es/api-reference/signing/master-wallet-typed-data)                | Firma datos estructurados EIP-712          |
| [Firmar Transacción](/es/api-reference/signing/master-wallet-sign-transaction)            | Firma una transacción en crudo             |
| [Broadcast de Transacción](/es/api-reference/signing/master-wallet-broadcast-transaction) | Firma y transmite una transacción en crudo |

### Endpoints de Dirección Hija

| Endpoint                                                                                  | Descripción                                                         |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| [Firmar Mensaje](/es/api-reference/signing/child-address-sign-message)                    | Firma un mensaje de texto plano desde una dirección hija            |
| [Firmar Datos Tipados](/es/api-reference/signing/child-address-typed-data)                | Firma datos estructurados EIP-712 desde una dirección hija          |
| [Firmar Transacción](/es/api-reference/signing/child-address-sign-transaction)            | Firma una transacción en crudo desde una dirección hija             |
| [Broadcast de Transacción](/es/api-reference/signing/child-address-broadcast-transaction) | Firma y transmite una transacción en crudo desde una dirección hija |
