In a nutshell
The Blockradar Signing API lets you cryptographically sign plain text messages, structured data (typed data), and raw transactions using your wallet’s private keys. Sign messages to prove wallet ownership. Sign transactions built externally (e.g., Jupiter swaps on Solana) without exposing private keys, and optionally broadcast them on-chain.
Prerequisites
Before using the Signing API, ensure you have:
Wallet Created
Create a master wallet from the Blockradar Dashboard . Navigate to Wallets and create one for your target blockchain. You’ll need the walletId for signing operations.
Environment
Choose between Testnet (for development) or Mainnet (for production). Wallets are isolated per environment.
How It Works
The Signing API produces a cryptographic signature that proves you control a specific wallet address. The signed output can be verified by any third party without accessing your private keys.
Message Signing Sign plain text messages to prove wallet ownership. Works on all supported blockchains: EVM, Tron, and Solana.
Typed Data Signing Sign structured data following the EIP-712 standard. Used for gasless approvals (EIP-2612 Permit) and authorized transfers (EIP-3009). EVM-only.
Transaction Signing Sign raw transactions built externally. Build a swap on Jupiter, a contract call via ethers.js, or a TronWeb transfer, then send the unsigned tx and get it signed without exposing private keys.
Transaction Broadcast Sign and broadcast a raw transaction in one step. Blockradar signs the transaction and submits it on-chain via a reliable queue with automatic retries.
Common use cases
Third-party provider registration : Prove you own an address when onboarding with services like Iron, Circle, or other DeFi protocols
Gasless token approvals : Sign EIP-2612 Permit messages to authorize token spending without an on-chain transaction
Authorized transfers : Sign EIP-3009 TransferWithAuthorization messages for delegated transfers
Off-chain attestations : Create verifiable proofs of intent or agreement tied to a wallet address
External swap execution : Build a Jupiter swap on Solana, sign it with Blockradar, and broadcast it on-chain
Custom contract interactions : Build any transaction externally and have Blockradar sign and/or submit it
Master Wallet vs Child Address
The Signing API is available at two levels:
Master Wallet Sign using the master wallet’s keys. Ideal for treasury-level operations and provider integrations.
Child Address Sign using a specific child address’s keys. Use when the third party requires a signature from a deposit address.
Endpoints
Operation Master Wallet Child Address Sign Message POST /v1/wallets/{walletId}/signing/messagePOST /v1/wallets/{walletId}/addresses/{addressId}/signing/messageSign Typed Data POST /v1/wallets/{walletId}/signing/typed-dataPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/typed-dataSign Transaction POST /v1/wallets/{walletId}/signing/transactionPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/transactionSign + Broadcast POST /v1/wallets/{walletId}/signing/broadcastPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/broadcast
Message Signing
Sign a plain text message with your wallet’s private key. The API signs the message, verifies the signature matches the wallet address, and returns both the signature and a transaction record.
Supported Blockchains
Blockchain Signing Standard Signature Format EVM (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo) EIP-191 (personal_sign) Hex-encoded with r, s, v components Tron TronWeb signMessageV2 Hex-encoded string Solana Ed25519 Base58-encoded string
Request Parameters
Parameter Type Required Description messagestring Yes The plain text message to sign. Maximum 4,096 characters. referencestring No Your internal tracking ID. Use for idempotency. Duplicate references are rejected. metadataobject No Custom key-value pairs stored with the transaction record.
Message Signing Example
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 Response
{
"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 Response
For Tron and Solana, the signedTransaction object contains only the signature field (no r, s, v components):
{
"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"
}
}
Response Fields
Field Description idUnique transaction ID for the signing record hashThe cryptographic signature. For EVM: hex string. For Tron: hex string. For Solana: base58 string. statusAlways SUCCESS for completed signatures typeAlways SIGNED for signing transactions senderAddressThe wallet address that produced the signature signedTransactionSignature components. EVM includes r, s, v, and full signature. Tron and Solana include signature only. referenceYour provided reference string (if any) metadataYour provided metadata object (if any)
Typed Data Signing (EVM Only)
Sign structured data following the EIP-712 standard. This is used for gasless approvals, delegated transfers, and other on-chain authorization flows that require a structured signature.
Typed data signing is only available for EVM-compatible blockchains (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo). Tron and Solana do not support EIP-712.
Supported Standards
Standard Use Case EIP-712 Generic structured data signing EIP-2612 (Permit) Gasless token approvals. Approve spending without an on-chain transaction EIP-3009 (TransferWithAuthorization) Delegated transfers. Authorize a transfer that a third party submits
Request Parameters
Parameter Type Required Description domainobject Yes EIP-712 domain separator. Includes name, version, chainId, and verifyingContract. typesobject Yes Type definitions for the structured data. messageobject Yes The data to sign, conforming to the type definitions.
EIP-2612 Permit Example
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"
}
}'
Typed Data Response
{
"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 Object Fields
Field Type Required Description namestring Yes The name of the signing domain (e.g., the token name or dApp name) versionstring Yes The version of the domain chainIdnumber Yes The chain ID. Must match the wallet’s blockchain network. verifyingContractstring Yes The contract address that will verify the signature saltstring No Optional domain salt for EIP-712 v4
Chain ID validation
The chainId in your domain object must match the chain ID of the wallet’s blockchain network. If they don’t match, the API returns a 400 Chain ID mismatch error.
Child Address Signing
Sign messages, typed data, transactions, or broadcast using a specific child address instead of the master wallet. All four signing operations are available for child addresses:
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"
}'
Child address signing follows the same request and response format as master wallet signing. The only difference is the endpoint URL, which includes the addressId.
Webhook Events
Signing operations trigger a webhook with the transaction record:
Event Description signed.successSigning completed successfully. For message/typed data/transaction sign, this fires immediately. For broadcast, this fires after on chain confirmation. signed.failedTransaction broadcast failed after all retries were exhausted. Only applies to the /broadcast endpoint.
Webhook Payload (Message or Typed Data Signing)
{
"event" : "signed.success" ,
"data" : {
"id" : "770f9100-7338-4823-b1ce-3658fc67db09" ,
"hash" : "0xdb095e6cbf...b31b" ,
"status" : "SUCCESS" ,
"type" : "SIGNED" ,
"senderAddress" : "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a" ,
"recipientAddress" : "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a" ,
"signedTransaction" : {
"r" : "0xdb095e6cbf...2133" ,
"s" : "0x5aa3918399...89b3" ,
"v" : 27 ,
"signature" : "0xdb095e6cbf...b31b"
},
"reference" : "iron-verification-001" ,
"metadata" : {
"provider" : "iron" ,
"purpose" : "wallet-verification"
},
"wallet" : {
"id" : "d236a191-c1d4-423c-a439-54ce6542ca41" ,
"name" : "Ethereum Master Wallet"
},
"blockchain" : {
"name" : "ethereum" ,
"network" : "testnet"
},
"confirmed" : true ,
"createdAt" : "2025-03-02T19:00:52.000Z"
}
}
Webhook Payload (Transaction Signing)
For transaction signing, the signedTransaction field is a string (not an object). The format depends on the chain.
{
"event" : "signed.success" ,
"data" : {
"id" : "782942da-48b0-416b-924b-8f657ae637a7" ,
"reference" : "52TQawmiqYpNiWD2Ks0P" ,
"hash" : "0xac4c73ca084608ac6b981e54db948dc80c15b4ea3ffd0c9f5781f3af7ad6fe51" ,
"status" : "SUCCESS" ,
"type" : "SIGNED" ,
"senderAddress" : "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446" ,
"recipientAddress" : "0xC887a3Cb8E7AbA4A77D7275AD4B242f71cbd5446" ,
"signedTransaction" : "0x02f87383aa36a763843b9aca008459682f00..." ,
"network" : "testnet" ,
"chainId" : 11155111 ,
"confirmed" : true ,
"wallet" : {
"id" : "3f9aca5c-38ee-4e1d-ab67-c084a2e37bb2" ,
"name" : "Ethereum Wallet"
},
"blockchain" : {
"name" : "ethereum" ,
"symbol" : "eth" ,
"slug" : "ethereum"
},
"createdAt" : "2026-03-19T13:34:24.937Z"
}
}
Webhook Payload (Broadcast Success)
After the broadcast queue confirms the transaction on chain, you receive this webhook. The hash field is updated to the on chain transaction hash and confirmed changes to true.
{
"event" : "signed.success" ,
"data" : {
"id" : "f3efdbaa-a1f8-4365-b3b4-768413c9a92b" ,
"reference" : "docs-test-broadcast" ,
"hash" : "5bKNw9RX8aXkrK1VEHg5aPa1xtckpShPyenSRET4mUBXh5uCkWLFV5MhGRi4cMACDJvFn6VfkoKb75Pk4KYw6xtw" ,
"status" : "SUCCESS" ,
"type" : "SIGNED" ,
"senderAddress" : "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw" ,
"recipientAddress" : "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw" ,
"signedTransaction" : "AeWpW65y80rSu+TU0CSrcvFNovyDiybKRjSskCpfffAFLM0GIYzx..." ,
"network" : "testnet" ,
"chainId" : 103 ,
"confirmed" : true ,
"wallet" : {
"id" : "c72a6f21-6ab5-48ad-9f99-fd90a2d6d311" ,
"name" : "Solana Testnet Wallet"
},
"blockchain" : {
"name" : "solana" ,
"symbol" : "sol" ,
"slug" : "solana"
},
"createdAt" : "2026-03-19T13:35:09.921Z"
}
}
Webhook Payload (Broadcast Failed)
If the broadcast fails permanently after all retry attempts, you receive this webhook. The status is FAILED and confirmed remains false.
{
"event" : "signed.failed" ,
"data" : {
"id" : "f3efdbaa-a1f8-4365-b3b4-768413c9a92b" ,
"reference" : "docs-test-broadcast" ,
"hash" : "5bKNw9RX8aXkrK1VEHg5aPa1xtckpShPyenSRET4mUBX..." ,
"status" : "FAILED" ,
"type" : "SIGNED" ,
"senderAddress" : "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw" ,
"recipientAddress" : "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw" ,
"signedTransaction" : "AeWpW65y80rSu+TU0CSrcvFNovyDiybKRjSskCpfffAFLM0GIYzx..." ,
"network" : "testnet" ,
"chainId" : 103 ,
"confirmed" : false ,
"wallet" : {
"id" : "c72a6f21-6ab5-48ad-9f99-fd90a2d6d311" ,
"name" : "Solana Testnet Wallet"
},
"blockchain" : {
"name" : "solana" ,
"symbol" : "sol" ,
"slug" : "solana"
},
"createdAt" : "2026-03-19T13:35:09.921Z"
}
}
Transaction Signing
Sign a raw, unsigned transaction built externally. You build the transaction using any SDK (ethers.js, TronWeb, Solana web3.js, Jupiter API), then send the serialized unsigned transaction to Blockradar. Blockradar signs it with the wallet’s private key and returns the signed transaction without ever exposing the key to your application.
Blockchain transaction field formatHow to build Solana Base64 of VersionedTransaction.serialize() Jupiter API /swap response, or @solana/web3.js TransactionMessage EVM JSON string of {to, value, data, nonce, chainId, gasLimit, maxFeePerGas, ...} ethers.js populateTransaction()Tron JSON string of TronWeb transaction object {txID, raw_data, raw_data_hex} tronWeb.transactionBuilder.triggerSmartContract()
Request Parameters
Parameter Type Required Description transactionstring Yes The serialized unsigned transaction. Format depends on the blockchain. referencestring No Your internal tracking ID. metadataobject No Custom key-value pairs stored with the transaction record.
Transaction Signing Example (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 );
Transaction Signing Example (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);
Sign-Only Response (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
}
}
Sign-Only Response (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
}
}
Sign-Only Response (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
}
}
For transaction signing, signedTransaction is a string , not an object. This is different from message signing where it returns an object with signature components like r, s, v.
Chain Type Format What to do with it Solana string Base64 encoded bytes of the signed VersionedTransaction Decode to bytes and pass to connection.sendRawTransaction() EVM string Hex string starting with 0x containing the RLP encoded signed transaction Pass directly to eth_sendRawTransaction or provider.sendTransaction() Tron string JSON string of the signed transaction object containing a signature array Parse with JSON.parse() and pass to tronWeb.trx.sendRawTransaction()
hash Field by Chain
Chain Format How it is derived Solana Base58 string First signature from the signed transaction EVM Hex string starting with 0x Keccak256 hash of the signed transaction bytes Tron Hex string The txID field from the transaction object, computed during transaction building
Transaction Broadcast
Sign and broadcast a raw transaction in one step. Blockradar signs the transaction, then submits it on-chain via a reliable queue with automatic retries. The API returns immediately with PENDING status. You’ll receive a signed.success or signed.failed webhook when the on-chain result is confirmed.
Broadcast requires testnet/mainnet funds in the wallet to pay gas fees. The transaction must be valid and not expired (Solana blockhashes expire in ~90 seconds).
Request
Same parameters as transaction signing:
Parameter Type Required Description transactionstring Yes The serialized unsigned transaction. referencestring No Your internal tracking ID. metadataobject No Custom key-value pairs.
Broadcast Example
// 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
{
"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
}
}
Broadcast Lifecycle
The transaction goes through these states:
Status Meaning PENDINGTransaction signed, broadcast queued. You receive this in the HTTP response. SUCCESSTransaction confirmed on-chain. Webhook signed.success is sent. FAILEDBroadcast failed after all retries exhausted. Webhook signed.failed is sent.
The broadcast queue retries up to 10 times with 5-minute intervals. For Solana, if the blockhash expires, retries will not help. You’ll need to rebuild the transaction with a fresh blockhash.
Complete Flow Example
Here’s a full implementation for signing a message and submitting the signature to a third-party provider:
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.'
);
Error Responses
{
"message" : "Wallet not found" ,
"statusCode" : 404
}
The walletId does not exist or does not belong to your business.
{
"message" : "Address not found" ,
"statusCode" : 404
}
The addressId does not exist or is not associated with the specified wallet.
Unsupported Blockchain (Typed Data)
{
"message" : "Typed data signing is only supported for EVM blockchains" ,
"statusCode" : 400
}
Typed data signing (EIP-712) is only available on EVM-compatible chains. Use message signing for Tron and Solana.
{
"message" : "Chain ID mismatch" ,
"statusCode" : 400
}
The chainId in your typed data domain object does not match the wallet’s blockchain network.
Signature Verification Failed
{
"message" : "Signature verification failed" ,
"statusCode" : 400
}
Internal round-trip verification failed. This indicates a system error. Please contact support.
Invalid Transaction Format (Solana)
Invalid Transaction Format (EVM/Tron)
Best Practices
Security
Use references : Track signing operations with unique reference IDs for audit trails and idempotency
Verify the message : Before signing, confirm the message content matches what the third-party service expects
Limit message length : Messages are capped at 4,096 characters. Keep messages concise and specific
Integration
No gas fees : Signing operations are off-chain and do not require native token balance
Immediate response : Signatures are generated synchronously. No polling or webhook waiting required for the signature itself
Listen for webhooks : Use webhooks to maintain an audit trail of all signing events
Typed Data
Match chain IDs : The chainId in your domain must match the wallet’s network. Use sandbox (testnet) chain IDs for testing and production (mainnet) chain IDs for live operations
Check the contract : The verifyingContract must be the contract that will verify the signature on-chain
Transaction Signing
Build the transaction with the correct sender : The unsigned transaction must use the wallet or child address public key as the fee payer (Solana) or sender (EVM/Tron). If the key does not match, signing will fail.
Solana blockhashes expire quickly : Solana blockhashes are valid for about 60 to 90 seconds. Build the transaction and call the signing endpoint promptly. If using broadcast, the queue retries will not help once the blockhash expires.
EVM nonce management : Set the nonce correctly. If the nonce is already used, the broadcast will fail. Query the nonce from the chain immediately before building the transaction.
Tron expiration : Tron transactions have a 24 hour expiration window set during building. This gives plenty of time for signing and broadcast.
Sign only vs broadcast : Use /signing/transaction when you want to broadcast the transaction yourself or through another service. Use /signing/broadcast when you want Blockradar to handle submission with automatic retries.
API Reference
Master Wallet Endpoints
Endpoint Description Sign Message Sign a plain text message Sign Typed Data Sign EIP-712 structured data Sign Transaction Sign a raw transaction Broadcast Transaction Sign and broadcast a raw transaction
Child Address Endpoints
Endpoint Description Sign Message Sign a plain text message from a child address Sign Typed Data Sign EIP-712 structured data from a child address Sign Transaction Sign a raw transaction from a child address Broadcast Transaction Sign and broadcast a raw transaction from a child address