@pooflabs/web 0.0.76 → 0.0.78

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.
Files changed (66) hide show
  1. package/README.md +32 -0
  2. package/dist/{index-COMIXUxl.js → index-CKaaE12K.js} +2 -2
  3. package/dist/{index-COMIXUxl.js.map → index-CKaaE12K.js.map} +1 -1
  4. package/dist/{index-Dsh0H37n.esm.js → index-Cmu0PVJD.esm.js} +2 -2
  5. package/dist/{index-Dsh0H37n.esm.js.map → index-Cmu0PVJD.esm.js.map} +1 -1
  6. package/dist/{index-BrlvWT1Q.js → index-Cp727oEW.js} +450 -23
  7. package/dist/index-Cp727oEW.js.map +1 -0
  8. package/dist/{index-C5Cnn7Hq.esm.js → index-CwGoYY0Y.esm.js} +450 -24
  9. package/dist/index-CwGoYY0Y.esm.js.map +1 -0
  10. package/dist/{index-BilNgDSc.js → index-DE7k2G22.js} +2 -2
  11. package/dist/{index-BilNgDSc.js.map → index-DE7k2G22.js.map} +1 -1
  12. package/dist/{index-DeVykeX4.esm.js → index-OAJ0rndN.esm.js} +2 -2
  13. package/dist/{index-DeVykeX4.esm.js.map → index-OAJ0rndN.esm.js.map} +1 -1
  14. package/dist/{index.browser-CMO2pjaF.js → index.browser-AZQ5TnZ4.js} +3 -3
  15. package/dist/{index.browser-CMO2pjaF.js.map → index.browser-AZQ5TnZ4.js.map} +1 -1
  16. package/dist/{index.browser-CSTWylhG.esm.js → index.browser-B4een3Gz.esm.js} +3 -3
  17. package/dist/{index.browser-CSTWylhG.esm.js.map → index.browser-B4een3Gz.esm.js.map} +1 -1
  18. package/dist/index.browser-BMtEulGJ.js +122 -0
  19. package/dist/index.browser-BMtEulGJ.js.map +1 -0
  20. package/dist/{index.browser-DZjyUgtx.esm.js → index.browser-C-_FEr5M.esm.js} +449 -479
  21. package/dist/index.browser-C-_FEr5M.esm.js.map +1 -0
  22. package/dist/index.browser-DFeGGyO7.esm.js +1250 -0
  23. package/dist/index.browser-DFeGGyO7.esm.js.map +1 -0
  24. package/dist/{index.browser-BOJRGZWX.js → index.browser-DjEZSiqI.js} +449 -479
  25. package/dist/index.browser-DjEZSiqI.js.map +1 -0
  26. package/dist/index.browser-QPkAiPQp.js +1253 -0
  27. package/dist/index.browser-QPkAiPQp.js.map +1 -0
  28. package/dist/index.browser-x87QUr4N.esm.js +119 -0
  29. package/dist/index.browser-x87QUr4N.esm.js.map +1 -0
  30. package/dist/index.esm.js +1 -1
  31. package/dist/index.js +2 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/{index.native-H-fEcP_L.esm.js → index.native-CjEJXA9y.esm.js} +450 -24
  34. package/dist/index.native-CjEJXA9y.esm.js.map +1 -0
  35. package/dist/{index.native-CkUXrvPQ.js → index.native-D7IrIMX1.js} +450 -23
  36. package/dist/index.native-D7IrIMX1.js.map +1 -0
  37. package/dist/index.native.esm.js +1 -1
  38. package/dist/index.native.js +2 -1
  39. package/dist/index.native.js.map +1 -1
  40. package/dist/{phantom-wallet-provider-5IQi4ihD.esm.js → phantom-wallet-provider-B1TleWsy.esm.js} +3 -3
  41. package/dist/{phantom-wallet-provider-5IQi4ihD.esm.js.map → phantom-wallet-provider-B1TleWsy.esm.js.map} +1 -1
  42. package/dist/{phantom-wallet-provider-DrNrxSUL.js → phantom-wallet-provider-DwmdHVd-.js} +3 -3
  43. package/dist/{phantom-wallet-provider-DrNrxSUL.js.map → phantom-wallet-provider-DwmdHVd-.js.map} +1 -1
  44. package/dist/{privy-wallet-provider-BtLH1dpY.esm.js → privy-wallet-provider-CZgiUwUN.esm.js} +3 -3
  45. package/dist/{privy-wallet-provider-BtLH1dpY.esm.js.map → privy-wallet-provider-CZgiUwUN.esm.js.map} +1 -1
  46. package/dist/{privy-wallet-provider-CrRfcONv.js → privy-wallet-provider-Cf6WgpK1.js} +3 -3
  47. package/dist/{privy-wallet-provider-CrRfcONv.js.map → privy-wallet-provider-Cf6WgpK1.js.map} +1 -1
  48. package/dist/{solana-mobile-wallet-provider-C3l6mxSm.esm.js → solana-mobile-wallet-provider-C9j8O3mD.esm.js} +3 -3
  49. package/dist/{solana-mobile-wallet-provider-C3l6mxSm.esm.js.map → solana-mobile-wallet-provider-C9j8O3mD.esm.js.map} +1 -1
  50. package/dist/{solana-mobile-wallet-provider-QcGazewW.js → solana-mobile-wallet-provider-DZmpeNIS.js} +3 -3
  51. package/dist/{solana-mobile-wallet-provider-QcGazewW.js.map → solana-mobile-wallet-provider-DZmpeNIS.js.map} +1 -1
  52. package/package.json +2 -2
  53. package/dist/index-BrlvWT1Q.js.map +0 -1
  54. package/dist/index-C5Cnn7Hq.esm.js.map +0 -1
  55. package/dist/index.browser--rDwfvXH.esm.js +0 -307
  56. package/dist/index.browser--rDwfvXH.esm.js.map +0 -1
  57. package/dist/index.browser-BOJRGZWX.js.map +0 -1
  58. package/dist/index.browser-CLZv9v_y.js +0 -310
  59. package/dist/index.browser-CLZv9v_y.js.map +0 -1
  60. package/dist/index.browser-DQKnuR3q.esm.js +0 -1468
  61. package/dist/index.browser-DQKnuR3q.esm.js.map +0 -1
  62. package/dist/index.browser-DZjyUgtx.esm.js.map +0 -1
  63. package/dist/index.browser-DqO3G-HJ.js +0 -1471
  64. package/dist/index.browser-DqO3G-HJ.js.map +0 -1
  65. package/dist/index.native-CkUXrvPQ.js.map +0 -1
  66. package/dist/index.native-H-fEcP_L.esm.js.map +0 -1
@@ -6379,6 +6379,261 @@ var ReconnectingWebSocket = /** @class */ (function () {
6379
6379
  return ReconnectingWebSocket;
6380
6380
  }());
6381
6381
 
6382
+ function getDefaultExportFromCjs (x) {
6383
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
6384
+ }
6385
+
6386
+ var isRetryAllowed$1;
6387
+ var hasRequiredIsRetryAllowed;
6388
+
6389
+ function requireIsRetryAllowed () {
6390
+ if (hasRequiredIsRetryAllowed) return isRetryAllowed$1;
6391
+ hasRequiredIsRetryAllowed = 1;
6392
+
6393
+ const denyList = new Set([
6394
+ 'ENOTFOUND',
6395
+ 'ENETUNREACH',
6396
+
6397
+ // SSL errors from https://github.com/nodejs/node/blob/fc8e3e2cdc521978351de257030db0076d79e0ab/src/crypto/crypto_common.cc#L301-L328
6398
+ 'UNABLE_TO_GET_ISSUER_CERT',
6399
+ 'UNABLE_TO_GET_CRL',
6400
+ 'UNABLE_TO_DECRYPT_CERT_SIGNATURE',
6401
+ 'UNABLE_TO_DECRYPT_CRL_SIGNATURE',
6402
+ 'UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY',
6403
+ 'CERT_SIGNATURE_FAILURE',
6404
+ 'CRL_SIGNATURE_FAILURE',
6405
+ 'CERT_NOT_YET_VALID',
6406
+ 'CERT_HAS_EXPIRED',
6407
+ 'CRL_NOT_YET_VALID',
6408
+ 'CRL_HAS_EXPIRED',
6409
+ 'ERROR_IN_CERT_NOT_BEFORE_FIELD',
6410
+ 'ERROR_IN_CERT_NOT_AFTER_FIELD',
6411
+ 'ERROR_IN_CRL_LAST_UPDATE_FIELD',
6412
+ 'ERROR_IN_CRL_NEXT_UPDATE_FIELD',
6413
+ 'OUT_OF_MEM',
6414
+ 'DEPTH_ZERO_SELF_SIGNED_CERT',
6415
+ 'SELF_SIGNED_CERT_IN_CHAIN',
6416
+ 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY',
6417
+ 'UNABLE_TO_VERIFY_LEAF_SIGNATURE',
6418
+ 'CERT_CHAIN_TOO_LONG',
6419
+ 'CERT_REVOKED',
6420
+ 'INVALID_CA',
6421
+ 'PATH_LENGTH_EXCEEDED',
6422
+ 'INVALID_PURPOSE',
6423
+ 'CERT_UNTRUSTED',
6424
+ 'CERT_REJECTED',
6425
+ 'HOSTNAME_MISMATCH'
6426
+ ]);
6427
+
6428
+ // TODO: Use `error?.code` when targeting Node.js 14
6429
+ isRetryAllowed$1 = error => !denyList.has(error && error.code);
6430
+ return isRetryAllowed$1;
6431
+ }
6432
+
6433
+ var isRetryAllowedExports = requireIsRetryAllowed();
6434
+ var isRetryAllowed = /*@__PURE__*/getDefaultExportFromCjs(isRetryAllowedExports);
6435
+
6436
+ const namespace = 'axios-retry';
6437
+ function isNetworkError(error) {
6438
+ const CODE_EXCLUDE_LIST = ['ERR_CANCELED', 'ECONNABORTED'];
6439
+ if (error.response) {
6440
+ return false;
6441
+ }
6442
+ if (!error.code) {
6443
+ return false;
6444
+ }
6445
+ // Prevents retrying timed out & cancelled requests
6446
+ if (CODE_EXCLUDE_LIST.includes(error.code)) {
6447
+ return false;
6448
+ }
6449
+ // Prevents retrying unsafe errors
6450
+ return isRetryAllowed(error);
6451
+ }
6452
+ const SAFE_HTTP_METHODS = ['get', 'head', 'options'];
6453
+ const IDEMPOTENT_HTTP_METHODS = SAFE_HTTP_METHODS.concat(['put', 'delete']);
6454
+ function isRetryableError(error) {
6455
+ return (error.code !== 'ECONNABORTED' &&
6456
+ (!error.response ||
6457
+ error.response.status === 429 ||
6458
+ (error.response.status >= 500 && error.response.status <= 599)));
6459
+ }
6460
+ function isSafeRequestError(error) {
6461
+ if (!error.config?.method) {
6462
+ // Cannot determine if the request can be retried
6463
+ return false;
6464
+ }
6465
+ return isRetryableError(error) && SAFE_HTTP_METHODS.indexOf(error.config.method) !== -1;
6466
+ }
6467
+ function isIdempotentRequestError(error) {
6468
+ if (!error.config?.method) {
6469
+ // Cannot determine if the request can be retried
6470
+ return false;
6471
+ }
6472
+ return isRetryableError(error) && IDEMPOTENT_HTTP_METHODS.indexOf(error.config.method) !== -1;
6473
+ }
6474
+ function isNetworkOrIdempotentRequestError(error) {
6475
+ return isNetworkError(error) || isIdempotentRequestError(error);
6476
+ }
6477
+ function retryAfter(error = undefined) {
6478
+ const retryAfterHeader = error?.response?.headers['retry-after'];
6479
+ if (!retryAfterHeader) {
6480
+ return 0;
6481
+ }
6482
+ // if the retry after header is a number, convert it to milliseconds
6483
+ let retryAfterMs = (Number(retryAfterHeader) || 0) * 1000;
6484
+ // If the retry after header is a date, get the number of milliseconds until that date
6485
+ if (retryAfterMs === 0) {
6486
+ retryAfterMs = (new Date(retryAfterHeader).valueOf() || 0) - Date.now();
6487
+ }
6488
+ return Math.max(0, retryAfterMs);
6489
+ }
6490
+ function noDelay(_retryNumber = 0, error = undefined) {
6491
+ return Math.max(0, retryAfter(error));
6492
+ }
6493
+ function exponentialDelay(retryNumber = 0, error = undefined, delayFactor = 100) {
6494
+ const calculatedDelay = 2 ** retryNumber * delayFactor;
6495
+ const delay = Math.max(calculatedDelay, retryAfter(error));
6496
+ const randomSum = delay * 0.2 * Math.random(); // 0-20% of the delay
6497
+ return delay + randomSum;
6498
+ }
6499
+ /**
6500
+ * Linear delay
6501
+ * @param {number | undefined} delayFactor - delay factor in milliseconds (default: 100)
6502
+ * @returns {function} (retryNumber: number, error: AxiosError | undefined) => number
6503
+ */
6504
+ function linearDelay(delayFactor = 100) {
6505
+ return (retryNumber = 0, error = undefined) => {
6506
+ const delay = retryNumber * delayFactor;
6507
+ return Math.max(delay, retryAfter(error));
6508
+ };
6509
+ }
6510
+ const DEFAULT_OPTIONS = {
6511
+ retries: 3,
6512
+ retryCondition: isNetworkOrIdempotentRequestError,
6513
+ retryDelay: noDelay,
6514
+ shouldResetTimeout: false,
6515
+ onRetry: () => { },
6516
+ onMaxRetryTimesExceeded: () => { },
6517
+ validateResponse: null
6518
+ };
6519
+ function getRequestOptions(config, defaultOptions) {
6520
+ return { ...DEFAULT_OPTIONS, ...defaultOptions, ...config[namespace] };
6521
+ }
6522
+ function setCurrentState(config, defaultOptions, resetLastRequestTime = false) {
6523
+ const currentState = getRequestOptions(config, defaultOptions || {});
6524
+ currentState.retryCount = currentState.retryCount || 0;
6525
+ if (!currentState.lastRequestTime || resetLastRequestTime) {
6526
+ currentState.lastRequestTime = Date.now();
6527
+ }
6528
+ config[namespace] = currentState;
6529
+ return currentState;
6530
+ }
6531
+ function fixConfig(axiosInstance, config) {
6532
+ // @ts-ignore
6533
+ if (axiosInstance.defaults.agent === config.agent) {
6534
+ // @ts-ignore
6535
+ delete config.agent;
6536
+ }
6537
+ if (axiosInstance.defaults.httpAgent === config.httpAgent) {
6538
+ delete config.httpAgent;
6539
+ }
6540
+ if (axiosInstance.defaults.httpsAgent === config.httpsAgent) {
6541
+ delete config.httpsAgent;
6542
+ }
6543
+ }
6544
+ async function shouldRetry(currentState, error) {
6545
+ const { retries, retryCondition } = currentState;
6546
+ const shouldRetryOrPromise = (currentState.retryCount || 0) < retries && retryCondition(error);
6547
+ // This could be a promise
6548
+ if (typeof shouldRetryOrPromise === 'object') {
6549
+ try {
6550
+ const shouldRetryPromiseResult = await shouldRetryOrPromise;
6551
+ // keep return true unless shouldRetryPromiseResult return false for compatibility
6552
+ return shouldRetryPromiseResult !== false;
6553
+ }
6554
+ catch (_err) {
6555
+ return false;
6556
+ }
6557
+ }
6558
+ return shouldRetryOrPromise;
6559
+ }
6560
+ async function handleRetry(axiosInstance, currentState, error, config) {
6561
+ currentState.retryCount += 1;
6562
+ const { retryDelay, shouldResetTimeout, onRetry } = currentState;
6563
+ const delay = retryDelay(currentState.retryCount, error);
6564
+ // Axios fails merging this configuration to the default configuration because it has an issue
6565
+ // with circular structures: https://github.com/mzabriskie/axios/issues/370
6566
+ fixConfig(axiosInstance, config);
6567
+ if (!shouldResetTimeout && config.timeout && currentState.lastRequestTime) {
6568
+ const lastRequestDuration = Date.now() - currentState.lastRequestTime;
6569
+ const timeout = config.timeout - lastRequestDuration - delay;
6570
+ if (timeout <= 0) {
6571
+ return Promise.reject(error);
6572
+ }
6573
+ config.timeout = timeout;
6574
+ }
6575
+ config.transformRequest = [(data) => data];
6576
+ await onRetry(currentState.retryCount, error, config);
6577
+ if (config.signal?.aborted) {
6578
+ return Promise.resolve(axiosInstance(config));
6579
+ }
6580
+ return new Promise((resolve) => {
6581
+ const abortListener = () => {
6582
+ clearTimeout(timeout);
6583
+ resolve(axiosInstance(config));
6584
+ };
6585
+ const timeout = setTimeout(() => {
6586
+ resolve(axiosInstance(config));
6587
+ if (config.signal?.removeEventListener) {
6588
+ config.signal.removeEventListener('abort', abortListener);
6589
+ }
6590
+ }, delay);
6591
+ if (config.signal?.addEventListener) {
6592
+ config.signal.addEventListener('abort', abortListener, { once: true });
6593
+ }
6594
+ });
6595
+ }
6596
+ async function handleMaxRetryTimesExceeded(currentState, error) {
6597
+ if (currentState.retryCount >= currentState.retries)
6598
+ await currentState.onMaxRetryTimesExceeded(error, currentState.retryCount);
6599
+ }
6600
+ const axiosRetry = (axiosInstance, defaultOptions) => {
6601
+ const requestInterceptorId = axiosInstance.interceptors.request.use((config) => {
6602
+ setCurrentState(config, defaultOptions, true);
6603
+ if (config[namespace]?.validateResponse) {
6604
+ // by setting this, all HTTP responses will be go through the error interceptor first
6605
+ config.validateStatus = () => false;
6606
+ }
6607
+ return config;
6608
+ });
6609
+ const responseInterceptorId = axiosInstance.interceptors.response.use(null, async (error) => {
6610
+ const { config } = error;
6611
+ // If we have no information to retry the request
6612
+ if (!config) {
6613
+ return Promise.reject(error);
6614
+ }
6615
+ const currentState = setCurrentState(config, defaultOptions);
6616
+ if (error.response && currentState.validateResponse?.(error.response)) {
6617
+ // no issue with response
6618
+ return error.response;
6619
+ }
6620
+ if (await shouldRetry(currentState, error)) {
6621
+ return handleRetry(axiosInstance, currentState, error, config);
6622
+ }
6623
+ await handleMaxRetryTimesExceeded(currentState, error);
6624
+ return Promise.reject(error);
6625
+ });
6626
+ return { requestInterceptorId, responseInterceptorId };
6627
+ };
6628
+ // Compatibility with CommonJS
6629
+ axiosRetry.isNetworkError = isNetworkError;
6630
+ axiosRetry.isSafeRequestError = isSafeRequestError;
6631
+ axiosRetry.isIdempotentRequestError = isIdempotentRequestError;
6632
+ axiosRetry.isNetworkOrIdempotentRequestError = isNetworkOrIdempotentRequestError;
6633
+ axiosRetry.exponentialDelay = exponentialDelay;
6634
+ axiosRetry.linearDelay = linearDelay;
6635
+ axiosRetry.isRetryableError = isRetryableError;
6636
+
6382
6637
  let axiosClient;
6383
6638
  async function getAxiosAuthClient() {
6384
6639
  if (!axiosClient) {
@@ -6388,6 +6643,7 @@ async function getAxiosAuthClient() {
6388
6643
  headers: {
6389
6644
  'Content-Type': 'application/json',
6390
6645
  },
6646
+ timeout: 30000, // 30s timeout, matching makeApiRequest
6391
6647
  });
6392
6648
  }
6393
6649
  return axiosClient;
@@ -6434,15 +6690,41 @@ async function createSessionWithPrivy(authToken, address, privyIdToken) {
6434
6690
  });
6435
6691
  return response.data;
6436
6692
  }
6693
+ // Deduplicate concurrent refreshSession calls to prevent multiple code paths
6694
+ // (WebSocket reconnection, periodic refresh, API 401 retry) from all hitting
6695
+ // /session/refresh simultaneously.
6696
+ // Note: module-level state is shared across requests in SSR/Node — acceptable
6697
+ // since there is only one active session per server instance (same pattern as
6698
+ // refreshInFlight in api.ts).
6699
+ let refreshInFlight$1 = null;
6700
+ let refreshInFlightToken = null;
6437
6701
  async function refreshSession(refreshToken) {
6438
- const client = await getAxiosAuthClient();
6439
- const config = await getConfig();
6440
- const appId = config.appId;
6441
- const response = await client.post('/session/refresh', {
6442
- refreshToken,
6443
- appId
6444
- });
6445
- return response.data;
6702
+ if (refreshInFlight$1 && refreshInFlightToken === refreshToken) {
6703
+ return refreshInFlight$1;
6704
+ }
6705
+ refreshInFlightToken = refreshToken;
6706
+ let currentFlight;
6707
+ currentFlight = refreshInFlight$1 = (async () => {
6708
+ try {
6709
+ const client = await getAxiosAuthClient();
6710
+ const config = await getConfig();
6711
+ const appId = config.appId;
6712
+ const response = await client.post('/session/refresh', {
6713
+ refreshToken,
6714
+ appId
6715
+ });
6716
+ return response.data;
6717
+ }
6718
+ finally {
6719
+ // Only clear if we're still the active in-flight request.
6720
+ // A second call with a different token may have replaced us.
6721
+ if (refreshInFlight$1 === currentFlight) {
6722
+ refreshInFlight$1 = null;
6723
+ refreshInFlightToken = null;
6724
+ }
6725
+ }
6726
+ })();
6727
+ return refreshInFlight$1;
6446
6728
  }
6447
6729
  async function signSessionCreateMessage(_signMessageFunction) {
6448
6730
  }
@@ -6580,14 +6862,10 @@ class WebSessionManager {
6580
6862
  WebSessionManager.TAROBASE_SESSION_STORAGE_KEY = "tarobase_session_storage";
6581
6863
 
6582
6864
  var webSessionManager = /*#__PURE__*/Object.freeze({
6583
- __proto__: null,
6584
- WebSessionManager: WebSessionManager
6865
+ __proto__: null,
6866
+ WebSessionManager: WebSessionManager
6585
6867
  });
6586
6868
 
6587
- function getDefaultExportFromCjs (x) {
6588
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
6589
- }
6590
-
6591
6869
  var buffer = {};
6592
6870
 
6593
6871
  var base64Js = {};
@@ -9384,7 +9662,19 @@ async function buildSetDocumentsTransaction(connection, idl, anchorProvider, pay
9384
9662
  }
9385
9663
  }
9386
9664
  else if (lutKey != null) {
9387
- const { value: table } = await connection.getAddressLookupTable(new PublicKey(lutKey));
9665
+ // The LUT may have just been created server-side and the client's RPC node
9666
+ // may not have indexed it yet (load-balancer split). Retry with exponential
9667
+ // back-off; first retry at 100 ms almost always resolves it.
9668
+ let table = null;
9669
+ for (let attempt = 0; attempt < 5; attempt++) {
9670
+ const { value } = await connection.getAddressLookupTable(new PublicKey(lutKey));
9671
+ if (value) {
9672
+ table = value;
9673
+ break;
9674
+ }
9675
+ if (attempt < 4)
9676
+ await new Promise(r => setTimeout(r, 100 * Math.pow(2, attempt)));
9677
+ }
9388
9678
  if (!table)
9389
9679
  throw new Error('LUT not found after creation/extend');
9390
9680
  lookupTables.push(table);
@@ -9519,8 +9809,8 @@ class ServerSessionManager {
9519
9809
  ServerSessionManager.instance = new ServerSessionManager();
9520
9810
 
9521
9811
  var serverSessionManager = /*#__PURE__*/Object.freeze({
9522
- __proto__: null,
9523
- ServerSessionManager: ServerSessionManager
9812
+ __proto__: null,
9813
+ ServerSessionManager: ServerSessionManager
9524
9814
  });
9525
9815
 
9526
9816
  /**
@@ -9619,6 +9909,23 @@ async function updateIdTokenAndAccessToken(idToken, accessToken, isServer = fals
9619
9909
  await WebSessionManager.updateIdTokenAndAccessToken(idToken, accessToken);
9620
9910
  }
9621
9911
 
9912
+ const apiClient = globalAxios.create();
9913
+ axiosRetry(apiClient, {
9914
+ retries: 2,
9915
+ retryCondition: (error) => {
9916
+ var _a, _b;
9917
+ // Only retry GET requests on network errors (ECONNRESET, ETIMEDOUT, etc.)
9918
+ // Writes (POST/PUT) are not retried — the server may have processed
9919
+ // the request before the connection was reset.
9920
+ return axiosRetry.isNetworkError(error) && ((_b = (_a = error.config) === null || _a === void 0 ? void 0 : _a.method) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === 'get';
9921
+ },
9922
+ retryDelay: axiosRetry.exponentialDelay,
9923
+ shouldResetTimeout: true,
9924
+ onRetry: (retryCount, error, requestConfig) => {
9925
+ var _a;
9926
+ console.warn(`[tarobase-sdk] retry ${retryCount} for ${(_a = requestConfig.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()} ${requestConfig.url} — ${error.code || error.message}`);
9927
+ },
9928
+ });
9622
9929
  const refreshInFlight = new Map();
9623
9930
  async function refreshAuthSessionOnce(appId, isServer) {
9624
9931
  const key = `${isServer ? "server" : "web"}:${appId}`;
@@ -9665,6 +9972,7 @@ async function makeApiRequest(method, urlPath, data, _overrides) {
9665
9972
  ServerSessionManager.instance.clearSession();
9666
9973
  };
9667
9974
  async function executeRequest() {
9975
+ var _a;
9668
9976
  // When _getAuthHeaders is provided (wallet client), use it as the sole auth source.
9669
9977
  // Otherwise use the global createAuthHeader (default path).
9670
9978
  const authHeader = (_overrides === null || _overrides === void 0 ? void 0 : _overrides._getAuthHeaders)
@@ -9686,11 +9994,12 @@ async function makeApiRequest(method, urlPath, data, _overrides) {
9686
9994
  method,
9687
9995
  url: `${config.apiUrl}${urlPath.startsWith("/") ? urlPath : `/${urlPath}`}`,
9688
9996
  headers,
9997
+ timeout: (_a = _overrides === null || _overrides === void 0 ? void 0 : _overrides.timeout) !== null && _a !== void 0 ? _a : 30000,
9689
9998
  };
9690
9999
  if (method !== "GET" && method !== "get") {
9691
10000
  requestConfig.data = data ? JSON.stringify(data) : {};
9692
10001
  }
9693
- const response = await globalAxios(requestConfig);
10002
+ const response = await apiClient(requestConfig);
9694
10003
  return { data: response.data, status: response.status, headers: response.headers };
9695
10004
  }
9696
10005
  try {
@@ -10101,6 +10410,90 @@ function cleanupExpiredCache() {
10101
10410
  });
10102
10411
  lastCacheCleanup = now;
10103
10412
  }
10413
+ async function getMany(paths, opts = {}) {
10414
+ if (paths.length === 0) {
10415
+ return [];
10416
+ }
10417
+ if (paths.length > 30) {
10418
+ throw new Error('Cannot fetch more than 30 documents at once');
10419
+ }
10420
+ const normalizedPaths = [];
10421
+ for (const path of paths) {
10422
+ let normalizedPath = path.startsWith("/") ? path.slice(1) : path;
10423
+ if (normalizedPath.endsWith("*") && normalizedPath.length > 1) {
10424
+ normalizedPath = normalizedPath.slice(0, -1);
10425
+ }
10426
+ if (!normalizedPath || normalizedPath.length === 0) {
10427
+ throw new Error(`Invalid path provided: ${path}`);
10428
+ }
10429
+ const pathIsDocument = normalizedPath.split("/").length % 2 === 0;
10430
+ if (!pathIsDocument) {
10431
+ throw new Error(`Path must point to a document (even number of segments): ${path}`);
10432
+ }
10433
+ normalizedPaths.push(normalizedPath);
10434
+ }
10435
+ const now = Date.now();
10436
+ const results = new Array(paths.length);
10437
+ const uncachedIndices = [];
10438
+ const uncachedPaths = [];
10439
+ for (let i = 0; i < normalizedPaths.length; i++) {
10440
+ const normalizedPath = normalizedPaths[i];
10441
+ const cacheKey = `${normalizedPath}:`;
10442
+ if (!opts.bypassCache && getCache[cacheKey] && now < getCache[cacheKey].expiresAt) {
10443
+ results[i] = { path: normalizedPath, data: getCache[cacheKey].data };
10444
+ }
10445
+ else {
10446
+ uncachedIndices.push(i);
10447
+ uncachedPaths.push(normalizedPath);
10448
+ }
10449
+ }
10450
+ if (uncachedPaths.length > 0) {
10451
+ try {
10452
+ const response = await makeApiRequest('POST', 'items/batch', { paths: uncachedPaths }, opts._overrides);
10453
+ const serverResults = response.data.results;
10454
+ const serverResultsMap = new Map();
10455
+ for (const result of serverResults) {
10456
+ serverResultsMap.set(result.path, result);
10457
+ }
10458
+ for (let i = 0; i < uncachedIndices.length; i++) {
10459
+ const originalIndex = uncachedIndices[i];
10460
+ const normalizedPath = uncachedPaths[i];
10461
+ const serverResult = serverResultsMap.get(normalizedPath);
10462
+ if (serverResult) {
10463
+ results[originalIndex] = serverResult;
10464
+ if (!serverResult.error && !opts.bypassCache) {
10465
+ const cacheKey = `${normalizedPath}:`;
10466
+ getCache[cacheKey] = {
10467
+ data: serverResult.data,
10468
+ expiresAt: now + GET_CACHE_TTL
10469
+ };
10470
+ }
10471
+ }
10472
+ else {
10473
+ results[originalIndex] = {
10474
+ path: normalizedPath,
10475
+ data: null,
10476
+ error: { code: 'NOT_FOUND', message: `No result returned for path ${normalizedPath}` }
10477
+ };
10478
+ }
10479
+ }
10480
+ if (now - lastCacheCleanup > 5000) {
10481
+ cleanupExpiredCache();
10482
+ lastCacheCleanup = now;
10483
+ }
10484
+ }
10485
+ catch (error) {
10486
+ for (const originalIndex of uncachedIndices) {
10487
+ results[originalIndex] = {
10488
+ path: normalizedPaths[originalIndex],
10489
+ data: null,
10490
+ error: { code: 'NOT_FOUND', message: error instanceof Error ? error.message : 'Unknown error' }
10491
+ };
10492
+ }
10493
+ }
10494
+ }
10495
+ return results;
10496
+ }
10104
10497
  async function runQuery(absolutePath, queryName, queryArgs, opts) {
10105
10498
  const result = await runQueryMany([{ absolutePath, queryName, queryArgs }], opts);
10106
10499
  return result[0];
@@ -10542,6 +10935,7 @@ function scheduleTokenRefresh(connection, isServer) {
10542
10935
  // This replaces the old single setTimeout approach which was unreliable for long
10543
10936
  // delays (browsers throttle/suspend timers in background tabs).
10544
10937
  connection.tokenRefreshTimer = setInterval(async () => {
10938
+ var _a, _b;
10545
10939
  try {
10546
10940
  const currentToken = await getIdToken$1(isServer);
10547
10941
  if (!currentToken)
@@ -10572,6 +10966,17 @@ function scheduleTokenRefresh(connection, isServer) {
10572
10966
  }
10573
10967
  }
10574
10968
  catch (refreshError) {
10969
+ // If the refresh token itself is invalid (401/403), stop retrying —
10970
+ // the token won't magically become valid next interval, and continuing
10971
+ // to hammer /session/refresh causes 429 rate-limit storms.
10972
+ if (((_a = refreshError === null || refreshError === void 0 ? void 0 : refreshError.response) === null || _a === void 0 ? void 0 : _a.status) === 401 || ((_b = refreshError === null || refreshError === void 0 ? void 0 : refreshError.response) === null || _b === void 0 ? void 0 : _b.status) === 403) {
10973
+ console.warn('[WS v2] Refresh token rejected (401/403), stopping periodic refresh');
10974
+ if (connection.tokenRefreshTimer) {
10975
+ clearInterval(connection.tokenRefreshTimer);
10976
+ connection.tokenRefreshTimer = null;
10977
+ }
10978
+ return;
10979
+ }
10575
10980
  console.warn('[WS v2] Proactive token refresh failed, will retry next interval:', refreshError);
10576
10981
  }
10577
10982
  }
@@ -10582,6 +10987,7 @@ function scheduleTokenRefresh(connection, isServer) {
10582
10987
  }, TOKEN_CHECK_INTERVAL);
10583
10988
  }
10584
10989
  async function getFreshAuthToken(isServer) {
10990
+ var _a, _b;
10585
10991
  const currentToken = await getIdToken$1(isServer);
10586
10992
  if (!currentToken) {
10587
10993
  return null;
@@ -10604,6 +11010,17 @@ async function getFreshAuthToken(isServer) {
10604
11010
  }
10605
11011
  catch (error) {
10606
11012
  console.error('[WS v2] Error refreshing token:', error);
11013
+ // If the refresh token is permanently invalid (401/403), clear the stale
11014
+ // session from storage so future attempts don't keep retrying with it.
11015
+ if (!isServer && (((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status) === 401 || ((_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.status) === 403)) {
11016
+ try {
11017
+ const { WebSessionManager } = await Promise.resolve().then(function () { return webSessionManager; });
11018
+ WebSessionManager.clearSession();
11019
+ }
11020
+ catch (clearError) {
11021
+ console.warn('[WS v2] Failed to clear stale session:', clearError);
11022
+ }
11023
+ }
10607
11024
  }
10608
11025
  // Return null instead of the expired token to prevent infinite 401 reconnect storms.
10609
11026
  // The server accepts unauthenticated connections; auth-required subscriptions will
@@ -10724,7 +11141,16 @@ async function getOrCreateConnection(appId, isServer) {
10724
11141
  ws.addEventListener('open', () => {
10725
11142
  connection.isConnecting = false;
10726
11143
  connection.isConnected = true;
10727
- connection.consecutiveAuthFailures = 0;
11144
+ // NOTE: Do NOT reset consecutiveAuthFailures here. It is reset when a
11145
+ // fresh auth token is actually obtained (in urlProvider, line ~389) or on
11146
+ // an explicit auth change (reconnectWithNewAuthV2, line ~854). Resetting
11147
+ // on every 'open' event created an infinite loop: auth fails 5x → connect
11148
+ // without auth → open resets counter → disconnect → auth fails 5x again →
11149
+ // repeat forever, hammering /session/refresh and causing 429s.
11150
+ //
11151
+ // An elevated counter is safe for anonymous/guest sessions: when there's no
11152
+ // token at all (getIdToken returns null), the counter is never checked —
11153
+ // urlProvider skips straight to unauthenticated connection.
10728
11154
  // Schedule periodic token freshness checks
10729
11155
  scheduleTokenRefresh(connection, isServer);
10730
11156
  // Re-subscribe to all existing subscriptions after reconnect
@@ -12386,15 +12812,15 @@ function clearIncompatibleSession() {
12386
12812
  // Lazy loaders for web-only providers.
12387
12813
  // Using dynamic import() ensures Metro (RN) never resolves these modules.
12388
12814
  async function loadPrivyWalletProvider() {
12389
- const mod = await import('./privy-wallet-provider-BtLH1dpY.esm.js');
12815
+ const mod = await import('./privy-wallet-provider-CZgiUwUN.esm.js');
12390
12816
  return mod.PrivyWalletProvider;
12391
12817
  }
12392
12818
  async function loadPhantomWalletProvider() {
12393
- const mod = await import('./phantom-wallet-provider-5IQi4ihD.esm.js');
12819
+ const mod = await import('./phantom-wallet-provider-B1TleWsy.esm.js');
12394
12820
  return { PhantomWalletProvider: mod.PhantomWalletProvider };
12395
12821
  }
12396
12822
  async function loadSolanaMobileWalletProvider() {
12397
- const mod = await import('./solana-mobile-wallet-provider-C3l6mxSm.esm.js');
12823
+ const mod = await import('./solana-mobile-wallet-provider-C9j8O3mD.esm.js');
12398
12824
  return mod.SolanaMobileWalletProvider;
12399
12825
  }
12400
12826
  async function hotSwapToPrivyProvider(config) {
@@ -13275,5 +13701,5 @@ class PrivyExpoProvider {
13275
13701
  }
13276
13702
  }
13277
13703
 
13278
- export { clearCache as $, set as A, setMany as B, setFile as C, getFiles as D, runQuery as E, runQueryMany as F, runExpression as G, runExpressionMany as H, signMessage as I, signTransaction as J, signAndSubmitTransaction as K, count as L, aggregate as M, subscribe as N, useAuth as O, deserializeTransaction as P, getIdToken as Q, setPlatform as R, SOLANA_MAINNET_RPC_URL as S, MockAuthProvider as T, DEFAULT_TEST_ADDRESS as U, OffchainAuthProvider as V, WebSessionManager as W, PrivyExpoProvider as X, InsufficientBalanceError as Y, ReactNativeSessionManager as Z, ServerSessionManager as _, SOLANA_DEVNET_RPC_URL as a, closeAllSubscriptions as a0, getCachedData as a1, reconnectWithNewAuth as a2, refreshSession as a3, signSessionCreateMessage as a4, index as a5, buildSetDocumentsTransaction as b, convertRemainingAccounts as c, bs58 as d, confirmAndCheckTransaction as e, createSessionWithPrivy as f, getPlatform as g, SURFNET_RPC_URL$1 as h, detectMobile as i, detectAndroid as j, setAuthLoading as k, genAuthNonce as l, genSolanaMessage as m, createSessionWithSignature as n, getDefaultExportFromCjs$1 as o, init as p, getCurrentUser as q, onAuthStateChanged as r, setCurrentUser as s, onAuthLoadingChanged as t, getAuthLoading as u, login as v, logout as w, getConfig as x, getAuthProvider as y, get as z };
13279
- //# sourceMappingURL=index.native-H-fEcP_L.esm.js.map
13704
+ export { clearCache as $, set as A, setMany as B, setFile as C, getFiles as D, runQuery as E, runQueryMany as F, runExpression as G, runExpressionMany as H, signMessage as I, signTransaction as J, signAndSubmitTransaction as K, count as L, aggregate as M, subscribe as N, useAuth as O, deserializeTransaction as P, getIdToken as Q, setPlatform as R, SOLANA_MAINNET_RPC_URL as S, MockAuthProvider as T, DEFAULT_TEST_ADDRESS as U, OffchainAuthProvider as V, WebSessionManager as W, PrivyExpoProvider as X, InsufficientBalanceError as Y, ReactNativeSessionManager as Z, ServerSessionManager as _, SOLANA_DEVNET_RPC_URL as a, closeAllSubscriptions as a0, getCachedData as a1, getMany as a2, reconnectWithNewAuth as a3, refreshSession as a4, signSessionCreateMessage as a5, index as a6, buildSetDocumentsTransaction as b, convertRemainingAccounts as c, bs58 as d, confirmAndCheckTransaction as e, createSessionWithPrivy as f, getPlatform as g, SURFNET_RPC_URL$1 as h, detectMobile as i, detectAndroid as j, setAuthLoading as k, genAuthNonce as l, genSolanaMessage as m, createSessionWithSignature as n, getDefaultExportFromCjs$1 as o, init as p, getCurrentUser as q, onAuthStateChanged as r, setCurrentUser as s, onAuthLoadingChanged as t, getAuthLoading as u, login as v, logout as w, getConfig as x, getAuthProvider as y, get as z };
13705
+ //# sourceMappingURL=index.native-CjEJXA9y.esm.js.map