Skip to content

Feat/security boundary audit - #1022

Merged
gummy789j merged 5 commits into
release_v4.14.0from
feat/security-boundary-audit
Sep 18, 2026
Merged

gummy789j merged 5 commits into
release_v4.14.0from
feat/security-boundary-audit

Conversation

@gummy789j

Copy link
Copy Markdown
Collaborator

No description provided.

…n execution result

A TRON transaction that is mined is not one that succeeded. The confirmation
normalizer only looked at the nested receipt.result, so a top-level
`result: "FAILED"` was ignored, a numeric receipt result was coerced away by
the schema, and a receipt with no result at all defaulted to failed=false —
reverted ERC-8004 writes were reported as `stage: confirmed`.

- honor the top-level `result: "FAILED"` as a failure
- keep a numeric receipt.result as a string instead of dropping it
- `tronConfirmation(..., { requireReceiptResult: true })` keeps polling when a
  contract call's receipt carries no execution result; contract-service uses
  it for call / deploy / TRC20, native transactions are unchanged
Findings from the release_v4.14.0 review, each with a regression test against
the installed SDK where the SDK is involved:

- TRON approve intent (CR-019): the one-time Permit2 approve is built by the
  RPC, and the integrity check only proved the JSON and bytes agreed. The
  bridge now signs nothing but `approve(Permit2, MaxUint256)` on a known token
  from the payer, with call_value 0 and the SDK's fee limit, before any device
  prompt; a substituted owner-only transaction is refused.
- GasFree fee cap (CR-011): `--max-gasfree-fee` is converted at signing time
  with the precision of the token the PermitTransfer names, not the candidate
  the CLI matched first; an unknown token refuses rather than guesses.
- Authorization deadline (CR-020): Permit2 `deadline`, EIP-3009 `validBefore`
  and GasFree `deadline` are checked before signing and again after the signer
  returns, so an authorization that expired while waiting for an approve or a
  device is never handed on.
- Approval evidence (CR-017): the signed approve's txId, token, spender and
  status (submitted / confirmed / exported) travel in `error.details.approval`
  and `data.approval`; a TRON approve no longer counts as a signed payment, so
  a later refusal reports `paymentStatus: not_sent` with the approval beside it.
- Output reservation (CR-015): `--out` is created exclusively before the first
  request, so an existing file fails with `output_exists` and nothing paid.
- Secret stdin (CR-001): `--body-file -` refuses to share stdin with any
  `--*-stdin` secret, not only `--password-stdin`.
- Spend control (CR-014): the SDK's built-in $1 refusal is reported as
  `amount_exceeds_limit` / `no_matching_requirement` with `not_sent`.
- Selected relay errors (CR-018): 429 → `provider_rate_limited` with a numeric
  Retry-After, transport errors keep `timeout` / `response_too_large`, a
  malformed answer is `invalid_x402_response`; still no relay fallback.
- Catalog warnings (CR-010) are sanitized before reaching the terminal.
The files whitelist listed docs/troubleshooting.md but not the
docs/troubleshooting/ directory it links to, so the legacy-derivation recovery
guide five packaged documents point at was missing from the tarball. It also
still listed docs/development/erc8004-sdk-integration.md, which no longer
exists.

verify:package now checks that every in-package relative Markdown link in a
packaged document resolves to a packaged file, so this cannot regress silently.
…clare

amount_exceeds_limit and no_matching_requirement are execution failures
(exit 1) in the error-code index; the SDK spend-control classification threw
them as UsageError (exit 2). Caught by bootstrap/error-codes.test.ts.
…gh tsx per spawn

Every golden case spawned `node --import tsx src/index.ts`, transpiling the
whole CLI import graph each time (~1.3s per spawn against ~0.4s for dist).
The golden project now builds once in a globalSetup and sets
WALLET_CLI_TEST_ENTRY to dist/index.js; the three test files that hardcoded
the tsx form honor the entry like the others already did.

An externally provided WALLET_CLI_TEST_ENTRY still wins, so verify:package
keeps testing the independently installed package rather than dist. The
"installed beta" files that skip without an entry now run in `npm test` too.
@gummy789j
gummy789j merged commit 878e892 into release_v4.14.0 Sep 18, 2026
2 checks passed
@gummy789j gummy789j mentioned this pull request Sep 18, 2026
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