@pafi-dev/core 0.2.0 → 0.3.0-alpha.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/README.md +32 -0
- package/dist/{chunk-O7LQKCBT.cjs → chunk-6I6K43RQ.cjs} +1 -1
- package/dist/chunk-6I6K43RQ.cjs.map +1 -0
- package/dist/{chunk-4QOWQQCH.cjs → chunk-L74CZAVQ.cjs} +1 -1
- package/dist/chunk-L74CZAVQ.cjs.map +1 -0
- package/dist/{chunk-37BBGXTS.js → chunk-UU72CX7E.js} +1 -1
- package/dist/{chunk-37BBGXTS.js.map → chunk-UU72CX7E.js.map} +1 -1
- package/dist/{chunk-DSCUHT3F.js → chunk-X4IXUTTD.js} +1 -1
- package/dist/chunk-X4IXUTTD.js.map +1 -0
- package/dist/index.cjs +164 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +271 -2
- package/dist/index.d.ts +271 -2
- package/dist/index.js +155 -2
- package/dist/index.js.map +1 -1
- package/dist/relay/index.cjs +2 -2
- package/dist/relay/index.d.cts +13 -0
- package/dist/relay/index.d.ts +13 -0
- package/dist/relay/index.js +1 -1
- package/dist/swap/index.cjs +2 -2
- package/dist/swap/index.d.cts +5 -0
- package/dist/swap/index.d.ts +5 -0
- package/dist/swap/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4QOWQQCH.cjs.map +0 -1
- package/dist/chunk-DSCUHT3F.js.map +0 -1
- package/dist/chunk-O7LQKCBT.cjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
encodeExtData,
|
|
62
62
|
encodeMintAndSwap,
|
|
63
63
|
simulateMintAndSwap
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-X4IXUTTD.js";
|
|
65
65
|
import {
|
|
66
66
|
relayAbi
|
|
67
67
|
} from "./chunk-4RYBJLF3.js";
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
buildV4SwapInput,
|
|
78
78
|
checkAllowance,
|
|
79
79
|
simulateSwap
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-UU72CX7E.js";
|
|
81
81
|
import {
|
|
82
82
|
erc20Abi,
|
|
83
83
|
permit2Abi,
|
|
@@ -93,6 +93,144 @@ import {
|
|
|
93
93
|
|
|
94
94
|
// src/index.ts
|
|
95
95
|
import { createPublicClient, http } from "viem";
|
|
96
|
+
|
|
97
|
+
// src/userop/types.ts
|
|
98
|
+
var ENTRY_POINT_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
|
|
99
|
+
var ZERO_VALUE = 0n;
|
|
100
|
+
|
|
101
|
+
// src/userop/operations.ts
|
|
102
|
+
import { encodeFunctionData, erc20Abi as erc20Abi2, parseAbi } from "viem";
|
|
103
|
+
var ERC20_BURNABLE_ABI = parseAbi(["function burn(uint256 amount)"]);
|
|
104
|
+
function erc20TransferOp(token, to, amount) {
|
|
105
|
+
return {
|
|
106
|
+
target: token,
|
|
107
|
+
value: 0n,
|
|
108
|
+
data: encodeFunctionData({
|
|
109
|
+
abi: erc20Abi2,
|
|
110
|
+
functionName: "transfer",
|
|
111
|
+
args: [to, amount]
|
|
112
|
+
})
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function erc20ApproveOp(token, spender, amount) {
|
|
116
|
+
return {
|
|
117
|
+
target: token,
|
|
118
|
+
value: 0n,
|
|
119
|
+
data: encodeFunctionData({
|
|
120
|
+
abi: erc20Abi2,
|
|
121
|
+
functionName: "approve",
|
|
122
|
+
args: [spender, amount]
|
|
123
|
+
})
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function erc20BurnOp(token, amount) {
|
|
127
|
+
return {
|
|
128
|
+
target: token,
|
|
129
|
+
value: 0n,
|
|
130
|
+
data: encodeFunctionData({
|
|
131
|
+
abi: ERC20_BURNABLE_ABI,
|
|
132
|
+
functionName: "burn",
|
|
133
|
+
args: [amount]
|
|
134
|
+
})
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function rawCallOp(target, data, value = 0n) {
|
|
138
|
+
return { target, value, data };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// src/userop/batchExecute.ts
|
|
142
|
+
import { encodeFunctionData as encodeFunctionData2, parseAbi as parseAbi2 } from "viem";
|
|
143
|
+
var BATCH_EXECUTOR_ABI = parseAbi2([
|
|
144
|
+
"function execute((address target, uint256 value, bytes data)[] calls)"
|
|
145
|
+
]);
|
|
146
|
+
function encodeBatchExecute(operations) {
|
|
147
|
+
if (operations.length === 0) {
|
|
148
|
+
throw new Error("encodeBatchExecute: operations array must not be empty");
|
|
149
|
+
}
|
|
150
|
+
return encodeFunctionData2({
|
|
151
|
+
abi: BATCH_EXECUTOR_ABI,
|
|
152
|
+
functionName: "execute",
|
|
153
|
+
args: [
|
|
154
|
+
operations.map((op) => ({
|
|
155
|
+
target: op.target,
|
|
156
|
+
value: op.value,
|
|
157
|
+
data: op.data
|
|
158
|
+
}))
|
|
159
|
+
]
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/userop/buildUserOperation.ts
|
|
164
|
+
var DEFAULT_CALL_GAS_LIMIT = 500000n;
|
|
165
|
+
var DEFAULT_VERIFICATION_GAS_LIMIT = 150000n;
|
|
166
|
+
var DEFAULT_PRE_VERIFICATION_GAS = 50000n;
|
|
167
|
+
function buildPartialUserOperation(params) {
|
|
168
|
+
return {
|
|
169
|
+
sender: params.sender,
|
|
170
|
+
nonce: params.nonce,
|
|
171
|
+
callData: encodeBatchExecute(params.operations),
|
|
172
|
+
callGasLimit: params.gasLimits?.callGasLimit ?? DEFAULT_CALL_GAS_LIMIT,
|
|
173
|
+
verificationGasLimit: params.gasLimits?.verificationGasLimit ?? DEFAULT_VERIFICATION_GAS_LIMIT,
|
|
174
|
+
preVerificationGas: params.gasLimits?.preVerificationGas ?? DEFAULT_PRE_VERIFICATION_GAS,
|
|
175
|
+
maxFeePerGas: params.feeOverrides?.maxFeePerGas ?? 0n,
|
|
176
|
+
maxPriorityFeePerGas: params.feeOverrides?.maxPriorityFeePerGas ?? 0n
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function assembleUserOperation(partial, paymaster, signature) {
|
|
180
|
+
return {
|
|
181
|
+
...partial,
|
|
182
|
+
paymaster: paymaster.paymaster,
|
|
183
|
+
paymasterData: paymaster.paymasterData,
|
|
184
|
+
paymasterVerificationGasLimit: paymaster.paymasterVerificationGasLimit,
|
|
185
|
+
paymasterPostOpGasLimit: paymaster.paymasterPostOpGasLimit,
|
|
186
|
+
signature
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/paymaster/config.ts
|
|
191
|
+
var _config = null;
|
|
192
|
+
function setPaymasterConfig(config) {
|
|
193
|
+
if (!config.pafiBackendUrl) {
|
|
194
|
+
throw new Error("setPaymasterConfig: pafiBackendUrl is required");
|
|
195
|
+
}
|
|
196
|
+
if (!config.issuerId) {
|
|
197
|
+
throw new Error("setPaymasterConfig: issuerId is required");
|
|
198
|
+
}
|
|
199
|
+
if (!config.apiKey) {
|
|
200
|
+
throw new Error("setPaymasterConfig: apiKey is required");
|
|
201
|
+
}
|
|
202
|
+
if (!config.feeRecipient) {
|
|
203
|
+
throw new Error("setPaymasterConfig: feeRecipient is required");
|
|
204
|
+
}
|
|
205
|
+
_config = { ...config };
|
|
206
|
+
}
|
|
207
|
+
function getPaymasterConfig() {
|
|
208
|
+
if (!_config) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
"PaymasterConfig not initialized \u2014 call setPaymasterConfig() at application boot before invoking any batch builder"
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
return _config;
|
|
214
|
+
}
|
|
215
|
+
function _resetPaymasterConfigForTests() {
|
|
216
|
+
_config = null;
|
|
217
|
+
}
|
|
218
|
+
function isPaymasterConfigured() {
|
|
219
|
+
return _config !== null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/utils/checkEthAndBranch.ts
|
|
223
|
+
var DEFAULT_MARGIN_BPS = 11e3;
|
|
224
|
+
async function checkEthAndBranch(params) {
|
|
225
|
+
const marginBps = params.marginBps ?? DEFAULT_MARGIN_BPS;
|
|
226
|
+
const required = params.estimatedGasWei * BigInt(marginBps) / 10000n;
|
|
227
|
+
const balance = await params.client.getBalance({
|
|
228
|
+
address: params.initiator
|
|
229
|
+
});
|
|
230
|
+
return balance >= required ? "normal" : "paymaster";
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/index.ts
|
|
96
234
|
var PafiSDK = class {
|
|
97
235
|
_pointTokenAddress;
|
|
98
236
|
_relayContractAddress;
|
|
@@ -344,9 +482,11 @@ var PafiSDK = class {
|
|
|
344
482
|
};
|
|
345
483
|
export {
|
|
346
484
|
ApiError,
|
|
485
|
+
BATCH_EXECUTOR_ABI,
|
|
347
486
|
COMMON_POOLS,
|
|
348
487
|
COMMON_TOKENS,
|
|
349
488
|
ConfigurationError,
|
|
489
|
+
ENTRY_POINT_V07,
|
|
350
490
|
POINT_TOKEN_POOLS,
|
|
351
491
|
PafiSDK,
|
|
352
492
|
PafiSDKError,
|
|
@@ -359,10 +499,14 @@ export {
|
|
|
359
499
|
UNIVERSAL_ROUTER_ADDRESSES,
|
|
360
500
|
V4_QUOTER_ADDRESSES,
|
|
361
501
|
V4_SWAP,
|
|
502
|
+
ZERO_VALUE,
|
|
503
|
+
_resetPaymasterConfigForTests,
|
|
504
|
+
assembleUserOperation,
|
|
362
505
|
buildAllPaths,
|
|
363
506
|
buildDomain,
|
|
364
507
|
buildErc20ApprovalCalldata,
|
|
365
508
|
buildMintRequestTypedData,
|
|
509
|
+
buildPartialUserOperation,
|
|
366
510
|
buildPermit2ApprovalCalldata,
|
|
367
511
|
buildReceiverConsentTypedData,
|
|
368
512
|
buildRelaySwapParams,
|
|
@@ -370,16 +514,22 @@ export {
|
|
|
370
514
|
buildUniversalRouterExecuteArgs,
|
|
371
515
|
buildV4SwapInput,
|
|
372
516
|
checkAllowance,
|
|
517
|
+
checkEthAndBranch,
|
|
373
518
|
combineRoutes,
|
|
374
519
|
createLoginMessage,
|
|
375
520
|
decodeExtData,
|
|
376
521
|
decodeMintAndSwap,
|
|
522
|
+
encodeBatchExecute,
|
|
377
523
|
encodeExtData,
|
|
378
524
|
encodeMintAndSwap,
|
|
379
525
|
erc20Abi,
|
|
526
|
+
erc20ApproveOp,
|
|
527
|
+
erc20BurnOp,
|
|
528
|
+
erc20TransferOp,
|
|
380
529
|
findBestQuote,
|
|
381
530
|
getIssuer2 as getIssuer,
|
|
382
531
|
getMintRequestNonce,
|
|
532
|
+
getPaymasterConfig,
|
|
383
533
|
getPointTokenBalance,
|
|
384
534
|
getPointTokenIssuer,
|
|
385
535
|
getIssuer as getPointTokenIssuerAddress,
|
|
@@ -388,6 +538,7 @@ export {
|
|
|
388
538
|
getUsdt,
|
|
389
539
|
isActiveIssuer,
|
|
390
540
|
isMinter,
|
|
541
|
+
isPaymasterConfigured,
|
|
391
542
|
issuerRegistryAbi,
|
|
392
543
|
mintRequestTypes,
|
|
393
544
|
mintingOracleAbi,
|
|
@@ -398,8 +549,10 @@ export {
|
|
|
398
549
|
quoteBestRoute,
|
|
399
550
|
quoteExactInput,
|
|
400
551
|
quoteExactInputSingle,
|
|
552
|
+
rawCallOp,
|
|
401
553
|
receiverConsentTypes,
|
|
402
554
|
relayAbi,
|
|
555
|
+
setPaymasterConfig,
|
|
403
556
|
signMintRequest,
|
|
404
557
|
signReceiverConsent,
|
|
405
558
|
simulateMintAndSwap,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createPublicClient, http } from \"viem\";\nimport type { Address, Hex, PublicClient, WalletClient } from \"viem\";\n\n// -------------------------------------------------------------------------\n// Re-export all sub-modules\n// -------------------------------------------------------------------------\nexport * from \"./types\";\nexport * from \"./constants\";\nexport * from \"./errors\";\nexport * from \"./abi/index\";\nexport * from \"./eip712/index\";\nexport * from \"./relay/index\";\nexport * from \"./contract/index\";\nexport * from \"./quoting/index\";\nexport * from \"./swap/index\";\nexport * from \"./auth/index\";\n\n// -------------------------------------------------------------------------\n// Internal imports for PafiSDK class\n// -------------------------------------------------------------------------\nimport { buildMintRequestTypedData, signMintRequest, verifyMintRequest } from \"./eip712/mintRequest\";\nimport {\n buildReceiverConsentTypedData,\n signReceiverConsent,\n verifyReceiverConsent,\n} from \"./eip712/receiverConsent\";\nimport {\n getMintRequestNonce,\n getReceiverConsentNonce,\n getTokenName,\n} from \"./contract/pointToken\";\nimport {\n encodeMintAndSwap,\n decodeMintAndSwap,\n encodeExtData,\n buildRelaySwapParams,\n} from \"./relay/calldata\";\nimport { findBestQuote } from \"./quoting/quote\";\nimport {\n buildSwapFromQuote,\n buildUniversalRouterExecuteArgs,\n} from \"./swap/universalRouter\";\nimport { simulateMintAndSwap } from \"./relay/simulate\";\nimport { simulateSwap } from \"./swap/simulate\";\nimport type { SimulationResult } from \"./relay/simulate\";\nimport type { SwapSimulationResult } from \"./swap/simulate\";\nimport { createLoginMessage } from \"./auth/loginMessage\";\nimport type { LoginMessageParams } from \"./auth/types\";\nimport { ConfigurationError } from \"./errors\";\nimport type {\n BestQuote,\n EIP712Signature,\n MintParams,\n MintRequest,\n PafiSDKConfig,\n PathKey,\n PointTokenDomainConfig,\n PoolKey,\n QuoteResult,\n ReceiverConsent,\n SignatureVerification,\n SwapParams,\n} from \"./types\";\n\n// -------------------------------------------------------------------------\n// PafiSDK — convenience class wrapping all contract + crypto primitives.\n//\n// This class is HTTP-client-free on purpose. It covers signing, verifying,\n// contract reads, and calldata encoding — the things that need a signer\n// or a provider but no HTTP layer. The issuer backend defines its own HTTP\n// contract via `@pafi/issuer`; frontends build `fetch()` calls against\n// those types directly.\n// -------------------------------------------------------------------------\n\nexport class PafiSDK {\n private _pointTokenAddress?: Address;\n private _relayContractAddress?: Address;\n private _signer?: WalletClient;\n private _provider?: PublicClient;\n private _chainId?: number;\n\n constructor(config: PafiSDKConfig) {\n this._pointTokenAddress = config.pointTokenAddress;\n this._relayContractAddress = config.relayContractAddress;\n this._signer = config.signer;\n this._chainId = config.chainId;\n\n if (config.provider) {\n this._provider = config.provider;\n } else if (config.rpcUrl) {\n this._provider = createPublicClient({\n transport: http(config.rpcUrl),\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // Setters\n // -------------------------------------------------------------------------\n\n setPointTokenAddress(address: Address): void {\n this._pointTokenAddress = address;\n }\n\n setRelayContractAddress(address: Address): void {\n this._relayContractAddress = address;\n }\n\n setSigner(signer: WalletClient): void {\n this._signer = signer;\n }\n\n setProvider(provider: PublicClient): void {\n this._provider = provider;\n }\n\n // -------------------------------------------------------------------------\n // Private guards\n // -------------------------------------------------------------------------\n\n private requirePointToken(): Address {\n if (!this._pointTokenAddress) {\n throw new ConfigurationError(\"pointTokenAddress not set\");\n }\n return this._pointTokenAddress;\n }\n\n private requireProvider(): PublicClient {\n if (!this._provider) {\n throw new ConfigurationError(\"provider not set\");\n }\n return this._provider;\n }\n\n private requireSigner(): WalletClient {\n if (!this._signer) {\n throw new ConfigurationError(\"signer not set\");\n }\n return this._signer;\n }\n\n private requireChainId(): number {\n if (this._chainId === undefined) {\n throw new ConfigurationError(\"chainId not set\");\n }\n return this._chainId;\n }\n\n // -------------------------------------------------------------------------\n // Domain\n // -------------------------------------------------------------------------\n\n async getDomain(): Promise<PointTokenDomainConfig> {\n const provider = this.requireProvider();\n const pointToken = this.requirePointToken();\n const chainId = this.requireChainId();\n const name = await getTokenName(provider, pointToken);\n return { name, verifyingContract: pointToken, chainId };\n }\n\n // -------------------------------------------------------------------------\n // EIP-712 — delegates to pure functions\n // -------------------------------------------------------------------------\n\n /**\n * Build the EIP-712 typed data for a MintRequest.\n * Pass the result to any external signer (Privy, WalletConnect, etc.).\n */\n async buildMintRequestTypedData(message: MintRequest) {\n const domain = await this.getDomain();\n return buildMintRequestTypedData(domain, message);\n }\n\n /**\n * Build the EIP-712 typed data for a ReceiverConsent.\n * Pass the result to any external signer (Privy, WalletConnect, etc.).\n */\n async buildReceiverConsentTypedData(message: ReceiverConsent) {\n const domain = await this.getDomain();\n return buildReceiverConsentTypedData(domain, message);\n }\n\n async signMintRequest(message: MintRequest): Promise<EIP712Signature> {\n const domain = await this.getDomain();\n return signMintRequest(this.requireSigner(), domain, message);\n }\n\n async verifyMintRequest(\n message: MintRequest,\n signature: Hex,\n expectedMinter: Address,\n ): Promise<SignatureVerification> {\n const domain = await this.getDomain();\n return verifyMintRequest(domain, message, signature, expectedMinter);\n }\n\n async signReceiverConsent(\n message: ReceiverConsent,\n ): Promise<EIP712Signature> {\n const domain = await this.getDomain();\n return signReceiverConsent(this.requireSigner(), domain, message);\n }\n\n async verifyReceiverConsent(\n message: ReceiverConsent,\n signature: Hex,\n expectedReceiver: Address,\n ): Promise<SignatureVerification> {\n const domain = await this.getDomain();\n return verifyReceiverConsent(domain, message, signature, expectedReceiver);\n }\n\n // -------------------------------------------------------------------------\n // Contract reads\n // -------------------------------------------------------------------------\n\n async getMintRequestNonce(receiver: Address): Promise<bigint> {\n return getMintRequestNonce(\n this.requireProvider(),\n this.requirePointToken(),\n receiver,\n );\n }\n\n async getReceiverConsentNonce(receiver: Address): Promise<bigint> {\n return getReceiverConsentNonce(\n this.requireProvider(),\n this.requirePointToken(),\n receiver,\n );\n }\n\n // -------------------------------------------------------------------------\n // Relay calldata — delegates to pure functions\n // -------------------------------------------------------------------------\n\n encodeMintAndSwap(mint: MintParams, swap: SwapParams): Hex {\n return encodeMintAndSwap(mint, swap);\n }\n\n decodeMintAndSwap(calldata: Hex): { mint: MintParams; swap: SwapParams } {\n return decodeMintAndSwap(calldata);\n }\n\n // -------------------------------------------------------------------------\n // Quoting — delegates to pure functions\n // -------------------------------------------------------------------------\n\n /**\n * Find the best swap route from `tokenIn` to `tokenOut`.\n * Merges `pools` with COMMON_POOLS for the configured chain, builds all\n * paths, and quotes via a single multicall RPC call.\n */\n async findBestQuote(\n tokenIn: Address,\n tokenOut: Address,\n exactAmount: bigint,\n pools: PoolKey[] = [],\n quoterAddress?: Address,\n maxHops?: number,\n ): Promise<BestQuote> {\n return findBestQuote(\n this.requireProvider(),\n this.requireChainId(),\n tokenIn,\n tokenOut,\n exactAmount,\n pools,\n quoterAddress,\n maxHops,\n );\n }\n\n // -------------------------------------------------------------------------\n // Swap building — delegates to pure functions\n // -------------------------------------------------------------------------\n\n /**\n * Build UniversalRouter execute args from a quote result.\n * The caller provides `minAmountOut` after applying their own slippage.\n */\n buildSwapFromQuote(params: {\n quote: QuoteResult;\n currencyIn: Address;\n currencyOut: Address;\n amountIn: bigint;\n minAmountOut: bigint;\n }): { commands: Hex; inputs: Hex[] } {\n return buildSwapFromQuote(params);\n }\n\n /**\n * Build Relay SwapParams + extData from a quote result.\n * Returns ready-to-use args for `Relay.mintAndSwap`.\n */\n buildRelaySwapParams(params: {\n quote: { path: PathKey[] };\n minAmountOut: bigint;\n feeInUsdt: bigint;\n deadline: bigint;\n }): { swapParams: SwapParams; extData: Hex } {\n return buildRelaySwapParams(params);\n }\n\n /**\n * Encode extData for ReceiverConsent and MintParams.\n * extData = abi.encode(minAmountOut, feeInUsdt)\n */\n encodeExtData(minAmountOut: bigint, feeInUsdt: bigint): Hex {\n return encodeExtData(minAmountOut, feeInUsdt);\n }\n\n // -------------------------------------------------------------------------\n // Simulation — dry-run via eth_call (no gas spent)\n // -------------------------------------------------------------------------\n\n /**\n * Simulate a Relay.mintAndSwap call. Catches reverts (bad signatures,\n * expired deadlines, insufficient mint cap, pool errors) before submitting.\n *\n * @param relayAddress - Relay contract address\n * @param mint - MintParams with real signatures\n * @param swap - SwapParams (path + deadline)\n * @param from - Relayer address that will submit the tx\n */\n async simulateMintAndSwap(\n relayAddress: Address,\n mint: MintParams,\n swap: SwapParams,\n from: Address,\n ): Promise<SimulationResult> {\n return simulateMintAndSwap(\n this.requireProvider(),\n relayAddress,\n mint,\n swap,\n from,\n );\n }\n\n /**\n * Simulate a UniversalRouter.execute swap call. Catches reverts (bad\n * approvals, insufficient balance, pool errors) before submitting.\n *\n * @param routerAddress - UniversalRouter contract address\n * @param commands - Packed command bytes (from buildSwapFromQuote)\n * @param inputs - Encoded inputs (from buildSwapFromQuote)\n * @param deadline - Unix timestamp\n * @param from - Address that will execute the swap\n */\n async simulateSwap(\n routerAddress: Address,\n commands: Hex,\n inputs: Hex[],\n deadline: bigint,\n from: Address,\n ): Promise<SwapSimulationResult> {\n return simulateSwap(\n this.requireProvider(),\n routerAddress,\n commands,\n inputs,\n deadline,\n from,\n );\n }\n\n // -------------------------------------------------------------------------\n // Auth — EIP-4361 login helpers (offline, stateless)\n //\n // These are convenience wrappers around the pure functions in\n // `./auth/loginMessage.ts`. They do NOT hit the network — the caller is\n // responsible for fetching the nonce, POSTing the signed message, and\n // storing the JWT returned by the issuer backend.\n // -------------------------------------------------------------------------\n\n /**\n * Build an EIP-4361 login message for the current signer + chain. The\n * caller supplies the issuer-specific fields (domain, nonce, uri); the SDK\n * fills in the wallet address and chain id from its own config.\n */\n async createLoginMessage(\n params: Omit<LoginMessageParams, \"address\" | \"chainId\">,\n ): Promise<string> {\n const signer = this.requireSigner();\n const chainId = this.requireChainId();\n const account = signer.account;\n if (!account) {\n throw new ConfigurationError(\"signer has no account attached\");\n }\n return createLoginMessage({ ...params, address: account.address, chainId });\n }\n\n /** Sign a login message string with the current signer (personal_sign) */\n async signLoginMessage(message: string): Promise<Hex> {\n const signer = this.requireSigner();\n const account = signer.account;\n if (!account) {\n throw new ConfigurationError(\"signer has no account attached\");\n }\n return signer.signMessage({ account, message });\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/userop/types.ts","../src/userop/operations.ts","../src/userop/batchExecute.ts","../src/userop/buildUserOperation.ts","../src/paymaster/config.ts","../src/utils/checkEthAndBranch.ts"],"sourcesContent":["import { createPublicClient, http } from \"viem\";\nimport type { Address, Hex, PublicClient, WalletClient } from \"viem\";\n\n// -------------------------------------------------------------------------\n// Re-export all sub-modules\n// -------------------------------------------------------------------------\nexport * from \"./types\";\nexport * from \"./constants\";\nexport * from \"./errors\";\nexport * from \"./abi/index\";\nexport * from \"./eip712/index\";\nexport * from \"./relay/index\";\nexport * from \"./contract/index\";\nexport * from \"./quoting/index\";\nexport * from \"./swap/index\";\nexport * from \"./auth/index\";\n\n// v1.4 — Account Abstraction primitives (EIP-7702 + ERC-4337 v0.7)\nexport * from \"./userop/index\";\nexport * from \"./paymaster/index\";\nexport * from \"./utils/index\";\n\n// -------------------------------------------------------------------------\n// Internal imports for PafiSDK class\n// -------------------------------------------------------------------------\nimport { buildMintRequestTypedData, signMintRequest, verifyMintRequest } from \"./eip712/mintRequest\";\nimport {\n buildReceiverConsentTypedData,\n signReceiverConsent,\n verifyReceiverConsent,\n} from \"./eip712/receiverConsent\";\nimport {\n getMintRequestNonce,\n getReceiverConsentNonce,\n getTokenName,\n} from \"./contract/pointToken\";\nimport {\n encodeMintAndSwap,\n decodeMintAndSwap,\n encodeExtData,\n buildRelaySwapParams,\n} from \"./relay/calldata\";\nimport { findBestQuote } from \"./quoting/quote\";\nimport {\n buildSwapFromQuote,\n buildUniversalRouterExecuteArgs,\n} from \"./swap/universalRouter\";\nimport { simulateMintAndSwap } from \"./relay/simulate\";\nimport { simulateSwap } from \"./swap/simulate\";\nimport type { SimulationResult } from \"./relay/simulate\";\nimport type { SwapSimulationResult } from \"./swap/simulate\";\nimport { createLoginMessage } from \"./auth/loginMessage\";\nimport type { LoginMessageParams } from \"./auth/types\";\nimport { ConfigurationError } from \"./errors\";\nimport type {\n BestQuote,\n EIP712Signature,\n MintParams,\n MintRequest,\n PafiSDKConfig,\n PathKey,\n PointTokenDomainConfig,\n PoolKey,\n QuoteResult,\n ReceiverConsent,\n SignatureVerification,\n SwapParams,\n} from \"./types\";\n\n// -------------------------------------------------------------------------\n// PafiSDK — convenience class wrapping all contract + crypto primitives.\n//\n// This class is HTTP-client-free on purpose. It covers signing, verifying,\n// contract reads, and calldata encoding — the things that need a signer\n// or a provider but no HTTP layer. The issuer backend defines its own HTTP\n// contract via `@pafi/issuer`; frontends build `fetch()` calls against\n// those types directly.\n// -------------------------------------------------------------------------\n\nexport class PafiSDK {\n private _pointTokenAddress?: Address;\n private _relayContractAddress?: Address;\n private _signer?: WalletClient;\n private _provider?: PublicClient;\n private _chainId?: number;\n\n constructor(config: PafiSDKConfig) {\n this._pointTokenAddress = config.pointTokenAddress;\n this._relayContractAddress = config.relayContractAddress;\n this._signer = config.signer;\n this._chainId = config.chainId;\n\n if (config.provider) {\n this._provider = config.provider;\n } else if (config.rpcUrl) {\n this._provider = createPublicClient({\n transport: http(config.rpcUrl),\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // Setters\n // -------------------------------------------------------------------------\n\n setPointTokenAddress(address: Address): void {\n this._pointTokenAddress = address;\n }\n\n setRelayContractAddress(address: Address): void {\n this._relayContractAddress = address;\n }\n\n setSigner(signer: WalletClient): void {\n this._signer = signer;\n }\n\n setProvider(provider: PublicClient): void {\n this._provider = provider;\n }\n\n // -------------------------------------------------------------------------\n // Private guards\n // -------------------------------------------------------------------------\n\n private requirePointToken(): Address {\n if (!this._pointTokenAddress) {\n throw new ConfigurationError(\"pointTokenAddress not set\");\n }\n return this._pointTokenAddress;\n }\n\n private requireProvider(): PublicClient {\n if (!this._provider) {\n throw new ConfigurationError(\"provider not set\");\n }\n return this._provider;\n }\n\n private requireSigner(): WalletClient {\n if (!this._signer) {\n throw new ConfigurationError(\"signer not set\");\n }\n return this._signer;\n }\n\n private requireChainId(): number {\n if (this._chainId === undefined) {\n throw new ConfigurationError(\"chainId not set\");\n }\n return this._chainId;\n }\n\n // -------------------------------------------------------------------------\n // Domain\n // -------------------------------------------------------------------------\n\n async getDomain(): Promise<PointTokenDomainConfig> {\n const provider = this.requireProvider();\n const pointToken = this.requirePointToken();\n const chainId = this.requireChainId();\n const name = await getTokenName(provider, pointToken);\n return { name, verifyingContract: pointToken, chainId };\n }\n\n // -------------------------------------------------------------------------\n // EIP-712 — delegates to pure functions\n // -------------------------------------------------------------------------\n\n /**\n * Build the EIP-712 typed data for a MintRequest.\n * Pass the result to any external signer (Privy, WalletConnect, etc.).\n */\n async buildMintRequestTypedData(message: MintRequest) {\n const domain = await this.getDomain();\n return buildMintRequestTypedData(domain, message);\n }\n\n /**\n * Build the EIP-712 typed data for a ReceiverConsent.\n * Pass the result to any external signer (Privy, WalletConnect, etc.).\n */\n async buildReceiverConsentTypedData(message: ReceiverConsent) {\n const domain = await this.getDomain();\n return buildReceiverConsentTypedData(domain, message);\n }\n\n async signMintRequest(message: MintRequest): Promise<EIP712Signature> {\n const domain = await this.getDomain();\n return signMintRequest(this.requireSigner(), domain, message);\n }\n\n async verifyMintRequest(\n message: MintRequest,\n signature: Hex,\n expectedMinter: Address,\n ): Promise<SignatureVerification> {\n const domain = await this.getDomain();\n return verifyMintRequest(domain, message, signature, expectedMinter);\n }\n\n async signReceiverConsent(\n message: ReceiverConsent,\n ): Promise<EIP712Signature> {\n const domain = await this.getDomain();\n return signReceiverConsent(this.requireSigner(), domain, message);\n }\n\n async verifyReceiverConsent(\n message: ReceiverConsent,\n signature: Hex,\n expectedReceiver: Address,\n ): Promise<SignatureVerification> {\n const domain = await this.getDomain();\n return verifyReceiverConsent(domain, message, signature, expectedReceiver);\n }\n\n // -------------------------------------------------------------------------\n // Contract reads\n // -------------------------------------------------------------------------\n\n async getMintRequestNonce(receiver: Address): Promise<bigint> {\n return getMintRequestNonce(\n this.requireProvider(),\n this.requirePointToken(),\n receiver,\n );\n }\n\n async getReceiverConsentNonce(receiver: Address): Promise<bigint> {\n return getReceiverConsentNonce(\n this.requireProvider(),\n this.requirePointToken(),\n receiver,\n );\n }\n\n // -------------------------------------------------------------------------\n // Relay calldata — delegates to pure functions\n // -------------------------------------------------------------------------\n\n encodeMintAndSwap(mint: MintParams, swap: SwapParams): Hex {\n return encodeMintAndSwap(mint, swap);\n }\n\n decodeMintAndSwap(calldata: Hex): { mint: MintParams; swap: SwapParams } {\n return decodeMintAndSwap(calldata);\n }\n\n // -------------------------------------------------------------------------\n // Quoting — delegates to pure functions\n // -------------------------------------------------------------------------\n\n /**\n * Find the best swap route from `tokenIn` to `tokenOut`.\n * Merges `pools` with COMMON_POOLS for the configured chain, builds all\n * paths, and quotes via a single multicall RPC call.\n */\n async findBestQuote(\n tokenIn: Address,\n tokenOut: Address,\n exactAmount: bigint,\n pools: PoolKey[] = [],\n quoterAddress?: Address,\n maxHops?: number,\n ): Promise<BestQuote> {\n return findBestQuote(\n this.requireProvider(),\n this.requireChainId(),\n tokenIn,\n tokenOut,\n exactAmount,\n pools,\n quoterAddress,\n maxHops,\n );\n }\n\n // -------------------------------------------------------------------------\n // Swap building — delegates to pure functions\n // -------------------------------------------------------------------------\n\n /**\n * Build UniversalRouter execute args from a quote result.\n * The caller provides `minAmountOut` after applying their own slippage.\n */\n buildSwapFromQuote(params: {\n quote: QuoteResult;\n currencyIn: Address;\n currencyOut: Address;\n amountIn: bigint;\n minAmountOut: bigint;\n }): { commands: Hex; inputs: Hex[] } {\n return buildSwapFromQuote(params);\n }\n\n /**\n * Build Relay SwapParams + extData from a quote result.\n * Returns ready-to-use args for `Relay.mintAndSwap`.\n */\n buildRelaySwapParams(params: {\n quote: { path: PathKey[] };\n minAmountOut: bigint;\n feeInUsdt: bigint;\n deadline: bigint;\n }): { swapParams: SwapParams; extData: Hex } {\n return buildRelaySwapParams(params);\n }\n\n /**\n * Encode extData for ReceiverConsent and MintParams.\n * extData = abi.encode(minAmountOut, feeInUsdt)\n */\n encodeExtData(minAmountOut: bigint, feeInUsdt: bigint): Hex {\n return encodeExtData(minAmountOut, feeInUsdt);\n }\n\n // -------------------------------------------------------------------------\n // Simulation — dry-run via eth_call (no gas spent)\n // -------------------------------------------------------------------------\n\n /**\n * Simulate a Relay.mintAndSwap call. Catches reverts (bad signatures,\n * expired deadlines, insufficient mint cap, pool errors) before submitting.\n *\n * @param relayAddress - Relay contract address\n * @param mint - MintParams with real signatures\n * @param swap - SwapParams (path + deadline)\n * @param from - Relayer address that will submit the tx\n */\n async simulateMintAndSwap(\n relayAddress: Address,\n mint: MintParams,\n swap: SwapParams,\n from: Address,\n ): Promise<SimulationResult> {\n return simulateMintAndSwap(\n this.requireProvider(),\n relayAddress,\n mint,\n swap,\n from,\n );\n }\n\n /**\n * Simulate a UniversalRouter.execute swap call. Catches reverts (bad\n * approvals, insufficient balance, pool errors) before submitting.\n *\n * @param routerAddress - UniversalRouter contract address\n * @param commands - Packed command bytes (from buildSwapFromQuote)\n * @param inputs - Encoded inputs (from buildSwapFromQuote)\n * @param deadline - Unix timestamp\n * @param from - Address that will execute the swap\n */\n async simulateSwap(\n routerAddress: Address,\n commands: Hex,\n inputs: Hex[],\n deadline: bigint,\n from: Address,\n ): Promise<SwapSimulationResult> {\n return simulateSwap(\n this.requireProvider(),\n routerAddress,\n commands,\n inputs,\n deadline,\n from,\n );\n }\n\n // -------------------------------------------------------------------------\n // Auth — EIP-4361 login helpers (offline, stateless)\n //\n // These are convenience wrappers around the pure functions in\n // `./auth/loginMessage.ts`. They do NOT hit the network — the caller is\n // responsible for fetching the nonce, POSTing the signed message, and\n // storing the JWT returned by the issuer backend.\n // -------------------------------------------------------------------------\n\n /**\n * Build an EIP-4361 login message for the current signer + chain. The\n * caller supplies the issuer-specific fields (domain, nonce, uri); the SDK\n * fills in the wallet address and chain id from its own config.\n */\n async createLoginMessage(\n params: Omit<LoginMessageParams, \"address\" | \"chainId\">,\n ): Promise<string> {\n const signer = this.requireSigner();\n const chainId = this.requireChainId();\n const account = signer.account;\n if (!account) {\n throw new ConfigurationError(\"signer has no account attached\");\n }\n return createLoginMessage({ ...params, address: account.address, chainId });\n }\n\n /** Sign a login message string with the current signer (personal_sign) */\n async signLoginMessage(message: string): Promise<Hex> {\n const signer = this.requireSigner();\n const account = signer.account;\n if (!account) {\n throw new ConfigurationError(\"signer has no account attached\");\n }\n return signer.signMessage({ account, message });\n }\n}\n","import type { Address, Hex } from \"viem\";\n\n/**\n * ERC-4337 v0.7 EntryPoint standard address (deployed deterministically\n * at the same address across chains).\n * https://eips.ethereum.org/EIPS/eip-4337\n */\nexport const ENTRY_POINT_V07: Address =\n \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\";\n\n/**\n * A single call inside a batch. `BatchExecutor.execute(Call[])` iterates\n * and invokes each one. When the batch runs via EIP-7702 delegation,\n * `msg.sender` for each call is the user's EOA.\n */\nexport interface Operation {\n target: Address;\n value: bigint;\n data: Hex;\n}\n\n/**\n * Paymaster fields attached to a UserOperation. Populated by the\n * Coinbase Paymaster (via PAFI Backend proxy) before the user signs.\n */\nexport interface PaymasterFields {\n paymaster: Address;\n paymasterData: Hex;\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n}\n\n/**\n * Partial UserOp used during preparation — before paymaster fields are\n * attached or the user signs.\n */\nexport interface PartialUserOperation {\n sender: Address;\n nonce: bigint;\n callData: Hex;\n callGasLimit: bigint;\n verificationGasLimit: bigint;\n preVerificationGas: bigint;\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n}\n\n/**\n * Full ERC-4337 v0.7 UserOperation, ready for bundler submission.\n */\nexport interface UserOperation extends PartialUserOperation {\n paymaster: Address;\n paymasterData: Hex;\n paymasterVerificationGasLimit: bigint;\n paymasterPostOpGasLimit: bigint;\n signature: Hex;\n}\n\n/**\n * Receipt returned by a bundler after a UserOp lands on-chain.\n */\nexport interface UserOpReceipt {\n userOpHash: Hex;\n success: boolean;\n txHash: Hex;\n blockNumber: bigint;\n gasUsed: bigint;\n /** Effective gas cost paid (wei). */\n actualGasCost: bigint;\n}\n\n/**\n * Sentinel operation value used in tests + docs when `Operation.value`\n * is irrelevant (ERC-20 transfers, for example).\n */\nexport const ZERO_VALUE = 0n;\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","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 type { PaymasterConfig } from \"./types\";\n\n/**\n * Module-level paymaster config. Read by batch builders (via\n * `getPaymasterConfig()`) and by `@pafi/issuer` `RelayService` when\n * building UserOps.\n *\n * Consumers call `setPaymasterConfig()` once at application boot. All\n * subsequent helpers that need the feeRecipient / issuer identity /\n * backend URL pull from here.\n *\n * This is global state by design — making every batch builder take a\n * config param would clutter every call site. The alternative (a\n * context/service) has more ceremony than this flow justifies.\n */\nlet _config: PaymasterConfig | null = null;\n\n/**\n * Set the application-wide paymaster config. Safe to call multiple\n * times (later calls override earlier). Throws if required fields\n * are missing.\n */\nexport function setPaymasterConfig(config: PaymasterConfig): void {\n if (!config.pafiBackendUrl) {\n throw new Error(\"setPaymasterConfig: pafiBackendUrl is required\");\n }\n if (!config.issuerId) {\n throw new Error(\"setPaymasterConfig: issuerId is required\");\n }\n if (!config.apiKey) {\n throw new Error(\"setPaymasterConfig: apiKey is required\");\n }\n if (!config.feeRecipient) {\n throw new Error(\"setPaymasterConfig: feeRecipient is required\");\n }\n _config = { ...config };\n}\n\n/**\n * Get the current paymaster config. Throws if `setPaymasterConfig()`\n * has not been called yet — this surfaces boot-order bugs early\n * instead of failing with \"paymaster.feeRecipient is undefined\" at\n * the point of use.\n */\nexport function getPaymasterConfig(): PaymasterConfig {\n if (!_config) {\n throw new Error(\n \"PaymasterConfig not initialized — call setPaymasterConfig() at application boot before invoking any batch builder\",\n );\n }\n return _config;\n}\n\n/** Test helper — clear the singleton. */\nexport function _resetPaymasterConfigForTests(): void {\n _config = null;\n}\n\n/** Check whether paymaster config has been initialized. */\nexport function isPaymasterConfigured(): boolean {\n return _config !== null;\n}\n","import type { Address, PublicClient } from \"viem\";\n\n/**\n * Submission path chosen by `checkEthAndBranch`.\n * - `normal`: initiator has enough ETH; submit via `walletClient.writeContract`\n * or a plain `eth_sendRawTransaction`. No paymaster round-trip.\n * - `paymaster`: initiator doesn't have enough ETH; wrap the batch as a\n * UserOperation and route through PAFI Backend → Coinbase Paymaster\n * → Bundler.\n */\nexport type SubmissionPath = \"normal\" | \"paymaster\";\n\nexport interface CheckEthAndBranchParams {\n /** viem PublicClient bound to the target chain. */\n client: PublicClient;\n /** The address whose ETH balance we check. */\n initiator: Address;\n /** Estimated gas cost in wei for the upcoming tx. */\n estimatedGasWei: bigint;\n /**\n * Optional safety margin multiplier (basis points). Defaults to\n * 11_000 (110%) — the initiator needs 10% above the estimate to\n * qualify for the normal path. Prevents edge cases where gas price\n * spikes between estimation and submission cause a \"has enough\"\n * decision to fail at broadcast time.\n */\n marginBps?: number;\n}\n\nconst DEFAULT_MARGIN_BPS = 11_000;\n\n/**\n * Step 3 of the Generalized Flow ([SPONSORED_PATH_FLOW.md §2]):\n * choose between the normal path (initiator pays ETH directly) and the\n * paymaster path (bundler + Coinbase Paymaster).\n *\n * Intentionally synchronous in spirit — the only network call is\n * `getBalance`. Callers can parallelize it with other reads.\n */\nexport async function checkEthAndBranch(\n params: CheckEthAndBranchParams,\n): Promise<SubmissionPath> {\n const marginBps = params.marginBps ?? DEFAULT_MARGIN_BPS;\n const required =\n (params.estimatedGasWei * BigInt(marginBps)) / 10_000n;\n\n const balance = await params.client.getBalance({\n address: params.initiator,\n });\n\n return balance >= required ? \"normal\" : \"paymaster\";\n}\n"],"mappings":"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","names":["erc20Abi","encodeFunctionData","parseAbi"]}
|
package/dist/relay/index.cjs
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _chunkL74CZAVQcjs = require('../chunk-L74CZAVQ.cjs');
|
|
9
9
|
require('../chunk-27V32VNM.cjs');
|
|
10
10
|
require('../chunk-5QJZT7VB.cjs');
|
|
11
11
|
|
|
@@ -15,5 +15,5 @@ require('../chunk-5QJZT7VB.cjs');
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
exports.buildRelaySwapParams =
|
|
18
|
+
exports.buildRelaySwapParams = _chunkL74CZAVQcjs.buildRelaySwapParams; exports.decodeExtData = _chunkL74CZAVQcjs.decodeExtData; exports.decodeMintAndSwap = _chunkL74CZAVQcjs.decodeMintAndSwap; exports.encodeExtData = _chunkL74CZAVQcjs.encodeExtData; exports.encodeMintAndSwap = _chunkL74CZAVQcjs.encodeMintAndSwap; exports.simulateMintAndSwap = _chunkL74CZAVQcjs.simulateMintAndSwap;
|
|
19
19
|
//# sourceMappingURL=index.cjs.map
|
package/dist/relay/index.d.cts
CHANGED
|
@@ -20,6 +20,12 @@ declare function decodeExtData(extData: Hex): {
|
|
|
20
20
|
* @param minAmountOut - Minimum acceptable USDT output (caller applies slippage)
|
|
21
21
|
* @param feeInUsdt - Fixed USDT fee for the relayer
|
|
22
22
|
* @param deadline - Swap deadline (unix timestamp)
|
|
23
|
+
*
|
|
24
|
+
* @deprecated Since v1.4 — the `claimAndSwap` flow is retired. The
|
|
25
|
+
* Issuer App now performs mint-only claims; swaps happen on PAFI Web.
|
|
26
|
+
* For PT→USDT swap batch calls on PAFI Web, use
|
|
27
|
+
* `buildSwapWithGasDeduction()` (v1.5). This helper is kept for legacy
|
|
28
|
+
* consumers still on v0.2.x and will be removed in v2.0.
|
|
23
29
|
*/
|
|
24
30
|
declare function buildRelaySwapParams(params: {
|
|
25
31
|
quote: {
|
|
@@ -32,6 +38,13 @@ declare function buildRelaySwapParams(params: {
|
|
|
32
38
|
swapParams: SwapParams;
|
|
33
39
|
extData: Hex;
|
|
34
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Encode calldata for the legacy `Relayer.mintAndSwap()` function.
|
|
43
|
+
*
|
|
44
|
+
* @deprecated Since v1.4 — the `claimAndSwap` flow is retired. Use
|
|
45
|
+
* `Relayer.mint()` instead (via `@pafi-dev/issuer` RelayService in v1.4).
|
|
46
|
+
* Kept for legacy v0.2.x consumers; will be removed in v2.0.
|
|
47
|
+
*/
|
|
35
48
|
declare function encodeMintAndSwap(mint: MintParams, swap: SwapParams): Hex;
|
|
36
49
|
declare function decodeMintAndSwap(calldata: Hex): {
|
|
37
50
|
mint: MintParams;
|
package/dist/relay/index.d.ts
CHANGED
|
@@ -20,6 +20,12 @@ declare function decodeExtData(extData: Hex): {
|
|
|
20
20
|
* @param minAmountOut - Minimum acceptable USDT output (caller applies slippage)
|
|
21
21
|
* @param feeInUsdt - Fixed USDT fee for the relayer
|
|
22
22
|
* @param deadline - Swap deadline (unix timestamp)
|
|
23
|
+
*
|
|
24
|
+
* @deprecated Since v1.4 — the `claimAndSwap` flow is retired. The
|
|
25
|
+
* Issuer App now performs mint-only claims; swaps happen on PAFI Web.
|
|
26
|
+
* For PT→USDT swap batch calls on PAFI Web, use
|
|
27
|
+
* `buildSwapWithGasDeduction()` (v1.5). This helper is kept for legacy
|
|
28
|
+
* consumers still on v0.2.x and will be removed in v2.0.
|
|
23
29
|
*/
|
|
24
30
|
declare function buildRelaySwapParams(params: {
|
|
25
31
|
quote: {
|
|
@@ -32,6 +38,13 @@ declare function buildRelaySwapParams(params: {
|
|
|
32
38
|
swapParams: SwapParams;
|
|
33
39
|
extData: Hex;
|
|
34
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Encode calldata for the legacy `Relayer.mintAndSwap()` function.
|
|
43
|
+
*
|
|
44
|
+
* @deprecated Since v1.4 — the `claimAndSwap` flow is retired. Use
|
|
45
|
+
* `Relayer.mint()` instead (via `@pafi-dev/issuer` RelayService in v1.4).
|
|
46
|
+
* Kept for legacy v0.2.x consumers; will be removed in v2.0.
|
|
47
|
+
*/
|
|
35
48
|
declare function encodeMintAndSwap(mint: MintParams, swap: SwapParams): Hex;
|
|
36
49
|
declare function decodeMintAndSwap(calldata: Hex): {
|
|
37
50
|
mint: MintParams;
|
package/dist/relay/index.js
CHANGED
package/dist/swap/index.cjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunk6I6K43RQcjs = require('../chunk-6I6K43RQ.cjs');
|
|
14
14
|
require('../chunk-IPXARZ6F.cjs');
|
|
15
15
|
require('../chunk-5QJZT7VB.cjs');
|
|
16
16
|
|
|
@@ -25,5 +25,5 @@ require('../chunk-5QJZT7VB.cjs');
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
exports.SETTLE_ALL =
|
|
28
|
+
exports.SETTLE_ALL = _chunk6I6K43RQcjs.SETTLE_ALL; exports.SWAP_EXACT_IN = _chunk6I6K43RQcjs.SWAP_EXACT_IN; exports.TAKE_ALL = _chunk6I6K43RQcjs.TAKE_ALL; exports.V4_SWAP = _chunk6I6K43RQcjs.V4_SWAP; exports.buildErc20ApprovalCalldata = _chunk6I6K43RQcjs.buildErc20ApprovalCalldata; exports.buildPermit2ApprovalCalldata = _chunk6I6K43RQcjs.buildPermit2ApprovalCalldata; exports.buildSwapFromQuote = _chunk6I6K43RQcjs.buildSwapFromQuote; exports.buildUniversalRouterExecuteArgs = _chunk6I6K43RQcjs.buildUniversalRouterExecuteArgs; exports.buildV4SwapInput = _chunk6I6K43RQcjs.buildV4SwapInput; exports.checkAllowance = _chunk6I6K43RQcjs.checkAllowance; exports.simulateSwap = _chunk6I6K43RQcjs.simulateSwap;
|
|
29
29
|
//# sourceMappingURL=index.cjs.map
|
package/dist/swap/index.d.cts
CHANGED
|
@@ -44,6 +44,11 @@ declare function buildUniversalRouterExecuteArgs(currencyIn: Address, path: Path
|
|
|
44
44
|
* @param currencyOut - Output token address
|
|
45
45
|
* @param amountIn - Exact input amount (same value passed to the quoter)
|
|
46
46
|
* @param minAmountOut - Minimum acceptable output (caller applies slippage)
|
|
47
|
+
*
|
|
48
|
+
* @deprecated Since v1.4 — the Issuer App no longer handles swaps.
|
|
49
|
+
* For the new PT→USDT batch call on PAFI Web (Scenario 4 with
|
|
50
|
+
* EIP-7702 gas deduction), use `buildSwapWithGasDeduction()` (v1.5).
|
|
51
|
+
* This helper is kept for legacy v0.2.x consumers; will be removed in v2.0.
|
|
47
52
|
*/
|
|
48
53
|
declare function buildSwapFromQuote(params: {
|
|
49
54
|
quote: QuoteResult;
|
package/dist/swap/index.d.ts
CHANGED
|
@@ -44,6 +44,11 @@ declare function buildUniversalRouterExecuteArgs(currencyIn: Address, path: Path
|
|
|
44
44
|
* @param currencyOut - Output token address
|
|
45
45
|
* @param amountIn - Exact input amount (same value passed to the quoter)
|
|
46
46
|
* @param minAmountOut - Minimum acceptable output (caller applies slippage)
|
|
47
|
+
*
|
|
48
|
+
* @deprecated Since v1.4 — the Issuer App no longer handles swaps.
|
|
49
|
+
* For the new PT→USDT batch call on PAFI Web (Scenario 4 with
|
|
50
|
+
* EIP-7702 gas deduction), use `buildSwapWithGasDeduction()` (v1.5).
|
|
51
|
+
* This helper is kept for legacy v0.2.x consumers; will be removed in v2.0.
|
|
47
52
|
*/
|
|
48
53
|
declare function buildSwapFromQuote(params: {
|
|
49
54
|
quote: QuoteResult;
|
package/dist/swap/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/phitran/Pacific-Finance/pafi-backend/pafi-sdk/packages/core/dist/chunk-4QOWQQCH.cjs","../src/relay/calldata.ts","../src/relay/simulate.ts"],"names":[],"mappings":"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","file":"/Users/phitran/Pacific-Finance/pafi-backend/pafi-sdk/packages/core/dist/chunk-4QOWQQCH.cjs","sourcesContent":[null,"import {\n decodeFunctionData,\n encodeFunctionData,\n encodeAbiParameters,\n decodeAbiParameters,\n} from \"viem\";\nimport type { Hex } from \"viem\";\nimport { relayAbi } from \"../abi/relay\";\nimport type { MintParams, PathKey, SwapParams } from \"../types\";\n\n/**\n * Encode extData for ReceiverConsent and MintParams.\n * extData = abi.encode(uint256 minAmountOut, uint256 feeInUsdt)\n */\nexport function encodeExtData(minAmountOut: bigint, feeInUsdt: bigint): Hex {\n return encodeAbiParameters(\n [{ type: \"uint256\" }, { type: \"uint256\" }],\n [minAmountOut, feeInUsdt],\n );\n}\n\n/**\n * Decode extData back to { minAmountOut, feeInUsdt }.\n */\nexport function decodeExtData(extData: Hex): {\n minAmountOut: bigint;\n feeInUsdt: bigint;\n} {\n const [minAmountOut, feeInUsdt] = decodeAbiParameters(\n [{ type: \"uint256\" }, { type: \"uint256\" }],\n extData,\n );\n return { minAmountOut, feeInUsdt };\n}\n\n/**\n * Build SwapParams and extData from a quote result for Relay.mintAndSwap.\n *\n * @param quote - Quote result containing the path\n * @param minAmountOut - Minimum acceptable USDT output (caller applies slippage)\n * @param feeInUsdt - Fixed USDT fee for the relayer\n * @param deadline - Swap deadline (unix timestamp)\n */\nexport function buildRelaySwapParams(params: {\n quote: { path: PathKey[] };\n minAmountOut: bigint;\n feeInUsdt: bigint;\n deadline: bigint;\n}): { swapParams: SwapParams; extData: Hex } {\n return {\n swapParams: {\n path: params.quote.path,\n deadline: params.deadline,\n },\n extData: encodeExtData(params.minAmountOut, params.feeInUsdt),\n };\n}\n\nexport function encodeMintAndSwap(mint: MintParams, swap: SwapParams): Hex {\n return encodeFunctionData({\n abi: relayAbi,\n functionName: \"mintAndSwap\",\n args: [mint, swap],\n });\n}\n\nexport function decodeMintAndSwap(calldata: Hex): {\n mint: MintParams;\n swap: SwapParams;\n} {\n const { args } = decodeFunctionData({\n abi: relayAbi,\n data: calldata,\n });\n\n const [rawMint, rawSwap] = args as [\n {\n pointToken: `0x${string}`;\n receiver: `0x${string}`;\n amount: bigint;\n deadline: bigint;\n minterSig: Hex;\n receiverSig: Hex;\n extData: Hex;\n },\n {\n path: ReadonlyArray<{\n intermediateCurrency: `0x${string}`;\n fee: number;\n tickSpacing: number;\n hooks: `0x${string}`;\n hookData: Hex;\n }>;\n deadline: bigint;\n },\n ];\n\n const mint: MintParams = {\n pointToken: rawMint.pointToken,\n receiver: rawMint.receiver,\n amount: rawMint.amount,\n deadline: rawMint.deadline,\n minterSig: rawMint.minterSig,\n receiverSig: rawMint.receiverSig,\n extData: rawMint.extData,\n };\n\n const swap: SwapParams = {\n path: rawSwap.path.map(\n (hop): PathKey => ({\n intermediateCurrency: hop.intermediateCurrency,\n fee: hop.fee,\n tickSpacing: hop.tickSpacing,\n hooks: hop.hooks,\n hookData: hop.hookData,\n }),\n ),\n deadline: rawSwap.deadline,\n };\n\n return { mint, swap };\n}\n","import type { Address, PublicClient } from \"viem\";\nimport { relayAbi } from \"../abi/relay\";\nimport type { MintParams, SwapParams } from \"../types\";\nimport { SimulationError } from \"../errors\";\n\nexport interface SimulationResult {\n success: boolean;\n gasEstimate: bigint;\n}\n\n/**\n * Simulate a Relay.mintAndSwap call via eth_call (no gas spent).\n *\n * Runs the full flow — signature verification, minting, swap via PoolManager,\n * fee split — without submitting a transaction. If the simulation reverts,\n * throws a `SimulationError` with the revert reason.\n *\n * Call this AFTER both signatures are collected but BEFORE submitting the tx.\n *\n * @param client - viem PublicClient\n * @param relayAddress - Relay contract address\n * @param mint - MintParams (with real minterSig + receiverSig)\n * @param swap - SwapParams (path + deadline)\n * @param from - Address that will call mintAndSwap (the relayer)\n */\nexport async function simulateMintAndSwap(\n client: PublicClient,\n relayAddress: Address,\n mint: MintParams,\n swap: SwapParams,\n from: Address,\n): Promise<SimulationResult> {\n try {\n const gasEstimate = await client.estimateContractGas({\n address: relayAddress,\n abi: relayAbi,\n functionName: \"mintAndSwap\",\n args: [mint, swap],\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(\"mintAndSwap\", message);\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/relay/calldata.ts","../src/relay/simulate.ts"],"sourcesContent":["import {\n decodeFunctionData,\n encodeFunctionData,\n encodeAbiParameters,\n decodeAbiParameters,\n} from \"viem\";\nimport type { Hex } from \"viem\";\nimport { relayAbi } from \"../abi/relay\";\nimport type { MintParams, PathKey, SwapParams } from \"../types\";\n\n/**\n * Encode extData for ReceiverConsent and MintParams.\n * extData = abi.encode(uint256 minAmountOut, uint256 feeInUsdt)\n */\nexport function encodeExtData(minAmountOut: bigint, feeInUsdt: bigint): Hex {\n return encodeAbiParameters(\n [{ type: \"uint256\" }, { type: \"uint256\" }],\n [minAmountOut, feeInUsdt],\n );\n}\n\n/**\n * Decode extData back to { minAmountOut, feeInUsdt }.\n */\nexport function decodeExtData(extData: Hex): {\n minAmountOut: bigint;\n feeInUsdt: bigint;\n} {\n const [minAmountOut, feeInUsdt] = decodeAbiParameters(\n [{ type: \"uint256\" }, { type: \"uint256\" }],\n extData,\n );\n return { minAmountOut, feeInUsdt };\n}\n\n/**\n * Build SwapParams and extData from a quote result for Relay.mintAndSwap.\n *\n * @param quote - Quote result containing the path\n * @param minAmountOut - Minimum acceptable USDT output (caller applies slippage)\n * @param feeInUsdt - Fixed USDT fee for the relayer\n * @param deadline - Swap deadline (unix timestamp)\n */\nexport function buildRelaySwapParams(params: {\n quote: { path: PathKey[] };\n minAmountOut: bigint;\n feeInUsdt: bigint;\n deadline: bigint;\n}): { swapParams: SwapParams; extData: Hex } {\n return {\n swapParams: {\n path: params.quote.path,\n deadline: params.deadline,\n },\n extData: encodeExtData(params.minAmountOut, params.feeInUsdt),\n };\n}\n\nexport function encodeMintAndSwap(mint: MintParams, swap: SwapParams): Hex {\n return encodeFunctionData({\n abi: relayAbi,\n functionName: \"mintAndSwap\",\n args: [mint, swap],\n });\n}\n\nexport function decodeMintAndSwap(calldata: Hex): {\n mint: MintParams;\n swap: SwapParams;\n} {\n const { args } = decodeFunctionData({\n abi: relayAbi,\n data: calldata,\n });\n\n const [rawMint, rawSwap] = args as [\n {\n pointToken: `0x${string}`;\n receiver: `0x${string}`;\n amount: bigint;\n deadline: bigint;\n minterSig: Hex;\n receiverSig: Hex;\n extData: Hex;\n },\n {\n path: ReadonlyArray<{\n intermediateCurrency: `0x${string}`;\n fee: number;\n tickSpacing: number;\n hooks: `0x${string}`;\n hookData: Hex;\n }>;\n deadline: bigint;\n },\n ];\n\n const mint: MintParams = {\n pointToken: rawMint.pointToken,\n receiver: rawMint.receiver,\n amount: rawMint.amount,\n deadline: rawMint.deadline,\n minterSig: rawMint.minterSig,\n receiverSig: rawMint.receiverSig,\n extData: rawMint.extData,\n };\n\n const swap: SwapParams = {\n path: rawSwap.path.map(\n (hop): PathKey => ({\n intermediateCurrency: hop.intermediateCurrency,\n fee: hop.fee,\n tickSpacing: hop.tickSpacing,\n hooks: hop.hooks,\n hookData: hop.hookData,\n }),\n ),\n deadline: rawSwap.deadline,\n };\n\n return { mint, swap };\n}\n","import type { Address, PublicClient } from \"viem\";\nimport { relayAbi } from \"../abi/relay\";\nimport type { MintParams, SwapParams } from \"../types\";\nimport { SimulationError } from \"../errors\";\n\nexport interface SimulationResult {\n success: boolean;\n gasEstimate: bigint;\n}\n\n/**\n * Simulate a Relay.mintAndSwap call via eth_call (no gas spent).\n *\n * Runs the full flow — signature verification, minting, swap via PoolManager,\n * fee split — without submitting a transaction. If the simulation reverts,\n * throws a `SimulationError` with the revert reason.\n *\n * Call this AFTER both signatures are collected but BEFORE submitting the tx.\n *\n * @param client - viem PublicClient\n * @param relayAddress - Relay contract address\n * @param mint - MintParams (with real minterSig + receiverSig)\n * @param swap - SwapParams (path + deadline)\n * @param from - Address that will call mintAndSwap (the relayer)\n */\nexport async function simulateMintAndSwap(\n client: PublicClient,\n relayAddress: Address,\n mint: MintParams,\n swap: SwapParams,\n from: Address,\n): Promise<SimulationResult> {\n try {\n const gasEstimate = await client.estimateContractGas({\n address: relayAddress,\n abi: relayAbi,\n functionName: \"mintAndSwap\",\n args: [mint, swap],\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(\"mintAndSwap\", message);\n }\n}\n"],"mappings":";;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASA,SAAS,cAAc,cAAsB,WAAwB;AAC1E,SAAO;AAAA,IACL,CAAC,EAAE,MAAM,UAAU,GAAG,EAAE,MAAM,UAAU,CAAC;AAAA,IACzC,CAAC,cAAc,SAAS;AAAA,EAC1B;AACF;AAKO,SAAS,cAAc,SAG5B;AACA,QAAM,CAAC,cAAc,SAAS,IAAI;AAAA,IAChC,CAAC,EAAE,MAAM,UAAU,GAAG,EAAE,MAAM,UAAU,CAAC;AAAA,IACzC;AAAA,EACF;AACA,SAAO,EAAE,cAAc,UAAU;AACnC;AAUO,SAAS,qBAAqB,QAKQ;AAC3C,SAAO;AAAA,IACL,YAAY;AAAA,MACV,MAAM,OAAO,MAAM;AAAA,MACnB,UAAU,OAAO;AAAA,IACnB;AAAA,IACA,SAAS,cAAc,OAAO,cAAc,OAAO,SAAS;AAAA,EAC9D;AACF;AAEO,SAAS,kBAAkB,MAAkB,MAAuB;AACzE,SAAO,mBAAmB;AAAA,IACxB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,IAAI;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,kBAAkB,UAGhC;AACA,QAAM,EAAE,KAAK,IAAI,mBAAmB;AAAA,IAClC,KAAK;AAAA,IACL,MAAM;AAAA,EACR,CAAC;AAED,QAAM,CAAC,SAAS,OAAO,IAAI;AAsB3B,QAAM,OAAmB;AAAA,IACvB,YAAY,QAAQ;AAAA,IACpB,UAAU,QAAQ;AAAA,IAClB,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA,IACrB,SAAS,QAAQ;AAAA,EACnB;AAEA,QAAM,OAAmB;AAAA,IACvB,MAAM,QAAQ,KAAK;AAAA,MACjB,CAAC,SAAkB;AAAA,QACjB,sBAAsB,IAAI;AAAA,QAC1B,KAAK,IAAI;AAAA,QACT,aAAa,IAAI;AAAA,QACjB,OAAO,IAAI;AAAA,QACX,UAAU,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,IACA,UAAU,QAAQ;AAAA,EACpB;AAEA,SAAO,EAAE,MAAM,KAAK;AACtB;;;AChGA,eAAsB,oBACpB,QACA,cACA,MACA,MACA,MAC2B;AAC3B,MAAI;AACF,UAAM,cAAc,MAAM,OAAO,oBAAoB;AAAA,MACnD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,MAAM,IAAI;AAAA,MACjB,SAAS;AAAA,IACX,CAAC;AAED,WAAO,EAAE,SAAS,MAAM,YAAY;AAAA,EACtC,SAAS,OAAgB;AACvB,UAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,UAAM,IAAI,gBAAgB,eAAe,OAAO;AAAA,EAClD;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/phitran/Pacific-Finance/pafi-backend/pafi-sdk/packages/core/dist/chunk-O7LQKCBT.cjs","../src/swap/approval.ts","../src/swap/universalRouter.ts","../src/swap/simulate.ts"],"names":[],"mappings":"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","file":"/Users/phitran/Pacific-Finance/pafi-backend/pafi-sdk/packages/core/dist/chunk-O7LQKCBT.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 */\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"]}
|