From 901431d8c2b41731507e78e8ba26be58da532a0b Mon Sep 17 00:00:00 2001 From: Rishin Date: Mon, 5 Oct 2020 16:09:23 -0400 Subject: [PATCH 1/5] Add --view flag --- README.md | 2 +- oclif.manifest.json | 1 + src/commands/config.ts | 78 +++++++++++++++++--------------------- src/utils/defaultConfig.ts | 2 +- 4 files changed, 37 insertions(+), 46 deletions(-) create mode 100644 oclif.manifest.json diff --git a/README.md b/README.md index e46a81c..a22537c 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ $ npm install -g defi $ defi COMMAND running command... $ defi (-v|--version|version) -defi/0.0.1 linux-x64 node-v12.16.3 +defi/0.0.1 linux-x64 node-v10.22.0 $ defi --help [COMMAND] USAGE $ defi COMMAND diff --git a/oclif.manifest.json b/oclif.manifest.json new file mode 100644 index 0000000..6aacc35 --- /dev/null +++ b/oclif.manifest.json @@ -0,0 +1 @@ +{"version":"0.0.1","commands":{"chainlink":{"id":"chainlink","description":"Chainlink CLI","pluginName":"defi","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"name":{"name":"name","type":"option","char":"n","description":"name to print"},"force":{"name":"force","type":"boolean","char":"f","allowNo":false}},"args":[{"name":"file"}]},"config":{"id":"config","description":"Configure DeFi CLI","pluginName":"defi","pluginType":"core","aliases":[],"examples":["$ defi config session set","$ defi config accounts view","$ defi config uniswap view"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"default":{"name":"default","type":"boolean","description":"set default config","allowNo":false},"all":{"name":"all","type":"boolean","description":"view full config","allowNo":false}},"args":[{"name":"item","required":true,"options":["session","networks","accounts","chainlink","uniswap","tokens","all","path"]},{"name":"subcommand","required":true,"options":["view","set"]}]},"eth":{"id":"eth","description":"Send and View Eth balance","pluginName":"defi","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"subcommand","required":true,"options":["balance","send"]}]},"hello":{"id":"hello","description":"describe the command here","pluginName":"defi","pluginType":"core","aliases":[],"examples":["$ defi hello\nhello world from ./src/hello.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"name":{"name":"name","type":"option","char":"n","description":"name to print"},"force":{"name":"force","type":"boolean","char":"f","allowNo":false}},"args":[{"name":"file"}]},"tokens":{"id":"tokens","description":"Interact with ERC20 Tokens","pluginName":"defi","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"token","required":true},{"name":"subcommand","required":true,"options":["balance","send"]}]},"uniswap":{"id":"uniswap","description":"Uniswap CLI","pluginName":"defi","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"name":{"name":"name","type":"option","char":"n","description":"name to print"},"force":{"name":"force","type":"boolean","char":"f","allowNo":false}},"args":[{"name":"file"}]}}} \ No newline at end of file diff --git a/src/commands/config.ts b/src/commands/config.ts index 7a8c0bf..a0bd1b4 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -22,38 +22,35 @@ export default class Config extends Command { static description = 'Configure DeFi CLI' static examples = [ - '$ defi config session set', - '$ defi config accounts view', - '$ defi config uniswap view', + '$ defi config session', + '$ defi config accounts', + '$ defi config networks', ] static flags: any = { + //--help flag help: flags.help({ char: 'h' }), + //--view flag + view: flags.boolean({ char: 'v', description: "logs current status in config"}, ), default: flags.boolean({ description: 'set default config' }), - all: flags.boolean({ description: 'view full config' }) - } + all: flags.boolean({description: 'view full config' }) + } static args = [{ name: 'item', - required: true, - options: ['session', 'networks', 'accounts', 'chainlink', 'uniswap', 'tokens', 'all', 'path'], - }, - { name: 'subcommand', required: true, options: ["view", "set"] } - ] + options: ['session', 'networks', 'accounts', 'chainlink', 'uniswap', 'tokens', 'all', 'path'] + }] async run() { const { args, flags }: any = this.parse(Config) const config = await credentials(this) - try { if (args.item === 'path') { const configPath = join(this.config.configDir, 'config.json') this.log(configPath) } else if (args.item === 'session') { - if (args.subcommand === 'view') { - this.log(config.session) - } else if (args.subcommand === 'set') { - const answers = await inquirer + if(flags.view) { console.log(config.session) } + else { const answers = await inquirer .prompt([{ type: 'list', name: 'networkId', @@ -74,17 +71,13 @@ export default class Config extends Command { config.session = answers await setCredentials(this, config) this.log('Session configured.') - } } else if (args.item === 'networks') { - const networks = config.networks - const networkNames = Object.values(networks).map((n: any) => n.name) - if (args.subcommand === 'view') { - this.log(config.networks) - - } else if (args.subcommand === 'set') { - const answers = await inquirer + const networks = config.networks + const networkNames = Object.values(networks).map((n: any) => n.name) + if (flags.view) { console.log(config.networks) } + else { const answers = await inquirer .prompt([ { type: 'list', @@ -144,19 +137,8 @@ export default class Config extends Command { } } else if (args.item === 'accounts') { const accounts = config.accounts - if (args.subcommand === 'view') { - if (flags.all) { - this.log(accounts) - } else { - const addressesByNetwork: any = {} - Object.entries(accounts).forEach(([networkId, networkAccounts]: [any, any]) => { - addressesByNetwork[networkId] = Object.keys(networkAccounts) - }) - this.log(addressesByNetwork) - } - - } else if (args.subcommand === 'set') { - + if (flags.view) { this.log(config.accounts) } + else { const networks = Object.values(config.networks).map((network: any) => { return { name: `${network.networkId} (${network.name})`, @@ -252,21 +234,29 @@ export default class Config extends Command { } else if (args.item === 'uniswap') { } else if (args.item === 'tokens') { - + const answers = await inquirer + .prompt([{ + type: 'list', + name: 'NetworkId', + message: 'Select networkId:', + choices: Object.keys(config.networks), + default: config.session.networkId + }, + { + type: 'input', + name: 'Address', + message: 'Enter Address:', + }, } else if (args.item === 'all') { - if (args.subcommand === 'view') { - this.log(config) - } else if (args.subcommand === 'set') { - - if (flags.default) { + if (flags.view) { console.log(config)} + else if (flags.default) { await setCredentials(this, defaultConfig) this.log('Default config set.') } else { throw new Error('configure all Unimplemented!') } - - } } + } catch (error) { this.error(error || 'A DeFi CLI error has occurred.', { diff --git a/src/utils/defaultConfig.ts b/src/utils/defaultConfig.ts index 38562e8..9d57d56 100644 --- a/src/utils/defaultConfig.ts +++ b/src/utils/defaultConfig.ts @@ -26,7 +26,7 @@ export interface Config { }, chainlink: any, uniswap: any, - accounts: any + accounts: any, } const defaultConfig: Config = { From 43694e96d013efc14b5cb0f204adc3e4a1f7cb5e Mon Sep 17 00:00:00 2001 From: Rishin Date: Fri, 9 Oct 2020 12:20:35 -0400 Subject: [PATCH 2/5] Configurated tokens Config --- build/contracts/Migrations.json | 886 ++++++++++++++++++++++++++++++ contracts/Migrations.sol | 19 + migrations/1_initial_migration.js | 5 + package-lock.json | 17 + package.json | 1 + src/commands/config.ts | 36 +- src/commands/tokens.ts | 26 +- test/.gitkeep | 0 test/commands/chainlink.test.ts | 17 - test/commands/config.test.ts | 17 - test/commands/eth.test.ts | 17 - test/commands/hello.test.ts | 17 - test/commands/tokens.test.ts | 17 - test/commands/uniswap.test.ts | 17 - test/mocha.opts | 5 - test/tsconfig.json | 9 - truffle-config.js | 96 ++++ 17 files changed, 1076 insertions(+), 126 deletions(-) create mode 100644 build/contracts/Migrations.json create mode 100644 contracts/Migrations.sol create mode 100644 migrations/1_initial_migration.js create mode 100644 test/.gitkeep delete mode 100644 test/commands/chainlink.test.ts delete mode 100644 test/commands/config.test.ts delete mode 100644 test/commands/eth.test.ts delete mode 100644 test/commands/hello.test.ts delete mode 100644 test/commands/tokens.test.ts delete mode 100644 test/commands/uniswap.test.ts delete mode 100644 test/mocha.opts delete mode 100644 test/tsconfig.json create mode 100644 truffle-config.js diff --git a/build/contracts/Migrations.json b/build/contracts/Migrations.json new file mode 100644 index 0000000..8a74933 --- /dev/null +++ b/build/contracts/Migrations.json @@ -0,0 +1,886 @@ +{ + "contractName": "Migrations", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "last_completed_migration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "completed", + "type": "uint256" + } + ], + "name": "setCompleted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "metadata": "{\"compiler\":{\"version\":\"0.5.16+commit.9c3226ce\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"last_completed_migration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"completed\",\"type\":\"uint256\"}],\"name\":\"setCompleted\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"/mnt/c/Users/rishi/OneDrive/Code/VulcanLink/defi-cli/contracts/Migrations.sol\":\"Migrations\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"/mnt/c/Users/rishi/OneDrive/Code/VulcanLink/defi-cli/contracts/Migrations.sol\":{\"keccak256\":\"0x7797e159bfd6b953422b4bd6d5de5946971d8b5ed74c4b1f6517d61fe236b851\",\"urls\":[\"bzz-raw://56bdf6130f3ced3e78baa0f3e7f34cb4c5131d90721326056bbf0dd202d8539d\",\"dweb:/ipfs/QmZqRKebKwn6YXejnnPribsyiXLmrAx32JpatFhvS76NKp\"]}},\"version\":1}", + "bytecode": "0x6080604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561005057600080fd5b5061021e806100606000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806101b76033913960400191505060405180910390fd5b806001819055505056fe546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572a265627a7a72315820b5359f89c72d653a124f5ab0be54cacb7095215568b4656202109a79833bc68764736f6c63430005100032", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806101b76033913960400191505060405180910390fd5b806001819055505056fe546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572a265627a7a72315820b5359f89c72d653a124f5ab0be54cacb7095215568b4656202109a79833bc68764736f6c63430005100032", + "sourceMap": "66:352:0:-;;;113:10;90:33;;;;;;;;;;;;;;;;;;;;66:352;8:9:-1;5:2;;;30:1;27;20:12;5:2;66:352:0;;;;;;;", + "deployedSourceMap": "66:352:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66:352:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;127:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;313:103;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;313:103:0;;;;;;;;;;;;;;;;;:::i;:::-;;127:36;;;;:::o;90:33::-;;;;;;;;;;;;;:::o;313:103::-;225:5;;;;;;;;;;;211:19;;:10;:19;;;196:101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;402:9;375:24;:36;;;;313:103;:::o", + "source": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.8.0;\n\ncontract Migrations {\n address public owner = msg.sender;\n uint public last_completed_migration;\n\n modifier restricted() {\n require(\n msg.sender == owner,\n \"This function is restricted to the contract's owner\"\n );\n _;\n }\n\n function setCompleted(uint completed) public restricted {\n last_completed_migration = completed;\n }\n}\n", + "sourcePath": "/mnt/c/Users/rishi/OneDrive/Code/VulcanLink/defi-cli/contracts/Migrations.sol", + "ast": { + "absolutePath": "/mnt/c/Users/rishi/OneDrive/Code/VulcanLink/defi-cli/contracts/Migrations.sol", + "exportedSymbols": { + "Migrations": [ + 32 + ] + }, + "id": 33, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.4", + ".22", + "<", + "0.8", + ".0" + ], + "nodeType": "PragmaDirective", + "src": "32:32:0" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 32, + "linearizedBaseContracts": [ + 32 + ], + "name": "Migrations", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "id": 5, + "name": "owner", + "nodeType": "VariableDeclaration", + "scope": 32, + "src": "90:33:0", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "90:7:0", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 3, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 47, + "src": "113:3:0", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 4, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "113:10:0", + "typeDescriptions": { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "visibility": "public" + }, + { + "constant": false, + "id": 7, + "name": "last_completed_migration", + "nodeType": "VariableDeclaration", + "scope": 32, + "src": "127:36:0", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 6, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "127:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 18, + "nodeType": "Block", + "src": "190:119:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 13, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 10, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 47, + "src": "211:3:0", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 11, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "211:10:0", + "typeDescriptions": { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 12, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "225:5:0", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "211:19:0", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572", + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "238:53:0", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1", + "typeString": "literal_string \"This function is restricted to the contract's owner\"" + }, + "value": "This function is restricted to the contract's owner" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1", + "typeString": "literal_string \"This function is restricted to the contract's owner\"" + } + ], + "id": 9, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 50, + 51 + ], + "referencedDeclaration": 51, + "src": "196:7:0", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 15, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "196:101:0", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 16, + "nodeType": "ExpressionStatement", + "src": "196:101:0" + }, + { + "id": 17, + "nodeType": "PlaceholderStatement", + "src": "303:1:0" + } + ] + }, + "documentation": null, + "id": 19, + "name": "restricted", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "187:2:0" + }, + "src": "168:141:0", + "visibility": "internal" + }, + { + "body": { + "id": 30, + "nodeType": "Block", + "src": "369:47:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 28, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 26, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7, + "src": "375:24:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 27, + "name": "completed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21, + "src": "402:9:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "375:36:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 29, + "nodeType": "ExpressionStatement", + "src": "375:36:0" + } + ] + }, + "documentation": null, + "id": 31, + "implemented": true, + "kind": "function", + "modifiers": [ + { + "arguments": null, + "id": 24, + "modifierName": { + "argumentTypes": null, + "id": 23, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 19, + "src": "358:10:0", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "358:10:0" + } + ], + "name": "setCompleted", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21, + "name": "completed", + "nodeType": "VariableDeclaration", + "scope": 31, + "src": "335:14:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "335:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "334:16:0" + }, + "returnParameters": { + "id": 25, + "nodeType": "ParameterList", + "parameters": [], + "src": "369:0:0" + }, + "scope": 32, + "src": "313:103:0", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 33, + "src": "66:352:0" + } + ], + "src": "32:387:0" + }, + "legacyAST": { + "absolutePath": "/mnt/c/Users/rishi/OneDrive/Code/VulcanLink/defi-cli/contracts/Migrations.sol", + "exportedSymbols": { + "Migrations": [ + 32 + ] + }, + "id": 33, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.4", + ".22", + "<", + "0.8", + ".0" + ], + "nodeType": "PragmaDirective", + "src": "32:32:0" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 32, + "linearizedBaseContracts": [ + 32 + ], + "name": "Migrations", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "id": 5, + "name": "owner", + "nodeType": "VariableDeclaration", + "scope": 32, + "src": "90:33:0", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "90:7:0", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 3, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 47, + "src": "113:3:0", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 4, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "113:10:0", + "typeDescriptions": { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "visibility": "public" + }, + { + "constant": false, + "id": 7, + "name": "last_completed_migration", + "nodeType": "VariableDeclaration", + "scope": 32, + "src": "127:36:0", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 6, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "127:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 18, + "nodeType": "Block", + "src": "190:119:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 13, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 10, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 47, + "src": "211:3:0", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 11, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "211:10:0", + "typeDescriptions": { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 12, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "225:5:0", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "211:19:0", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "argumentTypes": null, + "hexValue": "546869732066756e6374696f6e206973207265737472696374656420746f2074686520636f6e74726163742773206f776e6572", + "id": 14, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "238:53:0", + "subdenomination": null, + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1", + "typeString": "literal_string \"This function is restricted to the contract's owner\"" + }, + "value": "This function is restricted to the contract's owner" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_stringliteral_f60fe2d9d123295bf92ecf95167f1fa709e374da35e4c083bd39dc2d82acd8b1", + "typeString": "literal_string \"This function is restricted to the contract's owner\"" + } + ], + "id": 9, + "name": "require", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 50, + 51 + ], + "referencedDeclaration": 51, + "src": "196:7:0", + "typeDescriptions": { + "typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$", + "typeString": "function (bool,string memory) pure" + } + }, + "id": 15, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "196:101:0", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 16, + "nodeType": "ExpressionStatement", + "src": "196:101:0" + }, + { + "id": 17, + "nodeType": "PlaceholderStatement", + "src": "303:1:0" + } + ] + }, + "documentation": null, + "id": 19, + "name": "restricted", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "187:2:0" + }, + "src": "168:141:0", + "visibility": "internal" + }, + { + "body": { + "id": 30, + "nodeType": "Block", + "src": "369:47:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 28, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 26, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 7, + "src": "375:24:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 27, + "name": "completed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 21, + "src": "402:9:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "375:36:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 29, + "nodeType": "ExpressionStatement", + "src": "375:36:0" + } + ] + }, + "documentation": null, + "id": 31, + "implemented": true, + "kind": "function", + "modifiers": [ + { + "arguments": null, + "id": 24, + "modifierName": { + "argumentTypes": null, + "id": 23, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 19, + "src": "358:10:0", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "358:10:0" + } + ], + "name": "setCompleted", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 22, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 21, + "name": "completed", + "nodeType": "VariableDeclaration", + "scope": 31, + "src": "335:14:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 20, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "335:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "334:16:0" + }, + "returnParameters": { + "id": 25, + "nodeType": "ParameterList", + "parameters": [], + "src": "369:0:0" + }, + "scope": 32, + "src": "313:103:0", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 33, + "src": "66:352:0" + } + ], + "src": "32:387:0" + }, + "compiler": { + "name": "solc", + "version": "0.5.16+commit.9c3226ce.Emscripten.clang" + }, + "networks": { + "5777": { + "events": {}, + "links": {}, + "address": "0x164B75b7B82B59c5DD3A300fBC3271795779B358", + "transactionHash": "0x80064de798467598d52b3b9b52d15172fc46c204c4bd0b83a8b9bd22580c91be" + } + }, + "schemaVersion": "3.2.5", + "updatedAt": "2020-10-08T06:21:17.769Z", + "networkType": "ethereum", + "devdoc": { + "methods": {} + }, + "userdoc": { + "methods": {} + } +} \ No newline at end of file diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol new file mode 100644 index 0000000..f4661c6 --- /dev/null +++ b/contracts/Migrations.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.8.0; + +contract Migrations { + address public owner = msg.sender; + uint public last_completed_migration; + + modifier restricted() { + require( + msg.sender == owner, + "This function is restricted to the contract's owner" + ); + _; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } +} diff --git a/migrations/1_initial_migration.js b/migrations/1_initial_migration.js new file mode 100644 index 0000000..16a7ba5 --- /dev/null +++ b/migrations/1_initial_migration.js @@ -0,0 +1,5 @@ +const Migrations = artifacts.require("Migrations"); + +module.exports = function (deployer) { + deployer.deploy(Migrations); +}; diff --git a/package-lock.json b/package-lock.json index dfdc036..8a9f670 100644 --- a/package-lock.json +++ b/package-lock.json @@ -831,6 +831,15 @@ "@types/node": "*" } }, + "@types/inquirer": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-7.3.1.tgz", + "integrity": "sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g==", + "requires": { + "@types/through": "*", + "rxjs": "^6.4.0" + } + }, "@types/json-schema": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", @@ -897,6 +906,14 @@ "integrity": "sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==", "dev": true }, + "@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "requires": { + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "2.34.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", diff --git a/package.json b/package.json index e108051..8bb8761 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@oclif/command": "^1.8.0", "@oclif/config": "^1.17.0", "@oclif/plugin-help": "^3.2.0", + "@types/inquirer": "^7.3.1", "fs-extra": "^9.0.1", "inquirer": "^7.3.3", "node-emoji": "^1.10.0", diff --git a/src/commands/config.ts b/src/commands/config.ts index a0bd1b4..e0351db 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -1,4 +1,5 @@ import { Command, flags } from '@oclif/command' +import { lookupService } from 'dns' //@ts-ignore import inquirer from 'inquirer' import { join } from 'path' @@ -49,7 +50,7 @@ export default class Config extends Command { const configPath = join(this.config.configDir, 'config.json') this.log(configPath) } else if (args.item === 'session') { - if(flags.view) { console.log(config.session) } + if (flags.view) { console.log(config.session) } else { const answers = await inquirer .prompt([{ type: 'list', @@ -150,7 +151,7 @@ export default class Config extends Command { { name: 'Signing (generate)', value: 'generatePrivateKey' }, { name: 'Watch only (public key)', value: 'watchOnly' }, { name: 'Signing (private key)', value: 'inputPrivateKey' }, - { name: 'HD Wallet (BIP-39', value: 'HDWallet' } + { name: 'HD Wallet (BIP-39)', value: 'HDWallet' } ] const answers = await inquirer @@ -234,19 +235,39 @@ export default class Config extends Command { } else if (args.item === 'uniswap') { } else if (args.item === 'tokens') { + if (flags.view) { this.log(config.tokens) } + else { + const tokens = config.tokens const answers = await inquirer .prompt([{ type: 'list', - name: 'NetworkId', + name: 'networkId', message: 'Select networkId:', - choices: Object.keys(config.networks), - default: config.session.networkId + choices: Object.keys(config.networks) }, { type: 'input', - name: 'Address', - message: 'Enter Address:', + name: 'name', + message: 'Enter Token Name' }, + { + type: 'input', + name: 'address', + message: 'Enter Token Address' + } + ]) + + const web3 = new Web3() + const contract_json = require('../contracts/ERC20Detailed.json') + const abi = contract_json.abi + + const tokenContract = new web3.eth.Contract(abi, answers.address) + + config.tokens[answers.networkId] [answers.address] = { address: answers.address, name: answers.name } + + await setCredentials(this, config) + this.log('Token configured') + } } else if (args.item === 'all') { if (flags.view) { console.log(config)} else if (flags.default) { @@ -256,6 +277,7 @@ export default class Config extends Command { throw new Error('configure all Unimplemented!') } } + } catch (error) { diff --git a/src/commands/tokens.ts b/src/commands/tokens.ts index 01515f0..f564771 100644 --- a/src/commands/tokens.ts +++ b/src/commands/tokens.ts @@ -1,9 +1,11 @@ import { Command, flags } from '@oclif/command' import Web3 from 'web3' import chalk from 'chalk' +import inquirer from 'inquirer' import IERC20 from '../contracts/ERC20Detailed.json' import credentials from '../utils/credentials' +import { defaultCipherList } from 'constants' export default class Tokens extends Command { static description = 'Interact with ERC20 Tokens' @@ -13,8 +15,8 @@ export default class Tokens extends Command { } static args = [ - { name: 'token', required: true }, - { name: 'subcommand', required: true, options: ["balance", "send"] }] + { name: 'subcommand', required: true, options: ["balance", "send"] }, + { name: 'token'}] async run() { const { args, flags } = this.parse(Tokens) @@ -28,7 +30,25 @@ export default class Tokens extends Command { )} to configure.`) const tokens = config.tokens[session.networkId] - const token = tokens[args.token] || Object.values(tokens).find((token: any) => token.name === args.token) || { address: args.token } + let inputToken; + console.log(config.tokens) + if (args.token == null) { + inputToken = await inquirer + .prompt([ + { + type: 'list', + name: 'tokenSelect', + message: 'Select a token', + choices: Object.keys(config.tokens) + } + ]) + } + + else { + inputToken = tokens[args.token] || Object.values(tokens).find((token: any) => token.name === args.token) || { address: args.token } + } + + const token = inputToken; const web3 = new Web3(network.rpc) diff --git a/test/.gitkeep b/test/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/commands/chainlink.test.ts b/test/commands/chainlink.test.ts deleted file mode 100644 index 772b9f5..0000000 --- a/test/commands/chainlink.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {expect, test} from '@oclif/test' - -describe('chainlink', () => { - test - .stdout() - .command(['chainlink']) - .it('runs hello', ctx => { - expect(ctx.stdout).to.contain('hello world') - }) - - test - .stdout() - .command(['chainlink', '--name', 'jeff']) - .it('runs hello --name jeff', ctx => { - expect(ctx.stdout).to.contain('hello jeff') - }) -}) diff --git a/test/commands/config.test.ts b/test/commands/config.test.ts deleted file mode 100644 index d3f1c28..0000000 --- a/test/commands/config.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {expect, test} from '@oclif/test' - -describe('config', () => { - test - .stdout() - .command(['config']) - .it('runs hello', ctx => { - expect(ctx.stdout).to.contain('hello world') - }) - - test - .stdout() - .command(['config', '--name', 'jeff']) - .it('runs hello --name jeff', ctx => { - expect(ctx.stdout).to.contain('hello jeff') - }) -}) diff --git a/test/commands/eth.test.ts b/test/commands/eth.test.ts deleted file mode 100644 index 9c0b31d..0000000 --- a/test/commands/eth.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {expect, test} from '@oclif/test' - -describe('eth', () => { - test - .stdout() - .command(['eth']) - .it('runs hello', ctx => { - expect(ctx.stdout).to.contain('hello world') - }) - - test - .stdout() - .command(['eth', '--name', 'jeff']) - .it('runs hello --name jeff', ctx => { - expect(ctx.stdout).to.contain('hello jeff') - }) -}) diff --git a/test/commands/hello.test.ts b/test/commands/hello.test.ts deleted file mode 100644 index 5d22255..0000000 --- a/test/commands/hello.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {expect, test} from '@oclif/test' - -describe('hello', () => { - test - .stdout() - .command(['hello']) - .it('runs hello', ctx => { - expect(ctx.stdout).to.contain('hello world') - }) - - test - .stdout() - .command(['hello', '--name', 'jeff']) - .it('runs hello --name jeff', ctx => { - expect(ctx.stdout).to.contain('hello jeff') - }) -}) diff --git a/test/commands/tokens.test.ts b/test/commands/tokens.test.ts deleted file mode 100644 index b0d669d..0000000 --- a/test/commands/tokens.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {expect, test} from '@oclif/test' - -describe('tokens', () => { - test - .stdout() - .command(['tokens']) - .it('runs hello', ctx => { - expect(ctx.stdout).to.contain('hello world') - }) - - test - .stdout() - .command(['tokens', '--name', 'jeff']) - .it('runs hello --name jeff', ctx => { - expect(ctx.stdout).to.contain('hello jeff') - }) -}) diff --git a/test/commands/uniswap.test.ts b/test/commands/uniswap.test.ts deleted file mode 100644 index 575b206..0000000 --- a/test/commands/uniswap.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {expect, test} from '@oclif/test' - -describe('uniswap', () => { - test - .stdout() - .command(['uniswap']) - .it('runs hello', ctx => { - expect(ctx.stdout).to.contain('hello world') - }) - - test - .stdout() - .command(['uniswap', '--name', 'jeff']) - .it('runs hello --name jeff', ctx => { - expect(ctx.stdout).to.contain('hello jeff') - }) -}) diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index 73fb836..0000000 --- a/test/mocha.opts +++ /dev/null @@ -1,5 +0,0 @@ ---require ts-node/register ---watch-extensions ts ---recursive ---reporter spec ---timeout 5000 diff --git a/test/tsconfig.json b/test/tsconfig.json deleted file mode 100644 index 95898fc..0000000 --- a/test/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../tsconfig", - "compilerOptions": { - "noEmit": true - }, - "references": [ - {"path": ".."} - ] -} diff --git a/truffle-config.js b/truffle-config.js new file mode 100644 index 0000000..10e13de --- /dev/null +++ b/truffle-config.js @@ -0,0 +1,96 @@ +/** + * Use this file to configure your truffle project. It's seeded with some + * common settings for different networks and features like migrations, + * compilation and testing. Uncomment the ones you need or modify + * them to suit your project as necessary. + * + * More information about configuration can be found at: + * + * trufflesuite.com/docs/advanced/configuration + * + * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider) + * to sign your transactions before they're sent to a remote public node. Infura accounts + * are available for free at: infura.io/register. + * + * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate + * public/private key pairs. If you're publishing your code to GitHub make sure you load this + * phrase from a file you've .gitignored so it doesn't accidentally become public. + * + */ + +// const HDWalletProvider = require('@truffle/hdwallet-provider'); +// const infuraKey = "fj4jll3k....."; +// +// const fs = require('fs'); +// const mnemonic = fs.readFileSync(".secret").toString().trim(); + +module.exports = { + /** + * Networks define how you connect to your ethereum client and let you set the + * defaults web3 uses to send transactions. If you don't specify one truffle + * will spin up a development blockchain for you on port 9545 when you + * run `develop` or `test`. You can ask a truffle command to use a specific + * network from the command line, e.g + * + * $ truffle test --network + */ + + networks: { + // Useful for testing. The `development` name is special - truffle uses it by default + // if it's defined here and no other network is specified at the command line. + // You should run a client (like ganache-cli, geth or parity) in a separate terminal + // tab if you use this network and you must also set the `host`, `port` and `network_id` + // options below to some value. + // + // development: { + // host: "127.0.0.1", // Localhost (default: none) + // port: 8545, // Standard Ethereum port (default: none) + // network_id: "*", // Any network (default: none) + // }, + // Another network with more advanced options... + // advanced: { + // port: 8777, // Custom port + // network_id: 1342, // Custom network + // gas: 8500000, // Gas sent with each transaction (default: ~6700000) + // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) + // from:
, // Account to send txs from (default: accounts[0]) + // websockets: true // Enable EventEmitter interface for web3 (default: false) + // }, + // Useful for deploying to a public network. + // NB: It's important to wrap the provider as a function. + // ropsten: { + // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`), + // network_id: 3, // Ropsten's id + // gas: 5500000, // Ropsten has a lower block limit than mainnet + // confirmations: 2, // # of confs to wait between deployments. (default: 0) + // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) + // skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) + // }, + // Useful for private networks + // private: { + // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), + // network_id: 2111, // This network is yours, in the cloud. + // production: true // Treats this network as if it was a public net. (default: false) + // } + }, + + // Set default mocha options here, use special reporters etc. + mocha: { + // timeout: 100000 + }, + + // Configure your compilers + compilers: { + solc: { + // version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version) + // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) + // settings: { // See the solidity docs for advice about optimization and evmVersion + // optimizer: { + // enabled: false, + // runs: 200 + // }, + // evmVersion: "byzantium" + // } + }, + }, +}; From a87e90fc25bd59704b6ad033dfbc8452b8812a6e Mon Sep 17 00:00:00 2001 From: Rishin Date: Thu, 22 Oct 2020 12:47:48 -0400 Subject: [PATCH 3/5] configurated token send --- build/contracts/Migrations.json | 18 ++++++++-- src/commands/config.ts | 14 +++----- src/commands/tokens.ts | 60 ++++++++++++++++++++++++--------- src/utils/flags.ts | 0 truffle-config.js | 10 +++--- 5 files changed, 70 insertions(+), 32 deletions(-) create mode 100644 src/utils/flags.ts diff --git a/build/contracts/Migrations.json b/build/contracts/Migrations.json index 8a74933..adebfa2 100644 --- a/build/contracts/Migrations.json +++ b/build/contracts/Migrations.json @@ -870,12 +870,24 @@ "5777": { "events": {}, "links": {}, - "address": "0x164B75b7B82B59c5DD3A300fBC3271795779B358", - "transactionHash": "0x80064de798467598d52b3b9b52d15172fc46c204c4bd0b83a8b9bd22580c91be" + "address": "0xe4024415A682084CE91bCc4d72e7C8240cF138b9", + "transactionHash": "0x0e0c4159223a52a34adc78ea27e225efdba0fde3c627254da1e73a86b25efa7f" + }, + "1602516646691": { + "events": {}, + "links": {}, + "address": "0xaf7BCA62A346ace9d8c26C6DE61439172b1E751E", + "transactionHash": "0x5e004ca4e562b909f911e15736071b6f2c29fa0ea6a1bc9552adb858975f5010" + }, + "1602605563505": { + "events": {}, + "links": {}, + "address": "0x356bBa01EE7b42D77610CE8D9A6f06b41c6830c7", + "transactionHash": "0x7bd192d3ac77f6414939ca9ac16e3e5049ad4d80a15539f2ce5f9f56a03a00db" } }, "schemaVersion": "3.2.5", - "updatedAt": "2020-10-08T06:21:17.769Z", + "updatedAt": "2020-10-13T20:13:34.846Z", "networkType": "ethereum", "devdoc": { "methods": {} diff --git a/src/commands/config.ts b/src/commands/config.ts index e0351db..c27ba69 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -4,6 +4,7 @@ import { lookupService } from 'dns' import inquirer from 'inquirer' import { join } from 'path' import Web3 from 'web3' +import chalk from 'chalk' import credentials, { setCredentials } from '../utils/credentials' import defaultConfig from '../utils/defaultConfig' @@ -32,7 +33,8 @@ export default class Config extends Command { //--help flag help: flags.help({ char: 'h' }), //--view flag - view: flags.boolean({ char: 'v', description: "logs current status in config"}, ), + view: flags.boolean({ char: 'v', description: "logs current status in config"}), + remove: flags.boolean({ char: 'r', description: "remove network"}), default: flags.boolean({ description: 'set default config' }), all: flags.boolean({description: 'view full config' }) } @@ -235,9 +237,9 @@ export default class Config extends Command { } else if (args.item === 'uniswap') { } else if (args.item === 'tokens') { - if (flags.view) { this.log(config.tokens) } + //@ts-ignore + if (flags.view) { this.log(config.tokens) } else { - const tokens = config.tokens const answers = await inquirer .prompt([{ type: 'list', @@ -256,12 +258,6 @@ export default class Config extends Command { message: 'Enter Token Address' } ]) - - const web3 = new Web3() - const contract_json = require('../contracts/ERC20Detailed.json') - const abi = contract_json.abi - - const tokenContract = new web3.eth.Contract(abi, answers.address) config.tokens[answers.networkId] [answers.address] = { address: answers.address, name: answers.name } diff --git a/src/commands/tokens.ts b/src/commands/tokens.ts index f564771..6cdef99 100644 --- a/src/commands/tokens.ts +++ b/src/commands/tokens.ts @@ -3,7 +3,6 @@ import Web3 from 'web3' import chalk from 'chalk' import inquirer from 'inquirer' -import IERC20 from '../contracts/ERC20Detailed.json' import credentials from '../utils/credentials' import { defaultCipherList } from 'constants' @@ -11,7 +10,7 @@ export default class Tokens extends Command { static description = 'Interact with ERC20 Tokens' static flags: any = { - help: flags.help({ char: 'h' }) + help: flags.help({ char: 'h' }) } static args = [ @@ -31,43 +30,73 @@ export default class Tokens extends Command { const tokens = config.tokens[session.networkId] let inputToken; - console.log(config.tokens) + if (args.token == null) { - inputToken = await inquirer + let answers = await inquirer .prompt([ { type: 'list', name: 'tokenSelect', message: 'Select a token', - choices: Object.keys(config.tokens) + choices: Object.keys(tokens) } ]) + inputToken = { address: answers.tokenSelect } } - else { inputToken = tokens[args.token] || Object.values(tokens).find((token: any) => token.name === args.token) || { address: args.token } } - const token = inputToken; - + const token = inputToken const web3 = new Web3(network.rpc) + const ERC20Detailed = require('../contracts/ERC20Detailed.json') //@ts-ignore - const TokenContract = new web3.eth.Contract(IERC20.abi, token.address) + const TokenContract = new web3.eth.Contract(ERC20Detailed.abi, token.address) + const [balanceRaw, symbol, decimals] = await Promise.all([ TokenContract.methods.balanceOf(session.account).call(), TokenContract.methods.symbol().call(), TokenContract.methods.decimals().call() ]) - let balance; - try { - balance = parseInt(balanceRaw) / Math.pow(10, parseInt(decimals)) - } catch (error) { - balance = web3.utils.toBN(balanceRaw).div(web3.utils.toBN('10').pow(web3.utils.toBN(decimals))) + if (args.subcommand == 'balance') { + let balance; + try { + balance = parseInt(balanceRaw) / Math.pow(10, parseInt(decimals)) + } catch (error) { + balance = web3.utils.toBN(balanceRaw).div(web3.utils.toBN('10').pow(web3.utils.toBN(decimals))) + } + + this.log(`balance: ${balance} ${symbol}`) } - this.log(`balance: ${balance} ${symbol}`) + else if (args.subcommand == 'send') { + let answers = await inquirer + .prompt ([ + { + type: 'number', + name: 'amount', + message: 'Enter amount to send: ' + }, + { + type: 'input', + name: 'fromAddress', + message: 'Enter address you are sending from: ' + }, + { + type: 'input', + name: 'toAddress', + message: 'Enter address you are sending to: ' + } + ]) + let amount = web3.utils.toBN(answers.amount) + + let value = amount.mul(web3.utils.toBN(10).pow(web3.utils.toBN(decimals))) + TokenContract.methods.transfer(answers.toAddress, value).send({from: answers.fromAddress}).on('transactionHash', function(hash) { + console.log(hash) + }) + } } catch (error) { this.error(error || 'A DeFi CLI error has occurred.', { exit: 1, @@ -75,3 +104,4 @@ export default class Tokens extends Command { } } } + diff --git a/src/utils/flags.ts b/src/utils/flags.ts new file mode 100644 index 0000000..e69de29 diff --git a/truffle-config.js b/truffle-config.js index 10e13de..4586a36 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -42,11 +42,11 @@ module.exports = { // tab if you use this network and you must also set the `host`, `port` and `network_id` // options below to some value. // - // development: { - // host: "127.0.0.1", // Localhost (default: none) - // port: 8545, // Standard Ethereum port (default: none) - // network_id: "*", // Any network (default: none) - // }, + development: { + host: "127.0.0.1", // Localhost (default: none) + port: 7545, // Standard Ethereum port (default: none) + network_id: "*", // Any network (default: none) + }, // Another network with more advanced options... // advanced: { // port: 8777, // Custom port From 7467e700242f3f1fa2356bb6c09f17d30f6261e9 Mon Sep 17 00:00:00 2001 From: Rishin Date: Wed, 28 Oct 2020 03:51:44 -0400 Subject: [PATCH 4/5] git --- build/contracts/Migrations.json | 6 +++--- src/commands/config.ts | 5 ++--- src/commands/tokens.ts | 16 ++++++++++----- src/utils/flags.ts | 35 +++++++++++++++++++++++++++++++++ truffle-config.js | 4 ++-- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/build/contracts/Migrations.json b/build/contracts/Migrations.json index adebfa2..25efc3c 100644 --- a/build/contracts/Migrations.json +++ b/build/contracts/Migrations.json @@ -870,8 +870,8 @@ "5777": { "events": {}, "links": {}, - "address": "0xe4024415A682084CE91bCc4d72e7C8240cF138b9", - "transactionHash": "0x0e0c4159223a52a34adc78ea27e225efdba0fde3c627254da1e73a86b25efa7f" + "address": "0xb64109FE98152331e024B8f01f17263ac3106620", + "transactionHash": "0x27508b31d48572b8dd4a9c98e8f7fdaa00e8e07a7d912e95d1563988029d8f80" }, "1602516646691": { "events": {}, @@ -887,7 +887,7 @@ } }, "schemaVersion": "3.2.5", - "updatedAt": "2020-10-13T20:13:34.846Z", + "updatedAt": "2020-10-26T15:01:35.636Z", "networkType": "ethereum", "devdoc": { "methods": {} diff --git a/src/commands/config.ts b/src/commands/config.ts index c27ba69..a2fe8f7 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -4,7 +4,7 @@ import { lookupService } from 'dns' import inquirer from 'inquirer' import { join } from 'path' import Web3 from 'web3' -import chalk from 'chalk' +import {help} from '../utils/flags' import credentials, { setCredentials } from '../utils/credentials' import defaultConfig from '../utils/defaultConfig' @@ -31,10 +31,9 @@ export default class Config extends Command { static flags: any = { //--help flag - help: flags.help({ char: 'h' }), + help: help, //--view flag view: flags.boolean({ char: 'v', description: "logs current status in config"}), - remove: flags.boolean({ char: 'r', description: "remove network"}), default: flags.boolean({ description: 'set default config' }), all: flags.boolean({description: 'view full config' }) } diff --git a/src/commands/tokens.ts b/src/commands/tokens.ts index 6cdef99..d7a0f59 100644 --- a/src/commands/tokens.ts +++ b/src/commands/tokens.ts @@ -90,13 +90,19 @@ export default class Tokens extends Command { message: 'Enter address you are sending to: ' } ]) - let amount = web3.utils.toBN(answers.amount) + const amount = web3.utils.toBN(answers.amount) + const adjAmount = web3.utils.toHex(amount.div(web3.utils.toBN(10).pow(web3.utils.toBN(decimals)))) - let value = amount.mul(web3.utils.toBN(10).pow(web3.utils.toBN(decimals))) - TokenContract.methods.transfer(answers.toAddress, value).send({from: answers.fromAddress}).on('transactionHash', function(hash) { - console.log(hash) - }) + TokenContract.methods.transfer( + answers.toAddress, + adjAmount + ).send({from: answers.fromAddress}) + //@ts-ignore + .once('transactionHash', (hash) => { console.log(hash) }) + //@ts-ignore + .once('receipt', (receipt) => { console.log(receipt) }) } + } catch (error) { this.error(error || 'A DeFi CLI error has occurred.', { exit: 1, diff --git a/src/utils/flags.ts b/src/utils/flags.ts index e69de29..3bc4c90 100644 --- a/src/utils/flags.ts +++ b/src/utils/flags.ts @@ -0,0 +1,35 @@ +import {flags} from '@oclif/command' + +export const help = flags.help({ + char: 'h', + description: 'help menu', +} +) + +export const networkset = flags.string({ + char: 'n', + description: 'set the network', +} +) + +export const from = flags.string({ + char: 'f', + description: 'set account sending from', +} +) + +export const to = flags.string({ + description: 'set recipient account for transfers', +} +) + +export const network = flags.string({ + char: 'n', + description: 'set the network', +} +) + +export const gasprice = flags.integer({ + char: 'g', + description: 'set gas price' +}) \ No newline at end of file diff --git a/truffle-config.js b/truffle-config.js index 4586a36..d9c2a89 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -42,9 +42,9 @@ module.exports = { // tab if you use this network and you must also set the `host`, `port` and `network_id` // options below to some value. // - development: { + development: { host: "127.0.0.1", // Localhost (default: none) - port: 7545, // Standard Ethereum port (default: none) + port: 8545, // Standard Ethereum port (default: none) network_id: "*", // Any network (default: none) }, // Another network with more advanced options... From 31dfd13911f026fb3b35454f023542917e9a9d10 Mon Sep 17 00:00:00 2001 From: Rishin Date: Tue, 3 Nov 2020 15:34:22 -0500 Subject: [PATCH 5/5] finished tokens --- src/commands/config.ts | 29 +++++----- src/commands/tokens.ts | 121 +++++++++++++++++++++++++++++------------ src/utils/flags.ts | 16 ++---- 3 files changed, 106 insertions(+), 60 deletions(-) diff --git a/src/commands/config.ts b/src/commands/config.ts index a2fe8f7..3987e37 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -46,6 +46,13 @@ export default class Config extends Command { async run() { const { args, flags }: any = this.parse(Config) const config = await credentials(this) + const networksView = Object.values(config.networks).map((network: any) => { + return { + name: `${network.networkId} (${network.name})`, + value: network.networkId + } + }) + try { if (args.item === 'path') { const configPath = join(this.config.configDir, 'config.json') @@ -57,7 +64,7 @@ export default class Config extends Command { type: 'list', name: 'networkId', message: 'Select networkId:', - choices: Object.keys(config.networks), + choices: networksView, default: config.session.networkId }, { @@ -138,16 +145,8 @@ export default class Config extends Command { this.log('Networks configured.') } } else if (args.item === 'accounts') { - const accounts = config.accounts if (flags.view) { this.log(config.accounts) } else { - const networks = Object.values(config.networks).map((network: any) => { - return { - name: `${network.networkId} (${network.name})`, - value: network.networkId - } - }) - const accountTypes = [ { name: 'Signing (generate)', value: 'generatePrivateKey' }, { name: 'Watch only (public key)', value: 'watchOnly' }, @@ -168,7 +167,7 @@ export default class Config extends Command { type: 'list', name: 'networkId', message: 'Select network id:', - choices: networks, + choices: networksView, default: config.session.networkId }, { @@ -244,17 +243,17 @@ export default class Config extends Command { type: 'list', name: 'networkId', message: 'Select networkId:', - choices: Object.keys(config.networks) + choices: networksView }, { type: 'input', name: 'name', - message: 'Enter Token Name' + message: 'Enter Token Name:' }, { - type: 'input', - name: 'address', - message: 'Enter Token Address' + type: 'input', + name: 'address', + message: 'Enter Token Address:' } ]) diff --git a/src/commands/tokens.ts b/src/commands/tokens.ts index d7a0f59..f27e030 100644 --- a/src/commands/tokens.ts +++ b/src/commands/tokens.ts @@ -4,62 +4,92 @@ import chalk from 'chalk' import inquirer from 'inquirer' import credentials from '../utils/credentials' +import {from} from '../utils/flags' +import {help} from '../utils/flags' +import {network} from '../utils/flags' +import {to} from '../utils/flags' +import {gasprice} from '../utils/flags' +import {token} from '../utils/flags' import { defaultCipherList } from 'constants' export default class Tokens extends Command { static description = 'Interact with ERC20 Tokens' static flags: any = { - help: flags.help({ char: 'h' }) + from: from, + help: help, + network: network, + to: to, + gasprice: gasprice, + token: token } static args = [ - { name: 'subcommand', required: true, options: ["balance", "send"] }, - { name: 'token'}] + { name: 'subcommand', required: true, options: ["balance", "send"] } ] async run() { - const { args, flags } = this.parse(Tokens) + const { args, flags } : any = this.parse(Tokens) try { const config = await credentials(this) const { session } = config - const network = config.networks[session.networkId] - if (!network) throw new Error(`Network ${chalk.bold(`${session.networkId}`)} not configured. Use ${chalk.bold( + //Set the network + let setNetwork : any = config.networks[session.networkId] + if(flags.network) { + setNetwork = Object.values(config.networks).find((network: any) => network.networkId == flags.network) || Object.values(config.networks).find((network: any) => network.name == flags.network) + } + const network = setNetwork + + if (!network) throw new Error(`Network is not configured. Use ${chalk.bold( 'defi config networks', )} to configure.`) - const tokens = config.tokens[session.networkId] - let inputToken; + //Set the account + let setAccount : any = session.account + if(args.subcommand == "balance") { + let answers = await inquirer + .prompt ([ + { + type: 'input', + name: 'account', + message: 'Select an account: ' + } + ]) + setAccount = answers.account + } + const account = setAccount - if (args.token == null) { + //Get token + const tokens = config.tokens[network.networkId] + let inputToken = flags.token; + if (flags.token == null) { let answers = await inquirer .prompt([ { type: 'list', - name: 'tokenSelect', + name: 'token', message: 'Select a token', - choices: Object.keys(tokens) + choices: Object.values(tokens) } ]) - inputToken = { address: answers.tokenSelect } - } - else { - inputToken = tokens[args.token] || Object.values(tokens).find((token: any) => token.name === args.token) || { address: args.token } + inputToken = answers.token } - - const token = inputToken + const token = Object.values(tokens).find((token: any) => token.name === flags.token || token.name === inputToken) || { address: flags.token } + const web3 = new Web3(network.rpc) const ERC20Detailed = require('../contracts/ERC20Detailed.json') //@ts-ignore const TokenContract = new web3.eth.Contract(ERC20Detailed.abi, token.address) + //Get Contract Details const [balanceRaw, symbol, decimals] = await Promise.all([ - TokenContract.methods.balanceOf(session.account).call(), + TokenContract.methods.balanceOf(account).call(), TokenContract.methods.symbol().call(), TokenContract.methods.decimals().call() ]) + //balanceOf if (args.subcommand == 'balance') { let balance; try { @@ -71,38 +101,59 @@ export default class Tokens extends Command { this.log(`balance: ${balance} ${symbol}`) } + //transfer else if (args.subcommand == 'send') { let answers = await inquirer .prompt ([ { type: 'number', name: 'amount', - message: 'Enter amount to send: ' - }, - { - type: 'input', - name: 'fromAddress', - message: 'Enter address you are sending from: ' - }, - { - type: 'input', - name: 'toAddress', - message: 'Enter address you are sending to: ' + message: 'Enter amount to send:' } ]) - const amount = web3.utils.toBN(answers.amount) - const adjAmount = web3.utils.toHex(amount.div(web3.utils.toBN(10).pow(web3.utils.toBN(decimals)))) + + let setFrom = flags.from + if(flags.from == null){ + let answers = await inquirer + .prompt ([ + { + type: 'input', + name: 'fromAddress', + message: 'Enter address you are sending from:', + default: session.account + } + ]) + setFrom = answers.fromAddress + } + + let setTo = flags.to + if(flags.to == null){ + let answers = await inquirer + .prompt ([ + { + type: 'input', + name: 'toAddress', + message: 'Enter address you are sending to:' + } + ]) + setTo = answers.toAddress + } + + const sender = setFrom + const recipeint = setTo TokenContract.methods.transfer( - answers.toAddress, - adjAmount - ).send({from: answers.fromAddress}) + recipeint, + answers.amount + ).send({from: sender}) //@ts-ignore .once('transactionHash', (hash) => { console.log(hash) }) //@ts-ignore .once('receipt', (receipt) => { console.log(receipt) }) + + console.log("Transfer registered.") } - + } catch (error) { this.error(error || 'A DeFi CLI error has occurred.', { exit: 1, diff --git a/src/utils/flags.ts b/src/utils/flags.ts index 3bc4c90..499ef4f 100644 --- a/src/utils/flags.ts +++ b/src/utils/flags.ts @@ -6,14 +6,13 @@ export const help = flags.help({ } ) -export const networkset = flags.string({ +export const network = flags.string({ char: 'n', description: 'set the network', } ) -export const from = flags.string({ - char: 'f', +export const from = flags.string({ description: 'set account sending from', } ) @@ -23,13 +22,10 @@ export const to = flags.string({ } ) -export const network = flags.string({ - char: 'n', - description: 'set the network', -} -) - export const gasprice = flags.integer({ - char: 'g', description: 'set gas price' +}) + +export const token = flags.string({ + description: 'select a token' }) \ No newline at end of file