@bounded-sh/client 0.0.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.
Files changed (65) hide show
  1. package/README.md +298 -0
  2. package/dist/auth/hooks/useAuth.d.ts +8 -0
  3. package/dist/auth/index.d.ts +73 -0
  4. package/dist/auth/oidc-auth.d.ts +27 -0
  5. package/dist/auth/providers/email-auth-provider.d.ts +38 -0
  6. package/dist/auth/providers/guest-auth-provider.d.ts +14 -0
  7. package/dist/auth/providers/guest-keystore.d.ts +12 -0
  8. package/dist/auth/providers/mock-auth-provider.d.ts +49 -0
  9. package/dist/auth/providers/offchain-auth-provider.d.ts +56 -0
  10. package/dist/auth/providers/phantom-wallet-provider.d.ts +117 -0
  11. package/dist/auth/providers/privy-expo-provider.d.ts +115 -0
  12. package/dist/auth/providers/privy-wallet-provider.d.ts +80 -0
  13. package/dist/auth/providers/sol/sol-utils.d.ts +2 -0
  14. package/dist/auth/providers/solana-mobile-wallet-provider.d.ts +155 -0
  15. package/dist/auth/providers/transaction-utils.d.ts +10 -0
  16. package/dist/global.d.ts +13 -0
  17. package/dist/index-BHTfW8CV.esm.js +16091 -0
  18. package/dist/index-BHTfW8CV.esm.js.map +1 -0
  19. package/dist/index-C1VOdmRN.js +16130 -0
  20. package/dist/index-C1VOdmRN.js.map +1 -0
  21. package/dist/index-CT2j1oic.esm.js +16089 -0
  22. package/dist/index-CT2j1oic.esm.js.map +1 -0
  23. package/dist/index-VGx-869x.js +23572 -0
  24. package/dist/index-VGx-869x.js.map +1 -0
  25. package/dist/index-o5Hv9pfS.esm.js +23456 -0
  26. package/dist/index-o5Hv9pfS.esm.js.map +1 -0
  27. package/dist/index-sKqrgk0t.js +16132 -0
  28. package/dist/index-sKqrgk0t.js.map +1 -0
  29. package/dist/index.browser-BJZ7fYwv.js +5081 -0
  30. package/dist/index.browser-BJZ7fYwv.js.map +1 -0
  31. package/dist/index.browser-DaNhOhkQ.esm.js +4220 -0
  32. package/dist/index.browser-DaNhOhkQ.esm.js.map +1 -0
  33. package/dist/index.browser-DhAcjdpV.esm.js +5071 -0
  34. package/dist/index.browser-DhAcjdpV.esm.js.map +1 -0
  35. package/dist/index.browser-utVKQsEC.js +4225 -0
  36. package/dist/index.browser-utVKQsEC.js.map +1 -0
  37. package/dist/index.d.ts +21 -0
  38. package/dist/index.esm.js +8 -0
  39. package/dist/index.esm.js.map +1 -0
  40. package/dist/index.js +105 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/index.native-B5IBOdv_.js +19684 -0
  43. package/dist/index.native-B5IBOdv_.js.map +1 -0
  44. package/dist/index.native-JPUkdHJj.esm.js +19565 -0
  45. package/dist/index.native-JPUkdHJj.esm.js.map +1 -0
  46. package/dist/index.native.d.ts +26 -0
  47. package/dist/index.native.esm.js +6 -0
  48. package/dist/index.native.esm.js.map +1 -0
  49. package/dist/index.native.js +98 -0
  50. package/dist/index.native.js.map +1 -0
  51. package/dist/phantom-wallet-provider-CDLyxrih.js +1466 -0
  52. package/dist/phantom-wallet-provider-CDLyxrih.js.map +1 -0
  53. package/dist/phantom-wallet-provider-DMlaSrAl.esm.js +1445 -0
  54. package/dist/phantom-wallet-provider-DMlaSrAl.esm.js.map +1 -0
  55. package/dist/platform.d.ts +81 -0
  56. package/dist/privy-wallet-provider-DiHHTDbZ.js +956 -0
  57. package/dist/privy-wallet-provider-DiHHTDbZ.js.map +1 -0
  58. package/dist/privy-wallet-provider-nR52lXzI.esm.js +933 -0
  59. package/dist/privy-wallet-provider-nR52lXzI.esm.js.map +1 -0
  60. package/dist/solana-mobile-wallet-provider-B4CeMMQd.esm.js +1460 -0
  61. package/dist/solana-mobile-wallet-provider-B4CeMMQd.esm.js.map +1 -0
  62. package/dist/solana-mobile-wallet-provider-BYMfFjZb.js +1481 -0
  63. package/dist/solana-mobile-wallet-provider-BYMfFjZb.js.map +1 -0
  64. package/dist/utils.d.ts +1 -0
  65. package/package.json +100 -0
@@ -0,0 +1,956 @@
1
+ 'use strict';
2
+
3
+ var index_native = require('./index.native-B5IBOdv_.js');
4
+ var web3_js = require('@solana/web3.js');
5
+ var anchor = require('@coral-xyz/anchor');
6
+ var kit = require('@solana/kit');
7
+ var React = require('react');
8
+ var ReactDOM = require('react-dom/client');
9
+ require('axios');
10
+
11
+ function _interopNamespaceDefault(e) {
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var anchor__namespace = /*#__PURE__*/_interopNamespaceDefault(anchor);
29
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
30
+ var ReactDOM__namespace = /*#__PURE__*/_interopNamespaceDefault(ReactDOM);
31
+
32
+ const SURFNET_RPC_URL = "https://surfpool.fly.dev";
33
+ // @privy-io/react-auth(/solana) are OPTIONAL peer deps. They are loaded lazily
34
+ // via dynamic import() rather than a static top-level import: a static import
35
+ // would (a) in the ESM bundle still be a bare `import` the consumer resolves —
36
+ // fine — but (b) in the CJS bundle become an eager top-level require() that
37
+ // throws for any consumer who hasn't installed Privy (this module is pulled
38
+ // into the entry via a static re-export). The lazy import keeps the browser
39
+ // ESM bundle free of any runtime `require('@privy-io...')` AND lets a consumer
40
+ // who never uses Privy load the package without it installed. Populated once
41
+ // in `initialize()` (browser-only) before the Privy React tree renders.
42
+ let privyImports;
43
+ let privySolana;
44
+ async function loadPrivyModules() {
45
+ if (privyImports && privySolana)
46
+ return;
47
+ [privyImports, privySolana] = await Promise.all([
48
+ import('@privy-io/react-auth'),
49
+ import('@privy-io/react-auth/solana'),
50
+ ]);
51
+ }
52
+ const getDefaultPrivyConfig = () => ({
53
+ appId: "cm4ve714908o27dk2yurpnfhd",
54
+ config: {
55
+ embeddedWallets: {
56
+ solana: {
57
+ createOnLogin: "users-without-wallets"
58
+ }
59
+ },
60
+ appearance: {
61
+ walletChainType: 'solana-only'
62
+ },
63
+ externalWallets: { solana: { connectors: privySolana.toSolanaWalletConnectors() } }
64
+ }
65
+ });
66
+ class PrivyWalletProvider {
67
+ constructor(appName, appLogoUrl, privyConfig, networkUrl = null) {
68
+ this.containerElement = null;
69
+ this.chainId = 'solana:mainnet';
70
+ this.root = null;
71
+ this.privyMethods = null;
72
+ this.pendingLogin = null;
73
+ // This is used to store the pending transaction until the wallet is connected for workaround for the wallet not being connected after login completion
74
+ this.pendingTransaction = null;
75
+ // This is used to store pending signTransaction calls until the wallet is connected
76
+ this.pendingSignTransaction = null;
77
+ // This is used to store pending signMessage calls until the wallet is connected
78
+ this.pendingSignMessage = null;
79
+ // This is used to store pending signAndSubmitTransaction calls until the wallet is connected
80
+ this.pendingSignAndSubmitTransaction = null;
81
+ this.networkUrl = networkUrl;
82
+ if (typeof window === 'undefined') {
83
+ throw new Error('PrivyWalletProvider can only be instantiated in a browser environment');
84
+ }
85
+ if (PrivyWalletProvider.instance) {
86
+ return PrivyWalletProvider.instance;
87
+ }
88
+ this.containerElement = null;
89
+ this.root = null;
90
+ this.privyMethods = null;
91
+ this.privyConfig = privyConfig !== null && privyConfig !== void 0 ? privyConfig : getDefaultPrivyConfig();
92
+ // Only use the appName and appLogoUrl if no privyConfig is provided
93
+ if (privyConfig == null) {
94
+ if (appName != null && appName != '') {
95
+ this.privyConfig.config.appearance.landingHeader = appName;
96
+ }
97
+ if (appLogoUrl != null && appLogoUrl != '') {
98
+ this.privyConfig.config.appearance.logo = appLogoUrl;
99
+ }
100
+ }
101
+ // (externalWallets connectors are configured in initialize() once the
102
+ // Privy SDK is lazily loaded — see loadPrivyModules.)
103
+ // Add Solana RPC configuration for v3
104
+ let devnetUrl = index_native.SOLANA_DEVNET_RPC_URL;
105
+ let mainnetUrl = index_native.SOLANA_MAINNET_RPC_URL;
106
+ if (networkUrl != null) {
107
+ if (networkUrl.includes('mainnet')) {
108
+ mainnetUrl = networkUrl;
109
+ this.chainId = 'solana:mainnet';
110
+ }
111
+ else if (networkUrl.includes('devnet')) {
112
+ devnetUrl = networkUrl;
113
+ this.chainId = 'solana:devnet';
114
+ }
115
+ }
116
+ if (!this.privyConfig.config.solana) {
117
+ this.privyConfig.config.solana = {};
118
+ }
119
+ this.privyConfig.config.solana.rpcs = {
120
+ 'solana:devnet': {
121
+ rpc: kit.createSolanaRpc(devnetUrl),
122
+ rpcSubscriptions: kit.createSolanaRpcSubscriptions(devnetUrl.replace('https://', 'wss://'))
123
+ },
124
+ 'solana:mainnet': {
125
+ rpc: kit.createSolanaRpc(mainnetUrl),
126
+ rpcSubscriptions: kit.createSolanaRpcSubscriptions(mainnetUrl.replace('https://', 'wss://'))
127
+ }
128
+ };
129
+ const existingProviders = document.querySelectorAll('[data-privy-provider]');
130
+ existingProviders.forEach(el => el.remove());
131
+ // Fire-and-forget: initialize() lazily loads the Privy SDK then renders
132
+ // the hidden React tree. privyMethods stays null until that render runs,
133
+ // which the login/connect methods already wait for. Surface a clear error
134
+ // if the optional @privy-io/react-auth peer dep isn't installed.
135
+ this.initialize().catch((err) => {
136
+ console.error('PrivyWalletProvider: failed to load @privy-io/react-auth — ensure it is installed to use Privy login.', err);
137
+ });
138
+ // Assign this instance to the static instance property
139
+ PrivyWalletProvider.instance = this;
140
+ }
141
+ // Optional: Provide a static method to get the instance
142
+ static getInstance(appName, appLogoUrl, privyConfig) {
143
+ if (!PrivyWalletProvider.instance) {
144
+ new PrivyWalletProvider(appName, appLogoUrl, privyConfig);
145
+ }
146
+ return PrivyWalletProvider.instance;
147
+ }
148
+ async initialize() {
149
+ // Lazily load the Privy SDK (browser-only) before building the React tree.
150
+ await loadPrivyModules();
151
+ // Ensure externalWallets connectors are always configured — required for
152
+ // useWallets().ready to resolve even when no browser extension is present.
153
+ if (!this.privyConfig.config.externalWallets && privySolana) {
154
+ this.privyConfig.config.externalWallets = {
155
+ solana: { connectors: privySolana.toSolanaWalletConnectors() }
156
+ };
157
+ }
158
+ if (!this.containerElement) {
159
+ this.containerElement = document.createElement('div');
160
+ this.containerElement.setAttribute('data-privy-provider', 'true');
161
+ document.body.appendChild(this.containerElement);
162
+ const that = this;
163
+ const PrivyComponent = () => {
164
+ const privy = privyImports.usePrivy();
165
+ const useOAuthTokens = privyImports.useOAuthTokens();
166
+ const useFundWalletSolana = privySolana.useFundWallet();
167
+ const useSendTransactionSolana = privySolana.useSignAndSendTransaction();
168
+ const { signTransaction } = privySolana.useSignTransaction();
169
+ const { signMessage: signMessageHook } = privySolana.useSignMessage();
170
+ const { ready: walletReady, wallets } = privySolana.useWallets();
171
+ const { createWallet } = privySolana.useCreateWallet();
172
+ const { exportWallet } = privySolana.useExportWallet();
173
+ const useSolanaWallets = { createWallet, exportWallet, ready: walletReady, wallets };
174
+ const useIdentityToken = privyImports.useIdentityToken();
175
+ const { connectWallet } = privyImports.useConnectWallet({
176
+ onSuccess: async ({ wallet }) => {
177
+ await that.createSession(wallet.address, await privy.getAccessToken(), useIdentityToken.identityToken);
178
+ // If there's a pending transaction, execute it now
179
+ if (that.pendingTransaction) {
180
+ const { evmTransactionData, solTransactionData, options, resolve, reject } = that.pendingTransaction;
181
+ try {
182
+ const result = await that.runTransaction(evmTransactionData, solTransactionData, options);
183
+ resolve(result);
184
+ }
185
+ catch (error) {
186
+ reject(error);
187
+ }
188
+ that.pendingTransaction = null;
189
+ }
190
+ // If there's a pending signTransaction, execute it now
191
+ if (that.pendingSignTransaction) {
192
+ const { transaction, resolve, reject } = that.pendingSignTransaction;
193
+ try {
194
+ const result = await that.signTransaction(transaction);
195
+ resolve(result);
196
+ }
197
+ catch (error) {
198
+ reject(error);
199
+ }
200
+ that.pendingSignTransaction = null;
201
+ }
202
+ // If there's a pending signMessage, execute it now
203
+ if (that.pendingSignMessage) {
204
+ const { message, resolve, reject } = that.pendingSignMessage;
205
+ try {
206
+ const result = await that.signMessage(message);
207
+ resolve(result);
208
+ }
209
+ catch (error) {
210
+ reject(error);
211
+ }
212
+ that.pendingSignMessage = null;
213
+ }
214
+ // If there's a pending signAndSubmitTransaction, execute it now
215
+ if (that.pendingSignAndSubmitTransaction) {
216
+ const { transaction, feePayer, resolve, reject } = that.pendingSignAndSubmitTransaction;
217
+ try {
218
+ const result = await that.signAndSubmitTransaction(transaction, feePayer);
219
+ resolve(result);
220
+ }
221
+ catch (error) {
222
+ reject(error);
223
+ }
224
+ that.pendingSignAndSubmitTransaction = null;
225
+ }
226
+ },
227
+ onError: (error) => {
228
+ // Only log errors that aren't user-initiated cancellations
229
+ if (error !== 'exited_auth_flow' && (error === null || error === void 0 ? void 0 : error.message) !== 'exited_auth_flow') {
230
+ console.error('Wallet connection error:', error);
231
+ }
232
+ if (that.pendingTransaction) {
233
+ that.pendingTransaction.reject(error);
234
+ that.pendingTransaction = null;
235
+ }
236
+ if (that.pendingSignTransaction) {
237
+ that.pendingSignTransaction.reject(error);
238
+ that.pendingSignTransaction = null;
239
+ }
240
+ if (that.pendingSignMessage) {
241
+ that.pendingSignMessage.reject(error);
242
+ that.pendingSignMessage = null;
243
+ }
244
+ if (that.pendingSignAndSubmitTransaction) {
245
+ that.pendingSignAndSubmitTransaction.reject(error);
246
+ that.pendingSignAndSubmitTransaction = null;
247
+ }
248
+ }
249
+ });
250
+ const { login } = privyImports.useLogin({
251
+ onComplete: async ({ user }) => {
252
+ var _a;
253
+ // This is a hack to indicate to the app that privy login is not complete
254
+ // @ts-ignore
255
+ window.runningPrivyOnComplete = true;
256
+ if (!user) {
257
+ index_native.getActiveSessionManager().clearSession();
258
+ return;
259
+ }
260
+ const solanaLinkedAccounts = user.linkedAccounts.filter((account) => account.chainType === 'solana');
261
+ const sortedLinkedAccounts = solanaLinkedAccounts.sort((a, b) => new Date(b.latestVerifiedAt).getTime() - new Date(a.latestVerifiedAt).getTime());
262
+ let finalAddress = (_a = sortedLinkedAccounts[0]) === null || _a === void 0 ? void 0 : _a.address;
263
+ if (!finalAddress) {
264
+ const solanaWallet = await createWallet();
265
+ finalAddress = solanaWallet.address;
266
+ index_native.getActiveSessionManager().clearSession();
267
+ return;
268
+ }
269
+ const session = await index_native.getActiveSessionManager().getSession();
270
+ if (!session || finalAddress !== session.address) {
271
+ try {
272
+ const accessToken = await privy.getAccessToken();
273
+ const idToken = useIdentityToken.identityToken;
274
+ await that.createSession(finalAddress, accessToken, idToken);
275
+ }
276
+ catch (error) {
277
+ console.error('Error creating session:', error);
278
+ }
279
+ }
280
+ // @ts-ignore
281
+ window.runningPrivyOnComplete = false;
282
+ index_native.setCurrentUser({ address: finalAddress, provider: that });
283
+ if (that.pendingLogin) {
284
+ that.pendingLogin.resolve({ address: finalAddress, provider: that });
285
+ that.pendingLogin = null;
286
+ }
287
+ },
288
+ onError: (error) => {
289
+ // Only log errors that aren't user-initiated cancellations
290
+ if (error !== 'exited_auth_flow' && (error === null || error === void 0 ? void 0 : error.message) !== 'exited_auth_flow') {
291
+ console.error('Login error:', error);
292
+ }
293
+ if (that.pendingLogin) {
294
+ that.pendingLogin.reject(error);
295
+ that.pendingLogin = null;
296
+ }
297
+ }
298
+ });
299
+ const { logout } = privyImports.useLogout({
300
+ onSuccess: () => {
301
+ index_native.getActiveSessionManager().clearSession();
302
+ index_native.setCurrentUser(null);
303
+ }
304
+ });
305
+ React__namespace.useEffect(() => {
306
+ if (privy.ready) {
307
+ that.privyMethods = {
308
+ ready: privy.ready,
309
+ walletReady: walletReady,
310
+ authenticated: privy.authenticated,
311
+ wallets,
312
+ login,
313
+ logout,
314
+ connectWallet,
315
+ getAccessToken: privy.getAccessToken,
316
+ identityToken: useIdentityToken.identityToken,
317
+ usePrivy: privy,
318
+ useOAuthTokens: useOAuthTokens,
319
+ useFundWalletSolana: useFundWalletSolana,
320
+ useSendTransactionSolana: useSendTransactionSolana,
321
+ useSolanaWallets: useSolanaWallets,
322
+ signTransaction: signTransaction,
323
+ signMessage: signMessageHook,
324
+ };
325
+ }
326
+ }, [privy.ready, privy.authenticated, wallets, login, logout, walletReady]);
327
+ return null;
328
+ };
329
+ const FinalPrivyComponent = () => {
330
+ if (typeof window === 'undefined') {
331
+ return null;
332
+ }
333
+ return React__namespace.createElement(privyImports.PrivyProvider, {
334
+ appId: this.privyConfig.appId,
335
+ config: this.privyConfig.config,
336
+ children: React__namespace.createElement(PrivyComponent)
337
+ });
338
+ };
339
+ this.root = ReactDOM__namespace.createRoot(this.containerElement);
340
+ this.root.render(React__namespace.createElement(FinalPrivyComponent));
341
+ }
342
+ }
343
+ async login() {
344
+ var _a, _b;
345
+ await this.ensureReady();
346
+ // Check if we have a valid session that matches an authenticated wallet
347
+ const session = await index_native.getActiveSessionManager().getSession();
348
+ if (((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.authenticated) && ((_b = this.privyMethods.wallets) === null || _b === void 0 ? void 0 : _b.length) > 0 && session) {
349
+ // Find the wallet matching the session
350
+ const matchingWallet = this.privyMethods.wallets.find((wallet) => wallet.address === session.address);
351
+ if (matchingWallet) {
352
+ // Valid session with matching wallet, return immediately
353
+ index_native.setCurrentUser({ address: matchingWallet.address, provider: this });
354
+ return {
355
+ address: matchingWallet.address,
356
+ provider: this
357
+ };
358
+ }
359
+ // Session exists but doesn't match any connected wallet
360
+ // This can happen after wallet switching - force fresh login
361
+ console.log('Session wallet mismatch detected, forcing fresh login flow');
362
+ }
363
+ // If no valid session or wallet mismatch, force a fresh login flow
364
+ // This ensures the user can select the correct wallet, especially after logout
365
+ if (this.pendingLogin) {
366
+ return new Promise((resolve, reject) => {
367
+ this.pendingLogin.resolve = resolve;
368
+ this.pendingLogin.reject = reject;
369
+ });
370
+ }
371
+ return new Promise((resolve, reject) => {
372
+ this.pendingLogin = { resolve, reject };
373
+ // open Privy modal to let user select/verify wallet
374
+ this.privyMethods.login();
375
+ // safety timeout
376
+ setTimeout(() => {
377
+ if (this.pendingLogin) {
378
+ this.pendingLogin.reject(new Error("Login timed out"));
379
+ this.pendingLogin = null;
380
+ }
381
+ }, 180000);
382
+ });
383
+ }
384
+ async getNativeMethods() {
385
+ var _a;
386
+ await this.ensureReady();
387
+ return (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.usePrivy;
388
+ }
389
+ async logout() {
390
+ await this.ensureReady();
391
+ await this.privyMethods.logout();
392
+ }
393
+ async runTransaction(_evmTransactionData, solTransactionData, options) {
394
+ var _a, _b, _c;
395
+ await this.ensureReady({ waitForWallets: true });
396
+ let session = await index_native.getActiveSessionManager().getSession();
397
+ let sessionAddress = session === null || session === void 0 ? void 0 : session.address;
398
+ let privyWallets = (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets;
399
+ let privyWallet = privyWallets === null || privyWallets === void 0 ? void 0 : privyWallets.find((wallet) => wallet.address === sessionAddress);
400
+ // If wallet not found yet, it may be an embedded wallet (email login) that hasn't
401
+ // appeared in the wallets array due to React state timing. Wait for it before
402
+ // falling back to connectWallet() which shows an unwanted wallet selection modal.
403
+ if (!privyWallets || privyWallets.length === 0 || !privyWallet) {
404
+ if (((_b = this.privyMethods) === null || _b === void 0 ? void 0 : _b.authenticated) && sessionAddress) {
405
+ privyWallet = await this.waitForMatchingWallet(sessionAddress);
406
+ }
407
+ }
408
+ if (!privyWallet) {
409
+ // If there's already a pending transaction, throw an error to prevent overlapping calls
410
+ if (this.pendingTransaction) {
411
+ throw new Error("Oops... something went wrong. Please try again.");
412
+ }
413
+ // Create a promise to wait for the transaction result
414
+ return new Promise((resolve, reject) => {
415
+ this.pendingTransaction = {
416
+ resolve,
417
+ reject,
418
+ evmTransactionData: _evmTransactionData,
419
+ solTransactionData,
420
+ options
421
+ };
422
+ this.privyMethods.connectWallet();
423
+ // Set a timeout to reject the promise if connection takes too long
424
+ setTimeout(() => {
425
+ if (this.pendingTransaction) {
426
+ this.pendingTransaction.reject(new Error("Wallet connection timed out"));
427
+ this.pendingTransaction = null;
428
+ }
429
+ }, 30000); // 30 seconds timeout
430
+ });
431
+ }
432
+ // Proceed with the transaction using privyWallet
433
+ const wallet = privyWallet;
434
+ if (solTransactionData == null) {
435
+ throw new Error("Solana transaction data is required");
436
+ }
437
+ const rpcUrl = this.getRpcUrl(solTransactionData.network);
438
+ const connection = new web3_js.Connection(rpcUrl, "confirmed");
439
+ const remainingAccounts = index_native.convertRemainingAccounts(solTransactionData.txArgs[0].remainingAccounts);
440
+ let app_id = solTransactionData.appId;
441
+ if (typeof window !== 'undefined' && window.CUSTOM_TAROBASE_APP_ID_HEADER) {
442
+ const customAppId = window.CUSTOM_TAROBASE_APP_ID_HEADER;
443
+ if (customAppId) {
444
+ app_id = customAppId;
445
+ }
446
+ }
447
+ if (!app_id) {
448
+ throw new Error("App ID is required");
449
+ }
450
+ const anchorProvider = new anchor__namespace.AnchorProvider(connection, wallet.provider, anchor__namespace.AnchorProvider.defaultOptions());
451
+ const finalDeduped = [];
452
+ for (const acc of remainingAccounts) {
453
+ const existing = finalDeduped.find((d) => d.pubkey.equals(acc.pubkey));
454
+ if (existing) {
455
+ existing.isSigner = existing.isSigner || acc.isSigner;
456
+ existing.isWritable = existing.isWritable || acc.isWritable;
457
+ }
458
+ else {
459
+ finalDeduped.push(acc);
460
+ }
461
+ }
462
+ let tx;
463
+ let blockhash;
464
+ let lastValidBlockHeight;
465
+ if (solTransactionData.signedTransaction) {
466
+ // Server already set the blockhash and co-signed — do NOT overwrite
467
+ // the blockhash or it will invalidate the server's signature.
468
+ tx = web3_js.VersionedTransaction.deserialize(index_native.bufferExports.Buffer.from(solTransactionData.signedTransaction, 'base64'));
469
+ // Extract the blockhash that was baked into the signed message
470
+ blockhash = tx.message.recentBlockhash;
471
+ const latestBlockhash = await connection.getLatestBlockhash('confirmed');
472
+ lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
473
+ }
474
+ else {
475
+ const result = await index_native.buildSetDocumentsTransaction(connection, solTransactionData.txArgs[0].idl, anchorProvider, new web3_js.PublicKey(wallet.address), { app_id, documents: solTransactionData.txArgs[0].setDocumentData, delete_paths: solTransactionData.txArgs[0].deletePaths, txData: solTransactionData.txArgs[0].txData }, finalDeduped, solTransactionData.lutKey, solTransactionData.preInstructions, false, solTransactionData.additionalLutAddresses);
476
+ tx = result.tx;
477
+ blockhash = result.blockhash;
478
+ lastValidBlockHeight = result.lastValidBlockHeight;
479
+ }
480
+ // Use duck typing instead of instanceof to handle multiple @solana/web3.js versions
481
+ const isLegacyTx = 'recentBlockhash' in tx && !('message' in tx && 'staticAccountKeys' in tx.message);
482
+ if (isLegacyTx) {
483
+ tx.recentBlockhash = blockhash;
484
+ tx.lastValidBlockHeight = lastValidBlockHeight;
485
+ }
486
+ else {
487
+ tx.message.recentBlockhash = blockhash;
488
+ }
489
+ try {
490
+ if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
491
+ // Just sign, don't submit - return raw signed bytes (same as original runTransaction)
492
+ const signedTx = await this.signTransactionRaw(tx, privyWallet);
493
+ return {
494
+ signedTransaction: signedTx, // Raw Uint8Array from Privy
495
+ blockNumber: 0,
496
+ gasUsed: "0",
497
+ data: ""
498
+ };
499
+ }
500
+ // Sign and submit using shared helper
501
+ const { signature, txInfo } = await this.signAndSubmitInternal(tx, privyWallet, rpcUrl, connection);
502
+ return {
503
+ transactionSignature: signature,
504
+ blockNumber: (txInfo === null || txInfo === void 0 ? void 0 : txInfo.slot) || 0,
505
+ gasUsed: ((_c = txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta) === null || _c === void 0 ? void 0 : _c.fee.toString()) || '0',
506
+ data: txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta,
507
+ };
508
+ }
509
+ catch (err) {
510
+ console.error(err);
511
+ throw err;
512
+ }
513
+ }
514
+ /**
515
+ * Signs a Solana transaction without submitting it.
516
+ *
517
+ * This method handles blockhash automatically if not set - you do NOT need to
518
+ * set recentBlockhash on the transaction before calling this method.
519
+ * The network/RPC URL is derived from the provider's configuration (set during initialization).
520
+ *
521
+ * @param transaction - The transaction to sign (Transaction or VersionedTransaction)
522
+ * @returns The signed transaction
523
+ */
524
+ async signTransaction(transaction) {
525
+ var _a, _b;
526
+ await this.ensureReady({ waitForWallets: true });
527
+ let privyWallets = (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets;
528
+ let session = await index_native.getActiveSessionManager().getSession();
529
+ let sessionAddress = session === null || session === void 0 ? void 0 : session.address;
530
+ let privyWallet = privyWallets === null || privyWallets === void 0 ? void 0 : privyWallets.find((wallet) => wallet.address === sessionAddress);
531
+ // If there's already a pending sign transaction, throw an error to prevent overlapping calls
532
+ if (this.pendingSignTransaction) {
533
+ throw new Error("Oops... something went wrong. Please try again.");
534
+ }
535
+ // If wallet not found yet, it may be an embedded wallet (email login) that hasn't
536
+ // appeared in the wallets array due to React state timing. Wait for it before
537
+ // falling back to connectWallet() which shows an unwanted wallet selection modal.
538
+ if (!privyWallets || privyWallets.length === 0 || !privyWallet) {
539
+ if (((_b = this.privyMethods) === null || _b === void 0 ? void 0 : _b.authenticated) && sessionAddress) {
540
+ privyWallet = await this.waitForMatchingWallet(sessionAddress);
541
+ }
542
+ }
543
+ // If still no wallet after waiting, trigger connection and queue the signing
544
+ if (!privyWallet) {
545
+ return new Promise((resolve, reject) => {
546
+ this.pendingSignTransaction = {
547
+ resolve,
548
+ reject,
549
+ transaction
550
+ };
551
+ this.privyMethods.connectWallet();
552
+ // Set a timeout to reject the promise if connection takes too long
553
+ setTimeout(() => {
554
+ if (this.pendingSignTransaction) {
555
+ this.pendingSignTransaction.reject(new Error("Wallet connection timed out"));
556
+ this.pendingSignTransaction = null;
557
+ }
558
+ }, 30000); // 30 seconds timeout
559
+ });
560
+ }
561
+ // Privy requires serialized transaction bytes, which requires a blockhash.
562
+ // If the transaction doesn't have one, get a fresh blockhash and set it.
563
+ // Use duck typing instead of instanceof to handle multiple @solana/web3.js versions
564
+ const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
565
+ if (isLegacyTransaction) {
566
+ const legacyTx = transaction;
567
+ if (!legacyTx.recentBlockhash) {
568
+ const rpcUrl = this.getRpcUrl();
569
+ const connection = new web3_js.Connection(rpcUrl, 'confirmed');
570
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
571
+ legacyTx.recentBlockhash = blockhash;
572
+ legacyTx.lastValidBlockHeight = lastValidBlockHeight;
573
+ }
574
+ // Set feePayer if not already set
575
+ if (!legacyTx.feePayer) {
576
+ legacyTx.feePayer = new web3_js.PublicKey(privyWallet.address);
577
+ }
578
+ }
579
+ else {
580
+ // VersionedTransaction
581
+ const versionedTx = transaction;
582
+ if (!versionedTx.message.recentBlockhash) {
583
+ const rpcUrl = this.getRpcUrl();
584
+ const connection = new web3_js.Connection(rpcUrl, 'confirmed');
585
+ const { blockhash } = await connection.getLatestBlockhash('confirmed');
586
+ versionedTx.message.recentBlockhash = blockhash;
587
+ }
588
+ }
589
+ // Sign using raw method, then deserialize for the public API
590
+ const signedTxRaw = await this.signTransactionRaw(transaction, privyWallet);
591
+ return this.deserializeSignedTransaction(signedTxRaw);
592
+ }
593
+ /**
594
+ * Signs and submits a Solana transaction to the network.
595
+ *
596
+ * This method handles blockhash and transaction confirmation automatically - you do NOT need to
597
+ * set recentBlockhash or lastValidBlockHeight on the transaction before calling this method.
598
+ * The network/RPC URL is derived from the provider's configuration (set during initialization).
599
+ *
600
+ * @param transaction - The transaction to sign and submit (Transaction or VersionedTransaction)
601
+ * @param feePayer - Optional fee payer public key. If not provided and the transaction doesn't
602
+ * already have a feePayer set, the connected wallet address will be used.
603
+ * Useful for co-signing scenarios where a different account pays the fees.
604
+ * @returns The transaction signature
605
+ */
606
+ async signAndSubmitTransaction(transaction, feePayer) {
607
+ var _a, _b;
608
+ await this.ensureReady({ waitForWallets: true });
609
+ let privyWallets = (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets;
610
+ let session = await index_native.getActiveSessionManager().getSession();
611
+ let sessionAddress = session === null || session === void 0 ? void 0 : session.address;
612
+ let privyWallet = privyWallets === null || privyWallets === void 0 ? void 0 : privyWallets.find((wallet) => wallet.address === sessionAddress);
613
+ // If there's already a pending signAndSubmitTransaction, throw an error to prevent overlapping calls
614
+ if (this.pendingSignAndSubmitTransaction) {
615
+ throw new Error("Oops... something went wrong. Please try again.");
616
+ }
617
+ // If wallet not found yet, it may be an embedded wallet (email login) that hasn't
618
+ // appeared in the wallets array due to React state timing. Wait for it before
619
+ // falling back to connectWallet() which shows an unwanted wallet selection modal.
620
+ if (!privyWallets || privyWallets.length === 0 || !privyWallet) {
621
+ if (((_b = this.privyMethods) === null || _b === void 0 ? void 0 : _b.authenticated) && sessionAddress) {
622
+ privyWallet = await this.waitForMatchingWallet(sessionAddress);
623
+ }
624
+ }
625
+ // If still no wallet after waiting, trigger connection and queue the signing
626
+ if (!privyWallet) {
627
+ return new Promise((resolve, reject) => {
628
+ this.pendingSignAndSubmitTransaction = {
629
+ resolve,
630
+ reject,
631
+ transaction,
632
+ feePayer
633
+ };
634
+ this.privyMethods.connectWallet();
635
+ // Set a timeout to reject the promise if connection takes too long
636
+ setTimeout(() => {
637
+ if (this.pendingSignAndSubmitTransaction) {
638
+ this.pendingSignAndSubmitTransaction.reject(new Error("Wallet connection timed out"));
639
+ this.pendingSignAndSubmitTransaction = null;
640
+ }
641
+ }, 30000); // 30 seconds timeout
642
+ });
643
+ }
644
+ // Get RPC URL and create connection
645
+ const rpcUrl = this.getRpcUrl();
646
+ const connection = new web3_js.Connection(rpcUrl, 'confirmed');
647
+ // Get fresh blockhash and set it on the transaction before signing
648
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
649
+ // Use duck typing instead of instanceof to handle multiple @solana/web3.js versions
650
+ const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
651
+ if (isLegacyTransaction) {
652
+ const legacyTx = transaction;
653
+ legacyTx.recentBlockhash = blockhash;
654
+ legacyTx.lastValidBlockHeight = lastValidBlockHeight;
655
+ // Set feePayer if not already set
656
+ if (!legacyTx.feePayer) {
657
+ legacyTx.feePayer = feePayer !== null && feePayer !== void 0 ? feePayer : new web3_js.PublicKey(privyWallet.address);
658
+ }
659
+ }
660
+ else {
661
+ // VersionedTransaction
662
+ const versionedTx = transaction;
663
+ versionedTx.message.recentBlockhash = blockhash;
664
+ // Note: VersionedTransaction feePayer is set in the message at creation time
665
+ // and cannot be modified after creation
666
+ }
667
+ // Use shared sign and submit logic
668
+ const { signature } = await this.signAndSubmitInternal(transaction, privyWallet, rpcUrl, connection);
669
+ return signature;
670
+ }
671
+ // ============ Private Helpers ============
672
+ getRpcUrl(network) {
673
+ if (this.networkUrl) {
674
+ return this.networkUrl;
675
+ }
676
+ if (network === 'solana_devnet') {
677
+ return index_native.SOLANA_DEVNET_RPC_URL;
678
+ }
679
+ else if (network === 'solana_mainnet') {
680
+ return index_native.SOLANA_MAINNET_RPC_URL;
681
+ }
682
+ else if (network === 'surfnet') {
683
+ return SURFNET_RPC_URL;
684
+ }
685
+ return index_native.SOLANA_MAINNET_RPC_URL; // default to mainnet
686
+ }
687
+ /**
688
+ * Internal sign transaction - serializes and signs via Privy
689
+ * Returns the raw result from Privy (Uint8Array)
690
+ * This mirrors exactly what runTransaction was doing
691
+ */
692
+ async signTransactionRaw(transaction, privyWallet) {
693
+ var _a;
694
+ // Serialize the transaction
695
+ // Use duck typing instead of instanceof to handle multiple @solana/web3.js versions
696
+ const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
697
+ let serializedForSign;
698
+ if (isLegacyTransaction) {
699
+ serializedForSign = transaction.serialize({ requireAllSignatures: false, verifySignatures: false });
700
+ }
701
+ else {
702
+ serializedForSign = transaction.serialize();
703
+ }
704
+ // Sign via Privy - returns { signedTransaction: Uint8Array }
705
+ const result = await ((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.signTransaction({
706
+ transaction: serializedForSign,
707
+ wallet: privyWallet,
708
+ chain: this.chainId
709
+ }));
710
+ // Privy returns { signedTransaction: Uint8Array }, unwrap it
711
+ const signedTx = (result === null || result === void 0 ? void 0 : result.signedTransaction) || result;
712
+ return signedTx;
713
+ }
714
+ /**
715
+ * Deserialize a signed transaction from Uint8Array to Transaction object
716
+ */
717
+ deserializeSignedTransaction(signedTxRaw) {
718
+ // Handle different formats Privy might return
719
+ let signedTx;
720
+ if (signedTxRaw instanceof Uint8Array) {
721
+ signedTx = signedTxRaw;
722
+ }
723
+ else if (Array.isArray(signedTxRaw)) {
724
+ signedTx = new Uint8Array(signedTxRaw);
725
+ }
726
+ else if (signedTxRaw && typeof signedTxRaw === 'object' && 'signedTransaction' in signedTxRaw) {
727
+ // Privy might wrap the result
728
+ signedTx = signedTxRaw.signedTransaction instanceof Uint8Array
729
+ ? signedTxRaw.signedTransaction
730
+ : new Uint8Array(signedTxRaw.signedTransaction);
731
+ }
732
+ else if (index_native.bufferExports.Buffer.isBuffer(signedTxRaw)) {
733
+ signedTx = new Uint8Array(signedTxRaw);
734
+ }
735
+ else {
736
+ throw new Error(`Unexpected signed transaction format: ${typeof signedTxRaw}`);
737
+ }
738
+ // Try to deserialize as VersionedTransaction first, fall back to legacy Transaction
739
+ try {
740
+ return web3_js.VersionedTransaction.deserialize(signedTx);
741
+ }
742
+ catch (_a) {
743
+ return web3_js.Transaction.from(signedTx);
744
+ }
745
+ }
746
+ /**
747
+ * Internal sign and submit - handles Surfnet vs non-Surfnet logic
748
+ * This is the core submission logic used by both signAndSubmitTransaction and runTransaction
749
+ *
750
+ * For Surfnet: sign with signTransactionRaw, then sendRawTransaction
751
+ * For non-Surfnet: use Privy's signAndSendTransaction (combined operation)
752
+ */
753
+ async signAndSubmitInternal(transaction, privyWallet, rpcUrl, connection) {
754
+ var _a;
755
+ const isSurfnet = rpcUrl === SURFNET_RPC_URL;
756
+ let signature;
757
+ if (isSurfnet) {
758
+ // For Surfnet: sign with signTransactionRaw, then sendRawTransaction
759
+ const signedTx = await this.signTransactionRaw(transaction, privyWallet);
760
+ signature = await connection.sendRawTransaction(signedTx);
761
+ }
762
+ else {
763
+ // For non-Surfnet: use Privy's combined signAndSendTransaction
764
+ // Serialize the transaction for Privy API
765
+ // Use duck typing instead of instanceof to handle multiple @solana/web3.js versions
766
+ const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
767
+ let serializedTx;
768
+ if (isLegacyTransaction) {
769
+ serializedTx = transaction.serialize({ requireAllSignatures: false, verifySignatures: false });
770
+ }
771
+ else {
772
+ serializedTx = transaction.serialize();
773
+ }
774
+ const result = await ((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.useSendTransactionSolana.signAndSendTransaction({
775
+ transaction: serializedTx,
776
+ wallet: privyWallet,
777
+ chain: this.chainId
778
+ }));
779
+ // Handle case where signature might be bytes instead of string
780
+ const rawSig = result.signature;
781
+ if (rawSig instanceof Uint8Array || Array.isArray(rawSig)) {
782
+ signature = index_native.base58.encode(rawSig instanceof Uint8Array ? rawSig : new Uint8Array(rawSig));
783
+ }
784
+ else {
785
+ signature = rawSig;
786
+ }
787
+ }
788
+ const txInfo = await index_native.confirmAndCheckTransaction(connection, signature);
789
+ return { signature, txInfo };
790
+ }
791
+ async signMessage(message) {
792
+ var _a, _b, _c;
793
+ await this.ensureReady({ waitForWallets: true });
794
+ const session = await index_native.getActiveSessionManager().getSession();
795
+ let sessionAddress = session === null || session === void 0 ? void 0 : session.address;
796
+ // If there's already a pending sign message, throw an error to prevent overlapping calls
797
+ if (this.pendingSignMessage) {
798
+ throw new Error("Oops... something went wrong. Please try again.");
799
+ }
800
+ // If no wallets connected yet, it may be an embedded wallet (email login) that hasn't
801
+ // appeared in the wallets array due to React state timing. Wait for it before
802
+ // falling back to connectWallet() which shows an unwanted wallet selection modal.
803
+ if (!((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets) || this.privyMethods.wallets.length === 0) {
804
+ if (((_b = this.privyMethods) === null || _b === void 0 ? void 0 : _b.authenticated) && sessionAddress) {
805
+ const matchedWallet = await this.waitForMatchingWallet(sessionAddress);
806
+ if (!matchedWallet) {
807
+ return new Promise((resolve, reject) => {
808
+ this.pendingSignMessage = {
809
+ resolve,
810
+ reject,
811
+ message
812
+ };
813
+ this.privyMethods.connectWallet();
814
+ // Set a timeout to reject the promise if connection takes too long
815
+ setTimeout(() => {
816
+ if (this.pendingSignMessage) {
817
+ this.pendingSignMessage.reject(new Error("Wallet connection timed out"));
818
+ this.pendingSignMessage = null;
819
+ }
820
+ }, 30000); // 30 seconds timeout
821
+ });
822
+ }
823
+ }
824
+ else {
825
+ return new Promise((resolve, reject) => {
826
+ this.pendingSignMessage = {
827
+ resolve,
828
+ reject,
829
+ message
830
+ };
831
+ this.privyMethods.connectWallet();
832
+ // Set a timeout to reject the promise if connection takes too long
833
+ setTimeout(() => {
834
+ if (this.pendingSignMessage) {
835
+ this.pendingSignMessage.reject(new Error("Wallet connection timed out"));
836
+ this.pendingSignMessage = null;
837
+ }
838
+ }, 30000); // 30 seconds timeout
839
+ });
840
+ }
841
+ }
842
+ let privyWallet = this.privyMethods.wallets.find((wallet) => wallet.address === sessionAddress);
843
+ if (!privyWallet) {
844
+ // Session address is not a privy wallet, just default to the first wallet
845
+ const accessToken = await this.privyMethods.getAccessToken();
846
+ await this.createSession(this.privyMethods.wallets[0].address, accessToken, this.privyMethods.identityToken);
847
+ index_native.setCurrentUser({ address: this.privyMethods.wallets[0].address, provider: this });
848
+ const session = await index_native.getActiveSessionManager().getSession();
849
+ sessionAddress = session === null || session === void 0 ? void 0 : session.address;
850
+ if (!sessionAddress) {
851
+ throw new Error('No wallet connected or logged in to sign message');
852
+ }
853
+ privyWallet = this.privyMethods.wallets[0];
854
+ }
855
+ // Use the Privy signMessage hook for Solana wallets
856
+ // The message needs to be passed as a Uint8Array
857
+ const messageBytes = index_native.getPlatform().textEncode(message);
858
+ const result = await ((_c = this.privyMethods) === null || _c === void 0 ? void 0 : _c.signMessage({
859
+ message: messageBytes,
860
+ wallet: privyWallet,
861
+ }));
862
+ // The signature is returned as a Uint8Array, encode it as base58 (standard Solana format)
863
+ const signatureBytes = (result === null || result === void 0 ? void 0 : result.signature) || result;
864
+ const bs58 = await Promise.resolve().then(function () { return require('./index.native-B5IBOdv_.js'); }).then(function (n) { return n.index; });
865
+ return bs58.default.encode(signatureBytes);
866
+ }
867
+ async restoreSession() {
868
+ const session = await index_native.getActiveSessionManager().getSession();
869
+ if (session) {
870
+ return { provider: this, address: session.address };
871
+ }
872
+ else {
873
+ return null;
874
+ }
875
+ }
876
+ // NOTE: accessToken/idToken are accepted for backwards-compat with existing
877
+ // call sites but are no longer used. The session is minted by having the Privy
878
+ // Solana wallet SIGN the canonical SIWS challenge (the same wallet-signature
879
+ // path Phantom/MWA/guest use), so the bounded /session issuer needs no
880
+ // Privy-specific token verification — it arrives as a Solana signature and is
881
+ // recorded server-side as authMethod 'phantom'.
882
+ async createSession(address, _accessToken, _idToken) {
883
+ var _a, _b, _c, _d, _e, _f, _g;
884
+ // Resolve the Privy wallet for this address (fall back to the first wallet).
885
+ const privyWallet = (_c = (_b = (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets) === null || _b === void 0 ? void 0 : _b.find((w) => w.address === address)) !== null && _c !== void 0 ? _c : (_e = (_d = this.privyMethods) === null || _d === void 0 ? void 0 : _d.wallets) === null || _e === void 0 ? void 0 : _e[0];
886
+ if (!privyWallet) {
887
+ throw new Error('No Privy Solana wallet available to mint a session.');
888
+ }
889
+ const nonce = await index_native.genAuthNonce();
890
+ const message = await index_native.genSolanaMessage(address, nonce);
891
+ const messageBytes = index_native.getPlatform().textEncode(message);
892
+ // Low-level Privy sign hook — signs WITHOUT touching the session (the public
893
+ // signMessage() bootstraps sessions, which would recurse here).
894
+ const signResult = await ((_f = this.privyMethods) === null || _f === void 0 ? void 0 : _f.signMessage({
895
+ message: messageBytes,
896
+ wallet: privyWallet,
897
+ }));
898
+ const signatureBytes = (_g = signResult === null || signResult === void 0 ? void 0 : signResult.signature) !== null && _g !== void 0 ? _g : signResult;
899
+ // base64-encoded detached signature (matches Phantom + guest providers).
900
+ const signature = index_native.bufferExports.Buffer.from(signatureBytes).toString('base64');
901
+ const createSessionResult = await index_native.createSessionWithSignature(address, message, signature);
902
+ if (createSessionResult) {
903
+ await index_native.getActiveSessionManager().storeSession(address, createSessionResult.accessToken, createSessionResult.idToken, createSessionResult.refreshToken);
904
+ }
905
+ }
906
+ /**
907
+ * Waits for a wallet matching the session address to appear in the wallets array.
908
+ * This handles the timing gap where Privy's embedded wallet (created for email login users)
909
+ * may not yet be in the useWallets() array when signTransaction is called immediately after login.
910
+ */
911
+ async waitForMatchingWallet(sessionAddress, timeoutMs = 10000) {
912
+ var _a;
913
+ const startTime = Date.now();
914
+ while (Date.now() - startTime < timeoutMs) {
915
+ const wallets = (_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.wallets;
916
+ if (wallets && wallets.length > 0) {
917
+ const wallet = wallets.find((w) => w.address === sessionAddress);
918
+ if (wallet)
919
+ return wallet;
920
+ }
921
+ await new Promise(resolve => setTimeout(resolve, 200));
922
+ }
923
+ return null;
924
+ }
925
+ async ensureReady({ waitForWallets = false, timeoutMs = 15000 } = {}) {
926
+ const isReady = () => {
927
+ var _a, _b;
928
+ if (!((_a = this.privyMethods) === null || _a === void 0 ? void 0 : _a.ready))
929
+ return false;
930
+ if (waitForWallets && !((_b = this.privyMethods) === null || _b === void 0 ? void 0 : _b.walletReady))
931
+ return false;
932
+ return true;
933
+ };
934
+ if (isReady())
935
+ return;
936
+ return new Promise((resolve, reject) => {
937
+ const startTime = Date.now();
938
+ const check = () => {
939
+ if (isReady()) {
940
+ resolve();
941
+ }
942
+ else if (Date.now() - startTime > timeoutMs) {
943
+ reject(new Error('Login provider failed to initialize. This can happen in incognito mode or when third-party cookies are blocked. Try using a regular browser window.'));
944
+ }
945
+ else {
946
+ setTimeout(check, 100);
947
+ }
948
+ };
949
+ check();
950
+ });
951
+ }
952
+ }
953
+ PrivyWalletProvider.instance = null;
954
+
955
+ exports.PrivyWalletProvider = PrivyWalletProvider;
956
+ //# sourceMappingURL=privy-wallet-provider-DiHHTDbZ.js.map