Skip to content

Commit

Permalink
Merge branch 'master' into mixpanel/identity-management
Browse files Browse the repository at this point in the history
  • Loading branch information
icerove committed Nov 24, 2020
2 parents 4701a3e + 80d5d66 commit 051e121
Show file tree
Hide file tree
Showing 11 changed files with 3,213 additions and 782 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ For a list of up-to-date commands, run `near` in your terminal with no arguments
near delete-key [accessKey] # delete access key
```

#### For smart contract:
#### For native smart contracts:
```bash
near deploy [accountId] [wasmFile] [initFunction] [initArgs] [initGas] [initDeposit] # deploy your smart contract
near dev-deploy [wasmFile] # deploy your smart contract using temporary account (TestNet only)
Expand All @@ -47,6 +47,12 @@ For a list of up-to-date commands, run `near` in your terminal with no arguments
near clean # clean the smart contract build locally (remove ./out )
```

#### For NEAR EVM smart contracts:
```bash
near evm-view <evmAccount> <contractName> <methodName> [args] # make an EVM smart contract call which can view state
near evm-call <evmAccount> <contractName> <methodName> [args] # schedule an EVM smart contract call which can modify state
```

#### For transactions:
```bash
near tx-status <hash> # lookup transaction status by hash
Expand Down
3 changes: 3 additions & 0 deletions bin/near-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ yargs // eslint-disable-line
.middleware(require('../middleware/print-options'))
.middleware(require('../middleware/key-store'))
.middleware(require('../middleware/ledger'))
.middleware(require('../middleware/abi'))
.middleware(require('../middleware/seed-phrase'))
.command(require('../commands/create-account').createAccountCommand)
.command(require('../commands/create-account').createAccountCommandDeprecated)
Expand All @@ -244,6 +245,8 @@ yargs // eslint-disable-line
.command(require('../commands/delete-key'))
.command(require('../commands/validators'))
.command(require('../commands/proposals'))
.command(require('../commands/evm-call'))
.command(require('../commands/evm-view'))
.config(config)
.alias({
'accountId': ['account_id'],
Expand Down
4 changes: 2 additions & 2 deletions commands/call.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ module.exports = {
desc: 'schedule smart contract call which can modify state',
builder: (yargs) => yargs
.option('gas', {
desc: 'Max amount of gas this call can use',
desc: 'Max amount of gas this call can use (in gas units)',
type: 'string',
default: '100000000000000'
})
.option('amount', {
desc: 'Number of tokens to attach',
desc: 'Number of tokens to attach (in NEAR)',
type: 'string',
default: '0'
})
Expand Down
56 changes: 56 additions & 0 deletions commands/evm-call.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const exitOnError = require('../utils/exit-on-error');
const web3 = require('web3');
const { NearProvider, utils } = require('near-web3-provider');
const assert = require('assert');

module.exports = {
command: 'evm-call <evmAccount> <contractName> <methodName> [args]',
desc: 'Schedule call inside EVM machine',
builder: (yargs) => yargs
.option('gas', {
desc: 'Max amount of NEAR gas this call can use',
type: 'string',
default: '100000000000000'
})
.option('amount', {
desc: 'Number of tokens to attach',
type: 'string',
default: '0'
})
.option('args', {
desc: 'Arguments to the contract call, in JSON format (e.g. \'[1, "str"]\') based on contract ABI',
type: 'string',
default: null
})
.option('accountId', {
required: true,
desc: 'Unique identifier for the account that will be used to sign this call',
type: 'string',
})
.option('abi', {
required: true,
desc: 'Path to ABI for given contract',
type: 'string',
}),
handler: exitOnError(scheduleEVMFunctionCall)
};

async function scheduleEVMFunctionCall(options) {
const args = JSON.parse(options.args || '[]');
console.log(`Scheduling a call inside ${options.evmAccount} EVM:`);
console.log(`${options.contractName}.${options.methodName}()` +
(options.amount && options.amount !== '0' ? ` with attached ${options.amount} NEAR` : ''));
console.log(' with args', args);
const web = new web3();
web.setProvider(new NearProvider({
nodeUrl: options.nodeUrl,
// TODO: make sure near-api-js has the same version between near-web3-provider.
// keyStore: options.keyStore,
masterAccountId: options.accountId,
networkId: options.networkId,
evmAccountId: options.evmAccount,
}));
const contract = new web.eth.Contract(options.abi, options.contractName);
assert(options.methodName in contract.methods, `${options.methodName} is not present in ABI`);
await contract.methods[options.methodName](...args).send({ from: utils.nearAccountToEvmAddress(options.accountId) });
}
42 changes: 42 additions & 0 deletions commands/evm-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const exitOnError = require('../utils/exit-on-error');
const web3 = require('web3');
const { NearProvider, utils } = require('near-web3-provider');
const assert = require('assert');

module.exports = {
command: 'evm-view <evmAccount> <contractName> <methodName> [args]',
desc: 'View call inside EVM machine',
builder: (yargs) => yargs
.option('args', {
desc: 'Arguments to the contract call, in JSON format (e.g. \'[1, "str"]\') based on contract ABI',
type: 'string',
default: null
})
.option('accountId', {
required: true,
desc: 'Unique identifier for the account that will be used to sign this call',
type: 'string',
})
.option('abi', {
desc: 'Path to ABI for given contract',
type: 'string',
}),
handler: exitOnError(scheduleEVMFunctionView)
};

async function scheduleEVMFunctionView(options) {
const web = new web3();
web.setProvider(new NearProvider({
nodeUrl: options.nodeUrl,
// TODO: make sure near-api-js has the same version between near-web3-provider.
// keyStore: options.keyStore,
masterAccountId: options.accountId,
networkId: options.networkId,
evmAccountId: options.evmAccount,
}));
const contract = new web.eth.Contract(options.abi, options.contractName);
const args = JSON.parse(options.args || '[]');
assert(options.methodName in contract.methods, `${options.methodName} is not present in ABI`);
const result = await contract.methods[options.methodName](...args).call({ from: utils.nearAccountToEvmAddress(options.accountId) });
console.log(result);
}
8 changes: 6 additions & 2 deletions commands/generate-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ async function generateKey(options) {
options.publicKey = keyPair.publicKey.toString();
options.accountId = options.accountId || implicitAccountId(options.publicKey);
await keyStore.setKey(options.networkId, options.accountId, keyPair);
} else if (options.seedPhrase) {
const seededKeyPair = await options.signer.keyStore.getKey(options.networkId, options.accountId);
await keyStore.setKey(options.networkId, options.accountId, seededKeyPair);
}

console.log(`Key pair with ${options.publicKey} public key for an account "${options.accountId}"`);

}
}

1 change: 0 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const qs = require('querystring');
const chalk = require('chalk'); // colorize output
const open = require('open'); // open URL in default browser
const { KeyPair, utils, transactions } = require('near-api-js');

const connect = require('./utils/connect');
const verify = require('./utils/verify-account');
const capture = require('./utils/capture-login-success');
Expand Down
11 changes: 11 additions & 0 deletions middleware/abi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const fs = require('fs');

async function loadAbi(abiPath) {
return JSON.parse(fs.readFileSync(abiPath)).abi;
}

module.exports = async function parseAbi(options) {
if (options.abi) {
options.abi = await loadAbi(options.abi);
}
};
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "near-cli",
"version": "1.2.0",
"version": "1.4.0",
"description": "General purpose command line tools for interacting with NEAR Protocol",
"engines": {
"node": ">= 12"
Expand Down Expand Up @@ -42,7 +42,8 @@
"jest-environment-node": "^26.0.0",
"mixpanel": "^0.13.0",
"ncp": "^2.0.0",
"near-api-js": "^0.30.0",
"near-web3-provider": "^1.0.0",
"near-api-js": "^0.34.0",
"near-seed-phrase": "^0.1.0",
"open": "^7.0.1",
"rimraf": "^3.0.0",
Expand All @@ -51,6 +52,7 @@
"update-notifier": "^5.0.0",
"uuid": "^8.0.0",
"v8flags": "^3.1.3",
"web3": "^1.2.11",
"yargs": "^16.0.3"
},
"optionalDependencies": {
Expand Down
24 changes: 23 additions & 1 deletion utils/inspect-response.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
const explorer = require('./explorer');

const config = require('../get-config')();
const chalk = require('chalk'); // colorize output
const util = require('util');


const checkForAccDoesNotExist = (error, options) => {
if(!String(error).includes('does not exist while viewing')) return false;

const suffixesToNetworks = {near:'mainnet', testnet:'testnet', betanet:'betanet'};

const currentNetwork = config.helperAccount;
console.log(chalk`\n{bold.red Account {bold.white ${options.accountId}} is not found in {bold.white ${suffixesToNetworks[currentNetwork]}}\n}`);

const accSuffix = String(options.accountId).match('[^.]*$')[0];
const accNetwork = suffixesToNetworks[accSuffix];
if (currentNetwork != accSuffix && accNetwork) {
console.log(chalk`{bold.white Use export NEAR_ENV=${accNetwork} to use ${accNetwork} accounts. \n}`);
}

return true;
};

const prettyPrintResponse = (response, options) => {
if (options.verbose) {
console.log(formatResponse(response));
Expand All @@ -13,6 +33,8 @@ const prettyPrintResponse = (response, options) => {
};

const prettyPrintError = (error, options) => {
if (checkForAccDoesNotExist(error, options)) return;

console.log('An error occured');
console.log(formatResponse(error));
const txnId = getTxnIdFromError(error);
Expand Down

0 comments on commit 051e121

Please sign in to comment.