Compare commits

..
37 Commits
Author SHA1 Message Date
Github Actions 99073e2a88 [CI Skip] 0.99.1
skip-checks: true
2019-12-13 09:33:27 +00:00
Jaco Greeff f9a42e47e7 0.99 (#1669)
* 0.99

* Rewrite yarn.lock
2019-12-13 10:26:41 +01:00
Github Actions b80d72edbd [CI Skip] 0.99.0-beta.16
skip-checks: true
2019-12-12 06:51:19 +00:00
Jaco Greeff 1f7b9f7f3a democracy.lowestUnbaked (#1665) 2019-12-12 07:43:56 +01:00
Github Actions 843efb2146 [CI Skip] 0.99.0-beta.15
skip-checks: true
2019-12-11 17:24:47 +00:00
Jaco Greeff 3619fabe5f Update .123trigger 2019-12-11 18:17:29 +01:00
Github Actions bf598e392e [CI Skip] 0.99.0-beta.14
skip-checks: true
2019-12-11 16:43:19 +00:00
Jaco Greeff f026137545 Chace down more phantoms (#1664) 2019-12-11 17:35:57 +01:00
Github Actions 2264f53a43 [CI Skip] 0.99.0-beta.13
skip-checks: true
2019-12-09 22:09:01 +00:00
Jaco Greeff 8ba4029633 Fix elections typo 2019-12-09 23:01:46 +01:00
Github Actions 05cb2cef5a [CI Skip] 0.99.0-beta.12
skip-checks: true
2019-12-09 21:12:47 +00:00
Keith Ingram 3a70594594 Combine elections.info derive (#1659)
* Combine elections.info derive

* remove tests
2019-12-09 22:05:56 +01:00
Github Actions 019cb58dd1 [CI Skip] 0.99.0-beta.11
skip-checks: true
2019-12-09 19:43:53 +00:00
Jaco Greeff d487490ca0 Identity types (#1658)
* Identity types

* Refine findMeta* error outputs

* Cleanups, don't return crappy info, fail

* Revert callIndex with size alloc
2019-12-09 20:36:52 +01:00
Github Actions b9fad61da0 [CI Skip] 0.99.0-beta.10
skip-checks: true
2019-12-09 17:24:49 +00:00
Jaco Greeff 77bf33b4e4 Derive with optional democracy (#1657)
* Derive with optional democracy

* Cleanup optionals

* Multi for preimage retrievals

* Convert indexes to hex before lookup
2019-12-09 18:17:41 +01:00
Github Actions 7ed7c9d3a8 [CI Skip] 0.99.0-beta.9
skip-checks: true
2019-12-09 14:44:41 +00:00
Jaco Greeff 0d2896630d Replace Data/U8a with un-aliassed Raw (#1656)
* Replace Data with un-aliassed U8a

* Export U8a

* Explicitly add U8a to the registry

* U8a -> Raw
2019-12-09 15:38:07 +01:00
Github Actions 74dbff32df [CI Skip] 0.99.0-beta.8
skip-checks: true
2019-12-09 13:24:56 +00:00
Jaco Greeff 4653cc0d84 Add council & treasury derives (#1654) 2019-12-09 14:18:13 +01:00
Github Actions 50e115f6a1 [CI Skip] 0.99.0-beta.7
skip-checks: true
2019-12-09 09:22:19 +00:00
Jaco Greeff 8a5a86e8b3 Better performant per-account staking queries (#1652)
* Better performant per-account staking queries

* Rename retrieval (no confusion)

* staking.info -> staking.account

* Update .info test
2019-12-09 10:14:51 +01:00
Jaco Greeff 48ef5af93f Add missing BTreeMap is metadata checking (#1653) 2019-12-09 10:14:12 +01:00
Github Actions e5c20be666 [CI Skip] 0.99.0-beta.6
skip-checks: true
2019-12-09 07:44:00 +00:00
Jaco Greeff 6bf0d5eea9 DoubleMap hashing over full value (#1650)
* DoubleMap hashing over full value

* Expand Bytes tests

* Expand

* Hashing test with soublemaps

* Small extra test comments
2019-12-09 08:37:47 +01:00
Github Actions 21c57b60a1 [CI Skip] 0.99.0-beta.5
skip-checks: true
2019-12-07 22:07:10 +00:00
Keith Ingram b1dff22954 Fix encodeWithParams for only valid types (#1644)
* fix param display

* space
2019-12-07 23:00:02 +01:00
Github Actions a3d0cb0999 [CI Skip] 0.99.0-beta.4
skip-checks: true
2019-12-07 13:18:44 +00:00
Jaco Greeff bf946c20db Latest metadata (#1647)
* Latest metadata

* Updte static version (v9)

* Update tests for new storage keys

* Bump deps

* Bump extra

* Case, V8 -> v8
2019-12-07 14:13:20 +01:00
Github Actions 664d2c8ab6 [CI Skip] 0.99.0-beta.3
skip-checks: true
2019-12-05 18:56:23 +00:00
Jaco Greeff 01a4d6b4a9 Remove RPC data toU8a (#1643) 2019-12-05 19:49:50 +01:00
Github Actions 18454083db [CI Skip] 0.99.0-beta.2
skip-checks: true
2019-12-05 12:01:09 +00:00
Jaco Greeff 191abe4e08 Cleanup Text from U8a (wrapper class) (#1642)
* Cleanup Text from U8a (wrapper class)

* U8a test
2019-12-05 12:54:52 +01:00
Github Actions 97fbb4732d [CI Skip] 0.99.0-beta.1
skip-checks: true
2019-12-05 10:16:01 +00:00
Jaco Greeff 01f3666cc7 Bump deps (#1641)
* Bump deps

* Linting
2019-12-05 11:09:27 +01:00
Github Actions 468fcdccaa [CI Skip] 0.99.0-beta.0
skip-checks: true
2019-12-04 14:53:39 +00:00
Jaco Greeff c8dd26b0da Remove debug logs (#1637) 2019-12-04 15:46:56 +01:00
98 changed files with 1636 additions and 1072 deletions
+1 -1
View File
@@ -1 +1 @@
13
14
+1
View File
@@ -12,6 +12,7 @@ tmp/
.env.production.local
.npmrc
.rpt2_cache
.vscode/
cc-test-reporter
lerna-debug.log*
npm-debug.log*
+9
View File
@@ -1,3 +1,12 @@
# 0.99.1
- **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
- Add additional derives for both council & treasury
- Alignment with latest Polkadot/Substrate master branch types
# 0.98.1
- Make the TypeScript generation script mor re-usable (Thanks to @xlc)
+1 -1
View File
@@ -9,5 +9,5 @@
"packages": [
"packages/*"
],
"version": "0.98.1"
"version": "0.99.1"
}
+6 -6
View File
@@ -1,5 +1,5 @@
{
"version": "0.98.1",
"version": "0.99.1",
"private": true,
"engines": {
"yarn": "^1.10.1"
@@ -9,7 +9,7 @@
],
"resolutions": {
"babel-core": "^7.0.0-bridge.0",
"typescript": "^3.7.2"
"typescript": "^3.7.3"
},
"scripts": {
"build": "yarn build:interfaces && polkadot-dev-build-ts",
@@ -29,10 +29,10 @@
"test:watch": "jest --coverage --watch"
},
"devDependencies": {
"@babel/core": "^7.7.4",
"@babel/core": "^7.7.5",
"@babel/register": "^7.7.4",
"@babel/runtime": "^7.7.4",
"@polkadot/dev": "^0.32.0-beta.15",
"@polkadot/ts": "^0.1.86"
"@babel/runtime": "^7.7.6",
"@polkadot/dev": "^0.32.0-beta.18",
"@polkadot/ts": "^0.1.88"
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-contract",
"version": "0.98.1",
"version": "0.99.1",
"description": "Interfaces for interacting with contracts and contract ABIs",
"main": "index.js",
"keywords": [
@@ -26,7 +26,7 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/types": "^0.98.1"
"@babel/runtime": "^7.7.6",
"@polkadot/types": "^0.99.1"
}
}
+1 -1
View File
@@ -75,7 +75,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
output = message.returnType
? formatData(this.registry, data, message.returnType)
: createType(this.registry, 'Data', data);
: createType(this.registry, 'Raw', data);
}
return {
+4 -6
View File
@@ -4,19 +4,17 @@
import { Codec, Registry, TypeDefInfo, TypeDef } from '@polkadot/types/types';
import { Data, Option, createClass } from '@polkadot/types';
import { Option, Raw, createClass } from '@polkadot/types';
import { createTypeUnsafe } from '@polkadot/types/codec';
export function formatData (registry: Registry, data: Data, { info, type }: TypeDef): Codec {
const u8a = data.toU8a();
export function formatData (registry: Registry, data: Raw, { info, type }: TypeDef): Codec {
if (info === TypeDefInfo.Option) {
return new Option(
registry,
createClass(registry, type),
createTypeUnsafe(registry, type, [u8a], true)
createTypeUnsafe(registry, type, [data], true)
);
}
return createTypeUnsafe(registry, type, [u8a], true);
return createTypeUnsafe(registry, type, [data], true);
}
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-derive",
"version": "0.98.1",
"version": "0.99.1",
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
"main": "index.js",
"keywords": [
@@ -27,9 +27,9 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/api": "^0.98.1",
"@polkadot/types": "^0.98.1"
"@babel/runtime": "^7.7.6",
"@polkadot/api": "^0.99.1",
"@polkadot/types": "^0.99.1"
},
"devDependencies": {
"@polkadot/keyring": "^1.7.1"
+5
View File
@@ -0,0 +1,5 @@
// Copyright 2017-2019 @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.
export * from './proposals';
@@ -0,0 +1,48 @@
// Copyright 2017-2019 @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 { Hash, Proposal, Votes } from '@polkadot/types/interfaces';
import { DerivedCouncilProposals } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { memo } from '../util';
function retrieveProposals (api: ApiInterfaceRx, hashes: Hash[]): Observable<DerivedCouncilProposals> {
return combineLatest([
api.query.council.proposalOf.multi<Option<Proposal>>(hashes),
api.query.council.voting.multi<Option<Votes>>(hashes)
]).pipe(
map(([proposals, votes]: [Option<Proposal>[], Option<Votes>[]]): DerivedCouncilProposals => {
const result: DerivedCouncilProposals = [];
proposals.forEach((proposalOpt, index): void => {
if (proposalOpt.isSome) {
result.push({
hash: hashes[index],
proposal: proposalOpt.unwrap(),
votes: votes[index].unwrapOr(null)
});
}
});
return result;
})
);
}
export function proposals (api: ApiInterfaceRx): () => Observable<DerivedCouncilProposals> {
return memo((): Observable<DerivedCouncilProposals> =>
api.query.council
? api.query.council.proposals().pipe(
switchMap((proposals: Hash[]): Observable<DerivedCouncilProposals> =>
retrieveProposals(api, proposals)
)
)
: of([] as DerivedCouncilProposals)
);
}
+52 -52
View File
@@ -14,62 +14,62 @@ import { Bytes, Option, Vec, createType } from '@polkadot/types';
import { memo } from '../util';
export type PreImage = Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>;
type Depositors = Option<ITuple<[Balance, Vec<AccountId>]>>;
type Proposals = Vec<ITuple<[PropIndex, Hash, AccountId]>>;
interface Result {
depositors: Depositors[];
preimages: PreImage[];
proposals: Proposals;
}
function parse (api: ApiInterfaceRx, { depositors, proposals, preimages }: Result): DeriveProposal[] {
return proposals
.filter(([, , proposer], index): boolean =>
!!(preimages[index]?.isSome) && !!(depositors[index]?.isSome) && !proposer.isEmpty
)
.map(([propIndex, hash, proposer], index): DeriveProposal => {
const preimage = preimages[index].unwrapOr(null);
const depositor = depositors[index].unwrap();
return {
balance: depositor[0],
hash,
index: propIndex,
preimage: preimage
? {
at: preimage[3],
balance: preimage[2],
proposer: preimage[1]
}
: undefined,
proposal: preimage
? createType(api.registry, 'Proposal', preimage[0].toU8a(true))
: undefined,
proposer,
seconds: depositor[1]
};
});
}
export function proposals (api: ApiInterfaceRx): () => Observable<DeriveProposal[]> {
return memo((): Observable<DeriveProposal[]> =>
api.query.democracy
.publicProps<Vec<ITuple<[PropIndex, Hash, AccountId]>>>()
.pipe(
switchMap((proposals) =>
combineLatest([
of(proposals),
combineLatest(
...proposals.map(([, hash]) =>
api.query.democracy.preimages<PreImage>(hash)
)
)
])
),
switchMap(([proposals, preimages]) =>
combineLatest([
of(proposals),
of(preimages),
combineLatest(
...proposals.map(([index]) =>
api.query.democracy.depositOf<Depositors>(index)
)
)
])
),
map(([proposals, _preImages, _depositors]): DeriveProposal[] =>
proposals
.filter(([, , proposer], index): boolean =>
!!(_preImages[index]?.isSome) && !!(_depositors[index]?.isSome) && !proposer.isEmpty
)
.map(([propIndex, hash, proposer], index): DeriveProposal => {
const preImage = _preImages[index].unwrapOr(null);
const depositors = _depositors[index].unwrap();
return {
balance: depositors[0],
hash,
index: propIndex,
preimage: preImage
? {
at: preImage[3],
balance: preImage[2],
proposer: preImage[1]
}
: undefined,
proposal: preImage
? createType(api.registry, 'Proposal', preImage[0].toU8a(true))
: undefined,
proposer,
seconds: depositors[1]
};
})
api.query.democracy?.publicProps
? api.query.democracy
.publicProps<Proposals>()
.pipe(
switchMap((proposals) =>
combineLatest([
of(proposals),
api.query.democracy.preimages.multi<PreImage>(proposals.map(([, hash]): Hash => hash)),
api.query.democracy.depositOf.multi<Depositors>(proposals.map(([index]): PropIndex => index))
])
),
map(([proposals, preimages, depositors]): DeriveProposal[] =>
parse(api, { depositors, proposals, preimages })
)
)
)
: of([] as DeriveProposal[])
);
}
@@ -15,8 +15,6 @@ import { Option, createType } from '@polkadot/types';
import { memo } from '../util';
function constructInfo (api: ApiInterfaceRx, index: BN | number, _info: Option<ReferendumInfo>, _preimage?: PreImage): DerivedReferendum | null {
console.log(JSON.stringify(_info), JSON.stringify(_preimage));
const preImage = _preimage?.isSome
? _preimage.unwrap()
: null;
@@ -44,8 +42,6 @@ function constructInfo (api: ApiInterfaceRx, index: BN | number, _info: Option<R
}
export function retrieveInfo (api: ApiInterfaceRx, index: BN | number, info: Option<ReferendumInfo>): Observable<DerivedReferendum | null> {
console.log(JSON.stringify(info));
return ((
info?.isSome
? api.query.democracy.preimages<PreImage>(info.unwrap().proposalHash)
@@ -14,18 +14,22 @@ import { memo } from '../util';
export function referendums (api: ApiInterfaceRx): () => Observable<DerivedReferendum[]> {
return memo((): Observable<DerivedReferendum[]> =>
api.queryMulti<[ReferendumIndex, ReferendumIndex]>([
api.query.democracy.nextTally,
api.query.democracy.referendumCount
]).pipe(
switchMap(([nextTally, referendumCount]): Observable<DerivedReferendum[]> =>
referendumCount && nextTally && referendumCount.gt(nextTally) && referendumCount.gtn(0)
? api.derive.democracy.referendumInfos(
[...Array(referendumCount.sub(nextTally).toNumber())].map((_, i): BN =>
nextTally.addn(i)
// V2 vs V1 (and early V2)
api.query.democracy?.lowestUnbaked || api.query.democracy?.nextTally
? api.queryMulti<[ReferendumIndex, ReferendumIndex]>([
api.query.democracy.lowestUnbaked || api.query.democracy.nextTally,
api.query.democracy.referendumCount
]).pipe(
switchMap(([earliest, referendumCount]): Observable<DerivedReferendum[]> =>
referendumCount?.gt(earliest) && referendumCount?.gtn(0)
? api.derive.democracy.referendumInfos(
[...Array(referendumCount.sub(earliest).toNumber())].map((_, i): BN =>
earliest.addn(i)
)
)
)
: of([])
: of([])
)
)
));
: of([] as DerivedReferendum[])
);
}
@@ -1,49 +0,0 @@
// Copyright 2017-2019 @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 { AccountId, ApprovalFlag, SetIndex } from '@polkadot/types/interfaces';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Observable, of } from 'rxjs';
import { Vec } from '@polkadot/types';
import { switchMap, map } from 'rxjs/operators';
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
import { memo } from '../util';
function queryElections (api: ApiInterfaceRx, who: AccountId | string): Observable<boolean[][]> {
return api.query.elections.nextVoterSet<SetIndex>().pipe(
switchMap((nextVoterSet: SetIndex): Observable<Vec<ApprovalFlag>[]> =>
api.query.elections.approvalsOf.multi(
[...Array(nextVoterSet.toNumber() + 1).keys()].map((i): [string, number] =>
[who.toString(), i]
)
) as any as Observable<Vec<ApprovalFlag>[]>
),
map((votes: Vec<ApprovalFlag>[]): boolean[][] =>
votes.map((flags: Vec<ApprovalFlag>): boolean[] =>
approvalFlagsToBools(flags)
)
)
);
}
/**
* @name approvalsOf
* @returns A nested array of boolean approvals for the given account in each voter set index, converted from its ApprovalFlag(s).
* @example
* <BR>
*
* ```javascript
* api.derive.elections.approvalsOf(ALICE, (approvals) => {
* // approvals === [[false], [true, false], ...]
* });
* ```
*/
export function approvalsOf (api: ApiInterfaceRx): (who: AccountId | string) => Observable<boolean[][]> {
return memo((who: AccountId | string): Observable<boolean[][]> =>
api.query.elections
? queryElections(api, who)
: of([])
);
}
@@ -1,40 +0,0 @@
// Copyright 2017-2019 @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 { AccountId, ApprovalFlag, SetIndex } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Vec } from '@polkadot/types';
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
import { memo } from '../util';
function queryElections (api: ApiInterfaceRx, who: AccountId | string, at: SetIndex | BN | number): Observable<boolean[]> {
return api.query.elections.approvalsOf<Vec<ApprovalFlag>>([who.toString(), at]).pipe(
map((flags: Vec<ApprovalFlag>): boolean[] => approvalFlagsToBools(flags))
);
}
/**
* @name approvalsOfAt
* @returns An array of boolean approvals for the account and set index, converted from the returned ApprovalFlag.
* @example
* <BR>
*
* ```javascript
* api.derive.elections.approvalsOfAt(ALICE, new BN(0), (approvals) => {
* // approvals === [false, true, ...]
* });
* ```
*/
export function approvalsOfAt (api: ApiInterfaceRx): (who: AccountId, at: SetIndex) => Observable<boolean[]> {
return memo((who: AccountId | string, at: SetIndex | BN | number): Observable<boolean[]> =>
api.query.elections
? queryElections(api, who, at)
: of([])
);
}
@@ -2,8 +2,4 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './approvalsOf';
export * from './approvalsOfAt';
export * from './info';
export * from './voters';
export * from './voterPositions';
+14 -49
View File
@@ -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, Balance, BlockNumber, SetIndex, VoteIndex } from '@polkadot/types/interfaces';
import { AccountId, Balance, BlockNumber } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { Observable, combineLatest } from 'rxjs';
@@ -13,40 +13,7 @@ import { createType, Vec, u32 } from '@polkadot/types';
import { DerivedElectionsInfo } from '../types';
import { memo } from '../util';
type ResultElectionsInner = [u32, u32, Vec<ITuple<[AccountId, BlockNumber]>>, SetIndex, BlockNumber, VoteIndex, SetIndex];
type ResultElections = [Vec<AccountId>, ResultElectionsInner];
function deriveElections (api: ApiInterfaceRx, [candidates, [candidateCount, desiredSeats, members, nextVoterSet, termDuration, voteCount, voterCount]]: ResultElections): DerivedElectionsInfo {
return {
candidates,
candidateCount,
desiredSeats,
nextVoterSet,
members: members.map(([accountId]): [AccountId, Balance] => [accountId, createType(api.registry, 'Balance')]),
runnersUp: [],
termDuration,
voteCount,
voterCount
};
}
function queryElections (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
// NOTE We have an issue where candidates can return `null` for an empty array
return combineLatest([
api.query.elections.candidates<Vec<AccountId>>(),
api.queryMulti<ResultElectionsInner>([
api.query.elections.candidateCount,
api.query.elections.desiredSeats,
api.query.elections.members,
api.query.elections.nextVoterSet,
api.query.elections.termDuration,
api.query.elections.voteCount,
api.query.elections.voterCount
])
]).pipe(map((result): DerivedElectionsInfo => deriveElections(api, result)));
}
function derivePhragmen (api: ApiInterfaceRx, candidates: AccountId[], members: [AccountId, Balance][], runnersUp: [AccountId, Balance][], candidacyBond: Balance, desiredSeats: u32, termDuration: BlockNumber, votingBond: Balance): DerivedElectionsInfo {
function deriveElections (api: ApiInterfaceRx, candidates: AccountId[], members: [AccountId, Balance][], runnersUp: [AccountId, Balance][], candidacyBond: Balance, desiredSeats: u32, termDuration: BlockNumber, votingBond: Balance): DerivedElectionsInfo {
return {
candidates,
candidateCount: createType(api.registry, 'u32', candidates.length),
@@ -59,23 +26,25 @@ function derivePhragmen (api: ApiInterfaceRx, candidates: AccountId[], members:
};
}
function queryPhragmen (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
function queryElections (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
const section = api.query.electionsPhragmen ? 'electionsPhragmen' : 'elections';
// NOTE We have an issue where candidates can return `null` for an empty array, hence
// we are not using multi queries here, so empty array is empty (instead of space-filled)
return combineLatest([
api.query.electionsPhragmen.candidates<Vec<AccountId>>(),
api.query.electionsPhragmen.members<Vec<ITuple<[AccountId, Balance]>>>(),
api.query.electionsPhragmen.runnersUp<Vec<ITuple<[AccountId, Balance]>>>()
api.query[section].candidates<Vec<AccountId>>(),
api.query[section].members<Vec<ITuple<[AccountId, Balance]>>>(),
api.query[section].runnersUp<Vec<ITuple<[AccountId, Balance]>>>()
]).pipe(
map(([candidates, members, runnersUp]): DerivedElectionsInfo => derivePhragmen(
map(([candidates, members, runnersUp]): DerivedElectionsInfo => deriveElections(
api,
candidates,
members,
runnersUp,
api.consts.electionsPhragmen.candidacyBond as Balance,
api.consts.electionsPhragmen.desiredMembers as u32,
api.consts.electionsPhragmen.termDuration as BlockNumber,
api.consts.electionsPhragmen.votingBond as Balance
api.consts[section].candidacyBond as Balance,
api.consts[section].desiredMembers as u32,
api.consts[section].termDuration as BlockNumber,
api.consts[section].votingBond as Balance
))
);
}
@@ -94,9 +63,5 @@ function queryPhragmen (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
* ```
*/
export function info (api: ApiInterfaceRx): () => Observable<DerivedElectionsInfo> {
return memo((): Observable<DerivedElectionsInfo> =>
api.query.electionsPhragmen
? queryPhragmen(api)
: queryElections(api)
);
return memo((): Observable<DerivedElectionsInfo> => queryElections(api));
}
@@ -1,62 +0,0 @@
// Copyright 2017-2019 @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 { AccountId, SetIndex } from '@polkadot/types/interfaces';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Vec, Option, createType, u32 } from '@polkadot/types';
import { DerivedVoterPositions } from '../types';
import BN from 'bn.js';
import { of, Observable } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';
import { memo } from '../util';
function queryElections (api: ApiInterfaceRx): Observable<DerivedVoterPositions> {
return api.query.elections.nextVoterSet<SetIndex>().pipe(
switchMap((nextVoterSet: SetIndex): Observable<Vec<Option<AccountId>>[]> =>
api.query.elections.voters.multi<Vec<Option<AccountId>>>([...Array(+nextVoterSet + 1).keys()].map((_, i): [number] => [i]))
),
map((voters: Vec<Option<AccountId>>[]): DerivedVoterPositions => {
return voters.reduce((result: DerivedVoterPositions, vec, setIndex): DerivedVoterPositions => {
vec.forEach((e, index): void => {
// re-create the index based on position 0 is [0][0] and likewise
// 64 (0..63 in first) is [1][0] (the first index value in set 2)
const accountId: AccountId | null = e.unwrapOr(null);
if (accountId) {
result[accountId.toString()] = {
globalIndex: (api.consts.elections.voterSetSize as u32).muln(setIndex).addn(index),
index: new BN(index),
setIndex: createType(api.registry, 'SetIndex', setIndex)
};
}
});
return result;
}, {});
})
);
}
/**
* @name voterPositions
* @returns An mapping of all current voter accounts to their voter set and global index.
* @example
* <BR>
*
* ```javascript
* api.derive.elections.voterPositions((voters) => {
* const { index, setIndex, globalIndex } = voters[ALICE];
* console.log(`ALICE is a voter at index ${index} in voter set ${setIndex}, with global index ${globalIndex}.`);
* });
* ```
*/
export function voterPositions (api: ApiInterfaceRx): () => Observable<DerivedVoterPositions> {
return memo((): Observable<DerivedVoterPositions> =>
api.query.elections
? queryElections(api)
: of({})
);
}
@@ -1,46 +0,0 @@
// Copyright 2017-2019 @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 } from '@polkadot/types/interfaces';
import { DerivedVoterPositions } from '../types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType, Vec } from '@polkadot/types';
import { memo } from '../util';
function queryElections (api: ApiInterfaceRx): Observable<AccountId[]> {
return api.derive.elections.voterPositions().pipe(
map((voterPositions: DerivedVoterPositions): Vec<AccountId> =>
createType(
api.registry,
'Vec<AccountId>',
Object.entries(voterPositions)
.sort((a, b): number => a[1].globalIndex.cmp(b[1].globalIndex))
.map(([accountId]): AccountId => createType(api.registry, 'AccountId', accountId))
)
)
);
}
/**
* @name voters
* @returns An array of all current voters from all sets.
* @example
* <BR>
*
* ```javascript
* api.derive.elections.voters((voters) => {
* console.log(`There are ${voters.length} current voters.`);
* });
* ```
*/
export function voters (api: ApiInterfaceRx): () => Observable<AccountId[]> {
return memo((): Observable<AccountId[]> =>
api.query.elections
? queryElections(api)
: of([])
);
}
+1 -5
View File
@@ -55,17 +55,13 @@ describe('derive', (): void => {
testFunction(api)('democracy', 'referendumVotesFor', []);
testFunction(api)('democracy', 'votes', []);
testFunction(api)('elections', 'approvalsOf', []);
// FIXME This one has an additional check which mock doesnt (yet) cater for
// testFunction(api)('elections', 'approvalsOfAt', []);
testFunction(api)('elections', 'info', []);
testFunction(api)('elections', 'voters', []);
testFunction(api)('session', 'eraLength', []);
testFunction(api)('session', 'eraProgress', []);
testFunction(api)('session', 'sessionProgress', []);
testFunction(api)('staking', 'info', []);
testFunction(api)('staking', 'account', []);
testFunction(api)('staking', 'recentlyOffline', []);
testFunction(api)('staking', 'controllers', []);
});
+3 -1
View File
@@ -11,11 +11,13 @@ import * as accounts from './accounts';
import * as balances from './balances';
import * as chain from './chain';
import * as contracts from './contracts';
import * as council from './council';
import * as democracy from './democracy';
import * as elections from './elections';
import * as imOnline from './imOnline';
import * as session from './session';
import * as staking from './staking';
import * as treasury from './treasury';
export * from './type';
@@ -56,7 +58,7 @@ function injectFunctions<AllSections> (api: ApiInterfaceRx, allSections: AllSect
}, {} as DeriveAllSections<AllSections>);
}
export const derive = { accounts, balances, chain, contracts, democracy, elections, imOnline, session, staking };
export const derive = { accounts, balances, chain, contracts, council, democracy, elections, imOnline, session, staking, treasury };
export type ExactDerive = DeriveAllSections<typeof derive>;
// FIXME The return type of this function should be {...ExactDerive, ...DeriveCustom}
+100
View File
@@ -0,0 +1,100 @@
// Copyright 2017-2019 @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 { Balance, BlockNumber, StakingLedger, UnlockChunk } from '@polkadot/types/interfaces';
import { DerivedSessionInfo, DerivedStakingAccount, DerivedStakingQuery, DerivedUnlocking } from '../types';
import BN from 'bn.js';
import { combineLatest, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType } from '@polkadot/types';
import { isUndefined } from '@polkadot/util';
import { memo } from '../util';
// groups the supplied chunks by era, i.e. { [era]: BN(total of values) }
function groupByEra (list: UnlockChunk[]): Record<string, BN> {
return list.reduce((map: Record<string, BN>, { era, value }): Record<string, BN> => {
const key = era.toString();
map[key] = !map[key]
? value.unwrap()
: map[key].add(value.unwrap());
return map;
}, {});
}
// calculate the remaining blocks in a specific unlock era
function remainingBlocks (api: ApiInterfaceRx, era: BN, sessionInfo: DerivedSessionInfo): BlockNumber {
const remaining = era.sub(sessionInfo.currentEra);
// on the Rust side the current-era >= era-for-unlock (removal done on >)
return createType(api.registry, 'BlockNumber', remaining.gtn(0)
? remaining
.subn(1)
.mul(sessionInfo.eraLength)
.add(sessionInfo.eraLength.sub(sessionInfo.eraProgress))
: 0
);
}
function calculateUnlocking (api: ApiInterfaceRx, stakingLedger: StakingLedger | undefined, sessionInfo: DerivedSessionInfo): DerivedUnlocking[] | undefined {
if (isUndefined(stakingLedger)) {
return undefined;
}
const unlockingChunks = stakingLedger.unlocking.filter(({ era }): boolean =>
remainingBlocks(api, era.unwrap(), sessionInfo).gtn(0)
);
if (!unlockingChunks.length) {
return undefined;
}
// group the unlock chunks that have the same era and sum their values
const groupedResult = groupByEra(unlockingChunks);
const results = Object.entries(groupedResult).map(([eraString, value]): DerivedUnlocking => ({
value: createType(api.registry, 'Balance', value),
remainingBlocks: remainingBlocks(api, new BN(eraString), sessionInfo)
}));
return results.length ? results : undefined;
}
function redeemableSum (api: ApiInterfaceRx, stakingLedger: StakingLedger | undefined, sessionInfo: DerivedSessionInfo): Balance {
if (isUndefined(stakingLedger)) {
return createType(api.registry, 'Balance');
}
return createType(api.registry, 'Balance', stakingLedger.unlocking.reduce((total, { era, value }): BN => {
return remainingBlocks(api, era.unwrap(), sessionInfo).eqn(0)
? total.add(value.unwrap())
: total;
}, new BN(0)));
}
function parseResult (api: ApiInterfaceRx, sessionInfo: DerivedSessionInfo, query: DerivedStakingQuery): DerivedStakingAccount {
return {
...query,
redeemable: redeemableSum(api, query.stakingLedger, sessionInfo),
unlocking: calculateUnlocking(api, query.stakingLedger, sessionInfo)
};
}
/**
* @description From a stash, retrieve the controllerId and fill in all the relevant staking details
*/
export function account (api: ApiInterfaceRx): (accountId: Uint8Array | string) => Observable<DerivedStakingAccount> {
return memo((accountId: Uint8Array | string): Observable<DerivedStakingAccount> =>
combineLatest([
api.derive.session.info(),
api.derive.staking.query(accountId)
]).pipe(
map(([sessionInfo, query]: [DerivedSessionInfo, DerivedStakingQuery]) =>
parseResult(api, sessionInfo, query))
));
}
@@ -4,7 +4,7 @@
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId } from '@polkadot/types/interfaces';
import { DerivedStaking, DerivedStakingElected } from '../types';
import { DerivedStakingQuery, DerivedStakingElected } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
@@ -14,11 +14,11 @@ import { memo } from '../util';
export function electedInfo (api: ApiInterfaceRx): () => Observable<DerivedStakingElected> {
return memo((): Observable<DerivedStakingElected> =>
api.derive.staking.validators().pipe(
switchMap(({ currentElected }): Observable<[AccountId[], DerivedStaking[]]> =>
switchMap(({ currentElected }): Observable<[AccountId[], DerivedStakingQuery[]]> =>
combineLatest([
of(currentElected),
combineLatest(currentElected.map((accountId): Observable<DerivedStaking> =>
api.derive.staking.info(accountId)
combineLatest(currentElected.map((accountId): Observable<DerivedStakingQuery> =>
api.derive.staking.query(accountId)
))
])
),
+2 -1
View File
@@ -2,9 +2,10 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './account';
export * from './controllers';
export * from './electedInfo';
export * from './info';
export * from './overview';
export * from './query';
export * from './recentlyOffline';
export * from './validators';
@@ -3,27 +3,22 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, Balance, BlockNumber, Exposure, Keys, Nominations, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces';
import { AccountId, Exposure, Keys, Nominations, RewardDestination, StakingLedger, ValidatorPrefs } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DerivedRecentlyOffline, DerivedSessionInfo, DerivedStaking, DerivedUnlocking } from '../types';
import { DerivedStakingQuery } from '../types';
import BN from 'bn.js';
import { combineLatest, Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { createType, Option, Vec } from '@polkadot/types';
import { isUndefined } from '@polkadot/util';
import { memo } from '../util';
interface ParseInput {
accountId: AccountId;
controllerId: AccountId;
recentlyOffline?: DerivedRecentlyOffline;
nominators: AccountId[];
rewardDestination: RewardDestination;
queuedKeys?: [AccountId, Keys][];
sessionInfo: DerivedSessionInfo;
stakers: Exposure;
stakingLedger: Option<StakingLedger>;
stashId: AccountId;
@@ -32,68 +27,6 @@ interface ParseInput {
nextKeyFor?: Option<AccountId>;
}
// groups the supplied chunks by era, i.e. { [era]: BN(total of values) }
function groupByEra (list: UnlockChunk[]): Record<string, BN> {
return list.reduce((map: Record<string, BN>, { era, value }): Record<string, BN> => {
const key = era.toString();
map[key] = !map[key]
? value.unwrap()
: map[key].add(value.unwrap());
return map;
}, {});
}
// calculate the remaining blocks in a specific unlock era
function remainingBlocks (api: ApiInterfaceRx, era: BN, sessionInfo: DerivedSessionInfo): BlockNumber {
const remaining = era.sub(sessionInfo.currentEra);
// on the Rust side the current-era >= era-for-unlock (removal done on >)
return createType(api.registry, 'BlockNumber', remaining.gtn(0)
? remaining
.subn(1)
.mul(sessionInfo.eraLength)
.add(sessionInfo.eraLength.sub(sessionInfo.eraProgress))
: 0
);
}
function calculateUnlocking (api: ApiInterfaceRx, stakingLedger: StakingLedger | undefined, sessionInfo: DerivedSessionInfo): DerivedUnlocking[] | undefined {
if (isUndefined(stakingLedger)) {
return undefined;
}
const unlockingChunks = stakingLedger.unlocking.filter(({ era }): boolean =>
remainingBlocks(api, era.unwrap(), sessionInfo).gtn(0)
);
if (!unlockingChunks.length) {
return undefined;
}
// group the unlock chunks that have the same era and sum their values
const groupedResult = groupByEra(unlockingChunks);
const results = Object.entries(groupedResult).map(([eraString, value]): DerivedUnlocking => ({
value: createType(api.registry, 'Balance', value),
remainingBlocks: remainingBlocks(api, new BN(eraString), sessionInfo)
}));
return results.length ? results : undefined;
}
function redeemableSum (api: ApiInterfaceRx, stakingLedger: StakingLedger | undefined, sessionInfo: DerivedSessionInfo): Balance {
if (isUndefined(stakingLedger)) {
return createType(api.registry, 'Balance');
}
return createType(api.registry, 'Balance', stakingLedger.unlocking.reduce((total, { era, value }): BN => {
return remainingBlocks(api, era.unwrap(), sessionInfo).eqn(0)
? total.add(value.unwrap())
: total;
}, new BN(0)));
}
function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; sessionIds: AccountId[] } {
// for 2.x we have a Vec<(ValidatorId,Keys)> of the keys
if (Array.isArray(queuedKeys)) {
@@ -119,7 +52,7 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [
};
}
function parseResult (api: ApiInterfaceRx, { accountId, controllerId, stashId, sessionInfo, recentlyOffline = {}, nextKeyFor, queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys }: ParseInput): DerivedStaking {
function parseResult (api: ApiInterfaceRx, { accountId, controllerId, stashId, nextKeyFor, queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys }: ParseInput): DerivedStakingQuery {
const _stakingLedger = stakingLedger.unwrapOr(undefined);
const _nextKeyFor = nextKeyFor || createType(api.registry, 'Option<AccountId>', null);
const _nextKeys = nextKeys || createType(api.registry, 'Option<Keys>', null);
@@ -128,13 +61,10 @@ function parseResult (api: ApiInterfaceRx, { accountId, controllerId, stashId, s
accountId,
controllerId,
nominators,
offline: recentlyOffline[stashId.toString()],
redeemable: redeemableSum(api, _stakingLedger, sessionInfo),
rewardDestination,
stakers,
stakingLedger: _stakingLedger,
stashId,
unlocking: calculateUnlocking(api, _stakingLedger, sessionInfo),
validatorPrefs,
...unwrapSessionIds(stashId, queuedKeys || _nextKeyFor, _nextKeys)
};
@@ -142,10 +72,8 @@ function parseResult (api: ApiInterfaceRx, { accountId, controllerId, stashId, s
type MultiResultV1 = [Option<AccountId>, Option<StakingLedger>, [Vec<AccountId>], RewardDestination, Exposure, ITuple<[ValidatorPrefs]>];
function retrieveInfoV1 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
return combineLatest([
api.derive.session.info(),
api.derive.staking.recentlyOffline(),
function retrieveInfoV1 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStakingQuery> {
return (
api.queryMulti([
[api.query.session.nextKeyFor, controllerId],
[api.query.staking.ledger, controllerId],
@@ -154,18 +82,17 @@ function retrieveInfoV1 (api: ApiInterfaceRx, accountId: AccountId, stashId: Acc
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId]
]) as Observable<MultiResultV1>
]).pipe(map(([sessionInfo, recentlyOffline, [nextKeyFor, stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]]: [DerivedSessionInfo, DerivedRecentlyOffline, MultiResultV1]): DerivedStaking =>
).pipe(map(([nextKeyFor, stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]: MultiResultV1): DerivedStakingQuery =>
parseResult(api, {
accountId, controllerId, stashId, sessionInfo, recentlyOffline, nextKeyFor, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs
accountId, controllerId, stashId, nextKeyFor, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs
})
));
}
type MultiResultV2 = [[Vec<AccountId>] | Option<ITuple<[Nominations]>>, RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>, Option<StakingLedger>];
function retrieveInfoV2 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
function retrieveInfoV2 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStakingQuery> {
return combineLatest([
api.derive.session.info(),
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
api.queryMulti([
[api.query.staking.nominators, stashId],
@@ -175,7 +102,7 @@ function retrieveInfoV2 (api: ApiInterfaceRx, accountId: AccountId, stashId: Acc
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]],
[api.query.staking.ledger, controllerId]
]) as Observable<MultiResultV2>
]).pipe(map(([sessionInfo, queuedKeys, [_nominators, rewardDestination, stakers, [validatorPrefs], nextKeys, stakingLedger]]: [DerivedSessionInfo, [AccountId, Keys][], MultiResultV2]): DerivedStaking => {
]).pipe(map(([queuedKeys, [_nominators, rewardDestination, stakers, [validatorPrefs], nextKeys, stakingLedger]]: [[AccountId, Keys][], MultiResultV2]): DerivedStakingQuery => {
// if we have staking.storageVersion it indicates the new structure, unwrap as needed
// FIXME We really want to be pulling all the new (valuable) info along
const nominators: AccountId[] = api.query.staking.storageVersion
@@ -185,17 +112,17 @@ function retrieveInfoV2 (api: ApiInterfaceRx, accountId: AccountId, stashId: Acc
: (_nominators as [Vec<AccountId>])[0];
return parseResult(api, {
accountId, controllerId, stashId, sessionInfo, queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys
accountId, controllerId, stashId, queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys
});
}));
}
function retrieveV1 (api: ApiInterfaceRx, accountId: AccountId): Observable<DerivedStaking> {
function retrieveV1 (api: ApiInterfaceRx, accountId: AccountId): Observable<DerivedStakingQuery> {
// depending on where we come from, this may be a controller or stash
return combineLatest([
api.query.staking.bonded<Option<AccountId>>(accountId),
api.query.staking.ledger<Option<StakingLedger>>(accountId)
]).pipe(switchMap(([bonded, stakingLedger]): Observable<DerivedStaking> =>
]).pipe(switchMap(([bonded, stakingLedger]): Observable<DerivedStakingQuery> =>
stakingLedger.isSome
? retrieveInfoV1(api, accountId, stakingLedger.unwrap().stash, accountId)
: bonded.isSome
@@ -204,10 +131,10 @@ function retrieveV1 (api: ApiInterfaceRx, accountId: AccountId): Observable<Deri
));
}
function retrieveV2 (api: ApiInterfaceRx, stashId: AccountId): Observable<DerivedStaking> {
function retrieveV2 (api: ApiInterfaceRx, stashId: AccountId): Observable<DerivedStakingQuery> {
return api.query.staking
.bonded<Option<AccountId>>(stashId)
.pipe(switchMap((controllerId): Observable<DerivedStaking> =>
.pipe(switchMap((controllerId): Observable<DerivedStakingQuery> =>
controllerId.isSome
? retrieveInfoV2(api, stashId, stashId, controllerId.unwrap())
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] })
@@ -217,11 +144,11 @@ function retrieveV2 (api: ApiInterfaceRx, stashId: AccountId): Observable<Derive
/**
* @description From a stash, retrieve the controllerId and fill in all the relevant staking details
*/
export function info (api: ApiInterfaceRx): (_accountId: Uint8Array | string) => Observable<DerivedStaking> {
const query = api.consts.session
export function query (api: ApiInterfaceRx): (_accountId: Uint8Array | string) => Observable<DerivedStakingQuery> {
const retrieve = api.consts.session
? retrieveV2
: retrieveV1;
return memo((accountId: Uint8Array | string): Observable<DerivedStaking> =>
query(api, createType(api.registry, 'AccountId', accountId)));
return memo((accountId: Uint8Array | string): Observable<DerivedStakingQuery> =>
retrieve(api, createType(api.registry, 'AccountId', accountId)));
}
@@ -0,0 +1,5 @@
// Copyright 2017-2019 @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.
export * from './proposals';
@@ -0,0 +1,94 @@
// Copyright 2017-2019 @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 { ProposalIndex, TreasuryProposal } from '@polkadot/types/interfaces';
import { DerivedCouncilProposals, DerivedTreasuryProposal, DerivedTreasuryProposals } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { createType, Option } from '@polkadot/types';
import { memo } from '../util';
interface Result {
allIds: ProposalIndex[];
allProposals: Option<TreasuryProposal>[];
approvalIds: ProposalIndex[];
councilProposals: DerivedCouncilProposals;
proposalCount: ProposalIndex;
}
function parseResult (_api: ApiInterfaceRx, { allIds, allProposals, approvalIds, councilProposals, proposalCount }: Result): DerivedTreasuryProposals {
const approvals: DerivedTreasuryProposal[] = [];
const proposals: DerivedTreasuryProposal[] = [];
const councilTreasury = councilProposals.filter(({ proposal: { methodName, sectionName } }): boolean =>
sectionName === 'treasury' &&
['approveProposal', 'rejectProposal'].includes(methodName)
);
allIds.forEach((id, index): void => {
if (allProposals[index].isSome) {
const council = councilTreasury
.filter(({ proposal }): boolean => id.eq(proposal.args[0]))
.sort((a, b): number => a.proposal.methodName.localeCompare(b.proposal.methodName));
const isApproval = approvalIds.some((approvalId): boolean => approvalId.eq(id));
const derived = { council, id, proposal: allProposals[index].unwrap() };
if (isApproval) {
approvals.push(derived);
} else {
proposals.push(derived);
}
}
});
return { approvals, proposalCount, proposals };
}
function retrieveProposals (api: ApiInterfaceRx, proposalCount: ProposalIndex, approvalIds: ProposalIndex[]): Observable<DerivedTreasuryProposals> {
const proposalIds: ProposalIndex[] = [];
const count = proposalCount.toNumber();
for (let index = 0; index < count; index++) {
const isApproval = approvalIds.some((id): boolean => id.eqn(index));
if (!isApproval) {
proposalIds.push(createType(api.registry, 'ProposalIndex', index));
}
}
const allIds = [...proposalIds, ...approvalIds];
return combineLatest([
api.query.treasury.proposals.multi<Option<TreasuryProposal>>(allIds),
api.derive.council.proposals()
]).pipe(
map(([allProposals, councilProposals]: [Option<TreasuryProposal>[], DerivedCouncilProposals]): DerivedTreasuryProposals =>
parseResult(api, { allIds, allProposals, approvalIds, councilProposals, proposalCount })
)
);
}
/**
* @description Retrieve all active and approved treasury proposals, along with their info
*/
export function proposals (api: ApiInterfaceRx): () => Observable<DerivedTreasuryProposals> {
return memo((): Observable<DerivedTreasuryProposals> =>
api.query.treasury
? combineLatest([
api.query.treasury.proposalCount(),
api.query.treasury.approvals()
]).pipe(
switchMap(([proposalCount, approvalIds]: [ProposalIndex, ProposalIndex[]]) =>
retrieveProposals(api, proposalCount, approvalIds)
)
)
: of({
approvals: [],
proposalCount: createType(api.registry, 'ProposalIndex'),
proposals: []
} as DerivedTreasuryProposals)
);
}
+31 -20
View File
@@ -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, AccountIndex, Balance, BalanceLock, BlockNumber, EraIndex, EraPoints, Exposure, Hash, Index, Keys, Proposal, PropIndex, ReferendumInfo, RewardDestination, SessionIndex, SetIndex, StakingLedger, ValidatorPrefs, Vote, VoteIndex } from '@polkadot/types/interfaces';
import { AccountId, AccountIndex, Balance, BalanceLock, BlockNumber, EraIndex, EraPoints, Exposure, Hash, Index, Keys, Proposal, PropIndex, ProposalIndex, ReferendumInfo, RewardDestination, SessionIndex, SetIndex, StakingLedger, TreasuryProposal, ValidatorPrefs, Vote, Votes, VoteIndex } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import { u32, Vec } from '@polkadot/types';
@@ -44,6 +44,14 @@ export interface DerivedContractFees {
transferFee: BN;
}
export interface DerivedCouncilProposal {
hash: Hash;
proposal: Proposal;
votes: Votes | null;
}
export type DerivedCouncilProposals = DerivedCouncilProposal[];
export interface DerivedElectionsInfo {
candidates: AccountId[];
candidateCount: u32;
@@ -126,24 +134,9 @@ export interface DerivedSessionInfo extends DeriveSessionIndexes {
sessionProgress: BlockNumber;
}
export type DerivedStakingAccount = [AccountId, DerivedStakingOnlineStatus];
export type DerivedStakingAccounts = DerivedStakingAccount[];
export interface DerivedStakingElected {
currentElected: AccountId[];
info: DerivedStaking[];
}
export interface DerivedStakingOnlineStatus {
online?: {
isOnline: boolean;
blockNumber?: BlockNumber;
};
offline?: {
blockNumber: BlockNumber;
count: BN;
}[];
info: DerivedStakingQuery[];
}
export interface DeriveStakingValidators {
@@ -161,12 +154,15 @@ export interface DerivedStakingStash {
validatorPrefs?: ValidatorPrefs;
}
export interface DerivedStaking extends DerivedStakingOnlineStatus, DerivedStakingStash {
export interface DerivedStakingQuery extends DerivedStakingStash {
accountId: AccountId;
nextSessionIds: AccountId[];
redeemable?: Balance;
sessionIds: AccountId[];
stakingLedger?: StakingLedger;
}
export interface DerivedStakingAccount extends DerivedStakingQuery {
redeemable?: Balance;
unlocking?: DerivedUnlocking[];
}
@@ -176,7 +172,22 @@ export interface DerivedStakingOverview extends DeriveSessionIndexes {
validators: AccountId[];
}
export type DerivedUnlocking = { remainingBlocks: BlockNumber; value: Balance };
export interface DerivedTreasuryProposal {
council: DerivedCouncilProposal[];
id: ProposalIndex;
proposal: TreasuryProposal;
}
export interface DerivedTreasuryProposals {
approvals: DerivedTreasuryProposal[];
proposalCount: ProposalIndex;
proposals: DerivedTreasuryProposal[];
}
export type DerivedUnlocking = {
remainingBlocks: BlockNumber;
value: Balance;
};
export interface VoterPosition {
globalIndex: BN;
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api",
"version": "0.98.1",
"version": "0.99.1",
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
"main": "index.js",
"keywords": [
@@ -26,13 +26,13 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/api-derive": "^0.98.1",
"@babel/runtime": "^7.7.6",
"@polkadot/api-derive": "^0.99.1",
"@polkadot/keyring": "^1.7.1",
"@polkadot/metadata": "^0.98.1",
"@polkadot/rpc-core": "^0.98.1",
"@polkadot/rpc-provider": "^0.98.1",
"@polkadot/types": "^0.98.1",
"@polkadot/metadata": "^0.99.1",
"@polkadot/rpc-core": "^0.99.1",
"@polkadot/rpc-provider": "^0.99.1",
"@polkadot/types": "^0.99.1",
"@polkadot/util-crypto": "^1.7.1"
},
"devDependencies": {
+1
View File
@@ -47,6 +47,7 @@ declare module '@polkadot/metadata/Decorated/types' {
minimumDeposit: BalanceOf & ConstantCodec;
emergencyVotingPeriod: BlockNumber & ConstantCodec;
cooloffPeriod: BlockNumber & ConstantCodec;
preimageByteDeposit: BalanceOf & ConstantCodec;
};
elections: {
[index: string]: Codec;
+1 -1
View File
@@ -88,7 +88,7 @@ describe('Combinator', (): void => {
const combinator = new Combinator([
mocker,
// eslint-disable-next-line @typescript-eslint/require-await
async (): UnsubscribePromise => (): void => {}
async (): UnsubscribePromise => (): void => undefined
// eslint-disable-next-line @typescript-eslint/no-unused-vars
], (value: any[]): void => {
// ignore
+8 -8
View File
@@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
import { Observable } from 'rxjs';
import { Option, U8a, Vec } from '@polkadot/types/codec';
import { Option, Raw, Vec } from '@polkadot/types/codec';
import { Bytes, Null, bool, u32, u64 } from '@polkadot/types';
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';
@@ -47,10 +47,10 @@ declare module './types' {
authorities: StorageEntryExact<ApiType, () => Observable<Vec<ITuple<[AuthorityId, BabeAuthorityWeight]>>>> & QueryableStorageEntry<ApiType>;
genesisSlot: StorageEntryExact<ApiType, () => Observable<u64>> & QueryableStorageEntry<ApiType>;
currentSlot: StorageEntryExact<ApiType, () => Observable<u64>> & QueryableStorageEntry<ApiType>;
randomness: StorageEntryExact<ApiType, () => Observable<U8a>> & QueryableStorageEntry<ApiType>;
nextRandomness: StorageEntryExact<ApiType, () => Observable<U8a>> & QueryableStorageEntry<ApiType>;
randomness: StorageEntryExact<ApiType, () => Observable<Raw>> & QueryableStorageEntry<ApiType>;
nextRandomness: StorageEntryExact<ApiType, () => Observable<Raw>> & QueryableStorageEntry<ApiType>;
segmentIndex: StorageEntryExact<ApiType, () => Observable<u32>> & QueryableStorageEntry<ApiType>;
underConstruction: StorageEntryExact<ApiType, (arg: u32 | Uint8Array | number | string) => Observable<Vec<U8a>>> & QueryableStorageEntry<ApiType>;
underConstruction: StorageEntryExact<ApiType, (arg: u32 | Uint8Array | number | string) => Observable<Vec<Raw>>> & QueryableStorageEntry<ApiType>;
initialized: StorageEntryExact<ApiType, () => Observable<Option<MaybeVrf>>> & QueryableStorageEntry<ApiType>;
};
timestamp: {
@@ -123,18 +123,19 @@ declare module './types' {
democracy: {
[index: string]: QueryableStorageEntry<ApiType>;
publicPropCount: StorageEntryExact<ApiType, () => Observable<PropIndex>> & QueryableStorageEntry<ApiType>;
publicProps: StorageEntryExact<ApiType, () => Observable<Vec<ITuple<[PropIndex, Proposal, AccountId]>>>> & QueryableStorageEntry<ApiType>;
publicProps: StorageEntryExact<ApiType, () => Observable<Vec<ITuple<[PropIndex, Hash, AccountId]>>>> & QueryableStorageEntry<ApiType>;
preimages: StorageEntryExact<ApiType, (arg: Hash | Uint8Array | string) => Observable<Option<ITuple<[Bytes, AccountId, BalanceOf, BlockNumber]>>>> & QueryableStorageEntry<ApiType>;
depositOf: StorageEntryExact<ApiType, (arg: PropIndex | Uint8Array | number | string) => Observable<Option<ITuple<[BalanceOf, Vec<AccountId>]>>>> & QueryableStorageEntry<ApiType>;
referendumCount: StorageEntryExact<ApiType, () => Observable<ReferendumIndex>> & QueryableStorageEntry<ApiType>;
nextTally: StorageEntryExact<ApiType, () => Observable<ReferendumIndex>> & QueryableStorageEntry<ApiType>;
referendumInfoOf: StorageEntryExact<ApiType, (arg: ReferendumIndex | Uint8Array | number | string) => Observable<Option<ReferendumInfo>>> & QueryableStorageEntry<ApiType>;
dispatchQueue: StorageEntryExact<ApiType, (arg: BlockNumber | Uint8Array | number | string) => Observable<Vec<Option<ITuple<[Proposal, ReferendumIndex]>>>>> & QueryableStorageEntry<ApiType>;
dispatchQueue: StorageEntryExact<ApiType, (arg: BlockNumber | Uint8Array | number | string) => Observable<Vec<Option<ITuple<[Hash, ReferendumIndex]>>>>> & QueryableStorageEntry<ApiType>;
votersFor: StorageEntryExact<ApiType, (arg: ReferendumIndex | Uint8Array | number | string) => Observable<Vec<AccountId>>> & QueryableStorageEntry<ApiType>;
voteOf: StorageEntryExact<ApiType, (arg: ITuple<[ReferendumIndex, AccountId]>) => Observable<Vote>> & QueryableStorageEntry<ApiType>;
proxy: StorageEntryExact<ApiType, (arg: AccountId | Uint8Array | string) => Observable<Option<AccountId>>> & QueryableStorageEntry<ApiType>;
delegations: StorageEntryExact<ApiType, (arg: AccountId | Uint8Array | string) => Observable<ITuple<[AccountId, Conviction]>>> & QueryableStorageEntry<ApiType>;
lastTabledWasExternal: StorageEntryExact<ApiType, () => Observable<bool>> & QueryableStorageEntry<ApiType>;
nextExternal: StorageEntryExact<ApiType, () => Observable<Option<ITuple<[Proposal, VoteThreshold]>>>> & QueryableStorageEntry<ApiType>;
nextExternal: StorageEntryExact<ApiType, () => Observable<Option<ITuple<[Hash, VoteThreshold]>>>> & QueryableStorageEntry<ApiType>;
blacklist: StorageEntryExact<ApiType, (arg: Hash | Uint8Array | string) => Observable<Option<ITuple<[BlockNumber, Vec<AccountId>]>>>> & QueryableStorageEntry<ApiType>;
cancellations: StorageEntryExact<ApiType, (arg: Hash | Uint8Array | string) => Observable<bool>> & QueryableStorageEntry<ApiType>;
};
@@ -162,7 +163,6 @@ declare module './types' {
votesOf: StorageEntryExact<ApiType, (arg: AccountId | Uint8Array | string) => Observable<Vec<AccountId>>> & QueryableStorageEntry<ApiType>;
stakeOf: StorageEntryExact<ApiType, (arg: AccountId | Uint8Array | string) => Observable<BalanceOf>> & QueryableStorageEntry<ApiType>;
candidates: StorageEntryExact<ApiType, () => Observable<Vec<AccountId>>> & QueryableStorageEntry<ApiType>;
didMigrate: StorageEntryExact<ApiType, () => Observable<bool>> & QueryableStorageEntry<ApiType>;
};
technicalMembership: {
[index: string]: QueryableStorageEntry<ApiType>;
+2 -2
View File
@@ -4,11 +4,11 @@
import { EventRecord, SignedBlock } from '@polkadot/types/interfaces';
import { U8a } from '@polkadot/types';
import { Raw } from '@polkadot/types';
import l from './logging';
export default function filterEvents (extHash: U8a, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[]): EventRecord[] | undefined {
export default function filterEvents (extHash: Raw, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[]): EventRecord[] | undefined {
// extrinsics to hashes
const myHash = extHash.toHex();
const allHashes = extrinsics.map((ext): string => ext.hash.toHex());
@@ -6,7 +6,7 @@ import ApiPromise from '@polkadot/api/promise/Api';
import testingPairs from '@polkadot/keyring/testingPairs';
import { WsProvider } from '@polkadot/rpc-provider';
import { SubmittableResult } from '@polkadot/api';
import { DerivedBalances, DerivedStaking } from '@polkadot/api-derive/types';
import { DerivedBalances, DerivedStakingAccount } from '@polkadot/api-derive/types';
import { describeE2E } from '../../util';
@@ -49,7 +49,7 @@ describeE2E({
it('retrieves all staking info (for controller)', (done): Promise<() => void> => {
const accountId = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
return api.derive.staking.info(accountId, (info: DerivedStaking): void => {
return api.derive.staking.account(accountId, (info: DerivedStakingAccount): void => {
console.error(JSON.stringify(info));
expect(info.accountId.eq(accountId)).toBe(true);
@@ -64,7 +64,7 @@ describeE2E({
it('retrieves all staking info (for stash)', (done): Promise<() => void> => {
const accountId = '5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY';
return api.derive.staking.info(accountId, (info: DerivedStaking): void => {
return api.derive.staking.account(accountId, (info: DerivedStakingAccount): void => {
console.error(JSON.stringify(info));
if (!info.stashId || !info.controllerId || !info.stakingLedger) {
@@ -95,7 +95,7 @@ describeE2E({
});
it('verifies that derive.staking.unlocking isn\'t empty/undefined', (): Promise<() => void> => {
return api.derive.staking.info(ALICE_STASH, (info: DerivedStaking): void => {
return api.derive.staking.account(ALICE_STASH, (info: DerivedStakingAccount): void => {
expect(info.unlocking).toBeDefined();
});
});
@@ -116,7 +116,7 @@ describeE2E({
});
it('verifies payee for ALICE_STASH', (done): Promise<() => void> => {
return api.derive.staking.info(ALICE_STASH, (info: DerivedStaking): void => {
return api.derive.staking.account(ALICE_STASH, (info: DerivedStakingAccount): void => {
if (!info.rewardDestination) {
return done.fail(new Error('rewardDestination is undefined.'));
} else {
@@ -127,7 +127,7 @@ describeE2E({
});
});
it('staking.info updates itself after changing reward destination', async (done): Promise<void> => {
it('staking.account updates itself after changing reward destination', async (done): Promise<void> => {
const stashId = testingPairs().alice_stash.address;
// start by setting the reqred to Staked, so we have a common starting point
@@ -139,19 +139,18 @@ describeE2E({
}
});
let count = 0; // The # of times we got a callback response from api.derive.staking.info
let count = 0; // The # of times we got a callback response from api.derive.staking.account
// Subscribe to staking.info
api.derive.staking
.info(stashId, (result): void => {
++count;
// Subscribe to staking.account
api.derive.staking.account(stashId, (result): void => {
++count;
console.error('***', count, JSON.stringify(result));
console.error('***', count, JSON.stringify(result));
if (count >= 2 && result.rewardDestination!.toString() === 'Stash') {
done();
}
});
if (count >= 2 && result.rewardDestination!.toString() === 'Stash') {
done();
}
});
// Wait a bit, and change reward destination
// eslint-disable-next-line @typescript-eslint/no-misused-promises
+1 -1
View File
@@ -52,7 +52,7 @@ export function describeE2E (options?: Options): (message: string, inner: (wsUrl
const wsEndpoints = getWsEndpoints(options);
if (!wsEndpoints.length) {
describe('Empty test Suite', (): void => {
it('No tests found for passed endpoints', (): void => {});
it('No tests found for passed endpoints', (): void => undefined);
});
} else {
wsEndpoints.map((wsName): [string, string] => [wsName, WS_ENDPOINTS[wsName]])
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/metadata",
"version": "0.98.1",
"version": "0.99.1",
"description": "Helpers to extract information from runtime metadata",
"main": "index.js",
"publishConfig": {
@@ -26,8 +26,8 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-metadata#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/types": "^0.98.1",
"@babel/runtime": "^7.7.6",
"@polkadot/types": "^0.99.1",
"@polkadot/util": "^1.7.1",
"@polkadot/util-crypto": "^1.7.1"
},
@@ -3,6 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ClassOf, createType, TypeRegistry } from '@polkadot/types/codec/create';
import { hexToU8a } from '@polkadot/util';
import Decorated from './Decorated';
import json from '../Metadata/static';
@@ -17,10 +18,9 @@ describe('Decorated', () => {
.balances
.freeBalance('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
).toEqual(
// length prefix attached
Uint8Array.from([
128, 127, 134, 78, 24, 227, 221, 139, 88, 56, 99, 16, 210, 254, 9, 25, 238, 242, 124, 110, 85, 133, 100, 183, 246, 127, 34, 217, 157, 32, 245, 135, 187
])
hexToU8a(
'0x0101c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42e3fb4c297a84c5cebc0e78257d213d0927ccc7596044c6ba013dd05522aacba'
)
);
});
@@ -15,6 +15,12 @@ const consts = fromMetadata(registry, metadata);
describe('fromMetadata', (): void => {
it('should return constants with the correct type and value', (): void => {
expect(consts.democracy.cooloffPeriod).toBeInstanceOf(ClassOf(registry, 'BlockNumber'));
expect(consts.democracy.cooloffPeriod.toHex()).toEqual('0x000c4e00');
// 3 second blocks, 28 days
expect(consts.democracy.cooloffPeriod.toNumber()).toEqual(28 * 24 * 60 * (60 / 3));
});
it('correctly handles bytes', (): void => {
// 0x34 removes as the length prefix removed
expect(consts.session.dedupKeyPrefix.toHex()).toEqual('0x3a73657373696f6e3a6b657973');
});
});
@@ -10,6 +10,8 @@ import { stringCamelCase } from '@polkadot/util';
import Metadata from '../../../Metadata';
const AS_STRIPPED = ['Bytes'];
/**
* Retrieve the parameter types (module constants) from the runtime metadata.
*
@@ -25,13 +27,20 @@ export default function fromMetadata (registry: Registry, metadata: Metadata): C
// For access, we change the index names, i.e. Democracy.EnactmentPeriod -> democracy.enactmentPeriod
result[stringCamelCase(name.toString())] = moduleMetadata.constants.reduce((newModule: ModuleConstants, meta): ModuleConstants => {
const codec = createTypeUnsafe(registry, meta.type.toString(), [meta.value]);
// in the case of Bytes, the data has a length prefix encoded when received,
// leading to double-encoding unless removed
const type = meta.type.toString();
const codec: ConstantCodec = createTypeUnsafe(registry, type, [
AS_STRIPPED.includes(type)
? meta.value.toU8a(true)
: meta.value
]);
// This is not a perfect idea, however as it stands with number-only constants on the metadata
// does not have any effect. However, this could become problematic in cases where items are
// exposed that contain their own metadata. As of now, the compatibility with current, e.g.
// storage is the driving factor, one consistent way of handling interfaces
(codec as ConstantCodec).meta = meta;
codec.meta = meta;
newModule[stringCamelCase(meta.name.toString())] = codec;
return newModule;
@@ -86,7 +86,7 @@ describe('createFunction', (): void => {
key1: new Text(registry, 'AccountId'),
key2: new Text(registry, 'AccountId'),
value: new Text(registry, 'Balance'),
key2Hasher: new Text(registry, 'twox_128')
key2Hasher: new StorageHasher(registry, 'Twox128')
}
}
} as any
@@ -118,7 +118,7 @@ describe('createFunction', (): void => {
key1: new Text(registry, 'Null'),
key2: new Text(registry, 'Hash'),
value: new Text(registry, 'Vec<(BlockNumber,EventIndex)>'),
key2Hasher: new Text(registry, 'blake2_256')
key2Hasher: new StorageHasher(registry, 'Blake2_256')
}
}
} as any
@@ -129,4 +129,43 @@ describe('createFunction', (): void => {
// the value of the not Null type key does effect the result
expect(u8aToHex(storageFn(['any', [1, 2, 3]]))).not.toEqual(u8aToHex(storageFn(['any', [1, 2, 3, 4]])));
});
it('allows creating of known DoubleMap keys (with Bytes)', (): void => {
const storageFn = createFunction(registry, {
prefix: 'Session',
section: 'session',
method: 'NextKeys',
meta: {
type: {
isDoubleMap: true,
asDoubleMap: {
hasher: new StorageHasher(registry, 'Twox64Concat'),
key1: new Text(registry, 'Bytes'),
key2: new Text(registry, 'AccountId'),
value: new Text(registry, 'SessionKeys5'),
key2Hasher: new StorageHasher(registry, 'Blake2_256')
}
}
} as any
}, { metaVersion: 9 });
expect(
u8aToHex(
storageFn([
// hex, without length prefix
'0x3a73657373696f6e3a6b657973',
// address
'DB2mp5nNhbFN86J9hxoAog8JALMhDXgwvWMxrRMLNUFMEY4'
])
)
).toEqual(
'0x' +
'5901' + // length
'cec5070d609dd3497f72bde07fc96ba0' + // twox 128
'4c014e6bf8b8c2c011e7290b85696bb3' + // twox 128
'9fe6329cc0b39e09' + // twox 64
'343a73657373696f6e3a6b657973' + // twox 64 (concat, with length)
'5eb36b60f0fc4b9177116eba3e5cd57fea6289a57f5f5b9ffeb0475c66e7a521' // blake2
);
});
});
@@ -6,7 +6,7 @@ import { StorageEntryMetadataLatest } from '@polkadot/types/interfaces/metadata'
import { Codec, Registry } from '@polkadot/types/types';
import BN from 'bn.js';
import { Compact, U8a, createType, createTypeUnsafe } from '@polkadot/types/codec';
import { Compact, Raw, createType, createTypeUnsafe } from '@polkadot/types/codec';
import StorageKey, { StorageEntry } from '@polkadot/types/primitive/StorageKey';
import { assert, isNull, isUndefined, stringLowerFirst, stringToU8a, u8aConcat } from '@polkadot/util';
import { xxhashAsU8a } from '@polkadot/util-crypto';
@@ -27,7 +27,7 @@ export interface CreateItemFn {
}
interface IterFn {
(): U8a;
(): Raw;
meta: StorageEntryMetadataLatest;
}
@@ -78,8 +78,8 @@ function createKeyDoubleMap (registry: Registry, itemFn: CreateItemFn, stringKey
const [key1, key2] = args;
const map = type.asDoubleMap;
const val1 = createTypeUnsafe(registry, map.key1.toString(), [key1]).toU8a(true);
const val2 = createTypeUnsafe(registry, map.key2.toString(), [key2]).toU8a(true);
const val1 = createTypeUnsafe(registry, map.key1.toString(), [key1]).toU8a();
const val2 = createTypeUnsafe(registry, map.key2.toString(), [key2]).toU8a();
// as per createKey, always add the length prefix (underlying it is Bytes)
return Compact.addLengthPrefix(
@@ -142,7 +142,7 @@ function expandWithMeta ({ meta, method, prefix, section }: CreateItemFn, storag
return storageFn;
}
function extendHeadMeta (registry: Registry, { meta: { documentation, name, type }, section }: CreateItemFn, { method }: StorageEntry, iterFn: () => U8a): StorageKey {
function extendHeadMeta (registry: Registry, { meta: { documentation, name, type }, section }: CreateItemFn, { method }: StorageEntry, iterFn: () => Raw): StorageKey {
const map = type.asMap;
const outputType = map.key.toString();
@@ -165,8 +165,8 @@ function extendLinkedMap (registry: Registry, itemFn: CreateItemFn, storageFn: S
? hasher(`head of ${stringKey}`)
: u8aConcat(xxhashAsU8a(itemFn.prefix, 128), xxhashAsU8a(`HeadOf${itemFn.method}`, 128));
storageFn.iterKey = extendHeadMeta(registry, itemFn, storageFn, (): U8a =>
new U8a(registry, key)
storageFn.iterKey = extendHeadMeta(registry, itemFn, storageFn, (): Raw =>
new Raw(registry, key)
);
return storageFn;
@@ -174,8 +174,8 @@ function extendLinkedMap (registry: Registry, itemFn: CreateItemFn, storageFn: S
// attach the full list hashing for prefixed maps
function extendPrefixedMap (registry: Registry, itemFn: CreateItemFn, storageFn: StorageEntry): StorageEntry {
storageFn.iterKey = extendHeadMeta(registry, itemFn, storageFn, (): U8a =>
new U8a(registry, createPrefixedKey(itemFn))
storageFn.iterKey = extendHeadMeta(registry, itemFn, storageFn, (): Raw =>
new Raw(registry, createPrefixedKey(itemFn))
);
return storageFn;
@@ -7,28 +7,49 @@ import { TypeRegistry } from '@polkadot/types';
import { u8aToHex } from '@polkadot/util';
import rpcMetadata from '../../../Metadata/static';
import rpcMetadataV8 from '../../../Metadata/v8/static';
import Decorated from '../../Decorated';
const registry = new TypeRegistry();
const keyring = testingPairs({ type: 'ed25519' });
const decorated = new Decorated(registry, rpcMetadata);
describe('fromMetadata', (): void => {
it('should throw if the storage function expects an argument', (): void => {
expect((): any => decorated.query.balances.freeBalance()).toThrowError(/requires one argument/);
describe('latest', (): void => {
const registry = new TypeRegistry();
const decorated = new Decorated(registry, rpcMetadata);
it('should throw if the storage function expects an argument', (): void => {
expect((): any => decorated.query.balances.freeBalance()).toThrowError(/requires one argument/);
});
it('should return a value if the storage function does not expect an argument', (): void => {
expect((): any => decorated.query.timestamp.now()).not.toThrow();
});
it('should return the correct length-prefixed storage key', (): void => {
expect(
u8aToHex(
decorated.query.balances.freeBalance(keyring.alice.address)
)
).toEqual(
// new storage key format
'0x0101c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b42e3fb4c297a84c5cebc0e78257d213d0927ccc7596044c6ba013dd05522aacba'
);
});
});
it('should return a value if the storage function does not expect an argument', (): void => {
expect((): any => decorated.query.timestamp.now()).not.toThrow();
});
describe('V8', (): void => {
const registry = new TypeRegistry();
const decorated = new Decorated(registry, rpcMetadataV8);
it('should return the correct length-prefixed storage key', (): void => {
expect(
u8aToHex(
decorated.query.balances.freeBalance(keyring.alice.address)
)
).toEqual(
'0x807f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587bb'
);
it('should return the correct length-prefixed storage key', (): void => {
expect(
u8aToHex(
decorated.query.balances.freeBalance(keyring.alice.address)
)
).toEqual(
// old storage key format
'0x807f864e18e3dd8b58386310d2fe0919eef27c6e558564b7f67f22d99d20f587bb'
);
});
});
});
+1 -1
View File
@@ -2,6 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import metadata from './v8/static';
import metadata from './v9/static';
export default metadata;
@@ -25,11 +25,10 @@ function extractTypes (types: string[]): any[] {
case TypeDefInfo.VecFixed:
return extractTypes([(decoded.ext as TypeDefExtVecFixed).type]);
case TypeDefInfo.BTreeMap:
case TypeDefInfo.Result:
case TypeDefInfo.Tuple:
return extractTypes(
(decoded.sub as TypeDef[]).map((sub): string => sub.type)
);
return extractTypes((decoded.sub as TypeDef[]).map((sub): string => sub.type));
default:
throw new Error(`Unhandled: Unable to create and validate type from ${type}`);
@@ -1089,18 +1089,21 @@
},
{
"name": "Nominators",
"modifier": 1,
"modifier": 0,
"type": {
"Map": {
"hasher": "Blake2_256",
"key": "AccountId",
"value": "Vec<AccountId>",
"value": "Nominations",
"linked": true
}
},
"fallback": "0x00",
"documentation": [
" The map from nominator stash key to the set of stash keys of all validators to nominate."
" The map from nominator stash key to the set of stash keys of all validators to nominate.",
"",
" NOTE: is private so that we can ensure upgraded before all typical accesses.",
" Direct storage APIs can still bypass this protection."
]
},
{
@@ -1214,6 +1217,34 @@
" The rest of the slashed value is handled by the `Slash`."
]
},
{
"name": "CanceledSlashPayout",
"modifier": 1,
"type": {
"Plain": "BalanceOf"
},
"fallback": "0x00000000000000000000000000000000",
"documentation": [
" The amount of currency given to reporters of a slash event which was",
" canceled by extraordinary circumstances (e.g. governance)."
]
},
{
"name": "UnappliedSlashes",
"modifier": 1,
"type": {
"Map": {
"hasher": "Blake2_256",
"key": "EraIndex",
"value": "Vec<UnappliedSlash>",
"linked": false
}
},
"fallback": "0x00",
"documentation": [
" All unapplied slashes that are queued for later."
]
},
{
"name": "BondedEras",
"modifier": 1,
@@ -1226,19 +1257,93 @@
]
},
{
"name": "EraSlashJournal",
"modifier": 1,
"name": "ValidatorSlashInEra",
"modifier": 0,
"type": {
"DoubleMap": {
"hasher": "Blake2_256",
"key1": "EraIndex",
"key2": "AccountId",
"value": "(Perbill,BalanceOf)",
"key2Hasher": "Twox128"
}
},
"fallback": "0x00",
"documentation": [
" All slashing events on validators, mapped by era to the highest slash proportion",
" and slash value of the era."
]
},
{
"name": "NominatorSlashInEra",
"modifier": 0,
"type": {
"DoubleMap": {
"hasher": "Blake2_256",
"key1": "EraIndex",
"key2": "AccountId",
"value": "BalanceOf",
"key2Hasher": "Twox128"
}
},
"fallback": "0x00",
"documentation": [
" All slashing events on nominators, mapped by era to the highest slash value of the era."
]
},
{
"name": "SlashingSpans",
"modifier": 0,
"type": {
"Map": {
"hasher": "Blake2_256",
"key": "EraIndex",
"value": "Vec<SlashJournalEntry>",
"key": "AccountId",
"value": "SlashingSpans",
"linked": false
}
},
"fallback": "0x00",
"documentation": [
" All slashes that have occurred in a given era."
" Slashing spans for stash accounts."
]
},
{
"name": "SpanSlash",
"modifier": 1,
"type": {
"Map": {
"hasher": "Blake2_256",
"key": "(AccountId,SpanIndex)",
"value": "SpanRecord",
"linked": false
}
},
"fallback": "0x0000000000000000000000000000000000000000000000000000000000000000",
"documentation": [
" Records information about the maximum slash of a stash within a slashing span,",
" as well as how much reward has been paid out."
]
},
{
"name": "EarliestUnappliedSlash",
"modifier": 0,
"type": {
"Plain": "EraIndex"
},
"fallback": "0x00",
"documentation": [
" The earliest era for which we have a pending, unapplied slash."
]
},
{
"name": "StorageVersion",
"modifier": 1,
"type": {
"Plain": "u32"
},
"fallback": "0x00000000",
"documentation": [
" The version of storage for upgrade."
]
}
]
@@ -1533,6 +1638,28 @@
" - One storage write",
" # </weight>"
]
},
{
"name": "cancel_deferred_slash",
"args": [
{
"name": "era",
"type": "EraIndex"
},
{
"name": "slash_indices",
"type": "Vec<u32>"
}
],
"documentation": [
" Cancel enactment of a deferred slash. Can be called by either the root origin or",
" the `T::SlashCancelOrigin`.",
" passing the era and indices of the slashes for that era to kill.",
"",
" # <weight>",
" - One storage write.",
" # </weight>"
]
}
],
"events": [
@@ -1766,11 +1893,28 @@
"name": "PublicProps",
"modifier": 1,
"type": {
"Plain": "Vec<(PropIndex,Proposal,AccountId)>"
"Plain": "Vec<(PropIndex,Hash,AccountId)>"
},
"fallback": "0x00",
"documentation": [
" The public proposals. Unsorted."
" The public proposals. Unsorted. The second item is the proposal's hash."
]
},
{
"name": "Preimages",
"modifier": 0,
"type": {
"Map": {
"hasher": "Blake2_256",
"key": "Hash",
"value": "(Bytes,AccountId,BalanceOf,BlockNumber)",
"linked": false
}
},
"fallback": "0x00",
"documentation": [
" Map of hashes to the proposal preimage, along with who registered it and their deposit.",
" The block number is the block at which it was deposited."
]
},
{
@@ -1832,9 +1976,9 @@
"modifier": 1,
"type": {
"Map": {
"hasher": "Blake2_256",
"hasher": "Twox64Concat",
"key": "BlockNumber",
"value": "Vec<Option<(Proposal,ReferendumIndex)>>",
"value": "Vec<Option<(Hash,ReferendumIndex)>>",
"linked": false
}
},
@@ -1927,7 +2071,7 @@
"name": "NextExternal",
"modifier": 0,
"type": {
"Plain": "(Proposal,VoteThreshold)"
"Plain": "(Hash,VoteThreshold)"
},
"fallback": "0x00",
"documentation": [
@@ -1977,8 +2121,8 @@
"name": "propose",
"args": [
{
"name": "proposal",
"type": "Proposal"
"name": "proposal_hash",
"type": "Hash"
},
{
"name": "value",
@@ -2072,8 +2216,8 @@
"name": "external_propose",
"args": [
{
"name": "proposal",
"type": "Proposal"
"name": "proposal_hash",
"type": "Hash"
}
],
"documentation": [
@@ -2085,8 +2229,8 @@
"name": "external_propose_majority",
"args": [
{
"name": "proposal",
"type": "Proposal"
"name": "proposal_hash",
"type": "Hash"
}
],
"documentation": [
@@ -2101,8 +2245,8 @@
"name": "external_propose_default",
"args": [
{
"name": "proposal",
"type": "Proposal"
"name": "proposal_hash",
"type": "Hash"
}
],
"documentation": [
@@ -2258,6 +2402,59 @@
" - O(1).",
" # </weight>"
]
},
{
"name": "clear_public_proposals",
"args": [],
"documentation": [
" Veto and blacklist the proposal hash. Must be from Root origin."
]
},
{
"name": "note_preimage",
"args": [
{
"name": "encoded_proposal",
"type": "Bytes"
}
],
"documentation": [
" Register the preimage for an upcoming proposal. This doesn't require the proposal to be",
" in the dispatch queue but does require a deposit, returned once enacted."
]
},
{
"name": "note_imminent_preimage",
"args": [
{
"name": "encoded_proposal",
"type": "Bytes"
},
{
"name": "when",
"type": "BlockNumber"
},
{
"name": "which",
"type": "u32"
}
],
"documentation": [
" Register the preimage for an upcoming proposal. This requires the proposal to be",
" in the dispatch queue. No deposit is needed."
]
},
{
"name": "reap_preimage",
"args": [
{
"name": "proposal_hash",
"type": "Hash"
}
],
"documentation": [
" Remove an expired proposal preimage and collect the deposit."
]
}
],
"events": [
@@ -2267,7 +2464,9 @@
"PropIndex",
"Balance"
],
"documentation": []
"documentation": [
" A motion has been proposed by a public account."
]
},
{
"name": "Tabled",
@@ -2276,12 +2475,16 @@
"Balance",
"Vec<AccountId>"
],
"documentation": []
"documentation": [
" A public proposal has been tabled for referendum vote."
]
},
{
"name": "ExternalTabled",
"args": [],
"documentation": []
"documentation": [
" An external proposal has been tabled."
]
},
{
"name": "Started",
@@ -2289,28 +2492,36 @@
"ReferendumIndex",
"VoteThreshold"
],
"documentation": []
"documentation": [
" A referendum has begun."
]
},
{
"name": "Passed",
"args": [
"ReferendumIndex"
],
"documentation": []
"documentation": [
" A proposal has been approved by referendum."
]
},
{
"name": "NotPassed",
"args": [
"ReferendumIndex"
],
"documentation": []
"documentation": [
" A proposal has been rejected by referendum."
]
},
{
"name": "Cancelled",
"args": [
"ReferendumIndex"
],
"documentation": []
"documentation": [
" A referendum has been cancelled."
]
},
{
"name": "Executed",
@@ -2318,7 +2529,9 @@
"ReferendumIndex",
"bool"
],
"documentation": []
"documentation": [
" A proposal has been enacted."
]
},
{
"name": "Delegated",
@@ -2326,14 +2539,18 @@
"AccountId",
"AccountId"
],
"documentation": []
"documentation": [
" An account has delegated their vote to another account."
]
},
{
"name": "Undelegated",
"args": [
"AccountId"
],
"documentation": []
"documentation": [
" An account has cancelled a previous delegation operation."
]
},
{
"name": "Vetoed",
@@ -2342,7 +2559,63 @@
"Hash",
"BlockNumber"
],
"documentation": []
"documentation": [
" An external proposal has been vetoed."
]
},
{
"name": "PreimageNoted",
"args": [
"Hash",
"AccountId",
"Balance"
],
"documentation": [
" A proposal's preimage was noted, and the deposit taken."
]
},
{
"name": "PreimageUsed",
"args": [
"Hash",
"AccountId",
"Balance"
],
"documentation": [
" A proposal preimage was removed and used (the deposit was returned)."
]
},
{
"name": "PreimageInvalid",
"args": [
"Hash",
"ReferendumIndex"
],
"documentation": [
" A proposal could not be executed because its preimage was invalid."
]
},
{
"name": "PreimageMissing",
"args": [
"Hash",
"ReferendumIndex"
],
"documentation": [
" A proposal could not be executed because its preimage was missing."
]
},
{
"name": "PreimageReaped",
"args": [
"Hash",
"AccountId",
"Balance",
"AccountId"
],
"documentation": [
" A registered preimage was removed and the deposit collected by the reaper (last item)."
]
}
],
"constants": [
@@ -2397,6 +2670,14 @@
"documentation": [
" Period in blocks where an external proposal may not be re-submitted after being vetoed."
]
},
{
"name": "PreimageByteDeposit",
"type": "BalanceOf",
"value": "0x0010a5d4e80000000000000000000000",
"documentation": [
" The amount of balance that must be deposited per byte of preimage stored."
]
}
],
"errors": []
@@ -3205,6 +3486,20 @@
"",
" May only be called from `ResetOrigin` or root."
]
},
{
"name": "change_key",
"args": [
{
"name": "new",
"type": "AccountId"
}
],
"documentation": [
" Swap out the sending member for some other key `new`.",
"",
" May only be called from `Signed` origin of a current member."
]
}
],
"events": [
@@ -3236,6 +3531,13 @@
" The membership was reset; see the transaction for who the new set is."
]
},
{
"name": "KeyChanged",
"args": [],
"documentation": [
" One of the members' keys changed."
]
},
{
"name": "Dummy",
"args": [
File diff suppressed because one or more lines are too long
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/rpc-core",
"version": "0.98.1",
"version": "0.99.1",
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
"main": "index.js",
"keywords": [
@@ -26,10 +26,10 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-core#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/jsonrpc": "^0.98.1",
"@polkadot/rpc-provider": "^0.98.1",
"@polkadot/types": "^0.98.1",
"@babel/runtime": "^7.7.6",
"@polkadot/jsonrpc": "^0.99.1",
"@polkadot/rpc-provider": "^0.99.1",
"@polkadot/types": "^0.99.1",
"@polkadot/util": "^1.7.1",
"rxjs": "^6.5.3"
}
+4 -4
View File
@@ -359,8 +359,8 @@ export default class Rpc implements RpcInterface {
private formatStorageData (key: StorageKey, value: string | null): Codec {
// single return value (via state.getStorage), decode the value based on the
// outputType that we have specified. Fallback to Data on nothing
const type = key.outputType || 'Data';
// outputType that we have specified. Fallback to Raw on nothing
const type = key.outputType || 'Raw';
const meta = key.meta || EMPTY_META;
const isEmpty = isNull(value);
@@ -386,8 +386,8 @@ export default class Rpc implements RpcInterface {
}
private formatStorageSet (key: StorageKey, changes: [string, string | null][], witCache: boolean): Codec {
// Fallback to Data (i.e. just the encoding) if we don't have a specific type
const type = key.outputType || 'Data';
// Fallback to Raw (i.e. just the encoding) if we don't have a specific type
const type = key.outputType || 'Raw';
const hexKey = key.toHex();
const meta = key.meta || EMPTY_META;
+2 -2
View File
@@ -44,7 +44,7 @@ describe('methodSend', (): void => {
const method = (rpc as any).createMethodSend(methods.blah);
method().subscribe(
(): void => {},
(): void => undefined,
(error: Error): void => {
expect(error.message).toMatch(/blah\(foo: Bytes\): Bytes/);
done();
@@ -57,7 +57,7 @@ describe('methodSend', (): void => {
const method = (rpc as any).createMethodSend(methods.bleh);
method(1).subscribe(
(): void => {},
(): void => undefined,
(error: Error): void => {
expect(error.message).toMatch(/parameters, 1 found instead/);
done();
+1 -1
View File
@@ -26,7 +26,7 @@ const ERR = (error: Error): Observable<never> => {
throw error;
};
const NOOP = (): void => {};
const NOOP = (): void => undefined;
/**
* Shorthand for distinctUntilChanged(), publishReplay(1) and refCount().
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/rpc-provider",
"version": "0.98.1",
"version": "0.99.1",
"description": "Transport providers for the API",
"main": "index.js",
"keywords": [
@@ -26,13 +26,13 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/metadata": "^0.98.1",
"@babel/runtime": "^7.7.6",
"@polkadot/metadata": "^0.99.1",
"@polkadot/util": "^1.7.1",
"@polkadot/util-crypto": "^1.7.1",
"eventemitter3": "^4.0.0",
"isomorphic-fetch": "^2.2.1",
"websocket": "^1.0.30"
"websocket": "^1.0.31"
},
"devDependencies": {
"@polkadot/keyring": "^1.7.1",
@@ -24,7 +24,7 @@ describe('subscribe', (): void => {
it('returns a subscription id', (): Promise<void> => {
return mock
.subscribe('chain_newHead', 'chain_subscribeNewHead', (): void => {})
.subscribe('chain_newHead', 'chain_subscribeNewHead', (): void => undefined)
.then((id): void => {
expect(id).toEqual(1);
});
@@ -15,7 +15,7 @@ describe('unsubscribe', (): void => {
mock = new Mock(registry);
return mock
.subscribe('chain_newHead', 'chain_subscribeNewHead', (): void => {})
.subscribe('chain_newHead', 'chain_subscribeNewHead', (): void => undefined)
.then((_id): void => {
id = _id;
});
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/jsonrpc",
"version": "0.98.1",
"version": "0.99.1",
"description": "Method definitions for the Polkadot RPC layer",
"main": "index.js",
"publishConfig": {
@@ -26,6 +26,6 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-jsonrpc#readme",
"dependencies": {
"@babel/runtime": "^7.7.4"
"@babel/runtime": "^7.7.6"
}
}
+1 -2
View File
@@ -17,7 +17,7 @@ These are the base types of the codec. They are typically not used directly, but
| [[Set]] | An Set is an array of string values, represented an an encoded type by a bitwise representation of the values |
| [[Struct]] | A Struct defines an Object with key-value pairs - where the values are Codec values. |
| [[Tuple]] | A Tuple defines an anonymous fixed-length array, where each element has its own type |
| [[U8a]] | A basic wrapper around Uint8Array. It will consume the full Uint8Array as passed to it |
| [[Raw]] | A basic wrapper around Uint8Array. It will consume the full Uint8Array as passed to it |
| [[U8aFixed]] | A U8a that manages a a sequence of bytes up to the specified bitLength |
| [[UInt]] | A generic unsigned integer codec. It handles the encoding and decoding of Little Endian encoded numbers in Substrate |
| [[Vec]] | This manages codec arrays. Internally it keeps track of the length (as decoded) |
@@ -36,7 +36,6 @@ These primitive types are available:
| [[bool]] | Representation for a boolean value in the system |
| [[Bytes]] | A Bytes wrapper for `Vec<u8>` |
| [[Call]] | Extrinsic function descriptor, as defined in [the extrinsic format for a node](https://github.com/paritytech/wiki/blob/master/Extrinsic.md#the-extrinsic-format-for-node) |
| [[Data]] | A raw data structure. It is an encoding of a U8a without any length encoding |
| [[Event]] | Wrapper for the actual data that forms part of an [[Event]] |
| [[EventRecord]] | A record for an [[Event]] (as specified by [[Metadata]]) with the specific [[Phase]] of application |
| [[Extrinsic]] | Representation of an Extrinsic in the system |
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/types",
"version": "0.98.1",
"version": "0.99.1",
"description": "Implementation of the Parity codec",
"main": "index.js",
"keywords": [
@@ -26,8 +26,8 @@
},
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types#readme",
"dependencies": {
"@babel/runtime": "^7.7.4",
"@polkadot/metadata": "^0.98.1",
"@babel/runtime": "^7.7.6",
"@polkadot/metadata": "^0.99.1",
"@polkadot/util": "^1.7.1",
"@polkadot/util-crypto": "^1.7.1",
"@types/memoizee": "^0.4.3",
+2 -2
View File
@@ -8,7 +8,7 @@ import { u8aConcat, u8aToHex } from '@polkadot/util';
import { blake2AsU8a } from '@polkadot/util-crypto';
import Compact from './Compact';
import U8a from './U8a';
import Raw from './Raw';
import { compareArray } from './utils';
/**
@@ -40,7 +40,7 @@ export default abstract class AbstractArray<T extends Codec> extends Array<T> im
* @description returns a hash of the contents
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
+2 -2
View File
@@ -8,7 +8,7 @@ import BN from 'bn.js';
import { bnToBn, hexToBn, isHex, isString, isU8a, u8aToBn } from '@polkadot/util';
import { blake2AsU8a } from '@polkadot/util-crypto';
import U8a from './U8a';
import Raw from './Raw';
export type UIntBitLength = 8 | 16 | 32 | 64 | 128 | 256;
@@ -78,7 +78,7 @@ export default abstract class AbstractInt extends BN implements Codec {
* @description returns a hash of the contents
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
+2 -2
View File
@@ -8,7 +8,7 @@ import { isHex, hexToU8a, isU8a, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot
import { blake2AsU8a } from '@polkadot/util-crypto';
import Compact from './Compact';
import U8a from './U8a';
import Raw from './Raw';
import { compareMap, decodeU8a, typeToConstructor } from './utils';
export default class BTreeMap<K extends Codec = Codec, V extends Codec = Codec> extends Map<K, V> implements Codec {
@@ -119,7 +119,7 @@ export default class BTreeMap<K extends Codec = Codec, V extends Codec = Codec>
* @description Returns a hash of the value
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
+2 -2
View File
@@ -6,7 +6,7 @@ import { AnyJson, BareOpts, Codec, IHash, Registry } from '../types';
import { blake2AsU8a } from '@polkadot/util-crypto';
import U8a from './U8a';
import Raw from './Raw';
/**
* @name Base
@@ -33,7 +33,7 @@ export default abstract class Base<T extends Codec> implements Codec {
* @description returns a hash of the contents
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
+1 -1
View File
@@ -131,7 +131,7 @@ describe('Compact', (): void => {
).toEqual(4);
});
it('constructs properly via U8a as U32', (): void => {
it('constructs properly via Uint8Array as U32', (): void => {
expect(
new (Compact.with(U32))(registry, new Uint8Array([254, 255, 3, 0])).toNumber()
).toEqual(new BN(0xffff).toNumber());
+1 -1
View File
@@ -208,7 +208,7 @@ describe('Enum', (): void => {
).toEqual(1);
});
it('converts to and from U8a', (): void => {
it('converts to and from Uint8Array', (): void => {
expect(
new Enum(registry, ['foo', 'bar'], new Uint8Array([1])).toU8a()
).toEqual(new Uint8Array([1]));
@@ -5,29 +5,29 @@
import { CodecTo } from '../types';
import { TypeRegistry } from './create';
import U8a from './U8a';
import Raw from './Raw';
const registry = new TypeRegistry();
const testDecode = (type: string, input: any, expected: string): void =>
it(`can decode from ${type}`, (): void => {
const e = new U8a(registry, input);
const e = new Raw(registry, input);
expect(e.toString()).toBe(expected);
});
const testEncode = (to: CodecTo, expected: any): void =>
it(`can encode ${to}`, (): void => {
const e = new U8a(registry, [1, 2, 3, 4, 5]);
const e = new Raw(registry, [1, 2, 3, 4, 5]);
expect(e[to]()).toEqual(expected);
});
describe('U8a', (): void => {
let u8a: U8a;
let u8a: Raw;
beforeEach((): void => {
u8a = new U8a(registry, [1, 2, 3, 4, 5]);
u8a = new Raw(registry, [1, 2, 3, 4, 5]);
});
testDecode('Array', [1, 2, 3, 4, 5], '0x0102030405');
@@ -50,7 +50,7 @@ describe('U8a', (): void => {
it('allows wrapping of a pre-existing instance', (): void => {
expect(
new U8a(registry, u8a).length
new Raw(registry, u8a).length
).toEqual(5);
});
@@ -8,7 +8,7 @@ import { isU8a, isUndefined, u8aToHex, u8aToU8a } from '@polkadot/util';
import { blake2AsU8a } from '@polkadot/util-crypto';
/**
* @name U8a
* @name Raw
* @description
* A basic wrapper around Uint8Array, with no frills and no fuss. It does differ
* from other implementations where it will consume the full Uint8Array as passed to it.
@@ -16,11 +16,11 @@ import { blake2AsU8a } from '@polkadot/util-crypto';
* actual lengths instead of used directly.
* @noInheritDoc
*/
export default class U8a extends Uint8Array implements IU8a {
export default class Raw extends Uint8Array implements IU8a {
public readonly registry: Registry;
constructor (registry: Registry, value?: AnyU8a) {
super(U8a.decodeU8a(value));
super(Raw.decodeU8a(value));
this.registry = registry;
}
@@ -44,7 +44,7 @@ export default class U8a extends Uint8Array implements IU8a {
* @description returns a hash of the contents
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
@@ -78,7 +78,7 @@ export default class U8a extends Uint8Array implements IU8a {
!this.some((value, index): boolean => value !== other[index]);
}
return this.eq(U8a.decodeU8a(other));
return this.eq(Raw.decodeU8a(other));
}
/**
+2 -2
View File
@@ -7,7 +7,7 @@ import { Codec, Constructor, IHash, Registry } from '../types';
import { assert, isU8a, isNumber, isUndefined, stringCamelCase, stringUpperFirst, u8aToHex } from '@polkadot/util';
import { blake2AsU8a } from '@polkadot/util-crypto';
import U8a from './U8a';
import Raw from './Raw';
import { compareArray } from './utils';
type SetValues = Record<string, number>;
@@ -109,7 +109,7 @@ export default class CodecSet extends Set<string> implements Codec {
* @description returns a hash of the contents
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
+2 -2
View File
@@ -7,7 +7,7 @@ import { AnyJsonObject, BareOpts, Codec, Constructor, ConstructorDef, IHash, Int
import { hexToU8a, isBoolean, isHex, isObject, isU8a, isUndefined, u8aConcat, u8aToHex } from '@polkadot/util';
import { blake2AsU8a } from '@polkadot/util-crypto';
import U8a from './U8a';
import Raw from './Raw';
import { compareMap, decodeU8a, mapToTypeMap } from './utils';
type TypesDef<T = Codec> = Record<string, InterfaceTypes | Constructor<T>>;
@@ -180,7 +180,7 @@ export default class Struct<
* @description returns a hash of the contents
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
+2 -2
View File
@@ -7,7 +7,7 @@ import { AnyJsonObject, Codec, IHash, Registry } from '../types';
import { isUndefined } from '@polkadot/util';
import { blake2AsU8a } from '@polkadot/util-crypto';
import U8a from './U8a';
import Raw from './Raw';
import { compareMap } from './utils';
@@ -58,7 +58,7 @@ export default class StructAny extends Map<string, any> implements Codec {
* @description returns a hash of the contents
*/
public get hash (): IHash {
return new U8a(this.registry, blake2AsU8a(this.toU8a(), 256));
return new Raw(this.registry, blake2AsU8a(this.toU8a(), 256));
}
/**
+2 -2
View File
@@ -6,7 +6,7 @@ import { isString, u8aToU8a } from '@polkadot/util';
import { AnyU8a, Constructor, Registry } from '../types';
import U8a from './U8a';
import Raw from './Raw';
// The 520 here is a weird one - it is explicitly for a [u8; 65] as found as a EcdsaSignature
// Likewise 160 is for [u8; 20], which is also a H160, i.e. an Ethereum address. Both these are
@@ -19,7 +19,7 @@ export type BitLength = 8 | 16 | 32 | 64 | 128 | 160 | 256 | 512 | 520 | 1024 |
* A U8a that manages a a sequence of bytes up to the specified bitLength. Not meant
* to be used directly, rather is should be subclassed with the specific lengths.
*/
export default class U8aFixed extends U8a {
export default class U8aFixed extends Raw {
constructor (registry: Registry, value: AnyU8a = new Uint8Array(), bitLength: BitLength = 256) {
super(registry, U8aFixed.decodeU8aFixed(value, bitLength));
}
+12 -14
View File
@@ -8,16 +8,12 @@ import { CallFunction, Codec, Constructor, RegistryTypes, Registry, RegistryMeta
import extrinsicsFromMeta from '@polkadot/metadata/Decorated/extrinsics/fromMetadata';
import { assert, isFunction, isString, isUndefined, stringCamelCase, u8aToHex } from '@polkadot/util';
import Raw from '../Raw';
import { EventData } from '../../primitive/Generic/Event';
import { createClass } from './createClass';
import { getTypeClass } from './getTypeClass';
import { getTypeDef } from './getTypeDef';
const FN_UNKNOWN: Partial<CallFunction> = {
method: 'unknown',
section: 'unknown'
};
// create event classes from metadata
function decorateEvents (registry: Registry, metadata: RegistryMetadata, metadataEvents: Record<string, Constructor<EventData>>): void {
// decorate the events
@@ -38,7 +34,7 @@ function decorateEvents (registry: Registry, metadata: RegistryMetadata, metadat
console.error(error);
}
metadataEvents[eventIndex.toString()] = class extends EventData {
metadataEvents[u8aToHex(eventIndex)] = class extends EventData {
constructor (registry: Registry, value: Uint8Array) {
super(registry, Types, value, typeDef, meta, sectionName, methodName);
}
@@ -54,7 +50,7 @@ function decorateExtrinsics (registry: Registry, metadata: RegistryMetadata, met
// decorate the extrinsics
Object.values(extrinsics).forEach((methods): void =>
Object.values(methods).forEach((method): void => {
metadataCalls[method.callIndex.toString()] = method;
metadataCalls[u8aToHex(method.callIndex)] = method;
})
);
}
@@ -76,7 +72,7 @@ export class TypeRegistry implements Registry {
const definitions: Record<string, { types: RegistryTypes }> = require('../../interfaces/definitions');
// since these are classes, they are injected first
this.register({ ...baseTypes });
this.register({ Raw, ...baseTypes });
// since these are definitions, they would only get created when needed
Object.values(definitions).forEach(({ types }): void =>
@@ -85,17 +81,19 @@ export class TypeRegistry implements Registry {
}
public findMetaCall (callIndex: Uint8Array): CallFunction {
assert(Object.keys(this._metadataCalls).length > 0, 'Calling registry.findMetaCall before metadata has been attached.');
const hexIndex = u8aToHex(callIndex);
const fn = this._metadataCalls[hexIndex];
return this._metadataCalls[callIndex.toString()] || FN_UNKNOWN;
assert(!isUndefined(fn), `findMetaCall: Unable to find Call with index ${hexIndex}/[${callIndex}]`);
return fn;
}
public findMetaEvent (eventIndex: Uint8Array): Constructor<EventData> {
assert(Object.keys(this._metadataEvents).length > 0, 'Calling registry.findMetaEvent before metadata has been attached.');
const hexIndex = u8aToHex(eventIndex);
const Event = this._metadataEvents[hexIndex];
const Event = this._metadataEvents[eventIndex.toString()];
assert(!isUndefined(Event), `Unable to find Event with index ${u8aToHex(eventIndex)}`);
assert(!isUndefined(Event), `findMetaEvent: Unable to find Event with index ${hexIndex}/[${eventIndex}]`);
return Event;
}
@@ -46,6 +46,7 @@ const mappings: Mapper[] = [
_alias('exec::StorageKey', 'ContractStorageKey'),
// Phantom
_alias('rstd::marker::PhantomData', 'PhantomData'),
_alias('sp_std::marker::PhantomData', 'PhantomData'),
// flattens tuples with one value, `(AccountId)` -> `AccountId`
_flattenSingleTuple(),
// converts ::Type to Type, <T as Trait<I>>::Proposal -> ::Proposal
+1 -1
View File
@@ -21,7 +21,7 @@ export { default as Tuple } from './Tuple';
export { default as Vec } from './Vec';
// Convenience base classes, used as "anything of this type" bases
export { default as U8a } from './U8a';
export { default as Raw } from './Raw';
export { default as UInt } from './UInt';
// Type management helper functions
+17 -7
View File
@@ -21,14 +21,24 @@ export function paramsNotation (outer: string, inner?: string | any[], transform
}
function encodeWithParams (typeDef: Pick<TypeDef, any>, outer = typeDef.displayName || typeDef.type): string {
const { sub, params } = typeDef;
const { info, sub, params } = typeDef;
return paramsNotation(
outer,
params || sub,
// eslint-disable-next-line @typescript-eslint/no-use-before-define
(param: TypeDef) => displayType(param)
);
switch (info) {
case TypeDefInfo.BTreeMap:
case TypeDefInfo.Compact:
case TypeDefInfo.Linkage:
case TypeDefInfo.Option:
case TypeDefInfo.Result:
case TypeDefInfo.Vec:
return paramsNotation(
outer,
params || sub,
// eslint-disable-next-line @typescript-eslint/no-use-before-define
(param: TypeDef) => displayType(param)
);
default:
return outer;
}
}
function encodeSubTypes (sub: TypeDef[], asEnum?: boolean): string {
+34 -5
View File
@@ -1,8 +1,8 @@
// Auto-generated via `yarn build:interfaces`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
import { Compact, Option, Vec } from '@polkadot/types/codec';
import { Bytes, Data, Fixed64, H160, H256, H512, Null, StorageData, StorageHasher, StorageKey, Text, Type, U256, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { Compact, Option, Raw, Vec } from '@polkadot/types/codec';
import { Bytes, Fixed64, H160, H256, H512, Null, StorageData, StorageHasher, StorageKey, Text, Type, U256, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, Moment, MortalEra, MultiSignature, Origin, Perbill, Permill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { InclusionHeight, Uncle, UncleEntryItem } from '@polkadot/types/interfaces/authorship';
import { RawAuraPreDigest } from '@polkadot/types/interfaces/aura';
@@ -16,6 +16,7 @@ import { AccountInfo, Amount, AssetOf, InherentOfflineReport, LockPeriods, NewAc
import { ApprovalFlag, SetIndex, Vote, VoteIndex, VoteThreshold, VoterInfo } from '@polkadot/types/interfaces/elections';
import { AssetOptions, Owner, PermissionLatest, PermissionVersions, PermissionsV1 } from '@polkadot/types/interfaces/genericAsset';
import { AuthorityIndex, AuthorityList, AuthorityWeight, NextAuthority, PendingPause, PendingResume, SetId, StoredPendingChange, StoredState } from '@polkadot/types/interfaces/grandpa';
import { Data, IdentityFields, IdentityInfo, IdentityInfoAdditional, Judgement, RegistrarIndex, RegistrarInfo, Registration, RegistrationJudgement } from '@polkadot/types/interfaces/identity';
import { AuthIndex, AuthoritySignature, Heartbeat, OpaqueMultiaddr, OpaqueNetworkState, OpaquePeerId } from '@polkadot/types/interfaces/imOnline';
import { Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences';
import { FullIdentification, IdentificationTuple, Keys, SessionIndex, SessionKeys1, SessionKeys2, SessionKeys3, SessionKeys4, SessionKeys5, SessionKeys6 } from '@polkadot/types/interfaces/session';
@@ -37,9 +38,6 @@ export interface InterfaceRegistry {
Bytes: Bytes;
'Option<Bytes>': Option<Bytes>;
'Vec<Bytes>': Vec<Bytes>;
Data: Data;
'Option<Data>': Option<Data>;
'Vec<Data>': Vec<Data>;
H160: H160;
'Option<H160>': Option<H160>;
'Vec<H160>': Vec<H160>;
@@ -120,6 +118,9 @@ export interface InterfaceRegistry {
'Compact<usize>': Compact<usize>;
'Option<usize>': Option<usize>;
'Vec<usize>': Vec<usize>;
Raw: Raw;
'Option<Raw>': Option<Raw>;
'Vec<Raw>': Vec<Raw>;
AccountId: AccountId;
'Option<AccountId>': Option<AccountId>;
'Vec<AccountId>': Vec<AccountId>;
@@ -534,6 +535,34 @@ export interface InterfaceRegistry {
StoredState: StoredState;
'Option<StoredState>': Option<StoredState>;
'Vec<StoredState>': Vec<StoredState>;
Data: Data;
'Option<Data>': Option<Data>;
'Vec<Data>': Vec<Data>;
IdentityFields: IdentityFields;
'Option<IdentityFields>': Option<IdentityFields>;
'Vec<IdentityFields>': Vec<IdentityFields>;
IdentityInfoAdditional: IdentityInfoAdditional;
'Option<IdentityInfoAdditional>': Option<IdentityInfoAdditional>;
'Vec<IdentityInfoAdditional>': Vec<IdentityInfoAdditional>;
IdentityInfo: IdentityInfo;
'Option<IdentityInfo>': Option<IdentityInfo>;
'Vec<IdentityInfo>': Vec<IdentityInfo>;
Judgement: Judgement;
'Option<Judgement>': Option<Judgement>;
'Vec<Judgement>': Vec<Judgement>;
RegistrationJudgement: RegistrationJudgement;
'Option<RegistrationJudgement>': Option<RegistrationJudgement>;
'Vec<RegistrationJudgement>': Vec<RegistrationJudgement>;
Registration: Registration;
'Option<Registration>': Option<Registration>;
'Vec<Registration>': Vec<Registration>;
RegistrarIndex: RegistrarIndex;
'Compact<RegistrarIndex>': Compact<RegistrarIndex>;
'Option<RegistrarIndex>': Option<RegistrarIndex>;
'Vec<RegistrarIndex>': Vec<RegistrarIndex>;
RegistrarInfo: RegistrarInfo;
'Option<RegistrarInfo>': Option<RegistrarInfo>;
'Vec<RegistrarInfo>': Vec<RegistrarInfo>;
AuthIndex: AuthIndex;
'Compact<AuthIndex>': Compact<AuthIndex>;
'Option<AuthIndex>': Option<AuthIndex>;
@@ -22,7 +22,7 @@ export default {
},
ContractExecResultSuccess: {
status: 'u8',
data: 'Data'
data: 'Raw'
},
ContractExecResult: {
_enum: {
@@ -2,8 +2,8 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
import { Codec } from '@polkadot/types/types';
import { Compact, Enum, Option, Struct } from '@polkadot/types/codec';
import { Bytes, Data, Null, bool, u32, u64, u8 } from '@polkadot/types/primitive';
import { Compact, Enum, Option, Raw, Struct } from '@polkadot/types/codec';
import { Bytes, Null, bool, u32, u64, u8 } from '@polkadot/types/primitive';
import { AccountId, Balance, BlockNumber, Hash } from '@polkadot/types/interfaces/runtime';
/** Struct */
@@ -53,8 +53,8 @@ export interface ContractExecResult extends Enum {
export interface ContractExecResultSuccess extends Struct {
/** u8 */
readonly status: u8;
/** Data */
readonly data: Data;
/** Raw */
readonly data: Raw;
}
/** Enum */
@@ -18,6 +18,7 @@ export { default as deprecated } from './deprecated/definitions';
export { default as elections } from './elections/definitions';
export { default as genericAsset } from './genericAsset/definitions';
export { default as grandpa } from './grandpa/definitions';
export { default as identity } from './identity/definitions';
export { default as imOnline } from './imOnline/definitions';
export { default as offences } from './offences/definitions';
export { default as session } from './session/definitions';
@@ -0,0 +1,63 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export default {
types: {
Data: {
_enum: {
None: 'Null',
Raw: 'Bytes',
BlakeTwo256: 'H256',
Sha256: 'H256',
Keccak256: 'H256',
ShaThree256: 'H256'
}
},
IdentityFields: {
_set: {
Display: 0b0000000000000000000000000000000000000000000000000000000000000001,
Legal: 0b0000000000000000000000000000000000000000000000000000000000000010,
Web: 0b0000000000000000000000000000000000000000000000000000000000000100,
Riot: 0b0000000000000000000000000000000000000000000000000000000000001000,
Email: 0b0000000000000000000000000000000000000000000000000000000000010000,
PgpFingerprint: 0b0000000000000000000000000000000000000000000000000000000000100000,
Image: 0b0000000000000000000000000000000000000000000000000000000001000000
}
},
IdentityInfoAdditional: '(Data, Data)',
IdentityInfo: {
additional: 'Vec<IdentityInfoAdditional>',
display: 'Data',
legal: 'Data',
web: 'Data',
riot: 'Data',
email: 'Data',
pgpFingerprint: 'Option<H160>',
image: 'Data'
},
Judgement: {
_enum: {
Unknown: 'Null',
FeePaid: 'Balance',
Reasonable: 'Null',
KnownGood: 'Null',
OutOfDate: 'Null',
LowQuality: 'Null',
Erroneous: 'Null'
}
},
RegistrationJudgement: '(RegistrarIndex, Judgement)',
Registration: {
judgements: 'Vec<RegistrationJudgement>',
deposit: 'Balance',
info: 'IdentityInfo'
},
RegistrarIndex: 'u32',
RegistrarInfo: {
account: 'AccountId',
fee: 'Balance',
fields: 'IdentityFields'
}
}
};
@@ -0,0 +1,4 @@
// Auto-generated via `yarn build:interfaces`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
export * from './types';
@@ -0,0 +1,120 @@
// Auto-generated via `yarn build:interfaces`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
import { ITuple } from '@polkadot/types/types';
import { Enum, Option, Set, Struct, Vec } from '@polkadot/types/codec';
import { Bytes, H160, H256, u32 } from '@polkadot/types/primitive';
import { AccountId, Balance } from '@polkadot/types/interfaces/runtime';
/** Enum */
export interface Data extends Enum {
/** 0:: None */
readonly isNone: boolean;
/** 1:: Raw(Bytes) */
readonly isRaw: boolean;
/** Bytes */
readonly asRaw: Bytes;
/** 2:: BlakeTwo256(H256) */
readonly isBlakeTwo256: boolean;
/** H256 */
readonly asBlakeTwo256: H256;
/** 3:: Sha256(H256) */
readonly isSha256: boolean;
/** H256 */
readonly asSha256: H256;
/** 4:: Keccak256(H256) */
readonly isKeccak256: boolean;
/** H256 */
readonly asKeccak256: H256;
/** 5:: ShaThree256(H256) */
readonly isShaThree256: boolean;
/** H256 */
readonly asShaThree256: H256;
}
/** Set */
export interface IdentityFields extends Set {
/** boolean */
readonly isDisplay: boolean;
/** boolean */
readonly isLegal: boolean;
/** boolean */
readonly isWeb: boolean;
/** boolean */
readonly isRiot: boolean;
/** boolean */
readonly isEmail: boolean;
/** boolean */
readonly isPgpFingerprint: boolean;
/** boolean */
readonly isImage: boolean;
}
/** Struct */
export interface IdentityInfo extends Struct {
/** Vec<IdentityInfoAdditional> */
readonly additional: Vec<IdentityInfoAdditional>;
/** Data */
readonly display: Data;
/** Data */
readonly legal: Data;
/** Data */
readonly web: Data;
/** Data */
readonly riot: Data;
/** Data */
readonly email: Data;
/** Option<H160> */
readonly pgpFingerprint: Option<H160>;
/** Data */
readonly image: Data;
}
/** ITuple<[Data, Data]> */
export interface IdentityInfoAdditional extends ITuple<[Data, Data]> {}
/** Enum */
export interface Judgement extends Enum {
/** 0:: Unknown */
readonly isUnknown: boolean;
/** 1:: FeePaid(Balance) */
readonly isFeePaid: boolean;
/** Balance */
readonly asFeePaid: Balance;
/** 2:: Reasonable */
readonly isReasonable: boolean;
/** 3:: KnownGood */
readonly isKnownGood: boolean;
/** 4:: OutOfDate */
readonly isOutOfDate: boolean;
/** 5:: LowQuality */
readonly isLowQuality: boolean;
/** 6:: Erroneous */
readonly isErroneous: boolean;
}
/** u32 */
export interface RegistrarIndex extends u32 {}
/** Struct */
export interface RegistrarInfo extends Struct {
/** AccountId */
readonly account: AccountId;
/** Balance */
readonly fee: Balance;
/** IdentityFields */
readonly fields: IdentityFields;
}
/** Struct */
export interface Registration extends Struct {
/** Vec<RegistrationJudgement> */
readonly judgements: Vec<RegistrationJudgement>;
/** Balance */
readonly deposit: Balance;
/** IdentityInfo */
readonly info: IdentityInfo;
}
/** ITuple<[RegistrarIndex, Judgement]> */
export interface RegistrationJudgement extends ITuple<[RegistrarIndex, Judgement]> {}
@@ -42,7 +42,7 @@ describe('SignedBlock', (): void => {
const indexes = s.block.extrinsics.map(({ method: { callIndex } }): Uint8Array => callIndex);
expect(indexes).toEqual([
new Uint8Array([0x02, 0x00]),
new Uint8Array([0x03, 0x00]),
new Uint8Array([0x0c, 0x00])
]);
});
@@ -13,7 +13,7 @@ import json3 from '../../json/EventRecord.003.json';
describe('EventRecord', (): void => {
const registry = new TypeRegistry();
describe('EventRecord_0_76', (): void => {
describe('EventRecordTo76', (): void => {
beforeEach((): void => {
// eslint-disable-next-line no-new
new Metadata(registry, rpcMetadataV0);
@@ -46,7 +46,8 @@ describe('EventRecord', (): void => {
const er = records[0];
expect(er.phase.type).toEqual('ApplyExtrinsic');
expect(records.toHex()).toEqual(hex);
// additional payment info
expect(records.toHex()).toEqual(`${hex}000000000000`);
});
});
});
+1
View File
@@ -14,6 +14,7 @@ export * from './deprecated/types';
export * from './elections/types';
export * from './genericAsset/types';
export * from './grandpa/types';
export * from './identity/types';
export * from './imOnline/types';
export * from './offences/types';
export * from './session/types';
+2 -2
View File
@@ -3,7 +3,7 @@
"result": {
"block": {
"extrinsics": [
"0x010200b0b1c85b00000000"
"0x010300b0b1c85b00000000"
],
"header": {
"digest": {
@@ -55,4 +55,4 @@
}
},
"id": 8
}
}
+1 -1
View File
@@ -1 +1 @@
{"jsonrpc":"2.0","result":{"block":{"extrinsics":["0x280202000b868d92346c01","0x14020c008151"],"header":{"digest":{"logs":["0x0642414245c101a5cb8138000000000000000000000000549baa911a66f7bab6318a6930380bfd015713f77b6775d2df467d37dadd224dda0a80881cfbddc580d45b3b7358f28e4990d950df4508590543d39d635b3402822279397c1d55449b201710c706ce5de3fd3cb2e269bea6ba89c71e4446fd06","0x05424142450101e4e9f32bb0e72821032f752422c6dc23e8acd5388eb17cbe009d7e3764a0625b38c1b90ec6f19bb5d8c093deeddf9df01845352ac6fefad49601be1f726cea09"]},"extrinsicsRoot":"0x794ff5dde3eaa27d56cc760dd18774c883d51ed9206ff93c9a7e7d6a8a6dca11","number":"0x1461","parentHash":"0x28cda71a46766fe3cf64475b566916d367617d14627e895067f4186e65609d0e","stateRoot":"0xc7803b39c1b30a87566ec9d95890db76cf2eee7034faee4c8a0997759e7bcb7e"}},"justification":null},"id":29}
{"jsonrpc":"2.0","result":{"block":{"extrinsics":["0x280203000b868d92346c01","0x14020c008151"],"header":{"digest":{"logs":["0x0642414245c101a5cb8138000000000000000000000000549baa911a66f7bab6318a6930380bfd015713f77b6775d2df467d37dadd224dda0a80881cfbddc580d45b3b7358f28e4990d950df4508590543d39d635b3402822279397c1d55449b201710c706ce5de3fd3cb2e269bea6ba89c71e4446fd06","0x05424142450101e4e9f32bb0e72821032f752422c6dc23e8acd5388eb17cbe009d7e3764a0625b38c1b90ec6f19bb5d8c093deeddf9df01845352ac6fefad49601be1f726cea09"]},"extrinsicsRoot":"0x794ff5dde3eaa27d56cc760dd18774c883d51ed9206ff93c9a7e7d6a8a6dca11","number":"0x1461","parentHash":"0x28cda71a46766fe3cf64475b566916d367617d14627e895067f4186e65609d0e","stateRoot":"0xc7803b39c1b30a87566ec9d95890db76cf2eee7034faee4c8a0997759e7bcb7e"}},"justification":null},"id":29}
+34 -8
View File
@@ -7,34 +7,60 @@ import Bytes from './Bytes';
describe('Bytes', (): void => {
const registry = new TypeRegistry();
const CODE = new Uint8Array([0x14, 0x3a, 0x63, 0x6f, 0x64, 0x65]);
const NUM = [0x3a, 0x63, 0x6f, 0x64, 0x65];
const U8A = new Uint8Array([0x14, ...NUM]);
const HEX = '0x3a636f6465';
describe('construction', (): void => {
it('decodes when input is string', (): void => {
expect(
new Bytes(registry, ':code').toU8a()
).toEqual(CODE);
).toEqual(U8A);
});
it('decodes when hex is not length prefixed', (): void => {
expect(
new Bytes(registry, '0x3a636f6465').toU8a()
).toEqual(CODE);
new Bytes(registry, HEX).toU8a()
).toEqual(U8A);
});
it('decodes from UInt8Array', (): void => {
expect(
new Bytes(registry, U8A).toU8a()
).toEqual(U8A);
});
it('decodes from number[]', (): void => {
expect(
new Bytes(registry, [0x3a, 0x63, 0x6f, 0x64, 0x65]).toU8a()
).toEqual(CODE);
new Bytes(registry, NUM).toU8a()
).toEqual(U8A);
});
it('creates via storagedata (no prefix)', (): void => {
expect(
new Bytes(
registry,
createType(registry, 'StorageData', '0x3a636f6465')
createType(registry, 'StorageData', HEX)
).toU8a()
).toEqual(CODE);
).toEqual(U8A);
});
it('encodes from itself', (): void => {
expect(
new Bytes(registry, new Bytes(registry, HEX)).toU8a()
).toEqual(U8A);
});
it('strips length with toU8a(true)', (): void => {
expect(
new Bytes(registry, HEX).toU8a(true)
).toEqual(U8A.subarray(1));
});
it('strips length with toHex', (): void => {
expect(
new Bytes(registry, HEX).toHex()
).toEqual(HEX);
});
});
});
+4 -4
View File
@@ -7,7 +7,7 @@ import { AnyU8a, Registry } from '../types';
import { assert, isString, isU8a, u8aToU8a } from '@polkadot/util';
import Compact from '../codec/Compact';
import U8a from '../codec/U8a';
import Raw from '../codec/Raw';
/**
* @name Bytes
@@ -16,7 +16,7 @@ import U8a from '../codec/U8a';
* is that this version allows for length-encoding. (i.e. it is a variable-item codec, the same
* as what is found in [[Text]] and [[Vec]])
*/
export default class Bytes extends U8a {
export default class Bytes extends Raw {
constructor (registry: Registry, value?: AnyU8a) {
super(registry, Bytes.decodeBytes(value));
}
@@ -24,8 +24,8 @@ export default class Bytes extends U8a {
private static decodeBytes (value?: AnyU8a): Uint8Array | undefined {
if (Array.isArray(value) || isString(value)) {
return u8aToU8a(value);
} else if (!(value instanceof U8a) && isU8a(value)) {
// We are ensuring we are not a U8a instance. In the case of a U8a we already have gotten
} else if (!(value instanceof Raw) && isU8a(value)) {
// We are ensuring we are not a Rawv instance. In the case of a Raw we already have gotten
// rid of the length, i.e. new Bytes(new Bytes(...)) will work as expected
return Bytes.decodeBytesU8a(value);
}
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2017-2019 @polkadot/types 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 U8a from '../codec/U8a';
/**
* @name Data
* @description
* A raw data structure. It is just an encoding of a U8a, without any length encoding
*/
export default class Data extends U8a {
}
@@ -9,7 +9,7 @@ import { assert, bnToBn, hexToU8a, isHex, isU8a, isObject, u8aToBn } from '@polk
import Enum from '../../codec/Enum';
import Tuple from '../../codec/Tuple';
import U8a from '../../codec/U8a';
import Raw from '../../codec/Raw';
import U64 from '../U64';
import { IMMORTAL_ERA } from './constants';
@@ -33,7 +33,7 @@ interface ImmortalEnumDef {
* @description
* The ImmortalEra for an extrinsic
*/
export class ImmortalEra extends U8a {
export class ImmortalEra extends Raw {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
constructor (registry: Registry, value?: AnyU8a) {
// For immortals, we always provide the known value (i.e. treated as a
@@ -10,7 +10,7 @@ import { u8aToHex } from '@polkadot/util';
import { createType } from '../../codec/create';
import Base from '../../codec/Base';
import Compact from '../../codec/Compact';
import U8a from '../../codec/U8a';
import Raw from '../../codec/Raw';
import u32 from '../../primitive/U32';
import ExtrinsicEra from './ExtrinsicEra';
import { DEFAULT_VERSION } from './constants';
@@ -72,9 +72,9 @@ export default class ExtrinsicPayload extends Base<ExtrinsicPayloadVx> {
}
/**
* @description The [[U8a]] contained in the payload
* @description The [[Raw]] contained in the payload
*/
public get method (): U8a {
public get method (): Raw {
return this.raw.method;
}
@@ -5,7 +5,7 @@
import { setSS58Format } from '@polkadot/util-crypto';
import { createType, TypeRegistry } from '../../codec/create';
import U8a from '../../codec/U8a';
import Raw from '../../codec/Raw';
import jsonVec from '../../json/AccountIdVec.001.json';
import AccountId from './AccountId';
@@ -43,8 +43,8 @@ describe('AccountId', (): void => {
testDecode('hex', '0x0102030405060708010203040506070801020304050607080102030405060708', '5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF');
testDecode('string', '5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF', '5C62W7ELLAAfix9LYrcx5smtcffbhvThkM5x7xfMeYXCtGwF');
testDecode(
'U8a',
new U8a(registry, [
'Raw',
new Raw(registry, [
1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8
]),
+4 -2
View File
@@ -93,8 +93,10 @@ export default class Call extends Struct implements IMethod {
}
private static decodeCallViaU8a (registry: Registry, value: Uint8Array, _meta?: FunctionMetadataLatest): DecodedMethod {
// The first 2 bytes are the callIndex
const callIndex = value.subarray(0, 2);
// We need 2 bytes for the callIndex
const callIndex = new Uint8Array(2);
callIndex.set(value.subarray(0, 2), 0);
// Find metadata with callIndex
const meta = _meta || registry.findMetaCall(callIndex).meta;
+2 -2
View File
@@ -4,7 +4,7 @@
import { CodecTo } from '../types';
import { TypeRegistry } from '../codec/create';
import U8a from '../codec/U8a';
import Raw from '../codec/Raw';
import Text from './Text';
describe('Text', (): void => {
@@ -19,7 +19,7 @@ describe('Text', (): void => {
testDecode('string', 'foo', 'foo');
testDecode('Text', new Text(registry, 'foo'), 'foo');
testDecode('Uint8Array', Uint8Array.from([12, 102, 111, 111]), 'foo');
testDecode('U8a', new U8a(registry, Uint8Array.from([12, 102, 111, 111])), 'foo');
testDecode('Raw', new Raw(registry, Uint8Array.from([102, 111, 111])), 'foo'); // no length
testDecode('object with `toString()`', { toString (): string { return 'foo'; } }, 'foo');
testDecode('hex input value', new Text(registry, '0x12345678'), '0x12345678', 'toHex');
});
+7
View File
@@ -9,6 +9,7 @@ import { blake2AsU8a } from '@polkadot/util-crypto';
import { createType } from '../codec/create';
import Compact from '../codec/Compact';
import Raw from '../codec/Raw';
/**
* @name Text
@@ -37,6 +38,12 @@ export default class Text extends String implements Codec {
return '';
}
// for Raw, the internal buffer does not have an internal length
// (the same applies in e.g. Bytes, where length is added at encoding-time)
if (value instanceof Raw) {
return u8aToString(value);
}
const [offset, length] = Compact.decodeU8a(value);
const total = offset + length.toNumber();
-1
View File
@@ -10,7 +10,6 @@
*/
export { default as bool } from './Bool';
export { default as Bytes } from './Bytes';
export { default as Data } from './Data';
export { default as H160 } from './H160';
export { default as H256 } from './H256';
export { default as H512 } from './H512';
@@ -4,8 +4,9 @@
import fs from 'fs';
import Raw from '../../codec/Raw';
import * as defaultDefinitions from '../../interfaces/definitions';
import * as primitiveClasses from '../../primitive';
import * as defaultPrimitives from '../../primitive';
import {
createImportCode, createImports,
FOOTER,
@@ -15,6 +16,11 @@ import {
setImports
} from '../util';
const primitiveClasses = {
...defaultPrimitives,
Raw
};
export function generateInterfaceRegistry (importDefinitions: { [importPath: string]: object }, output: string): void {
console.log(`Writing ${output}`);
@@ -116,10 +116,10 @@ export function formatType (definitions: object, type: string | TypeDef, imports
}
case TypeDefInfo.VecFixed: {
if ((typeDef.ext as TypeDefExtVecFixed).type === 'u8') {
setImports(definitions, imports, ['U8a']);
setImports(definitions, imports, ['Raw']);
// `[u8, 32]` gets transformed into U8a
return 'U8a';
// `[u8, 32]` gets transformed into Raw
return 'Raw';
}
setImports(definitions, imports, ['Vec']);
return formatVec(formatType(definitions, (typeDef.ext as TypeDefExtVecFixed).type, imports));
+341 -368
View File
File diff suppressed because it is too large Load Diff