@aptos-labs/wallet-adapter-core 0.1.7 → 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # @aptos-labs/wallet-adapter-core
2
+
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 1c3576e: Throw Sign Transaction is not supported error
8
+
9
+ ## 0.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 576bb57: Add chainId and url propoerties to NetworkInfo type
14
+ - 6e53116: Add support to verify a signed message
15
+
16
+ ### Patch Changes
17
+
18
+ - 18a0429: Add properties to SignMessageResponse interface
19
+ - 42e29f6: Add multisig support for AccountInfo
package/dist/index.d.ts CHANGED
@@ -30,11 +30,14 @@ declare type WalletName<T extends string = string> = T & {
30
30
  __brand__: "WalletName";
31
31
  };
32
32
  declare type NetworkInfo = {
33
- name: NetworkName | undefined;
33
+ name: NetworkName;
34
+ chainId?: string;
35
+ url?: string;
34
36
  };
35
37
  declare type AccountInfo = {
36
38
  address: string;
37
- publicKey: string;
39
+ publicKey: string | string[];
40
+ minKeysRequired?: number;
38
41
  };
39
42
  interface AptosWalletErrorResult {
40
43
  code: number;
@@ -96,14 +99,15 @@ interface SignMessagePayload {
96
99
  nonce: string;
97
100
  }
98
101
  interface SignMessageResponse {
99
- address: string;
100
- application: string;
101
- chainId: number;
102
+ address?: string;
103
+ application?: string;
104
+ chainId?: number;
102
105
  fullMessage: string;
103
106
  message: string;
104
107
  nonce: string;
105
108
  prefix: "APTOS";
106
- signature: string;
109
+ signature: string | string[];
110
+ bitmap?: Uint8Array;
107
111
  }
108
112
 
109
113
  declare class WalletCore extends EventEmitter<WalletCoreEvents> {
@@ -115,7 +119,7 @@ declare class WalletCore extends EventEmitter<WalletCoreEvents> {
115
119
  private _connected;
116
120
  constructor(plugins: Wallet[]);
117
121
  private scopePollingDetectionStrategy;
118
- private isWalletExists;
122
+ private doesWalletExist;
119
123
  private clearData;
120
124
  setWallet(wallet: Wallet | null): void;
121
125
  setAccount(account: AccountInfo | null): void;
@@ -191,6 +195,7 @@ declare class WalletCore extends EventEmitter<WalletCoreEvents> {
191
195
  @throws WalletNetworkChangeError
192
196
  */
193
197
  onNetworkChange(): Promise<void>;
198
+ signMessageAndVerify(message: SignMessagePayload): Promise<boolean>;
194
199
  }
195
200
 
196
201
  export { AccountInfo, AdapterPlugin, AdapterPluginEvents, AdapterPluginProps, AptosWalletErrorResult, NetworkInfo, NetworkName, PluginProvider, SignMessagePayload, SignMessageResponse, Wallet, WalletCore, WalletCoreEvents, WalletInfo, WalletName, WalletReadyState };
package/dist/index.js CHANGED
@@ -33,7 +33,10 @@ __export(src_exports, {
33
33
  module.exports = __toCommonJS(src_exports);
34
34
 
35
35
  // src/WalletCore.ts
36
+ var import_aptos = require("aptos");
36
37
  var import_eventemitter3 = __toESM(require("eventemitter3"));
38
+ var import_tweetnacl = require("tweetnacl");
39
+ var import_buffer = require("buffer");
37
40
 
38
41
  // src/constants.ts
39
42
  var WalletReadyState = /* @__PURE__ */ ((WalletReadyState2) => {
@@ -117,6 +120,12 @@ var WalletSignMessageError = class extends WalletError {
117
120
  this.name = "WalletSignMessageError";
118
121
  }
119
122
  };
123
+ var WalletSignMessageAndVerifyError = class extends WalletError {
124
+ constructor() {
125
+ super(...arguments);
126
+ this.name = "WalletSignMessageAndVerifyError";
127
+ }
128
+ };
120
129
  var WalletSignAndSubmitMessageError = class extends WalletError {
121
130
  constructor() {
122
131
  super(...arguments);
@@ -129,6 +138,12 @@ var WalletSignTransactionError = class extends WalletError {
129
138
  this.name = "WalletSignTransactionError";
130
139
  }
131
140
  };
141
+ var WalletNotSupportedMethod = class extends WalletError {
142
+ constructor() {
143
+ super(...arguments);
144
+ this.name = "WalletNotSupportedMethod";
145
+ }
146
+ };
132
147
 
133
148
  // src/utils/scopePollingDetectionStrategy.ts
134
149
  function scopePollingDetectionStrategy(detect) {
@@ -199,7 +214,7 @@ var WalletCore = class extends import_eventemitter3.default {
199
214
  }
200
215
  });
201
216
  }
202
- isWalletExists() {
217
+ doesWalletExist() {
203
218
  if (!this._connected || this._connecting || !this._wallet)
204
219
  throw new WalletNotConnectedError().name;
205
220
  if (!(this._wallet.readyState === "Loadable" /* Loadable */ || this._wallet.readyState === "Installed" /* Installed */))
@@ -287,7 +302,7 @@ var WalletCore = class extends import_eventemitter3.default {
287
302
  async disconnect() {
288
303
  var _a;
289
304
  try {
290
- this.isWalletExists();
305
+ this.doesWalletExist();
291
306
  await ((_a = this._wallet) == null ? void 0 : _a.disconnect());
292
307
  this.clearData();
293
308
  this.emit("disconnect");
@@ -298,7 +313,7 @@ var WalletCore = class extends import_eventemitter3.default {
298
313
  async signAndSubmitTransaction(transaction) {
299
314
  var _a;
300
315
  try {
301
- this.isWalletExists();
316
+ this.doesWalletExist();
302
317
  const response = await ((_a = this._wallet) == null ? void 0 : _a.signAndSubmitTransaction(
303
318
  transaction
304
319
  ));
@@ -309,10 +324,14 @@ var WalletCore = class extends import_eventemitter3.default {
309
324
  }
310
325
  }
311
326
  async signTransaction(transaction) {
327
+ var _a;
328
+ if (this._wallet && !("signTransaction" in this._wallet)) {
329
+ throw new WalletNotSupportedMethod(
330
+ `Sign Transaction is not supported by ${(_a = this.wallet) == null ? void 0 : _a.name}`
331
+ ).message;
332
+ }
312
333
  try {
313
- if (this._wallet && !("signTransaction" in this._wallet))
314
- return null;
315
- this.isWalletExists();
334
+ this.doesWalletExist();
316
335
  const response = await this._wallet.signTransaction(transaction);
317
336
  return response;
318
337
  } catch (error) {
@@ -323,7 +342,7 @@ var WalletCore = class extends import_eventemitter3.default {
323
342
  async signMessage(message) {
324
343
  var _a;
325
344
  try {
326
- this.isWalletExists();
345
+ this.doesWalletExist();
327
346
  if (!this._wallet)
328
347
  return null;
329
348
  const response = await ((_a = this._wallet) == null ? void 0 : _a.signMessage(message));
@@ -336,7 +355,7 @@ var WalletCore = class extends import_eventemitter3.default {
336
355
  async onAccountChange() {
337
356
  var _a;
338
357
  try {
339
- this.isWalletExists();
358
+ this.doesWalletExist();
340
359
  await ((_a = this._wallet) == null ? void 0 : _a.onAccountChange((data) => {
341
360
  this.setAccount({ ...data });
342
361
  this.emit("accountChange", this._account);
@@ -349,7 +368,7 @@ var WalletCore = class extends import_eventemitter3.default {
349
368
  async onNetworkChange() {
350
369
  var _a;
351
370
  try {
352
- this.isWalletExists();
371
+ this.doesWalletExist();
353
372
  await ((_a = this._wallet) == null ? void 0 : _a.onNetworkChange((data) => {
354
373
  this.setNetwork({ ...data });
355
374
  this.emit("networkChange", this._network);
@@ -359,6 +378,34 @@ var WalletCore = class extends import_eventemitter3.default {
359
378
  throw new WalletNetworkChangeError(errMsg).message;
360
379
  }
361
380
  }
381
+ async signMessageAndVerify(message) {
382
+ var _a;
383
+ try {
384
+ this.doesWalletExist();
385
+ if (!this._account)
386
+ throw new Error("No account found!");
387
+ const response = await ((_a = this._wallet) == null ? void 0 : _a.signMessage(message));
388
+ if (!response)
389
+ throw new WalletSignMessageAndVerifyError("Failed to sign a message").message;
390
+ let verified = false;
391
+ if (Array.isArray(response.signature)) {
392
+ } else {
393
+ const currentAccountPublicKey = new import_aptos.HexString(
394
+ this._account.publicKey
395
+ );
396
+ const signature = new import_aptos.HexString(response.signature);
397
+ verified = import_tweetnacl.sign.detached.verify(
398
+ import_buffer.Buffer.from(response.fullMessage),
399
+ import_buffer.Buffer.from(signature.noPrefix(), "hex"),
400
+ import_buffer.Buffer.from(currentAccountPublicKey.noPrefix(), "hex")
401
+ );
402
+ }
403
+ return verified;
404
+ } catch (error) {
405
+ const errMsg = typeof error == "object" && "message" in error ? error.message : error;
406
+ throw new WalletSignMessageAndVerifyError(errMsg).message;
407
+ }
408
+ }
362
409
  };
363
410
  // Annotate the CommonJS export names for ESM import in node:
364
411
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1,5 +1,8 @@
1
1
  // src/WalletCore.ts
2
+ import { HexString } from "aptos";
2
3
  import EventEmitter from "eventemitter3";
4
+ import { sign } from "tweetnacl";
5
+ import { Buffer } from "buffer";
3
6
 
4
7
  // src/constants.ts
5
8
  var WalletReadyState = /* @__PURE__ */ ((WalletReadyState2) => {
@@ -83,6 +86,12 @@ var WalletSignMessageError = class extends WalletError {
83
86
  this.name = "WalletSignMessageError";
84
87
  }
85
88
  };
89
+ var WalletSignMessageAndVerifyError = class extends WalletError {
90
+ constructor() {
91
+ super(...arguments);
92
+ this.name = "WalletSignMessageAndVerifyError";
93
+ }
94
+ };
86
95
  var WalletSignAndSubmitMessageError = class extends WalletError {
87
96
  constructor() {
88
97
  super(...arguments);
@@ -95,6 +104,12 @@ var WalletSignTransactionError = class extends WalletError {
95
104
  this.name = "WalletSignTransactionError";
96
105
  }
97
106
  };
107
+ var WalletNotSupportedMethod = class extends WalletError {
108
+ constructor() {
109
+ super(...arguments);
110
+ this.name = "WalletNotSupportedMethod";
111
+ }
112
+ };
98
113
 
99
114
  // src/utils/scopePollingDetectionStrategy.ts
100
115
  function scopePollingDetectionStrategy(detect) {
@@ -165,7 +180,7 @@ var WalletCore = class extends EventEmitter {
165
180
  }
166
181
  });
167
182
  }
168
- isWalletExists() {
183
+ doesWalletExist() {
169
184
  if (!this._connected || this._connecting || !this._wallet)
170
185
  throw new WalletNotConnectedError().name;
171
186
  if (!(this._wallet.readyState === "Loadable" /* Loadable */ || this._wallet.readyState === "Installed" /* Installed */))
@@ -253,7 +268,7 @@ var WalletCore = class extends EventEmitter {
253
268
  async disconnect() {
254
269
  var _a;
255
270
  try {
256
- this.isWalletExists();
271
+ this.doesWalletExist();
257
272
  await ((_a = this._wallet) == null ? void 0 : _a.disconnect());
258
273
  this.clearData();
259
274
  this.emit("disconnect");
@@ -264,7 +279,7 @@ var WalletCore = class extends EventEmitter {
264
279
  async signAndSubmitTransaction(transaction) {
265
280
  var _a;
266
281
  try {
267
- this.isWalletExists();
282
+ this.doesWalletExist();
268
283
  const response = await ((_a = this._wallet) == null ? void 0 : _a.signAndSubmitTransaction(
269
284
  transaction
270
285
  ));
@@ -275,10 +290,14 @@ var WalletCore = class extends EventEmitter {
275
290
  }
276
291
  }
277
292
  async signTransaction(transaction) {
293
+ var _a;
294
+ if (this._wallet && !("signTransaction" in this._wallet)) {
295
+ throw new WalletNotSupportedMethod(
296
+ `Sign Transaction is not supported by ${(_a = this.wallet) == null ? void 0 : _a.name}`
297
+ ).message;
298
+ }
278
299
  try {
279
- if (this._wallet && !("signTransaction" in this._wallet))
280
- return null;
281
- this.isWalletExists();
300
+ this.doesWalletExist();
282
301
  const response = await this._wallet.signTransaction(transaction);
283
302
  return response;
284
303
  } catch (error) {
@@ -289,7 +308,7 @@ var WalletCore = class extends EventEmitter {
289
308
  async signMessage(message) {
290
309
  var _a;
291
310
  try {
292
- this.isWalletExists();
311
+ this.doesWalletExist();
293
312
  if (!this._wallet)
294
313
  return null;
295
314
  const response = await ((_a = this._wallet) == null ? void 0 : _a.signMessage(message));
@@ -302,7 +321,7 @@ var WalletCore = class extends EventEmitter {
302
321
  async onAccountChange() {
303
322
  var _a;
304
323
  try {
305
- this.isWalletExists();
324
+ this.doesWalletExist();
306
325
  await ((_a = this._wallet) == null ? void 0 : _a.onAccountChange((data) => {
307
326
  this.setAccount({ ...data });
308
327
  this.emit("accountChange", this._account);
@@ -315,7 +334,7 @@ var WalletCore = class extends EventEmitter {
315
334
  async onNetworkChange() {
316
335
  var _a;
317
336
  try {
318
- this.isWalletExists();
337
+ this.doesWalletExist();
319
338
  await ((_a = this._wallet) == null ? void 0 : _a.onNetworkChange((data) => {
320
339
  this.setNetwork({ ...data });
321
340
  this.emit("networkChange", this._network);
@@ -325,6 +344,34 @@ var WalletCore = class extends EventEmitter {
325
344
  throw new WalletNetworkChangeError(errMsg).message;
326
345
  }
327
346
  }
347
+ async signMessageAndVerify(message) {
348
+ var _a;
349
+ try {
350
+ this.doesWalletExist();
351
+ if (!this._account)
352
+ throw new Error("No account found!");
353
+ const response = await ((_a = this._wallet) == null ? void 0 : _a.signMessage(message));
354
+ if (!response)
355
+ throw new WalletSignMessageAndVerifyError("Failed to sign a message").message;
356
+ let verified = false;
357
+ if (Array.isArray(response.signature)) {
358
+ } else {
359
+ const currentAccountPublicKey = new HexString(
360
+ this._account.publicKey
361
+ );
362
+ const signature = new HexString(response.signature);
363
+ verified = sign.detached.verify(
364
+ Buffer.from(response.fullMessage),
365
+ Buffer.from(signature.noPrefix(), "hex"),
366
+ Buffer.from(currentAccountPublicKey.noPrefix(), "hex")
367
+ );
368
+ }
369
+ return verified;
370
+ } catch (error) {
371
+ const errMsg = typeof error == "object" && "message" in error ? error.message : error;
372
+ throw new WalletSignMessageAndVerifyError(errMsg).message;
373
+ }
374
+ }
328
375
  };
329
376
  export {
330
377
  NetworkName,
package/jest.config.js ADDED
@@ -0,0 +1,5 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
2
+ module.exports = {
3
+ preset: "ts-jest",
4
+ testEnvironment: "node",
5
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aptos-labs/wallet-adapter-core",
3
- "version": "0.1.7",
3
+ "version": "0.2.1",
4
4
  "description": "Aptos Wallet Adapter Core",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -27,21 +27,27 @@
27
27
  "Wallet Adapter",
28
28
  "Aptos Wallet"
29
29
  ],
30
- "scripts": {
31
- "build": "tsup src/index.ts --format esm,cjs --dts",
32
- "dev": "tsup src/index.ts --format esm,cjs --watch --dts",
33
- "lint": "TIMING=1 eslint \"src/**/*.ts*\"",
34
- "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
35
- },
36
30
  "devDependencies": {
37
- "@aptos-labs/wallet-adapter-tsconfig": "workspace:*",
31
+ "@types/jest": "^29.2.4",
38
32
  "eslint": "^8.15.0",
39
- "@aptos-labs/eslint-config-adapter": "workspace:*",
33
+ "jest": "^29.3.1",
34
+ "ts-jest": "^29.0.3",
40
35
  "tsup": "^5.10.1",
41
- "typescript": "^4.5.3"
36
+ "typescript": "^4.5.3",
37
+ "@aptos-labs/eslint-config-adapter": "0.0.0",
38
+ "@aptos-labs/wallet-adapter-tsconfig": "0.0.0"
42
39
  },
43
40
  "dependencies": {
44
41
  "aptos": "^1.3.17",
45
- "eventemitter3": "^4.0.7"
42
+ "buffer": "^6.0.3",
43
+ "eventemitter3": "^4.0.7",
44
+ "tweetnacl": "^1.0.3"
45
+ },
46
+ "scripts": {
47
+ "build": "tsup src/index.ts --format esm,cjs --dts",
48
+ "dev": "tsup src/index.ts --format esm,cjs --watch --dts",
49
+ "test": "jest",
50
+ "lint": "TIMING=1 eslint \"src/**/*.ts*\"",
51
+ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
46
52
  }
47
- }
53
+ }
package/src/WalletCore.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { Types } from "aptos";
1
+ import { HexString, Types } from "aptos";
2
2
  import EventEmitter from "eventemitter3";
3
+ import { sign } from "tweetnacl";
4
+ import { Buffer } from "buffer";
3
5
 
4
6
  import { WalletReadyState } from "./constants";
5
7
  import {
@@ -12,7 +14,9 @@ import {
12
14
  WalletNotConnectedError,
13
15
  WalletNotReadyError,
14
16
  WalletNotSelectedError,
17
+ WalletNotSupportedMethod,
15
18
  WalletSignAndSubmitMessageError,
19
+ WalletSignMessageAndVerifyError,
16
20
  WalletSignMessageError,
17
21
  WalletSignTransactionError,
18
22
  } from "./error";
@@ -67,7 +71,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
67
71
  });
68
72
  }
69
73
 
70
- private isWalletExists(): boolean | WalletNotConnectedError {
74
+ private doesWalletExist(): boolean | WalletNotConnectedError {
71
75
  if (!this._connected || this._connecting || !this._wallet)
72
76
  throw new WalletNotConnectedError().name;
73
77
  if (
@@ -197,7 +201,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
197
201
  */
198
202
  async disconnect(): Promise<void> {
199
203
  try {
200
- this.isWalletExists();
204
+ this.doesWalletExist();
201
205
  await this._wallet?.disconnect();
202
206
  this.clearData();
203
207
  this.emit("disconnect");
@@ -216,7 +220,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
216
220
  transaction: Types.TransactionPayload
217
221
  ): Promise<any> {
218
222
  try {
219
- this.isWalletExists();
223
+ this.doesWalletExist();
220
224
  const response = await this._wallet?.signAndSubmitTransaction(
221
225
  transaction
222
226
  );
@@ -237,9 +241,14 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
237
241
  async signTransaction(
238
242
  transaction: Types.TransactionPayload
239
243
  ): Promise<Uint8Array | null> {
244
+ if (this._wallet && !("signTransaction" in this._wallet)) {
245
+ throw new WalletNotSupportedMethod(
246
+ `Sign Transaction is not supported by ${this.wallet?.name}`
247
+ ).message;
248
+ }
249
+
240
250
  try {
241
- if (this._wallet && !("signTransaction" in this._wallet)) return null;
242
- this.isWalletExists();
251
+ this.doesWalletExist();
243
252
  const response = await (this._wallet as any).signTransaction(transaction);
244
253
  return response;
245
254
  } catch (error: any) {
@@ -259,7 +268,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
259
268
  message: SignMessagePayload
260
269
  ): Promise<SignMessageResponse | null> {
261
270
  try {
262
- this.isWalletExists();
271
+ this.doesWalletExist();
263
272
  if (!this._wallet) return null;
264
273
  const response = await this._wallet?.signMessage(message);
265
274
  return response;
@@ -277,7 +286,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
277
286
  */
278
287
  async onAccountChange(): Promise<void> {
279
288
  try {
280
- this.isWalletExists();
289
+ this.doesWalletExist();
281
290
  await this._wallet?.onAccountChange((data: AccountInfo) => {
282
291
  this.setAccount({ ...data });
283
292
  this.emit("accountChange", this._account);
@@ -296,7 +305,7 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
296
305
  */
297
306
  async onNetworkChange(): Promise<void> {
298
307
  try {
299
- this.isWalletExists();
308
+ this.doesWalletExist();
300
309
  await this._wallet?.onNetworkChange((data: NetworkInfo) => {
301
310
  this.setNetwork({ ...data });
302
311
  this.emit("networkChange", this._network);
@@ -307,4 +316,39 @@ export class WalletCore extends EventEmitter<WalletCoreEvents> {
307
316
  throw new WalletNetworkChangeError(errMsg).message;
308
317
  }
309
318
  }
319
+
320
+ async signMessageAndVerify(message: SignMessagePayload): Promise<boolean> {
321
+ try {
322
+ this.doesWalletExist();
323
+ if (!this._account) throw new Error("No account found!");
324
+ const response = await this._wallet?.signMessage(message);
325
+ if (!response)
326
+ throw new WalletSignMessageAndVerifyError("Failed to sign a message")
327
+ .message;
328
+ // Verify that the bytes were signed using the private key that matches the known public key
329
+ let verified = false;
330
+ if (Array.isArray(response.signature)) {
331
+ // multi sig wallets
332
+ // TODO - implement multi sig wallets
333
+ } else {
334
+ // single sig wallets
335
+ // support for when address doesnt have hex prefix (0x)
336
+ const currentAccountPublicKey = new HexString(
337
+ this._account.publicKey as string
338
+ );
339
+ // support for when address doesnt have hex prefix (0x)
340
+ const signature = new HexString(response.signature);
341
+ verified = sign.detached.verify(
342
+ Buffer.from(response.fullMessage),
343
+ Buffer.from(signature.noPrefix(), "hex"),
344
+ Buffer.from(currentAccountPublicKey.noPrefix(), "hex")
345
+ );
346
+ }
347
+ return verified;
348
+ } catch (error: any) {
349
+ const errMsg =
350
+ typeof error == "object" && "message" in error ? error.message : error;
351
+ throw new WalletSignMessageAndVerifyError(errMsg).message;
352
+ }
353
+ }
310
354
  }
@@ -0,0 +1,106 @@
1
+ import { AptosAccount } from "aptos";
2
+ import {
3
+ SignMessagePayload,
4
+ SignMessageResponse,
5
+ Wallet,
6
+ WalletName,
7
+ } from "../types";
8
+ import { WalletCore } from "../WalletCore";
9
+
10
+ const signMessageResponseMock: SignMessageResponse = {
11
+ fullMessage: "",
12
+ message: "message",
13
+ nonce: Date.now().toString(),
14
+ prefix: "APTOS",
15
+ signature: "",
16
+ };
17
+
18
+ const mockSignMessagePayload: SignMessagePayload = {
19
+ message: "my-message",
20
+ nonce: Date.now().toString(),
21
+ };
22
+
23
+ const connectMock = jest.fn(() => Promise.resolve(console.log("connect")));
24
+ const disconnectMock = jest.fn(() =>
25
+ Promise.resolve(console.log("disconnect"))
26
+ );
27
+ const networkMock = jest.fn(() => Promise.resolve(console.log("network")));
28
+ const signAndSubmitTransactionkMock = jest.fn((transaction, options?) =>
29
+ Promise.resolve({ hash: "signAndSubmitTransactionkMock" })
30
+ );
31
+ const signMessageMock = jest.fn((message) =>
32
+ Promise.resolve(signMessageResponseMock)
33
+ );
34
+
35
+ const onNetworkChangeeMock = jest.fn((callback: any) =>
36
+ Promise.resolve(console.log("onNetworkChange"))
37
+ );
38
+ const onAccountChangeMock = jest.fn((callback: any) =>
39
+ Promise.resolve(console.log("onAccountChangeMock"))
40
+ );
41
+
42
+ const walletMock: Wallet = {
43
+ name: "wallet-name" as WalletName<"wallet-name">,
44
+ url: "my-url",
45
+ icon: `data:image/png;base64,uri`,
46
+ provider: {},
47
+ connect: connectMock,
48
+ disconnect: disconnectMock,
49
+ network: networkMock,
50
+ signAndSubmitTransaction: signAndSubmitTransactionkMock,
51
+ signMessage: signMessageMock,
52
+ onNetworkChange: onNetworkChangeeMock,
53
+ onAccountChange: onAccountChangeMock,
54
+ };
55
+
56
+ const pluginsMock: Wallet[] = [walletMock];
57
+
58
+ const walletCoreMock = new WalletCore(pluginsMock);
59
+
60
+ describe("signMessageAndVerify", () => {
61
+ walletCoreMock.setWallet(walletMock);
62
+ const account = new AptosAccount();
63
+ walletCoreMock.setAccount({
64
+ address: account.address().hex(),
65
+ publicKey: account.pubKey().hex(),
66
+ });
67
+ signMessageResponseMock.fullMessage = `\nmessage: ${signMessageResponseMock.message} \nnonce: ${signMessageResponseMock.nonce}`;
68
+ jest
69
+ .spyOn(walletCoreMock as any, "doesWalletExist")
70
+ .mockImplementation(() => true);
71
+
72
+ it("it should verify a signed message", async () => {
73
+ const encoder = new TextEncoder();
74
+ const messageBytes = encoder.encode(signMessageResponseMock.fullMessage);
75
+ const signature = account.signBuffer(messageBytes);
76
+ const signatureString = signature.noPrefix();
77
+ signMessageResponseMock.signature = signatureString;
78
+
79
+ jest
80
+ .spyOn((walletCoreMock as any)._wallet, "signMessage")
81
+ .mockResolvedValue(signMessageResponseMock);
82
+
83
+ const verified = await walletCoreMock.signMessageAndVerify(
84
+ mockSignMessagePayload
85
+ );
86
+ expect(verified).toBeTruthy();
87
+ });
88
+
89
+ it("it should fails to verify signed message", async () => {
90
+ const account2 = new AptosAccount();
91
+ const encoder = new TextEncoder();
92
+ const messageBytes = encoder.encode(signMessageResponseMock.fullMessage);
93
+ const signature = account2.signBuffer(messageBytes);
94
+ const signatureString = signature.noPrefix();
95
+ signMessageResponseMock.signature = signatureString;
96
+
97
+ jest
98
+ .spyOn((walletCoreMock as any)._wallet, "signMessage")
99
+ .mockResolvedValue(signMessageResponseMock);
100
+
101
+ const verified = await walletCoreMock.signMessageAndVerify(
102
+ mockSignMessagePayload
103
+ );
104
+ expect(verified).toBeFalsy();
105
+ });
106
+ });
@@ -71,6 +71,10 @@ export class WalletSignMessageError extends WalletError {
71
71
  name = "WalletSignMessageError";
72
72
  }
73
73
 
74
+ export class WalletSignMessageAndVerifyError extends WalletError {
75
+ name = "WalletSignMessageAndVerifyError";
76
+ }
77
+
74
78
  export class WalletSignAndSubmitMessageError extends WalletError {
75
79
  name = "WalletSignAndSubmitMessageError";
76
80
  }
@@ -94,3 +98,7 @@ export class WalletWindowClosedError extends WalletError {
94
98
  export class WalletResponseError extends WalletError {
95
99
  name = "WalletResponseError";
96
100
  }
101
+
102
+ export class WalletNotSupportedMethod extends WalletError {
103
+ name = "WalletNotSupportedMethod";
104
+ }
package/src/types.ts CHANGED
@@ -6,12 +6,15 @@ export type WalletName<T extends string = string> = T & {
6
6
  __brand__: "WalletName";
7
7
  };
8
8
  export type NetworkInfo = {
9
- name: NetworkName | undefined;
9
+ name: NetworkName;
10
+ chainId?: string;
11
+ url?: string;
10
12
  };
11
13
 
12
14
  export type AccountInfo = {
13
15
  address: string;
14
- publicKey: string;
16
+ publicKey: string | string[];
17
+ minKeysRequired?: number
15
18
  };
16
19
 
17
20
  export interface AptosWalletErrorResult {
@@ -90,12 +93,13 @@ export interface SignMessagePayload {
90
93
  }
91
94
 
92
95
  export interface SignMessageResponse {
93
- address: string;
94
- application: string;
95
- chainId: number;
96
+ address?: string;
97
+ application?: string;
98
+ chainId?: number;
96
99
  fullMessage: string; // The message that was generated to sign
97
100
  message: string; // The message passed in by the user
98
101
  nonce: string;
99
102
  prefix: "APTOS"; // Should always be APTOS
100
- signature: string; // The signed full message
103
+ signature: string | string[]; // The signed full message
104
+ bitmap?: Uint8Array; // a 4-byte (32 bits) bit-vector of length N
101
105
  }