eth_subscribe

Astar API - Subscribe to different event types like newHeads and logs using websockets.

Creates a new subscription for desired events. Sends data as soon as it occurs.

🚧

A note on limits over 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.

Parameters

  • Event types- specifies the type of event to listen to (ex: new pending transactions, logs, etc.)
  • Optional params - optional parameters to include to describe the type of event to listen to (ex: address)

Returns

While the subscription is active, you will receive events formatted as an object described below:

  • Event Object:
    • jsonrpc: Always "2.0"
    • method: Always "eth_subscription"
    • params: An object with the following fields:
      • subscription: The subscription ID returned by the eth_subscribe call which created this subscription. This ID will be attached to all received events and can also be used to cancel the subscription using eth_unsubscribe
      • result: An object whose contents vary depending on the event type.

Event types

The following event types are accepted in all eth_subscribe WebSocket requests through your Alchemy endpoint.

Event Types

Description

newHeads

Emits new blocks that are added to the blockchain.

logs

Emits logs attached to a new block that match certain topic filters.

newHeads ("block")

Emits an event any time a new header (block) is added to the chain, including during a chain reorganization.

📘

NOTE: Chain Reorganizations (ReOrgs)

When a chain reorganization occurs, this subscription will emit an event containing all new headers (blocks) for the new chain. This means that you may see multiple headers emitted with the same height, and when this happens the later header should be taken as the correct one after a reorganization.

Parameters

  • None

Request

// initiate websocket stream first
wscat -c wss://astar-mainnet.g.alchemy.com/v2/demo

// then call subscription 
{"jsonrpc":"2.0","id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
// Installation: npm install alchemy-sdk
import { Alchemy, Network } from "alchemy-sdk";

const settings = {
  apiKey: "demo", // Replace with your Alchemy API Key.
  network: Network.ASTAR_MAINNET, // Replace with your network.
};
const alchemy = new Alchemy(settings);

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

Result

{"jsonrpc":"2.0", "id":1, "result":"0x9ce59a13059e417087c02d3236a0b1cc"}

{
   "jsonrpc": "2.0",
   "method": "eth_subscription",
   "params": {
     "result": {
       "difficulty": "0x15d9223a23aa",
       "extraData": "0xd983010305844765746887676f312e342e328777696e646f7773",
       "gasLimit": "0x47e7c4",
       "gasUsed": "0x38658",
       "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
       "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
       "nonce": "0x084149998194cc5f",
       "number": "0x1348c9",
       "parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701",
       "receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36",
       "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
       "stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378",
       "timestamp": "0x56ffeff8",
       "transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f"
     },
   "subscription": "0x9ce59a13059e417087c02d3236a0b1cc"
   }
 }

logs

Emits logs that are part of newly added blocks that match specified filter criteria.

📘

NOTE: Chain Reorganizations (ReOrgs)

When a chain reorganization occurs, logs that are part of blocks on the old chain will be emitted again with the property removed set to true.

Logs that are part of the blocks on the new chain are also emitted, it is possible to see logs for the same transaction multiple times in the case of a reorganization.

Parameters

An object with the following fields:

  • address (optional): [string] or [array of strings] Singular address or array of addresses.
    • Only logs created from one of these addresses will be emitted.
  • topics: an array of topic specifiers.
    • Each topic specifier is either null, a single string, or an array of strings.
    • For every non null topic, a log will be emitted when activity associated with that topic occurs.

📘

Topic Specifications:

  • []: Any topics allowed.
  • [A]: A in first position (and anything after).
  • [null, B]: Anything in first position and B in second position (and anything after).
  • [A, B]: A in first position and B in second position (and anything after).
  • [[A, B], [A, B]]: (A or B) in first position and (A or B) in second position (and anything after).

To learn more about how log topics work, check out this page.

Request

// initiate websocket stream first
wscat -c wss://astar-mainnet.g.alchemy.com/v2/demo

// then call subscription 
{"jsonrpc":"2.0","id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}
import { Alchemy, Network } from "alchemy-sdk";
import { ethers } from "ethers";

const settings = {
  apiKey: "demo", // Replace with your Alchemy API Key.
  network: Network.ASTAR_MAINNET, // Replace with your network.
};
const alchemy = new Alchemy(settings);

// 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: [ethers.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 = [
  ethers.utils.id("Transfer(address,address,uint256)"),
  null,
  [address1, address2],
];

alchemy.ws.on(topicSets, (log, event) => {
  // Emitted any token is sent TO either address
});

Result

{
    "jsonrpc":"2.0",
    "id":1,
    "result":"0x4a8a4c0517381924f9838102c5a4dcb7"
}

{
    "jsonrpc":"2.0",
    "method":"eth_subscription",
    "params": {
        "subscription":"0x4a8a4c0517381924f9838102c5a4dcb7",
        "result":{
            "address":"0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",
            "blockHash":"0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04",
            "blockNumber":"0x29e87",
            "data":"0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003",
            "logIndex":"0x0",
            "topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],
            "transactionHash":"0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4",
            "transactionIndex":"0x0"
        }
    }
}