From 5e5c981ba97ae55ccf928b5e96c5d1f5bfc283b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 13:22:28 +0200 Subject: [PATCH 1/9] feat: Improve CLI output Transform CLI tools to TypeScript Add CLI tsconfig file and update build script Fix ESLint types resolution Change argument parser from yargs to commander Add signale logger Add verbose flag Add verbose flag recognition to near-bindgen-exporter --- .eslintrc.cjs | 8 +- cli/cli.d.ts | 4 + cli/cli.js | 257 +++++++++------------ cli/package.json | 74 ++++++ cli/post-install.d.ts | 1 + cli/post-install.js | 86 +++---- cli/save-bytecode.d.ts | 1 + cli/save-bytecode.js | 22 ++ cli/src/cli/cli.d.ts | 4 + cli/src/cli/cli.js | 188 ++++++++++++++++ cli/src/cli/post-install.d.ts | 1 + cli/src/cli/post-install.js | 60 +++++ cli/src/cli/save-bytecode.d.ts | 1 + cli/src/cli/save-bytecode.js | 22 ++ cli/src/cli/utils.d.ts | 1 + cli/src/cli/utils.js | 22 ++ cli/src/cli/wasm-to-bytes.d.ts | 1 + cli/src/cli/wasm-to-bytes.js | 16 ++ cli/utils.d.ts | 1 + cli/utils.js | 42 ++-- cli/wasm-to-bytes.d.ts | 1 + cli/wasm-to-bytes.js | 16 ++ lib/build-tools/include-bytes.js | 26 +-- lib/build-tools/near-bindgen-exporter.js | 6 +- package.json | 13 +- src/build-tools/include-bytes.ts | 30 +-- src/build-tools/near-bindgen-exporter.ts | 10 +- src/cli/cli.ts | 201 +++++++++++++++++ src/cli/post-install.ts | 105 +++++++++ src/cli/save-bytecode.ts | 29 +++ src/cli/utils.ts | 30 +++ src/cli/wasm-to-bytes.ts | 24 ++ tsconfig.cli.json | 24 ++ tsconfig.json | 3 +- yarn.lock | 274 ++++++++++++++++------- 35 files changed, 1254 insertions(+), 350 deletions(-) create mode 100644 cli/cli.d.ts create mode 100644 cli/package.json create mode 100644 cli/post-install.d.ts create mode 100644 cli/save-bytecode.d.ts create mode 100644 cli/save-bytecode.js create mode 100644 cli/src/cli/cli.d.ts create mode 100644 cli/src/cli/cli.js create mode 100644 cli/src/cli/post-install.d.ts create mode 100644 cli/src/cli/post-install.js create mode 100644 cli/src/cli/save-bytecode.d.ts create mode 100644 cli/src/cli/save-bytecode.js create mode 100644 cli/src/cli/utils.d.ts create mode 100644 cli/src/cli/utils.js create mode 100644 cli/src/cli/wasm-to-bytes.d.ts create mode 100644 cli/src/cli/wasm-to-bytes.js create mode 100644 cli/utils.d.ts create mode 100644 cli/wasm-to-bytes.d.ts create mode 100644 cli/wasm-to-bytes.js create mode 100644 src/cli/cli.ts create mode 100644 src/cli/post-install.ts create mode 100644 src/cli/save-bytecode.ts create mode 100644 src/cli/utils.ts create mode 100644 src/cli/wasm-to-bytes.ts create mode 100644 tsconfig.cli.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs index c4c1b4d0e..e3f4f3856 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,3 +1,4 @@ +/** @type {import('eslint').Linter.Config} */ module.exports = { root: true, env: { @@ -16,7 +17,11 @@ module.exports = { parserOptions: { ecmaVersion: "latest", sourceType: "module", - project: ["./{t,j}sconfig.json", "./**/{t,j}sconfig.json"], + project: [ + "./{t,j}sconfig.json", + "./**/{t,j}sconfig.json", + "./tsconfig.cli.json", + ], }, plugins: ["@typescript-eslint"], rules: { @@ -41,6 +46,7 @@ module.exports = { "build", "./**/deps", "deps", + "cli", ], rules: {}, }; diff --git a/cli/cli.d.ts b/cli/cli.d.ts new file mode 100644 index 000000000..10fcdae58 --- /dev/null +++ b/cli/cli.d.ts @@ -0,0 +1,4 @@ +#!/usr/bin/env node +export declare function buildCom(source: string, target: string, { verbose }: { + verbose: boolean; +}): Promise; diff --git a/cli/cli.js b/cli/cli.js index 6858da042..a52018631 100755 --- a/cli/cli.js +++ b/cli/cli.js @@ -1,175 +1,126 @@ #!/usr/bin/env node - import fs from "fs/promises"; -import path from "path"; - -import yargs from "yargs"; -import { hideBin } from "yargs/helpers"; - +import path, { basename, dirname } from "path"; +// import yargs from "yargs"; +// import { hideBin } from "yargs/helpers"; import { nodeResolve } from "@rollup/plugin-node-resolve"; import sourcemaps from "rollup-plugin-sourcemaps"; import { babel } from "@rollup/plugin-babel"; import { rollup } from "rollup"; - +import { Command } from "commander"; +import signal from "signale"; +const { Signale } = signal; import { executeCommand } from "./utils.js"; - const PROJECT_DIR = process.cwd(); const NEAR_SDK_JS = "node_modules/near-sdk-js"; const TSC = "node_modules/.bin/tsc"; const QJSC_DIR = `${NEAR_SDK_JS}/cli/deps/quickjs`; const QJSC = `${NEAR_SDK_JS}/cli/deps/qjsc`; - -yargs(hideBin(process.argv)) - .scriptName("near-sdk-js") - .usage("$0 [args]") - .command( - "build [source] [target]", - "Build NEAR JS Smart-contract", - (yargs) => { - yargs - .positional("source", { - type: "string", - default: "src/index.js", - describe: "Contract to build", - }) - .positional("target", { - type: "string", - default: "build/contract.wasm", - describe: "Target file path and name", - }); - }, - build - ) - .help().argv; - -async function build(argv) { - const SOURCE_FILE_WITH_PATH = argv.source; - const SOURCE_EXT = argv.source.split(".").pop(); - const TARGET_DIR = path.dirname(argv.target); - const TARGET_EXT = argv.target.split(".").pop(); - const TARGET_FILE_NAME = path.basename(argv.target, `.${TARGET_EXT}`); - - if ("wasm" !== TARGET_EXT) { - throw new Error( - `Unsupported target ${TARGET_EXT}, make sure target ends with .wasm` - ); - } - - const ROLLUP_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.js`; - const QJSC_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.h`; - const CONTRACT_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.wasm`; - - console.log(`Building ${SOURCE_FILE_WITH_PATH} contract...`); - - if (SOURCE_EXT === "ts") { - await checkTsBuildWithTsc(SOURCE_FILE_WITH_PATH); - } - - console.log(`Creating ${TARGET_DIR} directory...`); - await executeCommand(`mkdir -p ${TARGET_DIR}`); - - await createJsFileWithRullup(SOURCE_FILE_WITH_PATH, ROLLUP_TARGET); - - await createHeaderFileWithQjsc(ROLLUP_TARGET, QJSC_TARGET); - - await createMethodsHeaderFile(ROLLUP_TARGET); - await createWasmContract(QJSC_TARGET, CONTRACT_TARGET); - await wasiStubContract(CONTRACT_TARGET); +const program = new Command(); +program + .name("near-sdk-js") + .addCommand(new Command("build") + .usage("[source] [target]") + .description("Build NEAR JS Smart-contract") + .argument("[source]", "Contract to build.", "src/index.js") + .argument("[target]", "Target file path and name.", "build/contract.wasm") + .option("--verbose", "Whether to print more verbose output.", false) + .action(buildCom)) + .parse(); +export async function buildCom(source, target, { verbose = false }) { + const SOURCE_EXT = source.split(".").pop(); + const TARGET_DIR = dirname(target); + const TARGET_EXT = target.split(".").pop(); + const TARGET_FILE_NAME = basename(target, `.${TARGET_EXT}`); + const signale = new Signale({ scope: "build", interactive: true }); + if (TARGET_EXT !== "wasm") { + signale.error(`Unsupported target ${TARGET_EXT}, make sure target ends with .wasm!`); + process.exit(1); + } + const ROLLUP_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.js`; + const QJSC_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.h`; + const CONTRACT_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.wasm`; + signale.await(`Building ${source} contract...`); + if (SOURCE_EXT === "ts") { + signale.await(`Typechecking ${source} with tsc...`); + await checkTsBuildWithTsc(source, verbose); + } + signale.await(`Creating ${TARGET_DIR} directory...`); + await executeCommand(`mkdir -p ${TARGET_DIR}`, verbose); + signale.await(`Creating ${source} file with Rollup...`); + await createJsFileWithRullup(source, ROLLUP_TARGET, verbose); + signale.await(`Creating ${QJSC_TARGET} file with QJSC...`); + await createHeaderFileWithQjsc(ROLLUP_TARGET, QJSC_TARGET, verbose); + signale.await("Generating methods.h file..."); + await createMethodsHeaderFile(ROLLUP_TARGET, verbose); + signale.await(`Creating ${CONTRACT_TARGET} contract...`); + await createWasmContract(QJSC_TARGET, CONTRACT_TARGET, verbose); + signale.await("Executing wasi-stub..."); + await wasiStubContract(CONTRACT_TARGET, verbose); + signale.success(`Generated ${CONTRACT_TARGET} contract successfully!`); } - -async function checkTsBuildWithTsc(sourceFileWithPath) { - console.log(`check TypeScript build of ${sourceFileWithPath} with tsc`); - await executeCommand( - `${TSC} --noEmit --experimentalDecorators --target es2020 --moduleResolution node ${sourceFileWithPath}` - ); +async function checkTsBuildWithTsc(sourceFileWithPath, verbose = false) { + await executeCommand(`${TSC} --noEmit --experimentalDecorators --target es2020 --moduleResolution node ${sourceFileWithPath}`, verbose); } - // Common build function -async function createJsFileWithRullup(sourceFileWithPath, rollupTarget) { - console.log(`Creating ${rollupTarget} file with Rollup...`); - const bundle = await rollup({ - input: sourceFileWithPath, - plugins: [ - nodeResolve({ - extensions: [".js", ".ts"], - }), - sourcemaps(), - // commonjs(), - babel({ - babelHelpers: "bundled", - extensions: [".ts", ".js", ".jsx", ".es6", ".es", ".mjs"], - presets: ["@babel/preset-typescript"], +async function createJsFileWithRullup(sourceFileWithPath, rollupTarget, verbose = false) { + const bundle = await rollup({ + input: sourceFileWithPath, plugins: [ - "near-sdk-js/lib/build-tools/include-bytes.js", - "near-sdk-js/lib/build-tools/near-bindgen-exporter.js", - ["@babel/plugin-proposal-decorators", { version: "legacy" }], + nodeResolve({ + extensions: [".js", ".ts"], + }), + sourcemaps(), + // commonjs(), + babel({ + babelHelpers: "bundled", + extensions: [".ts", ".js", ".jsx", ".es6", ".es", ".mjs"], + presets: ["@babel/preset-typescript"], + plugins: [ + "near-sdk-js/lib/build-tools/include-bytes.js", + ["near-sdk-js/lib/build-tools/near-bindgen-exporter.js", { verbose }], + ["@babel/plugin-proposal-decorators", { version: "legacy" }], + ], + }), ], - }), - ], - }); - - await bundle.write({ - sourcemap: true, - file: rollupTarget, - format: "es", - }); + }); + await bundle.write({ + sourcemap: true, + file: rollupTarget, + format: "es", + }); } - -async function createHeaderFileWithQjsc(rollupTarget, qjscTarget) { - console.log(`Creating ${qjscTarget} file with QJSC...`); - await executeCommand( - `${QJSC} -c -m -o ${qjscTarget} -N code ${rollupTarget}` - ); +async function createHeaderFileWithQjsc(rollupTarget, qjscTarget, verbose = false) { + await executeCommand(`${QJSC} -c -m -o ${qjscTarget} -N code ${rollupTarget}`, verbose); } - -async function createMethodsHeaderFile(rollupTarget) { - console.log(`Genereting methods.h file`); - - const source = rollupTarget; - const buildPath = path.dirname(source); - - console.log(rollupTarget); - - const mod = await import(`${PROJECT_DIR}/${rollupTarget}`); - const exportNames = Object.keys(mod); - const methods = exportNames.reduce( - (result, key) => `${result}DEFINE_NEAR_METHOD(${key})\n`, - "" - ); - - await fs.writeFile(`${buildPath}/methods.h`, methods); +async function createMethodsHeaderFile(rollupTarget, verbose = false) { + const buildPath = path.dirname(rollupTarget); + if (verbose) { + console.log(rollupTarget); + } + const mod = await import(`${PROJECT_DIR}/${rollupTarget}`); + const exportNames = Object.keys(mod); + const methods = exportNames.reduce((result, key) => `${result}DEFINE_NEAR_METHOD(${key})\n`, ""); + await fs.writeFile(`${buildPath}/methods.h`, methods); } - -async function createWasmContract(qjscTarget, contractTarget) { - console.log(`Creating ${contractTarget} contract...`); - const WASI_SDK_PATH = `${NEAR_SDK_JS}/cli/deps/wasi-sdk`; - - const CC = `${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot`; - let DEFS = `-D_GNU_SOURCE '-DCONFIG_VERSION="2021-03-27"' -DCONFIG_BIGNUM`; - - if (process.env.NEAR_NIGHTLY) { - DEFS = DEFS + " -DNIGHTLY"; - } - - const INCLUDES = `-I${QJSC_DIR} -I.`; - const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/cli/builder/builder.c`; - const NEW_BUILDER_PATH = `${path.dirname(contractTarget)}/builder.c`; - const SOURCES = `${NEW_BUILDER_PATH} ${QJSC_DIR}/quickjs.c ${QJSC_DIR}/libregexp.c ${QJSC_DIR}/libunicode.c ${QJSC_DIR}/cutils.c ${QJSC_DIR}/quickjs-libc-min.c ${QJSC_DIR}/libbf.c`; - const LIBS = `-lm`; - - // copying builder.c file to the build folder - await executeCommand(`cp ${ORIGINAL_BUILDER_PATH} ${NEW_BUILDER_PATH}`); - await executeCommand(`mv ${qjscTarget} build/code.h`); - - await executeCommand( - `${CC} --target=wasm32-wasi -nostartfiles -Oz -flto ${DEFS} ${INCLUDES} ${SOURCES} ${LIBS} -Wl,--no-entry -Wl,--allow-undefined -Wl,-z,stack-size=${ - 256 * 1024 - } -Wl,--lto-O3 -o ${contractTarget}` - ); +async function createWasmContract(qjscTarget, contractTarget, verbose = false) { + const WASI_SDK_PATH = `${NEAR_SDK_JS}/cli/deps/wasi-sdk`; + const CC = `${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot`; + let DEFS = `-D_GNU_SOURCE '-DCONFIG_VERSION="2021-03-27"' -DCONFIG_BIGNUM`; + if (process.env.NEAR_NIGHTLY) { + DEFS = DEFS + " -DNIGHTLY"; + } + const INCLUDES = `-I${QJSC_DIR} -I.`; + const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/cli/builder/builder.c`; + const NEW_BUILDER_PATH = `${path.dirname(contractTarget)}/builder.c`; + const SOURCES = `${NEW_BUILDER_PATH} ${QJSC_DIR}/quickjs.c ${QJSC_DIR}/libregexp.c ${QJSC_DIR}/libunicode.c ${QJSC_DIR}/cutils.c ${QJSC_DIR}/quickjs-libc-min.c ${QJSC_DIR}/libbf.c`; + const LIBS = `-lm`; + // copying builder.c file to the build folder + await executeCommand(`cp ${ORIGINAL_BUILDER_PATH} ${NEW_BUILDER_PATH}`, verbose); + await executeCommand(`mv ${qjscTarget} build/code.h`, verbose); + await executeCommand(`${CC} --target=wasm32-wasi -nostartfiles -Oz -flto ${DEFS} ${INCLUDES} ${SOURCES} ${LIBS} -Wl,--no-entry -Wl,--allow-undefined -Wl,-z,stack-size=${256 * 1024} -Wl,--lto-O3 -o ${contractTarget}`, verbose); } - -async function wasiStubContract(contractTarget) { - console.log(`Executing wasi-stub...`); - const WASI_STUB = `${NEAR_SDK_JS}/cli/deps/binaryen/wasi-stub/run.sh`; - await executeCommand(`${WASI_STUB} ${contractTarget} >/dev/null`); +async function wasiStubContract(contractTarget, verbose = false) { + const WASI_STUB = `${NEAR_SDK_JS}/cli/deps/binaryen/wasi-stub/run.sh`; + await executeCommand(`${WASI_STUB} ${contractTarget} >/dev/null`, verbose); } diff --git a/cli/package.json b/cli/package.json new file mode 100644 index 000000000..881a5a4b6 --- /dev/null +++ b/cli/package.json @@ -0,0 +1,74 @@ +{ + "name": "near-sdk-js", + "version": "0.5.0-1", + "description": "High Level JavaScript SDK for building smart contracts on NEAR", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "type": "module", + "repository": { + "type": "git", + "url": "git+https://github.com/near/near-sdk-js.git" + }, + "homepage": "https://github.com/near/near-sdk-js", + "keywords": [ + "JS", + "JavaScript", + "NEAR", + "SDK", + "contract", + "smart", + "smart-contract" + ], + "license": "(MIT AND Apache-2.0)", + "scripts": { + "build": "yarn build:lib && yarn build:cli", + "build:lib": "tsc -p ./tsconfig.json", + "build:cli": "tsc -p ./tsconfig.cli.json", + "pretest": "yarn build", + "test": "yarn test:unit && yarn test:examples", + "lint": "eslint --fix .", + "format": "prettier --write .", + "test:unit": "yarn && cd tests && yarn && yarn build && yarn test && cd ..", + "test:examples": "yarn && cd examples && yarn && yarn build && yarn test && cd ..", + "postinstall": "cd cli && rm -rf deps && mkdir -p deps && cd deps && node ../post-install.js" + }, + "bin": { + "near-sdk-js": "cli/cli.js" + }, + "engines": { + "node": ">=14 <16.6.0 || >16.6.0" + }, + "author": "Near Inc ", + "dependencies": { + "@babel/core": "^7.17.5", + "@babel/plugin-proposal-decorators": "^7.17.2", + "@babel/preset-typescript": "^7.18.6", + "@rollup/plugin-babel": "^5.3.1", + "@rollup/plugin-commonjs": "^21.0.1", + "@rollup/plugin-node-resolve": "^13.1.1", + "@scure/base": "^1.1.1", + "commander": "^9.4.1", + "rollup": "^2.61.1", + "rollup-plugin-sourcemaps": "^0.6.3", + "signale": "^1.4.0", + "yargs": "^17.5.1" + }, + "files": [ + "cli", + "lib" + ], + "devDependencies": { + "@rollup/plugin-typescript": "^8.3.2", + "@types/babel__traverse": "^7.18.1", + "@types/node": "^17.0.38", + "@types/rollup": "^0.54.0", + "@types/signale": "^1.4.4", + "@types/yargs": "^17.0.13", + "@typescript-eslint/eslint-plugin": "^5.37.0", + "@typescript-eslint/parser": "^5.37.0", + "eslint": "^8.23.1", + "eslint-config-prettier": "^8.5.0", + "prettier": "^2.7.1", + "typescript": "^4.7.2" + } +} diff --git a/cli/post-install.d.ts b/cli/post-install.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/cli/post-install.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/cli/post-install.js b/cli/post-install.js index d87998b7e..00dc17b2f 100644 --- a/cli/post-install.js +++ b/cli/post-install.js @@ -1,98 +1,64 @@ import { executeCommand } from "./utils.js"; - -async function download(url) { - await executeCommand(`curl -LOf ${url}`); +import signal from "signale"; +const { Signale } = signal; +const signale = new Signale({ scope: "postinstall", interactive: true }); +async function download(url, verbose = false) { + await executeCommand(`curl -LOf ${url}`, verbose); } - -const OS = await executeCommand("uname -s", true); -const ARCH = await executeCommand("uname -m", true); - +const OS = await executeCommand("uname -s", false); +const ARCH = await executeCommand("uname -m", false); if (OS !== "Linux" && OS !== "Darwin") { - console.error(`OS ${OS} is not supported at the moment`); - process.exit(1); + console.error(`OS ${OS} is not supported at the moment`); + process.exit(1); } - if (ARCH !== "x86_64" && ARCH !== "arm64") { - console.error(` ${ARCH} architecture is unsapported at the moment`); - process.exit(1); + console.error(` ${ARCH} architecture is unsapported at the moment`); + process.exit(1); } - -console.log("Installing wasi-stub..."); - +signale.await("Installing wasi-stub..."); const BINARYEN_VERSION = `0.1.10`; const BINARYEN_VERSION_TAG = `v${BINARYEN_VERSION}`; -const BINARYEN_SYSTEM_NAME = - OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; -const BINARYEN_ARCH_NAME = - ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; +const BINARYEN_SYSTEM_NAME = OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; +const BINARYEN_ARCH_NAME = ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; const BINARYEN_TAR_NAME = `binaryen-${BINARYEN_SYSTEM_NAME}-${BINARYEN_ARCH_NAME}.tar.gz`; - -await download( - `https://github.com/near/binaryen/releases/download/${BINARYEN_VERSION_TAG}/${BINARYEN_TAR_NAME}` -); -await executeCommand( - `mkdir -p binaryen && tar xvf ${BINARYEN_TAR_NAME} --directory binaryen` -); +await download(`https://github.com/near/binaryen/releases/download/${BINARYEN_VERSION_TAG}/${BINARYEN_TAR_NAME}`); +await executeCommand(`mkdir -p binaryen && tar xvf ${BINARYEN_TAR_NAME} --directory binaryen`); await executeCommand(`rm ${BINARYEN_TAR_NAME}`); - -console.log("Installing QuickJS..."); - +signale.await("Installing QuickJS..."); const QUICK_JS_VERSION = `0.1.2`; const QUICK_JS_VERSION_TAG = `v${QUICK_JS_VERSION}`; -const QUICK_JS_SYSTEM_NAME = - OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; -const QUICK_JS_ARCH_NAME = - ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; +const QUICK_JS_SYSTEM_NAME = OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; +const QUICK_JS_ARCH_NAME = ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; const QUICK_JS_TAR_NAME = `${QUICK_JS_VERSION_TAG}.tar.gz`; const QUICK_JS_DOWNLOADED_FOLDER_NAME = `quickjs-${QUICK_JS_VERSION}`; const QUICK_JS_TARGET_FOLDER_NAME = "quickjs"; const QUICK_JS_DOWNLOADED_NAME = `qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}`; const QUICK_JS_TARGET_NAME = "qjsc"; - // Download QuickJS -await download( - `https://github.com/near/quickjs/releases/download/${QUICK_JS_VERSION_TAG}/qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}` -); -await download( - `https://github.com/near/quickjs/archive/refs/tags/${QUICK_JS_VERSION_TAG}.tar.gz` -); - +await download(`https://github.com/near/quickjs/releases/download/${QUICK_JS_VERSION_TAG}/qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}`); +await download(`https://github.com/near/quickjs/archive/refs/tags/${QUICK_JS_VERSION_TAG}.tar.gz`); // Extract QuickJS await executeCommand(`tar xvf ${QUICK_JS_TAR_NAME}`); - // Delete .tar file await executeCommand(`rm ${QUICK_JS_TAR_NAME}`); - // Delete version from folder name -await executeCommand( - `mv ${QUICK_JS_DOWNLOADED_FOLDER_NAME} ${QUICK_JS_TARGET_FOLDER_NAME}` -); - +await executeCommand(`mv ${QUICK_JS_DOWNLOADED_FOLDER_NAME} ${QUICK_JS_TARGET_FOLDER_NAME}`); // Rename qjsc file await executeCommand(`mv ${QUICK_JS_DOWNLOADED_NAME} ${QUICK_JS_TARGET_NAME}`); - // chmod qjsc await executeCommand(`chmod 777 ${QUICK_JS_TARGET_NAME}`); - -console.log("Installing wasi-sdk..."); - +signale.await("Installing wasi-sdk..."); const WASI_SDK_MAJOR_VER = 11; const WASI_SDK_MINOR_VER = 0; const WASI_SDK_DOWNLOADED_FOLDER_NAME = `wasi-sdk-${WASI_SDK_MAJOR_VER}.${WASI_SDK_MINOR_VER}`; -const WASI_SDK_SYSTEM_NAME = - OS === "Linux" ? "linux" : OS === "Darwin" ? "macos" : "other"; +const WASI_SDK_SYSTEM_NAME = OS === "Linux" ? "linux" : OS === "Darwin" ? "macos" : "other"; const WASI_SDK_TAR_NAME = `${WASI_SDK_DOWNLOADED_FOLDER_NAME}-${WASI_SDK_SYSTEM_NAME}.tar.gz`; - // Download WASI SDK -await download( - `https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_MAJOR_VER}/${WASI_SDK_TAR_NAME}` -); - +await download(`https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_MAJOR_VER}/${WASI_SDK_TAR_NAME}`); // Extract WASI SDK await executeCommand(`tar xvf ${WASI_SDK_TAR_NAME}`); - // Delete .tar file await executeCommand(`rm ${WASI_SDK_TAR_NAME}`); - // Delete version from folder name await executeCommand(`mv ${WASI_SDK_DOWNLOADED_FOLDER_NAME} wasi-sdk`); +signale.success("Successfully finished postinstall script!"); diff --git a/cli/save-bytecode.d.ts b/cli/save-bytecode.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/cli/save-bytecode.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/cli/save-bytecode.js b/cli/save-bytecode.js new file mode 100644 index 000000000..6adcb4ccd --- /dev/null +++ b/cli/save-bytecode.js @@ -0,0 +1,22 @@ +import { readFile, writeFile } from "fs/promises"; +import { resolve } from "path"; +//TODO: execute it in js env +async function main() { + const source = resolve(process.argv[process.argv.length - 2]); + const target = resolve(process.argv[process.argv.length - 1]); + const code = await readFile(source, "utf-8"); + const codes = code + .split("\n") + .map((line) => { + if (line.indexOf("0x") < 0) { + return []; + } + const trimmedLine = line.trim(); + const numbers = trimmedLine.slice(0, trimmedLine.length - 1).split(", "); + return numbers.map(Number); + }) + .filter((numbers) => numbers.length); + const bytecode = Buffer.concat(codes.map(Buffer.from)); + await writeFile(target, bytecode.toString("base64")); +} +main(); diff --git a/cli/src/cli/cli.d.ts b/cli/src/cli/cli.d.ts new file mode 100644 index 000000000..10fcdae58 --- /dev/null +++ b/cli/src/cli/cli.d.ts @@ -0,0 +1,4 @@ +#!/usr/bin/env node +export declare function buildCom(source: string, target: string, { verbose }: { + verbose: boolean; +}): Promise; diff --git a/cli/src/cli/cli.js b/cli/src/cli/cli.js new file mode 100644 index 000000000..22688d320 --- /dev/null +++ b/cli/src/cli/cli.js @@ -0,0 +1,188 @@ +#!/usr/bin/env node +import fs from "fs/promises"; +import path, { basename, dirname } from "path"; +// import yargs from "yargs"; +// import { hideBin } from "yargs/helpers"; +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import sourcemaps from "rollup-plugin-sourcemaps"; +import { babel } from "@rollup/plugin-babel"; +import { rollup } from "rollup"; +import { Command } from "commander"; +import signal from "signale"; +const { Signale } = signal; +import { executeCommand } from "./utils.js"; +const PROJECT_DIR = process.cwd(); +const NEAR_SDK_JS = "node_modules/near-sdk-js"; +const TSC = "node_modules/.bin/tsc"; +const QJSC_DIR = `${NEAR_SDK_JS}/cli/deps/quickjs`; +const QJSC = `${NEAR_SDK_JS}/cli/deps/qjsc`; +const program = new Command(); +function makeBuildCommand() { + return new Command("build") + .usage("[source] [target]") + .description("Build NEAR JS Smart-contract") + .argument("[source]", "Contract to build.", "src/index.js") + .argument("[target]", "Target file path and name.", "build/contract.wasm") + .option("--verbose", "Whether to print more verbose output.", false) + .action(console.log); +} +program + .name("near-sdk-js") + .version((await import("../../package.json", { assert: { type: "json" } })).version) + .addCommand(makeBuildCommand()) + .parse(); +export async function buildCom(source, target, { verbose = false }) { + console.log(source, target); + const SOURCE_EXT = source.split(".").pop(); + const TARGET_DIR = dirname(target); + const TARGET_EXT = target.split(".").pop(); + const TARGET_FILE_NAME = basename(target, `.${TARGET_EXT}`); + const signale = new Signale({ scope: "near-sdk-js", interactive: true }); + if (TARGET_EXT !== "wasm") { + signale.error(`Unsupported target ${TARGET_EXT}, make sure target ends with .wasm!`); + process.exit(1); + } + const ROLLUP_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.js`; + const QJSC_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.h`; + const CONTRACT_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.wasm`; + signale.await(`Building ${source} contract...`); + if (SOURCE_EXT === "ts") { + signale.await(`Typechecking ${source} with tsc...`); + await checkTsBuildWithTsc(source, verbose); + } + signale.await(`Creating ${TARGET_DIR} directory...`); + await executeCommand(`mkdir -p ${TARGET_DIR}`, verbose); + signale.await(`Creating ${source} file with Rollup...`); + await createJsFileWithRullup(source, ROLLUP_TARGET, verbose); + signale.await(`Creating ${QJSC_TARGET} file with QJSC...`); + await createHeaderFileWithQjsc(ROLLUP_TARGET, QJSC_TARGET, verbose); + signale.await("Generating methods.h file..."); + await createMethodsHeaderFile(ROLLUP_TARGET, verbose); + signale.await(`Creating ${CONTRACT_TARGET} contract...`); + await createWasmContract(QJSC_TARGET, CONTRACT_TARGET, verbose); + signale.await("Executing wasi-stub..."); + await wasiStubContract(CONTRACT_TARGET, verbose); + signale.success("Generated contract successfully!"); +} +// yargs(hideBin(process.argv)) +// .scriptName("near-sdk-js") +// .usage("$0 [args]") +// .command( +// "build [source] [target]", +// "Build NEAR JS Smart-contract", +// (yargs) => { +// yargs +// .positional("source", { +// type: "string", +// default: "src/index.js", +// describe: "Contract to build", +// }) +// .positional("target", { +// type: "string", +// default: "build/contract.wasm", +// describe: "Target file path and name", +// }); +// }, +// build +// ) +// .help().argv; +// +// async function build(argv: yargs.ArgumentsCamelCase): Promise { +// const SOURCE_FILE_WITH_PATH = argv.source; +// const SOURCE_EXT = argv.source.split(".").pop(); +// const TARGET_DIR = path.dirname(argv.target); +// const TARGET_EXT = argv.target.split(".").pop(); +// const TARGET_FILE_NAME = path.basename(argv.target, `.${TARGET_EXT}`); +// +// if ("wasm" !== TARGET_EXT) { +// throw new Error( +// `Unsupported target ${TARGET_EXT}, make sure target ends with .wasm` +// ); +// } +// +// const ROLLUP_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.js`; +// const QJSC_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.h`; +// const CONTRACT_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.wasm`; +// +// console.log(`Building ${SOURCE_FILE_WITH_PATH} contract...`); +// +// if (SOURCE_EXT === "ts") { +// await checkTsBuildWithTsc(SOURCE_FILE_WITH_PATH); +// } +// +// console.log(`Creating ${TARGET_DIR} directory...`); +// await executeCommand(`mkdir -p ${TARGET_DIR}`); +// +// await createJsFileWithRullup(SOURCE_FILE_WITH_PATH, ROLLUP_TARGET); +// +// await createHeaderFileWithQjsc(ROLLUP_TARGET, QJSC_TARGET); +// +// await createMethodsHeaderFile(ROLLUP_TARGET); +// await createWasmContract(QJSC_TARGET, CONTRACT_TARGET); +// await wasiStubContract(CONTRACT_TARGET); +// } +async function checkTsBuildWithTsc(sourceFileWithPath, verbose = false) { + await executeCommand(`${TSC} --noEmit --experimentalDecorators --target es2020 --moduleResolution node ${sourceFileWithPath}`, verbose); +} +// Common build function +async function createJsFileWithRullup(sourceFileWithPath, rollupTarget, _verbose = false) { + const bundle = await rollup({ + input: sourceFileWithPath, + plugins: [ + nodeResolve({ + extensions: [".js", ".ts"], + }), + sourcemaps(), + // commonjs(), + babel({ + babelHelpers: "bundled", + extensions: [".ts", ".js", ".jsx", ".es6", ".es", ".mjs"], + presets: ["@babel/preset-typescript"], + plugins: [ + "near-sdk-js/lib/build-tools/include-bytes.js", + "near-sdk-js/lib/build-tools/near-bindgen-exporter.js", + ["@babel/plugin-proposal-decorators", { version: "legacy" }], + ], + }), + ], + }); + await bundle.write({ + sourcemap: true, + file: rollupTarget, + format: "es", + }); +} +async function createHeaderFileWithQjsc(rollupTarget, qjscTarget, verbose = false) { + await executeCommand(`${QJSC} -c -m -o ${qjscTarget} -N code ${rollupTarget}`, verbose); +} +async function createMethodsHeaderFile(rollupTarget, verbose = false) { + const buildPath = path.dirname(rollupTarget); + if (verbose) { + console.log(rollupTarget); + } + const mod = await import(`${PROJECT_DIR}/${rollupTarget}`); + const exportNames = Object.keys(mod); + const methods = exportNames.reduce((result, key) => `${result}DEFINE_NEAR_METHOD(${key})\n`, ""); + await fs.writeFile(`${buildPath}/methods.h`, methods); +} +async function createWasmContract(qjscTarget, contractTarget, verbose = false) { + const WASI_SDK_PATH = `${NEAR_SDK_JS}/cli/deps/wasi-sdk`; + const CC = `${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot`; + let DEFS = `-D_GNU_SOURCE '-DCONFIG_VERSION="2021-03-27"' -DCONFIG_BIGNUM`; + if (process.env.NEAR_NIGHTLY) { + DEFS = DEFS + " -DNIGHTLY"; + } + const INCLUDES = `-I${QJSC_DIR} -I.`; + const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/cli/builder/builder.c`; + const NEW_BUILDER_PATH = `${path.dirname(contractTarget)}/builder.c`; + const SOURCES = `${NEW_BUILDER_PATH} ${QJSC_DIR}/quickjs.c ${QJSC_DIR}/libregexp.c ${QJSC_DIR}/libunicode.c ${QJSC_DIR}/cutils.c ${QJSC_DIR}/quickjs-libc-min.c ${QJSC_DIR}/libbf.c`; + const LIBS = `-lm`; + // copying builder.c file to the build folder + await executeCommand(`cp ${ORIGINAL_BUILDER_PATH} ${NEW_BUILDER_PATH}`, verbose); + await executeCommand(`mv ${qjscTarget} build/code.h`, verbose); + await executeCommand(`${CC} --target=wasm32-wasi -nostartfiles -Oz -flto ${DEFS} ${INCLUDES} ${SOURCES} ${LIBS} -Wl,--no-entry -Wl,--allow-undefined -Wl,-z,stack-size=${256 * 1024} -Wl,--lto-O3 -o ${contractTarget}`, verbose); +} +async function wasiStubContract(contractTarget, verbose = false) { + const WASI_STUB = `${NEAR_SDK_JS}/cli/deps/binaryen/wasi-stub/run.sh`; + await executeCommand(`${WASI_STUB} ${contractTarget} >/dev/null`, verbose); +} diff --git a/cli/src/cli/post-install.d.ts b/cli/src/cli/post-install.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/cli/src/cli/post-install.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/cli/src/cli/post-install.js b/cli/src/cli/post-install.js new file mode 100644 index 000000000..698539638 --- /dev/null +++ b/cli/src/cli/post-install.js @@ -0,0 +1,60 @@ +import { executeCommand } from "./utils.js"; +async function download(url, verbose = false) { + await executeCommand(`curl -LOf ${url}`, verbose); +} +const OS = await executeCommand("uname -s", false); +const ARCH = await executeCommand("uname -m", false); +if (OS !== "Linux" && OS !== "Darwin") { + console.error(`OS ${OS} is not supported at the moment`); + process.exit(1); +} +if (ARCH !== "x86_64" && ARCH !== "arm64") { + console.error(` ${ARCH} architecture is unsapported at the moment`); + process.exit(1); +} +console.log("Installing wasi-stub..."); +const BINARYEN_VERSION = `0.1.10`; +const BINARYEN_VERSION_TAG = `v${BINARYEN_VERSION}`; +const BINARYEN_SYSTEM_NAME = OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; +const BINARYEN_ARCH_NAME = ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; +const BINARYEN_TAR_NAME = `binaryen-${BINARYEN_SYSTEM_NAME}-${BINARYEN_ARCH_NAME}.tar.gz`; +await download(`https://github.com/near/binaryen/releases/download/${BINARYEN_VERSION_TAG}/${BINARYEN_TAR_NAME}`); +await executeCommand(`mkdir -p binaryen && tar xvf ${BINARYEN_TAR_NAME} --directory binaryen`); +await executeCommand(`rm ${BINARYEN_TAR_NAME}`); +console.log("Installing QuickJS..."); +const QUICK_JS_VERSION = `0.1.2`; +const QUICK_JS_VERSION_TAG = `v${QUICK_JS_VERSION}`; +const QUICK_JS_SYSTEM_NAME = OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; +const QUICK_JS_ARCH_NAME = ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; +const QUICK_JS_TAR_NAME = `${QUICK_JS_VERSION_TAG}.tar.gz`; +const QUICK_JS_DOWNLOADED_FOLDER_NAME = `quickjs-${QUICK_JS_VERSION}`; +const QUICK_JS_TARGET_FOLDER_NAME = "quickjs"; +const QUICK_JS_DOWNLOADED_NAME = `qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}`; +const QUICK_JS_TARGET_NAME = "qjsc"; +// Download QuickJS +await download(`https://github.com/near/quickjs/releases/download/${QUICK_JS_VERSION_TAG}/qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}`); +await download(`https://github.com/near/quickjs/archive/refs/tags/${QUICK_JS_VERSION_TAG}.tar.gz`); +// Extract QuickJS +await executeCommand(`tar xvf ${QUICK_JS_TAR_NAME}`); +// Delete .tar file +await executeCommand(`rm ${QUICK_JS_TAR_NAME}`); +// Delete version from folder name +await executeCommand(`mv ${QUICK_JS_DOWNLOADED_FOLDER_NAME} ${QUICK_JS_TARGET_FOLDER_NAME}`); +// Rename qjsc file +await executeCommand(`mv ${QUICK_JS_DOWNLOADED_NAME} ${QUICK_JS_TARGET_NAME}`); +// chmod qjsc +await executeCommand(`chmod 777 ${QUICK_JS_TARGET_NAME}`); +console.log("Installing wasi-sdk..."); +const WASI_SDK_MAJOR_VER = 11; +const WASI_SDK_MINOR_VER = 0; +const WASI_SDK_DOWNLOADED_FOLDER_NAME = `wasi-sdk-${WASI_SDK_MAJOR_VER}.${WASI_SDK_MINOR_VER}`; +const WASI_SDK_SYSTEM_NAME = OS === "Linux" ? "linux" : OS === "Darwin" ? "macos" : "other"; +const WASI_SDK_TAR_NAME = `${WASI_SDK_DOWNLOADED_FOLDER_NAME}-${WASI_SDK_SYSTEM_NAME}.tar.gz`; +// Download WASI SDK +await download(`https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_MAJOR_VER}/${WASI_SDK_TAR_NAME}`); +// Extract WASI SDK +await executeCommand(`tar xvf ${WASI_SDK_TAR_NAME}`); +// Delete .tar file +await executeCommand(`rm ${WASI_SDK_TAR_NAME}`); +// Delete version from folder name +await executeCommand(`mv ${WASI_SDK_DOWNLOADED_FOLDER_NAME} wasi-sdk`); diff --git a/cli/src/cli/save-bytecode.d.ts b/cli/src/cli/save-bytecode.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/cli/src/cli/save-bytecode.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/cli/src/cli/save-bytecode.js b/cli/src/cli/save-bytecode.js new file mode 100644 index 000000000..6adcb4ccd --- /dev/null +++ b/cli/src/cli/save-bytecode.js @@ -0,0 +1,22 @@ +import { readFile, writeFile } from "fs/promises"; +import { resolve } from "path"; +//TODO: execute it in js env +async function main() { + const source = resolve(process.argv[process.argv.length - 2]); + const target = resolve(process.argv[process.argv.length - 1]); + const code = await readFile(source, "utf-8"); + const codes = code + .split("\n") + .map((line) => { + if (line.indexOf("0x") < 0) { + return []; + } + const trimmedLine = line.trim(); + const numbers = trimmedLine.slice(0, trimmedLine.length - 1).split(", "); + return numbers.map(Number); + }) + .filter((numbers) => numbers.length); + const bytecode = Buffer.concat(codes.map(Buffer.from)); + await writeFile(target, bytecode.toString("base64")); +} +main(); diff --git a/cli/src/cli/utils.d.ts b/cli/src/cli/utils.d.ts new file mode 100644 index 000000000..2361fd683 --- /dev/null +++ b/cli/src/cli/utils.d.ts @@ -0,0 +1 @@ +export declare function executeCommand(command: string, silent?: boolean): Promise; diff --git a/cli/src/cli/utils.js b/cli/src/cli/utils.js new file mode 100644 index 000000000..a11d66902 --- /dev/null +++ b/cli/src/cli/utils.js @@ -0,0 +1,22 @@ +import childProcess from "child_process"; +import { promisify } from "util"; +const exec = promisify(childProcess.exec); +export async function executeCommand(command, silent = false) { + if (!silent) { + console.log(command); + } + try { + const { stdout, stderr } = await exec(command); + if (stderr && !silent) { + console.error(stderr); + } + if (!silent) { + console.log(stdout); + } + return stdout.trim(); + } + catch (error) { + console.log(error); + process.exit(1); + } +} diff --git a/cli/src/cli/wasm-to-bytes.d.ts b/cli/src/cli/wasm-to-bytes.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/cli/src/cli/wasm-to-bytes.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/cli/src/cli/wasm-to-bytes.js b/cli/src/cli/wasm-to-bytes.js new file mode 100644 index 000000000..adc1018cd --- /dev/null +++ b/cli/src/cli/wasm-to-bytes.js @@ -0,0 +1,16 @@ +import { readFile, writeFile } from "fs/promises"; +import { resolve } from "path"; +// used for deploy code in contract with near.promiseBatchActionDeployContract. +// Usage: +// node wasm_to_bytes.js contract.wasm contract.jsbytes +// copy paste the content of the contract.jsbytes, pass it as arguments to near.promiseBatchActionDeployContract: +// near.promiseBatchActionDeployContract(promsieId, '') +// Note, do not use `bytes()` type check here, which is too expensive for this long bytes and will exceed gas limit. +async function main() { + const source = resolve(process.argv[process.argv.length - 2]); + const target = resolve(process.argv[process.argv.length - 1]); + const code = await readFile(source); + const result = code.reduce((result, character) => `${result}\\x${character.toString(16).padStart(2, "0")}`, ""); + await writeFile(target, result); +} +main(); diff --git a/cli/utils.d.ts b/cli/utils.d.ts new file mode 100644 index 000000000..4fdb6d3f2 --- /dev/null +++ b/cli/utils.d.ts @@ -0,0 +1 @@ +export declare function executeCommand(command: string, verbose?: boolean): Promise; diff --git a/cli/utils.js b/cli/utils.js index 87733a807..725944ba1 100644 --- a/cli/utils.js +++ b/cli/utils.js @@ -1,24 +1,22 @@ -import { exec as exec_ } from "child_process"; +import childProcess from "child_process"; import { promisify } from "util"; - -const exec = promisify(exec_); - -export async function executeCommand(command, silent = false) { - console.log(command); - const { error, stdout, stderr } = await exec(command); - - if (error) { - console.log(error); - process.exit(1); - } - - if (stderr && !silent) { - console.error(stderr); - } - - if (silent) { - return stdout.trim(); - } - - console.log(stdout); +const exec = promisify(childProcess.exec); +export async function executeCommand(command, verbose = false) { + if (verbose) { + console.log(command); + } + try { + const { stdout, stderr } = await exec(command); + if (stderr && verbose) { + console.error(stderr); + } + if (verbose) { + console.log(stdout); + } + return stdout.trim(); + } + catch (error) { + console.log(error); + process.exit(1); + } } diff --git a/cli/wasm-to-bytes.d.ts b/cli/wasm-to-bytes.d.ts new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/cli/wasm-to-bytes.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/cli/wasm-to-bytes.js b/cli/wasm-to-bytes.js new file mode 100644 index 000000000..adc1018cd --- /dev/null +++ b/cli/wasm-to-bytes.js @@ -0,0 +1,16 @@ +import { readFile, writeFile } from "fs/promises"; +import { resolve } from "path"; +// used for deploy code in contract with near.promiseBatchActionDeployContract. +// Usage: +// node wasm_to_bytes.js contract.wasm contract.jsbytes +// copy paste the content of the contract.jsbytes, pass it as arguments to near.promiseBatchActionDeployContract: +// near.promiseBatchActionDeployContract(promsieId, '') +// Note, do not use `bytes()` type check here, which is too expensive for this long bytes and will exceed gas limit. +async function main() { + const source = resolve(process.argv[process.argv.length - 2]); + const target = resolve(process.argv[process.argv.length - 1]); + const code = await readFile(source); + const result = code.reduce((result, character) => `${result}\\x${character.toString(16).padStart(2, "0")}`, ""); + await writeFile(target, result); +} +main(); diff --git a/lib/build-tools/include-bytes.js b/lib/build-tools/include-bytes.js index 2c3217f48..48ef554bf 100644 --- a/lib/build-tools/include-bytes.js +++ b/lib/build-tools/include-bytes.js @@ -1,28 +1,24 @@ import * as t from "@babel/types"; -import fs from "fs"; -import path from "path"; +import { readFileSync } from "fs"; +import { join, dirname } from "path"; const assertStringLiteral = t.assertStringLiteral; export default function () { return { visitor: { - CallExpression(p, state) { - if (!("name" in p.node.callee)) { + CallExpression(path, { opts, file }) { + if (!("name" in path.node.callee)) { return; } // Extract the called method name. - const name = p.node.callee.name; + const name = path.node.callee.name; // If the method name is not "includeBytes" do nothing. if (name === "includeBytes") { // Extract the called method arguments. - const args = p.node.arguments; + const args = path.node.arguments; // Get the path of file - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const filename = this.file.opts.filename; + const filename = file.opts.filename; // User settings - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const root = state.opts.root || path.dirname(filename); + const root = opts.root || dirname(filename); // Read binary file into bytes, so encoding is 'latin1' (each byte is 0-255, become one character) const encoding = "latin1"; const [firstArg] = args; @@ -37,9 +33,9 @@ export default function () { } // Generate and locate the file const fileRelPath = firstArg.value; // Get literal string value - const filePath = path.join(root, fileRelPath); - const fileSrc = fs.readFileSync(filePath, { encoding }).toString(); - p.replaceWith(t.stringLiteral(fileSrc)); + const filePath = join(root, fileRelPath); + const fileSrc = readFileSync(filePath, { encoding }).toString(); + path.replaceWith(t.stringLiteral(fileSrc)); } }, }, diff --git a/lib/build-tools/near-bindgen-exporter.js b/lib/build-tools/near-bindgen-exporter.js index 191458574..7abffb2d5 100644 --- a/lib/build-tools/near-bindgen-exporter.js +++ b/lib/build-tools/near-bindgen-exporter.js @@ -215,7 +215,7 @@ function createDeclaration(classId, methodName, methodType) { export default function () { return { visitor: { - ClassDeclaration(path) { + ClassDeclaration(path, { opts: { verbose } }) { // Capture the node of the current path. const classNode = path.node; // Check that the class is decorated with NearBindgen otherwise do nothing. @@ -237,7 +237,9 @@ export default function () { if (methodTypes.includes(methodType) && "name" in child.key) { // Insert the method override into the class declaration. path.insertAfter(createDeclaration(classNode.id, child.key.name, methodType)); - console.log(`Babel ${child.key.name} method export done`); + if (verbose) { + console.log(`Babel ${child.key.name} method export done`); + } } } }); diff --git a/package.json b/package.json index ce09af1d0..fd25f8023 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,9 @@ ], "license": "(MIT AND Apache-2.0)", "scripts": { - "build": "tsc -p ./tsconfig.json", + "build": "yarn build:lib && yarn build:cli", + "build:lib": "tsc -p ./tsconfig.json", + "build:cli": "tsc -p ./tsconfig.cli.json", "pretest": "yarn build", "test": "yarn test:unit && yarn test:examples", "lint": "eslint --fix .", @@ -45,9 +47,10 @@ "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-node-resolve": "^13.1.1", "@scure/base": "^1.1.1", + "commander": "^9.4.1", "rollup": "^2.61.1", "rollup-plugin-sourcemaps": "^0.6.3", - "yargs": "^17.5.1" + "signale": "^1.4.0" }, "files": [ "cli", @@ -55,14 +58,20 @@ ], "devDependencies": { "@rollup/plugin-typescript": "^8.3.2", + "@types/babel__core": "^7.1.19", "@types/babel__traverse": "^7.18.1", + "@types/eslint": "^8.4.6", "@types/node": "^17.0.38", "@types/rollup": "^0.54.0", + "@types/signale": "^1.4.4", "@typescript-eslint/eslint-plugin": "^5.37.0", "@typescript-eslint/parser": "^5.37.0", "eslint": "^8.23.1", "eslint-config-prettier": "^8.5.0", "prettier": "^2.7.1", "typescript": "^4.7.2" + }, + "resolutions": { + "**/@types/estree": "^1.0.0" } } diff --git a/src/build-tools/include-bytes.ts b/src/build-tools/include-bytes.ts index e434e6304..5aabd83a5 100644 --- a/src/build-tools/include-bytes.ts +++ b/src/build-tools/include-bytes.ts @@ -1,7 +1,8 @@ +import { PluginPass } from "@babel/core"; import { Node, Visitor } from "@babel/traverse"; import * as t from "@babel/types"; -import fs from "fs"; -import path from "path"; +import { readFileSync } from "fs"; +import { join, dirname } from "path"; const assertStringLiteral: typeof t["assertStringLiteral"] = t.assertStringLiteral; @@ -9,28 +10,27 @@ const assertStringLiteral: typeof t["assertStringLiteral"] = export default function (): { visitor: Visitor } { return { visitor: { - CallExpression(p, state) { - if (!("name" in p.node.callee)) { + CallExpression( + path, + { opts, file }: PluginPass & { opts: { root?: string } } + ): void { + if (!("name" in path.node.callee)) { return; } // Extract the called method name. - const name = p.node.callee.name; + const name = path.node.callee.name; // If the method name is not "includeBytes" do nothing. if (name === "includeBytes") { // Extract the called method arguments. - const args = p.node.arguments; + const args = path.node.arguments; // Get the path of file - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const filename = this.file.opts.filename; + const filename = file.opts.filename; // User settings - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const root = state.opts.root || path.dirname(filename); + const root = opts.root || dirname(filename); // Read binary file into bytes, so encoding is 'latin1' (each byte is 0-255, become one character) const encoding = "latin1"; @@ -53,10 +53,10 @@ export default function (): { visitor: Visitor } { // Generate and locate the file const fileRelPath = firstArg.value; // Get literal string value - const filePath = path.join(root, fileRelPath); - const fileSrc = fs.readFileSync(filePath, { encoding }).toString(); + const filePath = join(root, fileRelPath); + const fileSrc = readFileSync(filePath, { encoding }).toString(); - p.replaceWith(t.stringLiteral(fileSrc) as Node); + path.replaceWith(t.stringLiteral(fileSrc) as Node); } }, }, diff --git a/src/build-tools/near-bindgen-exporter.ts b/src/build-tools/near-bindgen-exporter.ts index 9c3392e88..bcafae19c 100644 --- a/src/build-tools/near-bindgen-exporter.ts +++ b/src/build-tools/near-bindgen-exporter.ts @@ -1,3 +1,4 @@ +import { PluginPass } from "@babel/core"; import { Node, Visitor } from "@babel/traverse"; import * as t from "@babel/types"; @@ -348,7 +349,10 @@ function createDeclaration( export default function (): { visitor: Visitor } { return { visitor: { - ClassDeclaration(path) { + ClassDeclaration( + path, + { opts: { verbose } }: PluginPass & { opts: { verbose: boolean } } + ): void { // Capture the node of the current path. const classNode = path.node; @@ -383,7 +387,9 @@ export default function (): { visitor: Visitor } { ) as Node ); - console.log(`Babel ${child.key.name} method export done`); + if (verbose) { + console.log(`Babel ${child.key.name} method export done`); + } } } }); diff --git a/src/cli/cli.ts b/src/cli/cli.ts new file mode 100644 index 000000000..34c07e591 --- /dev/null +++ b/src/cli/cli.ts @@ -0,0 +1,201 @@ +#!/usr/bin/env node + +import fs from "fs/promises"; +import path, { basename, dirname } from "path"; + +// import yargs from "yargs"; +// import { hideBin } from "yargs/helpers"; + +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import sourcemaps from "rollup-plugin-sourcemaps"; +import { babel } from "@rollup/plugin-babel"; +import { rollup } from "rollup"; +import { Command } from "commander"; +import signal from "signale"; +const { Signale } = signal; + +import { executeCommand } from "./utils.js"; + +const PROJECT_DIR = process.cwd(); +const NEAR_SDK_JS = "node_modules/near-sdk-js"; +const TSC = "node_modules/.bin/tsc"; +const QJSC_DIR = `${NEAR_SDK_JS}/cli/deps/quickjs`; +const QJSC = `${NEAR_SDK_JS}/cli/deps/qjsc`; + +const program = new Command(); + +program + .name("near-sdk-js") + .addCommand( + new Command("build") + .usage("[source] [target]") + .description("Build NEAR JS Smart-contract") + .argument("[source]", "Contract to build.", "src/index.js") + .argument("[target]", "Target file path and name.", "build/contract.wasm") + .option("--verbose", "Whether to print more verbose output.", false) + .action(buildCom) + ) + .parse(); + +export async function buildCom( + source: string, + target: string, + { verbose = false }: { verbose: boolean } +): // command: Command +Promise { + const SOURCE_EXT = source.split(".").pop(); + const TARGET_DIR = dirname(target); + const TARGET_EXT = target.split(".").pop(); + const TARGET_FILE_NAME = basename(target, `.${TARGET_EXT}`); + const signale = new Signale({ scope: "build", interactive: true }); + + if (TARGET_EXT !== "wasm") { + signale.error( + `Unsupported target ${TARGET_EXT}, make sure target ends with .wasm!` + ); + process.exit(1); + } + + const ROLLUP_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.js`; + const QJSC_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.h`; + const CONTRACT_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.wasm`; + + signale.await(`Building ${source} contract...`); + + if (SOURCE_EXT === "ts") { + signale.await(`Typechecking ${source} with tsc...`); + await checkTsBuildWithTsc(source, verbose); + } + + signale.await(`Creating ${TARGET_DIR} directory...`); + await executeCommand(`mkdir -p ${TARGET_DIR}`, verbose); + + signale.await(`Creating ${source} file with Rollup...`); + await createJsFileWithRullup(source, ROLLUP_TARGET, verbose); + + signale.await(`Creating ${QJSC_TARGET} file with QJSC...`); + await createHeaderFileWithQjsc(ROLLUP_TARGET, QJSC_TARGET, verbose); + + signale.await("Generating methods.h file..."); + await createMethodsHeaderFile(ROLLUP_TARGET, verbose); + + signale.await(`Creating ${CONTRACT_TARGET} contract...`); + await createWasmContract(QJSC_TARGET, CONTRACT_TARGET, verbose); + + signale.await("Executing wasi-stub..."); + await wasiStubContract(CONTRACT_TARGET, verbose); + + signale.success(`Generated ${CONTRACT_TARGET} contract successfully!`); +} + +async function checkTsBuildWithTsc( + sourceFileWithPath: string, + verbose = false +) { + await executeCommand( + `${TSC} --noEmit --experimentalDecorators --target es2020 --moduleResolution node ${sourceFileWithPath}`, + verbose + ); +} + +// Common build function +async function createJsFileWithRullup( + sourceFileWithPath: string, + rollupTarget: string, + verbose = false +) { + const bundle = await rollup({ + input: sourceFileWithPath, + plugins: [ + nodeResolve({ + extensions: [".js", ".ts"], + }), + sourcemaps(), + // commonjs(), + babel({ + babelHelpers: "bundled", + extensions: [".ts", ".js", ".jsx", ".es6", ".es", ".mjs"], + presets: ["@babel/preset-typescript"], + plugins: [ + "near-sdk-js/lib/build-tools/include-bytes.js", + ["near-sdk-js/lib/build-tools/near-bindgen-exporter.js", { verbose }], + ["@babel/plugin-proposal-decorators", { version: "legacy" }], + ], + }), + ], + }); + + await bundle.write({ + sourcemap: true, + file: rollupTarget, + format: "es", + }); +} + +async function createHeaderFileWithQjsc( + rollupTarget: string, + qjscTarget: string, + verbose = false +) { + await executeCommand( + `${QJSC} -c -m -o ${qjscTarget} -N code ${rollupTarget}`, + verbose + ); +} + +async function createMethodsHeaderFile(rollupTarget: string, verbose = false) { + const buildPath = path.dirname(rollupTarget); + + if (verbose) { + console.log(rollupTarget); + } + + const mod = await import(`${PROJECT_DIR}/${rollupTarget}`); + const exportNames = Object.keys(mod); + const methods = exportNames.reduce( + (result, key) => `${result}DEFINE_NEAR_METHOD(${key})\n`, + "" + ); + + await fs.writeFile(`${buildPath}/methods.h`, methods); +} + +async function createWasmContract( + qjscTarget: string, + contractTarget: string, + verbose = false +) { + const WASI_SDK_PATH = `${NEAR_SDK_JS}/cli/deps/wasi-sdk`; + + const CC = `${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot`; + let DEFS = `-D_GNU_SOURCE '-DCONFIG_VERSION="2021-03-27"' -DCONFIG_BIGNUM`; + + if (process.env.NEAR_NIGHTLY) { + DEFS = DEFS + " -DNIGHTLY"; + } + + const INCLUDES = `-I${QJSC_DIR} -I.`; + const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/cli/builder/builder.c`; + const NEW_BUILDER_PATH = `${path.dirname(contractTarget)}/builder.c`; + const SOURCES = `${NEW_BUILDER_PATH} ${QJSC_DIR}/quickjs.c ${QJSC_DIR}/libregexp.c ${QJSC_DIR}/libunicode.c ${QJSC_DIR}/cutils.c ${QJSC_DIR}/quickjs-libc-min.c ${QJSC_DIR}/libbf.c`; + const LIBS = `-lm`; + + // copying builder.c file to the build folder + await executeCommand( + `cp ${ORIGINAL_BUILDER_PATH} ${NEW_BUILDER_PATH}`, + verbose + ); + await executeCommand(`mv ${qjscTarget} build/code.h`, verbose); + + await executeCommand( + `${CC} --target=wasm32-wasi -nostartfiles -Oz -flto ${DEFS} ${INCLUDES} ${SOURCES} ${LIBS} -Wl,--no-entry -Wl,--allow-undefined -Wl,-z,stack-size=${ + 256 * 1024 + } -Wl,--lto-O3 -o ${contractTarget}`, + verbose + ); +} + +async function wasiStubContract(contractTarget: string, verbose = false) { + const WASI_STUB = `${NEAR_SDK_JS}/cli/deps/binaryen/wasi-stub/run.sh`; + await executeCommand(`${WASI_STUB} ${contractTarget} >/dev/null`, verbose); +} diff --git a/src/cli/post-install.ts b/src/cli/post-install.ts new file mode 100644 index 000000000..cffb26b79 --- /dev/null +++ b/src/cli/post-install.ts @@ -0,0 +1,105 @@ +import { executeCommand } from "./utils.js"; +import signal from "signale"; + +const { Signale } = signal; + +const signale = new Signale({ scope: "postinstall", interactive: true }); + +async function download(url: string, verbose = false) { + await executeCommand(`curl -LOf ${url}`, verbose); +} + +const OS = await executeCommand("uname -s", false); +const ARCH = await executeCommand("uname -m", false); + +if (OS !== "Linux" && OS !== "Darwin") { + console.error(`OS ${OS} is not supported at the moment`); + process.exit(1); +} + +if (ARCH !== "x86_64" && ARCH !== "arm64") { + console.error(` ${ARCH} architecture is unsapported at the moment`); + process.exit(1); +} + +signale.await("Installing wasi-stub..."); + +const BINARYEN_VERSION = `0.1.10`; +const BINARYEN_VERSION_TAG = `v${BINARYEN_VERSION}`; +const BINARYEN_SYSTEM_NAME = + OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; +const BINARYEN_ARCH_NAME = + ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; +const BINARYEN_TAR_NAME = `binaryen-${BINARYEN_SYSTEM_NAME}-${BINARYEN_ARCH_NAME}.tar.gz`; + +await download( + `https://github.com/near/binaryen/releases/download/${BINARYEN_VERSION_TAG}/${BINARYEN_TAR_NAME}` +); +await executeCommand( + `mkdir -p binaryen && tar xvf ${BINARYEN_TAR_NAME} --directory binaryen` +); +await executeCommand(`rm ${BINARYEN_TAR_NAME}`); + +signale.await("Installing QuickJS..."); + +const QUICK_JS_VERSION = `0.1.2`; +const QUICK_JS_VERSION_TAG = `v${QUICK_JS_VERSION}`; +const QUICK_JS_SYSTEM_NAME = + OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; +const QUICK_JS_ARCH_NAME = + ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; +const QUICK_JS_TAR_NAME = `${QUICK_JS_VERSION_TAG}.tar.gz`; +const QUICK_JS_DOWNLOADED_FOLDER_NAME = `quickjs-${QUICK_JS_VERSION}`; +const QUICK_JS_TARGET_FOLDER_NAME = "quickjs"; +const QUICK_JS_DOWNLOADED_NAME = `qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}`; +const QUICK_JS_TARGET_NAME = "qjsc"; + +// Download QuickJS +await download( + `https://github.com/near/quickjs/releases/download/${QUICK_JS_VERSION_TAG}/qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}` +); +await download( + `https://github.com/near/quickjs/archive/refs/tags/${QUICK_JS_VERSION_TAG}.tar.gz` +); + +// Extract QuickJS +await executeCommand(`tar xvf ${QUICK_JS_TAR_NAME}`); + +// Delete .tar file +await executeCommand(`rm ${QUICK_JS_TAR_NAME}`); + +// Delete version from folder name +await executeCommand( + `mv ${QUICK_JS_DOWNLOADED_FOLDER_NAME} ${QUICK_JS_TARGET_FOLDER_NAME}` +); + +// Rename qjsc file +await executeCommand(`mv ${QUICK_JS_DOWNLOADED_NAME} ${QUICK_JS_TARGET_NAME}`); + +// chmod qjsc +await executeCommand(`chmod 777 ${QUICK_JS_TARGET_NAME}`); + +signale.await("Installing wasi-sdk..."); + +const WASI_SDK_MAJOR_VER = 11; +const WASI_SDK_MINOR_VER = 0; +const WASI_SDK_DOWNLOADED_FOLDER_NAME = `wasi-sdk-${WASI_SDK_MAJOR_VER}.${WASI_SDK_MINOR_VER}`; +const WASI_SDK_SYSTEM_NAME = + OS === "Linux" ? "linux" : OS === "Darwin" ? "macos" : "other"; +const WASI_SDK_TAR_NAME = `${WASI_SDK_DOWNLOADED_FOLDER_NAME}-${WASI_SDK_SYSTEM_NAME}.tar.gz`; + +// Download WASI SDK +await download( + `https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_MAJOR_VER}/${WASI_SDK_TAR_NAME}` +); + +// Extract WASI SDK +await executeCommand(`tar xvf ${WASI_SDK_TAR_NAME}`); + +// Delete .tar file +await executeCommand(`rm ${WASI_SDK_TAR_NAME}`); + +// Delete version from folder name +await executeCommand(`mv ${WASI_SDK_DOWNLOADED_FOLDER_NAME} wasi-sdk`); + +signale.success("Successfully finished postinstall script!"); diff --git a/src/cli/save-bytecode.ts b/src/cli/save-bytecode.ts new file mode 100644 index 000000000..588c0a393 --- /dev/null +++ b/src/cli/save-bytecode.ts @@ -0,0 +1,29 @@ +import { readFile, writeFile } from "fs/promises"; +import { resolve } from "path"; + +//TODO: execute it in js env +async function main(): Promise { + const source = resolve(process.argv[process.argv.length - 2]); + const target = resolve(process.argv[process.argv.length - 1]); + const code = await readFile(source, "utf-8"); + + const codes = code + .split("\n") + .map((line) => { + if (line.indexOf("0x") < 0) { + return []; + } + + const trimmedLine = line.trim(); + const numbers = trimmedLine.slice(0, trimmedLine.length - 1).split(", "); + + return numbers.map(Number); + }) + .filter((numbers) => numbers.length); + + const bytecode = Buffer.concat(codes.map(Buffer.from)); + + await writeFile(target, bytecode.toString("base64")); +} + +main(); diff --git a/src/cli/utils.ts b/src/cli/utils.ts new file mode 100644 index 000000000..40d59b896 --- /dev/null +++ b/src/cli/utils.ts @@ -0,0 +1,30 @@ +import childProcess from "child_process"; +import { promisify } from "util"; + +const exec = promisify(childProcess.exec); + +export async function executeCommand( + command: string, + verbose = false +): Promise { + if (verbose) { + console.log(command); + } + + try { + const { stdout, stderr } = await exec(command); + + if (stderr && verbose) { + console.error(stderr); + } + + if (verbose) { + console.log(stdout); + } + + return stdout.trim(); + } catch (error) { + console.log(error); + process.exit(1); + } +} diff --git a/src/cli/wasm-to-bytes.ts b/src/cli/wasm-to-bytes.ts new file mode 100644 index 000000000..1672b00d3 --- /dev/null +++ b/src/cli/wasm-to-bytes.ts @@ -0,0 +1,24 @@ +import { readFile, writeFile } from "fs/promises"; +import { resolve } from "path"; + +// used for deploy code in contract with near.promiseBatchActionDeployContract. +// Usage: +// node wasm_to_bytes.js contract.wasm contract.jsbytes +// copy paste the content of the contract.jsbytes, pass it as arguments to near.promiseBatchActionDeployContract: +// near.promiseBatchActionDeployContract(promsieId, '') +// Note, do not use `bytes()` type check here, which is too expensive for this long bytes and will exceed gas limit. +async function main(): Promise { + const source = resolve(process.argv[process.argv.length - 2]); + const target = resolve(process.argv[process.argv.length - 1]); + const code = await readFile(source); + + const result = code.reduce( + (result, character) => + `${result}\\x${character.toString(16).padStart(2, "0")}`, + "" + ); + + await writeFile(target, result); +} + +main(); diff --git a/tsconfig.cli.json b/tsconfig.cli.json new file mode 100644 index 000000000..1a0315d55 --- /dev/null +++ b/tsconfig.cli.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "lib": ["es2015", "esnext", "dom"], + "module": "esnext", + "target": "es2020", + "moduleResolution": "node", + "alwaysStrict": true, + "outDir": "./cli", + "declaration": true, + "preserveSymlinks": true, + "preserveWatchOutput": true, + "pretty": false, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "noUnusedLocals": true, + "experimentalDecorators": true, + "resolveJsonModule": true, + "allowJs": true + }, + "include": ["src/cli/**/*"] +} diff --git a/tsconfig.json b/tsconfig.json index d3db3b261..a54a5836b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,5 +24,6 @@ "src/index.ts", "src/build-tools/near-bindgen-exporter.ts", "src/build-tools/include-bytes.ts" - ] + ], + "exclude": ["src/cli/**/*"] } diff --git a/yarn.lock b/yarn.lock index 5b1cfa904..2477c2374 100644 --- a/yarn.lock +++ b/yarn.lock @@ -267,6 +267,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" @@ -277,6 +282,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== +"@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz" @@ -314,6 +324,11 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@^7.1.0": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.4.tgz#03c4339d2b8971eb3beca5252bafd9b9f79db3dc" + integrity sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA== + "@babel/parser@^7.16.7", "@babel/parser@^7.17.12": version "7.17.12" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.17.12.tgz" @@ -418,6 +433,15 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/types@^7.0.0": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.4.tgz#0dd5c91c573a202d600490a35b33246fed8a41c7" + integrity sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.17.12": version "7.17.12" resolved "https://registry.npmjs.org/@babel/types/-/types-7.17.12.tgz" @@ -612,6 +636,39 @@ resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== +"@types/babel__core@^7.1.19": + version "7.1.19" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" + integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== + dependencies: + "@babel/types" "^7.3.0" + "@types/babel__traverse@^7.18.1": version "7.18.1" resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.1.tgz#ce5e2c8c272b99b7a9fd69fa39f0b4cd85028bd9" @@ -619,12 +676,20 @@ dependencies: "@babel/types" "^7.3.0" -"@types/estree@*", "@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/eslint@^8.4.6": + version "8.4.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" + integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@0.0.39", "@types/estree@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== -"@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -653,6 +718,13 @@ dependencies: rollup "*" +"@types/signale@^1.4.4": + version "1.4.4" + resolved "https://registry.yarnpkg.com/@types/signale/-/signale-1.4.4.tgz#dbfd32b39f1084551ecda9ba0888e4fef49e9fea" + integrity sha512-VYy4VL64gA4uyUIYVj4tiGFF0VpdnRbJeqNENKGX42toNiTvt83rRzxdr0XK4DR3V01zPM0JQNIsL+IwWWfhsQ== + dependencies: + "@types/node" "*" + "@typescript-eslint/eslint-plugin@^5.37.0": version "5.37.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.37.0.tgz#5ccdd5d9004120f28fc6e717fb4b5c9bddcfbc04" @@ -766,7 +838,7 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -834,7 +906,7 @@ caniuse-lite@^1.0.30001332: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001339.tgz" integrity sha512-Es8PiVqCe+uXdms0Gu5xP5PF2bxLR7OBp3wUzUnuO7OHzhOfCyg3hdiGWVPVxhiuniOzng+hTc1u3fEQ0TlkSQ== -chalk@^2.0.0: +chalk@^2.0.0, chalk@^2.3.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -856,15 +928,6 @@ charcodes@^0.2.0: resolved "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz" integrity sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ== -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" @@ -889,6 +952,11 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^9.4.1: + version "9.4.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" + integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" @@ -956,10 +1024,12 @@ electron-to-chromium@^1.4.118: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz" integrity sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA== -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" escalade@^3.1.1: version "3.1.1" @@ -1140,6 +1210,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -1154,6 +1231,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== + dependencies: + locate-path "^2.0.0" + find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -1200,11 +1284,6 @@ gensync@^1.0.0-beta.2: resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1255,6 +1334,11 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +graceful-fs@^4.1.2: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + grapheme-splitter@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" @@ -1308,6 +1392,11 @@ inherits@2: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-builtin-module@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz" @@ -1327,11 +1416,6 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -1383,6 +1467,11 @@ jsesc@^2.5.1: resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1406,6 +1495,24 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -1486,6 +1593,13 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -1493,6 +1607,13 @@ p-limit@^3.0.2: dependencies: yocto-queue "^0.1.0" +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + p-locate@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" @@ -1500,6 +1621,11 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -1507,6 +1633,19 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -1542,6 +1681,19 @@ picomatch@^2.2.2, picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + +pkg-conf@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" + integrity sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g== + dependencies: + find-up "^2.0.0" + load-json-file "^4.0.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -1567,11 +1719,6 @@ regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -1656,6 +1803,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +signale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/signale/-/signale-1.4.0.tgz#c4be58302fb0262ac00fc3d886a7c113759042f1" + integrity sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w== + dependencies: + chalk "^2.3.2" + figures "^2.0.0" + pkg-conf "^2.1.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -1674,22 +1830,18 @@ sourcemap-codec@^1.4.8: resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -1779,48 +1931,16 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@^21.0.0: - version "21.0.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz" - integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== - -yargs@^17.5.1: - version "17.5.1" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz" - integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.0.0" - yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" From 3d01e26d5c16e310fd81c180a88e3b862226ad5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 13:28:55 +0200 Subject: [PATCH 2/9] fix: Ignore CLI folder for lints --- .eslintrc.cjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e3f4f3856..515f1c8e5 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -46,7 +46,8 @@ module.exports = { "build", "./**/deps", "deps", - "cli", + "cli/**/*.ts", + "cli/**/*.js", ], rules: {}, }; From 393829a559cda700b51f4e5dfa1f346622b4444f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 13:30:02 +0200 Subject: [PATCH 3/9] fix: Ignore CLI folder for formatting --- .prettierignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.prettierignore b/.prettierignore index 515c347a8..c3dd3989b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,5 @@ deps build node_modules lib +cli From 53f21379723c6faa8c3b9e765aa9f440b25d57df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 14:34:39 +0200 Subject: [PATCH 4/9] chore: Remove old files --- cli/save_bytecode.js | 29 ----------------------------- cli/wasm_to_bytes.js | 24 ------------------------ 2 files changed, 53 deletions(-) delete mode 100644 cli/save_bytecode.js delete mode 100644 cli/wasm_to_bytes.js diff --git a/cli/save_bytecode.js b/cli/save_bytecode.js deleted file mode 100644 index 8c93ea898..000000000 --- a/cli/save_bytecode.js +++ /dev/null @@ -1,29 +0,0 @@ -import fs from "fs/promises"; -import path from "path"; - -//TODO: execute it in js env -async function main() { - const source = path.resolve(process.argv[process.argv.length - 2]); - const target = path.resolve(process.argv[process.argv.length - 1]); - const code = await fs.readFile(source, "utf-8"); - - const codes = code - .split("\n") - .map((line) => { - if (line.indexOf("0x") < 0) { - return []; - } - - const trimmedLine = line.trim(); - const numbers = trimmedLine.slice(0, trimmedLine.length - 1).split(", "); - - return numbers.map(Number); - }) - .filter((numbers) => numbers.length); - - const bytecode = Buffer.concat(codes.map(Buffer.from)); - - await fs.writeFile(target, bytecode.toString("base64")); -} - -main(); diff --git a/cli/wasm_to_bytes.js b/cli/wasm_to_bytes.js deleted file mode 100644 index 59dbf7f63..000000000 --- a/cli/wasm_to_bytes.js +++ /dev/null @@ -1,24 +0,0 @@ -import fs from "fs/promises"; -import path from "path"; - -// used for deploy code in contract with near.promiseBatchActionDeployContract. -// Usage: -// node wasm_to_bytes.js contract.wasm contract.jsbytes -// copy paste the content of the contract.jsbytes, pass it as arguments to near.promiseBatchActionDeployContract: -// near.promiseBatchActionDeployContract(promsieId, '') -// Note, do not use `bytes()` type check here, which is too expensive for this long bytes and will exceed gas limit. -async function main() { - const source = path.resolve(process.argv[process.argv.length - 2]); - const target = path.resolve(process.argv[process.argv.length - 1]); - const code = await fs.readFile(source); - - const result = code.reduce( - (result, character) => - `${result}\\x${character.toString(16).padStart(2, "0")}`, - "" - ); - - await fs.writeFile(target, result); -} - -main(); From 3ffe6f6b72d1b499b5eb52c3862132849b8e72fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 16:05:34 +0200 Subject: [PATCH 5/9] fix: Remove copied files --- cli/.gitignore | 1 - cli/builder/builder.c | 1036 -------------------------------- cli/cli.js | 0 cli/package.json | 74 --- cli/src/cli/cli.d.ts | 4 - cli/src/cli/cli.js | 188 ------ cli/src/cli/post-install.d.ts | 1 - cli/src/cli/post-install.js | 60 -- cli/src/cli/save-bytecode.d.ts | 1 - cli/src/cli/save-bytecode.js | 22 - cli/src/cli/utils.d.ts | 1 - cli/src/cli/utils.js | 22 - cli/src/cli/wasm-to-bytes.d.ts | 1 - cli/src/cli/wasm-to-bytes.js | 16 - 14 files changed, 1427 deletions(-) delete mode 100644 cli/.gitignore delete mode 100644 cli/builder/builder.c mode change 100755 => 100644 cli/cli.js delete mode 100644 cli/package.json delete mode 100644 cli/src/cli/cli.d.ts delete mode 100644 cli/src/cli/cli.js delete mode 100644 cli/src/cli/post-install.d.ts delete mode 100644 cli/src/cli/post-install.js delete mode 100644 cli/src/cli/save-bytecode.d.ts delete mode 100644 cli/src/cli/save-bytecode.js delete mode 100644 cli/src/cli/utils.d.ts delete mode 100644 cli/src/cli/utils.js delete mode 100644 cli/src/cli/wasm-to-bytes.d.ts delete mode 100644 cli/src/cli/wasm-to-bytes.js diff --git a/cli/.gitignore b/cli/.gitignore deleted file mode 100644 index 1aa628036..000000000 --- a/cli/.gitignore +++ /dev/null @@ -1 +0,0 @@ -deps \ No newline at end of file diff --git a/cli/builder/builder.c b/cli/builder/builder.c deleted file mode 100644 index 4fc5153e0..000000000 --- a/cli/builder/builder.c +++ /dev/null @@ -1,1036 +0,0 @@ -#include -#include "../node_modules/near-sdk-js/cli/deps/quickjs/quickjs-libc-min.h" -#include "../node_modules/near-sdk-js/cli/deps/quickjs/libbf.h" -#include "code.h" - -static JSContext *JS_NewCustomContext(JSRuntime *rt) -{ - JSContext *ctx = JS_NewContextRaw(rt); - if (!ctx) - return NULL; - JS_AddIntrinsicBaseObjects(ctx); - JS_AddIntrinsicDate(ctx); - JS_AddIntrinsicEval(ctx); - JS_AddIntrinsicStringNormalize(ctx); - JS_AddIntrinsicRegExp(ctx); - JS_AddIntrinsicJSON(ctx); - JS_AddIntrinsicProxy(ctx); - JS_AddIntrinsicMapSet(ctx); - JS_AddIntrinsicTypedArrays(ctx); - JS_AddIntrinsicPromise(ctx); - JS_AddIntrinsicBigInt(ctx); - return ctx; -} - -#define DEFINE_NEAR_METHOD(name) \ - void name () __attribute__((export_name(#name))) {\ - JSRuntime *rt;\ - JSContext *ctx;\ - JSValue mod_obj, fun_obj, result, error, error_message, error_stack;\ - const char *error_message_c, *error_stack_c;\ - char *error_c;\ - size_t msg_len, stack_len;\ - rt = JS_NewRuntime();\ - ctx = JS_NewCustomContext(rt);\ - js_add_near_host_functions(ctx);\ - mod_obj = js_load_module_binary(ctx, code, code_size);\ - fun_obj = JS_GetProperty(ctx, mod_obj, JS_NewAtom(ctx, #name));\ - result = JS_Call(ctx, fun_obj, mod_obj, 0, NULL);\ - if (JS_IsException(result)) {\ - error = JS_GetException(ctx);\ - error_message = JS_GetPropertyStr(ctx, error, "message");\ - error_stack = JS_GetPropertyStr(ctx, error, "stack");\ - error_message_c = JS_ToCStringLen(ctx, &msg_len, error_message);\ - error_stack_c = JS_ToCStringLen(ctx, &stack_len, error_stack);\ - error_c = malloc(msg_len+1+stack_len);\ - strncpy(error_c, error_message_c, msg_len);\ - error_c[msg_len] = '\n';\ - strncpy(error_c+msg_len+1, error_stack_c, stack_len);\ - panic_utf8(msg_len+1+stack_len, (uint64_t)error_c);\ - }\ - js_std_loop(ctx);\ - } - -// ############# -// # Registers # -// ############# -extern void read_register(uint64_t register_id, uint64_t ptr); -extern uint64_t register_len(uint64_t register_id); -extern void write_register(uint64_t register_id, uint64_t data_len, uint64_t data_ptr); -// ############### -// # Context API # -// ############### -extern void current_account_id(uint64_t register_id); -extern void signer_account_id(uint64_t register_id); -extern void signer_account_pk(uint64_t register_id); -extern void predecessor_account_id(uint64_t register_id); -extern void input(uint64_t register_id); -extern uint64_t block_index(); -extern uint64_t block_timestamp(); -extern uint64_t epoch_height(); -extern uint64_t storage_usage(); -// ################# -// # Economics API # -// ################# -extern void account_balance(uint64_t balance_ptr); -extern void account_locked_balance(uint64_t balance_ptr); -extern void attached_deposit(uint64_t balance_ptr); -extern uint64_t prepaid_gas(); -extern uint64_t used_gas(); -// ############ -// # Math API # -// ############ -extern void random_seed(uint64_t register_id); -extern void sha256(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); -extern void keccak256(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); -extern void keccak512(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); -extern void ripemd160(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); -extern uint64_t ecrecover(uint64_t hash_len, uint64_t hash_ptr, uint64_t sign_len, uint64_t sig_ptr, uint64_t v, uint64_t malleability_flag, uint64_t register_id); -// ##################### -// # Miscellaneous API # -// ##################### -extern void value_return(uint64_t value_len, uint64_t value_ptr); -extern void panic(void); -extern void panic_utf8(uint64_t len, uint64_t ptr); -extern void log_utf8(uint64_t len, uint64_t ptr); -extern void log_utf16(uint64_t len, uint64_t ptr); -// Name confliction with WASI. Can be re-exported with a different name on NEAR side with a protocol upgrade -// Or, this is actually not a primitive, can be implement with log and panic host functions in C side or JS side. -// extern void abort(uint32_t msg_ptr, uint32_t filename_ptr, uint32_t u32, uint32_t col); -// ################ -// # Promises API # -// ################ -extern uint64_t promise_create(uint64_t account_id_len, uint64_t account_id_ptr, uint64_t method_name_len, uint64_t method_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas); -extern uint64_t promise_then(uint64_t promise_index, uint64_t account_id_len, uint64_t account_id_ptr, uint64_t method_name_len, uint64_t method_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas); -extern uint64_t promise_and(uint64_t promise_idx_ptr, uint64_t promise_idx_count); -extern uint64_t promise_batch_create(uint64_t account_id_len, uint64_t account_id_ptr); -extern uint64_t promise_batch_then(uint64_t promise_index, uint64_t account_id_len, uint64_t account_id_ptr); -// ####################### -// # Promise API actions # -// ####################### -extern void promise_batch_action_create_account(uint64_t promise_index); -extern void promise_batch_action_deploy_contract(uint64_t promise_index, uint64_t code_len, uint64_t code_ptr); -extern void promise_batch_action_function_call(uint64_t promise_index, uint64_t method_name_len, uint64_t method_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas); -extern void promise_batch_action_transfer(uint64_t promise_index, uint64_t amount_ptr); -extern void promise_batch_action_stake(uint64_t promise_index, uint64_t amount_ptr, uint64_t public_key_len, uint64_t public_key_ptr); -extern void promise_batch_action_add_key_with_full_access(uint64_t promise_index, uint64_t public_key_len, uint64_t public_key_ptr, uint64_t nonce); -extern void promise_batch_action_add_key_with_function_call(uint64_t promise_index, uint64_t public_key_len, uint64_t public_key_ptr, uint64_t nonce, uint64_t allowance_ptr, uint64_t receiver_id_len, uint64_t receiver_id_ptr, uint64_t method_names_len, uint64_t method_names_ptr); -extern void promise_batch_action_delete_key(uint64_t promise_index, uint64_t public_key_len, uint64_t public_key_ptr); -extern void promise_batch_action_delete_account(uint64_t promise_index, uint64_t beneficiary_id_len, uint64_t beneficiary_id_ptr); -extern void promise_batch_action_function_call_weight(uint64_t promise_index, uint64_t function_name_len, uint64_t function_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas, uint64_t weight); -// ####################### -// # Promise API results # -// ####################### -extern uint64_t promise_results_count(void); -extern uint64_t promise_result(uint64_t result_idx, uint64_t register_id); -extern void promise_return(uint64_t promise_idx); -// ############### -// # Storage API # -// ############### -extern uint64_t storage_write(uint64_t key_len, uint64_t key_ptr, uint64_t value_len, uint64_t value_ptr, uint64_t register_id); -extern uint64_t storage_read(uint64_t key_len, uint64_t key_ptr, uint64_t register_id); -extern uint64_t storage_remove(uint64_t key_len, uint64_t key_ptr, uint64_t register_id); -extern uint64_t storage_has_key(uint64_t key_len, uint64_t key_ptr); -// ################# -// # Validator API # -// ################# -extern void validator_stake(uint64_t account_id_len, uint64_t account_id_ptr, uint64_t stake_ptr); -extern void validator_total_stake(uint64_t stake_ptr); -// ############# -// # Alt BN128 # -// ############# -#ifdef NIGHTLY -extern void alt_bn128_g1_multiexp(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); -extern void alt_bn128_g1_sum(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); -extern uint64_t alt_bn128_pairing_check(uint64_t value_len, uint64_t value_ptr); -#endif - -static JSValue near_read_register(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - char *data; - uint64_t data_len; - JSValue ret; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - data_len = register_len(register_id); - if (data_len != UINT64_MAX) { - data = malloc(data_len); - read_register(register_id, (uint64_t)data); - ret = JS_NewStringLenRaw(ctx, data, data_len); - free(data); - return ret; - } else { - return JS_UNDEFINED; - } -} - -static JSValue near_register_len(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id, len; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - len = register_len(register_id); - return JS_NewBigUint64(ctx, len); -} - -static JSValue near_write_register(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - const char *data_ptr; - size_t data_len; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[1]); - - write_register(register_id, data_len, (uint64_t)data_ptr); - return JS_UNDEFINED; -} - -static JSValue near_current_account_id(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - current_account_id(register_id); - return JS_UNDEFINED; -} - -static JSValue near_signer_account_id(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { - uint64_t register_id; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - signer_account_id(register_id); - return JS_UNDEFINED; -} - -static JSValue near_signer_account_pk(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { - uint64_t register_id; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - signer_account_pk(register_id); - return JS_UNDEFINED; -} - -static JSValue near_predecessor_account_id(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { - uint64_t register_id; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - predecessor_account_id(register_id); - return JS_UNDEFINED; -} - -static JSValue near_input(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - input(register_id); - return JS_UNDEFINED; -} - -static JSValue near_block_index(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t value; - - value = block_index(); - return JS_NewBigUint64(ctx, value); -} - -static JSValue near_block_timestamp(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t value; - - value = block_timestamp(); - return JS_NewBigUint64(ctx, value); -} - -static JSValue near_epoch_height(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t value; - - value = epoch_height(); - return JS_NewBigUint64(ctx, value); -} - -static JSValue near_storage_usage(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t value; - - value = storage_usage(); - return JS_NewBigUint64(ctx, value); -} - -// ptr[0] ptr[1] is little-endian u128. -static JSValue u128_to_quickjs(JSContext *ctx, uint64_t* ptr) { - JSValue value; - bf_t* bn; - bf_t b; - - value = JS_NewBigInt(ctx); - bn = JS_GetBigInt(value); - // from ptr[] to bn - // high 64 bits - bf_set_ui(bn, ptr[1]); - bf_mul_2exp(bn, 64, BF_PREC_INF, BF_RNDZ); - // low 64 bits - bf_init(bn->ctx, &b); - bf_set_ui(&b, ptr[0]); - bf_add(bn, bn, &b, BF_PREC_INF, BF_RNDZ); - bf_delete(&b); - - return value; -} - -static int quickjs_bigint_to_u128(JSContext *ctx, JSValueConst val, uint64_t* ptr) { - bf_t* a; - bf_t q, r, b, one, u128max; - a = JS_GetBigInt(val); - bf_init(a->ctx, &u128max); - bf_set_ui(&u128max, 1); - bf_mul_2exp(&u128max, 128, BF_PREC_INF, BF_RNDZ); - if (bf_cmp_le(&u128max, a)) { - return 1; - } - bf_init(a->ctx, &q); - bf_init(a->ctx, &r); - bf_init(a->ctx, &b); - bf_init(a->ctx, &one); - bf_set_ui(&b, UINT64_MAX); - bf_set_ui(&one, 1); - bf_add(&b, &b, &one, BF_PREC_INF, BF_RNDZ); - bf_divrem(&q, &r, a, &b, BF_PREC_INF, BF_RNDZ, BF_RNDZ); - - bf_get_uint64(ptr, &r); - bf_get_uint64(ptr+1, &q); - return 0; -} - -static int quickjs_int_to_u128(JSContext *ctx, JSValueConst val, uint64_t* ptr) { - if (JS_ToUint64Ext(ctx, ptr, val) < 0) { - return 1; - } - ptr[1] = 0; - return 0; -} - -static int quickjs_to_u128(JSContext *ctx, JSValueConst val, uint64_t* ptr) { - if (JS_IsBigInt(ctx, val)) - return quickjs_bigint_to_u128(ctx, val, ptr); - else { - return quickjs_int_to_u128(ctx, val, ptr); - } -} - -static JSValue near_account_balance(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t ptr[2]; - - account_balance((uint64_t)ptr); - return u128_to_quickjs(ctx, ptr); -} - -static JSValue near_account_locked_balance(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t ptr[2]; - - account_locked_balance((uint64_t)ptr); - return u128_to_quickjs(ctx, ptr); -} - -static JSValue near_attached_deposit(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t ptr[2]; - - attached_deposit((uint64_t)ptr); - return u128_to_quickjs(ctx, ptr); -} - -static JSValue near_prepaid_gas(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t value; - - value = prepaid_gas(); - return JS_NewBigUint64(ctx, value); -} - -static JSValue near_used_gas(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t value; - - value = used_gas(); - return JS_NewBigUint64(ctx, value); -} - -static JSValue near_random_seed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - - if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - random_seed(register_id); - return JS_UNDEFINED; -} - -static JSValue near_sha256(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - - sha256(data_len, (uint64_t)data_ptr, register_id); - return JS_UNDEFINED; -} - -static JSValue near_keccak256(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - keccak256(data_len, (uint64_t)data_ptr, register_id); - return JS_UNDEFINED; -} - -static JSValue near_keccak512(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - - keccak512(data_len, (uint64_t)data_ptr, register_id); - return JS_UNDEFINED; -} - -static JSValue near_ripemd160(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - - ripemd160(data_len, (uint64_t)data_ptr, register_id); - return JS_UNDEFINED; -} - -static JSValue near_ecrecover(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t malleability_flag, v, register_id, result; - const char *hash_ptr, *sig_ptr; - size_t hash_len, sign_len; - - hash_ptr = JS_ToCStringLenRaw(ctx, &hash_len, argv[0]); - sig_ptr = JS_ToCStringLenRaw(ctx, &sign_len, argv[1]); - if (JS_ToUint64Ext(ctx, &malleability_flag, argv[2]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for malleability_flag"); - } - if (JS_ToUint64Ext(ctx, &v, argv[3]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for v"); - } - if (JS_ToUint64Ext(ctx, ®ister_id, argv[4]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - - result = ecrecover(hash_len, (uint64_t)hash_ptr, sign_len, (uint64_t)sig_ptr, malleability_flag, v, register_id); - return JS_NewBigUint64(ctx, result); -} - -static JSValue near_value_return(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *value_ptr; - size_t value_len; - - value_ptr = JS_ToCStringLenRaw(ctx, &value_len, argv[0]); - value_return(value_len, (uint64_t)value_ptr); - return JS_UNDEFINED; -} - -static JSValue near_panic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *data_ptr; - size_t data_len; - - if (argc == 1) { - data_ptr = JS_ToCStringLen(ctx, &data_len, argv[0]); - panic_utf8(data_len, (uint64_t)data_ptr); - } else { - panic(); - } - return JS_UNDEFINED; -} - -static JSValue near_panic_utf8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - - panic_utf8(data_len, (uint64_t)data_ptr); - return JS_UNDEFINED; -} - -static JSValue near_log(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLen(ctx, &data_len, argv[0]); - - log_utf8(data_len, (uint64_t)data_ptr); - return JS_UNDEFINED; -} - -static JSValue near_log_utf8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - - log_utf8(data_len, (uint64_t)data_ptr); - return JS_UNDEFINED; -} - -static JSValue near_log_utf16(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - log_utf16(data_len, (uint64_t)data_ptr); - return JS_UNDEFINED; -} - -static JSValue near_promise_create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *account_id_ptr, *method_name_ptr, *arguments_ptr; - size_t account_id_len, method_name_len, arguments_len; - uint64_t amount_ptr[2]; // amount is u128 - uint64_t gas, ret; - - account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[0]); - method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[1]); - arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[2]); - if (quickjs_to_u128(ctx, argv[3], amount_ptr) != 0) { - return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); - } - if (JS_ToUint64Ext(ctx, &gas, argv[4]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); - } - - ret = promise_create(account_id_len, (uint64_t)account_id_ptr, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas); - - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_promise_then(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *account_id_ptr, *method_name_ptr, *arguments_ptr; - size_t account_id_len, method_name_len, arguments_len; - uint64_t amount_ptr[2]; // amount is u128 - uint64_t gas, ret; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[1]); - method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[2]); - arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[3]); - if (quickjs_to_u128(ctx, argv[4], amount_ptr) != 0) { - return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); - } - if (JS_ToUint64Ext(ctx, &gas, argv[5]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); - } - - ret = promise_then(promise_index, account_id_len, (uint64_t)account_id_ptr, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas); - - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_promise_and(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_idx_ptr[argc], ret; - - for(int i = 0; i < argc; i++) { - if (JS_ToUint64Ext(ctx, &promise_idx_ptr[i], argv[i]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_id"); - } - } - ret = promise_and((uint64_t)promise_idx_ptr, argc); - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_promise_batch_create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *account_id_ptr; - size_t account_id_len; - uint64_t ret; - - account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[0]); - ret = promise_batch_create(account_id_len, (uint64_t)account_id_ptr); - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_promise_batch_then(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *account_id_ptr; - size_t account_id_len; - uint64_t ret; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[1]); - ret = promise_batch_then(promise_index, account_id_len, (uint64_t)account_id_ptr); - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_promise_batch_action_create_account(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - promise_batch_action_create_account(promise_index); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_deploy_contract(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *code_ptr; - size_t code_len; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - code_ptr = JS_ToCStringLenRaw(ctx, &code_len, argv[1]); - promise_batch_action_deploy_contract(promise_index, code_len, (uint64_t)code_ptr); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_function_call(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *method_name_ptr, *arguments_ptr; - size_t method_name_len, arguments_len; - uint64_t amount_ptr[2]; // amount is u128 - uint64_t gas; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[1]); - arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[2]); - if (quickjs_to_u128(ctx, argv[3], amount_ptr) != 0) { - return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); - } - if (JS_ToUint64Ext(ctx, &gas, argv[4]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); - } - promise_batch_action_function_call(promise_index, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_transfer(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - uint64_t amount_ptr[2]; // amount is u128 - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - if (quickjs_to_u128(ctx, argv[1], amount_ptr) != 0) { - return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); - } - promise_batch_action_transfer(promise_index, (uint64_t)amount_ptr); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_stake(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - uint64_t amount_ptr[2]; - const char *public_key_ptr; - size_t public_key_len; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - if (quickjs_to_u128(ctx, argv[1], amount_ptr) != 0) { - return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); - } - public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[2]); - - promise_batch_action_stake(promise_index, (uint64_t)amount_ptr, public_key_len, (uint64_t)public_key_ptr); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_add_key_with_full_access(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *public_key_ptr; - size_t public_key_len; - uint64_t nonce; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[1]); - if (JS_ToUint64Ext(ctx, &nonce, argv[2]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for nonce"); - } - promise_batch_action_add_key_with_full_access(promise_index, public_key_len, (uint64_t)public_key_ptr, nonce); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_add_key_with_function_call(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *public_key_ptr, *receiver_id_ptr, *method_names_ptr; - size_t public_key_len, receiver_id_len, method_names_len; - uint64_t nonce, allowance_ptr[2]; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[1]); - if (JS_ToUint64Ext(ctx, &nonce, argv[2]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for nonce"); - } - if (quickjs_to_u128(ctx, argv[3], allowance_ptr) != 0) { - return JS_ThrowTypeError(ctx, "Expect Uint128 for allowance"); - } - receiver_id_ptr = JS_ToCStringLen(ctx, &receiver_id_len, argv[4]); - method_names_ptr = JS_ToCStringLen(ctx, &method_names_len, argv[5]); - - promise_batch_action_add_key_with_function_call(promise_index, public_key_len, (uint64_t)public_key_ptr, nonce, (uint64_t)allowance_ptr, receiver_id_len, (uint64_t)receiver_id_ptr, method_names_len, (uint64_t)method_names_ptr); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_delete_key(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *public_key_ptr; - size_t public_key_len; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[1]); - promise_batch_action_delete_key(promise_index, public_key_len, (uint64_t)public_key_ptr); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_function_call_weight(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *method_name_ptr, *arguments_ptr; - size_t method_name_len, arguments_len; - uint64_t amount_ptr[2]; // amount is u128 - uint64_t gas; - uint64_t weight; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[1]); - arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[2]); - if (quickjs_to_u128(ctx, argv[3], amount_ptr) != 0) { - return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); - } - if (JS_ToUint64Ext(ctx, &gas, argv[4]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); - } - if (JS_ToUint64Ext(ctx, &weight, argv[5]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for weight"); - } - promise_batch_action_function_call_weight(promise_index, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas, weight); - return JS_UNDEFINED; -} - -static JSValue near_promise_batch_action_delete_account(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_index; - const char *beneficiary_id_ptr; - size_t beneficiary_id_len; - - if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); - } - beneficiary_id_ptr = JS_ToCStringLen(ctx, &beneficiary_id_len, argv[1]); - promise_batch_action_delete_account(promise_index, beneficiary_id_len, (uint64_t)beneficiary_id_ptr); - return JS_UNDEFINED; -} - -static JSValue near_promise_results_count(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t value; - - value = promise_results_count(); - return JS_NewBigUint64(ctx, value); -} - -static JSValue near_promise_result(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t result_idx, register_id; - uint64_t ret; - - if (JS_ToUint64Ext(ctx, &result_idx, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for result_idx"); - } - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - ret = promise_result(result_idx, register_id); - - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_promise_return(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t promise_idx; - if (JS_ToUint64Ext(ctx, &promise_idx, argv[0]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_idx"); - } - promise_return(promise_idx); - - return JS_UNDEFINED; -} - -static JSValue near_storage_write(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *key_ptr, *value_ptr; - size_t key_len, value_len; - uint64_t register_id, ret; - - key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); - value_ptr = JS_ToCStringLenRaw(ctx, &value_len, argv[1]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[2]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - ret = storage_write(key_len, (uint64_t)key_ptr, value_len, (uint64_t)value_ptr, register_id); - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_storage_read(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *key_ptr; - size_t key_len; - uint64_t register_id; - uint64_t ret; - - key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - ret = storage_read(key_len, (uint64_t)key_ptr, register_id); - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_storage_remove(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *key_ptr; - size_t key_len; - uint64_t register_id; - uint64_t ret; - - key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - ret = storage_remove(key_len, (uint64_t)key_ptr, register_id); - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_storage_has_key(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *key_ptr; - size_t key_len; - uint64_t ret; - - key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); - ret = storage_has_key(key_len, (uint64_t)key_ptr); - return JS_NewBigUint64(ctx, ret); -} - -static JSValue near_validator_stake(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *account_id_ptr; - size_t account_id_len; - uint64_t stake_ptr[2]; - - account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[0]); - validator_stake(account_id_len, (uint64_t)account_id_ptr, (uint64_t)stake_ptr); - - return u128_to_quickjs(ctx, stake_ptr); -} - -static JSValue near_validator_total_stake(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t stake_ptr[2]; - - validator_total_stake((uint64_t)stake_ptr); - return u128_to_quickjs(ctx, stake_ptr); -} - -#ifdef NIGHTLY -static JSValue near_alt_bn128_g1_multiexp(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - - alt_bn128_g1_multiexp(data_len, (uint64_t)data_ptr, register_id); - return JS_UNDEFINED; -} - -static JSValue near_alt_bn128_g1_sum(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - uint64_t register_id; - const char *data_ptr; - size_t data_len; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { - return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); - } - - alt_bn128_g1_sum(data_len, (uint64_t)data_ptr, register_id); - return JS_UNDEFINED; -} - -static JSValue near_alt_bn128_pairing_check(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) -{ - const char *data_ptr; - size_t data_len; - uint64_t ret; - - data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); - - ret = alt_bn128_pairing_check(data_len, (uint64_t)data_ptr); - return JS_NewBigUint64(ctx, ret); -} -#endif - -static void js_add_near_host_functions(JSContext* ctx) { - JSValue global_obj, env; - - global_obj = JS_GetGlobalObject(ctx); - env = JS_NewObject(ctx); - - JS_SetPropertyStr(ctx, env, "read_register", JS_NewCFunction(ctx, near_read_register, "read_register", 1)); - JS_SetPropertyStr(ctx, env, "register_len", JS_NewCFunction(ctx, near_register_len, "register_len", 1)); - JS_SetPropertyStr(ctx, env, "write_register", JS_NewCFunction(ctx, near_write_register, "write_register", 2)); - JS_SetPropertyStr(ctx, env, "current_account_id", JS_NewCFunction(ctx, near_current_account_id, "current_account_id", 1)); - JS_SetPropertyStr(ctx, env, "signer_account_id", JS_NewCFunction(ctx, near_signer_account_id, "signer_account_id", 1)); - JS_SetPropertyStr(ctx, env, "signer_account_pk", JS_NewCFunction(ctx, near_signer_account_pk, "signer_account_pk", 1)); - JS_SetPropertyStr(ctx, env, "predecessor_account_id", JS_NewCFunction(ctx, near_predecessor_account_id, "predecessor_account_id", 1)); - JS_SetPropertyStr(ctx, env, "input", JS_NewCFunction(ctx, near_input, "input", 1)); - JS_SetPropertyStr(ctx, env, "block_index", JS_NewCFunction(ctx, near_block_index, "block_index", 0)); - JS_SetPropertyStr(ctx, env, "block_timestamp", JS_NewCFunction(ctx, near_block_timestamp, "block_timestamp", 0)); - JS_SetPropertyStr(ctx, env, "epoch_height", JS_NewCFunction(ctx, near_epoch_height, "epoch_height", 0)); - JS_SetPropertyStr(ctx, env, "storage_usage", JS_NewCFunction(ctx, near_storage_usage, "storage_usage", 0)); - JS_SetPropertyStr(ctx, env, "account_balance", JS_NewCFunction(ctx, near_account_balance, "account_balance", 0)); - JS_SetPropertyStr(ctx, env, "account_locked_balance", JS_NewCFunction(ctx, near_account_locked_balance, "account_locked_balance", 0)); - JS_SetPropertyStr(ctx, env, "attached_deposit", JS_NewCFunction(ctx, near_attached_deposit, "attached_deposit", 0)); - JS_SetPropertyStr(ctx, env, "prepaid_gas", JS_NewCFunction(ctx, near_prepaid_gas, "prepaid_gas", 0)); - JS_SetPropertyStr(ctx, env, "used_gas", JS_NewCFunction(ctx, near_used_gas, "used_gas", 0)); - JS_SetPropertyStr(ctx, env, "random_seed", JS_NewCFunction(ctx, near_random_seed, "random_seed", 1)); - JS_SetPropertyStr(ctx, env, "sha256", JS_NewCFunction(ctx, near_sha256, "sha256", 2)); - JS_SetPropertyStr(ctx, env, "keccak256", JS_NewCFunction(ctx, near_keccak256, "keccak256", 2)); - JS_SetPropertyStr(ctx, env, "keccak512", JS_NewCFunction(ctx, near_keccak512, "keccak512", 2)); - JS_SetPropertyStr(ctx, env, "ripemd160", JS_NewCFunction(ctx, near_ripemd160, "ripemd160", 2)); - JS_SetPropertyStr(ctx, env, "ecrecover", JS_NewCFunction(ctx, near_ecrecover, "ecrecover", 5)); - JS_SetPropertyStr(ctx, env, "value_return", JS_NewCFunction(ctx, near_value_return, "value_return", 1)); - JS_SetPropertyStr(ctx, env, "panic", JS_NewCFunction(ctx, near_panic, "panic", 1)); - JS_SetPropertyStr(ctx, env, "panic_utf8", JS_NewCFunction(ctx, near_panic_utf8, "panic_utf8", 1)); - JS_SetPropertyStr(ctx, env, "log", JS_NewCFunction(ctx, near_log, "log", 1)); - JS_SetPropertyStr(ctx, env, "log_utf8", JS_NewCFunction(ctx, near_log_utf8, "log_utf8", 1)); - JS_SetPropertyStr(ctx, env, "log_utf16", JS_NewCFunction(ctx, near_log_utf16, "log_utf16", 1)); - JS_SetPropertyStr(ctx, env, "promise_create", JS_NewCFunction(ctx, near_promise_create, "promise_create", 5)); - JS_SetPropertyStr(ctx, env, "promise_then", JS_NewCFunction(ctx, near_promise_then, "promise_then", 6)); - JS_SetPropertyStr(ctx, env, "promise_and", JS_NewCFunction(ctx, near_promise_and, "promise_and", 1)); - JS_SetPropertyStr(ctx, env, "promise_batch_create", JS_NewCFunction(ctx, near_promise_batch_create, "promise_batch_create", 1)); - JS_SetPropertyStr(ctx, env, "promise_batch_then", JS_NewCFunction(ctx, near_promise_batch_then, "promise_batch_then", 2)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_create_account", JS_NewCFunction(ctx, near_promise_batch_action_create_account, "promise_batch_action_create_account", 1)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_deploy_contract", JS_NewCFunction(ctx, near_promise_batch_action_deploy_contract, "promise_batch_action_deploy_contract", 2)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_function_call", JS_NewCFunction(ctx, near_promise_batch_action_function_call, "promise_batch_action_function_call", 5)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_transfer", JS_NewCFunction(ctx, near_promise_batch_action_transfer, "promise_batch_action_transfer", 2)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_stake", JS_NewCFunction(ctx, near_promise_batch_action_stake, "promise_batch_action_stake", 3)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_add_key_with_full_access", JS_NewCFunction(ctx, near_promise_batch_action_add_key_with_full_access, "promise_batch_action_add_key_with_full_access", 3)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_add_key_with_function_call", JS_NewCFunction(ctx, near_promise_batch_action_add_key_with_function_call, "promise_batch_action_add_key_with_function_call", 6)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_delete_key", JS_NewCFunction(ctx, near_promise_batch_action_delete_key, "promise_batch_action_delete_key", 2)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_delete_account", JS_NewCFunction(ctx, near_promise_batch_action_delete_account, "promise_batch_action_delete_account", 2)); - JS_SetPropertyStr(ctx, env, "promise_batch_action_function_call_weight", JS_NewCFunction(ctx, near_promise_batch_action_function_call_weight, "promise_batch_action_function_call_weight", 6)); - JS_SetPropertyStr(ctx, env, "promise_results_count", JS_NewCFunction(ctx, near_promise_results_count, "promise_results_count", 0)); - JS_SetPropertyStr(ctx, env, "promise_result", JS_NewCFunction(ctx, near_promise_result, "promise_result", 2)); - JS_SetPropertyStr(ctx, env, "promise_return", JS_NewCFunction(ctx, near_promise_return, "promise_return", 1)); - JS_SetPropertyStr(ctx, env, "storage_write", JS_NewCFunction(ctx, near_storage_write, "storage_write", 2)); - JS_SetPropertyStr(ctx, env, "storage_read", JS_NewCFunction(ctx, near_storage_read, "storage_read", 2)); - JS_SetPropertyStr(ctx, env, "storage_remove", JS_NewCFunction(ctx, near_storage_remove, "storage_remove", 2)); - JS_SetPropertyStr(ctx, env, "storage_has_key", JS_NewCFunction(ctx, near_storage_has_key, "storage_has_key", 2)); - JS_SetPropertyStr(ctx, env, "validator_stake", JS_NewCFunction(ctx, near_validator_stake, "validator_stake", 2)); - JS_SetPropertyStr(ctx, env, "validator_total_stake", JS_NewCFunction(ctx, near_validator_total_stake, "validator_total_stake", 1)); - #ifdef NIGHTLY - // as of Jun 24, 2022, alt_bn128 is not a nightly protocol feature any more. It's part of protocol version 55. But, testnet -// is at protocol version 54 and mainnet is at protocol version 53. We'll enable and add alt_bn128 as they in testnet. - JS_SetPropertyStr(ctx, env, "alt_bn128_g1_multiexp", JS_NewCFunction(ctx, near_alt_bn128_g1_multiexp, "alt_bn128_g1_multiexp", 2)); - JS_SetPropertyStr(ctx, env, "alt_bn128_g1_sum", JS_NewCFunction(ctx, near_alt_bn128_g1_sum, "alt_bn128_g1_sum", 2)); - JS_SetPropertyStr(ctx, env, "alt_bn128_pairing_check", JS_NewCFunction(ctx, near_alt_bn128_pairing_check, "alt_bn128_pairing_check", 1)); - #endif - - JS_SetPropertyStr(ctx, global_obj, "env", env); -} - -JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, - int argc, JSValueConst *argv); - -void _start() {} - -#include "methods.h" diff --git a/cli/cli.js b/cli/cli.js old mode 100755 new mode 100644 diff --git a/cli/package.json b/cli/package.json deleted file mode 100644 index 881a5a4b6..000000000 --- a/cli/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "near-sdk-js", - "version": "0.5.0-1", - "description": "High Level JavaScript SDK for building smart contracts on NEAR", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "type": "module", - "repository": { - "type": "git", - "url": "git+https://github.com/near/near-sdk-js.git" - }, - "homepage": "https://github.com/near/near-sdk-js", - "keywords": [ - "JS", - "JavaScript", - "NEAR", - "SDK", - "contract", - "smart", - "smart-contract" - ], - "license": "(MIT AND Apache-2.0)", - "scripts": { - "build": "yarn build:lib && yarn build:cli", - "build:lib": "tsc -p ./tsconfig.json", - "build:cli": "tsc -p ./tsconfig.cli.json", - "pretest": "yarn build", - "test": "yarn test:unit && yarn test:examples", - "lint": "eslint --fix .", - "format": "prettier --write .", - "test:unit": "yarn && cd tests && yarn && yarn build && yarn test && cd ..", - "test:examples": "yarn && cd examples && yarn && yarn build && yarn test && cd ..", - "postinstall": "cd cli && rm -rf deps && mkdir -p deps && cd deps && node ../post-install.js" - }, - "bin": { - "near-sdk-js": "cli/cli.js" - }, - "engines": { - "node": ">=14 <16.6.0 || >16.6.0" - }, - "author": "Near Inc ", - "dependencies": { - "@babel/core": "^7.17.5", - "@babel/plugin-proposal-decorators": "^7.17.2", - "@babel/preset-typescript": "^7.18.6", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^21.0.1", - "@rollup/plugin-node-resolve": "^13.1.1", - "@scure/base": "^1.1.1", - "commander": "^9.4.1", - "rollup": "^2.61.1", - "rollup-plugin-sourcemaps": "^0.6.3", - "signale": "^1.4.0", - "yargs": "^17.5.1" - }, - "files": [ - "cli", - "lib" - ], - "devDependencies": { - "@rollup/plugin-typescript": "^8.3.2", - "@types/babel__traverse": "^7.18.1", - "@types/node": "^17.0.38", - "@types/rollup": "^0.54.0", - "@types/signale": "^1.4.4", - "@types/yargs": "^17.0.13", - "@typescript-eslint/eslint-plugin": "^5.37.0", - "@typescript-eslint/parser": "^5.37.0", - "eslint": "^8.23.1", - "eslint-config-prettier": "^8.5.0", - "prettier": "^2.7.1", - "typescript": "^4.7.2" - } -} diff --git a/cli/src/cli/cli.d.ts b/cli/src/cli/cli.d.ts deleted file mode 100644 index 10fcdae58..000000000 --- a/cli/src/cli/cli.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env node -export declare function buildCom(source: string, target: string, { verbose }: { - verbose: boolean; -}): Promise; diff --git a/cli/src/cli/cli.js b/cli/src/cli/cli.js deleted file mode 100644 index 22688d320..000000000 --- a/cli/src/cli/cli.js +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env node -import fs from "fs/promises"; -import path, { basename, dirname } from "path"; -// import yargs from "yargs"; -// import { hideBin } from "yargs/helpers"; -import { nodeResolve } from "@rollup/plugin-node-resolve"; -import sourcemaps from "rollup-plugin-sourcemaps"; -import { babel } from "@rollup/plugin-babel"; -import { rollup } from "rollup"; -import { Command } from "commander"; -import signal from "signale"; -const { Signale } = signal; -import { executeCommand } from "./utils.js"; -const PROJECT_DIR = process.cwd(); -const NEAR_SDK_JS = "node_modules/near-sdk-js"; -const TSC = "node_modules/.bin/tsc"; -const QJSC_DIR = `${NEAR_SDK_JS}/cli/deps/quickjs`; -const QJSC = `${NEAR_SDK_JS}/cli/deps/qjsc`; -const program = new Command(); -function makeBuildCommand() { - return new Command("build") - .usage("[source] [target]") - .description("Build NEAR JS Smart-contract") - .argument("[source]", "Contract to build.", "src/index.js") - .argument("[target]", "Target file path and name.", "build/contract.wasm") - .option("--verbose", "Whether to print more verbose output.", false) - .action(console.log); -} -program - .name("near-sdk-js") - .version((await import("../../package.json", { assert: { type: "json" } })).version) - .addCommand(makeBuildCommand()) - .parse(); -export async function buildCom(source, target, { verbose = false }) { - console.log(source, target); - const SOURCE_EXT = source.split(".").pop(); - const TARGET_DIR = dirname(target); - const TARGET_EXT = target.split(".").pop(); - const TARGET_FILE_NAME = basename(target, `.${TARGET_EXT}`); - const signale = new Signale({ scope: "near-sdk-js", interactive: true }); - if (TARGET_EXT !== "wasm") { - signale.error(`Unsupported target ${TARGET_EXT}, make sure target ends with .wasm!`); - process.exit(1); - } - const ROLLUP_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.js`; - const QJSC_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.h`; - const CONTRACT_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.wasm`; - signale.await(`Building ${source} contract...`); - if (SOURCE_EXT === "ts") { - signale.await(`Typechecking ${source} with tsc...`); - await checkTsBuildWithTsc(source, verbose); - } - signale.await(`Creating ${TARGET_DIR} directory...`); - await executeCommand(`mkdir -p ${TARGET_DIR}`, verbose); - signale.await(`Creating ${source} file with Rollup...`); - await createJsFileWithRullup(source, ROLLUP_TARGET, verbose); - signale.await(`Creating ${QJSC_TARGET} file with QJSC...`); - await createHeaderFileWithQjsc(ROLLUP_TARGET, QJSC_TARGET, verbose); - signale.await("Generating methods.h file..."); - await createMethodsHeaderFile(ROLLUP_TARGET, verbose); - signale.await(`Creating ${CONTRACT_TARGET} contract...`); - await createWasmContract(QJSC_TARGET, CONTRACT_TARGET, verbose); - signale.await("Executing wasi-stub..."); - await wasiStubContract(CONTRACT_TARGET, verbose); - signale.success("Generated contract successfully!"); -} -// yargs(hideBin(process.argv)) -// .scriptName("near-sdk-js") -// .usage("$0 [args]") -// .command( -// "build [source] [target]", -// "Build NEAR JS Smart-contract", -// (yargs) => { -// yargs -// .positional("source", { -// type: "string", -// default: "src/index.js", -// describe: "Contract to build", -// }) -// .positional("target", { -// type: "string", -// default: "build/contract.wasm", -// describe: "Target file path and name", -// }); -// }, -// build -// ) -// .help().argv; -// -// async function build(argv: yargs.ArgumentsCamelCase): Promise { -// const SOURCE_FILE_WITH_PATH = argv.source; -// const SOURCE_EXT = argv.source.split(".").pop(); -// const TARGET_DIR = path.dirname(argv.target); -// const TARGET_EXT = argv.target.split(".").pop(); -// const TARGET_FILE_NAME = path.basename(argv.target, `.${TARGET_EXT}`); -// -// if ("wasm" !== TARGET_EXT) { -// throw new Error( -// `Unsupported target ${TARGET_EXT}, make sure target ends with .wasm` -// ); -// } -// -// const ROLLUP_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.js`; -// const QJSC_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.h`; -// const CONTRACT_TARGET = `${TARGET_DIR}/${TARGET_FILE_NAME}.wasm`; -// -// console.log(`Building ${SOURCE_FILE_WITH_PATH} contract...`); -// -// if (SOURCE_EXT === "ts") { -// await checkTsBuildWithTsc(SOURCE_FILE_WITH_PATH); -// } -// -// console.log(`Creating ${TARGET_DIR} directory...`); -// await executeCommand(`mkdir -p ${TARGET_DIR}`); -// -// await createJsFileWithRullup(SOURCE_FILE_WITH_PATH, ROLLUP_TARGET); -// -// await createHeaderFileWithQjsc(ROLLUP_TARGET, QJSC_TARGET); -// -// await createMethodsHeaderFile(ROLLUP_TARGET); -// await createWasmContract(QJSC_TARGET, CONTRACT_TARGET); -// await wasiStubContract(CONTRACT_TARGET); -// } -async function checkTsBuildWithTsc(sourceFileWithPath, verbose = false) { - await executeCommand(`${TSC} --noEmit --experimentalDecorators --target es2020 --moduleResolution node ${sourceFileWithPath}`, verbose); -} -// Common build function -async function createJsFileWithRullup(sourceFileWithPath, rollupTarget, _verbose = false) { - const bundle = await rollup({ - input: sourceFileWithPath, - plugins: [ - nodeResolve({ - extensions: [".js", ".ts"], - }), - sourcemaps(), - // commonjs(), - babel({ - babelHelpers: "bundled", - extensions: [".ts", ".js", ".jsx", ".es6", ".es", ".mjs"], - presets: ["@babel/preset-typescript"], - plugins: [ - "near-sdk-js/lib/build-tools/include-bytes.js", - "near-sdk-js/lib/build-tools/near-bindgen-exporter.js", - ["@babel/plugin-proposal-decorators", { version: "legacy" }], - ], - }), - ], - }); - await bundle.write({ - sourcemap: true, - file: rollupTarget, - format: "es", - }); -} -async function createHeaderFileWithQjsc(rollupTarget, qjscTarget, verbose = false) { - await executeCommand(`${QJSC} -c -m -o ${qjscTarget} -N code ${rollupTarget}`, verbose); -} -async function createMethodsHeaderFile(rollupTarget, verbose = false) { - const buildPath = path.dirname(rollupTarget); - if (verbose) { - console.log(rollupTarget); - } - const mod = await import(`${PROJECT_DIR}/${rollupTarget}`); - const exportNames = Object.keys(mod); - const methods = exportNames.reduce((result, key) => `${result}DEFINE_NEAR_METHOD(${key})\n`, ""); - await fs.writeFile(`${buildPath}/methods.h`, methods); -} -async function createWasmContract(qjscTarget, contractTarget, verbose = false) { - const WASI_SDK_PATH = `${NEAR_SDK_JS}/cli/deps/wasi-sdk`; - const CC = `${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot`; - let DEFS = `-D_GNU_SOURCE '-DCONFIG_VERSION="2021-03-27"' -DCONFIG_BIGNUM`; - if (process.env.NEAR_NIGHTLY) { - DEFS = DEFS + " -DNIGHTLY"; - } - const INCLUDES = `-I${QJSC_DIR} -I.`; - const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/cli/builder/builder.c`; - const NEW_BUILDER_PATH = `${path.dirname(contractTarget)}/builder.c`; - const SOURCES = `${NEW_BUILDER_PATH} ${QJSC_DIR}/quickjs.c ${QJSC_DIR}/libregexp.c ${QJSC_DIR}/libunicode.c ${QJSC_DIR}/cutils.c ${QJSC_DIR}/quickjs-libc-min.c ${QJSC_DIR}/libbf.c`; - const LIBS = `-lm`; - // copying builder.c file to the build folder - await executeCommand(`cp ${ORIGINAL_BUILDER_PATH} ${NEW_BUILDER_PATH}`, verbose); - await executeCommand(`mv ${qjscTarget} build/code.h`, verbose); - await executeCommand(`${CC} --target=wasm32-wasi -nostartfiles -Oz -flto ${DEFS} ${INCLUDES} ${SOURCES} ${LIBS} -Wl,--no-entry -Wl,--allow-undefined -Wl,-z,stack-size=${256 * 1024} -Wl,--lto-O3 -o ${contractTarget}`, verbose); -} -async function wasiStubContract(contractTarget, verbose = false) { - const WASI_STUB = `${NEAR_SDK_JS}/cli/deps/binaryen/wasi-stub/run.sh`; - await executeCommand(`${WASI_STUB} ${contractTarget} >/dev/null`, verbose); -} diff --git a/cli/src/cli/post-install.d.ts b/cli/src/cli/post-install.d.ts deleted file mode 100644 index cb0ff5c3b..000000000 --- a/cli/src/cli/post-install.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/cli/src/cli/post-install.js b/cli/src/cli/post-install.js deleted file mode 100644 index 698539638..000000000 --- a/cli/src/cli/post-install.js +++ /dev/null @@ -1,60 +0,0 @@ -import { executeCommand } from "./utils.js"; -async function download(url, verbose = false) { - await executeCommand(`curl -LOf ${url}`, verbose); -} -const OS = await executeCommand("uname -s", false); -const ARCH = await executeCommand("uname -m", false); -if (OS !== "Linux" && OS !== "Darwin") { - console.error(`OS ${OS} is not supported at the moment`); - process.exit(1); -} -if (ARCH !== "x86_64" && ARCH !== "arm64") { - console.error(` ${ARCH} architecture is unsapported at the moment`); - process.exit(1); -} -console.log("Installing wasi-stub..."); -const BINARYEN_VERSION = `0.1.10`; -const BINARYEN_VERSION_TAG = `v${BINARYEN_VERSION}`; -const BINARYEN_SYSTEM_NAME = OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; -const BINARYEN_ARCH_NAME = ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; -const BINARYEN_TAR_NAME = `binaryen-${BINARYEN_SYSTEM_NAME}-${BINARYEN_ARCH_NAME}.tar.gz`; -await download(`https://github.com/near/binaryen/releases/download/${BINARYEN_VERSION_TAG}/${BINARYEN_TAR_NAME}`); -await executeCommand(`mkdir -p binaryen && tar xvf ${BINARYEN_TAR_NAME} --directory binaryen`); -await executeCommand(`rm ${BINARYEN_TAR_NAME}`); -console.log("Installing QuickJS..."); -const QUICK_JS_VERSION = `0.1.2`; -const QUICK_JS_VERSION_TAG = `v${QUICK_JS_VERSION}`; -const QUICK_JS_SYSTEM_NAME = OS === "Linux" ? "Linux" : OS === "Darwin" ? "macOS" : "other"; -const QUICK_JS_ARCH_NAME = ARCH === "x86_64" ? "X64" : ARCH === "arm64" ? "arm64" : "other"; -const QUICK_JS_TAR_NAME = `${QUICK_JS_VERSION_TAG}.tar.gz`; -const QUICK_JS_DOWNLOADED_FOLDER_NAME = `quickjs-${QUICK_JS_VERSION}`; -const QUICK_JS_TARGET_FOLDER_NAME = "quickjs"; -const QUICK_JS_DOWNLOADED_NAME = `qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}`; -const QUICK_JS_TARGET_NAME = "qjsc"; -// Download QuickJS -await download(`https://github.com/near/quickjs/releases/download/${QUICK_JS_VERSION_TAG}/qjsc-${QUICK_JS_SYSTEM_NAME}-${QUICK_JS_ARCH_NAME}`); -await download(`https://github.com/near/quickjs/archive/refs/tags/${QUICK_JS_VERSION_TAG}.tar.gz`); -// Extract QuickJS -await executeCommand(`tar xvf ${QUICK_JS_TAR_NAME}`); -// Delete .tar file -await executeCommand(`rm ${QUICK_JS_TAR_NAME}`); -// Delete version from folder name -await executeCommand(`mv ${QUICK_JS_DOWNLOADED_FOLDER_NAME} ${QUICK_JS_TARGET_FOLDER_NAME}`); -// Rename qjsc file -await executeCommand(`mv ${QUICK_JS_DOWNLOADED_NAME} ${QUICK_JS_TARGET_NAME}`); -// chmod qjsc -await executeCommand(`chmod 777 ${QUICK_JS_TARGET_NAME}`); -console.log("Installing wasi-sdk..."); -const WASI_SDK_MAJOR_VER = 11; -const WASI_SDK_MINOR_VER = 0; -const WASI_SDK_DOWNLOADED_FOLDER_NAME = `wasi-sdk-${WASI_SDK_MAJOR_VER}.${WASI_SDK_MINOR_VER}`; -const WASI_SDK_SYSTEM_NAME = OS === "Linux" ? "linux" : OS === "Darwin" ? "macos" : "other"; -const WASI_SDK_TAR_NAME = `${WASI_SDK_DOWNLOADED_FOLDER_NAME}-${WASI_SDK_SYSTEM_NAME}.tar.gz`; -// Download WASI SDK -await download(`https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_MAJOR_VER}/${WASI_SDK_TAR_NAME}`); -// Extract WASI SDK -await executeCommand(`tar xvf ${WASI_SDK_TAR_NAME}`); -// Delete .tar file -await executeCommand(`rm ${WASI_SDK_TAR_NAME}`); -// Delete version from folder name -await executeCommand(`mv ${WASI_SDK_DOWNLOADED_FOLDER_NAME} wasi-sdk`); diff --git a/cli/src/cli/save-bytecode.d.ts b/cli/src/cli/save-bytecode.d.ts deleted file mode 100644 index cb0ff5c3b..000000000 --- a/cli/src/cli/save-bytecode.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/cli/src/cli/save-bytecode.js b/cli/src/cli/save-bytecode.js deleted file mode 100644 index 6adcb4ccd..000000000 --- a/cli/src/cli/save-bytecode.js +++ /dev/null @@ -1,22 +0,0 @@ -import { readFile, writeFile } from "fs/promises"; -import { resolve } from "path"; -//TODO: execute it in js env -async function main() { - const source = resolve(process.argv[process.argv.length - 2]); - const target = resolve(process.argv[process.argv.length - 1]); - const code = await readFile(source, "utf-8"); - const codes = code - .split("\n") - .map((line) => { - if (line.indexOf("0x") < 0) { - return []; - } - const trimmedLine = line.trim(); - const numbers = trimmedLine.slice(0, trimmedLine.length - 1).split(", "); - return numbers.map(Number); - }) - .filter((numbers) => numbers.length); - const bytecode = Buffer.concat(codes.map(Buffer.from)); - await writeFile(target, bytecode.toString("base64")); -} -main(); diff --git a/cli/src/cli/utils.d.ts b/cli/src/cli/utils.d.ts deleted file mode 100644 index 2361fd683..000000000 --- a/cli/src/cli/utils.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare function executeCommand(command: string, silent?: boolean): Promise; diff --git a/cli/src/cli/utils.js b/cli/src/cli/utils.js deleted file mode 100644 index a11d66902..000000000 --- a/cli/src/cli/utils.js +++ /dev/null @@ -1,22 +0,0 @@ -import childProcess from "child_process"; -import { promisify } from "util"; -const exec = promisify(childProcess.exec); -export async function executeCommand(command, silent = false) { - if (!silent) { - console.log(command); - } - try { - const { stdout, stderr } = await exec(command); - if (stderr && !silent) { - console.error(stderr); - } - if (!silent) { - console.log(stdout); - } - return stdout.trim(); - } - catch (error) { - console.log(error); - process.exit(1); - } -} diff --git a/cli/src/cli/wasm-to-bytes.d.ts b/cli/src/cli/wasm-to-bytes.d.ts deleted file mode 100644 index cb0ff5c3b..000000000 --- a/cli/src/cli/wasm-to-bytes.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/cli/src/cli/wasm-to-bytes.js b/cli/src/cli/wasm-to-bytes.js deleted file mode 100644 index adc1018cd..000000000 --- a/cli/src/cli/wasm-to-bytes.js +++ /dev/null @@ -1,16 +0,0 @@ -import { readFile, writeFile } from "fs/promises"; -import { resolve } from "path"; -// used for deploy code in contract with near.promiseBatchActionDeployContract. -// Usage: -// node wasm_to_bytes.js contract.wasm contract.jsbytes -// copy paste the content of the contract.jsbytes, pass it as arguments to near.promiseBatchActionDeployContract: -// near.promiseBatchActionDeployContract(promsieId, '') -// Note, do not use `bytes()` type check here, which is too expensive for this long bytes and will exceed gas limit. -async function main() { - const source = resolve(process.argv[process.argv.length - 2]); - const target = resolve(process.argv[process.argv.length - 1]); - const code = await readFile(source); - const result = code.reduce((result, character) => `${result}\\x${character.toString(16).padStart(2, "0")}`, ""); - await writeFile(target, result); -} -main(); From 044bcbbf9ed1bd91b3be88c8a198624107a5a6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 16:08:42 +0200 Subject: [PATCH 6/9] fix: Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 971b987d5..ce142b630 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules yarn-error.log vendor .idea +cli/deps From a661bfa3439b57882769e0c69fc5b4e505e040ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 16:39:56 +0200 Subject: [PATCH 7/9] fix: Fix building Remove comments Restore builder.c file Update build:cli script to change cli.js to be executable --- cli/builder/builder.c | 1036 +++++++++++++++++++++++++++++++++++++++++ cli/cli.js | 4 +- package.json | 2 +- src/cli/cli.ts | 8 +- 4 files changed, 1040 insertions(+), 10 deletions(-) create mode 100644 cli/builder/builder.c mode change 100644 => 100755 cli/cli.js mode change 100644 => 100755 src/cli/cli.ts diff --git a/cli/builder/builder.c b/cli/builder/builder.c new file mode 100644 index 000000000..7da615b82 --- /dev/null +++ b/cli/builder/builder.c @@ -0,0 +1,1036 @@ +#include +#include "../node_modules/near-sdk-js/cli/deps/quickjs/quickjs-libc-min.h" +#include "../node_modules/near-sdk-js/cli/deps/quickjs/libbf.h" +#include "code.h" + +static JSContext *JS_NewCustomContext(JSRuntime *rt) +{ + JSContext *ctx = JS_NewContextRaw(rt); + if (!ctx) + return NULL; + JS_AddIntrinsicBaseObjects(ctx); + JS_AddIntrinsicDate(ctx); + JS_AddIntrinsicEval(ctx); + JS_AddIntrinsicStringNormalize(ctx); + JS_AddIntrinsicRegExp(ctx); + JS_AddIntrinsicJSON(ctx); + JS_AddIntrinsicProxy(ctx); + JS_AddIntrinsicMapSet(ctx); + JS_AddIntrinsicTypedArrays(ctx); + JS_AddIntrinsicPromise(ctx); + JS_AddIntrinsicBigInt(ctx); + return ctx; +} + +#define DEFINE_NEAR_METHOD(name) \ + void name () __attribute__((export_name(#name))) {\ + JSRuntime *rt;\ + JSContext *ctx;\ + JSValue mod_obj, fun_obj, result, error, error_message, error_stack;\ + const char *error_message_c, *error_stack_c;\ + char *error_c;\ + size_t msg_len, stack_len;\ + rt = JS_NewRuntime();\ + ctx = JS_NewCustomContext(rt);\ + js_add_near_host_functions(ctx);\ + mod_obj = js_load_module_binary(ctx, code, code_size);\ + fun_obj = JS_GetProperty(ctx, mod_obj, JS_NewAtom(ctx, #name));\ + result = JS_Call(ctx, fun_obj, mod_obj, 0, NULL);\ + if (JS_IsException(result)) {\ + error = JS_GetException(ctx);\ + error_message = JS_GetPropertyStr(ctx, error, "message");\ + error_stack = JS_GetPropertyStr(ctx, error, "stack");\ + error_message_c = JS_ToCStringLen(ctx, &msg_len, error_message);\ + error_stack_c = JS_ToCStringLen(ctx, &stack_len, error_stack);\ + error_c = malloc(msg_len+1+stack_len);\ + strncpy(error_c, error_message_c, msg_len);\ + error_c[msg_len] = '\n';\ + strncpy(error_c+msg_len+1, error_stack_c, stack_len);\ + panic_utf8(msg_len+1+stack_len, (uint64_t)error_c);\ + }\ + js_std_loop(ctx);\ + } + +// ############# +// # Registers # +// ############# +extern void read_register(uint64_t register_id, uint64_t ptr); +extern uint64_t register_len(uint64_t register_id); +extern void write_register(uint64_t register_id, uint64_t data_len, uint64_t data_ptr); +// ############### +// # Context API # +// ############### +extern void current_account_id(uint64_t register_id); +extern void signer_account_id(uint64_t register_id); +extern void signer_account_pk(uint64_t register_id); +extern void predecessor_account_id(uint64_t register_id); +extern void input(uint64_t register_id); +extern uint64_t block_index(); +extern uint64_t block_timestamp(); +extern uint64_t epoch_height(); +extern uint64_t storage_usage(); +// ################# +// # Economics API # +// ################# +extern void account_balance(uint64_t balance_ptr); +extern void account_locked_balance(uint64_t balance_ptr); +extern void attached_deposit(uint64_t balance_ptr); +extern uint64_t prepaid_gas(); +extern uint64_t used_gas(); +// ############ +// # Math API # +// ############ +extern void random_seed(uint64_t register_id); +extern void sha256(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); +extern void keccak256(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); +extern void keccak512(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); +extern void ripemd160(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); +extern uint64_t ecrecover(uint64_t hash_len, uint64_t hash_ptr, uint64_t sign_len, uint64_t sig_ptr, uint64_t v, uint64_t malleability_flag, uint64_t register_id); +// ##################### +// # Miscellaneous API # +// ##################### +extern void value_return(uint64_t value_len, uint64_t value_ptr); +extern void panic(void); +extern void panic_utf8(uint64_t len, uint64_t ptr); +extern void log_utf8(uint64_t len, uint64_t ptr); +extern void log_utf16(uint64_t len, uint64_t ptr); +// Name confliction with WASI. Can be re-exported with a different name on NEAR side with a protocol upgrade +// Or, this is actually not a primitive, can be implement with log and panic host functions in C side or JS side. +// extern void abort(uint32_t msg_ptr, uint32_t filename_ptr, uint32_t u32, uint32_t col); +// ################ +// # Promises API # +// ################ +extern uint64_t promise_create(uint64_t account_id_len, uint64_t account_id_ptr, uint64_t method_name_len, uint64_t method_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas); +extern uint64_t promise_then(uint64_t promise_index, uint64_t account_id_len, uint64_t account_id_ptr, uint64_t method_name_len, uint64_t method_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas); +extern uint64_t promise_and(uint64_t promise_idx_ptr, uint64_t promise_idx_count); +extern uint64_t promise_batch_create(uint64_t account_id_len, uint64_t account_id_ptr); +extern uint64_t promise_batch_then(uint64_t promise_index, uint64_t account_id_len, uint64_t account_id_ptr); +// ####################### +// # Promise API actions # +// ####################### +extern void promise_batch_action_create_account(uint64_t promise_index); +extern void promise_batch_action_deploy_contract(uint64_t promise_index, uint64_t code_len, uint64_t code_ptr); +extern void promise_batch_action_function_call(uint64_t promise_index, uint64_t method_name_len, uint64_t method_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas); +extern void promise_batch_action_transfer(uint64_t promise_index, uint64_t amount_ptr); +extern void promise_batch_action_stake(uint64_t promise_index, uint64_t amount_ptr, uint64_t public_key_len, uint64_t public_key_ptr); +extern void promise_batch_action_add_key_with_full_access(uint64_t promise_index, uint64_t public_key_len, uint64_t public_key_ptr, uint64_t nonce); +extern void promise_batch_action_add_key_with_function_call(uint64_t promise_index, uint64_t public_key_len, uint64_t public_key_ptr, uint64_t nonce, uint64_t allowance_ptr, uint64_t receiver_id_len, uint64_t receiver_id_ptr, uint64_t method_names_len, uint64_t method_names_ptr); +extern void promise_batch_action_delete_key(uint64_t promise_index, uint64_t public_key_len, uint64_t public_key_ptr); +extern void promise_batch_action_delete_account(uint64_t promise_index, uint64_t beneficiary_id_len, uint64_t beneficiary_id_ptr); +extern void promise_batch_action_function_call_weight(uint64_t promise_index, uint64_t function_name_len, uint64_t function_name_ptr, uint64_t arguments_len, uint64_t arguments_ptr, uint64_t amount_ptr, uint64_t gas, uint64_t weight); +// ####################### +// # Promise API results # +// ####################### +extern uint64_t promise_results_count(void); +extern uint64_t promise_result(uint64_t result_idx, uint64_t register_id); +extern void promise_return(uint64_t promise_idx); +// ############### +// # Storage API # +// ############### +extern uint64_t storage_write(uint64_t key_len, uint64_t key_ptr, uint64_t value_len, uint64_t value_ptr, uint64_t register_id); +extern uint64_t storage_read(uint64_t key_len, uint64_t key_ptr, uint64_t register_id); +extern uint64_t storage_remove(uint64_t key_len, uint64_t key_ptr, uint64_t register_id); +extern uint64_t storage_has_key(uint64_t key_len, uint64_t key_ptr); +// ################# +// # Validator API # +// ################# +extern void validator_stake(uint64_t account_id_len, uint64_t account_id_ptr, uint64_t stake_ptr); +extern void validator_total_stake(uint64_t stake_ptr); +// ############# +// # Alt BN128 # +// ############# +#ifdef NIGHTLY +extern void alt_bn128_g1_multiexp(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); +extern void alt_bn128_g1_sum(uint64_t value_len, uint64_t value_ptr, uint64_t register_id); +extern uint64_t alt_bn128_pairing_check(uint64_t value_len, uint64_t value_ptr); +#endif + +static JSValue near_read_register(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + char *data; + uint64_t data_len; + JSValue ret; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + data_len = register_len(register_id); + if (data_len != UINT64_MAX) { + data = malloc(data_len); + read_register(register_id, (uint64_t)data); + ret = JS_NewStringLenRaw(ctx, data, data_len); + free(data); + return ret; + } else { + return JS_UNDEFINED; + } +} + +static JSValue near_register_len(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id, len; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + len = register_len(register_id); + return JS_NewBigUint64(ctx, len); +} + +static JSValue near_write_register(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + const char *data_ptr; + size_t data_len; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[1]); + + write_register(register_id, data_len, (uint64_t)data_ptr); + return JS_UNDEFINED; +} + +static JSValue near_current_account_id(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + current_account_id(register_id); + return JS_UNDEFINED; +} + +static JSValue near_signer_account_id(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { + uint64_t register_id; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + signer_account_id(register_id); + return JS_UNDEFINED; +} + +static JSValue near_signer_account_pk(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { + uint64_t register_id; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + signer_account_pk(register_id); + return JS_UNDEFINED; +} + +static JSValue near_predecessor_account_id(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { + uint64_t register_id; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + predecessor_account_id(register_id); + return JS_UNDEFINED; +} + +static JSValue near_input(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + input(register_id); + return JS_UNDEFINED; +} + +static JSValue near_block_index(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t value; + + value = block_index(); + return JS_NewBigUint64(ctx, value); +} + +static JSValue near_block_timestamp(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t value; + + value = block_timestamp(); + return JS_NewBigUint64(ctx, value); +} + +static JSValue near_epoch_height(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t value; + + value = epoch_height(); + return JS_NewBigUint64(ctx, value); +} + +static JSValue near_storage_usage(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t value; + + value = storage_usage(); + return JS_NewBigUint64(ctx, value); +} + +// ptr[0] ptr[1] is little-endian u128. +static JSValue u128_to_quickjs(JSContext *ctx, uint64_t* ptr) { + JSValue value; + bf_t* bn; + bf_t b; + + value = JS_NewBigInt(ctx); + bn = JS_GetBigInt(value); + // from ptr[] to bn + // high 64 bits + bf_set_ui(bn, ptr[1]); + bf_mul_2exp(bn, 64, BF_PREC_INF, BF_RNDZ); + // low 64 bits + bf_init(bn->ctx, &b); + bf_set_ui(&b, ptr[0]); + bf_add(bn, bn, &b, BF_PREC_INF, BF_RNDZ); + bf_delete(&b); + + return value; +} + +static int quickjs_bigint_to_u128(JSContext *ctx, JSValueConst val, uint64_t* ptr) { + bf_t* a; + bf_t q, r, b, one, u128max; + a = JS_GetBigInt(val); + bf_init(a->ctx, &u128max); + bf_set_ui(&u128max, 1); + bf_mul_2exp(&u128max, 128, BF_PREC_INF, BF_RNDZ); + if (bf_cmp_le(&u128max, a)) { + return 1; + } + bf_init(a->ctx, &q); + bf_init(a->ctx, &r); + bf_init(a->ctx, &b); + bf_init(a->ctx, &one); + bf_set_ui(&b, UINT64_MAX); + bf_set_ui(&one, 1); + bf_add(&b, &b, &one, BF_PREC_INF, BF_RNDZ); + bf_divrem(&q, &r, a, &b, BF_PREC_INF, BF_RNDZ, BF_RNDZ); + + bf_get_uint64(ptr, &r); + bf_get_uint64(ptr+1, &q); + return 0; +} + +static int quickjs_int_to_u128(JSContext *ctx, JSValueConst val, uint64_t* ptr) { + if (JS_ToUint64Ext(ctx, ptr, val) < 0) { + return 1; + } + ptr[1] = 0; + return 0; +} + +static int quickjs_to_u128(JSContext *ctx, JSValueConst val, uint64_t* ptr) { + if (JS_IsBigInt(ctx, val)) + return quickjs_bigint_to_u128(ctx, val, ptr); + else { + return quickjs_int_to_u128(ctx, val, ptr); + } +} + +static JSValue near_account_balance(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t ptr[2]; + + account_balance((uint64_t)ptr); + return u128_to_quickjs(ctx, ptr); +} + +static JSValue near_account_locked_balance(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t ptr[2]; + + account_locked_balance((uint64_t)ptr); + return u128_to_quickjs(ctx, ptr); +} + +static JSValue near_attached_deposit(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t ptr[2]; + + attached_deposit((uint64_t)ptr); + return u128_to_quickjs(ctx, ptr); +} + +static JSValue near_prepaid_gas(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t value; + + value = prepaid_gas(); + return JS_NewBigUint64(ctx, value); +} + +static JSValue near_used_gas(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t value; + + value = used_gas(); + return JS_NewBigUint64(ctx, value); +} + +static JSValue near_random_seed(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + + if (JS_ToUint64Ext(ctx, ®ister_id, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + random_seed(register_id); + return JS_UNDEFINED; +} + +static JSValue near_sha256(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + + sha256(data_len, (uint64_t)data_ptr, register_id); + return JS_UNDEFINED; +} + +static JSValue near_keccak256(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + keccak256(data_len, (uint64_t)data_ptr, register_id); + return JS_UNDEFINED; +} + +static JSValue near_keccak512(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + + keccak512(data_len, (uint64_t)data_ptr, register_id); + return JS_UNDEFINED; +} + +static JSValue near_ripemd160(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + + ripemd160(data_len, (uint64_t)data_ptr, register_id); + return JS_UNDEFINED; +} + +static JSValue near_ecrecover(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t malleability_flag, v, register_id, result; + const char *hash_ptr, *sig_ptr; + size_t hash_len, sign_len; + + hash_ptr = JS_ToCStringLenRaw(ctx, &hash_len, argv[0]); + sig_ptr = JS_ToCStringLenRaw(ctx, &sign_len, argv[1]); + if (JS_ToUint64Ext(ctx, &malleability_flag, argv[2]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for malleability_flag"); + } + if (JS_ToUint64Ext(ctx, &v, argv[3]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for v"); + } + if (JS_ToUint64Ext(ctx, ®ister_id, argv[4]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + + result = ecrecover(hash_len, (uint64_t)hash_ptr, sign_len, (uint64_t)sig_ptr, malleability_flag, v, register_id); + return JS_NewBigUint64(ctx, result); +} + +static JSValue near_value_return(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *value_ptr; + size_t value_len; + + value_ptr = JS_ToCStringLenRaw(ctx, &value_len, argv[0]); + value_return(value_len, (uint64_t)value_ptr); + return JS_UNDEFINED; +} + +static JSValue near_panic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *data_ptr; + size_t data_len; + + if (argc == 1) { + data_ptr = JS_ToCStringLen(ctx, &data_len, argv[0]); + panic_utf8(data_len, (uint64_t)data_ptr); + } else { + panic(); + } + return JS_UNDEFINED; +} + +static JSValue near_panic_utf8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + + panic_utf8(data_len, (uint64_t)data_ptr); + return JS_UNDEFINED; +} + +static JSValue near_log(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLen(ctx, &data_len, argv[0]); + + log_utf8(data_len, (uint64_t)data_ptr); + return JS_UNDEFINED; +} + +static JSValue near_log_utf8(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + + log_utf8(data_len, (uint64_t)data_ptr); + return JS_UNDEFINED; +} + +static JSValue near_log_utf16(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + log_utf16(data_len, (uint64_t)data_ptr); + return JS_UNDEFINED; +} + +static JSValue near_promise_create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *account_id_ptr, *method_name_ptr, *arguments_ptr; + size_t account_id_len, method_name_len, arguments_len; + uint64_t amount_ptr[2]; // amount is u128 + uint64_t gas, ret; + + account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[0]); + method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[1]); + arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[2]); + if (quickjs_to_u128(ctx, argv[3], amount_ptr) != 0) { + return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); + } + if (JS_ToUint64Ext(ctx, &gas, argv[4]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); + } + + ret = promise_create(account_id_len, (uint64_t)account_id_ptr, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas); + + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_promise_then(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *account_id_ptr, *method_name_ptr, *arguments_ptr; + size_t account_id_len, method_name_len, arguments_len; + uint64_t amount_ptr[2]; // amount is u128 + uint64_t gas, ret; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[1]); + method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[2]); + arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[3]); + if (quickjs_to_u128(ctx, argv[4], amount_ptr) != 0) { + return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); + } + if (JS_ToUint64Ext(ctx, &gas, argv[5]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); + } + + ret = promise_then(promise_index, account_id_len, (uint64_t)account_id_ptr, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas); + + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_promise_and(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_idx_ptr[argc], ret; + + for(int i = 0; i < argc; i++) { + if (JS_ToUint64Ext(ctx, &promise_idx_ptr[i], argv[i]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_id"); + } + } + ret = promise_and((uint64_t)promise_idx_ptr, argc); + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_promise_batch_create(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *account_id_ptr; + size_t account_id_len; + uint64_t ret; + + account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[0]); + ret = promise_batch_create(account_id_len, (uint64_t)account_id_ptr); + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_promise_batch_then(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *account_id_ptr; + size_t account_id_len; + uint64_t ret; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[1]); + ret = promise_batch_then(promise_index, account_id_len, (uint64_t)account_id_ptr); + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_promise_batch_action_create_account(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + promise_batch_action_create_account(promise_index); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_deploy_contract(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *code_ptr; + size_t code_len; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + code_ptr = JS_ToCStringLenRaw(ctx, &code_len, argv[1]); + promise_batch_action_deploy_contract(promise_index, code_len, (uint64_t)code_ptr); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_function_call(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *method_name_ptr, *arguments_ptr; + size_t method_name_len, arguments_len; + uint64_t amount_ptr[2]; // amount is u128 + uint64_t gas; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[1]); + arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[2]); + if (quickjs_to_u128(ctx, argv[3], amount_ptr) != 0) { + return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); + } + if (JS_ToUint64Ext(ctx, &gas, argv[4]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); + } + promise_batch_action_function_call(promise_index, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_transfer(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + uint64_t amount_ptr[2]; // amount is u128 + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + if (quickjs_to_u128(ctx, argv[1], amount_ptr) != 0) { + return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); + } + promise_batch_action_transfer(promise_index, (uint64_t)amount_ptr); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_stake(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + uint64_t amount_ptr[2]; + const char *public_key_ptr; + size_t public_key_len; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + if (quickjs_to_u128(ctx, argv[1], amount_ptr) != 0) { + return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); + } + public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[2]); + + promise_batch_action_stake(promise_index, (uint64_t)amount_ptr, public_key_len, (uint64_t)public_key_ptr); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_add_key_with_full_access(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *public_key_ptr; + size_t public_key_len; + uint64_t nonce; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[1]); + if (JS_ToUint64Ext(ctx, &nonce, argv[2]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for nonce"); + } + promise_batch_action_add_key_with_full_access(promise_index, public_key_len, (uint64_t)public_key_ptr, nonce); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_add_key_with_function_call(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *public_key_ptr, *receiver_id_ptr, *method_names_ptr; + size_t public_key_len, receiver_id_len, method_names_len; + uint64_t nonce, allowance_ptr[2]; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[1]); + if (JS_ToUint64Ext(ctx, &nonce, argv[2]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for nonce"); + } + if (quickjs_to_u128(ctx, argv[3], allowance_ptr) != 0) { + return JS_ThrowTypeError(ctx, "Expect Uint128 for allowance"); + } + receiver_id_ptr = JS_ToCStringLen(ctx, &receiver_id_len, argv[4]); + method_names_ptr = JS_ToCStringLen(ctx, &method_names_len, argv[5]); + + promise_batch_action_add_key_with_function_call(promise_index, public_key_len, (uint64_t)public_key_ptr, nonce, (uint64_t)allowance_ptr, receiver_id_len, (uint64_t)receiver_id_ptr, method_names_len, (uint64_t)method_names_ptr); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_delete_key(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *public_key_ptr; + size_t public_key_len; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + public_key_ptr = JS_ToCStringLenRaw(ctx, &public_key_len, argv[1]); + promise_batch_action_delete_key(promise_index, public_key_len, (uint64_t)public_key_ptr); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_function_call_weight(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *method_name_ptr, *arguments_ptr; + size_t method_name_len, arguments_len; + uint64_t amount_ptr[2]; // amount is u128 + uint64_t gas; + uint64_t weight; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + method_name_ptr = JS_ToCStringLen(ctx, &method_name_len, argv[1]); + arguments_ptr = JS_ToCStringLenRaw(ctx, &arguments_len, argv[2]); + if (quickjs_to_u128(ctx, argv[3], amount_ptr) != 0) { + return JS_ThrowTypeError(ctx, "Expect Uint128 for amount"); + } + if (JS_ToUint64Ext(ctx, &gas, argv[4]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for gas"); + } + if (JS_ToUint64Ext(ctx, &weight, argv[5]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for weight"); + } + promise_batch_action_function_call_weight(promise_index, method_name_len, (uint64_t)method_name_ptr, arguments_len, (uint64_t)arguments_ptr, (uint64_t)amount_ptr, gas, weight); + return JS_UNDEFINED; +} + +static JSValue near_promise_batch_action_delete_account(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_index; + const char *beneficiary_id_ptr; + size_t beneficiary_id_len; + + if (JS_ToUint64Ext(ctx, &promise_index, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_index"); + } + beneficiary_id_ptr = JS_ToCStringLen(ctx, &beneficiary_id_len, argv[1]); + promise_batch_action_delete_account(promise_index, beneficiary_id_len, (uint64_t)beneficiary_id_ptr); + return JS_UNDEFINED; +} + +static JSValue near_promise_results_count(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t value; + + value = promise_results_count(); + return JS_NewBigUint64(ctx, value); +} + +static JSValue near_promise_result(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t result_idx, register_id; + uint64_t ret; + + if (JS_ToUint64Ext(ctx, &result_idx, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for result_idx"); + } + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + ret = promise_result(result_idx, register_id); + + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_promise_return(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t promise_idx; + if (JS_ToUint64Ext(ctx, &promise_idx, argv[0]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for promise_idx"); + } + promise_return(promise_idx); + + return JS_UNDEFINED; +} + +static JSValue near_storage_write(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *key_ptr, *value_ptr; + size_t key_len, value_len; + uint64_t register_id, ret; + + key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); + value_ptr = JS_ToCStringLenRaw(ctx, &value_len, argv[1]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[2]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + ret = storage_write(key_len, (uint64_t)key_ptr, value_len, (uint64_t)value_ptr, register_id); + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_storage_read(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *key_ptr; + size_t key_len; + uint64_t register_id; + uint64_t ret; + + key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + ret = storage_read(key_len, (uint64_t)key_ptr, register_id); + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_storage_remove(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *key_ptr; + size_t key_len; + uint64_t register_id; + uint64_t ret; + + key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + ret = storage_remove(key_len, (uint64_t)key_ptr, register_id); + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_storage_has_key(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *key_ptr; + size_t key_len; + uint64_t ret; + + key_ptr = JS_ToCStringLenRaw(ctx, &key_len, argv[0]); + ret = storage_has_key(key_len, (uint64_t)key_ptr); + return JS_NewBigUint64(ctx, ret); +} + +static JSValue near_validator_stake(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *account_id_ptr; + size_t account_id_len; + uint64_t stake_ptr[2]; + + account_id_ptr = JS_ToCStringLen(ctx, &account_id_len, argv[0]); + validator_stake(account_id_len, (uint64_t)account_id_ptr, (uint64_t)stake_ptr); + + return u128_to_quickjs(ctx, stake_ptr); +} + +static JSValue near_validator_total_stake(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t stake_ptr[2]; + + validator_total_stake((uint64_t)stake_ptr); + return u128_to_quickjs(ctx, stake_ptr); +} + +#ifdef NIGHTLY +static JSValue near_alt_bn128_g1_multiexp(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + + alt_bn128_g1_multiexp(data_len, (uint64_t)data_ptr, register_id); + return JS_UNDEFINED; +} + +static JSValue near_alt_bn128_g1_sum(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + uint64_t register_id; + const char *data_ptr; + size_t data_len; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + if (JS_ToUint64Ext(ctx, ®ister_id, argv[1]) < 0) { + return JS_ThrowTypeError(ctx, "Expect Uint64 for register_id"); + } + + alt_bn128_g1_sum(data_len, (uint64_t)data_ptr, register_id); + return JS_UNDEFINED; +} + +static JSValue near_alt_bn128_pairing_check(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) +{ + const char *data_ptr; + size_t data_len; + uint64_t ret; + + data_ptr = JS_ToCStringLenRaw(ctx, &data_len, argv[0]); + + ret = alt_bn128_pairing_check(data_len, (uint64_t)data_ptr); + return JS_NewBigUint64(ctx, ret); +} +#endif + +static void js_add_near_host_functions(JSContext* ctx) { + JSValue global_obj, env; + + global_obj = JS_GetGlobalObject(ctx); + env = JS_NewObject(ctx); + + JS_SetPropertyStr(ctx, env, "read_register", JS_NewCFunction(ctx, near_read_register, "read_register", 1)); + JS_SetPropertyStr(ctx, env, "register_len", JS_NewCFunction(ctx, near_register_len, "register_len", 1)); + JS_SetPropertyStr(ctx, env, "write_register", JS_NewCFunction(ctx, near_write_register, "write_register", 2)); + JS_SetPropertyStr(ctx, env, "current_account_id", JS_NewCFunction(ctx, near_current_account_id, "current_account_id", 1)); + JS_SetPropertyStr(ctx, env, "signer_account_id", JS_NewCFunction(ctx, near_signer_account_id, "signer_account_id", 1)); + JS_SetPropertyStr(ctx, env, "signer_account_pk", JS_NewCFunction(ctx, near_signer_account_pk, "signer_account_pk", 1)); + JS_SetPropertyStr(ctx, env, "predecessor_account_id", JS_NewCFunction(ctx, near_predecessor_account_id, "predecessor_account_id", 1)); + JS_SetPropertyStr(ctx, env, "input", JS_NewCFunction(ctx, near_input, "input", 1)); + JS_SetPropertyStr(ctx, env, "block_index", JS_NewCFunction(ctx, near_block_index, "block_index", 0)); + JS_SetPropertyStr(ctx, env, "block_timestamp", JS_NewCFunction(ctx, near_block_timestamp, "block_timestamp", 0)); + JS_SetPropertyStr(ctx, env, "epoch_height", JS_NewCFunction(ctx, near_epoch_height, "epoch_height", 0)); + JS_SetPropertyStr(ctx, env, "storage_usage", JS_NewCFunction(ctx, near_storage_usage, "storage_usage", 0)); + JS_SetPropertyStr(ctx, env, "account_balance", JS_NewCFunction(ctx, near_account_balance, "account_balance", 0)); + JS_SetPropertyStr(ctx, env, "account_locked_balance", JS_NewCFunction(ctx, near_account_locked_balance, "account_locked_balance", 0)); + JS_SetPropertyStr(ctx, env, "attached_deposit", JS_NewCFunction(ctx, near_attached_deposit, "attached_deposit", 0)); + JS_SetPropertyStr(ctx, env, "prepaid_gas", JS_NewCFunction(ctx, near_prepaid_gas, "prepaid_gas", 0)); + JS_SetPropertyStr(ctx, env, "used_gas", JS_NewCFunction(ctx, near_used_gas, "used_gas", 0)); + JS_SetPropertyStr(ctx, env, "random_seed", JS_NewCFunction(ctx, near_random_seed, "random_seed", 1)); + JS_SetPropertyStr(ctx, env, "sha256", JS_NewCFunction(ctx, near_sha256, "sha256", 2)); + JS_SetPropertyStr(ctx, env, "keccak256", JS_NewCFunction(ctx, near_keccak256, "keccak256", 2)); + JS_SetPropertyStr(ctx, env, "keccak512", JS_NewCFunction(ctx, near_keccak512, "keccak512", 2)); + JS_SetPropertyStr(ctx, env, "ripemd160", JS_NewCFunction(ctx, near_ripemd160, "ripemd160", 2)); + JS_SetPropertyStr(ctx, env, "ecrecover", JS_NewCFunction(ctx, near_ecrecover, "ecrecover", 5)); + JS_SetPropertyStr(ctx, env, "value_return", JS_NewCFunction(ctx, near_value_return, "value_return", 1)); + JS_SetPropertyStr(ctx, env, "panic", JS_NewCFunction(ctx, near_panic, "panic", 1)); + JS_SetPropertyStr(ctx, env, "panic_utf8", JS_NewCFunction(ctx, near_panic_utf8, "panic_utf8", 1)); + JS_SetPropertyStr(ctx, env, "log", JS_NewCFunction(ctx, near_log, "log", 1)); + JS_SetPropertyStr(ctx, env, "log_utf8", JS_NewCFunction(ctx, near_log_utf8, "log_utf8", 1)); + JS_SetPropertyStr(ctx, env, "log_utf16", JS_NewCFunction(ctx, near_log_utf16, "log_utf16", 1)); + JS_SetPropertyStr(ctx, env, "promise_create", JS_NewCFunction(ctx, near_promise_create, "promise_create", 5)); + JS_SetPropertyStr(ctx, env, "promise_then", JS_NewCFunction(ctx, near_promise_then, "promise_then", 6)); + JS_SetPropertyStr(ctx, env, "promise_and", JS_NewCFunction(ctx, near_promise_and, "promise_and", 1)); + JS_SetPropertyStr(ctx, env, "promise_batch_create", JS_NewCFunction(ctx, near_promise_batch_create, "promise_batch_create", 1)); + JS_SetPropertyStr(ctx, env, "promise_batch_then", JS_NewCFunction(ctx, near_promise_batch_then, "promise_batch_then", 2)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_create_account", JS_NewCFunction(ctx, near_promise_batch_action_create_account, "promise_batch_action_create_account", 1)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_deploy_contract", JS_NewCFunction(ctx, near_promise_batch_action_deploy_contract, "promise_batch_action_deploy_contract", 2)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_function_call", JS_NewCFunction(ctx, near_promise_batch_action_function_call, "promise_batch_action_function_call", 5)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_transfer", JS_NewCFunction(ctx, near_promise_batch_action_transfer, "promise_batch_action_transfer", 2)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_stake", JS_NewCFunction(ctx, near_promise_batch_action_stake, "promise_batch_action_stake", 3)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_add_key_with_full_access", JS_NewCFunction(ctx, near_promise_batch_action_add_key_with_full_access, "promise_batch_action_add_key_with_full_access", 3)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_add_key_with_function_call", JS_NewCFunction(ctx, near_promise_batch_action_add_key_with_function_call, "promise_batch_action_add_key_with_function_call", 6)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_delete_key", JS_NewCFunction(ctx, near_promise_batch_action_delete_key, "promise_batch_action_delete_key", 2)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_delete_account", JS_NewCFunction(ctx, near_promise_batch_action_delete_account, "promise_batch_action_delete_account", 2)); + JS_SetPropertyStr(ctx, env, "promise_batch_action_function_call_weight", JS_NewCFunction(ctx, near_promise_batch_action_function_call_weight, "promise_batch_action_function_call_weight", 6)); + JS_SetPropertyStr(ctx, env, "promise_results_count", JS_NewCFunction(ctx, near_promise_results_count, "promise_results_count", 0)); + JS_SetPropertyStr(ctx, env, "promise_result", JS_NewCFunction(ctx, near_promise_result, "promise_result", 2)); + JS_SetPropertyStr(ctx, env, "promise_return", JS_NewCFunction(ctx, near_promise_return, "promise_return", 1)); + JS_SetPropertyStr(ctx, env, "storage_write", JS_NewCFunction(ctx, near_storage_write, "storage_write", 2)); + JS_SetPropertyStr(ctx, env, "storage_read", JS_NewCFunction(ctx, near_storage_read, "storage_read", 2)); + JS_SetPropertyStr(ctx, env, "storage_remove", JS_NewCFunction(ctx, near_storage_remove, "storage_remove", 2)); + JS_SetPropertyStr(ctx, env, "storage_has_key", JS_NewCFunction(ctx, near_storage_has_key, "storage_has_key", 2)); + JS_SetPropertyStr(ctx, env, "validator_stake", JS_NewCFunction(ctx, near_validator_stake, "validator_stake", 2)); + JS_SetPropertyStr(ctx, env, "validator_total_stake", JS_NewCFunction(ctx, near_validator_total_stake, "validator_total_stake", 1)); + #ifdef NIGHTLY + // as of Jun 24, 2022, alt_bn128 is not a nightly protocol feature any more. It's part of protocol version 55. But, testnet +// is at protocol version 54 and mainnet is at protocol version 53. We'll enable and add alt_bn128 as they in testnet. + JS_SetPropertyStr(ctx, env, "alt_bn128_g1_multiexp", JS_NewCFunction(ctx, near_alt_bn128_g1_multiexp, "alt_bn128_g1_multiexp", 2)); + JS_SetPropertyStr(ctx, env, "alt_bn128_g1_sum", JS_NewCFunction(ctx, near_alt_bn128_g1_sum, "alt_bn128_g1_sum", 2)); + JS_SetPropertyStr(ctx, env, "alt_bn128_pairing_check", JS_NewCFunction(ctx, near_alt_bn128_pairing_check, "alt_bn128_pairing_check", 1)); + #endif + + JS_SetPropertyStr(ctx, global_obj, "env", env); +} + +JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, + int argc, JSValueConst *argv); + +void _start() {} + +#include "methods.h" diff --git a/cli/cli.js b/cli/cli.js old mode 100644 new mode 100755 index a52018631..20bd9aabb --- a/cli/cli.js +++ b/cli/cli.js @@ -1,16 +1,14 @@ #!/usr/bin/env node import fs from "fs/promises"; import path, { basename, dirname } from "path"; -// import yargs from "yargs"; -// import { hideBin } from "yargs/helpers"; import { nodeResolve } from "@rollup/plugin-node-resolve"; import sourcemaps from "rollup-plugin-sourcemaps"; import { babel } from "@rollup/plugin-babel"; import { rollup } from "rollup"; import { Command } from "commander"; import signal from "signale"; -const { Signale } = signal; import { executeCommand } from "./utils.js"; +const { Signale } = signal; const PROJECT_DIR = process.cwd(); const NEAR_SDK_JS = "node_modules/near-sdk-js"; const TSC = "node_modules/.bin/tsc"; diff --git a/package.json b/package.json index fd25f8023..2d2a450e4 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "scripts": { "build": "yarn build:lib && yarn build:cli", "build:lib": "tsc -p ./tsconfig.json", - "build:cli": "tsc -p ./tsconfig.cli.json", + "build:cli": "tsc -p ./tsconfig.cli.json && chmod u+x cli/cli.js", "pretest": "yarn build", "test": "yarn test:unit && yarn test:examples", "lint": "eslint --fix .", diff --git a/src/cli/cli.ts b/src/cli/cli.ts old mode 100644 new mode 100755 index 34c07e591..eb29bdfb6 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -3,19 +3,16 @@ import fs from "fs/promises"; import path, { basename, dirname } from "path"; -// import yargs from "yargs"; -// import { hideBin } from "yargs/helpers"; - import { nodeResolve } from "@rollup/plugin-node-resolve"; import sourcemaps from "rollup-plugin-sourcemaps"; import { babel } from "@rollup/plugin-babel"; import { rollup } from "rollup"; import { Command } from "commander"; import signal from "signale"; -const { Signale } = signal; import { executeCommand } from "./utils.js"; +const { Signale } = signal; const PROJECT_DIR = process.cwd(); const NEAR_SDK_JS = "node_modules/near-sdk-js"; const TSC = "node_modules/.bin/tsc"; @@ -41,8 +38,7 @@ export async function buildCom( source: string, target: string, { verbose = false }: { verbose: boolean } -): // command: Command -Promise { +): Promise { const SOURCE_EXT = source.split(".").pop(); const TARGET_DIR = dirname(target); const TARGET_EXT = target.split(".").pop(); From b6bedfc7df1213c76ab1caccac05bbe4a7676a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 17:49:50 +0200 Subject: [PATCH 8/9] feat: Restructure files Move CLI files to lib/cli Move builder to builder folder Change scripts for installation and fix paths in cli.js --- .eslintrc.cjs | 6 +----- .gitignore | 2 +- {cli/builder => builder}/builder.c | 4 ++-- cli/save-bytecode.d.ts | 1 - cli/save-bytecode.js | 22 ---------------------- cli/wasm-to-bytes.d.ts | 1 - cli/wasm-to-bytes.js | 16 ---------------- {cli => lib/cli}/cli.d.ts | 0 {cli => lib/cli}/cli.js | 10 +++++----- {cli => lib/cli}/post-install.d.ts | 0 {cli => lib/cli}/post-install.js | 0 {cli => lib/cli}/utils.d.ts | 0 {cli => lib/cli}/utils.js | 0 package.json | 10 ++++------ src/cli/cli.ts | 10 +++++----- tsconfig.cli.json | 24 ------------------------ tsconfig.json | 4 +++- 17 files changed, 21 insertions(+), 89 deletions(-) rename {cli/builder => builder}/builder.c (97%) delete mode 100644 cli/save-bytecode.d.ts delete mode 100644 cli/save-bytecode.js delete mode 100644 cli/wasm-to-bytes.d.ts delete mode 100644 cli/wasm-to-bytes.js rename {cli => lib/cli}/cli.d.ts (100%) rename {cli => lib/cli}/cli.js (94%) rename {cli => lib/cli}/post-install.d.ts (100%) rename {cli => lib/cli}/post-install.js (100%) rename {cli => lib/cli}/utils.d.ts (100%) rename {cli => lib/cli}/utils.js (100%) delete mode 100644 tsconfig.cli.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 515f1c8e5..582a480aa 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -17,11 +17,7 @@ module.exports = { parserOptions: { ecmaVersion: "latest", sourceType: "module", - project: [ - "./{t,j}sconfig.json", - "./**/{t,j}sconfig.json", - "./tsconfig.cli.json", - ], + project: ["./{t,j}sconfig.json", "./**/{t,j}sconfig.json"], }, plugins: ["@typescript-eslint"], rules: { diff --git a/.gitignore b/.gitignore index ce142b630..beea52241 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ node_modules yarn-error.log vendor .idea -cli/deps +deps diff --git a/cli/builder/builder.c b/builder/builder.c similarity index 97% rename from cli/builder/builder.c rename to builder/builder.c index 7da615b82..0e34df0b5 100644 --- a/cli/builder/builder.c +++ b/builder/builder.c @@ -1,6 +1,6 @@ #include -#include "../node_modules/near-sdk-js/cli/deps/quickjs/quickjs-libc-min.h" -#include "../node_modules/near-sdk-js/cli/deps/quickjs/libbf.h" +#include "../node_modules/near-sdk-js/lib/cli/deps/quickjs/quickjs-libc-min.h" +#include "../node_modules/near-sdk-js/lib/cli/deps/quickjs/libbf.h" #include "code.h" static JSContext *JS_NewCustomContext(JSRuntime *rt) diff --git a/cli/save-bytecode.d.ts b/cli/save-bytecode.d.ts deleted file mode 100644 index cb0ff5c3b..000000000 --- a/cli/save-bytecode.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/cli/save-bytecode.js b/cli/save-bytecode.js deleted file mode 100644 index 6adcb4ccd..000000000 --- a/cli/save-bytecode.js +++ /dev/null @@ -1,22 +0,0 @@ -import { readFile, writeFile } from "fs/promises"; -import { resolve } from "path"; -//TODO: execute it in js env -async function main() { - const source = resolve(process.argv[process.argv.length - 2]); - const target = resolve(process.argv[process.argv.length - 1]); - const code = await readFile(source, "utf-8"); - const codes = code - .split("\n") - .map((line) => { - if (line.indexOf("0x") < 0) { - return []; - } - const trimmedLine = line.trim(); - const numbers = trimmedLine.slice(0, trimmedLine.length - 1).split(", "); - return numbers.map(Number); - }) - .filter((numbers) => numbers.length); - const bytecode = Buffer.concat(codes.map(Buffer.from)); - await writeFile(target, bytecode.toString("base64")); -} -main(); diff --git a/cli/wasm-to-bytes.d.ts b/cli/wasm-to-bytes.d.ts deleted file mode 100644 index cb0ff5c3b..000000000 --- a/cli/wasm-to-bytes.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/cli/wasm-to-bytes.js b/cli/wasm-to-bytes.js deleted file mode 100644 index adc1018cd..000000000 --- a/cli/wasm-to-bytes.js +++ /dev/null @@ -1,16 +0,0 @@ -import { readFile, writeFile } from "fs/promises"; -import { resolve } from "path"; -// used for deploy code in contract with near.promiseBatchActionDeployContract. -// Usage: -// node wasm_to_bytes.js contract.wasm contract.jsbytes -// copy paste the content of the contract.jsbytes, pass it as arguments to near.promiseBatchActionDeployContract: -// near.promiseBatchActionDeployContract(promsieId, '') -// Note, do not use `bytes()` type check here, which is too expensive for this long bytes and will exceed gas limit. -async function main() { - const source = resolve(process.argv[process.argv.length - 2]); - const target = resolve(process.argv[process.argv.length - 1]); - const code = await readFile(source); - const result = code.reduce((result, character) => `${result}\\x${character.toString(16).padStart(2, "0")}`, ""); - await writeFile(target, result); -} -main(); diff --git a/cli/cli.d.ts b/lib/cli/cli.d.ts similarity index 100% rename from cli/cli.d.ts rename to lib/cli/cli.d.ts diff --git a/cli/cli.js b/lib/cli/cli.js similarity index 94% rename from cli/cli.js rename to lib/cli/cli.js index 20bd9aabb..132b6c92c 100755 --- a/cli/cli.js +++ b/lib/cli/cli.js @@ -12,8 +12,8 @@ const { Signale } = signal; const PROJECT_DIR = process.cwd(); const NEAR_SDK_JS = "node_modules/near-sdk-js"; const TSC = "node_modules/.bin/tsc"; -const QJSC_DIR = `${NEAR_SDK_JS}/cli/deps/quickjs`; -const QJSC = `${NEAR_SDK_JS}/cli/deps/qjsc`; +const QJSC_DIR = `${NEAR_SDK_JS}/lib/cli/deps/quickjs`; +const QJSC = `${NEAR_SDK_JS}/lib/cli/deps/qjsc`; const program = new Command(); program .name("near-sdk-js") @@ -102,14 +102,14 @@ async function createMethodsHeaderFile(rollupTarget, verbose = false) { await fs.writeFile(`${buildPath}/methods.h`, methods); } async function createWasmContract(qjscTarget, contractTarget, verbose = false) { - const WASI_SDK_PATH = `${NEAR_SDK_JS}/cli/deps/wasi-sdk`; + const WASI_SDK_PATH = `${NEAR_SDK_JS}/lib/cli/deps/wasi-sdk`; const CC = `${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot`; let DEFS = `-D_GNU_SOURCE '-DCONFIG_VERSION="2021-03-27"' -DCONFIG_BIGNUM`; if (process.env.NEAR_NIGHTLY) { DEFS = DEFS + " -DNIGHTLY"; } const INCLUDES = `-I${QJSC_DIR} -I.`; - const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/cli/builder/builder.c`; + const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/builder/builder.c`; const NEW_BUILDER_PATH = `${path.dirname(contractTarget)}/builder.c`; const SOURCES = `${NEW_BUILDER_PATH} ${QJSC_DIR}/quickjs.c ${QJSC_DIR}/libregexp.c ${QJSC_DIR}/libunicode.c ${QJSC_DIR}/cutils.c ${QJSC_DIR}/quickjs-libc-min.c ${QJSC_DIR}/libbf.c`; const LIBS = `-lm`; @@ -119,6 +119,6 @@ async function createWasmContract(qjscTarget, contractTarget, verbose = false) { await executeCommand(`${CC} --target=wasm32-wasi -nostartfiles -Oz -flto ${DEFS} ${INCLUDES} ${SOURCES} ${LIBS} -Wl,--no-entry -Wl,--allow-undefined -Wl,-z,stack-size=${256 * 1024} -Wl,--lto-O3 -o ${contractTarget}`, verbose); } async function wasiStubContract(contractTarget, verbose = false) { - const WASI_STUB = `${NEAR_SDK_JS}/cli/deps/binaryen/wasi-stub/run.sh`; + const WASI_STUB = `${NEAR_SDK_JS}/lib/cli/deps/binaryen/wasi-stub/run.sh`; await executeCommand(`${WASI_STUB} ${contractTarget} >/dev/null`, verbose); } diff --git a/cli/post-install.d.ts b/lib/cli/post-install.d.ts similarity index 100% rename from cli/post-install.d.ts rename to lib/cli/post-install.d.ts diff --git a/cli/post-install.js b/lib/cli/post-install.js similarity index 100% rename from cli/post-install.js rename to lib/cli/post-install.js diff --git a/cli/utils.d.ts b/lib/cli/utils.d.ts similarity index 100% rename from cli/utils.d.ts rename to lib/cli/utils.d.ts diff --git a/cli/utils.js b/lib/cli/utils.js similarity index 100% rename from cli/utils.js rename to lib/cli/utils.js diff --git a/package.json b/package.json index 2d2a450e4..3e5a1ed45 100644 --- a/package.json +++ b/package.json @@ -21,19 +21,17 @@ ], "license": "(MIT AND Apache-2.0)", "scripts": { - "build": "yarn build:lib && yarn build:cli", - "build:lib": "tsc -p ./tsconfig.json", - "build:cli": "tsc -p ./tsconfig.cli.json && chmod u+x cli/cli.js", + "build": "tsc -p ./tsconfig.json && chmod u+x lib/cli/cli.js", "pretest": "yarn build", "test": "yarn test:unit && yarn test:examples", "lint": "eslint --fix .", "format": "prettier --write .", "test:unit": "yarn && cd tests && yarn && yarn build && yarn test && cd ..", "test:examples": "yarn && cd examples && yarn && yarn build && yarn test && cd ..", - "postinstall": "cd cli && rm -rf deps && mkdir -p deps && cd deps && node ../post-install.js" + "postinstall": "cd lib/cli && rm -rf deps && mkdir -p deps && cd deps && node ../post-install.js" }, "bin": { - "near-sdk-js": "cli/cli.js" + "near-sdk-js": "lib/cli/cli.js" }, "engines": { "node": ">=14 <16.6.0 || >16.6.0" @@ -53,7 +51,7 @@ "signale": "^1.4.0" }, "files": [ - "cli", + "builder", "lib" ], "devDependencies": { diff --git a/src/cli/cli.ts b/src/cli/cli.ts index eb29bdfb6..5f1a7f84c 100755 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -16,8 +16,8 @@ const { Signale } = signal; const PROJECT_DIR = process.cwd(); const NEAR_SDK_JS = "node_modules/near-sdk-js"; const TSC = "node_modules/.bin/tsc"; -const QJSC_DIR = `${NEAR_SDK_JS}/cli/deps/quickjs`; -const QJSC = `${NEAR_SDK_JS}/cli/deps/qjsc`; +const QJSC_DIR = `${NEAR_SDK_JS}/lib/cli/deps/quickjs`; +const QJSC = `${NEAR_SDK_JS}/lib/cli/deps/qjsc`; const program = new Command(); @@ -161,7 +161,7 @@ async function createWasmContract( contractTarget: string, verbose = false ) { - const WASI_SDK_PATH = `${NEAR_SDK_JS}/cli/deps/wasi-sdk`; + const WASI_SDK_PATH = `${NEAR_SDK_JS}/lib/cli/deps/wasi-sdk`; const CC = `${WASI_SDK_PATH}/bin/clang --sysroot=${WASI_SDK_PATH}/share/wasi-sysroot`; let DEFS = `-D_GNU_SOURCE '-DCONFIG_VERSION="2021-03-27"' -DCONFIG_BIGNUM`; @@ -171,7 +171,7 @@ async function createWasmContract( } const INCLUDES = `-I${QJSC_DIR} -I.`; - const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/cli/builder/builder.c`; + const ORIGINAL_BUILDER_PATH = `${NEAR_SDK_JS}/builder/builder.c`; const NEW_BUILDER_PATH = `${path.dirname(contractTarget)}/builder.c`; const SOURCES = `${NEW_BUILDER_PATH} ${QJSC_DIR}/quickjs.c ${QJSC_DIR}/libregexp.c ${QJSC_DIR}/libunicode.c ${QJSC_DIR}/cutils.c ${QJSC_DIR}/quickjs-libc-min.c ${QJSC_DIR}/libbf.c`; const LIBS = `-lm`; @@ -192,6 +192,6 @@ async function createWasmContract( } async function wasiStubContract(contractTarget: string, verbose = false) { - const WASI_STUB = `${NEAR_SDK_JS}/cli/deps/binaryen/wasi-stub/run.sh`; + const WASI_STUB = `${NEAR_SDK_JS}/lib/cli/deps/binaryen/wasi-stub/run.sh`; await executeCommand(`${WASI_STUB} ${contractTarget} >/dev/null`, verbose); } diff --git a/tsconfig.cli.json b/tsconfig.cli.json deleted file mode 100644 index 1a0315d55..000000000 --- a/tsconfig.cli.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "esModuleInterop": true, - "lib": ["es2015", "esnext", "dom"], - "module": "esnext", - "target": "es2020", - "moduleResolution": "node", - "alwaysStrict": true, - "outDir": "./cli", - "declaration": true, - "preserveSymlinks": true, - "preserveWatchOutput": true, - "pretty": false, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": false, - "noImplicitReturns": true, - "noUnusedLocals": true, - "experimentalDecorators": true, - "resolveJsonModule": true, - "allowJs": true - }, - "include": ["src/cli/**/*"] -} diff --git a/tsconfig.json b/tsconfig.json index a54a5836b..5bcef4270 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,7 +23,9 @@ "files": [ "src/index.ts", "src/build-tools/near-bindgen-exporter.ts", - "src/build-tools/include-bytes.ts" + "src/build-tools/include-bytes.ts", + "src/cli/cli.ts", + "src/cli/post-install.ts" ], "exclude": ["src/cli/**/*"] } From 00ed8d7c612ec6bb425bfc5fb352a88afda46d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Vujovi=C4=87?= Date: Wed, 12 Oct 2022 17:53:03 +0200 Subject: [PATCH 9/9] chore: Remove unused files --- src/cli/save-bytecode.ts | 29 ----------------------------- src/cli/wasm-to-bytes.ts | 24 ------------------------ 2 files changed, 53 deletions(-) delete mode 100644 src/cli/save-bytecode.ts delete mode 100644 src/cli/wasm-to-bytes.ts diff --git a/src/cli/save-bytecode.ts b/src/cli/save-bytecode.ts deleted file mode 100644 index 588c0a393..000000000 --- a/src/cli/save-bytecode.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { readFile, writeFile } from "fs/promises"; -import { resolve } from "path"; - -//TODO: execute it in js env -async function main(): Promise { - const source = resolve(process.argv[process.argv.length - 2]); - const target = resolve(process.argv[process.argv.length - 1]); - const code = await readFile(source, "utf-8"); - - const codes = code - .split("\n") - .map((line) => { - if (line.indexOf("0x") < 0) { - return []; - } - - const trimmedLine = line.trim(); - const numbers = trimmedLine.slice(0, trimmedLine.length - 1).split(", "); - - return numbers.map(Number); - }) - .filter((numbers) => numbers.length); - - const bytecode = Buffer.concat(codes.map(Buffer.from)); - - await writeFile(target, bytecode.toString("base64")); -} - -main(); diff --git a/src/cli/wasm-to-bytes.ts b/src/cli/wasm-to-bytes.ts deleted file mode 100644 index 1672b00d3..000000000 --- a/src/cli/wasm-to-bytes.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { readFile, writeFile } from "fs/promises"; -import { resolve } from "path"; - -// used for deploy code in contract with near.promiseBatchActionDeployContract. -// Usage: -// node wasm_to_bytes.js contract.wasm contract.jsbytes -// copy paste the content of the contract.jsbytes, pass it as arguments to near.promiseBatchActionDeployContract: -// near.promiseBatchActionDeployContract(promsieId, '') -// Note, do not use `bytes()` type check here, which is too expensive for this long bytes and will exceed gas limit. -async function main(): Promise { - const source = resolve(process.argv[process.argv.length - 2]); - const target = resolve(process.argv[process.argv.length - 1]); - const code = await readFile(source); - - const result = code.reduce( - (result, character) => - `${result}\\x${character.toString(16).padStart(2, "0")}`, - "" - ); - - await writeFile(target, result); -} - -main();