@ekubo/yul-router-sdk 0.1.0 → 0.2.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.
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export declare const MIN_CALCULATED_AMOUNT_THRESHOLD: bigint;
5
5
  export declare const MAX_CALCULATED_AMOUNT_THRESHOLD: bigint;
6
6
  export declare const MAX_MULTIHOP_LENGTH = 256;
7
7
  export declare const MAX_HOP_LENGTH = 256;
8
+ export declare const YUL_ROUTER_ADDRESS: Address;
8
9
  export interface PoolKey {
9
10
  token0: Address;
10
11
  token1: Address;
@@ -30,12 +31,22 @@ export interface Ve33Hop {
30
31
  sqrtRatioLimit?: bigint;
31
32
  skipAhead?: number;
32
33
  }
34
+ export interface SignedExclusiveSwapHop {
35
+ type: "signedExclusiveSwap";
36
+ forwardee: Address;
37
+ poolKey: PoolKey;
38
+ meta: bigint | Hex;
39
+ minBalanceUpdate: Hex;
40
+ signature: Hex;
41
+ sqrtRatioLimit?: bigint;
42
+ skipAhead?: number;
43
+ }
33
44
  export interface WrapperHop {
34
45
  type: "wrapper";
35
46
  underlying: Address;
36
47
  wrapped: Address;
37
48
  }
38
- export type Hop = CoreHop | ForwardedHop | Ve33Hop | WrapperHop;
49
+ export type Hop = CoreHop | ForwardedHop | Ve33Hop | SignedExclusiveSwapHop | WrapperHop;
39
50
  export interface MultiHop {
40
51
  specifiedAmount: bigint;
41
52
  hops: readonly Hop[];
@@ -59,4 +70,12 @@ export type Parameters = EncodeRoutesParameters;
59
70
  export declare function encodeRoute(params: EncodeRouteParameters): Hex;
60
71
  export declare function generateCalldata(params: EncodeRoutesParameters): Hex;
61
72
  export declare function encodeRoutes(params: EncodeRoutesParameters): Hex;
73
+ export declare function encodePoolBalanceUpdate(delta0: bigint, delta1: bigint): Hex;
74
+ export interface EncodeSignedSwapMetaParameters {
75
+ authorizedLocker?: Address;
76
+ deadline: number;
77
+ fee?: number;
78
+ nonce: bigint | number;
79
+ }
80
+ export declare function encodeSignedSwapMeta(params: EncodeSignedSwapMetaParameters): Hex;
62
81
  export declare function calldataSize(data: Hex): number;
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ export const MIN_CALCULATED_AMOUNT_THRESHOLD = minInt128;
5
5
  export const MAX_CALCULATED_AMOUNT_THRESHOLD = maxInt128;
6
6
  export const MAX_MULTIHOP_LENGTH = 256;
7
7
  export const MAX_HOP_LENGTH = 256;
8
+ export const YUL_ROUTER_ADDRESS = "0x000000005fdB8E48978C5c804d406b76481674E8";
8
9
  export function encodeRoute(params) {
9
10
  const { specifiedAmount, hops, ...shared } = params;
10
11
  return encodeRoutes({
@@ -73,6 +74,22 @@ export function encodeRoutes(params) {
73
74
  currentToken = nextToken;
74
75
  break;
75
76
  }
77
+ case "signedExclusiveSwap": {
78
+ const { poolKey, forwardee } = hop;
79
+ const { nextToken } = resolvePoolHop(currentToken, poolKey);
80
+ encodedHops.push(concatHex([
81
+ "0x04",
82
+ encodeAddress(forwardee),
83
+ encodePoolKey(poolKey),
84
+ encodeSqrtRatioLimit(hop.sqrtRatioLimit),
85
+ encodeSkipAhead(hop.skipAhead),
86
+ encodeUint256(hop.meta, "meta"),
87
+ encodeBytes32(hop.minBalanceUpdate, "minBalanceUpdate"),
88
+ encodeSignature(hop.signature),
89
+ ]));
90
+ currentToken = nextToken;
91
+ break;
92
+ }
76
93
  case "wrapper": {
77
94
  const underlying = getAddress(hop.underlying);
78
95
  const wrapped = getAddress(hop.wrapped);
@@ -153,6 +170,28 @@ function encodePoolKey(poolKey) {
153
170
  function encodeAddress(address) {
154
171
  return getAddress(address);
155
172
  }
173
+ function encodeUint256(value, name) {
174
+ if (typeof value === "bigint") {
175
+ if (value < 0n || value > (1n << 256n) - 1n) {
176
+ throw new Error(`${name} must fit into uint256`);
177
+ }
178
+ return numberToHex(value, { size: 32 });
179
+ }
180
+ return encodeBytes32(value, name);
181
+ }
182
+ function encodeBytes32(value, name) {
183
+ if (size(value) > 32) {
184
+ throw new Error(`${name} must fit into bytes32`);
185
+ }
186
+ return padHex(value, { size: 32 });
187
+ }
188
+ function encodeSignature(signature) {
189
+ const signatureLength = size(signature);
190
+ if (signatureLength > 0xffffffff) {
191
+ throw new Error("signature length must fit into uint32");
192
+ }
193
+ return concatHex([numberToHex(signatureLength, { size: 4 }), signature]);
194
+ }
156
195
  function encodeSqrtRatioLimit(value) {
157
196
  if (value === undefined || value === 0n) {
158
197
  return "0x000000000000000000000000";
@@ -177,6 +216,32 @@ function encodeInt128(value) {
177
216
  assertInt128(value, "value");
178
217
  return numberToHex(BigInt.asUintN(128, value), { size: 16 });
179
218
  }
219
+ export function encodePoolBalanceUpdate(delta0, delta1) {
220
+ assertInt128(delta0, "delta0");
221
+ assertInt128(delta1, "delta1");
222
+ return numberToHex((BigInt.asUintN(128, delta0) << 128n) | BigInt.asUintN(128, delta1), {
223
+ size: 32,
224
+ });
225
+ }
226
+ export function encodeSignedSwapMeta(params) {
227
+ const { authorizedLocker = "0x0000000000000000000000000000000000000000", deadline, fee = 0, nonce } = params;
228
+ if (!Number.isInteger(deadline) || deadline < 0 || deadline > 0xffffffff) {
229
+ throw new Error("deadline must fit into uint32");
230
+ }
231
+ if (!Number.isInteger(fee) || fee < 0 || fee > 0xffffffff) {
232
+ throw new Error("fee must fit into uint32");
233
+ }
234
+ const nonceValue = BigInt(nonce);
235
+ if (nonceValue < 0n || nonceValue > (1n << 64n) - 1n) {
236
+ throw new Error("nonce must fit into uint64");
237
+ }
238
+ const lockerLow128 = hexToBigInt(getAddress(authorizedLocker)) & ((1n << 128n) - 1n);
239
+ const meta = (BigInt(deadline) << 224n) |
240
+ (BigInt(fee) << 192n) |
241
+ (nonceValue << 128n) |
242
+ lockerLow128;
243
+ return numberToHex(meta, { size: 32 });
244
+ }
180
245
  export function calldataSize(data) {
181
246
  return size(data);
182
247
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ekubo/yul-router-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -18,16 +18,15 @@
18
18
  ],
19
19
  "scripts": {
20
20
  "build": "tsc -p tsconfig.json",
21
- "generate-foundry-testdata": "npm run --silent build && node scripts/generate-foundry-testdata.mjs",
22
- "prepublishOnly": "npm run build && npm test",
23
- "test": "vitest run"
21
+ "generate-foundry-testdata": "bun scripts/generate-foundry-testdata.mjs",
22
+ "prepublishOnly": "bun run build && bun run test",
23
+ "test": "bun test test/index.test.ts"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "viem": "^2.31.7"
27
27
  },
28
28
  "devDependencies": {
29
29
  "typescript": "^5.8.3",
30
- "viem": "^2.31.7",
31
- "vitest": "^3.2.4"
30
+ "viem": "^2.31.7"
32
31
  }
33
32
  }