Skip to content

Conversation

10gic
Copy link

@10gic 10gic commented Sep 21, 2025

Currently, we can get transaction receipts from the HTTP API eth_getTransactionReceipt. In this PR, I add support for getting transaction receipts from the WebSocket API: Add a new subscription_name: transactionReceipts, which accepts an optional transaction hashes filter.

Why is this PR valuable?

  1. It provides users with faster access to transaction receipts than the HTTP API.
  2. It saves many HTTP RPC calls. Some libraries, for example waitForTransactionReceipt, need to monitor transaction and must use polling, which wastes a lot of RPC calls.

Usage:
Subscribe to a transaction receipt by transaction hash (multiple transaction hashes are also supported):

# Subscribe (WebSocket client --> WebSocket server):
{
	"jsonrpc": "2.0",
	"id": 1,
	"method": "eth_subscribe",
	"params": ["transactionReceipts", {
		"transactionHashes": [
			"0xffc4978dfe7ab496f0158ae8916adae6ffd0c1fca4f09f7a7134556011357424"
		]
	}]
}

# Notification (WebSocket server --> WebSocket client):
# Data format is the same as eth_getTransactionReceipt
{
    "jsonrpc": "2.0",
    "method": "eth_subscription",
    "params": {
        "subscription": "0xf9a92ce3f834c5f23100f4a9f6b8ddaf",
        "result": [
            {
                "blockHash": "0x53a6208ec0efcc8de6380eedc8c34f8dda0fc8156de94281f5539576e929b1be",
                "blockNumber": "0x2",
                "contractAddress": null,
                "cumulativeGasUsed": "0x5208",
                "effectiveGasPrice": "0x3b9aca00",
                "from": "0x71562b71999873db5b286df957af199ec94617f7",
                "gasUsed": "0x5208",
                "logs": [],
                "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
                "status": "0x1",
                "to": "0x71562b71999873db5b286df957af199ec94617f7",
                "transactionHash": "0xffc4978dfe7ab496f0158ae8916adae6ffd0c1fca4f09f7a7134556011357424",
                "transactionIndex": "0x0",
                "type": "0x0"
            }
        ]
    }
}

Subscribe to all transaction receipts:

# Subscribe (WebSocket client --> WebSocket server):
{
	"jsonrpc": "2.0",
	"id": 1,
	"method": "eth_subscribe",
	"params": ["transactionReceipts"]
}

# Notification (WebSocket server --> WebSocket client):
# Data format is the same as eth_getTransactionReceipt
{
    "jsonrpc": "2.0",
    "method": "eth_subscription",
    "params": {
        "subscription": "0x9374a0f623d50dd1477b4a3e25fc3b76",
        "result": [
            {
                "blockHash": "0x9fd9d918653b8b40406df7d230e3a3ab80bcc24da2bb5411c1f64aaa0d3546af",
                "blockNumber": "0x4",
                "contractAddress": null,
                "cumulativeGasUsed": "0x5208",
                "effectiveGasPrice": "0x3b9aca00",
                "from": "0x71562b71999873db5b286df957af199ec94617f7",
                "gasUsed": "0x5208",
                "logs": [],
                "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
                "status": "0x1",
                "to": "0x71562b71999873db5b286df957af199ec94617f7",
                "transactionHash": "0x9687a6a6805ada78575b8485d9ce2afdf4483ce51745f352fabeaf723c1e5e08",
                "transactionIndex": "0x0",
                "type": "0x0"
            },
            ......
        ]
    }
}

As mentioned in the above example, filtering is not performed when no second parameter is provided. The following describes three additional special cases where no filtering is performed:

  1. The transactionHashes field in the second parameter is set to null;
  2. The transactionHashes field in the second parameter is set to [] (empty array);
  3. The second parameter is {} (empty object).

All of the above are treated as subscribing to all transaction receipts:

# Setting `transactionHashes` field to `null` also means no filter
{
	"jsonrpc": "2.0",
	"id": 1,
	"method": "eth_subscribe",
	"params": ["transactionReceipts", {
		"transactionHashes": null
	}]
}

# Setting `transactionHashes` field to `[]` also means no filter
{
	"jsonrpc": "2.0",
	"id": 1,
	"method": "eth_subscribe",
	"params": ["transactionReceipts", {
		"transactionHashes": []
	}]
}

# Setting the second parameter to `{}` also means no filter
{
	"jsonrpc": "2.0",
	"id": 1,
	"method": "eth_subscribe",
	"params": ["transactionReceipts", {}]
}

I noticed that all HTTP APIs have been standardized in the execution-apis project, but WebSocket APIs are not included in that project. In this PR, I only enhance the WebSocket API - no HTTP APIs are changed.

@s1na
Copy link
Contributor

s1na commented Sep 23, 2025

Hey thanks for this, I think it's a fair request. I will have a look

@10gic
Copy link
Author

10gic commented Sep 29, 2025

Hi @s1na, hope you're doing well. When you have a chance, could you take a look at this PR? Any feedback would be great. Thanks!

@s1na
Copy link
Contributor

s1na commented Sep 29, 2025

Pushed a commit to avoid an extra db read of the receipts in SetCanonical

@10gic
Copy link
Author

10gic commented Sep 30, 2025

Pushed a commit to avoid an extra db read of the receipts in SetCanonical

You're very thorough, thank you for the commit.

@10gic
Copy link
Author

10gic commented Oct 1, 2025

Hi @s1na, just following up to see if you have any additional feedback on this PR? Happy to make any other changes if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants