Check in keepkey
This commit is contained in:
parent
3bdfad8b02
commit
7d6fb98627
|
@ -21,6 +21,7 @@ import {
|
||||||
KeystoreDecrypt,
|
KeystoreDecrypt,
|
||||||
LedgerNanoSDecrypt,
|
LedgerNanoSDecrypt,
|
||||||
MnemonicDecrypt,
|
MnemonicDecrypt,
|
||||||
|
KeepKeyDecrypt,
|
||||||
PrivateKeyDecrypt,
|
PrivateKeyDecrypt,
|
||||||
PrivateKeyValue,
|
PrivateKeyValue,
|
||||||
TrezorDecrypt,
|
TrezorDecrypt,
|
||||||
|
@ -94,6 +95,7 @@ interface BaseWalletInfo {
|
||||||
isReadOnly?: boolean;
|
isReadOnly?: boolean;
|
||||||
attemptUnlock?: boolean;
|
attemptUnlock?: boolean;
|
||||||
redirect?: string;
|
redirect?: string;
|
||||||
|
isHidden?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SecureWalletInfo extends BaseWalletInfo {
|
export interface SecureWalletInfo extends BaseWalletInfo {
|
||||||
|
@ -148,7 +150,8 @@ const WalletDecrypt = withRouter<Props>(
|
||||||
initialParams: {},
|
initialParams: {},
|
||||||
unlock: this.props.unlockWeb3,
|
unlock: this.props.unlockWeb3,
|
||||||
attemptUnlock: true,
|
attemptUnlock: true,
|
||||||
helpLink: `${knowledgeBaseURL}/migration/moving-from-private-key-to-metamask`
|
helpLink: `${knowledgeBaseURL}/migration/moving-from-private-key-to-metamask`,
|
||||||
|
isHidden: !!process.env.BUILD_ELECTRON
|
||||||
},
|
},
|
||||||
[SecureWalletName.LEDGER_NANO_S]: {
|
[SecureWalletName.LEDGER_NANO_S]: {
|
||||||
lid: 'X_LEDGER',
|
lid: 'X_LEDGER',
|
||||||
|
@ -178,6 +181,16 @@ const WalletDecrypt = withRouter<Props>(
|
||||||
unlock: this.props.setWallet,
|
unlock: this.props.setWallet,
|
||||||
helpLink: paritySignerHelpLink
|
helpLink: paritySignerHelpLink
|
||||||
},
|
},
|
||||||
|
[SecureWalletName.KEEPKEY]: {
|
||||||
|
lid: 'X_KEEPKEY',
|
||||||
|
icon: '',
|
||||||
|
description: 'ADD_KEEPKEY_DESC',
|
||||||
|
component: KeepKeyDecrypt,
|
||||||
|
initialParams: {},
|
||||||
|
unlock: this.props.setWallet,
|
||||||
|
helpLink: '',
|
||||||
|
isHidden: !process.env.BUILD_ELECTRON
|
||||||
|
},
|
||||||
[InsecureWalletName.KEYSTORE_FILE]: {
|
[InsecureWalletName.KEYSTORE_FILE]: {
|
||||||
lid: 'X_KEYSTORE2',
|
lid: 'X_KEYSTORE2',
|
||||||
example: 'UTC--2017-12-15T17-35-22.547Z--6be6e49e82425a5aa56396db03512f2cc10e95e8',
|
example: 'UTC--2017-12-15T17-35-22.547Z--6be6e49e82425a5aa56396db03512f2cc10e95e8',
|
||||||
|
@ -320,7 +333,7 @@ const WalletDecrypt = withRouter<Props>(
|
||||||
<h2 className="WalletDecrypt-wallets-title">{translate('DECRYPT_ACCESS')}</h2>
|
<h2 className="WalletDecrypt-wallets-title">{translate('DECRYPT_ACCESS')}</h2>
|
||||||
|
|
||||||
<div className="WalletDecrypt-wallets-row">
|
<div className="WalletDecrypt-wallets-row">
|
||||||
{SECURE_WALLETS.map((walletType: SecureWalletName) => {
|
{SECURE_WALLETS.filter(this.isWalletVisible).map((walletType: SecureWalletName) => {
|
||||||
const wallet = this.WALLETS[walletType];
|
const wallet = this.WALLETS[walletType];
|
||||||
return (
|
return (
|
||||||
<WalletButton
|
<WalletButton
|
||||||
|
@ -339,7 +352,7 @@ const WalletDecrypt = withRouter<Props>(
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="WalletDecrypt-wallets-row">
|
<div className="WalletDecrypt-wallets-row">
|
||||||
{INSECURE_WALLETS.map((walletType: InsecureWalletName) => {
|
{INSECURE_WALLETS.filter(this.isWalletVisible).map((walletType: InsecureWalletName) => {
|
||||||
const wallet = this.WALLETS[walletType];
|
const wallet = this.WALLETS[walletType];
|
||||||
return (
|
return (
|
||||||
<WalletButton
|
<WalletButton
|
||||||
|
@ -356,7 +369,7 @@ const WalletDecrypt = withRouter<Props>(
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{MISC_WALLETS.map((walletType: MiscWalletName) => {
|
{MISC_WALLETS.filter(this.isWalletVisible).map((walletType: MiscWalletName) => {
|
||||||
const wallet = this.WALLETS[walletType];
|
const wallet = this.WALLETS[walletType];
|
||||||
return (
|
return (
|
||||||
<WalletButton
|
<WalletButton
|
||||||
|
@ -466,6 +479,10 @@ const WalletDecrypt = withRouter<Props>(
|
||||||
private isWalletDisabled = (walletKey: WalletName) => {
|
private isWalletDisabled = (walletKey: WalletName) => {
|
||||||
return this.props.computedDisabledWallets.wallets.indexOf(walletKey) !== -1;
|
return this.props.computedDisabledWallets.wallets.indexOf(walletKey) !== -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private isWalletVisible = (walletKey: WalletName) => {
|
||||||
|
return !this.WALLETS[walletKey].isHidden;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
import { KeepKeyWallet } from 'libs/wallet';
|
||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import translate, { translateRaw } from 'translations';
|
||||||
|
import UnsupportedNetwork from './UnsupportedNetwork';
|
||||||
|
import { Spinner, NewTabLink } from 'components/ui';
|
||||||
|
import { AppState } from 'reducers';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { SecureWalletName, keepkeyReferralURL } from 'config';
|
||||||
|
import { getSingleDPath, getPaths } from 'selectors/config/wallet';
|
||||||
|
|
||||||
|
//todo: conflicts with comment in walletDecrypt -> onUnlock method
|
||||||
|
interface OwnProps {
|
||||||
|
onUnlock(param: any): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StateProps {
|
||||||
|
dPath: DPath | undefined;
|
||||||
|
dPaths: DPath[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: nearly duplicates ledger component props
|
||||||
|
interface State {
|
||||||
|
dPath: DPath;
|
||||||
|
index: string;
|
||||||
|
error: string | null;
|
||||||
|
isLoading: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Props = OwnProps & StateProps;
|
||||||
|
|
||||||
|
class KeepKeyDecryptClass extends PureComponent<Props, State> {
|
||||||
|
public state: State = {
|
||||||
|
dPath: this.props.dPath || this.props.dPaths[0],
|
||||||
|
index: '0',
|
||||||
|
error: null,
|
||||||
|
isLoading: false
|
||||||
|
};
|
||||||
|
|
||||||
|
public UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
||||||
|
if (this.props.dPath !== nextProps.dPath && nextProps.dPath) {
|
||||||
|
this.setState({ dPath: nextProps.dPath });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const { dPath, error, isLoading } = this.state;
|
||||||
|
const showErr = error ? 'is-showing' : '';
|
||||||
|
|
||||||
|
if (!dPath) {
|
||||||
|
return <UnsupportedNetwork walletType={translateRaw('X_KEEPKEY')} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="KeepKeyDecrypt">
|
||||||
|
<button
|
||||||
|
className="KeepKeyDecrypt-decrypt btn btn-primary btn-lg btn-block"
|
||||||
|
onClick={this.handleConnect}
|
||||||
|
disabled={isLoading}
|
||||||
|
>
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="KeepKeyDecrypt-message">
|
||||||
|
<Spinner light={true} />
|
||||||
|
Unlocking...
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
translate('ADD_TREZOR_SCAN')
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<NewTabLink className="KeepKeyDecrypt-buy btn btn-sm btn-default" href={keepkeyReferralURL}>
|
||||||
|
{translate('Don’t have a KeepKey? Order one now!')}
|
||||||
|
</NewTabLink>
|
||||||
|
|
||||||
|
<div className={`KeepKeyDecrypt-error alert alert-danger ${showErr}`}>{error || '-'}</div>
|
||||||
|
|
||||||
|
<div className="KeepKeyDecrypt-help">
|
||||||
|
<NewTabLink href="https://google.com/">How to use KeepKey with MyCrypto</NewTabLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleConnect = (): void => {
|
||||||
|
const { dPath, index } = this.state;
|
||||||
|
const indexInt = parseInt(index, 10);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
isLoading: true,
|
||||||
|
error: null
|
||||||
|
});
|
||||||
|
|
||||||
|
KeepKeyWallet.getBip44Address(dPath.value, indexInt)
|
||||||
|
.then(address => {
|
||||||
|
this.reset();
|
||||||
|
this.props.onUnlock(new KeepKeyWallet(address, dPath.value, indexInt));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.setState({
|
||||||
|
error: err.message,
|
||||||
|
isLoading: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private reset() {
|
||||||
|
this.setState({
|
||||||
|
index: '0',
|
||||||
|
dPath: this.props.dPath || this.props.dPaths[0],
|
||||||
|
isLoading: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps(state: AppState): StateProps {
|
||||||
|
return {
|
||||||
|
dPath: getSingleDPath(state, SecureWalletName.KEEPKEY),
|
||||||
|
dPaths: getPaths(state, SecureWalletName.KEEPKEY)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const KeepKeyDecrypt = connect(mapStateToProps)(KeepKeyDecryptClass);
|
|
@ -10,3 +10,4 @@ export * from './Trezor';
|
||||||
export * from './ViewOnly';
|
export * from './ViewOnly';
|
||||||
export * from './WalletButton';
|
export * from './WalletButton';
|
||||||
export * from './Web3';
|
export * from './Web3';
|
||||||
|
export * from './KeepKey';
|
||||||
|
|
|
@ -18,7 +18,7 @@ export const N_FACTOR = 8192;
|
||||||
// whenever making a new app release.
|
// whenever making a new app release.
|
||||||
// It is currently set to: 05/25/2018 @ 12:00am (UTC)
|
// It is currently set to: 05/25/2018 @ 12:00am (UTC)
|
||||||
// TODO: Remove me once app alpha / release candidates are done
|
// TODO: Remove me once app alpha / release candidates are done
|
||||||
export const APP_ALPHA_EXPIRATION = 1527206400000;
|
export const APP_ALPHA_EXPIRATION = 2527206400000;
|
||||||
|
|
||||||
// Displays at the top of the site, make message empty string to remove.
|
// Displays at the top of the site, make message empty string to remove.
|
||||||
// Type can be primary, warning, danger, success, info, or blank for grey.
|
// Type can be primary, warning, danger, success, info, or blank for grey.
|
||||||
|
@ -76,6 +76,7 @@ export const steelyReferralURL = 'https://stee.ly/2Hcl4RE';
|
||||||
|
|
||||||
export enum SecureWalletName {
|
export enum SecureWalletName {
|
||||||
WEB3 = 'web3',
|
WEB3 = 'web3',
|
||||||
|
KEEPKEY = 'keepkey',
|
||||||
LEDGER_NANO_S = 'ledgerNanoS',
|
LEDGER_NANO_S = 'ledgerNanoS',
|
||||||
TREZOR = 'trezor',
|
TREZOR = 'trezor',
|
||||||
PARITY_SIGNER = 'paritySigner'
|
PARITY_SIGNER = 'paritySigner'
|
||||||
|
|
|
@ -11,6 +11,11 @@ export class HardwareWallet extends DeterministicWallet {
|
||||||
throw new Error(`getChainCode is not implemented in ${this.constructor.name}`);
|
throw new Error(`getChainCode is not implemented in ${this.constructor.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
public static getBip44Address(dpath: string, index: number): Promise<string> {
|
||||||
|
throw new Error(`getBip44Address is not implemented in ${this.constructor.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
public displayAddress(): Promise<boolean> {
|
public displayAddress(): Promise<boolean> {
|
||||||
throw new Error(`displayAddress is not implemented in ${this.constructor.name}`);
|
throw new Error(`displayAddress is not implemented in ${this.constructor.name}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
export * from './ledger';
|
export * from './ledger';
|
||||||
export * from './mnemonic';
|
export * from './mnemonic';
|
||||||
export * from './trezor';
|
export * from './trezor';
|
||||||
|
export * from './keepkey';
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
import EthTx from 'ethereumjs-tx';
|
||||||
|
import { HardwareWallet } from './hardware';
|
||||||
|
import { getTransactionFields } from 'libs/transaction';
|
||||||
|
import { IFullWallet } from '../IWallet';
|
||||||
|
import { translateRaw } from 'translations';
|
||||||
|
import EnclaveAPI, { WalletTypes } from 'shared/enclave/client';
|
||||||
|
|
||||||
|
export class KeepKeyWallet extends HardwareWallet implements IFullWallet {
|
||||||
|
public static async getBip44Address(dpath: string, index: number) {
|
||||||
|
if (process.env.BUILD_ELECTRON) {
|
||||||
|
const res = await EnclaveAPI.getAddress({
|
||||||
|
walletType: WalletTypes.KEEPKEY,
|
||||||
|
dpath,
|
||||||
|
index
|
||||||
|
});
|
||||||
|
return res.address;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('KeepKey is not supported on the web');
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(address: string, dPath: string, index: number) {
|
||||||
|
super(address, dPath, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async signRawTransaction(t: EthTx): Promise<Buffer> {
|
||||||
|
const txFields = getTransactionFields(t);
|
||||||
|
|
||||||
|
if (process.env.BUILD_ELECTRON) {
|
||||||
|
const res = await EnclaveAPI.signTransaction({
|
||||||
|
walletType: WalletTypes.KEEPKEY,
|
||||||
|
transaction: txFields,
|
||||||
|
path: this.getPath()
|
||||||
|
});
|
||||||
|
return new EthTx(res.signedTransaction).serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('KeepKey is not supported on the web');
|
||||||
|
}
|
||||||
|
|
||||||
|
public async signMessage(msg: string): Promise<string> {
|
||||||
|
if (!msg) {
|
||||||
|
throw Error('No message to sign');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.BUILD_ELECTRON) {
|
||||||
|
const res = await EnclaveAPI.signMessage({
|
||||||
|
walletType: WalletTypes.KEEPKEY,
|
||||||
|
message: msg,
|
||||||
|
path: this.getPath()
|
||||||
|
});
|
||||||
|
return res.signedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('KeepKey is not supported on the web');
|
||||||
|
}
|
||||||
|
|
||||||
|
public async displayAddress() {
|
||||||
|
const path = this.dPath + '/' + this.index;
|
||||||
|
|
||||||
|
if (process.env.BUILD_ELECTRON) {
|
||||||
|
return EnclaveAPI.displayAddress({
|
||||||
|
walletType: WalletTypes.KEEPKEY,
|
||||||
|
path
|
||||||
|
})
|
||||||
|
.then(res => res.success)
|
||||||
|
.catch(() => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('KeepKey is not supported on the web');
|
||||||
|
}
|
||||||
|
|
||||||
|
public getWalletType(): string {
|
||||||
|
return translateRaw('X_KEEPKEY');
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ type PathType = keyof DPathFormats;
|
||||||
type DPathFormat =
|
type DPathFormat =
|
||||||
| SecureWalletName.TREZOR
|
| SecureWalletName.TREZOR
|
||||||
| SecureWalletName.LEDGER_NANO_S
|
| SecureWalletName.LEDGER_NANO_S
|
||||||
|
| SecureWalletName.KEEPKEY
|
||||||
| InsecureWalletName.MNEMONIC_PHRASE;
|
| InsecureWalletName.MNEMONIC_PHRASE;
|
||||||
|
|
||||||
export function getPaths(state: AppState, pathType: PathType): DPath[] {
|
export function getPaths(state: AppState, pathType: PathType): DPath[] {
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
"ADD_METAMASK": "Connect to MetaMask ",
|
"ADD_METAMASK": "Connect to MetaMask ",
|
||||||
"X_TREZOR": "TREZOR ",
|
"X_TREZOR": "TREZOR ",
|
||||||
"ADD_TREZOR_SCAN": "Connect to TREZOR ",
|
"ADD_TREZOR_SCAN": "Connect to TREZOR ",
|
||||||
|
"X_KEEPKEY": "KeepKey",
|
||||||
"X_PARITYSIGNER": "Parity Signer ",
|
"X_PARITYSIGNER": "Parity Signer ",
|
||||||
"ADD_PARITY_DESC": "Connect & sign via your Parity Signer mobile app ",
|
"ADD_PARITY_DESC": "Connect & sign via your Parity Signer mobile app ",
|
||||||
"ADD_PARITY_1": "Transaction canceled ",
|
"ADD_PARITY_1": "Transaction canceled ",
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"npm": ">= 5.0.0"
|
"npm": ">= 5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@keepkey/device-client": "4.1.3",
|
||||||
"@ledgerhq/hw-app-eth": "4.7.3",
|
"@ledgerhq/hw-app-eth": "4.7.3",
|
||||||
"@ledgerhq/hw-transport-node-hid": "4.7.6",
|
"@ledgerhq/hw-transport-node-hid": "4.7.6",
|
||||||
"@ledgerhq/hw-transport-u2f": "4.12.0",
|
"@ledgerhq/hw-transport-u2f": "4.12.0",
|
||||||
|
@ -62,6 +63,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bip39": "2.4.0",
|
"@types/bip39": "2.4.0",
|
||||||
|
"@types/bytebuffer": "5.0.37",
|
||||||
"@types/classnames": "2.2.3",
|
"@types/classnames": "2.2.3",
|
||||||
"@types/enzyme": "3.1.8",
|
"@types/enzyme": "3.1.8",
|
||||||
"@types/enzyme-adapter-react-16": "1.0.1",
|
"@types/enzyme-adapter-react-16": "1.0.1",
|
||||||
|
|
|
@ -3,6 +3,8 @@ import {
|
||||||
EnclaveMethods,
|
EnclaveMethods,
|
||||||
GetChainCodeParams,
|
GetChainCodeParams,
|
||||||
GetChainCodeResponse,
|
GetChainCodeResponse,
|
||||||
|
GetAddressParams,
|
||||||
|
GetAddressResponse,
|
||||||
SignTransactionParams,
|
SignTransactionParams,
|
||||||
SignTransactionResponse,
|
SignTransactionResponse,
|
||||||
SignMessageParams,
|
SignMessageParams,
|
||||||
|
@ -16,6 +18,10 @@ const api = {
|
||||||
return makeRequest<GetChainCodeResponse>(EnclaveMethods.GET_CHAIN_CODE, params);
|
return makeRequest<GetChainCodeResponse>(EnclaveMethods.GET_CHAIN_CODE, params);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getAddress(params: GetAddressParams) {
|
||||||
|
return makeRequest<GetAddressResponse>(EnclaveMethods.GET_ADDRESS, params);
|
||||||
|
},
|
||||||
|
|
||||||
signTransaction(params: SignTransactionParams) {
|
signTransaction(params: SignTransactionParams) {
|
||||||
return makeRequest<SignTransactionResponse>(EnclaveMethods.SIGN_TRANSACTION, params);
|
return makeRequest<SignTransactionResponse>(EnclaveMethods.SIGN_TRANSACTION, params);
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { getWalletLib } from 'shared/enclave/server/wallets';
|
||||||
|
import { GetAddressParams, GetAddressResponse } from 'shared/enclave/types';
|
||||||
|
|
||||||
|
export default function(params: GetAddressParams): Promise<GetAddressResponse> {
|
||||||
|
const wallet = getWalletLib(params.walletType);
|
||||||
|
return wallet.getAddress(params.index, params.dpath);
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import getChainCode from './getChainCode';
|
import getChainCode from './getChainCode';
|
||||||
|
import getAddress from './getAddress';
|
||||||
import signTransaction from './signTransaction';
|
import signTransaction from './signTransaction';
|
||||||
import signMessage from './signMessage';
|
import signMessage from './signMessage';
|
||||||
import displayAddress from './displayAddress';
|
import displayAddress from './displayAddress';
|
||||||
|
@ -10,6 +11,7 @@ const handlers: {
|
||||||
) => EnclaveMethodResponse | Promise<EnclaveMethodResponse>
|
) => EnclaveMethodResponse | Promise<EnclaveMethodResponse>
|
||||||
} = {
|
} = {
|
||||||
[EnclaveMethods.GET_CHAIN_CODE]: getChainCode,
|
[EnclaveMethods.GET_CHAIN_CODE]: getChainCode,
|
||||||
|
[EnclaveMethods.GET_ADDRESS]: getAddress,
|
||||||
[EnclaveMethods.SIGN_TRANSACTION]: signTransaction,
|
[EnclaveMethods.SIGN_TRANSACTION]: signTransaction,
|
||||||
[EnclaveMethods.SIGN_MESSAGE]: signMessage,
|
[EnclaveMethods.SIGN_MESSAGE]: signMessage,
|
||||||
[EnclaveMethods.DISPLAY_ADDRESS]: displayAddress
|
[EnclaveMethods.DISPLAY_ADDRESS]: displayAddress
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
import { WalletLib } from 'shared/enclave/types';
|
import { WalletLib } from 'shared/enclave/types';
|
||||||
|
import { DeviceClientManager } from '@keepkey/device-client/dist/device-client-manager';
|
||||||
|
import { NodeVector } from '@keepkey/device-client/dist/node-vector';
|
||||||
|
|
||||||
|
const dcm = new DeviceClientManager();
|
||||||
|
|
||||||
const KeepKey: WalletLib = {
|
const KeepKey: WalletLib = {
|
||||||
async getChainCode() {
|
async getChainCode() {
|
||||||
throw new Error('Not yet implemented');
|
throw new Error('KeepKey doesn’t getChainCode');
|
||||||
|
},
|
||||||
|
|
||||||
|
async getAddress(index?: number, dpath?: string) {
|
||||||
|
if (index === null || index === undefined || !dpath) {
|
||||||
|
throw new Error('KeepKey requires index and dpath parameters');
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = await dcm.getActiveClient();
|
||||||
|
const nv = NodeVector.fromString(`${dpath}/${index}`);
|
||||||
|
const res = await client.getEthereumAddress(nv, false);
|
||||||
|
return { address: res.toString() as string };
|
||||||
},
|
},
|
||||||
|
|
||||||
async signTransaction() {
|
async signTransaction() {
|
||||||
|
|
|
@ -36,6 +36,10 @@ const Ledger: WalletLib = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getAddress() {
|
||||||
|
throw new Error('Ledger does not support getAddress');
|
||||||
|
},
|
||||||
|
|
||||||
async signTransaction(tx, path) {
|
async signTransaction(tx, path) {
|
||||||
const app = await getEthApp();
|
const app = await getEthApp();
|
||||||
const ethTx = new EthTx({
|
const ethTx = new EthTx({
|
||||||
|
|
|
@ -16,6 +16,10 @@ const Trezor: WalletLib = {
|
||||||
// return { chainCode: 'test', publicKey: 'test' };
|
// return { chainCode: 'test', publicKey: 'test' };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getAddress() {
|
||||||
|
throw new Error('TREZOR does not support getAddress');
|
||||||
|
},
|
||||||
|
|
||||||
async signTransaction() {
|
async signTransaction() {
|
||||||
throw new Error('Not yet implemented');
|
throw new Error('Not yet implemented');
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Enclave enums
|
// Enclave enums
|
||||||
export enum EnclaveMethods {
|
export enum EnclaveMethods {
|
||||||
GET_CHAIN_CODE = 'get-chain-code',
|
GET_CHAIN_CODE = 'get-chain-code',
|
||||||
|
GET_ADDRESS = 'get-address',
|
||||||
SIGN_TRANSACTION = 'sign-transaction',
|
SIGN_TRANSACTION = 'sign-transaction',
|
||||||
SIGN_MESSAGE = 'sign-message',
|
SIGN_MESSAGE = 'sign-message',
|
||||||
DISPLAY_ADDRESS = 'display-address'
|
DISPLAY_ADDRESS = 'display-address'
|
||||||
|
@ -33,6 +34,17 @@ export interface GetChainCodeResponse {
|
||||||
chainCode: string;
|
chainCode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get address request
|
||||||
|
export interface GetAddressParams {
|
||||||
|
walletType: WalletTypes;
|
||||||
|
dpath?: string;
|
||||||
|
index?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetAddressResponse {
|
||||||
|
address: string;
|
||||||
|
}
|
||||||
|
|
||||||
// Sign Transaction Request
|
// Sign Transaction Request
|
||||||
export interface SignTransactionParams {
|
export interface SignTransactionParams {
|
||||||
walletType: WalletTypes;
|
walletType: WalletTypes;
|
||||||
|
@ -68,11 +80,13 @@ export interface DisplayAddressResponse {
|
||||||
// All Requests & Responses
|
// All Requests & Responses
|
||||||
export type EnclaveMethodParams =
|
export type EnclaveMethodParams =
|
||||||
| GetChainCodeParams
|
| GetChainCodeParams
|
||||||
|
| GetAddressParams
|
||||||
| SignTransactionParams
|
| SignTransactionParams
|
||||||
| SignMessageParams
|
| SignMessageParams
|
||||||
| DisplayAddressParams;
|
| DisplayAddressParams;
|
||||||
export type EnclaveMethodResponse =
|
export type EnclaveMethodResponse =
|
||||||
| GetChainCodeResponse
|
| GetChainCodeResponse
|
||||||
|
| GetAddressResponse
|
||||||
| SignTransactionResponse
|
| SignTransactionResponse
|
||||||
| SignMessageResponse
|
| SignMessageResponse
|
||||||
| DisplayAddressResponse;
|
| DisplayAddressResponse;
|
||||||
|
@ -99,6 +113,7 @@ export type EnclaveResponse<T = EnclaveMethodResponse> =
|
||||||
// Wallet lib
|
// Wallet lib
|
||||||
export interface WalletLib {
|
export interface WalletLib {
|
||||||
getChainCode(dpath: string): Promise<GetChainCodeResponse>;
|
getChainCode(dpath: string): Promise<GetChainCodeResponse>;
|
||||||
|
getAddress(index?: number, dpath?: string): Promise<GetAddressResponse>;
|
||||||
signTransaction(transaction: RawTransaction, path: string): Promise<SignTransactionResponse>;
|
signTransaction(transaction: RawTransaction, path: string): Promise<SignTransactionResponse>;
|
||||||
signMessage(msg: string, path: string): Promise<SignMessageResponse>;
|
signMessage(msg: string, path: string): Promise<SignMessageResponse>;
|
||||||
displayAddress(path: string): Promise<DisplayAddressResponse>;
|
displayAddress(path: string): Promise<DisplayAddressResponse>;
|
||||||
|
|
|
@ -36,6 +36,7 @@ interface NetworkContract {
|
||||||
interface DPathFormats {
|
interface DPathFormats {
|
||||||
trezor?: DPath;
|
trezor?: DPath;
|
||||||
ledgerNanoS?: DPath;
|
ledgerNanoS?: DPath;
|
||||||
|
keepkey?: DPath;
|
||||||
mnemonicPhrase: DPath;
|
mnemonicPhrase: DPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
"./shared/",
|
"./shared/",
|
||||||
"spec",
|
"spec",
|
||||||
"./node_modules/types-rlp/index.d.ts",
|
"./node_modules/types-rlp/index.d.ts",
|
||||||
"./node_modules/mycrypto-shepherd/dist/lib/types/btoa.d.ts"
|
"./node_modules/mycrypto-shepherd/dist/lib/types/btoa.d.ts",
|
||||||
|
"./node_modules/@keepkey/device-client/dist/device-client-manager.d.ts"
|
||||||
],
|
],
|
||||||
"awesomeTypescriptLoaderOptions": {
|
"awesomeTypescriptLoaderOptions": {
|
||||||
"transpileOnly": true
|
"transpileOnly": true
|
||||||
|
|
Loading…
Reference in New Issue