@sun-protocol/sun-sdk-sunswap-v4 0.1.0-beta.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.cjs ADDED
@@ -0,0 +1,1186 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ V4_ACTIONS: () => V4_ACTIONS,
24
+ V4_ACTION_CONSTANTS: () => V4_ACTION_CONSTANTS,
25
+ V4_DYNAMIC_FEE_FLAG: () => V4_DYNAMIC_FEE_FLAG,
26
+ V4_EMPTY_PARAMETERS: () => V4_EMPTY_PARAMETERS,
27
+ V4_HOOKS_REGISTRATION_OFFSET: () => V4_HOOKS_REGISTRATION_OFFSET,
28
+ V4_MAX_STATIC_FEE: () => V4_MAX_STATIC_FEE,
29
+ V4_POOL_MANAGER_READ_SELECTORS: () => V4_POOL_MANAGER_READ_SELECTORS,
30
+ V4_POSITION_MANAGER_READ_SELECTORS: () => V4_POSITION_MANAGER_READ_SELECTORS,
31
+ V4_POSITION_MANAGER_SELECTORS: () => V4_POSITION_MANAGER_SELECTORS,
32
+ V4_UINT24_MAX: () => V4_UINT24_MAX,
33
+ assertV4Fee: () => assertV4Fee,
34
+ assertV4HookFeeCombination: () => assertV4HookFeeCombination,
35
+ assertV4PoolId: () => assertV4PoolId,
36
+ assertV4PoolParameters: () => assertV4PoolParameters,
37
+ buildV4CollectAction: () => buildV4CollectAction,
38
+ buildV4DecreaseLiquidityAction: () => buildV4DecreaseLiquidityAction,
39
+ buildV4HookRegistrationBitmapRead: () => buildV4HookRegistrationBitmapRead,
40
+ buildV4IncreaseLiquidityAction: () => buildV4IncreaseLiquidityAction,
41
+ buildV4InitializePoolAction: () => buildV4InitializePoolAction,
42
+ buildV4MintPositionAction: () => buildV4MintPositionAction,
43
+ buildV4ModifyLiquiditiesAction: () => buildV4ModifyLiquiditiesAction,
44
+ buildV4MulticallAction: () => buildV4MulticallAction,
45
+ buildV4PoolAndPositionInfoRead: () => buildV4PoolAndPositionInfoRead,
46
+ buildV4PoolFeeGrowthGlobalsRead: () => buildV4PoolFeeGrowthGlobalsRead,
47
+ buildV4PoolKeyRead: () => buildV4PoolKeyRead,
48
+ buildV4PoolLiquidityRead: () => buildV4PoolLiquidityRead,
49
+ buildV4PoolSlot0Read: () => buildV4PoolSlot0Read,
50
+ buildV4PoolStateReads: () => buildV4PoolStateReads,
51
+ buildV4PositionApprovalForAllRead: () => buildV4PositionApprovalForAllRead,
52
+ buildV4PositionApprovedRead: () => buildV4PositionApprovedRead,
53
+ buildV4PositionFeesRead: () => buildV4PositionFeesRead,
54
+ buildV4PositionLiquidityRead: () => buildV4PositionLiquidityRead,
55
+ buildV4PositionOwnerRead: () => buildV4PositionOwnerRead,
56
+ buildV4PositionReads: () => buildV4PositionReads,
57
+ computeV4PoolId: () => computeV4PoolId,
58
+ createV4PoolKey: () => createV4PoolKey,
59
+ decodeV4HooksRegistration: () => decodeV4HooksRegistration,
60
+ decodeV4PoolParameters: () => decodeV4PoolParameters,
61
+ encodeV4ActionParams: () => encodeV4ActionParams,
62
+ encodeV4Actions: () => encodeV4Actions,
63
+ encodeV4ActionsPlanner: () => encodeV4ActionsPlanner,
64
+ encodeV4CollectPlannerPayload: () => encodeV4CollectPlannerPayload,
65
+ encodeV4ContractCallAction: () => encodeV4ContractCallAction,
66
+ encodeV4DecreaseLiquidityPlannerPayload: () => encodeV4DecreaseLiquidityPlannerPayload,
67
+ encodeV4HooksRegistration: () => encodeV4HooksRegistration,
68
+ encodeV4IncreaseLiquidityPlannerPayload: () => encodeV4IncreaseLiquidityPlannerPayload,
69
+ encodeV4MintPositionPlannerPayload: () => encodeV4MintPositionPlannerPayload,
70
+ encodeV4Permit2ForwardCall: () => encodeV4Permit2ForwardCall,
71
+ encodeV4PoolKey: () => encodeV4PoolKey,
72
+ encodeV4PoolParameters: () => encodeV4PoolParameters,
73
+ getV4StaticFee: () => getV4StaticFee,
74
+ isV4DynamicFee: () => isV4DynamicFee,
75
+ normalizeV4PoolKey: () => normalizeV4PoolKey,
76
+ toV4PoolKeyTuple: () => toV4PoolKeyTuple,
77
+ tronAddressToEvmHex: () => tronAddressToEvmHex
78
+ });
79
+ module.exports = __toCommonJS(index_exports);
80
+
81
+ // src/address.ts
82
+ var import_sha256 = require("@noble/hashes/sha256");
83
+ var import_sun_sdk_core = require("@sun-protocol/sun-sdk-core");
84
+ var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
85
+ var TRON_ADDRESS_BYTES = 21;
86
+ var TRON_ADDRESS_PAYLOAD_BYTES = 25;
87
+ function decodeBase58(value) {
88
+ let decoded = 0n;
89
+ for (const char of value) {
90
+ const index = BASE58_ALPHABET.indexOf(char);
91
+ (0, import_sun_sdk_core.sdkInvariant)(index >= 0, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "Invalid base58 character", { value, char });
92
+ decoded = decoded * 58n + BigInt(index);
93
+ }
94
+ const bytes = [];
95
+ while (decoded > 0n) {
96
+ bytes.unshift(Number(decoded & 0xffn));
97
+ decoded >>= 8n;
98
+ }
99
+ for (const char of value) {
100
+ if (char !== "1") break;
101
+ bytes.unshift(0);
102
+ }
103
+ return Uint8Array.from(bytes);
104
+ }
105
+ function tronAddressToEvmHex(address) {
106
+ const decoded = decodeBase58(address);
107
+ (0, import_sun_sdk_core.sdkInvariant)(
108
+ decoded.length === TRON_ADDRESS_PAYLOAD_BYTES,
109
+ import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
110
+ "TRON address payload must be 25 bytes",
111
+ { address, length: decoded.length }
112
+ );
113
+ const body = decoded.slice(0, TRON_ADDRESS_BYTES);
114
+ (0, import_sun_sdk_core.sdkInvariant)(body[0] === 65, import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "TRON address must use 0x41 prefix", {
115
+ address
116
+ });
117
+ const expectedChecksum = (0, import_sha256.sha256)((0, import_sha256.sha256)(body)).slice(0, 4);
118
+ const actualChecksum = decoded.slice(TRON_ADDRESS_BYTES);
119
+ (0, import_sun_sdk_core.sdkInvariant)(
120
+ expectedChecksum.every((byte, index) => byte === actualChecksum[index]),
121
+ import_sun_sdk_core.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
122
+ "TRON address has invalid base58 checksum",
123
+ { address }
124
+ );
125
+ return `0x${Array.from(body.slice(1)).map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
126
+ }
127
+
128
+ // src/actions.ts
129
+ var import_sun_sdk_chains = require("@sun-protocol/sun-sdk-chains");
130
+ var import_keccak256 = require("@ethersproject/keccak256");
131
+ var import_sun_sdk_core4 = require("@sun-protocol/sun-sdk-core");
132
+
133
+ // src/planner.ts
134
+ var import_sun_sdk_core3 = require("@sun-protocol/sun-sdk-core");
135
+
136
+ // src/pool-key.ts
137
+ var import_sun_sdk_core2 = require("@sun-protocol/sun-sdk-core");
138
+ var V4_DYNAMIC_FEE_FLAG = 8388608;
139
+ var V4_UINT24_MAX = 16777215;
140
+ var V4_MAX_STATIC_FEE = 1e6;
141
+ var V4_EMPTY_PARAMETERS = `0x${"0".repeat(64)}`;
142
+ var BYTES32_PATTERN = /^0x[a-fA-F0-9]{64}$/;
143
+ function sortCurrencies(currencyA, currencyB) {
144
+ (0, import_sun_sdk_core2.sdkInvariant)(
145
+ currencyA !== currencyB,
146
+ import_sun_sdk_core2.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
147
+ "V4 pool currencies must be different",
148
+ { currencyA, currencyB }
149
+ );
150
+ return tronAddressToEvmHex(currencyA) < tronAddressToEvmHex(currencyB) ? [currencyA, currencyB] : [currencyB, currencyA];
151
+ }
152
+ function isV4DynamicFee(fee) {
153
+ return (fee & V4_DYNAMIC_FEE_FLAG) !== 0;
154
+ }
155
+ function getV4StaticFee(fee) {
156
+ return fee & ~V4_DYNAMIC_FEE_FLAG;
157
+ }
158
+ function assertV4PoolParameters(value, label = "parameters") {
159
+ (0, import_sun_sdk_core2.sdkInvariant)(BYTES32_PATTERN.test(value), import_sun_sdk_core2.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be bytes32 hex`, {
160
+ label,
161
+ value
162
+ });
163
+ return value.toLowerCase();
164
+ }
165
+ function assertV4PoolId(value, label = "poolId") {
166
+ (0, import_sun_sdk_core2.sdkInvariant)(BYTES32_PATTERN.test(value), import_sun_sdk_core2.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be bytes32 hex`, {
167
+ label,
168
+ value
169
+ });
170
+ return value.toLowerCase();
171
+ }
172
+ function assertV4Fee(fee) {
173
+ (0, import_sun_sdk_core2.sdkInvariant)(Number.isInteger(fee), import_sun_sdk_core2.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "V4 fee must be an integer", { fee });
174
+ (0, import_sun_sdk_core2.sdkInvariant)(fee >= 0 && fee <= V4_UINT24_MAX, import_sun_sdk_core2.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "V4 fee must fit uint24", {
175
+ fee
176
+ });
177
+ const staticFee = getV4StaticFee(fee);
178
+ (0, import_sun_sdk_core2.sdkInvariant)(
179
+ isV4DynamicFee(fee) || staticFee <= V4_MAX_STATIC_FEE,
180
+ import_sun_sdk_core2.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
181
+ "V4 static fee cannot exceed 100%",
182
+ { fee, staticFee }
183
+ );
184
+ return fee;
185
+ }
186
+ function assertV4HookFeeCombination(hooks, fee) {
187
+ (0, import_sun_sdk_core2.sdkInvariant)(
188
+ !(hooks === import_sun_sdk_core2.TRON_ZERO_ADDRESS && isV4DynamicFee(fee)),
189
+ import_sun_sdk_core2.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
190
+ "V4 dynamic fee requires a non-empty hook address",
191
+ { hooks, fee }
192
+ );
193
+ }
194
+ function normalizeV4PoolKey(input) {
195
+ const currency0 = (0, import_sun_sdk_core2.assertTronAddress)(input.currency0, "currency0");
196
+ const currency1 = (0, import_sun_sdk_core2.assertTronAddress)(input.currency1, "currency1");
197
+ const hooks = (0, import_sun_sdk_core2.assertTronAddress)(input.hooks, "hooks");
198
+ const [sorted0, sorted1] = sortCurrencies(currency0, currency1);
199
+ const fee = assertV4Fee(input.fee);
200
+ assertV4HookFeeCombination(hooks, fee);
201
+ return {
202
+ network: input.network,
203
+ currency0: sorted0,
204
+ currency1: sorted1,
205
+ hooks,
206
+ fee,
207
+ parameters: assertV4PoolParameters(input.parameters)
208
+ };
209
+ }
210
+ function createV4PoolKey(input) {
211
+ const currencyA = (0, import_sun_sdk_core2.assertTronAddress)(input.currencyA, "currencyA");
212
+ const currencyB = (0, import_sun_sdk_core2.assertTronAddress)(input.currencyB, "currencyB");
213
+ const [currency0, currency1] = sortCurrencies(currencyA, currencyB);
214
+ const hooks = (0, import_sun_sdk_core2.assertTronAddress)(input.hooks ?? import_sun_sdk_core2.TRON_ZERO_ADDRESS, "hooks");
215
+ const fee = assertV4Fee(input.fee);
216
+ assertV4HookFeeCombination(hooks, fee);
217
+ return {
218
+ network: input.network,
219
+ currency0,
220
+ currency1,
221
+ hooks,
222
+ fee,
223
+ parameters: assertV4PoolParameters(input.parameters ?? V4_EMPTY_PARAMETERS)
224
+ };
225
+ }
226
+ function toV4PoolKeyTuple(poolKey) {
227
+ const normalized = normalizeV4PoolKey(poolKey);
228
+ return {
229
+ type: "tuple",
230
+ value: {
231
+ currency0: normalized.currency0,
232
+ currency1: normalized.currency1,
233
+ hooks: normalized.hooks,
234
+ fee: normalized.fee,
235
+ parameters: normalized.parameters
236
+ }
237
+ };
238
+ }
239
+
240
+ // src/planner.ts
241
+ var V4_ACTIONS = {
242
+ CL_INCREASE_LIQUIDITY: 0,
243
+ CL_DECREASE_LIQUIDITY: 1,
244
+ CL_MINT_POSITION: 2,
245
+ SETTLE: 11,
246
+ SETTLE_PAIR: 13,
247
+ TAKE_PAIR: 17,
248
+ CLOSE_CURRENCY: 18,
249
+ SWEEP: 20
250
+ };
251
+ var V4_ACTION_CONSTANTS = {
252
+ OPEN_DELTA: 0n,
253
+ MSG_SENDER: "0x0000000000000000000000000000000000000001",
254
+ ADDRESS_THIS: "0x0000000000000000000000000000000000000002"
255
+ };
256
+ var WORD_BYTES = 32;
257
+ var WORD_HEX_LENGTH = WORD_BYTES * 2;
258
+ var HEX_BYTES_PATTERN = /^0x(?:[a-fA-F0-9]{2})*$/;
259
+ var V4_ACTION_NAMES = {
260
+ [V4_ACTIONS.CL_INCREASE_LIQUIDITY]: "CL_INCREASE_LIQUIDITY",
261
+ [V4_ACTIONS.CL_DECREASE_LIQUIDITY]: "CL_DECREASE_LIQUIDITY",
262
+ [V4_ACTIONS.CL_MINT_POSITION]: "CL_MINT_POSITION",
263
+ [V4_ACTIONS.SETTLE]: "SETTLE",
264
+ [V4_ACTIONS.SETTLE_PAIR]: "SETTLE_PAIR",
265
+ [V4_ACTIONS.TAKE_PAIR]: "TAKE_PAIR",
266
+ [V4_ACTIONS.CLOSE_CURRENCY]: "CLOSE_CURRENCY",
267
+ [V4_ACTIONS.SWEEP]: "SWEEP"
268
+ };
269
+ function assertHexBytes(value, label) {
270
+ (0, import_sun_sdk_core3.sdkInvariant)(HEX_BYTES_PATTERN.test(value), import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be 0x-prefixed hex bytes`, {
271
+ label,
272
+ value
273
+ });
274
+ return value.toLowerCase();
275
+ }
276
+ function strip0x(value) {
277
+ return value.startsWith("0x") ? value.slice(2) : value;
278
+ }
279
+ function word(value) {
280
+ (0, import_sun_sdk_core3.sdkInvariant)(value >= 0n, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "ABI word cannot encode a negative uint", {
281
+ value: value.toString()
282
+ });
283
+ return value.toString(16).padStart(WORD_HEX_LENGTH, "0");
284
+ }
285
+ function encodeUint(value, bits, label) {
286
+ const uint = BigInt(value.toString());
287
+ const max = 1n << BigInt(bits);
288
+ (0, import_sun_sdk_core3.sdkInvariant)(uint >= 0n && uint < max, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} is out of uint${bits} range`, {
289
+ label,
290
+ value: uint.toString()
291
+ });
292
+ return word(uint);
293
+ }
294
+ function encodeInt(value, bits, label) {
295
+ (0, import_sun_sdk_core3.sdkInvariant)(Number.isInteger(value), import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be an integer`, { label, value });
296
+ const int = BigInt(value);
297
+ const min = -(1n << BigInt(bits - 1));
298
+ const max = 1n << BigInt(bits - 1);
299
+ (0, import_sun_sdk_core3.sdkInvariant)(int >= min && int < max, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} is out of int${bits} range`, {
300
+ label,
301
+ value
302
+ });
303
+ return word(int >= 0n ? int : (1n << BigInt(WORD_BYTES * 8)) + int);
304
+ }
305
+ function encodeBool(value) {
306
+ return word(value ? 1n : 0n);
307
+ }
308
+ function encodeAddress(value, label) {
309
+ const address = value.startsWith("0x") ? assertHexBytes(value, label) : tronAddressToEvmHex((0, import_sun_sdk_core3.assertTronAddress)(value, label));
310
+ const hex = strip0x(address);
311
+ (0, import_sun_sdk_core3.sdkInvariant)(hex.length === 40, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be a 20-byte address`, {
312
+ label,
313
+ value
314
+ });
315
+ return hex.padStart(WORD_HEX_LENGTH, "0");
316
+ }
317
+ function encodeBytes(value, label) {
318
+ const bytes = strip0x(assertHexBytes(value, label));
319
+ const length = bytes.length / 2;
320
+ const paddedLength = Math.ceil(length / WORD_BYTES) * WORD_HEX_LENGTH;
321
+ return `${word(BigInt(length))}${bytes.padEnd(paddedLength, "0")}`;
322
+ }
323
+ function concatHex(parts) {
324
+ return `0x${parts.join("")}`;
325
+ }
326
+ function encodePoolKeyFields(poolKey) {
327
+ const normalized = normalizeV4PoolKey(poolKey);
328
+ return [
329
+ encodeAddress(normalized.currency0, "poolKey.currency0"),
330
+ encodeAddress(normalized.currency1, "poolKey.currency1"),
331
+ encodeAddress(normalized.hooks, "poolKey.hooks"),
332
+ encodeUint(normalized.fee, 24, "poolKey.fee"),
333
+ strip0x(assertHexBytes(normalized.parameters, "poolKey.parameters"))
334
+ ];
335
+ }
336
+ function encodePositionConfig(config) {
337
+ return [
338
+ ...encodePoolKeyFields(config.poolKey),
339
+ encodeInt(config.tickLower, 24, "tickLower"),
340
+ encodeInt(config.tickUpper, 24, "tickUpper")
341
+ ];
342
+ }
343
+ function encodeWithTrailingBytes(staticParts, bytesValue) {
344
+ return concatHex([...staticParts, word(BigInt((staticParts.length + 1) * WORD_BYTES)), encodeBytes(bytesValue, "hookData")]);
345
+ }
346
+ function assertParamCount(plan, expected) {
347
+ (0, import_sun_sdk_core3.sdkInvariant)(
348
+ plan.params.length === expected,
349
+ import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
350
+ `V4 action ${V4_ACTION_NAMES[plan.action]} expects ${expected} params`,
351
+ { action: plan.action, expected, actual: plan.params.length }
352
+ );
353
+ }
354
+ function paramAt(plan, index) {
355
+ const value = plan.params[index];
356
+ (0, import_sun_sdk_core3.sdkInvariant)(value !== void 0, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `Missing V4 action param at index ${index}`, {
357
+ action: plan.action,
358
+ index
359
+ });
360
+ return value;
361
+ }
362
+ function asPositionConfig(value, label) {
363
+ (0, import_sun_sdk_core3.sdkInvariant)(typeof value === "object" && value !== null && "poolKey" in value, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be a V4 position config`, {
364
+ label
365
+ });
366
+ return value;
367
+ }
368
+ function encodePlanParam(plan) {
369
+ switch (plan.action) {
370
+ case V4_ACTIONS.CL_MINT_POSITION:
371
+ assertParamCount(plan, 6);
372
+ return encodeWithTrailingBytes(
373
+ [
374
+ ...encodePositionConfig(asPositionConfig(paramAt(plan, 0), "positionConfig")),
375
+ encodeUint(paramAt(plan, 1), 128, "liquidity"),
376
+ encodeUint(paramAt(plan, 2), 128, "amount0Max"),
377
+ encodeUint(paramAt(plan, 3), 128, "amount1Max"),
378
+ encodeAddress(paramAt(plan, 4), "owner")
379
+ ],
380
+ paramAt(plan, 5)
381
+ );
382
+ case V4_ACTIONS.CL_INCREASE_LIQUIDITY:
383
+ assertParamCount(plan, 5);
384
+ return encodeWithTrailingBytes(
385
+ [
386
+ encodeUint(paramAt(plan, 0), 256, "tokenId"),
387
+ encodeUint(paramAt(plan, 1), 128, "liquidity"),
388
+ encodeUint(paramAt(plan, 2), 128, "amount0Max"),
389
+ encodeUint(paramAt(plan, 3), 128, "amount1Max")
390
+ ],
391
+ paramAt(plan, 4)
392
+ );
393
+ case V4_ACTIONS.CL_DECREASE_LIQUIDITY:
394
+ assertParamCount(plan, 5);
395
+ return encodeWithTrailingBytes(
396
+ [
397
+ encodeUint(paramAt(plan, 0), 256, "tokenId"),
398
+ encodeUint(paramAt(plan, 1), 128, "liquidity"),
399
+ encodeUint(paramAt(plan, 2), 128, "amount0Min"),
400
+ encodeUint(paramAt(plan, 3), 128, "amount1Min")
401
+ ],
402
+ paramAt(plan, 4)
403
+ );
404
+ case V4_ACTIONS.SETTLE:
405
+ assertParamCount(plan, 3);
406
+ return concatHex([
407
+ encodeAddress(paramAt(plan, 0), "currency"),
408
+ encodeUint(paramAt(plan, 1), 256, "amount"),
409
+ encodeBool(paramAt(plan, 2))
410
+ ]);
411
+ case V4_ACTIONS.SETTLE_PAIR:
412
+ assertParamCount(plan, 2);
413
+ return concatHex([
414
+ encodeAddress(paramAt(plan, 0), "currency0"),
415
+ encodeAddress(paramAt(plan, 1), "currency1")
416
+ ]);
417
+ case V4_ACTIONS.TAKE_PAIR:
418
+ assertParamCount(plan, 3);
419
+ return concatHex([
420
+ encodeAddress(paramAt(plan, 0), "currency0"),
421
+ encodeAddress(paramAt(plan, 1), "currency1"),
422
+ encodeAddress(paramAt(plan, 2), "recipient")
423
+ ]);
424
+ case V4_ACTIONS.CLOSE_CURRENCY:
425
+ assertParamCount(plan, 1);
426
+ return concatHex([encodeAddress(paramAt(plan, 0), "currency")]);
427
+ case V4_ACTIONS.SWEEP:
428
+ assertParamCount(plan, 2);
429
+ return concatHex([
430
+ encodeAddress(paramAt(plan, 0), "currency"),
431
+ encodeAddress(paramAt(plan, 1), "recipient")
432
+ ]);
433
+ default:
434
+ (0, import_sun_sdk_core3.sdkInvariant)(false, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "Unsupported V4 action", { action: plan.action });
435
+ throw new Error("Unsupported V4 action");
436
+ }
437
+ }
438
+ function encodeDynamicBytesArray(values) {
439
+ const encodedValues = values.map((value, index) => encodeBytes(value, `params[${index}]`));
440
+ const offsets = [];
441
+ let tailOffset = BigInt(values.length * WORD_BYTES);
442
+ for (const encodedValue of encodedValues) {
443
+ offsets.push(word(tailOffset));
444
+ tailOffset += BigInt(encodedValue.length / 2);
445
+ }
446
+ return `${word(BigInt(values.length))}${offsets.join("")}${encodedValues.join("")}`;
447
+ }
448
+ function encodeV4Actions(plans) {
449
+ const actions = plans.map((plan) => {
450
+ (0, import_sun_sdk_core3.sdkInvariant)(V4_ACTION_NAMES[plan.action] !== void 0, import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "Unsupported V4 action", {
451
+ action: plan.action
452
+ });
453
+ return plan.action.toString(16).padStart(2, "0");
454
+ });
455
+ return concatHex(actions);
456
+ }
457
+ function encodeV4ActionParams(plans) {
458
+ return plans.map((plan) => encodePlanParam(plan));
459
+ }
460
+ function encodeV4ActionsPlanner(plans) {
461
+ const actions = encodeV4Actions(plans);
462
+ const params = encodeV4ActionParams(plans);
463
+ const encodedActions = encodeBytes(actions, "actions");
464
+ const encodedParams = encodeDynamicBytesArray(params);
465
+ return concatHex([word(64n), word(BigInt(64 + encodedActions.length / 2)), encodedActions, encodedParams]);
466
+ }
467
+ function encodeV4MintPositionPlannerPayload(params) {
468
+ const poolKey = normalizeV4PoolKey(params.positionConfig.poolKey);
469
+ const owner = (0, import_sun_sdk_core3.assertTronAddress)(params.owner, "owner");
470
+ const sweepRecipient = params.sweepRecipient ? (0, import_sun_sdk_core3.assertTronAddress)(params.sweepRecipient, "sweepRecipient") : owner;
471
+ const hookData = params.hookData ?? "0x";
472
+ const plans = [
473
+ {
474
+ action: V4_ACTIONS.CL_MINT_POSITION,
475
+ params: [{ ...params.positionConfig, poolKey }, params.liquidity, params.amount0Max, params.amount1Max, owner, hookData]
476
+ },
477
+ { action: V4_ACTIONS.SETTLE, params: [poolKey.currency0, V4_ACTION_CONSTANTS.OPEN_DELTA, poolKey.currency0 !== import_sun_sdk_core3.TRON_ZERO_ADDRESS] },
478
+ { action: V4_ACTIONS.SETTLE, params: [poolKey.currency1, V4_ACTION_CONSTANTS.OPEN_DELTA, poolKey.currency1 !== import_sun_sdk_core3.TRON_ZERO_ADDRESS] }
479
+ ];
480
+ if (poolKey.currency0 === import_sun_sdk_core3.TRON_ZERO_ADDRESS) {
481
+ plans.push({ action: V4_ACTIONS.SWEEP, params: [poolKey.currency0, sweepRecipient] });
482
+ }
483
+ if (poolKey.currency1 === import_sun_sdk_core3.TRON_ZERO_ADDRESS) {
484
+ plans.push({ action: V4_ACTIONS.SWEEP, params: [poolKey.currency1, sweepRecipient] });
485
+ }
486
+ return encodeV4ActionsPlanner(plans);
487
+ }
488
+ function encodeV4IncreaseLiquidityPlannerPayload(params) {
489
+ const poolKey = normalizeV4PoolKey(params.poolKey);
490
+ const hasNativeCurrency = poolKey.currency0 === import_sun_sdk_core3.TRON_ZERO_ADDRESS || poolKey.currency1 === import_sun_sdk_core3.TRON_ZERO_ADDRESS;
491
+ (0, import_sun_sdk_core3.sdkInvariant)(
492
+ !hasNativeCurrency || params.sweepRecipient !== void 0,
493
+ import_sun_sdk_core3.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
494
+ "sweepRecipient is required when increasing liquidity with native currency"
495
+ );
496
+ const sweepRecipient = params.sweepRecipient !== void 0 ? (0, import_sun_sdk_core3.assertTronAddress)(params.sweepRecipient, "sweepRecipient") : void 0;
497
+ const plans = [
498
+ {
499
+ action: V4_ACTIONS.CL_INCREASE_LIQUIDITY,
500
+ params: [params.tokenId, params.liquidity, params.amount0Max, params.amount1Max, params.hookData ?? "0x"]
501
+ },
502
+ { action: V4_ACTIONS.SETTLE, params: [poolKey.currency0, V4_ACTION_CONSTANTS.OPEN_DELTA, poolKey.currency0 !== import_sun_sdk_core3.TRON_ZERO_ADDRESS] },
503
+ { action: V4_ACTIONS.SETTLE, params: [poolKey.currency1, V4_ACTION_CONSTANTS.OPEN_DELTA, poolKey.currency1 !== import_sun_sdk_core3.TRON_ZERO_ADDRESS] }
504
+ ];
505
+ if (sweepRecipient && poolKey.currency0 === import_sun_sdk_core3.TRON_ZERO_ADDRESS) {
506
+ plans.push({ action: V4_ACTIONS.SWEEP, params: [poolKey.currency0, sweepRecipient] });
507
+ }
508
+ if (sweepRecipient && poolKey.currency1 === import_sun_sdk_core3.TRON_ZERO_ADDRESS) {
509
+ plans.push({ action: V4_ACTIONS.SWEEP, params: [poolKey.currency1, sweepRecipient] });
510
+ }
511
+ return encodeV4ActionsPlanner(plans);
512
+ }
513
+ function encodeV4DecreaseLiquidityPlannerPayload(params) {
514
+ const poolKey = normalizeV4PoolKey(params.poolKey);
515
+ const recipient = (0, import_sun_sdk_core3.assertTronAddress)(params.recipient, "recipient");
516
+ const plans = [
517
+ {
518
+ action: V4_ACTIONS.CL_DECREASE_LIQUIDITY,
519
+ params: [params.tokenId, params.liquidity, params.amount0Min, params.amount1Min, params.hookData ?? "0x"]
520
+ }
521
+ ];
522
+ if (params.settlementMode === "close-currency") {
523
+ plans.push(
524
+ { action: V4_ACTIONS.CLOSE_CURRENCY, params: [poolKey.currency0] },
525
+ { action: V4_ACTIONS.CLOSE_CURRENCY, params: [poolKey.currency1] }
526
+ );
527
+ } else {
528
+ plans.push({ action: V4_ACTIONS.TAKE_PAIR, params: [poolKey.currency0, poolKey.currency1, recipient] });
529
+ }
530
+ return encodeV4ActionsPlanner(plans);
531
+ }
532
+ function encodeV4CollectPlannerPayload(params) {
533
+ const poolKey = normalizeV4PoolKey(params.poolKey);
534
+ const recipient = (0, import_sun_sdk_core3.assertTronAddress)(params.recipient, "recipient");
535
+ return encodeV4ActionsPlanner([{ action: V4_ACTIONS.TAKE_PAIR, params: [poolKey.currency0, poolKey.currency1, recipient] }]);
536
+ }
537
+
538
+ // src/actions.ts
539
+ var V4_POSITION_MANAGER_SELECTORS = {
540
+ initializePool: "initializePool((address,address,address,uint24,bytes32),uint160)",
541
+ modifyLiquidities: "modifyLiquidities(bytes,uint256)",
542
+ multicall: "multicall(bytes[])"
543
+ };
544
+ var HEX_BYTES_PATTERN2 = /^0x(?:[a-fA-F0-9]{2})*$/;
545
+ function calldataWord(value) {
546
+ (0, import_sun_sdk_core4.sdkInvariant)(value >= 0n && value < 1n << 256n, import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "calldata word is out of range", {
547
+ value: value.toString()
548
+ });
549
+ return value.toString(16).padStart(64, "0");
550
+ }
551
+ function calldataAddress(value) {
552
+ const address = String(value);
553
+ const hex = address.startsWith("0x") ? assertHexBytes2(address, "address").slice(2) : tronAddressToEvmHex(address).slice(2);
554
+ (0, import_sun_sdk_core4.sdkInvariant)(hex.length === 40, import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "address must be a 20-byte address", {
555
+ value: address
556
+ });
557
+ return hex.toLowerCase().padStart(64, "0");
558
+ }
559
+ function calldataBytes32(value) {
560
+ const normalized = assertHexBytes2(String(value), "bytes32").slice(2);
561
+ (0, import_sun_sdk_core4.sdkInvariant)(normalized.length === 64, import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "bytes32 must contain exactly 32 bytes");
562
+ return normalized;
563
+ }
564
+ function functionSelector(signature) {
565
+ return (0, import_keccak256.keccak256)(new TextEncoder().encode(signature)).slice(2, 10);
566
+ }
567
+ function dynamicBytes(value) {
568
+ const bytes = assertHexBytes2(String(value), "bytes").slice(2);
569
+ const padding = (64 - bytes.length % 64) % 64;
570
+ return `${calldataWord(BigInt(bytes.length / 2))}${bytes}${"0".repeat(padding)}`;
571
+ }
572
+ function calldataUint(value, bits, label) {
573
+ const integer = BigInt(value.toString());
574
+ const maximum = 1n << BigInt(bits);
575
+ (0, import_sun_sdk_core4.sdkInvariant)(integer >= 0n && integer < maximum, import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} is out of uint${bits} range`, {
576
+ value: integer.toString()
577
+ });
578
+ return calldataWord(integer);
579
+ }
580
+ function encodeV4Permit2ForwardCall(input) {
581
+ const signature = input.permit.signature.startsWith("0x") ? input.permit.signature : `0x${input.permit.signature}`;
582
+ const selector = functionSelector("permit(address,((address,uint160,uint48,uint48),address,uint256),bytes)");
583
+ const signatureOffset = calldataWord(256n);
584
+ return `0x${selector}${calldataAddress(input.owner)}${calldataAddress(input.permit.details.token)}${calldataUint(input.permit.details.amount, 160, "permit amount")}${calldataUint(input.permit.details.expiration, 48, "permit expiration")}${calldataUint(input.permit.details.nonce, 48, "permit nonce")}${calldataAddress(input.permit.spender)}${calldataUint(input.permit.sigDeadline, 256, "permit sigDeadline")}${signatureOffset}${dynamicBytes(signature)}`;
585
+ }
586
+ function encodeV4ContractCallAction(action) {
587
+ if (action.functionSelector === V4_POSITION_MANAGER_SELECTORS.initializePool) {
588
+ const poolKey = action.parameters?.[0]?.value;
589
+ const sqrtPriceX96 = action.parameters?.[1]?.value;
590
+ (0, import_sun_sdk_core4.sdkInvariant)(
591
+ typeof poolKey === "object" && poolKey !== null && sqrtPriceX96 !== void 0,
592
+ import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
593
+ "initializePool action parameters are malformed"
594
+ );
595
+ const key = poolKey;
596
+ return `0x${functionSelector(action.functionSelector)}${calldataAddress(key.currency0)}${calldataAddress(key.currency1)}${calldataAddress(key.hooks)}${calldataWord(BigInt(String(key.fee)))}${calldataBytes32(key.parameters)}${calldataWord(BigInt(String(sqrtPriceX96)))}`;
597
+ }
598
+ if (action.functionSelector === V4_POSITION_MANAGER_SELECTORS.modifyLiquidities) {
599
+ const payload = action.parameters?.[0]?.value;
600
+ const deadline = action.parameters?.[1]?.value;
601
+ (0, import_sun_sdk_core4.sdkInvariant)(payload !== void 0 && deadline !== void 0, import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "modifyLiquidities action parameters are malformed");
602
+ return `0x${functionSelector(action.functionSelector)}${calldataWord(64n)}${calldataWord(BigInt(String(deadline)))}${dynamicBytes(payload)}`;
603
+ }
604
+ (0, import_sun_sdk_core4.sdkInvariant)(false, import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "V4 action cannot be encoded for multicall", {
605
+ functionSelector: action.functionSelector
606
+ });
607
+ throw new Error("Unsupported V4 multicall action");
608
+ }
609
+ function valueOf(value) {
610
+ return BigInt(value.toString()).toString();
611
+ }
612
+ function positionManagerTarget(params) {
613
+ return params.positionManager ?? (0, import_sun_sdk_chains.getContractAddress)(params.network, "sunswapV4PositionManager");
614
+ }
615
+ function actionId(params, suffix) {
616
+ return params.id ?? `sunswap-v4-${suffix}-${params.network}`;
617
+ }
618
+ function assertHexBytes2(value, label) {
619
+ (0, import_sun_sdk_core4.sdkInvariant)(HEX_BYTES_PATTERN2.test(value), import_sun_sdk_core4.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be 0x-prefixed hex bytes`, {
620
+ label,
621
+ value
622
+ });
623
+ return value.toLowerCase();
624
+ }
625
+ function nativeCallValue(poolKey, amount0, amount1) {
626
+ let value = 0n;
627
+ if (poolKey.currency0 === import_sun_sdk_core4.TRON_ZERO_ADDRESS) value += BigInt(amount0.toString());
628
+ if (poolKey.currency1 === import_sun_sdk_core4.TRON_ZERO_ADDRESS) value += BigInt(amount1.toString());
629
+ return value;
630
+ }
631
+ function tokenRequirements(poolKey, amount0, amount1, spender) {
632
+ const requirements = [];
633
+ const normalizedAmount0 = valueOf(amount0);
634
+ const normalizedAmount1 = valueOf(amount1);
635
+ if (poolKey.currency0 !== import_sun_sdk_core4.TRON_ZERO_ADDRESS && BigInt(normalizedAmount0) > 0n) {
636
+ requirements.push({
637
+ token: poolKey.currency0,
638
+ amount: normalizedAmount0,
639
+ spender,
640
+ approval: "approve-or-permit2"
641
+ });
642
+ }
643
+ if (poolKey.currency1 !== import_sun_sdk_core4.TRON_ZERO_ADDRESS && BigInt(normalizedAmount1) > 0n) {
644
+ requirements.push({
645
+ token: poolKey.currency1,
646
+ amount: normalizedAmount1,
647
+ spender,
648
+ approval: "approve-or-permit2"
649
+ });
650
+ }
651
+ return requirements;
652
+ }
653
+ function buildV4InitializePoolAction(params) {
654
+ const poolKey = normalizeV4PoolKey(params.poolKey);
655
+ return (0, import_sun_sdk_core4.createContractCallAction)({
656
+ id: actionId(params, "initialize-pool"),
657
+ target: positionManagerTarget(params),
658
+ functionSelector: V4_POSITION_MANAGER_SELECTORS.initializePool,
659
+ parameters: [toV4PoolKeyTuple(poolKey), { type: "uint160", value: valueOf(params.sqrtPriceX96) }],
660
+ ...params.callValue !== void 0 ? { callValue: params.callValue } : {},
661
+ ...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {},
662
+ ...params.metadata !== void 0 ? { metadata: params.metadata } : {}
663
+ });
664
+ }
665
+ function buildV4ModifyLiquiditiesAction(params) {
666
+ return (0, import_sun_sdk_core4.createContractCallAction)({
667
+ id: actionId(params, "modify-liquidities"),
668
+ target: positionManagerTarget(params),
669
+ functionSelector: V4_POSITION_MANAGER_SELECTORS.modifyLiquidities,
670
+ parameters: [
671
+ { type: "bytes", value: assertHexBytes2(params.payload, "payload") },
672
+ { type: "uint256", value: valueOf(params.deadline) }
673
+ ],
674
+ ...params.callValue !== void 0 ? { callValue: params.callValue } : {},
675
+ ...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {},
676
+ ...params.tokenRequirements !== void 0 ? { tokenRequirements: params.tokenRequirements } : {},
677
+ ...params.metadata !== void 0 ? { metadata: params.metadata } : {}
678
+ });
679
+ }
680
+ function buildV4MulticallAction(params) {
681
+ return (0, import_sun_sdk_core4.createContractCallAction)({
682
+ id: actionId(params, "multicall"),
683
+ target: positionManagerTarget(params),
684
+ functionSelector: V4_POSITION_MANAGER_SELECTORS.multicall,
685
+ parameters: [{ type: "bytes[]", value: params.calls.map((call, index) => assertHexBytes2(call, `calls[${index}]`)) }],
686
+ ...params.callValue !== void 0 ? { callValue: params.callValue } : {},
687
+ ...params.feeLimit !== void 0 ? { feeLimit: params.feeLimit } : {},
688
+ ...params.tokenRequirements !== void 0 ? { tokenRequirements: params.tokenRequirements } : {},
689
+ ...params.metadata !== void 0 ? { metadata: params.metadata } : {}
690
+ });
691
+ }
692
+ function buildV4MintPositionAction(params) {
693
+ const poolKey = normalizeV4PoolKey(params.positionConfig.poolKey);
694
+ const target = positionManagerTarget(params);
695
+ const payload = encodeV4MintPositionPlannerPayload({
696
+ positionConfig: { ...params.positionConfig, poolKey },
697
+ liquidity: params.liquidity,
698
+ amount0Max: params.amount0Max,
699
+ amount1Max: params.amount1Max,
700
+ owner: params.owner,
701
+ ...params.sweepRecipient !== void 0 ? { sweepRecipient: params.sweepRecipient } : {},
702
+ ...params.hookData !== void 0 ? { hookData: params.hookData } : {}
703
+ });
704
+ const computedCallValue = nativeCallValue(poolKey, params.amount0Max, params.amount1Max);
705
+ return buildV4ModifyLiquiditiesAction({
706
+ ...params,
707
+ id: actionId(params, "mint-position"),
708
+ payload,
709
+ deadline: params.deadline,
710
+ callValue: params.callValue ?? computedCallValue,
711
+ tokenRequirements: tokenRequirements(poolKey, params.amount0Max, params.amount1Max, target)
712
+ });
713
+ }
714
+ function buildV4IncreaseLiquidityAction(params) {
715
+ const poolKey = normalizeV4PoolKey(params.poolKey);
716
+ const target = positionManagerTarget(params);
717
+ const payload = encodeV4IncreaseLiquidityPlannerPayload({
718
+ poolKey,
719
+ tokenId: params.tokenId,
720
+ liquidity: params.liquidity,
721
+ amount0Max: params.amount0Max,
722
+ amount1Max: params.amount1Max,
723
+ ...params.sweepRecipient !== void 0 ? { sweepRecipient: params.sweepRecipient } : {},
724
+ ...params.hookData !== void 0 ? { hookData: params.hookData } : {}
725
+ });
726
+ const computedCallValue = nativeCallValue(poolKey, params.amount0Max, params.amount1Max);
727
+ return buildV4ModifyLiquiditiesAction({
728
+ ...params,
729
+ id: actionId(params, "increase-liquidity"),
730
+ payload,
731
+ deadline: params.deadline,
732
+ callValue: params.callValue ?? computedCallValue,
733
+ tokenRequirements: tokenRequirements(poolKey, params.amount0Max, params.amount1Max, target)
734
+ });
735
+ }
736
+ function buildV4DecreaseLiquidityAction(params) {
737
+ const poolKey = normalizeV4PoolKey(params.poolKey);
738
+ const payload = encodeV4DecreaseLiquidityPlannerPayload({
739
+ poolKey,
740
+ tokenId: params.tokenId,
741
+ liquidity: params.liquidity,
742
+ amount0Min: params.amount0Min,
743
+ amount1Min: params.amount1Min,
744
+ recipient: params.recipient,
745
+ ...params.settlementMode !== void 0 ? { settlementMode: params.settlementMode } : {},
746
+ ...params.hookData !== void 0 ? { hookData: params.hookData } : {}
747
+ });
748
+ return buildV4ModifyLiquiditiesAction({
749
+ ...params,
750
+ id: actionId(params, "decrease-liquidity"),
751
+ payload,
752
+ deadline: params.deadline,
753
+ callValue: params.callValue ?? 0n
754
+ });
755
+ }
756
+ function buildV4CollectAction(params) {
757
+ const poolKey = normalizeV4PoolKey(params.poolKey);
758
+ const payload = encodeV4DecreaseLiquidityPlannerPayload({
759
+ poolKey,
760
+ tokenId: params.tokenId,
761
+ liquidity: 0n,
762
+ amount0Min: 0n,
763
+ amount1Min: 0n,
764
+ recipient: params.recipient,
765
+ ...params.settlementMode !== void 0 ? { settlementMode: params.settlementMode } : {},
766
+ ...params.hookData !== void 0 ? { hookData: params.hookData } : {}
767
+ });
768
+ return buildV4ModifyLiquiditiesAction({
769
+ ...params,
770
+ id: actionId(params, "collect"),
771
+ payload,
772
+ deadline: params.deadline,
773
+ callValue: params.callValue ?? 0n
774
+ });
775
+ }
776
+
777
+ // src/parameters.ts
778
+ var import_sun_sdk_core5 = require("@sun-protocol/sun-sdk-core");
779
+ var V4_HOOKS_REGISTRATION_OFFSET = {
780
+ beforeInitialize: 0,
781
+ afterInitialize: 1,
782
+ beforeAddLiquidity: 2,
783
+ afterAddLiquidity: 3,
784
+ beforeRemoveLiquidity: 4,
785
+ afterRemoveLiquidity: 5,
786
+ beforeSwap: 6,
787
+ afterSwap: 7,
788
+ beforeDonate: 8,
789
+ afterDonate: 9,
790
+ beforeSwapReturnsDelta: 10,
791
+ afterSwapReturnsDelta: 11,
792
+ afterAddLiquidityReturnsDelta: 12,
793
+ afterRemoveLiquidityReturnsDelta: 13
794
+ };
795
+ var INT24_MIN = -8388608;
796
+ var INT24_MAX = 8388607;
797
+ var UINT16_MAX = 65535;
798
+ var HOOKS_REGISTRATION_MAX = 16383;
799
+ var BYTES32_HEX_LENGTH = 64;
800
+ function assertInt24(value, label) {
801
+ (0, import_sun_sdk_core5.sdkInvariant)(Number.isInteger(value), import_sun_sdk_core5.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be an integer`, {
802
+ label,
803
+ value
804
+ });
805
+ (0, import_sun_sdk_core5.sdkInvariant)(value >= INT24_MIN && value <= INT24_MAX, import_sun_sdk_core5.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must fit int24`, {
806
+ label,
807
+ value
808
+ });
809
+ return value;
810
+ }
811
+ function signedInt24ToHex(value) {
812
+ const int24 = assertInt24(value, "tickSpacing");
813
+ const encoded = int24 < 0 ? 16777216 + int24 : int24;
814
+ return encoded.toString(16).padStart(6, "0");
815
+ }
816
+ function hexToSignedInt24(hex) {
817
+ const value = Number.parseInt(hex, 16);
818
+ return value >= 8388608 ? value - 16777216 : value;
819
+ }
820
+ function encodeV4HooksRegistration(hooksRegistration = {}) {
821
+ let registration = 0;
822
+ for (const key of Object.keys(V4_HOOKS_REGISTRATION_OFFSET)) {
823
+ if (hooksRegistration[key]) {
824
+ registration |= 1 << V4_HOOKS_REGISTRATION_OFFSET[key];
825
+ }
826
+ }
827
+ return registration;
828
+ }
829
+ function decodeV4HooksRegistration(registration) {
830
+ (0, import_sun_sdk_core5.sdkInvariant)(
831
+ Number.isInteger(registration) && registration >= 0 && registration <= HOOKS_REGISTRATION_MAX,
832
+ import_sun_sdk_core5.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
833
+ "V4 hooks registration must fit the known 14-bit bitmap",
834
+ { registration }
835
+ );
836
+ const decoded = {};
837
+ for (const key of Object.keys(V4_HOOKS_REGISTRATION_OFFSET)) {
838
+ if ((registration & 1 << V4_HOOKS_REGISTRATION_OFFSET[key]) !== 0) {
839
+ decoded[key] = true;
840
+ }
841
+ }
842
+ return decoded;
843
+ }
844
+ function encodeV4PoolParameters(params) {
845
+ const tickSpacing = signedInt24ToHex(params.tickSpacing);
846
+ const hooksRegistration = encodeV4HooksRegistration(params.hooksRegistration);
847
+ (0, import_sun_sdk_core5.sdkInvariant)(
848
+ hooksRegistration <= UINT16_MAX,
849
+ import_sun_sdk_core5.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
850
+ "V4 hooks registration must fit uint16",
851
+ { hooksRegistration }
852
+ );
853
+ const hooksHex = hooksRegistration.toString(16).padStart(4, "0");
854
+ return assertV4PoolParameters(`0x${`${tickSpacing}${hooksHex}`.padStart(BYTES32_HEX_LENGTH, "0")}`);
855
+ }
856
+ function decodeV4PoolParameters(encoded) {
857
+ const parameters = assertV4PoolParameters(encoded);
858
+ const hex = parameters.slice(2);
859
+ const tickSpacingHex = hex.slice(-10, -4);
860
+ const hooksHex = hex.slice(-4);
861
+ const hooksRegistration = Number.parseInt(hooksHex, 16);
862
+ return {
863
+ tickSpacing: hexToSignedInt24(tickSpacingHex),
864
+ hooksRegistration: decodeV4HooksRegistration(hooksRegistration)
865
+ };
866
+ }
867
+
868
+ // src/pool-id.ts
869
+ var import_sun_sdk_core6 = require("@sun-protocol/sun-sdk-core");
870
+ var import_keccak2562 = require("@ethersproject/keccak256");
871
+ var EVM_ADDRESS_HEX_LENGTH = 40;
872
+ var BYTES32_HEX_LENGTH2 = 64;
873
+ function assertHex(value, label) {
874
+ (0, import_sun_sdk_core6.sdkInvariant)(/^0x[a-fA-F0-9]*$/.test(value), import_sun_sdk_core6.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, `${label} must be hex`, {
875
+ label,
876
+ value
877
+ });
878
+ return value.toLowerCase();
879
+ }
880
+ function encodeAbiAddress(value) {
881
+ const address = tronAddressToEvmHex(value).slice(2);
882
+ (0, import_sun_sdk_core6.sdkInvariant)(
883
+ address.length === EVM_ADDRESS_HEX_LENGTH,
884
+ import_sun_sdk_core6.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT,
885
+ "Encoded EVM address must be 20 bytes",
886
+ { value }
887
+ );
888
+ return address.padStart(BYTES32_HEX_LENGTH2, "0");
889
+ }
890
+ function encodeAbiUint24(value) {
891
+ (0, import_sun_sdk_core6.sdkInvariant)(Number.isInteger(value) && value >= 0 && value <= 16777215, import_sun_sdk_core6.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "uint24 value is out of range", {
892
+ value
893
+ });
894
+ return value.toString(16).padStart(BYTES32_HEX_LENGTH2, "0");
895
+ }
896
+ function encodeAbiBytes32(value) {
897
+ const bytes32 = assertHex(value, "bytes32").slice(2);
898
+ (0, import_sun_sdk_core6.sdkInvariant)(bytes32.length === BYTES32_HEX_LENGTH2, import_sun_sdk_core6.SDK_ERROR_CODES.SDK_INVALID_ARGUMENT, "bytes32 must be 32 bytes", {
899
+ value
900
+ });
901
+ return bytes32;
902
+ }
903
+ function encodeV4PoolKey(poolKey) {
904
+ const normalized = normalizeV4PoolKey(poolKey);
905
+ return `0x${[
906
+ encodeAbiAddress(normalized.currency0),
907
+ encodeAbiAddress(normalized.currency1),
908
+ encodeAbiAddress(normalized.hooks),
909
+ encodeAbiUint24(normalized.fee),
910
+ encodeAbiBytes32(normalized.parameters)
911
+ ].join("")}`;
912
+ }
913
+ function computeV4PoolId(poolKey) {
914
+ return (0, import_keccak2562.keccak256)(encodeV4PoolKey(poolKey));
915
+ }
916
+
917
+ // src/reads.ts
918
+ var import_sun_sdk_chains2 = require("@sun-protocol/sun-sdk-chains");
919
+ var V4_POOL_KEY_ABI_COMPONENTS = [
920
+ { name: "currency0", type: "address" },
921
+ { name: "currency1", type: "address" },
922
+ { name: "hooks", type: "address" },
923
+ { name: "fee", type: "uint24" },
924
+ { name: "parameters", type: "bytes32" }
925
+ ];
926
+ function positionReadAbi(name, inputs, outputs) {
927
+ return { type: "function", name, stateMutability: "view", inputs, outputs };
928
+ }
929
+ var V4_POSITION_MANAGER_READ_SELECTORS = {
930
+ ownerOf: "ownerOf(uint256)",
931
+ getApproved: "getApproved(uint256)",
932
+ isApprovedForAll: "isApprovedForAll(address,address)",
933
+ getPoolAndPositionInfo: "getPoolAndPositionInfo(uint256)",
934
+ getPositionLiquidity: "getPositionLiquidity(uint256)"
935
+ };
936
+ var V4_POOL_MANAGER_READ_SELECTORS = {
937
+ getSlot0: "getSlot0(bytes32)",
938
+ getLiquidity: "getLiquidity(bytes32)",
939
+ poolIdToPoolKey: "poolIdToPoolKey(bytes32)",
940
+ getFeeGrowthGlobals: "getFeeGrowthGlobals(bytes32)"
941
+ };
942
+ function valueOf2(value) {
943
+ return BigInt(value.toString()).toString();
944
+ }
945
+ function bytes32ValueOf(value) {
946
+ const normalized = BigInt(value.toString());
947
+ if (normalized < 0n || normalized >= 1n << 256n) {
948
+ throw new RangeError("tokenId must fit in an unsigned 256-bit value");
949
+ }
950
+ return `0x${normalized.toString(16).padStart(64, "0")}`;
951
+ }
952
+ function positionManagerTarget2(params) {
953
+ return params.positionManager ?? (0, import_sun_sdk_chains2.getContractAddress)(params.network, "sunswapV4PositionManager");
954
+ }
955
+ function poolManagerTarget(params) {
956
+ return params.poolManager ?? (0, import_sun_sdk_chains2.getContractAddress)(params.network, "sunswapV4PoolManager");
957
+ }
958
+ function positionManagerRead(params, functionSelector2, parameters, action, abiFunction) {
959
+ return {
960
+ target: positionManagerTarget2(params),
961
+ functionSelector: functionSelector2,
962
+ parameters,
963
+ abiFunction,
964
+ metadata: { protocol: "sunswap-v4", contract: "position-manager", action, network: params.network }
965
+ };
966
+ }
967
+ function poolReadAbi(functionSelector2) {
968
+ const name = functionSelector2.slice(0, functionSelector2.indexOf("("));
969
+ const outputs = {
970
+ getSlot0: [
971
+ { name: "sqrtPriceX96", type: "uint160" },
972
+ { name: "tick", type: "int24" },
973
+ { name: "protocolFee", type: "uint24" },
974
+ { name: "lpFee", type: "uint24" }
975
+ ],
976
+ getLiquidity: [{ name: "liquidity", type: "uint128" }],
977
+ poolIdToPoolKey: V4_POOL_KEY_ABI_COMPONENTS,
978
+ getFeeGrowthGlobals: [
979
+ { name: "feeGrowthGlobal0X128", type: "uint256" },
980
+ { name: "feeGrowthGlobal1X128", type: "uint256" }
981
+ ]
982
+ };
983
+ return positionReadAbi(name, [{ name: "id", type: "bytes32" }], outputs[name] ?? []);
984
+ }
985
+ function poolManagerRead(params, functionSelector2, poolId) {
986
+ return {
987
+ target: poolManagerTarget(params),
988
+ functionSelector: functionSelector2,
989
+ parameters: [{ type: "bytes32", value: assertV4PoolId(poolId) }],
990
+ abiFunction: poolReadAbi(functionSelector2),
991
+ metadata: { protocol: "sunswap-v4", contract: "pool-manager", network: params.network }
992
+ };
993
+ }
994
+ function buildV4PoolSlot0Read(params) {
995
+ return poolManagerRead(params, V4_POOL_MANAGER_READ_SELECTORS.getSlot0, params.poolId);
996
+ }
997
+ function buildV4PoolLiquidityRead(params) {
998
+ return poolManagerRead(params, V4_POOL_MANAGER_READ_SELECTORS.getLiquidity, params.poolId);
999
+ }
1000
+ function buildV4PoolKeyRead(params) {
1001
+ return poolManagerRead(params, V4_POOL_MANAGER_READ_SELECTORS.poolIdToPoolKey, params.poolId);
1002
+ }
1003
+ function buildV4PoolFeeGrowthGlobalsRead(params) {
1004
+ return poolManagerRead(params, V4_POOL_MANAGER_READ_SELECTORS.getFeeGrowthGlobals, params.poolId);
1005
+ }
1006
+ function buildV4HookRegistrationBitmapRead(params) {
1007
+ return {
1008
+ target: params.hooks,
1009
+ functionSelector: "getHooksRegistrationBitmap()",
1010
+ abiFunction: positionReadAbi(
1011
+ "getHooksRegistrationBitmap",
1012
+ [],
1013
+ [{ name: "permissions", type: "uint16" }]
1014
+ ),
1015
+ metadata: {
1016
+ protocol: "sunswap-v4",
1017
+ contract: "hooks",
1018
+ action: "get-registration-bitmap",
1019
+ network: params.network
1020
+ }
1021
+ };
1022
+ }
1023
+ function buildV4PoolStateReads(params) {
1024
+ return [buildV4PoolSlot0Read(params), buildV4PoolLiquidityRead(params)];
1025
+ }
1026
+ function buildV4PositionOwnerRead(params) {
1027
+ return positionManagerRead(
1028
+ params,
1029
+ V4_POSITION_MANAGER_READ_SELECTORS.ownerOf,
1030
+ [{ type: "uint256", value: valueOf2(params.tokenId) }],
1031
+ "owner-of",
1032
+ positionReadAbi("ownerOf", [{ name: "id", type: "uint256" }], [{ name: "owner", type: "address" }])
1033
+ );
1034
+ }
1035
+ function buildV4PositionApprovedRead(params) {
1036
+ return positionManagerRead(
1037
+ params,
1038
+ V4_POSITION_MANAGER_READ_SELECTORS.getApproved,
1039
+ [{ type: "uint256", value: valueOf2(params.tokenId) }],
1040
+ "get-approved",
1041
+ positionReadAbi("getApproved", [{ name: "tokenId", type: "uint256" }], [{ name: "approved", type: "address" }])
1042
+ );
1043
+ }
1044
+ function buildV4PoolAndPositionInfoRead(params) {
1045
+ return positionManagerRead(
1046
+ params,
1047
+ V4_POSITION_MANAGER_READ_SELECTORS.getPoolAndPositionInfo,
1048
+ [{ type: "uint256", value: valueOf2(params.tokenId) }],
1049
+ "get-pool-and-position-info",
1050
+ positionReadAbi(
1051
+ "getPoolAndPositionInfo",
1052
+ [{ name: "tokenId", type: "uint256" }],
1053
+ [
1054
+ { name: "poolKey", type: "tuple", components: V4_POOL_KEY_ABI_COMPONENTS },
1055
+ { name: "info", type: "uint256" }
1056
+ ]
1057
+ )
1058
+ );
1059
+ }
1060
+ function buildV4PositionLiquidityRead(params) {
1061
+ return positionManagerRead(
1062
+ params,
1063
+ V4_POSITION_MANAGER_READ_SELECTORS.getPositionLiquidity,
1064
+ [{ type: "uint256", value: valueOf2(params.tokenId) }],
1065
+ "get-position-liquidity",
1066
+ positionReadAbi("getPositionLiquidity", [{ name: "tokenId", type: "uint256" }], [{ name: "liquidity", type: "uint128" }])
1067
+ );
1068
+ }
1069
+ function buildV4PositionApprovalForAllRead(params) {
1070
+ return positionManagerRead(
1071
+ params,
1072
+ V4_POSITION_MANAGER_READ_SELECTORS.isApprovedForAll,
1073
+ [
1074
+ { type: "address", value: params.owner },
1075
+ { type: "address", value: params.operator }
1076
+ ],
1077
+ "is-approved-for-all",
1078
+ positionReadAbi(
1079
+ "isApprovedForAll",
1080
+ [{ name: "owner", type: "address" }, { name: "operator", type: "address" }],
1081
+ [{ name: "approved", type: "bool" }]
1082
+ )
1083
+ );
1084
+ }
1085
+ function buildV4PositionFeesRead(params) {
1086
+ return {
1087
+ target: params.lpFeeHelper ?? (0, import_sun_sdk_chains2.getContractAddress)(params.network, "sunswapV4LpFeeHelper"),
1088
+ functionSelector: "getLPFees(address,bytes32,address,int24,int24,bytes32)",
1089
+ parameters: [
1090
+ { type: "address", value: poolManagerTarget(params) },
1091
+ { type: "bytes32", value: assertV4PoolId(params.poolId) },
1092
+ { type: "address", value: positionManagerTarget2(params) },
1093
+ { type: "int24", value: params.tickLower },
1094
+ { type: "int24", value: params.tickUpper },
1095
+ { type: "bytes32", value: bytes32ValueOf(params.tokenId) }
1096
+ ],
1097
+ abiFunction: positionReadAbi(
1098
+ "getLPFees",
1099
+ [
1100
+ { name: "poolManager", type: "address" },
1101
+ { name: "poolId", type: "bytes32" },
1102
+ { name: "owner", type: "address" },
1103
+ { name: "tickLower", type: "int24" },
1104
+ { name: "tickUpper", type: "int24" },
1105
+ { name: "salt", type: "bytes32" }
1106
+ ],
1107
+ [
1108
+ { name: "feesOwed0", type: "uint256" },
1109
+ { name: "feesOwed1", type: "uint256" }
1110
+ ]
1111
+ ),
1112
+ metadata: {
1113
+ protocol: "sunswap-v4",
1114
+ contract: "lp-fee-helper",
1115
+ action: "get-position-fees",
1116
+ network: params.network
1117
+ }
1118
+ };
1119
+ }
1120
+ function buildV4PositionReads(params) {
1121
+ return [
1122
+ buildV4PoolAndPositionInfoRead(params),
1123
+ buildV4PositionLiquidityRead(params),
1124
+ buildV4PositionOwnerRead(params),
1125
+ buildV4PositionApprovedRead(params)
1126
+ ];
1127
+ }
1128
+ // Annotate the CommonJS export names for ESM import in node:
1129
+ 0 && (module.exports = {
1130
+ V4_ACTIONS,
1131
+ V4_ACTION_CONSTANTS,
1132
+ V4_DYNAMIC_FEE_FLAG,
1133
+ V4_EMPTY_PARAMETERS,
1134
+ V4_HOOKS_REGISTRATION_OFFSET,
1135
+ V4_MAX_STATIC_FEE,
1136
+ V4_POOL_MANAGER_READ_SELECTORS,
1137
+ V4_POSITION_MANAGER_READ_SELECTORS,
1138
+ V4_POSITION_MANAGER_SELECTORS,
1139
+ V4_UINT24_MAX,
1140
+ assertV4Fee,
1141
+ assertV4HookFeeCombination,
1142
+ assertV4PoolId,
1143
+ assertV4PoolParameters,
1144
+ buildV4CollectAction,
1145
+ buildV4DecreaseLiquidityAction,
1146
+ buildV4HookRegistrationBitmapRead,
1147
+ buildV4IncreaseLiquidityAction,
1148
+ buildV4InitializePoolAction,
1149
+ buildV4MintPositionAction,
1150
+ buildV4ModifyLiquiditiesAction,
1151
+ buildV4MulticallAction,
1152
+ buildV4PoolAndPositionInfoRead,
1153
+ buildV4PoolFeeGrowthGlobalsRead,
1154
+ buildV4PoolKeyRead,
1155
+ buildV4PoolLiquidityRead,
1156
+ buildV4PoolSlot0Read,
1157
+ buildV4PoolStateReads,
1158
+ buildV4PositionApprovalForAllRead,
1159
+ buildV4PositionApprovedRead,
1160
+ buildV4PositionFeesRead,
1161
+ buildV4PositionLiquidityRead,
1162
+ buildV4PositionOwnerRead,
1163
+ buildV4PositionReads,
1164
+ computeV4PoolId,
1165
+ createV4PoolKey,
1166
+ decodeV4HooksRegistration,
1167
+ decodeV4PoolParameters,
1168
+ encodeV4ActionParams,
1169
+ encodeV4Actions,
1170
+ encodeV4ActionsPlanner,
1171
+ encodeV4CollectPlannerPayload,
1172
+ encodeV4ContractCallAction,
1173
+ encodeV4DecreaseLiquidityPlannerPayload,
1174
+ encodeV4HooksRegistration,
1175
+ encodeV4IncreaseLiquidityPlannerPayload,
1176
+ encodeV4MintPositionPlannerPayload,
1177
+ encodeV4Permit2ForwardCall,
1178
+ encodeV4PoolKey,
1179
+ encodeV4PoolParameters,
1180
+ getV4StaticFee,
1181
+ isV4DynamicFee,
1182
+ normalizeV4PoolKey,
1183
+ toV4PoolKeyTuple,
1184
+ tronAddressToEvmHex
1185
+ });
1186
+ //# sourceMappingURL=index.cjs.map