import { PrivateKeyAccount, Wallet, Conflux } from "js-conflux-sdk"; import { Account } from "js-conflux-sdk/src/wallet/Account"; import { BaseProvider } from "../providers"; export class Signer { cfxClient?: Conflux; address?: string; index?: number; provider?: any; constructor(provider?) { if (provider === undefined) { this.provider = null; } else if (provider instanceof BaseProvider) { this.provider = provider; this.cfxClient = provider.cfxClient; } else { this.cfxClient = new Conflux(); this.cfxClient.provider = provider; provider.on("chainChanged", this.cfxClient.updateNetworkId); this.cfxClient.updateNetworkId(); } } /** * create */ public connect(provider: any) { this.cfxClient.provider = provider; } /** * create */ public create(entropy?: string) { return this.cfxClient.cfx.account.create(entropy); } /** * get address */ public getAddress(): Promise { return Promise.resolve(this.address); } /** * get balance */ public async getBalance(blockTag = "latest_state"): Promise { return await this.cfxClient.getBalance(await this.getAddress(), blockTag); } /** * get transaction */ async getTransaction(transactionHash: string, blockTag = "latest_state"): Promise { return this.cfxClient.getTransactionByHash(transactionHash); } /** * populate transaction */ public populateTransaction(options: object): Promise { return this.cfxClient.cfx.populateTransaction(options); } /** * sign transaction */ public signTransaction(options: object): Promise { const account = this.cfxClient.wallet.get(this.address); const signedTx = account.signTransaction(options); return signedTx.serialize(); } /** * sign message */ public signMessage(message: string): Promise { const account = this.cfxClient.wallet.get(this.address); const signedMsg = account.signMessage(message); return signedMsg.serialize(); } /** * Sign and send transaction * if `from` field in `conflux.wallet`, sign by local account and send raw transaction, * else call `cfx_sendTransaction` and sign by remote wallet */ public sendTransaction(options: object, password?: string): Promise { return this.cfxClient.sendTransaction(options, password); } /** * Estimate a transaction"s gas and storageCollateralize, * check whether user"s balance is enough for fee and value */ public estimateGas(options: object, epochNumber: string | number): Promise { return this.cfxClient.estimateGasAndCollateralAdvance(options, epochNumber) } public call(options: object, epochNumber: string | number): Promise { return this.cfxClient.call(options, epochNumber); } public async getAccountByAddress(address: string): Promise { return this.cfxClient.wallet.get(address) } public async getAccountByIndex(index: number = 0): Promise { const wallet = this.cfxClient.wallet; const account_array = Array.from(wallet.values()); const account = account_array[index] return account; } } export class VoidSigner extends Signer { address: string; cfxClient?: Conflux; constructor(address: string, provider?: any) { super(provider); this.address = address; } public connect(provider: any): VoidSigner { return new VoidSigner(this.address, provider); } public getAddress(): Promise { return Promise.resolve(this.address); } private _fail(message: string, operation: string, duration: number = 0): Promise { return Promise.resolve().then(() => { this.cfxClient.cfx.logger.error(operation, message, duration); }); } public async signMessage(message: any): Promise { const error_message = "VoidSigner cannot sign messages" this._fail(error_message, "signMessage"); return { "error_message": error_message }; } public async signTransaction(transaction: any): Promise { const error_message = "VoidSigner cannot sign transactions" this._fail("VoidSigner cannot sign transactions", "signTransaction"); return { "error_message": error_message }; } public createRandom(entropy?: any) { const account = this.cfxClient.wallet.addRandom(); this.address = account.address; return account; } }