Em resumo
A API de Assinatura da Blockradar permite que você assine criptograficamente mensagens de texto simples, dados estruturados (dados tipados) e transações brutas usando as chaves privadas da sua carteira. Assine mensagens para comprovar a propriedade da carteira. Assine transações construídas externamente (ex.: swaps Jupiter no Solana) sem expor chaves privadas, e opcionalmente faça broadcast delas on-chain.
Pré-requisitos
Antes de usar a API de Assinatura, certifique-se de ter:
Carteira Criada
Crie uma carteira mestra no Painel da Blockradar . Navegue até Wallets e crie uma para a blockchain desejada. Você precisará do walletId para operações de assinatura.
Ambiente
Escolha entre Testnet (para desenvolvimento) ou Mainnet (para produção). Carteiras são isoladas por ambiente.
Como Funciona
A API de Assinatura produz uma assinatura criptográfica que comprova que você controla um endereço de carteira específico. A saída assinada pode ser verificada por qualquer terceiro sem acessar suas chaves privadas.
Assinatura de Mensagem Assine mensagens de texto simples para comprovar a propriedade da carteira. Funciona em todas as blockchains suportadas: EVM, Tron e Solana.
Assinatura de Dados Tipados Assine dados estruturados seguindo o padrão EIP-712. Usado para aprovações sem gas (EIP-2612 Permit) e transferências autorizadas (EIP-3009). Apenas EVM.
Assinatura de Transação Assine transações brutas construídas externamente. Construa um swap no Jupiter, uma chamada de contrato via ethers.js ou uma transferência TronWeb, e envie a tx não assinada para obter a assinatura sem expor chaves privadas.
Broadcast de Transação Assine e faça broadcast de uma transação bruta em um único passo. A Blockradar assina a transação e a submete on-chain via uma fila confiável com retentativas automáticas.
Casos de uso comuns
Registro em provedores terceiros : Comprove que você é proprietário de um endereço ao se cadastrar em serviços como Iron, Circle ou outros protocolos DeFi
Aprovações de tokens sem gas : Assine mensagens EIP-2612 Permit para autorizar gastos de tokens sem uma transação on-chain
Transferências autorizadas : Assine mensagens EIP-3009 TransferWithAuthorization para transferências delegadas
Atestações off-chain : Crie provas verificáveis de intenção ou acordo vinculadas a um endereço de carteira
Execução de swaps externos : Construa um swap Jupiter no Solana, assine com a Blockradar e faça broadcast on-chain
Interações customizadas com contratos : Construa qualquer transação externamente e tenha a Blockradar assinando e/ou submetendo ela
Carteira Mestra vs Endereço Filho
A API de Assinatura está disponível em dois níveis:
Carteira Mestra Assine usando as chaves da carteira mestra. Ideal para operações de tesouraria e integrações com provedores.
Endereço Filho Assine usando as chaves de um endereço filho específico. Use quando o terceiro exigir uma assinatura de um endereço de depósito.
Endpoints
Operação Carteira Mestra Endereço Filho Assinar Mensagem POST /v1/wallets/{walletId}/signing/messagePOST /v1/wallets/{walletId}/addresses/{addressId}/signing/messageAssinar Dados Tipados POST /v1/wallets/{walletId}/signing/typed-dataPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/typed-dataAssinar Transação POST /v1/wallets/{walletId}/signing/transactionPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/transactionAssinar + Broadcast POST /v1/wallets/{walletId}/signing/broadcastPOST /v1/wallets/{walletId}/addresses/{addressId}/signing/broadcast
Assinatura de Mensagem
Assine uma mensagem de texto simples com a chave privada da sua carteira. A API assina a mensagem, verifica se a assinatura corresponde ao endereço da carteira e retorna tanto a assinatura quanto um registro de transação.
Blockchains Suportadas
Blockchain Padrão de Assinatura Formato da Assinatura EVM (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo) EIP-191 (personal_sign) Codificado em hex com componentes r, s, v Tron TronWeb signMessageV2 String codificada em hex Solana Ed25519 String codificada em Base58
Parâmetros da Requisição
Parâmetro Tipo Obrigatório Descrição messagestring Sim A mensagem de texto simples a ser assinada. Máximo de 4.096 caracteres. referencestring Não Seu ID de rastreamento interno. Use para idempotência. Referências duplicadas são rejeitadas. metadataobject Não Pares chave-valor personalizados armazenados com o registro da transação.
Exemplo de Assinatura de Mensagem
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"
}
}'
Resposta 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"
}
}
Resposta Tron / Solana
Para Tron e Solana, o objeto signedTransaction contém apenas o campo signature (sem componentes r, s, v):
{
"message" : "Message signed successfully" ,
"statusCode" : 200 ,
"data" : {
"id" : "a1b2c3d4-e5f6-7890-abcd-ef1234567890" ,
"hash" : "3xYkZ9..." ,
"status" : "SUCCESS" ,
"type" : "SIGNED" ,
"senderAddress" : "TJRabPrwbZy45sbavfcjinPJC18kjpRT9Y" ,
"recipientAddress" : "TJRabPrwbZy45sbavfcjinPJC18kjpRT9Y" ,
"signedTransaction" : {
"signature" : "3xYkZ9..."
},
"reference" : "tron-verification-001" ,
"confirmed" : true ,
"createdAt" : "2025-03-02T19:00:52.000Z"
}
}
Campos da Resposta
Campo Descrição idID único da transação para o registro de assinatura hashA assinatura criptográfica. Para EVM: string hex. Para Tron: string hex. Para Solana: string base58. statusSempre SUCCESS para assinaturas concluídas typeSempre SIGNED para transações de assinatura senderAddressO endereço da carteira que produziu a assinatura signedTransactionComponentes da assinatura. EVM inclui r, s, v e signature completa. Tron e Solana incluem apenas signature. referenceSua string de referência fornecida (se houver) metadataSeu objeto de metadados fornecido (se houver)
Assinatura de Dados Tipados (Apenas EVM)
Assine dados estruturados seguindo o padrão EIP-712. Isso é usado para aprovações sem gas, transferências delegadas e outros fluxos de autorização on-chain que requerem uma assinatura estruturada.
A assinatura de dados tipados está disponível apenas para blockchains compatíveis com EVM (Ethereum, Polygon, BSC, Base, Arbitrum, Optimism, Celo). Tron e Solana não suportam EIP-712.
Padrões Suportados
Padrão Caso de Uso EIP-712 Assinatura genérica de dados estruturados EIP-2612 (Permit) Aprovações de tokens sem gas. Aprove gastos sem uma transação on-chain EIP-3009 (TransferWithAuthorization) Transferências delegadas. Autorize uma transferência que um terceiro submete
Parâmetros da Requisição
Parâmetro Tipo Obrigatório Descrição domainobject Sim Separador de domínio EIP-712. Inclui name, version, chainId e verifyingContract. typesobject Sim Definições de tipo para os dados estruturados. messageobject Sim Os dados a serem assinados, em conformidade com as definições de tipo.
Exemplo 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"
}
}'
Resposta de Dados Tipados
{
"message" : "Typed data signed successfully" ,
"statusCode" : 200 ,
"data" : {
"id" : "770f9100-7338-4823-b1ce-3658fc67db09" ,
"hash" : "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e21335aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b31b" ,
"status" : "SUCCESS" ,
"type" : "SIGNED" ,
"senderAddress" : "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a" ,
"recipientAddress" : "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a" ,
"signedTransaction" : {
"r" : "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e2133" ,
"s" : "0x5aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b3" ,
"v" : 27 ,
"signature" : "0xdb095e6cbf...b31b"
},
"confirmed" : true ,
"createdAt" : "2025-03-02T19:00:52.000Z"
}
}
Campos do Objeto Domain
Campo Tipo Obrigatório Descrição namestring Sim O nome do domínio de assinatura (ex.: o nome do token ou do dApp) versionstring Sim A versão do domínio chainIdnumber Sim O ID da chain. Deve corresponder à rede blockchain da carteira. verifyingContractstring Sim O endereço do contrato que verificará a assinatura saltstring Não Salt de domínio opcional para EIP-712 v4
Validação do Chain ID
O chainId no seu objeto de domínio deve corresponder ao chain ID da rede blockchain da carteira. Se não corresponderem, a API retorna um erro 400 Chain ID mismatch.
Assine mensagens, dados tipados, transações ou faça broadcast usando um endereço filho específico em vez da carteira mestra. Todas as quatro operações de assinatura estão disponíveis para endereços filhos:
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"
}'
A assinatura com endereço filho segue o mesmo formato de requisição e resposta da assinatura com carteira mestra. A única diferença é a URL do endpoint, que inclui o addressId.
Eventos de Webhook
Operações de assinatura disparam um webhook com o registro da transação:
Evento Descrição signed.successAssinatura concluída com sucesso. Para assinatura de mensagem/dados tipados/transação, dispara imediatamente. Para broadcast, dispara após confirmação on-chain. signed.failedO broadcast da transação falhou após todas as retentativas serem esgotadas. Aplica-se apenas ao endpoint /broadcast.
Payload do Webhook (Assinatura de Mensagem ou Dados Tipados)
{
"event" : "signed.success" ,
"data" : {
"id" : "770f9100-7338-4823-b1ce-3658fc67db09" ,
"reference" : "iron-verification-001" ,
"senderAddress" : "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a" ,
"recipientAddress" : "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a" ,
"hash" : "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e21335aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b31b" ,
"confirmed" : true ,
"status" : "SUCCESS" ,
"type" : "SIGNED" ,
"createdChannel" : "api" ,
"reason" : "Message signed" ,
"network" : "testnet" ,
"chainId" : 11155111 ,
"metadata" : {
"provider" : "iron" ,
"purpose" : "wallet-verification"
},
"signedTransaction" : {
"r" : "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e2133" ,
"s" : "0x5aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b3" ,
"v" : 27 ,
"signature" : "0xdb095e6cbf235d630cee43e0953e60c351e46897bc4e65abfce3e975810e21335aa3918399dac1e01badb2dc8c59c171e65d0c328c92737de702da9d76b889b31b"
},
"amount" : null ,
"amountUSD" : "0.00" ,
"fee" : null ,
"feeUSD" : null ,
"currency" : "USD" ,
"createdAt" : "2025-03-02T19:00:52.000Z" ,
"updatedAt" : "2025-03-02T19:00:52.000Z" ,
"wallet" : {
"id" : "d236a191-c1d4-423c-a439-54ce6542ca41" ,
"name" : "Ethereum Master Wallet" ,
"address" : "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a" ,
"isActive" : true ,
"status" : "ACTIVE" ,
"network" : "testnet"
},
"asset" : null ,
"blockchain" : {
"id" : "85ffc132-3972-4c9e-99a5-5cf0ccb688bf" ,
"name" : "ethereum" ,
"symbol" : "eth" ,
"slug" : "ethereum" ,
"isEvmCompatible" : true ,
"tokenStandard" : "ERC20"
},
"beneficiary" : null
}
}
Payload do Webhook (Assinatura de Transação)
Para assinatura de transação, o campo signedTransaction é uma string (não um objeto). O formato depende da chain.
{
"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
}
}
Após a fila de broadcast confirmar a transação on-chain, você recebe este webhook. O campo hash é atualizado para o hash da transação on-chain e confirmed muda para 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
}
}
Se o broadcast falhar permanentemente após todas as tentativas de retentativa, você recebe este webhook. O status é FAILED e confirmed permanece 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
}
}
Assinatura de Transação
Assine uma transação bruta, não assinada, construída externamente. Você constrói a transação usando qualquer SDK (ethers.js, TronWeb, Solana web3.js, Jupiter API), e envia a transação serializada não assinada para a Blockradar. A Blockradar assina com a chave privada da carteira e retorna a transação assinada sem nunca expor a chave à sua aplicação.
Blockchain Formato do campo transaction Como construir Solana Base64 de VersionedTransaction.serialize() Resposta da Jupiter API /swap, ou @solana/web3.js TransactionMessage EVM String JSON de {to, value, data, nonce, chainId, gasLimit, maxFeePerGas, ...} ethers.js populateTransaction()Tron String JSON do objeto de transação TronWeb {txID, raw_data, raw_data_hex} tronWeb.transactionBuilder.triggerSmartContract()
Parâmetros da Requisição
Parâmetro Tipo Obrigatório Descrição transactionstring Sim A transação não assinada serializada. O formato depende da blockchain. referencestring Não Seu ID de rastreamento interno. metadataobject Não Pares chave-valor personalizados armazenados com o registro da transação.
Exemplo de Assinatura de Transação (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 );
Exemplo de Assinatura de Transação (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);
Resposta de Assinatura (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
}
}
Resposta de Assinatura (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
}
}
Resposta de Assinatura (Tron)
{
"statusCode" : 200 ,
"message" : "Transaction signed successfully" ,
"data" : {
"id" : "af44218f-d38b-472b-9834-49f461a20fd4" ,
"reference" : "J6RugzxXI6cdpeMXrhh" ,
"senderAddress" : "TMUZSkS3aF1pZxnTokWikUQH7SYt3bNb6G" ,
"recipientAddress" : "TMUZSkS3aF1pZxnTokWikUQH7SYt3bNb6G" ,
"hash" : "3180f971f692a78f62050278149d746abd946fbd1797a414f5ad0d5ed45c902b" ,
"confirmed" : true ,
"status" : "SUCCESS" ,
"type" : "SIGNED" ,
"createdChannel" : "api" ,
"reason" : "Transaction signed" ,
"network" : "testnet" ,
"chainId" : 3448148188 ,
"metadata" : null ,
"signedTransaction" : "{ \" visible \" :false, \" txID \" : \" 3180f971f692a78f... \" , \" raw_data \" :{ \" contract \" :[{ \" parameter \" :{ \" value \" :{ \" to_address \" : \" 418840e6c55b9ada... \" , \" owner_address \" : \" 417e3682ec8f5b98... \" , \" amount \" :1000000}, \" type_url \" : \" type.googleapis.com/protocol.TransferContract \" }, \" type \" : \" TransferContract \" }], \" ref_block_bytes \" : \" 513f \" , \" ref_block_hash \" : \" 08c7d5da0ddd12fb \" , \" expiration \" :1773927585000, \" timestamp \" :1773927525000}, \" signature \" :[ \" d5adac23f23414083ef4f93b995a4a18... \" ]}" ,
"amount" : null ,
"amountUSD" : "0.00" ,
"fee" : null ,
"feeUSD" : null ,
"currency" : "USD" ,
"createdAt" : "2026-03-19T13:38:47.096Z" ,
"updatedAt" : "2026-03-19T13:38:47.096Z" ,
"wallet" : {
"id" : "c4bbebea-6cec-4021-b842-ffead75fd0f1" ,
"name" : "Tron Wallet" ,
"address" : "TMUZSkS3aF1pZxnTokWikUQH7SYt3bNb6G" ,
"isActive" : true ,
"status" : "ACTIVE" ,
"network" : "testnet"
},
"asset" : null ,
"blockchain" : {
"id" : "fa91a922-3838-45f6-8a88-a4c771e1443a" ,
"name" : "tron" ,
"symbol" : "trx" ,
"slug" : "tron" ,
"isEvmCompatible" : false ,
"tokenStandard" : "TRC20"
},
"beneficiary" : null
}
}
Para assinatura de transação, signedTransaction é uma string , não um objeto. Isso é diferente da assinatura de mensagem, onde retorna um objeto com componentes da assinatura como r, s, v.
Chain Tipo Formato O que fazer com ele Solana string Bytes codificados em Base64 da VersionedTransaction assinada Decodifique para bytes e passe para connection.sendRawTransaction() EVM string String hex começando com 0x contendo a transação assinada codificada em RLP Passe diretamente para eth_sendRawTransaction ou provider.sendTransaction() Tron string String JSON do objeto de transação assinado contendo um array signature Parse com JSON.parse() e passe para tronWeb.trx.sendRawTransaction()
Campo hash por Chain
Chain Formato Como é derivado Solana String Base58 Primeira assinatura da transação assinada EVM String hex começando com 0x Hash Keccak256 dos bytes da transação assinada Tron String hex O campo txID do objeto de transação, calculado durante a construção da transação
Broadcast de Transação
Assine e faça broadcast de uma transação bruta em um único passo. A Blockradar assina a transação e a submete on-chain via uma fila confiável com retentativas automáticas. A API retorna imediatamente com status PENDING. Você receberá um webhook signed.success ou signed.failed quando o resultado on-chain for confirmado.
O broadcast requer fundos de testnet/mainnet na carteira para pagar taxas de gas. A transação deve ser válida e não estar expirada (blockhashes do Solana expiram em ~90 segundos).
Requisição
Mesmos parâmetros da assinatura de transação:
Parâmetro Tipo Obrigatório Descrição transactionstring Sim A transação não assinada serializada. referencestring Não Seu ID de rastreamento interno. metadataobject Não Pares chave-valor personalizados.
Exemplo de Broadcast
// 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
Resposta de Broadcast (Exemplo Solana, imediata)
{
"statusCode" : 200 ,
"message" : "Transaction signed and broadcast initiated" ,
"data" : {
"id" : "f3efdbaa-a1f8-4365-b3b4-768413c9a92b" ,
"reference" : "docs-test-broadcast" ,
"senderAddress" : "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw" ,
"recipientAddress" : "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw" ,
"hash" : "5bKNw9RX8aXkrK1VEHg5aPa1xtckpShPyenSRET4mUBXh5uCkWLFV5MhGRi4cMACDJvFn6VfkoKb75Pk4KYw6xtw" ,
"confirmed" : false ,
"status" : "PENDING" ,
"type" : "SIGNED" ,
"createdChannel" : "api" ,
"reason" : "Transaction signed and broadcast" ,
"network" : "testnet" ,
"chainId" : 103 ,
"metadata" : null ,
"signedTransaction" : "AeWpW65y80rSu+TU0CSrcvFNovyDiybKRjSskCpfffAFLM0GIYzx..." ,
"amount" : null ,
"amountUSD" : "0.00" ,
"fee" : null ,
"feeUSD" : null ,
"currency" : "USD" ,
"createdAt" : "2026-03-19T13:35:09.921Z" ,
"updatedAt" : "2026-03-19T13:35:09.921Z" ,
"wallet" : {
"id" : "c72a6f21-6ab5-48ad-9f99-fd90a2d6d311" ,
"name" : "Solana Testnet Wallet" ,
"address" : "HKqZUT3wuyJrsPYmrYPcGduDdjXZTggbLrNsF9WHMvbw" ,
"isActive" : true ,
"status" : "ACTIVE" ,
"network" : "testnet"
},
"asset" : null ,
"blockchain" : {
"id" : "196badf5-380f-4480-ab4a-d0e4304e91f0" ,
"name" : "solana" ,
"symbol" : "sol" ,
"slug" : "solana" ,
"isEvmCompatible" : false ,
"tokenStandard" : null
},
"beneficiary" : null
}
}
Ciclo de Vida do Broadcast
A transação passa pelos seguintes estados:
Status Significado PENDINGTransação assinada, broadcast na fila. Você recebe isso na resposta HTTP. SUCCESSTransação confirmada on-chain. Webhook signed.success é enviado. FAILEDBroadcast falhou após todas as retentativas esgotadas. Webhook signed.failed é enviado.
A fila de broadcast faz até 10 retentativas com intervalos de 5 minutos. Para Solana, se o blockhash expirar, as retentativas não ajudarão. Você precisará reconstruir a transação com um blockhash novo.
Exemplo de Fluxo Completo
Aqui está uma implementação completa para assinar uma mensagem e enviar a assinatura para um provedor terceiro:
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.'
);
Respostas de Erro
{
"message" : "Wallet not found" ,
"statusCode" : 404
}
O walletId não existe ou não pertence ao seu negócio.
{
"message" : "Address not found" ,
"statusCode" : 404
}
O addressId não existe ou não está associado à carteira especificada.
Blockchain Não Suportada (Dados Tipados)
{
"message" : "Typed data signing is only supported for EVM blockchains" ,
"statusCode" : 400
}
A assinatura de dados tipados (EIP-712) está disponível apenas em chains compatíveis com EVM. Use a assinatura de mensagem para Tron e Solana.
{
"message" : "Chain ID mismatch" ,
"statusCode" : 400
}
O chainId no seu objeto de domínio de dados tipados não corresponde à rede blockchain da carteira.
Falha na Verificação da Assinatura
{
"message" : "Signature verification failed" ,
"statusCode" : 400
}
A verificação interna de ida e volta falhou. Isso indica um erro do sistema. Entre em contato com o suporte.
Formato de Transação Inválido (Solana)
Formato de Transação Inválido (EVM/Tron)
Melhores Práticas
Segurança
Use referências : Rastreie operações de assinatura com IDs de referência únicos para trilhas de auditoria e idempotência
Verifique a mensagem : Antes de assinar, confirme que o conteúdo da mensagem corresponde ao que o serviço terceiro espera
Limite o tamanho da mensagem : Mensagens são limitadas a 4.096 caracteres. Mantenha as mensagens concisas e específicas
Integração
Sem taxas de gas : Operações de assinatura são off-chain e não requerem saldo de token nativo
Resposta imediata : As assinaturas são geradas de forma síncrona. Não é necessário polling ou espera por webhook para a assinatura em si
Ouça os webhooks : Use webhooks para manter uma trilha de auditoria de todos os eventos de assinatura
Dados Tipados
Combine os chain IDs : O chainId no seu domínio deve corresponder à rede da carteira. Use chain IDs de sandbox (testnet) para testes e chain IDs de produção (mainnet) para operações em produção
Verifique o contrato : O verifyingContract deve ser o contrato que verificará a assinatura on-chain
Assinatura de Transação
Construa a transação com o remetente correto : A transação não assinada deve usar a chave pública da carteira ou endereço filho como fee payer (Solana) ou remetente (EVM/Tron). Se a chave não corresponder, a assinatura falhará.
Blockhashes do Solana expiram rapidamente : Blockhashes do Solana são válidos por cerca de 60 a 90 segundos. Construa a transação e chame o endpoint de assinatura prontamente. Se usar broadcast, as retentativas da fila não ajudarão quando o blockhash expirar.
Gerenciamento de nonce EVM : Defina o nonce corretamente. Se o nonce já foi usado, o broadcast falhará. Consulte o nonce na chain imediatamente antes de construir a transação.
Expiração do Tron : Transações Tron têm uma janela de expiração de 24 horas definida durante a construção. Isso dá tempo suficiente para assinatura e broadcast.
Apenas assinar vs broadcast : Use /signing/transaction quando quiser fazer broadcast da transação você mesmo ou através de outro serviço. Use /signing/broadcast quando quiser que a Blockradar cuide da submissão com retentativas automáticas.
Referência da API
Endpoints da Carteira Mestra
Endpoint Descrição Assinar Mensagem Assinar uma mensagem de texto simples Assinar Dados Tipados Assinar dados estruturados EIP-712 Assinar Transação Assinar uma transação bruta Broadcast de Transação Assinar e fazer broadcast de uma transação bruta
Endpoints do Endereço Filho
Endpoint Descrição Assinar Mensagem Assinar uma mensagem de texto simples a partir de um endereço filho Assinar Dados Tipados Assinar dados estruturados EIP-712 a partir de um endereço filho Assinar Transação Assinar uma transação bruta a partir de um endereço filho Broadcast de Transação Assinar e fazer broadcast de uma transação bruta a partir de um endereço filho