80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import HDKey from 'hdkey';
|
||
import { pubToAddress, toChecksumAddress } from 'ethereumjs-util';
|
||
|
||
interface DeriveAddressesParams {
|
||
chainCode: string;
|
||
publicKey: string;
|
||
index: number;
|
||
numAddresses: number;
|
||
}
|
||
export function deriveAddressesFromPubKey(params: DeriveAddressesParams): string[] {
|
||
const addresses = [];
|
||
const hdkey = new HDKey();
|
||
hdkey.chainCode = new Buffer(params.chainCode, 'hex');
|
||
hdkey.publicKey = new Buffer(params.publicKey, 'hex');
|
||
|
||
for (let i = params.index; i < params.index + params.numAddresses; i++) {
|
||
const dkey = hdkey.derive(`m/${i}`);
|
||
const address = (pubToAddress(dkey.publicKey, true) as Buffer).toString('hex');
|
||
addresses.push(toChecksumAddress(address));
|
||
}
|
||
|
||
return addresses;
|
||
}
|
||
|
||
// Ledger throws a few types of errors
|
||
interface U2FError {
|
||
metaData: {
|
||
type: string;
|
||
code: number;
|
||
};
|
||
}
|
||
interface ErrorWithId {
|
||
id: string;
|
||
message: string;
|
||
name: string;
|
||
stack: string;
|
||
}
|
||
type LedgerError = U2FError | ErrorWithId | Error | string;
|
||
|
||
const isU2FError = (err: LedgerError): err is U2FError =>
|
||
!!err && !!(err as U2FError).metaData;
|
||
const isStringError = (err: LedgerError): err is string => typeof err === 'string';
|
||
const isErrorWithId = (err: LedgerError): err is ErrorWithId =>
|
||
err.hasOwnProperty('id') && err.hasOwnProperty('message');
|
||
|
||
export function parseLedgerError(err: LedgerError): string {
|
||
// https://developers.yubico.com/U2F/Libraries/Client_error_codes.html
|
||
if (isU2FError(err)) {
|
||
// Timeout
|
||
if (err.metaData.code === 5) {
|
||
return 'The request timed out';
|
||
}
|
||
|
||
return err.metaData.type;
|
||
}
|
||
|
||
if (isStringError(err)) {
|
||
// Wrong app logged into
|
||
if (err.includes('6804')) {
|
||
return 'Wrong application selected on your ledger device. Make sure you’ve selected the ETH app.';
|
||
}
|
||
// Ledger locked
|
||
if (err.includes('6801')) {
|
||
return 'Your Ledger device is locked';
|
||
}
|
||
|
||
return err;
|
||
}
|
||
|
||
if (isErrorWithId(err)) {
|
||
// Browser doesn't support U2F
|
||
if (err.message.includes('U2F not supported')) {
|
||
return 'Your browser doesn’t support Ledger. Please try updating it, or using a different one.';
|
||
}
|
||
}
|
||
|
||
// Other
|
||
return err.message || err.toString();
|
||
}
|