@pooflabs/web 0.0.86 → 0.0.87

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 (65) hide show
  1. package/dist/auth/providers/solana-mobile-wallet-provider.d.ts +43 -0
  2. package/dist/{index-D-Wbwevj.js → index-B-x9RTF7.js} +2 -2
  3. package/dist/index-B-x9RTF7.js.map +1 -0
  4. package/dist/{index-BHkED2YI.js → index-BKN0IwAx.js} +3054 -300
  5. package/dist/index-BKN0IwAx.js.map +1 -0
  6. package/dist/{index-BQUfNEiY.esm.js → index-BTwX7FYW.esm.js} +417 -74
  7. package/dist/index-BTwX7FYW.esm.js.map +1 -0
  8. package/dist/{index-DUn32Hkh.js → index-DYBdUxnT.js} +3055 -301
  9. package/dist/index-DYBdUxnT.js.map +1 -0
  10. package/dist/{index-hEc5_KoM.js → index-Dj1tZr6X.js} +418 -73
  11. package/dist/index-Dj1tZr6X.js.map +1 -0
  12. package/dist/{index-DK28JaJm.esm.js → index-DofM-ue2.esm.js} +3054 -301
  13. package/dist/index-DofM-ue2.esm.js.map +1 -0
  14. package/dist/index-_k6pjuwx.esm.js +6 -0
  15. package/dist/index-_k6pjuwx.esm.js.map +1 -0
  16. package/dist/{index-Cfp30Jm_.esm.js → index-x7a-wH2l.esm.js} +3055 -300
  17. package/dist/index-x7a-wH2l.esm.js.map +1 -0
  18. package/dist/{index.browser-DQqKPfDA.esm.js → index.browser-Cndx2raY.esm.js} +506 -1876
  19. package/dist/index.browser-Cndx2raY.esm.js.map +1 -0
  20. package/dist/{index.browser-CbawPvh6.js → index.browser-D7-FFk3q.js} +506 -1876
  21. package/dist/index.browser-D7-FFk3q.js.map +1 -0
  22. package/dist/{index.browser-DD8pg_L2.js → index.browser-DlA-NKvf.js} +1223 -2565
  23. package/dist/index.browser-DlA-NKvf.js.map +1 -0
  24. package/dist/{index.browser-C9gHoUen.esm.js → index.browser-nVGFrIHK.esm.js} +1223 -2565
  25. package/dist/index.browser-nVGFrIHK.esm.js.map +1 -0
  26. package/dist/index.esm.js +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/{index.native-BItnSD47.esm.js → index.native-19VsREMJ.esm.js} +43 -62
  29. package/dist/index.native-19VsREMJ.esm.js.map +1 -0
  30. package/dist/{index.native-7hiNiSyC.js → index.native-D8vj3Lbr.js} +44 -61
  31. package/dist/index.native-D8vj3Lbr.js.map +1 -0
  32. package/dist/index.native.esm.js +1 -1
  33. package/dist/index.native.js +1 -1
  34. package/dist/{phantom-wallet-provider-CjvLq_2_.js → phantom-wallet-provider-BlZZa_3s.js} +4 -4
  35. package/dist/{phantom-wallet-provider-CjvLq_2_.js.map → phantom-wallet-provider-BlZZa_3s.js.map} +1 -1
  36. package/dist/{phantom-wallet-provider-DE3vit2Z.esm.js → phantom-wallet-provider-Bz3qEFzX.esm.js} +4 -4
  37. package/dist/{phantom-wallet-provider-DE3vit2Z.esm.js.map → phantom-wallet-provider-Bz3qEFzX.esm.js.map} +1 -1
  38. package/dist/{privy-wallet-provider-DFZaQPss.js → privy-wallet-provider-CqCgq7uT.js} +3 -3
  39. package/dist/privy-wallet-provider-CqCgq7uT.js.map +1 -0
  40. package/dist/{privy-wallet-provider-ip2pqo_U.esm.js → privy-wallet-provider-DgNFzioA.esm.js} +3 -3
  41. package/dist/privy-wallet-provider-DgNFzioA.esm.js.map +1 -0
  42. package/dist/{solana-mobile-wallet-provider-D7BbSpez.esm.js → solana-mobile-wallet-provider-EeQsBTdr.esm.js} +378 -16
  43. package/dist/solana-mobile-wallet-provider-EeQsBTdr.esm.js.map +1 -0
  44. package/dist/{solana-mobile-wallet-provider-DwER68Rz.js → solana-mobile-wallet-provider-VqIGfdMV.js} +378 -16
  45. package/dist/solana-mobile-wallet-provider-VqIGfdMV.js.map +1 -0
  46. package/package.json +1 -1
  47. package/dist/index-BHkED2YI.js.map +0 -1
  48. package/dist/index-BQUfNEiY.esm.js.map +0 -1
  49. package/dist/index-Cfp30Jm_.esm.js.map +0 -1
  50. package/dist/index-D-Wbwevj.js.map +0 -1
  51. package/dist/index-DK28JaJm.esm.js.map +0 -1
  52. package/dist/index-DKyWaxCB.esm.js +0 -6
  53. package/dist/index-DKyWaxCB.esm.js.map +0 -1
  54. package/dist/index-DUn32Hkh.js.map +0 -1
  55. package/dist/index-hEc5_KoM.js.map +0 -1
  56. package/dist/index.browser-C9gHoUen.esm.js.map +0 -1
  57. package/dist/index.browser-CbawPvh6.js.map +0 -1
  58. package/dist/index.browser-DD8pg_L2.js.map +0 -1
  59. package/dist/index.browser-DQqKPfDA.esm.js.map +0 -1
  60. package/dist/index.native-7hiNiSyC.js.map +0 -1
  61. package/dist/index.native-BItnSD47.esm.js.map +0 -1
  62. package/dist/privy-wallet-provider-DFZaQPss.js.map +0 -1
  63. package/dist/privy-wallet-provider-ip2pqo_U.esm.js.map +0 -1
  64. package/dist/solana-mobile-wallet-provider-D7BbSpez.esm.js.map +0 -1
  65. package/dist/solana-mobile-wallet-provider-DwER68Rz.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-D-Wbwevj.js');
4
- var index_native = require('./index.native-7hiNiSyC.js');
3
+ var index = require('./index-B-x9RTF7.js');
4
+ var index_native = require('./index.native-D8vj3Lbr.js');
5
5
  var web3_js = require('@solana/web3.js');
6
6
  var anchor = require('@coral-xyz/anchor');
7
7
  require('axios');
@@ -26,6 +26,14 @@ function _interopNamespaceDefault(e) {
26
26
 
27
27
  var anchor__namespace = /*#__PURE__*/_interopNamespaceDefault(anchor);
28
28
 
29
+ /**
30
+ * Storage key for persisting the MWA auth_token across cold starts.
31
+ * Holds JSON `{ token: string, address: string }`. Cleared by
32
+ * `logout()`. Hydrated by the constructor on native so cold-start
33
+ * doesn't force the user back into Phantom's approval flow when the
34
+ * underlying wallet authorization is still valid.
35
+ */
36
+ const MWA_AUTH_TOKEN_STORAGE_KEY = 'tarobase_mwa_auth_token';
29
37
  const ED25519_SIGNATURE_LENGTH = 64;
30
38
  const STORED_AUTH_METHOD_KEY = 'tarobase_last_auth_method';
31
39
  const MWA_AUTH_METHOD = 'mobile-wallet-adapter';
@@ -527,19 +535,66 @@ class SolanaMobileWalletProvider {
527
535
  constructor(networkUrl = null, config = {}) {
528
536
  /** LocalSolanaMobileWalletAdapterWallet, lazy-constructed in ensureWallet(). */
529
537
  this.wallet = null;
538
+ /**
539
+ * Cached MWA auth_token returned by `wallet.authorize()`. Reused by
540
+ * subsequent native transact() calls (signMessage / signTransaction)
541
+ * so the user doesn't get the wallet-pick popup on every operation.
542
+ * Persisted to platform storage and hydrated by the constructor on
543
+ * native; cleared by logout() and on `ERROR_REAUTHORIZE`.
544
+ */
545
+ this.nativeAuthToken = null;
546
+ /** Cached public key string for the connected MWA wallet (native). */
547
+ this.nativeAddress = null;
530
548
  this.networkUrl = networkUrl;
531
549
  this.config = config;
532
- if (typeof window === 'undefined') {
550
+ // Allow construction in true React Native environments: getPlatform().hasDOM
551
+ // is false there even though `typeof window === 'object'` (RN exposes a
552
+ // partial window global). Web/PWA paths still keep their original guard:
553
+ // they need real window+document for wallet-standard-mobile's deep-link
554
+ // mechanism, so missing-window in those builds remains a fail-fast.
555
+ const hasDOM = index_native.getPlatform().hasDOM;
556
+ if (!hasDOM && typeof window === 'undefined') {
557
+ throw new Error('SolanaMobileWalletProvider can only be instantiated in a browser or React Native environment');
558
+ }
559
+ if (hasDOM && typeof window === 'undefined') {
533
560
  throw new Error('SolanaMobileWalletProvider can only be instantiated in a browser environment');
534
561
  }
535
562
  if (SolanaMobileWalletProvider.instance) {
536
563
  return SolanaMobileWalletProvider.instance;
537
564
  }
565
+ // `appIdentity.uri` is what Phantom Android (and other MWA wallets)
566
+ // display in their approval modal. On web/PWA this is the page
567
+ // origin; on native there's no `window.location`, so fall back to
568
+ // a stable identifier the user can recognize. Apps can override
569
+ // entirely via `config.appIdentity.uri`.
570
+ const fallbackUri = hasDOM
571
+ ? index_native.getPlatform().getLocationOrigin()
572
+ : 'tarobase://app';
538
573
  this.appIdentity = config.appIdentity || {
539
574
  name: 'TaroBase App',
540
- uri: index_native.getPlatform().getLocationOrigin(),
575
+ uri: fallbackUri,
541
576
  };
542
577
  this.cluster = config.cluster || 'mainnet-beta';
578
+ // Hydrate cached MWA auth_token from storage on native so we can
579
+ // skip the wallet-pick popup after a cold-start when the underlying
580
+ // wallet authorization is still valid. Sync storage call per the
581
+ // PlatformAdapter contract; safe to swallow read errors (a fresh
582
+ // login() just re-authorizes).
583
+ if (!hasDOM) {
584
+ try {
585
+ const raw = index_native.getPlatform().storage.getItem(MWA_AUTH_TOKEN_STORAGE_KEY);
586
+ if (raw) {
587
+ const parsed = JSON.parse(raw);
588
+ if (typeof parsed.token === 'string' && typeof parsed.address === 'string') {
589
+ this.nativeAuthToken = parsed.token;
590
+ this.nativeAddress = parsed.address;
591
+ }
592
+ }
593
+ }
594
+ catch (_a) {
595
+ // Corrupt or unreadable cache — ignore. login() will re-auth.
596
+ }
597
+ }
543
598
  SolanaMobileWalletProvider.instance = this;
544
599
  }
545
600
  static getInstance(networkUrl, config) {
@@ -552,7 +607,7 @@ class SolanaMobileWalletProvider {
552
607
  async ensureWallet() {
553
608
  if (this.wallet)
554
609
  return this.wallet;
555
- const mod = await Promise.resolve().then(function () { return require('./index.browser-CbawPvh6.js'); });
610
+ const mod = await Promise.resolve().then(function () { return require('./index.browser-D7-FFk3q.js'); });
556
611
  const chain = mapChainToWalletStandard(this.cluster);
557
612
  this.wallet = new mod.LocalSolanaMobileWalletAdapterWallet({
558
613
  appIdentity: this.appIdentity,
@@ -602,6 +657,134 @@ class SolanaMobileWalletProvider {
602
657
  getChain() {
603
658
  return mapChainToWalletStandard(this.cluster);
604
659
  }
660
+ /**
661
+ * Dynamically import and unwrap `transact` from the MWA web3js
662
+ * package. The package is externalized in rollup.config.js so this
663
+ * resolves to `lib/cjs/index.native.js` (TurboModule-backed) on
664
+ * Metro and `lib/esm/index.browser.js` (WebSocket) on webpack/vite
665
+ * per their respective platform conditions. Handles Metro's CJS-to-
666
+ * ESM interop variance (`mod.transact` vs `mod.default?.transact`).
667
+ */
668
+ async loadTransact() {
669
+ var _a;
670
+ const mod = await import('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
671
+ const t = mod.transact || ((_a = mod.default) === null || _a === void 0 ? void 0 : _a.transact);
672
+ if (typeof t !== 'function') {
673
+ throw new Error('MWA transact API not available on this platform');
674
+ }
675
+ return t;
676
+ }
677
+ /**
678
+ * Cache and persist a fresh MWA auth_token + address. Called from
679
+ * `_loginNative` after a successful authorize. Storage failures are
680
+ * non-fatal (next cold-start re-auths).
681
+ */
682
+ persistNativeAuth(token, address) {
683
+ this.nativeAuthToken = token;
684
+ this.nativeAddress = address;
685
+ try {
686
+ index_native.getPlatform().storage.setItem(MWA_AUTH_TOKEN_STORAGE_KEY, JSON.stringify({ token, address }));
687
+ }
688
+ catch (_a) {
689
+ // non-fatal — token still in-memory for this process
690
+ }
691
+ }
692
+ /** Clear cached + persisted native auth state. */
693
+ clearNativeAuth() {
694
+ this.nativeAuthToken = null;
695
+ this.nativeAddress = null;
696
+ try {
697
+ index_native.getPlatform().storage.removeItem(MWA_AUTH_TOKEN_STORAGE_KEY);
698
+ }
699
+ catch (_a) {
700
+ // ignore
701
+ }
702
+ }
703
+ /**
704
+ * Classify an MWA-native error as a user cancellation. User-cancel
705
+ * shouldn't surface as a red console.error; callers can swallow or
706
+ * show a softer message. MWA spec codes plus the same substring
707
+ * checks the web path uses to catch wallet-specific phrasing.
708
+ */
709
+ isNativeUserCancel(err) {
710
+ var _a;
711
+ if (!err)
712
+ return false;
713
+ const code = err.code;
714
+ if (code === 'ERROR_NOT_SIGNED')
715
+ return true;
716
+ const msg = String((_a = err.message) !== null && _a !== void 0 ? _a : '').toLowerCase();
717
+ return /user (rejected|denied|cancelled|canceled|declined)/.test(msg);
718
+ }
719
+ /**
720
+ * Native MWA login via @solana-mobile/mobile-wallet-adapter-protocol-web3js.
721
+ * Used in true React Native (Expo) environments where wallet-standard-mobile's
722
+ * web universal-link path doesn't apply. Does authorize + signMessage in a
723
+ * single transact() roundtrip — intent-based MWA doesn't need the two-popup
724
+ * dance the web path uses (no Chrome activation-loss concern). Persists the
725
+ * resulting auth_token so cold-start can reauthorize without a fresh popup.
726
+ */
727
+ async _loginNative() {
728
+ const transact = await this.loadTransact();
729
+ const existingSession = await index_native.WebSessionManager.getSession();
730
+ const nonce = await index_native.genAuthNonce();
731
+ const result = await transact(async (wallet) => {
732
+ const auth = await wallet.authorize({
733
+ chain: this.getChain(),
734
+ identity: this.appIdentity,
735
+ });
736
+ if (!auth.accounts || auth.accounts.length === 0) {
737
+ throw new Error('MWA returned no accounts');
738
+ }
739
+ const account = auth.accounts[0];
740
+ // account.address is base64-encoded per MWA spec; convert to
741
+ // the base58 form Tarobase + the rest of the SDK use.
742
+ const base58Addr = new web3_js.PublicKey(index.bufferExports.Buffer.from(account.address, 'base64')).toBase58();
743
+ // Reuse session if already valid for this address — skip the
744
+ // signMessages roundtrip entirely.
745
+ if (existingSession && existingSession.address === base58Addr) {
746
+ return {
747
+ base58Addr,
748
+ authToken: auth.auth_token,
749
+ signatureBase64: null,
750
+ };
751
+ }
752
+ const messageText = await index_native.genSolanaMessage(base58Addr, nonce);
753
+ const messageBytes = index_native.getPlatform().textEncode(messageText);
754
+ const signatures = await wallet.signMessages({
755
+ addresses: [account.address],
756
+ payloads: [messageBytes],
757
+ });
758
+ if (!signatures || signatures.length === 0) {
759
+ throw new Error('MWA returned no signature');
760
+ }
761
+ // Per spec, signMessages returns Uint8Array[] of signatures
762
+ // (one per payload), not message+signature concatenations.
763
+ const signatureBase64 = index.bufferExports.Buffer.from(signatures[0]).toString('base64');
764
+ return {
765
+ base58Addr,
766
+ authToken: auth.auth_token,
767
+ signatureBase64,
768
+ messageText,
769
+ };
770
+ });
771
+ this.persistNativeAuth(result.authToken, result.base58Addr);
772
+ // Existing valid session — short-circuit before re-creating server-side.
773
+ if (existingSession && existingSession.address === result.base58Addr) {
774
+ const user = { provider: this, address: result.base58Addr };
775
+ index_native.setCurrentUser(user);
776
+ return user;
777
+ }
778
+ // Create Tarobase session on the server.
779
+ if (!result.signatureBase64 || !result.messageText) {
780
+ throw new Error('MWA login completed without signature');
781
+ }
782
+ const createSessionResult = await index_native.createSessionWithSignature(result.base58Addr, result.messageText, result.signatureBase64);
783
+ await index_native.WebSessionManager.storeSession(result.base58Addr, createSessionResult.accessToken, createSessionResult.idToken, createSessionResult.refreshToken);
784
+ const user = { provider: this, address: result.base58Addr };
785
+ index_native.setCurrentUser(user);
786
+ return user;
787
+ }
605
788
  async login() {
606
789
  var _a, _b, _c, _d, _e;
607
790
  index_native.setAuthLoading(true);
@@ -612,6 +795,13 @@ class SolanaMobileWalletProvider {
612
795
  const prevAuthMethod = readAuthMethod();
613
796
  writeAuthMethod(MWA_AUTH_METHOD);
614
797
  try {
798
+ // True React Native: skip the wallet-standard-mobile path (which
799
+ // requires window.isSecureContext and a real DOM) and use the raw
800
+ // MWA protocol via Android intents.
801
+ if (!index_native.getPlatform().hasDOM) {
802
+ const user = await this._loginNative();
803
+ return user;
804
+ }
615
805
  const wallet = await this.ensureWallet();
616
806
  // Quick-check: wallet may already have authorization (e.g. from a
617
807
  // previous in-page login) and a matching Tarobase session — skip
@@ -713,6 +903,29 @@ class SolanaMobileWalletProvider {
713
903
  return null;
714
904
  }
715
905
  async logout() {
906
+ if (!index_native.getPlatform().hasDOM) {
907
+ // Native path: deauthorize the cached MWA auth_token if we have
908
+ // one (failures non-fatal — the wallet app may have been
909
+ // uninstalled or the token already revoked), then clear local
910
+ // and persisted state.
911
+ const token = this.nativeAuthToken;
912
+ if (token) {
913
+ try {
914
+ const transact = await this.loadTransact();
915
+ await transact(async (wallet) => {
916
+ await wallet.deauthorize({ auth_token: token });
917
+ });
918
+ }
919
+ catch (error) {
920
+ console.warn('[SolanaMobileWallet] Native deauthorize error:', error);
921
+ }
922
+ }
923
+ this.clearNativeAuth();
924
+ index_native.WebSessionManager.clearSession();
925
+ writeAuthMethod(null);
926
+ index_native.setCurrentUser(null);
927
+ return;
928
+ }
716
929
  try {
717
930
  const wallet = await this.ensureWallet();
718
931
  const disconnectFeat = getDisconnectFeature(wallet);
@@ -732,7 +945,42 @@ class SolanaMobileWalletProvider {
732
945
  index_native.setCurrentUser(null);
733
946
  }
734
947
  async signMessage(message) {
735
- var _a, _b;
948
+ var _a, _b, _c;
949
+ // Native: reauthorize with cached auth_token, then signMessages inside
950
+ // the same transact() session. No wallet-pick popup if the auth_token
951
+ // is still valid for the user's wallet.
952
+ if (!index_native.getPlatform().hasDOM) {
953
+ if (!this.nativeAuthToken || !this.nativeAddress) {
954
+ throw new Error('Wallet not connected. Call login() first.');
955
+ }
956
+ const transact = await this.loadTransact();
957
+ const messageBytes = index_native.getPlatform().textEncode(message);
958
+ const addressBase64 = new web3_js.PublicKey(this.nativeAddress).toBuffer().toString('base64');
959
+ const authToken = this.nativeAuthToken;
960
+ try {
961
+ const signature = await transact(async (wallet) => {
962
+ await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
963
+ const sigs = await wallet.signMessages({
964
+ addresses: [addressBase64],
965
+ payloads: [messageBytes],
966
+ });
967
+ if (!sigs || sigs.length === 0)
968
+ throw new Error('MWA returned no signature');
969
+ return sigs[0];
970
+ });
971
+ return index.bufferExports.Buffer.from(signature).toString('base64');
972
+ }
973
+ catch (error) {
974
+ if (this.isNativeUserCancel(error)) {
975
+ throw new Error('User declined to sign');
976
+ }
977
+ if ((error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED' || (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_REAUTHORIZE') {
978
+ await this.logout();
979
+ throw new Error('Wallet connection lost. Please reconnect.');
980
+ }
981
+ throw new Error(`Failed to sign message: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
982
+ }
983
+ }
736
984
  const account = await this.ensureAuthorized();
737
985
  const wallet = await this.ensureWallet();
738
986
  try {
@@ -746,7 +994,7 @@ class SolanaMobileWalletProvider {
746
994
  return index.bufferExports.Buffer.from(sigBytes).toString('base64');
747
995
  }
748
996
  catch (error) {
749
- if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
997
+ if (((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not connected')) || ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('not authorized')) ||
750
998
  (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
751
999
  await this.logout();
752
1000
  throw new Error('Wallet connection lost. Please reconnect.');
@@ -755,7 +1003,58 @@ class SolanaMobileWalletProvider {
755
1003
  }
756
1004
  }
757
1005
  async signTransaction(transaction) {
758
- var _a, _b;
1006
+ var _a, _b, _c;
1007
+ // Native: fill blockhash/feePayer if missing, then signTransactions
1008
+ // inside a transact() session keyed by the cached auth_token.
1009
+ if (!index_native.getPlatform().hasDOM) {
1010
+ if (!this.nativeAuthToken || !this.nativeAddress) {
1011
+ throw new Error('Wallet not connected. Call login() first.');
1012
+ }
1013
+ const connectedPubkey = new web3_js.PublicKey(this.nativeAddress);
1014
+ const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
1015
+ if (isLegacyTransaction) {
1016
+ const legacyTx = transaction;
1017
+ if (!legacyTx.recentBlockhash) {
1018
+ const conn = new web3_js.Connection(this.getRpcUrl(), 'confirmed');
1019
+ const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash('confirmed');
1020
+ legacyTx.recentBlockhash = blockhash;
1021
+ legacyTx.lastValidBlockHeight = lastValidBlockHeight;
1022
+ }
1023
+ if (!legacyTx.feePayer) {
1024
+ legacyTx.feePayer = connectedPubkey;
1025
+ }
1026
+ }
1027
+ else {
1028
+ const versionedTx = transaction;
1029
+ if (!versionedTx.message.recentBlockhash) {
1030
+ const conn = new web3_js.Connection(this.getRpcUrl(), 'confirmed');
1031
+ const { blockhash } = await conn.getLatestBlockhash('confirmed');
1032
+ versionedTx.message.recentBlockhash = blockhash;
1033
+ }
1034
+ }
1035
+ const transact = await this.loadTransact();
1036
+ const authToken = this.nativeAuthToken;
1037
+ try {
1038
+ const signed = await transact(async (wallet) => {
1039
+ await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
1040
+ const results = await wallet.signTransactions({ transactions: [transaction] });
1041
+ if (!results || results.length === 0)
1042
+ throw new Error('MWA returned no signed transaction');
1043
+ return results[0];
1044
+ });
1045
+ return signed;
1046
+ }
1047
+ catch (error) {
1048
+ if (this.isNativeUserCancel(error)) {
1049
+ throw new Error('User declined to sign');
1050
+ }
1051
+ if ((error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED' || (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_REAUTHORIZE') {
1052
+ await this.logout();
1053
+ throw new Error('Wallet connection lost. Please reconnect.');
1054
+ }
1055
+ throw new Error(`Failed to sign transaction: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
1056
+ }
1057
+ }
759
1058
  const account = await this.ensureAuthorized();
760
1059
  const connectedPubkey = new web3_js.PublicKey(account.publicKey);
761
1060
  const wallet = await this.ensureWallet();
@@ -794,7 +1093,7 @@ class SolanaMobileWalletProvider {
794
1093
  return txFromWireBytes(new Uint8Array(signedBytes));
795
1094
  }
796
1095
  catch (error) {
797
- if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
1096
+ if (((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not connected')) || ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('not authorized')) ||
798
1097
  (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
799
1098
  await this.logout();
800
1099
  throw new Error('Wallet connection lost. Please reconnect.');
@@ -803,7 +1102,70 @@ class SolanaMobileWalletProvider {
803
1102
  }
804
1103
  }
805
1104
  async signAndSubmitTransaction(transaction, feePayer) {
806
- var _a, _b, _c, _d, _e, _f;
1105
+ var _a, _b, _c, _d, _e, _f, _g;
1106
+ // Native: signAndSendTransactions inside a transact() session.
1107
+ // The wallet submits to its own RPC; we then await confirmation on
1108
+ // ours. Surfnet (custom RPC) needs manual submission because the
1109
+ // wallet won't route there — we fall back to sign-only + manual send.
1110
+ if (!index_native.getPlatform().hasDOM) {
1111
+ if (!this.nativeAuthToken || !this.nativeAddress) {
1112
+ throw new Error('Wallet not connected. Call login() first.');
1113
+ }
1114
+ const connectedPubkey = new web3_js.PublicKey(this.nativeAddress);
1115
+ const rpcUrl = this.getRpcUrl();
1116
+ const connection = new web3_js.Connection(rpcUrl, 'confirmed');
1117
+ const isSurfnet = rpcUrl === index_native.SURFNET_RPC_URL;
1118
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
1119
+ const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
1120
+ if (isLegacyTransaction) {
1121
+ const legacyTx = transaction;
1122
+ legacyTx.recentBlockhash = blockhash;
1123
+ legacyTx.lastValidBlockHeight = lastValidBlockHeight;
1124
+ if (!legacyTx.feePayer)
1125
+ legacyTx.feePayer = feePayer !== null && feePayer !== void 0 ? feePayer : connectedPubkey;
1126
+ }
1127
+ else {
1128
+ const versionedTx = transaction;
1129
+ versionedTx.message.recentBlockhash = blockhash;
1130
+ }
1131
+ const transact = await this.loadTransact();
1132
+ const authToken = this.nativeAuthToken;
1133
+ try {
1134
+ if (isSurfnet) {
1135
+ // Surfnet: sign only, submit manually to Surfnet RPC
1136
+ // (the wallet would route signAndSend to its own RPC).
1137
+ const signed = await transact(async (wallet) => {
1138
+ await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
1139
+ const results = await wallet.signTransactions({ transactions: [transaction] });
1140
+ if (!results || results.length === 0)
1141
+ throw new Error('MWA returned no signed transaction');
1142
+ return results[0];
1143
+ });
1144
+ const sig = await connection.sendRawTransaction(signed.serialize(), { preflightCommitment: 'confirmed' });
1145
+ await index_native.confirmAndCheckTransaction(connection, sig);
1146
+ return sig;
1147
+ }
1148
+ const sig = await transact(async (wallet) => {
1149
+ await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
1150
+ const results = await wallet.signAndSendTransactions({ transactions: [transaction] });
1151
+ if (!results || results.length === 0)
1152
+ throw new Error('MWA returned no signature');
1153
+ return results[0];
1154
+ });
1155
+ await index_native.confirmAndCheckTransaction(connection, sig);
1156
+ return sig;
1157
+ }
1158
+ catch (error) {
1159
+ if (this.isNativeUserCancel(error)) {
1160
+ throw new Error('User declined to sign');
1161
+ }
1162
+ if ((error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED' || (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_REAUTHORIZE') {
1163
+ await this.logout();
1164
+ throw new Error('Wallet connection lost. Please reconnect.');
1165
+ }
1166
+ throw new Error(`Failed to sign+submit transaction: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
1167
+ }
1168
+ }
807
1169
  const account = await this.ensureAuthorized();
808
1170
  const connectedPubkey = new web3_js.PublicKey(account.publicKey);
809
1171
  const wallet = await this.ensureWallet();
@@ -870,16 +1232,16 @@ class SolanaMobileWalletProvider {
870
1232
  return signature;
871
1233
  }
872
1234
  catch (error) {
873
- if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
1235
+ if (((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not connected')) || ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('not authorized')) ||
874
1236
  (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
875
1237
  await this.logout();
876
1238
  throw new Error('Wallet connection lost. Please reconnect.');
877
1239
  }
878
1240
  const isUserRejection = (error === null || error === void 0 ? void 0 : error.code) === 4001 ||
879
- ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.toLowerCase().includes('user rejected')) ||
880
- ((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.toLowerCase().includes('user denied')) ||
881
- ((_e = error === null || error === void 0 ? void 0 : error.message) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes('user cancelled')) ||
882
- ((_f = error === null || error === void 0 ? void 0 : error.message) === null || _f === void 0 ? void 0 : _f.toLowerCase().includes('user canceled'));
1241
+ ((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.toLowerCase().includes('user rejected')) ||
1242
+ ((_e = error === null || error === void 0 ? void 0 : error.message) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes('user denied')) ||
1243
+ ((_f = error === null || error === void 0 ? void 0 : error.message) === null || _f === void 0 ? void 0 : _f.toLowerCase().includes('user cancelled')) ||
1244
+ ((_g = error === null || error === void 0 ? void 0 : error.message) === null || _g === void 0 ? void 0 : _g.toLowerCase().includes('user canceled'));
883
1245
  if (!isUserRejection) {
884
1246
  console.error('[SolanaMobileWallet] Transaction failed:', error);
885
1247
  }
@@ -1084,4 +1446,4 @@ class SolanaMobileWalletProvider {
1084
1446
  SolanaMobileWalletProvider.instance = null;
1085
1447
 
1086
1448
  exports.SolanaMobileWalletProvider = SolanaMobileWalletProvider;
1087
- //# sourceMappingURL=solana-mobile-wallet-provider-DwER68Rz.js.map
1449
+ //# sourceMappingURL=solana-mobile-wallet-provider-VqIGfdMV.js.map