Check in progress

This commit is contained in:
Will O'Beirne 2018-04-27 16:49:17 -04:00
parent ac8777bab5
commit 50a960f62f
No known key found for this signature in database
GPG Key ID: 44C190DB5DEAF9F6
15 changed files with 134 additions and 37 deletions

View File

@ -8,7 +8,7 @@ import { render } from 'react-dom';
import Root from './Root';
import { configuredStore } from './store';
import consoleAdvertisement from './utils/consoleAdvertisement';
import { registerClient } from 'shared/enclave/client';
import EnclaveAPI, { registerClient } from 'shared/enclave/client';
const appEl = document.getElementById('app');
@ -28,4 +28,5 @@ if (process.env.NODE_ENV === 'production') {
if (process.env.BUILD_ELECTRON) {
registerClient();
(window as any).EnclaveAPI = EnclaveAPI;
}

View File

@ -4,6 +4,7 @@ import path from 'path';
import MENU from './menu';
import updater from './updater';
import { APP_TITLE } from '../constants';
import ledger from 'shared/enclave/server/wallets/ledger';
const isDevelopment = process.env.NODE_ENV !== 'production';
// Cached reference, preventing recreations

View File

@ -10,6 +10,8 @@
"npm": ">= 5.0.0"
},
"dependencies": {
"@ledgerhq/hw-app-eth": "4.7.3",
"@ledgerhq/hw-transport-node-hid": "4.7.6",
"@parity/qr-signer": "0.1.1",
"babel-polyfill": "6.26.0",
"bip39": "2.5.0",
@ -18,8 +20,7 @@
"classnames": "2.2.5",
"electron-updater": "2.21.4",
"ethereum-blockies-base64": "1.0.1",
"ethereumjs-abi":
"git://github.com/ethereumjs/ethereumjs-abi.git#09c3c48fd3bed143df7fa8f36f6f164205e23796",
"ethereumjs-abi": "git://github.com/ethereumjs/ethereumjs-abi.git#09c3c48fd3bed143df7fa8f36f6f164205e23796",
"ethereumjs-tx": "1.3.4",
"ethereumjs-util": "5.1.5",
"ethereumjs-wallet": "0.6.0",
@ -92,6 +93,7 @@
"css-loader": "0.28.11",
"electron": "1.8.4",
"electron-builder": "20.8.1",
"electron-rebuild": "1.7.3",
"empty": "0.10.1",
"enzyme": "3.3.0",
"enzyme-adapter-react-16": "1.1.1",
@ -109,6 +111,7 @@
"lint-staged": "7.0.4",
"mini-css-extract-plugin": "0.4.0",
"minimist": "1.2.0",
"node-hid": "0.7.2",
"node-sass": "4.8.3",
"nodemon": "1.17.3",
"null-loader": "0.1.1",
@ -153,19 +156,13 @@
"prebuild": "check-node-version --package",
"build:downloadable": "webpack --mode=production --config webpack_config/webpack.html.js",
"prebuild:downloadable": "check-node-version --package",
"build:electron":
"webpack --config webpack_config/webpack.electron-prod.js && node webpack_config/buildElectron.js",
"build:electron:osx":
"webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=osx node webpack_config/buildElectron.js",
"build:electron:windows":
"webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=windows node webpack_config/buildElectron.js",
"build:electron:linux":
"webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=linux node webpack_config/buildElectron.js",
"build:electron": "webpack --config webpack_config/webpack.electron-prod.js && node webpack_config/buildElectron.js",
"build:electron:osx": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=osx node webpack_config/buildElectron.js",
"build:electron:windows": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=windows node webpack_config/buildElectron.js",
"build:electron:linux": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=linux node webpack_config/buildElectron.js",
"prebuild:electron": "check-node-version --package",
"jenkins:build:linux":
"webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=JENKINS_LINUX node webpack_config/buildElectron.js",
"jenkins:build:mac":
"webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=JENKINS_MAC node webpack_config/buildElectron.js",
"jenkins:build:linux": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=JENKINS_LINUX node webpack_config/buildElectron.js",
"jenkins:build:mac": "webpack --config webpack_config/webpack.electron-prod.js && ELECTRON_OS=JENKINS_MAC node webpack_config/buildElectron.js",
"jenkins:upload": "node jenkins/upload",
"test:coverage": "jest --config=jest_config/jest.config.json --coverage",
"test": "jest --config=jest_config/jest.config.json",
@ -178,18 +175,16 @@
"predev": "check-node-version --package",
"dev:https": "HTTPS=true node webpack_config/devServer.js",
"predev:https": "check-node-version --package",
"dev:electron":
"concurrently --kill-others --names 'webpack,electron' 'BUILD_ELECTRON=true node webpack_config/devServer.js' 'webpack --config webpack_config/webpack.electron-dev.js && electron dist/electron-js/main.js'",
"dev:electron": "concurrently --kill-others --names 'webpack,electron' 'BUILD_ELECTRON=true node webpack_config/devServer.js' 'webpack --config webpack_config/webpack.electron-dev.js && electron dist/electron-js/main.js'",
"tslint": "tslint --project . --exclude common/vendor/**/*",
"tscheck": "tsc --noEmit",
"start": "npm run dev",
"precommit": "lint-staged",
"formatAll":
"find ./common/ -name '*.ts*' | xargs prettier --write --config ./.prettierrc --config-precedence file-override",
"prettier:diff":
"prettier --write --config ./.prettierrc --list-different \"common/**/*.ts\" \"common/**/*.tsx\"",
"formatAll": "find ./common/ -name '*.ts*' | xargs prettier --write --config ./.prettierrc --config-precedence file-override",
"prettier:diff": "prettier --write --config ./.prettierrc --list-different \"common/**/*.ts\" \"common/**/*.tsx\"",
"prepush": "npm run tslint && npm run tscheck",
"update:tokens": "ts-node scripts/update-tokens"
"update:tokens": "ts-node scripts/update-tokens",
"postinstall": "electron-rebuild --force"
},
"lint-staged": {
"*.{ts,tsx}": [

View File

@ -3,6 +3,8 @@ import {
EnclaveEvents,
GetAddressesParams,
GetAddressesResponse,
GetChainCodeParams,
GetChainCodeResponse,
SignTransactionParams,
SignTransactionResponse
} from 'shared/enclave/types';
@ -16,6 +18,10 @@ const api = {
return makeRequestExpectingResponse<GetAddressesResponse>(EnclaveEvents.GET_ADDRESSES, params);
},
getChainCode(params: GetChainCodeParams) {
return makeRequestExpectingResponse<GetChainCodeResponse>(EnclaveEvents.GET_CHAIN_CODE, params);
},
signTransaction(params: SignTransactionParams) {
return makeRequestExpectingResponse<SignTransactionResponse>(
EnclaveEvents.SIGN_TRANSACTION,

View File

@ -0,0 +1,7 @@
import { getWalletLib } from 'shared/enclave/server/wallets';
import { GetChainCodeParams, GetChainCodeResponse } from 'shared/enclave/types';
export default async function(params: GetChainCodeParams): Promise<GetChainCodeResponse> {
const wallet = getWalletLib(params.walletType);
return wallet.getChainCode(params.dpath);
}

View File

@ -1,9 +1,13 @@
import getAddresses from './getAddresses';
import getChainCode from './getChainCode';
import signTransaction from './signTransaction';
import { EnclaveEvents, EventParams, EventResponse } from 'shared/enclave/types';
const handlers: { [key in EnclaveEvents]: (params: EventParams) => EventResponse } = {
const handlers: {
[key in EnclaveEvents]: (params: EventParams) => EventResponse | Promise<EventResponse>
} = {
[EnclaveEvents.GET_ADDRESSES]: getAddresses,
[EnclaveEvents.GET_CHAIN_CODE]: getChainCode,
[EnclaveEvents.SIGN_TRANSACTION]: signTransaction
};

View File

@ -2,13 +2,14 @@ import handlers from './handlers';
import { isValidEventType } from 'shared/enclave/utils';
import { RpcRequest, RpcEventSuccess, RpcEventFailure, EventResponse } from 'shared/enclave/types';
function processRequest(req: RpcRequest) {
async function processRequest(req: RpcRequest) {
try {
const data = handlers[req.type](req.params);
const data = await handlers[req.type](req.params);
if (data) {
respondWithPayload(req, data);
}
} catch (err) {
console.error('Request', req.type, 'failed with error:', err);
respondWithError(req, err.toString());
}
}

View File

@ -0,0 +1,14 @@
import Ledger from './ledger';
import Trezor from './trezor';
import KeepKey from './keepkey';
import { WalletTypes, WalletLib } from 'shared/enclave/types';
export const wallets: { [key in WalletTypes]: WalletLib } = {
[WalletTypes.LEDGER]: Ledger,
[WalletTypes.TREZOR]: Trezor,
[WalletTypes.KEEPKEY]: KeepKey
};
export function getWalletLib(type: WalletTypes): WalletLib {
return wallets[type];
}

View File

@ -0,0 +1,9 @@
import { WalletLib } from 'shared/enclave/types';
const KeepKey: WalletLib = {
async getChainCode() {
throw new Error('Not yet supported');
}
};
export default KeepKey;

View File

@ -0,0 +1,27 @@
import { WalletLib } from 'shared/enclave/types';
import TransportNodeHid from '@ledgerhq/hw-transport-node-hid';
import LedgerEth from '@ledgerhq/hw-app-eth';
async function getEthApp() {
const transport = await TransportNodeHid.create();
return new LedgerEth(transport);
}
const Ledger: WalletLib = {
async getChainCode(dpath: string) {
const app = await getEthApp();
try {
const res = await app.getAddress(dpath);
console.log(res);
return {
publicKey: res.publicKey,
chainCode: res.chainCode
};
} catch (err) {
console.log('wtf', err);
throw new Error('test');
}
}
};
export default Ledger;

View File

@ -0,0 +1,9 @@
import { WalletLib } from 'shared/enclave/types';
const Trezor: WalletLib = {
async getChainCode() {
throw new Error('Not yet supported');
}
};
export default Trezor;

View File

@ -1,18 +1,36 @@
// All enclave event types
// Enclave enums
export enum EnclaveEvents {
GET_ADDRESSES = 'get-addresses',
GET_CHAIN_CODE = 'get-chain-code',
SIGN_TRANSACTION = 'sign-transaction'
}
export enum WalletTypes {
LEDGER = 'ledger',
TREZOR = 'trezor',
KEEPKEY = 'keepkey'
}
// Get Addresses Request
export interface GetAddressesParams {
walletType: string;
walletType: WalletTypes;
}
export interface GetAddressesResponse {
addresses: string[];
}
// Get chain code request
export interface GetChainCodeParams {
walletType: WalletTypes;
dpath: string;
}
export interface GetChainCodeResponse {
publicKey: string;
chainCode: string;
}
// Sign Transaction Request
export interface SignTransactionParams {
path: string;
@ -26,8 +44,8 @@ export interface SignTransactionResponse {
}
// All Requests & Responses
export type EventParams = GetAddressesParams | SignTransactionParams;
export type EventResponse = GetAddressesResponse | SignTransactionResponse;
export type EventParams = GetAddressesParams | GetChainCodeParams | SignTransactionParams;
export type EventResponse = GetAddressesResponse | GetChainCodeResponse | SignTransactionResponse;
// RPC requests, responses & failures
export interface RpcRequest {
@ -53,10 +71,7 @@ export interface RpcEventFailure {
export type RpcEvent<T = any> = RpcEventFailure | RpcEventSuccess<T>;
// No clue
export interface RpcEventServer<T = any> {
payload: T;
id: number;
// Wallet lib
export interface WalletLib {
getChainCode(dpath: string): Promise<GetChainCodeResponse>;
}
export type RpcEventHandler<A = any, R = any> = (event: EnclaveEvents, args: A) => R;
export type MatchingIdHandler<A = any> = (event: string, args: A) => void;

View File

@ -18,7 +18,8 @@
"noEmitOnError": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitAny": true
"noImplicitAny": true,
"noImplicitUseStrict": true
},
"include": [
"./scripts",

View File

@ -29,10 +29,15 @@ const electronConfig = {
'process.env.NODE_ENV': JSON.stringify('development')
}),
],
externals: {
'node-hid': 'commonjs node-hid',
'@ledger/hw-transport-hid': 'commonjs @ledger/hw-transport-hid'
},
node: {
__dirname: false,
__filename: false
}
},
devtool: 'eval'
};
module.exports = electronConfig;

View File

@ -23,4 +23,6 @@ electronConfig.plugins = [
new DelayPlugin(500)
];
electronConfig.devtool = undefined;
module.exports = [electronConfig, jsConfig];