Skip to content

feat: evm extension - #982

Merged
gummy789j merged 24 commits into
feat/v4.13.0from
feat/architecture-evm-extension
Aug 27, 2026
Merged

feat: evm extension#982
gummy789j merged 24 commits into
feat/v4.13.0from
feat/architecture-evm-extension

Conversation

@gummy789j

Copy link
Copy Markdown
Collaborator

No description provided.

@mollyvong

mollyvong commented Aug 24, 2026 via email

Copy link
Copy Markdown

gummy789j and others added 23 commits August 24, 2026 16:08
…asUsed union

- eslint.config.js: the scripts/**/*.mjs block never applied — scripts/** is in
  the global ignores, so `eslint .` is byte-identical with and without it.
- evm.ts: #send was a one-line pass-through to #request with a single caller;
  its doc comment moves to #request, which is what it describes.
- TxInfoView.gasUsed: production only ever writes String(...), so the `number`
  half was kept alive solely by a stale test fixture. Fixture aligned to the
  shape production emits; the rendered output is unchanged (formatInt already
  handles decimal strings).

Claude-Session: https://claude.ai/code/session_01Reu4W1oqGVqUWkMpAjR9Xo
…network API keys

Consolidates the TRON and EVM client adapters onto a single HttpTransport
(adapters/outbound/http) and builds the per-network credential pair on top of it.

Transport
- TronRpcClient and EvmRpcClient accept a NetworkDescriptor or an endpoint config;
  raw fetch calls, URL joining and timeout wiring now live in one place.
- tronweb is handed explicit HttpProviders so it carries the same headers.
- TronGridHistoryReader goes through the transport; its failures no longer echo
  the underlying message.

Per-network API key
- networks.<id>.apiKeyHeader / .apiKey are readable and writable via `config`.
  Both must be set before a header is sent, and the header name is validated as an
  RFC 9110 token so a hand-edited config.yaml cannot smuggle in a second header.
- apiKey is write-only on every read surface and forces the 0600 check on
  config.yaml, which now looks inside `networks` rather than only at top level.
- Credentialed requests refuse to follow redirects on both the fetch and the
  tronweb path, so a redirecting endpoint cannot collect the key.

Config surface
- A network renders as its configurable fields rather than a bare endpoint, so a
  new field shows up in every view at once. Listings still trim the endpoint to
  its host; naming one network reveals it in full.
- `config` prints the document as a tree. Nested keys carry no trailing colon --
  the ids at that level contain colons themselves.

Fixes found while re-testing the above on Nile and Sepolia
- EVM transport timeouts report `timeout`, not `rpc_error`, matching TRON and the
  documented meaning of the code.
- --args/--verb/--group/--source are rejected as user-typed flags. They are yargs
  plumbing keys that must stay in the per-command allowlist, so they worked as
  undocumented aliases: `contract call --args <addr>` bound into a slot the
  command has not got and answered 0, a wrong result that reads like a real one.
  The check runs on the raw tokens, before yargs folds the two sources together,
  and a meta-test pins that no command declares a field by those names.

Startup migration
- The gate runs ahead of every surface and stops after upgrading rather than
  running the command that triggered it.

Verified on Nile and Sepolia: reads across every transport path, TRX/TRC20 and
ETH transfers confirmed on-chain, the credential observed on the wire on all
three paths, and the redirect target receiving nothing once one is configured.

Claude-Session: https://claude.ai/code/session_01JSxAgrttq54UacDxykm7gy
The source-of-truth doc it named was deleted in 7a33dcd, leaving the one
instruction that tells a reader where the boundary rules live pointing at
nothing. Split the reference across what actually holds each part now: the
table below it for the boundaries, .dependency-cruiser.cjs for enforcement,
machine-interface.md for the JSON contract, and docs/adr/ for the reasoning.

Claude-Session: https://claude.ai/code/session_01JSxAgrttq54UacDxykm7gy
5389b00 pointed at ts/docs/adr/ after verifying it existed on disk, which is
the wrong test: ts/.gitignore:9 ignores it, so it holds zero tracked files and
is not there for anyone who clones. That replaced one dead reference with
another. What remains is what the repo actually carries: the table, the
dependency-cruiser config that enforces it, and machine-interface.md.

Claude-Session: https://claude.ai/code/session_01JSxAgrttq54UacDxykm7gy
@gummy789j
gummy789j merged commit fbf5362 into feat/v4.13.0 Aug 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants