aboutsummaryrefslogtreecommitdiffstats
path: root/packages/subproviders/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/subproviders/src')
-rw-r--r--packages/subproviders/src/globals.d.ts55
-rw-r--r--packages/subproviders/src/index.ts16
-rw-r--r--packages/subproviders/src/subproviders/injected_web3.ts16
-rw-r--r--packages/subproviders/src/subproviders/ledger.ts129
-rw-r--r--packages/subproviders/src/subproviders/redundant_rpc.ts31
-rw-r--r--packages/subproviders/src/subproviders/subprovider.ts22
-rw-r--r--packages/subproviders/src/types.ts12
7 files changed, 148 insertions, 133 deletions
diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts
index 520ca9232..53457fa24 100644
--- a/packages/subproviders/src/globals.d.ts
+++ b/packages/subproviders/src/globals.d.ts
@@ -1,10 +1,9 @@
-/// <reference types='chai-typescript-typings' />
-/// <reference types='chai-as-promised-typescript-typings' />
declare module 'dirty-chai';
declare module 'es6-promisify';
// tslint:disable:max-classes-per-file
// tslint:disable:class-name
+// tslint:disable:async-suffix
// tslint:disable:completed-docs
// Ethereumjs-tx declarations
@@ -46,19 +45,20 @@ declare module 'ledgerco' {
export class eth {
public comm: comm;
constructor(comm: comm);
- public getAddress_async(path: string, display?: boolean, chaincode?: boolean):
- Promise<{publicKey: string; address: string}>;
+ public getAddress_async(
+ path: string,
+ display?: boolean,
+ chaincode?: boolean,
+ ): Promise<{ publicKey: string; address: string; chainCode: string }>;
public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
- public getAppConfiguration_async(): Promise<{ arbitraryDataEnabled: number; version: string }>;
+ public getAppConfiguration_async(): Promise<{
+ arbitraryDataEnabled: number;
+ version: string;
+ }>;
public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
}
}
-// ethereum-address declarations
-declare module 'ethereum-address' {
- export const isAddress: (address: string) => boolean;
-}
-
// Semaphore-async-await declarations
declare module 'semaphore-async-await' {
class Semaphore {
@@ -77,21 +77,34 @@ declare module 'web3-provider-engine/subproviders/subprovider' {
declare module 'web3-provider-engine/subproviders/rpc' {
import * as Web3 from 'web3';
class RpcSubprovider {
- constructor(options: {rpcUrl: string});
+ constructor(options: { rpcUrl: string });
public handleRequest(
- payload: Web3.JSONRPCRequestPayload, next: () => void, end: (err: Error|null, data?: any) => void,
+ payload: Web3.JSONRPCRequestPayload,
+ next: () => void,
+ end: (err: Error | null, data?: any) => void,
): void;
}
export = RpcSubprovider;
}
declare module 'web3-provider-engine' {
- class Web3ProviderEngine {
- public on(event: string, handler: () => void): void;
- public send(payload: any): void;
- public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
- public addProvider(provider: any): void;
- public start(): void;
- public stop(): void;
- }
- export = Web3ProviderEngine;
+ class Web3ProviderEngine {
+ public on(event: string, handler: () => void): void;
+ public send(payload: any): void;
+ public sendAsync(payload: any, callback: (error: any, response: any) => void): void;
+ public addProvider(provider: any): void;
+ public start(): void;
+ public stop(): void;
+ }
+ export = Web3ProviderEngine;
+}
+
+// hdkey declarations
+declare module 'hdkey' {
+ class HDNode {
+ public publicKey: Buffer;
+ public chainCode: Buffer;
+ public constructor();
+ public derive(path: string): HDNode;
+ }
+ export = HDNode;
}
diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts
index 9b7cab3fa..720c4362f 100644
--- a/packages/subproviders/src/index.ts
+++ b/packages/subproviders/src/index.ts
@@ -4,18 +4,12 @@ import {
eth as LedgerEthereumClientFn,
} from 'ledgerco';
-import {LedgerEthereumClient} from './types';
+import { LedgerEthereumClient } from './types';
-export {InjectedWeb3Subprovider} from './subproviders/injected_web3';
-export {RedundantRPCSubprovider} from './subproviders/redundant_rpc';
-export {
- LedgerSubprovider,
-} from './subproviders/ledger';
-export {
- ECSignature,
- LedgerWalletSubprovider,
- LedgerCommunicationClient,
-} from './types';
+export { InjectedWeb3Subprovider } from './subproviders/injected_web3';
+export { RedundantRPCSubprovider } from './subproviders/redundant_rpc';
+export { LedgerSubprovider } from './subproviders/ledger';
+export { ECSignature, LedgerWalletSubprovider, LedgerCommunicationClient } from './types';
/**
* A factory method for creating a LedgerEthereumClient usable in a browser context.
diff --git a/packages/subproviders/src/subproviders/injected_web3.ts b/packages/subproviders/src/subproviders/injected_web3.ts
index 25d747a62..bd29acb22 100644
--- a/packages/subproviders/src/subproviders/injected_web3.ts
+++ b/packages/subproviders/src/subproviders/injected_web3.ts
@@ -9,29 +9,31 @@ import Web3ProviderEngine = require('web3-provider-engine');
* Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
*/
export class InjectedWeb3Subprovider {
- private injectedWeb3: Web3;
+ private _injectedWeb3: Web3;
constructor(injectedWeb3: Web3) {
- this.injectedWeb3 = injectedWeb3;
+ this._injectedWeb3 = injectedWeb3;
}
public handleRequest(
- payload: Web3.JSONRPCRequestPayload, next: () => void, end: (err: Error|null, result: any) => void,
+ payload: Web3.JSONRPCRequestPayload,
+ next: () => void,
+ end: (err: Error | null, result: any) => void,
) {
switch (payload.method) {
case 'web3_clientVersion':
- this.injectedWeb3.version.getNode(end);
+ this._injectedWeb3.version.getNode(end);
return;
case 'eth_accounts':
- this.injectedWeb3.eth.getAccounts(end);
+ this._injectedWeb3.eth.getAccounts(end);
return;
case 'eth_sendTransaction':
const [txParams] = payload.params;
- this.injectedWeb3.eth.sendTransaction(txParams, end);
+ this._injectedWeb3.eth.sendTransaction(txParams, end);
return;
case 'eth_sign':
const [address, message] = payload.params;
- this.injectedWeb3.eth.sign(address, message, end);
+ this._injectedWeb3.eth.sign(address, message, end);
return;
default:
diff --git a/packages/subproviders/src/subproviders/ledger.ts b/packages/subproviders/src/subproviders/ledger.ts
index e0a08f792..7267a793e 100644
--- a/packages/subproviders/src/subproviders/ledger.ts
+++ b/packages/subproviders/src/subproviders/ledger.ts
@@ -1,9 +1,8 @@
-import {assert} from '@0xproject/assert';
-import promisify = require('es6-promisify');
-import {isAddress} from 'ethereum-address';
+import { assert } from '@0xproject/assert';
+import { addressUtils } from '@0xproject/utils';
import EthereumTx = require('ethereumjs-tx');
import ethUtil = require('ethereumjs-util');
-import * as ledger from 'ledgerco';
+import HDNode = require('hdkey');
import * as _ from 'lodash';
import Semaphore from 'semaphore-async-await';
import Web3 = require('web3');
@@ -17,13 +16,12 @@ import {
ResponseWithTxParams,
} from '../types';
-import {Subprovider} from './subprovider';
+import { Subprovider } from './subprovider';
const DEFAULT_DERIVATION_PATH = `44'/60'/0'`;
const NUM_ADDRESSES_TO_FETCH = 10;
const ASK_FOR_ON_DEVICE_CONFIRMATION = false;
-const SHOULD_GET_CHAIN_CODE = false;
-const HEX_REGEX = /^[0-9A-Fa-f]+$/g;
+const SHOULD_GET_CHAIN_CODE = true;
export class LedgerSubprovider extends Subprovider {
private _nonceLock: Semaphore;
@@ -34,20 +32,8 @@ export class LedgerSubprovider extends Subprovider {
private _ledgerEthereumClientFactoryAsync: LedgerEthereumClientFactoryAsync;
private _ledgerClientIfExists?: LedgerEthereumClient;
private _shouldAlwaysAskForConfirmation: boolean;
- private static isValidHex(data: string) {
- if (!_.isString(data)) {
- return false;
- }
- const isHexPrefixed = data.slice(0, 2) === '0x';
- if (!isHexPrefixed) {
- return false;
- }
- const nonPrefixed = data.slice(2);
- const isValid = nonPrefixed.match(HEX_REGEX);
- return isValid;
- }
- private static validateSender(sender: string) {
- if (_.isUndefined(sender) || !isAddress(sender)) {
+ private static _validateSender(sender: string) {
+ if (_.isUndefined(sender) || !addressUtils.isAddress(sender)) {
throw new Error(LedgerSubproviderErrors.SenderInvalidOrNotSupplied);
}
}
@@ -58,12 +44,11 @@ export class LedgerSubprovider extends Subprovider {
this._networkId = config.networkId;
this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
- this._shouldAlwaysAskForConfirmation = !_.isUndefined(config.accountFetchingConfigs) &&
- !_.isUndefined(
- config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation,
- ) ?
- config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation :
- ASK_FOR_ON_DEVICE_CONFIRMATION;
+ this._shouldAlwaysAskForConfirmation =
+ !_.isUndefined(config.accountFetchingConfigs) &&
+ !_.isUndefined(config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation)
+ ? config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation
+ : ASK_FOR_ON_DEVICE_CONFIRMATION;
this._derivationPathIndex = 0;
}
public getPath(): string {
@@ -76,7 +61,9 @@ export class LedgerSubprovider extends Subprovider {
this._derivationPathIndex = pathIndex;
}
public async handleRequest(
- payload: Web3.JSONRPCRequestPayload, next: () => void, end: (err: Error|null, result?: any) => void,
+ payload: Web3.JSONRPCRequestPayload,
+ next: () => void,
+ end: (err: Error | null, result?: any) => void,
) {
let accounts;
let txParams;
@@ -102,8 +89,8 @@ export class LedgerSubprovider extends Subprovider {
case 'eth_sendTransaction':
txParams = payload.params[0];
try {
- LedgerSubprovider.validateSender(txParams.from);
- const result = await this.sendTransactionAsync(txParams);
+ LedgerSubprovider._validateSender(txParams.from);
+ const result = await this._sendTransactionAsync(txParams);
end(null, result);
} catch (err) {
end(err);
@@ -113,15 +100,16 @@ export class LedgerSubprovider extends Subprovider {
case 'eth_signTransaction':
txParams = payload.params[0];
try {
- const result = await this.signTransactionWithoutSendingAsync(txParams);
+ const result = await this._signTransactionWithoutSendingAsync(txParams);
end(null, result);
} catch (err) {
end(err);
}
return;
+ case 'eth_sign':
case 'personal_sign':
- const data = payload.params[0];
+ const data = payload.method === 'eth_sign' ? payload.params[1] : payload.params[0];
try {
if (_.isUndefined(data)) {
throw new Error(LedgerSubproviderErrors.DataMissingForSignPersonalMessage);
@@ -140,27 +128,38 @@ export class LedgerSubprovider extends Subprovider {
}
}
public async getAccountsAsync(): Promise<string[]> {
- this._ledgerClientIfExists = await this.createLedgerClientAsync();
+ this._ledgerClientIfExists = await this._createLedgerClientAsync();
+
+ let ledgerResponse;
+ try {
+ ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
+ this._derivationPath,
+ this._shouldAlwaysAskForConfirmation,
+ SHOULD_GET_CHAIN_CODE,
+ );
+ } finally {
+ await this._destroyLedgerClientAsync();
+ }
+
+ const hdKey = new HDNode();
+ hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
+ hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
- // TODO: replace with generating addresses without hitting Ledger
const accounts = [];
for (let i = 0; i < NUM_ADDRESSES_TO_FETCH; i++) {
- try {
- const derivationPath = `${this._derivationPath}/${i + this._derivationPathIndex}`;
- const result = await this._ledgerClientIfExists.getAddress_async(
- derivationPath, this._shouldAlwaysAskForConfirmation, SHOULD_GET_CHAIN_CODE,
- );
- accounts.push(result.address.toLowerCase());
- } catch (err) {
- await this.destoryLedgerClientAsync();
- throw err;
- }
+ const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
+ const derivedPublicKey = derivedHDNode.publicKey;
+ const shouldSanitizePublicKey = true;
+ const ethereumAddressUnprefixed = ethUtil
+ .publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
+ .toString('hex');
+ const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
+ accounts.push(ethereumAddressPrefixed.toLowerCase());
}
- await this.destoryLedgerClientAsync();
return accounts;
}
public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
- this._ledgerClientIfExists = await this.createLedgerClientAsync();
+ this._ledgerClientIfExists = await this._createLedgerClientAsync();
const tx = new EthereumTx(txParams);
@@ -171,7 +170,7 @@ export class LedgerSubprovider extends Subprovider {
const txHex = tx.serialize().toString('hex');
try {
- const derivationPath = this.getDerivationPath();
+ const derivationPath = this._getDerivationPath();
const result = await this._ledgerClientIfExists.signTransaction_async(derivationPath, txHex);
// Store signature in transaction
tx.r = Buffer.from(result.r, 'hex');
@@ -181,43 +180,45 @@ export class LedgerSubprovider extends Subprovider {
// EIP155: v should be chain_id * 2 + {35, 36}
const signedChainId = Math.floor((tx.v[0] - 35) / 2);
if (signedChainId !== this._networkId) {
- await this.destoryLedgerClientAsync();
+ await this._destroyLedgerClientAsync();
const err = new Error(LedgerSubproviderErrors.TooOldLedgerFirmware);
throw err;
}
const signedTxHex = `0x${tx.serialize().toString('hex')}`;
- await this.destoryLedgerClientAsync();
+ await this._destroyLedgerClientAsync();
return signedTxHex;
} catch (err) {
- await this.destoryLedgerClientAsync();
+ await this._destroyLedgerClientAsync();
throw err;
}
}
public async signPersonalMessageAsync(data: string): Promise<string> {
- this._ledgerClientIfExists = await this.createLedgerClientAsync();
+ this._ledgerClientIfExists = await this._createLedgerClientAsync();
try {
- const derivationPath = this.getDerivationPath();
+ const derivationPath = this._getDerivationPath();
const result = await this._ledgerClientIfExists.signPersonalMessage_async(
- derivationPath, ethUtil.stripHexPrefix(data));
+ derivationPath,
+ ethUtil.stripHexPrefix(data),
+ );
const v = result.v - 27;
let vHex = v.toString(16);
if (vHex.length < 2) {
vHex = `0${v}`;
}
const signature = `0x${result.r}${result.s}${vHex}`;
- await this.destoryLedgerClientAsync();
+ await this._destroyLedgerClientAsync();
return signature;
} catch (err) {
- await this.destoryLedgerClientAsync();
+ await this._destroyLedgerClientAsync();
throw err;
}
}
- private getDerivationPath() {
+ private _getDerivationPath() {
const derivationPath = `${this.getPath()}/${this._derivationPathIndex}`;
return derivationPath;
}
- private async createLedgerClientAsync(): Promise<LedgerEthereumClient> {
+ private async _createLedgerClientAsync(): Promise<LedgerEthereumClient> {
await this._connectionLock.wait();
if (!_.isUndefined(this._ledgerClientIfExists)) {
this._connectionLock.signal();
@@ -227,7 +228,7 @@ export class LedgerSubprovider extends Subprovider {
this._connectionLock.signal();
return ledgerEthereumClient;
}
- private async destoryLedgerClientAsync() {
+ private async _destroyLedgerClientAsync() {
await this._connectionLock.wait();
if (_.isUndefined(this._ledgerClientIfExists)) {
this._connectionLock.signal();
@@ -237,11 +238,11 @@ export class LedgerSubprovider extends Subprovider {
this._ledgerClientIfExists = undefined;
this._connectionLock.signal();
}
- private async sendTransactionAsync(txParams: PartialTxParams): Promise<Web3.JSONRPCResponsePayload> {
+ private async _sendTransactionAsync(txParams: PartialTxParams): Promise<string> {
await this._nonceLock.wait();
try {
// fill in the extras
- const filledParams = await this.populateMissingTxParamsAsync(txParams);
+ const filledParams = await this._populateMissingTxParamsAsync(txParams);
// sign it
const signedTx = await this.signTransactionAsync(filledParams);
// emit a submit
@@ -251,17 +252,17 @@ export class LedgerSubprovider extends Subprovider {
};
const result = await this.emitPayloadAsync(payload);
this._nonceLock.signal();
- return result;
+ return result.result;
} catch (err) {
this._nonceLock.signal();
throw err;
}
}
- private async signTransactionWithoutSendingAsync(txParams: PartialTxParams): Promise<ResponseWithTxParams> {
+ private async _signTransactionWithoutSendingAsync(txParams: PartialTxParams): Promise<ResponseWithTxParams> {
await this._nonceLock.wait();
try {
// fill in the extras
- const filledParams = await this.populateMissingTxParamsAsync(txParams);
+ const filledParams = await this._populateMissingTxParamsAsync(txParams);
// sign it
const signedTx = await this.signTransactionAsync(filledParams);
@@ -276,7 +277,7 @@ export class LedgerSubprovider extends Subprovider {
throw err;
}
}
- private async populateMissingTxParamsAsync(txParams: PartialTxParams): Promise<PartialTxParams> {
+ private async _populateMissingTxParamsAsync(txParams: PartialTxParams): Promise<PartialTxParams> {
if (_.isUndefined(txParams.gasPrice)) {
const gasPriceResult = await this.emitPayloadAsync({
method: 'eth_gasPrice',
diff --git a/packages/subproviders/src/subproviders/redundant_rpc.ts b/packages/subproviders/src/subproviders/redundant_rpc.ts
index 80462bbfb..a3cb463a8 100644
--- a/packages/subproviders/src/subproviders/redundant_rpc.ts
+++ b/packages/subproviders/src/subproviders/redundant_rpc.ts
@@ -1,17 +1,19 @@
-import {promisify} from '@0xproject/utils';
+import { promisify } from '@0xproject/utils';
import * as _ from 'lodash';
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
-import {JSONRPCPayload} from '../types';
+import { JSONRPCPayload } from '../types';
-import {Subprovider} from './subprovider';
+import { Subprovider } from './subprovider';
export class RedundantRPCSubprovider extends Subprovider {
- private rpcs: RpcSubprovider[];
- private static async firstSuccessAsync(
- rpcs: RpcSubprovider[], payload: JSONRPCPayload, next: () => void,
+ private _rpcs: RpcSubprovider[];
+ private static async _firstSuccessAsync(
+ rpcs: RpcSubprovider[],
+ payload: JSONRPCPayload,
+ next: () => void,
): Promise<any> {
- let lastErr: Error|undefined;
+ let lastErr: Error | undefined;
for (const rpc of rpcs) {
try {
const data = await promisify(rpc.handleRequest.bind(rpc))(payload, next);
@@ -27,21 +29,24 @@ export class RedundantRPCSubprovider extends Subprovider {
}
constructor(endpoints: string[]) {
super();
- this.rpcs = _.map(endpoints, endpoint => {
+ this._rpcs = _.map(endpoints, endpoint => {
return new RpcSubprovider({
rpcUrl: endpoint,
});
});
}
- public async handleRequest(payload: JSONRPCPayload, next: () => void,
- end: (err: Error|null, data?: any) => void): Promise<void> {
- const rpcsCopy = this.rpcs.slice();
+ // tslint:disable-next-line:async-suffix
+ public async handleRequest(
+ payload: JSONRPCPayload,
+ next: () => void,
+ end: (err: Error | null, data?: any) => void,
+ ): Promise<void> {
+ const rpcsCopy = this._rpcs.slice();
try {
- const data = await RedundantRPCSubprovider.firstSuccessAsync(rpcsCopy, payload, next);
+ const data = await RedundantRPCSubprovider._firstSuccessAsync(rpcsCopy, payload, next);
end(null, data);
} catch (err) {
end(err);
}
-
}
}
diff --git a/packages/subproviders/src/subproviders/subprovider.ts b/packages/subproviders/src/subproviders/subprovider.ts
index 64d97b958..6435c9f65 100644
--- a/packages/subproviders/src/subproviders/subprovider.ts
+++ b/packages/subproviders/src/subproviders/subprovider.ts
@@ -1,19 +1,16 @@
import promisify = require('es6-promisify');
import Web3 = require('web3');
-import {
- JSONRPCPayload,
-} from '../types';
+import { JSONRPCPayload } from '../types';
/*
* A version of the base class Subprovider found in providerEngine
* This one has an async/await `emitPayloadAsync` and also defined types.
* Altered version of: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js
*/
export class Subprovider {
- private engine: any;
- private currentBlock: any;
+ private _engine: any;
// Ported from: https://github.com/MetaMask/provider-engine/blob/master/util/random-id.js
- private static getRandomId() {
+ private static _getRandomId() {
const extraDigits = 3;
// 13 time digits
const datePart = new Date().getTime() * Math.pow(10, extraDigits);
@@ -22,10 +19,10 @@ export class Subprovider {
// 16 digits
return datePart + extraPart;
}
- private static createFinalPayload(payload: JSONRPCPayload): Web3.JSONRPCRequestPayload {
+ private static _createFinalPayload(payload: JSONRPCPayload): Web3.JSONRPCRequestPayload {
const finalPayload = {
// defaults
- id: Subprovider.getRandomId(),
+ id: Subprovider._getRandomId(),
jsonrpc: '2.0',
params: [],
...payload,
@@ -33,14 +30,11 @@ export class Subprovider {
return finalPayload;
}
public setEngine(engine: any): void {
- this.engine = engine;
- engine.on('block', (block: any) => {
- this.currentBlock = block;
- });
+ this._engine = engine;
}
public async emitPayloadAsync(payload: JSONRPCPayload): Promise<any> {
- const finalPayload = Subprovider.createFinalPayload(payload);
- const response = await promisify(this.engine.sendAsync, this.engine)(finalPayload);
+ const finalPayload = Subprovider._createFinalPayload(payload);
+ const response = await promisify(this._engine.sendAsync, this._engine)(finalPayload);
return response;
}
}
diff --git a/packages/subproviders/src/types.ts b/packages/subproviders/src/types.ts
index 38dc1e67e..3db8be943 100644
--- a/packages/subproviders/src/types.ts
+++ b/packages/subproviders/src/types.ts
@@ -1,5 +1,4 @@
import * as _ from 'lodash';
-import * as Web3 from 'web3';
export interface LedgerCommunicationClient {
close_async: () => Promise<void>;
@@ -11,8 +10,13 @@ export interface LedgerCommunicationClient {
* NodeJs and Browser communication are supported.
*/
export interface LedgerEthereumClient {
- getAddress_async: (derivationPath: string, askForDeviceConfirmation: boolean,
- shouldGetChainCode: boolean) => Promise<LedgerGetAddressResult>;
+ // shouldGetChainCode is defined as `true` instead of `boolean` because other types rely on the assumption
+ // that we get back the chain code and we don't have dependent types to express it properly
+ getAddress_async: (
+ derivationPath: string,
+ askForDeviceConfirmation: boolean,
+ shouldGetChainCode: true,
+ ) => Promise<LedgerGetAddressResult>;
signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<ECSignature>;
signTransaction_async: (derivationPath: string, txHex: string) => Promise<ECSignatureString>;
comm: LedgerCommunicationClient;
@@ -64,6 +68,8 @@ export interface SignatureData {
export interface LedgerGetAddressResult {
address: string;
+ publicKey: string;
+ chainCode: string;
}
export interface LedgerWalletSubprovider {