Building Better dapps with Infura’s Polygon WebSocket

John Vester - Jun 21 '23 - - Dev Community

Article Image

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.

WebSockets vs HTTP

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:

  1. Using real-time updates to keep a count of digital assets/NFTs minted by a particular smart contract.

  2. Keeping track of gas prices as each new block is added to the network.

  3. Keeping track of token balances for a particular wallet.

  4. Monitoring the DeFi dapp market by tracking market trades, orders, and Best Bid Offers (BBO).

Infura’s Polygon WebSocket

So how do you use WebSockets? Let’s look at Infura’s Polygon WebSocket.

In the current release, two types of requests are supported:

  • Stateful Subscriptions over WebSockets (wscat -c wss://). These allow you to submit eth_subscribe requests which create bidirectional and real-time connections that can push data between the client and server. You can listen to specific events such as specific logs, pending transactions, and newheads.

  • Stateless WebSockets over HTTP (https://). These allow you to subscribe to events using HTTP connections — but you only get a single response, as it’s not a persistent connection.

Creating a Real-Time Wallet Transactions Tracker

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.

Step 1: Create an Infura API Key

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.

Image #4

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.

Image #1

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.

Step 2: Create a MetaMask Wallet

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.

Image #5

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.

Step 3: Install Python and PIP

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
Enter fullscreen mode Exit fullscreen mode

Step 4: Create a Python Project

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
Enter fullscreen mode Exit fullscreen mode

Open the repository in your favorite code editor (for example, VS Code). You should see a single file named main.py.

Step 5: Write the Tracker Script

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())
Enter fullscreen mode Exit fullscreen mode

This is pretty easy and straightforward code. But let’s go through the important pieces:

  • We define a web3 provider with the Mumbai HTTP URL. This provider will be used to get more information on the transaction we’re interested in (i.e those involving our wallet).

  • We create a WebSocket connection using the Mumbai WSS URL and subscribe to all pending transactions on the Polygon Mumbai network.

  • We retrieve from and to information for every transaction, and if it involves our wallet, we print the details of the transaction.

The rest is boilerplate code that we don’t really need to get into the details of.

Step 6: Track Pending Transaction

We’re all set! Let’s run this script using the following command:

python3 main.py
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode

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:

  1. Getting free MATIC to your wallet from a faucet.

  2. Sending MATIC to another wallet.

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
Enter fullscreen mode Exit fullscreen mode

For a sanity check, we can search for this hash on Mumbai Polygonscan.

Image #2

Conclusion

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!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .