增加助记词恢复钱包和根据助记词生成帐号的功能

This commit is contained in:
cebgcontract 2022-07-08 13:23:42 +08:00
parent 6064f447e6
commit 2b4235449e
6 changed files with 116 additions and 18 deletions

View File

@ -14,19 +14,22 @@
"dependencies": {
"@metamask/eth-sig-util": "^4.0.1",
"bip39": "^3.0.4",
"crypto-js": "^4.1.1",
"ethereumjs-wallet": "^1.0.2",
"web3": "^1.7.4",
"whatwg-fetch": "^3.6.2"
},
"devDependencies": {
"assert": "^2.0.0",
"buffer": "^6.0.3",
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"babel-loader": "^8.1.0",
"@babel/preset-env": "^7.12.1",
"@babel/preset-typescript": "^7.12.1",
"@babel/runtime": "^7.12.1",
"@types/aes-js": "^3.1.1",
"@types/crypto-js": "^4.1.1",
"assert": "^2.0.0",
"babel-loader": "^8.1.0",
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.0",
"https-browserify": "^1.0.0",
"os-browserify": "^0.3.0",

View File

@ -11,6 +11,7 @@ import { IAccount, initAccount } from "./data/DataModel";
import { DataManage } from "./manage/DataManage";
import { WALLET_STORAGE_KEY_NAME } from "./config/constants";
import { DEFALUT_TOKENS } from "./config/chain_config";
import { newMnemonic, restoreWalletByMnemonic } from "./manage/WalletManage";
var global =
@ -88,19 +89,28 @@ export default class JCWallet {
}
}
if (!this.wallet || this.wallet.length === 0) {
// let key = '0xa6c4354fb93a55fb67117969a12465209395ec31089fea9e6e061f873b87a473'
// this.wallet.add(key);
// this.web3.eth.accounts.wallet.save(this.password, WALLET_STORAGE_KEY_NAME);
this.createAccount();
// this.createAccount();
this.newWallet('111111');
}
}
public newWallet(password: string) {
this.password = password
newMnemonic(this.password)
this.createAccount()
}
public restoreFromMnemonic(mnemonic: string, password: string) {
this.password = password
this.wallet.clear()
restoreWalletByMnemonic(mnemonic, this.password);
this.createAccount()
}
get currentChain() {
return this._currentChain
}
updateCurrentChain(chainId: number) {
const chainData = this.chainMap.get(chainId)
this._currentChain = chainData
@ -164,13 +174,14 @@ export default class JCWallet {
}
public createAccount() {
let account = this.web3.eth.accounts.create()
this.wallet.add(account)
// let account = this.web3.eth.accounts.create()
const index = this.getMaxIdexOfType(0);
const accountNew = this.dataManage.newAccount(this.password, index)
const account = this.wallet.add(accountNew)
this.wallet.save(this.password, WALLET_STORAGE_KEY_NAME)
const chain = this.currentChain.id
let data = this.data.find(o => o.address === account.address)
if (!data) {
const index = this.getMaxIdexOfType(0);
const nickname = `Account ${ index + 1 }`
data = initAccount({
address: account.address,
@ -188,11 +199,7 @@ export default class JCWallet {
}
public importAccount(privateKey: string) {
let account = this.web3.eth.accounts.privateKeyToAccount(privateKey)
if (this.wallet[account.address]) {
return false
}
this.wallet.add(account);
const account = this.wallet.add(privateKey);
const chain = this.currentChain.id
let data = this.data.find(o => o.address === account.address)
if (!data) {

View File

@ -1,7 +1,9 @@
import { IAccount } from "../data/DataModel";
import { singleton } from "../decorator/singleton.decorator";
import { aesDecrypt, aesEncrypt } from "../util/crypto.util";
const LOCAL_ACCOUNT_DATAS = 'local_account_datas'
const LOCAL_WALLET_MNEMONIC = 'local_wallet_mnemonic'
@singleton
export class DataManage{
public loadData(){
@ -21,4 +23,21 @@ export class DataManage{
const dataStr = JSON.stringify(datas)
localStorage.setItem(LOCAL_ACCOUNT_DATAS, dataStr)
}
public loadMnemonic(password: string) {
let dataStr: string = localStorage.getItem(LOCAL_WALLET_MNEMONIC)
if (dataStr) {
dataStr = aesDecrypt(dataStr, password)
}
return dataStr
}
public saveMnemonic(mnemonic: string, password: string) {
const dataStr = aesEncrypt(mnemonic, password);
localStorage.setItem(LOCAL_WALLET_MNEMONIC, dataStr);
}
}

View File

@ -0,0 +1,22 @@
import { hdkey } from 'ethereumjs-wallet'
import { generateMnemonic, mnemonicToSeedSync } from "bip39";
export function newAccount(password: string, index: number) {
const mnemonic = this.loadMnemonic(password)
const seed = mnemonicToSeedSync(mnemonic)
const hdWallet = hdkey.fromMasterSeed(seed)
const keyPair1 = hdWallet.derivePath(`m/44'/60'/0'/0/${index}`)
const w1 = keyPair1.getWallet()
return {address: w1.getAddressString(), privateKey: w1.getPrivateKeyString()}
}
export function newMnemonic(password: string) {
let mnemonic = generateMnemonic()
this.saveMnemonic(mnemonic, password)
return mnemonic
}
export function restoreWalletByMnemonic(mnemonic: string, password: string) {
this.saveMnemonic(mnemonic, password)
}

32
src/util/crypto.util.ts Normal file
View File

@ -0,0 +1,32 @@
import { AES, enc, mode, pad } from 'crypto-js';
import sha256 from 'crypto-js/sha256'
function generateIV(password: string) {
const key = sha256(password).toString();
const keyHex = enc.Base64.parse(key);
const ivHex = keyHex.clone();
ivHex.sigBytes = 16;
ivHex.words.splice(4);
return {keyHex,ivHex}
}
export function aesEncrypt(text: string, password: string) {
const {keyHex, ivHex} = generateIV(password);
const messageHex = enc.Utf8.parse(text);
const encrypted = AES.encrypt(messageHex, keyHex, {
"iv": ivHex,
"mode": mode.CBC,
"padding": pad.Pkcs7
});
return encrypted.toString();
}
export function aesDecrypt(encryptedText: string, password: string) {
const {keyHex, ivHex} = generateIV(password);
const decrypt = AES.decrypt(encryptedText, keyHex, {
"iv": ivHex,
"mode": mode.CBC,
"padding": pad.Pkcs7
});
return enc.Utf8.stringify(decrypt);
}

View File

@ -1204,6 +1204,11 @@
dependencies:
defer-to-connect "^1.0.1"
"@types/aes-js@^3.1.1":
version "3.1.1"
resolved "https://registry.npmmirror.com/@types/aes-js/-/aes-js-3.1.1.tgz#34b3978122310c135de4b377270d1d65676fae28"
integrity sha512-SDSGgXT3LRCH6qMWk8OHT1vLSVNuHNvCpKCx2/TYtQMbMGGgxJC9fspwSkQjqzRagrWnCrxuLL3jMNXLXHHvSw==
"@types/bn.js@^4.11.3":
version "4.11.6"
resolved "https://registry.npmmirror.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
@ -1218,6 +1223,11 @@
dependencies:
"@types/node" "*"
"@types/crypto-js@^4.1.1":
version "4.1.1"
resolved "https://registry.npmmirror.com/@types/crypto-js/-/crypto-js-4.1.1.tgz#602859584cecc91894eb23a4892f38cfa927890d"
integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==
"@types/json-schema@^7.0.5":
version "7.0.11"
resolved "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
@ -2381,6 +2391,11 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0, crypto-browserify@^3.12.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
crypto-js@^4.1.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
cyclist@^1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"