@pafi-dev/issuer 0.5.36 → 0.5.38

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,5 +1,5 @@
1
1
  import { Address, Hex, PublicClient, WalletClient } from 'viem';
2
- import { PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, ENTRY_POINT_V08 } from '@pafi-dev/core';
2
+ import { PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, Eip7702AuthorizationJsonRpc, ENTRY_POINT_V08 } from '@pafi-dev/core';
3
3
  export { PAFI_SUBGRAPH_URL } from '@pafi-dev/core';
4
4
 
5
5
  /**
@@ -2069,6 +2069,155 @@ declare class PerpDepositHandler {
2069
2069
  handle(request: PerpDepositRequest): Promise<PerpDepositResponse>;
2070
2070
  }
2071
2071
 
2072
+ /**
2073
+ * Pure mechanics for the EIP-7702 delegation submit flow. Builds the
2074
+ * empty-batch UserOp, attaches paymaster sponsorship, splits the user's
2075
+ * authorization signature into the JSON-RPC tuple, and relays via the
2076
+ * PAFI sponsor-relayer.
2077
+ *
2078
+ * The UserOp itself is a no-op — `BatchExecutor.execute([])` does
2079
+ * nothing. The work is in the `eip7702Auth` object: the bundler picks
2080
+ * it up, runs the EIP-7702 path, and installs the delegation on the
2081
+ * user's EOA atomically with the (empty) UserOp.
2082
+ *
2083
+ * Throws the same `BundlerNotConfiguredError` / `BundlerRejectedError`
2084
+ * as other relay paths so issuer controllers can use one error mapper.
2085
+ */
2086
+ interface HandleDelegateSubmitParams {
2087
+ userAddress: Address;
2088
+ chainId: number;
2089
+ /** Account nonce read at `delegate/prepare` time and signed by the user. */
2090
+ delegationNonce: bigint;
2091
+ /** ERC-4337 account nonce. Caller fetches via EntryPoint.getNonce. */
2092
+ aaNonce: bigint;
2093
+ /** 65-byte secp256k1 signature over the EIP-7702 authorization hash. */
2094
+ authSig: Hex | string;
2095
+ /** EIP-1559 fees from `provider.estimateFeesPerGas()` (or RPC equivalent). */
2096
+ fees: {
2097
+ maxFeePerGas?: bigint;
2098
+ maxPriorityFeePerGas?: bigint;
2099
+ };
2100
+ pafiBackendClient?: PafiBackendClient | null;
2101
+ onWarning?: (msg: string) => void;
2102
+ /** Override gas limits for the empty-batch UserOp. */
2103
+ gasLimits?: {
2104
+ callGasLimit?: bigint;
2105
+ verificationGasLimit?: bigint;
2106
+ preVerificationGas?: bigint;
2107
+ };
2108
+ }
2109
+ interface HandleDelegateSubmitResult {
2110
+ userOpHash: Hex;
2111
+ /** True when paymaster sponsorship was applied (gas is free). */
2112
+ isSponsored: boolean;
2113
+ /** The authorization tuple actually sent to the bundler. */
2114
+ authorization: Eip7702AuthorizationJsonRpc;
2115
+ }
2116
+ declare function handleDelegateSubmit(params: HandleDelegateSubmitParams): Promise<HandleDelegateSubmitResult>;
2117
+
2118
+ /**
2119
+ * Quote PT → USDT for the cashout preview screen.
2120
+ *
2121
+ * Three branches the FE needs distinct handling for:
2122
+ * - `pointAmount = 0` → all zeros, no RPC call.
2123
+ * - no pool / no path → `quoteError: 'QUOTE_UNAVAILABLE'`.
2124
+ * - amountOut < gas reimbursement → `quoteError: 'AMOUNT_TOO_SMALL_FOR_GAS'`.
2125
+ *
2126
+ * Returns derived `netUsdtOut`, `exchangeRate`, and a `suggestedDeadline`
2127
+ * so callers don't need to compute those locally.
2128
+ *
2129
+ * Replaces ~50 LoC of inline quote-handling in issuer controllers.
2130
+ */
2131
+ interface QuotePointTokenToUsdtParams {
2132
+ provider: PublicClient;
2133
+ chainId: number;
2134
+ pointTokenAddress: Address;
2135
+ pointAmount: bigint;
2136
+ pools: PoolKey[];
2137
+ /** Operator gas-reimbursement quoted in USDT (subtracted from output). */
2138
+ gasFeeUsdt: bigint;
2139
+ /** Override deadline window; default 300 seconds. */
2140
+ deadlineSeconds?: number;
2141
+ now?: () => number;
2142
+ }
2143
+ interface QuotePointTokenToUsdtResult {
2144
+ /** Raw V4 quote on the full point amount, before gas deduction. */
2145
+ estimatedUsdtOut: bigint;
2146
+ /** `estimatedUsdtOut - gasFeeUsdt`, clamped to 0. */
2147
+ netUsdtOut: bigint;
2148
+ /** USDT per 1.0 PT (1e18 raw units), formatted to 8 decimal places. */
2149
+ exchangeRate: string;
2150
+ /** V4 Quoter's gas estimate for the swap — informational. */
2151
+ gasEstimate: bigint;
2152
+ /** Unix seconds — `now + deadlineSeconds`. */
2153
+ suggestedDeadline: number;
2154
+ /** When set, the FE should hide the CTA / show "increase amount". */
2155
+ quoteError?: "QUOTE_UNAVAILABLE" | "AMOUNT_TOO_SMALL_FOR_GAS";
2156
+ }
2157
+ declare function quotePointTokenToUsdt(params: QuotePointTokenToUsdtParams): Promise<QuotePointTokenToUsdtResult>;
2158
+
2159
+ /**
2160
+ * Normalized HTTP status the issuer controller should surface for a
2161
+ * given SDK error. Kept to the three statuses every issuer needs —
2162
+ * `400/500/etc.` are not used because every SDK error already maps
2163
+ * cleanly into one of these three buckets.
2164
+ */
2165
+ type SdkErrorStatus = "not_found" | "unprocessable" | "service_unavailable";
2166
+ /**
2167
+ * Structured body the issuer controller passes to its
2168
+ * framework-specific exception class. Mirrors the shape every PAFI
2169
+ * issuer surfaces over HTTP today.
2170
+ */
2171
+ interface SdkErrorBody {
2172
+ code: string;
2173
+ message: string;
2174
+ details?: unknown;
2175
+ safeToRetry: boolean;
2176
+ }
2177
+ /**
2178
+ * Per-status exception factories. The issuer's controller wires one
2179
+ * factory per status to its preferred framework's exception class
2180
+ * (NestJS `UnprocessableEntityException`, Fastify `httpErrors.badData`,
2181
+ * etc). The factory must throw or return an Error — `createSdkErrorMapper`
2182
+ * uses `throw factory(body)` so either form is fine.
2183
+ */
2184
+ interface SdkErrorMapperFactories {
2185
+ notFound: (body: SdkErrorBody) => Error;
2186
+ unprocessable: (body: SdkErrorBody) => Error;
2187
+ serviceUnavailable: (body: SdkErrorBody) => Error;
2188
+ }
2189
+ /**
2190
+ * Build a single error-mapping function that converts any typed SDK
2191
+ * error into the issuer's framework-specific HTTP exception.
2192
+ *
2193
+ * - `PendingUserOpNotFoundError` → 404 (lock expired / already submitted)
2194
+ * - `BundlerNotConfiguredError` → 503 (PAFI backend client missing)
2195
+ * - `IssuerStateError` → 422 (cap exceeded / inactive)
2196
+ * - `PerpDepositError` → 422 (Orderly relay quote / broker)
2197
+ * - `PTClaimError`, `PTRedeemError`, `SwapError`, `BundlerRejectedError` → 422
2198
+ * - any other error → re-thrown as-is
2199
+ *
2200
+ * `safeToRetry` is `true` only for transient cases:
2201
+ * - `MINT_CAP_EXCEEDED` (cap may free up between requests)
2202
+ * - `RELAY_FEE_EXCEEDS_AMOUNT` (Orderly fee may drop)
2203
+ *
2204
+ * Usage (NestJS):
2205
+ *
2206
+ * ```ts
2207
+ * const mapSdkError = createSdkErrorMapper({
2208
+ * notFound: (body) => new NotFoundException(body),
2209
+ * unprocessable: (body) => new UnprocessableEntityException(body),
2210
+ * serviceUnavailable: (body) => new ServiceUnavailableException(body),
2211
+ * });
2212
+ *
2213
+ * try { ... } catch (err) { mapSdkError(err); }
2214
+ * ```
2215
+ *
2216
+ * Returns `never` so call sites in `try/catch` propagate the throw
2217
+ * without a redundant `throw` keyword.
2218
+ */
2219
+ declare function createSdkErrorMapper(factories: SdkErrorMapperFactories): (err: unknown) => never;
2220
+
2072
2221
  /**
2073
2222
  * Config for `createSubgraphPoolsProvider`.
2074
2223
  */
@@ -2593,4 +2742,4 @@ declare class IssuerStateValidator {
2593
2742
  /** SDK package version — bumped on every release */
2594
2743
  declare const PAFI_ISSUER_SDK_VERSION = "0.4.0";
2595
2744
 
2596
- 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, BundlerNotConfiguredError, BundlerRejectedError, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type CombinedBalance, DefaultPolicyEngine, type DefaultPolicyEngineOptions, FeeManager, type FeeManagerConfig, type HandleMobilePrepareParams, type HandleMobilePrepareResult, type HandleMobileSubmitParams, 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, PTClaimError, PTClaimHandler, type PTClaimHandlerConfig, type PTClaimRequest, type PTClaimResponse, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingCredit, type PendingUserOpEntry, PendingUserOpNotFoundError, PerpDepositError, PerpDepositHandler, type PerpDepositHandlerConfig, type PerpDepositRequest, type PerpDepositResponse, 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 RelayUserOpParams, type RelayUserOpRequest, type RelayUserOpResponse, type RequestPaymasterParams, type RetryConfig, type SerializedUserOpTypedData, type Session, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, SwapError, SwapHandler, type SwapHandlerConfig, type SwapRequest, type SwapResponse, TopUpRedemptionError, TopUpRedemptionHandler, type TopUpRedemptionHandlerConfig, type TopUpRedemptionRequest, type TopUpRedemptionResponse, authenticateRequest, createIssuerService, createNativePtQuoter, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, handleClaimStatus, handleMobilePrepare, handleMobileSubmit, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, relayUserOp, requestPaymaster, serializeEntryToJsonRpc, serializeUserOpTypedData };
2745
+ 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, BundlerNotConfiguredError, BundlerRejectedError, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type CombinedBalance, DefaultPolicyEngine, type DefaultPolicyEngineOptions, FeeManager, type FeeManagerConfig, type HandleDelegateSubmitParams, type HandleDelegateSubmitResult, type HandleMobilePrepareParams, type HandleMobilePrepareResult, type HandleMobileSubmitParams, 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, PTClaimError, PTClaimHandler, type PTClaimHandlerConfig, type PTClaimRequest, type PTClaimResponse, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingCredit, type PendingUserOpEntry, PendingUserOpNotFoundError, PerpDepositError, PerpDepositHandler, type PerpDepositHandlerConfig, type PerpDepositRequest, type PerpDepositResponse, 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, type QuotePointTokenToUsdtParams, type QuotePointTokenToUsdtResult, RelayError, type RelayErrorCode, RelayService, type RelayUserOpParams, type RelayUserOpRequest, type RelayUserOpResponse, type RequestPaymasterParams, type RetryConfig, type SdkErrorBody, type SdkErrorMapperFactories, type SdkErrorStatus, type SerializedUserOpTypedData, type Session, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, SwapError, SwapHandler, type SwapHandlerConfig, type SwapRequest, type SwapResponse, TopUpRedemptionError, TopUpRedemptionHandler, type TopUpRedemptionHandlerConfig, type TopUpRedemptionRequest, type TopUpRedemptionResponse, authenticateRequest, createIssuerService, createNativePtQuoter, createSdkErrorMapper, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, handleClaimStatus, handleDelegateSubmit, handleMobilePrepare, handleMobileSubmit, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, quotePointTokenToUsdt, relayUserOp, requestPaymaster, serializeEntryToJsonRpc, serializeUserOpTypedData };
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, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, ENTRY_POINT_V08 } from '@pafi-dev/core';
2
+ import { PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, Eip7702AuthorizationJsonRpc, ENTRY_POINT_V08 } from '@pafi-dev/core';
3
3
  export { PAFI_SUBGRAPH_URL } from '@pafi-dev/core';
4
4
 
5
5
  /**
@@ -2069,6 +2069,155 @@ declare class PerpDepositHandler {
2069
2069
  handle(request: PerpDepositRequest): Promise<PerpDepositResponse>;
2070
2070
  }
2071
2071
 
2072
+ /**
2073
+ * Pure mechanics for the EIP-7702 delegation submit flow. Builds the
2074
+ * empty-batch UserOp, attaches paymaster sponsorship, splits the user's
2075
+ * authorization signature into the JSON-RPC tuple, and relays via the
2076
+ * PAFI sponsor-relayer.
2077
+ *
2078
+ * The UserOp itself is a no-op — `BatchExecutor.execute([])` does
2079
+ * nothing. The work is in the `eip7702Auth` object: the bundler picks
2080
+ * it up, runs the EIP-7702 path, and installs the delegation on the
2081
+ * user's EOA atomically with the (empty) UserOp.
2082
+ *
2083
+ * Throws the same `BundlerNotConfiguredError` / `BundlerRejectedError`
2084
+ * as other relay paths so issuer controllers can use one error mapper.
2085
+ */
2086
+ interface HandleDelegateSubmitParams {
2087
+ userAddress: Address;
2088
+ chainId: number;
2089
+ /** Account nonce read at `delegate/prepare` time and signed by the user. */
2090
+ delegationNonce: bigint;
2091
+ /** ERC-4337 account nonce. Caller fetches via EntryPoint.getNonce. */
2092
+ aaNonce: bigint;
2093
+ /** 65-byte secp256k1 signature over the EIP-7702 authorization hash. */
2094
+ authSig: Hex | string;
2095
+ /** EIP-1559 fees from `provider.estimateFeesPerGas()` (or RPC equivalent). */
2096
+ fees: {
2097
+ maxFeePerGas?: bigint;
2098
+ maxPriorityFeePerGas?: bigint;
2099
+ };
2100
+ pafiBackendClient?: PafiBackendClient | null;
2101
+ onWarning?: (msg: string) => void;
2102
+ /** Override gas limits for the empty-batch UserOp. */
2103
+ gasLimits?: {
2104
+ callGasLimit?: bigint;
2105
+ verificationGasLimit?: bigint;
2106
+ preVerificationGas?: bigint;
2107
+ };
2108
+ }
2109
+ interface HandleDelegateSubmitResult {
2110
+ userOpHash: Hex;
2111
+ /** True when paymaster sponsorship was applied (gas is free). */
2112
+ isSponsored: boolean;
2113
+ /** The authorization tuple actually sent to the bundler. */
2114
+ authorization: Eip7702AuthorizationJsonRpc;
2115
+ }
2116
+ declare function handleDelegateSubmit(params: HandleDelegateSubmitParams): Promise<HandleDelegateSubmitResult>;
2117
+
2118
+ /**
2119
+ * Quote PT → USDT for the cashout preview screen.
2120
+ *
2121
+ * Three branches the FE needs distinct handling for:
2122
+ * - `pointAmount = 0` → all zeros, no RPC call.
2123
+ * - no pool / no path → `quoteError: 'QUOTE_UNAVAILABLE'`.
2124
+ * - amountOut < gas reimbursement → `quoteError: 'AMOUNT_TOO_SMALL_FOR_GAS'`.
2125
+ *
2126
+ * Returns derived `netUsdtOut`, `exchangeRate`, and a `suggestedDeadline`
2127
+ * so callers don't need to compute those locally.
2128
+ *
2129
+ * Replaces ~50 LoC of inline quote-handling in issuer controllers.
2130
+ */
2131
+ interface QuotePointTokenToUsdtParams {
2132
+ provider: PublicClient;
2133
+ chainId: number;
2134
+ pointTokenAddress: Address;
2135
+ pointAmount: bigint;
2136
+ pools: PoolKey[];
2137
+ /** Operator gas-reimbursement quoted in USDT (subtracted from output). */
2138
+ gasFeeUsdt: bigint;
2139
+ /** Override deadline window; default 300 seconds. */
2140
+ deadlineSeconds?: number;
2141
+ now?: () => number;
2142
+ }
2143
+ interface QuotePointTokenToUsdtResult {
2144
+ /** Raw V4 quote on the full point amount, before gas deduction. */
2145
+ estimatedUsdtOut: bigint;
2146
+ /** `estimatedUsdtOut - gasFeeUsdt`, clamped to 0. */
2147
+ netUsdtOut: bigint;
2148
+ /** USDT per 1.0 PT (1e18 raw units), formatted to 8 decimal places. */
2149
+ exchangeRate: string;
2150
+ /** V4 Quoter's gas estimate for the swap — informational. */
2151
+ gasEstimate: bigint;
2152
+ /** Unix seconds — `now + deadlineSeconds`. */
2153
+ suggestedDeadline: number;
2154
+ /** When set, the FE should hide the CTA / show "increase amount". */
2155
+ quoteError?: "QUOTE_UNAVAILABLE" | "AMOUNT_TOO_SMALL_FOR_GAS";
2156
+ }
2157
+ declare function quotePointTokenToUsdt(params: QuotePointTokenToUsdtParams): Promise<QuotePointTokenToUsdtResult>;
2158
+
2159
+ /**
2160
+ * Normalized HTTP status the issuer controller should surface for a
2161
+ * given SDK error. Kept to the three statuses every issuer needs —
2162
+ * `400/500/etc.` are not used because every SDK error already maps
2163
+ * cleanly into one of these three buckets.
2164
+ */
2165
+ type SdkErrorStatus = "not_found" | "unprocessable" | "service_unavailable";
2166
+ /**
2167
+ * Structured body the issuer controller passes to its
2168
+ * framework-specific exception class. Mirrors the shape every PAFI
2169
+ * issuer surfaces over HTTP today.
2170
+ */
2171
+ interface SdkErrorBody {
2172
+ code: string;
2173
+ message: string;
2174
+ details?: unknown;
2175
+ safeToRetry: boolean;
2176
+ }
2177
+ /**
2178
+ * Per-status exception factories. The issuer's controller wires one
2179
+ * factory per status to its preferred framework's exception class
2180
+ * (NestJS `UnprocessableEntityException`, Fastify `httpErrors.badData`,
2181
+ * etc). The factory must throw or return an Error — `createSdkErrorMapper`
2182
+ * uses `throw factory(body)` so either form is fine.
2183
+ */
2184
+ interface SdkErrorMapperFactories {
2185
+ notFound: (body: SdkErrorBody) => Error;
2186
+ unprocessable: (body: SdkErrorBody) => Error;
2187
+ serviceUnavailable: (body: SdkErrorBody) => Error;
2188
+ }
2189
+ /**
2190
+ * Build a single error-mapping function that converts any typed SDK
2191
+ * error into the issuer's framework-specific HTTP exception.
2192
+ *
2193
+ * - `PendingUserOpNotFoundError` → 404 (lock expired / already submitted)
2194
+ * - `BundlerNotConfiguredError` → 503 (PAFI backend client missing)
2195
+ * - `IssuerStateError` → 422 (cap exceeded / inactive)
2196
+ * - `PerpDepositError` → 422 (Orderly relay quote / broker)
2197
+ * - `PTClaimError`, `PTRedeemError`, `SwapError`, `BundlerRejectedError` → 422
2198
+ * - any other error → re-thrown as-is
2199
+ *
2200
+ * `safeToRetry` is `true` only for transient cases:
2201
+ * - `MINT_CAP_EXCEEDED` (cap may free up between requests)
2202
+ * - `RELAY_FEE_EXCEEDS_AMOUNT` (Orderly fee may drop)
2203
+ *
2204
+ * Usage (NestJS):
2205
+ *
2206
+ * ```ts
2207
+ * const mapSdkError = createSdkErrorMapper({
2208
+ * notFound: (body) => new NotFoundException(body),
2209
+ * unprocessable: (body) => new UnprocessableEntityException(body),
2210
+ * serviceUnavailable: (body) => new ServiceUnavailableException(body),
2211
+ * });
2212
+ *
2213
+ * try { ... } catch (err) { mapSdkError(err); }
2214
+ * ```
2215
+ *
2216
+ * Returns `never` so call sites in `try/catch` propagate the throw
2217
+ * without a redundant `throw` keyword.
2218
+ */
2219
+ declare function createSdkErrorMapper(factories: SdkErrorMapperFactories): (err: unknown) => never;
2220
+
2072
2221
  /**
2073
2222
  * Config for `createSubgraphPoolsProvider`.
2074
2223
  */
@@ -2593,4 +2742,4 @@ declare class IssuerStateValidator {
2593
2742
  /** SDK package version — bumped on every release */
2594
2743
  declare const PAFI_ISSUER_SDK_VERSION = "0.4.0";
2595
2744
 
2596
- 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, BundlerNotConfiguredError, BundlerRejectedError, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type CombinedBalance, DefaultPolicyEngine, type DefaultPolicyEngineOptions, FeeManager, type FeeManagerConfig, type HandleMobilePrepareParams, type HandleMobilePrepareResult, type HandleMobileSubmitParams, 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, PTClaimError, PTClaimHandler, type PTClaimHandlerConfig, type PTClaimRequest, type PTClaimResponse, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingCredit, type PendingUserOpEntry, PendingUserOpNotFoundError, PerpDepositError, PerpDepositHandler, type PerpDepositHandlerConfig, type PerpDepositRequest, type PerpDepositResponse, 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 RelayUserOpParams, type RelayUserOpRequest, type RelayUserOpResponse, type RequestPaymasterParams, type RetryConfig, type SerializedUserOpTypedData, type Session, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, SwapError, SwapHandler, type SwapHandlerConfig, type SwapRequest, type SwapResponse, TopUpRedemptionError, TopUpRedemptionHandler, type TopUpRedemptionHandlerConfig, type TopUpRedemptionRequest, type TopUpRedemptionResponse, authenticateRequest, createIssuerService, createNativePtQuoter, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, handleClaimStatus, handleMobilePrepare, handleMobileSubmit, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, relayUserOp, requestPaymaster, serializeEntryToJsonRpc, serializeUserOpTypedData };
2745
+ 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, BundlerNotConfiguredError, BundlerRejectedError, type BurnEvent, BurnIndexer, type BurnIndexerConfig, type BurnStatusParams, type BurnStatusResponse, type CombinedBalance, DefaultPolicyEngine, type DefaultPolicyEngineOptions, FeeManager, type FeeManagerConfig, type HandleDelegateSubmitParams, type HandleDelegateSubmitResult, type HandleMobilePrepareParams, type HandleMobilePrepareResult, type HandleMobileSubmitParams, 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, PTClaimError, PTClaimHandler, type PTClaimHandlerConfig, type PTClaimRequest, type PTClaimResponse, PTRedeemError, PTRedeemHandler, type PTRedeemHandlerConfig, type PTRedeemRequest, type PTRedeemResponse, PafiBackendClient, type PafiBackendConfig, PafiBackendError, type PafiBackendErrorCode, type PendingCredit, type PendingUserOpEntry, PendingUserOpNotFoundError, PerpDepositError, PerpDepositHandler, type PerpDepositHandlerConfig, type PerpDepositRequest, type PerpDepositResponse, 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, type QuotePointTokenToUsdtParams, type QuotePointTokenToUsdtResult, RelayError, type RelayErrorCode, RelayService, type RelayUserOpParams, type RelayUserOpRequest, type RelayUserOpResponse, type RequestPaymasterParams, type RetryConfig, type SdkErrorBody, type SdkErrorMapperFactories, type SdkErrorStatus, type SerializedUserOpTypedData, type Session, type SponsorshipRequest, type SponsorshipResponse, type SponsorshipTarget, type SponsorshipUserOp, type SubgraphNativeUsdtQuoterConfig, type SubgraphPoolsProviderConfig, SwapError, SwapHandler, type SwapHandlerConfig, type SwapRequest, type SwapResponse, TopUpRedemptionError, TopUpRedemptionHandler, type TopUpRedemptionHandlerConfig, type TopUpRedemptionRequest, type TopUpRedemptionResponse, authenticateRequest, createIssuerService, createNativePtQuoter, createSdkErrorMapper, createSubgraphNativeUsdtQuoter, createSubgraphPoolsProvider, handleClaimStatus, handleDelegateSubmit, handleMobilePrepare, handleMobileSubmit, handleRedeemStatus, mergePaymasterFields, prepareMobileUserOp, quotePointTokenToUsdt, relayUserOp, requestPaymaster, serializeEntryToJsonRpc, serializeUserOpTypedData };
package/dist/index.js CHANGED
@@ -2375,6 +2375,194 @@ var PerpDepositHandler = class {
2375
2375
  }
2376
2376
  };
2377
2377
 
2378
+ // src/api/delegateHandler.ts
2379
+ import {
2380
+ ENTRY_POINT_V08 as ENTRY_POINT_V082,
2381
+ buildEip7702Authorization,
2382
+ encodeBatchExecute,
2383
+ getContractAddresses as getContractAddresses5,
2384
+ serializeUserOpToJsonRpc as serializeUserOpToJsonRpc2
2385
+ } from "@pafi-dev/core";
2386
+ var DEFAULT_DELEGATE_GAS = {
2387
+ callGasLimit: 100000n,
2388
+ verificationGasLimit: 150000n,
2389
+ preVerificationGas: 50000n
2390
+ };
2391
+ async function handleDelegateSubmit(params) {
2392
+ const { batchExecutor } = getContractAddresses5(params.chainId);
2393
+ const callData = encodeBatchExecute([]);
2394
+ const userOp = {
2395
+ sender: params.userAddress,
2396
+ nonce: params.aaNonce,
2397
+ callData,
2398
+ callGasLimit: params.gasLimits?.callGasLimit ?? DEFAULT_DELEGATE_GAS.callGasLimit,
2399
+ verificationGasLimit: params.gasLimits?.verificationGasLimit ?? DEFAULT_DELEGATE_GAS.verificationGasLimit,
2400
+ preVerificationGas: params.gasLimits?.preVerificationGas ?? DEFAULT_DELEGATE_GAS.preVerificationGas,
2401
+ maxFeePerGas: params.fees.maxFeePerGas ?? 0n,
2402
+ maxPriorityFeePerGas: params.fees.maxPriorityFeePerGas ?? 0n
2403
+ };
2404
+ const paymasterFields = await requestPaymaster({
2405
+ client: params.pafiBackendClient,
2406
+ chainId: params.chainId,
2407
+ scenario: "delegate",
2408
+ userOp,
2409
+ pointTokenAddress: batchExecutor,
2410
+ onWarning: params.onWarning
2411
+ });
2412
+ const merged = {
2413
+ ...userOp,
2414
+ ...paymasterFields ?? {}
2415
+ };
2416
+ const userOpJson = serializeUserOpToJsonRpc2(
2417
+ {
2418
+ sender: merged.sender,
2419
+ nonce: merged.nonce,
2420
+ callData: merged.callData,
2421
+ callGasLimit: merged.callGasLimit,
2422
+ verificationGasLimit: merged.verificationGasLimit,
2423
+ preVerificationGas: merged.preVerificationGas,
2424
+ maxFeePerGas: merged.maxFeePerGas,
2425
+ maxPriorityFeePerGas: merged.maxPriorityFeePerGas,
2426
+ paymaster: paymasterFields?.paymaster,
2427
+ paymasterVerificationGasLimit: paymasterFields?.paymasterVerificationGasLimit,
2428
+ paymasterPostOpGasLimit: paymasterFields?.paymasterPostOpGasLimit,
2429
+ paymasterData: paymasterFields?.paymasterData
2430
+ },
2431
+ // Delegation UserOp is submitted unsigned — the EIP-7702 authorization
2432
+ // is the user's "consent"; no separate AA signature is needed.
2433
+ "0x"
2434
+ );
2435
+ const authorization = buildEip7702Authorization({
2436
+ chainId: params.chainId,
2437
+ address: batchExecutor,
2438
+ nonce: params.delegationNonce,
2439
+ authSig: params.authSig
2440
+ });
2441
+ const result = await relayUserOp({
2442
+ client: params.pafiBackendClient,
2443
+ userOp: userOpJson,
2444
+ entryPoint: ENTRY_POINT_V082,
2445
+ eip7702Auth: authorization
2446
+ });
2447
+ return {
2448
+ userOpHash: result.userOpHash,
2449
+ isSponsored: !!paymasterFields,
2450
+ authorization
2451
+ };
2452
+ }
2453
+
2454
+ // src/api/quoteHelper.ts
2455
+ import {
2456
+ findBestQuote as findBestQuote2,
2457
+ getContractAddresses as getContractAddresses6
2458
+ } from "@pafi-dev/core";
2459
+ var DEFAULT_DEADLINE_SECONDS = 300;
2460
+ async function quotePointTokenToUsdt(params) {
2461
+ const now = params.now ?? (() => Date.now());
2462
+ const suggestedDeadline = Math.floor(now() / 1e3) + (params.deadlineSeconds ?? DEFAULT_DEADLINE_SECONDS);
2463
+ if (params.pointAmount === 0n) {
2464
+ return {
2465
+ estimatedUsdtOut: 0n,
2466
+ netUsdtOut: 0n,
2467
+ exchangeRate: "0.00000000",
2468
+ gasEstimate: 0n,
2469
+ suggestedDeadline
2470
+ };
2471
+ }
2472
+ if (params.pools.length === 0) {
2473
+ return {
2474
+ estimatedUsdtOut: 0n,
2475
+ netUsdtOut: 0n,
2476
+ exchangeRate: "0.00000000",
2477
+ gasEstimate: 0n,
2478
+ suggestedDeadline,
2479
+ quoteError: "QUOTE_UNAVAILABLE"
2480
+ };
2481
+ }
2482
+ const { usdt: usdtAddress } = getContractAddresses6(params.chainId);
2483
+ let estimatedUsdtOut = 0n;
2484
+ let gasEstimate = 0n;
2485
+ try {
2486
+ const best = await findBestQuote2(
2487
+ params.provider,
2488
+ params.chainId,
2489
+ params.pointTokenAddress,
2490
+ usdtAddress,
2491
+ params.pointAmount,
2492
+ params.pools
2493
+ );
2494
+ estimatedUsdtOut = best.bestRoute.amountOut;
2495
+ gasEstimate = best.bestRoute.gasEstimate;
2496
+ } catch {
2497
+ return {
2498
+ estimatedUsdtOut: 0n,
2499
+ netUsdtOut: 0n,
2500
+ exchangeRate: "0.00000000",
2501
+ gasEstimate: 0n,
2502
+ suggestedDeadline,
2503
+ quoteError: "QUOTE_UNAVAILABLE"
2504
+ };
2505
+ }
2506
+ const netUsdtOut = estimatedUsdtOut > params.gasFeeUsdt ? estimatedUsdtOut - params.gasFeeUsdt : 0n;
2507
+ const quoteError = estimatedUsdtOut > 0n && netUsdtOut === 0n ? "AMOUNT_TOO_SMALL_FOR_GAS" : void 0;
2508
+ const rateNum = estimatedUsdtOut > 0n ? Number(
2509
+ estimatedUsdtOut * 1000000n * 10n ** 18n / params.pointAmount
2510
+ ) / 1e6 : 0;
2511
+ const exchangeRate = rateNum.toFixed(8);
2512
+ return {
2513
+ estimatedUsdtOut,
2514
+ netUsdtOut,
2515
+ exchangeRate,
2516
+ gasEstimate,
2517
+ suggestedDeadline,
2518
+ ...quoteError ? { quoteError } : {}
2519
+ };
2520
+ }
2521
+
2522
+ // src/api/errorMapper.ts
2523
+ function createSdkErrorMapper(factories) {
2524
+ return (err) => {
2525
+ if (err instanceof PendingUserOpNotFoundError) {
2526
+ throw factories.notFound({
2527
+ code: err.code,
2528
+ message: err.message,
2529
+ safeToRetry: false
2530
+ });
2531
+ }
2532
+ if (err instanceof BundlerNotConfiguredError) {
2533
+ throw factories.serviceUnavailable({
2534
+ code: err.code,
2535
+ message: err.message,
2536
+ safeToRetry: false
2537
+ });
2538
+ }
2539
+ if (err instanceof IssuerStateError) {
2540
+ throw factories.unprocessable({
2541
+ code: err.code,
2542
+ message: err.message,
2543
+ details: err.details,
2544
+ safeToRetry: err.code === "MINT_CAP_EXCEEDED"
2545
+ });
2546
+ }
2547
+ if (err instanceof PerpDepositError) {
2548
+ throw factories.unprocessable({
2549
+ code: err.code,
2550
+ message: err.message,
2551
+ safeToRetry: err.code === "RELAY_FEE_EXCEEDS_AMOUNT"
2552
+ });
2553
+ }
2554
+ if (err instanceof PTClaimError || err instanceof PTRedeemError || err instanceof SwapError || err instanceof BundlerRejectedError) {
2555
+ throw factories.unprocessable({
2556
+ code: err.code,
2557
+ message: err.message,
2558
+ details: "details" in err ? err.details : void 0,
2559
+ safeToRetry: false
2560
+ });
2561
+ }
2562
+ throw err;
2563
+ };
2564
+ }
2565
+
2378
2566
  // src/pools/subgraphPoolsProvider.ts
2379
2567
  import { isAddress } from "viem";
2380
2568
  import { PAFI_SUBGRAPH_URL } from "@pafi-dev/core";
@@ -2994,7 +3182,7 @@ var PafiBackendClient = class {
2994
3182
 
2995
3183
  // src/config.ts
2996
3184
  import { getAddress as getAddress9 } from "viem";
2997
- import { getContractAddresses as getContractAddresses5 } from "@pafi-dev/core";
3185
+ import { getContractAddresses as getContractAddresses7 } from "@pafi-dev/core";
2998
3186
  function createIssuerService(config) {
2999
3187
  if (!config.provider) {
3000
3188
  throw new Error("createIssuerService: provider is required");
@@ -3064,7 +3252,7 @@ function createIssuerService(config) {
3064
3252
  indexers.set(tokenAddress, new PointIndexer(indexerConfig));
3065
3253
  }
3066
3254
  const firstIndexer = indexers.get(tokenAddresses[0]);
3067
- const chainAddresses = getContractAddresses5(config.chainId);
3255
+ const chainAddresses = getContractAddresses7(config.chainId);
3068
3256
  const resolvedContracts = {
3069
3257
  batchExecutor: chainAddresses.batchExecutor,
3070
3258
  usdt: chainAddresses.usdt,
@@ -3116,7 +3304,7 @@ import { getAddress as getAddress10 } from "viem";
3116
3304
  import {
3117
3305
  POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI3,
3118
3306
  issuerRegistryGetIssuerFlatAbi,
3119
- getContractAddresses as getContractAddresses6
3307
+ getContractAddresses as getContractAddresses8
3120
3308
  } from "@pafi-dev/core";
3121
3309
  var ISSUER_RECORD_TTL_MS = 3e4;
3122
3310
  var IssuerStateValidator = class _IssuerStateValidator {
@@ -3134,7 +3322,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
3134
3322
  * `CONTRACT_ADDRESSES` map for the given chain.
3135
3323
  */
3136
3324
  static forChain(provider, chainId) {
3137
- const { issuerRegistry } = getContractAddresses6(chainId);
3325
+ const { issuerRegistry } = getContractAddresses8(chainId);
3138
3326
  return new _IssuerStateValidator(provider, issuerRegistry);
3139
3327
  }
3140
3328
  /**
@@ -3310,14 +3498,17 @@ export {
3310
3498
  authenticateRequest,
3311
3499
  createIssuerService,
3312
3500
  createNativePtQuoter,
3501
+ createSdkErrorMapper,
3313
3502
  createSubgraphNativeUsdtQuoter,
3314
3503
  createSubgraphPoolsProvider,
3315
3504
  handleClaimStatus,
3505
+ handleDelegateSubmit,
3316
3506
  handleMobilePrepare,
3317
3507
  handleMobileSubmit,
3318
3508
  handleRedeemStatus,
3319
3509
  mergePaymasterFields,
3320
3510
  prepareMobileUserOp,
3511
+ quotePointTokenToUsdt,
3321
3512
  relayUserOp,
3322
3513
  requestPaymaster,
3323
3514
  serializeEntryToJsonRpc,