@pafi-dev/issuer 0.5.32 → 0.5.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +209 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +383 -113
- package/dist/index.d.ts +383 -113
- package/dist/index.js +200 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Address, Hex, PublicClient, WalletClient } from 'viem';
|
|
2
|
-
import { PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey } from '@pafi-dev/core';
|
|
2
|
+
import { PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData } from '@pafi-dev/core';
|
|
3
3
|
export { PAFI_SUBGRAPH_URL } from '@pafi-dev/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -32,6 +32,28 @@ interface LockedMintRequest {
|
|
|
32
32
|
expiresAt: number;
|
|
33
33
|
/** On-chain transaction hash, set once the mint is confirmed */
|
|
34
34
|
txHash?: Hex;
|
|
35
|
+
/**
|
|
36
|
+
* ERC-4337 userOpHash returned by the bundler at submit time. Bound
|
|
37
|
+
* to the lock by `bindMintUserOpHash` so status endpoints can poll
|
|
38
|
+
* the bundler receipt directly — bypasses `PointIndexer`'s
|
|
39
|
+
* amount-based matching, which races when several PENDING locks
|
|
40
|
+
* share the same amount.
|
|
41
|
+
*/
|
|
42
|
+
userOpHash?: Hex;
|
|
43
|
+
}
|
|
44
|
+
/** A pending off-chain credit (burn → credit reverse flow). */
|
|
45
|
+
interface PendingCredit {
|
|
46
|
+
lockId: string;
|
|
47
|
+
userAddress: Address;
|
|
48
|
+
amount: bigint;
|
|
49
|
+
tokenAddress?: Address;
|
|
50
|
+
status: "PENDING" | "RESOLVED" | "EXPIRED";
|
|
51
|
+
createdAt: number;
|
|
52
|
+
expiresAt: number;
|
|
53
|
+
txHash?: Hex;
|
|
54
|
+
resolvedAt?: number;
|
|
55
|
+
/** Bundler-returned userOpHash. See `LockedMintRequest.userOpHash`. */
|
|
56
|
+
userOpHash?: Hex;
|
|
35
57
|
}
|
|
36
58
|
/**
|
|
37
59
|
* Issuer point ledger interface — the source of truth for off-chain user
|
|
@@ -92,6 +114,29 @@ interface IPointLedger {
|
|
|
92
114
|
* Throws if the lockId is unknown or already resolved.
|
|
93
115
|
*/
|
|
94
116
|
resolveCreditByBurnTx?(lockId: string, txHash: Hex): Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* Persist the bundler-returned userOpHash for a mint lock at
|
|
119
|
+
* submit time. Called once per `/claim/submit` after the bundler
|
|
120
|
+
* accepts the UserOp.
|
|
121
|
+
*/
|
|
122
|
+
bindMintUserOpHash?(lockId: string, userOpHash: Hex): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Persist the bundler-returned userOpHash for a pending credit at
|
|
125
|
+
* `/redeem/submit` time.
|
|
126
|
+
*/
|
|
127
|
+
bindCreditUserOpHash?(lockId: string, userOpHash: Hex): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Look up a mint lock by id. Returns `null` if the lock doesn't
|
|
130
|
+
* exist or doesn't belong to the supplied user (when provided).
|
|
131
|
+
* Used by `handleClaimStatus` for status polling. OPTIONAL — when
|
|
132
|
+
* absent, callers must implement status endpoints themselves.
|
|
133
|
+
*/
|
|
134
|
+
getMintLock?(lockId: string, userAddress?: Address): Promise<LockedMintRequest | null>;
|
|
135
|
+
/**
|
|
136
|
+
* Look up a pending credit by id. Symmetric counterpart of
|
|
137
|
+
* `getMintLock` for the burn/redeem flow.
|
|
138
|
+
*/
|
|
139
|
+
getPendingCredit?(lockId: string, userAddress?: Address): Promise<PendingCredit | null>;
|
|
95
140
|
}
|
|
96
141
|
|
|
97
142
|
/**
|
|
@@ -1294,6 +1339,194 @@ declare class TopUpRedemptionHandler {
|
|
|
1294
1339
|
handle(request: TopUpRedemptionRequest): Promise<TopUpRedemptionResponse>;
|
|
1295
1340
|
}
|
|
1296
1341
|
|
|
1342
|
+
interface RetryConfig {
|
|
1343
|
+
maxAttempts?: number;
|
|
1344
|
+
initialDelayMs?: number;
|
|
1345
|
+
maxDelayMs?: number;
|
|
1346
|
+
maxRetryAfterMs?: number;
|
|
1347
|
+
}
|
|
1348
|
+
interface PafiBackendConfig {
|
|
1349
|
+
url: string;
|
|
1350
|
+
issuerId: string;
|
|
1351
|
+
apiKey: string;
|
|
1352
|
+
fetchImpl?: typeof fetch;
|
|
1353
|
+
timeoutMs?: number;
|
|
1354
|
+
retry?: RetryConfig;
|
|
1355
|
+
}
|
|
1356
|
+
type PafiBackendErrorCode = "MISSING_ISSUER_ID" | "MISSING_API_KEY" | "ISSUER_UNAUTHORIZED" | "USER_UNAUTHORIZED" | "INTENT_REJECTED" | "MINT_CAP_EXCEEDED" | "ISSUER_INACTIVE" | "BROKER_NOT_WHITELISTED" | "RATE_LIMIT_EXCEEDED" | "RATE_LIMIT_EXCEEDED_DAILY" | "RATE_LIMIT_EXCEEDED_PER_USER" | "ISSUER_BUDGET_EXCEEDED" | "RATE_LIMITER_UNAVAILABLE" | "PAYMASTER_UNAVAILABLE" | "TARGET_NOT_ALLOWLISTED" | "BAD_REQUEST" | "INTERNAL_ERROR" | "TIMEOUT" | "NETWORK_ERROR" | (string & {});
|
|
1357
|
+
declare class PafiBackendError extends Error {
|
|
1358
|
+
code: PafiBackendErrorCode;
|
|
1359
|
+
httpStatus: number;
|
|
1360
|
+
details?: unknown | undefined;
|
|
1361
|
+
readonly retryAfter?: number;
|
|
1362
|
+
private readonly serverSafeToRetry?;
|
|
1363
|
+
constructor(code: PafiBackendErrorCode, message: string, httpStatus: number, details?: unknown | undefined, opts?: {
|
|
1364
|
+
retryAfter?: number;
|
|
1365
|
+
safeToRetry?: boolean;
|
|
1366
|
+
});
|
|
1367
|
+
get safeToRetry(): boolean;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
interface RelayUserOpRequest {
|
|
1371
|
+
userOp: Record<string, string | null>;
|
|
1372
|
+
entryPoint: string;
|
|
1373
|
+
eip7702Auth?: {
|
|
1374
|
+
chainId: string;
|
|
1375
|
+
address: string;
|
|
1376
|
+
nonce: string;
|
|
1377
|
+
r: string;
|
|
1378
|
+
s: string;
|
|
1379
|
+
yParity: string;
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
interface RelayUserOpResponse {
|
|
1383
|
+
userOpHash: Hex;
|
|
1384
|
+
}
|
|
1385
|
+
interface SponsorshipUserOp {
|
|
1386
|
+
sender: Address;
|
|
1387
|
+
nonce: bigint;
|
|
1388
|
+
callData: Hex;
|
|
1389
|
+
callGasLimit: bigint;
|
|
1390
|
+
verificationGasLimit: bigint;
|
|
1391
|
+
preVerificationGas: bigint;
|
|
1392
|
+
maxFeePerGas: bigint;
|
|
1393
|
+
maxPriorityFeePerGas: bigint;
|
|
1394
|
+
}
|
|
1395
|
+
interface SponsorshipTarget {
|
|
1396
|
+
contract: Address;
|
|
1397
|
+
function: string;
|
|
1398
|
+
pointToken: Address;
|
|
1399
|
+
}
|
|
1400
|
+
interface SponsorshipRequest {
|
|
1401
|
+
chainId: number;
|
|
1402
|
+
scenario: string;
|
|
1403
|
+
userOp: SponsorshipUserOp;
|
|
1404
|
+
target: SponsorshipTarget;
|
|
1405
|
+
}
|
|
1406
|
+
interface SponsorshipResponse {
|
|
1407
|
+
paymaster: Address;
|
|
1408
|
+
paymasterData: Hex;
|
|
1409
|
+
paymasterVerificationGasLimit: bigint;
|
|
1410
|
+
paymasterPostOpGasLimit: bigint;
|
|
1411
|
+
/**
|
|
1412
|
+
* Pimlico's `pm_sponsorUserOperation` re-estimates these gas fields
|
|
1413
|
+
* and signs its paymaster signature over the new values. Callers
|
|
1414
|
+
* MUST overwrite the matching userOp fields with these BEFORE
|
|
1415
|
+
* computing the EIP-712 userOpHash and submitting to the bundler.
|
|
1416
|
+
* Otherwise both `AA34` (paymaster sig) and `AA24` (sender sig) will
|
|
1417
|
+
* fire — the EntryPoint hashes the actual on-chain field values, and
|
|
1418
|
+
* a mismatch invalidates every sig over the hash.
|
|
1419
|
+
*/
|
|
1420
|
+
callGasLimit?: bigint;
|
|
1421
|
+
verificationGasLimit?: bigint;
|
|
1422
|
+
preVerificationGas?: bigint;
|
|
1423
|
+
/**
|
|
1424
|
+
* Bundler-required gas price (Pimlico's `pimlico_getUserOperationGasPrice`
|
|
1425
|
+
* fast tier). Pimlico's paymaster signs over these — caller MUST apply
|
|
1426
|
+
* to the userOp before computing the EIP-712 userOpHash. Base RPC's
|
|
1427
|
+
* `eth_feeHistory` underestimates the bundler floor by 10-15 %, so
|
|
1428
|
+
* relying on it produces "maxFeePerGas must be at least ..." rejections.
|
|
1429
|
+
*/
|
|
1430
|
+
maxFeePerGas?: bigint;
|
|
1431
|
+
maxPriorityFeePerGas?: bigint;
|
|
1432
|
+
expiresAt: number;
|
|
1433
|
+
}
|
|
1434
|
+
declare class PafiBackendClient {
|
|
1435
|
+
private readonly config;
|
|
1436
|
+
constructor(config: PafiBackendConfig);
|
|
1437
|
+
requestSponsorship(request: SponsorshipRequest): Promise<SponsorshipResponse>;
|
|
1438
|
+
/**
|
|
1439
|
+
* Fetch ERC-4337 UserOp receipt via PAFI's authenticated bundler proxy.
|
|
1440
|
+
* Returns `null` when the bundler hasn't seen the userOp yet — caller
|
|
1441
|
+
* should keep polling. Used by status endpoints to short-circuit the
|
|
1442
|
+
* on-chain indexer when several PENDING locks share the same amount.
|
|
1443
|
+
*/
|
|
1444
|
+
getUserOpReceipt(userOpHash: Hex): Promise<{
|
|
1445
|
+
success: boolean;
|
|
1446
|
+
txHash: Hex;
|
|
1447
|
+
blockNumber: string;
|
|
1448
|
+
} | null>;
|
|
1449
|
+
relayUserOperation(request: RelayUserOpRequest): Promise<RelayUserOpResponse>;
|
|
1450
|
+
private _doRequest;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
/**
|
|
1454
|
+
* Status snapshot returned to mobile clients polling a mint lock.
|
|
1455
|
+
* Matches the legacy gg56 shape so existing FE code keeps working.
|
|
1456
|
+
*/
|
|
1457
|
+
interface MintStatusResponse {
|
|
1458
|
+
lockId: string;
|
|
1459
|
+
status: "PENDING" | "MINTED" | "EXPIRED" | "FAILED";
|
|
1460
|
+
txHash: Hex | null;
|
|
1461
|
+
amount: string;
|
|
1462
|
+
createdAt: string;
|
|
1463
|
+
expiresAt: string;
|
|
1464
|
+
}
|
|
1465
|
+
interface BurnStatusResponse {
|
|
1466
|
+
lockId: string;
|
|
1467
|
+
status: "PENDING" | "RESOLVED" | "EXPIRED";
|
|
1468
|
+
txHash: Hex | null;
|
|
1469
|
+
amount: string;
|
|
1470
|
+
createdAt: string;
|
|
1471
|
+
expiresAt: string;
|
|
1472
|
+
resolvedAt?: string | null;
|
|
1473
|
+
}
|
|
1474
|
+
interface MintStatusParams {
|
|
1475
|
+
lockId: string;
|
|
1476
|
+
/** User EOA from auth — handler returns 404 if the lock isn't theirs. */
|
|
1477
|
+
userAddress: Address;
|
|
1478
|
+
ledger: IPointLedger;
|
|
1479
|
+
/**
|
|
1480
|
+
* PAFI backend client for the bundler-receipt fallback. Optional —
|
|
1481
|
+
* when omitted, status only reflects what the on-chain `PointIndexer`
|
|
1482
|
+
* has finalized into the ledger. With it, the handler queries the
|
|
1483
|
+
* bundler receipt when:
|
|
1484
|
+
* - lock.status === "PENDING"
|
|
1485
|
+
* - lock.userOpHash is bound (set by `/claim/submit`)
|
|
1486
|
+
*
|
|
1487
|
+
* If the bundler reports the UserOp confirmed, the handler updates
|
|
1488
|
+
* the ledger lock + returns `MINTED` immediately, bypassing
|
|
1489
|
+
* `PointIndexer`'s amount-based race (multiple PENDING locks with
|
|
1490
|
+
* the same amount can be matched to the wrong tx_hash).
|
|
1491
|
+
*/
|
|
1492
|
+
pafiBackendClient?: PafiBackendClient;
|
|
1493
|
+
/** Optional logger for "ledger update failed" warnings. */
|
|
1494
|
+
onWarning?: (msg: string) => void;
|
|
1495
|
+
}
|
|
1496
|
+
interface BurnStatusParams {
|
|
1497
|
+
lockId: string;
|
|
1498
|
+
userAddress: Address;
|
|
1499
|
+
ledger: IPointLedger;
|
|
1500
|
+
pafiBackendClient?: PafiBackendClient;
|
|
1501
|
+
onWarning?: (msg: string) => void;
|
|
1502
|
+
}
|
|
1503
|
+
declare class LockNotFoundError extends Error {
|
|
1504
|
+
readonly code = "LOCK_NOT_FOUND";
|
|
1505
|
+
constructor();
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* Handle GET /claim/status/:lockId.
|
|
1510
|
+
*
|
|
1511
|
+
* Returns the lock's current state from the ledger. When the ledger
|
|
1512
|
+
* supports `userOpHash` binding AND the lock is still PENDING, falls
|
|
1513
|
+
* back to the bundler receipt — the canonical truth that bypasses
|
|
1514
|
+
* `PointIndexer`'s amount-based matching race.
|
|
1515
|
+
*
|
|
1516
|
+
* Throws `LockNotFoundError` when the lock doesn't exist or doesn't
|
|
1517
|
+
* belong to `userAddress`. Caller maps to HTTP 404.
|
|
1518
|
+
*/
|
|
1519
|
+
declare function handleClaimStatus(params: MintStatusParams): Promise<MintStatusResponse>;
|
|
1520
|
+
/**
|
|
1521
|
+
* Handle GET /redeem/status/:lockId. Symmetric to `handleClaimStatus`
|
|
1522
|
+
* for the burn → off-chain credit flow.
|
|
1523
|
+
*
|
|
1524
|
+
* Bundler-receipt fallback resolves the credit via
|
|
1525
|
+
* `ledger.resolveCreditByBurnTx` when the bundler reports the burn
|
|
1526
|
+
* UserOp succeeded.
|
|
1527
|
+
*/
|
|
1528
|
+
declare function handleRedeemStatus(params: BurnStatusParams): Promise<BurnStatusResponse>;
|
|
1529
|
+
|
|
1297
1530
|
/**
|
|
1298
1531
|
* Config for `createSubgraphPoolsProvider`.
|
|
1299
1532
|
*/
|
|
@@ -1511,117 +1744,6 @@ declare class BalanceAggregator {
|
|
|
1511
1744
|
getCombinedBalanceMulti(user: Address, pointTokens: Address[]): Promise<Map<Address, CombinedBalance>>;
|
|
1512
1745
|
}
|
|
1513
1746
|
|
|
1514
|
-
interface RetryConfig {
|
|
1515
|
-
maxAttempts?: number;
|
|
1516
|
-
initialDelayMs?: number;
|
|
1517
|
-
maxDelayMs?: number;
|
|
1518
|
-
maxRetryAfterMs?: number;
|
|
1519
|
-
}
|
|
1520
|
-
interface PafiBackendConfig {
|
|
1521
|
-
url: string;
|
|
1522
|
-
issuerId: string;
|
|
1523
|
-
apiKey: string;
|
|
1524
|
-
fetchImpl?: typeof fetch;
|
|
1525
|
-
timeoutMs?: number;
|
|
1526
|
-
retry?: RetryConfig;
|
|
1527
|
-
}
|
|
1528
|
-
type PafiBackendErrorCode = "MISSING_ISSUER_ID" | "MISSING_API_KEY" | "ISSUER_UNAUTHORIZED" | "USER_UNAUTHORIZED" | "INTENT_REJECTED" | "MINT_CAP_EXCEEDED" | "ISSUER_INACTIVE" | "BROKER_NOT_WHITELISTED" | "RATE_LIMIT_EXCEEDED" | "RATE_LIMIT_EXCEEDED_DAILY" | "RATE_LIMIT_EXCEEDED_PER_USER" | "ISSUER_BUDGET_EXCEEDED" | "RATE_LIMITER_UNAVAILABLE" | "PAYMASTER_UNAVAILABLE" | "TARGET_NOT_ALLOWLISTED" | "BAD_REQUEST" | "INTERNAL_ERROR" | "TIMEOUT" | "NETWORK_ERROR" | (string & {});
|
|
1529
|
-
declare class PafiBackendError extends Error {
|
|
1530
|
-
code: PafiBackendErrorCode;
|
|
1531
|
-
httpStatus: number;
|
|
1532
|
-
details?: unknown | undefined;
|
|
1533
|
-
readonly retryAfter?: number;
|
|
1534
|
-
private readonly serverSafeToRetry?;
|
|
1535
|
-
constructor(code: PafiBackendErrorCode, message: string, httpStatus: number, details?: unknown | undefined, opts?: {
|
|
1536
|
-
retryAfter?: number;
|
|
1537
|
-
safeToRetry?: boolean;
|
|
1538
|
-
});
|
|
1539
|
-
get safeToRetry(): boolean;
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
interface RelayUserOpRequest {
|
|
1543
|
-
userOp: Record<string, string | null>;
|
|
1544
|
-
entryPoint: string;
|
|
1545
|
-
eip7702Auth?: {
|
|
1546
|
-
chainId: string;
|
|
1547
|
-
address: string;
|
|
1548
|
-
nonce: string;
|
|
1549
|
-
r: string;
|
|
1550
|
-
s: string;
|
|
1551
|
-
yParity: string;
|
|
1552
|
-
};
|
|
1553
|
-
}
|
|
1554
|
-
interface RelayUserOpResponse {
|
|
1555
|
-
userOpHash: Hex;
|
|
1556
|
-
}
|
|
1557
|
-
interface SponsorshipUserOp {
|
|
1558
|
-
sender: Address;
|
|
1559
|
-
nonce: bigint;
|
|
1560
|
-
callData: Hex;
|
|
1561
|
-
callGasLimit: bigint;
|
|
1562
|
-
verificationGasLimit: bigint;
|
|
1563
|
-
preVerificationGas: bigint;
|
|
1564
|
-
maxFeePerGas: bigint;
|
|
1565
|
-
maxPriorityFeePerGas: bigint;
|
|
1566
|
-
}
|
|
1567
|
-
interface SponsorshipTarget {
|
|
1568
|
-
contract: Address;
|
|
1569
|
-
function: string;
|
|
1570
|
-
pointToken: Address;
|
|
1571
|
-
}
|
|
1572
|
-
interface SponsorshipRequest {
|
|
1573
|
-
chainId: number;
|
|
1574
|
-
scenario: string;
|
|
1575
|
-
userOp: SponsorshipUserOp;
|
|
1576
|
-
target: SponsorshipTarget;
|
|
1577
|
-
}
|
|
1578
|
-
interface SponsorshipResponse {
|
|
1579
|
-
paymaster: Address;
|
|
1580
|
-
paymasterData: Hex;
|
|
1581
|
-
paymasterVerificationGasLimit: bigint;
|
|
1582
|
-
paymasterPostOpGasLimit: bigint;
|
|
1583
|
-
/**
|
|
1584
|
-
* Pimlico's `pm_sponsorUserOperation` re-estimates these gas fields
|
|
1585
|
-
* and signs its paymaster signature over the new values. Callers
|
|
1586
|
-
* MUST overwrite the matching userOp fields with these BEFORE
|
|
1587
|
-
* computing the EIP-712 userOpHash and submitting to the bundler.
|
|
1588
|
-
* Otherwise both `AA34` (paymaster sig) and `AA24` (sender sig) will
|
|
1589
|
-
* fire — the EntryPoint hashes the actual on-chain field values, and
|
|
1590
|
-
* a mismatch invalidates every sig over the hash.
|
|
1591
|
-
*/
|
|
1592
|
-
callGasLimit?: bigint;
|
|
1593
|
-
verificationGasLimit?: bigint;
|
|
1594
|
-
preVerificationGas?: bigint;
|
|
1595
|
-
/**
|
|
1596
|
-
* Bundler-required gas price (Pimlico's `pimlico_getUserOperationGasPrice`
|
|
1597
|
-
* fast tier). Pimlico's paymaster signs over these — caller MUST apply
|
|
1598
|
-
* to the userOp before computing the EIP-712 userOpHash. Base RPC's
|
|
1599
|
-
* `eth_feeHistory` underestimates the bundler floor by 10-15 %, so
|
|
1600
|
-
* relying on it produces "maxFeePerGas must be at least ..." rejections.
|
|
1601
|
-
*/
|
|
1602
|
-
maxFeePerGas?: bigint;
|
|
1603
|
-
maxPriorityFeePerGas?: bigint;
|
|
1604
|
-
expiresAt: number;
|
|
1605
|
-
}
|
|
1606
|
-
declare class PafiBackendClient {
|
|
1607
|
-
private readonly config;
|
|
1608
|
-
constructor(config: PafiBackendConfig);
|
|
1609
|
-
requestSponsorship(request: SponsorshipRequest): Promise<SponsorshipResponse>;
|
|
1610
|
-
/**
|
|
1611
|
-
* Fetch ERC-4337 UserOp receipt via PAFI's authenticated bundler proxy.
|
|
1612
|
-
* Returns `null` when the bundler hasn't seen the userOp yet — caller
|
|
1613
|
-
* should keep polling. Used by status endpoints to short-circuit the
|
|
1614
|
-
* on-chain indexer when several PENDING locks share the same amount.
|
|
1615
|
-
*/
|
|
1616
|
-
getUserOpReceipt(userOpHash: Hex): Promise<{
|
|
1617
|
-
success: boolean;
|
|
1618
|
-
txHash: Hex;
|
|
1619
|
-
blockNumber: string;
|
|
1620
|
-
} | null>;
|
|
1621
|
-
relayUserOperation(request: RelayUserOpRequest): Promise<RelayUserOpResponse>;
|
|
1622
|
-
private _doRequest;
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1625
1747
|
/**
|
|
1626
1748
|
* Top-level configuration for `createIssuerService`.
|
|
1627
1749
|
*
|
|
@@ -1814,6 +1936,154 @@ interface IPendingUserOpStore {
|
|
|
1814
1936
|
*/
|
|
1815
1937
|
declare function serializeEntryToJsonRpc(entry: PendingUserOpEntry, signature: Hex, variant?: "sponsored" | "fallback"): Record<string, string | null>;
|
|
1816
1938
|
|
|
1939
|
+
/**
|
|
1940
|
+
* Re-shape `UserOpTypedData` so all `bigint` fields become hex strings —
|
|
1941
|
+
* required for JSON transport over HTTP. Mirrors the inverse of what
|
|
1942
|
+
* `walletClient.signTypedData` accepts on the client (it auto-coerces hex
|
|
1943
|
+
* strings back to bigints for `uint256` fields).
|
|
1944
|
+
*/
|
|
1945
|
+
type SerializedUserOpTypedData = {
|
|
1946
|
+
domain: UserOpTypedData["domain"];
|
|
1947
|
+
types: UserOpTypedData["types"];
|
|
1948
|
+
primaryType: UserOpTypedData["primaryType"];
|
|
1949
|
+
message: {
|
|
1950
|
+
sender: Address;
|
|
1951
|
+
nonce: Hex;
|
|
1952
|
+
initCode: Hex;
|
|
1953
|
+
callData: Hex;
|
|
1954
|
+
accountGasLimits: Hex;
|
|
1955
|
+
preVerificationGas: Hex;
|
|
1956
|
+
gasFees: Hex;
|
|
1957
|
+
paymasterAndData: Hex;
|
|
1958
|
+
};
|
|
1959
|
+
};
|
|
1960
|
+
/**
|
|
1961
|
+
* Convert a `UserOpTypedData` payload into the JSON-safe wire form
|
|
1962
|
+
* (bigint → hex string). The mobile client passes this directly to
|
|
1963
|
+
* `eth_signTypedData_v4` / viem's `signTypedData`.
|
|
1964
|
+
*/
|
|
1965
|
+
declare function serializeUserOpTypedData(td: UserOpTypedData): SerializedUserOpTypedData;
|
|
1966
|
+
/**
|
|
1967
|
+
* Merge Pimlico's paymaster-sponsorship response into a UserOp
|
|
1968
|
+
* skeleton, applying only fields that are actually defined.
|
|
1969
|
+
*
|
|
1970
|
+
* `pm_sponsorUserOperation` returns:
|
|
1971
|
+
* - `paymaster` / `paymasterData` — required for the sponsored sig
|
|
1972
|
+
* - `paymasterVerificationGasLimit` / `paymasterPostOpGasLimit`
|
|
1973
|
+
* - **re-estimated** `callGasLimit` / `verificationGasLimit` /
|
|
1974
|
+
* `preVerificationGas` — the paymaster signature is computed over
|
|
1975
|
+
* these new values
|
|
1976
|
+
* - **bundler-required** `maxFeePerGas` / `maxPriorityFeePerGas` —
|
|
1977
|
+
* Base RPC's `eth_feeHistory` underestimates, bundler rejects
|
|
1978
|
+
*
|
|
1979
|
+
* Callers MUST re-merge ALL of these into the userOp BEFORE computing
|
|
1980
|
+
* the EIP-712 userOpHash — otherwise both the paymaster signature
|
|
1981
|
+
* (AA34) and the user signature (AA24, recovered against a different
|
|
1982
|
+
* hash) fail at validation.
|
|
1983
|
+
*
|
|
1984
|
+
* Skips fields that are undefined so legacy paymaster responses
|
|
1985
|
+
* (without re-estimated gas) don't accidentally zero out the original
|
|
1986
|
+
* estimates.
|
|
1987
|
+
*/
|
|
1988
|
+
declare function mergePaymasterFields<T extends object>(userOp: T, paymasterFields: {
|
|
1989
|
+
paymaster: Address;
|
|
1990
|
+
paymasterData: Hex;
|
|
1991
|
+
paymasterVerificationGasLimit: bigint;
|
|
1992
|
+
paymasterPostOpGasLimit: bigint;
|
|
1993
|
+
callGasLimit?: bigint;
|
|
1994
|
+
verificationGasLimit?: bigint;
|
|
1995
|
+
preVerificationGas?: bigint;
|
|
1996
|
+
maxFeePerGas?: bigint;
|
|
1997
|
+
maxPriorityFeePerGas?: bigint;
|
|
1998
|
+
} | undefined): T;
|
|
1999
|
+
interface PreparedUserOp {
|
|
2000
|
+
/** The bundler-ready UserOp (with paymaster + Pimlico-quoted gas). */
|
|
2001
|
+
userOp: PartialUserOperation & {
|
|
2002
|
+
maxFeePerGas: bigint;
|
|
2003
|
+
maxPriorityFeePerGas: bigint;
|
|
2004
|
+
paymaster?: Address;
|
|
2005
|
+
paymasterData?: Hex;
|
|
2006
|
+
paymasterVerificationGasLimit?: bigint;
|
|
2007
|
+
paymasterPostOpGasLimit?: bigint;
|
|
2008
|
+
};
|
|
2009
|
+
/** Hex-encoded EIP-712 digest. Equals `EntryPoint.getUserOpHash`. */
|
|
2010
|
+
userOpHash: Hex;
|
|
2011
|
+
/** Typed-data payload — pass directly to `eth_signTypedData_v4`. */
|
|
2012
|
+
typedData: SerializedUserOpTypedData;
|
|
2013
|
+
}
|
|
2014
|
+
interface PrepareMobileUserOpParams {
|
|
2015
|
+
/** Lock id (issuer-generated) keying both store entry + ledger row. */
|
|
2016
|
+
lockId: string;
|
|
2017
|
+
/**
|
|
2018
|
+
* Sponsored variant — built with the PT operator-fee transfer
|
|
2019
|
+
* included. SDK or caller should set `partialUserOp.maxFeePerGas` /
|
|
2020
|
+
* `maxPriorityFeePerGas` from `provider.estimateFeesPerGas()` before
|
|
2021
|
+
* calling — they get overridden by Pimlico's quote anyway, but
|
|
2022
|
+
* they must be valid bigints for the merge.
|
|
2023
|
+
*/
|
|
2024
|
+
partialUserOp: PartialUserOperation & {
|
|
2025
|
+
maxFeePerGas: bigint;
|
|
2026
|
+
maxPriorityFeePerGas: bigint;
|
|
2027
|
+
};
|
|
2028
|
+
/**
|
|
2029
|
+
* Optional fee-stripped fallback variant — built with `gasFeePt: 0n`
|
|
2030
|
+
* (no PT operator-fee transfer). Submitted when paymaster refuses
|
|
2031
|
+
* sponsorship and the user pays ETH gas directly.
|
|
2032
|
+
*/
|
|
2033
|
+
partialUserOpFallback?: PartialUserOperation & {
|
|
2034
|
+
maxFeePerGas?: bigint;
|
|
2035
|
+
maxPriorityFeePerGas?: bigint;
|
|
2036
|
+
};
|
|
2037
|
+
/** Paymaster sponsorship response, or `undefined` if PAFI declined. */
|
|
2038
|
+
paymasterFields?: {
|
|
2039
|
+
paymaster: Address;
|
|
2040
|
+
paymasterData: Hex;
|
|
2041
|
+
paymasterVerificationGasLimit: bigint;
|
|
2042
|
+
paymasterPostOpGasLimit: bigint;
|
|
2043
|
+
callGasLimit?: bigint;
|
|
2044
|
+
verificationGasLimit?: bigint;
|
|
2045
|
+
preVerificationGas?: bigint;
|
|
2046
|
+
maxFeePerGas?: bigint;
|
|
2047
|
+
maxPriorityFeePerGas?: bigint;
|
|
2048
|
+
};
|
|
2049
|
+
chainId: number;
|
|
2050
|
+
/** Pending-userop store implementation (Redis/Postgres/Memory). */
|
|
2051
|
+
store: IPendingUserOpStore;
|
|
2052
|
+
/** TTL the store entry should outlive — typically the MintRequest deadline. */
|
|
2053
|
+
ttlSeconds: number;
|
|
2054
|
+
}
|
|
2055
|
+
interface PrepareMobileUserOpResult {
|
|
2056
|
+
sponsored: PreparedUserOp;
|
|
2057
|
+
/**
|
|
2058
|
+
* Set when `partialUserOpFallback` was supplied AND the PT fee was
|
|
2059
|
+
* non-zero (i.e. sponsored ≠ fallback). Mobile client picks which
|
|
2060
|
+
* variant to sign + submit; SDK's `serializeEntryToJsonRpc` reads
|
|
2061
|
+
* the `variant` flag to dispatch.
|
|
2062
|
+
*/
|
|
2063
|
+
fallback?: PreparedUserOp;
|
|
2064
|
+
/** What got persisted into the pending-userop store. */
|
|
2065
|
+
entry: PendingUserOpEntry;
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* Build the sponsored UserOp + (optional) fee-stripped fallback for the
|
|
2069
|
+
* mobile prepare/submit flow.
|
|
2070
|
+
*
|
|
2071
|
+
* What this does, end-to-end:
|
|
2072
|
+
* 1. Merge Pimlico's paymaster sponsorship + re-quoted gas into the
|
|
2073
|
+
* caller's `partialUserOp` skeleton.
|
|
2074
|
+
* 2. Compute the EIP-712 userOpHash + the typed-data payload (in
|
|
2075
|
+
* JSON-safe form for HTTP transport).
|
|
2076
|
+
* 3. (Optional) Repeat for the `partialUserOpFallback` skeleton with
|
|
2077
|
+
* no paymaster fields — produces a separate hash + typed-data so
|
|
2078
|
+
* the client can re-sign if it falls back.
|
|
2079
|
+
* 4. Persist a single store entry containing BOTH callData variants
|
|
2080
|
+
* keyed by lockId. `serializeEntryToJsonRpc` reads the `variant`
|
|
2081
|
+
* param at submit time.
|
|
2082
|
+
*
|
|
2083
|
+
* Replaces ~100 LoC of glue per scenario in issuer controllers.
|
|
2084
|
+
*/
|
|
2085
|
+
declare function prepareMobileUserOp(params: PrepareMobileUserOpParams): Promise<PrepareMobileUserOpResult>;
|
|
2086
|
+
|
|
1817
2087
|
interface IssuerRegistryRecord {
|
|
1818
2088
|
issuerAddress: Address;
|
|
1819
2089
|
signerAddress: Address;
|
|
@@ -1907,4 +2177,4 @@ declare class IssuerStateValidator {
|
|
|
1907
2177
|
/** SDK package version — bumped on every release */
|
|
1908
2178
|
declare const PAFI_ISSUER_SDK_VERSION = "0.4.0";
|
|
1909
2179
|
|
|
1910
|
-
export { type ApiClaimRequest, type ApiClaimResponse, type ApiConfigResponse, type ApiGasFeeResponse, type ApiLoginRequest, type ApiLoginResponse, type ApiNonceResponse, type ApiPoolsRequest, type ApiPoolsResponse, type ApiRedeemRequest, type ApiRedeemResponse, type ApiTopUpRequest, type ApiTopUpResponse, type ApiUserRequest, type ApiUserResponse, type AuthContext, AuthError, type AuthErrorCode, AuthService, type AuthServiceConfig, BalanceAggregator, type BalanceAggregatorConfig, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type CombinedBalance, DefaultPolicyEngine, type DefaultPolicyEngineOptions, FeeManager, type FeeManagerConfig, type IIndexerCursorStore, type IPendingUserOpStore, type IPointLedger, type IPolicyEngine, type ISessionStore, InMemoryCursorStore, IssuerApiHandlers, type IssuerApiHandlersConfig, type IssuerRegistryRecord, type IssuerService, type IssuerServiceConfig, IssuerStateError, IssuerStateValidator, type LockedMintRequest, type LoginResult, MemorySessionStore, type MemorySessionStoreOptions, type MintEvent, type MintingStatus, type NativePtQuoterConfig, NonceManager, PAFI_ISSUER_SDK_VERSION, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingUserOpEntry, PointIndexer, type PointIndexerConfig, type PolicyDecision, type PolicyEvalRequest, type PoolsProvider, type PreValidateMintResult, type PrepareBurnDirectParams, type PrepareBurnParams, type PrepareBurnWithSigParams, type PrepareMintParams, RelayError, type RelayErrorCode, RelayService, type RelayUserOpRequest, type RelayUserOpResponse, type RetryConfig, type Session, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, TopUpRedemptionError, TopUpRedemptionHandler, type TopUpRedemptionHandlerConfig, type TopUpRedemptionRequest, type TopUpRedemptionResponse, authenticateRequest, createIssuerService, createNativePtQuoter, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, serializeEntryToJsonRpc };
|
|
2180
|
+
export { type ApiClaimRequest, type ApiClaimResponse, type ApiConfigResponse, type ApiGasFeeResponse, type ApiLoginRequest, type ApiLoginResponse, type ApiNonceResponse, type ApiPoolsRequest, type ApiPoolsResponse, type ApiRedeemRequest, type ApiRedeemResponse, type ApiTopUpRequest, type ApiTopUpResponse, type ApiUserRequest, type ApiUserResponse, type AuthContext, AuthError, type AuthErrorCode, AuthService, type AuthServiceConfig, BalanceAggregator, type BalanceAggregatorConfig, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type CombinedBalance, DefaultPolicyEngine, type DefaultPolicyEngineOptions, FeeManager, type FeeManagerConfig, type IIndexerCursorStore, type IPendingUserOpStore, type IPointLedger, type IPolicyEngine, type ISessionStore, InMemoryCursorStore, IssuerApiHandlers, type IssuerApiHandlersConfig, type IssuerRegistryRecord, type IssuerService, type IssuerServiceConfig, IssuerStateError, IssuerStateValidator, LockNotFoundError, type LockedMintRequest, type LoginResult, MemorySessionStore, type MemorySessionStoreOptions, type MintEvent, type MintStatusParams, type MintStatusResponse, type MintingStatus, type NativePtQuoterConfig, NonceManager, PAFI_ISSUER_SDK_VERSION, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingCredit, type PendingUserOpEntry, PointIndexer, type PointIndexerConfig, type PolicyDecision, type PolicyEvalRequest, type PoolsProvider, type PreValidateMintResult, type PrepareBurnDirectParams, type PrepareBurnParams, type PrepareBurnWithSigParams, type PrepareMintParams, type PrepareMobileUserOpParams, type PrepareMobileUserOpResult, type PreparedUserOp, RelayError, type RelayErrorCode, RelayService, type RelayUserOpRequest, type RelayUserOpResponse, type RetryConfig, type SerializedUserOpTypedData, type Session, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, TopUpRedemptionError, TopUpRedemptionHandler, type TopUpRedemptionHandlerConfig, type TopUpRedemptionRequest, type TopUpRedemptionResponse, authenticateRequest, createIssuerService, createNativePtQuoter, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, handleClaimStatus, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, serializeEntryToJsonRpc, serializeUserOpTypedData };
|