Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbfc15ba88 | ||
|
|
2d40d370f9 | ||
|
|
0728e40bfb | ||
|
|
1a50298ffe | ||
|
|
68f2cb5bb2 | ||
|
|
8598002801 | ||
|
|
333ff8528b | ||
|
|
c17f93a3ec | ||
|
|
67841a9212 | ||
|
|
6be6b027cb | ||
|
|
6943c9b36d | ||
|
|
253e48f7bb | ||
|
|
eeaf6118a5 | ||
|
|
c3c77ffe43 | ||
|
|
71e82aece8 | ||
|
|
a7132b4e9c | ||
|
|
8acb65931e | ||
|
|
dcf053633b | ||
|
|
015ade79e6 | ||
|
|
a4f56d3d38 | ||
|
|
73d10a55f1 | ||
|
|
2d0ce2ddff | ||
|
|
775697f51e | ||
|
|
9690777acb | ||
|
|
e7d38a5e59 | ||
|
|
c6355fb147 | ||
|
|
d85d9ca930 | ||
|
|
af643401b8 | ||
|
|
fcea797c8a | ||
|
|
cbc14cc291 | ||
|
|
64aa4dcc1c | ||
|
|
429ea4ca99 | ||
|
|
86ce696808 | ||
|
|
57ca9a9c32 | ||
|
|
70a26e33a7 | ||
|
|
c487094aa7 | ||
|
|
bab79b6473 | ||
|
|
586e838788 | ||
|
|
51cb64ade7 | ||
|
|
d09dcb8282 | ||
|
|
869f9b7af9 | ||
|
|
a938cb545a | ||
|
|
553b3df0b2 | ||
|
|
1fd157364b | ||
|
|
fa7ae72c59 | ||
|
|
443706a6e0 | ||
|
|
ba462aae8b | ||
|
|
a35da085d6 | ||
|
|
3d8d2e4988 | ||
|
|
6c5ef6ecd6 | ||
|
|
3bae45a331 | ||
|
|
196a0891b8 | ||
|
|
2a16b04420 | ||
|
|
790deca695 | ||
|
|
4ec87dc51c | ||
|
|
51686f0cd4 | ||
|
|
deddc6dc79 | ||
|
|
3bf4c3fac5 | ||
|
|
ccf32a6289 | ||
|
|
4540495a44 | ||
|
|
429b797b23 | ||
|
|
a3d5ef790c | ||
|
|
b548277c05 | ||
|
|
2de9317b30 | ||
|
|
877aa33efa | ||
|
|
8a9e523b84 | ||
|
|
19743d6634 | ||
|
|
85ec141b56 | ||
|
|
cb175b4bde | ||
|
|
8672a2e30e | ||
|
|
17936f849b | ||
|
|
3b9f348223 | ||
|
|
b5ff0434d9 | ||
|
|
877a339353 | ||
|
|
716f473887 | ||
|
|
1c1bfb295d | ||
|
|
dd0a31803f | ||
|
|
e04e5577ed | ||
|
|
09617aad2e | ||
|
|
3d8a57a7d5 | ||
|
|
feff458cbf | ||
|
|
543b4846f9 | ||
|
|
09ab373b54 | ||
|
|
bec6dba14a | ||
|
|
e80bea6680 | ||
|
|
9119e791d1 | ||
|
|
46b99ae83d | ||
|
|
92129746dc | ||
|
|
4a8a36d284 | ||
|
|
2b8ce1b3b7 | ||
|
|
0e1e0c0d37 | ||
|
|
427f821430 | ||
|
|
07307f8374 | ||
|
|
cc5b5c81c9 | ||
|
|
efbc017940 | ||
|
|
849972f7b0 | ||
|
|
01758229eb | ||
|
|
add9b59402 | ||
|
|
c8af75088a | ||
|
|
d4b45921fd | ||
|
|
30f5baa906 | ||
|
|
7150bdcbea | ||
|
|
d041c0abb2 | ||
|
|
524e694b90 | ||
|
|
bdd1e4c917 | ||
|
|
7233d7c754 | ||
|
|
aee09c48b9 | ||
|
|
7edbc58129 | ||
|
|
ad2939cc4f | ||
|
|
e984c74ca6 | ||
|
|
a5c8e3c4e1 | ||
|
|
1e5191d695 | ||
|
|
b46093e5d3 | ||
|
|
64f0d7b2a6 | ||
|
|
4a1e504ca2 | ||
|
|
ebf3f4491e | ||
|
|
849f519efe | ||
|
|
accc2b4f7d | ||
|
|
01abc030f9 | ||
|
|
e041946de5 | ||
|
|
502e54ce5c | ||
|
|
12986f0cda | ||
|
|
83d780220c | ||
|
|
ec7848ae92 | ||
|
|
2b5be7eaab | ||
|
|
21f4e3107a | ||
|
|
8a152ea4c0 | ||
|
|
fd7b38e781 | ||
|
|
5df22835f6 | ||
|
|
6a828eb11a | ||
|
|
ad2b1abdc9 | ||
|
|
d3dc2cb00a | ||
|
|
921e55a82e | ||
|
|
fde076152a | ||
|
|
6e535b0502 | ||
|
|
1ddad84d7e | ||
|
|
1e975c68ee | ||
|
|
5c962cf093 | ||
|
|
07f55af202 |
+1
-1
@@ -1 +1 @@
|
||||
18
|
||||
19
|
||||
|
||||
+4
-2
@@ -4,6 +4,8 @@ exclude_patterns:
|
||||
- "**/*.test.js"
|
||||
- "**/*.test.ts"
|
||||
- "docs/**/*.js"
|
||||
- "packages/api/src/types/augment/"
|
||||
- "packages/api/src/augment/"
|
||||
- "packages/typegen/scripts"
|
||||
- "packages/typegen/src"
|
||||
- "packages/types/src/interfaces/"
|
||||
- "packages/types/src/scripts/"
|
||||
- "packages/types/src/augment/"
|
||||
|
||||
@@ -14,6 +14,16 @@ jobs:
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Config yarn cache
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- uses: actions/cache@v1
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: lint
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
@@ -31,6 +41,16 @@ jobs:
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Config yarn cache
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- uses: actions/cache@v1
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: test
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
@@ -48,6 +68,16 @@ jobs:
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Config yarn cache
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- uses: actions/cache@v1
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: build
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
@@ -65,6 +95,16 @@ jobs:
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Config yarn cache
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- uses: actions/cache@v1
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: build
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
|
||||
@@ -20,6 +20,16 @@ jobs:
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Config yarn cache
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- uses: actions/cache@v1
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: build
|
||||
env:
|
||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||
@@ -44,6 +54,16 @@ jobs:
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Config yarn cache
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
- uses: actions/cache@v1
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
- name: build
|
||||
env:
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
|
||||
+43
-9
@@ -1,17 +1,51 @@
|
||||
# 1.4.1 Feb 26, 2020
|
||||
|
||||
- **Breaking change** (TypeScript only) The `*.d.ts` files now contain TypeScript 3.8 features (specifically `#private`), which is not usable in TS versions < 3.8
|
||||
- **Breaking change** - `api.derive.staking.*` has updated result types and detects support for lazy payouts queries
|
||||
- Rework type generation for `api.{query, tx}` to properly handle complex type inputs (Thanks to https://github.com/monitz87)
|
||||
- Rework metadata `--strict` mode to effectively decorate chain metadata (Thanks to https://github.com/monitz87)
|
||||
- Add `api.rpc.chain.subscribeAllHeads` (not just best) (Thanks to https://github.com/jak-pan)
|
||||
- Add `api.rpc.engine.*` for manual seal support
|
||||
- Add `api.injectMetadata(metadata)` to initialize API with a specific metadata version
|
||||
- The api now checks for runtime upgrades, augmenting the interfaces with new metadata when found
|
||||
- Support types & interfaces required for lazy reaping, lazy payouts & offchain phragmen
|
||||
- `Option` types now has an `.unwrapOrDefault` as an complement to `.unwrap` & `.unwrapOr`
|
||||
- Support JS `BigInt` inputs in any derived `UInt` and `Int` object, e.g. `api.tx.balances.transfer(..., 9876543210123456789n)`
|
||||
- `UInt` & `Int` now does source bitLength checks upon construction
|
||||
- Registry now exposes `.createType(<type>, ...args)` as an additional helper (like the API)
|
||||
- Expand `.toHuman` on `ExtrinsicEra`, `SubmittableResult` & `Vote`
|
||||
- Move `DigestItem`, `Fixed64`, `H160`, `H256` & `H512` to interfaces in `@polkadot/types/interfaces`
|
||||
- Align construction of unknown types in `registry.get` consistently warn on detection, throw on use
|
||||
- Support for arbitrary UInt types via `UInt<bitLength>` type definitions
|
||||
- Expose static `.with` on `UInt`, `Int` & `U8aFixed` classes with optional type name override
|
||||
- Remove [11 Jan 2019](https://github.com/polkadot-js/api/issues/574) extrinsic length hack
|
||||
- Use ES `#field` on private class fields as applicable
|
||||
- Move `types/primitive/{extrinsics, generic}` to `types/{extrinsics, generic}`
|
||||
- Cleanup augmentation and generation scripts for type definitions, aligning with api augmentation
|
||||
- Bump to `@polkadot/{util, util-crypto, keyring}` 2.5.1
|
||||
|
||||
# 1.3.1 Feb 18, 2020
|
||||
|
||||
- Add `@types/bn.js` as a normal dependency, exposed in `*.d.ts` (Thanks to https://github.com/monitz87)
|
||||
- Type generation scripts (including `polkadot-types-from-{chain,defs}`) has been moved to the `@polkadot/typegen` package
|
||||
- The `@polkadot/types/codec/create` has been moved to `@polkadot/types/create`, imports from `@polkadot/types` are unaffected
|
||||
- Expose chain properties on registry (and use for API type formatting)
|
||||
- Add `toHuman(isExtended?: boolean)` to all codec types, formatting into a human-readable structure
|
||||
|
||||
# 1.2.1 Feb 16, 2020
|
||||
|
||||
- **Important** Update RPC status codes (latest Substrate 2), with the `isInBlock` (`isFinalized` now indicates finality)
|
||||
- Storage `.entries(arg?: any)` now has the correct argument type for DoubleMap (Thanks to https://github.com/monitz87)
|
||||
- Swap Kusama and Polkadot aliasses for `Address` to `AccountId` (future update)
|
||||
- Add `LookupSource` and `LookupTarget` types instead of mapping these directly for aliassing
|
||||
- Swap Kusama and Polkadot aliases for `Address` to `AccountId` (future update)
|
||||
- Add `LookupSource` and `LookupTarget` types instead of mapping these directly for aliasing
|
||||
- Add `BitVec` type primitive
|
||||
- Add support for `system.account` for balance & nonce queries in derives as well as Submittables (Substrate composites)
|
||||
- Add `rpc.author.hasKey` and `rpc.author.hasSessinKeys` RPCs
|
||||
- Add `rpc.author.hasKey` and `rpc.author.hasSessionKeys` RPCs
|
||||
- Add derives for the parachains interfaces
|
||||
- Applied the latest types for Polkadot parachains
|
||||
- `registry.findMetaError` now can take in a `DispatchErrorModule` object for error lookups (from `asModule` in `DispatchError`)
|
||||
- Metadata now correctly serializes to the original input data via `toHex()` & `toU8a()`
|
||||
- Metadata dcocumentation generation rework, including the output of errors from metadata
|
||||
- Metadata documentation generation rework, including the output of errors from metadata
|
||||
- Update all examples and comments to use latest `system.account` queries (instead of `system.accountNonce` and `balances.freeBalance`/`balances.reservedBalance`)
|
||||
- Cleanup `codec/Date` tests to make it run properly on all timezones
|
||||
- Add explicit dependencies to all packages and move TypeScript `@types/*` to dev deps
|
||||
@@ -51,7 +85,7 @@
|
||||
|
||||
# 0.100.1 Jan 13, 2020
|
||||
|
||||
- **Important** This will the the last API version with Substrate 1.x support. Although you will still be able to use subsequent versions with older chans, dependent libraries such as sr25519 may not be compatible.
|
||||
- **Important** This will the the last API version with Substrate 1.x support. Although you will still be able to use subsequent versions with older chains, dependent libraries such as sr25519 may not be compatible.
|
||||
- Add support for the Substrate identity module
|
||||
- Remove the `codec/Data` type, to remove a conflict with Substrate. This type is now named `Raw`
|
||||
- Fix for linked maps using `Option`
|
||||
@@ -65,7 +99,7 @@
|
||||
- **Breaking change** The `Data` and `U8a` type has been renamed and just replaced with the `Raw` type
|
||||
- **Breaking change** The `api.derive.staking.info` has been split into 2 - `staking.query` for non-balance related information (more effective) and `staking.account` that enhances query for all the information previously found `.info`
|
||||
- Cleanup `DoubleMap` hashing to always hash over the full value (in the case of `Vec<T>`, this includes the length)
|
||||
- Update democracy derives to take care of nextTally and lowestU*nbaked
|
||||
- Update democracy derives to take care of nextTally and lowestUnbaked
|
||||
- Add additional derives for both council & treasury
|
||||
- Alignment with latest Polkadot/Substrate master branch types
|
||||
|
||||
@@ -120,7 +154,7 @@
|
||||
- Adjust API cloning now takes RPC filters from source into account
|
||||
- Simplification of isPedantic checks and less overhead on StorageData types
|
||||
- Cleanups and fixes around RPC and derive type definitions
|
||||
- Fix `derive.imOnline.receivedHeatbeats` to query via indexes
|
||||
- Fix `derive.imOnline.receivedHeartbeats` to query via indexes
|
||||
- Adjustment of `api.derive.elections.{approvalsOf|approvalsOfAt}` to allow ss58 address input
|
||||
- Cleanup `Enum` `.eq` handling to be more exhaustive
|
||||
- Add documentation for custom extrinsic formats (advanced chains)
|
||||
@@ -154,7 +188,7 @@
|
||||
- Redeemed balance calculation if `api.derive` now returns the correct values again (bug fix)
|
||||
- added the `yarn chain:info [--ws URL]` utility to extract a calls-only metadata version
|
||||
- Missing types are now logged via a `console.warn`, not via `.error`
|
||||
- `Extrinsic`, `ExtrinsicPayload` & `SignerPayload` is registered in the type registry and can be overriden now
|
||||
- `Extrinsic`, `ExtrinsicPayload` & `SignerPayload` is registered in the type registry and can be overridden now
|
||||
- **Breaking change** `SignerPayload` is renamed to `SignerPayloadJSON`
|
||||
- **Breaking change** `SignerPayloadJSON`, `SignerPayloadRawBase` and `SignerPayloadRaw` are all moved to `@polkadot/types`
|
||||
|
||||
@@ -180,7 +214,7 @@ If you are upgrading form an older version, use the CHANGELOG hand-in-hand with
|
||||
|
||||
- Support for substrate 2.x (master) has been extended,
|
||||
- Additional types have been addedd for the modules
|
||||
- `api.derive.contract` is now `api.derive.contracts` to align with the substrate 2.x rename. (Feture detection is used so it supports both 1.x and 2.x chains)
|
||||
- `api.derive.contract` is now `api.derive.contracts` to align with the substrate 2.x rename. (Feature detection is used so it supports both 1.x and 2.x chains)
|
||||
- Addition of `api.derive.elections`
|
||||
|
||||
- Support latest substrate 2 v6 metadata with module constants using `api.consts`.
|
||||
|
||||
@@ -27,7 +27,7 @@ The API is split up into a number of internal packages -
|
||||
|
||||
Type definitions for interfaces as exposed by Polkadot & Substrate clients -
|
||||
|
||||
- [@polkadot/jsonrpc](packages/type-jsonrpc/) Definitions for JSONRPC endpoints
|
||||
- [@polkadot/jsonrpc](packages/jsonrpc/) Definitions for JSONRPC endpoints
|
||||
- [@polkadot/types](packages/types/) Codecs for all Polkadot and Substrate primitives
|
||||
|
||||
## development
|
||||
|
||||
+1
-3
@@ -1,3 +1 @@
|
||||
module.exports = {
|
||||
extends: '@polkadot/dev/config/babel'
|
||||
};
|
||||
module.exports = require('@polkadot/dev/config/babel');
|
||||
|
||||
+10
-9
@@ -2,7 +2,7 @@
|
||||
|
||||
function copy_folder () {
|
||||
SRC="packages/$1/build"
|
||||
DST="../apps/node_modules/@polkadot/$2"
|
||||
DST="../apps/node_modules/@polkadot/$1"
|
||||
|
||||
echo "** Copying $SRC to $DST"
|
||||
|
||||
@@ -12,11 +12,12 @@ function copy_folder () {
|
||||
|
||||
yarn polkadot-dev-build-ts
|
||||
|
||||
copy_folder "api" "api"
|
||||
copy_folder "api-contract" "api-contract"
|
||||
copy_folder "api-derive" "api-derive"
|
||||
copy_folder "metadata" "metadata"
|
||||
copy_folder "rpc-core" "rpc-core"
|
||||
copy_folder "rpc-provider" "rpc-provider"
|
||||
copy_folder "type-jsonrpc" "jsonrpc"
|
||||
copy_folder "types" "types"
|
||||
copy_folder "api"
|
||||
copy_folder "api-contract"
|
||||
copy_folder "api-derive"
|
||||
copy_folder "metadata"
|
||||
copy_folder "rpc-core"
|
||||
copy_folder "rpc-provider"
|
||||
copy_folder "jsonrpc"
|
||||
copy_folder "types"
|
||||
copy_folder "typegen"
|
||||
|
||||
@@ -43,6 +43,7 @@ module.exports = {
|
||||
['start/api.tx.wrap.md', 'Complex transactions'],
|
||||
['start/types.basics.md', 'Type basics'],
|
||||
['start/types.extend.md', 'Extending types'],
|
||||
['start/types.create.md', 'Creating types'],
|
||||
['start/extrinsic.extend.md', 'Extending extrinsics'],
|
||||
['start/typescript.md', 'TypeScript interfaces'],
|
||||
['start/typescript.user.md', 'TypeScript user generated'],
|
||||
|
||||
@@ -13,13 +13,13 @@ async function main () {
|
||||
|
||||
// Retrieve the initial balance. Since the call has no callback, it is simply a promise
|
||||
// that resolves to the current on-chain value
|
||||
let [previousNonce, { free: previousFree }] = await api.query.system.account(Alice);
|
||||
let { nonce: previousNonce, data: { free: previousFree } } = await api.query.system.account(Alice);
|
||||
|
||||
console.log(`${Alice} has a balance of ${previousFree}, nonce ${previousNonce}`);
|
||||
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.system.account(Alice, ([currentNonce, { free: currentFree }]) => {
|
||||
api.query.system.account(Alice, ({ nonce: currentNonce, data: { free: currentFree } }) => {
|
||||
// Calculate the delta
|
||||
const change = currentFree.sub(previousFree);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ async function main () {
|
||||
|
||||
// Subscribe and listen to several balance changes
|
||||
api.query.system.account.multi([ALICE, BOB], (balances) => {
|
||||
console.log('Change detected, new balances: ', balances.map(([, { free }]) => free));
|
||||
console.log('Change detected, new balances: ', balances.map(({ data: { free } }) => free));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ async function main () {
|
||||
const api = await ApiPromise.create();
|
||||
|
||||
// Make our basic chain state/storage queries, all in one go
|
||||
const [[accountNonce], now, validators] = await Promise.all([
|
||||
const [{ nonce: accountNonce }, now, validators] = await Promise.all([
|
||||
api.query.system.account(ALICE),
|
||||
api.query.timestamp.now(),
|
||||
api.query.session.validators()
|
||||
@@ -32,8 +32,8 @@ async function main () {
|
||||
// Print out the authorityIds and balances of all validators
|
||||
console.log('validators', validators.map((authorityId, index) => ({
|
||||
address: authorityId.toString(),
|
||||
balance: validatorBalances[index][1].free.toString(),
|
||||
nonce: validatorBalances[index][0].toString()
|
||||
balance: validatorBalances[index].data.free.toHuman(),
|
||||
nonce: validatorBalances[index].nonce.toHuman()
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ async function main () {
|
||||
// the format is always `.at(<blockhash>, ...params)`
|
||||
const balance = await api.query.system.account.at(parentHash, ALICE);
|
||||
|
||||
console.log(`Alice's balance at ${parentHash.toHex()} was ${balance[1].free}`);
|
||||
console.log(`Alice's balance at ${parentHash.toHex()} was ${balance.data.free}`);
|
||||
|
||||
// Now perform a multi query, returning multiple balances at once
|
||||
const balances = await api.query.system.account.multi([ALICE, BOB]);
|
||||
|
||||
console.log(`Current balances for Alice and Bob are ${balances[0][1].free} and ${balances[1][1].free}`);
|
||||
console.log(`Current balances for Alice and Bob are ${balances[0].data.free} and ${balances[1].data.free}`);
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
|
||||
@@ -19,7 +19,7 @@ async function main () {
|
||||
const alice = keyring.addFromUri('//Alice');
|
||||
|
||||
// Get nonce for account
|
||||
const [nonce] = await api.query.system.account(alice.address);
|
||||
const { nonce } = await api.query.system.account(alice.address);
|
||||
|
||||
// Get current block
|
||||
const signedBlock = await api.rpc.chain.getBlock();
|
||||
|
||||
@@ -24,7 +24,7 @@ async function main () {
|
||||
const keyring = testKeyring.default();
|
||||
|
||||
// Get the nonce for the admin key
|
||||
const [nonce] = await api.query.system.account(ALICE);
|
||||
const { nonce } = await api.query.system.account(ALICE);
|
||||
|
||||
// Find the actual keypair in the keyring
|
||||
const alicePair = keyring.getPair(ALICE);
|
||||
@@ -40,13 +40,15 @@ async function main () {
|
||||
.signAndSend(alicePair, { nonce }, ({ events = [], status }) => {
|
||||
console.log('Transaction status:', status.type);
|
||||
|
||||
if (status.isFinalized) {
|
||||
console.log('Completed at block hash', status.asFinalized.toHex());
|
||||
if (status.isInBlock) {
|
||||
console.log('Included at block hash', status.asInBlock.toHex());
|
||||
console.log('Events:');
|
||||
|
||||
events.forEach(({ phase, event: { data, method, section } }) => {
|
||||
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
|
||||
});
|
||||
} else if (status.isFinalized) {
|
||||
console.log('Finalized block hash', status.asFinalized.toHex());
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
@@ -39,15 +39,15 @@ async function main () {
|
||||
.signAndSend(adminPair, ({ events = [], status }) => {
|
||||
console.log('Proposal status:', status.type);
|
||||
|
||||
if (status.isFinalized) {
|
||||
if (status.isInBlock) {
|
||||
console.error('You have just upgraded your chain');
|
||||
|
||||
console.log('Completed at block hash', status.asFinalized.toHex());
|
||||
console.log('Included at block hash', status.asInBlock.toHex());
|
||||
console.log('Events:');
|
||||
|
||||
events.forEach(({ phase, event: { data, method, section } }) => {
|
||||
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
|
||||
});
|
||||
console.log(JSON.stringify(events.toHuman(), null, 2));
|
||||
} else if (status.isFinalized) {
|
||||
console.log('Finalized block hash', status.asFinalized.toHex());
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ async function main () {
|
||||
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][1].free}`);
|
||||
console.log(`Alice ${Alice} has a balance of ${balance[1].data.free}`);
|
||||
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][1].free.sub(balance[0][1].free);
|
||||
const change = balance[1].data.free.sub(balance[0].date.free);
|
||||
|
||||
// Only display value changes
|
||||
if (!change.isZero()) {
|
||||
|
||||
@@ -36,16 +36,16 @@ function main () {
|
||||
})
|
||||
)
|
||||
// Then we're subscribing to the emitted results
|
||||
.subscribe(([[accountNonce], blockPeriod, validators, validatorBalances]) => {
|
||||
console.log(`accountNonce(${Alice}) ${accountNonce}`);
|
||||
.subscribe(([{ nonce }, blockPeriod, validators, validatorBalances]) => {
|
||||
console.log(`accountNonce(${Alice}) ${nonce}`);
|
||||
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][1].free.toString(),
|
||||
nonce: validatorBalances[index][0].toString()
|
||||
balance: validatorBalances[index].data.free.toString(),
|
||||
nonce: validatorBalances[index].data.toString()
|
||||
})));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -25,9 +25,14 @@ async function main () {
|
||||
.signAndSend(alice)
|
||||
// Subscribe to the status updates of the transfer
|
||||
.subscribe(({ status }) => {
|
||||
if (status.isFinalized) {
|
||||
console.log(`Successful transfer of 12345 from Alice to Bob with hash ${status.asFinalized.toHex()}`);
|
||||
if (status.isInBlock) {
|
||||
console.log(`Successful transfer of 12345 from Alice to Bob at block ${status.asInBlock.toHex()}`);
|
||||
} else if (status.isFinalized) {
|
||||
console.log('Finalized block hash', status.asFinalized.toHex());
|
||||
|
||||
subscription.unsubscribe();
|
||||
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log(`Status of transfer: ${status.type}`);
|
||||
}
|
||||
|
||||
@@ -44,13 +44,17 @@ async function main () {
|
||||
console.log('Transfer status:', status.type);
|
||||
|
||||
// Log system events once the transfer is finalised
|
||||
if (status.isFinalized) {
|
||||
console.log('Completed at block hash', status.asFinalized.toHex());
|
||||
if (status.isInBlock) {
|
||||
console.log('Included at block hash', status.asInBlock.toHex());
|
||||
console.log('Events:');
|
||||
|
||||
events.forEach(({ phase, event: { data, method, section } }) => {
|
||||
console.log('\t', phase.toString(), `: ${section}.${method}`, data.toString());
|
||||
});
|
||||
} else if (status.isFinalized) {
|
||||
console.log('Finalized block hash', status.asFinalized.toHex());
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -40,16 +40,16 @@ async function main () {
|
||||
// Log transfer events
|
||||
console.log('Proposal status:', status.type);
|
||||
|
||||
if (status.isFinalized) {
|
||||
if (status.isInBlock) {
|
||||
console.error('You have just upgraded your chain');
|
||||
|
||||
console.log('Completed at block hash', status.asFinalized.toHex());
|
||||
console.log('Included at block hash', status.asInBlock.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());
|
||||
});
|
||||
console.log(JSON.stringify(events.toHuman(), null, 2));
|
||||
} else if (status.isFinalized) {
|
||||
console.log('Finalized block hash', status.asFinalized.toHex());
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
+3
-1
@@ -36,6 +36,8 @@ The length for this transaction validity is set to 50 blocks, which translates t
|
||||
|
||||
## My chain does not support system.account queries
|
||||
|
||||
The API always tracks the latest Substrate master in terms of examples. This means that nonce & balance queries are done via the `api.query.system.account(<account>)` which returns a Tuple `(Index, AccountData)` where the first is the nonce, the second a struct containing the free and reserved balances. As with all `api.query.*` endpoint, this is decorated based on what the chain you connect to support.
|
||||
The API always tracks the latest Substrate master in terms of examples. This means that nonce & balance queries are done via the `api.query.system.account(<account>)` which returns a struct `{ nonce: Index, data: AccountData }` where the `data` is struct containing the free and reserved balances. As with all `api.query.*` endpoints, this is decorated based on what the chain you connect to support, via the metadata exchange.
|
||||
|
||||
It is possible that you are connecting to an older chain that has not been upgraded yet. For these chains, this storage entry won't be available (yet). To query the nonce on older chains, you can do a query to `api.query.system.accountNonce(<account>)` and balances can be retrieved via `api.query.balances.freeBalance(<account>)`.
|
||||
|
||||
Likewise, if your chain has been upgraded recently and you are still using the old `system.accountNonce` or `balances.freeBalance` queries in your code (which is now not available in the chain metadata), you need to update it to query the new location.
|
||||
|
||||
@@ -17,7 +17,7 @@ const ADDR = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE';
|
||||
const now = await api.query.timestamp.now();
|
||||
|
||||
// Retrieve the account balance & nonce via the system module
|
||||
const [nonce, balance] = await api.query.system.account(ADDR);
|
||||
const { nonce, data: balance } = await api.query.system.account(ADDR);
|
||||
|
||||
console.log(`${now}: balance of ${balance.free} and a nonce of ${nonce}`);
|
||||
```
|
||||
@@ -27,7 +27,7 @@ There have been some additions in the code above comparing with retrieving runti
|
||||
```js
|
||||
...
|
||||
// Retrieve last block timestamp, account nonce & balances
|
||||
const [now, [nonce, balances]] = await Promise.all([
|
||||
const [now, { nonce, data: balances }] = await Promise.all([
|
||||
api.query.timestamp.now(),
|
||||
api.query.system.account(ADDR)
|
||||
]);
|
||||
|
||||
@@ -11,7 +11,7 @@ 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.system.account.multi([ADDR1, ADDR2], (balances) => {
|
||||
const [[, balance1], [, balance2]] = balances;
|
||||
const [{ data: balance1 }, { data: balance2 }] = balances;
|
||||
|
||||
console.log(`The balances are ${balance1.free} and ${balance2.free}`);
|
||||
});
|
||||
@@ -44,7 +44,7 @@ The previous `.multi` examples assumes that we do queries for the same types, i.
|
||||
const unsub = await api.queryMulti([
|
||||
api.query.timestamp.now,
|
||||
[api.query.system.account, ADDR]
|
||||
], ([now, [nonce, balance]]) => {
|
||||
], ([now, { nonce, data: balance }]) => {
|
||||
console.log(`${now}: balance of ${balance.free} and a nonce of ${nonce}`);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -13,7 +13,7 @@ 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([
|
||||
const [{ data: balanceNow }, { data: balancePrev }] = await Promise.all([
|
||||
api.query.system.account.at(lastHdr.hash, ADDR),
|
||||
api.query.system.account.at(lastHdr.parentHash, ADDR)
|
||||
]);
|
||||
|
||||
@@ -25,7 +25,7 @@ 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.system.account(ADDR, ([nonce, balance]) => {
|
||||
const unsub = await api.query.system.account(ADDR, ({ nonce, data: balance }) => {
|
||||
console.log(`free balance is ${balance.freee} with ${balance.reserved} reserved and a nonce of ${nonce}`);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -28,7 +28,7 @@ The result for this call (we will deal with subscriptions in a short while), is
|
||||
|
||||
Despite the single-line format of `signAndSend`, there is a lot happening under the hood (and all of this can be manually provided) -
|
||||
|
||||
- Based on the sender, the API will retrieve the `system.accountNonce` to determine the next nonce to use
|
||||
- Based on the sender, the API will query `system.account` (or `system.accountNonce` on older chains) to determine the next nonce to use
|
||||
- The API will retrieve the current block hash and use it to create a mortal transaction, i.e. the transaction will only be valid for a limited number of blocks (by default this is 5 mins at 6s block times)
|
||||
- It will construct a payload and sign this, this includes the `genesisHash`, the `blockHash` for the start of the mortal era as well as the current chain `specVersion`
|
||||
- The transaction is submitted to the node
|
||||
|
||||
@@ -18,8 +18,10 @@ const unsub = await api.tx.balances
|
||||
.signAndSend(alice, (result) => {
|
||||
console.log(`Current status is ${result.status}`);
|
||||
|
||||
if (result.status.isFinalized) {
|
||||
console.log(`Transaction included at blockHash ${result.status.asFinalized}`);
|
||||
if (result.status.isInBlock) {
|
||||
console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
|
||||
} else if (result.status.isFinalized) {
|
||||
console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);
|
||||
unsub();
|
||||
}
|
||||
});
|
||||
@@ -27,7 +29,7 @@ const unsub = await api.tx.balances
|
||||
|
||||
As per all previous subscriptions, the transaction subscription returns in `unsub()` and the actual method has a subscription callback. The `result` object has 2 parts, `events` (to to covered in the next section) and the `status` enum.
|
||||
|
||||
When the `status` enum is in `Finalized` state (checked via `isFinalized`), the underlying value contains the block hash of the block where the transaction has been included. This does not mean the block is finalized, but rather applies to the transaction state, as no further updates will be received for this subscription.
|
||||
When the `status` enum is in `Finalized` state (checked via `isFinalized`), the underlying value contains the block hash of the block where the transaction has been finalized. `Finalized` will follow `InBlock`, which is the block where the transaction has been included. `InBlock` does not mean the block is finalized, but rather applies to the transaction state, where `Finalized` means that the transaction cannot be forked off the chain.
|
||||
|
||||
## Transaction events
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ To unpack this, we will start with the Metadata and explain what it actually pro
|
||||
|
||||
## Metadata
|
||||
|
||||
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 -
|
||||
When the API connects to a node, one of the first things it does is to retrieve the metadata and decorate the API based on the metadata information. 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.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>)`.
|
||||
@@ -14,6 +14,8 @@ When the API connects to a node, one of the first things it does is to retrieve
|
||||
|
||||
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.
|
||||
|
||||
None of the information contained within the `api.{consts, query, tx}.<module>.<method>` endpoints are hard coded in the API. Rather everything is fully decorated by what the metadata exposes and is therefore completely dynamic. This means that when you connect to different chains, the metadata and API decoration will change and the API interfaces will reflect what is available on the chain you are connected to.
|
||||
|
||||
## Types
|
||||
|
||||
The metadata defines the calls with all the type names used in the various interfaces. At the moment (this is undergoing investigations and could improve in future versions of metadata), this also means that the types between the API and the node need to be aligned. For instance, by default Substrate defines a `BlockNumber` type as a `u32` and the API follows the Substrate defaults - if a chain has a different definitions, the API needs to be aware of this so it can actually decode (and encode) the type.
|
||||
|
||||
@@ -68,6 +68,12 @@ await api.isReady;
|
||||
console.log(api.genesisHash.toHex());
|
||||
```
|
||||
|
||||
## Failures
|
||||
|
||||
In all cases the API will handle reconnections automatically. This means that when you connect and the endpoint is not (yet) ready, the promise will not resolve immediately, but rather when connected. The same applies to when connection is lost, the API will manage re-connections.
|
||||
|
||||
In cases where the API does not support the chain being connected to, such as it using an unknown metadata version, the ready promise will fail to resolve and instead reject.
|
||||
|
||||
## Advanced creation
|
||||
|
||||
There are more advanced cases where you would prefer to use the longer version, for instance: if you want to explicitly listen to events emitted, you probably want to attach to the API even before connecting to the chain. All API instances implement an `EventEmitter` interface, with `on` handlers, which emit `connected`, `disconnected`, `ready` and `error` events, allowing you to listen to events on the transport layer.
|
||||
|
||||
@@ -27,7 +27,7 @@ For example:
|
||||
|
||||
```js
|
||||
const { metadata } = await api.rpc.state.getMetadata();
|
||||
const modules = metadata.asV3.modules;
|
||||
const modules = metadata.asLatest.modules;
|
||||
|
||||
// This will not work, because `name` is an instance of `Text`, not a string
|
||||
// const system = modules.find(m => m.name === 'system');
|
||||
@@ -79,6 +79,8 @@ const [count, accountId] = tuple;
|
||||
console.log(`${accountId} has ${count.toNumber()} values`);
|
||||
```
|
||||
|
||||
When making a call that expect a `Tuple` input, pass it as an array, so to pass the example above into a call, it would be `.call([123, '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'])`
|
||||
|
||||
## Extending types
|
||||
|
||||
For customized chains, the need exists to register types so the API is aware of how to decode values for those types. The next section will provide a [walk-through for the definition of custom types](types.extend.md) allowing the definition or re-definition of any type the API is aware of.
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# Type creation
|
||||
|
||||
Circling back to metadata. There are two important things to remember when using the API to make queries or send transactions.
|
||||
|
||||
1. The functionality available, e.g. exposed on `api.query.*` is not hard-coded in the API, rather this is decorated from the chain metadata. So the metadata lets the API know which endpoints are available and what the type for those endpoints are.
|
||||
|
||||
2. When you supply a value to the API, internally it will convert that value to the correct type as expected by the chain, i.e. as determined by the metadata. This means that a function such as `balances.transfer(address: Address, value: Balance)` can take at least the following inputs, which are all converted to the correct types -
|
||||
|
||||
- `address` can be an `Address`, an `AccountId`, an `Uint8Array` publicKey, a hex publicKey or an ss58 formatted address;
|
||||
- `value` can be a `Balance`, a value encoded in hex, a `BN` object, a base-10 string, a JS `number`, a JS `BigInt` or even a SCALE-encoded `Uint8Array`
|
||||
|
||||
In cases where a value is returned such as storage queries, the response from the chain is always encoded into the correct `Codec` type. This means that while the node may return an encoded block (with encoded extrinsics) via `api.rpc.chain.getBlock()`, this is decoded into a proper `SignedBlock` by the API. Outputting this value via `.toJSON()` will yield an encoding for RPC, so if you are not using TypeScript (which adds code helpers on decoded objects), a representation via `.toHuman()` will be more representative of the actual object fields, re-formatted for human consumption.
|
||||
|
||||
## Why create types
|
||||
|
||||
With the conversions done in the API, there are limited reasons to create types "manually". However, just because there are not thousands of reasons, does not mean it is not valid. For instance, you may retrieve an `Option` and for the sake of sanity would like to use `.unwrapOr()` on it, returning a `Codec` default value where the value `.isNone`.
|
||||
|
||||
```js
|
||||
// type import for TypeScript
|
||||
import type { Balance } from '@polkadot/types/interfaces';
|
||||
|
||||
...
|
||||
// unwrap out option into a zero Balance whn not found
|
||||
const balance: Balance = balanceOpt.unwrapOr(api.createType('Balance'));
|
||||
```
|
||||
|
||||
In the example above, we introduced the `api.createType(<typeName>, [<value>])`. The same format is also exposed by the `TypeRegistry` (more on this in a short while) as well as `createType(...)` from the actual `@polkadot/types` package. All doing exactly the same.
|
||||
|
||||
## Choosing how to create
|
||||
|
||||
In most cases, you would always want to use the `api.createType` helper. What this does is call the underlying `@polkadot/types` `createType`, passing through the registry that is attached to the API. Registry? Yes, registry.
|
||||
|
||||
The registry contains a listing of all internal types and their classes that have been registered. So upon creation of an API instance, a `registry` object is attached to the API and this is passed through to all created types. This allows the type definitions to not pollute the global namespace, but rather be contained and able to reference one another.
|
||||
|
||||
As mentioned, the `createType` functions all do exactly the same, and it 99.99% of the cases you would be recommended to just forget about everything and use `api.createType` if and when required. In some cases, you may just have a type object and from that want to create another type instance. For that you can access the `registry` on the type object and call `createType` on it. (If this type object was created from an API instance, the registry on the type and on the API will point to the same instance.)
|
||||
|
||||
Basically, this means that we have equivalency in creation for all the items below, all creating on the same registry (containing all injected types), and all wrapping the same value -
|
||||
|
||||
```js
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
// via API (recommended)
|
||||
api.createType('Balance', 123);
|
||||
|
||||
// via registry (`.registry` is on all API and Codec objects)
|
||||
api.registry.createType('Balance', 123n);
|
||||
|
||||
// via the low-level approach
|
||||
createType(api.registry, 'Balance', '123');
|
||||
```
|
||||
|
||||
## Extending extrinsics
|
||||
|
||||
On customized chains, it is possible to [extend the format of the extrinsics and extrinsic payload for the chain](extrinsic.extend.md), next up we will look at this advanced use-case.
|
||||
@@ -137,6 +137,6 @@ const api = await ApiPromise.create({
|
||||
|
||||
`Balance` would be defined as an `u128` at the end. Effectively based on the flow it is first registered as a `u32`, then overridden as a `u64` and finally overridden once more as a `u128` by the chain types.
|
||||
|
||||
## Extending extrinsics
|
||||
## Type creation
|
||||
|
||||
On customized chains, it is possible to [extend the format of the extrinsics and extrinsic payload as customized on the chain](extrinsic.extend.md), next up we will look at this advanced use-case.
|
||||
While the API always converts all the inputs into the underlying type required by the operation, in some cases you may want to [cret an instance of a type](types.create.md) yourself.
|
||||
|
||||
@@ -33,18 +33,11 @@ However, to make this sane from a developer perspective the injected methods are
|
||||
import { AccountData, Index } from '@polkadot/types/interfaces';
|
||||
|
||||
...
|
||||
const [nonce, balance] = await api.query.system.account<[Index, AccountData]>(ADDR);
|
||||
const { nonce, data: balances } = 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.
|
||||
|
||||
## Future work
|
||||
|
||||
As of this writing, there are still some gray areas to type detection, specifically around the following interfaces -
|
||||
|
||||
- `.at` & `.multi` on `api.query` does not (yet) have a `<TypeOverride>` interface. This means `as <TypeOverride>` casts are presently needed for these results
|
||||
- `api.queryMulti` does not (yet) allow you to provide a hint to the types returned, this ties to the previous point
|
||||
|
||||
## Adding user types
|
||||
|
||||
In addition to the generated and available interfaces, there is also the ability to [create TypeScript interfaces from your own definitions and well as your on-chain modules](typescript.user.md).
|
||||
|
||||
@@ -6,14 +6,14 @@ In the previous section we looked at the TypeScript definitions that are availab
|
||||
|
||||
A large part of the type definitions are defined not as classes, but rather as structures from which type definitions are extracted and that can be used as-is to let the API know how to decode a type. By now you should be familiar with [type extensions](types.extend.md), but effectively the [types library does exactly the same](https://github.com/polkadot-js/api/tree/master/packages/types/src/interfaces).
|
||||
|
||||
To create TypeScript-aware definitions and keep your files in a single place, you can follow the same approach. Assuming you have a package named `@MeInc/stuff` where you have the definitions in an `stuff/interfaces` folder. Each sub-folder would indicate a runtime module, e.g.
|
||||
To create TypeScript-aware definitions and keep your files in a single place, you can follow the same approach. Assuming you have a package named `@MeInc/stuff` where you have the definitions in an `stuff/interfaces` folder. Each sub-folder would indicate a runtime module, e.g.
|
||||
|
||||
- `stuff/interfaces/<module>/definitions.ts` for each module (`types.ts` & `index.ts` will be generated)
|
||||
- `stuff/interfaces/defnitions.ts` importing all sub-definitions`
|
||||
|
||||
With this structure setup, you can generate TypeScript defintions.
|
||||
|
||||
In the root of your project (with the `@polkadot/api`), you can run `yarn polkadot-types-from-defs --input ./stuff/interfaces --package @MeInc/stuff/interfaces` which will create `types.ts` and `index.ts` files with the generated types. You can use these in exactly the same way as you would use your types from `@polkadot/types/interfaces`.
|
||||
In the root of your project (with the `@polkadot/typegen` package installed), you can run `yarn polkadot-types-from-defs --input ./stuff/interfaces --package @MeInc/stuff/interfaces` which will create `types.ts` and `index.ts` files with the generated types. You can use these in exactly the same way as you would use your types from `@polkadot/types/interfaces`.
|
||||
|
||||
## Chain modules
|
||||
|
||||
|
||||
+2
-2
@@ -7,19 +7,19 @@ module.exports = Object.assign({}, config, {
|
||||
'@polkadot/api-contract(.*)$': '<rootDir>/packages/api-contract/src/$1',
|
||||
'@polkadot/api-derive(.*)$': '<rootDir>/packages/api-derive/src/$1',
|
||||
'@polkadot/api(.*)$': '<rootDir>/packages/api/src/$1',
|
||||
'@polkadot/jsonrpc(.*)$': '<rootDir>/packages/jsonrpc/src/$1',
|
||||
'@polkadot/metadata(.*)$': '<rootDir>/packages/metadata/src/$1',
|
||||
'@polkadot/rpc-(core|provider)(.*)$': '<rootDir>/packages/rpc-$1/src/$2',
|
||||
'@polkadot/jsonrpc(.*)$': '<rootDir>/packages/type-jsonrpc/src/$1',
|
||||
'@polkadot/types(.*)$': '<rootDir>/packages/types/src/$1'
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/api/build',
|
||||
'<rootDir>/packages/api-derive/build',
|
||||
'<rootDir>/packages/api-contract/build',
|
||||
'<rootDir>/packages/jsonrpc/build',
|
||||
'<rootDir>/packages/metadata/build',
|
||||
'<rootDir>/packages/rpc-core/build',
|
||||
'<rootDir>/packages/rpc-provider/build',
|
||||
'<rootDir>/packages/type-jsonrpc/build',
|
||||
'<rootDir>/packages/types/build'
|
||||
],
|
||||
globals: {
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "1.2.1"
|
||||
"version": "1.4.1"
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "1.2.1",
|
||||
"version": "1.4.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"yarn": "^1.10.1"
|
||||
@@ -8,14 +8,13 @@
|
||||
"packages/*"
|
||||
],
|
||||
"resolutions": {
|
||||
"typescript": "^3.7.5"
|
||||
"typescript": "^3.8.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn build:interfaces && polkadot-dev-build-ts",
|
||||
"build:interfaces": "node packages/types/src/scripts/interfacesTsWrapper.js",
|
||||
"circular": "madge --circular --extensions ts ./",
|
||||
"docs": "node packages/types/src/scripts/MetadataMdWrapper.js && polkadot-dev-build-docs",
|
||||
"chain:info": "node packages/types/src/scripts/extractChainWrapper.js",
|
||||
"build": "yarn build:interfaces && polkadot-dev-build-ts && (cd packages/typegen && copyfiles scripts/* build)",
|
||||
"build:interfaces": "polkadot-types-internal-interfaces",
|
||||
"docs": "polkadot-types-internal-metadata && polkadot-dev-build-docs",
|
||||
"chain:info": "polkadot-types-chain-info",
|
||||
"lint": "polkadot-dev-run-lint",
|
||||
"clean": "polkadot-dev-clean-build",
|
||||
"postinstall": "polkadot-dev-yarn-only",
|
||||
@@ -27,7 +26,8 @@
|
||||
"@babel/core": "^7.8.4",
|
||||
"@babel/register": "^7.8.3",
|
||||
"@babel/runtime": "^7.8.4",
|
||||
"@polkadot/dev": "^0.40.16",
|
||||
"@polkadot/ts": "^0.2.3"
|
||||
"@polkadot/dev": "^0.41.4",
|
||||
"@polkadot/ts": "^0.2.3",
|
||||
"copyfiles": "^2.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api-contract",
|
||||
"version": "1.2.1",
|
||||
"version": "1.4.1",
|
||||
"description": "Interfaces for interacting with contracts and contract ABIs",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -27,10 +27,10 @@
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.4",
|
||||
"@polkadot/api": "^1.2.1",
|
||||
"@polkadot/rpc-core": "^1.2.1",
|
||||
"@polkadot/types": "^1.2.1",
|
||||
"@polkadot/util": "^2.3.1",
|
||||
"@polkadot/api": "1.4.1",
|
||||
"@polkadot/rpc-core": "1.4.1",
|
||||
"@polkadot/types": "1.4.1",
|
||||
"@polkadot/util": "^2.5.1",
|
||||
"bn.js": "^5.1.1",
|
||||
"rxjs": "^6.5.4"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { CodecArg, Constructor, Registry, TypeDef } from '@polkadot/types/types';
|
||||
import { ContractABIArgBasePre, ContractABIContract, ContractABIContractPre, ContractABIEvent, ContractABIEventPre, ContractABIFn, ContractABIFnArg, ContractABIMessage, ContractABIMessageBase, ContractABIMessagePre, ContractABI, ContractABIMessageCommon, ContractABIPre, ContractABIRange, ContractABIRangePre, ContractABIStorage, ContractABIStorageLayout, ContractABIStorageLayoutPre, ContractABIStoragePre, ContractABIStorageStruct, ContractABIStorageStructPre, ContractABITypePre } from './types';
|
||||
|
||||
import { Compact, u32, createClass, createType, encodeType } from '@polkadot/types';
|
||||
import { Compact, u32, createClass, encodeType } from '@polkadot/types';
|
||||
import { assert, hexToU8a, isNumber, isString, isNull, isObject, isUndefined, stringCamelCase, isHex, hexToNumber } from '@polkadot/util';
|
||||
|
||||
import MetaRegistry from './MetaRegistry';
|
||||
@@ -14,16 +14,16 @@ import MetaRegistry from './MetaRegistry';
|
||||
// just catch everything (since this is now non-standard for u32 anyway)
|
||||
function parseSelector (registry: Registry, fnname: string, input: ContractABIMessageCommon['selector']): u32 {
|
||||
if (isNumber(input)) {
|
||||
return createType(registry, 'u32', input);
|
||||
return registry.createType('u32', input);
|
||||
} else if (isHex(input)) {
|
||||
return createType(registry, 'u32', hexToU8a(input));
|
||||
return registry.createType('u32', hexToU8a(input));
|
||||
} else if (typeof input === 'string') {
|
||||
try {
|
||||
const array = JSON.parse(input);
|
||||
|
||||
assert(array.length === 4, `${fnname}: Invalid selector length`);
|
||||
|
||||
return createType(registry, 'u32', Uint8Array.from(
|
||||
return registry.createType('u32', Uint8Array.from(
|
||||
// the as number[] is here to pacify TS, it doesn't quite know how to handle the cb
|
||||
(array as number[]).map((value: string | number): number =>
|
||||
isHex(value)
|
||||
|
||||
@@ -260,7 +260,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
|
||||
|
||||
return {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
ext: { length: vecLength, type },
|
||||
length: vecLength, // ex: { type: type }
|
||||
type: `[${type};${vecLength}]`,
|
||||
sub: this.typeDefFromMetaTypeAt(vecTypeIndex)
|
||||
};
|
||||
|
||||
@@ -2,16 +2,15 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiTypes, DecorateMethod, SubmittableResultImpl } from '@polkadot/api/types';
|
||||
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
|
||||
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
|
||||
import { IKeyringPair } from '@polkadot/types/types';
|
||||
import { IKeyringPair, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { ApiObject, ContractABIPre } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { createType } from '@polkadot/types';
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import Abi from '../Abi';
|
||||
@@ -27,7 +26,7 @@ export interface BlueprintCreate<ApiType extends ApiTypes> {
|
||||
class BlueprintCreateResult<ApiType extends ApiTypes> extends SubmittableResult {
|
||||
public readonly contract?: Contract<ApiType>;
|
||||
|
||||
constructor (result: SubmittableResultImpl, contract?: Contract<ApiType>) {
|
||||
constructor (result: ISubmittableResult, contract?: Contract<ApiType>) {
|
||||
super(result);
|
||||
|
||||
this.contract = contract;
|
||||
@@ -41,7 +40,7 @@ export default class Blueprint<ApiType extends ApiTypes> extends BaseWithTx<ApiT
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, codeHash: string | Hash) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
this.codeHash = createType(this.registry, 'Hash', codeHash);
|
||||
this.codeHash = this.registry.createType('Hash', codeHash);
|
||||
}
|
||||
|
||||
public deployContract (constructorIndex = 0, endowment: number | BN, maxGas: number | BN, ...params: any[]): BlueprintCreate<ApiType> {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiTypes, DecorateMethod, SubmittableResultImpl } from '@polkadot/api/types';
|
||||
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
|
||||
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
|
||||
import { IKeyringPair } from '@polkadot/types/types';
|
||||
import { IKeyringPair, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { ApiObject, ContractABIPre } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
@@ -27,7 +27,7 @@ export interface CodePutCode<ApiType extends ApiTypes> {
|
||||
class CodePutCodeResult<ApiType extends ApiTypes> extends SubmittableResult {
|
||||
public readonly blueprint?: Blueprint<ApiType>;
|
||||
|
||||
constructor (result: SubmittableResultImpl, blueprint?: Blueprint<ApiType>) {
|
||||
constructor (result: ISubmittableResult, blueprint?: Blueprint<ApiType>) {
|
||||
super(result);
|
||||
|
||||
this.blueprint = blueprint;
|
||||
@@ -55,7 +55,7 @@ export default class Code<ApiType extends ApiTypes> extends BaseWithTx<ApiType>
|
||||
};
|
||||
}
|
||||
|
||||
private createResult = (result: SubmittableResultImpl): CodePutCodeResult<ApiType> => {
|
||||
private createResult = (result: ISubmittableResult): CodePutCodeResult<ApiType> => {
|
||||
let blueprint: Blueprint<ApiType> | undefined;
|
||||
|
||||
if (result.isInBlock) {
|
||||
|
||||
@@ -11,7 +11,6 @@ import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { createType } from '@polkadot/types';
|
||||
import Abi from '../Abi';
|
||||
import { formatData } from '../util';
|
||||
import { BaseWithTxAndRpcCall } from './util';
|
||||
@@ -44,7 +43,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
|
||||
as === 'rpc' && this.hasRpcContractsCall
|
||||
? (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'rpc'> => {
|
||||
return this.rpcContractsCall(
|
||||
createType(this.registry, 'ContractCallRequest', {
|
||||
this.registry.createType('ContractCallRequest', {
|
||||
origin: account,
|
||||
dest: this.address.toString(),
|
||||
value,
|
||||
@@ -54,7 +53,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
|
||||
)
|
||||
.pipe(
|
||||
map((result: ContractExecResult): ContractCallOutcome =>
|
||||
this.createOutcome(result, createType(this.registry, 'AccountId', account), def, params)
|
||||
this.createOutcome(result, this.registry.createType('AccountId', account), def, params)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -75,7 +74,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
|
||||
|
||||
output = message.returnType
|
||||
? formatData(this.registry, data, message.returnType)
|
||||
: createType(this.registry, 'Raw', data);
|
||||
: this.registry.createType('Raw', data);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -92,6 +91,6 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, address: string | AccountId | Address) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
this.address = createType(this.registry, 'Address', address);
|
||||
this.address = this.registry.createType('Address', address);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
|
||||
import { AccountId, Address, ContractExecResult } from '@polkadot/types/interfaces';
|
||||
import { Codec, CodecArg } from '@polkadot/types/types';
|
||||
import { MetaRegistryJson, StringIndex, TypeIndex, TypeDef } from '@polkadot/types/codec/create/types';
|
||||
import { MetaRegistryJson, StringIndex, TypeIndex, TypeDef } from '@polkadot/types/create/types';
|
||||
|
||||
// import { Observable } from 'rxjs';
|
||||
import { ApiPromise, ApiRx } from '@polkadot/api';
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
import { Codec, Registry, TypeDefInfo, TypeDef } from '@polkadot/types/types';
|
||||
|
||||
import { Option, Raw, createClass } from '@polkadot/types';
|
||||
import { createTypeUnsafe } from '@polkadot/types/codec';
|
||||
import { Option, Raw, createClass, createTypeUnsafe } from '@polkadot/types';
|
||||
|
||||
export function formatData (registry: Registry, data: Raw, { info, type }: TypeDef): Codec {
|
||||
if (info === TypeDefInfo.Option) {
|
||||
|
||||
@@ -18,10 +18,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -71,10 +68,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -116,10 +110,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -153,10 +144,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -183,10 +171,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -223,10 +208,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -256,10 +238,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -295,10 +274,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -340,10 +316,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -381,10 +354,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -402,10 +372,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -439,10 +406,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -460,10 +424,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -506,10 +467,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -527,10 +485,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -566,10 +521,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -587,10 +539,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -628,10 +577,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -677,10 +623,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -708,10 +651,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -725,10 +665,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -757,10 +694,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -802,10 +736,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -839,10 +770,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -869,10 +797,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -909,10 +834,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -942,10 +864,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -969,10 +888,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -998,10 +914,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1047,10 +960,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1082,10 +992,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1119,10 +1026,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1149,10 +1053,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1189,10 +1090,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1230,10 +1128,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1260,10 +1155,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1300,10 +1192,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1331,10 +1220,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1361,10 +1247,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1400,10 +1283,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1445,10 +1325,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1486,10 +1363,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1507,10 +1381,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1544,10 +1415,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1565,10 +1433,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1611,10 +1476,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1632,10 +1494,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1671,10 +1530,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1692,10 +1548,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1725,10 +1578,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1746,10 +1596,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1773,10 +1620,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1814,10 +1658,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1835,10 +1676,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1872,10 +1710,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1893,10 +1728,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1939,10 +1771,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1960,10 +1789,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2007,10 +1833,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2028,10 +1851,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2065,10 +1885,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2086,10 +1903,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2132,10 +1946,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2153,10 +1964,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2190,10 +1998,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2211,10 +2016,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2248,10 +2050,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2269,10 +2068,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2305,10 +2101,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -2328,10 +2121,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
|
||||
@@ -38,10 +38,7 @@
|
||||
{
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -89,10 +86,7 @@
|
||||
{
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -130,10 +124,7 @@
|
||||
{
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -153,10 +144,7 @@
|
||||
{
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -168,10 +156,7 @@
|
||||
{
|
||||
"info": 11,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": ""
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -181,4 +166,4 @@
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -18,10 +18,7 @@
|
||||
{
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
@@ -71,10 +68,7 @@
|
||||
{
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
@@ -120,10 +114,7 @@
|
||||
{
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
@@ -151,10 +142,7 @@
|
||||
{
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
@@ -168,10 +156,7 @@
|
||||
{
|
||||
"info": 13,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 7,
|
||||
"type": "u8"
|
||||
@@ -185,4 +170,4 @@
|
||||
"info": 7,
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -67,10 +64,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -104,10 +98,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -167,10 +158,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -241,10 +229,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -308,10 +293,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -381,10 +363,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -426,10 +405,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -483,10 +459,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -528,10 +501,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -565,10 +535,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -628,10 +595,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -702,10 +666,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -769,10 +730,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -830,10 +788,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -847,10 +802,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -932,10 +884,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -977,10 +926,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1008,10 +954,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1033,10 +976,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1070,10 +1010,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1133,10 +1070,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1207,10 +1141,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1282,10 +1213,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1345,10 +1273,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1419,10 +1344,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1484,10 +1406,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1547,10 +1466,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1620,10 +1536,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1665,10 +1578,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -1714,10 +1624,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -71,10 +68,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -288,10 +282,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -337,10 +328,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -438,10 +426,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -487,10 +472,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -518,10 +500,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -535,10 +514,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -563,10 +539,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
@@ -714,10 +687,7 @@
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"length": 32,
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api-derive",
|
||||
"version": "1.2.1",
|
||||
"version": "1.4.1",
|
||||
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -28,17 +28,17 @@
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.4",
|
||||
"@polkadot/api": "^1.2.1",
|
||||
"@polkadot/rpc-core": "^1.2.1",
|
||||
"@polkadot/rpc-provider": "^1.2.1",
|
||||
"@polkadot/types": "^1.2.1",
|
||||
"@polkadot/util": "^2.3.1",
|
||||
"@polkadot/util-crypto": "^2.3.1",
|
||||
"@polkadot/api": "1.4.1",
|
||||
"@polkadot/rpc-core": "1.4.1",
|
||||
"@polkadot/rpc-provider": "1.4.1",
|
||||
"@polkadot/types": "1.4.1",
|
||||
"@polkadot/util": "^2.5.1",
|
||||
"@polkadot/util-crypto": "^2.5.1",
|
||||
"bn.js": "^5.1.1",
|
||||
"memoizee": "^0.4.14",
|
||||
"rxjs": "^6.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^2.3.1"
|
||||
"@polkadot/keyring": "^2.5.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ITuple } from '@polkadot/types/types';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
|
||||
import { ClassOf, Option, Vec, createType } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
@@ -8,7 +8,7 @@ import { AccountIndexes } from '../types';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
|
||||
import { Vec, createType } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
@@ -54,6 +54,16 @@ function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [Accou
|
||||
email: dataAsString(info.email),
|
||||
image: dataAsString(info.image),
|
||||
legal: dataAsString(info.legal),
|
||||
other: info.additional.reduce((other: Record<string, string>, [_key, _value]): Record<string, string> => {
|
||||
const key = dataAsString(_key);
|
||||
const value = dataAsString(_value);
|
||||
|
||||
if (key && value) {
|
||||
other[key] = value;
|
||||
}
|
||||
|
||||
return other;
|
||||
}, {}),
|
||||
parent: superOf
|
||||
? superOf[0]
|
||||
: undefined,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, AccountData, AccountIndex, Address, Balance, Index } from '@polkadot/types/interfaces';
|
||||
import { AccountId, AccountData, AccountIndex, AccountInfo, Address, Balance, Index } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
import { DerivedBalancesAccount } from '../types';
|
||||
|
||||
@@ -52,10 +52,16 @@ function queryBalancesAccount (api: ApiInterfaceRx, accountId: AccountId): Obser
|
||||
}
|
||||
|
||||
function queryCurrent (api: ApiInterfaceRx, accountId: AccountId): Observable<Result> {
|
||||
return api.query.system.account<ITuple<[Index, AccountData]>>(accountId).pipe(
|
||||
map(([accountNonce, { free, reserved, miscFrozen, feeFrozen }]): Result =>
|
||||
[free, reserved, feeFrozen, miscFrozen, accountNonce]
|
||||
)
|
||||
// AccountInfo is current, support old, eg. Edgeware
|
||||
return api.query.system.account<AccountInfo | ITuple<[Index, AccountData]>>(accountId).pipe(
|
||||
map((infoOrTuple): Result => {
|
||||
const { free, reserved, miscFrozen, feeFrozen } = (infoOrTuple as AccountInfo).nonce
|
||||
? (infoOrTuple as AccountInfo).data
|
||||
: (infoOrTuple as [Index, AccountData])[1];
|
||||
const accountNonce = (infoOrTuple as AccountInfo).nonce || (infoOrTuple as [Index, AccountData])[0];
|
||||
|
||||
return [free, reserved, feeFrozen, miscFrozen, accountNonce];
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,21 +12,6 @@ import { createType } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type Result = [Balance, Balance, Balance, Balance, Balance];
|
||||
|
||||
function query (api: ApiInterfaceRx): Observable<Result> {
|
||||
return of([
|
||||
// deprecated - remove
|
||||
(api.consts.balances.creationFee as Balance) || createType(api.registry, 'Balance'),
|
||||
(api.consts.balances.transferFee as Balance) || createType(api.registry, 'Balance'),
|
||||
|
||||
// current
|
||||
api.consts.balances.existentialDeposit,
|
||||
api.consts.transactionPayment.transactionBaseFee,
|
||||
api.consts.transactionPayment.transactionByteFee
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name fees
|
||||
* @returns An object containing the combined results of the storage queries for
|
||||
@@ -42,7 +27,16 @@ function query (api: ApiInterfaceRx): Observable<Result> {
|
||||
*/
|
||||
export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
|
||||
return memo((): Observable<DerivedFees> =>
|
||||
query(api).pipe(
|
||||
of([
|
||||
// deprecated - remove
|
||||
(api.consts.balances.creationFee as Balance) || createType(api.registry, 'Balance'),
|
||||
(api.consts.balances.transferFee as Balance) || createType(api.registry, 'Balance'),
|
||||
|
||||
// current
|
||||
api.consts.balances.existentialDeposit,
|
||||
api.consts.transactionPayment.transactionBaseFee,
|
||||
api.consts.transactionPayment.transactionByteFee
|
||||
]).pipe(
|
||||
map(([creationFee, transferFee, existentialDeposit, transactionBaseFee, transactionByteFee]): DerivedFees => ({
|
||||
creationFee,
|
||||
existentialDeposit,
|
||||
|
||||
@@ -46,6 +46,7 @@ const deriveAvail: Record<string, string[]> = {
|
||||
democracy: ['democracy'],
|
||||
elections: ['electionsPhragmen', 'elections'],
|
||||
imOnline: ['imOnline'],
|
||||
parachains: ['parachains', 'registrar'],
|
||||
session: ['session'],
|
||||
society: ['society'],
|
||||
staking: ['staking'],
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { BlockNumber, CollatorId, ParaId, ParaInfo, Retriable, UpwardMessage } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
import { DeriveParachain, DeriveParachainActive } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Bytes, Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type ParaIds = ParaId[];
|
||||
type ParaInfoResult = Option<ParaInfo>;
|
||||
type PendingSwap = Option<ParaId>;
|
||||
type Active = ITuple<[ParaId, Option<ITuple<[CollatorId, Retriable]>>]>[];
|
||||
type RetryQueue = ITuple<[ParaId, CollatorId]>[][]
|
||||
type SelectedThreads = ITuple<[ParaId, CollatorId]>[][];
|
||||
type Heads = Bytes;
|
||||
type RelayDispatchQueue = Vec<UpwardMessage>
|
||||
type Watermarks = Option<BlockNumber>;
|
||||
type DidUpdate = Option<Vec<ParaId>>;
|
||||
|
||||
type Result = [
|
||||
ParaId[],
|
||||
[
|
||||
Active,
|
||||
RetryQueue,
|
||||
SelectedThreads,
|
||||
DidUpdate
|
||||
],
|
||||
ParaInfoResult[],
|
||||
PendingSwap[],
|
||||
Heads[],
|
||||
RelayDispatchQueue[],
|
||||
Watermarks[],
|
||||
];
|
||||
|
||||
function parseActive (id: ParaId, active: Active): DeriveParachainActive | null {
|
||||
const found = active.find(([paraId]): boolean => paraId === id);
|
||||
|
||||
if (found && found[1].isSome) {
|
||||
const [collatorId, retriable] = found[1].unwrap();
|
||||
|
||||
return {
|
||||
collatorId,
|
||||
...(
|
||||
retriable.isWithRetries
|
||||
? {
|
||||
isRetriable: true,
|
||||
retries: retriable.asWithRetries.toNumber()
|
||||
}
|
||||
: {
|
||||
isRetriable: false,
|
||||
retries: 0
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function parseCollators (id: ParaId, collatorQueue: SelectedThreads | RetryQueue): (CollatorId | null)[] {
|
||||
return collatorQueue
|
||||
.map((queue): CollatorId | null => {
|
||||
const found = queue.find(([paraId]): boolean => paraId === id);
|
||||
|
||||
return found ? found[1] : null;
|
||||
});
|
||||
}
|
||||
|
||||
function parse ([ids, [active, retryQueue, selectedThreads, didUpdate], infos, pendingSwaps, heads, relayDispatchQueues, watermarks]: Result): DeriveParachain[] {
|
||||
return ids.map((id, index): DeriveParachain => {
|
||||
return {
|
||||
active: parseActive(id, active),
|
||||
didUpdate: didUpdate.isSome
|
||||
? didUpdate.unwrap().some((paraId): boolean => paraId === id)
|
||||
: false,
|
||||
heads: heads[index],
|
||||
id,
|
||||
info: infos[index].unwrapOr(null),
|
||||
pendingSwapId: pendingSwaps[index].unwrapOr(null),
|
||||
relayDispatchQueue: relayDispatchQueues[index],
|
||||
retryCollators: parseCollators(id, retryQueue),
|
||||
selectedCollators: parseCollators(id, selectedThreads),
|
||||
watermark: watermarks[index].unwrapOr(null)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function all (api: ApiInterfaceRx): () => Observable<DeriveParachain[]> {
|
||||
return memo((): Observable<DeriveParachain[]> =>
|
||||
api.query.registrar?.parachains && api.query.parachains
|
||||
? api.query.registrar.parachains<ParaIds>().pipe(
|
||||
switchMap((paraIds) =>
|
||||
combineLatest([
|
||||
of(paraIds),
|
||||
api.queryMulti([
|
||||
api.query.registrar.active,
|
||||
api.query.registrar.retryQueue,
|
||||
api.query.registrar.selectedThreads,
|
||||
api.query.parachains.didUpdate
|
||||
]),
|
||||
api.query.registrar.paras.multi<ParaInfo>(paraIds),
|
||||
api.query.registrar.pendingSwap.multi<PendingSwap>(paraIds),
|
||||
api.query.parachains.heads.multi<Heads>(paraIds),
|
||||
api.query.parachains.relayDispatchQueue.multi<RelayDispatchQueue>(paraIds),
|
||||
api.query.parachains.watermarks.multi<Watermarks>(paraIds)
|
||||
]) as Observable<Result>
|
||||
),
|
||||
map((result: Result): DeriveParachain[] =>
|
||||
parse(result)
|
||||
)
|
||||
)
|
||||
: of([] as DeriveParachain[])
|
||||
);
|
||||
}
|
||||
@@ -2,4 +2,5 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export * from './all';
|
||||
export * from './info';
|
||||
export * from './overview';
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { CollatorId, ParaId } from '@polkadot/types/interfaces';
|
||||
import { DeriveParachainInfo, DeriveParachainFull, DeriveParachainActive } from '../types';
|
||||
import { Active, DidUpdate, Heads, ParaInfoResult, PendingSwap, RelayDispatchQueue, RetryQueue, SelectedThreads, Watermarks } from './types';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type Result = [
|
||||
Active,
|
||||
RetryQueue,
|
||||
SelectedThreads,
|
||||
DidUpdate,
|
||||
ParaInfoResult,
|
||||
PendingSwap,
|
||||
Heads,
|
||||
RelayDispatchQueue,
|
||||
Watermarks
|
||||
];
|
||||
|
||||
function parseActive (id: ParaId, active: Active): DeriveParachainActive | null {
|
||||
const found = active.find(([paraId]): boolean => paraId === id);
|
||||
|
||||
if (found && found[1].isSome) {
|
||||
const [collatorId, retriable] = found[1].unwrap();
|
||||
|
||||
return {
|
||||
collatorId,
|
||||
...(
|
||||
retriable.isWithRetries
|
||||
? {
|
||||
isRetriable: true,
|
||||
retries: retriable.asWithRetries.toNumber()
|
||||
}
|
||||
: {
|
||||
isRetriable: false,
|
||||
retries: 0
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function parseCollators (id: ParaId, collatorQueue: SelectedThreads | RetryQueue): (CollatorId | null)[] {
|
||||
return collatorQueue
|
||||
.map((queue): CollatorId | null => {
|
||||
const found = queue.find(([paraId]): boolean => paraId === id);
|
||||
|
||||
return found ? found[1] : null;
|
||||
});
|
||||
}
|
||||
|
||||
function parse (id: ParaId, [active, retryQueue, selectedThreads, didUpdate, info, pendingSwap, heads, relayDispatchQueue, watermarks]: Result): DeriveParachainFull {
|
||||
return {
|
||||
active: parseActive(id, active),
|
||||
didUpdate: didUpdate.isSome
|
||||
? !!didUpdate.unwrap().some((paraId): boolean => paraId.eq(id))
|
||||
: false,
|
||||
heads,
|
||||
id,
|
||||
info: { id, ...info.unwrapOr(null) } as DeriveParachainInfo,
|
||||
pendingSwapId: pendingSwap.unwrapOr(null),
|
||||
relayDispatchQueue,
|
||||
retryCollators: parseCollators(id, retryQueue),
|
||||
selectedCollators: parseCollators(id, selectedThreads),
|
||||
watermark: watermarks.unwrapOr(null)
|
||||
};
|
||||
}
|
||||
|
||||
export function info (api: ApiInterfaceRx): (id: ParaId | number) => Observable<DeriveParachainFull | null> {
|
||||
return memo((id: ParaId | number): Observable<DeriveParachainFull | null> =>
|
||||
api.query.registrar && api.query.parachains
|
||||
? api.queryMulti<Result>([
|
||||
api.query.registrar.active,
|
||||
api.query.registrar.retryQueue,
|
||||
api.query.registrar.selectedThreads,
|
||||
api.query.parachains.didUpdate,
|
||||
[api.query.registrar.paras, id],
|
||||
[api.query.registrar.pendingSwap, id],
|
||||
[api.query.parachains.heads, id],
|
||||
[api.query.parachains.relayDispatchQueue, id],
|
||||
[api.query.parachains.watermarks, id]
|
||||
])
|
||||
.pipe(
|
||||
map((result: Result): DeriveParachainFull =>
|
||||
parse(createType(api.registry, 'ParaId', id), result)
|
||||
)
|
||||
)
|
||||
: of(null)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ParaId } from '@polkadot/types/interfaces';
|
||||
import { DeriveParachain, DeriveParachainInfo } from '../types';
|
||||
import { DidUpdate, ParaInfoResult, PendingSwap, RelayDispatchQueueSize, Watermarks } from './types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type Result = [
|
||||
ParaId[],
|
||||
DidUpdate,
|
||||
ParaInfoResult[],
|
||||
PendingSwap[],
|
||||
RelayDispatchQueueSize[],
|
||||
Watermarks[],
|
||||
];
|
||||
|
||||
function parse ([ids, didUpdate, infos, pendingSwaps, relayDispatchQueueSizes, watermarks]: Result): DeriveParachain[] {
|
||||
return ids.map((id, index): DeriveParachain => {
|
||||
return {
|
||||
didUpdate: didUpdate.isSome
|
||||
? !!didUpdate.unwrap().some((paraId): boolean => paraId.eq(id))
|
||||
: false,
|
||||
id,
|
||||
info: { id, ...infos[index].unwrapOr(null) } as DeriveParachainInfo,
|
||||
pendingSwapId: pendingSwaps[index].unwrapOr(null),
|
||||
relayDispatchQueueSize: relayDispatchQueueSizes[index][0].toNumber(),
|
||||
watermark: watermarks[index].unwrapOr(null)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function overview (api: ApiInterfaceRx): () => Observable<DeriveParachain[]> {
|
||||
return memo((): Observable<DeriveParachain[]> =>
|
||||
api.query.registrar?.parachains && api.query.parachains
|
||||
? api.query.registrar.parachains<ParaId[]>().pipe(
|
||||
switchMap((paraIds) =>
|
||||
combineLatest([
|
||||
of(paraIds),
|
||||
api.query.parachains.didUpdate<DidUpdate>(),
|
||||
api.query.registrar.paras.multi<ParaInfoResult>(paraIds),
|
||||
api.query.registrar.pendingSwap.multi<PendingSwap>(paraIds),
|
||||
api.query.parachains.relayDispatchQueueSize.multi<RelayDispatchQueueSize>(paraIds),
|
||||
api.query.parachains.watermarks.multi<Watermarks>(paraIds)
|
||||
])
|
||||
),
|
||||
map((result: Result): DeriveParachain[] =>
|
||||
parse(result)
|
||||
)
|
||||
)
|
||||
: of([] as DeriveParachain[])
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { BlockNumber, CollatorId, ParaId, ParaInfo, Retriable, UpwardMessage } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
|
||||
import { Bytes, Option, u32, Vec } from '@polkadot/types';
|
||||
|
||||
export type ParaInfoResult = Option<ParaInfo>;
|
||||
export type PendingSwap = Option<ParaId>;
|
||||
export type Active = Vec<ITuple<[ParaId, Option<ITuple<[CollatorId, Retriable]>>]>>;
|
||||
export type RetryQueue = Vec<Vec<ITuple<[ParaId, CollatorId]>>>
|
||||
export type SelectedThreads = Vec<Vec<ITuple<[ParaId, CollatorId]>>>
|
||||
export type Code = Bytes;
|
||||
export type Heads = Bytes;
|
||||
export type RelayDispatchQueue = Vec<UpwardMessage>
|
||||
export type RelayDispatchQueueSize = ITuple<[u32, u32]>;
|
||||
export type Watermarks = Option<BlockNumber>;
|
||||
export type DidUpdate = Option<Vec<ParaId>>;
|
||||
@@ -3,29 +3,83 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { EraIndex, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { EraIndex, MomentOf, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DeriveSessionIndexes } from '../types';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { createType, u32 as U32 } from '@polkadot/types';
|
||||
import { createType, Option, u32 } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type Result = [EraIndex, Option<MomentOf>, EraIndex, SessionIndex, u32];
|
||||
|
||||
// parse into Indexes
|
||||
function parse ([activeEra, activeEraStart, currentEra, currentIndex, validatorCount]: Result): DeriveSessionIndexes {
|
||||
return {
|
||||
activeEra,
|
||||
activeEraStart,
|
||||
currentEra,
|
||||
currentIndex,
|
||||
validatorCount
|
||||
};
|
||||
}
|
||||
|
||||
// query for previous V2
|
||||
function queryNoActive (api: ApiInterfaceRx): Observable<Result> {
|
||||
return api.queryMulti<[EraIndex, SessionIndex, u32]>([
|
||||
api.query.staking.currentEra,
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.validatorCount
|
||||
]).pipe(
|
||||
map(([currentEra, currentIndex, validatorCount]): Result => [
|
||||
currentEra,
|
||||
createType(api.registry, 'Option<MomentOf>'),
|
||||
currentEra,
|
||||
currentIndex,
|
||||
validatorCount
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
// query based on latest
|
||||
function query (api: ApiInterfaceRx): Observable<Result> {
|
||||
return api.queryMulti<[Option<EraIndex>, Option<MomentOf>, Option<EraIndex>, SessionIndex, u32]>([
|
||||
api.query.staking.activeEra,
|
||||
api.query.staking.activeEraStart,
|
||||
api.query.staking.currentEra,
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.validatorCount
|
||||
]).pipe(
|
||||
map(([activeEra, activeEraStart, currentEra, currentIndex, validatorCount]): Result => [
|
||||
activeEra.unwrapOr(createType(api.registry, 'EraIndex', 1)),
|
||||
activeEraStart,
|
||||
currentEra.unwrapOr(createType(api.registry, 'EraIndex', 1)),
|
||||
currentIndex,
|
||||
validatorCount
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
// empty set when none is available
|
||||
function empty (api: ApiInterfaceRx): Observable<Result> {
|
||||
return of([
|
||||
createType(api.registry, 'EraIndex', 1),
|
||||
createType(api.registry, 'Option<MomentOf>'),
|
||||
createType(api.registry, 'EraIndex', 1),
|
||||
createType(api.registry, 'SessionIndex', 1),
|
||||
createType(api.registry, 'u32')
|
||||
]);
|
||||
}
|
||||
|
||||
export function indexes (api: ApiInterfaceRx): () => Observable<DeriveSessionIndexes> {
|
||||
return memo((): Observable<DeriveSessionIndexes> =>
|
||||
(
|
||||
// Some chains (eg. very limited node-template), does not have session
|
||||
api.query.session && api.query.staking
|
||||
? api.queryMulti<[SessionIndex, EraIndex, U32]>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.currentEra,
|
||||
api.query.staking.validatorCount
|
||||
])
|
||||
: of([createType(api.registry, 'SessionIndex', 1), createType(api.registry, 'EraIndex', 1), createType(api.registry, 'u32')])
|
||||
).pipe(
|
||||
map(([currentIndex, currentEra, validatorCount]): DeriveSessionIndexes => ({
|
||||
currentIndex, currentEra, validatorCount
|
||||
}))
|
||||
));
|
||||
? api.query.staking.activeEra
|
||||
? query(api)
|
||||
: queryNoActive(api)
|
||||
: empty(api)
|
||||
).pipe(map(parse))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,23 +5,26 @@
|
||||
import { SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo, DeriveSessionIndexes } from '../types';
|
||||
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { u64, createType } from '@polkadot/types';
|
||||
import { createType, Option, u64 } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type ResultSlots = [u64, u64, u64, SessionIndex];
|
||||
type ResultSlots = [u64, u64, u64, Option<SessionIndex>];
|
||||
type ResultSlotsFlat = [u64, u64, u64, SessionIndex];
|
||||
type ResultType = [boolean, u64, SessionIndex];
|
||||
type Result = [ResultType, DeriveSessionIndexes, ResultSlots];
|
||||
type Result = [ResultType, DeriveSessionIndexes, ResultSlotsFlat];
|
||||
|
||||
function createDerivedLatest (api: ApiInterfaceRx, [[hasBabe, epochDuration, sessionsPerEra], { currentIndex, currentEra, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, currentEraStartSessionIndex]]: Result): DerivedSessionInfo {
|
||||
function createDerived (api: ApiInterfaceRx, [[hasBabe, epochDuration, sessionsPerEra], { activeEra, activeEraStart, currentEra, currentIndex, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, activeEraStartSessionIndex]]: Result): DerivedSessionInfo {
|
||||
const epochStartSlot = epochIndex.mul(epochDuration).add(epochOrGenesisStartSlot);
|
||||
const sessionProgress = currentSlot.sub(epochStartSlot);
|
||||
const eraProgress = currentIndex.sub(currentEraStartSessionIndex).mul(epochDuration).add(sessionProgress);
|
||||
const eraProgress = currentIndex.sub(activeEraStartSessionIndex).mul(epochDuration).add(sessionProgress);
|
||||
|
||||
return {
|
||||
activeEra,
|
||||
activeEraStart,
|
||||
currentEra,
|
||||
currentIndex,
|
||||
eraLength: createType(api.registry, 'BlockNumber', sessionsPerEra.mul(epochDuration)),
|
||||
@@ -34,46 +37,76 @@ function createDerivedLatest (api: ApiInterfaceRx, [[hasBabe, epochDuration, ses
|
||||
};
|
||||
}
|
||||
|
||||
function infoLatestAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
function queryAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
return api.derive.session.indexes().pipe(
|
||||
map((indexes): DerivedSessionInfo =>
|
||||
createDerivedLatest(api, [
|
||||
[false, createType(api.registry, 'u64', 1), api.consts.staking?.sessionsPerEra || createType(api.registry, 'SessionIndex', 1)],
|
||||
createDerived(api, [
|
||||
[
|
||||
false,
|
||||
createType(api.registry, 'u64', 1),
|
||||
api.consts.staking?.sessionsPerEra || createType(api.registry, 'SessionIndex', 1)
|
||||
],
|
||||
indexes,
|
||||
[createType(api.registry, 'u64', 1), createType(api.registry, 'u64', 1), createType(api.registry, 'u64', 1), createType(api.registry, 'SessionIndex', 1)]
|
||||
[
|
||||
createType(api.registry, 'u64', 1),
|
||||
createType(api.registry, 'u64', 1),
|
||||
createType(api.registry, 'u64', 1),
|
||||
createType(api.registry, 'SessionIndex', 1)
|
||||
]
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
function queryBabe (api: ApiInterfaceRx): Observable<[DeriveSessionIndexes, ResultSlotsFlat]> {
|
||||
return api.derive.session.indexes().pipe(
|
||||
switchMap((indexes): Observable<[DeriveSessionIndexes, ResultSlots]> =>
|
||||
combineLatest([
|
||||
of(indexes),
|
||||
api.queryMulti<ResultSlots>([
|
||||
api.query.babe.currentSlot,
|
||||
api.query.babe.epochIndex,
|
||||
api.query.babe.genesisSlot,
|
||||
[api.query.staking.erasStartSessionIndex, indexes.activeEra]
|
||||
])
|
||||
])
|
||||
),
|
||||
map(([indexes, [currentSlot, epochIndex, genesisSlot, optStartIndex]]): [DeriveSessionIndexes, ResultSlotsFlat] => [
|
||||
indexes, [currentSlot, epochIndex, genesisSlot, optStartIndex.unwrapOr(createType(api.registry, 'SessionIndex', 1))]
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function queryBabeNoHistory (api: ApiInterfaceRx): Observable<[DeriveSessionIndexes, ResultSlotsFlat]> {
|
||||
return combineLatest([
|
||||
api.derive.session.indexes(),
|
||||
api.queryMulti<ResultSlots>([
|
||||
api.queryMulti<ResultSlotsFlat>([
|
||||
api.query.babe.currentSlot,
|
||||
api.query.babe.epochIndex,
|
||||
api.query.babe.genesisSlot,
|
||||
api.query.staking.currentEraStartSessionIndex
|
||||
])
|
||||
]).pipe(
|
||||
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlots]): DerivedSessionInfo =>
|
||||
createDerivedLatest(api, [
|
||||
[true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra],
|
||||
indexes,
|
||||
slots
|
||||
])
|
||||
)
|
||||
);
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras
|
||||
* @description Retrieves all the session and era query and calculates specific values on it as the length of the session and eras
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo> {
|
||||
const query = api.consts.babe
|
||||
? infoLatestBabe // 2.x with Babe
|
||||
: infoLatestAura; // 2.x with Aura (not all info there)
|
||||
|
||||
return memo((): Observable<DerivedSessionInfo> =>
|
||||
query(api));
|
||||
api.consts.babe
|
||||
? (api.query.staking.erasStartSessionIndex
|
||||
? queryBabe(api) // 2.x with Babe
|
||||
: queryBabeNoHistory(api)
|
||||
).pipe(
|
||||
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlotsFlat]): DerivedSessionInfo =>
|
||||
createDerived(api, [
|
||||
[true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra],
|
||||
indexes,
|
||||
slots
|
||||
])
|
||||
)
|
||||
)
|
||||
: queryAura(api)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,16 +14,17 @@ import { memo } from '../util';
|
||||
export function electedInfo (api: ApiInterfaceRx): () => Observable<DerivedStakingElected> {
|
||||
return memo((): Observable<DerivedStakingElected> =>
|
||||
api.derive.staking.validators().pipe(
|
||||
switchMap(({ currentElected }): Observable<[AccountId[], DerivedStakingQuery[]]> =>
|
||||
switchMap(({ nextElected }): Observable<[AccountId[], DerivedStakingQuery[]]> =>
|
||||
combineLatest([
|
||||
of(currentElected),
|
||||
combineLatest(currentElected.map((accountId): Observable<DerivedStakingQuery> =>
|
||||
of(nextElected),
|
||||
combineLatest(nextElected.map((accountId): Observable<DerivedStakingQuery> =>
|
||||
api.derive.staking.query(accountId)
|
||||
))
|
||||
])
|
||||
),
|
||||
map(([currentElected, info]): DerivedStakingElected => ({
|
||||
currentElected, info
|
||||
map(([nextElected, info]): DerivedStakingElected => ({
|
||||
info,
|
||||
nextElected
|
||||
}))
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, Exposure, Keys, Nominations, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { DerivedStakingStash } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type Result = [Option<AccountId>, Nominations, RewardDestination, Exposure, ValidatorPrefs, Option<Keys>];
|
||||
|
||||
function parse (stashId: AccountId, [_controllerId, nominators, rewardDestination, stakers, validatorPrefs, _nextKeys]: Result): DerivedStakingStash {
|
||||
return {
|
||||
controllerId: _controllerId.unwrapOr(undefined),
|
||||
nextKeys: _nextKeys.unwrapOr(undefined),
|
||||
nominators: nominators.targets,
|
||||
nominateAt: nominators.submittedIn,
|
||||
rewardDestination,
|
||||
stakers,
|
||||
stashId,
|
||||
validatorPrefs
|
||||
};
|
||||
}
|
||||
|
||||
function query (api: ApiInterfaceRx, stashId: AccountId): Observable<Result> {
|
||||
return api.queryMulti<Result>([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId],
|
||||
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
|
||||
]);
|
||||
}
|
||||
|
||||
export function infoStash (api: ApiInterfaceRx): (stashId: AccountId) => Observable<DerivedStakingStash> {
|
||||
return memo((stashId: AccountId): Observable<DerivedStakingStash> =>
|
||||
query(api, stashId).pipe(
|
||||
map((result): DerivedStakingStash => parse(stashId, result))
|
||||
));
|
||||
}
|
||||
@@ -2,15 +2,31 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { EraPoints } from '@polkadot/types/interfaces';
|
||||
import { AccountId, EraIndex, EraPoints, EraRewardPoints, RewardPoint } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DerivedStakingOverview } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
function retrievePointsPrev (api: ApiInterfaceRx, activeEra: EraIndex, currentElected: AccountId[]): Observable<EraRewardPoints> {
|
||||
return api.query.staking.currentEraPointsEarned<EraPoints>(activeEra).pipe(
|
||||
map(({ individual, total }): EraRewardPoints =>
|
||||
createType(api.registry, 'EraRewardPoints', {
|
||||
total,
|
||||
individual: new Map<AccountId, RewardPoint>(
|
||||
individual
|
||||
.map((points): RewardPoint => createType(api.registry, 'RewardPoint', points))
|
||||
.map((points, index): [AccountId, RewardPoint] => [currentElected[index], points])
|
||||
)
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Retrieve the staking overview, including elected and points earned
|
||||
*/
|
||||
@@ -20,14 +36,16 @@ export function overview (api: ApiInterfaceRx): () => Observable<DerivedStakingO
|
||||
api.derive.session.indexes(),
|
||||
api.derive.staking.validators()
|
||||
]).pipe(
|
||||
switchMap(([{ currentEra, currentIndex, validatorCount }, { currentElected, validators }]) =>
|
||||
switchMap(([indexes, { nextElected, validators }]) =>
|
||||
combineLatest([
|
||||
of({ currentElected, currentEra, currentIndex, validators, validatorCount }),
|
||||
api.query.staking.currentEraPointsEarned<EraPoints>(currentEra)
|
||||
of({ ...indexes, nextElected, validators }),
|
||||
api.query.staking.erasRewardPoints
|
||||
? api.query.staking.erasRewardPoints<EraRewardPoints>(indexes.activeEra)
|
||||
: retrievePointsPrev(api, indexes.activeEra, nextElected)
|
||||
])
|
||||
),
|
||||
map(([{ currentElected, currentEra, currentIndex, validators, validatorCount }, eraPoints]): DerivedStakingOverview => ({
|
||||
currentElected, currentEra, currentIndex, eraPoints, validators, validatorCount
|
||||
map(([info, eraPoints]): DerivedStakingOverview => ({
|
||||
...info, eraPoints
|
||||
}))
|
||||
));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, Exposure, Keys, Nominations, RewardDestination, StakingLedger, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { AccountId, Exposure, Keys, Nominations, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
import { DerivedStakingQuery } from '../types';
|
||||
|
||||
@@ -13,7 +13,7 @@ import { createType, Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type MultiResultV2 = [Option<AccountId>, Option<ITuple<[Nominations]>>, RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>, Option<StakingLedger>];
|
||||
type MultiResult = [Option<AccountId>, Option<ITuple<[Nominations]>>, RewardDestination, ITuple<[ValidatorPrefs]>, Option<Keys>, Exposure];
|
||||
|
||||
function unwrapSessionIds (stashId: AccountId, queuedKeys: [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; sessionIds: AccountId[] } {
|
||||
const sessionIds = (queuedKeys.find(([currentId]): boolean =>
|
||||
@@ -27,20 +27,52 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: [AccountId, Keys][],
|
||||
};
|
||||
}
|
||||
|
||||
function retrieve (api: ApiInterfaceRx, stashId: AccountId): Observable<[Vec<ITuple<[AccountId, Keys]>>, MultiResultV2]> {
|
||||
return combineLatest([
|
||||
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
|
||||
api.queryMulti([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId],
|
||||
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
|
||||
]) as Observable<MultiResultV2>
|
||||
function retrievePrev (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResult> {
|
||||
return api.queryMulti<MultiResult>([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.validators, stashId],
|
||||
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]],
|
||||
[api.query.staking.stakers, stashId]
|
||||
]);
|
||||
}
|
||||
|
||||
function retrieveCurr (api: ApiInterfaceRx, stashId: AccountId): Observable<MultiResult> {
|
||||
return api.derive.session.indexes().pipe(
|
||||
switchMap(({ activeEra }) =>
|
||||
api.queryMulti<MultiResult>([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.validators, stashId],
|
||||
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]],
|
||||
[api.query.staking.erasStakers, [activeEra, stashId]]
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function retrieveController (api: ApiInterfaceRx, stashId: AccountId, [queuedKeys, [controllerIdOpt, nominatorsOpt, rewardDestination, [validatorPrefs], nextKeys, exposure]]: [Vec<ITuple<[AccountId, Keys]>>, MultiResult]): Observable<DerivedStakingQuery> {
|
||||
const controllerId = controllerIdOpt.unwrapOr(null);
|
||||
|
||||
return controllerId
|
||||
? api.query.staking.ledger(controllerId).pipe(
|
||||
map((stakingLedgerOpt): DerivedStakingQuery => ({
|
||||
accountId: stashId,
|
||||
controllerId,
|
||||
exposure,
|
||||
nominators: nominatorsOpt.unwrapOr([{ targets: [] }])[0].targets,
|
||||
rewardDestination,
|
||||
stakingLedger: stakingLedgerOpt.unwrapOr(undefined),
|
||||
stashId,
|
||||
validatorPrefs,
|
||||
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
|
||||
}))
|
||||
)
|
||||
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] });
|
||||
}
|
||||
|
||||
/**
|
||||
* @description From a stash, retrieve the controllerId and all relevant details
|
||||
*/
|
||||
@@ -48,26 +80,15 @@ export function query (api: ApiInterfaceRx): (accountId: Uint8Array | string) =>
|
||||
return memo((accountId: Uint8Array | string): Observable<DerivedStakingQuery> => {
|
||||
const stashId = createType(api.registry, 'AccountId', accountId);
|
||||
|
||||
return retrieve(api, stashId).pipe(
|
||||
switchMap(([queuedKeys, [controllerIdOpt, nominatorsOpt, rewardDestination, stakers, [validatorPrefs], nextKeys]]): Observable<DerivedStakingQuery> => {
|
||||
const controllerId = controllerIdOpt.unwrapOr(null);
|
||||
|
||||
return controllerId
|
||||
? api.query.staking.ledger(controllerId).pipe(
|
||||
map((stakingLedgerOpt): DerivedStakingQuery => ({
|
||||
accountId: stashId,
|
||||
controllerId,
|
||||
nominators: nominatorsOpt.unwrapOr([{ targets: [] }])[0].targets,
|
||||
rewardDestination,
|
||||
stakers,
|
||||
stakingLedger: stakingLedgerOpt.unwrapOr(undefined),
|
||||
stashId,
|
||||
validatorPrefs,
|
||||
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
|
||||
}))
|
||||
)
|
||||
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] });
|
||||
})
|
||||
return combineLatest([
|
||||
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
|
||||
api.query.staking.erasStakers
|
||||
? retrieveCurr(api, stashId)
|
||||
: retrievePrev(api, stashId)
|
||||
]).pipe(
|
||||
switchMap((result): Observable<DerivedStakingQuery> =>
|
||||
retrieveController(api, stashId, result)
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,12 +22,16 @@ export function validators (api: ApiInterfaceRx): () => Observable<DeriveStaking
|
||||
api.query.session
|
||||
? api.query.session.validators()
|
||||
: of([]),
|
||||
api.query.staking
|
||||
? api.query.staking.currentElected()
|
||||
// FIXME need a replacement for currentElected in new
|
||||
api.query.staking?.currentElected
|
||||
? api.query.staking.erasStakers
|
||||
? of(null)
|
||||
: api.query.staking.currentElected()
|
||||
: of([])
|
||||
]).pipe(
|
||||
map(([validators, currentElected]): DeriveStakingValidators => ({
|
||||
currentElected, validators
|
||||
map(([validators, nextElected]): DeriveStakingValidators => ({
|
||||
nextElected: nextElected || validators,
|
||||
validators
|
||||
}))
|
||||
));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, Header } from '@polkadot/types/interfaces';
|
||||
import { AnyJsonObject, Constructor, Registry } from '@polkadot/types/types';
|
||||
import { AnyJson, Constructor, Registry } from '@polkadot/types/types';
|
||||
|
||||
import runtimeTypes from '@polkadot/types/interfaces/runtime/definitions';
|
||||
import { Struct } from '@polkadot/types';
|
||||
@@ -17,12 +17,12 @@ const _Header: Constructor<Header> = Struct.with(runtimeTypes.types.Header as an
|
||||
* A [[Block]] header with an additional `author` field that indicates the block author
|
||||
*/
|
||||
export default class HeaderExtended extends _Header {
|
||||
private _author?: AccountId;
|
||||
readonly #author?: AccountId;
|
||||
|
||||
constructor (registry: Registry, header?: Header, sessionValidators?: AccountId[]) {
|
||||
super(registry, header);
|
||||
|
||||
this._author = this.extractAuthor(sessionValidators);
|
||||
this.#author = this.extractAuthor(sessionValidators);
|
||||
}
|
||||
|
||||
private extractAuthor (sessionValidators: AccountId[] = []): AccountId | undefined {
|
||||
@@ -51,15 +51,27 @@ export default class HeaderExtended extends _Header {
|
||||
* @description Convenience method, returns the author for the block
|
||||
*/
|
||||
public get author (): AccountId | undefined {
|
||||
return this._author;
|
||||
return this.#author;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates a human-friendly JSON representation
|
||||
*/
|
||||
public toHuman (isExtended?: boolean): AnyJson {
|
||||
return {
|
||||
...super.toHuman(isExtended) as { [index: string]: AnyJson },
|
||||
author: this.author
|
||||
? this.author.toHuman()
|
||||
: undefined
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates the JSON representation
|
||||
*/
|
||||
public toJSON (): AnyJsonObject {
|
||||
public toJSON (): AnyJson {
|
||||
return {
|
||||
...super.toJSON() as AnyJsonObject,
|
||||
...super.toJSON() as { [index: string]: AnyJson },
|
||||
author: this.author
|
||||
? this.author.toJSON()
|
||||
: undefined
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ReferendumIndex, ReferendumInfo } from '@polkadot/types/interfaces/democracy';
|
||||
import { AnyJsonObject, Constructor, Registry } from '@polkadot/types/types';
|
||||
import { AnyJson, Constructor, Registry } from '@polkadot/types/types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import democracyTypes from '@polkadot/types/interfaces/democracy/definitions';
|
||||
import { Struct, createType } from '@polkadot/types';
|
||||
import { Struct } from '@polkadot/types';
|
||||
|
||||
// We can ignore the properties, added via Struct.with
|
||||
const _ReferendumInfo: Constructor<ReferendumInfo> = Struct.with(democracyTypes.types.ReferendumInfo as any) as any;
|
||||
@@ -18,29 +18,39 @@ const _ReferendumInfo: Constructor<ReferendumInfo> = Struct.with(democracyTypes.
|
||||
* A [[ReferendumInfo]] with an additional `index` field
|
||||
*/
|
||||
export default class ReferendumInfoExtended extends _ReferendumInfo {
|
||||
private _index: ReferendumIndex;
|
||||
readonly #index: ReferendumIndex;
|
||||
|
||||
constructor (registry: Registry, value: ReferendumInfo | ReferendumInfoExtended, index?: BN | number) {
|
||||
super(registry, value);
|
||||
|
||||
this._index = value instanceof ReferendumInfoExtended
|
||||
this.#index = value instanceof ReferendumInfoExtended
|
||||
? value.index
|
||||
: createType(registry, 'ReferendumIndex', index);
|
||||
: registry.createType('ReferendumIndex', index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Convenience getter, returns the referendumIndex
|
||||
*/
|
||||
public get index (): ReferendumIndex {
|
||||
return this._index;
|
||||
return this.#index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates a human-friendly JSON representation
|
||||
*/
|
||||
public toHuman (isExtended?: boolean): AnyJson {
|
||||
return {
|
||||
...super.toHuman(isExtended) as { [index: string]: AnyJson },
|
||||
index: this.index.toHuman(isExtended)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates the JSON representation
|
||||
*/
|
||||
public toJSON (): AnyJsonObject {
|
||||
public toJSON (): AnyJson {
|
||||
return {
|
||||
...super.toJSON() as AnyJsonObject,
|
||||
...super.toJSON() as { [index: string]: AnyJson },
|
||||
index: this.index.toJSON()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, AccountIndex, Balance, BalanceLock, BalanceLockTo212, BalanceOf, Bid, BidKind, BlockNumber, CollatorId, EraIndex, EraPoints, Exposure, Hash, Index, Keys, ParaId, ParaInfo, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, SocietyVote, StakingLedger, StrikeCount, TreasuryProposal, UpwardMessage, ValidatorPrefs, Vote, Votes, VoteIndex, VouchingStatus } from '@polkadot/types/interfaces';
|
||||
import { AccountId, AccountIndex, Balance, BalanceLock, BalanceLockTo212, BalanceOf, Bid, BidKind, BlockNumber, CollatorId, EraIndex, EraRewardPoints, Exposure, Hash, Index, Keys, MomentOf, ParaId, ParaInfo, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RegistrationJudgement, RewardDestination, SessionIndex, SetIndex, SocietyVote, StakingLedger, StrikeCount, TreasuryProposal, UpwardMessage, ValidatorPrefs, Vote, Votes, VoteIndex, VouchingStatus } from '@polkadot/types/interfaces';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Bytes, u32, Vec } from '@polkadot/types';
|
||||
import { Bytes, Option, u32, Vec } from '@polkadot/types';
|
||||
|
||||
export type AccountIndexes = Record<string, AccountIndex>;
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface DeriveAccountRegistration {
|
||||
email?: string;
|
||||
image?: string;
|
||||
legal?: string;
|
||||
other?: Record<string, string>;
|
||||
parent?: AccountId;
|
||||
pgp?: string;
|
||||
riot?: string;
|
||||
@@ -113,17 +114,28 @@ export interface DeriveParachainActive {
|
||||
retries: number;
|
||||
}
|
||||
|
||||
export interface DeriveParachainInfo extends ParaInfo {
|
||||
id: ParaId;
|
||||
icon?: string;
|
||||
name?: string;
|
||||
owner?: string;
|
||||
}
|
||||
|
||||
export interface DeriveParachain {
|
||||
active: DeriveParachainActive | null;
|
||||
didUpdate: boolean;
|
||||
pendingSwapId: ParaId | null;
|
||||
heads: Bytes | null;
|
||||
id: ParaId;
|
||||
info: ParaInfo | null;
|
||||
info: DeriveParachainInfo | null;
|
||||
relayDispatchQueueSize?: number;
|
||||
watermark: BlockNumber | null;
|
||||
}
|
||||
|
||||
export interface DeriveParachainFull extends DeriveParachain {
|
||||
active: DeriveParachainActive | null;
|
||||
heads: Bytes | null;
|
||||
relayDispatchQueue: UpwardMessage[];
|
||||
retryCollators: (CollatorId | null)[];
|
||||
selectedCollators: (CollatorId | null)[];
|
||||
watermark: BlockNumber | null;
|
||||
}
|
||||
|
||||
export interface DeriveProposalPreImage {
|
||||
@@ -159,6 +171,8 @@ export interface DerivedReferendumVote {
|
||||
}
|
||||
|
||||
export interface DeriveSessionIndexes {
|
||||
activeEra: EraIndex;
|
||||
activeEraStart: Option<MomentOf>;
|
||||
currentEra: EraIndex;
|
||||
currentIndex: SessionIndex;
|
||||
validatorCount: u32;
|
||||
@@ -200,22 +214,22 @@ export interface DeriveSocietyMember {
|
||||
}
|
||||
|
||||
export interface DerivedStakingElected {
|
||||
currentElected: AccountId[];
|
||||
nextElected: AccountId[];
|
||||
info: DerivedStakingQuery[];
|
||||
}
|
||||
|
||||
export interface DeriveStakingValidators {
|
||||
currentElected: AccountId[];
|
||||
nextElected: AccountId[];
|
||||
validators: AccountId[];
|
||||
}
|
||||
|
||||
export interface DerivedStakingStash {
|
||||
controllerId?: AccountId;
|
||||
exposure?: Exposure;
|
||||
nominators?: AccountId[];
|
||||
nominateAt?: EraIndex;
|
||||
rewardDestination?: RewardDestination;
|
||||
nextKeys?: Keys;
|
||||
stakers?: Exposure;
|
||||
stashId?: AccountId;
|
||||
validatorPrefs?: ValidatorPrefs;
|
||||
}
|
||||
@@ -233,8 +247,8 @@ export interface DerivedStakingAccount extends DerivedStakingQuery {
|
||||
}
|
||||
|
||||
export interface DerivedStakingOverview extends DeriveSessionIndexes {
|
||||
currentElected: AccountId[];
|
||||
eraPoints: EraPoints;
|
||||
eraPoints: EraRewardPoints;
|
||||
nextElected: AccountId[];
|
||||
validators: AccountId[];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { ApprovalFlag } from '@polkadot/types/interfaces';
|
||||
|
||||
import { createType, TypeRegistry } from '@polkadot/types';
|
||||
import { TypeRegistry } from '@polkadot/types';
|
||||
|
||||
import { approvalFlagsToBools } from './approvalFlagsToBools';
|
||||
|
||||
@@ -20,7 +20,7 @@ describe('approvalFlagsToBools', (): void => {
|
||||
it('translates a single input', (): void => {
|
||||
expect(
|
||||
approvalFlagsToBools([
|
||||
createType(registry, 'ApprovalFlag', 0b1010)
|
||||
registry.createType('ApprovalFlag', 0b1010)
|
||||
])
|
||||
).toEqual([false, true, false, true]);
|
||||
});
|
||||
@@ -28,8 +28,8 @@ describe('approvalFlagsToBools', (): void => {
|
||||
it('translates multiple inputs', (): void => {
|
||||
expect(
|
||||
approvalFlagsToBools([
|
||||
createType(registry, 'ApprovalFlag', 0b0000),
|
||||
createType(registry, 'ApprovalFlag', 0b1100)
|
||||
registry.createType('ApprovalFlag', 0b0000),
|
||||
registry.createType('ApprovalFlag', 0b1100)
|
||||
])
|
||||
).toEqual([false, false, false, true, true]);
|
||||
});
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api",
|
||||
"version": "1.2.1",
|
||||
"version": "1.4.1",
|
||||
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -27,19 +27,19 @@
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.4",
|
||||
"@polkadot/api-derive": "^1.2.1",
|
||||
"@polkadot/keyring": "^2.3.1",
|
||||
"@polkadot/metadata": "^1.2.1",
|
||||
"@polkadot/rpc-core": "^1.2.1",
|
||||
"@polkadot/rpc-provider": "^1.2.1",
|
||||
"@polkadot/types": "^1.2.1",
|
||||
"@polkadot/util": "^2.3.1",
|
||||
"@polkadot/util-crypto": "^2.3.1",
|
||||
"@polkadot/api-derive": "1.4.1",
|
||||
"@polkadot/keyring": "^2.5.1",
|
||||
"@polkadot/metadata": "1.4.1",
|
||||
"@polkadot/rpc-core": "1.4.1",
|
||||
"@polkadot/rpc-provider": "1.4.1",
|
||||
"@polkadot/types": "1.4.1",
|
||||
"@polkadot/util": "^2.5.1",
|
||||
"@polkadot/util-crypto": "^2.5.1",
|
||||
"bn.js": "^5.1.1",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"rxjs": "^6.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^2.3.1"
|
||||
"@polkadot/keyring": "^2.5.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
|
||||
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface */
|
||||
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
import { Bytes, u32, u64 } from '@polkadot/types/primitive';
|
||||
import { Balance, BalanceOf, BlockNumber, Moment, Percent, Permill } from '@polkadot/types/interfaces/runtime';
|
||||
import { Gas } from '@polkadot/types/interfaces/contracts';
|
||||
import { Balance, BalanceOf, BlockNumber, Moment, Percent, Permill } from '@polkadot/types/interfaces/runtime';
|
||||
import { SessionIndex } from '@polkadot/types/interfaces/session';
|
||||
import { EraIndex } from '@polkadot/types/interfaces/staking';
|
||||
|
||||
declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
export interface Constants {
|
||||
[index: string]: ModuleConstants;
|
||||
babe: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* The number of **slots** that an epoch takes. We couple sessions to
|
||||
* epochs, i.e. we start a new session once the new epoch begins.
|
||||
@@ -27,7 +28,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
expectedBlockTime: AugmentedConst<Moment>;
|
||||
};
|
||||
timestamp: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* The minimum period between blocks. Beware that this is different to the *expected* period
|
||||
* that the block production apparatus provides. Your chosen consensus system will generally
|
||||
@@ -37,14 +38,14 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
minimumPeriod: AugmentedConst<Moment>;
|
||||
};
|
||||
balances: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* The minimum amount required to keep an account open.
|
||||
**/
|
||||
existentialDeposit: AugmentedConst<Balance>;
|
||||
};
|
||||
transactionPayment: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* The fee to be paid for making a transaction; the base.
|
||||
**/
|
||||
@@ -55,7 +56,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
transactionByteFee: AugmentedConst<BalanceOf>;
|
||||
};
|
||||
staking: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* Number of sessions per era.
|
||||
**/
|
||||
@@ -66,7 +67,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
bondingDuration: AugmentedConst<EraIndex>;
|
||||
};
|
||||
session: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* Used as first key for `NextKeys` and `KeyOwner` to put all the data into the same branch
|
||||
* of the trie.
|
||||
@@ -74,7 +75,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
dedupKeyPrefix: AugmentedConst<Bytes>;
|
||||
};
|
||||
democracy: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* The minimum period of locking and the period between a proposal being approved and enacted.
|
||||
* It should generally be a little more than the unstake period to ensure that
|
||||
@@ -108,7 +109,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
preimageByteDeposit: AugmentedConst<BalanceOf>;
|
||||
};
|
||||
elections: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
candidacyBond: AugmentedConst<BalanceOf>;
|
||||
votingBond: AugmentedConst<BalanceOf>;
|
||||
desiredMembers: AugmentedConst<u32>;
|
||||
@@ -116,7 +117,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
termDuration: AugmentedConst<BlockNumber>;
|
||||
};
|
||||
finalityTracker: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* The number of recent samples to keep from this chain. Default is 101.
|
||||
**/
|
||||
@@ -127,7 +128,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
reportLatency: AugmentedConst<BlockNumber>;
|
||||
};
|
||||
treasury: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* Fraction of a proposal's value that should be bonded in order to place the proposal.
|
||||
* An accepted proposal gets these back. A rejected proposal does not.
|
||||
@@ -163,7 +164,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
tipReportDepositPerByte: AugmentedConst<BalanceOf>;
|
||||
};
|
||||
contracts: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* Number of block delay an extrinsic claim surcharge has.
|
||||
* When claim surcharge is called by an extrinsic the rent is checked
|
||||
@@ -236,7 +237,7 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||
blockGasLimit: AugmentedConst<Gas>;
|
||||
};
|
||||
society: {
|
||||
[index: string]: Codec;
|
||||
[index: string]: AugmentedConst<object & Codec>;
|
||||
/**
|
||||
* The minimum amount of a deposit required for a bid to be made.
|
||||
**/
|
||||
@@ -1,10 +1,9 @@
|
||||
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
|
||||
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface */
|
||||
|
||||
import { AnyNumber, ITuple } from '@polkadot/types/types';
|
||||
import { Option, Raw, Vec } from '@polkadot/types/codec';
|
||||
import { Option, U8aFixed, Vec } from '@polkadot/types/codec';
|
||||
import { Bytes, Data, bool, u32, u64 } from '@polkadot/types/primitive';
|
||||
import { AccountId, AccountIndex, Balance, BalanceOf, BlockNumber, Hash, Index, KeyTypeId, Moment, Perbill, ValidatorId, Weight } from '@polkadot/types/interfaces/runtime';
|
||||
import { UncleEntryItem } from '@polkadot/types/interfaces/authorship';
|
||||
import { BabeAuthorityWeight, MaybeVrf } from '@polkadot/types/interfaces/babe';
|
||||
import { AccountData, BalanceLock } from '@polkadot/types/interfaces/balances';
|
||||
@@ -18,6 +17,7 @@ import { RegistrarInfo, Registration } from '@polkadot/types/interfaces/identity
|
||||
import { AuthIndex } from '@polkadot/types/interfaces/imOnline';
|
||||
import { Kind, OffenceDetails, OpaqueTimeSlot, ReportIdOf } from '@polkadot/types/interfaces/offences';
|
||||
import { ActiveRecovery, RecoveryConfig } from '@polkadot/types/interfaces/recovery';
|
||||
import { AccountId, AccountIndex, Balance, BalanceOf, BlockNumber, Hash, Index, KeyTypeId, Moment, Perbill, ValidatorId, Weight } from '@polkadot/types/interfaces/runtime';
|
||||
import { Keys, SessionIndex } from '@polkadot/types/interfaces/session';
|
||||
import { Bid, BidKind, SocietyVote, StrikeCount, VouchingStatus } from '@polkadot/types/interfaces/society';
|
||||
import { EraIndex, EraPoints, Exposure, Forcing, MomentOf, Nominations, RewardDestination, SlashingSpans, SpanIndex, SpanRecord, StakingLedger, UnappliedSlash, ValidatorPrefs } from '@polkadot/types/interfaces/staking';
|
||||
@@ -27,6 +27,7 @@ import { Multiplier } from '@polkadot/types/interfaces/txpayment';
|
||||
import { Multisig } from '@polkadot/types/interfaces/utility';
|
||||
import { VestingInfo } from '@polkadot/types/interfaces/vesting';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ApiTypes } from '@polkadot/api/types';
|
||||
|
||||
declare module '@polkadot/api/types/storage' {
|
||||
export interface AugmentedQueries<ApiType> {
|
||||
@@ -97,7 +98,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
/**
|
||||
* The set of open multisig operations.
|
||||
**/
|
||||
multisigs: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: Raw | string | Uint8Array) => Observable<Option<Multisig>>, AccountId | string | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
multisigs: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: U8aFixed | string | Uint8Array) => Observable<Option<Multisig>>> & QueryableStorageEntry<ApiType>;
|
||||
};
|
||||
babe: {
|
||||
[index: string]: QueryableStorageEntry<ApiType>;
|
||||
@@ -128,11 +129,11 @@ declare module '@polkadot/api/types/storage' {
|
||||
* used where a number is needed that cannot have been chosen by an
|
||||
* adversary, for purposes such as public-coin zero-knowledge proofs.
|
||||
**/
|
||||
randomness: AugmentedQuery<ApiType, () => Observable<Raw>> & QueryableStorageEntry<ApiType>;
|
||||
randomness: AugmentedQuery<ApiType, () => Observable<U8aFixed>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* Next epoch randomness.
|
||||
**/
|
||||
nextRandomness: AugmentedQuery<ApiType, () => Observable<Raw>> & QueryableStorageEntry<ApiType>;
|
||||
nextRandomness: AugmentedQuery<ApiType, () => Observable<U8aFixed>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* Randomness under construction.
|
||||
* We make a tradeoff between storage accesses and list length.
|
||||
@@ -143,7 +144,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
* epoch.
|
||||
**/
|
||||
segmentIndex: AugmentedQuery<ApiType, () => Observable<u32>> & QueryableStorageEntry<ApiType>;
|
||||
underConstruction: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Vec<Raw>>> & QueryableStorageEntry<ApiType>;
|
||||
underConstruction: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Vec<U8aFixed>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* Temporary value (cleared at block finalization) which is `Some`
|
||||
* if per-block initialization has already been called for current block.
|
||||
@@ -306,11 +307,11 @@ declare module '@polkadot/api/types/storage' {
|
||||
* All slashing events on validators, mapped by era to the highest slash proportion
|
||||
* and slash value of the era.
|
||||
**/
|
||||
validatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ITuple<[Perbill, BalanceOf]>>>, EraIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
validatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ITuple<[Perbill, BalanceOf]>>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* All slashing events on nominators, mapped by era to the highest slash value of the era.
|
||||
**/
|
||||
nominatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<BalanceOf>>, EraIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
nominatorSlashInEra: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<BalanceOf>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* Slashing spans for stash accounts.
|
||||
**/
|
||||
@@ -319,7 +320,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
* Records information about the maximum slash of a stash within a slashing span,
|
||||
* as well as how much reward has been paid out.
|
||||
**/
|
||||
spanSlash: AugmentedQuery<ApiType, (arg: ITuple<[AccountId, SpanIndex]>) => Observable<SpanRecord>> & QueryableStorageEntry<ApiType>;
|
||||
spanSlash: AugmentedQuery<ApiType, (arg: ITuple<[AccountId, SpanIndex]> | [AccountId | string | Uint8Array, SpanIndex | AnyNumber | Uint8Array]) => Observable<SpanRecord>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* The earliest era for which we have a pending, unapplied slash.
|
||||
**/
|
||||
@@ -355,13 +356,13 @@ declare module '@polkadot/api/types/storage' {
|
||||
* The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of
|
||||
* the trie. Having all data in the same branch should prevent slowing down other queries.
|
||||
**/
|
||||
nextKeys: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<Option<Keys>>, Bytes | string | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
nextKeys: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<Option<Keys>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* The owner of a key. The second key is the `KeyTypeId` + the encoded key.
|
||||
* The first key is always `DEDUP_KEY_PREFIX` to have all the data in the same branch of
|
||||
* the trie. Having all data in the same branch should prevent slowing down other queries.
|
||||
**/
|
||||
keyOwner: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ITuple<[KeyTypeId, Bytes]>) => Observable<Option<ValidatorId>>, Bytes | string | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
keyOwner: AugmentedQueryDoubleMap<ApiType, (key1: Bytes | string | Uint8Array, key2: ITuple<[KeyTypeId, Bytes]> | [KeyTypeId | AnyNumber | Uint8Array, Bytes | string | Uint8Array]) => Observable<Option<ValidatorId>>> & QueryableStorageEntry<ApiType>;
|
||||
};
|
||||
democracy: {
|
||||
[index: string]: QueryableStorageEntry<ApiType>;
|
||||
@@ -409,7 +410,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
* default `Vote` value otherwise). If you don't want to check `voters_for`, then you can
|
||||
* also check for simple existence with `VoteOf::contains_key` first.
|
||||
**/
|
||||
voteOf: AugmentedQuery<ApiType, (arg: ITuple<[ReferendumIndex, AccountId]>) => Observable<Vote>> & QueryableStorageEntry<ApiType>;
|
||||
voteOf: AugmentedQuery<ApiType, (arg: ITuple<[ReferendumIndex, AccountId]> | [ReferendumIndex | AnyNumber | Uint8Array, AccountId | string | Uint8Array]) => Observable<Vote>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* Who is able to vote for whom. Value is the fund-holding account, key is the
|
||||
* vote-transaction-sending account.
|
||||
@@ -643,12 +644,12 @@ declare module '@polkadot/api/types/storage' {
|
||||
* For each session index, we keep a mapping of `AuthIndex`
|
||||
* to `offchain::OpaqueNetworkState`.
|
||||
**/
|
||||
receivedHeartbeats: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: AuthIndex | AnyNumber | Uint8Array) => Observable<Option<Bytes>>, SessionIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
receivedHeartbeats: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: AuthIndex | AnyNumber | Uint8Array) => Observable<Option<Bytes>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* For each session index, we keep a mapping of `T::ValidatorId` to the
|
||||
* number of blocks authored by the given authority.
|
||||
**/
|
||||
authoredBlocks: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<u32>, SessionIndex | AnyNumber | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
authoredBlocks: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<u32>> & QueryableStorageEntry<ApiType>;
|
||||
};
|
||||
offences: {
|
||||
[index: string]: QueryableStorageEntry<ApiType>;
|
||||
@@ -659,7 +660,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
/**
|
||||
* A vector of reports of the same kind that happened at the same time slot.
|
||||
**/
|
||||
concurrentReportsIndex: AugmentedQueryDoubleMap<ApiType, (key1: Kind | string | Uint8Array, key2: OpaqueTimeSlot | string | Uint8Array) => Observable<Vec<ReportIdOf>>, Kind | string | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
concurrentReportsIndex: AugmentedQueryDoubleMap<ApiType, (key1: Kind | string | Uint8Array, key2: OpaqueTimeSlot | string | Uint8Array) => Observable<Vec<ReportIdOf>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* Enumerates all reports of a kind along with the time they happened.
|
||||
* All reports are sorted by the time of offence.
|
||||
@@ -754,7 +755,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
/**
|
||||
* Double map from Candidate -> Voter -> (Maybe) Vote.
|
||||
**/
|
||||
votes: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<SocietyVote>>, AccountId | string | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
votes: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<SocietyVote>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* The defending member currently being challenged.
|
||||
**/
|
||||
@@ -779,7 +780,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
* First account is the account to be recovered, and the second account
|
||||
* is the user trying to recover the account.
|
||||
**/
|
||||
activeRecoveries: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ActiveRecovery>>, AccountId | string | Uint8Array> & QueryableStorageEntry<ApiType>;
|
||||
activeRecoveries: AugmentedQueryDoubleMap<ApiType, (key1: AccountId | string | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Option<ActiveRecovery>>> & QueryableStorageEntry<ApiType>;
|
||||
/**
|
||||
* The final list of recovered accounts.
|
||||
* Map from the recovered account to the user who can access it.
|
||||
@@ -794,4 +795,8 @@ declare module '@polkadot/api/types/storage' {
|
||||
vesting: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<VestingInfo>>> & QueryableStorageEntry<ApiType>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface QueryableStorage<ApiType extends ApiTypes> extends AugmentedQueries<ApiType> {
|
||||
[index: string]: QueryableModuleStorage<ApiType>;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
|
||||
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface */
|
||||
|
||||
import { AnyNumber, Codec, IExtrinsic } from '@polkadot/types/types';
|
||||
import { Option, Vec } from '@polkadot/types/codec';
|
||||
import { Bytes, H256, StorageData, StorageKey, Text, bool, u32, u64 } from '@polkadot/types/primitive';
|
||||
import { Bytes, StorageKey, Text, bool, u32, u64 } from '@polkadot/types/primitive';
|
||||
import { Metadata } from '@polkadot/types';
|
||||
import { AccountId, BlockNumber, Extrinsic, Hash, Header, Index, SignedBlock } from '@polkadot/types/interfaces/runtime';
|
||||
import { ContractCallRequest, ContractExecResult } from '@polkadot/types/interfaces/contracts';
|
||||
import { Extrinsic } from '@polkadot/types/interfaces/extrinsics';
|
||||
import { BlockHash, ChainProperties, ExtrinsicOrHash, ExtrinsicStatus, Health, NetworkState, PeerInfo, RpcMethods, RuntimeDispatchInfo, RuntimeVersion, StorageChangeSet } from '@polkadot/types/interfaces/rpc';
|
||||
import { AccountId, BlockNumber, H256, Hash, Header, Index, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
declare module '@polkadot/rpc-core/types.jsonrpc' {
|
||||
@@ -69,6 +70,10 @@ declare module '@polkadot/rpc-core/types.jsonrpc' {
|
||||
* Retrieves the header for a specific block
|
||||
**/
|
||||
getHeader(hash?: BlockHash | string | Uint8Array): Observable<Header>;
|
||||
/**
|
||||
* Retrieves the newest header via subscription
|
||||
**/
|
||||
subscribeAllHeads(): Observable<Header>;
|
||||
/**
|
||||
* Retrieves the best finalized header via subscription
|
||||
**/
|
||||
@@ -1,22 +1,23 @@
|
||||
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
|
||||
// Auto-generated via `yarn polkadot-types-from-chain`, do not edit
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface */
|
||||
|
||||
import { AnyNumber, ITuple } from '@polkadot/types/types';
|
||||
import { Compact, Option, Raw, Vec } from '@polkadot/types/codec';
|
||||
import { Bytes, Data, IdentityFields, bool, u16, u32, u64 } from '@polkadot/types/primitive';
|
||||
import { AccountId, AccountIndex, Address, Balance, BalanceOf, BlockNumber, Call, ChangesTrieConfiguration, Hash, Header, KeyValue, LookupSource, Moment, Signature } from '@polkadot/types/interfaces/runtime';
|
||||
import { Compact, Option, U8aFixed, Vec } from '@polkadot/types/codec';
|
||||
import { Bytes, Data, bool, u16, u32, u64 } from '@polkadot/types/primitive';
|
||||
import { MemberCount, ProposalIndex } from '@polkadot/types/interfaces/collective';
|
||||
import { CodeHash, Gas, Schedule } from '@polkadot/types/interfaces/contracts';
|
||||
import { Conviction, PropIndex, Proposal, ReferendumIndex } from '@polkadot/types/interfaces/democracy';
|
||||
import { Vote } from '@polkadot/types/interfaces/elections';
|
||||
import { IdentityInfo, IdentityJudgement, RegistrarIndex } from '@polkadot/types/interfaces/identity';
|
||||
import { Signature } from '@polkadot/types/interfaces/extrinsics';
|
||||
import { IdentityFields, IdentityInfo, IdentityJudgement, RegistrarIndex } from '@polkadot/types/interfaces/identity';
|
||||
import { Heartbeat } from '@polkadot/types/interfaces/imOnline';
|
||||
import { AccountId, AccountIndex, Address, Balance, BalanceOf, BlockNumber, Call, ChangesTrieConfiguration, Hash, Header, KeyValue, LookupSource, Moment } from '@polkadot/types/interfaces/runtime';
|
||||
import { Keys } from '@polkadot/types/interfaces/session';
|
||||
import { SocietyJudgement } from '@polkadot/types/interfaces/society';
|
||||
import { EraIndex, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces/staking';
|
||||
import { Key } from '@polkadot/types/interfaces/system';
|
||||
import { Timepoint } from '@polkadot/types/interfaces/utility';
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
|
||||
import { ApiTypes, SubmittableExtrinsic } from '@polkadot/api/types';
|
||||
|
||||
declare module '@polkadot/api/types/submittable' {
|
||||
export interface AugmentedSubmittables<ApiType> {
|
||||
@@ -151,7 +152,7 @@ declare module '@polkadot/api/types/submittable' {
|
||||
* `MultisigDepositBase + threshold * MultisigDepositFactor`.
|
||||
* # </weight>
|
||||
**/
|
||||
approveAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], maybeTimepoint: Option<Timepoint> | null | object | string | Uint8Array, callHash: Raw | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
|
||||
approveAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], maybeTimepoint: Option<Timepoint> | null | object | string | Uint8Array, callHash: U8aFixed | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
|
||||
/**
|
||||
* Cancel a pre-existing, on-going multisig transaction. Any deposit reserved previously
|
||||
* for this operation will be unreserved on success.
|
||||
@@ -173,7 +174,7 @@ declare module '@polkadot/api/types/submittable' {
|
||||
* - Storage: removes one item.
|
||||
* # </weight>
|
||||
**/
|
||||
cancelAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], timepoint: Timepoint | { height?: any; index?: any } | string | Uint8Array, callHash: Raw | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
|
||||
cancelAsMulti: AugmentedSubmittable<(threshold: u16 | AnyNumber | Uint8Array, otherSignatories: Vec<AccountId> | (AccountId | string | Uint8Array)[], timepoint: Timepoint | { height?: any; index?: any } | string | Uint8Array, callHash: U8aFixed | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
|
||||
};
|
||||
timestamp: {
|
||||
[index: string]: SubmittableExtrinsicFunction<ApiType>;
|
||||
@@ -1621,4 +1622,9 @@ declare module '@polkadot/api/types/submittable' {
|
||||
vestOther: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface SubmittableExtrinsics<ApiType extends ApiTypes> extends AugmentedSubmittables<ApiType> {
|
||||
(extrinsic: Uint8Array | string): SubmittableExtrinsic<ApiType>;
|
||||
[index: string]: SubmittableModuleExtrinsics<ApiType>;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
import { Constants, Storage } from '@polkadot/metadata/Decorated/types';
|
||||
import { RpcInterface } from '@polkadot/rpc-core/types';
|
||||
import { InterfaceRegistry } from '@polkadot/types/interfaceRegistry';
|
||||
import { Call, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import { AnyFunction, CallFunction, Codec, CodecArg as Arg, ITuple, InterfaceTypes, ModulesWithCalls, Registry, RegistryTypes } from '@polkadot/types/types';
|
||||
import { SubmittableExtrinsic } from '../submittable/types';
|
||||
@@ -14,17 +13,19 @@ import BN from 'bn.js';
|
||||
import { BehaviorSubject, Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import decorateDerive, { ExactDerive } from '@polkadot/api-derive';
|
||||
import DecoratedMeta from '@polkadot/metadata/Decorated';
|
||||
import getHasher from '@polkadot/metadata/Decorated/storage/fromMetadata/getHasher';
|
||||
import RpcCore from '@polkadot/rpc-core';
|
||||
import { WsProvider } from '@polkadot/rpc-provider';
|
||||
import { Metadata, Null, Option, TypeRegistry, u64, Vec } from '@polkadot/types';
|
||||
import { Metadata, Null, Option, Text, TypeRegistry, u64, Vec } from '@polkadot/types';
|
||||
import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage';
|
||||
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/primitive/Extrinsic/constants';
|
||||
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/extrinsic/constants';
|
||||
import StorageKey, { StorageEntry } from '@polkadot/types/primitive/StorageKey';
|
||||
import { assert, compactStripLength, isNull, isUndefined, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { createSubmittable } from '../submittable';
|
||||
import { decorateSections, DeriveAllSections } from '../util/decorate';
|
||||
import augmentObject from '../util/augmentObject';
|
||||
import Events from './Events';
|
||||
|
||||
interface MetaDecoration {
|
||||
@@ -43,11 +44,11 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
// HACK Use BN import so decorateDerive works... yes, wtf.
|
||||
protected __phantom = new BN(0);
|
||||
|
||||
protected _consts?: Constants;
|
||||
protected _consts: Constants = {} as Constants;
|
||||
|
||||
protected _derive?: ReturnType<Decorate<ApiType>['decorateDerive']>;
|
||||
|
||||
protected _extrinsics?: SubmittableExtrinsics<ApiType>;
|
||||
protected _extrinsics: SubmittableExtrinsics<ApiType> = {} as SubmittableExtrinsics<ApiType>;
|
||||
|
||||
protected _extrinsicType: number = EXTRINSIC_DEFAULT_VERSION;
|
||||
|
||||
@@ -59,7 +60,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
|
||||
protected readonly _options: ApiOptions;
|
||||
|
||||
protected _query?: QueryableStorage<ApiType>;
|
||||
protected _query: QueryableStorage<ApiType> = {} as QueryableStorage<ApiType>;
|
||||
|
||||
protected _queryMulti?: QueryableStorageMulti<ApiType>;
|
||||
|
||||
@@ -67,11 +68,17 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
|
||||
protected _rpcCore: RpcCore;
|
||||
|
||||
protected _runtimeChain?: Text;
|
||||
|
||||
protected _runtimeMetadata?: Metadata;
|
||||
|
||||
protected _runtimeVersion?: RuntimeVersion;
|
||||
|
||||
protected _rx: Partial<ApiInterfaceRx> = {};
|
||||
protected _rx: ApiInterfaceRx = {
|
||||
consts: {} as Constants,
|
||||
query: {} as QueryableStorage<'rxjs'>,
|
||||
tx: {} as SubmittableExtrinsics<'rxjs'>
|
||||
} as ApiInterfaceRx;
|
||||
|
||||
protected _type: ApiTypes;
|
||||
|
||||
@@ -129,9 +136,19 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
this._rx.registry = this.registry;
|
||||
}
|
||||
|
||||
public abstract createType <K extends InterfaceTypes> (type: K, ...params: any[]): InterfaceRegistry[K];
|
||||
/**
|
||||
* @description Creates an instance of a type as registered
|
||||
*/
|
||||
public createType <K extends keyof InterfaceTypes> (type: K, ...params: any[]): InterfaceTypes[K] {
|
||||
return this.registry.createType(type, ...params);
|
||||
}
|
||||
|
||||
public abstract registerTypes (types?: RegistryTypes): void;
|
||||
/**
|
||||
* @description Register additional user-defined of chain-specific types in the type registry
|
||||
*/
|
||||
public registerTypes (types?: RegistryTypes): void {
|
||||
types && this.registry.register(types);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns `true` if the API operates with subscriptions
|
||||
@@ -140,6 +157,20 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
return this._rpcCore.provider.hasSubscriptions;
|
||||
}
|
||||
|
||||
public injectMetadata (metadata: Metadata, fromEmpty?: boolean): void {
|
||||
const decoratedMeta = new DecoratedMeta(this.registry, metadata);
|
||||
|
||||
// this API
|
||||
augmentObject('tx', this.decorateExtrinsics(decoratedMeta.tx, this.decorateMethod), this._extrinsics, fromEmpty);
|
||||
augmentObject('query', this.decorateStorage(decoratedMeta.query, this.decorateMethod), this._query, fromEmpty);
|
||||
augmentObject('consts', decoratedMeta.consts, this._consts, fromEmpty);
|
||||
|
||||
// rx
|
||||
augmentObject('', this.decorateExtrinsics(decoratedMeta.tx, this.rxDecorateMethod), this._rx.tx, fromEmpty);
|
||||
augmentObject('', this.decorateStorage(decoratedMeta.query, this.rxDecorateMethod), this._rx.query, fromEmpty);
|
||||
augmentObject('', decoratedMeta.consts, this._rx.consts, fromEmpty);
|
||||
}
|
||||
|
||||
private decorateFunctionMeta (input: MetaDecoration, output: MetaDecoration): MetaDecoration {
|
||||
output.meta = input.meta;
|
||||
output.method = input.method;
|
||||
@@ -219,7 +250,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
}
|
||||
|
||||
protected decorateExtrinsics<ApiType extends ApiTypes> (extrinsics: ModulesWithCalls, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType> {
|
||||
const creator = createSubmittable(this._type, this._rx as ApiInterfaceRx, decorateMethod);
|
||||
const creator = createSubmittable(this._type, this._rx, decorateMethod);
|
||||
|
||||
return Object.entries(extrinsics).reduce((out, [name, section]): SubmittableExtrinsics<ApiType> => {
|
||||
out[name] = Object.entries(section).reduce((out, [name, method]): SubmittableModuleExtrinsics<ApiType> => {
|
||||
@@ -411,13 +442,13 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
||||
|
||||
protected decorateDeriveRx (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<'rxjs', ExactDerive> {
|
||||
// Pull in derive from api-derive
|
||||
const derive = decorateDerive(this._rx as ApiInterfaceRx, this._options.derives);
|
||||
const derive = decorateDerive(this._rx, this._options.derives);
|
||||
|
||||
return decorateSections<'rxjs', ExactDerive>(derive, decorateMethod);
|
||||
}
|
||||
|
||||
protected decorateDerive (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<ApiType, ExactDerive> {
|
||||
return decorateSections<ApiType, ExactDerive>(this._rx.derive as DeriveAllSections<'rxjs', ExactDerive>, decorateMethod);
|
||||
return decorateSections<ApiType, ExactDerive>(this._rx.derive, decorateMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,10 +7,10 @@ import { ApiInterfaceEvents } from '../types';
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
export default class Events {
|
||||
private _eventemitter = new EventEmitter();
|
||||
#eventemitter = new EventEmitter();
|
||||
|
||||
protected emit (type: ApiInterfaceEvents, ...args: any[]): boolean {
|
||||
return this._eventemitter.emit(type, ...args);
|
||||
return this.#eventemitter.emit(type, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ export default class Events {
|
||||
* ```
|
||||
*/
|
||||
public on (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this {
|
||||
this._eventemitter.on(type, handler);
|
||||
this.#eventemitter.on(type, handler);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ export default class Events {
|
||||
* ```
|
||||
*/
|
||||
public off (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this {
|
||||
this._eventemitter.removeListener(type, handler);
|
||||
this.#eventemitter.removeListener(type, handler);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ export default class Events {
|
||||
* ```
|
||||
*/
|
||||
public once (type: ApiInterfaceEvents, handler: (...args: any[]) => any): this {
|
||||
this._eventemitter.once(type, handler);
|
||||
this.#eventemitter.once(type, handler);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -2,31 +2,33 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SignedBlock } from '@polkadot/types/interfaces';
|
||||
import { SignedBlock, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import { ApiBase, ApiOptions, ApiTypes, DecorateMethod } from '../types';
|
||||
|
||||
import DecoratedMeta from '@polkadot/metadata/Decorated';
|
||||
import { Metadata, u32 as U32 } from '@polkadot/types';
|
||||
import { getChainTypes, getMetadataTypes } from '@polkadot/types/known';
|
||||
import { LATEST_EXTRINSIC_VERSION } from '@polkadot/types/primitive/Extrinsic/Extrinsic';
|
||||
import { Subscription, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Metadata, Text } from '@polkadot/types';
|
||||
import { LATEST_EXTRINSIC_VERSION } from '@polkadot/types/extrinsic/Extrinsic';
|
||||
import { getMetadataTypes, getSpecTypes, getUserTypes } from '@polkadot/types/known';
|
||||
import { logger } from '@polkadot/util';
|
||||
import { cryptoWaitReady, setSS58Format } from '@polkadot/util-crypto';
|
||||
import addressDefaults from '@polkadot/util-crypto/address/defaults';
|
||||
import { cryptoWaitReady } from '@polkadot/util-crypto';
|
||||
|
||||
import Decorate from './Decorate';
|
||||
|
||||
const KEEPALIVE_INTERVAL = 15000;
|
||||
|
||||
const l = logger('api/decorator');
|
||||
const l = logger('api/init');
|
||||
|
||||
export default abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
private _healthTimer: NodeJS.Timeout | null = null;
|
||||
#healthTimer: NodeJS.Timeout | null = null;
|
||||
|
||||
#updateSub?: Subscription;
|
||||
|
||||
constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super(options, type, decorateMethod);
|
||||
|
||||
if (!this.hasSubscriptions) {
|
||||
console.warn('Api will be available in a limited mode since the provider does not support subscriptions');
|
||||
l.warn('Api will be available in a limited mode since the provider does not support subscriptions');
|
||||
}
|
||||
|
||||
// We only register the types (global) if this is not a cloned instance.
|
||||
@@ -42,28 +44,43 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
this._rx.queryMulti = this.decorateMulti(this.rxDecorateMethod);
|
||||
this._rx.signer = options.signer;
|
||||
|
||||
this._rpcCore.provider.on('disconnected', this._onProviderDisconnect);
|
||||
this._rpcCore.provider.on('error', this._onProviderError);
|
||||
this._rpcCore.provider.on('connected', this._onProviderConnect);
|
||||
this._rpcCore.provider.on('disconnected', this.#onProviderDisconnect);
|
||||
this._rpcCore.provider.on('error', this.#onProviderError);
|
||||
this._rpcCore.provider.on('connected', this.#onProviderConnect);
|
||||
|
||||
// If the provider was instantiated earlier, and has already emitted a
|
||||
// 'connected' event, then the `on('connected')` won't fire anymore. To
|
||||
// cater for this case, we call manually `this._onProviderConnect`.
|
||||
if (this._rpcCore.provider.isConnected()) {
|
||||
this._onProviderConnect();
|
||||
this.#onProviderConnect();
|
||||
}
|
||||
}
|
||||
|
||||
protected async loadMeta (): Promise<boolean> {
|
||||
const genesisHash = await this._rpcCore.chain.getBlockHash(0).toPromise();
|
||||
|
||||
// on re-connection to the same chain, we don't want to re-do everything from chain again
|
||||
if (this._isReady && !this._options.source && genesisHash.eq(this._genesisHash)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this._genesisHash) {
|
||||
l.warn('Connection to new genesis detected, re-initializing');
|
||||
}
|
||||
|
||||
this._genesisHash = genesisHash;
|
||||
|
||||
if (this.#updateSub) {
|
||||
this.#updateSub.unsubscribe();
|
||||
}
|
||||
|
||||
const { metadata = {} } = this._options;
|
||||
|
||||
// only load from on-chain if we are not a clone (default path), alternatively
|
||||
// just use the values from the source instance provided
|
||||
if (!this._options.source || !this._options.source._isReady) {
|
||||
this._runtimeMetadata = await this.metaFromChain(metadata);
|
||||
} else {
|
||||
this._runtimeMetadata = await this.metaFromSource(this._options.source);
|
||||
}
|
||||
this._runtimeMetadata = this._options.source?._isReady
|
||||
? await this.metaFromSource(this._options.source)
|
||||
: await this.metaFromChain(metadata);
|
||||
|
||||
return this.initFromMeta(this._runtimeMetadata);
|
||||
}
|
||||
@@ -73,6 +90,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
this._extrinsicType = source.extrinsicVersion;
|
||||
this._runtimeVersion = source.runtimeVersion;
|
||||
this._genesisHash = source.genesisHash;
|
||||
this.registry.setChainProperties(source.registry.getChainProperties());
|
||||
|
||||
const methods: string[] = [];
|
||||
|
||||
@@ -89,34 +107,64 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
return source.runtimeMetadata;
|
||||
}
|
||||
|
||||
// subscribe to metadata updates, inject the types on changes
|
||||
private subscribeUpdates (): void {
|
||||
if (this.#updateSub) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.#updateSub = this._rpcCore.state.subscribeRuntimeVersion().pipe(
|
||||
switchMap((version: RuntimeVersion) =>
|
||||
combineLatest(
|
||||
of(version),
|
||||
this._rpcCore.state.getMetadata()
|
||||
)
|
||||
),
|
||||
map(([version, metadata]: [RuntimeVersion, Metadata]): boolean => {
|
||||
if (this._runtimeVersion?.specVersion.eq(version.specVersion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
l.log(`Runtime version updated to ${version.specVersion}`);
|
||||
|
||||
this._runtimeMetadata = metadata;
|
||||
this._runtimeVersion = version;
|
||||
|
||||
this.registerTypes(getSpecTypes(this._runtimeChain as Text, version));
|
||||
this.injectMetadata(metadata, false);
|
||||
|
||||
return true;
|
||||
})
|
||||
).subscribe();
|
||||
}
|
||||
|
||||
private async metaFromChain (optMetadata: Record<string, string>): Promise<Metadata> {
|
||||
const { typesChain, typesSpec } = this._options;
|
||||
const [genesisHash, runtimeVersion, chain, chainProps] = await Promise.all([
|
||||
this._rpcCore.chain.getBlockHash(0).toPromise(),
|
||||
const [runtimeVersion, chain, chainProps] = await Promise.all([
|
||||
this._rpcCore.state.getRuntimeVersion().toPromise(),
|
||||
this._rpcCore.system.chain().toPromise(),
|
||||
this._rpcCore.system.properties().toPromise()
|
||||
]);
|
||||
|
||||
// based on the node spec & chain, inject specific type overrides
|
||||
this.registerTypes(getChainTypes(chain, runtimeVersion, typesChain, typesSpec));
|
||||
// set our chain version & genesisHash as returned
|
||||
this._runtimeChain = chain;
|
||||
this._runtimeVersion = runtimeVersion;
|
||||
|
||||
// do the setup for the specific chain
|
||||
this.registry.setChainProperties(chainProps);
|
||||
this.registerTypes(getSpecTypes(chain, runtimeVersion));
|
||||
this.registerTypes(getUserTypes(chain, runtimeVersion, typesChain, typesSpec));
|
||||
this.subscribeUpdates();
|
||||
|
||||
// filter the RPC methods (this does an rpc-methods call)
|
||||
await this.filterRpc();
|
||||
|
||||
// retrieve metadata, either from chain or as pass-in via options
|
||||
const metadataKey = `${genesisHash}-${runtimeVersion.specVersion}`;
|
||||
const metadataKey = `${this._genesisHash}-${runtimeVersion.specVersion}`;
|
||||
const metadata = metadataKey in optMetadata
|
||||
? new Metadata(this.registry, optMetadata[metadataKey])
|
||||
: await this._rpcCore.state.getMetadata().toPromise();
|
||||
|
||||
// set our chain version & genesisHash as returned
|
||||
this._genesisHash = genesisHash;
|
||||
this._runtimeVersion = runtimeVersion;
|
||||
|
||||
// set the global ss58Format as detected by the chain
|
||||
setSS58Format(chainProps.ss58Format.unwrapOr(new U32(this.registry, addressDefaults.prefix)).toNumber());
|
||||
|
||||
// get unique types & validate
|
||||
metadata.getUniqTypes(false);
|
||||
|
||||
@@ -127,7 +175,6 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
// inject types based on metadata, if applicable
|
||||
this.registerTypes(getMetadataTypes(metadata.version));
|
||||
|
||||
const decoratedMeta = new DecoratedMeta(this.registry, metadata);
|
||||
const metaExtrinsic = metadata.asLatest.extrinsic;
|
||||
|
||||
// only inject if we are not a clone (global init)
|
||||
@@ -141,16 +188,11 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
this._extrinsicType = firstTx ? firstTx.type : LATEST_EXTRINSIC_VERSION;
|
||||
}
|
||||
|
||||
this._extrinsics = this.decorateExtrinsics(decoratedMeta.tx, this.decorateMethod);
|
||||
this._query = this.decorateStorage(decoratedMeta.query, this.decorateMethod);
|
||||
this._consts = decoratedMeta.consts;
|
||||
|
||||
this._rx.extrinsicType = this._extrinsicType;
|
||||
this._rx.genesisHash = this._genesisHash;
|
||||
this._rx.runtimeVersion = this._runtimeVersion;
|
||||
this._rx.tx = this.decorateExtrinsics(decoratedMeta.tx, this.rxDecorateMethod);
|
||||
this._rx.query = this.decorateStorage(decoratedMeta.query, this.rxDecorateMethod);
|
||||
this._rx.consts = decoratedMeta.consts;
|
||||
|
||||
this.injectMetadata(metadata, true);
|
||||
|
||||
// derive is last, since it uses the decorated rx
|
||||
this._rx.derive = this.decorateDeriveRx(this.rxDecorateMethod);
|
||||
@@ -159,7 +201,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
return true;
|
||||
}
|
||||
|
||||
private _onProviderConnect = async (): Promise<void> => {
|
||||
#onProviderConnect = async (): Promise<void> => {
|
||||
this.emit('connected');
|
||||
this._isConnected.next(true);
|
||||
|
||||
@@ -175,7 +217,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
this.emit('ready', this);
|
||||
}
|
||||
|
||||
this._healthTimer = setInterval((): void => {
|
||||
this.#healthTimer = setInterval((): void => {
|
||||
this._rpcCore.system.health().toPromise().catch((): void => {
|
||||
// ignore
|
||||
});
|
||||
@@ -189,17 +231,17 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
||||
}
|
||||
}
|
||||
|
||||
private _onProviderDisconnect = (): void => {
|
||||
#onProviderDisconnect = (): void => {
|
||||
this.emit('disconnected');
|
||||
this._isConnected.next(false);
|
||||
|
||||
if (this._healthTimer) {
|
||||
clearInterval(this._healthTimer);
|
||||
this._healthTimer = null;
|
||||
if (this.#healthTimer) {
|
||||
clearInterval(this.#healthTimer);
|
||||
this.#healthTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
private _onProviderError = (error: Error): void => {
|
||||
#onProviderError = (error: Error): void => {
|
||||
this.emit('error', error);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
import { Constants } from '@polkadot/metadata/Decorated/types';
|
||||
import { RpcInterface } from '@polkadot/rpc-core/types';
|
||||
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import { InterfaceRegistry } from '@polkadot/types/interfaceRegistry';
|
||||
import { CallFunction, InterfaceTypes, RegistryError, RegistryTypes, SignerPayloadRawBase } from '@polkadot/types/types';
|
||||
import { CallFunction, RegistryError, SignerPayloadRawBase } from '@polkadot/types/types';
|
||||
import { ApiInterfaceRx, ApiOptions, ApiTypes, DecoratedRpc, DecorateMethod, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics, Signer } from '../types';
|
||||
|
||||
import { Metadata, createType } from '@polkadot/types';
|
||||
import { Metadata } from '@polkadot/types';
|
||||
import { assert, isString, isUndefined, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import Init from './Init';
|
||||
@@ -22,15 +21,21 @@ interface SignerRawOptions {
|
||||
signer?: Signer;
|
||||
}
|
||||
|
||||
let pkgJson: { name: string; version: string };
|
||||
|
||||
try {
|
||||
pkgJson = require('../package.json');
|
||||
} catch (error) {
|
||||
// development environment
|
||||
pkgJson = { name: '@polkadot/api', version: '-' };
|
||||
interface PkgJson {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
let pkgJson: PkgJson = { name: '@polkadot/api', version: '-' };
|
||||
|
||||
import('../package.json')
|
||||
.then((_pkgJson: any): void => {
|
||||
pkgJson = _pkgJson;
|
||||
})
|
||||
.catch((): void => {
|
||||
// ignore
|
||||
});
|
||||
|
||||
function assertResult<T> (value: T | undefined): T {
|
||||
assert(!isUndefined(value), 'Api needs to be initialized before using, listen on \'ready\'');
|
||||
|
||||
@@ -228,13 +233,6 @@ export default abstract class ApiBase<ApiType extends ApiTypes> extends Init<Api
|
||||
return assertResult(this._extrinsics);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates an instance of a type as registered
|
||||
*/
|
||||
public createType = <K extends InterfaceTypes> (type: K, ...params: any[]): InterfaceRegistry[K] => {
|
||||
return createType(this.registry, type, ...params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Disconnect from the underlying provider, halting all network traffic
|
||||
*/
|
||||
@@ -256,13 +254,6 @@ export default abstract class ApiBase<ApiType extends ApiTypes> extends Init<Api
|
||||
return this.registry.findMetaError(u8aToU8a(errorIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Register additional user-defined of chain-specific types in the type registry
|
||||
*/
|
||||
public registerTypes (types?: RegistryTypes): void {
|
||||
types && this.registry.register(types);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Set an external signer which will be used to sign extrinsic when account passed in is not KeyringPair
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ import { IExtrinsic, IMethod } from '@polkadot/types/types';
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { HeaderExtended } from '@polkadot/api-derive';
|
||||
import testKeyring, { TestKeyringMap } from '@polkadot/keyring/testingPairs';
|
||||
import { createType, createTypeUnsafe, TypeRegistry } from '@polkadot/types/codec';
|
||||
import { createTypeUnsafe, TypeRegistry } from '@polkadot/types';
|
||||
|
||||
import { SubmittableResult } from './';
|
||||
|
||||
@@ -75,21 +75,22 @@ async function rpc (api: ApiPromise): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
function types (): void {
|
||||
function types (api: ApiPromise): void {
|
||||
// check correct types with `createType`
|
||||
const balance = createType(registry, 'Balance', 2);
|
||||
const gas = createType(registry, 'Gas', 2);
|
||||
const compact = createType(registry, 'Compact<u32>', 2);
|
||||
// const random = createType(registry, 'RandomType', 2); // This one should deliberately show a TS error
|
||||
const balance = registry.createType('Balance', 2);
|
||||
const gas = registry.createType('Gas', 2);
|
||||
const compact = registry.createType('Compact<u32>', 2);
|
||||
// const random = registry.createType('RandomType', 2); // This one should deliberately show a TS error
|
||||
|
||||
const gasUnsafe = createTypeUnsafe(registry, 'Gas', [2]);
|
||||
const overriddenUnsafe = createTypeUnsafe<Header>(registry, 'Gas', [2]);
|
||||
|
||||
console.log(balance, gas, compact, gasUnsafe, overriddenUnsafe);
|
||||
console.log(balance, gas, compact, gasUnsafe, overriddenUnsafe, api.createType('AccountData'));
|
||||
}
|
||||
|
||||
async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
|
||||
const transfer = api.tx.balances.transfer(keyring.bob.address, 12345);
|
||||
// transfer, also allows for BigInt inputs here
|
||||
const transfer = api.tx.balances.transfer(keyring.bob.address, 123_456_789n);
|
||||
|
||||
console.log('transfer as Call', transfer as IMethod);
|
||||
console.log('transfer as Extrinsic', transfer as IExtrinsic);
|
||||
@@ -138,7 +139,7 @@ async function main (): Promise<void> {
|
||||
derive(api);
|
||||
query(api, keyring);
|
||||
rpc(api);
|
||||
types();
|
||||
types(api);
|
||||
tx(api, keyring);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
|
||||
// eslint-disable-next-line no-useless-catch
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
detectPackage(require('./package.json'), __dirname);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
// FIXME This really should be `import(...).then(...)`, but need to check rejections
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
detectPackage(require('./package.json'), __dirname);
|
||||
|
||||
export { Keyring } from '@polkadot/keyring';
|
||||
export { WsProvider } from '@polkadot/rpc-provider';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ApiOptions } from '../types';
|
||||
import createPair from '@polkadot/keyring/pair';
|
||||
import testKeyring from '@polkadot/keyring/testing';
|
||||
import Mock from '@polkadot/rpc-provider/mock/index';
|
||||
import { createType, TypeRegistry } from '@polkadot/types';
|
||||
import { TypeRegistry } from '@polkadot/types';
|
||||
import { hexToU8a } from '@polkadot/util';
|
||||
|
||||
import { SingleAccountSigner } from '../../test/util';
|
||||
@@ -17,7 +17,8 @@ describe('ApiPromise', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
const keyring = testKeyring({ type: 'ed25519' });
|
||||
const aliceEd = keyring.addPair(
|
||||
createPair('ed25519', {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
createPair({ toSS58: keyring.encodeAddress, type: 'ed25519' }, {
|
||||
secretKey: hexToU8a('0xabf8e5bdbe30c65656c0a3cbd181ff8a56294a69dfedd27982aace4a7690911588dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee'),
|
||||
publicKey: hexToU8a('0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee')
|
||||
})
|
||||
@@ -32,7 +33,7 @@ describe('ApiPromise', (): void => {
|
||||
describe('initialization', (): void => {
|
||||
it('Create API instance with metadata map and makes the runtime, rpc, state & extrinsics available', async (): Promise<void> => {
|
||||
const rpcData = await provider.send('state_getMetadata', []);
|
||||
const genesisHash = createType(registry, 'Hash', await provider.send('chain_getBlockHash', [])).toHex();
|
||||
const genesisHash = registry.createType('Hash', await provider.send('chain_getBlockHash', [])).toHex();
|
||||
const specVersion = 0;
|
||||
const metadata: any = {};
|
||||
const key = `${genesisHash}-${specVersion}`;
|
||||
@@ -120,15 +121,12 @@ describe('ApiPromise', (): void => {
|
||||
|
||||
const signer = new SingleAccountSigner(registry, aliceEd);
|
||||
const api = await ApiPromise.create({ provider, registry, signer });
|
||||
const transfer = api.tx.balances.transfer(keyring.getPair('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e').address, 12345);
|
||||
const transfer = api.tx.balances.transfer(keyring.getPair('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e').address, 321_564_789_876_512_345n);
|
||||
|
||||
await transfer.signAsync(aliceEd.address, {});
|
||||
|
||||
expect(transfer.signature.toHex()).toEqual(
|
||||
// v1 extrinsic
|
||||
// '0x6b9ccc95afbd4e916d30c65c720f4f7b70a77db545735b48a763844aa5210e695aa346686bad1224af77d00bcfbf6fc8d2c216a60731027835d5a414186a2607'
|
||||
// v4 extrinsic
|
||||
'0x0716cbdc3b649dad8741238bcc8e4336f859c518cf2b17a3427b2f5d0b8a79cf518da71b9ac71d92c517342e0978f297f5e05362babf5987d3f1c5ba3314af08'
|
||||
'0x62bfcd07a9f50ba32ed9e2c41ca11267ac62a24c95949e25efdccc4989d48573f84754dbbaa1d0937ceb888ad8a2cf71daced1545a839d9d6cceac33a5771401'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -173,7 +173,7 @@ export function decorateMethod<Method extends AnyFunction> (method: Method, opti
|
||||
* ```
|
||||
*/
|
||||
export default class ApiPromise extends ApiBase<'promise'> {
|
||||
private _isReadyPromise: Promise<ApiPromise>;
|
||||
#isReadyPromise: Promise<ApiPromise>;
|
||||
|
||||
/**
|
||||
* @description Creates an ApiPromise instance using the supplied provider. Returns an Promise containing the actual Api instance.
|
||||
@@ -216,7 +216,7 @@ export default class ApiPromise extends ApiBase<'promise'> {
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'promise', decorateMethod);
|
||||
|
||||
this._isReadyPromise = new Promise((resolve, reject): void => {
|
||||
this.#isReadyPromise = new Promise((resolve, reject): void => {
|
||||
super.once('ready', (): void => {
|
||||
resolve(this);
|
||||
});
|
||||
@@ -230,7 +230,7 @@ export default class ApiPromise extends ApiBase<'promise'> {
|
||||
* @description Promise that returns the first time we are connected and loaded
|
||||
*/
|
||||
public get isReady (): Promise<ApiPromise> {
|
||||
return this._isReadyPromise;
|
||||
return this.#isReadyPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,31 +13,31 @@ export interface CombinatorFunction {
|
||||
}
|
||||
|
||||
export default class Combinator {
|
||||
protected _allHasFired = false;
|
||||
#allHasFired = false;
|
||||
|
||||
protected _callback: CombinatorCallback;
|
||||
#callback: CombinatorCallback;
|
||||
|
||||
protected _fired: boolean[] = [];
|
||||
#fired: boolean[] = [];
|
||||
|
||||
protected _fns: CombinatorFunction[] = [];
|
||||
#fns: CombinatorFunction[] = [];
|
||||
|
||||
protected _isActive = true;
|
||||
#isActive = true;
|
||||
|
||||
protected _results: any[] = [];
|
||||
#results: any[] = [];
|
||||
|
||||
protected _subscriptions: UnsubscribePromise[] = [];
|
||||
#subscriptions: UnsubscribePromise[] = [];
|
||||
|
||||
constructor (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback) {
|
||||
this._callback = callback;
|
||||
this.#callback = callback;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
this._subscriptions = fns.map(async (input, index): UnsubscribePromise => {
|
||||
this.#subscriptions = fns.map(async (input, index): UnsubscribePromise => {
|
||||
const [fn, ...args] = Array.isArray(input)
|
||||
? input
|
||||
: [input];
|
||||
|
||||
this._fired.push(false);
|
||||
this._fns.push(fn);
|
||||
this.#fired.push(false);
|
||||
this.#fns.push(fn);
|
||||
|
||||
// Not quite 100% how to have a variable number at the front here
|
||||
return (fn as Function)(...args, this.createCallback(index));
|
||||
@@ -45,43 +45,43 @@ export default class Combinator {
|
||||
}
|
||||
|
||||
protected allHasFired (): boolean {
|
||||
if (!this._allHasFired) {
|
||||
this._allHasFired = this._fired.filter((hasFired): boolean => !hasFired).length === 0;
|
||||
if (!this.#allHasFired) {
|
||||
this.#allHasFired = this.#fired.filter((hasFired): boolean => !hasFired).length === 0;
|
||||
}
|
||||
|
||||
return this._allHasFired;
|
||||
return this.#allHasFired;
|
||||
}
|
||||
|
||||
protected createCallback (index: number): (value: any) => void {
|
||||
return (value: any): void => {
|
||||
this._fired[index] = true;
|
||||
this._results[index] = value;
|
||||
this.#fired[index] = true;
|
||||
this.#results[index] = value;
|
||||
|
||||
this.triggerUpdate();
|
||||
};
|
||||
}
|
||||
|
||||
protected triggerUpdate (): void {
|
||||
if (!this._isActive || !isFunction(this._callback) || !this.allHasFired()) {
|
||||
if (!this.#isActive || !isFunction(this.#callback) || !this.allHasFired()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this._callback(this._results);
|
||||
this.#callback(this.#results);
|
||||
} catch (error) {
|
||||
// swallow, we don't want the handler to trip us up
|
||||
}
|
||||
}
|
||||
|
||||
public unsubscribe (): void {
|
||||
if (!this._isActive) {
|
||||
if (!this.#isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isActive = false;
|
||||
this.#isActive = false;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||
this._subscriptions.forEach(async (subscription): Promise<void> => {
|
||||
this.#subscriptions.forEach(async (subscription): Promise<void> => {
|
||||
try {
|
||||
const unsubscribe = await subscription;
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ export function decorateMethod <Method extends AnyFunction> (method: Method): Me
|
||||
* ```
|
||||
*/
|
||||
export default class ApiRx extends ApiBase<'rxjs'> {
|
||||
private _isReadyRx: Observable<ApiRx>;
|
||||
#isReadyRx: Observable<ApiRx>;
|
||||
|
||||
/**
|
||||
* @description Creates an ApiRx instance using the supplied provider. Returns an Observable containing the actual Api instance.
|
||||
@@ -163,7 +163,7 @@ export default class ApiRx extends ApiBase<'rxjs'> {
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'rxjs', decorateMethod);
|
||||
|
||||
this._isReadyRx = from(
|
||||
this.#isReadyRx = from(
|
||||
// You can create an observable from an event, however my mind groks this form better
|
||||
new Promise((resolve): void => {
|
||||
super.on('ready', (): void => {
|
||||
@@ -184,7 +184,7 @@ export default class ApiRx extends ApiBase<'rxjs'> {
|
||||
* @description Observable that returns the first time we are connected and loaded
|
||||
*/
|
||||
public get isReady (): Observable<ApiRx> {
|
||||
return this._isReadyRx;
|
||||
return this.#isReadyRx;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ExtrinsicStatus, EventRecord } from '@polkadot/types/interfaces';
|
||||
import { SubmittableResultImpl, SubmittableResultValue } from './types';
|
||||
import { AnyJson, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { SubmittableResultValue } from './types';
|
||||
|
||||
export default class SubmittableResult implements SubmittableResultImpl {
|
||||
export default class SubmittableResult implements ISubmittableResult {
|
||||
public readonly events: EventRecord[];
|
||||
|
||||
public readonly status: ExtrinsicStatus;
|
||||
@@ -48,4 +49,14 @@ export default class SubmittableResult implements SubmittableResultImpl {
|
||||
event.section === section && event.method === method
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates a human representation of the output
|
||||
*/
|
||||
public toHuman (isExtended?: boolean): AnyJson {
|
||||
return {
|
||||
events: this.events.map((event) => event.toHuman(isExtended)),
|
||||
status: this.status.toHuman(isExtended)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountData, Address, Call, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { Callback, Codec, Constructor, IKeyringPair, ITuple, Registry, SignatureOptions } from '@polkadot/types/types';
|
||||
import { Address, Call, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { Callback, Codec, Constructor, IKeyringPair, Registry, SignatureOptions, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { ApiInterfaceRx, ApiTypes, SignerResult } from '../types';
|
||||
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittablePaymentResult, SubmittableResultImpl, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
|
||||
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittablePaymentResult, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { first, map, mapTo, mergeMap, switchMap, tap } from 'rxjs/operators';
|
||||
import { createType, ClassOf } from '@polkadot/types';
|
||||
import { ClassOf } from '@polkadot/types';
|
||||
import { assert, isBn, isFunction, isNumber, isUndefined } from '@polkadot/util';
|
||||
|
||||
import { filterEvents, isKeyringPair } from '../util';
|
||||
@@ -35,38 +35,32 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
const Extrinsic = ClassOf(api.registry, 'Extrinsic');
|
||||
|
||||
return class Submittable extends Extrinsic implements SubmittableExtrinsic<ApiType> {
|
||||
private readonly _api: ApiInterfaceRx;
|
||||
|
||||
private readonly _decorateMethod: ApiBase<ApiType>['decorateMethod'];
|
||||
|
||||
private readonly _ignoreStatusCb: boolean;
|
||||
readonly #ignoreStatusCb: boolean;
|
||||
|
||||
constructor (registry: Registry, extrinsic: Call | Uint8Array | string) {
|
||||
super(registry, extrinsic, { version: api.extrinsicType });
|
||||
|
||||
this._api = api;
|
||||
this._decorateMethod = decorateMethod;
|
||||
this._ignoreStatusCb = apiType === 'rxjs';
|
||||
this.#ignoreStatusCb = apiType === 'rxjs';
|
||||
}
|
||||
|
||||
// calculate the payment info for this transaction (if signed and submitted)
|
||||
public paymentInfo (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittablePaymentResult<ApiType> {
|
||||
const [allOptions] = this._makeSignAndSendOptions(options);
|
||||
const [allOptions] = this.#makeSignAndSendOptions(options);
|
||||
const address = isKeyringPair(account) ? account.address : account.toString();
|
||||
|
||||
return this._decorateMethod(
|
||||
return decorateMethod(
|
||||
(): Observable<RuntimeDispatchInfo> =>
|
||||
this._getPrelimState(address, allOptions).pipe(
|
||||
this.#getPrelimState(address, allOptions).pipe(
|
||||
first(),
|
||||
switchMap(([nonce, header]): Observable<RuntimeDispatchInfo> => {
|
||||
// setup our options (same way as in signAndSend)
|
||||
const eraOptions = this._makeEraOptions(allOptions, { header, nonce });
|
||||
const signOptions = this._makeSignOptions(eraOptions, {});
|
||||
const eraOptions = this.#makeEraOptions(allOptions, { header, nonce });
|
||||
const signOptions = this.#makeSignOptions(eraOptions, {});
|
||||
|
||||
// add a fake signature to the extrinsic
|
||||
this.signFake(address, signOptions);
|
||||
|
||||
return this._api.rpc.payment.queryInfo(this.toHex());
|
||||
return api.rpc.payment.queryInfo(this.toHex());
|
||||
})
|
||||
)
|
||||
)();
|
||||
@@ -74,7 +68,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
|
||||
// sign a transaction, returning the this to allow chaining, i.e. .sign(...).send()
|
||||
public sign (account: IKeyringPair, optionsOrNonce: Partial<SignerOptions>): this {
|
||||
super.sign(account, this._makeSignOptions(this._optionsOrNonce(optionsOrNonce), {}));
|
||||
super.sign(account, this.#makeSignOptions(this.#optionsOrNonce(optionsOrNonce), {}));
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -83,9 +77,9 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
//
|
||||
// also supports signing through external signers
|
||||
public signAsync (account: AddressOrPair, optionsOrNonce: Partial<SignerOptions>): SubmittableThis<ApiType, this> {
|
||||
return this._decorateMethod(
|
||||
return decorateMethod(
|
||||
(): Observable<this> =>
|
||||
this._signObservable(account, optionsOrNonce).pipe(mapTo(this))
|
||||
this.#observeSign(account, optionsOrNonce).pipe(mapTo(this))
|
||||
)();
|
||||
}
|
||||
|
||||
@@ -93,23 +87,23 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
public signAndSend (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
||||
|
||||
// signAndSend with a subscription, i.e. callback provided
|
||||
public signAndSend (account: AddressOrPair, statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
public signAndSend (account: AddressOrPair, statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// signAndSend with options and a callback
|
||||
public signAndSend (account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
public signAndSend (account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// signAndSend implementation for all 3 cases above
|
||||
public signAndSend (account: AddressOrPair, optionsOrStatus?: Partial<SignerOptions> | Callback<SubmittableResultImpl>, optionalStatusCb?: Callback<SubmittableResultImpl>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const [options, statusCb] = this._makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
|
||||
const isSubscription = this._api.hasSubscriptions && (this._ignoreStatusCb || !!statusCb);
|
||||
public signAndSend (account: AddressOrPair, optionsOrStatus?: Partial<SignerOptions> | Callback<ISubmittableResult>, optionalStatusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const [options, statusCb] = this.#makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
|
||||
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
||||
|
||||
return this._decorateMethod(
|
||||
return decorateMethod(
|
||||
(): Observable<Codec> => (
|
||||
this._signObservable(account, options).pipe(
|
||||
switchMap((updateId: number | undefined): Observable<SubmittableResultImpl> | Observable<Hash> =>
|
||||
this.#observeSign(account, options).pipe(
|
||||
switchMap((updateId: number | undefined): Observable<ISubmittableResult> | Observable<Hash> =>
|
||||
isSubscription
|
||||
? this._subscribeObservable(updateId)
|
||||
: this._sendObservable(updateId)
|
||||
? this.#observeSubscribe(updateId)
|
||||
: this.#observeSend(updateId)
|
||||
)
|
||||
) as Observable<Codec>) // FIXME This is wrong, SubmittableResult is _not_ a codec
|
||||
)(statusCb);
|
||||
@@ -119,20 +113,69 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
public send (): SubmittableResultResult<ApiType>;
|
||||
|
||||
// send with a status callback
|
||||
public send (statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
public send (statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// send implementation for both immediate Hash and statusCb variants
|
||||
public send (statusCb?: Callback<SubmittableResultImpl>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const isSubscription = this._api.hasSubscriptions && (this._ignoreStatusCb || !!statusCb);
|
||||
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
||||
|
||||
return this._decorateMethod(
|
||||
return decorateMethod(
|
||||
isSubscription
|
||||
? this._subscribeObservable
|
||||
: this._sendObservable
|
||||
? this.#observeSubscribe
|
||||
: this.#observeSend
|
||||
)(statusCb);
|
||||
}
|
||||
|
||||
private _makeSignAndSendOptions (optionsOrStatus?: Partial<SignerOptions> | Callback<SubmittableResultImpl>, statusCb?: Callback<SubmittableResultImpl>): [Partial<SignerOptions>, Callback<SubmittableResultImpl>?] {
|
||||
#getPrelimState = (address: string, options: Partial<SignerOptions>): Observable<[Index, Header | null]> => {
|
||||
return combineLatest([
|
||||
// if we have a nonce already, don't retrieve the latest, use what is there
|
||||
isUndefined(options.nonce)
|
||||
? api.derive.balances.account(address).pipe(
|
||||
map(({ accountNonce }): Index => accountNonce)
|
||||
)
|
||||
: of(this.registry.createType('Index', options.nonce)),
|
||||
// if we have an era provided already or eraLength is <= 0 (immortal)
|
||||
// don't get the latest block, just pass null, handle in mergeMap
|
||||
(isUndefined(options.era) || (isNumber(options.era) && options.era > 0))
|
||||
? api.rpc.chain.getHeader()
|
||||
: of(null)
|
||||
]);
|
||||
}
|
||||
|
||||
#makeEraOptions = (options: Partial<SignerOptions>, { header, nonce }: { header: Header | null; nonce: Index }): SignatureOptions => {
|
||||
if (!header) {
|
||||
if (isNumber(options.era)) {
|
||||
// since we have no header, it is immortal, remove any option overrides
|
||||
// so we only supply the genesisHash and no era to the construction
|
||||
delete options.era;
|
||||
delete options.blockHash;
|
||||
}
|
||||
|
||||
return this.#makeSignOptions(options, { nonce });
|
||||
}
|
||||
|
||||
return this.#makeSignOptions(options, {
|
||||
blockHash: header.hash,
|
||||
era: this.registry.createType('ExtrinsicEra', {
|
||||
current: header.number,
|
||||
period: options.era || DEFAULT_MORTAL_LENGTH
|
||||
}),
|
||||
nonce
|
||||
});
|
||||
}
|
||||
|
||||
#makeSignOptions = (options: Partial<SignerOptions>, extras: { blockHash?: Hash; era?: ExtrinsicEra; nonce?: Index }): SignatureOptions => {
|
||||
return {
|
||||
blockHash: api.genesisHash,
|
||||
...options,
|
||||
...extras,
|
||||
genesisHash: api.genesisHash,
|
||||
runtimeVersion: api.runtimeVersion,
|
||||
version: api.extrinsicType
|
||||
} as SignatureOptions;
|
||||
}
|
||||
|
||||
#makeSignAndSendOptions = (optionsOrStatus?: Partial<SignerOptions> | Callback<ISubmittableResult>, statusCb?: Callback<ISubmittableResult>): [Partial<SignerOptions>, Callback<ISubmittableResult>?] => {
|
||||
let options: Partial<SignerOptions> = {};
|
||||
|
||||
if (isFunction(optionsOrStatus)) {
|
||||
@@ -144,32 +187,85 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
return [options, statusCb];
|
||||
}
|
||||
|
||||
private _signObservable (account: AddressOrPair, optionsOrNonce: Partial<SignerOptions>): Observable<number | undefined> {
|
||||
#observeSign = (account: AddressOrPair, optionsOrNonce: Partial<SignerOptions>): Observable<number | undefined> => {
|
||||
const address = isKeyringPair(account) ? account.address : account.toString();
|
||||
const options = this._optionsOrNonce(optionsOrNonce);
|
||||
const options = this.#optionsOrNonce(optionsOrNonce);
|
||||
let updateId: number | undefined;
|
||||
|
||||
return this._getPrelimState(address, options).pipe(
|
||||
return this.#getPrelimState(address, options).pipe(
|
||||
first(),
|
||||
mergeMap(async ([nonce, header]): Promise<void> => {
|
||||
const eraOptions = this._makeEraOptions(options, { header, nonce });
|
||||
const eraOptions = this.#makeEraOptions(options, { header, nonce });
|
||||
|
||||
if (isKeyringPair(account)) {
|
||||
this.sign(account, eraOptions);
|
||||
} else {
|
||||
updateId = await this._signViaSigner(address, eraOptions, header);
|
||||
updateId = await this.#signViaSigner(address, eraOptions, header);
|
||||
}
|
||||
}),
|
||||
mapTo(updateId)
|
||||
);
|
||||
}
|
||||
|
||||
private async _signViaSigner (address: Address | string | Uint8Array, options: SignatureOptions, header: Header | null): Promise<number> {
|
||||
const signer = options.signer || this._api.signer;
|
||||
#observeStatus = (status: ExtrinsicStatus): Observable<ISubmittableResult> => {
|
||||
if (!status.isFinalized && !status.isInBlock) {
|
||||
return of(new SubmittableResult({ status }));
|
||||
}
|
||||
|
||||
const blockHash = status.isInBlock
|
||||
? status.asInBlock
|
||||
: status.asFinalized;
|
||||
|
||||
return combineLatest([
|
||||
api.rpc.chain.getBlock(blockHash),
|
||||
api.query.system.events.at(blockHash)
|
||||
]).pipe(
|
||||
map(([signedBlock, allEvents]): ISubmittableResult =>
|
||||
new SubmittableResult({
|
||||
events: filterEvents(this.hash, signedBlock, allEvents, status),
|
||||
status
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#observeSend = (updateId = -1): Observable<Hash> => {
|
||||
return api.rpc.author
|
||||
.submitExtrinsic(this)
|
||||
.pipe(
|
||||
tap((hash): void => {
|
||||
this.#updateSigner(updateId, hash);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#observeSubscribe = (updateId = -1): Observable<ISubmittableResult> => {
|
||||
return api.rpc.author
|
||||
.submitAndWatchExtrinsic(this)
|
||||
.pipe(
|
||||
switchMap((status): Observable<ISubmittableResult> =>
|
||||
this.#observeStatus(status)
|
||||
),
|
||||
tap((status): void => {
|
||||
this.#updateSigner(updateId, status);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE here we actually override nonce if it was specified (backwards compat for
|
||||
// the previous signature - don't let userspace break, but allow then time to upgrade)
|
||||
#optionsOrNonce = (optionsOrNonce: Partial<SignerOptions>): Partial<SignerOptions> => {
|
||||
return isBn(optionsOrNonce) || isNumber(optionsOrNonce)
|
||||
? { nonce: optionsOrNonce }
|
||||
: optionsOrNonce;
|
||||
}
|
||||
|
||||
#signViaSigner = async (address: Address | string | Uint8Array, options: SignatureOptions, header: Header | null): Promise<number> => {
|
||||
const signer = options.signer || api.signer;
|
||||
|
||||
assert(signer, 'No signer specified, either via api.setSigner or via sign options');
|
||||
|
||||
const payload = createType(this.registry, 'SignerPayload', {
|
||||
const payload = this.registry.createType('SignerPayload', {
|
||||
...options,
|
||||
address,
|
||||
method: this.method,
|
||||
@@ -193,119 +289,10 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
||||
return result.id;
|
||||
}
|
||||
|
||||
private _makeSignOptions (options: Partial<SignerOptions>, extras: { blockHash?: Hash; era?: ExtrinsicEra; nonce?: Index }): SignatureOptions {
|
||||
return {
|
||||
blockHash: this._api.genesisHash,
|
||||
...options,
|
||||
...extras,
|
||||
genesisHash: this._api.genesisHash,
|
||||
runtimeVersion: this._api.runtimeVersion,
|
||||
version: this._api.extrinsicType
|
||||
} as SignatureOptions;
|
||||
}
|
||||
|
||||
private _makeEraOptions (options: Partial<SignerOptions>, { header, nonce }: { header: Header | null; nonce: Index }): SignatureOptions {
|
||||
if (!header) {
|
||||
if (isNumber(options.era)) {
|
||||
// since we have no header, it is immortal, remove any option overrides
|
||||
// so we only supply the genesisHash and no era to the construction
|
||||
delete options.era;
|
||||
delete options.blockHash;
|
||||
}
|
||||
|
||||
return this._makeSignOptions(options, { nonce });
|
||||
#updateSigner = (updateId: number, status: Hash | ISubmittableResult): void => {
|
||||
if ((updateId !== -1) && api.signer && api.signer.update) {
|
||||
api.signer.update(updateId, status);
|
||||
}
|
||||
|
||||
return this._makeSignOptions(options, {
|
||||
blockHash: header.hash,
|
||||
era: createType(this.registry, 'ExtrinsicEra', {
|
||||
current: header.number,
|
||||
period: options.era || DEFAULT_MORTAL_LENGTH
|
||||
}),
|
||||
nonce
|
||||
});
|
||||
}
|
||||
|
||||
private _getPrelimState (address: string, options: Partial<SignerOptions>): Observable<[Index, Header | null]> {
|
||||
return combineLatest([
|
||||
// if we have a nonce already, don't retrieve the latest, use what is there
|
||||
isUndefined(options.nonce)
|
||||
// FIXME This apparently is having issues on latest Kusama for nonce retrieval,
|
||||
// hence we are using the accountNonce only
|
||||
// ? this._api.rpc.account.nextIndex
|
||||
// ? this._api.rpc.account.nextIndex(address)
|
||||
// : this._api.query.system.accountNonce(address)
|
||||
? this._api.query.system.account
|
||||
? this._api.query.system.account<ITuple<[Index, AccountData]>>(address).pipe(
|
||||
map(([nonce]): Index => nonce)
|
||||
)
|
||||
: this._api.query.system.accountNonce<Index>(address)
|
||||
: of(createType(this.registry, 'Index', options.nonce)),
|
||||
// if we have an era provided already or eraLength is <= 0 (immortal)
|
||||
// don't get the latest block, just pass null, handle in mergeMap
|
||||
(isUndefined(options.era) || (isNumber(options.era) && options.era > 0))
|
||||
? this._api.rpc.chain.getHeader()
|
||||
: of(null)
|
||||
]);
|
||||
}
|
||||
|
||||
private _updateSigner (updateId: number, status: Hash | SubmittableResultImpl): void {
|
||||
if ((updateId !== -1) && this._api.signer && this._api.signer.update) {
|
||||
this._api.signer.update(updateId, status);
|
||||
}
|
||||
}
|
||||
|
||||
private _statusObservable (status: ExtrinsicStatus): Observable<SubmittableResultImpl> {
|
||||
if (!status.isFinalized && !status.isInBlock) {
|
||||
return of(new SubmittableResult({ status }));
|
||||
}
|
||||
|
||||
const blockHash = status.isInBlock
|
||||
? status.asInBlock
|
||||
: status.asFinalized;
|
||||
|
||||
return combineLatest([
|
||||
this._api.rpc.chain.getBlock(blockHash),
|
||||
this._api.query.system.events.at(blockHash)
|
||||
]).pipe(
|
||||
map(([signedBlock, allEvents]): SubmittableResultImpl =>
|
||||
new SubmittableResult({
|
||||
events: filterEvents(this.hash, signedBlock, allEvents),
|
||||
status
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private _sendObservable = (updateId = -1): Observable<Hash> => {
|
||||
return this._api.rpc.author
|
||||
.submitExtrinsic(this)
|
||||
.pipe(
|
||||
tap((hash): void => {
|
||||
this._updateSigner(updateId, hash);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _subscribeObservable = (updateId = -1): Observable<SubmittableResultImpl> => {
|
||||
return this._api.rpc.author
|
||||
.submitAndWatchExtrinsic(this)
|
||||
.pipe(
|
||||
switchMap((status): Observable<SubmittableResultImpl> =>
|
||||
this._statusObservable(status)
|
||||
),
|
||||
tap((status): void => {
|
||||
this._updateSigner(updateId, status);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE here we actually override nonce if it was specified (backwards compat for
|
||||
// the previous signature - don't let userspace break, but allow then time to upgrade)
|
||||
private _optionsOrNonce = (optionsOrNonce: Partial<SignerOptions>): Partial<SignerOptions> => {
|
||||
return isBn(optionsOrNonce) || isNumber(optionsOrNonce)
|
||||
? { nonce: optionsOrNonce }
|
||||
: optionsOrNonce;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,23 +3,11 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, Address, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||
import { AnyNumber, AnyU8a, Callback, Codec, IExtrinsic, IExtrinsicEra, IKeyringPair, SignatureOptions } from '@polkadot/types/types';
|
||||
import { ApiTypes, Signer } from '../types';
|
||||
import { AnyNumber, AnyU8a, Callback, Codec, IExtrinsic, IExtrinsicEra, IKeyringPair, SignatureOptions, Signer, ISubmittableResult } from '@polkadot/types/types';
|
||||
import { ApiTypes } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface SubmittableResultImpl {
|
||||
readonly events: EventRecord[];
|
||||
readonly status: ExtrinsicStatus;
|
||||
readonly isCompleted: boolean;
|
||||
readonly isError: boolean;
|
||||
readonly isFinalized: boolean;
|
||||
readonly isInBlock: boolean;
|
||||
|
||||
filterRecords (section: string, method: string): EventRecord[];
|
||||
findRecord (section: string, method: string): EventRecord | undefined;
|
||||
}
|
||||
|
||||
export interface SubmittableResultValue {
|
||||
events?: EventRecord[];
|
||||
status: ExtrinsicStatus;
|
||||
@@ -32,12 +20,12 @@ export type SubmittablePaymentResult<ApiType extends ApiTypes> =
|
||||
|
||||
export type SubmittableResultResult<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? Observable<SubmittableResultImpl>
|
||||
? Observable<ISubmittableResult>
|
||||
: Promise<Hash>;
|
||||
|
||||
export type SubmittableResultSubscription<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? Observable<SubmittableResultImpl>
|
||||
? Observable<ISubmittableResult>
|
||||
: Promise<() => void>;
|
||||
|
||||
export type SubmittableThis<ApiType extends ApiTypes, THIS> =
|
||||
@@ -60,7 +48,7 @@ export interface SubmittableExtrinsic<ApiType extends ApiTypes> extends IExtrins
|
||||
|
||||
send(): SubmittableResultResult<ApiType>;
|
||||
|
||||
send(statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
send(statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
sign(account: IKeyringPair, _options: Partial<SignatureOptions>): this;
|
||||
|
||||
@@ -68,7 +56,7 @@ export interface SubmittableExtrinsic<ApiType extends ApiTypes> extends IExtrins
|
||||
|
||||
signAndSend(account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
||||
|
||||
signAndSend(account: AddressOrPair, statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
signAndSend(account: AddressOrPair, statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
signAndSend(account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
signAndSend(account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
// Module augmentation so that `api.{consts,query,rpc,tx}.*.*` work
|
||||
import './augment';
|
||||
// Augment the modules
|
||||
import '@polkadot/api/augment';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { DeriveCustom, ExactDerive } from '@polkadot/api-derive';
|
||||
@@ -11,10 +11,9 @@ import { Constants } from '@polkadot/metadata/Decorated/types';
|
||||
import { RpcInterface, UserRpc } from '@polkadot/rpc-core/types';
|
||||
import { Metadata } from '@polkadot/types';
|
||||
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import { RegistryTypes, SignatureOptions, SignerPayloadJSON, SignerPayloadRaw, Registry } from '@polkadot/types/types';
|
||||
import { RegistryTypes, Signer, SignerResult, SignatureOptions, Registry } from '@polkadot/types/types';
|
||||
|
||||
import ApiBase from '../base';
|
||||
import { SubmittableResultImpl } from '../submittable/types';
|
||||
import { DeriveAllSections } from '../util/decorate';
|
||||
import { DecoratedRpc } from './rpc';
|
||||
import { QueryableStorage, QueryableStorageMulti } from './storage';
|
||||
@@ -79,11 +78,11 @@ export interface ApiInterfaceRx {
|
||||
// TODO This needs to be typed correctly
|
||||
derive: DeriveAllSections<'rxjs', ExactDerive>;
|
||||
extrinsicType: number;
|
||||
genesisHash: Hash;
|
||||
genesisHash?: Hash;
|
||||
hasSubscriptions: boolean;
|
||||
registry: Registry;
|
||||
runtimeMetadata: Metadata;
|
||||
runtimeVersion: RuntimeVersion;
|
||||
runtimeVersion?: RuntimeVersion;
|
||||
query: QueryableStorage<'rxjs'>;
|
||||
queryMulti: QueryableStorageMulti<'rxjs'>;
|
||||
rpc: DecoratedRpc<'rxjs', RpcInterface>;
|
||||
@@ -98,33 +97,4 @@ export interface SignerOptions extends SignatureOptions {
|
||||
genesisHash: Hash;
|
||||
}
|
||||
|
||||
export interface SignerResult {
|
||||
/**
|
||||
* @description The id for this request
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @description The resulting signature in hex
|
||||
*/
|
||||
signature: string;
|
||||
}
|
||||
|
||||
export interface Signer {
|
||||
/**
|
||||
* @description signs an extrinsic payload from a serialized form
|
||||
*/
|
||||
signPayload?: (payload: SignerPayloadJSON) => Promise<SignerResult>;
|
||||
|
||||
/**
|
||||
* @description signs a raw payload, only the bytes data as supplied
|
||||
*/
|
||||
signRaw?: (raw: SignerPayloadRaw) => Promise<SignerResult>;
|
||||
|
||||
/**
|
||||
* @description Receives an update for the extrinsic signed by a `signer.sign`
|
||||
*/
|
||||
update?: (id: number, status: Hash | SubmittableResultImpl) => void;
|
||||
}
|
||||
|
||||
export { ApiBase };
|
||||
export { ApiBase, Signer, SignerResult };
|
||||
|
||||
@@ -15,7 +15,7 @@ export interface AugmentedQueries<ApiType extends ApiTypes> { }
|
||||
|
||||
export type AugmentedQuery<ApiType extends ApiTypes, F extends AnyFunction> = MethodResult<ApiType, F> & StorageEntryBase<ApiType, F>
|
||||
|
||||
export type AugmentedQueryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction, FirstKeyType = any> = MethodResult<ApiType, F> & StorageEntryDoubleMap<ApiType, F, FirstKeyType>
|
||||
export type AugmentedQueryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction> = MethodResult<ApiType, F> & StorageEntryDoubleMap<ApiType, F>
|
||||
|
||||
// This is the most generic typings we can have for a storage entry function
|
||||
type GenericStorageEntryFunction = (arg1?: CodecArg, arg2?: CodecArg) => Observable<Codec>
|
||||
@@ -36,8 +36,8 @@ export interface StorageEntryBase<ApiType extends ApiTypes, F extends AnyFunctio
|
||||
multi: ApiType extends 'rxjs' ? StorageEntryObservableMulti : StorageEntryPromiseMulti;
|
||||
}
|
||||
|
||||
export interface StorageEntryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction, FirstKeyType> extends StorageEntryBase<ApiType, F> {
|
||||
entries: (arg?: FirstKeyType) => PromiseOrObs<ApiType, [StorageKey, ObsInnerType<ReturnType<F>>][]>;
|
||||
export interface StorageEntryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction> extends StorageEntryBase<ApiType, F> {
|
||||
entries: (arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, ObsInnerType<ReturnType<F>>][]>;
|
||||
}
|
||||
|
||||
interface StorageEntryObservableMulti {
|
||||
@@ -77,7 +77,3 @@ export type QueryableStorageMulti<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? QueryableStorageMultiBase<ApiType>
|
||||
: QueryableStorageMultiPromise<ApiType>;
|
||||
|
||||
export interface QueryableStorage<ApiType extends ApiTypes> extends AugmentedQueries<ApiType> {
|
||||
[index: string]: QueryableModuleStorage<ApiType>;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,3 @@ export interface SubmittableExtrinsicFunction<ApiType extends ApiTypes> extends
|
||||
export interface SubmittableModuleExtrinsics<ApiType extends ApiTypes> {
|
||||
[index: string]: SubmittableExtrinsicFunction<ApiType>;
|
||||
}
|
||||
|
||||
export interface SubmittableExtrinsics<ApiType extends ApiTypes> extends AugmentedSubmittables<ApiType> {
|
||||
(extrinsic: Uint8Array | string): SubmittableExtrinsic<ApiType>;
|
||||
[index: string]: SubmittableModuleExtrinsics<ApiType>;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2017-2020 @polkadot/api authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import augmentObject from './augmentObject';
|
||||
|
||||
describe('augmentObject', (): void => {
|
||||
let spy: any;
|
||||
|
||||
beforeEach((): void => {
|
||||
spy = jest.spyOn(console, 'warn');
|
||||
});
|
||||
|
||||
afterEach((): void => {
|
||||
spy.mockClear();
|
||||
});
|
||||
|
||||
it('logs added/removed sections and methods', (): void => {
|
||||
augmentObject(
|
||||
'test',
|
||||
{ foo: { f: 1, d: 1 }, bar: { b: 1 }, new: { z: 1 } },
|
||||
{ foo: { f: 1, c: 1 }, bar: { a: 1, c: 1 }, baz: { a: 1 } }
|
||||
);
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.stringContaining('API/AUGMENT'),
|
||||
'api.test: Found 1 added and 1 removed modules:\n\t added: new\n\tremoved: baz'
|
||||
);
|
||||
expect(spy).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.stringContaining('API/AUGMENT'),
|
||||
'api.test: Found 2 added and 3 removed calls:\n\t added: bar.b, foo.d\n\tremoved: bar.a, bar.c, foo.c'
|
||||
);
|
||||
});
|
||||
|
||||
it('copies sections to the dest', (): void => {
|
||||
const src = { foo: { a: 1 }, bar: { b: 1 } };
|
||||
|
||||
expect(augmentObject('test', src, {})).toEqual(src);
|
||||
});
|
||||
|
||||
it('adds fields to existing sections', (): void => {
|
||||
const src = { foo: { a: 1 }, bar: { b: 1 } };
|
||||
const dst = { foo: { b: 2 }, baz: { c: 1 } };
|
||||
|
||||
expect(augmentObject('test', src, dst)).toEqual({
|
||||
foo: { b: 2, a: 1 },
|
||||
bar: { b: 1 },
|
||||
baz: { c: 1 }
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright 2017-2020 @polkadot/api authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { logger } from '@polkadot/util';
|
||||
|
||||
type StringsStrings = [string[], string[]];
|
||||
|
||||
const l = logger('api/augment');
|
||||
|
||||
function logLength (type: 'added' | 'removed', values: string[], and: string[] = []): string {
|
||||
return values.length
|
||||
? ` ${values.length} ${type}${and.length ? ' and' : ''}`
|
||||
: '';
|
||||
}
|
||||
|
||||
function logValues (type: 'added' | 'removed', values: string[]): string {
|
||||
return values.length
|
||||
? `\n\t${type.padStart(7)}: ${values.sort().join(', ')}`
|
||||
: '';
|
||||
}
|
||||
|
||||
// log details to console
|
||||
function warn (prefix: string, type: 'calls' | 'modules', [added, removed]: StringsStrings): void {
|
||||
if (added.length || removed.length) {
|
||||
l.warn(`api.${prefix}: Found${logLength('added', added, removed)}${logLength('removed', removed)} ${type}:${logValues('added', added)}${logValues('removed', removed)}`);
|
||||
}
|
||||
}
|
||||
|
||||
function extractKeys (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
|
||||
return [Object.keys(src), Object.keys(dst)];
|
||||
}
|
||||
|
||||
function findSectionExcludes (a: string[], b: string[]): string[] {
|
||||
return a.filter((section): boolean => !b.includes(section));
|
||||
}
|
||||
|
||||
function extractSections (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
|
||||
const [srcSections, dstSections] = extractKeys(src, dst);
|
||||
|
||||
return [
|
||||
findSectionExcludes(srcSections, dstSections),
|
||||
findSectionExcludes(dstSections, srcSections)
|
||||
];
|
||||
}
|
||||
|
||||
function findMethodExcludes (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): string[] {
|
||||
const srcSections = Object.keys(src);
|
||||
const dstSections = Object.keys(dst);
|
||||
|
||||
return dstSections
|
||||
.filter((section): boolean => srcSections.includes(section))
|
||||
.reduce((rmMethods: string[], section): string[] => {
|
||||
const srcMethods = Object.keys(src[section]);
|
||||
|
||||
return rmMethods.concat(
|
||||
...Object
|
||||
.keys(dst[section])
|
||||
.filter((method): boolean => !srcMethods.includes(method))
|
||||
.map((method): string => `${section}.${method}`)
|
||||
);
|
||||
}, []);
|
||||
}
|
||||
|
||||
function extractMethods (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
|
||||
return [
|
||||
findMethodExcludes(dst, src),
|
||||
findMethodExcludes(src, dst)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a decorated api section (e.g. api.tx) and augment it with the details. It does not override what is
|
||||
* already available, but rather just adds new missing ites into the result object.
|
||||
* @internal
|
||||
*/
|
||||
export default function augmentObject (prefix: string, src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>, fromEmpty = false): Record<string, Record<string, any>> {
|
||||
if (fromEmpty) {
|
||||
Object.keys(dst).forEach((key): void => {
|
||||
delete dst[key];
|
||||
});
|
||||
}
|
||||
|
||||
if (prefix && Object.keys(dst).length) {
|
||||
warn(prefix, 'modules', extractSections(src, dst));
|
||||
warn(prefix, 'calls', extractMethods(src, dst));
|
||||
}
|
||||
|
||||
return Object
|
||||
.keys(src)
|
||||
.reduce((newSection, sectionName): Record<string, Record<string, any>> => {
|
||||
const section = src[sectionName];
|
||||
|
||||
newSection[sectionName] = Object
|
||||
.keys(section)
|
||||
.reduce((result, methodName): Record<string, any> => {
|
||||
// TODO When it does match, check the actual details and warn when there are differences
|
||||
if (!result[methodName]) {
|
||||
result[methodName] = section[methodName];
|
||||
}
|
||||
|
||||
return result;
|
||||
}, dst[sectionName] || {});
|
||||
|
||||
return newSection;
|
||||
}, dst);
|
||||
}
|
||||
@@ -2,13 +2,11 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { EventRecord, SignedBlock } from '@polkadot/types/interfaces';
|
||||
|
||||
import { Raw } from '@polkadot/types';
|
||||
import { EventRecord, ExtrinsicStatus, H256, SignedBlock } from '@polkadot/types/interfaces';
|
||||
|
||||
import l from './logging';
|
||||
|
||||
export default function filterEvents (extHash: Raw, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[]): EventRecord[] | undefined {
|
||||
export default function filterEvents (extHash: H256, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[], status: ExtrinsicStatus): EventRecord[] | undefined {
|
||||
// extrinsics to hashes
|
||||
const myHash = extHash.toHex();
|
||||
const allHashes = extrinsics.map((ext): string => ext.hash.toHex());
|
||||
@@ -18,7 +16,10 @@ export default function filterEvents (extHash: Raw, { block: { extrinsics, heade
|
||||
|
||||
// if we do get the block after finalized, it _should_ be there
|
||||
if (index === -1) {
|
||||
l.warn(`block ${header.hash}: Unable to find extrinsic ${myHash} inside ${allHashes}`);
|
||||
// only warn on filtering with isInBlock (finalization finalizes after)
|
||||
if (status.isInBlock) {
|
||||
l.warn(`block ${header.hash}: Unable to find extrinsic ${myHash} inside ${allHashes}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import { Signer, SignerResult } from '@polkadot/api/types';
|
||||
import { KeyringPair } from '@polkadot/keyring/types';
|
||||
import { Registry, SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types';
|
||||
|
||||
import { createType } from '@polkadot/types';
|
||||
import { hexToU8a, u8aToHex } from '@polkadot/util';
|
||||
|
||||
let id = 0;
|
||||
@@ -31,7 +30,7 @@ export class SingleAccountSigner implements Signer {
|
||||
|
||||
return new Promise((resolve): void => {
|
||||
setTimeout((): void => {
|
||||
const signed = createType(this.registry, 'ExtrinsicPayload', payload, { version: payload.version }).sign(this.keyringPair);
|
||||
const signed = this.registry.createType('ExtrinsicPayload', payload, { version: payload.version }).sign(this.keyringPair);
|
||||
|
||||
resolve({
|
||||
id: ++id,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user