Compare commits

...
22 Commits
Author SHA1 Message Date
Github Actions f7c968b7a6 [CI Skip] release/stable 2.9.1
skip-checks: true
2020-11-30 11:25:01 +00:00
Jaco Greeff c1b7660122 2.9 (#2891) 2020-11-30 12:16:29 +01:00
Github Actions 811a2291ed [CI Skip] release/beta 2.8.3-5
skip-checks: true
2020-11-29 15:16:18 +00:00
Jaco Greeff 90cc148383 Correct hasIdentity parentId extraction (#2884) 2020-11-29 16:08:39 +01:00
Github Actions b652bdc2de [CI Skip] release/beta 2.8.3-4
skip-checks: true
2020-11-29 14:24:26 +00:00
Jaco Greeff f6942cc0f0 Extract identity-only derive from accounts.info (#2882)
* Extract identity-only derive from accounts.info

* Add hasIdentity

* hasIdentityMulti
2020-11-29 15:16:54 +01:00
Github Actions 8e852db87c [CI Skip] release/beta 2.8.3-3
skip-checks: true
2020-11-29 11:49:15 +00:00
Jordan 75f97bb1ff Allow typegen for custom RPCs (#2876)
* Allow typegen for custom RPCs

* It runs

* fix lint

* Remove unused metadata arg
2020-11-29 12:42:42 +01:00
Github Actions c8d7e971bc [CI Skip] release/beta 2.8.3-2
skip-checks: true
2020-11-28 12:05:18 +00:00
Jaco Greeff 09aa046ab4 Remove send queue, always require connection (#2881)
* Remove send queue, always require connection

* Adjust tests for non-queued
2020-11-28 12:57:24 +01:00
Github Actions 25e29d9565 [CI Skip] release/beta 2.8.3-1
skip-checks: true
2020-11-28 11:32:57 +00:00
Jaco Greeff c396b963ee Version bump (pre) (#2880) 2020-11-28 12:25:56 +01:00
Github Actions 46be42705b [CI Skip] release/stable 2.8.2
skip-checks: true
2020-11-28 11:09:03 +00:00
Jaco Greeff d65eb7a27f Raw slice with from (like subarray) (#2879)
* Raw slice with from (like subarray)

* Dep bumps

* 2.8.2

* re-use toU8a()

* Uint8Array.from

* slice on derived comment
2020-11-28 12:00:29 +01:00
Github Actions a1a73cbf01 [CI Skip] release/beta 2.8.2-3
skip-checks: true
2020-11-26 10:41:05 +00:00
Jaco Greeff 72e03138e8 Fix 0-259 for node 2020-11-26 11:33:32 +01:00
Github Actions b0e7440ca6 [CI Skip] release/beta 2.8.2-2
skip-checks: true
2020-11-26 10:09:35 +00:00
Jaco Greeff 4847988a94 Types for Substrate node (MultiAddress) (#2875) 2020-11-26 11:02:31 +01:00
Github Actions a58be22764 [CI Skip] release/beta 2.8.2-1
skip-checks: true
2020-11-25 12:15:04 +00:00
Jaco Greeff f6af257051 derive.staking.electedInfo also contains current (#2874) 2020-11-25 13:08:17 +01:00
Github Actions 790e0ebdcf [CI Skip] release/beta 2.8.2-0
skip-checks: true
2020-11-24 12:22:26 +00:00
Jaco Greeff 1db2cfbedf Bump deps (#2872) 2020-11-24 13:13:12 +01:00
31 changed files with 614 additions and 588 deletions
+1 -1
View File
@@ -4,4 +4,4 @@
1.11.2
1.12.2
1.17.2
1.31.2
1.31.22.8.2
+19
View File
@@ -1,5 +1,24 @@
# CHANGELOG
## 2.9.1 Nov 30, 2020
Upgrade priority: Low. No major changes when on at least 2.8.2. Users encouraged to upgrade to at least that patch.
- **Breaking change** The API will now not attempt to queue calls made while not connected and send on connection. Rather when making a call and the RPC node is not connected, an error will be thrown.
Contributed:
- Add typegen capability for custom RPCs (Thanks to https://github.com/holygits)
Changes:
- Remove rpc-core send queue, only allow sends while connected
- Adjust staking derive for `electedInfo` to contain details of current validators
- Extract identity-only derive from `accounts.info` for simpler reusability
- Add types for Substrate master node (to allow for consistent swapping to `MultiAddress`)
- Adjust `Bytes` with `.slice` to be consistent for `Uint8array` extensions (already released in 2.8.2 as a bugfix)
## 2.8.1 Nov 23, 2020
Upgrade priority: Low. Recommended if using Substrate master with new `MultiAddress`.
+4 -4
View File
@@ -7,7 +7,7 @@
"packages/*"
],
"resolutions": {
"typescript": "^4.0.5"
"typescript": "^4.1.2"
},
"scripts": {
"build": "yarn build:interfaces && polkadot-dev-build-ts && (cd packages/typegen && copyfiles scripts/* build)",
@@ -23,14 +23,14 @@
"test:watch": "polkadot-dev-run-test --watch"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/core": "^7.12.8",
"@babel/register": "^7.12.1",
"@babel/runtime": "^7.12.5",
"@polkadot/dev": "^0.60.3",
"@polkadot/dev": "^0.60.5",
"@polkadot/ts": "^0.3.55",
"@polkadot/typegen": "workspace:packages/typegen",
"@types/jest": "^26.0.15",
"copyfiles": "^2.4.0"
},
"version": "2.8.1"
"version": "2.9.1"
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-contract",
"version": "2.8.1",
"version": "2.9.1",
"description": "Interfaces for interacting with contracts and contract ABIs",
"main": "index.js",
"sideEffects": false,
@@ -17,8 +17,8 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/api": "2.8.1",
"@polkadot/types": "2.8.1",
"@polkadot/api": "2.9.1",
"@polkadot/types": "2.9.1",
"@polkadot/util": "^4.2.1",
"bn.js": "^4.11.9",
"rxjs": "^6.6.3"
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-derive",
"version": "2.8.1",
"version": "2.9.1",
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
"main": "index.js",
"sideEffects": false,
@@ -18,9 +18,9 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/api": "2.8.1",
"@polkadot/rpc-core": "2.8.1",
"@polkadot/types": "2.8.1",
"@polkadot/api": "2.9.1",
"@polkadot/rpc-core": "2.9.1",
"@polkadot/types": "2.9.1",
"@polkadot/util": "^4.2.1",
"@polkadot/util-crypto": "^4.2.1",
"bn.js": "^4.11.9",
@@ -29,6 +29,6 @@
},
"devDependencies": {
"@polkadot/keyring": "^4.2.1",
"@polkadot/rpc-provider": "2.8.1"
"@polkadot/rpc-provider": "2.9.1"
}
}
@@ -12,7 +12,7 @@ import { decodeAddress } from '@polkadot/util-crypto';
import { memo } from '../util';
function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIndex | string | null | undefined): Observable<AccountIdAndIndex> {
function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIndex | Uint8Array | string | null | undefined): Observable<AccountIdAndIndex> {
try {
// yes, this can fail, don't care too much, catch will catch it
const decoded = isU8a(address)
@@ -39,7 +39,7 @@ function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIn
/**
* @name idAndIndex
* @param {(Address | AccountId | AccountIndex | string | null)} address - An accounts address in various formats.
* @param {(Address | AccountId | AccountIndex | Uint8Array | string | null)} address - An accounts address in various formats.
* @description An array containing the [[AccountId]] and [[AccountIndex]] as optional values.
* @example
* <BR>
@@ -50,7 +50,7 @@ function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIn
* });
* ```
*/
export function idAndIndex (instanceId: string, api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable<AccountIdAndIndex> {
return memo(instanceId, (address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> =>
export function idAndIndex (instanceId: string, api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | Uint8Array | string | null) => Observable<AccountIdAndIndex> {
return memo(instanceId, (address?: Address | AccountId | AccountIndex | Uint8Array | string | null): Observable<AccountIdAndIndex> =>
retrieve(api, address));
}
@@ -0,0 +1,126 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, IdentityInfoAdditional, Registration } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveAccountRegistration, DeriveHasIdentity } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Data, Option } from '@polkadot/types';
import { u8aToString } from '@polkadot/util';
import { memo } from '../util';
const UNDEF_HEX = { toHex: () => undefined };
function dataAsString (data: Data): string | undefined {
return data.isRaw
? u8aToString(data.asRaw.toU8a(true))
: data.isNone
? undefined
: data.toHex();
}
function extractOther (additional: IdentityInfoAdditional[]): Record<string, string> {
return additional.reduce((other: Record<string, string>, [_key, _value]): Record<string, string> => {
const key = dataAsString(_key);
const value = dataAsString(_value);
if (key && value) {
other[key] = value;
}
return other;
}, {});
}
function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [AccountId, Data]): DeriveAccountRegistration {
if (!identityOfOpt?.isSome) {
return { judgements: [] };
}
const { info, judgements } = identityOfOpt.unwrap();
const topDisplay = dataAsString(info.display);
return {
display: (superOf && dataAsString(superOf[1])) || topDisplay,
displayParent: superOf && topDisplay,
email: dataAsString(info.email),
image: dataAsString(info.image),
judgements,
legal: dataAsString(info.legal),
other: extractOther(info.additional),
parent: superOf && superOf[0],
pgp: info.pgpFingerprint.unwrapOr(UNDEF_HEX).toHex(),
riot: dataAsString(info.riot),
twitter: dataAsString(info.twitter),
web: dataAsString(info.web)
};
}
function getParent (api: ApiInterfaceRx, identityOfOpt: Option<Registration> | undefined, superOfOpt: Option<ITuple<[AccountId, Data]>> | undefined): Observable<[Option<Registration> | undefined, [AccountId, Data] | undefined]> {
if (identityOfOpt?.isSome) {
// this identity has something set
return of([identityOfOpt, undefined]);
} else if (superOfOpt?.isSome) {
const superOf = superOfOpt.unwrap();
// we have a super
return combineLatest([
api.query.identity.identityOf<Option<Registration>>(superOf[0]),
of(superOf)
]);
}
// nothing of value returned
return of([undefined, undefined]);
}
export function _identityBase (instanceId: string, api: ApiInterfaceRx): (accountId?: AccountId | Uint8Array | string) => Observable<[Option<Registration> | undefined, Option<ITuple<[AccountId, Data]>> | undefined]> {
return memo(instanceId, (accountId?: AccountId | Uint8Array | string): Observable<[Option<Registration> | undefined, Option<ITuple<[AccountId, Data]>> | undefined]> =>
accountId && api.query.identity?.identityOf
? api.queryMulti<[Option<Registration>, Option<ITuple<[AccountId, Data]>>]>([
[api.query.identity.identityOf, accountId],
[api.query.identity.superOf, accountId]
])
: of([undefined, undefined])
);
}
/**
* @name identity
* @description Returns identity info for an account
*/
export function identity (instanceId: string, api: ApiInterfaceRx): (accountId?: AccountId | Uint8Array | string) => Observable<DeriveAccountRegistration> {
return memo(instanceId, (accountId?: AccountId | Uint8Array | string): Observable<DeriveAccountRegistration> =>
api.derive.accounts._identityBase(accountId).pipe(
switchMap(([identityOfOpt, superOfOpt]) => getParent(api, identityOfOpt, superOfOpt)),
map(([identityOfOpt, superOf]) => extractIdentity(identityOfOpt, superOf))
)
);
}
export function hasIdentity (instanceId: string, api: ApiInterfaceRx): (accountId: AccountId | Uint8Array | string) => Observable<DeriveHasIdentity> {
return memo(instanceId, (accountId: AccountId | Uint8Array | string): Observable<DeriveHasIdentity> =>
api.derive.accounts._identityBase(accountId).pipe(
map(([identityOfOpt, superOfOpt]: [Option<Registration> | undefined, Option<ITuple<[AccountId, Data]>> | undefined]): DeriveHasIdentity => {
const parentId = superOfOpt && superOfOpt.isSome
? superOfOpt.unwrap()[0].toString()
: null;
const hasIdentity = !!parentId || !!(identityOfOpt && identityOfOpt.isSome);
return { hasIdentity, parentId };
})
)
);
}
export function hasIdentityMulti (instanceId: string, api: ApiInterfaceRx): (accountIds: (AccountId | Uint8Array | string)[]) => Observable<DeriveHasIdentity[]> {
return memo(instanceId, (accountIds: (AccountId | Uint8Array | string)[]): Observable<DeriveHasIdentity[]> =>
combineLatest(
accountIds.map((accountId) => api.derive.accounts.hasIdentity(accountId))
)
);
}
@@ -5,6 +5,7 @@ export * from './accountId';
export * from './flags';
export * from './idAndIndex';
export * from './idToIndex';
export * from './identity';
export * from './indexToId';
export * from './indexes';
export * from './info';
+5 -84
View File
@@ -2,27 +2,17 @@
// SPDX-License-Identifier: Apache-2.0
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, AccountIndex, Address, Balance, IdentityInfoAdditional, Registration } from '@polkadot/types/interfaces';
import { AccountId, AccountIndex, Address, Balance } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveAccountInfo, DeriveAccountRegistration } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Bytes, Data, Option, u32 } from '@polkadot/types';
import { Bytes, Option, u32 } from '@polkadot/types';
import { u8aToString } from '@polkadot/util';
import { memo } from '../util';
const UNDEF_HEX = { toHex: () => undefined };
function dataAsString (data: Data): string | undefined {
return data.isRaw
? u8aToString(data.asRaw.toU8a(true))
: data.isNone
? undefined
: data.toHex();
}
function retrieveNick (api: ApiInterfaceRx, accountId?: AccountId): Observable<string | undefined> {
return ((
accountId && api.query.nicks?.nameOf
@@ -37,86 +27,17 @@ function retrieveNick (api: ApiInterfaceRx, accountId?: AccountId): Observable<s
);
}
function extractOther (additional: IdentityInfoAdditional[]): Record<string, string> {
return additional.reduce((other: Record<string, string>, [_key, _value]): Record<string, string> => {
const key = dataAsString(_key);
const value = dataAsString(_value);
if (key && value) {
other[key] = value;
}
return other;
}, {});
}
function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [AccountId, Data]): DeriveAccountRegistration {
if (!identityOfOpt?.isSome) {
return { judgements: [] };
}
const { info, judgements } = identityOfOpt.unwrap();
const topDisplay = dataAsString(info.display);
return {
display: (superOf && dataAsString(superOf[1])) || topDisplay,
displayParent: superOf && topDisplay,
email: dataAsString(info.email),
image: dataAsString(info.image),
judgements,
legal: dataAsString(info.legal),
other: extractOther(info.additional),
parent: superOf && superOf[0],
pgp: info.pgpFingerprint.unwrapOr(UNDEF_HEX).toHex(),
riot: dataAsString(info.riot),
twitter: dataAsString(info.twitter),
web: dataAsString(info.web)
};
}
function retrieveIdentity (api: ApiInterfaceRx, accountId?: AccountId): Observable<DeriveAccountRegistration> {
return ((
accountId && api.query.identity?.identityOf
? api.queryMulti([
[api.query.identity.identityOf, accountId],
[api.query.identity.superOf, accountId]
])
: of([undefined, undefined])
) as Observable<[Option<Registration> | undefined, Option<ITuple<[AccountId, Data]>> | undefined]>).pipe(
switchMap(([identityOfOpt, superOfOpt]): Observable<[Option<Registration> | undefined, [AccountId, Data] | undefined]> => {
if (identityOfOpt?.isSome) {
// this identity has something set
return of([identityOfOpt, undefined]);
} else if (superOfOpt?.isSome) {
const superOf = superOfOpt.unwrap();
// we have a super
return combineLatest([
api.query.identity.identityOf<Option<Registration>>(superOf[0]),
of(superOf)
]);
}
// nothing of value returned
return of([undefined, undefined]);
}),
map(([identityOfOpt, superOf]): DeriveAccountRegistration =>
extractIdentity(identityOfOpt, superOf)
)
);
}
/**
* @name info
* @description Returns aux. info with regards to an account, current that includes the accountId, accountIndex and nickname
*/
export function info (instanceId: string, api: ApiInterfaceRx): (address?: AccountIndex | AccountId | Address | string | null) => Observable<DeriveAccountInfo> {
return memo(instanceId, (address?: AccountIndex | AccountId | Address | string | null): Observable<DeriveAccountInfo> =>
export function info (instanceId: string, api: ApiInterfaceRx): (address?: AccountIndex | AccountId | Address | Uint8Array | string | null) => Observable<DeriveAccountInfo> {
return memo(instanceId, (address?: AccountIndex | AccountId | Address | Uint8Array | string | null): Observable<DeriveAccountInfo> =>
api.derive.accounts.idAndIndex(address).pipe(
switchMap(([accountId, accountIndex]): Observable<[Partial<DeriveAccountInfo>, DeriveAccountRegistration, string?]> =>
combineLatest([
of({ accountId, accountIndex }),
retrieveIdentity(api, accountId),
api.derive.accounts.identity(accountId),
retrieveNick(api, accountId)
])
),
@@ -35,3 +35,8 @@ export interface DeriveAccountInfo {
identity: DeriveAccountRegistration;
nickname?: string;
}
export interface DeriveHasIdentity {
hasIdentity: boolean;
parentId: string | null;
}
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId } from '@polkadot/types/interfaces';
import { DeriveStakingElected } from '../types';
import { Observable } from 'rxjs';
@@ -9,14 +10,19 @@ import { map, switchMap } from 'rxjs/operators';
import { memo } from '../util';
function combineAccounts (nextElected: AccountId[], validators: AccountId[]): AccountId[] {
return [...nextElected].concat(...validators.filter((v) => !nextElected.find((n) => n.eq(v))));
}
export function electedInfo (instanceId: string, api: ApiInterfaceRx): () => Observable<DeriveStakingElected> {
return memo(instanceId, (): Observable<DeriveStakingElected> =>
api.derive.staking.validators().pipe(
switchMap(({ nextElected }): Observable<DeriveStakingElected> =>
api.derive.staking.queryMulti(nextElected).pipe(
switchMap(({ nextElected, validators }): Observable<DeriveStakingElected> =>
api.derive.staking.queryMulti(combineAccounts(nextElected, validators)).pipe(
map((info): DeriveStakingElected => ({
info,
nextElected
nextElected,
validators
}))
)
)
+2 -1
View File
@@ -120,8 +120,9 @@ export interface DeriveStakingQuery extends DeriveStakingStash {
}
export interface DeriveStakingElected {
nextElected: AccountId[];
info: DeriveStakingQuery[];
nextElected: AccountId[];
validators: AccountId[];
}
export interface DeriveStakingWaiting {
@@ -30,7 +30,6 @@ export function validators (instanceId: string, api: ApiInterfaceRx): () => Obse
return memo(instanceId, (): Observable<DeriveStakingValidators> =>
// Sadly the node-template is (for some obscure reason) not comprehensive, so while the derive works
// in all actual real-world deployed chains, it does create some confusion for limited template chains
// NOTE: Not doing multi queries here, since we have validators as a single in the derived newHead
combineLatest([
api.query.session
? api.query.session.validators()
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api",
"version": "2.8.1",
"version": "2.9.1",
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
"main": "index.js",
"sideEffects": false,
@@ -17,13 +17,13 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/api-derive": "2.8.1",
"@polkadot/api-derive": "2.9.1",
"@polkadot/keyring": "^4.2.1",
"@polkadot/metadata": "2.8.1",
"@polkadot/rpc-core": "2.8.1",
"@polkadot/rpc-provider": "2.8.1",
"@polkadot/types": "2.8.1",
"@polkadot/types-known": "2.8.1",
"@polkadot/metadata": "2.9.1",
"@polkadot/rpc-core": "2.9.1",
"@polkadot/rpc-provider": "2.9.1",
"@polkadot/types": "2.9.1",
"@polkadot/types-known": "2.9.1",
"@polkadot/util": "^4.2.1",
"@polkadot/util-crypto": "^4.2.1",
"bn.js": "^4.11.9",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/metadata",
"version": "2.8.1",
"version": "2.9.1",
"description": "Helpers to extract information from runtime metadata",
"main": "index.js",
"sideEffects": false,
@@ -16,8 +16,8 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-metadata#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/types": "2.8.1",
"@polkadot/types-known": "2.8.1",
"@polkadot/types": "2.9.1",
"@polkadot/types-known": "2.9.1",
"@polkadot/util": "^4.2.1",
"@polkadot/util-crypto": "^4.2.1",
"bn.js": "^4.11.9"
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/rpc-core",
"version": "2.8.1",
"version": "2.9.1",
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
"main": "index.js",
"sideEffects": false,
@@ -17,9 +17,9 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-core#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/metadata": "2.8.1",
"@polkadot/rpc-provider": "2.8.1",
"@polkadot/types": "2.8.1",
"@polkadot/metadata": "2.9.1",
"@polkadot/rpc-provider": "2.9.1",
"@polkadot/types": "2.9.1",
"@polkadot/util": "^4.2.1",
"memoizee": "^0.4.14",
"rxjs": "^6.6.3"
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/rpc-provider",
"version": "2.8.1",
"version": "2.9.1",
"description": "Transport providers for the API",
"main": "index.js",
"sideEffects": false,
@@ -17,7 +17,7 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/types": "2.8.1",
"@polkadot/types": "2.9.1",
"@polkadot/util": "^4.2.1",
"@polkadot/util-crypto": "^4.2.1",
"@polkadot/x-fetch": "^4.2.1",
@@ -27,7 +27,7 @@
},
"devDependencies": {
"@polkadot/keyring": "^4.2.1",
"@polkadot/metadata": "2.8.1",
"@polkadot/metadata": "2.9.1",
"mock-socket": "^9.0.3",
"nock": "^13.0.5"
}
+28 -35
View File
@@ -71,7 +71,7 @@ export class WsProvider implements ProviderInterface {
readonly #handlers: Record<string, WsStateAwaiting> = {};
readonly #queued: Record<string, string> = {};
readonly #isReadyPromise: Promise<WsProvider>;
readonly #waitingForId: Record<string, JsonRpcResponse> = {};
@@ -113,6 +113,12 @@ export class WsProvider implements ProviderInterface {
// does not throw
});
}
this.#isReadyPromise = new Promise((resolve): void => {
this.#eventemitter.once('connected', (): void => {
resolve(this);
});
});
}
/**
@@ -130,6 +136,13 @@ export class WsProvider implements ProviderInterface {
return this.#isConnected;
}
/**
* @description Promise that resolves the first time we are connected and loaded
*/
public get isReady (): Promise<WsProvider> {
return this.#isReadyPromise;
}
/**
* @description Returns a clone of the object
*/
@@ -225,12 +238,14 @@ export class WsProvider implements ProviderInterface {
/**
* @summary Send JSON data using WebSockets to configured HTTP Endpoint or queue.
* @param method The RPC methods to execute
* @param params Encoded paramaters as appliucable for the method
* @param params Encoded parameters as applicable for the method
* @param subscription Subscription details (internally used)
*/
public send (method: string, params: any[], subscription?: SubscriptionHandler): Promise<any> {
return new Promise((resolve, reject): void => {
try {
assert(this.isConnected && !isNull(this.#websocket), 'WebSocket is not connected');
const json = this.#coder.encodeJson(method, params);
const id = this.#coder.getId();
@@ -240,7 +255,7 @@ export class WsProvider implements ProviderInterface {
: resolve(result);
};
l.debug((): string[] => ['calling', method, json]);
l.debug(() => ['calling', method, json]);
this.#handlers[id] = {
callback,
@@ -249,11 +264,7 @@ export class WsProvider implements ProviderInterface {
subscription
};
if (this.isConnected && !isNull(this.#websocket)) {
this.#websocket.send(json);
} else {
this.#queued[id] = json;
}
this.#websocket.send(json);
} catch (error) {
reject(error);
}
@@ -300,7 +311,7 @@ export class WsProvider implements ProviderInterface {
// a slight complication in solving - since we cannot rely on the send id, but rather
// need to find the actual subscription id to map it
if (isUndefined(this.#subscriptions[subscription])) {
l.debug((): string => `Unable to find active subscription=${subscription}`);
l.debug(() => `Unable to find active subscription=${subscription}`);
return false;
}
@@ -334,15 +345,14 @@ export class WsProvider implements ProviderInterface {
}
#onSocketError = (error: Event): void => {
l.debug((): any => ['socket error', error]);
l.debug(() => ['socket error', error]);
this.#emit('error', error);
}
#onSocketMessage = (message: MessageEvent): void => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
#onSocketMessage = (message: MessageEvent<string>): void => {
l.debug(() => ['received', message.data]);
const response = JSON.parse(message.data as string) as JsonRpcResponse;
const response = JSON.parse(message.data) as JsonRpcResponse;
return isUndefined(response.method)
? this.#onSocketMessageResult(response)
@@ -353,7 +363,7 @@ export class WsProvider implements ProviderInterface {
const handler = this.#handlers[response.id];
if (!handler) {
l.debug((): string => `Unable to find handler for id=${response.id}`);
l.debug(() => `Unable to find handler for id=${response.id}`);
return;
}
@@ -396,7 +406,7 @@ export class WsProvider implements ProviderInterface {
// store the JSON, we could have out-of-order subid coming in
this.#waitingForId[subId] = response;
l.debug((): string => `Unable to find handler for subscription=${subId}`);
l.debug(() => `Unable to find handler for subscription=${subId}`);
return;
}
@@ -416,12 +426,11 @@ export class WsProvider implements ProviderInterface {
#onSocketOpen = (): boolean => {
assert(!isNull(this.#websocket), 'WebSocket cannot be null in onOpen');
l.debug((): any[] => ['connected to', this.#endpoints[this.#endpointIndex]]);
l.debug(() => ['connected to', this.#endpoints[this.#endpointIndex]]);
this.#isConnected = true;
this.#emit('connected');
this.#sendQueue();
this.#resubscribe();
return true;
@@ -432,8 +441,7 @@ export class WsProvider implements ProviderInterface {
this.#subscriptions = {};
// eslint-disable-next-line @typescript-eslint/no-misused-promises
Object.keys(subscriptions).forEach(async (id): Promise<void> => {
Promise.all(Object.keys(subscriptions).map(async (id): Promise<void> => {
const { callback, method, params, type } = subscriptions[id];
// only re-create subscriptions which are not in author (only area where
@@ -448,21 +456,6 @@ export class WsProvider implements ProviderInterface {
} catch (error) {
l.error(error);
}
});
}
#sendQueue = (): void => {
Object.keys(this.#queued).forEach((id): void => {
try {
// we have done the websocket check in onSocketOpen, if an issue, will catch it
(this.#websocket as WebSocket).send(
this.#queued[id]
);
delete this.#queued[id];
} catch (error) {
l.error(error);
}
});
})).catch(l.error);
}
}
@@ -1,43 +0,0 @@
// Copyright 2017-2020 @polkadot/rpc-provider authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { Mock } from './../mock/types';
import { mockWs, TEST_WS_URL } from '../../test/mockWs';
import { WsProvider } from './';
let ws: WsProvider;
let mock: Mock;
function createWs (requests: any[], autoConnect: number | undefined = 1000): WsProvider {
mock = mockWs(requests);
ws = new WsProvider(TEST_WS_URL, autoConnect);
return ws;
}
describe('onOpen', (): void => {
afterEach((): void => {
if (mock) {
mock.done();
}
});
it('sends messages when connected', (): Promise<void> => {
const ws = createWs([{
id: 1,
method: 'test_queue',
reply: {
result: 'ok'
}
}], 0);
const sendPromise = ws.send('test_queue', []);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
ws.connect();
return sendPromise.then((result): void => {
expect(result).toEqual('ok');
});
});
});
+33 -25
View File
@@ -17,10 +17,10 @@ function createMock (requests: any[]): void {
mock = mockWs(requests);
}
function createWs (autoConnect = 1000): WsProvider {
function createWs (autoConnect = 1000): Promise<WsProvider> {
provider = new WsProvider(TEST_WS_URL, autoConnect);
return provider;
return provider.isReady;
}
describe('send', (): void => {
@@ -47,11 +47,13 @@ describe('send', (): void => {
}
}]);
return createWs()
.send('test_encoding', [{ error: 'send error' }])
.catch((error): void => {
expect((error as Error).message).toEqual('send error');
});
return createWs().then((ws) =>
ws
.send('test_encoding', [{ error: 'send error' }])
.catch((error): void => {
expect((error as Error).message).toEqual('send error');
})
);
});
it('passes the body through correctly', (): Promise<void> => {
@@ -63,14 +65,16 @@ describe('send', (): void => {
}
}]);
return createWs()
.send('test_body', ['param'])
.then((): void => {
expect(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(mock.body as any).test_body
).toEqual('{"id":1,"jsonrpc":"2.0","method":"test_body","params":["param"]}');
});
return createWs().then((ws) =>
ws
.send('test_body', ['param'])
.then((): void => {
expect(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(mock.body as any).test_body
).toEqual('{"id":1,"jsonrpc":"2.0","method":"test_body","params":["param"]}');
})
);
});
it('throws error when !response.ok', (): Promise<any> => {
@@ -82,11 +86,13 @@ describe('send', (): void => {
id: 1
}]);
return createWs()
.send('test_error', [])
.catch((error): void => {
expect((error as Error).message).toMatch(/666: error/);
});
return createWs().then((ws) =>
ws
.send('test_error', [])
.catch((error): void => {
expect((error as Error).message).toMatch(/666: error/);
})
);
});
it('adds subscriptions', (): Promise<void> => {
@@ -98,10 +104,12 @@ describe('send', (): void => {
}
}]);
return createWs()
.send('test_sub', [])
.then((id): void => {
expect(id).toEqual(1);
});
return createWs().then((ws) =>
ws
.send('test_sub', [])
.then((id): void => {
expect(id).toEqual(1);
})
);
});
});
+11 -9
View File
@@ -17,10 +17,10 @@ function createMock (requests: any[]): void {
mock = mockWs(requests);
}
function createWs (autoConnect = 1000): WsProvider {
function createWs (autoConnect = 1000): Promise<WsProvider> {
ws = new WsProvider(TEST_WS_URL, autoConnect);
return ws;
return ws.isReady;
}
describe('subscribe', (): void => {
@@ -47,12 +47,14 @@ describe('subscribe', (): void => {
}
}]);
return createWs()
.subscribe('type', 'test_sub', [], (cb): void => {
expect(cb).toEqual(expect.anything());
})
.then((id): void => {
expect(id).toEqual(1);
});
return createWs().then((ws) =>
ws
.subscribe('type', 'test_sub', [], (cb): void => {
expect(cb).toEqual(expect.anything());
})
.then((id): void => {
expect(id).toEqual(1);
})
);
});
});
@@ -17,10 +17,10 @@ function createMock (requests: any): void {
mock = mockWs(requests);
}
function createWs (autoConnect = 1000): WsProvider {
function createWs (autoConnect = 1000): Promise<WsProvider> {
ws = new WsProvider(TEST_WS_URL, autoConnect);
return ws;
return ws.isReady;
}
describe('subscribe', (): void => {
@@ -56,15 +56,15 @@ describe('subscribe', (): void => {
}
]);
const ws = createWs();
return ws
.subscribe('test', 'subscribe_test', [], (cb): void => {
expect(cb).toEqual(expect.anything());
})
.then((id): Promise<boolean> => {
return ws.unsubscribe('test', 'subscribe_test', id);
});
return createWs().then((ws) =>
ws
.subscribe('test', 'subscribe_test', [], (cb): void => {
expect(cb).toEqual(expect.anything());
})
.then((id): Promise<boolean> => {
return ws.unsubscribe('test', 'subscribe_test', id);
})
);
});
it('fails when sub not found', (): Promise<void> => {
@@ -76,17 +76,17 @@ describe('subscribe', (): void => {
}
}]);
const ws = createWs();
return ws
.subscribe('test', 'subscribe_test', [], (cb): void => {
expect(cb).toEqual(expect.anything());
})
.then((): Promise<boolean> => {
return ws.unsubscribe('test', 'subscribe_test', 111);
})
.then((result): void => {
expect(result).toBe(false);
});
return createWs().then((ws) =>
ws
.subscribe('test', 'subscribe_test', [], (cb): void => {
expect(cb).toEqual(expect.anything());
})
.then((): Promise<boolean> => {
return ws.unsubscribe('test', 'subscribe_test', 111);
})
.then((result): void => {
expect(result).toBe(false);
})
);
});
});
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/typegen",
"version": "2.8.1",
"version": "2.9.1",
"description": "Type generation scripts",
"main": "index.js",
"sideEffects": false,
@@ -23,20 +23,20 @@
"bugs": "https://github.com/polkadot-js/api/issues",
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/typegen#readme",
"dependencies": {
"@babel/core": "^7.12.3",
"@babel/core": "^7.12.8",
"@babel/register": "^7.12.1",
"@babel/runtime": "^7.12.5",
"@polkadot/api": "2.8.1",
"@polkadot/metadata": "2.8.1",
"@polkadot/rpc-provider": "2.8.1",
"@polkadot/types": "2.8.1",
"@polkadot/api": "2.9.1",
"@polkadot/metadata": "2.9.1",
"@polkadot/rpc-provider": "2.9.1",
"@polkadot/types": "2.9.1",
"@polkadot/util": "^4.2.1",
"handlebars": "^4.7.6",
"websocket": "^1.0.32",
"yargs": "^16.1.0"
"yargs": "^16.1.1"
},
"devDependencies": {
"@types/websocket": "^1.0.1",
"@types/yargs": "^15.0.9"
"@types/yargs": "^15.0.10"
}
}
+3 -2
View File
@@ -6,7 +6,7 @@ import yargs from 'yargs';
import { formatNumber } from '@polkadot/util';
import WS from '@polkadot/x-ws';
import { generateDefaultConsts, generateDefaultQuery, generateDefaultTx } from './generate';
import { generateDefaultConsts, generateDefaultQuery, generateDefaultRpc, generateDefaultTx } from './generate';
import { HEADER, writeFile } from './util';
function generate (metaHex: string, pkg: string | undefined, output: string, isStrict?: boolean): void {
@@ -19,6 +19,7 @@ function generate (metaHex: string, pkg: string | undefined, output: string, isS
generateDefaultConsts(path.join(process.cwd(), output, 'augment-api-consts.ts'), metaHex, extraTypes, isStrict);
generateDefaultQuery(path.join(process.cwd(), output, 'augment-api-query.ts'), metaHex, extraTypes, isStrict);
generateDefaultRpc(path.join(process.cwd(), output, 'augment-api-rpc.ts'), extraTypes);
generateDefaultTx(path.join(process.cwd(), output, 'augment-api-tx.ts'), metaHex, extraTypes, isStrict);
writeFile(path.join(process.cwd(), output, 'augment-api.ts'), (): string =>
@@ -26,7 +27,7 @@ function generate (metaHex: string, pkg: string | undefined, output: string, isS
HEADER('chain'),
...[
'@polkadot/api/augment/rpc',
...['consts', 'query', 'tx'].filter((key) => !!key).map((key) => `./augment-api-${key}`)
...['consts', 'query', 'tx', 'rpc'].filter((key) => !!key).map((key) => `./augment-api-${key}`)
].map((path) => `import '${path}';\n`)
].join('')
);
+14 -8
View File
@@ -7,7 +7,7 @@ import { TypeRegistry } from '@polkadot/types/create';
import { Definitions } from '@polkadot/types/types';
import * as defaultDefinitions from '@polkadot/types/interfaces/definitions';
import { createImports, getSimilarTypes, formatType, readTemplate, setImports, writeFile } from '../util';
import { createImports, getSimilarTypes, formatType, readTemplate, registerDefinitions, setImports, writeFile } from '../util';
const StorageKeyTye = 'StorageKey | string | Uint8Array | any';
@@ -15,12 +15,12 @@ const template = readTemplate('rpc');
const generateRpcTypesTemplate = Handlebars.compile(template);
/** @internal */
export function generateRpcTypes (importDefinitions: { [importPath: string]: Record<string, Definitions> }, dest: string): void {
export function generateRpcTypes (registry: TypeRegistry, importDefinitions: Record<string, Definitions>, dest: string, extraTypes: Record<string, Record<string, { types: Record<string, any> }>> = {}): void {
writeFile(dest, (): string => {
const registry = new TypeRegistry();
const imports = createImports(importDefinitions);
const allTypes: Record<string, Record<string, { types: Record<string, any> }>> = { '@polkadot/types/interfaces': importDefinitions, ...extraTypes };
const imports = createImports(allTypes);
const definitions = imports.definitions as Record<string, Definitions>;
const allDefs = Object.entries(importDefinitions).reduce((defs, [path, obj]) => {
const allDefs = Object.entries(allTypes).reduce((defs, [path, obj]) => {
return Object.entries(obj).reduce((defs, [key, value]) => ({ ...defs, [`${path}/${key}`]: value }), defs);
}, {});
@@ -111,9 +111,15 @@ export function generateRpcTypes (importDefinitions: { [importPath: string]: Rec
});
}
export function generateDefaultRpc (): void {
export function generateDefaultRpc (dest = 'packages/api/src/augment/rpc.ts', extraTypes: Record<string, Record<string, { types: Record<string, any> }>> = {}): void {
const registry = new TypeRegistry();
registerDefinitions(registry, extraTypes);
generateRpcTypes(
{ '@polkadot/types/interfaces': defaultDefinitions },
'packages/api/src/augment/rpc.ts'
registry,
defaultDefinitions,
dest,
extraTypes
);
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/types-known",
"version": "2.8.1",
"version": "2.9.1",
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
"main": "index.js",
"sideEffects": false,
@@ -17,7 +17,7 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types-known#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/types": "2.8.1",
"@polkadot/types": "2.9.1",
"@polkadot/util": "^4.2.1",
"bn.js": "^4.11.9"
},
+2
View File
@@ -5,6 +5,7 @@ import { OverrideVersionedType } from '@polkadot/types/types';
import centrifugeChain from './centrifuge-chain';
import kusama from './kusama';
import node from './node';
import nodeTemplate from './node-template';
import polkadot from './polkadot';
import rococo from './rococo';
@@ -14,6 +15,7 @@ import westend from './westend';
const typesSpec: Record<string, OverrideVersionedType[]> = {
'centrifuge-chain': centrifugeChain,
kusama,
node,
'node-template': nodeTemplate,
polkadot,
rococo,
+26
View File
@@ -0,0 +1,26 @@
// Copyright 2017-2020 @polkadot/types-known authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable sort-keys */
import { OverrideVersionedType } from '@polkadot/types/types';
// these are override types for Polkadot
const versioned: OverrideVersionedType[] = [
{
minmax: [0, 259],
types: {
Address: 'LookupSource',
LookupSource: 'IndicesLookupSource'
}
},
{
minmax: [260, undefined],
types: {
Address: 'MultiAddress',
LookupSource: 'MultiAddress'
}
}
];
export default versioned;
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/types",
"version": "2.8.1",
"version": "2.9.1",
"description": "Implementation of the Parity codec",
"main": "index.js",
"sideEffects": false,
@@ -17,7 +17,7 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types#readme",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@polkadot/metadata": "2.8.1",
"@polkadot/metadata": "2.9.1",
"@polkadot/util": "^4.2.1",
"@polkadot/util-crypto": "^4.2.1",
"@types/bn.js": "^4.11.6",
+12 -1
View File
@@ -95,12 +95,23 @@ export class Raw extends Uint8Array implements IU8a {
return this.eq(decodeU8a(other));
}
/**
* @description Create a new slice from the actual buffer. (compat)
* @param start The position to start at
* @param end The position to end at
*/
public slice (start?: number, end?: number): Uint8Array {
// Like subarray below, we have to follow this approach since we are extending the TypeArray.
// This happens especially when it comes to further extensions, the length may be an override
return Uint8Array.from(this).slice(start, end);
}
/**
* @description Create a new subarray from the actual buffer. (compat)
* @param begin The position to start at
* @param end The position to end at
*/
public subarray (begin: number, end?: number): Uint8Array {
public subarray (begin?: number, end?: number): Uint8Array {
return Uint8Array.from(this).subarray(begin, end);
}
+249 -307
View File
File diff suppressed because it is too large Load Diff