newTxs and pendingTxs
Name:
newTxs
, pendingTxs
Key | Description | Values |
include | Fields to include in the transaction stream. The subscription plan determines the list of available fields. | tx_hash,tx_contents [Default: all] |
duplicates | Whether or not to include transactions already published in the feed. | True,False [Default] |
include_from_blockchain | Whether or not to include transactions received first from the connected blockchain node.
(Mainly used for testing) | True [Default],False |
filters | You can specify filters in SQL-Like format to only receive certain transactions. | Users can customize the filters. |
blockchain_network | Blockchain network name. Use with Cloud-API when working with BSC | Mainnet [Default, Ethereum Mainnet], BSC-Mainnet , Polygon-Mainnet |
The BDN supports subscribing to two transaction streams:
- 1.
newTxs
is a stream of all new transactions as they are propagated in the BDN. - 2.
pendingTxs
is a stream of all new transactions as they enter the Ethereum/BSC/Polygon transaction pool.
For expedience, all transactions received through the BDN are immediately published to the
newTxs
feed. By design, the Gateway/Cloud-API do not perform the same detail of transaction validation that the Ethereum nodes do, and cannot completely guarantee that all transactions propagated are valid (e.g. the Gateway/Cloud-API do not check for double spends). Therefore, these transactions have had basic validations done (e.g. checksums and other sanity checks) but may not be accepted into the TxPool.The Gateway/Cloud-API can then leverage the Ethereum nodes for further validation of the transaction (e.g. check that it will be accepted into the TxPool), and publish results to the
pendingTxs
feed. Users planning to use pendingTxs
with a Gateway feed should enable validation against their local Ethereum node.It is expected that
newTxs
stream will perform faster than pendingTxs
. The performance difference can be significant (10-100ms). Users interested in timely transaction information could find newTxs
stream more appealing, while those who rely on strict correctness of the transactions data should utilize the pendingTxs
stream.The
newTxs
stream can send transactions that have been (a) previously confirmed hours or days prior, or (b) replaced by a higher priced transaction with the same nonce. It is recommended that users with latency sensitive applications track the latest nonce for each account and use it to filter out stale messages.The fields allowed in the
include
section depends on the user's subscription plan:Plan | Available Fields |
Introductory | tx_hash |
Professional and above | tx_hash , tx_contents.input , tx_contents.v , tx_contents.r , tx_contents.s , tx_contents.type , tx_contents.from , tx_contents.to , tx_contents.value , tx_contents.nonce , tx_contents.gas , tx_contents.gas_price , tx_contents.max_priority_fee_per_gas ,tx_contents.max_fee_per_gas ,local_region ,raw_tx |
The transaction feed will publish the data for each transaction in a separate message. Users that are only interested in a subset of transactions can utilize the feed's filtering options.
Notes:
- Follow the examples below based on your subscription plan. We suggest you to use "try...catch" to better handle exceptions caused by potential disconnections. The examples below contain the minimum code required for all transactions stream subscriptions.
- Enterprise plan users can choose to work directly with
wss://<region>.<network name>.blxrbdn.com/ws
(e.g.wss://virginia.eth.blxrbdn.com/ws
for ETH)for the best performance. - Non-Enterprise plan users should use
wss://api.blxrbdn.com/ws
.
wscat
Python
Node.js
Golang
## ETH Example
wscat -c wss://virginia.eth.blxrbdn.com/ws --header "Authorization: <YOUR-AUTHORIZATION-HEADER>"
> {"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"]}]}
< ......
## BSC Example
wscat -c wss://virginia.bsc.blxrbdn.com/ws --header "Authorization: <YOUR-AUTHORIZATION-HEADER>"
> {"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"], "blockchain_network": "BSC-Mainnet"}]}
< ......
## Polygon Example
wscat -c wss://virginia.polygon.blxrbdn.com/ws --header "Authorization: <YOUR-AUTHORIZATION-HEADER>"
> {"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"], "blockchain_network": "Polygon-Mainnet"}]}
< ......
async with WsProvider(
uri="wss://virginia.eth.blxrbdn.com/ws",
headers={"Authorization": <YOUR-AUTHORIZATION-HEADER>},
# Add the following line if you work with IP instead of DNS
# skip_ssl_cert_verify=True
) as ws:
# Non Enterprise users should follow line 12-17
# async with WsProvider(
# uri="wss://api.blxrbdn.com/ws",
# headers={"Authorization": <YOUR-AUTHORIZATION-HEADER>}
# Add the following line if you work with IP instead of DNS
# skip_ssl_cert_verify=True
# ) as ws:
# ETH Example
subscription_id = await ws.subscribe("newTxs", {"include": ["tx_hash"]})
# BSC Example (only available at endpoint wss://<region>.bsc.blxrbdn.com/ws)
# subscription_id = await ws.subscribe("newTxs", {"include": ["tx_hash"], "blockchain_network": "BSC-Mainnet"})
# Polygon Example (only available at endpoint wss://<region>.polygon.blxrbdn.com/ws)
# subscription_id = await ws.subscribe("newTxs", {"include": ["tx_hash"], "blockchain_network": "Polygon-Mainnet"})
while True:
next_notification = await ws.get_next_subscription_notification_by_id(subscription_id)
print(next_notification) # or process it generally
await ws.unsubscribe(subscription_id)
var fs = require('fs');
const WebSocket = require('ws');
// Enterprise users can follow line 5-16
const ws = new WebSocket(
'wss://virginia.eth.blxrbdn.com/ws', // for ETH
// use 'wss://virginia.bsc.blxrbdn.com/ws', //for BSC
// use 'wss://virginia.polygon.blxrbdn.com/ws', // for Polygon
{
headers: {
"Authorization" : <YOUR-AUTHORIZATION-HEADER>
},
// Add the following line if you work with IP instead of DNS
// rejectUnauthorized: false,
}
);
// Non Enterprise users should follow line 19-27
// const ws = new WebSocket(
// "wss://api.blxrbdn.com/ws",
// {
// headers: {
// "Authorization" : <YOUR-AUTHORIZATION-HEADER>
// },
// rejectUnauthorized: false,
// }
// );
function proceed() {
// ETH Example
ws.send(`{"jsonrpc": "2.0", "id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"]}]}`);
// BSC Example (only available at endpoint wss://<region>.bsc.blxrbdn.com/ws)
// ws.send(`{"jsonrpc": "2.0", "id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"], "blockchain_network": "BSC-Mainnet"}]}`);
// Polygon Example (only available at endpoint wss://<region>.polygon.blxrbdn.com/ws)
// ws.send(`{"jsonrpc": "2.0", "id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"], "blockchain_network": "Polygon-Mainnet"}]}`);
}
function handle(nextNotification) {
console.log(nextNotification.toString()); // or process it generally
}
ws.on('open', proceed);
ws.on('message', handle);
package main
import (
"crypto/tls"
"fmt"
"github.com/gorilla/websocket"
"net/http"
)
func main() {
dialer := websocket.DefaultDialer
// Add the following lines if you work with IP instead of DNS
// tlsConfig := &tls.Config{
// Certificates: []tls.Certificate{cert},
// InsecureSkipVerify: true,
// }
// dialer.TLSClientConfig = tlsConfig
// Enterprise users can follow line 20
wsSubscriber, _, err := dialer.Dial("wss://virginia.eth.blxrbdn.com/ws", http.Header{"Authorization": []string{<YOUR-AUTHORIZATION-HEADER>}})
// Non Enterprise users can follow line 23
// wsSubscriber, _, err := dialer.Dial("wss://api.blxrbdn.com/ws", http.Header{"Authorization": []string{<YOUR-AUTHORIZATION-HEADER>}})
if err != nil {
fmt.Println(err)
return
}
// ETH Example
subRequest := `{"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"]}]}`
// BSC Example (only available at endpoint wss://<region>.bsc.feed.blxrbdn.com:28333)
// subRequest := `{"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"], "blockchain_network": "BSC-Mainnet"}]}`
// Polygon Example (only available at endpoint wss://<region>.polygon.blxrbdn.com:28333)
// subRequest := `{"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"], "blockchain_network": "Polygon-Mainnet"}]}`
err = wsSubscriber.WriteMessage(websocket.TextMessage, []byte(subRequest))
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
}
}
Notes:
- We assume that the Gateway IP is
127.0.0.1
with default ws port28333
in the examples below. By default, the WebSocket endpoint isws://127.0.0.1:28333/ws
for Go Gateway. - For Go Gateway, the authentication header is always required for ws connection.
wscat
Python
Node.js
Golang
wscat -c ws://127.0.0.1:28333/ws --header "Authorization: <YOUR-AUTHORIZATION-HEADER>"
> {"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"]}]}
< ......
from bxcommon.rpc.provider.ws_provider import WsProvider
ws_uri = "ws://127.0.0.1:28333/ws"
auth_header = <YOUR-AUTHORIZATION-HEADER>
while True:
try:
async with WsProvider(uri=ws_uri, headers={"Authorization": auth_header}) as ws:
subscription_id = await ws.subscribe("newTxs", {"include": ["tx_hash"]})
while True:
next_notification = await ws.get_next_subscription_notification_by_id(subscription_id)
print(next_notification) # or process it generally
except Exception as e:
print(f"Connection broken to feed, {str(e)}, retrying.")
await ws.unsubscribe(subscription_id)
const WebSocket = require('ws');
const ws = new WebSocket(
'ws://127.0.0.1:28333/ws',
{
headers: {
"Authorization" : <YOUR-AUTHORIZATION-HEADER>
},
}
);
function proceed() {
ws.send(`{"jsonrpc": "2.0", "id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"]}]}`);
}
function handle(nextNotification) {
console.log(nextNotification.toString()); // or process it generally
}
ws.on('open', proceed);
ws.on('message', handle);
package main
import (
"fmt"
"github.com/gorilla/websocket"
)
func main() {
dialer := websocket.DefaultDialer
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
}
subRequest := `{"id": 1, "method": "subscribe", "params": ["newTxs", {"include": ["tx_hash"]}]}`
err = wsSubscriber.WriteMessage(websocket.TextMessage, []byte(subRequest))
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
}
}
Transaction Event
# Examples for Professional and Enterprise plan:
# Type 0 legacy transaction:
<<< {
"jsonrpc":"2.0",
"id":null,
"method":"subscribe",
"params":{
"subscription":"414f2873-a7b0-451c-aefa-4e9280f25ce7",
"result":{
"txHash":"0x277...2ae",
"txContents":{
"from":"0xcfc...bf2",
"gas":"0x8caf",
"gasPrice":"0x8d8f9fc00",
"hash":"0x277...2ae",
"input":"0x2e1...000",
"nonce":"0x1eb",
"value":"0x0",
"v":"0x26",
"r":"0xbf7...742",
"s":"0x249...346",
"type":"0x0",
"to":"0xc02...cc2"
},
"localRegion":true
}
}
}
# Type 2 dynamic fee transaction:
<<< {
"jsonrpc":"2.0",
"id":null,
"method":"subscribe",
"params":{
"subscription":"414f2873-a7b0-451c-aefa-4e9280f25ce7",
"result":{
"txHash":"0x03...da0",
"txContents":{
"from":"0x001...9e8",
"gas":"0xd6d8",
"gasPrice":null,
"hash":"0x03...da0",
"input":"0x",
"nonce":"0x2e6c02",
"value":"0x8087c960bae00",
"v":"0x1",
"r":"0xc44...431",
"s":"0x4bd...858",
"type":"0x2",
"to":"0xdea...aac",
"chainId":"0x1",
"accessList":[],
"maxPriorityFeePerGas":"0x3b9aca00",
"maxFeePerGas":"0xba43b7400"
},
"localRegion":true
}
}
}
Last modified 3mo ago