@solana-mobile/wallet-adapter-mobile 0.9.5 → 0.9.7

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 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
- ![A screenshot showing the Solana Mobile wallet adapter in use with the wallet adapter dialog](https://user-images.githubusercontent.com/13243/174880433-92486385-6f9a-4221-bb55-c05bab057be6.png)
6
-
7
5
  ## Usage
8
6
 
9
- Create an instance of the mobile wallet adapter like this.
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({
@@ -22,7 +28,7 @@ new SolanaMobileWalletAdapter({
22
28
  });
23
29
  ```
24
30
 
25
- Use that adapter instance alongside the other adapters used by your app.
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.
26
32
 
27
33
  ```typescript
28
34
  const wallets = useMemo(() => [
@@ -37,8 +43,6 @@ const wallets = useMemo(() => [
37
43
  cluster: WalletAdapterNetwork.Devnet,
38
44
  onWalletNotFound: createDefaultWalletNotFoundHandler(),
39
45
  });
40
- new PhantomWalletAdapter(),
41
- /* ... other wallets ... */
42
46
  ]);
43
47
 
44
48
  return (
@@ -2,11 +2,11 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
6
5
  var walletAdapterBase = require('@solana/wallet-adapter-base');
7
6
  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.
11
11
 
12
12
  Permission to use, copy, modify, and/or distribute this software for any
@@ -51,6 +51,9 @@ 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();
@@ -61,6 +64,12 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
61
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;
@@ -224,6 +233,8 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
224
233
  disconnect() {
225
234
  return __awaiter(this, void 0, void 0, function* () {
226
235
  this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
236
+ this._connecting = false;
237
+ this._connectionGeneration++;
227
238
  delete this._authorizationResult;
228
239
  delete this._publicKey;
229
240
  delete this._selectedAddress;
@@ -235,10 +246,14 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
235
246
  return __awaiter(this, void 0, void 0, function* () {
236
247
  const walletUriBase = (_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.wallet_uri_base;
237
248
  const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
249
+ const currentConnectionGeneration = this._connectionGeneration;
238
250
  try {
239
251
  return yield mobileWalletAdapterProtocolWeb3js.transact(callback, config);
240
252
  }
241
253
  catch (e) {
254
+ if (this._connectionGeneration !== currentConnectionGeneration) {
255
+ yield new Promise(() => { }); // Never resolve.
256
+ }
242
257
  if (e instanceof Error &&
243
258
  e.name === 'SolanaMobileWalletAdapterError' &&
244
259
  e.code === 'ERROR_WALLET_NOT_FOUND') {
@@ -280,9 +295,43 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
280
295
  const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
281
296
  try {
282
297
  return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
283
- yield Promise.all([
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(),
284
333
  this.performReauthorization(wallet, authToken),
285
- 'version' in transaction
334
+ isVersionedTransaction(transaction)
286
335
  ? null
287
336
  : /**
288
337
  * Unlike versioned transactions, legacy `Transaction` objects
@@ -293,52 +342,32 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
293
342
  var _a;
294
343
  transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
295
344
  if (transaction.recentBlockhash == null) {
296
- let targetCommitment;
297
- switch (connection.commitment) {
298
- case 'confirmed':
299
- case 'finalized':
300
- case 'processed':
301
- targetCommitment = connection.commitment;
302
- break;
303
- default:
304
- targetCommitment = 'finalized';
305
- }
306
- let targetPreflightCommitment;
307
- switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
308
- case 'confirmed':
309
- case 'finalized':
310
- case 'processed':
311
- targetPreflightCommitment = options.preflightCommitment;
312
- break;
313
- case undefined:
314
- targetPreflightCommitment = targetCommitment;
315
- default:
316
- targetPreflightCommitment = 'finalized';
317
- }
318
- const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
319
- ? 2
320
- : targetPreflightCommitment === 'confirmed'
321
- ? 1
322
- : 0;
323
- const targetCommitmentScore = targetCommitment === 'finalized'
324
- ? 2
325
- : targetCommitment === 'confirmed'
326
- ? 1
327
- : 0;
328
345
  const { blockhash } = yield connection.getLatestBlockhash({
329
- commitment: preflightCommitmentScore < targetCommitmentScore
330
- ? targetPreflightCommitment
331
- : targetCommitment,
346
+ commitment: getTargetCommitment(),
332
347
  });
333
348
  transaction.recentBlockhash = blockhash;
334
349
  }
335
350
  }))(),
336
351
  ]);
337
- const signatures = yield wallet.signAndSendTransactions({
338
- minContextSlot,
339
- transactions: [transaction],
340
- });
341
- return signatures[0];
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
+ }
342
371
  }));
343
372
  }
344
373
  catch (error) {
package/lib/cjs/index.js CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
6
5
  var walletAdapterBase = require('@solana/wallet-adapter-base');
7
6
  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.
11
11
 
12
12
  Permission to use, copy, modify, and/or distribute this software for any
@@ -51,6 +51,9 @@ 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();
@@ -61,6 +64,12 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
61
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;
@@ -224,6 +233,8 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
224
233
  disconnect() {
225
234
  return __awaiter(this, void 0, void 0, function* () {
226
235
  this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
236
+ this._connecting = false;
237
+ this._connectionGeneration++;
227
238
  delete this._authorizationResult;
228
239
  delete this._publicKey;
229
240
  delete this._selectedAddress;
@@ -235,10 +246,14 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
235
246
  return __awaiter(this, void 0, void 0, function* () {
236
247
  const walletUriBase = (_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.wallet_uri_base;
237
248
  const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
249
+ const currentConnectionGeneration = this._connectionGeneration;
238
250
  try {
239
251
  return yield mobileWalletAdapterProtocolWeb3js.transact(callback, config);
240
252
  }
241
253
  catch (e) {
254
+ if (this._connectionGeneration !== currentConnectionGeneration) {
255
+ yield new Promise(() => { }); // Never resolve.
256
+ }
242
257
  if (e instanceof Error &&
243
258
  e.name === 'SolanaMobileWalletAdapterError' &&
244
259
  e.code === 'ERROR_WALLET_NOT_FOUND') {
@@ -280,9 +295,43 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
280
295
  const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
281
296
  try {
282
297
  return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
283
- yield Promise.all([
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(),
284
333
  this.performReauthorization(wallet, authToken),
285
- 'version' in transaction
334
+ isVersionedTransaction(transaction)
286
335
  ? null
287
336
  : /**
288
337
  * Unlike versioned transactions, legacy `Transaction` objects
@@ -293,52 +342,32 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
293
342
  var _a;
294
343
  transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
295
344
  if (transaction.recentBlockhash == null) {
296
- let targetCommitment;
297
- switch (connection.commitment) {
298
- case 'confirmed':
299
- case 'finalized':
300
- case 'processed':
301
- targetCommitment = connection.commitment;
302
- break;
303
- default:
304
- targetCommitment = 'finalized';
305
- }
306
- let targetPreflightCommitment;
307
- switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
308
- case 'confirmed':
309
- case 'finalized':
310
- case 'processed':
311
- targetPreflightCommitment = options.preflightCommitment;
312
- break;
313
- case undefined:
314
- targetPreflightCommitment = targetCommitment;
315
- default:
316
- targetPreflightCommitment = 'finalized';
317
- }
318
- const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
319
- ? 2
320
- : targetPreflightCommitment === 'confirmed'
321
- ? 1
322
- : 0;
323
- const targetCommitmentScore = targetCommitment === 'finalized'
324
- ? 2
325
- : targetCommitment === 'confirmed'
326
- ? 1
327
- : 0;
328
345
  const { blockhash } = yield connection.getLatestBlockhash({
329
- commitment: preflightCommitmentScore < targetCommitmentScore
330
- ? targetPreflightCommitment
331
- : targetCommitment,
346
+ commitment: getTargetCommitment(),
332
347
  });
333
348
  transaction.recentBlockhash = blockhash;
334
349
  }
335
350
  }))(),
336
351
  ]);
337
- const signatures = yield wallet.signAndSendTransactions({
338
- minContextSlot,
339
- transactions: [transaction],
340
- });
341
- return signatures[0];
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
+ }
342
371
  }));
343
372
  }
344
373
  catch (error) {
@@ -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');
6
5
  var walletAdapterBase = require('@solana/wallet-adapter-base');
7
6
  var web3_js = require('@solana/web3.js');
7
+ var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-adapter-protocol-web3js');
8
8
  var jsBase64 = require('js-base64');
9
9
  var reactNative = require('react-native');
10
10
  var AsyncStorage = require('@react-native-async-storage/async-storage');
@@ -13,7 +13,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
13
13
 
14
14
  var AsyncStorage__default = /*#__PURE__*/_interopDefaultLegacy(AsyncStorage);
15
15
 
16
- /*! *****************************************************************************
16
+ /******************************************************************************
17
17
  Copyright (c) Microsoft Corporation.
18
18
 
19
19
  Permission to use, copy, modify, and/or distribute this software for any
@@ -48,6 +48,9 @@ function getPublicKeyFromAddress(address) {
48
48
  const publicKeyByteArray = jsBase64.toUint8Array(address);
49
49
  return new web3_js.PublicKey(publicKeyByteArray);
50
50
  }
51
+ function isVersionedTransaction(transaction) {
52
+ return 'version' in transaction;
53
+ }
51
54
  class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalletAdapter {
52
55
  constructor(config) {
53
56
  super();
@@ -58,6 +61,12 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
58
61
  this.url = 'https://solanamobile.com/wallets';
59
62
  this.icon = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI4IiB3aWR0aD0iMjgiIHZpZXdCb3g9Ii0zIDAgMjggMjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI0RDQjhGRiI+PHBhdGggZD0iTTE3LjQgMTcuNEgxNXYyLjRoMi40di0yLjRabTEuMi05LjZoLTIuNHYyLjRoMi40VjcuOFoiLz48cGF0aCBkPSJNMjEuNiAzVjBoLTIuNHYzaC0zLjZWMGgtMi40djNoLTIuNHY2LjZINC41YTIuMSAyLjEgMCAxIDEgMC00LjJoMi43VjNINC41QTQuNSA0LjUgMCAwIDAgMCA3LjVWMjRoMjEuNnYtNi42aC0yLjR2NC4ySDIuNFYxMS41Yy41LjMgMS4yLjQgMS44LjVoNy41QTYuNiA2LjYgMCAwIDAgMjQgOVYzaC0yLjRabTAgNS43YTQuMiA0LjIgMCAxIDEtOC40IDBWNS40aDguNHYzLjNaIi8+PC9nPjwvc3ZnPg==';
60
63
  this._connecting = false;
64
+ /**
65
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
66
+ * increment this and use it to make sure that `transact` calls from the previous
67
+ * 'generation' don't continue to do work and throw exceptions.
68
+ */
69
+ this._connectionGeneration = 0;
61
70
  this._readyState = getIsSupported() ? walletAdapterBase.WalletReadyState.Loadable : walletAdapterBase.WalletReadyState.Unsupported;
62
71
  this._authorizationResultCache = config.authorizationResultCache;
63
72
  this._addressSelector = config.addressSelector;
@@ -221,6 +230,8 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
221
230
  disconnect() {
222
231
  return __awaiter(this, void 0, void 0, function* () {
223
232
  this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
233
+ this._connecting = false;
234
+ this._connectionGeneration++;
224
235
  delete this._authorizationResult;
225
236
  delete this._publicKey;
226
237
  delete this._selectedAddress;
@@ -232,10 +243,14 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
232
243
  return __awaiter(this, void 0, void 0, function* () {
233
244
  const walletUriBase = (_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.wallet_uri_base;
234
245
  const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
246
+ const currentConnectionGeneration = this._connectionGeneration;
235
247
  try {
236
248
  return yield mobileWalletAdapterProtocolWeb3js.transact(callback, config);
237
249
  }
238
250
  catch (e) {
251
+ if (this._connectionGeneration !== currentConnectionGeneration) {
252
+ yield new Promise(() => { }); // Never resolve.
253
+ }
239
254
  if (e instanceof Error &&
240
255
  e.name === 'SolanaMobileWalletAdapterError' &&
241
256
  e.code === 'ERROR_WALLET_NOT_FOUND') {
@@ -277,9 +292,43 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
277
292
  const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
278
293
  try {
279
294
  return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
280
- yield Promise.all([
295
+ function getTargetCommitment() {
296
+ let targetCommitment;
297
+ switch (connection.commitment) {
298
+ case 'confirmed':
299
+ case 'finalized':
300
+ case 'processed':
301
+ targetCommitment = connection.commitment;
302
+ break;
303
+ default:
304
+ targetCommitment = 'finalized';
305
+ }
306
+ let targetPreflightCommitment;
307
+ switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
308
+ case 'confirmed':
309
+ case 'finalized':
310
+ case 'processed':
311
+ targetPreflightCommitment = options.preflightCommitment;
312
+ break;
313
+ case undefined:
314
+ targetPreflightCommitment = targetCommitment;
315
+ default:
316
+ targetPreflightCommitment = 'finalized';
317
+ }
318
+ const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
319
+ ? 2
320
+ : targetPreflightCommitment === 'confirmed'
321
+ ? 1
322
+ : 0;
323
+ const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
324
+ return preflightCommitmentScore < targetCommitmentScore
325
+ ? targetPreflightCommitment
326
+ : targetCommitment;
327
+ }
328
+ const [capabilities, _1, _2] = yield Promise.all([
329
+ wallet.getCapabilities(),
281
330
  this.performReauthorization(wallet, authToken),
282
- 'version' in transaction
331
+ isVersionedTransaction(transaction)
283
332
  ? null
284
333
  : /**
285
334
  * Unlike versioned transactions, legacy `Transaction` objects
@@ -290,52 +339,32 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
290
339
  var _a;
291
340
  transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
292
341
  if (transaction.recentBlockhash == null) {
293
- let targetCommitment;
294
- switch (connection.commitment) {
295
- case 'confirmed':
296
- case 'finalized':
297
- case 'processed':
298
- targetCommitment = connection.commitment;
299
- break;
300
- default:
301
- targetCommitment = 'finalized';
302
- }
303
- let targetPreflightCommitment;
304
- switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
305
- case 'confirmed':
306
- case 'finalized':
307
- case 'processed':
308
- targetPreflightCommitment = options.preflightCommitment;
309
- break;
310
- case undefined:
311
- targetPreflightCommitment = targetCommitment;
312
- default:
313
- targetPreflightCommitment = 'finalized';
314
- }
315
- const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
316
- ? 2
317
- : targetPreflightCommitment === 'confirmed'
318
- ? 1
319
- : 0;
320
- const targetCommitmentScore = targetCommitment === 'finalized'
321
- ? 2
322
- : targetCommitment === 'confirmed'
323
- ? 1
324
- : 0;
325
342
  const { blockhash } = yield connection.getLatestBlockhash({
326
- commitment: preflightCommitmentScore < targetCommitmentScore
327
- ? targetPreflightCommitment
328
- : targetCommitment,
343
+ commitment: getTargetCommitment(),
329
344
  });
330
345
  transaction.recentBlockhash = blockhash;
331
346
  }
332
347
  }))(),
333
348
  ]);
334
- const signatures = yield wallet.signAndSendTransactions({
335
- minContextSlot,
336
- transactions: [transaction],
337
- });
338
- return signatures[0];
349
+ if (capabilities.supports_sign_and_send_transactions) {
350
+ const signatures = yield wallet.signAndSendTransactions({
351
+ minContextSlot,
352
+ transactions: [transaction],
353
+ });
354
+ return signatures[0];
355
+ }
356
+ else {
357
+ const [signedTransaction] = yield wallet.signTransactions({
358
+ transactions: [transaction],
359
+ });
360
+ if (isVersionedTransaction(signedTransaction)) {
361
+ return yield connection.sendTransaction(signedTransaction);
362
+ }
363
+ else {
364
+ const serializedTransaction = signedTransaction.serialize();
365
+ return yield connection.sendRawTransaction(serializedTransaction, Object.assign(Object.assign({}, options), { preflightCommitment: getTargetCommitment() }));
366
+ }
367
+ }
339
368
  }));
340
369
  }
341
370
  catch (error) {
@@ -1,8 +1,8 @@
1
- import { transact } from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';
2
1
  import { BaseMessageSignerWalletAdapter, WalletReadyState, WalletPublicKeyError, WalletNotReadyError, WalletConnectionError, WalletDisconnectedError, WalletNotConnectedError, WalletSignTransactionError, WalletSendTransactionError, WalletSignMessageError } from '@solana/wallet-adapter-base';
3
2
  import { PublicKey } from '@solana/web3.js';
3
+ import { transact } from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';
4
4
 
5
- /*! *****************************************************************************
5
+ /******************************************************************************
6
6
  Copyright (c) Microsoft Corporation.
7
7
 
8
8
  Permission to use, copy, modify, and/or distribute this software for any
@@ -47,6 +47,9 @@ function getPublicKeyFromAddress(address) {
47
47
  const publicKeyByteArray = toUint8Array(address);
48
48
  return new PublicKey(publicKeyByteArray);
49
49
  }
50
+ function isVersionedTransaction(transaction) {
51
+ return 'version' in transaction;
52
+ }
50
53
  class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
51
54
  constructor(config) {
52
55
  super();
@@ -57,6 +60,12 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
57
60
  this.url = 'https://solanamobile.com/wallets';
58
61
  this.icon = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI4IiB3aWR0aD0iMjgiIHZpZXdCb3g9Ii0zIDAgMjggMjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI0RDQjhGRiI+PHBhdGggZD0iTTE3LjQgMTcuNEgxNXYyLjRoMi40di0yLjRabTEuMi05LjZoLTIuNHYyLjRoMi40VjcuOFoiLz48cGF0aCBkPSJNMjEuNiAzVjBoLTIuNHYzaC0zLjZWMGgtMi40djNoLTIuNHY2LjZINC41YTIuMSAyLjEgMCAxIDEgMC00LjJoMi43VjNINC41QTQuNSA0LjUgMCAwIDAgMCA3LjVWMjRoMjEuNnYtNi42aC0yLjR2NC4ySDIuNFYxMS41Yy41LjMgMS4yLjQgMS44LjVoNy41QTYuNiA2LjYgMCAwIDAgMjQgOVYzaC0yLjRabTAgNS43YTQuMiA0LjIgMCAxIDEtOC40IDBWNS40aDguNHYzLjNaIi8+PC9nPjwvc3ZnPg==';
59
62
  this._connecting = false;
63
+ /**
64
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
65
+ * increment this and use it to make sure that `transact` calls from the previous
66
+ * 'generation' don't continue to do work and throw exceptions.
67
+ */
68
+ this._connectionGeneration = 0;
60
69
  this._readyState = getIsSupported() ? WalletReadyState.Loadable : WalletReadyState.Unsupported;
61
70
  this._authorizationResultCache = config.authorizationResultCache;
62
71
  this._addressSelector = config.addressSelector;
@@ -220,6 +229,8 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
220
229
  disconnect() {
221
230
  return __awaiter(this, void 0, void 0, function* () {
222
231
  this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
232
+ this._connecting = false;
233
+ this._connectionGeneration++;
223
234
  delete this._authorizationResult;
224
235
  delete this._publicKey;
225
236
  delete this._selectedAddress;
@@ -231,10 +242,14 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
231
242
  return __awaiter(this, void 0, void 0, function* () {
232
243
  const walletUriBase = (_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.wallet_uri_base;
233
244
  const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
245
+ const currentConnectionGeneration = this._connectionGeneration;
234
246
  try {
235
247
  return yield transact(callback, config);
236
248
  }
237
249
  catch (e) {
250
+ if (this._connectionGeneration !== currentConnectionGeneration) {
251
+ yield new Promise(() => { }); // Never resolve.
252
+ }
238
253
  if (e instanceof Error &&
239
254
  e.name === 'SolanaMobileWalletAdapterError' &&
240
255
  e.code === 'ERROR_WALLET_NOT_FOUND') {
@@ -276,9 +291,43 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
276
291
  const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
277
292
  try {
278
293
  return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
279
- yield Promise.all([
294
+ function getTargetCommitment() {
295
+ let targetCommitment;
296
+ switch (connection.commitment) {
297
+ case 'confirmed':
298
+ case 'finalized':
299
+ case 'processed':
300
+ targetCommitment = connection.commitment;
301
+ break;
302
+ default:
303
+ targetCommitment = 'finalized';
304
+ }
305
+ let targetPreflightCommitment;
306
+ switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
307
+ case 'confirmed':
308
+ case 'finalized':
309
+ case 'processed':
310
+ targetPreflightCommitment = options.preflightCommitment;
311
+ break;
312
+ case undefined:
313
+ targetPreflightCommitment = targetCommitment;
314
+ default:
315
+ targetPreflightCommitment = 'finalized';
316
+ }
317
+ const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
318
+ ? 2
319
+ : targetPreflightCommitment === 'confirmed'
320
+ ? 1
321
+ : 0;
322
+ const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
323
+ return preflightCommitmentScore < targetCommitmentScore
324
+ ? targetPreflightCommitment
325
+ : targetCommitment;
326
+ }
327
+ const [capabilities, _1, _2] = yield Promise.all([
328
+ wallet.getCapabilities(),
280
329
  this.performReauthorization(wallet, authToken),
281
- 'version' in transaction
330
+ isVersionedTransaction(transaction)
282
331
  ? null
283
332
  : /**
284
333
  * Unlike versioned transactions, legacy `Transaction` objects
@@ -289,52 +338,32 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
289
338
  var _a;
290
339
  transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
291
340
  if (transaction.recentBlockhash == null) {
292
- let targetCommitment;
293
- switch (connection.commitment) {
294
- case 'confirmed':
295
- case 'finalized':
296
- case 'processed':
297
- targetCommitment = connection.commitment;
298
- break;
299
- default:
300
- targetCommitment = 'finalized';
301
- }
302
- let targetPreflightCommitment;
303
- switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
304
- case 'confirmed':
305
- case 'finalized':
306
- case 'processed':
307
- targetPreflightCommitment = options.preflightCommitment;
308
- break;
309
- case undefined:
310
- targetPreflightCommitment = targetCommitment;
311
- default:
312
- targetPreflightCommitment = 'finalized';
313
- }
314
- const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
315
- ? 2
316
- : targetPreflightCommitment === 'confirmed'
317
- ? 1
318
- : 0;
319
- const targetCommitmentScore = targetCommitment === 'finalized'
320
- ? 2
321
- : targetCommitment === 'confirmed'
322
- ? 1
323
- : 0;
324
341
  const { blockhash } = yield connection.getLatestBlockhash({
325
- commitment: preflightCommitmentScore < targetCommitmentScore
326
- ? targetPreflightCommitment
327
- : targetCommitment,
342
+ commitment: getTargetCommitment(),
328
343
  });
329
344
  transaction.recentBlockhash = blockhash;
330
345
  }
331
346
  }))(),
332
347
  ]);
333
- const signatures = yield wallet.signAndSendTransactions({
334
- minContextSlot,
335
- transactions: [transaction],
336
- });
337
- return signatures[0];
348
+ if (capabilities.supports_sign_and_send_transactions) {
349
+ const signatures = yield wallet.signAndSendTransactions({
350
+ minContextSlot,
351
+ transactions: [transaction],
352
+ });
353
+ return signatures[0];
354
+ }
355
+ else {
356
+ const [signedTransaction] = yield wallet.signTransactions({
357
+ transactions: [transaction],
358
+ });
359
+ if (isVersionedTransaction(signedTransaction)) {
360
+ return yield connection.sendTransaction(signedTransaction);
361
+ }
362
+ else {
363
+ const serializedTransaction = signedTransaction.serialize();
364
+ return yield connection.sendRawTransaction(serializedTransaction, Object.assign(Object.assign({}, options), { preflightCommitment: getTargetCommitment() }));
365
+ }
366
+ }
338
367
  }));
339
368
  }
340
369
  catch (error) {
@@ -1,8 +1,8 @@
1
- import { transact } from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';
2
1
  import { BaseMessageSignerWalletAdapter, WalletReadyState, WalletPublicKeyError, WalletNotReadyError, WalletConnectionError, WalletDisconnectedError, WalletNotConnectedError, WalletSignTransactionError, WalletSendTransactionError, WalletSignMessageError } from '@solana/wallet-adapter-base';
3
2
  import { PublicKey } from '@solana/web3.js';
3
+ import { transact } from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';
4
4
 
5
- /*! *****************************************************************************
5
+ /******************************************************************************
6
6
  Copyright (c) Microsoft Corporation.
7
7
 
8
8
  Permission to use, copy, modify, and/or distribute this software for any
@@ -47,6 +47,9 @@ function getPublicKeyFromAddress(address) {
47
47
  const publicKeyByteArray = toUint8Array(address);
48
48
  return new PublicKey(publicKeyByteArray);
49
49
  }
50
+ function isVersionedTransaction(transaction) {
51
+ return 'version' in transaction;
52
+ }
50
53
  class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
51
54
  constructor(config) {
52
55
  super();
@@ -57,6 +60,12 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
57
60
  this.url = 'https://solanamobile.com/wallets';
58
61
  this.icon = 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjI4IiB3aWR0aD0iMjgiIHZpZXdCb3g9Ii0zIDAgMjggMjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI0RDQjhGRiI+PHBhdGggZD0iTTE3LjQgMTcuNEgxNXYyLjRoMi40di0yLjRabTEuMi05LjZoLTIuNHYyLjRoMi40VjcuOFoiLz48cGF0aCBkPSJNMjEuNiAzVjBoLTIuNHYzaC0zLjZWMGgtMi40djNoLTIuNHY2LjZINC41YTIuMSAyLjEgMCAxIDEgMC00LjJoMi43VjNINC41QTQuNSA0LjUgMCAwIDAgMCA3LjVWMjRoMjEuNnYtNi42aC0yLjR2NC4ySDIuNFYxMS41Yy41LjMgMS4yLjQgMS44LjVoNy41QTYuNiA2LjYgMCAwIDAgMjQgOVYzaC0yLjRabTAgNS43YTQuMiA0LjIgMCAxIDEtOC40IDBWNS40aDguNHYzLjNaIi8+PC9nPjwvc3ZnPg==';
59
62
  this._connecting = false;
63
+ /**
64
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
65
+ * increment this and use it to make sure that `transact` calls from the previous
66
+ * 'generation' don't continue to do work and throw exceptions.
67
+ */
68
+ this._connectionGeneration = 0;
60
69
  this._readyState = getIsSupported() ? WalletReadyState.Loadable : WalletReadyState.Unsupported;
61
70
  this._authorizationResultCache = config.authorizationResultCache;
62
71
  this._addressSelector = config.addressSelector;
@@ -220,6 +229,8 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
220
229
  disconnect() {
221
230
  return __awaiter(this, void 0, void 0, function* () {
222
231
  this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
232
+ this._connecting = false;
233
+ this._connectionGeneration++;
223
234
  delete this._authorizationResult;
224
235
  delete this._publicKey;
225
236
  delete this._selectedAddress;
@@ -231,10 +242,14 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
231
242
  return __awaiter(this, void 0, void 0, function* () {
232
243
  const walletUriBase = (_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.wallet_uri_base;
233
244
  const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
245
+ const currentConnectionGeneration = this._connectionGeneration;
234
246
  try {
235
247
  return yield transact(callback, config);
236
248
  }
237
249
  catch (e) {
250
+ if (this._connectionGeneration !== currentConnectionGeneration) {
251
+ yield new Promise(() => { }); // Never resolve.
252
+ }
238
253
  if (e instanceof Error &&
239
254
  e.name === 'SolanaMobileWalletAdapterError' &&
240
255
  e.code === 'ERROR_WALLET_NOT_FOUND') {
@@ -276,9 +291,43 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
276
291
  const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
277
292
  try {
278
293
  return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
279
- yield Promise.all([
294
+ function getTargetCommitment() {
295
+ let targetCommitment;
296
+ switch (connection.commitment) {
297
+ case 'confirmed':
298
+ case 'finalized':
299
+ case 'processed':
300
+ targetCommitment = connection.commitment;
301
+ break;
302
+ default:
303
+ targetCommitment = 'finalized';
304
+ }
305
+ let targetPreflightCommitment;
306
+ switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
307
+ case 'confirmed':
308
+ case 'finalized':
309
+ case 'processed':
310
+ targetPreflightCommitment = options.preflightCommitment;
311
+ break;
312
+ case undefined:
313
+ targetPreflightCommitment = targetCommitment;
314
+ default:
315
+ targetPreflightCommitment = 'finalized';
316
+ }
317
+ const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
318
+ ? 2
319
+ : targetPreflightCommitment === 'confirmed'
320
+ ? 1
321
+ : 0;
322
+ const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
323
+ return preflightCommitmentScore < targetCommitmentScore
324
+ ? targetPreflightCommitment
325
+ : targetCommitment;
326
+ }
327
+ const [capabilities, _1, _2] = yield Promise.all([
328
+ wallet.getCapabilities(),
280
329
  this.performReauthorization(wallet, authToken),
281
- 'version' in transaction
330
+ isVersionedTransaction(transaction)
282
331
  ? null
283
332
  : /**
284
333
  * Unlike versioned transactions, legacy `Transaction` objects
@@ -289,52 +338,32 @@ class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
289
338
  var _a;
290
339
  transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
291
340
  if (transaction.recentBlockhash == null) {
292
- let targetCommitment;
293
- switch (connection.commitment) {
294
- case 'confirmed':
295
- case 'finalized':
296
- case 'processed':
297
- targetCommitment = connection.commitment;
298
- break;
299
- default:
300
- targetCommitment = 'finalized';
301
- }
302
- let targetPreflightCommitment;
303
- switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
304
- case 'confirmed':
305
- case 'finalized':
306
- case 'processed':
307
- targetPreflightCommitment = options.preflightCommitment;
308
- break;
309
- case undefined:
310
- targetPreflightCommitment = targetCommitment;
311
- default:
312
- targetPreflightCommitment = 'finalized';
313
- }
314
- const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
315
- ? 2
316
- : targetPreflightCommitment === 'confirmed'
317
- ? 1
318
- : 0;
319
- const targetCommitmentScore = targetCommitment === 'finalized'
320
- ? 2
321
- : targetCommitment === 'confirmed'
322
- ? 1
323
- : 0;
324
341
  const { blockhash } = yield connection.getLatestBlockhash({
325
- commitment: preflightCommitmentScore < targetCommitmentScore
326
- ? targetPreflightCommitment
327
- : targetCommitment,
342
+ commitment: getTargetCommitment(),
328
343
  });
329
344
  transaction.recentBlockhash = blockhash;
330
345
  }
331
346
  }))(),
332
347
  ]);
333
- const signatures = yield wallet.signAndSendTransactions({
334
- minContextSlot,
335
- transactions: [transaction],
336
- });
337
- return signatures[0];
348
+ if (capabilities.supports_sign_and_send_transactions) {
349
+ const signatures = yield wallet.signAndSendTransactions({
350
+ minContextSlot,
351
+ transactions: [transaction],
352
+ });
353
+ return signatures[0];
354
+ }
355
+ else {
356
+ const [signedTransaction] = yield wallet.signTransactions({
357
+ transactions: [transaction],
358
+ });
359
+ if (isVersionedTransaction(signedTransaction)) {
360
+ return yield connection.sendTransaction(signedTransaction);
361
+ }
362
+ else {
363
+ const serializedTransaction = signedTransaction.serialize();
364
+ return yield connection.sendRawTransaction(serializedTransaction, Object.assign(Object.assign({}, options), { preflightCommitment: getTargetCommitment() }));
365
+ }
366
+ }
338
367
  }));
339
368
  }
340
369
  catch (error) {
@@ -1,7 +1,7 @@
1
- import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
2
1
  import { BaseMessageSignerWalletAdapter, WalletName, WalletReadyState } from "@solana/wallet-adapter-base";
3
2
  import { Connection, PublicKey, SendOptions, TransactionSignature, TransactionVersion, VersionedTransaction } from "@solana/web3.js";
4
3
  import { Transaction as LegacyTransaction } from "@solana/web3.js";
4
+ import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
5
5
  interface AuthorizationResultCache {
6
6
  clear(): Promise<void>;
7
7
  get(): Promise<AuthorizationResult | undefined>;
@@ -21,6 +21,12 @@ declare class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
21
21
  private _authorizationResult;
22
22
  private _authorizationResultCache;
23
23
  private _connecting;
24
+ /**
25
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
26
+ * increment this and use it to make sure that `transact` calls from the previous
27
+ * 'generation' don't continue to do work and throw exceptions.
28
+ */
29
+ private _connectionGeneration;
24
30
  private _cluster;
25
31
  private _onWalletNotFound;
26
32
  private _publicKey;
@@ -1,7 +1,7 @@
1
- import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
2
1
  import { BaseMessageSignerWalletAdapter, WalletName, WalletReadyState } from "@solana/wallet-adapter-base";
3
2
  import { Connection, PublicKey, SendOptions, TransactionSignature, TransactionVersion, VersionedTransaction } from "@solana/web3.js";
4
3
  import { Transaction as LegacyTransaction } from "@solana/web3.js";
4
+ import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
5
5
  interface AuthorizationResultCache {
6
6
  clear(): Promise<void>;
7
7
  get(): Promise<AuthorizationResult | undefined>;
@@ -21,6 +21,12 @@ declare class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
21
21
  private _authorizationResult;
22
22
  private _authorizationResultCache;
23
23
  private _connecting;
24
+ /**
25
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
26
+ * increment this and use it to make sure that `transact` calls from the previous
27
+ * 'generation' don't continue to do work and throw exceptions.
28
+ */
29
+ private _connectionGeneration;
24
30
  private _cluster;
25
31
  private _onWalletNotFound;
26
32
  private _publicKey;
@@ -1,7 +1,7 @@
1
- import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
2
1
  import { BaseMessageSignerWalletAdapter, WalletName, WalletReadyState } from "@solana/wallet-adapter-base";
3
2
  import { Connection, PublicKey, SendOptions, TransactionSignature, TransactionVersion, VersionedTransaction } from "@solana/web3.js";
4
3
  import { Transaction as LegacyTransaction } from "@solana/web3.js";
4
+ import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
5
5
  interface AuthorizationResultCache {
6
6
  clear(): Promise<void>;
7
7
  get(): Promise<AuthorizationResult | undefined>;
@@ -21,6 +21,12 @@ declare class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
21
21
  private _authorizationResult;
22
22
  private _authorizationResultCache;
23
23
  private _connecting;
24
+ /**
25
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
26
+ * increment this and use it to make sure that `transact` calls from the previous
27
+ * 'generation' don't continue to do work and throw exceptions.
28
+ */
29
+ private _connectionGeneration;
24
30
  private _cluster;
25
31
  private _onWalletNotFound;
26
32
  private _publicKey;
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
1
  {
2
2
  "name": "@solana-mobile/wallet-adapter-mobile",
3
3
  "description": "An adapter for mobile wallet apps that conform to the Solana Mobile Wallet Adapter protocol",
4
- "version": "0.9.5",
4
+ "version": "0.9.7",
5
5
  "author": "Steven Luscher <steven.luscher@solanamobile.com>",
6
6
  "repository": "https://github.com/solana-mobile/mobile-wallet-adapter",
7
7
  "license": "Apache-2.0",
8
8
  "type": "module",
9
9
  "sideEffects": false,
10
10
  "main": "lib/cjs/index.js",
11
- "module": "lib/esm/index.mjs",
11
+ "module": "lib/esm/index.js",
12
12
  "react-native": "lib/cjs/index.native.js",
13
13
  "types": "lib/types/index.d.ts",
14
14
  "browser": {
15
15
  "./lib/cjs/index.js": "./lib/cjs/index.browser.js",
16
- "./lib/esm/index.mjs": "./lib/esm/index.browser.mjs"
16
+ "./lib/esm/index.js": "./lib/esm/index.browser.js"
17
17
  },
18
18
  "exports": {
19
19
  "./package.json": "./package.json",
20
20
  ".": {
21
- "import": "./lib/esm/index.mjs",
21
+ "import": "./lib/esm/index.js",
22
22
  "require": "./lib/cjs/index.js"
23
23
  }
24
24
  },
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@react-native-async-storage/async-storage": "^1.17.7",
44
- "@solana-mobile/mobile-wallet-adapter-protocol-web3js": "^0.9.5",
44
+ "@solana-mobile/mobile-wallet-adapter-protocol-web3js": "^0.9.7",
45
45
  "@solana/wallet-adapter-base": "^0.9.17",
46
46
  "js-base64": "^3.7.2"
47
47
  },
@@ -51,5 +51,5 @@
51
51
  "cross-env": "^7.0.3",
52
52
  "shx": "^0.3.4"
53
53
  },
54
- "gitHead": "d3da860526efa336e0bd4c4d680f0f38b1d8f146"
54
+ "gitHead": "91473dbc1754c0161994a22c2895c43c36f9377d"
55
55
  }
@@ -1,59 +0,0 @@
1
- import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
2
- import { BaseMessageSignerWalletAdapter, WalletName, WalletReadyState } from "@solana/wallet-adapter-base";
3
- import { Connection, PublicKey, SendOptions, TransactionSignature, TransactionVersion, VersionedTransaction } from "@solana/web3.js";
4
- import { Transaction as LegacyTransaction } from "@solana/web3.js";
5
- interface AuthorizationResultCache {
6
- clear(): Promise<void>;
7
- get(): Promise<AuthorizationResult | undefined>;
8
- set(authorizationResult: AuthorizationResult): Promise<void>;
9
- }
10
- interface AddressSelector {
11
- select(addresses: Base64EncodedAddress[]): Promise<Base64EncodedAddress>;
12
- }
13
- declare const SolanaMobileWalletAdapterWalletName: WalletName<string>;
14
- declare class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
15
- readonly supportedTransactionVersions: Set<TransactionVersion>;
16
- name: WalletName<string>;
17
- url: string;
18
- icon: string;
19
- private _addressSelector;
20
- private _appIdentity;
21
- private _authorizationResult;
22
- private _authorizationResultCache;
23
- private _connecting;
24
- private _cluster;
25
- private _onWalletNotFound;
26
- private _publicKey;
27
- private _readyState;
28
- private _selectedAddress;
29
- constructor(config: {
30
- addressSelector: AddressSelector;
31
- appIdentity: AppIdentity;
32
- authorizationResultCache: AuthorizationResultCache;
33
- cluster: Cluster;
34
- onWalletNotFound: (mobileWalletAdapter: SolanaMobileWalletAdapter) => Promise<void>;
35
- });
36
- get publicKey(): PublicKey | null;
37
- get connected(): boolean;
38
- get connecting(): boolean;
39
- get readyState(): WalletReadyState;
40
- private declareWalletAsInstalled;
41
- private runWithGuard;
42
- autoConnect_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(): Promise<void>;
43
- connect(): Promise<void>;
44
- private handleAuthorizationResult;
45
- private performReauthorization;
46
- disconnect(): Promise<void>;
47
- private transact;
48
- private assertIsAuthorized;
49
- private performSignTransactions;
50
- sendTransaction<T extends LegacyTransaction | VersionedTransaction>(transaction: T, connection: Connection, options?: SendOptions): Promise<TransactionSignature>;
51
- signTransaction<T extends LegacyTransaction | VersionedTransaction>(transaction: T): Promise<T>;
52
- signAllTransactions<T extends LegacyTransaction | VersionedTransaction>(transactions: T[]): Promise<T[]>;
53
- signMessage(message: Uint8Array): Promise<Uint8Array>;
54
- }
55
- declare function createDefaultAddressSelector(): AddressSelector;
56
- declare function createDefaultAuthorizationResultCache(): AuthorizationResultCache;
57
- declare function createDefaultWalletNotFoundHandler(): (mobileWalletAdapter: SolanaMobileWalletAdapter) => Promise<void>;
58
- export { AuthorizationResultCache, AddressSelector, SolanaMobileWalletAdapterWalletName, SolanaMobileWalletAdapter, createDefaultAddressSelector, createDefaultAuthorizationResultCache, createDefaultWalletNotFoundHandler };
59
- //# sourceMappingURL=index.browser.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.browser.d.mts","sourceRoot":"","sources":["../../src/index.ts","../../src/base64Utils.ts","../../src/getIsSupported.ts","../../src/adapter.ts","../../src/createDefaultAddressSelector.ts","../../src/createDefaultAuthorizationResultCache.ts","../../src/createDefaultWalletNotFoundHandler.ts"],"names":[],"mappings":""}
@@ -1,59 +0,0 @@
1
- import { AppIdentity, AuthorizationResult, Base64EncodedAddress, Cluster } from "@solana-mobile/mobile-wallet-adapter-protocol";
2
- import { BaseMessageSignerWalletAdapter, WalletName, WalletReadyState } from "@solana/wallet-adapter-base";
3
- import { Connection, PublicKey, SendOptions, TransactionSignature, TransactionVersion, VersionedTransaction } from "@solana/web3.js";
4
- import { Transaction as LegacyTransaction } from "@solana/web3.js";
5
- interface AuthorizationResultCache {
6
- clear(): Promise<void>;
7
- get(): Promise<AuthorizationResult | undefined>;
8
- set(authorizationResult: AuthorizationResult): Promise<void>;
9
- }
10
- interface AddressSelector {
11
- select(addresses: Base64EncodedAddress[]): Promise<Base64EncodedAddress>;
12
- }
13
- declare const SolanaMobileWalletAdapterWalletName: WalletName<string>;
14
- declare class SolanaMobileWalletAdapter extends BaseMessageSignerWalletAdapter {
15
- readonly supportedTransactionVersions: Set<TransactionVersion>;
16
- name: WalletName<string>;
17
- url: string;
18
- icon: string;
19
- private _addressSelector;
20
- private _appIdentity;
21
- private _authorizationResult;
22
- private _authorizationResultCache;
23
- private _connecting;
24
- private _cluster;
25
- private _onWalletNotFound;
26
- private _publicKey;
27
- private _readyState;
28
- private _selectedAddress;
29
- constructor(config: {
30
- addressSelector: AddressSelector;
31
- appIdentity: AppIdentity;
32
- authorizationResultCache: AuthorizationResultCache;
33
- cluster: Cluster;
34
- onWalletNotFound: (mobileWalletAdapter: SolanaMobileWalletAdapter) => Promise<void>;
35
- });
36
- get publicKey(): PublicKey | null;
37
- get connected(): boolean;
38
- get connecting(): boolean;
39
- get readyState(): WalletReadyState;
40
- private declareWalletAsInstalled;
41
- private runWithGuard;
42
- autoConnect_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(): Promise<void>;
43
- connect(): Promise<void>;
44
- private handleAuthorizationResult;
45
- private performReauthorization;
46
- disconnect(): Promise<void>;
47
- private transact;
48
- private assertIsAuthorized;
49
- private performSignTransactions;
50
- sendTransaction<T extends LegacyTransaction | VersionedTransaction>(transaction: T, connection: Connection, options?: SendOptions): Promise<TransactionSignature>;
51
- signTransaction<T extends LegacyTransaction | VersionedTransaction>(transaction: T): Promise<T>;
52
- signAllTransactions<T extends LegacyTransaction | VersionedTransaction>(transactions: T[]): Promise<T[]>;
53
- signMessage(message: Uint8Array): Promise<Uint8Array>;
54
- }
55
- declare function createDefaultAddressSelector(): AddressSelector;
56
- declare function createDefaultAuthorizationResultCache(): AuthorizationResultCache;
57
- declare function createDefaultWalletNotFoundHandler(): (mobileWalletAdapter: SolanaMobileWalletAdapter) => Promise<void>;
58
- export { AuthorizationResultCache, AddressSelector, SolanaMobileWalletAdapterWalletName, SolanaMobileWalletAdapter, createDefaultAddressSelector, createDefaultAuthorizationResultCache, createDefaultWalletNotFoundHandler };
59
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/index.ts","../../src/base64Utils.ts","../../src/getIsSupported.ts","../../src/adapter.ts","../../src/createDefaultAddressSelector.ts","../../src/createDefaultAuthorizationResultCache.ts","../../src/createDefaultWalletNotFoundHandler.ts"],"names":[],"mappings":""}