Remove balances.freeBalance & system.accountNonce refs (#1847)

* Remove freeBalance references

* Cleanup placeholders

* Add substrate templates to .gitignore

* Swap all use of system.accountNonce

* typo
This commit is contained in:
Jaco Greeff
2020-02-14 13:52:45 +01:00
committed by GitHub
parent 679e31668e
commit 5c4920db6f
31 changed files with 95 additions and 1703 deletions
+6 -10
View File
@@ -16,24 +16,20 @@ const ADDR = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE';
// Retrieve the last timestamp
const now = await api.query.timestamp.now();
// Retrieve the account nonce via the system module
const nonce = await api.query.system.accountNonce(ADDR);
// Retrieve the account balance & nonce via the system module
const [nonce, balance] = await api.query.system.account(ADDR);
// Retrieve the account balance via the balances module
const balance = await api.query.balances.freeBalance(ADDR);
console.log(`${now}: balance of ${balance} and a nonce of ${nonce}`);
console.log(`${now}: balance of ${balance.free} and a nonce of ${nonce}`);
```
There have been some additions in the code above comparing with retrieving runtime constants. In these cases, since we are making a query to the actual chain, we use the `await` syntax to retrieve the information. Since the API is Promise-based, this means we can also rewrite the above to follow a Promise pattern,
```js
...
// Retrieve last block timestamp, account nonce & balance
const [now, nonce, balance] = await Promise.all([
// Retrieve last block timestamp, account nonce & balances
const [now, [nonce, balances]] = await Promise.all([
api.query.timestamp.now(),
api.query.system.accountNonce(ADDR),
api.query.balances.freeBalance(ADDR)
api.query.system.account(ADDR)
]);
```
+10 -11
View File
@@ -10,14 +10,14 @@ Where possible, the use of multi queries are encouraged since it tracks a number
...
// Subscribe to balance changes for 2 accounts, ADDR1 & ADDR2 (already defined)
const unsub = await api.query.balances.freeBalance.multi([ADDR1, ADDR2], (balances) => {
const [balance1, balance2] = balances;
const unsub = await api.query.system.account.multi([ADDR1, ADDR2], (balances) => {
const [[, balance1], [, balance2]] = balances;
console.log(`The balances are ${balance1} and ${balance2}`);
console.log(`The balances are ${balance1.free} and ${balance2.free}`);
});
```
A couple of items to note in the example above: we don't call `freeBalance` directly, but rather `freeBalance.multi`. We pass the addresses we want to query as an array, and the length thereof would depend on the number of addresses we want to query. As an extended example, we can track the balances of a list of validators,
A couple of items to note in the example above: we don't call `account` directly, but rather `account.multi`. We pass the addresses we want to query as an array, and the length thereof would depend on the number of addresses we want to query. As an extended example, we can track the balances of a list of validators,
```js
...
@@ -26,8 +26,8 @@ A couple of items to note in the example above: we don't call `freeBalance` dire
const validators = await api.query.session.validators();
// Subscribe to the balances for these accounts
const unsub = await api.query.balances.freeBalance.multi(validators, (balances) => {
console.log(`The balances are: ${balances}`);
const unsub = await api.query.balances.account.multi(validators, (balances) => {
console.log(`The nonce and free balances are: ${balances.map(([nonce, { free }]) => [nonce, free])}`);
});
```
@@ -43,17 +43,16 @@ The previous `.multi` examples assumes that we do queries for the same types, i.
// Subscribe to the timestamp, our index and balance
const unsub = await api.queryMulti([
api.query.timestamp.now,
[api.query.system.accountNonce, ADDR],
[api.query.balances.freeBalance, ADDR]
], ([now, nonce, balance]) => {
console.log(`${now}: balance of ${balance} and a nonce of ${nonce}`);
[api.query.system.account, ADDR]
], ([now, [nonce, balance]]) => {
console.log(`${now}: balance of ${balance.free} and a nonce of ${nonce}`);
});
```
The above example certainly does not quite look as ergonomic and clean, but the API needs to understand (a) which are all the calls we need to make and (b) the calls and their params (if required). So breaking it down -
- `api.query.timestamp.now` - the timestamp is passed naked without any params. Also note that we do not call it while passing, but rather only provides a reference to the function, i.e. we do not have the expected `()` at the end. (This could also be of the form `[api.query.timestamp.now]`, aligning with subsequent entries)
- `[api.query.system.accountNonce, ADDR]` - the nonce query is passed as an array containing the function (once again naked), followed by the parameters that apply.
- `[api.query.system.account, ADDR]` - the nonce & balance query is passed as an array containing the function (once again naked), followed by the parameters that apply.
## Rounding out queries
+8 -8
View File
@@ -13,13 +13,13 @@ Quite often is is useful (taking pruning into account, more on this later) to re
const lastHdr = await api.rpc.chain.getHeader();
// Retrieve the balance at both the current and the parent hashes
const [balanceNow, balancePrev] = await Promise.all([
api.query.balances.freeBalance.at(lastHdr.hash, ADDR),
api.query.balances.freeBalance.at(lastHdr.parentHash, ADDR)
const [[, balanceNow], [, balancePrev]] = await Promise.all([
api.query.system.account.at(lastHdr.hash, ADDR),
api.query.system.account.at(lastHdr.parentHash, ADDR)
]);
// Display the difference
console.log(`The delta was ${balanceNow.sub(balancePrev)}`);
console.log(`The delta was ${balanceNow.free.sub(balancePrev.free)}`);
```
In the above example, we introduce the `.at(<hash>[, ...params])` query. For all `.at` queries, the first parameter is always the block hash at which we want to make the query, in our example we use both the last retrieved block and the parent thereof. The params are optional as per the type of query made, for instance to retrieve the timestamp for a previous block, it would be -
@@ -44,8 +44,8 @@ In addition to using `api.query` to make actual on-chain queries, it can also be
// Retrieve the hash & size of the entry as stored on-chain
const [entryHash, entrySize] = await Promise.all([
api.query.balances.freeBalance.hash(ADDR),
api.query.balances.freeBalance.size(ADDR)
api.query.system.account.hash(ADDR),
api.query.system.account.size(ADDR)
]);
// Output the info
@@ -60,11 +60,11 @@ It has been explained that the `api.query` interfaces are decorated from the met
```js
// Extract the info
const { meta, method, section } = api.query.balances.freeBalance;
const { meta, method, section } = api.query.system.account;
// Display some info on a specific entry
console.log(`${section}.${method}: ${meta.documentation.join(' ')}`);
console.log(`query key: ${api.query.balances.freeBalance.key(ADDR)}`);
console.log(`query key: ${api.query.system.account.key(ADDR)}`);
```
The `section` & `method` is an indication of where it is exposed on the API. In addition the `meta` holds an array with the metadata documentation for the entry.
+2 -2
View File
@@ -25,8 +25,8 @@ If we had a query with parameters, i.e. where we wish to perform a query for a s
...
// Subscribe to balance changes for our account
const unsub = await api.query.balances.freeBalance(ADDR, (balance) => {
console.log(`Your account balance is ${balance}`);
const unsub = await api.query.system.account(ADDR, ([nonce, balance]) => {
console.log(`free balance is ${balance.freee} with ${balance.reserved} reserved and a nonce of ${nonce}`);
});
```
+2 -2
View File
@@ -8,8 +8,8 @@ To unpack this, we will start with the Metadata and explain what it actually pro
When the API connects to a node, one of the first things it does is to retrieve the metadata. The metadata, effectively provides data in the form of `api.<type>.<module>.<section>` that fits into one of the following categories -
- [consts](../substrate/constants.md) - All runtime constants, e.g. `api.consts.balances.creationFee`. These are not functions, rather accessing the endpoint immediately yields the result as defined.
- [query](../substrate/storage.md) - All chain state, e.g. `api.query.balances.freeBalance(<accountId>)`.
- [consts](../substrate/constants.md) - All runtime constants, e.g. `api.consts.balances.existentialDeposit`. These are not functions, rather accessing the endpoint immediately yields the result as defined.
- [query](../substrate/storage.md) - All chain state, e.g. `api.query.system.account(<accountId>)`.
- [tx](../substrate/extrinsics.md) - All extrinsics, e.g. `api.tx.balances.transfer(<accountId>, <value>)`.
Additionally the metadata also provides information on [events](../substrate/events.md), these are query-able via the `api.query.system.events()` interface and also appear on transactions... both these cases are detailed later.
+2 -3
View File
@@ -30,11 +30,10 @@ For any interface injected by metadata, the types are not available by default (
However, to make this sane from a developer perspective the injected methods are generic, effectively making the following possible -
```js
import { Balance, Index } from '@polkadot/types/interfaces';
import { AccountData, Index } from '@polkadot/types/interfaces';
...
const nonce = await api.query.system.accountNonce<Index>(ADDR);
const balance = await api.query.balances.freeBalance<Balance>(ADDR);
const [nonce, balance] = await api.query.system.account<[Index, AccountData]>(ADDR);
```
In both these case we can instruct the TypeScript compiler that the type we are expecting in `Index` and `Balance` respectively, not just pure `Codec`. This means that functions like `.toNumber()` is available on both these types - as opposed to just the [general type defaults](types.basics.md#everything-is-a-type) with `.toHex()` and friends.