├── .babelrc ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── work_item.md ├── PULL_REQUEST_TEMPLATE.md └── workflow │ └── checkin-actions ├── .gitignore ├── .npmignore ├── .npmrc.template ├── .prettierrc ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cypress └── integration │ └── index.spec.js ├── docs ├── 2.-Transaction-Examples.md ├── 3.-Browsers.md ├── 4.-Reading blockchain-Examples.md ├── 5.-Testing and Building with DUNE.md ├── Testing ReadOnly.md └── design │ └── Cryptography.md ├── package-lock.json ├── package.json ├── scripts ├── is_latest.sh ├── publish-edge.sh ├── publish-tag.sh ├── publish-utils.sh ├── run-cypress.sh └── simple-publish.sh ├── src ├── ChainSemanticVersion.ts ├── PrivateKey.ts ├── PublicKey.ts ├── Signature.ts ├── abi.abi.json ├── eosjs-api-interfaces.ts ├── eosjs-api.ts ├── eosjs-jsonrpc.ts ├── eosjs-jssig.ts ├── eosjs-key-conversions.ts ├── eosjs-numeric.ts ├── eosjs-rpc-interfaces.ts ├── eosjs-rpcerror.ts ├── eosjs-serialize.ts ├── eosjs-webauthn-sig.ts ├── index.ts ├── ripemd.es5.js ├── ripemd.js ├── rpc-web.ts ├── tests │ ├── TestConfig.ts │ ├── eosjs-api.test.ts │ ├── eosjs-jsonrpc.test.ts │ ├── eosjs-jssig.test.ts │ ├── eosjs-util.test.ts │ ├── logo.svg │ ├── node.js │ ├── node.test.ts │ ├── readonly_contract │ │ ├── contract.cpp │ │ └── include │ │ │ └── contract.hpp │ ├── serialization.test.ts │ ├── setupJest.js │ ├── strict-serialization.test.ts │ ├── web.css │ └── web.html └── transaction.abi.json ├── tsconfig.json ├── tsconfig.web.json ├── tslint.json ├── typedoc.json ├── webpack.debug.js ├── webpack.prod.js └── workflows └── unit-tests.yml /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "targets": { 5 | "browsers": ["last 2 versions"] 6 | } 7 | }], 8 | "stage-1" 9 | ], 10 | "plugins": [ 11 | [ 12 | "transform-runtime", 13 | { 14 | "polyfill": false, 15 | "regenerator": true 16 | } 17 | ] 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": ["@typescript-eslint", "es-x"], 5 | "ignorePatterns": ["lib/*", "node_modules/**"], 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:prettier/recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended", 11 | "plugin:es-x/no-new-in-es2022" 12 | ], 13 | "rules": { 14 | "prettier/prettier": "warn", 15 | "no-console": "warn", 16 | "sort-imports": [ 17 | "warn", 18 | { 19 | "ignoreCase": true, 20 | "ignoreDeclarationSort": true 21 | } 22 | ], 23 | "@typescript-eslint/explicit-module-boundary-types": "off", 24 | "@typescript-eslint/no-explicit-any": "off", 25 | "@typescript-eslint/no-namespace": "off", 26 | "@typescript-eslint/no-non-null-assertion": "off", 27 | "@typescript-eslint/no-empty-function": "warn", 28 | "@typescript-eslint/no-this-alias": "off", 29 | "no-inner-declarations": "off", 30 | "es-x/no-class-fields": "OFF", 31 | "es-x/no-export-ns-from": "OFF" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | --- 5 | 6 | ## Version of EOSJS 7 | _which version of eosjs exhibits the issue_ 8 | 9 | ### Bug 10 | A clear and concise title 11 | **Expected behavior** What you expected to happen. 12 | 13 | #### `To Reproduce` 14 | Steps to reproduce the behavior. 15 | 16 | #### `Screenshots` 17 | Always Helpful 18 | 19 | #### `Platform` 20 | - [ ] Node 21 | - [ ] Web Browser 22 | - [ ] Mobile 23 | 24 | #### `Additional Details` 25 | _version of node, version of browser, mobile os version, anything else_ 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/work_item.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Work Item 3 | about: Describes planned features and updates 4 | 5 | --- 6 | 7 | ### Work Title 8 | Summarize Desired Outcome 9 | 10 | #### `Requirements` 11 | One Sentence 12 | 13 | #### `Scenarios` 14 | 15 | ### Additional Considerations 16 | _The Following Are Optional_ 17 | 18 | #### `Design Notes` 19 | Tradeoffs, compatibility, encapsulation 20 | 21 | #### `Coding Notes` 22 | How to code it 23 | 24 | #### `Additional context` 25 | Add any other context about the problem here. 26 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Change 2 | short description 3 | 4 | ### Listing of Commits 5 | 6 | 7 | ### Listing of Files Changed 8 | 9 | 10 | ### API Changes 11 | 12 | ### Documentation Additions 13 | -------------------------------------------------------------------------------- /.github/workflow/checkin-actions: -------------------------------------------------------------------------------- 1 | name: checkin-actions 2 | on: 3 | push: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | node-version: [18.x 19.x] 12 | 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v3 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - run: npm ci 21 | - run: npm run build 22 | - run: npm run test 23 | - run: npm run test-serialization -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | # ignore webstorm IDE 3 | .idea 4 | dist/ 5 | dist-web/ 6 | node_modules/ 7 | docs-build/ 8 | *.tgz 9 | 10 | #cypress artifacts 11 | cypress/screenshots/ 12 | cypress/videos/ 13 | reports/ 14 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Exclude all files by default 2 | * 3 | 4 | # Include distribution bundle but exclude test files if they are built into dist 5 | !dist/** 6 | *.test.* 7 | 8 | # Include documentation and version information in bundle 9 | !CONTRIBUTING.md 10 | 11 | # Include any additional source files which should be bundled 12 | !src/**/*.abi.json 13 | -------------------------------------------------------------------------------- /.npmrc.template: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | arrowParens: "always" 2 | bracketSpacing: false 3 | endOfLine: "lf" 4 | printWidth: 100 5 | semi: false 6 | singleQuote: true 7 | tabWidth: 4 8 | trailingComma: "es5" -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | env: 2 | global: 3 | PUBLISH_NPM_LATEST_FROM="master" 4 | sudo: false 5 | language: node_js 6 | node_js: 7 | - '16.0.0' 8 | before_install: 9 | - npm i -g npm@8.0.0 10 | - npm install -g typescript 11 | - npm install -g webpack 12 | before_script: 13 | - source ./scripts/is_latest.sh 14 | script: 15 | - npm run lint 16 | - npm run test 17 | deploy: 18 | - provider: script 19 | skip_cleanup: true 20 | script: 21 | - ./scripts/publish-edge.sh 22 | on: 23 | branch: develop 24 | - provider: script 25 | skip_cleanup: true 26 | script: 27 | - ./scripts/publish-tag.sh $PUBLISH_NPM_LATEST_FROM 28 | on: 29 | tags: true 30 | condition: $TRAVIS_IS_LATEST_TAG = true # sourced from ./scripts/is_latest.sh 31 | notifications: 32 | webhooks: 33 | secure: bBIpgJmtb4WbXgGTD71INlC7LqscHKOWZMiBmRtkUD1X9fjNzgNVKsjf4ZlTWpq9YtKFox0bAWjS00feRYlHZZal5tZEt9wRKJbkZEgnCa32YF2YOng0Q5JxoIBskH0SSUf/qocwjPmYQu+2Y3Y9KoLoV2C72qedGgSrrMmLWSVPA91tyqPl4gOU0HS6/9KU1QNf7Uv0v7Fo10+V+JwQC03MoC2+1dkz799LuUr2SmmN3JuLWSXl9KIq7CCF7wkcqzq1vMk176mmEH1/26InNXKLXIW/MqIjMfkZq4j+IjW+JbuWz/Qh3EY+rbQAMT+++tIYHNsh2wZppvAAPjf4vqO3m9Q4WBB2KbL6EDvE/ySDURxLzZl618u8WUbJh2o61k0R0rxPPl6yFdkl9jXV48IVTHEDYHkgghtLSSENMUmjK8kshA2qreG79Mj2l2jicZ5Vn7jv4iORQHS0PUXg4ouds+5dY0SPm9aLIop6f9WD0mcQFP9mEfagWA6EnGUxTPFQDQmNVGkpZk2afYNAT4LbOd8wrqDTsNWXRvA3QLLOiqBbhajY17Fvrh24ecJ79TERABLscFkYtke8Xx2K/lKg/T10TZuaL9VbTg4rKrD+59OTZev6JlNdGG8FR31SuJK8Ds3zmiyojCoCay54BDUbmZ0STJ1/6ocUvFka0YE= 34 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to EOSJS 2 | 3 | eosjs is deprecated. Please see [WharfKit](https://github.com/wharfkit/) for an updated SDK and library. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | eosnetworkfoundation/mandel-eosjs 2 | 3 | Copyright (c) 2021-2022 EOS Network Foundation (ENF) and its contributors. All rights reserved. 4 | This ENF software is based upon: 5 | 6 | EOSIO/eosjs 7 | 8 | Copyright (c) 2017-2019 block.one and its contributors. All rights reserved. 9 | 10 | The MIT License 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | enf-eosjs  2 | 3 | ## ⚠ enf-eosjs is deprecated please use [WharfKit](https://github.com/wharfkit/) as the latest EOS SDK. For a basic SDK similar to eosjs check out [WharfKit Antelope](https://github.com/wharfkit/antelope) 4 | 5 | ## Installation 6 | 7 | ### NPM 8 | 9 | [enf-eosjs](https://www.npmjs.com/package/enf-eosjs) has been updated to support latest features in EOS blockchain. This is an updated version of the popular eosjs package. 10 | 11 | ### NodeJS Dependency 12 | 13 | `npm install enf-eosjs` 14 | 15 | ### Using with Typescript 16 | 17 | 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`: 18 | 19 | ``` 20 | { 21 | "compilerOptions": { 22 | "lib": [..., "dom"] 23 | } 24 | } 25 | ``` 26 | 27 | ### Browser Distribution 28 | 29 | Clone this repository locally then run `npm run 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. 30 | 31 | ## Getting Started 32 | 33 | Very simple example of using **enf-eosjs**. Included unused imports as examples. 34 | 35 | ```shell 36 | npm init es6 37 | npm install enf-eosjs 38 | node node_test 39 | ``` 40 | 41 | ```js 42 | /* 43 | * @module test_enf_eosjs 44 | * PUT THIS INTO A FILE NAMED node_test.js 45 | */ 46 | 47 | import { Api, JsonRpc, RpcError } from 'enf-eosjs'; 48 | import fetch from 'node-fetch' 49 | 50 | const rpc = new JsonRpc('https://localhost:443', { fetch }); 51 | const api = new Api({ rpc, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }); 52 | 53 | var info = await rpc.get_info(); 54 | 55 | console.log(info); 56 | ``` 57 | 58 | ## Import 59 | 60 | ### Signature Providers 61 | 62 | It best to use a secure well supported secret store. Some examples of providers include: 63 | * Azure Key Vault 64 | * Hashicorp Vault 65 | * Google Cloud Secret Manager 66 | * AWS Secrets Management 67 | 68 | *JsSignatureProvider* is included as an example, and it is not provided by enf-eosjs. 69 | 70 | ### ES Modules 71 | 72 | Importing using ES6 module syntax in the browser is supported if you have a transpiler, such as Babel. 73 | ```js 74 | import { Api, JsonRpc, RpcError } from 'enf-eosjs'; 75 | import { JsSignatureProvider } from 'enf-eosjs/dist/eosjs-jssig'; // development only 76 | ``` 77 | 78 | ### CommonJS 79 | 80 | Importing using commonJS syntax is supported by NodeJS out of the box. 81 | ```js 82 | const { Api, JsonRpc, RpcError } = require('enf-eosjs'); 83 | const fetch = require('node-fetch'); // node only; not needed in browsers 84 | ``` 85 | 86 | ## Basic Usage 87 | 88 | ### Signature Provider 89 | 90 | The Signature Provider holds private keys and is responsible for signing transactions. 91 | 92 | ***Using the JsSignatureProvider in the browser is not secure and should only be used for development purposes. Use a secure vault outside of the context of the webpage to ensure security when signing transactions in production*** 93 | 94 | ```js 95 | const defaultPrivateKey = "5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr"; // bob 96 | const signatureProvider = new JsSignatureProvider([defaultPrivateKey]); 97 | ``` 98 | 99 | ### JSON-RPC 100 | 101 | Open a connection to JSON-RPC, include `fetch` when on NodeJS. 102 | ```js 103 | const rpc = new JsonRpc('http://127.0.0.1:8888', { fetch }); 104 | ``` 105 | 106 | ### API 107 | 108 | No longer need to include textDecoder and textEncoder when using in Node, React Native, IE11 or Edge Browsers. 109 | ```js 110 | const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }); 111 | ``` 112 | 113 | ### Sending a transaction 114 | 115 | `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. 116 | 117 | With the introduction of Leap v3.1 the retry transaction feature also adds 5 new optional fields to the configuration object: 118 | 119 | - `useOldRPC`: use old RPC `push_transaction`, rather than new RPC send_transaction 120 | - `useOldSendRPC`: use old RPC `/v1/chain/send_transaction`, rather than new RPC `/v1/chain/send_transaction2` 121 | - `returnFailureTrace`: return partial traces on failed transactions 122 | - `retryTrxNumBlocks`: request node to retry transaction until in a block of given height, blocking call 123 | - `retryIrreversible`: request node to retry transaction until it is irreversible or expires, blocking call 124 | 125 | ```js 126 | (async () => { 127 | const result = await api.transact({ 128 | actions: [{ 129 | account: 'eosio.token', 130 | name: 'transfer', 131 | authorization: [{ 132 | actor: 'useraaaaaaaa', 133 | permission: 'active', 134 | }], 135 | data: { 136 | from: 'useraaaaaaaa', 137 | to: 'useraaaaaaab', 138 | quantity: '0.0001 SYS', 139 | memo: '', 140 | }, 141 | }] 142 | }, { 143 | blocksBehind: 3, 144 | expireSeconds: 30 145 | }); 146 | console.dir(result); 147 | })(); 148 | ``` 149 | 150 | ### Read Only Transactions 151 | Leap 4.0 introduced read only transaction. A read-only transaction does not change the state and is not added into the blockchain. It is useful for users to retrieve complex chain information. 152 | 153 | ```js 154 | /* 155 | * Read Only transaciton can not modify state 156 | * In this example a special read only action in a custom contract is executed 157 | * Note the empty fields for authoriziation and data. 158 | */ 159 | const readonlyTransfer = async () => 160 | await api.transact( 161 | { 162 | actions: [ 163 | { 164 | account: testActor, 165 | name: 'getvalue', 166 | authorization: [], 167 | data: {}, 168 | }, 169 | ], 170 | }, 171 | { 172 | broadcast: true, 173 | readOnly: true, 174 | blocksBehind: 3, 175 | expireSeconds: 72, 176 | } 177 | ) 178 | // execute the read only transaction 179 | const transactionReadOnlyResponse = await readonlyTransfer(); 180 | // processed.receipt has status,cpu_usage_us,net_usage_words 181 | console.log(`Transaction Id ${transactionReadOnlyResponse.transaction_id} CPU Usage ${transactionReadOnlyResponse.processed.receipt.cpu_usage_us}`) 182 | ``` 183 | 184 | ### Error handling 185 | 186 | use `RpcError` for handling RPC Errors 187 | ```js 188 | ... 189 | try { 190 | const result = await api.transact({ 191 | ... 192 | } catch (e) { 193 | console.log('\nCaught exception: ' + e); 194 | if (e instanceof RpcError) 195 | console.log(JSON.stringify(e.json, null, 2)); 196 | } 197 | ... 198 | ``` 199 | 200 | ## Contributing 201 | 202 | [Contributing Guide](./CONTRIBUTING.md) 203 | 204 | [Code of Conduct](./CONTRIBUTING.md#conduct) 205 | 206 | ## License 207 | 208 | [MIT](./LICENSE) 209 | 210 | ## Important 211 | 212 | See LICENSE for copyright and license terms. This work is made 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 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 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. Any person using or offering this software in connection with providing software, goods or services to third parties shall advise such third parties of these license terms, disclaimers and exclusions of liability. Block.one, EOSIO, EOSIO Labs, EOS, EOS Network Foundation. 213 | 214 | 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 this software. 215 | -------------------------------------------------------------------------------- /cypress/integration/index.spec.js: -------------------------------------------------------------------------------- 1 | describe('eosjs web test', () => { 2 | it('loads', () => { 3 | cy.visit(('./src/tests/web.html')); 4 | }); 5 | it('runs all tests successfully', () => { 6 | cy.visit(('./src/tests/web.html')) 7 | cy.get('div.tests>div>button').each((test) => { // iterate through all the tests 8 | cy.wrap(test).click(); // click the button to start the test 9 | cy.wrap(test).contains('Success', { timeout: 5000 }); // wait 5 seconds for success or treat as failure 10 | cy.wait(500); // allow time for transaction to confirm (prevents duplicate transactions) 11 | }); 12 | }); 13 | }) 14 | -------------------------------------------------------------------------------- /docs/2.-Transaction-Examples.md: -------------------------------------------------------------------------------- 1 | # Transactions 2 | 3 | To send transactions and trigger actions on the blockchain, you must have an instance of `Api`. 4 | 5 | The signature provider must contain the private keys corresponding to the actors and permission requirements of the actions being executed. 6 | 7 | 8 | ## CommonJS 9 | 10 | ```javascript 11 | const { Api, JsonRpc } = require('eosjs'); 12 | const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig'); // development only 13 | const fetch = require('node-fetch'); // node only 14 | const { TextDecoder, TextEncoder } = require('util'); // node only 15 | const { TextEncoder, TextDecoder } = require('text-util'); // React Native, IE11, and Edge Browsers only 16 | 17 | const privateKeys = [privateKey1]; 18 | 19 | const signatureProvider = new JsSignatureProvider(privateKeys); 20 | const rpc = new JsonRpc('http://127.0.0.1:8888', { fetch }); 21 | const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }); 22 | ``` 23 | 24 | ## ES Modules 25 | 26 | ```javascript 27 | import { Api, JsonRpc } from 'eosjs'; 28 | import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig'; // development only 29 | 30 | const privateKeys = [privateKey1]; 31 | 32 | const signatureProvider = new JsSignatureProvider(privateKeys); 33 | const rpc = new JsonRpc('http://127.0.0.1:8888'); 34 | const api = new Api({ rpc, signatureProvider }) 35 | ``` 36 | 37 | ## Examples 38 | 39 | ### Buy ram 40 | 41 | ```javascript 42 | const result = await api.transact({ 43 | actions: [{ 44 | account: 'eosio', 45 | name: 'buyrambytes', 46 | authorization: [{ 47 | actor: 'useraaaaaaaa', 48 | permission: 'active', 49 | }], 50 | data: { 51 | payer: 'useraaaaaaaa', 52 | receiver: 'useraaaaaaaa', 53 | bytes: 8192, 54 | }, 55 | }] 56 | }, { 57 | blocksBehind: 3, 58 | expireSeconds: 30, 59 | }); 60 | ``` 61 | 62 | ### Stake 63 | 64 | ```javascript 65 | const result = await api.transact({ 66 | actions: [{ 67 | account: 'eosio', 68 | name: 'delegatebw', 69 | authorization: [{ 70 | actor: 'useraaaaaaaa', 71 | permission: 'active', 72 | }], 73 | data: { 74 | from: 'useraaaaaaaa', 75 | receiver: 'useraaaaaaaa', 76 | stake_net_quantity: '1.0000 SYS', 77 | stake_cpu_quantity: '1.0000 SYS', 78 | transfer: false, 79 | } 80 | }] 81 | }, { 82 | blocksBehind: 3, 83 | expireSeconds: 30, 84 | }); 85 | ``` 86 | 87 | ## Example: Unstake 88 | 89 | ```javascript 90 | const result = await api.transact({ 91 | actions: [{ 92 | account: 'eosio', 93 | name: 'undelegatebw', 94 | authorization: [{ 95 | actor: 'useraaaaaaaa', 96 | permission: 'active', 97 | }], 98 | data: { 99 | from: 'useraaaaaaaa', 100 | receiver: 'useraaaaaaaa', 101 | unstake_net_quantity: '1.0000 SYS', 102 | unstake_cpu_quantity: '1.0000 SYS', 103 | transfer: false, 104 | } 105 | }] 106 | }, { 107 | blocksBehind: 3, 108 | expireSeconds: 30, 109 | }); 110 | ``` 111 | 112 | ### Create New Account (multiple actions) 113 | 114 | ```javascript 115 | const result = await api.transact({ 116 | actions: [{ 117 | account: 'eosio', 118 | name: 'newaccount', 119 | authorization: [{ 120 | actor: 'useraaaaaaaa', 121 | permission: 'active', 122 | }], 123 | data: { 124 | creator: 'useraaaaaaaa', 125 | name: 'mynewaccount', 126 | owner: { 127 | threshold: 1, 128 | keys: [{ 129 | key: 'PUB_R1_6FPFZqw5ahYrR9jD96yDbbDNTdKtNqRbze6oTDLntrsANgQKZu', 130 | weight: 1 131 | }], 132 | accounts: [], 133 | waits: [] 134 | }, 135 | active: { 136 | threshold: 1, 137 | keys: [{ 138 | key: 'PUB_R1_6FPFZqw5ahYrR9jD96yDbbDNTdKtNqRbze6oTDLntrsANgQKZu', 139 | weight: 1 140 | }], 141 | accounts: [], 142 | waits: [] 143 | }, 144 | }, 145 | }, 146 | { 147 | account: 'eosio', 148 | name: 'buyrambytes', 149 | authorization: [{ 150 | actor: 'useraaaaaaaa', 151 | permission: 'active', 152 | }], 153 | data: { 154 | payer: 'useraaaaaaaa', 155 | receiver: 'mynewaccount', 156 | bytes: 8192, 157 | }, 158 | }, 159 | { 160 | account: 'eosio', 161 | name: 'delegatebw', 162 | authorization: [{ 163 | actor: 'useraaaaaaaa', 164 | permission: 'active', 165 | }], 166 | data: { 167 | from: 'useraaaaaaaa', 168 | receiver: 'mynewaccount', 169 | stake_net_quantity: '1.0000 SYS', 170 | stake_cpu_quantity: '1.0000 SYS', 171 | transfer: false, 172 | } 173 | }] 174 | }, { 175 | blocksBehind: 3, 176 | expireSeconds: 30, 177 | }); 178 | ``` 179 | ## Old RPC Behavior 180 | 181 | By default, transactions use the send_transaction2 endpoint and the updated transaction behavior. If you would like to revert to the previous behavior pass in the boolean **useOldSendRPC** with value True. 182 | [See Readme *Sending A Transaction*](../README.md#Sending%20a%20transaction) for additional paramaters. 183 | 184 | ```javascript 185 | const result = await api.transact({ 186 | actions: [{ 187 | account: 'eosio', 188 | name: 'delegatebw', 189 | authorization: [{ 190 | actor: 'useraaaaaaaa', 191 | permission: 'active', 192 | }], 193 | data: { 194 | from: 'useraaaaaaaa', 195 | receiver: 'useraaaaaaaa', 196 | stake_net_quantity: '1.0000 SYS', 197 | stake_cpu_quantity: '1.0000 SYS', 198 | transfer: false, 199 | } 200 | }] 201 | }, { 202 | blocksBehind: 3, 203 | expireSeconds: 30, 204 | useOldSendRPC: true, 205 | }); 206 | ``` -------------------------------------------------------------------------------- /docs/3.-Browsers.md: -------------------------------------------------------------------------------- 1 | # Browsers 2 | 3 | ## Usage 4 | `npm run build-web` 5 | 6 | Reuse the `api` object for all transactions; it caches ABIs to reduce network usage. Only call `new eosjs_api.Api(...)` once. 7 | 8 | ```html 9 |
10 | 11 | 12 | 13 | 14 | 50 | ``` 51 | 52 | ## Debugging 53 | 54 | If you would like readable source files for debugging, change the file reference to the `-debug.js` files inside `dist-web/debug` directory. These files should only be used for development as they are over 10 times as large as the minified versions, and importing the debug versions will increase loading times for the end user. 55 | 56 | ## IE11 and Edge Support 57 | If you need to support IE11 or Edge you will also need to install a text-encoding polyfill as eosjs Signing is dependent on the TextEncoder which IE11 and Edge do not provide. Pass the TextEncoder and TextDecoder to the API constructor as demonstrated in the [ES 2015 example](#node-es-2015). Refer to the documentation here https://github.com/inexorabletash/text-encoding to determine the best way to include it in your project. 58 | -------------------------------------------------------------------------------- /docs/4.-Reading blockchain-Examples.md: -------------------------------------------------------------------------------- 1 | # Reading blockchain 2 | 3 | Reading blockchain state only requires an instance of `JsonRpc` connected to a node. 4 | 5 | ```javascript 6 | const { JsonRpc } = require('eosjs'); 7 | const fetch = require('node-fetch'); // node only; not needed in browsers 8 | const rpc = new JsonRpc('http://localhost:8888', { fetch }); 9 | ``` 10 | 11 | ## Examples 12 | 13 | ### Get table rows 14 | 15 | Get the first 10 token balances of account _testacc_. 16 | 17 | ```javascript 18 | const resp = await rpc.get_table_rows({ 19 | json: true, // Get the response as json 20 | code: 'eosio.token', // Contract that we target 21 | scope: 'testacc', // Account that owns the data 22 | table: 'accounts', // Table name 23 | limit: 10, // Maximum number of rows that we want to get 24 | reverse: false, // Optional: Get reversed data 25 | show_payer: false, // Optional: Show ram payer 26 | }); 27 | 28 | console.log(resp.rows); 29 | ``` 30 | Output: 31 | 32 | ```json 33 | { 34 | "rows": [{ 35 | "balance": "100.0000 HAK" 36 | } 37 | ], 38 | "more": false 39 | } 40 | ``` 41 | 42 | ### Get one row by index 43 | 44 | ```javascript 45 | const resp = await rpc.get_table_rows({ 46 | json: true, // Get the response as json 47 | code: 'contract', // Contract that we target 48 | scope: 'contract', // Account that owns the data 49 | table: 'profiles', // Table name 50 | lower_bound: 'testacc', // Table primary key value 51 | limit: 1, // Here we limit to 1 to get only the 52 | reverse: false, // Optional: Get reversed data 53 | show_payer: false, // Optional: Show ram payer 54 | }); 55 | console.log(resp.rows); 56 | ``` 57 | Output: 58 | 59 | ```json 60 | { 61 | "rows": [{ 62 | "user": "testacc", 63 | "age": 21, 64 | "surname": "Martin" 65 | } 66 | ], 67 | "more": false 68 | } 69 | ``` 70 | 71 | ### Get one row by secondary index 72 | 73 | ```javascript 74 | const resp = await rpc.get_table_rows({ 75 | json: true, // Get the response as json 76 | code: 'contract', // Contract that we target 77 | scope: 'contract', // Account that owns the data 78 | table: 'profiles', // Table name 79 | table_key: 'age', // Table secondaray key name 80 | lower_bound: 21, // Table secondary key value 81 | limit: 1, // Here we limit to 1 to get only row 82 | reverse: false, // Optional: Get reversed data 83 | show_payer: false, // Optional: Show ram payer 84 | }); 85 | console.log(resp.rows); 86 | ``` 87 | Output: 88 | 89 | ```json 90 | { 91 | "rows": [{ 92 | "user": "testacc", 93 | "age": 21, 94 | "surname": "Martin" 95 | } 96 | ], 97 | "more": false 98 | } 99 | ``` 100 | 101 | ### Get currency balance 102 | 103 | ```javascript 104 | console.log(await rpc.get_currency_balance('eosio.token', 'testacc', 'HAK')); 105 | ``` 106 | Output: 107 | 108 | ```json 109 | [ "1000000000.0000 HAK" ] 110 | ``` 111 | 112 | ### Get account info 113 | 114 | ```javascript 115 | console.log(await rpc.get_account('testacc')); 116 | ``` 117 | Output: 118 | 119 | ```json 120 | { "account_name": "testacc", 121 | "head_block_num": 1079, 122 | "head_block_time": "2018-11-10T00:45:53.500", 123 | "privileged": false, 124 | "last_code_update": "1970-01-01T00:00:00.000", 125 | "created": "2018-11-10T00:37:05.000", 126 | "ram_quota": -1, 127 | "net_weight": -1, 128 | "cpu_weight": -1, 129 | "net_limit": { "used": -1, "available": -1, "max": -1 }, 130 | "cpu_limit": { "used": -1, "available": -1, "max": -1 }, 131 | "ram_usage": 2724, 132 | "permissions": 133 | [ { "perm_name": "active", "parent": "owner", "required_auth": [] }, 134 | { "perm_name": "owner", "parent": "", "required_auth": [] } ], 135 | "total_resources": null, 136 | "self_delegated_bandwidth": null, 137 | "refund_request": null, 138 | "voter_info": null } 139 | ``` 140 | 141 | ### Get block 142 | 143 | ```javascript 144 | console.log(await rpc.get_block(1)); 145 | ``` 146 | Output: 147 | 148 | ```json 149 | { "timestamp": "2018-06-01T12:00:00.000", 150 | "producer": "", 151 | "confirmed": 1, 152 | "previous": "0000000000000000000000000000000000000000000000000000000000000000", 153 | "transaction_mroot": "0000000000000000000000000000000000000000000000000000000000000000", 154 | "action_mroot": "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f", 155 | "schedule_version": 0, 156 | "new_producers": null, 157 | "header_extensions": [], 158 | "producer_signature": "SIG_K1_111111111111111111111111111111111111111111111111111111111111111116uk5ne", 159 | "transactions": [], 160 | "block_extensions": [], 161 | "id": "00000001bcf2f448225d099685f14da76803028926af04d2607eafcf609c265c", 162 | "block_num": 1, 163 | "ref_block_prefix": 2517196066 } 164 | ``` 165 | -------------------------------------------------------------------------------- /docs/5.-Testing and Building with DUNE.md: -------------------------------------------------------------------------------- 1 | # Testing and Building with DUNE 2 | 3 | DUNE makes it easier to test locally. Performing integration tests with DUNE requires some setup. 4 | [DUNE may be installed from git hub](https://github.com/eosnetworkfoundation/DUNE) 5 | 6 | ## Open Local Node Port 7 | 8 | Need to change **scripts/config.ini** from `http-server-address = 127.0.0.1:8888` to `http-server-address = 0.0.0.0:8888`. This will enable port 8888 to listen on all ports, and that is needed because docker runs on a different network. 9 | 10 | This is part of the docker image, so this must be completed before running `bootstrap`. If you already have a docker image you can 11 | * Destroy the docker container 12 | * Remove docker image 13 | * Re-run bootstrap 14 | 15 | An alternative option is to enter the docker container, change the configuration, and restart the node. 16 | 17 | ## DUNE Keys 18 | 19 | Once you follow the directions you need to grap the keys for the existing eosio account. 20 | 21 | ``` 22 | egrep 'priv_key|pub_key' src/dune/*.py 23 | ``` 24 | 25 | ## Start a Node 26 | 27 | Start a node if you haven't already 28 | ``` 29 | dune --start test_node 30 | ``` 31 | 32 | ## Create Wallet 33 | Start a Docker shell. Must be done locally due to permission problems with DUNE. 34 | ``` 35 | docker exec -it dune_container /bin/bash 36 | ``` 37 | Commands to make wallet 38 | ``` 39 | cleos wallet create -n bob -f jungle4-wallet/bob.wallet 40 | cleos wallet unlock -n bobtestlion1 --password $(cat jungle4-wallet/bob.wallet) 41 | ``` 42 | 43 | ## Create Accounts 44 | 45 | Now we can create our test accounts. In the examples below replace, **priv_key** and **pub_key** with the values from [DUNE Keys](#DUNE Keys) 46 | 47 | ``` 48 | dune --create-key 49 | dune --create-account bob eosio pub_key priv_key 50 | dune --create-key 51 | dune --create-account alice eosio pub_key priv_key 52 | ``` 53 | 54 | ## Add Private Key to Wallet 55 | 56 | Use bob's priv_key 57 | Note done locally 58 | ``` 59 | cleos wallet import -n bobtestlion1 --private-key priv_key 60 | ``` 61 | 62 | ## Test Transfer 63 | Note done locally 64 | ``` 65 | cleos transfer bob alice "0.001 EOS" "Hodl!" -p bob 66 | ``` 67 | 68 | ## Private Keys in Tests 69 | 70 | Look at `src/tests/node.js` and `src/tests/web.html` to make sure the private key matches DUNE's. 71 | 72 | ## Run Tests 73 | 74 | ``` 75 | npm run test node 76 | ``` 77 | 78 | If you want just the integration tests run. 79 | ```angular2html 80 | npm run test-node 81 | ``` 82 | -------------------------------------------------------------------------------- /docs/Testing ReadOnly.md: -------------------------------------------------------------------------------- 1 | The read only contract requires a special contract. You can find the source code under `src/tests/readonly_contract`. 2 | Once compiled the contracted is loaded via the command `cleos -u https://jungle4.cryptolions.io set contract hokieshokies ./ contract.wasm contract.abi` 3 | The action on `read-only` test will refer to `mycontract`, and with the contract loaded you will be able to run the test -------------------------------------------------------------------------------- /docs/design/Cryptography.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | Place holder for future notes on better design patterns. 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "enf-eosjs", 3 | "version": "23.0.0", 4 | "description": "JS API to talk to eos blockchain", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "cypress": "cypress run --spec 'cypress/integration/index.spec.js'", 8 | "cypress-ui": "cypress open", 9 | "prepare": "npm run build", 10 | "lint": "eslint --ext .js,.jsx,.ts,.tsx src", 11 | "test": "jest src/tests/*eosjs*", 12 | "test-serialization": "jest src/tests/serialization.test.ts", 13 | "test-node": "jest src/tests/node.test.ts", 14 | "test-all": "npm run test && npm run test-node && npm run test-serialization && npm run cypress", 15 | "build": "tsc -p ./tsconfig.json && cp src/ripemd.es5.js dist/ripemd.js", 16 | "build-web": "webpack --config webpack.prod.js && webpack --config webpack.debug.js", 17 | "build-production": "npm run build && npm run build-web && npm run test-all", 18 | "clean": "rm -rf dist", 19 | "docs-init": "sh .docs/scripts/init.sh", 20 | "docs-build": "sh .docs/scripts/build.sh", 21 | "docs-serve": "python -m SimpleHTTPServer", 22 | "docs-publish": "sh .docs/scripts/publish.sh" 23 | }, 24 | "author": "eosnetworkfoundation", 25 | "license": "MIT", 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/eosnetworkfoundation/mandel-eosjs" 29 | }, 30 | "dependencies": { 31 | "bn.js": "5.2.0", 32 | "elliptic": "6.5.4", 33 | "hash.js": "1.1.7", 34 | "node-fetch": "2.6.7" 35 | }, 36 | "devDependencies": { 37 | "@types/elliptic": "^6.4.13", 38 | "@types/jest": "^26.0.24", 39 | "@types/node-fetch": "^2.6.3", 40 | "@typescript-eslint/eslint-plugin": "^5.51.0", 41 | "@typescript-eslint/parser": "^5.51.0", 42 | "buffer": "^6.0.3", 43 | "cypress": "^7.7.0", 44 | "eslint": "^8.33.0", 45 | "eslint-config-prettier": "^8.6.0", 46 | "eslint-plugin-es-x": "^6.0.0", 47 | "eslint-plugin-prettier": "^4.2.1", 48 | "jest": "^26.6.3", 49 | "jest-extended": "^0.11.5", 50 | "jest-fetch-mock": "^3.0.3", 51 | "none": "^1.0.0", 52 | "prettier": "2.8.4", 53 | "text-encoding": "^0.7.0", 54 | "ts-jest": "^26.5.6", 55 | "ts-loader": "^9.4.3", 56 | "typedoc": "^0.24.6", 57 | "typedoc-plugin-markdown": "^3.15.2", 58 | "typescript": "^4.9.5", 59 | "webpack": "^5.44.0", 60 | "webpack-cli": "^5.1.3" 61 | }, 62 | "jest": { 63 | "automock": false, 64 | "setupFiles": [ 65 | "./src/tests/setupJest.js" 66 | ], 67 | "setupFilesAfterEnv": [ 68 | "jest-extended" 69 | ], 70 | "moduleFileExtensions": [ 71 | "ts", 72 | "tsx", 73 | "js" 74 | ], 75 | "transform": { 76 | "^.+\\.(tsx?)$": "ts-jest" 77 | }, 78 | "globals": { 79 | "ts-jest": { 80 | "tsconfig": "tsconfig.json" 81 | } 82 | }, 83 | "testRegex": "(/src/.*(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 84 | "testEnvironment": "node" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /scripts/is_latest.sh: -------------------------------------------------------------------------------- 1 | is_latest=false; 2 | 3 | current_commit="$(git rev-parse HEAD)"; 4 | tags="$(git tag --sort=-creatordate)"; 5 | 6 | IFS='\n' read -ra arry <<< "$tags" 7 | 8 | latest_tag="${arry[0]}" 9 | 10 | if [ "$latest_tag" == "" ]; then 11 | latest_tag="v0.0.0"; 12 | else 13 | tag_commit="$(git rev-list -n 1 ${latest_tag})"; 14 | if [ "$tag_commit" == "$current_commit" ]; then 15 | is_latest=true; 16 | fi 17 | fi 18 | 19 | echo "tag_commit: ${tag_commit}"; 20 | echo "current_commit: ${current_commit}"; 21 | echo "is_latest: ${is_latest}"; 22 | 23 | export TRAVIS_IS_LATEST_TAG="$is_latest" -------------------------------------------------------------------------------- /scripts/publish-edge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . "${TRAVIS_BUILD_DIR}/scripts/publish-utils.sh"; 4 | 5 | echo "Running on branch/tag ${TRAVIS_BRANCH}": 6 | 7 | echo "Setting up git" 8 | setup_git 9 | 10 | echo "Creating new version" 11 | git checkout -- . 12 | 13 | git status 14 | 15 | # get the short commit hash to include in the npm package 16 | current_commit="$(git rev-parse --short HEAD)"; 17 | 18 | npm version prerelease -preid "${current_commit}" -no-git-tag-version 19 | 20 | git commit -a -m "Updating version [skip ci]" 21 | 22 | echo "Publish to NPM" 23 | 24 | cp .npmrc.template $HOME/.npmrc 25 | 26 | npm publish --tag edge -------------------------------------------------------------------------------- /scripts/publish-tag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . "${TRAVIS_BUILD_DIR}/scripts/publish-utils.sh"; 4 | 5 | if [[ "$TRAVIS_TAG" == "" ]]; then 6 | echo "No tag specified, skipping..."; 7 | else 8 | echo "Running on branch/tag ${TRAVIS_TAG}": 9 | 10 | echo "Setting up git" 11 | setup_git 12 | 13 | echo "Creating new version" 14 | git checkout -- . 15 | 16 | git status 17 | 18 | npm version -no-git-tag-version $TRAVIS_TAG 19 | 20 | echo "Pushing to git" 21 | git commit -a -m "Publishing version ${TRAVIS_TAG} [skip ci]" 22 | 23 | git push origin HEAD:${1} 24 | 25 | echo "Build and Publish to NPM" 26 | 27 | cp .npmrc.template $HOME/.npmrc 28 | 29 | if [[ "$TRAVIS_TAG" == *"-beta"* ]]; then 30 | echo "Publishing with beta tag to npm" 31 | npm publish --tag beta 32 | else 33 | echo "Publishing with latest tag to npm" 34 | npm publish 35 | fi 36 | fi 37 | 38 | -------------------------------------------------------------------------------- /scripts/publish-utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | setup_git() { 4 | # Set the user name and email to match the API token holder 5 | # This will make sure the git commits will have the correct photo 6 | # and the user gets the credit for a checkin 7 | git config --global user.email "eric.passmore@gmail.com" 8 | git config --global user.name "ericpassmore" 9 | git config --global push.default matching 10 | 11 | # Get the credentials from a file 12 | git config credential.helper "store --file=.git/credentials" 13 | 14 | # This associates the API Key with the account 15 | echo "https://${GITHUB_API_KEY}:@github.com" > .git/credentials 16 | } -------------------------------------------------------------------------------- /scripts/run-cypress.sh: -------------------------------------------------------------------------------- 1 | RUNMODE=$1 2 | 3 | if [ "$RUNMODE" == "" ]; then 4 | RUNMODE="headless" 5 | fi 6 | 7 | if [ "$RUNMODE" == "ui" ]; then 8 | echo 9 | echo -e "\033[34mOpen Cypress UI...\033[0m" 10 | cypress open 11 | else 12 | { 13 | echo 14 | echo -e "\033[34mCypress run...\033[0m" 15 | cypress run --reporter mochawesome --spec 'cypress/integration/index.spec.js' 16 | } || { 17 | EXIT_CODE=1 18 | } 19 | fi 20 | 21 | exit $EXIT_CODE 22 | -------------------------------------------------------------------------------- /scripts/simple-publish.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | npm login 4 | npm publish -------------------------------------------------------------------------------- /src/ChainSemanticVersion.ts: -------------------------------------------------------------------------------- 1 | interface CleanedVersion { 2 | version: string 3 | hasReleaseCandidate: boolean 4 | parsingError: boolean 5 | } 6 | 7 | interface MajorMinorPatch { 8 | major: number 9 | minor: number 10 | patch?: number 11 | } 12 | 13 | export class ChainSemanticVersion { 14 | public semverString: CleanedVersion 15 | 16 | /** 17 | * 18 | * @param info is a version string, starts with 'v' and followed by semver seperated by '. Example 'v4.0.1' 19 | * 20 | */ 21 | constructor(info: string) { 22 | this.semverString = this.stripReleaseCandidate(this.stripLeadingV(info)) 23 | } 24 | 25 | public supportsLeap3Features(): boolean { 26 | const versionObject = this.getMajorMinorVersion() 27 | // must be major version 3 with minor version 1 or better 28 | // note v3.1.0-rc1 is a pre-v3.1.0 release and does not support 3.0 features 29 | return ( 30 | // better then 3 ok! 31 | versionObject.major > 3 || 32 | // version 3 must be version 1 or better 33 | (versionObject.major == 3 && 34 | ((versionObject.minor == 1 && !this.semverString.hasReleaseCandidate) 35 | || 36 | versionObject.minor > 1) 37 | ) 38 | ) 39 | } 40 | 41 | public supportsLeap4Features(): boolean { 42 | const versionObject = this.getMajorMinorVersion() 43 | // must be major version 4 with minor version 0 or better 44 | // note v4.0.0-rc1 is a pre-v4.0.0 release and does not support 4.0 features 45 | return ( 46 | // better then 4 ok! 47 | versionObject.major > 4 || 48 | (versionObject.major == 4 && versionObject.minor > 0) || 49 | // RC versions of v4.0.0 will not work. RC version of other version will work 50 | // Treat patch level undefined as patch level 0 51 | (versionObject.major == 4 && 52 | !( 53 | versionObject.minor == 0 && 54 | (versionObject.patch == 0 || versionObject.patch == null) && 55 | this.semverString.hasReleaseCandidate 56 | )) 57 | ) 58 | } 59 | 60 | private stripLeadingV(info: string): string { 61 | if (info.startsWith('v')) { 62 | return info.slice(1) 63 | } else { 64 | return info 65 | } 66 | } 67 | 68 | private stripReleaseCandidate(info: string): CleanedVersion { 69 | const versionString = info.split('-') 70 | if (versionString.length > 1) { 71 | return { 72 | version: versionString[0], 73 | hasReleaseCandidate: true, 74 | parsingError: false, 75 | } 76 | } 77 | return { 78 | version: info, 79 | hasReleaseCandidate: false, 80 | parsingError: false, 81 | } 82 | } 83 | 84 | private getMajorMinorVersion(): MajorMinorPatch { 85 | const semVersions = this.semverString.version.split('.') 86 | // expect at least major and minor version 87 | if (semVersions.length < 2) { 88 | this.semverString.parsingError = true 89 | return {major: 0, minor: 0} 90 | } 91 | // expect a number 92 | if (isNaN(parseInt(semVersions[0])) || isNaN(parseInt(semVersions[1]))) { 93 | this.semverString.parsingError = true 94 | return {major: 0, minor: 0} 95 | } 96 | let patch = undefined 97 | if (semVersions.length > 2 && !isNaN(parseInt(semVersions[2]))) { 98 | patch = parseInt(semVersions[2]) 99 | } 100 | return {major: parseInt(semVersions[0]), minor: parseInt(semVersions[1]), patch: patch} 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/PrivateKey.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 EOS Network Foundation (ENF) and its contributors. All rights reserved. 3 | * Copyright (c) 2017-2020 block.one and its contributors. All rights reserved. 4 | * MIT License 5 | * Oct 12, 2022 sourced from https://github.com/EOSIO/eosjs/archive/refs/tags/v22.1.0.zip 6 | */ 7 | 8 | import { BNInput, ec as EC } from 'elliptic'; 9 | import { 10 | Key, 11 | KeyType, 12 | privateKeyToLegacyString, 13 | privateKeyToString, 14 | stringToPrivateKey, 15 | } from './eosjs-numeric'; 16 | import { constructElliptic, PublicKey, Signature } from './eosjs-key-conversions'; 17 | 18 | /** Represents/stores a private key and provides easy conversion for use with `elliptic` lib */ 19 | export class PrivateKey { 20 | constructor(private key: Key, private ec: EC) {} 21 | 22 | /** Instantiate private key from an `elliptic`-format private key */ 23 | public static fromElliptic(privKey: EC.KeyPair, keyType: KeyType, ec?: EC): PrivateKey { 24 | if (!ec) { 25 | ec = constructElliptic(keyType); 26 | } 27 | return new PrivateKey({ 28 | type: keyType, 29 | data: privKey.getPrivate().toArrayLike(Buffer, 'be', 32), 30 | }, ec); 31 | } 32 | 33 | /** Instantiate private key from an EOS-format private key */ 34 | public static fromString(keyString: string, ec?: EC): PrivateKey { 35 | const privateKey = stringToPrivateKey(keyString); 36 | if (!ec) { 37 | ec = constructElliptic(privateKey.type); 38 | } 39 | return new PrivateKey(privateKey, ec); 40 | } 41 | 42 | /** Export private key as `elliptic`-format private key */ 43 | public toElliptic(): EC.KeyPair { 44 | return this.ec.keyFromPrivate(this.key.data); 45 | } 46 | 47 | public toLegacyString(): string { 48 | return privateKeyToLegacyString(this.key); 49 | } 50 | 51 | /** Export private key as EOS-format private key */ 52 | public toString(): string { 53 | return privateKeyToString(this.key); 54 | } 55 | 56 | /** Get key type from key */ 57 | public getType(): KeyType { 58 | return this.key.type; 59 | } 60 | 61 | /** Retrieve the public key from a private key */ 62 | public getPublicKey(): PublicKey { 63 | const ellipticPrivateKey = this.toElliptic(); 64 | return PublicKey.fromElliptic(ellipticPrivateKey, this.getType(), this.ec); 65 | } 66 | 67 | /** Sign a message or hashed message digest with private key */ 68 | public sign(data: BNInput, shouldHash: boolean = true, encoding: BufferEncoding = 'utf8'): Signature { 69 | if (shouldHash) { 70 | if (typeof data === 'string') { 71 | data = Buffer.from(data, encoding); 72 | } 73 | data = this.ec.hash().update(data).digest(); 74 | } 75 | let tries = 0; 76 | let signature: Signature; 77 | const isCanonical = (sigData: Uint8Array): boolean => 78 | !(sigData[1] & 0x80) && !(sigData[1] === 0 && !(sigData[2] & 0x80)) 79 | && !(sigData[33] & 0x80) && !(sigData[33] === 0 && !(sigData[34] & 0x80)); 80 | const constructSignature = (options: EC.SignOptions): Signature => { 81 | const ellipticPrivateKey = this.toElliptic(); 82 | const ellipticSignature = ellipticPrivateKey.sign(data, options); 83 | return Signature.fromElliptic(ellipticSignature, this.getType(), this.ec); 84 | }; 85 | 86 | if (this.key.type === KeyType.k1) { 87 | do { 88 | signature = constructSignature({canonical: true, pers: [++tries]}); 89 | } while (!isCanonical(signature.toBinary())); 90 | } else { 91 | signature = constructSignature({canonical: true}); 92 | } 93 | return signature; 94 | } 95 | 96 | /** Validate a private key */ 97 | public isValid(): boolean { 98 | try { 99 | const ellipticPrivateKey = this.toElliptic(); 100 | const validationObj = ellipticPrivateKey.validate(); 101 | return validationObj.result; 102 | } catch { 103 | return false; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/PublicKey.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 EOS Network Foundation (ENF) and its contributors. All rights reserved. 3 | * Copyright (c) 2017-2020 block.one and its contributors. All rights reserved. 4 | * MIT License 5 | * Oct 12, 2022 sourced from https://github.com/EOSIO/eosjs/archive/refs/tags/v22.1.0.zip 6 | */ 7 | 8 | import { ec as EC } from 'elliptic'; 9 | import { 10 | Key, 11 | KeyType, 12 | publicKeyToLegacyString, 13 | publicKeyToString, 14 | stringToPublicKey, 15 | } from './eosjs-numeric'; 16 | import { constructElliptic } from './eosjs-key-conversions'; 17 | 18 | /** Represents/stores a public key and provides easy conversion for use with `elliptic` lib */ 19 | export class PublicKey { 20 | constructor(private key: Key, private ec: EC) {} 21 | 22 | /** Instantiate public key from an EOS-format public key */ 23 | public static fromString(publicKeyStr: string, ec?: EC): PublicKey { 24 | const key = stringToPublicKey(publicKeyStr); 25 | if (!ec) { 26 | ec = constructElliptic(key.type); 27 | } 28 | return new PublicKey(key, ec); 29 | } 30 | 31 | /** Instantiate public key from an `elliptic`-format public key */ 32 | public static fromElliptic(publicKey: EC.KeyPair, keyType: KeyType, ec?: EC): PublicKey { 33 | const x = publicKey.getPublic().getX().toArray('be', 32); 34 | const y = publicKey.getPublic().getY().toArray('be', 32); 35 | if (!ec) { 36 | ec = constructElliptic(keyType); 37 | } 38 | return new PublicKey({ 39 | type: keyType, 40 | data: new Uint8Array([(y[31] & 1) ? 3 : 2].concat(x)), 41 | }, ec); 42 | } 43 | 44 | /** Export public key as EOSIO-format public key */ 45 | public toString(): string { 46 | return publicKeyToString(this.key); 47 | } 48 | 49 | /** Export public key as Legacy EOS-format public key */ 50 | public toLegacyString(): string { 51 | return publicKeyToLegacyString(this.key); 52 | } 53 | 54 | /** Export public key as `elliptic`-format public key */ 55 | public toElliptic(): EC.KeyPair { 56 | return this.ec.keyPair({ 57 | pub: Buffer.from(this.key.data), 58 | }); 59 | } 60 | 61 | /** Get key type from key */ 62 | public getType(): KeyType { 63 | return this.key.type; 64 | } 65 | 66 | /** Validate a public key */ 67 | public isValid(): boolean { 68 | try { 69 | const ellipticPublicKey = this.toElliptic(); 70 | const validationObj = ellipticPublicKey.validate(); 71 | return validationObj.result; 72 | } catch { 73 | return false; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Signature.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 EOS Network Foundation (ENF) and its contributors. All rights reserved. 3 | * Copyright (c) 2017-2020 block.one and its contributors. All rights reserved. 4 | * MIT License 5 | * Oct 12, 2022 sourced from https://github.com/EOSIO/eosjs/archive/refs/tags/v22.1.0.zip 6 | */ 7 | 8 | import { BNInput, ec as EC } from 'elliptic'; 9 | import BN = require('bn.js'); 10 | 11 | import { 12 | Key, 13 | KeyType, 14 | signatureToString, 15 | stringToSignature, 16 | } from './eosjs-numeric'; 17 | import { constructElliptic, PublicKey } from './eosjs-key-conversions'; 18 | 19 | /** Represents/stores a Signature and provides easy conversion for use with `elliptic` lib */ 20 | export class Signature { 21 | constructor(private signature: Key, private ec: EC) {} 22 | 23 | /** Instantiate Signature from an EOS-format Signature */ 24 | public static fromString(sig: string, ec?: EC): Signature { 25 | const signature = stringToSignature(sig); 26 | if (!ec) { 27 | ec = constructElliptic(signature.type); 28 | } 29 | return new Signature(signature, ec); 30 | } 31 | 32 | /** Instantiate Signature from an `elliptic`-format Signature */ 33 | public static fromElliptic(ellipticSig: EC.Signature, keyType: KeyType, ec?: EC): Signature { 34 | const r = ellipticSig.r.toArray('be', 32); 35 | const s = ellipticSig.s.toArray('be', 32); 36 | let eosioRecoveryParam; 37 | if (keyType === KeyType.k1 || keyType === KeyType.r1) { 38 | eosioRecoveryParam = ellipticSig.recoveryParam + 27; 39 | if (ellipticSig.recoveryParam <= 3) { 40 | eosioRecoveryParam += 4; 41 | } 42 | } else if (keyType === KeyType.wa) { 43 | eosioRecoveryParam = ellipticSig.recoveryParam; 44 | } 45 | const sigData = new Uint8Array([eosioRecoveryParam].concat(r, s)); 46 | if (!ec) { 47 | ec = constructElliptic(keyType); 48 | } 49 | return new Signature({ 50 | type: keyType, 51 | data: sigData, 52 | }, ec); 53 | } 54 | 55 | /** Export Signature as `elliptic`-format Signature 56 | * NOTE: This isn't an actual elliptic-format Signature, as ec.Signature is not exported by the library. 57 | * That's also why the return type is `any`. We're *actually* returning an object with the 3 params 58 | * not an ec.Signature. 59 | * Further NOTE: @types/elliptic shows ec.Signature as exported; it is *not*. Hence the `any`. 60 | */ 61 | public toElliptic(): any { 62 | const lengthOfR = 32; 63 | const lengthOfS = 32; 64 | const r = new BN(this.signature.data.slice(1, lengthOfR + 1)); 65 | const s = new BN(this.signature.data.slice(lengthOfR + 1, lengthOfR + lengthOfS + 1)); 66 | 67 | let ellipticRecoveryBitField; 68 | if (this.signature.type === KeyType.k1 || this.signature.type === KeyType.r1) { 69 | ellipticRecoveryBitField = this.signature.data[0] - 27; 70 | if (ellipticRecoveryBitField > 3) { 71 | ellipticRecoveryBitField -= 4; 72 | } 73 | } else if (this.signature.type === KeyType.wa) { 74 | ellipticRecoveryBitField = this.signature.data[0]; 75 | } 76 | const recoveryParam = ellipticRecoveryBitField & 3; 77 | return { r, s, recoveryParam }; 78 | } 79 | 80 | /** Export Signature as EOSIO-format Signature */ 81 | public toString(): string { 82 | return signatureToString(this.signature); 83 | } 84 | 85 | /** Export Signature in binary format */ 86 | public toBinary(): Uint8Array { 87 | return this.signature.data; 88 | } 89 | 90 | /** Get key type from signature */ 91 | public getType(): KeyType { 92 | return this.signature.type; 93 | } 94 | 95 | /** Verify a signature with a message or hashed message digest and public key */ 96 | public verify(data: BNInput, publicKey: PublicKey, shouldHash: boolean = true, encoding: BufferEncoding = 'utf8'): boolean { 97 | if (shouldHash) { 98 | if (typeof data === 'string') { 99 | data = Buffer.from(data, encoding); 100 | } 101 | data = this.ec.hash().update(data).digest(); 102 | } 103 | const ellipticSignature = this.toElliptic(); 104 | const ellipticPublicKey = publicKey.toElliptic(); 105 | return this.ec.verify(data, ellipticSignature, ellipticPublicKey, encoding); 106 | } 107 | 108 | /** Recover a public key from a message or hashed message digest and signature */ 109 | public recover(data: BNInput, shouldHash: boolean = true, encoding: BufferEncoding = 'utf8'): PublicKey { 110 | if (shouldHash) { 111 | if (typeof data === 'string') { 112 | data = Buffer.from(data, encoding); 113 | } 114 | data = this.ec.hash().update(data).digest(); 115 | } 116 | const ellipticSignature = this.toElliptic(); 117 | const recoveredPublicKey = this.ec.recoverPubKey( 118 | data, 119 | ellipticSignature, 120 | ellipticSignature.recoveryParam, 121 | encoding 122 | ); 123 | const ellipticKPub = this.ec.keyFromPublic(recoveredPublicKey); 124 | return PublicKey.fromElliptic(ellipticKPub, this.getType(), this.ec); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/abi.abi.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "eosio::abi/1.1", 3 | "structs": [ 4 | { 5 | "name": "extensions_entry", 6 | "base": "", 7 | "fields": [ 8 | { 9 | "name": "tag", 10 | "type": "uint16" 11 | }, 12 | { 13 | "name": "value", 14 | "type": "bytes" 15 | } 16 | ] 17 | }, 18 | { 19 | "name": "type_def", 20 | "base": "", 21 | "fields": [ 22 | { 23 | "name": "new_type_name", 24 | "type": "string" 25 | }, 26 | { 27 | "name": "type", 28 | "type": "string" 29 | } 30 | ] 31 | }, 32 | { 33 | "name": "field_def", 34 | "base": "", 35 | "fields": [ 36 | { 37 | "name": "name", 38 | "type": "string" 39 | }, 40 | { 41 | "name": "type", 42 | "type": "string" 43 | } 44 | ] 45 | }, 46 | { 47 | "name": "struct_def", 48 | "base": "", 49 | "fields": [ 50 | { 51 | "name": "name", 52 | "type": "string" 53 | }, 54 | { 55 | "name": "base", 56 | "type": "string" 57 | }, 58 | { 59 | "name": "fields", 60 | "type": "field_def[]" 61 | } 62 | ] 63 | }, 64 | { 65 | "name": "action_def", 66 | "base": "", 67 | "fields": [ 68 | { 69 | "name": "name", 70 | "type": "name" 71 | }, 72 | { 73 | "name": "type", 74 | "type": "string" 75 | }, 76 | { 77 | "name": "ricardian_contract", 78 | "type": "string" 79 | } 80 | ] 81 | }, 82 | { 83 | "name": "table_def", 84 | "base": "", 85 | "fields": [ 86 | { 87 | "name": "name", 88 | "type": "name" 89 | }, 90 | { 91 | "name": "index_type", 92 | "type": "string" 93 | }, 94 | { 95 | "name": "key_names", 96 | "type": "string[]" 97 | }, 98 | { 99 | "name": "key_types", 100 | "type": "string[]" 101 | }, 102 | { 103 | "name": "type", 104 | "type": "string" 105 | } 106 | ] 107 | }, 108 | { 109 | "name": "clause_pair", 110 | "base": "", 111 | "fields": [ 112 | { 113 | "name": "id", 114 | "type": "string" 115 | }, 116 | { 117 | "name": "body", 118 | "type": "string" 119 | } 120 | ] 121 | }, 122 | { 123 | "name": "error_message", 124 | "base": "", 125 | "fields": [ 126 | { 127 | "name": "error_code", 128 | "type": "uint64" 129 | }, 130 | { 131 | "name": "error_msg", 132 | "type": "string" 133 | } 134 | ] 135 | }, 136 | { 137 | "name": "variant_def", 138 | "base": "", 139 | "fields": [ 140 | { 141 | "name": "name", 142 | "type": "string" 143 | }, 144 | { 145 | "name": "types", 146 | "type": "string[]" 147 | } 148 | ] 149 | }, 150 | { 151 | "name": "abi_def", 152 | "base": "", 153 | "fields": [ 154 | { 155 | "name": "version", 156 | "type": "string" 157 | }, 158 | { 159 | "name": "types", 160 | "type": "type_def[]" 161 | }, 162 | { 163 | "name": "structs", 164 | "type": "struct_def[]" 165 | }, 166 | { 167 | "name": "actions", 168 | "type": "action_def[]" 169 | }, 170 | { 171 | "name": "tables", 172 | "type": "table_def[]" 173 | }, 174 | { 175 | "name": "ricardian_clauses", 176 | "type": "clause_pair[]" 177 | }, 178 | { 179 | "name": "error_messages", 180 | "type": "error_message[]" 181 | }, 182 | { 183 | "name": "abi_extensions", 184 | "type": "extensions_entry[]" 185 | }, 186 | { 187 | "name": "variants", 188 | "type": "variant_def[]$" 189 | } 190 | ] 191 | } 192 | ] 193 | } 194 | -------------------------------------------------------------------------------- /src/eosjs-api-interfaces.ts: -------------------------------------------------------------------------------- 1 | // copyright defined in eosjs/LICENSE.txt 2 | 3 | import { Abi, PushTransactionArgs } from './eosjs-rpc-interfaces'; 4 | 5 | /** Arguments to `getRequiredKeys` */ 6 | export interface AuthorityProviderArgs { 7 | /** Transaction that needs to be signed */ 8 | transaction: any; 9 | 10 | /** Public keys associated with the private keys that the `SignatureProvider` holds */ 11 | availableKeys: string[]; 12 | } 13 | 14 | /** Get subset of `availableKeys` needed to meet authorities in `transaction` */ 15 | export interface AuthorityProvider { 16 | /** Get subset of `availableKeys` needed to meet authorities in `transaction` */ 17 | getRequiredKeys: (args: AuthorityProviderArgs) => Promise