In a nutshell
Blockradar’s Smart Contract API enables you to interact with any smart contract directly from your wallet without managing RPC endpoints, signing flows, or contract deployments yourself.
Prerequisites
Before using the Smart Contract API, ensure you have:
Wallet Created
Create a wallet via the Create Wallet API or dashboard. You’ll need the walletId for all smart contract operations.
Native Currency Balance
Fund your wallet with native currency (ETH, BNB, MATIC, etc.) to cover gas fees. Use the Network Fee endpoint to estimate costs before executing.
Supported Blockchains
The Smart Contract API supports all EVM-compatible blockchains and Tron available on Blockradar. See Integrations for the complete list of supported networks and faucet links.
Solana is not supported for smart contract interactions. The Smart Contract API only works with EVM-compatible chains and Tron.
Start with testnets during development to avoid spending real funds.
Introduction
The Smart Contract API transforms Blockradar from a wallet infrastructure into a programmable execution layer. You can read contract state, execute contract functions, estimate gas fees, and sign transactions—all through a unified API surface.
Read Operations Retrieve data from any smart contract on supported blockchains.
Write Operations Execute smart contract functions with full transaction management.
Fee Estimation Calculate gas costs before execution to ensure sufficient funds.
Batch Operations Execute multiple contract calls in a single API request.
Use Cases
The Smart Contract API unlocks powerful capabilities for fintech developers:
DeFi Integration : Connect to protocols like Uniswap, Aave, or Compound for yield and liquidity management
Treasury Operations : Automate treasury management within your fintech platform
Tokenized Assets : Integrate real-world assets into your product flows
Programmable Settlements : Execute compliance checks and automated settlements
Custom Assets : Manage custom assets, reward systems, and loyalty programs
Master Wallet vs Child Address
The Smart Contract API is available at two levels:
Master Wallet Execute contract operations directly from your master wallet. Ideal for treasury operations and centralized fund management.
Child Address Execute contract operations from individual child addresses. Perfect for user-specific operations and segregated fund management.
Master Wallet Endpoints
Operation Endpoint Description Read POST /v1/wallets/{walletId}/contracts/readRetrieve data from smart contracts Write POST /v1/wallets/{walletId}/contracts/writeExecute smart contract functions Network Fee POST /v1/wallets/{walletId}/contracts/network-feeEstimate gas costs Sign Only POST /v1/wallets/{walletId}/contracts/write/signSign without broadcasting
Child Address Endpoints
Operation Endpoint Description Read POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/readRetrieve data from smart contracts Write POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/writeExecute smart contract functions Network Fee POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/network-feeEstimate gas costs Sign Only POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/write/signSign without broadcasting
Request Structure
All smart contract requests require these parameters:
Parameter Type Required Description addressstring Yes The smart contract’s blockchain address methodstring Yes The function name to call parametersarray Yes Arguments matching the function’s ABI order abiarray Yes The contract’s Application Binary Interface referencestring No Your internal tracking ID for the transaction metadataobject No Custom key-value pairs for additional transaction details
The reference and metadata fields are only applicable for write operations. Read operations do not support these fields.
Understanding ABIs
The ABI (Application Binary Interface) defines how to interact with a smart contract. You can obtain ABIs from:
Block explorers : Etherscan, BscScan, PolygonScan (verified contracts)
Protocol documentation : Official docs from DeFi protocols
Contract source code : Compile from Solidity source
Reading Contract Data
Use the read endpoint to query contract state without modifying the blockchain.
Master Wallet Read Example
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/contracts/read \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x337610d27c682E347C9cD60BD4b3b107C9d34dDd",
"method": "balanceOf",
"parameters": ["0x947514e4B803e312C312da0F1B41fEDdbe15ae7a"],
"abi": [{
"constant": true,
"inputs": [{"name": "account", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}]
}'
Child Address Read Example
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/contracts/read \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x337610d27c682E347C9cD60BD4b3b107C9d34dDd",
"method": "balanceOf",
"parameters": ["0x947514e4B803e312C312da0F1B41fEDdbe15ae7a"],
"abi": [{
"constant": true,
"inputs": [{"name": "account", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}]
}'
Read Response
{
"message" : "Contract read successfully" ,
"statusCode" : 200 ,
"data" : "10052335235393043"
}
Read Error Responses
{
"message" : "Invalid contract address" ,
"statusCode" : 400 ,
"error" : "BAD_REQUEST"
}
{
"message" : "Method 'balanceOf' not found in ABI" ,
"statusCode" : 400 ,
"error" : "ABI_METHOD_NOT_FOUND"
}
Contract Execution Reverted
{
"message" : "Contract execution reverted" ,
"statusCode" : 400 ,
"error" : "EXECUTION_REVERTED" ,
"data" : {
"reason" : "ERC20: balance query for zero address"
}
}
{
"message" : "Parameter count mismatch. Expected 1, got 2" ,
"statusCode" : 400 ,
"error" : "INVALID_PARAMETERS"
}
Writing to Contracts
Execute state-changing functions on smart contracts.
Master Wallet Write Example
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/contracts/write \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0xYOUR_TOKEN_CONTRACT",
"method": "approve",
"parameters": ["0xYOUR_SPENDER_ADDRESS", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
Child Address Write Example
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/contracts/write \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0xYOUR_TOKEN_CONTRACT",
"method": "approve",
"parameters": ["0xYOUR_SPENDER_ADDRESS", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
Write Response
{
"message" : "Contract write initiated" ,
"statusCode" : 200 ,
"data" : {
"id" : "tx-uuid" ,
"hash" : "0x..." ,
"status" : "PENDING"
}
}
Write operations are asynchronous. The initial response shows PENDING status. Listen for the custom-smart-contract.success webhook to confirm transaction completion.
Write Error Responses
{
"message" : "Insufficient native token balance for gas" ,
"statusCode" : 400 ,
"error" : "INSUFFICIENT_GAS" ,
"data" : {
"required" : "0.005" ,
"available" : "0.001" ,
"token" : "ETH"
}
}
{
"message" : "Insufficient token balance" ,
"statusCode" : 400 ,
"error" : "INSUFFICIENT_BALANCE" ,
"data" : {
"required" : "1000000000000000000" ,
"available" : "500000000000000000"
}
}
{
"message" : "Transaction would revert" ,
"statusCode" : 400 ,
"error" : "EXECUTION_REVERTED" ,
"data" : {
"reason" : "ERC20: transfer amount exceeds allowance"
}
}
{
"message" : "Invalid ABI format" ,
"statusCode" : 400 ,
"error" : "INVALID_ABI" ,
"data" : {
"details" : "Missing 'inputs' field in ABI definition"
}
}
{
"message" : "Wallet not found" ,
"statusCode" : 404 ,
"error" : "NOT_FOUND"
}
Estimating Network Fees
Always estimate fees before executing write operations to ensure your wallet has sufficient native currency.
Master Wallet Fee Estimation
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/contracts/network-fee \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0xYOUR_TOKEN_CONTRACT",
"method": "approve",
"parameters": ["0xYOUR_SPENDER_ADDRESS", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
Child Address Fee Estimation
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/contracts/network-fee \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0xYOUR_TOKEN_CONTRACT",
"method": "approve",
"parameters": ["0xYOUR_SPENDER_ADDRESS", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
Fee Response
{
"message" : "Network fee retrieved" ,
"statusCode" : 200 ,
"data" : {
"networkFee" : "0.00001247904" ,
"networkFeeInUSD" : "0.01" ,
"nativeBalance" : "0.5" ,
"nativeBalanceInUSD" : "450.00" ,
"estimatedArrivalTime" : 30
}
}
Practical Example: Asset Swap on Uniswap
This section demonstrates two approaches to executing an asset swap: without batch operations (sequential calls) and with batch operations (single API call).
Example 1: Asset Swap WITHOUT Batch Operations
This approach makes individual API calls for each step. Use this when you need fine-grained control over each transaction or when operations depend on the results of previous calls.
Step 1: Check Asset Balance
const balanceOfAbi = {
constant: true ,
inputs: [{ name: 'account' , type: 'address' }],
name: 'balanceOf' ,
outputs: [{ name: '' , type: 'uint256' }],
stateMutability: 'view' ,
type: 'function'
};
const balance = await fetch (
`https://api.blockradar.co/v1/wallets/ ${ walletId } /contracts/read` ,
{
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' , 'x-api-key' : apiKey },
body: JSON . stringify ({
address: TOKEN_ADDRESS ,
method: 'balanceOf' ,
parameters: [ walletAddress ],
abi: [ balanceOfAbi ]
})
}
). then ( r => r . json ());
console . log ( 'Asset Balance:' , balance . data );
Step 2: Approve Asset Spending
const approveAbi = {
inputs: [
{ name: 'spender' , type: 'address' },
{ name: 'amount' , type: 'uint256' }
],
name: 'approve' ,
outputs: [{ name: '' , type: 'bool' }],
stateMutability: 'nonpayable' ,
type: 'function'
};
const approval = await fetch (
`https://api.blockradar.co/v1/wallets/ ${ walletId } /contracts/write` ,
{
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' , 'x-api-key' : apiKey },
body: JSON . stringify ({
address: TOKEN_ADDRESS ,
method: 'approve' ,
parameters: [ UNISWAP_ROUTER , amountIn ],
abi: [ approveAbi ]
})
}
). then ( r => r . json ());
console . log ( 'Approval TX:' , approval . data . hash );
// IMPORTANT: Wait for webhook confirmation before proceeding
Always wait for the custom-smart-contract.success webhook confirming the approval transaction was mined before executing the swap.
Step 3: Estimate Swap Fees
const swapAbi = {
inputs: [
{ name: 'amountIn' , type: 'uint256' },
{ name: 'amountOutMin' , type: 'uint256' },
{ name: 'path' , type: 'address[]' },
{ name: 'to' , type: 'address' },
{ name: 'deadline' , type: 'uint256' }
],
name: 'swapExactTokensForTokens' ,
outputs: [{ name: 'amounts' , type: 'uint256[]' }],
stateMutability: 'nonpayable' ,
type: 'function'
};
const fees = await fetch (
`https://api.blockradar.co/v1/wallets/ ${ walletId } /contracts/network-fee` ,
{
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' , 'x-api-key' : apiKey },
body: JSON . stringify ({
address: UNISWAP_ROUTER ,
method: 'swapExactTokensForTokens' ,
parameters: [
amountIn ,
amountOutMin ,
[ TOKEN_A , TOKEN_B ],
walletAddress ,
deadline
],
abi: [ swapAbi ]
})
}
). then ( r => r . json ());
console . log ( 'Estimated Fee:' , fees . data . networkFee );
Step 4: Execute Swap
const swap = await fetch (
`https://api.blockradar.co/v1/wallets/ ${ walletId } /contracts/write` ,
{
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' , 'x-api-key' : apiKey },
body: JSON . stringify ({
address: UNISWAP_ROUTER ,
method: 'swapExactTokensForTokens' ,
parameters: [
amountIn ,
amountOutMin ,
[ TOKEN_A , TOKEN_B ],
walletAddress ,
deadline
],
abi: [ swapAbi ]
})
}
). then ( r => r . json ());
console . log ( 'Swap TX:' , swap . data . hash );
Example 2: Asset Swap WITH Batch Operations
This approach combines approve + swap into a single API call using the calls array. Use this for efficiency when you want to queue multiple operations together.
Batch operations execute sequentially. Each operation is submitted as a separate transaction, but you only need one API call.
Batch Request: Approve + Swap in One Call
const approveAbi = {
inputs: [
{ name: 'spender' , type: 'address' },
{ name: 'amount' , type: 'uint256' }
],
name: 'approve' ,
outputs: [{ name: '' , type: 'bool' }],
stateMutability: 'nonpayable' ,
type: 'function'
};
const swapAbi = {
inputs: [
{ name: 'amountIn' , type: 'uint256' },
{ name: 'amountOutMin' , type: 'uint256' },
{ name: 'path' , type: 'address[]' },
{ name: 'to' , type: 'address' },
{ name: 'deadline' , type: 'uint256' }
],
name: 'swapExactTokensForTokens' ,
outputs: [{ name: 'amounts' , type: 'uint256[]' }],
stateMutability: 'nonpayable' ,
type: 'function'
};
const batchSwap = await fetch (
`https://api.blockradar.co/v1/wallets/ ${ walletId } /contracts/write` ,
{
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' , 'x-api-key' : apiKey },
body: JSON . stringify ({
calls: [
{
address: TOKEN_ADDRESS ,
method: 'approve' ,
parameters: [ UNISWAP_ROUTER , amountIn ],
abi: [ approveAbi ],
reference: 'approve-tx' ,
metadata: { step: 'approval' }
},
{
address: UNISWAP_ROUTER ,
method: 'swapExactTokensForTokens' ,
parameters: [
amountIn ,
amountOutMin ,
[ TOKEN_A , TOKEN_B ],
walletAddress ,
deadline
],
abi: [ swapAbi ],
reference: 'swap-tx' ,
metadata: { step: 'swap' }
}
]
})
}
). then ( r => r . json ());
console . log ( 'Batch Result:' , batchSwap . data );
Batch Response
{
"message" : "Batch contract write initiated successfully" ,
"statusCode" : 200 ,
"data" : {
"success" : [
{
"index" : 0 ,
"id" : "tx-uuid-1" ,
"hash" : "0xapprove..." ,
"status" : "PENDING" ,
"reference" : "approve-tx"
},
{
"index" : 1 ,
"id" : "tx-uuid-2" ,
"hash" : "0xswap..." ,
"status" : "PENDING" ,
"reference" : "swap-tx"
}
],
"errors" : []
}
}
Handling Partial Failures in Batch
const result = await batchSwap . json ();
// Check for successful operations
result . data . success . forEach ( tx => {
console . log ( `✓ ${ tx . reference } : ${ tx . hash } ` );
});
// Check for failed operations
result . data . errors . forEach ( error => {
console . error ( `✗ Operation ${ error . index } ( ${ error . method } ): ${ error . error } ` );
});
Batch Operation Rules
Rule Value Maximum batch size 20 operations Execution order Sequential Error handling Partial success (failures don’t stop subsequent operations)
When to Use Each Approach
Scenario Recommended Approach Need to check results between steps Without Batch Dynamic parameters based on previous results Without Batch Simple approve + action patterns With Batch Multiple independent operations With Batch Minimize API calls With Batch
Webhook Events
Smart contract operations trigger webhook notifications:
Event Description custom-smart-contract.successContract operation completed successfully custom-smart-contract.failedContract operation failed
Webhook Payload
{
"event" : "custom-smart-contract.success" ,
"data" : {
"id" : "tx-uuid" ,
"hash" : "0x..." ,
"status" : "SUCCESS" ,
"method" : "approve" ,
"contractAddress" : "0x..." ,
"blockchain" : {
"name" : "ethereum" ,
"network" : "mainnet"
}
}
}
Best Practices
Security
Verify contract addresses : Always double-check contract addresses before interacting
Use trusted ABIs : Obtain ABIs from verified sources like block explorers
Set reasonable limits : Use slippage protection and amount caps for DeFi operations
Gas Management
Estimate before executing : Always call the network-fee endpoint first
Monitor native balance : Ensure sufficient ETH/BNB/MATIC for gas fees
Use batch operations : Reduce overhead by batching related operations
Error Handling
Implement webhook listeners : Don’t rely solely on API responses
Handle partial failures : Check both success and errors arrays in batch responses
Retry with backoff : Implement exponential backoff for transient failures
API Reference
Master Wallet Endpoints
Endpoint Description Read Contract Read contract state Write Contract Execute contract functions Network Fee Estimate gas costs Sign Only Sign without broadcasting
Child Address Endpoints
Endpoint Description Read Contract Read contract state Write Contract Execute contract functions Network Fee Estimate gas costs Sign Only Sign without broadcasting
Support
The Smart Contract API enables you to build sophisticated blockchain integrations without managing infrastructure complexity. Start with simple read operations and gradually incorporate write operations as you become familiar with the system.