SDK WebSockets Endpoints

What are WebSockets and how do they differ from HTTP?

WebSockets is a bidirectional communication protocol that maintains a network connection between a server and a client. Unlike HTTP, with WebSockets clients don't need to continuously make requests when they want information.

Instead, an open WebSocket connection can push network updates to clients by allowing them to subscribe to certain network states, such as new transactions or blocks being added to the blockchain.


Getting Started

The Alchemy SDK is the easiest way to start using WebSockets. It exposes WebSockets support via the Ethers.js syntax. In addition, it exposes an additional Enhanced APIs created by Alchemy.

See an example below:

// Setup: npm install alchemy-sdk
import { Alchemy } from "alchemy-sdk";

// Optional config object, but defaults to demo api-key and eth-mainnet.
const settings = {
  apiKey: "demo", // Replace with your Alchemy API Key.
  network: Network.ETH_MAINNET, // Replace with your network.
};

const alchemy = new Alchemy(settings);

// Subscription for new blocks on Eth Mainnet.
alchemy.ws.on("block", (blockNumber) =>
  console.log("The latest block number is", blockNumber)
);

// Subscription for Alchemy's pendingTransactions Enhanced API
alchemy.ws.on(
  {
    method: "alchemy_pendingTransactions",
    toAddress: "vitalik.eth",
  },
  (tx) => console.log(tx)
);

👍

Automatic Retries on the Alchemy SDK

The Alchemy SDK automatically adds retry handling for WebSocket failures with no configuration necessary.

Alchemy SDK's Subscription Methods

These are the methods that you can call to begin a subscription. For types of events you can subscribe to, see Alchemy SDK's Event Types.

The Alchemy SDK's WebSockets is built on top of Ethers.js's implementation of WebSockets, so the majority of the syntax will be identical.

alchemy.ws.on( eventName , listener ) ⇒ this

  • Add a listener to be triggered for each eventName event.

alchemy.ws.once( eventName , listener ) ⇒ this

  • Add a listener to be triggered for only the next eventName event, at which time it will be removed.

alchemy.ws.emit( eventName , ...args ) ⇒ boolean

  • Notify all listeners of the eventName event, passing args to each listener. This is generally only used internally.

alchemy.ws.off( eventName [ , listener ] ) ⇒ this

  • Remove a listener for the eventName event. If no listener is provided, all listeners for eventName are removed.

alchemy.ws.removeAllListeners( [ eventName ] ) ⇒ this

  • Remove all the listeners for the eventName events. If no eventName is provided, all events are removed.

alchemy.ws.listenerCount( [ eventName ] ) ⇒ number

  • Returns the number of listeners for the eventName events. If no eventName is provided, the total number of listeners is returned.

alchemy.ws.listeners( eventName ) ⇒ Array< Listener >

  • Returns the list of Listeners for the eventName events.

Alchemy SDK's Event Types

block (newHeads)

Emitted when a new block is mined.

import { Alchemy } from "alchemy-sdk";
const alchemy = new Alchemy();

// Subscribe to new blocks, or newHeads
alchemy.ws.on("block", (blockNumber) =>
  console.log("Latest block:", blockNumber)
);

pendingTransactions

Emitted when a new transaction enters the memory pool. Alchemy's custom implementation of this endpoint allows you to filter based on fromAddress or toAddress, the address a transaction was sent to or received from.

import { Alchemy } from "alchemy-sdk";
const alchemy = new Alchemy();

// Subscription for Alchemy's pendingTransactions API
alchemy.ws.on(
  {
    method: "alchemy_pendingTransactions",
    toAddress: "vitalik.eth",
    fromAddress: "0xshah.eth",
  },
  (tx) => console.log(tx)
);

transactions

Emitted when a specified transaction has been mined.

import { Alchemy } from "alchemy-sdk";
const alchemy = new Alchemy();

const txHash = "0xfc89ec10998a74c37a107535ca1cf8714edad409bff40d6da9e8a436cef6daad";

// Subscription for a specific transaction to be mined
alchemy.ws.on(
  txHash,
  (tx) => console.log(tx)
);

logs

A filter is an object, representing a contract log Filter, which has the optional properties address (the source contract) and topics (a topic-set to match).

If address is unspecified, the filter matches any contract address.

import { Alchemy } from "alchemy-sdk";
const alchemy = new Alchemy();

// This filter could also be generated with the Contract or
// Interface API. If address is not specified, any address
// matches and if topics is not specified, any log matches
const filter = {
  address: "dai.tokens.ethers.eth",
  topics: [
    utils.id("Transfer(address,address,uint256)")
  ]
}
alchemy.ws.on(filter, (log, event) => {
  // Emitted whenever a DAI token transfer occurs
})

// Notice this is an array of topic-sets and is identical to
// using a filter with no address (i.e. match any address)
const topicSets = [
  utils.id("Transfer(address,address,uint256)"),
  null,
  [
    hexZeroPad(myAddress, 32),
    hexZeroPad(myOtherAddress, 32)
  ]
]
alchemy.ws.on(topicSets, (log, event) => {
  // Emitted any token is sent TO either address
})

Subscription Type Support Per Chain

For the latest Alchemy support by chain for certain WebSockets requests, check our Feature Support By Chain article here.


WebSocket Limits

The following limits apply for WebSocket connections:

  • There is a limit of 20,000 WebSocket connections per API Key as well as 1,000 parallel WebSocket subscriptions per WebSocket connection, creating a maximum of 20 million subscriptions per application.
  • The maximum size of a JSON-RPC batch request that can be sent over a WebSocket connection is 20
  • Free tier users will be limited to 10 concurrent requests per WebSocket connection.

Error Codes

Error Code

Error Message

Solution

32600

"The maximum batch size that can be sent over a websocket connection is 10. Please decrease the batch size and try again."

Occurs when user attempts to send high-volume JSON-RPC traffic over Websockets. We recommend this traffic be sent over HTTP instead to optimize server backends.


Example Projects