jcwallet/src/manage/WalletManage.ts
2023-08-17 18:59:58 +08:00

171 lines
5.6 KiB
TypeScript

import { hdkey } from 'ethereumjs-wallet';
import { generateMnemonic, mnemonicToSeedSync } from 'bip39';
import { loadMnemonic, saveMnemonic } from './DataManage';
import { NativeSvr } from '../services/NativeSvr';
import {
appleAuth,
clientAuth,
facebookAuth,
getWalletInfo,
googleAuth,
tikTokAuth,
twitterAuth,
uploadWalletInfo,
} from '../api/WalletApi';
import { WalletEnv } from '../config/WalletEnv';
import { retry } from '../util/promise.util';
import { MAX_TRY_COUNT, MAX_UPLOAD_COUNT } from '../config/constants';
import { ZError } from '../common/ZError';
import { emailLogin } from '../api/EmailApi';
export function newAccount(password: string, index: number) {
const mnemonic = 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();
saveMnemonic(mnemonic, password);
return mnemonic;
}
export function restoreWalletByMnemonic(mnemonic: string, password: string) {
saveMnemonic(mnemonic, password);
}
export async function syncWalletEnv() {
let walletEnv = new WalletEnv();
let infoRes = await retry(() => getWalletInfo(), MAX_TRY_COUNT);
if (infoRes.errcode) {
throw new ZError(infoRes.errcode, infoRes.errmsg);
}
walletEnv.address = infoRes.data.address;
walletEnv.key = infoRes.data.key;
walletEnv.salt = infoRes.data.salt;
}
export async function walletPreLogin(channel: number) {
let walletEnv = new WalletEnv();
let tokenRes: any;
if (channel == 1) {
let res: any = await new NativeSvr().signWithApple();
window.debug && console.log('native apple res: ' + res);
tokenRes = await appleAuth(res);
} else if (channel == 2) {
let res: any = await new NativeSvr().signWithTikTok();
window.debug && console.log('native tiktok res: ' + res);
tokenRes = await tikTokAuth(res);
} else if (channel == 3) {
let res: any = await new NativeSvr().signWithFacebook();
window.debug && console.log('native facebook res: ' + res);
tokenRes = await facebookAuth(res);
} else if (channel == 4) {
let res: any = await new NativeSvr().signWithTwitter();
window.debug && console.log('native twitter res: ' + res);
tokenRes = await twitterAuth(res);
} else if (channel == 10) {
let res: any = await new NativeSvr().clientLogin();
console.log('native client res: ' + res);
tokenRes = await clientAuth(res);
} else {
let res: any = await new NativeSvr().signWithGoogle();
window.debug && console.log('native google res: ' + res);
tokenRes = await googleAuth(res);
}
window.debug && console.log(tokenRes);
window.debug && console.log('wallet token: ' + tokenRes.data?.token);
if (tokenRes.errcode || !tokenRes.data?.token) {
throw new ZError(tokenRes.errcode, tokenRes.errmsg);
}
walletEnv.token = tokenRes.data.token;
await syncWalletEnv();
return { token: walletEnv.token, address: walletEnv.address };
}
export async function loginByEmail(email: string, password: string) {
password = jsb.hashSvrPass(password);
let tokenRes = await emailLogin({ email, password });
if (tokenRes.errcode || !tokenRes.data?.token) {
throw new ZError(tokenRes.errcode, tokenRes.errmsg);
}
let walletEnv = new WalletEnv();
walletEnv.token = tokenRes.data.token;
await syncWalletEnv();
return { token: walletEnv.token, address: walletEnv.address };
}
export async function loadInternalWallet(pass: string) {
let walletEnv = new WalletEnv();
let address = await prepareInternalWallet(pass);
if (walletEnv.address && walletEnv.address !== address) {
throw new ZError(10, 'address not match, perhaps wrong password');
}
if (!walletEnv.address) {
retry(() => uploadWalletInfo({ address }), MAX_UPLOAD_COUNT);
}
walletEnv.address = address;
return address;
}
async function prepareInternalWallet(pass: string) {
let walletEnv = new WalletEnv();
if (!walletEnv.key) {
await syncWalletEnv();
}
let { id, openid } = walletEnv.tokenData;
let address = jsb.prepareWallet(id, openid, walletEnv.key, walletEnv.salt, pass);
return address;
}
/**
* calc wallet address and check if address is same with walletEnv.address
* @param pass
* @returns
*/
export async function verifyPassword(pass: string) {
let address = await prepareInternalWallet(pass);
return new WalletEnv().address === address;
}
export function exportSecKey(pass: string) {
let walletEnv = new WalletEnv();
if (!walletEnv.address || !walletEnv.key) {
throw new ZError(10, 'wallet not found');
}
let { id, openid } = walletEnv.tokenData;
let resultStr = jsb.walletSecKey(id, openid, walletEnv.key, walletEnv.salt, pass);
let result = JSON.parse(resultStr);
if (result.address !== walletEnv.address) {
throw new ZError(11, 'address not match, perhaps wrong password');
}
return result.key;
}
export function walletSign(str: string) {
let result = jsb.walletSign(str);
return result;
}
export async function parseWebLogin(dataStr: string) {
console.log('found web login scheme, begin login');
// if (dataStr.indexOf("|") < 0) {
// return;
// }
// let datas = dataStr.split("|");
// let webtoken = datas[0];
// let pk64 = datas[1];
// let pk = jsb.hexInflate(pk64);
// let keyEncrypt = jsb.encryptedLocalKey(pk);
// console.log("webtoken: " + webtoken);
// console.log("local key: " + keyEncrypt);
// let result = await uploadInfoForWebLogin({ key: keyEncrypt, webtoken });
// console.log("login result: " + result);
}