@aptos-labs/wallet-adapter-core 0.2.1 → 0.2.2
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 +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +41 -9
- package/dist/index.mjs +41 -9
- package/package.json +1 -1
- package/src/WalletCore.ts +57 -11
- package/src/types.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @aptos-labs/wallet-adapter-core
|
|
2
2
|
|
|
3
|
+
## 0.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d4e298f: Support Lodable wallet
|
|
8
|
+
Implement multi signature verification
|
|
9
|
+
Add a new optional property propertyName for multi-chain wallet
|
|
10
|
+
- 5fc6981: Throw wallet not found error when trying to connect to an uninstalled wallet
|
|
11
|
+
- d711f43: Import tweetnacl package via default export to support commonJS
|
|
12
|
+
|
|
3
13
|
## 0.2.1
|
|
4
14
|
|
|
5
15
|
### 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
|
|
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
|
-
|
|
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[
|
|
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
|
-
|
|
281
|
-
|
|
282
|
-
return;
|
|
282
|
+
if (!selectedWallet || selectedWallet.readyState !== "Installed" /* Installed */ && selectedWallet.readyState !== "Loadable" /* Loadable */) {
|
|
283
|
+
throw new WalletConnectionError(`${walletName} wallet not found`).message;
|
|
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
|
|
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
|
|
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
|
-
|
|
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[
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
return;
|
|
248
|
+
if (!selectedWallet || selectedWallet.readyState !== "Installed" /* Installed */ && selectedWallet.readyState !== "Loadable" /* Loadable */) {
|
|
249
|
+
throw new WalletConnectionError(`${walletName} wallet not found`).message;
|
|
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
package/src/WalletCore.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HexString, Types } from "aptos";
|
|
2
2
|
import EventEmitter from "eventemitter3";
|
|
3
|
-
import
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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[
|
|
67
|
+
wallet.provider = window[providerName as any];
|
|
65
68
|
this.emit("readyStateChange", wallet);
|
|
66
69
|
return true;
|
|
67
70
|
}
|
|
@@ -171,8 +174,16 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
|
|
|
171
174
|
const selectedWallet = this._wallets?.find(
|
|
172
175
|
(wallet: Wallet) => wallet.name === walletName
|
|
173
176
|
);
|
|
174
|
-
|
|
175
|
-
if (
|
|
177
|
+
|
|
178
|
+
if (
|
|
179
|
+
!selectedWallet ||
|
|
180
|
+
(selectedWallet.readyState !== WalletReadyState.Installed &&
|
|
181
|
+
selectedWallet.readyState !== WalletReadyState.Loadable)
|
|
182
|
+
) {
|
|
183
|
+
throw new WalletConnectionError(`${walletName} wallet not found`)
|
|
184
|
+
.message;
|
|
185
|
+
}
|
|
186
|
+
|
|
176
187
|
if (this._connected) {
|
|
177
188
|
await this.disconnect();
|
|
178
189
|
}
|
|
@@ -329,7 +340,42 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
|
|
|
329
340
|
let verified = false;
|
|
330
341
|
if (Array.isArray(response.signature)) {
|
|
331
342
|
// multi sig wallets
|
|
332
|
-
|
|
343
|
+
const { fullMessage, signature, bitmap } = response;
|
|
344
|
+
if (bitmap) {
|
|
345
|
+
const minKeysRequired = this._account.minKeysRequired as number;
|
|
346
|
+
if (signature.length < minKeysRequired) {
|
|
347
|
+
verified = false;
|
|
348
|
+
} else {
|
|
349
|
+
// Getting an array which marks the keys signing the message with 1, while marking 0 for the keys not being used.
|
|
350
|
+
const bits = Array.from(bitmap).flatMap((n) =>
|
|
351
|
+
Array.from({ length: 8 }).map((_, i) => (n >> i) & 1)
|
|
352
|
+
);
|
|
353
|
+
// Filter out indexes of the keys we need
|
|
354
|
+
const index = bits.map((_, i) => i).filter((i) => bits[i]);
|
|
355
|
+
|
|
356
|
+
const publicKeys = this._account.publicKey as string[];
|
|
357
|
+
const matchedPublicKeys = publicKeys.filter(
|
|
358
|
+
(_: string, i: number) => index.includes(i)
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
verified = true;
|
|
362
|
+
for (let i = 0; i < signature.length; i++) {
|
|
363
|
+
const isSigVerified = nacl.sign.detached.verify(
|
|
364
|
+
Buffer.from(fullMessage),
|
|
365
|
+
Buffer.from(signature[i], "hex"),
|
|
366
|
+
Buffer.from(matchedPublicKeys[i], "hex")
|
|
367
|
+
); // `isSigVerified` should be `true` for every signature
|
|
368
|
+
|
|
369
|
+
if (!isSigVerified) {
|
|
370
|
+
verified = false;
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
} else {
|
|
376
|
+
throw new WalletSignMessageAndVerifyError("Failed to get a bitmap")
|
|
377
|
+
.message;
|
|
378
|
+
}
|
|
333
379
|
} else {
|
|
334
380
|
// single sig wallets
|
|
335
381
|
// support for when address doesnt have hex prefix (0x)
|
|
@@ -338,7 +384,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
|
|
|
338
384
|
);
|
|
339
385
|
// support for when address doesnt have hex prefix (0x)
|
|
340
386
|
const signature = new HexString(response.signature);
|
|
341
|
-
verified = sign.detached.verify(
|
|
387
|
+
verified = nacl.sign.detached.verify(
|
|
342
388
|
Buffer.from(response.fullMessage),
|
|
343
389
|
Buffer.from(signature.noPrefix(), "hex"),
|
|
344
390
|
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>;
|