WIP: Sd 569 docs add and fix apirx examples (#600)

* Docs: Fixed keyring examples

* Docs: Added Rx examples

* [Docs] Added timeout to showcase unsubscribe method in ApiPromise

* [Docs] Added timeout to showcase unsubscribe method in ApiPromise

* [Docs] Added comments to read_storage example

* [Docs] Renamed "transfer_dots' to a more generic 'make_transfer' since it's not only DOT's

* [Docs] ApiRx examples for simple_connect, listen_to_blocks (incl. unsubscribe), listen_to_balance_change and read_storage

* [Docs] changed back keyring import syntax to require

* [Docs] Removed provider from read storage example

* [Docs] ApiRx "make transfer" example

* [Docs] ApiRx "system events" example

* [Docs] ApiRx "transfer events" example

* [Docs] Removed unused utility functions import

* [Docs] ApiRx 'upgrade chain' example

* [Docs] removed generated html files

* [Docs] Ficed wrong Readme of listen to blocks example

* [Docs added missing import]

* [Docs] Removed unsubscribe() example from 'listen to blocks'

* [Docs] Added Unsubscribe example for ApiPromise and ApiRx

* [Docs] Added links to summary

* [Docs] Removed duplicate info/comment from 04_unsubscribe

* [Docs] Fixed wording

* [Docs] Log actual transaction status in "make_transfer"

* [Docs] Changed author name

* [Docs] Log actual transaction status in "make_transfer"

* [Docs] changed headline of make_transfer example README's

* [Docs] changed status.value to status.asFinalised

* [Docs] Removed auto-generated html

* [Docs] Changed all occurances of status.value.toHex() to status.asFinalised.toHex()

* [Docs] Remove call to nonce observable from signAndSend examples

* [Docs] Use RxJs' zip() operator instead of 'await Promise.all()'

* [Docs] Remove call to nonce observable from 'upgrade_chain' example

* [Docs] Changed author

* [Docs] Changed wording of balance change example

* [Docs] smaller code-review fixes

* [Docs] Fix Rx read_storage example

* [Docs] use pairwise together with startWith in the Rx balance_change example

* [Docs] Wording & little less code

* [Docs] Added whitespace

* [Docs] Use switchMap instead fo subscribe inside subscribe syntax

* [Docs] Fixed import syntax for RxJs examples

* [Docs] removed provider

* [Docs] WIP read storage make-over

* [Docs] update Rx read_storage

* [Docs] Read storage example with piped switchMap()

* [Docs] Turn null into observable

* [Docs] Read storage example added 2nd version using tap()

* [Docs] fixed name typo

* [Docs] removed tap() example
This commit is contained in:
Stefanie Doll
2019-01-22 11:47:27 +01:00
committed by Amaury Martiny
parent 187eae8c81
commit 2433d8d1fc
45 changed files with 692 additions and 2175 deletions
+12 -2
View File
@@ -16,16 +16,26 @@
- [Events (runtime)](METHODS_EVENTS.md)
## Examples
- [ApiPromise](examples/promise/README.md)
- [Simple connect](examples/promise/01_simple_connect/README.md)
- [Listen to blocks](examples/promise/02_listen_to_blocks/README.md)
- [Listen to balance change](examples/promise/03_listen_to_balance_change/README.md)
- [Unsubscribe from listening](examples/promise/04_unsubscribe/README.md)
- [Read chain state](examples/promise/05_read_storage/README.md)
- [Make a transfer](examples/promise/07_transfer_dots/README.md)
- [Make a transfer](examples/promise/06_make_transfer/README.md)
- [Display system events](examples/promise/08_system_events/README.md)(
- [Transaction with events](examples/promise/09_transfer_events/README.md)
- [Upgrade via sudo](examples/promise/10_upgrade_chain/README.md)
- [ApiRx](examples/rx/README.md)
- [Simple connect](examples/rx/01_simple_connect/README.md)
- [Listen to blocks](examples/rx/02_listen_to_blocks/README.md)
- [Listen to balance change](examples/rx/03_listen_to_balance_change/README.md)
- [Unsubscribe from listening](examples/rx/04_unsubscribe/README.md)
- [Read chain state](examples/rx/05_read_storage/README.md)
- [Make a transfer](examples/rx/06_make_transfer/README.md)
- [Display system events](examples/rx/08_system_events/README.md)(
- [Transaction with events](examples/rx/09_transfer_events/README.md)
- [Upgrade via sudo](examples/rx/10_upgrade_chain/README.md)
<!-- These are hidden, allowing HTML generation but does not appear in the sidebar -->
+11 -12
View File
@@ -30,12 +30,12 @@ api.rpc.chain.subscribeNewHead().subscribe((header) => {
});
```
Subscribing to chain state -
```javascript
import { combineLatest } from 'rxjs';
import { combineLatest, switchMap } from 'rxjs';
import { ApiRx } from '@polkadot/api';
import { WsProvider } from '@polkadot/rpc-provider';
@@ -54,18 +54,18 @@ new ApiRx(provider)
api.query.timestamp.blockPeriod(),
api.query.timestamp.now()
])
)
.subscribe(([blockPeriod, timestamp]) => {
const elapsed = last
? `, ${timestamp.toNumber() - last}s since last`
: '';
)
.subscribe(([blockPeriod, timestamp]) => {
const elapsed = last
? `, ${timestamp.toNumber() - last}s since last`
: '';
last = timestamp.toNumber();
console.log(`timestamp ${timestamp}${elapsed} (${blockPeriod}s target)`);
});
last = timestamp.toNumber();
console.log(`timestamp ${timestamp}${elapsed} (${blockPeriod}s target)`);
}));
```
Submitting a transaction -
@@ -432,4 +432,3 @@ Api.create().subscribe((api) => {
**Returns:** `Observable`<[ApiRx](_rx_index_.apirx.md)>
___
@@ -1,5 +1,5 @@
# Simple Connect
The following example shows how to instantiate a Polkadot API object and use it to connect to a node.
The following example shows how to instantiate a Polkadot API object and use it to connect to a node using ApiPromise.
[include](index.js)
@@ -1,5 +1,4 @@
# Listen to new blocks
This example shows how to subscribe to new blocks.
It displays the block number every time a new block is seen by the node you are connected to.
@@ -10,13 +10,9 @@ async function main () {
// Subscribe to the new headers on-chain. The callback is fired when new headers
// are found, the call itself returns a promise with a subscription that can be
// used to unsubscribe from the newHead subscription
const subscriptionId = await api.rpc.chain.subscribeNewHead((header) => {
console.log(`best #${header.blockNumber}`);
const unsubscribe = await api.rpc.chain.subscribeNewHead((header) => {
console.log(`Chain is at block: #${header.blockNumber}`);
});
// Id for the subscription, we can cleanup and unsubscribe via
// `api.chain.newHead.unsubscribe(subscriptionId)`
console.log(`subsciptionId: ${subscriptionId}`);
}
main().catch(console.error);
@@ -1,4 +1,4 @@
// Import the Api
// Import the API
const { ApiPromise } = require('@polkadot/api');
// Known account we want to use (available on dev chain, with funds)
@@ -12,7 +12,7 @@ async function main () {
// that resolves to the current on-chain value
let previous = await api.query.balances.freeBalance(Alice);
console.log(`${Alice} has a ${previous} balance`);
console.log(`${Alice} has a balance of ${previous}`);
console.log(`You may leave this example running and start example 06 or transfer any value to ${Alice}`);
// Here we subscribe to any balance changes and update the on-screen value
@@ -22,13 +22,10 @@ async function main () {
// Only display positive value changes (Since we are pulling `previous` above already,
// the initial balance change will also be zero)
if (change.isZero()) {
return;
if (!change.isZero()) {
previous = current;
console.log(`New balance change of: ${change}`);
}
previous = current;
console.log(`Balance of ${Alice}: ${current}, ${change} change`);
});
}
@@ -0,0 +1,7 @@
# Unsubscribe from listening to updates
This example shows how to subscribe to and later unsubscribe from listening to block updates.
In this example we're calling the built-in unsubscribe() function after a timeOut of 20s to cleanup and unsubscribe from listening to updates.
[include](index.js)
@@ -0,0 +1,22 @@
// Import the API
const { ApiPromise } = require('@polkadot/api');
async function main () {
// Create a new instance of the api
const api = await ApiPromise.create();
// Subscribe to chain updates and log the current block number on update.
const unsubscribe = await api.rpc.chain.subscribeNewHead((header) => {
console.log(`Chain is at block: #${header.blockNumber}`);
});
// In this example we're calling the unsubscribe() function that is being
// returned by the api call function after 20s.
setTimeout(() => {
unsubscribe();
console.log('Unsubscribed')
}, 20000);
}
main().catch(console.error);
@@ -0,0 +1,18 @@
{
"name": "02_listen_to_blocks",
"version": "0.2.0",
"description": "Example showing how to use subscriptions",
"main": "index.js",
"author": "chevdor",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
+13 -10
View File
@@ -18,17 +18,20 @@ async function main () {
console.log(`accountNonce(${Alice}) ${accountNonce}`);
console.log(`blockPeriod ${blockPeriod.toNumber()} seconds`);
// Retrieve the balances for all validators
const validatorBalances = await Promise.all(
validators.map((authorityId) =>
api.query.balances.freeBalance(authorityId)
)
);
if (validators && validators.length > 0) {
// Retrieve the balances for all validators
const validatorBalances = await Promise.all(
validators.map(authorityId =>
api.query.balances.freeBalance(authorityId)
)
);
console.log('validators', validators.map((authorityId, index) => ({
address: authorityId.toString(),
balance: validatorBalances[index].toString()
})));
// Print out the authorityIds and balances of all validators
console.log('validators', validators.map((authorityId, index) => ({
address: authorityId.toString(),
balance: validatorBalances[index].toString()
})));
}
}
main().catch(console.error).finally(_ => process.exit());
@@ -1,4 +1,4 @@
# Tranfer DOTs
# Make a simple transfer
This sample shows how to create a transaction to make a transfer from one an account to another.
@@ -24,13 +24,14 @@ async function main () {
// here we split it out for the sake of readability
const transfer = api.tx.balances.transfer(BOB_ADDR, 12345);
// Sign the transaction using our account
transfer.sign(alice, aliceNonce);
// Send the transaction and retrieve the resulting Hash
const hash = await transfer.send();
console.log(`transfer 12345 to Bob with hash ${hash}`);
// Sign and send the transaction using our account. Send the transaction and retrieve the resulting Hash
transfer.signAndSend(alice, ({ status, type }) => {
if (type === 'Finalised') {
console.log(`Successful transfer of 12345 from Alice to Bob with hash ${status.asFinalised.toHex()}`);
} else {
console.log(`Transaction status: ${type}`);
}
});
}
main().catch(console.error).finally(_ => process.exit());
@@ -1,5 +1,5 @@
{
"name": "07_transfer_dots",
"name": "06_make_transfer",
"version": "0.2.0",
"description": "Example showing how to transfer DOTs",
"main": "index.js",
File diff suppressed because it is too large Load Diff
@@ -13,6 +13,8 @@ const AMOUNT = 10000;
async function main () {
// create an instance of our testign keyring
// If you're using ES6 module imports instead of require, just change this line to:
// const keyring = testKeyring();
const keyring = testKeyring.default();
// Create the API and wait until ready
@@ -37,7 +39,7 @@ async function main () {
console.log('Transaction status:', type);
if (type === 'Finalised') {
console.log('Completed at block hash', status.value.toHex());
console.log('Completed at block hash', status.asFinalised.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
@@ -5,9 +5,6 @@ const { WsProvider } = require('@polkadot/rpc-provider');
// import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
const testKeyring = require('@polkadot/keyring/testing');
// utility functions
const { compactAddLength, hexToU8a } = require('@polkadot/util');
const fs = require('fs');
async function main () {
@@ -38,14 +35,13 @@ async function main () {
// preform the actual chain upgrade via the sudo module
api.tx.sudo
.sudo(proposal)
.sign(adminPair, adminNonce)
.send(({ events = [], status, type }) => {
console.log('Transaction status:', type);
.signAndSend(adminPair, ({ events = [], status, type }) => {
console.log('Proposal status:', type);
if (type === 'Finalised') {
console.error('You have just upgraded your chain');
console.log('Completed at block hash', status.value.toHex());
console.log('Completed at block hash', status.asFinalised.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
@@ -0,0 +1,5 @@
# Simple Connect
The following example shows how to instantiate a Polkadot API object and use it to connect to a node using ApiRx.
[include](index.js)
@@ -0,0 +1,26 @@
// Required imports
const { zip } = require('rxjs');
const { ApiRx } = require('@polkadot/api');
const { WsProvider } = require('@polkadot/rpc-provider');
function main () {
// Initialise the provider to connect to the local node
const provider = new WsProvider('ws://127.0.0.1:9944');
// Create the API and wait until ready
const api = await ApiRx.create(provider).toPromise();
// We're using RxJs 'zip()' combination operator to get the emitted values
// of multiple observables as an array
zip(
api.rpc.system.chain(),
api.rpc.system.name(),
api.rpc.system.version()
)
// Then we subscribe to the result
.subscribe(([chain, nodeName, nodeVersion]) => {
console.log(`You are connected to chain ${chain} using ${nodeName} v${nodeVersion}`);
});
}
main().catch(console.error).finally(() => process.exit());
@@ -0,0 +1,20 @@
{
"name": "01_simple_connect",
"version": "0.2.0",
"description": "Example showing how to connect using a WebSocket",
"main": "index.js",
"author": "Stefie",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6",
"@polkadot/rpc-provider": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,9 @@
# Listen to new blocks
This example shows how to subscribe to new blocks.
It displays the block number every time a new block is seen by the node you are connected to.
NOTE: The example runs until you stop it with CTRL+C
[include](index.js)
@@ -0,0 +1,19 @@
// Import the API
const { ApiRx } = require('@polkadot/api');
const { switchMap } = require('rxjs/operators');
async function main () {
// Here we don't pass the (optional) provider, connecting directly to the default
// node/port, i.e. `ws://127.0.0.1:9944`. Await for the isReady promise to ensure
// the API has connected to the node and completed the initialisation process
new ApiRx().isReady
.pipe(
switchMap((api) =>
api.rpc.chain.subscribeNewHead()
))
.subscribe((header) => {
console.log(`Chain is at block: #${header.blockNumber}`);
});
}
main().catch(console.error);
@@ -0,0 +1,18 @@
{
"name": "02_listen_to_blocks",
"version": "0.2.0",
"description": "Example showing how to use subscriptions",
"main": "index.js",
"author": "Stefie",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,5 @@
# Listen to balance changes
This example shows how to instantiate a Polkadot API object and use it to connect to a node and retrieve balance updates.
[include](index.js)
@@ -0,0 +1,38 @@
// Import the API and operators from RxJs
const { ApiRx } = require('@polkadot/api');
const { pairwise, startWith } = require('rxjs/operators');
// Known account we want to use (available on dev chain, with funds)
const Alice = '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDtZ';
async function main () {
// Create an await for the API
const api = await ApiRx.create().toPromise();
// Here we subscribe to any balance changes and update the on-screen value.
// We're using RxJs pairwise() operator to get the previous and current values as an array.
api.query.balances.freeBalance(Alice)
.pipe(
// since pairwise only starts emitting values on the second emission, we prepend an
// initial value with the startWith() operator to be able to also receive the first value
startWith('first'),
pairwise()
)
.subscribe((balance) => {
if (balance[0] === 'first') {
// Now we know that if the previous value emitted as balance[0] is `first`,
// then balance[1] is the initial value of Alice account.
console.log(`<b>Alice</b> ${Alice} has a balance of ${balance[1]}`);
console.log('You may leave this example running and start the "Make a transfer" example or transfer any value to Alice address');
return;
}
const change = balance[1].sub(balance[0]);
// Only display value changes
if (!change.isZero()) {
console.log(`New balance change of: ${change}`);
}
});
}
main().catch(console.error);
@@ -0,0 +1,18 @@
{
"name": "03_listen_to_balance_change",
"version": "0.2.0",
"description": "Example showing how to subscribe to balance change",
"main": "index.js",
"author": "Stefie",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,7 @@
# Unsubscribe from listening to updates
This example shows how to subscribe to and later unsubscribe from listening to block updates.
In this example we're calling the built-in unsubscribe() function after a timeOut of 20s to cleanup and unsubscribe from listening to updates.
[include](index.js)
+25
View File
@@ -0,0 +1,25 @@
// Import the API
const { ApiRx } = require('@polkadot/api');
const { switchMap } = require('rxjs/operators');
async function main () {
// Create a new instance of the api
// Subscribe to chain updates and log the current block number on update.
const subscription = new ApiRx().isReady
.pipe(
switchMap((api) =>
api.rpc.chain.subscribeNewHead()
))
.subscribe((header) => {
console.log(`Chain is at block: #${header.blockNumber}`);
});
// In this example we're calling the Overvables unsubscribe() //
// function after 20s.
setTimeout(() => {
subscription.unsubscribe();
console.log('Unsubscribed');
}, 20000);
}
main().catch(console.error);
@@ -0,0 +1,18 @@
{
"name": "02_listen_to_blocks",
"version": "0.2.0",
"description": "Example showing how to use subscriptions",
"main": "index.js",
"author": "Stefie",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,5 @@
# Read storage
Many important variables are available through the storage API. This example shows how to call a few of those APIs.
[include](index.js)
+51
View File
@@ -0,0 +1,51 @@
// Import the API
const { ApiRx } = require('@polkadot/api');
// Import dependencies from RxJs
const { combineLatest, of, tap } = require('rxjs');
const { first, switchMap } = require('rxjs/operators');
// Our address for Alice on the dev chain
const Alice = '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDtZ';
function main () {
// Create our API with a default connection to the local node
new ApiRx(provider).isReady
.pipe(
// Here we ake our basic chain state/storage queries
switchMap((api) => combineLatest(
of(api),
api.query.session.validators().pipe(first())
)),
switchMap(([api, validators]) => {
// In the next step, we're checking if the node has active validators.
// If it does, we're making another call to the api to get the balances for all validators
const balances = (validators && validators.length > 0)
? combineLatest(validators.map(authorityId => api.query.balances.freeBalance(authorityId).pipe(first())))
: of(null);
// We're combining the results together with the emitted value 'validators',
// which we're turning back into an observable using of()
return combineLatest(
api.query.system.accountNonce(Alice).pipe(first()),
api.query.timestamp.blockPeriod().pipe(first()),
of(validators),
balances
);
})
)
// Then we're subscribing to the emitted results
.subscribe(([accountNonce, blockPeriod, validators, validatorBalances]) => {
console.log(`accountNonce(${Alice}) ${accountNonce}`);
console.log(`blockPeriod ${blockPeriod.toNumber()} seconds`);
if (validatorBalances) {
// And lastly we print out the authorityIds and balances of all validators
console.log('validators', validators.map((authorityId, index) => ({
address: authorityId.toString(),
balance: validatorBalances[index].toString()
})));
}
});
}
main().catch(console.error).finally(_ => process.exit());
@@ -0,0 +1,18 @@
{
"name": "05_read_storage",
"version": "0.2.0",
"description": "Example showing how to query storage",
"main": "index.js",
"author": "Stefie",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,5 @@
# Make a simple transfer
This sample shows how to create a transaction to make a transfer from one an account to another.
[include](index.js)
@@ -0,0 +1,35 @@
// Import the API, Keyring and some utility functions
const { ApiPromise } = require('@polkadot/api');
const { Keyring } = require('@polkadot/keyring');
const { stringToU8a } = require('@polkadot/util');
const ALICE_SEED = 'Alice'.padEnd(32, ' ');
const BOB_ADDR = '5Gw3s7q4QLkSWwknsiPtjujPv3XM4Trxi5d4PgKMMk3gfGTE';
async function main () {
// Create an instance of the keyring
const keyring = new Keyring();
// Add Alice to our keyring (with the known seed for the account)
const alice = keyring.addFromSeed(stringToU8a(ALICE_SEED));
// Instantiate the API
const api = await ApiRx.create().toPromise();
// Create a extrinsic, transferring 12345 units to Bob.
api.tx.balances
// create transfer
.transfer(BOB, randomAmount)
// Sign and send the transcation
.signAndSend(alice)
// Subscribe to the status updates of the transfer
.subscribe(({ status, type }) => {
if (type === 'Finalised') {
console.log(`Successful transfer of 12345 from Alice to Bob with hash ${status.asFinalised.toHex()}`);
} else {
console.log(`Staus of transfer: ${type}`);
}
});
}
main().catch(console.error).finally(_ => process.exit());
@@ -0,0 +1,18 @@
{
"name": "06_make_transfer",
"version": "0.2.0",
"description": "Example showing how to transfer DOTs",
"main": "index.js",
"author": "Stefie",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,5 @@
# Traverse events
Query the system events and extract information from them. This example runs until exited via Ctrl-C
[include](index.js)
@@ -0,0 +1,37 @@
// Import the API and selected RxJs operators
const { switchMap } = require('rxjs/operators');
const { ApiRx } = require('@polkadot/api');
async function main () {
// Create our API with a default connection to the local node
ApiRx.create()
.pipe(
switchMap((api) =>
// subscribe to system events via storage
api.query.system.events()
))
// Then we're subscribing to the emitted results
.subscribe((events) => {
console.log(`\nReceived ${events.length} events:`);
// loop through the Vec<EventRecord>
events.forEach((record) => {
// extract the phase, event and the event types
const { event, phase } = record;
const types = event.typeDef;
// show what we are busy with
console.log(`\t${event.section}:${event.method}:: (phase=${phase.toString()})`);
console.log(`\t\t${event.meta.documentation.toString()}`);
// loop through each of the parameters, displaying the type and data
event.data.forEach((data, index) => {
console.log(`\t\t\t${types[index].type}: ${data.toString()}`);
});
});
});
};
main().catch((error) => {
console.error(error);
process.exit(-1);
});
@@ -0,0 +1,18 @@
{
"name": "08_system_events",
"version": "0.1.0",
"description": "Example showing how to query and parse events",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,5 @@
# Transfer events
Display the events that occur during a transfer by sending a value to a random account
[include](index.js)
@@ -0,0 +1,54 @@
// Import the API and some utility functions
const { ApiRx } = require('@polkadot/api');
// import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
const testKeyring = require('@polkadot/keyring/testing');
// utility function for random values
const { randomAsU8a } = require('@polkadot/util-crypto');
// some constants we are using in this sample
const ALICE = '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDtZ';
const AMOUNT = 10000;
async function main () {
// create an instance of our testign keyring
// If you're using ES6 module imports instead of require, just change this line to:
// const keyring = testKeyring();
const keyring = testKeyring.default();
// Create our API with a connection to the node
const api = await ApiRx.create().toPromise();
// find the actual keypair in the keyring
const alicePair = keyring.getPair(ALICE);
// create a new random recipient
const recipient = keyring.addFromSeed(randomAsU8a(32)).address();
console.log('Sending', AMOUNT, 'from', alicePair.address(), 'to', recipient);
// get the nonce for the admin key
// Create a extrinsic, transferring 12345 units to Bob.
api.tx.balances
// Do the transfer
.transfer(recipient, AMOUNT)
// Sign and send it
.signAndSend(alicePair)
// And subscribe to the actual status
.subscribe(({ events = [], status, type }) => {
// Log transfer events
console.log('Transfer status:', type);
// Log system events once the transfer is finalised
if (type === 'Finalised') {
console.log('Completed at block hash', status.asFinalised.toHex());
console.log('Events:');
events.forEach(({ phase, event: { data, method, section } }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
}
});
}
main().catch(console.error);
@@ -0,0 +1,18 @@
{
"name": "09_transfer_events",
"version": "0.1.0",
"description": "Example showing how to transfer DOTs (with events)",
"main": "index.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
@@ -0,0 +1,5 @@
# Chain upgrade
Performs a chain upgrade using the `sudo` module. This may brick your chain, so us it as an educational sample. (use `substrate --dev purge-chain` to remove DB and recover).
[include](index.js)
@@ -0,0 +1,59 @@
// Import the API & Provider and some utility functions
const { ApiRx } = require('@polkadot/api');
const { WsProvider } = require('@polkadot/rpc-provider');
// import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
const testKeyring = require('@polkadot/keyring/testing');
const fs = require('fs');
async function main () {
// Initialise the provider to connect to the local node
const provider = new WsProvider('ws://127.0.0.1:9944');
// Create the API and wait until ready (optional provider passed through)
const api = await ApiRx.create(provider).toPromise();
// retrieve the upgrade key from the chain state
const adminId = await api.query.sudo.key().toPromise();
// find the actual keypair in the keyring (if this is an changed value, the key
// needs to be added to the keyring before - this assumes we have defaults, i.e.
// Alice as the key - and this already exists on the test keyring)
const keyring = testKeyring.default();
const adminPair = keyring.getPair(adminId.toString());
// retrieve the runtime to upgrade to
const code = fs.readFileSync('./test.wasm').toString('hex');
const proposal = api.tx.consensus.setCode(`0x${code}`);
console.log(`Upgrading chain runtime from ${adminId}`);
api.tx.sudo
// preform the actual chain upgrade via the sudo module
.sudo(proposal)
// sign and send the proposal
.signAndSend(adminPair)
// subscribe to overall result
.subscribe(({ events = [], status, type }) => {
// Log transfer events
console.log('Proposal status:', type);
if (type === 'Finalised') {
console.error('You have just upgraded your chain');
console.log('Completed at block hash', status.asFinalised.toHex());
console.log('Events:');
// Log system events once the chain update is finalised
events.forEach(({ phase, event: { data, method, section } }) => {
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
});
process.exit(0);
}
});
}
main().catch((error) => {
console.error(error);
process.exit(-1);
});
@@ -0,0 +1,18 @@
{
"name": "10_upgrade_chain",
"version": "0.2.0",
"description": "Example showing how to upgrade via upgradeKey",
"main": "index.js",
"author": "Stefie",
"license": "MIT",
"scripts": {
"clean": "rimraf node_modules",
"start": "node index.js"
},
"dependencies": {
"@polkadot/api": "^0.38.6"
},
"devDependencies": {
"rimraf": "^2.6.2"
}
}
Binary file not shown.
+26
View File
@@ -0,0 +1,26 @@
# ApiPromise Examples
Here you will find a list of examples that takes you through the basics of connecting to a local node, retrieving data from the Node and chain and execute transactions on the chain. It uses the [[ApiRx]] interface.
## Prerequisites
For the following examples, you need a local node. It is usually convenient testing with:
```
substrate --dev
```
## Running the examples
From each folder, run `yarn` to install the required dependencies and then run `yarn start` to execute the example against the running node.
## Development accounts
Some of the examples use the following accounts:
- Alice: `5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDtZ`
- Bob: `5Gw3s7q4QLkSWwknsiPtjujPv3XM4Trxi5d4PgKMMk3gfGTE`
Those accounts are easy to add if you don't have/see them. The seed of Alice's account is `Alice␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣` and the seed of Bob is... well you guess...
NOTE: Note the spaces padding Alice's key up to 32 chars.