@solana-mobile/wallet-adapter-mobile 0.9.4 → 0.9.6
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/README.md +19 -7
- package/lib/cjs/index.browser.js +105 -53
- package/lib/cjs/index.js +105 -53
- package/lib/cjs/index.native.js +99 -47
- package/lib/esm/index.browser.mjs +105 -54
- package/lib/esm/index.mjs +105 -54
- package/lib/types/index.browser.d.mts +10 -1
- package/lib/types/index.browser.d.mts.map +1 -1
- package/lib/types/index.browser.d.ts +10 -1
- package/lib/types/index.browser.d.ts.map +1 -1
- package/lib/types/index.d.mts +10 -1
- package/lib/types/index.d.mts.map +1 -1
- package/lib/types/index.d.ts +10 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.native.d.ts +10 -1
- package/lib/types/index.native.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,11 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
This is a plugin for use with [`@solana/wallet-adapter`](https://github.com/solana-labs/wallet-adapter). It enables apps to use a native wallet app on a mobile device to sign messages and transactions, and to send transactions if the wallet offers support for sending transactions.
|
|
4
4
|
|
|
5
|
-

|
|
6
|
-
|
|
7
5
|
## Usage
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
Users of these libraries do not need to take any extra steps:
|
|
8
|
+
|
|
9
|
+
* `@solana/wallet-adapter-react@">=0.15.21"`
|
|
10
|
+
|
|
11
|
+
Those libraries automatically bundle the Mobile Wallet Adapter plugin, and enable it when running in a compatible mobile environment.
|
|
12
|
+
|
|
13
|
+
## Advanced usage
|
|
14
|
+
|
|
15
|
+
Developers might wish to customize the behavior of this plugin for their app. Specifying the app's name and icon, deciding which address to select in the event the wallet authorizes the app to use more than one, specifying which network cluster to communicate with, and more are made possible by creating an instance of the mobile wallet adapter like this.
|
|
10
16
|
|
|
11
17
|
```typescript
|
|
12
18
|
new SolanaMobileWalletAdapter({
|
|
@@ -18,10 +24,11 @@ new SolanaMobileWalletAdapter({
|
|
|
18
24
|
},
|
|
19
25
|
authorizationResultCache: createDefaultAuthorizationResultCache(),
|
|
20
26
|
cluster: WalletAdapterNetwork.Devnet,
|
|
27
|
+
onWalletNotFound: createDefaultWalletNotFoundHandler(),
|
|
21
28
|
});
|
|
22
29
|
```
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
Developers who use `@solana/wallet-adapter-react@">=0.15.21"` can supply this custom instance to `WalletProvider` which will use it to override the default one.
|
|
25
32
|
|
|
26
33
|
```typescript
|
|
27
34
|
const wallets = useMemo(() => [
|
|
@@ -34,9 +41,8 @@ const wallets = useMemo(() => [
|
|
|
34
41
|
},
|
|
35
42
|
authorizationResultCache: createDefaultAuthorizationResultCache(),
|
|
36
43
|
cluster: WalletAdapterNetwork.Devnet,
|
|
44
|
+
onWalletNotFound: createDefaultWalletNotFoundHandler(),
|
|
37
45
|
});
|
|
38
|
-
new PhantomWalletAdapter(),
|
|
39
|
-
/* ... other wallets ... */
|
|
40
46
|
]);
|
|
41
47
|
|
|
42
48
|
return (
|
|
@@ -88,4 +94,10 @@ Alternatively, you can use the included `createDefaultAuthorizationResultCache()
|
|
|
88
94
|
|
|
89
95
|
### Cluster
|
|
90
96
|
|
|
91
|
-
Each authorization a dApp makes with a wallet is tied to a particular Solana cluster. If a dApp wants to change the cluster on which to transact, it must seek an authorization for that cluster.
|
|
97
|
+
Each authorization a dApp makes with a wallet is tied to a particular Solana cluster. If a dApp wants to change the cluster on which to transact, it must seek an authorization for that cluster.
|
|
98
|
+
|
|
99
|
+
### Wallet-not-found handler
|
|
100
|
+
|
|
101
|
+
When you call `connect()` but no wallet responds within a reasonable amount of time, it is presumed that no compatible wallet is installed. You must supply an `onWalletNotFound` function to handle this case.
|
|
102
|
+
|
|
103
|
+
Alternatively, you can use the included `createDefaultWalletNotFoundHandler()` method to create a function that opens the Solana Mobile ecosystem wallets webpage.
|
package/lib/cjs/index.browser.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
|
|
5
6
|
var walletAdapterBase = require('@solana/wallet-adapter-base');
|
|
6
7
|
var web3_js = require('@solana/web3.js');
|
|
7
|
-
var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
|
|
8
8
|
|
|
9
9
|
/*! *****************************************************************************
|
|
10
10
|
Copyright (c) Microsoft Corporation.
|
|
@@ -31,13 +31,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function getIsSupported() {
|
|
35
|
-
return (typeof window !== 'undefined' &&
|
|
36
|
-
window.isSecureContext &&
|
|
37
|
-
typeof document !== 'undefined' &&
|
|
38
|
-
/android/i.test(navigator.userAgent));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
34
|
function toUint8Array(base64EncodedByteArray) {
|
|
42
35
|
return new Uint8Array(window
|
|
43
36
|
.atob(base64EncodedByteArray)
|
|
@@ -45,12 +38,22 @@ function toUint8Array(base64EncodedByteArray) {
|
|
|
45
38
|
.map((c) => c.charCodeAt(0)));
|
|
46
39
|
}
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
function getIsSupported() {
|
|
42
|
+
return (typeof window !== 'undefined' &&
|
|
43
|
+
window.isSecureContext &&
|
|
44
|
+
typeof document !== 'undefined' &&
|
|
45
|
+
/android/i.test(navigator.userAgent));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const SolanaMobileWalletAdapterWalletName = 'Mobile Wallet Adapter';
|
|
49
49
|
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
50
50
|
function getPublicKeyFromAddress(address) {
|
|
51
51
|
const publicKeyByteArray = toUint8Array(address);
|
|
52
52
|
return new web3_js.PublicKey(publicKeyByteArray);
|
|
53
53
|
}
|
|
54
|
+
function isVersionedTransaction(transaction) {
|
|
55
|
+
return 'version' in transaction;
|
|
56
|
+
}
|
|
54
57
|
class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalletAdapter {
|
|
55
58
|
constructor(config) {
|
|
56
59
|
super();
|
|
@@ -58,14 +61,21 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
58
61
|
// FIXME(#244): We can't actually know what versions are supported until we know which wallet we're talking to.
|
|
59
62
|
['legacy', 0]);
|
|
60
63
|
this.name = SolanaMobileWalletAdapterWalletName;
|
|
61
|
-
this.url = 'https://solanamobile.com';
|
|
64
|
+
this.url = 'https://solanamobile.com/wallets';
|
|
62
65
|
this.icon = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI4IiB3aWR0aD0iMjgiIHZpZXdCb3g9Ii0zIDAgMjggMjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI0RDQjhGRiI+PHBhdGggZD0iTTE3LjQgMTcuNEgxNXYyLjRoMi40di0yLjRabTEuMi05LjZoLTIuNHYyLjRoMi40VjcuOFoiLz48cGF0aCBkPSJNMjEuNiAzVjBoLTIuNHYzaC0zLjZWMGgtMi40djNoLTIuNHY2LjZINC41YTIuMSAyLjEgMCAxIDEgMC00LjJoMi43VjNINC41QTQuNSA0LjUgMCAwIDAgMCA3LjVWMjRoMjEuNnYtNi42aC0yLjR2NC4ySDIuNFYxMS41Yy41LjMgMS4yLjQgMS44LjVoNy41QTYuNiA2LjYgMCAwIDAgMjQgOVYzaC0yLjRabTAgNS43YTQuMiA0LjIgMCAxIDEtOC40IDBWNS40aDguNHYzLjNaIi8+PC9nPjwvc3ZnPg==';
|
|
63
66
|
this._connecting = false;
|
|
67
|
+
/**
|
|
68
|
+
* Every time the connection is recycled in some way (eg. `disconnect()` is called)
|
|
69
|
+
* increment this and use it to make sure that `transact` calls from the previous
|
|
70
|
+
* 'generation' don't continue to do work and throw exceptions.
|
|
71
|
+
*/
|
|
72
|
+
this._connectionGeneration = 0;
|
|
64
73
|
this._readyState = getIsSupported() ? walletAdapterBase.WalletReadyState.Loadable : walletAdapterBase.WalletReadyState.Unsupported;
|
|
65
74
|
this._authorizationResultCache = config.authorizationResultCache;
|
|
66
75
|
this._addressSelector = config.addressSelector;
|
|
67
76
|
this._appIdentity = config.appIdentity;
|
|
68
77
|
this._cluster = config.cluster;
|
|
78
|
+
this._onWalletNotFound = config.onWalletNotFound;
|
|
69
79
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Unsupported) {
|
|
70
80
|
this._authorizationResultCache.get().then((authorizationResult) => {
|
|
71
81
|
if (authorizationResult) {
|
|
@@ -223,6 +233,8 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
223
233
|
disconnect() {
|
|
224
234
|
return __awaiter(this, void 0, void 0, function* () {
|
|
225
235
|
this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
236
|
+
this._connecting = false;
|
|
237
|
+
this._connectionGeneration++;
|
|
226
238
|
delete this._authorizationResult;
|
|
227
239
|
delete this._publicKey;
|
|
228
240
|
delete this._selectedAddress;
|
|
@@ -234,7 +246,21 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
234
246
|
return __awaiter(this, void 0, void 0, function* () {
|
|
235
247
|
const walletUriBase = (_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.wallet_uri_base;
|
|
236
248
|
const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
|
|
237
|
-
|
|
249
|
+
const currentConnectionGeneration = this._connectionGeneration;
|
|
250
|
+
try {
|
|
251
|
+
return yield mobileWalletAdapterProtocolWeb3js.transact(callback, config);
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
if (this._connectionGeneration !== currentConnectionGeneration) {
|
|
255
|
+
yield new Promise(() => { }); // Never resolve.
|
|
256
|
+
}
|
|
257
|
+
if (e instanceof Error &&
|
|
258
|
+
e.name === 'SolanaMobileWalletAdapterError' &&
|
|
259
|
+
e.code === 'ERROR_WALLET_NOT_FOUND') {
|
|
260
|
+
yield this._onWalletNotFound(this);
|
|
261
|
+
}
|
|
262
|
+
throw e;
|
|
263
|
+
}
|
|
238
264
|
});
|
|
239
265
|
}
|
|
240
266
|
assertIsAuthorized() {
|
|
@@ -269,9 +295,43 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
269
295
|
const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
|
|
270
296
|
try {
|
|
271
297
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
272
|
-
|
|
298
|
+
function getTargetCommitment() {
|
|
299
|
+
let targetCommitment;
|
|
300
|
+
switch (connection.commitment) {
|
|
301
|
+
case 'confirmed':
|
|
302
|
+
case 'finalized':
|
|
303
|
+
case 'processed':
|
|
304
|
+
targetCommitment = connection.commitment;
|
|
305
|
+
break;
|
|
306
|
+
default:
|
|
307
|
+
targetCommitment = 'finalized';
|
|
308
|
+
}
|
|
309
|
+
let targetPreflightCommitment;
|
|
310
|
+
switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
|
|
311
|
+
case 'confirmed':
|
|
312
|
+
case 'finalized':
|
|
313
|
+
case 'processed':
|
|
314
|
+
targetPreflightCommitment = options.preflightCommitment;
|
|
315
|
+
break;
|
|
316
|
+
case undefined:
|
|
317
|
+
targetPreflightCommitment = targetCommitment;
|
|
318
|
+
default:
|
|
319
|
+
targetPreflightCommitment = 'finalized';
|
|
320
|
+
}
|
|
321
|
+
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
322
|
+
? 2
|
|
323
|
+
: targetPreflightCommitment === 'confirmed'
|
|
324
|
+
? 1
|
|
325
|
+
: 0;
|
|
326
|
+
const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
|
|
327
|
+
return preflightCommitmentScore < targetCommitmentScore
|
|
328
|
+
? targetPreflightCommitment
|
|
329
|
+
: targetCommitment;
|
|
330
|
+
}
|
|
331
|
+
const [capabilities, _1, _2] = yield Promise.all([
|
|
332
|
+
wallet.getCapabilities(),
|
|
273
333
|
this.performReauthorization(wallet, authToken),
|
|
274
|
-
|
|
334
|
+
isVersionedTransaction(transaction)
|
|
275
335
|
? null
|
|
276
336
|
: /**
|
|
277
337
|
* Unlike versioned transactions, legacy `Transaction` objects
|
|
@@ -282,52 +342,32 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
282
342
|
var _a;
|
|
283
343
|
transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
|
|
284
344
|
if (transaction.recentBlockhash == null) {
|
|
285
|
-
let targetCommitment;
|
|
286
|
-
switch (connection.commitment) {
|
|
287
|
-
case 'confirmed':
|
|
288
|
-
case 'finalized':
|
|
289
|
-
case 'processed':
|
|
290
|
-
targetCommitment = connection.commitment;
|
|
291
|
-
break;
|
|
292
|
-
default:
|
|
293
|
-
targetCommitment = 'finalized';
|
|
294
|
-
}
|
|
295
|
-
let targetPreflightCommitment;
|
|
296
|
-
switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
|
|
297
|
-
case 'confirmed':
|
|
298
|
-
case 'finalized':
|
|
299
|
-
case 'processed':
|
|
300
|
-
targetPreflightCommitment = options.preflightCommitment;
|
|
301
|
-
break;
|
|
302
|
-
case undefined:
|
|
303
|
-
targetPreflightCommitment = targetCommitment;
|
|
304
|
-
default:
|
|
305
|
-
targetPreflightCommitment = 'finalized';
|
|
306
|
-
}
|
|
307
|
-
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
308
|
-
? 2
|
|
309
|
-
: targetPreflightCommitment === 'confirmed'
|
|
310
|
-
? 1
|
|
311
|
-
: 0;
|
|
312
|
-
const targetCommitmentScore = targetCommitment === 'finalized'
|
|
313
|
-
? 2
|
|
314
|
-
: targetCommitment === 'confirmed'
|
|
315
|
-
? 1
|
|
316
|
-
: 0;
|
|
317
345
|
const { blockhash } = yield connection.getLatestBlockhash({
|
|
318
|
-
commitment:
|
|
319
|
-
? targetPreflightCommitment
|
|
320
|
-
: targetCommitment,
|
|
346
|
+
commitment: getTargetCommitment(),
|
|
321
347
|
});
|
|
322
348
|
transaction.recentBlockhash = blockhash;
|
|
323
349
|
}
|
|
324
350
|
}))(),
|
|
325
351
|
]);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
352
|
+
if (capabilities.supports_sign_and_send_transactions) {
|
|
353
|
+
const signatures = yield wallet.signAndSendTransactions({
|
|
354
|
+
minContextSlot,
|
|
355
|
+
transactions: [transaction],
|
|
356
|
+
});
|
|
357
|
+
return signatures[0];
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
const [signedTransaction] = yield wallet.signTransactions({
|
|
361
|
+
transactions: [transaction],
|
|
362
|
+
});
|
|
363
|
+
if (isVersionedTransaction(signedTransaction)) {
|
|
364
|
+
return yield connection.sendTransaction(signedTransaction);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
const serializedTransaction = signedTransaction.serialize();
|
|
368
|
+
return yield connection.sendRawTransaction(serializedTransaction, Object.assign(Object.assign({}, options), { preflightCommitment: getTargetCommitment() }));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
331
371
|
}));
|
|
332
372
|
}
|
|
333
373
|
catch (error) {
|
|
@@ -433,7 +473,19 @@ function createDefaultAuthorizationResultCache() {
|
|
|
433
473
|
};
|
|
434
474
|
}
|
|
435
475
|
|
|
476
|
+
function defaultWalletNotFoundHandler(mobileWalletAdapter) {
|
|
477
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
478
|
+
if (typeof window !== 'undefined') {
|
|
479
|
+
window.location.assign(mobileWalletAdapter.url);
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
function createDefaultWalletNotFoundHandler() {
|
|
484
|
+
return defaultWalletNotFoundHandler;
|
|
485
|
+
}
|
|
486
|
+
|
|
436
487
|
exports.SolanaMobileWalletAdapter = SolanaMobileWalletAdapter;
|
|
437
488
|
exports.SolanaMobileWalletAdapterWalletName = SolanaMobileWalletAdapterWalletName;
|
|
438
489
|
exports.createDefaultAddressSelector = createDefaultAddressSelector;
|
|
439
490
|
exports.createDefaultAuthorizationResultCache = createDefaultAuthorizationResultCache;
|
|
491
|
+
exports.createDefaultWalletNotFoundHandler = createDefaultWalletNotFoundHandler;
|
package/lib/cjs/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
|
|
5
6
|
var walletAdapterBase = require('@solana/wallet-adapter-base');
|
|
6
7
|
var web3_js = require('@solana/web3.js');
|
|
7
|
-
var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
|
|
8
8
|
|
|
9
9
|
/*! *****************************************************************************
|
|
10
10
|
Copyright (c) Microsoft Corporation.
|
|
@@ -31,13 +31,6 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function getIsSupported() {
|
|
35
|
-
return (typeof window !== 'undefined' &&
|
|
36
|
-
window.isSecureContext &&
|
|
37
|
-
typeof document !== 'undefined' &&
|
|
38
|
-
/android/i.test(navigator.userAgent));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
34
|
function toUint8Array(base64EncodedByteArray) {
|
|
42
35
|
return new Uint8Array(window
|
|
43
36
|
.atob(base64EncodedByteArray)
|
|
@@ -45,12 +38,22 @@ function toUint8Array(base64EncodedByteArray) {
|
|
|
45
38
|
.map((c) => c.charCodeAt(0)));
|
|
46
39
|
}
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
function getIsSupported() {
|
|
42
|
+
return (typeof window !== 'undefined' &&
|
|
43
|
+
window.isSecureContext &&
|
|
44
|
+
typeof document !== 'undefined' &&
|
|
45
|
+
/android/i.test(navigator.userAgent));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const SolanaMobileWalletAdapterWalletName = 'Mobile Wallet Adapter';
|
|
49
49
|
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
50
50
|
function getPublicKeyFromAddress(address) {
|
|
51
51
|
const publicKeyByteArray = toUint8Array(address);
|
|
52
52
|
return new web3_js.PublicKey(publicKeyByteArray);
|
|
53
53
|
}
|
|
54
|
+
function isVersionedTransaction(transaction) {
|
|
55
|
+
return 'version' in transaction;
|
|
56
|
+
}
|
|
54
57
|
class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalletAdapter {
|
|
55
58
|
constructor(config) {
|
|
56
59
|
super();
|
|
@@ -58,14 +61,21 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
58
61
|
// FIXME(#244): We can't actually know what versions are supported until we know which wallet we're talking to.
|
|
59
62
|
['legacy', 0]);
|
|
60
63
|
this.name = SolanaMobileWalletAdapterWalletName;
|
|
61
|
-
this.url = 'https://solanamobile.com';
|
|
64
|
+
this.url = 'https://solanamobile.com/wallets';
|
|
62
65
|
this.icon = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI4IiB3aWR0aD0iMjgiIHZpZXdCb3g9Ii0zIDAgMjggMjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI0RDQjhGRiI+PHBhdGggZD0iTTE3LjQgMTcuNEgxNXYyLjRoMi40di0yLjRabTEuMi05LjZoLTIuNHYyLjRoMi40VjcuOFoiLz48cGF0aCBkPSJNMjEuNiAzVjBoLTIuNHYzaC0zLjZWMGgtMi40djNoLTIuNHY2LjZINC41YTIuMSAyLjEgMCAxIDEgMC00LjJoMi43VjNINC41QTQuNSA0LjUgMCAwIDAgMCA3LjVWMjRoMjEuNnYtNi42aC0yLjR2NC4ySDIuNFYxMS41Yy41LjMgMS4yLjQgMS44LjVoNy41QTYuNiA2LjYgMCAwIDAgMjQgOVYzaC0yLjRabTAgNS43YTQuMiA0LjIgMCAxIDEtOC40IDBWNS40aDguNHYzLjNaIi8+PC9nPjwvc3ZnPg==';
|
|
63
66
|
this._connecting = false;
|
|
67
|
+
/**
|
|
68
|
+
* Every time the connection is recycled in some way (eg. `disconnect()` is called)
|
|
69
|
+
* increment this and use it to make sure that `transact` calls from the previous
|
|
70
|
+
* 'generation' don't continue to do work and throw exceptions.
|
|
71
|
+
*/
|
|
72
|
+
this._connectionGeneration = 0;
|
|
64
73
|
this._readyState = getIsSupported() ? walletAdapterBase.WalletReadyState.Loadable : walletAdapterBase.WalletReadyState.Unsupported;
|
|
65
74
|
this._authorizationResultCache = config.authorizationResultCache;
|
|
66
75
|
this._addressSelector = config.addressSelector;
|
|
67
76
|
this._appIdentity = config.appIdentity;
|
|
68
77
|
this._cluster = config.cluster;
|
|
78
|
+
this._onWalletNotFound = config.onWalletNotFound;
|
|
69
79
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Unsupported) {
|
|
70
80
|
this._authorizationResultCache.get().then((authorizationResult) => {
|
|
71
81
|
if (authorizationResult) {
|
|
@@ -223,6 +233,8 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
223
233
|
disconnect() {
|
|
224
234
|
return __awaiter(this, void 0, void 0, function* () {
|
|
225
235
|
this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
236
|
+
this._connecting = false;
|
|
237
|
+
this._connectionGeneration++;
|
|
226
238
|
delete this._authorizationResult;
|
|
227
239
|
delete this._publicKey;
|
|
228
240
|
delete this._selectedAddress;
|
|
@@ -234,7 +246,21 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
234
246
|
return __awaiter(this, void 0, void 0, function* () {
|
|
235
247
|
const walletUriBase = (_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.wallet_uri_base;
|
|
236
248
|
const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
|
|
237
|
-
|
|
249
|
+
const currentConnectionGeneration = this._connectionGeneration;
|
|
250
|
+
try {
|
|
251
|
+
return yield mobileWalletAdapterProtocolWeb3js.transact(callback, config);
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
if (this._connectionGeneration !== currentConnectionGeneration) {
|
|
255
|
+
yield new Promise(() => { }); // Never resolve.
|
|
256
|
+
}
|
|
257
|
+
if (e instanceof Error &&
|
|
258
|
+
e.name === 'SolanaMobileWalletAdapterError' &&
|
|
259
|
+
e.code === 'ERROR_WALLET_NOT_FOUND') {
|
|
260
|
+
yield this._onWalletNotFound(this);
|
|
261
|
+
}
|
|
262
|
+
throw e;
|
|
263
|
+
}
|
|
238
264
|
});
|
|
239
265
|
}
|
|
240
266
|
assertIsAuthorized() {
|
|
@@ -269,9 +295,43 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
269
295
|
const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
|
|
270
296
|
try {
|
|
271
297
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
272
|
-
|
|
298
|
+
function getTargetCommitment() {
|
|
299
|
+
let targetCommitment;
|
|
300
|
+
switch (connection.commitment) {
|
|
301
|
+
case 'confirmed':
|
|
302
|
+
case 'finalized':
|
|
303
|
+
case 'processed':
|
|
304
|
+
targetCommitment = connection.commitment;
|
|
305
|
+
break;
|
|
306
|
+
default:
|
|
307
|
+
targetCommitment = 'finalized';
|
|
308
|
+
}
|
|
309
|
+
let targetPreflightCommitment;
|
|
310
|
+
switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
|
|
311
|
+
case 'confirmed':
|
|
312
|
+
case 'finalized':
|
|
313
|
+
case 'processed':
|
|
314
|
+
targetPreflightCommitment = options.preflightCommitment;
|
|
315
|
+
break;
|
|
316
|
+
case undefined:
|
|
317
|
+
targetPreflightCommitment = targetCommitment;
|
|
318
|
+
default:
|
|
319
|
+
targetPreflightCommitment = 'finalized';
|
|
320
|
+
}
|
|
321
|
+
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
322
|
+
? 2
|
|
323
|
+
: targetPreflightCommitment === 'confirmed'
|
|
324
|
+
? 1
|
|
325
|
+
: 0;
|
|
326
|
+
const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
|
|
327
|
+
return preflightCommitmentScore < targetCommitmentScore
|
|
328
|
+
? targetPreflightCommitment
|
|
329
|
+
: targetCommitment;
|
|
330
|
+
}
|
|
331
|
+
const [capabilities, _1, _2] = yield Promise.all([
|
|
332
|
+
wallet.getCapabilities(),
|
|
273
333
|
this.performReauthorization(wallet, authToken),
|
|
274
|
-
|
|
334
|
+
isVersionedTransaction(transaction)
|
|
275
335
|
? null
|
|
276
336
|
: /**
|
|
277
337
|
* Unlike versioned transactions, legacy `Transaction` objects
|
|
@@ -282,52 +342,32 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
282
342
|
var _a;
|
|
283
343
|
transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
|
|
284
344
|
if (transaction.recentBlockhash == null) {
|
|
285
|
-
let targetCommitment;
|
|
286
|
-
switch (connection.commitment) {
|
|
287
|
-
case 'confirmed':
|
|
288
|
-
case 'finalized':
|
|
289
|
-
case 'processed':
|
|
290
|
-
targetCommitment = connection.commitment;
|
|
291
|
-
break;
|
|
292
|
-
default:
|
|
293
|
-
targetCommitment = 'finalized';
|
|
294
|
-
}
|
|
295
|
-
let targetPreflightCommitment;
|
|
296
|
-
switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
|
|
297
|
-
case 'confirmed':
|
|
298
|
-
case 'finalized':
|
|
299
|
-
case 'processed':
|
|
300
|
-
targetPreflightCommitment = options.preflightCommitment;
|
|
301
|
-
break;
|
|
302
|
-
case undefined:
|
|
303
|
-
targetPreflightCommitment = targetCommitment;
|
|
304
|
-
default:
|
|
305
|
-
targetPreflightCommitment = 'finalized';
|
|
306
|
-
}
|
|
307
|
-
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
308
|
-
? 2
|
|
309
|
-
: targetPreflightCommitment === 'confirmed'
|
|
310
|
-
? 1
|
|
311
|
-
: 0;
|
|
312
|
-
const targetCommitmentScore = targetCommitment === 'finalized'
|
|
313
|
-
? 2
|
|
314
|
-
: targetCommitment === 'confirmed'
|
|
315
|
-
? 1
|
|
316
|
-
: 0;
|
|
317
345
|
const { blockhash } = yield connection.getLatestBlockhash({
|
|
318
|
-
commitment:
|
|
319
|
-
? targetPreflightCommitment
|
|
320
|
-
: targetCommitment,
|
|
346
|
+
commitment: getTargetCommitment(),
|
|
321
347
|
});
|
|
322
348
|
transaction.recentBlockhash = blockhash;
|
|
323
349
|
}
|
|
324
350
|
}))(),
|
|
325
351
|
]);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
352
|
+
if (capabilities.supports_sign_and_send_transactions) {
|
|
353
|
+
const signatures = yield wallet.signAndSendTransactions({
|
|
354
|
+
minContextSlot,
|
|
355
|
+
transactions: [transaction],
|
|
356
|
+
});
|
|
357
|
+
return signatures[0];
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
const [signedTransaction] = yield wallet.signTransactions({
|
|
361
|
+
transactions: [transaction],
|
|
362
|
+
});
|
|
363
|
+
if (isVersionedTransaction(signedTransaction)) {
|
|
364
|
+
return yield connection.sendTransaction(signedTransaction);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
const serializedTransaction = signedTransaction.serialize();
|
|
368
|
+
return yield connection.sendRawTransaction(serializedTransaction, Object.assign(Object.assign({}, options), { preflightCommitment: getTargetCommitment() }));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
331
371
|
}));
|
|
332
372
|
}
|
|
333
373
|
catch (error) {
|
|
@@ -433,7 +473,19 @@ function createDefaultAuthorizationResultCache() {
|
|
|
433
473
|
};
|
|
434
474
|
}
|
|
435
475
|
|
|
476
|
+
function defaultWalletNotFoundHandler(mobileWalletAdapter) {
|
|
477
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
478
|
+
if (typeof window !== 'undefined') {
|
|
479
|
+
window.location.assign(mobileWalletAdapter.url);
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
function createDefaultWalletNotFoundHandler() {
|
|
484
|
+
return defaultWalletNotFoundHandler;
|
|
485
|
+
}
|
|
486
|
+
|
|
436
487
|
exports.SolanaMobileWalletAdapter = SolanaMobileWalletAdapter;
|
|
437
488
|
exports.SolanaMobileWalletAdapterWalletName = SolanaMobileWalletAdapterWalletName;
|
|
438
489
|
exports.createDefaultAddressSelector = createDefaultAddressSelector;
|
|
439
490
|
exports.createDefaultAuthorizationResultCache = createDefaultAuthorizationResultCache;
|
|
491
|
+
exports.createDefaultWalletNotFoundHandler = createDefaultWalletNotFoundHandler;
|