简而言之
Blockradar 签名 API 允许您使用钱包的私钥对纯文本消息、结构化数据(类型化数据)和原始交易进行加密签名。签名消息可以证明钱包所有权。签名外部构建的交易(例如 Solana 上的 Jupiter 兑换)无需暴露私钥,还可以选择将交易广播到链上。
前提条件
在使用签名 API 之前,请确保您已完成以下准备:
环境选择
选择 Testnet(测试网,用于开发)或 Mainnet(主网,用于生产)。钱包按环境隔离。
工作原理
签名 API 生成加密签名,证明您控制着特定的钱包地址。签名输出可以被任何第三方验证,而无需访问您的私钥。
消息签名
签署纯文本消息以证明钱包所有权。支持所有区块链:EVM、Tron 和 Solana。
类型化数据签名
按照 EIP-712 标准签署结构化数据。用于无 Gas 授权(EIP-2612 Permit)和委托转账(EIP-3009)。仅限 EVM。
交易签名
签署外部构建的原始交易。在 Jupiter 上构建兑换、通过 ethers.js 进行合约调用或 TronWeb 转账,然后发送未签名的交易进行签名,无需暴露私钥。
交易广播
一步完成原始交易的签名和广播。Blockradar 签名交易并通过可靠队列将其提交到链上,支持自动重试。
常见使用场景
- 第三方服务注册:在接入 Iron、Circle 或其他 DeFi 协议等服务时,证明您拥有某个地址
- 无 Gas 代币授权:签署 EIP-2612 Permit 消息以授权代币支出,无需链上交易
- 委托转账:签署 EIP-3009 TransferWithAuthorization 消息以进行委托转账
- 链下证明:创建与钱包地址关联的可验证意向或协议证明
- 外部兑换执行:在 Solana 上构建 Jupiter 兑换,使用 Blockradar 签名,然后广播到链上
- 自定义合约交互:在外部构建任意交易,由 Blockradar 签名和/或提交
主钱包与子地址
签名 API 可在两个层级使用:
主钱包
使用主钱包的密钥进行签名。适用于资金管理级别的操作和服务商集成。
子地址
使用特定子地址的密钥进行签名。当第三方要求使用充值地址进行签名时使用。
接口端点
| 操作 | 主钱包 | 子地址 |
|---|
| 消息签名 | 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 | 否 | 与交易记录一起存储的自定义键值对。 |
消息签名示例
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"
}
}'
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"
}
}
Tron / Solana 响应
对于 Tron 和 Solana,signedTransaction 对象仅包含 signature 字段(没有 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"
}
}
响应字段
| 字段 | 描述 |
|---|
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 授权、委托转账以及其他需要结构化签名的链上授权流程。
类型化数据签名仅适用于 EVM 兼容的区块链(Ethereum、Polygon、BSC、Base、Arbitrum、Optimism、Celo)。Tron 和 Solana 不支持 EIP-712。
支持的标准
| 标准 | 使用场景 |
|---|
| EIP-712 | 通用结构化数据签名 |
| EIP-2612 (Permit) | 无 Gas 代币授权。无需链上交易即可授权代币支出 |
| EIP-3009 (TransferWithAuthorization) | 委托转账。授权由第三方提交的转账 |
请求参数
| 参数 | 类型 | 必填 | 描述 |
|---|
domain | object | 是 | EIP-712 域分隔符。包括 name、version、chainId 和 verifyingContract。 |
types | object | 是 | 结构化数据的类型定义。 |
message | object | 是 | 要签署的数据,需符合类型定义。 |
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"
}
}'
类型化数据响应
{
"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 |
链 ID 验证
域对象中的 chainId 必须与钱包所在区块链网络的链 ID 匹配。如果不匹配,API 将返回 400 Chain ID mismatch 错误。
子地址签名
使用特定子地址(而非主钱包)签署消息、类型化数据、交易或进行广播。所有四种签名操作均可用于子地址:
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"
}'
子地址签名遵循与主钱包签名相同的请求和响应格式。唯一的区别是端点 URL 中包含了 addressId。
Webhook 事件
签名操作会触发一个包含交易记录的 Webhook:
| 事件 | 描述 |
|---|
signed.success | 签名成功完成。对于消息/类型化数据/交易签名,立即触发。对于广播,在链上确认后触发。 |
signed.failed | 交易广播在所有重试耗尽后失败。仅适用于 /broadcast 端点。 |
Webhook 载荷(消息或类型化数据签名)
{
"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 字段是字符串(而非对象)。格式取决于链。
{
"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。
{
"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。
{
"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。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)
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);
交易签名示例(EVM)
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);
仅签名响应(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
}
}
仅签名响应(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
}
}
仅签名响应(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
}
}
对于交易签名,signedTransaction 是字符串而非对象。这与消息签名不同,消息签名返回包含 r、s、v 等签名组件的对象。
各链 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。
广播需要钱包中有测试网/主网资金以支付 Gas 费用。交易必须有效且未过期(Solana blockhash 约在 90 秒后过期)。
请求参数
与交易签名相同的参数:
| 参数 | 类型 | 必填 | 描述 |
|---|
transaction | string | 是 | 序列化的未签名交易。 |
reference | string | 否 | 您的内部追踪 ID。 |
metadata | object | 否 | 自定义键值对。 |
广播示例
// 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
广播响应(Solana 示例,即时返回)
{
"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。 |
广播队列最多重试 10 次,间隔 5 分钟。对于 Solana,如果 blockhash 过期,重试不会有效。您需要使用新的 blockhash 重新构建交易。
完整流程示例
以下是一个完整的实现示例,演示如何签署消息并将签名提交给第三方服务商:
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.'
);
错误响应
{
"message": "Wallet not found",
"statusCode": 404
}
该 walletId 不存在或不属于您的业务。
{
"message": "Address not found",
"statusCode": 404
}
该 addressId 不存在或未与指定钱包关联。
{
"message": "Typed data signing is only supported for EVM blockchains",
"statusCode": 400
}
类型化数据签名(EIP-712)仅适用于 EVM 兼容链。Tron 和 Solana 请使用消息签名。
{
"message": "Chain ID mismatch",
"statusCode": 400
}
类型化数据域对象中的 chainId 与钱包的区块链网络不匹配。
{
"message": "Signature verification failed",
"statusCode": 400
}
内部往返验证失败,表明系统出现错误。请联系技术支持。
{
"message": "Invalid transaction format: expected a base64-encoded Solana VersionedTransaction",
"statusCode": 400
}
transaction 字段不是有效的 Base64,或解码后的字节不是有效的 Solana VersionedTransaction。
{
"message": "Invalid transaction format: expected a JSON string",
"statusCode": 400
}
transaction 字段不是有效的 JSON。EVM 和 Tron 交易必须是 JSON 字符串化的对象。
最佳实践
安全性
- 使用 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 参考
主钱包端点
| 端点 | 描述 |
|---|
| 消息签名 | 签署纯文本消息 |
| 类型化数据签名 | 签署 EIP-712 结构化数据 |
| 交易签名 | 签署原始交易 |
| 交易广播 | 签署并广播原始交易 |
子地址端点
| 端点 | 描述 |
|---|
| 消息签名 | 从子地址签署纯文本消息 |
| 类型化数据签名 | 从子地址签署 EIP-712 结构化数据 |
| 交易签名 | 从子地址签署原始交易 |
| 交易广播 | 从子地址签署并广播原始交易 |