Skip to content

Instantly share code, notes, and snippets.

@uF4No
Last active June 23, 2022 16:39
Show Gist options
  • Save uF4No/18c601881f60c28a9a69150ab17a081b to your computer and use it in GitHub Desktop.
Save uF4No/18c601881f60c28a9a69150ab17a081b to your computer and use it in GitHub Desktop.
Simulates how to control websocket errors connecting to a blockchain node
var Web3 = require('web3')
const ABI = [
{
constant: true,
inputs: [],
name: 'name',
outputs: [
{
name: '',
type: 'string',
},
],
payable: false,
stateMutability: 'view',
type: 'function',
},
{
constant: false,
inputs: [
{
name: '_spender',
type: 'address',
},
{
name: '_value',
type: 'uint256',
},
],
name: 'approve',
outputs: [
{
name: '',
type: 'bool',
},
],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
},
{
constant: true,
inputs: [],
name: 'totalSupply',
outputs: [
{
name: '',
type: 'uint256',
},
],
payable: false,
stateMutability: 'view',
type: 'function',
},
{
constant: false,
inputs: [
{
name: '_from',
type: 'address',
},
{
name: '_to',
type: 'address',
},
{
name: '_value',
type: 'uint256',
},
],
name: 'transferFrom',
outputs: [
{
name: '',
type: 'bool',
},
],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
},
{
constant: true,
inputs: [],
name: 'decimals',
outputs: [
{
name: '',
type: 'uint8',
},
],
payable: false,
stateMutability: 'view',
type: 'function',
},
{
constant: true,
inputs: [
{
name: '_owner',
type: 'address',
},
],
name: 'balanceOf',
outputs: [
{
name: 'balance',
type: 'uint256',
},
],
payable: false,
stateMutability: 'view',
type: 'function',
},
{
constant: true,
inputs: [],
name: 'symbol',
outputs: [
{
name: '',
type: 'string',
},
],
payable: false,
stateMutability: 'view',
type: 'function',
},
{
constant: false,
inputs: [
{
name: '_to',
type: 'address',
},
{
name: '_value',
type: 'uint256',
},
],
name: 'transfer',
outputs: [
{
name: '',
type: 'bool',
},
],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
},
{
constant: true,
inputs: [
{
name: '_owner',
type: 'address',
},
{
name: '_spender',
type: 'address',
},
],
name: 'allowance',
outputs: [
{
name: '',
type: 'uint256',
},
],
payable: false,
stateMutability: 'view',
type: 'function',
},
{
payable: true,
stateMutability: 'payable',
type: 'fallback',
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'owner',
type: 'address',
},
{
indexed: true,
name: 'spender',
type: 'address',
},
{
indexed: false,
name: 'value',
type: 'uint256',
},
],
name: 'Approval',
type: 'event',
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'from',
type: 'address',
},
{
indexed: true,
name: 'to',
type: 'address',
},
{
indexed: false,
name: 'value',
type: 'uint256',
},
],
name: 'Transfer',
type: 'event',
},
]
// Polygon USDC
const tokenAddress = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174'
// declared here to reconnect
let provider, web3
let endpointIndex = 0
let counter = 0
const endpoints = [
// invalid
'wss://chainstack.com/12345',
// valid Polygon endpoint
'wss://YOUR_WSS_RPC_ENDPOINT/123456',
// Polygon backup
'wss://ws-matic-mainnet.chainstacklabs.com',
]
const options = {
reconnect: {
auto: true,
delay: 1000,
maxAttempts: 2,
onTimeout: false,
},
}
const reconnect = () => {
if (endpointIndex < endpoints.length - 1) {
endpointIndex++
} else {
endpointIndex = 0
}
console.log('Connecting to >>> ', endpoints[endpointIndex])
// refresh provider
provider = new Web3.providers.WebsocketProvider(
endpoints[endpointIndex],
options
)
web3.setProvider(provider)
initListeners()
}
const checkActive = async () => {
console.log('counter', counter)
console.log('checking status on >> ', new Date())
console.log('URL >>> ', web3.currentProvider.url)
console.log(`Provider connected >>> `, web3.currentProvider.connected)
console.log(`Provider reconnecting >>> `, web3.currentProvider.reconnecting)
}
const initListeners = () => {
console.log('Initialising listenres....')
const contract = new web3.eth.Contract(ABI, tokenAddress)
const listenerOptions = {
// filter: {
// value: ['1000', '1337'], //Only get events where transfer value was 1000 or 1337
// },
// fromBlock: 0, //Number || "earliest" || "pending" || "latest"
// toBlock: 'latest',
}
contract.events
.Transfer({ listenerOptions })
.on('data', (evt) => {
console.log('Transfer event detected ')
counter++
// You could save the current block in state to resume from it
// after reconnecting using the listenerOptions filter
})
.on('error', (error) => {
console.error('ERROR: >> ', error.message)
console.error('Error with provider >> ', web3.currentProvider.url)
// takes care of reconnecting to next endpoint
reconnect()
})
}
// First connection
provider = new Web3.providers.WebsocketProvider(
endpoints[endpointIndex],
options
)
web3 = new Web3(provider)
// start listeners
initListeners()
// check status every 2 seconds
setInterval(checkActive, 2000)
// changes provider every 8secs to mess things up
setInterval(() => {
console.log(`🎲🎲🎲🎲🎲 CHANGING PROVIDER.....🎲🎲🎲🎲🎲`)
reconnect()
}, 8000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment