@pooflabs/web 0.0.84 → 0.0.85-rc2
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 +47 -20
- package/dist/{index-BM6hgCdH.js → index-B1_Q49qQ.js} +2 -2
- package/dist/{index-BM6hgCdH.js.map → index-B1_Q49qQ.js.map} +1 -1
- package/dist/{index-CH2G5Y9i.esm.js → index-B7tJ8TAn.esm.js} +2 -2
- package/dist/{index-CH2G5Y9i.esm.js.map → index-B7tJ8TAn.esm.js.map} +1 -1
- package/dist/{index-BPlF6-PQ.js → index-BeFR3-cf.js} +522 -289
- package/dist/{index-BPlF6-PQ.js.map → index-BeFR3-cf.js.map} +1 -1
- package/dist/index-DbJCCvVN.esm.js +6 -0
- package/dist/index-DbJCCvVN.esm.js.map +1 -0
- package/dist/{index-CSeN3jbG.js → index-DflG_JAB.js} +3 -3
- package/dist/{index-CSeN3jbG.js.map → index-DflG_JAB.js.map} +1 -1
- package/dist/{index-Bp4b5LXs.js → index-DyRIXw-l.js} +2 -2
- package/dist/index-DyRIXw-l.js.map +1 -0
- package/dist/{index-XHbmzFFO.esm.js → index-QukWgaIi.esm.js} +523 -290
- package/dist/{index-XHbmzFFO.esm.js.map → index-QukWgaIi.esm.js.map} +1 -1
- package/dist/{index-ep10Sw82.esm.js → index-agGmWBn4.esm.js} +3 -3
- package/dist/{index-ep10Sw82.esm.js.map → index-agGmWBn4.esm.js.map} +1 -1
- package/dist/{index.browser-C1QL04xM.js → index.browser-BJmFjY2f.js} +1006 -15
- package/dist/index.browser-BJmFjY2f.js.map +1 -0
- package/dist/index.browser-DZtZWdul.js +4994 -0
- package/dist/index.browser-DZtZWdul.js.map +1 -0
- package/dist/index.browser-lHP9glAW.esm.js +6060 -0
- package/dist/index.browser-lHP9glAW.esm.js.map +1 -0
- package/dist/{index.browser-Cgj7Hs6n.esm.js → index.browser-p-pgsxxW.esm.js} +836 -916
- package/dist/index.browser-p-pgsxxW.esm.js.map +1 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{index.native-BmtuyGXs.js → index.native-ANhb4jEB.js} +4 -4
- package/dist/{index.native-BmtuyGXs.js.map → index.native-ANhb4jEB.js.map} +1 -1
- package/dist/{index.native-X01vlukI.esm.js → index.native-a3mhu9HP.esm.js} +4 -4
- package/dist/{index.native-X01vlukI.esm.js.map → index.native-a3mhu9HP.esm.js.map} +1 -1
- package/dist/index.native.esm.js +1 -1
- package/dist/index.native.js +1 -1
- package/dist/{phantom-wallet-provider-C_LPU6Ns.js → phantom-wallet-provider-BOdn0D1Q.js} +4 -4
- package/dist/{phantom-wallet-provider-C_LPU6Ns.js.map → phantom-wallet-provider-BOdn0D1Q.js.map} +1 -1
- package/dist/{phantom-wallet-provider-DRvhBbbR.esm.js → phantom-wallet-provider-Dsza6TBv.esm.js} +4 -4
- package/dist/{phantom-wallet-provider-DRvhBbbR.esm.js.map → phantom-wallet-provider-Dsza6TBv.esm.js.map} +1 -1
- package/dist/{privy-wallet-provider-DQM8xO38.js → privy-wallet-provider-BlPh3Gn_.js} +3 -3
- package/dist/{privy-wallet-provider-DQM8xO38.js.map → privy-wallet-provider-BlPh3Gn_.js.map} +1 -1
- package/dist/{privy-wallet-provider-ZGu8q5T5.esm.js → privy-wallet-provider-bwwhkFjL.esm.js} +3 -3
- package/dist/{privy-wallet-provider-ZGu8q5T5.esm.js.map → privy-wallet-provider-bwwhkFjL.esm.js.map} +1 -1
- package/dist/solana-mobile-wallet-provider-S8yWHG6i.js +841 -0
- package/dist/solana-mobile-wallet-provider-S8yWHG6i.js.map +1 -0
- package/dist/solana-mobile-wallet-provider-fzLIgJBf.esm.js +820 -0
- package/dist/solana-mobile-wallet-provider-fzLIgJBf.esm.js.map +1 -0
- package/package.json +2 -1
- package/dist/index-Bp4b5LXs.js.map +0 -1
- package/dist/index-C80kRxWk.esm.js +0 -6
- package/dist/index-C80kRxWk.esm.js.map +0 -1
- package/dist/index.browser-BvNsUWjt.js +0 -105
- package/dist/index.browser-BvNsUWjt.js.map +0 -1
- package/dist/index.browser-BwIqqM4U.js +0 -1099
- package/dist/index.browser-BwIqqM4U.js.map +0 -1
- package/dist/index.browser-C1QL04xM.js.map +0 -1
- package/dist/index.browser-Cgj7Hs6n.esm.js.map +0 -1
- package/dist/index.browser-CifFI7Ju.esm.js +0 -1096
- package/dist/index.browser-CifFI7Ju.esm.js.map +0 -1
- package/dist/index.browser-D8VWPXTZ.esm.js +0 -102
- package/dist/index.browser-D8VWPXTZ.esm.js.map +0 -1
- package/dist/index.browser-OvGNsMPu.esm.js +0 -1002
- package/dist/index.browser-OvGNsMPu.esm.js.map +0 -1
- package/dist/index.browser-vuTr40so.js +0 -1008
- package/dist/index.browser-vuTr40so.js.map +0 -1
- package/dist/solana-mobile-wallet-provider-6gNw2_bX.js +0 -608
- package/dist/solana-mobile-wallet-provider-6gNw2_bX.js.map +0 -1
- package/dist/solana-mobile-wallet-provider-B65A7abd.esm.js +0 -587
- package/dist/solana-mobile-wallet-provider-B65A7abd.esm.js.map +0 -1
|
@@ -12838,10 +12838,10 @@ let currentAuthProvider = null;
|
|
|
12838
12838
|
let currentAuthMethod = null;
|
|
12839
12839
|
let initConfig = null;
|
|
12840
12840
|
// --- localStorage helpers: track which auth method the user last logged in with ---
|
|
12841
|
-
const STORED_AUTH_METHOD_KEY = 'tarobase_last_auth_method';
|
|
12841
|
+
const STORED_AUTH_METHOD_KEY$1 = 'tarobase_last_auth_method';
|
|
12842
12842
|
function getStoredAuthMethod() {
|
|
12843
12843
|
try {
|
|
12844
|
-
return getPlatform().storage.getItem(STORED_AUTH_METHOD_KEY);
|
|
12844
|
+
return getPlatform().storage.getItem(STORED_AUTH_METHOD_KEY$1);
|
|
12845
12845
|
}
|
|
12846
12846
|
catch (_a) {
|
|
12847
12847
|
return null;
|
|
@@ -12850,10 +12850,10 @@ function getStoredAuthMethod() {
|
|
|
12850
12850
|
function setStoredAuthMethod(method) {
|
|
12851
12851
|
try {
|
|
12852
12852
|
if (method) {
|
|
12853
|
-
getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY, method);
|
|
12853
|
+
getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY$1, method);
|
|
12854
12854
|
}
|
|
12855
12855
|
else {
|
|
12856
|
-
getPlatform().storage.removeItem(STORED_AUTH_METHOD_KEY);
|
|
12856
|
+
getPlatform().storage.removeItem(STORED_AUTH_METHOD_KEY$1);
|
|
12857
12857
|
}
|
|
12858
12858
|
}
|
|
12859
12859
|
catch (_a) {
|
|
@@ -15730,7 +15730,7 @@ async function loadDependencies() {
|
|
|
15730
15730
|
const [reactModule, reactDomModule, phantomModule] = await Promise.all([
|
|
15731
15731
|
import('react'),
|
|
15732
15732
|
import('react-dom/client'),
|
|
15733
|
-
Promise.resolve().then(function () { return require('./index-
|
|
15733
|
+
Promise.resolve().then(function () { return require('./index-B1_Q49qQ.js'); })
|
|
15734
15734
|
]);
|
|
15735
15735
|
// Extract default export from ESM module namespace
|
|
15736
15736
|
// Dynamic import() returns { default: Module, ...exports }, not the module directly
|
|
@@ -21299,26 +21299,239 @@ function isMobileWalletAvailable() {
|
|
|
21299
21299
|
return detectAndroid();
|
|
21300
21300
|
}
|
|
21301
21301
|
const ED25519_SIGNATURE_LENGTH = 64;
|
|
21302
|
-
|
|
21303
|
-
|
|
21304
|
-
|
|
21305
|
-
|
|
21306
|
-
|
|
21307
|
-
|
|
21308
|
-
|
|
21309
|
-
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21302
|
+
const STORED_AUTH_METHOD_KEY = 'tarobase_last_auth_method';
|
|
21303
|
+
const MWA_AUTH_METHOD = 'mobile-wallet-adapter';
|
|
21304
|
+
function findMwaError(e, maxDepth = 5) {
|
|
21305
|
+
var _a;
|
|
21306
|
+
let cur = e;
|
|
21307
|
+
let depth = 0;
|
|
21308
|
+
while (cur && depth < maxDepth) {
|
|
21309
|
+
if ((cur === null || cur === void 0 ? void 0 : cur.name) === 'SolanaMobileWalletAdapterError' && typeof (cur === null || cur === void 0 ? void 0 : cur.code) === 'string') {
|
|
21310
|
+
return { code: cur.code, message: String((_a = cur.message) !== null && _a !== void 0 ? _a : '') };
|
|
21311
|
+
}
|
|
21312
|
+
cur = cur === null || cur === void 0 ? void 0 : cur.cause;
|
|
21313
|
+
depth++;
|
|
21314
|
+
}
|
|
21315
|
+
return null;
|
|
21316
|
+
}
|
|
21317
|
+
/**
|
|
21318
|
+
* Returns the matched MwaErrorInfo when the error is from an association
|
|
21319
|
+
* failure that an automatic retry can recover from (i.e. the wallet exists
|
|
21320
|
+
* on-device but the dApp's protocol session didn't complete in time). Returns
|
|
21321
|
+
* null for non-retryable errors (user cancel, unknown wallet errors, etc.).
|
|
21322
|
+
*
|
|
21323
|
+
* Specifically:
|
|
21324
|
+
* - ERROR_WALLET_NOT_FOUND: thrown from the protocol's startScenario when
|
|
21325
|
+
* it gave up waiting for a wallet to respond. On Seeker this races the
|
|
21326
|
+
* first-time-consent UI on the very first authorize.
|
|
21327
|
+
* - ERROR_SESSION_TIMEOUT: similar — the protocol's session-establishment
|
|
21328
|
+
* timer expired.
|
|
21329
|
+
* - ERROR_ASSOCIATION_CANCELLED: shared by user-cancel ("Wallet connection
|
|
21330
|
+
* cancelled by user") AND the 30s wallet-standard WALLET_ASSOCIATION_TIMEOUT
|
|
21331
|
+
* ("Wallet connection timed out"). Discriminate by message — never retry
|
|
21332
|
+
* a user cancel.
|
|
21333
|
+
*/
|
|
21334
|
+
function isMwaAssociationRetryable(e) {
|
|
21335
|
+
const info = findMwaError(e);
|
|
21336
|
+
if (!info)
|
|
21337
|
+
return null;
|
|
21338
|
+
if (info.code === 'ERROR_WALLET_NOT_FOUND')
|
|
21339
|
+
return info;
|
|
21340
|
+
if (info.code === 'ERROR_SESSION_TIMEOUT')
|
|
21341
|
+
return info;
|
|
21342
|
+
if (info.code === 'ERROR_ASSOCIATION_CANCELLED' && /timed out/i.test(info.message))
|
|
21343
|
+
return info;
|
|
21344
|
+
return null;
|
|
21345
|
+
}
|
|
21346
|
+
/**
|
|
21347
|
+
* Single-retry wrapper for MWA association failures. Used ONLY for login's
|
|
21348
|
+
* `standard:connect` and `solana:signMessage` calls — never for
|
|
21349
|
+
* `signAndSendTransaction`/`runTransaction` because retry on a path that
|
|
21350
|
+
* may have already submitted a tx can double-send.
|
|
21351
|
+
*
|
|
21352
|
+
* The retry exists for one specific scenario: on first-time MWA usage from a
|
|
21353
|
+
* given origin on Seeker, the protocol's session-establishment timer races
|
|
21354
|
+
* Seeker's first-time consent UI. The user reads the consent sheet, taps
|
|
21355
|
+
* Connect — but by then the protocol has given up and thrown
|
|
21356
|
+
* ERROR_WALLET_NOT_FOUND. The consent itself IS persisted on Seeker though,
|
|
21357
|
+
* so a second attempt skips the consent sheet, jumps straight to
|
|
21358
|
+
* Verify/Approve, and completes inside the timeout.
|
|
21359
|
+
*/
|
|
21360
|
+
async function withMwaAssociationRetry(label, fn) {
|
|
21361
|
+
const t0 = Date.now();
|
|
21362
|
+
console.log(`[MWA-DEBUG] ${label} attempt=1 start`);
|
|
21363
|
+
try {
|
|
21364
|
+
const result = await fn();
|
|
21365
|
+
console.log(`[MWA-DEBUG] ${label} attempt=1 ok (${Date.now() - t0}ms)`);
|
|
21366
|
+
return result;
|
|
21367
|
+
}
|
|
21368
|
+
catch (e) {
|
|
21369
|
+
const info = findMwaError(e);
|
|
21370
|
+
console.log(`[MWA-DEBUG] ${label} attempt=1 err (${Date.now() - t0}ms)`, {
|
|
21371
|
+
outer: { name: e === null || e === void 0 ? void 0 : e.name, message: e === null || e === void 0 ? void 0 : e.message },
|
|
21372
|
+
mwa: info,
|
|
21373
|
+
});
|
|
21374
|
+
const retryable = isMwaAssociationRetryable(e);
|
|
21375
|
+
if (!retryable)
|
|
21376
|
+
throw e;
|
|
21377
|
+
// Seeker's consent sheet is a bottom-sheet overlay — Chrome doesn't
|
|
21378
|
+
// reliably flip document.visibilityState to 'hidden' while it's open,
|
|
21379
|
+
// so visibility-based waits fire too early. Use a fixed delay long
|
|
21380
|
+
// enough for Seeker to dismiss its sheet and the OS to release intent
|
|
21381
|
+
// state. 2.5s is empirically safe; tune from device traces if needed.
|
|
21382
|
+
console.log(`[MWA-DEBUG] ${label} retryable (${retryable.code}); waiting 2500ms before retry`);
|
|
21383
|
+
await new Promise(r => setTimeout(r, 2500));
|
|
21384
|
+
const t1 = Date.now();
|
|
21385
|
+
console.log(`[MWA-DEBUG] ${label} attempt=2 start`);
|
|
21313
21386
|
try {
|
|
21314
|
-
|
|
21387
|
+
const result = await fn();
|
|
21388
|
+
console.log(`[MWA-DEBUG] ${label} attempt=2 ok (${Date.now() - t1}ms)`);
|
|
21389
|
+
return result;
|
|
21315
21390
|
}
|
|
21316
|
-
catch (
|
|
21317
|
-
|
|
21318
|
-
|
|
21391
|
+
catch (e2) {
|
|
21392
|
+
const info2 = findMwaError(e2);
|
|
21393
|
+
console.log(`[MWA-DEBUG] ${label} attempt=2 err (${Date.now() - t1}ms)`, {
|
|
21394
|
+
outer: { name: e2 === null || e2 === void 0 ? void 0 : e2.name, message: e2 === null || e2 === void 0 ? void 0 : e2.message },
|
|
21395
|
+
mwa: info2,
|
|
21396
|
+
});
|
|
21397
|
+
// Only mask the error with the clean Seeker message when the
|
|
21398
|
+
// second failure is also an association-flavored error. If it's
|
|
21399
|
+
// a user cancel, wallet rejection, or unknown error, rethrow
|
|
21400
|
+
// the original so the host app surfaces the real cause.
|
|
21401
|
+
if (isMwaAssociationRetryable(e2)) {
|
|
21402
|
+
throw new Error("Couldn't connect to your Seeker wallet. Please try again.");
|
|
21403
|
+
}
|
|
21404
|
+
throw e2;
|
|
21319
21405
|
}
|
|
21320
|
-
}
|
|
21321
|
-
|
|
21406
|
+
}
|
|
21407
|
+
}
|
|
21408
|
+
/**
|
|
21409
|
+
* Normalize a chain string to a wallet-standard Solana chain identifier.
|
|
21410
|
+
*
|
|
21411
|
+
* Handles three input shapes that all show up in practice:
|
|
21412
|
+
* - Bare cluster name from `SolanaMobileWalletConfig.cluster` (e.g. 'devnet').
|
|
21413
|
+
* - Prefixed `solana:cluster` (e.g. 'solana:devnet').
|
|
21414
|
+
* - Double-prefixed `solana:solana:cluster` (constructor used to wrap cluster
|
|
21415
|
+
* with `solana:` blindly; if a caller already passed a prefixed string the
|
|
21416
|
+
* result was `solana:solana:devnet`).
|
|
21417
|
+
*
|
|
21418
|
+
* Wallet-standard Solana chains are exactly:
|
|
21419
|
+
* 'solana:mainnet' | 'solana:devnet' | 'solana:testnet' | 'solana:localnet'
|
|
21420
|
+
* — `mainnet-beta` is NOT a valid wallet-standard identifier and must be
|
|
21421
|
+
* normalized to `solana:mainnet`.
|
|
21422
|
+
*/
|
|
21423
|
+
function mapChainToWalletStandard(input) {
|
|
21424
|
+
if (!input)
|
|
21425
|
+
return 'solana:mainnet';
|
|
21426
|
+
let s = String(input).toLowerCase();
|
|
21427
|
+
while (s.startsWith('solana:'))
|
|
21428
|
+
s = s.slice('solana:'.length);
|
|
21429
|
+
if (s === 'mainnet-beta' || s === 'mainnet')
|
|
21430
|
+
return 'solana:mainnet';
|
|
21431
|
+
if (s === 'devnet')
|
|
21432
|
+
return 'solana:devnet';
|
|
21433
|
+
if (s === 'testnet')
|
|
21434
|
+
return 'solana:testnet';
|
|
21435
|
+
if (s === 'localnet')
|
|
21436
|
+
return 'solana:localnet';
|
|
21437
|
+
return 'solana:mainnet';
|
|
21438
|
+
}
|
|
21439
|
+
/**
|
|
21440
|
+
* Serialize a Transaction/VersionedTransaction to a Uint8Array wire payload
|
|
21441
|
+
* that the wallet-standard `solana:signTransaction` /
|
|
21442
|
+
* `solana:signAndSendTransaction` features expect.
|
|
21443
|
+
*
|
|
21444
|
+
* Legacy transactions must serialize with `requireAllSignatures: false` and
|
|
21445
|
+
* `verifySignatures: false` — the wallet hasn't signed yet, and the default
|
|
21446
|
+
* `serialize()` would throw "Signature verification failed". Versioned
|
|
21447
|
+
* transactions use the default `serialize()` which already permits unsigned
|
|
21448
|
+
* payloads. Mirrors the helper at
|
|
21449
|
+
* `@solana-mobile/mobile-wallet-adapter-protocol-web3js/lib/esm/index.browser.js:13-18`.
|
|
21450
|
+
*/
|
|
21451
|
+
function txToWireBytes(tx) {
|
|
21452
|
+
if ('version' in tx)
|
|
21453
|
+
return tx.serialize();
|
|
21454
|
+
return tx.serialize({ requireAllSignatures: false, verifySignatures: false });
|
|
21455
|
+
}
|
|
21456
|
+
/**
|
|
21457
|
+
* Deserialize a wire-format transaction returned by the wallet
|
|
21458
|
+
* `solana:signTransaction` feature. Mirrors the helper at
|
|
21459
|
+
* `@solana-mobile/mobile-wallet-adapter-protocol-web3js/lib/esm/index.browser.js:19-23`
|
|
21460
|
+
* so legacy and versioned bytes both round-trip correctly.
|
|
21461
|
+
*/
|
|
21462
|
+
function txFromWireBytes(byteArray) {
|
|
21463
|
+
const messageOffset = byteArray[0] * ED25519_SIGNATURE_LENGTH + 1;
|
|
21464
|
+
const messageVersion = web3_js.VersionedMessage.deserializeMessageVersion(byteArray.slice(messageOffset, byteArray.length));
|
|
21465
|
+
if (messageVersion === 'legacy') {
|
|
21466
|
+
return web3_js.Transaction.from(byteArray);
|
|
21467
|
+
}
|
|
21468
|
+
return web3_js.VersionedTransaction.deserialize(byteArray);
|
|
21469
|
+
}
|
|
21470
|
+
/**
|
|
21471
|
+
* Per-method runtime narrowing of wallet-standard features. The wallet's
|
|
21472
|
+
* `.features` type is a union (`signAndSendTransaction` | `signTransaction`),
|
|
21473
|
+
* and after authorization the wallet may also narrow `#optionalFeatures`
|
|
21474
|
+
* based on actual wallet capabilities. Narrow at the call site so a method
|
|
21475
|
+
* that needs only `signMessage` doesn't fail when a wallet lacks
|
|
21476
|
+
* `signTransaction`.
|
|
21477
|
+
*/
|
|
21478
|
+
function getSignMessageFeature(wallet) {
|
|
21479
|
+
const f = wallet.features;
|
|
21480
|
+
const feat = f['solana:signMessage'];
|
|
21481
|
+
if (!feat || typeof feat.signMessage !== 'function') {
|
|
21482
|
+
throw new Error('Wallet does not support solana:signMessage');
|
|
21483
|
+
}
|
|
21484
|
+
return feat;
|
|
21485
|
+
}
|
|
21486
|
+
function getSignTransactionFeature(wallet) {
|
|
21487
|
+
const f = wallet.features;
|
|
21488
|
+
const feat = f['solana:signTransaction'];
|
|
21489
|
+
if (!feat || typeof feat.signTransaction !== 'function') {
|
|
21490
|
+
throw new Error('Wallet does not support solana:signTransaction');
|
|
21491
|
+
}
|
|
21492
|
+
return feat;
|
|
21493
|
+
}
|
|
21494
|
+
function getSignAndSendTransactionFeature(wallet) {
|
|
21495
|
+
const f = wallet.features;
|
|
21496
|
+
const feat = f['solana:signAndSendTransaction'];
|
|
21497
|
+
if (!feat || typeof feat.signAndSendTransaction !== 'function') {
|
|
21498
|
+
throw new Error('Wallet does not support solana:signAndSendTransaction');
|
|
21499
|
+
}
|
|
21500
|
+
return feat;
|
|
21501
|
+
}
|
|
21502
|
+
function getConnectFeature(wallet) {
|
|
21503
|
+
const f = wallet.features;
|
|
21504
|
+
const feat = f['standard:connect'];
|
|
21505
|
+
if (!feat || typeof feat.connect !== 'function') {
|
|
21506
|
+
throw new Error('Wallet does not support standard:connect');
|
|
21507
|
+
}
|
|
21508
|
+
return feat;
|
|
21509
|
+
}
|
|
21510
|
+
function getDisconnectFeature(wallet) {
|
|
21511
|
+
const f = wallet.features;
|
|
21512
|
+
const feat = f['standard:disconnect'];
|
|
21513
|
+
return feat && typeof feat.disconnect === 'function' ? feat : null;
|
|
21514
|
+
}
|
|
21515
|
+
function writeAuthMethod(method) {
|
|
21516
|
+
try {
|
|
21517
|
+
if (method === null) {
|
|
21518
|
+
getPlatform().storage.removeItem(STORED_AUTH_METHOD_KEY);
|
|
21519
|
+
}
|
|
21520
|
+
else {
|
|
21521
|
+
getPlatform().storage.setItem(STORED_AUTH_METHOD_KEY, method);
|
|
21522
|
+
}
|
|
21523
|
+
}
|
|
21524
|
+
catch (_a) {
|
|
21525
|
+
// storage may be unavailable
|
|
21526
|
+
}
|
|
21527
|
+
}
|
|
21528
|
+
function readAuthMethod() {
|
|
21529
|
+
try {
|
|
21530
|
+
return getPlatform().storage.getItem(STORED_AUTH_METHOD_KEY);
|
|
21531
|
+
}
|
|
21532
|
+
catch (_a) {
|
|
21533
|
+
return null;
|
|
21534
|
+
}
|
|
21322
21535
|
}
|
|
21323
21536
|
/**
|
|
21324
21537
|
* Registers Mobile Wallet Adapter as a wallet-standard wallet so it appears
|
|
@@ -21329,11 +21542,11 @@ async function loadMwaProtocol() {
|
|
|
21329
21542
|
* @param config - App identity and optional remote host authority for desktop QR code support
|
|
21330
21543
|
*/
|
|
21331
21544
|
async function registerMobileWalletAdapter(config) {
|
|
21332
|
-
var _a;
|
|
21545
|
+
var _a, _b;
|
|
21333
21546
|
if (typeof window === 'undefined')
|
|
21334
21547
|
return;
|
|
21335
21548
|
try {
|
|
21336
|
-
const walletStandardMobile = await Promise.resolve().then(function () { return require('./index.browser-
|
|
21549
|
+
const walletStandardMobile = await Promise.resolve().then(function () { return require('./index.browser-BJmFjY2f.js'); });
|
|
21337
21550
|
const registerMwa = walletStandardMobile.registerMwa || ((_a = walletStandardMobile.default) === null || _a === void 0 ? void 0 : _a.registerMwa);
|
|
21338
21551
|
if (!registerMwa) {
|
|
21339
21552
|
console.warn('[SolanaMobileWallet] registerMwa not found in @solana-mobile/wallet-standard-mobile');
|
|
@@ -21356,38 +21569,50 @@ async function registerMobileWalletAdapter(config) {
|
|
|
21356
21569
|
if (walletStandardMobile.createDefaultChainSelector) {
|
|
21357
21570
|
options.chainSelector = walletStandardMobile.createDefaultChainSelector();
|
|
21358
21571
|
}
|
|
21359
|
-
|
|
21360
|
-
|
|
21361
|
-
|
|
21572
|
+
// Default: suppress the "We can't find a wallet" modal — see
|
|
21573
|
+
// SolanaMobileWalletProvider.ensureWallet() for why. Consumers that
|
|
21574
|
+
// want their own UX can pass config.onWalletNotFound.
|
|
21575
|
+
options.onWalletNotFound = (_b = config === null || config === void 0 ? void 0 : config.onWalletNotFound) !== null && _b !== void 0 ? _b : (async () => {
|
|
21576
|
+
console.warn('[MWA-DEBUG] registerMobileWalletAdapter onWalletNotFound (suppressed)');
|
|
21577
|
+
});
|
|
21362
21578
|
registerMwa(options);
|
|
21363
21579
|
}
|
|
21364
21580
|
catch (e) {
|
|
21365
|
-
// @solana-mobile/wallet-standard-mobile is an optional dependency
|
|
21366
|
-
// Silently skip if not installed — the provider still works via
|
|
21367
|
-
// @solana-mobile/mobile-wallet-adapter-protocol-web3js directly
|
|
21368
21581
|
console.debug('[SolanaMobileWallet] @solana-mobile/wallet-standard-mobile not available, skipping wallet-standard registration');
|
|
21369
21582
|
}
|
|
21370
21583
|
}
|
|
21371
21584
|
/**
|
|
21372
|
-
* SolanaMobileWalletProvider implements the AuthProvider interface using
|
|
21373
|
-
* Solana Mobile
|
|
21585
|
+
* SolanaMobileWalletProvider implements the AuthProvider interface using
|
|
21586
|
+
* Solana Mobile's wallet-standard wrapper (`LocalSolanaMobileWalletAdapterWallet`).
|
|
21587
|
+
*
|
|
21588
|
+
* Why wallet-standard and not the raw MWA protocol: as of
|
|
21589
|
+
* `@solana-mobile/wallet-standard-mobile@0.5.0+`, the wallet's internal
|
|
21590
|
+
* `#transact` calls `checkLocalNetworkAccessPermission()` before opening the
|
|
21591
|
+
* localhost WebSocket. That helper renders a three-stage UX flow Solana
|
|
21592
|
+
* Mobile designed specifically to defuse Chrome's Local Network Access
|
|
21593
|
+
* permission dialog (which renders with disabled buttons on Android Chrome,
|
|
21594
|
+
* the source of the long-running Seeker MWA bug):
|
|
21595
|
+
*
|
|
21596
|
+
* 1. "Allow connections to your wallet" informational modal.
|
|
21597
|
+
* 2. Chrome's permission prompt (interactive because it's spawned as a
|
|
21598
|
+
* fresh user gesture from step 1).
|
|
21599
|
+
* 3. "Ready to connect!" success modal.
|
|
21374
21600
|
*
|
|
21375
|
-
*
|
|
21376
|
-
*
|
|
21377
|
-
*
|
|
21601
|
+
* `checkLocalNetworkAccessPermission` is internal to the library — it's not
|
|
21602
|
+
* exported. The only way to invoke it is to go through the wallet's
|
|
21603
|
+
* `standard:connect` / `solana:sign*` features, which is what this provider
|
|
21604
|
+
* does.
|
|
21378
21605
|
*
|
|
21379
|
-
*
|
|
21380
|
-
*
|
|
21381
|
-
*
|
|
21606
|
+
* Notes on UX: login uses two wallet popups in succession — `standard:connect`
|
|
21607
|
+
* (authorize) and `solana:signMessage` (sign the Tarobase nonce). The
|
|
21608
|
+
* previous implementation combined both inside a single `transact` callback;
|
|
21609
|
+
* splitting them is the cost of going through wallet-standard, and is
|
|
21610
|
+
* acceptable given the alternative was broken on Seeker.
|
|
21382
21611
|
*/
|
|
21383
21612
|
class SolanaMobileWalletProvider {
|
|
21384
21613
|
constructor(networkUrl = null, config = {}) {
|
|
21385
|
-
|
|
21386
|
-
this.
|
|
21387
|
-
this.walletUriBase = null;
|
|
21388
|
-
this.base64Address = null;
|
|
21389
|
-
this.authorizedPublicKey = null;
|
|
21390
|
-
this.publicKeyObj = null;
|
|
21614
|
+
/** LocalSolanaMobileWalletAdapterWallet, lazy-constructed in ensureWallet(). */
|
|
21615
|
+
this.wallet = null;
|
|
21391
21616
|
this.networkUrl = networkUrl;
|
|
21392
21617
|
this.config = config;
|
|
21393
21618
|
if (typeof window === 'undefined') {
|
|
@@ -21400,7 +21625,7 @@ class SolanaMobileWalletProvider {
|
|
|
21400
21625
|
name: 'TaroBase App',
|
|
21401
21626
|
uri: getPlatform().getLocationOrigin(),
|
|
21402
21627
|
};
|
|
21403
|
-
this.
|
|
21628
|
+
this.cluster = config.cluster || 'mainnet-beta';
|
|
21404
21629
|
SolanaMobileWalletProvider.instance = this;
|
|
21405
21630
|
}
|
|
21406
21631
|
static getInstance(networkUrl, config) {
|
|
@@ -21409,154 +21634,136 @@ class SolanaMobileWalletProvider {
|
|
|
21409
21634
|
}
|
|
21410
21635
|
return SolanaMobileWalletProvider.instance;
|
|
21411
21636
|
}
|
|
21412
|
-
/**
|
|
21413
|
-
|
|
21414
|
-
if (this.
|
|
21415
|
-
return
|
|
21416
|
-
}
|
|
21417
|
-
|
|
21637
|
+
/** Lazy-construct LocalSolanaMobileWalletAdapterWallet on first need. */
|
|
21638
|
+
async ensureWallet() {
|
|
21639
|
+
if (this.wallet)
|
|
21640
|
+
return this.wallet;
|
|
21641
|
+
const mod = await Promise.resolve().then(function () { return require('./index.browser-BJmFjY2f.js'); });
|
|
21642
|
+
const chain = mapChainToWalletStandard(this.cluster);
|
|
21643
|
+
this.wallet = new mod.LocalSolanaMobileWalletAdapterWallet({
|
|
21644
|
+
appIdentity: this.appIdentity,
|
|
21645
|
+
authorizationCache: mod.createDefaultAuthorizationCache(),
|
|
21646
|
+
chains: [chain],
|
|
21647
|
+
chainSelector: mod.createDefaultChainSelector(),
|
|
21648
|
+
// Suppress the default "We can't find a wallet" modal — that
|
|
21649
|
+
// modal is misleading when ERROR_WALLET_NOT_FOUND fires during
|
|
21650
|
+
// a first-time-consent race on Seeker (the wallet IS installed,
|
|
21651
|
+
// the protocol just gave up before the user finished consenting).
|
|
21652
|
+
// login()'s withMwaAssociationRetry handles this case; on second
|
|
21653
|
+
// failure it surfaces a clean error message to the host app.
|
|
21654
|
+
onWalletNotFound: async () => {
|
|
21655
|
+
console.warn('[MWA-DEBUG] ensureWallet onWalletNotFound (suppressed)');
|
|
21656
|
+
},
|
|
21657
|
+
});
|
|
21658
|
+
return this.wallet;
|
|
21418
21659
|
}
|
|
21419
|
-
/**
|
|
21420
|
-
|
|
21421
|
-
|
|
21422
|
-
|
|
21423
|
-
|
|
21424
|
-
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21660
|
+
/**
|
|
21661
|
+
* Ensure the wallet has an active authorization. After a Tarobase session
|
|
21662
|
+
* is restored from storage on cold-start, `wallet.accounts` is empty until
|
|
21663
|
+
* we silently reconnect from the AuthorizationCache. If the cache is also
|
|
21664
|
+
* empty, fall back to interactive `login()` (which surfaces the three-stage
|
|
21665
|
+
* Solana Mobile LNA flow + wallet popups).
|
|
21666
|
+
*
|
|
21667
|
+
* Returns the wallet-standard `WalletAccount` to use for sign operations.
|
|
21668
|
+
*/
|
|
21669
|
+
async ensureAuthorized() {
|
|
21670
|
+
const wallet = await this.ensureWallet();
|
|
21671
|
+
if (wallet.accounts.length === 0) {
|
|
21672
|
+
try {
|
|
21673
|
+
const connectFeat = getConnectFeature(wallet);
|
|
21674
|
+
await connectFeat.connect({ silent: true });
|
|
21675
|
+
}
|
|
21676
|
+
catch (e) {
|
|
21677
|
+
console.warn('[SolanaMobileWallet] silent connect failed:', e === null || e === void 0 ? void 0 : e.message);
|
|
21678
|
+
}
|
|
21429
21679
|
}
|
|
21430
|
-
|
|
21431
|
-
const
|
|
21432
|
-
|
|
21433
|
-
|
|
21434
|
-
});
|
|
21435
|
-
this.storeAuthResult(authResult);
|
|
21436
|
-
return authResult;
|
|
21437
|
-
}
|
|
21438
|
-
catch (e) {
|
|
21439
|
-
// Reauth failed (token expired, wallet reset, etc.) — try fresh authorize
|
|
21440
|
-
console.warn('[SolanaMobileWallet] Reauthorization failed, attempting fresh authorize:', e === null || e === void 0 ? void 0 : e.message);
|
|
21441
|
-
const authResult = await wallet.authorize({
|
|
21442
|
-
identity: this.appIdentity,
|
|
21443
|
-
chain: this.chain,
|
|
21444
|
-
});
|
|
21445
|
-
this.storeAuthResult(authResult);
|
|
21446
|
-
return authResult;
|
|
21680
|
+
if (wallet.accounts.length === 0) {
|
|
21681
|
+
const user = await this.login();
|
|
21682
|
+
if (!user)
|
|
21683
|
+
throw new Error('MWA not connected');
|
|
21447
21684
|
}
|
|
21685
|
+
return wallet.accounts[0];
|
|
21448
21686
|
}
|
|
21449
|
-
/**
|
|
21450
|
-
|
|
21451
|
-
|
|
21452
|
-
this.authToken = authResult.auth_token;
|
|
21453
|
-
this.walletUriBase = authResult.wallet_uri_base;
|
|
21454
|
-
if (((_a = authResult.accounts) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
21455
|
-
const account = authResult.accounts[0];
|
|
21456
|
-
this.base64Address = account.address;
|
|
21457
|
-
// Decode base64 address → PublicKey → base58
|
|
21458
|
-
const addressBytes = Uint8Array.from(getPlatform().atob(account.address), c => c.charCodeAt(0));
|
|
21459
|
-
this.publicKeyObj = new web3_js.PublicKey(addressBytes);
|
|
21460
|
-
this.authorizedPublicKey = this.publicKeyObj.toBase58();
|
|
21461
|
-
}
|
|
21687
|
+
/** Returns the active wallet-standard chain identifier (e.g. 'solana:mainnet'). */
|
|
21688
|
+
getChain() {
|
|
21689
|
+
return mapChainToWalletStandard(this.cluster);
|
|
21462
21690
|
}
|
|
21463
21691
|
async login() {
|
|
21464
21692
|
var _a, _b, _c, _d, _e;
|
|
21465
21693
|
setAuthLoading(true);
|
|
21466
|
-
// Mark the auth method early so a concurrent Phantom auto-create
|
|
21467
|
-
// 'mobile-wallet-adapter'
|
|
21468
|
-
// roundtrip and
|
|
21469
|
-
//
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
prevAuthMethod = getPlatform().storage.getItem('tarobase_last_auth_method');
|
|
21473
|
-
}
|
|
21474
|
-
catch (_f) { }
|
|
21475
|
-
try {
|
|
21476
|
-
getPlatform().storage.setItem('tarobase_last_auth_method', 'mobile-wallet-adapter');
|
|
21477
|
-
}
|
|
21478
|
-
catch (_g) { }
|
|
21694
|
+
// Mark the auth method early so a concurrent Phantom auto-create-session
|
|
21695
|
+
// effect (see phantom-wallet-provider) sees 'mobile-wallet-adapter'
|
|
21696
|
+
// during our slow connect/sign roundtrip and backs off. Capture the
|
|
21697
|
+
// previous value so we can restore it if login fails.
|
|
21698
|
+
const prevAuthMethod = readAuthMethod();
|
|
21699
|
+
writeAuthMethod(MWA_AUTH_METHOD);
|
|
21479
21700
|
try {
|
|
21480
|
-
await
|
|
21481
|
-
|
|
21482
|
-
//
|
|
21483
|
-
|
|
21701
|
+
const wallet = await this.ensureWallet();
|
|
21702
|
+
// Quick-check: wallet may already have authorization (e.g. from a
|
|
21703
|
+
// previous in-page login) and a matching Tarobase session — skip
|
|
21704
|
+
// popups in that case.
|
|
21705
|
+
if (wallet.accounts.length > 0) {
|
|
21706
|
+
const accountPubkey = new web3_js.PublicKey(wallet.accounts[0].publicKey);
|
|
21707
|
+
const base58Addr = accountPubkey.toBase58();
|
|
21484
21708
|
const existingSession = await WebSessionManager.getSession();
|
|
21485
|
-
if (existingSession && existingSession.address ===
|
|
21486
|
-
const user = { provider: this, address:
|
|
21709
|
+
if (existingSession && existingSession.address === base58Addr) {
|
|
21710
|
+
const user = { provider: this, address: base58Addr };
|
|
21487
21711
|
setCurrentUser(user);
|
|
21488
21712
|
return user;
|
|
21489
21713
|
}
|
|
21490
21714
|
}
|
|
21491
|
-
// Pre-fetch nonce
|
|
21715
|
+
// Pre-fetch nonce while the wallet popup is not yet open.
|
|
21492
21716
|
const nonce = await genAuthNonce();
|
|
21493
|
-
//
|
|
21494
|
-
|
|
21495
|
-
|
|
21496
|
-
|
|
21497
|
-
|
|
21498
|
-
|
|
21499
|
-
|
|
21500
|
-
|
|
21501
|
-
|
|
21502
|
-
|
|
21503
|
-
|
|
21504
|
-
|
|
21505
|
-
|
|
21506
|
-
|
|
21507
|
-
|
|
21508
|
-
|
|
21509
|
-
|
|
21510
|
-
|
|
21511
|
-
|
|
21512
|
-
|
|
21513
|
-
const signatureBytes = signedPayload.slice(-ED25519_SIGNATURE_LENGTH);
|
|
21514
|
-
return {
|
|
21515
|
-
base58Address: base58Addr,
|
|
21516
|
-
base64Address: base64Addr,
|
|
21517
|
-
publicKey: pubkey,
|
|
21518
|
-
signature: bufferExports.Buffer.from(signatureBytes).toString('base64'),
|
|
21519
|
-
messageText,
|
|
21520
|
-
authToken: authResult.auth_token,
|
|
21521
|
-
walletUriBase: authResult.wallet_uri_base,
|
|
21522
|
-
};
|
|
21523
|
-
}, this.getAssociationConfig());
|
|
21524
|
-
// Store MWA auth state for reauthorization in subsequent transact() calls
|
|
21525
|
-
this.authToken = result.authToken;
|
|
21526
|
-
this.walletUriBase = result.walletUriBase;
|
|
21527
|
-
this.base64Address = result.base64Address;
|
|
21528
|
-
this.authorizedPublicKey = result.base58Address;
|
|
21529
|
-
this.publicKeyObj = result.publicKey;
|
|
21530
|
-
// Check if we already have a valid session for this address
|
|
21717
|
+
// Wallet popup #1: standard:connect performs MWA authorize. This
|
|
21718
|
+
// is where wallet-standard's checkLocalNetworkAccessPermission()
|
|
21719
|
+
// fires the three-stage LNA UX (info modal → permission prompt →
|
|
21720
|
+
// success modal) before opening the localhost WebSocket.
|
|
21721
|
+
//
|
|
21722
|
+
// Wrap with single-retry: on a Seeker origin's first MWA usage,
|
|
21723
|
+
// the protocol's session-establishment timer often races Seeker's
|
|
21724
|
+
// first-time consent UI and throws ERROR_WALLET_NOT_FOUND before
|
|
21725
|
+
// the user finishes tapping. The retry hits Seeker's cached
|
|
21726
|
+
// consent on the second pass and completes quickly. See
|
|
21727
|
+
// withMwaAssociationRetry for details.
|
|
21728
|
+
const connectFeat = getConnectFeature(wallet);
|
|
21729
|
+
const { accounts } = await withMwaAssociationRetry('login:connect', () => connectFeat.connect());
|
|
21730
|
+
if (!accounts || accounts.length === 0) {
|
|
21731
|
+
throw new Error('MWA returned no accounts');
|
|
21732
|
+
}
|
|
21733
|
+
const account = accounts[0];
|
|
21734
|
+
const accountPubkey = new web3_js.PublicKey(account.publicKey);
|
|
21735
|
+
const base58Addr = accountPubkey.toBase58();
|
|
21736
|
+
// If we happen to already have a matching Tarobase session, reuse it.
|
|
21531
21737
|
const existingSession = await WebSessionManager.getSession();
|
|
21532
|
-
if (existingSession && existingSession.address ===
|
|
21533
|
-
const user = { provider: this, address:
|
|
21738
|
+
if (existingSession && existingSession.address === base58Addr) {
|
|
21739
|
+
const user = { provider: this, address: base58Addr };
|
|
21534
21740
|
setCurrentUser(user);
|
|
21535
21741
|
return user;
|
|
21536
21742
|
}
|
|
21537
|
-
//
|
|
21538
|
-
|
|
21539
|
-
|
|
21540
|
-
//
|
|
21541
|
-
|
|
21542
|
-
|
|
21743
|
+
// Wallet popup #2: sign the Tarobase nonce message. Wrap with the
|
|
21744
|
+
// same retry for defense in depth — by now Seeker has cached the
|
|
21745
|
+
// consent so this rarely hits the retry path, but if the
|
|
21746
|
+
// protocol's session timer fires here too we recover transparently.
|
|
21747
|
+
const messageText = await genSolanaMessage(base58Addr, nonce);
|
|
21748
|
+
const messageBytes = getPlatform().textEncode(messageText);
|
|
21749
|
+
const signMessageFeat = getSignMessageFeature(wallet);
|
|
21750
|
+
const signResults = await withMwaAssociationRetry('login:signMessage', () => signMessageFeat.signMessage({ account, message: messageBytes }));
|
|
21751
|
+
if (!signResults || signResults.length === 0) {
|
|
21752
|
+
throw new Error('MWA returned no signature');
|
|
21543
21753
|
}
|
|
21544
|
-
|
|
21545
|
-
const
|
|
21754
|
+
const { signature: sigBytes } = signResults[0];
|
|
21755
|
+
const signatureBase64 = bufferExports.Buffer.from(sigBytes).toString('base64');
|
|
21756
|
+
// Create Tarobase session on the server.
|
|
21757
|
+
const createSessionResult = await createSessionWithSignature(base58Addr, messageText, signatureBase64);
|
|
21758
|
+
await WebSessionManager.storeSession(base58Addr, createSessionResult.accessToken, createSessionResult.idToken, createSessionResult.refreshToken);
|
|
21759
|
+
// Auth-method marker is already 'mobile-wallet-adapter' from above.
|
|
21760
|
+
const user = { provider: this, address: base58Addr };
|
|
21546
21761
|
setCurrentUser(user);
|
|
21547
21762
|
return user;
|
|
21548
21763
|
}
|
|
21549
21764
|
catch (error) {
|
|
21550
|
-
// Restore the previous auth
|
|
21551
|
-
|
|
21552
|
-
if (prevAuthMethod === null) {
|
|
21553
|
-
getPlatform().storage.removeItem('tarobase_last_auth_method');
|
|
21554
|
-
}
|
|
21555
|
-
else {
|
|
21556
|
-
getPlatform().storage.setItem('tarobase_last_auth_method', prevAuthMethod);
|
|
21557
|
-
}
|
|
21558
|
-
}
|
|
21559
|
-
catch (_j) { }
|
|
21765
|
+
// Restore the previous auth-method marker since this login attempt failed.
|
|
21766
|
+
writeAuthMethod(prevAuthMethod);
|
|
21560
21767
|
const isUserRejection = (error === null || error === void 0 ? void 0 : error.code) === 4001 ||
|
|
21561
21768
|
((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes('user rejected')) ||
|
|
21562
21769
|
((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes('user denied')) ||
|
|
@@ -21575,61 +21782,42 @@ class SolanaMobileWalletProvider {
|
|
|
21575
21782
|
async restoreSession() {
|
|
21576
21783
|
const session = await WebSessionManager.getSession();
|
|
21577
21784
|
if (session) {
|
|
21578
|
-
this.authorizedPublicKey = session.address;
|
|
21579
|
-
this.publicKeyObj = new web3_js.PublicKey(session.address);
|
|
21580
21785
|
return { provider: this, address: session.address };
|
|
21581
21786
|
}
|
|
21582
21787
|
return null;
|
|
21583
21788
|
}
|
|
21584
21789
|
async logout() {
|
|
21585
|
-
|
|
21586
|
-
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
await
|
|
21592
|
-
await wallet.deauthorize({ auth_token: authToken });
|
|
21593
|
-
}, this.getAssociationConfig());
|
|
21594
|
-
}
|
|
21595
|
-
catch (error) {
|
|
21596
|
-
console.error('[SolanaMobileWallet] Deauthorize error:', error);
|
|
21790
|
+
try {
|
|
21791
|
+
const wallet = await this.ensureWallet();
|
|
21792
|
+
const disconnectFeat = getDisconnectFeature(wallet);
|
|
21793
|
+
if (disconnectFeat) {
|
|
21794
|
+
// Disconnect clears the AuthorizationCache and resets
|
|
21795
|
+
// wallet.#authorization internally (no LNA dialog).
|
|
21796
|
+
await disconnectFeat.disconnect();
|
|
21597
21797
|
}
|
|
21598
21798
|
}
|
|
21599
|
-
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
this.authorizedPublicKey = null;
|
|
21603
|
-
this.publicKeyObj = null;
|
|
21799
|
+
catch (error) {
|
|
21800
|
+
console.error('[SolanaMobileWallet] Disconnect error:', error);
|
|
21801
|
+
}
|
|
21604
21802
|
WebSessionManager.clearSession();
|
|
21605
21803
|
// Clear the auth-method marker so Phantom auto-create is unblocked
|
|
21606
21804
|
// for any subsequent fresh login on this device.
|
|
21607
|
-
|
|
21608
|
-
getPlatform().storage.removeItem('tarobase_last_auth_method');
|
|
21609
|
-
}
|
|
21610
|
-
catch (_a) { }
|
|
21805
|
+
writeAuthMethod(null);
|
|
21611
21806
|
setCurrentUser(null);
|
|
21612
21807
|
}
|
|
21613
21808
|
async signMessage(message) {
|
|
21614
21809
|
var _a, _b;
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
}
|
|
21618
|
-
await loadMwaProtocol();
|
|
21619
|
-
const { transact } = mwaProtocolModule;
|
|
21620
|
-
const base64Addr = this.base64Address;
|
|
21810
|
+
const account = await this.ensureAuthorized();
|
|
21811
|
+
const wallet = await this.ensureWallet();
|
|
21621
21812
|
try {
|
|
21622
|
-
const
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
const signedPayload = signedMessages[0];
|
|
21631
|
-
const signatureBytes = signedPayload.slice(-ED25519_SIGNATURE_LENGTH);
|
|
21632
|
-
return bufferExports.Buffer.from(signatureBytes).toString('base64');
|
|
21813
|
+
const signMessageFeat = getSignMessageFeature(wallet);
|
|
21814
|
+
const messageBytes = getPlatform().textEncode(message);
|
|
21815
|
+
const results = await signMessageFeat.signMessage({ account, message: messageBytes });
|
|
21816
|
+
if (!results || results.length === 0) {
|
|
21817
|
+
throw new Error('MWA returned no signature');
|
|
21818
|
+
}
|
|
21819
|
+
const { signature: sigBytes } = results[0];
|
|
21820
|
+
return bufferExports.Buffer.from(sigBytes).toString('base64');
|
|
21633
21821
|
}
|
|
21634
21822
|
catch (error) {
|
|
21635
21823
|
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
|
|
@@ -21642,41 +21830,42 @@ class SolanaMobileWalletProvider {
|
|
|
21642
21830
|
}
|
|
21643
21831
|
async signTransaction(transaction) {
|
|
21644
21832
|
var _a, _b;
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
//
|
|
21833
|
+
const account = await this.ensureAuthorized();
|
|
21834
|
+
const connectedPubkey = new web3_js.PublicKey(account.publicKey);
|
|
21835
|
+
const wallet = await this.ensureWallet();
|
|
21836
|
+
const chain = this.getChain();
|
|
21837
|
+
// Preserve existing prep: fill missing blockhash / fee payer so call
|
|
21838
|
+
// sites that build a tx without these fields don't regress.
|
|
21651
21839
|
const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
|
|
21652
21840
|
if (isLegacyTransaction) {
|
|
21653
21841
|
const legacyTx = transaction;
|
|
21654
21842
|
if (!legacyTx.recentBlockhash) {
|
|
21655
|
-
const
|
|
21656
|
-
const
|
|
21657
|
-
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
21843
|
+
const conn = new web3_js.Connection(this.getRpcUrl(), 'confirmed');
|
|
21844
|
+
const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash('confirmed');
|
|
21658
21845
|
legacyTx.recentBlockhash = blockhash;
|
|
21659
21846
|
legacyTx.lastValidBlockHeight = lastValidBlockHeight;
|
|
21660
21847
|
}
|
|
21661
|
-
if (!legacyTx.feePayer
|
|
21662
|
-
legacyTx.feePayer =
|
|
21848
|
+
if (!legacyTx.feePayer) {
|
|
21849
|
+
legacyTx.feePayer = connectedPubkey;
|
|
21663
21850
|
}
|
|
21664
21851
|
}
|
|
21665
21852
|
else {
|
|
21666
21853
|
const versionedTx = transaction;
|
|
21667
21854
|
if (!versionedTx.message.recentBlockhash) {
|
|
21668
|
-
const
|
|
21669
|
-
const
|
|
21670
|
-
const { blockhash } = await connection.getLatestBlockhash('confirmed');
|
|
21855
|
+
const conn = new web3_js.Connection(this.getRpcUrl(), 'confirmed');
|
|
21856
|
+
const { blockhash } = await conn.getLatestBlockhash('confirmed');
|
|
21671
21857
|
versionedTx.message.recentBlockhash = blockhash;
|
|
21672
21858
|
}
|
|
21673
21859
|
}
|
|
21674
21860
|
try {
|
|
21675
|
-
const
|
|
21676
|
-
|
|
21677
|
-
|
|
21678
|
-
|
|
21679
|
-
|
|
21861
|
+
const signTxFeat = getSignTransactionFeature(wallet);
|
|
21862
|
+
const wireBytes = txToWireBytes(transaction);
|
|
21863
|
+
const results = await signTxFeat.signTransaction({ account, transaction: wireBytes, chain });
|
|
21864
|
+
if (!results || results.length === 0) {
|
|
21865
|
+
throw new Error('MWA returned no signed transaction');
|
|
21866
|
+
}
|
|
21867
|
+
const { signedTransaction: signedBytes } = results[0];
|
|
21868
|
+
return txFromWireBytes(new Uint8Array(signedBytes));
|
|
21680
21869
|
}
|
|
21681
21870
|
catch (error) {
|
|
21682
21871
|
if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('not connected')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('not authorized')) ||
|
|
@@ -21689,15 +21878,15 @@ class SolanaMobileWalletProvider {
|
|
|
21689
21878
|
}
|
|
21690
21879
|
async signAndSubmitTransaction(transaction, feePayer) {
|
|
21691
21880
|
var _a, _b, _c, _d, _e, _f;
|
|
21692
|
-
|
|
21693
|
-
|
|
21694
|
-
|
|
21695
|
-
|
|
21696
|
-
const { transact } = mwaProtocolModule;
|
|
21881
|
+
const account = await this.ensureAuthorized();
|
|
21882
|
+
const connectedPubkey = new web3_js.PublicKey(account.publicKey);
|
|
21883
|
+
const wallet = await this.ensureWallet();
|
|
21884
|
+
const chain = this.getChain();
|
|
21697
21885
|
const rpcUrl = this.getRpcUrl();
|
|
21698
21886
|
const connection = new web3_js.Connection(rpcUrl, 'confirmed');
|
|
21699
21887
|
const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
|
|
21700
21888
|
try {
|
|
21889
|
+
// Preserve existing prep: refresh blockhash and set fee payer.
|
|
21701
21890
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
21702
21891
|
const isLegacyTransaction = 'recentBlockhash' in transaction && !('message' in transaction && 'staticAccountKeys' in transaction.message);
|
|
21703
21892
|
if (isLegacyTransaction) {
|
|
@@ -21705,12 +21894,7 @@ class SolanaMobileWalletProvider {
|
|
|
21705
21894
|
legacyTx.recentBlockhash = blockhash;
|
|
21706
21895
|
legacyTx.lastValidBlockHeight = lastValidBlockHeight;
|
|
21707
21896
|
if (!legacyTx.feePayer) {
|
|
21708
|
-
|
|
21709
|
-
legacyTx.feePayer = feePayer;
|
|
21710
|
-
}
|
|
21711
|
-
else if (this.publicKeyObj) {
|
|
21712
|
-
legacyTx.feePayer = this.publicKeyObj;
|
|
21713
|
-
}
|
|
21897
|
+
legacyTx.feePayer = feePayer !== null && feePayer !== void 0 ? feePayer : connectedPubkey;
|
|
21714
21898
|
}
|
|
21715
21899
|
}
|
|
21716
21900
|
else {
|
|
@@ -21718,14 +21902,19 @@ class SolanaMobileWalletProvider {
|
|
|
21718
21902
|
versionedTx.message.recentBlockhash = blockhash;
|
|
21719
21903
|
}
|
|
21720
21904
|
if (isSurfnet) {
|
|
21721
|
-
// Surfnet: sign-
|
|
21722
|
-
|
|
21723
|
-
|
|
21724
|
-
|
|
21725
|
-
|
|
21726
|
-
const
|
|
21905
|
+
// Surfnet: sign locally via wallet-standard, submit manually
|
|
21906
|
+
// to the Surfnet RPC. Don't route through signAndSendTransaction
|
|
21907
|
+
// because the wallet would submit to its own RPC.
|
|
21908
|
+
const signTxFeat = getSignTransactionFeature(wallet);
|
|
21909
|
+
const wireBytes = txToWireBytes(transaction);
|
|
21910
|
+
const results = await signTxFeat.signTransaction({ account, transaction: wireBytes, chain });
|
|
21911
|
+
if (!results || results.length === 0) {
|
|
21912
|
+
throw new Error('MWA returned no signed transaction');
|
|
21913
|
+
}
|
|
21914
|
+
const { signedTransaction: signedBytes } = results[0];
|
|
21915
|
+
const signedTx = txFromWireBytes(new Uint8Array(signedBytes));
|
|
21727
21916
|
const signature = await connection.sendRawTransaction(signedTx.serialize(), {
|
|
21728
|
-
preflightCommitment: 'confirmed'
|
|
21917
|
+
preflightCommitment: 'confirmed',
|
|
21729
21918
|
});
|
|
21730
21919
|
const confirmation = await connection.confirmTransaction({
|
|
21731
21920
|
signature,
|
|
@@ -21737,15 +21926,20 @@ class SolanaMobileWalletProvider {
|
|
|
21737
21926
|
}
|
|
21738
21927
|
return signature;
|
|
21739
21928
|
}
|
|
21740
|
-
// Non-
|
|
21741
|
-
const
|
|
21742
|
-
|
|
21743
|
-
|
|
21744
|
-
|
|
21745
|
-
|
|
21746
|
-
|
|
21747
|
-
|
|
21748
|
-
|
|
21929
|
+
// Non-Surfnet: wallet signs and submits to its own RPC.
|
|
21930
|
+
const signSendFeat = getSignAndSendTransactionFeature(wallet);
|
|
21931
|
+
const wireBytes = txToWireBytes(transaction);
|
|
21932
|
+
const results = await signSendFeat.signAndSendTransaction({
|
|
21933
|
+
account,
|
|
21934
|
+
transaction: wireBytes,
|
|
21935
|
+
chain,
|
|
21936
|
+
options: { commitment: 'confirmed' },
|
|
21937
|
+
});
|
|
21938
|
+
if (!results || results.length === 0) {
|
|
21939
|
+
throw new Error('MWA returned no signature');
|
|
21940
|
+
}
|
|
21941
|
+
const { signature: sigBytes } = results[0];
|
|
21942
|
+
const signature = base58.encode(sigBytes);
|
|
21749
21943
|
await confirmAndCheckTransaction(connection, signature);
|
|
21750
21944
|
return signature;
|
|
21751
21945
|
}
|
|
@@ -21771,16 +21965,14 @@ class SolanaMobileWalletProvider {
|
|
|
21771
21965
|
if (!solTransactionData) {
|
|
21772
21966
|
throw new Error('Solana transaction data is required for mobile wallet');
|
|
21773
21967
|
}
|
|
21774
|
-
|
|
21775
|
-
|
|
21776
|
-
|
|
21777
|
-
|
|
21778
|
-
const { transact } = mwaProtocolModule;
|
|
21968
|
+
const account = await this.ensureAuthorized();
|
|
21969
|
+
const connectedPubkey = new web3_js.PublicKey(account.publicKey);
|
|
21970
|
+
const wallet = await this.ensureWallet();
|
|
21971
|
+
const chain = this.getChain();
|
|
21779
21972
|
const rpcUrl = this.getRpcUrl(solTransactionData.network);
|
|
21780
21973
|
const connection = new web3_js.Connection(rpcUrl, 'confirmed');
|
|
21781
21974
|
const isSurfnet = rpcUrl === SURFNET_RPC_URL$2;
|
|
21782
21975
|
try {
|
|
21783
|
-
const publicKey = this.publicKeyObj;
|
|
21784
21976
|
const remainingAccounts = convertRemainingAccounts(solTransactionData.txArgs[0].remainingAccounts);
|
|
21785
21977
|
let app_id = solTransactionData.appId;
|
|
21786
21978
|
if (typeof window !== 'undefined' && window.CUSTOM_TAROBASE_APP_ID_HEADER) {
|
|
@@ -21789,9 +21981,9 @@ class SolanaMobileWalletProvider {
|
|
|
21789
21981
|
if (!app_id) {
|
|
21790
21982
|
throw new Error('App ID is required');
|
|
21791
21983
|
}
|
|
21792
|
-
//
|
|
21984
|
+
// Mock wallet adapter for Anchor — only publicKey is read during build.
|
|
21793
21985
|
const mockWalletAdapter = {
|
|
21794
|
-
publicKey,
|
|
21986
|
+
publicKey: connectedPubkey,
|
|
21795
21987
|
signTransaction: async (tx) => tx,
|
|
21796
21988
|
signAllTransactions: async (txs) => txs,
|
|
21797
21989
|
};
|
|
@@ -21809,10 +22001,12 @@ class SolanaMobileWalletProvider {
|
|
|
21809
22001
|
}
|
|
21810
22002
|
let tx;
|
|
21811
22003
|
if (solTransactionData.signedTransaction) {
|
|
22004
|
+
// Server has co-signed a CPI attestation. Do NOT mutate its
|
|
22005
|
+
// blockhash — that would invalidate the server's signature.
|
|
21812
22006
|
tx = web3_js.VersionedTransaction.deserialize(bufferExports.Buffer.from(solTransactionData.signedTransaction, 'base64'));
|
|
21813
22007
|
}
|
|
21814
22008
|
else {
|
|
21815
|
-
const result = await buildSetDocumentsTransaction(connection, solTransactionData.txArgs[0].idl, anchorProvider,
|
|
22009
|
+
const result = await buildSetDocumentsTransaction(connection, solTransactionData.txArgs[0].idl, anchorProvider, connectedPubkey, {
|
|
21816
22010
|
app_id,
|
|
21817
22011
|
documents: solTransactionData.txArgs[0].setDocumentData,
|
|
21818
22012
|
delete_paths: solTransactionData.txArgs[0].deletePaths,
|
|
@@ -21820,11 +22014,16 @@ class SolanaMobileWalletProvider {
|
|
|
21820
22014
|
}, finalDeduped, solTransactionData.lutKey, solTransactionData.preInstructions, false, solTransactionData.additionalLutAddresses);
|
|
21821
22015
|
tx = result.tx;
|
|
21822
22016
|
}
|
|
22017
|
+
// Sign-only branch — sign the tx but don't submit.
|
|
21823
22018
|
if ((options === null || options === void 0 ? void 0 : options.shouldSubmitTx) === false) {
|
|
21824
|
-
const
|
|
21825
|
-
|
|
21826
|
-
|
|
21827
|
-
|
|
22019
|
+
const signTxFeat = getSignTransactionFeature(wallet);
|
|
22020
|
+
const wireBytes = txToWireBytes(tx);
|
|
22021
|
+
const results = await signTxFeat.signTransaction({ account, transaction: wireBytes, chain });
|
|
22022
|
+
if (!results || results.length === 0) {
|
|
22023
|
+
throw new Error('MWA returned no signed transaction');
|
|
22024
|
+
}
|
|
22025
|
+
const { signedTransaction: signedBytes } = results[0];
|
|
22026
|
+
const signedTx = txFromWireBytes(new Uint8Array(signedBytes));
|
|
21828
22027
|
return {
|
|
21829
22028
|
signedTransaction: signedTx,
|
|
21830
22029
|
blockNumber: 0,
|
|
@@ -21833,14 +22032,18 @@ class SolanaMobileWalletProvider {
|
|
|
21833
22032
|
};
|
|
21834
22033
|
}
|
|
21835
22034
|
if (isSurfnet) {
|
|
21836
|
-
// Surfnet: sign
|
|
21837
|
-
const
|
|
21838
|
-
|
|
21839
|
-
|
|
21840
|
-
|
|
22035
|
+
// Surfnet: sign locally via wallet-standard, submit manually.
|
|
22036
|
+
const signTxFeat = getSignTransactionFeature(wallet);
|
|
22037
|
+
const wireBytes = txToWireBytes(tx);
|
|
22038
|
+
const results = await signTxFeat.signTransaction({ account, transaction: wireBytes, chain });
|
|
22039
|
+
if (!results || results.length === 0) {
|
|
22040
|
+
throw new Error('MWA returned no signed transaction');
|
|
22041
|
+
}
|
|
22042
|
+
const { signedTransaction: signedBytes } = results[0];
|
|
22043
|
+
const signedTx = txFromWireBytes(new Uint8Array(signedBytes));
|
|
21841
22044
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
|
21842
22045
|
const signature = await connection.sendRawTransaction(signedTx.serialize(), {
|
|
21843
|
-
preflightCommitment: 'confirmed'
|
|
22046
|
+
preflightCommitment: 'confirmed',
|
|
21844
22047
|
});
|
|
21845
22048
|
const confirmation = await connection.confirmTransaction({
|
|
21846
22049
|
signature,
|
|
@@ -21852,7 +22055,7 @@ class SolanaMobileWalletProvider {
|
|
|
21852
22055
|
}
|
|
21853
22056
|
const txInfo = await connection.getParsedTransaction(signature, {
|
|
21854
22057
|
maxSupportedTransactionVersion: 0,
|
|
21855
|
-
commitment: 'confirmed'
|
|
22058
|
+
commitment: 'confirmed',
|
|
21856
22059
|
});
|
|
21857
22060
|
return {
|
|
21858
22061
|
transactionSignature: signature,
|
|
@@ -21861,15 +22064,20 @@ class SolanaMobileWalletProvider {
|
|
|
21861
22064
|
data: txInfo === null || txInfo === void 0 ? void 0 : txInfo.meta,
|
|
21862
22065
|
};
|
|
21863
22066
|
}
|
|
21864
|
-
// Non-
|
|
21865
|
-
const
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
|
|
21869
|
-
|
|
21870
|
-
|
|
21871
|
-
|
|
21872
|
-
|
|
22067
|
+
// Non-Surfnet: wallet signs and submits to its own RPC.
|
|
22068
|
+
const signSendFeat = getSignAndSendTransactionFeature(wallet);
|
|
22069
|
+
const wireBytes = txToWireBytes(tx);
|
|
22070
|
+
const results = await signSendFeat.signAndSendTransaction({
|
|
22071
|
+
account,
|
|
22072
|
+
transaction: wireBytes,
|
|
22073
|
+
chain,
|
|
22074
|
+
options: { commitment: 'confirmed' },
|
|
22075
|
+
});
|
|
22076
|
+
if (!results || results.length === 0) {
|
|
22077
|
+
throw new Error('MWA returned no signature');
|
|
22078
|
+
}
|
|
22079
|
+
const { signature: sigBytes } = results[0];
|
|
22080
|
+
const signature = base58.encode(sigBytes);
|
|
21873
22081
|
const txInfo = await confirmAndCheckTransaction(connection, signature);
|
|
21874
22082
|
return {
|
|
21875
22083
|
transactionSignature: signature,
|
|
@@ -21896,11 +22104,36 @@ class SolanaMobileWalletProvider {
|
|
|
21896
22104
|
}
|
|
21897
22105
|
}
|
|
21898
22106
|
async getNativeMethods() {
|
|
22107
|
+
var _a, _b, _c;
|
|
22108
|
+
// Synchronous-ish state read; tolerate the wallet being unauthorized
|
|
22109
|
+
// (return nulls). Don't trigger ensureAuthorized() here — callers that
|
|
22110
|
+
// need the wallet active should sign through one of the sign methods.
|
|
22111
|
+
const wallet = this.wallet;
|
|
22112
|
+
if (!wallet) {
|
|
22113
|
+
return {
|
|
22114
|
+
authToken: null,
|
|
22115
|
+
walletUriBase: null,
|
|
22116
|
+
publicKey: null,
|
|
22117
|
+
base64Address: null,
|
|
22118
|
+
wallet: null,
|
|
22119
|
+
currentAuthorization: null,
|
|
22120
|
+
};
|
|
22121
|
+
}
|
|
22122
|
+
const acct = (_a = wallet.accounts) === null || _a === void 0 ? void 0 : _a[0];
|
|
22123
|
+
const auth = wallet.currentAuthorization;
|
|
22124
|
+
let publicKey = null;
|
|
22125
|
+
let base64Address = null;
|
|
22126
|
+
if (acct) {
|
|
22127
|
+
publicKey = new web3_js.PublicKey(acct.publicKey);
|
|
22128
|
+
base64Address = btoa(String.fromCharCode(...acct.publicKey));
|
|
22129
|
+
}
|
|
21899
22130
|
return {
|
|
21900
|
-
authToken:
|
|
21901
|
-
walletUriBase:
|
|
21902
|
-
publicKey
|
|
21903
|
-
base64Address
|
|
22131
|
+
authToken: (_b = auth === null || auth === void 0 ? void 0 : auth.auth_token) !== null && _b !== void 0 ? _b : null,
|
|
22132
|
+
walletUriBase: (_c = auth === null || auth === void 0 ? void 0 : auth.wallet_uri_base) !== null && _c !== void 0 ? _c : null,
|
|
22133
|
+
publicKey,
|
|
22134
|
+
base64Address,
|
|
22135
|
+
wallet,
|
|
22136
|
+
currentAuthorization: auth !== null && auth !== void 0 ? auth : null,
|
|
21904
22137
|
};
|
|
21905
22138
|
}
|
|
21906
22139
|
/* ----------------------------------------------------------- *
|
|
@@ -22328,4 +22561,4 @@ exports.signSessionCreateMessage = signSessionCreateMessage;
|
|
|
22328
22561
|
exports.signTransaction = signTransaction;
|
|
22329
22562
|
exports.subscribe = subscribe;
|
|
22330
22563
|
exports.useAuth = useAuth;
|
|
22331
|
-
//# sourceMappingURL=index-
|
|
22564
|
+
//# sourceMappingURL=index-BeFR3-cf.js.map
|