UNPKG

ldpos-chain-crypto

Version:
107 lines (93 loc) 3.06 kB
const fs = require('fs'); const path = require('path'); const util = require('util'); const mkdir = util.promisify(fs.mkdir); const { createClient } = require('ldpos-client'); const { LDEX_LDPOS_MULTISIG_KEY_INDEX } = process.env; class LDPoSChainCrypto { constructor({ chainSymbol, chainOptions }) { this.chainSymbol = chainSymbol; this.chainModuleAlias = chainOptions.moduleAlias; this.passphrase = chainOptions.passphrase; this.multisigAddress = chainOptions.multisigAddress; this.memberAddress = chainOptions.memberAddress; if (chainOptions.keyIndexDirPath == null) { throw new Error( `A keyIndexDirPath must be specified as part of the ${ this.chainSymbol } chain config` ); } this.keyIndexDirPath = path.resolve(chainOptions.keyIndexDirPath); } async load(channel) { await mkdir(this.keyIndexDirPath, { recursive: true }); this.ldposClient = createClient({ networkSymbol: this.chainSymbol, adapter: { getNetworkSymbol: async () => { return this.chainSymbol; }, getAccount: async (walletAddress) => { return channel.invoke(`${this.chainModuleAlias}:getAccount`, { walletAddress }); } }, keyIndexDirPath: this.keyIndexDirPath }); await this.ldposClient.connect({ passphrase: this.passphrase, walletAddress: this.memberAddress, multisigKeyIndex: LDEX_LDPOS_MULTISIG_KEY_INDEX == null ? null : Number(LDEX_LDPOS_MULTISIG_KEY_INDEX) }); await this.ldposClient.syncKeyIndex('multisig'); } async unload() { this.ldposClient.disconnect(); } // This method checks that: // 1. The signerAddress corresponds to the publicKey. // 2. The publicKey corresponds to the signature. async verifyTransactionSignature(transaction, signaturePacket) { let { signerAddress, multisigPublicKey } = signaturePacket; let account = await this.ldposClient.getAccount(signerAddress); if ( multisigPublicKey !== account.multisigPublicKey && multisigPublicKey !== account.nextMultisigPublicKey ) { return false; } return this.ldposClient.verifyMultisigTransactionSignature(transaction, signaturePacket); } async prepareTransaction(transactionData) { let { recipientAddress, amount, fee, timestamp, message } = transactionData; if (!this.ldposClient.validateWalletAddress(recipientAddress)) { throw new Error( 'Failed to prepare the transaction because the recipientAddress was invalid' ); } let unsignedTransaction = { type: 'transfer', senderAddress: this.multisigAddress, recipientAddress, amount, fee, timestamp, message }; let transaction = this.ldposClient.prepareMultisigTransaction(unsignedTransaction); let signature = await this.ldposClient.signMultisigTransaction(transaction); return { transaction, signature }; } } module.exports = LDPoSChainCrypto;