@aptos-labs/wallet-adapter-core 0.2.1 → 0.2.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @aptos-labs/wallet-adapter-core
2
2
 
3
+ ## 0.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 017556c: connect() to simply return if wallet is not installed
8
+
9
+ ## 0.2.2
10
+
11
+ ### Patch Changes
12
+
13
+ - d4e298f: Support Lodable wallet
14
+ Implement multi signature verification
15
+ Add a new optional property propertyName for multi-chain wallet
16
+ - 5fc6981: Throw wallet not found error when trying to connect to an uninstalled wallet
17
+ - d711f43: Import tweetnacl package via default export to support commonJS
18
+
3
19
  ## 0.2.1
4
20
 
5
21
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -66,6 +66,7 @@ interface AdapterPluginProps<Name extends string = string> {
66
66
  name: WalletName<Name>;
67
67
  url: string;
68
68
  icon: `data:image/${"svg+xml" | "webp" | "png" | "gif"};base64,${string}`;
69
+ providerName?: string;
69
70
  provider: any;
70
71
  connect(): Promise<any>;
71
72
  disconnect: () => Promise<any>;
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ module.exports = __toCommonJS(src_exports);
35
35
  // src/WalletCore.ts
36
36
  var import_aptos = require("aptos");
37
37
  var import_eventemitter3 = __toESM(require("eventemitter3"));
38
- var import_tweetnacl = require("tweetnacl");
38
+ var import_tweetnacl = __toESM(require("tweetnacl"));
39
39
  var import_buffer = require("buffer");
40
40
 
41
41
  // src/constants.ts
@@ -200,12 +200,15 @@ var WalletCore = class extends import_eventemitter3.default {
200
200
  scopePollingDetectionStrategy() {
201
201
  var _a;
202
202
  (_a = this._wallets) == null ? void 0 : _a.forEach((wallet) => {
203
- wallet.readyState = typeof window === "undefined" || typeof document === "undefined" ? "Unsupported" /* Unsupported */ : "NotDetected" /* NotDetected */;
203
+ if (!wallet.readyState) {
204
+ wallet.readyState = typeof window === "undefined" || typeof document === "undefined" ? "Unsupported" /* Unsupported */ : "NotDetected" /* NotDetected */;
205
+ }
204
206
  if (typeof window !== "undefined") {
205
207
  scopePollingDetectionStrategy(() => {
206
- if (Object.keys(window).includes(wallet.name.toLowerCase())) {
208
+ const providerName = wallet.providerName || wallet.name.toLowerCase();
209
+ if (Object.keys(window).includes(providerName)) {
207
210
  wallet.readyState = "Installed" /* Installed */;
208
- wallet.provider = window[wallet.name.toLowerCase()];
211
+ wallet.provider = window[providerName];
209
212
  this.emit("readyStateChange", wallet);
210
213
  return true;
211
214
  }
@@ -276,10 +279,9 @@ var WalletCore = class extends import_eventemitter3.default {
276
279
  const selectedWallet = (_a = this._wallets) == null ? void 0 : _a.find(
277
280
  (wallet) => wallet.name === walletName
278
281
  );
279
- if (!selectedWallet)
280
- return;
281
- if (selectedWallet.readyState !== "Installed" /* Installed */)
282
+ if (!selectedWallet || selectedWallet.readyState !== "Installed" /* Installed */ && selectedWallet.readyState !== "Loadable" /* Loadable */) {
282
283
  return;
284
+ }
283
285
  if (this._connected) {
284
286
  await this.disconnect();
285
287
  }
@@ -389,12 +391,42 @@ var WalletCore = class extends import_eventemitter3.default {
389
391
  throw new WalletSignMessageAndVerifyError("Failed to sign a message").message;
390
392
  let verified = false;
391
393
  if (Array.isArray(response.signature)) {
394
+ const { fullMessage, signature, bitmap } = response;
395
+ if (bitmap) {
396
+ const minKeysRequired = this._account.minKeysRequired;
397
+ if (signature.length < minKeysRequired) {
398
+ verified = false;
399
+ } else {
400
+ const bits = Array.from(bitmap).flatMap(
401
+ (n) => Array.from({ length: 8 }).map((_, i) => n >> i & 1)
402
+ );
403
+ const index = bits.map((_, i) => i).filter((i) => bits[i]);
404
+ const publicKeys = this._account.publicKey;
405
+ const matchedPublicKeys = publicKeys.filter(
406
+ (_, i) => index.includes(i)
407
+ );
408
+ verified = true;
409
+ for (let i = 0; i < signature.length; i++) {
410
+ const isSigVerified = import_tweetnacl.default.sign.detached.verify(
411
+ import_buffer.Buffer.from(fullMessage),
412
+ import_buffer.Buffer.from(signature[i], "hex"),
413
+ import_buffer.Buffer.from(matchedPublicKeys[i], "hex")
414
+ );
415
+ if (!isSigVerified) {
416
+ verified = false;
417
+ break;
418
+ }
419
+ }
420
+ }
421
+ } else {
422
+ throw new WalletSignMessageAndVerifyError("Failed to get a bitmap").message;
423
+ }
392
424
  } else {
393
425
  const currentAccountPublicKey = new import_aptos.HexString(
394
426
  this._account.publicKey
395
427
  );
396
428
  const signature = new import_aptos.HexString(response.signature);
397
- verified = import_tweetnacl.sign.detached.verify(
429
+ verified = import_tweetnacl.default.sign.detached.verify(
398
430
  import_buffer.Buffer.from(response.fullMessage),
399
431
  import_buffer.Buffer.from(signature.noPrefix(), "hex"),
400
432
  import_buffer.Buffer.from(currentAccountPublicKey.noPrefix(), "hex")
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/WalletCore.ts
2
2
  import { HexString } from "aptos";
3
3
  import EventEmitter from "eventemitter3";
4
- import { sign } from "tweetnacl";
4
+ import nacl from "tweetnacl";
5
5
  import { Buffer } from "buffer";
6
6
 
7
7
  // src/constants.ts
@@ -166,12 +166,15 @@ var WalletCore = class extends EventEmitter {
166
166
  scopePollingDetectionStrategy() {
167
167
  var _a;
168
168
  (_a = this._wallets) == null ? void 0 : _a.forEach((wallet) => {
169
- wallet.readyState = typeof window === "undefined" || typeof document === "undefined" ? "Unsupported" /* Unsupported */ : "NotDetected" /* NotDetected */;
169
+ if (!wallet.readyState) {
170
+ wallet.readyState = typeof window === "undefined" || typeof document === "undefined" ? "Unsupported" /* Unsupported */ : "NotDetected" /* NotDetected */;
171
+ }
170
172
  if (typeof window !== "undefined") {
171
173
  scopePollingDetectionStrategy(() => {
172
- if (Object.keys(window).includes(wallet.name.toLowerCase())) {
174
+ const providerName = wallet.providerName || wallet.name.toLowerCase();
175
+ if (Object.keys(window).includes(providerName)) {
173
176
  wallet.readyState = "Installed" /* Installed */;
174
- wallet.provider = window[wallet.name.toLowerCase()];
177
+ wallet.provider = window[providerName];
175
178
  this.emit("readyStateChange", wallet);
176
179
  return true;
177
180
  }
@@ -242,10 +245,9 @@ var WalletCore = class extends EventEmitter {
242
245
  const selectedWallet = (_a = this._wallets) == null ? void 0 : _a.find(
243
246
  (wallet) => wallet.name === walletName
244
247
  );
245
- if (!selectedWallet)
246
- return;
247
- if (selectedWallet.readyState !== "Installed" /* Installed */)
248
+ if (!selectedWallet || selectedWallet.readyState !== "Installed" /* Installed */ && selectedWallet.readyState !== "Loadable" /* Loadable */) {
248
249
  return;
250
+ }
249
251
  if (this._connected) {
250
252
  await this.disconnect();
251
253
  }
@@ -355,12 +357,42 @@ var WalletCore = class extends EventEmitter {
355
357
  throw new WalletSignMessageAndVerifyError("Failed to sign a message").message;
356
358
  let verified = false;
357
359
  if (Array.isArray(response.signature)) {
360
+ const { fullMessage, signature, bitmap } = response;
361
+ if (bitmap) {
362
+ const minKeysRequired = this._account.minKeysRequired;
363
+ if (signature.length < minKeysRequired) {
364
+ verified = false;
365
+ } else {
366
+ const bits = Array.from(bitmap).flatMap(
367
+ (n) => Array.from({ length: 8 }).map((_, i) => n >> i & 1)
368
+ );
369
+ const index = bits.map((_, i) => i).filter((i) => bits[i]);
370
+ const publicKeys = this._account.publicKey;
371
+ const matchedPublicKeys = publicKeys.filter(
372
+ (_, i) => index.includes(i)
373
+ );
374
+ verified = true;
375
+ for (let i = 0; i < signature.length; i++) {
376
+ const isSigVerified = nacl.sign.detached.verify(
377
+ Buffer.from(fullMessage),
378
+ Buffer.from(signature[i], "hex"),
379
+ Buffer.from(matchedPublicKeys[i], "hex")
380
+ );
381
+ if (!isSigVerified) {
382
+ verified = false;
383
+ break;
384
+ }
385
+ }
386
+ }
387
+ } else {
388
+ throw new WalletSignMessageAndVerifyError("Failed to get a bitmap").message;
389
+ }
358
390
  } else {
359
391
  const currentAccountPublicKey = new HexString(
360
392
  this._account.publicKey
361
393
  );
362
394
  const signature = new HexString(response.signature);
363
- verified = sign.detached.verify(
395
+ verified = nacl.sign.detached.verify(
364
396
  Buffer.from(response.fullMessage),
365
397
  Buffer.from(signature.noPrefix(), "hex"),
366
398
  Buffer.from(currentAccountPublicKey.noPrefix(), "hex")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aptos-labs/wallet-adapter-core",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Aptos Wallet Adapter Core",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
package/src/WalletCore.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { HexString, Types } from "aptos";
2
2
  import EventEmitter from "eventemitter3";
3
- import { sign } from "tweetnacl";
3
+ import nacl from "tweetnacl";
4
4
  import { Buffer } from "buffer";
5
5
 
6
6
  import { WalletReadyState } from "./constants";
@@ -53,15 +53,18 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
53
53
 
54
54
  private scopePollingDetectionStrategy() {
55
55
  this._wallets?.forEach((wallet: Wallet) => {
56
- wallet.readyState =
57
- typeof window === "undefined" || typeof document === "undefined"
58
- ? WalletReadyState.Unsupported
59
- : WalletReadyState.NotDetected;
56
+ if (!wallet.readyState) {
57
+ wallet.readyState =
58
+ typeof window === "undefined" || typeof document === "undefined"
59
+ ? WalletReadyState.Unsupported
60
+ : WalletReadyState.NotDetected;
61
+ }
60
62
  if (typeof window !== "undefined") {
61
63
  scopePollingDetectionStrategy(() => {
62
- if (Object.keys(window).includes(wallet.name.toLowerCase())) {
64
+ const providerName = wallet.providerName || wallet.name.toLowerCase();
65
+ if (Object.keys(window).includes(providerName)) {
63
66
  wallet.readyState = WalletReadyState.Installed;
64
- wallet.provider = window[wallet.name.toLowerCase() as any];
67
+ wallet.provider = window[providerName as any];
65
68
  this.emit("readyStateChange", wallet);
66
69
  return true;
67
70
  }
@@ -171,8 +174,15 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
171
174
  const selectedWallet = this._wallets?.find(
172
175
  (wallet: Wallet) => wallet.name === walletName
173
176
  );
174
- if (!selectedWallet) return;
175
- if (selectedWallet.readyState !== WalletReadyState.Installed) return;
177
+
178
+ if (
179
+ !selectedWallet ||
180
+ (selectedWallet.readyState !== WalletReadyState.Installed &&
181
+ selectedWallet.readyState !== WalletReadyState.Loadable)
182
+ ) {
183
+ return;
184
+ }
185
+
176
186
  if (this._connected) {
177
187
  await this.disconnect();
178
188
  }
@@ -329,7 +339,42 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
329
339
  let verified = false;
330
340
  if (Array.isArray(response.signature)) {
331
341
  // multi sig wallets
332
- // TODO - implement multi sig wallets
342
+ const { fullMessage, signature, bitmap } = response;
343
+ if (bitmap) {
344
+ const minKeysRequired = this._account.minKeysRequired as number;
345
+ if (signature.length < minKeysRequired) {
346
+ verified = false;
347
+ } else {
348
+ // Getting an array which marks the keys signing the message with 1, while marking 0 for the keys not being used.
349
+ const bits = Array.from(bitmap).flatMap((n) =>
350
+ Array.from({ length: 8 }).map((_, i) => (n >> i) & 1)
351
+ );
352
+ // Filter out indexes of the keys we need
353
+ const index = bits.map((_, i) => i).filter((i) => bits[i]);
354
+
355
+ const publicKeys = this._account.publicKey as string[];
356
+ const matchedPublicKeys = publicKeys.filter(
357
+ (_: string, i: number) => index.includes(i)
358
+ );
359
+
360
+ verified = true;
361
+ for (let i = 0; i < signature.length; i++) {
362
+ const isSigVerified = nacl.sign.detached.verify(
363
+ Buffer.from(fullMessage),
364
+ Buffer.from(signature[i], "hex"),
365
+ Buffer.from(matchedPublicKeys[i], "hex")
366
+ ); // `isSigVerified` should be `true` for every signature
367
+
368
+ if (!isSigVerified) {
369
+ verified = false;
370
+ break;
371
+ }
372
+ }
373
+ }
374
+ } else {
375
+ throw new WalletSignMessageAndVerifyError("Failed to get a bitmap")
376
+ .message;
377
+ }
333
378
  } else {
334
379
  // single sig wallets
335
380
  // support for when address doesnt have hex prefix (0x)
@@ -338,7 +383,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
338
383
  );
339
384
  // support for when address doesnt have hex prefix (0x)
340
385
  const signature = new HexString(response.signature);
341
- verified = sign.detached.verify(
386
+ verified = nacl.sign.detached.verify(
342
387
  Buffer.from(response.fullMessage),
343
388
  Buffer.from(signature.noPrefix(), "hex"),
344
389
  Buffer.from(currentAccountPublicKey.noPrefix(), "hex")
package/src/types.ts CHANGED
@@ -50,6 +50,7 @@ export interface AdapterPluginProps<Name extends string = string> {
50
50
  name: WalletName<Name>;
51
51
  url: string;
52
52
  icon: `data:image/${"svg+xml" | "webp" | "png" | "gif"};base64,${string}`;
53
+ providerName?: string
53
54
  provider: any;
54
55
  connect(): Promise<any>;
55
56
  disconnect: () => Promise<any>;