@pafi-dev/core 0.3.0-beta.0 → 0.3.0-beta.2

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.
@@ -0,0 +1,311 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+ var _chunkIPXARZ6Fcjs = require('./chunk-IPXARZ6F.cjs');
6
+
7
+
8
+ var _chunk5QJZT7VBcjs = require('./chunk-5QJZT7VB.cjs');
9
+
10
+ // src/swap/approval.ts
11
+ var _viem = require('viem');
12
+ async function checkAllowance(client, token, owner, spender) {
13
+ return client.readContract({
14
+ address: token,
15
+ abi: _chunkIPXARZ6Fcjs.erc20Abi,
16
+ functionName: "allowance",
17
+ args: [owner, spender]
18
+ });
19
+ }
20
+ function buildErc20ApprovalCalldata(spender, amount) {
21
+ return _viem.encodeFunctionData.call(void 0, {
22
+ abi: _chunkIPXARZ6Fcjs.erc20Abi,
23
+ functionName: "approve",
24
+ args: [spender, amount]
25
+ });
26
+ }
27
+ function buildPermit2ApprovalCalldata(token, spender, amount, expiration) {
28
+ return _viem.encodeFunctionData.call(void 0, {
29
+ abi: _chunkIPXARZ6Fcjs.permit2Abi,
30
+ functionName: "approve",
31
+ args: [token, spender, amount, expiration]
32
+ });
33
+ }
34
+
35
+ // src/swap/universalRouter.ts
36
+
37
+ var V4_SWAP = 16;
38
+ var SWAP_EXACT_IN = 7;
39
+ var SETTLE_ALL = 12;
40
+ var TAKE_ALL = 15;
41
+ var PATH_KEY_ABI_COMPONENTS = [
42
+ { name: "intermediateCurrency", type: "address" },
43
+ { name: "fee", type: "uint256" },
44
+ { name: "tickSpacing", type: "int24" },
45
+ { name: "hooks", type: "address" },
46
+ { name: "hookData", type: "bytes" }
47
+ ];
48
+ var EXACT_INPUT_PARAMS_ABI = [
49
+ { name: "currencyIn", type: "address" },
50
+ {
51
+ name: "path",
52
+ type: "tuple[]",
53
+ components: PATH_KEY_ABI_COMPONENTS
54
+ },
55
+ { name: "amountIn", type: "uint128" },
56
+ { name: "amountOutMinimum", type: "uint128" }
57
+ ];
58
+ function buildV4SwapInput(currencyIn, path, amountIn, minAmountOut, outputCurrency) {
59
+ const actions = _viem.encodePacked.call(void 0,
60
+ ["uint8", "uint8", "uint8"],
61
+ [SWAP_EXACT_IN, SETTLE_ALL, TAKE_ALL]
62
+ );
63
+ const swapParam = _viem.encodeAbiParameters.call(void 0,
64
+ [{ name: "swap", type: "tuple", components: EXACT_INPUT_PARAMS_ABI }],
65
+ [
66
+ {
67
+ currencyIn,
68
+ path: path.map((p) => ({
69
+ intermediateCurrency: p.intermediateCurrency,
70
+ fee: BigInt(p.fee),
71
+ tickSpacing: p.tickSpacing,
72
+ hooks: p.hooks,
73
+ hookData: p.hookData
74
+ })),
75
+ amountIn,
76
+ amountOutMinimum: minAmountOut
77
+ }
78
+ ]
79
+ );
80
+ const settleParam = _viem.encodeAbiParameters.call(void 0,
81
+ [
82
+ { name: "currency", type: "address" },
83
+ { name: "maxAmount", type: "uint256" }
84
+ ],
85
+ [currencyIn, amountIn]
86
+ );
87
+ const takeParam = _viem.encodeAbiParameters.call(void 0,
88
+ [
89
+ { name: "currency", type: "address" },
90
+ { name: "minAmount", type: "uint256" }
91
+ ],
92
+ [outputCurrency, minAmountOut]
93
+ );
94
+ return _viem.encodeAbiParameters.call(void 0,
95
+ [
96
+ { name: "actions", type: "bytes" },
97
+ { name: "params", type: "bytes[]" }
98
+ ],
99
+ [actions, [swapParam, settleParam, takeParam]]
100
+ );
101
+ }
102
+ function buildUniversalRouterExecuteArgs(currencyIn, path, amountIn, minAmountOut, outputCurrency) {
103
+ const commands = _viem.encodePacked.call(void 0, ["uint8"], [V4_SWAP]);
104
+ const inputs = [
105
+ buildV4SwapInput(currencyIn, path, amountIn, minAmountOut, outputCurrency)
106
+ ];
107
+ return { commands, inputs };
108
+ }
109
+ function buildSwapFromQuote(params) {
110
+ return buildUniversalRouterExecuteArgs(
111
+ params.currencyIn,
112
+ params.quote.path,
113
+ params.amountIn,
114
+ params.minAmountOut,
115
+ params.currencyOut
116
+ );
117
+ }
118
+
119
+ // src/swap/simulate.ts
120
+ async function simulateSwap(client, routerAddress, commands, inputs, deadline, from) {
121
+ try {
122
+ const gasEstimate = await client.estimateContractGas({
123
+ address: routerAddress,
124
+ abi: _chunkIPXARZ6Fcjs.universalRouterAbi,
125
+ functionName: "execute",
126
+ args: [commands, inputs, deadline],
127
+ account: from
128
+ });
129
+ return { success: true, gasEstimate };
130
+ } catch (error) {
131
+ const message = error instanceof Error ? error.message : "Unknown simulation error";
132
+ throw new (0, _chunk5QJZT7VBcjs.SimulationError)("swap", message);
133
+ }
134
+ }
135
+
136
+ // src/swap/buildSwapWithGasDeduction.ts
137
+
138
+
139
+ // src/userop/batchExecute.ts
140
+
141
+ var BATCH_EXECUTOR_ABI = _viem.parseAbi.call(void 0, [
142
+ "function execute((address target, uint256 value, bytes data)[] calls)"
143
+ ]);
144
+ function encodeBatchExecute(operations) {
145
+ if (operations.length === 0) {
146
+ throw new Error("encodeBatchExecute: operations array must not be empty");
147
+ }
148
+ return _viem.encodeFunctionData.call(void 0, {
149
+ abi: BATCH_EXECUTOR_ABI,
150
+ functionName: "execute",
151
+ args: [
152
+ operations.map((op) => ({
153
+ target: op.target,
154
+ value: op.value,
155
+ data: op.data
156
+ }))
157
+ ]
158
+ });
159
+ }
160
+
161
+ // src/userop/buildUserOperation.ts
162
+ var DEFAULT_CALL_GAS_LIMIT = 500000n;
163
+ var DEFAULT_VERIFICATION_GAS_LIMIT = 150000n;
164
+ var DEFAULT_PRE_VERIFICATION_GAS = 50000n;
165
+ function buildPartialUserOperation(params) {
166
+ return {
167
+ sender: params.sender,
168
+ nonce: params.nonce,
169
+ callData: encodeBatchExecute(params.operations),
170
+ callGasLimit: _nullishCoalesce(_optionalChain([params, 'access', _ => _.gasLimits, 'optionalAccess', _2 => _2.callGasLimit]), () => ( DEFAULT_CALL_GAS_LIMIT)),
171
+ verificationGasLimit: _nullishCoalesce(_optionalChain([params, 'access', _3 => _3.gasLimits, 'optionalAccess', _4 => _4.verificationGasLimit]), () => ( DEFAULT_VERIFICATION_GAS_LIMIT)),
172
+ preVerificationGas: _nullishCoalesce(_optionalChain([params, 'access', _5 => _5.gasLimits, 'optionalAccess', _6 => _6.preVerificationGas]), () => ( DEFAULT_PRE_VERIFICATION_GAS)),
173
+ maxFeePerGas: _nullishCoalesce(_optionalChain([params, 'access', _7 => _7.feeOverrides, 'optionalAccess', _8 => _8.maxFeePerGas]), () => ( 0n)),
174
+ maxPriorityFeePerGas: _nullishCoalesce(_optionalChain([params, 'access', _9 => _9.feeOverrides, 'optionalAccess', _10 => _10.maxPriorityFeePerGas]), () => ( 0n))
175
+ };
176
+ }
177
+ function assembleUserOperation(partial, paymaster, signature) {
178
+ return {
179
+ ...partial,
180
+ paymaster: paymaster.paymaster,
181
+ paymasterData: paymaster.paymasterData,
182
+ paymasterVerificationGasLimit: paymaster.paymasterVerificationGasLimit,
183
+ paymasterPostOpGasLimit: paymaster.paymasterPostOpGasLimit,
184
+ signature
185
+ };
186
+ }
187
+
188
+ // src/userop/operations.ts
189
+
190
+ var ERC20_BURNABLE_ABI = _viem.parseAbi.call(void 0, ["function burn(uint256 amount)"]);
191
+ function erc20TransferOp(token, to, amount) {
192
+ return {
193
+ target: token,
194
+ value: 0n,
195
+ data: _viem.encodeFunctionData.call(void 0, {
196
+ abi: _viem.erc20Abi,
197
+ functionName: "transfer",
198
+ args: [to, amount]
199
+ })
200
+ };
201
+ }
202
+ function erc20ApproveOp(token, spender, amount) {
203
+ return {
204
+ target: token,
205
+ value: 0n,
206
+ data: _viem.encodeFunctionData.call(void 0, {
207
+ abi: _viem.erc20Abi,
208
+ functionName: "approve",
209
+ args: [spender, amount]
210
+ })
211
+ };
212
+ }
213
+ function erc20BurnOp(token, amount) {
214
+ return {
215
+ target: token,
216
+ value: 0n,
217
+ data: _viem.encodeFunctionData.call(void 0, {
218
+ abi: ERC20_BURNABLE_ABI,
219
+ functionName: "burn",
220
+ args: [amount]
221
+ })
222
+ };
223
+ }
224
+ function rawCallOp(target, data, value = 0n) {
225
+ return { target, value, data };
226
+ }
227
+
228
+ // src/swap/buildSwapWithGasDeduction.ts
229
+ function buildSwapWithGasDeduction(params) {
230
+ if (params.amountIn <= 0n) {
231
+ throw new Error("buildSwapWithGasDeduction: amountIn must be positive");
232
+ }
233
+ if (params.minAmountOut < 0n) {
234
+ throw new Error(
235
+ "buildSwapWithGasDeduction: minAmountOut must be non-negative"
236
+ );
237
+ }
238
+ if (params.gasFeePt < 0n) {
239
+ throw new Error(
240
+ "buildSwapWithGasDeduction: gasFeePt must be non-negative"
241
+ );
242
+ }
243
+ if (params.swapPath.length === 0) {
244
+ throw new Error(
245
+ "buildSwapWithGasDeduction: swapPath must contain at least one PathKey"
246
+ );
247
+ }
248
+ const { commands, inputs } = buildUniversalRouterExecuteArgs(
249
+ params.pointTokenAddress,
250
+ params.swapPath,
251
+ params.amountIn,
252
+ params.minAmountOut,
253
+ params.outputTokenAddress
254
+ );
255
+ const swapCallData = _viem.encodeFunctionData.call(void 0, {
256
+ abi: _chunkIPXARZ6Fcjs.universalRouterAbi,
257
+ functionName: "execute",
258
+ args: [commands, inputs, params.deadline]
259
+ });
260
+ const operations = [
261
+ erc20ApproveOp(
262
+ params.pointTokenAddress,
263
+ params.universalRouterAddress,
264
+ params.amountIn
265
+ ),
266
+ rawCallOp(params.universalRouterAddress, swapCallData)
267
+ ];
268
+ if (params.gasFeePt > 0n) {
269
+ operations.push(
270
+ erc20TransferOp(
271
+ params.pointTokenAddress,
272
+ params.feeRecipient,
273
+ params.gasFeePt
274
+ )
275
+ );
276
+ }
277
+ return buildPartialUserOperation({
278
+ sender: params.userAddress,
279
+ nonce: params.aaNonce,
280
+ operations,
281
+ gasLimits: {
282
+ callGasLimit: _nullishCoalesce(_optionalChain([params, 'access', _11 => _11.gasLimits, 'optionalAccess', _12 => _12.callGasLimit]), () => ( 700000n)),
283
+ verificationGasLimit: _nullishCoalesce(_optionalChain([params, 'access', _13 => _13.gasLimits, 'optionalAccess', _14 => _14.verificationGasLimit]), () => ( 150000n)),
284
+ preVerificationGas: _nullishCoalesce(_optionalChain([params, 'access', _15 => _15.gasLimits, 'optionalAccess', _16 => _16.preVerificationGas]), () => ( 50000n))
285
+ }
286
+ });
287
+ }
288
+
289
+
290
+
291
+
292
+
293
+
294
+
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+ exports.checkAllowance = checkAllowance; exports.buildErc20ApprovalCalldata = buildErc20ApprovalCalldata; exports.buildPermit2ApprovalCalldata = buildPermit2ApprovalCalldata; exports.V4_SWAP = V4_SWAP; exports.SWAP_EXACT_IN = SWAP_EXACT_IN; exports.SETTLE_ALL = SETTLE_ALL; exports.TAKE_ALL = TAKE_ALL; exports.buildV4SwapInput = buildV4SwapInput; exports.buildUniversalRouterExecuteArgs = buildUniversalRouterExecuteArgs; exports.buildSwapFromQuote = buildSwapFromQuote; exports.simulateSwap = simulateSwap; exports.BATCH_EXECUTOR_ABI = BATCH_EXECUTOR_ABI; exports.encodeBatchExecute = encodeBatchExecute; exports.buildPartialUserOperation = buildPartialUserOperation; exports.assembleUserOperation = assembleUserOperation; exports.erc20TransferOp = erc20TransferOp; exports.erc20ApproveOp = erc20ApproveOp; exports.erc20BurnOp = erc20BurnOp; exports.rawCallOp = rawCallOp; exports.buildSwapWithGasDeduction = buildSwapWithGasDeduction;
311
+ //# sourceMappingURL=chunk-CXFUP2YK.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/phitran/Pacific-Finance/pafi-backend/pafi-sdk/packages/core/dist/chunk-CXFUP2YK.cjs","../src/swap/approval.ts","../src/swap/universalRouter.ts","../src/swap/simulate.ts","../src/swap/buildSwapWithGasDeduction.ts","../src/userop/batchExecute.ts","../src/userop/buildUserOperation.ts","../src/userop/operations.ts"],"names":["encodeFunctionData","parseAbi","erc20Abi"],"mappings":"AAAA;AACE;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACTA,4BAAmC;AAKnC,MAAA,SAAsB,cAAA,CACpB,MAAA,EACA,KAAA,EACA,KAAA,EACA,OAAA,EACiB;AACjB,EAAA,OAAO,MAAA,CAAO,YAAA,CAAa;AAAA,IACzB,OAAA,EAAS,KAAA;AAAA,IACT,GAAA,EAAK,0BAAA;AAAA,IACL,YAAA,EAAc,WAAA;AAAA,IACd,IAAA,EAAM,CAAC,KAAA,EAAO,OAAO;AAAA,EACvB,CAAC,CAAA;AACH;AAKO,SAAS,0BAAA,CACd,OAAA,EACA,MAAA,EACK;AACL,EAAA,OAAO,sCAAA;AAAmB,IACxB,GAAA,EAAK,0BAAA;AAAA,IACL,YAAA,EAAc,SAAA;AAAA,IACd,IAAA,EAAM,CAAC,OAAA,EAAS,MAAM;AAAA,EACxB,CAAC,CAAA;AACH;AAKO,SAAS,4BAAA,CACd,KAAA,EACA,OAAA,EACA,MAAA,EACA,UAAA,EACK;AACL,EAAA,OAAO,sCAAA;AAAmB,IACxB,GAAA,EAAK,4BAAA;AAAA,IACL,YAAA,EAAc,SAAA;AAAA,IACd,IAAA,EAAM,CAAC,KAAA,EAAO,OAAA,EAAS,MAAA,EAAQ,UAAU;AAAA,EAC3C,CAAC,CAAA;AACH;ADdA;AACA;AElCA;AAUO,IAAM,QAAA,EAAU,EAAA;AAIhB,IAAM,cAAA,EAAgB,CAAA;AACtB,IAAM,WAAA,EAAa,EAAA;AACnB,IAAM,SAAA,EAAW,EAAA;AAYxB,IAAM,wBAAA,EAA0B;AAAA,EAC9B,EAAE,IAAA,EAAM,sBAAA,EAAwB,IAAA,EAAM,UAAU,CAAA;AAAA,EAChD,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,UAAU,CAAA;AAAA,EAC/B,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,QAAQ,CAAA;AAAA,EACrC,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,UAAU,CAAA;AAAA,EACjC,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,QAAQ;AACpC,CAAA;AAEA,IAAM,uBAAA,EAAyB;AAAA,EAC7B,EAAE,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,UAAU,CAAA;AAAA,EACtC;AAAA,IACE,IAAA,EAAM,MAAA;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,UAAA,EAAY;AAAA,EACd,CAAA;AAAA,EACA,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,UAAU,CAAA;AAAA,EACpC,EAAE,IAAA,EAAM,kBAAA,EAAoB,IAAA,EAAM,UAAU;AAC9C,CAAA;AAWO,SAAS,gBAAA,CACd,UAAA,EACA,IAAA,EACA,QAAA,EACA,YAAA,EACA,cAAA,EACK;AACL,EAAA,MAAM,QAAA,EAAU,gCAAA;AAAA,IACd,CAAC,OAAA,EAAS,OAAA,EAAS,OAAO,CAAA;AAAA,IAC1B,CAAC,aAAA,EAAe,UAAA,EAAY,QAAQ;AAAA,EACtC,CAAA;AAIA,EAAA,MAAM,UAAA,EAAY,uCAAA;AAAA,IAChB,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,UAAA,EAAY,uBAAuB,CAAC,CAAA;AAAA,IACpE;AAAA,MACE;AAAA,QACE,UAAA;AAAA,QACA,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAA,GAAA,CAAO;AAAA,UACrB,oBAAA,EAAsB,CAAA,CAAE,oBAAA;AAAA,UACxB,GAAA,EAAK,MAAA,CAAO,CAAA,CAAE,GAAG,CAAA;AAAA,UACjB,WAAA,EAAa,CAAA,CAAE,WAAA;AAAA,UACf,KAAA,EAAO,CAAA,CAAE,KAAA;AAAA,UACT,QAAA,EAAU,CAAA,CAAE;AAAA,QACd,CAAA,CAAE,CAAA;AAAA,QACF,QAAA;AAAA,QACA,gBAAA,EAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,YAAA,EAAc,uCAAA;AAAA,IAClB;AAAA,MACE,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,UAAU,CAAA;AAAA,MACpC,EAAE,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,UAAU;AAAA,IACvC,CAAA;AAAA,IACA,CAAC,UAAA,EAAY,QAAQ;AAAA,EACvB,CAAA;AAGA,EAAA,MAAM,UAAA,EAAY,uCAAA;AAAA,IAChB;AAAA,MACE,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,UAAU,CAAA;AAAA,MACpC,EAAE,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,UAAU;AAAA,IACvC,CAAA;AAAA,IACA,CAAC,cAAA,EAAgB,YAAY;AAAA,EAC/B,CAAA;AAEA,EAAA,OAAO,uCAAA;AAAA,IACL;AAAA,MACE,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,QAAQ,CAAA;AAAA,MACjC,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,UAAU;AAAA,IACpC,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,CAAC,SAAA,EAAW,WAAA,EAAa,SAAS,CAAC;AAAA,EAC/C,CAAA;AACF;AAKO,SAAS,+BAAA,CACd,UAAA,EACA,IAAA,EACA,QAAA,EACA,YAAA,EACA,cAAA,EACkC;AAClC,EAAA,MAAM,SAAA,EAAW,gCAAA,CAAc,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAClD,EAAA,MAAM,OAAA,EAAgB;AAAA,IACpB,gBAAA,CAAiB,UAAA,EAAY,IAAA,EAAM,QAAA,EAAU,YAAA,EAAc,cAAc;AAAA,EAC3E,CAAA;AACA,EAAA,OAAO,EAAE,QAAA,EAAU,OAAO,CAAA;AAC5B;AAmBO,SAAS,kBAAA,CAAmB,MAAA,EAME;AACnC,EAAA,OAAO,+BAAA;AAAA,IACL,MAAA,CAAO,UAAA;AAAA,IACP,MAAA,CAAO,KAAA,CAAM,IAAA;AAAA,IACb,MAAA,CAAO,QAAA;AAAA,IACP,MAAA,CAAO,YAAA;AAAA,IACP,MAAA,CAAO;AAAA,EACT,CAAA;AACF;AF9CA;AACA;AG/FA,MAAA,SAAsB,YAAA,CACpB,MAAA,EACA,aAAA,EACA,QAAA,EACA,MAAA,EACA,QAAA,EACA,IAAA,EAC+B;AAC/B,EAAA,IAAI;AACF,IAAA,MAAM,YAAA,EAAc,MAAM,MAAA,CAAO,mBAAA,CAAoB;AAAA,MACnD,OAAA,EAAS,aAAA;AAAA,MACT,GAAA,EAAK,oCAAA;AAAA,MACL,YAAA,EAAc,SAAA;AAAA,MACd,IAAA,EAAM,CAAC,QAAA,EAAU,MAAA,EAAQ,QAAQ,CAAA;AAAA,MACjC,OAAA,EAAS;AAAA,IACX,CAAC,CAAA;AAED,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,YAAY,CAAA;AAAA,EACtC,EAAA,MAAA,CAAS,KAAA,EAAgB;AACvB,IAAA,MAAM,QAAA,EACJ,MAAA,WAAiB,MAAA,EAAQ,KAAA,CAAM,QAAA,EAAU,0BAAA;AAC3C,IAAA,MAAM,IAAI,sCAAA,CAAgB,MAAA,EAAQ,OAAO,CAAA;AAAA,EAC3C;AACF;AHwFA;AACA;AIvIA;AJyIA;AACA;AK1IA;AAaO,IAAM,mBAAA,EAAqB,4BAAA;AAAS,EACzC;AACF,CAAC,CAAA;AAaM,SAAS,kBAAA,CAAmB,UAAA,EAA8B;AAC/D,EAAA,GAAA,CAAI,UAAA,CAAW,OAAA,IAAW,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,KAAA,CAAM,wDAAwD,CAAA;AAAA,EAC1E;AACA,EAAA,OAAOA,sCAAAA;AAAmB,IACxB,GAAA,EAAK,kBAAA;AAAA,IACL,YAAA,EAAc,SAAA;AAAA,IACd,IAAA,EAAM;AAAA,MACJ,UAAA,CAAW,GAAA,CAAI,CAAC,EAAA,EAAA,GAAA,CAAQ;AAAA,QACtB,MAAA,EAAQ,EAAA,CAAG,MAAA;AAAA,QACX,KAAA,EAAO,EAAA,CAAG,KAAA;AAAA,QACV,IAAA,EAAM,EAAA,CAAG;AAAA,MACX,CAAA,CAAE;AAAA,IACJ;AAAA,EACF,CAAC,CAAA;AACH;ALoHA;AACA;AMvJA,IAAM,uBAAA,EAAyB,OAAA;AAC/B,IAAM,+BAAA,EAAiC,OAAA;AACvC,IAAM,6BAAA,EAA+B,MAAA;AA+B9B,SAAS,yBAAA,CACd,MAAA,EACsB;AACtB,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,MAAA,CAAO,MAAA;AAAA,IACf,KAAA,EAAO,MAAA,CAAO,KAAA;AAAA,IACd,QAAA,EAAU,kBAAA,CAAmB,MAAA,CAAO,UAAU,CAAA;AAAA,IAC9C,YAAA,mCAAc,MAAA,mBAAO,SAAA,6BAAW,cAAA,UAAgB,wBAAA;AAAA,IAChD,oBAAA,mCACE,MAAA,qBAAO,SAAA,6BAAW,sBAAA,UAClB,gCAAA;AAAA,IACF,kBAAA,mCACE,MAAA,qBAAO,SAAA,6BAAW,oBAAA,UAAsB,8BAAA;AAAA,IAC1C,YAAA,mCAAc,MAAA,qBAAO,YAAA,6BAAc,cAAA,UAAgB,IAAA;AAAA,IACnD,oBAAA,mCAAsB,MAAA,qBAAO,YAAA,+BAAc,sBAAA,UAAwB;AAAA,EACrE,CAAA;AACF;AAOO,SAAS,qBAAA,CACd,OAAA,EACA,SAAA,EAMA,SAAA,EACe;AACf,EAAA,OAAO;AAAA,IACL,GAAG,OAAA;AAAA,IACH,SAAA,EAAW,SAAA,CAAU,SAAA;AAAA,IACrB,aAAA,EAAe,SAAA,CAAU,aAAA;AAAA,IACzB,6BAAA,EAA+B,SAAA,CAAU,6BAAA;AAAA,IACzC,uBAAA,EAAyB,SAAA,CAAU,uBAAA;AAAA,IACnC;AAAA,EACF,CAAA;AACF;ANuGA;AACA;AO3LA;AASA,IAAM,mBAAA,EAAqBC,4BAAAA,CAAU,+BAA+B,CAAC,CAAA;AAO9D,SAAS,eAAA,CACd,KAAA,EACA,EAAA,EACA,MAAA,EACW;AACX,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,KAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,IAAA,EAAMD,sCAAAA;AAAmB,MACvB,GAAA,EAAKE,cAAAA;AAAA,MACL,YAAA,EAAc,UAAA;AAAA,MACd,IAAA,EAAM,CAAC,EAAA,EAAI,MAAM;AAAA,IACnB,CAAC;AAAA,EACH,CAAA;AACF;AAOO,SAAS,cAAA,CACd,KAAA,EACA,OAAA,EACA,MAAA,EACW;AACX,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,KAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,IAAA,EAAMF,sCAAAA;AAAmB,MACvB,GAAA,EAAKE,cAAAA;AAAA,MACL,YAAA,EAAc,SAAA;AAAA,MACd,IAAA,EAAM,CAAC,OAAA,EAAS,MAAM;AAAA,IACxB,CAAC;AAAA,EACH,CAAA;AACF;AAWO,SAAS,WAAA,CAAY,KAAA,EAAgB,MAAA,EAA2B;AACrE,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,KAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,IAAA,EAAMF,sCAAAA;AAAmB,MACvB,GAAA,EAAK,kBAAA;AAAA,MACL,YAAA,EAAc,MAAA;AAAA,MACd,IAAA,EAAM,CAAC,MAAM;AAAA,IACf,CAAC;AAAA,EACH,CAAA;AACF;AAOO,SAAS,SAAA,CACd,MAAA,EACA,IAAA,EACA,MAAA,EAAgB,EAAA,EACL;AACX,EAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAK,CAAA;AAC/B;AP6IA;AACA;AIrHO,SAAS,yBAAA,CACd,MAAA,EACsB;AACtB,EAAA,GAAA,CAAI,MAAA,CAAO,SAAA,GAAY,EAAA,EAAI;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,sDAAsD,CAAA;AAAA,EACxE;AACA,EAAA,GAAA,CAAI,MAAA,CAAO,aAAA,EAAe,EAAA,EAAI;AAC5B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,IACF,CAAA;AAAA,EACF;AACA,EAAA,GAAA,CAAI,MAAA,CAAO,SAAA,EAAW,EAAA,EAAI;AACxB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,IACF,CAAA;AAAA,EACF;AACA,EAAA,GAAA,CAAI,MAAA,CAAO,QAAA,CAAS,OAAA,IAAW,CAAA,EAAG;AAChC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,IACF,CAAA;AAAA,EACF;AAKA,EAAA,MAAM,EAAE,QAAA,EAAU,OAAO,EAAA,EAAI,+BAAA;AAAA,IAC3B,MAAA,CAAO,iBAAA;AAAA,IACP,MAAA,CAAO,QAAA;AAAA,IACP,MAAA,CAAO,QAAA;AAAA,IACP,MAAA,CAAO,YAAA;AAAA,IACP,MAAA,CAAO;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,aAAA,EAAoBA,sCAAAA;AAAmB,IAC3C,GAAA,EAAK,oCAAA;AAAA,IACL,YAAA,EAAc,SAAA;AAAA,IACd,IAAA,EAAM,CAAC,QAAA,EAAU,MAAA,EAAQ,MAAA,CAAO,QAAQ;AAAA,EAC1C,CAAC,CAAA;AAGD,EAAA,MAAM,WAAA,EAA0B;AAAA,IAC9B,cAAA;AAAA,MACE,MAAA,CAAO,iBAAA;AAAA,MACP,MAAA,CAAO,sBAAA;AAAA,MACP,MAAA,CAAO;AAAA,IACT,CAAA;AAAA,IACA,SAAA,CAAU,MAAA,CAAO,sBAAA,EAAwB,YAAY;AAAA,EACvD,CAAA;AAIA,EAAA,GAAA,CAAI,MAAA,CAAO,SAAA,EAAW,EAAA,EAAI;AACxB,IAAA,UAAA,CAAW,IAAA;AAAA,MACT,eAAA;AAAA,QACE,MAAA,CAAO,iBAAA;AAAA,QACP,MAAA,CAAO,YAAA;AAAA,QACP,MAAA,CAAO;AAAA,MACT;AAAA,IACF,CAAA;AAAA,EACF;AAEA,EAAA,OAAO,yBAAA,CAA0B;AAAA,IAC/B,MAAA,EAAQ,MAAA,CAAO,WAAA;AAAA,IACf,KAAA,EAAO,MAAA,CAAO,OAAA;AAAA,IACd,UAAA;AAAA,IACA,SAAA,EAAW;AAAA,MACT,YAAA,mCAAc,MAAA,uBAAO,SAAA,+BAAW,cAAA,UAAgB,SAAA;AAAA,MAChD,oBAAA,mCACE,MAAA,uBAAO,SAAA,+BAAW,sBAAA,UAAwB,SAAA;AAAA,MAC5C,kBAAA,mCAAoB,MAAA,uBAAO,SAAA,+BAAW,oBAAA,UAAsB;AAAA,IAC9D;AAAA,EACF,CAAC,CAAA;AACH;AJyGA;AACA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,y6BAAC","file":"/Users/phitran/Pacific-Finance/pafi-backend/pafi-sdk/packages/core/dist/chunk-CXFUP2YK.cjs","sourcesContent":[null,"import { encodeFunctionData } from \"viem\";\nimport type { Address, Hex, PublicClient } from \"viem\";\nimport { erc20Abi } from \"../abi/erc20\";\nimport { permit2Abi } from \"../abi/permit2\";\n\nexport async function checkAllowance(\n client: PublicClient,\n token: Address,\n owner: Address,\n spender: Address,\n): Promise<bigint> {\n return client.readContract({\n address: token,\n abi: erc20Abi,\n functionName: \"allowance\",\n args: [owner, spender],\n });\n}\n\n/**\n * Encode an ERC-20 approve(spender, amount) call.\n */\nexport function buildErc20ApprovalCalldata(\n spender: Address,\n amount: bigint,\n): Hex {\n return encodeFunctionData({\n abi: erc20Abi,\n functionName: \"approve\",\n args: [spender, amount],\n });\n}\n\n/**\n * Encode a Permit2 approve(token, spender, amount, expiration) call.\n */\nexport function buildPermit2ApprovalCalldata(\n token: Address,\n spender: Address,\n amount: bigint,\n expiration: number,\n): Hex {\n return encodeFunctionData({\n abi: permit2Abi,\n functionName: \"approve\",\n args: [token, spender, amount, expiration],\n });\n}\n","import { encodeAbiParameters, encodePacked } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport type { PathKey, QuoteResult } from \"../types\";\n\n// -------------------------------------------------------------------------\n// V4 UniversalRouter command / action constants\n// Reference: https://github.com/Uniswap/v4-periphery/blob/main/src/libraries/Actions.sol\n// -------------------------------------------------------------------------\n\n/** UniversalRouter command byte for V4 swap */\nexport const V4_SWAP = 0x10 as const;\n\n/** V4 actions */\nexport const SWAP_EXACT_IN_SINGLE = 0x06 as const;\nexport const SWAP_EXACT_IN = 0x07 as const;\nexport const SETTLE_ALL = 0x0c as const;\nexport const TAKE_ALL = 0x0f as const;\n\n// -------------------------------------------------------------------------\n// ABI type strings matching Uniswap's V4Planner encoding\n// Reference: https://github.com/Uniswap/sdks/blob/main/sdks/v4-sdk/src/utils/v4Planner.ts\n//\n// IMPORTANT: PathKey.fee is uint256 in the V4 Router ABI (not uint24).\n// -------------------------------------------------------------------------\n\n// PathKey components for V4 Router ABI encoding.\n// IMPORTANT: fee is uint256 in the V4 Router (not uint24 as in PoolKey).\n// Reference: https://github.com/Uniswap/sdks/blob/main/sdks/v4-sdk/src/utils/v4Planner.ts\nconst PATH_KEY_ABI_COMPONENTS = [\n { name: \"intermediateCurrency\", type: \"address\" },\n { name: \"fee\", type: \"uint256\" },\n { name: \"tickSpacing\", type: \"int24\" },\n { name: \"hooks\", type: \"address\" },\n { name: \"hookData\", type: \"bytes\" },\n] as const;\n\nconst EXACT_INPUT_PARAMS_ABI = [\n { name: \"currencyIn\", type: \"address\" },\n {\n name: \"path\",\n type: \"tuple[]\",\n components: PATH_KEY_ABI_COMPONENTS,\n },\n { name: \"amountIn\", type: \"uint128\" },\n { name: \"amountOutMinimum\", type: \"uint128\" },\n] as const;\n\n/**\n * Build the calldata inputs[0] (the V4_SWAP command payload) for\n * UniversalRouter.execute.\n *\n * Actions encoded: SWAP_EXACT_IN → SETTLE_ALL → TAKE_ALL\n *\n * Encoding matches the Uniswap V4 SDK's V4Planner — each action's params\n * are individually ABI-encoded, then wrapped together with the action bytes.\n */\nexport function buildV4SwapInput(\n currencyIn: Address,\n path: PathKey[],\n amountIn: bigint,\n minAmountOut: bigint,\n outputCurrency: Address,\n): Hex {\n const actions = encodePacked(\n [\"uint8\", \"uint8\", \"uint8\"],\n [SWAP_EXACT_IN, SETTLE_ALL, TAKE_ALL],\n );\n\n // Param 0: ExactInputParams — encoded as a single tuple so the CalldataDecoder\n // can locate it via a single offset pointer. fee is uint256 per V4 Router spec.\n const swapParam = encodeAbiParameters(\n [{ name: \"swap\", type: \"tuple\", components: EXACT_INPUT_PARAMS_ABI }],\n [\n {\n currencyIn,\n path: path.map((p) => ({\n intermediateCurrency: p.intermediateCurrency,\n fee: BigInt(p.fee),\n tickSpacing: p.tickSpacing,\n hooks: p.hooks,\n hookData: p.hookData,\n })),\n amountIn,\n amountOutMinimum: minAmountOut,\n },\n ],\n );\n\n // Param 1: SETTLE_ALL { currency, maxAmount }\n const settleParam = encodeAbiParameters(\n [\n { name: \"currency\", type: \"address\" },\n { name: \"maxAmount\", type: \"uint256\" },\n ],\n [currencyIn, amountIn],\n );\n\n // Param 2: TAKE_ALL { currency, minAmount }\n const takeParam = encodeAbiParameters(\n [\n { name: \"currency\", type: \"address\" },\n { name: \"minAmount\", type: \"uint256\" },\n ],\n [outputCurrency, minAmountOut],\n );\n\n return encodeAbiParameters(\n [\n { name: \"actions\", type: \"bytes\" },\n { name: \"params\", type: \"bytes[]\" },\n ],\n [actions, [swapParam, settleParam, takeParam]],\n );\n}\n\n/**\n * Build the full commands + inputs args for UniversalRouter.execute.\n */\nexport function buildUniversalRouterExecuteArgs(\n currencyIn: Address,\n path: PathKey[],\n amountIn: bigint,\n minAmountOut: bigint,\n outputCurrency: Address,\n): { commands: Hex; inputs: Hex[] } {\n const commands = encodePacked([\"uint8\"], [V4_SWAP]);\n const inputs: Hex[] = [\n buildV4SwapInput(currencyIn, path, amountIn, minAmountOut, outputCurrency),\n ];\n return { commands, inputs };\n}\n\n/**\n * Build UniversalRouter execute args from a quote result.\n *\n * Takes the output of `findBestQuote` / `quoteBestRoute` and produces\n * ready-to-use `{ commands, inputs }` for `UniversalRouter.execute`.\n *\n * @param quote - Quote result containing the path\n * @param currencyIn - Input token address\n * @param currencyOut - Output token address\n * @param amountIn - Exact input amount (same value passed to the quoter)\n * @param minAmountOut - Minimum acceptable output (caller applies slippage)\n *\n * @deprecated Since v1.4 — the Issuer App no longer handles swaps.\n * For the new PT→USDT batch call on PAFI Web (Scenario 4 with\n * EIP-7702 gas deduction), use `buildSwapWithGasDeduction()` (v1.5).\n * This helper is kept for legacy v0.2.x consumers; will be removed in v2.0.\n */\nexport function buildSwapFromQuote(params: {\n quote: QuoteResult;\n currencyIn: Address;\n currencyOut: Address;\n amountIn: bigint;\n minAmountOut: bigint;\n}): { commands: Hex; inputs: Hex[] } {\n return buildUniversalRouterExecuteArgs(\n params.currencyIn,\n params.quote.path,\n params.amountIn,\n params.minAmountOut,\n params.currencyOut,\n );\n}\n","import type { Address, Hex, PublicClient } from \"viem\";\nimport { universalRouterAbi } from \"../abi/universalRouter\";\nimport { SimulationError } from \"../errors\";\n\nexport interface SwapSimulationResult {\n success: boolean;\n gasEstimate: bigint;\n}\n\n/**\n * Simulate a UniversalRouter.execute swap call via eth_call (no gas spent).\n *\n * Runs the full V4 swap flow — token transfer via Permit2, swap via\n * PoolManager, output settlement — without submitting a transaction.\n * If the simulation reverts, throws a `SimulationError` with the reason.\n *\n * @param client - viem PublicClient\n * @param routerAddress - UniversalRouter contract address\n * @param commands - Packed command bytes (from buildSwapFromQuote)\n * @param inputs - Encoded inputs per command (from buildSwapFromQuote)\n * @param deadline - Unix timestamp after which the tx expires\n * @param from - Address that will execute the swap\n */\nexport async function simulateSwap(\n client: PublicClient,\n routerAddress: Address,\n commands: Hex,\n inputs: Hex[],\n deadline: bigint,\n from: Address,\n): Promise<SwapSimulationResult> {\n try {\n const gasEstimate = await client.estimateContractGas({\n address: routerAddress,\n abi: universalRouterAbi,\n functionName: \"execute\",\n args: [commands, inputs, deadline],\n account: from,\n });\n\n return { success: true, gasEstimate };\n } catch (error: unknown) {\n const message =\n error instanceof Error ? error.message : \"Unknown simulation error\";\n throw new SimulationError(\"swap\", message);\n }\n}\n","import { encodeFunctionData } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport { universalRouterAbi } from \"../abi/universalRouter\";\nimport type { PathKey } from \"../types\";\nimport { buildPartialUserOperation } from \"../userop/buildUserOperation\";\nimport type { PartialUserOperation } from \"../userop/types\";\nimport {\n erc20ApproveOp,\n erc20TransferOp,\n rawCallOp,\n} from \"../userop/operations\";\nimport type { Operation } from \"../userop/types\";\nimport { buildUniversalRouterExecuteArgs } from \"./universalRouter\";\n\n/**\n * v1.5 — Scenario 4: Swap PT → USDT on PAFI Web with **gas fee\n * deducted in PT** from the user's balance.\n *\n * Builds an unsigned `PartialUserOperation` that packages three inner\n * calls into a single `BatchExecutor.execute(calls[])`:\n *\n * 1. `PT.approve(UniversalRouter, amountIn)` — let the router pull\n * `amountIn` PT for the swap\n * 2. `UniversalRouter.execute(commands, inputs, deadline)` — V4 swap\n * PT → USDT, user receives `minAmountOut` USDT\n * 3. `PT.transfer(feeRecipient, gasFeePt)` — pay the operator back\n * for sponsoring the gas, in PT (application-level recovery —\n * no custom paymaster contract needed)\n *\n * The user's wallet must hold `amountIn + gasFeePt` PT **before** the\n * UserOp runs. The three inner calls execute atomically via\n * EIP-7702 delegation (`msg.sender = user`), so a reverting swap\n * unwinds the approve + fee transfer too.\n *\n * ## Fee model\n *\n * Exact-out on the **USDT side** is not attempted here. The user\n * specifies `amountIn` PT for the swap; the minimum USDT out comes\n * from a separate quote (not this function). The gas fee is a\n * separate `transfer` call — it does NOT come out of the swap's USDT\n * output, because that output goes straight to the user's wallet with\n * no intermediate hook to skim from.\n *\n * If the FE wants \"user receives exactly X USDT after gas\", it should:\n * 1. Quote PT→USDT for candidate `amountIn` values\n * 2. Pick an `amountIn` where `minAmountOut ≈ X`\n * 3. Separately compute `gasFeePt` from the operator's rate\n * 4. Ensure user's PT balance ≥ `amountIn + gasFeePt`\n *\n * ## Order of operations\n *\n * Approve → swap → fee transfer. The fee transfer comes **last** so\n * if the swap reverts, the user is also refunded the fee (atomic\n * batch revert). Doing fee transfer first would still unwind on\n * revert, but ordering it last matches the intuitive \"only charge\n * gas on success\" semantics.\n */\nexport interface BuildSwapWithGasDeductionParams {\n /** User's EOA (with EIP-7702 delegation to BatchExecutor). */\n userAddress: Address;\n /** ERC-4337 account nonce — fetched from EntryPoint by the caller. */\n aaNonce: bigint;\n\n /** PT token address being swapped. */\n pointTokenAddress: Address;\n /** Destination currency (typically USDT). */\n outputTokenAddress: Address;\n /** UniversalRouter contract address (chain-specific). */\n universalRouterAddress: Address;\n\n /** PT units to swap. User's balance must be ≥ `amountIn + gasFeePt`. */\n amountIn: bigint;\n /**\n * Minimum USDT to accept out of the swap. Caller applies slippage\n * (typically ~0.5-1%) against a fresh quote. Sub-minimum swap reverts.\n */\n minAmountOut: bigint;\n\n /** V4 pool path for the swap. Single-hop = 1 PathKey. */\n swapPath: PathKey[];\n /** Unix seconds. After this, the router rejects the swap. */\n deadline: bigint;\n\n /** PT amount transferred to `feeRecipient` as gas fee recovery. */\n gasFeePt: bigint;\n /** Where the gas fee lands — typically the operator or fee collector. */\n feeRecipient: Address;\n\n /**\n * Optional — pre-signed Permit2 / EIP-2612 approval. If omitted, a\n * standard `approve()` call is appended as the first batch op.\n * Future work: support Permit2 so the approve is part of the swap\n * input rather than a separate call.\n */\n gasLimits?: {\n callGasLimit?: bigint;\n verificationGasLimit?: bigint;\n preVerificationGas?: bigint;\n };\n}\n\n/**\n * Build an unsigned UserOp for Scenario 4. Returns a\n * `PartialUserOperation` — caller attaches paymaster sponsorship (via\n * `POST /api/paymaster/sponsor`), adds the user's UserOp-hash\n * signature, and submits to the Bundler.\n *\n * @throws when `amountIn` or `gasFeePt` is not positive, or when\n * `swapPath` is empty (at least one PathKey required).\n */\nexport function buildSwapWithGasDeduction(\n params: BuildSwapWithGasDeductionParams,\n): PartialUserOperation {\n if (params.amountIn <= 0n) {\n throw new Error(\"buildSwapWithGasDeduction: amountIn must be positive\");\n }\n if (params.minAmountOut < 0n) {\n throw new Error(\n \"buildSwapWithGasDeduction: minAmountOut must be non-negative\",\n );\n }\n if (params.gasFeePt < 0n) {\n throw new Error(\n \"buildSwapWithGasDeduction: gasFeePt must be non-negative\",\n );\n }\n if (params.swapPath.length === 0) {\n throw new Error(\n \"buildSwapWithGasDeduction: swapPath must contain at least one PathKey\",\n );\n }\n\n // Step 1 — build the V4 swap calldata. `buildUniversalRouterExecuteArgs`\n // returns `{ commands, inputs }` — we wrap it into a full\n // `execute(commands, inputs, deadline)` call below.\n const { commands, inputs } = buildUniversalRouterExecuteArgs(\n params.pointTokenAddress,\n params.swapPath,\n params.amountIn,\n params.minAmountOut,\n params.outputTokenAddress,\n );\n\n const swapCallData: Hex = encodeFunctionData({\n abi: universalRouterAbi,\n functionName: \"execute\",\n args: [commands, inputs, params.deadline],\n });\n\n // Step 2 — assemble the three batch ops in execution order.\n const operations: Operation[] = [\n erc20ApproveOp(\n params.pointTokenAddress,\n params.universalRouterAddress,\n params.amountIn,\n ),\n rawCallOp(params.universalRouterAddress, swapCallData),\n ];\n\n // Optional fee transfer — skip when gasFeePt is 0 so a\n // zero-fee swap (promo, etc) doesn't carry a pointless batch entry.\n if (params.gasFeePt > 0n) {\n operations.push(\n erc20TransferOp(\n params.pointTokenAddress,\n params.feeRecipient,\n params.gasFeePt,\n ),\n );\n }\n\n return buildPartialUserOperation({\n sender: params.userAddress,\n nonce: params.aaNonce,\n operations,\n gasLimits: {\n callGasLimit: params.gasLimits?.callGasLimit ?? 700_000n,\n verificationGasLimit:\n params.gasLimits?.verificationGasLimit ?? 150_000n,\n preVerificationGas: params.gasLimits?.preVerificationGas ?? 50_000n,\n },\n });\n}\n","import { encodeFunctionData, parseAbi } from \"viem\";\nimport type { Hex } from \"viem\";\nimport type { Operation } from \"./types\";\n\n/**\n * Standard BatchExecutor ABI — a contract that takes an array of calls\n * and invokes each one in sequence, reverting all if any fail.\n *\n * Compatible with OpenZeppelin `Account.execute(Call[])`, Biconomy\n * `executeBatch`, Safe `MultiSend`, and most EIP-7702 delegation\n * targets. The exact deployed address is supplied by the infra team\n * (see [V1.4_V1.5_READINESS.md B2]).\n */\nexport const BATCH_EXECUTOR_ABI = parseAbi([\n \"function execute((address target, uint256 value, bytes data)[] calls)\",\n]);\n\n/**\n * Encode a batch of operations into calldata for `BatchExecutor.execute()`.\n * The resulting calldata goes into `UserOperation.callData`.\n *\n * When the EOA has an EIP-7702 delegation to a BatchExecutor, calling\n * this calldata against the EOA runs all operations with\n * `msg.sender = EOA` for each inner call.\n *\n * @param operations batch of calls, in execution order\n * @returns calldata bytes for `execute((address,uint256,bytes)[])`\n */\nexport function encodeBatchExecute(operations: Operation[]): Hex {\n if (operations.length === 0) {\n throw new Error(\"encodeBatchExecute: operations array must not be empty\");\n }\n return encodeFunctionData({\n abi: BATCH_EXECUTOR_ABI,\n functionName: \"execute\",\n args: [\n operations.map((op) => ({\n target: op.target,\n value: op.value,\n data: op.data,\n })),\n ],\n });\n}\n","import type { Address } from \"viem\";\nimport type { Operation, PartialUserOperation, UserOperation } from \"./types\";\nimport { encodeBatchExecute } from \"./batchExecute\";\n\n/**\n * Default gas limits — rough upper bounds for a 2-op batch on Base.\n * Bundler re-estimates before submission, so these are only used when\n * the caller doesn't supply their own.\n */\nconst DEFAULT_CALL_GAS_LIMIT = 500_000n;\nconst DEFAULT_VERIFICATION_GAS_LIMIT = 150_000n;\nconst DEFAULT_PRE_VERIFICATION_GAS = 50_000n;\n\nexport interface BuildPartialUserOpParams {\n /** User's EOA (with EIP-7702 delegation). */\n sender: Address;\n /** Batch of operations — encoded into callData via `encodeBatchExecute`. */\n operations: Operation[];\n /** EntryPoint nonce for this sender. Caller fetches from the EntryPoint contract. */\n nonce: bigint;\n /** Optional gas overrides; bundler re-estimates before submission. */\n gasLimits?: {\n callGasLimit?: bigint;\n verificationGasLimit?: bigint;\n preVerificationGas?: bigint;\n };\n /** Optional fee overrides; bundler usually fills these. */\n feeOverrides?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\n/**\n * Build a partial ERC-4337 UserOperation from a batch of operations.\n * Paymaster fields and signature are populated later:\n * 1. Call `PafiBackendClient.requestSponsorship()` → get paymaster fields\n * 2. Compute userOpHash and have the user sign it (via Privy)\n * 3. Attach `signature` → submit to bundler\n *\n * This function is a pure struct builder — no network calls.\n */\nexport function buildPartialUserOperation(\n params: BuildPartialUserOpParams,\n): PartialUserOperation {\n return {\n sender: params.sender,\n nonce: params.nonce,\n callData: encodeBatchExecute(params.operations),\n callGasLimit: params.gasLimits?.callGasLimit ?? DEFAULT_CALL_GAS_LIMIT,\n verificationGasLimit:\n params.gasLimits?.verificationGasLimit ??\n DEFAULT_VERIFICATION_GAS_LIMIT,\n preVerificationGas:\n params.gasLimits?.preVerificationGas ?? DEFAULT_PRE_VERIFICATION_GAS,\n maxFeePerGas: params.feeOverrides?.maxFeePerGas ?? 0n,\n maxPriorityFeePerGas: params.feeOverrides?.maxPriorityFeePerGas ?? 0n,\n };\n}\n\n/**\n * Assemble a full UserOperation once paymaster fields + signature are\n * known. Used after `PafiBackendClient.requestSponsorship()` and user\n * signing complete.\n */\nexport function assembleUserOperation(\n partial: PartialUserOperation,\n paymaster: {\n paymaster: Address;\n paymasterData: `0x${string}`;\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n },\n signature: `0x${string}`,\n): UserOperation {\n return {\n ...partial,\n paymaster: paymaster.paymaster,\n paymasterData: paymaster.paymasterData,\n paymasterVerificationGasLimit: paymaster.paymasterVerificationGasLimit,\n paymasterPostOpGasLimit: paymaster.paymasterPostOpGasLimit,\n signature,\n };\n}\n","import { encodeFunctionData, erc20Abi, parseAbi } from \"viem\";\nimport type { Address } from \"viem\";\nimport type { Operation } from \"./types\";\n\n/**\n * ERC20Burnable extension — `burn(uint256 amount)` burns from msg.sender.\n * The EOA (via EIP-7702 delegation) is the `msg.sender` when a batch\n * runs — so this burns the user's balance without any role check.\n */\nconst ERC20_BURNABLE_ABI = parseAbi([\"function burn(uint256 amount)\"]);\n\n/**\n * Build an ERC-20 `transfer(to, amount)` operation. Used inside a batch\n * to move fee tokens from the user to the fee recipient atomically with\n * the main action.\n */\nexport function erc20TransferOp(\n token: Address,\n to: Address,\n amount: bigint,\n): Operation {\n return {\n target: token,\n value: 0n,\n data: encodeFunctionData({\n abi: erc20Abi,\n functionName: \"transfer\",\n args: [to, amount],\n }),\n };\n}\n\n/**\n * Build an ERC-20 `approve(spender, amount)` operation. Used inside a\n * batch before a swap / deposit call so the AMM / protocol can pull\n * tokens from the user.\n */\nexport function erc20ApproveOp(\n token: Address,\n spender: Address,\n amount: bigint,\n): Operation {\n return {\n target: token,\n value: 0n,\n data: encodeFunctionData({\n abi: erc20Abi,\n functionName: \"approve\",\n args: [spender, amount],\n }),\n };\n}\n\n/**\n * Build an ERC-20 `burn(amount)` operation (OpenZeppelin ERC20Burnable\n * extension). Burns from `msg.sender`, which — via EIP-7702 — is the\n * user's EOA.\n *\n * Requires the PointToken contract to expose a public `burn(uint256)`\n * without a role check. See\n * [SDK_V1.4_TASKS.md §11 — PointToken.burn callable via batch].\n */\nexport function erc20BurnOp(token: Address, amount: bigint): Operation {\n return {\n target: token,\n value: 0n,\n data: encodeFunctionData({\n abi: ERC20_BURNABLE_ABI,\n functionName: \"burn\",\n args: [amount],\n }),\n };\n}\n\n/**\n * Build a raw call operation with caller-supplied calldata. Useful for\n * non-ERC-20 contracts (PoolManager.swap, PerpDEX.deposit, Relayer.mint)\n * where the encoding is specific to that protocol.\n */\nexport function rawCallOp(\n target: Address,\n data: `0x${string}`,\n value: bigint = 0n,\n): Operation {\n return { target, value, data };\n}\n"]}
@@ -0,0 +1,311 @@
1
+ import {
2
+ erc20Abi,
3
+ permit2Abi,
4
+ universalRouterAbi
5
+ } from "./chunk-2PIXFXA2.js";
6
+ import {
7
+ SimulationError
8
+ } from "./chunk-P56TUGTS.js";
9
+
10
+ // src/swap/approval.ts
11
+ import { encodeFunctionData } from "viem";
12
+ async function checkAllowance(client, token, owner, spender) {
13
+ return client.readContract({
14
+ address: token,
15
+ abi: erc20Abi,
16
+ functionName: "allowance",
17
+ args: [owner, spender]
18
+ });
19
+ }
20
+ function buildErc20ApprovalCalldata(spender, amount) {
21
+ return encodeFunctionData({
22
+ abi: erc20Abi,
23
+ functionName: "approve",
24
+ args: [spender, amount]
25
+ });
26
+ }
27
+ function buildPermit2ApprovalCalldata(token, spender, amount, expiration) {
28
+ return encodeFunctionData({
29
+ abi: permit2Abi,
30
+ functionName: "approve",
31
+ args: [token, spender, amount, expiration]
32
+ });
33
+ }
34
+
35
+ // src/swap/universalRouter.ts
36
+ import { encodeAbiParameters, encodePacked } from "viem";
37
+ var V4_SWAP = 16;
38
+ var SWAP_EXACT_IN = 7;
39
+ var SETTLE_ALL = 12;
40
+ var TAKE_ALL = 15;
41
+ var PATH_KEY_ABI_COMPONENTS = [
42
+ { name: "intermediateCurrency", type: "address" },
43
+ { name: "fee", type: "uint256" },
44
+ { name: "tickSpacing", type: "int24" },
45
+ { name: "hooks", type: "address" },
46
+ { name: "hookData", type: "bytes" }
47
+ ];
48
+ var EXACT_INPUT_PARAMS_ABI = [
49
+ { name: "currencyIn", type: "address" },
50
+ {
51
+ name: "path",
52
+ type: "tuple[]",
53
+ components: PATH_KEY_ABI_COMPONENTS
54
+ },
55
+ { name: "amountIn", type: "uint128" },
56
+ { name: "amountOutMinimum", type: "uint128" }
57
+ ];
58
+ function buildV4SwapInput(currencyIn, path, amountIn, minAmountOut, outputCurrency) {
59
+ const actions = encodePacked(
60
+ ["uint8", "uint8", "uint8"],
61
+ [SWAP_EXACT_IN, SETTLE_ALL, TAKE_ALL]
62
+ );
63
+ const swapParam = encodeAbiParameters(
64
+ [{ name: "swap", type: "tuple", components: EXACT_INPUT_PARAMS_ABI }],
65
+ [
66
+ {
67
+ currencyIn,
68
+ path: path.map((p) => ({
69
+ intermediateCurrency: p.intermediateCurrency,
70
+ fee: BigInt(p.fee),
71
+ tickSpacing: p.tickSpacing,
72
+ hooks: p.hooks,
73
+ hookData: p.hookData
74
+ })),
75
+ amountIn,
76
+ amountOutMinimum: minAmountOut
77
+ }
78
+ ]
79
+ );
80
+ const settleParam = encodeAbiParameters(
81
+ [
82
+ { name: "currency", type: "address" },
83
+ { name: "maxAmount", type: "uint256" }
84
+ ],
85
+ [currencyIn, amountIn]
86
+ );
87
+ const takeParam = encodeAbiParameters(
88
+ [
89
+ { name: "currency", type: "address" },
90
+ { name: "minAmount", type: "uint256" }
91
+ ],
92
+ [outputCurrency, minAmountOut]
93
+ );
94
+ return encodeAbiParameters(
95
+ [
96
+ { name: "actions", type: "bytes" },
97
+ { name: "params", type: "bytes[]" }
98
+ ],
99
+ [actions, [swapParam, settleParam, takeParam]]
100
+ );
101
+ }
102
+ function buildUniversalRouterExecuteArgs(currencyIn, path, amountIn, minAmountOut, outputCurrency) {
103
+ const commands = encodePacked(["uint8"], [V4_SWAP]);
104
+ const inputs = [
105
+ buildV4SwapInput(currencyIn, path, amountIn, minAmountOut, outputCurrency)
106
+ ];
107
+ return { commands, inputs };
108
+ }
109
+ function buildSwapFromQuote(params) {
110
+ return buildUniversalRouterExecuteArgs(
111
+ params.currencyIn,
112
+ params.quote.path,
113
+ params.amountIn,
114
+ params.minAmountOut,
115
+ params.currencyOut
116
+ );
117
+ }
118
+
119
+ // src/swap/simulate.ts
120
+ async function simulateSwap(client, routerAddress, commands, inputs, deadline, from) {
121
+ try {
122
+ const gasEstimate = await client.estimateContractGas({
123
+ address: routerAddress,
124
+ abi: universalRouterAbi,
125
+ functionName: "execute",
126
+ args: [commands, inputs, deadline],
127
+ account: from
128
+ });
129
+ return { success: true, gasEstimate };
130
+ } catch (error) {
131
+ const message = error instanceof Error ? error.message : "Unknown simulation error";
132
+ throw new SimulationError("swap", message);
133
+ }
134
+ }
135
+
136
+ // src/swap/buildSwapWithGasDeduction.ts
137
+ import { encodeFunctionData as encodeFunctionData4 } from "viem";
138
+
139
+ // src/userop/batchExecute.ts
140
+ import { encodeFunctionData as encodeFunctionData2, parseAbi } from "viem";
141
+ var BATCH_EXECUTOR_ABI = parseAbi([
142
+ "function execute((address target, uint256 value, bytes data)[] calls)"
143
+ ]);
144
+ function encodeBatchExecute(operations) {
145
+ if (operations.length === 0) {
146
+ throw new Error("encodeBatchExecute: operations array must not be empty");
147
+ }
148
+ return encodeFunctionData2({
149
+ abi: BATCH_EXECUTOR_ABI,
150
+ functionName: "execute",
151
+ args: [
152
+ operations.map((op) => ({
153
+ target: op.target,
154
+ value: op.value,
155
+ data: op.data
156
+ }))
157
+ ]
158
+ });
159
+ }
160
+
161
+ // src/userop/buildUserOperation.ts
162
+ var DEFAULT_CALL_GAS_LIMIT = 500000n;
163
+ var DEFAULT_VERIFICATION_GAS_LIMIT = 150000n;
164
+ var DEFAULT_PRE_VERIFICATION_GAS = 50000n;
165
+ function buildPartialUserOperation(params) {
166
+ return {
167
+ sender: params.sender,
168
+ nonce: params.nonce,
169
+ callData: encodeBatchExecute(params.operations),
170
+ callGasLimit: params.gasLimits?.callGasLimit ?? DEFAULT_CALL_GAS_LIMIT,
171
+ verificationGasLimit: params.gasLimits?.verificationGasLimit ?? DEFAULT_VERIFICATION_GAS_LIMIT,
172
+ preVerificationGas: params.gasLimits?.preVerificationGas ?? DEFAULT_PRE_VERIFICATION_GAS,
173
+ maxFeePerGas: params.feeOverrides?.maxFeePerGas ?? 0n,
174
+ maxPriorityFeePerGas: params.feeOverrides?.maxPriorityFeePerGas ?? 0n
175
+ };
176
+ }
177
+ function assembleUserOperation(partial, paymaster, signature) {
178
+ return {
179
+ ...partial,
180
+ paymaster: paymaster.paymaster,
181
+ paymasterData: paymaster.paymasterData,
182
+ paymasterVerificationGasLimit: paymaster.paymasterVerificationGasLimit,
183
+ paymasterPostOpGasLimit: paymaster.paymasterPostOpGasLimit,
184
+ signature
185
+ };
186
+ }
187
+
188
+ // src/userop/operations.ts
189
+ import { encodeFunctionData as encodeFunctionData3, erc20Abi as erc20Abi2, parseAbi as parseAbi2 } from "viem";
190
+ var ERC20_BURNABLE_ABI = parseAbi2(["function burn(uint256 amount)"]);
191
+ function erc20TransferOp(token, to, amount) {
192
+ return {
193
+ target: token,
194
+ value: 0n,
195
+ data: encodeFunctionData3({
196
+ abi: erc20Abi2,
197
+ functionName: "transfer",
198
+ args: [to, amount]
199
+ })
200
+ };
201
+ }
202
+ function erc20ApproveOp(token, spender, amount) {
203
+ return {
204
+ target: token,
205
+ value: 0n,
206
+ data: encodeFunctionData3({
207
+ abi: erc20Abi2,
208
+ functionName: "approve",
209
+ args: [spender, amount]
210
+ })
211
+ };
212
+ }
213
+ function erc20BurnOp(token, amount) {
214
+ return {
215
+ target: token,
216
+ value: 0n,
217
+ data: encodeFunctionData3({
218
+ abi: ERC20_BURNABLE_ABI,
219
+ functionName: "burn",
220
+ args: [amount]
221
+ })
222
+ };
223
+ }
224
+ function rawCallOp(target, data, value = 0n) {
225
+ return { target, value, data };
226
+ }
227
+
228
+ // src/swap/buildSwapWithGasDeduction.ts
229
+ function buildSwapWithGasDeduction(params) {
230
+ if (params.amountIn <= 0n) {
231
+ throw new Error("buildSwapWithGasDeduction: amountIn must be positive");
232
+ }
233
+ if (params.minAmountOut < 0n) {
234
+ throw new Error(
235
+ "buildSwapWithGasDeduction: minAmountOut must be non-negative"
236
+ );
237
+ }
238
+ if (params.gasFeePt < 0n) {
239
+ throw new Error(
240
+ "buildSwapWithGasDeduction: gasFeePt must be non-negative"
241
+ );
242
+ }
243
+ if (params.swapPath.length === 0) {
244
+ throw new Error(
245
+ "buildSwapWithGasDeduction: swapPath must contain at least one PathKey"
246
+ );
247
+ }
248
+ const { commands, inputs } = buildUniversalRouterExecuteArgs(
249
+ params.pointTokenAddress,
250
+ params.swapPath,
251
+ params.amountIn,
252
+ params.minAmountOut,
253
+ params.outputTokenAddress
254
+ );
255
+ const swapCallData = encodeFunctionData4({
256
+ abi: universalRouterAbi,
257
+ functionName: "execute",
258
+ args: [commands, inputs, params.deadline]
259
+ });
260
+ const operations = [
261
+ erc20ApproveOp(
262
+ params.pointTokenAddress,
263
+ params.universalRouterAddress,
264
+ params.amountIn
265
+ ),
266
+ rawCallOp(params.universalRouterAddress, swapCallData)
267
+ ];
268
+ if (params.gasFeePt > 0n) {
269
+ operations.push(
270
+ erc20TransferOp(
271
+ params.pointTokenAddress,
272
+ params.feeRecipient,
273
+ params.gasFeePt
274
+ )
275
+ );
276
+ }
277
+ return buildPartialUserOperation({
278
+ sender: params.userAddress,
279
+ nonce: params.aaNonce,
280
+ operations,
281
+ gasLimits: {
282
+ callGasLimit: params.gasLimits?.callGasLimit ?? 700000n,
283
+ verificationGasLimit: params.gasLimits?.verificationGasLimit ?? 150000n,
284
+ preVerificationGas: params.gasLimits?.preVerificationGas ?? 50000n
285
+ }
286
+ });
287
+ }
288
+
289
+ export {
290
+ checkAllowance,
291
+ buildErc20ApprovalCalldata,
292
+ buildPermit2ApprovalCalldata,
293
+ V4_SWAP,
294
+ SWAP_EXACT_IN,
295
+ SETTLE_ALL,
296
+ TAKE_ALL,
297
+ buildV4SwapInput,
298
+ buildUniversalRouterExecuteArgs,
299
+ buildSwapFromQuote,
300
+ simulateSwap,
301
+ BATCH_EXECUTOR_ABI,
302
+ encodeBatchExecute,
303
+ buildPartialUserOperation,
304
+ assembleUserOperation,
305
+ erc20TransferOp,
306
+ erc20ApproveOp,
307
+ erc20BurnOp,
308
+ rawCallOp,
309
+ buildSwapWithGasDeduction
310
+ };
311
+ //# sourceMappingURL=chunk-IK4UK7KT.js.map