From 9bd54ec8f66c190d0d1ac885aa4eaaef687cd012 Mon Sep 17 00:00:00 2001 From: Shusetsu Toda Date: Wed, 5 Dec 2018 19:46:46 +0100 Subject: [PATCH 1/2] :seedling: Update transaction commands to typescript --- .../{broadcast.js => broadcast.ts} | 52 +++---- .../transaction/{create.js => create.ts} | 88 +++++++----- .../create/{delegate.js => delegate.ts} | 75 +++++----- .../transaction/create/multisignature.js | 122 ---------------- .../transaction/create/multisignature.ts | 132 ++++++++++++++++++ ...ond-passphrase.js => second-passphrase.ts} | 0 .../create/{transfer.js => transfer.ts} | 0 .../transaction/create/{vote.js => vote.ts} | 75 +++++----- src/commands/transaction/{get.js => get.ts} | 132 +++++++++--------- src/commands/transaction/{sign.js => sign.ts} | 64 +++++---- .../transaction/{verify.js => verify.ts} | 72 +++++----- src/utils/flags.ts | 2 +- 12 files changed, 433 insertions(+), 381 deletions(-) rename src/commands/transaction/{broadcast.js => broadcast.ts} (66%) rename src/commands/transaction/{create.js => create.ts} (57%) rename src/commands/transaction/create/{delegate.js => delegate.ts} (54%) delete mode 100644 src/commands/transaction/create/multisignature.js create mode 100644 src/commands/transaction/create/multisignature.ts rename src/commands/transaction/create/{second-passphrase.js => second-passphrase.ts} (100%) rename src/commands/transaction/create/{transfer.js => transfer.ts} (100%) rename src/commands/transaction/create/{vote.js => vote.ts} (59%) rename src/commands/transaction/{get.js => get.ts} (58%) rename src/commands/transaction/{sign.js => sign.ts} (73%) rename src/commands/transaction/{verify.js => verify.ts} (70%) diff --git a/src/commands/transaction/broadcast.js b/src/commands/transaction/broadcast.ts similarity index 66% rename from src/commands/transaction/broadcast.js rename to src/commands/transaction/broadcast.ts index 055520be..9984f80f 100644 --- a/src/commands/transaction/broadcast.js +++ b/src/commands/transaction/broadcast.ts @@ -14,17 +14,18 @@ * */ import BaseCommand from '../../base'; -import { parseTransactionString } from '../../utils/transactions'; +import { getAPIClient } from '../../utils/api'; import { ValidationError } from '../../utils/error'; import { getStdIn } from '../../utils/input/utils'; -import { getAPIClient } from '../../utils/api'; +import { parseTransactionString } from '../../utils/transactions'; -const getTransactionInput = async () => { +const getTransactionInput = async (): Promise => { try { const { data } = await getStdIn({ dataIsRequired: true }); if (!data) { throw new ValidationError('No transaction was provided.'); } + return data; } catch (e) { throw new ValidationError('No transaction was provided.'); @@ -32,7 +33,29 @@ const getTransactionInput = async () => { }; export default class BroadcastCommand extends BaseCommand { - async run() { + static args = [ + { + name: 'transaction', + description: 'Transaction to broadcast in JSON format.', + }, + ]; + + static description = ` + Broadcasts a transaction to the network via the node specified in the current config. + Accepts a stringified JSON transaction as an argument, or a transaction can be piped from a previous command. + If piping make sure to quote out the entire command chain to avoid piping-related conflicts in your shell. + `; + + static examples = [ + 'broadcast transaction \'{"type":0,"amount":"100",...}\'', + 'echo \'{"type":0,"amount":"100",...}\' | lisk transaction:broadcast', + ]; + + static flags = { + ...BaseCommand.flags, + }; + + async run(): Promise { const { args: { transaction } } = this.parse(BroadcastCommand); const transactionInput = transaction || (await getTransactionInput()); const transactionObject = parseTransactionString(transactionInput); @@ -42,24 +65,3 @@ export default class BroadcastCommand extends BaseCommand { } } -BroadcastCommand.args = [ - { - name: 'transaction', - description: 'Transaction to broadcast in JSON format.', - }, -]; - -BroadcastCommand.flags = { - ...BaseCommand.flags, -}; - -BroadcastCommand.description = ` -Broadcasts a transaction to the network via the node specified in the current config. -Accepts a stringified JSON transaction as an argument, or a transaction can be piped from a previous command. -If piping make sure to quote out the entire command chain to avoid piping-related conflicts in your shell. -`; - -BroadcastCommand.examples = [ - 'broadcast transaction \'{"type":0,"amount":"100",...}\'', - 'echo \'{"type":0,"amount":"100",...}\' | lisk transaction:broadcast', -]; diff --git a/src/commands/transaction/create.js b/src/commands/transaction/create.ts similarity index 57% rename from src/commands/transaction/create.js rename to src/commands/transaction/create.ts index 324b079a..79c5645e 100644 --- a/src/commands/transaction/create.js +++ b/src/commands/transaction/create.ts @@ -16,28 +16,36 @@ import { flags as flagParser } from '@oclif/command'; import BaseCommand from '../../base'; import { flags as commonFlags } from '../../utils/flags'; -import TransferCommand from './create/transfer'; -import SecondPassphraseCommand from './create/second-passphrase'; -import VoteCommand from './create/vote'; import DelegateCommand from './create/delegate'; import MultisignatureCommand from './create/multisignature'; +import SecondPassphraseCommand from './create/second-passphrase'; +import TransferCommand from './create/transfer'; +import VoteCommand from './create/vote'; const MAX_ARG_NUM = 3; -const typeNumberMap = { - 0: 'transfer', - 1: 'second-passphrase', - 2: 'delegate', - 3: 'vote', - 4: 'multisignature', +interface TypeNumberMap { + readonly [key: string]: string; +} + +const typeNumberMap: TypeNumberMap = { + '0': 'transfer', + '1': 'second-passphrase', + '2': 'delegate', + '3': 'vote', + '4': 'multisignature', }; const options = Object.entries(typeNumberMap).reduce( - (accumulated, [key, value]) => [...accumulated, key, value], + (accumulated: ReadonlyArray, [key, value]: [string, string]) => [...accumulated, key, value], [], ); -const typeClassMap = { +interface TypeClassMap { + readonly [key: string]: typeof BaseCommand; +} + +const typeClassMap: TypeClassMap = { transfer: TransferCommand, 'second-passphrase': SecondPassphraseCommand, vote: VoteCommand, @@ -45,7 +53,7 @@ const typeClassMap = { multisignature: MultisignatureCommand, }; -const resolveFlags = (accumulated, [key, value]) => { +const resolveFlags = (accumulated: ReadonlyArray, [key, value]: [string, string | boolean | undefined]) => { if (key === 'type') { return accumulated; } @@ -53,11 +61,40 @@ const resolveFlags = (accumulated, [key, value]) => { return [...accumulated, `--${key}`, value]; } const boolKey = value === false ? `--no-${key}` : `--${key}`; + return [...accumulated, boolKey]; }; export default class CreateCommand extends BaseCommand { - async run() { + static args = new Array(MAX_ARG_NUM).fill(0).map(i => ({ + name: `${i}_arg`, + })); + + static description = ` + Creates a transaction object. + `; + + static examples = [ + 'transaction:create --type=0 100 13356260975429434553L', + 'transaction:create --type=delegate lightcurve', + ]; + + static flags = { + ...BaseCommand.flags, + type: flagParser.string({ + char: 't', + description: 'type of transaction to create', + required: true, + options, + }), + passphrase: flagParser.string(commonFlags.passphrase), + 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), + 'no-signature': flagParser.boolean(commonFlags.noSignature), + votes: flagParser.string(commonFlags.votes), + unvotes: flagParser.string(commonFlags.unvotes), + }; + + async run(): Promise { const { argv, flags } = this.parse(CreateCommand); const { type } = flags; const commandType = Object.keys(typeNumberMap).includes(type) @@ -68,30 +105,5 @@ export default class CreateCommand extends BaseCommand { } } -CreateCommand.flags = { - ...BaseCommand.flags, - type: flagParser.string({ - char: 't', - description: 'type of transaction to create', - required: true, - options, - }), - passphrase: flagParser.string(commonFlags.passphrase), - 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), - 'no-signature': flagParser.boolean(commonFlags.noSignature), - votes: flagParser.string(commonFlags.votes), - unvotes: flagParser.string(commonFlags.unvotes), -}; - -CreateCommand.args = new Array(MAX_ARG_NUM).fill().map(i => ({ - name: `${i}_arg`, -})); -CreateCommand.description = ` -Creates a transaction object. -`; -CreateCommand.examples = [ - 'transaction:create --type=0 100 13356260975429434553L', - 'transaction:create --type=delegate lightcurve', -]; diff --git a/src/commands/transaction/create/delegate.js b/src/commands/transaction/create/delegate.ts similarity index 54% rename from src/commands/transaction/create/delegate.js rename to src/commands/transaction/create/delegate.ts index 32d4edc2..ae5591e8 100644 --- a/src/commands/transaction/create/delegate.js +++ b/src/commands/transaction/create/delegate.ts @@ -13,23 +13,48 @@ * Removal or modification of this copyright notice is prohibited. * */ +import { registerDelegate } from '@liskhq/lisk-transactions'; import { flags as flagParser } from '@oclif/command'; -import * as transactions from '@liskhq/lisk-transactions'; import BaseCommand from '../../../base'; import { flags as commonFlags } from '../../../utils/flags'; -import { getInputsFromSources } from '../../../utils/input'; +import { getInputsFromSources, InputFromSourceOutput } from '../../../utils/input'; -const processInputs = username => ({ passphrase, secondPassphrase }) => - transactions.registerDelegate({ +interface Args { + readonly username: string; +} + +const processInputs = (username: string) => ({ passphrase, secondPassphrase }: InputFromSourceOutput) => + registerDelegate({ passphrase, secondPassphrase, username, }); export default class DelegateCommand extends BaseCommand { - async run() { + static args = [ + { + name: 'username', + required: true, + description: 'Username to register as a delegate.', + }, + ]; + + static description = ` + Creates a transaction which will register the account as a delegate candidate if broadcast to the network. + `; + + static examples = ['transaction:create:delegate lightcurve']; + + static flags = { + ...BaseCommand.flags, + passphrase: flagParser.string(commonFlags.passphrase), + 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), + 'no-signature': flagParser.boolean(commonFlags.noSignature), + }; + + async run(): Promise { const { - args: { username }, + args, flags: { passphrase: passphraseSource, 'second-passphrase': secondPassphraseSource, @@ -37,14 +62,17 @@ export default class DelegateCommand extends BaseCommand { }, } = this.parse(DelegateCommand); + const { username }: Args = args; const processFunction = processInputs(username); if (noSignature) { - const result = processFunction({ - passphrase: null, - secondPassphrase: null, + const noSignatureResult = processFunction({ + passphrase: undefined, + secondPassphrase: undefined, }); - return this.print(result); + this.print(noSignatureResult); + + return; } const inputs = await getInputsFromSources({ @@ -53,34 +81,13 @@ export default class DelegateCommand extends BaseCommand { repeatPrompt: true, }, secondPassphrase: !secondPassphraseSource - ? null + ? undefined : { source: secondPassphraseSource, repeatPrompt: true, }, }); const result = processFunction(inputs); - return this.print(result); + this.print(result); } -} - -DelegateCommand.args = [ - { - name: 'username', - required: true, - description: 'Username to register as a delegate.', - }, -]; - -DelegateCommand.flags = { - ...BaseCommand.flags, - passphrase: flagParser.string(commonFlags.passphrase), - 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), - 'no-signature': flagParser.boolean(commonFlags.noSignature), -}; - -DelegateCommand.description = ` -Creates a transaction which will register the account as a delegate candidate if broadcast to the network. -`; - -DelegateCommand.examples = ['transaction:create:delegate lightcurve']; +} \ No newline at end of file diff --git a/src/commands/transaction/create/multisignature.js b/src/commands/transaction/create/multisignature.js deleted file mode 100644 index ba23503a..00000000 --- a/src/commands/transaction/create/multisignature.js +++ /dev/null @@ -1,122 +0,0 @@ -/* - * LiskHQ/lisk-commander - * Copyright © 2017–2018 Lisk Foundation - * - * See the LICENSE file at the top-level directory of this distribution - * for licensing information. - * - * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, - * no part of this software, including this file, may be copied, modified, - * propagated, or distributed except according to the terms contained in the - * LICENSE file. - * - * Removal or modification of this copyright notice is prohibited. - * - */ -import { flags as flagParser } from '@oclif/command'; -import * as transactions from '@liskhq/lisk-transactions'; -import BaseCommand from '../../../base'; -import { flags as commonFlags } from '../../../utils/flags'; -import { getInputsFromSources } from '../../../utils/input'; -import { validateLifetime, validateMinimum } from '../../../utils/helpers'; - -const processInputs = (lifetime, minimum, keysgroup) => ({ - passphrase, - secondPassphrase, -}) => - transactions.registerMultisignature({ - passphrase, - secondPassphrase, - keysgroup, - lifetime, - minimum, - }); - -export default class MultisignatureCommand extends BaseCommand { - async run() { - const { - args: { lifetime, minimum, keysgroup }, - flags: { - passphrase: passphraseSource, - 'second-passphrase': secondPassphraseSource, - 'no-signature': noSignature, - }, - } = this.parse(MultisignatureCommand); - - transactions.utils.validatePublicKeys(keysgroup); - - validateLifetime(lifetime); - validateMinimum(minimum); - - const transactionLifetime = parseInt(lifetime, 10); - const transactionMinimumConfirmations = parseInt(minimum, 10); - const processFunction = processInputs( - transactionLifetime, - transactionMinimumConfirmations, - keysgroup, - ); - - if (noSignature) { - const result = processFunction({ - passphrase: null, - secondPassphrase: null, - }); - return this.print(result); - } - - const inputs = await getInputsFromSources({ - passphrase: { - source: passphraseSource, - repeatPrompt: true, - }, - secondPassphrase: !secondPassphraseSource - ? null - : { - source: secondPassphraseSource, - repeatPrompt: true, - }, - }); - const result = processFunction(inputs); - return this.print(result); - } -} - -MultisignatureCommand.args = [ - { - name: 'lifetime', - required: true, - description: - 'Number of hours the transaction should remain in the transaction pool before becoming invalid.', - }, - { - name: 'minimum', - required: true, - description: - 'Minimum number of signatures required for a transaction from the account to be valid.', - }, - { - name: 'keysgroup', - required: true, - description: - 'Public keys to verify signatures against for the multisignature group.', - parse: input => input.split(','), - }, -]; - -MultisignatureCommand.flags = { - ...BaseCommand.flags, - passphrase: flagParser.string(commonFlags.passphrase), - 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), - 'no-signature': flagParser.boolean(commonFlags.noSignature), -}; - -MultisignatureCommand.description = ` -Creates a transaction which will register the account as a multisignature account if broadcast to the network, using the following arguments: - 1. Number of hours the transaction should remain in the transaction pool before becoming invalid. - 2. Minimum number of signatures required for a transaction from the account to be valid. - 3. Public keys to verify signatures against for the multisignature group. -`; - -MultisignatureCommand.examples = [ - 'transaction:create:multisignature 24 2 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca,922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', -]; diff --git a/src/commands/transaction/create/multisignature.ts b/src/commands/transaction/create/multisignature.ts new file mode 100644 index 00000000..089fe618 --- /dev/null +++ b/src/commands/transaction/create/multisignature.ts @@ -0,0 +1,132 @@ +/* + * LiskHQ/lisk-commander + * Copyright © 2017–2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { registerMultisignature, utils as transactionUtils } from '@liskhq/lisk-transactions'; +import { flags as flagParser } from '@oclif/command'; +import BaseCommand from '../../../base'; +import { flags as commonFlags } from '../../../utils/flags'; +import { validateLifetime, validateMinimum } from '../../../utils/helpers'; +import { getInputsFromSources, InputFromSourceOutput } from '../../../utils/input'; + +interface Args { + readonly keysgroup: string; + readonly lifetime: string; + readonly minimum: string; +} + +const processInputs = (lifetime: number, minimum: number, keysgroup: ReadonlyArray) => ({ + passphrase, + secondPassphrase, +}: InputFromSourceOutput) => + registerMultisignature({ + passphrase, + secondPassphrase, + keysgroup, + lifetime, + minimum, + }); + +export default class MultisignatureCommand extends BaseCommand { + static args = [ + { + name: 'lifetime', + required: true, + description: + 'Number of hours the transaction should remain in the transaction pool before becoming invalid.', + }, + { + name: 'minimum', + required: true, + description: + 'Minimum number of signatures required for a transaction from the account to be valid.', + }, + { + name: 'keysgroup', + required: true, + description: + 'Public keys to verify signatures against for the multisignature group.', + }, + ]; + + static description = ` + Creates a transaction which will register the account as a multisignature account if broadcast to the network, using the following arguments: + 1. Number of hours the transaction should remain in the transaction pool before becoming invalid. + 2. Minimum number of signatures required for a transaction from the account to be valid. + 3. Public keys to verify signatures against for the multisignature group. + `; + + static examples = [ + 'transaction:create:multisignature 24 2 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca,922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + ]; + + static flags = { + ...BaseCommand.flags, + passphrase: flagParser.string(commonFlags.passphrase), + 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), + 'no-signature': flagParser.boolean(commonFlags.noSignature), + }; + + async run(): Promise { + const { + args, + flags: { + passphrase: passphraseSource, + 'second-passphrase': secondPassphraseSource, + 'no-signature': noSignature, + }, + } = this.parse(MultisignatureCommand); + + const { lifetime, minimum, keysgroup: keysgroupStr }: Args = args; + const keysgroup = keysgroupStr.split(','); + + transactionUtils.validatePublicKeys(keysgroup); + + validateLifetime(lifetime); + validateMinimum(minimum); + + const transactionLifetime = parseInt(lifetime, 10); + const transactionMinimumConfirmations = parseInt(minimum, 10); + const processFunction = processInputs( + transactionLifetime, + transactionMinimumConfirmations, + keysgroup, + ); + + if (noSignature) { + const noSignatureResult = processFunction({ + passphrase: undefined, + secondPassphrase: undefined, + }); + this.print(noSignatureResult); + + return; + } + + const inputs = await getInputsFromSources({ + passphrase: { + source: passphraseSource, + repeatPrompt: true, + }, + secondPassphrase: !secondPassphraseSource + ? undefined + : { + source: secondPassphraseSource, + repeatPrompt: true, + }, + }); + const result = processFunction(inputs); + this.print(result); + } +} \ No newline at end of file diff --git a/src/commands/transaction/create/second-passphrase.js b/src/commands/transaction/create/second-passphrase.ts similarity index 100% rename from src/commands/transaction/create/second-passphrase.js rename to src/commands/transaction/create/second-passphrase.ts diff --git a/src/commands/transaction/create/transfer.js b/src/commands/transaction/create/transfer.ts similarity index 100% rename from src/commands/transaction/create/transfer.js rename to src/commands/transaction/create/transfer.ts diff --git a/src/commands/transaction/create/vote.js b/src/commands/transaction/create/vote.ts similarity index 59% rename from src/commands/transaction/create/vote.js rename to src/commands/transaction/create/vote.ts index 9c966a70..2ae49965 100644 --- a/src/commands/transaction/create/vote.js +++ b/src/commands/transaction/create/vote.ts @@ -13,39 +13,57 @@ * Removal or modification of this copyright notice is prohibited. * */ +import { castVotes, utils as transactionUtils } from '@liskhq/lisk-transactions'; import { flags as flagParser } from '@oclif/command'; -import * as transactions from '@liskhq/lisk-transactions'; import BaseCommand from '../../../base'; +import { ValidationError } from '../../../utils/error'; import { flags as commonFlags } from '../../../utils/flags'; -import { getInputsFromSources } from '../../../utils/input'; +import { getInputsFromSources, InputFromSourceOutput } from '../../../utils/input'; import { getData } from '../../../utils/input/utils'; -import { ValidationError } from '../../../utils/error'; -const processInputs = (votes, unvotes) => ({ passphrase, secondPassphrase }) => - transactions.castVotes({ +const processInputs = (votes: ReadonlyArray, unvotes: ReadonlyArray) => ({ passphrase, secondPassphrase }: InputFromSourceOutput) => + castVotes({ passphrase, votes, unvotes, secondPassphrase, }); -const processVotesInput = async votes => +const processVotesInput = async (votes: string) => votes.includes(':') ? getData(votes) : votes; -const processVotes = votes => +const processVotes = (votes: string) => votes .replace(/\n/g, ',') .split(',') .filter(Boolean) .map(vote => vote.trim()); -const validatePublicKeys = inputs => { - transactions.utils.validatePublicKeys(inputs); +const validatePublicKeys = (inputs: ReadonlyArray) => { + transactionUtils.validatePublicKeys(inputs); + return inputs; }; export default class VoteCommand extends BaseCommand { - async run() { + static description = ` + Creates a transaction which will cast votes (or unvotes) for delegate candidates using their public keys if broadcast to the network. + `; + + static examples = [ + 'transaction:create:vote --votes 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca,922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa --unvotes e01b6b8a9b808ec3f67a638a2d3fa0fe1a9439b91dbdde92e2839c3327bd4589,ac09bc40c889f688f9158cca1fcfcdf6320f501242e0f7088d52a5077084ccba', + ]; + + static flags = { + ...BaseCommand.flags, + passphrase: flagParser.string(commonFlags.passphrase), + 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), + 'no-signature': flagParser.boolean(commonFlags.noSignature), + votes: flagParser.string(commonFlags.votes), + unvotes: flagParser.string(commonFlags.unvotes), + }; + + async run(): Promise { const { flags: { passphrase: passphraseSource, @@ -70,10 +88,10 @@ export default class VoteCommand extends BaseCommand { const processedVotesInput = votes ? await processVotesInput(votes.toString()) - : null; + : undefined; const processedUnvotesInput = unvotes ? await processVotesInput(unvotes.toString()) - : null; + : undefined; const validatedVotes = processedVotesInput ? validatePublicKeys(processVotes(processedVotesInput)) @@ -85,11 +103,13 @@ export default class VoteCommand extends BaseCommand { const processFunction = processInputs(validatedVotes, validatedUnvotes); if (noSignature) { - const result = processFunction({ - passphrase: null, - secondPassphrase: null, + const noSignatureResult = processFunction({ + passphrase: undefined, + secondPassphrase: undefined, }); - return this.print(result); + this.print(noSignatureResult); + + return; } const inputs = await getInputsFromSources({ @@ -98,7 +118,7 @@ export default class VoteCommand extends BaseCommand { repeatPrompt: true, }, secondPassphrase: !secondPassphraseSource - ? null + ? undefined : { source: secondPassphraseSource, repeatPrompt: true, @@ -106,23 +126,6 @@ export default class VoteCommand extends BaseCommand { }); const result = processFunction(inputs); - return this.print(result); + this.print(result); } -} - -VoteCommand.flags = { - ...BaseCommand.flags, - passphrase: flagParser.string(commonFlags.passphrase), - 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), - 'no-signature': flagParser.boolean(commonFlags.noSignature), - votes: flagParser.string(commonFlags.votes), - unvotes: flagParser.string(commonFlags.unvotes), -}; - -VoteCommand.description = ` -Creates a transaction which will cast votes (or unvotes) for delegate candidates using their public keys if broadcast to the network. -`; - -VoteCommand.examples = [ - 'transaction:create:vote --votes 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca,922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa --unvotes e01b6b8a9b808ec3f67a638a2d3fa0fe1a9439b91dbdde92e2839c3327bd4589,ac09bc40c889f688f9158cca1fcfcdf6320f501242e0f7088d52a5077084ccba', -]; +} \ No newline at end of file diff --git a/src/commands/transaction/get.js b/src/commands/transaction/get.ts similarity index 58% rename from src/commands/transaction/get.js rename to src/commands/transaction/get.ts index cf5daf90..a4888d43 100644 --- a/src/commands/transaction/get.js +++ b/src/commands/transaction/get.ts @@ -16,8 +16,13 @@ import { flags as flagParser } from '@oclif/command'; import BaseCommand from '../../base'; import { getAPIClient } from '../../utils/api'; +import { AlphabetLowercase } from '../../utils/flags'; import { query, queryNodeTransaction } from '../../utils/query'; +interface Args { + readonly ids?: string; +} + const TRANSACTION_STATES = ['unsigned', 'unprocessed']; const SORT_OPTIONS = [ 'amount:asc', @@ -37,7 +42,7 @@ const senderIdFlag = { `, }; const stateFlag = { - char: 's', + char: 's' as AlphabetLowercase, options: TRANSACTION_STATES, description: `Get transactions based on a given state. Possible values for the state are 'unsigned' and 'unprocessed'. Examples: @@ -47,9 +52,53 @@ const stateFlag = { }; export default class GetCommand extends BaseCommand { - async run() { + static args = [ + { + name: 'ids', + required: false, + description: 'Comma-separated transaction ID(s) to get information about.', + }, + ]; + + static description = ` + Gets transaction information from the blockchain. + `; + + static examples = [ + 'transaction:get 10041151099734832021', + 'transaction:get 10041151099734832021,1260076503909567890', + 'transaction:get 10041151099734832021,1260076503909567890 --state=unprocessed', + 'transaction:get --state=unsigned --sender-id=1813095620424213569L', + 'transaction:get 10041151099734832021 --state=unsigned --sender-id=1813095620424213569L', + 'transaction:get --sender-id=1813095620424213569L', + 'transaction:get --limit=10 --sort=amount:desc', + 'transaction:get --limit=10 --offset=5', + ]; + + static flags = { + ...BaseCommand.flags, + state: flagParser.string(stateFlag), + 'sender-id': flagParser.string(senderIdFlag), + limit: flagParser.string({ + description: + 'Limits the returned transactions array by specified integer amount. Maximum is 100.', + default: '10', + }), + offset: flagParser.string({ + description: + 'Offsets the returned transactions array by specified integer amount.', + default: '0', + }), + sort: flagParser.string({ + description: 'Fields to sort results by.', + default: 'timestamp:desc', + options: SORT_OPTIONS, + }), + }; + + async run(): Promise { const { - args: { ids }, + args, flags: { limit, offset, @@ -58,6 +107,8 @@ export default class GetCommand extends BaseCommand { state: txnState, }, } = this.parse(GetCommand); + const { ids: idsStr = '' }: Args = args; + const ids = idsStr.split(',').filter(Boolean); const client = getAPIClient(this.userConfig.api); @@ -75,13 +126,13 @@ export default class GetCommand extends BaseCommand { }, })); - const results = await queryNodeTransaction( + const stateSenderIdsResult = await queryNodeTransaction( client.node, txnState, reqTxnSenderId, ); - return this.print(results); + return this.print(stateSenderIdsResult); } if (txnState && ids) { @@ -96,13 +147,13 @@ export default class GetCommand extends BaseCommand { }, })); - const results = await queryNodeTransaction( + const txnStateIdsResult = await queryNodeTransaction( client.node, txnState, reqTransactionIds, ); - return this.print(results); + return this.print(txnStateIdsResult); } if (txnState && senderAddress) { const reqWithSenderId = [ @@ -120,13 +171,13 @@ export default class GetCommand extends BaseCommand { }, ]; - const results = await queryNodeTransaction( + const txnStateSenderResult = await queryNodeTransaction( client.node, txnState, reqWithSenderId, ); - return this.print(results); + return this.print(txnStateSenderResult); } if (txnState) { @@ -143,13 +194,13 @@ export default class GetCommand extends BaseCommand { }, ]; - const results = await queryNodeTransaction( + const txnStateResult = await queryNodeTransaction( client.node, txnState, reqByLimitOffset, ); - return this.print(results); + return this.print(txnStateResult); } if (ids) { @@ -163,9 +214,9 @@ export default class GetCommand extends BaseCommand { message: 'Transaction not found.', }, })); - const results = await query(client, 'transactions', reqTransactionIDs); + const idsResult = await query(client, 'transactions', reqTransactionIDs); - return this.print(results); + return this.print(idsResult); } if (senderAddress) { @@ -180,9 +231,9 @@ export default class GetCommand extends BaseCommand { message: 'No transactions found.', }, }; - const results = await query(client, 'transactions', reqSenderId); + const senderAddressResult = await query(client, 'transactions', reqSenderId); - return this.print(results); + return this.print(senderAddressResult); } const req = { @@ -195,53 +246,8 @@ export default class GetCommand extends BaseCommand { message: 'No transactions found.', }, }; - const results = await query(client, 'transactions', req); + const defaultResults = await query(client, 'transactions', req); - return this.print(results); + return this.print(defaultResults); } -} - -GetCommand.args = [ - { - name: 'ids', - required: false, - description: 'Comma-separated transaction ID(s) to get information about.', - parse: input => input.split(',').filter(Boolean), - }, -]; - -GetCommand.flags = { - ...BaseCommand.flags, - state: flagParser.string(stateFlag), - 'sender-id': flagParser.string(senderIdFlag), - limit: flagParser.string({ - description: - 'Limits the returned transactions array by specified integer amount. Maximum is 100.', - default: '10', - }), - offset: flagParser.string({ - description: - 'Offsets the returned transactions array by specified integer amount.', - default: '0', - }), - sort: flagParser.string({ - description: 'Fields to sort results by.', - default: 'timestamp:desc', - options: SORT_OPTIONS, - }), -}; - -GetCommand.description = ` -Gets transaction information from the blockchain. -`; - -GetCommand.examples = [ - 'transaction:get 10041151099734832021', - 'transaction:get 10041151099734832021,1260076503909567890', - 'transaction:get 10041151099734832021,1260076503909567890 --state=unprocessed', - 'transaction:get --state=unsigned --sender-id=1813095620424213569L', - 'transaction:get 10041151099734832021 --state=unsigned --sender-id=1813095620424213569L', - 'transaction:get --sender-id=1813095620424213569L', - 'transaction:get --limit=10 --sort=amount:desc', - 'transaction:get --limit=10 --offset=5', -]; +} \ No newline at end of file diff --git a/src/commands/transaction/sign.js b/src/commands/transaction/sign.ts similarity index 73% rename from src/commands/transaction/sign.js rename to src/commands/transaction/sign.ts index c584093b..eca42602 100644 --- a/src/commands/transaction/sign.js +++ b/src/commands/transaction/sign.ts @@ -16,18 +16,23 @@ import * as transactions from '@liskhq/lisk-transactions'; import { flags as flagParser } from '@oclif/command'; import BaseCommand from '../../base'; -import { getStdIn } from '../../utils/input/utils'; import { ValidationError } from '../../utils/error'; -import { parseTransactionString } from '../../utils/transactions'; -import { getInputsFromSources } from '../../utils/input'; import { flags as commonFlags } from '../../utils/flags'; +import { getInputsFromSources } from '../../utils/input'; +import { getStdIn } from '../../utils/input/utils'; +import { parseTransactionString } from '../../utils/transactions'; + +interface Args { + readonly transaction?: string; +} -const getTransactionInput = async () => { +const getTransactionInput = async (): Promise => { try { const { data } = await getStdIn({ dataIsRequired: true }); if (!data) { throw new ValidationError('No transaction was provided.'); } + return data; } catch (e) { throw new ValidationError('No transaction was provided.'); @@ -35,15 +40,37 @@ const getTransactionInput = async () => { }; export default class SignCommand extends BaseCommand { - async run() { + static args = [ + { + name: 'transaction', + description: 'Transaction to sign in JSON format.', + }, + ]; + + static description = ` + Sign a transaction using your secret passphrase. + `; + + static examples = [ + 'transaction:sign \'{"amount":"100","recipientId":"13356260975429434553L","senderPublicKey":null,"timestamp":52871598,"type":0,"fee":"10000000","recipientPublicKey":null,"asset":{}}\'', + ]; + + static flags = { + ...BaseCommand.flags, + passphrase: flagParser.string(commonFlags.passphrase), + 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), + }; + + async run(): Promise { const { - args: { transaction }, + args, flags: { passphrase: passphraseSource, 'second-passphrase': secondPassphraseSource, }, } = this.parse(SignCommand); + const { transaction }: Args = args; const transactionInput = transaction || (await getTransactionInput()); const transactionObject = parseTransactionString(transactionInput); @@ -58,7 +85,7 @@ export default class SignCommand extends BaseCommand { repeatPrompt: true, }, secondPassphrase: !secondPassphraseSource - ? null + ? undefined : { source: secondPassphraseSource, repeatPrompt: true, @@ -73,25 +100,4 @@ export default class SignCommand extends BaseCommand { this.print(result); } -} - -SignCommand.args = [ - { - name: 'transaction', - description: 'Transaction to sign in JSON format.', - }, -]; - -SignCommand.flags = { - ...BaseCommand.flags, - passphrase: flagParser.string(commonFlags.passphrase), - 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), -}; - -SignCommand.description = ` -Sign a transaction using your secret passphrase. -`; - -SignCommand.examples = [ - 'transaction:sign \'{"amount":"100","recipientId":"13356260975429434553L","senderPublicKey":null,"timestamp":52871598,"type":0,"fee":"10000000","recipientPublicKey":null,"asset":{}}\'', -]; +} \ No newline at end of file diff --git a/src/commands/transaction/verify.js b/src/commands/transaction/verify.ts similarity index 70% rename from src/commands/transaction/verify.js rename to src/commands/transaction/verify.ts index 6cc17c1b..3919333b 100644 --- a/src/commands/transaction/verify.js +++ b/src/commands/transaction/verify.ts @@ -16,9 +16,13 @@ import * as transactions from '@liskhq/lisk-transactions'; import { flags as flagParser } from '@oclif/command'; import BaseCommand from '../../base'; -import { parseTransactionString } from '../../utils/transactions'; -import { getStdIn, getData } from '../../utils/input/utils'; import { ValidationError } from '../../utils/error'; +import { getData, getStdIn } from '../../utils/input/utils'; +import { parseTransactionString } from '../../utils/transactions'; + +interface Args { + readonly transaction?: string; +} const secondPublicKeyDescription = `Specifies a source for providing a second public key to the command. The second public key must be provided via this option. Sources must be one of \`file\` or \`stdin\`. In the case of \`file\`, a corresponding identifier must also be provided. @@ -29,34 +33,60 @@ const secondPublicKeyDescription = `Specifies a source for providing a second pu - --second-public-key 790049f919979d5ea42cca7b7aa0812cbae8f0db3ee39c1fe3cef18e25b67951 `; -const getTransactionInput = async () => { +const getTransactionInput = async (): Promise => { try { const { data } = await getStdIn({ dataIsRequired: true }); if (!data) { throw new ValidationError('No transaction was provided.'); } + return data; } catch (e) { throw new ValidationError('No transaction was provided.'); } }; -const processSecondPublicKey = async secondPublicKey => +const processSecondPublicKey = async (secondPublicKey: string) => secondPublicKey.includes(':') ? getData(secondPublicKey) : secondPublicKey; export default class VerifyCommand extends BaseCommand { - async run() { + static args = [ + { + name: 'transaction', + description: 'Transaction to verify in JSON format.', + }, + ]; + + static description = ` + Verifies a transaction has a valid signature. + `; + + static examples = [ + 'transaction:verify \'{"type":0,"amount":"100",...}\'', + 'transaction:verify \'{"type":0,"amount":"100",...}\' --second-public-key=647aac1e2df8a5c870499d7ddc82236b1e10936977537a3844a6b05ea33f9ef6', + ]; + + static flags = { + ...BaseCommand.flags, + 'second-public-key': flagParser.string({ + name: 'Second public key', + description: secondPublicKeyDescription, + }), + }; + + async run(): Promise { const { - args: { transaction }, + args, flags: { 'second-public-key': secondPublicKeySource }, } = this.parse(VerifyCommand); - + + const { transaction }: Args = args; const transactionInput = transaction || (await getTransactionInput()); const transactionObject = parseTransactionString(transactionInput); const secondPublicKey = secondPublicKeySource ? await processSecondPublicKey(secondPublicKeySource) - : null; + : undefined; const verified = transactions.utils.verifyTransaction( transactionObject, @@ -64,28 +94,4 @@ export default class VerifyCommand extends BaseCommand { ); this.print({ verified }); } -} - -VerifyCommand.args = [ - { - name: 'transaction', - description: 'Transaction to verify in JSON format.', - }, -]; - -VerifyCommand.flags = { - ...BaseCommand.flags, - 'second-public-key': flagParser.string({ - name: 'Second public key', - description: secondPublicKeyDescription, - }), -}; - -VerifyCommand.description = ` -Verifies a transaction has a valid signature. -`; - -VerifyCommand.examples = [ - 'transaction:verify \'{"type":0,"amount":"100",...}\'', - 'transaction:verify \'{"type":0,"amount":"100",...}\' --second-public-key=647aac1e2df8a5c870499d7ddc82236b1e10936977537a3844a6b05ea33f9ef6', -]; +} \ No newline at end of file diff --git a/src/utils/flags.ts b/src/utils/flags.ts index 280fb764..77328b8d 100644 --- a/src/utils/flags.ts +++ b/src/utils/flags.ts @@ -65,7 +65,7 @@ const unvotesDescription = `Specifies the public keys for the delegate candidate const noSignatureDescription = 'Creates the transaction without a signature. Your passphrase will therefore not be required.'; -type AlphabetLowercase = +export type AlphabetLowercase = | 'a' | 'b' | 'c' From 507d70ffd64245be29bb6dcb52088770b4d6de19 Mon Sep 17 00:00:00 2001 From: Shusetsu Toda Date: Thu, 6 Dec 2018 17:57:19 +0100 Subject: [PATCH 2/2] :white_check_mark: Update transaction tests --- package.json | 2 +- src/commands/transaction/create.ts | 2 +- .../transaction/create/second-passphrase.ts | 47 ++++---- src/commands/transaction/create/transfer.ts | 103 ++++++++++-------- src/commands/transaction/get.ts | 24 ++-- .../{broadcast.test.js => broadcast.test.ts} | 20 ++-- .../{create.test.js => create.test.ts} | 6 +- .../{delegate.test.js => delegate.test.ts} | 30 ++--- ...gnature.test.js => multisignature.test.ts} | 30 ++--- ...rase.test.js => second-passphrase.test.ts} | 24 ++-- .../{transfer.test.js => transfer.test.ts} | 30 ++--- .../create/{vote.test.js => vote.test.ts} | 54 ++++----- .../transaction/{get.test.js => get.test.ts} | 58 +++++----- .../{sign.test.js => sign.test.ts} | 48 ++++---- .../{verify.test.js => verify.test.ts} | 20 ++-- 15 files changed, 260 insertions(+), 238 deletions(-) rename test/commands/transaction/{broadcast.test.js => broadcast.test.ts} (87%) rename test/commands/transaction/{create.test.js => create.test.ts} (96%) rename test/commands/transaction/create/{delegate.test.js => delegate.test.ts} (84%) rename test/commands/transaction/create/{multisignature.test.js => multisignature.test.ts} (90%) rename test/commands/transaction/create/{second-passphrase.test.js => second-passphrase.test.ts} (85%) rename test/commands/transaction/create/{transfer.test.js => transfer.test.ts} (87%) rename test/commands/transaction/create/{vote.test.js => vote.test.ts} (86%) rename test/commands/transaction/{get.test.js => get.test.ts} (86%) rename test/commands/transaction/{sign.test.js => sign.test.ts} (87%) rename test/commands/transaction/{verify.test.js => verify.test.ts} (93%) diff --git a/package.json b/package.json index 09a1e723..08c059c2 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "lint": "tslint --format codeFrame --project .", "lint:fix": "npm run lint -- --fix", "test": "if [ -z $JENKINS_HOME ]; then npm run test:local; else npm run test:ci; fi", - "test:local": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/,/**/**/}/*.ts", + "test:local": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/,/**/**/,/**/**/**/}/*.ts", "test:ci": "NODE_ENV=test nyc --exclude \"**/node_modules/** coverage/**\" mocha test", "test:watch": "npm run test:local -- --watch", "test:watch:min": "npm run test:watch -- --reporter=min", diff --git a/src/commands/transaction/create.ts b/src/commands/transaction/create.ts index 79c5645e..dcc7df02 100644 --- a/src/commands/transaction/create.ts +++ b/src/commands/transaction/create.ts @@ -37,7 +37,7 @@ const typeNumberMap: TypeNumberMap = { }; const options = Object.entries(typeNumberMap).reduce( - (accumulated: ReadonlyArray, [key, value]: [string, string]) => [...accumulated, key, value], + (accumulated: string[], [key, value]: [string, string]) => [...accumulated, key, value], [], ); diff --git a/src/commands/transaction/create/second-passphrase.ts b/src/commands/transaction/create/second-passphrase.ts index b9b25912..b615bee2 100644 --- a/src/commands/transaction/create/second-passphrase.ts +++ b/src/commands/transaction/create/second-passphrase.ts @@ -13,20 +13,40 @@ * Removal or modification of this copyright notice is prohibited. * */ +import { registerSecondPassphrase } from '@liskhq/lisk-transactions'; import { flags as flagParser } from '@oclif/command'; -import * as transactions from '@liskhq/lisk-transactions'; import BaseCommand from '../../../base'; +import { ValidationError } from '../../../utils/error'; import { flags as commonFlags } from '../../../utils/flags'; -import { getInputsFromSources } from '../../../utils/input'; +import { getInputsFromSources, InputFromSourceOutput } from '../../../utils/input'; -export const processInputs = () => ({ passphrase, secondPassphrase }) => - transactions.registerSecondPassphrase({ +export const processInputs = () => ({ passphrase, secondPassphrase }: InputFromSourceOutput) => { + if (!secondPassphrase) { + throw new ValidationError('No second passphrase was provided.'); + } + + return registerSecondPassphrase({ passphrase, secondPassphrase, }); +} + export default class SecondPassphraseCommand extends BaseCommand { - async run() { + static description = ` + Creates a transaction which will register a second passphrase for the account if broadcast to the network. + `; + + static examples = ['transaction:create:second-passphrase']; + + static flags = { + ...BaseCommand.flags, + passphrase: flagParser.string(commonFlags.passphrase), + 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), + 'no-signature': flagParser.boolean(commonFlags.noSignature), + }; + + async run(): Promise { const { flags: { passphrase: passphraseSource, @@ -39,7 +59,7 @@ export default class SecondPassphraseCommand extends BaseCommand { const inputs = noSignature ? await getInputsFromSources({ - passphrase: null, + passphrase: undefined, secondPassphrase: { source: secondPassphraseSource, repeatPrompt: true, @@ -58,17 +78,4 @@ export default class SecondPassphraseCommand extends BaseCommand { const result = processFunction(inputs); this.print(result); } -} - -SecondPassphraseCommand.flags = { - ...BaseCommand.flags, - passphrase: flagParser.string(commonFlags.passphrase), - 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), - 'no-signature': flagParser.boolean(commonFlags.noSignature), -}; - -SecondPassphraseCommand.description = ` -Creates a transaction which will register a second passphrase for the account if broadcast to the network. -`; - -SecondPassphraseCommand.examples = ['transaction:create:second-passphrase']; +} \ No newline at end of file diff --git a/src/commands/transaction/create/transfer.ts b/src/commands/transaction/create/transfer.ts index db392a87..f9f2c48b 100644 --- a/src/commands/transaction/create/transfer.ts +++ b/src/commands/transaction/create/transfer.ts @@ -13,25 +13,30 @@ * Removal or modification of this copyright notice is prohibited. * */ +import { transfer, utils as transactionUtils } from '@liskhq/lisk-transactions'; import { flags as flagParser } from '@oclif/command'; -import * as transactions from '@liskhq/lisk-transactions'; import BaseCommand from '../../../base'; -import { flags as commonFlags } from '../../../utils/flags'; -import { getInputsFromSources } from '../../../utils/input'; +import { AlphabetLowercase, flags as commonFlags } from '../../../utils/flags'; +import { getInputsFromSources, InputFromSourceOutput } from '../../../utils/input'; + +interface Args { + readonly address: string; + readonly amount: string; +} const dataFlag = { - char: 'd', + char: 'd' as AlphabetLowercase, description: `Optional UTF8 encoded data (maximum of 64 bytes) to include in the transaction asset. Examples: - --data=customInformation `, }; -const processInputs = (amount, address, data) => ({ +const processInputs = (amount: string, address: string, data?: string) => ({ passphrase, secondPassphrase, -}) => - transactions.transfer({ +}: InputFromSourceOutput) => + transfer({ recipientId: address, amount, data, @@ -40,9 +45,38 @@ const processInputs = (amount, address, data) => ({ }); export default class TransferCommand extends BaseCommand { - async run() { + static args = [ + { + name: 'amount', + required: true, + description: 'Amount of LSK to send.', + }, + { + name: 'address', + required: true, + description: 'Address of the recipient.', + }, + ]; + + static description = ` + Creates a transaction which will transfer the specified amount to an address if broadcast to the network. + `; + + static examples = [ + 'transaction:create:transfer 100 13356260975429434553L', + ]; + + static flags = { + ...BaseCommand.flags, + passphrase: flagParser.string(commonFlags.passphrase), + 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), + 'no-signature': flagParser.boolean(commonFlags.noSignature), + data: flagParser.string(dataFlag), + }; + + async run(): Promise { const { - args: { amount, address }, + args, flags: { passphrase: passphraseSource, 'second-passphrase': secondPassphraseSource, @@ -51,8 +85,10 @@ export default class TransferCommand extends BaseCommand { }, } = this.parse(TransferCommand); - transactions.utils.validateAddress(address); - const normalizedAmount = transactions.utils.convertLSKToBeddows(amount); + const { amount, address }: Args = args; + + transactionUtils.validateAddress(address); + const normalizedAmount = transactionUtils.convertLSKToBeddows(amount); const processFunction = processInputs( normalizedAmount, @@ -61,11 +97,13 @@ export default class TransferCommand extends BaseCommand { ); if (noSignature) { - const result = processFunction({ - passphrase: null, - secondPassphrase: null, + const noSignatureResult = processFunction({ + passphrase: undefined, + secondPassphrase: undefined, }); - return this.print(result); + this.print(noSignatureResult); + + return; } const inputs = await getInputsFromSources({ @@ -74,42 +112,13 @@ export default class TransferCommand extends BaseCommand { repeatPrompt: true, }, secondPassphrase: !secondPassphraseSource - ? null + ? undefined : { source: secondPassphraseSource, repeatPrompt: true, }, }); const result = processFunction(inputs); - return this.print(result); + this.print(result); } -} - -TransferCommand.args = [ - { - name: 'amount', - required: true, - description: 'Amount of LSK to send.', - }, - { - name: 'address', - required: true, - description: 'Address of the recipient.', - }, -]; - -TransferCommand.flags = { - ...BaseCommand.flags, - passphrase: flagParser.string(commonFlags.passphrase), - 'second-passphrase': flagParser.string(commonFlags.secondPassphrase), - 'no-signature': flagParser.boolean(commonFlags.noSignature), - data: flagParser.string(dataFlag), -}; - -TransferCommand.description = ` -Creates a transaction which will transfer the specified amount to an address if broadcast to the network. - `; - -TransferCommand.examples = [ - 'transaction:create:transfer 100 13356260975429434553L', -]; +} \ No newline at end of file diff --git a/src/commands/transaction/get.ts b/src/commands/transaction/get.ts index a4888d43..7108499e 100644 --- a/src/commands/transaction/get.ts +++ b/src/commands/transaction/get.ts @@ -107,8 +107,8 @@ export default class GetCommand extends BaseCommand { state: txnState, }, } = this.parse(GetCommand); - const { ids: idsStr = '' }: Args = args; - const ids = idsStr.split(',').filter(Boolean); + const { ids: idsStr }: Args = args; + const ids = idsStr ? idsStr.split(',').filter(Boolean) : undefined; const client = getAPIClient(this.userConfig.api); @@ -131,8 +131,9 @@ export default class GetCommand extends BaseCommand { txnState, reqTxnSenderId, ); + this.print(stateSenderIdsResult); - return this.print(stateSenderIdsResult); + return; } if (txnState && ids) { @@ -152,8 +153,9 @@ export default class GetCommand extends BaseCommand { txnState, reqTransactionIds, ); + this.print(txnStateIdsResult); - return this.print(txnStateIdsResult); + return; } if (txnState && senderAddress) { const reqWithSenderId = [ @@ -176,8 +178,9 @@ export default class GetCommand extends BaseCommand { txnState, reqWithSenderId, ); + this.print(txnStateSenderResult); - return this.print(txnStateSenderResult); + return; } if (txnState) { @@ -199,8 +202,9 @@ export default class GetCommand extends BaseCommand { txnState, reqByLimitOffset, ); + this.print(txnStateResult); - return this.print(txnStateResult); + return; } if (ids) { @@ -215,8 +219,9 @@ export default class GetCommand extends BaseCommand { }, })); const idsResult = await query(client, 'transactions', reqTransactionIDs); + this.print(idsResult); - return this.print(idsResult); + return; } if (senderAddress) { @@ -232,8 +237,9 @@ export default class GetCommand extends BaseCommand { }, }; const senderAddressResult = await query(client, 'transactions', reqSenderId); + this.print(senderAddressResult); - return this.print(senderAddressResult); + return; } const req = { @@ -248,6 +254,6 @@ export default class GetCommand extends BaseCommand { }; const defaultResults = await query(client, 'transactions', req); - return this.print(defaultResults); + this.print(defaultResults); } } \ No newline at end of file diff --git a/test/commands/transaction/broadcast.test.js b/test/commands/transaction/broadcast.test.ts similarity index 87% rename from test/commands/transaction/broadcast.test.js rename to test/commands/transaction/broadcast.test.ts index 7770a21b..bd455f28 100644 --- a/test/commands/transaction/broadcast.test.js +++ b/test/commands/transaction/broadcast.test.ts @@ -13,10 +13,10 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; +import { expect, test } from '@oclif/test'; import * as config from '../../../src/utils/config'; -import * as print from '../../../src/utils/print'; -import * as api from '../../../src/utils/api'; +import * as printUtils from '../../../src/utils/print'; +import * as apiUtils from '../../../src/utils/api'; import * as inputUtils from '../../../src/utils/input/utils'; describe('transaction:broadcast', () => { @@ -55,9 +55,9 @@ describe('transaction:broadcast', () => { }; const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({ api: apiConfig })) - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stdout(); describe('transaction:broadcast', () => { @@ -68,7 +68,7 @@ describe('transaction:broadcast', () => { sandbox.stub().rejects(new Error('Timeout error')), ) .command(['transaction:broadcast']) - .catch(error => { + .catch((error: Error) => { return expect(error.message).to.contain('No transaction was provided.'); }) .it('should throw an error without transaction'); @@ -77,7 +77,7 @@ describe('transaction:broadcast', () => { describe('transaction:broadcast transaction', () => { setupTest() .command(['transaction:broadcast', wrongTransaction]) - .catch(error => { + .catch((error: Error) => { return expect(error.message).to.contain( 'Could not parse transaction JSON.', ); @@ -87,7 +87,7 @@ describe('transaction:broadcast', () => { setupTest() .command(['transaction:broadcast', JSON.stringify(defaultTransaction)]) .it('should broadcast the transaction', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(apiClientStub.transactions.broadcast).to.be.calledWithExactly( defaultTransaction, ); @@ -101,7 +101,7 @@ describe('transaction:broadcast', () => { setupTest() .stub(inputUtils, 'getStdIn', sandbox.stub().resolves({})) .command(['transaction:broadcast']) - .catch(error => { + .catch((error: Error) => { return expect(error.message).to.contain('No transaction was provided.'); }) .it('should throw an error with invalid transaction from stdin'); @@ -128,7 +128,7 @@ describe('transaction:broadcast', () => { ) .command(['transaction:broadcast']) .it('should broadcast the transaction', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(apiClientStub.transactions.broadcast).to.be.calledWithExactly( defaultTransaction, ); diff --git a/test/commands/transaction/create.test.js b/test/commands/transaction/create.test.ts similarity index 96% rename from test/commands/transaction/create.test.js rename to test/commands/transaction/create.test.ts index c43e453d..6c00c220 100644 --- a/test/commands/transaction/create.test.js +++ b/test/commands/transaction/create.test.ts @@ -13,9 +13,9 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; +import { expect, test } from '@oclif/test'; import * as config from '../../../src/utils/config'; -import * as print from '../../../src/utils/print'; +import * as printUtils from '../../../src/utils/print'; import TransferCommand from '../../../src/commands/transaction/create/transfer'; import SecondPassphraseCommand from '../../../src/commands/transaction/create/second-passphrase'; import DelegateCommand from '../../../src/commands/transaction/create/delegate'; @@ -26,7 +26,7 @@ describe('transaction:create', () => { const printMethodStub = sandbox.stub(); const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub(TransferCommand, 'run', sandbox.stub()) .stub(SecondPassphraseCommand, 'run', sandbox.stub()) diff --git a/test/commands/transaction/create/delegate.test.js b/test/commands/transaction/create/delegate.test.ts similarity index 84% rename from test/commands/transaction/create/delegate.test.js rename to test/commands/transaction/create/delegate.test.ts index 50901778..3435f6f3 100644 --- a/test/commands/transaction/create/delegate.test.js +++ b/test/commands/transaction/create/delegate.test.ts @@ -13,11 +13,11 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; -import transactions from '@liskhq/lisk-transactions'; +import { expect, test } from '@oclif/test'; +import * as transactions from '@liskhq/lisk-transactions'; import * as config from '../../../../src/utils/config'; -import * as print from '../../../../src/utils/print'; -import * as getInputsFromSources from '../../../../src/utils/input'; +import * as printUtils from '../../../../src/utils/print'; +import * as inputUtils from '../../../../src/utils/input'; describe('transaction:create:delegate', () => { const defaultUsername = 'user-light'; @@ -40,7 +40,7 @@ describe('transaction:create:delegate', () => { const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub( transactions, @@ -48,8 +48,8 @@ describe('transaction:create:delegate', () => { sandbox.stub().returns(defaultTransaction), ) .stub( - getInputsFromSources, - 'default', + inputUtils, + 'getInputsFromSources', sandbox.stub().resolves(defaultInputs), ) .stdout(); @@ -67,12 +67,12 @@ describe('transaction:create:delegate', () => { setupTest() .command(['transaction:create:delegate', defaultUsername]) .it('create a transaction with the username', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactions.registerDelegate).to.be.calledWithExactly({ passphrase: defaultInputs.passphrase, @@ -95,12 +95,12 @@ describe('transaction:create:delegate', () => { .it( 'create a transaction with the username with the passphrase from flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactions.registerDelegate).to.be.calledWithExactly({ passphrase: defaultInputs.passphrase, @@ -125,7 +125,7 @@ describe('transaction:create:delegate', () => { .it( 'create a transaction with the username and the passphrase and second passphrase from the flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, @@ -156,11 +156,11 @@ describe('transaction:create:delegate', () => { ]) .it('create a transaction with the username without signature', () => { expect(transactions.registerDelegate).to.be.calledWithExactly({ - passphrase: null, - secondPassphrase: null, + passphrase: undefined, + secondPassphrase: undefined, username: defaultUsername, }); - expect(getInputsFromSources.default).not.to.be.called; + expect(inputUtils.getInputsFromSources).not.to.be.called; return expect(printMethodStub).to.be.calledWithExactly( defaultTransaction, ); diff --git a/test/commands/transaction/create/multisignature.test.js b/test/commands/transaction/create/multisignature.test.ts similarity index 90% rename from test/commands/transaction/create/multisignature.test.js rename to test/commands/transaction/create/multisignature.test.ts index 21add8bc..a047cba0 100644 --- a/test/commands/transaction/create/multisignature.test.js +++ b/test/commands/transaction/create/multisignature.test.ts @@ -13,11 +13,11 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; -import transactions from '@liskhq/lisk-transactions'; +import { expect, test } from '@oclif/test'; +import * as transactions from '@liskhq/lisk-transactions'; import * as config from '../../../../src/utils/config'; -import * as print from '../../../../src/utils/print'; -import * as getInputsFromSources from '../../../../src/utils/input'; +import * as printUtils from '../../../../src/utils/print'; +import * as inputUtils from '../../../../src/utils/input'; describe('transaction:create:multisignature', () => { const defaultLifetime = '24'; @@ -48,7 +48,7 @@ describe('transaction:create:multisignature', () => { const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub( transactions, @@ -57,8 +57,8 @@ describe('transaction:create:multisignature', () => { ) .stub(transactions, 'utils', transactionUtilStub) .stub( - getInputsFromSources, - 'default', + inputUtils, + 'getInputsFromSources', sandbox.stub().resolves(defaultInputs), ) .stdout(); @@ -132,12 +132,12 @@ describe('transaction:create:multisignature', () => { expect(transactionUtilStub.validatePublicKeys).to.be.calledWithExactly( defaultKeysgroup, ); - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactions.registerMultisignature).to.be.calledWithExactly({ passphrase: defaultInputs.passphrase, @@ -165,12 +165,12 @@ describe('transaction:create:multisignature', () => { expect(transactionUtilStub.validatePublicKeys).to.be.calledWithExactly( defaultKeysgroup, ); - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactions.registerMultisignature).to.be.calledWithExactly({ passphrase: defaultInputs.passphrase, @@ -201,7 +201,7 @@ describe('transaction:create:multisignature', () => { expect( transactionUtilStub.validatePublicKeys, ).to.be.calledWithExactly(defaultKeysgroup); - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, @@ -240,10 +240,10 @@ describe('transaction:create:multisignature', () => { expect( transactionUtilStub.validatePublicKeys, ).to.be.calledWithExactly(defaultKeysgroup); - expect(getInputsFromSources.default).not.to.be.called; + expect(inputUtils.getInputsFromSources).not.to.be.called; expect(transactions.registerMultisignature).to.be.calledWithExactly({ - passphrase: null, - secondPassphrase: null, + passphrase: undefined, + secondPassphrase: undefined, keysgroup: defaultKeysgroup, lifetime: parseInt(defaultLifetime, 10), minimum: parseInt(defaultMinimum, 10), diff --git a/test/commands/transaction/create/second-passphrase.test.js b/test/commands/transaction/create/second-passphrase.test.ts similarity index 85% rename from test/commands/transaction/create/second-passphrase.test.js rename to test/commands/transaction/create/second-passphrase.test.ts index 1eb2615b..683a97f5 100644 --- a/test/commands/transaction/create/second-passphrase.test.js +++ b/test/commands/transaction/create/second-passphrase.test.ts @@ -13,11 +13,11 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; -import transactions from '@liskhq/lisk-transactions'; +import { expect, test } from '@oclif/test'; +import * as transactions from '@liskhq/lisk-transactions'; import * as config from '../../../../src/utils/config'; -import * as print from '../../../../src/utils/print'; -import * as getInputsFromSources from '../../../../src/utils/input'; +import * as printUtils from '../../../../src/utils/print'; +import * as inputUtils from '../../../../src/utils/input'; describe('transaction:create:second-passphrase', () => { const defaultInputs = { @@ -39,7 +39,7 @@ describe('transaction:create:second-passphrase', () => { const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub( transactions, @@ -47,8 +47,8 @@ describe('transaction:create:second-passphrase', () => { sandbox.stub().returns(defaultTransaction), ) .stub( - getInputsFromSources, - 'default', + inputUtils, + 'getInputsFromSources', sandbox.stub().resolves(defaultInputs), ) .stdout(); @@ -57,7 +57,7 @@ describe('transaction:create:second-passphrase', () => { setupTest() .command(['transaction:create:second-passphrase']) .it('should create second passphrase transaction', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, @@ -85,7 +85,7 @@ describe('transaction:create:second-passphrase', () => { .it( 'should create second passphrase transaction with passphrase from flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, @@ -115,7 +115,7 @@ describe('transaction:create:second-passphrase', () => { .it( 'should create second passphrase transaction with passphrase and second passphrase from flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, @@ -141,8 +141,8 @@ describe('transaction:create:second-passphrase', () => { .it( 'should create second passphrase transaction withoug passphrase', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ - passphrase: null, + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ + passphrase: undefined, secondPassphrase: { source: undefined, repeatPrompt: true, diff --git a/test/commands/transaction/create/transfer.test.js b/test/commands/transaction/create/transfer.test.ts similarity index 87% rename from test/commands/transaction/create/transfer.test.js rename to test/commands/transaction/create/transfer.test.ts index 52fa3bf4..20b96d76 100644 --- a/test/commands/transaction/create/transfer.test.js +++ b/test/commands/transaction/create/transfer.test.ts @@ -13,11 +13,11 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; -import transactions from '@liskhq/lisk-transactions'; +import { expect, test } from '@oclif/test'; +import * as transactions from '@liskhq/lisk-transactions'; import * as config from '../../../../src/utils/config'; -import * as print from '../../../../src/utils/print'; -import * as getInputsFromSources from '../../../../src/utils/input'; +import * as printUtils from '../../../../src/utils/print'; +import * as inputUtils from '../../../../src/utils/input'; describe('transaction:create:transfer', () => { const defaultAmount = '1'; @@ -45,7 +45,7 @@ describe('transaction:create:transfer', () => { const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub( transactions, @@ -54,8 +54,8 @@ describe('transaction:create:transfer', () => { ) .stub(transactions, 'utils', transactionUtilStub) .stub( - getInputsFromSources, - 'default', + inputUtils, + 'getInputsFromSources', sandbox.stub().resolves(defaultInputs), ) .stdout(); @@ -88,12 +88,12 @@ describe('transaction:create:transfer', () => { expect(transactionUtilStub.convertLSKToBeddows).to.be.calledWithExactly( defaultAmount, ); - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); return expect(printMethodStub).to.be.calledWithExactly( defaultTransaction, @@ -116,12 +116,12 @@ describe('transaction:create:transfer', () => { expect(transactionUtilStub.convertLSKToBeddows).to.be.calledWithExactly( defaultAmount, ); - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); return expect(printMethodStub).to.be.calledWithExactly( defaultTransaction, @@ -144,7 +144,7 @@ describe('transaction:create:transfer', () => { expect(transactionUtilStub.convertLSKToBeddows).to.be.calledWithExactly( defaultAmount, ); - expect(getInputsFromSources.default).not.to.be.called; + expect(inputUtils.getInputsFromSources).not.to.be.called; return expect(printMethodStub).to.be.calledWithExactly( defaultTransaction, ); @@ -166,12 +166,12 @@ describe('transaction:create:transfer', () => { expect(transactionUtilStub.convertLSKToBeddows).to.be.calledWithExactly( defaultAmount, ); - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); return expect(printMethodStub).to.be.calledWithExactly( defaultTransaction, @@ -195,7 +195,7 @@ describe('transaction:create:transfer', () => { expect(transactionUtilStub.convertLSKToBeddows).to.be.calledWithExactly( defaultAmount, ); - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, diff --git a/test/commands/transaction/create/vote.test.js b/test/commands/transaction/create/vote.test.ts similarity index 86% rename from test/commands/transaction/create/vote.test.js rename to test/commands/transaction/create/vote.test.ts index dda07b97..0111f91e 100644 --- a/test/commands/transaction/create/vote.test.js +++ b/test/commands/transaction/create/vote.test.ts @@ -13,12 +13,12 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; -import transactions from '@liskhq/lisk-transactions'; +import { expect, test } from '@oclif/test'; +import * as transactions from '@liskhq/lisk-transactions'; import * as config from '../../../../src/utils/config'; -import * as print from '../../../../src/utils/print'; -import * as getInputsFromSources from '../../../../src/utils/input'; -import * as inputUtils from '../../../../src/utils/input/utils'; +import * as printUtils from '../../../../src/utils/print'; +import * as inputUtils from '../../../../src/utils/input'; +import * as inputModule from '../../../../src/utils/input/utils'; describe('transaction:create:vote', () => { const defaultVote = [ @@ -55,7 +55,7 @@ describe('transaction:create:vote', () => { const setupStub = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub( transactions, @@ -63,10 +63,10 @@ describe('transaction:create:vote', () => { sandbox.stub().returns(defaultTransaction), ) .stub(transactions, 'utils', transactionUtilStub) - .stub(inputUtils, 'getData', sandbox.stub().resolves(fileVotes.join(','))) + .stub(inputModule, 'getData', sandbox.stub().resolves(fileVotes.join(','))) .stub( - getInputsFromSources, - 'default', + inputUtils, + 'getInputsFromSources', sandbox.stub().resolves(defaultInputs), ) .stdout(); @@ -86,12 +86,12 @@ describe('transaction:create:vote', () => { setupStub() .command(['transaction:create:vote', `--votes=${defaultVote.join(',')}`]) .it('should create transaction with only votes', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactionUtilStub.validatePublicKeys).to.be.calledWithExactly( defaultVote, @@ -110,14 +110,14 @@ describe('transaction:create:vote', () => { setupStub() .command(['transaction:create:vote', '--votes=file:vote.txt']) .it('should create transaction with only votes from the file', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); - expect(inputUtils.getData).to.be.calledWithExactly('file:vote.txt'); + expect(inputModule.getData).to.be.calledWithExactly('file:vote.txt'); expect(transactionUtilStub.validatePublicKeys).to.be.calledWithExactly( fileVotes, ); @@ -140,12 +140,12 @@ describe('transaction:create:vote', () => { `--unvotes=${defaultUnvote.join(',')}`, ]) .it('should create transaction with only unvotes', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactionUtilStub.validatePublicKeys).to.be.calledWithExactly( defaultUnvote, @@ -164,14 +164,14 @@ describe('transaction:create:vote', () => { setupStub() .command(['transaction:create:vote', '--unvotes=file:unvote.txt']) .it('should create transaction with only unvotes from the file', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); - expect(inputUtils.getData).to.be.calledWithExactly('file:unvote.txt'); + expect(inputModule.getData).to.be.calledWithExactly('file:unvote.txt'); expect(transactionUtilStub.validatePublicKeys).to.be.calledWithExactly( fileVotes, ); @@ -208,12 +208,12 @@ describe('transaction:create:vote', () => { `--unvotes=${defaultUnvote.join(',')}`, ]) .it('should create a transaction with votes and unvotes', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactionUtilStub.validatePublicKeys).to.be.calledWithExactly( defaultVote, @@ -244,7 +244,7 @@ describe('transaction:create:vote', () => { .it( 'should create a transaction with votes and unvotes without signature', () => { - expect(getInputsFromSources.default).not.to.be.called; + expect(inputUtils.getInputsFromSources).not.to.be.called; expect( transactionUtilStub.validatePublicKeys, ).to.be.calledWithExactly(defaultVote); @@ -252,8 +252,8 @@ describe('transaction:create:vote', () => { transactionUtilStub.validatePublicKeys, ).to.be.calledWithExactly(defaultUnvote); expect(transactions.castVotes).to.be.calledWithExactly({ - passphrase: null, - secondPassphrase: null, + passphrase: undefined, + secondPassphrase: undefined, votes: defaultVote, unvotes: defaultUnvote, }); @@ -275,12 +275,12 @@ describe('transaction:create:vote', () => { .it( 'should create a transaction with votes and unvotes with the passphrase from the flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect( transactionUtilStub.validatePublicKeys, @@ -313,7 +313,7 @@ describe('transaction:create:vote', () => { .it( 'should create a transaction with votes and unvotes with the passphrase and second passphrase from the flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, diff --git a/test/commands/transaction/get.test.js b/test/commands/transaction/get.test.ts similarity index 86% rename from test/commands/transaction/get.test.js rename to test/commands/transaction/get.test.ts index 67ef9a39..38437bfe 100644 --- a/test/commands/transaction/get.test.js +++ b/test/commands/transaction/get.test.ts @@ -13,10 +13,10 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; +import { expect, test } from '@oclif/test'; import * as config from '../../../src/utils/config'; -import * as print from '../../../src/utils/print'; -import * as api from '../../../src/utils/api'; +import * as printUtils from '../../../src/utils/print'; +import * as apiUtils from '../../../src/utils/api'; import * as queryHandler from '../../../src/utils/query'; describe('transaction:get', () => { @@ -29,7 +29,7 @@ describe('transaction:get', () => { const apiClientStub = sandbox.stub(); const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({ api: apiConfig })) .stdout(); @@ -41,11 +41,11 @@ describe('transaction:get', () => { }; setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stub(queryHandler, 'query', sandbox.stub().resolves(queryResult)) .command(['transaction:get', transactionId]) .it('should get a transaction’s info and display as an array', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.query).to.be.calledWithExactly( apiClientStub, endpoint, @@ -87,11 +87,11 @@ describe('transaction:get', () => { ]; setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stub(queryHandler, 'query', sandbox.stub().resolves(queryResult)) .command(['transaction:get', transactionIds.join(',')]) .it('should get two transaction’s info and display as an array.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.query).to.be.calledWithExactly( apiClientStub, endpoint, @@ -122,13 +122,13 @@ describe('transaction:get', () => { }); setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stub(queryHandler, 'query', sandbox.stub().resolves(queryResult)) .command(['transaction:get', transactionIdsWithEmpty.join(',')]) .it( 'should get transaction’s info only using non-empty args and display as an array.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.query).to.be.calledWithExactly( apiClientStub, endpoint, @@ -161,11 +161,11 @@ describe('transaction:get', () => { describe('transaction:get --sender-id', () => { setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stub(queryHandler, 'query', sandbox.stub().resolves(queryResult)) .command(['transaction:get', '--sender-id=12668885769632475474L']) .it('should get all transactions for a given sender-id.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.query).to.be.calledWithExactly( apiClientStub, endpoint, @@ -187,11 +187,11 @@ describe('transaction:get', () => { describe('transaction: get --limit --offset', () => { setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stub(queryHandler, 'query', sandbox.stub().resolves(queryResult)) .command(['transaction:get', '--limit=10']) .it('should get all transactions info limited by limit value.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.query).to.be.calledWithExactly( apiClientStub, endpoint, @@ -210,13 +210,13 @@ describe('transaction:get', () => { }); setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stub(queryHandler, 'query', sandbox.stub().resolves(queryResult)) .command(['transaction:get']) .it( 'should get all transactions based on default value of limit(10) and offset(0).', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.query).to.be.calledWithExactly( apiClientStub, endpoint, @@ -236,7 +236,7 @@ describe('transaction:get', () => { ); setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStub)) .stub( queryHandler, 'query', @@ -246,7 +246,7 @@ describe('transaction:get', () => { .it( 'should return a message that no transactions found when there are no transactions after a given offset value.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.query).to.be.calledWithExactly( apiClientStub, endpoint, @@ -299,7 +299,7 @@ describe('transaction:get', () => { }; setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStubNode)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStubNode)) .command(['transaction:get', '--state=unsign', '--offset=1']) .catch(error => { return expect(error.message).to.contain( @@ -324,7 +324,7 @@ describe('transaction:get', () => { }; setupTest() - .stub(api, 'default', sandbox.stub().returns(localClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(localClientStub)) .stub( queryHandler, 'queryNodeTransaction', @@ -334,7 +334,7 @@ describe('transaction:get', () => { .it( 'should get an unprocessed transaction’s info by Id and display as an array.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.queryNodeTransaction).to.be.calledWithExactly( localClientStub.node, 'unprocessed', @@ -360,7 +360,7 @@ describe('transaction:get', () => { describe('transaction:get transactions --state=unprocessed', () => { setupTest() - .stub(api, 'default', sandbox.stub().returns(apiClientStubNode)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(apiClientStubNode)) .stub( queryHandler, 'queryNodeTransaction', @@ -374,7 +374,7 @@ describe('transaction:get', () => { .it( 'should get transaction’s info for given ids and unsigned state.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.queryNodeTransaction).to.be.calledWithExactly( apiClientStubNode.node, 'unsigned', @@ -426,7 +426,7 @@ describe('transaction:get', () => { }; setupTest() - .stub(api, 'default', sandbox.stub().returns(clientStubNode)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(clientStubNode)) .stub( queryHandler, 'queryNodeTransaction', @@ -440,7 +440,7 @@ describe('transaction:get', () => { .it( 'should get a transaction’s info for a given sender’s address and state and display as an array.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.queryNodeTransaction).to.be.calledWithExactly( clientStubNode.node, 'unprocessed', @@ -466,7 +466,7 @@ describe('transaction:get', () => { ); setupTest() - .stub(api, 'default', sandbox.stub().returns(clientStubNode)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(clientStubNode)) .stub( queryHandler, 'queryNodeTransaction', @@ -481,7 +481,7 @@ describe('transaction:get', () => { .it( 'should get a transaction’s info for a given txn Id, sender’s address and state and display as an array.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.queryNodeTransaction).to.be.calledWithExactly( clientStubNode.node, 'unprocessed', @@ -523,7 +523,7 @@ describe('transaction:get', () => { }; setupTest() - .stub(api, 'default', sandbox.stub().returns(localClientStub)) + .stub(apiUtils, 'getAPIClient', sandbox.stub().returns(localClientStub)) .stub( queryHandler, 'queryNodeTransaction', @@ -533,7 +533,7 @@ describe('transaction:get', () => { .it( 'should get transactions for a given state without specified txn id and limited by limit flag.', () => { - expect(api.default).to.be.calledWithExactly(apiConfig); + expect(apiUtils.getAPIClient).to.be.calledWithExactly(apiConfig); expect(queryHandler.queryNodeTransaction).to.be.calledWithExactly( localClientStub.node, 'unprocessed', diff --git a/test/commands/transaction/sign.test.js b/test/commands/transaction/sign.test.ts similarity index 87% rename from test/commands/transaction/sign.test.js rename to test/commands/transaction/sign.test.ts index 9e5abb52..c6858e3f 100644 --- a/test/commands/transaction/sign.test.js +++ b/test/commands/transaction/sign.test.ts @@ -13,12 +13,12 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; -import transactions from '@liskhq/lisk-transactions'; +import { expect, test } from '@oclif/test'; +import * as transactions from '@liskhq/lisk-transactions'; import * as config from '../../../src/utils/config'; -import * as print from '../../../src/utils/print'; -import * as inputUtils from '../../../src/utils/input/utils'; -import * as getInputsFromSources from '../../../src/utils/input'; +import * as printUtils from '../../../src/utils/print'; +import * as inputModule from '../../../src/utils/input/utils'; +import * as inputUtils from '../../../src/utils/input'; describe('transaction:sign', () => { const defaultTransaction = { @@ -50,12 +50,12 @@ describe('transaction:sign', () => { const printMethodStub = sandbox.stub(); const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub(transactions, 'utils', transactionUtilStub) .stub( - getInputsFromSources, - 'default', + inputUtils, + 'getInputsFromSources', sandbox.stub().resolves(defaultInputs), ) .stdout(); @@ -63,7 +63,7 @@ describe('transaction:sign', () => { describe('transaction:sign', () => { setupTest() .stub( - inputUtils, + inputModule, 'getStdIn', sandbox.stub().rejects(new Error('Timeout error')), ) @@ -99,12 +99,12 @@ describe('transaction:sign', () => { setupTest() .command(['transaction:sign', JSON.stringify(defaultTransaction)]) .it('should take transaction from arg to sign', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactionUtilStub.prepareTransaction).to.be.calledWithExactly( defaultTransaction, @@ -127,12 +127,12 @@ describe('transaction:sign', () => { .it( 'should take transaction from arg and passphrase from flag to sign', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect( transactionUtilStub.prepareTransaction, @@ -159,7 +159,7 @@ describe('transaction:sign', () => { .it( 'should take transaction from arg and passphrase and second passphrase from flag to sign', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, @@ -185,7 +185,7 @@ describe('transaction:sign', () => { describe('transaction | transaction:sign', () => { setupTest() - .stub(inputUtils, 'getStdIn', sandbox.stub().resolves({})) + .stub(inputModule, 'getStdIn', sandbox.stub().resolves({})) .command(['transaction:sign']) .catch(error => { return expect(error.message).to.contain('No transaction was provided.'); @@ -194,7 +194,7 @@ describe('transaction:sign', () => { setupTest() .stub( - inputUtils, + inputModule, 'getStdIn', sandbox.stub().resolves({ data: invalidTransaction }), ) @@ -208,18 +208,18 @@ describe('transaction:sign', () => { setupTest() .stub( - inputUtils, + inputModule, 'getStdIn', sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }), ) .command(['transaction:sign']) .it('should take transaction from stdin and sign', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: undefined, repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect(transactionUtilStub.prepareTransaction).to.be.calledWithExactly( defaultTransaction, @@ -235,7 +235,7 @@ describe('transaction:sign', () => { describe('transaction | transaction:sign --passphrase=pass:xxx', () => { setupTest() .stub( - inputUtils, + inputModule, 'getStdIn', sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }), ) @@ -243,12 +243,12 @@ describe('transaction:sign', () => { .it( 'should take transaction from stdin and sign with passphrase from flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:123', repeatPrompt: true, }, - secondPassphrase: null, + secondPassphrase: undefined, }); expect( transactionUtilStub.prepareTransaction, @@ -267,7 +267,7 @@ describe('transaction:sign', () => { describe('transaction | transaction:sign --passphrase=pass:xxx --second-passphrase=pass:xxx', () => { setupTest() .stub( - inputUtils, + inputModule, 'getStdIn', sandbox.stub().resolves({ data: JSON.stringify(defaultTransaction) }), ) @@ -279,7 +279,7 @@ describe('transaction:sign', () => { .it( 'should take transaction from stdin and sign with passphrase and second passphrase from flag', () => { - expect(getInputsFromSources.default).to.be.calledWithExactly({ + expect(inputUtils.getInputsFromSources).to.be.calledWithExactly({ passphrase: { source: 'pass:abc', repeatPrompt: true, diff --git a/test/commands/transaction/verify.test.js b/test/commands/transaction/verify.test.ts similarity index 93% rename from test/commands/transaction/verify.test.js rename to test/commands/transaction/verify.test.ts index 95c16284..871555e2 100644 --- a/test/commands/transaction/verify.test.js +++ b/test/commands/transaction/verify.test.ts @@ -13,10 +13,10 @@ * Removal or modification of this copyright notice is prohibited. * */ -import { test } from '@oclif/test'; -import transactions from '@liskhq/lisk-transactions'; +import { expect, test } from '@oclif/test'; +import * as transactions from '@liskhq/lisk-transactions'; import * as config from '../../../src/utils/config'; -import * as print from '../../../src/utils/print'; +import * as printUtils from '../../../src/utils/print'; import * as inputUtils from '../../../src/utils/input/utils'; describe('transaction:verify', () => { @@ -48,7 +48,7 @@ describe('transaction:verify', () => { }; const setupTest = () => test - .stub(print, 'default', sandbox.stub().returns(printMethodStub)) + .stub(printUtils, 'print', sandbox.stub().returns(printMethodStub)) .stub(config, 'getConfig', sandbox.stub().returns({})) .stub(transactions, 'utils', transactionUtilStub) .stub( @@ -66,7 +66,7 @@ describe('transaction:verify', () => { sandbox.stub().rejects(new Error('Timeout error')), ) .command(['transaction:verify']) - .catch(error => { + .catch((error: Error) => { return expect(error.message).to.contain('No transaction was provided.'); }) .it('should throw an error'); @@ -75,7 +75,7 @@ describe('transaction:verify', () => { describe('transaction:verify transaction', () => { setupTest() .command(['transaction:verify', invalidTransaction]) - .catch(error => { + .catch((error: Error) => { return expect(error.message).to.contain( 'Could not parse transaction JSON.', ); @@ -87,7 +87,7 @@ describe('transaction:verify', () => { .it('should verify transaction from arg', () => { expect(transactionUtilStub.verifyTransaction).to.be.calledWithExactly( defaultTransaction, - null, + undefined, ); return expect(printMethodStub).to.be.calledWithExactly( defaultVerifyTransactionResult, @@ -141,7 +141,7 @@ describe('transaction:verify', () => { setupTest() .stub(inputUtils, 'getStdIn', sandbox.stub().resolves({})) .command(['transaction:verify']) - .catch(error => { + .catch((error: Error) => { return expect(error.message).to.contain('No transaction was provided.'); }) .it('should throw an error when no stdin was provided'); @@ -153,7 +153,7 @@ describe('transaction:verify', () => { sandbox.stub().resolves({ data: invalidTransaction }), ) .command(['transaction:verify']) - .catch(error => { + .catch((error: Error) => { return expect(error.message).to.contain( 'Could not parse transaction JSON.', ); @@ -170,7 +170,7 @@ describe('transaction:verify', () => { .it('should verify transaction from stdin', () => { expect(transactionUtilStub.verifyTransaction).to.be.calledWithExactly( defaultTransaction, - null, + undefined, ); return expect(printMethodStub).to.be.calledWithExactly( defaultVerifyTransactionResult,