SDK WebSockets Endpoints

How to use WebSockets with the Alchemy SDK

Available Subscription Types

Subscription TypeDescription
Alchemy Mined TransactionsEmits full transaction objects or hashes that are mined on the network based on provided filters and block tags.
Alchemy Pending TransactionsEmits full transaction objects or hashes that are sent to the network, marked as "pending", based on provided filters.
block (newHeads)Emits new blocks that are added to the blockchain.
transactionsEmitted when a specified transaction has been mined.
logsEmits logs attached to a new block that match certain topic filters.

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, AlchemySubscription } 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: AlchemySubscription.PENDING_TRANSACTIONS,
    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 Subscription 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.

Subscription MethodDescription
alchemy.ws.on( eventName , listener ) ⇒ thisAdd a listener to be triggered for each eventName event.
alchemy.ws.once( eventName , listener ) ⇒ thisAdd a listener to be triggered for only the next eventName event, at which time it will be removed.
alchemy.ws.emit( eventName , ...args ) ⇒ booleanNotify all listeners of the eventName event, passing args to each listener. This is generally only used internally.
alchemy.ws.off( eventName [ , listener ] ) ⇒ thisRemove a listener for the eventName event. If no listener is provided, all listeners for eventName are removed.
alchemy.ws.removeAllListeners( [ eventName ] ) ⇒ thisRemove all the listeners for the eventName events. If no eventName is provided, all events are removed.
alchemy.ws.listenerCount( [ eventName ] ) ⇒ numberReturns 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.

SDK Subscription Types Support by Chain

ChainMined TransactionsPending Transactionstransactionsblock (newHeads)logs
Ethereum:x::white-check-mark::white-check-mark::white-check-mark::white-check-mark:
Polygon:x::white-check-mark::white-check-mark::white-check-mark::white-check-mark:
Arbitrum:x::x::x::white-check-mark::white-check-mark:
Optimism:x::x::x::white-check-mark::white-check-mark:
Polygon zkEVM:x::x::x::x::x:

Alchemy SDK's Subscription 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)
);

AlchemySubscription.MINED_TRANSACTIONS

Emitted when a transaction is confirmed onto the blockchain. 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, AlchemySubscription } from "alchemy-sdk";
const alchemy = new Alchemy();

// Subscription for Alchemy's Mined Transactions  API
alchemy.ws.on(
  {
    method: AlchemySubscription.MINED_TRANSACTIONS,
    addresses: [
      {
        from: "0x473780deaf4a2ac070bbba936b0cdefe7f267dfc",
        to: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      },
      {
        to: "0x473780deaf4a2ac070bbba936b0cdefe7f267dfc",
      },
    ],
    includeRemoved: true,
    hashesOnly: false,
  },
  (tx) => console.log(tx)
);

AlchemySubscription.PENDING_TRANSACTIONS

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.

📘

Migrating from Web3.js or Ethers.js

If you were previously using the newPendingTransactions method on either Web3.js or Ethers.js, you should use alchemy_pendingTransactions. It's a strict superset of the functionality of newPendingTransactions, and functions identically if you don't pass in a fromAddress or toAddress filter.

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

// Subscription for Alchemy's pendingTransactions API
alchemy.ws.on(
  {
    method: AlchemySubscription.PENDING_TRANSACTIONS,
    toAddress: "vitalik.eth",
    fromAddress: "vitalik.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 CodeError MessageSolution
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

ReadMe