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

Update transaction commands to TypeScript #681

Merged
merged 2 commits into from
Dec 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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