Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #451 from EOSIO/beta3-prep
Browse files Browse the repository at this point in the history
Beta3 prep
  • Loading branch information
c0d3ster authored Dec 11, 2018
2 parents 8b096ed + a64c59d commit 73152ad
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 839 deletions.
46 changes: 24 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,42 @@ Documentation can be found [here](https://eosio.github.io/eosjs)

## Installation

### NodeJS
### NodeJS Dependency

`npm install eosjs@beta`
`npm install eosjs@beta` or `yarn add eosjs@beta`

## Basic Usage
### Browser Distribution

Clone this repository locally then run `npm run build-web` or `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/static/3.-Browsers.html).

### Browser
## Import

### ES Modules

Importing using ES6 module syntax in the browser is supported if you have a transpiler, such as Babel.
```js
import { Api, JsonRpc, RpcError } from 'eosjs';

// If using default signature provider
import JsSignatureProvider from 'eosjs/dist/eosjs-jssig'
import JsSignatureProvider from 'eosjs/dist/eosjs-jssig';
```

### NodeJS
### CommonJS

Importing using commonJS syntax is supported by node out of the box.
Importing using commonJS syntax is supported by NodeJS out of the box.
```js
const { Api, JsonRpc, RpcError } = require('eosjs');
const JsSignatureProvider = require('eosjs/dist/eosjs-jssig');
const fetch = require('node-fetch'); // node only; not needed in browsers
const { TextDecoder, TextEncoder } = require('text-encoding'); // IE11 and IE Edge Browsers only
const {TextEncoder,TextDecoder} = require('util') // node only; native TextEncoder/Decoder
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

### SignatureProvider

SignatureProvider holds private keys and is responsible for signing transactions.
The SignatureProvider holds private keys and is responsible for signing transactions.

***Using the default 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***

Expand All @@ -52,10 +58,10 @@ const signatureProvider = new JsSignatureProvider([defaultPrivateKey]);

Open a connection to JSON-RPC, include `fetch` when on NodeJS.
```js
const rpc = new JsonRpc('http://127.0.0.1:8000', { fetch });
const rpc = new JsonRpc('http://127.0.0.1:8888', { fetch });
```

### API Constructor
### API

Include textDecoder and textEncoder when using in browser.
```js
Expand All @@ -64,6 +70,8 @@ const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), te

### 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.

```js
(async () => {
const result = await api.transact({
Expand Down Expand Up @@ -105,16 +113,10 @@ try {
...
```
## Browsers
After running `npm run build-web` or `yarn build-web`, the browser distribution will be located in `dist`. For full browser usage examples, [see the documentation](https://eosio.github.io/eosjs/static/3.-Browsers.html).
## How it works
`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.
## Running Tests
### Automated Test Suite
### Automated Unit Test Suite
`npm run test` or `yarn test`
### Web Integration Test Suite
Run `npm run build-web` to build the browser distrubution then open `src/tests/web.html` in the browser of your choice. The file should run through 6 tests, relaying the results onto the webpage with a 2 second delay after each test. The final 2 tests should relay the exceptions being thrown onto the webpage for an invalid transaction and invalid rpc call.
5 changes: 3 additions & 2 deletions docs/2.-Transaction-Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ To be able to send transactions and trigger actions on the blockchain, you must
The signature provider must contains the private keys corresponsing to the actors and permissions of the actions.

```javascript
const { Api, JsonRpc, JsSignatureProvider } = require('eosjs');
const { Api, JsonRpc } = require('eosjs');
const JsSignatureProvider = require('eosjs/dist/eosjs-jssig');
const fetch = require('node-fetch'); // node only; not needed in browsers
const { TextDecoder, TextEncoder } = require('text-encoding'); // node, IE11 and IE Edge Browsers

const privateKeys = [privateKey1];

const signatureProvider = new JsSignatureProvider(privateKeys);
const rpc = new JsonRpc('http://127.0.0.1:8000', { fetch });
const rpc = new JsonRpc('http://127.0.0.1:8888', { fetch });
const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });

```
Expand Down
13 changes: 8 additions & 5 deletions docs/3.-Browsers.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ Reuse the `api` object for all transactions; it caches ABIs to reduce network us
```html
<pre style="width: 100%; height: 100%; margin:0px; "></pre>

<script src='dist-web/eosjs-api-debug.js'></script>
<script src='dist-web/eosjs-jsonrpc-debug.js'></script>
<script src='dist-web/eosjs-rpcerror-debug.js'></script>
<script src='dist-web/eosjs-jssig-debug.js'></script>
<script src='dist-web/eosjs-api.js'></script>
<script src='dist-web/eosjs-jsonrpc.js'></script>
<script src='dist-web/eosjs-jssig.js'></script>
<script>
let pre = document.getElementsByTagName('pre')[0];
const defaultPrivateKey = "5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr"; // useraaaaaaaa
Expand Down Expand Up @@ -43,12 +42,16 @@ Reuse the `api` object for all transactions; it caches ABIs to reduce network us
pre.textContent += '\n\nTransaction pushed!\n\n' + JSON.stringify(result, null, 2);
} catch (e) {
pre.textContent = '\nCaught exception: ' + e;
if (e instanceof eosjs_rpcerror.default)
if (e instanceof eosjs_jsonrpc.RpcError)
pre.textContent += '\n\n' + JSON.stringify(e.json, null, 2);
}
})();
</script>
```

## Debugging

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.

## IE11 and Edge Support
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.
4 changes: 2 additions & 2 deletions docs/4.-Reading blockchain-Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
Reading blockchain state only requires an instance of `JsonRpc` connected to a node.

```javascript
const {JsonRpc } = require('eosjs');
const { JsonRpc } = require('eosjs');
const fetch = require('node-fetch'); // node only; not needed in browsers
const rpc = new JsonRpc('http://127.0.0.1:8000', { fetch });
const rpc = new JsonRpc('http://127.0.0.1:8888', { fetch });
```

## Examples
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eosjs",
"version": "20.0.0-beta2",
"version": "20.0.0-beta3",
"description": "Talk to eos API",
"main": "dist/index.js",
"scripts": {
Expand All @@ -9,7 +9,7 @@
"lint": "tslint -c tslint.json src/**/*.ts",
"lint-fix": "tslint -c tslint.json src/**/*.ts --fix",
"build": "tsc -p ./tsconfig.json && cp src/ripemd.es5.js dist/ripemd.js",
"build-web": "webpack",
"build-web": "webpack --config webpack.prod.js && webpack --config webpack.debug.js",
"clean": "rm -rf dist",
"docs-init": "sh .docs/scripts/init.sh",
"docs-build": "sh .docs/scripts/build.sh",
Expand All @@ -23,13 +23,14 @@
"url": "https://github.com/EOSIO/eosjs.git"
},
"dependencies": {
"@types/jest": "^23.3.1",
"babel-runtime": "^6.26.0",
"eosjs-ecc": "^4.0.1",
"text-encoding": "^0.6.4"
},
"devDependencies": {
"@types/jest": "^23.3.1",
"@types/node": "^10.3.1",
"@types/text-encoding": "^0.0.35",
"babel-cli": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
Expand Down Expand Up @@ -60,7 +61,7 @@
},
"globals": {
"ts-jest": {
"tsConfigFile": "tsconfig.json"
"tsConfig": "tsconfig.json"
}
},
"testRegex": "(/src/.*(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
Expand Down
2 changes: 1 addition & 1 deletion src/eosjs-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default class Api {
* * `signatureProvider`: Signs transactions
* * `chainId`: Identifies chain
* * `textEncoder`: `TextEncoder` instance to use. Pass in `null` if running in a browser
* * `textDecoder`: `TextDecider` instance to use. Pass in `null` if running in a browser
* * `textDecoder`: `TextDecoder` instance to use. Pass in `null` if running in a browser
*/
constructor(args: {
rpc: JsonRpc,
Expand Down
4 changes: 4 additions & 0 deletions src/rpc-web.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import JsonRpc from "./eosjs-jsonrpc";
import RpcError from "./eosjs-rpcerror";

export { JsonRpc as default, RpcError };
151 changes: 151 additions & 0 deletions src/tests/web.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<pre style='width: 100%; height: 100%; margin:0px; '></pre>

<script src='../../dist-web/eosjs-api-debug.js'></script>
<script src='../../dist-web/eosjs-jsonrpc-debug.js'></script>
<script src='../../dist-web/eosjs-jssig-debug.js'></script>
<script>
let pre = document.getElementsByTagName('pre')[0];
const defaultPrivateKey = '5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr'; // useraaaaaaaa

const rpc = new eosjs_jsonrpc.default('http://localhost:8888');
const signatureProvider = new eosjs_jssig.default([defaultPrivateKey]);
const api = new eosjs_api.default({ rpc, signatureProvider });

function waitTwoSeconds() {
return new Promise(resolve => setTimeout(resolve, 2000));
}

(async () => {
try {
const resultWithConfig = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'useraaaaaaaa',
permission: 'active',
}],
data: {
from: 'useraaaaaaaa',
to: 'useraaaaaaab',
quantity: '0.0001 SYS',
memo: '',
},
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});
pre.textContent += '\n\nTransaction with configured TAPOS pushed!\n\n' + JSON.stringify(resultWithConfig, null, 2);
await waitTwoSeconds(); // run additional tests after 2 second delay

const resultWithoutBroadcast = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'useraaaaaaaa',
permission: 'active',
}],
data: {
from: 'useraaaaaaaa',
to: 'useraaaaaaab',
quantity: '0.0001 SYS',
memo: '',
},
}]
}, {
broadcast: false,
blocksBehind: 3,
expireSeconds: 30,
});
pre.textContent = '\n\nTransaction serialized and signed but not pushed!\n\n' + JSON.stringify(resultWithoutBroadcast, null, 2);
await waitTwoSeconds();

const broadcastResult = await api.pushSignedTransaction(resultWithoutBroadcast);
pre.textContent = '\n\nSerialized Transaction and signatures pushed!\n\n' + JSON.stringify(broadcastResult, null, 2);
await waitTwoSeconds();

const blockInfo = await rpc.get_block(broadcastResult.processed.block_num)
const currentDate = new Date();
const timePlusTen = currentDate.getTime() + 10000;
const timeInISOString = (new Date(timePlusTen)).toISOString();
const expiration = timeInISOString.substr(0, timeInISOString.length - 1);

const resultWithoutConfig = await api.transact({
expiration,
ref_block_num: blockInfo.block_num & 0xffff,
ref_block_prefix: blockInfo.ref_block_prefix,
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'useraaaaaaaa',
permission: 'active',
}],
data: {
from: 'useraaaaaaaa',
to: 'useraaaaaaab',
quantity: '0.0001 SYS',
memo: '',
},
}]
});
pre.textContent = '\n\nTransaction with manual TAPOS pushed!\n\n' + JSON.stringify(resultWithoutConfig, null, 2);
}
catch(e) {
throw new Error('Web Integration Test Failed Unexpectedly: ' + e.message)
}
await waitTwoSeconds();

let failedAsPlanned;
try {
failedAsPlanned = true;
const resultShouldFail = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'useraaaaaaaa',
permission: 'active',
}],
data: {
from: 'useraaaaaaaa',
to: 'useraaaaaaab',
quantity: '0.0001 SYS',
memo: '',
},
}]
});
failedAsPlanned = false;
} catch (e) {
if (e.message == 'Required configuration or TAPOS fields are not present') {
pre.textContent = '\n\nCaught Exception successfully: \n\n' + e;
}
else { failedAsPlanned = false }
}
if (!failedAsPlanned) {
throw new Error('The final transact call (lacking TAPoS and config) did not fail as expected');
}
await waitTwoSeconds();

try {
failedAsPlanned = true;
const invalidRpcCall = await rpc.get_block(-1);
failedAsPlanned = false;
}
catch(e) {
if (e instanceof eosjs_jsonrpc.RpcError) {
pre.textContent = '\n\nCaught RpcError successfully: \n\n' + JSON.stringify(e.json, null, 2);
}
else {
failedAsPlanned = false;
}
}
if (!failedAsPlanned) {
throw new Error('An rpc error is not being thrown for invalid rpc calls');
}
await waitTwoSeconds();

})();
</script>
24 changes: 24 additions & 0 deletions tsconfig.web.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "es5",
"module": "CommonJS",
"outDir": "dist",
"alwaysStrict": true,
"sourceMap": false,
"noImplicitAny": true,
"moduleResolution": "node",
"declaration": false,
"downlevelIteration": true,
"lib": [
"es2017",
"dom"
]
},
"include": [
"src/*.ts",
"src/*.js"
],
"exclude": [
"src/*.test.ts"
]
}
Loading

0 comments on commit 73152ad

Please sign in to comment.