@pooflabs/web 0.0.85-rc3 → 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.
- package/dist/auth/providers/solana-mobile-wallet-provider.d.ts +43 -0
- package/dist/{index-B5qYY4YM.js → index-B-x9RTF7.js} +2 -2
- package/dist/index-B-x9RTF7.js.map +1 -0
- package/dist/{index-BaKs3A8s.js → index-BKN0IwAx.js} +3054 -300
- package/dist/index-BKN0IwAx.js.map +1 -0
- package/dist/{index-C4AnWFs_.esm.js → index-BTwX7FYW.esm.js} +425 -119
- package/dist/index-BTwX7FYW.esm.js.map +1 -0
- package/dist/{index-BzeiIIwF.js → index-DYBdUxnT.js} +3055 -301
- package/dist/index-DYBdUxnT.js.map +1 -0
- package/dist/{index-bEXLwE7_.js → index-Dj1tZr6X.js} +426 -118
- package/dist/index-Dj1tZr6X.js.map +1 -0
- package/dist/{index-dqqR5q7b.esm.js → index-DofM-ue2.esm.js} +3054 -301
- package/dist/index-DofM-ue2.esm.js.map +1 -0
- package/dist/index-_k6pjuwx.esm.js +6 -0
- package/dist/index-_k6pjuwx.esm.js.map +1 -0
- package/dist/{index-BE-VWSJT.esm.js → index-x7a-wH2l.esm.js} +3055 -300
- package/dist/index-x7a-wH2l.esm.js.map +1 -0
- package/dist/{index.browser-D8ttddP4.esm.js → index.browser-Cndx2raY.esm.js} +506 -1876
- package/dist/index.browser-Cndx2raY.esm.js.map +1 -0
- package/dist/{index.browser-CN6obNQM.js → index.browser-D7-FFk3q.js} +506 -1876
- package/dist/index.browser-D7-FFk3q.js.map +1 -0
- package/dist/{index.browser-CZIJCtms.js → index.browser-DlA-NKvf.js} +1223 -2565
- package/dist/index.browser-DlA-NKvf.js.map +1 -0
- package/dist/{index.browser-DQIwLToJ.esm.js → index.browser-nVGFrIHK.esm.js} +1223 -2565
- package/dist/index.browser-nVGFrIHK.esm.js.map +1 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{index.native-DLziTime.esm.js → index.native-19VsREMJ.esm.js} +43 -62
- package/dist/index.native-19VsREMJ.esm.js.map +1 -0
- package/dist/{index.native-pG1NTZ0f.js → index.native-D8vj3Lbr.js} +44 -61
- package/dist/index.native-D8vj3Lbr.js.map +1 -0
- package/dist/index.native.esm.js +1 -1
- package/dist/index.native.js +1 -1
- package/dist/{phantom-wallet-provider-zBp7-uEw.js → phantom-wallet-provider-BlZZa_3s.js} +4 -4
- package/dist/{phantom-wallet-provider-zBp7-uEw.js.map → phantom-wallet-provider-BlZZa_3s.js.map} +1 -1
- package/dist/{phantom-wallet-provider-CP6NXRwG.esm.js → phantom-wallet-provider-Bz3qEFzX.esm.js} +4 -4
- package/dist/{phantom-wallet-provider-CP6NXRwG.esm.js.map → phantom-wallet-provider-Bz3qEFzX.esm.js.map} +1 -1
- package/dist/{privy-wallet-provider-CoyW5Gdg.js → privy-wallet-provider-CqCgq7uT.js} +3 -3
- package/dist/privy-wallet-provider-CqCgq7uT.js.map +1 -0
- package/dist/{privy-wallet-provider-CGYvf3-r.esm.js → privy-wallet-provider-DgNFzioA.esm.js} +3 -3
- package/dist/privy-wallet-provider-DgNFzioA.esm.js.map +1 -0
- package/dist/{solana-mobile-wallet-provider-B8rHfsPN.esm.js → solana-mobile-wallet-provider-EeQsBTdr.esm.js} +385 -60
- package/dist/solana-mobile-wallet-provider-EeQsBTdr.esm.js.map +1 -0
- package/dist/{solana-mobile-wallet-provider-CN-D_H4l.js → solana-mobile-wallet-provider-VqIGfdMV.js} +385 -60
- package/dist/solana-mobile-wallet-provider-VqIGfdMV.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-B5qYY4YM.js.map +0 -1
- package/dist/index-BE-VWSJT.esm.js.map +0 -1
- package/dist/index-BaKs3A8s.js.map +0 -1
- package/dist/index-BzeiIIwF.js.map +0 -1
- package/dist/index-C4AnWFs_.esm.js.map +0 -1
- package/dist/index-TzHXEf3-.esm.js +0 -6
- package/dist/index-TzHXEf3-.esm.js.map +0 -1
- package/dist/index-bEXLwE7_.js.map +0 -1
- package/dist/index-dqqR5q7b.esm.js.map +0 -1
- package/dist/index.browser-CN6obNQM.js.map +0 -1
- package/dist/index.browser-CZIJCtms.js.map +0 -1
- package/dist/index.browser-D8ttddP4.esm.js.map +0 -1
- package/dist/index.browser-DQIwLToJ.esm.js.map +0 -1
- package/dist/index.native-DLziTime.esm.js.map +0 -1
- package/dist/index.native-pG1NTZ0f.js.map +0 -1
- package/dist/privy-wallet-provider-CGYvf3-r.esm.js.map +0 -1
- package/dist/privy-wallet-provider-CoyW5Gdg.js.map +0 -1
- package/dist/solana-mobile-wallet-provider-B8rHfsPN.esm.js.map +0 -1
- package/dist/solana-mobile-wallet-provider-CN-D_H4l.js.map +0 -1
|
@@ -4,6 +4,21 @@ import * as anchor from '@coral-xyz/anchor';
|
|
|
4
4
|
import { Program } from '@coral-xyz/anchor';
|
|
5
5
|
import * as React$2 from 'react';
|
|
6
6
|
|
|
7
|
+
function _mergeNamespaces(n, m) {
|
|
8
|
+
m.forEach(function (e) {
|
|
9
|
+
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default' && !(k in n)) {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
return Object.freeze(n);
|
|
20
|
+
}
|
|
21
|
+
|
|
7
22
|
function getDefaultExportFromCjs$1 (x) {
|
|
8
23
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
9
24
|
}
|
|
@@ -6749,28 +6764,6 @@ class WebSessionManager {
|
|
|
6749
6764
|
static async storeSession(address, accessToken, idToken, refreshToken) {
|
|
6750
6765
|
if (typeof window === "undefined")
|
|
6751
6766
|
return;
|
|
6752
|
-
// JWT-wallet binding: refuse to store a session whose idToken is bound
|
|
6753
|
-
// to a different wallet than `address`. Prevents races that would otherwise
|
|
6754
|
-
// leave localStorage with mismatched address/token state.
|
|
6755
|
-
try {
|
|
6756
|
-
const payloadB64 = idToken.split(".")[1];
|
|
6757
|
-
if (payloadB64) {
|
|
6758
|
-
const payload = JSON.parse(this.decodeBase64Url(payloadB64));
|
|
6759
|
-
const tokenWallet = payload["custom:walletAddress"];
|
|
6760
|
-
if (tokenWallet && tokenWallet !== address) {
|
|
6761
|
-
throw new Error(`[WebSessionManager] Refusing to store session: address (${address}) does not match idToken custom:walletAddress (${tokenWallet})`);
|
|
6762
|
-
}
|
|
6763
|
-
if (!tokenWallet) {
|
|
6764
|
-
console.warn("[WebSessionManager] storeSession: idToken has no custom:walletAddress claim — writing without validation");
|
|
6765
|
-
}
|
|
6766
|
-
}
|
|
6767
|
-
}
|
|
6768
|
-
catch (err) {
|
|
6769
|
-
if (typeof (err === null || err === void 0 ? void 0 : err.message) === "string" && err.message.includes("Refusing to store session")) {
|
|
6770
|
-
throw err;
|
|
6771
|
-
}
|
|
6772
|
-
console.warn("[WebSessionManager] storeSession: failed to decode idToken for validation:", err);
|
|
6773
|
-
}
|
|
6774
6767
|
const config = await getConfig();
|
|
6775
6768
|
const currentAppId = config.appId;
|
|
6776
6769
|
localStorage.setItem(this.TAROBASE_SESSION_STORAGE_KEY, JSON.stringify({
|
|
@@ -9469,11 +9462,11 @@ function requireSrc$1 () {
|
|
|
9469
9462
|
}
|
|
9470
9463
|
|
|
9471
9464
|
var bs58$1;
|
|
9472
|
-
var hasRequiredBs58;
|
|
9465
|
+
var hasRequiredBs58$1;
|
|
9473
9466
|
|
|
9474
|
-
function requireBs58 () {
|
|
9475
|
-
if (hasRequiredBs58) return bs58$1;
|
|
9476
|
-
hasRequiredBs58 = 1;
|
|
9467
|
+
function requireBs58$1 () {
|
|
9468
|
+
if (hasRequiredBs58$1) return bs58$1;
|
|
9469
|
+
hasRequiredBs58$1 = 1;
|
|
9477
9470
|
var basex = requireSrc$1();
|
|
9478
9471
|
var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
9479
9472
|
|
|
@@ -9481,8 +9474,8 @@ function requireBs58 () {
|
|
|
9481
9474
|
return bs58$1;
|
|
9482
9475
|
}
|
|
9483
9476
|
|
|
9484
|
-
var bs58Exports = requireBs58();
|
|
9485
|
-
var bs58 = /*@__PURE__*/getDefaultExportFromCjs(bs58Exports);
|
|
9477
|
+
var bs58Exports$1 = requireBs58$1();
|
|
9478
|
+
var bs58$2 = /*@__PURE__*/getDefaultExportFromCjs(bs58Exports$1);
|
|
9486
9479
|
|
|
9487
9480
|
// ─────────────────────────────────────────────────────────────
|
|
9488
9481
|
// Local implementation of getSimulationComputeUnits
|
|
@@ -9744,7 +9737,7 @@ function loadKeypairFromEnv() {
|
|
|
9744
9737
|
try {
|
|
9745
9738
|
const secretKey = secret.trim().startsWith("[")
|
|
9746
9739
|
? Uint8Array.from(JSON.parse(secret))
|
|
9747
|
-
: bs58.decode(secret.trim());
|
|
9740
|
+
: bs58$2.decode(secret.trim());
|
|
9748
9741
|
return Keypair.fromSecretKey(secretKey);
|
|
9749
9742
|
}
|
|
9750
9743
|
catch (err) {
|
|
@@ -11689,28 +11682,6 @@ class ReactNativeSessionManager {
|
|
|
11689
11682
|
/* STORE */
|
|
11690
11683
|
/* ------------------------------------------------------------------ */
|
|
11691
11684
|
static async storeSession(address, accessToken, idToken, refreshToken) {
|
|
11692
|
-
// JWT-wallet binding: refuse to store a session whose idToken is bound
|
|
11693
|
-
// to a different wallet than `address`. Prevents races that would otherwise
|
|
11694
|
-
// leave storage with mismatched address/token state.
|
|
11695
|
-
try {
|
|
11696
|
-
const payloadB64 = idToken.split(".")[1];
|
|
11697
|
-
if (payloadB64) {
|
|
11698
|
-
const payload = JSON.parse(this.decodeBase64Url(payloadB64));
|
|
11699
|
-
const tokenWallet = payload["custom:walletAddress"];
|
|
11700
|
-
if (tokenWallet && tokenWallet !== address) {
|
|
11701
|
-
throw new Error(`[ReactNativeSessionManager] Refusing to store session: address (${address}) does not match idToken custom:walletAddress (${tokenWallet})`);
|
|
11702
|
-
}
|
|
11703
|
-
if (!tokenWallet) {
|
|
11704
|
-
console.warn("[ReactNativeSessionManager] storeSession: idToken has no custom:walletAddress claim — writing without validation");
|
|
11705
|
-
}
|
|
11706
|
-
}
|
|
11707
|
-
}
|
|
11708
|
-
catch (err) {
|
|
11709
|
-
if (typeof (err === null || err === void 0 ? void 0 : err.message) === "string" && err.message.includes("Refusing to store session")) {
|
|
11710
|
-
throw err;
|
|
11711
|
-
}
|
|
11712
|
-
console.warn("[ReactNativeSessionManager] storeSession: failed to decode idToken for validation:", err);
|
|
11713
|
-
}
|
|
11714
11685
|
const config = await getConfig();
|
|
11715
11686
|
const currentAppId = config.appId;
|
|
11716
11687
|
this.getStorage().setItem(this.TAROBASE_SESSION_STORAGE_KEY, JSON.stringify({
|
|
@@ -15709,7 +15680,7 @@ async function loadDependencies() {
|
|
|
15709
15680
|
const [reactModule, reactDomModule, phantomModule] = await Promise.all([
|
|
15710
15681
|
import('react'),
|
|
15711
15682
|
import('react-dom/client'),
|
|
15712
|
-
import('./index-
|
|
15683
|
+
import('./index-DofM-ue2.esm.js')
|
|
15713
15684
|
]);
|
|
15714
15685
|
// Extract default export from ESM module namespace
|
|
15715
15686
|
// Dynamic import() returns { default: Module, ...exports }, not the module directly
|
|
@@ -20367,16 +20338,26 @@ function requireSrc () {
|
|
|
20367
20338
|
return src;
|
|
20368
20339
|
}
|
|
20369
20340
|
|
|
20370
|
-
var
|
|
20371
|
-
var
|
|
20341
|
+
var bs58;
|
|
20342
|
+
var hasRequiredBs58;
|
|
20372
20343
|
|
|
20373
|
-
|
|
20374
|
-
|
|
20344
|
+
function requireBs58 () {
|
|
20345
|
+
if (hasRequiredBs58) return bs58;
|
|
20346
|
+
hasRequiredBs58 = 1;
|
|
20347
|
+
var basex = requireSrc();
|
|
20348
|
+
var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
20375
20349
|
|
|
20376
|
-
|
|
20350
|
+
bs58 = basex(ALPHABET);
|
|
20351
|
+
return bs58;
|
|
20352
|
+
}
|
|
20353
|
+
|
|
20354
|
+
var bs58Exports = requireBs58();
|
|
20355
|
+
var base58 = /*@__PURE__*/getDefaultExportFromCjs$1(bs58Exports);
|
|
20356
|
+
|
|
20357
|
+
var index = /*#__PURE__*/_mergeNamespaces({
|
|
20377
20358
|
__proto__: null,
|
|
20378
20359
|
default: base58
|
|
20379
|
-
});
|
|
20360
|
+
}, [bs58Exports]);
|
|
20380
20361
|
|
|
20381
20362
|
const SURFNET_RPC_URL$1 = "https://surfpool.fly.dev";
|
|
20382
20363
|
let React;
|
|
@@ -21265,6 +21246,14 @@ var privyWalletProvider = /*#__PURE__*/Object.freeze({
|
|
|
21265
21246
|
PrivyWalletProvider: PrivyWalletProvider
|
|
21266
21247
|
});
|
|
21267
21248
|
|
|
21249
|
+
/**
|
|
21250
|
+
* Storage key for persisting the MWA auth_token across cold starts.
|
|
21251
|
+
* Holds JSON `{ token: string, address: string }`. Cleared by
|
|
21252
|
+
* `logout()`. Hydrated by the constructor on native so cold-start
|
|
21253
|
+
* doesn't force the user back into Phantom's approval flow when the
|
|
21254
|
+
* underlying wallet authorization is still valid.
|
|
21255
|
+
*/
|
|
21256
|
+
const MWA_AUTH_TOKEN_STORAGE_KEY = 'tarobase_mwa_auth_token';
|
|
21268
21257
|
/**
|
|
21269
21258
|
* Detects whether the current environment is a mobile browser capable of
|
|
21270
21259
|
* Mobile Wallet Adapter (MWA) communication.
|
|
@@ -21336,20 +21325,11 @@ function isMwaAssociationRetryable(e) {
|
|
|
21336
21325
|
* so a second attempt skips the consent sheet, jumps straight to
|
|
21337
21326
|
* Verify/Approve, and completes inside the timeout.
|
|
21338
21327
|
*/
|
|
21339
|
-
async function withMwaAssociationRetry(
|
|
21340
|
-
const t0 = Date.now();
|
|
21341
|
-
console.log(`[MWA-DEBUG] ${label} attempt=1 start`);
|
|
21328
|
+
async function withMwaAssociationRetry(fn) {
|
|
21342
21329
|
try {
|
|
21343
|
-
|
|
21344
|
-
console.log(`[MWA-DEBUG] ${label} attempt=1 ok (${Date.now() - t0}ms)`);
|
|
21345
|
-
return result;
|
|
21330
|
+
return await fn();
|
|
21346
21331
|
}
|
|
21347
21332
|
catch (e) {
|
|
21348
|
-
const info = findMwaError(e);
|
|
21349
|
-
console.log(`[MWA-DEBUG] ${label} attempt=1 err (${Date.now() - t0}ms)`, {
|
|
21350
|
-
outer: { name: e === null || e === void 0 ? void 0 : e.name, message: e === null || e === void 0 ? void 0 : e.message },
|
|
21351
|
-
mwa: info,
|
|
21352
|
-
});
|
|
21353
21333
|
const retryable = isMwaAssociationRetryable(e);
|
|
21354
21334
|
if (!retryable)
|
|
21355
21335
|
throw e;
|
|
@@ -21358,21 +21338,11 @@ async function withMwaAssociationRetry(label, fn) {
|
|
|
21358
21338
|
// so visibility-based waits fire too early. Use a fixed delay long
|
|
21359
21339
|
// enough for Seeker to dismiss its sheet and the OS to release intent
|
|
21360
21340
|
// state. 2.5s is empirically safe; tune from device traces if needed.
|
|
21361
|
-
console.log(`[MWA-DEBUG] ${label} retryable (${retryable.code}); waiting 2500ms before retry`);
|
|
21362
21341
|
await new Promise(r => setTimeout(r, 2500));
|
|
21363
|
-
const t1 = Date.now();
|
|
21364
|
-
console.log(`[MWA-DEBUG] ${label} attempt=2 start`);
|
|
21365
21342
|
try {
|
|
21366
|
-
|
|
21367
|
-
console.log(`[MWA-DEBUG] ${label} attempt=2 ok (${Date.now() - t1}ms)`);
|
|
21368
|
-
return result;
|
|
21343
|
+
return await fn();
|
|
21369
21344
|
}
|
|
21370
21345
|
catch (e2) {
|
|
21371
|
-
const info2 = findMwaError(e2);
|
|
21372
|
-
console.log(`[MWA-DEBUG] ${label} attempt=2 err (${Date.now() - t1}ms)`, {
|
|
21373
|
-
outer: { name: e2 === null || e2 === void 0 ? void 0 : e2.name, message: e2 === null || e2 === void 0 ? void 0 : e2.message },
|
|
21374
|
-
mwa: info2,
|
|
21375
|
-
});
|
|
21376
21346
|
// Only mask the error with the clean Seeker message when the
|
|
21377
21347
|
// second failure is also an association-flavored error. If it's
|
|
21378
21348
|
// a user cancel, wallet rejection, or unknown error, rethrow
|
|
@@ -21411,7 +21381,7 @@ async function withMwaAssociationRetry(label, fn) {
|
|
|
21411
21381
|
* next tap is a new activation (a real retry). A timer-based retry would
|
|
21412
21382
|
* just hit the same Chrome block. Cap at 3 attempts before giving up.
|
|
21413
21383
|
*/
|
|
21414
|
-
async function awaitSignInGestureAndSign(
|
|
21384
|
+
async function awaitSignInGestureAndSign(theme, signFn) {
|
|
21415
21385
|
if (typeof document === 'undefined' || typeof window === 'undefined') {
|
|
21416
21386
|
// SSR / non-browser: skip the gesture, just call (the activation
|
|
21417
21387
|
// model doesn't apply outside the browser).
|
|
@@ -21578,18 +21548,15 @@ async function awaitSignInGestureAndSign(label, theme, signFn) {
|
|
|
21578
21548
|
finishReject(new Error('User cancelled wallet sign in'));
|
|
21579
21549
|
};
|
|
21580
21550
|
closeBtn.addEventListener('click', () => {
|
|
21581
|
-
console.log(`[MWA-DEBUG] ${label} gesture: close clicked`);
|
|
21582
21551
|
handleCancel();
|
|
21583
21552
|
});
|
|
21584
21553
|
overlay.addEventListener('click', (e) => {
|
|
21585
21554
|
if (e.target === overlay) {
|
|
21586
|
-
console.log(`[MWA-DEBUG] ${label} gesture: overlay clicked (cancel)`);
|
|
21587
21555
|
handleCancel();
|
|
21588
21556
|
}
|
|
21589
21557
|
});
|
|
21590
21558
|
const onKeydown = (e) => {
|
|
21591
21559
|
if (e.key === 'Escape') {
|
|
21592
|
-
console.log(`[MWA-DEBUG] ${label} gesture: Escape pressed (cancel)`);
|
|
21593
21560
|
handleCancel();
|
|
21594
21561
|
}
|
|
21595
21562
|
};
|
|
@@ -21599,7 +21566,6 @@ async function awaitSignInGestureAndSign(label, theme, signFn) {
|
|
|
21599
21566
|
return;
|
|
21600
21567
|
attemptCount++;
|
|
21601
21568
|
const attempt = attemptCount;
|
|
21602
|
-
console.log(`[MWA-DEBUG] ${label} gesture: button click attempt=${attempt}`);
|
|
21603
21569
|
// Disable to prevent double-clicks while the wallet popup is up.
|
|
21604
21570
|
button.disabled = true;
|
|
21605
21571
|
setButtonDisabledStyle();
|
|
@@ -21611,29 +21577,17 @@ async function awaitSignInGestureAndSign(label, theme, signFn) {
|
|
|
21611
21577
|
// so Chrome's transient user activation propagates to the
|
|
21612
21578
|
// protocol's window.location.assign(associationUrl) inside
|
|
21613
21579
|
// launchAssociation(). Do not `await` before calling.
|
|
21614
|
-
const t0 = Date.now();
|
|
21615
|
-
console.log(`[MWA-DEBUG] ${label} gesture: signMessage start (attempt=${attempt})`);
|
|
21616
21580
|
signFn().then((results) => {
|
|
21617
|
-
const elapsed = Date.now() - t0;
|
|
21618
21581
|
if (!results || results.length === 0) {
|
|
21619
|
-
console.log(`[MWA-DEBUG] ${label} gesture: signMessage returned empty (attempt=${attempt}, ${elapsed}ms)`);
|
|
21620
21582
|
finishReject(new Error('MWA returned no signature'));
|
|
21621
21583
|
return;
|
|
21622
21584
|
}
|
|
21623
|
-
console.log(`[MWA-DEBUG] ${label} gesture: signMessage ok (attempt=${attempt}, ${elapsed}ms)`);
|
|
21624
21585
|
finishResolve(results[0]);
|
|
21625
21586
|
}).catch((err) => {
|
|
21626
|
-
const elapsed = Date.now() - t0;
|
|
21627
|
-
const info = findMwaError(err);
|
|
21628
|
-
console.log(`[MWA-DEBUG] ${label} gesture: signMessage err (attempt=${attempt}, ${elapsed}ms)`, {
|
|
21629
|
-
outer: { name: err === null || err === void 0 ? void 0 : err.name, message: err === null || err === void 0 ? void 0 : err.message },
|
|
21630
|
-
mwa: info,
|
|
21631
|
-
});
|
|
21632
21587
|
const retryable = isMwaAssociationRetryable(err);
|
|
21633
21588
|
if (retryable && attempt < MAX_ATTEMPTS) {
|
|
21634
21589
|
// Re-enable the button so the user's next tap provides a
|
|
21635
21590
|
// fresh user activation. Show inline error text.
|
|
21636
|
-
console.log(`[MWA-DEBUG] ${label} gesture: retryable (${retryable.code}); awaiting user tap to retry (attempt ${attempt}/${MAX_ATTEMPTS})`);
|
|
21637
21591
|
button.disabled = false;
|
|
21638
21592
|
setButtonEnabledStyle();
|
|
21639
21593
|
button.textContent = originalText;
|
|
@@ -21643,7 +21597,6 @@ async function awaitSignInGestureAndSign(label, theme, signFn) {
|
|
|
21643
21597
|
}
|
|
21644
21598
|
if (retryable) {
|
|
21645
21599
|
// Hit the attempt cap with a still-retryable failure.
|
|
21646
|
-
console.log(`[MWA-DEBUG] ${label} gesture: retryable but attempt cap reached (${attempt})`);
|
|
21647
21600
|
finishReject(new Error("Couldn't connect to your Seeker wallet. Please try again."));
|
|
21648
21601
|
return;
|
|
21649
21602
|
}
|
|
@@ -21652,7 +21605,6 @@ async function awaitSignInGestureAndSign(label, theme, signFn) {
|
|
|
21652
21605
|
finishReject(err);
|
|
21653
21606
|
});
|
|
21654
21607
|
});
|
|
21655
|
-
console.log(`[MWA-DEBUG] ${label} gesture: modal shown`);
|
|
21656
21608
|
});
|
|
21657
21609
|
}
|
|
21658
21610
|
/**
|
|
@@ -21796,7 +21748,7 @@ async function registerMobileWalletAdapter(config) {
|
|
|
21796
21748
|
if (typeof window === 'undefined')
|
|
21797
21749
|
return;
|
|
21798
21750
|
try {
|
|
21799
|
-
const walletStandardMobile = await import('./index.browser-
|
|
21751
|
+
const walletStandardMobile = await import('./index.browser-nVGFrIHK.esm.js');
|
|
21800
21752
|
const registerMwa = walletStandardMobile.registerMwa || ((_a = walletStandardMobile.default) === null || _a === void 0 ? void 0 : _a.registerMwa);
|
|
21801
21753
|
if (!registerMwa) {
|
|
21802
21754
|
console.warn('[SolanaMobileWallet] registerMwa not found in @solana-mobile/wallet-standard-mobile');
|
|
@@ -21823,7 +21775,7 @@ async function registerMobileWalletAdapter(config) {
|
|
|
21823
21775
|
// SolanaMobileWalletProvider.ensureWallet() for why. Consumers that
|
|
21824
21776
|
// want their own UX can pass config.onWalletNotFound.
|
|
21825
21777
|
options.onWalletNotFound = (_b = config === null || config === void 0 ? void 0 : config.onWalletNotFound) !== null && _b !== void 0 ? _b : (async () => {
|
|
21826
|
-
|
|
21778
|
+
// intentional no-op
|
|
21827
21779
|
});
|
|
21828
21780
|
registerMwa(options);
|
|
21829
21781
|
}
|
|
@@ -21863,19 +21815,66 @@ class SolanaMobileWalletProvider {
|
|
|
21863
21815
|
constructor(networkUrl = null, config = {}) {
|
|
21864
21816
|
/** LocalSolanaMobileWalletAdapterWallet, lazy-constructed in ensureWallet(). */
|
|
21865
21817
|
this.wallet = null;
|
|
21818
|
+
/**
|
|
21819
|
+
* Cached MWA auth_token returned by `wallet.authorize()`. Reused by
|
|
21820
|
+
* subsequent native transact() calls (signMessage / signTransaction)
|
|
21821
|
+
* so the user doesn't get the wallet-pick popup on every operation.
|
|
21822
|
+
* Persisted to platform storage and hydrated by the constructor on
|
|
21823
|
+
* native; cleared by logout() and on `ERROR_REAUTHORIZE`.
|
|
21824
|
+
*/
|
|
21825
|
+
this.nativeAuthToken = null;
|
|
21826
|
+
/** Cached public key string for the connected MWA wallet (native). */
|
|
21827
|
+
this.nativeAddress = null;
|
|
21866
21828
|
this.networkUrl = networkUrl;
|
|
21867
21829
|
this.config = config;
|
|
21868
|
-
|
|
21830
|
+
// Allow construction in true React Native environments: getPlatform().hasDOM
|
|
21831
|
+
// is false there even though `typeof window === 'object'` (RN exposes a
|
|
21832
|
+
// partial window global). Web/PWA paths still keep their original guard:
|
|
21833
|
+
// they need real window+document for wallet-standard-mobile's deep-link
|
|
21834
|
+
// mechanism, so missing-window in those builds remains a fail-fast.
|
|
21835
|
+
const hasDOM = getPlatform().hasDOM;
|
|
21836
|
+
if (!hasDOM && typeof window === 'undefined') {
|
|
21837
|
+
throw new Error('SolanaMobileWalletProvider can only be instantiated in a browser or React Native environment');
|
|
21838
|
+
}
|
|
21839
|
+
if (hasDOM && typeof window === 'undefined') {
|
|
21869
21840
|
throw new Error('SolanaMobileWalletProvider can only be instantiated in a browser environment');
|
|
21870
21841
|
}
|
|
21871
21842
|
if (SolanaMobileWalletProvider.instance) {
|
|
21872
21843
|
return SolanaMobileWalletProvider.instance;
|
|
21873
21844
|
}
|
|
21845
|
+
// `appIdentity.uri` is what Phantom Android (and other MWA wallets)
|
|
21846
|
+
// display in their approval modal. On web/PWA this is the page
|
|
21847
|
+
// origin; on native there's no `window.location`, so fall back to
|
|
21848
|
+
// a stable identifier the user can recognize. Apps can override
|
|
21849
|
+
// entirely via `config.appIdentity.uri`.
|
|
21850
|
+
const fallbackUri = hasDOM
|
|
21851
|
+
? getPlatform().getLocationOrigin()
|
|
21852
|
+
: 'tarobase://app';
|
|
21874
21853
|
this.appIdentity = config.appIdentity || {
|
|
21875
21854
|
name: 'TaroBase App',
|
|
21876
|
-
uri:
|
|
21855
|
+
uri: fallbackUri,
|
|
21877
21856
|
};
|
|
21878
21857
|
this.cluster = config.cluster || 'mainnet-beta';
|
|
21858
|
+
// Hydrate cached MWA auth_token from storage on native so we can
|
|
21859
|
+
// skip the wallet-pick popup after a cold-start when the underlying
|
|
21860
|
+
// wallet authorization is still valid. Sync storage call per the
|
|
21861
|
+
// PlatformAdapter contract; safe to swallow read errors (a fresh
|
|
21862
|
+
// login() just re-authorizes).
|
|
21863
|
+
if (!hasDOM) {
|
|
21864
|
+
try {
|
|
21865
|
+
const raw = getPlatform().storage.getItem(MWA_AUTH_TOKEN_STORAGE_KEY);
|
|
21866
|
+
if (raw) {
|
|
21867
|
+
const parsed = JSON.parse(raw);
|
|
21868
|
+
if (typeof parsed.token === 'string' && typeof parsed.address === 'string') {
|
|
21869
|
+
this.nativeAuthToken = parsed.token;
|
|
21870
|
+
this.nativeAddress = parsed.address;
|
|
21871
|
+
}
|
|
21872
|
+
}
|
|
21873
|
+
}
|
|
21874
|
+
catch (_a) {
|
|
21875
|
+
// Corrupt or unreadable cache — ignore. login() will re-auth.
|
|
21876
|
+
}
|
|
21877
|
+
}
|
|
21879
21878
|
SolanaMobileWalletProvider.instance = this;
|
|
21880
21879
|
}
|
|
21881
21880
|
static getInstance(networkUrl, config) {
|
|
@@ -21888,7 +21887,7 @@ class SolanaMobileWalletProvider {
|
|
|
21888
21887
|
async ensureWallet() {
|
|
21889
21888
|
if (this.wallet)
|
|
21890
21889
|
return this.wallet;
|
|
21891
|
-
const mod = await import('./index.browser-
|
|
21890
|
+
const mod = await import('./index.browser-nVGFrIHK.esm.js');
|
|
21892
21891
|
const chain = mapChainToWalletStandard(this.cluster);
|
|
21893
21892
|
this.wallet = new mod.LocalSolanaMobileWalletAdapterWallet({
|
|
21894
21893
|
appIdentity: this.appIdentity,
|
|
@@ -21902,7 +21901,7 @@ class SolanaMobileWalletProvider {
|
|
|
21902
21901
|
// login()'s withMwaAssociationRetry handles this case; on second
|
|
21903
21902
|
// failure it surfaces a clean error message to the host app.
|
|
21904
21903
|
onWalletNotFound: async () => {
|
|
21905
|
-
|
|
21904
|
+
// intentional no-op
|
|
21906
21905
|
},
|
|
21907
21906
|
});
|
|
21908
21907
|
return this.wallet;
|
|
@@ -21938,6 +21937,134 @@ class SolanaMobileWalletProvider {
|
|
|
21938
21937
|
getChain() {
|
|
21939
21938
|
return mapChainToWalletStandard(this.cluster);
|
|
21940
21939
|
}
|
|
21940
|
+
/**
|
|
21941
|
+
* Dynamically import and unwrap `transact` from the MWA web3js
|
|
21942
|
+
* package. The package is externalized in rollup.config.js so this
|
|
21943
|
+
* resolves to `lib/cjs/index.native.js` (TurboModule-backed) on
|
|
21944
|
+
* Metro and `lib/esm/index.browser.js` (WebSocket) on webpack/vite
|
|
21945
|
+
* per their respective platform conditions. Handles Metro's CJS-to-
|
|
21946
|
+
* ESM interop variance (`mod.transact` vs `mod.default?.transact`).
|
|
21947
|
+
*/
|
|
21948
|
+
async loadTransact() {
|
|
21949
|
+
var _a;
|
|
21950
|
+
const mod = await import('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
|
|
21951
|
+
const t = mod.transact || ((_a = mod.default) === null || _a === void 0 ? void 0 : _a.transact);
|
|
21952
|
+
if (typeof t !== 'function') {
|
|
21953
|
+
throw new Error('MWA transact API not available on this platform');
|
|
21954
|
+
}
|
|
21955
|
+
return t;
|
|
21956
|
+
}
|
|
21957
|
+
/**
|
|
21958
|
+
* Cache and persist a fresh MWA auth_token + address. Called from
|
|
21959
|
+
* `_loginNative` after a successful authorize. Storage failures are
|
|
21960
|
+
* non-fatal (next cold-start re-auths).
|
|
21961
|
+
*/
|
|
21962
|
+
persistNativeAuth(token, address) {
|
|
21963
|
+
this.nativeAuthToken = token;
|
|
21964
|
+
this.nativeAddress = address;
|
|
21965
|
+
try {
|
|
21966
|
+
getPlatform().storage.setItem(MWA_AUTH_TOKEN_STORAGE_KEY, JSON.stringify({ token, address }));
|
|
21967
|
+
}
|
|
21968
|
+
catch (_a) {
|
|
21969
|
+
// non-fatal — token still in-memory for this process
|
|
21970
|
+
}
|
|
21971
|
+
}
|
|
21972
|
+
/** Clear cached + persisted native auth state. */
|
|
21973
|
+
clearNativeAuth() {
|
|
21974
|
+
this.nativeAuthToken = null;
|
|
21975
|
+
this.nativeAddress = null;
|
|
21976
|
+
try {
|
|
21977
|
+
getPlatform().storage.removeItem(MWA_AUTH_TOKEN_STORAGE_KEY);
|
|
21978
|
+
}
|
|
21979
|
+
catch (_a) {
|
|
21980
|
+
// ignore
|
|
21981
|
+
}
|
|
21982
|
+
}
|
|
21983
|
+
/**
|
|
21984
|
+
* Classify an MWA-native error as a user cancellation. User-cancel
|
|
21985
|
+
* shouldn't surface as a red console.error; callers can swallow or
|
|
21986
|
+
* show a softer message. MWA spec codes plus the same substring
|
|
21987
|
+
* checks the web path uses to catch wallet-specific phrasing.
|
|
21988
|
+
*/
|
|
21989
|
+
isNativeUserCancel(err) {
|
|
21990
|
+
var _a;
|
|
21991
|
+
if (!err)
|
|
21992
|
+
return false;
|
|
21993
|
+
const code = err.code;
|
|
21994
|
+
if (code === 'ERROR_NOT_SIGNED')
|
|
21995
|
+
return true;
|
|
21996
|
+
const msg = String((_a = err.message) !== null && _a !== void 0 ? _a : '').toLowerCase();
|
|
21997
|
+
return /user (rejected|denied|cancelled|canceled|declined)/.test(msg);
|
|
21998
|
+
}
|
|
21999
|
+
/**
|
|
22000
|
+
* Native MWA login via @solana-mobile/mobile-wallet-adapter-protocol-web3js.
|
|
22001
|
+
* Used in true React Native (Expo) environments where wallet-standard-mobile's
|
|
22002
|
+
* web universal-link path doesn't apply. Does authorize + signMessage in a
|
|
22003
|
+
* single transact() roundtrip — intent-based MWA doesn't need the two-popup
|
|
22004
|
+
* dance the web path uses (no Chrome activation-loss concern). Persists the
|
|
22005
|
+
* resulting auth_token so cold-start can reauthorize without a fresh popup.
|
|
22006
|
+
*/
|
|
22007
|
+
async _loginNative() {
|
|
22008
|
+
const transact = await this.loadTransact();
|
|
22009
|
+
const existingSession = await WebSessionManager.getSession();
|
|
22010
|
+
const nonce = await genAuthNonce();
|
|
22011
|
+
const result = await transact(async (wallet) => {
|
|
22012
|
+
const auth = await wallet.authorize({
|
|
22013
|
+
chain: this.getChain(),
|
|
22014
|
+
identity: this.appIdentity,
|
|
22015
|
+
});
|
|
22016
|
+
if (!auth.accounts || auth.accounts.length === 0) {
|
|
22017
|
+
throw new Error('MWA returned no accounts');
|
|
22018
|
+
}
|
|
22019
|
+
const account = auth.accounts[0];
|
|
22020
|
+
// account.address is base64-encoded per MWA spec; convert to
|
|
22021
|
+
// the base58 form Tarobase + the rest of the SDK use.
|
|
22022
|
+
const base58Addr = new PublicKey(bufferExports.Buffer.from(account.address, 'base64')).toBase58();
|
|
22023
|
+
// Reuse session if already valid for this address — skip the
|
|
22024
|
+
// signMessages roundtrip entirely.
|
|
22025
|
+
if (existingSession && existingSession.address === base58Addr) {
|
|
22026
|
+
return {
|
|
22027
|
+
base58Addr,
|
|
22028
|
+
authToken: auth.auth_token,
|
|
22029
|
+
signatureBase64: null,
|
|
22030
|
+
};
|
|
22031
|
+
}
|
|
22032
|
+
const messageText = await genSolanaMessage(base58Addr, nonce);
|
|
22033
|
+
const messageBytes = getPlatform().textEncode(messageText);
|
|
22034
|
+
const signatures = await wallet.signMessages({
|
|
22035
|
+
addresses: [account.address],
|
|
22036
|
+
payloads: [messageBytes],
|
|
22037
|
+
});
|
|
22038
|
+
if (!signatures || signatures.length === 0) {
|
|
22039
|
+
throw new Error('MWA returned no signature');
|
|
22040
|
+
}
|
|
22041
|
+
// Per spec, signMessages returns Uint8Array[] of signatures
|
|
22042
|
+
// (one per payload), not message+signature concatenations.
|
|
22043
|
+
const signatureBase64 = bufferExports.Buffer.from(signatures[0]).toString('base64');
|
|
22044
|
+
return {
|
|
22045
|
+
base58Addr,
|
|
22046
|
+
authToken: auth.auth_token,
|
|
22047
|
+
signatureBase64,
|
|
22048
|
+
messageText,
|
|
22049
|
+
};
|
|
22050
|
+
});
|
|
22051
|
+
this.persistNativeAuth(result.authToken, result.base58Addr);
|
|
22052
|
+
// Existing valid session — short-circuit before re-creating server-side.
|
|
22053
|
+
if (existingSession && existingSession.address === result.base58Addr) {
|
|
22054
|
+
const user = { provider: this, address: result.base58Addr };
|
|
22055
|
+
setCurrentUser(user);
|
|
22056
|
+
return user;
|
|
22057
|
+
}
|
|
22058
|
+
// Create Tarobase session on the server.
|
|
22059
|
+
if (!result.signatureBase64 || !result.messageText) {
|
|
22060
|
+
throw new Error('MWA login completed without signature');
|
|
22061
|
+
}
|
|
22062
|
+
const createSessionResult = await createSessionWithSignature(result.base58Addr, result.messageText, result.signatureBase64);
|
|
22063
|
+
await WebSessionManager.storeSession(result.base58Addr, createSessionResult.accessToken, createSessionResult.idToken, createSessionResult.refreshToken);
|
|
22064
|
+
const user = { provider: this, address: result.base58Addr };
|
|
22065
|
+
setCurrentUser(user);
|
|
22066
|
+
return user;
|
|
22067
|
+
}
|
|
21941
22068
|
async login() {
|
|
21942
22069
|
var _a, _b, _c, _d, _e;
|
|
21943
22070
|
setAuthLoading(true);
|
|
@@ -21948,6 +22075,13 @@ class SolanaMobileWalletProvider {
|
|
|
21948
22075
|
const prevAuthMethod = readAuthMethod();
|
|
21949
22076
|
writeAuthMethod(MWA_AUTH_METHOD);
|
|
21950
22077
|
try {
|
|
22078
|
+
// True React Native: skip the wallet-standard-mobile path (which
|
|
22079
|
+
// requires window.isSecureContext and a real DOM) and use the raw
|
|
22080
|
+
// MWA protocol via Android intents.
|
|
22081
|
+
if (!getPlatform().hasDOM) {
|
|
22082
|
+
const user = await this._loginNative();
|
|
22083
|
+
return user;
|
|
22084
|
+
}
|
|
21951
22085
|
const wallet = await this.ensureWallet();
|
|
21952
22086
|
// Quick-check: wallet may already have authorization (e.g. from a
|
|
21953
22087
|
// previous in-page login) and a matching Tarobase session — skip
|
|
@@ -21976,7 +22110,7 @@ class SolanaMobileWalletProvider {
|
|
|
21976
22110
|
// consent on the second pass and completes quickly. See
|
|
21977
22111
|
// withMwaAssociationRetry for details.
|
|
21978
22112
|
const connectFeat = getConnectFeature(wallet);
|
|
21979
|
-
const { accounts } = await withMwaAssociationRetry(
|
|
22113
|
+
const { accounts } = await withMwaAssociationRetry(() => connectFeat.connect());
|
|
21980
22114
|
if (!accounts || accounts.length === 0) {
|
|
21981
22115
|
throw new Error('MWA returned no accounts');
|
|
21982
22116
|
}
|
|
@@ -22009,7 +22143,7 @@ class SolanaMobileWalletProvider {
|
|
|
22009
22143
|
const messageText = await genSolanaMessage(base58Addr, nonce);
|
|
22010
22144
|
const messageBytes = getPlatform().textEncode(messageText);
|
|
22011
22145
|
const signMessageFeat = getSignMessageFeature(wallet);
|
|
22012
|
-
const signResult = await awaitSignInGestureAndSign(
|
|
22146
|
+
const signResult = await awaitSignInGestureAndSign(this.config.theme, () => signMessageFeat.signMessage({ account, message: messageBytes }));
|
|
22013
22147
|
if (!signResult) {
|
|
22014
22148
|
throw new Error('MWA returned no signature');
|
|
22015
22149
|
}
|
|
@@ -22049,6 +22183,29 @@ class SolanaMobileWalletProvider {
|
|
|
22049
22183
|
return null;
|
|
22050
22184
|
}
|
|
22051
22185
|
async logout() {
|
|
22186
|
+
if (!getPlatform().hasDOM) {
|
|
22187
|
+
// Native path: deauthorize the cached MWA auth_token if we have
|
|
22188
|
+
// one (failures non-fatal — the wallet app may have been
|
|
22189
|
+
// uninstalled or the token already revoked), then clear local
|
|
22190
|
+
// and persisted state.
|
|
22191
|
+
const token = this.nativeAuthToken;
|
|
22192
|
+
if (token) {
|
|
22193
|
+
try {
|
|
22194
|
+
const transact = await this.loadTransact();
|
|
22195
|
+
await transact(async (wallet) => {
|
|
22196
|
+
await wallet.deauthorize({ auth_token: token });
|
|
22197
|
+
});
|
|
22198
|
+
}
|
|
22199
|
+
catch (error) {
|
|
22200
|
+
console.warn('[SolanaMobileWallet] Native deauthorize error:', error);
|
|
22201
|
+
}
|
|
22202
|
+
}
|
|
22203
|
+
this.clearNativeAuth();
|
|
22204
|
+
WebSessionManager.clearSession();
|
|
22205
|
+
writeAuthMethod(null);
|
|
22206
|
+
setCurrentUser(null);
|
|
22207
|
+
return;
|
|
22208
|
+
}
|
|
22052
22209
|
try {
|
|
22053
22210
|
const wallet = await this.ensureWallet();
|
|
22054
22211
|
const disconnectFeat = getDisconnectFeature(wallet);
|
|
@@ -22068,7 +22225,42 @@ class SolanaMobileWalletProvider {
|
|
|
22068
22225
|
setCurrentUser(null);
|
|
22069
22226
|
}
|
|
22070
22227
|
async signMessage(message) {
|
|
22071
|
-
var _a, _b;
|
|
22228
|
+
var _a, _b, _c;
|
|
22229
|
+
// Native: reauthorize with cached auth_token, then signMessages inside
|
|
22230
|
+
// the same transact() session. No wallet-pick popup if the auth_token
|
|
22231
|
+
// is still valid for the user's wallet.
|
|
22232
|
+
if (!getPlatform().hasDOM) {
|
|
22233
|
+
if (!this.nativeAuthToken || !this.nativeAddress) {
|
|
22234
|
+
throw new Error('Wallet not connected. Call login() first.');
|
|
22235
|
+
}
|
|
22236
|
+
const transact = await this.loadTransact();
|
|
22237
|
+
const messageBytes = getPlatform().textEncode(message);
|
|
22238
|
+
const addressBase64 = new PublicKey(this.nativeAddress).toBuffer().toString('base64');
|
|
22239
|
+
const authToken = this.nativeAuthToken;
|
|
22240
|
+
try {
|
|
22241
|
+
const signature = await transact(async (wallet) => {
|
|
22242
|
+
await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
|
|
22243
|
+
const sigs = await wallet.signMessages({
|
|
22244
|
+
addresses: [addressBase64],
|
|
22245
|
+
payloads: [messageBytes],
|
|
22246
|
+
});
|
|
22247
|
+
if (!sigs || sigs.length === 0)
|
|
22248
|
+
throw new Error('MWA returned no signature');
|
|
22249
|
+
return sigs[0];
|
|
22250
|
+
});
|
|
22251
|
+
return bufferExports.Buffer.from(signature).toString('base64');
|
|
22252
|
+
}
|
|
22253
|
+
catch (error) {
|
|
22254
|
+
if (this.isNativeUserCancel(error)) {
|
|
22255
|
+
throw new Error('User declined to sign');
|
|
22256
|
+
}
|
|
22257
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED' || (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_REAUTHORIZE') {
|
|
22258
|
+
await this.logout();
|
|
22259
|
+
throw new Error('Wallet connection lost. Please reconnect.');
|
|
22260
|
+
}
|
|
22261
|
+
throw new Error(`Failed to sign message: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
22262
|
+
}
|
|
22263
|
+
}
|
|
22072
22264
|
const account = await this.ensureAuthorized();
|
|
22073
22265
|
const wallet = await this.ensureWallet();
|
|
22074
22266
|
try {
|
|
@@ -22082,7 +22274,7 @@ class SolanaMobileWalletProvider {
|
|
|
22082
22274
|
return bufferExports.Buffer.from(sigBytes).toString('base64');
|
|
22083
22275
|
}
|
|
22084
22276
|
catch (error) {
|
|
22085
|
-
if (((
|
|
22277
|
+
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')) ||
|
|
22086
22278
|
(error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
|
|
22087
22279
|
await this.logout();
|
|
22088
22280
|
throw new Error('Wallet connection lost. Please reconnect.');
|
|
@@ -22091,7 +22283,58 @@ class SolanaMobileWalletProvider {
|
|
|
22091
22283
|
}
|
|
22092
22284
|
}
|
|
22093
22285
|
async signTransaction(transaction) {
|
|
22094
|
-
var _a, _b;
|
|
22286
|
+
var _a, _b, _c;
|
|
22287
|
+
// Native: fill blockhash/feePayer if missing, then signTransactions
|
|
22288
|
+
// inside a transact() session keyed by the cached auth_token.
|
|
22289
|
+
if (!getPlatform().hasDOM) {
|
|
22290
|
+
if (!this.nativeAuthToken || !this.nativeAddress) {
|
|
22291
|
+
throw new Error('Wallet not connected. Call login() first.');
|
|
22292
|
+
}
|
|
22293
|
+
const connectedPubkey = new PublicKey(this.nativeAddress);
|
|
22294
|
+
const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
|
|
22295
|
+
if (isLegacyTransaction) {
|
|
22296
|
+
const legacyTx = transaction;
|
|
22297
|
+
if (!legacyTx.recentBlockhash) {
|
|
22298
|
+
const conn = new Connection(this.getRpcUrl(), 'confirmed');
|
|
22299
|
+
const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash('confirmed');
|
|
22300
|
+
legacyTx.recentBlockhash = blockhash;
|
|
22301
|
+
legacyTx.lastValidBlockHeight = lastValidBlockHeight;
|
|
22302
|
+
}
|
|
22303
|
+
if (!legacyTx.feePayer) {
|
|
22304
|
+
legacyTx.feePayer = connectedPubkey;
|
|
22305
|
+
}
|
|
22306
|
+
}
|
|
22307
|
+
else {
|
|
22308
|
+
const versionedTx = transaction;
|
|
22309
|
+
if (!versionedTx.message.recentBlockhash) {
|
|
22310
|
+
const conn = new Connection(this.getRpcUrl(), 'confirmed');
|
|
22311
|
+
const { blockhash } = await conn.getLatestBlockhash('confirmed');
|
|
22312
|
+
versionedTx.message.recentBlockhash = blockhash;
|
|
22313
|
+
}
|
|
22314
|
+
}
|
|
22315
|
+
const transact = await this.loadTransact();
|
|
22316
|
+
const authToken = this.nativeAuthToken;
|
|
22317
|
+
try {
|
|
22318
|
+
const signed = await transact(async (wallet) => {
|
|
22319
|
+
await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
|
|
22320
|
+
const results = await wallet.signTransactions({ transactions: [transaction] });
|
|
22321
|
+
if (!results || results.length === 0)
|
|
22322
|
+
throw new Error('MWA returned no signed transaction');
|
|
22323
|
+
return results[0];
|
|
22324
|
+
});
|
|
22325
|
+
return signed;
|
|
22326
|
+
}
|
|
22327
|
+
catch (error) {
|
|
22328
|
+
if (this.isNativeUserCancel(error)) {
|
|
22329
|
+
throw new Error('User declined to sign');
|
|
22330
|
+
}
|
|
22331
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED' || (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_REAUTHORIZE') {
|
|
22332
|
+
await this.logout();
|
|
22333
|
+
throw new Error('Wallet connection lost. Please reconnect.');
|
|
22334
|
+
}
|
|
22335
|
+
throw new Error(`Failed to sign transaction: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
22336
|
+
}
|
|
22337
|
+
}
|
|
22095
22338
|
const account = await this.ensureAuthorized();
|
|
22096
22339
|
const connectedPubkey = new PublicKey(account.publicKey);
|
|
22097
22340
|
const wallet = await this.ensureWallet();
|
|
@@ -22130,7 +22373,7 @@ class SolanaMobileWalletProvider {
|
|
|
22130
22373
|
return txFromWireBytes(new Uint8Array(signedBytes));
|
|
22131
22374
|
}
|
|
22132
22375
|
catch (error) {
|
|
22133
|
-
if (((
|
|
22376
|
+
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')) ||
|
|
22134
22377
|
(error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
|
|
22135
22378
|
await this.logout();
|
|
22136
22379
|
throw new Error('Wallet connection lost. Please reconnect.');
|
|
@@ -22139,7 +22382,70 @@ class SolanaMobileWalletProvider {
|
|
|
22139
22382
|
}
|
|
22140
22383
|
}
|
|
22141
22384
|
async signAndSubmitTransaction(transaction, feePayer) {
|
|
22142
|
-
var _a, _b, _c, _d, _e, _f;
|
|
22385
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
22386
|
+
// Native: signAndSendTransactions inside a transact() session.
|
|
22387
|
+
// The wallet submits to its own RPC; we then await confirmation on
|
|
22388
|
+
// ours. Surfnet (custom RPC) needs manual submission because the
|
|
22389
|
+
// wallet won't route there — we fall back to sign-only + manual send.
|
|
22390
|
+
if (!getPlatform().hasDOM) {
|
|
22391
|
+
if (!this.nativeAuthToken || !this.nativeAddress) {
|
|
22392
|
+
throw new Error('Wallet not connected. Call login() first.');
|
|
22393
|
+
}
|
|
22394
|
+
const connectedPubkey = new PublicKey(this.nativeAddress);
|
|
22395
|
+
const rpcUrl = this.getRpcUrl();
|
|
22396
|
+
const connection = new Connection(rpcUrl, 'confirmed');
|
|
22397
|
+
const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
|
|
22398
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
22399
|
+
const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
|
|
22400
|
+
if (isLegacyTransaction) {
|
|
22401
|
+
const legacyTx = transaction;
|
|
22402
|
+
legacyTx.recentBlockhash = blockhash;
|
|
22403
|
+
legacyTx.lastValidBlockHeight = lastValidBlockHeight;
|
|
22404
|
+
if (!legacyTx.feePayer)
|
|
22405
|
+
legacyTx.feePayer = feePayer !== null && feePayer !== void 0 ? feePayer : connectedPubkey;
|
|
22406
|
+
}
|
|
22407
|
+
else {
|
|
22408
|
+
const versionedTx = transaction;
|
|
22409
|
+
versionedTx.message.recentBlockhash = blockhash;
|
|
22410
|
+
}
|
|
22411
|
+
const transact = await this.loadTransact();
|
|
22412
|
+
const authToken = this.nativeAuthToken;
|
|
22413
|
+
try {
|
|
22414
|
+
if (isSurfnet) {
|
|
22415
|
+
// Surfnet: sign only, submit manually to Surfnet RPC
|
|
22416
|
+
// (the wallet would route signAndSend to its own RPC).
|
|
22417
|
+
const signed = await transact(async (wallet) => {
|
|
22418
|
+
await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
|
|
22419
|
+
const results = await wallet.signTransactions({ transactions: [transaction] });
|
|
22420
|
+
if (!results || results.length === 0)
|
|
22421
|
+
throw new Error('MWA returned no signed transaction');
|
|
22422
|
+
return results[0];
|
|
22423
|
+
});
|
|
22424
|
+
const sig = await connection.sendRawTransaction(signed.serialize(), { preflightCommitment: 'confirmed' });
|
|
22425
|
+
await confirmAndCheckTransaction(connection, sig);
|
|
22426
|
+
return sig;
|
|
22427
|
+
}
|
|
22428
|
+
const sig = await transact(async (wallet) => {
|
|
22429
|
+
await wallet.reauthorize({ auth_token: authToken, identity: this.appIdentity });
|
|
22430
|
+
const results = await wallet.signAndSendTransactions({ transactions: [transaction] });
|
|
22431
|
+
if (!results || results.length === 0)
|
|
22432
|
+
throw new Error('MWA returned no signature');
|
|
22433
|
+
return results[0];
|
|
22434
|
+
});
|
|
22435
|
+
await confirmAndCheckTransaction(connection, sig);
|
|
22436
|
+
return sig;
|
|
22437
|
+
}
|
|
22438
|
+
catch (error) {
|
|
22439
|
+
if (this.isNativeUserCancel(error)) {
|
|
22440
|
+
throw new Error('User declined to sign');
|
|
22441
|
+
}
|
|
22442
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED' || (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_REAUTHORIZE') {
|
|
22443
|
+
await this.logout();
|
|
22444
|
+
throw new Error('Wallet connection lost. Please reconnect.');
|
|
22445
|
+
}
|
|
22446
|
+
throw new Error(`Failed to sign+submit transaction: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
22447
|
+
}
|
|
22448
|
+
}
|
|
22143
22449
|
const account = await this.ensureAuthorized();
|
|
22144
22450
|
const connectedPubkey = new PublicKey(account.publicKey);
|
|
22145
22451
|
const wallet = await this.ensureWallet();
|
|
@@ -22206,16 +22512,16 @@ class SolanaMobileWalletProvider {
|
|
|
22206
22512
|
return signature;
|
|
22207
22513
|
}
|
|
22208
22514
|
catch (error) {
|
|
22209
|
-
if (((
|
|
22515
|
+
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')) ||
|
|
22210
22516
|
(error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHORIZATION_FAILED') {
|
|
22211
22517
|
await this.logout();
|
|
22212
22518
|
throw new Error('Wallet connection lost. Please reconnect.');
|
|
22213
22519
|
}
|
|
22214
22520
|
const isUserRejection = (error === null || error === void 0 ? void 0 : error.code) === 4001 ||
|
|
22215
|
-
((
|
|
22216
|
-
((
|
|
22217
|
-
((
|
|
22218
|
-
((
|
|
22521
|
+
((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.toLowerCase().includes('user rejected')) ||
|
|
22522
|
+
((_e = error === null || error === void 0 ? void 0 : error.message) === null || _e === void 0 ? void 0 : _e.toLowerCase().includes('user denied')) ||
|
|
22523
|
+
((_f = error === null || error === void 0 ? void 0 : error.message) === null || _f === void 0 ? void 0 : _f.toLowerCase().includes('user cancelled')) ||
|
|
22524
|
+
((_g = error === null || error === void 0 ? void 0 : error.message) === null || _g === void 0 ? void 0 : _g.toLowerCase().includes('user canceled'));
|
|
22219
22525
|
if (!isUserRejection) {
|
|
22220
22526
|
console.error('[SolanaMobileWallet] Transaction failed:', error);
|
|
22221
22527
|
}
|
|
@@ -22765,5 +23071,5 @@ class PrivyExpoProvider {
|
|
|
22765
23071
|
}
|
|
22766
23072
|
}
|
|
22767
23073
|
|
|
22768
|
-
export {
|
|
22769
|
-
//# sourceMappingURL=index-
|
|
23074
|
+
export { genAuthNonce as $, count as A, aggregate as B, subscribe as C, useAuth as D, deserializeTransaction as E, getIdToken as F, setPlatform as G, getPlatform as H, PrivyWalletProvider as I, DEFAULT_TEST_ADDRESS as J, isMobileWalletAvailable as K, registerMobileWalletAdapter as L, MockAuthProvider as M, PrivyExpoProvider as N, OffchainAuthProvider as O, PhantomWalletProvider as P, InsufficientBalanceError as Q, ReactNativeSessionManager as R, SolanaMobileWalletProvider as S, ServerSessionManager as T, buildSetDocumentsTransaction as U, clearCache as V, WebSessionManager as W, closeAllSubscriptions as X, convertRemainingAccounts as Y, createSessionWithPrivy as Z, createSessionWithSignature as _, base58 as a, genSolanaMessage as a0, getCachedData as a1, getMany as a2, reconnectWithNewAuth as a3, refreshSession as a4, signSessionCreateMessage as a5, bufferExports as b, commonjsRequire as c, getCurrentUser as d, onAuthLoadingChanged as e, getAuthLoading as f, getDefaultExportFromCjs$1 as g, logout as h, init as i, getConfig as j, getAuthProvider as k, login as l, get as m, setMany as n, onAuthStateChanged as o, setFile as p, getFiles as q, require$$0 as r, set as s, runQuery as t, runQueryMany as u, runExpression as v, runExpressionMany as w, signMessage as x, signTransaction as y, signAndSubmitTransaction as z };
|
|
23075
|
+
//# sourceMappingURL=index-BTwX7FYW.esm.js.map
|