Code Examples
This page provides practical examples of integrating with Shield in various programming languages.
JavaScript (Node.js)
Complete Integration Example
const axios = require('axios');
const bitcoin = require('bitcoinjs-lib');
const ecpair = require('ecpair');
const ecc = require('tiny-secp256k1');
// Initialize libraries
const ECPair = ecpair.ECPairFactory(ecc);
const network = bitcoin.networks.bitcoin;
async function getShieldInfo() {
try {
const response = await axios.get('https://shield.rebarlabs.io/v1/info');
return response.data;
} catch (error) {
console.error('Error fetching Shield info:', error.message);
throw error;
}
}
async function createAndSendTransaction(utxos, recipientAddress, amount, privateKey) {
try {
// Get Shield info
const shieldInfo = await getShieldInfo();
const shieldAddress = shieldInfo.payment.p2wpkh;
// Choose fee rate (for this example, we'll use the highest)
const feeRateOption = shieldInfo.fees.reduce((highest, current) => {
return current.estimated_hashrate > highest.estimated_hashrate ? current : highest;
}, shieldInfo.fees[0]);
const feeRate = feeRateOption.feerate;
console.log(`Using fee rate of ${feeRate} sats/vbyte`);
// Create keypair from private key
const keyPair = ECPair.fromPrivateKey(Buffer.from(privateKey, 'hex'));
const { address } = bitcoin.payments.p2wpkh({
pubkey: keyPair.publicKey,
network
});
// Build transaction
const psbt = new bitcoin.Psbt({ network });
// Add inputs
let inputValue = 0;
utxos.forEach(utxo => {
psbt.addInput({
hash: utxo.txid,
index: utxo.vout,
witnessUtxo: {
script: bitcoin.address.toOutputScript(address, network),
value: utxo.value,
}
});
inputValue += utxo.value;
});
// Estimate transaction size (simplified)
const estimatedTxSize = (utxos.length * 68) + (2 * 34) + 10;
// Calculate Shield fee
const shieldFee = Math.ceil(estimatedTxSize * feeRate);
console.log(`Estimated Shield fee: ${shieldFee} satoshis`);
// Add outputs
psbt.addOutput({
address: recipientAddress,
value: amount
});
psbt.addOutput({
address: shieldAddress,
value: shieldFee
});
// Calculate change amount
const changeAmount = inputValue - amount - shieldFee;
if (changeAmount > 546) { // Dust threshold
psbt.addOutput({
address: address, // Change back to sender
value: changeAmount
});
}
// Sign inputs
utxos.forEach((_, index) => {
psbt.signInput(index, keyPair);
});
// Finalize and extract transaction
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
const txHex = tx.toHex();
// Submit to Shield
const response = await axios.post('https://shield.rebarlabs.io/v1/rpc', {
jsonrpc: '1.0',
id: 'shield',
method: 'sendrawtransaction',
params: [txHex]
});
console.log('Transaction submitted successfully:', response.data.result);
return response.data.result;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
throw error;
}
}
// Usage example (do not include real private keys in code)
// const utxos = [{ txid: '...', vout: 0, value: 10000000 }];
// const recipientAddress = 'bc1q...';
// const amount = 5000000; // 0.05 BTC in satoshis
// const privateKey = '...';
// createAndSendTransaction(utxos, recipientAddress, amount, privateKey);
Python
Basic Integration Example
import requests
import json
class ShieldClient:
def __init__(self, base_url="https://shield.rebarlabs.io/v1"):
self.base_url = base_url
self.payment_address = None
self.fee_options = None
self.refresh_info()
def refresh_info(self):
"""Fetch current Shield payment address and fee information"""
response = requests.get(f"{self.base_url}/info")
data = response.json()
self.payment_address = data['payment']['p2wpkh']
self.fee_options = data['fees']
return data
def get_recommended_fee_rate(self, target_hashrate=0.9):
"""Get fee rate for target hashrate percentage"""
if not self.fee_options:
self.refresh_info()
# Find fee rate that meets or exceeds target hashrate
for option in sorted(self.fee_options, key=lambda x: x['estimated_hashrate']):
if option['estimated_hashrate'] >= target_hashrate:
return option['feerate']
# If no option meets target, return highest available
return max(self.fee_options, key=lambda x: x['estimated_hashrate'])['feerate']
def calculate_fee(self, tx_size_vbytes, target_hashrate=0.9):
"""Calculate Shield fee for a transaction"""
fee_rate = self.get_recommended_fee_rate(target_hashrate)
return tx_size_vbytes * fee_rate
def send_raw_transaction(self, tx_hex):
"""Submit raw transaction to Shield"""
payload = {
'jsonrpc': '1.0',
'id': 'shield',
'method': 'sendrawtransaction',
'params': [tx_hex]
}
response = requests.post(f"{self.base_url}/rpc", json=payload)
return response.json()
# Usage example
if __name__ == "__main__":
client = ShieldClient()
print(f"Shield payment address: {client.payment_address}")
print(f"Available fee options: {client.fee_options}")
# Calculate fee for a 250 vbyte transaction targeting 90% hashrate
fee = client.calculate_fee(250, 0.9)
print(f"Recommended fee for 250 vbyte tx: {fee} satoshis")
# Example transaction submission (uncomment to use)
# tx_hex = "..." # Your signed transaction hex
# result = client.send_raw_transaction(tx_hex)
# print(f"Transaction submission result: {result}")
Integration Tips
Always fetch current info: Shield's payment address and fee rates can change. Always fetch the latest information from the
/info
endpoint before creating transactions.Implement error handling: Shield returns detailed error codes and messages. Implement proper error handling to interpret and respond to these errors.
Consider retry logic: For network errors or temporary service unavailability, implement retry logic with exponential backoff.
Optimize transaction size: Smaller transactions require less in fees. Use native SegWit addresses and batch transactions when possible.
Include logging: Log transaction submissions and responses for debugging and audit purposes.
Last updated