# eth_getTransactionCount - Optimism RPC Method

Returns the number of transactions sent from an address on Optimism, commonly known as the **nonce**. The nonce is required for every outbound transaction to ensure correct ordering and prevent replay attacks.

> **Why Optimism?** Build on the heart of the Superchain powering 60%+ of Ethereum L2 transactions with $6B+ TVL with OP Stack modularity, Superchain interoperability, 17M+ daily transactions across 33 chains, and 20% of tokens for public goods.

## When to Use This Method

`eth_getTransactionCount` is essential for L2 builders, DeFi developers, and teams launching Superchain-compatible apps:

- **Transaction Signing** - Get the correct nonce before building and signing a new transaction on Optimism
- **Nonce Gap Detection** - Compare `latest` and `pending` nonces to identify stuck or dropped transactions in the mempool
- **Account Activity Analysis** - Track the total number of outgoing transactions from any address on cross-chain DeFi, Superchain-interoperable dApps, and public goods funding recipients
- **Batch Transaction Sequencing** - Assign sequential nonces when submitting multiple transactions from the same address

## Request Parameters

- `address` (`DATA (20 bytes), required`): The address to query the transaction count for
- `blockParameter` (`QUANTITY|TAG, required`): Block number as hex, or tag: latest (confirmed nonce), pending (includes mempool txs), earliest

## Request Example

```json
{
  "jsonrpc": "2.0",
  "method": "eth_getTransactionCount",
  "params": [
    "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    "latest"
  ],
  "id": 1
}
```

## Response Fields

- `result` (`QUANTITY, required`): Hexadecimal string representing the number of transactions sent from the address

## Successful Response

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x1a"
}
```

## Error Responses

### Error Response

- Code: `-32602`

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Invalid params: invalid address"
  }
}
```

## Code Examples

cURL
JavaScript
Python
Go

```bash
curl -X POST https://api-optimism-mainnet-archive.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_getTransactionCount",
    "params": [
      "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "latest"
    ],
    "id": 1
  }'
```

```javascript
// Using fetch
const response = await fetch('https://api-optimism-mainnet-archive.n.dwellir.com/YOUR_API_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    method: 'eth_getTransactionCount',
    params: ['0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 'latest'],
    id: 1
  })
});

const { result } = await response.json();
const nonce = parseInt(result, 16);
console.log('Optimism nonce:', nonce);

// Using ethers.js
import { JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://api-optimism-mainnet-archive.n.dwellir.com/YOUR_API_KEY');
const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045';

const nonce = await provider.getTransactionCount(address);
console.log('Confirmed nonce:', nonce);

// Get pending nonce for new transaction
const pendingNonce = await provider.getTransactionCount(address, 'pending');
console.log('Next nonce:', pendingNonce);
```

```python
import requests

def get_transaction_count(address, block='latest'):
    response = requests.post(
        'https://api-optimism-mainnet-archive.n.dwellir.com/YOUR_API_KEY',
        json={
            'jsonrpc': '2.0',
            'method': 'eth_getTransactionCount',
            'params': [address, block],
            'id': 1
        }
    )
    result = response.json()['result']
    return int(result, 16)

address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
nonce = get_transaction_count(address)
print(f'Optimism nonce: {nonce}')

pending_nonce = get_transaction_count(address, 'pending')
print(f'Pending nonce: {pending_nonce}')

# Using web3.py
from web3 import Web3

w3 = Web3(Web3.HTTPProvider('https://api-optimism-mainnet-archive.n.dwellir.com/YOUR_API_KEY'))
nonce = w3.eth.get_transaction_count(address)
print(f'Nonce: {nonce}')

pending = w3.eth.get_transaction_count(address, 'pending')
print(f'Pending nonce: {pending}')
```

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
    client, err := ethclient.Dial("https://api-optimism-mainnet-archive.n.dwellir.com/YOUR_API_KEY")
    if err != nil {
        log.Fatal(err)
    }

    address := common.HexToAddress("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")

    // Get confirmed nonce
    nonce, err := client.NonceAt(context.Background(), address, nil)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Optimism nonce: %d\n", nonce)

    // Get pending nonce for new transaction
    pendingNonce, err := client.PendingNonceAt(context.Background(), address)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Pending nonce: %d\n", pendingNonce)
}
```

## Common Use Cases

### 1. Safe Transaction Sender with Nonce Management

Build a transaction sender that handles nonces correctly on Optimism:

```javascript
import { JsonRpcProvider, Wallet, parseEther } from 'ethers';

const provider = new JsonRpcProvider('https://api-optimism-mainnet-archive.n.dwellir.com/YOUR_API_KEY');

class TransactionSender {
  constructor(privateKey) {
    this.wallet = new Wallet(privateKey, provider);
    this.localNonce = null;
  }

  async getNextNonce() {
    // Get the pending nonce from the network
    const pendingNonce = await provider.getTransactionCount(
      this.wallet.address, 'pending'
    );

    // Use whichever is higher: local tracker or network pending
    if (this.localNonce === null || pendingNonce > this.localNonce) {
      this.localNonce = pendingNonce;
    }

    const nonce = this.localNonce;
    this.localNonce++;
    return nonce;
  }

  async sendTransaction(to, valueEth) {
    const nonce = await this.getNextNonce();

    const tx = await this.wallet.sendTransaction({
      to,
      value: parseEther(valueEth),
      nonce
    });

    console.log(`Sent tx ${tx.hash} with nonce ${nonce}`);
    return tx;
  }

  // Reset local nonce tracker (e.g., after errors)
  resetNonce() {
    this.localNonce = null;
  }
}
```

### 2. Stuck Transaction Detector

Detect and report stuck transactions by comparing nonces:

```javascript
async function detectStuckTransactions(provider, address) {
  const confirmedNonce = await provider.getTransactionCount(address, 'latest');
  const pendingNonce = await provider.getTransactionCount(address, 'pending');

  const pendingCount = pendingNonce - confirmedNonce;

  if (pendingCount === 0) {
    console.log('No pending transactions');
    return { status: 'clear', pendingCount: 0 };
  }

  console.log(`${pendingCount} pending transaction(s) detected`);
  console.log(`Confirmed nonce: ${confirmedNonce}`);
  console.log(`Pending nonce: ${pendingNonce}`);
  console.log(`Stuck nonces: ${confirmedNonce} to ${pendingNonce - 1}`);

  return {
    status: 'stuck',
    pendingCount,
    confirmedNonce,
    pendingNonce,
    stuckNonces: Array.from(
      { length: pendingCount },
      (_, i) => confirmedNonce + i
    )
  };
}

// Usage
const result = await detectStuckTransactions(provider, '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');
if (result.status === 'stuck') {
  console.log('Consider replacing transactions at nonces:', result.stuckNonces);
}
```

### 3. Batch Transaction Submitter

Submit multiple transactions in sequence with correct nonce ordering:

```javascript
async function sendBatchTransactions(wallet, transactions) {
  const startNonce = await provider.getTransactionCount(
    wallet.address, 'pending'
  );

  console.log(`Sending ${transactions.length} transactions starting at nonce ${startNonce}`);

  const receipts = [];
  for (let i = 0; i < transactions.length; i++) {
    const nonce = startNonce + i;
    const tx = await wallet.sendTransaction({
      ...transactions[i],
      nonce
    });

    console.log(`Tx ${i + 1}/${transactions.length} sent: ${tx.hash} (nonce: ${nonce})`);
    receipts.push(tx);
  }

  // Wait for all to confirm
  const confirmed = await Promise.all(
    receipts.map(tx => tx.wait())
  );

  console.log(`All ${confirmed.length} transactions confirmed`);
  return confirmed;
}

// Usage
const transactions = [
  { to: '0xRecipient1...', value: parseEther('0.1') },
  { to: '0xRecipient2...', value: parseEther('0.2') },
  { to: '0xRecipient3...', value: parseEther('0.05') }
];

await sendBatchTransactions(wallet, transactions);
```

## Best Practices

- Always use `pending` block tag when fetching the nonce for a new transaction to avoid nonce collisions
- Track nonces locally with a monotonic counter that syncs with the pending nonce from the network on reset
- If `pending` nonce equals `latest` nonce, no stuck transactions exist -- the account is clean
- For high-throughput applications (multiple transactions per second), implement a local nonce manager with retry logic
- The nonce starts at 0 for new accounts and increments by 1 for each confirmed outbound transaction

## Related Methods

- [`eth_sendRawTransaction`](https://www.dwellir.com/docs/optimism/eth_sendRawTransaction) - Send a signed transaction to the network
- [`eth_getBalance`](https://www.dwellir.com/docs/optimism/eth_getBalance) - Get the ETH balance of an address
- [`eth_getTransactionByHash`](https://www.dwellir.com/docs/optimism/eth_getTransactionByHash) - Get transaction details by hash
- [`eth_getTransactionReceipt`](https://www.dwellir.com/docs/optimism/eth_getTransactionReceipt) - Get the receipt of a confirmed transaction
