Skip to main content
After building and signing a transaction, the final step is broadcasting it to the Hive network. This guide covers the broadcasting process and how to handle responses.

Prerequisites

Before broadcasting, ensure your transaction is:
1

Built with valid operations

Your transaction must contain at least one operation.
console.log('Operations:', tx.transaction.operations.length);
2

Properly signed

The transaction must have valid signatures for all required authorities.
if (!tx.isSigned()) {
  throw new Error('Transaction must be signed before broadcasting');
}
3

Validated

Run validation to catch any errors before broadcasting.
tx.validate();

Basic broadcasting

Use the broadcast() method on your chain instance to send a transaction to the network.
import { createHiveChain } from '@hiveio/wax';
import beekeeperFactory from '@hiveio/beekeeper';

async function broadcastTransaction() {
  // Initialize chain
  const chain = await createHiveChain();

  // Create and build transaction
  const tx = await chain.createTransaction();
  tx.pushOperation({
    vote_operation: {
      voter: "alice",
      author: "bob",
      permlink: "example-post",
      weight: 10000
    }
  });

  // Sign transaction
  const beekeeper = await beekeeperFactory();
  const session = beekeeper.createSession('my-app');
  const { wallet } = await session.createWallet('my-wallet');
  await wallet.importKey(privateKey);
  const [publicKey] = wallet.getPublicKeys();
  
  tx.sign(wallet, publicKey);

  // Broadcast to network
  try {
    await chain.broadcast(tx.transaction);
    console.log('Transaction broadcast successfully!');
    console.log('Transaction ID:', tx.id);
  } catch (error) {
    console.error('Broadcast failed:', error);
  }
}
Broadcasting is an asynchronous operation. It sends your transaction to the network where it will be included in a block by witness nodes.

Broadcasting with custom endpoint

You can specify a custom API endpoint when creating your chain instance.
import { createHiveChain } from '@hiveio/wax';

// Use a specific API node
const chain = await createHiveChain({
  endpoint_url: 'https://api.hive.blog'
});

// Or use a different network (testnet)
const testnetChain = await createHiveChain({
  endpoint_url: 'https://testnet.openhive.network',
  chainId: '42' // Testnet chain ID
});

await chain.broadcast(tx.transaction);

Handling broadcast responses

The broadcast method doesn’t return much data, but you can check the transaction status using the transaction ID.
async function broadcastAndVerify() {
  const chain = await createHiveChain();
  const tx = await chain.createTransaction();
  
  // Build and sign transaction...
  
  const txId = tx.id;
  console.log('Transaction ID:', txId);

  try {
    // Broadcast
    await chain.broadcast(tx.transaction);
    console.log('✓ Transaction broadcast successfully');

    // Wait a moment for the transaction to be included
    await new Promise(resolve => setTimeout(resolve, 3000));

    // Verify transaction was included
    const result = await chain.api.database_api.get_transaction({
      id: txId
    });

    if (result) {
      console.log('✓ Transaction confirmed in block:', result.block_num);
    }
  } catch (error) {
    console.error('✗ Broadcast failed:', error.message);
    throw error;
  }
}

Common broadcast errors

Understanding common errors helps you handle them appropriately.
Error: Missing Active Authority or Missing Posting AuthorityCause: The transaction wasn’t signed with the correct authority level.Solution: Check required authorities and sign with the correct key.
const authorities = tx.requiredAuthorities;
console.log('Required authorities:', authorities);
// Make sure you sign with a key that has the required authority
Error: Duplicate transaction check failedCause: The same transaction was already broadcast.Solution: Create a new transaction or wait for the previous one to expire.
// Don't broadcast the same transaction twice
// Create a new transaction if you need to retry
const newTx = await chain.createTransaction();
Error: Transaction expiredCause: The transaction’s expiration time has passed.Solution: Create a new transaction with a fresh expiration time.
// Transactions expire after 1 minute by default
// Create transactions close to when you'll broadcast them
const tx = await chain.createTransaction({
  expirationTime: "+5m" // Give yourself more time if needed
});
Error: Invalid signatureCause: The signature doesn’t match the transaction or was created with wrong chain ID.Solution: Ensure you’re using the correct chain ID and signing properly.
// Make sure chain ID matches the network
console.log('Chain ID:', chain.chainId);

// Validate before signing
tx.validate();
Error: Insufficient funds or Account does not have sufficient fundsCause: The account doesn’t have enough balance for the operation.Solution: Check account balance before creating transfer operations.
// Check balance before transferring
const accounts = await chain.api.database_api.find_accounts({
  accounts: ['alice']
});
console.log('Balance:', accounts.accounts[0].balance);

Broadcasting with retry logic

Implement retry logic to handle temporary network issues.
async function broadcastWithRetry(
  chain: any,
  tx: any,
  maxRetries: number = 3,
  retryDelay: number = 1000
) {
  let lastError: Error | null = null;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      console.log(`Broadcast attempt ${attempt}/${maxRetries}`);
      await chain.broadcast(tx.transaction);
      console.log('✓ Broadcast successful');
      return true;
    } catch (error) {
      lastError = error as Error;
      console.warn(`Attempt ${attempt} failed:`, error.message);

      // Don't retry certain errors
      if (
        error.message.includes('Duplicate transaction') ||
        error.message.includes('expired') ||
        error.message.includes('Invalid signature')
      ) {
        throw error;
      }

      if (attempt < maxRetries) {
        console.log(`Retrying in ${retryDelay}ms...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      }
    }
  }

  throw lastError || new Error('Broadcast failed after retries');
}

// Usage
try {
  await broadcastWithRetry(chain, tx);
} catch (error) {
  console.error('All broadcast attempts failed:', error);
}

Complete example

Here’s a complete example that builds, signs, and broadcasts a transaction.
import { createHiveChain } from '@hiveio/wax';
import beekeeperFactory from '@hiveio/beekeeper';

async function completeExample() {
  // Step 1: Initialize
  const chain = await createHiveChain();
  const beekeeper = await beekeeperFactory();
  const session = beekeeper.createSession('my-app');
  const { wallet } = await session.createWallet('my-wallet');

  // Step 2: Import key
  const privateKey = process.env.PRIVATE_KEY!;
  await wallet.importKey(privateKey);
  const [publicKey] = wallet.getPublicKeys();

  // Step 3: Build transaction
  const tx = await chain.createTransaction();
  tx.pushOperation({
    transfer_operation: {
      from_account: "alice",
      to_account: "bob",
      amount: chain.hive.satoshis(1),
      memo: "hello from wax!"
    }
  });

  // Step 4: Validate
  tx.validate();
  console.log('✓ Transaction valid');

  // Step 5: Sign
  tx.sign(wallet, publicKey);
  console.log('✓ Transaction signed');
  console.log('Transaction ID:', tx.id);

  // Step 6: Broadcast
  try {
    await chain.broadcast(tx.transaction);
    console.log('✓ Transaction broadcast successfully!');
    console.log('View on explorer:', `https://hiveblocks.com/tx/${tx.id}`);
  } catch (error) {
    console.error('✗ Broadcast failed:', error);
    throw error;
  }
}

completeExample().catch(console.error);

Best practices

Broadcast checklist

Before broadcasting, ensure:
  • ✅ Transaction is validated
  • ✅ Transaction is properly signed
  • ✅ You’re using the correct network (mainnet vs testnet)
  • ✅ Account has sufficient funds for the operation
  • ✅ You have error handling in place
  • ✅ Transaction hasn’t expired

After broadcasting

After a successful broadcast:
  • ⏱️ Transactions typically appear in blocks within 3 seconds
  • 🔍 Use the transaction ID to track status
  • 📝 Save the transaction ID for your records
  • ⚠️ Wait for irreversibility (about 1 minute) for critical operations

Next steps

Complex operations

Learn about high-level operation helpers

API calls

Explore the Hive API for checking transaction status

Error handling

Comprehensive error handling guide

Network broadcast API

API reference for broadcasting

Build docs developers (and LLMs) love