Last active
June 23, 2022 16:39
-
-
Save uF4No/18c601881f60c28a9a69150ab17a081b to your computer and use it in GitHub Desktop.
Simulates how to control websocket errors connecting to a blockchain node
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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