@nradko/metric-omm-sdk-v1 0.3.0 → 0.4.2

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.
Files changed (110) hide show
  1. package/README.md +98 -111
  2. package/dist/abis/MetricOmmPool.d.ts +14 -0
  3. package/dist/abis/MetricOmmPool.d.ts.map +1 -1
  4. package/dist/abis/MetricOmmPool.js +18 -0
  5. package/dist/abis/MetricOmmPool.js.map +1 -1
  6. package/dist/abis/MetricOmmPoolDataProvider.d.ts +0 -136
  7. package/dist/abis/MetricOmmPoolDataProvider.d.ts.map +1 -1
  8. package/dist/abis/MetricOmmPoolDataProvider.js +0 -177
  9. package/dist/abis/MetricOmmPoolDataProvider.js.map +1 -1
  10. package/dist/abis/MetricOmmPoolStateView.d.ts +238 -0
  11. package/dist/abis/MetricOmmPoolStateView.d.ts.map +1 -0
  12. package/dist/abis/MetricOmmPoolStateView.js +315 -0
  13. package/dist/abis/MetricOmmPoolStateView.js.map +1 -0
  14. package/dist/abis/MetricOmmSimpleRouter.d.ts +619 -0
  15. package/dist/abis/{MetricOmmPoolSwapper.d.ts.map → MetricOmmSimpleRouter.d.ts.map} +1 -1
  16. package/dist/abis/MetricOmmSimpleRouter.js +805 -0
  17. package/dist/abis/MetricOmmSimpleRouter.js.map +1 -0
  18. package/dist/abis/MetricOmmSwapQuoter.d.ts +576 -0
  19. package/dist/abis/{PriceProviderUi.d.ts.map → MetricOmmSwapQuoter.d.ts.map} +1 -1
  20. package/dist/abis/MetricOmmSwapQuoter.js +748 -0
  21. package/dist/abis/MetricOmmSwapQuoter.js.map +1 -0
  22. package/dist/abis/OracleProvider.d.ts +106 -0
  23. package/dist/abis/OracleProvider.d.ts.map +1 -0
  24. package/dist/abis/OracleProvider.js +62 -0
  25. package/dist/abis/OracleProvider.js.map +1 -0
  26. package/dist/abis/PriceProvider.d.ts +8 -2
  27. package/dist/abis/PriceProvider.d.ts.map +1 -1
  28. package/dist/abis/PriceProvider.js +9 -1
  29. package/dist/abis/PriceProvider.js.map +1 -1
  30. package/dist/abis/index.d.ts +4 -2
  31. package/dist/abis/index.d.ts.map +1 -1
  32. package/dist/abis/index.js +4 -2
  33. package/dist/abis/index.js.map +1 -1
  34. package/dist/addresses.d.ts +3 -3
  35. package/dist/addresses.d.ts.map +1 -1
  36. package/dist/addresses.js +10 -10
  37. package/dist/addresses.js.map +1 -1
  38. package/dist/constants.d.ts +4 -1
  39. package/dist/constants.d.ts.map +1 -1
  40. package/dist/constants.js +7 -2
  41. package/dist/constants.js.map +1 -1
  42. package/dist/index.d.ts +5 -3
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +8 -4
  45. package/dist/index.js.map +1 -1
  46. package/dist/oracle/index.d.ts +5 -0
  47. package/dist/oracle/index.d.ts.map +1 -0
  48. package/dist/oracle/index.js +5 -0
  49. package/dist/oracle/index.js.map +1 -0
  50. package/dist/oracle/registry.d.ts +53 -0
  51. package/dist/oracle/registry.d.ts.map +1 -0
  52. package/dist/oracle/registry.js +70 -0
  53. package/dist/oracle/registry.js.map +1 -0
  54. package/dist/quoter/index.d.ts +6 -0
  55. package/dist/quoter/index.d.ts.map +1 -0
  56. package/dist/quoter/index.js +6 -0
  57. package/dist/quoter/index.js.map +1 -0
  58. package/dist/quoter/quote.d.ts +58 -0
  59. package/dist/quoter/quote.d.ts.map +1 -0
  60. package/dist/quoter/quote.js +74 -0
  61. package/dist/quoter/quote.js.map +1 -0
  62. package/dist/quoter/quotePath.d.ts +65 -0
  63. package/dist/quoter/quotePath.d.ts.map +1 -0
  64. package/dist/quoter/quotePath.js +108 -0
  65. package/dist/quoter/quotePath.js.map +1 -0
  66. package/dist/router/index.d.ts +2 -1
  67. package/dist/router/index.d.ts.map +1 -1
  68. package/dist/router/index.js +2 -1
  69. package/dist/router/index.js.map +1 -1
  70. package/dist/router/swap.d.ts +37 -92
  71. package/dist/router/swap.d.ts.map +1 -1
  72. package/dist/router/swap.js +96 -298
  73. package/dist/router/swap.js.map +1 -1
  74. package/dist/router/swapPath.d.ts +56 -0
  75. package/dist/router/swapPath.d.ts.map +1 -0
  76. package/dist/router/swapPath.js +98 -0
  77. package/dist/router/swapPath.js.map +1 -0
  78. package/dist/swap/path.d.ts +13 -0
  79. package/dist/swap/path.d.ts.map +1 -0
  80. package/dist/swap/path.js +74 -0
  81. package/dist/swap/path.js.map +1 -0
  82. package/package.json +4 -5
  83. package/src/abis/MetricOmmPool.ts +18 -0
  84. package/src/abis/MetricOmmPoolDataProvider.ts +0 -177
  85. package/src/abis/MetricOmmPoolStateView.ts +314 -0
  86. package/src/abis/MetricOmmSimpleRouter.ts +804 -0
  87. package/src/abis/MetricOmmSwapQuoter.ts +747 -0
  88. package/src/abis/OracleProvider.ts +61 -0
  89. package/src/abis/PriceProvider.ts +9 -1
  90. package/src/abis/index.ts +4 -2
  91. package/src/addresses.ts +13 -13
  92. package/src/constants.ts +7 -2
  93. package/src/index.ts +62 -23
  94. package/src/oracle/index.ts +14 -0
  95. package/src/oracle/registry.ts +146 -0
  96. package/src/quoter/index.ts +28 -0
  97. package/src/quoter/quote.ts +193 -0
  98. package/src/quoter/quotePath.ts +240 -0
  99. package/src/router/index.ts +24 -25
  100. package/src/router/swap.ts +142 -480
  101. package/src/router/swapPath.ts +181 -0
  102. package/src/swap/path.ts +107 -0
  103. package/dist/abis/MetricOmmPoolSwapper.d.ts +0 -917
  104. package/dist/abis/MetricOmmPoolSwapper.js +0 -1185
  105. package/dist/abis/MetricOmmPoolSwapper.js.map +0 -1
  106. package/dist/abis/PriceProviderUi.d.ts +0 -433
  107. package/dist/abis/PriceProviderUi.js +0 -318
  108. package/dist/abis/PriceProviderUi.js.map +0 -1
  109. package/src/abis/MetricOmmPoolSwapper.ts +0 -1184
  110. package/src/abis/PriceProviderUi.ts +0 -317
@@ -1,558 +1,220 @@
1
1
  /**
2
- * MetricAMM SDK - Swapper (v1 periphery) helpers for building and encoding swaps.
2
+ * MetricAMM SDK - SimpleRouter single-hop swap helpers.
3
3
  */
4
4
 
5
- import type { Address, PublicClient, Hex } from "viem";
6
- import { encodeFunctionData, zeroAddress } from "viem";
7
- import { MAX_UINT128, POOL_ABI, SWAPPER_ABI } from "../constants.js";
5
+ import type { Address, Hex } from "viem";
6
+ import { encodeFunctionData } from "viem";
7
+ import { defaultPriceLimitX64 } from "../quoter/quotePath.js";
8
+ import { quoteLiveExactInSingle, quoteLiveExactOutSingle } from "../quoter/quote.js";
9
+ import { resolveSwapPath } from "../swap/path.js";
10
+ import { SIMPLE_ROUTER_ABI } from "../constants.js";
8
11
  import { EMPTY_EXTENSION_DATA } from "../extensions/types.js";
9
- import { PriceProviderUiAbi } from "../abis/PriceProviderUi.js";
12
+ import type { PublicClient } from "viem";
10
13
 
11
14
  const BPS_BASE = 10_000n;
12
15
 
13
- function withExtensionData(args: readonly unknown[]): readonly unknown[] {
14
- return args.length >= 8 ? args : [...args, EMPTY_EXTENSION_DATA];
15
- }
16
-
17
- function quoteSwapArgs(params: {
16
+ export type ExactInputSingleParams = {
18
17
  pool: Address;
19
- recipient: Address;
20
- zeroForOne: boolean;
21
- amountSpecified: bigint;
22
- priceLimitX64: bigint;
23
- bidPriceX64: bigint;
24
- askPriceX64: bigint;
25
- extensionData?: Hex;
26
- }): readonly [Address, Address, boolean, bigint, bigint, bigint, bigint, Hex] {
27
- return [
28
- params.pool,
29
- params.recipient,
30
- params.zeroForOne,
31
- params.amountSpecified,
32
- params.priceLimitX64,
33
- params.bidPriceX64,
34
- params.askPriceX64,
35
- params.extensionData ?? EMPTY_EXTENSION_DATA,
36
- ];
37
- }
38
- export interface PreparedSwapTransaction {
39
- data: Hex;
40
- value?: bigint;
41
- }
42
-
43
- export type SwapExactInputArgs = readonly [
44
- Address,
45
- Address,
46
- boolean,
47
- bigint,
48
- bigint,
49
- bigint,
50
- bigint,
51
- ];
52
-
53
- export type SwapExactInputParams = {
54
- pool: Address;
55
- recipient: Address;
18
+ tokenIn: Address;
19
+ tokenOut: Address;
56
20
  zeroForOne: boolean;
57
21
  amountIn: bigint;
58
- priceLimitX64: bigint;
59
- minAmountOut: bigint;
22
+ amountOutMinimum: bigint;
23
+ recipient: Address;
60
24
  deadline: bigint;
25
+ priceLimitX64: bigint;
26
+ extensionData?: Hex;
61
27
  };
62
28
 
63
- export type SwapExactOutputArgs = readonly [
64
- Address,
65
- Address,
66
- boolean,
67
- bigint,
68
- bigint,
69
- bigint,
70
- bigint,
71
- ];
72
-
73
- export type SwapExactOutputParams = {
29
+ export type ExactOutputSingleParams = {
74
30
  pool: Address;
75
- recipient: Address;
31
+ tokenIn: Address;
32
+ tokenOut: Address;
76
33
  zeroForOne: boolean;
77
34
  amountOut: bigint;
78
- priceLimitX64: bigint;
79
- maxAmountIn: bigint;
35
+ amountInMaximum: bigint;
36
+ recipient: Address;
80
37
  deadline: bigint;
38
+ priceLimitX64: bigint;
39
+ extensionData?: Hex;
81
40
  };
82
41
 
83
- export interface BuildSwapPrices {
84
- bidPriceX64: bigint;
85
- askPriceX64: bigint;
86
- }
87
-
88
- /** Shared fields for swap builders that may auto-fetch bid/ask from the pool's price provider. */
89
- export interface BuildSwapWithFactoryParams {
42
+ export interface BuildExactInputSingleParams {
90
43
  publicClient: PublicClient;
91
- /** Factory that deployed the pool (required when `prices` is omitted). */
92
- factoryAddress?: Address;
93
44
  pool: Address;
94
- prices?: BuildSwapPrices;
95
- extensionData?: Hex;
96
- }
97
-
98
- export interface BuildSwapExactInputParams extends BuildSwapWithFactoryParams {
99
- swapperAddress: Address;
45
+ tokenIn: Address;
46
+ tokenOut: Address;
100
47
  recipient: Address;
101
- zeroForOne: boolean;
102
48
  amountIn: bigint;
103
49
  slippagePercent: number;
104
50
  priceLimitX64?: bigint;
105
51
  deadline: bigint;
52
+ extensionData?: Hex;
53
+ quoterAddress?: Address;
106
54
  }
107
55
 
108
- export interface BuildSwapExactOutputParams extends BuildSwapWithFactoryParams {
109
- swapperAddress: Address;
56
+ export interface BuildExactOutputSingleParams {
57
+ publicClient: PublicClient;
58
+ pool: Address;
59
+ tokenIn: Address;
60
+ tokenOut: Address;
110
61
  recipient: Address;
111
- zeroForOne: boolean;
112
62
  amountOut: bigint;
113
63
  slippagePercent: number;
114
64
  priceLimitX64?: bigint;
115
65
  deadline: bigint;
66
+ extensionData?: Hex;
67
+ quoterAddress?: Address;
116
68
  }
117
69
 
118
- export type QuoteExpectedAmountsForSwapExactInputParams = Omit<
119
- BuildSwapExactInputParams,
120
- "deadline"
121
- >;
122
-
123
- export type QuoteExpectedAmountsForSwapExactOutputParams = Omit<
124
- BuildSwapExactOutputParams,
125
- "deadline"
126
- >;
127
-
128
- function toSlippageBps(slippagePercent: number): bigint {
70
+ export function toSlippageBps(slippagePercent: number): bigint {
129
71
  if (!Number.isFinite(slippagePercent) || slippagePercent < 0 || slippagePercent > 100) {
130
72
  throw new Error("slippagePercent must be a finite number between 0 and 100");
131
73
  }
132
74
  return BigInt(Math.round(slippagePercent * 100));
133
75
  }
134
76
 
135
- function absBigInt(value: bigint): bigint {
136
- return value < 0n ? -value : value;
137
- }
138
-
139
- function ceilDiv(numerator: bigint, denominator: bigint): bigint {
77
+ export function ceilDiv(numerator: bigint, denominator: bigint): bigint {
140
78
  if (denominator <= 0n) {
141
79
  throw new Error("denominator must be > 0");
142
80
  }
143
81
  return numerator === 0n ? 0n : (numerator + denominator - 1n) / denominator;
144
82
  }
145
83
 
146
- function defaultPriceLimitX64(zeroForOne: boolean): bigint {
147
- return zeroForOne ? 0n : MAX_UINT128;
84
+ function withExtensionData(extensionData?: Hex): Hex {
85
+ return extensionData ?? EMPTY_EXTENSION_DATA;
148
86
  }
149
87
 
150
- async function readBidAskFromPoolPriceProvider(
151
- publicClient: PublicClient,
152
- poolAddress: Address,
153
- ): Promise<{ bidPriceX64: bigint; askPriceX64: bigint }> {
154
- const imm = (await publicClient.readContract({
155
- address: poolAddress,
156
- abi: POOL_ABI,
157
- functionName: "getImmutables",
158
- })) as { immutablePriceProvider: Address };
159
-
160
- const priceProviderAddress = imm.immutablePriceProvider;
161
- if (
162
- !priceProviderAddress ||
163
- priceProviderAddress === "0x0000000000000000000000000000000000000000"
164
- ) {
165
- throw new Error(`pool ${poolAddress} has no immutable price provider (getImmutables)`);
166
- }
167
-
168
- const [bidPriceX64, askPriceX64] = (await publicClient.readContract({
169
- address: priceProviderAddress,
170
- abi: PriceProviderUiAbi,
171
- functionName: "getBidAndAskPriceUi",
172
- })) as [bigint, bigint];
173
-
174
- return { bidPriceX64, askPriceX64 };
88
+ function toExactInputSingleStruct(params: ExactInputSingleParams) {
89
+ return {
90
+ pool: params.pool,
91
+ tokenIn: params.tokenIn,
92
+ tokenOut: params.tokenOut,
93
+ zeroForOne: params.zeroForOne,
94
+ amountIn: params.amountIn,
95
+ amountOutMinimum: params.amountOutMinimum,
96
+ recipient: params.recipient,
97
+ deadline: params.deadline,
98
+ priceLimitX64: params.priceLimitX64,
99
+ extensionData: withExtensionData(params.extensionData),
100
+ };
175
101
  }
176
102
 
177
- async function resolveBidAskPrices(params: {
178
- publicClient: PublicClient;
179
- factoryAddress?: Address;
180
- pool: Address;
181
- prices?: BuildSwapPrices;
182
- }): Promise<{ bidPriceX64: bigint; askPriceX64: bigint }> {
183
- if (params.prices) {
184
- return params.prices;
185
- }
186
-
187
- return readBidAskFromPoolPriceProvider(params.publicClient, params.pool);
103
+ function toExactOutputSingleStruct(params: ExactOutputSingleParams) {
104
+ return {
105
+ pool: params.pool,
106
+ tokenIn: params.tokenIn,
107
+ tokenOut: params.tokenOut,
108
+ zeroForOne: params.zeroForOne,
109
+ amountOut: params.amountOut,
110
+ amountInMaximum: params.amountInMaximum,
111
+ recipient: params.recipient,
112
+ deadline: params.deadline,
113
+ priceLimitX64: params.priceLimitX64,
114
+ extensionData: withExtensionData(params.extensionData),
115
+ };
188
116
  }
189
117
 
190
- export async function buildArgsForSwapExactInput(
191
- params: BuildSwapExactInputParams,
192
- ): Promise<SwapExactInputArgs> {
118
+ export async function buildExactInputSingleParams(
119
+ params: BuildExactInputSingleParams,
120
+ ): Promise<ExactInputSingleParams> {
193
121
  const slippageBps = toSlippageBps(params.slippagePercent);
194
- const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
195
-
196
- const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
197
-
198
- const {
199
- result: [amount0Delta, amount1Delta],
200
- } = (await params.publicClient.simulateContract({
201
- address: params.swapperAddress,
202
- abi: SWAPPER_ABI,
203
- functionName: "quoteSwap",
204
- args: quoteSwapArgs({
205
- pool: params.pool,
206
- recipient: params.recipient,
207
- zeroForOne: params.zeroForOne,
208
- amountSpecified: params.amountIn,
209
- priceLimitX64,
210
- bidPriceX64,
211
- askPriceX64,
212
- extensionData: params.extensionData,
213
- }),
214
- account: params.recipient,
215
- })) as unknown as { result: [bigint, bigint] };
216
-
217
- const amountSwapWillResultIn = params.zeroForOne
218
- ? absBigInt(amount1Delta)
219
- : absBigInt(amount0Delta);
220
-
221
- const minAmountOut = (amountSwapWillResultIn * (BPS_BASE - slippageBps)) / BPS_BASE;
222
-
223
- return [
224
- params.pool,
225
- params.recipient,
226
- params.zeroForOne,
227
- params.amountIn,
122
+ const { zeroForOnes } = await resolveSwapPath(
123
+ params.publicClient,
124
+ params.tokenIn,
125
+ params.tokenOut,
126
+ [params.pool],
127
+ params.extensionData ? [params.extensionData] : undefined,
128
+ );
129
+ const zeroForOne = zeroForOnes[0]!;
130
+ const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(zeroForOne);
131
+
132
+ const { amountOut } = await quoteLiveExactInSingle({
133
+ publicClient: params.publicClient,
134
+ pool: params.pool,
135
+ tokenIn: params.tokenIn,
136
+ tokenOut: params.tokenOut,
137
+ recipient: params.recipient,
138
+ amountIn: params.amountIn,
228
139
  priceLimitX64,
229
- minAmountOut,
230
- params.deadline,
231
- ];
232
- }
233
-
234
- export async function buildArgsAndExpectedAmountsForSwapExactInput(
235
- params: BuildSwapExactInputParams,
236
- ): Promise<{
237
- args: SwapExactInputArgs;
238
- expectedInput: bigint;
239
- expectedOutput: bigint;
240
- }> {
241
- const slippageBps = toSlippageBps(params.slippagePercent);
242
- const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
243
-
244
- const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
245
-
246
- const {
247
- result: [amount0Delta, amount1Delta],
248
- } = (await params.publicClient.simulateContract({
249
- address: params.swapperAddress,
250
- abi: SWAPPER_ABI,
251
- functionName: "quoteSwap",
252
- args: quoteSwapArgs({
253
- pool: params.pool,
254
- recipient: params.recipient,
255
- zeroForOne: params.zeroForOne,
256
- amountSpecified: params.amountIn,
257
- priceLimitX64,
258
- bidPriceX64,
259
- askPriceX64,
260
- extensionData: params.extensionData,
261
- }),
262
- account: params.recipient,
263
- })) as unknown as { result: [bigint, bigint] };
264
-
265
- const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
266
-
267
- const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
268
-
269
- const minAmountOut = (expectedOutput * (BPS_BASE - slippageBps)) / BPS_BASE;
140
+ extensionData: params.extensionData,
141
+ quoterAddress: params.quoterAddress,
142
+ });
270
143
 
271
- const args: SwapExactInputArgs = [
272
- params.pool,
273
- params.recipient,
274
- params.zeroForOne,
275
- params.amountIn,
276
- priceLimitX64,
277
- minAmountOut,
278
- params.deadline,
279
- ];
144
+ const amountOutMinimum = (amountOut * (BPS_BASE - slippageBps)) / BPS_BASE;
280
145
 
281
146
  return {
282
- args,
283
- expectedInput,
284
- expectedOutput,
147
+ pool: params.pool,
148
+ tokenIn: params.tokenIn,
149
+ tokenOut: params.tokenOut,
150
+ zeroForOne,
151
+ amountIn: params.amountIn,
152
+ amountOutMinimum,
153
+ recipient: params.recipient,
154
+ deadline: params.deadline,
155
+ priceLimitX64,
156
+ extensionData: params.extensionData,
285
157
  };
286
158
  }
287
159
 
288
- export type QuoteSwapParams = BuildSwapWithFactoryParams & {
289
- swapperAddress: Address;
290
- zeroForOne: boolean;
291
- amountSpecified: bigint;
292
- priceLimitX64?: bigint;
293
- /** Defaults to zero address when omitted. */
294
- recipient?: Address;
295
- };
296
-
297
- export type QuoteSwapResult = {
298
- amount0Delta: bigint;
299
- amount1Delta: bigint;
300
- amountIn: bigint;
301
- amountOut: bigint;
302
- };
303
-
304
- export async function quoteSwap(params: QuoteSwapParams): Promise<QuoteSwapResult> {
305
- const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
306
- const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
307
-
308
- const [amount0Delta, amount1Delta] = (await params.publicClient.readContract({
309
- address: params.swapperAddress,
310
- abi: SWAPPER_ABI,
311
- functionName: "quoteSwap",
312
- args: quoteSwapArgs({
313
- pool: params.pool,
314
- recipient: params.recipient ?? zeroAddress,
315
- zeroForOne: params.zeroForOne,
316
- amountSpecified: params.amountSpecified,
317
- priceLimitX64,
318
- bidPriceX64,
319
- askPriceX64,
320
- extensionData: params.extensionData,
321
- }),
322
- })) as [bigint, bigint];
323
-
324
- const amountIn = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
325
- const amountOut = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
326
-
327
- return { amount0Delta, amount1Delta, amountIn, amountOut };
328
- }
329
-
330
- export async function quoteExpectedAmountsForSwapExactInput(
331
- params: QuoteExpectedAmountsForSwapExactInputParams,
332
- ): Promise<{ expectedInput: bigint; expectedOutput: bigint }> {
333
- const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
334
-
335
- const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
336
-
337
- const [amount0Delta, amount1Delta] = (await params.publicClient.readContract({
338
- address: params.swapperAddress,
339
- abi: SWAPPER_ABI,
340
- functionName: "quoteSwap",
341
- args: quoteSwapArgs({
342
- pool: params.pool,
343
- recipient: params.recipient,
344
- zeroForOne: params.zeroForOne,
345
- amountSpecified: params.amountIn,
346
- priceLimitX64,
347
- bidPriceX64,
348
- askPriceX64,
349
- extensionData: params.extensionData,
350
- }),
351
- })) as [bigint, bigint];
352
-
353
- const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
354
-
355
- const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
356
-
357
- return { expectedInput, expectedOutput };
358
- }
359
-
360
- export async function buildArgsForSwapExactOutput(
361
- params: BuildSwapExactOutputParams,
362
- ): Promise<SwapExactOutputArgs> {
160
+ export async function buildExactOutputSingleParams(
161
+ params: BuildExactOutputSingleParams,
162
+ ): Promise<ExactOutputSingleParams> {
363
163
  const slippageBps = toSlippageBps(params.slippagePercent);
364
- const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
365
-
366
- const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
367
-
368
- const {
369
- result: [amount0Delta, amount1Delta],
370
- } = (await params.publicClient.simulateContract({
371
- address: params.swapperAddress,
372
- abi: SWAPPER_ABI,
373
- functionName: "quoteSwap",
374
- args: quoteSwapArgs({
375
- pool: params.pool,
376
- recipient: params.recipient,
377
- zeroForOne: params.zeroForOne,
378
- amountSpecified: -params.amountOut,
379
- priceLimitX64,
380
- bidPriceX64,
381
- askPriceX64,
382
- extensionData: params.extensionData,
383
- }),
384
- account: params.recipient,
385
- })) as unknown as { result: [bigint, bigint] };
386
-
387
- const quotedAmountIn = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
388
-
389
- const maxAmountIn = ceilDiv(quotedAmountIn * (BPS_BASE + slippageBps), BPS_BASE);
390
-
391
- return [
392
- params.pool,
393
- params.recipient,
394
- params.zeroForOne,
395
- params.amountOut,
164
+ const { zeroForOnes } = await resolveSwapPath(
165
+ params.publicClient,
166
+ params.tokenIn,
167
+ params.tokenOut,
168
+ [params.pool],
169
+ params.extensionData ? [params.extensionData] : undefined,
170
+ );
171
+ const zeroForOne = zeroForOnes[0]!;
172
+ const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(zeroForOne);
173
+
174
+ const { amountIn } = await quoteLiveExactOutSingle({
175
+ publicClient: params.publicClient,
176
+ pool: params.pool,
177
+ tokenIn: params.tokenIn,
178
+ tokenOut: params.tokenOut,
179
+ recipient: params.recipient,
180
+ amountOut: params.amountOut,
396
181
  priceLimitX64,
397
- maxAmountIn,
398
- params.deadline,
399
- ];
400
- }
401
-
402
- export async function buildArgsAndExpectedAmountsForSwapExactOutput(
403
- params: BuildSwapExactOutputParams,
404
- ): Promise<{
405
- args: SwapExactOutputArgs;
406
- expectedInput: bigint;
407
- expectedOutput: bigint;
408
- }> {
409
- const slippageBps = toSlippageBps(params.slippagePercent);
410
- const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
411
-
412
- const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
413
-
414
- const {
415
- result: [amount0Delta, amount1Delta],
416
- } = (await params.publicClient.simulateContract({
417
- address: params.swapperAddress,
418
- abi: SWAPPER_ABI,
419
- functionName: "quoteSwap",
420
- args: quoteSwapArgs({
421
- pool: params.pool,
422
- recipient: params.recipient,
423
- zeroForOne: params.zeroForOne,
424
- amountSpecified: -params.amountOut,
425
- priceLimitX64,
426
- bidPriceX64,
427
- askPriceX64,
428
- extensionData: params.extensionData,
429
- }),
430
- account: params.recipient,
431
- })) as unknown as { result: [bigint, bigint] };
432
-
433
- const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
434
-
435
- const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
436
-
437
- const maxAmountIn = ceilDiv(expectedInput * (BPS_BASE + slippageBps), BPS_BASE);
182
+ extensionData: params.extensionData,
183
+ quoterAddress: params.quoterAddress,
184
+ });
438
185
 
439
- const args: SwapExactOutputArgs = [
440
- params.pool,
441
- params.recipient,
442
- params.zeroForOne,
443
- params.amountOut,
444
- priceLimitX64,
445
- maxAmountIn,
446
- params.deadline,
447
- ];
186
+ const amountInMaximum = ceilDiv(amountIn * (BPS_BASE + slippageBps), BPS_BASE);
448
187
 
449
188
  return {
450
- args,
451
- expectedInput,
452
- expectedOutput,
189
+ pool: params.pool,
190
+ tokenIn: params.tokenIn,
191
+ tokenOut: params.tokenOut,
192
+ zeroForOne,
193
+ amountOut: params.amountOut,
194
+ amountInMaximum,
195
+ recipient: params.recipient,
196
+ deadline: params.deadline,
197
+ priceLimitX64,
198
+ extensionData: params.extensionData,
453
199
  };
454
200
  }
455
201
 
456
- export async function quoteExpectedAmountsForSwapExactOutput(
457
- params: QuoteExpectedAmountsForSwapExactOutputParams,
458
- ): Promise<{ expectedInput: bigint; expectedOutput: bigint }> {
459
- const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
460
-
461
- const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
462
-
463
- const [amount0Delta, amount1Delta] = (await params.publicClient.readContract({
464
- address: params.swapperAddress,
465
- abi: SWAPPER_ABI,
466
- functionName: "quoteSwap",
467
- args: quoteSwapArgs({
468
- pool: params.pool,
469
- recipient: params.recipient,
470
- zeroForOne: params.zeroForOne,
471
- amountSpecified: -params.amountOut,
472
- priceLimitX64,
473
- bidPriceX64,
474
- askPriceX64,
475
- extensionData: params.extensionData,
476
- }),
477
- })) as [bigint, bigint];
478
-
479
- const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
480
-
481
- const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
482
-
483
- return { expectedInput, expectedOutput };
484
- }
485
-
486
- export function encodeSwapExactInputCalldata(
487
- argsOrParams: SwapExactInputArgs | SwapExactInputParams,
488
- ): `0x${string}` {
489
- const args = Array.isArray(argsOrParams)
490
- ? argsOrParams
491
- : ([
492
- (argsOrParams as SwapExactInputParams).pool,
493
- (argsOrParams as SwapExactInputParams).recipient,
494
- (argsOrParams as SwapExactInputParams).zeroForOne,
495
- (argsOrParams as SwapExactInputParams).amountIn,
496
- (argsOrParams as SwapExactInputParams).priceLimitX64,
497
- (argsOrParams as SwapExactInputParams).minAmountOut,
498
- (argsOrParams as SwapExactInputParams).deadline,
499
- ] as const);
500
-
202
+ export function encodeExactInputSingleCalldata(params: ExactInputSingleParams): Hex {
501
203
  return encodeFunctionData({
502
- abi: SWAPPER_ABI,
503
- functionName: "swapExactInput",
504
- args: withExtensionData(args),
204
+ abi: SIMPLE_ROUTER_ABI,
205
+ functionName: "exactInputSingle",
206
+ args: [toExactInputSingleStruct(params)],
505
207
  });
506
208
  }
507
209
 
508
- export const prepareSwapExactInputCalldata = encodeSwapExactInputCalldata;
509
-
510
- export function encodeSwapExactOutputCalldata(
511
- argsOrParams: SwapExactOutputArgs | SwapExactOutputParams,
512
- ): `0x${string}` {
513
- const args = Array.isArray(argsOrParams)
514
- ? argsOrParams
515
- : ([
516
- (argsOrParams as SwapExactOutputParams).pool,
517
- (argsOrParams as SwapExactOutputParams).recipient,
518
- (argsOrParams as SwapExactOutputParams).zeroForOne,
519
- (argsOrParams as SwapExactOutputParams).amountOut,
520
- (argsOrParams as SwapExactOutputParams).priceLimitX64,
521
- (argsOrParams as SwapExactOutputParams).maxAmountIn,
522
- (argsOrParams as SwapExactOutputParams).deadline,
523
- ] as const);
210
+ export const prepareExactInputSingleCalldata = encodeExactInputSingleCalldata;
524
211
 
212
+ export function encodeExactOutputSingleCalldata(params: ExactOutputSingleParams): Hex {
525
213
  return encodeFunctionData({
526
- abi: SWAPPER_ABI,
527
- functionName: "swapExactOutput",
528
- args: withExtensionData(args),
214
+ abi: SIMPLE_ROUTER_ABI,
215
+ functionName: "exactOutputSingle",
216
+ args: [toExactOutputSingleStruct(params)],
529
217
  });
530
218
  }
531
219
 
532
- export const prepareSwapExactOutputCalldata = encodeSwapExactOutputCalldata;
533
-
534
- export function encodeSwapExactInputNativeForTokensCalldata(
535
- params: SwapExactInputParams,
536
- ): PreparedSwapTransaction {
537
- const data = encodeFunctionData({
538
- abi: SWAPPER_ABI,
539
- functionName: "swapExactInputNativeForTokens",
540
- args: withExtensionData([
541
- params.pool,
542
- params.recipient,
543
- params.zeroForOne,
544
- params.amountIn,
545
- params.priceLimitX64,
546
- params.minAmountOut,
547
- params.deadline,
548
- ]),
549
- });
550
-
551
- return {
552
- data,
553
- value: params.amountIn,
554
- };
555
- }
556
-
557
- export const prepareSwapExactInputNativeForTokensCalldata =
558
- encodeSwapExactInputNativeForTokensCalldata;
220
+ export const prepareExactOutputSingleCalldata = encodeExactOutputSingleCalldata;