This EIP extends the existing eth_subscribe JSON-RPC method with a new subscription type transactionInclusion that enables clients to receive real-time notifications when transactions are included in blocks. This subscription-based approach provides efficient transaction confirmation monitoring without blocking connections, supporting both combined transaction submission and monitoring in a single call, as well as monitoring of already-submitted transactions.
Current transaction submission workflows require separate calls to eth_sendRawTransaction followed by repeated polling of eth_getTransactionReceipt, creating unnecessary latency and network overhead. While EIP-7966 proposes eth_sendRawTransactionSync to address this through a synchronous blocking approach, blocking HTTP connections presents significant drawbacks:
The subscription-based approach leverages the battle-tested eth_subscribe mechanism already implemented across all major Ethereum clients, providing superior resource efficiency and scalability while maintaining feature parity with synchronous approaches.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
A new subscription type transactionInclusion is added to the eth_subscribe method.
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_subscribe",
"params": ["transactionInclusion", {
"transaction": "0x...",
"includeReorgs": false
}]
}
Or for monitoring an already-submitted transaction:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_subscribe",
"params": ["transactionInclusion", {
"hash": "0x...",
"includeReorgs": false
}]
}
The subscription parameters object accepts the following fields:
transaction (DATA, optional): Signed transaction data to submit and monitor. When provided, the node MUST immediately submit this transaction to the network.hash (DATA, 32 bytes, optional): Transaction hash to monitor for already-submitted transactions.includeReorgs (boolean, optional, default: false): Controls reorg monitoring behavior.false: Subscription auto-unsubscribes immediately after first inclusion notification. Reorgs are not monitored.true: Subscription actively monitors for reorgs and sends notifications for reorgs, re-inclusions, and finalization.Exactly one of transaction or hash MUST be provided. If both or neither are provided, the node MUST return a JSON-RPC error with code -32602 (Invalid params).
Upon successful subscription, the node MUST return a subscription ID:
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x1234567890abcdef"
}
When the transaction status changes, the node MUST send a notification:
{
"jsonrpc": "2.0",
"method": "eth_subscription",
"params": {
"subscription": "0x1234567890abcdef",
"result": {
"status": "included",
"blockHash": "0x...",
"blockNumber": "0x...",
"transactionIndex": "0x...",
"receipt": {
"transactionHash": "0x...",
"transactionIndex": "0x...",
"blockHash": "0x...",
"blockNumber": "0x...",
"from": "0x...",
"to": "0x...",
"cumulativeGasUsed": "0x...",
"gasUsed": "0x...",
"contractAddress": null,
"logs": [],
"logsBloom": "0x...",
"status": "0x1"
}
}
}
}
The status field MAY be one of:
"included": Transaction has been included in a block"finalized": Transaction's block has reached finality (only sent when includeReorgs is false)"reorged": Transaction was removed from the canonical chain (only sent if includeReorgs is true)The receipt field MUST contain the complete transaction receipt object as defined by eth_getTransactionReceipt.
The node MUST implement the following behavior:
transaction is provided:eth_sendRawTransactionIf submission fails, the node MUST return a JSON-RPC error and MUST NOT create the subscription
Transaction Already Included:
If the monitored transaction is already included in a block at subscription time:
includeReorgs is false: The node MUST immediately send an inclusion notification and automatically unsubscribeincludeReorgs is true: The node MUST immediately send an inclusion notification and continue monitoring until finalizationPending Transaction:
includeReorgs is false, the node MUST then automatically unsubscribeIf includeReorgs is true, the node MUST continue monitoring
Reorg Monitoring (when includeReorgs is true):
"status": "reorged""status": "included""status": "finalized"The node MUST automatically unsubscribe after sending the finalization notification
Auto-unsubscribe:
includeReorgs is false, the node MUST automatically unsubscribe after sending the first inclusion notificationThe node SHOULD send an eth_subscription unsubscribe confirmation
Transaction Not Found:
txHash that doesn't exist in the mempool or chain, the subscription remains activeSubscriptions provide several advantages over the synchronous approach proposed in EIP-7966:
eth_subscribe implementation present in all major clientsThe addition of the transaction parameter provides complete feature parity with eth_sendRawTransactionSync by enabling submission and monitoring in a single call.
eth_subscribe?The eth_subscribe mechanism is battle-tested and already implemented across all major Ethereum clients. Extending it with a new subscription type requires minimal implementation effort compared to introducing entirely new RPC methods.
transaction and hash?Supporting both parameters provides maximum flexibility:
transaction: Optimal for new transactions, matching the convenience of synchronous methodshash: Enables monitoring of transactions submitted through other means or by other partiesApplications requiring high confidence in transaction finality benefit from reorg notifications. This is particularly important on chains with faster block times where reorgs may be more common. The optional nature of this feature allows applications to choose the appropriate trade-off between functionality and resource usage.
A single WebSocket connection can support unlimited concurrent transaction subscriptions, whereas synchronous approaches require one blocking HTTP connection per transaction. This represents a significant improvement in resource utilization for applications monitoring multiple transactions.
Both modes auto-unsubscribe to prevent unbounded subscription accumulation and provide clear lifecycle management:
includeReorgs: false: Unsubscribes immediately after first inclusion for fast feedback with minimal resource usage. Users accepting this mode understand the transaction may still be reorged and can manually monitor if needed.includeReorgs: true: Unsubscribes after finalization when reorgs are no longer possible, providing complete transaction lifecycle monitoring.The key difference is the level of guarantee:
includeReorgs: false: Fast notification, transaction is included (may still reorg)includeReorgs: true: Complete lifecycle tracking until finality (cannot reorg)This EIP is fully backwards compatible. It extends the existing eth_subscribe method with a new subscription type. Clients that have not implemented this feature will return a standard JSON-RPC error indicating the subscription type is not supported. Existing applications continue to function unchanged.
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_subscribe",
"params": ["transactionInclusion", {
"transaction": "0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83"
}]
}
Expected Behavior:
"status": "included" and receiptRequest:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_subscribe",
"params": ["transactionInclusion", {
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"includeReorgs": false
}]
}
Expected Behavior:
"status": "included"Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_subscribe",
"params": ["transactionInclusion", {
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"includeReorgs": true
}]
}
Expected Behavior:
"status": "included")"status": "reorged")"status": "included")"status": "finalized")Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_subscribe",
"params": ["transactionInclusion", {
"includeReorgs": false
}]
}
Expected Response:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "Invalid params: exactly one of transaction or hash must be provided"
}
}
A minimal reference implementation can be realized by:
signedTransaction parameter: Call internal eth_sendRawTransaction logic and capture the transaction hashincludeReorgs is false, automatically unsubscribe after first inclusionincludeReorgs is true, continue monitoring for chain reorganizationsImplementation pseudo-code:
def handle_transaction_inclusion_subscription(params):
if 'transaction' in params:
tx_hash = submit_transaction(params['transaction'])
elif 'hash' in params:
tx_hash = params['hash']
else:
raise InvalidParamsError()
include_reorgs = params.get('includeReorgs', False)
subscription_id = generate_subscription_id()
register_subscription(subscription_id, tx_hash, include_reorgs)
return subscription_id
def on_block_added(block):
for tx in block.transactions:
subscriptions = get_subscriptions_for_tx(tx.hash)
for sub in subscriptions:
receipt = get_transaction_receipt(tx.hash)
send_notification(sub.id, 'included', receipt)
if not sub.include_reorgs:
unsubscribe(sub.id)
def on_chain_reorg(old_blocks, new_blocks):
removed_txs = get_transactions_from_blocks(old_blocks)
for tx_hash in removed_txs:
subscriptions = get_subscriptions_for_tx(tx_hash)
for sub in subscriptions:
if sub.include_reorgs:
send_notification(sub.id, 'reorged', None)
def on_block_finalized(block):
for tx in block.transactions:
subscriptions = get_subscriptions_for_tx(tx.hash)
for sub in subscriptions:
receipt = get_transaction_receipt(tx.hash)
send_notification(sub.id, 'finalized', receipt)
unsubscribe(sub.id)
When transaction is provided, nodes MUST perform the same validation as eth_sendRawTransaction before creating the subscription. Invalid transactions MUST result in an error response without creating a subscription.
Monitoring transactions by hash does not introduce new privacy concerns beyond existing eth_getTransactionReceipt polling. However, applications should be aware that subscribing to transaction hashes reveals interest in those transactions to the node operator.
Applications using includeReorgs: true should implement appropriate logic to handle reorg notifications, particularly on chains where reorgs may be used maliciously. The notification mechanism provides transparency but does not prevent reorg-based attacks.
Copyright and related rights waived via CC0.