@anywalletkit/protocol-swap2-wrap 0.0.0-stage → 0.1.3

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.
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/protocol.ts
21
+ var protocol_exports = {};
22
+ __export(protocol_exports, {
23
+ WrapSwap2Protocol: () => WrapSwap2Protocol
24
+ });
25
+ module.exports = __toCommonJS(protocol_exports);
26
+ var import_single = require("@anywalletkit/protocol-swap2-core/swap2/single");
27
+ var import_util3 = require("@anywalletkit/protocol-swap2-core/util");
28
+
29
+ // src/provider.ts
30
+ var import_viem = require("viem");
31
+
32
+ // src/activity.ts
33
+ var import_activity = require("@anywalletkit/protocol-swap2-core/activity");
34
+ var import_util = require("@anywalletkit/protocol-swap2-core/util");
35
+ var WRAP_MODULE = "@anywalletkit/protocol-swap2-wrap";
36
+ var WETH_DEPOSIT = "0xd0e30db0";
37
+ var WETH_WITHDRAW = "0x2e1a7d4d";
38
+ function describeWrapActivity(tx, ctx, wrapped = WRAPPED_NATIVE) {
39
+ if (!(0, import_util.isEvm)(tx.chain)) return null;
40
+ const w = wrapped[(0, import_util.evmRef)(tx.chain)];
41
+ if (!w) return null;
42
+ const isDeposit = (0, import_activity.matchesCall)(tx, [w.address], [WETH_DEPOSIT]);
43
+ const isWithdraw = !isDeposit && (0, import_activity.matchesCall)(tx, [w.address], [WETH_WITHDRAW]);
44
+ if (!isDeposit && !isWithdraw) return null;
45
+ const { assetsIn, assetsOut } = (0, import_activity.ownerAssets)(tx, ctx);
46
+ const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);
47
+ const nativeLabel = native ? (0, import_activity.assetLabel)(tx, native) : w.symbol.replace(/^[Ww]/, "");
48
+ return (0, import_activity.describeSwapLike)(tx, ctx, {
49
+ protocol: WRAP_MODULE,
50
+ subtitle: w.symbol,
51
+ kind: isDeposit ? "wrap" : "unwrap",
52
+ title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`
53
+ });
54
+ }
55
+
56
+ // src/provider.ts
57
+ var import_swap2_assets = require("@anywalletkit/swap2-assets");
58
+ var import_util2 = require("@anywalletkit/protocol-swap2-core/util");
59
+ var WRAPPED_NATIVE = Object.freeze({
60
+ 1: { address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", symbol: "WETH" },
61
+ 10: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
62
+ 56: { address: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", symbol: "WBNB" },
63
+ 100: { address: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", symbol: "WXDAI" },
64
+ 130: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
65
+ 137: { address: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", symbol: "WPOL" },
66
+ 143: { address: "0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A", symbol: "WMON" },
67
+ 999: { address: "0x5555555555555555555555555555555555555555", symbol: "WHYPE" },
68
+ 324: { address: "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", symbol: "WETH" },
69
+ 4326: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
70
+ 9745: { address: "0x6100E367285b01F48D07953803A2d8dCA5D19873", symbol: "WXPL" },
71
+ 146: { address: "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38", symbol: "wS" },
72
+ 59144: { address: "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", symbol: "WETH" },
73
+ 8453: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
74
+ 42161: { address: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", symbol: "WETH" },
75
+ 43114: { address: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", symbol: "WAVAX" },
76
+ 80094: { address: "0x6969696969696969696969696969696969696969", symbol: "WBERA" },
77
+ 534352: { address: "0x5300000000000000000000000000000000000004", symbol: "WETH" },
78
+ // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).
79
+ 480: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
80
+ 1329: { address: "0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7", symbol: "WSEI" },
81
+ 57073: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
82
+ 98866: { address: "0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1", symbol: "WPLUME" },
83
+ 196: { address: "0xe538905cf8410324e03A5A23C1c177a474D59b2b", symbol: "WOKB" },
84
+ // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the
85
+ // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is
86
+ // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).
87
+ // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).
88
+ 5e3: { address: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8", symbol: "WMNT" },
89
+ 747474: { address: "0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62", symbol: "vbETH" },
90
+ 2818: { address: "0x5300000000000000000000000000000000000011", symbol: "WETH" },
91
+ 14: { address: "0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d", symbol: "WFLR" }
92
+ });
93
+ var WETH_ABI = (0, import_viem.parseAbi)([
94
+ "function deposit() payable",
95
+ "function withdraw(uint256 wad)",
96
+ "function symbol() view returns (string)",
97
+ "function decimals() view returns (uint8)"
98
+ ]);
99
+ var GAS_LIMIT = "90000";
100
+ function wrapProvider(config) {
101
+ const wrapped = config.wrapped ?? WRAPPED_NATIVE;
102
+ const verified = /* @__PURE__ */ new Map();
103
+ const chainIdOf = (caip2) => {
104
+ if (!(0, import_util2.isEvm)(caip2)) return null;
105
+ const id = (0, import_util2.evmRef)(caip2);
106
+ return wrapped[id] && config.rpcUrls[id]?.length ? id : null;
107
+ };
108
+ async function rpc(chainId, method, params) {
109
+ let lastErr;
110
+ for (const url of config.rpcUrls[chainId] ?? []) {
111
+ try {
112
+ const res = await fetch(url, {
113
+ method: "POST",
114
+ headers: { "content-type": "application/json" },
115
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
116
+ signal: (0, import_util2.timeoutSignal)(1e4)
117
+ });
118
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
119
+ const body = await res.json();
120
+ if (body.error) throw new Error(body.error.message ?? "rpc error");
121
+ return body.result ?? null;
122
+ } catch (e) {
123
+ lastErr = e;
124
+ }
125
+ }
126
+ throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);
127
+ }
128
+ function verify(chainId) {
129
+ let p = verified.get(chainId);
130
+ if (!p) {
131
+ const w = wrapped[chainId];
132
+ p = (async () => {
133
+ const read = async (fn) => (0, import_viem.decodeFunctionResult)({ abi: WETH_ABI, functionName: fn, data: await rpc(chainId, "eth_call", [{ to: w.address, data: (0, import_viem.encodeFunctionData)({ abi: WETH_ABI, functionName: fn }) }, "latest"]) });
134
+ const [symbol, decimals] = await Promise.all([read("symbol"), read("decimals")]);
135
+ if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} \u2014 refusing`);
136
+ })();
137
+ p.catch(() => verified.delete(chainId));
138
+ verified.set(chainId, p);
139
+ }
140
+ return p;
141
+ }
142
+ return {
143
+ name: "wrap",
144
+ describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),
145
+ supportsSameChain: true,
146
+ enabled: () => config.enabled ?? true,
147
+ supportsChain: (caip2) => chainIdOf(caip2) !== null,
148
+ supportsChainPair: (from, to) => from === to && chainIdOf(from) !== null,
149
+ supportsRoute(from, to) {
150
+ return from.chain === to.chain && chainIdOf(from.chain) !== null;
151
+ },
152
+ async getQuote(params) {
153
+ const refuse = (why) => {
154
+ params.onRefusal?.(`wrap: ${why}`);
155
+ return null;
156
+ };
157
+ if (params.flex) return refuse("amount-flexible deposits are not supported");
158
+ if (params.sourceChain !== params.destChain) return refuse("same-chain only");
159
+ const chainId = chainIdOf(params.sourceChain);
160
+ if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);
161
+ const w = wrapped[chainId];
162
+ const src = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
163
+ if (!src) return refuse(`unknown source token ${params.sourceToken}`);
164
+ const nativeIn = !src.contract;
165
+ 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);
166
+ const nativeOut = /^0x0+$/.test(params.destToken);
167
+ const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && (0, import_viem.getAddress)(params.destToken) === (0, import_viem.getAddress)(w.address);
168
+ const wrap = nativeIn && destIsWrapped;
169
+ const unwrap = srcIsWrapped && nativeOut;
170
+ if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} \u2194 ${w.symbol}`);
171
+ if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (0, import_viem.getAddress)(params.refundAddress) !== (0, import_viem.getAddress)(params.destAddress)) {
172
+ return refuse("wrapping pays the sender's own address \u2014 send the result separately");
173
+ }
174
+ let amount;
175
+ try {
176
+ amount = BigInt(params.amountIn);
177
+ } catch {
178
+ return refuse("amount is not an integer");
179
+ }
180
+ if (amount <= 0n) return refuse("amount must be positive");
181
+ if (params.minAmountOut !== void 0 && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);
182
+ try {
183
+ await verify(chainId);
184
+ } catch (e) {
185
+ return refuse(e instanceof Error ? e.message.replace(/^wrap: /, "") : String(e));
186
+ }
187
+ const data = wrap ? (0, import_viem.encodeFunctionData)({ abi: WETH_ABI, functionName: "deposit" }) : (0, import_viem.encodeFunctionData)({ abi: WETH_ABI, functionName: "withdraw", args: [amount] });
188
+ return {
189
+ provider: "wrap",
190
+ intentId: `wrap:${chainId}`,
191
+ depositAddress: "",
192
+ depositMemo: null,
193
+ txRequest: { to: w.address, data, value: wrap ? amount.toString() : "0", chainId, gasLimit: GAS_LIMIT },
194
+ sourceAmount: amount.toString(),
195
+ destAmount: amount.toString(),
196
+ minDestAmount: amount.toString(),
197
+ feeUsd: 0,
198
+ etaSeconds: 15,
199
+ reliability: 0.995,
200
+ validUntilMs: Date.now() + 5 * 6e4,
201
+ providerData: { action: wrap ? "wrap" : "unwrap", token: w.address }
202
+ };
203
+ },
204
+ async buildDeposit(quote) {
205
+ const tx = quote.txRequest;
206
+ if (!tx?.to || !tx.data) throw new Error("swap2: wrap quote has no transaction request");
207
+ return { chain: "", to: tx.to, value: tx.value ?? "0", data: tx.data, ...tx.chainId !== void 0 ? { chainId: tx.chainId } : {}, ...tx.gasLimit ? { gasLimit: tx.gasLimit } : {} };
208
+ },
209
+ async trackIntent(ref) {
210
+ if (!ref.sourceTxHash) return { state: "pending" };
211
+ const chainId = Number(ref.intentId.split(":")[1]);
212
+ if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return { state: "pending" };
213
+ try {
214
+ const receipt = await rpc(chainId, "eth_getTransactionReceipt", [ref.sourceTxHash]);
215
+ if (!receipt) return { state: "pending" };
216
+ return receipt.status === "0x1" ? { state: "completed", destTxHash: ref.sourceTxHash } : { state: "failed" };
217
+ } catch {
218
+ return { state: "pending" };
219
+ }
220
+ }
221
+ };
222
+ }
223
+
224
+ // src/protocol.ts
225
+ var WrapSwap2Protocol = class extends import_single.SingleProviderSwap2 {
226
+ provider;
227
+ _rpcUrls;
228
+ _wrapped;
229
+ constructor(account, config) {
230
+ super(account, config);
231
+ this.provider = wrapProvider(config);
232
+ this._rpcUrls = config.rpcUrls ?? {};
233
+ this._wrapped = config.wrapped ?? WRAPPED_NATIVE;
234
+ }
235
+ chainSupported(caip2) {
236
+ return (0, import_util3.isEvm)(caip2) && !!this._wrapped[(0, import_util3.evmRef)(caip2)] && !!this._rpcUrls[(0, import_util3.evmRef)(caip2)]?.length;
237
+ }
238
+ pairSupported(fromChain, toChain) {
239
+ return fromChain === toChain && this.chainSupported(fromChain);
240
+ }
241
+ };
242
+ //# sourceMappingURL=protocol.cjs.map
@@ -0,0 +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 {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 * 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"]}
@@ -0,0 +1,18 @@
1
+ import * as _anywalletkit_protocol_swap2_core_types from '@anywalletkit/protocol-swap2-core/types';
2
+ import { SingleProviderSwap2 } from '@anywalletkit/protocol-swap2-core/swap2/single';
3
+ import { Swap2Account, Swap2EngineConfig } from '@anywalletkit/protocol-swap2-core/swap2/base';
4
+ import { WrapProviderConfig } from './provider.cjs';
5
+
6
+ interface WrapSwap2Config extends Swap2EngineConfig, WrapProviderConfig {
7
+ }
8
+ /** Wrap / unwrap the native coin on one account (ETH ↔ WETH and friends). */
9
+ declare class WrapSwap2Protocol extends SingleProviderSwap2 {
10
+ protected readonly provider: _anywalletkit_protocol_swap2_core_types.CrossChainProvider;
11
+ private readonly _rpcUrls;
12
+ private readonly _wrapped;
13
+ constructor(account: Swap2Account | undefined, config: WrapSwap2Config);
14
+ protected chainSupported(caip2: string): boolean;
15
+ protected pairSupported(fromChain: string, toChain: string): boolean;
16
+ }
17
+
18
+ export { type WrapSwap2Config, WrapSwap2Protocol };
@@ -0,0 +1,18 @@
1
+ import * as _anywalletkit_protocol_swap2_core_types from '@anywalletkit/protocol-swap2-core/types';
2
+ import { SingleProviderSwap2 } from '@anywalletkit/protocol-swap2-core/swap2/single';
3
+ import { Swap2Account, Swap2EngineConfig } from '@anywalletkit/protocol-swap2-core/swap2/base';
4
+ import { WrapProviderConfig } from './provider.js';
5
+
6
+ interface WrapSwap2Config extends Swap2EngineConfig, WrapProviderConfig {
7
+ }
8
+ /** Wrap / unwrap the native coin on one account (ETH ↔ WETH and friends). */
9
+ declare class WrapSwap2Protocol extends SingleProviderSwap2 {
10
+ protected readonly provider: _anywalletkit_protocol_swap2_core_types.CrossChainProvider;
11
+ private readonly _rpcUrls;
12
+ private readonly _wrapped;
13
+ constructor(account: Swap2Account | undefined, config: WrapSwap2Config);
14
+ protected chainSupported(caip2: string): boolean;
15
+ protected pairSupported(fromChain: string, toChain: string): boolean;
16
+ }
17
+
18
+ export { type WrapSwap2Config, WrapSwap2Protocol };
@@ -0,0 +1,8 @@
1
+ import {
2
+ WrapSwap2Protocol
3
+ } from "./chunk-ATKZPIBU.js";
4
+ import "./chunk-AVEVP6OU.js";
5
+ export {
6
+ WrapSwap2Protocol
7
+ };
8
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/provider.ts
21
+ var provider_exports = {};
22
+ __export(provider_exports, {
23
+ WRAPPED_NATIVE: () => WRAPPED_NATIVE,
24
+ wrapProvider: () => wrapProvider
25
+ });
26
+ module.exports = __toCommonJS(provider_exports);
27
+ var import_viem = require("viem");
28
+
29
+ // src/activity.ts
30
+ var import_activity = require("@anywalletkit/protocol-swap2-core/activity");
31
+ var import_util = require("@anywalletkit/protocol-swap2-core/util");
32
+ var WRAP_MODULE = "@anywalletkit/protocol-swap2-wrap";
33
+ var WETH_DEPOSIT = "0xd0e30db0";
34
+ var WETH_WITHDRAW = "0x2e1a7d4d";
35
+ function describeWrapActivity(tx, ctx, wrapped = WRAPPED_NATIVE) {
36
+ if (!(0, import_util.isEvm)(tx.chain)) return null;
37
+ const w = wrapped[(0, import_util.evmRef)(tx.chain)];
38
+ if (!w) return null;
39
+ const isDeposit = (0, import_activity.matchesCall)(tx, [w.address], [WETH_DEPOSIT]);
40
+ const isWithdraw = !isDeposit && (0, import_activity.matchesCall)(tx, [w.address], [WETH_WITHDRAW]);
41
+ if (!isDeposit && !isWithdraw) return null;
42
+ const { assetsIn, assetsOut } = (0, import_activity.ownerAssets)(tx, ctx);
43
+ const native = [...assetsIn, ...assetsOut].find((a) => a.token === null);
44
+ const nativeLabel = native ? (0, import_activity.assetLabel)(tx, native) : w.symbol.replace(/^[Ww]/, "");
45
+ return (0, import_activity.describeSwapLike)(tx, ctx, {
46
+ protocol: WRAP_MODULE,
47
+ subtitle: w.symbol,
48
+ kind: isDeposit ? "wrap" : "unwrap",
49
+ title: isDeposit ? `Wrapped ${nativeLabel}` : `Unwrapped ${w.symbol}`
50
+ });
51
+ }
52
+
53
+ // src/provider.ts
54
+ var import_swap2_assets = require("@anywalletkit/swap2-assets");
55
+ var import_util2 = require("@anywalletkit/protocol-swap2-core/util");
56
+ var WRAPPED_NATIVE = Object.freeze({
57
+ 1: { address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", symbol: "WETH" },
58
+ 10: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
59
+ 56: { address: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", symbol: "WBNB" },
60
+ 100: { address: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", symbol: "WXDAI" },
61
+ 130: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
62
+ 137: { address: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", symbol: "WPOL" },
63
+ 143: { address: "0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A", symbol: "WMON" },
64
+ 999: { address: "0x5555555555555555555555555555555555555555", symbol: "WHYPE" },
65
+ 324: { address: "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91", symbol: "WETH" },
66
+ 4326: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
67
+ 9745: { address: "0x6100E367285b01F48D07953803A2d8dCA5D19873", symbol: "WXPL" },
68
+ 146: { address: "0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38", symbol: "wS" },
69
+ 59144: { address: "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f", symbol: "WETH" },
70
+ 8453: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
71
+ 42161: { address: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", symbol: "WETH" },
72
+ 43114: { address: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", symbol: "WAVAX" },
73
+ 80094: { address: "0x6969696969696969696969696969696969696969", symbol: "WBERA" },
74
+ 534352: { address: "0x5300000000000000000000000000000000000004", symbol: "WETH" },
75
+ // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer — verified on-chain (symbol, decimals, supply, deposit()).
76
+ 480: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
77
+ 1329: { address: "0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7", symbol: "WSEI" },
78
+ 57073: { address: "0x4200000000000000000000000000000000000006", symbol: "WETH" },
79
+ 98866: { address: "0xEa237441c92CAe6FC17Caaf9a7acB3f953be4bd1", symbol: "WPLUME" },
80
+ 196: { address: "0xe538905cf8410324e03A5A23C1c177a474D59b2b", symbol: "WOKB" },
81
+ // 2026-10-14: Mantle, Katana, Morph, Flare — symbol, 18 decimals, supply, deposit()/withdraw() selectors in the
82
+ // bytecode and eth_estimateGas of deposit() with value from a funded sender, all checked on-chain. Katana's WETH9 is
83
+ // Vault Bridge's vbETH (the on-chain symbol the verify step compares against; the catalog shows it as WETH).
84
+ // Arc has no wrapper by design: its native USDC already exposes an ERC-20 interface (docs.arc.network).
85
+ 5e3: { address: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8", symbol: "WMNT" },
86
+ 747474: { address: "0xEE7D8BCFb72bC1880D0Cf19822eB0A2e6577aB62", symbol: "vbETH" },
87
+ 2818: { address: "0x5300000000000000000000000000000000000011", symbol: "WETH" },
88
+ 14: { address: "0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d", symbol: "WFLR" }
89
+ });
90
+ var WETH_ABI = (0, import_viem.parseAbi)([
91
+ "function deposit() payable",
92
+ "function withdraw(uint256 wad)",
93
+ "function symbol() view returns (string)",
94
+ "function decimals() view returns (uint8)"
95
+ ]);
96
+ var GAS_LIMIT = "90000";
97
+ function wrapProvider(config) {
98
+ const wrapped = config.wrapped ?? WRAPPED_NATIVE;
99
+ const verified = /* @__PURE__ */ new Map();
100
+ const chainIdOf = (caip2) => {
101
+ if (!(0, import_util2.isEvm)(caip2)) return null;
102
+ const id = (0, import_util2.evmRef)(caip2);
103
+ return wrapped[id] && config.rpcUrls[id]?.length ? id : null;
104
+ };
105
+ async function rpc(chainId, method, params) {
106
+ let lastErr;
107
+ for (const url of config.rpcUrls[chainId] ?? []) {
108
+ try {
109
+ const res = await fetch(url, {
110
+ method: "POST",
111
+ headers: { "content-type": "application/json" },
112
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
113
+ signal: (0, import_util2.timeoutSignal)(1e4)
114
+ });
115
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
116
+ const body = await res.json();
117
+ if (body.error) throw new Error(body.error.message ?? "rpc error");
118
+ return body.result ?? null;
119
+ } catch (e) {
120
+ lastErr = e;
121
+ }
122
+ }
123
+ throw new Error(`wrap: no RPC answered on chain ${chainId} (${lastErr instanceof Error ? lastErr.message : String(lastErr)})`);
124
+ }
125
+ function verify(chainId) {
126
+ let p = verified.get(chainId);
127
+ if (!p) {
128
+ const w = wrapped[chainId];
129
+ p = (async () => {
130
+ const read = async (fn) => (0, import_viem.decodeFunctionResult)({ abi: WETH_ABI, functionName: fn, data: await rpc(chainId, "eth_call", [{ to: w.address, data: (0, import_viem.encodeFunctionData)({ abi: WETH_ABI, functionName: fn }) }, "latest"]) });
131
+ const [symbol, decimals] = await Promise.all([read("symbol"), read("decimals")]);
132
+ if (symbol !== w.symbol || Number(decimals) !== 18) throw new Error(`wrap: ${w.address} on chain ${chainId} is not ${w.symbol} \u2014 refusing`);
133
+ })();
134
+ p.catch(() => verified.delete(chainId));
135
+ verified.set(chainId, p);
136
+ }
137
+ return p;
138
+ }
139
+ return {
140
+ name: "wrap",
141
+ describeActivity: (tx, ctx) => describeWrapActivity(tx, ctx, wrapped),
142
+ supportsSameChain: true,
143
+ enabled: () => config.enabled ?? true,
144
+ supportsChain: (caip2) => chainIdOf(caip2) !== null,
145
+ supportsChainPair: (from, to) => from === to && chainIdOf(from) !== null,
146
+ supportsRoute(from, to) {
147
+ return from.chain === to.chain && chainIdOf(from.chain) !== null;
148
+ },
149
+ async getQuote(params) {
150
+ const refuse = (why) => {
151
+ params.onRefusal?.(`wrap: ${why}`);
152
+ return null;
153
+ };
154
+ if (params.flex) return refuse("amount-flexible deposits are not supported");
155
+ if (params.sourceChain !== params.destChain) return refuse("same-chain only");
156
+ const chainId = chainIdOf(params.sourceChain);
157
+ if (chainId === null) return refuse(`no wrapped native token or RPC for ${params.sourceChain}`);
158
+ const w = wrapped[chainId];
159
+ const src = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
160
+ if (!src) return refuse(`unknown source token ${params.sourceToken}`);
161
+ const nativeIn = !src.contract;
162
+ 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);
163
+ const nativeOut = /^0x0+$/.test(params.destToken);
164
+ const destIsWrapped = /^0x[0-9a-fA-F]{40}$/.test(params.destToken) && !nativeOut && (0, import_viem.getAddress)(params.destToken) === (0, import_viem.getAddress)(w.address);
165
+ const wrap = nativeIn && destIsWrapped;
166
+ const unwrap = srcIsWrapped && nativeOut;
167
+ if (!wrap && !unwrap) return refuse(`only ${w.symbol.slice(1)} \u2194 ${w.symbol}`);
168
+ if (params.refundAddress && /^0x[0-9a-fA-F]{40}$/.test(params.refundAddress) && (0, import_viem.getAddress)(params.refundAddress) !== (0, import_viem.getAddress)(params.destAddress)) {
169
+ return refuse("wrapping pays the sender's own address \u2014 send the result separately");
170
+ }
171
+ let amount;
172
+ try {
173
+ amount = BigInt(params.amountIn);
174
+ } catch {
175
+ return refuse("amount is not an integer");
176
+ }
177
+ if (amount <= 0n) return refuse("amount must be positive");
178
+ if (params.minAmountOut !== void 0 && amount < BigInt(params.minAmountOut)) return refuse(`floor breach (min=${amount} < floor=${params.minAmountOut})`);
179
+ try {
180
+ await verify(chainId);
181
+ } catch (e) {
182
+ return refuse(e instanceof Error ? e.message.replace(/^wrap: /, "") : String(e));
183
+ }
184
+ const data = wrap ? (0, import_viem.encodeFunctionData)({ abi: WETH_ABI, functionName: "deposit" }) : (0, import_viem.encodeFunctionData)({ abi: WETH_ABI, functionName: "withdraw", args: [amount] });
185
+ return {
186
+ provider: "wrap",
187
+ intentId: `wrap:${chainId}`,
188
+ depositAddress: "",
189
+ depositMemo: null,
190
+ txRequest: { to: w.address, data, value: wrap ? amount.toString() : "0", chainId, gasLimit: GAS_LIMIT },
191
+ sourceAmount: amount.toString(),
192
+ destAmount: amount.toString(),
193
+ minDestAmount: amount.toString(),
194
+ feeUsd: 0,
195
+ etaSeconds: 15,
196
+ reliability: 0.995,
197
+ validUntilMs: Date.now() + 5 * 6e4,
198
+ providerData: { action: wrap ? "wrap" : "unwrap", token: w.address }
199
+ };
200
+ },
201
+ async buildDeposit(quote) {
202
+ const tx = quote.txRequest;
203
+ if (!tx?.to || !tx.data) throw new Error("swap2: wrap quote has no transaction request");
204
+ return { chain: "", to: tx.to, value: tx.value ?? "0", data: tx.data, ...tx.chainId !== void 0 ? { chainId: tx.chainId } : {}, ...tx.gasLimit ? { gasLimit: tx.gasLimit } : {} };
205
+ },
206
+ async trackIntent(ref) {
207
+ if (!ref.sourceTxHash) return { state: "pending" };
208
+ const chainId = Number(ref.intentId.split(":")[1]);
209
+ if (!wrapped[chainId] || !config.rpcUrls[chainId]?.length) return { state: "pending" };
210
+ try {
211
+ const receipt = await rpc(chainId, "eth_getTransactionReceipt", [ref.sourceTxHash]);
212
+ if (!receipt) return { state: "pending" };
213
+ return receipt.status === "0x1" ? { state: "completed", destTxHash: ref.sourceTxHash } : { state: "failed" };
214
+ } catch {
215
+ return { state: "pending" };
216
+ }
217
+ }
218
+ };
219
+ }
220
+ //# sourceMappingURL=provider.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/provider.ts","../src/activity.ts"],"sourcesContent":["import {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 * 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"]}