Skip to content

Commit

Permalink
Merge pull request #169 from BaojunCZ/feat-walletmanage-store
Browse files Browse the repository at this point in the history
feat: import wallet to store
  • Loading branch information
ashchan authored Mar 26, 2019
2 parents 6e910ae + d108b34 commit 4b65439
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ export default (props: React.PropsWithoutRef<ContentProps & RouteComponentProps>
// temp logic for simulate creation
props.dispatch(
actionCreators.createWallet({
name: settings.name,
mnemonic: '',
walletName: settings.name,
password: '',
}),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ export default (props: React.PropsWithoutRef<ContentProps & RouteComponentProps>
// temp logic for simulate creation
props.dispatch(
actionCreators.importWallet({
name: settings.name,
walletName: settings.name,
mnemonic: settings.seeds,
password: '',
keystore: '',
}),
)
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { initState, MainActions } from '../reducer'
import { createWallet, importWallet, exportWallet } from '../../../services/UILayer'

export default {
createWallet: (wallet: typeof initState.tempWallet) => {
createWallet: (wallet: typeof initState.createWallet) => {
createWallet(wallet)
return {
type: MainActions.CreateWallet,
Expand Down
7 changes: 6 additions & 1 deletion packages/neuron-ui/src/containers/MainContent/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import { CapacityUnit } from '../../utils/const'

export const initState = {
tempWallet: {
name: '',
walletName: '',
password: '',
mnemonic: '',
keystore: '',
},
createWallet: {
walletName: '',
password: '',
},
transfer: {
items: [
Expand Down
5 changes: 3 additions & 2 deletions packages/neuron-ui/src/services/UILayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const getWallets = () => {
UILayer.send(Channel.GetWallets)
}

export const createWallet = (wallet: { name: string; mnemonic: any; password: string }) =>
export const createWallet = (wallet: { walletName: string; password: string }) =>
UILayer.send(Channel.CreateWallet, wallet)

export const deleteWallet = (walletID: string, password: string, handleResult: any) => {
Expand Down Expand Up @@ -85,8 +85,9 @@ export const editWallet = (
})
}

export const importWallet = (wallet: { name: string; mnemonic: any; password: string }) =>
export const importWallet = (wallet: { walletName: string; password: string; mnemonic: string; keystore: string }) =>
UILayer.send(Channel.ImportWallet, wallet)

export const exportWallet = () => UILayer.send(Channel.ExportWallet)
export const getLiveCell = (outpoint: any) => UILayer.send('getLiveCell', outpoint)
export const getCellsByTypeHash = (typeHash: string) => {
Expand Down
70 changes: 54 additions & 16 deletions packages/neuron-wallet/src/channel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { Channel } from '../utils/const'
import { transactions, transactionCount, wallets, Wallet, updateWallets, validatePassword } from '../mock'
import asw from '../wallets/asw'
import ckbCore from '../core'
import Key from '../keys/key'
import WalletStore from '../store/WalletStore'

enum ResponseStatus {
Fail,
Expand Down Expand Up @@ -82,16 +84,17 @@ export class Listeners {
* @description channel to create wallet
*/
static createWallet = () => {
return ipcMain.on(Channel.CreateWallet, (e: Electron.Event, wallet: Wallet) => {
e.sender.send(Channel.CreateWallet, {
status: ResponseStatus.Success,
result: {
name: wallet.name,
address: 'wallet address',
publicKey: 'public key',
},
})
})
return ipcMain.on(
Channel.CreateWallet,
(e: Electron.Event, { walletName, password }: { walletName: string; password: string }) => {
const walletStore = new WalletStore()
const walletID = walletStore.saveWallet(walletName, Key.generateKey(password).getKeystore())
e.sender.send(Channel.CreateWallet, {
status: ResponseStatus.Success,
result: walletID,
})
},
)
}

/**
Expand Down Expand Up @@ -165,12 +168,47 @@ export class Listeners {
* @description channel to import a wallet
*/
static importWallet = () => {
return ipcMain.on(Channel.ImportWallet, (e: Electron.Event) => {
e.sender.send(Channel.ImportWallet, {
status: ResponseStatus.Success,
result: `wallet imported`,
})
})
return ipcMain.on(
Channel.ImportWallet,
(
e: Electron.Event,
{
walletName,
password,
mnemonic,
keystore,
}: { walletName: string; password: string; mnemonic: string; keystore: string },
) => {
try {
const walletStore = new WalletStore()
let storedKeystore
if (mnemonic) {
storedKeystore = Key.fromMnemonic(mnemonic, true, password).getKeystore()
} else if (keystore) {
storedKeystore = Key.fromKeystoreString(keystore, password).getKeystore()
}
if (storedKeystore) {
walletStore.saveWallet(walletName, storedKeystore)
e.sender.send(Channel.ImportWallet, {
status: ResponseStatus.Success,
result: true,
})
} else {
e.sender.send(Channel.ImportWallet, {
status: ResponseStatus.Success,
result: false,
msg: 'Error',
})
}
} catch (error) {
e.sender.send(Channel.ImportWallet, {
status: ResponseStatus.Success,
result: false,
msg: error.message,
})
}
},
)
}

/**
Expand Down
23 changes: 17 additions & 6 deletions packages/neuron-wallet/src/keys/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ export default class Key {
this.mnemonic = mnemonic
}

public static fromKeystore = (keystore: Keystore) => {
public static fromKeystore = (keystore: Keystore, password: string) => {
if (!Key.checkPassword(keystore, password)) {
throw new Error('Wrong password')
}
return new Key(keystore, '')
}

public static fromKeystoreString = (json: string) => {
return new Key(JSON.parse(json), '')
public static fromKeystoreString = (json: string, password: string) => {
return Key.fromKeystore(JSON.parse(json), password)
}

public static checkPassword(keystore: Keystore, password: string) {
return keystore.password === password
}

getKeystore = () => this.keystore
Expand All @@ -27,12 +34,15 @@ export default class Key {

getMnemonic = () => this.mnemonic

public static generateKey = () => {
public static generateKey = (password: string) => {
const mnemonic = bip39.generateMnemonic()
return Key.fromMnemonic(mnemonic, false)
return Key.fromMnemonic(mnemonic, false, password)
}

public static fromMnemonic = (mnemonic: string, derive: boolean) => {
public static fromMnemonic = (mnemonic: string, derive: boolean, password: string) => {
if (!bip39.validateMnemonic(mnemonic)) {
throw new Error('Wrong Mnemonic')
}
const seed = bip39.mnemonicToSeed(mnemonic)
const root = bip32.fromSeed(seed)
const master = {
Expand All @@ -41,6 +51,7 @@ export default class Key {
}
const keystore: Keystore = {
master,
password,
}
if (derive) {
keystore.children = Tool.searchUsedChildKeys(root)
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-wallet/src/keys/keystore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export interface Child {
export interface Keystore {
master: Master
children?: Child[]
password: string
}
14 changes: 7 additions & 7 deletions packages/neuron-wallet/tests/key.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,31 @@ import Key from '../src/keys/key'
describe('Key tests', () => {
const mnemonic = 'mechanic oppose oyster normal bunker trim step nasty birth naive panel soldier'
const keystoreJson =
'{"master":{"privateKey":"4e91f531d3351fd561506538ec0a68ba05d3d3444197e81d615ab76bbd200488","chainCode":"769382d9761bef8ed409ce4f9d5aeae5b5260f6f60e50f791826c27ae7afc495"}}'
'{"master":{"privateKey":"4e91f531d3351fd561506538ec0a68ba05d3d3444197e81d615ab76bbd200488","chainCode":"769382d9761bef8ed409ce4f9d5aeae5b5260f6f60e50f791826c27ae7afc495"},"password":"1qaz.2wsx"}'

it('import key from mnemonic without children', async () => {
const key = Key.fromMnemonic(mnemonic, false)
const key = Key.fromMnemonic(mnemonic, false, '1qaz.2wsx')
expect(key.getMnemonic()).toBe('mechanic oppose oyster normal bunker trim step nasty birth naive panel soldier')
expect(key.getKeystoreString()).toBe(keystoreJson)
expect(key.getKeystore().master.privateKey).toBe('4e91f531d3351fd561506538ec0a68ba05d3d3444197e81d615ab76bbd200488')
expect(key.getKeystore().master.chainCode).toBe('769382d9761bef8ed409ce4f9d5aeae5b5260f6f60e50f791826c27ae7afc495')
})

it('import key from keystore json without children', async () => {
const key = Key.fromKeystoreString(keystoreJson)
const key = Key.fromKeystoreString(keystoreJson, '1qaz.2wsx')
expect(key.getKeystore().master.privateKey).toBe('4e91f531d3351fd561506538ec0a68ba05d3d3444197e81d615ab76bbd200488')
expect(key.getKeystore().master.chainCode).toBe('769382d9761bef8ed409ce4f9d5aeae5b5260f6f60e50f791826c27ae7afc495')
})

it('generate key', async () => {
const key = Key.generateKey()
const key = Key.generateKey('1qaz.2wsx')
expect(key.getMnemonic()).not.toEqual(null)
expect(key.getKeystore()).not.toEqual(null)
expect(key.getKeystore().master).not.toEqual(null)
})

it('import key from mnemonic with children', async () => {
const key = Key.fromMnemonic(mnemonic, true)
const key = Key.fromMnemonic(mnemonic, true, '1qaz.2wsx')
expect(key.getMnemonic()).toBe('mechanic oppose oyster normal bunker trim step nasty birth naive panel soldier')
expect(key.getKeystore().master.privateKey).toBe('4e91f531d3351fd561506538ec0a68ba05d3d3444197e81d615ab76bbd200488')
expect(key.getKeystore().master.chainCode).toBe('769382d9761bef8ed409ce4f9d5aeae5b5260f6f60e50f791826c27ae7afc495')
Expand All @@ -36,8 +36,8 @@ describe('Key tests', () => {
})

it('import key from keystore json with children', async () => {
const keystore = Key.fromMnemonic(mnemonic, true).getKeystoreString()
const key = Key.fromKeystoreString(keystore)
const keystore = Key.fromMnemonic(mnemonic, true, '1qaz.2wsx').getKeystoreString()
const key = Key.fromKeystoreString(keystore, '1qaz.2wsx')
expect(key.getKeystore().master.privateKey).toBe('4e91f531d3351fd561506538ec0a68ba05d3d3444197e81d615ab76bbd200488')
expect(key.getKeystore().master.chainCode).toBe('769382d9761bef8ed409ce4f9d5aeae5b5260f6f60e50f791826c27ae7afc495')
expect(key.getKeystore().children!.length > 0).toEqual(true)
Expand Down

0 comments on commit 4b65439

Please sign in to comment.