From 780c81d9c004e623f4aab64ab82504a0f3ad8a0f Mon Sep 17 00:00:00 2001 From: "roger.gan" Date: Fri, 3 Jul 2026 19:47:52 +0800 Subject: [PATCH 1/3] fix(tron): use hex chain id in CAIP-2 network identifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per upstream spec PR x402-foundation/x402#2076 review feedback, CAIP-2 network identifiers must use the hex chain id, not human-readable network names. Replaces all `tron:mainnet`/`tron:nile`/`tron:shasta` keys with `tron:0x2b6653dc`/`tron:0xcd8690dc`/`tron:0x94a9059e` across the codebase. BREAKING CHANGE: network identifiers change from `tron:mainnet`/`tron:nile` to `tron:0x2b6653dc`/`tron:0xcd8690dc`. Clients and servers must be upgraded together — a mismatched pair will fail to interop. The `tron:` CAIP-2 namespace is still provisional pending CASA registration (ChainAgnostic/namespaces#170, #162). --- examples/typescript/.env-batch.example | 6 +- examples/typescript/.env-exact.example | 6 +- examples/typescript/.env-gasfree.example | 2 +- examples/typescript/.env-upto.example | 6 +- examples/typescript/README.md | 8 +-- .../batch-settlement/src/chains/tron.ts | 4 +- .../clients/batch-settlement/src/env.ts | 2 +- .../clients/batch-settlement/src/index.ts | 6 +- .../clients/fetch/src/chains/tron.ts | 2 +- examples/typescript/clients/fetch/src/env.ts | 2 +- .../typescript/clients/fetch/src/index.ts | 14 ++--- .../clients/gasfree/src/chains/tron.ts | 4 +- .../typescript/clients/gasfree/src/env.ts | 4 +- examples/typescript/clients/mcp/README.md | 2 +- .../typescript/clients/mcp/src/chains/tron.ts | 2 +- examples/typescript/clients/mcp/src/env.ts | 2 +- examples/typescript/clients/mcp/src/index.ts | 6 +- .../clients/upto/src/chains/tron.ts | 4 +- examples/typescript/clients/upto/src/env.ts | 2 +- examples/typescript/clients/upto/src/index.ts | 6 +- .../typescript/facilitator/basic/README.md | 2 +- .../facilitator/basic/src/chains/tron.ts | 2 +- .../typescript/facilitator/basic/src/env.ts | 2 +- .../facilitator/batch-settlement/README.md | 2 +- .../batch-settlement/src/chains/tron.ts | 2 +- .../facilitator/batch-settlement/src/env.ts | 2 +- .../typescript/facilitator/gasfree/README.md | 2 +- .../facilitator/gasfree/src/chains/tron.ts | 4 +- .../typescript/facilitator/gasfree/src/env.ts | 2 +- .../typescript/facilitator/upto/README.md | 4 +- .../facilitator/upto/src/chains/tron.ts | 2 +- .../typescript/facilitator/upto/src/env.ts | 2 +- .../servers/batch-settlement/README.md | 2 +- .../batch-settlement/src/chains/tron.ts | 6 +- examples/typescript/servers/express/README.md | 2 +- .../servers/express/src/chains/tron.ts | 6 +- .../servers/gasfree/src/chains/tron.ts | 4 +- examples/typescript/servers/mcp/README.md | 2 +- .../typescript/servers/mcp/src/chains/tron.ts | 8 +-- examples/typescript/servers/upto/README.md | 2 +- .../servers/upto/src/chains/tron.ts | 6 +- typescript/packages/mechanisms/tron/README.md | 8 +-- .../src/batch-settlement/client/voucher.ts | 2 +- .../src/batch-settlement/server/scheme.ts | 2 +- .../packages/mechanisms/tron/src/constants.ts | 29 +++++++--- .../tron/src/exact/server/scheme.ts | 6 +- .../tron/src/gasfree/client/scheme.ts | 2 +- .../packages/mechanisms/tron/src/index.ts | 5 +- .../packages/mechanisms/tron/src/rpc.ts | 16 +++--- .../batch-settlement/authorizerSigner.ts | 4 +- .../src/shared/batch-settlement/constants.ts | 14 ++--- .../tron/src/shared/batch-settlement/utils.ts | 2 +- .../tron/src/shared/defaultAssets.ts | 2 +- .../tron/src/shared/gasfree/config.ts | 18 +++--- .../mechanisms/tron/src/shared/tokens.ts | 14 ++--- .../packages/mechanisms/tron/src/signer.ts | 18 +++--- .../mechanisms/tron/src/upto/server/scheme.ts | 6 +- .../packages/mechanisms/tron/src/utils.ts | 2 +- .../test/unit/batch-refund-network.test.ts | 6 +- .../unit/batch-settlement/deposit-sig.test.ts | 6 +- .../test/unit/batch-settlement/digest.test.ts | 6 +- .../unit/batch-settlement/lifecycle.test.ts | 2 +- .../batch-settlement/server-hooks.test.ts | 2 +- .../tron/test/unit/client-allowance.test.ts | 2 +- .../tron/test/unit/facilitator-wallet.test.ts | 2 +- .../tron/test/unit/fee-plumbing.test.ts | 2 +- .../mechanisms/tron/test/unit/fee.test.ts | 2 +- .../tron/test/unit/flow-integration.test.ts | 2 +- .../tron/test/unit/gasfree-digest.test.ts | 2 +- .../tron/test/unit/gasfree-feeto.test.ts | 2 +- .../tron/test/unit/gasfree-flow.test.ts | 4 +- .../tron/test/unit/permit2-digest.test.ts | 2 +- .../mechanisms/tron/test/unit/rpc.test.ts | 12 ++-- .../tron/test/unit/selection.test.ts | 2 +- .../test/unit/server.moneyConversion.test.ts | 4 +- .../tron/test/unit/signer-wallet.test.ts | 2 +- .../mechanisms/tron/test/unit/tokens.test.ts | 56 +++++++++---------- .../tron/test/unit/upto-flow.test.ts | 2 +- 78 files changed, 224 insertions(+), 202 deletions(-) diff --git a/examples/typescript/.env-batch.example b/examples/typescript/.env-batch.example index fbaad9a4..09deb86a 100644 --- a/examples/typescript/.env-batch.example +++ b/examples/typescript/.env-batch.example @@ -20,11 +20,11 @@ TRON_GRID_API_KEY= # ── CLIENT · the payer (clients/batch-settlement) ───────────────────────── # Which chains to exercise, one burst (+refund) per entry, in order. Each entry is -# [@] network: "eip155:97"/"tron:nile" (or "eip155"/"tron"); +# [@] network: "eip155:97"/"tron:0xcd8690dc" (or "eip155"/"tron"); # token optional (each chain advertises one: EVM=USDC, TRON=USDT) — symbol or # asset address. Use `@` (not `#`) — dotenv treats `#` as a comment. # Unset ⇒ each configured chain once. -PAY_TARGETS=eip155:97,tron:nile +PAY_TARGETS=eip155:97,tron:0xcd8690dc # The resource the client fetches (server route). RESOURCE_URL=http://localhost:4041/weather @@ -45,7 +45,7 @@ REFUND_AFTER_REQUESTS=false # refund the remaining channel balance after the bur # ── SERVER · the resource provider (servers/batch-settlement) ───────────── # Payout addresses (set the chain(s) you want to accept). EVM_ADDRESS=0x... # BSC, eip155:97 (token USDC, permit2) -TRON_ADDRESS=T... # TRON, tron:nile (token USDT, permit2) +TRON_ADDRESS=T... # TRON, tron:0xcd8690dc (token USDT, permit2) # Where the server binds, and where it reaches the facilitator. SERVER_PORT=4041 diff --git a/examples/typescript/.env-exact.example b/examples/typescript/.env-exact.example index 5c94dd46..f5a65d25 100644 --- a/examples/typescript/.env-exact.example +++ b/examples/typescript/.env-exact.example @@ -24,12 +24,12 @@ TRON_GRID_API_KEY= # ── CLIENT · the payer (clients/fetch · clients/mcp) ────────────────────── # Which chains/tokens to pay, one payment per entry, in order. -# [@] network: "eip155:97"/"tron:nile" (or "eip155"/"tron"); +# [@] network: "eip155:97"/"tron:0xcd8690dc" (or "eip155"/"tron"); # token: symbol (DHLU/USDC/USDT on EVM, USDT/USDD on TRON) or an asset address; # omit the token to use that network's first advertised token. # Use `@` (not `#`) — dotenv treats `#` as a comment and would truncate the value. # Unset ⇒ each configured chain once, with its first token. -PAY_TARGETS=eip155:97@DHLU,tron:nile@USDT +PAY_TARGETS=eip155:97@DHLU,tron:0xcd8690dc@USDT # The resource the client fetches (server route). RESOURCE_URL=http://localhost:4021/weather @@ -40,7 +40,7 @@ MCP_SERVER_URL=http://localhost:4023 # ── SERVER · the resource provider (servers/express · servers/mcp) ──────── # Payout addresses (set the chain(s) you want to accept). EVM_ADDRESS=0x... # BSC, eip155:97 -TRON_ADDRESS=T... # TRON, tron:nile +TRON_ADDRESS=T... # TRON, tron:0xcd8690dc # Where the server binds, and where it reaches the facilitator. SERVER_PORT=4021 diff --git a/examples/typescript/.env-gasfree.example b/examples/typescript/.env-gasfree.example index 7df58c14..50842110 100644 --- a/examples/typescript/.env-gasfree.example +++ b/examples/typescript/.env-gasfree.example @@ -30,7 +30,7 @@ RESOURCE_URL=http://localhost:4031/weather # ── SERVER · the resource provider (servers/gasfree) ────────────────────── # Payout address (TRON only). -TRON_ADDRESS=T... # TRON, tron:nile +TRON_ADDRESS=T... # TRON, tron:0xcd8690dc # Where the server binds, and where it reaches the facilitator. SERVER_PORT=4031 diff --git a/examples/typescript/.env-upto.example b/examples/typescript/.env-upto.example index 9a5a9e1f..4e4e57d3 100644 --- a/examples/typescript/.env-upto.example +++ b/examples/typescript/.env-upto.example @@ -21,11 +21,11 @@ TRON_GRID_API_KEY= # ── CLIENT · the payer (clients/upto) ───────────────────────────────────── # Which chains to exercise, one N-request run per entry, in order. Each entry is -# [@] network: "eip155:97"/"tron:nile" (or "eip155"/"tron"); +# [@] network: "eip155:97"/"tron:0xcd8690dc" (or "eip155"/"tron"); # token optional (each chain advertises one: EVM=USDC, TRON=USDT) — symbol or # asset address. Use `@` (not `#`) — dotenv treats `#` as a comment. # Unset ⇒ each configured chain once. -PAY_TARGETS=eip155:97,tron:nile +PAY_TARGETS=eip155:97,tron:0xcd8690dc # The resource the client fetches (server route). RESOURCE_URL=http://localhost:4051/generate @@ -41,7 +41,7 @@ NUMBER_OF_REQUESTS=3 # ── SERVER · the resource provider (servers/upto) ───────────────────────── # Payout addresses (set the chain(s) you want to accept). EVM_ADDRESS=0x... # BSC, eip155:97 (token USDC, permit2) -TRON_ADDRESS=T... # TRON, tron:nile (token USDT, permit2) +TRON_ADDRESS=T... # TRON, tron:0xcd8690dc (token USDT, permit2) # Where the server binds, and where it reaches the facilitator. SERVER_PORT=4051 diff --git a/examples/typescript/README.md b/examples/typescript/README.md index 7903a63b..31a6f245 100644 --- a/examples/typescript/README.md +++ b/examples/typescript/README.md @@ -91,8 +91,8 @@ amount and strips the header. BSC uses USDC, TRON Nile uses USDT — both Permit | Chain | Network | Token | Scheme | One-time approve | User pays gas? | |---|---|---|---|---|---| -| TRON nile | `tron:nile` | USDT (6) | exact **permit2** | yes — client auto-broadcasts | only the approve (TRX) | -| TRON nile | `tron:nile` | USDD (18) | exact **permit2** | yes — client auto-broadcasts | only the approve (TRX) | +| TRON nile | `tron:0xcd8690dc` | USDT (6) | exact **permit2** | yes — client auto-broadcasts | only the approve (TRX) | +| TRON nile | `tron:0xcd8690dc` | USDD (18) | exact **permit2** | yes — client auto-broadcasts | only the approve (TRX) | | BSC testnet | `eip155:97` | DHLU (6) | exact **eip3009** | none | **none (fully gasless)** | | BSC testnet | `eip155:97` | USDC (18) | exact **permit2 + gas-sponsoring** | yes — client signs, facilitator relays | only the approve (BNB) | @@ -131,8 +131,8 @@ below). All verified on-chain; sources: the official | `eip155:56` (BSC) | USDC | `0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d` | 18 | permit2 | | `eip155:56` (BSC) | USDT | `0x55d398326f99059fF775485246999027B3197955` | 18 | permit2 | | `eip155:56` (BSC) | EPS | `0xA7f552078dcC247C2684336020c03648500C6d9F` | 18 | permit2 | -| `tron:mainnet` | USDT | `TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t` | 6 | permit2 | -| `tron:mainnet` | USDD | `TXDk8mbtRbXeYuMNS83CfKPaYYT8XWv9Hz` | 18 | permit2 | +| `tron:0x2b6653dc` | USDT | `TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t` | 6 | permit2 | +| `tron:0x2b6653dc` | USDD | `TXDk8mbtRbXeYuMNS83CfKPaYYT8XWv9Hz` | 18 | permit2 | > BSC mainnet has **no ERC-3009 token** (USDC/USDT/EPS are all plain BEP-20) — so > mainnet EVM payments all go permit2 + gas-sponsored approve. DHLU (eip3009) is diff --git a/examples/typescript/clients/batch-settlement/src/chains/tron.ts b/examples/typescript/clients/batch-settlement/src/chains/tron.ts index 4e7131fe..b2a79cfd 100644 --- a/examples/typescript/clients/batch-settlement/src/chains/tron.ts +++ b/examples/typescript/clients/batch-settlement/src/chains/tron.ts @@ -4,7 +4,7 @@ * the address and re-adds the `0x` prefix agent-wallet strips. The TronWeb * instance carries no private key. * - * On `tron:nile` the server advertises USDT, a Permit2 token — the first request + * On `tron:0xcd8690dc` the server advertises USDT, a Permit2 token — the first request * opens the channel via a **Permit2 deposit**, which needs a one-time * `approve(Permit2)` from the payer. `signTransaction` lets the signer * auto-broadcast that approve (parity with the `exact` TRON client). Later @@ -16,7 +16,7 @@ import type { x402Client } from "@bankofai/x402-fetch"; import { tryResolveWallet, type BatchClientOptions, type RefundableScheme } from "../env.js"; -const TRON_NETWORK = "tron:nile"; +const TRON_NETWORK = "tron:0xcd8690dc"; /** * Registers the TRON `batch-settlement` client scheme, if a TRON wallet is diff --git a/examples/typescript/clients/batch-settlement/src/env.ts b/examples/typescript/clients/batch-settlement/src/env.ts index 423202f4..3a4fdd34 100644 --- a/examples/typescript/clients/batch-settlement/src/env.ts +++ b/examples/typescript/clients/batch-settlement/src/env.ts @@ -20,7 +20,7 @@ export type SignerWallet = Wallet & { */ const CAIP2_BY_FAMILY: Record<"evm" | "tron", string> = { evm: "eip155:97", - tron: "tron:nile", + tron: "tron:0xcd8690dc", }; /** diff --git a/examples/typescript/clients/batch-settlement/src/index.ts b/examples/typescript/clients/batch-settlement/src/index.ts index e99bcb89..acd96614 100644 --- a/examples/typescript/clients/batch-settlement/src/index.ts +++ b/examples/typescript/clients/batch-settlement/src/index.ts @@ -10,7 +10,7 @@ * target. This file imports no chain SDK directly. * * PAY_TARGETS — comma-separated, one burst (+refund) per entry, in order: - * [@] network: "eip155:97"/"tron:nile" (or "eip155"/"tron"); + * [@] network: "eip155:97"/"tron:0xcd8690dc" (or "eip155"/"tron"); * token: symbol or asset address; omit ⇒ the network's first advertised token. * (`@` not `#` — dotenv treats `#` as a comment.) * Unset ⇒ each configured chain once. @@ -36,8 +36,8 @@ const opts: BatchClientOptions = { const TOKEN_ADDRESSES: Record = { DHLU: "0x375cADdd2cB68cE82e3D9B075D551067a7b4B816", // eip155:97, ERC-3009 USDC: "0x64544969ed7EBf5f083679233325356EbE738930", // eip155:97, permit2 (default) - USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:nile, permit2 (default) - USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:nile, permit2 + USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:0xcd8690dc, permit2 (default) + USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:0xcd8690dc, permit2 }; /** A single payment target: a network prefix + optional asset address. */ diff --git a/examples/typescript/clients/fetch/src/chains/tron.ts b/examples/typescript/clients/fetch/src/chains/tron.ts index 9f274f82..b465830f 100644 --- a/examples/typescript/clients/fetch/src/chains/tron.ts +++ b/examples/typescript/clients/fetch/src/chains/tron.ts @@ -15,7 +15,7 @@ import type { x402Client } from "@bankofai/x402-fetch"; import { tryResolveWallet } from "../env.js"; -const TRON_NETWORKS = ["tron:nile", "tron:mainnet"] as const; +const TRON_NETWORKS = ["tron:0xcd8690dc", "tron:0x2b6653dc"] as const; /** * Registers the TRON `exact` client scheme, if a TRON wallet is configured. diff --git a/examples/typescript/clients/fetch/src/env.ts b/examples/typescript/clients/fetch/src/env.ts index 99d3b5ab..18cd0cfe 100644 --- a/examples/typescript/clients/fetch/src/env.ts +++ b/examples/typescript/clients/fetch/src/env.ts @@ -23,7 +23,7 @@ export type SignerWallet = Wallet & { */ const CAIP2_BY_FAMILY: Record<"evm" | "tron", string> = { evm: "eip155:97", - tron: "tron:nile", + tron: "tron:0xcd8690dc", }; /** diff --git a/examples/typescript/clients/fetch/src/index.ts b/examples/typescript/clients/fetch/src/index.ts index 5c8385fd..c583072f 100644 --- a/examples/typescript/clients/fetch/src/index.ts +++ b/examples/typescript/clients/fetch/src/index.ts @@ -10,10 +10,10 @@ * * PAY_TARGETS — comma-separated, one payment per entry, in order: * [@] - * matched by prefix: "eip155:97" / "tron:nile" (or "eip155" / "tron") + * matched by prefix: "eip155:97" / "tron:0xcd8690dc" (or "eip155" / "tron") * symbol (DHLU/USDC/USDT/USDD) or an asset address; omit ⇒ that * network's first advertised token - * e.g. PAY_TARGETS=eip155:97@DHLU,tron:nile@USDT,tron:nile@USDD + * e.g. PAY_TARGETS=eip155:97@DHLU,tron:0xcd8690dc@USDT,tron:0xcd8690dc@USDD * (`@` not `#` — dotenv treats `#` as a comment.) * Unset ⇒ each configured chain once, with its first advertised token. */ @@ -28,7 +28,7 @@ const RESOURCE_URL = // Friendly token symbol → asset address, mirroring what `servers/express` // advertises. Lets PAY_TARGETS name tokens by symbol instead of address. // Indexed by chain family so the same symbol can resolve differently per -// network (e.g. USDT on eip155:97 vs tron:nile are different contracts). +// network (e.g. USDT on eip155:97 vs tron:0xcd8690dc are different contracts). const TOKEN_ADDRESSES: Record> = { "eip155:97": { DHLU: "0x375cADdd2cB68cE82e3D9B075D551067a7b4B816", // eip155:97, ERC-3009 @@ -39,11 +39,11 @@ const TOKEN_ADDRESSES: Record> = { USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", USDT: "0x55d398326f99059fF775485246999027B3197955", }, - "tron:nile": { - USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:nile, permit2 - USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:nile, permit2 + "tron:0xcd8690dc": { + USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:0xcd8690dc, permit2 + USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:0xcd8690dc, permit2 }, - "tron:mainnet": { + "tron:0x2b6653dc": { USDT: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", USDD: "TXDk8mbtRbXeYuMNS83CfKPaYYT8XWv9Hz", }, diff --git a/examples/typescript/clients/gasfree/src/chains/tron.ts b/examples/typescript/clients/gasfree/src/chains/tron.ts index 17d3bc22..21114983 100644 --- a/examples/typescript/clients/gasfree/src/chains/tron.ts +++ b/examples/typescript/clients/gasfree/src/chains/tron.ts @@ -16,7 +16,7 @@ import type { x402Client } from "@bankofai/x402-fetch"; import { tryResolveTronWallet } from "../env.js"; -const TRON_NETWORK = "tron:nile"; +const TRON_NETWORK = "tron:0xcd8690dc"; /** * Registers the TRON `exact_gasfree` client scheme, if a TRON wallet resolves. @@ -43,7 +43,7 @@ export async function registerTronGasFree(client: x402Client): Promise registerExactGasFreeTronScheme(client, { signer, ...(process.env.GASFREE_API_URL - ? { schemeOptions: { apiBaseUrls: { "tron:nile": process.env.GASFREE_API_URL } } } + ? { schemeOptions: { apiBaseUrls: { "tron:0xcd8690dc": process.env.GASFREE_API_URL } } } : {}), }); console.info(`[tron] client registered tron:* exact_gasfree (${signer.address})`); diff --git a/examples/typescript/clients/gasfree/src/env.ts b/examples/typescript/clients/gasfree/src/env.ts index 80ed0e56..1401bbd3 100644 --- a/examples/typescript/clients/gasfree/src/env.ts +++ b/examples/typescript/clients/gasfree/src/env.ts @@ -18,13 +18,13 @@ export type SignerWallet = Wallet & { * * `@bankofai/agent-wallet` expects a **CAIP-2** network id. Key derivation is * chain-id-independent within a family, so any `tron:` id resolves the same - * address; we use `tron:nile`. + * address; we use `tron:0xcd8690dc`. * * @returns The wallet, or `null` to skip TRON. */ export async function tryResolveTronWallet(): Promise { try { - return (await resolveWallet({ network: "tron:nile" })) as SignerWallet; + return (await resolveWallet({ network: "tron:0xcd8690dc" })) as SignerWallet; } catch { return null; } diff --git a/examples/typescript/clients/mcp/README.md b/examples/typescript/clients/mcp/README.md index 0f6893f1..4a31b37f 100644 --- a/examples/typescript/clients/mcp/README.md +++ b/examples/typescript/clients/mcp/README.md @@ -2,7 +2,7 @@ Connects to an MCP server over SSE and calls its tools. On a 402, the SDK pays automatically using whichever registered scheme matches the server's offered -network — **BSC testnet** (`eip155:97`) or **TRON Nile** (`tron:nile`). +network — **BSC testnet** (`eip155:97`) or **TRON Nile** (`tron:0xcd8690dc`). Both chains are registered in one `createx402MCPClient({ schemes })` call; the payment-selection pipeline filters by the offered network and picks a match. Each diff --git a/examples/typescript/clients/mcp/src/chains/tron.ts b/examples/typescript/clients/mcp/src/chains/tron.ts index eaf8ff12..24acc696 100644 --- a/examples/typescript/clients/mcp/src/chains/tron.ts +++ b/examples/typescript/clients/mcp/src/chains/tron.ts @@ -11,7 +11,7 @@ import type { Network, SchemeNetworkClient } from "@bankofai/x402-core/types"; import { tryResolveWallet } from "../env.js"; /** CAIP-2 network this client pays on. */ -export const TRON_NETWORK: Network = "tron:nile"; +export const TRON_NETWORK: Network = "tron:0xcd8690dc"; /** * Builds the TRON `exact` client scheme registration, if a TRON wallet resolves. diff --git a/examples/typescript/clients/mcp/src/env.ts b/examples/typescript/clients/mcp/src/env.ts index 959e4dd7..49a19e21 100644 --- a/examples/typescript/clients/mcp/src/env.ts +++ b/examples/typescript/clients/mcp/src/env.ts @@ -21,7 +21,7 @@ export type SignerWallet = Wallet & { */ const CAIP2_BY_FAMILY: Record<"evm" | "tron", string> = { evm: "eip155:97", - tron: "tron:nile", + tron: "tron:0xcd8690dc", }; /** diff --git a/examples/typescript/clients/mcp/src/index.ts b/examples/typescript/clients/mcp/src/index.ts index 307639d3..85932735 100644 --- a/examples/typescript/clients/mcp/src/index.ts +++ b/examples/typescript/clients/mcp/src/index.ts @@ -10,7 +10,7 @@ * lives in `src/chains/`. * * PAY_TARGETS — comma-separated, one paid call per entry, in order: - * [@] network: "eip155:97"/"tron:nile" (or "eip155"/"tron"); + * [@] network: "eip155:97"/"tron:0xcd8690dc" (or "eip155"/"tron"); * token: symbol (DHLU on EVM; USDT/USDD on TRON) or an asset address; omit ⇒ * the network's first advertised token. * (`@` not `#` — dotenv treats `#` as a comment.) @@ -31,8 +31,8 @@ const SERVER_URL = process.env.MCP_SERVER_URL || "http://localhost:4023"; const TOKEN_ADDRESSES: Record = { DHLU: "0x375cADdd2cB68cE82e3D9B075D551067a7b4B816", // eip155:97, ERC-3009 USDC: "0x64544969ed7EBf5f083679233325356EbE738930", // eip155:97, permit2 - USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:nile, permit2 - USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:nile, permit2 + USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:0xcd8690dc, permit2 + USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:0xcd8690dc, permit2 }; /** A single payment target: a network prefix + optional asset address. */ diff --git a/examples/typescript/clients/upto/src/chains/tron.ts b/examples/typescript/clients/upto/src/chains/tron.ts index 4e6e762f..5e7e8cf0 100644 --- a/examples/typescript/clients/upto/src/chains/tron.ts +++ b/examples/typescript/clients/upto/src/chains/tron.ts @@ -4,7 +4,7 @@ * the address and re-adds the `0x` prefix agent-wallet strips. The TronWeb * instance carries no private key. * - * On `tron:nile` the server advertises USDT, a **Permit2** token — the upto + * On `tron:0xcd8690dc` the server advertises USDT, a **Permit2** token — the upto * payment is a Permit2 `PermitWitnessTransferFrom` signed for up to the * advertised maximum, and needs a one-time `approve(Permit2)` from the payer. * `signTransaction` lets the signer auto-broadcast that approve. @@ -15,7 +15,7 @@ import type { x402Client } from "@bankofai/x402-fetch"; import { tryResolveWallet } from "../env.js"; -const TRON_NETWORK = "tron:nile"; +const TRON_NETWORK = "tron:0xcd8690dc"; /** * Registers the TRON `upto` client scheme, if a TRON wallet is configured. diff --git a/examples/typescript/clients/upto/src/env.ts b/examples/typescript/clients/upto/src/env.ts index ccb20086..eeed6f4c 100644 --- a/examples/typescript/clients/upto/src/env.ts +++ b/examples/typescript/clients/upto/src/env.ts @@ -21,7 +21,7 @@ export type SignerWallet = Wallet & { */ const CAIP2_BY_FAMILY: Record<"evm" | "tron", string> = { evm: "eip155:97", - tron: "tron:nile", + tron: "tron:0xcd8690dc", }; /** diff --git a/examples/typescript/clients/upto/src/index.ts b/examples/typescript/clients/upto/src/index.ts index 912b084b..ccd8e30c 100644 --- a/examples/typescript/clients/upto/src/index.ts +++ b/examples/typescript/clients/upto/src/index.ts @@ -10,7 +10,7 @@ * imports no chain SDK directly. * * PAY_TARGETS — comma-separated, one run (N requests) per entry, in order: - * [@] network: "eip155:97"/"tron:nile" (or "eip155"/"tron"); + * [@] network: "eip155:97"/"tron:0xcd8690dc" (or "eip155"/"tron"); * token: symbol or asset address; omit ⇒ the network's first advertised token. * (`@` not `#` — dotenv treats `#` as a comment.) * Unset ⇒ each configured chain once. @@ -27,8 +27,8 @@ const NUMBER_OF_REQUESTS = Number(process.env.NUMBER_OF_REQUESTS ?? "3"); const TOKEN_ADDRESSES: Record = { DHLU: "0x375cADdd2cB68cE82e3D9B075D551067a7b4B816", // eip155:97, ERC-3009 USDC: "0x64544969ed7EBf5f083679233325356EbE738930", // eip155:97, permit2 (default) - USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:nile, permit2 (default) - USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:nile, permit2 + USDT: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", // tron:0xcd8690dc, permit2 (default) + USDD: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", // tron:0xcd8690dc, permit2 }; /** A single payment target: a network prefix + optional asset address. */ diff --git a/examples/typescript/facilitator/basic/README.md b/examples/typescript/facilitator/basic/README.md index e3f9b15c..68511247 100644 --- a/examples/typescript/facilitator/basic/README.md +++ b/examples/typescript/facilitator/basic/README.md @@ -36,7 +36,7 @@ provider matrix. | Chain | Network | Scheme | |---|---|---| | EVM | `eip155:97` (BSC testnet) | `exact` — DHLU via eip3009, USDC via permit2 + gas-sponsored approve | -| TRON | `tron:nile` | `exact` — USDT/USDD via permit2 (auto-approve) | +| TRON | `tron:0xcd8690dc` | `exact` — USDT/USDD via permit2 (auto-approve) | Add another EVM network (e.g. Base Sepolia) by adding one entry to the `EVM_NETWORKS` table in `src/chains/evm.ts`. The ERC-20 approval gas-sponsoring diff --git a/examples/typescript/facilitator/basic/src/chains/tron.ts b/examples/typescript/facilitator/basic/src/chains/tron.ts index a30a1392..c271bd3e 100644 --- a/examples/typescript/facilitator/basic/src/chains/tron.ts +++ b/examples/typescript/facilitator/basic/src/chains/tron.ts @@ -10,7 +10,7 @@ import type { x402Facilitator } from "@bankofai/x402-core/facilitator"; import { tryResolveWallet } from "../env.js"; /** TRON testnet + mainnet. */ -export const TRON_NETWORKS = ["tron:nile", "tron:mainnet"] as const; +export const TRON_NETWORKS = ["tron:0xcd8690dc", "tron:0x2b6653dc"] as const; /** * Registers the TRON `exact` scheme on the facilitator, if a TRON wallet is diff --git a/examples/typescript/facilitator/basic/src/env.ts b/examples/typescript/facilitator/basic/src/env.ts index ba0e2272..ae4d4071 100644 --- a/examples/typescript/facilitator/basic/src/env.ts +++ b/examples/typescript/facilitator/basic/src/env.ts @@ -24,7 +24,7 @@ export type SignerWallet = Wallet & { */ const CAIP2_BY_FAMILY: Record<"evm" | "tron", string> = { evm: "eip155:97", - tron: "tron:nile", + tron: "tron:0xcd8690dc", }; /** diff --git a/examples/typescript/facilitator/batch-settlement/README.md b/examples/typescript/facilitator/batch-settlement/README.md index 291aef8d..18c44c4c 100644 --- a/examples/typescript/facilitator/batch-settlement/README.md +++ b/examples/typescript/facilitator/batch-settlement/README.md @@ -41,7 +41,7 @@ server. Endpoints: `POST /verify`, `POST /settle`, `GET /supported`. | Chain | CAIP-2 | Contract | Token (advertised by server) | |---|---|---|---| | BSC testnet | `eip155:97` | deterministic singleton `0x4020…0003` | USDC (Permit2) | -| TRON Nile | `tron:nile` | `TWBwWHZWwH8TzrZnbxit1J645VGYY1K2fA` | USDT (Permit2) | +| TRON Nile | `tron:0xcd8690dc` | `TWBwWHZWwH8TzrZnbxit1J645VGYY1K2fA` | USDT (Permit2) | Add a chain by extending `EVM_NETWORKS` in [`src/chains/evm.ts`](src/chains/evm.ts) or adapting [`src/chains/tron.ts`](src/chains/tron.ts). diff --git a/examples/typescript/facilitator/batch-settlement/src/chains/tron.ts b/examples/typescript/facilitator/batch-settlement/src/chains/tron.ts index eb2db9ed..6fe95b11 100644 --- a/examples/typescript/facilitator/batch-settlement/src/chains/tron.ts +++ b/examples/typescript/facilitator/batch-settlement/src/chains/tron.ts @@ -17,7 +17,7 @@ import type { x402Facilitator } from "@bankofai/x402-core/facilitator"; import { tryResolveWallet } from "../env.js"; /** CAIP-2 network this facilitator settles on. */ -export const TRON_NETWORK = "tron:nile"; +export const TRON_NETWORK = "tron:0xcd8690dc"; /** * Registers the TRON `batch-settlement` scheme on the facilitator, if a TRON diff --git a/examples/typescript/facilitator/batch-settlement/src/env.ts b/examples/typescript/facilitator/batch-settlement/src/env.ts index 2cfbc79c..4730b4aa 100644 --- a/examples/typescript/facilitator/batch-settlement/src/env.ts +++ b/examples/typescript/facilitator/batch-settlement/src/env.ts @@ -24,7 +24,7 @@ export type SignerWallet = Wallet & { */ const CAIP2_BY_FAMILY: Record<"evm" | "tron", string> = { evm: "eip155:97", - tron: "tron:nile", + tron: "tron:0xcd8690dc", }; /** diff --git a/examples/typescript/facilitator/gasfree/README.md b/examples/typescript/facilitator/gasfree/README.md index ce0f5bd2..bffc34e0 100644 --- a/examples/typescript/facilitator/gasfree/README.md +++ b/examples/typescript/facilitator/gasfree/README.md @@ -4,7 +4,7 @@ Verifies and settles TRON **GasFree** payments. Unlike the `exact` facilitator i does **not** broadcast a raw TRON transaction — it forwards the signed TIP-712 permit to the **GasFree relayer API**, which pays the on-chain energy and submits. -- Scheme: `exact_gasfree` on `tron:nile`. +- Scheme: `exact_gasfree` on `tron:0xcd8690dc`. - Port `4032`. - Key custody in `@bankofai/agent-wallet`; the TronWeb instance holds no key. diff --git a/examples/typescript/facilitator/gasfree/src/chains/tron.ts b/examples/typescript/facilitator/gasfree/src/chains/tron.ts index 90ff8897..18661263 100644 --- a/examples/typescript/facilitator/gasfree/src/chains/tron.ts +++ b/examples/typescript/facilitator/gasfree/src/chains/tron.ts @@ -15,7 +15,7 @@ import type { x402Facilitator } from "@bankofai/x402-core/facilitator"; import { tryResolveTronWallet } from "../env.js"; /** CAIP-2 network this facilitator settles on. */ -export const TRON_NETWORK = "tron:nile"; +export const TRON_NETWORK = "tron:0xcd8690dc"; /** * Registers the TRON `exact_gasfree` scheme on the facilitator, if a TRON wallet @@ -44,7 +44,7 @@ export async function registerTronGasFree(facilitator: x402Facilitator): Promise signer, networks: TRON_NETWORK, ...(process.env.GASFREE_API_URL - ? { apiBaseUrls: { "tron:nile": process.env.GASFREE_API_URL } } + ? { apiBaseUrls: { "tron:0xcd8690dc": process.env.GASFREE_API_URL } } : {}), }); console.info(`[tron] facilitator registered ${TRON_NETWORK} exact_gasfree (${address})`); diff --git a/examples/typescript/facilitator/gasfree/src/env.ts b/examples/typescript/facilitator/gasfree/src/env.ts index 5200ddec..240e4096 100644 --- a/examples/typescript/facilitator/gasfree/src/env.ts +++ b/examples/typescript/facilitator/gasfree/src/env.ts @@ -20,7 +20,7 @@ export type SignerWallet = Wallet & { */ export async function tryResolveTronWallet(): Promise { try { - return (await resolveWallet({ network: "tron:nile" })) as SignerWallet; + return (await resolveWallet({ network: "tron:0xcd8690dc" })) as SignerWallet; } catch { return null; } diff --git a/examples/typescript/facilitator/upto/README.md b/examples/typescript/facilitator/upto/README.md index 934314b9..b47c43a5 100644 --- a/examples/typescript/facilitator/upto/README.md +++ b/examples/typescript/facilitator/upto/README.md @@ -29,7 +29,7 @@ server and client. ## Notes - The upto Permit2 proxy is a deterministic CREATE2 singleton on EVM (same - address on every chain) and is deployed per-network on TRON (`tron:nile` / - `tron:mainnet`). + address on every chain) and is deployed per-network on TRON (`tron:0xcd8690dc` / + `tron:0x2b6653dc`). - The settled amount is bounded by the client's Permit2 witness — the facilitator cannot settle more than the authorized maximum. diff --git a/examples/typescript/facilitator/upto/src/chains/tron.ts b/examples/typescript/facilitator/upto/src/chains/tron.ts index 6e1ce2aa..6c872462 100644 --- a/examples/typescript/facilitator/upto/src/chains/tron.ts +++ b/examples/typescript/facilitator/upto/src/chains/tron.ts @@ -14,7 +14,7 @@ import type { x402Facilitator } from "@bankofai/x402-core/facilitator"; import { tryResolveWallet } from "../env.js"; /** CAIP-2 network this facilitator settles on. */ -export const TRON_NETWORK = "tron:nile"; +export const TRON_NETWORK = "tron:0xcd8690dc"; /** * Registers the TRON `upto` scheme on the facilitator, if a TRON wallet is diff --git a/examples/typescript/facilitator/upto/src/env.ts b/examples/typescript/facilitator/upto/src/env.ts index b2234e11..fe5ea8dc 100644 --- a/examples/typescript/facilitator/upto/src/env.ts +++ b/examples/typescript/facilitator/upto/src/env.ts @@ -19,7 +19,7 @@ export type SignerWallet = Wallet; */ const CAIP2_BY_FAMILY: Record<"evm" | "tron", string> = { evm: "eip155:97", - tron: "tron:nile", + tron: "tron:0xcd8690dc", }; /** diff --git a/examples/typescript/servers/batch-settlement/README.md b/examples/typescript/servers/batch-settlement/README.md index 130ddc4c..38e74ad4 100644 --- a/examples/typescript/servers/batch-settlement/README.md +++ b/examples/typescript/servers/batch-settlement/README.md @@ -14,7 +14,7 @@ supplies the `receiverAuthorizer` (fetched via `/supported`). - Set the payout address(es) you want to accept: - `EVM_ADDRESS` → BSC (`eip155:97`), token USDC (Permit2) - - `TRON_ADDRESS` → TRON Nile (`tron:nile`), token USDT (Permit2) + - `TRON_ADDRESS` → TRON Nile (`tron:0xcd8690dc`), token USDT (Permit2) - A running batch-settlement facilitator (default `FACILITATOR_URL=http://localhost:4042`). ## Run diff --git a/examples/typescript/servers/batch-settlement/src/chains/tron.ts b/examples/typescript/servers/batch-settlement/src/chains/tron.ts index d9493460..81b6c1d8 100644 --- a/examples/typescript/servers/batch-settlement/src/chains/tron.ts +++ b/examples/typescript/servers/batch-settlement/src/chains/tron.ts @@ -5,7 +5,7 @@ * and runs a `BatchSettlementChannelManager` that claims + settles to `payTo`. * The `receiverAuthorizer` comes from the facilitator (`/supported`). * - * `tron:nile` USDT IS in the default-asset registry, so the channel manager is + * `tron:0xcd8690dc` USDT IS in the default-asset registry, so the channel manager is * built via `scheme.createChannelManager()` (it resolves the token) and the price * is given in `"$"` form (the scheme maps it to the default asset). USDT is a * Permit2 token (no ERC-3009), so the client deposits via Permit2 — the payer @@ -17,9 +17,9 @@ import type { x402ResourceServer } from "@bankofai/x402-express"; import type { StoppableManager } from "./evm.js"; -// Switch to "tron:mainnet" for production (REAL FUNDS): USDT is registered there +// Switch to "tron:0x2b6653dc" for production (REAL FUNDS): USDT is registered there // too — only the facilitator/client TronWeb `fullHost` must point at mainnet. -export const TRON_NETWORK: `${string}:${string}` = "tron:nile"; +export const TRON_NETWORK: `${string}:${string}` = "tron:0xcd8690dc"; /** TRON is enabled when a payout address is configured. */ export function hasTron(): boolean { diff --git a/examples/typescript/servers/express/README.md b/examples/typescript/servers/express/README.md index 2c1d86d7..22de6dc6 100644 --- a/examples/typescript/servers/express/README.md +++ b/examples/typescript/servers/express/README.md @@ -29,7 +29,7 @@ Then pay it with the fetch client (`../../clients/fetch`). | Chain | Network | Tokens advertised | payTo env | |---|---|---|---| | EVM | `eip155:97` (BSC testnet) | DHLU (eip3009), USDC (permit2) | `EVM_ADDRESS` | -| TRON | `tron:nile` | USDT, USDD (permit2) | `TRON_ADDRESS` | +| TRON | `tron:0xcd8690dc` | USDT, USDD (permit2) | `TRON_ADDRESS` | Tokens are configured per network in `src/chains/evm.ts` (`EVM_TOKENS`) and `src/chains/tron.ts`. BSC USDC needs a one-time Permit2 approve, advertised via diff --git a/examples/typescript/servers/express/src/chains/tron.ts b/examples/typescript/servers/express/src/chains/tron.ts index e43eb086..c65346a9 100644 --- a/examples/typescript/servers/express/src/chains/tron.ts +++ b/examples/typescript/servers/express/src/chains/tron.ts @@ -2,7 +2,7 @@ * TRON setup for the resource server — mirrors the EVM module. Keyless: just the * `exact` server scheme and `accepts` entries with the TRON payout address. * - * Offers both USDT and USDD on `tron:nile`. Both are permit2 tokens (no ERC-3009); + * Offers both USDT and USDD on `tron:0xcd8690dc`. Both are permit2 tokens (no ERC-3009); * the client's shipped auto-approve handles the one-time Permit2 `approve`. Prices * use the `" "` form so the TRON scheme resolves each token from * its registry (USDD is registered alongside USDT). @@ -10,10 +10,10 @@ import { ExactTronScheme } from "@bankofai/x402-tron/exact/server"; import type { x402ResourceServer } from "@bankofai/x402-express"; -// Switch to "tron:mainnet" for production (REAL FUNDS). USDT/USDD are registered +// Switch to "tron:0x2b6653dc" for production (REAL FUNDS). USDT/USDD are registered // for mainnet too (both permit2), so `tronAccepts()` works unchanged — only the // client/facilitator TronWeb `fullHost` must point at a mainnet node. -export const TRON_NETWORKS = ["tron:nile", "tron:mainnet"] as const; +export const TRON_NETWORKS = ["tron:0xcd8690dc", "tron:0x2b6653dc"] as const; /** TRON is enabled when a payout address is configured. */ export function hasTron(): boolean { diff --git a/examples/typescript/servers/gasfree/src/chains/tron.ts b/examples/typescript/servers/gasfree/src/chains/tron.ts index 24b50c91..f3d7b1ba 100644 --- a/examples/typescript/servers/gasfree/src/chains/tron.ts +++ b/examples/typescript/servers/gasfree/src/chains/tron.ts @@ -9,9 +9,9 @@ import { registerExactGasFreeTronScheme } from "@bankofai/x402-tron/gasfree/server"; import type { x402ResourceServer } from "@bankofai/x402-express"; -// Switch to "tron:mainnet" for production (REAL FUNDS); only the client and +// Switch to "tron:0x2b6653dc" for production (REAL FUNDS); only the client and // facilitator TronWeb/relayer endpoints change, this module is unchanged. -export const TRON_NETWORK: `${string}:${string}` = "tron:nile"; +export const TRON_NETWORK: `${string}:${string}` = "tron:0xcd8690dc"; /** TRON GasFree is enabled when a payout address is configured. */ export function hasTron(): boolean { diff --git a/examples/typescript/servers/mcp/README.md b/examples/typescript/servers/mcp/README.md index 7bccc27d..2766d584 100644 --- a/examples/typescript/servers/mcp/README.md +++ b/examples/typescript/servers/mcp/README.md @@ -1,7 +1,7 @@ # MCP server — dual-chain (BSC testnet + TRON Nile) An MCP server whose `get_weather` tool is gated behind x402 payment, accepting -**both** BSC testnet (`eip155:97`) and TRON Nile (`tron:nile`) at once. A 402 +**both** BSC testnet (`eip155:97`) and TRON Nile (`tron:0xcd8690dc`) at once. A 402 challenge offers every enabled chain; the client pays on whichever it supports. `ping` is free. diff --git a/examples/typescript/servers/mcp/src/chains/tron.ts b/examples/typescript/servers/mcp/src/chains/tron.ts index 86624811..3a4ee619 100644 --- a/examples/typescript/servers/mcp/src/chains/tron.ts +++ b/examples/typescript/servers/mcp/src/chains/tron.ts @@ -1,6 +1,6 @@ /** * TRON setup for the MCP resource server — mirrors the EVM module. Keyless: just - * the `exact` server scheme on `tron:nile` and `accepts` with the payout address. + * the `exact` server scheme on `tron:0xcd8690dc` and `accepts` with the payout address. * * Offers USDT and USDD (both permit2 tokens — no ERC-3009). The TRON client ships * an auto-approve that broadcasts the one-time Permit2 `approve`, so the server @@ -11,9 +11,9 @@ import { ExactTronScheme } from "@bankofai/x402-tron/exact/server"; import type { Network } from "@bankofai/x402-core/types"; import type { ResourceConfig, x402ResourceServer } from "@bankofai/x402-core/server"; -/** CAIP-2 network this server accepts TRON payments on. Switch to "tron:mainnet" +/** CAIP-2 network this server accepts TRON payments on. Switch to "tron:0x2b6653dc" * for production (REAL FUNDS); USDT/USDD are registered there too. */ -export const TRON_NETWORK: Network = "tron:nile"; +export const TRON_NETWORK: Network = "tron:0xcd8690dc"; /** TRON is enabled when a payout address is configured. */ export function hasTron(): boolean { @@ -21,7 +21,7 @@ export function hasTron(): boolean { } /** - * Registers the TRON `exact` server scheme on `tron:nile`. + * Registers the TRON `exact` server scheme on `tron:0xcd8690dc`. * * @param resourceServer - The resource server to register on. */ diff --git a/examples/typescript/servers/upto/README.md b/examples/typescript/servers/upto/README.md index c8e80d13..92fce0e0 100644 --- a/examples/typescript/servers/upto/README.md +++ b/examples/typescript/servers/upto/README.md @@ -14,7 +14,7 @@ over HTTP. - Set the payout address(es) you want to accept: - `EVM_ADDRESS` → BSC (`eip155:97`), token USDC (Permit2) - - `TRON_ADDRESS` → TRON Nile (`tron:nile`), token USDT (Permit2) + - `TRON_ADDRESS` → TRON Nile (`tron:0xcd8690dc`), token USDT (Permit2) - A running upto facilitator (default `FACILITATOR_URL=http://localhost:4052`). ## Run diff --git a/examples/typescript/servers/upto/src/chains/tron.ts b/examples/typescript/servers/upto/src/chains/tron.ts index 7b525c32..c57d2d29 100644 --- a/examples/typescript/servers/upto/src/chains/tron.ts +++ b/examples/typescript/servers/upto/src/chains/tron.ts @@ -5,16 +5,16 @@ * actual charge is decided per request in `index.ts` via a `Settlement-Overrides` * response header. * - * `tron:nile` USDT is in the default-asset registry, so the price is given in + * `tron:0xcd8690dc` USDT is in the default-asset registry, so the price is given in * `"$"` form (the scheme maps it to USDT). USDT is a **Permit2** token, so the * client authorizes via Permit2 — the payer needs a one-time `approve(Permit2)`. */ import { UptoTronScheme } from "@bankofai/x402-tron/upto/server"; import type { x402ResourceServer } from "@bankofai/x402-express"; -// Switch to "tron:mainnet" for production (REAL FUNDS): USDT is registered there +// Switch to "tron:0x2b6653dc" for production (REAL FUNDS): USDT is registered there // too — only the facilitator/client TronWeb `fullHost` must point at mainnet. -export const TRON_NETWORK: `${string}:${string}` = "tron:nile"; +export const TRON_NETWORK: `${string}:${string}` = "tron:0xcd8690dc"; /** TRON is enabled when a payout address is configured. */ export function hasTron(): boolean { diff --git a/typescript/packages/mechanisms/tron/README.md b/typescript/packages/mechanisms/tron/README.md index 0cb3bdd5..c082ce5e 100644 --- a/typescript/packages/mechanisms/tron/README.md +++ b/typescript/packages/mechanisms/tron/README.md @@ -121,7 +121,7 @@ registerExactTronScheme(server); // prices to the network's default stablecoin import { x402Facilitator } from "@bankofai/x402-core/facilitator"; import { registerExactTronScheme } from "@bankofai/x402-tron/exact/facilitator"; -registerExactTronScheme(facilitator, { signer: facilitatorSigner, networks: "tron:nile" }); +registerExactTronScheme(facilitator, { signer: facilitatorSigner, networks: "tron:0xcd8690dc" }); ``` ## Networks & on-chain dependencies @@ -130,9 +130,9 @@ The `permit2` path depends on three on-chain contracts. Addresses live in `src/c | Network | chainId (TIP-712) | Permit2 | x402ExactPermit2Proxy | | --- | --- | --- | --- | -| `tron:nile` | 3448148188 | `TYQuuhGbEMxF7nZxUHV3uHJxAVVAegNU9h` | `TFGoaq2KjizijgjtkVxT7yjffW1A5T1j6F` | -| `tron:mainnet` | 728126428 | *(placeholder — replace)* | *(placeholder — replace)* | -| `tron:shasta` | 2494104990 | — (no Permit2 deployment) | — | +| `tron:0xcd8690dc` | 3448148188 | `TYQuuhGbEMxF7nZxUHV3uHJxAVVAegNU9h` | `TFGoaq2KjizijgjtkVxT7yjffW1A5T1j6F` | +| `tron:0x2b6653dc` | 728126428 | *(placeholder — replace)* | *(placeholder — replace)* | +| `tron:0x94a9059e` | 2494104990 | — (no Permit2 deployment) | — | > ⚠️ **Before mainnet:** deploy your own audited Permit2 + `x402ExactPermit2Proxy` and replace the addresses in `constants.ts`. Do not reuse placeholder/testnet addresses. The proxy `PERMIT2()` immutable must equal the configured Permit2 address, and its `WITNESS_TYPEHASH` must match the 2-field witness. diff --git a/typescript/packages/mechanisms/tron/src/batch-settlement/client/voucher.ts b/typescript/packages/mechanisms/tron/src/batch-settlement/client/voucher.ts index aa22b80c..1a70122b 100644 --- a/typescript/packages/mechanisms/tron/src/batch-settlement/client/voucher.ts +++ b/typescript/packages/mechanisms/tron/src/batch-settlement/client/voucher.ts @@ -12,7 +12,7 @@ import { BatchSettlementVoucherFields } from "../types"; * @param signer - Client wallet used to produce the TIP-712 signature. * @param channelId - Identifier of the payment channel (see `computeChannelId`). * @param maxClaimableAmount - Cumulative ceiling the receiver may claim (decimal string). - * @param network - CAIP-2 network identifier (e.g. `"tron:nile"`). + * @param network - CAIP-2 network identifier (e.g. `"tron:0xcd8690dc"`). * @returns Signed voucher fields ready to be included in a payment payload. */ export async function signVoucher( diff --git a/typescript/packages/mechanisms/tron/src/batch-settlement/server/scheme.ts b/typescript/packages/mechanisms/tron/src/batch-settlement/server/scheme.ts index 16531eb8..166f0a34 100644 --- a/typescript/packages/mechanisms/tron/src/batch-settlement/server/scheme.ts +++ b/typescript/packages/mechanisms/tron/src/batch-settlement/server/scheme.ts @@ -347,7 +347,7 @@ export class BatchSettlementTronScheme implements SchemeNetworkServer { * receiver, default token for the given network, and the provided facilitator. * * @param facilitator - Facilitator client for submitting onchain claims/settlements. - * @param network - CAIP-2 network identifier (e.g. `"tron:nile"`). + * @param network - CAIP-2 network identifier (e.g. `"tron:0xcd8690dc"`). * @returns A ready-to-use channel manager. */ createChannelManager( diff --git a/typescript/packages/mechanisms/tron/src/constants.ts b/typescript/packages/mechanisms/tron/src/constants.ts index b93aa315..7d87725f 100644 --- a/typescript/packages/mechanisms/tron/src/constants.ts +++ b/typescript/packages/mechanisms/tron/src/constants.ts @@ -1,3 +1,14 @@ +// --- CAIP-2 network identifiers --- +// TRON uses hex chain IDs in the CAIP-2 reference (not human-readable names), +// per upstream spec PR x402-foundation/x402#2076 review feedback. + +/** TRON mainnet CAIP-2 id (chain id 0x2b6653dc). */ +export const TRON_MAINNET = "tron:0x2b6653dc"; +/** TRON Nile testnet CAIP-2 id (chain id 0xcd8690dc). */ +export const TRON_NILE = "tron:0xcd8690dc"; +/** TRON Shasta testnet CAIP-2 id (chain id 0x94a9059e). */ +export const TRON_SHASTA = "tron:0x94a9059e"; + // --- TIP-712 (TransferWithAuthorization) constants --- /** @@ -101,8 +112,8 @@ export const uptoPermit2WitnessTypes = { * Permit2 contract addresses per TRON network. */ export const PERMIT2_ADDRESSES: Record = { - "tron:mainnet": "TTJxU3P8rHycAyFY4kVtGNfmnMH4ezcuM9", - "tron:nile": "TYQuuhGbEMxF7nZxUHV3uHJxAVVAegNU9h", + "tron:0x2b6653dc": "TTJxU3P8rHycAyFY4kVtGNfmnMH4ezcuM9", + "tron:0xcd8690dc": "TYQuuhGbEMxF7nZxUHV3uHJxAVVAegNU9h", }; /** @@ -110,8 +121,8 @@ export const PERMIT2_ADDRESSES: Record = { * Enforces that Permit2 transfers can only go to the witness.to address. */ export const X402_PERMIT2_PROXY_ADDRESSES: Record = { - "tron:mainnet": "TN49yaJmZMZoEdDCqjB4uPzQLHvYkGw95m", - "tron:nile": "TFGoaq2KjizijgjtkVxT7yjffW1A5T1j6F", + "tron:0x2b6653dc": "TN49yaJmZMZoEdDCqjB4uPzQLHvYkGw95m", + "tron:0xcd8690dc": "TFGoaq2KjizijgjtkVxT7yjffW1A5T1j6F", }; /** @@ -119,8 +130,8 @@ export const X402_PERMIT2_PROXY_ADDRESSES: Record = { * Used by variable-amount settlement flows. */ export const X402_UPTO_PERMIT2_PROXY_ADDRESSES: Record = { - "tron:mainnet": "TBLeFPkfDiweBbYmAPqnakaFBPDt9p93sR", - "tron:nile": "TKvcqQ7S2bYyys5ZZNpjj9xGiPhiwzHq1K", + "tron:0x2b6653dc": "TBLeFPkfDiweBbYmAPqnakaFBPDt9p93sR", + "tron:0xcd8690dc": "TKvcqQ7S2bYyys5ZZNpjj9xGiPhiwzHq1K", }; /** @@ -246,9 +257,9 @@ export const erc20ApproveAbi = [ * TRON chain IDs for TIP-712 signing. */ export const TRON_CHAIN_IDS: Record = { - "tron:mainnet": 728126428, // 0x2b6653dc - "tron:shasta": 2494104990, // 0x94a9059e - "tron:nile": 3448148188, // 0xcd8690dc + "tron:0x2b6653dc": 728126428, // 0x2b6653dc + "tron:0x94a9059e": 2494104990, // 0x94a9059e + "tron:0xcd8690dc": 3448148188, // 0xcd8690dc }; /** diff --git a/typescript/packages/mechanisms/tron/src/exact/server/scheme.ts b/typescript/packages/mechanisms/tron/src/exact/server/scheme.ts index 69a031b1..13eef7f3 100644 --- a/typescript/packages/mechanisms/tron/src/exact/server/scheme.ts +++ b/typescript/packages/mechanisms/tron/src/exact/server/scheme.ts @@ -6,7 +6,11 @@ import { SchemeNetworkServer, MoneyParser, } from "@bankofai/x402-core/types"; -import { convertToTokenAmount, numberToDecimalString, parseMoneyString } from "@bankofai/x402-core/utils"; +import { + convertToTokenAmount, + numberToDecimalString, + parseMoneyString, +} from "@bankofai/x402-core/utils"; import { ExactDefaultAssetInfo, getDefaultAsset } from "../../shared/defaultAssets"; import { getDecimals, parsePrice as parseTokenPrice } from "../../shared/tokens"; import { buildFeeInfo, type ExactTronFeeConfig } from "../../shared/fee"; diff --git a/typescript/packages/mechanisms/tron/src/gasfree/client/scheme.ts b/typescript/packages/mechanisms/tron/src/gasfree/client/scheme.ts index 6a35a218..294d3f54 100644 --- a/typescript/packages/mechanisms/tron/src/gasfree/client/scheme.ts +++ b/typescript/packages/mechanisms/tron/src/gasfree/client/scheme.ts @@ -36,7 +36,7 @@ export interface ExactGasFreeSchemeOptions { * @returns The min/max deltas in seconds. */ function getDeadlineBounds(network: string): { minDelta: number; maxDelta: number } { - if (network === "tron:mainnet") { + if (network === "tron:0x2b6653dc") { return { minDelta: 55, maxDelta: 595 }; } return { minDelta: 55, maxDelta: 3595 }; diff --git a/typescript/packages/mechanisms/tron/src/index.ts b/typescript/packages/mechanisms/tron/src/index.ts index 5a03c2b4..2da61543 100644 --- a/typescript/packages/mechanisms/tron/src/index.ts +++ b/typescript/packages/mechanisms/tron/src/index.ts @@ -73,10 +73,7 @@ export { } from "./shared/tokens"; // Fee -export { - type FeeInfo, - type ExactTronFeeConfig, -} from "./shared/fee"; +export { type FeeInfo, type ExactTronFeeConfig } from "./shared/fee"; // Token selection + balance-aware selection export { diff --git a/typescript/packages/mechanisms/tron/src/rpc.ts b/typescript/packages/mechanisms/tron/src/rpc.ts index eb7bfe8e..5df7a95a 100644 --- a/typescript/packages/mechanisms/tron/src/rpc.ts +++ b/typescript/packages/mechanisms/tron/src/rpc.ts @@ -11,9 +11,9 @@ import { log } from "@bankofai/x402-core"; /** CAIP-2 network → default TronGrid fullHost (used when an API key is supplied). */ const TRON_RPC: Record = { - "tron:mainnet": "https://api.trongrid.io", - "tron:shasta": "https://api.shasta.trongrid.io", - "tron:nile": "https://nile.trongrid.io", + "tron:0x2b6653dc": "https://api.trongrid.io", + "tron:0x94a9059e": "https://api.shasta.trongrid.io", + "tron:0xcd8690dc": "https://nile.trongrid.io", }; /** @@ -24,11 +24,11 @@ const TRON_RPC: Record = { * the Python/legacy `TRON_FALLBACK_RPC_URLS` (commit 8a893b8). */ const TRON_FALLBACK_RPC: Record = { - "tron:mainnet": "https://hptg.bankofai.io", + "tron:0x2b6653dc": "https://hptg.bankofai.io", // nileex is the official Nile endpoint and works without a TronGrid key // (the default nile.trongrid.io host gets rate-limited unkeyed). - "tron:nile": "https://api.nileex.io", - "tron:shasta": "https://api.shasta.trongrid.io", + "tron:0xcd8690dc": "https://api.nileex.io", + "tron:0x94a9059e": "https://api.shasta.trongrid.io", }; /** Networks already warned about a missing API key (warn once per process). */ @@ -48,7 +48,7 @@ export interface BuildTronWebOptions { * Precedence: explicit `rpcUrl` → keyed TronGrid default (when `apiKey` is set) * → key-less fallback endpoint → TronGrid default. Exported for unit testing. * - * @param network - CAIP-2 id, e.g. `"tron:nile"`. + * @param network - CAIP-2 id, e.g. `"tron:0xcd8690dc"`. * @param opts - Optional RPC override / API key. * @returns The resolved fullHost. * @throws When the network is unknown and no `rpcUrl` is supplied. @@ -80,7 +80,7 @@ export function resolveTronRpcUrl(network: string, opts: BuildTronWebOptions = { /** * Builds a `TronWeb` for a CAIP-2 network (contract reads + broadcast). * - * @param network - CAIP-2 id, e.g. `"tron:nile"`. + * @param network - CAIP-2 id, e.g. `"tron:0xcd8690dc"`. * @param opts - Optional RPC override / API key. * @returns A TronWeb instance. */ diff --git a/typescript/packages/mechanisms/tron/src/shared/batch-settlement/authorizerSigner.ts b/typescript/packages/mechanisms/tron/src/shared/batch-settlement/authorizerSigner.ts index 37f14743..c7489596 100644 --- a/typescript/packages/mechanisms/tron/src/shared/batch-settlement/authorizerSigner.ts +++ b/typescript/packages/mechanisms/tron/src/shared/batch-settlement/authorizerSigner.ts @@ -13,7 +13,7 @@ import { computeChannelId, getBatchSettlementTip712Domain } from "./utils"; * * @param signer - Authorizer signer holding the `receiverAuthorizer` key. * @param claims - Voucher claims to include in the batch. - * @param network - CAIP-2 network identifier (e.g. `"tron:nile"`). + * @param network - CAIP-2 network identifier (e.g. `"tron:0xcd8690dc"`). * @returns TIP-712 signature over `ClaimBatch(ClaimEntry[] claims)`. */ export async function signClaimBatch( @@ -42,7 +42,7 @@ export async function signClaimBatch( * @param channelId - Channel to authorize refund for. * @param amount - Refund amount (capped to unclaimed escrow onchain). * @param nonce - Must match onchain `refundNonce(channelId)`. - * @param network - CAIP-2 network identifier (e.g. `"tron:nile"`). + * @param network - CAIP-2 network identifier (e.g. `"tron:0xcd8690dc"`). * @returns TIP-712 signature over `Refund(channelId, nonce, amount)`. */ export async function signRefund( diff --git a/typescript/packages/mechanisms/tron/src/shared/batch-settlement/constants.ts b/typescript/packages/mechanisms/tron/src/shared/batch-settlement/constants.ts index eafd3930..8b398f17 100644 --- a/typescript/packages/mechanisms/tron/src/shared/batch-settlement/constants.ts +++ b/typescript/packages/mechanisms/tron/src/shared/batch-settlement/constants.ts @@ -15,30 +15,30 @@ export const BATCH_SETTLEMENT_SCHEME = "batch-settlement" as const; * Deployed `x402BatchSettlement` contract addresses per TRON network (Base58Check). */ export const BATCH_SETTLEMENT_ADDRESSES: Record = { - "tron:mainnet": "TW9yNhTySkEHYfjnGQU2u4NAsdb1tW4fbm", - "tron:nile": "TWBwWHZWwH8TzrZnbxit1J645VGYY1K2fA", + "tron:0x2b6653dc": "TW9yNhTySkEHYfjnGQU2u4NAsdb1tW4fbm", + "tron:0xcd8690dc": "TWBwWHZWwH8TzrZnbxit1J645VGYY1K2fA", }; /** * Deployed `ERC3009DepositCollector` contract addresses per TRON network. */ export const ERC3009_DEPOSIT_COLLECTOR_ADDRESSES: Record = { - "tron:mainnet": "TTWA7aWMdx4jfcbp8XRAS2JAd2sUhyF9qj", - "tron:nile": "TJUQ3BQt4YFg8EeevjiUa5LbfSGz5BxzRW", + "tron:0x2b6653dc": "TTWA7aWMdx4jfcbp8XRAS2JAd2sUhyF9qj", + "tron:0xcd8690dc": "TJUQ3BQt4YFg8EeevjiUa5LbfSGz5BxzRW", }; /** * Deployed `Permit2DepositCollector` contract addresses per TRON network. */ export const PERMIT2_DEPOSIT_COLLECTOR_ADDRESSES: Record = { - "tron:mainnet": "TAg5qqp1K9x5KeSTWnRa8LT79B5HUjzSHY", - "tron:nile": "TEp6bCqSEKAr99sCiqANC84RtRwx7xGbA4", + "tron:0x2b6653dc": "TAg5qqp1K9x5KeSTWnRa8LT79B5HUjzSHY", + "tron:0xcd8690dc": "TEp6bCqSEKAr99sCiqANC84RtRwx7xGbA4", }; /** * Resolve the `x402BatchSettlement` address for a network. * - * @param network - CAIP-2 network identifier (e.g. `"tron:nile"`). + * @param network - CAIP-2 network identifier (e.g. `"tron:0xcd8690dc"`). * @returns The Base58Check contract address. * @throws When no contract is configured for the network. */ diff --git a/typescript/packages/mechanisms/tron/src/shared/batch-settlement/utils.ts b/typescript/packages/mechanisms/tron/src/shared/batch-settlement/utils.ts index 254d4d13..aeb3c616 100644 --- a/typescript/packages/mechanisms/tron/src/shared/batch-settlement/utils.ts +++ b/typescript/packages/mechanisms/tron/src/shared/batch-settlement/utils.ts @@ -45,7 +45,7 @@ export function hashTypedData( /** * Returns the full TIP-712 domain for the batch-settlement contract on a network. * - * @param network - CAIP-2 network identifier (e.g. `"tron:nile"`). + * @param network - CAIP-2 network identifier (e.g. `"tron:0xcd8690dc"`). * @returns Domain with `name`, `version`, `chainId`, and EVM-hex `verifyingContract`. */ export function getBatchSettlementTip712Domain(network: string): Eip712Domain { diff --git a/typescript/packages/mechanisms/tron/src/shared/defaultAssets.ts b/typescript/packages/mechanisms/tron/src/shared/defaultAssets.ts index 9bc7c33c..c6882bea 100644 --- a/typescript/packages/mechanisms/tron/src/shared/defaultAssets.ts +++ b/typescript/packages/mechanisms/tron/src/shared/defaultAssets.ts @@ -66,7 +66,7 @@ function toExactAssetInfo(token: TokenInfo): ExactDefaultAssetInfo { * * Resolves the network's default symbol (USDT) against the token registry. * - * @param network - The CAIP-2 network identifier (e.g., "tron:nile"). + * @param network - The CAIP-2 network identifier (e.g., "tron:0xcd8690dc"). * @returns The default asset configuration for the network. * @throws Error if no default asset is configured for the network. */ diff --git a/typescript/packages/mechanisms/tron/src/shared/gasfree/config.ts b/typescript/packages/mechanisms/tron/src/shared/gasfree/config.ts index e7a269a5..84f168d8 100644 --- a/typescript/packages/mechanisms/tron/src/shared/gasfree/config.ts +++ b/typescript/packages/mechanisms/tron/src/shared/gasfree/config.ts @@ -12,16 +12,16 @@ import { getTronChainId, tronAddressToEvm } from "../../utils"; /** GasFreeController contract addresses (Base58Check) per network. */ export const GASFREE_CONTROLLER_ADDRESSES: Record = { - "tron:mainnet": "TFFAMQLZybALaLb4uxHA9RBE7pxhUAjF3U", - "tron:shasta": "TQghdCeVDA6CnuNVTUhfaAyPfTetqZWNpm", - "tron:nile": "THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc", + "tron:0x2b6653dc": "TFFAMQLZybALaLb4uxHA9RBE7pxhUAjF3U", + "tron:0x94a9059e": "TQghdCeVDA6CnuNVTUhfaAyPfTetqZWNpm", + "tron:0xcd8690dc": "THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc", }; /** GasFree beacon contract addresses (Base58Check) per network. */ export const GASFREE_BEACON_ADDRESSES: Record = { - "tron:mainnet": "TSP9UW6FQhT76XD2jWA6ipGMx3yGbjDffP", - "tron:shasta": "TQ1jvA3nLDMDNbJoMPLzTPoqAg8NvZ5CCW", - "tron:nile": "TLtCGmaxH3PbuaF6kbybwteZcHptEdgQGC", + "tron:0x2b6653dc": "TSP9UW6FQhT76XD2jWA6ipGMx3yGbjDffP", + "tron:0x94a9059e": "TQ1jvA3nLDMDNbJoMPLzTPoqAg8NvZ5CCW", + "tron:0xcd8690dc": "TLtCGmaxH3PbuaF6kbybwteZcHptEdgQGC", }; /** @@ -35,9 +35,9 @@ export const GASFREE_BEACON_ADDRESSES: Record = { * client / registration config. */ export const GASFREE_API_BASE_URLS: Record = { - "tron:mainnet": "https://facilitator.bankofai.io/mainnet", - "tron:shasta": "https://facilitator.bankofai.io/shasta", - "tron:nile": "https://facilitator.bankofai.io/nile", + "tron:0x2b6653dc": "https://facilitator.bankofai.io/mainnet", + "tron:0x94a9059e": "https://facilitator.bankofai.io/shasta", + "tron:0xcd8690dc": "https://facilitator.bankofai.io/nile", }; /** diff --git a/typescript/packages/mechanisms/tron/src/shared/tokens.ts b/typescript/packages/mechanisms/tron/src/shared/tokens.ts index 71200cd9..96528fd3 100644 --- a/typescript/packages/mechanisms/tron/src/shared/tokens.ts +++ b/typescript/packages/mechanisms/tron/src/shared/tokens.ts @@ -37,13 +37,13 @@ export interface TokenInfo { /** * Built-in TRC-20 tokens indexed by CAIP-2 network and uppercased symbol. * - * Note: `tron:mainnet` and `tron:nile` have Permit2 + x402Permit2Proxy - * deployments, so their tokens default to `permit2`. `tron:shasta` has no + * Note: `tron:0x2b6653dc` and `tron:0xcd8690dc` have Permit2 + x402Permit2Proxy + * deployments, so their tokens default to `permit2`. `tron:0x94a9059e` has no * Permit2 deployment, so USDT there falls back to the TIP-712 * TransferWithAuthorization (`eip3009`) path. */ const TOKENS: Record> = { - "tron:mainnet": { + "tron:0x2b6653dc": { USDT: { address: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", decimals: 6, @@ -61,7 +61,7 @@ const TOKENS: Record> = { assetTransferMethod: "permit2", }, }, - "tron:nile": { + "tron:0xcd8690dc": { USDT: { address: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", decimals: 6, @@ -79,7 +79,7 @@ const TOKENS: Record> = { assetTransferMethod: "permit2", }, }, - "tron:shasta": { + "tron:0x94a9059e": { USDT: { address: "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs", decimals: 6, @@ -107,7 +107,7 @@ export function getDefaultAssetSymbol(): string { /** * Get token info by network and symbol (case-insensitive). * - * @param network - CAIP-2 network identifier (e.g. "tron:nile"). + * @param network - CAIP-2 network identifier (e.g. "tron:0xcd8690dc"). * @param symbol - Token symbol (e.g. "USDT"); matched case-insensitively. * @returns The token info, or undefined if not registered. */ @@ -189,7 +189,7 @@ export function buildAssetExtra(token: TokenInfo): Record { * * @param price - `" "` (e.g. `"1.25 USDT"`). * Whitespace-tolerant; symbol lookup is case-insensitive. - * @param network - CAIP-2 network identifier (e.g. `"tron:nile"`). + * @param network - CAIP-2 network identifier (e.g. `"tron:0xcd8690dc"`). * @returns The asset amount in smallest units, with token metadata in `extra`. * @throws If the format is invalid, the amount is not a non-negative decimal, * the token is not registered, or the amount has more decimal places diff --git a/typescript/packages/mechanisms/tron/src/signer.ts b/typescript/packages/mechanisms/tron/src/signer.ts index 0c97c9f9..93b5c52b 100644 --- a/typescript/packages/mechanisms/tron/src/signer.ts +++ b/typescript/packages/mechanisms/tron/src/signer.ts @@ -214,7 +214,7 @@ export function toFacilitatorTronSigner( /** Options for {@link createClientTronSigner}. */ export interface CreateClientTronSignerOptions { - /** CAIP-2 network, e.g. `"tron:nile"`. The TronWeb client is built from it. */ + /** CAIP-2 network, e.g. `"tron:0xcd8690dc"`. The TronWeb client is built from it. */ network: string; /** RPC fullHost override; falls back to the network's default. */ rpcUrl?: string; @@ -245,7 +245,7 @@ export interface CreateClientTronSignerOptions { * * @example * ```typescript - * const signer = await createClientTronSigner(wallet, { network: "tron:nile" }); + * const signer = await createClientTronSigner(wallet, { network: "tron:0xcd8690dc" }); * client.register("tron:*", new ExactTronScheme(signer)); * ``` */ @@ -337,7 +337,7 @@ export type FacilitatorTronWallet = FacilitatorWallet; /** Options for {@link createFacilitatorTronSigner}. */ export interface FacilitatorTronSignerOptions { - /** CAIP-2 network, e.g. `"tron:nile"`. The TronWeb client is built from it. */ + /** CAIP-2 network, e.g. `"tron:0xcd8690dc"`. The TronWeb client is built from it. */ network: string; /** RPC fullHost override; falls back to the network's default. */ rpcUrl?: string; @@ -583,9 +583,11 @@ async function pollTransactionPacked(tronWeb: TronWeb, hash: string): Promise<{ await new Promise(resolve => setTimeout(resolve, delayMs)); let info: TronTxInfo | null = null; try { - info = (await tronWeb.fullNode.request("wallet/gettransactioninfobyid", { value: hash }, "post")) as - | TronTxInfo - | null; + info = (await tronWeb.fullNode.request( + "wallet/gettransactioninfobyid", + { value: hash }, + "post", + )) as TronTxInfo | null; } catch { // Not yet confirmed / transient node or rate-limit error — keep polling. } @@ -706,8 +708,8 @@ async function ensurePermit2Allowance( * * @example * ```typescript - * const signer = await createFacilitatorTronSigner(wallet, { network: "tron:nile" }); - * facilitator.register("tron:nile", new ExactTronScheme(signer)); + * const signer = await createFacilitatorTronSigner(wallet, { network: "tron:0xcd8690dc" }); + * facilitator.register("tron:0xcd8690dc", new ExactTronScheme(signer)); * ``` */ export async function createFacilitatorTronSigner( diff --git a/typescript/packages/mechanisms/tron/src/upto/server/scheme.ts b/typescript/packages/mechanisms/tron/src/upto/server/scheme.ts index db9b8672..cc9868fa 100644 --- a/typescript/packages/mechanisms/tron/src/upto/server/scheme.ts +++ b/typescript/packages/mechanisms/tron/src/upto/server/scheme.ts @@ -6,7 +6,11 @@ import { SchemeNetworkServer, MoneyParser, } from "@bankofai/x402-core/types"; -import { convertToTokenAmount, numberToDecimalString, parseMoneyString } from "@bankofai/x402-core/utils"; +import { + convertToTokenAmount, + numberToDecimalString, + parseMoneyString, +} from "@bankofai/x402-core/utils"; import { ExactDefaultAssetInfo, getDefaultAsset } from "../../shared/defaultAssets"; import { getDecimals, parsePrice as parseTokenPrice } from "../../shared/tokens"; import { buildFeeInfo, type ExactTronFeeConfig } from "../../shared/fee"; diff --git a/typescript/packages/mechanisms/tron/src/utils.ts b/typescript/packages/mechanisms/tron/src/utils.ts index 18f4a37b..dc9686dd 100644 --- a/typescript/packages/mechanisms/tron/src/utils.ts +++ b/typescript/packages/mechanisms/tron/src/utils.ts @@ -4,7 +4,7 @@ import { TRON_CHAIN_IDS } from "./constants"; /** * Get the numeric chain ID for a TRON network identifier. * - * @param network - The network identifier in CAIP-2 format (e.g., "tron:nile") + * @param network - The network identifier in CAIP-2 format (e.g., "tron:0xcd8690dc") * @returns The numeric chain ID * @throws Error if the network is not a recognized TRON network */ diff --git a/typescript/packages/mechanisms/tron/test/unit/batch-refund-network.test.ts b/typescript/packages/mechanisms/tron/test/unit/batch-refund-network.test.ts index 6ff472e4..ebb8f9db 100644 --- a/typescript/packages/mechanisms/tron/test/unit/batch-refund-network.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/batch-refund-network.test.ts @@ -14,7 +14,7 @@ import type { PaymentRequired, PaymentRequirements } from "@bankofai/x402-core/t * * We drive scheme.refund() with a mocked 402 whose accepts list an EVM option * FIRST, and a signer whose readContract throws a sentinel. Reaching the sentinel - * proves the TRON requirement was selected (computeChannelId(tron:nile) ran and + * proves the TRON requirement was selected (computeChannelId(tron:0xcd8690dc) ran and * the flow got to the on-chain channel read); a regression would throw the * eip155 network error before that. */ @@ -40,7 +40,7 @@ function evmAccept(): PaymentRequirements { function tronAccept(): PaymentRequirements { return { scheme: "batch-settlement", - network: "tron:nile", + network: "tron:0xcd8690dc", asset: TRON_ASSET, amount: "1000000", payTo: TRON_PAYTO, @@ -75,7 +75,7 @@ describe("TRON batch-settlement refund — multi-network route", () => { const scheme = new BatchSettlementTronScheme(mockSigner()); const fetchImpl = vi.fn().mockResolvedValue(multiNetwork402()); - // Reaching the on-chain read (sentinel) proves computeChannelId(tron:nile) + // Reaching the on-chain read (sentinel) proves computeChannelId(tron:0xcd8690dc) // ran. A regression would throw "Unsupported network format: eip155:97". await expect(scheme.refund(URL, { fetch: fetchImpl })).rejects.toThrow("READCONTRACT_REACHED"); }); diff --git a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/deposit-sig.test.ts b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/deposit-sig.test.ts index ca81e269..786a6919 100644 --- a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/deposit-sig.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/deposit-sig.test.ts @@ -32,7 +32,7 @@ import type { * and the channel-bound Permit2 `DepositWitness`. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; const ASSET = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"; const PAY_TO = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; @@ -80,7 +80,9 @@ describe("batch-settlement deposit authorizations (TRON)", () => { beforeAll(async () => { const tronWeb = new TronWeb({ fullHost: "https://nile.trongrid.io", privateKey: PAYER_PK }); vi.mocked(buildTronWeb).mockReturnValue(tronWeb); - signer = await createClientTronSigner(privateKeyTronWallet(tronWeb, PAYER_PK), { network: NETWORK }); + signer = await createClientTronSigner(privateKeyTronWallet(tronWeb, PAYER_PK), { + network: NETWORK, + }); payerHex = tronAddressToEvm(signer.address); config = { payer: normalizeAddressForSigning(signer.address), diff --git a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/digest.test.ts b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/digest.test.ts index 450745bc..07231aae 100644 --- a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/digest.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/digest.test.ts @@ -25,7 +25,7 @@ import type { FacilitatorTronSigner } from "../../../src/signer"; * contract), and (2) a client-signed voucher verifies via the facilitator path. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; // Read on-chain from the deployed Nile contract (CHANNEL_CONFIG_TYPEHASH()). @@ -69,7 +69,9 @@ describe("batch-settlement digest (TRON)", () => { beforeAll(async () => { const tronWeb = new TronWeb({ fullHost: "https://nile.trongrid.io", privateKey: PAYER_PK }); vi.mocked(buildTronWeb).mockReturnValue(tronWeb); - signer = await createClientTronSigner(privateKeyTronWallet(tronWeb, PAYER_PK), { network: NETWORK }); + signer = await createClientTronSigner(privateKeyTronWallet(tronWeb, PAYER_PK), { + network: NETWORK, + }); config = { payer: normalizeAddressForSigning(signer.address), payerAuthorizer: normalizeAddressForSigning(signer.address), diff --git a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/lifecycle.test.ts b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/lifecycle.test.ts index bae24d1d..704bf4bd 100644 --- a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/lifecycle.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/lifecycle.test.ts @@ -18,7 +18,7 @@ import type { PaymentRequirements } from "@bankofai/x402-core/types"; * and how the cumulative voucher ceiling advances across charges. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; const PAY_TO = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; diff --git a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/server-hooks.test.ts b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/server-hooks.test.ts index 40847559..fdce7d2f 100644 --- a/typescript/packages/mechanisms/tron/test/unit/batch-settlement/server-hooks.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/batch-settlement/server-hooks.test.ts @@ -29,7 +29,7 @@ import * as Errors from "../../../src/batch-settlement/errors"; * These are pure logic over an in-memory channel store; no chain access. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; const RECEIVER = "0x9876543210987654321098765432109876543210"; const RECEIVER_AUTHORIZER = "0x1111111111111111111111111111111111111111"; diff --git a/typescript/packages/mechanisms/tron/test/unit/client-allowance.test.ts b/typescript/packages/mechanisms/tron/test/unit/client-allowance.test.ts index c524105c..4ab80330 100644 --- a/typescript/packages/mechanisms/tron/test/unit/client-allowance.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/client-allowance.test.ts @@ -20,7 +20,7 @@ vi.mock("../../src/rpc", () => ({ buildTronWeb: vi.fn() })); * reads the allowance and broadcasts that approve when (and only when) needed. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const OWNER = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; const TOKEN = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"; // nile USDT const PERMIT2 = PERMIT2_ADDRESSES[NETWORK]!; diff --git a/typescript/packages/mechanisms/tron/test/unit/facilitator-wallet.test.ts b/typescript/packages/mechanisms/tron/test/unit/facilitator-wallet.test.ts index bb775621..2b812a87 100644 --- a/typescript/packages/mechanisms/tron/test/unit/facilitator-wallet.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/facilitator-wallet.test.ts @@ -14,7 +14,7 @@ vi.mock("../../src/rpc", () => ({ buildTronWeb: vi.fn() })); * from our ABI and pinned here to the known-correct canonical string. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const FAC_ADDR = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; const PROXY = "TFGoaq2KjizijgjtkVxT7yjffW1A5T1j6F"; const TOKEN = "0x" + "a".repeat(40); diff --git a/typescript/packages/mechanisms/tron/test/unit/fee-plumbing.test.ts b/typescript/packages/mechanisms/tron/test/unit/fee-plumbing.test.ts index f960f42c..1f99fe97 100644 --- a/typescript/packages/mechanisms/tron/test/unit/fee-plumbing.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/fee-plumbing.test.ts @@ -9,7 +9,7 @@ import type { PaymentRequirements } from "@bankofai/x402-core/types"; * server's enhancePaymentRequirements turns it into per-asset extra.fee (F3). */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const USDT = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"; const USDD = "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK"; const SIGNER_ADDR = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; diff --git a/typescript/packages/mechanisms/tron/test/unit/fee.test.ts b/typescript/packages/mechanisms/tron/test/unit/fee.test.ts index cc7a5791..a4ce9c60 100644 --- a/typescript/packages/mechanisms/tron/test/unit/fee.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/fee.test.ts @@ -16,7 +16,7 @@ import { * Offline unit tests for the TRON facilitator fee layer (F3). */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const USDT = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"; const USDD = "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK"; const FEE_TO = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; diff --git a/typescript/packages/mechanisms/tron/test/unit/flow-integration.test.ts b/typescript/packages/mechanisms/tron/test/unit/flow-integration.test.ts index b81ff545..9570e2ca 100644 --- a/typescript/packages/mechanisms/tron/test/unit/flow-integration.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/flow-integration.test.ts @@ -34,7 +34,7 @@ vi.mock("../../src/rpc", () => ({ buildTronWeb: vi.fn() })); * stubbed, keeping the suite offline and deterministic. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const USDT = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"; const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; const FAC_PK = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"; diff --git a/typescript/packages/mechanisms/tron/test/unit/gasfree-digest.test.ts b/typescript/packages/mechanisms/tron/test/unit/gasfree-digest.test.ts index 51699df7..9c7ec222 100644 --- a/typescript/packages/mechanisms/tron/test/unit/gasfree-digest.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/gasfree-digest.test.ts @@ -20,7 +20,7 @@ import type { GasFreeAddressInfo, GasFreeProvider } from "../../src/shared/gasfr * verification fails here before any real submission. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; const FACIL_PK = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"; const PAY_TO = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; diff --git a/typescript/packages/mechanisms/tron/test/unit/gasfree-feeto.test.ts b/typescript/packages/mechanisms/tron/test/unit/gasfree-feeto.test.ts index 0cce0986..e0e4083d 100644 --- a/typescript/packages/mechanisms/tron/test/unit/gasfree-feeto.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/gasfree-feeto.test.ts @@ -14,7 +14,7 @@ import type { FacilitatorTronSigner } from "../../src/signer"; * provider list (mirroring the Python facilitator's `fee_quote`). */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const SIGNER_ADDR = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; // facilitator wallet (NOT a provider) const PROVIDER = "TKtWbdzEq5ss9vTS9kwRhBp5mXmBfBns3E"; // a registered relayer provider diff --git a/typescript/packages/mechanisms/tron/test/unit/gasfree-flow.test.ts b/typescript/packages/mechanisms/tron/test/unit/gasfree-flow.test.ts index 928a4307..04a8de76 100644 --- a/typescript/packages/mechanisms/tron/test/unit/gasfree-flow.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/gasfree-flow.test.ts @@ -13,7 +13,7 @@ import type { GasFreeAddressInfo, GasFreeProvider } from "../../src/shared/gasfr */ const addr = (pk: string) => TronWeb.address.fromPrivateKey(pk) as string; -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const USER = addr("0000000000000000000000000000000000000000000000000000000000000001"); const PAY_TO = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; const ASSET = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"; // Nile USDT (6 decimals) @@ -176,7 +176,7 @@ describe("GasFree client createPaymentPayload", () => { extensions: { skipBalanceCheck: true }, }); const p = result.payload as ExactGasFreePayload; - // tron:nile max window = 3595s + // tron:0xcd8690dc max window = 3595s const deadline = Number(p.gasfree.deadline); expect(deadline).toBeGreaterThanOrEqual(before + 3590); expect(deadline).toBeLessThanOrEqual(before + 3595 + 2); diff --git a/typescript/packages/mechanisms/tron/test/unit/permit2-digest.test.ts b/typescript/packages/mechanisms/tron/test/unit/permit2-digest.test.ts index e2f51b13..8914dfa9 100644 --- a/typescript/packages/mechanisms/tron/test/unit/permit2-digest.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/permit2-digest.test.ts @@ -24,7 +24,7 @@ import type { ExactPermit2Payload } from "../../src/types"; * contract, these assertions fail before any gas is spent. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; // Fixed test key → deterministic payer address (no network, no randomness). const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; const PAY_TO = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; diff --git a/typescript/packages/mechanisms/tron/test/unit/rpc.test.ts b/typescript/packages/mechanisms/tron/test/unit/rpc.test.ts index 29f4b3cf..a33c101d 100644 --- a/typescript/packages/mechanisms/tron/test/unit/rpc.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/rpc.test.ts @@ -11,24 +11,24 @@ import { resolveTronRpcUrl } from "../../src/rpc"; describe("resolveTronRpcUrl", () => { it("uses an explicit rpcUrl override above everything else", () => { - expect(resolveTronRpcUrl("tron:nile", { rpcUrl: "https://my.host", apiKey: "k" })).toBe( + expect(resolveTronRpcUrl("tron:0xcd8690dc", { rpcUrl: "https://my.host", apiKey: "k" })).toBe( "https://my.host", ); }); it("uses the keyed TronGrid default when an API key is supplied", () => { - expect(resolveTronRpcUrl("tron:nile", { apiKey: "k" })).toBe("https://nile.trongrid.io"); - expect(resolveTronRpcUrl("tron:mainnet", { apiKey: "k" })).toBe("https://api.trongrid.io"); + expect(resolveTronRpcUrl("tron:0xcd8690dc", { apiKey: "k" })).toBe("https://nile.trongrid.io"); + expect(resolveTronRpcUrl("tron:0x2b6653dc", { apiKey: "k" })).toBe("https://api.trongrid.io"); }); it("uses the key-less fallback for nile when no API key is set", () => { // nile.trongrid.io rate-limits unkeyed; nileex works key-less. - expect(resolveTronRpcUrl("tron:nile")).toBe("https://api.nileex.io"); + expect(resolveTronRpcUrl("tron:0xcd8690dc")).toBe("https://api.nileex.io"); }); it("uses the key-less fallback for mainnet/shasta when no API key is set", () => { - expect(resolveTronRpcUrl("tron:mainnet")).toBe("https://hptg.bankofai.io"); - expect(resolveTronRpcUrl("tron:shasta")).toBe("https://api.shasta.trongrid.io"); + expect(resolveTronRpcUrl("tron:0x2b6653dc")).toBe("https://hptg.bankofai.io"); + expect(resolveTronRpcUrl("tron:0x94a9059e")).toBe("https://api.shasta.trongrid.io"); }); it("throws for an unknown network with no rpcUrl", () => { diff --git a/typescript/packages/mechanisms/tron/test/unit/selection.test.ts b/typescript/packages/mechanisms/tron/test/unit/selection.test.ts index 1f4efa7b..0203ad51 100644 --- a/typescript/packages/mechanisms/tron/test/unit/selection.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/selection.test.ts @@ -15,7 +15,7 @@ import { * No core changes: selection is a sync selector, affordability is async helpers. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const USDT = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"; // 6 decimals const USDD = "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK"; // 18 decimals diff --git a/typescript/packages/mechanisms/tron/test/unit/server.moneyConversion.test.ts b/typescript/packages/mechanisms/tron/test/unit/server.moneyConversion.test.ts index dfe6fd62..b33345dd 100644 --- a/typescript/packages/mechanisms/tron/test/unit/server.moneyConversion.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/server.moneyConversion.test.ts @@ -2,8 +2,8 @@ import { describe, it, expect } from "vitest"; import { ExactTronScheme } from "../../src/exact/server/scheme"; import { UptoTronScheme } from "../../src/upto/server/scheme"; -// tron:nile USDT is 6 decimals -const NILE = "tron:nile"; +// tron:0xcd8690dc USDT is 6 decimals +const NILE = "tron:0xcd8690dc"; describe("ExactTronScheme (Server) - money conversion", () => { const server = new ExactTronScheme(); diff --git a/typescript/packages/mechanisms/tron/test/unit/signer-wallet.test.ts b/typescript/packages/mechanisms/tron/test/unit/signer-wallet.test.ts index 16dd5159..8b361287 100644 --- a/typescript/packages/mechanisms/tron/test/unit/signer-wallet.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/signer-wallet.test.ts @@ -37,7 +37,7 @@ function tron(): TronWeb { /** Build a client signer with the given TronWeb routed through the mocked builder. */ async function makeClient(tw: TronWeb, wallet: ClientTronWallet) { vi.mocked(buildTronWeb).mockReturnValue(tw); - return createClientTronSigner(wallet, { network: "tron:nile" }); + return createClientTronSigner(wallet, { network: "tron:0xcd8690dc" }); } describe("privateKeyTronWallet", () => { diff --git a/typescript/packages/mechanisms/tron/test/unit/tokens.test.ts b/typescript/packages/mechanisms/tron/test/unit/tokens.test.ts index 2adb8c1d..07ffdb53 100644 --- a/typescript/packages/mechanisms/tron/test/unit/tokens.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/tokens.test.ts @@ -21,54 +21,54 @@ const USDD_NILE = "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK"; describe("token registry lookups", () => { it("resolves tokens by symbol case-insensitively", () => { - expect(getToken("tron:nile", "usdt")?.address).toBe(USDT_NILE); - expect(getToken("tron:nile", "USDT")?.decimals).toBe(6); - expect(getToken("tron:nile", "USDD")?.decimals).toBe(18); + expect(getToken("tron:0xcd8690dc", "usdt")?.address).toBe(USDT_NILE); + expect(getToken("tron:0xcd8690dc", "USDT")?.decimals).toBe(6); + expect(getToken("tron:0xcd8690dc", "USDD")?.decimals).toBe(18); }); it("resolves tokens by address case-insensitively", () => { - expect(findByAddress("tron:nile", USDT_NILE.toLowerCase())?.symbol).toBe("USDT"); - expect(findByAddress("tron:nile", USDD_NILE)?.symbol).toBe("USDD"); + expect(findByAddress("tron:0xcd8690dc", USDT_NILE.toLowerCase())?.symbol).toBe("USDT"); + expect(findByAddress("tron:0xcd8690dc", USDD_NILE)?.symbol).toBe("USDD"); }); it("returns undefined for unknown network/token", () => { expect(getToken("tron:unknown", "USDT")).toBeUndefined(); - expect(findByAddress("tron:nile", "TNotARealAddress")).toBeUndefined(); + expect(findByAddress("tron:0xcd8690dc", "TNotARealAddress")).toBeUndefined(); }); it("lists all tokens for a network", () => { - const tokens = getNetworkTokens("tron:nile"); + const tokens = getNetworkTokens("tron:0xcd8690dc"); expect(Object.keys(tokens).sort()).toEqual(["USDD", "USDT"]); expect(getNetworkTokens("tron:unknown")).toEqual({}); }); it("mainnet and nile USDT default to permit2, shasta USDT does not", () => { - expect(getToken("tron:mainnet", "USDT")?.assetTransferMethod).toBe("permit2"); - expect(getToken("tron:nile", "USDT")?.assetTransferMethod).toBe("permit2"); - expect(getToken("tron:shasta", "USDT")?.assetTransferMethod).toBeUndefined(); + expect(getToken("tron:0x2b6653dc", "USDT")?.assetTransferMethod).toBe("permit2"); + expect(getToken("tron:0xcd8690dc", "USDT")?.assetTransferMethod).toBe("permit2"); + expect(getToken("tron:0x94a9059e", "USDT")?.assetTransferMethod).toBeUndefined(); }); }); describe("getDecimals", () => { it("returns token decimals when registered", () => { - expect(getDecimals("tron:nile", USDT_NILE)).toBe(6); - expect(getDecimals("tron:nile", USDD_NILE)).toBe(18); + expect(getDecimals("tron:0xcd8690dc", USDT_NILE)).toBe(6); + expect(getDecimals("tron:0xcd8690dc", USDD_NILE)).toBe(18); }); it("falls back to 6 for unknown assets", () => { - expect(getDecimals("tron:nile", "TUnknown")).toBe(6); + expect(getDecimals("tron:0xcd8690dc", "TUnknown")).toBe(6); }); }); describe("buildAssetExtra", () => { it("omits name/version for plain permit2 tokens but keeps assetTransferMethod", () => { - const usdt = getToken("tron:nile", "USDT")!; + const usdt = getToken("tron:0xcd8690dc", "USDT")!; const extra = buildAssetExtra(usdt); expect(extra).toEqual({ assetTransferMethod: "permit2" }); }); it("includes name/version for eip3009 tokens (no transfer method)", () => { - const shasta = getToken("tron:shasta", "USDT")!; + const shasta = getToken("tron:0x94a9059e", "USDT")!; const extra = buildAssetExtra(shasta); expect(extra).toEqual({ name: "Tether USD", version: "1" }); }); @@ -93,47 +93,47 @@ describe("buildAssetExtra", () => { describe("parsePrice", () => { it("converts whole and fractional amounts to smallest units", () => { - expect(parsePrice("1 USDT", "tron:nile")).toEqual({ + expect(parsePrice("1 USDT", "tron:0xcd8690dc")).toEqual({ asset: USDT_NILE, amount: "1000000", extra: { assetTransferMethod: "permit2" }, }); - expect(parsePrice("1.25 USDT", "tron:nile").amount).toBe("1250000"); - expect(parsePrice("0.000001 USDT", "tron:nile").amount).toBe("1"); + expect(parsePrice("1.25 USDT", "tron:0xcd8690dc").amount).toBe("1250000"); + expect(parsePrice("0.000001 USDT", "tron:0xcd8690dc").amount).toBe("1"); }); it("handles 18-decimal tokens with BigInt-safe conversion", () => { - expect(parsePrice("1 USDD", "tron:nile").amount).toBe("1000000000000000000"); - expect(parsePrice("0.5 USDD", "tron:nile").amount).toBe("500000000000000000"); + expect(parsePrice("1 USDD", "tron:0xcd8690dc").amount).toBe("1000000000000000000"); + expect(parsePrice("0.5 USDD", "tron:0xcd8690dc").amount).toBe("500000000000000000"); }); it("is whitespace-tolerant and symbol case-insensitive", () => { - expect(parsePrice(" 2.5 usdt ".trim(), "tron:nile").amount).toBe("2500000"); + expect(parsePrice(" 2.5 usdt ".trim(), "tron:0xcd8690dc").amount).toBe("2500000"); }); it("rejects malformed price formats", () => { - expect(() => parsePrice("1USDT", "tron:nile")).toThrow(/Expected/); - expect(() => parsePrice("USDT", "tron:nile")).toThrow(/Expected/); - expect(() => parsePrice("-1 USDT", "tron:nile")).toThrow(/non-negative decimal/); + expect(() => parsePrice("1USDT", "tron:0xcd8690dc")).toThrow(/Expected/); + expect(() => parsePrice("USDT", "tron:0xcd8690dc")).toThrow(/Expected/); + expect(() => parsePrice("-1 USDT", "tron:0xcd8690dc")).toThrow(/non-negative decimal/); }); it("rejects unknown tokens", () => { - expect(() => parsePrice("1 WBTC", "tron:nile")).toThrow(/Unknown token/); + expect(() => parsePrice("1 WBTC", "tron:0xcd8690dc")).toThrow(/Unknown token/); }); it("rejects precision overflow", () => { - expect(() => parsePrice("1.1234567 USDT", "tron:nile")).toThrow(/more decimal places/); + expect(() => parsePrice("1.1234567 USDT", "tron:0xcd8690dc")).toThrow(/more decimal places/); }); it("supports runtime-registered tokens", () => { - registerToken("tron:nile", { + registerToken("tron:0xcd8690dc", { address: "TTestTokenAddress0000000000000000000", decimals: 2, name: "Test", symbol: "TEST", version: "1", }); - expect(parsePrice("3.21 TEST", "tron:nile")).toEqual({ + expect(parsePrice("3.21 TEST", "tron:0xcd8690dc")).toEqual({ asset: "TTestTokenAddress0000000000000000000", amount: "321", extra: { name: "Test", version: "1" }, diff --git a/typescript/packages/mechanisms/tron/test/unit/upto-flow.test.ts b/typescript/packages/mechanisms/tron/test/unit/upto-flow.test.ts index cb64f0a6..5ac3eb75 100644 --- a/typescript/packages/mechanisms/tron/test/unit/upto-flow.test.ts +++ b/typescript/packages/mechanisms/tron/test/unit/upto-flow.test.ts @@ -31,7 +31,7 @@ import type { PaymentPayload, PaymentRequirements } from "@bankofai/x402-core/ty * chain I/O is stubbed, keeping the suite offline and deterministic. */ -const NETWORK = "tron:nile"; +const NETWORK = "tron:0xcd8690dc"; const PAYER_PK = "da146374a75310b9666e834ee4ad0866d6f4035967bfc76217c5a495fff9f0d0"; const FAC_PK = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"; const PAY_TO = "TJRyWwFs9wTFGZg3JbrVriFbNfCug5tDeC"; From 28d4b0f4e30496f65f74c425f8e7945e8dac709a Mon Sep 17 00:00:00 2001 From: "roger.gan" Date: Mon, 6 Jul 2026 14:48:16 +0800 Subject: [PATCH 2/3] fix(tron): sync hex chain-id docs, export network constants, add breaking changeset Address PR review on hex CAIP-2 network id change: - README/JSDoc/CLAUDE.md: replace residual tron:nile|shasta|mainnet with hex ids (tron:0xcd8690dc/0x94a9059e/0x2b6653dc) so docs match the implementation and no longer cause Unknown TRON network errors - Export TRON_MAINNET/TRON_NILE/TRON_SHASTA from package entry so consumers can import canonical ids instead of copying opaque strings - Init BofAI changeset baseline + add major changeset for @bankofai/x402-tron documenting the breaking CAIP-2 id change - Update refund-network test mock to use the live Nile id --- CLAUDE.md | 4 ++-- README.md | 8 ++++---- typescript/.changeset/README.md | 3 +++ typescript/.changeset/config.json | 16 ++++++++++++++++ .../.changeset/tron-caip2-hex-chain-id.md | 17 +++++++++++++++++ .../src/observability/facilitatorLogging.ts | 2 +- .../src/observability/resourceServerLogging.ts | 2 +- typescript/packages/http/fetch/src/index.ts | 2 +- .../batch-settlement/refund-network.test.ts | 4 ++-- .../packages/mechanisms/tron/src/index.ts | 3 +++ 10 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 typescript/.changeset/README.md create mode 100644 typescript/.changeset/config.json create mode 100644 typescript/.changeset/tron-caip2-hex-chain-id.md diff --git a/CLAUDE.md b/CLAUDE.md index 2905d820..a4cbba34 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,8 +38,8 @@ Each component has its own `CLAUDE.md` (where present) with build/test commands - **Addresses, selectors, event topics**: lowercase-normalized everywhere. TRON addresses are converted to **0x-prefixed EVM hex** before any EIP-712/TIP-712 signing — see [docs/solutions.md entry #1](docs/solutions.md). - **Payment ID**: 16 random bytes, encoded as `0x` + 32 hex chars, signed as `bytes16`. - **HTTP header encoding**: `Base64(UTF-8(JSON.stringify(object)))` for `PAYMENT-REQUIRED`, `PAYMENT-SIGNATURE`, `PAYMENT-RESPONSE`. -- **Network identifiers**: CAIP-2 `eip155:` for EVM; `tron:` for TRON. -- **Mechanism registration**: `tron:nile` (exact match, higher priority) beats `tron:*` (wildcard, lower priority). +- **Network identifiers**: CAIP-2 `eip155:` for EVM; `tron:` for TRON (e.g. `tron:0xcd8690dc` for Nile). +- **Mechanism registration**: `tron:0xcd8690dc` (exact match, higher priority) beats `tron:*` (wildcard, lower priority). - **Commit messages**: `(): ` — e.g. `fix(tron): preserve raw_data_hex in tron approvals`. ## AI-native development diff --git a/README.md b/README.md index bac81ccf..8502ff5b 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ const wallet = /* resolve your @bankofai/agent-wallet */; // Permit2 approve that USDT/USDD need. When TRON_GRID_API_KEY is unset, mainnet // RPC falls back to a BankofAI-operated endpoint. const signer = await createClientTronSigner(wallet, { - network: "tron:nile", + network: "tron:0xcd8690dc", apiKey: process.env.TRON_GRID_API_KEY, }); @@ -148,9 +148,9 @@ x402 currently supports TRC-20 tokens on the TRON network and BEP-20 tokens on t | Network | ID | Status | Recommended For | |---------|----|--------|-----------------| -| **TRON Nile** | `tron:nile` | Testnet | **Development & Testing** | -| **TRON Shasta** | `tron:shasta` | Testnet | Alternative Testing | -| **TRON Mainnet** | `tron:mainnet` | Mainnet | Production | +| **TRON Nile** | `tron:0xcd8690dc` | Testnet | **Development & Testing** | +| **TRON Shasta** | `tron:0x94a9059e` | Testnet | Alternative Testing | +| **TRON Mainnet** | `tron:0x2b6653dc` | Mainnet | Production | | **BSC Testnet** | `eip155:97` | Testnet | **Development & Testing** | | **BSC Mainnet** | `eip155:56` | Mainnet | Production | diff --git a/typescript/.changeset/README.md b/typescript/.changeset/README.md new file mode 100644 index 00000000..851a231f --- /dev/null +++ b/typescript/.changeset/README.md @@ -0,0 +1,3 @@ +# Changesets + +For more info, check out the [Changesets documentation](https://github.com/changesets/changesets). diff --git a/typescript/.changeset/config.json b/typescript/.changeset/config.json new file mode 100644 index 00000000..b9f3de2b --- /dev/null +++ b/typescript/.changeset/config.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": [ + "@changesets/changelog-github", + { + "repo": "BofAI/x402" + } + ], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/typescript/.changeset/tron-caip2-hex-chain-id.md b/typescript/.changeset/tron-caip2-hex-chain-id.md new file mode 100644 index 00000000..e7274132 --- /dev/null +++ b/typescript/.changeset/tron-caip2-hex-chain-id.md @@ -0,0 +1,17 @@ +--- +"@bankofai/x402-tron": major +--- + +**Breaking:** TRON CAIP-2 network identifiers now use the hex chain ID as the +reference (e.g. `tron:0xcd8690dc` for Nile) instead of the human-readable name +(`tron:nile` / `tron:shasta` / `tron:mainnet`). Passing the old string IDs to the +signer factories (`createClientTronSigner`, `createFacilitatorTronSigner`, +`createAuthorizerTronSigner`) or to `getTronChainId` / RPC resolution now throws +`Unknown TRON network` / `No TRON RPC configured`. + +To migrate: +- Replace `tron:nile` → `tron:0xcd8690dc`, `tron:shasta` → `tron:0x94a9059e`, + `tron:mainnet` → `tron:0x2b6653dc`. +- Prefer importing the new canonical constants from the package entry: + `import { TRON_MAINNET, TRON_NILE, TRON_SHASTA } from "@bankofai/x402-tron"` — + these are now exported so consumers no longer need to copy opaque hex strings. diff --git a/typescript/packages/core/src/observability/facilitatorLogging.ts b/typescript/packages/core/src/observability/facilitatorLogging.ts index f60716f1..18f2ddd0 100644 --- a/typescript/packages/core/src/observability/facilitatorLogging.ts +++ b/typescript/packages/core/src/observability/facilitatorLogging.ts @@ -14,7 +14,7 @@ * import { createFacilitator } from "@bankofai/x402-core"; * * const facilitator = createFacilitator(); // logging pre-attached - * facilitator.register("tron:nile", scheme); + * facilitator.register("tron:0xcd8690dc", scheme); * ``` */ import { diff --git a/typescript/packages/core/src/observability/resourceServerLogging.ts b/typescript/packages/core/src/observability/resourceServerLogging.ts index 6f780c1d..6b0fb573 100644 --- a/typescript/packages/core/src/observability/resourceServerLogging.ts +++ b/typescript/packages/core/src/observability/resourceServerLogging.ts @@ -25,7 +25,7 @@ * import { createResourceServer } from "@bankofai/x402-core"; * * const server = createResourceServer(facilitatorClient); // logging pre-attached - * server.register("tron:nile", scheme); + * server.register("tron:0xcd8690dc", scheme); * ``` */ import { diff --git a/typescript/packages/http/fetch/src/index.ts b/typescript/packages/http/fetch/src/index.ts index d1e69d2b..8f313d16 100644 --- a/typescript/packages/http/fetch/src/index.ts +++ b/typescript/packages/http/fetch/src/index.ts @@ -24,7 +24,7 @@ import { log } from "@bankofai/x402-core"; * * const client = new x402Client() * .register('eip155:8453', new ExactEvmScheme(evmSigner)) - * .register('tron:mainnet', new ExactTronScheme(tronSigner)) + * .register('tron:0x2b6653dc', new ExactTronScheme(tronSigner)) * .register('eip155:1', new ExactEvmScheme(evmSigner), 1); // v1 protocol * * const fetchWithPay = wrapFetchWithPayment(fetch, client); diff --git a/typescript/packages/mechanisms/evm/test/unit/batch-settlement/refund-network.test.ts b/typescript/packages/mechanisms/evm/test/unit/batch-settlement/refund-network.test.ts index 3a97c19b..95be4946 100644 --- a/typescript/packages/mechanisms/evm/test/unit/batch-settlement/refund-network.test.ts +++ b/typescript/packages/mechanisms/evm/test/unit/batch-settlement/refund-network.test.ts @@ -10,7 +10,7 @@ import type { PaymentRequired, PaymentRequirements } from "@bankofai/x402-core/t * (e.g. TRON + EVM), the refund probe must pick THIS package's chain family. * * Previously it took the first scheme match; when a non-eip155 accept came first - * the EVM refund would feed e.g. tron:nile into computeChannelId. The fix filters + * the EVM refund would feed e.g. a tron:* network into computeChannelId. The fix filters * to eip155:*. * * We drive scheme.refund() with a mocked 402 whose accepts list a TRON option @@ -29,7 +29,7 @@ const EVM_AUTHORIZER = "0x1111111111111111111111111111111111111111"; function tronAccept(): PaymentRequirements { return { scheme: "batch-settlement", - network: "tron:nile", + network: "tron:0xcd8690dc", asset: "TGjgvdTWWrybVLaVeFqSyVqJQWjxqRYbaK", amount: "1000000", payTo: "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf", diff --git a/typescript/packages/mechanisms/tron/src/index.ts b/typescript/packages/mechanisms/tron/src/index.ts index 2da61543..d9e5b1c0 100644 --- a/typescript/packages/mechanisms/tron/src/index.ts +++ b/typescript/packages/mechanisms/tron/src/index.ts @@ -47,6 +47,9 @@ export { isPermit2Payload, isEIP3009Payload, isUptoPermit2Payload } from "./type // Constants export { + TRON_MAINNET, + TRON_NILE, + TRON_SHASTA, TRON_CHAIN_IDS, PERMIT2_ADDRESSES, X402_PERMIT2_PROXY_ADDRESSES, From 673d5c3ac01957deaf1bcd687ff3d4145febec98 Mon Sep 17 00:00:00 2001 From: "roger.gan" Date: Mon, 6 Jul 2026 14:53:28 +0800 Subject: [PATCH 3/3] fix(tron): correct changeset authorizer desc, sync .claude rules to hex chain ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - changeset: drop createAuthorizerTronSigner from the list of factories that throw on old network ids — it takes only a wallet (offline signing), no network param - .claude/rules/networks/tron.md: identifier is tron:; update table to canonical constants + hex ids; clarify authorizer signer takes no network - .claude/rules/common/conventions.md, rules/CLAUDE.md, agents/code-reviewer.md: replace tron:/tron:nile with hex ids so code-gen and review agents stop emitting the broken values - rpc.ts module doc: tron: --- .claude/agents/code-reviewer.md | 2 +- .claude/rules/CLAUDE.md | 2 +- .claude/rules/common/conventions.md | 4 ++-- .claude/rules/networks/tron.md | 14 +++++++------- typescript/.changeset/tron-caip2-hex-chain-id.md | 4 ++-- typescript/packages/mechanisms/tron/src/rpc.ts | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.claude/agents/code-reviewer.md b/.claude/agents/code-reviewer.md index e844dae3..daab77b8 100644 --- a/.claude/agents/code-reviewer.md +++ b/.claude/agents/code-reviewer.md @@ -12,7 +12,7 @@ General code review for x402 changes. Treat like a normal `code-reviewer`, but b 1. **Wire format**: any touch to `PaymentRequired`, `PaymentPayload`, or `PaymentResponse` serialization must match [specs/protocol.md](../../specs/protocol.md) and not break [specs/001-exact-v2-compat/spec.md](../../specs/001-exact-v2-compat/spec.md). 2. **Scheme payload**: check that `payload.authorization` is used (not legacy `extensions.transferAuthorization`) for `exact`. 3. **Pipeline step ordering**: client payment selection is 5 steps in [specs/roles.md](../../specs/roles.md). Policies go at step 5. -4. **Mechanism registration**: exact-match network keys (`tron:nile`) win over wildcards (`tron:*`). Flag changes to registration logic. +4. **Mechanism registration**: exact-match network keys (`tron:0xcd8690dc`) win over wildcards (`tron:*`). Flag changes to registration logic. 5. **Lowercase addresses**: all address/selector/topic strings lowercase. Flag any uppercase leak. 6. **Header encoding**: `Base64(UTF-8(JSON.stringify(...)))`, never raw JSON in the header value. diff --git a/.claude/rules/CLAUDE.md b/.claude/rules/CLAUDE.md index 6a799a72..75b7fd10 100644 --- a/.claude/rules/CLAUDE.md +++ b/.claude/rules/CLAUDE.md @@ -35,7 +35,7 @@ When multiple rule files apply, read all of them before editing. Rules are layer │ └── exact-gasfree.md # TRON GasFree custodial + TIP-712 relayer ├── networks/ │ ├── evm.md # eip155:, contracts, signing -│ └── tron.md # tron:, TIP-712 hex-address rule, GasFree link +│ └── tron.md # tron:, TIP-712 hex-address rule, GasFree link ├── typescript/ │ └── conventions.md # pnpm/turbo, ESM, viem/tronweb, fork+overlay, signer factories └── testing/ diff --git a/.claude/rules/common/conventions.md b/.claude/rules/common/conventions.md index 6059b69e..5e9770e2 100644 --- a/.claude/rules/common/conventions.md +++ b/.claude/rules/common/conventions.md @@ -6,7 +6,7 @@ Repository-wide conventions that apply to every component, every scheme. Break t - **Lowercase everything**: addresses, selectors, event topics. - **TRON + EIP/TIP-712**: convert TRON Base58 addresses (`T...`) to **0x-prefixed EVM hex** before passing to any EIP-712 / TIP-712 signer. This applies to `verifyingContract`, `token`, `serviceProvider`, `user`, `receiver`, and any other `address`-typed field, **both in the domain and in the message**. Use `tronAddressToEvm` / `normalizeAddressForSigning` from `mechanisms/tron/src/utils.ts` — do not reimplement. See [docs/solutions.md entry #1](../../../docs/solutions.md). -- **Network identifiers**: CAIP-2 `eip155:` for EVM, `tron:` for TRON. Detection rule: `tron:` prefix → TRON, `eip155:` prefix → EVM. +- **Network identifiers**: CAIP-2 `eip155:` for EVM, `tron:` for TRON (e.g. `tron:0xcd8690dc` for Nile). Detection rule: `tron:` prefix → TRON, `eip155:` prefix → EVM. Prefer the exported constants `TRON_MAINNET` / `TRON_NILE` / `TRON_SHASTA` from `@bankofai/x402-tron` over copying the hex strings. ## Amounts & fees @@ -36,7 +36,7 @@ Repository-wide conventions that apply to every component, every scheme. Break t ## Mechanism registration -- **Exact match** (e.g. `"tron:nile"`) outranks **wildcard** (e.g. `"tron:*"`). Register more specific first, or accept that exact-match mechanisms win the lookup regardless of insertion order. +- **Exact match** (e.g. `"tron:0xcd8690dc"`) outranks **wildcard** (e.g. `"tron:*"`). Register more specific first, or accept that exact-match mechanisms win the lookup regardless of insertion order. - Each scheme class is registered per `(network, scheme)` with `new + register` (no thin wrapper). Do not conflate schemes across mechanisms; register each scheme-network pair explicitly. See [typescript/CLAUDE.md](../../../typescript/CLAUDE.md) "Scheme API surface". ## Policy pipeline diff --git a/.claude/rules/networks/tron.md b/.claude/rules/networks/tron.md index 73d3b41f..8057d0fa 100644 --- a/.claude/rules/networks/tron.md +++ b/.claude/rules/networks/tron.md @@ -2,13 +2,13 @@ Mechanisms: `typescript/packages/mechanisms/tron` (`@bankofai/x402-tron`). **In-house, no upstream** — edit directly. -Identifier: `tron:` where `` ∈ {`mainnet`, `shasta`, `nile`}. +Identifier: `tron:` per CAIP-2 (hex chain id as the reference, not a human-readable name). Canonical constants: `TRON_MAINNET`, `TRON_NILE`, `TRON_SHASTA` exported from `@bankofai/x402-tron`. -| Identifier | Chain ID (decimal) | Chain ID (hex) | -|---|---|---| -| `tron:mainnet` | 728126428 | 0x2b6653dc | -| `tron:shasta` | 2494104990 | 0x94a9059e | -| `tron:nile` | 3448148188 | 0xcd8690dc | +| Constant | Identifier | Chain ID (decimal) | Chain ID (hex) | +|---|---|---|---| +| `TRON_MAINNET` | `tron:0x2b6653dc` | 728126428 | 0x2b6653dc | +| `TRON_SHASTA` | `tron:0x94a9059e` | 2494104990 | 0x94a9059e | +| `TRON_NILE` | `tron:0xcd8690dc` | 3448148188 | 0xcd8690dc | Chain id helper: `getTronChainId(network)` in `mechanisms/tron/src/utils.ts`. @@ -17,7 +17,7 @@ Chain id helper: `getTronChainId(network)` in `mechanisms/tron/src/utils.ts`. - TIP-712 is TRON's EIP-712 analogue. Structurally identical; same struct-hash / domain-separator algorithm. Uses the in-tree TIP-712 signer — do not add a new lib. - **Every `address` field** — domain and message — must be **0x-prefixed EVM hex**. Passing Base58 produces a valid-looking but wrong signature. - Convert Base58 → hex via `tronAddressToEvm` / `normalizeAddressForSigning` (`mechanisms/tron/src/utils.ts`). Do not reimplement. -- Signer factories: `createClientTronSigner` / `createFacilitatorTronSigner` / `createAuthorizerTronSigner` from `@bankofai/x402-tron`. Pass `{ network, apiKey? }`; the factory builds TronWeb internally. +- Signer factories: `createClientTronSigner` / `createFacilitatorTronSigner` / `createAuthorizerTronSigner` from `@bankofai/x402-tron`. `createClientTronSigner` / `createFacilitatorTronSigner` take `{ network, apiKey? }` and build TronWeb internally; `createAuthorizerTronSigner` takes only a wallet (no network — it signs offline). ## Gas & fees diff --git a/typescript/.changeset/tron-caip2-hex-chain-id.md b/typescript/.changeset/tron-caip2-hex-chain-id.md index e7274132..3b63d48a 100644 --- a/typescript/.changeset/tron-caip2-hex-chain-id.md +++ b/typescript/.changeset/tron-caip2-hex-chain-id.md @@ -5,8 +5,8 @@ **Breaking:** TRON CAIP-2 network identifiers now use the hex chain ID as the reference (e.g. `tron:0xcd8690dc` for Nile) instead of the human-readable name (`tron:nile` / `tron:shasta` / `tron:mainnet`). Passing the old string IDs to the -signer factories (`createClientTronSigner`, `createFacilitatorTronSigner`, -`createAuthorizerTronSigner`) or to `getTronChainId` / RPC resolution now throws +signer factories (`createClientTronSigner`, `createFacilitatorTronSigner`) +or to `getTronChainId` / RPC resolution now throws `Unknown TRON network` / `No TRON RPC configured`. To migrate: diff --git a/typescript/packages/mechanisms/tron/src/rpc.ts b/typescript/packages/mechanisms/tron/src/rpc.ts index 5df7a95a..3660039b 100644 --- a/typescript/packages/mechanisms/tron/src/rpc.ts +++ b/typescript/packages/mechanisms/tron/src/rpc.ts @@ -1,7 +1,7 @@ /** * TRON RPC resolution — builds a `TronWeb` instance for a CAIP-2 network. * - * Centralizes the `tron:` → fullHost mapping so the client/facilitator + * Centralizes the `tron:` → fullHost mapping so the client/facilitator * factories take a `network` instead of a caller-built `TronWeb` (mirrors EVM's * `adapters/chains.ts`). Isolated in its own module so unit tests can `vi.mock` * it and inject a fake TronWeb without touching the network.