web3-tools-mcp 2.0.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -0
- package/README.md +5 -0
- package/dist/anvil.d.ts +17 -19
- package/dist/anvil.d.ts.map +1 -1
- package/dist/anvil.js +124 -228
- package/dist/anvil.js.map +1 -1
- package/dist/chains.d.ts +9 -1
- package/dist/chains.d.ts.map +1 -1
- package/dist/chains.js +11 -2
- package/dist/chains.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +22 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +24 -0
- package/dist/context.js.map +1 -0
- package/dist/hosted.d.ts +12 -0
- package/dist/hosted.d.ts.map +1 -0
- package/dist/hosted.js +12 -0
- package/dist/hosted.js.map +1 -0
- package/dist/http-server.d.ts +13 -0
- package/dist/http-server.d.ts.map +1 -1
- package/dist/http-server.js +13 -4
- package/dist/http-server.js.map +1 -1
- package/dist/index.js +15 -11
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +24 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +23 -0
- package/dist/lib.js.map +1 -0
- package/dist/mcp-server.d.ts +4 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +43 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/oauth.d.ts +41 -6
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +75 -41
- package/dist/oauth.js.map +1 -1
- package/dist/preview.d.ts +7 -0
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +14 -2
- package/dist/preview.js.map +1 -1
- package/dist/signing-requests.d.ts +81 -0
- package/dist/signing-requests.d.ts.map +1 -0
- package/dist/signing-requests.js +138 -0
- package/dist/signing-requests.js.map +1 -0
- package/dist/tools/index.d.ts +27 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +37 -15
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/{advanced.d.ts → read/advanced.d.ts} +30 -26
- package/dist/tools/read/advanced.d.ts.map +1 -0
- package/dist/tools/{advanced.js → read/advanced.js} +10 -10
- package/dist/tools/read/advanced.js.map +1 -0
- package/dist/tools/{balance.d.ts → read/balance.d.ts} +8 -7
- package/dist/tools/read/balance.d.ts.map +1 -0
- package/dist/tools/{balance.js → read/balance.js} +2 -2
- package/dist/tools/read/balance.js.map +1 -0
- package/dist/tools/{contract-info.d.ts → read/contract-info.d.ts} +18 -15
- package/dist/tools/read/contract-info.d.ts.map +1 -0
- package/dist/tools/{contract-info.js → read/contract-info.js} +2 -2
- package/dist/tools/read/contract-info.js.map +1 -0
- package/dist/tools/{contract.d.ts → read/contract.d.ts} +14 -12
- package/dist/tools/read/contract.d.ts.map +1 -0
- package/dist/tools/{contract.js → read/contract.js} +2 -2
- package/dist/tools/read/contract.js.map +1 -0
- package/dist/tools/{ens.d.ts → read/ens.d.ts} +30 -25
- package/dist/tools/read/ens.d.ts.map +1 -0
- package/dist/tools/{ens.js → read/ens.js} +2 -2
- package/dist/tools/read/ens.js.map +1 -0
- package/dist/tools/read/gas.d.ts +171 -0
- package/dist/tools/read/gas.d.ts.map +1 -0
- package/dist/tools/read/gas.js +368 -0
- package/dist/tools/read/gas.js.map +1 -0
- package/dist/tools/{logs.d.ts → read/logs.d.ts} +6 -5
- package/dist/tools/read/logs.d.ts.map +1 -0
- package/dist/tools/{logs.js → read/logs.js} +2 -2
- package/dist/tools/read/logs.js.map +1 -0
- package/dist/tools/{signatures.d.ts → read/signatures.d.ts} +8 -4
- package/dist/tools/read/signatures.d.ts.map +1 -0
- package/dist/tools/{signatures.js → read/signatures.js} +1 -1
- package/dist/tools/read/signatures.js.map +1 -0
- package/dist/tools/read/signing.d.ts +27 -0
- package/dist/tools/read/signing.d.ts.map +1 -0
- package/dist/tools/read/signing.js +75 -0
- package/dist/tools/read/signing.js.map +1 -0
- package/dist/tools/sign/errors.d.ts +9 -0
- package/dist/tools/sign/errors.d.ts.map +1 -0
- package/dist/tools/sign/errors.js +29 -0
- package/dist/tools/sign/errors.js.map +1 -0
- package/dist/tools/{transactions.d.ts → sign/transactions.d.ts} +48 -62
- package/dist/tools/sign/transactions.d.ts.map +1 -0
- package/dist/tools/sign/transactions.js +316 -0
- package/dist/tools/sign/transactions.js.map +1 -0
- package/dist/tools/sign/wallet.d.ts +50 -0
- package/dist/tools/sign/wallet.d.ts.map +1 -0
- package/dist/tools/sign/wallet.js +180 -0
- package/dist/tools/sign/wallet.js.map +1 -0
- package/dist/utils.d.ts +5 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +5 -2
- package/dist/utils.js.map +1 -1
- package/dist/wallet-client.d.ts +33 -4
- package/dist/wallet-client.d.ts.map +1 -1
- package/dist/wallet-client.js +90 -24
- package/dist/wallet-client.js.map +1 -1
- package/dist/walletconnect.d.ts +100 -13
- package/dist/walletconnect.d.ts.map +1 -1
- package/dist/walletconnect.js +215 -50
- package/dist/walletconnect.js.map +1 -1
- package/package.json +10 -4
- package/src/anvil.ts +150 -271
- package/src/chains.ts +14 -2
- package/src/client.ts +0 -1
- package/src/context.ts +27 -0
- package/src/hosted.ts +11 -0
- package/src/http-server.ts +30 -5
- package/src/index.ts +15 -12
- package/src/lib.ts +24 -0
- package/src/mcp-server.ts +47 -0
- package/src/oauth.ts +98 -45
- package/src/preview.ts +21 -2
- package/src/signing-requests.ts +198 -0
- package/src/tools/index.ts +67 -16
- package/src/tools/{advanced.ts → read/advanced.ts} +13 -11
- package/src/tools/{balance.ts → read/balance.ts} +3 -3
- package/src/tools/{contract-info.ts → read/contract-info.ts} +3 -3
- package/src/tools/{contract.ts → read/contract.ts} +3 -3
- package/src/tools/{ens.ts → read/ens.ts} +3 -3
- package/src/tools/read/gas.ts +480 -0
- package/src/tools/{logs.ts → read/logs.ts} +3 -3
- package/src/tools/{signatures.ts → read/signatures.ts} +2 -2
- package/src/tools/read/signing.ts +86 -0
- package/src/tools/sign/errors.ts +28 -0
- package/src/tools/sign/transactions.ts +428 -0
- package/src/tools/sign/wallet.ts +216 -0
- package/src/utils.ts +5 -2
- package/src/wallet-client.ts +91 -22
- package/src/walletconnect.ts +250 -48
- package/dist/tools/advanced.d.ts.map +0 -1
- package/dist/tools/advanced.js.map +0 -1
- package/dist/tools/balance.d.ts.map +0 -1
- package/dist/tools/balance.js.map +0 -1
- package/dist/tools/contract-info.d.ts.map +0 -1
- package/dist/tools/contract-info.js.map +0 -1
- package/dist/tools/contract.d.ts.map +0 -1
- package/dist/tools/contract.js.map +0 -1
- package/dist/tools/ens.d.ts.map +0 -1
- package/dist/tools/ens.js.map +0 -1
- package/dist/tools/gas.d.ts +0 -99
- package/dist/tools/gas.d.ts.map +0 -1
- package/dist/tools/gas.js +0 -181
- package/dist/tools/gas.js.map +0 -1
- package/dist/tools/logs.d.ts.map +0 -1
- package/dist/tools/logs.js.map +0 -1
- package/dist/tools/signatures.d.ts.map +0 -1
- package/dist/tools/signatures.js.map +0 -1
- package/dist/tools/transactions.d.ts.map +0 -1
- package/dist/tools/transactions.js +0 -365
- package/dist/tools/transactions.js.map +0 -1
- package/src/tools/gas.ts +0 -219
- package/src/tools/transactions.ts +0 -456
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,103 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes per release. Dates are release dates; unreleased work sits at the top.
|
|
4
4
|
|
|
5
|
+
## [3.0.0] — 2026-09-23
|
|
6
|
+
|
|
7
|
+
The theme is multi-tenancy: one server can now carry several people without their wallets
|
|
8
|
+
meeting. Nothing turns that on by itself — a server still authenticates its deployment
|
|
9
|
+
rather than a person, so everyone on it remains the same user until something issues
|
|
10
|
+
distinct identities.
|
|
11
|
+
|
|
12
|
+
`web3-wallet-relay` goes to 2.0.0 alongside, and `web3-tools-mcp` pins it exactly: the
|
|
13
|
+
handshake changed, so a mismatched pair cannot pair at all.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **Tracing uses a node that is already running, instead of starting one.** Each trace used
|
|
18
|
+
to spawn an Anvil fork and kill it afterwards, which on a shared server is unbounded child
|
|
19
|
+
processes. It now talks to `ANVIL_RPC_URL`, defaulting to `127.0.0.1:8545` — any node
|
|
20
|
+
exposing `debug_traceCall` will do, and a provider whose RPC can trace is still preferred.
|
|
21
|
+
|
|
22
|
+
Anvil serves no block below its own fork height, so replaying an older transaction means
|
|
23
|
+
re-forking the node there, which clears whatever state it held. That only happens with
|
|
24
|
+
`ANVIL_ALLOW_RESET=1`; without it the trace fails and says so. The node is returned to
|
|
25
|
+
head afterwards rather than left pinned to an old block.
|
|
26
|
+
|
|
27
|
+
Re-forking reads state from the chain's configured RPC, so tracing an old transaction
|
|
28
|
+
needs one with archive access — a provider key or a `CUSTOM_RPC`. The hard-coded archive
|
|
29
|
+
endpoint for Arbitrum is gone.
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **Several phone wallets can be paired at once** — a hot wallet and a hardware one, say.
|
|
34
|
+
`pair_phone_wallet` used to report that one was already paired and stop; it now pairs, and
|
|
35
|
+
says which wallets the new one joins. `wallet_status` lists them all, and the signing
|
|
36
|
+
tools take `account` to choose between them, as does `disconnect_phone_wallet` — which
|
|
37
|
+
still clears everything when no account is named. With one wallet paired nothing changes,
|
|
38
|
+
and omitting `account` uses the most recently paired.
|
|
39
|
+
|
|
40
|
+
### Security
|
|
41
|
+
|
|
42
|
+
- **Signing is scoped to whoever asked for it.** Every tool call now carries the identity it
|
|
43
|
+
is acting for, and both signers are keyed by it: a wallet page reaches only the person it
|
|
44
|
+
belongs to, and a phone session is matched by a binding recorded when it was approved.
|
|
45
|
+
Sessions were previously picked as "the most recently paired", so on a server with more
|
|
46
|
+
than one user a signing request could be sent to somebody else's phone — and
|
|
47
|
+
`disconnect_phone_wallet` ended everybody's sessions. Phones paired before this keep
|
|
48
|
+
working on a single-user server.
|
|
49
|
+
|
|
50
|
+
- **Relay tokens name the room they admit you to**, signed by the relay's secret, so the
|
|
51
|
+
server can mint a pair per person and the relay needs no record of who exists. Naming a
|
|
52
|
+
room without the signature is refused.
|
|
53
|
+
|
|
54
|
+
- **The relay bounds what one room can take.** A frame over 512KB is refused, rather than
|
|
55
|
+
the 100MB the WebSocket library would otherwise accept, and a room holds at most 16
|
|
56
|
+
connections. Neither is reachable in normal use — contract creation calldata tops out
|
|
57
|
+
near 98KB of hex, and a person needs a wallet tab or two plus a requester per editor
|
|
58
|
+
session — but without them one connection could exhaust the process for everybody else.
|
|
59
|
+
|
|
60
|
+
- **`localhost` is not a chain a hosted server will accept.** It resolves to the machine
|
|
61
|
+
running the server, so on a shared deployment it was a way to aim requests at whatever
|
|
62
|
+
that host had listening on its own loopback. Self-hosted runs are unaffected.
|
|
63
|
+
|
|
64
|
+
The same switch keeps a hosted server from probing its own loopback for a tracing node
|
|
65
|
+
and from opening a browser on itself. The CLI flips it with `MCP_HTTP_PORT`; a host that
|
|
66
|
+
assembles its own server from the library sets `MCP_HOSTED=1` before importing it, and
|
|
67
|
+
`startHttpServer` refuses to run without one of the two.
|
|
68
|
+
|
|
69
|
+
- **The relay drops a frame it cannot use instead of dying on it.** A peer that had
|
|
70
|
+
authenticated could send `null` — valid JSON, not an object — and take the relay down,
|
|
71
|
+
along with the MCP server it is embedded in when hosted. Tokens are also compared in
|
|
72
|
+
constant time.
|
|
73
|
+
|
|
74
|
+
- **A request signs from the account it named.** With a session exposing several
|
|
75
|
+
addresses, `account` chose the session but the transaction was still sent from its first
|
|
76
|
+
address. Concurrent pairings on one server no longer overwrite each other's ownership
|
|
77
|
+
record, and a hosted server closes a person's idle relay socket after ten minutes
|
|
78
|
+
instead of holding one open per person forever.
|
|
79
|
+
|
|
80
|
+
- **The signing page and the MCP server now hold different tokens.** One token granted both
|
|
81
|
+
roles, and a relay client may either answer transaction proposals (the page) or make them
|
|
82
|
+
(the server). The page's token is the exposed one — it rides in a URL you open, keep in
|
|
83
|
+
history and show on screen — so anyone who saw it could push proposals at your wallet.
|
|
84
|
+
The page's token is derived from the server's and grants the signing role only; the
|
|
85
|
+
server's never reaches a browser.
|
|
86
|
+
|
|
87
|
+
**Re-open the signing page from the link the server prints.** Pairing URLs issued before
|
|
88
|
+
this carry a token the relay no longer accepts for signing.
|
|
89
|
+
|
|
90
|
+
- **The signing page no longer takes the transaction's value from the preview.** The preview
|
|
91
|
+
travels with the request and is forwarded untouched, so a hostile requester could state
|
|
92
|
+
one amount while the calldata did another. The value is now read from the transaction
|
|
93
|
+
itself, and the calldata is shown even when a decoded view is available, so a claim that
|
|
94
|
+
disagrees with the bytes is visible on the same screen.
|
|
95
|
+
|
|
96
|
+
- **A relay can serve several people without their wallets meeting.** Connections resolve to
|
|
97
|
+
a room, and a transaction only ever reaches a page in the same one. Previously the relay
|
|
98
|
+
offered each transaction to whichever page was first in its pool, broadcast the first
|
|
99
|
+
signer's address to every requester, and let any page answer a request by its id. A
|
|
100
|
+
self-hosted relay keeps one room and behaves exactly as before.
|
|
101
|
+
|
|
5
102
|
## [2.0.2] — 2026-09-22
|
|
6
103
|
|
|
7
104
|
### Fixed
|
package/README.md
CHANGED
|
@@ -396,6 +396,11 @@ Then point the server at it with `WALLET_SERVER_URL` and the same `WALLET_TOKEN`
|
|
|
396
396
|
`render.yaml` deploys it as-is. Anyone holding `WALLET_TOKEN` can send your browser a
|
|
397
397
|
transaction to sign — treat it like a password, and always serve over HTTPS.
|
|
398
398
|
|
|
399
|
+
The pairing link the server prints carries a different token, derived from that one, which
|
|
400
|
+
can only answer signing requests and not make them. Sharing a pairing link is therefore not
|
|
401
|
+
the same as sharing `WALLET_TOKEN` — but it still lets whoever has it act as your wallet
|
|
402
|
+
page, so a signing request can reach them instead of you.
|
|
403
|
+
|
|
399
404
|
Locally nothing changes: the server embeds the same relay.
|
|
400
405
|
|
|
401
406
|
</details>
|
package/dist/anvil.d.ts
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
forkUrl: string;
|
|
11
|
-
forkBlockNumber?: bigint;
|
|
12
|
-
port?: number;
|
|
13
|
-
chainId?: number;
|
|
14
|
-
}
|
|
15
|
-
export declare function isAnvilInstalled(): Promise<boolean>;
|
|
16
|
-
export declare function startAnvil(config: AnvilConfig): Promise<AnvilInstance>;
|
|
17
|
-
export declare function stopAnvil(instance: AnvilInstance): void;
|
|
18
|
-
export declare function withAnvil<T>(config: AnvilConfig, fn: (instance: AnvilInstance) => Promise<T>): Promise<T>;
|
|
19
|
-
export declare function traceTransactionWithAnvil(forkUrl: string, transactionHash: string, blockNumber: bigint, tracer?: 'callTracer' | 'prestateTracer' | 'stateDiffTracer', chainName?: string): Promise<unknown>;
|
|
1
|
+
/**
|
|
2
|
+
* The node to ask for traces, or undefined when there is none.
|
|
3
|
+
*
|
|
4
|
+
* Hosted, only an explicit setting counts: defaulting to loopback would turn every trace
|
|
5
|
+
* into a request against the server's own private network.
|
|
6
|
+
*/
|
|
7
|
+
export declare function debugRpcUrl(): string | undefined;
|
|
8
|
+
/** Whether a tracing node is reachable and actually offers the debug namespace. */
|
|
9
|
+
export declare function isDebugNodeAvailable(): Promise<boolean>;
|
|
20
10
|
export interface SimulateCallParams {
|
|
21
11
|
to: string;
|
|
22
12
|
data?: string;
|
|
@@ -24,6 +14,14 @@ export interface SimulateCallParams {
|
|
|
24
14
|
value?: bigint;
|
|
25
15
|
gas?: bigint;
|
|
26
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Replay a transaction through the tracing node.
|
|
19
|
+
*
|
|
20
|
+
* Run against the block before it, so the state is what the transaction actually saw. The
|
|
21
|
+
* node needs archive access to that block; without it this fails rather than quietly
|
|
22
|
+
* tracing against the wrong state.
|
|
23
|
+
*/
|
|
24
|
+
export declare function traceTransactionWithAnvil(forkUrl: string, transactionHash: string, blockNumber: bigint, tracer?: 'callTracer' | 'prestateTracer' | 'stateDiffTracer'): Promise<unknown>;
|
|
27
25
|
export declare function simulateCallWithTrace(forkUrl: string, params: SimulateCallParams, blockNumber?: bigint, tracer?: 'callTracer' | 'prestateTracer'): Promise<{
|
|
28
26
|
result: string;
|
|
29
27
|
trace: unknown;
|
package/dist/anvil.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anvil.d.ts","sourceRoot":"","sources":["../src/anvil.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"anvil.d.ts","sourceRoot":"","sources":["../src/anvil.ts"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,SAAS,CAGhD;AAMD,mFAAmF;AACnF,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAe7D;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AA0ED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,YAAY,GAAG,gBAAgB,GAAG,iBAAgC,GACzE,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,EAC1B,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,GAAE,YAAY,GAAG,gBAA+B,GACrD,OAAO,CAAC;IACT,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,CAiCD"}
|
package/dist/anvil.js
CHANGED
|
@@ -1,256 +1,152 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
1
|
import { createPublicClient, http } from 'viem';
|
|
3
2
|
import { mainnet } from 'viem/chains';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
import { HOSTED } from './hosted.js';
|
|
4
|
+
/**
|
|
5
|
+
* Tracing through a node that already supports `debug_*`, usually a local Anvil. Nothing
|
|
6
|
+
* is started here.
|
|
7
|
+
*
|
|
8
|
+
* Anvil serves no block below its own fork height — `debug_traceCall` at an earlier one
|
|
9
|
+
* fails with BlockOutOfRangeError — so replaying an old transaction means re-forking the
|
|
10
|
+
* node there with `anvil_reset`. That discards whatever state it held, which is why it
|
|
11
|
+
* happens only when ANVIL_ALLOW_RESET says so. A provider whose endpoint exposes
|
|
12
|
+
* `debug_traceTransaction` needs none of this and is tried first.
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_DEBUG_RPC = 'http://127.0.0.1:8545';
|
|
15
|
+
/** Re-forking clears the node, so it is never done to someone's dev chain uninvited. */
|
|
16
|
+
const ALLOW_RESET = ['1', 'true', 'yes'].includes((process.env.ANVIL_ALLOW_RESET ?? '').toLowerCase());
|
|
17
|
+
/**
|
|
18
|
+
* The node to ask for traces, or undefined when there is none.
|
|
19
|
+
*
|
|
20
|
+
* Hosted, only an explicit setting counts: defaulting to loopback would turn every trace
|
|
21
|
+
* into a request against the server's own private network.
|
|
22
|
+
*/
|
|
23
|
+
export function debugRpcUrl() {
|
|
24
|
+
if (process.env.ANVIL_RPC_URL)
|
|
25
|
+
return process.env.ANVIL_RPC_URL;
|
|
26
|
+
return HOSTED ? undefined : DEFAULT_DEBUG_RPC;
|
|
11
27
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const net = await import('node:net');
|
|
15
|
-
return new Promise((resolve, reject) => {
|
|
16
|
-
const server = net.createServer();
|
|
17
|
-
server.listen(startPort, () => {
|
|
18
|
-
const address = server.address();
|
|
19
|
-
if (address && typeof address === 'object') {
|
|
20
|
-
server.close(() => resolve(address.port));
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
server.close(() => reject(new Error('Could not get port')));
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
server.on('error', () => {
|
|
27
|
-
// Port in use, try next one
|
|
28
|
-
findAvailablePort(startPort + 1)
|
|
29
|
-
.then(resolve)
|
|
30
|
-
.catch(reject);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
28
|
+
function debugClient(url) {
|
|
29
|
+
return createPublicClient({ chain: mainnet, transport: http(url) });
|
|
33
30
|
}
|
|
34
|
-
|
|
35
|
-
export async function
|
|
36
|
-
const
|
|
37
|
-
if (!
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
/** Whether a tracing node is reachable and actually offers the debug namespace. */
|
|
32
|
+
export async function isDebugNodeAvailable() {
|
|
33
|
+
const url = debugRpcUrl();
|
|
34
|
+
if (!url)
|
|
35
|
+
return false;
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetch(url, {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: { 'Content-Type': 'application/json' },
|
|
40
|
+
body: JSON.stringify({ jsonrpc: '2.0', method: 'web3_clientVersion', params: [], id: 1 }),
|
|
41
|
+
signal: AbortSignal.timeout(2000)
|
|
42
|
+
});
|
|
43
|
+
return response.ok;
|
|
45
44
|
}
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
48
47
|
}
|
|
49
|
-
return new Promise((resolve, reject) => {
|
|
50
|
-
const proc = spawn('anvil', args, {
|
|
51
|
-
shell: true,
|
|
52
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
53
|
-
});
|
|
54
|
-
let stderr = '';
|
|
55
|
-
proc.stderr?.on('data', (data) => {
|
|
56
|
-
stderr += data.toString();
|
|
57
|
-
});
|
|
58
|
-
proc.on('error', (err) => {
|
|
59
|
-
reject(new Error(`Failed to start Anvil: ${err.message}`));
|
|
60
|
-
});
|
|
61
|
-
proc.on('close', (code) => {
|
|
62
|
-
if (code !== 0 && code !== null) {
|
|
63
|
-
reject(new Error(`Anvil exited with code ${code}: ${stderr}`));
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
// Wait for Anvil to be ready by polling the RPC
|
|
67
|
-
const maxAttempts = 50; // 5 seconds
|
|
68
|
-
let attempts = 0;
|
|
69
|
-
const checkReady = async () => {
|
|
70
|
-
attempts++;
|
|
71
|
-
try {
|
|
72
|
-
const response = await fetch(rpcUrl, {
|
|
73
|
-
method: 'POST',
|
|
74
|
-
headers: { 'Content-Type': 'application/json' },
|
|
75
|
-
body: JSON.stringify({
|
|
76
|
-
jsonrpc: '2.0',
|
|
77
|
-
method: 'eth_blockNumber',
|
|
78
|
-
params: [],
|
|
79
|
-
id: 1
|
|
80
|
-
})
|
|
81
|
-
});
|
|
82
|
-
if (response.ok) {
|
|
83
|
-
// Add small delay to ensure all RPC methods are ready (including debug_*)
|
|
84
|
-
await new Promise((r) => setTimeout(r, 100));
|
|
85
|
-
const client = createPublicClient({
|
|
86
|
-
chain: mainnet, // Chain is overridden by fork anyway
|
|
87
|
-
transport: http(rpcUrl)
|
|
88
|
-
});
|
|
89
|
-
resolve({ process: proc, port, rpcUrl, client });
|
|
90
|
-
}
|
|
91
|
-
else if (attempts < maxAttempts) {
|
|
92
|
-
setTimeout(checkReady, 100);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
proc.kill();
|
|
96
|
-
reject(new Error('Anvil failed to start within timeout'));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
catch {
|
|
100
|
-
if (attempts < maxAttempts) {
|
|
101
|
-
setTimeout(checkReady, 100);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
proc.kill();
|
|
105
|
-
reject(new Error('Anvil failed to start within timeout'));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
// Start checking after a small delay
|
|
110
|
-
setTimeout(checkReady, 200);
|
|
111
|
-
});
|
|
112
48
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
49
|
+
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
50
|
+
function callObject(params) {
|
|
51
|
+
return {
|
|
52
|
+
to: params.to,
|
|
53
|
+
data: params.data,
|
|
54
|
+
from: params.from ?? ZERO_ADDRESS,
|
|
55
|
+
value: params.value ? `0x${params.value.toString(16)}` : undefined,
|
|
56
|
+
gas: params.gas ? `0x${params.gas.toString(16)}` : undefined
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function blockTag(blockNumber) {
|
|
60
|
+
return blockNumber === undefined ? 'latest' : `0x${blockNumber.toString(16)}`;
|
|
61
|
+
}
|
|
62
|
+
function requireDebugNode() {
|
|
63
|
+
const url = debugRpcUrl();
|
|
64
|
+
if (!url) {
|
|
65
|
+
throw new Error('No tracing node configured. Set ANVIL_RPC_URL to a node exposing debug_traceCall, such as a local Anvil.');
|
|
117
66
|
}
|
|
67
|
+
return url;
|
|
68
|
+
}
|
|
69
|
+
function isBlockOutOfRange(error) {
|
|
70
|
+
return /BlockOutOfRangeError|block height is/i.test(error?.message ?? '');
|
|
118
71
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Run something against a block, re-forking the node when it cannot reach that far back.
|
|
74
|
+
*
|
|
75
|
+
* Returns to head afterwards rather than leaving the node pinned to an old block, which
|
|
76
|
+
* would silently break whatever the owner does with it next. Its state is gone either way.
|
|
77
|
+
*/
|
|
78
|
+
async function atBlock(client, forkUrl, blockNumber, run) {
|
|
122
79
|
try {
|
|
123
|
-
return await
|
|
80
|
+
return await run(blockTag(blockNumber));
|
|
124
81
|
}
|
|
125
|
-
|
|
126
|
-
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (blockNumber === undefined || !isBlockOutOfRange(error))
|
|
84
|
+
throw error;
|
|
85
|
+
if (!ALLOW_RESET) {
|
|
86
|
+
throw new Error(`The tracing node is forked past block ${blockNumber}, and Anvil serves nothing earlier. Re-forking it there would clear its state, so set ANVIL_ALLOW_RESET=1 to allow that — or use an RPC whose endpoint supports debug_traceTransaction.`);
|
|
87
|
+
}
|
|
88
|
+
const refork = (block) => client.request({
|
|
89
|
+
method: 'anvil_reset',
|
|
90
|
+
params: [{ forking: { jsonRpcUrl: forkUrl, ...(block === undefined ? {} : { blockNumber: Number(block) }) } }]
|
|
91
|
+
});
|
|
92
|
+
await refork(blockNumber);
|
|
93
|
+
try {
|
|
94
|
+
return await run('latest');
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
await refork().catch(() => { });
|
|
98
|
+
}
|
|
127
99
|
}
|
|
128
100
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const tx = await fetchClient.getTransaction({
|
|
143
|
-
hash: transactionHash
|
|
144
|
-
});
|
|
145
|
-
if (!tx) {
|
|
101
|
+
function traceCall(client, call, block, tracer) {
|
|
102
|
+
return client.request({ method: 'debug_traceCall', params: [call, block, { tracer }] });
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Replay a transaction through the tracing node.
|
|
106
|
+
*
|
|
107
|
+
* Run against the block before it, so the state is what the transaction actually saw. The
|
|
108
|
+
* node needs archive access to that block; without it this fails rather than quietly
|
|
109
|
+
* tracing against the wrong state.
|
|
110
|
+
*/
|
|
111
|
+
export async function traceTransactionWithAnvil(forkUrl, transactionHash, blockNumber, tracer = 'callTracer') {
|
|
112
|
+
const tx = await debugClient(forkUrl).getTransaction({ hash: transactionHash });
|
|
113
|
+
if (!tx)
|
|
146
114
|
throw new Error(`Transaction ${transactionHash} not found`);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const forkBlock = blockNumber > 0n ? blockNumber - 1n : 0n;
|
|
151
|
-
return withAnvil({
|
|
152
|
-
forkUrl: archiveUrl,
|
|
153
|
-
forkBlockNumber: forkBlock
|
|
154
|
-
}, async (instance) => {
|
|
155
|
-
// Use debug_traceCall to simulate and trace the transaction
|
|
156
|
-
// Note: This replays the tx against the post-block state, which may differ slightly
|
|
157
|
-
// from the original execution if state changed within the block
|
|
158
|
-
const trace = await instance.client.request({
|
|
159
|
-
method: 'debug_traceCall',
|
|
160
|
-
params: [
|
|
161
|
-
{
|
|
162
|
-
from: tx.from,
|
|
163
|
-
to: tx.to,
|
|
164
|
-
data: tx.input,
|
|
165
|
-
value: tx.value ? `0x${tx.value.toString(16)}` : '0x0',
|
|
166
|
-
gas: tx.gas ? `0x${tx.gas.toString(16)}` : undefined
|
|
167
|
-
},
|
|
168
|
-
'latest',
|
|
169
|
-
{ tracer }
|
|
170
|
-
]
|
|
171
|
-
});
|
|
172
|
-
return trace;
|
|
173
|
-
});
|
|
115
|
+
const client = debugClient(requireDebugNode());
|
|
116
|
+
const call = callObject({ to: tx.to ?? ZERO_ADDRESS, data: tx.input, from: tx.from, value: tx.value, gas: tx.gas });
|
|
117
|
+
return atBlock(client, forkUrl, blockNumber > 0n ? blockNumber - 1n : 0n, (block) => traceCall(client, call, block, tracer));
|
|
174
118
|
}
|
|
175
119
|
export async function simulateCallWithTrace(forkUrl, params, blockNumber, tracer = 'callTracer') {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
120
|
+
const client = debugClient(requireDebugNode());
|
|
121
|
+
const call = callObject(params);
|
|
122
|
+
// Call, gas and trace all inside one atBlock, so they describe the same state: a block
|
|
123
|
+
// the node cannot serve re-forks it once, instead of being reported as a revert.
|
|
124
|
+
return atBlock(client, forkUrl, blockNumber, async (block) => {
|
|
181
125
|
let result = '0x';
|
|
182
126
|
let success = true;
|
|
183
127
|
let revertReason;
|
|
184
128
|
let gasUsed = 0n;
|
|
185
129
|
try {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
method: '
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
data: params.data,
|
|
193
|
-
from: params.from ?? '0x0000000000000000000000000000000000000000',
|
|
194
|
-
value: params.value ? `0x${params.value.toString(16)}` : undefined,
|
|
195
|
-
gas: params.gas ? `0x${params.gas.toString(16)}` : undefined
|
|
196
|
-
},
|
|
197
|
-
'latest'
|
|
198
|
-
]
|
|
199
|
-
}));
|
|
200
|
-
// Estimate gas
|
|
201
|
-
try {
|
|
202
|
-
gasUsed = await instance.client.estimateGas({
|
|
203
|
-
to: params.to,
|
|
204
|
-
data: params.data,
|
|
205
|
-
account: params.from,
|
|
206
|
-
value: params.value
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
catch {
|
|
210
|
-
// Ignore gas estimation errors
|
|
211
|
-
}
|
|
130
|
+
result = (await client.request({ method: 'eth_call', params: [call, block] }));
|
|
131
|
+
gasUsed = await client
|
|
132
|
+
.request({ method: 'eth_estimateGas', params: [call, block] })
|
|
133
|
+
.then((gas) => BigInt(gas))
|
|
134
|
+
// Gas estimation is a nicety; a failure here says nothing about the call itself.
|
|
135
|
+
.catch(() => 0n);
|
|
212
136
|
}
|
|
213
137
|
catch (error) {
|
|
138
|
+
if (isBlockOutOfRange(error))
|
|
139
|
+
throw error;
|
|
214
140
|
success = false;
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
const revertMatch = errorMessage.match(/revert(?:ed)?[:\s]*(.+?)(?:\n|$)/i);
|
|
218
|
-
if (revertMatch) {
|
|
219
|
-
revertReason = revertMatch[1].trim();
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
revertReason = errorMessage;
|
|
223
|
-
}
|
|
141
|
+
const message = error.message;
|
|
142
|
+
revertReason = message.match(/revert(?:ed)?[:\s]*(.+?)(?:\n|$)/i)?.[1]?.trim() ?? message;
|
|
224
143
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
{
|
|
232
|
-
to: params.to,
|
|
233
|
-
data: params.data,
|
|
234
|
-
from: params.from ?? '0x0000000000000000000000000000000000000000',
|
|
235
|
-
value: params.value ? `0x${params.value.toString(16)}` : undefined,
|
|
236
|
-
gas: params.gas ? `0x${params.gas.toString(16)}` : undefined
|
|
237
|
-
},
|
|
238
|
-
'latest',
|
|
239
|
-
{ tracer }
|
|
240
|
-
]
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
catch (traceError) {
|
|
244
|
-
// If tracing fails, include the error
|
|
245
|
-
trace = { error: traceError.message };
|
|
246
|
-
}
|
|
247
|
-
return {
|
|
248
|
-
result,
|
|
249
|
-
trace,
|
|
250
|
-
gasUsed,
|
|
251
|
-
success,
|
|
252
|
-
revertReason
|
|
253
|
-
};
|
|
144
|
+
const trace = await traceCall(client, call, block, tracer).catch((error) => {
|
|
145
|
+
if (isBlockOutOfRange(error))
|
|
146
|
+
throw error;
|
|
147
|
+
return { error: error.message };
|
|
148
|
+
});
|
|
149
|
+
return { result, trace, gasUsed, success, revertReason };
|
|
254
150
|
});
|
|
255
151
|
}
|
|
256
152
|
//# sourceMappingURL=anvil.js.map
|
package/dist/anvil.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anvil.js","sourceRoot":"","sources":["../src/anvil.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"anvil.js","sourceRoot":"","sources":["../src/anvil.ts"],"names":[],"mappings":"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"}
|
package/dist/chains.d.ts
CHANGED
|
@@ -954,7 +954,15 @@ declare const TABLE: {
|
|
|
954
954
|
};
|
|
955
955
|
export type ChainName = keyof typeof TABLE;
|
|
956
956
|
export declare const CHAINS: Record<ChainName, ChainInfo>;
|
|
957
|
-
/**
|
|
957
|
+
/**
|
|
958
|
+
* Chains the tools will accept.
|
|
959
|
+
*
|
|
960
|
+
* `localhost` is dropped when hosted. It resolves to the machine running the server, so on
|
|
961
|
+
* a shared host it is not the caller's dev node — it is a way to aim requests at whatever
|
|
962
|
+
* that host has listening on its own loopback.
|
|
963
|
+
*
|
|
964
|
+
* Tuple rather than array, because `z.enum` needs a non-empty literal list.
|
|
965
|
+
*/
|
|
958
966
|
export declare const SUPPORTED_CHAINS: [ChainName, ...ChainName[]];
|
|
959
967
|
export {};
|
|
960
968
|
//# sourceMappingURL=chains.d.ts.map
|
package/dist/chains.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAA;AAkBjC;;;;GAIG;AACH,UAAU,SAAS;IACjB,KAAK,EAAE,KAAK,CAAA;IACZ,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gFAmEuD,CAAC;;;;;sFAS/D,CAAF;;;;;6FASS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gFAlBC,CAAC;;;;;sFAOL,CAAC;;;;;6FAUN,CAAJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+EArDI,CAAC;;;;;qFAQmC,CAAC;;;;;4FAY1B,CAAC;;;;;yFAaJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gFAL6B,CAAC;;;;;sFAQW,CAAC;;;;;6FASxC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BApGd,CAAC;;;;;0BAO4B,CAAC;;;;;;;;2BAO9B,CAAC;oCAC+D,CAAC;0BAEnB,CAAC;+BAEQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyGZ,CAAA;AAE9C,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,KAAK,CAAA;AAI1C,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAS,CAAA;AAEzD;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,EAAkG,CAC7H,SAAS,EACT,GAAG,SAAS,EAAE,CACf,CAAA"}
|