@anywalletkit/protocol-swap2-wrap 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,8 +20,9 @@ On npm: [@anywalletkit/protocol-swap2-wrap](https://www.npmjs.com/package/@anywa
20
20
 
21
21
  When the provider runs on your server, spread its pins into the app's stub:
22
22
  `remoteProvider({name: "wrap", baseUrl, ...wrapPins})`. The engine then lets the EVM route call and
23
- approve only the wrapped-native contract (no spender), never an address the backend names; without the pins the stub gets no
24
- EVM calldata route (fail closed).
23
+ approve only the wrapped-native contract (no spender), never an address the backend names, and `wrapVerifyQuote`
24
+ checks the call on the device: `deposit()` with the input as value, or `withdraw(input)` with no value, for the
25
+ sender. Without the pins the stub gets no EVM calldata route (fail closed).
25
26
 
26
27
  ## Activity
27
28
 
package/dist/activity.cjs CHANGED
@@ -73,13 +73,60 @@ var WETH_ABI = (0, import_viem.parseAbi)([
73
73
  "function symbol() view returns (string)",
74
74
  "function decimals() view returns (uint8)"
75
75
  ]);
76
+ function wrappedFor(chain) {
77
+ const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
78
+ return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
79
+ }
80
+ function wrapVerifyQuote(params, quote) {
81
+ const w = wrappedFor(params.sourceChain);
82
+ if (!w || params.destChain !== params.sourceChain) return "not a same-chain wrap on a pinned wrapped native";
83
+ const src = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
84
+ if (!src) return `unknown source token ${params.sourceToken}`;
85
+ const nativeIn = !src.contract;
86
+ const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && (0, import_viem.getAddress)(src.contract) === (0, import_viem.getAddress)(w.address);
87
+ const nativeOut = /^0x0+$/.test(params.destToken);
88
+ const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && (0, import_viem.getAddress)(params.destToken) === (0, import_viem.getAddress)(w.address);
89
+ const wrap = nativeIn && destIsWrapped;
90
+ if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} \u2194 ${w.symbol}`;
91
+ if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || (0, import_viem.getAddress)(params.refundAddress) !== (0, import_viem.getAddress)(params.destAddress))) {
92
+ return "wrapping pays the sender's own address";
93
+ }
94
+ const tx = quote.txRequest;
95
+ if (!tx?.data || !tx.to || tx.serializedTx !== void 0) return "the quote carries no wrapped-native call";
96
+ if ((0, import_viem.getAddress)(tx.to) !== (0, import_viem.getAddress)(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;
97
+ if (tx.approvalAddress !== void 0) return "a wrap approves nothing";
98
+ if (tx.chainId !== void 0 && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;
99
+ let amount, value;
100
+ try {
101
+ amount = BigInt(params.amountIn);
102
+ value = BigInt(tx.value ?? "0");
103
+ } catch {
104
+ return "the request does not name amounts";
105
+ }
106
+ if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;
107
+ let call;
108
+ try {
109
+ call = (0, import_viem.decodeFunctionData)({ abi: WETH_ABI, data: tx.data });
110
+ } catch {
111
+ return "the call is neither deposit() nor withdraw(amount)";
112
+ }
113
+ if (wrap) {
114
+ if (call.functionName !== "deposit" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;
115
+ if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;
116
+ } else {
117
+ if (call.functionName !== "withdraw") return `${call.functionName} is not withdraw(amount)`;
118
+ if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;
119
+ if (value !== 0n) return "withdraw attaches no value";
120
+ }
121
+ return null;
122
+ }
76
123
  var wrapPins = Object.freeze({
77
124
  callTargets: (chain) => {
78
- const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
79
- const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
125
+ const w = wrappedFor(chain);
80
126
  return w ? [w.address] : [];
81
127
  },
82
- spenders: () => []
128
+ spenders: () => [],
129
+ verifyQuote: wrapVerifyQuote
83
130
  });
84
131
 
85
132
  // src/activity.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/activity.ts","../src/provider.ts"],"sourcesContent":["/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves) — the\n * app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan 2026-10-27 modules, F8/F16).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n});\n"],"mappings":"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","names":["import_util"]}
1
+ {"version":3,"sources":["../src/activity.ts","../src/provider.ts"],"sourcesContent":["/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionData, decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\nfunction wrappedFor(chain: string): {address: `0x${string}`; symbol: string} | undefined {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n}\n\n/**\n * A remote wrap / unwrap quote, decoded on the device against the app's own request (scan 2026-10-30, F3): native →\n * wrapped is exactly `deposit()` with the input as value; wrapped → native is exactly `withdraw(input)` with no value;\n * on the chain's wrapped native, no approval, and (as WETH9 pays `msg.sender`) a recipient that is the sender. The\n * reason it fails, or null.\n */\nexport function wrapVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n const w = wrappedFor(params.sourceChain);\n if (!w || params.destChain !== params.sourceChain) return \"not a same-chain wrap on a pinned wrapped native\";\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return `unknown source token ${params.sourceToken}`;\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} ↔ ${w.symbol}`;\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || getAddress(params.refundAddress) !== getAddress(params.destAddress))) {\n return \"wrapping pays the sender's own address\";\n }\n const tx = quote.txRequest;\n if (!tx?.data || !tx.to || tx.serializedTx !== undefined) return \"the quote carries no wrapped-native call\";\n if (getAddress(tx.to) !== getAddress(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;\n if (tx.approvalAddress !== undefined) return \"a wrap approves nothing\";\n if (tx.chainId !== undefined && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;\n let amount: bigint, value: bigint;\n try {\n amount = BigInt(params.amountIn);\n value = BigInt(tx.value ?? \"0\");\n } catch {\n return \"the request does not name amounts\";\n }\n if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;\n let call: {functionName: string; args?: readonly unknown[]};\n try {\n call = decodeFunctionData({abi: WETH_ABI, data: tx.data as Hex});\n } catch {\n return \"the call is neither deposit() nor withdraw(amount)\";\n }\n if (wrap) {\n if (call.functionName !== \"deposit\" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;\n if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;\n } else {\n if (call.functionName !== \"withdraw\") return `${call.functionName} is not withdraw(amount)`;\n if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;\n if (value !== 0n) return \"withdraw attaches no value\";\n }\n return null;\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves), and\n * {@link wrapVerifyQuote} — the app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan\n * 2026-10-27 modules, F8/F16; the call itself since scan 2026-10-30, F3).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const w = wrappedFor(chain);\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n verifyQuote: wrapVerifyQuote,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,sBAAqE;AACrE,IAAAA,eAA4B;;;ACN5B,kBAA2G;AAE3G,0BAAsB;AACtB,kBAA2C;AASpC,IAAM,iBAAqF,OAAO,OAAO;AAAA,EAC9G,GAAG,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EACzE,IAAI,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC1E,IAAI,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC1E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,QAAO;AAAA,EAC5E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC3E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC3E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC3E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,QAAO;AAAA,EAC5E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC3E,MAAM,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC5E,MAAM,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC5E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,KAAI;AAAA,EACzE,OAAO,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC7E,MAAM,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC5E,OAAO,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC7E,OAAO,EAAC,SAAS,8CAA8C,QAAQ,QAAO;AAAA,EAC9E,OAAO,EAAC,SAAS,8CAA8C,QAAQ,QAAO;AAAA,EAC9E,QAAQ,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA;AAAA,EAE9E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC3E,MAAM,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC5E,OAAO,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC7E,OAAO,EAAC,SAAS,8CAA8C,QAAQ,SAAQ;AAAA,EAC/E,KAAK,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3E,KAAM,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC5E,QAAQ,EAAC,SAAS,8CAA8C,QAAQ,QAAO;AAAA,EAC/E,MAAM,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAAA,EAC5E,IAAI,EAAC,SAAS,8CAA8C,QAAQ,OAAM;AAC5E,CAAC;AAED,IAAM,eAAW,sBAAS;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAuJD,SAAS,WAAW,OAAqE;AACvF,QAAM,KAAK,kBAAkB,KAAK,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC,CAAC,IAAI;AACpE,SAAO,OAAO,UAAU,eAAe,KAAK,gBAAgB,EAAE,IAAI,eAAe,EAAE,IAAI;AACzF;AAQO,SAAS,gBAAgB,QAAqB,OAA6B;AAChF,QAAM,IAAI,WAAW,OAAO,WAAW;AACvC,MAAI,CAAC,KAAK,OAAO,cAAc,OAAO,YAAa,QAAO;AAC1D,QAAM,UAAM,6BAAQ,OAAO,aAAa,OAAO,WAAW;AAC1D,MAAI,CAAC,IAAK,QAAO,wBAAwB,OAAO,WAAW;AAC3D,QAAM,WAAW,CAAC,IAAI;AACtB,QAAM,eAAe,CAAC,CAAC,IAAI,YAAY,sBAAsB,KAAK,IAAI,QAAQ,SAAK,wBAAW,IAAI,QAAQ,UAAM,wBAAW,EAAE,OAAO;AACpI,QAAM,YAAY,SAAS,KAAK,OAAO,SAAS;AAChD,QAAM,gBAAgB,sBAAsB,KAAK,OAAO,SAAS,KAAK,CAAC,iBAAa,wBAAW,OAAO,SAAS,UAAM,wBAAW,EAAE,OAAO;AACzI,QAAM,OAAO,YAAY;AACzB,MAAI,CAAC,QAAQ,EAAE,gBAAgB,WAAY,QAAO,QAAQ,EAAE,OAAO,MAAM,CAAC,CAAC,WAAM,EAAE,MAAM;AACzF,MAAI,OAAO,iBAAiB,sBAAsB,KAAK,OAAO,aAAa,MAAM,CAAC,sBAAsB,KAAK,OAAO,WAAW,SAAK,wBAAW,OAAO,aAAa,UAAM,wBAAW,OAAO,WAAW,IAAI;AACxM,WAAO;AAAA,EACT;AACA,QAAM,KAAK,MAAM;AACjB,MAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,MAAM,GAAG,iBAAiB,OAAW,QAAO;AACjE,UAAI,wBAAW,GAAG,EAAE,UAAM,wBAAW,EAAE,OAAO,EAAG,QAAO,oBAAoB,GAAG,EAAE,SAAS,EAAE,MAAM;AAClG,MAAI,GAAG,oBAAoB,OAAW,QAAO;AAC7C,MAAI,GAAG,YAAY,UAAa,UAAU,GAAG,OAAO,OAAO,OAAO,YAAa,QAAO,yBAAyB,GAAG,OAAO;AACzH,MAAI,QAAgB;AACpB,MAAI;AACF,aAAS,OAAO,OAAO,QAAQ;AAC/B,YAAQ,OAAO,GAAG,SAAS,GAAG;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,OAAO,MAAM,YAAY,MAAM,OAAQ,QAAO,mBAAmB,MAAM,YAAY,aAAa,MAAM;AAC1G,MAAI;AACJ,MAAI;AACF,eAAO,gCAAmB,EAAC,KAAK,UAAU,MAAM,GAAG,KAAW,CAAC;AAAA,EACjE,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,MAAM;AACR,QAAI,KAAK,iBAAiB,aAAa,GAAG,KAAK,WAAW,GAAI,QAAO,GAAG,KAAK,YAAY;AACzF,QAAI,UAAU,OAAQ,QAAO,sBAAsB,KAAK,aAAa,MAAM;AAAA,EAC7E,OAAO;AACL,QAAI,KAAK,iBAAiB,WAAY,QAAO,GAAG,KAAK,YAAY;AACjE,QAAI,KAAK,OAAO,CAAC,MAAM,OAAQ,QAAO,YAAY,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,MAAM;AAC9F,QAAI,UAAU,GAAI,QAAO;AAAA,EAC3B;AACA,SAAO;AACT;AAOO,IAAM,WAAuB,OAAO,OAAO;AAAA,EAChD,aAAa,CAAC,UAAqC;AACjD,UAAM,IAAI,WAAW,KAAK;AAC1B,WAAO,IAAI,CAAC,EAAE,OAAO,IAAI,CAAC;AAAA,EAC5B;AAAA,EACA,UAAU,MAAyB,CAAC;AAAA,EACpC,aAAa;AACf,CAAC;;;ADrQM,IAAM,cAAc;AAGpB,IAAM,eAAe;AAErB,IAAM,gBAAgB;AAEtB,SAAS,qBACd,IACA,KACA,UAA8E,gBACzD;AACrB,MAAI,KAAC,oBAAM,GAAG,KAAK,EAAG,QAAO;AAC7B,QAAM,IAAI,YAAQ,qBAAO,GAAG,KAAK,CAAC;AAClC,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,gBAAY,6BAAY,IAAI,CAAC,EAAE,OAAO,GAAG,CAAC,YAAY,CAAC;AAC7D,QAAM,aAAa,CAAC,iBAAa,6BAAY,IAAI,CAAC,EAAE,OAAO,GAAG,CAAC,aAAa,CAAC;AAC7E,MAAI,CAAC,aAAa,CAAC,WAAY,QAAO;AACtC,QAAM,EAAC,UAAU,UAAS,QAAI,6BAAY,IAAI,GAAG;AACjD,QAAM,SAAS,CAAC,GAAG,UAAU,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI;AACvE,QAAM,cAAc,aAAS,4BAAW,IAAI,MAAM,IAAI,EAAE,OAAO,QAAQ,SAAS,EAAE;AAClF,aAAO,kCAAiB,IAAI,KAAK;AAAA,IAC/B,UAAU;AAAA,IACV,UAAU,EAAE;AAAA,IACZ,MAAM,YAAY,SAAS;AAAA,IAC3B,OAAO,YAAY,WAAW,WAAW,KAAK,aAAa,EAAE,MAAM;AAAA,EACrE,CAAC;AACH;","names":["import_util"]}
package/dist/activity.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  WETH_WITHDRAW,
4
4
  WRAP_MODULE,
5
5
  describeWrapActivity
6
- } from "./chunk-AEJD6XTY.js";
6
+ } from "./chunk-KB57Z5SA.js";
7
7
  export {
8
8
  WETH_DEPOSIT,
9
9
  WETH_WITHDRAW,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  WRAPPED_NATIVE,
3
3
  wrapProvider
4
- } from "./chunk-AEJD6XTY.js";
4
+ } from "./chunk-KB57Z5SA.js";
5
5
 
6
6
  // src/protocol.ts
7
7
  import { SingleProviderSwap2 } from "@anywalletkit/protocol-swap2-core/swap2/single";
@@ -27,4 +27,4 @@ var WrapSwap2Protocol = class extends SingleProviderSwap2 {
27
27
  export {
28
28
  WrapSwap2Protocol
29
29
  };
30
- //# sourceMappingURL=chunk-FUAB7KLL.js.map
30
+ //# sourceMappingURL=chunk-4BUCH5HA.js.map
@@ -3,7 +3,7 @@ import { assetLabel, describeSwapLike, matchesCall, ownerAssets } from "@anywall
3
3
  import { evmRef as evmRef2, isEvm as isEvm2 } from "@anywalletkit/protocol-swap2-core/util";
4
4
 
5
5
  // src/provider.ts
6
- import { decodeFunctionResult, encodeFunctionData, getAddress, parseAbi } from "viem";
6
+ import { decodeFunctionData, decodeFunctionResult, encodeFunctionData, getAddress, parseAbi } from "viem";
7
7
  import { ccAsset } from "@anywalletkit/swap2-assets";
8
8
  import { evmRef, isEvm, timeoutSignal } from "@anywalletkit/protocol-swap2-core/util";
9
9
  var WRAPPED_NATIVE = Object.freeze({
@@ -170,13 +170,60 @@ function wrapProvider(config) {
170
170
  }
171
171
  };
172
172
  }
173
+ function wrappedFor(chain) {
174
+ const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
175
+ return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
176
+ }
177
+ function wrapVerifyQuote(params, quote) {
178
+ const w = wrappedFor(params.sourceChain);
179
+ if (!w || params.destChain !== params.sourceChain) return "not a same-chain wrap on a pinned wrapped native";
180
+ const src = ccAsset(params.sourceChain, params.sourceToken);
181
+ if (!src) return `unknown source token ${params.sourceToken}`;
182
+ const nativeIn = !src.contract;
183
+ const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);
184
+ const nativeOut = /^0x0+$/.test(params.destToken);
185
+ const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);
186
+ const wrap = nativeIn && destIsWrapped;
187
+ if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} \u2194 ${w.symbol}`;
188
+ if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || getAddress(params.refundAddress) !== getAddress(params.destAddress))) {
189
+ return "wrapping pays the sender's own address";
190
+ }
191
+ const tx = quote.txRequest;
192
+ if (!tx?.data || !tx.to || tx.serializedTx !== void 0) return "the quote carries no wrapped-native call";
193
+ if (getAddress(tx.to) !== getAddress(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;
194
+ if (tx.approvalAddress !== void 0) return "a wrap approves nothing";
195
+ if (tx.chainId !== void 0 && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;
196
+ let amount, value;
197
+ try {
198
+ amount = BigInt(params.amountIn);
199
+ value = BigInt(tx.value ?? "0");
200
+ } catch {
201
+ return "the request does not name amounts";
202
+ }
203
+ if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;
204
+ let call;
205
+ try {
206
+ call = decodeFunctionData({ abi: WETH_ABI, data: tx.data });
207
+ } catch {
208
+ return "the call is neither deposit() nor withdraw(amount)";
209
+ }
210
+ if (wrap) {
211
+ if (call.functionName !== "deposit" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;
212
+ if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;
213
+ } else {
214
+ if (call.functionName !== "withdraw") return `${call.functionName} is not withdraw(amount)`;
215
+ if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;
216
+ if (value !== 0n) return "withdraw attaches no value";
217
+ }
218
+ return null;
219
+ }
173
220
  var wrapPins = Object.freeze({
174
221
  callTargets: (chain) => {
175
- const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
176
- const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
222
+ const w = wrappedFor(chain);
177
223
  return w ? [w.address] : [];
178
224
  },
179
- spenders: () => []
225
+ spenders: () => [],
226
+ verifyQuote: wrapVerifyQuote
180
227
  });
181
228
 
182
229
  // src/activity.ts
@@ -208,6 +255,7 @@ export {
208
255
  describeWrapActivity,
209
256
  WRAPPED_NATIVE,
210
257
  wrapProvider,
258
+ wrapVerifyQuote,
211
259
  wrapPins
212
260
  };
213
- //# sourceMappingURL=chunk-AEJD6XTY.js.map
261
+ //# sourceMappingURL=chunk-KB57Z5SA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/activity.ts","../src/provider.ts"],"sourcesContent":["/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionData, decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\nfunction wrappedFor(chain: string): {address: `0x${string}`; symbol: string} | undefined {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n}\n\n/**\n * A remote wrap / unwrap quote, decoded on the device against the app's own request (scan 2026-10-30, F3): native →\n * wrapped is exactly `deposit()` with the input as value; wrapped → native is exactly `withdraw(input)` with no value;\n * on the chain's wrapped native, no approval, and (as WETH9 pays `msg.sender`) a recipient that is the sender. The\n * reason it fails, or null.\n */\nexport function wrapVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n const w = wrappedFor(params.sourceChain);\n if (!w || params.destChain !== params.sourceChain) return \"not a same-chain wrap on a pinned wrapped native\";\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return `unknown source token ${params.sourceToken}`;\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} ↔ ${w.symbol}`;\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || getAddress(params.refundAddress) !== getAddress(params.destAddress))) {\n return \"wrapping pays the sender's own address\";\n }\n const tx = quote.txRequest;\n if (!tx?.data || !tx.to || tx.serializedTx !== undefined) return \"the quote carries no wrapped-native call\";\n if (getAddress(tx.to) !== getAddress(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;\n if (tx.approvalAddress !== undefined) return \"a wrap approves nothing\";\n if (tx.chainId !== undefined && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;\n let amount: bigint, value: bigint;\n try {\n amount = BigInt(params.amountIn);\n value = BigInt(tx.value ?? \"0\");\n } catch {\n return \"the request does not name amounts\";\n }\n if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;\n let call: {functionName: string; args?: readonly unknown[]};\n try {\n call = decodeFunctionData({abi: WETH_ABI, data: tx.data as Hex});\n } catch {\n return \"the call is neither deposit() nor withdraw(amount)\";\n }\n if (wrap) {\n if (call.functionName !== \"deposit\" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;\n if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;\n } else {\n if (call.functionName !== \"withdraw\") return `${call.functionName} is not withdraw(amount)`;\n if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;\n if (value !== 0n) return \"withdraw attaches no value\";\n }\n return null;\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves), and\n * {@link wrapVerifyQuote} — the app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan\n * 2026-10-27 modules, F8/F16; the call itself since scan 2026-10-30, F3).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const w = wrappedFor(chain);\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n verifyQuote: wrapVerifyQuote,\n});\n"],"mappings":"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","names":["evmRef","isEvm","isEvm","evmRef"]}
package/dist/index.cjs CHANGED
@@ -28,7 +28,8 @@ __export(src_exports, {
28
28
  default: () => WrapSwap2Protocol,
29
29
  describeWrapActivity: () => describeWrapActivity,
30
30
  wrapPins: () => wrapPins,
31
- wrapProvider: () => wrapProvider
31
+ wrapProvider: () => wrapProvider,
32
+ wrapVerifyQuote: () => wrapVerifyQuote
32
33
  });
33
34
  module.exports = __toCommonJS(src_exports);
34
35
 
@@ -226,13 +227,60 @@ function wrapProvider(config) {
226
227
  }
227
228
  };
228
229
  }
230
+ function wrappedFor(chain) {
231
+ const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
232
+ return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
233
+ }
234
+ function wrapVerifyQuote(params, quote) {
235
+ const w = wrappedFor(params.sourceChain);
236
+ if (!w || params.destChain !== params.sourceChain) return "not a same-chain wrap on a pinned wrapped native";
237
+ const src = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
238
+ if (!src) return `unknown source token ${params.sourceToken}`;
239
+ const nativeIn = !src.contract;
240
+ const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && (0, import_viem.getAddress)(src.contract) === (0, import_viem.getAddress)(w.address);
241
+ const nativeOut = /^0x0+$/.test(params.destToken);
242
+ const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && (0, import_viem.getAddress)(params.destToken) === (0, import_viem.getAddress)(w.address);
243
+ const wrap = nativeIn && destIsWrapped;
244
+ if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} \u2194 ${w.symbol}`;
245
+ if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || (0, import_viem.getAddress)(params.refundAddress) !== (0, import_viem.getAddress)(params.destAddress))) {
246
+ return "wrapping pays the sender's own address";
247
+ }
248
+ const tx = quote.txRequest;
249
+ if (!tx?.data || !tx.to || tx.serializedTx !== void 0) return "the quote carries no wrapped-native call";
250
+ if ((0, import_viem.getAddress)(tx.to) !== (0, import_viem.getAddress)(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;
251
+ if (tx.approvalAddress !== void 0) return "a wrap approves nothing";
252
+ if (tx.chainId !== void 0 && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;
253
+ let amount, value;
254
+ try {
255
+ amount = BigInt(params.amountIn);
256
+ value = BigInt(tx.value ?? "0");
257
+ } catch {
258
+ return "the request does not name amounts";
259
+ }
260
+ if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;
261
+ let call;
262
+ try {
263
+ call = (0, import_viem.decodeFunctionData)({ abi: WETH_ABI, data: tx.data });
264
+ } catch {
265
+ return "the call is neither deposit() nor withdraw(amount)";
266
+ }
267
+ if (wrap) {
268
+ if (call.functionName !== "deposit" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;
269
+ if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;
270
+ } else {
271
+ if (call.functionName !== "withdraw") return `${call.functionName} is not withdraw(amount)`;
272
+ if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;
273
+ if (value !== 0n) return "withdraw attaches no value";
274
+ }
275
+ return null;
276
+ }
229
277
  var wrapPins = Object.freeze({
230
278
  callTargets: (chain) => {
231
- const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
232
- const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
279
+ const w = wrappedFor(chain);
233
280
  return w ? [w.address] : [];
234
281
  },
235
- spenders: () => []
282
+ spenders: () => [],
283
+ verifyQuote: wrapVerifyQuote
236
284
  });
237
285
 
238
286
  // src/protocol.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/provider.ts","../src/activity.ts","../src/protocol.ts"],"sourcesContent":["export * from \"./provider.js\";\nexport {WrapSwap2Protocol} from \"./protocol.js\";\nexport {WrapSwap2Protocol as default} from \"./protocol.js\";\nexport * from \"./activity.js\";\nexport type { WrapSwap2Config } from \"./protocol.js\"\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves) — the\n * app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan 2026-10-27 modules, F8/F16).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n});\n","/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n","import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE, wrapProvider, type WrapProviderConfig} from \"./provider.js\";\n\nexport interface WrapSwap2Config extends Swap2EngineConfig, WrapProviderConfig {}\n\n/** Wrap / unwrap the native coin on one account (ETH ↔ WETH and friends). */\nexport class WrapSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n private readonly _rpcUrls: WrapProviderConfig[\"rpcUrls\"];\n private readonly _wrapped: NonNullable<WrapProviderConfig[\"wrapped\"]>;\n constructor(account: Swap2Account | undefined, config: WrapSwap2Config) {\n super(account, config);\n this.provider = wrapProvider(config);\n this._rpcUrls = config.rpcUrls ?? {};\n this._wrapped = config.wrapped ?? WRAPPED_NATIVE;\n }\n protected override chainSupported(caip2: string): boolean {\n return isEvm(caip2) && !!this._wrapped[evmRef(caip2)] && !!this._rpcUrls[evmRef(caip2)]?.length;\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return fromChain === toChain && this.chainSupported(fromChain);\n }\n}\n"],"mappings":"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","names":["import_util","import_util"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/provider.ts","../src/activity.ts","../src/protocol.ts"],"sourcesContent":["export * from \"./provider.js\";\nexport {WrapSwap2Protocol} from \"./protocol.js\";\nexport {WrapSwap2Protocol as default} from \"./protocol.js\";\nexport * from \"./activity.js\";\nexport type { WrapSwap2Config } from \"./protocol.js\"\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionData, decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\nfunction wrappedFor(chain: string): {address: `0x${string}`; symbol: string} | undefined {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n}\n\n/**\n * A remote wrap / unwrap quote, decoded on the device against the app's own request (scan 2026-10-30, F3): native →\n * wrapped is exactly `deposit()` with the input as value; wrapped → native is exactly `withdraw(input)` with no value;\n * on the chain's wrapped native, no approval, and (as WETH9 pays `msg.sender`) a recipient that is the sender. The\n * reason it fails, or null.\n */\nexport function wrapVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n const w = wrappedFor(params.sourceChain);\n if (!w || params.destChain !== params.sourceChain) return \"not a same-chain wrap on a pinned wrapped native\";\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return `unknown source token ${params.sourceToken}`;\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} ↔ ${w.symbol}`;\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || getAddress(params.refundAddress) !== getAddress(params.destAddress))) {\n return \"wrapping pays the sender's own address\";\n }\n const tx = quote.txRequest;\n if (!tx?.data || !tx.to || tx.serializedTx !== undefined) return \"the quote carries no wrapped-native call\";\n if (getAddress(tx.to) !== getAddress(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;\n if (tx.approvalAddress !== undefined) return \"a wrap approves nothing\";\n if (tx.chainId !== undefined && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;\n let amount: bigint, value: bigint;\n try {\n amount = BigInt(params.amountIn);\n value = BigInt(tx.value ?? \"0\");\n } catch {\n return \"the request does not name amounts\";\n }\n if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;\n let call: {functionName: string; args?: readonly unknown[]};\n try {\n call = decodeFunctionData({abi: WETH_ABI, data: tx.data as Hex});\n } catch {\n return \"the call is neither deposit() nor withdraw(amount)\";\n }\n if (wrap) {\n if (call.functionName !== \"deposit\" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;\n if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;\n } else {\n if (call.functionName !== \"withdraw\") return `${call.functionName} is not withdraw(amount)`;\n if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;\n if (value !== 0n) return \"withdraw attaches no value\";\n }\n return null;\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves), and\n * {@link wrapVerifyQuote} — the app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan\n * 2026-10-27 modules, F8/F16; the call itself since scan 2026-10-30, F3).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const w = wrappedFor(chain);\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n verifyQuote: wrapVerifyQuote,\n});\n","/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n","import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE, wrapProvider, type WrapProviderConfig} from \"./provider.js\";\n\nexport interface WrapSwap2Config extends Swap2EngineConfig, WrapProviderConfig {}\n\n/** Wrap / unwrap the native coin on one account (ETH ↔ WETH and friends). */\nexport class WrapSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n private readonly _rpcUrls: WrapProviderConfig[\"rpcUrls\"];\n private readonly _wrapped: NonNullable<WrapProviderConfig[\"wrapped\"]>;\n constructor(account: Swap2Account | undefined, config: WrapSwap2Config) {\n super(account, config);\n this.provider = wrapProvider(config);\n this._rpcUrls = config.rpcUrls ?? {};\n this._wrapped = config.wrapped ?? WRAPPED_NATIVE;\n }\n protected override chainSupported(caip2: string): boolean {\n return isEvm(caip2) && !!this._wrapped[evmRef(caip2)] && !!this._rpcUrls[evmRef(caip2)]?.length;\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return fromChain === toChain && this.chainSupported(fromChain);\n }\n}\n"],"mappings":"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","names":["import_util","import_util"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { WRAPPED_NATIVE, WrapProviderConfig, wrapPins, wrapProvider } from './provider.cjs';
1
+ export { WRAPPED_NATIVE, WrapProviderConfig, wrapPins, wrapProvider, wrapVerifyQuote } from './provider.cjs';
2
2
  export { WrapSwap2Config, WrapSwap2Protocol, WrapSwap2Protocol as default } from './protocol.cjs';
3
3
  export { WETH_DEPOSIT, WETH_WITHDRAW, WRAP_MODULE, describeWrapActivity } from './activity.cjs';
4
4
  import '@anywalletkit/protocol-swap2-core/types';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { WRAPPED_NATIVE, WrapProviderConfig, wrapPins, wrapProvider } from './provider.js';
1
+ export { WRAPPED_NATIVE, WrapProviderConfig, wrapPins, wrapProvider, wrapVerifyQuote } from './provider.js';
2
2
  export { WrapSwap2Config, WrapSwap2Protocol, WrapSwap2Protocol as default } from './protocol.js';
3
3
  export { WETH_DEPOSIT, WETH_WITHDRAW, WRAP_MODULE, describeWrapActivity } from './activity.js';
4
4
  import '@anywalletkit/protocol-swap2-core/types';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  WrapSwap2Protocol
3
- } from "./chunk-FUAB7KLL.js";
3
+ } from "./chunk-4BUCH5HA.js";
4
4
  import {
5
5
  WETH_DEPOSIT,
6
6
  WETH_WITHDRAW,
@@ -8,8 +8,9 @@ import {
8
8
  WRAP_MODULE,
9
9
  describeWrapActivity,
10
10
  wrapPins,
11
- wrapProvider
12
- } from "./chunk-AEJD6XTY.js";
11
+ wrapProvider,
12
+ wrapVerifyQuote
13
+ } from "./chunk-KB57Z5SA.js";
13
14
  export {
14
15
  WETH_DEPOSIT,
15
16
  WETH_WITHDRAW,
@@ -19,6 +20,7 @@ export {
19
20
  WrapSwap2Protocol as default,
20
21
  describeWrapActivity,
21
22
  wrapPins,
22
- wrapProvider
23
+ wrapProvider,
24
+ wrapVerifyQuote
23
25
  };
24
26
  //# sourceMappingURL=index.js.map
package/dist/protocol.cjs CHANGED
@@ -220,13 +220,60 @@ function wrapProvider(config) {
220
220
  }
221
221
  };
222
222
  }
223
+ function wrappedFor(chain) {
224
+ const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
225
+ return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
226
+ }
227
+ function wrapVerifyQuote(params, quote) {
228
+ const w = wrappedFor(params.sourceChain);
229
+ if (!w || params.destChain !== params.sourceChain) return "not a same-chain wrap on a pinned wrapped native";
230
+ const src = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
231
+ if (!src) return `unknown source token ${params.sourceToken}`;
232
+ const nativeIn = !src.contract;
233
+ const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && (0, import_viem.getAddress)(src.contract) === (0, import_viem.getAddress)(w.address);
234
+ const nativeOut = /^0x0+$/.test(params.destToken);
235
+ const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && (0, import_viem.getAddress)(params.destToken) === (0, import_viem.getAddress)(w.address);
236
+ const wrap = nativeIn && destIsWrapped;
237
+ if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} \u2194 ${w.symbol}`;
238
+ if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || (0, import_viem.getAddress)(params.refundAddress) !== (0, import_viem.getAddress)(params.destAddress))) {
239
+ return "wrapping pays the sender's own address";
240
+ }
241
+ const tx = quote.txRequest;
242
+ if (!tx?.data || !tx.to || tx.serializedTx !== void 0) return "the quote carries no wrapped-native call";
243
+ if ((0, import_viem.getAddress)(tx.to) !== (0, import_viem.getAddress)(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;
244
+ if (tx.approvalAddress !== void 0) return "a wrap approves nothing";
245
+ if (tx.chainId !== void 0 && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;
246
+ let amount, value;
247
+ try {
248
+ amount = BigInt(params.amountIn);
249
+ value = BigInt(tx.value ?? "0");
250
+ } catch {
251
+ return "the request does not name amounts";
252
+ }
253
+ if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;
254
+ let call;
255
+ try {
256
+ call = (0, import_viem.decodeFunctionData)({ abi: WETH_ABI, data: tx.data });
257
+ } catch {
258
+ return "the call is neither deposit() nor withdraw(amount)";
259
+ }
260
+ if (wrap) {
261
+ if (call.functionName !== "deposit" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;
262
+ if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;
263
+ } else {
264
+ if (call.functionName !== "withdraw") return `${call.functionName} is not withdraw(amount)`;
265
+ if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;
266
+ if (value !== 0n) return "withdraw attaches no value";
267
+ }
268
+ return null;
269
+ }
223
270
  var wrapPins = Object.freeze({
224
271
  callTargets: (chain) => {
225
- const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
226
- const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
272
+ const w = wrappedFor(chain);
227
273
  return w ? [w.address] : [];
228
274
  },
229
- spenders: () => []
275
+ spenders: () => [],
276
+ verifyQuote: wrapVerifyQuote
230
277
  });
231
278
 
232
279
  // src/protocol.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/protocol.ts","../src/provider.ts","../src/activity.ts"],"sourcesContent":["import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE, wrapProvider, type WrapProviderConfig} from \"./provider.js\";\n\nexport interface WrapSwap2Config extends Swap2EngineConfig, WrapProviderConfig {}\n\n/** Wrap / unwrap the native coin on one account (ETH ↔ WETH and friends). */\nexport class WrapSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n private readonly _rpcUrls: WrapProviderConfig[\"rpcUrls\"];\n private readonly _wrapped: NonNullable<WrapProviderConfig[\"wrapped\"]>;\n constructor(account: Swap2Account | undefined, config: WrapSwap2Config) {\n super(account, config);\n this.provider = wrapProvider(config);\n this._rpcUrls = config.rpcUrls ?? {};\n this._wrapped = config.wrapped ?? WRAPPED_NATIVE;\n }\n protected override chainSupported(caip2: string): boolean {\n return isEvm(caip2) && !!this._wrapped[evmRef(caip2)] && !!this._rpcUrls[evmRef(caip2)]?.length;\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return fromChain === toChain && this.chainSupported(fromChain);\n }\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves) — the\n * app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan 2026-10-27 modules, F8/F16).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n});\n","/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n"],"mappings":"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","names":["import_util","import_util"]}
1
+ {"version":3,"sources":["../src/protocol.ts","../src/provider.ts","../src/activity.ts"],"sourcesContent":["import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE, wrapProvider, type WrapProviderConfig} from \"./provider.js\";\n\nexport interface WrapSwap2Config extends Swap2EngineConfig, WrapProviderConfig {}\n\n/** Wrap / unwrap the native coin on one account (ETH ↔ WETH and friends). */\nexport class WrapSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n private readonly _rpcUrls: WrapProviderConfig[\"rpcUrls\"];\n private readonly _wrapped: NonNullable<WrapProviderConfig[\"wrapped\"]>;\n constructor(account: Swap2Account | undefined, config: WrapSwap2Config) {\n super(account, config);\n this.provider = wrapProvider(config);\n this._rpcUrls = config.rpcUrls ?? {};\n this._wrapped = config.wrapped ?? WRAPPED_NATIVE;\n }\n protected override chainSupported(caip2: string): boolean {\n return isEvm(caip2) && !!this._wrapped[evmRef(caip2)] && !!this._rpcUrls[evmRef(caip2)]?.length;\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return fromChain === toChain && this.chainSupported(fromChain);\n }\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionData, decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\nfunction wrappedFor(chain: string): {address: `0x${string}`; symbol: string} | undefined {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n}\n\n/**\n * A remote wrap / unwrap quote, decoded on the device against the app's own request (scan 2026-10-30, F3): native →\n * wrapped is exactly `deposit()` with the input as value; wrapped → native is exactly `withdraw(input)` with no value;\n * on the chain's wrapped native, no approval, and (as WETH9 pays `msg.sender`) a recipient that is the sender. The\n * reason it fails, or null.\n */\nexport function wrapVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n const w = wrappedFor(params.sourceChain);\n if (!w || params.destChain !== params.sourceChain) return \"not a same-chain wrap on a pinned wrapped native\";\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return `unknown source token ${params.sourceToken}`;\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} ↔ ${w.symbol}`;\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || getAddress(params.refundAddress) !== getAddress(params.destAddress))) {\n return \"wrapping pays the sender's own address\";\n }\n const tx = quote.txRequest;\n if (!tx?.data || !tx.to || tx.serializedTx !== undefined) return \"the quote carries no wrapped-native call\";\n if (getAddress(tx.to) !== getAddress(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;\n if (tx.approvalAddress !== undefined) return \"a wrap approves nothing\";\n if (tx.chainId !== undefined && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;\n let amount: bigint, value: bigint;\n try {\n amount = BigInt(params.amountIn);\n value = BigInt(tx.value ?? \"0\");\n } catch {\n return \"the request does not name amounts\";\n }\n if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;\n let call: {functionName: string; args?: readonly unknown[]};\n try {\n call = decodeFunctionData({abi: WETH_ABI, data: tx.data as Hex});\n } catch {\n return \"the call is neither deposit() nor withdraw(amount)\";\n }\n if (wrap) {\n if (call.functionName !== \"deposit\" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;\n if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;\n } else {\n if (call.functionName !== \"withdraw\") return `${call.functionName} is not withdraw(amount)`;\n if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;\n if (value !== 0n) return \"withdraw attaches no value\";\n }\n return null;\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves), and\n * {@link wrapVerifyQuote} — the app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan\n * 2026-10-27 modules, F8/F16; the call itself since scan 2026-10-30, F3).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const w = wrappedFor(chain);\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n verifyQuote: wrapVerifyQuote,\n});\n","/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n"],"mappings":"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","names":["import_util","import_util"]}
package/dist/protocol.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  WrapSwap2Protocol
3
- } from "./chunk-FUAB7KLL.js";
4
- import "./chunk-AEJD6XTY.js";
3
+ } from "./chunk-4BUCH5HA.js";
4
+ import "./chunk-KB57Z5SA.js";
5
5
  export {
6
6
  WrapSwap2Protocol
7
7
  };
package/dist/provider.cjs CHANGED
@@ -22,7 +22,8 @@ var provider_exports = {};
22
22
  __export(provider_exports, {
23
23
  WRAPPED_NATIVE: () => WRAPPED_NATIVE,
24
24
  wrapPins: () => wrapPins,
25
- wrapProvider: () => wrapProvider
25
+ wrapProvider: () => wrapProvider,
26
+ wrapVerifyQuote: () => wrapVerifyQuote
26
27
  });
27
28
  module.exports = __toCommonJS(provider_exports);
28
29
  var import_viem = require("viem");
@@ -218,12 +219,59 @@ function wrapProvider(config) {
218
219
  }
219
220
  };
220
221
  }
222
+ function wrappedFor(chain) {
223
+ const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
224
+ return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
225
+ }
226
+ function wrapVerifyQuote(params, quote) {
227
+ const w = wrappedFor(params.sourceChain);
228
+ if (!w || params.destChain !== params.sourceChain) return "not a same-chain wrap on a pinned wrapped native";
229
+ const src = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
230
+ if (!src) return `unknown source token ${params.sourceToken}`;
231
+ const nativeIn = !src.contract;
232
+ const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && (0, import_viem.getAddress)(src.contract) === (0, import_viem.getAddress)(w.address);
233
+ const nativeOut = /^0x0+$/.test(params.destToken);
234
+ const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && (0, import_viem.getAddress)(params.destToken) === (0, import_viem.getAddress)(w.address);
235
+ const wrap = nativeIn && destIsWrapped;
236
+ if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} \u2194 ${w.symbol}`;
237
+ if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || (0, import_viem.getAddress)(params.refundAddress) !== (0, import_viem.getAddress)(params.destAddress))) {
238
+ return "wrapping pays the sender's own address";
239
+ }
240
+ const tx = quote.txRequest;
241
+ if (!tx?.data || !tx.to || tx.serializedTx !== void 0) return "the quote carries no wrapped-native call";
242
+ if ((0, import_viem.getAddress)(tx.to) !== (0, import_viem.getAddress)(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;
243
+ if (tx.approvalAddress !== void 0) return "a wrap approves nothing";
244
+ if (tx.chainId !== void 0 && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;
245
+ let amount, value;
246
+ try {
247
+ amount = BigInt(params.amountIn);
248
+ value = BigInt(tx.value ?? "0");
249
+ } catch {
250
+ return "the request does not name amounts";
251
+ }
252
+ if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;
253
+ let call;
254
+ try {
255
+ call = (0, import_viem.decodeFunctionData)({ abi: WETH_ABI, data: tx.data });
256
+ } catch {
257
+ return "the call is neither deposit() nor withdraw(amount)";
258
+ }
259
+ if (wrap) {
260
+ if (call.functionName !== "deposit" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;
261
+ if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;
262
+ } else {
263
+ if (call.functionName !== "withdraw") return `${call.functionName} is not withdraw(amount)`;
264
+ if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;
265
+ if (value !== 0n) return "withdraw attaches no value";
266
+ }
267
+ return null;
268
+ }
221
269
  var wrapPins = Object.freeze({
222
270
  callTargets: (chain) => {
223
- const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;
224
- const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : void 0;
271
+ const w = wrappedFor(chain);
225
272
  return w ? [w.address] : [];
226
273
  },
227
- spenders: () => []
274
+ spenders: () => [],
275
+ verifyQuote: wrapVerifyQuote
228
276
  });
229
277
  //# sourceMappingURL=provider.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.ts","../src/activity.ts"],"sourcesContent":["import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves) — the\n * app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan 2026-10-27 modules, F8/F16).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n});\n","/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n"],"mappings":"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","names":["import_util"]}
1
+ {"version":3,"sources":["../src/provider.ts","../src/activity.ts"],"sourcesContent":["import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionData, decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\nfunction wrappedFor(chain: string): {address: `0x${string}`; symbol: string} | undefined {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n return Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n}\n\n/**\n * A remote wrap / unwrap quote, decoded on the device against the app's own request (scan 2026-10-30, F3): native →\n * wrapped is exactly `deposit()` with the input as value; wrapped → native is exactly `withdraw(input)` with no value;\n * on the chain's wrapped native, no approval, and (as WETH9 pays `msg.sender`) a recipient that is the sender. The\n * reason it fails, or null.\n */\nexport function wrapVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n const w = wrappedFor(params.sourceChain);\n if (!w || params.destChain !== params.sourceChain) return \"not a same-chain wrap on a pinned wrapped native\";\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return `unknown source token ${params.sourceToken}`;\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n if (!wrap && !(srcIsWrapped && nativeOut)) return `only ${w.symbol.slice(1)} ↔ ${w.symbol}`;\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (!/^0x[0-9a-fA-F]{40}$/.test(params.destAddress) || getAddress(params.refundAddress) !== getAddress(params.destAddress))) {\n return \"wrapping pays the sender's own address\";\n }\n const tx = quote.txRequest;\n if (!tx?.data || !tx.to || tx.serializedTx !== undefined) return \"the quote carries no wrapped-native call\";\n if (getAddress(tx.to) !== getAddress(w.address)) return `the call targets ${tx.to}, not ${w.symbol}`;\n if (tx.approvalAddress !== undefined) return \"a wrap approves nothing\";\n if (tx.chainId !== undefined && `eip155:${tx.chainId}` !== params.sourceChain) return `the call is for chain ${tx.chainId}`;\n let amount: bigint, value: bigint;\n try {\n amount = BigInt(params.amountIn);\n value = BigInt(tx.value ?? \"0\");\n } catch {\n return \"the request does not name amounts\";\n }\n if (BigInt(quote.sourceAmount) !== amount) return `the quote moves ${quote.sourceAmount}, not the ${amount} input`;\n let call: {functionName: string; args?: readonly unknown[]};\n try {\n call = decodeFunctionData({abi: WETH_ABI, data: tx.data as Hex});\n } catch {\n return \"the call is neither deposit() nor withdraw(amount)\";\n }\n if (wrap) {\n if (call.functionName !== \"deposit\" || tx.data.length !== 10) return `${call.functionName} is not deposit()`;\n if (value !== amount) return `deposit() attaches ${value}, not the ${amount} input`;\n } else {\n if (call.functionName !== \"withdraw\") return `${call.functionName} is not withdraw(amount)`;\n if (call.args?.[0] !== amount) return `withdraw(${String(call.args?.[0])}) is not the ${amount} input`;\n if (value !== 0n) return \"withdraw attaches no value\";\n }\n return null;\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves), and\n * {@link wrapVerifyQuote} — the app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan\n * 2026-10-27 modules, F8/F16; the call itself since scan 2026-10-30, F3).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const w = wrappedFor(chain);\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n verifyQuote: wrapVerifyQuote,\n});\n","/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n"],"mappings":"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","names":["import_util"]}
@@ -1,4 +1,4 @@
1
- import { RemotePins, CrossChainProvider } from '@anywalletkit/protocol-swap2-core/types';
1
+ import { RemotePins, CrossChainProvider, QuoteParams, Quote } from '@anywalletkit/protocol-swap2-core/types';
2
2
 
3
3
  /**
4
4
  * The chain's canonical wrapped native token (WETH9-style `deposit()` /
@@ -28,9 +28,17 @@ interface WrapProviderConfig {
28
28
  */
29
29
  declare function wrapProvider(config: WrapProviderConfig): CrossChainProvider;
30
30
  /**
31
- * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves) — the
32
- * app's pins for `remoteProvider({name: "wrap", baseUrl, ...wrapPins})` (scan 2026-10-27 modules, F8/F16).
31
+ * A remote wrap / unwrap quote, decoded on the device against the app's own request (scan 2026-10-30, F3): native →
32
+ * wrapped is exactly `deposit()` with the input as value; wrapped → native is exactly `withdraw(input)` with no value;
33
+ * on the chain's wrapped native, no approval, and (as WETH9 pays `msg.sender`) a recipient that is the sender. The
34
+ * reason it fails, or null.
35
+ */
36
+ declare function wrapVerifyQuote(params: QuoteParams, quote: Quote): string | null;
37
+ /**
38
+ * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves), and
39
+ * {@link wrapVerifyQuote} — the app's pins for `remoteProvider({name: "wrap", baseUrl, ...wrapPins})` (scan
40
+ * 2026-10-27 modules, F8/F16; the call itself since scan 2026-10-30, F3).
33
41
  */
34
42
  declare const wrapPins: RemotePins;
35
43
 
36
- export { WRAPPED_NATIVE, type WrapProviderConfig, wrapPins, wrapProvider };
44
+ export { WRAPPED_NATIVE, type WrapProviderConfig, wrapPins, wrapProvider, wrapVerifyQuote };
@@ -1,4 +1,4 @@
1
- import { RemotePins, CrossChainProvider } from '@anywalletkit/protocol-swap2-core/types';
1
+ import { RemotePins, CrossChainProvider, QuoteParams, Quote } from '@anywalletkit/protocol-swap2-core/types';
2
2
 
3
3
  /**
4
4
  * The chain's canonical wrapped native token (WETH9-style `deposit()` /
@@ -28,9 +28,17 @@ interface WrapProviderConfig {
28
28
  */
29
29
  declare function wrapProvider(config: WrapProviderConfig): CrossChainProvider;
30
30
  /**
31
- * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves) — the
32
- * app's pins for `remoteProvider({name: "wrap", baseUrl, ...wrapPins})` (scan 2026-10-27 modules, F8/F16).
31
+ * A remote wrap / unwrap quote, decoded on the device against the app's own request (scan 2026-10-30, F3): native →
32
+ * wrapped is exactly `deposit()` with the input as value; wrapped → native is exactly `withdraw(input)` with no value;
33
+ * on the chain's wrapped native, no approval, and (as WETH9 pays `msg.sender`) a recipient that is the sender. The
34
+ * reason it fails, or null.
35
+ */
36
+ declare function wrapVerifyQuote(params: QuoteParams, quote: Quote): string | null;
37
+ /**
38
+ * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves), and
39
+ * {@link wrapVerifyQuote} — the app's pins for `remoteProvider({name: "wrap", baseUrl, ...wrapPins})` (scan
40
+ * 2026-10-27 modules, F8/F16; the call itself since scan 2026-10-30, F3).
33
41
  */
34
42
  declare const wrapPins: RemotePins;
35
43
 
36
- export { WRAPPED_NATIVE, type WrapProviderConfig, wrapPins, wrapProvider };
44
+ export { WRAPPED_NATIVE, type WrapProviderConfig, wrapPins, wrapProvider, wrapVerifyQuote };
package/dist/provider.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import {
2
2
  WRAPPED_NATIVE,
3
3
  wrapPins,
4
- wrapProvider
5
- } from "./chunk-AEJD6XTY.js";
4
+ wrapProvider,
5
+ wrapVerifyQuote
6
+ } from "./chunk-KB57Z5SA.js";
6
7
  export {
7
8
  WRAPPED_NATIVE,
8
9
  wrapPins,
9
- wrapProvider
10
+ wrapProvider,
11
+ wrapVerifyQuote
10
12
  };
11
13
  //# sourceMappingURL=provider.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anywalletkit/protocol-swap2-wrap",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Wrap and unwrap the native coin (ETH↔WETH, BNB↔WBNB, POL↔WPOL…) on 13 EVM chains as a swap2 venue: 1:1, no pool, wrapped tokens verified on-chain.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://docs.anywallet.tech",
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "viem": "^2.57.2",
48
48
  "@anywalletkit/swap2-assets": "0.2.2",
49
- "@anywalletkit/protocol-swap2-core": "0.8.0"
49
+ "@anywalletkit/protocol-swap2-core": "0.9.0"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "@anywalletkit/core": "0.7.0"
@@ -54,8 +54,8 @@
54
54
  "devDependencies": {
55
55
  "@types/node": "^22",
56
56
  "vitest": "^5.0.3",
57
- "@anywalletkit/conformance": "0.4.6",
58
- "@anywalletkit/core": "0.7.0"
57
+ "@anywalletkit/core": "0.7.0",
58
+ "@anywalletkit/conformance": "0.4.6"
59
59
  },
60
60
  "keywords": [
61
61
  "wrap",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/activity.ts","../src/provider.ts"],"sourcesContent":["/**\n * Activity recognition for the Wrap module: WETH9 `deposit()` → `wrap`\n * (\"Wrapped ETH\"), `withdraw(uint256)` → `unwrap` (\"Unwrapped WETH\"), on the\n * wrapper the table (or the caller's override) names for the chain.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {assetLabel, describeSwapLike, matchesCall, ownerAssets} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {WRAPPED_NATIVE} from \"./provider.js\";\n\nexport const WRAP_MODULE = \"@anywalletkit/protocol-swap2-wrap\";\n\n/** deposit() */\nexport const WETH_DEPOSIT = \"0xd0e30db0\";\n/** withdraw(uint256 wad) */\nexport const WETH_WITHDRAW = \"0x2e1a7d4d\";\n\nexport function describeWrapActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n wrapped: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = WRAPPED_NATIVE,\n): ActivityItem | null {\n if (!isEvm(tx.chain)) return null;\n const w = wrapped[evmRef(tx.chain)];\n if (!w) return null;\n const isDeposit = matchesCall(tx, [w.address], [WETH_DEPOSIT]);\n const isWithdraw = !isDeposit && matchesCall(tx, [w.address], [WETH_WITHDRAW]);\n if (!isDeposit && !isWithdraw) return null;\n const {assetsIn, assetsOut} = ownerAssets(tx, ctx);\n const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);\n const nativeLabel = native ? assetLabel(tx, native) : w.symbol.replace(/^[Ww]/, \"\");\n return describeSwapLike(tx, ctx, {\n protocol: WRAP_MODULE,\n subtitle: w.symbol,\n kind: isDeposit ? \"wrap\" : \"unwrap\",\n title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`,\n });\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeFunctionResult, encodeFunctionData, getAddress, parseAbi, type Hex} from \"viem\";\nimport {describeWrapActivity} from \"./activity.js\";\nimport {ccAsset} from \"@anywalletkit/swap2-assets\";\nimport {evmRef, isEvm, timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\n/**\n * The chain's canonical wrapped native token (WETH9-style `deposit()` /\n * `withdraw(uint256)`). Every entry was checked on-chain 2026-10-12: symbol,\n * 18 decimals, non-zero supply, and `deposit()` succeeding for a funded sender.\n * The provider re-checks symbol + decimals once per chain before quoting.\n */\nexport const WRAPPED_NATIVE: Readonly<Record<number, {address: `0x${string}`; symbol: string}>> = Object.freeze({\n 1: {address: \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", symbol: \"WETH\"},\n 10: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 56: {address: \"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c\", symbol: \"WBNB\"},\n 100: {address: \"0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d\", symbol: \"WXDAI\"},\n 130: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 137: {address: \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\", symbol: \"WPOL\"},\n 143: {address: \"0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A\", symbol: \"WMON\"},\n 999: {address: \"0x5555555555555555555555555555555555555555\", symbol: \"WHYPE\"},\n 324: {address: \"0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91\", symbol: \"WETH\"},\n 4326: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 9745: {address: \"0x6100E367285b01F48D07953803A2d8dCA5D19873\", symbol: \"WXPL\"},\n 146: {address: \"0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38\", symbol: \"wS\"},\n 59144: {address: \"0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f\", symbol: \"WETH\"},\n 8453: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 42161: {address: \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\", symbol: \"WETH\"},\n 43114: {address: \"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7\", symbol: \"WAVAX\"},\n 80094: {address: \"0x6969696969696969696969696969696969696969\", symbol: \"WBERA\"},\n 534352: {address: \"0x5300000000000000000000000000000000000004\", symbol: \"WETH\"},\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).\n 480: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 1329: {address: \"0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7\", symbol: \"WSEI\"},\n 57073: {address: \"0x4200000000000000000000000000000000000006\", symbol: \"WETH\"},\n 98866: {address: \"0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1\", symbol: \"WPLUME\"},\n 196: {address: \"0xe538905cf8410324e03A5A23C1c177a474D59b2b\", symbol: \"WOKB\"},\n // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the\n // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is\n // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).\n // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).\n 5000: {address: \"0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8\", symbol: \"WMNT\"},\n 747474: {address: \"0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62\", symbol: \"vbETH\"},\n 2818: {address: \"0x5300000000000000000000000000000000000011\", symbol: \"WETH\"},\n 14: {address: \"0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d\", symbol: \"WFLR\"},\n});\n\nconst WETH_ABI = parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 wad)\",\n \"function symbol() view returns (string)\",\n \"function decimals() view returns (uint8)\",\n]);\n/** deposit/withdraw on WETH9 cost ~30-45k; a generous cap, the account still estimates. */\nconst GAS_LIMIT = \"90000\";\n\nexport interface WrapProviderConfig {\n enabled?: boolean;\n /** JSON-RPC endpoints per EVM chain id (on-chain token check + receipt tracking). */\n rpcUrls: Readonly<Record<number, readonly string[]>>;\n /** Override the wrapped tokens (tests, new chains). Still verified on-chain before use. */\n wrapped?: Readonly<Record<number, {address: `0x${string}`; symbol: string}>>;\n}\n\n/**\n * Native ↔ wrapped native as a swap2 venue: `deposit()` with value to wrap,\n * `withdraw(amount)` to unwrap. 1:1, no pool, no slippage, no approval. WETH9\n * credits and pays `msg.sender`, so the recipient must be the sender — a wrap\n * \"to someone else\" is refused rather than silently paid to the wrong place.\n */\nexport function wrapProvider(config: WrapProviderConfig): CrossChainProvider {\n const wrapped = config.wrapped ?? WRAPPED_NATIVE;\n const verified = new Map<number, Promise<void>>();\n\n const chainIdOf = (caip2: string): number | null => {\n if (!isEvm(caip2)) return null;\n const id = evmRef(caip2);\n return wrapped[id] && config.rpcUrls[id]?.length ? id : null;\n };\n\n async function rpc(chainId: number, method: string, params: unknown[]): Promise<unknown> {\n let lastErr: unknown;\n for (const url of config.rpcUrls[chainId] ?? []) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\"content-type\": \"application/json\"},\n body: JSON.stringify({jsonrpc: \"2.0\", id: 1, method, params}),\n signal: timeoutSignal(10_000),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const body = (await res.json()) as {result?: unknown; error?: {message?: string}};\n if (body.error) throw new Error(body.error.message ?? \"rpc error\");\n return body.result ?? null;\n } catch (e) {\n lastErr = e;\n }\n }\n throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);\n }\n\n function verify(chainId: number): Promise<void> {\n let p = verified.get(chainId);\n if (!p) {\n const w = wrapped[chainId]!;\n p = (async () => {\n const read = async (fn: \"symbol\" | \"decimals\") =>\n decodeFunctionResult({abi: WETH_ABI, functionName: fn, data: (await rpc(chainId, \"eth_call\", [{to: w.address, data: encodeFunctionData({abi: WETH_ABI, functionName: fn})}, \"latest\"])) as Hex});\n const [symbol, decimals] = await Promise.all([read(\"symbol\"), read(\"decimals\")]);\n if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} — refusing`);\n })();\n p.catch(() => verified.delete(chainId));\n verified.set(chainId, p);\n }\n return p;\n }\n\n return {\n name: \"wrap\",\n describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n supportsChain: (caip2: string) => chainIdOf(caip2) !== null,\n supportsChainPair: (from: string, to: string) => from === to && chainIdOf(from) !== null,\n supportsRoute(from: Asset, to: Asset): boolean {\n return from.chain === to.chain && chainIdOf(from.chain) !== null;\n },\n\n async getQuote(params: QuoteParams): Promise<Quote | null> {\n const refuse = (why: string): null => {\n params.onRefusal?.(`wrap: ${why}`);\n return null;\n };\n if (params.flex) return refuse(\"amount-flexible deposits are not supported\");\n if (params.sourceChain !== params.destChain) return refuse(\"same-chain only\");\n const chainId = chainIdOf(params.sourceChain);\n if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);\n const w = wrapped[chainId]!;\n const src = ccAsset(params.sourceChain, params.sourceToken);\n if (!src) return refuse(`unknown source token ${params.sourceToken}`);\n const nativeIn = !src.contract;\n const srcIsWrapped = !!src.contract && /^0x[0-9a-fA-F]{40}$/.test(src.contract) && getAddress(src.contract) === getAddress(w.address);\n const nativeOut = /^0x0+$/.test(params.destToken);\n const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && getAddress(params.destToken) === getAddress(w.address);\n const wrap = nativeIn && destIsWrapped;\n const unwrap = srcIsWrapped && nativeOut;\n if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} ↔ ${w.symbol}`);\n // WETH9 credits / pays msg.sender: the recipient can only be the sender.\n if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && getAddress(params.refundAddress) !== getAddress(params.destAddress)) {\n return refuse(\"wrapping pays the sender's own address — send the result separately\");\n }\n let amount: bigint;\n try {\n amount = BigInt(params.amountIn);\n } catch {\n return refuse(\"amount is not an integer\");\n }\n if (amount <= 0n) return refuse(\"amount must be positive\");\n if (params.minAmountOut !== undefined && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);\n try {\n await verify(chainId);\n } catch (e) {\n return refuse(e instanceof Error ? e.message.replace(/^wrap: /, \"\") : String(e));\n }\n const data = wrap ? encodeFunctionData({abi: WETH_ABI, functionName: \"deposit\"}) : encodeFunctionData({abi: WETH_ABI, functionName: \"withdraw\", args: [amount]});\n return {\n provider: \"wrap\",\n intentId: `wrap:${chainId}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: w.address, data, value: wrap ? amount.toString() : \"0\", chainId, gasLimit: GAS_LIMIT},\n sourceAmount: amount.toString(),\n destAmount: amount.toString(),\n minDestAmount: amount.toString(),\n feeUsd: 0,\n etaSeconds: 15,\n reliability: 0.995,\n validUntilMs: Date.now() + 5 * 60_000,\n providerData: {action: wrap ? \"wrap\" : \"unwrap\", token: w.address},\n };\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"swap2: wrap quote has no transaction request\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {})};\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const chainId = Number(ref.intentId.split(\":\")[1]);\n if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return {state: \"pending\"};\n try {\n const receipt = (await rpc(chainId, \"eth_getTransactionReceipt\", [ref.sourceTxHash])) as {status?: string} | null;\n if (!receipt) return {state: \"pending\"};\n return receipt.status === \"0x1\" ? {state: \"completed\", destTxHash: ref.sourceTxHash} : {state: \"failed\"};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n/**\n * The wrapped-native contract a wrap / unwrap calls on a chain (no spender: neither approves) — the\n * app's pins for `remoteProvider({name: \"wrap\", baseUrl, ...wrapPins})` (scan 2026-10-27 modules, F8/F16).\n */\nexport const wrapPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => {\n const id = /^eip155:[0-9]+$/.test(chain) ? Number(chain.slice(7)) : NaN;\n const w = Object.prototype.hasOwnProperty.call(WRAPPED_NATIVE, id) ? WRAPPED_NATIVE[id] : undefined;\n return w ? [w.address] : [];\n },\n spenders: (): readonly string[] => [],\n});\n"],"mappings":"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","names":["evmRef","isEvm","isEvm","evmRef"]}