diff --git a/docs/examples/promise/01_simple_connect/package.json b/docs/examples/promise/01_simple_connect/package.json new file mode 100644 index 0000000000..5ab5faf386 --- /dev/null +++ b/docs/examples/promise/01_simple_connect/package.json @@ -0,0 +1,19 @@ +{ + "name": "01_simple_connect", + "version": "0.2.0", + "description": "Example showing how to connect using a WebSocket", + "main": "index.js", + "author": "chevdor", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + + "dependencies": { + "@polkadot/api": "^0.45.14" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/promise/03_listen_to_balance_change/index.js b/docs/examples/promise/03_listen_to_balance_change/index.js new file mode 100755 index 0000000000..fb04323f6d --- /dev/null +++ b/docs/examples/promise/03_listen_to_balance_change/index.js @@ -0,0 +1,33 @@ +// @ts-check +// Import the API +const { ApiPromise } = require('@polkadot/api'); + +// 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 ApiPromise.create(); + + // Retrieve the initial balance. Since the call has no callback, it is simply a promise + // that resolves to the current on-chain value + let previous = await api.query.balances.freeBalance(Alice); + + 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 + api.query.balances.freeBalance(Alice, (current) => { + // Calculate the delta + const change = current.sub(previous); + + // Only display positive value changes (Since we are pulling `previous` above already, + // the initial balance change will also be zero) + if (!change.isZero()) { + previous = current; + console.log(`New balance change of: ${change}`); + } + }); +} + +main().catch(console.error); diff --git a/docs/examples/promise/03_listen_to_balance_change/package.json b/docs/examples/promise/03_listen_to_balance_change/package.json new file mode 100644 index 0000000000..a3c743bb9f --- /dev/null +++ b/docs/examples/promise/03_listen_to_balance_change/package.json @@ -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": "chevdor", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.45.14" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/promise/05_read_storage/index.js b/docs/examples/promise/05_read_storage/index.js new file mode 100755 index 0000000000..67a2544fcb --- /dev/null +++ b/docs/examples/promise/05_read_storage/index.js @@ -0,0 +1,38 @@ +// @ts-check +// Import the API +const { ApiPromise } = require('@polkadot/api'); + +// Our address for Alice on the dev chain +const Alice = '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDtZ'; + +async function main () { + // Create our API with a default connection to the local node + const api = await ApiPromise.create(); + + // Make our basic chain state/storage queries, all in one go + const [accountNonce, blockPeriod, validators] = await Promise.all([ + api.query.system.accountNonce(Alice), + api.query.timestamp.blockPeriod(), + api.query.session.validators() + ]); + + console.log(`accountNonce(${Alice}) ${accountNonce}`); + console.log(`blockPeriod ${blockPeriod.toNumber()} seconds`); + + if (validators && validators.length > 0) { + // Retrieve the balances for all validators + const validatorBalances = await Promise.all( + validators.map(authorityId => + api.query.balances.freeBalance(authorityId) + ) + ); + + // 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()); diff --git a/docs/examples/promise/05_read_storage/package.json b/docs/examples/promise/05_read_storage/package.json new file mode 100644 index 0000000000..2135ab5ed1 --- /dev/null +++ b/docs/examples/promise/05_read_storage/package.json @@ -0,0 +1,18 @@ +{ + "name": "05_read_storage", + "version": "0.2.0", + "description": "Example showing how to query storage", + "main": "index.js", + "author": "chevdor", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.45.14" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/promise/06_make_transfer/index.js b/docs/examples/promise/06_make_transfer/index.js new file mode 100755 index 0000000000..ac940e2cf5 --- /dev/null +++ b/docs/examples/promise/06_make_transfer/index.js @@ -0,0 +1,31 @@ +// @ts-check +// Import the API, Keyring and some utility functions +const { ApiPromise } = require('@polkadot/api'); +const { Keyring } = require('@polkadot/keyring'); +const { stringToU8a } = require('@polkadot/util'); + +// Important to note that we pad the seed to a length of 32 bytes using ' ' +// The underlying seed needs to be exactly 32 bytes in length +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 ApiPromise.create(); + + // Create a extrinsic, transferring 12345 units to Bob + const transfer = api.tx.balances.transfer(BOB_ADDR, 12345); + + // Sign and send the transaction using our account + const hash = await transfer.signAndSend(alice); + + console.log('Transfer sent with hash', hash.toHex()); +} + +main().catch(console.error).finally(() => process.exit()); diff --git a/docs/examples/promise/06_make_transfer/package.json b/docs/examples/promise/06_make_transfer/package.json new file mode 100644 index 0000000000..fe35dda333 --- /dev/null +++ b/docs/examples/promise/06_make_transfer/package.json @@ -0,0 +1,18 @@ +{ + "name": "06_make_transfer", + "version": "0.2.0", + "description": "Example showing how to make a transfer", + "main": "index.js", + "author": "chevdor", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.45.14" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/promise/08_system_events/package.json b/docs/examples/promise/08_system_events/package.json new file mode 100644 index 0000000000..ee420fcc04 --- /dev/null +++ b/docs/examples/promise/08_system_events/package.json @@ -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 ", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.45.14" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/promise/09_transfer_events/index.js b/docs/examples/promise/09_transfer_events/index.js new file mode 100755 index 0000000000..13bbec4c5b --- /dev/null +++ b/docs/examples/promise/09_transfer_events/index.js @@ -0,0 +1,55 @@ +// @ts-check +// Import the API & Provider and some utility functions +const { ApiPromise } = 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 the API and wait until ready + const api = await ApiPromise.create(); + + // get the nonce for the admin key + const nonce = await api.query.system.accountNonce(ALICE); + + // 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, 'with nonce', nonce.toString()); + + // Do the transfer and track the actual status + api.tx.balances + .transfer(recipient, AMOUNT) + .sign(alicePair, { nonce }) + .send(({ events = [], status, type }) => { + console.log('Transaction status:', type); + + 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()); + }); + + process.exit(0); + } + }); +} + +main().catch(console.error); diff --git a/docs/examples/promise/09_transfer_events/package.json b/docs/examples/promise/09_transfer_events/package.json new file mode 100644 index 0000000000..483e77bf25 --- /dev/null +++ b/docs/examples/promise/09_transfer_events/package.json @@ -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 ", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.45.14" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/promise/10_upgrade_chain/index.js b/docs/examples/promise/10_upgrade_chain/index.js new file mode 100755 index 0000000000..1a6ddc47d0 --- /dev/null +++ b/docs/examples/promise/10_upgrade_chain/index.js @@ -0,0 +1,56 @@ +// @ts-check +// Import the API & Provider and some utility functions +const { ApiPromise, WsProvider } = require('@polkadot/api'); + +// 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 ApiPromise.create(provider); + + // retrieve the upgrade key from the chain state + const adminId = await api.query.sudo.key(); + + // 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 from ${adminId}, ${code.length / 2} bytes`); + + // preform the actual chain upgrade via the sudo module + api.tx.sudo + .sudo(proposal) + .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.asFinalised.toHex()); + console.log('Events:'); + + 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); +}); diff --git a/docs/examples/promise/10_upgrade_chain/package.json b/docs/examples/promise/10_upgrade_chain/package.json new file mode 100644 index 0000000000..73b58862f5 --- /dev/null +++ b/docs/examples/promise/10_upgrade_chain/package.json @@ -0,0 +1,18 @@ +{ + "name": "10_upgrade_chain", + "version": "0.2.0", + "description": "Example showing how to upgrade via upgradeKey", + "main": "index.js", + "author": "Jaco Greeff ", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.45.14" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/01_simple_connect/package.json b/docs/examples/rx/01_simple_connect/package.json new file mode 100644 index 0000000000..e754832f74 --- /dev/null +++ b/docs/examples/rx/01_simple_connect/package.json @@ -0,0 +1,20 @@ +{ + "name": "rx_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.43.6", + "@polkadot/rpc-provider": "^0.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/02_listen_to_blocks/package.json b/docs/examples/rx/02_listen_to_blocks/package.json new file mode 100644 index 0000000000..d8dcce992c --- /dev/null +++ b/docs/examples/rx/02_listen_to_blocks/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_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.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/03_listen_to_balance_change/index.js b/docs/examples/rx/03_listen_to_balance_change/index.js new file mode 100644 index 0000000000..fd030d6424 --- /dev/null +++ b/docs/examples/rx/03_listen_to_balance_change/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(`Alice ${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); diff --git a/docs/examples/rx/03_listen_to_balance_change/package.json b/docs/examples/rx/03_listen_to_balance_change/package.json new file mode 100644 index 0000000000..58859f1a80 --- /dev/null +++ b/docs/examples/rx/03_listen_to_balance_change/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_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.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/04_unsubscribe/package.json b/docs/examples/rx/04_unsubscribe/package.json new file mode 100644 index 0000000000..a8a685fc30 --- /dev/null +++ b/docs/examples/rx/04_unsubscribe/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_04_unsubscribe", + "version": "0.2.0", + "description": "Example showing how to unsubscribe from a subscription", + "main": "index.js", + "author": "Stefie", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/05_read_storage/index.js b/docs/examples/rx/05_read_storage/index.js new file mode 100644 index 0000000000..642f8a09ea --- /dev/null +++ b/docs/examples/rx/05_read_storage/index.js @@ -0,0 +1,51 @@ +// Import the API +const { ApiRx } = require('@polkadot/api'); +// Import dependencies from RxJs +const { combineLatest, of } = 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()); diff --git a/docs/examples/rx/05_read_storage/package.json b/docs/examples/rx/05_read_storage/package.json new file mode 100644 index 0000000000..1486b9ad4a --- /dev/null +++ b/docs/examples/rx/05_read_storage/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_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.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/06_make_transfer/index.js b/docs/examples/rx/06_make_transfer/index.js new file mode 100644 index 0000000000..90fd1c1401 --- /dev/null +++ b/docs/examples/rx/06_make_transfer/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()); diff --git a/docs/examples/rx/06_make_transfer/package.json b/docs/examples/rx/06_make_transfer/package.json new file mode 100644 index 0000000000..98958f22a4 --- /dev/null +++ b/docs/examples/rx/06_make_transfer/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_06_make_transfer", + "version": "0.2.0", + "description": "Example showing how to make a transfer", + "main": "index.js", + "author": "Stefie", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/08_system_events/package.json b/docs/examples/rx/08_system_events/package.json new file mode 100644 index 0000000000..1e06ff4c38 --- /dev/null +++ b/docs/examples/rx/08_system_events/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_08_system_events", + "version": "0.1.0", + "description": "Example showing how to query and parse events", + "main": "index.js", + "author": "Stefie", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/09_transfer_events/index.js b/docs/examples/rx/09_transfer_events/index.js new file mode 100644 index 0000000000..5a5d197c7c --- /dev/null +++ b/docs/examples/rx/09_transfer_events/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); diff --git a/docs/examples/rx/09_transfer_events/package.json b/docs/examples/rx/09_transfer_events/package.json new file mode 100644 index 0000000000..18b64d99a6 --- /dev/null +++ b/docs/examples/rx/09_transfer_events/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_09_transfer_events", + "version": "0.1.0", + "description": "Example showing how to transfer DOTs (with events)", + "main": "index.js", + "author": "Stefie", + "license": "MIT", + "scripts": { + "clean": "rimraf node_modules", + "start": "node index.js" + }, + "dependencies": { + "@polkadot/api": "^0.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/docs/examples/rx/10_upgrade_chain/index.js b/docs/examples/rx/10_upgrade_chain/index.js new file mode 100644 index 0000000000..818756ad9d --- /dev/null +++ b/docs/examples/rx/10_upgrade_chain/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); +}); diff --git a/docs/examples/rx/10_upgrade_chain/package.json b/docs/examples/rx/10_upgrade_chain/package.json new file mode 100644 index 0000000000..98db317df4 --- /dev/null +++ b/docs/examples/rx/10_upgrade_chain/package.json @@ -0,0 +1,18 @@ +{ + "name": "rx_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.43.6" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +}