diff --git a/.babelrc b/.babelrc deleted file mode 100644 index f3a001138..000000000 --- a/.babelrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "presets": [ - ["env", { - "targets": { - "browsers": ["last 2 versions"] - } - }], - "stage-1" - ], - "plugins": [ - [ - "transform-runtime", - { - "polyfill": false, - "regenerator": true - } - ] - ] -} diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..a0bb5c393 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,20 @@ +{ + "extends": "@blockone/blockone", + "rules": { + "no-bitwise": "off", + "semi": ["error", "always"], + "indent": ["error", 4] + }, + "overrides": [ + { + "files": ["**/*.ts", "**/*.tsx"], + "rules":{ + "indent": "off", + "@typescript-eslint/indent": ["error", 4], + "@typescript-eslint/no-var-requires": "off", + "semi": "off", + "@typescript-eslint/semi": ["error", "always"] + } + } + ] +} diff --git a/.github/eosjs-ci/Dockerfile b/.github/eosjs-ci/Dockerfile new file mode 100644 index 000000000..1f6d7b030 --- /dev/null +++ b/.github/eosjs-ci/Dockerfile @@ -0,0 +1,89 @@ +FROM ubuntu:18.04 +ENTRYPOINT ["nodeos", "--data-dir", "/root/.local/share", "-e", "-p", "eosio", "--replay-blockchain", "--plugin", "eosio::producer_plugin", "--plugin", "eosio::chain_api_plugin", "--plugin", "eosio::http_plugin", "--http-server-address=0.0.0.0:8888", "--access-control-allow-origin=*", "--contracts-console", "--http-validate-host=false", "--verbose-http-errors", "--max-transaction-time=100"] + +### base +RUN yes | unminimize \ + && apt-get update \ + && apt-get install -yq \ + binutils-gold \ + build-essential \ + clang-tools-8 \ + curl \ + g++-8 \ + git \ + libcurl4-gnutls-dev \ + libgflags-dev \ + libgmp3-dev \ + libssl-dev \ + libusb-1.0-0-dev \ + lld-8 \ + llvm-7 \ + llvm-7-dev \ + locales \ + ninja-build \ + pkg-config \ + python \ + software-properties-common \ + wget \ + xz-utils \ + zlib1g-dev \ + && update-alternatives --remove-all cc \ + && update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-8 100 \ + && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 100 \ + && update-alternatives --remove-all c++ \ + && update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-8 100 \ + && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 100 \ + && update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-8 100 \ + && locale-gen en_US.UTF-8 \ + && curl -sL https://deb.nodesource.com/setup_10.x | bash - + +ENV LANG=en_US.UTF-8 + +### cmake +WORKDIR /root +RUN curl -LO https://cmake.org/files/v3.13/cmake-3.13.2.tar.gz \ + && tar -xzf cmake-3.13.2.tar.gz \ + && cd cmake-3.13.2 \ + && ./bootstrap --prefix=/usr/local --parallel=8 \ + && make -j8 \ + && make install \ + && cd /root \ + && rm -rf cmake-3.13.2.tar.gz cmake-3.13.2 + +### boost +RUN curl -LO https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.tar.bz2 \ + && tar -xjf boost_1_72_0.tar.bz2 \ + && cd boost_1_72_0 \ + && ./bootstrap.sh --prefix=/usr/local \ + && ./b2 --with-iostreams --with-date_time --with-filesystem --with-system --with-program_options --with-chrono --with-test -j$(nproc) install \ + && cd /root \ + && rm -rf boost_1_72_0.tar.bz2 boost_1_72_0 + +### eosio.cdt +RUN git clone https://github.com/EOSIO/eosio.cdt.git \ + && cd eosio.cdt \ + && git checkout eosio-cdt-2.1-staging-c \ + && git submodule update --init --recursive \ + && mkdir build \ + && cd build \ + && cmake -GNinja .. \ + && ninja -j8 + +### eos +RUN git clone https://github.com/EOSIO/eos.git \ + && cd eos \ + && git checkout develop \ + && git submodule update --init --recursive \ + && mkdir build \ + && cd build \ + && CC=clang-8 CXX=clang++-8 cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_AR=/usr/bin/llvm-ar-8 -DCMAKE_RANLIB=/usr/bin/llvm-ranlib-8 -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld .. \ + && CC=clang-8 CXX=clang++-8 ninja -j8 + +ENV PATH="/root/eos/build/bin/:/root/eosio.cdt/build/bin/:${PATH}" + +RUN mkdir -p "/opt/eosio/bin/contracts" + +COPY ./ /opt/eosio/bin + +RUN mkdir -p "/opt/eosio/bin/config-dir" +RUN /bin/bash /opt/eosio/bin/scripts/deploy_contracts.sh diff --git a/.github/eosjs-ci/scripts/deploy_contracts.sh b/.github/eosjs-ci/scripts/deploy_contracts.sh new file mode 100644 index 000000000..acede2c3f --- /dev/null +++ b/.github/eosjs-ci/scripts/deploy_contracts.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +NODEOS_RUNNING=$1 + +set -m + +# CAUTION: Never use these development keys for a production account! +# Doing so will most certainly result in the loss of access to your account, these private keys are publicly known. +SYSTEM_ACCOUNT_PRIVATE_KEY="5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3" +SYSTEM_ACCOUNT_PUBLIC_KEY="EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + +EXAMPLE_ACCOUNT_PRIVATE_KEY="5JuH9fCXmU3xbj8nRmhPZaVrxxXrdPaRmZLW1cznNTmTQR2Kg5Z" +EXAMPLE_ACCOUNT_PUBLIC_KEY="EOS7bxrQUTbQ4mqcoefhWPz1aFieN4fA9RQAiozRz7FrUChHZ7Rb8" + +R1_EXAMPLE_ACCOUNT_PRIVATE_KEY="PVT_R1_GrfEfbv5at9kbeHcGagQmvbFLdm6jqEpgE1wsGbrfbZNjpVgT" +R1_EXAMPLE_ACCOUNT_PUBLIC_KEY="PUB_R1_4ztaVy8L9zbmzTdpfq5GcaFYwGwXTNmN3qW7qcgHMmfUZhpzQQ" + +ROOT_DIR="/opt" +CONTRACTS_DIR="$ROOT_DIR/eosio/bin/contracts" +BLOCKCHAIN_DATA_DIR=/root/.local/share +BLOCKCHAIN_CONFIG_DIR=/opt/eosio/bin/config-dir +WALLET_DIR="/root/eosio-wallet/" + +mkdir -p $ROOT_DIR/bin + +# Set PATH +PATH="$PATH:$ROOT_DIR/bin:$ROOT_DIR/bin/scripts" +CONFIG_DIR="$ROOT_DIR/bin/config-dir" + +function start_wallet { + echo "Starting the wallet" + rm -rf $WALLET_DIR + mkdir -p $WALLET_DIR + nohup keosd --unlock-timeout 999999999 --wallet-dir $WALLET_DIR --http-server-address 127.0.0.1:8900 2>&1 & + sleep 1s + wallet_password=$(cleos wallet create --to-console | awk 'FNR > 3 { print $1 }' | tr -d '"') + echo $wallet_password > "$CONFIG_DIR"/keys/default_wallet_password.txt + + cleos wallet import --private-key $SYSTEM_ACCOUNT_PRIVATE_KEY +} + +function post_preactivate { + curl -X POST http://127.0.0.1:8888/v1/producer/schedule_protocol_feature_activations -d '{"protocol_features_to_activate": ["0ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd"]}' +} + +# $1 feature disgest to activate +function activate_feature { + cleos push action eosio activate '["'"$1"'"]' -p eosio + if [ $? -ne 0 ]; then + exit 1 + fi +} + +# $1 account name +# $2 contract directory +# $3 wasm file name +# $4 abi file name +function setcode { + retry_count="4" + + while [ $retry_count -gt 0 ]; do + cleos set code $1 $2 -p $1@active + if [ $? -eq 0 ]; then + break + fi + + echo "setcode failed retrying..." + sleep 1s + retry_count=$[$retry_count-1] + done + + if [ $retry_count -eq 0 ]; then + echo "setcode failed too many times, bailing." + exit 1 + fi +} + +# $1 account name +# $2 contract directory +# $3 abi file name +function setabi { + retry_count="4" + + while [ $retry_count -gt 0 ]; do + cleos set abi $1 $2 -p $1@active + if [ $? -eq 0 ]; then + break + fi + + echo "setcode failed retrying..." + sleep 1s + retry_count=$[$retry_count-1] + done + + if [ $retry_count -eq 0 ]; then + echo "setcode failed too many times, bailing." + exit 1 + fi +} + +# $1 - account name +# $2 - public key +# $3 - private key +function create_account { + cleos wallet import --private-key $3 + cleos create account eosio $1 $2 +} + +# Move into the executable directory +cd $ROOT_DIR/bin/ +mkdir -p $CONFIG_DIR +mkdir -p $BLOCKCHAIN_DATA_DIR +mkdir -p $BLOCKCHAIN_CONFIG_DIR + +if [ -z "$NODEOS_RUNNING" ]; then + echo "Starting the chain for setup" + nodeos -e -p eosio \ + --data-dir $BLOCKCHAIN_DATA_DIR \ + --config-dir $BLOCKCHAIN_CONFIG_DIR \ + --http-validate-host=false \ + --plugin eosio::producer_api_plugin \ + --plugin eosio::chain_api_plugin \ + --plugin eosio::http_plugin \ + --http-server-address=0.0.0.0:8888 \ + --access-control-allow-origin=* \ + --contracts-console \ + --max-transaction-time=100000 \ + --verbose-http-errors & +fi + +mkdir -p "$CONFIG_DIR"/keys + +sleep 1s + +echo "Waiting for the chain to finish startup" +until curl localhost:8888/v1/chain/get_info +do + echo "Still waiting" + sleep 1s +done + +# Sleep for 2s to allow time for 4 blocks to be created so we have blocks to reference when sending transactions +sleep 2s +echo "Creating accounts and deploying contracts" + +start_wallet + +# preactivate concensus upgrades +post_preactivate + +sleep 1s +cleos wallet unlock --password $(cat "$CONFIG_DIR"/keys/default_wallet_password.txt) || true +setabi eosio $CONTRACTS_DIR/boot/boot.abi +setcode eosio $CONTRACTS_DIR/boot/boot.wasm +sleep 2s +cleos push action eosio boot "[]" -p eosio@active + +sleep 1s +cleos wallet unlock --password $(cat "$CONFIG_DIR"/keys/default_wallet_password.txt) || true +setcode eosio $CONTRACTS_DIR/system/system.wasm +setabi eosio $CONTRACTS_DIR/system/system.abi + +# token +sleep 1s +cleos wallet unlock --password $(cat "$CONFIG_DIR"/keys/default_wallet_password.txt) || true +create_account eosio.token $SYSTEM_ACCOUNT_PUBLIC_KEY $SYSTEM_ACCOUNT_PRIVATE_KEY +create_account bob $EXAMPLE_ACCOUNT_PUBLIC_KEY $EXAMPLE_ACCOUNT_PRIVATE_KEY +create_account alice $EXAMPLE_ACCOUNT_PUBLIC_KEY $EXAMPLE_ACCOUNT_PRIVATE_KEY +create_account bobr1 $R1_EXAMPLE_ACCOUNT_PUBLIC_KEY $R1_EXAMPLE_ACCOUNT_PRIVATE_KEY +create_account alicer1 $R1_EXAMPLE_ACCOUNT_PUBLIC_KEY $R1_EXAMPLE_ACCOUNT_PRIVATE_KEY + +sleep 1s +cleos set abi eosio.token $CONTRACTS_DIR/token/token.abi -p eosio.token@active -p eosio@active +cleos set code eosio.token $CONTRACTS_DIR/token/token.wasm -p eosio.token@active -p eosio@active + +cleos push action eosio.token create '["bob", "10000000000.0000 SYS"]' -p eosio.token +cleos push action eosio.token issue '["bob", "5000000000.0000 SYS", "Half of available supply"]' -p bob +cleos push action eosio.token transfer '["bob", "alice", "1000000.0000 SYS", "memo"]' -p bob +cleos push action eosio.token transfer '["bob", "bobr1", "1000000.0000 SYS", "memo"]' -p bob +cleos push action eosio.token transfer '["bob", "alicer1", "1000000.0000 SYS", "memo"]' -p bob + +cleos push action eosio init "[]" -p eosio@active + +echo "All done initializing the blockchain" + +if [[ -z $NODEOS_RUNNING ]]; then + echo "Shut down Nodeos, sleeping for 2 seconds to allow time for at least 4 blocks to be created after deploying contracts" + sleep 2s + kill %1 + fg %1 +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..a14a7e2f2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,80 @@ +name: CI +on: + push: + branches-ignore: + - develop + pull_request: + +jobs: + ci: + name: CI + runs-on: ubuntu-18.04 + strategy: + matrix: + node-version: [12.14.1] + steps: + - name: Check for GIT_API_KEY + id: check_token + run: echo ::set-output name=token_exists::${HAS_SECRET} + env: + HAS_SECRET: ${{ secrets.GIT_API_KEY != null }} + - name: Checkout (with GIT_API_KEY) + if: ${{ steps.check_token.outputs.token_exists == 'true' }} + uses: actions/checkout@f90c7b395dac7c5a277c1a6d93d5057c1cddb74e + with: + token: ${{ secrets.GIT_API_KEY }} + - name: Checkout (with GitHub Token) + if: ${{ steps.check_token.outputs.token_exists == 'false' }} + uses: actions/checkout@f90c7b395dac7c5a277c1a6d93d5057c1cddb74e + with: + token: ${{ github.token }} + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@1c5c1375b3817ad821719597effe8e3d6f764930 + with: + node-version: ${{ matrix.node-version }} + registry-url: 'https://registry.npmjs.org' + - name: Update + run: | + yarn install && yarn upgrade && npx syncyarnlock@1.0.19 -s -k && rm -rf yarn.lock && yarn install + - name: Install + run: | + yarn --frozen-lockfile + - name: Lint + run: | + yarn lint + - name: Audit + run: | + yarn audit + - name: Test + run: | + yarn test + - name: Test Node + run: | + yarn test-node + - name: Build + run: | + yarn build-web + - name: Test Web + uses: cypress-io/github-action@8aac1d019734a107e4eaaefe2e26beb3149e5540 + with: + spec: cypress/integration/index.spec.js + - name: Get Protected Status + if: github.event_name == 'push' + id: protected_step + run: | + PROTECTED=$(curl "https://api.github.com/repos/${{ github.repository }}/branches/${GITHUB_REF#refs/*/}" 2>/dev/null | jq -r '.protected') + echo ::set-output name=protected::$PROTECTED + - name: Commit/Push + if: github.event_name == 'push' && steps.protected_step.outputs.protected == 'false' + run: | + git config --global user.name 'Block.one DevOps' + git config --global user.email 'blockone-devops@users.noreply.github.com' + git commit package.json yarn.lock -m "Updating package.json and yarn.lock" || echo "Nothing to commit" + git push origin ${GITHUB_REF#refs/*/} + services: + nodeos: + image: eosio/eosjs-ci:v0.2.1 + + ports: + - 8888:8888 + - 9876:9876 diff --git a/.github/workflows/publish-edge.yml b/.github/workflows/publish-edge.yml new file mode 100644 index 000000000..c81a3a620 --- /dev/null +++ b/.github/workflows/publish-edge.yml @@ -0,0 +1,65 @@ +name: Publish Edge +on: + push: + branches: + - develop + +jobs: + publish-edge: + name: Publish Edge + runs-on: ubuntu-18.04 + steps: + - name: Checkout + uses: actions/checkout@f90c7b395dac7c5a277c1a6d93d5057c1cddb74e + - name: Setup Node.js + uses: actions/setup-node@1c5c1375b3817ad821719597effe8e3d6f764930 + with: + node-version: '12.14.1' + registry-url: 'https://registry.npmjs.org' + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - uses: actions/cache@70655ec8323daeeaa7ef06d7c56e1b9191396cbe + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install + run: | + yarn --frozen-lockfile + - name: Lint + run: | + yarn lint + - name: Test + run: | + yarn test + - name: Test Node + run: | + yarn test-node + - name: Build + run: | + yarn build-web + - name: Test Web + uses: cypress-io/github-action@8aac1d019734a107e4eaaefe2e26beb3149e5540 + with: + spec: cypress/integration/index.spec.js + - name: Publish Edge + run: | + . ./scripts/publish-utils.sh + setup_git + COMMIT=${GITHUB_SHA:0:7} + sed -i "s/ \"version\": \"\([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/&-$GITHUB_RUN_NUMBER-$COMMIT/" package.json + git commit -a -m "Updating version [skip ci]" --allow-empty + npm publish --access public --tag edge + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + + services: + nodeos: + image: eosio/eosjs-ci:v0.2.1 + + ports: + - 8888:8888 + - 9876:9876 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 000000000..57237c8b4 --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,124 @@ +name: Publish +on: + release: + types: [published] + +jobs: + publish-release: + if: "!github.event.release.prerelease" + name: Publish Release + runs-on: ubuntu-18.04 + steps: + - name: Checkout + uses: actions/checkout@f90c7b395dac7c5a277c1a6d93d5057c1cddb74e + - name: Setup Node.js + uses: actions/setup-node@1c5c1375b3817ad821719597effe8e3d6f764930 + with: + node-version: '12.14.1' + registry-url: 'https://registry.npmjs.org' + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - uses: actions/cache@70655ec8323daeeaa7ef06d7c56e1b9191396cbe + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install + run: | + yarn --frozen-lockfile + - name: Lint + run: | + yarn lint + - name: Test + run: | + yarn test + - name: Test Node + run: | + yarn test-node + - name: Build + run: | + yarn build-web + - name: Test Web + uses: cypress-io/github-action@8aac1d019734a107e4eaaefe2e26beb3149e5540 + with: + spec: cypress/integration/index.spec.js + - name: Publish Release + run: | + . ./scripts/publish-utils.sh + setup_git + ensure_version_match + git commit -a -m "Updating version [skip ci]" --allow-empty + npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + + services: + nodeos: + image: eosio/eosjs-ci:v0.2.1 + + ports: + - 8888:8888 + - 9876:9876 + + + publish-rc: + if: "github.event.release.prerelease" + name: Publish RC + runs-on: ubuntu-16.04 + steps: + - name: Checkout + uses: actions/checkout@f90c7b395dac7c5a277c1a6d93d5057c1cddb74e + - name: Setup Node.js + uses: actions/setup-node@1c5c1375b3817ad821719597effe8e3d6f764930 + with: + node-version: '12.14.1' + registry-url: 'https://registry.npmjs.org' + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - uses: actions/cache@70655ec8323daeeaa7ef06d7c56e1b9191396cbe + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install + run: | + yarn --frozen-lockfile + - name: Lint + run: | + yarn lint + - name: Test + run: | + yarn test + - name: Test Node + run: | + yarn test-node + - name: Build + run: | + yarn build-web + - name: Test Web + uses: cypress-io/github-action@8aac1d019734a107e4eaaefe2e26beb3149e5540 + with: + spec: cypress/integration/index.spec.js + - name: Publish RC + run: | + . ./scripts/publish-utils.sh + setup_git + ensure_version_match + git commit -a -m "Updating version [skip ci]" --allow-empty + npm publish --access public --tag RC + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} + + services: + nodeos: + image: eosio/eosjs-ci:v0.2.1 + + ports: + - 8888:8888 + - 9876:9876 diff --git a/.gitignore b/.gitignore index 94ef35587..6bca495a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +.idea dist/ dist-web/ node_modules/ @@ -8,4 +9,3 @@ docs-build/ #cypress artifacts cypress/screenshots/ cypress/videos/ -reports/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 701e20376..000000000 --- a/.travis.yml +++ /dev/null @@ -1,30 +0,0 @@ -env: - global: - PUBLISH_NPM_LATEST_FROM="master" -sudo: false -language: node_js -node_js: - - '10.0.0' -before_install: - - npm i -g npm@6.4.1 - - yarn global add typescript - - yarn global add webpack -before_script: - - source ./scripts/is_latest.sh -script: - - yarn run lint - - yarn run test -deploy: - - provider: script - skip_cleanup: true - script: - - ./scripts/publish-edge.sh - on: - branch: develop - - provider: script - skip_cleanup: true - script: - - ./scripts/publish-tag.sh $PUBLISH_NPM_LATEST_FROM - on: - tags: true - condition: $TRAVIS_IS_LATEST_TAG = true # sourced from ./scripts/is_latest.sh diff --git a/IMPORTANT.md b/IMPORTANT.md new file mode 100644 index 000000000..ed433799c --- /dev/null +++ b/IMPORTANT.md @@ -0,0 +1,27 @@ +# Important Notice + +We (block.one and its affiliates) make available EOSIO and other software, updates, patches and documentation (collectively, Software) on a voluntary basis as a member of the EOSIO community. A condition of you accessing any Software, websites, articles, media, publications, documents or other material (collectively, Material) is your acceptance of the terms of this important notice. + +## Software +We are not responsible for ensuring the overall performance of Software or any related applications. Any test results or performance figures are indicative and will not reflect performance under all conditions. Software may contain components that are open sourced and subject to their own licenses; you are responsible for ensuring your compliance with those licenses. + +We make no representation, warranty, guarantee or undertaking in respect of Software, whether expressed or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software. + +Wallets and related components are complex software that require the highest levels of security. If incorrectly built or used, they may compromise users’ private keys and digital assets. Wallet applications and related components should undergo thorough security evaluations before being used. Only experienced developers should work with such Software. + +Material is not made available to any person or entity that is the subject of sanctions administered or enforced by any country or government or otherwise designated on any list of prohibited or restricted parties (including but not limited to the lists maintained by the United Nations Security Council, the U.S. Government, the European Union or its Member States, or other applicable government authority) or organized or resident in a country or territory that is the subject of country-wide or territory-wide sanctions. You represent and warrant that neither you nor any party having a direct or indirect beneficial interest in you or on whose behalf you are acting as agent or nominee is such a person or entity and you will comply with all applicable import, re-import, sanctions, anti-boycott, export, and re-export control laws and regulations. If this is not accurate or you do not agree, then you must immediately cease accessing our Material and delete all copies of Software. + +Any person using or offering Software in connection with providing software, goods or services to third parties shall advise such third parties of this important notice, including all limitations, restrictions and exclusions of liability. + +## Trademarks +Block.one, EOSIO, EOS, the heptahedron and associated logos and related marks are our trademarks. Other trademarks referenced in Material are the property of their respective owners. + +## Third parties +Any reference in Material to any third party or third-party product, resource or service is not an endorsement or recommendation by Block.one. We are not responsible for, and disclaim any and all responsibility and liability for, your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so information in Material may be out of date or inaccurate. + +## Forward-looking statements +Please note that in making statements expressing Block.one’s vision, we do not guarantee anything, and all aspects of our vision are subject to change at any time and in all respects at Block.one’s sole discretion, with or without notice. We call these “forward-looking statements”, which includes statements on our website and in other Material, other than statements of historical facts, such as statements regarding EOSIO’s development, expected performance, and future features, or our business strategy, plans, prospects, developments and objectives. These statements are only predictions and reflect Block.one’s current beliefs and expectations with respect to future events; they are based on assumptions and are subject to risk, uncertainties and change at any time. + +We operate in a rapidly changing environment and new risks emerge from time to time. Given these risks and uncertainties, you are cautioned not to rely on these forward-looking statements. Actual results, performance or events may differ materially from what is predicted in the forward-looking statements. Some of the factors that could cause actual results, performance or events to differ materially from the forward-looking statements include, without limitation: technical feasibility and barriers; market trends and volatility; continued availability of capital, financing and personnel; product acceptance; the commercial success of any new products or technologies; competition; government regulation and laws; and general economic, market or business conditions. + +All statements are valid only as of the date of first posting and Block.one is under no obligation to, and expressly disclaims any obligation to, update or alter any statements, whether as a result of new information, subsequent events or otherwise. Nothing in any Material constitutes technological, financial, investment, legal or other advice, either in general or with regard to any particular situation or implementation. Please consult with experts in appropriate areas before implementing or utilizing anything contained in Material. diff --git a/LICENSE b/LICENSE index 22d36d65d..463694e95 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017-2019 block.one and its contributors. All rights reserved. +Copyright (c) 2017-2020 block.one and its contributors. All rights reserved. The MIT License diff --git a/README.md b/README.md index b0c6b6d60..e9dfe7bfb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# eosjs ![npm](https://img.shields.io/npm/dw/eosjs.svg) +# eosjs +[![Build Status](https://github.com/eosio/eosjs/workflows/CI/badge.svg?branch=master)](https://github.com/EOSIO/eosjs/actions) [![npm version](https://badge.fury.io/js/eosjs.svg)](https://badge.fury.io/js/eosjs) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ![npm](https://img.shields.io/npm/dw/eosjs.svg) Javascript API for integration with EOSIO-based blockchains using [EOSIO RPC API](https://developers.eos.io/eosio-nodeos/reference). @@ -14,6 +15,21 @@ The official distribution package can be found at [npm](https://www.npmjs.com/pa `yarn add eosjs` +### Using with Typescript + +In order to get access to the `TextEncoding` and `TextDecoding` types, you need to add `@types/text-encoding` as a dev dependency: +`yarn add --dev @types/text-encoding` + +If you're using Node (not a browser) then you'll also need to make sure the `dom` lib is referenced in your `tsconfig.json`: + +``` +{ + "compilerOptions": { + "lib": [..., "dom"] + } +} +``` + ### Browser Distribution Clone this repository locally then run `yarn build-web`. The browser distribution will be located in `dist-web` and can be directly copied into your project repository. The `dist-web` folder contains minified bundles ready for production, along with source mapped versions of the library for debugging. For full browser usage examples, [see the documentation](https://eosio.github.io/eosjs/guides/1.-Browsers.html). @@ -36,7 +52,6 @@ const { Api, JsonRpc, RpcError } = require('eosjs'); const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig'); // development only const fetch = require('node-fetch'); // node only; not needed in browsers const { TextEncoder, TextDecoder } = require('util'); // node only; native TextEncoder/Decoder -const { TextEncoder, TextDecoder } = require('text-encoding'); // React Native, IE11, and Edge Browsers only ``` ## Basic Usage @@ -61,14 +76,14 @@ const rpc = new JsonRpc('http://127.0.0.1:8888', { fetch }); ### API -Include textDecoder and textEncoder when using in Node, React Native, IE11 or Edge Browsers. +Include textDecoder and textEncoder when using in Node. You may exclude these when running in a browser since most modern browsers now natively support these. If your browser does not support these (https://caniuse.com/#feat=textencoder), then you can import them as a dependency through the following deprecated npm package: https://www.npmjs.com/package/text-encoding ```js const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }); ``` ### Sending a transaction -`transact()` is used to sign and push transactions onto the blockchain with an optional configuration object parameter. This parameter can override the default value of `broadcast: true`, and can be used to fill TAPOS fields given `blocksBehind` and `expireSeconds`. Given no configuration options, transactions are expected to be unpacked with TAPOS fields (`expiration`, `ref_block_num`, `ref_block_prefix`) and will automatically be broadcast onto the chain. +`transact()` is used to sign and push transactions onto the blockchain with an optional configuration object parameter. This parameter can override the default value of `broadcast: true`, and can be used to fill TAPOS fields given `expireSeconds` and either `blocksBehind` or `useLastIrreversible`. Given no configuration options, transactions are expected to be unpacked with TAPOS fields (`expiration`, `ref_block_num`, `ref_block_prefix`) and will automatically be broadcast onto the chain. ```js (async () => { @@ -123,4 +138,6 @@ try { ## Important -See LICENSE for copyright and license terms. Block.one makes its contribution on a voluntary basis as a member of the EOSIO community and is not responsible for ensuring the overall performance of the software or any related applications. We make no representation, warranty, guarantee or undertaking in respect of the software or any related documentation, whether expressed or implied, including but not limited to the warranties or merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or documentation or the use or other dealings in the software or documentation. Any test results or performance figures are indicative and will not reflect performance under all conditions. Any reference to any third party or third-party product, service or other resource is not an endorsement or recommendation by Block.one. We are not responsible, and disclaim any and all responsibility and liability, for your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so the information here may be out of date or inaccurate. +See [LICENSE](./LICENSE) for copyright and license terms. + +All repositories and other materials are provided subject to the terms of this [IMPORTANT](./IMPORTANT.md) notice and you must familiarize yourself with its terms. The notice contains important information, limitations and restrictions relating to our software, publications, trademarks, third-party resources, and forward-looking statements. By accessing any of our repositories and other materials, you accept and agree to the terms of the notice. diff --git a/cypress.json b/cypress.json index af2eeb167..e2ebfe37c 100644 --- a/cypress.json +++ b/cypress.json @@ -3,10 +3,5 @@ "fixturesFolder": false, "pluginsFile": false, "supportFile": false, - "reporter": "mochawesome", - "reporterOptions": { - "reportDir": "reports", - "overwrite": false - }, "userAgent": "Chrome cypress" } diff --git a/docs.json b/docs.json new file mode 100644 index 000000000..fb544e6fc --- /dev/null +++ b/docs.json @@ -0,0 +1,20 @@ +{ + "name": "eosjs", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "typedoc", + "options": { + "disable_filters": true + }, + "filters": [ + { "name": "remove_extension" } + ] + } + ] +} diff --git a/docs/01_technical-overview.md b/docs/01_technical-overview.md new file mode 100644 index 000000000..fb7804bad --- /dev/null +++ b/docs/01_technical-overview.md @@ -0,0 +1,24 @@ +As stated in the [introduction](index.md), `eosjs` integrates with EOSIO-based blockchains using the [EOSIO Nodeos RPC API](https://developers.eos.io/eosio-nodeos/reference). + +In general, there are two objects that are used to interact with a blockchain via `eosjs`: the `JsonRpc` object, and the `Api` object. + +## JsonRpc +The `JsonRpc` object is typically used when signing is not necessary. Some examples include [getting block information](how-to-guides/00_how-to-get-block-information.md), [getting transaction information](how-to-guides/02_how-to-get-transaction-information.md), or [getting table information](how-to-guides/09_how-to-get-table-information.md). + +The requests made by the `JsonRpc` object will either use a built-in `fetch` library, or [the `fetch` library passed in by the user](basic-usage/01_commonjs.md) to issue requests to the endpoint specified when instantiating the `JsonRpc` object. When the various methods ([get_abi](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-jsonrpc.ts#L66), [get_account](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-jsonrpc.ts#L71), [get_block_header_state](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-jsonrpc.ts#L76), etc) of the `JsonRpc` object are invoked, the calls are delegated to the `JsonRpc` object's [fetch function](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-jsonrpc.ts#L42-L63), which in turn, delegate the requests to the `fetch` library. + +## Api +The `Api` object is typically used when transacting on an EOSIO-based blockchain. Some examples include [staking](how-to-guides/03_how-to-stake.md), [creating an account](how-to-guides/05_how-to-create-an-account.md), or [proposing multi-sig transactions](how-to-guides/13_how-to-propose-a-multisig-transaction.md). + +The typical use of the `Api` object is to call its [`transact` method](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-api.ts#L214-L254). This method performs a number of steps depending on the input passed to it: + +* The `transact` method first checks if the **chainId** was set in the `Api` constructor, and if not, uses the [`JsonRpc` object's](#jsonrpc) [`get_info`](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-jsonrpc.ts#L101) method to retrieve the **chainId**. +* The `transact` method then checks if the `expireSeconds` and either `blocksBehind` or `useLastIrreversible` fields are set and well-formed in the [optional configuration object, as specified in *How to Submit a Transaction*](how-to-guides/01_how-to-submit-a-transaction.md#). + * If so, either the *last_irreversible_block_num* or the block *blocksBehind* the head block retrieved from [`JsonRpc`'s `get_info`](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-jsonrpc.ts#L101) is set as the reference block and the transaction header is serialized using this reference block and the `expireSeconds` field. +* The `transact` method then checks if the appropriate TAPOS fields are present in the transaction ([they can either be specified directly in the transaction or in the optional configuration object](how-to-guides/01_how-to-submit-a-transaction.md#)) and throws an Error if not. +* The necessary `abi`s for a transaction are then retrieved for the case when `transact` is expected to sign the transaction. +* The `actions` are serialized using the `eosjs-serialize` `ser` object. +* The entire transaction is then [serialized](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-api.ts#L154-L166), also using the `eosjs-serialize` `ser` object. +* The transaction is then optionally signed, using the `signatureProvider`, the previously retrieved `abi`s, the private keys of the `signatureProvider`, and the `chainId`. +* The transaction is then optionally compressed, using the `deflate` function of a Javascript zlib library. +* The transaction is then optionally broadcasted using `JsonRpc`'s [`push_transaction`](https://github.com/EOSIO/eosjs/blob/master/src/eosjs-jsonrpc.ts#L187). \ No newline at end of file diff --git a/docs/02_installation.md b/docs/02_installation.md new file mode 100644 index 000000000..4c0b4e9ac --- /dev/null +++ b/docs/02_installation.md @@ -0,0 +1,9 @@ +`eosjs` can be installed via [`yarn`](https://yarnpkg.com/en/) +```javascript +yarn add eosjs +``` + +or [`npm`](https://www.npmjs.com/) +```javascript +npm install eosjs +``` \ No newline at end of file diff --git a/docs/2.-Transaction-Examples.md b/docs/2.-Transaction-Examples.md deleted file mode 100644 index d59dbd9d3..000000000 --- a/docs/2.-Transaction-Examples.md +++ /dev/null @@ -1,178 +0,0 @@ -# Transactions - -To send transactions and trigger actions on the blockchain, you must have an instance of `Api`. - -The signature provider must contain the private keys corresponding to the actors and permission requirements of the actions being executed. - - -## CommonJS - -```javascript -const { Api, JsonRpc } = require('eosjs'); -const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig'); // development only -const fetch = require('node-fetch'); // node only -const { TextDecoder, TextEncoder } = require('util'); // node only -const { TextEncoder, TextDecoder } = require('text-encoding'); // React Native, IE11, and Edge Browsers only - -const privateKeys = [privateKey1]; - -const signatureProvider = new JsSignatureProvider(privateKeys); -const rpc = new JsonRpc('http://127.0.0.1:8888', { fetch }); -const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }); -``` - -## ES Modules - -```javascript -import { Api, JsonRpc } from 'eosjs'; -import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig'; // development only - -const privateKeys = [privateKey1]; - -const signatureProvider = new JsSignatureProvider(privateKeys); -const rpc = new JsonRpc('http://127.0.0.1:8888'); -const api = new Api({ rpc, signatureProvider }) -``` - -## Examples - -### Buy ram - -```javascript -const result = await api.transact({ - actions: [{ - account: 'eosio', - name: 'buyrambytes', - authorization: [{ - actor: 'useraaaaaaaa', - permission: 'active', - }], - data: { - payer: 'useraaaaaaaa', - receiver: 'useraaaaaaaa', - bytes: 8192, - }, - }] -}, { - blocksBehind: 3, - expireSeconds: 30, -}); -``` - -### Stake - -```javascript -const result = await api.transact({ - actions: [{ - account: 'eosio', - name: 'delegatebw', - authorization: [{ - actor: 'useraaaaaaaa', - permission: 'active', - }], - data: { - from: 'useraaaaaaaa', - receiver: 'useraaaaaaaa', - stake_net_quantity: '1.0000 SYS', - stake_cpu_quantity: '1.0000 SYS', - transfer: false, - } - }] -}, { - blocksBehind: 3, - expireSeconds: 30, -}); -``` - -## Example: Unstake - -```javascript -const result = await api.transact({ - actions: [{ - account: 'eosio', - name: 'undelegatebw', - authorization: [{ - actor: 'useraaaaaaaa', - permission: 'active', - }], - data: { - from: 'useraaaaaaaa', - receiver: 'useraaaaaaaa', - unstake_net_quantity: '1.0000 SYS', - unstake_cpu_quantity: '1.0000 SYS', - transfer: false, - } - }] -}, { - blocksBehind: 3, - expireSeconds: 30, -}); -``` - -### Create New Account (multiple actions) - -```javascript -const result = await api.transact({ - actions: [{ - account: 'eosio', - name: 'newaccount', - authorization: [{ - actor: 'useraaaaaaaa', - permission: 'active', - }], - data: { - creator: 'useraaaaaaaa', - name: 'mynewaccount', - owner: { - threshold: 1, - keys: [{ - key: 'PUB_R1_6FPFZqw5ahYrR9jD96yDbbDNTdKtNqRbze6oTDLntrsANgQKZu', - weight: 1 - }], - accounts: [], - waits: [] - }, - active: { - threshold: 1, - keys: [{ - key: 'PUB_R1_6FPFZqw5ahYrR9jD96yDbbDNTdKtNqRbze6oTDLntrsANgQKZu', - weight: 1 - }], - accounts: [], - waits: [] - }, - }, - }, - { - account: 'eosio', - name: 'buyrambytes', - authorization: [{ - actor: 'useraaaaaaaa', - permission: 'active', - }], - data: { - payer: 'useraaaaaaaa', - receiver: 'mynewaccount', - bytes: 8192, - }, - }, - { - account: 'eosio', - name: 'delegatebw', - authorization: [{ - actor: 'useraaaaaaaa', - permission: 'active', - }], - data: { - from: 'useraaaaaaaa', - receiver: 'mynewaccount', - stake_net_quantity: '1.0000 SYS', - stake_cpu_quantity: '1.0000 SYS', - transfer: false, - } - }] -}, { - blocksBehind: 3, - expireSeconds: 30, -}); -``` diff --git a/docs/4.-Reading blockchain-Examples.md b/docs/4.-Reading blockchain-Examples.md deleted file mode 100644 index 4174c0b3f..000000000 --- a/docs/4.-Reading blockchain-Examples.md +++ /dev/null @@ -1,164 +0,0 @@ -# Reading blockchain - -Reading blockchain state only requires an instance of `JsonRpc` connected to a node. - -```javascript -const { JsonRpc } = require('eosjs'); -const fetch = require('node-fetch'); // node only; not needed in browsers -const rpc = new JsonRpc('http://localhost:8888', { fetch }); -``` - -## Examples - -### Get table rows - -Get the first 10 token balances of account _testacc_. - -```javascript -const resp = await rpc.get_table_rows({ - json: true, // Get the response as json - code: 'eosio.token', // Contract that we target - scope: 'testacc' // Account that owns the data - table: 'accounts' // Table name - limit: 10, // Maximum number of rows that we want to get - reverse = false, // Optional: Get reversed data - show_payer = false, // Optional: Show ram payer -}); - -console.log(resp.rows); -``` -Output: - -```json -{ - "rows": [{ - "balance": "100.0000 HAK" - } - ], - "more": false -} -``` - -### Get one row by index - -```javascript -const resp = await rpc.get_table_rows({ - json: true, // Get the response as json - code: 'contract', // Contract that we target - scope: 'contract' // Account that owns the data - table: 'profiles' // Table name - lower_bound: 'testacc' // Table primary key value - limit: 1, // Here we limit to 1 to get only the - reverse = false, // Optional: Get reversed data - show_payer = false, // Optional: Show ram payer -}); -console.log(resp.rows); -``` -Output: - -```json -{ - "rows": [{ - "user": "testacc", - "age": 21, - "surname": "Martin" - } - ], - "more": false -} -``` - -### Get one row by secondary index - -```javascript -const resp = await rpc.get_table_rows({ - json: true, // Get the response as json - code: 'contract', // Contract that we target - scope: 'contract' // Account that owns the data - table: 'profiles' // Table name - table_key: 'age' // Table secondaray key name - lower_bound: 21 // Table secondary key value - limit: 1, // Here we limit to 1 to get only row - reverse = false, // Optional: Get reversed data - show_payer = false, // Optional: Show ram payer -}); -console.log(resp.rows); -``` -Output: - -```json -{ - "rows": [{ - "user": "testacc", - "age": 21, - "surname": "Martin" - } - ], - "more": false -} -``` - -### Get currency balance - -```javascript -console.log(await rpc.get_currency_balance('eosio.token', 'testacc', 'HAK')); -``` -Output: - -```json -[ "1000000000.0000 HAK" ] -``` - -### Get account info - -```javascript -console.log(await rpc.get_account('testacc')); -``` -Output: - -```json -{ "account_name": "testacc", - "head_block_num": 1079, - "head_block_time": "2018-11-10T00:45:53.500", - "privileged": false, - "last_code_update": "1970-01-01T00:00:00.000", - "created": "2018-11-10T00:37:05.000", - "ram_quota": -1, - "net_weight": -1, - "cpu_weight": -1, - "net_limit": { "used": -1, "available": -1, "max": -1 }, - "cpu_limit": { "used": -1, "available": -1, "max": -1 }, - "ram_usage": 2724, - "permissions": - [ { "perm_name": "active", "parent": "owner", "required_auth": [] }, - { "perm_name": "owner", "parent": "", "required_auth": [] } ], - "total_resources": null, - "self_delegated_bandwidth": null, - "refund_request": null, - "voter_info": null } -``` - -### Get block - -```javascript -console.log(await rpc.get_block(1)); -``` -Output: - -```json -{ "timestamp": "2018-06-01T12:00:00.000", - "producer": "", - "confirmed": 1, - "previous": "0000000000000000000000000000000000000000000000000000000000000000", - "transaction_mroot": "0000000000000000000000000000000000000000000000000000000000000000", - "action_mroot": "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f", - "schedule_version": 0, - "new_producers": null, - "header_extensions": [], - "producer_signature": "SIG_K1_111111111111111111111111111111111111111111111111111111111111111116uk5ne", - "transactions": [], - "block_extensions": [], - "id": "00000001bcf2f448225d099685f14da76803028926af04d2607eafcf609c265c", - "block_num": 1, - "ref_block_prefix": 2517196066 } -``` diff --git a/docs/3.-Browsers.md b/docs/basic-usage/00_browser.md similarity index 56% rename from docs/3.-Browsers.md rename to docs/basic-usage/00_browser.md index 35a485069..840e05c9e 100644 --- a/docs/3.-Browsers.md +++ b/docs/basic-usage/00_browser.md @@ -1,16 +1,14 @@ -# Browsers - -## Usage -`npm run build-web` or `yarn build-web` - -Reuse the `api` object for all transactions; it caches ABIs to reduce network usage. Only call `new eosjs_api.Api(...)` once. - +To use `eosjs` in a browser run `npm run build-web` or `yarn build-web`. This will create the `dist-web` folder and web distribution modules. ```html

 
-
-
-
+
+
+
+```
+
+To cache ABIs and reduce network usage, reuse the `api` object for all transactions.  This implies you should only call `new eosjs_api.Api(...)` once.
+```html
 
-        
-        
+        
+        
+