@uniswap/universal-router-sdk 5.1.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +61 -62
  2. package/dist/cjs/src/entities/actions/uniswap.js +19 -19
  3. package/dist/cjs/src/index.d.ts +3 -0
  4. package/dist/cjs/src/index.js +6 -1
  5. package/dist/cjs/src/index.js.map +1 -1
  6. package/dist/cjs/src/swapRouter.d.ts +17 -1
  7. package/dist/cjs/src/swapRouter.js +83 -8
  8. package/dist/cjs/src/swapRouter.js.map +1 -1
  9. package/dist/cjs/src/types/encodeSwaps.d.ts +149 -0
  10. package/dist/cjs/src/types/encodeSwaps.js +3 -0
  11. package/dist/cjs/src/types/encodeSwaps.js.map +1 -0
  12. package/dist/cjs/src/utils/computeEncodeSwapsAmounts.d.ts +8 -0
  13. package/dist/cjs/src/utils/computeEncodeSwapsAmounts.js +47 -0
  14. package/dist/cjs/src/utils/computeEncodeSwapsAmounts.js.map +1 -0
  15. package/dist/cjs/src/utils/encodeSwapStep.d.ts +4 -0
  16. package/dist/cjs/src/utils/encodeSwapStep.js +61 -0
  17. package/dist/cjs/src/utils/encodeSwapStep.js.map +1 -0
  18. package/dist/cjs/src/utils/encodeV4Action.d.ts +8 -0
  19. package/dist/cjs/src/utils/encodeV4Action.js +97 -0
  20. package/dist/cjs/src/utils/encodeV4Action.js.map +1 -0
  21. package/dist/cjs/src/utils/normalizeEncodeSwapsSpec.d.ts +2 -0
  22. package/dist/cjs/src/utils/normalizeEncodeSwapsSpec.js +18 -0
  23. package/dist/cjs/src/utils/normalizeEncodeSwapsSpec.js.map +1 -0
  24. package/dist/cjs/src/utils/routerCommands.js +5 -5
  25. package/dist/cjs/src/utils/validateEncodeSwaps.d.ts +2 -0
  26. package/dist/cjs/src/utils/validateEncodeSwaps.js +135 -0
  27. package/dist/cjs/src/utils/validateEncodeSwaps.js.map +1 -0
  28. package/dist/esm/src/entities/actions/uniswap.js +19 -19
  29. package/dist/esm/src/index.d.ts +3 -0
  30. package/dist/esm/src/index.js +3 -0
  31. package/dist/esm/src/index.js.map +1 -1
  32. package/dist/esm/src/swapRouter.d.ts +17 -1
  33. package/dist/esm/src/swapRouter.js +85 -10
  34. package/dist/esm/src/swapRouter.js.map +1 -1
  35. package/dist/esm/src/types/encodeSwaps.d.ts +149 -0
  36. package/dist/esm/src/types/encodeSwaps.js +2 -0
  37. package/dist/esm/src/types/encodeSwaps.js.map +1 -0
  38. package/dist/esm/src/utils/computeEncodeSwapsAmounts.d.ts +8 -0
  39. package/dist/esm/src/utils/computeEncodeSwapsAmounts.js +43 -0
  40. package/dist/esm/src/utils/computeEncodeSwapsAmounts.js.map +1 -0
  41. package/dist/esm/src/utils/encodeSwapStep.d.ts +4 -0
  42. package/dist/esm/src/utils/encodeSwapStep.js +57 -0
  43. package/dist/esm/src/utils/encodeSwapStep.js.map +1 -0
  44. package/dist/esm/src/utils/encodeV4Action.d.ts +8 -0
  45. package/dist/esm/src/utils/encodeV4Action.js +92 -0
  46. package/dist/esm/src/utils/encodeV4Action.js.map +1 -0
  47. package/dist/esm/src/utils/normalizeEncodeSwapsSpec.d.ts +2 -0
  48. package/dist/esm/src/utils/normalizeEncodeSwapsSpec.js +14 -0
  49. package/dist/esm/src/utils/normalizeEncodeSwapsSpec.js.map +1 -0
  50. package/dist/esm/src/utils/routerCommands.js +5 -5
  51. package/dist/esm/src/utils/validateEncodeSwaps.d.ts +2 -0
  52. package/dist/esm/src/utils/validateEncodeSwaps.js +130 -0
  53. package/dist/esm/src/utils/validateEncodeSwaps.js.map +1 -0
  54. package/dist/types/src/index.d.ts +3 -0
  55. package/dist/types/src/swapRouter.d.ts +17 -1
  56. package/dist/types/src/types/encodeSwaps.d.ts +149 -0
  57. package/dist/types/src/utils/computeEncodeSwapsAmounts.d.ts +8 -0
  58. package/dist/types/src/utils/encodeSwapStep.d.ts +4 -0
  59. package/dist/types/src/utils/encodeV4Action.d.ts +8 -0
  60. package/dist/types/src/utils/normalizeEncodeSwapsSpec.d.ts +2 -0
  61. package/dist/types/src/utils/validateEncodeSwaps.d.ts +2 -0
  62. package/package.json +3 -3
@@ -0,0 +1,149 @@
1
+ import { BigNumberish } from 'ethers';
2
+ import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core';
3
+ import { type PathKey, type PoolKey } from '@uniswap/v4-sdk';
4
+ import { TokenTransferMode } from '../entities/actions/uniswap';
5
+ import { Permit2Permit } from '../utils/inputTokens';
6
+ import { UniversalRouterVersion } from '../utils/constants';
7
+ export type { PathKey, PoolKey };
8
+ export type Fee = {
9
+ kind: 'portion';
10
+ recipient: string;
11
+ fee: Percent;
12
+ } | {
13
+ kind: 'flat';
14
+ recipient: string;
15
+ amount: BigNumberish;
16
+ };
17
+ export type SwapSpecification = {
18
+ tradeType: TradeType;
19
+ routing: {
20
+ inputToken: Currency;
21
+ outputToken: Currency;
22
+ amount: CurrencyAmount<Currency>;
23
+ quote: CurrencyAmount<Currency>;
24
+ };
25
+ slippageTolerance: Percent;
26
+ recipient?: string;
27
+ fee?: Fee;
28
+ tokenTransferMode?: TokenTransferMode;
29
+ permit?: Permit2Permit;
30
+ chainId?: number;
31
+ deadline?: BigNumberish;
32
+ urVersion?: UniversalRouterVersion;
33
+ safeMode?: boolean;
34
+ };
35
+ export type NormalizedSwapSpecification = Omit<SwapSpecification, 'recipient' | 'tokenTransferMode' | 'urVersion' | 'safeMode'> & {
36
+ recipient: string;
37
+ tokenTransferMode: TokenTransferMode;
38
+ urVersion: UniversalRouterVersion;
39
+ safeMode: boolean;
40
+ };
41
+ export type V2SwapExactIn = {
42
+ type: 'V2_SWAP_EXACT_IN';
43
+ recipient: string;
44
+ amountIn: BigNumberish;
45
+ amountOutMin: BigNumberish;
46
+ path: string[];
47
+ minHopPriceX36?: BigNumberish[];
48
+ };
49
+ export type V2SwapExactOut = {
50
+ type: 'V2_SWAP_EXACT_OUT';
51
+ recipient: string;
52
+ amountOut: BigNumberish;
53
+ amountInMax: BigNumberish;
54
+ path: string[];
55
+ minHopPriceX36?: BigNumberish[];
56
+ };
57
+ export type V3SwapExactIn = {
58
+ type: 'V3_SWAP_EXACT_IN';
59
+ recipient: string;
60
+ amountIn: BigNumberish;
61
+ amountOutMin: BigNumberish;
62
+ path: string;
63
+ minHopPriceX36?: BigNumberish[];
64
+ };
65
+ export type V3SwapExactOut = {
66
+ type: 'V3_SWAP_EXACT_OUT';
67
+ recipient: string;
68
+ amountOut: BigNumberish;
69
+ amountInMax: BigNumberish;
70
+ path: string;
71
+ minHopPriceX36?: BigNumberish[];
72
+ };
73
+ export type V4Swap = {
74
+ type: 'V4_SWAP';
75
+ v4Actions: V4Action[];
76
+ };
77
+ export type WrapEth = {
78
+ type: 'WRAP_ETH';
79
+ recipient: string;
80
+ amount: BigNumberish;
81
+ };
82
+ export type UnwrapWeth = {
83
+ type: 'UNWRAP_WETH';
84
+ recipient: string;
85
+ amountMin: BigNumberish;
86
+ };
87
+ export type SwapStep = V2SwapExactIn | V2SwapExactOut | V3SwapExactIn | V3SwapExactOut | V4Swap | WrapEth | UnwrapWeth;
88
+ export type V4SwapExactIn = {
89
+ action: 'SWAP_EXACT_IN';
90
+ currencyIn: string;
91
+ path: PathKey[];
92
+ amountIn: BigNumberish;
93
+ amountOutMinimum: BigNumberish;
94
+ minHopPriceX36?: BigNumberish[];
95
+ };
96
+ export type V4SwapExactInSingle = {
97
+ action: 'SWAP_EXACT_IN_SINGLE';
98
+ poolKey: PoolKey;
99
+ zeroForOne: boolean;
100
+ amountIn: BigNumberish;
101
+ amountOutMinimum: BigNumberish;
102
+ minHopPriceX36?: BigNumberish;
103
+ hookData: string;
104
+ };
105
+ export type V4SwapExactOut = {
106
+ action: 'SWAP_EXACT_OUT';
107
+ currencyOut: string;
108
+ path: PathKey[];
109
+ amountOut: BigNumberish;
110
+ amountInMaximum: BigNumberish;
111
+ minHopPriceX36?: BigNumberish[];
112
+ };
113
+ export type V4SwapExactOutSingle = {
114
+ action: 'SWAP_EXACT_OUT_SINGLE';
115
+ poolKey: PoolKey;
116
+ zeroForOne: boolean;
117
+ amountOut: BigNumberish;
118
+ amountInMaximum: BigNumberish;
119
+ minHopPriceX36?: BigNumberish;
120
+ hookData: string;
121
+ };
122
+ export type V4Settle = {
123
+ action: 'SETTLE';
124
+ currency: string;
125
+ amount: BigNumberish;
126
+ };
127
+ export type V4SettleAll = {
128
+ action: 'SETTLE_ALL';
129
+ currency: string;
130
+ maxAmount: BigNumberish;
131
+ };
132
+ export type V4Take = {
133
+ action: 'TAKE';
134
+ currency: string;
135
+ recipient: string;
136
+ amount: BigNumberish;
137
+ };
138
+ export type V4TakeAll = {
139
+ action: 'TAKE_ALL';
140
+ currency: string;
141
+ minAmount: BigNumberish;
142
+ };
143
+ export type V4TakePortion = {
144
+ action: 'TAKE_PORTION';
145
+ currency: string;
146
+ recipient: string;
147
+ bips: BigNumberish;
148
+ };
149
+ export type V4Action = V4SwapExactIn | V4SwapExactInSingle | V4SwapExactOut | V4SwapExactOutSingle | V4Settle | V4SettleAll | V4Take | V4TakeAll | V4TakePortion;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=encodeSwaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeSwaps.js","sourceRoot":"","sources":["../../../../src/types/encodeSwaps.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { BigNumber } from 'ethers';
2
+ import { NormalizedSwapSpecification } from '../types/encodeSwaps';
3
+ export type EncodeSwapsAmounts = {
4
+ exactOrMaxAmountIn: BigNumber;
5
+ grossMinOrExactAmountOut: BigNumber;
6
+ netMinOrExactAmountOut: BigNumber;
7
+ };
8
+ export declare function computeEncodeSwapsAmounts(spec: NormalizedSwapSpecification): EncodeSwapsAmounts;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeEncodeSwapsAmounts = void 0;
4
+ const ethers_1 = require("ethers");
5
+ const sdk_core_1 = require("@uniswap/sdk-core");
6
+ const constants_1 = require("./constants");
7
+ const numbers_1 = require("./numbers");
8
+ // Slippage is applied to the quote: scaled down to a floor for exact-input output,
9
+ // scaled up to a ceiling for exact-output input. The unscaled side is the user's exact value.
10
+ // Portion fees pair with exact-input (1e18 precision on >=v2.1.1, bps on v2.0); flat fees pair with exact-output.
11
+ function computeEncodeSwapsAmounts(spec) {
12
+ var _a, _b;
13
+ const routingAmount = ethers_1.BigNumber.from(spec.routing.amount.quotient.toString());
14
+ const routingQuote = ethers_1.BigNumber.from(spec.routing.quote.quotient.toString());
15
+ const slippageNumerator = ethers_1.BigNumber.from(spec.slippageTolerance.numerator.toString());
16
+ const slippageDenominator = ethers_1.BigNumber.from(spec.slippageTolerance.denominator.toString());
17
+ if (spec.tradeType === sdk_core_1.TradeType.EXACT_INPUT) {
18
+ const grossMinOrExactAmountOut = routingQuote
19
+ .mul(slippageDenominator)
20
+ .div(slippageDenominator.add(slippageNumerator));
21
+ if (((_a = spec.fee) === null || _a === void 0 ? void 0 : _a.kind) === 'portion') {
22
+ const feeAmount = (0, constants_1.isAtLeastV2_1_1)(spec.urVersion)
23
+ ? grossMinOrExactAmountOut.mul(ethers_1.BigNumber.from((0, numbers_1.encodeFee1e18)(spec.fee.fee))).div(ethers_1.BigNumber.from(10).pow(18))
24
+ : grossMinOrExactAmountOut.mul(ethers_1.BigNumber.from((0, numbers_1.encodeFeeBips)(spec.fee.fee))).div(10000);
25
+ return {
26
+ exactOrMaxAmountIn: routingAmount,
27
+ grossMinOrExactAmountOut,
28
+ netMinOrExactAmountOut: grossMinOrExactAmountOut.sub(feeAmount),
29
+ };
30
+ }
31
+ return {
32
+ exactOrMaxAmountIn: routingAmount,
33
+ grossMinOrExactAmountOut,
34
+ netMinOrExactAmountOut: grossMinOrExactAmountOut,
35
+ };
36
+ }
37
+ const exactOrMaxAmountIn = routingQuote.mul(slippageDenominator.add(slippageNumerator)).div(slippageDenominator);
38
+ const grossMinOrExactAmountOut = routingAmount;
39
+ const netMinOrExactAmountOut = ((_b = spec.fee) === null || _b === void 0 ? void 0 : _b.kind) === 'flat' ? grossMinOrExactAmountOut.sub(ethers_1.BigNumber.from(spec.fee.amount)) : grossMinOrExactAmountOut;
40
+ return {
41
+ exactOrMaxAmountIn,
42
+ grossMinOrExactAmountOut,
43
+ netMinOrExactAmountOut,
44
+ };
45
+ }
46
+ exports.computeEncodeSwapsAmounts = computeEncodeSwapsAmounts;
47
+ //# sourceMappingURL=computeEncodeSwapsAmounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeEncodeSwapsAmounts.js","sourceRoot":"","sources":["../../../../src/utils/computeEncodeSwapsAmounts.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAClC,gDAA6C;AAC7C,2CAA6C;AAC7C,uCAAwD;AAWxD,mFAAmF;AACnF,8FAA8F;AAC9F,kHAAkH;AAClH,SAAgB,yBAAyB,CAAC,IAAiC;;IACzE,MAAM,aAAa,GAAG,kBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC7E,MAAM,YAAY,GAAG,kBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC3E,MAAM,iBAAiB,GAAG,kBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAA;IACrF,MAAM,mBAAmB,GAAG,kBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEzF,IAAI,IAAI,CAAC,SAAS,KAAK,oBAAS,CAAC,WAAW,EAAE;QAC5C,MAAM,wBAAwB,GAAG,YAAY;aAC1C,GAAG,CAAC,mBAAmB,CAAC;aACxB,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAA;QAElD,IAAI,CAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,MAAK,SAAS,EAAE;YAChC,MAAM,SAAS,GAAG,IAAA,2BAAe,EAAC,IAAI,CAAC,SAAS,CAAC;gBAC/C,CAAC,CAAC,wBAAwB,CAAC,GAAG,CAAC,kBAAS,CAAC,IAAI,CAAC,IAAA,uBAAa,EAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC3G,CAAC,CAAC,wBAAwB,CAAC,GAAG,CAAC,kBAAS,CAAC,IAAI,CAAC,IAAA,uBAAa,EAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAM,CAAC,CAAA;YAEzF,OAAO;gBACL,kBAAkB,EAAE,aAAa;gBACjC,wBAAwB;gBACxB,sBAAsB,EAAE,wBAAwB,CAAC,GAAG,CAAC,SAAS,CAAC;aAChE,CAAA;SACF;QAED,OAAO;YACL,kBAAkB,EAAE,aAAa;YACjC,wBAAwB;YACxB,sBAAsB,EAAE,wBAAwB;SACjD,CAAA;KACF;IAED,MAAM,kBAAkB,GAAG,YAAY,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;IAChH,MAAM,wBAAwB,GAAG,aAAa,CAAA;IAC9C,MAAM,sBAAsB,GAC1B,CAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,MAAK,MAAM,CAAC,CAAC,CAAC,wBAAwB,CAAC,GAAG,CAAC,kBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAA;IAEtH,OAAO;QACL,kBAAkB;QAClB,wBAAwB;QACxB,sBAAsB;KACvB,CAAA;AACH,CAAC;AAxCD,8DAwCC"}
@@ -0,0 +1,4 @@
1
+ import { UniversalRouterVersion } from './constants';
2
+ import { RoutePlanner } from './routerCommands';
3
+ import { SwapStep } from '../types/encodeSwaps';
4
+ export declare function encodeSwapStep(planner: RoutePlanner, step: SwapStep, urVersion?: UniversalRouterVersion): void;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encodeSwapStep = void 0;
4
+ const v4_sdk_1 = require("@uniswap/v4-sdk");
5
+ const constants_1 = require("./constants");
6
+ const routerCommands_1 = require("./routerCommands");
7
+ const encodeV4Action_1 = require("./encodeV4Action");
8
+ // V2/V3 swap params hardcode payerIsUser=false; encodeSwaps pulls funds into the router first via PERMIT2_TRANSFER_FROM
9
+ function encodeSwapStep(planner, step, urVersion) {
10
+ var _a, _b, _c, _d;
11
+ const useV2_1_1 = (0, constants_1.isAtLeastV2_1_1)(urVersion);
12
+ switch (step.type) {
13
+ case 'V2_SWAP_EXACT_IN': {
14
+ const params = [step.recipient, step.amountIn, step.amountOutMin, step.path, false];
15
+ if (useV2_1_1)
16
+ params.push((_a = step.minHopPriceX36) !== null && _a !== void 0 ? _a : []);
17
+ planner.addCommand(routerCommands_1.CommandType.V2_SWAP_EXACT_IN, params, false, urVersion);
18
+ return;
19
+ }
20
+ case 'V2_SWAP_EXACT_OUT': {
21
+ const params = [step.recipient, step.amountOut, step.amountInMax, step.path, false];
22
+ if (useV2_1_1)
23
+ params.push((_b = step.minHopPriceX36) !== null && _b !== void 0 ? _b : []);
24
+ planner.addCommand(routerCommands_1.CommandType.V2_SWAP_EXACT_OUT, params, false, urVersion);
25
+ return;
26
+ }
27
+ case 'V3_SWAP_EXACT_IN': {
28
+ const params = [step.recipient, step.amountIn, step.amountOutMin, step.path, false];
29
+ if (useV2_1_1)
30
+ params.push((_c = step.minHopPriceX36) !== null && _c !== void 0 ? _c : []);
31
+ planner.addCommand(routerCommands_1.CommandType.V3_SWAP_EXACT_IN, params, false, urVersion);
32
+ return;
33
+ }
34
+ case 'V3_SWAP_EXACT_OUT': {
35
+ const params = [step.recipient, step.amountOut, step.amountInMax, step.path, false];
36
+ if (useV2_1_1)
37
+ params.push((_d = step.minHopPriceX36) !== null && _d !== void 0 ? _d : []);
38
+ planner.addCommand(routerCommands_1.CommandType.V3_SWAP_EXACT_OUT, params, false, urVersion);
39
+ return;
40
+ }
41
+ case 'V4_SWAP': {
42
+ const v4Planner = new v4_sdk_1.V4Planner();
43
+ for (const v4Action of step.v4Actions) {
44
+ const encoded = (0, encodeV4Action_1.encodeV4Action)(v4Action, urVersion);
45
+ v4Planner.addAction(encoded.action, encoded.params, (0, encodeV4Action_1.toV4URVersion)(urVersion));
46
+ }
47
+ planner.addCommand(routerCommands_1.CommandType.V4_SWAP, [v4Planner.finalize()], false, urVersion);
48
+ return;
49
+ }
50
+ case 'WRAP_ETH':
51
+ planner.addCommand(routerCommands_1.CommandType.WRAP_ETH, [step.recipient, step.amount], false, urVersion);
52
+ return;
53
+ case 'UNWRAP_WETH':
54
+ planner.addCommand(routerCommands_1.CommandType.UNWRAP_WETH, [step.recipient, step.amountMin], false, urVersion);
55
+ return;
56
+ default:
57
+ throw new Error(`Unknown swap step type: ${step.type}`);
58
+ }
59
+ }
60
+ exports.encodeSwapStep = encodeSwapStep;
61
+ //# sourceMappingURL=encodeSwapStep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeSwapStep.js","sourceRoot":"","sources":["../../../../src/utils/encodeSwapStep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Actions, URVersion } from '@uniswap/v4-sdk';
2
+ import { UniversalRouterVersion } from './constants';
3
+ import { V4Action } from '../types/encodeSwaps';
4
+ export declare function toV4URVersion(version?: UniversalRouterVersion): URVersion;
5
+ export declare function encodeV4Action(v4Action: V4Action, urVersion?: UniversalRouterVersion): {
6
+ action: Actions;
7
+ params: any[];
8
+ };
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encodeV4Action = exports.toV4URVersion = void 0;
4
+ const v4_sdk_1 = require("@uniswap/v4-sdk");
5
+ const constants_1 = require("./constants");
6
+ const ACTION_NAME_TO_ENUM = Object.fromEntries(Object.entries(v4_sdk_1.Actions).filter(([key]) => isNaN(Number(key))));
7
+ const V4_UR_VERSION_MAP = {
8
+ [constants_1.UniversalRouterVersion.V2_0]: v4_sdk_1.URVersion.V2_0,
9
+ [constants_1.UniversalRouterVersion.V2_1_1]: v4_sdk_1.URVersion.V2_1_1,
10
+ };
11
+ function toV4URVersion(version) {
12
+ if (version === undefined)
13
+ return v4_sdk_1.URVersion.V2_0;
14
+ const mapped = V4_UR_VERSION_MAP[version];
15
+ if (!mapped)
16
+ throw new Error(`No v4-sdk URVersion mapping for UniversalRouterVersion: ${version}`);
17
+ return mapped;
18
+ }
19
+ exports.toV4URVersion = toV4URVersion;
20
+ function encodeV4Action(v4Action, urVersion) {
21
+ var _a, _b, _c, _d;
22
+ const action = ACTION_NAME_TO_ENUM[v4Action.action];
23
+ if (action === undefined)
24
+ throw new Error(`Unknown V4 action: ${v4Action.action}`);
25
+ const useV2_1_1 = (0, constants_1.isAtLeastV2_1_1)(urVersion);
26
+ switch (v4Action.action) {
27
+ case 'SWAP_EXACT_IN':
28
+ return {
29
+ action,
30
+ params: [
31
+ {
32
+ currencyIn: v4Action.currencyIn,
33
+ path: v4Action.path,
34
+ ...(useV2_1_1 && { minHopPriceX36: (_a = v4Action.minHopPriceX36) !== null && _a !== void 0 ? _a : [] }),
35
+ amountIn: v4Action.amountIn,
36
+ amountOutMinimum: v4Action.amountOutMinimum,
37
+ },
38
+ ],
39
+ };
40
+ case 'SWAP_EXACT_IN_SINGLE':
41
+ return {
42
+ action,
43
+ params: [
44
+ {
45
+ poolKey: v4Action.poolKey,
46
+ zeroForOne: v4Action.zeroForOne,
47
+ amountIn: v4Action.amountIn,
48
+ amountOutMinimum: v4Action.amountOutMinimum,
49
+ ...(useV2_1_1 && { minHopPriceX36: (_b = v4Action.minHopPriceX36) !== null && _b !== void 0 ? _b : 0 }),
50
+ hookData: v4Action.hookData,
51
+ },
52
+ ],
53
+ };
54
+ case 'SWAP_EXACT_OUT':
55
+ return {
56
+ action,
57
+ params: [
58
+ {
59
+ currencyOut: v4Action.currencyOut,
60
+ path: v4Action.path,
61
+ ...(useV2_1_1 && { minHopPriceX36: (_c = v4Action.minHopPriceX36) !== null && _c !== void 0 ? _c : [] }),
62
+ amountOut: v4Action.amountOut,
63
+ amountInMaximum: v4Action.amountInMaximum,
64
+ },
65
+ ],
66
+ };
67
+ case 'SWAP_EXACT_OUT_SINGLE':
68
+ return {
69
+ action,
70
+ params: [
71
+ {
72
+ poolKey: v4Action.poolKey,
73
+ zeroForOne: v4Action.zeroForOne,
74
+ amountOut: v4Action.amountOut,
75
+ amountInMaximum: v4Action.amountInMaximum,
76
+ ...(useV2_1_1 && { minHopPriceX36: (_d = v4Action.minHopPriceX36) !== null && _d !== void 0 ? _d : 0 }),
77
+ hookData: v4Action.hookData,
78
+ },
79
+ ],
80
+ };
81
+ case 'SETTLE':
82
+ // payerIsUser=false: same router-custody model as encodeSwapStep — funds are already in the router
83
+ return { action, params: [v4Action.currency, v4Action.amount, false] };
84
+ case 'SETTLE_ALL':
85
+ return { action, params: [v4Action.currency, v4Action.maxAmount] };
86
+ case 'TAKE':
87
+ return { action, params: [v4Action.currency, v4Action.recipient, v4Action.amount] };
88
+ case 'TAKE_ALL':
89
+ return { action, params: [v4Action.currency, v4Action.minAmount] };
90
+ case 'TAKE_PORTION':
91
+ return { action, params: [v4Action.currency, v4Action.recipient, v4Action.bips] };
92
+ default:
93
+ throw new Error(`Unhandled V4 action: ${v4Action.action}`);
94
+ }
95
+ }
96
+ exports.encodeV4Action = encodeV4Action;
97
+ //# sourceMappingURL=encodeV4Action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeV4Action.js","sourceRoot":"","sources":["../../../../src/utils/encodeV4Action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { NormalizedSwapSpecification, SwapSpecification } from '../types/encodeSwaps';
2
+ export declare function normalizeEncodeSwapsSpec(spec: SwapSpecification): NormalizedSwapSpecification;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeEncodeSwapsSpec = void 0;
4
+ const uniswap_1 = require("../entities/actions/uniswap");
5
+ const constants_1 = require("./constants");
6
+ // Fills the four optional fields that `validateEncodeSwaps` and `computeEncodeSwapsAmounts` require.
7
+ function normalizeEncodeSwapsSpec(spec) {
8
+ var _a, _b, _c, _d;
9
+ return {
10
+ ...spec,
11
+ recipient: (_a = spec.recipient) !== null && _a !== void 0 ? _a : constants_1.SENDER_AS_RECIPIENT,
12
+ tokenTransferMode: (_b = spec.tokenTransferMode) !== null && _b !== void 0 ? _b : uniswap_1.TokenTransferMode.Permit2,
13
+ urVersion: (_c = spec.urVersion) !== null && _c !== void 0 ? _c : constants_1.UniversalRouterVersion.V2_0,
14
+ safeMode: (_d = spec.safeMode) !== null && _d !== void 0 ? _d : false,
15
+ };
16
+ }
17
+ exports.normalizeEncodeSwapsSpec = normalizeEncodeSwapsSpec;
18
+ //# sourceMappingURL=normalizeEncodeSwapsSpec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeEncodeSwapsSpec.js","sourceRoot":"","sources":["../../../../src/utils/normalizeEncodeSwapsSpec.ts"],"names":[],"mappings":";;;AAAA,yDAA+D;AAE/D,2CAAyE;AAEzE,qGAAqG;AACrG,SAAgB,wBAAwB,CAAC,IAAuB;;IAC9D,OAAO;QACL,GAAG,IAAI;QACP,SAAS,EAAE,MAAA,IAAI,CAAC,SAAS,mCAAI,+BAAmB;QAChD,iBAAiB,EAAE,MAAA,IAAI,CAAC,iBAAiB,mCAAI,2BAAiB,CAAC,OAAO;QACtE,SAAS,EAAE,MAAA,IAAI,CAAC,SAAS,mCAAI,kCAAsB,CAAC,IAAI;QACxD,QAAQ,EAAE,MAAA,IAAI,CAAC,QAAQ,mCAAI,KAAK;KACjC,CAAA;AACH,CAAC;AARD,4DAQC"}
@@ -221,7 +221,7 @@ exports.COMMAND_DEFINITION = {
221
221
  ],
222
222
  },
223
223
  };
224
- // V2.1.1 ABI definitions for V2/V3 swap commands (extended with maxHopSlippage)
224
+ // V2.1.1 ABI definitions for V2/V3 swap commands (extended with minHopPriceX36)
225
225
  exports.V2V3_SWAP_COMMANDS_V2_1_1 = {
226
226
  [CommandType.V3_SWAP_EXACT_IN]: {
227
227
  parser: Parser.Abi,
@@ -231,7 +231,7 @@ exports.V2V3_SWAP_COMMANDS_V2_1_1 = {
231
231
  { name: 'amountOutMin', type: 'uint256' },
232
232
  { name: 'path', subparser: Subparser.V3PathExactIn, type: 'bytes' },
233
233
  { name: 'payerIsUser', type: 'bool' },
234
- { name: 'maxHopSlippage', type: 'uint256[]' },
234
+ { name: 'minHopPriceX36', type: 'uint256[]' },
235
235
  ],
236
236
  },
237
237
  [CommandType.V3_SWAP_EXACT_OUT]: {
@@ -242,7 +242,7 @@ exports.V2V3_SWAP_COMMANDS_V2_1_1 = {
242
242
  { name: 'amountInMax', type: 'uint256' },
243
243
  { name: 'path', subparser: Subparser.V3PathExactOut, type: 'bytes' },
244
244
  { name: 'payerIsUser', type: 'bool' },
245
- { name: 'maxHopSlippage', type: 'uint256[]' },
245
+ { name: 'minHopPriceX36', type: 'uint256[]' },
246
246
  ],
247
247
  },
248
248
  [CommandType.V2_SWAP_EXACT_IN]: {
@@ -253,7 +253,7 @@ exports.V2V3_SWAP_COMMANDS_V2_1_1 = {
253
253
  { name: 'amountOutMin', type: 'uint256' },
254
254
  { name: 'path', type: 'address[]' },
255
255
  { name: 'payerIsUser', type: 'bool' },
256
- { name: 'maxHopSlippage', type: 'uint256[]' },
256
+ { name: 'minHopPriceX36', type: 'uint256[]' },
257
257
  ],
258
258
  },
259
259
  [CommandType.V2_SWAP_EXACT_OUT]: {
@@ -264,7 +264,7 @@ exports.V2V3_SWAP_COMMANDS_V2_1_1 = {
264
264
  { name: 'amountInMax', type: 'uint256' },
265
265
  { name: 'path', type: 'address[]' },
266
266
  { name: 'payerIsUser', type: 'bool' },
267
- { name: 'maxHopSlippage', type: 'uint256[]' },
267
+ { name: 'minHopPriceX36', type: 'uint256[]' },
268
268
  ],
269
269
  },
270
270
  };
@@ -0,0 +1,2 @@
1
+ import { NormalizedSwapSpecification, SwapStep } from '../types/encodeSwaps';
2
+ export declare function validateEncodeSwaps(spec: NormalizedSwapSpecification, swapSteps: SwapStep[]): void;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateEncodeSwaps = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const ethers_1 = require("ethers");
6
+ const tiny_invariant_1 = tslib_1.__importDefault(require("tiny-invariant"));
7
+ const sdk_core_1 = require("@uniswap/sdk-core");
8
+ const uniswap_1 = require("../entities/actions/uniswap");
9
+ const constants_1 = require("./constants");
10
+ // V3 path: 20-byte address + N × (3-byte fee + 20-byte address); minimum is 43 bytes (single hop, N=1)
11
+ // Returns N or undefined if malformed
12
+ function getV3HopCount(path) {
13
+ if (!path.startsWith('0x'))
14
+ return undefined;
15
+ const byteLength = (path.length - 2) / 2;
16
+ if (byteLength < 43)
17
+ return undefined;
18
+ const variableSegmentLength = byteLength - 20;
19
+ if (variableSegmentLength < 23 || variableSegmentLength % 23 !== 0)
20
+ return undefined;
21
+ return variableSegmentLength / 23;
22
+ }
23
+ function hasV4MinHopPriceX36(action) {
24
+ switch (action.action) {
25
+ case 'SWAP_EXACT_IN':
26
+ case 'SWAP_EXACT_OUT':
27
+ case 'SWAP_EXACT_IN_SINGLE':
28
+ case 'SWAP_EXACT_OUT_SINGLE':
29
+ return action.minHopPriceX36 !== undefined;
30
+ default:
31
+ return false;
32
+ }
33
+ }
34
+ function validateV4HopCounts(actions) {
35
+ for (const action of actions) {
36
+ switch (action.action) {
37
+ case 'SWAP_EXACT_IN':
38
+ case 'SWAP_EXACT_OUT':
39
+ (0, tiny_invariant_1.default)(!action.minHopPriceX36 || action.minHopPriceX36.length === action.path.length, 'V4_MIN_HOP_PRICE_X36_LENGTH_MISMATCH');
40
+ break;
41
+ default:
42
+ break;
43
+ }
44
+ }
45
+ }
46
+ function assertRouterRecipient(recipient) {
47
+ (0, tiny_invariant_1.default)(recipient === constants_1.ROUTER_AS_RECIPIENT, 'STEP_RECIPIENT_MUST_BE_ROUTER');
48
+ }
49
+ function assertRouterActionRecipient(recipient) {
50
+ (0, tiny_invariant_1.default)(recipient === constants_1.ROUTER_AS_RECIPIENT, 'V4_ACTION_RECIPIENT_MUST_BE_ROUTER');
51
+ }
52
+ // V4 actions that take a recipient must use router custody so the SDK's settlement sweeps see the funds
53
+ function validateV4Recipients(actions) {
54
+ for (const action of actions) {
55
+ switch (action.action) {
56
+ case 'TAKE':
57
+ case 'TAKE_PORTION':
58
+ assertRouterActionRecipient(action.recipient);
59
+ break;
60
+ default:
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ function validateEncodeSwaps(spec, swapSteps) {
66
+ var _a, _b, _c, _d;
67
+ (0, tiny_invariant_1.default)(swapSteps.length > 0, 'EMPTY_SWAP_STEPS');
68
+ const amountCurrency = spec.routing.amount.currency.wrapped;
69
+ const quoteCurrency = spec.routing.quote.currency.wrapped;
70
+ const inputCurrency = spec.routing.inputToken.wrapped;
71
+ const outputCurrency = spec.routing.outputToken.wrapped;
72
+ (0, tiny_invariant_1.default)(!spec.slippageTolerance.lessThan(0), 'SLIPPAGE_TOLERANCE');
73
+ (0, tiny_invariant_1.default)(spec.recipient !== constants_1.ZERO_ADDRESS, 'RECIPIENT_CANNOT_BE_ZERO');
74
+ (0, tiny_invariant_1.default)(spec.recipient !== constants_1.ROUTER_AS_RECIPIENT, 'RECIPIENT_CANNOT_BE_ROUTER');
75
+ // routing.amount is on the exact side of the trade; routing.quote is on the slippage side
76
+ if (spec.tradeType === sdk_core_1.TradeType.EXACT_INPUT) {
77
+ (0, tiny_invariant_1.default)(amountCurrency.equals(inputCurrency), 'INVALID_ROUTING_AMOUNT_CURRENCY');
78
+ (0, tiny_invariant_1.default)(quoteCurrency.equals(outputCurrency), 'INVALID_ROUTING_QUOTE_CURRENCY');
79
+ }
80
+ else {
81
+ (0, tiny_invariant_1.default)(amountCurrency.equals(outputCurrency), 'INVALID_ROUTING_AMOUNT_CURRENCY');
82
+ (0, tiny_invariant_1.default)(quoteCurrency.equals(inputCurrency), 'INVALID_ROUTING_QUOTE_CURRENCY');
83
+ }
84
+ // ApproveProxy ingress lives upstream in the proxy contract: needs chain id, ERC20 input, no permit2, explicit recipient
85
+ if (spec.tokenTransferMode === uniswap_1.TokenTransferMode.ApproveProxy) {
86
+ (0, tiny_invariant_1.default)(!!spec.chainId, 'PROXY_MISSING_CHAIN_ID');
87
+ (0, tiny_invariant_1.default)(!spec.routing.inputToken.isNative, 'PROXY_NATIVE_INPUT');
88
+ (0, tiny_invariant_1.default)(!spec.permit, 'PROXY_PERMIT_CONFLICT');
89
+ (0, tiny_invariant_1.default)(spec.recipient !== constants_1.SENDER_AS_RECIPIENT, 'PROXY_EXPLICIT_RECIPIENT_REQUIRED');
90
+ }
91
+ // permit2 is ERC20-only; native input pays via msg.value
92
+ (0, tiny_invariant_1.default)(!(spec.routing.inputToken.isNative && spec.permit), 'NATIVE_INPUT_PERMIT');
93
+ // portion fees pair with exact-input (% of variable output); flat fees pair with exact-output (fixed deduction from the target)
94
+ (0, tiny_invariant_1.default)(!(((_a = spec.fee) === null || _a === void 0 ? void 0 : _a.kind) === 'portion' && spec.tradeType !== sdk_core_1.TradeType.EXACT_INPUT), 'INVALID_PORTION_FEE_TRADE_TYPE');
95
+ (0, tiny_invariant_1.default)(!(((_b = spec.fee) === null || _b === void 0 ? void 0 : _b.kind) === 'flat' && spec.tradeType !== sdk_core_1.TradeType.EXACT_OUTPUT), 'INVALID_FLAT_FEE_TRADE_TYPE');
96
+ (0, tiny_invariant_1.default)(!(((_c = spec.fee) === null || _c === void 0 ? void 0 : _c.kind) === 'flat' &&
97
+ ethers_1.BigNumber.from(spec.fee.amount).gt(ethers_1.BigNumber.from(spec.routing.amount.quotient.toString()))), 'FLAT_FEE_GT_AMOUNT');
98
+ // v2.0 PAY_PORTION takes whole bps; fractional bps need >=v2.1.1's PAY_PORTION_FULL_PRECISION
99
+ (0, tiny_invariant_1.default)(!(((_d = spec.fee) === null || _d === void 0 ? void 0 : _d.kind) === 'portion' &&
100
+ spec.urVersion === constants_1.UniversalRouterVersion.V2_0 &&
101
+ !spec.fee.fee.multiply(10000).remainder.equalTo(0)), 'FRACTIONAL_BPS_PORTION_FEE_UNSUPPORTED_ON_V2_0');
102
+ // per-step: capability-gate by UR version, recipients must be router custody, per-hop arrays must match hop counts
103
+ for (const step of swapSteps) {
104
+ if (spec.urVersion === constants_1.UniversalRouterVersion.V2_0) {
105
+ (0, tiny_invariant_1.default)(!('minHopPriceX36' in step) || step.minHopPriceX36 === undefined, 'MIN_HOP_PRICE_X36_UNSUPPORTED_ON_V2_0');
106
+ (0, tiny_invariant_1.default)(!(step.type === 'V4_SWAP' && step.v4Actions.some(hasV4MinHopPriceX36)), 'MIN_HOP_PRICE_X36_UNSUPPORTED_ON_V2_0');
107
+ }
108
+ switch (step.type) {
109
+ case 'V2_SWAP_EXACT_IN':
110
+ case 'V2_SWAP_EXACT_OUT':
111
+ assertRouterRecipient(step.recipient);
112
+ (0, tiny_invariant_1.default)(!step.minHopPriceX36 || step.minHopPriceX36.length === step.path.length - 1, 'V2_MIN_HOP_PRICE_X36_LENGTH_MISMATCH');
113
+ break;
114
+ case 'V3_SWAP_EXACT_IN':
115
+ case 'V3_SWAP_EXACT_OUT': {
116
+ assertRouterRecipient(step.recipient);
117
+ const hopCount = getV3HopCount(step.path);
118
+ (0, tiny_invariant_1.default)(hopCount === undefined || !step.minHopPriceX36 || step.minHopPriceX36.length === hopCount, 'V3_MIN_HOP_PRICE_X36_LENGTH_MISMATCH');
119
+ break;
120
+ }
121
+ case 'WRAP_ETH':
122
+ case 'UNWRAP_WETH':
123
+ assertRouterRecipient(step.recipient);
124
+ break;
125
+ case 'V4_SWAP':
126
+ validateV4HopCounts(step.v4Actions);
127
+ validateV4Recipients(step.v4Actions);
128
+ break;
129
+ default:
130
+ break;
131
+ }
132
+ }
133
+ }
134
+ exports.validateEncodeSwaps = validateEncodeSwaps;
135
+ //# sourceMappingURL=validateEncodeSwaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateEncodeSwaps.js","sourceRoot":"","sources":["../../../../src/utils/validateEncodeSwaps.ts"],"names":[],"mappings":"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"}