Skip to content

Commit

Permalink
Merge pull request #92 from AElfProject/feature/json
Browse files Browse the repository at this point in the history
feat: pass params through json
  • Loading branch information
hzz780 authored Aug 27, 2024
2 parents 52ca774 + 9b7faf8 commit 7bb708a
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 39 deletions.
54 changes: 44 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ _A CLI tools built for AElf_

## Features

- Get or Set common configs, `endpoint`, `account`, `datadir`, `password`, `csv`.
- Get or Set common configs, `endpoint`, `account`, `datadir`, `password`, `csv`, `json`.
- For new users who are not familiar with the CLI parameters, any missing parameters will be asked in a prompting way.
- Create a new `account`.
- Load an account from a given `private key` or `mnemonic`.
Expand Down Expand Up @@ -130,7 +130,7 @@ Welcome to aelf interactive console. Ctrl + C to terminate the program. Double t
║ NAME | DESCRIPTION ║
║ AElf | imported from aelf-sdk ║
║ aelf | the instance of an aelf-sdk, connect to ║
| http://13.231.179.27:8000
| https://tdvw-test-node.aelf.io
║ _account | the instance of an AElf wallet, address ║
| is ║
| 2Ue31YTuB5Szy7cnr3SCEGU2gtGi5uMQBYarYUR… ║
Expand All @@ -155,6 +155,7 @@ Options:
-p, --password <password> The password of encrypted keyStore
-d, --datadir <directory> The directory that contains the AElf related files. Defaults to {home}/.local/share/aelf
-c, --csv <csv> The location of the CSV file containing the parameters.
-j, --json <json> The location of the JSON file containing the parameters.
-h, --help output usage information

Commands:
Expand Down Expand Up @@ -216,7 +217,8 @@ aelf-command console
- `endpoint`: The endpoint for the RPC service.
- `account`: The account to be used to interact with the blockchain `endpoint`.
- `password`: The password for unlocking the given `account`.
- `csv>`: The location of the CSV file containing the parameters.
- `csv`: The location of the CSV file containing the parameters.
- `json`: The location of the JSON file containing the parameters.
You can specified options above in several ways, and the priority is in the order of low to high.
Expand Down Expand Up @@ -670,7 +672,7 @@ In each item:
```bash
$ aelf-command send
✔ Enter the the URI of an AElf node … http://13.231.179.27:8000
✔ Enter the the URI of an AElf node … https://tdvw-test-node.aelf.io
✔ Enter a valid wallet address, if you don't have, create one by aelf-command create … D3vSjRYL8MpeRpvUDy85ktXijnBe2tHn8NTACsggUVteQCNGP
✔ Enter the password you typed when creating a wallet … ********
✔ Enter contract name (System contracts only) or the address of contract … AElf.ContractNames.Token
Expand Down Expand Up @@ -708,7 +710,7 @@ aelf-command send AElf.ContractNames.Token Transfer '{"symbol": "ELF", "to": "C9
```bash
$ aelf-command call
✔ Enter the the URI of an AElf node … http://13.231.179.27:8000
✔ Enter the the URI of an AElf node … https://tdvw-test-node.aelf.io
✔ Enter a valid wallet address, if you don't have, create one by aelf-command create … D3vSjRYL8MpeRpvUDy85ktXijnBe2tHn8NTACsggUVteQCNGP
✔ Enter the password you typed when creating a wallet … ********
✔ Enter contract name (System contracts only) or the address of contract … AElf.ContractNames.Token
Expand Down Expand Up @@ -744,6 +746,38 @@ Result:
aelf-command call AElf.ContractNames.Token GetTokenInfo '{"symbol":"ELF"}'
```
#### Call a read-only method and pass params through CSV
```bash
$ aelf-command call -e https://tdvw-test-node.aelf.io/ -a GyQX6t18kpwaD9XHXe1ToKxfov8mSeTLE9q9NwUAeTE8tULZk -p 1234*Qwer -j ./test.csv AElf.ContractNames.Token GetBalance
✔ Fetching contract successfully!
✔ Calling method successfully!
AElf [Info]:
Result:
{
"symbol": "ELF",
"owner": "GyQX6t18kpwaD9XHXe1ToKxfov8mSeTLE9q9NwUAeTE8tULZk",
"balance": "155000"
}
✔ Succeed!
```
#### Call a read-only method and pass params through JSON
```bash
$ aelf-command call -e https://tdvw-test-node.aelf.io/ -a GyQX6t18kpwaD9XHXe1ToKxfov8mSeTLE9q9NwUAeTE8tULZk -p 1234*Qwer -j ./test.json AElf.ContractNames.Token GetBalance
✔ Fetching contract successfully!
✔ Calling method successfully!
AElf [Info]:
Result:
{
"symbol": "ELF",
"owner": "GyQX6t18kpwaD9XHXe1ToKxfov8mSeTLE9q9NwUAeTE8tULZk",
"balance": "155000"
}
✔ Succeed!
```
### get-chain-status - Get the current status of the block chain
```bash
Expand All @@ -770,7 +804,7 @@ $ aelf-command get-chain-status
```bash
$ aelf-command get-tx-result
✔ Enter the the URI of an AElf node … http://13.231.179.27:8000
✔ Enter the the URI of an AElf node … https://tdvw-test-node.aelf.io
✔ Enter a valid transaction id in hex format … 7b620a49ee9666c0c381fdb33f94bd31e1b5eb0fdffa081463c3954e9f734a02
✔ Succeed!
{ TransactionId:
Expand Down Expand Up @@ -800,7 +834,7 @@ $ aelf-command get-tx-result
```bash
$ aelf-command get-blk-height
✔ Enter the the URI of an AElf node … http://13.231.179.27:8000
✔ Enter the the URI of an AElf node … https://tdvw-test-node.aelf.io
> 7902091
```
Expand All @@ -810,7 +844,7 @@ You can pass a block height or a block hash to this sub-command.
```bash
$ aelf-command get-blk-info
✔ Enter the the URI of an AElf node: http://13.231.179.27:8000
✔ Enter the the URI of an AElf node: https://tdvw-test-node.aelf.io
✔ Enter a valid height or block hash: 123
✔ Include transactions whether or not: no / yes
{ BlockHash:
Expand Down Expand Up @@ -845,7 +879,7 @@ aelf-command get-blk-info ca61c7c8f5fc1bc8af0536bc9b51c61a94f39641a93a748e72802b
```bash
$ aelf-command console
✔ Enter the the URI of an AElf node … http://13.231.179.27:8000
✔ Enter the the URI of an AElf node … https://tdvw-test-node.aelf.io
✔ Enter a valid wallet address, if you don't have, create one by aelf-command create … 2Ue31YTuB5Szy7cnr3SCEGU2gtGi5uMQBYarYUR5oGin1sys6H
✔ Enter the password you typed when creating a wallet … ********
✔ Succeed!
Expand All @@ -856,7 +890,7 @@ Welcome to aelf interactive console. Ctrl + C to terminate the program. Double t
║ NAME | DESCRIPTION ║
║ AElf | imported from aelf-sdk ║
║ aelf | instance of aelf-sdk, connect to ║
| http://13.231.179.27:8000
| https://tdvw-test-node.aelf.io
║ _account | instance of AElf wallet, wallet address ║
| is ║
| 2Ue31YTuB5Szy7cnr3SCEGU2gtGi5uMQBYarYUR… ║
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aelf-command",
"version": "0.1.49-beta.0",
"version": "0.1.50-beta.0",
"description": "A CLI tools for AElf",
"main": "src/index.js",
"type": "module",
Expand Down
12 changes: 6 additions & 6 deletions src/command/call.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import AElf from 'aelf-sdk';
import inquirer from 'inquirer';
import chalk from 'chalk';
import { createReadStream } from 'fs';
import csv from 'csv-parser';
import BaseSubCommand from './baseSubCommand.js';
import { callCommandUsages, callCommandParameters } from '../utils/constants.js';
import {
Expand All @@ -12,7 +10,8 @@ import {
promptTolerateSeveralTimes,
getParams,
parseJSON,
parseCSV
parseCSV,
parseJSONFile
} from '../utils/utils.js';
import { getWallet } from '../utils/wallet.js';
import { logger } from '../utils/myLogger.js';
Expand Down Expand Up @@ -91,7 +90,7 @@ class CallCommand extends BaseSubCommand {
// @ts-ignore
const { options, subOptions } = await super.run(commander, ...args);
const subOptionsLength = Object.keys(subOptions).length;
const { endpoint, datadir, account, password, csv } = options;
const { endpoint, datadir, account, password, csv, json } = options;
const aelf = new AElf(new AElf.providers.HttpProvider(endpoint));
try {
let { contractAddress, method, params } = subOptions;
Expand Down Expand Up @@ -127,8 +126,9 @@ class CallCommand extends BaseSubCommand {
contractAddress = await getContractInstance(contractAddress, aelf, wallet, this.oraInstance);
method = getMethod(method, contractAddress);
if (csv) {
const csvParams = await parseCSV(csv);
params = csvParams;
params = await parseCSV(csv);
} else if (json) {
params = await parseJSONFile(json);
} else {
params = await getParams(method);
params = typeof params === 'string' ? params : BaseSubCommand.normalizeConfig(params);
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ function init(options) {
`The directory that contains the AElf related files. Default to be ${userHomeDir}/aelf`
);
commander.option('-c, --csv <csv>', 'The location of the CSV file containing the parameters.');
commander.option('-j, --json <json>', 'The location of the JSON file containing the parameters.');
const rc = new RC();
Object.values(commands).forEach(Value => {
const command = new Value(rc);
Expand Down
5 changes: 5 additions & 0 deletions src/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,11 @@ const commonGlobalOptionValidatorDesc = {
type: 'string',
required: false,
message: 'set params in csv file by -c <csv>'
},
json: {
type: 'string',
required: false,
message: 'set params in csv file by -j <json>'
}
};

Expand Down
14 changes: 13 additions & 1 deletion src/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,17 @@ const parseCSV = async address => {
return results;
};

const parseJSONFile = async address => {
try {
const absolutePath = path.resolve(address);
const data = await fs.readFileSync(absolutePath);
const jsonObject = JSON.parse(data.toString('utf8'));
return jsonObject;
} catch (error) {
throw new Error(`An error occurred while reading or parsing the JSON file: ${error.message}`);
}
};

export {
promisify,
camelCase,
Expand All @@ -494,5 +505,6 @@ export {
randomId,
getParams,
deserializeLogs,
parseCSV
parseCSV,
parseJSONFile
};
22 changes: 21 additions & 1 deletion test/command/call.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { callCommandUsages, callCommandParameters } from '../../src/utils/consta
import { getContractInstance } from '../../src/utils/utils.js';
import { userHomeDir } from '../../src/utils/userHomeDir.js';
import { logger } from '../../src/utils/myLogger.js';
import { endpoint as endPoint, account, password, dataDir, csvDir } from '../constants.js';
import { endpoint as endPoint, account, password, dataDir, csvDir, jsonDir } from '../constants.js';

const sampleRc = { getConfigs: jest.fn() };
jest.mock('../../src/utils/myLogger');
Expand Down Expand Up @@ -122,6 +122,26 @@ describe('CallCommand', () => {
expect(logger.info).toHaveBeenCalled();
});

test('should run with json', async () => {
inquirer.prompt = questions =>
Promise.resolve({
symbol: 'ELF',
owner: 'GyQX6t18kpwaD9XHXe1ToKxfov8mSeTLE9q9NwUAeTE8tULZk'
});
const commander = new Command();
commander.option('-e, --endpoint <URI>', 'The URI of an AElf node. Eg: http://127.0.0.1:8000');
commander.option('-a, --account <account>', 'The address of AElf wallet');
commander.option('-p, --password <password>', 'The password of encrypted keyStore');
commander.option(
'-d, --datadir <directory>',
`The directory that contains the AElf related files. Default to be ${userHomeDir}/aelf`
);
commander.option('-j, --json <json>', 'The location of the JSON file containing the parameters.');
commander.parse([process.argv[0], '', 'call', '-e', endPoint, '-a', account, '-p', password, '-d', dataDir, '-j', jsonDir]);
await callCommand.run(commander, 'AElf.ContractNames.Token', 'GetBalance');
expect(logger.info).toHaveBeenCalled();
});

test('should run with invalid parameters', async () => {
inquirer.prompt = backup;
callCommand = new CallCommand(sampleRc, 'call', 'Call a read-only method on a contract.', [
Expand Down
1 change: 1 addition & 0 deletions test/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export const account = 'GyQX6t18kpwaD9XHXe1ToKxfov8mSeTLE9q9NwUAeTE8tULZk';
export const password = '1234*Qwer';
export const dataDir = path.resolve(__dirname, './dataDir/aelf');
export const csvDir = path.resolve(__dirname, './test.csv');
export const jsonDir = path.resolve(__dirname, './test.json');
4 changes: 4 additions & 0 deletions test/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"symbol": "ELF",
"owner": "GyQX6t18kpwaD9XHXe1ToKxfov8mSeTLE9q9NwUAeTE8tULZk"
}
30 changes: 10 additions & 20 deletions types/utils/constants.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,32 @@ export interface CallCommandParameter {
}
export const callCommandParameters: CallCommandParameter[];

export interface PasswordValidatorDesc {
interface BaseValidatorDesc {
type: string;
required: boolean;
message: string;
}
export interface PasswordValidatorDesc extends BaseValidatorDesc {
validator(rule: any, value: any): boolean;
}

export interface EndpointValidatorDesc {
type: string;
required: boolean;
export interface EndpointValidatorDesc extends BaseValidatorDesc {
pattern: RegExp;
message: string;
}

export interface DatadirValidatorDesc {
type: string;
required: boolean;
message: string;
}
export interface DatadirValidatorDesc extends BaseValidatorDesc {}

export interface AccountValidatorDesc {
type: string;
required: boolean;
message: string;
}
export interface CSVValidatorDesc {
type: string;
required: boolean;
message: string;
}
export interface AccountValidatorDesc extends BaseValidatorDesc {}
export interface CSVValidatorDesc extends BaseValidatorDesc {}

export interface JSONValidatorDesc extends BaseValidatorDesc {}
export interface CommonGlobalOptionValidatorDesc {
password: PasswordValidatorDesc;
endpoint: EndpointValidatorDesc;
datadir: DatadirValidatorDesc;
account: AccountValidatorDesc;
csv: CSVValidatorDesc;
json: JSONValidatorDesc;
}
export const commonGlobalOptionValidatorDesc: CommonGlobalOptionValidatorDesc;

Expand Down

0 comments on commit 7bb708a

Please sign in to comment.