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

# 签名

> 使用您的钱包密钥签署消息、类型化数据和原始交易

<Note>
  简而言之<br />
  Blockradar 签名 API 允许您使用钱包的私钥对纯文本消息、结构化数据（类型化数据）和原始交易进行加密签名。签名消息可以证明钱包所有权。签名外部构建的交易（例如 Solana 上的 Jupiter 兑换）无需暴露私钥，还可以选择将交易广播到链上。
</Note>

## 前提条件

在使用签名 API 之前，请确保您已完成以下准备：

<Steps>
  <Step title="API 密钥">
    从 [Blockradar 控制台](https://dashboard.blockradar.co) 获取您的 API 密钥。导航至 **Developers** 生成密钥。
  </Step>

  <Step title="已创建钱包">
    从 [Blockradar 控制台](https://dashboard.blockradar.co) 创建主钱包。导航至 **Wallets** 并为目标区块链创建钱包。签名操作需要使用 `walletId`。
  </Step>

  <Step title="环境选择">
    选择 **Testnet**（测试网，用于开发）或 **Mainnet**（主网，用于生产）。钱包按环境隔离。
  </Step>
</Steps>

## 工作原理

签名 API 生成加密签名，证明您控制着特定的钱包地址。签名输出可以被任何第三方验证，而无需访问您的私钥。

<CardGroup cols={2}>
  <Card title="消息签名" icon="pen">
    签署纯文本消息以证明钱包所有权。支持所有区块链：EVM、Tron 和 Solana。
  </Card>

  <Card title="类型化数据签名" icon="file-signature">
    按照 EIP-712 标准签署结构化数据。用于无 Gas 授权（EIP-2612 Permit）和委托转账（EIP-3009）。仅限 EVM。
  </Card>

  <Card title="交易签名" icon="file-contract">
    签署外部构建的原始交易。在 Jupiter 上构建兑换、通过 ethers.js 进行合约调用或 TronWeb 转账，然后发送未签名的交易进行签名，无需暴露私钥。
  </Card>

  <Card title="交易广播" icon="tower-broadcast">
    一步完成原始交易的签名和广播。Blockradar 签名交易并通过可靠队列将其提交到链上，支持自动重试。
  </Card>
</CardGroup>

### 常见使用场景

* **第三方服务注册**：在接入 Iron、Circle 或其他 DeFi 协议等服务时，证明您拥有某个地址
* **无 Gas 代币授权**：签署 EIP-2612 Permit 消息以授权代币支出，无需链上交易
* **委托转账**：签署 EIP-3009 TransferWithAuthorization 消息以进行委托转账
* **链下证明**：创建与钱包地址关联的可验证意向或协议证明
* **外部兑换执行**：在 Solana 上构建 Jupiter 兑换，使用 Blockradar 签名，然后广播到链上
* **自定义合约交互**：在外部构建任意交易，由 Blockradar 签名和/或提交

## 主钱包与子地址

签名 API 可在两个层级使用：

<CardGroup cols={2}>
  <Card title="主钱包" icon="wallet">
    使用主钱包的密钥进行签名。适用于资金管理级别的操作和服务商集成。
  </Card>

  <Card title="子地址" icon="address-card">
    使用特定子地址的密钥进行签名。当第三方要求使用充值地址进行签名时使用。
  </Card>
</CardGroup>

### 接口端点

| 操作      | 主钱包                                               | 子地址                                                                     |
| ------- | ------------------------------------------------- | ----------------------------------------------------------------------- |
| 消息签名    | `POST /v1/wallets/{walletId}/signing/message`     | `POST /v1/wallets/{walletId}/addresses/{addressId}/signing/message`     |
| 类型化数据签名 | `POST /v1/wallets/{walletId}/signing/typed-data`  | `POST /v1/wallets/{walletId}/addresses/{addressId}/signing/typed-data`  |
| 交易签名    | `POST /v1/wallets/{walletId}/signing/transaction` | `POST /v1/wallets/{walletId}/addresses/{addressId}/signing/transaction` |
| 签名+广播   | `POST /v1/wallets/{walletId}/signing/broadcast`   | `POST /v1/wallets/{walletId}/addresses/{addressId}/signing/broadcast`   |

***

## 消息签名

使用钱包的私钥签署纯文本消息。API 会签署消息、验证签名与钱包地址匹配，并返回签名和交易记录。

### 支持的区块链

| 区块链                                                          | 签名标准                     | 签名格式                     |
| ------------------------------------------------------------ | ------------------------ | ------------------------ |
| EVM (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo) | EIP-191 (personal\_sign) | 十六进制编码，包含 `r`、`s`、`v` 组件 |
| Tron                                                         | TronWeb signMessageV2    | 十六进制编码字符串                |
| Solana                                                       | Ed25519                  | Base58 编码字符串             |

### 请求参数

| 参数          | 类型     | 必填 | 描述                                  |
| ----------- | ------ | -- | ----------------------------------- |
| `message`   | string | 是  | 要签署的纯文本消息。最大 4,096 个字符。             |
| `reference` | string | 否  | 您的内部追踪 ID。用于幂等性。重复的 reference 会被拒绝。 |
| `metadata`  | object | 否  | 与交易记录一起存储的自定义键值对。                   |

### 消息签名示例

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

### 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"
  }
}
```

### Tron / Solana 响应

对于 Tron 和 Solana，`signedTransaction` 对象仅包含 `signature` 字段（没有 `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"
  }
}
```

### 响应字段

| 字段                  | 描述                                                                      |
| ------------------- | ----------------------------------------------------------------------- |
| `id`                | 签名记录的唯一交易 ID                                                            |
| `hash`              | 加密签名。EVM：十六进制字符串。Tron：十六进制字符串。Solana：Base58 字符串。                        |
| `status`            | 对于已完成的签名，始终为 `SUCCESS`                                                  |
| `type`              | 对于签名交易，始终为 `SIGNED`                                                     |
| `senderAddress`     | 生成签名的钱包地址                                                               |
| `signedTransaction` | 签名组件。EVM 包含 `r`、`s`、`v` 和完整的 `signature`。Tron 和 Solana 仅包含 `signature`。 |
| `reference`         | 您提供的 reference 字符串（如有）                                                  |
| `metadata`          | 您提供的 metadata 对象（如有）                                                    |

***

## 类型化数据签名（仅限 EVM）

按照 EIP-712 标准签署结构化数据。用于无 Gas 授权、委托转账以及其他需要结构化签名的链上授权流程。

<Warning>
  类型化数据签名仅适用于 EVM 兼容的区块链（Ethereum、Polygon、BSC、Base、Arbitrum、Optimism、Celo）。Tron 和 Solana 不支持 EIP-712。
</Warning>

### 支持的标准

| 标准                                   | 使用场景                      |
| ------------------------------------ | ------------------------- |
| EIP-712                              | 通用结构化数据签名                 |
| EIP-2612 (Permit)                    | 无 Gas 代币授权。无需链上交易即可授权代币支出 |
| EIP-3009 (TransferWithAuthorization) | 委托转账。授权由第三方提交的转账          |

### 请求参数

| 参数        | 类型     | 必填 | 描述                                                                |
| --------- | ------ | -- | ----------------------------------------------------------------- |
| `domain`  | object | 是  | EIP-712 域分隔符。包括 `name`、`version`、`chainId` 和 `verifyingContract`。 |
| `types`   | object | 是  | 结构化数据的类型定义。                                                       |
| `message` | object | 是  | 要签署的数据，需符合类型定义。                                                   |

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

### 类型化数据响应

```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"
  }
}
```

### Domain 对象字段

| 字段                  | 类型     | 必填 | 描述                      |
| ------------------- | ------ | -- | ----------------------- |
| `name`              | string | 是  | 签名域的名称（例如代币名称或 dApp 名称） |
| `version`           | string | 是  | 域的版本                    |
| `chainId`           | number | 是  | 链 ID。必须与钱包的区块链网络匹配。     |
| `verifyingContract` | string | 是  | 将验证签名的合约地址              |
| `salt`              | string | 否  | EIP-712 v4 的可选域 salt    |

<Warning>
  链 ID 验证<br />
  域对象中的 `chainId` 必须与钱包所在区块链网络的链 ID 匹配。如果不匹配，API 将返回 `400 Chain ID mismatch` 错误。
</Warning>

***

## 子地址签名

使用特定子地址（而非主钱包）签署消息、类型化数据、交易或进行广播。所有四种签名操作均可用于子地址：

<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>
  子地址签名遵循与主钱包签名相同的请求和响应格式。唯一的区别是端点 URL 中包含了 `addressId`。
</Tip>

***

## Webhook 事件

签名操作会触发一个包含交易记录的 Webhook：

| 事件               | 描述                                         |
| ---------------- | ------------------------------------------ |
| `signed.success` | 签名成功完成。对于消息/类型化数据/交易签名，立即触发。对于广播，在链上确认后触发。 |
| `signed.failed`  | 交易广播在所有重试耗尽后失败。仅适用于 `/broadcast` 端点。       |

### Webhook 载荷（消息或类型化数据签名）

```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
  }
}
```

### Webhook 载荷（交易签名）

对于交易签名，`signedTransaction` 字段是字符串（而非对象）。格式取决于链。

```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
  }
}
```

### Webhook 载荷（广播成功）

广播队列在链上确认交易后，您会收到此 Webhook。`hash` 字段更新为链上交易哈希，`confirmed` 变为 `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
  }
}
```

### Webhook 载荷（广播失败）

如果广播在所有重试耗尽后永久失败，您会收到此 Webhook。`status` 为 `FAILED`，`confirmed` 保持 `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
  }
}
```

***

## 交易签名

签署外部构建的原始未签名交易。您可以使用任何 SDK（ethers.js、TronWeb、Solana web3.js、Jupiter API）构建交易，然后将序列化的未签名交易发送给 Blockradar 进行签名和/或广播，无需构建或管理自己的基础设施或区块链节点。

### 支持的区块链和格式

| 区块链    | `transaction` 字段格式                                                          | 构建方式                                                          |
| ------ | --------------------------------------------------------------------------- | ------------------------------------------------------------- |
| Solana | `VersionedTransaction.serialize()` 的 Base64 编码                              | Jupiter API `/swap` 响应，或 `@solana/web3.js` TransactionMessage |
| EVM    | `{to, value, data, nonce, chainId, gasLimit, maxFeePerGas, ...}` 的 JSON 字符串 | `ethers.js` populateTransaction()                             |
| Tron   | TronWeb 交易对象 `{txID, raw_data, raw_data_hex}` 的 JSON 字符串                    | `tronWeb.transactionBuilder.triggerSmartContract()`           |

### 请求参数

| 参数            | 类型     | 必填 | 描述                  |
| ------------- | ------ | -- | ------------------- |
| `transaction` | string | 是  | 序列化的未签名交易。格式取决于区块链。 |
| `reference`   | string | 否  | 您的内部追踪 ID。          |
| `metadata`    | object | 否  | 与交易记录一起存储的自定义键值对。   |

### 交易签名示例（Solana + Jupiter）

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { Connection, PublicKey, VersionedTransaction } from '@solana/web3.js';

  // Step 1: Build the swap transaction 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());

  // Step 2: Send the unsigned transaction to Blockradar for signing
  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>

### 交易签名示例（EVM）

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { ethers } from 'ethers';

  // Step 1: Build the unsigned transaction
  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,
  });

  // Step 2: Send to Blockradar for signing
  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());

  // The signed transaction can be broadcast via any 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>

### 仅签名响应（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
  }
}
```

### 仅签名响应（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
  }
}
```

### 仅签名响应（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>
  对于交易签名，`signedTransaction` 是**字符串**而非对象。这与消息签名不同，消息签名返回包含 `r`、`s`、`v` 等签名组件的对象。
</Note>

### 各链 `signedTransaction` 格式

| 链      | 类型     | 格式                                     | 用途                                                           |
| ------ | ------ | -------------------------------------- | ------------------------------------------------------------ |
| Solana | string | 已签名 VersionedTransaction 的 Base64 编码字节 | 解码为字节后传给 `connection.sendRawTransaction()`                   |
| EVM    | string | 以 `0x` 开头的十六进制字符串，包含 RLP 编码的已签名交易      | 直接传给 `eth_sendRawTransaction` 或 `provider.sendTransaction()` |
| Tron   | string | 已签名交易对象的 JSON 字符串，包含 `signature` 数组    | 使用 `JSON.parse()` 解析后传给 `tronWeb.trx.sendRawTransaction()`   |

### 各链 `hash` 字段

| 链      | 格式                | 生成方式                       |
| ------ | ----------------- | -------------------------- |
| Solana | Base58 字符串        | 已签名交易的第一个签名                |
| EVM    | 以 `0x` 开头的十六进制字符串 | 已签名交易字节的 Keccak256 哈希      |
| Tron   | 十六进制字符串           | 交易对象中的 `txID` 字段，在交易构建期间计算 |

***

## 交易广播

一步完成原始交易的签名**和**广播。Blockradar 签名交易，然后通过可靠队列将其提交到链上，支持自动重试。API 立即返回 `PENDING` 状态。链上结果确认后，您会收到 `signed.success` 或 `signed.failed` Webhook。

<Warning>
  广播需要钱包中有测试网/主网资金以支付 Gas 费用。交易必须有效且未过期（Solana blockhash 约在 90 秒后过期）。
</Warning>

### 请求参数

与交易签名相同的参数：

| 参数            | 类型     | 必填 | 描述         |
| ------------- | ------ | -- | ---------- |
| `transaction` | string | 是  | 序列化的未签名交易。 |
| `reference`   | string | 否  | 您的内部追踪 ID。 |
| `metadata`    | object | 否  | 自定义键值对。    |

### 广播示例

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Build the unsigned tx (same as sign-only examples above)
  const unsignedTx = swapResponse.swapTransaction; // Jupiter base64 tx

  // Sign + broadcast in one call
  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);
  // Wait for webhook: signed.success or 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>

### 广播响应（Solana 示例，即时返回）

```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
  }
}
```

### 广播生命周期

交易会经历以下状态：

| 状态        | 含义                                      |
| --------- | --------------------------------------- |
| `PENDING` | 交易已签名，广播已入队。HTTP 响应中返回此状态。              |
| `SUCCESS` | 交易已在链上确认。发送 `signed.success` Webhook。   |
| `FAILED`  | 所有重试耗尽后广播失败。发送 `signed.failed` Webhook。 |

<Tip>
  广播队列最多重试 10 次，间隔 5 分钟。对于 Solana，如果 blockhash 过期，重试不会有效。您需要使用新的 blockhash 重新构建交易。
</Tip>

***

## 完整流程示例

以下是一个完整的实现示例，演示如何签署消息并将签名提交给第三方服务商：

```javascript theme={null}
async function signAndVerifyWithProvider(walletId, providerMessage) {
  const apiKey = process.env.BLOCKRADAR_API_KEY;
  const baseUrl = 'https://api.blockradar.co/v1';

  // Step 1: Sign the message
  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;

  // Step 2: Submit the signature to the third-party provider
  // The provider can verify the signature matches the wallet address
  // without accessing your private keys
  return {
    address: senderAddress,
    signature: hash,
    message: providerMessage
  };
}

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

***

## 错误响应

<AccordionGroup>
  <Accordion title="钱包未找到">
    ```json theme={null}
    {
      "message": "Wallet not found",
      "statusCode": 404
    }
    ```

    该 `walletId` 不存在或不属于您的业务。
  </Accordion>

  <Accordion title="地址未找到">
    ```json theme={null}
    {
      "message": "Address not found",
      "statusCode": 404
    }
    ```

    该 `addressId` 不存在或未与指定钱包关联。
  </Accordion>

  <Accordion title="不支持的区块链（类型化数据）">
    ```json theme={null}
    {
      "message": "Typed data signing is only supported for EVM blockchains",
      "statusCode": 400
    }
    ```

    类型化数据签名（EIP-712）仅适用于 EVM 兼容链。Tron 和 Solana 请使用消息签名。
  </Accordion>

  <Accordion title="链 ID 不匹配">
    ```json theme={null}
    {
      "message": "Chain ID mismatch",
      "statusCode": 400
    }
    ```

    类型化数据域对象中的 `chainId` 与钱包的区块链网络不匹配。
  </Accordion>

  <Accordion title="签名验证失败">
    ```json theme={null}
    {
      "message": "Signature verification failed",
      "statusCode": 400
    }
    ```

    内部往返验证失败，表明系统出现错误。请联系技术支持。
  </Accordion>

  <Accordion title="无效交易格式（Solana）">
    ```json theme={null}
    {
      "message": "Invalid transaction format: expected a base64-encoded Solana VersionedTransaction",
      "statusCode": 400
    }
    ```

    `transaction` 字段不是有效的 Base64，或解码后的字节不是有效的 Solana VersionedTransaction。
  </Accordion>

  <Accordion title="无效交易格式（EVM/Tron）">
    ```json theme={null}
    {
      "message": "Invalid transaction format: expected a JSON string",
      "statusCode": 400
    }
    ```

    `transaction` 字段不是有效的 JSON。EVM 和 Tron 交易必须是 JSON 字符串化的对象。
  </Accordion>
</AccordionGroup>

***

## 最佳实践

### 安全性

* **使用 reference**：使用唯一的 reference ID 追踪签名操作，用于审计跟踪和幂等性
* **验证消息内容**：签名前，确认消息内容与第三方服务预期的内容一致
* **限制消息长度**：消息上限为 4,096 个字符。保持消息简洁明确

### 集成

* **无 Gas 费用**：签名操作在链下进行，不需要原生代币余额
* **即时响应**：签名是同步生成的。签名本身不需要轮询或等待 Webhook
* **监听 Webhook**：使用 Webhook 维护所有签名事件的审计记录

### 类型化数据

* **匹配链 ID**：域中的 `chainId` 必须与钱包的网络匹配。测试使用沙盒（测试网）链 ID，生产使用正式（主网）链 ID
* **检查合约**：`verifyingContract` 必须是将在链上验证签名的合约

### 交易签名

* **使用正确的发送方构建交易**：未签名交易必须使用钱包或子地址的公钥作为费用支付方（Solana）或发送方（EVM/Tron）。如果密钥不匹配，签名将失败。
* **Solana blockhash 过期很快**：Solana blockhash 约在 60 到 90 秒内有效。构建交易后应尽快调用签名端点。如果使用广播，blockhash 过期后重试不会有效。
* **EVM nonce 管理**：正确设置 nonce。如果 nonce 已被使用，广播将失败。在构建交易前从链上查询最新 nonce。
* **Tron 过期时间**：Tron 交易在构建时设置 24 小时过期窗口，有充足的签名和广播时间。
* **仅签名 vs 广播**：如果您希望自行或通过其他服务广播交易，使用 `/signing/transaction`。如果希望 Blockradar 处理提交并自动重试，使用 `/signing/broadcast`。

***

## API 参考

### 主钱包端点

| 端点                                                                    | 描述               |
| --------------------------------------------------------------------- | ---------------- |
| [消息签名](/zh/api-reference/signing/master-wallet-sign-message)          | 签署纯文本消息          |
| [类型化数据签名](/zh/api-reference/signing/master-wallet-typed-data)         | 签署 EIP-712 结构化数据 |
| [交易签名](/zh/api-reference/signing/master-wallet-sign-transaction)      | 签署原始交易           |
| [交易广播](/zh/api-reference/signing/master-wallet-broadcast-transaction) | 签署并广播原始交易        |

### 子地址端点

| 端点                                                                    | 描述                   |
| --------------------------------------------------------------------- | -------------------- |
| [消息签名](/zh/api-reference/signing/child-address-sign-message)          | 从子地址签署纯文本消息          |
| [类型化数据签名](/zh/api-reference/signing/child-address-typed-data)         | 从子地址签署 EIP-712 结构化数据 |
| [交易签名](/zh/api-reference/signing/child-address-sign-transaction)      | 从子地址签署原始交易           |
| [交易广播](/zh/api-reference/signing/child-address-broadcast-transaction) | 从子地址签署并广播原始交易        |
