@nradko/metric-omm-sdk-v1 0.0.16
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 +111 -0
- package/dist/abis/MetricOmmPool.d.ts +784 -0
- package/dist/abis/MetricOmmPool.d.ts.map +1 -0
- package/dist/abis/MetricOmmPool.js +1008 -0
- package/dist/abis/MetricOmmPool.js.map +1 -0
- package/dist/abis/MetricOmmPoolFactory.d.ts +1365 -0
- package/dist/abis/MetricOmmPoolFactory.d.ts.map +1 -0
- package/dist/abis/MetricOmmPoolFactory.js +1754 -0
- package/dist/abis/MetricOmmPoolFactory.js.map +1 -0
- package/dist/abis/MetricOmmPoolLiquidityAdder.d.ts +308 -0
- package/dist/abis/MetricOmmPoolLiquidityAdder.d.ts.map +1 -0
- package/dist/abis/MetricOmmPoolLiquidityAdder.js +401 -0
- package/dist/abis/MetricOmmPoolLiquidityAdder.js.map +1 -0
- package/dist/abis/MetricOmmPoolStateView.d.ts +538 -0
- package/dist/abis/MetricOmmPoolStateView.d.ts.map +1 -0
- package/dist/abis/MetricOmmPoolStateView.js +717 -0
- package/dist/abis/MetricOmmPoolStateView.js.map +1 -0
- package/dist/abis/MetricOmmPoolSwapper.d.ts +557 -0
- package/dist/abis/MetricOmmPoolSwapper.d.ts.map +1 -0
- package/dist/abis/MetricOmmPoolSwapper.js +723 -0
- package/dist/abis/MetricOmmPoolSwapper.js.map +1 -0
- package/dist/abis/Multicall3.d.ts +333 -0
- package/dist/abis/Multicall3.d.ts.map +1 -0
- package/dist/abis/Multicall3.js +441 -0
- package/dist/abis/Multicall3.js.map +1 -0
- package/dist/abis/PriceProvider.d.ts +142 -0
- package/dist/abis/PriceProvider.d.ts.map +1 -0
- package/dist/abis/PriceProvider.js +184 -0
- package/dist/abis/PriceProvider.js.map +1 -0
- package/dist/abis/PriceProviderUi.d.ts +433 -0
- package/dist/abis/PriceProviderUi.d.ts.map +1 -0
- package/dist/abis/PriceProviderUi.js +318 -0
- package/dist/abis/PriceProviderUi.js.map +1 -0
- package/dist/abis/index.d.ts +11 -0
- package/dist/abis/index.d.ts.map +1 -0
- package/dist/abis/index.js +11 -0
- package/dist/abis/index.js.map +1 -0
- package/dist/addresses.d.ts +52 -0
- package/dist/addresses.d.ts.map +1 -0
- package/dist/addresses.js +58 -0
- package/dist/addresses.js.map +1 -0
- package/dist/constants.d.ts +20 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +26 -0
- package/dist/constants.js.map +1 -0
- package/dist/factory/collectFees.d.ts +41 -0
- package/dist/factory/collectFees.d.ts.map +1 -0
- package/dist/factory/collectFees.js +120 -0
- package/dist/factory/collectFees.js.map +1 -0
- package/dist/factory/index.d.ts +5 -0
- package/dist/factory/index.d.ts.map +1 -0
- package/dist/factory/index.js +5 -0
- package/dist/factory/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/pool/create.d.ts +80 -0
- package/dist/pool/create.d.ts.map +1 -0
- package/dist/pool/create.js +80 -0
- package/dist/pool/create.js.map +1 -0
- package/dist/pool/index.d.ts +7 -0
- package/dist/pool/index.d.ts.map +1 -0
- package/dist/pool/index.js +10 -0
- package/dist/pool/index.js.map +1 -0
- package/dist/pool/liquidity.d.ts +165 -0
- package/dist/pool/liquidity.d.ts.map +1 -0
- package/dist/pool/liquidity.js +508 -0
- package/dist/pool/liquidity.js.map +1 -0
- package/dist/pool/read.d.ts +22 -0
- package/dist/pool/read.d.ts.map +1 -0
- package/dist/pool/read.js +88 -0
- package/dist/pool/read.js.map +1 -0
- package/dist/router/index.d.ts +5 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +5 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/swap.d.ts +117 -0
- package/dist/router/swap.d.ts.map +1 -0
- package/dist/router/swap.js +298 -0
- package/dist/router/swap.js.map +1 -0
- package/dist/stateView/index.d.ts +5 -0
- package/dist/stateView/index.d.ts.map +1 -0
- package/dist/stateView/index.js +5 -0
- package/dist/stateView/index.js.map +1 -0
- package/dist/stateView/read.d.ts +80 -0
- package/dist/stateView/read.d.ts.map +1 -0
- package/dist/stateView/read.js +249 -0
- package/dist/stateView/read.js.map +1 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/binData.d.ts +65 -0
- package/dist/utils/binData.d.ts.map +1 -0
- package/dist/utils/binData.js +109 -0
- package/dist/utils/binData.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/liquidityMath.d.ts +10 -0
- package/dist/utils/liquidityMath.d.ts.map +1 -0
- package/dist/utils/liquidityMath.js +31 -0
- package/dist/utils/liquidityMath.js.map +1 -0
- package/dist/utils/price.d.ts +13 -0
- package/dist/utils/price.d.ts.map +1 -0
- package/dist/utils/price.js +21 -0
- package/dist/utils/price.js.map +1 -0
- package/package.json +74 -0
- package/src/abis/MetricOmmPool.ts +1007 -0
- package/src/abis/MetricOmmPoolFactory.ts +1753 -0
- package/src/abis/MetricOmmPoolLiquidityAdder.ts +400 -0
- package/src/abis/MetricOmmPoolStateView.ts +716 -0
- package/src/abis/MetricOmmPoolSwapper.ts +722 -0
- package/src/abis/Multicall3.ts +440 -0
- package/src/abis/PriceProvider.ts +183 -0
- package/src/abis/PriceProviderUi.ts +317 -0
- package/src/abis/index.ts +11 -0
- package/src/addresses.ts +100 -0
- package/src/constants.ts +35 -0
- package/src/factory/collectFees.ts +197 -0
- package/src/factory/index.ts +12 -0
- package/src/index.ts +157 -0
- package/src/pool/create.ts +158 -0
- package/src/pool/index.ts +47 -0
- package/src/pool/liquidity.ts +839 -0
- package/src/pool/read.ts +131 -0
- package/src/router/index.ts +27 -0
- package/src/router/swap.ts +507 -0
- package/src/stateView/index.ts +18 -0
- package/src/stateView/read.ts +355 -0
- package/src/types.ts +162 -0
- package/src/utils/binData.ts +127 -0
- package/src/utils/index.ts +26 -0
- package/src/utils/liquidityMath.ts +47 -0
- package/src/utils/price.ts +23 -0
package/src/pool/read.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetricAMM SDK - Pool read helpers (v1 pools + factory-backed immutables).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Address, PublicClient } from "viem";
|
|
6
|
+
import { POOL_FACTORY_ABI, STATE_VIEW_ABI } from "../constants.js";
|
|
7
|
+
import type { PoolImmutables, PoolState, BinState } from "../types.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Read pool immutables via the factory (v1 pools do not expose a pool-side immutables getter).
|
|
11
|
+
*/
|
|
12
|
+
export async function getPoolImmutables(
|
|
13
|
+
publicClient: PublicClient,
|
|
14
|
+
factoryAddress: Address,
|
|
15
|
+
poolAddress: Address,
|
|
16
|
+
): Promise<PoolImmutables> {
|
|
17
|
+
const imm = (await publicClient.readContract({
|
|
18
|
+
address: factoryAddress,
|
|
19
|
+
abi: POOL_FACTORY_ABI,
|
|
20
|
+
functionName: "poolImmutables",
|
|
21
|
+
args: [poolAddress],
|
|
22
|
+
})) as {
|
|
23
|
+
token0: Address;
|
|
24
|
+
token1: Address;
|
|
25
|
+
immutablePriceProvider: Address;
|
|
26
|
+
depositAllowlistProvider: Address;
|
|
27
|
+
swapAllowlistProvider: Address;
|
|
28
|
+
reportSwapToPriceProvider: boolean;
|
|
29
|
+
token0ScaleMultiplier: bigint;
|
|
30
|
+
token1ScaleMultiplier: bigint;
|
|
31
|
+
initialScaledAmount0PerShareE18: bigint;
|
|
32
|
+
initialScaledAmount1PerShareE18: bigint;
|
|
33
|
+
minimalMintableLiquidity: bigint;
|
|
34
|
+
lowestBin: number;
|
|
35
|
+
highestBin: number;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
factory: factoryAddress,
|
|
40
|
+
token0: imm.token0,
|
|
41
|
+
token1: imm.token1,
|
|
42
|
+
token0ScaleMultiplier: imm.token0ScaleMultiplier,
|
|
43
|
+
token1ScaleMultiplier: imm.token1ScaleMultiplier,
|
|
44
|
+
initialScaledToken0PerShareE18: imm.initialScaledAmount0PerShareE18,
|
|
45
|
+
initialScaledToken1PerShareE18: imm.initialScaledAmount1PerShareE18,
|
|
46
|
+
minimalMintableLiquidity: imm.minimalMintableLiquidity,
|
|
47
|
+
maxDriftE8: 0n,
|
|
48
|
+
maxDriftDecayPerSecondE8: 0n,
|
|
49
|
+
lowestBin: imm.lowestBin,
|
|
50
|
+
highestBin: imm.highestBin,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Read pool state via StateView (slot0 + slot1).
|
|
56
|
+
*/
|
|
57
|
+
export async function getPoolState(
|
|
58
|
+
publicClient: PublicClient,
|
|
59
|
+
stateViewAddress: Address,
|
|
60
|
+
poolAddress: Address,
|
|
61
|
+
): Promise<PoolState> {
|
|
62
|
+
const [slot0, slot1] = await Promise.all([
|
|
63
|
+
publicClient.readContract({
|
|
64
|
+
address: stateViewAddress,
|
|
65
|
+
abi: STATE_VIEW_ABI,
|
|
66
|
+
functionName: "slot0",
|
|
67
|
+
args: [poolAddress],
|
|
68
|
+
}) as Promise<readonly [number, number, bigint, number, number, number]>,
|
|
69
|
+
publicClient.readContract({
|
|
70
|
+
address: stateViewAddress,
|
|
71
|
+
abi: STATE_VIEW_ABI,
|
|
72
|
+
functionName: "slot1",
|
|
73
|
+
args: [poolAddress],
|
|
74
|
+
}) as Promise<readonly [bigint, bigint]>,
|
|
75
|
+
]);
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
pauseLevel: slot0[0],
|
|
79
|
+
curBinIdx: slot0[1],
|
|
80
|
+
curPosInBin: slot0[2],
|
|
81
|
+
curBinDistFromProvidedPrice: slot0[3],
|
|
82
|
+
spreadFeeE6: slot0[4],
|
|
83
|
+
notionalFeeE8: slot0[5],
|
|
84
|
+
totalScaledToken0InBins: slot1[0],
|
|
85
|
+
totalScaledToken1InBins: slot1[1],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Read bin state (scaled balances) via StateView.
|
|
91
|
+
*/
|
|
92
|
+
export async function getBinState(
|
|
93
|
+
publicClient: PublicClient,
|
|
94
|
+
stateViewAddress: Address,
|
|
95
|
+
poolAddress: Address,
|
|
96
|
+
binIdx: number,
|
|
97
|
+
): Promise<BinState> {
|
|
98
|
+
const result = (await publicClient.readContract({
|
|
99
|
+
address: stateViewAddress,
|
|
100
|
+
abi: STATE_VIEW_ABI,
|
|
101
|
+
functionName: "binStateScaled",
|
|
102
|
+
args: [poolAddress, binIdx],
|
|
103
|
+
})) as readonly [bigint, bigint, number, number, number];
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
token0BalanceScaled: result[0],
|
|
107
|
+
token1BalanceScaled: result[1],
|
|
108
|
+
lengthE6: result[2],
|
|
109
|
+
addFeeBuyE6: result[3],
|
|
110
|
+
addFeeSellE6: result[4],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Get user position shares in a specific bin (StateView).
|
|
116
|
+
*/
|
|
117
|
+
export async function getPositionBinShares(
|
|
118
|
+
publicClient: PublicClient,
|
|
119
|
+
stateViewAddress: Address,
|
|
120
|
+
poolAddress: Address,
|
|
121
|
+
owner: Address,
|
|
122
|
+
salt: bigint,
|
|
123
|
+
binIdx: number,
|
|
124
|
+
): Promise<bigint> {
|
|
125
|
+
return (await publicClient.readContract({
|
|
126
|
+
address: stateViewAddress,
|
|
127
|
+
abi: STATE_VIEW_ABI,
|
|
128
|
+
functionName: "positionBinShares",
|
|
129
|
+
args: [poolAddress, owner, salt, binIdx],
|
|
130
|
+
})) as bigint;
|
|
131
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetricAMM SDK - Router Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
quoteSwap,
|
|
7
|
+
buildArgsForSwapExactInput,
|
|
8
|
+
buildArgsAndExpectedAmountsForSwapExactInput,
|
|
9
|
+
quoteExpectedAmountsForSwapExactInput,
|
|
10
|
+
buildArgsForSwapExactOutput,
|
|
11
|
+
buildArgsAndExpectedAmountsForSwapExactOutput,
|
|
12
|
+
quoteExpectedAmountsForSwapExactOutput,
|
|
13
|
+
prepareSwapExactInputCalldata,
|
|
14
|
+
prepareSwapExactOutputCalldata,
|
|
15
|
+
prepareSwapExactInputNativeForTokensCalldata,
|
|
16
|
+
type PreparedSwapTransaction,
|
|
17
|
+
type BuildSwapExactInputParams,
|
|
18
|
+
type QuoteExpectedAmountsForSwapExactInputParams,
|
|
19
|
+
type SwapExactInputParams,
|
|
20
|
+
type BuildSwapExactOutputParams,
|
|
21
|
+
type QuoteExpectedAmountsForSwapExactOutputParams,
|
|
22
|
+
type SwapExactOutputParams,
|
|
23
|
+
type SwapExactInputArgs,
|
|
24
|
+
type SwapExactOutputArgs,
|
|
25
|
+
type QuoteSwapParams,
|
|
26
|
+
type QuoteSwapResult,
|
|
27
|
+
} from "./swap.js";
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetricAMM SDK - Swapper (v1 periphery) helpers for building and encoding swaps.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Address, PublicClient, Hex } from "viem";
|
|
6
|
+
import { encodeFunctionData } from "viem";
|
|
7
|
+
import { MAX_UINT128, POOL_ABI, SWAPPER_ABI } from "../constants.js";
|
|
8
|
+
import { PriceProviderUiAbi } from "../abis/PriceProviderUi.js";
|
|
9
|
+
|
|
10
|
+
const BPS_BASE = 10_000n;
|
|
11
|
+
export interface PreparedSwapTransaction {
|
|
12
|
+
data: Hex;
|
|
13
|
+
value?: bigint;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type SwapExactInputArgs = readonly [
|
|
17
|
+
Address,
|
|
18
|
+
Address,
|
|
19
|
+
boolean,
|
|
20
|
+
bigint,
|
|
21
|
+
bigint,
|
|
22
|
+
bigint,
|
|
23
|
+
bigint,
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export type SwapExactInputParams = {
|
|
27
|
+
pool: Address;
|
|
28
|
+
recipient: Address;
|
|
29
|
+
zeroForOne: boolean;
|
|
30
|
+
amountIn: bigint;
|
|
31
|
+
priceLimitX64: bigint;
|
|
32
|
+
minAmountOut: bigint;
|
|
33
|
+
deadline: bigint;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type SwapExactOutputArgs = readonly [
|
|
37
|
+
Address,
|
|
38
|
+
Address,
|
|
39
|
+
boolean,
|
|
40
|
+
bigint,
|
|
41
|
+
bigint,
|
|
42
|
+
bigint,
|
|
43
|
+
bigint,
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
export type SwapExactOutputParams = {
|
|
47
|
+
pool: Address;
|
|
48
|
+
recipient: Address;
|
|
49
|
+
zeroForOne: boolean;
|
|
50
|
+
amountOut: bigint;
|
|
51
|
+
priceLimitX64: bigint;
|
|
52
|
+
maxAmountIn: bigint;
|
|
53
|
+
deadline: bigint;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export interface BuildSwapPrices {
|
|
57
|
+
bidPriceX64: bigint;
|
|
58
|
+
askPriceX64: bigint;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface BuildSwapExactInputParams {
|
|
62
|
+
publicClient: PublicClient;
|
|
63
|
+
swapperAddress: Address;
|
|
64
|
+
pool: Address;
|
|
65
|
+
recipient: Address;
|
|
66
|
+
zeroForOne: boolean;
|
|
67
|
+
amountIn: bigint;
|
|
68
|
+
slippagePercent: number;
|
|
69
|
+
prices?: BuildSwapPrices;
|
|
70
|
+
priceLimitX64?: bigint;
|
|
71
|
+
deadline: bigint;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface BuildSwapExactOutputParams {
|
|
75
|
+
publicClient: PublicClient;
|
|
76
|
+
swapperAddress: Address;
|
|
77
|
+
pool: Address;
|
|
78
|
+
recipient: Address;
|
|
79
|
+
zeroForOne: boolean;
|
|
80
|
+
amountOut: bigint;
|
|
81
|
+
slippagePercent: number;
|
|
82
|
+
prices?: BuildSwapPrices;
|
|
83
|
+
priceLimitX64?: bigint;
|
|
84
|
+
deadline: bigint;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type QuoteExpectedAmountsForSwapExactInputParams = Omit<
|
|
88
|
+
BuildSwapExactInputParams,
|
|
89
|
+
"recipient" | "deadline"
|
|
90
|
+
>;
|
|
91
|
+
|
|
92
|
+
export type QuoteExpectedAmountsForSwapExactOutputParams = Omit<
|
|
93
|
+
BuildSwapExactOutputParams,
|
|
94
|
+
"recipient" | "deadline"
|
|
95
|
+
>;
|
|
96
|
+
|
|
97
|
+
function toSlippageBps(slippagePercent: number): bigint {
|
|
98
|
+
if (!Number.isFinite(slippagePercent) || slippagePercent < 0) {
|
|
99
|
+
throw new Error("slippagePercent must be a non-negative finite number");
|
|
100
|
+
}
|
|
101
|
+
return BigInt(Math.round(slippagePercent * 100));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function absBigInt(value: bigint): bigint {
|
|
105
|
+
return value < 0n ? -value : value;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function ceilDiv(numerator: bigint, denominator: bigint): bigint {
|
|
109
|
+
if (denominator <= 0n) {
|
|
110
|
+
throw new Error("denominator must be > 0");
|
|
111
|
+
}
|
|
112
|
+
return numerator === 0n ? 0n : (numerator + denominator - 1n) / denominator;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function defaultPriceLimitX64(zeroForOne: boolean): bigint {
|
|
116
|
+
return zeroForOne ? 0n : MAX_UINT128;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function readBidAskFromPoolPriceProvider(
|
|
120
|
+
publicClient: PublicClient,
|
|
121
|
+
poolAddress: Address,
|
|
122
|
+
): Promise<{ bidPriceX64: bigint; askPriceX64: bigint }> {
|
|
123
|
+
const immutables = (await publicClient.readContract({
|
|
124
|
+
address: poolAddress,
|
|
125
|
+
abi: POOL_ABI,
|
|
126
|
+
functionName: "getImmutables",
|
|
127
|
+
})) as readonly unknown[];
|
|
128
|
+
|
|
129
|
+
const priceProviderAddress = immutables[1] as Address;
|
|
130
|
+
|
|
131
|
+
const [bidPriceX64, askPriceX64] = (await publicClient.readContract({
|
|
132
|
+
address: priceProviderAddress,
|
|
133
|
+
abi: PriceProviderUiAbi,
|
|
134
|
+
functionName: "getBidAndAskPriceUi",
|
|
135
|
+
})) as [bigint, bigint];
|
|
136
|
+
|
|
137
|
+
return { bidPriceX64, askPriceX64 };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function resolveBidAskPrices(params: {
|
|
141
|
+
publicClient: PublicClient;
|
|
142
|
+
pool: Address;
|
|
143
|
+
prices?: BuildSwapPrices;
|
|
144
|
+
}): Promise<{ bidPriceX64: bigint; askPriceX64: bigint }> {
|
|
145
|
+
if (params.prices) {
|
|
146
|
+
return params.prices;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return readBidAskFromPoolPriceProvider(params.publicClient, params.pool);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function buildArgsForSwapExactInput(
|
|
153
|
+
params: BuildSwapExactInputParams,
|
|
154
|
+
): Promise<SwapExactInputArgs> {
|
|
155
|
+
const slippageBps = toSlippageBps(params.slippagePercent);
|
|
156
|
+
const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
|
|
157
|
+
|
|
158
|
+
const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
|
|
159
|
+
|
|
160
|
+
const {
|
|
161
|
+
result: [amount0Delta, amount1Delta],
|
|
162
|
+
} = (await params.publicClient.simulateContract({
|
|
163
|
+
address: params.swapperAddress,
|
|
164
|
+
abi: SWAPPER_ABI,
|
|
165
|
+
functionName: "quoteSwap",
|
|
166
|
+
args: [
|
|
167
|
+
params.pool,
|
|
168
|
+
params.zeroForOne,
|
|
169
|
+
params.amountIn,
|
|
170
|
+
priceLimitX64,
|
|
171
|
+
bidPriceX64,
|
|
172
|
+
askPriceX64,
|
|
173
|
+
],
|
|
174
|
+
account: params.recipient,
|
|
175
|
+
})) as unknown as { result: [bigint, bigint] };
|
|
176
|
+
|
|
177
|
+
const amountSwapWillResultIn = params.zeroForOne
|
|
178
|
+
? absBigInt(amount1Delta)
|
|
179
|
+
: absBigInt(amount0Delta);
|
|
180
|
+
|
|
181
|
+
const minAmountOut = (amountSwapWillResultIn * (BPS_BASE - slippageBps)) / BPS_BASE;
|
|
182
|
+
|
|
183
|
+
return [
|
|
184
|
+
params.pool,
|
|
185
|
+
params.recipient,
|
|
186
|
+
params.zeroForOne,
|
|
187
|
+
params.amountIn,
|
|
188
|
+
priceLimitX64,
|
|
189
|
+
minAmountOut,
|
|
190
|
+
params.deadline,
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export async function buildArgsAndExpectedAmountsForSwapExactInput(
|
|
195
|
+
params: BuildSwapExactInputParams,
|
|
196
|
+
): Promise<{
|
|
197
|
+
args: SwapExactInputArgs;
|
|
198
|
+
expectedInput: bigint;
|
|
199
|
+
expectedOutput: bigint;
|
|
200
|
+
}> {
|
|
201
|
+
const slippageBps = toSlippageBps(params.slippagePercent);
|
|
202
|
+
const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
|
|
203
|
+
|
|
204
|
+
const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
|
|
205
|
+
|
|
206
|
+
const {
|
|
207
|
+
result: [amount0Delta, amount1Delta],
|
|
208
|
+
} = (await params.publicClient.simulateContract({
|
|
209
|
+
address: params.swapperAddress,
|
|
210
|
+
abi: SWAPPER_ABI,
|
|
211
|
+
functionName: "quoteSwap",
|
|
212
|
+
args: [
|
|
213
|
+
params.pool,
|
|
214
|
+
params.zeroForOne,
|
|
215
|
+
params.amountIn,
|
|
216
|
+
priceLimitX64,
|
|
217
|
+
bidPriceX64,
|
|
218
|
+
askPriceX64,
|
|
219
|
+
],
|
|
220
|
+
account: params.recipient,
|
|
221
|
+
})) as unknown as { result: [bigint, bigint] };
|
|
222
|
+
|
|
223
|
+
const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
|
|
224
|
+
|
|
225
|
+
const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
|
|
226
|
+
|
|
227
|
+
const minAmountOut = (expectedOutput * (BPS_BASE - slippageBps)) / BPS_BASE;
|
|
228
|
+
|
|
229
|
+
const args: SwapExactInputArgs = [
|
|
230
|
+
params.pool,
|
|
231
|
+
params.recipient,
|
|
232
|
+
params.zeroForOne,
|
|
233
|
+
params.amountIn,
|
|
234
|
+
priceLimitX64,
|
|
235
|
+
minAmountOut,
|
|
236
|
+
params.deadline,
|
|
237
|
+
];
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
args,
|
|
241
|
+
expectedInput,
|
|
242
|
+
expectedOutput,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export type QuoteSwapParams = {
|
|
247
|
+
publicClient: PublicClient;
|
|
248
|
+
swapperAddress: Address;
|
|
249
|
+
pool: Address;
|
|
250
|
+
zeroForOne: boolean;
|
|
251
|
+
amountSpecified: bigint;
|
|
252
|
+
priceLimitX64?: bigint;
|
|
253
|
+
prices?: BuildSwapPrices;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export type QuoteSwapResult = {
|
|
257
|
+
amount0Delta: bigint;
|
|
258
|
+
amount1Delta: bigint;
|
|
259
|
+
amountIn: bigint;
|
|
260
|
+
amountOut: bigint;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export async function quoteSwap(params: QuoteSwapParams): Promise<QuoteSwapResult> {
|
|
264
|
+
const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
|
|
265
|
+
const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
|
|
266
|
+
|
|
267
|
+
const [amount0Delta, amount1Delta] = (await params.publicClient.readContract({
|
|
268
|
+
address: params.swapperAddress,
|
|
269
|
+
abi: SWAPPER_ABI,
|
|
270
|
+
functionName: "quoteSwap",
|
|
271
|
+
args: [
|
|
272
|
+
params.pool,
|
|
273
|
+
params.zeroForOne,
|
|
274
|
+
params.amountSpecified,
|
|
275
|
+
priceLimitX64,
|
|
276
|
+
bidPriceX64,
|
|
277
|
+
askPriceX64,
|
|
278
|
+
],
|
|
279
|
+
})) as [bigint, bigint];
|
|
280
|
+
|
|
281
|
+
const amountIn = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
|
|
282
|
+
const amountOut = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
|
|
283
|
+
|
|
284
|
+
return { amount0Delta, amount1Delta, amountIn, amountOut };
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export async function quoteExpectedAmountsForSwapExactInput(
|
|
288
|
+
params: QuoteExpectedAmountsForSwapExactInputParams,
|
|
289
|
+
): Promise<{ expectedInput: bigint; expectedOutput: bigint }> {
|
|
290
|
+
const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
|
|
291
|
+
|
|
292
|
+
const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
|
|
293
|
+
|
|
294
|
+
const [amount0Delta, amount1Delta] = (await params.publicClient.readContract({
|
|
295
|
+
address: params.swapperAddress,
|
|
296
|
+
abi: SWAPPER_ABI,
|
|
297
|
+
functionName: "quoteSwap",
|
|
298
|
+
args: [
|
|
299
|
+
params.pool,
|
|
300
|
+
params.zeroForOne,
|
|
301
|
+
params.amountIn,
|
|
302
|
+
priceLimitX64,
|
|
303
|
+
bidPriceX64,
|
|
304
|
+
askPriceX64,
|
|
305
|
+
],
|
|
306
|
+
})) as [bigint, bigint];
|
|
307
|
+
|
|
308
|
+
const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
|
|
309
|
+
|
|
310
|
+
const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
|
|
311
|
+
|
|
312
|
+
return { expectedInput, expectedOutput };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export async function buildArgsForSwapExactOutput(
|
|
316
|
+
params: BuildSwapExactOutputParams,
|
|
317
|
+
): Promise<SwapExactOutputArgs> {
|
|
318
|
+
const slippageBps = toSlippageBps(params.slippagePercent);
|
|
319
|
+
const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
|
|
320
|
+
|
|
321
|
+
const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
|
|
322
|
+
|
|
323
|
+
const {
|
|
324
|
+
result: [amount0Delta, amount1Delta],
|
|
325
|
+
} = (await params.publicClient.simulateContract({
|
|
326
|
+
address: params.swapperAddress,
|
|
327
|
+
abi: SWAPPER_ABI,
|
|
328
|
+
functionName: "quoteSwap",
|
|
329
|
+
args: [
|
|
330
|
+
params.pool,
|
|
331
|
+
params.zeroForOne,
|
|
332
|
+
-params.amountOut,
|
|
333
|
+
priceLimitX64,
|
|
334
|
+
bidPriceX64,
|
|
335
|
+
askPriceX64,
|
|
336
|
+
],
|
|
337
|
+
account: params.recipient,
|
|
338
|
+
})) as unknown as { result: [bigint, bigint] };
|
|
339
|
+
|
|
340
|
+
const quotedAmountIn = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
|
|
341
|
+
|
|
342
|
+
const maxAmountIn = ceilDiv(quotedAmountIn * (BPS_BASE + slippageBps), BPS_BASE);
|
|
343
|
+
|
|
344
|
+
return [
|
|
345
|
+
params.pool,
|
|
346
|
+
params.recipient,
|
|
347
|
+
params.zeroForOne,
|
|
348
|
+
params.amountOut,
|
|
349
|
+
priceLimitX64,
|
|
350
|
+
maxAmountIn,
|
|
351
|
+
params.deadline,
|
|
352
|
+
];
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export async function buildArgsAndExpectedAmountsForSwapExactOutput(
|
|
356
|
+
params: BuildSwapExactOutputParams,
|
|
357
|
+
): Promise<{
|
|
358
|
+
args: SwapExactOutputArgs;
|
|
359
|
+
expectedInput: bigint;
|
|
360
|
+
expectedOutput: bigint;
|
|
361
|
+
}> {
|
|
362
|
+
const slippageBps = toSlippageBps(params.slippagePercent);
|
|
363
|
+
const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
|
|
364
|
+
|
|
365
|
+
const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
|
|
366
|
+
|
|
367
|
+
const {
|
|
368
|
+
result: [amount0Delta, amount1Delta],
|
|
369
|
+
} = (await params.publicClient.simulateContract({
|
|
370
|
+
address: params.swapperAddress,
|
|
371
|
+
abi: SWAPPER_ABI,
|
|
372
|
+
functionName: "quoteSwap",
|
|
373
|
+
args: [
|
|
374
|
+
params.pool,
|
|
375
|
+
params.zeroForOne,
|
|
376
|
+
-params.amountOut,
|
|
377
|
+
priceLimitX64,
|
|
378
|
+
bidPriceX64,
|
|
379
|
+
askPriceX64,
|
|
380
|
+
],
|
|
381
|
+
account: params.recipient,
|
|
382
|
+
})) as unknown as { result: [bigint, bigint] };
|
|
383
|
+
|
|
384
|
+
const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
|
|
385
|
+
|
|
386
|
+
const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
|
|
387
|
+
|
|
388
|
+
const maxAmountIn = ceilDiv(expectedInput * (BPS_BASE + slippageBps), BPS_BASE);
|
|
389
|
+
|
|
390
|
+
const args: SwapExactOutputArgs = [
|
|
391
|
+
params.pool,
|
|
392
|
+
params.recipient,
|
|
393
|
+
params.zeroForOne,
|
|
394
|
+
params.amountOut,
|
|
395
|
+
priceLimitX64,
|
|
396
|
+
maxAmountIn,
|
|
397
|
+
params.deadline,
|
|
398
|
+
];
|
|
399
|
+
|
|
400
|
+
return {
|
|
401
|
+
args,
|
|
402
|
+
expectedInput,
|
|
403
|
+
expectedOutput,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export async function quoteExpectedAmountsForSwapExactOutput(
|
|
408
|
+
params: QuoteExpectedAmountsForSwapExactOutputParams,
|
|
409
|
+
): Promise<{ expectedInput: bigint; expectedOutput: bigint }> {
|
|
410
|
+
const priceLimitX64 = params.priceLimitX64 ?? defaultPriceLimitX64(params.zeroForOne);
|
|
411
|
+
|
|
412
|
+
const { bidPriceX64, askPriceX64 } = await resolveBidAskPrices(params);
|
|
413
|
+
|
|
414
|
+
const [amount0Delta, amount1Delta] = (await params.publicClient.readContract({
|
|
415
|
+
address: params.swapperAddress,
|
|
416
|
+
abi: SWAPPER_ABI,
|
|
417
|
+
functionName: "quoteSwap",
|
|
418
|
+
args: [
|
|
419
|
+
params.pool,
|
|
420
|
+
params.zeroForOne,
|
|
421
|
+
-params.amountOut,
|
|
422
|
+
priceLimitX64,
|
|
423
|
+
bidPriceX64,
|
|
424
|
+
askPriceX64,
|
|
425
|
+
],
|
|
426
|
+
})) as [bigint, bigint];
|
|
427
|
+
|
|
428
|
+
const expectedInput = params.zeroForOne ? absBigInt(amount0Delta) : absBigInt(amount1Delta);
|
|
429
|
+
|
|
430
|
+
const expectedOutput = params.zeroForOne ? absBigInt(amount1Delta) : absBigInt(amount0Delta);
|
|
431
|
+
|
|
432
|
+
return { expectedInput, expectedOutput };
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
export function encodeSwapExactInputCalldata(
|
|
436
|
+
argsOrParams: SwapExactInputArgs | SwapExactInputParams,
|
|
437
|
+
): `0x${string}` {
|
|
438
|
+
const args = Array.isArray(argsOrParams)
|
|
439
|
+
? argsOrParams
|
|
440
|
+
: ([
|
|
441
|
+
(argsOrParams as SwapExactInputParams).pool,
|
|
442
|
+
(argsOrParams as SwapExactInputParams).recipient,
|
|
443
|
+
(argsOrParams as SwapExactInputParams).zeroForOne,
|
|
444
|
+
(argsOrParams as SwapExactInputParams).amountIn,
|
|
445
|
+
(argsOrParams as SwapExactInputParams).priceLimitX64,
|
|
446
|
+
(argsOrParams as SwapExactInputParams).minAmountOut,
|
|
447
|
+
(argsOrParams as SwapExactInputParams).deadline,
|
|
448
|
+
] as const);
|
|
449
|
+
|
|
450
|
+
return encodeFunctionData({
|
|
451
|
+
abi: SWAPPER_ABI,
|
|
452
|
+
functionName: "swapExactInput",
|
|
453
|
+
args,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export const prepareSwapExactInputCalldata = encodeSwapExactInputCalldata;
|
|
458
|
+
|
|
459
|
+
export function encodeSwapExactOutputCalldata(
|
|
460
|
+
argsOrParams: SwapExactOutputArgs | SwapExactOutputParams,
|
|
461
|
+
): `0x${string}` {
|
|
462
|
+
const args = Array.isArray(argsOrParams)
|
|
463
|
+
? argsOrParams
|
|
464
|
+
: ([
|
|
465
|
+
(argsOrParams as SwapExactOutputParams).pool,
|
|
466
|
+
(argsOrParams as SwapExactOutputParams).recipient,
|
|
467
|
+
(argsOrParams as SwapExactOutputParams).zeroForOne,
|
|
468
|
+
(argsOrParams as SwapExactOutputParams).amountOut,
|
|
469
|
+
(argsOrParams as SwapExactOutputParams).priceLimitX64,
|
|
470
|
+
(argsOrParams as SwapExactOutputParams).maxAmountIn,
|
|
471
|
+
(argsOrParams as SwapExactOutputParams).deadline,
|
|
472
|
+
] as const);
|
|
473
|
+
|
|
474
|
+
return encodeFunctionData({
|
|
475
|
+
abi: SWAPPER_ABI,
|
|
476
|
+
functionName: "swapExactOutput",
|
|
477
|
+
args,
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
export const prepareSwapExactOutputCalldata = encodeSwapExactOutputCalldata;
|
|
482
|
+
|
|
483
|
+
export function encodeSwapExactInputNativeForTokensCalldata(
|
|
484
|
+
params: SwapExactInputParams,
|
|
485
|
+
): PreparedSwapTransaction {
|
|
486
|
+
const data = encodeFunctionData({
|
|
487
|
+
abi: SWAPPER_ABI,
|
|
488
|
+
functionName: "swapExactInputNativeForTokens",
|
|
489
|
+
args: [
|
|
490
|
+
params.pool,
|
|
491
|
+
params.recipient,
|
|
492
|
+
params.zeroForOne,
|
|
493
|
+
params.amountIn,
|
|
494
|
+
params.priceLimitX64,
|
|
495
|
+
params.minAmountOut,
|
|
496
|
+
params.deadline,
|
|
497
|
+
],
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
return {
|
|
501
|
+
data,
|
|
502
|
+
value: params.amountIn,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
export const prepareSwapExactInputNativeForTokensCalldata =
|
|
507
|
+
encodeSwapExactInputNativeForTokensCalldata;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetricAMM SDK - StateView Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
getSlot0,
|
|
7
|
+
getSlot1,
|
|
8
|
+
getBinStateExternal,
|
|
9
|
+
getBinStatesExternal,
|
|
10
|
+
getBinStatesScaled,
|
|
11
|
+
getBinTotalShares,
|
|
12
|
+
getPositionBinSharesFromStateView,
|
|
13
|
+
toPositionBinKey,
|
|
14
|
+
getPositionBinSharesRange,
|
|
15
|
+
getFeeConfig,
|
|
16
|
+
getPriceProvider,
|
|
17
|
+
getLastTradeTimestamp,
|
|
18
|
+
} from "./read.js";
|