@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.
- package/README.md +98 -111
- package/dist/abis/MetricOmmPool.d.ts +14 -0
- package/dist/abis/MetricOmmPool.d.ts.map +1 -1
- package/dist/abis/MetricOmmPool.js +18 -0
- package/dist/abis/MetricOmmPool.js.map +1 -1
- package/dist/abis/MetricOmmPoolDataProvider.d.ts +0 -136
- package/dist/abis/MetricOmmPoolDataProvider.d.ts.map +1 -1
- package/dist/abis/MetricOmmPoolDataProvider.js +0 -177
- package/dist/abis/MetricOmmPoolDataProvider.js.map +1 -1
- package/dist/abis/MetricOmmPoolStateView.d.ts +238 -0
- package/dist/abis/MetricOmmPoolStateView.d.ts.map +1 -0
- package/dist/abis/MetricOmmPoolStateView.js +315 -0
- package/dist/abis/MetricOmmPoolStateView.js.map +1 -0
- package/dist/abis/MetricOmmSimpleRouter.d.ts +619 -0
- package/dist/abis/{MetricOmmPoolSwapper.d.ts.map → MetricOmmSimpleRouter.d.ts.map} +1 -1
- package/dist/abis/MetricOmmSimpleRouter.js +805 -0
- package/dist/abis/MetricOmmSimpleRouter.js.map +1 -0
- package/dist/abis/MetricOmmSwapQuoter.d.ts +576 -0
- package/dist/abis/{PriceProviderUi.d.ts.map → MetricOmmSwapQuoter.d.ts.map} +1 -1
- package/dist/abis/MetricOmmSwapQuoter.js +748 -0
- package/dist/abis/MetricOmmSwapQuoter.js.map +1 -0
- package/dist/abis/OracleProvider.d.ts +106 -0
- package/dist/abis/OracleProvider.d.ts.map +1 -0
- package/dist/abis/OracleProvider.js +62 -0
- package/dist/abis/OracleProvider.js.map +1 -0
- package/dist/abis/PriceProvider.d.ts +8 -2
- package/dist/abis/PriceProvider.d.ts.map +1 -1
- package/dist/abis/PriceProvider.js +9 -1
- package/dist/abis/PriceProvider.js.map +1 -1
- package/dist/abis/index.d.ts +4 -2
- package/dist/abis/index.d.ts.map +1 -1
- package/dist/abis/index.js +4 -2
- package/dist/abis/index.js.map +1 -1
- package/dist/addresses.d.ts +3 -3
- package/dist/addresses.d.ts.map +1 -1
- package/dist/addresses.js +10 -10
- package/dist/addresses.js.map +1 -1
- package/dist/constants.d.ts +4 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +7 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/dist/oracle/index.d.ts +5 -0
- package/dist/oracle/index.d.ts.map +1 -0
- package/dist/oracle/index.js +5 -0
- package/dist/oracle/index.js.map +1 -0
- package/dist/oracle/registry.d.ts +53 -0
- package/dist/oracle/registry.d.ts.map +1 -0
- package/dist/oracle/registry.js +70 -0
- package/dist/oracle/registry.js.map +1 -0
- package/dist/quoter/index.d.ts +6 -0
- package/dist/quoter/index.d.ts.map +1 -0
- package/dist/quoter/index.js +6 -0
- package/dist/quoter/index.js.map +1 -0
- package/dist/quoter/quote.d.ts +58 -0
- package/dist/quoter/quote.d.ts.map +1 -0
- package/dist/quoter/quote.js +74 -0
- package/dist/quoter/quote.js.map +1 -0
- package/dist/quoter/quotePath.d.ts +65 -0
- package/dist/quoter/quotePath.d.ts.map +1 -0
- package/dist/quoter/quotePath.js +108 -0
- package/dist/quoter/quotePath.js.map +1 -0
- package/dist/router/index.d.ts +2 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +2 -1
- package/dist/router/index.js.map +1 -1
- package/dist/router/swap.d.ts +37 -92
- package/dist/router/swap.d.ts.map +1 -1
- package/dist/router/swap.js +96 -298
- package/dist/router/swap.js.map +1 -1
- package/dist/router/swapPath.d.ts +56 -0
- package/dist/router/swapPath.d.ts.map +1 -0
- package/dist/router/swapPath.js +98 -0
- package/dist/router/swapPath.js.map +1 -0
- package/dist/swap/path.d.ts +13 -0
- package/dist/swap/path.d.ts.map +1 -0
- package/dist/swap/path.js +74 -0
- package/dist/swap/path.js.map +1 -0
- package/package.json +4 -5
- package/src/abis/MetricOmmPool.ts +18 -0
- package/src/abis/MetricOmmPoolDataProvider.ts +0 -177
- package/src/abis/MetricOmmPoolStateView.ts +314 -0
- package/src/abis/MetricOmmSimpleRouter.ts +804 -0
- package/src/abis/MetricOmmSwapQuoter.ts +747 -0
- package/src/abis/OracleProvider.ts +61 -0
- package/src/abis/PriceProvider.ts +9 -1
- package/src/abis/index.ts +4 -2
- package/src/addresses.ts +13 -13
- package/src/constants.ts +7 -2
- package/src/index.ts +62 -23
- package/src/oracle/index.ts +14 -0
- package/src/oracle/registry.ts +146 -0
- package/src/quoter/index.ts +28 -0
- package/src/quoter/quote.ts +193 -0
- package/src/quoter/quotePath.ts +240 -0
- package/src/router/index.ts +24 -25
- package/src/router/swap.ts +142 -480
- package/src/router/swapPath.ts +181 -0
- package/src/swap/path.ts +107 -0
- package/dist/abis/MetricOmmPoolSwapper.d.ts +0 -917
- package/dist/abis/MetricOmmPoolSwapper.js +0 -1185
- package/dist/abis/MetricOmmPoolSwapper.js.map +0 -1
- package/dist/abis/PriceProviderUi.d.ts +0 -433
- package/dist/abis/PriceProviderUi.js +0 -318
- package/dist/abis/PriceProviderUi.js.map +0 -1
- package/src/abis/MetricOmmPoolSwapper.ts +0 -1184
- package/src/abis/PriceProviderUi.ts +0 -317
package/src/router/swap.ts
CHANGED
|
@@ -1,558 +1,220 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MetricAMM SDK -
|
|
2
|
+
* MetricAMM SDK - SimpleRouter single-hop swap helpers.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { Address,
|
|
6
|
-
import { encodeFunctionData
|
|
7
|
-
import {
|
|
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 {
|
|
12
|
+
import type { PublicClient } from "viem";
|
|
10
13
|
|
|
11
14
|
const BPS_BASE = 10_000n;
|
|
12
15
|
|
|
13
|
-
|
|
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
|
-
|
|
20
|
-
|
|
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
|
-
|
|
59
|
-
|
|
22
|
+
amountOutMinimum: bigint;
|
|
23
|
+
recipient: Address;
|
|
60
24
|
deadline: bigint;
|
|
25
|
+
priceLimitX64: bigint;
|
|
26
|
+
extensionData?: Hex;
|
|
61
27
|
};
|
|
62
28
|
|
|
63
|
-
export type
|
|
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
|
-
|
|
31
|
+
tokenIn: Address;
|
|
32
|
+
tokenOut: Address;
|
|
76
33
|
zeroForOne: boolean;
|
|
77
34
|
amountOut: bigint;
|
|
78
|
-
|
|
79
|
-
|
|
35
|
+
amountInMaximum: bigint;
|
|
36
|
+
recipient: Address;
|
|
80
37
|
deadline: bigint;
|
|
38
|
+
priceLimitX64: bigint;
|
|
39
|
+
extensionData?: Hex;
|
|
81
40
|
};
|
|
82
41
|
|
|
83
|
-
export interface
|
|
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
|
-
|
|
95
|
-
|
|
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
|
|
109
|
-
|
|
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
|
|
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
|
|
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
|
|
147
|
-
return
|
|
84
|
+
function withExtensionData(extensionData?: Hex): Hex {
|
|
85
|
+
return extensionData ?? EMPTY_EXTENSION_DATA;
|
|
148
86
|
}
|
|
149
87
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
191
|
-
params:
|
|
192
|
-
): Promise<
|
|
118
|
+
export async function buildExactInputSingleParams(
|
|
119
|
+
params: BuildExactInputSingleParams,
|
|
120
|
+
): Promise<ExactInputSingleParams> {
|
|
193
121
|
const slippageBps = toSlippageBps(params.slippagePercent);
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
230
|
-
params.
|
|
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
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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
|
|
289
|
-
|
|
290
|
-
|
|
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
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
-
|
|
398
|
-
params.
|
|
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
|
|
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
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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
|
|
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:
|
|
503
|
-
functionName: "
|
|
504
|
-
args:
|
|
204
|
+
abi: SIMPLE_ROUTER_ABI,
|
|
205
|
+
functionName: "exactInputSingle",
|
|
206
|
+
args: [toExactInputSingleStruct(params)],
|
|
505
207
|
});
|
|
506
208
|
}
|
|
507
209
|
|
|
508
|
-
export const
|
|
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:
|
|
527
|
-
functionName: "
|
|
528
|
-
args:
|
|
214
|
+
abi: SIMPLE_ROUTER_ABI,
|
|
215
|
+
functionName: "exactOutputSingle",
|
|
216
|
+
args: [toExactOutputSingleStruct(params)],
|
|
529
217
|
});
|
|
530
218
|
}
|
|
531
219
|
|
|
532
|
-
export const
|
|
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;
|