Web3 dapps are often slow and clunky. But WebSockets on Ethereum L2s can help solve this problem by bringing real-time, bidirectional, client-server communications to the world of web3. 3rd party offerings (such as Infura’s WebSockets on Polygon) can help you create dynamic, low latency, next-gen dapps.
In this article we’ll look in detail at WebSockets — what they are, how they compare to traditional HTTP, and some use cases where they shine brightest. Finally we’ll write a script that uses Infura’s Polygon Websocket to get real-time updates of all pending transactions associated with our crypto wallet.
The majority of the web is powered by HTTP requests, but HTTP is a stateless protocol that only supports unidirectional communication and is non-persistent. They typically involve a client (an app or a browser) sending a request to a server, and the server sending a response in return.
These requests are sufficient for powering most of the web’s functionality. For example, displaying the latest contents of a page, publishing a comment, sending money, etc.
WebSockets, on the other hand, establishes a persistent connection between a client and a server and unlike HTTP where communication happens in turns, WebSockets enable agents to talk to each other bidirectionally and in real time.
As you can guess, WebSockets is the go-to technology for web applications such as online multiplayer gaming, collaborative tools like Figma and Miro, stock market and live streaming apps, and push notifications.
The use of WebSockets in the world of web3 and blockchain, however, has lagged. But they are needed! Using WebSockets in combination with the scalability of Ethereum L2s, you can build web3 applications that benefit from instant updates and continuous data streams.
Here are some use cases where WebSockets could be superior to traditional HTTP:
So how do you use WebSockets? Let’s look at Infura’s Polygon WebSocket.
In the current release, two types of requests are supported:
So let’s jump in and code an example! We’ll use Infura’s Polygon WebSocket support to create a script that will monitor real-time transactions on a wallet.
In order to get access to a Polygon WebSocket endpoint, we will need to create a free Infura account. Once you’ve created an account, you will be redirected to the main Infura dashboard. On the top right, click Create New API KEY.
For network, choose the default Web3 API. You can name the key anything you want.
Once you’ve created the key, you will be redirected to the project’s dashboard.
In the Endpoints tab, navigate down until you find Polygon, and click on Activate Add-On.
You’ll be redirected to a plans and billing page. The beginner tier, Core, is more than enough for this walkthrough.
In the Network Add-Ons section at the bottom, select Polygon PoS. This, like the core tier above, is free. You may be required to provide credit card details (though you won’t be charged) to complete this request.
Once you’ve checked out, navigate back to the Endpoints section of your project, and you should see a Websockets tab. This will now contain a WSS URL for both the Polygon mainnet and the testnet (called Mumbai). Take note of the Mumbai WSS URL. It should be of the form wss://polygon-mumbai.infura.io/ws/v3/<-YOUR API KEY->.
Next, navigate back to the HTTPS tab and take note of the Mumbai HTTP URL.
Now let’s create a wallet whose transactions we can track.
There are quite a few wallets available, but let’s stick with the most popular, MetaMask. You can install the MetaMask wallet as a free browser extension.
After installation, MetaMask will walk you through a series of steps to set up your wallet. Along the way you’ll be given a secret recovery phrase. Store this in a safe place (ideally, both digitally and physically) since if you lose it, you won’t be able to recover your wallet.
Once your wallet has been created, navigate to the top right of the extension window, and click the network drop-down. From here, toggle to Show Test Networks.
From the drop-down, select Polygon Mumbai. This is the network we will be dealing with for the rest of the tutorial.
If this is your first time using the Mumbai network, you will see a 0 MATIC balance. Don’t worry; adding crypto to your wallet is not required for this tutorial.
We’ll be building our tracker using Python 3. Download and install the required software for your local machine’s OS here.
Once it’s done, check that you have Python and pip correctly installed by getting their version numbers.
python3 –version
pip3 –version
With Python and pip installed on our machines, let’s create our project repository and install the necessary packages, namely web3 and websockets.
mkdir polygon-ws && cd polygon-ws
pip3 install web3 websockets
touch main.py
Open the repository in your favorite code editor (for example, VS Code). You should see a single file named main.py.
In the main.py
file, add the following code:
import asyncio
import json
import requests
from web3 import Web3
from websockets import connect
# Instantiate HTTP and WSS URLs
WSS_URL = '< INFURA WSS MUMBAI URL >'
HTTP_URL = '< INFURA HTTP MUMBAI URL >'
# Define a HTTP web3 provider
web3 = Web3(Web3.HTTPProvider(HTTP_URL))
# Wallet address you want to track transactions of
wallet = '< METAMASK WALLET ADDRESS >'
async def get_event():
async with connect(WSS_URL) as ws:
# Create a websocket connection
await ws.send('{"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}')
subscription_response = await ws.recv()
print("Created a new websocket connection:")
print(subscription_response)
while True:
try:
# Check for all pending transactions
message = await asyncio.wait_for(ws.recv(), timeout=15)
response = json.loads(message)
txHash = response['params']['result']
# Monitor transactions to a specific address
tx = web3.eth.get_transaction(txHash)
if tx["to"] == wallet or tx["from"] == wallet:
print("Pending transaction found with the following details:")
print("Txn Hash:", txHash)
pass
except:
pass
if __name__ == "__main__":
loop = asyncio.get_event_loop()
while True:
loop.run_until_complete(get_event())
This is pretty easy and straightforward code. But let’s go through the important pieces:
The rest is boilerplate code that we don’t really need to get into the details of.
We’re all set! Let’s run this script using the following command:
python3 main.py
If all goes well, you should see output that looks something like this:
Created a new websocket connection:
{"jsonrpc":"2.0","id":1,"result":"0xc68a169a0da44750b0f505a77f7bfd99"}
In the background, our script is using WebSockets to track all pending transactions. Let’s now initiate a transaction using our wallet and see if our script is notified.
We can do this in two ways:
For the former, you can use the faucet available here.
Once you trigger any of the above transactions, after a few seconds, you should see your script displaying details of the transaction … which means it worked!
Pending transaction found with the following details:
Txn Hash: 0x2e83edfba2fbbc8fc2753ab4675f10d204ff3b740ec47cb6c3a9b6f6dd4ebe95
For a sanity check, we can search for this hash on Mumbai Polygonscan.
Using WebSockets on Polygon provides a level of user experience on dapps that traditional HTTP API requests just can’t match. We’re just beginning to see the use cases this real-time, bidirectional communication enables. Try it out using Infura’s WebSockets and see what you can build!
Have a really great day!