Skip to content

Draft proposal: wallet_getTransactionCountIncludingQueued#64

Open
cds-amal wants to merge 2 commits into
MetaMask:mainfrom
cds-io:wallet_queued
Open

Draft proposal: wallet_getTransactionCountIncludingQueued#64
cds-amal wants to merge 2 commits into
MetaMask:mainfrom
cds-io:wallet_queued

Conversation

@cds-amal
Copy link
Copy Markdown

@cds-amal cds-amal commented Nov 26, 2025

Summary

Propose a new JSON-RPC method wallet_getTransactionCountIncludingQueued that returns the next available nonce including transactions pending locally in MetaMask.

Motivation

eth_getTransactionCount("pending") queries the node but doesn't include transactions that are queued locally in MetaMask. This breaks rapid sequential transaction submission - by the time a dApp queries for the next nonce, the previous transaction may not have propagated to the node yet, causing nonce collisions.

This affects orchestration tools (like https://txtx.sh) that submit multiple dependent transactions in sequence (e.g., deploy factory → deploy contracts → wire them together). Currently developers must implement their own NonceManager to work around this.

Historical context

MetaMask previously included local pending transactions in nonce queries (see nonce-tracker). This was
changed ~2019 on extension, and more recently on mobile according to Slack discussion with Mark Stacey and @davidmurdoch. A new method avoids breaking dApps that depend on current eth_getTransactionCount behavior.


Note

Adds a new MIP specifying wallet_getTransactionCountIncludingQueued to return the next nonce including locally queued MetaMask transactions.

  • MIP Added: MIPs/mip-x.md
    • Proposes wallet_getTransactionCountIncludingQueued to return the next available nonce including locally pending/queued transactions.
    • Specification:
      • Params: address (required).
      • Return: hex nonce = max(on_chain_pending_nonce, highest_local_pending_nonce + 1).
      • Errors: invalidParams for bad address; unauthorized if address not connected.
    • Usage: Example flow to predict CREATE addresses and submit dependent transactions using MetaMask.
    • Alternatives: Not modifying eth_getTransactionCount('pending'); reject new block tag; rationale for a wallet_-scoped method.
    • Implementation Notes: Expose internal nonce tracker; add RPC handler (extension/mobile); doc updates; pseudocode provided.
    • Adoption: Feature detection, fallback strategies, and race-condition handling guidance.
    • UX/Security: Clarifies wallet-local state scope, cross-dApp visibility, and read-only nature.

Written by Cursor Bugbot for commit 54ae5ce. This will update automatically on new commits. Configure here.

Comment thread MIPs/mip-x.md Outdated

## Summary

This proposal introduces a new JSON-RPC method `wallet_getTransactionCountIncludingQueued` that returns the next available nonce for an account, including transactions that are pending locally in MetaMask but not yet confirmed on-chain. This enables dApps to reliably submit multiple sequential transactions without waiting for each to be mined.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you elaborate on why the dapp would want to set the nonce in the first place? Usually the wallet will assign the nonce. We don't even accept the nonce as a parameter for eth_sendTransaction: https://docs.metamask.io/wallet/reference/json-rpc-methods/eth_sendtransaction/

Is this intended for dapps that are using eth_sendRawTransaction, and signing it themselves?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TXTX is a runbook orchestrator for blockchain deployments. Rather than asking users to hand over private keys to sign raw transactions, TXTX deliberately uses eth_sendTransaction to leverage MetaMask's security stack: transaction simulation, phishing detection, spend limits, and confirmation flows. They're building on MetaMask's battle-tested security, not bypassing it. This is one of the reasons my project, DIN, chose to use TXTX.

The use case is multi-step contract deployments where CREATE addresses must be predicted upfront:

  1. Deploy Factory (nonce N) -> predicted address: 0xABC
  2. Deploy Contract via Factory (nonce N+1) -> references 0xABC
  3. Initialize contracts (nonce N+2) -> wires them together

The backend computes 0xABC = keccak256(rlp(sender, N)) before transaction N confirms, so subsequent transactions can reference it. This requires knowing N precisely.

TXTX wants MetaMask to assign nonces; that's the point: trust MM's nonce tracker over naively rolling an independent one. But for this to work, there needs to be visibility into exactly what nonce MM will assign, so CREATE address predictions match reality.

Currently eth_getTransactionCount("pending") doesn't reflect MetaMask's local queue. After submitting tx N, querying for the next nonce still returns N until it propagates to the node, so the prediction for tx N+1's CREATE address is wrong.

wallet_getTransactionCountIncludingQueued would let us query "what nonce will MM assign next?", allowing TXTX to compose a safe UX with MetaMask.

Copy link
Copy Markdown
Member

@Gudahtt Gudahtt Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

multi-step contract deployments where CREATE addresses must be predicted upfront

Ahhh I see, that makes sense, this is the part I was missing.

It would be great if this was highlighted more clearly in the document. Most dapps don't have this requirement, which explains why we haven't seen a huge amount of demand for this feature.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could mention something about predicting contract deployment addresses?

It's already possible to safely "submit multiple transactions in rapid succession / as a batch" today, but not when one is a contract deployment that later transactions rely on I guess.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let me know if this was addressed @Gudahtt

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