Skip to content

Sync/upstream 2026 07#79

Open
roger-gan wants to merge 14 commits into
mainfrom
sync/upstream-2026-07
Open

Sync/upstream 2026 07#79
roger-gan wants to merge 14 commits into
mainfrom
sync/upstream-2026-07

Conversation

@roger-gan

Copy link
Copy Markdown
Contributor

Description

Tests

Checklist

  • I have formatted and linted my code
  • All new and existing tests pass
  • My commits are signed (required for merge) -- you may need to rebase if you initially pushed unsigned commits

roger-gan added 11 commits July 8, 2026 17:14
…xact_gasfree

Add servers/multi-scheme: an Express resource server that accepts EVM exact,
TRON exact, and TRON exact_gasfree payments on one endpoint. Wires the two
existing facilitators (basic :4022, gasfree :4032); the resource server routes
verify/settle by (network, scheme) via /supported from each. Adds dev script,
README, and .env-multi-scheme.example.
…ACILITATOR_URL

Use a comma-separated FACILITATOR_URL for all facilitators instead of two
separate env vars; the resource server still routes by (network, scheme) via
/supported from each.
Port 7 upstream commits from @x402/* to @bankofai/x402-*:

1. 04860337 — authorization_value_mismatch error (EVM + legacy)
2. a3ad102b — MCP cross-SDK interop: null field normalization + parsePaymentRequired
3. 59ac597d — dynamicInfoFields for extension echo validation
4. 4cba2622 — EVM wallet compatibility: strict signature verification (EOA/ERC-1271/ERC-6492/ERC-7702), counterfactual deposit support
5. f4c532e8 — validAfter time-window correction (EVM + Tron)
6. 8f22db34 — Retry-After regex fix
7. 266b19d2 — validateFacilitatorSupport hook + optional authorizerSigner (EVM + Tron)

Tests: core 516/517 (1 pre-existing network failure), EVM 747/747, Tron 152/152, MCP 99/99, extensions 471/471.
Format 17 files across core, mcp, evm, tron packages to pass
the format quality gate.
Format settle.ts, exact/server/scheme.ts, upto/server/scheme.ts
to pass the format quality gate.
…ent examples

The upto and batch-settlement facilitators were missing EVM_RPC_URL support
that the exact facilitator already had, causing EVM verify/settle to fail
with ECONNREFUSED when viem's default BSC testnet endpoint was unreachable.
SDK (tron package):
- constants.ts: add Shasta to PERMIT2_ADDRESSES, X402_PERMIT2_PROXY_ADDRESSES,
  X402_UPTO_PERMIT2_PROXY_ADDRESSES
- batch-settlement/constants.ts: add Shasta to BATCH_SETTLEMENT_ADDRESSES,
  ERC3009_DEPOSIT_COLLECTOR_ADDRESSES, PERMIT2_DEPOSIT_COLLECTOR_ADDRESSES
- tokens.ts: set Shasta USDT to permit2 (was eip3009); update comments
- tokens.test.ts: update Shasta assertions to match permit2

Examples:
- Replace all hardcoded tron:0x... CAIP-2 IDs with SDK-exported TRON_NILE /
  TRON_MAINNET / TRON_SHASTA constants (28 files)
- Add TRON_SHASTA to multi-network arrays (exact trio)
- Make single-network scenarios env-switchable via TRON_NETWORK env var
  (upto, batch, gasfree, mcp, multi-scheme)
- Convert flat TOKEN_ADDRESSES to nested by-network structure (upto, batch,
  mcp clients); add Shasta USDT entry
- servers/express: tronAccepts() now dynamically lists tokens per network
  via getNetworkTokens() instead of hardcoding USDT+USDD
- .env-*.example: document all available TRON networks (Nile/Shasta/Mainnet)
  and add TRON_NETWORK env var hint for single-network scenarios

Tested on Shasta: exact, upto, batch-settlement scenarios all pass.
Replace hardcoded USDT+USDD with dynamic getNetworkTokens() lookup,
matching the fix already applied to servers/express. Fixes 500 error
on networks without USDD (e.g. Shasta).
Remove the external facilitator service-fee (feeConfig) configuration across
exact/upto/gasfree schemes, along with the shared/fee.ts module and its
FeeInfo/ExactTronFeeConfig exports. The GasFree provider-driven fees
(transferFee, activateFee, relayer provider selection and provider-list
validation) are preserved.

BREAKING CHANGE: TronFacilitatorConfig.fee, TronGasFreeFacilitatorConfig.fee,
the upto facilitator feeConfig constructor parameter, and the FeeInfo /
ExactTronFeeConfig type exports are removed. Upgrade requires a major version.
filterAffordableRequirements only checked req.amount, but GasFree deducts
amount + maxFee (transferFee + activateFee). Add an optional estimateCost
method to BalanceCheckable; the GasFree client implements it by reusing
computeMaxFee so options whose balance covers amount but not amount + fee
are excluded before selection instead of failing later in createPaymentPayload.

Also applies prettier formatting to the fee-removal files flagged by CI.

@matrix-agent116 matrix-agent116 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This is a substantial upstream synchronization with useful interoperability, wallet-compatibility, and TRON network updates. However, the new counterfactual batch-deposit verification can accept reverted simulations, and the example network-selection changes contain regressions, so I’m requesting changes before merge.

Required improvements

  1. Blocker: Inspect the results returned by the counterfactual ERC-6492 batch-deposit multicall. tryAggregate(false, ...) reports individual reverts as failure entries rather than throwing, so the current function returns success even when deployment or deposit simulation failed.
  2. Blocker: Key custom GasFree API URLs by the selected TRON_NETWORK in both the client and facilitator. The current Nile-only map replaces the complete defaults map and leaves Shasta/mainnet without a configured client when an override is supplied.
  3. Blocker: Preserve documented family-prefix targets such as tron@USDT and eip155@USDC, or remove those shortcuts from the documentation. The new network-indexed lookup currently leaves such symbols unresolved in the batch-settlement, MCP, and upto clients.
  4. Add regression coverage for failed multicall entries, non-Nile GasFree overrides, and family-prefix token targets.
  5. Remove the newly introduced unused imports and provide the PR’s test/lint results in the description before the next review.

callData: depositCallData,
},
]);
return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[blocker] Please check both results returned by multicall before returning success. The helper calls tryAggregate(false, ...), so a reverted factory deployment or deposit is returned as { status: "failure" } without rejecting the promise; as written, any normally returned result array reaches return true, allowing an invalid counterfactual deposit to pass verify. Require successful deployment and deposit entries, and add tests for each failure case.

? { schemeOptions: { apiBaseUrls: { "tron:0xcd8690dc": process.env.GASFREE_API_URL } } }
? {
schemeOptions: {
apiBaseUrls: { [TRON_NILE]: process.env.GASFREE_API_URL },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[blocker] This override must be keyed by TRON_NETWORK, not always TRON_NILE. Supplying GASFREE_API_URL replaces the SDK’s complete default URL map with this one-entry map; when TRON_NETWORK selects Shasta or mainnet, getApiClient therefore has no entry for the payment network. The facilitator has the same issue in its apiBaseUrls override and should be updated together.

function resolveToken(token: string): string {
return TOKEN_ADDRESSES[token.toUpperCase()] ?? token;
function resolveToken(prefix: string, token: string): string {
return TOKEN_ADDRESSES[prefix]?.[token.toUpperCase()] ?? token;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[blocker] The documented family shortcuts no longer work when a token symbol is included. For example, tron@USDT looks up TOKEN_ADDRESSES["tron"], falls back to the literal string USDT, and later compares that string with an advertised asset address, so no option matches. Please resolve a family prefix against the matching configured networks (with ambiguity handled explicitly), or require a full network whenever a symbol is supplied and update the documentation. The same new lookup appears in the MCP and upto clients.

import { getAddress, encodeFunctionData } from "viem";
import { parseErc6492Signature, isAddressEqual } from "viem";
import { FacilitatorEvmSigner } from "../../signer";
import { verifyTypedDataSignature } from "../../shared/verifySignature";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] verifyTypedDataSignature is imported here but is not referenced in this file; isContractRevert on line 19 is also unused. Please remove both imports because this package’s ESLint configuration treats unused variables/imports as errors.

@ibrihymfastk-collab

Copy link
Copy Markdown


IMG_0378

upto is permit2-only (no EIP-3009 path), so facilitatorAddress and
permit2FacilitatorAddress were always identical. Remove the redundant
field and its fallback reads across facilitator/client/server; keep
only permit2FacilitatorAddress.
Resolve fee-removal conflicts by taking ours (full GasFree fee removal).
Adopt main's requirementsWithoutFee fee-stripping in exact/upto servers,
advisory-fee-removal tests, README/changeset fixes, and signer-wallet
naming. Fix README and changeset to reflect GasFree fee also removed.
- Check multicall results in counterfactual ERC-6492 deposit simulation:
  tryAggregate(false) returns failure entries without throwing, so verify
  each result is successful instead of unconditionally returning true
- Key GASFREE_API_URL override by TRON_NETWORK instead of hardcoded
  TRON_NILE in both client and facilitator, so non-Nile networks resolve
- Require full CAIP-2 network when a token symbol is specified in
  PAY_TARGETS across batch-settlement, upto, mcp, and fetch clients;
  family prefixes (e.g. tron@USDT) now error with a clear message
- Remove unused verifyTypedDataSignature and isContractRevert imports
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.

3 participants