Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Commit

Permalink
Merge pull request #681 from LiskHQ/662-update_transaction_cmd_ts
Browse files Browse the repository at this point in the history
Update transaction commands to TypeScript
  • Loading branch information
shuse2 authored Dec 14, 2018
2 parents 493d93a + 507d70f commit 78ade71
Show file tree
Hide file tree
Showing 23 changed files with 683 additions and 609 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,48 @@
*
*/
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<string> => {
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.');
}
};

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<void> {
const { args: { transaction } } = this.parse(BroadcastCommand);
const transactionInput = transaction || (await getTransactionInput());
const transactionObject = parseTransactionString(transactionInput);
Expand All @@ -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',
];
Original file line number Diff line number Diff line change
Expand Up @@ -16,48 +16,85 @@
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: string[], [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,
delegate: DelegateCommand,
multisignature: MultisignatureCommand,
};

const resolveFlags = (accumulated, [key, value]) => {
const resolveFlags = (accumulated: ReadonlyArray<string>, [key, value]: [string, string | boolean | undefined]) => {
if (key === 'type') {
return accumulated;
}
if (typeof value === 'string') {
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<void> {
const { argv, flags } = this.parse(CreateCommand);
const { type } = flags;
const commandType = Object.keys(typeNumberMap).includes(type)
Expand All @@ -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',
];
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,66 @@
* 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<void> {
const {
args: { username },
args,
flags: {
passphrase: passphraseSource,
'second-passphrase': secondPassphraseSource,
'no-signature': noSignature,
},
} = 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({
Expand All @@ -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'];
}
Loading

0 comments on commit 78ade71

Please sign in to comment.