@solana-mobile/wallet-adapter-mobile 0.0.1-alpha.7 → 0.9.1
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 +175 -96
- package/lib/cjs/index.js +175 -96
- package/lib/cjs/index.native.js +169 -96
- package/lib/esm/index.browser.mjs +176 -98
- package/lib/esm/index.mjs +176 -98
- package/lib/types/index.browser.d.mts +13 -3
- package/lib/types/index.browser.d.mts.map +1 -1
- package/lib/types/index.browser.d.ts +13 -3
- package/lib/types/index.browser.d.ts.map +1 -1
- package/lib/types/index.d.mts +13 -3
- package/lib/types/index.d.mts.map +1 -1
- package/lib/types/index.d.ts +13 -3
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.native.d.ts +13 -3
- package/lib/types/index.native.d.ts.map +1 -1
- package/package.json +7 -5
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
|
@@ -6,7 +6,7 @@ var mobileWalletAdapterProtocolWeb3js = require('@solana-mobile/mobile-wallet-ad
|
|
|
6
6
|
var walletAdapterBase = require('@solana/wallet-adapter-base');
|
|
7
7
|
var web3_js = require('@solana/web3.js');
|
|
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
|
|
@@ -31,6 +31,13 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
function toUint8Array(base64EncodedByteArray) {
|
|
35
|
+
return new Uint8Array(window
|
|
36
|
+
.atob(base64EncodedByteArray)
|
|
37
|
+
.split('')
|
|
38
|
+
.map((c) => c.charCodeAt(0)));
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
function getIsSupported() {
|
|
35
42
|
return (typeof window !== 'undefined' &&
|
|
36
43
|
window.isSecureContext &&
|
|
@@ -40,6 +47,10 @@ function getIsSupported() {
|
|
|
40
47
|
|
|
41
48
|
const SolanaMobileWalletAdapterWalletName = 'Default wallet app';
|
|
42
49
|
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
50
|
+
function getPublicKeyFromAddress(address) {
|
|
51
|
+
const publicKeyByteArray = toUint8Array(address);
|
|
52
|
+
return new web3_js.PublicKey(publicKeyByteArray);
|
|
53
|
+
}
|
|
43
54
|
class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalletAdapter {
|
|
44
55
|
constructor(config) {
|
|
45
56
|
super();
|
|
@@ -49,7 +60,9 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
49
60
|
this._connecting = false;
|
|
50
61
|
this._readyState = getIsSupported() ? walletAdapterBase.WalletReadyState.Loadable : walletAdapterBase.WalletReadyState.Unsupported;
|
|
51
62
|
this._authorizationResultCache = config.authorizationResultCache;
|
|
63
|
+
this._addressSelector = config.addressSelector;
|
|
52
64
|
this._appIdentity = config.appIdentity;
|
|
65
|
+
this._cluster = config.cluster;
|
|
53
66
|
if (this._readyState !== walletAdapterBase.WalletReadyState.Unsupported) {
|
|
54
67
|
this._authorizationResultCache.get().then((authorizationResult) => {
|
|
55
68
|
if (authorizationResult) {
|
|
@@ -62,8 +75,13 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
77
|
get publicKey() {
|
|
65
|
-
if (this._publicKey == null && this.
|
|
66
|
-
|
|
78
|
+
if (this._publicKey == null && this._selectedAddress != null) {
|
|
79
|
+
try {
|
|
80
|
+
this._publicKey = getPublicKeyFromAddress(this._selectedAddress);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
throw new walletAdapterBase.WalletPublicKeyError((e instanceof Error && (e === null || e === void 0 ? void 0 : e.message)) || 'Unknown error', e);
|
|
84
|
+
}
|
|
67
85
|
}
|
|
68
86
|
return this._publicKey ? this._publicKey : null;
|
|
69
87
|
}
|
|
@@ -76,71 +94,88 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
76
94
|
get readyState() {
|
|
77
95
|
return this._readyState;
|
|
78
96
|
}
|
|
79
|
-
|
|
97
|
+
runWithGuard(callback) {
|
|
80
98
|
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.emit('error', err);
|
|
84
|
-
throw err;
|
|
99
|
+
try {
|
|
100
|
+
return yield callback();
|
|
85
101
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this._authorizationResult = cachedAuthorizationResult;
|
|
90
|
-
this._connecting = false;
|
|
91
|
-
if (this._readyState !== walletAdapterBase.WalletReadyState.Installed) {
|
|
92
|
-
this.emit('readyStateChange', (this._readyState = walletAdapterBase.WalletReadyState.Installed));
|
|
93
|
-
}
|
|
94
|
-
this.emit('connect',
|
|
95
|
-
// Having just set an `authorizationResult`, `this.publicKey` is definitely non-null
|
|
96
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
97
|
-
this.publicKey);
|
|
98
|
-
return;
|
|
102
|
+
catch (e) {
|
|
103
|
+
this.emit('error', e);
|
|
104
|
+
throw e;
|
|
99
105
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
connect() {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
if (this._readyState !== walletAdapterBase.WalletReadyState.Installed && this._readyState !== walletAdapterBase.WalletReadyState.Loadable) {
|
|
112
|
+
throw new walletAdapterBase.WalletNotReadyError();
|
|
113
|
+
}
|
|
114
|
+
this._connecting = true;
|
|
115
|
+
const cachedAuthorizationResult = yield this._authorizationResultCache.get();
|
|
116
|
+
if (cachedAuthorizationResult) {
|
|
117
|
+
this._authorizationResult = cachedAuthorizationResult;
|
|
118
|
+
this._connecting = false;
|
|
119
|
+
if (this._readyState !== walletAdapterBase.WalletReadyState.Installed) {
|
|
120
|
+
this.emit('readyStateChange', (this._readyState = walletAdapterBase.WalletReadyState.Installed));
|
|
108
121
|
}
|
|
109
|
-
this.
|
|
110
|
-
auth_token,
|
|
111
|
-
pub_key: base58PublicKey,
|
|
112
|
-
wallet_uri_base: wallet_uri_base,
|
|
113
|
-
}); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
122
|
+
this._selectedAddress = yield this._addressSelector.select(cachedAuthorizationResult.accounts.map(({ address }) => address));
|
|
114
123
|
this.emit('connect',
|
|
115
|
-
// Having just set
|
|
124
|
+
// Having just set `this._selectedAddress`, `this.publicKey` is definitely non-null
|
|
116
125
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
117
126
|
this.publicKey);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
131
|
+
const authorizationResult = yield wallet.authorize({
|
|
132
|
+
cluster: this._cluster,
|
|
133
|
+
identity: this._appIdentity,
|
|
134
|
+
});
|
|
135
|
+
this.handleAuthorizationResult(authorizationResult); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
throw new walletAdapterBase.WalletConnectionError((e instanceof Error && e.message) || 'Unknown error', e);
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
this._connecting = false;
|
|
143
|
+
}
|
|
144
|
+
}));
|
|
126
145
|
});
|
|
127
146
|
}
|
|
128
147
|
handleAuthorizationResult(authorizationResult) {
|
|
148
|
+
var _a;
|
|
129
149
|
return __awaiter(this, void 0, void 0, function* () {
|
|
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);
|
|
130
157
|
this._authorizationResult = authorizationResult;
|
|
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
|
+
}
|
|
168
|
+
}
|
|
131
169
|
yield this._authorizationResultCache.set(authorizationResult);
|
|
132
170
|
});
|
|
133
171
|
}
|
|
134
|
-
performReauthorization(wallet,
|
|
172
|
+
performReauthorization(wallet, authToken) {
|
|
135
173
|
return __awaiter(this, void 0, void 0, function* () {
|
|
136
174
|
try {
|
|
137
|
-
const
|
|
138
|
-
auth_token:
|
|
175
|
+
const authorizationResult = yield wallet.reauthorize({
|
|
176
|
+
auth_token: authToken,
|
|
139
177
|
});
|
|
140
|
-
|
|
141
|
-
this.handleAuthorizationResult(Object.assign(Object.assign({}, currentAuthorizationResult), { auth_token })); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
142
|
-
}
|
|
143
|
-
return auth_token;
|
|
178
|
+
this.handleAuthorizationResult(authorizationResult); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
144
179
|
}
|
|
145
180
|
catch (e) {
|
|
146
181
|
this.disconnect();
|
|
@@ -153,6 +188,7 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
153
188
|
this._authorizationResultCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
|
|
154
189
|
delete this._authorizationResult;
|
|
155
190
|
delete this._publicKey;
|
|
191
|
+
delete this._selectedAddress;
|
|
156
192
|
this.emit('disconnect');
|
|
157
193
|
});
|
|
158
194
|
}
|
|
@@ -165,46 +201,82 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
165
201
|
});
|
|
166
202
|
}
|
|
167
203
|
assertIsAuthorized() {
|
|
168
|
-
|
|
169
|
-
if (!authorizationResult)
|
|
204
|
+
if (!this._authorizationResult || !this._selectedAddress)
|
|
170
205
|
throw new walletAdapterBase.WalletNotConnectedError();
|
|
171
|
-
return
|
|
206
|
+
return {
|
|
207
|
+
authToken: this._authorizationResult.auth_token,
|
|
208
|
+
selectedAddress: this._selectedAddress,
|
|
209
|
+
};
|
|
172
210
|
}
|
|
173
211
|
performSignTransactions(transactions) {
|
|
174
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
213
|
+
const { authToken } = this.assertIsAuthorized();
|
|
175
214
|
try {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
184
|
-
return signedTransactions;
|
|
185
|
-
}));
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
throw new walletAdapterBase.WalletSignTransactionError(error === null || error === void 0 ? void 0 : error.message, error);
|
|
189
|
-
}
|
|
215
|
+
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
216
|
+
yield this.performReauthorization(wallet, authToken);
|
|
217
|
+
const signedTransactions = yield wallet.signTransactions({
|
|
218
|
+
transactions,
|
|
219
|
+
});
|
|
220
|
+
return signedTransactions;
|
|
221
|
+
}));
|
|
190
222
|
}
|
|
191
223
|
catch (error) {
|
|
192
|
-
|
|
193
|
-
throw error;
|
|
224
|
+
throw new walletAdapterBase.WalletSignTransactionError(error === null || error === void 0 ? void 0 : error.message, error);
|
|
194
225
|
}
|
|
195
226
|
});
|
|
196
227
|
}
|
|
197
|
-
sendTransaction(transaction, connection,
|
|
228
|
+
sendTransaction(transaction, connection, options) {
|
|
198
229
|
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
-
|
|
200
|
-
const
|
|
230
|
+
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
231
|
+
const { authToken } = this.assertIsAuthorized();
|
|
232
|
+
const minContextSlot = options === null || options === void 0 ? void 0 : options.minContextSlot;
|
|
201
233
|
try {
|
|
202
234
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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);
|
|
278
|
+
const signatures = yield wallet.signAndSendTransactions({
|
|
279
|
+
minContextSlot,
|
|
208
280
|
transactions: [transaction],
|
|
209
281
|
});
|
|
210
282
|
return signatures[0];
|
|
@@ -213,34 +285,34 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
213
285
|
catch (error) {
|
|
214
286
|
throw new walletAdapterBase.WalletSendTransactionError(error === null || error === void 0 ? void 0 : error.message, error);
|
|
215
287
|
}
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
this.emit('error', error);
|
|
219
|
-
throw error;
|
|
220
|
-
}
|
|
288
|
+
}));
|
|
221
289
|
});
|
|
222
290
|
}
|
|
223
291
|
signTransaction(transaction) {
|
|
224
292
|
return __awaiter(this, void 0, void 0, function* () {
|
|
225
|
-
|
|
226
|
-
|
|
293
|
+
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
294
|
+
const [signedTransaction] = yield this.performSignTransactions([transaction]);
|
|
295
|
+
return signedTransaction;
|
|
296
|
+
}));
|
|
227
297
|
});
|
|
228
298
|
}
|
|
229
299
|
signAllTransactions(transactions) {
|
|
230
300
|
return __awaiter(this, void 0, void 0, function* () {
|
|
231
|
-
|
|
232
|
-
|
|
301
|
+
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
302
|
+
const signedTransactions = yield this.performSignTransactions(transactions);
|
|
303
|
+
return signedTransactions;
|
|
304
|
+
}));
|
|
233
305
|
});
|
|
234
306
|
}
|
|
235
307
|
signMessage(message) {
|
|
236
308
|
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
-
|
|
238
|
-
const
|
|
309
|
+
return yield this.runWithGuard(() => __awaiter(this, void 0, void 0, function* () {
|
|
310
|
+
const { authToken, selectedAddress } = this.assertIsAuthorized();
|
|
239
311
|
try {
|
|
240
312
|
return yield this.transact((wallet) => __awaiter(this, void 0, void 0, function* () {
|
|
241
|
-
|
|
242
|
-
const [signedMessage] = yield wallet.
|
|
243
|
-
|
|
313
|
+
yield this.performReauthorization(wallet, authToken);
|
|
314
|
+
const [signedMessage] = yield wallet.signMessages({
|
|
315
|
+
addresses: [selectedAddress],
|
|
244
316
|
payloads: [message],
|
|
245
317
|
});
|
|
246
318
|
const signature = signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES);
|
|
@@ -250,15 +322,21 @@ class SolanaMobileWalletAdapter extends walletAdapterBase.BaseMessageSignerWalle
|
|
|
250
322
|
catch (error) {
|
|
251
323
|
throw new walletAdapterBase.WalletSignMessageError(error === null || error === void 0 ? void 0 : error.message, error);
|
|
252
324
|
}
|
|
253
|
-
}
|
|
254
|
-
catch (error) {
|
|
255
|
-
this.emit('error', error);
|
|
256
|
-
throw error;
|
|
257
|
-
}
|
|
325
|
+
}));
|
|
258
326
|
});
|
|
259
327
|
}
|
|
260
328
|
}
|
|
261
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
|
+
|
|
262
340
|
const CACHE_KEY = 'SolanaMobileWalletAdapterDefaultAuthorizationCache';
|
|
263
341
|
function createDefaultAuthorizationResultCache() {
|
|
264
342
|
let storage;
|
|
@@ -309,4 +387,5 @@ function createDefaultAuthorizationResultCache() {
|
|
|
309
387
|
|
|
310
388
|
exports.SolanaMobileWalletAdapter = SolanaMobileWalletAdapter;
|
|
311
389
|
exports.SolanaMobileWalletAdapterWalletName = SolanaMobileWalletAdapterWalletName;
|
|
390
|
+
exports.createDefaultAddressSelector = createDefaultAddressSelector;
|
|
312
391
|
exports.createDefaultAuthorizationResultCache = createDefaultAuthorizationResultCache;
|