From 2c69773b65db304ab421061b723bdf862ea6ce98 Mon Sep 17 00:00:00 2001 From: Yifang Ma Date: Fri, 1 Nov 2019 18:55:17 -0700 Subject: [PATCH 1/4] delete blank project and fix issues 161, 164, 165 --- README.md | 29 +++- bin/near | 128 +++++++------- blank_project/.gitattributes | 2 - blank_project/README.md | 6 - blank_project/assembly/main.ts | 32 ---- blank_project/assembly/model.ts | 13 -- blank_project/assembly/tsconfig.json | 6 - blank_project/gulpfile.js | 11 -- .../shared-test-staging/test.near.json | 1 - .../neardev/shared-test/test.near.json | 1 - blank_project/out/.gitignore | 4 - blank_project/package.json | 30 ---- blank_project/src/index.html | 38 ----- blank_project/src/main.js | 94 ----------- blank_project/src/test.js | 41 ----- blank_project/src/wallet/login/index.html | 28 --- blank_project/src/config.js => config.js | 0 get-config.js | 2 +- index.js | 159 +++++++++--------- 19 files changed, 155 insertions(+), 470 deletions(-) delete mode 100644 blank_project/.gitattributes delete mode 100755 blank_project/README.md delete mode 100755 blank_project/assembly/main.ts delete mode 100644 blank_project/assembly/model.ts delete mode 100755 blank_project/assembly/tsconfig.json delete mode 100644 blank_project/gulpfile.js delete mode 100644 blank_project/neardev/shared-test-staging/test.near.json delete mode 100644 blank_project/neardev/shared-test/test.near.json delete mode 100644 blank_project/out/.gitignore delete mode 100644 blank_project/package.json delete mode 100755 blank_project/src/index.html delete mode 100755 blank_project/src/main.js delete mode 100755 blank_project/src/test.js delete mode 100644 blank_project/src/wallet/login/index.html rename blank_project/src/config.js => config.js (100%) diff --git a/README.md b/README.md index 99a2888e..0a81c684 100644 --- a/README.md +++ b/README.md @@ -21,23 +21,31 @@ near ### Commands +For account: +```bash + near login # create a developer account + near create_account # create a developer account with masterAccount, publicKey and initialBalance + near view # view account state + near keys # view account public keys + near send # send tokens to given receiver + near stake # create staking transaction (base58 encoded) + near delete # delete an account and transfer funds to beneficiary account +``` + +For smart contract: ```bash - near create_account # create a developer account - near state # view account - near tx-status # lookup transaction status by hash near build # build your smart contract near deploy # deploy your smart contract near call # schedule smart contract call which [args] # can modify state near view # make smart contract call which can [args] # view state - near state # view account - near send # send tokens to given receiver near clean # clean the build environment - near new_project [projectDir] # create a new blank project - near stake [accountId] [publicKey] [amount] # create staking transaction - near login # create a developer account +``` +For transactions: +```bash + near tx-status # lookup transaction status by hash ``` ### Options @@ -51,4 +59,7 @@ near | --helperUrl | NEAR contract helper URL | [string] | | | --keyPath | Path to master account key | [string] | | | --homeDir | Where to look for master account | [string] |"~/.near" | -| --accountId, --account_id | Unique identifier for the account | [string] | | +| --accountId, --account_id | Unique identifier for the account | [string] [required]| | +| --masterAccount | Account used to create requested account. | [string] [required]| | +| --publicKey | Public key to initialize the account with | [string] [required]| | +| --initialBalance | Number of tokens to transfer to newly account | [string] [required]| | \ No newline at end of file diff --git a/bin/near b/bin/near index 9e3f8c20..47b087c1 100755 --- a/bin/near +++ b/bin/near @@ -12,6 +12,25 @@ const exitOnError = async function(promise) { } } +//For smart contract: +const { spawn } = require('child_process'); +const build = { + command: 'build', + desc: 'build your smart contract', + handler: (argv) => { + const gulp = spawn('gulp'); + gulp.stdout.on('data', function (data) { + console.log(data.toString()); + }); + gulp.stderr.on('data', function (data) { + console.log(data.toString()); + }); + gulp.on('exit', function (code) { + process.exit(code); + }); + } +}; + const deploy = { command: 'deploy', desc: 'deploy your smart contract', @@ -46,34 +65,22 @@ const callViewFunction = { handler: (argv) => exitOnError(main.callViewFunction(argv)) }; -const sendMoney = { - command: 'send ', - desc: 'send tokens to given receiver', - builder: (yargs) => yargs, - handler: (argv) => exitOnError(main.sendMoney(argv)) -}; - -const { spawn } = require('child_process'); -const build = { - command: 'build', - desc: 'build your smart contract', - handler: (argv) => { - const gulp = spawn('gulp'); - gulp.stdout.on('data', function (data) { - console.log(data.toString()); - }); - gulp.stderr.on('data', function (data) { - console.log(data.toString()); - }); - gulp.on('exit', function (code) { - process.exit(code); - }); - } +const clean = { + command: 'clean', + desc: 'clean the build environment', + builder: (yargs) => yargs + .option('outDir', { + desc: 'build directory', + type: 'string', + default: './out' + }), + handler: (argv) => exitOnError(main.clean(argv)) }; +//For Account: const createAccount = { command: 'create_account ', - desc: 'create a developer account', + desc: 'create a developer account with --masterAccount, --publicKey and --initialBalance', builder: (yargs) => yargs .option('accountId', { desc: 'Unique identifier for the newly created account', @@ -100,14 +107,14 @@ const createAccount = { const login = { command: 'login', - desc: 'create a developer account', + desc: 'logging into NEAR wallet', builder: (yargs) => yargs, handler: (argv) => exitOnError(main.login(argv)) }; const viewAccount = { - command: 'state ', - desc: 'view account', + command: 'view ', + desc: 'view account state', builder: (yargs) => yargs .option('accountId', { desc: 'Account to view', @@ -118,8 +125,8 @@ const viewAccount = { }; const deleteAccount = { - command: 'delete_account ', - desc: 'delete an account and transfer funds to beneficiary account.', + command: 'delete ', + desc: 'delete an account and transfer funds to beneficiary account', builder: (yargs) => yargs .option('accountId', { desc: 'Account to view', @@ -146,44 +153,8 @@ const keys = { handler: (argv) => exitOnError(main.keys(argv)) }; -const txStatus = { - command: 'tx-status ', - desc: 'lookup transaction status by hash', - builder: (yargs) => yargs - .option('hash', { - desc: 'base58-encoded hash', - type: 'string', - required: true - }), - handler: (argv) => exitOnError(main.txStatus(argv)) -}; - -const clean = { - command: 'clean', - desc: 'clean the build environment', - builder: (yargs) => yargs - .option('outDir', { - desc: 'build directory', - type: 'string', - default: './out' - }), - handler: (argv) => exitOnError(main.clean(argv)) -}; - -const newProject = { - command: 'new_project [projectDir]', - desc: 'create a new blank project', - builder: (yargs) => yargs - .option('projectDir', { - desc: 'project directory', - type: 'string', - default: '.' - }), - handler: (argv) => exitOnError(main.newProject(argv)) -}; - const stake = { - command: 'stake [accountId] [publicKey] [amount]', + command: 'stake ', desc: 'create staking transaction', builder: (yargs) => yargs .option('accountId', { @@ -191,7 +162,7 @@ const stake = { type: 'string', required: true, }) - .option('publicKey', { + .option('stakeKey', { descr: 'Public key to stake with (base58 encoded)', type: 'string', required: true, @@ -202,7 +173,27 @@ const stake = { required: true, }), handler: (argv) => exitOnError(main.stake(argv)) -} +}; + +const sendMoney = { + command: 'send ', + desc: 'send tokens to given receiver', + builder: (yargs) => yargs, + handler: (argv) => exitOnError(main.sendMoney(argv)) +}; + +//For transaction: +const txStatus = { + command: 'tx-status ', + desc: 'lookup transaction status by hash', + builder: (yargs) => yargs + .option('hash', { + desc: 'base58-encoded hash', + type: 'string', + required: true + }), + handler: (argv) => exitOnError(main.txStatus(argv)) +}; let config = require('../get-config')(); yargs // eslint-disable-line @@ -245,7 +236,6 @@ yargs // eslint-disable-line .command(viewAccount) .command(sendMoney) .command(clean) - .command(newProject) .command(stake) .command(login) .config(config) diff --git a/blank_project/.gitattributes b/blank_project/.gitattributes deleted file mode 100644 index a030d665..00000000 --- a/blank_project/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -package-lock.json linguist-generated=true -diff -yarn.lock linguist-generated=true -diff diff --git a/blank_project/README.md b/blank_project/README.md deleted file mode 100755 index 4f400ede..00000000 --- a/blank_project/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Greeter example in AssemblyScript - -## Description - -The contract implements a single function to return a greeting. -For instructions on how to run this project, please follow our online tutorial https://docs.nearprotocol.com/quick-start/local-development diff --git a/blank_project/assembly/main.ts b/blank_project/assembly/main.ts deleted file mode 100755 index 303bdf9b..00000000 --- a/blank_project/assembly/main.ts +++ /dev/null @@ -1,32 +0,0 @@ -//@nearfile -import { near, context, storage, logging } from "near-runtime-ts"; -import { Greeter } from "./model"; - -// --- contract code goes below - -// It's good to use common constant, but not required. -const LAST_SENDER_KEY = "last_sender"; - -// This is our change method. It modifies the state of the contract by -// storing the account_id of the sender under the key "last_sender" on the blockchain -export function sayHi(): void { - // context.sender is the account_id of the user who sent this call to the contract - // It's provided by the Blockchain runtime. For now we just store it in a local variable. - let sender = context.sender; - // `near` class contains some helper functions, e.g. logging. - // Logs are not persistently stored on the blockchain, but produced by the blockchain runtime. - // It's helpful to use logs for debugging your functions or when you need to get some info - // from the change methods (since change methods don't return values to the front-end). - logging.log(sender + " says \"Hello mate!\""); - // storage is a helper class that allows contracts to modify the persistent state - // and read from it. setString allows you to persitently store a string value for a given string key. - // We'll store the last sender of this contract who called this method. - storage.setString(LAST_SENDER_KEY, sender); -} - -// This is our view method. It returns the last account_id of a sender who called `sayHi`. -// It reads value from the persistent store under the key "last_sender" and returns it. -export function whoSaidHi(): string | null { - // getString returns a string value for a given string key. - return storage.getString(LAST_SENDER_KEY); -} diff --git a/blank_project/assembly/model.ts b/blank_project/assembly/model.ts deleted file mode 100644 index 1a49e961..00000000 --- a/blank_project/assembly/model.ts +++ /dev/null @@ -1,13 +0,0 @@ -//@nearfile -// Basic data model -export class Greeter { - text: string; - - constructor(text: string) { - this.text = text; - } - - greet(userId: string): string { - return "Hello, " + userId; - } -} diff --git a/blank_project/assembly/tsconfig.json b/blank_project/assembly/tsconfig.json deleted file mode 100755 index c76b0d8b..00000000 --- a/blank_project/assembly/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../node_modules/assemblyscript/std/assembly.json", - "include": [ - "./**/*.ts" - ] -} diff --git a/blank_project/gulpfile.js b/blank_project/gulpfile.js deleted file mode 100644 index e327a313..00000000 --- a/blank_project/gulpfile.js +++ /dev/null @@ -1,11 +0,0 @@ -const gulp = require('gulp'); -const nearUtils = require('near-shell/gulp-utils'); - -function build_wasm(done){ - nearUtils.compile('./assembly/main.ts', './out/main.wasm', done); -} - -const build = gulp.series(build_wasm); - - -exports.default = build; diff --git a/blank_project/neardev/shared-test-staging/test.near.json b/blank_project/neardev/shared-test-staging/test.near.json deleted file mode 100644 index 5477035f..00000000 --- a/blank_project/neardev/shared-test-staging/test.near.json +++ /dev/null @@ -1 +0,0 @@ -{"account_id":"test.near","private_key":"ed25519:2wyRcSwSuHtRVmkMCGjPwnzZmQLeXLzLLyED1NDMt4BjnKgQL6tF85yBx6Jr26D2dUNeC716RBoTxntVHsegogYw"} diff --git a/blank_project/neardev/shared-test/test.near.json b/blank_project/neardev/shared-test/test.near.json deleted file mode 100644 index 5477035f..00000000 --- a/blank_project/neardev/shared-test/test.near.json +++ /dev/null @@ -1 +0,0 @@ -{"account_id":"test.near","private_key":"ed25519:2wyRcSwSuHtRVmkMCGjPwnzZmQLeXLzLLyED1NDMt4BjnKgQL6tF85yBx6Jr26D2dUNeC716RBoTxntVHsegogYw"} diff --git a/blank_project/out/.gitignore b/blank_project/out/.gitignore deleted file mode 100644 index 5e7d2734..00000000 --- a/blank_project/out/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/blank_project/package.json b/blank_project/package.json deleted file mode 100644 index 233bf095..00000000 --- a/blank_project/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "hello_world_ts", - "description": "", - "version": "0.0.1", - "scripts": { - "build": "mkdir -p out/ && gulp", - "deploy:contract": "near deploy", - "deploy:pages": "gh-pages -d src", - "deploy": "npm run build && npm run deploy:contract && npm run deploy:pages", - "prestart": "npm run build && npm run deploy:contract", - "start": "serve src", - "test": "npm run build && jest test --env=near-shell/test_environment" - }, - "devDependencies": { - "gh-pages": "^2.1.1", - "gulp": "^4.0.2", - "jest": "^24.8.0", - "jest-environment-node": "^24.8.0", - "near-runtime-ts": "^0.5.1", - "near-shell": "github:nearprotocol/near-shell" - }, - "wasmStudio": { - "name": "Hello World Example", - "description": "The contract implements a single function to return \"Hello, World!\" using AssemblyScript", - "icon": "typescript-lang-file-icon" - }, - "dependencies": { - "serve": "^11.0.1" - } -} diff --git a/blank_project/src/index.html b/blank_project/src/index.html deleted file mode 100755 index 0789066f..00000000 --- a/blank_project/src/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - -
-
-

??? was the last person to say "Hi!"

-   -
-
-
-
- -
-
-
-
-

Hi, !

-
-
-
- -
-
- -
-
-
-
- - - - - - diff --git a/blank_project/src/main.js b/blank_project/src/main.js deleted file mode 100755 index aca24b59..00000000 --- a/blank_project/src/main.js +++ /dev/null @@ -1,94 +0,0 @@ -// Initializing contract -async function initContract() { - console.log('nearConfig', nearConfig); - - // Initializing connection to the NEAR DevNet. - window.near = await nearlib.connect(Object.assign({ deps: { keyStore: new nearlib.keyStores.BrowserLocalStorageKeyStore() } }, nearConfig)); - - // Initializing Wallet based Account. It can work with NEAR DevNet wallet that - // is hosted at https://wallet.nearprotocol.com - window.walletAccount = new nearlib.WalletAccount(window.near); - - // Getting the Account ID. If unauthorized yet, it's just empty string. - window.accountId = window.walletAccount.getAccountId(); - - // Initializing our contract APIs by contract name and configuration. - window.contract = await near.loadContract(nearConfig.contractName, { // eslint-disable-line require-atomic-updates - // NOTE: This configuration only needed while NEAR is still in development - // View methods are read only. They don't modify the state, but usually return some value. - viewMethods: ['whoSaidHi'], - // Change methods can modify the state. But you don't receive the returned value when called. - changeMethods: ['sayHi'], - // Sender is the account ID to initialize transactions. - sender: window.accountId, - }); -} - -// Using initialized contract -async function doWork() { - // Setting up refresh button - document.getElementById('refresh-button').addEventListener('click', updateWhoSaidHi); - - // Based on whether you've authorized, checking which flow we should go. - if (!window.walletAccount.isSignedIn()) { - signedOutFlow(); - } else { - signedInFlow(); - } -} - -// Function that initializes the signIn button using WalletAccount -function signedOutFlow() { - // Displaying the signed out flow container. - document.getElementById('signed-out-flow').classList.remove('d-none'); - // Adding an event to a sing-in button. - document.getElementById('sign-in-button').addEventListener('click', () => { - window.walletAccount.requestSignIn( - // The contract name that would be authorized to be called by the user's account. - window.nearConfig.contractName, - // This is the app name. It can be anything. - 'Who was the last person to say "Hi!"?', - // We can also provide URLs to redirect on success and failure. - // The current URL is used by default. - ); - }); -} - -// Main function for the signed-in flow (already authorized by the wallet). -function signedInFlow() { - // Displaying the signed in flow container. - document.getElementById('signed-in-flow').classList.remove('d-none'); - - // Displaying current account name. - document.getElementById('account-id').innerText = window.accountId; - - // Adding an event to a say-hi button. - document.getElementById('say-hi').addEventListener('click', () => { - // We call say Hi and then update who said Hi last. - window.contract.sayHi().then(updateWhoSaidHi); - }); - - // Adding an event to a sing-out button. - document.getElementById('sign-out-button').addEventListener('click', () => { - walletAccount.signOut(); - // Forcing redirect. - window.location.replace(window.location.origin + window.location.pathname); - }); -} - -// Function to update who said hi -function updateWhoSaidHi() { - // JavaScript tip: - // This is another example of how to use promises. Since this function is not async, - // we can't await for `contract.whoSaidHi()`, instead we attaching a callback function - // usin `.then()`. - contract.whoSaidHi().then((who) => { - // If the result doesn't have a value we fallback to the text - document.getElementById('who').innerText = who || 'Nobody (but you can be the first)'; - }); -} - -// Loads nearlib and this contract into window scope. -window.nearInitPromise = initContract() - .then(doWork) - .catch(console.error); \ No newline at end of file diff --git a/blank_project/src/test.js b/blank_project/src/test.js deleted file mode 100755 index 9c8fdeb0..00000000 --- a/blank_project/src/test.js +++ /dev/null @@ -1,41 +0,0 @@ -// >> tests-snippet -describe('Greeter', function() { - let near; - let contract; - let accountId; - - jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; - - // Common setup below - beforeAll(async function() { - if (window.testSettings === undefined) { - window.testSettings = {}; - } - near = await nearlib.connect(testSettings); - accountId = testSettings.accountId; - const contractName = testSettings.contractName ? - testSettings.contractName : - (new URL(window.location.href)).searchParams.get('contractName'); - contract = await near.loadContract(contractName, { - // NOTE: This configuration only needed while NEAR is still in development - // View methods are read only. They don't modify the state, but usually return some value. - viewMethods: ['whoSaidHi'], - // Change methods can modify the state. But you don't receive the returned value when called. - changeMethods: [], - sender: accountId - }); - }); - - // Multiple tests can be described below. Search Jasmine JS for documentation. - describe('simple', function() { - beforeAll(async function() { - // There can be some common setup for each test. - }); - - it('get hello message', async function() { - const result = await contract.whoSaidHi(); - expect(result).toBeNull(); - }); - }); -}); -// << tests-snippet diff --git a/blank_project/src/wallet/login/index.html b/blank_project/src/wallet/login/index.html deleted file mode 100644 index 979c49c9..00000000 --- a/blank_project/src/wallet/login/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -
Please run the following command in shell, then enter account id here. masterAccountId default: test.near -
-
- -
- - - - - \ No newline at end of file diff --git a/blank_project/src/config.js b/config.js similarity index 100% rename from blank_project/src/config.js rename to config.js diff --git a/get-config.js b/get-config.js index 5934a2ff..2bf71add 100644 --- a/get-config.js +++ b/get-config.js @@ -8,7 +8,7 @@ module.exports = function getConfig() { } catch (e) { if (e.code == 'MODULE_NOT_FOUND') { console.warn(`[WARNING] Didn't find config at ${configPath}, using default shell config`); - const defaultConfig = require('./blank_project/src/config')(process.env.NODE_ENV || 'development'); + const defaultConfig = require('./config')(process.env.NODE_ENV || 'development'); return defaultConfig; } throw e; diff --git a/index.js b/index.js index ec3fd190..19e688a2 100644 --- a/index.js +++ b/index.js @@ -16,30 +16,6 @@ const inspectResponse = (response) => { return util.inspect(response, { showHidden: false, depth: null, colors: true }); }; -// TODO: Fix promisified wrappers to handle error properly - -exports.newProject = async function(options) { - // Need to wait for the copy to finish, otherwise next tasks do not find files. - const projectDir = options.projectDir; - const sourceDir = __dirname + '/blank_project'; - console.log(`Copying files to new project directory (${projectDir}) from template source (${sourceDir}).`); - const copyDirFn = () => { - return new Promise(resolve => { - ncp (sourceDir, options.projectDir, response => resolve(response)); - });}; - await copyDirFn(); - console.log('Copying project files complete.'); -}; - -exports.clean = async function() { - const rmDirFn = () => { - return new Promise(resolve => { - rimraf(yargs.argv.outDir, response => resolve(response)); - });}; - await rmDirFn(); - console.log('Clean complete.'); -}; - async function connect(options) { const keyStore = new UnencryptedFileSystemKeyStore('./neardev'); options.deps = { @@ -49,53 +25,16 @@ async function connect(options) { return await nearjs.connect(options); } -exports.createAccount = async function(options) { - let near = await connect(options); - let keyPair; - let publicKey; - if (options.publicKey) { - publicKey = options.publicKey; - } else { - keyPair = await KeyPair.fromRandom('ed25519'); - publicKey = keyPair.getPublicKey(); - } - await near.createAccount(options.accountId, publicKey); - if (keyPair) { - await near.connection.signer.keyStore.setKey(options.networkId, options.accountId, keyPair); - } - console.log(`Account ${options.accountId} for network "${options.networkId}" was created.`); -}; - -exports.viewAccount = async function(options) { - let near = await connect(options); - let account = await near.account(options.accountId); - let state = await account.state(); - console.log(`Account ${options.accountId}`); - console.log(inspectResponse(state)); -}; - -exports.deleteAccount = async function(options) { - console.log( - `Deleting account. Account id: ${options.accountId}, node: ${options.nodeUrl}, helper: ${options.helperUrl}, beneficiary: ${options.beneficiaryId}`); - const near = await connect(options); - const account = await near.account(options.accountId); - await account.deleteAccount(options.beneficiaryId); - console.log(`Account ${options.accountId} for network "${options.networkId}" was deleted.`); -}; - -exports.keys = async function(options) { - let near = await connect(options); - let account = await near.account(options.accountId); - let accessKeys = await account.getAccessKeys(); - console.log(`Keys for account ${options.accountId}`); - console.log(inspectResponse(accessKeys)); -}; +// TODO: Fix promisified wrappers to handle error properly -exports.txStatus = async function(options) { - let near = await connect(options); - let status = await near.connection.provider.txStatus(bs58.decode(options.hash), options.accountId || options.masterAccount); - console.log(`Transaction ${options.hash}`); - console.log(inspectResponse(status)); +//For smart contract: +exports.clean = async function() { + const rmDirFn = () => { + return new Promise(resolve => { + rimraf(yargs.argv.outDir, response => resolve(response)); + });}; + await rmDirFn(); + console.log('Clean complete.'); }; exports.deploy = async function(options) { @@ -117,13 +56,6 @@ exports.scheduleFunctionCall = async function(options) { console.log(inspectResponse(result)); }; -exports.sendMoney = async function(options) { - console.log(`Sending ${options.amount} NEAR to ${options.receiver} from ${options.sender}`); - const near = await connect(options); - const account = await near.account(options.sender); - console.log(inspectResponse(await account.sendMoney(options.receiver, options.amount))); -}; - exports.callViewFunction = async function(options) { console.log(`View call: ${options.contractName}.${options.methodName}(${options.args || ''})`); const near = await connect(options); @@ -132,12 +64,22 @@ exports.callViewFunction = async function(options) { console.log(inspectResponse(await account.viewFunction(options.contractName, options.methodName, JSON.parse(options.args || '{}')))); }; -exports.stake = async function(options) { - console.log(`Staking ${options.amount} on ${options.accountId} with public key = ${options.publicKey}.`); - const near = await connect(options); - const account = await near.account(options.accountId); - const result = await account.stake(options.publicKey, options.amount); - console.log(inspectResponse(result)); +//For account: +exports.createAccount = async function(options) { + let near = await connect(options); + let keyPair; + let publicKey; + if (options.publicKey) { + publicKey = options.publicKey; + } else { + keyPair = await KeyPair.fromRandom('ed25519'); + publicKey = keyPair.getPublicKey(); + } + await near.createAccount(options.accountId, publicKey); + if (keyPair) { + await near.connection.signer.keyStore.setKey(options.networkId, options.accountId, keyPair); + } + console.log(`Account ${options.accountId} for network "${options.networkId}" was created.`); }; exports.login = async function(options) { @@ -161,11 +103,12 @@ exports.login = async function(options) { const near = await connect(options); let account = await near.account(accountId); let keys = await account.getAccessKeys(); + let publicKey = keyPair.getPublicKey().toString(); let keyFound = keys.some(key => key.public_key == keyPair.getPublicKey().toString()); if (keyFound) { const keyStore = new UnencryptedFileSystemKeyStore('./neardev'); await keyStore.setKey(options.networkId, accountId, keyPair); - console.log(`Logged in with ${accountId}`); + console.log(`Logged in as ${accountId} with public key ${publicKey} successfully`); } else { console.log('Log in did not succeed. Please try again.'); } @@ -176,3 +119,51 @@ exports.login = async function(options) { }); } }; + +exports.viewAccount = async function(options) { + let near = await connect(options); + let account = await near.account(options.accountId); + let state = await account.state(); + console.log(`Account ${options.accountId}`); + console.log(inspectResponse(state)); +}; + +exports.deleteAccount = async function(options) { + console.log( + `Deleting account. Account id: ${options.accountId}, node: ${options.nodeUrl}, helper: ${options.helperUrl}, beneficiary: ${options.beneficiaryId}`); + const near = await connect(options); + const account = await near.account(options.accountId); + await account.deleteAccount(options.beneficiaryId); + console.log(`Account ${options.accountId} for network "${options.networkId}" was deleted.`); +}; + +exports.keys = async function(options) { + let near = await connect(options); + let account = await near.account(options.accountId); + let accessKeys = await account.getAccessKeys(); + console.log(`Keys for account ${options.accountId}`); + console.log(inspectResponse(accessKeys)); +}; + +exports.sendMoney = async function(options) { + console.log(`Sending ${options.amount} NEAR to ${options.receiver} from ${options.sender}`); + const near = await connect(options); + const account = await near.account(options.sender); + console.log(inspectResponse(await account.sendMoney(options.receiver, options.amount))); +}; + +exports.stake = async function(options) { + console.log(`Staking ${options.amount} on ${options.accountId} with public key = ${options.stakeKey}.`); + const near = await connect(options); + const account = await near.account(options.accountId); + const result = await account.stake(options.stakeKey, options.amount); + console.log(inspectResponse(result)); +}; + +//For transaction: +exports.txStatus = async function(options) { + let near = await connect(options); + let status = await near.connection.provider.txStatus(bs58.decode(options.hash), options.accountId || options.masterAccount); + console.log(`Transaction ${options.hash}`); + console.log(inspectResponse(status)); +}; From e7997c832f33ca8552d025ac7616bef5489f3990 Mon Sep 17 00:00:00 2001 From: Yifang Ma Date: Fri, 1 Nov 2019 19:05:23 -0700 Subject: [PATCH 2/4] remove test for new project --- test/test_new_project.sh | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100755 test/test_new_project.sh diff --git a/test/test_new_project.sh b/test/test_new_project.sh deleted file mode 100755 index be0d3c4a..00000000 --- a/test/test_new_project.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -ex - -# remove temporary blank project -rm -rf tmp-project - -# test generating new project in cwd -mkdir tmp-project -cd tmp-project -../bin/near new_project -yarn -yarn remove near-shell -yarn add ../ -yarn test -cd .. - -# test generating new project in new dir -rm -rf tmp-project -./bin/near new_project 'tmp-project' -cd tmp-project -FILE=package.json -if test -f "$FILE"; then - echo "$FILE exists. Have a cookie!" -else - echo "ERROR: $FILE not found." - exit 1 -fi From 82d61d5634ad01e5b50288eed03045c2ff8619db Mon Sep 17 00:00:00 2001 From: Yifang Ma Date: Fri, 1 Nov 2019 21:12:39 -0700 Subject: [PATCH 3/4] fix test --- test/test_account_operations.sh | 4 ++-- test/test_contract.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_account_operations.sh b/test/test_account_operations.sh index e212f494..8b1e8361 100755 --- a/test/test_account_operations.sh +++ b/test/test_account_operations.sh @@ -1,7 +1,7 @@ #!/bin/bash set -ex rm -rf tmp-project -./bin/near new_project 'tmp-project' +yarn create near-app --plain tmp-project cd tmp-project timestamp=$(date +%s) testaccount=testaccount$timestamp @@ -9,7 +9,7 @@ echo Create account ../bin/near create_account $testaccount echo Get account state -RESULT=$(../bin/near state $testaccount | strip-ansi) +RESULT=$(../bin/near view $testaccount | strip-ansi) echo $RESULT EXPECTED=".+Account $testaccount.+amount:.+'1000000000000000000'.+ " if [[ ! "$RESULT" =~ $EXPECTED ]]; then diff --git a/test/test_contract.sh b/test/test_contract.sh index 2e12ab43..b8000f95 100755 --- a/test/test_contract.sh +++ b/test/test_contract.sh @@ -1,7 +1,7 @@ #!/bin/bash set -ex rm -rf tmp-project -./bin/near new_project 'tmp-project' +yarn create near-app --plain tmp-project cd tmp-project rm -rf assembly mkdir assembly From 8c80fec60890800b1509cd3373f5afd2f4a0bad2 Mon Sep 17 00:00:00 2001 From: Yifang Ma Date: Mon, 4 Nov 2019 11:57:12 -0800 Subject: [PATCH 4/4] change to staking key and add spaces --- README.md | 4 ++-- bin/near | 12 ++++++------ index.js | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 0a81c684..8f333e95 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ For account: near view # view account state near keys # view account public keys near send # send tokens to given receiver - near stake # create staking transaction (base58 encoded) + near stake # create staking transaction (stakingKey is base58 encoded) near delete # delete an account and transfer funds to beneficiary account ``` @@ -40,7 +40,7 @@ For smart contract: [args] # can modify state near view # make smart contract call which can [args] # view state - near clean # clean the build environment + near clean # clean the smart contract build locally(remove ./out ) ``` For transactions: diff --git a/bin/near b/bin/near index 47b087c1..fa40f12e 100755 --- a/bin/near +++ b/bin/near @@ -12,7 +12,7 @@ const exitOnError = async function(promise) { } } -//For smart contract: +// For smart contract: const { spawn } = require('child_process'); const build = { command: 'build', @@ -67,7 +67,7 @@ const callViewFunction = { const clean = { command: 'clean', - desc: 'clean the build environment', + desc: 'clean the smart contract build locally', builder: (yargs) => yargs .option('outDir', { desc: 'build directory', @@ -77,7 +77,7 @@ const clean = { handler: (argv) => exitOnError(main.clean(argv)) }; -//For Account: +// For Account: const createAccount = { command: 'create_account ', desc: 'create a developer account with --masterAccount, --publicKey and --initialBalance', @@ -154,7 +154,7 @@ const keys = { }; const stake = { - command: 'stake ', + command: 'stake ', desc: 'create staking transaction', builder: (yargs) => yargs .option('accountId', { @@ -162,7 +162,7 @@ const stake = { type: 'string', required: true, }) - .option('stakeKey', { + .option('stakingKey', { descr: 'Public key to stake with (base58 encoded)', type: 'string', required: true, @@ -182,7 +182,7 @@ const sendMoney = { handler: (argv) => exitOnError(main.sendMoney(argv)) }; -//For transaction: +// For transaction: const txStatus = { command: 'tx-status ', desc: 'lookup transaction status by hash', diff --git a/index.js b/index.js index 19e688a2..91175394 100644 --- a/index.js +++ b/index.js @@ -27,7 +27,7 @@ async function connect(options) { // TODO: Fix promisified wrappers to handle error properly -//For smart contract: +// For smart contract: exports.clean = async function() { const rmDirFn = () => { return new Promise(resolve => { @@ -64,7 +64,7 @@ exports.callViewFunction = async function(options) { console.log(inspectResponse(await account.viewFunction(options.contractName, options.methodName, JSON.parse(options.args || '{}')))); }; -//For account: +// For account: exports.createAccount = async function(options) { let near = await connect(options); let keyPair; @@ -153,14 +153,14 @@ exports.sendMoney = async function(options) { }; exports.stake = async function(options) { - console.log(`Staking ${options.amount} on ${options.accountId} with public key = ${options.stakeKey}.`); + console.log(`Staking ${options.amount} on ${options.accountId} with public key = ${options.stakingKey}.`); const near = await connect(options); const account = await near.account(options.accountId); - const result = await account.stake(options.stakeKey, options.amount); + const result = await account.stake(options.stakingKey, options.amount); console.log(inspectResponse(result)); }; -//For transaction: +// For transaction: exports.txStatus = async function(options) { let near = await connect(options); let status = await near.connection.provider.txStatus(bs58.decode(options.hash), options.accountId || options.masterAccount);