@solana-mobile/wallet-adapter-mobile 0.0.1-alpha.8 → 0.9.0
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 +2 -0
- package/lib/cjs/index.browser.js +93 -26
- package/lib/cjs/index.js +93 -26
- package/lib/cjs/index.native.js +93 -26
- package/lib/esm/index.browser.mjs +93 -27
- package/lib/esm/index.mjs +93 -27
- package/lib/types/index.browser.d.mts +10 -3
- package/lib/types/index.browser.d.mts.map +1 -1
- package/lib/types/index.browser.d.ts +10 -3
- package/lib/types/index.browser.d.ts.map +1 -1
- package/lib/types/index.d.mts +10 -3
- package/lib/types/index.d.mts.map +1 -1
- package/lib/types/index.d.ts +10 -3
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.native.d.ts +10 -3
- package/lib/types/index.native.d.ts.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ Create an instance of the mobile wallet adapter like this.
|
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
12
|
new SolanaMobileWalletAdapter({
|
|
13
|
+
addressSelector: createDefaultAddressSelector(),
|
|
13
14
|
appIdentity: {
|
|
14
15
|
name: 'My app',
|
|
15
16
|
uri: 'https://myapp.io',
|
|
@@ -24,6 +25,7 @@ Use that adapter instance alongside the other adapters used by your app.
|
|
|
24
25
|
```typescript
|
|
25
26
|
const wallets = useMemo(() => [
|
|
26
27
|
new SolanaMobileWalletAdapter({
|
|
28
|
+
addressSelector: createDefaultAddressSelector(),
|
|
27
29
|
appIdentity: {
|
|
28
30
|
name: 'My app',
|
|
29
31
|
uri: 'https://myapp.io',
|
package/lib/cjs/index.browser.js
CHANGED
|
@@ -60,6 +60,7 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
60
60
|
this._connecting = false;
|
|
61
61
|
this._readyState = getIsSupported() ? walletAdapterBase.WalletReadyState.Loadable : walletAdapterBase.WalletReadyState.Unsupported;
|
|
62
62
|
this._authorizationResultCache = config.authorizationResultCache;
|
|
63
|
+
this._addressSelector = config.addressSelector;
|
|
63
64
|
this._appIdentity = config.appIdentity;
|
|
64
65
|
this._cluster = config.cluster;
|
|
65
66
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Unsupported) {
|
|
@@ -74,11 +75,9 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
get publicKey() {
|
|
77
|
-
if (this._publicKey == null && this.
|
|
78
|
+
if (this._publicKey == null && this._selectedAddress != null) {
|
|
78
79
|
try {
|
|
79
|
-
this._publicKey = getPublicKeyFromAddress(
|
|
80
|
-
// TODO(#44): support multiple addresses
|
|
81
|
-
this._authorizationResult.addresses[0]);
|
|
80
|
+
this._publicKey = getPublicKeyFromAddress(this._selectedAddress);
|
|
82
81
|
}
|
|
83
82
|
catch (e) {
|
|
84
83
|
throw new walletAdapterBase.WalletPublicKeyError((e instanceof Error && (e === null || e === void 0 ? void 0 : e.message)) || 'Unknown error', e);
|
|
@@ -120,8 +119,9 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
120
119
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Installed) {
|
|
121
120
|
this.emit('readyStateChange', (this._readyState = walletAdapterBase.WalletReadyState.Installed));
|
|
122
121
|
}
|
|
122
|
+
this._selectedAddress = yield this._addressSelector.select(cachedAuthorizationResult.accounts.map(({ address }) => address));
|
|
123
123
|
this.emit('connect',
|
|
124
|
-
// Having just set
|
|
124
|
+
// Having just set `this._selectedAddress`, `this.publicKey` is definitely non-null
|
|
125
125
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
126
126
|
this.publicKey);
|
|
127
127
|
return;
|
|
@@ -147,23 +147,33 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
147
147
|
handleAuthorizationResult(authorizationResult) {
|
|
148
148
|
var _a;
|
|
149
149
|
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
const
|
|
150
|
+
const didPublicKeysChange =
|
|
151
|
+
// Case 1: We started from having no authorization.
|
|
152
|
+
this._authorizationResult == null ||
|
|
153
|
+
// Case 2: The number of authorized accounts changed.
|
|
154
|
+
((_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.accounts.length) !== authorizationResult.accounts.length ||
|
|
155
|
+
// Case 3: The new list of addresses isn't exactly the same as the old list, in the same order.
|
|
156
|
+
this._authorizationResult.accounts.some((account, ii) => account.address !== authorizationResult.accounts[ii].address);
|
|
151
157
|
this._authorizationResult = authorizationResult;
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
this.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
if (didPublicKeysChange) {
|
|
159
|
+
const nextSelectedAddress = yield this._addressSelector.select(authorizationResult.accounts.map(({ address }) => address));
|
|
160
|
+
if (nextSelectedAddress !== this._selectedAddress) {
|
|
161
|
+
this._selectedAddress = nextSelectedAddress;
|
|
162
|
+
delete this._publicKey;
|
|
163
|
+
this.emit('connect',
|
|
164
|
+
// Having just set `this._selectedAddress`, `this.publicKey` is definitely non-null
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
166
|
+
this.publicKey);
|
|
167
|
+
}
|
|
158
168
|
}
|
|
159
169
|
yield this._authorizationResultCache.set(authorizationResult);
|
|
160
170
|
});
|
|
161
171
|
}
|
|
162
|
-
performReauthorization(wallet,
|
|
172
|
+
performReauthorization(wallet, authToken) {
|
|
163
173
|
return __awaiter(this, void 0, void 0, function* () {
|
|
164
174
|
try {
|
|
165
175
|
const authorizationResult = yield wallet.reauthorize({
|
|
166
|
-
auth_token:
|
|
176
|
+
auth_token: authToken,
|
|
167
177
|
});
|
|
168
178
|
this.handleAuthorizationResult(authorizationResult); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
169
179
|
}
|
|
@@ -178,6 +188,7 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
178
188
|
this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
179
189
|
delete this._authorizationResult;
|
|
180
190
|
delete this._publicKey;
|
|
191
|
+
delete this._selectedAddress;
|
|
181
192
|
this.emit('disconnect');
|
|
182
193
|
});
|
|
183
194
|
}
|
|
@@ -190,17 +201,19 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
190
201
|
});
|
|
191
202
|
}
|
|
192
203
|
assertIsAuthorized() {
|
|
193
|
-
|
|
194
|
-
if (!authorizationResult)
|
|
204
|
+
if (!this._authorizationResult || !this._selectedAddress)
|
|
195
205
|
throw new walletAdapterBase.WalletNotConnectedError();
|
|
196
|
-
return
|
|
206
|
+
return {
|
|
207
|
+
authToken: this._authorizationResult.auth_token,
|
|
208
|
+
selectedAddress: this._selectedAddress,
|
|
209
|
+
};
|
|
197
210
|
}
|
|
198
211
|
performSignTransactions(transactions) {
|
|
199
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
const
|
|
213
|
+
const { authToken } = this.assertIsAuthorized();
|
|
201
214
|
try {
|
|
202
215
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
203
|
-
yield this.performReauthorization(wallet,
|
|
216
|
+
yield this.performReauthorization(wallet, authToken);
|
|
204
217
|
const signedTransactions = yield wallet.signTransactions({
|
|
205
218
|
transactions,
|
|
206
219
|
});
|
|
@@ -212,16 +225,58 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
212
225
|
}
|
|
213
226
|
});
|
|
214
227
|
}
|
|
215
|
-
sendTransaction(transaction, connection,
|
|
228
|
+
sendTransaction(transaction, connection, options) {
|
|
216
229
|
return __awaiter(this, void 0, void 0, function* () {
|
|
217
230
|
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
218
|
-
const
|
|
231
|
+
const { authToken } = this.assertIsAuthorized();
|
|
232
|
+
const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
|
|
219
233
|
try {
|
|
220
234
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
221
|
-
|
|
235
|
+
var _a;
|
|
236
|
+
let targetCommitment;
|
|
237
|
+
switch (connection.commitment) {
|
|
238
|
+
case 'confirmed':
|
|
239
|
+
case 'finalized':
|
|
240
|
+
case 'processed':
|
|
241
|
+
targetCommitment = connection.commitment;
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
targetCommitment = 'finalized';
|
|
245
|
+
}
|
|
246
|
+
let targetPreflightCommitment;
|
|
247
|
+
switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
|
|
248
|
+
case 'confirmed':
|
|
249
|
+
case 'finalized':
|
|
250
|
+
case 'processed':
|
|
251
|
+
targetPreflightCommitment = options.preflightCommitment;
|
|
252
|
+
break;
|
|
253
|
+
case undefined:
|
|
254
|
+
targetPreflightCommitment = targetCommitment;
|
|
255
|
+
default:
|
|
256
|
+
targetPreflightCommitment = 'finalized';
|
|
257
|
+
}
|
|
258
|
+
yield Promise.all([
|
|
259
|
+
this.performReauthorization(wallet, authToken),
|
|
260
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
261
|
+
if (transaction.recentBlockhash == null) {
|
|
262
|
+
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
263
|
+
? 2
|
|
264
|
+
: targetPreflightCommitment === 'confirmed'
|
|
265
|
+
? 1
|
|
266
|
+
: 0;
|
|
267
|
+
const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
|
|
268
|
+
const { blockhash } = yield connection.getLatestBlockhash({
|
|
269
|
+
commitment: preflightCommitmentScore < targetCommitmentScore
|
|
270
|
+
? targetPreflightCommitment
|
|
271
|
+
: targetCommitment,
|
|
272
|
+
});
|
|
273
|
+
transaction.recentBlockhash = blockhash;
|
|
274
|
+
}
|
|
275
|
+
}))(),
|
|
276
|
+
]);
|
|
277
|
+
transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
|
|
222
278
|
const signatures = yield wallet.signAndSendTransactions({
|
|
223
|
-
|
|
224
|
-
fee_payer: transaction.feePayer,
|
|
279
|
+
minContextSlot,
|
|
225
280
|
transactions: [transaction],
|
|
226
281
|
});
|
|
227
282
|
return signatures[0];
|
|
@@ -252,11 +307,12 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
252
307
|
signMessage(message) {
|
|
253
308
|
return __awaiter(this, void 0, void 0, function* () {
|
|
254
309
|
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
255
|
-
const
|
|
310
|
+
const { authToken, selectedAddress } = this.assertIsAuthorized();
|
|
256
311
|
try {
|
|
257
312
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
258
|
-
yield this.performReauthorization(wallet,
|
|
313
|
+
yield this.performReauthorization(wallet, authToken);
|
|
259
314
|
const [signedMessage] = yield wallet.signMessages({
|
|
315
|
+
addresses: [selectedAddress],
|
|
260
316
|
payloads: [message],
|
|
261
317
|
});
|
|
262
318
|
const signature = signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES);
|
|
@@ -271,6 +327,16 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
271
327
|
}
|
|
272
328
|
}
|
|
273
329
|
|
|
330
|
+
function createDefaultAddressSelector() {
|
|
331
|
+
return {
|
|
332
|
+
select(addresses) {
|
|
333
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
334
|
+
return addresses[0];
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
274
340
|
const CACHE_KEY = 'SolanaMobileWalletAdapterDefaultAuthorizationCache';
|
|
275
341
|
function createDefaultAuthorizationResultCache() {
|
|
276
342
|
let storage;
|
|
@@ -321,4 +387,5 @@ function createDefaultAuthorizationResultCache() {
|
|
|
321
387
|
|
|
322
388
|
exports.SolanaMobileWalletAdapter = SolanaMobileWalletAdapter;
|
|
323
389
|
exports.SolanaMobileWalletAdapterWalletName = SolanaMobileWalletAdapterWalletName;
|
|
390
|
+
exports.createDefaultAddressSelector = createDefaultAddressSelector;
|
|
324
391
|
exports.createDefaultAuthorizationResultCache = createDefaultAuthorizationResultCache;
|
package/lib/cjs/index.js
CHANGED
|
@@ -60,6 +60,7 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
60
60
|
this._connecting = false;
|
|
61
61
|
this._readyState = getIsSupported() ? walletAdapterBase.WalletReadyState.Loadable : walletAdapterBase.WalletReadyState.Unsupported;
|
|
62
62
|
this._authorizationResultCache = config.authorizationResultCache;
|
|
63
|
+
this._addressSelector = config.addressSelector;
|
|
63
64
|
this._appIdentity = config.appIdentity;
|
|
64
65
|
this._cluster = config.cluster;
|
|
65
66
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Unsupported) {
|
|
@@ -74,11 +75,9 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
get publicKey() {
|
|
77
|
-
if (this._publicKey == null && this.
|
|
78
|
+
if (this._publicKey == null && this._selectedAddress != null) {
|
|
78
79
|
try {
|
|
79
|
-
this._publicKey = getPublicKeyFromAddress(
|
|
80
|
-
// TODO(#44): support multiple addresses
|
|
81
|
-
this._authorizationResult.addresses[0]);
|
|
80
|
+
this._publicKey = getPublicKeyFromAddress(this._selectedAddress);
|
|
82
81
|
}
|
|
83
82
|
catch (e) {
|
|
84
83
|
throw new walletAdapterBase.WalletPublicKeyError((e instanceof Error && (e === null || e === void 0 ? void 0 : e.message)) || 'Unknown error', e);
|
|
@@ -120,8 +119,9 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
120
119
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Installed) {
|
|
121
120
|
this.emit('readyStateChange', (this._readyState = walletAdapterBase.WalletReadyState.Installed));
|
|
122
121
|
}
|
|
122
|
+
this._selectedAddress = yield this._addressSelector.select(cachedAuthorizationResult.accounts.map(({ address }) => address));
|
|
123
123
|
this.emit('connect',
|
|
124
|
-
// Having just set
|
|
124
|
+
// Having just set `this._selectedAddress`, `this.publicKey` is definitely non-null
|
|
125
125
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
126
126
|
this.publicKey);
|
|
127
127
|
return;
|
|
@@ -147,23 +147,33 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
147
147
|
handleAuthorizationResult(authorizationResult) {
|
|
148
148
|
var _a;
|
|
149
149
|
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
const
|
|
150
|
+
const didPublicKeysChange =
|
|
151
|
+
// Case 1: We started from having no authorization.
|
|
152
|
+
this._authorizationResult == null ||
|
|
153
|
+
// Case 2: The number of authorized accounts changed.
|
|
154
|
+
((_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.accounts.length) !== authorizationResult.accounts.length ||
|
|
155
|
+
// Case 3: The new list of addresses isn't exactly the same as the old list, in the same order.
|
|
156
|
+
this._authorizationResult.accounts.some((account, ii) => account.address !== authorizationResult.accounts[ii].address);
|
|
151
157
|
this._authorizationResult = authorizationResult;
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
this.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
if (didPublicKeysChange) {
|
|
159
|
+
const nextSelectedAddress = yield this._addressSelector.select(authorizationResult.accounts.map(({ address }) => address));
|
|
160
|
+
if (nextSelectedAddress !== this._selectedAddress) {
|
|
161
|
+
this._selectedAddress = nextSelectedAddress;
|
|
162
|
+
delete this._publicKey;
|
|
163
|
+
this.emit('connect',
|
|
164
|
+
// Having just set `this._selectedAddress`, `this.publicKey` is definitely non-null
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
166
|
+
this.publicKey);
|
|
167
|
+
}
|
|
158
168
|
}
|
|
159
169
|
yield this._authorizationResultCache.set(authorizationResult);
|
|
160
170
|
});
|
|
161
171
|
}
|
|
162
|
-
performReauthorization(wallet,
|
|
172
|
+
performReauthorization(wallet, authToken) {
|
|
163
173
|
return __awaiter(this, void 0, void 0, function* () {
|
|
164
174
|
try {
|
|
165
175
|
const authorizationResult = yield wallet.reauthorize({
|
|
166
|
-
auth_token:
|
|
176
|
+
auth_token: authToken,
|
|
167
177
|
});
|
|
168
178
|
this.handleAuthorizationResult(authorizationResult); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
169
179
|
}
|
|
@@ -178,6 +188,7 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
178
188
|
this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
179
189
|
delete this._authorizationResult;
|
|
180
190
|
delete this._publicKey;
|
|
191
|
+
delete this._selectedAddress;
|
|
181
192
|
this.emit('disconnect');
|
|
182
193
|
});
|
|
183
194
|
}
|
|
@@ -190,17 +201,19 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
190
201
|
});
|
|
191
202
|
}
|
|
192
203
|
assertIsAuthorized() {
|
|
193
|
-
|
|
194
|
-
if (!authorizationResult)
|
|
204
|
+
if (!this._authorizationResult || !this._selectedAddress)
|
|
195
205
|
throw new walletAdapterBase.WalletNotConnectedError();
|
|
196
|
-
return
|
|
206
|
+
return {
|
|
207
|
+
authToken: this._authorizationResult.auth_token,
|
|
208
|
+
selectedAddress: this._selectedAddress,
|
|
209
|
+
};
|
|
197
210
|
}
|
|
198
211
|
performSignTransactions(transactions) {
|
|
199
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
const
|
|
213
|
+
const { authToken } = this.assertIsAuthorized();
|
|
201
214
|
try {
|
|
202
215
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
203
|
-
yield this.performReauthorization(wallet,
|
|
216
|
+
yield this.performReauthorization(wallet, authToken);
|
|
204
217
|
const signedTransactions = yield wallet.signTransactions({
|
|
205
218
|
transactions,
|
|
206
219
|
});
|
|
@@ -212,16 +225,58 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
212
225
|
}
|
|
213
226
|
});
|
|
214
227
|
}
|
|
215
|
-
sendTransaction(transaction, connection,
|
|
228
|
+
sendTransaction(transaction, connection, options) {
|
|
216
229
|
return __awaiter(this, void 0, void 0, function* () {
|
|
217
230
|
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
218
|
-
const
|
|
231
|
+
const { authToken } = this.assertIsAuthorized();
|
|
232
|
+
const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
|
|
219
233
|
try {
|
|
220
234
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
221
|
-
|
|
235
|
+
var _a;
|
|
236
|
+
let targetCommitment;
|
|
237
|
+
switch (connection.commitment) {
|
|
238
|
+
case 'confirmed':
|
|
239
|
+
case 'finalized':
|
|
240
|
+
case 'processed':
|
|
241
|
+
targetCommitment = connection.commitment;
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
targetCommitment = 'finalized';
|
|
245
|
+
}
|
|
246
|
+
let targetPreflightCommitment;
|
|
247
|
+
switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
|
|
248
|
+
case 'confirmed':
|
|
249
|
+
case 'finalized':
|
|
250
|
+
case 'processed':
|
|
251
|
+
targetPreflightCommitment = options.preflightCommitment;
|
|
252
|
+
break;
|
|
253
|
+
case undefined:
|
|
254
|
+
targetPreflightCommitment = targetCommitment;
|
|
255
|
+
default:
|
|
256
|
+
targetPreflightCommitment = 'finalized';
|
|
257
|
+
}
|
|
258
|
+
yield Promise.all([
|
|
259
|
+
this.performReauthorization(wallet, authToken),
|
|
260
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
261
|
+
if (transaction.recentBlockhash == null) {
|
|
262
|
+
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
263
|
+
? 2
|
|
264
|
+
: targetPreflightCommitment === 'confirmed'
|
|
265
|
+
? 1
|
|
266
|
+
: 0;
|
|
267
|
+
const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
|
|
268
|
+
const { blockhash } = yield connection.getLatestBlockhash({
|
|
269
|
+
commitment: preflightCommitmentScore < targetCommitmentScore
|
|
270
|
+
? targetPreflightCommitment
|
|
271
|
+
: targetCommitment,
|
|
272
|
+
});
|
|
273
|
+
transaction.recentBlockhash = blockhash;
|
|
274
|
+
}
|
|
275
|
+
}))(),
|
|
276
|
+
]);
|
|
277
|
+
transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
|
|
222
278
|
const signatures = yield wallet.signAndSendTransactions({
|
|
223
|
-
|
|
224
|
-
fee_payer: transaction.feePayer,
|
|
279
|
+
minContextSlot,
|
|
225
280
|
transactions: [transaction],
|
|
226
281
|
});
|
|
227
282
|
return signatures[0];
|
|
@@ -252,11 +307,12 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
252
307
|
signMessage(message) {
|
|
253
308
|
return __awaiter(this, void 0, void 0, function* () {
|
|
254
309
|
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
255
|
-
const
|
|
310
|
+
const { authToken, selectedAddress } = this.assertIsAuthorized();
|
|
256
311
|
try {
|
|
257
312
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
258
|
-
yield this.performReauthorization(wallet,
|
|
313
|
+
yield this.performReauthorization(wallet, authToken);
|
|
259
314
|
const [signedMessage] = yield wallet.signMessages({
|
|
315
|
+
addresses: [selectedAddress],
|
|
260
316
|
payloads: [message],
|
|
261
317
|
});
|
|
262
318
|
const signature = signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES);
|
|
@@ -271,6 +327,16 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
271
327
|
}
|
|
272
328
|
}
|
|
273
329
|
|
|
330
|
+
function createDefaultAddressSelector() {
|
|
331
|
+
return {
|
|
332
|
+
select(addresses) {
|
|
333
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
334
|
+
return addresses[0];
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
274
340
|
const CACHE_KEY = 'SolanaMobileWalletAdapterDefaultAuthorizationCache';
|
|
275
341
|
function createDefaultAuthorizationResultCache() {
|
|
276
342
|
let storage;
|
|
@@ -321,4 +387,5 @@ function createDefaultAuthorizationResultCache() {
|
|
|
321
387
|
|
|
322
388
|
exports.SolanaMobileWalletAdapter = SolanaMobileWalletAdapter;
|
|
323
389
|
exports.SolanaMobileWalletAdapterWalletName = SolanaMobileWalletAdapterWalletName;
|
|
390
|
+
exports.createDefaultAddressSelector = createDefaultAddressSelector;
|
|
324
391
|
exports.createDefaultAuthorizationResultCache = createDefaultAuthorizationResultCache;
|
package/lib/cjs/index.native.js
CHANGED
|
@@ -57,6 +57,7 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
57
57
|
this._connecting = false;
|
|
58
58
|
this._readyState = getIsSupported() ? walletAdapterBase.WalletReadyState.Loadable : walletAdapterBase.WalletReadyState.Unsupported;
|
|
59
59
|
this._authorizationResultCache = config.authorizationResultCache;
|
|
60
|
+
this._addressSelector = config.addressSelector;
|
|
60
61
|
this._appIdentity = config.appIdentity;
|
|
61
62
|
this._cluster = config.cluster;
|
|
62
63
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Unsupported) {
|
|
@@ -71,11 +72,9 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
get publicKey() {
|
|
74
|
-
if (this._publicKey == null && this.
|
|
75
|
+
if (this._publicKey == null && this._selectedAddress != null) {
|
|
75
76
|
try {
|
|
76
|
-
this._publicKey = getPublicKeyFromAddress(
|
|
77
|
-
// TODO(#44): support multiple addresses
|
|
78
|
-
this._authorizationResult.addresses[0]);
|
|
77
|
+
this._publicKey = getPublicKeyFromAddress(this._selectedAddress);
|
|
79
78
|
}
|
|
80
79
|
catch (e) {
|
|
81
80
|
throw new walletAdapterBase.WalletPublicKeyError((e instanceof Error && (e === null || e === void 0 ? void 0 : e.message)) || 'Unknown error', e);
|
|
@@ -117,8 +116,9 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
117
116
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Installed) {
|
|
118
117
|
this.emit('readyStateChange', (this._readyState = walletAdapterBase.WalletReadyState.Installed));
|
|
119
118
|
}
|
|
119
|
+
this._selectedAddress = yield this._addressSelector.select(cachedAuthorizationResult.accounts.map(({ address }) => address));
|
|
120
120
|
this.emit('connect',
|
|
121
|
-
// Having just set
|
|
121
|
+
// Having just set `this._selectedAddress`, `this.publicKey` is definitely non-null
|
|
122
122
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
123
123
|
this.publicKey);
|
|
124
124
|
return;
|
|
@@ -144,23 +144,33 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
144
144
|
handleAuthorizationResult(authorizationResult) {
|
|
145
145
|
var _a;
|
|
146
146
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
-
const
|
|
147
|
+
const didPublicKeysChange =
|
|
148
|
+
// Case 1: We started from having no authorization.
|
|
149
|
+
this._authorizationResult == null ||
|
|
150
|
+
// Case 2: The number of authorized accounts changed.
|
|
151
|
+
((_a = this._authorizationResult) === null || _a === void 0 ? void 0 : _a.accounts.length) !== authorizationResult.accounts.length ||
|
|
152
|
+
// Case 3: The new list of addresses isn't exactly the same as the old list, in the same order.
|
|
153
|
+
this._authorizationResult.accounts.some((account, ii) => account.address !== authorizationResult.accounts[ii].address);
|
|
148
154
|
this._authorizationResult = authorizationResult;
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
this.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
if (didPublicKeysChange) {
|
|
156
|
+
const nextSelectedAddress = yield this._addressSelector.select(authorizationResult.accounts.map(({ address }) => address));
|
|
157
|
+
if (nextSelectedAddress !== this._selectedAddress) {
|
|
158
|
+
this._selectedAddress = nextSelectedAddress;
|
|
159
|
+
delete this._publicKey;
|
|
160
|
+
this.emit('connect',
|
|
161
|
+
// Having just set `this._selectedAddress`, `this.publicKey` is definitely non-null
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
163
|
+
this.publicKey);
|
|
164
|
+
}
|
|
155
165
|
}
|
|
156
166
|
yield this._authorizationResultCache.set(authorizationResult);
|
|
157
167
|
});
|
|
158
168
|
}
|
|
159
|
-
performReauthorization(wallet,
|
|
169
|
+
performReauthorization(wallet, authToken) {
|
|
160
170
|
return __awaiter(this, void 0, void 0, function* () {
|
|
161
171
|
try {
|
|
162
172
|
const authorizationResult = yield wallet.reauthorize({
|
|
163
|
-
auth_token:
|
|
173
|
+
auth_token: authToken,
|
|
164
174
|
});
|
|
165
175
|
this.handleAuthorizationResult(authorizationResult); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
166
176
|
}
|
|
@@ -175,6 +185,7 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
175
185
|
this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
176
186
|
delete this._authorizationResult;
|
|
177
187
|
delete this._publicKey;
|
|
188
|
+
delete this._selectedAddress;
|
|
178
189
|
this.emit('disconnect');
|
|
179
190
|
});
|
|
180
191
|
}
|
|
@@ -187,17 +198,19 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
187
198
|
});
|
|
188
199
|
}
|
|
189
200
|
assertIsAuthorized() {
|
|
190
|
-
|
|
191
|
-
if (!authorizationResult)
|
|
201
|
+
if (!this._authorizationResult || !this._selectedAddress)
|
|
192
202
|
throw new walletAdapterBase.WalletNotConnectedError();
|
|
193
|
-
return
|
|
203
|
+
return {
|
|
204
|
+
authToken: this._authorizationResult.auth_token,
|
|
205
|
+
selectedAddress: this._selectedAddress,
|
|
206
|
+
};
|
|
194
207
|
}
|
|
195
208
|
performSignTransactions(transactions) {
|
|
196
209
|
return __awaiter(this, void 0, void 0, function* () {
|
|
197
|
-
const
|
|
210
|
+
const { authToken } = this.assertIsAuthorized();
|
|
198
211
|
try {
|
|
199
212
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
yield this.performReauthorization(wallet,
|
|
213
|
+
yield this.performReauthorization(wallet, authToken);
|
|
201
214
|
const signedTransactions = yield wallet.signTransactions({
|
|
202
215
|
transactions,
|
|
203
216
|
});
|
|
@@ -209,16 +222,58 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
209
222
|
}
|
|
210
223
|
});
|
|
211
224
|
}
|
|
212
|
-
sendTransaction(transaction, connection,
|
|
225
|
+
sendTransaction(transaction, connection, options) {
|
|
213
226
|
return __awaiter(this, void 0, void 0, function* () {
|
|
214
227
|
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
215
|
-
const
|
|
228
|
+
const { authToken } = this.assertIsAuthorized();
|
|
229
|
+
const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
|
|
216
230
|
try {
|
|
217
231
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
218
|
-
|
|
232
|
+
var _a;
|
|
233
|
+
let targetCommitment;
|
|
234
|
+
switch (connection.commitment) {
|
|
235
|
+
case 'confirmed':
|
|
236
|
+
case 'finalized':
|
|
237
|
+
case 'processed':
|
|
238
|
+
targetCommitment = connection.commitment;
|
|
239
|
+
break;
|
|
240
|
+
default:
|
|
241
|
+
targetCommitment = 'finalized';
|
|
242
|
+
}
|
|
243
|
+
let targetPreflightCommitment;
|
|
244
|
+
switch (options === null || options === void 0 ? void 0 : options.preflightCommitment) {
|
|
245
|
+
case 'confirmed':
|
|
246
|
+
case 'finalized':
|
|
247
|
+
case 'processed':
|
|
248
|
+
targetPreflightCommitment = options.preflightCommitment;
|
|
249
|
+
break;
|
|
250
|
+
case undefined:
|
|
251
|
+
targetPreflightCommitment = targetCommitment;
|
|
252
|
+
default:
|
|
253
|
+
targetPreflightCommitment = 'finalized';
|
|
254
|
+
}
|
|
255
|
+
yield Promise.all([
|
|
256
|
+
this.performReauthorization(wallet, authToken),
|
|
257
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
258
|
+
if (transaction.recentBlockhash == null) {
|
|
259
|
+
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
260
|
+
? 2
|
|
261
|
+
: targetPreflightCommitment === 'confirmed'
|
|
262
|
+
? 1
|
|
263
|
+
: 0;
|
|
264
|
+
const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
|
|
265
|
+
const { blockhash } = yield connection.getLatestBlockhash({
|
|
266
|
+
commitment: preflightCommitmentScore < targetCommitmentScore
|
|
267
|
+
? targetPreflightCommitment
|
|
268
|
+
: targetCommitment,
|
|
269
|
+
});
|
|
270
|
+
transaction.recentBlockhash = blockhash;
|
|
271
|
+
}
|
|
272
|
+
}))(),
|
|
273
|
+
]);
|
|
274
|
+
transaction.feePayer || (transaction.feePayer = (_a = this.publicKey) !== null && _a !== void 0 ? _a : undefined);
|
|
219
275
|
const signatures = yield wallet.signAndSendTransactions({
|
|
220
|
-
|
|
221
|
-
fee_payer: transaction.feePayer,
|
|
276
|
+
minContextSlot,
|
|
222
277
|
transactions: [transaction],
|
|
223
278
|
});
|
|
224
279
|
return signatures[0];
|
|
@@ -249,11 +304,12 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
249
304
|
signMessage(message) {
|
|
250
305
|
return __awaiter(this, void 0, void 0, function* () {
|
|
251
306
|
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
252
|
-
const
|
|
307
|
+
const { authToken, selectedAddress } = this.assertIsAuthorized();
|
|
253
308
|
try {
|
|
254
309
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
255
|
-
yield this.performReauthorization(wallet,
|
|
310
|
+
yield this.performReauthorization(wallet, authToken);
|
|
256
311
|
const [signedMessage] = yield wallet.signMessages({
|
|
312
|
+
addresses: [selectedAddress],
|
|
257
313
|
payloads: [message],
|
|
258
314
|
});
|
|
259
315
|
const signature = signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES);
|
|
@@ -268,6 +324,16 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
268
324
|
}
|
|
269
325
|
}
|
|
270
326
|
|
|
327
|
+
function createDefaultAddressSelector() {
|
|
328
|
+
return {
|
|
329
|
+
select(addresses) {
|
|
330
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
331
|
+
return addresses[0];
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
271
337
|
const CACHE_KEY = 'SolanaMobileWalletAdapterDefaultAuthorizationCache';
|
|
272
338
|
function createDefaultAuthorizationResultCache() {
|
|
273
339
|
return {
|
|
@@ -303,4 +369,5 @@ function createDefaultAuthorizationResultCache() {
|
|
|
303
369
|
|
|
304
370
|
exports.SolanaMobileWalletAdapter = SolanaMobileWalletAdapter;
|
|
305
371
|
exports.SolanaMobileWalletAdapterWalletName = SolanaMobileWalletAdapterWalletName;
|
|
372
|
+
exports.createDefaultAddressSelector = createDefaultAddressSelector;
|
|
306
373
|
exports.createDefaultAuthorizationResultCache = createDefaultAuthorizationResultCache;
|