# Raw Transaction Construction

The `blxr_tx` endpoint expects raw transaction bytes. These are usually built using libraries like **web3** or **ethers**.\
Below are examples showing how to:

* Create and send a simple transfer via `blxr_tx`
* Create and send a token swap transaction via `blxr_tx`

{% tabs %}
{% tab title="Transfer - Node.js" %}

```javascript
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)
}
```

{% endtab %}

{% tab title="Transfer - Python " %}

```python
# 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())

```

{% endtab %}

{% tab title="Transfer - Go" %}

```go
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
	}

}



```

{% endtab %}

{% tab title="Swap - Node.js" %}

```javascript
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,
    }
  );
```

{% endtab %}

{% tab title="Swap - Python" %}

```python
# 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()
```

{% endtab %}

{% tab title="Swap - Go" %}

```go
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
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.bloxroute.com/eth/sending-transactions/raw-transaction-construction.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
