Skip to content

Commit 88d8650

Browse files
authored
Merge pull request #204 from KeystoneHQ/update-metamask-usb-keyring
Update metamask usb keyring
2 parents 032fa0d + 2b163a6 commit 88d8650

File tree

3 files changed

+131
-34
lines changed

3 files changed

+131
-34
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"typescript": "^5.2.2"
6767
},
6868
"dependencies": {
69+
"@metamask/keyring-utils": "^3.1.0",
6970
"uuid": "^8.3.2"
7071
}
7172
}

packages/metamask-keystone-usb-keyring/src/KeystoneUSBKeyring.ts

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
TypedTransaction,
1313
} from "@ethereumjs/tx";
1414
import { KeystoneBridge } from "./KeystoneBridge";
15+
import { Keyring } from '@metamask/keyring-utils';
16+
import { Hex, Json } from "@metamask/utils";
1517

1618
const keyringType = "Keystone Hardware";
1719
const pathBase = "m";
@@ -42,19 +44,19 @@ export enum KEYSTONE_HD_PATH {
4244
LEDGER_LEGACY = "m/44'/60'/0'/X",
4345
}
4446

45-
export class KeystoneUSBKeyring {
47+
export class KeystoneUSBKeyring implements Keyring {
4648
// @ts-ignore
4749
private version = 1;
4850
static type = keyringType;
4951
protected xfp: string;
50-
protected type = keyringType;
52+
readonly type: string = keyringType;
5153
protected initialized: boolean;
5254
protected hdPath: string;
5355
protected accounts: string[];
5456
protected currentAccount: number;
5557
protected page: number;
5658
protected perPage: number;
57-
protected hdk: any;
59+
protected hdk: HDKey | undefined;
5860
protected name: string;
5961

6062
//standard and ledger legacy
@@ -90,7 +92,7 @@ export class KeystoneUSBKeyring {
9092
this.ledger_live_accounts = {};
9193
this.hd_account = "";
9294

93-
this.deserialize(opts);
95+
this.deserialize(opts ?? null);
9496

9597
this.bridge = bridge;
9698
this.bridgeSetup = false;
@@ -183,9 +185,10 @@ export class KeystoneUSBKeyring {
183185
});
184186
}
185187

186-
deserialize(opts?: StoredKeyring): void {
187-
if (opts) {
188+
async deserialize(state: Json): Promise<void> {
189+
if (state) {
188190
//common props;
191+
const opts = state as StoredKeyring;
189192
this.accounts = opts.accounts;
190193
this.currentAccount = opts.currentAccount;
191194
this.page = opts.page;
@@ -217,19 +220,19 @@ export class KeystoneUSBKeyring {
217220
this.unlockedAccount = parseInt(index, 10);
218221
};
219222

220-
async addAccounts(n = 1): Promise<string[]> {
223+
async addAccounts(n = 1): Promise<Hex[]> {
221224
const from = this.unlockedAccount;
222225
const to = from + n;
223-
const newAccounts = [];
226+
const newAccounts: Hex[] = [];
224227

225228
for (let i = from; i < to; i++) {
226229
const address = await this.__addressFromIndex(pathBase, i);
227-
newAccounts.push(address);
230+
newAccounts.push(address as Hex);
228231
this.page = 0;
229232
this.unlockedAccount++;
230233
}
231234
this.accounts = this.accounts.concat(newAccounts);
232-
return this.accounts;
235+
return this.accounts as Hex[];
233236
}
234237

235238
getFirstPage(): Promise<PagedAccount[]> {
@@ -306,11 +309,11 @@ export class KeystoneUSBKeyring {
306309
}
307310
}
308311

309-
getAccounts() {
310-
return Promise.resolve(this.accounts);
312+
async getAccounts(): Promise<Hex[]>{
313+
return Promise.resolve(this.accounts as Hex[]);
311314
}
312315

313-
removeAccount(address: string): void {
316+
removeAccount(address: Hex): void {
314317
if (
315318
!this.accounts.map((a) => a.toLowerCase()).includes(address.toLowerCase())
316319
) {
@@ -322,7 +325,7 @@ export class KeystoneUSBKeyring {
322325
}
323326

324327
async signTransaction(
325-
address: string,
328+
address: Hex,
326329
tx: TypedTransaction
327330
): Promise<TypedTransaction> {
328331
await this.setUpBridge();
@@ -338,13 +341,11 @@ export class KeystoneUSBKeyring {
338341
}
339342
const hdPath = await this._pathFromAddress(address);
340343
const isLegacy = tx.type === 0;
341-
342344
const { r, s, v } = await this.bridge.signTransaction(
343345
hdPath,
344346
messageToSign.toString("hex"),
345347
isLegacy
346348
);
347-
348349
return TransactionFactory.fromTxData(
349350
{
350351
...tx,
@@ -357,13 +358,13 @@ export class KeystoneUSBKeyring {
357358
);
358359
}
359360

360-
signMessage(withAccount: string, data: string): Promise<string> {
361+
signMessage(withAccount: Hex, data: Hex): Promise<string> {
361362
return this.signPersonalMessage(withAccount, data);
362363
}
363364

364365
async signPersonalMessage(
365-
withAccount: string,
366-
messageHex: string
366+
withAccount: Hex,
367+
messageHex: Hex
367368
): Promise<string> {
368369
await this.setUpBridge();
369370
const usignedHex = stripHexPrefix(messageHex);
@@ -385,7 +386,7 @@ export class KeystoneUSBKeyring {
385386
);
386387
}
387388

388-
async signTypedData(withAccount: string, typedData: any): Promise<string> {
389+
async signTypedData(withAccount: Hex, typedData: any): Promise<string> {
389390
await this.setUpBridge();
390391
const hdPath = await this._pathFromAddress(withAccount);
391392

@@ -412,7 +413,7 @@ export class KeystoneUSBKeyring {
412413
}
413414
const childrenPath =
414415
this.hdPath === KEYSTONE_HD_PATH.STANDARD ? `0/${i}` : String(i);
415-
const dkey = this.hdk.derive(`${pb}/${childrenPath}`);
416+
const dkey = this.hdk!.derive(`${pb}/${childrenPath}`);
416417
const address =
417418
"0x" + publicToAddress(dkey.publicKey, true).toString("hex");
418419
return toChecksumAddress(address);
@@ -458,4 +459,9 @@ export class KeystoneUSBKeyring {
458459
return path;
459460
}
460461
}
462+
463+
async destroy(): Promise<void> {
464+
this.forgetDevice();
465+
this.hdk = undefined;
466+
}
461467
}

0 commit comments

Comments
 (0)