bloXroute Documentation
WebsiteBlogTwitterDiscord
  • Welcome to bloXroute
  • Introduction
    • Why Use bloXroute?
    • Products
    • Create An Account
    • Technical Support
  • SOLANA
    • Trader API
      • Introduction
        • Regions
        • Authorization
        • Rate Limits
        • Tip and Tipping Addresses
      • Quick Start
        • Transaction Submission
        • Front-Running Protection & Transaction Bundle
        • Go SDK
        • Python SDK
        • Typescript SDK
        • Rust SDK
      • API Endpoints
        • Core Endpoints
          • submit
          • submit-paladin
          • submit-batch
          • balance
          • rate-limit
          • transaction
          • priority-fee
          • GetPriorityFeeStream
          • GetBundleTipStream
          • submit-snipe
        • Pump.fun
          • quotes
          • swap
          • swap-sol
          • GetPumpFunNewTokensStream
          • GetPumpFunSwapsStream
          • GetPumpFunAMMSwapsStream
        • Raydium
          • quotes
          • pools
          • pool-reserves
          • swap
          • cpmm-swap
          • clmm-swap
          • route-swap
          • GetPoolReservesStream
          • GetSwapsStream
          • GetNewRaydiumPoolsStream
          • GetNewRaydiumPoolsByTransactionStream
        • Jupiter
          • quotes
          • swap
          • swap-instructions
          • route-swap
        • Openbook
          • markets
          • orderbooks/{market}
          • depth/{market}
          • tickers/{market}
          • open-orders/{market}
          • unsettled/{market}
          • place
          • replace
          • cancel
          • settle
          • GetOrderbooksStream
          • GetTickersStream
      • Best Performance for Landing Transactions
      • Support
        • API Health
        • Contact us
        • Suggestions
        • Wiki
          • Terms & Concepts
          • Resources
    • Optimized Feed Relay (OFR)
      • Transaction Streamer
      • Gateway and OFR Requirements
      • Gateway and OFR Setup
      • Gateway Startup Arguments
      • OFR performance
      • Logging
      • Submitting Transaction
      • Upgrading Gateway
      • Troubleshooting
  • BSC & ETH
    • EVM Blockchain Distribution Network (BDN)
      • How to Connect
      • The bloXroute Gateway
        • Local Gateway
          • Installation and Startup
            • Authentication & Certificates
            • Requirements
            • Supported Clients
            • GitHub repository option
            • Docker container option
            • Startup Script
            • Startup Arguments
          • General Connectivity Troubleshooting
          • Logging
          • Upgrading your Gateway
        • Add Your Gateway as a Trusted Peer to Your Execution Layer Client
        • Connecting Your Gateway with the Consensus Layer
      • IPs & Relays
        • Relays IPs
        • Private Relays
        • Cloud-API IPs
          • ⏩Reducing Latencies using the BDN
    • APIs
      • Authorization
      • Check Transaction Quota
      • Submit a Transaction
        • Raw Transaction Construction
        • Tx-Validation
        • Batch Transaction
      • Private Transactions
        • ETH Private Transactions
        • BSC Private Transactions
      • Transaction Bundles
        • Bundle Simulation
        • Bundle Validation
        • Bundle Submission
          • BSC Bundle Submission
            • List of BSC Validators
          • ETH Bundle Submission
          • Bundle Submission with Gateway
        • Bundle Tracking
          • BSC Bundle-Trace
          • ETH Bundle-Trace
          • ETH Bundle Inclusion Status
        • Bundle Refunds
          • Priority Fee Refund
          • Bundle Refund
          • Latest Bundle Refunds
      • Backrun Arbitrage
        • BackRunMe: Bundle Submission
          • BSC submit arbOnly
          • ETH submit arbOnly
            • blxr_info
            • ETH arbOnly Simulation
      • Token Launch Sniping
      • Other Utilities
        • List of bloXroute Builders
        • List of External Builders
        • Tx-Trace
        • Ping
    • Streams
      • Requirements
      • Subscription limits
      • Working With Streams
        • Creating a Subscription
          • Websocket
          • gRPC
        • Handling the Notification
          • Websocket
          • gRPC
        • Cancelling a Subscription
          • Websocket
          • gRPC
        • Local Node Validation
      • newTxs and pendingTxs
        • Filters
        • Raw TX Reconstruction
      • BackRunMe: arbOnlyMEV
        • ETH arbOnlyMEV
        • BSC arbOnlyMEV
      • transactionStatus
      • txReceipts
      • newBlocks
      • bdnBlocks
      • ethOnBlock
      • MEVBlockValue
      • MEVNextProposerInfo
    • Block Builders and Validators
      • Validator Gateway
      • MEV Relay (For Validators)
      • Block Submission
      • Proposer MEV-Protect
      • Compliance Lists
      • Preconfirmations
    • Protect RPCs
      • ETH Protect RPC
      • ETH Gas Protect RPC
      • BSC Protect RPC
      • SOL Protect RPC
  • Base Network
    • Submit Transactions
    • Streams
      • GetBdnBlockStream
  • TON NETWORK
    • TON Trader API
      • Quick Start
      • Fee Schedule
      • Connection
      • Submit Signed Transaction
  • Resources
    • BDN Explorer
    • Block Explorer
    • Guides
      • Algorithmic Trading
      • Setting Up a Local Gateway
      • Gateway as Web3 Bridge
    • Architecture
      • BDN Architecture
        • Network Components
        • Performance Techniques
          • Block Compression
          • Cut-through Routing
          • Optimized Topology
      • bloXroute Protocol
        • Versioning
        • Message Structure
        • Message Types
    • Contact Us
Powered by GitBook
On this page
  1. BSC & ETH
  2. APIs
  3. Submit a Transaction

Raw Transaction Construction

The blxr_tx endpoint is expecting raw transaction bytes. Constructing the transaction is typically done using a library like web3 or ethers. The below examples demonstrate constructing a raw transaction and submitting it to blxr_tx .

Examples - Create a Simple Transfer raw transaction and submit it to blxr_tx api

const WebSocket = require('ws')
const EthereumTx = require('ethereumjs-tx').Transaction
// Needed for BSC
// const Common = require('ethereumjs-common').default
const Web3 = require('web3')

const web3 = new Web3('PROVIDER_URL')

const account = 'YOUR_ADDRESS'

const privateKey = Buffer.from(
  'YOUR_PRIVATE_KEY',
  'hex',
)

// const BSC = Common.forCustomChain(
//   'mainnet',
//   {
//       name: 'Binance Smart Chain Mainnet',
//       networkId: 56,
//       chainId: 56,
//       url: 'https://bsc-dataseed.binance.org/'
//   },
//   'istanbul',
// )

const main = async () => {
  const tx = new EthereumTx({
      to: 'TO_ADDRESS',
      nonce: nonce,
      // Pass in decimal number for fields below
      gasPrice: web3.utils.toHex(),
      gas: web3.utils.toHex(),
      value: web3.utils.toHex(),
      chainId: 1
      // If using BSC
      // chainId: 56
    } //, { common: BSC } 
  )
  tx.sign(privateKey)

  const serializedTx = tx.serialize()
  const rawTx = serializedTx.toString('hex')
  
  const ws = new WebSocket(
    "ws://127.0.0.1:28333/ws", 
    {
      headers: { 
        "Authorization" : <YOUR-AUTHORIZATION-HEADER>
      },
      rejectUnauthorized: false,
    }
  );

  function proceed() {
    ws.send(`{"jsonrpc": "2.0", "id": 1, "method": "blxr_tx", "params": {"transaction": "${rawTx}"}}`)
  }

  function handle(response) {
    console.log(response.toString()) // Or process it generally
  }
  ws.on('open', proceed)
  ws.on('message', handle)
}
# Python 3.7 or higher required due to the use of asyncio.run()
import json, ssl, asyncio, websockets
from web3 import Web3

async def send_tx():
    web3 = Web3(Web3.HTTPProvider())
    private_key = "YOUR_PRIVATE_KEY"
    to_address = "TO_ADDRESS"
    gas = 21000  # Pass in correct gas
    gas_price = web3.toWei('50', 'gwei')  # Pass in correct gas_price
    nonce = web3.eth.getTransactionCount(web3.eth.defaultAccount)
    chain_id = 1  # BSC chainId is 56

    transaction = {
        "to": to_address,
        "value": 0,
        "gas": gas,
        "gasPrice": gas_price,
        "nonce": nonce,
        "chainId": chain_id
    }
    signed_tx = web3.eth.account.sign_transaction(transaction, private_key)
    raw_tx = signed_tx.rawTransaction.hex()

    async with websockets.connect(
        "wss://api.blxrbdn.com/ws",
        extra_headers=[("Authorization", "YOUR_AUTHORIZATION_HEADER")],
        ssl=ssl.SSLContext(cert_reqs=ssl.CERT_NONE)
    ) as ws:
        request = json.dumps({"id": 1, "method": "blxr_tx", "params": {"transaction": raw_tx}})
        await ws.send(request)
        response = await ws.recv()
        print(response)

if __name__ == '__main__':
    asyncio.run(send_tx())
package main

import (
	"context"
	"crypto/ecdsa"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"log"
	"math/big"
	"net/http"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/ethereum/go-ethereum/rlp"
	"github.com/gorilla/websocket"
)

func main() {
	// go-ethereum will know the chain info base on PROVIDER_URL given
	client, err := ethclient.Dial("PROVIDER_URL")
	if err != nil {
		log.Fatal(err)
	}

	privateKey, err := crypto.HexToECDSA("YOUR_PRIVATE_KEY")
	if err != nil {
		log.Fatal(err)
	}

	publicKey := privateKey.Public()
	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		log.Fatal("error casting public key to ECDSA")
	}

	// go-ethereum gets the public address from the private keys provided
	fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
	nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
	if err != nil {
		log.Fatal(err)
	}

	value := big.NewInt()

	toAddress := common.HexToAddress("ADDRESS_TO_SEND_TO")

	chainID, err := client.NetworkID(context.Background())

	if err != nil {
		log.Fatal(err)
	}

	gasFeeCap := big.NewInt()

	gasTipCap := big.NewInt()

	gas := uint64()

	var data []byte

	// To send EIP-1559 Transactions / Type 2 
	tx := types.NewTx(&types.DynamicFeeTx{
		Nonce:     nonce,
		GasFeeCap: gasFeeCap,
		GasTipCap: gasTipCap,
		Gas:       gas,
		To:        &toAddress,
		Value:     value,
		Data:      data})

	signedTx, err := types.SignTx(tx, types.NewLondonSigner(chainID), privateKey)

	/*
		// For Legacy Transactions / Type 0

		gasPrice, err := client.SuggestGasPrice(context.Background())
		if err != nil {
			log.Fatal(err)
		}

		tx := types.NewTx(&types.LegacyTx{
			Nonce:    nonce,
			GasPrice: gasPrice,
			Gas:      gas,
			To:       &toAddress,
			Value:    value,
			Data:     data})

		signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
	*/

	if err != nil {
		log.Fatal(err)
	}

	rawTxBytes, err := signedTx.MarshalBinary()
	rawTxHex := hex.EncodeToString(rawTxBytes)

	if err != nil {
		log.Fatal("Unable to cast to raw txn")
	}

	fmt.Printf("raw bytes: %x", rawTxBytes)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
	}
	dialer := websocket.DefaultDialer
	dialer.TLSClientConfig = tlsConfig
	wsSubscriber, _, err := dialer.Dial("ws://127.0.0.1:28333/ws", http.Header{"Authorization": []string{<YOUR-AUTHORIZATION-HEADER>}})

	if err != nil {
		fmt.Println(err)
		return
	}

	jsonString := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "blxr_tx", "params": {"transaction": "%s"}}`, rawTxHex)

	request := jsonString

	err = wsSubscriber.WriteMessage(websocket.TextMessage, []byte(request))
	if err != nil {
		fmt.Println(err)
		return
	}

	for {
		_, nextNotification, err := wsSubscriber.ReadMessage()
		if err != nil {
			fmt.Println(err)
		}
		fmt.Println(string(nextNotification)) // or process it generally
	}

}


Examples - Create a Token Swap raw transaction and submit it to blxr_tx api

const fs = require('fs')
const WebSocket = require('ws')
const EthereumTx = require('ethereumjs-tx').Transaction
const Common = require('ethereumjs-common').default
const Web3 = require('web3')

const web3 = new Web3('PROVIDER_URL')

const account = 'YOUR_ADDRESS'

const privateKey = Buffer.from(
  'PRIVATE_KEY',
  'hex',
)

// Network you would like to connect to, in this case BSC Mainnet
const BSC_FORK = Common.forCustomChain(
  'mainnet',
  {
      name: 'Binance Smart Chain Mainnet',
      networkId: 56,
      chainId: 56,
      url: 'https://bsc-dataseed.binance.org/'
  },
  'istanbul',
)


const main = async () => {
  const bnb = 'WBNB_TOKEN_ADDRESS'
  const token = 'TOKEN_ADDRESS_TO_SWAP_FOR'

  const pair = [bnb, token]

  // Amount of BNB to swap
  const tokenAmountIn = web3.utils.toHex()
  // Desired amount of token returned
  const amountOutMin = web3.utils.toHex()

  const pancakeSwapRouterAddress = 'PANCAKESWAP_ROUTER_ADDRESS'

  // Export Pancakeswap ABI to json file in same directory
  const abi = JSON.parse(fs.readFileSync('pancake-router-abi.json', 'utf-8'));
  const contract = new web3.eth.Contract(abi, pancakeSwapRouterAddress, {from: account})
    
  const data = contract.methods.swapExactETHForTokens(
    amountOutMin,
    pair,
    account,
    Date.now() + 1000 * 60 * 10,
    )

    const tx = new EthereumTx({
        to: pancakeSwapRouterAddress,
        nonce: nonce,
        // Desired gas usage in decimal format
        gasPrice: web3.utils.toHex(),
        gas: web3.utils.toHex(),
        value: tokenAmountIn,
        data: data.encodeABI(),
        chainId: 56
      }, {common: BSC_FORK}
    )

  tx.sign(privateKey)

  const serializedTx = tx.serialize()
  const rawTx = serializedTx.toString('hex')
    
  const ws = new WebSocket(
    "ws://127.0.0.1:28333/ws", 
    {
      headers: { 
        "Authorization" : <YOUR-AUTHORIZATION-HEADER>
      },
      rejectUnauthorized: false,
    }
  );

  function proceed() {
    ws.send(`{"jsonrpc": "2.0", "id": 1, "method": "blxr_tx", "params": {"transaction": "${rawTx}", "blockchain_network": "BSC-Mainnet"}}`)
  }

  function handle(response) {
    console.log(response.toString()) // Or process it generally
  }
  ws.on('open', proceed)
  ws.on('message', handle)
}
# Python 3.7 or higher required due to the use of asyncio.run()
import json, time, websocket
from web3 import Web3

web3 = Web3(Web3.HTTPProvider("https://bsc-dataseed.binance.org/"))

private_key = "YOUR_PRIVATE_KEY"
account = "YOUR_ADDRESS"

wbnb_address = "WBNB_TOKEN_ADDRESS"
token_address = "TOKEN_ADDRESS_TO_SWAP_FOR"

pair = [wbnb_address, token_address]

# Amount of BNB to swap
token_amount_in = 1
# Desired amount of token returned
amount_out_min = 2

pancake_swap_router_address = "PANCAKESWAP_ROUTER_ADDRESS"

# Export Pancakeswap ABI to json file in same directory
with open("./pancake-router-abi.json") as f:
    abi = json.load(f)
contract = web3.eth.contract(pancake_swap_router_address, abi=abi)

data = contract.functions.swapExactETHForTokens(
    amount_out_min,
    pair,
    account,
    int(time.time()) + 60 * 10
).buildTransaction({"chainId": 56, "gas": 100, "gasPrice": 35000000000})["data"]

transaction = {
    "to": pancake_swap_router_address,
    "value": token_amount_in,
    "gas": gas, # Pass in correct gas
    "gasPrice": gas_price, # Pass in correct gas_price
    "nonce": nonce, # Pass in correct nonce
    "chainId": 56,
    "data": data
}
signed_tx = web3.eth.account.sign_transaction(transaction, private_key)
raw_tx = signed_tx.rawTransaction.hex()[2:]

headers = {"Authorization": <YOUR-AUTHORIZATION-HEADER>}

try:
    ws = websocket.create_connection(
        'wss://bx-api.blxrbdn.com/ws',
        header=["Authorization:{}".format(headers["Authorization"])],
        subprotocols=['binary']
    )

    request = json.dumps({"id": 1, "method": "blxr_tx", "params": {"transaction": raw_tx}})
    ws.send(request)

    while True:
        response = json.loads(ws.recv())
        print(response)
except Exception as e:
    print(f'Connection failed, Reason: {e}')
finally:
    ws.close()
package main

import (
	"context"
	"crypto/ecdsa"
	"crypto/tls"
	"encoding/hex"

	"fmt"
	"log"
	"math/big"
	"net/http"
	"time"

	store "Pancake" // abi created go script

	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/ethereum/go-ethereum/rlp"
	"github.com/gorilla/websocket"
)

func main() {
	client, err := ethclient.Dial("PROVIDER_URL")
	if err != nil {
		log.Fatal(err)
	}

	// BSC network chain id is 56
	chainId := big.NewInt(56)

	if err != nil {
		log.Fatal(err)
	}

	privateKey, err := crypto.HexToECDSA("YOUR_PRIVATE_KEY")
	if err != nil {
		log.Fatal(err)
	}

	publicKey := privateKey.Public()
	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
	}

	fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
	nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
	if err != nil {
		log.Fatal(err)
	}

	gasPrice, err := client.SuggestGasPrice(context.Background())
	if err != nil {
		log.Fatal(err)
	}

	auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainId)
	if err != nil {
		fmt.Println(err)
	}
	auth.Nonce = big.NewInt(int64(nonce))
	auth.Value = big.NewInt(0)     // in wei
	auth.GasLimit = uint64(0)      // in units
	auth.GasPrice = gasPrice

	address := common.HexToAddress("PANCAKESWAP_ROUTER_ADDRESS")
	instance, err := store.NewStore(address, client)
	if err != nil {
		log.Fatal(err)
	}
	const (
		WETH        = "WBNB_TOKEN_ADDRESS"
		tokenWanted = "TOKEN_ADDRESS_TO_SWAP_FOR"
	)

	tokenWantedAddress := common.HexToAddress(tokenWanted)
	wethTokenAddress := common.HexToAddress(WETH)
	path := []common.Address{wethTokenAddress, tokenWantedAddress}
	// You ethereum address where tokens will be receive 
	myAddress := common.HexToAddress("YOUR_WALLET_ADDRESS")
	// The minimum amount tokens to receive.
	amountOutMin := big.NewInt(0)
	currentTime := big.NewInt(time.Now().UTC().UnixNano()/1e6 + 1000*60*10)

	tx, err := instance.SwapExactETHForTokens(auth, amountOutMin, path, myAddress, currentTime)
	if err != nil {
		log.Fatal(err)
	}

	ts := types.Transactions{tx}
	rawTxBytes, _ := ts[0].MarshalBinary()
	rawTxHex := hex.EncodeToString(rawTxBytes)

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
	}
	dialer := websocket.DefaultDialer
	dialer.TLSClientConfig = tlsConfig
	wsSubscriber, _, err := dialer.Dial("ws://127.0.0.1:28333/ws", http.Header{"Authorization": []string{<YOUR-AUTHORIZATION-HEADER>}})

	if err != nil {
		fmt.Println(err)
		return
	}

	jsonString := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "blxr_tx", "params": {"transaction": "%s"}}`, rawTxHex)

	request := jsonString

	err = wsSubscriber.WriteMessage(websocket.TextMessage, []byte(request))
	if err != nil {
		fmt.Println(err)
		return
	}

	for {
		_, nextNotification, err := wsSubscriber.ReadMessage()
		if err != nil {
			fmt.Println(err)
		}
		fmt.Println(string(nextNotification)) // or process it generally
	}
}
PreviousSubmit a TransactionNextTx-Validation