Docs

wallet/broadcasttransaction - Broadcast TRON Tr...

Broadcast signed TRON transactions to the network with instant confirmation and detailed result tracking via Dwellir's high-performance endpoints.

Instant Transaction Broadcasting

Dwellir's TRON endpoints broadcast transactions to the network in under 100ms with real-time confirmation tracking. Get instant feedback on transaction success and network inclusion.

Start broadcasting now

Broadcasts a signed transaction to the TRON network for execution. This is the final step after creating and signing a transaction.

When to Use This Method

wallet/broadcasttransaction is essential for:

  • Transaction Execution - Submit signed transactions to the network
  • Payment Processing - Complete payment transactions in real-time
  • Smart Contract Calls - Execute signed contract interactions
  • Multi-Signature Operations - Broadcast fully-signed multi-sig transactions
  • Batch Processing - Submit multiple transactions efficiently

Parameters

Signed Transaction Object - Complete transaction with signatures

  • txID - Transaction identifier
  • raw_data - Original transaction data
  • raw_data_hex - Hex encoded transaction data
  • signature - Array of signatures (hex strings)
  • visible - Address format indicator
JSON
{
  "txID": "94eea63bb6774c8fc4f4c9d1b62c1e8c2f7c8c2e4d3a2b1c0d9e8f7a6b5c4d3e2f1",
  "raw_data": {
    "contract": [
      {
        "parameter": {
          "value": {
            "amount": 1000000,
            "owner_address": "TJmmqjb1DK9TTZbQXzRQ2AuA94z4gKAPFh",
            "to_address": "TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN"
          },
          "type_url": "type.googleapis.com/protocol.TransferContract"
        },
        "type": "TransferContract"
      }
    ],
    "ref_block_bytes": "4a7b",
    "ref_block_hash": "e15e44aa73bd9e15",
    "expiration": 1734567890000,
    "timestamp": 1734567830000
  },
  "signature": ["c8f8f8e8d8c8b8a898887878686858484838281807060504030201"]
}

Returns

Broadcast Result containing:

  • result - Boolean indicating broadcast success
  • txid - Transaction ID (if successful)
  • code - Error code (if failed)
  • message - Error message (if failed)

Implementation Examples

Bash
# Basic transaction broadcast
curl -X POST "https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/broadcasttransaction" \
  -H "Content-Type: application/json" \
  -d '{
    "txID": "94eea63bb6774c8fc4f4c9d1b62c1e8c2f7c8c2e4d3a2b1c0d9e8f7a6b5c4d3e2f1",
    "raw_data": {
      "contract": [{
        "parameter": {
          "value": {
            "amount": 1000000,
            "owner_address": "TJmmqjb1DK9TTZbQXzRQ2AuA94z4gKAPFh",
            "to_address": "TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN"
          },
          "type_url": "type.googleapis.com/protocol.TransferContract"
        },
        "type": "TransferContract"
      }],
      "ref_block_bytes": "4a7b",
      "ref_block_hash": "e15e44aa73bd9e15",
      "expiration": 1734567890000,
      "timestamp": 1734567830000
    },
    "signature": ["c8f8f8e8d8c8b8a898887878686858484838281807060504030201"]
  }'

# Broadcast and check result
curl -s -X POST "https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/broadcasttransaction" \
  -H "Content-Type: application/json" \
  -d @signed_transaction.json | jq '{
    success: .result,
    txid: .txid,
    error: .message
  }'

# Script with retry logic
#!/bin/bash
API_KEY="YOUR_API_KEY"
SIGNED_TX_FILE="signed_transaction.json"
MAX_RETRIES=3

broadcast_with_retry() {
  local attempt=1
  
  while [ $attempt -le $MAX_RETRIES ]; do
    echo "Broadcasting transaction (attempt $attempt/$MAX_RETRIES)..."
    
    RESULT=$(curl -s -X POST "https://api-tron-mainnet.n.dwellir.com/$API_KEY/wallet/broadcasttransaction" \
      -H "Content-Type: application/json" \
      -d @"$SIGNED_TX_FILE")
    
    SUCCESS=$(echo "$RESULT" | jq -r '.result // false')
    
    if [ "$SUCCESS" = "true" ]; then
      TXID=$(echo "$RESULT" | jq -r '.txid')
      echo "✓ Transaction broadcast successful: $TXID"
      return 0
    else
      ERROR=$(echo "$RESULT" | jq -r '.message // "Unknown error"')
      echo "✗ Attempt $attempt failed: $ERROR"
      
      if [ $attempt -eq $MAX_RETRIES ]; then
        echo "Transaction broadcast failed after $MAX_RETRIES attempts"
        return 1
      fi
      
      # Exponential backoff
      DELAY=$((2 ** (attempt - 1)))
      echo "Waiting ${DELAY}s before retry..."
      sleep $DELAY
    fi
    
    ((attempt++))
  done
}

# Check transaction confirmation
check_confirmation() {
  local txid=$1
  local timeout=${2:-30}
  local start_time=$(date +%s)
  
  echo "Waiting for confirmation of $txid..."
  
  while true; do
    current_time=$(date +%s)
    elapsed=$((current_time - start_time))
    
    if [ $elapsed -ge $timeout ]; then
      echo "Confirmation timeout after ${timeout}s"
      return 1
    fi
    
    TX_INFO=$(curl -s -X POST "https://api-tron-mainnet.n.dwellir.com/$API_KEY/wallet/gettransactionbyid" \
      -H "Content-Type: application/json" \
      -d "{\"value\": \"$txid\", \"visible\": true}")
    
    BLOCK_NUM=$(echo "$TX_INFO" | jq -r '.blockNumber // null')
    
    if [ "$BLOCK_NUM" != "null" ]; then
      echo "✓ Transaction confirmed in block $BLOCK_NUM"
      return 0
    fi
    
    echo "Checking confirmation... (${elapsed}s elapsed)"
    sleep 3
  done
}

# Batch broadcasting script
batch_broadcast() {
  local tx_files=("$@")
  local successful=0
  local failed=0
  
  echo "Broadcasting ${#tx_files[@]} transactions..."
  
  for tx_file in "${tx_files[@]}"; do
    echo "Processing $tx_file..."
    
    if broadcast_with_retry "$tx_file"; then
      ((successful++))
    else
      ((failed++))
    fi
    
    # Rate limiting
    sleep 0.1
  done
  
  echo "Batch complete: $successful successful, $failed failed"
}

# Usage
if [ "$1" = "single" ]; then
  broadcast_with_retry && check_confirmation "$(echo "$RESULT" | jq -r '.txid')"
elif [ "$1" = "batch" ]; then
  shift
  batch_broadcast "$@"
else
  echo "Usage: $0 {single|batch} [tx_files...]"
fi
JavaScript
const TRON_API = 'https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY';

// Broadcast a signed transaction
async function broadcastTransaction(signedTransaction) {
  const response = await fetch(`${TRON_API}/wallet/broadcasttransaction`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(signedTransaction)
  });

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  return await response.json();
}

// Enhanced broadcast with monitoring and retry logic
async function broadcastWithMonitoring(signedTransaction, options = {}) {
  const {
    maxRetries = 3,
    retryDelay = 1000,
    confirmationTimeout = 30000
  } = options;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      console.log(`Broadcasting transaction (attempt ${attempt}/${maxRetries})...`);
      
      const result = await broadcastTransaction(signedTransaction);
      
      if (result.result) {
        console.log(`✓ Transaction broadcast successful: ${result.txid}`);
        
        // Optional: Wait for confirmation
        if (options.waitForConfirmation) {
          const confirmation = await waitForConfirmation(result.txid, confirmationTimeout);
          return { ...result, confirmation };
        }
        
        return result;
      } else {
        throw new Error(`Broadcast failed: ${result.message || 'Unknown error'}`);
      }
    } catch (error) {
      console.log(`✗ Attempt ${attempt} failed:`, error.message);
      
      if (attempt === maxRetries) {
        throw new Error(`Transaction broadcast failed after ${maxRetries} attempts: ${error.message}`);
      }
      
      // Exponential backoff
      await new Promise(resolve => setTimeout(resolve, retryDelay * Math.pow(2, attempt - 1)));
    }
  }
}

// Wait for transaction confirmation
async function waitForConfirmation(txId, timeout = 30000) {
  const startTime = Date.now();
  const checkInterval = 3000; // Check every 3 seconds
  
  while (Date.now() - startTime < timeout) {
    try {
      const txInfo = await getTransactionInfo(txId);
      
      if (txInfo && txInfo.blockNumber) {
        return {
          confirmed: true,
          blockNumber: txInfo.blockNumber,
          confirmationTime: Date.now() - startTime,
          fee: txInfo.fee || 0
        };
      }
    } catch (error) {
      console.log('Checking confirmation...', error.message);
    }
    
    await new Promise(resolve => setTimeout(resolve, checkInterval));
  }
  
  return {
    confirmed: false,
    timeout: true,
    message: 'Transaction confirmation timeout'
  };
}

// Get transaction information for confirmation
async function getTransactionInfo(txId) {
  const response = await fetch(`${TRON_API}/wallet/gettransactionbyid`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ value: txId, visible: true })
  });
  
  return await response.json();
}

// Batch transaction broadcasting
async function broadcastBatch(signedTransactions, options = {}) {
  const { 
    concurrency = 5,
    delayBetween = 100 
  } = options;
  
  const results = [];
  
  // Process in chunks to respect rate limits
  for (let i = 0; i < signedTransactions.length; i += concurrency) {
    const chunk = signedTransactions.slice(i, i + concurrency);
    
    const chunkPromises = chunk.map(async (tx, index) => {
      try {
        // Stagger requests slightly
        await new Promise(resolve => setTimeout(resolve, index * delayBetween));
        
        const result = await broadcastWithMonitoring(tx);
        return {
          success: true,
          txId: tx.txID,
          result: result,
          index: i + index
        };
      } catch (error) {
        return {
          success: false,
          txId: tx.txID,
          error: error.message,
          index: i + index
        };
      }
    });
    
    const chunkResults = await Promise.allSettled(chunkPromises);
    results.push(...chunkResults.map(r => r.status === 'fulfilled' ? r.value : r.reason));
    
    // Delay between chunks
    if (i + concurrency < signedTransactions.length) {
      await new Promise(resolve => setTimeout(resolve, delayBetween * concurrency));
    }
  }
  
  return {
    total: signedTransactions.length,
    successful: results.filter(r => r.success).length,
    failed: results.filter(r => !r.success).length,
    results: results
  };
}

// Complete transaction flow example
async function sendTRXTransaction(fromAddress, toAddress, amount, privateKey) {
  try {
    // Step 1: Create transaction
    console.log('Creating transaction...');
    const transaction = await createTransaction(fromAddress, toAddress, amount);
    
    // Step 2: Sign transaction (simplified - use proper signing library)
    console.log('Signing transaction...');
    const signedTransaction = await signTransaction(transaction, privateKey);
    
    // Step 3: Broadcast transaction
    console.log('Broadcasting transaction...');
    const result = await broadcastWithMonitoring(signedTransaction, {
      waitForConfirmation: true,
      maxRetries: 3
    });
    
    console.log('Transaction completed:', result);
    return result;
    
  } catch (error) {
    console.error('Transaction failed:', error.message);
    throw error;
  }
}

// Usage examples
(async () => {
  try {
    // Single transaction broadcast
    const signedTx = {
      // ... signed transaction object
    };
    
    const result = await broadcastWithMonitoring(signedTx, {
      waitForConfirmation: true,
      maxRetries: 3
    });
    console.log('Broadcast result:', result);
    
    // Batch broadcasting
    const signedTransactions = [
      // ... array of signed transactions
    ];
    
    const batchResult = await broadcastBatch(signedTransactions, {
      concurrency: 3,
      delayBetween: 200
    });
    console.log(`Batch complete: ${batchResult.successful}/${batchResult.total} successful`);
    
  } catch (error) {
    console.error('Error:', error);
  }
})();
Python
import requests
import json
import time
import asyncio
import aiohttp
from typing import Dict, List, Optional

class TronBroadcaster:
    def __init__(self, api_key: str):
        self.base_url = f"https://api-tron-mainnet.n.dwellir.com/{api_key}"
        self.headers = {
            'Content-Type': 'application/json'
        }
    
    def broadcast_transaction(self, signed_transaction: Dict) -> Dict:
        """Broadcast a signed transaction to TRON network"""
        url = f"{self.base_url}/wallet/broadcasttransaction"
        
        response = requests.post(url, headers=self.headers, json=signed_transaction)
        response.raise_for_status()
        
        return response.json()
    
    def broadcast_with_monitoring(self, signed_transaction: Dict, 
                                 max_retries: int = 3,
                                 retry_delay: int = 1000,
                                 wait_for_confirmation: bool = False,
                                 confirmation_timeout: int = 30000) -> Dict:
        """Broadcast transaction with retry logic and optional confirmation"""
        
        for attempt in range(1, max_retries + 1):
            try:
                print(f"Broadcasting transaction (attempt {attempt}/{max_retries})...")
                
                result = self.broadcast_transaction(signed_transaction)
                
                if result.get('result'):
                    print(f"✓ Transaction broadcast successful: {result.get('txid')}")
                    
                    # Optional: Wait for confirmation
                    if wait_for_confirmation:
                        confirmation = self.wait_for_confirmation(
                            result['txid'], 
                            confirmation_timeout
                        )
                        result['confirmation'] = confirmation
                    
                    return result
                else:
                    raise Exception(f"Broadcast failed: {result.get('message', 'Unknown error')}")
                    
            except Exception as e:
                print(f"✗ Attempt {attempt} failed: {str(e)}")
                
                if attempt == max_retries:
                    raise Exception(f"Transaction broadcast failed after {max_retries} attempts: {str(e)}")
                
                # Exponential backoff
                time.sleep((retry_delay / 1000) * (2 ** (attempt - 1)))
        
        raise Exception("Unexpected error in broadcast_with_monitoring")
    
    def wait_for_confirmation(self, tx_id: str, timeout: int = 30000) -> Dict:
        """Wait for transaction confirmation"""
        start_time = time.time() * 1000
        check_interval = 3000  # Check every 3 seconds
        
        while (time.time() * 1000) - start_time < timeout:
            try:
                tx_info = self.get_transaction_info(tx_id)
                
                if tx_info and tx_info.get('blockNumber'):
                    return {
                        'confirmed': True,
                        'block_number': tx_info['blockNumber'],
                        'confirmation_time': (time.time() * 1000) - start_time,
                        'fee': tx_info.get('fee', 0)
                    }
            except Exception as e:
                print(f"Checking confirmation... {str(e)}")
            
            time.sleep(check_interval / 1000)
        
        return {
            'confirmed': False,
            'timeout': True,
            'message': 'Transaction confirmation timeout'
        }
    
    def get_transaction_info(self, tx_id: str) -> Dict:
        """Get transaction information for confirmation"""
        url = f"{self.base_url}/wallet/gettransactionbyid"
        
        payload = {
            'value': tx_id,
            'visible': True
        }
        
        response = requests.post(url, headers=self.headers, json=payload)
        response.raise_for_status()
        
        return response.json()
    
    def broadcast_batch(self, signed_transactions: List[Dict], 
                       concurrency: int = 5,
                       delay_between: float = 0.1) -> Dict:
        """Broadcast multiple transactions in batch"""
        results = []
        
        # Process in chunks to respect rate limits
        for i in range(0, len(signed_transactions), concurrency):
            chunk = signed_transactions[i:i + concurrency]
            
            chunk_results = []
            for index, tx in enumerate(chunk):
                try:
                    # Stagger requests slightly
                    time.sleep(index * delay_between)
                    
                    result = self.broadcast_with_monitoring(tx)
                    chunk_results.append({
                        'success': True,
                        'tx_id': tx['txID'],
                        'result': result,
                        'index': i + index
                    })
                except Exception as e:
                    chunk_results.append({
                        'success': False,
                        'tx_id': tx['txID'],
                        'error': str(e),
                        'index': i + index
                    })
            
            results.extend(chunk_results)
            
            # Delay between chunks
            if i + concurrency < len(signed_transactions):
                time.sleep(delay_between * concurrency)
        
        successful = [r for r in results if r['success']]
        failed = [r for r in results if not r['success']]
        
        return {
            'total': len(signed_transactions),
            'successful': len(successful),
            'failed': len(failed),
            'results': results
        }
    
    async def broadcast_async(self, signed_transactions: List[Dict], 
                             concurrency: int = 5) -> Dict:
        """Asynchronous batch broadcasting"""
        semaphore = asyncio.Semaphore(concurrency)
        
        async def broadcast_single(session, tx, index):
            async with semaphore:
                try:
                    async with session.post(
                        f"{self.base_url}/wallet/broadcasttransaction",
                        headers=self.headers,
                        json=tx
                    ) as response:
                        result = await response.json()
                        return {
                            'success': True,
                            'tx_id': tx['txID'],
                            'result': result,
                            'index': index
                        }
                except Exception as e:
                    return {
                        'success': False,
                        'tx_id': tx['txID'],
                        'error': str(e),
                        'index': index
                    }
        
        async with aiohttp.ClientSession() as session:
            tasks = [
                broadcast_single(session, tx, i) 
                for i, tx in enumerate(signed_transactions)
            ]
            results = await asyncio.gather(*tasks, return_exceptions=True)
        
        successful = [r for r in results if isinstance(r, dict) and r.get('success')]
        failed = [r for r in results if isinstance(r, dict) and not r.get('success')]
        
        return {
            'total': len(signed_transactions),
            'successful': len(successful),
            'failed': len(failed),
            'results': results
        }

# Usage examples
if __name__ == "__main__":
    broadcaster = TronBroadcaster('YOUR_API_KEY')
    
    # Example signed transaction
    signed_tx = {
        "txID": "94eea63bb6774c8fc4f4c9d1b62c1e8c2f7c8c2e4d3a2b1c0d9e8f7a6b5c4d3e2f1",
        "raw_data": {
            # ... transaction data
        },
        "signature": ["c8f8f8e8d8c8b8a898887878686858484838281807060504030201"]
    }
    
    try:
        # Single transaction broadcast
        result = broadcaster.broadcast_with_monitoring(
            signed_tx,
            wait_for_confirmation=True,
            max_retries=3
        )
        print(f"Broadcast result: {result}")
        
        # Batch broadcasting
        signed_transactions = [signed_tx]  # List of signed transactions
        
        batch_result = broadcaster.broadcast_batch(
            signed_transactions,
            concurrency=3,
            delay_between=0.2
        )
        print(f"Batch complete: {batch_result['successful']}/{batch_result['total']} successful")
        
    except Exception as e:
        print(f"Error: {e}")

Response Examples

Successful Broadcast

JSON
{
  "result": true,
  "txid": "94eea63bb6774c8fc4f4c9d1b62c1e8c2f7c8c2e4d3a2b1c0d9e8f7a6b5c4d3e2f1"
}

Failed Broadcast (Insufficient Energy)

JSON
{
  "result": false,
  "code": "CONTRACT_VALIDATE_ERROR",
  "message": "account does not have enough energy"
}

Network Error

JSON
{
  "result": false,
  "code": "SERVER_BUSY",
  "message": "Server is busy, please try again later"
}

Common Use Cases

1. Payment Gateway Completion

JavaScript
class PaymentProcessor {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.broadcaster = new TronBroadcaster(apiKey);
  }
  
  async processPayment(paymentRequest) {
    try {
      const { signedTransaction, paymentId, amount, customer } = paymentRequest;
      
      console.log(`Processing payment ${paymentId} for ${amount} TRX`);
      
      // Broadcast with monitoring
      const result = await this.broadcaster.broadcast_with_monitoring(
        signedTransaction,
        {
          maxRetries: 5,
          waitForConfirmation: true,
          confirmationTimeout: 60000
        }
      );
      
      if (result.result && result.confirmation?.confirmed) {
        // Payment successful
        await this.updatePaymentStatus(paymentId, 'completed', result.txid);
        await this.notifyCustomer(customer, 'payment_success', result.txid);
        
        return {
          status: 'completed',
          txId: result.txid,
          blockNumber: result.confirmation.blockNumber,
          fee: result.confirmation.fee
        };
      } else {
        throw new Error('Payment confirmation failed');
      }
      
    } catch (error) {
      await this.updatePaymentStatus(paymentId, 'failed', null, error.message);
      await this.notifyCustomer(customer, 'payment_failed', error.message);
      throw error;
    }
  }
  
  async updatePaymentStatus(paymentId, status, txId = null, error = null) {
    // Update payment in database
    console.log(`Payment ${paymentId} status: ${status}`);
  }
  
  async notifyCustomer(customer, event, data) {
    // Send notification to customer
    console.log(`Notifying ${customer}: ${event} - ${data}`);
  }
}

2. Multi-Signature Transaction Execution

JavaScript
async function executeMultiSigTransaction(multiSigTransaction, requiredSignatures) {
  try {
    // Verify we have enough signatures
    if (multiSigTransaction.signature.length < requiredSignatures) {
      throw new Error(`Insufficient signatures: ${multiSigTransaction.signature.length}/${requiredSignatures}`);
    }
    
    console.log(`Executing multi-sig transaction with ${multiSigTransaction.signature.length} signatures`);
    
    const result = await broadcastWithMonitoring(multiSigTransaction, {
      maxRetries: 3,
      waitForConfirmation: true
    });
    
    return {
      executed: true,
      txId: result.txid,
      signatures: multiSigTransaction.signature.length,
      confirmation: result.confirmation
    };
    
  } catch (error) {
    console.error('Multi-sig execution failed:', error);
    return {
      executed: false,
      error: error.message,
      signatures: multiSigTransaction.signature?.length || 0
    };
  }
}

3. Automated Trading Bot

JavaScript
class TronTradingBot {
  constructor(apiKey, strategy) {
    this.apiKey = apiKey;
    this.strategy = strategy;
    this.broadcaster = new TronBroadcaster(apiKey);
    this.pendingTrades = new Map();
  }
  
  async executeTrade(tradeSignal) {
    try {
      const { action, amount, price, signedTransaction } = tradeSignal;
      
      console.log(`Executing ${action} trade: ${amount} TRX at ${price}`);
      
      // Broadcast trade transaction
      const result = await this.broadcaster.broadcast_with_monitoring(
        signedTransaction,
        { 
          maxRetries: 2,
          waitForConfirmation: false // Don't wait for DEX trades
        }
      );
      
      if (result.result) {
        // Track pending trade
        this.pendingTrades.set(result.txid, {
          action,
          amount,
          price,
          timestamp: Date.now(),
          status: 'pending'
        });
        
        // Monitor in background
        this.monitorTradeConfirmation(result.txid);
        
        return {
          success: true,
          tradeId: result.txid,
          action,
          amount,
          price
        };
      } else {
        throw new Error(`Trade broadcast failed: ${result.message}`);
      }
      
    } catch (error) {
      console.error('Trade execution failed:', error);
      return {
        success: false,
        error: error.message,
        action: tradeSignal.action
      };
    }
  }
  
  async monitorTradeConfirmation(txId) {
    // Background monitoring
    setTimeout(async () => {
      try {
        const confirmation = await this.broadcaster.wait_for_confirmation(txId, 30000);
        const trade = this.pendingTrades.get(txId);
        
        if (confirmation.confirmed && trade) {
          trade.status = 'confirmed';
          trade.blockNumber = confirmation.blockNumber;
          console.log(`Trade ${txId} confirmed in block ${confirmation.blockNumber}`);
          
          // Update strategy
          this.strategy.onTradeConfirmed(trade);
        }
      } catch (error) {
        console.error(`Trade monitoring failed for ${txId}:`, error);
      }
    }, 1000);
  }
}

4. Subscription Payment Processing

JavaScript
class SubscriptionManager {
  constructor(apiKey) {
    this.broadcaster = new TronBroadcaster(apiKey);
    this.subscriptions = new Map();
  }
  
  async processSubscriptionPayment(subscriptionId, signedTransaction) {
    try {
      const subscription = this.subscriptions.get(subscriptionId);
      if (!subscription) {
        throw new Error('Subscription not found');
      }
      
      console.log(`Processing subscription payment for ${subscriptionId}`);
      
      const result = await this.broadcaster.broadcast_with_monitoring(
        signedTransaction,
        {
          maxRetries: 3,
          waitForConfirmation: true,
          confirmationTimeout: 45000
        }
      );
      
      if (result.result && result.confirmation?.confirmed) {
        // Update subscription status
        subscription.status = 'active';
        subscription.lastPayment = Date.now();
        subscription.nextBilling = Date.now() + (30 * 24 * 60 * 60 * 1000); // 30 days
        subscription.txId = result.txid;
        
        await this.activateSubscription(subscriptionId);
        await this.scheduleNextBilling(subscriptionId);
        
        return {
          success: true,
          subscriptionId,
          txId: result.txid,
          nextBilling: subscription.nextBilling
        };
      } else {
        throw new Error('Payment confirmation failed');
      }
      
    } catch (error) {
      console.error(`Subscription payment failed for ${subscriptionId}:`, error);
      
      // Update subscription status
      const subscription = this.subscriptions.get(subscriptionId);
      if (subscription) {
        subscription.status = 'payment_failed';
        subscription.lastError = error.message;
      }
      
      throw error;
    }
  }
  
  async activateSubscription(subscriptionId) {
    console.log(`Activating subscription ${subscriptionId}`);
    // Activate user's subscription features
  }
  
  async scheduleNextBilling(subscriptionId) {
    const subscription = this.subscriptions.get(subscriptionId);
    if (subscription) {
      console.log(`Next billing for ${subscriptionId}: ${new Date(subscription.nextBilling)}`);
      // Schedule next payment reminder
    }
  }
}

Error Handling

Error CodeDescriptionSolution
CONTRACT_VALIDATE_ERRORTransaction validation failedCheck balance, signatures, and transaction data
BANDWIDTH_ERRORInsufficient bandwidthWait for bandwidth reset or use TRX for fees
ENERGY_ERRORInsufficient energyFreeze TRX for energy or rent energy
SIGNATURE_ERRORInvalid signatureRe-sign transaction with correct private key
EXPIRED_ERRORTransaction expiredCreate new transaction with updated timestamp
SERVER_BUSYNetwork congestionRetry with exponential backoff
JavaScript
// Comprehensive error handling
async function robustBroadcast(signedTransaction, options = {}) {
  const errors = {
    CONTRACT_VALIDATE_ERROR: 'Transaction validation failed',
    BANDWIDTH_ERROR: 'Insufficient bandwidth - wait 24h or freeze TRX',
    ENERGY_ERROR: 'Insufficient energy - freeze TRX or rent energy',
    SIGNATURE_ERROR: 'Invalid signature - check private key',
    EXPIRED_ERROR: 'Transaction expired - create new transaction',
    SERVER_BUSY: 'Network busy - retrying...'
  };
  
  try {
    const result = await broadcastWithMonitoring(signedTransaction, options);
    return { success: true, result };
  } catch (error) {
    const errorCode = error.message.includes('CONTRACT_VALIDATE_ERROR') ? 'CONTRACT_VALIDATE_ERROR' :
                     error.message.includes('bandwidth') ? 'BANDWIDTH_ERROR' :
                     error.message.includes('energy') ? 'ENERGY_ERROR' :
                     error.message.includes('signature') ? 'SIGNATURE_ERROR' :
                     error.message.includes('expired') ? 'EXPIRED_ERROR' :
                     error.message.includes('busy') ? 'SERVER_BUSY' : 'UNKNOWN_ERROR';
    
    return {
      success: false,
      errorCode,
      errorMessage: errors[errorCode] || error.message,
      retryable: ['SERVER_BUSY', 'BANDWIDTH_ERROR'].includes(errorCode),
      originalError: error.message
    };
  }
}

Performance Tips

  1. Parallel Processing - Broadcast multiple transactions concurrently with rate limiting
  2. Retry Strategy - Implement exponential backoff for failed broadcasts
  3. Confirmation Polling - Use efficient polling intervals for transaction confirmation
  4. Error Recovery - Handle different error types with appropriate recovery strategies
JavaScript
// Performance-optimized batch broadcaster
class OptimizedBroadcaster {
  constructor(apiKey, options = {}) {
    this.apiKey = apiKey;
    this.maxConcurrency = options.maxConcurrency || 10;
    this.rateLimitPerSecond = options.rateLimitPerSecond || 20;
    this.queue = [];
    this.processing = false;
  }
  
  async addToBroadcastQueue(signedTransaction, priority = 'normal') {
    return new Promise((resolve, reject) => {
      this.queue.push({
        transaction: signedTransaction,
        priority,
        resolve,
        reject,
        timestamp: Date.now()
      });
      
      this.processQueue();
    });
  }
  
  async processQueue() {
    if (this.processing) return;
    this.processing = true;
    
    // Sort by priority
    this.queue.sort((a, b) => {
      const priorities = { high: 3, normal: 2, low: 1 };
      return priorities[b.priority] - priorities[a.priority];
    });
    
    while (this.queue.length > 0) {
      const batch = this.queue.splice(0, this.maxConcurrency);
      
      const promises = batch.map(async (item, index) => {
        // Stagger requests to respect rate limits
        await new Promise(resolve => 
          setTimeout(resolve, (index * 1000) / this.rateLimitPerSecond)
        );
        
        try {
          const result = await broadcastWithMonitoring(item.transaction);
          item.resolve(result);
        } catch (error) {
          item.reject(error);
        }
      });
      
      await Promise.allSettled(promises);
    }
    
    this.processing = false;
  }
}

Need help? Contact our support team or check the TRON documentation.