@pafi-dev/core 0.7.0 → 0.7.1

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
@@ -100,6 +100,22 @@ declare class ApiError extends PafiSDKError {
100
100
  status?: number | undefined;
101
101
  constructor(message: string, status?: number | undefined);
102
102
  }
103
+ /**
104
+ * Thrown by `quoteOperatorFee*` when an upstream price source
105
+ * (Chainlink ETH/USD, PAFI subgraph) is unavailable or stale and the
106
+ * caller did not opt in to the hardcoded fallback prices.
107
+ *
108
+ * v0.7.1 — previously `quoteOperatorFeePt` silently fell back to
109
+ * ETH=$3000 / PT=$0.10 with `console.warn`. That caused mass
110
+ * `INSUFFICIENT_FEE` rejects during Chainlink incidents, or worse,
111
+ * accepted under-priced fees. Now opt-in via
112
+ * `allowStaleFallback: true`. See SDK_CORE_TRADING_AUDIT.md C2.
113
+ */
114
+ declare class OracleStaleError extends PafiSDKError {
115
+ readonly source: "chainlink" | "subgraph";
116
+ readonly reason: string;
117
+ constructor(source: "chainlink" | "subgraph", reason: string);
118
+ }
103
119
 
104
120
  /**
105
121
  * Orderly Network Vault — entrypoint for **perp deposit** flow on
@@ -1169,13 +1185,18 @@ interface SmartAccountSender {
1169
1185
  * Returns true when `err` originates from the **paymaster layer** rather
1170
1186
  * than the contract or bundler layer. Covers:
1171
1187
  *
1172
- * - ERC-4337 AA3x validation errors (AA31–AA34)
1173
- * - Pimlico sponsorship rejections (`pm_*` methods, "sponsorship" messages)
1174
- * - PAFI proxy HTTP errors (401, 403, 429, 503)
1188
+ * - ERC-4337 AA3x validation errors (AA31–AA34, word-boundary match)
1189
+ * - Pimlico sponsorship rejections (`pm_*` methods, "sponsorship" / "paymaster")
1190
+ * - PAFI proxy HTTP errors checked via typed `status` / `statusCode`
1191
+ * field when present, NOT substring match
1175
1192
  * - Generic "rate limit" / "unauthorized" strings
1176
1193
  *
1177
1194
  * Use this to decide whether retrying without a paymaster makes sense.
1178
1195
  * Contract reverts (AA23, AA24, AA25) and bundler errors are NOT matched.
1196
+ *
1197
+ * v0.7.1 — replaced naive substring matching that false-positived on
1198
+ * arbitrary text containing "503"/"403"/"429" (e.g. address/transit ID).
1199
+ * See SDK_CORE_TRADING_AUDIT.md C3.
1179
1200
  */
1180
1201
  declare function isPaymasterError(err: unknown): boolean;
1181
1202
  interface SendWithPaymasterFallbackParams {
@@ -1251,9 +1272,20 @@ interface QuoteOperatorFeePtConfig {
1251
1272
  subgraphUrl?: string;
1252
1273
  /** USDT token decimals. Default 6 (USDC/USDT on Base/Ethereum). */
1253
1274
  usdtDecimals?: number;
1254
- /** Fallback ETH price (USD) when Chainlink is unreachable. Default 3000. */
1275
+ /**
1276
+ * Opt-in fallback prices used when Chainlink / subgraph is
1277
+ * unavailable. Default `false` — throw `OracleStaleError`. Set
1278
+ * `true` AND configure `fallbackEthPriceUsd` / `fallbackPtPriceUsdt`
1279
+ * to absorb oracle outages instead of surfacing them.
1280
+ *
1281
+ * v0.7.1 — previously fallback was always-on with hardcoded
1282
+ * defaults (ETH=$3000, PT=$0.10), causing under-priced fees during
1283
+ * incidents. See SDK_CORE_TRADING_AUDIT.md C2.
1284
+ */
1285
+ allowStaleFallback?: boolean;
1286
+ /** Fallback ETH price (USD) when Chainlink is unreachable. Only used when `allowStaleFallback: true`. Default 3000. */
1255
1287
  fallbackEthPriceUsd?: number;
1256
- /** Fallback PT price (USDT per 1 PT) when subgraph is unreachable. Default 0.1. */
1288
+ /** Fallback PT price (USDT per 1 PT) when subgraph is unreachable. Only used when `allowStaleFallback: true`. Default 0.1. */
1257
1289
  fallbackPtPriceUsdt?: number;
1258
1290
  fetchImpl?: typeof fetch;
1259
1291
  }
@@ -1270,6 +1302,11 @@ interface QuoteOperatorFeeUsdtConfig {
1270
1302
  premiumBps?: number;
1271
1303
  chainlinkFeedAddress?: Address;
1272
1304
  usdtDecimals?: number;
1305
+ /**
1306
+ * Opt-in fallback price when Chainlink is unavailable. Default
1307
+ * `false` — throw `OracleStaleError`. v0.7.1 — see C2.
1308
+ */
1309
+ allowStaleFallback?: boolean;
1273
1310
  fallbackEthPriceUsd?: number;
1274
1311
  }
1275
1312
  /**
@@ -1713,4 +1750,4 @@ declare class PafiSDK {
1713
1750
  signLoginMessage(message: string): Promise<Hex>;
1714
1751
  }
1715
1752
 
1716
- export { ApiError, BATCH_EXECUTOR_7702_IMPL, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, type BuildDelegationUserOpParams, type BuildPartialUserOpParams, type BuildPerpDepositViaRelayParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, DUMMY_SIGNATURE_V07, type DelegateImpl, EIP712Signature, ENTRY_POINT_V07, ENTRY_POINT_V08, type Eip7702AuthorizationJsonRpc, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_RELAY_ABI, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, type Operation, type OrderlyRelayDepositRequest, PAFI_SUBGRAPH_URL, PERMIT2_ADDRESS, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, type PackedUserOperationMessage, type PafiProxyTransportParams, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, type PartialUserOperation, type PaymasterConfig, type PaymasterFields, PointTokenDomainConfig, PoolKey, type QuoteOperatorFeePtConfig, type QuoteOperatorFeeUsdtConfig, ReceiverConsent, SIMPLE_7702_IMPL_BASE_MAINNET, SUPPORTED_CHAINS, type SendWithPaymasterFallbackParams, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SmartAccountSender, type SponsorshipScenario, type SubmissionPath, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, type UserOpReceipt, type UserOpTypedData, type UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, ZERO_VALUE, _resetPaymasterConfigForTests, assembleUserOperation, buildDelegationUserOp, buildEip7702Authorization, buildPartialUserOperation, buildPerpDepositViaRelay, buildPerpDepositWithGasDeduction, buildUserOpTypedData, burnRequestTypes, checkDelegation, checkEthAndBranch, computeAccountId, computeAuthorizationHash, computeUserOpHash, createPafiProxyTransport, decodeBatchExecuteCalls, detectDelegateImpl, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, fetchPafiPools, getAaNonce, getContractAddresses, getDummySignatureFor7702, getPafiWebModalAdapter, getPaymasterConfig, isDelegatedTo, isDelegatedToTarget, isPaymasterConfigured, isPaymasterError, mintRequestTypes, openPafiWebModal, openWebPopup, parseEip7702DelegatedAddress, quoteOperatorFeePt, quoteOperatorFeeUsdt, rawCallOp, receiverConsentTypes, sendWithPaymasterFallback, serializeUserOpToJsonRpc, setPafiWebModalAdapter, setPaymasterConfig, splitAuthorizationSig, webPopupAdapter };
1753
+ export { ApiError, BATCH_EXECUTOR_7702_IMPL, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, type BuildDelegationUserOpParams, type BuildPartialUserOpParams, type BuildPerpDepositViaRelayParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, DUMMY_SIGNATURE_V07, type DelegateImpl, EIP712Signature, ENTRY_POINT_V07, ENTRY_POINT_V08, type Eip7702AuthorizationJsonRpc, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_RELAY_ABI, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, type Operation, OracleStaleError, type OrderlyRelayDepositRequest, PAFI_SUBGRAPH_URL, PERMIT2_ADDRESS, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, type PackedUserOperationMessage, type PafiProxyTransportParams, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, type PartialUserOperation, type PaymasterConfig, type PaymasterFields, PointTokenDomainConfig, PoolKey, type QuoteOperatorFeePtConfig, type QuoteOperatorFeeUsdtConfig, ReceiverConsent, SIMPLE_7702_IMPL_BASE_MAINNET, SUPPORTED_CHAINS, type SendWithPaymasterFallbackParams, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SmartAccountSender, type SponsorshipScenario, type SubmissionPath, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, type UserOpReceipt, type UserOpTypedData, type UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, ZERO_VALUE, _resetPaymasterConfigForTests, assembleUserOperation, buildDelegationUserOp, buildEip7702Authorization, buildPartialUserOperation, buildPerpDepositViaRelay, buildPerpDepositWithGasDeduction, buildUserOpTypedData, burnRequestTypes, checkDelegation, checkEthAndBranch, computeAccountId, computeAuthorizationHash, computeUserOpHash, createPafiProxyTransport, decodeBatchExecuteCalls, detectDelegateImpl, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, fetchPafiPools, getAaNonce, getContractAddresses, getDummySignatureFor7702, getPafiWebModalAdapter, getPaymasterConfig, isDelegatedTo, isDelegatedToTarget, isPaymasterConfigured, isPaymasterError, mintRequestTypes, openPafiWebModal, openWebPopup, parseEip7702DelegatedAddress, quoteOperatorFeePt, quoteOperatorFeeUsdt, rawCallOp, receiverConsentTypes, sendWithPaymasterFallback, serializeUserOpToJsonRpc, setPafiWebModalAdapter, setPaymasterConfig, splitAuthorizationSig, webPopupAdapter };
package/dist/index.d.ts CHANGED
@@ -100,6 +100,22 @@ declare class ApiError extends PafiSDKError {
100
100
  status?: number | undefined;
101
101
  constructor(message: string, status?: number | undefined);
102
102
  }
103
+ /**
104
+ * Thrown by `quoteOperatorFee*` when an upstream price source
105
+ * (Chainlink ETH/USD, PAFI subgraph) is unavailable or stale and the
106
+ * caller did not opt in to the hardcoded fallback prices.
107
+ *
108
+ * v0.7.1 — previously `quoteOperatorFeePt` silently fell back to
109
+ * ETH=$3000 / PT=$0.10 with `console.warn`. That caused mass
110
+ * `INSUFFICIENT_FEE` rejects during Chainlink incidents, or worse,
111
+ * accepted under-priced fees. Now opt-in via
112
+ * `allowStaleFallback: true`. See SDK_CORE_TRADING_AUDIT.md C2.
113
+ */
114
+ declare class OracleStaleError extends PafiSDKError {
115
+ readonly source: "chainlink" | "subgraph";
116
+ readonly reason: string;
117
+ constructor(source: "chainlink" | "subgraph", reason: string);
118
+ }
103
119
 
104
120
  /**
105
121
  * Orderly Network Vault — entrypoint for **perp deposit** flow on
@@ -1169,13 +1185,18 @@ interface SmartAccountSender {
1169
1185
  * Returns true when `err` originates from the **paymaster layer** rather
1170
1186
  * than the contract or bundler layer. Covers:
1171
1187
  *
1172
- * - ERC-4337 AA3x validation errors (AA31–AA34)
1173
- * - Pimlico sponsorship rejections (`pm_*` methods, "sponsorship" messages)
1174
- * - PAFI proxy HTTP errors (401, 403, 429, 503)
1188
+ * - ERC-4337 AA3x validation errors (AA31–AA34, word-boundary match)
1189
+ * - Pimlico sponsorship rejections (`pm_*` methods, "sponsorship" / "paymaster")
1190
+ * - PAFI proxy HTTP errors checked via typed `status` / `statusCode`
1191
+ * field when present, NOT substring match
1175
1192
  * - Generic "rate limit" / "unauthorized" strings
1176
1193
  *
1177
1194
  * Use this to decide whether retrying without a paymaster makes sense.
1178
1195
  * Contract reverts (AA23, AA24, AA25) and bundler errors are NOT matched.
1196
+ *
1197
+ * v0.7.1 — replaced naive substring matching that false-positived on
1198
+ * arbitrary text containing "503"/"403"/"429" (e.g. address/transit ID).
1199
+ * See SDK_CORE_TRADING_AUDIT.md C3.
1179
1200
  */
1180
1201
  declare function isPaymasterError(err: unknown): boolean;
1181
1202
  interface SendWithPaymasterFallbackParams {
@@ -1251,9 +1272,20 @@ interface QuoteOperatorFeePtConfig {
1251
1272
  subgraphUrl?: string;
1252
1273
  /** USDT token decimals. Default 6 (USDC/USDT on Base/Ethereum). */
1253
1274
  usdtDecimals?: number;
1254
- /** Fallback ETH price (USD) when Chainlink is unreachable. Default 3000. */
1275
+ /**
1276
+ * Opt-in fallback prices used when Chainlink / subgraph is
1277
+ * unavailable. Default `false` — throw `OracleStaleError`. Set
1278
+ * `true` AND configure `fallbackEthPriceUsd` / `fallbackPtPriceUsdt`
1279
+ * to absorb oracle outages instead of surfacing them.
1280
+ *
1281
+ * v0.7.1 — previously fallback was always-on with hardcoded
1282
+ * defaults (ETH=$3000, PT=$0.10), causing under-priced fees during
1283
+ * incidents. See SDK_CORE_TRADING_AUDIT.md C2.
1284
+ */
1285
+ allowStaleFallback?: boolean;
1286
+ /** Fallback ETH price (USD) when Chainlink is unreachable. Only used when `allowStaleFallback: true`. Default 3000. */
1255
1287
  fallbackEthPriceUsd?: number;
1256
- /** Fallback PT price (USDT per 1 PT) when subgraph is unreachable. Default 0.1. */
1288
+ /** Fallback PT price (USDT per 1 PT) when subgraph is unreachable. Only used when `allowStaleFallback: true`. Default 0.1. */
1257
1289
  fallbackPtPriceUsdt?: number;
1258
1290
  fetchImpl?: typeof fetch;
1259
1291
  }
@@ -1270,6 +1302,11 @@ interface QuoteOperatorFeeUsdtConfig {
1270
1302
  premiumBps?: number;
1271
1303
  chainlinkFeedAddress?: Address;
1272
1304
  usdtDecimals?: number;
1305
+ /**
1306
+ * Opt-in fallback price when Chainlink is unavailable. Default
1307
+ * `false` — throw `OracleStaleError`. v0.7.1 — see C2.
1308
+ */
1309
+ allowStaleFallback?: boolean;
1273
1310
  fallbackEthPriceUsd?: number;
1274
1311
  }
1275
1312
  /**
@@ -1713,4 +1750,4 @@ declare class PafiSDK {
1713
1750
  signLoginMessage(message: string): Promise<Hex>;
1714
1751
  }
1715
1752
 
1716
- export { ApiError, BATCH_EXECUTOR_7702_IMPL, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, type BuildDelegationUserOpParams, type BuildPartialUserOpParams, type BuildPerpDepositViaRelayParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, DUMMY_SIGNATURE_V07, type DelegateImpl, EIP712Signature, ENTRY_POINT_V07, ENTRY_POINT_V08, type Eip7702AuthorizationJsonRpc, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_RELAY_ABI, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, type Operation, type OrderlyRelayDepositRequest, PAFI_SUBGRAPH_URL, PERMIT2_ADDRESS, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, type PackedUserOperationMessage, type PafiProxyTransportParams, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, type PartialUserOperation, type PaymasterConfig, type PaymasterFields, PointTokenDomainConfig, PoolKey, type QuoteOperatorFeePtConfig, type QuoteOperatorFeeUsdtConfig, ReceiverConsent, SIMPLE_7702_IMPL_BASE_MAINNET, SUPPORTED_CHAINS, type SendWithPaymasterFallbackParams, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SmartAccountSender, type SponsorshipScenario, type SubmissionPath, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, type UserOpReceipt, type UserOpTypedData, type UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, ZERO_VALUE, _resetPaymasterConfigForTests, assembleUserOperation, buildDelegationUserOp, buildEip7702Authorization, buildPartialUserOperation, buildPerpDepositViaRelay, buildPerpDepositWithGasDeduction, buildUserOpTypedData, burnRequestTypes, checkDelegation, checkEthAndBranch, computeAccountId, computeAuthorizationHash, computeUserOpHash, createPafiProxyTransport, decodeBatchExecuteCalls, detectDelegateImpl, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, fetchPafiPools, getAaNonce, getContractAddresses, getDummySignatureFor7702, getPafiWebModalAdapter, getPaymasterConfig, isDelegatedTo, isDelegatedToTarget, isPaymasterConfigured, isPaymasterError, mintRequestTypes, openPafiWebModal, openWebPopup, parseEip7702DelegatedAddress, quoteOperatorFeePt, quoteOperatorFeeUsdt, rawCallOp, receiverConsentTypes, sendWithPaymasterFallback, serializeUserOpToJsonRpc, setPafiWebModalAdapter, setPaymasterConfig, splitAuthorizationSig, webPopupAdapter };
1753
+ export { ApiError, BATCH_EXECUTOR_7702_IMPL, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, type BuildDelegationUserOpParams, type BuildPartialUserOpParams, type BuildPerpDepositViaRelayParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, DUMMY_SIGNATURE_V07, type DelegateImpl, EIP712Signature, ENTRY_POINT_V07, ENTRY_POINT_V08, type Eip7702AuthorizationJsonRpc, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_RELAY_ABI, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, type Operation, OracleStaleError, type OrderlyRelayDepositRequest, PAFI_SUBGRAPH_URL, PERMIT2_ADDRESS, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, type PackedUserOperationMessage, type PafiProxyTransportParams, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, type PartialUserOperation, type PaymasterConfig, type PaymasterFields, PointTokenDomainConfig, PoolKey, type QuoteOperatorFeePtConfig, type QuoteOperatorFeeUsdtConfig, ReceiverConsent, SIMPLE_7702_IMPL_BASE_MAINNET, SUPPORTED_CHAINS, type SendWithPaymasterFallbackParams, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SmartAccountSender, type SponsorshipScenario, type SubmissionPath, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, type UserOpReceipt, type UserOpTypedData, type UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, ZERO_VALUE, _resetPaymasterConfigForTests, assembleUserOperation, buildDelegationUserOp, buildEip7702Authorization, buildPartialUserOperation, buildPerpDepositViaRelay, buildPerpDepositWithGasDeduction, buildUserOpTypedData, burnRequestTypes, checkDelegation, checkEthAndBranch, computeAccountId, computeAuthorizationHash, computeUserOpHash, createPafiProxyTransport, decodeBatchExecuteCalls, detectDelegateImpl, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, fetchPafiPools, getAaNonce, getContractAddresses, getDummySignatureFor7702, getPafiWebModalAdapter, getPaymasterConfig, isDelegatedTo, isDelegatedToTarget, isPaymasterConfigured, isPaymasterError, mintRequestTypes, openPafiWebModal, openWebPopup, parseEip7702DelegatedAddress, quoteOperatorFeePt, quoteOperatorFeeUsdt, rawCallOp, receiverConsentTypes, sendWithPaymasterFallback, serializeUserOpToJsonRpc, setPafiWebModalAdapter, setPaymasterConfig, splitAuthorizationSig, webPopupAdapter };
package/dist/index.js CHANGED
@@ -102,6 +102,16 @@ var ApiError = class extends PafiSDKError {
102
102
  }
103
103
  status;
104
104
  };
105
+ var OracleStaleError = class extends PafiSDKError {
106
+ source;
107
+ reason;
108
+ constructor(source, reason) {
109
+ super(`Oracle ${source} unavailable: ${reason}`);
110
+ this.name = "OracleStaleError";
111
+ this.source = source;
112
+ this.reason = reason;
113
+ }
114
+ };
105
115
 
106
116
  // src/perp/buildPerpDepositWithGasDeduction.ts
107
117
  import { encodeFunctionData as encodeFunctionData3 } from "viem";
@@ -594,11 +604,9 @@ function parseEip7702DelegatedAddress(code) {
594
604
  if (!code || code === "0x" || code === "0x0") return null;
595
605
  const normalized = code.toLowerCase();
596
606
  const magic = EIP7702_MAGIC.toLowerCase();
597
- const idx = normalized.indexOf(magic);
598
- if (idx === -1) return null;
599
- const raw = normalized.slice(idx + magic.length, idx + magic.length + 40);
600
- if (raw.length !== 40) return null;
601
- return `0x${raw}`;
607
+ if (!normalized.startsWith(magic)) return null;
608
+ if (normalized.length !== magic.length + 40) return null;
609
+ return `0x${normalized.slice(magic.length)}`;
602
610
  }
603
611
  async function checkDelegation(client, address) {
604
612
  const code = await client.getCode({ address });
@@ -727,9 +735,24 @@ function createPafiProxyTransport(params) {
727
735
  }
728
736
 
729
737
  // src/transport/paymasterFallback.ts
738
+ var PAYMASTER_HTTP_STATUSES = /* @__PURE__ */ new Set([401, 403, 429, 503]);
739
+ var PAYMASTER_PATTERNS = [
740
+ /\bAA3[1-4]\b/i,
741
+ /\bpaymaster\b/i,
742
+ /\bsponsorship\b/i,
743
+ /\bpm_\w+/i,
744
+ /\brate ?limit\b/i,
745
+ /\bunauthorized\b/i
746
+ ];
730
747
  function isPaymasterError(err) {
731
- const msg = (err?.message ?? String(err)).toLowerCase();
732
- return msg.includes("paymaster") || msg.includes("sponsorship") || msg.includes("aa31") || msg.includes("aa32") || msg.includes("aa33") || msg.includes("aa34") || msg.includes("pm_") || msg.includes("rate limit") || msg.includes("unauthorized") || msg.includes("403") || msg.includes("429") || msg.includes("503");
748
+ if (err == null || typeof err !== "object") return false;
749
+ const e = err;
750
+ const status = e.status ?? e.statusCode ?? e.response?.status ?? e.cause?.status;
751
+ if (typeof status === "number" && PAYMASTER_HTTP_STATUSES.has(status)) {
752
+ return true;
753
+ }
754
+ const msg = e.message ?? String(err);
755
+ return PAYMASTER_PATTERNS.some((re) => re.test(msg));
733
756
  }
734
757
  async function sendWithPaymasterFallback(params) {
735
758
  const { primaryClient, fallbackClient, txParams, txParamsFallback, onFallback } = params;
@@ -899,6 +922,7 @@ async function quoteOperatorFeeUsdt(config) {
899
922
  gasUnits = DEFAULT_GAS_UNITS,
900
923
  premiumBps = DEFAULT_PREMIUM_BPS,
901
924
  usdtDecimals = DEFAULT_USDT_DECIMALS,
925
+ allowStaleFallback = false,
902
926
  fallbackEthPriceUsd = 3e3
903
927
  } = config;
904
928
  const chainlinkFeedAddress = config.chainlinkFeedAddress ?? getContractAddresses(chainId).chainlinkEthUsd;
@@ -908,7 +932,7 @@ async function quoteOperatorFeeUsdt(config) {
908
932
  const ethPrice8dec = await getEthPrice8dec(
909
933
  provider,
910
934
  chainlinkFeedAddress,
911
- fallbackEthPriceUsd
935
+ allowStaleFallback ? fallbackEthPriceUsd : null
912
936
  );
913
937
  const denomExp = 18 + 8 - usdtDecimals;
914
938
  return withPremium * ethPrice8dec / 10n ** BigInt(denomExp);
@@ -922,6 +946,7 @@ async function quoteOperatorFeePt(config) {
922
946
  premiumBps = DEFAULT_PREMIUM_BPS,
923
947
  subgraphUrl = PAFI_SUBGRAPH_URL,
924
948
  usdtDecimals = DEFAULT_USDT_DECIMALS,
949
+ allowStaleFallback = false,
925
950
  fallbackEthPriceUsd = 3e3,
926
951
  fallbackPtPriceUsdt = 0.1,
927
952
  fetchImpl = globalThis.fetch
@@ -931,12 +956,16 @@ async function quoteOperatorFeePt(config) {
931
956
  const nativeCost = gasPrice * gasUnits;
932
957
  const withPremium = nativeCost * BigInt(premiumBps) / 10000n;
933
958
  const [ethPrice8dec, ptPerUsdt18dec] = await Promise.all([
934
- getEthPrice8dec(provider, chainlinkFeedAddress, fallbackEthPriceUsd),
959
+ getEthPrice8dec(
960
+ provider,
961
+ chainlinkFeedAddress,
962
+ allowStaleFallback ? fallbackEthPriceUsd : null
963
+ ),
935
964
  getPtPerUsdt18dec(
936
965
  fetchImpl,
937
966
  subgraphUrl,
938
967
  pointTokenAddress,
939
- fallbackPtPriceUsdt
968
+ allowStaleFallback ? fallbackPtPriceUsdt : null
940
969
  )
941
970
  ]);
942
971
  return withPremium * ethPrice8dec * ptPerUsdt18dec / 10n ** 26n;
@@ -957,9 +986,13 @@ async function getEthPrice8dec(provider, feed, fallback) {
957
986
  }
958
987
  return answer;
959
988
  } catch (err) {
989
+ const reason = err instanceof Error ? err.message : String(err);
990
+ if (fallback === null) {
991
+ throw new OracleStaleError("chainlink", reason);
992
+ }
960
993
  console.warn(
961
- "[quoteOperatorFeePt] Chainlink unavailable, using fallback:",
962
- err.message
994
+ "[quoteOperatorFee] Chainlink unavailable, using opt-in fallback:",
995
+ reason
963
996
  );
964
997
  return BigInt(Math.round(fallback * 1e8));
965
998
  }
@@ -992,9 +1025,13 @@ async function getPtPerUsdt18dec(fetchImpl, subgraphUrl, pointTokenAddress, fall
992
1025
  }
993
1026
  return 10n ** 24n / raw;
994
1027
  } catch (err) {
1028
+ const reason = err instanceof Error ? err.message : String(err);
1029
+ if (fallbackPtPriceUsdt === null) {
1030
+ throw new OracleStaleError("subgraph", reason);
1031
+ }
995
1032
  console.warn(
996
- "[quoteOperatorFeePt] subgraph unavailable, using fallback:",
997
- err.message
1033
+ "[quoteOperatorFeePt] subgraph unavailable, using opt-in fallback:",
1034
+ reason
998
1035
  );
999
1036
  const ptPerUsdtHuman = 1 / fallbackPtPriceUsdt;
1000
1037
  return parseBigDecimalTo18(ptPerUsdtHuman.toFixed(18));
@@ -1307,6 +1344,7 @@ export {
1307
1344
  ORDERLY_VAULT_ABI,
1308
1345
  ORDERLY_VAULT_ADDRESSES,
1309
1346
  ORDERLY_VAULT_BASE_MAINNET,
1347
+ OracleStaleError,
1310
1348
  PAFI_SUBGRAPH_URL,
1311
1349
  PERMIT2_ADDRESS,
1312
1350
  POINT_TOKEN_FACTORY_ADDRESSES,