Skip to content

Commit

Permalink
Merge 3722598 into b4f3095
Browse files Browse the repository at this point in the history
  • Loading branch information
ltfschoen committed Oct 12, 2018
2 parents b4f3095 + 3722598 commit c6a4c82
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 14 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -41,8 +41,8 @@ To get started -
3. Ensure that you have a recent version of Yarn, for development purposes [Yarn >=1.3.2](https://yarnpkg.com/docs/install) is required.
4. Install the dependencies by running `yarn`
5. Build the API Docs, via `yarn run build`
5. Ready! Now you can launch the API Docs, via `yarn gitbook serve`
6. Access the API Docs via [http://localhost:4000](http://localhost:4000)
6. Ready! Now you can launch the API Docs, via `yarn gitbook serve`
7. Access the API Docs via [http://localhost:4000](http://localhost:4000)

## tutorials

Expand Down
5 changes: 5 additions & 0 deletions docs/SUMMARY.md
Expand Up @@ -7,6 +7,11 @@
- [HttpProvider](rpc-provider/classes/_http_index_.httpprovider.md)
- [WsProvider](rpc-provider/classes/_ws_index_.wsprovider.md)

## Node Interfaces
- [RPC](METHODS_RPC.md)
- [Storage chain state (runtime)](METHODS_STORAGE.md)
- [Extrinsics (runtime)](METHODS_EXTRINSICS.md)

## Examples

- [ApiPromise](examples/promise/README.md)
Expand Down
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -13,8 +13,10 @@
"typescript": "^3.0.1"
},
"scripts": {
"build": "polkadot-dev-build-ts && polkadot-dev-build-docs",
"build": "yarn run build:methodsdoc && polkadot-dev-build-ts && polkadot-dev-build-docs",
"build:htmldoc": "yarn clean && typedoc --theme default --out docs/html",
"build:methodsdoc": "node packages/types/src/scripts/MetadataMdWrapper.js",
"build:decodedjson": "node packages/types/src/scripts/MetadataJsonDecodeWrapper.js",
"check": "tslint --project . && tsc --noEmit",
"clean": "polkadot-dev-clean-build",
"postinstall": "polkadot-dev-yarn-only",
Expand All @@ -25,6 +27,7 @@
"@polkadot/ts": "^0.1.30"
},
"dependencies": {
"babel-plugin-module-resolver": "^3.1.1",
"gitbook-plugin-include-codeblock": "^3.2.2",
"gitbook-plugin-mermaid-gb3": "^2.1.0",
"gitbook-plugin-sunlight-highlighter": "^0.4.3"
Expand Down
13 changes: 8 additions & 5 deletions packages/api/README.md
Expand Up @@ -4,22 +4,25 @@ The Polkadot-JS API provides easy-to-use wrappers around JSONRPC calls that flow

The API wrappers provide a standard interface for use -

- A static `.create(<optional WsProvider>)` that returns an API istance when connected, decorated and ready-to use
- A static `.create(<optional WsProvider>)` that returns an API instance when connected, decorated and ready-to use
- The above is just a wrapper for `new Api(<optional WsProvider>) `, exposing the `isReady` getter
- `api.rpc.<section>.<method>` provides access to actual RPC calls, be it for queries, submission or retrieving chain information
- [RPC (node interface)](../METHODS_RPC.md)
- `api.query.<section>.<method>` provides access to chain state queries. These are dynamically populated based on what the runtime provides
- `api.tx.<section>.<method>` provides the ability to create transaction, like chain state, this list is populated from a runtime query
- [Storage chain state (runtime node interface)](../METHODS_STORAGE.md)
- `api.tx.<section>.<method>` provides the ability to create a transaction, like chain state, this list is populated from a runtime query
- [Extrinsics (runtime node interface)](../METHODS_EXTRINSICS.md)

## API Selection

There are two flavours of the API provided, one allowing a standard interface via JavaScript Promises and the second provides an Observable wrapper using [RxJS](https://github.com/ReactiveX/rxjs). Depending on your use-case and familiarity, you can choose either (or even both) for your application.

- [[ApiPromise]] All interface calls returns Promises, including the static `.create(...)`. Additionally any subscription method use `(value) => {}` callbacks, returning the value as the subscription is updated.
- [[ApiRx]] All interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion and subscription-based methods return long-running Observables that update with the latest values.
- [[ApiPromise]] All interface calls returns Promises, including the static `.create(...)`. Additionally any subscription method uses `(value) => {}` callbacks, returning the value as the subscription is updated.
- [[ApiRx]] All interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion subscription-based methods return long-running Observables that update with the latest values.

## Dynamic by default

Subtrate (on which Polkadot is built) used on-chain on-chain WASM runtimes, allowing for upgradability. Each runtime defining the actual chain extrinsics (submitted transactions and block intrinsics) as well as available entries in the chain state. Due to this, the API endpoints for queries and transactions are dynamically populated from the running chain.
Substrate (upon which Polkadot is built) uses on-chain WASM runtimes, allowing for upgradability. Each runtime defining the actual chain extrinsics (submitted transactions and block intrinsics) as well as available entries in the chain state. Due to this, the API endpoints for queries and transactions are dynamically populated from the running chain.

Due to this dynamic nature, this API departs from traditional APIs which only has fixed endpoints, driving use by what is available by the runtime. As a start, this generic nature has a learning curve, although the provided documentation, examples and linked documentation tries to make that experience as seamless as possible.

Expand Down
4 changes: 2 additions & 2 deletions packages/rpc-provider/README.md
@@ -1,10 +1,10 @@
# @polkadot/rpc-provider

Generic transport providers to handle the transport of method calls to and from Polkadot clients from applications interacting with it. It provides an interface to making RPC class and is 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, rather only passed to a higher-level interface.
Generic transport providers to handle the transport of method calls to and from Polkadot clients from applications interacting with it. It provides an interface to making RPC calls and is 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, rather only passed to a higher-level interface.

## Provider Selection

There are two flavours of the providers provided, one allowing for using HTTP as a transport machanism, the other using WebSockets. It is generally recommended to use the [[WsProvider]] since in addition to standard calls, it allows for subscriptions where all changes to state can be pushed from the node to the client.
There are two flavours of the providers provided, one allowing for using HTTP as a transport mechanism, the other using WebSockets. It is generally recommended to use the [[WsProvider]] since in addition to standard calls, it allows for subscriptions where all changes to state can be pushed from the node to the client.

Both providers are usable (as is the API), in both browser-based and Node.js environments. Polyfills for unsupported functionality are automatically applied based on feature-detection.

Expand Down
2 changes: 1 addition & 1 deletion packages/type-jsonrpc/README.md
Expand Up @@ -2,7 +2,7 @@

A definition 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.

For a list of currently exposed methods, see the [method documentation](docs/README.md).
For a list of currently exposed methods, see the [method documentation](docs/METHODS_RPC.md).

## Usage

Expand Down
2 changes: 1 addition & 1 deletion packages/type-jsonrpc/src/chain.ts
Expand Up @@ -40,7 +40,7 @@ const getHead: RpcMethodOpt = {
};

const getRuntimeVersion: RpcMethodOpt = {
description: ' Get the runtime version',
description: 'Get the runtime version',
params: [
createParam('hash', 'Hash', { isOptional: true })
],
Expand Down
4 changes: 3 additions & 1 deletion packages/type-jsonrpc/src/index.ts
Expand Up @@ -2,12 +2,14 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

import { RpcSection } from './types';

import author from './author';
import chain from './chain';
import state from './state';
import system from './system';

const interfaces = {
const interfaces: { [key: string]: RpcSection } = {
author,
chain,
state,
Expand Down
15 changes: 15 additions & 0 deletions packages/types/babelConfig.js
@@ -0,0 +1,15 @@
#!/usr/bin/env node
// Copyright 2017-2018 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

require('@babel/register')({
extensions: ['.js', '.ts'],
plugins: [
['module-resolver', {
alias: {
'^@polkadot/types(.*)': './packages/types/src\\2'
}
}]
]
});
1 change: 0 additions & 1 deletion packages/types/src/Metadata.spec.js
Expand Up @@ -8,7 +8,6 @@ import rpcdata from './Metadata.rpc';
describe('Metadata', () => {
it('decodes properly', () => {
const decoded = new Metadata().fromJSON(rpcdata);

const str = JSON.stringify(decoded.toJSON());

console.error(str);
Expand Down
26 changes: 26 additions & 0 deletions packages/types/src/scripts/METHODS_STORAGE_SUBSTRATE.md
@@ -0,0 +1,26 @@

---

### substrate

_These are keys that are always available to the runtime implementation_

**code**(): `Bytes`
- **summary**: Wasm code of the runtime.

**heapPages**(): `u64`
- **summary**: Number of wasm linear memory pages required for execution of the runtime.

**authorityCount**(): `u32`
- **summary**: Number of authorities.

**authorityPrefix**(): `u32`
- **summary**: Prefix under which authorities are storied.

**extrinsicIndex**(): `u32`
- **summary**: Current extrinsic index (u32) is stored under this key.

**changesTrieConfig**(): `u32`
- **summary**: Changes trie configuration is stored under this key.

---
29 changes: 29 additions & 0 deletions packages/types/src/scripts/MetadataJsonDecode.ts
@@ -0,0 +1,29 @@
// Copyright 2017-2018 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

const fs = require('fs');

import Metadata from '../Metadata';
import rpcdata from '../Metadata.rpc';

function metadataStringifyAsJson () {
const decoded = new Metadata().fromJSON(rpcdata);

return JSON.stringify(decoded.toJSON(), null, 2);
}

function writeToJson () {
const options = { encoding: 'ascii' };
const writeStream = fs.createWriteStream('packages/types/src/Metadata.decoded.json', options);

writeStream.write(metadataStringifyAsJson());

writeStream.on('finish', () => {
console.log('wrote all decoded metadata to JSON file');
});

writeStream.end('\n');
}

writeToJson();
7 changes: 7 additions & 0 deletions packages/types/src/scripts/MetadataJsonDecodeWrapper.js
@@ -0,0 +1,7 @@
#!/usr/bin/env node
// Copyright 2017-2018 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

require('../../babelConfig.js');
require('./MetadataJsonDecode.ts');
150 changes: 150 additions & 0 deletions packages/types/src/scripts/MetadataMd.ts
@@ -0,0 +1,150 @@
// Copyright 2017-2018 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

const fs = require('fs');
import { stringCamelCase, stringLowerFirst } from '@polkadot/util/string';

import interfaces from '../../../type-jsonrpc/src';
import Metadata from '../Metadata';
import rpcdata from '../Metadata.rpc';
import Method from '../Method';

// some intro text goes in here
const DESC_RPC = '\n\n_The following RPC methods are the Remote Calls that are available by default and allow you to interact with the actual node, query, and submit. The RPCs are provided by Substrate itself. The RPCs are never exposed by the runtime._';
const DESC_EXTRINSICS = '\n\n_The following Extrinsics methods are part of the default Substrate runtime. Since an Extrinsic is a holder of an object that is just an array of bytes to be included, it does not have a return._';
const DESC_STORAGE = '\n\n_The following Storage methods are part of the default Substrate runtime._';

function addRpc () {
const renderHeading = `## JSON-RPC${DESC_RPC}\n`;

return Object.keys(interfaces).reduce((md, sectionName) => {
const section = interfaces[sectionName];
const renderSection = `${md}\n___\n\n### ${sectionName}\n\n_${section.description}_\n`;

return Object.keys(section.methods).reduce((md, methodName) => {
const method = section.methods[methodName];
const args = method.params.map(({ name, isOptional, type }) => {
return name + (isOptional ? '?' : '') + ': `' + type + '`';
}).join(', ');
const type = '`' + method.type + '`';
const isSub = method.isSubscription;
const renderMethod = `${md}\n▸ **${methodName}**(${args})`;
const renderReturnType = `: ${type}`;
const renderSignature = `${renderMethod}${renderReturnType}`;
const renderSignatureSub = `${renderMethod}**.subscribe**(CALLBACK)${renderReturnType}`;
const renderSummary = `${method && method.description ? `\n- **summary**: ${method.description}\n` : `\n\n`}`;

return isSub ? `${renderSignatureSub}${renderSummary}` : `${renderSignature}${renderSummary}`;
}, renderSection);
}, renderHeading);
}

function addExtrinsics (metadata: any) {
const renderHeading = `## Extrinsics${DESC_EXTRINSICS}`;

return metadata.modules.reduce((md: string, meta: any) => {
if (!meta.module.call || !meta.module.call.functions.length) {
return md;
}

const sectionName = stringCamelCase(meta.prefix.toString());
const renderSection = `${md}\n___\n### ${sectionName}\n`;

return meta.module.call.functions.reduce((md: string, func: any) => {
const methodName = stringCamelCase(func.name.toString());
const args = Method.filterOrigin(func).map(({ name, type }) => `${name}: ` + '`' + type + '`').join(', ');
const doc = func.documentation.reduce((md: string, doc: string) => `${md} ${doc}`, '');
const renderSignature = `${md}\n▸ **${methodName}**(${args})`;
const renderSummary = `${doc ? `\n- **summary**: ${doc}\n` : '\n'}`;

return renderSignature + renderSummary;
}, renderSection);
}, renderHeading);
}

function addStorage (metadata: any) {
const renderHeading = `## Storage${DESC_STORAGE}`;

return metadata.modules.reduce((md: string, moduleMetadata: any) => {
if (!moduleMetadata.storage) {
return md;
}

const sectionName = stringLowerFirst(moduleMetadata.storage.prefix.toString());
const renderSection = `${md}\n___\n### ${sectionName}\n`;

return moduleMetadata.storage.functions.reduce((md: string, func: any) => {
const methodName = stringLowerFirst(func.name.toString());
const arg = func.type.isMap ? ('`' + func.type.asMap.key.toString() + '`') : '';
const doc = func.documentation.reduce((md: string, doc: string) => `${md} ${doc}`, '');
const renderSignature = `${md}\n▸ **${methodName}**(${arg}): ` + '`' + func.type + '`';
const renderSummary = `${doc ? `\n- **summary**: ${doc}\n` : '\n'}`;

return renderSignature + renderSummary;
}, renderSection);
}, renderHeading);
}

function metadataStorageMethodsAsText () {
const metadata = new Metadata().fromJSON(rpcdata);
return addStorage(metadata);
}

function metadataExtrinsicsMethodsAsText () {
const metadata = new Metadata().fromJSON(rpcdata);
return addExtrinsics(metadata);
}

function writeToRpcMd () {
const options = { flags: 'w', encoding: 'utf8' };
const writeStream = fs.createWriteStream('docs/METHODS_RPC.md', options);

writeStream.write(addRpc());

writeStream.on('finish', () => {
console.log('wrote all rpc method metadata to Gitbook Markdown file');
});

writeStream.end();
}

function writeToStorageMd () {
const optionsRead = { flags: 'r', encoding: 'utf8' };
fs.readFile('packages/types/src/scripts/METHODS_STORAGE_SUBSTRATE.md', optionsRead, function read (err: Error, data: string) {
if (err) {
throw err;
}

// 'utf8', 'ascii', 'binary', 'hex', 'base64', or 'utf16le'
const options = { flags: 'w', encoding: 'utf8' };
const writeStream = fs.createWriteStream('docs/METHODS_STORAGE.md', options);

writeStream.write(metadataStorageMethodsAsText());
writeStream.write(data);

// finish emitting event when all data flushed from stream
writeStream.on('finish', () => {
console.log('wrote all storage method metadata to Gitbook Markdown file');
});

writeStream.end();
});
}

function writeToExtrinsicsMd () {
const options = { flags: 'w', encoding: 'utf8' };
const writeStream = fs.createWriteStream('docs/METHODS_EXTRINSICS.md', options);

writeStream.write(metadataExtrinsicsMethodsAsText());

writeStream.on('finish', () => {
console.log('wrote all extrinsics method metadata to Gitbook Markdown file');
});

writeStream.end();
}

writeToRpcMd();
writeToStorageMd();
writeToExtrinsicsMd();
7 changes: 7 additions & 0 deletions packages/types/src/scripts/MetadataMdWrapper.js
@@ -0,0 +1,7 @@
#!/usr/bin/env node
// Copyright 2017-2018 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

require('../../babelConfig.js');
require('./MetadataMd.ts');

0 comments on commit c6a4c82

Please sign in to comment.