@solana-mobile/wallet-adapter-mobile 2.2.6 → 2.2.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 +4 -5
- package/lib/cjs/index.browser.js +321 -394
- package/lib/cjs/index.browser.js.map +1 -0
- package/lib/cjs/index.js +321 -394
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/index.native.js +361 -415
- package/lib/cjs/index.native.js.map +1 -0
- package/lib/cjs/package.json +1 -3
- package/lib/esm/index.browser.js +318 -390
- package/lib/esm/index.browser.js.map +1 -0
- package/lib/esm/index.js +318 -390
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/package.json +1 -3
- package/lib/types/index.d.ts +66 -59
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +12 -11
- package/lib/types/index.browser.d.ts +0 -79
- package/lib/types/index.browser.d.ts.map +0 -1
- package/lib/types/index.native.d.ts +0 -79
- package/lib/types/index.native.d.ts.map +0 -1
package/lib/esm/index.browser.js
CHANGED
|
@@ -1,410 +1,338 @@
|
|
|
1
|
-
import { BaseSignInMessageSignerWalletAdapter,
|
|
2
|
-
import { PublicKey,
|
|
3
|
-
import { SolanaSignIn, SolanaSignMessage,
|
|
4
|
-
import {
|
|
5
|
-
import { SolanaMobileWalletAdapterRemoteWalletName as SolanaMobileWalletAdapterRemoteWalletName$1, SolanaMobileWalletAdapterWalletName as SolanaMobileWalletAdapterWalletName$1,
|
|
6
|
-
|
|
1
|
+
import { BaseSignInMessageSignerWalletAdapter, WalletConnectionError, WalletNotConnectedError, WalletNotReadyError, WalletPublicKeyError, WalletReadyState, WalletSendTransactionError, WalletSignMessageError, WalletSignTransactionError } from "@solana/wallet-adapter-base";
|
|
2
|
+
import { PublicKey, Transaction, VersionedMessage, VersionedTransaction } from "@solana/web3.js";
|
|
3
|
+
import { SolanaSignAndSendTransaction, SolanaSignIn, SolanaSignMessage, SolanaSignTransaction } from "@solana/wallet-standard-features";
|
|
4
|
+
import { StandardConnect, StandardDisconnect, StandardEvents } from "@wallet-standard/core";
|
|
5
|
+
import { LocalSolanaMobileWalletAdapterWallet, RemoteSolanaMobileWalletAdapterWallet, SolanaMobileWalletAdapterRemoteWalletName as SolanaMobileWalletAdapterRemoteWalletName$1, SolanaMobileWalletAdapterWalletName as SolanaMobileWalletAdapterWalletName$1, createDefaultAuthorizationCache, createDefaultChainSelector, defaultErrorModalWalletNotFoundHandler } from "@solana-mobile/wallet-standard-mobile";
|
|
6
|
+
//#region src/base64Utils.ts
|
|
7
7
|
function fromUint8Array(byteArray) {
|
|
8
|
-
|
|
8
|
+
return window.btoa(String.fromCharCode.call(null, ...byteArray));
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/getIsSupported.ts
|
|
11
12
|
function getIsSupported() {
|
|
12
|
-
|
|
13
|
-
window.isSecureContext &&
|
|
14
|
-
typeof document !== 'undefined' &&
|
|
15
|
-
/android/i.test(navigator.userAgent));
|
|
13
|
+
return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && /android/i.test(navigator.userAgent);
|
|
16
14
|
}
|
|
17
|
-
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/adapter.ts
|
|
18
17
|
const SolanaMobileWalletAdapterWalletName = SolanaMobileWalletAdapterWalletName$1;
|
|
19
18
|
const SolanaMobileWalletAdapterRemoteWalletName = SolanaMobileWalletAdapterRemoteWalletName$1;
|
|
20
19
|
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
21
20
|
function isVersionedTransaction(transaction) {
|
|
22
|
-
|
|
21
|
+
return "version" in transaction;
|
|
23
22
|
}
|
|
24
23
|
function chainOrClusterToChainId(chain) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return 'solana:devnet';
|
|
32
|
-
default:
|
|
33
|
-
return chain;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
class BaseSolanaMobileWalletAdapter extends BaseSignInMessageSignerWalletAdapter {
|
|
37
|
-
supportedTransactionVersions = new Set(
|
|
38
|
-
// FIXME(#244): We can't actually know what versions are supported until we know which wallet we're talking to.
|
|
39
|
-
['legacy', 0]);
|
|
40
|
-
name;
|
|
41
|
-
icon;
|
|
42
|
-
url;
|
|
43
|
-
#wallet;
|
|
44
|
-
#connecting = false;
|
|
45
|
-
#readyState = getIsSupported() ? WalletReadyState.Loadable : WalletReadyState.Unsupported;
|
|
46
|
-
#accountSelector;
|
|
47
|
-
#selectedAccount;
|
|
48
|
-
#publicKey;
|
|
49
|
-
#handleChangeEvent = async (properties) => {
|
|
50
|
-
if (properties.accounts && properties.accounts.length > 0) {
|
|
51
|
-
this.#declareWalletAsInstalled();
|
|
52
|
-
const nextSelectedAccount = await this.#accountSelector(properties.accounts);
|
|
53
|
-
if (nextSelectedAccount !== this.#selectedAccount) {
|
|
54
|
-
this.#selectedAccount = nextSelectedAccount;
|
|
55
|
-
this.#publicKey = undefined;
|
|
56
|
-
this.emit('connect',
|
|
57
|
-
// Having just set `this.#selectedAccount`, `this.publicKey` is definitely non-null
|
|
58
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
59
|
-
this.publicKey);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
constructor(wallet, config) {
|
|
64
|
-
super();
|
|
65
|
-
// this.#chain = chainOrClusterToChainId(config.chain);
|
|
66
|
-
this.#accountSelector = async (accounts) => {
|
|
67
|
-
const selectedBase64EncodedAddress = await config.addressSelector.select(accounts.map(({ publicKey }) => fromUint8Array(new Uint8Array(publicKey))));
|
|
68
|
-
return accounts.find(({ publicKey }) => fromUint8Array(new Uint8Array(publicKey)) === selectedBase64EncodedAddress) ?? accounts[0];
|
|
69
|
-
};
|
|
70
|
-
this.#wallet = wallet;
|
|
71
|
-
this.#wallet.features[StandardEvents].on('change', this.#handleChangeEvent);
|
|
72
|
-
this.name = this.#wallet.name;
|
|
73
|
-
this.icon = this.#wallet.icon;
|
|
74
|
-
this.url = this.#wallet.url;
|
|
75
|
-
// TODO: evaluate if this logic should be kept - it seems to create a nasty bug where
|
|
76
|
-
// the wallet tries to auto connect on page load and gets blocked by the popup blocker
|
|
77
|
-
// if (this.#readyState !== WalletReadyState.Unsupported) {
|
|
78
|
-
// config.authorizationResultCache.get().then((authorizationResult) => {
|
|
79
|
-
// if (authorizationResult) {
|
|
80
|
-
// // Having a prior authorization result is, right now, the best
|
|
81
|
-
// // indication that a mobile wallet is installed. There is no API
|
|
82
|
-
// // we can use to test for whether the association URI is supported.
|
|
83
|
-
// this.#declareWalletAsInstalled();
|
|
84
|
-
// }
|
|
85
|
-
// });
|
|
86
|
-
// }
|
|
87
|
-
}
|
|
88
|
-
get publicKey() {
|
|
89
|
-
if (!this.#publicKey && this.#selectedAccount) {
|
|
90
|
-
try {
|
|
91
|
-
this.#publicKey = new PublicKey(this.#selectedAccount.publicKey);
|
|
92
|
-
}
|
|
93
|
-
catch (e) {
|
|
94
|
-
throw new WalletPublicKeyError((e instanceof Error && e?.message) || 'Unknown error', e);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return this.#publicKey ?? null;
|
|
98
|
-
}
|
|
99
|
-
get connected() {
|
|
100
|
-
return this.#wallet.connected;
|
|
101
|
-
}
|
|
102
|
-
get connecting() {
|
|
103
|
-
return this.#connecting;
|
|
104
|
-
}
|
|
105
|
-
get readyState() {
|
|
106
|
-
return this.#readyState;
|
|
107
|
-
}
|
|
108
|
-
/** @deprecated Use `autoConnect()` instead. */
|
|
109
|
-
async autoConnect_DO_NOT_USE_OR_YOU_WILL_BE_FIRED() {
|
|
110
|
-
return await this.autoConnect();
|
|
111
|
-
}
|
|
112
|
-
async autoConnect() {
|
|
113
|
-
this.#connect(true);
|
|
114
|
-
}
|
|
115
|
-
async connect() {
|
|
116
|
-
this.#connect();
|
|
117
|
-
}
|
|
118
|
-
async #connect(autoConnect = false) {
|
|
119
|
-
if (this.connecting || this.connected) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
return await this.#runWithGuard(async () => {
|
|
123
|
-
if (this.#readyState !== WalletReadyState.Installed && this.#readyState !== WalletReadyState.Loadable) {
|
|
124
|
-
throw new WalletNotReadyError();
|
|
125
|
-
}
|
|
126
|
-
this.#connecting = true;
|
|
127
|
-
try {
|
|
128
|
-
await this.#wallet.features[StandardConnect].connect({ silent: autoConnect });
|
|
129
|
-
}
|
|
130
|
-
catch (e) {
|
|
131
|
-
throw new WalletConnectionError((e instanceof Error && e.message) || 'Unknown error', e);
|
|
132
|
-
}
|
|
133
|
-
finally {
|
|
134
|
-
this.#connecting = false;
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
/** @deprecated Use `connect()` or `autoConnect()` instead. */
|
|
139
|
-
async performAuthorization(signInPayload) {
|
|
140
|
-
try {
|
|
141
|
-
const cachedAuthorizationResult = await this.#wallet.cachedAuthorizationResult;
|
|
142
|
-
if (cachedAuthorizationResult) {
|
|
143
|
-
await this.#wallet.features[StandardConnect].connect({ silent: true });
|
|
144
|
-
return cachedAuthorizationResult;
|
|
145
|
-
}
|
|
146
|
-
if (signInPayload) {
|
|
147
|
-
await this.#wallet.features[SolanaSignIn].signIn(signInPayload);
|
|
148
|
-
}
|
|
149
|
-
else
|
|
150
|
-
await this.#wallet.features[StandardConnect].connect();
|
|
151
|
-
const authorizationResult = await await this.#wallet.cachedAuthorizationResult;
|
|
152
|
-
return authorizationResult;
|
|
153
|
-
}
|
|
154
|
-
catch (e) {
|
|
155
|
-
throw new WalletConnectionError((e instanceof Error && e.message) || 'Unknown error', e);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
async disconnect() {
|
|
159
|
-
// return await this.#runWithGuard(this.#wallet.features[StandardDisconnect].disconnect);
|
|
160
|
-
return await this.#runWithGuard(async () => {
|
|
161
|
-
this.#connecting = false;
|
|
162
|
-
this.#publicKey = undefined;
|
|
163
|
-
this.#selectedAccount = undefined;
|
|
164
|
-
await this.#wallet.features[StandardDisconnect].disconnect();
|
|
165
|
-
this.emit('disconnect');
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
async signIn(input) {
|
|
169
|
-
return this.#runWithGuard(async () => {
|
|
170
|
-
if (this.#readyState !== WalletReadyState.Installed && this.#readyState !== WalletReadyState.Loadable) {
|
|
171
|
-
throw new WalletNotReadyError();
|
|
172
|
-
}
|
|
173
|
-
this.#connecting = true;
|
|
174
|
-
try {
|
|
175
|
-
const outputs = await this.#wallet.features[SolanaSignIn].signIn({
|
|
176
|
-
...input,
|
|
177
|
-
domain: input?.domain ?? window.location.host
|
|
178
|
-
});
|
|
179
|
-
if (outputs.length > 0) {
|
|
180
|
-
return outputs[0];
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
throw new Error("Sign in failed, no sign in result returned by wallet");
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
catch (e) {
|
|
187
|
-
throw new WalletConnectionError((e instanceof Error && e.message) || 'Unknown error', e);
|
|
188
|
-
}
|
|
189
|
-
finally {
|
|
190
|
-
this.#connecting = false;
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
async signMessage(message) {
|
|
195
|
-
return await this.#runWithGuard(async () => {
|
|
196
|
-
const account = this.#assertIsAuthorized();
|
|
197
|
-
try {
|
|
198
|
-
const outputs = await this.#wallet.features[SolanaSignMessage].signMessage({
|
|
199
|
-
account, message: message
|
|
200
|
-
});
|
|
201
|
-
return outputs[0].signature;
|
|
202
|
-
}
|
|
203
|
-
catch (error) {
|
|
204
|
-
throw new WalletSignMessageError(error?.message, error);
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
async sendTransaction(transaction, connection, options) {
|
|
209
|
-
return await this.#runWithGuard(async () => {
|
|
210
|
-
const account = this.#assertIsAuthorized();
|
|
211
|
-
try {
|
|
212
|
-
function getTargetCommitment() {
|
|
213
|
-
let targetCommitment;
|
|
214
|
-
switch (connection.commitment) {
|
|
215
|
-
case 'confirmed':
|
|
216
|
-
case 'finalized':
|
|
217
|
-
case 'processed':
|
|
218
|
-
targetCommitment = connection.commitment;
|
|
219
|
-
break;
|
|
220
|
-
default:
|
|
221
|
-
targetCommitment = 'finalized';
|
|
222
|
-
}
|
|
223
|
-
let targetPreflightCommitment;
|
|
224
|
-
switch (options?.preflightCommitment) {
|
|
225
|
-
case 'confirmed':
|
|
226
|
-
case 'finalized':
|
|
227
|
-
case 'processed':
|
|
228
|
-
targetPreflightCommitment = options.preflightCommitment;
|
|
229
|
-
break;
|
|
230
|
-
case undefined:
|
|
231
|
-
targetPreflightCommitment = targetCommitment;
|
|
232
|
-
break;
|
|
233
|
-
default:
|
|
234
|
-
targetPreflightCommitment = 'finalized';
|
|
235
|
-
}
|
|
236
|
-
const preflightCommitmentScore = targetPreflightCommitment === 'finalized'
|
|
237
|
-
? 2
|
|
238
|
-
: targetPreflightCommitment === 'confirmed'
|
|
239
|
-
? 1
|
|
240
|
-
: 0;
|
|
241
|
-
const targetCommitmentScore = targetCommitment === 'finalized' ? 2 : targetCommitment === 'confirmed' ? 1 : 0;
|
|
242
|
-
return preflightCommitmentScore < targetCommitmentScore
|
|
243
|
-
? targetPreflightCommitment
|
|
244
|
-
: targetCommitment;
|
|
245
|
-
}
|
|
246
|
-
if (SolanaSignAndSendTransaction in this.#wallet.features) {
|
|
247
|
-
const chain = chainOrClusterToChainId(this.#wallet.currentAuthorization.chain);
|
|
248
|
-
const [signature] = (await this.#wallet.features[SolanaSignAndSendTransaction].signAndSendTransaction({
|
|
249
|
-
account,
|
|
250
|
-
transaction: transaction.serialize(),
|
|
251
|
-
chain: chain,
|
|
252
|
-
options: options ? {
|
|
253
|
-
skipPreflight: options.skipPreflight,
|
|
254
|
-
maxRetries: options.maxRetries
|
|
255
|
-
} : undefined
|
|
256
|
-
})).map(((output) => {
|
|
257
|
-
return fromUint8Array(output.signature);
|
|
258
|
-
}));
|
|
259
|
-
return signature;
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
const [signedTransaction] = await this.#performSignTransactions([transaction]);
|
|
263
|
-
if (isVersionedTransaction(signedTransaction)) {
|
|
264
|
-
return await connection.sendTransaction(signedTransaction);
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
const serializedTransaction = signedTransaction.serialize();
|
|
268
|
-
return await connection.sendRawTransaction(serializedTransaction, {
|
|
269
|
-
...options,
|
|
270
|
-
preflightCommitment: getTargetCommitment(),
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
catch (error) {
|
|
276
|
-
throw new WalletSendTransactionError(error?.message, error);
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
async signTransaction(transaction) {
|
|
281
|
-
return await this.#runWithGuard(async () => {
|
|
282
|
-
const [signedTransaction] = await this.#performSignTransactions([transaction]);
|
|
283
|
-
return signedTransaction;
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
async signAllTransactions(transactions) {
|
|
287
|
-
return await this.#runWithGuard(async () => {
|
|
288
|
-
const signedTransactions = await this.#performSignTransactions(transactions);
|
|
289
|
-
return signedTransactions;
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
#declareWalletAsInstalled() {
|
|
293
|
-
if (this.#readyState !== WalletReadyState.Installed) {
|
|
294
|
-
this.emit('readyStateChange', (this.#readyState = WalletReadyState.Installed));
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
#assertIsAuthorized() {
|
|
298
|
-
if (!this.#wallet.isAuthorized || !this.#selectedAccount)
|
|
299
|
-
throw new WalletNotConnectedError();
|
|
300
|
-
return this.#selectedAccount;
|
|
301
|
-
}
|
|
302
|
-
async #performSignTransactions(transactions) {
|
|
303
|
-
const account = this.#assertIsAuthorized();
|
|
304
|
-
try {
|
|
305
|
-
if (SolanaSignTransaction in this.#wallet.features) {
|
|
306
|
-
return this.#wallet.features[SolanaSignTransaction].signTransaction(...transactions.map((value) => {
|
|
307
|
-
return { account, transaction: value.serialize() };
|
|
308
|
-
})).then((outputs) => {
|
|
309
|
-
return outputs.map((output) => {
|
|
310
|
-
const byteArray = output.signedTransaction;
|
|
311
|
-
const numSignatures = byteArray[0];
|
|
312
|
-
const messageOffset = numSignatures * SIGNATURE_LENGTH_IN_BYTES + 1;
|
|
313
|
-
const version = VersionedMessage.deserializeMessageVersion(byteArray.slice(messageOffset, byteArray.length));
|
|
314
|
-
if (version === 'legacy') {
|
|
315
|
-
return Transaction.from(byteArray);
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
return VersionedTransaction.deserialize(byteArray);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
throw new Error('Connected wallet does not support signing transactions');
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
catch (error) {
|
|
328
|
-
throw new WalletSignTransactionError(error?.message, error);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
async #runWithGuard(callback) {
|
|
332
|
-
try {
|
|
333
|
-
return await callback();
|
|
334
|
-
}
|
|
335
|
-
catch (e) {
|
|
336
|
-
this.emit('error', e);
|
|
337
|
-
throw e;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
class LocalSolanaMobileWalletAdapter extends BaseSolanaMobileWalletAdapter {
|
|
342
|
-
constructor(config) {
|
|
343
|
-
const chain = chainOrClusterToChainId(config.chain ?? config.cluster);
|
|
344
|
-
super(new LocalSolanaMobileWalletAdapterWallet({
|
|
345
|
-
appIdentity: config.appIdentity,
|
|
346
|
-
authorizationCache: {
|
|
347
|
-
set: config.authorizationResultCache.set,
|
|
348
|
-
get: async () => {
|
|
349
|
-
return await config.authorizationResultCache.get();
|
|
350
|
-
},
|
|
351
|
-
clear: config.authorizationResultCache.clear,
|
|
352
|
-
},
|
|
353
|
-
chains: [chain],
|
|
354
|
-
chainSelector: createDefaultChainSelector(),
|
|
355
|
-
onWalletNotFound: async () => {
|
|
356
|
-
config.onWalletNotFound(this);
|
|
357
|
-
},
|
|
358
|
-
}), {
|
|
359
|
-
addressSelector: config.addressSelector,
|
|
360
|
-
chain: chain,
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
class RemoteSolanaMobileWalletAdapter extends BaseSolanaMobileWalletAdapter {
|
|
365
|
-
constructor(config) {
|
|
366
|
-
const chain = chainOrClusterToChainId(config.chain);
|
|
367
|
-
super(new RemoteSolanaMobileWalletAdapterWallet({
|
|
368
|
-
appIdentity: config.appIdentity,
|
|
369
|
-
authorizationCache: {
|
|
370
|
-
set: config.authorizationResultCache.set,
|
|
371
|
-
get: async () => {
|
|
372
|
-
return await config.authorizationResultCache.get();
|
|
373
|
-
},
|
|
374
|
-
clear: config.authorizationResultCache.clear,
|
|
375
|
-
},
|
|
376
|
-
chains: [chain],
|
|
377
|
-
chainSelector: createDefaultChainSelector(),
|
|
378
|
-
remoteHostAuthority: config.remoteHostAuthority,
|
|
379
|
-
onWalletNotFound: async () => {
|
|
380
|
-
config.onWalletNotFound(this);
|
|
381
|
-
},
|
|
382
|
-
}), {
|
|
383
|
-
addressSelector: config.addressSelector,
|
|
384
|
-
chain: chain,
|
|
385
|
-
});
|
|
386
|
-
}
|
|
24
|
+
switch (chain) {
|
|
25
|
+
case "mainnet-beta": return "solana:mainnet";
|
|
26
|
+
case "testnet": return "solana:testnet";
|
|
27
|
+
case "devnet": return "solana:devnet";
|
|
28
|
+
default: return chain;
|
|
29
|
+
}
|
|
387
30
|
}
|
|
388
|
-
class
|
|
389
|
-
|
|
390
|
-
|
|
31
|
+
var BaseSolanaMobileWalletAdapter = class extends BaseSignInMessageSignerWalletAdapter {
|
|
32
|
+
supportedTransactionVersions = new Set(["legacy", 0]);
|
|
33
|
+
name;
|
|
34
|
+
icon;
|
|
35
|
+
url;
|
|
36
|
+
#wallet;
|
|
37
|
+
#connecting = false;
|
|
38
|
+
#readyState = getIsSupported() ? WalletReadyState.Loadable : WalletReadyState.Unsupported;
|
|
39
|
+
#accountSelector;
|
|
40
|
+
#selectedAccount;
|
|
41
|
+
#publicKey;
|
|
42
|
+
#handleChangeEvent = async (properties) => {
|
|
43
|
+
if (properties.accounts && properties.accounts.length > 0) {
|
|
44
|
+
this.#declareWalletAsInstalled();
|
|
45
|
+
const nextSelectedAccount = await this.#accountSelector(properties.accounts);
|
|
46
|
+
if (nextSelectedAccount !== this.#selectedAccount) {
|
|
47
|
+
this.#selectedAccount = nextSelectedAccount;
|
|
48
|
+
this.#publicKey = void 0;
|
|
49
|
+
this.emit("connect", this.publicKey);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
constructor(wallet, config) {
|
|
54
|
+
super();
|
|
55
|
+
this.#accountSelector = async (accounts) => {
|
|
56
|
+
const selectedBase64EncodedAddress = await config.addressSelector.select(accounts.map(({ publicKey }) => fromUint8Array(new Uint8Array(publicKey))));
|
|
57
|
+
return accounts.find(({ publicKey }) => fromUint8Array(new Uint8Array(publicKey)) === selectedBase64EncodedAddress) ?? accounts[0];
|
|
58
|
+
};
|
|
59
|
+
this.#wallet = wallet;
|
|
60
|
+
this.#wallet.features[StandardEvents].on("change", this.#handleChangeEvent);
|
|
61
|
+
this.name = this.#wallet.name;
|
|
62
|
+
this.icon = this.#wallet.icon;
|
|
63
|
+
this.url = this.#wallet.url;
|
|
64
|
+
}
|
|
65
|
+
get publicKey() {
|
|
66
|
+
if (!this.#publicKey && this.#selectedAccount) try {
|
|
67
|
+
this.#publicKey = new PublicKey(this.#selectedAccount.publicKey);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
throw new WalletPublicKeyError(e instanceof Error && e?.message || "Unknown error", e);
|
|
70
|
+
}
|
|
71
|
+
return this.#publicKey ?? null;
|
|
72
|
+
}
|
|
73
|
+
get connected() {
|
|
74
|
+
return this.#wallet.connected;
|
|
75
|
+
}
|
|
76
|
+
get connecting() {
|
|
77
|
+
return this.#connecting;
|
|
78
|
+
}
|
|
79
|
+
get readyState() {
|
|
80
|
+
return this.#readyState;
|
|
81
|
+
}
|
|
82
|
+
/** @deprecated Use `autoConnect()` instead. */
|
|
83
|
+
async autoConnect_DO_NOT_USE_OR_YOU_WILL_BE_FIRED() {
|
|
84
|
+
return await this.autoConnect();
|
|
85
|
+
}
|
|
86
|
+
async autoConnect() {
|
|
87
|
+
this.#connect(true);
|
|
88
|
+
}
|
|
89
|
+
async connect() {
|
|
90
|
+
this.#connect();
|
|
91
|
+
}
|
|
92
|
+
async #connect(autoConnect = false) {
|
|
93
|
+
if (this.connecting || this.connected) return;
|
|
94
|
+
return await this.#runWithGuard(async () => {
|
|
95
|
+
if (this.#readyState !== WalletReadyState.Installed && this.#readyState !== WalletReadyState.Loadable) throw new WalletNotReadyError();
|
|
96
|
+
this.#connecting = true;
|
|
97
|
+
try {
|
|
98
|
+
await this.#wallet.features[StandardConnect].connect({ silent: autoConnect });
|
|
99
|
+
} catch (e) {
|
|
100
|
+
throw new WalletConnectionError(e instanceof Error && e.message || "Unknown error", e);
|
|
101
|
+
} finally {
|
|
102
|
+
this.#connecting = false;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/** @deprecated Use `connect()` or `autoConnect()` instead. */
|
|
107
|
+
async performAuthorization(signInPayload) {
|
|
108
|
+
try {
|
|
109
|
+
const cachedAuthorizationResult = await this.#wallet.cachedAuthorizationResult;
|
|
110
|
+
if (cachedAuthorizationResult) {
|
|
111
|
+
await this.#wallet.features[StandardConnect].connect({ silent: true });
|
|
112
|
+
return cachedAuthorizationResult;
|
|
113
|
+
}
|
|
114
|
+
if (signInPayload) await this.#wallet.features[SolanaSignIn].signIn(signInPayload);
|
|
115
|
+
else await this.#wallet.features[StandardConnect].connect();
|
|
116
|
+
return await await this.#wallet.cachedAuthorizationResult;
|
|
117
|
+
} catch (e) {
|
|
118
|
+
throw new WalletConnectionError(e instanceof Error && e.message || "Unknown error", e);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async disconnect() {
|
|
122
|
+
return await this.#runWithGuard(async () => {
|
|
123
|
+
this.#connecting = false;
|
|
124
|
+
this.#publicKey = void 0;
|
|
125
|
+
this.#selectedAccount = void 0;
|
|
126
|
+
await this.#wallet.features[StandardDisconnect].disconnect();
|
|
127
|
+
this.emit("disconnect");
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
async signIn(input) {
|
|
131
|
+
return this.#runWithGuard(async () => {
|
|
132
|
+
if (this.#readyState !== WalletReadyState.Installed && this.#readyState !== WalletReadyState.Loadable) throw new WalletNotReadyError();
|
|
133
|
+
this.#connecting = true;
|
|
134
|
+
try {
|
|
135
|
+
const outputs = await this.#wallet.features[SolanaSignIn].signIn({
|
|
136
|
+
...input,
|
|
137
|
+
domain: input?.domain ?? window.location.host
|
|
138
|
+
});
|
|
139
|
+
if (outputs.length > 0) return outputs[0];
|
|
140
|
+
else throw new Error("Sign in failed, no sign in result returned by wallet");
|
|
141
|
+
} catch (e) {
|
|
142
|
+
throw new WalletConnectionError(e instanceof Error && e.message || "Unknown error", e);
|
|
143
|
+
} finally {
|
|
144
|
+
this.#connecting = false;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async signMessage(message) {
|
|
149
|
+
return await this.#runWithGuard(async () => {
|
|
150
|
+
const account = this.#assertIsAuthorized();
|
|
151
|
+
try {
|
|
152
|
+
return (await this.#wallet.features[SolanaSignMessage].signMessage({
|
|
153
|
+
account,
|
|
154
|
+
message
|
|
155
|
+
}))[0].signature;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
throw new WalletSignMessageError(error?.message, error);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async sendTransaction(transaction, connection, options) {
|
|
162
|
+
return await this.#runWithGuard(async () => {
|
|
163
|
+
const account = this.#assertIsAuthorized();
|
|
164
|
+
try {
|
|
165
|
+
function getTargetCommitment() {
|
|
166
|
+
let targetCommitment;
|
|
167
|
+
switch (connection.commitment) {
|
|
168
|
+
case "confirmed":
|
|
169
|
+
case "finalized":
|
|
170
|
+
case "processed":
|
|
171
|
+
targetCommitment = connection.commitment;
|
|
172
|
+
break;
|
|
173
|
+
default: targetCommitment = "finalized";
|
|
174
|
+
}
|
|
175
|
+
let targetPreflightCommitment;
|
|
176
|
+
switch (options?.preflightCommitment) {
|
|
177
|
+
case "confirmed":
|
|
178
|
+
case "finalized":
|
|
179
|
+
case "processed":
|
|
180
|
+
targetPreflightCommitment = options.preflightCommitment;
|
|
181
|
+
break;
|
|
182
|
+
case void 0:
|
|
183
|
+
targetPreflightCommitment = targetCommitment;
|
|
184
|
+
break;
|
|
185
|
+
default: targetPreflightCommitment = "finalized";
|
|
186
|
+
}
|
|
187
|
+
return (targetPreflightCommitment === "finalized" ? 2 : targetPreflightCommitment === "confirmed" ? 1 : 0) < (targetCommitment === "finalized" ? 2 : targetCommitment === "confirmed" ? 1 : 0) ? targetPreflightCommitment : targetCommitment;
|
|
188
|
+
}
|
|
189
|
+
if (SolanaSignAndSendTransaction in this.#wallet.features) {
|
|
190
|
+
const chain = chainOrClusterToChainId(this.#wallet.currentAuthorization.chain);
|
|
191
|
+
const [signature] = (await this.#wallet.features[SolanaSignAndSendTransaction].signAndSendTransaction({
|
|
192
|
+
account,
|
|
193
|
+
transaction: transaction.serialize(),
|
|
194
|
+
chain,
|
|
195
|
+
options: options ? {
|
|
196
|
+
skipPreflight: options.skipPreflight,
|
|
197
|
+
maxRetries: options.maxRetries
|
|
198
|
+
} : void 0
|
|
199
|
+
})).map((output) => {
|
|
200
|
+
return fromUint8Array(output.signature);
|
|
201
|
+
});
|
|
202
|
+
return signature;
|
|
203
|
+
} else {
|
|
204
|
+
const [signedTransaction] = await this.#performSignTransactions([transaction]);
|
|
205
|
+
if (isVersionedTransaction(signedTransaction)) return await connection.sendTransaction(signedTransaction);
|
|
206
|
+
else {
|
|
207
|
+
const serializedTransaction = signedTransaction.serialize();
|
|
208
|
+
return await connection.sendRawTransaction(serializedTransaction, {
|
|
209
|
+
...options,
|
|
210
|
+
preflightCommitment: getTargetCommitment()
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
} catch (error) {
|
|
215
|
+
throw new WalletSendTransactionError(error?.message, error);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async signTransaction(transaction) {
|
|
220
|
+
return await this.#runWithGuard(async () => {
|
|
221
|
+
const [signedTransaction] = await this.#performSignTransactions([transaction]);
|
|
222
|
+
return signedTransaction;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
async signAllTransactions(transactions) {
|
|
226
|
+
return await this.#runWithGuard(async () => {
|
|
227
|
+
return await this.#performSignTransactions(transactions);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
#declareWalletAsInstalled() {
|
|
231
|
+
if (this.#readyState !== WalletReadyState.Installed) this.emit("readyStateChange", this.#readyState = WalletReadyState.Installed);
|
|
232
|
+
}
|
|
233
|
+
#assertIsAuthorized() {
|
|
234
|
+
if (!this.#wallet.isAuthorized || !this.#selectedAccount) throw new WalletNotConnectedError();
|
|
235
|
+
return this.#selectedAccount;
|
|
236
|
+
}
|
|
237
|
+
async #performSignTransactions(transactions) {
|
|
238
|
+
const account = this.#assertIsAuthorized();
|
|
239
|
+
try {
|
|
240
|
+
if (SolanaSignTransaction in this.#wallet.features) return this.#wallet.features[SolanaSignTransaction].signTransaction(...transactions.map((value) => {
|
|
241
|
+
return {
|
|
242
|
+
account,
|
|
243
|
+
transaction: value.serialize()
|
|
244
|
+
};
|
|
245
|
+
})).then((outputs) => {
|
|
246
|
+
return outputs.map((output) => {
|
|
247
|
+
const byteArray = output.signedTransaction;
|
|
248
|
+
const messageOffset = byteArray[0] * SIGNATURE_LENGTH_IN_BYTES + 1;
|
|
249
|
+
if (VersionedMessage.deserializeMessageVersion(byteArray.slice(messageOffset, byteArray.length)) === "legacy") return Transaction.from(byteArray);
|
|
250
|
+
else return VersionedTransaction.deserialize(byteArray);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
else throw new Error("Connected wallet does not support signing transactions");
|
|
254
|
+
} catch (error) {
|
|
255
|
+
throw new WalletSignTransactionError(error?.message, error);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async #runWithGuard(callback) {
|
|
259
|
+
try {
|
|
260
|
+
return await callback();
|
|
261
|
+
} catch (e) {
|
|
262
|
+
this.emit("error", e);
|
|
263
|
+
throw e;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
var LocalSolanaMobileWalletAdapter = class extends BaseSolanaMobileWalletAdapter {
|
|
268
|
+
constructor(config) {
|
|
269
|
+
const chain = chainOrClusterToChainId(config.chain ?? config.cluster);
|
|
270
|
+
super(new LocalSolanaMobileWalletAdapterWallet({
|
|
271
|
+
appIdentity: config.appIdentity,
|
|
272
|
+
authorizationCache: {
|
|
273
|
+
set: config.authorizationResultCache.set,
|
|
274
|
+
get: async () => {
|
|
275
|
+
return await config.authorizationResultCache.get();
|
|
276
|
+
},
|
|
277
|
+
clear: config.authorizationResultCache.clear
|
|
278
|
+
},
|
|
279
|
+
chains: [chain],
|
|
280
|
+
chainSelector: createDefaultChainSelector(),
|
|
281
|
+
onWalletNotFound: async () => {
|
|
282
|
+
config.onWalletNotFound(this);
|
|
283
|
+
}
|
|
284
|
+
}), {
|
|
285
|
+
addressSelector: config.addressSelector,
|
|
286
|
+
chain
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
var RemoteSolanaMobileWalletAdapter = class extends BaseSolanaMobileWalletAdapter {
|
|
291
|
+
constructor(config) {
|
|
292
|
+
const chain = chainOrClusterToChainId(config.chain);
|
|
293
|
+
super(new RemoteSolanaMobileWalletAdapterWallet({
|
|
294
|
+
appIdentity: config.appIdentity,
|
|
295
|
+
authorizationCache: {
|
|
296
|
+
set: config.authorizationResultCache.set,
|
|
297
|
+
get: async () => {
|
|
298
|
+
return await config.authorizationResultCache.get();
|
|
299
|
+
},
|
|
300
|
+
clear: config.authorizationResultCache.clear
|
|
301
|
+
},
|
|
302
|
+
chains: [chain],
|
|
303
|
+
chainSelector: createDefaultChainSelector(),
|
|
304
|
+
remoteHostAuthority: config.remoteHostAuthority,
|
|
305
|
+
onWalletNotFound: async () => {
|
|
306
|
+
config.onWalletNotFound(this);
|
|
307
|
+
}
|
|
308
|
+
}), {
|
|
309
|
+
addressSelector: config.addressSelector,
|
|
310
|
+
chain
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
var SolanaMobileWalletAdapter = class extends LocalSolanaMobileWalletAdapter {};
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/createDefaultAddressSelector.ts
|
|
391
317
|
function createDefaultAddressSelector() {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
},
|
|
396
|
-
};
|
|
318
|
+
return { async select(addresses) {
|
|
319
|
+
return addresses[0];
|
|
320
|
+
} };
|
|
397
321
|
}
|
|
398
|
-
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/createDefaultAuthorizationResultCache.ts
|
|
399
324
|
function createDefaultAuthorizationResultCache() {
|
|
400
|
-
|
|
325
|
+
return createDefaultAuthorizationCache();
|
|
401
326
|
}
|
|
402
|
-
|
|
327
|
+
//#endregion
|
|
328
|
+
//#region src/createDefaultWalletNotFoundHandler.ts
|
|
403
329
|
async function defaultWalletNotFoundHandler(mobileWalletAdapter) {
|
|
404
|
-
|
|
330
|
+
return defaultErrorModalWalletNotFoundHandler();
|
|
405
331
|
}
|
|
406
332
|
function createDefaultWalletNotFoundHandler() {
|
|
407
|
-
|
|
333
|
+
return defaultWalletNotFoundHandler;
|
|
408
334
|
}
|
|
409
|
-
|
|
335
|
+
//#endregion
|
|
410
336
|
export { LocalSolanaMobileWalletAdapter, RemoteSolanaMobileWalletAdapter, SolanaMobileWalletAdapter, SolanaMobileWalletAdapterRemoteWalletName, SolanaMobileWalletAdapterWalletName, createDefaultAddressSelector, createDefaultAuthorizationResultCache, createDefaultWalletNotFoundHandler };
|
|
337
|
+
|
|
338
|
+
//# sourceMappingURL=index.browser.js.map
|