Move to lerna repo (#19)
* Pull api-* packages into lerna repo * Bootstrap with hoist * Update jest alias config * Add api-jsonrpc * Pull in jsonrpc * Update badges * Don't hoist, use workspaces * .eslintrc to root * Cleanups, build from root * Shorthand commands * Update to @polkadot/dev 0.9.1 * Update description
This commit is contained in:
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
**/build/*
|
||||
@@ -2,6 +2,7 @@
|
||||
.*/build/.*
|
||||
|
||||
[include]
|
||||
./node_modules/@polkadot/dev/flow-typed
|
||||
|
||||
[libs]
|
||||
|
||||
@@ -9,3 +10,7 @@
|
||||
esproposal.decorators=ignore
|
||||
module.ignore_non_literal_requires=true
|
||||
unsafe.enable_getters_and_setters=true
|
||||
module.name_mapper='^@polkadot/api-format\(.*\)$' -> '<PROJECT_ROOT>/packages/api-format/src\1'
|
||||
module.name_mapper='^@polkadot/api-jsonrpc\(.*\)$' -> '<PROJECT_ROOT>/packages/api-jsonrpc/src\1'
|
||||
module.name_mapper='^@polkadot/api-provider\(.*\)$' -> '<PROJECT_ROOT>/packages/api-provider/src\1'
|
||||
module.name_mapper='^@polkadot/jsonrpc\(.*\)$' -> '<PROJECT_ROOT>/packages/api-jsonrpc/src\1'
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,6 +7,7 @@ tmp/
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
lerna-debug.log*
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
22
.npmignore
22
.npmignore
@@ -1,21 +1 @@
|
||||
coverage
|
||||
scripts
|
||||
src
|
||||
test
|
||||
tmp
|
||||
.babelrc
|
||||
.coveralls.yml
|
||||
.editorconfig
|
||||
.eslintrc.json
|
||||
.flowconfig
|
||||
.gitignore
|
||||
.istanbul.yml
|
||||
.travis.yml
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ cache:
|
||||
directories:
|
||||
- node_modules
|
||||
before_install:
|
||||
- npm install -g yarn --cache-min 999999999
|
||||
- npm install --global yarn --cache-min 999999999
|
||||
- npm install --global lerna
|
||||
install:
|
||||
- yarn
|
||||
- yarn install
|
||||
- lerna bootstrap
|
||||
script:
|
||||
- yarn run polkadot-dev-build-travis
|
||||
- yarn polkadot-dev-build-travis
|
||||
|
||||
44
README.md
44
README.md
@@ -1,40 +1,22 @@
|
||||

|
||||
[](https://www.npmjs.com/package/@polkadot/api)
|
||||
[](https://travis-ci.org/polkadot-js/api)
|
||||
[](https://coveralls.io/github/polkadot-js/api?branch=master)
|
||||
[](https://greenkeeper.io/)
|
||||
[](https://david-dm.org/polkadot-js/api)
|
||||
[](https://david-dm.org/polkadot-js/api#info=devDependencies)
|
||||
|
||||
# @polkadot/api
|
||||
# @polkadot/client
|
||||
|
||||
Warning - currently this does not actually do all that much, it is an attempt to put into code some thoughts about how to maintain the endpoints. This library provides a clean wrapper around all the methods exposed by a Polkadot network client. Methods are auto-generated for the [JsonRPC interface definitions](https://github.com/polkadot-js/jsonrpc).
|
||||
This library provides a clean wrapper around all the methods exposed by a Polkadot network client.
|
||||
|
||||
## Usage
|
||||
It is split up into a number of internal packages -
|
||||
|
||||
Installation -
|
||||
- [@polkadot/api](packages/api/) The API library
|
||||
- [@polkadot/api-format](packages/api-format/) Input and output formatters
|
||||
- [@polkadot/api-jsonrpc](packages/api-jsonrpc/) Interface definitions for RPC
|
||||
- [@polkadot/api-provider](packages/api-provider/) Transport providers
|
||||
|
||||
```
|
||||
npm install --save @polkadot/api
|
||||
```
|
||||
## Contributing
|
||||
|
||||
Initialisation -
|
||||
|
||||
```js
|
||||
import Api from '@polkadot/api';
|
||||
import HttpProvider from '@polkadot/api-provider/http';
|
||||
|
||||
const provider = new HttpProvider('http://127.0.0.1:9933');
|
||||
const api = new Api(provider);
|
||||
```
|
||||
|
||||
Making calls -
|
||||
|
||||
```js
|
||||
api.chain
|
||||
.getHeader('0x1234567890')
|
||||
.then((header) => console.log(header))
|
||||
.catch((error) => console.error(error));
|
||||
```
|
||||
|
||||
## Available methods
|
||||
|
||||
For a list of currently exposed methods, see the [@polkadot/jsonrpc](https://github.com/polkadot-js/jsonrpc#readme) repository.
|
||||
- Make sure you have [Lerna](https://lernajs.io/) installed, `yarn install -g lerna`
|
||||
- Bootstrap the dependencies, `lerna bootstrap`
|
||||
- Make any changes in the relevant package, on master merges new versions will be published automatically
|
||||
|
||||
@@ -1 +1,9 @@
|
||||
module.exports = require('@polkadot/dev/jest.config');
|
||||
const config = require('@polkadot/dev/jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleNameMapper: {
|
||||
'@polkadot/api-format(.*)$': '<rootDir>/packages/api-format/src/$1',
|
||||
'@polkadot/api-jsonrpc(.*)$': '<rootDir>/packages/api-jsonrpc/src/$1',
|
||||
'@polkadot/api-provider(.*)$': '<rootDir>/packages/api-provider/src/$1'
|
||||
}
|
||||
});
|
||||
|
||||
14
lerna.json
Normal file
14
lerna.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"lerna": "2.5.1",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
"publish": {
|
||||
"allowBranch": "master"
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.5.0"
|
||||
}
|
||||
39
package.json
39
package.json
@@ -1,20 +1,13 @@
|
||||
{
|
||||
"name": "@polkadot/api",
|
||||
"version": "0.4.14",
|
||||
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"JsonRPC"
|
||||
],
|
||||
"name": "@polkadot/api-wrapper",
|
||||
"version": "0.5.0",
|
||||
"description": "Non-published, see packages/",
|
||||
"keywords": [],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"license": "ISC",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=6.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
"node": ">=8.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,18 +18,16 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api#readme",
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-babel",
|
||||
"check": "eslint src && flow check",
|
||||
"test": "jest --coverage src"
|
||||
"build": "yarn polkadot-dev-build-babel",
|
||||
"check": "yarn eslint packages && yarn flow check",
|
||||
"test": "yarn jest --coverage packages"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/dev": "^0.8.1"
|
||||
"@polkadot/dev": "^0.9.1",
|
||||
"lerna": "^2.5.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/api-format": "^0.3.7",
|
||||
"@polkadot/api-provider": "^0.1.6",
|
||||
"@polkadot/jsonrpc": "^0.3.9",
|
||||
"@polkadot/util": "^0.5.10",
|
||||
"babel-runtime": "^6.26.0"
|
||||
}
|
||||
"dependencies": {},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
]
|
||||
}
|
||||
|
||||
15
packages/api-format/LICENSE
Normal file
15
packages/api-format/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
||||
ISC License (ISC)
|
||||
|
||||
Copyright 2017 Jaco Greeff <jacogr@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
14
packages/api-format/README.md
Normal file
14
packages/api-format/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api-format)
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api-format#info=devDependencies)
|
||||
|
||||
# @polkadot/api-format
|
||||
|
||||
Formatters that are used by the application API interface, taking care of transparently formatting parameters (inputs) and the results (output) for requests made over the client RPC interfaces.
|
||||
|
||||
## Usage
|
||||
|
||||
Installation -
|
||||
|
||||
```
|
||||
npm install --save @polkadot/api-format
|
||||
```
|
||||
40
packages/api-format/package.json
Normal file
40
packages/api-format/package.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@polkadot/api-format",
|
||||
"version": "0.5.0",
|
||||
"description": "Input/Output formatters for JsonRPC exchange",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"JsonRPC"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=6.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/api/issues"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-format#readme",
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-babel",
|
||||
"check": "eslint src && flow check",
|
||||
"test": "echo \"Tests only available from root wrapper\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/api-jsonrpc": "^0.5.0",
|
||||
"@polkadot/dev": "^0.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util": "^0.5.15",
|
||||
"babel-runtime": "^6.26.0"
|
||||
}
|
||||
}
|
||||
10
packages/api-format/src/index.js
Normal file
10
packages/api-format/src/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
const formatInputs = require('./input');
|
||||
const formatOutput = require('./output');
|
||||
|
||||
module.exports = {
|
||||
formatInputs,
|
||||
formatOutput
|
||||
};
|
||||
10
packages/api-format/src/input/address.js
Normal file
10
packages/api-format/src/input/address.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
const { formatH160 } = require('./hex');
|
||||
|
||||
// TODO: Currently the format assumes 160-bit values (like Ethereum)
|
||||
// this will probably change along the way as things get firmed up
|
||||
module.exports = function format (value: ?string): string {
|
||||
return formatH160(value);
|
||||
};
|
||||
13
packages/api-format/src/input/address.spec.js
Normal file
13
packages/api-format/src/input/address.spec.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const format = require('./address');
|
||||
|
||||
describe('input/address', () => {
|
||||
describe('format', () => {
|
||||
it('pads to H160 value', () => {
|
||||
expect(
|
||||
format('0x1234567890')
|
||||
).toEqual('0x0000000000000000000000000000001234567890');
|
||||
});
|
||||
});
|
||||
});
|
||||
33
packages/api-format/src/input/hex.js
Normal file
33
packages/api-format/src/input/hex.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
const { hexAddPrefix, hexHasPrefix, hexStripPrefix } = require('@polkadot/util/hex');
|
||||
|
||||
const H64_ZERO: string = '00000000000000000000000000000000';
|
||||
const H128_ZERO: string = `${H64_ZERO}${H64_ZERO}`;
|
||||
const H256_ZERO: string = `${H128_ZERO}${H128_ZERO}`;
|
||||
// const H512_ZERO: string = `${H256_ZERO}${H256_ZERO}`;
|
||||
|
||||
function leftHexPad (value: ?string, bitLength: number): string {
|
||||
const length = 2 * bitLength / 8;
|
||||
|
||||
if (hexHasPrefix(value)) {
|
||||
value = hexStripPrefix(value);
|
||||
}
|
||||
|
||||
return hexAddPrefix(`${H256_ZERO}${value || ''}`.slice(-length));
|
||||
}
|
||||
|
||||
function formatH160 (value: ?string): string {
|
||||
return leftHexPad(value, 160);
|
||||
}
|
||||
|
||||
function formatH256 (value: ?string): string {
|
||||
return leftHexPad(value, 256);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
leftHexPad,
|
||||
formatH160,
|
||||
formatH256
|
||||
};
|
||||
53
packages/api-format/src/input/hex.spec.js
Normal file
53
packages/api-format/src/input/hex.spec.js
Normal file
@@ -0,0 +1,53 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const { leftHexPad, formatH160, formatH256 } = require('./hex');
|
||||
|
||||
describe('input/hex', () => {
|
||||
describe('leftHexPad', () => {
|
||||
it('padds to the required length', () => {
|
||||
expect(
|
||||
leftHexPad('0x123', 16)
|
||||
).toEqual('0x0123');
|
||||
});
|
||||
|
||||
it('padds to the required length (no prefix)', () => {
|
||||
expect(
|
||||
leftHexPad('123', 16)
|
||||
).toEqual('0x0123');
|
||||
});
|
||||
|
||||
it('pads null values correctly', () => {
|
||||
expect(
|
||||
leftHexPad(null, 16)
|
||||
).toEqual('0x0000');
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatH160', () => {
|
||||
it('pads to 40 bytes', () => {
|
||||
expect(
|
||||
formatH160('0x1234567890')
|
||||
).toEqual('0x0000000000000000000000000000001234567890');
|
||||
});
|
||||
|
||||
it('pads null values correctly', () => {
|
||||
expect(
|
||||
formatH160(null)
|
||||
).toMatch(/^0x(00){20,}$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatH256', () => {
|
||||
it('pads to 64 bytes', () => {
|
||||
expect(
|
||||
formatH256('0x1234567890')
|
||||
).toEqual('0x0000000000000000000000000000000000000000000000000000001234567890');
|
||||
});
|
||||
|
||||
it('pads null values correctly', () => {
|
||||
expect(
|
||||
formatH256(null)
|
||||
).toMatch(/^0x(00){32,}$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
24
packages/api-format/src/input/index.js
Normal file
24
packages/api-format/src/input/index.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { FormatInputType, InterfaceInputType } from '@polkadot/api-jsonrpc/types';
|
||||
import type { FormatterFunction } from '../types';
|
||||
|
||||
const formatAddress = require('./address');
|
||||
const { formatH256 } = require('./hex');
|
||||
const formatNoop = require('../noop');
|
||||
const util = require('../util');
|
||||
|
||||
const formatters: { [FormatInputType]: FormatterFunction } = {
|
||||
'Address': formatAddress,
|
||||
'CallData': formatNoop,
|
||||
'H256': formatH256,
|
||||
'HeaderHash': formatH256,
|
||||
'String': formatNoop
|
||||
};
|
||||
|
||||
module.exports = function format (inputs: Array<InterfaceInputType>, values: Array<any>): Array<any> {
|
||||
const types = inputs.map(({ type }) => type);
|
||||
|
||||
return util.formatArray(formatters, types, values);
|
||||
};
|
||||
22
packages/api-format/src/input/index.spec.js
Normal file
22
packages/api-format/src/input/index.spec.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const format = require('./index');
|
||||
|
||||
describe('input', () => {
|
||||
describe('format', () => {
|
||||
it('formats each value in an array', () => {
|
||||
expect(
|
||||
format(
|
||||
[
|
||||
{ name: 'foo', type: 'Address' },
|
||||
{ name: 'bar', type: 'H256' }
|
||||
],
|
||||
['0x1234', '0xabcd']
|
||||
)
|
||||
).toEqual([
|
||||
'0x0000000000000000000000000000000000001234',
|
||||
'0x000000000000000000000000000000000000000000000000000000000000abcd'
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
6
packages/api-format/src/noop.js
Normal file
6
packages/api-format/src/noop.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
module.exports = function format (value: any): any {
|
||||
return value;
|
||||
};
|
||||
13
packages/api-format/src/noop.spec.js
Normal file
13
packages/api-format/src/noop.spec.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const format = require('./noop');
|
||||
|
||||
describe('noop', () => {
|
||||
it('returns input value as output value', () => {
|
||||
const input = { 'some': 'object' };
|
||||
|
||||
expect(
|
||||
format(input)
|
||||
).toEqual(input);
|
||||
});
|
||||
});
|
||||
18
packages/api-format/src/output/index.js
Normal file
18
packages/api-format/src/output/index.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { FormatOutputType, InterfaceOutputType } from '@polkadot/api-jsonrpc/types';
|
||||
import type { FormatterFunction } from '../types';
|
||||
|
||||
const formatNoop = require('../noop');
|
||||
const util = require('../util');
|
||||
|
||||
const formatters: { [FormatOutputType]: FormatterFunction } = {
|
||||
'Header': formatNoop,
|
||||
'OutData': formatNoop,
|
||||
'StorageData': formatNoop
|
||||
};
|
||||
|
||||
module.exports = function format (output: InterfaceOutputType, value: any): any {
|
||||
return util.format(formatters, output.type, value);
|
||||
};
|
||||
13
packages/api-format/src/output/index.spec.js
Normal file
13
packages/api-format/src/output/index.spec.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const format = require('./index');
|
||||
|
||||
describe('output', () => {
|
||||
describe('format', () => {
|
||||
it('formats the value', () => {
|
||||
expect(
|
||||
format('Header', 'test')
|
||||
).toEqual('test');
|
||||
});
|
||||
});
|
||||
});
|
||||
4
packages/api-format/src/types.js
Normal file
4
packages/api-format/src/types.js
Normal file
@@ -0,0 +1,4 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
export type FormatterFunction = (value: any) => any;
|
||||
49
packages/api-format/src/util.js
Normal file
49
packages/api-format/src/util.js
Normal file
@@ -0,0 +1,49 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { FormatterFunction } from './types';
|
||||
|
||||
const { isUndefined } = require('@polkadot/util/is');
|
||||
const formatNoop = require('./noop');
|
||||
|
||||
const arrayTypeRegex = /\[\]$/;
|
||||
|
||||
function format (formatters: { [any]: FormatterFunction }, type: string, value: any): any {
|
||||
const isArrayType: boolean = arrayTypeRegex.test(type);
|
||||
const formatter: FormatterFunction = isArrayType
|
||||
? formatters[type.replace(arrayTypeRegex, '')]
|
||||
: formatters[type];
|
||||
|
||||
if (isUndefined(formatter)) {
|
||||
console.warn(`Unable to find default formatter for '${type}', falling back to noop`);
|
||||
|
||||
return formatNoop(value);
|
||||
}
|
||||
|
||||
if (isArrayType && !Array.isArray(value)) {
|
||||
throw new Error(`Unable to format non-array '${value}' as '${type}'`);
|
||||
}
|
||||
|
||||
try {
|
||||
if (isArrayType) {
|
||||
return (value: Array<any>).map((value) => formatter(value));
|
||||
} else {
|
||||
return formatter(value);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Error formatting '${value}' as '${type}'': ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function formatArray (formatters: { [any]: FormatterFunction }, types: Array<string>, values: Array<any>): Array<any> {
|
||||
return types.map((type, index) => {
|
||||
const value = values[index];
|
||||
|
||||
return format(formatters, type, value);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
format,
|
||||
formatArray
|
||||
};
|
||||
86
packages/api-format/src/util.spec.js
Normal file
86
packages/api-format/src/util.spec.js
Normal file
@@ -0,0 +1,86 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
/* global jest */
|
||||
|
||||
const { format, formatArray } = require('./util');
|
||||
const formatNoop = require('./noop');
|
||||
|
||||
describe('util', () => {
|
||||
let formatters;
|
||||
let noopSpy;
|
||||
let warnSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
noopSpy = jest.fn(formatNoop);
|
||||
warnSpy = jest.spyOn(console, 'warn');
|
||||
|
||||
formatters = {
|
||||
'Address': noopSpy,
|
||||
'Address[]': noopSpy,
|
||||
'Exception': () => {
|
||||
throw new Error('something went wrong');
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
noopSpy.mockRestore();
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
|
||||
describe('format', () => {
|
||||
it('formats unknown types with a fallback', () => {
|
||||
expect(
|
||||
format(formatters, 'Unknown', 'test')
|
||||
).toEqual('test');
|
||||
});
|
||||
|
||||
it('logs a warning with unknown types', () => {
|
||||
format(formatters, 'Unknown', 'test');
|
||||
expect(warnSpy).toHaveBeenCalledWith("Unable to find default formatter for 'Unknown', falling back to noop");
|
||||
});
|
||||
|
||||
it('wraps exceptions with the type', () => {
|
||||
expect(
|
||||
() => format(formatters, 'Exception', 'test')
|
||||
).toThrow(/Error formatting 'test' as 'Exception'/);
|
||||
});
|
||||
|
||||
describe('primitives', () => {
|
||||
it('formats known types using the supplied formatter', () => {
|
||||
format(formatters, 'Address', '0xaddress');
|
||||
|
||||
expect(noopSpy).toHaveBeenCalledWith('0xaddress');
|
||||
});
|
||||
});
|
||||
|
||||
describe('primitive[]', () => {
|
||||
it('throws exception with array type, but non-array value', () => {
|
||||
expect(
|
||||
() => format(formatters, 'Address[]', 'not-an-array')
|
||||
).toThrow(/Unable to format non-array/);
|
||||
});
|
||||
|
||||
it('formats using the primitive type', () => {
|
||||
format(formatters, 'Address[]', ['0x123', '0x234']);
|
||||
|
||||
expect(noopSpy).toHaveBeenCalledWith('0x123');
|
||||
expect(noopSpy).toHaveBeenCalledWith('0x234');
|
||||
});
|
||||
|
||||
it('returns formatted values as arrays', () => {
|
||||
expect(
|
||||
format(formatters, 'Address[]', ['0x123', '0x234'])
|
||||
).toEqual(['0x123', '0x234']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatArray', () => {
|
||||
it('formats each value in an array', () => {
|
||||
expect(
|
||||
formatArray(formatters, ['Unknown', 'Unknown'], ['test', 'blah'])
|
||||
).toEqual(['test', 'blah']);
|
||||
});
|
||||
});
|
||||
});
|
||||
15
packages/api-jsonrpc/LICENSE
Normal file
15
packages/api-jsonrpc/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
||||
ISC License (ISC)
|
||||
|
||||
Copyright 2017 Jaco Greeff <jacogr@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
23
packages/api-jsonrpc/README.md
Normal file
23
packages/api-jsonrpc/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api-jsonrpc)
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api-jsonrpc#info=devDependencies)
|
||||
|
||||
# @polkadot/api-jsonrpc
|
||||
|
||||
A defintion of all the methods exposed in a general Polkadot client application. These are used not only to provide a comprehensive code-generated document of the available methods, but are also used in the API to auto-generate endpoints with the required type-checking.
|
||||
|
||||
## Usage
|
||||
|
||||
Installation -
|
||||
|
||||
```
|
||||
npm install --save @polkadot/api-jsonrpc
|
||||
```
|
||||
|
||||
For a list of currently exposed methods, see the [method documentation](docs/README.md).
|
||||
|
||||
## Adding methods
|
||||
|
||||
As methods are added, simply adding the name, inputs & output will prepare it for use.
|
||||
|
||||
- Add the method to the correct file in [src/rpc/](src/rpc/) (Input/Output types as cross-referenced from the canonical implementation and match one-to-one)
|
||||
- Should a new type be required, add it to the type list, [src/types.js](src/types.js) (Required for flow type checking)
|
||||
7
packages/api-jsonrpc/docs/README.md
Normal file
7
packages/api-jsonrpc/docs/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Available interfaces
|
||||
|
||||
Exposes the definition for the RPC endpoints for a Polkadot client node
|
||||
|
||||
- [chain](chain.md) Methods to retrieve chain data.
|
||||
- [state](state.md) Query the state and state storage.
|
||||
|
||||
17
packages/api-jsonrpc/docs/chain.md
Normal file
17
packages/api-jsonrpc/docs/chain.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# chain
|
||||
|
||||
Methods to retrieve chain data.
|
||||
|
||||
- [getHeader](#getheader) Retrieves the header for a specific block.
|
||||
|
||||
## getHeader
|
||||
|
||||
Retrieves the header for a specific block.
|
||||
|
||||
```js
|
||||
chain_getHeader (hash: HeaderHash): Header
|
||||
```
|
||||
|
||||
|
||||
Given a block header specified by `hash`, return the full block `Header` information.
|
||||
|
||||
31
packages/api-jsonrpc/docs/state.md
Normal file
31
packages/api-jsonrpc/docs/state.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# state
|
||||
|
||||
Query the state and state storage.
|
||||
|
||||
- [call](#call) Perform a call to a builtin on the chain.
|
||||
- [getStorage](#getstorage) Retrieves the storage for an address.
|
||||
|
||||
## call
|
||||
|
||||
Perform a call to a builtin on the chain.
|
||||
|
||||
```js
|
||||
chain_call (address: Address, method: String, data: CallData, block: HeaderHash): OutData
|
||||
```
|
||||
|
||||
|
||||
Calls a `method` at a specific `address`, passing the encoded `data`. The query is executed at the block specified by `block`.
|
||||
|
||||
|
||||
|
||||
## getStorage
|
||||
|
||||
Retrieves the storage for an address.
|
||||
|
||||
```js
|
||||
chain_getStorage (address: Address, key: H256, block: HeaderHash): StorageData
|
||||
```
|
||||
|
||||
|
||||
Retrieves the storage `key` at a specific `address`, executing the query at a specific `block`.
|
||||
|
||||
38
packages/api-jsonrpc/package.json
Normal file
38
packages/api-jsonrpc/package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "@polkadot/api-jsonrpc",
|
||||
"version": "0.5.0",
|
||||
"description": "Method definitions for the Polkadot RPC layer",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=6.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"JsonRPC"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/api/issues"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-jsonrpc#readme",
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-babel && polkadot-dev-build-docs",
|
||||
"check": "eslint src && flow check",
|
||||
"test": "echo \"Tests only available from root wrapper\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/dev": "^0.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-runtime": "^6.26.0"
|
||||
}
|
||||
}
|
||||
21
packages/api-jsonrpc/src/chain/getHeader.js
Normal file
21
packages/api-jsonrpc/src/chain/getHeader.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { InterfaceMethodDefinition } from '../types';
|
||||
|
||||
/**
|
||||
@name getHeader
|
||||
@signature chain_getHeader (hash: HeaderHash): Header
|
||||
@summary Retrieves the header for a specific block.
|
||||
@description
|
||||
Given a block header specified by `hash`, return the full block `Header` information.
|
||||
*/
|
||||
module.exports = ({
|
||||
inputs: [
|
||||
{
|
||||
name: 'hash',
|
||||
type: 'HeaderHash'
|
||||
}
|
||||
],
|
||||
output: { type: 'Header' }
|
||||
}: InterfaceMethodDefinition);
|
||||
15
packages/api-jsonrpc/src/chain/index.js
Normal file
15
packages/api-jsonrpc/src/chain/index.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { InterfaceDefinition } from '../types';
|
||||
|
||||
const getHeader = require('./getHeader');
|
||||
|
||||
/**
|
||||
@summary Methods to retrieve chain data.
|
||||
*/
|
||||
module.exports = ({
|
||||
methods: {
|
||||
getHeader
|
||||
}
|
||||
}: InterfaceDefinition);
|
||||
15
packages/api-jsonrpc/src/index.js
Normal file
15
packages/api-jsonrpc/src/index.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { InterfaceDefinition } from './types';
|
||||
|
||||
const chain = require('./chain');
|
||||
const state = require('./state');
|
||||
|
||||
/**
|
||||
@summary Exposes the definition for the RPC endpoints for a Polkadot client node
|
||||
*/
|
||||
module.exports = ({
|
||||
chain,
|
||||
state
|
||||
}: { [string]: InterfaceDefinition });
|
||||
10
packages/api-jsonrpc/src/index.spec.js
Normal file
10
packages/api-jsonrpc/src/index.spec.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const interfaces = require('./index');
|
||||
|
||||
describe('jsonrpc', () => {
|
||||
it('exports the available interfaces', () => {
|
||||
expect(interfaces).toBeDefined();
|
||||
expect(Object.keys(interfaces).length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
35
packages/api-jsonrpc/src/state/call.js
Normal file
35
packages/api-jsonrpc/src/state/call.js
Normal file
@@ -0,0 +1,35 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { InterfaceMethodDefinition } from '../types';
|
||||
|
||||
/**
|
||||
@name call
|
||||
@signature chain_call (address: Address, method: String, data: CallData, block: HeaderHash): OutData
|
||||
@summary Perform a call to a builtin on the chain.
|
||||
@description
|
||||
Calls a `method` at a specific `address`, passing the encoded `data`. The query is executed at the block specified by `block`.
|
||||
*/
|
||||
module.exports = ({
|
||||
inputs: [
|
||||
{
|
||||
name: 'address',
|
||||
type: 'Address'
|
||||
},
|
||||
{
|
||||
name: 'method',
|
||||
type: 'String'
|
||||
},
|
||||
{
|
||||
name: 'data',
|
||||
type: 'CallData'
|
||||
},
|
||||
{
|
||||
name: 'block',
|
||||
type: 'HeaderHash'
|
||||
}
|
||||
],
|
||||
output: {
|
||||
type: 'OutData'
|
||||
}
|
||||
}: InterfaceMethodDefinition);
|
||||
31
packages/api-jsonrpc/src/state/getStorage.js
Normal file
31
packages/api-jsonrpc/src/state/getStorage.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { InterfaceMethodDefinition } from '../types';
|
||||
|
||||
/**
|
||||
@name getStorage
|
||||
@signature chain_getStorage (address: Address, key: H256, block: HeaderHash): StorageData
|
||||
@summary Retrieves the storage for an address.
|
||||
@description
|
||||
Retrieves the storage `key` at a specific `address`, executing the query at a specific `block`.
|
||||
*/
|
||||
module.exports = ({
|
||||
inputs: [
|
||||
{
|
||||
name: 'address',
|
||||
type: 'Address'
|
||||
},
|
||||
{
|
||||
name: 'key',
|
||||
type: 'H256'
|
||||
},
|
||||
{
|
||||
name: 'block',
|
||||
type: 'HeaderHash'
|
||||
}
|
||||
],
|
||||
output: {
|
||||
type: 'StorageData'
|
||||
}
|
||||
}: InterfaceMethodDefinition);
|
||||
17
packages/api-jsonrpc/src/state/index.js
Normal file
17
packages/api-jsonrpc/src/state/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { InterfaceDefinition } from '../types';
|
||||
|
||||
const call = require('./call');
|
||||
const getStorage = require('./getStorage');
|
||||
|
||||
/**
|
||||
@summary Query the state and state storage.
|
||||
*/
|
||||
module.exports = ({
|
||||
methods: {
|
||||
call,
|
||||
getStorage
|
||||
}
|
||||
}: InterfaceDefinition);
|
||||
27
packages/api-jsonrpc/src/types.js
Normal file
27
packages/api-jsonrpc/src/types.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
export type FormatInputType = 'Address' | 'CallData' | 'H256' | 'HeaderHash' | 'String';
|
||||
|
||||
export type FormatOutputType = 'Header' | 'OutData' | 'StorageData';
|
||||
|
||||
export type InterfaceInputType = {
|
||||
name: string,
|
||||
type: FormatInputType
|
||||
};
|
||||
|
||||
export type InterfaceOutputType = {
|
||||
type: FormatOutputType
|
||||
};
|
||||
|
||||
export type InterfaceMethodDefinition = {
|
||||
deprecated?: boolean,
|
||||
inputs: Array<InterfaceInputType>,
|
||||
output: InterfaceOutputType
|
||||
};
|
||||
|
||||
export type InterfaceDefinition = {
|
||||
methods: {
|
||||
[string]: InterfaceMethodDefinition
|
||||
}
|
||||
};
|
||||
15
packages/api-provider/LICENSE
Normal file
15
packages/api-provider/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
||||
ISC License (ISC)
|
||||
|
||||
Copyright 2017 Jaco Greeff <jacogr@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
25
packages/api-provider/README.md
Normal file
25
packages/api-provider/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api-provider)
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api-provider#info=devDependencies)
|
||||
|
||||
# @polkadot/api-provider
|
||||
|
||||
Generic transport providers to handle the transport of method calls to and from Polkadot clients from applications interacting with it. Generally, unless you are operating at a low-level and taking care of encoding and decoding of parameters/results, it won't be directly used. API interfaces building on top these providers can support various transports with the same underlying interfaces.
|
||||
|
||||
## Usage
|
||||
|
||||
Installation -
|
||||
|
||||
```
|
||||
npm install --save @polkadot/api-provider
|
||||
```
|
||||
|
||||
Initialisation -
|
||||
|
||||
```js
|
||||
import HttpProvider from '@polkadot/api-provider/http';
|
||||
|
||||
const provider = new HttpProvider('http://127.0.0.1:9933');
|
||||
const version = await provider.send('client_version', []);
|
||||
|
||||
console.log('clientVersion', version);
|
||||
```
|
||||
42
packages/api-provider/package.json
Normal file
42
packages/api-provider/package.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "@polkadot/api-provider",
|
||||
"version": "0.5.0",
|
||||
"description": "Transport providers for the API",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"JsonRPC"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=6.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/api/issues"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-provider#readme",
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-babel",
|
||||
"check": "eslint src && flow check",
|
||||
"test": "echo \"Tests only available from root wrapper\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/dev": "^0.9.1",
|
||||
"mock-socket": "^7.1.0",
|
||||
"nock": "^9.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util": "^0.5.15",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"isomorphic-fetch": "^2.2.1"
|
||||
}
|
||||
}
|
||||
39
packages/api-provider/src/http/index.js
Normal file
39
packages/api-provider/src/http/index.js
Normal file
@@ -0,0 +1,39 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { ProviderInterface } from '../types';
|
||||
|
||||
require('./polyfill');
|
||||
|
||||
const JsonRpcCoder = require('../jsonRpcCoder');
|
||||
|
||||
module.exports = class HttpProvider extends JsonRpcCoder implements ProviderInterface {
|
||||
_endpoint: string;
|
||||
|
||||
constructor (endpoint: string) {
|
||||
super();
|
||||
|
||||
this._endpoint = endpoint;
|
||||
}
|
||||
|
||||
async send (method: string, params: Array<any>): Promise<any> {
|
||||
const body = this.encodeJson(method, params);
|
||||
const response = await fetch(this._endpoint, {
|
||||
body,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Length': `${body.length}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`[${response.status}]: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
return this.decodeResponse(result);
|
||||
}
|
||||
};
|
||||
97
packages/api-provider/src/http/index.spec.js
Normal file
97
packages/api-provider/src/http/index.spec.js
Normal file
@@ -0,0 +1,97 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
/* global jest */
|
||||
|
||||
const { mockHttp, TEST_HTTP_URL } = require('../../test/mockHttp');
|
||||
|
||||
const Http = require('./index');
|
||||
|
||||
describe('Http', () => {
|
||||
let http;
|
||||
let mock;
|
||||
let encodeSpy;
|
||||
let decodeSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
http = new Http(TEST_HTTP_URL);
|
||||
|
||||
encodeSpy = jest.spyOn(http, 'encodeJson');
|
||||
decodeSpy = jest.spyOn(http, 'decodeResponse');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
encodeSpy.mockRestore();
|
||||
decodeSpy.mockRestore();
|
||||
|
||||
mock.done();
|
||||
});
|
||||
|
||||
describe('send', () => {
|
||||
it('encodes requests', () => {
|
||||
mock = mockHttp([{
|
||||
method: 'test_encoding',
|
||||
reply: {
|
||||
result: 'ok'
|
||||
}
|
||||
}]);
|
||||
|
||||
return http
|
||||
.send('test_encoding', ['param'])
|
||||
.then((result) => {
|
||||
expect(encodeSpy).toHaveBeenCalledWith('test_encoding', ['param']);
|
||||
});
|
||||
});
|
||||
|
||||
it('decodes responses', () => {
|
||||
mock = mockHttp([{
|
||||
method: 'test_encoding',
|
||||
reply: {
|
||||
result: 'ok'
|
||||
}
|
||||
}]);
|
||||
|
||||
return http
|
||||
.send('test_encoding', ['param'])
|
||||
.then((result) => {
|
||||
expect(decodeSpy).toHaveBeenCalledWith({
|
||||
id: 1,
|
||||
jsonrpc: '2.0',
|
||||
result: 'ok'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('passes the body through correctly', () => {
|
||||
mock = mockHttp([{
|
||||
method: 'test_body',
|
||||
reply: {
|
||||
result: 'ok'
|
||||
}
|
||||
}]);
|
||||
|
||||
return http
|
||||
.send('test_body', ['param'])
|
||||
.then((result) => {
|
||||
expect(mock.body['test_body']).toEqual({
|
||||
id: 1,
|
||||
jsonrpc: '2.0',
|
||||
method: 'test_body',
|
||||
params: ['param']
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('throws error when !response.ok', () => {
|
||||
mock = mockHttp([{
|
||||
code: 500,
|
||||
method: 'test_error'
|
||||
}]);
|
||||
|
||||
return http
|
||||
.send('test_error', [])
|
||||
.catch((error) => {
|
||||
expect(error.message).toMatch(/\[500\]: Internal Server/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
6
packages/api-provider/src/http/polyfill.js
Normal file
6
packages/api-provider/src/http/polyfill.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
if (typeof fetch === 'undefined') {
|
||||
require('isomorphic-fetch');
|
||||
}
|
||||
24
packages/api-provider/src/http/polyfill.spec.js
Normal file
24
packages/api-provider/src/http/polyfill.spec.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
describe('http/polyfill', () => {
|
||||
let origFetch;
|
||||
|
||||
beforeEach(() => {
|
||||
origFetch = global.fetch;
|
||||
global.fetch = null;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = origFetch;
|
||||
});
|
||||
|
||||
it('polyfills with no exceptions (without fetch)', () => {
|
||||
expect(require('./polyfill')).toBeDefined();
|
||||
});
|
||||
|
||||
it('polyfills with no exceptions (with fetch)', () => {
|
||||
global.fetch = () => true;
|
||||
|
||||
expect(require('./polyfill')).toBeDefined();
|
||||
});
|
||||
});
|
||||
10
packages/api-provider/src/index.js
Normal file
10
packages/api-provider/src/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
const Http = require('./http');
|
||||
const Ws = require('./ws');
|
||||
|
||||
module.exports = {
|
||||
Http,
|
||||
Ws
|
||||
};
|
||||
55
packages/api-provider/src/jsonRpcCoder.js
Normal file
55
packages/api-provider/src/jsonRpcCoder.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { JsonRpcRequest, JsonRpcResponse } from './types';
|
||||
|
||||
const { isNumber, isUndefined } = require('@polkadot/util/is');
|
||||
|
||||
module.exports = class JsonRpcCoder {
|
||||
_id: number = 0;
|
||||
|
||||
decodeResponse (response: JsonRpcResponse): any {
|
||||
if (!response) {
|
||||
throw new Error('Empty response object received');
|
||||
}
|
||||
|
||||
if (response.jsonrpc !== '2.0') {
|
||||
throw new Error('Invalid jsonrpc field in decoded object');
|
||||
}
|
||||
|
||||
if (!isNumber(response.id)) {
|
||||
throw new Error('Invalid id field in decoded object');
|
||||
}
|
||||
|
||||
if (response.error) {
|
||||
const { code, message } = response.error;
|
||||
|
||||
throw new Error(`[${code}]: ${message}`);
|
||||
}
|
||||
|
||||
if (isUndefined(response.result)) {
|
||||
throw new Error('No result found in JsonRpc response');
|
||||
}
|
||||
|
||||
return response.result;
|
||||
}
|
||||
|
||||
encodeObject (method: string, params: Array<any>): JsonRpcRequest {
|
||||
return {
|
||||
id: ++this._id,
|
||||
jsonrpc: '2.0',
|
||||
method,
|
||||
params
|
||||
};
|
||||
}
|
||||
|
||||
encodeJson (method: string, params: Array<any>): string {
|
||||
return JSON.stringify(
|
||||
this.encodeObject(method, params)
|
||||
);
|
||||
}
|
||||
|
||||
get id (): number {
|
||||
return this._id;
|
||||
}
|
||||
};
|
||||
77
packages/api-provider/src/jsonRpcCoder.spec.js
Normal file
77
packages/api-provider/src/jsonRpcCoder.spec.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const JsonRpcCoder = require('./jsonRpcCoder');
|
||||
|
||||
describe('JsonRpcCoder', () => {
|
||||
let coder;
|
||||
|
||||
beforeEach(() => {
|
||||
coder = new JsonRpcCoder();
|
||||
});
|
||||
|
||||
describe('id', () => {
|
||||
it('starts with id === 0 (nothing sent)', () => {
|
||||
expect(coder.id).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('decodeResponse', () => {
|
||||
it('expects a non-empty input object', () => {
|
||||
expect(
|
||||
() => coder.decodeResponse()
|
||||
).toThrow(/Empty response/);
|
||||
});
|
||||
|
||||
it('expects a valid jsonrpc field', () => {
|
||||
expect(
|
||||
() => coder.decodeResponse({})
|
||||
).toThrow(/Invalid jsonrpc/);
|
||||
});
|
||||
|
||||
it('expects a valid id field', () => {
|
||||
expect(
|
||||
() => coder.decodeResponse({ jsonrpc: '2.0' })
|
||||
).toThrow(/Invalid id/);
|
||||
});
|
||||
|
||||
it('expects a valid result field', () => {
|
||||
expect(
|
||||
() => coder.decodeResponse({ id: 1, jsonrpc: '2.0' })
|
||||
).toThrow(/No result/);
|
||||
});
|
||||
|
||||
it('throws any error found', () => {
|
||||
expect(
|
||||
() => coder.decodeResponse({ id: 1, jsonrpc: '2.0', error: { code: 123, message: 'test error' } })
|
||||
).toThrow(/\[123\]: test error/);
|
||||
});
|
||||
|
||||
it('returns the result', () => {
|
||||
expect(
|
||||
coder.decodeResponse({ id: 1, jsonrpc: '2.0', result: 'some result' })
|
||||
).toEqual('some result');
|
||||
});
|
||||
});
|
||||
|
||||
describe('encodeObject', () => {
|
||||
it('encodes a valid JsonRPC object', () => {
|
||||
expect(
|
||||
coder.encodeObject('method', 'params')
|
||||
).toEqual({
|
||||
id: 1,
|
||||
jsonrpc: '2.0',
|
||||
method: 'method',
|
||||
params: 'params'
|
||||
});
|
||||
expect(coder.id).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('encodeJson', () => {
|
||||
it('encodes a valid JsonRPC JSON string', () => {
|
||||
expect(
|
||||
coder.encodeJson('method', 'params')
|
||||
).toEqual('{"id":1,"jsonrpc":"2.0","method":"method","params":"params"}');
|
||||
});
|
||||
});
|
||||
});
|
||||
26
packages/api-provider/src/types.js
Normal file
26
packages/api-provider/src/types.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
export type JsonRpcObject = {
|
||||
id: number;
|
||||
jsonrpc: '2.0';
|
||||
};
|
||||
|
||||
export type JsonRpcRequest = JsonRpcObject & {
|
||||
method: string;
|
||||
params: Array<any>;
|
||||
};
|
||||
|
||||
export type JsonRpcResponseBase = {
|
||||
error?: {
|
||||
code: number,
|
||||
message: string
|
||||
};
|
||||
result?: any;
|
||||
}
|
||||
|
||||
export type JsonRpcResponse = JsonRpcObject & JsonRpcResponseBase;
|
||||
|
||||
export interface ProviderInterface {
|
||||
send (method: string, params: Array<any>): Promise<any>;
|
||||
}
|
||||
101
packages/api-provider/src/ws/index.js
Normal file
101
packages/api-provider/src/ws/index.js
Normal file
@@ -0,0 +1,101 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
// @flow
|
||||
|
||||
import type { JsonRpcResponse, ProviderInterface } from '../types';
|
||||
|
||||
type AwaitingType = {
|
||||
callback: (error: ?Error, result: any) => void
|
||||
};
|
||||
|
||||
type WsMessageType = {
|
||||
data: any
|
||||
};
|
||||
|
||||
const JsonRpcCoder = require('../jsonRpcCoder');
|
||||
|
||||
module.exports = class WsProvider extends JsonRpcCoder implements ProviderInterface {
|
||||
_autoConnect: boolean = true;
|
||||
_endpoint: string;
|
||||
_handlers: { [number]: AwaitingType } = {};
|
||||
_websocket: WebSocket;
|
||||
|
||||
constructor (endpoint: string, autoConnect: boolean = true) {
|
||||
super();
|
||||
|
||||
this._endpoint = endpoint;
|
||||
this._autoConnect = autoConnect;
|
||||
|
||||
if (autoConnect) {
|
||||
this.connect();
|
||||
}
|
||||
}
|
||||
|
||||
connect = () => {
|
||||
this._handlers = {};
|
||||
|
||||
this._websocket = new WebSocket(this._endpoint);
|
||||
|
||||
this._websocket.onclose = this._onClose;
|
||||
this._websocket.onerror = this._onError;
|
||||
this._websocket.onmessage = this._onMessage;
|
||||
this._websocket.onopen = this._onOpen;
|
||||
}
|
||||
|
||||
_onClose = () => {
|
||||
// console.log('disconnected from', this._endpoint);
|
||||
|
||||
if (this._autoConnect) {
|
||||
setTimeout(this.connect, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
_onError = (error: Event) => {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
_onOpen = () => {
|
||||
// console.log('connected to', this._endpoint);
|
||||
}
|
||||
|
||||
_onMessage = (message: WsMessageType) => {
|
||||
const response: JsonRpcResponse = JSON.parse(message.data);
|
||||
const handler = this._handlers[response.id];
|
||||
|
||||
if (!handler) {
|
||||
console.error(`Unable to find handler for id=${response.id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = this.decodeResponse(response);
|
||||
|
||||
handler.callback(null, result);
|
||||
} catch (error) {
|
||||
handler.callback(error);
|
||||
}
|
||||
|
||||
delete this._handlers[response.id];
|
||||
}
|
||||
|
||||
send (method: string, params: Array<any>): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
this._websocket.send(
|
||||
this.encodeObject(method, params)
|
||||
);
|
||||
|
||||
this._handlers[this.id] = {
|
||||
callback: (error: ?Error, result: any) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
195
packages/api-provider/src/ws/index.spec.js
Normal file
195
packages/api-provider/src/ws/index.spec.js
Normal file
@@ -0,0 +1,195 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
/* global jest */
|
||||
|
||||
const { mockWs, TEST_WS_URL } = require('../../test/mockWs');
|
||||
|
||||
const { isUndefined } = require('@polkadot/util/is');
|
||||
|
||||
const Ws = require('./index');
|
||||
|
||||
let ws;
|
||||
let mock;
|
||||
let encodeSpy;
|
||||
let decodeSpy;
|
||||
|
||||
function createWs (requests, autoConnect) {
|
||||
mock = autoConnect || isUndefined(autoConnect)
|
||||
? mockWs(requests)
|
||||
: null;
|
||||
|
||||
ws = new Ws(TEST_WS_URL, autoConnect);
|
||||
|
||||
encodeSpy = jest.spyOn(ws, 'encodeObject');
|
||||
decodeSpy = jest.spyOn(ws, 'decodeResponse');
|
||||
|
||||
return ws;
|
||||
}
|
||||
|
||||
describe('Ws', () => {
|
||||
afterEach(() => {
|
||||
encodeSpy.mockRestore();
|
||||
decodeSpy.mockRestore();
|
||||
|
||||
if (mock) {
|
||||
mock.done();
|
||||
}
|
||||
});
|
||||
|
||||
describe('websocket', () => {
|
||||
let errorSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
ws = createWs([]);
|
||||
|
||||
errorSpy = jest.spyOn(console, 'error');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
errorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('sets up the on* handlers', () => {
|
||||
expect(ws._websocket.onclose[0]).toEqual(ws._onClose);
|
||||
expect(ws._websocket.onerror[0]).toEqual(ws._onError);
|
||||
expect(ws._websocket.onmessage[0]).toEqual(ws._onMessage);
|
||||
expect(ws._websocket.onopen[0]).toEqual(ws._onOpen);
|
||||
});
|
||||
|
||||
describe('_onClose', () => {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('reconnects after delay', () => {
|
||||
ws.connect = jest.fn();
|
||||
ws._onClose();
|
||||
|
||||
expect(ws.connect).not.toHaveBeenCalled();
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(ws.connect).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not reconnect when autoConnect false', () => {
|
||||
mock.done();
|
||||
ws = createWs([], false);
|
||||
|
||||
ws.connect = jest.fn();
|
||||
ws._onClose();
|
||||
|
||||
expect(ws.connect).not.toHaveBeenCalled();
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(ws.connect).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('_onError', () => {
|
||||
it('logs the error', () => {
|
||||
ws._onError('test error');
|
||||
|
||||
expect(errorSpy).toHaveBeenCalledWith('test error');
|
||||
});
|
||||
});
|
||||
|
||||
describe('_onMessage', () => {
|
||||
it('fails with log when handler not found', () => {
|
||||
ws._onMessage({ data: '{"id":2}' });
|
||||
|
||||
expect(errorSpy).toHaveBeenCalledWith('Unable to find handler for id=2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('send', () => {
|
||||
it('handles internal errors', () => {
|
||||
ws = createWs([], false);
|
||||
|
||||
return ws
|
||||
.send('test_encoding', ['param'])
|
||||
.catch((error) => {
|
||||
expect(error).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes requests', () => {
|
||||
ws = createWs([{
|
||||
id: 1,
|
||||
method: 'test_encoding',
|
||||
reply: {
|
||||
result: 'ok'
|
||||
}
|
||||
}]);
|
||||
|
||||
return ws
|
||||
.send('test_encoding', ['param'])
|
||||
.then((result) => {
|
||||
expect(encodeSpy).toHaveBeenCalledWith('test_encoding', ['param']);
|
||||
});
|
||||
});
|
||||
|
||||
it('decodes responses', () => {
|
||||
ws = createWs([{
|
||||
id: 1,
|
||||
method: 'test_encoding',
|
||||
reply: {
|
||||
result: 'ok'
|
||||
}
|
||||
}]);
|
||||
|
||||
return ws
|
||||
.send('test_encoding', ['param'])
|
||||
.then((result) => {
|
||||
expect(decodeSpy).toHaveBeenCalledWith({
|
||||
id: 1,
|
||||
jsonrpc: '2.0',
|
||||
result: 'ok'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('passes the body through correctly', () => {
|
||||
ws = createWs([{
|
||||
id: 1,
|
||||
method: 'test_body',
|
||||
reply: {
|
||||
result: 'ok'
|
||||
}
|
||||
}]);
|
||||
|
||||
return ws
|
||||
.send('test_body', ['param'])
|
||||
.then((result) => {
|
||||
expect(mock.body['test_body']).toEqual({
|
||||
id: 1,
|
||||
jsonrpc: '2.0',
|
||||
method: 'test_body',
|
||||
params: ['param']
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('throws error when !response.ok', () => {
|
||||
ws = createWs([{
|
||||
id: 1,
|
||||
error: {
|
||||
code: 666,
|
||||
message: 'error'
|
||||
}
|
||||
}]);
|
||||
|
||||
return ws
|
||||
.send('test_error', [])
|
||||
.catch((error) => {
|
||||
expect(error.message).toMatch(/\[666\]: error/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
25
packages/api-provider/test/mockHttp.js
Normal file
25
packages/api-provider/test/mockHttp.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const nock = require('nock');
|
||||
|
||||
const TEST_HTTP_URL = 'http://localhost:9944';
|
||||
|
||||
function mockHttp (requests) {
|
||||
nock.cleanAll();
|
||||
|
||||
return requests.reduce((scope, request, index) => {
|
||||
return scope
|
||||
.post('/')
|
||||
.reply(request.code || 200, (uri, body) => {
|
||||
scope.body = scope.body || {};
|
||||
scope.body[request.method] = body;
|
||||
|
||||
return Object.assign({ id: body.id, jsonrpc: '2.0' }, request.reply || {});
|
||||
});
|
||||
}, nock(TEST_HTTP_URL));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
TEST_HTTP_URL,
|
||||
mockHttp
|
||||
};
|
||||
50
packages/api-provider/test/mockWs.js
Normal file
50
packages/api-provider/test/mockWs.js
Normal file
@@ -0,0 +1,50 @@
|
||||
// ISC, Copyright 2017 Jaco Greeff
|
||||
|
||||
const { Server } = require('mock-socket');
|
||||
|
||||
const TEST_WS_URL = 'ws://localhost:9955';
|
||||
|
||||
let server;
|
||||
|
||||
function mockWs (requests) {
|
||||
server = new Server(TEST_WS_URL);
|
||||
let requestCount = 0;
|
||||
|
||||
server.on('message', (body) => {
|
||||
const request = requests[requestCount];
|
||||
const result = request.reply;
|
||||
const response = request.error
|
||||
? {
|
||||
id: request.id,
|
||||
jsonrpc: '2.0',
|
||||
error: {
|
||||
code: request.error.code,
|
||||
message: request.error.message
|
||||
}
|
||||
}
|
||||
: {
|
||||
id: request.id,
|
||||
jsonrpc: '2.0',
|
||||
result: result.result
|
||||
};
|
||||
|
||||
scope.body[request.method] = body;
|
||||
requestCount++;
|
||||
|
||||
server.send(JSON.stringify(response));
|
||||
});
|
||||
|
||||
const scope = {
|
||||
body: {},
|
||||
requests: 0,
|
||||
server,
|
||||
done: () => server.stop()
|
||||
};
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
TEST_WS_URL,
|
||||
mockWs
|
||||
};
|
||||
15
packages/api/LICENSE
Normal file
15
packages/api/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
||||
ISC License (ISC)
|
||||
|
||||
Copyright 2017 Jaco Greeff <jacogr@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
37
packages/api/README.md
Normal file
37
packages/api/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api)
|
||||
[](https://david-dm.org/polkadot-js/api?path=packages/api#info=devDependencies)
|
||||
|
||||
# @polkadot/api
|
||||
|
||||
Warning - currently this does not actually do all that much, it is an attempt to put into code some thoughts about how to maintain the endpoints. This library provides a clean wrapper around all the methods exposed by a Polkadot network client. Methods are auto-generated for the [JsonRPC interface definitions](https://github.com/polkadot-js/api/packages/api-jsonrpc).
|
||||
|
||||
## Usage
|
||||
|
||||
Installation -
|
||||
|
||||
```
|
||||
npm install --save @polkadot/api
|
||||
```
|
||||
|
||||
Initialisation -
|
||||
|
||||
```js
|
||||
import Api from '@polkadot/api';
|
||||
import HttpProvider from '@polkadot/api-provider/http';
|
||||
|
||||
const provider = new HttpProvider('http://127.0.0.1:9933');
|
||||
const api = new Api(provider);
|
||||
```
|
||||
|
||||
Making calls -
|
||||
|
||||
```js
|
||||
api.chain
|
||||
.getHeader('0x1234567890')
|
||||
.then((header) => console.log(header))
|
||||
.catch((error) => console.error(error));
|
||||
```
|
||||
|
||||
## Available methods
|
||||
|
||||
For a list of currently exposed methods, see the [@polkadot/api-jsonrpc](https://github.com/polkadot-js/api/packages/api-jsonrpc#readme) repository.
|
||||
42
packages/api/package.json
Normal file
42
packages/api/package.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "@polkadot/api",
|
||||
"version": "0.5.0",
|
||||
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"JsonRPC"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=6.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/api/issues"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-babel",
|
||||
"check": "eslint src && flow check",
|
||||
"test": "echo \"Tests only available from root wrapper\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/dev": "^0.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/api-format": "^0.5.0",
|
||||
"@polkadot/api-jsonrpc": "^0.5.0",
|
||||
"@polkadot/api-provider": "^0.5.0",
|
||||
"@polkadot/util": "^0.5.15",
|
||||
"babel-runtime": "^6.26.0"
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,11 @@
|
||||
// @flow
|
||||
|
||||
import type { ProviderInterface } from '@polkadot/api-provider/types';
|
||||
import type { InterfaceDefinition } from '@polkadot/jsonrpc/types';
|
||||
import type { InterfaceDefinition } from '@polkadot/api-jsonrpc/types';
|
||||
import type { ApiInterface } from './types';
|
||||
|
||||
const { formatInputs, formatOutput } = require('@polkadot/api-format');
|
||||
const interfaces = require('@polkadot/jsonrpc');
|
||||
const interfaces = require('@polkadot/api-jsonrpc');
|
||||
const isFunction = require('@polkadot/util/is/function');
|
||||
const jsonrpcSignature = require('@polkadot/util/jsonrpc/signature');
|
||||
|
||||
Reference in New Issue
Block a user