Full Code of lmittmann/w3 for AI

main 856b989ac237 cached
263 files
76.8 MB
1.8M tokens
583 symbols
1 requests
Download .txt
Showing preview only (7,090K chars total). Download the full file or copy to clipboard to get everything.
Repository: lmittmann/w3
Branch: main
Commit: 856b989ac237
Files: 263
Total size: 76.8 MB

Directory structure:
gitextract_vxq391jt/

├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── doc.yml
│       └── go.yml
├── .gitignore
├── LICENSE
├── README.md
├── client.go
├── client_test.go
├── docs/
│   ├── components/
│   │   └── DocLink.jsx
│   ├── next.config.js
│   ├── package.json
│   ├── pages/
│   │   ├── 404.mdx
│   │   ├── _app.js
│   │   ├── _meta.js
│   │   ├── examples/
│   │   │   ├── _meta.js
│   │   │   └── index.mdx
│   │   ├── examples.mdx
│   │   ├── helper-abi.mdx
│   │   ├── helper-utils.mdx
│   │   ├── index.mdx
│   │   ├── rpc-extension.mdx
│   │   ├── rpc-methods/
│   │   │   ├── _meta.js
│   │   │   ├── admin.mdx
│   │   │   ├── debug.mdx
│   │   │   ├── eth.mdx
│   │   │   ├── net.mdx
│   │   │   ├── txpool.mdx
│   │   │   └── web3.mdx
│   │   ├── rpc-methods.mdx
│   │   ├── rpc-overview.mdx
│   │   ├── style.css
│   │   ├── vm-overview.mdx
│   │   ├── vm-testing.mdx
│   │   └── vm-tracing.mdx
│   ├── postcss.config.cjs
│   ├── public/
│   │   ├── _redirects
│   │   └── robots.txt
│   ├── tailwind.config.js
│   └── theme.config.jsx
├── event.go
├── event_test.go
├── example_test.go
├── func.go
├── func_test.go
├── go.mod
├── go.sum
├── internal/
│   ├── abi/
│   │   ├── arguments.go
│   │   ├── arguments_test.go
│   │   ├── copy.go
│   │   ├── copy_test.go
│   │   ├── doc.go
│   │   ├── lexer.go
│   │   ├── lexer_test.go
│   │   ├── parser.go
│   │   ├── parser_test.go
│   │   ├── tuple.go
│   │   └── tuple_test.go
│   ├── cmp.go
│   ├── cmp_test.go
│   ├── crypto/
│   │   └── keccak.go
│   ├── fourbyte/
│   │   ├── events.go
│   │   ├── events.txt
│   │   ├── fourbyte.go
│   │   ├── funcs.go
│   │   ├── funcs.txt
│   │   └── gen.go
│   ├── hexutil/
│   │   ├── bytes.go
│   │   ├── bytes_test.go
│   │   ├── hash.go
│   │   └── hash_test.go
│   ├── mod/
│   │   ├── root.go
│   │   └── root_test.go
│   └── module/
│       ├── factory.go
│       ├── util.go
│       └── util_test.go
├── module/
│   ├── admin/
│   │   ├── admin.go
│   │   ├── admin_test.go
│   │   └── testdata/
│   │       ├── add_peer.golden
│   │       ├── add_trusted_peer.golden
│   │       ├── node_info.golden
│   │       ├── remove_peer.golden
│   │       └── remove_trusted_peer.golden
│   ├── debug/
│   │   ├── call_trace.go
│   │   ├── call_trace_test.go
│   │   ├── doc.go
│   │   ├── testdata/
│   │   │   ├── traceCall.golden
│   │   │   ├── traceCall_callTracer.golden
│   │   │   ├── traceTx__1150000_0.golden
│   │   │   ├── traceTx__12244000_0.golden
│   │   │   └── traceTx_revertReason.golden
│   │   ├── trace.go
│   │   └── trace_test.go
│   ├── eth/
│   │   ├── balance.go
│   │   ├── balance_test.go
│   │   ├── block.go
│   │   ├── block_number.go
│   │   ├── block_number_test.go
│   │   ├── block_test.go
│   │   ├── call.go
│   │   ├── call_test.go
│   │   ├── chain_id.go
│   │   ├── chain_id_test.go
│   │   ├── code.go
│   │   ├── code_test.go
│   │   ├── doc.go
│   │   ├── gas_price.go
│   │   ├── gas_price_test.go
│   │   ├── gas_tip_cap.go
│   │   ├── gas_tip_cap_test.go
│   │   ├── get_logs.go
│   │   ├── get_logs_test.go
│   │   ├── storage_at.go
│   │   ├── storage_at_test.go
│   │   ├── subscribe.go
│   │   ├── syncing.go
│   │   ├── syncing_test.go
│   │   ├── testdata/
│   │   │   ├── block_number.golden
│   │   │   ├── block_transaction_count_by_hash__0x00.golden
│   │   │   ├── block_transaction_count_by_hash__15050000.golden
│   │   │   ├── block_transaction_count_by_number__15050000.golden
│   │   │   ├── call_func.golden
│   │   │   ├── call_func__overrides.golden
│   │   │   ├── chain_id.golden
│   │   │   ├── create_access_list.golden
│   │   │   ├── estimate_gas.golden
│   │   │   ├── gas_price.golden
│   │   │   ├── gas_tip_cap.golden
│   │   │   ├── get_balance.golden
│   │   │   ├── get_balance__at_block.golden
│   │   │   ├── get_block_by_hash__0x00.golden
│   │   │   ├── get_block_by_hash__1.golden
│   │   │   ├── get_block_by_hash__12965000.golden
│   │   │   ├── get_block_by_hash__18000000.golden
│   │   │   ├── get_block_by_hash__46147.golden
│   │   │   ├── get_block_by_number__1.golden
│   │   │   ├── get_block_by_number__12965000.golden
│   │   │   ├── get_block_by_number__46147.golden
│   │   │   ├── get_block_by_number__999999999.golden
│   │   │   ├── get_block_receipts.golden
│   │   │   ├── get_code.golden
│   │   │   ├── get_logs.golden
│   │   │   ├── get_storage_at.golden
│   │   │   ├── get_storage_at__number.golden
│   │   │   ├── get_transaction_by_block_hash_and_index.golden
│   │   │   ├── get_transaction_by_block_hash_and_index__300.golden
│   │   │   ├── get_transaction_by_block_number_and_index.golden
│   │   │   ├── get_transaction_by_hash__0x00.golden
│   │   │   ├── get_transaction_by_hash__type0.golden
│   │   │   ├── get_transaction_by_hash__type2.golden
│   │   │   ├── get_transaction_count.golden
│   │   │   ├── get_transaction_receipt.golden
│   │   │   ├── get_transaction_receipt_0x00.golden
│   │   │   ├── send_raw_transaction.golden
│   │   │   ├── syncing__false.golden
│   │   │   ├── syncing__true.golden
│   │   │   ├── uncle_by_hash_and_index__15050036.golden
│   │   │   ├── uncle_by_hash_and_index__15050036_1.golden
│   │   │   ├── uncle_by_number_and_index__15050036.golden
│   │   │   ├── uncle_count_by_hash__15050036.golden
│   │   │   └── uncle_count_by_number__15050036.golden
│   │   ├── tx.go
│   │   ├── tx_test.go
│   │   ├── uncle.go
│   │   └── uncle_test.go
│   ├── net/
│   │   ├── net.go
│   │   ├── net_test.go
│   │   └── testdata/
│   │       ├── listening.golden
│   │       ├── peer_count.golden
│   │       └── version.golden
│   ├── txpool/
│   │   ├── content.go
│   │   ├── content_test.go
│   │   ├── doc.go
│   │   ├── status.go
│   │   ├── status_test.go
│   │   └── testdata/
│   │       ├── content.golden
│   │       ├── contentFrom.golden
│   │       └── status.golden
│   └── web3/
│       ├── testdata/
│       │   ├── client_version.golden
│       │   └── client_version__err.golden
│       ├── web3.go
│       └── web3_test.go
├── rpctest/
│   ├── server.go
│   └── test_case.go
├── testdata/
│   └── w3vm/
│       ├── 1_12243997.json
│       ├── 1_12243998.json
│       ├── 1_12243999.json
│       ├── 1_12244000.json
│       ├── 1_12964997.json
│       ├── 1_12964998.json
│       ├── 1_12964999.json
│       ├── 1_12965000.json
│       ├── 1_13772997.json
│       ├── 1_13772998.json
│       ├── 1_13772999.json
│       ├── 1_13773000.json
│       ├── 1_15049997.json
│       ├── 1_15049998.json
│       ├── 1_15049999.json
│       ├── 1_15050000.json
│       ├── 1_15537391.json
│       ├── 1_15537392.json
│       ├── 1_15537393.json
│       ├── 1_15537394.json
│       ├── 1_17034867.json
│       ├── 1_17034868.json
│       ├── 1_17034869.json
│       ├── 1_17034870.json
│       ├── 1_18999999.json
│       ├── 1_19000000.json
│       ├── 1_19000001.json
│       ├── 1_19000002.json
│       ├── 1_19000003.json
│       ├── 1_19000004.json
│       ├── 1_19000005.json
│       ├── 1_19000006.json
│       ├── 1_19000007.json
│       ├── 1_19000008.json
│       ├── 1_19426484.json
│       ├── 1_19426485.json
│       ├── 1_19426486.json
│       ├── 1_19426487.json
│       ├── 1_19999999.json
│       ├── 1_4369997.json
│       ├── 1_4369998.json
│       ├── 1_4369999.json
│       ├── 1_4370000.json
│       ├── 1_7279997.json
│       ├── 1_7279998.json
│       ├── 1_7279999.json
│       ├── 1_7280000.json
│       ├── 1_9068997.json
│       ├── 1_9068998.json
│       ├── 1_9068999.json
│       ├── 1_9069000.json
│       ├── 1_9199997.json
│       ├── 1_9199998.json
│       ├── 1_9199999.json
│       ├── 1_9200000.json
│       ├── 1_header_hashes.json
│       └── contracts.json
├── util.go
├── util_test.go
├── w3types/
│   ├── interfaces.go
│   ├── interfaces_test.go
│   ├── message.go
│   ├── rpc.go
│   ├── rpc_test.go
│   ├── state.go
│   └── state_test.go
└── w3vm/
    ├── bench_test.go
    ├── db.go
    ├── example_test.go
    ├── fetcher.go
    ├── fetcher_test.go
    ├── hooks/
    │   └── call_tracer.go
    ├── receipt.go
    ├── testdata/
    │   ├── burntpix.genesis.json
    │   └── weth9.bytecode
    ├── util.go
    ├── util_test.go
    ├── vm.go
    └── vm_test.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
testdata/ linguist-generated=true


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "daily"


================================================
FILE: .github/workflows/doc.yml
================================================
name: Doc

on:
  push:
    branches: [main]
    tags: ["v*"]
  pull_request:

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
      - run: bun install
        working-directory: ./docs
      - run: bun run build
        working-directory: ./docs
      - name: upload Pages artifact
        if: github.ref_type == 'tag'
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./docs/out

  deploy:
    name: Deploy
    needs: build
    if: github.ref_type == 'tag'
    runs-on: ubuntu-latest

    permissions:
      pages: write
      id-token: write

    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

    steps:
      - name: deploy to GitHub pages
        id: deployment
        uses: actions/deploy-pages@v4


================================================
FILE: .github/workflows/go.yml
================================================
name: Go

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-go@v6
        with:
          go-version: stable
      - name: fmt
        run: diff -u <(echo -n) <(gofmt -s -d .)
      - name: vet
        run: go vet ./...
      - name: staticcheck
        run: go run honnef.co/go/tools/cmd/staticcheck@latest ./...
      - name: tidy
        run: go mod tidy -diff

  test:
    name: Test
    runs-on: ubuntu-latest
    env:
      RPC_MAINNET: ${{ secrets.RPC_MAINNET }}
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-go@v6
        with:
          go-version-file: go.mod
      - name: test
        run: go test -short -covermode atomic -coverprofile=covprofile ./...
      - name: goveralls
        env:
          COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: go run github.com/mattn/goveralls@latest -coverprofile=covprofile -service=github


================================================
FILE: .gitignore
================================================
# files
LOCK

# dirs
.next/
node_modules/
out/


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2022 lmittmann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# `w3`: Enhanced Ethereum Integration for Go

[![Go Reference](https://pkg.go.dev/badge/github.com/lmittmann/w3.svg)](https://pkg.go.dev/github.com/lmittmann/w3)
[![Go Report Card](https://goreportcard.com/badge/github.com/lmittmann/w3)](https://goreportcard.com/report/github.com/lmittmann/w3)
[![Coverage Status](https://coveralls.io/repos/github/lmittmann/w3/badge.svg?branch=main)](https://coveralls.io/github/lmittmann/w3?branch=main)
[![Latest Release](https://img.shields.io/github/v/release/lmittmann/w3)](https://github.com/lmittmann/w3/releases)
[![Chat on Telegram](https://img.shields.io/badge/Telegram-blue?logo=telegram&logoColor=white)](https://t.me/w3_golang)
<img src="https://w3.cool/gopher.png" align="right" alt="W3 Gopher" width="158" height="224">

`w3` is your toolbelt for integrating with Ethereum in Go. Closely linked to `go‑ethereum`, it provides an ergonomic wrapper for working with **RPC**, **ABI's**, and the **EVM**.


```
go get github.com/lmittmann/w3
```


## At a Glance

* Use `w3.Client` to connect to an RPC endpoint. The client features batch request support for up to **80x faster requests** and easy extendibility. [learn&nbsp;more&nbsp;↗](#rpc-client)
* Use `w3vm.VM` to simulate EVM execution with optional tracing and Mainnet state forking, or test Smart Contracts. [learn&nbsp;more&nbsp;↗](#vm)
* Use `w3.Func` and `w3.Event` to create ABI bindings from Solidity function and event signatures. [learn&nbsp;more&nbsp;↗](#abi-bindings)
* Use `w3.A`, `w3.H`, and many other utility functions to parse addresses, hashes, and other common types from strings. [learn&nbsp;more&nbsp;↗](#utils)


## Sponsors

<picture>
    <source media="(prefers-color-scheme: dark)" srcset="docs/public/assets/ef-logo-dark.svg">
    <source media="(prefers-color-scheme: light)" srcset="docs/public/assets/ef-logo.svg">
    <img src="docs/public/assets/ef-logo.svg" alt="ef logo" width="256" height="auto">
</picture>


## Getting Started

### RPC Client

[`w3.Client`](https://pkg.go.dev/github.com/lmittmann/w3#Client) is a batch request focused RPC client that can be used to connect to an Ethereum node via HTTP, WebSocket, or IPC. Its modular API allows to create custom RPC method integrations that can be used alongside the common methods implemented by this package.

**Example:** Batch Request ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchEOAState))

```go
// 1. Connect to an RPC endpoint
client, err := w3.Dial("https://eth.llamarpc.com")
if err != nil {
    // handle error
}
defer client.Close()

// 2. Make a batch request
var (
    balance *big.Int
    nonce   uint64
)
if err := client.Call(
    eth.Balance(addr, nil).Returns(&balance),
    eth.Nonce(addr, nil).Returns(&nonce),
); err != nil {
    // handle error
}
```

> [!NOTE]
> #### Why send batch requests?
> Most of the time you need to call multiple RPC methods to get the data you need. When you make separate requests per RPC call you need a single round trip to the server for each call. This can be slow, especially for remote endpoints. Batching multiple RPC calls into a single request only requires a single round trip, and speeds up RPC calls significantly.

#### Error Handling

If one or more calls in a batch request fail, `Client.Call` returns an error of type [`w3.CallErrors`](https://pkg.go.dev/github.com/lmittmann/w3#CallErrors).

**Example:** Check which RPC calls failed in a batch request ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchHandleError))
```go
var batchErr w3.CallErrors
if err := client.Call(calls...); errors.As(err, &batchErr) {
    // handle call errors
} else if err != nil {
    // handle other errors
}
```

#### Learn More
* List of supported [**RPC methods**](#rpc-methods)
* Learn how to create [**custom RPC method bindings**](#custom-rpc-method-bindings)

### VM

[`w3vm.VM`](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#VM) is a high-level EVM environment with a simple but powerful API to simulate EVM execution, test Smart Contracts, or trace transactions. It supports Mainnet state forking via RPC and state caching for faster testing.

**Example:** Simulate an Uniswap v3 swap ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-UniswapV3Swap))

```go
// 1. Create a VM that forks the Mainnet state from the latest block,
// disables the base fee, and has a fake WETH balance and approval for the router
vm, err := w3vm.New(
    w3vm.WithFork(client, nil),
    w3vm.WithNoBaseFee(),
    w3vm.WithState(w3types.State{
        addrWETH: {Storage: w3types.Storage{
            w3vm.WETHBalanceSlot(addrEOA):               common.BigToHash(w3.I("1 ether")),
            w3vm.WETHAllowanceSlot(addrEOA, addrRouter): common.BigToHash(w3.I("1 ether")),
        }},
    }),
)
if err != nil {
    // handle error
}

// 2. Simulate a Uniswap v3 swap
receipt, err := vm.Apply(&w3types.Message{
    From: addrEOA,
    To:   &addrRouter,
    Func: funcExactInput,
    Args: []any{&ExactInputParams{
        Path:             encodePath(addrWETH, 500, addrUNI),
        Recipient:        addrEOA,
        Deadline:         big.NewInt(time.Now().Unix()),
        AmountIn:         w3.I("1 ether"),
        AmountOutMinimum: w3.Big0,
    }},
})
if err != nil {
    // handle error
}

// 3. Decode output amount
var amountOut *big.Int
if err := receipt.DecodeReturns(&amountOut); err != nil {
    // handle error
}
```

### ABI Bindings

ABI bindings in `w3` are specified for individual functions using Solidity syntax and are usable for any contract that supports that function.

**Example:** ABI binding for the ERC20 `balanceOf` function ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-NewFunc-BalanceOf))

```go
funcBalanceOf := w3.MustNewFunc("balanceOf(address)", "uint256")
```

**Example:** ABI binding for the Uniswap v4 `swap` function ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-NewFunc-UniswapV4Swap))

```go
funcSwap := w3.MustNewFunc(`swap(
    (address currency0, address currency1, uint24 fee, int24 tickSpacing, address hooks) key,
    (bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96) params,
    bytes hookData
)`, "int256 delta")
```

A [`Func`](https://pkg.go.dev/github.com/lmittmann/w3#Func) can be used to

* encode arguments to the contracts input data ([`Func.EncodeArgs`](https://pkg.go.dev/github.com/lmittmann/w3#Func.EncodeArgs)),
* decode arguments from the contracts input data ([`Func.DecodeArgs`](https://pkg.go.dev/github.com/lmittmann/w3#Func.DecodeArgs)), and
* decode returns from the contracts output data ([`Func.DecodeReturns`](https://pkg.go.dev/github.com/lmittmann/w3#Func.DecodeReturns)).

### Utils

Static addresses, hashes, bytes or integers can be parsed from (hex-)strings with the following utility functions that panic if the string is not valid.

```go
addr := w3.A("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
hash := w3.H("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
bytes := w3.B("0x27c5342c")
amount := w3.I("12.34 ether")
```

Use [go-ethereum/common](https://pkg.go.dev/github.com/ethereum/go-ethereum/common) to parse strings that may not be valid instead.


## RPC Methods

List of supported RPC methods for [`w3.Client`](https://pkg.go.dev/github.com/lmittmann/w3#Client).

### [`eth`](https://pkg.go.dev/github.com/lmittmann/w3/module/eth)

| Method                                    | Go Code
| :---------------------------------------- | :-------
| `eth_blockNumber`                         | `eth.BlockNumber().Returns(blockNumber **big.Int)`
| `eth_call`                                | `eth.Call(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(output *[]byte)`<br>`eth.CallFunc(contract common.Address, f w3types.Func, args ...any).Returns(returns ...any)`
| `eth_chainId`                             | `eth.ChainID().Returns(chainID *uint64)`
| `eth_createAccessList`                    | `eth.AccessList(msg *w3types.Message, blockNumber *big.Int).Returns(resp **eth.AccessListResponse)`
| `eth_estimateGas`                         | `eth.EstimateGas(msg *w3types.Message, blockNumber *big.Int).Returns(gas *uint64)`
| `eth_gasPrice`                            | `eth.GasPrice().Returns(gasPrice **big.Int)`
| `eth_maxPriorityFeePerGas`                | `eth.GasTipCap().Returns(gasTipCap **big.Int)`
| `eth_getBalance`                          | `eth.Balance(addr common.Address, blockNumber *big.Int).Returns(balance **big.Int)`
| `eth_getBlockByHash`                      | `eth.BlockByHash(hash common.Hash).Returns(block *types.Block)`<br>`eth.HeaderByHash(hash common.Hash).Returns(header **types.Header)`
| `eth_getBlockByNumber`                    | `eth.BlockByNumber(number *big.Int).Returns(block *types.Block)`<br>`eth.HeaderByNumber(number *big.Int).Returns(header **types.Header)`
| `eth_getBlockReceipts`                    | `eth.BlockReceipts(blockNumber *big.Int).Returns(receipts *types.Receipts)`
| `eth_getBlockTransactionCountByHash`      | `eth.BlockTxCountByHash(hash common.Hash).Returns(count *uint)`
| `eth_getBlockTransactionCountByNumber`    | `eth.BlockTxCountByNumber(number *big.Int).Returns(count *uint)`
| `eth_getCode`                             | `eth.Code(addr common.Address, blockNumber *big.Int).Returns(code *[]byte)`
| `eth_getLogs`                             | `eth.Logs(q ethereum.FilterQuery).Returns(logs *[]types.Log)`
| `eth_getStorageAt`                        | `eth.StorageAt(addr common.Address, slot common.Hash, blockNumber *big.Int).Returns(storage *common.Hash)`
| `eth_getTransactionByHash`                | `eth.Tx(hash common.Hash).Returns(tx **types.Transaction)`
| `eth_getTransactionByBlockHashAndIndex`   | `eth.TxByBlockHashAndIndex(blockHash common.Hash, index uint).Returns(tx **types.Transaction)`
| `eth_getTransactionByBlockNumberAndIndex` | `eth.TxByBlockNumberAndIndex(blockNumber *big.Int, index uint).Returns(tx **types.Transaction)`
| `eth_getTransactionCount`                 | `eth.Nonce(addr common.Address, blockNumber *big.Int).Returns(nonce *uint)`
| `eth_getTransactionReceipt`               | `eth.TxReceipt(txHash common.Hash).Returns(receipt **types.Receipt)`
| `eth_sendRawTransaction`                  | `eth.SendRawTx(rawTx []byte).Returns(hash *common.Hash)`<br>`eth.SendTx(tx *types.Transaction).Returns(hash *common.Hash)`
| `eth_getUncleByBlockHashAndIndex`         | `eth.UncleByBlockHashAndIndex(hash common.Hash, index uint).Returns(uncle **types.Header)`
| `eth_getUncleByBlockNumberAndIndex`       | `eth.UncleByBlockNumberAndIndex(number *big.Int, index uint).Returns(uncle **types.Header)`
| `eth_getUncleCountByBlockHash`            | `eth.UncleCountByBlockHash(hash common.Hash).Returns(count *uint)`
| `eth_getUncleCountByBlockNumber`          | `eth.UncleCountByBlockNumber(number *big.Int).Returns(count *uint)`
| `eth_syncing`                             | `eth.Syncing().Returns(syncing *bool)`

### [`debug`](https://pkg.go.dev/github.com/lmittmann/w3/module/debug)

| Method                   | Go Code
| :----------------------- | :-------
| `debug_traceCall`        | `debug.TraceCall(msg *w3types.Message, blockNumber *big.Int, config *debug.TraceConfig).Returns(trace **debug.Trace)`<br>`debug.CallTraceCall(msg *w3types.Message, blockNumber *big.Int, overrides w3types.State).Returns(trace **debug.CallTrace)`
| `debug_traceTransaction` | `debug.TraceTx(txHash common.Hash, config *debug.TraceConfig).Returns(trace **debug.Trace)`<br>`debug.CallTraceTx(txHash common.Hash, overrides w3types.State).Returns(trace **debug.CallTrace)`

### [`txpool`](https://pkg.go.dev/github.com/lmittmann/w3/module/txpool)

| Method               | Go Code
| :--------------------| :-------
| `txpool_content`     | `txpool.Content().Returns(resp **txpool.ContentResponse)`
| `txpool_contentFrom` | `txpool.ContentFrom(addr common.Address).Returns(resp **txpool.ContentFromResponse)`
| `txpool_status`      | `txpool.Status().Returns(resp **txpool.StatusResponse)`

### [`admin`](https://pkg.go.dev/github.com/lmittmann/w3/module/admin)

| Method                    | Go Code
| :------------------------ | :-------
| `admin_addPeer`           | `admin.AddPeer(url *enode.Node).Returns(resp *bool)`
| `admin_removePeer`        | `admin.RemovePeer(url *enode.Node).Returns(resp *bool)`
| `admin_addTrustedPeer`    | `admin.AddTrustedPeer(url *enode.Node).Returns(resp *bool)`
| `admin_removeTrustedPeer` | `admin.RemoveTrustedPeer(url *enode.Node).Returns(resp *bool)`
| `admin_nodeInfo`          | `admin.NodeInfo().Returns(resp **admin.NodeInfoResponse)`

### [`net`](https://pkg.go.dev/github.com/lmittmann/w3/module/net)

| Method               | Go Code
| :------------------- | :-------
| `net_listening`     | `net.Listening().Returns(resp *bool)`
| `net_peerCount`     | `net.PeerCount().Returns(resp *int)`
| `net_version`       | `net.Version().Returns(resp *int)`

### [`web3`](https://pkg.go.dev/github.com/lmittmann/w3/module/web3)

| Method               | Go Code
| :------------------- | :-------
| `web3_clientVersion` | `web3.ClientVersion().Returns(clientVersion *string)`

### Third Party RPC Method Packages

| Package                                                                  | Description
| :----------------------------------------------------------------------- | :-----------
| [github.com/lmittmann/flashbots](https://github.com/lmittmann/flashbots) | Package `flashbots` implements RPC API bindings for the Flashbots relay and mev-geth.


## Custom RPC Method Bindings

Custom RPC method bindings can be created by implementing the [`w3types.RPCCaller`](https://pkg.go.dev/github.com/lmittmann/w3/w3types#RPCCaller) interface.

**Example:** RPC binding for the Otterscan `ots_getTransactionBySenderAndNonce` method ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3types#example-RPCCaller-GetTransactionBySenderAndNonce))

```go
// TxBySenderAndNonceFactory requests the senders transaction hash by the nonce.
func TxBySenderAndNonceFactory(sender common.Address, nonce uint64) w3types.RPCCallerFactory[common.Hash] {
    return &getTransactionBySenderAndNonceFactory{
        sender: sender,
        nonce:  nonce,
    }
}

// getTransactionBySenderAndNonceFactory implements the w3types.RPCCaller and
// w3types.RPCCallerFactory interfaces. It stores the method parameters and
// the reference to the return value.
type getTransactionBySenderAndNonceFactory struct {
    // params
    sender common.Address
    nonce  uint64

    // returns
    returns *common.Hash
}

// Returns sets the reference to the return value.
func (f *getTransactionBySenderAndNonceFactory) Returns(txHash *common.Hash) w3types.RPCCaller {
    f.returns = txHash
    return f
}

// CreateRequest creates a batch request element for the Otterscan getTransactionBySenderAndNonce method.
func (f *getTransactionBySenderAndNonceFactory) CreateRequest() (rpc.BatchElem, error) {
    return rpc.BatchElem{
        Method: "ots_getTransactionBySenderAndNonce",
        Args:   []any{f.sender, f.nonce},
        Result: f.returns,
    }, nil
}

// HandleResponse handles the response of the Otterscan getTransactionBySenderAndNonce method.
func (f *getTransactionBySenderAndNonceFactory) HandleResponse(elem rpc.BatchElem) error {
    if err := elem.Error; err != nil {
        return err
    }
    return nil
}
```


================================================
FILE: client.go
================================================
/*
Package w3 is your toolbelt for integrating with Ethereum in Go. Closely linked
to [go-ethereum], it provides an ergonomic wrapper for working with RPC, ABI's,
and the EVM.

[go-ethereum]: https://github.com/ethereum/go-ethereum
*/
package w3

import (
	"context"
	"fmt"
	"reflect"
	"strings"

	"github.com/ethereum/go-ethereum/rpc"
	"github.com/lmittmann/w3/w3types"
	"golang.org/x/time/rate"
)

// Client represents a connection to an RPC endpoint.
type Client struct {
	client *rpc.Client

	// rate limiter
	rl         *rate.Limiter
	rlCostFunc func(methods []string) (cost int)
}

// NewClient returns a new Client given an rpc.Client client.
func NewClient(client *rpc.Client, opts ...Option) *Client {
	if client == nil {
		panic("w3: client is nil")
	}
	c := &Client{client: client}
	for _, opt := range opts {
		if opt == nil {
			continue
		}
		opt(c)
	}
	return c
}

// Dial returns a new Client connected to the URL rawurl. An error is returned
// if the connection establishment fails.
//
// The supported URL schemes are "http", "https", "ws" and "wss". If rawurl is a
// file name with no URL scheme, a local IPC socket connection is established.
func Dial(rawurl string, opts ...Option) (*Client, error) {
	client, err := rpc.Dial(rawurl)
	if err != nil {
		return nil, err
	}
	return NewClient(client, opts...), nil
}

// MustDial is like [Dial] but panics if the connection establishment fails.
func MustDial(rawurl string, opts ...Option) *Client {
	client, err := Dial(rawurl, opts...)
	if err != nil {
		panic(fmt.Sprintf("w3: %s", err))
	}
	return client
}

// Close the RPC connection and cancel all in-flight requests.
//
// Close implements the [io.Closer] interface.
func (c *Client) Close() error {
	c.client.Close()
	return nil
}

// CallCtx creates the final RPC request, sends it, and handles the RPC
// response.
//
// An error is returned if RPC request creation, networking, or RPC response
// handling fails.
func (c *Client) CallCtx(ctx context.Context, calls ...w3types.RPCCaller) error {
	// no requests = nothing to do
	if len(calls) <= 0 {
		return nil
	}

	// create requests
	batchElems := make([]rpc.BatchElem, len(calls))
	var err error
	for i, req := range calls {
		batchElems[i], err = req.CreateRequest()
		if err != nil {
			return err
		}
	}

	// invoke rate limiter
	if err := c.rateLimit(ctx, batchElems); err != nil {
		return err
	}

	// do requests
	if len(batchElems) > 1 {
		// batch requests if >1 request
		err = c.client.BatchCallContext(ctx, batchElems)
		if err != nil {
			return err
		}
	} else {
		// non-batch requests if 1 request
		batchElem := batchElems[0]
		err = c.client.CallContext(ctx, batchElem.Result, batchElem.Method, batchElem.Args...)
		if err != nil {
			switch reflect.TypeOf(err).String() {
			case "*rpc.jsonError":
				batchElems[0].Error = err
			default:
				return err
			}
		}
	}

	// handle responses
	var callErrs CallErrors
	for i, req := range calls {
		err = req.HandleResponse(batchElems[i])
		if err != nil {
			if callErrs == nil {
				callErrs = make(CallErrors, len(calls))
			}
			callErrs[i] = err
		}
	}
	if len(callErrs) > 0 {
		return callErrs
	}
	return nil
}

// Call is like [Client.CallCtx] with ctx equal to context.Background().
func (c *Client) Call(calls ...w3types.RPCCaller) error {
	return c.CallCtx(context.Background(), calls...)
}

// SubscribeCtx creates a new subscription and returns a [rpc.ClientSubscription].
func (c *Client) SubscribeCtx(ctx context.Context, s w3types.RPCSubscriber) (*rpc.ClientSubscription, error) {
	namespace, ch, params, err := s.CreateRequest()
	if err != nil {
		return nil, err
	}
	return c.client.Subscribe(ctx, namespace, ch, params...)
}

// Subscribe is like [Client.SubscribeCtx] with ctx equal to context.Background().
func (c *Client) Subscribe(s w3types.RPCSubscriber) (*rpc.ClientSubscription, error) {
	return c.SubscribeCtx(context.Background(), s)
}

func (c *Client) rateLimit(ctx context.Context, batchElems []rpc.BatchElem) error {
	if c.rl == nil {
		return nil
	}

	if c.rlCostFunc == nil {
		// limit requests
		return c.rl.Wait(ctx)
	}

	// limit requests based on Compute Units (CUs)
	methods := make([]string, len(batchElems))
	for i, batchElem := range batchElems {
		methods[i] = batchElem.Method
	}
	cost := c.rlCostFunc(methods)
	return c.rl.WaitN(ctx, cost)
}

// CallErrors is an error type that contains the errors of multiple calls. The
// length of the error slice is equal to the number of calls. Each error at a
// given index corresponds to the call at the same index. An error is nil if the
// corresponding call was successful.
type CallErrors []error

func (e CallErrors) Error() string {
	if len(e) == 1 && e[0] != nil {
		return fmt.Sprintf("w3: call failed: %s", e[0])
	}

	var errors []string
	for i, err := range e {
		if err == nil {
			continue
		}
		errors = append(errors, fmt.Sprintf("call[%d]: %s", i, err))
	}

	var plr string
	if len(errors) > 1 {
		plr = "s"
	}
	return fmt.Sprintf("w3: %d call%s failed:\n%s", len(errors), plr, strings.Join(errors, "\n"))
}

func (e CallErrors) Is(target error) bool {
	_, ok := target.(CallErrors)
	return ok
}

// An Option configures a Client.
type Option func(*Client)

// WithRateLimiter sets the rate limiter for the client. Set the optional argument
// costFunc to nil to limit the number of requests. Supply a costFunc to limit
// the number of requests based on individual RPC calls for advanced rate
// limiting by e.g. Compute Units (CUs). Note that only if len(methods) > 1, the
// calls are sent in a batch request.
func WithRateLimiter(rl *rate.Limiter, costFunc func(methods []string) (cost int)) Option {
	return func(c *Client) {
		c.rl = rl
		c.rlCostFunc = costFunc
	}
}


================================================
FILE: client_test.go
================================================
package w3_test

import (
	"bytes"
	"context"
	"errors"
	"flag"
	"math/big"
	"strconv"
	"testing"

	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/ethereum/go-ethereum/rpc"
	"github.com/google/go-cmp/cmp"
	"github.com/lmittmann/w3"
	"github.com/lmittmann/w3/internal"
	"github.com/lmittmann/w3/module/eth"
	"github.com/lmittmann/w3/rpctest"
	"github.com/lmittmann/w3/w3types"
)

var (
	benchRPC = flag.String("benchRPC", "", "RPC endpoint for benchmark")

	jsonCalls1 = `> {"jsonrpc":"2.0","id":1}` + "\n" +
		`< {"jsonrpc":"2.0","id":1,"result":"0x1"}`
	jsonCalls2 = `> [{"jsonrpc":"2.0","id":1},{"jsonrpc":"2.0","id":2}]` + "\n" +
		`< [{"jsonrpc":"2.0","id":1,"result":"0x1"},{"jsonrpc":"2.0","id":2,"result":"0x1"}]`
)

func TestClientCall(t *testing.T) {
	tests := []struct {
		Buf     *bytes.Buffer
		Calls   []w3types.RPCCaller
		WantErr error
	}{
		{
			Buf:   bytes.NewBufferString(jsonCalls1),
			Calls: []w3types.RPCCaller{&testCaller{}},
		},
		{
			Buf:     bytes.NewBufferString(jsonCalls1),
			Calls:   []w3types.RPCCaller{&testCaller{RequestErr: errors.New("err")}},
			WantErr: errors.New("err"),
		},
		{
			Buf:     bytes.NewBufferString(jsonCalls1),
			Calls:   []w3types.RPCCaller{&testCaller{ReturnErr: errors.New("err")}},
			WantErr: errors.New("w3: call failed: err"),
		},
		{
			Buf: bytes.NewBufferString(jsonCalls2),
			Calls: []w3types.RPCCaller{
				&testCaller{RequestErr: errors.New("err")},
				&testCaller{},
			},
			WantErr: errors.New("err"),
		},
		{
			Buf: bytes.NewBufferString(jsonCalls2),
			Calls: []w3types.RPCCaller{
				&testCaller{ReturnErr: errors.New("err")},
				&testCaller{},
			},
			WantErr: errors.New("w3: 1 call failed:\ncall[0]: err"),
		},
		{
			Buf: bytes.NewBufferString(jsonCalls2),
			Calls: []w3types.RPCCaller{
				&testCaller{},
				&testCaller{ReturnErr: errors.New("err")},
			},
			WantErr: errors.New("w3: 1 call failed:\ncall[1]: err"),
		},
		{
			Buf: bytes.NewBufferString(jsonCalls2),
			Calls: []w3types.RPCCaller{
				&testCaller{ReturnErr: errors.New("err")},
				&testCaller{ReturnErr: errors.New("err")},
			},
			WantErr: errors.New("w3: 2 calls failed:\ncall[0]: err\ncall[1]: err"),
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			srv := rpctest.NewServer(t, test.Buf)

			client, err := w3.Dial(srv.URL())
			if err != nil {
				t.Fatalf("Failed to connect to test RPC endpoint: %v", err)
			}

			err = client.Call(test.Calls...)
			if diff := cmp.Diff(test.WantErr, err,
				internal.EquateErrors(),
			); diff != "" {
				t.Fatalf("(-want, +got)\n%s", diff)
			}
		})
	}
}

func TestClientCall_CallErrors(t *testing.T) {
	srv := rpctest.NewServer(t, bytes.NewBufferString(jsonCalls2))

	client, err := w3.Dial(srv.URL())
	if err != nil {
		t.Fatalf("Failed to connect to test RPC endpoint: %v", err)
	}

	err = client.Call(&testCaller{}, &testCaller{ReturnErr: errors.New("err")})
	if err == nil {
		t.Fatal("Want error")
	}
	if !errors.Is(err, w3.CallErrors{}) {
		t.Fatalf("Want w3.CallErrors, got %T", err)
	}
	callErrs := err.(w3.CallErrors)
	if callErrs[0] != nil {
		t.Errorf("callErrs[0]: want <nil>, got %v", callErrs[0])
	}
	if callErrs[1] == nil || callErrs[1].Error() != "err" {
		t.Errorf(`callErrs[1]: want "err", got %v`, callErrs[1])
	}
}

type testCaller struct {
	RequestErr error
	ReturnErr  error
}

func (c *testCaller) CreateRequest() (elem rpc.BatchElem, err error) {
	return rpc.BatchElem{}, c.RequestErr
}

func (c *testCaller) HandleResponse(elem rpc.BatchElem) (err error) {
	return c.ReturnErr
}

func BenchmarkCall_BalanceNonce(b *testing.B) {
	if *benchRPC == "" {
		b.Skipf("Missing -benchRPC")
	}

	w3Client := w3.MustDial(*benchRPC)
	defer w3Client.Close()

	ethClient, _ := ethclient.Dial(*benchRPC)
	defer ethClient.Close()

	addr := common.Address{}

	b.Run("Batch", func(b *testing.B) {
		var (
			nonce   uint64
			balance *big.Int
		)
		for range b.N {
			w3Client.Call(
				eth.Nonce(addr, nil).Returns(&nonce),
				eth.Balance(addr, nil).Returns(&balance),
			)
		}
	})

	b.Run("Sequential", func(b *testing.B) {
		for range b.N {
			ethClient.NonceAt(context.Background(), addr, nil)
			ethClient.BalanceAt(context.Background(), addr, nil)
		}
	})
}

func BenchmarkCall_Balance100(b *testing.B) {
	if *benchRPC == "" {
		b.Skipf("Missing -benchRPC")
	}

	w3Client := w3.MustDial(*benchRPC)
	defer w3Client.Close()

	ethClient, _ := ethclient.Dial(*benchRPC)
	defer ethClient.Close()

	addr100 := make([]common.Address, 100)
	for i := range len(addr100) {
		addr100[i] = common.BigToAddress(big.NewInt(int64(i)))
	}

	b.Run("Batch", func(b *testing.B) {
		var balance *big.Int
		for range b.N {
			requests := make([]w3types.RPCCaller, len(addr100))
			for j := range len(requests) {
				requests[j] = eth.Balance(addr100[j], nil).Returns(&balance)
			}
			w3Client.Call(requests...)
		}
	})

	b.Run("Sequential", func(b *testing.B) {
		for range b.N {
			for _, addr := range addr100 {
				ethClient.BalanceAt(context.Background(), addr, nil)
			}
		}
	})
}

func BenchmarkCall_BalanceOf100(b *testing.B) {
	if *benchRPC == "" {
		b.Skipf("Missing -benchRPC")
	}

	w3Client := w3.MustDial(*benchRPC)
	defer w3Client.Close()

	ethClient, _ := ethclient.Dial(*benchRPC)
	defer ethClient.Close()

	addr100 := make([]common.Address, 100)
	for i := range len(addr100) {
		addr100[i] = common.BigToAddress(big.NewInt(int64(i)))
	}

	funcBalanceOf := w3.MustNewFunc("balanceOf(address)", "uint256")
	addrWeth9 := w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")

	b.Run("Batch", func(b *testing.B) {
		var balance big.Int
		for range b.N {
			requests := make([]w3types.RPCCaller, len(addr100))
			for j := range len(requests) {
				requests[j] = eth.CallFunc(addrWeth9, funcBalanceOf, addr100[j]).Returns(&balance)
			}
			w3Client.Call(requests...)
		}
	})

	b.Run("Sequential", func(b *testing.B) {
		for range b.N {
			for _, addr := range addr100 {
				input, err := funcBalanceOf.EncodeArgs(addr)
				if err != nil {
					b.Fatalf("Failed to encode args: %v", err)
				}
				ethClient.CallContract(context.Background(), ethereum.CallMsg{
					To:   &addrWeth9,
					Data: input,
				}, nil)
			}
		}
	})
}

func BenchmarkCall_Block100(b *testing.B) {
	if *benchRPC == "" {
		b.Skipf("Missing -benchRPC")
	}

	w3Client := w3.MustDial(*benchRPC)
	defer w3Client.Close()

	ethClient, _ := ethclient.Dial(*benchRPC)
	defer ethClient.Close()

	block100 := make([]*big.Int, 100)
	for i := range len(block100) {
		block100[i] = big.NewInt(int64(14_000_000 + i))
	}

	b.Run("Batch", func(b *testing.B) {
		var block *types.Block
		for range b.N {
			requests := make([]w3types.RPCCaller, len(block100))
			for j := range len(requests) {
				requests[j] = eth.BlockByNumber(block100[j]).Returns(&block)
			}
			w3Client.Call(requests...)
		}
	})

	b.Run("Sequential", func(b *testing.B) {
		for range b.N {
			for _, number := range block100 {
				ethClient.BlockByNumber(context.Background(), number)
			}
		}
	})
}


================================================
FILE: docs/components/DocLink.jsx
================================================
import { Link } from 'nextra-theme-docs'
import { Code } from 'nextra/components'

const pkgNameToPath = {
    'w3': 'github.com/lmittmann/w3',
    'module': 'github.com/lmittmann/w3/module',
    'debug': 'github.com/lmittmann/w3/module/debug',
    'eth': 'github.com/lmittmann/w3/module/eth',
    'txpool': 'github.com/lmittmann/w3/module/txpool',
    'web3': 'github.com/lmittmann/w3/module/web3',
    'w3types': 'github.com/lmittmann/w3/w3types',
    'w3vm': 'github.com/lmittmann/w3/w3vm',
    'hooks': 'github.com/lmittmann/w3/w3vm/hooks',
    'tracing': 'github.com/ethereum/go-ethereum/core/tracing',
    'logger': 'github.com/ethereum/go-ethereum/eth/tracers/logger',
}

export const DocLink = ({ title, id }) => {
    if (typeof id === 'undefined') { id = title }
    let dotIndex = id.indexOf('.');
    let pkg = id.substring(0, dotIndex);
    let comp = id.substring(dotIndex + 1);

    return (
        <Link href={`https://pkg.go.dev/${pkgNameToPath[pkg]}#${comp}`}>
            <Code>{title}</Code>
        </Link>
    )
}


================================================
FILE: docs/next.config.js
================================================
import nextra from 'nextra'

const withNextra = nextra({
	theme: 'nextra-theme-docs',
	themeConfig: './theme.config.jsx',
	staticImage: true,
	search: {
		codeblocks: true
	},
	defaultShowCopyCode: true
})

export default withNextra({
	output: 'export',
	reactStrictMode: true,
	images: {
		unoptimized: true,
	}
})


================================================
FILE: docs/package.json
================================================
{
	"type": "module",
	"scripts": {
		"dev": "next dev",
		"build": "next build"
	},
	"dependencies": {
		"next": "^14.2.14",
		"nextra": "3.0.0-alpha.40",
		"nextra-theme-docs": "3.0.0-alpha.40",
		"react": "^18.3.1",
		"react-dom": "^18.3.1"
	},
	"devDependencies": {
		"autoprefixer": "^10.4.20",
		"postcss": "^8.4.47",
		"tailwindcss": "^3.4.13"
	}
}


================================================
FILE: docs/pages/404.mdx
================================================
# Page Not Found

Get back on track: [Homepage](/)


================================================
FILE: docs/pages/_app.js
================================================
import './style.css'
import 'nextra-theme-docs/style.css'
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export default function Nextra({ Component, pageProps }) {
    const getLayout = Component.getLayout || ((page) => page)
    return getLayout(
        <div className={inter.className}>
            <Component  {...pageProps} />
        </div>
    )
}


================================================
FILE: docs/pages/_meta.js
================================================
export default {
    index: {
        title: 'Overview',
        display: 'hidden',
        theme: { breadcrumb: false, toc: false, pagination: false },
    },
    '404': {
        title: '404',
        display: 'hidden',
        theme: {
            breadcrumb: false,
            toc: false,
            layout: 'full',
            pagination: false,
        }
    },
    '--- RPC Client': {
        type: 'separator',
        title: 'RPC Client'
    },
    'rpc-overview': {
        title: 'Overview',
        theme: { breadcrumb: false },
    },
    'rpc-methods': {
        title: 'Methods',
        theme: { breadcrumb: false },
    },
    'rpc-extension': {
        title: 'Extension',
        theme: { breadcrumb: false },
    },
    '+++ VM': {
        'title': '',
        'type': 'separator'
    },
    '--- VM': {
        type: 'separator',
        title: 'VM'
    },
    'vm-overview': {
        title: 'Overview',
        theme: { breadcrumb: false },
    },
    'vm-tracing': {
        title: 'Tracing',
        theme: { breadcrumb: false },
    },
    'vm-testing': {
        title: 'Testing',
        theme: { breadcrumb: false },
    },
    '+++ HELPER': {
        'title': '',
        'type': 'separator'
    },
    '--- HELPER': {
        type: 'separator',
        title: 'Helper'
    },
    'helper-abi': {
        title: 'ABI',
        theme: { breadcrumb: false },
    },
    'helper-utils': {
        title: 'Utils',
        theme: { breadcrumb: false },
    },
    examples: {
        title: 'Examples',
        type: 'page',
    },
    releases: {
        title: 'Releases',
        type: 'page',
        href: 'https://github.com/lmittmann/w3/releases',
        newWindow: true
    },
    godoc: {
        title: 'GoDoc',
        type: 'page',
        href: 'https://pkg.go.dev/github.com/lmittmann/w3#section-documentation',
        newWindow: true
    },
}


================================================
FILE: docs/pages/examples/_meta.js
================================================
export default {
    index: {
        title: 'Examples',
        display: 'hidden',
        theme: { breadcrumb: false, toc: true, pagination: false },
    },
}


================================================
FILE: docs/pages/examples/index.mdx
================================================
# Examples

## `w3.Client` Examples

* **Batch Fetch** 1000 blocks ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchBlocks))
* **Batch Call** the name, symbol, decimals, and balanceOf functions of the Wrapped Ether in a single batch ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchCallFunc))
* **Batch Call** the Uniswap V3 Quoter for quotes on swapping 100 WETH for DAI in pools of all fee tiers in a single batch ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchCallFuncUniswapQuoter))
* **Batch Fetch** the nonce and balance of an EOA in a single batch ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchEOAState))
* **Batch Fetch** a transaction and its receipt in a single batch ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchTxDetails))
* **Call** the token balance of an address ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-CallFunc))
* **Call** the token balance of an address, with state override ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-CallFuncWithStateOverride))
* **Handle errors** of individual calls in a batch ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-BatchHandleError))
* **Rate Limit** the number of requests to 300 compute units (CUs) per second, with bursts of up to 300 CUs. An individual CU can be charged per RPC method call ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-RateLimitByComputeUnits))
* **Rate Limit** the number of requests to 10 per second, with bursts of up to 20 requests ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-RateLimitByRequest))
* **Send Ether** transfer ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-SendETHTransfer))
* **Send ERC20 token** transfer (Wrapped Ether) ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-SendTokenTransfer))
* **Subscribe** to pending transactions ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Client-SubscribeToPendingTransactions))

**[See all examples ↗](https://pkg.go.dev/github.com/lmittmann/w3#pkg-examples)**


## `w3vm.VM` Examples

* **Ether transfer** ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-SimpleTransfer))
* **ERC20 token transfer** with faked token balance (Wrapped Ether) ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-FakeTokenBalance))
* **Uniswap V3 swap** ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-UniswapV3Swap))

* **Call ERC20 balanceOf** with raw a `w3types.Message` using the `Message.{Func,Args}` helper ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-Call))
* **Call ERC20 balanceOf**, using the `VM.CallFunc` helper ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-CallFunc))
* **Prank** a sender ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-PrankZeroAddress))
* **Trace calls** (and opcodes) of a transaction ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-TraceCalls))
* **Trace** the execution to obtain the access list ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-TraceAccessList))
* **Trace** the execution of all op's in a block ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-TraceBlock))

**[See all examples ↗](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#pkg-examples)**


================================================
FILE: docs/pages/examples.mdx
================================================


================================================
FILE: docs/pages/helper-abi.mdx
================================================
# ABI Bindings

ABI bindings allow the encoding and decoding of Smart Contract function calls or the decoding of events.
In `w3` ABI bindings are defined for individual functions or events at runtime using Solidity syntax.

* **Easy to write:** Creating an ABI binding only requires the Solidity function signature. No need
  to firstly generate an ABI json file using `solc` and secondly generate ABI bindings using `abigen`.
* **Flexible:** ABI bindings for a function or event can be used with any Smart Contract. No need to
  generate overlapping bindings for multiple Smart Contracts.


## Functions

Function ABI bindings can be defined using
* `func NewFunc(signature, returns string) (*Func, error)`, or
* `func MustNewFunc(signature, returns string) *Func` which panics on error.

### Syntax

Function signatures are defined using Solidity syntax. Arguments and returns can optionally be named. While naming is optional, it is recommended for more complex functions or tuple variables. Alias types, such as `uint` for `uint256`, are supported.

#### Example: ERC20 `balanceOf`

ABI binding for the ERC20 `balanceOf` function ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-NewFunc-BalanceOf)):

```solidity filename="Solidity"
interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    // ...
}
```

```go filename="Go"
var funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256")
// or
var funcBalanceOf = w3.MustNewFunc("balanceOf(address who)", "uint256 amount")
```

#### Example: QuoterV2 `quoteExactInputSingle`

ABI binding for the Uniswap QuoterV2 `quoteExactInputSingle` function with a tuple parameter (Solidity `struct`):

```solidity filename="Solidity"
interface QuoterV2 {

    struct QuoteExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint256 amountIn;
        uint24 fee;
        uint160 sqrtPriceLimitX96;
    }

    function quoteExactInputSingle(QuoteExactInputSingleParams memory params)
        external
        returns (
            uint256 amountOut,
            uint160 sqrtPriceX96After,
            uint32 initializedTicksCrossed,
            uint256 gasEstimate
        );
    // ...
}
```

```go filename="Go"
type QuoteExactInputSingleParams struct {
    TokenIn           common.Address
    TokenOut          common.Address
    AmountIn          *big.Int
    Fee               *big.Int `abitype:"uint24"`
    SqrtPriceLimitX96 *big.Int `abitype:"uint160"`
}

var funcQuoteExactInputSingle = w3.MustNewFunc(
    `quoteExactInputSingle(QuoteExactInputSingleParams params)`,
    `uint256 amountOut,
     uint160 sqrtPriceX96After,
     uint32 initializedTicksCrossed,
     uint256 gasEstimate`,
    QuoteExactInputSingleParams{}, // Pass struct type as tuple definition
)
```

##### Alternative: Inline Tuple Definition

For simple cases or when you prefer not to define separate structs, you can use inline tuple definitions:

```go filename="Go"
var funcQuoteExactInputSingle = w3.MustNewFunc(
    `quoteExactInputSingle((
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint24 fee,
        uint160 sqrtPriceLimitX96
    ) params)`,
    `uint256 amountOut,
     uint160 sqrtPriceX96After,
     uint32 initializedTicksCrossed,
     uint256 gasEstimate`,
)
```

### Tuples (Solidity `struct`'s)

Tuple types need to be embedded in parentheses, with comma-separated fields. Fields must be named, so they can be mapped to the fields of a Go struct.

To map a tuple type to a Go struct, the struct must be defined manually with each tuple field being mapped to a Go struct field. Field names need to match, but Go field names must always start with an uppercase letter. E.g. the tuple field `address tokenIn{:solidity}` must be matched to the Go struct field `TokenIn common.Address{:go}`.

<Callout type="info">
    See [Type Mappings](#type-mappings) for more information on how to map primitive Solidity types to Go types and vice versa.
</Callout>

### `EncodeArgs`

The `EncodeArgs` method of a `Func` ABI encodes a Solidity function call. Each argument of the Solidity function must be matched by a corresponding Go value.

### `DecodeArgs` and `DecodeReturns`

The `DecodeArgs` and `DecodeReturns` methods of a `Func` ABI decode the arguments and returns of a Solidity function call. The Go values that should hold the decoded data must be defined beforehand, and passed as pointers to the decode methods. Values that should not be decoded can be passed as `nil`. Tailing `nil` values can be omitted.

#### Example: Uniswap Pair `getReserves`

ABI decode the output of the Uniswap Pair `getReserves` function ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Func.DecodeReturns-GetReserves)):

```go filename="Go"
var (
    funcGetReserves = w3.MustNewFunc("getReserves()", "uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast")
    output []byte   = w3.B("0x00…")
)

var (
    reserve0, reserve1 *big.Int
    blockTimestampLast uint32
)
if err := funcGetReserves.DecodeReturns(output, &reserve0, &reserve1, &blockTimestampLast); err != nil {
    // ...
}
```

In case only the reserves should be decoded, the `blockTimestampLast` can be ignored using `funcGetReserves.DecodeReturns(output, &reserve0, &reserve1, nil){:go}`, which is equivalent to `funcGetReserves.DecodeReturns(output, &reserve0, &reserve1){:go}`.


## Events

Event ABI bindings can be defined using
* `func NewEvent(signature string) (*Event, error)`, or
* `func MustNewEvent(signature string) *Event` which panics on error.

#### Example: ERC20 `Transfer`

ABI binding for the ERC20 `Transfer` event:

```solidity filename="Solidity"
interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    // ...
}
```

```go filename="Go"
var evtTransfer = w3.MustNewEvent("Transfer(address indexed from, address indexed to, uint256 value)")
```


## Type Mappings

| **Solidity Type**                                    | **Go Type**                 |
|:-----------------------------------------------------|:----------------------------|
| `bool`                                               | `bool`                      |
| `int8`                                               | `int8`                      |
| `int16`                                              | `int16`                     |
| `int32`                                              | `int32`                     |
| `int64`                                              | `int64`                     |
| `int24`,`int40`…`int56`,`int72`…`int256`,`int`       | `*big.Int`                  |
| `uint8`                                              | `uint8`                     |
| `uint16`                                             | `uint16`                    |
| `uint32`                                             | `uint32`                    |
| `uint64`                                             | `uint64`                    |
| `uint24`,`uint40`…`uint56`,`uint72`…`uint256`,`uint` | `*big.Int`                  |
| `bytes`                                              | `[]byte`                    |
| `bytes1`…`bytes32`                                   | `[1]byte`…`[32]byte`        |
| `address`                                            | `common.Address`/`[20]byte` |
| `bytes32`                                            | `common.Hash`/`[32]byte`    |

### Arrays and Slices

Solidity arrays and slices are mapped to Go arrays and slices respectively and vice versa.

| **Solidity Type** | **Go Type** |
|:------------------|:------------|
| `type[n]`         | `[n]type`   |
| `type[]`          | `[]type`    |


================================================
FILE: docs/pages/helper-utils.mdx
================================================
# Utils

Static addresses, hashes, bytes or integers can be parsed from (hex-)strings with the following utility functions that panic if the string is not valid.

```go
addr := w3.A("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
hash := w3.H("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
bytes := w3.B("0x27c5342c")
amount := w3.I("12.34 ether")
```

Use [go-ethereum/common](https://pkg.go.dev/github.com/ethereum/go-ethereum/common) to parse strings that may not be valid instead.


================================================
FILE: docs/pages/index.mdx
================================================
---
description: 'w3: Enhanced Ethereum Integration for Go'
---

# `w3`: Enhanced Ethereum Integration for Go

<div className="flex flex-wrap gap-2 my-2">
  <a href="https://pkg.go.dev/github.com/lmittmann/w3">
    <img src="https://pkg.go.dev/badge/github.com/lmittmann/w3.svg" alt="Go Reference" />
  </a>
  <a href="https://goreportcard.com/report/github.com/lmittmann/w3">
    <img src="https://goreportcard.com/badge/github.com/lmittmann/w3" alt="Go Report Card" />
  </a>
  <a href="https://coveralls.io/github/lmittmann/w3?branch=main">
    <img src="https://coveralls.io/repos/github/lmittmann/w3/badge.svg?branch=main" alt="Coverage Status" />
  </a>
  <a href="https://github.com/lmittmann/w3/releases">
    <img src="https://img.shields.io/github/v/release/lmittmann/w3" alt="Latest Release" />
  </a>
  <a href="https://t.me/w3_golang">
    <img src="https://img.shields.io/badge/Telegram-blue?logo=telegram&logoColor=white" alt="Chat on Telegram" />
  </a>
</div>

<Image src="/gopher.png" alt="W3 Gopher" width={158} height={224} align="right" className="ml-2 md:ml-6 mb-2"/>

`w3` is your toolbelt for integrating with Ethereum in Go. Closely linked to `go‑ethereum`, it provides an ergonomic wrapper for working with **RPC**, **ABI's**, and the **EVM**.


```txt
go get github.com/lmittmann/w3
```


## At a Glance

* Use `w3.Client` to connect to an RPC endpoint. The client features batch request support for up to **80x faster requests** and easy extendibility. [learn&nbsp;more&nbsp;➔](/rpc-overview)
* Use `w3vm.VM` to simulate EVM execution with optional tracing and Mainnet state forking, or test Smart Contracts. [learn&nbsp;more&nbsp;➔](/vm-overview)
* Use `w3.Func` and `w3.Event` to create ABI bindings from Solidity function and event signatures. [learn&nbsp;more&nbsp;➔](/helper-abi)
* Use `w3.A`, `w3.H`, and many other utility functions to parse addresses, hashes, and other common types from strings. [learn&nbsp;more&nbsp;➔](/helper-utils)


## Sponsors

<div class="mt-4">
  <img src="/assets/ef-logo.svg" alt="EF Logo" class="w-full max-w-72 dark:hidden" />
  <img src="/assets/ef-logo-dark.svg" alt="EF Logo Dark" class="w-full max-w-72 hidden dark:block" />
</div>


================================================
FILE: docs/pages/rpc-extension.mdx
================================================
# Custom RPC Method Bindings

Custom RPC method bindings can be created by implementing the <DocLink title="w3types.RPCCaller" /> interface. By convention, the `w3types.RPCCaller` is setup using an unexported factory, which implements the <DocLink title="w3types.RPCCallerFactory" /> interface, to keep the package API small and readable. The factory stores the method parameters and the reference to the return value.

**Example:** RPC binding for the Otterscan `ots_getTransactionBySenderAndNonce` method ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3types#example-RPCCaller-GetTransactionBySenderAndNonce))

```go
// TxBySenderAndNonceFactory requests the senders transaction hash by the nonce.
func TxBySenderAndNonceFactory(sender common.Address, nonce uint64) w3types.RPCCallerFactory[common.Hash] {
    return &getTransactionBySenderAndNonceFactory{
        sender: sender,
        nonce:  nonce,
    }
}

// getTransactionBySenderAndNonceFactory implements the w3types.RPCCaller and
// w3types.RPCCallerFactory interfaces. It stores the method parameters and
// the reference to the return value.
type getTransactionBySenderAndNonceFactory struct {
    // params
    sender common.Address
    nonce  uint64

    // returns
    returns *common.Hash
}

// Returns sets the reference to the return value.
func (f *getTransactionBySenderAndNonceFactory) Returns(txHash *common.Hash) w3types.RPCCaller {
    f.returns = txHash
    return f
}

// CreateRequest creates a batch request element for the Otterscan getTransactionBySenderAndNonce method.
func (f *getTransactionBySenderAndNonceFactory) CreateRequest() (rpc.BatchElem, error) {
    return rpc.BatchElem{
        Method: "ots_getTransactionBySenderAndNonce",
        Args:   []any{f.sender, f.nonce},
        Result: f.returns,
    }, nil
}

// HandleResponse handles the response of the Otterscan getTransactionBySenderAndNonce method.
func (f *getTransactionBySenderAndNonceFactory) HandleResponse(elem rpc.BatchElem) error {
    if err := elem.Error; err != nil {
        return err
    }
    return nil
}
```


================================================
FILE: docs/pages/rpc-methods/_meta.js
================================================
export default {
    eth: 'eth',
    debug: 'debug',
    txpool: 'txpool',
    admin: 'admin',
    net: 'net',
    web3: 'web3',
}


================================================
FILE: docs/pages/rpc-methods/admin.mdx
================================================
# `admin`-Namespace

List of supported RPC methods for `w3.Client` in the `admin`-namespace.

## `admin_addPeer`
`AddPeer` adds a new peer to the node's peer set and returns a bool indicating success.
```go {3}
var success bool
client.Call(
    admin.AddPeer(url).Returns(&success),
)
```

## `admin_removePeer`
`RemovePeer` removes a peer from the node's peer set and returns a bool indicating success.
```go {3}
var success bool
client.Call(
    admin.RemovePeer(url).Returns(&success),
)
```

## `admin_addTrustedPeer`
`AddTrustedPeer` adds a new trusted peer to the node's trusted peer set and returns a bool indicating success.
```go {3}
var success bool
client.Call(
    admin.AddTrustedPeer(url).Returns(&success),
)
```

## `admin_removeTrustedPeer`
`RemoveTrustedPeer` removes a trusted peer from the node's trusted peer set and returns a bool indicating success.
```go {3}
var success bool
client.Call(
    admin.RemoveTrustedPeer(url).Returns(&success),
)
```

## `admin_nodeInfo`
`NodeInfo` returns information about the running node.
```go {3}
var nodeInfo *admin.NodeInfoResponse
client.Call(
    admin.NodeInfo().Returns(&nodeInfo),
)
```


================================================
FILE: docs/pages/rpc-methods/debug.mdx
================================================
# `debug`-Namespace

List of supported RPC methods for `w3.Client` in the `debug`-namespace.

## `debug_traceCall`
`TraceCall` requests the trace of the given message.
```go {3}
var trace *debug.Trace
client.Call(
    debug.TraceCall(msg, blockNumber, config).Returns(&trace),
)
```

`CallTraceCall` requests the call trace of the given message.
```go {3}
var trace *debug.CallTrace
client.Call(
    debug.CallTraceCall(msg, blockNumber, overrides).Returns(&trace),
)
```

## `debug_traceTransaction`
`TraceTx` requests the trace of the transaction with the given hash.
TraceTx requests the trace of the transaction with the given hash.
```go {3}
var trace *debug.Trace
client.Call(
    debug.TraceTx(txHash, config).Returns(&trace),
)
```

`CallTraceTx` requests the call trace of the transaction with the given hash.
```go {3}
var trace *debug.CallTrace
client.Call(
    debug.CallTraceTx(txHash, overrides).Returns(&trace),
)
```


================================================
FILE: docs/pages/rpc-methods/eth.mdx
================================================
# `eth`-Namespace

List of supported RPC methods for `w3.Client` in the `eth`-namespace.

## `eth_blockNumber`
`BlockNumber` requests the number of the most recent block.
```go {3}
var blockNumber *big.Int
client.Call(
    eth.BlockNumber().Returns(&blockNumber),
)
```

## `eth_call`
`Call` requests the output data of the given message at the given blockNumber. If blockNumber is nil, the output of the message at the latest known block is requested.
```go {3}
var output []byte
client.Call(
    eth.Call(msg, blockNumber, overrides).Returns(&output),
)
```

## `eth_chainId`
`ChainID` requests the chains ID.
```go {3}
var chainID uint64
client.Call(
    eth.ChainID().Returns(&chainID),
)
```

## `eth_createAccessList`
`AccessList` requests the access list of the given message at the given blockNumber. If blockNumber is nil, the access list of the message at the latest block is requested.
```go {3}
var accessListResp *AccessListResponse
client.Call(
    eth.AccessList(msg, blockNumber).Returns(&accessListResp),
)
```

## `eth_estimateGas`
`EstimateGas` requests the estimated gas cost of the given message at the given blockNumber. If blockNumber is nil, the estimated gas cost of the message at the latest block is requested.
```go {3}
var gas uint64
client.Call(
    eth.EstimateGas(msg, blockNumber).Returns(&gas),
)
```

## `eth_gasPrice`
`GasPrice` requests the current gas price in wei.
```go {3}
var gasPrice *big.Int
client.Call(
    eth.GasPrice().Returns(&gasPrice),
)
```

## `eth_maxPriorityFeePerGas`
`GasTipCap` requests the currently suggested gas tip cap after EIP-1559 to allow a timely execution of a transaction.
```go {3}
var gasTipCap *big.Int
client.Call(
    eth.GasTipCap().Returns(&gasTipCap),
)
```

## `eth_getBalance`
`Balance` requests the balance of the given common.Address addr at the given blockNumber. If blockNumber is nil, the balance at the latest known block is requested.
```go {3}
var balance *big.Int
client.Call(
    eth.Balance(addr, blockNumber).Returns(&balance),
)
```

## `eth_getBlockByHash`
`BlockByHash` requests the block with the given hash with full transactions.
```go {3}
var block *types.Block
client.Call(
    eth.BlockByHash(hash).Returns(&block),
)
```

## `eth_getBlockByNumber`
`BlockByNumber` requests the block with the given number with full transactions. If number is nil, the latest block is requested.
```go {3}
var block *types.Block
client.Call(
    eth.BlockByNumber(number).Returns(&block),
)
```

## `eth_getBlockReceipts`
`BlockReceipts` requests all receipts of the transactions in the given block.
```go {3}
var receipts types.Receipts
client.Call(
    eth.BlockReceipts(blockNumber).Returns(&receipts),
)
```

## `eth_getBlockTransactionCountByHash`
`BlockTxCountByHash` requests the number of transactions in the block with the given hash.
```go {3}
var count uint
client.Call(
    eth.BlockTxCountByHash(hash).Returns(&count),
)
```

## `eth_getBlockTransactionCountByNumber`
`BlockTxCountByNumber` requests the number of transactions in the block with the given number.
```go {3}
var count uint
client.Call(
    eth.BlockTxCountByNumber(number).Returns(&count),
)
```

## `eth_getCode`
`Code` requests the code of the given common.Address addr at the given blockNumber. If blockNumber is nil, the code at the latest known block is requested.
```go {3}
var code []byte
client.Call(
    eth.Code(addr, blockNumber).Returns(&code),
)
```

## `eth_getLogs`
`Logs` requests the logs of the given ethereum.FilterQuery q.
```go {3}
var logs []types.Log
client.Call(
    eth.Logs(query).Returns(&logs),
)
```

## `eth_getStorageAt`
`StorageAt` requests the storage of the given common.Address addr at the given common.Hash slot at the given blockNumber. If block number is nil, the slot at the latest known block is requested.
```go {3}
var storage common.Hash
client.Call(
    eth.StorageAt(addr, slot, blockNumber).Returns(&storage),
)
```

## `eth_getTransactionByHash`
`Tx` requests the transaction with the given hash.
```go {3}
var tx *types.Transaction
client.Call(
    eth.Tx(hash).Returns(&tx),
)
```

## `eth_getTransactionByBlockHashAndIndex`
`TxByBlockHashAndIndex` requests the transaction in the given block with the given index.
```go {3}
var tx *types.Transaction
client.Call(
    eth.TxByBlockHashAndIndex(blockHash, index).Returns(&tx),
)
```

## `eth_getTransactionByBlockNumberAndIndex`
`TxByBlockNumberAndIndex` requests the transaction in the given block with the given index.
```go {3}
var tx *types.Transaction
client.Call(
    eth.TxByBlockNumberAndIndex(blockNumber, index).Returns(&tx),
)
```
## `eth_getTransactionCount`
`Nonce` requests the nonce of the given common.Address addr at the given blockNumber. If blockNumber is nil, the nonce at the latest known block is requested.
```go {3}
var count uint
client.Call(
    eth.Nonce(addr, blockHash).Returns(&count),
)
```

## `eth_getTransactionReceipt`
`TxReceipt` requests the receipt of the transaction with the given hash.
```go {3}
var receipt *types.Receipt
client.Call(
    eth.TxReceipt(txHash).Returns(&receipt),
)
```

## `eth_sendRawTransaction`
`SendRawTx` sends a raw transaction to the network and returns its hash.
```go {3}
var txHash common.Hash
client.Call(
    eth.SendRawTx(rawTx).Returns(&txHash),
)
```

SendTx sends a signed transaction to the network and returns its hash.
```go {3}
var txHash common.Hash
client.Call(
    eth.SendTx(tx).Returns(&txHash),
)
```

## `eth_getUncleByBlockHashAndIndex`
`UncleByBlockHashAndIndex` requests the uncle of the block with the given hash at the given index.
```go {3}
var uncle *types.Header
client.Call(
    eth.UncleByBlockHashAndIndex(hash, index).Returns(&uncle),
)
```

## `eth_getUncleByBlockNumberAndIndex`
`UncleByBlockNumberAndIndex` requests the uncle of the block with the given number at the given index.
```go {3}
var uncle *types.Header
client.Call(
    eth.UncleByBlockNumberAndIndex(number, index).Returns(&uncle),
)
```
## `eth_getUncleCountByBlockHash`
`UncleCountByBlockHash` requests the number of uncles of the block with the given hash.
```go {3}
var count uint
client.Call(
    eth.UncleCountByBlockHash(hash).Returns(&count),
)
```

## `eth_getUncleCountByBlockNumber`
`UncleCountByBlockNumber` requests the number of uncles of the block with the given number.
```go {3}
var count uint
client.Call(
    eth.UncleCountByBlockNumber(number).Returns(&count),
)
```

## `eth_syncing`
`Syncing` requests the syncing status of the node.
```go {3}
var syncing bool
client.Call(
    eth.Syncing().Returns(&syncing),
)
```


================================================
FILE: docs/pages/rpc-methods/net.mdx
================================================
# `net`-Namespace

List of supported RPC methods for `w3.Client` in the `net`-namespace.

## `net_listening`
`Listening` returns whether the client is actively listening for network connections.
```go {3}
var listening bool
client.Call(
    net.Listening().Returns(&listening),
)
```

## `net_peerCount`
`PeerCount` returns the number of peers connected to the node.
```go {3}
var peerCount int
client.Call(
    net.PeerCount().Returns(&peerCount),
)
```

## `net_version`
`Version` returns the network ID (e.g. 1 for mainnet).
```go {3}
var version int
client.Call(
    net.Version().Returns(&version),
)
```


================================================
FILE: docs/pages/rpc-methods/txpool.mdx
================================================
# `txpool`-Namespace

List of supported RPC methods for `w3.Client` in the `txpool`-namespace.

## `txpool_content`
`Content` requests the pending and queued transactions in the transaction pool.
```go {3}
var content *txpool.ContentResponse
client.Call(
    txpool.Content().Returns(&content),
)
```

## `txpool_contentFrom`
`ContentFrom` requests the pending and queued transactions in the transaction pool from the given address.
```go {3}
var contentFrom *txpool.ContentFromResponse
client.Call(
    txpool.ContentFrom(addr).Returns(&contentFrom),
)
```


## `txpool_status`
`Status` requests the number of pending and queued transactions in the transaction pool.
```go {3}
var status *txpool.StatusResponse
client.Call(
    txpool.Status().Returns(&status),
)
```


================================================
FILE: docs/pages/rpc-methods/web3.mdx
================================================
# `web3`-Namespace

List of supported RPC methods for `w3.Client` in the `web3`-namespace.

## `web3_clientVersion`
`ClientVersion` requests the endpoints client version.
```go {3}
var clientVersion string
client.Call(
    web3.ClientVersion().Returns(&clientVersion),
)
```


================================================
FILE: docs/pages/rpc-methods.mdx
================================================
# Methods

`w3` supports most common RPC methods for Ethereum and other EVM chains. If you are in need of a method that is not supported by `w3` natively, you can use [third party method packages](#third-party-rpc-method-packages), or easily write a custom method-binding and use it with `w3`.

## RPC Namespaces

RPC methods supported by `w3` are grouped into namespaces.

<Cards>
  <Card title="eth" href="/rpc-methods/eth"/>
  <Card title="debug" href="/rpc-methods/debug"/>
  <Card title="txpool" href="/rpc-methods/txpool"/>
  <Card title="admin" href="/rpc-methods/admin"/>
  <Card title="net" href="/rpc-methods/net"/>
  <Card title="web3" href="/rpc-methods/web3" />
</Cards>

## Third Party RPC Method Packages

List of third party method packages that can be used with `w3.Client`.

| Package                                                                  | Description
| :----------------------------------------------------------------------- | :-----------
| [github.com/lmittmann/flashbots](https://github.com/lmittmann/flashbots) | Package `flashbots` implements RPC API bindings for the Flashbots relay and mev-geth.


================================================
FILE: docs/pages/rpc-overview.mdx
================================================
# RPC Client

<DocLink title="w3.Client" /> is a blazing fast RPC client, built on top of `go-ethereum/rpc.Client`. It is designed for **batch requests** and **easy extendibility**.

## Get Started

<DocLink title="w3.Client" /> is a batch request focused RPC client that can be used to connect to an Ethereum node via HTTP, WebSocket, or IPC. Its modular API allows to create custom RPC method integrations that can be used alongside the common methods implemented by this package.

<Steps>

### Connect to an RPC Endpoint

Connect to an RPC endpoint via HTTP, WebSocket, or IPC using <DocLink title="w3.Dial" /> or <DocLink title="w3.MustDial" />.

```go
client, err := w3.Dial("https://eth.llamarpc.com")
if err != nil {
    // ...
}
defer client.Close()
```

### Make a Request

Make a single HTTP request that calls two RPC methods.

```go
var (
    balance *big.Int
    nonce   uint64
)
if err := client.Call(
    eth.Balance(addr, nil).Returns(&balance),
    eth.Nonce(addr, nil).Returns(&nonce),
); err != nil {
    // ...
}
```

</Steps>

<Callout type="info">
#### Why send batch requests?
Most of the time you need to call multiple RPC methods to get the data you need. When you make separate requests per RPC call you need a single round trip to the server for each call. This can be slow, especially for remote endpoints. Batching multiple RPC calls into a single request only requires a single round trip, and speeds up RPC calls significantly.
</Callout>

## Call

<Callout type="info">Coming soon...</Callout>

## Call Contracts

<Callout type="info">Coming soon...</Callout>

## Subscribe

`w3.Client` supports subscriptions through the <DocLink title="Client.Subscribe" id="w3.Client.Subscribe" /> and <DocLink title="Client.SubscribeCtx" id="w3.Client.SubscribeCtx" /> methods. Subscriptions can be used to listen to events, emitted by the Ethereum node.

### Subscriptions

* `eth.NewHeads(ch chan<- *types.Header)`: Subscribe to new block headers.
* `eth.NewLogs(ch chan<- *types.Log, q ethereum.FilterQuery)`: Subscribe to new logs.
* `eth.PendingTransactions(ch chan<- *types.Transaction)`: Subscribe to new pending transactions.

#### Example: Subscribe to Pending Transactions

Subscribe to new pending transactions ([Playground](https://pkg.go.dev/github.com/lmittmann/w3##example-Client-SubscribeToPendingTransactions)):

```go
pendingTxCh := make(chan *types.Transaction)
sub, err := client.Subscribe(eth.PendingTransactions(pendingTxCh))
if err != nil {
    // ...
}

for {
    select {
    case tx := <-pendingTxCh:
        fmt.Printf("New pending tx: %s\n", tx.Hash())
    case err := <-sub.Err():
        fmt.Printf("Subscription error: %v\n", err)
        return
    }
}
```

## Error Handling

If one or more calls in a batch request fail, `Client.Call` returns an error of type <DocLink title="w3.CallErrors" />.

#### Example: `w3.CallErrors`

Check which RPC calls failed in a batch request ([Playground](https://pkg.go.dev/github.com/lmittmann/w3##example-Client-BatchHandleError))
```go
var batchErr w3.CallErrors
if err := client.Call(calls...); errors.As(err, &batchErr) {
    // handle call errors
} else if err != nil {
    // handle other errors
}
```


================================================
FILE: docs/pages/style.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
    main {
        @apply dark:text-neutral-300;
    }

    main strong,
    main :not(a)>code {
        @apply dark:text-white;
    }
}

/* Headings */
h2 {
    @apply border-none;
}

/* Links */
a._underline {
    @apply no-underline;
}

/* Tables */
tr._border-gray-300 td,
tr._border-gray-300 th {
    @apply dark:border-neutral-700;
}

tr._border-gray-300 {
    @apply even:bg-neutral-900 !important;
}

/* Customize header */
.nextra-nav-container nav a[target="_blank"]:nth-child(2):after,
.nextra-nav-container nav a[target="_blank"]:nth-child(3):after,
.nextra-nav-container nav a[target="_blank"]:nth-child(4):after,
aside.nextra-sidebar-container li a[target="_blank"]:after {
    content: url('data:image/svg+xml,<svg width="8" height="8" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.33622 2.84025L1.17647 10L0 8.82354L7.15975 1.66378H0.849212V0H10V9.15081H8.33622V2.84025Z" fill="%239195A6"/></svg>');
    @apply pl-2;
}

.nextra-nav-container nav a {
    @apply font-semibold;
}

/* Customize sidebar */
aside.nextra-sidebar-container li._text-sm.\[word-break\:break-word\] {
    @apply text-base;
}

aside.nextra-sidebar-container li._my-4.\[word-break\:break-word\]  {
    @apply mt-4 mb-0;
}


================================================
FILE: docs/pages/vm-overview.mdx
================================================
# VM

<DocLink title="w3vm.VM" /> is an easy-to-use Ethereum Virtual Machine (EVM), built on top of `go-ethereum`'s `vm.EVM`. It supports **tracing**, **state forking** via RPC, and can be used for simulation, debugging EVM execution, or testing Smart Contracts.

* **State forking** via RPC or custom state fetchers enables transaction simulations or Smart Contract tests on live, or historical chain state.
* **Tracing** of EVM execution is supported via `go-ethereum/core/tracing.Hooks`.


## Get Started

<Steps>

### Create a VM Instance

Create a VM instance, that forks the latest Mainnet state.

```go
client, err := w3.Dial("https://eth.llamarpc.com")
if err != nil {
    // ...
}
defer client.Close()

vm, err := w3vm.New(
    w3vm.WithFork(client, nil),
    w3vm.WithNoBaseFee(),
)
if err != nil {
    // ...
}
```

### Simulate a Simple Message

Transfer ETH from the zero address to a random recipient.

```go
recipient := w3vm.RandA()

receipt, err := vm.Apply(&w3types.Message{
    From:  common.Address{},
    To:    &recipient,
    Value: w3.I("1 ether"),
})
if err != nil {
    // ...
}
```

### Verify the Recipient's Balance

Verify the recipient's balance after the applied message.

```go
balance, err := vm.Balance(recipient)
if err != nil {
    // ...
}

fmt.Printf("Balance: %s ETH\n", w3.FromWei(balance, 18))
// Output: Balance: 1 ETH
```

</Steps>


## Setup

A new VM instance is created using the `w3vm.New` function, which accepts various options to customize the VM behavior:

* `WithChainConfig(cfg *params.ChainConfig)`: Sets the chain configuration. If not provided, the VM defaults to the Mainnet configuration.
* `WithNoBaseFee()`: Forces the EIP-1559 base fee to 0.
* `WithBlockContext(ctx *vm.BlockContext)`: Sets the block context for the VM.
* `WithPrecompile(addr common.Address, contract vm.PrecompiledContract)`: Registers a precompile contract at the given address in the VM.
* `WithHeader(header *types.Header)`: Configures the block context for the VM using the provided header.
* `WithState(state w3types.State)`: Sets the pre-state of the VM. When used with `WithFork`, the pre-state overrides the forked state.
* `WithStateDB(db *state.StateDB)`: Specifies the state database for the VM, typically a snapshot from `VM.Snapshot`.
* `WithFork(client *w3.Client, blockNumber *big.Int)`: Forks state from a live Ethereum client at the specified block number.
* `WithFetcher(fetcher Fetcher)`: Assigns a fetcher to the VM.
* `WithTB(tb testing.TB)`: Enables persistent state caching when used in conjunction with `WithFork`.


## Execution

Messages represent transactions or contract calls that can be executed by the VM.

<Callout type="info">All execution methods support **tracing** via `go-ethereum/core/tracing.Hooks`. [Learn&nbsp;more&nbsp;➔](/vm-tracing) </Callout>

### `Apply` Method

<DocLink title="Apply" id="w3vm.VM.Apply" /> applies a `w3types.Message` to the VM and returns a `Receipt`. If the execution doesn't revert, the VM's underlying state may change.

#### Example: Apply a Message

```go
msg := &w3types.Message{
    From:  addrSender,
    To:    &addrRecipient,
    Value: w3.I("1 ether"),
    Gas:   21000,
}

receipt, err := vm.Apply(msg)
if err != nil {
    // ...
}
fmt.Printf("Gas Used: %d\n", receipt.GasUsed)
```

### `ApplyTx` Method

<DocLink title="ApplyTx" id="w3vm.VM.ApplyTx" /> is like `Apply`, but takes a `types.Transaction` instead of a message. The given transaction is converted to a message internally, using a signer, that is derived from the VM's chain configuration and fork block.

### `Call` Method

<DocLink title="Call" id="w3vm.VM.Call" /> is like `Apply`, but any state changes during execution are reverted in the end, so the VM's state is never modified.

#### Example: Call `balanceOf`

```go
funcBalanceOf := w3.MustNewFunc("balanceOf(address)", "uint256")

msg := &w3types.Message{
    To:    &addrToken,
    Func:  funcBalanceOf,
    Args:  []any{addrOwner},
}

receipt, err := vm.Call(msg)
if err != nil {
    // handle error
}

var balance *big.Int
if err := receipt.DecodeReturns(&balance); err != nil {
    // handle error
}
fmt.Printf("Balance: %s\n", balance)
```

### `CallFunc` Method

<DocLink title="CallFunc" id="w3vm.VM.CallFunc" /> is a helper, that greatly simplifies common usage of `Call`. It is designed analogues to the `eth.CallFunc` RPC client method.

#### Example: Call `balanceOf` with `CallFunc`

This is a simplified version of the [Call `balanceOf`](#example-call-balanceof) example.

```go
funcBalanceOf := w3.MustNewFunc("balanceOf(address)", "uint256")

var balance *big.Int
err := vm.CallFunc(addrToken, funcBalanceOf, addrOwner).Returns(&balance)
if err != nil {
    // handle error
}
fmt.Printf("Balance: %s\n", balance)
```

### `Clone` Method

<DocLink title="Clone" id="w3vm.VM.Clone" /> returns a copy of the VM and its state. The cloned VM is independent of the original VM, and state changes do not affect the original VM.

### `Receipt` Type

The `Receipt` struct contains the result of an executed message.

#### Fields

* `GasUsed uint64`: Gas used for executing the message (including refunds).
* `MaxGasUsed uint64`: Maximum gas used during executing the message (excluding refunds).
* `Logs []*types.Log`: Logs emitted while executing the message.
* `Output []byte`: Output of the executed message.
* `ContractAddress *common.Address`: Address of the created contract, if any.
* `Err error`: Execution error, if any.

#### Methods

* `DecodeReturns(returns ...any) error`: Decodes the return values. This method only works, if the executed message had `w3types.Message.Func` set.


## State

The VM provides methods to read, and write account state.

### Reading State

* `vm.Balance(addr common.Address) (*big.Int, error)`: Returns the balance of the given address.
* `vm.Nonce(addr common.Address) (uint64, error)`: Returns the nonce of the given address.
* `vm.Code(addr common.Address) ([]byte, error)`: Returns the code of the given address.
* `vm.StorageAt(addr common.Address, slot common.Hash) (common.Hash, error)`: Returns the state of the given address at the given storage slot.

<Callout type="info">
An error only can only occur, if the VM fails to fetch state via a `w3vm.Fetcher`. Thus, it is safe to ignore the error, if no state fetcher is used by the VM.
</Callout>

### Writing State

* `vm.SetBalance(addr common.Address, balance *big.Int)`: Sets the balance of the given address.
* `vm.SetNonce(addr common.Address, nonce uint64)`: Sets the nonce of the given address.
* `vm.SetCode(addr common.Address, code []byte)`: Sets the code of the given address.
* `vm.SetStorageAt(addr common.Address, slot common.Hash, value common.Hash)`: Sets the state of the given address at the give storage slot.


## Helper

* `w3vm.RandA() common.Address`: Returns a random address.
* `WETHBalanceSlot(addr common.Address) common.Hash`: Returns the storage slot that stores the WETH balance of the given address.
* `WETHAllowanceSlot(owner, spender common.Address) common.Hash`: Returns the storage slot that stores the WETH allowance of the given owner to the spender.

### Storage Slot Calculation

Calculate storage slots for mappings. Solidity and Vyper use different parameter ordering for keccak256 hash calculation.

* `SoliditySlot(pos, key common.Hash) common.Hash`: Single mapping storage slot.
* `SoliditySlot2(pos, key0, key1 common.Hash) common.Hash`: Double mapping storage slot.
* `SoliditySlot3(pos, key0, key1, key2 common.Hash) common.Hash`: Triple mapping storage slot.
* `VyperSlot(pos, key common.Hash) common.Hash`: Single HashMap storage slot.
* `VyperSlot2(pos, key0, key1 common.Hash) common.Hash`: Double HashMap storage slot.
* `VyperSlot3(pos, key0, key1, key2 common.Hash) common.Hash`: Triple HashMap storage slot.


================================================
FILE: docs/pages/vm-testing.mdx
================================================
# Contract Testing

`w3vm` can be used to test Smart Contracts in Go utilizing Go's handy testing and fuzzing features.

<Callout type="warning">
`w3vm` **does not** natively support Smart Contract compilation.
</Callout>

## Compile Smart Contracts

The first step to testing a Smart Contract is usually to compile it to bytecode. There are a number of third party packages that provide compiler bindings in Go:

* [`go-solc`](https://github.com/lmittmann/go-solc): Go bindings for the Solidity compiler (`solc`)
* [`go-huffc`](https://github.com/project-blanc/go-huffc): Go Bindings for the Huff Compiler (`huffc`)
* [`geas`](https://github.com/fjl/geas): The Good Ethereum Assembler


## Setup a `w3vm.VM`

Before a Smart Contract can be tested with a `w3vm.VM` instance, its bytecode must be deployed to the VM. This can be done in two ways, depending on whether constructor logic is present.

### Without Constructor Logic

If the Smart Contract does not require constructor logic, its runtime bytecode can be directly set as the bytecode of an address:


```go
contractRuntime = w3.B("0x...")
contractAddr := w3vm.RandA()

vm, _ := w3vm.New(
    w3vm.WithState(w3types.State{
        contractAddr: {Code: runtime},
    }),
)
```

### With Constructor Logic

If the Smart Contract requires constructor logic, the constructor bytecode must be sent in a standard deployment transaction (`w3types.Message`) without recipient:

```go
contractConstructor := w3.B("0x...")
deployerAddr := w3vm.RandA()

vm, _ := w3vm.New()
receipt, err := vm.Apply(&w3types.Message{
    From:  deployerAddr,
    Input: contractConstructor,
})
if err != nil || receipt.ContractAddress == nil {
    // ...
}
contractAddr := *receipt.ContractAddress
```

### Custom State

The state of the VM can be fully customized using the `w3vm.WithState` option. This allows, e.g., setting a balance for addresses that interact with the Smart Contract. State can also be modified after the VM is created using the [state write methods](/vm-overview#writing-state).

### State Forking

If the tested Smart Contract interacts with other existing contracts, the VM can be configured to fork the state at a specific block number (or the latest block). This enables testing contracts in a real-world environment.

```go
client := w3.MustDial("https://eth.llamarpc.com")
defer client.Close()

vm, err := w3vm.New(
    w3vm.WithFork(client, big.NewInt(20_000_000)),
    w3vm.WithNoBaseFee(),
    w3vm.WithTB(t),
)
if err != nil {
    // ...
}
```

<Callout>
`w3vm.WithTB(t)` can be used in tests or benchmarks to **cache state**. The VM persists this cached state in `{package of test}/testdata/w3vm/`. This is particularly useful when working with public RPC providers, as it reduces the number of requests and significantly speeds up test execution.
</Callout>


## Testing

Testing Smart Contracts with `w3vm` follows the standard Go testing patterns using the package `testing`. By integrating `w3vm` into your tests, you can simulate blockchain interactions and validate Smart Contract behaviors within your test cases.

#### Example: Test WETH `deposit` Function

Test of the WETH `deposit` function.

```go
func TestWETHDeposit(t *testing.T) {
    // setup VM
    vm, _ := w3vm.New(
        w3vm.WithState(w3types.State{
            addrWETH: {Code: codeWETH},
            addrA:    {Balance: w3.I("1 ether")},
        }),
    )

    // pre check
    var wethBalanceBefore *big.Int
    if err := vm.CallFunc(addrWETH, funcBalanceOf, addrA).Returns(&wethBalanceBefore); err != nil {
        t.Fatal(err)
    }
    if wethBalanceBefore.Sign() != 0 {
        t.Fatal("Invalid WETH balance: want 0")
    }

    // deposit (via fallback)
    if _, err := vm.Apply(&w3types.Message{
        From:  addrA,
        To:    &addrWETH,
        Value: w3.I("1 ether"),
    }); err != nil {
        t.Fatalf("Deposit failed: %v", err)
    }

    // post check
    var wethBalanceAfter *big.Int
    if err := vm.CallFunc(addrWETH, funcBalanceOf, addrA).Returns(&wethBalanceAfter); err != nil {
        t.Fatal(err)
    }
    if w3.I("1 ether").Cmp(wethBalanceAfter) != 0 {
        t.Fatalf("Invalid WETH balance: want 1")
    }
}
```


## Fuzz Testing

Fuzzing Smart Contracts with `w3vm` leverages Go's fuzz testing capabilities to automatically generate a wide range of inputs for your contracts. By incorporating `w3vm` into your fuzzing tests, you can effectively discover vulnerabilities and unexpected behaviors in your Smart Contracts.

#### Example: Fuzz Test WETH `deposit` Function

Fuzz test of the WETH `deposit` function.

```go
func FuzzWETHDeposit(f *testing.F) {
    f.Add([]byte{1})
    f.Fuzz(func(t *testing.T, amountBytes []byte) {
        if len(amountBytes) > 32 {
            t.Skip()
        }
        amount := new(big.Int).SetBytes(amountBytes)

        // setup VM
        vm, _ := w3vm.New(
            w3vm.WithState(w3types.State{
                addrWETH: {Code: codeWETH},
                addrA:    {Balance: w3.BigMaxUint256},
            }),
        )

        // Pre-check WETH balance
        var wethBalanceBefore *big.Int
        if err := vm.CallFunc(addrWETH, funcBalanceOf, addrA).Returns(&wethBalanceBefore); err != nil {
            t.Fatal(err)
        }

        // Attempt deposit
        vm.Apply(&w3types.Message{
            From:  addrA,
            To:    &addrWETH,
            Value: amount,
        })

        // Post-check WETH balance
        var wethBalanceAfter *big.Int
        if err := vm.CallFunc(addrWETH, funcBalanceOf, addrA).Returns(&wethBalanceAfter); err != nil {
            t.Fatal(err)
        }

        // Verify balance increment
        wantBalance := new(big.Int).Add(wethBalanceBefore, amount)
        if wethBalanceAfter.Cmp(wantBalance) != 0 {
            t.Fatalf("Invalid WETH balance: want %s, got %s", wantBalance, wethBalanceAfter)
        }
    })
}
```


================================================
FILE: docs/pages/vm-tracing.mdx
================================================
# Tracing

Tracing can give detailed insights into the execution of EVM contracts. `w3vm.VM` supports tracing via `go‑ethereum`'s <DocLink title="tracing.Hooks" />.

## Usage

A `tracing.Hooks` can be passed to <DocLink title="VM.Apply" id="w3vm.VM.Apply" />, <DocLink title="VM.ApplyTx" id="w3vm.VM.ApplyTx" />, and <DocLink title="VM.Call" id="w3vm.VM.Call" />. These methods can also be called with multiple hooks at the same time.

#### Example: Trace Calls and OpCodes of an Execution

`w3vm` contains a powerful call an opcode tracer <DocLink title="hooks.CallTracer" id="hooks.NewCallTracer" /> that can be used gain detailed insights into the execution of EVM contracts ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-Trace)):

```go
callTracer := hooks.NewCallTracer(os.Stdout, &hooks.CallTracerOptions{
    ShowStaticcall: true,
    DecodeABI:      true,
})
vm.ApplyTx(tx, callTracer)
```

![Example Call Trace](/assets/call-trace.png)

#### Example: Generate an Access List

Access list tracing using `go-ethereum`'s <DocLink title="logger.AccessListTracer" /> ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-TraceAccessList)):

```go {2-8}
// setup access list tracer
signer := types.MakeSigner(params.MainnetChainConfig, header.Number, header.Time)
from, _ := signer.Sender(tx)
accessListTracer := logger.NewAccessListTracer(
    nil,
    from, *tx.To(),
    gethVm.ActivePrecompiles(params.MainnetChainConfig.Rules(header.Number, header.Difficulty.Sign() == 0, header.Time)),
)

if _, err := vm.ApplyTx(tx, accessListTracer.Hooks()); err != nil {
    // ...
}
fmt.Println("Access List:", accessListTracer.AccessList())
```

#### Example: Trace the Execution of all OpCodes in a Block

Trace the execution of all op's in a block ([Playground](https://pkg.go.dev/github.com/lmittmann/w3/w3vm#example-VM-TraceBlock)):

```go {2-7}
// setup block op's tracer
var opCount [256]uint64
tracer := &tracing.Hooks{
    OnOpcode: func(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) {
        opCount[op]++
    },
}

for _, tx := range block.Transactions() {
    vm.ApplyTx(tx, tracer)
}
```


================================================
FILE: docs/postcss.config.cjs
================================================
module.exports = {
    plugins: {
        "tailwindcss/nesting": {},
        tailwindcss: {},
        autoprefixer: {},
    },
};


================================================
FILE: docs/public/_redirects
================================================
/vm /vm-overview
/rpc /rpc-overview
/abi /helper-abi


================================================
FILE: docs/public/robots.txt
================================================
User-agent: *
Allow: /


================================================
FILE: docs/tailwind.config.js
================================================
module.exports = {
	content: [
		'./pages/**/*.{js,jsx,mdx}',
		'./components/**/*.{js,jsx}',
		'./theme.config.jsx'
	],
	theme: {
		extend: {}
	},
	plugins: [],
	darkMode: 'class'
}


================================================
FILE: docs/theme.config.jsx
================================================
import Image from 'next/image'
import { useConfig } from 'nextra-theme-docs'
import { Callout, Cards, Steps } from 'nextra/components'
import { DocLink } from './components/DocLink'

export default {
    logo: <>
        <div className="rounded-full h-10 w-10 mr-2 overflow-hidden bg-black/10 dark:bg-white/10">
            <Image src="/gopher.png" alt="w3" width={48} height={48} className='w-11/12 mx-auto' />
        </div>
        <span className="text-2xl font-bold">w3</span>
    </>,
    head: () => {
        const { frontMatter } = useConfig()
        const title = frontMatter.title ? `${frontMatter.title} – w3` : 'w3'
        return (
            <>
                <title>{title}</title>
                <meta property="og:title" content={title} />
                <meta
                    property="og:description"
                    content={frontMatter.description || 'w3'}
                />
            </>
        )
    },
    footer: {
        component: null,
    },
    components: {
        Callout: Callout,
        Card: Cards.Card,
        Cards: Cards,
        Image: Image,
        Steps: Steps,
        DocLink: DocLink,
    },
    project: {
        link: 'https://github.com/lmittmann/w3',
    },
    chat: {
        link: 'https://t.me/w3_golang',
        icon: (
            <svg width="24" height="24" viewBox="0 0 48 48" fill="currentColor">
                <path d="M41.4193 7.30899C41.4193 7.30899 45.3046 5.79399 44.9808 9.47328C44.8729 10.9883 43.9016 16.2908 43.1461 22.0262L40.5559 39.0159C40.5559 39.0159 40.3401 41.5048 38.3974 41.9377C36.4547 42.3705 33.5408 40.4227 33.0011 39.9898C32.5694 39.6652 24.9068 34.7955 22.2086 32.4148C21.4531 31.7655 20.5897 30.4669 22.3165 28.9519L33.6487 18.1305C34.9438 16.8319 36.2389 13.8019 30.8426 17.4812L15.7331 27.7616C15.7331 27.7616 14.0063 28.8437 10.7686 27.8698L3.75342 25.7055C3.75342 25.7055 1.16321 24.0823 5.58815 22.459C16.3807 17.3729 29.6555 12.1786 41.4193 7.30899Z" />
            </svg>
        )
    },
    feedback: {
        content: null,
    },
    docsRepositoryBase: 'https://github.com/lmittmann/w3/blob/main/docs',
    color: {
        hue: 189,
        saturation: 100,
    },
}


================================================
FILE: event.go
================================================
package w3

import (
	"fmt"

	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
	_abi "github.com/lmittmann/w3/internal/abi"
)

// Event represents a Smart Contract event decoder.
type Event struct {
	Signature string        // Event signature
	Topic0    common.Hash   // Hash of event signature (Topic 0)
	Args      abi.Arguments // Arguments

	indexedArgs abi.Arguments // Subset of Args that are indexed
}

// NewEvent returns a new Smart Contract event log decoder from the given
// Solidity event signature.
//
// The optional tuples parameter accepts struct definitions that can be
// referenced by name in the signature instead of using inline tuple
// definitions. This enables cleaner, more readable function signatures when
// working with complex tuple types.
//
// An error is returned if the signature parsing fails.
func NewEvent(signature string, tuples ...any) (*Event, error) {
	name, args, err := _abi.ParseWithName(signature, tuples...)
	if err != nil {
		return nil, fmt.Errorf("%w: %v", ErrInvalidABI, err)
	}
	if name == "" {
		return nil, fmt.Errorf("%w: missing event name", ErrInvalidABI)
	}

	indexedArgs := make(abi.Arguments, 0)
	for _, arg := range args {
		if arg.Indexed {
			arg.Indexed = false
			indexedArgs = append(indexedArgs, arg)
		}
	}

	sig := args.SignatureWithName(name)
	return &Event{
		Signature:   sig,
		Topic0:      crypto.Keccak256Hash([]byte(sig)),
		Args:        abi.Arguments(args),
		indexedArgs: indexedArgs,
	}, nil
}

// MustNewEvent is like [NewEvent] but panics if the signature parsing fails.
func MustNewEvent(signature string, tuples ...any) *Event {
	event, err := NewEvent(signature, tuples...)
	if err != nil {
		panic(err)
	}
	return event
}

// DecodeArgs decodes the topics and data of the given log to the given args.
func (e *Event) DecodeArgs(log *types.Log, args ...any) error {
	if len(log.Topics) <= 0 || e.Topic0 != log.Topics[0] {
		return fmt.Errorf("w3: topic0 mismatch")
	}

	if len(e.Args) != len(args) {
		return fmt.Errorf("%w: expected %d arguments, got %d", ErrArgumentMismatch, len(e.Args), len(args))
	}
	if len(e.indexedArgs) != len(log.Topics)-1 {
		return fmt.Errorf("%w: expected %d indexed arguments, got %d", ErrArgumentMismatch, len(e.indexedArgs), len(log.Topics)-1)
	}

	indexedArgs := make([]any, 0, len(e.indexedArgs))
	nonIndexedArgs := make([]any, 0, len(e.Args)-len(e.indexedArgs))
	for i, arg := range e.Args {
		if arg.Indexed {
			indexedArgs = append(indexedArgs, args[i])
		} else {
			nonIndexedArgs = append(nonIndexedArgs, args[i])
		}
	}

	// decode indexed args
	for i, arg := range indexedArgs {
		if err := (_abi.Arguments{e.indexedArgs[i]}).Decode(log.Topics[i+1][:], arg); err != nil {
			return err
		}
	}

	// decode non-indexed args
	if err := _abi.Arguments(e.Args).Decode(log.Data, nonIndexedArgs...); err != nil {
		return err
	}
	return nil
}


================================================
FILE: event_test.go
================================================
package w3_test

import (
	"math/big"
	"strconv"
	"testing"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"github.com/lmittmann/w3"
)

func TestNewEvent(t *testing.T) {
	tests := []struct {
		Signature string
		WantEvent *w3.Event
	}{
		{
			Signature: "Transfer(address,address,uint256)",
			WantEvent: &w3.Event{
				Signature: "Transfer(address,address,uint256)",
				Topic0:    w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
			},
		},
		{
			Signature: "Transfer(address from, address to, uint256 value)",
			WantEvent: &w3.Event{
				Signature: "Transfer(address,address,uint256)",
				Topic0:    w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
			},
		},
		{
			Signature: "Approval(address,address,uint256)",
			WantEvent: &w3.Event{
				Signature: "Approval(address,address,uint256)",
				Topic0:    w3.H("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"),
			},
		},
		{
			Signature: "Approval(address owner, address spender, uint256 value)",
			WantEvent: &w3.Event{
				Signature: "Approval(address,address,uint256)",
				Topic0:    w3.H("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"),
			},
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			gotEvent, err := w3.NewEvent(test.Signature)
			if err != nil {
				t.Fatalf("Failed to create new FUnc: %v", err)
			}

			if diff := cmp.Diff(test.WantEvent, gotEvent,
				cmpopts.IgnoreUnexported(w3.Event{}),
				cmpopts.IgnoreFields(w3.Event{}, "Args"),
			); diff != "" {
				t.Fatalf("(-want, +got)\n%s", diff)
			}
		})
	}
}

func TestEventDecodeArgs(t *testing.T) {
	tests := []struct {
		Event    *w3.Event
		Log      *types.Log
		Args     []any
		WantArgs []any
	}{
		{
			Event: w3.MustNewEvent("Transfer(address,address,uint256)"),
			Log: &types.Log{
				Topics: []common.Hash{
					w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
				},
				Data: w3.B("0x" +
					"000000000000000000000000000000000000000000000000000000000000c0fe" +
					"000000000000000000000000000000000000000000000000000000000000dead" +
					"000000000000000000000000000000000000000000000000000000000000002a"),
			},
			Args: []any{new(common.Address), new(common.Address), new(big.Int)},
			WantArgs: []any{
				w3.APtr("0x000000000000000000000000000000000000c0Fe"),
				w3.APtr("0x000000000000000000000000000000000000dEaD"),
				big.NewInt(42),
			},
		},
		{
			Event: w3.MustNewEvent("Transfer(address indexed, address, uint256)"),
			Log: &types.Log{
				Topics: []common.Hash{
					w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
					w3.H("0x000000000000000000000000000000000000000000000000000000000000c0fe"),
				},
				Data: w3.B("0x" +
					"000000000000000000000000000000000000000000000000000000000000dead" +
					"000000000000000000000000000000000000000000000000000000000000002a"),
			},
			Args: []any{new(common.Address), new(common.Address), new(big.Int)},
			WantArgs: []any{
				w3.APtr("0x000000000000000000000000000000000000c0Fe"),
				w3.APtr("0x000000000000000000000000000000000000dEaD"),
				big.NewInt(42),
			},
		},
		{
			Event: w3.MustNewEvent("Transfer(address, address indexed, uint256)"),
			Log: &types.Log{
				Topics: []common.Hash{
					w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
					w3.H("0x000000000000000000000000000000000000000000000000000000000000dead"),
				},
				Data: w3.B("0x" +
					"000000000000000000000000000000000000000000000000000000000000c0fe" +
					"000000000000000000000000000000000000000000000000000000000000002a"),
			},
			Args: []any{new(common.Address), new(common.Address), new(big.Int)},
			WantArgs: []any{
				w3.APtr("0x000000000000000000000000000000000000c0Fe"),
				w3.APtr("0x000000000000000000000000000000000000dEaD"),
				big.NewInt(42),
			},
		},
		{
			Event: w3.MustNewEvent("Transfer(address indexed, address indexed, uint256)"),
			Log: &types.Log{
				Topics: []common.Hash{
					w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
					w3.H("0x000000000000000000000000000000000000000000000000000000000000c0fe"),
					w3.H("0x000000000000000000000000000000000000000000000000000000000000dead"),
				},
				Data: w3.B("0x000000000000000000000000000000000000000000000000000000000000002a"),
			},
			Args: []any{new(common.Address), new(common.Address), new(big.Int)},
			WantArgs: []any{
				w3.APtr("0x000000000000000000000000000000000000c0Fe"),
				w3.APtr("0x000000000000000000000000000000000000dEaD"),
				big.NewInt(42),
			},
		},
		{
			Event: w3.MustNewEvent("Transfer(address indexed, address indexed, uint256 indexed)"),
			Log: &types.Log{
				Topics: []common.Hash{
					w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
					w3.H("0x000000000000000000000000000000000000000000000000000000000000c0fe"),
					w3.H("0x000000000000000000000000000000000000000000000000000000000000dead"),
					w3.H("0x000000000000000000000000000000000000000000000000000000000000002a"),
				},
			},
			Args: []any{new(common.Address), new(common.Address), new(big.Int)},
			WantArgs: []any{
				w3.APtr("0x000000000000000000000000000000000000c0Fe"),
				w3.APtr("0x000000000000000000000000000000000000dEaD"),
				big.NewInt(42),
			},
		},
		{ // https://github.com/lmittmann/w3/issues/15
			Event: w3.MustNewEvent("NameRegistered(string name, bytes32 indexed label, address indexed owner, uint cost, uint expires)"),
			Log: &types.Log{
				Address: w3.A("0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5"),
				Topics: []common.Hash{
					w3.H("0xca6abbe9d7f11422cb6ca7629fbf6fe9efb1c621f71ce8f02b9f2a230097404f"),
					w3.H("0x4e59ffc7ae105a2b19f7f29b63e9f9c5ac28e27bce744a330804c6a89269cec0"),
					w3.H("0x000000000000000000000000bd08f39b2523426cc1d6961e2d6a9744b3b432b5"),
				},
				Data: w3.B("0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000165a7d3a3e48ad0000000000000000000000000000000000000000000000000000000066e4d0a50000000000000000000000000000000000000000000000000000000000000009656c666172657373690000000000000000000000000000000000000000000000"),
			},
			Args: []any{new(string), new(common.Hash), new(common.Address), new(big.Int), new(big.Int)},
			WantArgs: []any{
				ptr("elfaressi"),
				ptr(w3.H("0x4e59ffc7ae105a2b19f7f29b63e9f9c5ac28e27bce744a330804c6a89269cec0")),
				w3.APtr("0xbD08F39B2523426Cc1d6961e2d6A9744B3B432b5"),
				big.NewInt(6291943382206637),
				big.NewInt(1726271653),
			},
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			if err := test.Event.DecodeArgs(test.Log, test.Args...); err != nil {
				t.Fatalf("Failed to decode args: %v", err)
			}
			if diff := cmp.Diff(test.WantArgs, test.Args,
				cmp.AllowUnexported(big.Int{}),
				cmpopts.IgnoreUnexported(w3.Event{}),
			); diff != "" {
				t.Fatalf("(-want, +got)\n%s", diff)
			}
		})
	}
}


================================================
FILE: example_test.go
================================================
package w3_test

import (
	"crypto/ecdsa"
	"errors"
	"fmt"
	"math/big"
	"time"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/params"
	"github.com/lmittmann/w3"
	"github.com/lmittmann/w3/module/eth"
	"github.com/lmittmann/w3/w3types"
	"github.com/lmittmann/w3/w3vm"
	"golang.org/x/time/rate"
)

var (
	funcName      = w3.MustNewFunc("name()", "string")
	funcSymbol    = w3.MustNewFunc("symbol()", "string")
	funcDecimals  = w3.MustNewFunc("decimals()", "uint8")
	funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256")

	addrA = common.Address{0x0a}
	addrB = common.Address{0x0b}

	prvA *ecdsa.PrivateKey // dummy private key for addrA

	addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
	addrDAI  = w3.A("0x6B175474E89094C44Da98b954EedeAC495271d0F")

	client = w3.MustDial("https://ethereum-rpc.publicnode.com")
)

// Call the name, symbol, decimals, and balanceOf functions of the Wrapped Ether
// in a single batch.
func ExampleClient_batchCallFunc() {
	blockNumber := big.NewInt(20_000_000)

	var (
		name, symbol string
		decimals     uint8
		balance      big.Int
	)
	if err := client.Call(
		eth.CallFunc(addrWETH, funcName).Returns(&name),
		eth.CallFunc(addrWETH, funcSymbol).Returns(&symbol),
		eth.CallFunc(addrWETH, funcDecimals).Returns(&decimals),
		eth.CallFunc(addrWETH, funcBalanceOf, addrWETH).AtBlock(blockNumber).Returns(&balance),
	); err != nil {
		// ...
	}

	fmt.Printf("%s's own balance: %s %s\n", name, w3.FromWei(&balance, decimals), symbol)
	// Output:
	// Wrapped Ether's own balance: 748.980125465356473638 WETH
}

// Call the Uniswap V3 Quoter for quotes on swapping 100 WETH for DAI in pools
// of all fee tiers in a single batch.
func ExampleClient_batchCallFuncUniswapQuoter() {
	blockNumber := big.NewInt(20_000_000)

	var (
		addrUniswapV3Quoter = w3.A("0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6")
		addrTokenIn         = addrWETH
		addrTokenOut        = addrDAI

		funcQuote = w3.MustNewFunc(`quoteExactInputSingle(
			address tokenIn,
			address tokenOut,
			uint24 fee,
			uint256 amountIn,
			uint160 sqrtPriceLimitX96clear
		)`, "uint256 amountOut")
	)

	var (
		amountIn       = w3.I("100 ether")
		amountOut100   *big.Int
		amountOut500   *big.Int
		amountOut3000  *big.Int
		amountOut10000 *big.Int
	)
	if err := client.Call(
		eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(100), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut100),
		eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(500), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut500),
		eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(3000), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut3000),
		eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(10000), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut10000),
	); err != nil {
		// ...
	}
	fmt.Println("Swap 100 WETH for DAI:")
	fmt.Printf("Pool with 0.01%% fee: %s DAI\n", w3.FromWei(amountOut100, 18))
	fmt.Printf("Pool with 0.05%% fee: %s DAI\n", w3.FromWei(amountOut500, 18))
	fmt.Printf("Pool with  0.3%% fee: %s DAI\n", w3.FromWei(amountOut3000, 18))
	fmt.Printf("Pool with    1%% fee: %s DAI\n", w3.FromWei(amountOut10000, 18))
	// Output:
	// Swap 100 WETH for DAI:
	// Pool with 0.01% fee: 0.840975419471618588 DAI
	// Pool with 0.05% fee: 371877.453117609415215338 DAI
	// Pool with  0.3% fee: 378532.856217317782434539 DAI
	// Pool with    1% fee: 3447.634026125332130689 DAI
}

// Fetch the nonce and balance of an EOA in a single batch.
func ExampleClient_batchEOAState() {
	var (
		nonce   uint64
		balance *big.Int
	)
	if err := client.Call(
		eth.Nonce(addrA, nil).Returns(&nonce),
		eth.Balance(addrA, nil).Returns(&balance),
	); err != nil {
		// ...
	}

	fmt.Printf("Nonce: %d\nBalance: %d\n", nonce, balance)
}

// Fetch a transaction and its receipt in a single batch.
func ExampleClient_batchTxDetails() {
	txHash := w3.H("0xc31d7e7e85cab1d38ce1b8ac17e821ccd47dbde00f9d57f2bd8613bff9428396")

	var (
		tx      *types.Transaction
		receipt *types.Receipt
	)
	if err := client.Call(
		eth.Tx(txHash).Returns(&tx),
		eth.TxReceipt(txHash).Returns(&receipt),
	); err != nil {
		// ...
	}

	fmt.Printf("Tx: %#v\nReceipt: %#v\n", tx, receipt)
}

// Fetch 1000 blocks in batches.
func ExampleClient_batchBlocks() {
	const (
		startBlock = 20_000_000
		nBlocks    = 1000
		batchSize  = 100
	)

	blocks := make([]*types.Block, nBlocks)
	calls := make([]w3types.RPCCaller, batchSize)
	for i := 0; i < nBlocks; i += batchSize {
		for j := range batchSize {
			blockNumber := new(big.Int).SetUint64(uint64(startBlock + i + j))
			calls[j] = eth.BlockByNumber(blockNumber).Returns(&blocks[i+j])
		}
		if err := client.Call(calls...); err != nil {
			// ...
		}
		fmt.Printf("Fetched %d blocks\n", i+batchSize)
	}
}

// Handle errors of individual calls in a batch.
func ExampleClient_batchHandleError() {
	tokens := []common.Address{addrWETH, addrA, addrB}
	symbols := make([]string, len(tokens))

	// build rpc calls
	calls := make([]w3types.RPCCaller, len(tokens))
	for i, token := range tokens {
		calls[i] = eth.CallFunc(token, funcSymbol).Returns(&symbols[i])
	}

	var batchErr w3.CallErrors
	if err := client.Call(calls...); errors.As(err, &batchErr) {
	} else if err != nil {
		// all calls failed
	}

	for i, symbol := range symbols {
		if len(batchErr) > 0 && batchErr[i] != nil {
			symbol = "call failed"
		}
		fmt.Printf("%s: %s\n", tokens[i], symbol)
	}
	// Output:
	// 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2: WETH
	// 0x0a00000000000000000000000000000000000000: call failed
	// 0x0B00000000000000000000000000000000000000: call failed
}

// Fetch the token balance of an address.
func ExampleClient_callFunc() {
	var balance *big.Int
	if err := client.Call(
		eth.CallFunc(addrWETH, funcBalanceOf, addrA).Returns(&balance),
	); err != nil {
		// ...
	}

	fmt.Printf("Balance: %s WETH\n", w3.FromWei(balance, 18))
	// Output:
	// Balance: 0 WETH
}

// Fetch the token balance of an address, with state override.
func ExampleClient_callFuncWithStateOverride() {
	var balance *big.Int
	if err := client.Call(
		eth.CallFunc(addrWETH, funcBalanceOf, addrA).Overrides(w3types.State{
			addrWETH: {Storage: w3types.Storage{
				w3vm.WETHBalanceSlot(addrA): common.BigToHash(w3.I("100 ether")),
			}},
		}).Returns(&balance),
	); err != nil {
		// ...
	}

	fmt.Printf("Balance: %s WETH\n", w3.FromWei(balance, 18))
	// Output:
	// Balance: 100 WETH
}

// Send Ether transfer.
func ExampleClient_sendETHTransfer() {
	var (
		nonce    uint64
		gasPrice *big.Int
	)
	if err := client.Call(
		eth.Nonce(addrA, nil).Returns(&nonce),
		eth.GasPrice().Returns(&gasPrice),
	); err != nil {
		// ...
	}

	signer := types.LatestSigner(params.MainnetChainConfig)
	tx := types.MustSignNewTx(prvA, signer, &types.LegacyTx{
		Nonce:    nonce,
		Gas:      21_000,
		GasPrice: gasPrice,
		To:       &addrB,
		Value:    w3.I("1 ether"),
	})

	var txHash common.Hash
	if err := client.Call(eth.SendTx(tx).Returns(&txHash)); err != nil {
		// ...
	}

	fmt.Printf("Sent tx: %s\n", txHash)
}

// Send ERC20 token transfer (Wrapped Ether).
func ExampleClient_sendTokenTransfer() {
	var (
		nonce    uint64
		gasPrice *big.Int
	)
	if err := client.Call(
		eth.Nonce(addrA, nil).Returns(&nonce),
		eth.GasPrice().Returns(&gasPrice),
	); err != nil {
		// ...
	}

	funcTransfer := w3.MustNewFunc("transfer(address receiver, uint256 amount)", "bool")
	data, err := funcTransfer.EncodeArgs(addrB, w3.I("1 ether"))
	if err != nil {
		// ...
	}

	signer := types.LatestSigner(params.MainnetChainConfig)
	tx := types.MustSignNewTx(prvA, signer, &types.LegacyTx{
		Nonce:    nonce,
		Gas:      100_000,
		GasPrice: gasPrice,
		To:       &addrWETH,
		Data:     data,
	})

	var txHash common.Hash
	if err := client.Call(eth.SendTx(tx).Returns(&txHash)); err != nil {
		// ...
	}

	fmt.Printf("Sent tx: %s\n", txHash)
}

// Subscribe to pending transactions.
func ExampleClient_subscribeToPendingTransactions() {
	client, err := w3.Dial("wss://mainnet.gateway.tenderly.co")
	if err != nil {
		// ...
	}
	defer client.Close()

	pendingTxCh := make(chan *types.Transaction)
	sub, err := client.Subscribe(eth.PendingTransactions(pendingTxCh))
	if err != nil {
		// ...
	}

	for {
		select {
		case tx := <-pendingTxCh:
			fmt.Printf("New pending tx: %s\n", tx.Hash())
		case err := <-sub.Err():
			fmt.Printf("Subscription error: %v\n", err)
			return
		}
	}
}

// Rate Limit the number of requests to 10 per second, with bursts of up to 20
// requests.
func ExampleClient_rateLimitByRequest() {
	client, err := w3.Dial("https://ethereum-rpc.publicnode.com",
		w3.WithRateLimiter(rate.NewLimiter(rate.Every(time.Second/10), 20), nil),
	)
	if err != nil {
		// ...
	}
	defer client.Close()
}

// Rate Limit the number of requests to 300 compute units (CUs) per second, with
// bursts of up to 300 CUs.
// An individual CU can be charged per RPC method call.
func ExampleClient_rateLimitByComputeUnits() {
	// cu returns the CU cost for all method calls in a batch.
	cu := func(methods []string) (cost int) {
		for _, method := range methods {
			switch method {
			case "eth_blockNumber":
				cost += 5
			case "eth_getBalance",
				"eth_getBlockByNumber",
				"eth_getCode",
				"eth_getStorageAt",
				"eth_getTransactionByHash",
				"eth_getTransactionReceipt":
				cost += 15
			case "eth_call":
				cost += 20
			case "eth_getTransactionCount":
				cost += 25
			default:
				panic(fmt.Sprintf("unknown costs for %q", method))
			}
		}
		return cost
	}

	client, err := w3.Dial("https://ethereum-rpc.publicnode.com",
		w3.WithRateLimiter(rate.NewLimiter(rate.Every(time.Second/300), 300), cu),
	)
	if err != nil {
		// ...
	}
	defer client.Close()
}

// ABI bindings for the ERC20 functions.
func ExampleFunc_erc20() {
	var (
		funcTotalSupply  = w3.MustNewFunc("totalSupply()", "uint256")
		funcBalanceOf    = w3.MustNewFunc("balanceOf(address)", "uint256")
		funcTransfer     = w3.MustNewFunc("transfer(address to, uint256 amount)", "bool")
		funcAllowance    = w3.MustNewFunc("allowance(address owner, address spender)", "uint256")
		funcApprove      = w3.MustNewFunc("approve(address spender, uint256 amount)", "bool")
		funcTransferFrom = w3.MustNewFunc("transferFrom(address from, address to, uint256 amount)", "bool")
	)
	_ = funcTotalSupply
	_ = funcBalanceOf
	_ = funcTransfer
	_ = funcAllowance
	_ = funcApprove
	_ = funcTransferFrom
}

// Encode and decode the arguments of the balanceOf function.
func ExampleFunc_balanceOf() {
	// encode
	input, err := funcBalanceOf.EncodeArgs(addrA)
	if err != nil {
		// ...
	}
	fmt.Printf("encoded: 0x%x\n", input)

	// decode
	var who common.Address
	if err := funcBalanceOf.DecodeArgs(input, &who); err != nil {
		// ...
	}
	fmt.Printf("decoded: balanceOf(%s)\n", who)
	// Output:
	// encoded: 0x70a082310000000000000000000000000a00000000000000000000000000000000000000
	// decoded: balanceOf(0x0a00000000000000000000000000000000000000)
}

// ABI bindings for the Uniswap v4 swap function.
func ExampleFunc_uniswapV4Swap() {
	// ABI binding for the PoolKey struct.
	type PoolKey struct {
		Currency0   common.Address
		Currency1   common.Address
		Fee         *big.Int `abitype:"uint24"`
		TickSpacing *big.Int `abitype:"int24"`
		Hooks       common.Address
	}

	// ABI binding for the SwapParams struct.
	type SwapParams struct {
		ZeroForOne        bool
		AmountSpecified   *big.Int `abitype:"int256"`
		SqrtPriceLimitX96 *big.Int `abitype:"uint160"`
	}

	funcSwap := w3.MustNewFunc(`swap(PoolKey key, SwapParams params, bytes hookData)`, "int256 delta",
		PoolKey{}, SwapParams{},
	)

	// encode
	input, _ := funcSwap.EncodeArgs(
		&PoolKey{
			Currency0:   addrWETH,
			Currency1:   addrDAI,
			Fee:         big.NewInt(0),
			TickSpacing: big.NewInt(0),
		},
		&SwapParams{
			ZeroForOne:        false,
			AmountSpecified:   big.NewInt(0),
			SqrtPriceLimitX96: big.NewInt(0),
		},
		[]byte{},
	)
	fmt.Printf("encoded: 0x%x\n", input)
	// Output:
	// encoded: 0xf3cd914c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000
}

func ExampleFunc_DecodeReturns_getReserves() {
	funcGetReserves := w3.MustNewFunc("getReserves()", "uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast")
	output := w3.B(
		"0x00000000000000000000000000000000000000000000003635c9adc5dea00000",
		"0x0000000000000000000000000000000000000000000000a2a15d09519be00000",
		"0x0000000000000000000000000000000000000000000000000000000064373057",
	)

	var (
		reserve0, reserve1 *big.Int
		blockTimestampLast uint32
	)
	if err := funcGetReserves.DecodeReturns(output, &reserve0, &reserve1, &blockTimestampLast); err != nil {
		// ...
	}
	fmt.Println("Reserve0:", reserve0)
	fmt.Println("Reserve1:", reserve1)
	fmt.Println("BlockTimestampLast:", blockTimestampLast)
	// Output:
	// Reserve0: 1000000000000000000000
	// Reserve1: 3000000000000000000000
	// BlockTimestampLast: 1681338455
}

func ExampleEvent_decodeTransferEvent() {
	var (
		eventTransfer = w3.MustNewEvent("Transfer(address indexed from, address indexed to, uint256 value)")
		log           = &types.Log{
			Address: w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
			Topics: []common.Hash{
				w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
				w3.H("0x000000000000000000000000000000000000000000000000000000000000c0fe"),
				w3.H("0x000000000000000000000000000000000000000000000000000000000000dead"),
			},
			Data: w3.B("0x0000000000000000000000000000000000000000000000001111d67bb1bb0000"),
		}

		from  common.Address
		to    common.Address
		value big.Int
	)

	if err := eventTransfer.DecodeArgs(log, &from, &to, &value); err != nil {
		fmt.Printf("Failed to decode event log: %v\n", err)
		return
	}
	fmt.Printf("Transferred %s WETH9 from %s to %s", w3.FromWei(&value, 18), from, to)
	// Output:
	// Transferred 1.23 WETH9 from 0x000000000000000000000000000000000000c0Fe to 0x000000000000000000000000000000000000dEaD
}


================================================
FILE: func.go
================================================
package w3

import (
	"bytes"
	"errors"
	"fmt"

	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/ethereum/go-ethereum/crypto"
	_abi "github.com/lmittmann/w3/internal/abi"
)

var (
	ErrInvalidABI       = errors.New("w3: invalid ABI")
	ErrArgumentMismatch = errors.New("w3: argument mismatch")
	ErrReturnsMismatch  = errors.New("w3: returns mismatch")
	ErrInvalidType      = errors.New("w3: invalid type")
	ErrEvmRevert        = errors.New("w3: evm reverted")

	revertSelector       = selector("Error(string)")
	outputSuccess        = B("0x0000000000000000000000000000000000000000000000000000000000000001")
	approveSelector      = selector("approve(address,uint256)")
	transferSelector     = selector("transfer(address,uint256)")
	transferFromSelector = selector("transferFrom(address,address,uint256)")
)

// Func represents a Smart Contract function ABI binding.
//
// Func implements the [w3types.Func] interface.
type Func struct {
	Signature string        // Function signature
	Selector  [4]byte       // 4-byte selector
	Args      abi.Arguments // Arguments (input)
	Returns   abi.Arguments // Returns (output)

	name string // Function name
}

// NewFunc returns a new Smart Contract function ABI binding from the given
// Solidity function signature and its returns.
//
// The optional tuples parameter accepts struct definitions that can be
// referenced by name in the signature instead of using inline tuple
// definitions. This enables cleaner, more readable function signatures when
// working with complex tuple types.
//
// Examples:
//
//	// Without named tuples (inline)
//	NewFunc("transfer((address,uint256))", "bool")
//
//	// With named tuple
//	type Token struct { To common.Address; Amount *big.Int }
//	NewFunc("transfer(Token)", "bool", Token{})
//
// An error is returned if the signature or returns parsing fails.
func NewFunc(signature, returns string, tuples ...any) (*Func, error) {
	name, args, err := _abi.ParseWithName(signature, tuples...)
	if err != nil {
		return nil, fmt.Errorf("%w: %v", ErrInvalidABI, err)
	}
	if name == "" {
		return nil, fmt.Errorf("%w: missing function name", ErrInvalidABI)
	}

	returnArgs, err := _abi.Parse(returns, tuples...)
	if err != nil {
		return nil, fmt.Errorf("%w: %v", ErrInvalidABI, err)
	}

	sig := args.SignatureWithName(name)
	return &Func{
		Signature: sig,
		Selector:  selector(sig),
		Args:      abi.Arguments(args),
		Returns:   abi.Arguments(returnArgs),
		name:      name,
	}, nil
}

// MustNewFunc is like [NewFunc] but panics if the signature or returns parsing
// fails.
func MustNewFunc(signature, returns string, tuples ...any) *Func {
	fn, err := NewFunc(signature, returns, tuples...)
	if err != nil {
		panic(err)
	}
	return fn
}

// EncodeArgs ABI-encodes the given args and prepends the Func's 4-byte
// selector.
func (f *Func) EncodeArgs(args ...any) ([]byte, error) {
	return _abi.Arguments(f.Args).EncodeWithSelector(f.Selector, args...)
}

// DecodeArgs ABI-decodes the given input to the given args.
func (f *Func) DecodeArgs(input []byte, args ...any) error {
	if len(input) < 4 {
		return errors.New("w3: insufficient input length")
	}
	if !bytes.Equal(input[:4], f.Selector[:]) {
		return errors.New("w3: input does not match selector")
	}
	return _abi.Arguments(f.Args).Decode(input[4:], args...)
}

// DecodeReturns ABI-decodes the given output to the given returns.
func (f *Func) DecodeReturns(output []byte, returns ...any) error {
	// check the output for a revert reason
	if bytes.HasPrefix(output, revertSelector[:]) {
		if reason, err := abi.UnpackRevert(output); err != nil {
			return err
		} else {
			return fmt.Errorf("%w: %s", ErrEvmRevert, reason)
		}
	}

	// Gracefully handle uncompliant ERC20 returns
	if len(returns) == 1 && len(output) == 0 &&
		(f.Selector == approveSelector ||
			f.Selector == transferSelector ||
			f.Selector == transferFromSelector) {
		output = outputSuccess
	}

	return _abi.Arguments(f.Returns).Decode(output, returns...)
}

// selector returns the 4-byte selector of the given signature.
func selector(signature string) (selector [4]byte) {
	copy(selector[:], crypto.Keccak256([]byte(signature)))
	return
}


================================================
FILE: func_test.go
================================================
package w3_test

import (
	"bytes"
	"errors"
	"math/big"
	"strconv"
	"testing"

	"github.com/ethereum/go-ethereum/common"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"github.com/lmittmann/w3"
	"github.com/lmittmann/w3/internal"
	"github.com/lmittmann/w3/w3types"
)

func TestNewFunc(t *testing.T) {
	tests := []struct {
		Signature string
		Returns   string
		Tuples    []any
		WantFunc  *w3.Func
	}{
		{
			Signature: "transfer(address,uint256)",
			Returns:   "bool",
			WantFunc: &w3.Func{
				Signature: "transfer(address,uint256)",
				Selector:  [4]byte{0xa9, 0x05, 0x9c, 0xbb},
			},
		},
		{
			Signature: "transfer(address recipient, uint256 amount)",
			Returns:   "bool success",
			WantFunc: &w3.Func{
				Signature: "transfer(address,uint256)",
				Selector:  [4]byte{0xa9, 0x05, 0x9c, 0xbb},
			},
		},
		{
			Signature: "testTuple(tuple)",
			Returns:   "bool",
			Tuples:    []any{tuple{}},
			WantFunc: &w3.Func{
				Signature: "testTuple((address,uint256))",
				Selector:  [4]byte{0xa0, 0x54, 0xdf, 0xd5},
			},
		},
		{
			Signature: "testTuple(tupleWithTag)",
			Returns:   "bool",
			Tuples:    []any{tupleWithTag{}},
			WantFunc: &w3.Func{
				Signature: "testTuple((address,uint128))",
				Selector:  [4]byte{0xa8, 0x97, 0xff, 0xb3},
			},
		},
		{
			Signature: "testTuple(tupleWithNesting)",
			Returns:   "bool",
			Tuples:    []any{tupleWithNesting{}},
			WantFunc: &w3.Func{
				Signature: "testTuple((address,(address,uint256)))",
				Selector:  [4]byte{0xff, 0x4c, 0x07, 0xd1},
			},
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			gotFunc, err := w3.NewFunc(test.Signature, test.Returns, test.Tuples...)
			if err != nil {
				t.Fatalf("Failed to create new FUnc: %v", err)
			}

			if diff := cmp.Diff(test.WantFunc, gotFunc,
				cmpopts.IgnoreFields(w3.Func{}, "Args", "Returns", "name"),
			); diff != "" {
				t.Fatalf("(-want, +got)\n%s", diff)
			}
		})
	}
}

func TestFuncEncodeArgs(t *testing.T) {
	tests := []struct {
		Func w3types.Func
		Args []any
		Want []byte
	}{
		{
			Func: w3.MustNewFunc("balanceOf(address who)", "uint256 balance"),
			Args: []any{w3.A("0x000000000000000000000000000000000000dEaD")},
			Want: w3.B("0x70a08231000000000000000000000000000000000000000000000000000000000000dEaD"),
		},
		{
			Func: w3.MustNewFunc("transfer(address recipient, uint256 amount)", "bool success"),
			Args: []any{w3.A("0x000000000000000000000000000000000000dEaD"), big.NewInt(1)},
			Want: w3.B("0xa9059cbb000000000000000000000000000000000000000000000000000000000000dEaD0000000000000000000000000000000000000000000000000000000000000001"),
		},
		{
			Func: w3.MustNewFunc("name()", "string"),
			Args: []any{},
			Want: w3.B("0x06fdde03"),
		},
		{
			Func: w3.MustNewFunc("withdraw(uint256)", ""),
			Args: []any{big.NewInt(1)},
			Want: w3.B("0x2e1a7d4d0000000000000000000000000000000000000000000000000000000000000001"),
		},
		{
			Func: w3.MustNewFunc("getAmountsOut(uint256,address[])", "uint256[]"),
			Args: []any{big.NewInt(1), []common.Address{w3.A("0x1111111111111111111111111111111111111111"), w3.A("0x2222222222222222222222222222222222222222")}},
			Want: w3.B("0xd06ca61f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000011111111111111111111111111111111111111110000000000000000000000002222222222222222222222222222222222222222"),
		},
		{
			Func: w3.MustNewFunc("test((address arg0, uint256 arg1))", ""),
			Args: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
			Want: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
		},
		{
			Func: w3.MustNewFunc("test((address arg0, uint256 arg1))", ""),
			Args: []any{&tupleWithWrongOrder{
				Arg1: big.NewInt(42),
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
			}},
			Want: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
		},
		{
			Func: w3.MustNewFunc("test((address arg0, uint256 arg1))", ""),
			Args: []any{&tupleWithMoreArgs{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
				Arg2: big.NewInt(7),
			}},
			Want: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
		},
		{
			Func: w3.MustNewFunc("test((address arg0, uint256 arg1)[] args)", ""),
			Args: []any{
				[]tuple{
					{Arg0: w3.A("0x1111111111111111111111111111111111111111"), Arg1: big.NewInt(7)},
					{Arg0: w3.A("0x2222222222222222222222222222222222222222"), Arg1: big.NewInt(42)},
				},
			},
			Want: w3.B("0xae4f5efa00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000070000000000000000000000002222222222222222222222222222222222222222000000000000000000000000000000000000000000000000000000000000002a"),
		},
		{
			Func: w3.MustNewFunc("test((address arg0, bytes arg1)[] calls)", ""),
			Args: []any{
				[]tupleWithBytes{
					{Arg0: w3.A("0x1111111111111111111111111111111111111111"), Arg1: w3.B("0xc0fe")},
					{Arg0: w3.A("0x2222222222222222222222222222222222222222"), Arg1: w3.B("0xdeadbeef")},
				},
			},
			Want: w3.B("0x3a91207700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002c0fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"),
		},
		{
			Func: w3.MustNewFunc("test(tupleWithBytes[] calls)", "", tupleWithBytes{}),
			Args: []any{
				[]tupleWithBytes{
					{Arg0: w3.A("0x1111111111111111111111111111111111111111"), Arg1: w3.B("0xc0fe")},
					{Arg0: w3.A("0x2222222222222222222222222222222222222222"), Arg1: w3.B("0xdeadbeef")},
				},
			},
			Want: w3.B("0x3a91207700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002c0fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"),
		},
		{
			Func: w3.MustNewFunc("test(uint[])", ""),
			Args: []any{
				[]*big.Int{big.NewInt(0xdead), big.NewInt(0xbeef)},
			},
			Want: w3.B("0xca16068400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
		},
		{
			Func: w3.MustNewFunc("test(uint[2])", ""),
			Args: []any{
				[2]*big.Int{big.NewInt(0xdead), big.NewInt(0xbeef)},
			},
			Want: w3.B("0xf1635056000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
		},
		{
			Func: w3.MustNewFunc("test(uint64[])", ""),
			Args: []any{
				[]uint64{0xdead, 0xbeef},
			},
			Want: w3.B("0xd3469fbd00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
		},
		{
			Func: w3.MustNewFunc("test(uint64[2])", ""),
			Args: []any{
				[2]uint64{0xdead, 0xbeef},
			},
			Want: w3.B("0x533d6285000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
		},
		{
			Func: w3.MustNewFunc("testTuple(tuple)", "bool", tuple{}),
			Args: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
			Want: w3.B("0xa054dfd5000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
		},
		{ // https://github.com/lmittmann/w3/issues/35
			Func: w3.MustNewFunc("test(((address to)[] recipients) param)", ""),
			Args: []any{
				&tupleIssue35{Recipients: []struct {
					To common.Address
				}{
					{To: w3.A("0x1111111111111111111111111111111111111111")},
					{To: w3.A("0x2222222222222222222222222222222222222222")},
				}},
			},
			Want: w3.B("0xf61d1a2a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000011111111111111111111111111111111111111110000000000000000000000002222222222222222222222222222222222222222"),
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			encodedInput, err := test.Func.EncodeArgs(test.Args...)
			if err != nil {
				t.Fatalf("Failed to encode args: %v", err)
			}

			if !bytes.Equal(test.Want, encodedInput) {
				t.Fatalf("(-want, +got)\n- 0x%x\n+ 0x%x", test.Want, encodedInput)
			}
		})
	}
}

func TestFuncDecodeArgs(t *testing.T) {
	tests := []struct {
		Func     w3types.Func
		Input    []byte
		Args     []any
		WantArgs []any
		WantErr  error
	}{
		{
			Func:     w3.MustNewFunc("test(address)", ""),
			Input:    w3.B("0xbb29998e000000000000000000000000000000000000000000000000000000000000c0fe"),
			Args:     []any{new(common.Address)},
			WantArgs: []any{w3.APtr("0x000000000000000000000000000000000000c0Fe")},
		},
		{
			Func:     w3.MustNewFunc("test(uint256)", ""),
			Input:    w3.B("0x29e99f07000000000000000000000000000000000000000000000000000000000000002a"),
			Args:     []any{new(big.Int)},
			WantArgs: []any{big.NewInt(42)},
		},
		{
			Func:     w3.MustNewFunc("test(bool)", ""),
			Input:    w3.B("0x36091dff0000000000000000000000000000000000000000000000000000000000000001"),
			Args:     []any{ptr(false)},
			WantArgs: []any{ptr(true)},
		},
		{
			Func:     w3.MustNewFunc("test(bytes32)", ""),
			Input:    w3.B("0x993723210102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"),
			Args:     []any{&[32]byte{}},
			WantArgs: []any{&[32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}},
		},
		{
			Func:     w3.MustNewFunc("test(bytes32)", ""),
			Input:    w3.B("0x993723210102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"),
			Args:     []any{new(common.Hash)},
			WantArgs: []any{ptr(w3.H("0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"))},
		},
		{
			Func:     w3.MustNewFunc("test(bytes)", ""),
			Input:    w3.B("0x2f570a23000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030102030000000000000000000000000000000000000000000000000000000000"),
			Args:     []any{&[]byte{}},
			WantArgs: []any{&[]byte{1, 2, 3}},
		},
		{
			Func:  w3.MustNewFunc("test((address arg0, uint256 arg1))", ""),
			Input: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tuple)},
			WantArgs: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
		},
		{
			Func:  w3.MustNewFunc("test(tuple)", "", tuple{}),
			Input: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tuple)},
			WantArgs: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
		},
		{
			// https://github.com/lmittmann/w3/issues/67
			Func:     w3.MustNewFunc("test((address, uint256))", ""),
			Input:    w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:     []any{nil},
			WantArgs: []any{nil},
		},
		{
			// https://github.com/lmittmann/w3/issues/67
			Func:  w3.MustNewFunc("test((address, uint256))", ""),
			Input: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tuple)},
			WantArgs: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
		},
		{
			// https://github.com/lmittmann/w3/issues/67
			Func:  w3.MustNewFunc("test((address, (address, uint256)))", ""),
			Input: w3.B("0x1a68b84c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tupleNested)},
			WantArgs: []any{&tupleNested{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: tuple{
					Arg0: w3.A("0x000000000000000000000000000000000000dEaD"),
					Arg1: big.NewInt(42),
				},
			}},
		},
		{
			Func:  w3.MustNewFunc("test((address arg0, uint256 arg1))", ""),
			Input: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tupleWithWrongOrder)},
			WantArgs: []any{&tupleWithWrongOrder{
				Arg1: big.NewInt(42),
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
			}},
		},
		{
			Func:  w3.MustNewFunc("test((address arg0, uint256 arg1))", ""),
			Input: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tupleWithMoreArgs)},
			WantArgs: []any{&tupleWithMoreArgs{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
		},
		{ // https://github.com/lmittmann/w3/issues/22
			Func:    w3.MustNewFunc("transfer(address recipient, uint256 amount)", "bool success"),
			Input:   w3.B("0x"),
			Args:    []any{new(common.Address), new(big.Int)},
			WantErr: errors.New("w3: insufficient input length"),
		},
		{
			Func:  w3.MustNewFunc("test((address arg0, uint256 arg1))", ""),
			Input: w3.B("0xba71720c000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tupleWithUnexportedProperty)},
			WantArgs: []any{&tupleWithUnexportedProperty{
				Arg1: big.NewInt(42),
			}},
		},
		{
			Func:  w3.MustNewFunc("test((address arg0, bytes arg1)[] calls)", ""),
			Input: w3.B("0x3a91207700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002c0fe000000000000000000000000000000000000000000000000000000000000000000000000000000000000222222222222222222222222222222222222222200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004deadbeef00000000000000000000000000000000000000000000000000000000"),
			Args:  []any{&[]*tupleWithBytes{}},
			WantArgs: []any{
				&[]*tupleWithBytes{
					{Arg0: w3.A("0x1111111111111111111111111111111111111111"), Arg1: w3.B("0xc0fe")},
					{Arg0: w3.A("0x2222222222222222222222222222222222222222"), Arg1: w3.B("0xdeadbeef")},
				},
			},
		},
		{
			Func:  w3.MustNewFunc("test(uint[])", ""),
			Input: w3.B("0xca16068400000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
			Args:  []any{new([]*big.Int)},
			WantArgs: []any{
				&[]*big.Int{big.NewInt(0xdead), big.NewInt(0xbeef)},
			},
		},
		{
			Func:  w3.MustNewFunc("test(uint[2])", ""),
			Input: w3.B("0xf1635056000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
			Args:  []any{new([2]*big.Int)},
			WantArgs: []any{
				&[2]*big.Int{big.NewInt(0xdead), big.NewInt(0xbeef)},
			},
		},
		{
			Func:  w3.MustNewFunc("test(uint64[])", ""),
			Input: w3.B("0xd3469fbd00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
			Args:  []any{new([]uint64)},
			WantArgs: []any{
				&[]uint64{0xdead, 0xbeef},
			},
		},
		{
			Func:  w3.MustNewFunc("test(uint64[2])", ""),
			Input: w3.B("0x533d6285000000000000000000000000000000000000000000000000000000000000dead000000000000000000000000000000000000000000000000000000000000beef"),
			Args:  []any{new([2]uint64)},
			WantArgs: []any{
				&[2]uint64{0xdead, 0xbeef},
			},
		},
		{
			Func:  w3.MustNewFunc("testTuple(tuple)", "bool", tuple{}),
			Input: w3.B("0xa054dfd5000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Args:  []any{new(tuple)},
			WantArgs: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
		},
		{ // https://github.com/lmittmann/w3/issues/35
			Func:  w3.MustNewFunc("test(((address to)[] recipients) param)", ""),
			Input: w3.B("0xf61d1a2a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000011111111111111111111111111111111111111110000000000000000000000002222222222222222222222222222222222222222"),
			Args:  []any{new(tupleIssue35)},
			WantArgs: []any{
				&tupleIssue35{Recipients: []struct {
					To common.Address
				}{
					{To: w3.A("0x1111111111111111111111111111111111111111")},
					{To: w3.A("0x2222222222222222222222222222222222222222")},
				}},
			},
		},
		{
			Func:    w3.MustNewFunc("test(address)", ""),
			Input:   w3.B("0xffffffff000000000000000000000000000000000000000000000000000000000000c0fe"),
			Args:    []any{new(common.Address)},
			WantErr: errors.New("w3: input does not match selector"),
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			err := test.Func.DecodeArgs(test.Input, test.Args...)
			if diff := cmp.Diff(test.WantErr, err, internal.EquateErrors()); diff != "" {
				t.Fatalf("Err: (-want, +got)\n%s", diff)
			}
			if err != nil {
				return
			}

			if diff := cmp.Diff(test.WantArgs, test.Args,
				cmp.AllowUnexported(big.Int{}, tupleWithUnexportedProperty{}),
			); diff != "" {
				t.Fatalf("Args: (-want, +got)\n%s", diff)
			}
		})
	}
}

func TestFuncDecodeReturns(t *testing.T) {
	tests := []struct {
		Func        w3types.Func
		Output      []byte
		Returns     []any
		WantReturns []any
	}{
		{
			Func:        w3.MustNewFunc("test()", "address"),
			Output:      w3.B("0x000000000000000000000000000000000000000000000000000000000000c0fe"),
			Returns:     []any{new(common.Address)},
			WantReturns: []any{w3.APtr("0x000000000000000000000000000000000000c0Fe")},
		},
		{
			Func:        w3.MustNewFunc("test()", "uint256"),
			Output:      w3.B("0x000000000000000000000000000000000000000000000000000000000000002a"),
			Returns:     []any{new(big.Int)},
			WantReturns: []any{big.NewInt(42)},
		},
		{
			Func:        w3.MustNewFunc("test()", "bool"),
			Output:      w3.B("0x0000000000000000000000000000000000000000000000000000000000000001"),
			Returns:     []any{ptr(false)},
			WantReturns: []any{ptr(true)},
		},
		{
			Func:        w3.MustNewFunc("test()", "bytes32"),
			Output:      w3.B("0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"),
			Returns:     []any{&[32]byte{}},
			WantReturns: []any{&[32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}},
		},
		{
			Func:        w3.MustNewFunc("test()", "bytes32"),
			Output:      w3.B("0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"),
			Returns:     []any{new(common.Hash)},
			WantReturns: []any{ptr(w3.H("0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"))},
		},
		{
			Func:        w3.MustNewFunc("test()", "bytes"),
			Output:      w3.B("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030102030000000000000000000000000000000000000000000000000000000000"),
			Returns:     []any{&[]byte{}},
			WantReturns: []any{&[]byte{1, 2, 3}},
		},
		{ // https://github.com/lmittmann/w3/issues/25
			Func:    w3.MustNewFunc("test()", "(address arg0, uint256 arg1)"),
			Output:  w3.B("0x000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Returns: []any{new(tuple)},
			WantReturns: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
		},
		{
			Func:    w3.MustNewFunc("test()", "tuple", tuple{}),
			Output:  w3.B("0x000000000000000000000000000000000000000000000000000000000000c0fe000000000000000000000000000000000000000000000000000000000000002a"),
			Returns: []any{new(tuple)},
			WantReturns: []any{&tuple{
				Arg0: w3.A("0x000000000000000000000000000000000000c0Fe"),
				Arg1: big.NewInt(42),
			}},
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			if err := test.Func.DecodeReturns(test.Output, test.Returns...); err != nil {
				t.Fatalf("Failed to decode returns: %v", err)
			}
			if diff := cmp.Diff(test.WantReturns, test.Returns, cmp.AllowUnexported(big.Int{})); diff != "" {
				t.Fatalf("(-want, +got)\n%s", diff)
			}
		})
	}
}

func ptr[T any](v T) *T { return &v }

type tuple struct {
	Arg0 common.Address
	Arg1 *big.Int
}

type tupleWithTag struct {
	Arg0 common.Address `abitype:"address"`
	Arg1 *big.Int       `abitype:"uint128"`
}

type tupleWithNesting struct {
	Arg0 common.Address
	Arg1 tuple
}

type tupleWithBytes struct {
	Arg0 common.Address
	Arg1 []byte
}

type tupleWithUnexportedProperty struct {
	//lint:ignore U1000 ignore unused field
	arg0 common.Address
	Arg1 *big.Int
}

type tupleWithWrongOrder struct {
	Arg1 *big.Int
	Arg0 common.Address
}

type tupleWithMoreArgs struct {
	Arg0 common.Address
	Arg1 *big.Int
	Arg2 *big.Int // Arg that is missing in func signature
}

type tupleIssue35 struct {
	Recipients []struct {
		To common.Address
	}
}

type tupleNested struct {
	Arg0 common.Address
	Arg1 tuple
}

func BenchmarkFuncEncode(b *testing.B) {
	var (
		funcSwap   = w3.MustNewFunc("swap(uint amount0Out, uint amount1Out, address to, bytes data)", "")
		amount0Out = big.NewInt(1000000000000000000) // 1 ETH
		amount1Out = big.NewInt(0)                   // 0 token
		to         = w3.A("0x000000000000000000000000000000000000c0Fe")
		data       = []byte{}
	)

	b.ReportAllocs()
	b.ResetTimer()
	for range b.N {
		funcSwap.EncodeArgs(amount0Out, amount1Out, to, data)
	}
}


================================================
FILE: go.mod
================================================
module github.com/lmittmann/w3

go 1.25.0

require (
	github.com/charmbracelet/lipgloss v1.1.0
	github.com/ethereum/go-ethereum v1.17.1
	github.com/gofrs/flock v0.13.0
	github.com/google/go-cmp v0.7.0
	github.com/holiman/uint256 v1.3.2
	golang.org/x/time v0.15.0
)

require (
	github.com/Microsoft/go-winio v0.6.2 // indirect
	github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect
	github.com/StackExchange/wmi v1.2.1 // indirect
	github.com/VictoriaMetrics/fastcache v1.13.0 // indirect
	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
	github.com/bits-and-blooms/bitset v1.20.0 // indirect
	github.com/cespare/xxhash/v2 v2.3.0 // indirect
	github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
	github.com/charmbracelet/x/ansi v0.8.0 // indirect
	github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
	github.com/charmbracelet/x/term v0.2.1 // indirect
	github.com/consensys/gnark-crypto v0.18.1 // indirect
	github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect
	github.com/deckarep/golang-set/v2 v2.6.0 // indirect
	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
	github.com/emicklei/dot v1.6.2 // indirect
	github.com/ethereum/c-kzg-4844/v2 v2.1.6 // indirect
	github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab // indirect
	github.com/ferranbt/fastssz v0.1.4 // indirect
	github.com/go-logr/logr v1.4.3 // indirect
	github.com/go-logr/stdr v1.2.2 // indirect
	github.com/go-ole/go-ole v1.3.0 // indirect
	github.com/golang/snappy v1.0.0 // indirect
	github.com/gorilla/websocket v1.5.0 // indirect
	github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
	github.com/klauspost/cpuid/v2 v2.0.9 // indirect
	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
	github.com/mattn/go-isatty v0.0.20 // indirect
	github.com/mattn/go-runewidth v0.0.16 // indirect
	github.com/minio/sha256-simd v1.0.0 // indirect
	github.com/mitchellh/mapstructure v1.4.1 // indirect
	github.com/muesli/termenv v0.16.0 // indirect
	github.com/rivo/uniseg v0.4.7 // indirect
	github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
	github.com/supranational/blst v0.3.16 // indirect
	github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
	github.com/tklauser/go-sysconf v0.3.12 // indirect
	github.com/tklauser/numcpus v0.6.1 // indirect
	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
	go.opentelemetry.io/auto/sdk v1.2.1 // indirect
	go.opentelemetry.io/otel v1.39.0 // indirect
	go.opentelemetry.io/otel/metric v1.39.0 // indirect
	go.opentelemetry.io/otel/trace v1.39.0 // indirect
	golang.org/x/crypto v0.44.0 // indirect
	golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
	golang.org/x/sync v0.18.0 // indirect
	golang.org/x/sys v0.39.0 // indirect
	gopkg.in/yaml.v2 v2.4.0 // indirect
)


================================================
FILE: go.sum
================================================
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU=
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0=
github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU=
github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I=
github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8=
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4=
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw=
github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo=
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI=
github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg=
github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=
github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A=
github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
github.com/ethereum/c-kzg-4844/v2 v2.1.6 h1:xQymkKCT5E2Jiaoqf3v4wsNgjZLY0lRSkZn27fRjSls=
github.com/ethereum/c-kzg-4844/v2 v2.1.6/go.mod h1:8HMkUZ5JRv4hpw/XUrYWSQNAUzhHMg2UDb/U+5m+XNw=
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk=
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8=
github.com/ethereum/go-ethereum v1.17.1 h1:IjlQDjgxg2uL+GzPRkygGULPMLzcYWncEI7wbaizvho=
github.com/ethereum/go-ethereum v1.17.1/go.mod h1:7UWOVHL7K3b8RfVRea022btnzLCaanwHtBuH1jUCH/I=
github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY=
github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grafana/pyroscope-go v1.2.7 h1:VWBBlqxjyR0Cwk2W6UrE8CdcdD80GOFNutj0Kb1T8ac=
github.com/grafana/pyroscope-go v1.2.7/go.mod h1:o/bpSLiJYYP6HQtvcoVKiE9s5RiNgjYTj1DhiddP2Pc=
github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og=
github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330=
github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg=
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=
github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A=
github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0=
github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ=
github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4=
github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jqwYhE=
github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=


================================================
FILE: internal/abi/arguments.go
================================================
package abi

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/lmittmann/w3/internal/crypto"
)

// Arguments represents a slice of [abi.Argument]'s.
type Arguments []abi.Argument

func (a Arguments) Signature() string {
	if len(a) <= 0 {
		return ""
	}

	fields := make([]string, len(a))
	for i, arg := range a {
		fields[i] = typeToString(&arg.Type)
	}
	return strings.Join(fields, ",")
}

func (a Arguments) SignatureWithName(name string) string {
	return name + "(" + a.Signature() + ")"
}

// Encode ABI-encodes the given arguments args.
func (a Arguments) Encode(args ...any) ([]byte, error) {
	data, err := abi.Arguments(a).PackValues(args)
	if err != nil {
		return nil, err
	}
	return data, nil
}

// EncodeWithSelector ABI-encodes the given arguments args prepended by the
// given selector.
func (a Arguments) EncodeWithSelector(selector [4]byte, args ...any) ([]byte, error) {
	data, err := a.Encode(args...)
	if err != nil {
		return nil, err
	}

	data = append(selector[:], data...)
	return data, nil
}

// EncodeWithSignature ABI-encodes the given arguments args prepended by the
// first 4 bytes of the hash of the given signature.
func (a Arguments) EncodeWithSignature(signature string, args ...any) ([]byte, error) {
	var selector [4]byte
	copy(selector[:], crypto.Keccak256([]byte(signature))[:4])

	return a.EncodeWithSelector(selector, args...)
}

// Decode ABI-decodes the given data to the given arguments args.
func (a Arguments) Decode(data []byte, args ...any) error {
	values, err := abi.Arguments(a).UnpackValues(data)
	if err != nil {
		return err
	}

	for i, arg := range args {
		// discard if arg is nil
		if arg == nil {
			continue
		}

		if err := Copy(arg, values[i]); err != nil {
			return err
		}
	}
	return nil
}

// typeToString returns the string representation of a [abi.Type].
func typeToString(t *abi.Type) string {
	switch t.T {
	case abi.IntTy:
		return "int" + strconv.Itoa(t.Size)
	case abi.UintTy:
		return "uint" + strconv.Itoa(t.Size)
	case abi.BoolTy:
		return "bool"
	case abi.StringTy:
		return "string"
	case abi.SliceTy:
		return typeToString(t.Elem) + "[]"
	case abi.ArrayTy:
		return typeToString(t.Elem) + "[" + strconv.Itoa(t.Size) + "]"
	case abi.TupleTy:
		fields := make([]string, len(t.TupleElems))
		for i, elem := range t.TupleElems {
			fields[i] = typeToString(elem)
		}
		return "(" + strings.Join(fields, ",") + ")"
	case abi.AddressTy:
		return "address"
	case abi.FixedBytesTy:
		return "bytes" + strconv.Itoa(t.Size)
	case abi.BytesTy:
		return "bytes"
	case abi.HashTy:
		return "hash"
	default:
		panic(fmt.Sprintf("unsupported type %v", t))
	}
}


================================================
FILE: internal/abi/arguments_test.go
================================================
package abi

import (
	"bytes"
	"math/big"
	"reflect"
	"strconv"
	"testing"

	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/ethereum/go-ethereum/common"
	"github.com/google/go-cmp/cmp"
)

func TestSignature(t *testing.T) {
	tests := []struct {
		Args          Arguments
		WantSignature string
	}{
		{
			Args:          Arguments{},
			WantSignature: "",
		},
		{
			Args:          Arguments{{Type: typeUint256}},
			WantSignature: "uint256",
		},
		{
			Args:          Arguments{{Type: abi.Type{Elem: &typeUint256, T: abi.SliceTy}}},
			WantSignature: "uint256[]",
		},
		{
			Args:          Arguments{{Type: abi.Type{Elem: &typeUint256, T: abi.ArrayTy, Size: 3}}},
			WantSignature: "uint256[3]",
		},
		{
			Args: Arguments{{
				Type: abi.Type{
					T:             abi.TupleTy,
					TupleElems:    []*abi.Type{&typeUint256},
					TupleRawNames: []string{"arg0"},
				},
			}},
			WantSignature: "(uint256)",
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			gotSignature := test.Args.Signature()
			if test.WantSignature != gotSignature {
				t.Fatalf("want %q, got %q", test.WantSignature, gotSignature)
			}
		})
	}
}

func TestSignatureWithName(t *testing.T) {
	tests := []struct {
		Arguments     Arguments
		Name          string
		WantSignature string
	}{
		{
			Arguments:     Arguments{},
			Name:          "func",
			WantSignature: "func()",
		},
		{
			Arguments:     Arguments{{Type: typeUint256}},
			Name:          "func",
			WantSignature: "func(uint256)",
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			gotSignature := test.Arguments.SignatureWithName(test.Name)
			if test.WantSignature != gotSignature {
				t.Fatalf("want %q, got %q", test.WantSignature, gotSignature)
			}
		})
	}
}

func TestEncode(t *testing.T) {
	tests := []struct {
		Arguments Arguments
		Args      []any
		WantData  []byte
	}{
		{
			Arguments: Arguments{{Type: typeUint256}},
			Args:      []any{big.NewInt(1)},
			WantData:  common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000001"),
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			gotData, err := test.Arguments.Encode(test.Args...)
			if err != nil {
				t.Fatalf("Failed to encode args: %v", err)
			}
			if !bytes.Equal(test.WantData, gotData) {
				t.Fatalf("\nwant 0x%x\ngot  0x%x", test.WantData, gotData)
			}
		})
	}
}

func TestEncodeWithSelector(t *testing.T) {
	tests := []struct {
		Arguments Arguments
		Selector  [4]byte
		Args      []any
		WantData  []byte
	}{
		{
			Arguments: Arguments{{Type: typeUint256}},
			Selector:  [4]byte{0x12, 0x34, 0x56, 0x78},
			Args:      []any{big.NewInt(1)},
			WantData:  common.FromHex("0x123456780000000000000000000000000000000000000000000000000000000000000001"),
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			gotData, err := test.Arguments.EncodeWithSelector(test.Selector, test.Args...)
			if err != nil {
				t.Fatalf("Failed to encode args: %v", err)
			}

			if !bytes.Equal(test.WantData, gotData) {
				t.Fatalf("\nwant 0x%x\ngot  0x%x", test.WantData, gotData)
			}
		})
	}
}

func TestEncodeWithSignature(t *testing.T) {
	tests := []struct {
		Arguments Arguments
		Args      []any
		Signature string
		WantData  []byte
	}{
		{
			Arguments: Arguments{{Type: typeUint256}},
			Args:      []any{big.NewInt(1)},
			Signature: "func(uint256)",
			WantData:  common.FromHex("0x7f98a45e0000000000000000000000000000000000000000000000000000000000000001"),
		},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			gotData, err := test.Arguments.EncodeWithSignature(test.Signature, test.Args...)
			if err != nil {
				t.Fatalf("Failed to encode args: %v", err)
			}
			if !bytes.Equal(test.WantData, gotData) {
				t.Fatalf("\nwant 0x%x\ngot  0x%x", test.WantData, gotData)
			}
		})
	}
}

func TestDecode(t *testing.T) {
	type tuple struct {
		A bool
		B *big.Int
	}

	var (
		dataUintBool = common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000001")
		argsUint     = Arguments{{Type: typeUint256}}
		argsBool     = Arguments{{Type: typeBool}}

		dataTuple = common.FromHex("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000007")
		argsTuple = Arguments{{Type: abi.Type{
			T:             abi.TupleTy,
			TupleElems:    []*abi.Type{&typeBool, &typeUint256},
			TupleRawNames: []string{"A", "_a"},
			TupleType: reflect.TypeFor[struct {
				A bool     `abi:"a"`
				B *big.Int `abi:"b"`
			}](),
		}}}

		dataBytes2 = common.FromHex("0xc0fe000000000000000000000000000000000000000000000000000000000000")
		argsBytes2 = Arguments{{Type: abi.Type{T: abi.FixedBytesTy, Size: 2}}}

		dataSlice = common.FromHex("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000007")
		argsSlice = Arguments{{Type: abi.Type{T: abi.SliceTy, Size: 1, Elem: &typeUint256}}}
	)

	t.Run("set-ptr", func(t *testing.T) {
		var arg big.Int
		err := argsUint.Decode(dataUintBool, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		if want := big.NewInt(1); arg.Cmp(want) != 0 {
			t.Fatalf("want %v, got %v", want, arg)
		}
	})

	t.Run("set-ptr-of-ptr", func(t *testing.T) {
		var arg *big.Int
		err := argsUint.Decode(dataUintBool, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		if want := big.NewInt(1); arg.Cmp(want) != 0 {
			t.Fatalf("want %v, got %v", want, arg)
		}
	})

	t.Run("nil-val", func(t *testing.T) {
		var arg *big.Int
		err := argsUint.Decode(dataUintBool, arg)
		if want := "abi: decode nil *big.Int"; err == nil || want != err.Error() {
			t.Fatalf("want %v, got %v", want, err)
		}
	})

	t.Run("nil", func(t *testing.T) {
		if err := argsUint.Decode(dataUintBool, nil); err != nil {
			t.Fatalf("want nil, got %v", err)
		}
	})

	t.Run("non-ptr", func(t *testing.T) {
		var arg bool
		err := argsBool.Decode(dataUintBool, arg)
		if want := "abi: decode non-pointer bool"; err == nil || want != err.Error() {
			t.Fatalf("want %v, got %v", want, err)
		}
	})

	t.Run("set-bool-ptr", func(t *testing.T) {
		var arg bool
		err := argsBool.Decode(dataUintBool, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		if want := true; arg != want {
			t.Fatalf("want %v, got %v", want, arg)
		}
	})

	t.Run("set-bool-ptr-of-ptr", func(t *testing.T) {
		var arg *bool
		err := argsBool.Decode(dataUintBool, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		if want := true; *arg != want {
			t.Fatalf("want %v, got %v", want, arg)
		}
	})

	t.Run("set-bytes2", func(t *testing.T) {
		var arg [2]byte
		err := argsBytes2.Decode(dataBytes2, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		want := [2]byte{0xc0, 0xfe}
		if diff := cmp.Diff(want, arg); diff != "" {
			t.Fatalf("(-want, +got)\n%s", diff)
		}
	})

	t.Run("set-tuple-ptr", func(t *testing.T) {
		var arg tuple
		err := argsTuple.Decode(dataTuple, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		want := tuple{A: true, B: big.NewInt(7)}
		if diff := cmp.Diff(want, arg, cmp.AllowUnexported(big.Int{})); diff != "" {
			t.Fatalf("(-want, +got)\n%s", diff)
		}
	})

	t.Run("set-tuple-ptr-of-ptr", func(t *testing.T) {
		var arg *tuple
		err := argsTuple.Decode(dataTuple, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		want := &tuple{A: true, B: big.NewInt(7)}
		if diff := cmp.Diff(want, arg, cmp.AllowUnexported(big.Int{})); diff != "" {
			t.Fatalf("(-want, +got)\n%s", diff)
		}
	})

	t.Run("set-slice", func(t *testing.T) {
		var arg []*big.Int
		err := argsSlice.Decode(dataSlice, &arg)
		if err != nil {
			t.Fatalf("Failed to decode args: %v", err)
		}
		want := []*big.Int{big.NewInt(7)}
		if diff := cmp.Diff(want, arg, cmp.AllowUnexported(big.Int{})); diff != "" {
			t.Fatalf("(-want, +got)\n%s", diff)
		}
	})
}

func TestTypeToString(t *testing.T) {
	tests := []struct {
		Type *abi.Type
		Want string
	}{
		{Type: &abi.Type{T: abi.BoolTy}, Want: "bool"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.BoolTy}}, Want: "bool[]"},
		{Type: &abi.Type{Size: 2, T: abi.ArrayTy, Elem: &abi.Type{T: abi.BoolTy}}, Want: "bool[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.BoolTy}}}, Want: "bool[2][]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.BoolTy}}}, Want: "bool[][]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.BoolTy}}}, Want: "bool[][2]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.BoolTy}}}, Want: "bool[2][2]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.BoolTy}}}}, Want: "bool[2][][2]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.BoolTy}}}}, Want: "bool[2][2][2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.BoolTy}}}}, Want: "bool[][][]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.BoolTy}}}}, Want: "bool[][2][]"},
		{Type: &abi.Type{Size: 8, T: abi.IntTy}, Want: "int8"},
		{Type: &abi.Type{Size: 16, T: abi.IntTy}, Want: "int16"},
		{Type: &abi.Type{Size: 32, T: abi.IntTy}, Want: "int32"},
		{Type: &abi.Type{Size: 64, T: abi.IntTy}, Want: "int64"},
		{Type: &abi.Type{Size: 256, T: abi.IntTy}, Want: "int256"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 8, T: abi.IntTy}}, Want: "int8[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 8, T: abi.IntTy}}, Want: "int8[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 16, T: abi.IntTy}}, Want: "int16[]"},
		{Type: &abi.Type{Size: 2, T: abi.ArrayTy, Elem: &abi.Type{Size: 16, T: abi.IntTy}}, Want: "int16[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 32, T: abi.IntTy}}, Want: "int32[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 32, T: abi.IntTy}}, Want: "int32[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 64, T: abi.IntTy}}, Want: "int64[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 64, T: abi.IntTy}}, Want: "int64[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 256, T: abi.IntTy}}, Want: "int256[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 256, T: abi.IntTy}}, Want: "int256[2]"},
		{Type: &abi.Type{Size: 8, T: abi.UintTy}, Want: "uint8"},
		{Type: &abi.Type{Size: 16, T: abi.UintTy}, Want: "uint16"},
		{Type: &abi.Type{Size: 32, T: abi.UintTy}, Want: "uint32"},
		{Type: &abi.Type{Size: 64, T: abi.UintTy}, Want: "uint64"},
		{Type: &abi.Type{Size: 256, T: abi.UintTy}, Want: "uint256"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 8, T: abi.UintTy}}, Want: "uint8[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 8, T: abi.UintTy}}, Want: "uint8[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 16, T: abi.UintTy}}, Want: "uint16[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 16, T: abi.UintTy}}, Want: "uint16[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 32, T: abi.UintTy}}, Want: "uint32[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 32, T: abi.UintTy}}, Want: "uint32[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 64, T: abi.UintTy}}, Want: "uint64[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 64, T: abi.UintTy}}, Want: "uint64[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 256, T: abi.UintTy}}, Want: "uint256[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 256, T: abi.UintTy}}, Want: "uint256[2]"},
		{Type: &abi.Type{T: abi.FixedBytesTy, Size: 32}, Want: "bytes32"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.BytesTy}}, Want: "bytes[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.BytesTy}}, Want: "bytes[2]"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.FixedBytesTy, Size: 32}}, Want: "bytes32[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.FixedBytesTy, Size: 32}}, Want: "bytes32[2]"},
		{Type: &abi.Type{T: abi.HashTy, Size: 20}, Want: "hash"},
		{Type: &abi.Type{T: abi.StringTy}, Want: "string"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{T: abi.StringTy}}, Want: "string[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{T: abi.StringTy}}, Want: "string[2]"},
		{Type: &abi.Type{Size: 20, T: abi.AddressTy}, Want: "address"},
		{Type: &abi.Type{T: abi.SliceTy, Elem: &abi.Type{Size: 20, T: abi.AddressTy}}, Want: "address[]"},
		{Type: &abi.Type{T: abi.ArrayTy, Size: 2, Elem: &abi.Type{Size: 20, T: abi.AddressTy}}, Want: "address[2]"},
		{Type: &abi.Type{T: abi.TupleTy, TupleElems: []*abi.Type{&typeUint256, &typeUint256}}, Want: "(uint256,uint256)"},
		{Type: &abi.Type{T: abi.TupleTy, TupleElems: []*abi.Type{{T: abi.TupleTy, TupleElems: []*abi.Type{&typeUint256, &typeUint256}}, &typeUint256}}, Want: "((uint256,uint256),uint256)"},
	}

	for i, test := range tests {
		t.Run(strconv.Itoa(i), func(t *testing.T) {
			got := typeToString(test.Type)
			if test.Want != got {
				t.Fatalf("want %q, got %q", test.Want, got)
			}
		})
	}
}

var (
	big1 = big.NewInt(1)
	hex1 = common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000001")
)

func TestTypeMapping(t *testing.T) {
	tests := []struct {
		RAWType string
		Data    []byte
		Arg     any
		Want    any
	}{
		{RAWType: "bool", Data: hex1, Arg: new(bool), Want: ptr(true)},

		{RAWType: "int8", Data: hex1, Arg: new(int8), Want: ptr[int8](1)},
		{RAWType: "int16", Data: hex1, Arg: new(int16), Want: ptr[int16](1)},
		{RAWType: "int24", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int32", Data: hex1, Arg: new(int32), Want: ptr[int32](1)},
		{RAWType: "int40", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int48", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int56", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int64", Data: hex1, Arg: new(int64), Want: ptr[int64](1)},
		{RAWType: "int72", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int80", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int88", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int96", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int104", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int112", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int120", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int128", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int136", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int144", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int152", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int160", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int168", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int176", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int184", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int192", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int200", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int208", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int216", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int224", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int232", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int240", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int248", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int256", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "int", Data: hex1, Arg: new(big.Int), Want: big1},

		{RAWType: "uint8", Data: hex1, Arg: new(uint8), Want: ptr[uint8](1)},
		{RAWType: "uint16", Data: hex1, Arg: new(uint16), Want: ptr[uint16](1)},
		{RAWType: "uint24", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint32", Data: hex1, Arg: new(uint32), Want: ptr[uint32](1)},
		{RAWType: "uint40", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint48", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint56", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint64", Data: hex1, Arg: new(uint64), Want: ptr[uint64](1)},
		{RAWType: "uint72", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint80", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint88", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint96", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint104", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint112", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint120", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint128", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint136", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint144", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint152", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint160", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint168", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint176", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint184", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint192", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint200", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint208", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint216", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint224", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint232", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint240", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint248", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint256", Data: hex1, Arg: new(big.Int), Want: big1},
		{RAWType: "uint", Data: hex1, Arg: new(big.Int), Want: big1},

		{RAWType: "bytes1", Data: hex1, Arg: new([1]byte), Want: &[1]byte{}},
		{RAWType: "bytes2", Data: hex1, Arg: new([2]byte), Want: &[2]byte{}},
		{RAWType: "bytes3", Data: hex1, Arg: new([3]byte), Want: &[3]byte{}},
		{RAWType: "bytes4", Data: hex1, Arg: new([4]byte), Want: &[4]byte{}},
		{RAWType: "bytes5", Data: hex1, Arg: new([5]byte), Want: &[5]byte{}},
		{RAWType: "bytes6", Data: hex1, Arg: new([6]byte), Want: &[6]byte{}},
		{RAWType: "bytes7", Data: hex1, Arg: new([7]byte), Want: &[7]byte{}},
		{RAWType: "bytes8", Data: hex1, Arg: new([8]byte), Want: &[8]byte{}},
		{RAWType: "bytes9", Data: hex1, Arg: new([9]byte), Want: &[9]byte{}},
		{RAWType: "bytes10", Data: hex1, Arg: new([10]byte), Want: &[10]byte{}},
		{RAWType: "bytes11", Data: hex1, Arg: new([11]byte), Want: &[11]byte{}},
		{RAWType: "bytes12", Data: hex1, Arg: new([12]byte), Want: &[12]byte{}},
		{RAWType: "bytes13", Data: hex1, Arg: new([13]byte), Want: &[13]byte{}},
		{RAWType: "bytes14", Data: hex1, Arg: new([14]byte), Want: &[14]byte{}},
		{RAWType: "bytes15", Data: hex1, Arg: new([15]byte), Want: &[15]byte{}},
		{RAWType: "bytes16", Data: hex1, Arg: new([16]byte), Want: &[16]byte{}},
		{RAWType: "bytes17", Data: hex1, Arg: new([17]byte), Want: &[17]byte{}},
		{RAWType: "bytes18", Data: hex1, Arg: new([18]byte), Want: &[18]byte{}},
		{RAWType: "bytes19", Data: hex1, Arg: new([19]byte), Want: &[19]byte{}},
		{RAWType: "bytes20", Data: hex1, Arg: new([20]byte), Want: &[20]byte{}},
		{RAWType: "address", Data: hex1, Arg: new(common.Address), Want: &common.Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
		{RAWType: "bytes21", Data: hex1, Arg: new([21]byte), Want: &[21]byte{}},
		{RAWType: "bytes22", Data: hex1, Arg: new([22]byte), Want: &[22]byte{}},
		{RAWType: "bytes23", Data: hex1, Arg: new([23]byte), Want: &[23]byte{}},
		{RAWType: "bytes24", Data: hex1, Arg: new([24]byte), Want: &[24]byte{}},
		{RAWType: "bytes25", Data: hex1, Arg: new([25]byte), Want: &[25]byte{}},
		{RAWType: "bytes26", Data: hex1, Arg: new([26]byte), Want: &[26]byte{}},
		{RAWType: "bytes27", Data: hex1, Arg: new([27]byte), Want: &[27]byte{}},
		{RAWType: "bytes28", Data: hex1, Arg: new([28]byte), Want: &[28]byte{}},
		{RAWType: "bytes29", Data: hex1, Arg: new([29]byte), Want: &[29]byte{}},
		{RAWType: "bytes30", Data: hex1, Arg: new([30]byte), Want: &[30]byte{}},
		{RAWType: "bytes31", Data: hex1, Arg: new([31]byte), Want: &[31]byte{}},
		{RAWType: "bytes32", Data: hex1, Arg: new([32]byte), Want: &[32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Download .txt
gitextract_vxq391jt/

├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── doc.yml
│       └── go.yml
├── .gitignore
├── LICENSE
├── README.md
├── client.go
├── client_test.go
├── docs/
│   ├── components/
│   │   └── DocLink.jsx
│   ├── next.config.js
│   ├── package.json
│   ├── pages/
│   │   ├── 404.mdx
│   │   ├── _app.js
│   │   ├── _meta.js
│   │   ├── examples/
│   │   │   ├── _meta.js
│   │   │   └── index.mdx
│   │   ├── examples.mdx
│   │   ├── helper-abi.mdx
│   │   ├── helper-utils.mdx
│   │   ├── index.mdx
│   │   ├── rpc-extension.mdx
│   │   ├── rpc-methods/
│   │   │   ├── _meta.js
│   │   │   ├── admin.mdx
│   │   │   ├── debug.mdx
│   │   │   ├── eth.mdx
│   │   │   ├── net.mdx
│   │   │   ├── txpool.mdx
│   │   │   └── web3.mdx
│   │   ├── rpc-methods.mdx
│   │   ├── rpc-overview.mdx
│   │   ├── style.css
│   │   ├── vm-overview.mdx
│   │   ├── vm-testing.mdx
│   │   └── vm-tracing.mdx
│   ├── postcss.config.cjs
│   ├── public/
│   │   ├── _redirects
│   │   └── robots.txt
│   ├── tailwind.config.js
│   └── theme.config.jsx
├── event.go
├── event_test.go
├── example_test.go
├── func.go
├── func_test.go
├── go.mod
├── go.sum
├── internal/
│   ├── abi/
│   │   ├── arguments.go
│   │   ├── arguments_test.go
│   │   ├── copy.go
│   │   ├── copy_test.go
│   │   ├── doc.go
│   │   ├── lexer.go
│   │   ├── lexer_test.go
│   │   ├── parser.go
│   │   ├── parser_test.go
│   │   ├── tuple.go
│   │   └── tuple_test.go
│   ├── cmp.go
│   ├── cmp_test.go
│   ├── crypto/
│   │   └── keccak.go
│   ├── fourbyte/
│   │   ├── events.go
│   │   ├── events.txt
│   │   ├── fourbyte.go
│   │   ├── funcs.go
│   │   ├── funcs.txt
│   │   └── gen.go
│   ├── hexutil/
│   │   ├── bytes.go
│   │   ├── bytes_test.go
│   │   ├── hash.go
│   │   └── hash_test.go
│   ├── mod/
│   │   ├── root.go
│   │   └── root_test.go
│   └── module/
│       ├── factory.go
│       ├── util.go
│       └── util_test.go
├── module/
│   ├── admin/
│   │   ├── admin.go
│   │   ├── admin_test.go
│   │   └── testdata/
│   │       ├── add_peer.golden
│   │       ├── add_trusted_peer.golden
│   │       ├── node_info.golden
│   │       ├── remove_peer.golden
│   │       └── remove_trusted_peer.golden
│   ├── debug/
│   │   ├── call_trace.go
│   │   ├── call_trace_test.go
│   │   ├── doc.go
│   │   ├── testdata/
│   │   │   ├── traceCall.golden
│   │   │   ├── traceCall_callTracer.golden
│   │   │   ├── traceTx__1150000_0.golden
│   │   │   ├── traceTx__12244000_0.golden
│   │   │   └── traceTx_revertReason.golden
│   │   ├── trace.go
│   │   └── trace_test.go
│   ├── eth/
│   │   ├── balance.go
│   │   ├── balance_test.go
│   │   ├── block.go
│   │   ├── block_number.go
│   │   ├── block_number_test.go
│   │   ├── block_test.go
│   │   ├── call.go
│   │   ├── call_test.go
│   │   ├── chain_id.go
│   │   ├── chain_id_test.go
│   │   ├── code.go
│   │   ├── code_test.go
│   │   ├── doc.go
│   │   ├── gas_price.go
│   │   ├── gas_price_test.go
│   │   ├── gas_tip_cap.go
│   │   ├── gas_tip_cap_test.go
│   │   ├── get_logs.go
│   │   ├── get_logs_test.go
│   │   ├── storage_at.go
│   │   ├── storage_at_test.go
│   │   ├── subscribe.go
│   │   ├── syncing.go
│   │   ├── syncing_test.go
│   │   ├── testdata/
│   │   │   ├── block_number.golden
│   │   │   ├── block_transaction_count_by_hash__0x00.golden
│   │   │   ├── block_transaction_count_by_hash__15050000.golden
│   │   │   ├── block_transaction_count_by_number__15050000.golden
│   │   │   ├── call_func.golden
│   │   │   ├── call_func__overrides.golden
│   │   │   ├── chain_id.golden
│   │   │   ├── create_access_list.golden
│   │   │   ├── estimate_gas.golden
│   │   │   ├── gas_price.golden
│   │   │   ├── gas_tip_cap.golden
│   │   │   ├── get_balance.golden
│   │   │   ├── get_balance__at_block.golden
│   │   │   ├── get_block_by_hash__0x00.golden
│   │   │   ├── get_block_by_hash__1.golden
│   │   │   ├── get_block_by_hash__12965000.golden
│   │   │   ├── get_block_by_hash__18000000.golden
│   │   │   ├── get_block_by_hash__46147.golden
│   │   │   ├── get_block_by_number__1.golden
│   │   │   ├── get_block_by_number__12965000.golden
│   │   │   ├── get_block_by_number__46147.golden
│   │   │   ├── get_block_by_number__999999999.golden
│   │   │   ├── get_block_receipts.golden
│   │   │   ├── get_code.golden
│   │   │   ├── get_logs.golden
│   │   │   ├── get_storage_at.golden
│   │   │   ├── get_storage_at__number.golden
│   │   │   ├── get_transaction_by_block_hash_and_index.golden
│   │   │   ├── get_transaction_by_block_hash_and_index__300.golden
│   │   │   ├── get_transaction_by_block_number_and_index.golden
│   │   │   ├── get_transaction_by_hash__0x00.golden
│   │   │   ├── get_transaction_by_hash__type0.golden
│   │   │   ├── get_transaction_by_hash__type2.golden
│   │   │   ├── get_transaction_count.golden
│   │   │   ├── get_transaction_receipt.golden
│   │   │   ├── get_transaction_receipt_0x00.golden
│   │   │   ├── send_raw_transaction.golden
│   │   │   ├── syncing__false.golden
│   │   │   ├── syncing__true.golden
│   │   │   ├── uncle_by_hash_and_index__15050036.golden
│   │   │   ├── uncle_by_hash_and_index__15050036_1.golden
│   │   │   ├── uncle_by_number_and_index__15050036.golden
│   │   │   ├── uncle_count_by_hash__15050036.golden
│   │   │   └── uncle_count_by_number__15050036.golden
│   │   ├── tx.go
│   │   ├── tx_test.go
│   │   ├── uncle.go
│   │   └── uncle_test.go
│   ├── net/
│   │   ├── net.go
│   │   ├── net_test.go
│   │   └── testdata/
│   │       ├── listening.golden
│   │       ├── peer_count.golden
│   │       └── version.golden
│   ├── txpool/
│   │   ├── content.go
│   │   ├── content_test.go
│   │   ├── doc.go
│   │   ├── status.go
│   │   ├── status_test.go
│   │   └── testdata/
│   │       ├── content.golden
│   │       ├── contentFrom.golden
│   │       └── status.golden
│   └── web3/
│       ├── testdata/
│       │   ├── client_version.golden
│       │   └── client_version__err.golden
│       ├── web3.go
│       └── web3_test.go
├── rpctest/
│   ├── server.go
│   └── test_case.go
├── testdata/
│   └── w3vm/
│       ├── 1_12243997.json
│       ├── 1_12243998.json
│       ├── 1_12243999.json
│       ├── 1_12244000.json
│       ├── 1_12964997.json
│       ├── 1_12964998.json
│       ├── 1_12964999.json
│       ├── 1_12965000.json
│       ├── 1_13772997.json
│       ├── 1_13772998.json
│       ├── 1_13772999.json
│       ├── 1_13773000.json
│       ├── 1_15049997.json
│       ├── 1_15049998.json
│       ├── 1_15049999.json
│       ├── 1_15050000.json
│       ├── 1_15537391.json
│       ├── 1_15537392.json
│       ├── 1_15537393.json
│       ├── 1_15537394.json
│       ├── 1_17034867.json
│       ├── 1_17034868.json
│       ├── 1_17034869.json
│       ├── 1_17034870.json
│       ├── 1_18999999.json
│       ├── 1_19000000.json
│       ├── 1_19000001.json
│       ├── 1_19000002.json
│       ├── 1_19000003.json
│       ├── 1_19000004.json
│       ├── 1_19000005.json
│       ├── 1_19000006.json
│       ├── 1_19000007.json
│       ├── 1_19000008.json
│       ├── 1_19426484.json
│       ├── 1_19426485.json
│       ├── 1_19426486.json
│       ├── 1_19426487.json
│       ├── 1_19999999.json
│       ├── 1_4369997.json
│       ├── 1_4369998.json
│       ├── 1_4369999.json
│       ├── 1_4370000.json
│       ├── 1_7279997.json
│       ├── 1_7279998.json
│       ├── 1_7279999.json
│       ├── 1_7280000.json
│       ├── 1_9068997.json
│       ├── 1_9068998.json
│       ├── 1_9068999.json
│       ├── 1_9069000.json
│       ├── 1_9199997.json
│       ├── 1_9199998.json
│       ├── 1_9199999.json
│       ├── 1_9200000.json
│       ├── 1_header_hashes.json
│       └── contracts.json
├── util.go
├── util_test.go
├── w3types/
│   ├── interfaces.go
│   ├── interfaces_test.go
│   ├── message.go
│   ├── rpc.go
│   ├── rpc_test.go
│   ├── state.go
│   └── state_test.go
└── w3vm/
    ├── bench_test.go
    ├── db.go
    ├── example_test.go
    ├── fetcher.go
    ├── fetcher_test.go
    ├── hooks/
    │   └── call_tracer.go
    ├── receipt.go
    ├── testdata/
    │   ├── burntpix.genesis.json
    │   └── weth9.bytecode
    ├── util.go
    ├── util_test.go
    ├── vm.go
    └── vm_test.go
Download .txt
SYMBOL INDEX (583 symbols across 95 files)

FILE: client.go
  type Client (line 22) | type Client struct
    method Close (line 70) | func (c *Client) Close() error {
    method CallCtx (line 80) | func (c *Client) CallCtx(ctx context.Context, calls ...w3types.RPCCall...
    method Call (line 140) | func (c *Client) Call(calls ...w3types.RPCCaller) error {
    method SubscribeCtx (line 145) | func (c *Client) SubscribeCtx(ctx context.Context, s w3types.RPCSubscr...
    method Subscribe (line 154) | func (c *Client) Subscribe(s w3types.RPCSubscriber) (*rpc.ClientSubscr...
    method rateLimit (line 158) | func (c *Client) rateLimit(ctx context.Context, batchElems []rpc.Batch...
  function NewClient (line 31) | func NewClient(client *rpc.Client, opts ...Option) *Client {
  function Dial (line 50) | func Dial(rawurl string, opts ...Option) (*Client, error) {
  function MustDial (line 59) | func MustDial(rawurl string, opts ...Option) *Client {
  type CallErrors (line 181) | type CallErrors
    method Error (line 183) | func (e CallErrors) Error() string {
    method Is (line 203) | func (e CallErrors) Is(target error) bool {
  type Option (line 209) | type Option
  function WithRateLimiter (line 216) | func WithRateLimiter(rl *rate.Limiter, costFunc func(methods []string) (...

FILE: client_test.go
  function TestClientCall (line 34) | func TestClientCall(t *testing.T) {
  function TestClientCall_CallErrors (line 107) | func TestClientCall_CallErrors(t *testing.T) {
  type testCaller (line 131) | type testCaller struct
    method CreateRequest (line 136) | func (c *testCaller) CreateRequest() (elem rpc.BatchElem, err error) {
    method HandleResponse (line 140) | func (c *testCaller) HandleResponse(elem rpc.BatchElem) (err error) {
  function BenchmarkCall_BalanceNonce (line 144) | func BenchmarkCall_BalanceNonce(b *testing.B) {
  function BenchmarkCall_Balance100 (line 178) | func BenchmarkCall_Balance100(b *testing.B) {
  function BenchmarkCall_BalanceOf100 (line 214) | func BenchmarkCall_BalanceOf100(b *testing.B) {
  function BenchmarkCall_Block100 (line 260) | func BenchmarkCall_Block100(b *testing.B) {

FILE: docs/pages/_app.js
  function Nextra (line 7) | function Nextra({ Component, pageProps }) {

FILE: event.go
  type Event (line 14) | type Event struct
    method DecodeArgs (line 67) | func (e *Event) DecodeArgs(log *types.Log, args ...any) error {
  function NewEvent (line 31) | func NewEvent(signature string, tuples ...any) (*Event, error) {
  function MustNewEvent (line 58) | func MustNewEvent(signature string, tuples ...any) *Event {

FILE: event_test.go
  function TestNewEvent (line 15) | func TestNewEvent(t *testing.T) {
  function TestEventDecodeArgs (line 67) | func TestEventDecodeArgs(t *testing.T) {

FILE: example_test.go
  function ExampleClient_batchCallFunc (line 39) | func ExampleClient_batchCallFunc() {
  function ExampleClient_batchCallFuncUniswapQuoter (line 63) | func ExampleClient_batchCallFuncUniswapQuoter() {
  function ExampleClient_batchEOAState (line 109) | func ExampleClient_batchEOAState() {
  function ExampleClient_batchTxDetails (line 125) | func ExampleClient_batchTxDetails() {
  function ExampleClient_batchBlocks (line 143) | func ExampleClient_batchBlocks() {
  function ExampleClient_batchHandleError (line 165) | func ExampleClient_batchHandleError() {
  function ExampleClient_callFunc (line 194) | func ExampleClient_callFunc() {
  function ExampleClient_callFuncWithStateOverride (line 208) | func ExampleClient_callFuncWithStateOverride() {
  function ExampleClient_sendETHTransfer (line 226) | func ExampleClient_sendETHTransfer() {
  function ExampleClient_sendTokenTransfer (line 256) | func ExampleClient_sendTokenTransfer() {
  function ExampleClient_subscribeToPendingTransactions (line 292) | func ExampleClient_subscribeToPendingTransactions() {
  function ExampleClient_rateLimitByRequest (line 318) | func ExampleClient_rateLimitByRequest() {
  function ExampleClient_rateLimitByComputeUnits (line 331) | func ExampleClient_rateLimitByComputeUnits() {
  function ExampleFunc_erc20 (line 366) | func ExampleFunc_erc20() {
  function ExampleFunc_balanceOf (line 384) | func ExampleFunc_balanceOf() {
  function ExampleFunc_uniswapV4Swap (line 404) | func ExampleFunc_uniswapV4Swap() {
  function ExampleFunc_DecodeReturns_getReserves (line 445) | func ExampleFunc_DecodeReturns_getReserves() {
  function ExampleEvent_decodeTransferEvent (line 469) | func ExampleEvent_decodeTransferEvent() {

FILE: func.go
  type Func (line 30) | type Func struct
    method EncodeArgs (line 93) | func (f *Func) EncodeArgs(args ...any) ([]byte, error) {
    method DecodeArgs (line 98) | func (f *Func) DecodeArgs(input []byte, args ...any) error {
    method DecodeReturns (line 109) | func (f *Func) DecodeReturns(output []byte, returns ...any) error {
  function NewFunc (line 57) | func NewFunc(signature, returns string, tuples ...any) (*Func, error) {
  function MustNewFunc (line 83) | func MustNewFunc(signature, returns string, tuples ...any) *Func {
  function selector (line 131) | func selector(signature string) (selector [4]byte) {

FILE: func_test.go
  function TestNewFunc (line 18) | func TestNewFunc(t *testing.T) {
  function TestFuncEncodeArgs (line 86) | func TestFuncEncodeArgs(t *testing.T) {
  function TestFuncDecodeArgs (line 236) | func TestFuncDecodeArgs(t *testing.T) {
  function TestFuncDecodeReturns (line 452) | func TestFuncDecodeReturns(t *testing.T) {
  function ptr (line 527) | func ptr[T any](v T) *T { return &v }
  type tuple (line 529) | type tuple struct
  type tupleWithTag (line 534) | type tupleWithTag struct
  type tupleWithNesting (line 539) | type tupleWithNesting struct
  type tupleWithBytes (line 544) | type tupleWithBytes struct
  type tupleWithUnexportedProperty (line 549) | type tupleWithUnexportedProperty struct
  type tupleWithWrongOrder (line 555) | type tupleWithWrongOrder struct
  type tupleWithMoreArgs (line 560) | type tupleWithMoreArgs struct
  type tupleIssue35 (line 566) | type tupleIssue35 struct
  type tupleNested (line 572) | type tupleNested struct
  function BenchmarkFuncEncode (line 577) | func BenchmarkFuncEncode(b *testing.B) {

FILE: internal/abi/arguments.go
  type Arguments (line 13) | type Arguments
    method Signature (line 15) | func (a Arguments) Signature() string {
    method SignatureWithName (line 27) | func (a Arguments) SignatureWithName(name string) string {
    method Encode (line 32) | func (a Arguments) Encode(args ...any) ([]byte, error) {
    method EncodeWithSelector (line 42) | func (a Arguments) EncodeWithSelector(selector [4]byte, args ...any) (...
    method EncodeWithSignature (line 54) | func (a Arguments) EncodeWithSignature(signature string, args ...any) ...
    method Decode (line 62) | func (a Arguments) Decode(data []byte, args ...any) error {
  function typeToString (line 82) | func typeToString(t *abi.Type) string {

FILE: internal/abi/arguments_test.go
  function TestSignature (line 15) | func TestSignature(t *testing.T) {
  function TestSignatureWithName (line 58) | func TestSignatureWithName(t *testing.T) {
  function TestEncode (line 86) | func TestEncode(t *testing.T) {
  function TestEncodeWithSelector (line 112) | func TestEncodeWithSelector(t *testing.T) {
  function TestEncodeWithSignature (line 141) | func TestEncodeWithSignature(t *testing.T) {
  function TestDecode (line 169) | func TestDecode(t *testing.T) {
  function TestTypeToString (line 313) | func TestTypeToString(t *testing.T) {
  function TestTypeMapping (line 390) | func TestTypeMapping(t *testing.T) {

FILE: internal/abi/copy.go
  function Copy (line 73) | func Copy(dst, src any) error {
  function rCopy (line 100) | func rCopy(dst, src reflect.Value) error {
  function set (line 114) | func set(dst, src reflect.Value) error {
  function setStruct (line 138) | func setStruct(dst, src reflect.Value) error {
  function setSlice (line 177) | func setSlice(dst, src reflect.Value) error {
  function setArray (line 197) | func setArray(dst, src reflect.Value) error {
  function dereference (line 212) | func dereference(v reflect.Value) reflect.Value {
  function reference (line 219) | func reference(v reflect.Value) reflect.Value {

FILE: internal/abi/copy_test.go
  function TestCopy (line 14) | func TestCopy(t *testing.T) {
  function ptr (line 313) | func ptr[T any](v T) *T { return &v }
  function val (line 314) | func val[T any](v *T) T { return *v }
  type tuple0 (line 316) | type tuple0 struct
  type tuple1 (line 321) | type tuple1 struct
  type tuple2 (line 326) | type tuple2 struct
  type tuple3 (line 331) | type tuple3 struct

FILE: internal/abi/lexer.go
  type item (line 12) | type item struct
    method String (line 19) | func (i item) String() string {
    method IsType (line 27) | func (i *item) IsType() (*abi.Type, bool) {
  type itemType (line 17) | type itemType
  constant itemTypeID (line 37) | itemTypeID    itemType = iota
  constant itemTypePunct (line 38) | itemTypePunct
  constant itemTypeNum (line 39) | itemTypeNum
  constant itemTypeEOF (line 40) | itemTypeEOF
  constant eof (line 42) | eof rune = -1
  constant num0 (line 44) | num0  = "123456789"
  constant num (line 45) | num   = "0" + num0
  constant id0 (line 46) | id0   = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
  constant id (line 47) | id    = id0 + num
  constant space (line 48) | space = " \t\r\n"
  type lexer (line 52) | type lexer struct
    method nextItem (line 63) | func (l *lexer) nextItem() (*item, error) {
    method next (line 88) | func (l *lexer) next() (next rune) {
    method backup (line 98) | func (l *lexer) backup() {
    method ignore (line 102) | func (l *lexer) ignore() {
    method peek (line 106) | func (l *lexer) peek() (next rune) {
    method accept (line 112) | func (l *lexer) accept(valid string) bool {
    method acceptRun (line 121) | func (l *lexer) acceptRun(valid string) {
    method token (line 127) | func (l *lexer) token() string {
  function newLexer (line 59) | func newLexer(input string) *lexer {

FILE: internal/abi/lexer_test.go
  function TestLexer (line 13) | func TestLexer(t *testing.T) {
  function lex (line 42) | func lex(input string) ([]*item, error) {

FILE: internal/abi/parser.go
  function Parse (line 15) | func Parse(s string, tuples ...any) (a Arguments, err error) {
  function ParseWithName (line 27) | func ParseWithName(s string, tuples ...any) (name string, a Arguments, e...
  type parser (line 37) | type parser struct
    method next (line 60) | func (p *parser) next() *item {
    method backup (line 77) | func (p *parser) backup() {
    method peek (line 81) | func (p *parser) peek() *item {
    method parseArgsWithName (line 87) | func (p *parser) parseArgsWithName() error {
    method parseArgs (line 124) | func (p *parser) parseArgs() error {
    method parseType (line 191) | func (p *parser) parseType() (*abi.Type, error) {
    method parseTupleType (line 232) | func (p *parser) parseTupleType(i int) (*abi.Type, string, error) {
    method parseTupleTypes (line 252) | func (p *parser) parseTupleTypes() (*abi.Type, error) {
    method parseSliceOrArray (line 292) | func (p *parser) parseSliceOrArray(typ *abi.Type) (*abi.Type, error) {
  function newParser (line 51) | func newParser(lexer *lexer, tuples []any) *parser {

FILE: internal/abi/parser_test.go
  function TestParseArgs (line 24) | func TestParseArgs(t *testing.T) {
  function TestParseArgsWithName (line 533) | func TestParseArgsWithName(t *testing.T) {
  function BenchmarkParseArgsWithName (line 660) | func BenchmarkParseArgsWithName(b *testing.B) {
  type simpleStruct (line 704) | type simpleStruct struct
  type simpleStructWithoutTags (line 709) | type simpleStructWithoutTags struct
  type nestedStruct (line 714) | type nestedStruct struct
  type complexStruct (line 719) | type complexStruct struct
  type arrayStruct (line 726) | type arrayStruct struct
  type emptyStruct (line 731) | type emptyStruct struct
  type structWithInvalidField (line 734) | type structWithInvalidField struct

FILE: internal/abi/tuple.go
  function tupleMap (line 16) | func tupleMap(tuples ...any) (map[string]reflect.Type, error) {
  function buildTuples (line 32) | func buildTuples(tuples ...any) (map[string]abi.Argument, error) {
  function typeOfField (line 59) | func typeOfField(field reflect.StructField) (*abi.Type, error) {
  function typeOf (line 66) | func typeOf(typ reflect.Type, abiType string) (*abi.Type, error) {
  function toCamelCase (line 184) | func toCamelCase(s string) string {

FILE: internal/abi/tuple_test.go
  function TestTupleMap (line 19) | func TestTupleMap(t *testing.T) {
  type Tuple1 (line 70) | type Tuple1 struct
  type Tuple2 (line 74) | type Tuple2 struct
  function TestTypeOfField (line 79) | func TestTypeOfField(t *testing.T) {
  function TestToCamelCase (line 225) | func TestToCamelCase(t *testing.T) {

FILE: internal/cmp.go
  function EquateErrors (line 8) | func EquateErrors() cmp.Option {
  function areConcreteErrors (line 12) | func areConcreteErrors(x, y any) bool {
  function compareErrors (line 18) | func compareErrors(x, y any) bool {

FILE: internal/cmp_test.go
  function TestEquateErrors (line 12) | func TestEquateErrors(t *testing.T) {

FILE: internal/crypto/keccak.go
  function Keccak256Hash (line 20) | func Keccak256Hash(data ...[]byte) (hash common.Hash) {
  function Keccak256 (line 40) | func Keccak256(data ...[]byte) (hash []byte) {

FILE: internal/fourbyte/fourbyte.go
  function Function (line 22) | func Function(sig [4]byte, addr common.Address) (fn *w3.Func, isPrecompi...
  function Event (line 36) | func Event(topic0 [32]byte, addr common.Address) *w3.Event {

FILE: internal/fourbyte/gen.go
  function main (line 18) | func main() {
  function genFuncs (line 46) | func genFuncs(fn, goFn string) error {
  function genEvents (line 123) | func genEvents(fn, goFn string) error {
  type model (line 191) | type model struct
  type function (line 196) | type function struct
  type event (line 202) | type event struct

FILE: internal/hexutil/bytes.go
  type Bytes (line 8) | type Bytes
    method UnmarshalText (line 11) | func (b *Bytes) UnmarshalText(data []byte) error {
    method MarshalText (line 22) | func (b Bytes) MarshalText() ([]byte, error) {

FILE: internal/hexutil/bytes_test.go
  function TestBytesUnmarshalText (line 21) | func TestBytesUnmarshalText(t *testing.T) {
  function TestBytesMarshalText (line 35) | func TestBytesMarshalText(t *testing.T) {

FILE: internal/hexutil/hash.go
  type Hash (line 13) | type Hash
    method UnmarshalText (line 15) | func (h *Hash) UnmarshalText(text []byte) error {
    method MarshalText (line 28) | func (h Hash) MarshalText() ([]byte, error) {

FILE: internal/hexutil/hash_test.go
  function TestHashUnmarshalText (line 23) | func TestHashUnmarshalText(t *testing.T) {
  function TestHashMarshalText (line 38) | func TestHashMarshalText(t *testing.T) {

FILE: internal/mod/root.go
  function init (line 12) | func init() {

FILE: internal/mod/root_test.go
  function TestModRoot (line 10) | func TestModRoot(t *testing.T) {

FILE: internal/module/factory.go
  type Option (line 16) | type Option
  type ArgsWrapperFunc (line 18) | type ArgsWrapperFunc
  type RetWrapperFunc (line 20) | type RetWrapperFunc
  type Factory (line 22) | type Factory struct
  function NewFactory (line 31) | func NewFactory[T any](method string, args []any, opts ...Option[T]) *Fa...
  method Returns (line 45) | func (f Factory[T]) Returns(ret *T) w3types.RPCCaller {
  method CreateRequest (line 50) | func (f Factory[T]) CreateRequest() (rpc.BatchElem, error) {
  method HandleResponse (line 66) | func (f Factory[T]) HandleResponse(elem rpc.BatchElem) error {
  function WithArgsWrapper (line 82) | func WithArgsWrapper[T any](fn ArgsWrapperFunc) Option[T] {
  function WithRetWrapper (line 88) | func WithRetWrapper[T any](fn RetWrapperFunc[T]) Option[T] {
  function HexBigRetWrapper (line 94) | func HexBigRetWrapper(ret **big.Int) any {
  function HexUintRetWrapper (line 98) | func HexUintRetWrapper(ret *uint) any     { return (*hexutil.Uint)(ret) }
  function HexUint64RetWrapper (line 99) | func HexUint64RetWrapper(ret *uint64) any { return (*hexutil.Uint64)(ret) }
  function HexBytesRetWrapper (line 100) | func HexBytesRetWrapper(ret *[]byte) any  { return (*hexutil.Bytes)(ret) }

FILE: internal/module/util.go
  function BlockNumberArg (line 12) | func BlockNumberArg(blockNumber *big.Int) string {

FILE: internal/module/util_test.go
  function TestBlockNumberArg (line 9) | func TestBlockNumberArg(t *testing.T) {

FILE: module/admin/admin.go
  function AddPeer (line 18) | func AddPeer(url *enode.Node) w3types.RPCCallerFactory[bool] {
  function RemovePeer (line 27) | func RemovePeer(url *enode.Node) w3types.RPCCallerFactory[bool] {
  function AddTrustedPeer (line 36) | func AddTrustedPeer(url *enode.Node) w3types.RPCCallerFactory[bool] {
  function RemoveTrustedPeer (line 45) | func RemoveTrustedPeer(url *enode.Node) w3types.RPCCallerFactory[bool] {
  function NodeInfo (line 53) | func NodeInfo() w3types.RPCCallerFactory[*NodeInfoResponse] {
  type NodeInfoResponse (line 60) | type NodeInfoResponse struct
  type PortsInfo (line 70) | type PortsInfo struct
  type ProtocolInfo (line 75) | type ProtocolInfo struct

FILE: module/admin/admin_test.go
  function TestAddPeer (line 16) | func TestAddPeer(t *testing.T) {
  function TestRemovePeer (line 26) | func TestRemovePeer(t *testing.T) {
  function TestAddTrustedPeer (line 36) | func TestAddTrustedPeer(t *testing.T) {
  function TestRemoveTrustedPeer (line 46) | func TestRemoveTrustedPeer(t *testing.T) {
  function TestNodeInfo (line 56) | func TestNodeInfo(t *testing.T) {

FILE: module/debug/call_trace.go
  function CallTraceCall (line 14) | func CallTraceCall(msg *w3types.Message, blockNumber *big.Int, overrides...
  function CallTraceTx (line 23) | func CallTraceTx(txHash common.Hash, overrides w3types.State) w3types.RP...
  type CallTrace (line 30) | type CallTrace struct
    method UnmarshalJSON (line 45) | func (c *CallTrace) UnmarshalJSON(data []byte) error {
  type traceConfig (line 81) | type traceConfig struct

FILE: module/debug/call_trace_test.go
  function TestCallTraceTx (line 12) | func TestCallTraceTx(t *testing.T) {

FILE: module/debug/trace.go
  function TraceCall (line 18) | func TraceCall(msg *w3types.Message, blockNumber *big.Int, config *Trace...
  function TraceTx (line 30) | func TraceTx(txHash common.Hash, config *TraceConfig) w3types.RPCCallerF...
  type TraceConfig (line 40) | type TraceConfig struct
    method MarshalJSON (line 50) | func (c *TraceConfig) MarshalJSON() ([]byte, error) {
  type Trace (line 72) | type Trace struct
    method UnmarshalJSON (line 79) | func (t *Trace) UnmarshalJSON(data []byte) error {
  type StructLog (line 99) | type StructLog struct
    method UnmarshalJSON (line 110) | func (l *StructLog) UnmarshalJSON(data []byte) error {
  type optionalPrefixedHash (line 146) | type optionalPrefixedHash
    method UnmarshalText (line 148) | func (h *optionalPrefixedHash) UnmarshalText(data []byte) error {
  type memory (line 161) | type memory
    method UnmarshalJSON (line 163) | func (m *memory) UnmarshalJSON(data []byte) error {
  function msgArgsWrapper (line 176) | func msgArgsWrapper(slice []any) ([]any, error) {

FILE: module/debug/trace_test.go
  function TestTraceTx (line 14) | func TestTraceTx(t *testing.T) {
  function TestTraceCall (line 44) | func TestTraceCall(t *testing.T) {

FILE: module/eth/balance.go
  function Balance (line 14) | func Balance(addr common.Address, blockNumber *big.Int) w3types.RPCCalle...

FILE: module/eth/balance_test.go
  function TestBalance (line 12) | func TestBalance(t *testing.T) {

FILE: module/eth/block.go
  function BlockByHash (line 14) | func BlockByHash(hash common.Hash) w3types.RPCCallerFactory[*types.Block] {
  function BlockByNumber (line 24) | func BlockByNumber(number *big.Int) w3types.RPCCallerFactory[*types.Bloc...
  function BlockTxCountByHash (line 34) | func BlockTxCountByHash(hash common.Hash) w3types.RPCCallerFactory[uint] {
  function BlockTxCountByNumber (line 44) | func BlockTxCountByNumber(number *big.Int) w3types.RPCCallerFactory[uint] {
  function HeaderByHash (line 53) | func HeaderByHash(hash common.Hash) w3types.RPCCallerFactory[*types.Head...
  function HeaderByNumber (line 62) | func HeaderByNumber(number *big.Int) w3types.RPCCallerFactory[*types.Hea...
  function blockRetWrapper (line 69) | func blockRetWrapper(ret **types.Block) any { *ret = new(types.Block); r...
  type rpcBlock (line 71) | type rpcBlock struct
    method UnmarshalJSON (line 73) | func (b *rpcBlock) UnmarshalJSON(data []byte) error {

FILE: module/eth/block_number.go
  function BlockNumber (line 11) | func BlockNumber() w3types.RPCCallerFactory[*big.Int] {

FILE: module/eth/block_number_test.go
  function TestBlockNumber (line 12) | func TestBlockNumber(t *testing.T) {

FILE: module/eth/block_test.go
  function TestBlockByHash (line 15) | func TestBlockByHash(t *testing.T) {
  function TestBlockByNumber (line 107) | func TestBlockByNumber(t *testing.T) {
  function TestBlockTxCountByHash (line 172) | func TestBlockTxCountByHash(t *testing.T) {
  function TestBlockTxCountByNumber (line 187) | func TestBlockTxCountByNumber(t *testing.T) {
  function TestHeaderByHash (line 197) | func TestHeaderByHash(t *testing.T) {
  function TestHeaderByNumber (line 224) | func TestHeaderByNumber(t *testing.T) {
  function ptr (line 251) | func ptr[T any](v T) *T { return &v }

FILE: module/eth/call.go
  function Call (line 18) | func Call(msg *w3types.Message, blockNumber *big.Int, overrides w3types....
  function EstimateGas (line 35) | func EstimateGas(msg *w3types.Message, blockNumber *big.Int) w3types.RPC...
  function AccessList (line 47) | func AccessList(msg *w3types.Message, blockNumber *big.Int) w3types.RPCC...
  type AccessListResponse (line 55) | type AccessListResponse struct
    method UnmarshalJSON (line 61) | func (resp *AccessListResponse) UnmarshalJSON(data []byte) error {
  function msgArgsWrapper (line 77) | func msgArgsWrapper(slice []any) ([]any, error) {
  function CallFunc (line 94) | func CallFunc(contract common.Address, f w3types.Func, args ...any) *Cal...
  type CallFuncFactory (line 102) | type CallFuncFactory struct
    method Returns (line 113) | func (f *CallFuncFactory) Returns(returns ...any) w3types.RPCCaller {
    method From (line 118) | func (f *CallFuncFactory) From(from common.Address) *CallFuncFactory {
    method Value (line 123) | func (f *CallFuncFactory) Value(value *big.Int) *CallFuncFactory {
    method AtBlock (line 128) | func (f *CallFuncFactory) AtBlock(blockNumber *big.Int) *CallFuncFacto...
    method Overrides (line 133) | func (f *CallFuncFactory) Overrides(overrides w3types.State) *CallFunc...
    method CreateRequest (line 138) | func (f *CallFuncFactory) CreateRequest() (rpc.BatchElem, error) {
    method HandleResponse (line 160) | func (f *CallFuncFactory) HandleResponse(elem rpc.BatchElem) error {

FILE: module/eth/call_test.go
  function TestCall (line 17) | func TestCall(t *testing.T) {
  function TestCallFunc (line 46) | func TestCallFunc(t *testing.T) {
  function TestEstimateGas (line 67) | func TestEstimateGas(t *testing.T) {
  function TestAccessList (line 81) | func TestAccessList(t *testing.T) {

FILE: module/eth/chain_id.go
  function ChainID (line 9) | func ChainID() w3types.RPCCallerFactory[uint64] {

FILE: module/eth/chain_id_test.go
  function TestChainID (line 10) | func TestChainID(t *testing.T) {

FILE: module/eth/code.go
  function Code (line 14) | func Code(addr common.Address, blockNumber *big.Int) w3types.RPCCallerFa...

FILE: module/eth/code_test.go
  function TestCode (line 11) | func TestCode(t *testing.T) {

FILE: module/eth/gas_price.go
  function GasPrice (line 11) | func GasPrice() w3types.RPCCallerFactory[*big.Int] {

FILE: module/eth/gas_price_test.go
  function TestGasPrice (line 12) | func TestGasPrice(t *testing.T) {

FILE: module/eth/gas_tip_cap.go
  function GasTipCap (line 12) | func GasTipCap() w3types.RPCCallerFactory[*big.Int] {

FILE: module/eth/gas_tip_cap_test.go
  function TestGasTipCap (line 12) | func TestGasTipCap(t *testing.T) {

FILE: module/eth/get_logs.go
  function Logs (line 14) | func Logs(q ethereum.FilterQuery) w3types.RPCCallerFactory[[]types.Log] {
  type logsFactory (line 18) | type logsFactory struct
    method Returns (line 26) | func (f *logsFactory) Returns(logs *[]types.Log) w3types.RPCCaller {
    method CreateRequest (line 32) | func (f *logsFactory) CreateRequest() (rpc.BatchElem, error) {
    method HandleResponse (line 46) | func (f *logsFactory) HandleResponse(elem rpc.BatchElem) error {
  function toFilterArg (line 53) | func toFilterArg(q ethereum.FilterQuery) (any, error) {

FILE: module/eth/get_logs_test.go
  function TestLogs (line 15) | func TestLogs(t *testing.T) {

FILE: module/eth/storage_at.go
  function StorageAt (line 15) | func StorageAt(addr common.Address, slot common.Hash, blockNumber *big.I...

FILE: module/eth/storage_at_test.go
  function TestStorageAt (line 12) | func TestStorageAt(t *testing.T) {

FILE: module/eth/subscribe.go
  function NewHeads (line 10) | func NewHeads(ch chan<- *types.Header) w3types.RPCSubscriber {
  function PendingTransactions (line 15) | func PendingTransactions(ch chan<- *types.Transaction) w3types.RPCSubscr...
  function NewLogs (line 20) | func NewLogs(ch chan<- *types.Log, q ethereum.FilterQuery) w3types.RPCSu...
  type ethSubscription (line 25) | type ethSubscription struct
  method CreateRequest (line 31) | func (s *ethSubscription[T]) CreateRequest() (string, any, []any, error) {

FILE: module/eth/syncing.go
  function Syncing (line 9) | func Syncing() w3types.RPCCallerFactory[bool] {
  function syncingRetWrapper (line 17) | func syncingRetWrapper(ret *bool) any {
  type syncingBool (line 21) | type syncingBool
    method UnmarshalJSON (line 23) | func (s *syncingBool) UnmarshalJSON(b []byte) error {

FILE: module/eth/syncing_test.go
  function TestSyncing (line 10) | func TestSyncing(t *testing.T) {

FILE: module/eth/tx.go
  function Tx (line 14) | func Tx(hash common.Hash) w3types.RPCCallerFactory[*types.Transaction] {
  function TxByBlockHashAndIndex (line 22) | func TxByBlockHashAndIndex(blockHash common.Hash, index uint64) w3types....
  function TxByBlockNumberAndIndex (line 30) | func TxByBlockNumberAndIndex(blockNumber *big.Int, index uint64) w3types...
  function SendRawTx (line 38) | func SendRawTx(rawTx []byte) w3types.RPCCallerFactory[common.Hash] {
  function SendTx (line 46) | func SendTx(tx *types.Transaction) w3types.RPCCallerFactory[common.Hash] {
  function TxReceipt (line 63) | func TxReceipt(txHash common.Hash) w3types.RPCCallerFactory[*types.Recei...
  function BlockReceipts (line 71) | func BlockReceipts(number *big.Int) w3types.RPCCallerFactory[types.Recei...
  function Nonce (line 81) | func Nonce(addr common.Address, blockNumber *big.Int) w3types.RPCCallerF...

FILE: module/eth/tx_test.go
  function TestTx (line 31) | func TestTx(t *testing.T) {
  function TestTxByBlockNumberAndIndex (line 63) | func TestTxByBlockNumberAndIndex(t *testing.T) {
  function TestSendTx (line 77) | func TestSendTx(t *testing.T) {
  function TestTxReceipt (line 87) | func TestTxReceipt(t *testing.T) {
  function TestBlockReceipts (line 129) | func TestBlockReceipts(t *testing.T) {
  function TestNonce (line 168) | func TestNonce(t *testing.T) {

FILE: module/eth/uncle.go
  function UncleByBlockHashAndIndex (line 15) | func UncleByBlockHashAndIndex(hash common.Hash, index uint) w3types.RPCC...
  function UncleByBlockNumberAndIndex (line 24) | func UncleByBlockNumberAndIndex(number *big.Int, index uint) w3types.RPC...
  function UncleCountByBlockHash (line 33) | func UncleCountByBlockHash(hash common.Hash) w3types.RPCCallerFactory[ui...
  function UncleCountByBlockNumber (line 43) | func UncleCountByBlockNumber(number *big.Int) w3types.RPCCallerFactory[u...

FILE: module/eth/uncle_test.go
  function blockNonce (line 33) | func blockNonce(data []byte) (nonce types.BlockNonce) {
  function blockBloom (line 38) | func blockBloom(data []byte) (bloom types.Bloom) {
  function TestUncleByBlockHashAndIndex (line 43) | func TestUncleByBlockHashAndIndex(t *testing.T) {
  function TestUncleByBlockNumberAndIndex (line 58) | func TestUncleByBlockNumberAndIndex(t *testing.T) {
  function TestUncleCountByBlockHash (line 68) | func TestUncleCountByBlockHash(t *testing.T) {
  function TestUncleCountByBlockNumber (line 78) | func TestUncleCountByBlockNumber(t *testing.T) {

FILE: module/net/net.go
  function Listening (line 12) | func Listening() w3types.RPCCallerFactory[bool] {
  function PeerCount (line 20) | func PeerCount() w3types.RPCCallerFactory[int] {
  function Version (line 28) | func Version() w3types.RPCCallerFactory[int] {

FILE: module/net/net_test.go
  function TestListening (line 10) | func TestListening(t *testing.T) {
  function TestPeerCount (line 20) | func TestPeerCount(t *testing.T) {
  function TestVersion (line 30) | func TestVersion(t *testing.T) {

FILE: module/txpool/content.go
  function Content (line 14) | func Content() w3types.RPCCallerFactory[*ContentResponse] {
  function ContentFrom (line 23) | func ContentFrom(addr common.Address) w3types.RPCCallerFactory[*ContentF...
  type ContentResponse (line 30) | type ContentResponse struct
    method UnmarshalJSON (line 35) | func (c *ContentResponse) UnmarshalJSON(data []byte) error {
  type ContentFromResponse (line 69) | type ContentFromResponse struct
    method UnmarshalJSON (line 74) | func (cf *ContentFromResponse) UnmarshalJSON(data []byte) error {

FILE: module/txpool/content_test.go
  function TestContent (line 14) | func TestContent(t *testing.T) {
  function TestContentFrom (line 57) | func TestContentFrom(t *testing.T) {

FILE: module/txpool/status.go
  function Status (line 12) | func Status() w3types.RPCCallerFactory[*StatusResponse] {
  type StatusResponse (line 19) | type StatusResponse struct
    method UnmarshalJSON (line 24) | func (s *StatusResponse) UnmarshalJSON(data []byte) error {

FILE: module/txpool/status_test.go
  function TestStatus (line 10) | func TestStatus(t *testing.T) {

FILE: module/web3/web3.go
  function ClientVersion (line 12) | func ClientVersion() w3types.RPCCallerFactory[string] {

FILE: module/web3/web3_test.go
  function TestClientVersion (line 11) | func TestClientVersion(t *testing.T) {

FILE: rpctest/server.go
  type Server (line 26) | type Server struct
    method ServeHTTP (line 58) | func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    method URL (line 78) | func (srv *Server) URL() string {
    method Close (line 83) | func (srv *Server) Close() {
    method readGolden (line 87) | func (srv *Server) readGolden() {
  function NewServer (line 39) | func NewServer(t *testing.T, r io.Reader) *Server {
  function NewFileServer (line 49) | func NewFileServer(t *testing.T, filename string) *Server {

FILE: rpctest/test_case.go
  type TestCase (line 16) | type TestCase struct
  function RunTestCases (line 23) | func RunTestCases[T any](t *testing.T, tests []TestCase[T], opts ...cmp....
  function comp (line 43) | func comp[T any](t *testing.T, wantVal, gotVal T, wantErr, gotErr error,...

FILE: util.go
  function A (line 67) | func A(hexAddr string) (addr common.Address) {
  function APtr (line 83) | func APtr(hexAddress string) *common.Address {
  function B (line 93) | func B(hexBytes ...string) (bytes []byte) {
  function H (line 112) | func H(hexHash string) (hash common.Hash) {
  function I (line 139) | func I(strInt string) *big.Int {
  function parseHexBig (line 146) | func parseHexBig(hexBig string) *big.Int {
  function parseDecimal (line 154) | func parseDecimal(strBig string) *big.Int {
  function FromWei (line 210) | func FromWei(wei *big.Int, decimals uint8) string {
  function has0xPrefix (line 232) | func has0xPrefix(hexStr string) bool {
  function BigMin (line 237) | func BigMin(a, b *big.Int) *big.Int {
  function BigMax (line 245) | func BigMax(a, b *big.Int) *big.Int {

FILE: util_test.go
  function ExampleI (line 14) | func ExampleI() {
  function ExampleFromWei (line 26) | func ExampleFromWei() {
  function TestA (line 33) | func TestA(t *testing.T) {
  function TestB (line 71) | func TestB(t *testing.T) {
  function TestH (line 103) | func TestH(t *testing.T) {
  function TestI (line 141) | func TestI(t *testing.T) {
  function strBig (line 211) | func strBig(s string) *big.Int {
  function FuzzI (line 216) | func FuzzI(f *testing.F) {
  function BenchmarkI (line 232) | func BenchmarkI(b *testing.B) {
  function TestFromWei (line 251) | func TestFromWei(t *testing.T) {
  function TestBigMin (line 294) | func TestBigMin(t *testing.T) {
  function TestBigMax (line 313) | func TestBigMax(t *testing.T) {

FILE: w3types/interfaces.go
  type Func (line 9) | type Func interface
  type RPCCaller (line 23) | type RPCCaller interface
  type RPCCallerFactory (line 32) | type RPCCallerFactory interface
  type RPCSubscriber (line 39) | type RPCSubscriber interface

FILE: w3types/interfaces_test.go
  function TxBySenderAndNonceFactory (line 13) | func TxBySenderAndNonceFactory(sender common.Address, nonce uint64) w3ty...
  type getTransactionBySenderAndNonceFactory (line 23) | type getTransactionBySenderAndNonceFactory struct
    method Returns (line 35) | func (f *getTransactionBySenderAndNonceFactory) Returns(txHash *common...
    method CreateRequest (line 43) | func (f *getTransactionBySenderAndNonceFactory) CreateRequest() (rpc.B...
    method HandleResponse (line 54) | func (f *getTransactionBySenderAndNonceFactory) HandleResponse(elem rp...
  function ExampleRPCCaller_getTransactionBySenderAndNonce (line 61) | func ExampleRPCCaller_getTransactionBySenderAndNonce() {

FILE: w3types/message.go
  type Message (line 18) | type Message struct
    method Set (line 38) | func (msg *Message) Set(msg2 *Message) *Message {
    method SetTx (line 58) | func (msg *Message) SetTx(tx *types.Transaction, signer types.Signer) ...
    method MustSetTx (line 81) | func (msg *Message) MustSetTx(tx *types.Transaction, signer types.Sign...
    method SetCallMsg (line 90) | func (msg *Message) SetCallMsg(callMsg ethereum.CallMsg) *Message {
    method MarshalJSON (line 123) | func (msg *Message) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 164) | func (msg *Message) UnmarshalJSON(data []byte) error {
  type message (line 105) | type message struct

FILE: w3types/rpc.go
  type BlockOverrides (line 11) | type BlockOverrides struct
    method MarshalJSON (line 33) | func (o BlockOverrides) MarshalJSON() ([]byte, error) {
  type blockOverrides (line 22) | type blockOverrides struct

FILE: w3types/rpc_test.go
  function TestBlockOverrides_MarshalJSON (line 13) | func TestBlockOverrides_MarshalJSON(t *testing.T) {

FILE: w3types/state.go
  type State (line 16) | type State
    method SetGenesisAlloc (line 20) | func (s State) SetGenesisAlloc(alloc types.GenesisAlloc) State {
    method Merge (line 35) | func (s State) Merge(other State) (merged State) {
  type Account (line 54) | type Account struct
    method deepCopy (line 64) | func (acc *Account) deepCopy() *Account {
    method merge (line 79) | func (dst *Account) merge(src *Account) {
    method CodeHash (line 105) | func (acc *Account) CodeHash() common.Hash {
    method MarshalJSON (line 121) | func (acc *Account) MarshalJSON() ([]byte, error) {
  type Storage (line 145) | type Storage

FILE: w3types/state_test.go
  function TestStateMerge (line 12) | func TestStateMerge(t *testing.T) {

FILE: w3vm/bench_test.go
  function BenchmarkVM (line 27) | func BenchmarkVM(b *testing.B) {
  function BenchmarkVMCall (line 111) | func BenchmarkVMCall(b *testing.B) {
  function BenchmarkVMSnapshot (line 201) | func BenchmarkVMSnapshot(b *testing.B) {

FILE: w3vm/db.go
  type db (line 21) | type db struct
    method Has (line 37) | func (db *db) Has(addr common.Address, codeHash common.Hash) bool {
    method Code (line 42) | func (db *db) Code(addr common.Address, codeHash common.Hash) ([]byte,...
    method CodeSize (line 54) | func (db *db) CodeSize(addr common.Address, codeHash common.Hash) (int...
    method Account (line 62) | func (db *db) Account(addr common.Address) (*types.StateAccount, error) {
    method Storage (line 73) | func (db *db) Storage(addr common.Address, slot common.Hash) (common.H...
    method Reader (line 91) | func (db *db) Reader(common.Hash) (state.Reader, error) { return db, n...
    method OpenTrie (line 93) | func (db *db) OpenTrie(common.Hash) (state.Trie, error) { return fakeT...
    method OpenStorageTrie (line 95) | func (db *db) OpenStorageTrie(common.Hash, common.Address, common.Hash...
    method TrieDB (line 99) | func (*db) TrieDB() *triedb.Database { return fakeTrieDB }
    method Snapshot (line 101) | func (*db) Snapshot() *snapshot.Tree { panic("not implemented") }
  function newDB (line 25) | func newDB(fetcher Fetcher) *db {

FILE: w3vm/example_test.go
  function ExampleVM_simpleTransfer (line 31) | func ExampleVM_simpleTransfer() {
  function ExampleVM_fakeTokenBalance (line 62) | func ExampleVM_fakeTokenBalance() {
  function ExampleVM_call (line 114) | func ExampleVM_call() {
  function ExampleVM_callFunc (line 146) | func ExampleVM_callFunc() {
  function ExampleVM_uniswapV3Swap (line 169) | func ExampleVM_uniswapV3Swap() {
  function ExampleVM_prankZeroAddress (line 249) | func ExampleVM_prankZeroAddress() {
  function ExampleVM_traceCalls (line 278) | func ExampleVM_traceCalls() {
  function ExampleVM_traceAccessList (line 307) | func ExampleVM_traceAccessList() {
  function ExampleVM_traceBlock (line 350) | func ExampleVM_traceBlock() {
  function TestWETHDeposit (line 383) | func TestWETHDeposit(t *testing.T) {
  function FuzzWETHDeposit (line 420) | func FuzzWETHDeposit(f *testing.F) {
  function ExampleWETHBalanceSlot (line 463) | func ExampleWETHBalanceSlot() {

FILE: w3vm/fetcher.go
  type Fetcher (line 32) | type Fetcher interface
  type rpcFetcher (line 46) | type rpcFetcher struct
    method Account (line 86) | func (f *rpcFetcher) Account(addr common.Address) (a *types.StateAccou...
    method Code (line 135) | func (f *rpcFetcher) Code(codeHash common.Hash) ([]byte, error) {
    method StorageAt (line 145) | func (f *rpcFetcher) StorageAt(addr common.Address, slot common.Hash) ...
    method HeaderHash (line 172) | func (f *rpcFetcher) HeaderHash(blockNumber uint64) (common.Hash, erro...
    method call (line 197) | func (f *rpcFetcher) call(calls ...w3types.RPCCaller) error {
    method loadTestdataState (line 250) | func (f *rpcFetcher) loadTestdataState(chainID uint64) (err error) {
    method storeTestdataState (line 312) | func (f *rpcFetcher) storeTestdataState(chainID uint64) (err error) {
  function NewRPCFetcher (line 71) | func NewRPCFetcher(client *w3.Client, blockNumber *big.Int) Fetcher {
  function newRPCFetcher (line 75) | func newRPCFetcher(client *w3.Client, blockNumber *big.Int) *rpcFetcher {
  function NewTestingRPCFetcher (line 207) | func NewTestingRPCFetcher(tb testing.TB, chainID uint64, client *w3.Clie...
  type storageKey (line 422) | type storageKey struct
  type testdataState (line 429) | type testdataState
    method Merge (line 431) | func (s testdataState) Merge(other testdataState) error {
  type testdataAccount (line 445) | type testdataAccount struct
    method codeHash (line 452) | func (a *testdataAccount) codeHash() common.Hash {
    method Merge (line 459) | func (a *testdataAccount) Merge(other *testdataAccount) error {
  type testdataContracts (line 490) | type testdataContracts
    method Merge (line 492) | func (c testdataContracts) Merge(other testdataContracts) error {
  type testdataHeaderHashes (line 506) | type testdataHeaderHashes
    method Merge (line 508) | func (h testdataHeaderHashes) Merge(other testdataHeaderHashes) error {
  function readTestdata (line 521) | func readTestdata(filename string, data any, onlyIfModifiedAfter time.Ti...
  function writeTestdata (line 549) | func writeTestdata(filename string, data any) error {
  function testdataPath (line 575) | func testdataPath(filename string) string {

FILE: w3vm/fetcher_test.go
  function TestTestdataContractsMerge (line 16) | func TestTestdataContractsMerge(t *testing.T) {
  function TestTestdataHeaderHashesMerge (line 79) | func TestTestdataHeaderHashesMerge(t *testing.T) {
  function TestTestdataAccountMerge (line 142) | func TestTestdataAccountMerge(t *testing.T) {
  function TestTestdataStateMerge (line 263) | func TestTestdataStateMerge(t *testing.T) {

FILE: w3vm/hooks/call_tracer.go
  type CallTracerOptions (line 38) | type CallTracerOptions struct
    method targetStyler (line 50) | func (opts *CallTracerOptions) targetStyler(addr common.Address) lipgl...
    method showOp (line 61) | func (opts *CallTracerOptions) showOp(op byte, pc uint64, addr common....
    method opStyler (line 68) | func (opts *CallTracerOptions) opStyler(op byte) lipgloss.Style {
  function defaultTargetStyler (line 75) | func defaultTargetStyler(addr common.Address) lipgloss.Style {
  function defaultOpStyler (line 84) | func defaultOpStyler(byte) lipgloss.Style {
  function NewCallTracer (line 89) | func NewCallTracer(w io.Writer, opts *CallTracerOptions) *tracing.Hooks {
  type callTracer (line 103) | type callTracer struct
    method EnterHook (line 115) | func (c *callTracer) EnterHook(depth int, typ byte, from common.Addres...
    method ExitHook (line 141) | func (c *callTracer) ExitHook(depth int, output []byte, gasUsed uint64...
    method OpcodeHook (line 159) | func (c *callTracer) OpcodeHook(pc uint64, op byte, gas, cost uint64, ...
    method OnLog (line 167) | func (c *callTracer) OnLog(log *types.Log) {
  function renderIdent (line 173) | func renderIdent(callStack []call, styler func(addr common.Address) lipg...
  function renderAddr (line 191) | func renderAddr(addr common.Address, styler func(addr common.Address) li...
  function renderCallType (line 195) | func renderCallType(typ byte) string {
  function renderValue (line 216) | func renderValue(decodeABI bool, val *big.Int) string {
  function renderInput (line 226) | func renderInput(fn *w3.Func, isPrecompile bool, input []byte, styler fu...
  function renderOutput (line 236) | func renderOutput(fn *w3.Func, output []byte, styler func(addr common.Ad...
  function renderRevert (line 246) | func renderRevert(revertErr error, output []byte, decodeABI bool) string {
  function renderRawInput (line 261) | func renderRawInput(input []byte, styler func(addr common.Address) lipgl...
  function renderRawOutput (line 274) | func renderRawOutput(output []byte, styler func(addr common.Address) lip...
  function renderWord (line 286) | func renderWord(word []byte, _ func(addr common.Address) lipgloss.Style)...
  function renderAbiInput (line 295) | func renderAbiInput(fn *w3.Func, isPrecompile bool, input []byte, styler...
  function renderAbiOutput (line 309) | func renderAbiOutput(fn *w3.Func, output []byte, styler func(addr common...
  function renderAbiArgs (line 318) | func renderAbiArgs(args abi.Arguments, vals []any, styler func(addr comm...
  function renderAbiTyp (line 329) | func renderAbiTyp(typ *abi.Type, name string, val any, styler func(addr ...
  function renderOp (line 451) | func renderOp(op byte, style func(byte) lipgloss.Style, pc uint64, scope...
  type call (line 478) | type call struct
  function opAccessesStackElem (line 486) | func opAccessesStackElem(op byte, i int) bool {

FILE: w3vm/receipt.go
  type Receipt (line 14) | type Receipt struct
    method DecodeReturns (line 28) | func (r Receipt) DecodeReturns(returns ...any) error {

FILE: w3vm/util.go
  function RandA (line 19) | func RandA() (addr common.Address) {
  function WETHBalanceSlot (line 31) | func WETHBalanceSlot(addr common.Address) common.Hash {
  function WETHAllowanceSlot (line 37) | func WETHAllowanceSlot(owner, spender common.Address) common.Hash {
  function SoliditySlot (line 44) | func SoliditySlot(pos, key common.Hash) common.Hash {
  function SoliditySlot2 (line 52) | func SoliditySlot2(pos, key0, key1 common.Hash) common.Hash {
  function SoliditySlot3 (line 63) | func SoliditySlot3(pos, key0, key1, key2 common.Hash) common.Hash {
  function VyperSlot (line 76) | func VyperSlot(pos, key common.Hash) common.Hash {
  function VyperSlot2 (line 84) | func VyperSlot2(pos, key0, key1 common.Hash) common.Hash {
  function VyperSlot3 (line 95) | func VyperSlot3(pos, key0, key1, key2 common.Hash) common.Hash {
  function Slot (line 112) | func Slot(pos, key common.Hash) common.Hash {
  function Slot2 (line 124) | func Slot2(pos, key0, key1 common.Hash) common.Hash {
  function Slot3 (line 136) | func Slot3(pos, key0, key1, key2 common.Hash) common.Hash {
  function zeroHashFunc (line 141) | func zeroHashFunc(uint64) common.Hash {
  function ethBalance (line 150) | func ethBalance(addr common.Address, blockNumber *big.Int) w3types.RPCCa...
  function ethHeaderHash (line 159) | func ethHeaderHash(blockNumber uint64) w3types.RPCCallerFactory[header] {
  type header (line 166) | type header struct
  function joinHooks (line 175) | func joinHooks(hooks []*tracing.Hooks) *tracing.Hooks {

FILE: w3vm/util_test.go
  function TestWETHBalanceSlot (line 12) | func TestWETHBalanceSlot(t *testing.T) {
  function TestWETHAllowanceSlot (line 37) | func TestWETHAllowanceSlot(t *testing.T) {

FILE: w3vm/vm.go
  type VM (line 40) | type VM struct
    method Apply (line 83) | func (vm *VM) Apply(msg *w3types.Message, hooks ...*tracing.Hooks) (*R...
    method ApplyTx (line 88) | func (vm *VM) ApplyTx(tx *types.Transaction, hooks ...*tracing.Hooks) ...
    method apply (line 96) | func (v *VM) apply(msg *w3types.Message, isCall bool, hooks *tracing.H...
    method Call (line 179) | func (vm *VM) Call(msg *w3types.Message, hooks ...*tracing.Hooks) (*Re...
    method CallFunc (line 196) | func (vm *VM) CallFunc(contract common.Address, f w3types.Func, args ....
    method Nonce (line 218) | func (vm *VM) Nonce(addr common.Address) (uint64, error) {
    method SetNonce (line 227) | func (vm *VM) SetNonce(addr common.Address, nonce uint64) {
    method Balance (line 232) | func (vm *VM) Balance(addr common.Address) (*big.Int, error) {
    method SetBalance (line 241) | func (vm *VM) SetBalance(addr common.Address, balance *big.Int) {
    method Code (line 246) | func (vm *VM) Code(addr common.Address) ([]byte, error) {
    method SetCode (line 255) | func (vm *VM) SetCode(addr common.Address, code []byte) {
    method StorageAt (line 260) | func (vm *VM) StorageAt(addr common.Address, slot common.Hash) (common...
    method SetStorageAt (line 269) | func (vm *VM) SetStorageAt(addr common.Address, slot, val common.Hash) {
    method Snapshot (line 275) | func (vm *VM) Snapshot() *state.StateDB { return vm.db.Copy() }
    method Rollback (line 278) | func (vm *VM) Rollback(snapshot *state.StateDB) {
    method buildMessage (line 283) | func (v *VM) buildMessage(msg *w3types.Message, skipAccChecks bool) (*...
    method Clone (line 419) | func (vm *VM) Clone() *VM {
  function New (line 48) | func New(opts ...Option) (*VM, error) {
  type CallFuncFactory (line 205) | type CallFuncFactory struct
    method Returns (line 210) | func (cff *CallFuncFactory) Returns(returns ...any) error {
  function newBlockContext (line 358) | func newBlockContext(config *params.ChainConfig, h *types.Header, getHas...
  function defaultBlockContext (line 396) | func defaultBlockContext() *vm.BlockContext {
  type options (line 431) | type options struct
    method Signer (line 449) | func (opt *options) Signer() types.Signer {
    method Init (line 456) | func (opts *options) Init() error {
  function fetcherHashFunc (line 518) | func fetcherHashFunc(fetcher Fetcher) vm.GetHashFunc {
  type Option (line 526) | type Option
  function WithChainConfig (line 531) | func WithChainConfig(cfg *params.ChainConfig) Option {
  function WithBlockContext (line 536) | func WithBlockContext(ctx *vm.BlockContext) Option {
  function WithPrecompile (line 541) | func WithPrecompile(addr common.Address, contract vm.PrecompiledContract...
  function WithState (line 554) | func WithState(state w3types.State) Option {
  function WithStateDB (line 560) | func WithStateDB(db *state.StateDB) Option {
  function WithNoBaseFee (line 568) | func WithNoBaseFee() Option {
  function WithFork (line 578) | func WithFork(client *w3.Client, blockNumber *big.Int) Option {
  function WithHeader (line 586) | func WithHeader(header *types.Header) Option {
  function WithFetcher (line 591) | func WithFetcher(fetcher Fetcher) Option {
  function WithTB (line 597) | func WithTB(tb testing.TB) Option {
  function WithJumpDestCache (line 602) | func WithJumpDestCache(cache vm.JumpDestCache) Option {

FILE: w3vm/vm_test.go
  function TestVMSetNonce (line 54) | func TestVMSetNonce(t *testing.T) {
  function TestVMSetBalance (line 69) | func TestVMSetBalance(t *testing.T) {
  function TestVMSetCode (line 84) | func TestVMSetCode(t *testing.T) {
  function TestVMSetStorage (line 99) | func TestVMSetStorage(t *testing.T) {
  function TestVMApply (line 114) | func TestVMApply(t *testing.T) {
  function TestVMApply_Hook (line 298) | func TestVMApply_Hook(t *testing.T) {
  function TestVMSnapshot (line 340) | func TestVMSnapshot(t *testing.T) {
  function TestVMSnapshot_Logs (line 392) | func TestVMSnapshot_Logs(t *testing.T) {
  function TestVMCall (line 566) | func TestVMCall(t *testing.T) {
  function TestVMCallFunc (line 617) | func TestVMCallFunc(t *testing.T) {
  function TestVM_Fetcher (line 640) | func TestVM_Fetcher(t *testing.T) {
  function TestVM_BaseFee (line 674) | func TestVM_BaseFee(t *testing.T) {
  type testFetcher (line 764) | type testFetcher struct
    method Account (line 766) | func (f *testFetcher) Account(addr common.Address) (*types.StateAccoun...
    method Code (line 770) | func (f *testFetcher) Code(codeHash common.Hash) ([]byte, error) {
    method StorageAt (line 774) | func (f *testFetcher) StorageAt(addr common.Address, key common.Hash) ...
    method HeaderHash (line 778) | func (f *testFetcher) HeaderHash(blockNumber uint64) (common.Hash, err...
  function TestVMApply_Integration (line 782) | func TestVMApply_Integration(t *testing.T) {
  function mustEncodeArgs (line 890) | func mustEncodeArgs(f w3types.Func, args ...any) []byte {
  function BenchmarkTransferWETH9 (line 898) | func BenchmarkTransferWETH9(b *testing.B) {
  function TestVMClone (line 977) | func TestVMClone(t *testing.T) {
  type mockPrecompile (line 1113) | type mockPrecompile struct
    method RequiredGas (line 1115) | func (m *mockPrecompile) RequiredGas(input []byte) uint64  { return 100 }
    method Run (line 1116) | func (m *mockPrecompile) Run(input []byte) ([]byte, error) { return in...
    method Name (line 1117) | func (m *mockPrecompile) Name() string                     { return "m...
  function ptr (line 1119) | func ptr[T any](t T) *T { return &t }
Condensed preview — 263 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,958K chars).
[
  {
    "path": ".gitattributes",
    "chars": 34,
    "preview": "testdata/ linguist-generated=true\n"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 108,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/doc.yml",
    "chars": 910,
    "preview": "name: Doc\n\non:\n  push:\n    branches: [main]\n    tags: [\"v*\"]\n  pull_request:\n\njobs:\n  build:\n    name: Build\n    runs-on"
  },
  {
    "path": ".github/workflows/go.yml",
    "chars": 1015,
    "preview": "name: Go\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-lates"
  },
  {
    "path": ".gitignore",
    "chars": 47,
    "preview": "# files\nLOCK\n\n# dirs\n.next/\nnode_modules/\nout/\n"
  },
  {
    "path": "LICENSE",
    "chars": 1066,
    "preview": "MIT License\n\nCopyright (c) 2022 lmittmann\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\n"
  },
  {
    "path": "README.md",
    "chars": 15430,
    "preview": "# `w3`: Enhanced Ethereum Integration for Go\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/lmittmann/w3.svg)](ht"
  },
  {
    "path": "client.go",
    "chars": 5727,
    "preview": "/*\nPackage w3 is your toolbelt for integrating with Ethereum in Go. Closely linked\nto [go-ethereum], it provides an ergo"
  },
  {
    "path": "client_test.go",
    "chars": 7113,
    "preview": "package w3_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"flag\"\n\t\"math/big\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/ethereum"
  },
  {
    "path": "docs/components/DocLink.jsx",
    "chars": 1037,
    "preview": "import { Link } from 'nextra-theme-docs'\nimport { Code } from 'nextra/components'\n\nconst pkgNameToPath = {\n    'w3': 'gi"
  },
  {
    "path": "docs/next.config.js",
    "chars": 316,
    "preview": "import nextra from 'nextra'\n\nconst withNextra = nextra({\n\ttheme: 'nextra-theme-docs',\n\tthemeConfig: './theme.config.jsx'"
  },
  {
    "path": "docs/package.json",
    "chars": 355,
    "preview": "{\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"next dev\",\n\t\t\"build\": \"next build\"\n\t},\n\t\"dependencies\": {\n\t\t\"next\": \"^14.2."
  },
  {
    "path": "docs/pages/404.mdx",
    "chars": 51,
    "preview": "# Page Not Found\n\nGet back on track: [Homepage](/)\n"
  },
  {
    "path": "docs/pages/_app.js",
    "chars": 395,
    "preview": "import './style.css'\nimport 'nextra-theme-docs/style.css'\nimport { Inter } from 'next/font/google'\n\nconst inter = Inter("
  },
  {
    "path": "docs/pages/_meta.js",
    "chars": 1887,
    "preview": "export default {\n    index: {\n        title: 'Overview',\n        display: 'hidden',\n        theme: { breadcrumb: false, "
  },
  {
    "path": "docs/pages/examples/_meta.js",
    "chars": 161,
    "preview": "export default {\n    index: {\n        title: 'Examples',\n        display: 'hidden',\n        theme: { breadcrumb: false, "
  },
  {
    "path": "docs/pages/examples/index.mdx",
    "chars": 3583,
    "preview": "# Examples\n\n## `w3.Client` Examples\n\n* **Batch Fetch** 1000 blocks ([Playground](https://pkg.go.dev/github.com/lmittmann"
  },
  {
    "path": "docs/pages/examples.mdx",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/pages/helper-abi.mdx",
    "chars": 7706,
    "preview": "# ABI Bindings\n\nABI bindings allow the encoding and decoding of Smart Contract function calls or the decoding of events."
  },
  {
    "path": "docs/pages/helper-utils.mdx",
    "chars": 506,
    "preview": "# Utils\n\nStatic addresses, hashes, bytes or integers can be parsed from (hex-)strings with the following utility functio"
  },
  {
    "path": "docs/pages/index.mdx",
    "chars": 2202,
    "preview": "---\ndescription: 'w3: Enhanced Ethereum Integration for Go'\n---\n\n# `w3`: Enhanced Ethereum Integration for Go\n\n<div clas"
  },
  {
    "path": "docs/pages/rpc-extension.mdx",
    "chars": 2088,
    "preview": "# Custom RPC Method Bindings\n\nCustom RPC method bindings can be created by implementing the <DocLink title=\"w3types.RPCC"
  },
  {
    "path": "docs/pages/rpc-methods/_meta.js",
    "chars": 131,
    "preview": "export default {\n    eth: 'eth',\n    debug: 'debug',\n    txpool: 'txpool',\n    admin: 'admin',\n    net: 'net',\n    web3:"
  },
  {
    "path": "docs/pages/rpc-methods/admin.mdx",
    "chars": 1154,
    "preview": "# `admin`-Namespace\n\nList of supported RPC methods for `w3.Client` in the `admin`-namespace.\n\n## `admin_addPeer`\n`AddPee"
  },
  {
    "path": "docs/pages/rpc-methods/debug.mdx",
    "chars": 933,
    "preview": "# `debug`-Namespace\n\nList of supported RPC methods for `w3.Client` in the `debug`-namespace.\n\n## `debug_traceCall`\n`Trac"
  },
  {
    "path": "docs/pages/rpc-methods/eth.mdx",
    "chars": 6563,
    "preview": "# `eth`-Namespace\n\nList of supported RPC methods for `w3.Client` in the `eth`-namespace.\n\n## `eth_blockNumber`\n`BlockNum"
  },
  {
    "path": "docs/pages/rpc-methods/net.mdx",
    "chars": 610,
    "preview": "# `net`-Namespace\n\nList of supported RPC methods for `w3.Client` in the `net`-namespace.\n\n## `net_listening`\n`Listening`"
  },
  {
    "path": "docs/pages/rpc-methods/txpool.mdx",
    "chars": 769,
    "preview": "# `txpool`-Namespace\n\nList of supported RPC methods for `w3.Client` in the `txpool`-namespace.\n\n## `txpool_content`\n`Con"
  },
  {
    "path": "docs/pages/rpc-methods/web3.mdx",
    "chars": 275,
    "preview": "# `web3`-Namespace\n\nList of supported RPC methods for `w3.Client` in the `web3`-namespace.\n\n## `web3_clientVersion`\n`Cli"
  },
  {
    "path": "docs/pages/rpc-methods.mdx",
    "chars": 1135,
    "preview": "# Methods\n\n`w3` supports most common RPC methods for Ethereum and other EVM chains. If you are in need of a method that "
  },
  {
    "path": "docs/pages/rpc-overview.mdx",
    "chars": 3196,
    "preview": "# RPC Client\n\n<DocLink title=\"w3.Client\" /> is a blazing fast RPC client, built on top of `go-ethereum/rpc.Client`. It i"
  },
  {
    "path": "docs/pages/style.css",
    "chars": 1317,
    "preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n    main {\n        @apply dark:text-neutral-30"
  },
  {
    "path": "docs/pages/vm-overview.mdx",
    "chars": 7801,
    "preview": "# VM\n\n<DocLink title=\"w3vm.VM\" /> is an easy-to-use Ethereum Virtual Machine (EVM), built on top of `go-ethereum`'s `vm."
  },
  {
    "path": "docs/pages/vm-testing.mdx",
    "chars": 5894,
    "preview": "# Contract Testing\n\n`w3vm` can be used to test Smart Contracts in Go utilizing Go's handy testing and fuzzing features.\n"
  },
  {
    "path": "docs/pages/vm-tracing.mdx",
    "chars": 2196,
    "preview": "# Tracing\n\nTracing can give detailed insights into the execution of EVM contracts. `w3vm.VM` supports tracing via `go‑et"
  },
  {
    "path": "docs/postcss.config.cjs",
    "chars": 130,
    "preview": "module.exports = {\n    plugins: {\n        \"tailwindcss/nesting\": {},\n        tailwindcss: {},\n        autoprefixer: {},\n"
  },
  {
    "path": "docs/public/_redirects",
    "chars": 53,
    "preview": "/vm /vm-overview\n/rpc /rpc-overview\n/abi /helper-abi\n"
  },
  {
    "path": "docs/public/robots.txt",
    "chars": 23,
    "preview": "User-agent: *\nAllow: /\n"
  },
  {
    "path": "docs/tailwind.config.js",
    "chars": 183,
    "preview": "module.exports = {\n\tcontent: [\n\t\t'./pages/**/*.{js,jsx,mdx}',\n\t\t'./components/**/*.{js,jsx}',\n\t\t'./theme.config.jsx'\n\t],"
  },
  {
    "path": "docs/theme.config.jsx",
    "chars": 2190,
    "preview": "import Image from 'next/image'\nimport { useConfig } from 'nextra-theme-docs'\nimport { Callout, Cards, Steps } from 'next"
  },
  {
    "path": "event.go",
    "chars": 2991,
    "preview": "package w3\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t"
  },
  {
    "path": "event_test.go",
    "chars": 7084,
    "preview": "package w3_test\n\nimport (\n\t\"math/big\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethe"
  },
  {
    "path": "example_test.go",
    "chars": 14660,
    "preview": "package w3_test\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/ethereum/go-ethereum/common"
  },
  {
    "path": "func.go",
    "chars": 4169,
    "preview": "package w3\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n\t\"github.com/ethereum/go"
  },
  {
    "path": "func_test.go",
    "chars": 24655,
    "preview": "package w3_test\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"math/big\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common"
  },
  {
    "path": "go.mod",
    "chars": 2925,
    "preview": "module github.com/lmittmann/w3\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/charmbracelet/lipgloss v1.1.0\n\tgithub.com/ethereum/go-e"
  },
  {
    "path": "go.sum",
    "chars": 27146,
    "preview": "github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=\ngithub.com/DataDog/zstd v1.4.5/go.mod h1:"
  },
  {
    "path": "internal/abi/arguments.go",
    "chars": 2673,
    "preview": "package abi\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n\t\"github.com/lmittma"
  },
  {
    "path": "internal/abi/arguments_test.go",
    "chars": 21808,
    "preview": "package abi\n\nimport (\n\t\"bytes\"\n\t\"math/big\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/"
  },
  {
    "path": "internal/abi/copy.go",
    "chars": 8062,
    "preview": "package abi\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"reflect\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n\t\"github."
  },
  {
    "path": "internal/abi/copy_test.go",
    "chars": 7528,
    "preview": "package abi\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/go"
  },
  {
    "path": "internal/abi/doc.go",
    "chars": 74,
    "preview": "/*\nPackage abi implements a Solidity ABI lexer and parser.\n*/\npackage abi\n"
  },
  {
    "path": "internal/abi/lexer.go",
    "chars": 7029,
    "preview": "package abi\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n)\n\nt"
  },
  {
    "path": "internal/abi/lexer_test.go",
    "chars": 1547,
    "preview": "package abi\n\nimport (\n\t\"errors\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cm"
  },
  {
    "path": "internal/abi/parser.go",
    "chars": 6891,
    "preview": "package abi\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n)\n\nvar Err"
  },
  {
    "path": "internal/abi/parser_test.go",
    "chars": 19377,
    "preview": "package abi\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n\t\"github."
  },
  {
    "path": "internal/abi/tuple.go",
    "chars": 6754,
    "preview": "package abi\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"reflect\"\n\t\"unicode\"\n\n\t\"github.com/ethereum/go-ethereum/accounts/abi"
  },
  {
    "path": "internal/abi/tuple_test.go",
    "chars": 7423,
    "preview": "package abi\n\nimport (\n\t\"errors\"\n\t\"maps\"\n\t\"math/big\"\n\t\"reflect\"\n\t\"slices\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go"
  },
  {
    "path": "internal/cmp.go",
    "chars": 521,
    "preview": "package internal\n\nimport (\n\t\"github.com/google/go-cmp/cmp\"\n)\n\n// EquateErrors returns a cmp.Option that can be used to c"
  },
  {
    "path": "internal/cmp_test.go",
    "chars": 1001,
    "preview": "package internal\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestEquateErrors("
  },
  {
    "path": "internal/crypto/keccak.go",
    "chars": 1015,
    "preview": "package crypto\n\nimport (\n\t\"sync\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n)\n"
  },
  {
    "path": "internal/fourbyte/events.go",
    "chars": 2180,
    "preview": "// Code generated by \"go generate\"; DO NOT EDIT.\npackage fourbyte\n\nimport \"github.com/lmittmann/w3\"\n\nvar events = map[[3"
  },
  {
    "path": "internal/fourbyte/events.txt",
    "chars": 535,
    "preview": "Approval(address indexed owner, address indexed spender, uint256 value)\nBurn(address indexed sender, uint256 amount0, ui"
  },
  {
    "path": "internal/fourbyte/fourbyte.go",
    "chars": 974,
    "preview": "//go:generate go run gen.go\n\npackage fourbyte\n\nimport (\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/lmittmann"
  },
  {
    "path": "internal/fourbyte/funcs.go",
    "chars": 66609,
    "preview": "// Code generated by \"go generate\"; DO NOT EDIT.\npackage fourbyte\n\nimport \"github.com/lmittmann/w3\"\n\nvar functions = map"
  },
  {
    "path": "internal/fourbyte/funcs.txt",
    "chars": 41316,
    "preview": "_BASE_TOKEN_()\taddress\n_QUOTE_TOKEN_()\taddress\nA()\tuint256\nA_precise()\tuint256\naccessor()\taddress\naccumulateReward(uint3"
  },
  {
    "path": "internal/fourbyte/gen.go",
    "chars": 5920,
    "preview": "//go:build ignore\n\npackage main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"slices\"\n\t\"strings\"\n\t\"sync\"\n\t\"text/template\"\n\n"
  },
  {
    "path": "internal/hexutil/bytes.go",
    "chars": 693,
    "preview": "package hexutil\n\nimport (\n\t\"encoding/hex\"\n)\n\n// Bytes is a byte slice that marshals/unmarshals from a hex-encoded string"
  },
  {
    "path": "internal/hexutil/bytes_test.go",
    "chars": 1017,
    "preview": "package hexutil_test\n\nimport (\n\t\"bytes\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3/internal/hexutil\"\n)\n\nvar bytesT"
  },
  {
    "path": "internal/hexutil/hash.go",
    "chars": 916,
    "preview": "package hexutil\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n)\n\n// Hash is a wrapper ty"
  },
  {
    "path": "internal/hexutil/hash_test.go",
    "chars": 1223,
    "preview": "package hexutil_test\n\nimport (\n\t\"math/big\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com"
  },
  {
    "path": "internal/mod/root.go",
    "chars": 359,
    "preview": "package mod\n\nimport (\n\t\"os/exec\"\n\t\"strings\"\n)\n\n// Root contains the absolute path of the module root. Its value is empty"
  },
  {
    "path": "internal/mod/root_test.go",
    "chars": 223,
    "preview": "package mod_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3/internal/mod\"\n)\n\nfunc TestModRoot(t *testing"
  },
  {
    "path": "internal/module/factory.go",
    "chars": 2166,
    "preview": "package module\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common/hexutil\""
  },
  {
    "path": "internal/module/util.go",
    "chars": 346,
    "preview": "package module\n\nimport (\n\t\"errors\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n)\n\nvar errNotFound = e"
  },
  {
    "path": "internal/module/util_test.go",
    "chars": 412,
    "preview": "package module\n\nimport (\n\t\"math/big\"\n\t\"strconv\"\n\t\"testing\"\n)\n\nfunc TestBlockNumberArg(t *testing.T) {\n\ttests := []struct"
  },
  {
    "path": "module/admin/admin.go",
    "chars": 2194,
    "preview": "/*\nPackage admin implements RPC API bindings for methods in the \"admin\" namespace.\n*/\npackage admin\n\nimport (\n\t\"math/big"
  },
  {
    "path": "module/admin/admin_test.go",
    "chars": 2887,
    "preview": "package admin_test\n\nimport (\n\t\"math/big\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/p2p/enode\"\n\t\"github.com/et"
  },
  {
    "path": "module/admin/testdata/add_peer.golden",
    "chars": 263,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"admin_addPeer\",\"params\":[\"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7"
  },
  {
    "path": "module/admin/testdata/add_trusted_peer.golden",
    "chars": 270,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"admin_addTrustedPeer\",\"params\":[\"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa33"
  },
  {
    "path": "module/admin/testdata/node_info.golden",
    "chars": 864,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"admin_nodeInfo\",\"params\":[]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"enode\":\"enode://44"
  },
  {
    "path": "module/admin/testdata/remove_peer.golden",
    "chars": 266,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"admin_removePeer\",\"params\":[\"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6"
  },
  {
    "path": "module/admin/testdata/remove_trusted_peer.golden",
    "chars": 273,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"admin_removeTrustedPeer\",\"params\":[\"enode://a979fb575495b8d6db44f750317d0f4622bf4c2a"
  },
  {
    "path": "module/debug/call_trace.go",
    "chars": 2390,
    "preview": "package debug\n\nimport (\n\t\"encoding/json\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go"
  },
  {
    "path": "module/debug/call_trace_test.go",
    "chars": 1432,
    "preview": "package debug_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3\"\n\t\"github.com/lmittmann/w3/module/debug\"\n\t\"github.com"
  },
  {
    "path": "module/debug/doc.go",
    "chars": 100,
    "preview": "/*\nPackage debug implements RPC API bindings for methods in the \"debug\" namespace.\n*/\npackage debug\n"
  },
  {
    "path": "module/debug/testdata/traceCall.golden",
    "chars": 468,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"debug_traceCall\",\"params\":[{\"from\":\"0x000000000000000000000000000000000000c0fe\",\"to\""
  },
  {
    "path": "module/debug/testdata/traceCall_callTracer.golden",
    "chars": 569,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"debug_traceCall\",\"params\":[{\"from\":\"0x000000000000000000000000000000000000c0fe\",\"to\""
  },
  {
    "path": "module/debug/testdata/traceTx__1150000_0.golden",
    "chars": 307,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"debug_traceTransaction\",\"params\":[\"0x38f299591902bfada359527fa6b9b597a959c41c6f72a3b"
  },
  {
    "path": "module/debug/testdata/traceTx__12244000_0.golden",
    "chars": 755,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"debug_traceTransaction\",\"params\":[\"0xac503dd98281d4d52c2043e297a6e684d175339a7ebf831"
  },
  {
    "path": "module/debug/testdata/traceTx_revertReason.golden",
    "chars": 464,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"debug_traceTransaction\",\"params\":[\"0x6ea1798a2d0d21db18d6e45ca00f230160b05f172f6022a"
  },
  {
    "path": "module/debug/trace.go",
    "chars": 4915,
    "preview": "package debug\n\nimport (\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t"
  },
  {
    "path": "module/debug/trace_test.go",
    "chars": 1977,
    "preview": "package debug_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/core/vm\"\n\t\"github.com/holiman/uint256\"\n\t\"gith"
  },
  {
    "path": "module/eth/balance.go",
    "chars": 576,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/lmittmann/w3/internal/module\"\n"
  },
  {
    "path": "module/eth/balance_test.go",
    "chars": 566,
    "preview": "package eth_test\n\nimport (\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3\"\n\t\"github.com/lmittmann/w3/module/eth\"\n\t\"gi"
  },
  {
    "path": "module/eth/block.go",
    "chars": 2740,
    "preview": "package eth\n\nimport (\n\t\"encoding/json\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-e"
  },
  {
    "path": "module/eth/block_number.go",
    "chars": 343,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/lmittmann/w3/internal/module\"\n\t\"github.com/lmittmann/w3/w3types\"\n)\n\n// B"
  },
  {
    "path": "module/eth/block_number_test.go",
    "chars": 348,
    "preview": "package eth_test\n\nimport (\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3\"\n\t\"github.com/lmittmann/w3/module/eth\"\n\t\"gi"
  },
  {
    "path": "module/eth/block_test.go",
    "chars": 14782,
    "preview": "package eth_test\n\nimport (\n\t\"errors\"\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethe"
  },
  {
    "path": "module/eth/call.go",
    "chars": 4293,
    "preview": "package eth\n\nimport (\n\t\"encoding/json\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-e"
  },
  {
    "path": "module/eth/call_test.go",
    "chars": 2930,
    "preview": "package eth_test\n\nimport (\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-et"
  },
  {
    "path": "module/eth/chain_id.go",
    "chars": 297,
    "preview": "package eth\n\nimport (\n\t\"github.com/lmittmann/w3/internal/module\"\n\t\"github.com/lmittmann/w3/w3types\"\n)\n\n// ChainID reques"
  },
  {
    "path": "module/eth/chain_id_test.go",
    "chars": 282,
    "preview": "package eth_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3/module/eth\"\n\t\"github.com/lmittmann/w3/rpctest\"\n)\n\nfunc "
  },
  {
    "path": "module/eth/code.go",
    "chars": 561,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/lmittmann/w3/internal/module\"\n"
  },
  {
    "path": "module/eth/code_test.go",
    "chars": 375,
    "preview": "package eth_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3\"\n\t\"github.com/lmittmann/w3/module/eth\"\n\t\"github.com/lmi"
  },
  {
    "path": "module/eth/doc.go",
    "chars": 94,
    "preview": "/*\nPackage eth implements RPC API bindings for methods in the \"eth\" namespace.\n*/\npackage eth\n"
  },
  {
    "path": "module/eth/gas_price.go",
    "chars": 327,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/lmittmann/w3/internal/module\"\n\t\"github.com/lmittmann/w3/w3types\"\n)\n\n// G"
  },
  {
    "path": "module/eth/gas_price_test.go",
    "chars": 339,
    "preview": "package eth_test\n\nimport (\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3\"\n\t\"github.com/lmittmann/w3/module/eth\"\n\t\"gi"
  },
  {
    "path": "module/eth/gas_tip_cap.go",
    "chars": 411,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/lmittmann/w3/internal/module\"\n\t\"github.com/lmittmann/w3/w3types\"\n)\n\n// G"
  },
  {
    "path": "module/eth/gas_tip_cap_test.go",
    "chars": 343,
    "preview": "package eth_test\n\nimport (\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3\"\n\t\"github.com/lmittmann/w3/module/eth\"\n\t\"gi"
  },
  {
    "path": "module/eth/get_logs.go",
    "chars": 1703,
    "preview": "package eth\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/ethereum/go-ethereum\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github."
  },
  {
    "path": "module/eth/get_logs_test.go",
    "chars": 2484,
    "preview": "package eth_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"gi"
  },
  {
    "path": "module/eth/storage_at.go",
    "chars": 716,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/lmittmann/w3/internal/hexutil\""
  },
  {
    "path": "module/eth/storage_at_test.go",
    "chars": 865,
    "preview": "package eth_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/lmittmann/w3\"\n\t\"github.com"
  },
  {
    "path": "module/eth/subscribe.go",
    "chars": 1096,
    "preview": "package eth\n\nimport (\n\t\"github.com/ethereum/go-ethereum\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/lmit"
  },
  {
    "path": "module/eth/syncing.go",
    "chars": 535,
    "preview": "package eth\n\nimport (\n\t\"github.com/lmittmann/w3/internal/module\"\n\t\"github.com/lmittmann/w3/w3types\"\n)\n\n// Syncing reques"
  },
  {
    "path": "module/eth/syncing_test.go",
    "chars": 373,
    "preview": "package eth_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3/module/eth\"\n\t\"github.com/lmittmann/w3/rpctest\"\n)\n\nfunc "
  },
  {
    "path": "module/eth/testdata/block_number.golden",
    "chars": 99,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_blockNumber\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0xc0fe\"}\n"
  },
  {
    "path": "module/eth/testdata/block_transaction_count_by_hash__0x00.golden",
    "chars": 194,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockTransactionCountByHash\",\"params\":[\"0x00000000000000000000000000000000000"
  },
  {
    "path": "module/eth/testdata/block_transaction_count_by_hash__15050000.golden",
    "chars": 196,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockTransactionCountByHash\",\"params\":[\"0xc43d35f6a64f8a64f046c8deb4069572d62"
  },
  {
    "path": "module/eth/testdata/block_transaction_count_by_number__15050000.golden",
    "chars": 140,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockTransactionCountByNumber\",\"params\":[\"0xe5a510\"]}\n< {\"jsonrpc\":\"2.0\",\"id\""
  },
  {
    "path": "module/eth/testdata/call_func.golden",
    "chars": 308,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_call\",\"params\":[{\"to\":\"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\",\"data\":\"0x70a"
  },
  {
    "path": "module/eth/testdata/call_func__overrides.golden",
    "chars": 509,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_call\",\"params\":[{\"to\":\"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\",\"data\":\"0x70a"
  },
  {
    "path": "module/eth/testdata/chain_id.golden",
    "chars": 92,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_chainId\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0x1\"}\n"
  },
  {
    "path": "module/eth/testdata/create_access_list.golden",
    "chars": 429,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_createAccessList\",\"params\":[{\"to\":\"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\",\""
  },
  {
    "path": "module/eth/testdata/estimate_gas.golden",
    "chars": 255,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_estimateGas\",\"params\":[{\"to\":\"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\",\"data\""
  },
  {
    "path": "module/eth/testdata/gas_price.golden",
    "chars": 96,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_gasPrice\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0xc0fe\"}\n"
  },
  {
    "path": "module/eth/testdata/gas_tip_cap.golden",
    "chars": 108,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_maxPriorityFeePerGas\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0xc0fe\"}\n"
  },
  {
    "path": "module/eth/testdata/get_balance.golden",
    "chars": 174,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBalance\",\"params\":[\"0x000000000000000000000000000000000000c0fe\",\"latest\"]}\n< "
  },
  {
    "path": "module/eth/testdata/get_balance__at_block.golden",
    "chars": 172,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBalance\",\"params\":[\"0x000000000000000000000000000000000000c0fe\",\"0xff\"]}\n< {\""
  },
  {
    "path": "module/eth/testdata/get_block_by_hash__0x00.golden",
    "chars": 183,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByHash\",\"params\":[\"0x000000000000000000000000000000000000000000000000000"
  },
  {
    "path": "module/eth/testdata/get_block_by_hash__1.golden",
    "chars": 1610,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByHash\",\"params\":[\"0x88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cd"
  },
  {
    "path": "module/eth/testdata/get_block_by_hash__12965000.golden",
    "chars": 19537,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByHash\",\"params\":[\"0x9b83c12c69edb74f6c8dd5d052765c1adf940e320bd1291696e"
  },
  {
    "path": "module/eth/testdata/get_block_by_hash__18000000.golden",
    "chars": 1896,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByHash\",\"params\":[\"0x95b198e154acbfc64109dfd22d8224fe927fd8dfdedfae01587"
  },
  {
    "path": "module/eth/testdata/get_block_by_hash__46147.golden",
    "chars": 2160,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByHash\",\"params\":[\"0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db"
  },
  {
    "path": "module/eth/testdata/get_block_by_number__1.golden",
    "chars": 1549,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByNumber\",\"params\":[\"0x1\",true]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"di"
  },
  {
    "path": "module/eth/testdata/get_block_by_number__12965000.golden",
    "chars": 19481,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByNumber\",\"params\":[\"0xc5d488\",false]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result"
  },
  {
    "path": "module/eth/testdata/get_block_by_number__46147.golden",
    "chars": 2102,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByNumber\",\"params\":[\"0xb443\",true]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{"
  },
  {
    "path": "module/eth/testdata/get_block_by_number__999999999.golden",
    "chars": 129,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockByNumber\",\"params\":[\"0x3b9ac9ff\",true]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"resul"
  },
  {
    "path": "module/eth/testdata/get_block_receipts.golden",
    "chars": 1694,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getBlockReceipts\",\"params\":[\"0xc0fe\"]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":[{\"blo"
  },
  {
    "path": "module/eth/testdata/get_code.golden",
    "chars": 164,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getCode\",\"params\":[\"0x000000000000000000000000000000000000c0de\",\"latest\"]}\n< {\"j"
  },
  {
    "path": "module/eth/testdata/get_logs.golden",
    "chars": 1563,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getLogs\",\"params\":[{\"fromBlock\":\"0x989680\",\"toBlock\":\"0x98bd90\",\"topics\":[[\"0x0d"
  },
  {
    "path": "module/eth/testdata/get_storage_at.golden",
    "chars": 294,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getStorageAt\",\"params\":[\"0x000000000000000000000000000000000000c0de\",\"0x00000000"
  },
  {
    "path": "module/eth/testdata/get_storage_at__number.golden",
    "chars": 232,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getStorageAt\",\"params\":[\"0x000000000000000000000000000000000000c0de\",\"0x00000000"
  },
  {
    "path": "module/eth/testdata/get_transaction_by_block_hash_and_index.golden",
    "chars": 997,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionByBlockHashAndIndex\",\"params\":[\"0xa32d159805750cbe428b799a49b85dcb"
  },
  {
    "path": "module/eth/testdata/get_transaction_by_block_hash_and_index__300.golden",
    "chars": 205,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionByBlockHashAndIndex\",\"params\":[\"0xa32d159805750cbe428b799a49b85dcb"
  },
  {
    "path": "module/eth/testdata/get_transaction_by_block_number_and_index.golden",
    "chars": 941,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionByBlockNumberAndIndex\",\"params\":[\"0xc5d489\",\"0x62\"]}\n< {\"jsonrpc\":"
  },
  {
    "path": "module/eth/testdata/get_transaction_by_hash__0x00.golden",
    "chars": 184,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionByHash\",\"params\":[\"0x000000000000000000000000000000000000000000000"
  },
  {
    "path": "module/eth/testdata/get_transaction_by_hash__type0.golden",
    "chars": 745,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionByHash\",\"params\":[\"0x2ecd08e86079f08cfc27c326aa01b1c8d62f288d59611"
  },
  {
    "path": "module/eth/testdata/get_transaction_by_hash__type2.golden",
    "chars": 977,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionByHash\",\"params\":[\"0xed382cb554ad10e94921d263a56c670669d6c380bbdac"
  },
  {
    "path": "module/eth/testdata/get_transaction_count.golden",
    "chars": 169,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionCount\",\"params\":[\"0x000000000000000000000000000000000000c0fe\",\"lat"
  },
  {
    "path": "module/eth/testdata/get_transaction_receipt.golden",
    "chars": 1757,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionReceipt\",\"params\":[\"0xed382cb554ad10e94921d263a56c670669d6c380bbda"
  },
  {
    "path": "module/eth/testdata/get_transaction_receipt_0x00.golden",
    "chars": 185,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getTransactionReceipt\",\"params\":[\"0x00000000000000000000000000000000000000000000"
  },
  {
    "path": "module/eth/testdata/send_raw_transaction.golden",
    "chars": 546,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_sendRawTransaction\",\"params\":[\"0x02f8b301820105850712ca0300850789ff970082b886944"
  },
  {
    "path": "module/eth/testdata/syncing__false.golden",
    "chars": 104,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_syncing\",\"params\":[]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":false}\n"
  },
  {
    "path": "module/eth/testdata/syncing__true.golden",
    "chars": 455,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_syncing\",\"params\":[]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"currentBlock\":\"0x3cf5"
  },
  {
    "path": "module/eth/testdata/uncle_by_hash_and_index__15050036.golden",
    "chars": 1620,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getUncleByBlockHashAndIndex\",\"params\":[\"0x7a98a492c1288a8451905bc665cb28d45fbdf8"
  },
  {
    "path": "module/eth/testdata/uncle_by_hash_and_index__15050036_1.golden",
    "chars": 197,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getUncleByBlockHashAndIndex\",\"params\":[\"0x7a98a492c1288a8451905bc665cb28d45fbdf8"
  },
  {
    "path": "module/eth/testdata/uncle_by_number_and_index__15050036.golden",
    "chars": 1564,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getUncleByBlockNumberAndIndex\",\"params\":[\"0xe5a534\",\"0x0\"]}\n< {\"jsonrpc\":\"2.0\",\""
  },
  {
    "path": "module/eth/testdata/uncle_count_by_hash__15050036.golden",
    "chars": 189,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getUncleCountByBlockHash\",\"params\":[\"0x7a98a492c1288a8451905bc665cb28d45fbdf8913"
  },
  {
    "path": "module/eth/testdata/uncle_count_by_number__15050036.golden",
    "chars": 133,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"eth_getUncleCountByBlockNumber\",\"params\":[\"0xe5a534\"]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"re"
  },
  {
    "path": "module/eth/tx.go",
    "chars": 2846,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/he"
  },
  {
    "path": "module/eth/tx_test.go",
    "chars": 7215,
    "preview": "package eth_test\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n\t\"sync/atomic\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"git"
  },
  {
    "path": "module/eth/uncle.go",
    "chars": 1575,
    "preview": "package eth\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/he"
  },
  {
    "path": "module/eth/uncle_test.go",
    "chars": 3270,
    "preview": "package eth_test\n\nimport (\n\t\"errors\"\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/"
  },
  {
    "path": "module/net/net.go",
    "chars": 740,
    "preview": "/*\nPackage net implements RPC API bindings for methods in the \"net\" namespace.\n*/\npackage net\n\nimport (\n\t\"github.com/lmi"
  },
  {
    "path": "module/net/net_test.go",
    "chars": 624,
    "preview": "package net_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3/module/net\"\n\t\"github.com/lmittmann/w3/rpctest\"\n)\n\nfunc "
  },
  {
    "path": "module/net/testdata/listening.golden",
    "chars": 105,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"net_listening\",\"params\":[]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":true}\n"
  },
  {
    "path": "module/net/testdata/peer_count.golden",
    "chars": 103,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"net_peerCount\",\"params\":[]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":10}\n"
  },
  {
    "path": "module/net/testdata/version.golden",
    "chars": 100,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"net_version\",\"params\":[]}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":1}\n"
  },
  {
    "path": "module/txpool/content.go",
    "chars": 2475,
    "preview": "package txpool\n\nimport (\n\t\"encoding/json\"\n\t\"sort\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-et"
  },
  {
    "path": "module/txpool/content_test.go",
    "chars": 4341,
    "preview": "package txpool_test\n\nimport (\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go"
  },
  {
    "path": "module/txpool/doc.go",
    "chars": 103,
    "preview": "/*\nPackage txpool implements RPC API bindings for methods in the \"txpool\" namespace.\n*/\npackage txpool\n"
  },
  {
    "path": "module/txpool/status.go",
    "chars": 797,
    "preview": "package txpool\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\t\"github.com/lmittmann/w3/i"
  },
  {
    "path": "module/txpool/status_test.go",
    "chars": 348,
    "preview": "package txpool_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3/module/txpool\"\n\t\"github.com/lmittmann/w3/rpctest\"\n)\n"
  },
  {
    "path": "module/txpool/testdata/content.golden",
    "chars": 2962,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"txpool_content\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"pending\":{\"0x000454307bB96E303"
  },
  {
    "path": "module/txpool/testdata/contentFrom.golden",
    "chars": 756,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"txpool_contentFrom\",\"params\":[\"0x1ba4ca9ac6ff4cf192c11e8c1624563f302caa87\"]}\n< {\"jso"
  },
  {
    "path": "module/txpool/testdata/status.golden",
    "chars": 121,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"txpool_status\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"pending\":\"0xa\",\"queued\":\"0x7\"}}"
  },
  {
    "path": "module/web3/testdata/client_version.golden",
    "chars": 100,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"Geth\"}\n"
  },
  {
    "path": "module/web3/testdata/client_version__err.golden",
    "chars": 182,
    "preview": "> {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\"}\n< {\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32601,\"message\":\"the"
  },
  {
    "path": "module/web3/web3.go",
    "chars": 371,
    "preview": "/*\nPackage web3 implements RPC API bindings for methods in the \"web3\" namespace.\n*/\npackage web3\n\nimport (\n\t\"github.com/"
  },
  {
    "path": "module/web3/web3_test.go",
    "chars": 502,
    "preview": "package web3_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/lmittmann/w3/module/web3\"\n\t\"github.com/lmittmann/w3/rpcte"
  },
  {
    "path": "rpctest/server.go",
    "chars": 2646,
    "preview": "// Package rpctest provides utilities for testing RPC methods.\npackage rpctest\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\t\"net/h"
  },
  {
    "path": "rpctest/test_case.go",
    "chars": 1755,
    "preview": "package rpctest\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/goog"
  },
  {
    "path": "testdata/w3vm/1_12243997.json",
    "chars": 150928,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000002\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0x261bf27028cd820\"\n\t},\n\t\"0x0000000000"
  },
  {
    "path": "testdata/w3vm/1_12243998.json",
    "chars": 132165,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xb9d9fabaebe71e25\"\n\t},\n\t\"0x00000000c"
  },
  {
    "path": "testdata/w3vm/1_12243999.json",
    "chars": 136964,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xb9d9fabaebe71e25\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_12244000.json",
    "chars": 101428,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xb9d9fabaebe71e25\"\n\t},\n\t\"0x0000a1c00"
  },
  {
    "path": "testdata/w3vm/1_12964997.json",
    "chars": 168027,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xb9e06356c739eb57\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_12964998.json",
    "chars": 176031,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xb9e06356c739eb57\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_12964999.json",
    "chars": 297490,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xb9e06356c739eb57\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_12965000.json",
    "chars": 225519,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xb9e06356c739eb57\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_13772997.json",
    "chars": 113018,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xbd251d6b80b88add\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_13772998.json",
    "chars": 257051,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xbd251d6b80b88add\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_13772999.json",
    "chars": 168610,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xbd251d6b80b88add\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_13773000.json",
    "chars": 277251,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xbd251d6b80b88add\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_15049997.json",
    "chars": 288233,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xdd105b3be81e8add\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_15049998.json",
    "chars": 121694,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xdd105b3be81e8add\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_15049999.json",
    "chars": 31986,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xdd105b3be81e8add\"\n\t},\n\t\"0x000000000"
  },
  {
    "path": "testdata/w3vm/1_15050000.json",
    "chars": 85447,
    "preview": "{\n\t\"0x0000000000000000000000000000000000000001\": {\n\t\t\"nonce\": \"0x0\",\n\t\t\"balance\": \"0xdd105b3be81e8add\"\n\t},\n\t\"0x000000000"
  }
]

// ... and 63 more files (download for full content)

About this extraction

This page contains the full source code of the lmittmann/w3 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 263 files (76.8 MB), approximately 1.8M tokens, and a symbol index with 583 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!