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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { Address, WalletClient, PublicClient, Hex } from 'viem';
2
- import { P as PoolKey, C as ChainConfig, a as PafiSDKConfig, b as PointTokenDomainConfig, M as MintRequest, R as ReceiverConsent, E as EIP712Signature, S as SignatureVerification, c as MintParams, d as SwapParams, B as BestQuote, Q as QuoteResult, e as PathKey } from './types-CkRJzrZr.cjs';
3
- export { I as Issuer } from './types-CkRJzrZr.cjs';
1
+ import { Address, Hex, PublicClient, WalletClient } from 'viem';
2
+ import { P as PoolKey, C as ChainConfig, a as PointTokenDomainConfig, E as EIP712Signature, S as SignatureVerification, b as PafiSDKConfig, M as MintRequest, R as ReceiverConsent, c as MintParams, d as SwapParams, B as BestQuote, Q as QuoteResult, e as PathKey } from './types-BDOnH5Le.cjs';
3
+ export { I as Issuer } from './types-BDOnH5Le.cjs';
4
4
  export { erc20Abi, issuerRegistryAbi, mintingOracleAbi, permit2Abi, pointTokenAbi, pointTokenFactoryAbi, relayAbi, universalRouterAbi, v4QuoterAbi } from './abi/index.cjs';
5
5
  export { buildDomain, buildMintRequestTypedData, buildReceiverConsentTypedData, signMintRequest, signReceiverConsent, verifyMintRequest, verifyReceiverConsent } from './eip712/index.cjs';
6
6
  import { SimulationResult } from './relay/index.cjs';
@@ -74,6 +74,744 @@ declare class ApiError extends PafiSDKError {
74
74
  constructor(message: string, status?: number | undefined);
75
75
  }
76
76
 
77
+ /**
78
+ * ERC-4337 v0.7 EntryPoint standard address (deployed deterministically
79
+ * at the same address across chains).
80
+ * https://eips.ethereum.org/EIPS/eip-4337
81
+ */
82
+ declare const ENTRY_POINT_V07: Address;
83
+ /**
84
+ * A single call inside a batch. `BatchExecutor.execute(Call[])` iterates
85
+ * and invokes each one. When the batch runs via EIP-7702 delegation,
86
+ * `msg.sender` for each call is the user's EOA.
87
+ */
88
+ interface Operation {
89
+ target: Address;
90
+ value: bigint;
91
+ data: Hex;
92
+ }
93
+ /**
94
+ * Paymaster fields attached to a UserOperation. Populated by the
95
+ * Coinbase Paymaster (via PAFI Backend proxy) before the user signs.
96
+ */
97
+ interface PaymasterFields {
98
+ paymaster: Address;
99
+ paymasterData: Hex;
100
+ paymasterVerificationGasLimit: bigint;
101
+ paymasterPostOpGasLimit: bigint;
102
+ }
103
+ /**
104
+ * Partial UserOp used during preparation — before paymaster fields are
105
+ * attached or the user signs.
106
+ */
107
+ interface PartialUserOperation {
108
+ sender: Address;
109
+ nonce: bigint;
110
+ callData: Hex;
111
+ callGasLimit: bigint;
112
+ verificationGasLimit: bigint;
113
+ preVerificationGas: bigint;
114
+ maxFeePerGas: bigint;
115
+ maxPriorityFeePerGas: bigint;
116
+ }
117
+ /**
118
+ * Full ERC-4337 v0.7 UserOperation, ready for bundler submission.
119
+ */
120
+ interface UserOperation extends PartialUserOperation {
121
+ paymaster: Address;
122
+ paymasterData: Hex;
123
+ paymasterVerificationGasLimit: bigint;
124
+ paymasterPostOpGasLimit: bigint;
125
+ signature: Hex;
126
+ }
127
+ /**
128
+ * Receipt returned by a bundler after a UserOp lands on-chain.
129
+ */
130
+ interface UserOpReceipt {
131
+ userOpHash: Hex;
132
+ success: boolean;
133
+ txHash: Hex;
134
+ blockNumber: bigint;
135
+ gasUsed: bigint;
136
+ /** Effective gas cost paid (wei). */
137
+ actualGasCost: bigint;
138
+ }
139
+ /**
140
+ * Sentinel operation value used in tests + docs when `Operation.value`
141
+ * is irrelevant (ERC-20 transfers, for example).
142
+ */
143
+ declare const ZERO_VALUE = 0n;
144
+
145
+ /**
146
+ * Build an ERC-20 `transfer(to, amount)` operation. Used inside a batch
147
+ * to move fee tokens from the user to the fee recipient atomically with
148
+ * the main action.
149
+ */
150
+ declare function erc20TransferOp(token: Address, to: Address, amount: bigint): Operation;
151
+ /**
152
+ * Build an ERC-20 `approve(spender, amount)` operation. Used inside a
153
+ * batch before a swap / deposit call so the AMM / protocol can pull
154
+ * tokens from the user.
155
+ */
156
+ declare function erc20ApproveOp(token: Address, spender: Address, amount: bigint): Operation;
157
+ /**
158
+ * Build an ERC-20 `burn(amount)` operation (OpenZeppelin ERC20Burnable
159
+ * extension). Burns from `msg.sender`, which — via EIP-7702 — is the
160
+ * user's EOA.
161
+ *
162
+ * Requires the PointToken contract to expose a public `burn(uint256)`
163
+ * without a role check. See
164
+ * [SDK_V1.4_TASKS.md §11 — PointToken.burn callable via batch].
165
+ */
166
+ declare function erc20BurnOp(token: Address, amount: bigint): Operation;
167
+ /**
168
+ * Build a raw call operation with caller-supplied calldata. Useful for
169
+ * non-ERC-20 contracts (PoolManager.swap, PerpDEX.deposit, Relayer.mint)
170
+ * where the encoding is specific to that protocol.
171
+ */
172
+ declare function rawCallOp(target: Address, data: `0x${string}`, value?: bigint): Operation;
173
+
174
+ /**
175
+ * Standard BatchExecutor ABI — a contract that takes an array of calls
176
+ * and invokes each one in sequence, reverting all if any fail.
177
+ *
178
+ * Compatible with OpenZeppelin `Account.execute(Call[])`, Biconomy
179
+ * `executeBatch`, Safe `MultiSend`, and most EIP-7702 delegation
180
+ * targets. The exact deployed address is supplied by the infra team
181
+ * (see [V1.4_V1.5_READINESS.md B2]).
182
+ */
183
+ declare const BATCH_EXECUTOR_ABI: readonly [{
184
+ readonly name: "execute";
185
+ readonly type: "function";
186
+ readonly stateMutability: "nonpayable";
187
+ readonly inputs: readonly [{
188
+ readonly type: "tuple[]";
189
+ readonly components: readonly [{
190
+ readonly type: "address";
191
+ readonly name: "target";
192
+ }, {
193
+ readonly type: "uint256";
194
+ readonly name: "value";
195
+ }, {
196
+ readonly type: "bytes";
197
+ readonly name: "data";
198
+ }];
199
+ readonly name: "calls";
200
+ }];
201
+ readonly outputs: readonly [];
202
+ }];
203
+ /**
204
+ * Encode a batch of operations into calldata for `BatchExecutor.execute()`.
205
+ * The resulting calldata goes into `UserOperation.callData`.
206
+ *
207
+ * When the EOA has an EIP-7702 delegation to a BatchExecutor, calling
208
+ * this calldata against the EOA runs all operations with
209
+ * `msg.sender = EOA` for each inner call.
210
+ *
211
+ * @param operations batch of calls, in execution order
212
+ * @returns calldata bytes for `execute((address,uint256,bytes)[])`
213
+ */
214
+ declare function encodeBatchExecute(operations: Operation[]): Hex;
215
+
216
+ interface BuildPartialUserOpParams {
217
+ /** User's EOA (with EIP-7702 delegation). */
218
+ sender: Address;
219
+ /** Batch of operations — encoded into callData via `encodeBatchExecute`. */
220
+ operations: Operation[];
221
+ /** EntryPoint nonce for this sender. Caller fetches from the EntryPoint contract. */
222
+ nonce: bigint;
223
+ /** Optional gas overrides; bundler re-estimates before submission. */
224
+ gasLimits?: {
225
+ callGasLimit?: bigint;
226
+ verificationGasLimit?: bigint;
227
+ preVerificationGas?: bigint;
228
+ };
229
+ /** Optional fee overrides; bundler usually fills these. */
230
+ feeOverrides?: {
231
+ maxFeePerGas?: bigint;
232
+ maxPriorityFeePerGas?: bigint;
233
+ };
234
+ }
235
+ /**
236
+ * Build a partial ERC-4337 UserOperation from a batch of operations.
237
+ * Paymaster fields and signature are populated later:
238
+ * 1. Call `PafiBackendClient.requestSponsorship()` → get paymaster fields
239
+ * 2. Compute userOpHash and have the user sign it (via Privy)
240
+ * 3. Attach `signature` → submit to bundler
241
+ *
242
+ * This function is a pure struct builder — no network calls.
243
+ */
244
+ declare function buildPartialUserOperation(params: BuildPartialUserOpParams): PartialUserOperation;
245
+ /**
246
+ * Assemble a full UserOperation once paymaster fields + signature are
247
+ * known. Used after `PafiBackendClient.requestSponsorship()` and user
248
+ * signing complete.
249
+ */
250
+ declare function assembleUserOperation(partial: PartialUserOperation, paymaster: {
251
+ paymaster: Address;
252
+ paymasterData: `0x${string}`;
253
+ paymasterVerificationGasLimit: bigint;
254
+ paymasterPostOpGasLimit: bigint;
255
+ }, signature: `0x${string}`): UserOperation;
256
+
257
+ /**
258
+ * Module-level paymaster config shared by all batch builders and the
259
+ * `@pafi/issuer` RelayService. Holds the fee recipient address and the
260
+ * PAFI-assigned issuer identity.
261
+ *
262
+ * v1.4 update: the paymaster endpoint is **PAFI Backend**, which proxies
263
+ * to Coinbase Paymaster. See [SPONSORED_PATH_FLOW.md].
264
+ */
265
+ interface PaymasterConfig {
266
+ /**
267
+ * PAFI Backend API base URL. Example:
268
+ * https://api.pacificfinance.org/paymaster
269
+ */
270
+ pafiBackendUrl: string;
271
+ /** PAFI-assigned issuer ID. Passed in X-Issuer-Id header. */
272
+ issuerId: string;
273
+ /** Per-issuer API key (or JWT) for Authorization header. */
274
+ apiKey: string;
275
+ /**
276
+ * Where the fee transfer lands inside the batch call. Fee recovery is
277
+ * application-level — Paymaster sponsors gas, fee is a separate
278
+ * ERC-20 transfer inside the batch that reimburses the issuer.
279
+ */
280
+ feeRecipient: Address;
281
+ /** EIP-4337 EntryPoint address. Default: v0.7 (same across chains). */
282
+ entryPoint?: Address;
283
+ /** Chain ID the paymaster sponsors on. Defaults to consumer config. */
284
+ chainId?: number;
285
+ }
286
+ /**
287
+ * Which PAFI-defined scenario this UserOp represents. PAFI Backend
288
+ * validates the request's target contracts + function selectors
289
+ * match the expected pattern for the scenario.
290
+ */
291
+ type SponsorshipScenario = "mint" | "burn" | "swap" | "perp-deposit";
292
+
293
+ /**
294
+ * Set the application-wide paymaster config. Safe to call multiple
295
+ * times (later calls override earlier). Throws if required fields
296
+ * are missing.
297
+ */
298
+ declare function setPaymasterConfig(config: PaymasterConfig): void;
299
+ /**
300
+ * Get the current paymaster config. Throws if `setPaymasterConfig()`
301
+ * has not been called yet — this surfaces boot-order bugs early
302
+ * instead of failing with "paymaster.feeRecipient is undefined" at
303
+ * the point of use.
304
+ */
305
+ declare function getPaymasterConfig(): PaymasterConfig;
306
+ /** Test helper — clear the singleton. */
307
+ declare function _resetPaymasterConfigForTests(): void;
308
+ /** Check whether paymaster config has been initialized. */
309
+ declare function isPaymasterConfigured(): boolean;
310
+
311
+ /**
312
+ * Submission path chosen by `checkEthAndBranch`.
313
+ * - `normal`: initiator has enough ETH; submit via `walletClient.writeContract`
314
+ * or a plain `eth_sendRawTransaction`. No paymaster round-trip.
315
+ * - `paymaster`: initiator doesn't have enough ETH; wrap the batch as a
316
+ * UserOperation and route through PAFI Backend → Coinbase Paymaster
317
+ * → Bundler.
318
+ */
319
+ type SubmissionPath = "normal" | "paymaster";
320
+ interface CheckEthAndBranchParams {
321
+ /** viem PublicClient bound to the target chain. */
322
+ client: PublicClient;
323
+ /** The address whose ETH balance we check. */
324
+ initiator: Address;
325
+ /** Estimated gas cost in wei for the upcoming tx. */
326
+ estimatedGasWei: bigint;
327
+ /**
328
+ * Optional safety margin multiplier (basis points). Defaults to
329
+ * 11_000 (110%) — the initiator needs 10% above the estimate to
330
+ * qualify for the normal path. Prevents edge cases where gas price
331
+ * spikes between estimation and submission cause a "has enough"
332
+ * decision to fail at broadcast time.
333
+ */
334
+ marginBps?: number;
335
+ }
336
+ /**
337
+ * Step 3 of the Generalized Flow ([SPONSORED_PATH_FLOW.md §2]):
338
+ * choose between the normal path (initiator pays ETH directly) and the
339
+ * paymaster path (bundler + Coinbase Paymaster).
340
+ *
341
+ * Intentionally synchronous in spirit — the only network call is
342
+ * `getBalance`. Callers can parallelize it with other reads.
343
+ */
344
+ declare function checkEthAndBranch(params: CheckEthAndBranchParams): Promise<SubmissionPath>;
345
+
346
+ /**
347
+ * ⚠️ MOCK — Relayer v2 `mint()` ABI for the v1.4 sponsored flow.
348
+ *
349
+ * Signature guess based on stakeholder memo (`REQUIREMENTS_V2.md §3`):
350
+ *
351
+ * mint(
352
+ * MintRequest request, // EIP-712 signed by user + issuer
353
+ * Signature userSig, // v, r, s
354
+ * Signature issuerSig, // v, r, s
355
+ * uint256 feeAmount, // PT units to split off to feeRecipient
356
+ * address feeRecipient // typically operator or fee collector
357
+ * )
358
+ *
359
+ * Behaviour expected:
360
+ * - Verify user + issuer EIP-712 signatures against `request`
361
+ * - Mint `request.amount` PT to `request.to`
362
+ * - Atomic transfer `feeAmount` from `request.to` → `feeRecipient`
363
+ * (net mint = `amount - feeAmount`)
364
+ * - Increment the on-chain nonce to prevent replay
365
+ *
366
+ * When SC team publishes the real ABI, drop it in under
367
+ * `src/contracts/real/relayerV2.abi.ts` and flip the export in
368
+ * `src/contracts/index.ts` — call sites unchanged.
369
+ *
370
+ * See [SC_MOCK_PLAN.md §2.1] for the rationale + swap checklist.
371
+ */
372
+ declare const MOCK_RELAYER_V2_ABI: readonly [{
373
+ readonly name: "mint";
374
+ readonly type: "function";
375
+ readonly stateMutability: "nonpayable";
376
+ readonly inputs: readonly [{
377
+ readonly type: "tuple";
378
+ readonly components: readonly [{
379
+ readonly type: "address";
380
+ readonly name: "to";
381
+ }, {
382
+ readonly type: "uint256";
383
+ readonly name: "amount";
384
+ }, {
385
+ readonly type: "uint256";
386
+ readonly name: "feeAmount";
387
+ }, {
388
+ readonly type: "address";
389
+ readonly name: "feeRecipient";
390
+ }, {
391
+ readonly type: "uint256";
392
+ readonly name: "nonce";
393
+ }, {
394
+ readonly type: "uint256";
395
+ readonly name: "deadline";
396
+ }, {
397
+ readonly type: "bytes";
398
+ readonly name: "extData";
399
+ }];
400
+ readonly name: "request";
401
+ }, {
402
+ readonly type: "tuple";
403
+ readonly components: readonly [{
404
+ readonly type: "uint8";
405
+ readonly name: "v";
406
+ }, {
407
+ readonly type: "bytes32";
408
+ readonly name: "r";
409
+ }, {
410
+ readonly type: "bytes32";
411
+ readonly name: "s";
412
+ }];
413
+ readonly name: "userSig";
414
+ }, {
415
+ readonly type: "tuple";
416
+ readonly components: readonly [{
417
+ readonly type: "uint8";
418
+ readonly name: "v";
419
+ }, {
420
+ readonly type: "bytes32";
421
+ readonly name: "r";
422
+ }, {
423
+ readonly type: "bytes32";
424
+ readonly name: "s";
425
+ }];
426
+ readonly name: "issuerSig";
427
+ }];
428
+ readonly outputs: readonly [];
429
+ }, {
430
+ readonly name: "mintRequestNonce";
431
+ readonly type: "function";
432
+ readonly stateMutability: "view";
433
+ readonly inputs: readonly [{
434
+ readonly type: "address";
435
+ readonly name: "user";
436
+ }];
437
+ readonly outputs: readonly [{
438
+ readonly type: "uint256";
439
+ }];
440
+ }, {
441
+ readonly name: "Minted";
442
+ readonly type: "event";
443
+ readonly inputs: readonly [{
444
+ readonly type: "address";
445
+ readonly name: "user";
446
+ readonly indexed: true;
447
+ }, {
448
+ readonly type: "uint256";
449
+ readonly name: "amount";
450
+ }, {
451
+ readonly type: "uint256";
452
+ readonly name: "feeAmount";
453
+ }, {
454
+ readonly type: "address";
455
+ readonly name: "feeRecipient";
456
+ readonly indexed: true;
457
+ }, {
458
+ readonly type: "bytes32";
459
+ readonly name: "requestHash";
460
+ }];
461
+ }];
462
+ /**
463
+ * Calldata function selector for `mint((...),(...),(...))` as encoded
464
+ * by viem against {@link MOCK_RELAYER_V2_ABI}. Callers compare against
465
+ * this to sanity-check decoded UserOp inner calls.
466
+ *
467
+ * Recompute when the real ABI lands — almost certainly differs.
468
+ */
469
+ declare const MOCK_RELAYER_V2_MINT_SELECTOR: "0xMOCKED__";
470
+ /**
471
+ * Struct shape that matches {@link MOCK_RELAYER_V2_ABI}. Exported so
472
+ * builders can accept a typed input without `as const` gymnastics.
473
+ */
474
+ interface MockMintRequestV2 {
475
+ to: Address;
476
+ amount: bigint;
477
+ feeAmount: bigint;
478
+ feeRecipient: Address;
479
+ nonce: bigint;
480
+ deadline: bigint;
481
+ extData: `0x${string}`;
482
+ }
483
+ interface MockSignatureStruct {
484
+ v: number;
485
+ r: `0x${string}`;
486
+ s: `0x${string}`;
487
+ }
488
+
489
+ /**
490
+ * ⚠️ MOCK — `PointToken` v1.4 burn surface.
491
+ *
492
+ * Two variants mocked — SC team will pick ONE before stable; the other
493
+ * gets deleted during Phase B swap.
494
+ *
495
+ * Variant A (simpler, most likely):
496
+ * burn(uint256 amount)
497
+ * - burns from `msg.sender`
498
+ * - caller handles authorization (the user is `msg.sender` via
499
+ * EIP-7702 delegation, so `msg.sender == user`)
500
+ *
501
+ * Variant B (signature-based, if SC prefers explicit consent on-chain):
502
+ * burnWithSig(BurnConsent consent, Signature sig)
503
+ * - verifies EIP-712 signature before burning
504
+ * - used when the caller isn't the user (e.g. a relayer burns on
505
+ * behalf of the user)
506
+ *
507
+ * Either way the ERC-20 emits `Transfer(from, address(0), amount)` so
508
+ * `BurnIndexer` semantics don't change.
509
+ */
510
+ declare const MOCK_POINT_TOKEN_V2_ABI: readonly [{
511
+ readonly name: "burn";
512
+ readonly type: "function";
513
+ readonly stateMutability: "nonpayable";
514
+ readonly inputs: readonly [{
515
+ readonly type: "uint256";
516
+ readonly name: "amount";
517
+ }];
518
+ readonly outputs: readonly [];
519
+ }, {
520
+ readonly name: "burnWithSig";
521
+ readonly type: "function";
522
+ readonly stateMutability: "nonpayable";
523
+ readonly inputs: readonly [{
524
+ readonly type: "tuple";
525
+ readonly components: readonly [{
526
+ readonly type: "address";
527
+ readonly name: "user";
528
+ }, {
529
+ readonly type: "address";
530
+ readonly name: "pointToken";
531
+ }, {
532
+ readonly type: "uint256";
533
+ readonly name: "amount";
534
+ }, {
535
+ readonly type: "uint256";
536
+ readonly name: "nonce";
537
+ }, {
538
+ readonly type: "uint256";
539
+ readonly name: "deadline";
540
+ }];
541
+ readonly name: "consent";
542
+ }, {
543
+ readonly type: "tuple";
544
+ readonly components: readonly [{
545
+ readonly type: "uint8";
546
+ readonly name: "v";
547
+ }, {
548
+ readonly type: "bytes32";
549
+ readonly name: "r";
550
+ }, {
551
+ readonly type: "bytes32";
552
+ readonly name: "s";
553
+ }];
554
+ readonly name: "sig";
555
+ }];
556
+ readonly outputs: readonly [];
557
+ }, {
558
+ readonly name: "balanceOf";
559
+ readonly type: "function";
560
+ readonly stateMutability: "view";
561
+ readonly inputs: readonly [{
562
+ readonly type: "address";
563
+ readonly name: "user";
564
+ }];
565
+ readonly outputs: readonly [{
566
+ readonly type: "uint256";
567
+ }];
568
+ }, {
569
+ readonly name: "burnNonce";
570
+ readonly type: "function";
571
+ readonly stateMutability: "view";
572
+ readonly inputs: readonly [{
573
+ readonly type: "address";
574
+ readonly name: "user";
575
+ }];
576
+ readonly outputs: readonly [{
577
+ readonly type: "uint256";
578
+ }];
579
+ }, {
580
+ readonly name: "Transfer";
581
+ readonly type: "event";
582
+ readonly inputs: readonly [{
583
+ readonly type: "address";
584
+ readonly name: "from";
585
+ readonly indexed: true;
586
+ }, {
587
+ readonly type: "address";
588
+ readonly name: "to";
589
+ readonly indexed: true;
590
+ }, {
591
+ readonly type: "uint256";
592
+ readonly name: "value";
593
+ }];
594
+ }];
595
+
596
+ /**
597
+ * ⚠️ MOCK — placeholder BatchExecutor address.
598
+ *
599
+ * Real deployment:
600
+ * - Coinbase may pre-deploy a canonical BatchExecutor that we target
601
+ * via EIP-7702 delegation (see blocker B2 in V1.4_V1.5_READINESS.md)
602
+ * - Otherwise PAFI deploys a minimal one and publishes the address
603
+ *
604
+ * The ABI itself (`execute(Call[])`) is stable and lives under
605
+ * `../../userop/batchExecute.ts` — that's the real one, unchanged
606
+ * by the mock swap. Only the **address** is mocked here.
607
+ *
608
+ * Pattern: checksum address with hex "DEAD0001" suffix per chain so
609
+ * it's obvious in logs which chain is using a mock.
610
+ */
611
+ declare const MOCK_BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA: Address;
612
+ declare const MOCK_BATCH_EXECUTOR_ADDRESS_BASE_MAINNET: Address;
613
+
614
+ /**
615
+ * ⚠️ MOCK — per-chain contract addresses for the v1.4 sponsored flow.
616
+ *
617
+ * Real addresses come from SC team once they deploy Relayer v2 and
618
+ * pick a BatchExecutor. Until then we use placeholders so the SDK
619
+ * code path compiles + tests execute end-to-end.
620
+ *
621
+ * **Intentionally not merge-safe to mainnet** — callers that resolve
622
+ * a mainnet address here get a `0x...DEAD` placeholder which will
623
+ * revert at contract-level. That's the point: prod refuses to run
624
+ * on mocks.
625
+ *
626
+ * Chain id map:
627
+ * - 8453 Base mainnet
628
+ * - 84532 Base Sepolia
629
+ *
630
+ * Swap workflow when SC delivers:
631
+ * 1. Rename this file → `addresses.ts` under `src/contracts/real/`
632
+ * 2. Fill real addresses per chain
633
+ * 3. Update `src/contracts/index.ts` re-export
634
+ * 4. Delete MOCK_* named exports
635
+ */
636
+ interface ContractAddresses {
637
+ relayerV2: Address;
638
+ pointToken: Address;
639
+ batchExecutor: Address;
640
+ usdt: Address;
641
+ issuerRegistry: Address;
642
+ mintingOracle: Address;
643
+ }
644
+ declare const MOCK_ADDRESSES: Record<number, ContractAddresses>;
645
+ /**
646
+ * Lookup helper — throws if the chain isn't in the map so callers fail
647
+ * loudly on misconfiguration instead of silently using `undefined`.
648
+ */
649
+ declare function getMockAddresses(chainId: number): ContractAddresses;
650
+
651
+ /**
652
+ * ⚠️ MOCK — `MintRequest` v2 EIP-712 types.
653
+ *
654
+ * Extends v0.2.x `MintRequest` (4 fields) with three new fields needed
655
+ * for the v1.4 sponsored flow:
656
+ *
657
+ * + feeAmount PT units taken from the mint for the operator
658
+ * + feeRecipient where the fee goes (operator or treasury)
659
+ * + extData arbitrary bytes for future extensions (swap path, etc.)
660
+ *
661
+ * When SC team confirms the real struct, drop this file's content into
662
+ * the real builder and remove the MOCK_ prefix. The function signatures
663
+ * below stay stable — only `MOCK_MINT_REQUEST_V2_TYPES` changes.
664
+ */
665
+ declare const MOCK_MINT_REQUEST_V2_TYPES: {
666
+ readonly MintRequest: readonly [{
667
+ readonly name: "to";
668
+ readonly type: "address";
669
+ }, {
670
+ readonly name: "amount";
671
+ readonly type: "uint256";
672
+ }, {
673
+ readonly name: "feeAmount";
674
+ readonly type: "uint256";
675
+ }, {
676
+ readonly name: "feeRecipient";
677
+ readonly type: "address";
678
+ }, {
679
+ readonly name: "nonce";
680
+ readonly type: "uint256";
681
+ }, {
682
+ readonly name: "deadline";
683
+ readonly type: "uint256";
684
+ }, {
685
+ readonly name: "extData";
686
+ readonly type: "bytes";
687
+ }];
688
+ };
689
+ /**
690
+ * Build the typed-data envelope that any EIP-712 signer (viem, ethers,
691
+ * Privy) can consume. Callers typically pass the result to
692
+ * `walletClient.signTypedData()` or `privy.signTypedData()`.
693
+ */
694
+ declare function buildMockMintRequestV2TypedData(domain: PointTokenDomainConfig, message: MockMintRequestV2): {
695
+ domain: {
696
+ name: string;
697
+ version: "1";
698
+ chainId: number;
699
+ verifyingContract: `0x${string}`;
700
+ };
701
+ types: {
702
+ readonly MintRequest: readonly [{
703
+ readonly name: "to";
704
+ readonly type: "address";
705
+ }, {
706
+ readonly name: "amount";
707
+ readonly type: "uint256";
708
+ }, {
709
+ readonly name: "feeAmount";
710
+ readonly type: "uint256";
711
+ }, {
712
+ readonly name: "feeRecipient";
713
+ readonly type: "address";
714
+ }, {
715
+ readonly name: "nonce";
716
+ readonly type: "uint256";
717
+ }, {
718
+ readonly name: "deadline";
719
+ readonly type: "uint256";
720
+ }, {
721
+ readonly name: "extData";
722
+ readonly type: "bytes";
723
+ }];
724
+ };
725
+ primaryType: "MintRequest";
726
+ message: MockMintRequestV2;
727
+ };
728
+ /**
729
+ * Sign a `MintRequest` v2 with a viem WalletClient — server-side flow
730
+ * where the issuer holds the private key directly (KMS-backed signer
731
+ * is the production path; see `@pafi-dev/issuer` KMSSignerAdapter).
732
+ */
733
+ declare function signMockMintRequestV2(walletClient: WalletClient, domain: PointTokenDomainConfig, message: MockMintRequestV2): Promise<EIP712Signature>;
734
+ /**
735
+ * Verify a `MintRequest` v2 signature and check it came from the
736
+ * expected signer (either user or issuer depending on which side is
737
+ * being verified).
738
+ */
739
+ declare function verifyMockMintRequestV2(domain: PointTokenDomainConfig, message: MockMintRequestV2, signature: Hex, expectedSigner: Address): Promise<SignatureVerification>;
740
+
741
+ /**
742
+ * ⚠️ MOCK — `BurnConsent` EIP-712 type for the v1.4 reverse flow.
743
+ *
744
+ * New type entirely — v0.2.x had no burn-for-credit flow.
745
+ *
746
+ * User signs `BurnConsent` to authorize burning `amount` PT from their
747
+ * wallet in exchange for an off-chain credit of (amount - gasFee).
748
+ * Signature is consumed either by:
749
+ * - A relayer calling `PointToken.burnWithSig(...)` (Variant B)
750
+ * - The paymaster-proxy-sponsored UserOp calling `PointToken.burn(...)`
751
+ * with msg.sender = user via EIP-7702 (Variant A)
752
+ *
753
+ * Either way the tx emits `Transfer(user → 0x0)` which the issuer's
754
+ * `BurnIndexer` watches for and uses to credit the off-chain ledger.
755
+ *
756
+ * Field list is a best-guess — SC team may add fields (e.g. `feeAmount`
757
+ * explicit, `extData`). Update this mock when they freeze the spec.
758
+ */
759
+ interface MockBurnConsent {
760
+ user: Address;
761
+ pointToken: Address;
762
+ amount: bigint;
763
+ nonce: bigint;
764
+ deadline: bigint;
765
+ }
766
+ declare const MOCK_BURN_CONSENT_TYPES: {
767
+ readonly BurnConsent: readonly [{
768
+ readonly name: "user";
769
+ readonly type: "address";
770
+ }, {
771
+ readonly name: "pointToken";
772
+ readonly type: "address";
773
+ }, {
774
+ readonly name: "amount";
775
+ readonly type: "uint256";
776
+ }, {
777
+ readonly name: "nonce";
778
+ readonly type: "uint256";
779
+ }, {
780
+ readonly name: "deadline";
781
+ readonly type: "uint256";
782
+ }];
783
+ };
784
+ declare function buildMockBurnConsentTypedData(domain: PointTokenDomainConfig, message: MockBurnConsent): {
785
+ domain: {
786
+ name: string;
787
+ version: "1";
788
+ chainId: number;
789
+ verifyingContract: `0x${string}`;
790
+ };
791
+ types: {
792
+ readonly BurnConsent: readonly [{
793
+ readonly name: "user";
794
+ readonly type: "address";
795
+ }, {
796
+ readonly name: "pointToken";
797
+ readonly type: "address";
798
+ }, {
799
+ readonly name: "amount";
800
+ readonly type: "uint256";
801
+ }, {
802
+ readonly name: "nonce";
803
+ readonly type: "uint256";
804
+ }, {
805
+ readonly name: "deadline";
806
+ readonly type: "uint256";
807
+ }];
808
+ };
809
+ primaryType: "BurnConsent";
810
+ message: MockBurnConsent;
811
+ };
812
+ declare function signMockBurnConsent(walletClient: WalletClient, domain: PointTokenDomainConfig, message: MockBurnConsent): Promise<EIP712Signature>;
813
+ declare function verifyMockBurnConsent(domain: PointTokenDomainConfig, message: MockBurnConsent, signature: Hex, expectedUser: Address): Promise<SignatureVerification>;
814
+
77
815
  declare class PafiSDK {
78
816
  private _pointTokenAddress?;
79
817
  private _relayContractAddress?;
@@ -236,4 +974,4 @@ declare class PafiSDK {
236
974
  signLoginMessage(message: string): Promise<Hex>;
237
975
  }
238
976
 
239
- export { ApiError, BestQuote, COMMON_POOLS, COMMON_TOKENS, ChainConfig, ConfigurationError, EIP712Signature, LoginMessageParams, MintParams, MintRequest, POINT_TOKEN_POOLS, PafiSDK, PafiSDKConfig, PafiSDKError, PathKey, PointTokenDomainConfig, PoolKey, QuoteResult, ReceiverConsent, SUPPORTED_CHAINS, SignatureVerification, SigningError, SimulationError, SimulationResult, SwapParams, SwapSimulationResult, UNIVERSAL_ROUTER_ADDRESSES, V4_QUOTER_ADDRESSES, mintRequestTypes, receiverConsentTypes };
977
+ export { ApiError, BATCH_EXECUTOR_ABI, MOCK_BATCH_EXECUTOR_ADDRESS_BASE_MAINNET as BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, MOCK_BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA as BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, MOCK_BURN_CONSENT_TYPES as BURN_CONSENT_TYPES, BestQuote, type BuildPartialUserOpParams, type MockBurnConsent as BurnConsent, COMMON_POOLS, COMMON_TOKENS, MOCK_ADDRESSES as CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, EIP712Signature, ENTRY_POINT_V07, LoginMessageParams, MOCK_MINT_REQUEST_V2_TYPES as MINT_REQUEST_V2_TYPES, MintParams, MintRequest, type MockMintRequestV2 as MintRequestV2, type Operation, POINT_TOKEN_POOLS, MOCK_POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI, PafiSDK, PafiSDKConfig, PafiSDKError, type PartialUserOperation, PathKey, type PaymasterConfig, type PaymasterFields, PointTokenDomainConfig, PoolKey, QuoteResult, MOCK_RELAYER_V2_ABI as RELAYER_V2_ABI, MOCK_RELAYER_V2_MINT_SELECTOR as RELAYER_V2_MINT_SELECTOR, ReceiverConsent, SUPPORTED_CHAINS, type MockSignatureStruct as SignatureStruct, SignatureVerification, SigningError, SimulationError, SimulationResult, type SponsorshipScenario, type SubmissionPath, SwapParams, SwapSimulationResult, UNIVERSAL_ROUTER_ADDRESSES, type UserOpReceipt, type UserOperation, V4_QUOTER_ADDRESSES, ZERO_VALUE, _resetPaymasterConfigForTests, assembleUserOperation, buildMockBurnConsentTypedData as buildBurnConsentTypedData, buildMockMintRequestV2TypedData as buildMintRequestV2TypedData, buildPartialUserOperation, checkEthAndBranch, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getMockAddresses as getContractAddresses, getPaymasterConfig, isPaymasterConfigured, mintRequestTypes, rawCallOp, receiverConsentTypes, setPaymasterConfig, signMockBurnConsent as signBurnConsent, signMockMintRequestV2 as signMintRequestV2, verifyMockBurnConsent as verifyBurnConsent, verifyMockMintRequestV2 as verifyMintRequestV2 };