@pooflabs/web 0.0.93 → 0.0.94

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 (56) hide show
  1. package/dist/{index-beZzBYpc.esm.js → index-Blxu9ZBh.esm.js} +2407 -3
  2. package/dist/index-Blxu9ZBh.esm.js.map +1 -0
  3. package/dist/index-C2VF8Cds.esm.js +6 -0
  4. package/dist/index-C2VF8Cds.esm.js.map +1 -0
  5. package/dist/{index-Baq-MUI8.js → index-CGei1juZ.js} +2407 -3
  6. package/dist/index-CGei1juZ.js.map +1 -0
  7. package/dist/{index-CDoDnDyA.js → index-CdKrnAsF.js} +2406 -2
  8. package/dist/index-CdKrnAsF.js.map +1 -0
  9. package/dist/{index-DbX66ch3.esm.js → index-Cnx5UBPU.esm.js} +152 -30
  10. package/dist/index-Cnx5UBPU.esm.js.map +1 -0
  11. package/dist/{index-BRKarMUo.js → index-DOz63COz.js} +152 -28
  12. package/dist/index-DOz63COz.js.map +1 -0
  13. package/dist/{index-BJhw8pOb.esm.js → index-DSSkK8ZR.esm.js} +2406 -2
  14. package/dist/index-DSSkK8ZR.esm.js.map +1 -0
  15. package/dist/{index-Dw03bD6R.js → index-DzZ1tiet.js} +2 -2
  16. package/dist/index-DzZ1tiet.js.map +1 -0
  17. package/dist/{index.browser-D15wyxan.esm.js → index.browser-AkckBwjb.esm.js} +2 -2
  18. package/dist/{index.browser-D15wyxan.esm.js.map → index.browser-AkckBwjb.esm.js.map} +1 -1
  19. package/dist/{index.browser-CI4TkG8U.js → index.browser-By5vlelY.js} +2 -2
  20. package/dist/{index.browser-CI4TkG8U.js.map → index.browser-By5vlelY.js.map} +1 -1
  21. package/dist/{index.browser-BSQvgdMT.esm.js → index.browser-ClqAxUrJ.esm.js} +2 -2
  22. package/dist/{index.browser-BSQvgdMT.esm.js.map → index.browser-ClqAxUrJ.esm.js.map} +1 -1
  23. package/dist/{index.browser-Bmi3o9v0.js → index.browser-Um9-5Cbs.js} +2 -2
  24. package/dist/{index.browser-Bmi3o9v0.js.map → index.browser-Um9-5Cbs.js.map} +1 -1
  25. package/dist/index.esm.js +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/{index.native-0P9dPMFG.esm.js → index.native-9ugIwvrJ.esm.js} +152 -30
  28. package/dist/index.native-9ugIwvrJ.esm.js.map +1 -0
  29. package/dist/{index.native-DIXtlrL_.js → index.native-CpA5KDvL.js} +152 -28
  30. package/dist/index.native-CpA5KDvL.js.map +1 -0
  31. package/dist/index.native.esm.js +1 -1
  32. package/dist/index.native.js +1 -1
  33. package/dist/{phantom-wallet-provider-DV12qfW6.js → phantom-wallet-provider-LGxBWZXy.js} +4 -4
  34. package/dist/{phantom-wallet-provider-DV12qfW6.js.map → phantom-wallet-provider-LGxBWZXy.js.map} +1 -1
  35. package/dist/{phantom-wallet-provider-44BDf-tk.esm.js → phantom-wallet-provider-wskKKVNr.esm.js} +4 -4
  36. package/dist/{phantom-wallet-provider-44BDf-tk.esm.js.map → phantom-wallet-provider-wskKKVNr.esm.js.map} +1 -1
  37. package/dist/{privy-wallet-provider-CzoLQPiq.esm.js → privy-wallet-provider-B3bghDWY.esm.js} +3 -3
  38. package/dist/{privy-wallet-provider-CzoLQPiq.esm.js.map → privy-wallet-provider-B3bghDWY.esm.js.map} +1 -1
  39. package/dist/{privy-wallet-provider-CQnyjLEI.js → privy-wallet-provider-DsHSkIJJ.js} +3 -3
  40. package/dist/{privy-wallet-provider-CQnyjLEI.js.map → privy-wallet-provider-DsHSkIJJ.js.map} +1 -1
  41. package/dist/{solana-mobile-wallet-provider-BbvaCCuE.esm.js → solana-mobile-wallet-provider-CFYL4aOO.esm.js} +4 -4
  42. package/dist/{solana-mobile-wallet-provider-BbvaCCuE.esm.js.map → solana-mobile-wallet-provider-CFYL4aOO.esm.js.map} +1 -1
  43. package/dist/{solana-mobile-wallet-provider-BmXTQow5.js → solana-mobile-wallet-provider-EkUSbs-q.js} +4 -4
  44. package/dist/{solana-mobile-wallet-provider-BmXTQow5.js.map → solana-mobile-wallet-provider-EkUSbs-q.js.map} +1 -1
  45. package/package.json +2 -2
  46. package/dist/index-BJhw8pOb.esm.js.map +0 -1
  47. package/dist/index-BQN3A4SI.esm.js +0 -6
  48. package/dist/index-BQN3A4SI.esm.js.map +0 -1
  49. package/dist/index-BRKarMUo.js.map +0 -1
  50. package/dist/index-Baq-MUI8.js.map +0 -1
  51. package/dist/index-CDoDnDyA.js.map +0 -1
  52. package/dist/index-DbX66ch3.esm.js.map +0 -1
  53. package/dist/index-Dw03bD6R.js.map +0 -1
  54. package/dist/index-beZzBYpc.esm.js.map +0 -1
  55. package/dist/index.native-0P9dPMFG.esm.js.map +0 -1
  56. package/dist/index.native-DIXtlrL_.js.map +0 -1
@@ -6704,7 +6704,14 @@ async function createSessionWithPrivy(authToken, address, privyIdToken) {
6704
6704
  const appId = config.appId;
6705
6705
  const response = await client.post('/session', {
6706
6706
  appId,
6707
- authMethod: config.authMethod,
6707
+ // createSessionWithPrivy is, by definition, the Privy session path, so the
6708
+ // server must receive authMethod:'privy' (its branch validates authToken+
6709
+ // idToken+appId). Do NOT read config.authMethod here: on a Phantom-primary app
6710
+ // with the staged Privy email swap, config.authMethod is still 'phantom' at this
6711
+ // point (commitPrivy runs after login() resolves), which routes the request to
6712
+ // the signature/message branch and fails. Hardcoding 'privy' also correctly
6713
+ // covers 'privy-expo', which the backend expects mapped to 'privy'.
6714
+ authMethod: 'privy',
6708
6715
  authToken,
6709
6716
  idToken: privyIdToken,
6710
6717
  address
@@ -9961,6 +9968,14 @@ async function updateIdTokenAndAccessToken(idToken, accessToken, isServer = fals
9961
9968
  await WebSessionManager.updateIdTokenAndAccessToken(idToken, accessToken);
9962
9969
  }
9963
9970
 
9971
+ var utils = /*#__PURE__*/Object.freeze({
9972
+ __proto__: null,
9973
+ createAuthHeader: createAuthHeader,
9974
+ getIdToken: getIdToken$1,
9975
+ getRefreshToken: getRefreshToken,
9976
+ updateIdTokenAndAccessToken: updateIdTokenAndAccessToken
9977
+ });
9978
+
9964
9979
  const apiClient = globalAxios.create();
9965
9980
  axiosRetry(apiClient, {
9966
9981
  retries: 2,
@@ -10388,7 +10403,7 @@ async function get(path, opts = {}) {
10388
10403
  // For realtime chains, prefer WebSocket reads (lower latency, already connected)
10389
10404
  const config = await getConfig();
10390
10405
  const pathIsDocument = normalizedPath.split("/").length % 2 === 0;
10391
- if (((_a = config.chain) === null || _a === void 0 ? void 0 : _a.startsWith('realtime_')) && !config.isServer && !opts.prompt && !opts.shape && !opts.cursor) {
10406
+ if (((_a = config.chain) === null || _a === void 0 ? void 0 : _a.startsWith('realtime_')) && !config.isServer && !opts.prompt && !opts.shape && !opts.cursor && !opts.includeSubPaths) {
10392
10407
  try {
10393
10408
  const { wsGet, wsQuery, hasActiveConnection } = await Promise.resolve().then(function () { return subscriptionV2; });
10394
10409
  if (hasActiveConnection()) {
@@ -10619,7 +10634,7 @@ async function set(path, document, options) {
10619
10634
  return result;
10620
10635
  }
10621
10636
  async function setMany(many, options) {
10622
- var _a, _b, _c, _d, _e, _f, _g, _h;
10637
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
10623
10638
  // Returns the data that was set, or undefined if the document was already set.
10624
10639
  try {
10625
10640
  const config = await getConfig();
@@ -10662,12 +10677,24 @@ async function setMany(many, options) {
10662
10677
  try {
10663
10678
  const { wsSet, hasActiveConnection } = await Promise.resolve().then(function () { return subscriptionV2; });
10664
10679
  if (hasActiveConnection()) {
10680
+ // Connection is active — send via WS. If this throws, the write
10681
+ // may have been applied server-side (ack lost). Do NOT fall through
10682
+ // to HTTP, as that would double-apply non-idempotent ops (Increment).
10665
10683
  const wsResult = await wsSet(documents);
10666
- // Normalize to same shape as HTTP 200 response so downstream handling is identical
10667
10684
  setResponse = { data: wsResult, status: 200 };
10668
10685
  }
10669
10686
  }
10670
- catch ( /* fall through to HTTP */_j) { /* fall through to HTTP */ }
10687
+ catch (wsError) {
10688
+ // Only fall through to HTTP if the request was never sent (connection not available).
10689
+ // If the request was sent and ack was lost (timeout), the server may have
10690
+ // applied it — re-sending via HTTP risks double-write for non-idempotent ops.
10691
+ const msg = (_d = wsError === null || wsError === void 0 ? void 0 : wsError.message) !== null && _d !== void 0 ? _d : '';
10692
+ const neverSent = msg.includes('not available') || msg.includes('connection timeout');
10693
+ if (!neverSent) {
10694
+ throw wsError;
10695
+ }
10696
+ // Safe to retry via HTTP — request was never sent
10697
+ }
10671
10698
  }
10672
10699
  if (!setResponse) {
10673
10700
  setResponse = await makeApiRequest('PUT', `items`, { documents }, options === null || options === void 0 ? void 0 : options._overrides);
@@ -10675,9 +10702,9 @@ async function setMany(many, options) {
10675
10702
  }
10676
10703
  catch (error) {
10677
10704
  if ((error === null || error === void 0 ? void 0 : error.statusCode) === 402 && (error === null || error === void 0 ? void 0 : error.error) === 'INSUFFICIENT_BALANCE') {
10678
- const deficitLamports = Number((_d = error.deficitLamports) !== null && _d !== void 0 ? _d : 0);
10679
- const deficitSol = Number((_e = error.deficitSol) !== null && _e !== void 0 ? _e : deficitLamports / 1000000000);
10680
- throw new InsufficientBalanceError(String((_f = error.address) !== null && _f !== void 0 ? _f : ''), Number((_g = error.balanceLamports) !== null && _g !== void 0 ? _g : 0), Number((_h = error.estimatedCostLamports) !== null && _h !== void 0 ? _h : 0), deficitLamports, deficitSol);
10705
+ const deficitLamports = Number((_e = error.deficitLamports) !== null && _e !== void 0 ? _e : 0);
10706
+ const deficitSol = Number((_f = error.deficitSol) !== null && _f !== void 0 ? _f : deficitLamports / 1000000000);
10707
+ throw new InsufficientBalanceError(String((_g = error.address) !== null && _g !== void 0 ? _g : ''), Number((_h = error.balanceLamports) !== null && _h !== void 0 ? _h : 0), Number((_j = error.estimatedCostLamports) !== null && _j !== void 0 ? _j : 0), deficitLamports, deficitSol);
10681
10708
  }
10682
10709
  throw error;
10683
10710
  }
@@ -10699,7 +10726,13 @@ async function setMany(many, options) {
10699
10726
  let signedTransaction = undefined;
10700
10727
  for (let i = 0; i < transactions.length; i++) {
10701
10728
  const curTx = transactions[i];
10702
- const transactionResult = await handleSolanaTransaction(curTx, authProvider, options);
10729
+ let transactionResult;
10730
+ if (curTx.serializedTransaction) {
10731
+ transactionResult = await handlePreBuiltTransaction(curTx, authProvider, options);
10732
+ }
10733
+ else {
10734
+ transactionResult = await handleSolanaTransaction(curTx, authProvider, options);
10735
+ }
10703
10736
  lastTxSignature = transactionResult.transactionSignature;
10704
10737
  signedTransaction = transactionResult.signedTransaction;
10705
10738
  }
@@ -10805,6 +10838,68 @@ async function setMany(many, options) {
10805
10838
  const transactionResult = await authProvider.runTransaction(undefined, solTransaction, options);
10806
10839
  return transactionResult;
10807
10840
  }
10841
+ async function handlePreBuiltTransaction(tx, authProvider, options) {
10842
+ var _a, _b;
10843
+ const config = await getConfig();
10844
+ const rpcUrl = config.rpcUrl || (tx.network === 'solana_devnet'
10845
+ ? 'https://api.devnet.solana.com'
10846
+ : 'https://api.mainnet-beta.solana.com');
10847
+ const connection = new web3_js.Connection(rpcUrl, 'confirmed');
10848
+ const txBytes = bufferExports.Buffer.from(tx.serializedTransaction, 'base64');
10849
+ const transaction = web3_js.VersionedTransaction.deserialize(txBytes);
10850
+ // Validate the transaction before signing: ensure only allowed programs
10851
+ // and no unauthorized System program instructions (e.g., SOL transfers)
10852
+ const TAROBASE_PROGRAM = 'poof4b5pk1L9tmThvBmaABjcyjfhFGbMbQP5BXk2QZp';
10853
+ const COMPUTE_BUDGET = 'ComputeBudget111111111111111111111111111111';
10854
+ const SYSTEM_PROGRAM = '11111111111111111111111111111111';
10855
+ const ALLOWED_PROGRAMS = new Set([TAROBASE_PROGRAM, COMPUTE_BUDGET, SYSTEM_PROGRAM]);
10856
+ // System program instruction discriminators (first 4 bytes, little-endian u32)
10857
+ const SYSTEM_TRANSFER = 2; // Transfer instruction index
10858
+ const SYSTEM_TRANSFER_WITH_SEED = 11;
10859
+ const accountKeys = transaction.message.staticAccountKeys;
10860
+ for (const ix of transaction.message.compiledInstructions) {
10861
+ if (ix.programIdIndex >= accountKeys.length) {
10862
+ throw new Error('Pre-built transaction has program ID in lookup table (not allowed)');
10863
+ }
10864
+ const programId = accountKeys[ix.programIdIndex].toBase58();
10865
+ if (!ALLOWED_PROGRAMS.has(programId)) {
10866
+ throw new Error(`Pre-built transaction contains unauthorized program: ${programId}`);
10867
+ }
10868
+ // Block System program transfer instructions — a compromised DO could
10869
+ // embed a SOL drain. Only allow createAccount/allocate (needed for PDA init).
10870
+ if (programId === SYSTEM_PROGRAM && ix.data.length >= 4) {
10871
+ const ixIndex = ix.data[0] | (ix.data[1] << 8) | (ix.data[2] << 16) | (ix.data[3] << 24);
10872
+ if (ixIndex === SYSTEM_TRANSFER || ixIndex === SYSTEM_TRANSFER_WITH_SEED) {
10873
+ throw new Error('Pre-built transaction contains unauthorized System transfer instruction');
10874
+ }
10875
+ }
10876
+ }
10877
+ const signedTx = await authProvider.signTransaction(transaction);
10878
+ const rawTx = signedTx.serialize();
10879
+ if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
10880
+ return {
10881
+ transactionSignature: '',
10882
+ signedTransaction: bufferExports.Buffer.from(rawTx).toString('base64'),
10883
+ blockNumber: 0,
10884
+ gasUsed: '0',
10885
+ };
10886
+ }
10887
+ const signature = await connection.sendRawTransaction(rawTx, {
10888
+ skipPreflight: false,
10889
+ maxRetries: 3,
10890
+ });
10891
+ const confirmation = await connection.confirmTransaction({
10892
+ signature,
10893
+ blockhash: tx.blockhash,
10894
+ lastValidBlockHeight: tx.lastValidBlockHeight,
10895
+ }, 'confirmed');
10896
+ return {
10897
+ transactionSignature: signature,
10898
+ signedTransaction: bufferExports.Buffer.from(rawTx).toString('base64'),
10899
+ blockNumber: (_b = (_a = confirmation.context) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0,
10900
+ gasUsed: '0',
10901
+ };
10902
+ }
10808
10903
  async function handleOffchainTransaction(tx, authProvider, options) {
10809
10904
  var _a, _b, _c, _d, _e, _f;
10810
10905
  const config = await getConfig();
@@ -12117,30 +12212,53 @@ class RealtimeStore {
12117
12212
  this.idbDirtyKeys = new Set();
12118
12213
  this.closed = false;
12119
12214
  this.authToken = null;
12215
+ this.isServer = false;
12216
+ this.tokenRefreshTimer = null;
12217
+ // -----------------------------------------------------------------------
12218
+ // WebSocket connection
12219
+ // -----------------------------------------------------------------------
12220
+ this.initPromise = null;
12120
12221
  }
12121
12222
  // -----------------------------------------------------------------------
12122
12223
  // Initialization
12123
12224
  // -----------------------------------------------------------------------
12124
12225
  async init() {
12125
- var _a, _b;
12126
12226
  const config = await getConfig();
12127
12227
  this.appId = config.appId;
12128
12228
  this.wsUrl = config.wsApiUrl;
12129
- if (config.authProvider) {
12130
- try {
12131
- const headers = await ((_b = (_a = config.authProvider).getAuthHeaders) === null || _b === void 0 ? void 0 : _b.call(_a));
12132
- if (headers === null || headers === void 0 ? void 0 : headers.Authorization) {
12133
- this.authToken = headers.Authorization.replace('Bearer ', '');
12134
- }
12135
- }
12136
- catch ( /* no auth */_c) { /* no auth */ }
12229
+ this.isServer = config.isServer;
12230
+ await this.refreshToken();
12231
+ this.startTokenRefresh();
12232
+ }
12233
+ async refreshToken() {
12234
+ try {
12235
+ const { getIdToken } = await Promise.resolve().then(function () { return utils; });
12236
+ const token = await getIdToken(this.isServer);
12237
+ if (token)
12238
+ this.authToken = token;
12137
12239
  }
12240
+ catch ( /* no auth available */_a) { /* no auth available */ }
12241
+ }
12242
+ startTokenRefresh() {
12243
+ if (this.tokenRefreshTimer)
12244
+ return;
12245
+ this.tokenRefreshTimer = setInterval(async () => {
12246
+ var _a;
12247
+ const prevToken = this.authToken;
12248
+ await this.refreshToken();
12249
+ if (this.authToken && this.authToken !== prevToken && ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
12250
+ // Token changed — reconnect with fresh token
12251
+ this.ws.close(1000, 'Token refreshed');
12252
+ }
12253
+ }, 5 * 60 * 1000); // Check every 5 minutes
12138
12254
  }
12139
- // -----------------------------------------------------------------------
12140
- // WebSocket connection
12141
- // -----------------------------------------------------------------------
12142
12255
  async ensureConnected() {
12143
12256
  var _a;
12257
+ if (!this.appId) {
12258
+ if (!this.initPromise)
12259
+ this.initPromise = this.init();
12260
+ await this.initPromise;
12261
+ }
12144
12262
  if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN)
12145
12263
  return;
12146
12264
  if (this.connectPromise)
@@ -12156,10 +12274,12 @@ class RealtimeStore {
12156
12274
  }
12157
12275
  const params = new URLSearchParams();
12158
12276
  params.set('apiKey', this.appId);
12159
- // Auth token sent via subprotocol to avoid leaking in URL/logs
12277
+ if (this.authToken)
12278
+ params.set('authorization', this.authToken);
12279
+ // Note: token in URL is required until DO server supports subprotocol auth.
12280
+ // WSS encrypts the full URL including query params on the wire.
12160
12281
  const url = `${this.wsUrl}?${params.toString()}`;
12161
- const protocols = this.authToken ? [`bearer-${this.authToken}`] : undefined;
12162
- const ws = protocols ? new WebSocket(url, protocols) : new WebSocket(url);
12282
+ const ws = new WebSocket(url);
12163
12283
  this.ws = ws;
12164
12284
  const onOpen = () => {
12165
12285
  ws.removeEventListener('error', onError);
@@ -12790,6 +12910,8 @@ class RealtimeStore {
12790
12910
  clearTimeout(this.reconnectTimer);
12791
12911
  if (this.idbFlushTimer)
12792
12912
  clearTimeout(this.idbFlushTimer);
12913
+ if (this.tokenRefreshTimer)
12914
+ clearInterval(this.tokenRefreshTimer);
12793
12915
  this.flushIdb();
12794
12916
  if (this.ws) {
12795
12917
  this.ws.close(1000, 'Store closed');
@@ -13899,15 +14021,15 @@ function clearIncompatibleSession() {
13899
14021
  // Lazy loaders for web-only providers.
13900
14022
  // Using dynamic import() ensures Metro (RN) never resolves these modules.
13901
14023
  async function loadPrivyWalletProvider() {
13902
- const mod = await Promise.resolve().then(function () { return require('./privy-wallet-provider-CQnyjLEI.js'); });
14024
+ const mod = await Promise.resolve().then(function () { return require('./privy-wallet-provider-DsHSkIJJ.js'); });
13903
14025
  return mod.PrivyWalletProvider;
13904
14026
  }
13905
14027
  async function loadPhantomWalletProvider() {
13906
- const mod = await Promise.resolve().then(function () { return require('./phantom-wallet-provider-DV12qfW6.js'); });
14028
+ const mod = await Promise.resolve().then(function () { return require('./phantom-wallet-provider-LGxBWZXy.js'); });
13907
14029
  return { PhantomWalletProvider: mod.PhantomWalletProvider };
13908
14030
  }
13909
14031
  async function loadSolanaMobileWalletProvider() {
13910
- const mod = await Promise.resolve().then(function () { return require('./solana-mobile-wallet-provider-BmXTQow5.js'); });
14032
+ const mod = await Promise.resolve().then(function () { return require('./solana-mobile-wallet-provider-EkUSbs-q.js'); });
13911
14033
  return mod.SolanaMobileWalletProvider;
13912
14034
  }
13913
14035
  async function hotSwapToPrivyProvider(config) {
@@ -17339,6 +17461,7 @@ exports.base58 = base58;
17339
17461
  exports.buildSetDocumentsTransaction = buildSetDocumentsTransaction;
17340
17462
  exports.clearCache = clearCache;
17341
17463
  exports.closeAllSubscriptions = closeAllSubscriptions;
17464
+ exports.commonjsRequire = commonjsRequire;
17342
17465
  exports.confirmAndCheckTransaction = confirmAndCheckTransaction;
17343
17466
  exports.convertRemainingAccounts = convertRemainingAccounts;
17344
17467
  exports.count = count;
@@ -17370,6 +17493,7 @@ exports.onAuthLoadingChanged = onAuthLoadingChanged;
17370
17493
  exports.onAuthStateChanged = onAuthStateChanged;
17371
17494
  exports.reconnectWithNewAuth = reconnectWithNewAuth;
17372
17495
  exports.refreshSession = refreshSession;
17496
+ exports.require$$0 = require$$0;
17373
17497
  exports.requireBuffer = requireBuffer;
17374
17498
  exports.resetRealtimeStore = resetRealtimeStore;
17375
17499
  exports.runExpression = runExpression;
@@ -17393,4 +17517,4 @@ exports.wsGet = wsGet;
17393
17517
  exports.wsGetMany = wsGetMany;
17394
17518
  exports.wsQuery = wsQuery;
17395
17519
  exports.wsSet = wsSet;
17396
- //# sourceMappingURL=index.native-DIXtlrL_.js.map
17520
+ //# sourceMappingURL=index.native-CpA5KDvL.js.map