@anywalletkit/protocol-swap2-curve 0.0.0-stage → 0.1.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.
@@ -0,0 +1,390 @@
1
+ import { C as CurveRouterFamily, a as CurveDeployment } from './deployments-D4pk2tPy.cjs';
2
+ export { b as CRVUSD_ETHEREUM, c as CURVE_DENIED_POOLS, d as CURVE_DEPLOYMENTS, e as CURVE_ETH, f as CURVE_LEGACY_ROUTERS, M as MAX_ROUTE_POOLS, g as MAX_ROUTE_STEPS, S as SCRVUSD, Z as ZERO_ADDRESS, h as chainIdOf, i as deploymentOf } from './deployments-D4pk2tPy.cjs';
3
+ import { Hex } from 'viem';
4
+ import { C as CurvePool, a as CurveChainPools } from './provider-B_n93qi8.cjs';
5
+ export { b as CurveProviderConfig, c as curveProvider } from './provider-B_n93qi8.cjs';
6
+ import { Quote, UnsignedTx, RemotePins, QuoteParams } from '@anywalletkit/protocol-swap2-core/types';
7
+ export { CURVE_MODULE, describeCurveActivity } from './activity.cjs';
8
+ export { CurveSwap2Config, CurveSwap2Protocol, CurveSwap2Protocol as default } from './protocol.cjs';
9
+ import '@anywalletkit/core';
10
+ import '@anywalletkit/protocol-swap2-core/swap2/single';
11
+ import '@anywalletkit/protocol-swap2-core/swap2/base';
12
+
13
+ /**
14
+ * Router NG entry points, both ABI families (selectors with `viem toFunctionSelector`, checked against every pinned
15
+ * router's code 2026-11-05). This module writes only the explicit-receiver `exchange` of each family and reads
16
+ * `get_dy`; the other forms are listed for history recognition.
17
+ */
18
+ declare const ROUTER_NG5_ABI: readonly [{
19
+ readonly name: "exchange";
20
+ readonly type: "function";
21
+ readonly stateMutability: "payable";
22
+ readonly inputs: readonly [{
23
+ readonly type: "address[11]";
24
+ readonly name: "_route";
25
+ }, {
26
+ readonly type: "uint256[5][5]";
27
+ readonly name: "_swap_params";
28
+ }, {
29
+ readonly type: "uint256";
30
+ readonly name: "_amount";
31
+ }, {
32
+ readonly type: "uint256";
33
+ readonly name: "_min_dy";
34
+ }];
35
+ readonly outputs: readonly [{
36
+ readonly type: "uint256";
37
+ }];
38
+ }, {
39
+ readonly name: "exchange";
40
+ readonly type: "function";
41
+ readonly stateMutability: "payable";
42
+ readonly inputs: readonly [{
43
+ readonly type: "address[11]";
44
+ readonly name: "_route";
45
+ }, {
46
+ readonly type: "uint256[5][5]";
47
+ readonly name: "_swap_params";
48
+ }, {
49
+ readonly type: "uint256";
50
+ readonly name: "_amount";
51
+ }, {
52
+ readonly type: "uint256";
53
+ readonly name: "_min_dy";
54
+ }, {
55
+ readonly type: "address[5]";
56
+ readonly name: "_pools";
57
+ }];
58
+ readonly outputs: readonly [{
59
+ readonly type: "uint256";
60
+ }];
61
+ }, {
62
+ readonly name: "exchange";
63
+ readonly type: "function";
64
+ readonly stateMutability: "payable";
65
+ readonly inputs: readonly [{
66
+ readonly type: "address[11]";
67
+ readonly name: "_route";
68
+ }, {
69
+ readonly type: "uint256[5][5]";
70
+ readonly name: "_swap_params";
71
+ }, {
72
+ readonly type: "uint256";
73
+ readonly name: "_amount";
74
+ }, {
75
+ readonly type: "uint256";
76
+ readonly name: "_min_dy";
77
+ }, {
78
+ readonly type: "address[5]";
79
+ readonly name: "_pools";
80
+ }, {
81
+ readonly type: "address";
82
+ readonly name: "_receiver";
83
+ }];
84
+ readonly outputs: readonly [{
85
+ readonly type: "uint256";
86
+ }];
87
+ }, {
88
+ readonly name: "get_dy";
89
+ readonly type: "function";
90
+ readonly stateMutability: "view";
91
+ readonly inputs: readonly [{
92
+ readonly type: "address[11]";
93
+ readonly name: "_route";
94
+ }, {
95
+ readonly type: "uint256[5][5]";
96
+ readonly name: "_swap_params";
97
+ }, {
98
+ readonly type: "uint256";
99
+ readonly name: "_amount";
100
+ }];
101
+ readonly outputs: readonly [{
102
+ readonly type: "uint256";
103
+ }];
104
+ }, {
105
+ readonly name: "version";
106
+ readonly type: "function";
107
+ readonly stateMutability: "view";
108
+ readonly inputs: readonly [];
109
+ readonly outputs: readonly [{
110
+ readonly type: "string";
111
+ }];
112
+ }];
113
+ declare const ROUTER_LITE4_ABI: readonly [{
114
+ readonly name: "exchange";
115
+ readonly type: "function";
116
+ readonly stateMutability: "payable";
117
+ readonly inputs: readonly [{
118
+ readonly type: "address[11]";
119
+ readonly name: "_route";
120
+ }, {
121
+ readonly type: "uint256[4][5]";
122
+ readonly name: "_swap_params";
123
+ }, {
124
+ readonly type: "uint256";
125
+ readonly name: "_amount";
126
+ }, {
127
+ readonly type: "uint256";
128
+ readonly name: "_min_dy";
129
+ }];
130
+ readonly outputs: readonly [{
131
+ readonly type: "uint256";
132
+ }];
133
+ }, {
134
+ readonly name: "exchange";
135
+ readonly type: "function";
136
+ readonly stateMutability: "payable";
137
+ readonly inputs: readonly [{
138
+ readonly type: "address[11]";
139
+ readonly name: "_route";
140
+ }, {
141
+ readonly type: "uint256[4][5]";
142
+ readonly name: "_swap_params";
143
+ }, {
144
+ readonly type: "uint256";
145
+ readonly name: "_amount";
146
+ }, {
147
+ readonly type: "uint256";
148
+ readonly name: "_min_dy";
149
+ }, {
150
+ readonly type: "address";
151
+ readonly name: "_receiver";
152
+ }];
153
+ readonly outputs: readonly [{
154
+ readonly type: "uint256";
155
+ }];
156
+ }, {
157
+ readonly name: "get_dy";
158
+ readonly type: "function";
159
+ readonly stateMutability: "view";
160
+ readonly inputs: readonly [{
161
+ readonly type: "address[11]";
162
+ readonly name: "_route";
163
+ }, {
164
+ readonly type: "uint256[4][5]";
165
+ readonly name: "_swap_params";
166
+ }, {
167
+ readonly type: "uint256";
168
+ readonly name: "_amount";
169
+ }];
170
+ readonly outputs: readonly [{
171
+ readonly type: "uint256";
172
+ }];
173
+ }, {
174
+ readonly name: "version";
175
+ readonly type: "function";
176
+ readonly stateMutability: "view";
177
+ readonly inputs: readonly [];
178
+ readonly outputs: readonly [{
179
+ readonly type: "string";
180
+ }];
181
+ }];
182
+ declare const VERSION_ABI: readonly [{
183
+ readonly name: "version";
184
+ readonly type: "function";
185
+ readonly stateMutability: "view";
186
+ readonly inputs: readonly [];
187
+ readonly outputs: readonly [{
188
+ readonly type: "string";
189
+ }];
190
+ }];
191
+ /** `coins(uint256)` (every NG pool and most plain ones) and `coins(int128)` (the oldest stable pools). */
192
+ declare const COINS_UINT: Hex;
193
+ declare const COINS_INT: Hex;
194
+ declare const ADDRESS_PROVIDER_ABI: readonly [{
195
+ readonly name: "get_address";
196
+ readonly type: "function";
197
+ readonly stateMutability: "view";
198
+ readonly inputs: readonly [{
199
+ readonly type: "uint256";
200
+ readonly name: "_id";
201
+ }];
202
+ readonly outputs: readonly [{
203
+ readonly type: "address";
204
+ }];
205
+ }];
206
+ /** The `exchange` this module builds: with an explicit receiver. */
207
+ declare const EXCHANGE_SELECTOR: Readonly<Record<CurveRouterFamily, Hex>>;
208
+ declare const GET_DY_SELECTOR: Readonly<Record<CurveRouterFamily, Hex>>;
209
+ /** Every swap entry point per family, for history: `[5][5]` 4-, 5- and 6-argument forms; `[4][5]` 4- and 5-argument. */
210
+ declare const ROUTER_SELECTORS: Readonly<Record<CurveRouterFamily, ReadonlySet<string>>>;
211
+ /** topic0 of the router's `Exchange` event per family (`[5][5]` logs `pools` too). */
212
+ declare const EXCHANGE_TOPIC: Readonly<Record<CurveRouterFamily, Hex>>;
213
+ /** A route as the router takes it: 11 addresses and one swap-params row per step (5 rows; 5 or 4 columns). */
214
+ interface RouterArgs {
215
+ route: readonly Hex[];
216
+ params: readonly (readonly bigint[])[];
217
+ }
218
+ /** One router call, decoded. `receiver` is null when the call names none (the router then pays `msg.sender`). */
219
+ interface DecodedExchange extends RouterArgs {
220
+ amount: bigint;
221
+ minDy: bigint;
222
+ pools: readonly Hex[] | null;
223
+ receiver: Hex | null;
224
+ selector: Hex;
225
+ }
226
+ /** `exchange(route, params, amount, minDy, [zero pools,] receiver)` for the router family. */
227
+ declare function encodeExchange(family: CurveRouterFamily, args: RouterArgs, amount: bigint, minDy: bigint, receiver: Hex): Hex;
228
+ /** `get_dy(route, params, amount)` for the router family. */
229
+ declare function encodeGetDy(family: CurveRouterFamily, args: RouterArgs, amount: bigint): Hex;
230
+ /** Any of the family's `exchange` forms, decoded; null for anything else (another selector, malformed data). */
231
+ declare function decodeExchange(family: CurveRouterFamily, data: string): DecodedExchange | null;
232
+
233
+ /** One router step: a pool swap, the native ↔ wrapped-native hop (8) or the ERC-4626 hop (9). */
234
+ type CurveStep = {
235
+ kind: "pool";
236
+ pool: CurvePool;
237
+ swapType: 1 | 2;
238
+ i: number;
239
+ j: number;
240
+ tokenIn: Hex;
241
+ tokenOut: Hex;
242
+ } | {
243
+ kind: "wrap";
244
+ weth: Hex;
245
+ tokenIn: Hex;
246
+ tokenOut: Hex;
247
+ } | {
248
+ kind: "erc4626";
249
+ vault: Hex;
250
+ deposit: boolean;
251
+ tokenIn: Hex;
252
+ tokenOut: Hex;
253
+ };
254
+ interface CurveRoute {
255
+ steps: readonly CurveStep[];
256
+ /** Human description for the review / logs, e.g. "3pool", "wrap → TricryptoUSDT". */
257
+ label: string;
258
+ }
259
+ /** Most candidate routes priced for one quote (three JSON-RPC batches of ten). */
260
+ declare const MAX_QUOTE_CANDIDATES = 30;
261
+ /**
262
+ * Whether a route may hand the swap through `token` between two hops on `chainId`: the router's native sentinel, the
263
+ * pinned wrapped native, or a token the swap2-assets catalog lists on that chain, matched by address. The source and
264
+ * the destination follow the engine's listed / unlisted token policy instead (as for every provider).
265
+ */
266
+ declare function intermediateAllowed(chainId: number, deployment: CurveDeployment, token: string): boolean;
267
+ /**
268
+ * Whether `exchange_underlying` (swap_type 2) may run on `pool`, given the chain's allowlisted pools `index`: only on a
269
+ * metapool that names its base pool, with that base pool itself allowlisted (and not denied), and `underlying` the
270
+ * meta coins followed by the base pool's coins. Never on a lending pool (no base pool): its underlying route deposits
271
+ * into the lending venue, which a `get_dy` view never touches (Aave v2 on Polygon has every reserve frozen).
272
+ */
273
+ declare function underlyingAllowed(pool: CurvePool, index: ReadonlyMap<string, CurvePool>): boolean;
274
+ /** Pool types the router family can execute: `[4][5]` routers speak only to NG pools (stable-ng, twocrypto-ng, tricrypto-ng). */
275
+ declare function poolTypeAllowed(family: CurveDeployment["family"], poolType: number): boolean;
276
+ /** Allowlisted pools by address (lowercase), denied pools left out. */
277
+ declare function poolIndex(chainId: number, deployment: CurveDeployment, table: CurveChainPools | undefined): Map<string, CurvePool>;
278
+ /**
279
+ * Candidate routes tokenIn → tokenOut: at most {@link MAX_ROUTE_POOLS} pools and {@link MAX_ROUTE_STEPS} steps, no
280
+ * token or pool twice, at most one wrap and one ERC-4626 hop. Ranked fewest pools first, then by the thinnest pool's
281
+ * TVL, and cut to `limit`. `truncated` says the cut (or the search budget) dropped some.
282
+ */
283
+ declare function findRoutes(chainId: number, deployment: CurveDeployment, table: CurveChainPools | undefined, tokenIn: Hex, tokenOut: Hex, limit?: number): {
284
+ routes: CurveRoute[];
285
+ truncated: boolean;
286
+ };
287
+ /** The router's `_route` / `_swap_params` for a route, in the deployment's ABI family. */
288
+ declare function routeArgs(family: CurveDeployment["family"], route: CurveRoute): RouterArgs;
289
+ /** Pool addresses a route's router arguments cross, in order. */
290
+ declare function routePools(args: RouterArgs): Hex[];
291
+ /**
292
+ * Whether router arguments are a route this module would build on `chainId`: from `tokenIn` to `tokenOut`, every pool
293
+ * hop through an allowlisted (and not denied) pool whose pinned coins at `i`/`j` are the hop's tokens, with the pool's
294
+ * own pool type, an allowed swap type (1, or 2 for a metapool listing it whose base pool is allowlisted too) and its
295
+ * coin count; every token between two hops a catalog token, the native coin or the pinned wrapped native; swap_type 8 only through
296
+ * the pinned wrapped native between it and the native sentinel; swap_type 9 only on a v1.2 router through its pinned
297
+ * ERC-4626 vault; no other swap type; at most {@link MAX_ROUTE_POOLS} pools, {@link MAX_ROUTE_STEPS} steps, no pool
298
+ * twice, and nothing after the route's end. The reason it is not, or null.
299
+ */
300
+ declare function checkRoute(chainId: number, deployment: CurveDeployment, table: CurveChainPools | undefined, args: RouterArgs, tokenIn: string, tokenOut: string): string | null;
301
+
302
+ type RpcCall = {
303
+ method: string;
304
+ params: unknown[];
305
+ };
306
+
307
+ interface CurveTables {
308
+ /** Override the deployments (tests). */
309
+ deployments?: Readonly<Record<number, CurveDeployment>>;
310
+ /** Override the pool allowlist (tests). */
311
+ pools?: Readonly<Record<number, CurveChainPools>>;
312
+ }
313
+ /**
314
+ * The check of a Curve quote's router call against the app's own request, with the tables it uses. The returned
315
+ * function is {@link curveVerifyQuote} for the shipped tables: synchronous, no I/O — the allowlist is static.
316
+ */
317
+ declare function curveQuoteCheck(tables?: CurveTables): (params: QuoteParams, quote: Quote) => string | null;
318
+ /**
319
+ * The swap a Curve quote's router call makes, opened on the client against the app's own request: the explicit-receiver
320
+ * `exchange` on the chain's pinned Router NG (`0xc872a3c5` on `[5][5]` routers, `0xfd44959c` on `[4][5]`), selling
321
+ * exactly the input of the source token (the router's native sentinel for a native input, paid as exactly that
322
+ * `value`; a token input attaches no value and approves exactly the router), for the destination token, with
323
+ * `min_dy` the quote's minimum (never 0), paid to the recipient, no zap pools, and a route that `checkRoute` accepts:
324
+ * allowlisted pools only, their pinned coins, swap types 1/2 (8 through the pinned wrapped native, 9 only on router
325
+ * v1.2 through scrvUSD). The reason it fails, or null.
326
+ */
327
+ declare const curveVerifyQuote: (params: QuoteParams, quote: Quote) => string | null;
328
+ /**
329
+ * The Router NG a Curve swap calls and approves on a chain (the shipped {@link CURVE_DEPLOYMENTS} table), and
330
+ * {@link curveVerifyQuote} — the app's pins for `remoteProvider({name: "curve", baseUrl, ...curvePins})`. For the build
331
+ * checked on chain as well (router code hash, fresh `get_dy`, pool coins), use {@link curveRemotePins}.
332
+ */
333
+ declare const curvePins: RemotePins;
334
+ interface CurveOnChainOptions extends CurveTables {
335
+ rpcUrls: Readonly<Record<number, readonly string[]>>;
336
+ /** Told when the chain's AddressProvider lists another router than the pinned one (never acted on). Default console.warn. */
337
+ onWarning?: (message: string) => void;
338
+ }
339
+ /**
340
+ * On-chain checks shared by the provider and {@link curveRemotePins}: the pinned router's code hash and version (once
341
+ * per chain; the AddressProvider's id 2 only compared), and a sealed quote re-checked right before broadcast.
342
+ */
343
+ declare function curveOnChain(opts: CurveOnChainOptions): {
344
+ rpc: (chainId: number, calls: RpcCall[], signal?: AbortSignal) => Promise<(unknown | null)[]>;
345
+ verifyDeployment: (chainId: number) => Promise<void>;
346
+ checkSealed: (quote: Quote, tx: UnsignedTx) => Promise<string | null>;
347
+ inspectSealed: (quote: Quote, tx: UnsignedTx, probe: boolean) => Promise<string | {
348
+ out: bigint;
349
+ probeOut: bigint | null;
350
+ amount: bigint;
351
+ minDy: bigint;
352
+ }>;
353
+ };
354
+ /**
355
+ * How far the device's own auto slippage may sit under the backend's before a remote build's minimum counts as too low:
356
+ * the backend sized it from its probe at quote time, the device from a fresh one, and half the impact moves it.
357
+ */
358
+ declare const CURVE_AUTO_SLIPPAGE_DRIFT_BPS = 5;
359
+ interface CurveRemotePinsOptions extends CurveOnChainOptions {
360
+ /** The backend provider's `defaultSlippageBps`, when it sets one (a build's minimum is bounded by it). Default: auto slippage. */
361
+ defaultSlippageBps?: number;
362
+ }
363
+ /**
364
+ * {@link curvePins} plus `verifyBuild`: a remote Curve build checked on the client — {@link curveVerifyQuote} on the
365
+ * request it answered, then on chain (over the app's own RPCs) the pinned router (code and version, once per chain),
366
+ * each hop pool's pinned code and coins, and a fresh `get_dy` of the exact route at or above the minimum. The quote's
367
+ * figures are then held to that fresh `get_dy` (§5.3 C9: the minimum is the device's own): `destAmount` no more than the
368
+ * slippage above it, and `min_dy` no more than the slippage below it (or below `destAmount`, if lower) — the request's
369
+ * `slippageBps`, else `defaultSlippageBps`, else the provider's auto slippage re-derived here from a fresh 1/1000 probe
370
+ * (plus {@link CURVE_AUTO_SLIPPAGE_DRIFT_BPS}). A backend naming `min_dy = 1` or an inflated output is refused.
371
+ * `remoteProvider({name: "curve", baseUrl, ...curveRemotePins({rpcUrls})})`.
372
+ */
373
+ declare function curveRemotePins(opts: CurveRemotePinsOptions): RemotePins & {
374
+ verifyBuild(quote: Quote, tx: UnsignedTx, params?: QuoteParams): Promise<string | null>;
375
+ };
376
+
377
+ /**
378
+ * Labels for the contracts a Curve swap touches on `chainId`, for tx-preview's `known` (address → label): the pinned
379
+ * Router NG (and Ethereum's older routers, so history reads), every allowlisted pool, the wrapped native the router's
380
+ * wrap hop uses and, on Ethereum, the scrvUSD vault. Empty for a chain without a pinned router.
381
+ */
382
+ declare function curveKnownContracts(chainId: number, tables?: {
383
+ deployments?: Readonly<Record<number, CurveDeployment>>;
384
+ pools?: Readonly<Record<number, CurveChainPools>>;
385
+ }): Record<string, string>;
386
+
387
+ /** Curated Curve pools per chain id. A chain missing here has no pool that passed the rules. */
388
+ declare const CURVE_POOLS: Readonly<Record<number, CurveChainPools>>;
389
+
390
+ export { ADDRESS_PROVIDER_ABI, COINS_INT, COINS_UINT, CURVE_AUTO_SLIPPAGE_DRIFT_BPS, CURVE_POOLS, CurveChainPools, CurveDeployment, type CurveOnChainOptions, CurvePool, type CurveRemotePinsOptions, type CurveRoute, CurveRouterFamily, type CurveStep, type CurveTables, type DecodedExchange, EXCHANGE_SELECTOR, EXCHANGE_TOPIC, GET_DY_SELECTOR, MAX_QUOTE_CANDIDATES, ROUTER_LITE4_ABI, ROUTER_NG5_ABI, ROUTER_SELECTORS, type RouterArgs, type RpcCall, VERSION_ABI, checkRoute, curveKnownContracts, curveOnChain, curvePins, curveQuoteCheck, curveRemotePins, curveVerifyQuote, decodeExchange, encodeExchange, encodeGetDy, findRoutes, intermediateAllowed, poolIndex, poolTypeAllowed, routeArgs, routePools, underlyingAllowed };