@pafi-dev/issuer 0.12.7 → 0.15.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 +172 -95
- package/dist/index.cjs +107 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +144 -127
- package/dist/index.d.ts +144 -127
- package/dist/index.js +93 -137
- package/dist/index.js.map +1 -1
- package/package.json +13 -2
package/dist/index.d.cts
CHANGED
|
@@ -115,8 +115,18 @@ interface IPointLedger {
|
|
|
115
115
|
/** List currently-pending locked mint requests for a user. */
|
|
116
116
|
getLockedRequests(userAddress: Address, tokenAddress?: Address): Promise<LockedMintRequest[]>;
|
|
117
117
|
/**
|
|
118
|
-
* Transition a lock to a
|
|
118
|
+
* Transition a lock from `PENDING` to a terminal status
|
|
119
|
+
* (`MINTED` | `EXPIRED` | `FAILED`). The on-chain tx hash is
|
|
119
120
|
* supplied when the status is `MINTED`.
|
|
121
|
+
*
|
|
122
|
+
* Terminal states are immutable: once a lock leaves `PENDING` the
|
|
123
|
+
* status is fixed. Calling `updateMintStatus` on a non-PENDING lock
|
|
124
|
+
* is a silent no-op. This protects against late-arriving writes from
|
|
125
|
+
* different code paths (e.g. PointIndexer.finalize and the bundler-
|
|
126
|
+
* receipt fallback in statusHandlers) racing to overwrite each
|
|
127
|
+
* other — particularly the case where a stale `EXPIRED`/`FAILED`
|
|
128
|
+
* write would corrupt a `MINTED` lock whose balance has already
|
|
129
|
+
* been deducted.
|
|
120
130
|
*/
|
|
121
131
|
updateMintStatus(lockId: string, status: MintingStatus, txHash?: Hex): Promise<void>;
|
|
122
132
|
/**
|
|
@@ -204,7 +214,7 @@ interface DefaultPolicyEngineOptions {
|
|
|
204
214
|
provider?: PublicClient;
|
|
205
215
|
mintingOracleAddress?: Address;
|
|
206
216
|
/**
|
|
207
|
-
* Override the on-chain cap check. Defaults to `@pafi/core`'s
|
|
217
|
+
* Override the on-chain cap check. Defaults to `@pafi-dev/core`'s
|
|
208
218
|
* `verifyMintCap`, which reverts if the issuer's declared supply would
|
|
209
219
|
* be exceeded. A rejected check should throw; returning normally is pass.
|
|
210
220
|
*/
|
|
@@ -561,7 +571,7 @@ interface RelayServiceConfig {
|
|
|
561
571
|
chainId?: number;
|
|
562
572
|
}
|
|
563
573
|
/**
|
|
564
|
-
* Builds unsigned `PartialUserOperation` payloads for the
|
|
574
|
+
* Builds unsigned `PartialUserOperation` payloads for the sponsored
|
|
565
575
|
* flow. The service is stateless and HTTP-client-free:
|
|
566
576
|
*
|
|
567
577
|
* - `prepareMint` signs a `MintRequest` EIP-712 with the caller-supplied
|
|
@@ -573,7 +583,7 @@ interface RelayServiceConfig {
|
|
|
573
583
|
* deadline, burnerSig)`.
|
|
574
584
|
*
|
|
575
585
|
* There is no broadcasting, no operator wallet, no simulation — those
|
|
576
|
-
* concerns
|
|
586
|
+
* concerns live in the Bundler + Paymaster.
|
|
577
587
|
*/
|
|
578
588
|
declare class RelayService {
|
|
579
589
|
private readonly provider;
|
|
@@ -607,13 +617,13 @@ declare class RelayService {
|
|
|
607
617
|
* provides a pre-signed `BurnRequest` + sig bytes (typically from
|
|
608
618
|
* `PTRedeemHandler`).
|
|
609
619
|
*
|
|
610
|
-
* Direct burn (no sig)
|
|
611
|
-
*
|
|
620
|
+
* Direct burn (no sig) is not used — every burn goes through the
|
|
621
|
+
* issuer-signed `BurnRequest` path.
|
|
612
622
|
*/
|
|
613
623
|
prepareBurn(params: PrepareBurnParams): Promise<PartialUserOperation>;
|
|
614
624
|
}
|
|
615
625
|
/**
|
|
616
|
-
*
|
|
626
|
+
* Sig-gated `PointToken.mint(to, amount, deadline, minterSig)`.
|
|
617
627
|
*
|
|
618
628
|
* The issuer backend validates off-chain (balance, policy, KYC), signs
|
|
619
629
|
* a `MintRequest` EIP-712 with its minter signer, and packages the
|
|
@@ -645,16 +655,16 @@ interface PrepareMintParams {
|
|
|
645
655
|
/** Unix timestamp after which the signature expires. */
|
|
646
656
|
deadline: bigint;
|
|
647
657
|
/**
|
|
648
|
-
* Optional
|
|
658
|
+
* Optional — when set, mint is routed through MintFeeWrapper:
|
|
649
659
|
* - sig.receiver = wrapper address (vs `userAddress` for direct path)
|
|
650
660
|
* - calldata target = wrapper.mintWithFee(pointToken, user, gross, ...)
|
|
651
661
|
* - the wrapper then mints `amount` to itself, splits per recipient list,
|
|
652
662
|
* and forwards net to the user.
|
|
653
663
|
*
|
|
654
|
-
* Leave undefined
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
664
|
+
* Leave undefined for direct-mint behavior (no fee skim). Wrapper
|
|
665
|
+
* must be registered on the PointToken via `IssuerRegistry.addIssuer`
|
|
666
|
+
* cascade (or owner-only `wrapper.registerToken`) before this path
|
|
667
|
+
* works on-chain.
|
|
658
668
|
*/
|
|
659
669
|
mintFeeWrapperAddress?: Address;
|
|
660
670
|
/**
|
|
@@ -669,11 +679,10 @@ interface PrepareMintParams {
|
|
|
669
679
|
preVerificationGas?: bigint;
|
|
670
680
|
}
|
|
671
681
|
/**
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
*
|
|
676
|
-
* branched on internally.
|
|
682
|
+
* Sig-gated burn only — every burn goes through `BurnRequest` EIP-712
|
|
683
|
+
* signed by the issuer burner. The `mode: 'burnWithSig'` discriminant
|
|
684
|
+
* is preserved for backwards-compat with existing callers but is no
|
|
685
|
+
* longer branched on internally.
|
|
677
686
|
*/
|
|
678
687
|
interface PrepareBurnParams {
|
|
679
688
|
userAddress: Address;
|
|
@@ -715,8 +724,8 @@ interface FeeManagerConfig {
|
|
|
715
724
|
gasPremiumBps?: number;
|
|
716
725
|
/**
|
|
717
726
|
* Quote function — given an amount of native wei, return the
|
|
718
|
-
* equivalent amount in the fee currency (PT raw units
|
|
719
|
-
* USDT 6-decimal
|
|
727
|
+
* equivalent amount in the fee currency (typically PT raw units;
|
|
728
|
+
* USDT 6-decimal for swap / perp deposit flows).
|
|
720
729
|
*
|
|
721
730
|
* Injected so the manager stays chain- and token-agnostic. Issuers
|
|
722
731
|
* wire it to `@pafi-dev/core` V4 quoting, a subgraph query, or an
|
|
@@ -728,18 +737,14 @@ interface FeeManagerConfig {
|
|
|
728
737
|
* Computes how much fee to collect from the user to cover the gas cost
|
|
729
738
|
* of a sponsored UserOp.
|
|
730
739
|
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
733
|
-
* The fee is now expressed in the **fee currency** chosen by the caller
|
|
734
|
-
* (PT for mint/burn, USDT for swap/perp_deposit) — not hardcoded to USDT.
|
|
740
|
+
* The fee is expressed in the **fee currency** chosen by the caller
|
|
741
|
+
* (PT for mint/burn, USDT for swap/perp_deposit) — not hardcoded.
|
|
735
742
|
*
|
|
736
|
-
* **
|
|
737
|
-
*
|
|
738
|
-
*
|
|
743
|
+
* **No operator rebalancing.** The operator does not hold ETH directly;
|
|
744
|
+
* gas is paid by PAFI sponsor-relayer via the paymaster-proxy (see
|
|
745
|
+
* [SPONSORED_PATH_FLOW.md]). The fee collected here is an
|
|
739
746
|
* application-level ERC-20 transfer inside the same UserOp batch, not a
|
|
740
747
|
* reimbursement to a wallet that needs topping up.
|
|
741
|
-
*
|
|
742
|
-
* `rebalanceIfNeeded()` and `swapUsdtToNative` were removed in 0.3.0.
|
|
743
748
|
*/
|
|
744
749
|
declare class FeeManager {
|
|
745
750
|
private readonly provider;
|
|
@@ -815,8 +820,9 @@ interface PointIndexerConfig {
|
|
|
815
820
|
pointTokenAddress: Address;
|
|
816
821
|
ledger: IPointLedger;
|
|
817
822
|
/**
|
|
818
|
-
*
|
|
819
|
-
* (filtered by this `pointToken`) instead of
|
|
823
|
+
* When set, indexer listens to `MintFeeWrapper.MintWithFee`
|
|
824
|
+
* (filtered by this `pointToken`) instead of
|
|
825
|
+
* `PointToken.Transfer(0x0)`.
|
|
820
826
|
*
|
|
821
827
|
* Required for wrapper-mediated mints because the on-chain Transfer
|
|
822
828
|
* destination is the wrapper itself (not the end user), so a naive
|
|
@@ -874,15 +880,15 @@ interface PointIndexerConfig {
|
|
|
874
880
|
*
|
|
875
881
|
* **Two modes** — selected at construction by `mintFeeWrapperAddress`:
|
|
876
882
|
*
|
|
877
|
-
* 1. **Wrapper mode (
|
|
883
|
+
* 1. **Wrapper mode (recommended for mainnet)**
|
|
878
884
|
* Listens to `MintFeeWrapper.MintWithFee(indexed pointToken, indexed to,
|
|
879
885
|
* grossAmount, netAmount, feeAmount)` filtered by `pointToken`. The
|
|
880
886
|
* `to` field is the actual end-user (not the wrapper), and `grossAmount`
|
|
881
887
|
* matches the off-chain lock's amount.
|
|
882
888
|
*
|
|
883
|
-
* 2. **Direct mode (
|
|
884
|
-
* Listens to `PointToken.Transfer(from=0x0 → to)
|
|
885
|
-
*
|
|
889
|
+
* 2. **Direct mode (chains without wrapper)**
|
|
890
|
+
* Listens to `PointToken.Transfer(from=0x0 → to)`. Used when the
|
|
891
|
+
* wrapper address is undefined / zero / dead.
|
|
886
892
|
*
|
|
887
893
|
* Finalization strategy (per event):
|
|
888
894
|
* 1. Find a PENDING locked mint request for `to` with matching amount.
|
|
@@ -934,7 +940,7 @@ declare class PointIndexer {
|
|
|
934
940
|
*/
|
|
935
941
|
processBlockRange(from: bigint, to: bigint): Promise<void>;
|
|
936
942
|
/**
|
|
937
|
-
* Wrapper mode
|
|
943
|
+
* Wrapper mode: listen for `MintWithFee` on the wrapper,
|
|
938
944
|
* filtered to events for THIS pointToken only. The event's `to` field
|
|
939
945
|
* is the actual end user, and `grossAmount` matches the lock amount.
|
|
940
946
|
*/
|
|
@@ -1071,23 +1077,21 @@ interface ApiConfigResponse {
|
|
|
1071
1077
|
/**
|
|
1072
1078
|
* EIP-7702 delegation target — the single contract every user's
|
|
1073
1079
|
* EOA must delegate to before submitting sponsored UserOps. On
|
|
1074
|
-
* Base mainnet this is
|
|
1080
|
+
* Base mainnet this is Pimlico's `Simple7702Account` at
|
|
1081
|
+
* `0xe6Cae83BdE06E4c305530e199D7217f42808555B` (swapped in
|
|
1082
|
+
* 2026-04-27 to replace the earlier Coinbase Smart Wallet v2
|
|
1083
|
+
* BatchExecutor, which had a SignatureWrapper incompatibility
|
|
1084
|
+
* surfacing as AA23 0x3c10b94e during validateUserOp).
|
|
1075
1085
|
*/
|
|
1076
1086
|
batchExecutor?: Address;
|
|
1077
1087
|
/**
|
|
1078
|
-
*
|
|
1079
|
-
* (USDT→PT is free). FE uses this in `PoolKey.hooks` when building
|
|
1080
|
-
* a swap; the pool is only discoverable when the hook matches.
|
|
1081
|
-
*/
|
|
1082
|
-
pafiHook?: Address;
|
|
1083
|
-
/**
|
|
1084
|
-
* v1.6 — single global MintFeeWrapper that skims a fee on every
|
|
1088
|
+
* Single global MintFeeWrapper that skims a fee on every
|
|
1085
1089
|
* sig-gated mint and distributes across the configured recipients.
|
|
1086
1090
|
*/
|
|
1087
1091
|
mintFeeWrapper?: Address;
|
|
1088
1092
|
};
|
|
1089
1093
|
/**
|
|
1090
|
-
*
|
|
1094
|
+
* Per-PointToken mint fee (in basis points, 0–10000) read from
|
|
1091
1095
|
* `MintFeeWrapper.totalFeeBps(pointToken)`. Frontend uses this to show
|
|
1092
1096
|
* "you'll receive X PT (Y% mint fee)" before user signs.
|
|
1093
1097
|
*
|
|
@@ -1146,7 +1150,6 @@ interface ApiUserRequest {
|
|
|
1146
1150
|
}
|
|
1147
1151
|
interface ApiUserResponse {
|
|
1148
1152
|
mintRequestNonce: bigint;
|
|
1149
|
-
receiverConsentNonce: bigint;
|
|
1150
1153
|
/**
|
|
1151
1154
|
* Off-chain point balance from the issuer's ledger (excludes PENDING locks).
|
|
1152
1155
|
* This is what the user can claim into on-chain PT via `/claim`.
|
|
@@ -1163,8 +1166,8 @@ interface ApiUserResponse {
|
|
|
1163
1166
|
*/
|
|
1164
1167
|
totalBalance: bigint;
|
|
1165
1168
|
/**
|
|
1166
|
-
* @deprecated
|
|
1167
|
-
*
|
|
1169
|
+
* @deprecated Use `offChainBalance` instead. Retained as a wire-level
|
|
1170
|
+
* alias for older mobile clients that still read it.
|
|
1168
1171
|
*/
|
|
1169
1172
|
balance: bigint;
|
|
1170
1173
|
isMinter: boolean;
|
|
@@ -1348,10 +1351,10 @@ interface IssuerApiHandlersConfig {
|
|
|
1348
1351
|
*/
|
|
1349
1352
|
pafiWebUrl?: string;
|
|
1350
1353
|
/**
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1353
|
-
*
|
|
1354
|
-
*
|
|
1354
|
+
* MintFeeWrapper address used to read per-PointToken fee basis
|
|
1355
|
+
* points for `/config`. When omitted, the response will not include
|
|
1356
|
+
* `mintFeeBpsByToken` and FE must assume zero fee. Wrapper is shared
|
|
1357
|
+
* across PointTokens; per-token recipients live inside it.
|
|
1355
1358
|
*/
|
|
1356
1359
|
mintFeeWrapperAddress?: Address;
|
|
1357
1360
|
/** Required by `handleGasFee`; omit to disable the endpoint. */
|
|
@@ -1380,7 +1383,7 @@ interface IssuerApiHandlersConfig {
|
|
|
1380
1383
|
*
|
|
1381
1384
|
* Every protected handler takes a pre-verified `userAddress` as its first
|
|
1382
1385
|
* argument. The issuer's middleware wraps `authenticateRequest()` from
|
|
1383
|
-
* `@pafi/issuer` to extract that address from the Bearer token before
|
|
1386
|
+
* `@pafi-dev/issuer` to extract that address from the Bearer token before
|
|
1384
1387
|
* routing.
|
|
1385
1388
|
*/
|
|
1386
1389
|
declare class IssuerApiHandlers {
|
|
@@ -1454,9 +1457,8 @@ declare class IssuerApiHandlers {
|
|
|
1454
1457
|
/**
|
|
1455
1458
|
* `GET /user?chainId=<id>&user=<addr>&pointToken=<addr>`
|
|
1456
1459
|
*
|
|
1457
|
-
* Returns per-user state the frontend needs to build a fresh
|
|
1458
|
-
*
|
|
1459
|
-
* balance.
|
|
1460
|
+
* Returns per-user state the frontend needs to build a fresh mint:
|
|
1461
|
+
* on-chain nonces + minter status + off-chain balance.
|
|
1460
1462
|
*/
|
|
1461
1463
|
handleUser(userAddress: Address, request: ApiUserRequest): Promise<ApiUserResponse>;
|
|
1462
1464
|
/**
|
|
@@ -1482,7 +1484,7 @@ declare class IssuerApiHandlers {
|
|
|
1482
1484
|
}
|
|
1483
1485
|
|
|
1484
1486
|
/**
|
|
1485
|
-
*
|
|
1487
|
+
* Reverse flow — user-initiated PT redeem.
|
|
1486
1488
|
*
|
|
1487
1489
|
* User has on-chain PT, wants to convert back to off-chain points. The
|
|
1488
1490
|
* issuer backend signs a `BurnRequest` with its burner signer, reserves
|
|
@@ -2037,7 +2039,13 @@ declare function serializeUserOpTypedData(td: UserOpTypedData): SerializedUserOp
|
|
|
2037
2039
|
* (without re-estimated gas) don't accidentally zero out the original
|
|
2038
2040
|
* estimates.
|
|
2039
2041
|
*/
|
|
2040
|
-
|
|
2042
|
+
/**
|
|
2043
|
+
* Subset of `SponsorshipResponse` consumed by the merge/hash helpers.
|
|
2044
|
+
* Inlined as a structural type (rather than importing
|
|
2045
|
+
* `SponsorshipResponse` from `pafi-backend/client`) to keep
|
|
2046
|
+
* `userop-store` independent of the HTTP-client module.
|
|
2047
|
+
*/
|
|
2048
|
+
interface PaymasterGasEstimates {
|
|
2041
2049
|
paymaster: Address;
|
|
2042
2050
|
paymasterData: Hex;
|
|
2043
2051
|
paymasterVerificationGasLimit: bigint;
|
|
@@ -2047,7 +2055,8 @@ declare function mergePaymasterFields<T extends object>(userOp: T, paymasterFiel
|
|
|
2047
2055
|
preVerificationGas?: bigint;
|
|
2048
2056
|
maxFeePerGas?: bigint;
|
|
2049
2057
|
maxPriorityFeePerGas?: bigint;
|
|
2050
|
-
}
|
|
2058
|
+
}
|
|
2059
|
+
declare function mergePaymasterFields<T extends object>(userOp: T, paymasterFields: PaymasterGasEstimates | undefined): T;
|
|
2051
2060
|
interface PreparedUserOp {
|
|
2052
2061
|
/** The bundler-ready UserOp (with paymaster + Pimlico-quoted gas). */
|
|
2053
2062
|
userOp: PartialUserOperation & {
|
|
@@ -2063,6 +2072,51 @@ interface PreparedUserOp {
|
|
|
2063
2072
|
/** Typed-data payload — pass directly to `eth_signTypedData_v4`. */
|
|
2064
2073
|
typedData: SerializedUserOpTypedData;
|
|
2065
2074
|
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Atomic "merge paymaster fields + compute hash + build typed data" —
|
|
2077
|
+
* the only place the SDK should be doing all three operations.
|
|
2078
|
+
*
|
|
2079
|
+
* Why bundled into one call:
|
|
2080
|
+
*
|
|
2081
|
+
* Pimlico's `pm_sponsorUserOperation` re-estimates
|
|
2082
|
+
* `callGasLimit` / `verificationGasLimit` / `preVerificationGas` and
|
|
2083
|
+
* the bundler fee fields (`maxFeePerGas` / `maxPriorityFeePerGas`),
|
|
2084
|
+
* then signs `paymasterData` over the new values. The EntryPoint
|
|
2085
|
+
* hashes the actual on-chain field values during validation, so
|
|
2086
|
+
* callers MUST overwrite the matching userOp fields BEFORE
|
|
2087
|
+
* computing the userOpHash. Forgetting any field triggers AA34
|
|
2088
|
+
* (paymaster signature mismatch) and/or AA24 (sender signature
|
|
2089
|
+
* mismatch) — opaque failures that take hours to debug.
|
|
2090
|
+
*
|
|
2091
|
+
* Splitting "merge" and "hash" into two free functions invited
|
|
2092
|
+
* exactly this bug — each call site reinvented the merge logic,
|
|
2093
|
+
* and one was already drifting (see audit M-02). Returning all
|
|
2094
|
+
* three pieces (`userOp`, `userOpHash`, `typedData`) from a single
|
|
2095
|
+
* call makes "hash before merge" structurally impossible: there is
|
|
2096
|
+
* no intermediate userOp to compute a stale hash over.
|
|
2097
|
+
*
|
|
2098
|
+
* Behaviour:
|
|
2099
|
+
* - When `paymasterFields` is undefined (paymaster declined / Path
|
|
2100
|
+
* C self-pay), the result is just the hash + typed-data of the
|
|
2101
|
+
* caller's `partialUserOp` — no fields are touched.
|
|
2102
|
+
* - When provided, only defined keys in `paymasterFields` overwrite
|
|
2103
|
+
* the matching fields. Original gas/fee estimates survive when
|
|
2104
|
+
* the paymaster did not re-estimate.
|
|
2105
|
+
*
|
|
2106
|
+
* Replaces:
|
|
2107
|
+
* - manual spread merges (e.g. previous `delegateHandler.ts`)
|
|
2108
|
+
* - `mergePaymasterFields` + separate `computeUserOpHash` +
|
|
2109
|
+
* `buildUserOpTypedData` triplets in any new call site.
|
|
2110
|
+
*
|
|
2111
|
+
* Note: the original `mergePaymasterFields` and the raw
|
|
2112
|
+
* `computeUserOpHash` / `buildUserOpTypedData` exports remain
|
|
2113
|
+
* available — use this helper unless you have a specific reason to
|
|
2114
|
+
* stage the operations.
|
|
2115
|
+
*/
|
|
2116
|
+
declare function applyPaymasterGasEstimates(partialUserOp: PartialUserOperation & {
|
|
2117
|
+
maxFeePerGas: bigint;
|
|
2118
|
+
maxPriorityFeePerGas: bigint;
|
|
2119
|
+
}, paymasterFields: PaymasterGasEstimates | undefined, chainId: number): PreparedUserOp;
|
|
2066
2120
|
interface PrepareMobileUserOpParams {
|
|
2067
2121
|
/** Lock id (issuer-generated) keying both store entry + ledger row. */
|
|
2068
2122
|
lockId: string;
|
|
@@ -2276,7 +2330,7 @@ interface IssuerStateValidatorLike {
|
|
|
2276
2330
|
preValidateMint(pointToken: Address, amount: bigint): Promise<unknown>;
|
|
2277
2331
|
}
|
|
2278
2332
|
/**
|
|
2279
|
-
*
|
|
2333
|
+
* Sig-gated mint handler — mirrors `PTRedeemHandler` on the mint side.
|
|
2280
2334
|
*
|
|
2281
2335
|
* Pre-validates against IssuerRegistry + on-chain totalSupply, locks the
|
|
2282
2336
|
* off-chain balance, builds the sponsored UserOp (mint + PT fee
|
|
@@ -2316,7 +2370,7 @@ interface PTClaimHandlerConfig {
|
|
|
2316
2370
|
signatureDeadlineSeconds?: number;
|
|
2317
2371
|
now?: () => number;
|
|
2318
2372
|
/**
|
|
2319
|
-
* Optional override for the
|
|
2373
|
+
* Optional override for the MintFeeWrapper address. By default the
|
|
2320
2374
|
* handler auto-resolves the wrapper from the request's `chainId` via
|
|
2321
2375
|
* `getContractAddresses(chainId).mintFeeWrapper`. Set this only when:
|
|
2322
2376
|
* - testing against a non-canonical wrapper deploy, or
|
|
@@ -2557,12 +2611,12 @@ declare function createSdkErrorMapper(factories: SdkErrorMapperFactories): (err:
|
|
|
2557
2611
|
/**
|
|
2558
2612
|
* Top-level configuration for `createIssuerService`.
|
|
2559
2613
|
*
|
|
2560
|
-
*
|
|
2614
|
+
* The SDK is HTTP-client-free: it signs EIP-712 messages, reads
|
|
2561
2615
|
* on-chain state, builds unsigned UserOperations, and maintains the
|
|
2562
2616
|
* off-chain ledger. It never broadcasts transactions — that's the
|
|
2563
2617
|
* frontend's responsibility via Bundler + Paymaster.
|
|
2564
2618
|
*
|
|
2565
|
-
* **Multi-token
|
|
2619
|
+
* **Multi-token:** Pass `pointTokenAddresses: Address[]` to
|
|
2566
2620
|
* support multiple PointTokens under a single issuer backend. Legacy
|
|
2567
2621
|
* `pointTokenAddress: Address` still works for single-token deployments.
|
|
2568
2622
|
* When both are provided, `pointTokenAddresses` takes precedence.
|
|
@@ -2576,8 +2630,8 @@ interface IssuerServiceConfig {
|
|
|
2576
2630
|
/**
|
|
2577
2631
|
* Issuer-specific contract addresses merged into the `/config` response.
|
|
2578
2632
|
* PAFI-owned addresses (batchExecutor, usdt, issuerRegistry, mintingOracle,
|
|
2579
|
-
*
|
|
2580
|
-
* can be omitted. Only `pointToken` / `pointTokens` must be provided.
|
|
2633
|
+
* mintFeeWrapper, …) are auto-resolved from `getContractAddresses(chainId)`
|
|
2634
|
+
* and can be omitted. Only `pointToken` / `pointTokens` must be provided.
|
|
2581
2635
|
*/
|
|
2582
2636
|
contracts?: Pick<ApiConfigResponse["contracts"], "pointToken" | "pointTokens" | "relay">;
|
|
2583
2637
|
/**
|
|
@@ -2629,11 +2683,11 @@ interface IssuerServiceConfig {
|
|
|
2629
2683
|
*/
|
|
2630
2684
|
autoStart?: boolean;
|
|
2631
2685
|
/**
|
|
2632
|
-
*
|
|
2633
|
-
*
|
|
2686
|
+
* Override the MintFeeWrapper address used by the indexer. When
|
|
2687
|
+
* omitted, the factory auto-resolves from
|
|
2634
2688
|
* `getContractAddresses(chainId).mintFeeWrapper`. Pass the
|
|
2635
2689
|
* dead-zero address (`0x...dEaD`) to force direct-Transfer mode
|
|
2636
|
-
* (
|
|
2690
|
+
* (useful for local fork tests).
|
|
2637
2691
|
*/
|
|
2638
2692
|
mintFeeWrapperAddress?: Address;
|
|
2639
2693
|
};
|
|
@@ -2673,11 +2727,6 @@ interface IssuerService {
|
|
|
2673
2727
|
fee: FeeManager | undefined;
|
|
2674
2728
|
/** All indexers keyed by PointToken address. */
|
|
2675
2729
|
indexers: Map<Address, PointIndexer>;
|
|
2676
|
-
/**
|
|
2677
|
-
* First indexer. Kept for backward compat with 0.1.x callers.
|
|
2678
|
-
* @deprecated use `indexers.get(tokenAddress)` for multi-token.
|
|
2679
|
-
*/
|
|
2680
|
-
indexer: PointIndexer;
|
|
2681
2730
|
/** Framework-agnostic HTTP handlers — wire into Express / Fastify / Hono. */
|
|
2682
2731
|
api: IssuerApiHandlers;
|
|
2683
2732
|
/**
|
|
@@ -2756,7 +2805,6 @@ interface PoolsDto {
|
|
|
2756
2805
|
}
|
|
2757
2806
|
interface UserDto {
|
|
2758
2807
|
mintRequestNonce: string;
|
|
2759
|
-
receiverConsentNonce: string;
|
|
2760
2808
|
offChainBalance: string;
|
|
2761
2809
|
onChainBalance: string;
|
|
2762
2810
|
totalBalance: string;
|
|
@@ -2986,12 +3034,22 @@ interface SubgraphPoolsProviderConfig {
|
|
|
2986
3034
|
* Optional clock override for tests.
|
|
2987
3035
|
*/
|
|
2988
3036
|
now?: () => number;
|
|
3037
|
+
/**
|
|
3038
|
+
* Optional error callback. Invoked on every recoverable error (subgraph
|
|
3039
|
+
* unreachable, non-200 response, GraphQL errors, invalid pool payload).
|
|
3040
|
+
* The provider continues to return `{ pools: [] }` on error and also
|
|
3041
|
+
* logs via `console.warn`/`console.error`; this hook lets host apps
|
|
3042
|
+
* forward errors to their own observability stack without parsing logs.
|
|
3043
|
+
* Throwing inside this callback is swallowed so the provider remains
|
|
3044
|
+
* total. (Addresses CODE_REVIEW issuer MEDIUM-5.)
|
|
3045
|
+
*/
|
|
3046
|
+
onError?: (error: Error) => void;
|
|
2989
3047
|
}
|
|
2990
3048
|
/**
|
|
2991
3049
|
* Create a `PoolsProvider` backed by the PAFI subgraph.
|
|
2992
3050
|
*
|
|
2993
3051
|
* Queries the `pafiTokens` entity for the given `pointTokenAddress`,
|
|
2994
|
-
* reads its linked `Pool`, and returns a single-element `PoolKey[]`.
|
|
3052
|
+
* reads its linked V3 `Pool`, and returns a single-element `PoolKey[]`.
|
|
2995
3053
|
* Multiple pools per token would require a subgraph schema change.
|
|
2996
3054
|
*
|
|
2997
3055
|
* The result is cached in-process with a short TTL (default 30s). Pool
|
|
@@ -3002,19 +3060,22 @@ interface SubgraphPoolsProviderConfig {
|
|
|
3002
3060
|
* - the token is not registered on PAFI yet (no PafiToken entity)
|
|
3003
3061
|
* - the token is registered but its pool has not been initialised
|
|
3004
3062
|
* - the subgraph is unreachable or returns an error (logs to console,
|
|
3005
|
-
* does not throw — callers should
|
|
3063
|
+
* invokes `onError` if provided; does not throw — callers should
|
|
3064
|
+
* handle empty pool list gracefully)
|
|
3006
3065
|
*
|
|
3007
|
-
* Assumes the PAFI subgraph schema
|
|
3066
|
+
* Assumes the PAFI subgraph schema (`pafiToken { pool { id feeTier
|
|
3067
|
+
* token0 { id } token1 { id } } }`). Issuers with a custom subgraph must
|
|
3008
3068
|
* implement `PoolsProvider` themselves instead of using this helper.
|
|
3009
3069
|
*
|
|
3010
3070
|
* @example
|
|
3011
3071
|
* ```ts
|
|
3012
|
-
* import { createSubgraphPoolsProvider, createIssuerService } from "@pafi/issuer";
|
|
3072
|
+
* import { createSubgraphPoolsProvider, createIssuerService } from "@pafi-dev/issuer";
|
|
3013
3073
|
*
|
|
3014
3074
|
* const service = createIssuerService({
|
|
3015
3075
|
* // ...other config
|
|
3016
3076
|
* poolsProvider: createSubgraphPoolsProvider({
|
|
3017
3077
|
* subgraphUrl: "https://graph.pacificfinance.org/subgraphs/name/pafi",
|
|
3078
|
+
* onError: (err) => metrics.increment("issuer.pools.error", { reason: err.message }),
|
|
3018
3079
|
* }),
|
|
3019
3080
|
* });
|
|
3020
3081
|
* ```
|
|
@@ -3065,8 +3126,8 @@ interface SubgraphNativeUsdtQuoterConfig {
|
|
|
3065
3126
|
* Create a native→USDT quoter backed by the PAFI subgraph's
|
|
3066
3127
|
* `Bundle.ethPriceUSD`. The returned function has the shape
|
|
3067
3128
|
* `(amountNative: bigint) => Promise<bigint>` and can be passed as
|
|
3068
|
-
* `quoteNativeToFee` to `FeeManager` —
|
|
3069
|
-
*
|
|
3129
|
+
* `quoteNativeToFee` to `FeeManager` — the fee currency is configured
|
|
3130
|
+
* at the integration layer, not hardcoded here.
|
|
3070
3131
|
*
|
|
3071
3132
|
* Used by `FeeManager.estimateGasFee()` to convert the gas cost into
|
|
3072
3133
|
* an ERC-20 amount charged as part of the sponsored UserOp batch.
|
|
@@ -3135,50 +3196,6 @@ interface NativePtQuoterConfig {
|
|
|
3135
3196
|
*/
|
|
3136
3197
|
declare function createNativePtQuoter(config: NativePtQuoterConfig): (amountNative: bigint) => Promise<bigint>;
|
|
3137
3198
|
|
|
3138
|
-
/**
|
|
3139
|
-
* Combined off-chain + on-chain balance for a single user / token pair.
|
|
3140
|
-
*
|
|
3141
|
-
* - `offChain` — the issuer's ledger balance (available, excluding locks)
|
|
3142
|
-
* - `onChain` — the user's ERC-20 balance from `PointToken.balanceOf`
|
|
3143
|
-
* - `total` — `offChain + onChain` (what the Issuer App displays)
|
|
3144
|
-
*/
|
|
3145
|
-
interface CombinedBalance {
|
|
3146
|
-
offChain: bigint;
|
|
3147
|
-
onChain: bigint;
|
|
3148
|
-
total: bigint;
|
|
3149
|
-
}
|
|
3150
|
-
interface BalanceAggregatorConfig {
|
|
3151
|
-
provider: PublicClient;
|
|
3152
|
-
ledger: IPointLedger;
|
|
3153
|
-
}
|
|
3154
|
-
/**
|
|
3155
|
-
* v1.4 utility — aggregates off-chain + on-chain point balances into a
|
|
3156
|
-
* single view for the "combined balance" UI in the Issuer App.
|
|
3157
|
-
*
|
|
3158
|
-
* The `/user` API handler uses this internally; the helper is exposed
|
|
3159
|
-
* publicly so Issuer Apps can call it directly without going through
|
|
3160
|
-
* the HTTP layer (e.g., for server-rendered pages or admin dashboards).
|
|
3161
|
-
*
|
|
3162
|
-
* See [REQUIREMENTS_V2.md] §1 — "The Issuer App displays a combined
|
|
3163
|
-
* balance (off-chain points + on-chain PT) and does not surface USDT."
|
|
3164
|
-
*/
|
|
3165
|
-
declare class BalanceAggregator {
|
|
3166
|
-
private readonly provider;
|
|
3167
|
-
private readonly ledger;
|
|
3168
|
-
constructor(config: BalanceAggregatorConfig);
|
|
3169
|
-
/**
|
|
3170
|
-
* Combined balance for a single (user, token) pair. Fetches off-chain
|
|
3171
|
-
* + on-chain in parallel.
|
|
3172
|
-
*/
|
|
3173
|
-
getCombinedBalance(user: Address, pointToken: Address): Promise<CombinedBalance>;
|
|
3174
|
-
/**
|
|
3175
|
-
* Combined balance for multiple tokens owned by the same user. Runs
|
|
3176
|
-
* all lookups in parallel. Returns a Map keyed by the token address
|
|
3177
|
-
* (same casing as supplied — caller should normalize if needed).
|
|
3178
|
-
*/
|
|
3179
|
-
getCombinedBalanceMulti(user: Address, pointTokens: Address[]): Promise<Map<Address, CombinedBalance>>;
|
|
3180
|
-
}
|
|
3181
|
-
|
|
3182
3199
|
/**
|
|
3183
3200
|
* Typed errors thrown by the helpers below — issuer controllers map
|
|
3184
3201
|
* these to the appropriate HTTP status. We don't depend on @nestjs/common
|
|
@@ -3299,9 +3316,9 @@ interface IssuerRegistryRecord {
|
|
|
3299
3316
|
mintingOracle: Address;
|
|
3300
3317
|
}
|
|
3301
3318
|
/**
|
|
3302
|
-
*
|
|
3303
|
-
*
|
|
3304
|
-
* PointTokens with different supply policies.
|
|
3319
|
+
* Per-token cap config read from `MintingOracle.tokenCaps()`. Caps
|
|
3320
|
+
* live per PointToken (not per issuer), so a single issuer can run
|
|
3321
|
+
* many PointTokens with different supply policies.
|
|
3305
3322
|
*/
|
|
3306
3323
|
interface TokenCapRecord {
|
|
3307
3324
|
declaredTotalSupply: bigint;
|
|
@@ -3470,4 +3487,4 @@ declare class MemoryRedemptionHistoryStore implements IRedemptionHistoryStore {
|
|
|
3470
3487
|
|
|
3471
3488
|
declare const PAFI_ISSUER_SDK_VERSION: string;
|
|
3472
3489
|
|
|
3473
|
-
export { AdapterMisconfiguredError, type ApiConfigResponse, type ApiGasFeeResponse, type ApiLoginRequest, type ApiLoginResponse, type ApiNonceResponse, type ApiPoolsRequest, type ApiPoolsResponse, type ApiRedemptionEvaluateRequest, type ApiRedemptionEvaluateResponse, type ApiRedemptionPreviewRequest, type ApiRedemptionPreviewResponse, type ApiUserRequest, type ApiUserResponse, type AuthContext, AuthError, type AuthErrorCode, AuthService, type AuthServiceConfig,
|
|
3490
|
+
export { AdapterMisconfiguredError, type ApiConfigResponse, type ApiGasFeeResponse, type ApiLoginRequest, type ApiLoginResponse, type ApiNonceResponse, type ApiPoolsRequest, type ApiPoolsResponse, type ApiRedemptionEvaluateRequest, type ApiRedemptionEvaluateResponse, type ApiRedemptionPreviewRequest, type ApiRedemptionPreviewResponse, type ApiUserRequest, type ApiUserResponse, type AuthContext, AuthError, type AuthErrorCode, AuthService, type AuthServiceConfig, BundlerNotConfiguredError, BundlerRejectedError, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type ClaimDto, type ConfigDto, ConfigurationError, DEFAULT_REDEMPTION_POLICY, type DecodedCallDto, DefaultPolicyEngine, type DefaultPolicyEngineOptions, type DelegatePrepareDto, type DelegateStatusDto, type EvaluateInput, FeeManager, type FeeManagerConfig, type FetchFailureReason, type FetchResult, type GasFeeDto, type HandleDelegateSubmitParams, type HandleDelegateSubmitResult, type HandleMobilePrepareParams, type HandleMobilePrepareResult, type HandleMobileSubmitParams, type IIndexerCursorStore, type IPendingUserOpStore, type IPointLedger, type IPolicyEngine, type IRateLimiter, type IRedemptionHistoryStore, type ISessionStore, InMemoryCursorStore, IssuerApiAdapter, type IssuerApiAdapterConfig, IssuerApiHandlers, type IssuerApiHandlersConfig, type IssuerRegistryRecord, type IssuerService, type IssuerServiceConfig, IssuerStateError, IssuerStateValidator, LockNotFoundError, type LockedMintRequest, type LoginResult, MemoryPendingUserOpStore, MemoryRateLimiter, MemoryRedemptionHistoryStore, MemorySessionStore, type MemorySessionStoreOptions, type MintEvent, type MintStatusParams, type MintStatusResponse, type MintingStatus, type MobilePrepareDto, type MobileSubmitDto, type NativePtQuoterConfig, NonceManager, NoopRateLimiter, PAFI_ISSUER_SDK_VERSION, PTClaimError, PTClaimHandler, type PTClaimHandlerConfig, type PTClaimRequest, type PTClaimResponse, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PaymasterGasEstimates, type PendingCredit, type PendingUserOpEntry, PendingUserOpForbiddenError, PendingUserOpNotFoundError, type PerpDepositDto, PerpDepositError, PerpDepositHandler, type PerpDepositHandlerConfig, type PerpDepositRequest, type PerpDepositResponse, PointIndexer, type PointIndexerConfig, type PolicyDecision, type PolicyEvalRequest, PolicyProvider, type PolicyProviderConfig, type PoolsDto, type PoolsProvider, type PreValidateMintResult, type PrepareBurnParams, type PrepareMintParams, type PrepareMobileUserOpParams, type PrepareMobileUserOpResult, type PreparedUserOp, REDEMPTION_HISTORY_WINDOW_SEC, type RateLimitAction, type RateLimiterConfig, type RedeemDto, type RedeemPrepareDto, RedemptionService, type RedemptionServiceConfig, RelayError, type RelayErrorCode, RelayService, type RelayUserOpParams, type RelayUserOpRequest, type RelayUserOpResponse, type RequestPaymasterParams, type ResolvedPolicy, type RetryConfig, type SdkErrorBody, type SdkErrorMapperFactories, type SdkErrorStatus, type SerializedUserOpTypedData, type Session, SettlementClient, type SettlementClientConfig, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, type UserDto, type UserHistory, applyPaymasterGasEstimates, authenticateRequest, buildSdkErrorBody, createIssuerService, createNativePtQuoter, createSdkErrorMapper, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, defaultPolicyFor, evaluateRedemption, handleClaimStatus, handleDelegateSubmit, handleMobilePrepare, handleMobileSubmit, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, relayUserOp, requestPaymaster, serializeEntryToJsonRpc, serializeUserOpTypedData };
|