@nradko/metric-omm-sdk-v1 0.4.2 → 0.4.4
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 +134 -19
- package/dist/abis/DepositAllowlistExtension.d.ts +43 -0
- package/dist/abis/DepositAllowlistExtension.d.ts.map +1 -1
- package/dist/abis/DepositAllowlistExtension.js +56 -0
- package/dist/abis/DepositAllowlistExtension.js.map +1 -1
- package/dist/abis/MetricOmmPoolFactory.d.ts +12 -0
- package/dist/abis/MetricOmmPoolFactory.d.ts.map +1 -1
- package/dist/abis/MetricOmmPoolFactory.js +16 -0
- package/dist/abis/MetricOmmPoolFactory.js.map +1 -1
- package/dist/abis/MetricOmmPoolLiquidityAdder.d.ts +116 -5
- package/dist/abis/MetricOmmPoolLiquidityAdder.d.ts.map +1 -1
- package/dist/abis/MetricOmmPoolLiquidityAdder.js +150 -5
- package/dist/abis/MetricOmmPoolLiquidityAdder.js.map +1 -1
- package/dist/abis/MetricOmmSimpleRouter.d.ts +32 -0
- package/dist/abis/MetricOmmSimpleRouter.d.ts.map +1 -1
- package/dist/abis/MetricOmmSimpleRouter.js +42 -0
- package/dist/abis/MetricOmmSimpleRouter.js.map +1 -1
- package/dist/abis/MetricOmmSwapQuoter.d.ts +14 -2
- package/dist/abis/MetricOmmSwapQuoter.d.ts.map +1 -1
- package/dist/abis/MetricOmmSwapQuoter.js +18 -2
- package/dist/abis/MetricOmmSwapQuoter.js.map +1 -1
- package/dist/abis/SwapAllowlistExtension.d.ts +43 -0
- package/dist/abis/SwapAllowlistExtension.d.ts.map +1 -1
- package/dist/abis/SwapAllowlistExtension.js +56 -0
- package/dist/abis/SwapAllowlistExtension.js.map +1 -1
- package/dist/abis/index.d.ts +2 -3
- package/dist/abis/index.d.ts.map +1 -1
- package/dist/abis/index.js +2 -3
- package/dist/abis/index.js.map +1 -1
- package/dist/addresses.d.ts +2 -4
- package/dist/addresses.d.ts.map +1 -1
- package/dist/addresses.js +11 -12
- package/dist/addresses.js.map +1 -1
- package/dist/dataProvider/index.d.ts +1 -1
- package/dist/dataProvider/index.d.ts.map +1 -1
- package/dist/dataProvider/index.js +1 -1
- package/dist/dataProvider/index.js.map +1 -1
- package/dist/dataProvider/read.d.ts +1 -3
- package/dist/dataProvider/read.d.ts.map +1 -1
- package/dist/dataProvider/read.js +1 -3
- package/dist/dataProvider/read.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/peripheryPayments/index.d.ts +2 -0
- package/dist/peripheryPayments/index.d.ts.map +1 -0
- package/dist/peripheryPayments/index.js +2 -0
- package/dist/peripheryPayments/index.js.map +1 -0
- package/dist/peripheryPayments/simpleRouter.d.ts +9 -0
- package/dist/peripheryPayments/simpleRouter.d.ts.map +1 -0
- package/dist/peripheryPayments/simpleRouter.js +27 -0
- package/dist/peripheryPayments/simpleRouter.js.map +1 -0
- package/dist/pool/cursorBounds.d.ts +29 -0
- package/dist/pool/cursorBounds.d.ts.map +1 -0
- package/dist/pool/cursorBounds.js +76 -0
- package/dist/pool/cursorBounds.js.map +1 -0
- package/dist/pool/index.d.ts +3 -1
- package/dist/pool/index.d.ts.map +1 -1
- package/dist/pool/index.js +3 -1
- package/dist/pool/index.js.map +1 -1
- package/dist/pool/liquidity.d.ts +114 -7
- package/dist/pool/liquidity.d.ts.map +1 -1
- package/dist/pool/liquidity.js +96 -11
- package/dist/pool/liquidity.js.map +1 -1
- package/dist/pool/nativeLiquidity.d.ts +32 -0
- package/dist/pool/nativeLiquidity.d.ts.map +1 -0
- package/dist/pool/nativeLiquidity.js +47 -0
- package/dist/pool/nativeLiquidity.js.map +1 -0
- package/dist/router/fromRoute.d.ts +93 -0
- package/dist/router/fromRoute.d.ts.map +1 -0
- package/dist/router/fromRoute.js +187 -0
- package/dist/router/fromRoute.js.map +1 -0
- package/dist/router/index.d.ts +8 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +8 -1
- package/dist/router/index.js.map +1 -1
- package/dist/router/nativeSwap.d.ts +47 -0
- package/dist/router/nativeSwap.d.ts.map +1 -0
- package/dist/router/nativeSwap.js +89 -0
- package/dist/router/nativeSwap.js.map +1 -0
- package/dist/router/swap.d.ts +82 -1
- package/dist/router/swap.d.ts.map +1 -1
- package/dist/router/swap.js +51 -1
- package/dist/router/swap.js.map +1 -1
- package/dist/router/swapPath.d.ts +46 -1
- package/dist/router/swapPath.d.ts.map +1 -1
- package/dist/router/swapPath.js +34 -0
- package/dist/router/swapPath.js.map +1 -1
- package/package.json +2 -2
- package/src/abis/DepositAllowlistExtension.ts +56 -0
- package/src/abis/MetricOmmPoolFactory.ts +16 -0
- package/src/abis/MetricOmmPoolLiquidityAdder.ts +150 -5
- package/src/abis/MetricOmmSimpleRouter.ts +42 -0
- package/src/abis/MetricOmmSwapQuoter.ts +18 -2
- package/src/abis/SwapAllowlistExtension.ts +56 -0
- package/src/abis/index.ts +2 -3
- package/src/addresses.ts +12 -15
- package/src/dataProvider/index.ts +0 -1
- package/src/dataProvider/read.ts +1 -4
- package/src/index.ts +38 -2
- package/src/peripheryPayments/index.ts +5 -0
- package/src/peripheryPayments/simpleRouter.ts +31 -0
- package/src/pool/cursorBounds.ts +112 -0
- package/src/pool/index.ts +15 -0
- package/src/pool/liquidity.ts +124 -15
- package/src/pool/nativeLiquidity.ts +71 -0
- package/src/router/fromRoute.ts +318 -0
- package/src/router/index.ts +36 -1
- package/src/router/nativeSwap.ts +123 -0
- package/src/router/swap.ts +82 -1
- package/src/router/swapPath.ts +47 -1
- package/dist/abis/MetricOmmPoolStateView.d.ts +0 -238
- package/dist/abis/MetricOmmPoolStateView.d.ts.map +0 -1
- package/dist/abis/MetricOmmPoolStateView.js +0 -315
- package/dist/abis/MetricOmmPoolStateView.js.map +0 -1
- package/src/abis/MetricOmmPoolStateView.ts +0 -314
package/src/pool/liquidity.ts
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Liquidity position builders and calldata encoders.
|
|
3
|
+
*
|
|
4
|
+
* **Add liquidity (recommended path):**
|
|
5
|
+
* 1. `buildModifyLiquidityArgsForAddition` / `ForUniformAddition` / `ForUniformAdditionWithTotalTokenAmount`
|
|
6
|
+
* 2. `buildAddLiquidityExactSharesParamsFromBinTargets` (optional convenience)
|
|
7
|
+
* 3. `encodeAddLiquidityExactSharesSelfCalldata` or `encodeAddLiquidityExactSharesWithOwnerCalldata`
|
|
8
|
+
* — target `addresses.liquidityAdder`
|
|
9
|
+
* 4. Approve token0 and token1 on the LiquidityAdder for `maxAmountToken0` / `maxAmountToken1`
|
|
10
|
+
*
|
|
11
|
+
* **Self vs WithOwner encoders:**
|
|
12
|
+
* - `*SelfCalldata` — credits liquidity to **`msg.sender`** (the transaction sender owns the position).
|
|
13
|
+
* - `*WithOwnerCalldata` — credits liquidity to **`owner`** (e.g. router, vault, or relayer paying on behalf of a user).
|
|
14
|
+
* The caller still supplies tokens and must approve the LiquidityAdder; only the position owner differs.
|
|
15
|
+
*
|
|
16
|
+
* **Remove liquidity:** `buildModifyLiquidityArgsForRemoval` → `buildRemoveLiquidityPoolDelta`
|
|
17
|
+
* → `encodeRemoveLiquidityCalldata` — call the **pool** directly (no adder approval).
|
|
18
|
+
*
|
|
19
|
+
* Position identity is `(owner, salt)`; use the same `salt` for adds and removes.
|
|
4
20
|
*/
|
|
5
21
|
|
|
6
22
|
import type { Address, PublicClient, Hex } from "viem";
|
|
@@ -40,19 +56,27 @@ function getLiquidityAdderFunction(name: string, inputCount: number) {
|
|
|
40
56
|
return item;
|
|
41
57
|
}
|
|
42
58
|
|
|
59
|
+
/** High-level removal options (used by UI helpers). Prefer {@link BuildModifyLiquidityArgsForRemovalParams} in SDK code. */
|
|
43
60
|
export interface RemoveLiquidityParams {
|
|
61
|
+
/** Percent of each selected bin's shares to burn (0–100). */
|
|
44
62
|
percentageToRemove: number;
|
|
63
|
+
/** Explicit bin list; when omitted, scans `lowerBin`–`upperBin` for position shares. */
|
|
45
64
|
bins?: number[];
|
|
46
65
|
lowerBin?: number;
|
|
47
66
|
upperBin?: number;
|
|
48
67
|
}
|
|
49
68
|
|
|
69
|
+
/** Per-bin removal: specify exactly one of `percentageToRemove` or `sharesToRemove`. */
|
|
50
70
|
export interface BinRemovalSpec {
|
|
51
71
|
bin: number;
|
|
52
72
|
percentageToRemove?: number;
|
|
53
73
|
sharesToRemove?: bigint;
|
|
54
74
|
}
|
|
55
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Sentinel passed as `specAmount0` / `specAmount1` on removals — no minimum output enforced.
|
|
78
|
+
* Same value the pool uses for "accept any amount" on `modifyLiquidity` removes.
|
|
79
|
+
*/
|
|
56
80
|
export const NO_SLIPPAGE_LIMIT = MAX_INT128;
|
|
57
81
|
|
|
58
82
|
type ModifyLiquidityParams = {
|
|
@@ -62,30 +86,39 @@ type ModifyLiquidityParams = {
|
|
|
62
86
|
specAmount1: bigint;
|
|
63
87
|
};
|
|
64
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Tuple for low-level `modifyLiquidity` on the pool:
|
|
91
|
+
* `[salt, deltas, specAmount0, specAmount1]`.
|
|
92
|
+
* Prefer LiquidityAdder encode helpers for additions.
|
|
93
|
+
*/
|
|
65
94
|
export type ModifyLiquidityArgs = readonly [bigint, LiquidityDelta[], bigint, bigint];
|
|
66
95
|
|
|
67
96
|
export interface BuildModifyLiquidityArgsBase {
|
|
68
97
|
publicClient: PublicClient;
|
|
69
|
-
/** MetricOmmPoolDataProvider
|
|
98
|
+
/** MetricOmmPoolDataProvider (`addresses.dataProvider`). */
|
|
70
99
|
dataProviderAddress: Address;
|
|
71
100
|
poolAddress: Address;
|
|
101
|
+
/** Extra headroom on spec amounts (percent); `0` = exact computed caps. */
|
|
72
102
|
specAmountBufferPercent?: number;
|
|
73
103
|
}
|
|
74
104
|
|
|
75
|
-
/** Addition builders read pool immutables
|
|
105
|
+
/** Addition builders need the factory to read pool immutables (decimals, bin range). */
|
|
76
106
|
export interface BuildModifyLiquidityArgsWithFactory extends BuildModifyLiquidityArgsBase {
|
|
77
107
|
factoryAddress: Address;
|
|
78
108
|
}
|
|
79
109
|
|
|
110
|
+
/** Per-bin target amounts for {@link buildModifyLiquidityArgsForAddition}. */
|
|
80
111
|
export interface BuildModifyLiquidityArgsForAdditionParams extends BuildModifyLiquidityArgsWithFactory {
|
|
81
112
|
bins: LiquidityBinValueInput[];
|
|
82
|
-
/** Human
|
|
113
|
+
/** Human price token1/token0; omit when `currentPriceX64` is set. */
|
|
83
114
|
currentPrice?: number;
|
|
84
|
-
/**
|
|
115
|
+
/** Q64.64 price from slot0; preferred over `currentPrice`. */
|
|
85
116
|
currentPriceX64?: bigint;
|
|
117
|
+
/** Position salt; default `0n`. Reuse across adds to the same position. */
|
|
86
118
|
salt?: bigint;
|
|
87
119
|
}
|
|
88
120
|
|
|
121
|
+
/** Same value in every bin from `lowerBin` through `upperBin` inclusive. */
|
|
89
122
|
export interface BuildModifyLiquidityArgsForUniformAdditionParams extends BuildModifyLiquidityArgsWithFactory {
|
|
90
123
|
amountInTokensPerBin: bigint;
|
|
91
124
|
amountIsInToken0: boolean;
|
|
@@ -95,6 +128,7 @@ export interface BuildModifyLiquidityArgsForUniformAdditionParams extends BuildM
|
|
|
95
128
|
salt?: bigint;
|
|
96
129
|
}
|
|
97
130
|
|
|
131
|
+
/** Split a total token budget across `bins` (optional `weights`); calibrates share scaling on-chain. */
|
|
98
132
|
export interface BuildModifyLiquidityArgsForUniformAdditionWithTotalTokenAmountParams extends BuildModifyLiquidityArgsWithFactory {
|
|
99
133
|
bins: number[];
|
|
100
134
|
weights?: number[];
|
|
@@ -104,6 +138,7 @@ export interface BuildModifyLiquidityArgsForUniformAdditionWithTotalTokenAmountP
|
|
|
104
138
|
salt?: bigint;
|
|
105
139
|
}
|
|
106
140
|
|
|
141
|
+
/** Remove the same percentage from all bins with liquidity (or from explicit `bins`). */
|
|
107
142
|
export interface BuildModifyLiquidityArgsForPercentageRemovalParams extends BuildModifyLiquidityArgsBase {
|
|
108
143
|
owner: Address;
|
|
109
144
|
salt: bigint;
|
|
@@ -113,6 +148,7 @@ export interface BuildModifyLiquidityArgsForPercentageRemovalParams extends Buil
|
|
|
113
148
|
upperBin?: number;
|
|
114
149
|
}
|
|
115
150
|
|
|
151
|
+
/** Granular per-bin removal specs. */
|
|
116
152
|
export interface BuildModifyLiquidityArgsForRemovalParams extends BuildModifyLiquidityArgsBase {
|
|
117
153
|
owner: Address;
|
|
118
154
|
salt: bigint;
|
|
@@ -130,7 +166,10 @@ function resolvePriceE18(params: { currentPrice?: number; currentPriceX64?: bigi
|
|
|
130
166
|
}
|
|
131
167
|
|
|
132
168
|
/**
|
|
133
|
-
*
|
|
169
|
+
* Uniform liquidity: same token amount in every bin from `lowerBin` to `upperBin`.
|
|
170
|
+
* Delegates to {@link buildModifyLiquidityArgsForAddition}.
|
|
171
|
+
*
|
|
172
|
+
* @returns `[salt, deltas, specAmount0, specAmount1]` — max token caps for the adder.
|
|
134
173
|
*/
|
|
135
174
|
export async function buildModifyLiquidityArgsForUniformAddition({
|
|
136
175
|
publicClient,
|
|
@@ -517,6 +556,11 @@ export async function buildModifyLiquidityArgsForAddition({
|
|
|
517
556
|
return toModifyLiquidityArgs(computed);
|
|
518
557
|
}
|
|
519
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Remove liquidity by explicit per-bin specs (percentage or absolute shares).
|
|
561
|
+
*
|
|
562
|
+
* `specAmount0` / `specAmount1` are set to {@link NO_SLIPPAGE_LIMIT} (accept any output).
|
|
563
|
+
*/
|
|
520
564
|
export async function buildModifyLiquidityArgsForRemoval(
|
|
521
565
|
params: BuildModifyLiquidityArgsForRemovalParams,
|
|
522
566
|
): Promise<ModifyLiquidityArgs> {
|
|
@@ -598,6 +642,10 @@ export async function buildModifyLiquidityArgsForRemoval(
|
|
|
598
642
|
return toModifyLiquidityArgs(computed);
|
|
599
643
|
}
|
|
600
644
|
|
|
645
|
+
/**
|
|
646
|
+
* Remove the same `percentageToRemove` from every bin that has position shares.
|
|
647
|
+
* When `bins` is omitted, discovers bins via `getPositionBinSharesRange(lowerBin, upperBin)`.
|
|
648
|
+
*/
|
|
601
649
|
export async function buildModifyLiquidityArgsForPercentageRemoval({
|
|
602
650
|
publicClient,
|
|
603
651
|
dataProviderAddress,
|
|
@@ -650,6 +698,7 @@ export async function buildModifyLiquidityArgsForPercentageRemoval({
|
|
|
650
698
|
});
|
|
651
699
|
}
|
|
652
700
|
|
|
701
|
+
/** Convert positive `deltaShares` from a modify plan into `PoolLiquidityDelta` for the adder. */
|
|
653
702
|
export function additionPlanToPoolLiquidityDelta(
|
|
654
703
|
deltas: readonly LiquidityDelta[],
|
|
655
704
|
): PoolLiquidityDelta {
|
|
@@ -660,6 +709,7 @@ export function additionPlanToPoolLiquidityDelta(
|
|
|
660
709
|
};
|
|
661
710
|
}
|
|
662
711
|
|
|
712
|
+
/** Convert negative `deltaShares` from a modify plan into burn `PoolLiquidityDelta` for `removeLiquidity`. */
|
|
663
713
|
export function removalPlanToPoolLiquidityDelta(
|
|
664
714
|
deltas: readonly LiquidityDelta[],
|
|
665
715
|
): PoolLiquidityDelta {
|
|
@@ -698,6 +748,19 @@ export function scaleWeightedPoolDeltasToFitCaps(params: {
|
|
|
698
748
|
return { binIdxs: weights.binIdxs, shares };
|
|
699
749
|
}
|
|
700
750
|
|
|
751
|
+
/**
|
|
752
|
+
* Convenience wrapper: bin targets → adder-ready `{ salt, poolLiquidityDelta, maxAmountToken0, maxAmountToken1 }`.
|
|
753
|
+
*
|
|
754
|
+
* @example
|
|
755
|
+
* ```ts
|
|
756
|
+
* const add = await buildAddLiquidityExactSharesParamsFromBinTargets({
|
|
757
|
+
* publicClient, factoryAddress, dataProviderAddress, poolAddress,
|
|
758
|
+
* bins: [{ bin: 0, targetValueInToken: parseUnits("100", 6), targetValueInToken0: false }],
|
|
759
|
+
* currentPriceX64: slot0.priceX64,
|
|
760
|
+
* });
|
|
761
|
+
* const data = encodeAddLiquidityExactSharesSelfCalldata({ pool: poolAddress, ...add });
|
|
762
|
+
* ```
|
|
763
|
+
*/
|
|
701
764
|
export async function buildAddLiquidityExactSharesParamsFromBinTargets(
|
|
702
765
|
params: BuildModifyLiquidityArgsForAdditionParams,
|
|
703
766
|
): Promise<{
|
|
@@ -715,6 +778,27 @@ export async function buildAddLiquidityExactSharesParamsFromBinTargets(
|
|
|
715
778
|
};
|
|
716
779
|
}
|
|
717
780
|
|
|
781
|
+
/** Cursor bounds that disable weighted-add cursor checks (matches on-chain test helpers). */
|
|
782
|
+
export const UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS = {
|
|
783
|
+
minimalCurBin: -128,
|
|
784
|
+
minimalPosition: 0n,
|
|
785
|
+
maximalCurBin: 127,
|
|
786
|
+
maximalPosition: MAX_UINT104,
|
|
787
|
+
} as const;
|
|
788
|
+
|
|
789
|
+
export type LiquidityCursorBounds = {
|
|
790
|
+
minimalCurBin: number;
|
|
791
|
+
minimalPosition: bigint;
|
|
792
|
+
maximalCurBin: number;
|
|
793
|
+
maximalPosition: bigint;
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Encode `LiquidityAdder.addLiquidityExactShares` for the transaction sender.
|
|
798
|
+
*
|
|
799
|
+
* Creates or increases the position `(msg.sender, salt)` — liquidity is credited to whoever
|
|
800
|
+
* sends the transaction. Approve both pool tokens on the LiquidityAdder before sending.
|
|
801
|
+
*/
|
|
718
802
|
export function encodeAddLiquidityExactSharesSelfCalldata(params: {
|
|
719
803
|
pool: Address;
|
|
720
804
|
salt: bigint;
|
|
@@ -737,6 +821,13 @@ export function encodeAddLiquidityExactSharesSelfCalldata(params: {
|
|
|
737
821
|
});
|
|
738
822
|
}
|
|
739
823
|
|
|
824
|
+
/**
|
|
825
|
+
* Encode `LiquidityAdder.addLiquidityExactShares` for an explicit position owner.
|
|
826
|
+
*
|
|
827
|
+
* Creates or increases the position `(owner, salt)` while `msg.sender` pays for the deposit
|
|
828
|
+
* (e.g. router, vault, or meta-transaction relayer acting on behalf of `owner`).
|
|
829
|
+
* Approve both pool tokens on the LiquidityAdder before sending.
|
|
830
|
+
*/
|
|
740
831
|
export function encodeAddLiquidityExactSharesWithOwnerCalldata(params: {
|
|
741
832
|
pool: Address;
|
|
742
833
|
owner: Address;
|
|
@@ -761,6 +852,13 @@ export function encodeAddLiquidityExactSharesWithOwnerCalldata(params: {
|
|
|
761
852
|
});
|
|
762
853
|
}
|
|
763
854
|
|
|
855
|
+
/**
|
|
856
|
+
* Encode weighted add for the transaction sender.
|
|
857
|
+
*
|
|
858
|
+
* `weightDeltas` are relative share weights; the adder scales to fit
|
|
859
|
+
* `maxAmountToken0` / `maxAmountToken1`. Use {@link scaleWeightedPoolDeltasToFitCaps} to pre-scale.
|
|
860
|
+
* Creates or increases the position `(msg.sender, salt)`.
|
|
861
|
+
*/
|
|
764
862
|
export function encodeAddLiquidityWeightedSelfCalldata(params: {
|
|
765
863
|
pool: Address;
|
|
766
864
|
salt: bigint;
|
|
@@ -782,15 +880,21 @@ export function encodeAddLiquidityWeightedSelfCalldata(params: {
|
|
|
782
880
|
{ binIdxs: [...params.weightDeltas.binIdxs], shares: [...params.weightDeltas.shares] },
|
|
783
881
|
params.maxAmountToken0,
|
|
784
882
|
params.maxAmountToken1,
|
|
785
|
-
params.minimalCurBin ??
|
|
786
|
-
params.minimalPosition ??
|
|
787
|
-
params.maximalCurBin ??
|
|
788
|
-
params.maximalPosition ??
|
|
883
|
+
params.minimalCurBin ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.minimalCurBin,
|
|
884
|
+
params.minimalPosition ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.minimalPosition,
|
|
885
|
+
params.maximalCurBin ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.maximalCurBin,
|
|
886
|
+
params.maximalPosition ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.maximalPosition,
|
|
789
887
|
params.extensionData ?? EMPTY_EXTENSION_DATA,
|
|
790
888
|
],
|
|
791
889
|
});
|
|
792
890
|
}
|
|
793
891
|
|
|
892
|
+
/**
|
|
893
|
+
* Encode weighted add for an explicit position owner.
|
|
894
|
+
*
|
|
895
|
+
* Same as {@link encodeAddLiquidityWeightedSelfCalldata} but credits liquidity to `(owner, salt)`
|
|
896
|
+
* while `msg.sender` pays for the deposit.
|
|
897
|
+
*/
|
|
794
898
|
export function encodeAddLiquidityWeightedWithOwnerCalldata(params: {
|
|
795
899
|
pool: Address;
|
|
796
900
|
owner: Address;
|
|
@@ -814,15 +918,19 @@ export function encodeAddLiquidityWeightedWithOwnerCalldata(params: {
|
|
|
814
918
|
{ binIdxs: [...params.weightDeltas.binIdxs], shares: [...params.weightDeltas.shares] },
|
|
815
919
|
params.maxAmountToken0,
|
|
816
920
|
params.maxAmountToken1,
|
|
817
|
-
params.minimalCurBin ??
|
|
818
|
-
params.minimalPosition ??
|
|
819
|
-
params.maximalCurBin ??
|
|
820
|
-
params.maximalPosition ??
|
|
921
|
+
params.minimalCurBin ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.minimalCurBin,
|
|
922
|
+
params.minimalPosition ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.minimalPosition,
|
|
923
|
+
params.maximalCurBin ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.maximalCurBin,
|
|
924
|
+
params.maximalPosition ?? UNCONSTRAINED_LIQUIDITY_CURSOR_BOUNDS.maximalPosition,
|
|
821
925
|
params.extensionData ?? EMPTY_EXTENSION_DATA,
|
|
822
926
|
],
|
|
823
927
|
});
|
|
824
928
|
}
|
|
825
929
|
|
|
930
|
+
/**
|
|
931
|
+
* Encode `Pool.removeLiquidity(owner, salt, deltas, extensionData)`.
|
|
932
|
+
* Send to the **pool** contract; no token approval required (tokens are sent out).
|
|
933
|
+
*/
|
|
826
934
|
export function encodeRemoveLiquidityCalldata(params: {
|
|
827
935
|
owner: Address;
|
|
828
936
|
salt: bigint;
|
|
@@ -841,6 +949,7 @@ export function encodeRemoveLiquidityCalldata(params: {
|
|
|
841
949
|
});
|
|
842
950
|
}
|
|
843
951
|
|
|
952
|
+
/** Build `{ salt, poolLiquidityDelta }` for {@link encodeRemoveLiquidityCalldata}. */
|
|
844
953
|
export async function buildRemoveLiquidityPoolDelta(
|
|
845
954
|
params: BuildModifyLiquidityArgsForRemovalParams,
|
|
846
955
|
): Promise<{ salt: bigint; poolLiquidityDelta: PoolLiquidityDelta }> {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Hex } from "viem";
|
|
2
|
+
import {
|
|
3
|
+
encodeAddLiquidityExactSharesSelfCalldata,
|
|
4
|
+
encodeAddLiquidityExactSharesWithOwnerCalldata,
|
|
5
|
+
encodeAddLiquidityWeightedSelfCalldata,
|
|
6
|
+
encodeAddLiquidityWeightedWithOwnerCalldata,
|
|
7
|
+
} from "./liquidity.js";
|
|
8
|
+
import { encodeMulticallCalldata, encodeRefundETHCalldata } from "../peripheryPayments/index.js";
|
|
9
|
+
|
|
10
|
+
type ExactSharesSelfParams = Parameters<typeof encodeAddLiquidityExactSharesSelfCalldata>[0];
|
|
11
|
+
type ExactSharesWithOwnerParams = Parameters<
|
|
12
|
+
typeof encodeAddLiquidityExactSharesWithOwnerCalldata
|
|
13
|
+
>[0];
|
|
14
|
+
type WeightedSelfParams = Parameters<typeof encodeAddLiquidityWeightedSelfCalldata>[0];
|
|
15
|
+
type WeightedWithOwnerParams = Parameters<typeof encodeAddLiquidityWeightedWithOwnerCalldata>[0];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Exact-shares add with native ETH for the pool WETH leg.
|
|
19
|
+
* Credits liquidity to `(msg.sender, salt)`. Set `msg.value` on the transaction;
|
|
20
|
+
* unused ETH is refunded to the caller.
|
|
21
|
+
*/
|
|
22
|
+
export function prepareAddLiquidityExactSharesSelfSupportingNativePaymentCalldata(
|
|
23
|
+
params: ExactSharesSelfParams,
|
|
24
|
+
): Hex {
|
|
25
|
+
return encodeMulticallCalldata([
|
|
26
|
+
encodeAddLiquidityExactSharesSelfCalldata(params),
|
|
27
|
+
encodeRefundETHCalldata(),
|
|
28
|
+
]);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Exact-shares add with native ETH for the pool WETH leg.
|
|
33
|
+
* Credits liquidity to `(owner, salt)` while `msg.sender` pays. Set `msg.value` on the
|
|
34
|
+
* transaction; unused ETH is refunded to the caller.
|
|
35
|
+
*/
|
|
36
|
+
export function prepareAddLiquidityExactSharesWithOwnerSupportingNativePaymentCalldata(
|
|
37
|
+
params: ExactSharesWithOwnerParams,
|
|
38
|
+
): Hex {
|
|
39
|
+
return encodeMulticallCalldata([
|
|
40
|
+
encodeAddLiquidityExactSharesWithOwnerCalldata(params),
|
|
41
|
+
encodeRefundETHCalldata(),
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Weighted add with native ETH for the pool WETH leg.
|
|
47
|
+
* Credits liquidity to `(msg.sender, salt)`. Set `msg.value` on the transaction;
|
|
48
|
+
* unused ETH is refunded to the caller.
|
|
49
|
+
*/
|
|
50
|
+
export function prepareAddLiquidityWeightedSelfSupportingNativePaymentCalldata(
|
|
51
|
+
params: WeightedSelfParams,
|
|
52
|
+
): Hex {
|
|
53
|
+
return encodeMulticallCalldata([
|
|
54
|
+
encodeAddLiquidityWeightedSelfCalldata(params),
|
|
55
|
+
encodeRefundETHCalldata(),
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Weighted add with native ETH for the pool WETH leg.
|
|
61
|
+
* Credits liquidity to `(owner, salt)` while `msg.sender` pays. Set `msg.value` on the
|
|
62
|
+
* transaction; unused ETH is refunded to the caller.
|
|
63
|
+
*/
|
|
64
|
+
export function prepareAddLiquidityWeightedWithOwnerSupportingNativePaymentCalldata(
|
|
65
|
+
params: WeightedWithOwnerParams,
|
|
66
|
+
): Hex {
|
|
67
|
+
return encodeMulticallCalldata([
|
|
68
|
+
encodeAddLiquidityWeightedWithOwnerCalldata(params),
|
|
69
|
+
encodeRefundETHCalldata(),
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map route API POST /public/v1/evm/:chain_id/route responses to SimpleRouter swap params.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Address, Hex, PublicClient } from "viem";
|
|
6
|
+
import { getAddress } from "viem";
|
|
7
|
+
import { resolveSwapPath } from "../swap/path.js";
|
|
8
|
+
import { ceilDiv, toSlippageBps } from "./swap.js";
|
|
9
|
+
import type { ExactInputParams, ExactOutputParams } from "./swapPath.js";
|
|
10
|
+
import type { ExactInputSingleParams, ExactOutputSingleParams } from "./swap.js";
|
|
11
|
+
|
|
12
|
+
const BPS_BASE = 10_000n;
|
|
13
|
+
|
|
14
|
+
/** Wire tradeType from the route API. */
|
|
15
|
+
export type TradeType = "exact_in" | "exact_out";
|
|
16
|
+
|
|
17
|
+
/** Wire routeType from the route API. */
|
|
18
|
+
export type RouteType = "direct" | "one_hop";
|
|
19
|
+
|
|
20
|
+
/** One hop in a route API response (RouteLegResponse). */
|
|
21
|
+
export type RouteLegResponse = {
|
|
22
|
+
tradeType: TradeType;
|
|
23
|
+
poolAddress: string;
|
|
24
|
+
pair: string;
|
|
25
|
+
zeroForOne: boolean;
|
|
26
|
+
tokenIn: string;
|
|
27
|
+
tokenOut: string;
|
|
28
|
+
amountIn: string;
|
|
29
|
+
amountOut: string;
|
|
30
|
+
effectivePriceX64: string;
|
|
31
|
+
priceImpactE6: string;
|
|
32
|
+
priceLimitX64: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** One execution path in a route API response (RouteOptionResponse). */
|
|
36
|
+
export type RouteOptionResponse = {
|
|
37
|
+
tradeType: TradeType;
|
|
38
|
+
routeType: RouteType;
|
|
39
|
+
amountIn: string;
|
|
40
|
+
amountOut: string;
|
|
41
|
+
effectivePriceX64: string;
|
|
42
|
+
priceImpactE6: string;
|
|
43
|
+
legs: RouteLegResponse[];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** Route API response (RouteResponse). */
|
|
47
|
+
export type RouteResponse = {
|
|
48
|
+
tokenIn: string;
|
|
49
|
+
tokenOut: string;
|
|
50
|
+
tradeType: TradeType;
|
|
51
|
+
amountIn: string;
|
|
52
|
+
amountOut: string;
|
|
53
|
+
effectivePriceX64: string;
|
|
54
|
+
priceImpactBestRoute: string;
|
|
55
|
+
candidatesConsidered: number;
|
|
56
|
+
routes: RouteOptionResponse[];
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type PrepareExactInputFromRouteParams = {
|
|
60
|
+
publicClient: PublicClient;
|
|
61
|
+
route: RouteResponse;
|
|
62
|
+
recipient: Address;
|
|
63
|
+
deadline: bigint;
|
|
64
|
+
/** Human-readable slippage tolerance applied to the selected route's `amountOut`, e.g. `0.5` = 0.5%. */
|
|
65
|
+
slippagePercent: number;
|
|
66
|
+
extensionDatas?: readonly Hex[];
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export type PrepareExactOutputFromRouteParams = {
|
|
70
|
+
publicClient: PublicClient;
|
|
71
|
+
route: RouteResponse;
|
|
72
|
+
recipient: Address;
|
|
73
|
+
deadline: bigint;
|
|
74
|
+
/** Human-readable slippage tolerance applied to the selected route's `amountIn`, e.g. `0.5` = 0.5%. */
|
|
75
|
+
slippagePercent: number;
|
|
76
|
+
extensionDatas?: readonly Hex[];
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export type PreparedExactInputFromRoute =
|
|
80
|
+
| { kind: "single"; params: ExactInputSingleParams }
|
|
81
|
+
| { kind: "multihop"; params: ExactInputParams };
|
|
82
|
+
|
|
83
|
+
export type PreparedExactOutputFromRoute =
|
|
84
|
+
| { kind: "single"; params: ExactOutputSingleParams }
|
|
85
|
+
| { kind: "multihop"; params: ExactOutputParams };
|
|
86
|
+
|
|
87
|
+
function parseAddress(value: string, field: string): Address {
|
|
88
|
+
try {
|
|
89
|
+
return getAddress(value);
|
|
90
|
+
} catch {
|
|
91
|
+
throw new Error(`invalid ${field}: ${value}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function parseAmount(value: string, field: string): bigint {
|
|
96
|
+
try {
|
|
97
|
+
const amount = BigInt(value);
|
|
98
|
+
if (amount < 0n) {
|
|
99
|
+
throw new Error(`${field} must be non-negative`);
|
|
100
|
+
}
|
|
101
|
+
return amount;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
if (error instanceof Error && error.message.includes("must be non-negative")) {
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
throw new Error(`invalid ${field}: ${value}`, { cause: error });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function selectRouteOption(route: RouteResponse): RouteOptionResponse {
|
|
111
|
+
if (route.routes.length === 0) {
|
|
112
|
+
throw new Error("route.routes must not be empty");
|
|
113
|
+
}
|
|
114
|
+
if (route.routes.length > 1) {
|
|
115
|
+
throw new Error("route was split across multiple routes; re-request with maxRoutes=1");
|
|
116
|
+
}
|
|
117
|
+
return route.routes[0]!;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function assertTradeType(
|
|
121
|
+
route: RouteResponse,
|
|
122
|
+
option: RouteOptionResponse,
|
|
123
|
+
tradeType: TradeType,
|
|
124
|
+
): void {
|
|
125
|
+
if (route.tradeType !== tradeType) {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`route tradeType must be ${tradeType}; use ${
|
|
128
|
+
tradeType === "exact_in" ? "prepareExactOutputFromRoute" : "prepareExactInputFromRoute"
|
|
129
|
+
} for ${tradeType === "exact_in" ? "exact_out" : "exact_in"}`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (option.tradeType !== tradeType) {
|
|
133
|
+
throw new Error(`routes[0].tradeType must be ${tradeType}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function validateRouteLegs(
|
|
138
|
+
legs: RouteLegResponse[],
|
|
139
|
+
tokenIn: Address,
|
|
140
|
+
tokenOut: Address,
|
|
141
|
+
): Address[] {
|
|
142
|
+
if (legs.length === 0) {
|
|
143
|
+
throw new Error("routes[0].legs must not be empty");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const pools: Address[] = [];
|
|
147
|
+
for (let i = 0; i < legs.length; i++) {
|
|
148
|
+
const leg = legs[i]!;
|
|
149
|
+
const legTokenIn = parseAddress(leg.tokenIn, `legs[${i}].tokenIn`);
|
|
150
|
+
const legTokenOut = parseAddress(leg.tokenOut, `legs[${i}].tokenOut`);
|
|
151
|
+
pools.push(parseAddress(leg.poolAddress, `legs[${i}].poolAddress`));
|
|
152
|
+
|
|
153
|
+
if (i === 0 && legTokenIn !== tokenIn) {
|
|
154
|
+
throw new Error(`legs[0].tokenIn (${legTokenIn}) does not match route.tokenIn (${tokenIn})`);
|
|
155
|
+
}
|
|
156
|
+
if (i === legs.length - 1 && legTokenOut !== tokenOut) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
`legs[${i}].tokenOut (${legTokenOut}) does not match route.tokenOut (${tokenOut})`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
if (i > 0) {
|
|
162
|
+
const prevLegTokenOut = parseAddress(legs[i - 1]!.tokenOut, `legs[${i - 1}].tokenOut`);
|
|
163
|
+
if (legTokenIn !== prevLegTokenOut) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
`legs[${i}].tokenIn (${legTokenIn}) does not connect to legs[${i - 1}].tokenOut (${prevLegTokenOut})`,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return pools;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function amountOutMinimumFromRoute(amountOut: bigint, slippagePercent: number): bigint {
|
|
175
|
+
const slippageBps = toSlippageBps(slippagePercent);
|
|
176
|
+
return (amountOut * (BPS_BASE - slippageBps)) / BPS_BASE;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function amountInMaximumFromRoute(amountIn: bigint, slippagePercent: number): bigint {
|
|
180
|
+
const slippageBps = toSlippageBps(slippagePercent);
|
|
181
|
+
return ceilDiv(amountIn * (BPS_BASE + slippageBps), BPS_BASE);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Convert a route API exact-in response into SimpleRouter exact-input swap params.
|
|
186
|
+
*
|
|
187
|
+
* Resolves swap direction on-chain, applies slippage to the quoted `amountOut`, and
|
|
188
|
+
* returns params ready for `encodeExactInputSingleCalldata` or `encodeExactInputCalldata`.
|
|
189
|
+
*/
|
|
190
|
+
export async function routeToExactInputParams(
|
|
191
|
+
params: PrepareExactInputFromRouteParams,
|
|
192
|
+
): Promise<PreparedExactInputFromRoute> {
|
|
193
|
+
const { route, publicClient, recipient, deadline, slippagePercent, extensionDatas } = params;
|
|
194
|
+
|
|
195
|
+
const tokenIn = parseAddress(route.tokenIn, "tokenIn");
|
|
196
|
+
const tokenOut = parseAddress(route.tokenOut, "tokenOut");
|
|
197
|
+
const option = selectRouteOption(route);
|
|
198
|
+
assertTradeType(route, option, "exact_in");
|
|
199
|
+
|
|
200
|
+
const requestedAmountIn = parseAmount(route.amountIn, "amountIn");
|
|
201
|
+
const amountIn = parseAmount(option.amountIn, "routes[0].amountIn");
|
|
202
|
+
if (amountIn !== requestedAmountIn) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
"routes[0].amountIn does not match request amountIn; partial fill is not supported",
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
const quotedAmountOut = parseAmount(option.amountOut, "routes[0].amountOut");
|
|
208
|
+
const amountOutMinimum = amountOutMinimumFromRoute(quotedAmountOut, slippagePercent);
|
|
209
|
+
|
|
210
|
+
const pools = validateRouteLegs(option.legs, tokenIn, tokenOut);
|
|
211
|
+
const {
|
|
212
|
+
tokens,
|
|
213
|
+
zeroForOnes,
|
|
214
|
+
extensionDatas: resolvedExtensionDatas,
|
|
215
|
+
zeroForOneBitMap,
|
|
216
|
+
} = await resolveSwapPath(publicClient, tokenIn, tokenOut, pools, extensionDatas);
|
|
217
|
+
|
|
218
|
+
if (pools.length === 1) {
|
|
219
|
+
const leg = option.legs[0]!;
|
|
220
|
+
return {
|
|
221
|
+
kind: "single",
|
|
222
|
+
params: {
|
|
223
|
+
pool: pools[0]!,
|
|
224
|
+
tokenIn,
|
|
225
|
+
tokenOut,
|
|
226
|
+
zeroForOne: zeroForOnes[0]!,
|
|
227
|
+
amountIn,
|
|
228
|
+
amountOutMinimum,
|
|
229
|
+
recipient,
|
|
230
|
+
deadline,
|
|
231
|
+
priceLimitX64: parseAmount(leg.priceLimitX64, "legs[0].priceLimitX64"),
|
|
232
|
+
extensionData: resolvedExtensionDatas[0],
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
kind: "multihop",
|
|
239
|
+
params: {
|
|
240
|
+
tokens,
|
|
241
|
+
pools,
|
|
242
|
+
extensionDatas: resolvedExtensionDatas,
|
|
243
|
+
zeroForOneBitMap,
|
|
244
|
+
amountIn,
|
|
245
|
+
amountOutMinimum,
|
|
246
|
+
recipient,
|
|
247
|
+
deadline,
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Convert a route API exact-out response into SimpleRouter exact-output swap params.
|
|
254
|
+
*
|
|
255
|
+
* Resolves swap direction on-chain, applies slippage to the quoted `amountIn`, and
|
|
256
|
+
* returns params ready for `encodeExactOutputSingleCalldata` or `encodeExactOutputCalldata`.
|
|
257
|
+
*/
|
|
258
|
+
export async function routeToExactOutputParams(
|
|
259
|
+
params: PrepareExactOutputFromRouteParams,
|
|
260
|
+
): Promise<PreparedExactOutputFromRoute> {
|
|
261
|
+
const { route, publicClient, recipient, deadline, slippagePercent, extensionDatas } = params;
|
|
262
|
+
|
|
263
|
+
const tokenIn = parseAddress(route.tokenIn, "tokenIn");
|
|
264
|
+
const tokenOut = parseAddress(route.tokenOut, "tokenOut");
|
|
265
|
+
const option = selectRouteOption(route);
|
|
266
|
+
assertTradeType(route, option, "exact_out");
|
|
267
|
+
|
|
268
|
+
const requestedAmountOut = parseAmount(route.amountOut, "amountOut");
|
|
269
|
+
const amountOut = parseAmount(option.amountOut, "routes[0].amountOut");
|
|
270
|
+
if (amountOut !== requestedAmountOut) {
|
|
271
|
+
throw new Error(
|
|
272
|
+
"routes[0].amountOut does not match request amountOut; partial fill is not supported",
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
const quotedAmountIn = parseAmount(option.amountIn, "routes[0].amountIn");
|
|
276
|
+
const amountInMaximum = amountInMaximumFromRoute(quotedAmountIn, slippagePercent);
|
|
277
|
+
|
|
278
|
+
const pools = validateRouteLegs(option.legs, tokenIn, tokenOut);
|
|
279
|
+
const {
|
|
280
|
+
tokens,
|
|
281
|
+
zeroForOnes,
|
|
282
|
+
extensionDatas: resolvedExtensionDatas,
|
|
283
|
+
zeroForOneBitMap,
|
|
284
|
+
} = await resolveSwapPath(publicClient, tokenIn, tokenOut, pools, extensionDatas);
|
|
285
|
+
|
|
286
|
+
if (pools.length === 1) {
|
|
287
|
+
const leg = option.legs[0]!;
|
|
288
|
+
return {
|
|
289
|
+
kind: "single",
|
|
290
|
+
params: {
|
|
291
|
+
pool: pools[0]!,
|
|
292
|
+
tokenIn,
|
|
293
|
+
tokenOut,
|
|
294
|
+
zeroForOne: zeroForOnes[0]!,
|
|
295
|
+
amountOut,
|
|
296
|
+
amountInMaximum,
|
|
297
|
+
recipient,
|
|
298
|
+
deadline,
|
|
299
|
+
priceLimitX64: parseAmount(leg.priceLimitX64, "legs[0].priceLimitX64"),
|
|
300
|
+
extensionData: resolvedExtensionDatas[0],
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
kind: "multihop",
|
|
307
|
+
params: {
|
|
308
|
+
tokens,
|
|
309
|
+
pools,
|
|
310
|
+
extensionDatas: resolvedExtensionDatas,
|
|
311
|
+
zeroForOneBitMap,
|
|
312
|
+
amountOut,
|
|
313
|
+
amountInMaximum,
|
|
314
|
+
recipient,
|
|
315
|
+
deadline,
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
}
|