Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f2c3016d7 | ||
|
|
938ace2342 | ||
|
|
e5d2607dff | ||
|
|
50b8db2263 | ||
|
|
91766a6885 | ||
|
|
4b1a9ab9e1 | ||
|
|
9a14c65336 | ||
|
|
4aa66fd4c6 | ||
|
|
3d9c62d538 | ||
|
|
4156eb44ab | ||
|
|
4b2d33693c | ||
|
|
e8b127e177 | ||
|
|
b052b03f31 | ||
|
|
6727e12468 | ||
|
|
c130285651 | ||
|
|
47fc4a2b3c | ||
|
|
97cb408f36 | ||
|
|
dde7c8085a | ||
|
|
8b02fafb99 | ||
|
|
393f46ba4a | ||
|
|
455f5ad834 | ||
|
|
674324e7f9 | ||
|
|
b0dc7cf451 | ||
|
|
cbe1b2b1ce | ||
|
|
4bd2f2fc32 | ||
|
|
053112470d | ||
|
|
acdf27a272 | ||
|
|
f70b32ba76 | ||
|
|
67a3376ef8 | ||
|
|
eb06bb6e93 | ||
|
|
f8f7e92da4 | ||
|
|
d0fd3eca25 | ||
|
|
dac1df35de | ||
|
|
597563d2bb | ||
|
|
f825c7f187 | ||
|
|
2e71a6160e | ||
|
|
c076c37119 | ||
|
|
0e18fdbccc | ||
|
|
c3eebd8fbe | ||
|
|
45786b31da |
@@ -1,3 +1,24 @@
|
|||||||
|
# 1.16.1 May 26, 2020
|
||||||
|
|
||||||
|
- Support for Polkadot CC1 types & signed extensions
|
||||||
|
- Add support for Babe VRF secondary digests (author extraction)
|
||||||
|
- Adjust `Perbill/Permill` `toHuman()` formatting to output percentage
|
||||||
|
- Support for latest Substrate types & metadata
|
||||||
|
- Update to latest TypeScript, eslint & typescript-eslint
|
||||||
|
- `@polkadot/util` 2.11
|
||||||
|
|
||||||
|
# 1.15.1 May 23, 2020
|
||||||
|
|
||||||
|
- Adjust `keyPrefix()` with DoubleMap args (Thanks to https://github.com/KiChjang)
|
||||||
|
- Added `WeightToFeeCoefficient` type (Thanks to https://github.com/danforbes)
|
||||||
|
- Spelling fixes for console logs (Thanks to https://github.com/JoshOrndorff)
|
||||||
|
- Spelling fixes in cookbook (Thanks to https://github.com/pawelnguyen)
|
||||||
|
- Add `transactionVersion` getter in payloads (Thanks to https://github.com/amaurymartiny)
|
||||||
|
- Adjust `stakerRewards` derive ordering for improved on-payout refreshes
|
||||||
|
- Baseline implementation for derive caching infrastructure
|
||||||
|
- Adjust `Multiplier` type to `Fixed128` (as per latest Substrate)
|
||||||
|
- Updated to latest Substrate metadata & add new types
|
||||||
|
|
||||||
# 1.14.1 May 14, 2020
|
# 1.14.1 May 14, 2020
|
||||||
|
|
||||||
- **Important** `DispatchInfo` changed `paysFee` to an enum, if using an older version use, `DispatchInfo: 'DispatchInfoTo244'`
|
- **Important** `DispatchInfo` changed `paysFee` to an enum, if using an older version use, `DispatchInfo: 'DispatchInfoTo244'`
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ signedBlock.block.extrinsics.forEach((ex, index) => {
|
|||||||
|
|
||||||
## How do I extract the block author?
|
## How do I extract the block author?
|
||||||
|
|
||||||
Th block author is encoded inside the consensus logs for the block. To extract, you need to decode the log (which the API does do) and then map the index of the validator to the list of session validators. This extraction is however available on the api derive for new head subscriptions, which returns an extended header with the author populated (assuming that the digest logs are known).
|
The block author is encoded inside the consensus logs for the block. To extract, you need to decode the log (which the API does do) and then map the index of the validator to the list of session validators. This extraction is however available on the api derive for new head subscriptions, which returns an extended header with the author populated (assuming that the digest logs are known).
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// subscribe to all new headers (with extended info)
|
// subscribe to all new headers (with extended info)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable header/header */
|
/* eslint-disable header/header */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
/* eslint-disable @typescript-eslint/unbound-method */
|
||||||
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
|
|
||||||
// Import the API
|
// Import the API
|
||||||
const { ApiPromise } = require('@polkadot/api');
|
const { ApiPromise } = require('@polkadot/api');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable header/header */
|
/* eslint-disable header/header */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
/* eslint-disable @typescript-eslint/unbound-method */
|
||||||
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
|
|
||||||
// Import the API
|
// Import the API
|
||||||
const { ApiPromise } = require('@polkadot/api');
|
const { ApiPromise } = require('@polkadot/api');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable header/header */
|
/* eslint-disable header/header */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
/* eslint-disable @typescript-eslint/unbound-method */
|
||||||
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
|
|
||||||
// Import the API
|
// Import the API
|
||||||
const { ApiPromise } = require('@polkadot/api');
|
const { ApiPromise } = require('@polkadot/api');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable header/header */
|
/* eslint-disable header/header */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
|
|
||||||
// Import the API & Provider and some utility functions
|
// Import the API & Provider and some utility functions
|
||||||
const { ApiPromise } = require('@polkadot/api');
|
const { ApiPromise } = require('@polkadot/api');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable header/header */
|
/* eslint-disable header/header */
|
||||||
/* eslint-disable @typescript-eslint/require-await */
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
/* eslint-disable @typescript-eslint/unbound-method */
|
/* eslint-disable @typescript-eslint/unbound-method */
|
||||||
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
|
|
||||||
// Import the API & Provider and some utility functions
|
// Import the API & Provider and some utility functions
|
||||||
const { ApiPromise, WsProvider } = require('@polkadot/api');
|
const { ApiPromise, WsProvider } = require('@polkadot/api');
|
||||||
|
|||||||
+1
-1
@@ -9,5 +9,5 @@
|
|||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"version": "1.14.1"
|
"version": "1.16.1"
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -7,7 +7,7 @@
|
|||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"typescript": "^3.8.3"
|
"babel-core": "^7.0.0-bridge.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yarn build:interfaces && polkadot-dev-build-ts && (cd packages/typegen && copyfiles scripts/* build)",
|
"build": "yarn build:interfaces && polkadot-dev-build-ts && (cd packages/typegen && copyfiles scripts/* build)",
|
||||||
@@ -27,11 +27,11 @@
|
|||||||
"@babel/core": "^7.9.6",
|
"@babel/core": "^7.9.6",
|
||||||
"@babel/register": "^7.9.0",
|
"@babel/register": "^7.9.0",
|
||||||
"@babel/runtime": "^7.9.6",
|
"@babel/runtime": "^7.9.6",
|
||||||
"@polkadot/dev": "^0.52.19",
|
"@polkadot/dev": "^0.54.1",
|
||||||
"@polkadot/ts": "^0.3.21",
|
"@polkadot/ts": "^0.3.23",
|
||||||
"@polkadot/typegen": "workspace:packages/typegen",
|
"@polkadot/typegen": "workspace:packages/typegen",
|
||||||
"@types/jest": "^25.2.1",
|
"@types/jest": "^25.2.3",
|
||||||
"@vuepress/plugin-search": "^1.4.1",
|
"@vuepress/plugin-search": "^1.5.0",
|
||||||
"copyfiles": "^2.2.0"
|
"copyfiles": "^2.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@polkadot/api-contract",
|
"name": "@polkadot/api-contract",
|
||||||
"version": "1.14.1",
|
"version": "1.16.1",
|
||||||
"description": "Interfaces for interacting with contracts and contract ABIs",
|
"description": "Interfaces for interacting with contracts and contract ABIs",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -27,11 +27,11 @@
|
|||||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
|
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.9.6",
|
"@babel/runtime": "^7.9.6",
|
||||||
"@polkadot/api": "1.14.1",
|
"@polkadot/api": "1.16.1",
|
||||||
"@polkadot/rpc-core": "1.14.1",
|
"@polkadot/rpc-core": "1.16.1",
|
||||||
"@polkadot/types": "1.14.1",
|
"@polkadot/types": "1.16.1",
|
||||||
"@polkadot/util": "^2.10.1",
|
"@polkadot/util": "^2.11.1",
|
||||||
"bn.js": "^5.1.1",
|
"bn.js": "^5.1.2",
|
||||||
"rxjs": "^6.5.5"
|
"rxjs": "^6.5.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ function parseSelector (registry: Registry, fnname: string, input: ContractABIMe
|
|||||||
return registry.createType('u32', hexToU8a(input));
|
return registry.createType('u32', hexToU8a(input));
|
||||||
} else if (typeof input === 'string') {
|
} else if (typeof input === 'string') {
|
||||||
try {
|
try {
|
||||||
const array = JSON.parse(input);
|
const array = JSON.parse(input) as unknown[];
|
||||||
|
|
||||||
assert(array.length === 4, `${fnname}: Invalid selector length`);
|
assert(array.length === 4, `${fnname}: Invalid selector length`);
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ export default class ContractRegistry extends MetaRegistry {
|
|||||||
|
|
||||||
public createMessage (name: string, message: Partial<ContractABIMessage> & ContractABIMessageBase): ContractABIFn {
|
public createMessage (name: string, message: Partial<ContractABIMessage> & ContractABIMessageBase): ContractABIFn {
|
||||||
const args = message.args.map(({ name, type }): ContractABIFnArg => {
|
const args = message.args.map(({ name, type }): ContractABIFnArg => {
|
||||||
assert(isObject(type), `Invalid type at index ${type}`);
|
assert(isObject(type), `Invalid type at index ${type.toString()}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: stringCamelCase(name),
|
name: stringCamelCase(name),
|
||||||
@@ -183,6 +183,7 @@ export default class ContractRegistry extends MetaRegistry {
|
|||||||
public convertMessage ({ args, name, return_type: returnType, ...message }: ContractABIMessagePre): ContractABIMessage {
|
public convertMessage ({ args, name, return_type: returnType, ...message }: ContractABIMessagePre): ContractABIMessage {
|
||||||
return {
|
return {
|
||||||
...message,
|
...message,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
args: this.convertArgs(args),
|
args: this.convertArgs(args),
|
||||||
name: this._stringAt(name),
|
name: this._stringAt(name),
|
||||||
returnType: returnType ? this.convertType(returnType) : null
|
returnType: returnType ? this.convertType(returnType) : null
|
||||||
@@ -191,6 +192,7 @@ export default class ContractRegistry extends MetaRegistry {
|
|||||||
|
|
||||||
public convertEvent ({ args }: ContractABIEventPre): ContractABIEvent {
|
public convertEvent ({ args }: ContractABIEventPre): ContractABIEvent {
|
||||||
return {
|
return {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
args: this.convertArgs(args)
|
args: this.convertArgs(args)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import { MetaRegistryItem, MetaRegistryJson, MetaTypeDefClikeEnum, MetaType, Met
|
|||||||
import { assert } from '@polkadot/util';
|
import { assert } from '@polkadot/util';
|
||||||
import { displayType, withTypeString } from '@polkadot/types';
|
import { displayType, withTypeString } from '@polkadot/types';
|
||||||
|
|
||||||
const builtinMap: [(id: any) => boolean, MetaTypeInfo][] = [
|
const builtinMap: [(id: unknown | unknown[] | { 'array.type': unknown } | { 'slice.type': unknown }) => boolean, MetaTypeInfo][] = [
|
||||||
[(id: any): boolean => typeof id === 'string', MetaTypeInfo.BuiltinPlain],
|
[(id: any) => typeof id === 'string', MetaTypeInfo.BuiltinPlain],
|
||||||
[(id: any): boolean => Array.isArray(id), MetaTypeInfo.BuiltinTuple],
|
[(id: any) => Array.isArray(id), MetaTypeInfo.BuiltinTuple],
|
||||||
[(id: any): boolean => !!(id['array.type']), MetaTypeInfo.BuiltinVecFixed],
|
[(id: any) => !!((id as { 'array.type': unknown })['array.type']), MetaTypeInfo.BuiltinVecFixed],
|
||||||
[(id: any): boolean => !!(id['slice.type']), MetaTypeInfo.BuiltinVec]
|
[(id: any) => !!((id as { 'slice.type': unknown })['slice.type']), MetaTypeInfo.BuiltinVec]
|
||||||
];
|
];
|
||||||
|
|
||||||
const typeMap: [string, MetaTypeInfo][] = [
|
const typeMap: [string, MetaTypeInfo][] = [
|
||||||
@@ -25,8 +25,8 @@ function detectedType ({ def, id }: MetaType): MetaTypeInfo {
|
|||||||
assert(!(def as MetaTypeDefUnion)['union.fields'], 'Invalid union type definition found');
|
assert(!(def as MetaTypeDefUnion)['union.fields'], 'Invalid union type definition found');
|
||||||
|
|
||||||
const lookup = def === 'builtin'
|
const lookup = def === 'builtin'
|
||||||
? builtinMap.find(([test]): boolean => test(id))
|
? builtinMap.find(([test]) => test(id))
|
||||||
: typeMap.find(([test]): boolean => !!(def as any)[test]);
|
: typeMap.find(([test]) => !!(def as unknown as Record<string, unknown>)[test]);
|
||||||
|
|
||||||
return lookup
|
return lookup
|
||||||
? lookup[1]
|
? lookup[1]
|
||||||
@@ -59,7 +59,7 @@ class MetadataRegistryLookup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _itemAt (index: number, variant: MetaRegistryItem): any {
|
protected _itemAt (index: number, variant: MetaRegistryItem): string | MetaType | TypeDef {
|
||||||
assert(this._hasItemAt(index, variant), `MetaRegistry: Invalid ${variant} index ${index} found in metadata`);
|
assert(this._hasItemAt(index, variant), `MetaRegistry: Invalid ${variant} index ${index} found in metadata`);
|
||||||
|
|
||||||
switch (variant) {
|
switch (variant) {
|
||||||
@@ -72,24 +72,24 @@ class MetadataRegistryLookup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _itemsAt (indices: number[], variant: MetaRegistryItem): any[] {
|
protected _itemsAt (indices: number[], variant: MetaRegistryItem): (string | MetaType | TypeDef)[] {
|
||||||
return indices.map((index: number): string => this._itemAt(index, variant));
|
return indices.map((index: number) => this._itemAt(index, variant));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _stringAt (index: StringIndex): string {
|
protected _stringAt (index: StringIndex): string {
|
||||||
return this._itemAt(index, MetaRegistryItem.String);
|
return this._itemAt(index, MetaRegistryItem.String) as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
public stringsAt (indices: StringIndex[]): string[] {
|
public stringsAt (indices: StringIndex[]): string[] {
|
||||||
return this._itemsAt(indices, MetaRegistryItem.String);
|
return this._itemsAt(indices, MetaRegistryItem.String) as string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
public typeAt (index: TypeIndex): MetaType {
|
public typeAt (index: TypeIndex): MetaType {
|
||||||
return this._itemAt(index, MetaRegistryItem.Type);
|
return this._itemAt(index, MetaRegistryItem.Type) as MetaType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public typesAt (indices: TypeIndex[]): MetaType[] {
|
public typesAt (indices: TypeIndex[]): MetaType[] {
|
||||||
return this._itemsAt(indices, MetaRegistryItem.Type);
|
return this._itemsAt(indices, MetaRegistryItem.Type) as MetaType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasTypeDefAt (index: TypeIndex): boolean {
|
public hasTypeDefAt (index: TypeIndex): boolean {
|
||||||
@@ -98,7 +98,7 @@ class MetadataRegistryLookup {
|
|||||||
|
|
||||||
public typeDefAt (index: TypeIndex, extra: Pick<TypeDef, never> = {}): TypeDef {
|
public typeDefAt (index: TypeIndex, extra: Pick<TypeDef, never> = {}): TypeDef {
|
||||||
return {
|
return {
|
||||||
...this._itemAt(index, MetaRegistryItem.TypeDef),
|
...this._itemAt(index, MetaRegistryItem.TypeDef) as TypeDef,
|
||||||
...extra
|
...extra
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _typeDefDefFields (metaType: MetaType, typeIndex?: TypeIndex): Pick<TypeDef, never> {
|
private _typeDefDefFields (metaType: MetaType, typeIndex: TypeIndex = -1): Pick<TypeDef, never> {
|
||||||
let typeDef;
|
let typeDef;
|
||||||
|
|
||||||
switch (detectedType(metaType)) {
|
switch (detectedType(metaType)) {
|
||||||
@@ -234,7 +234,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _typeDefForBuiltinVec (id: MetaTypeIdVec, typeIndex?: TypeIndex): Pick<TypeDef, never> {
|
private _typeDefForBuiltinVec (id: MetaTypeIdVec, typeIndex: TypeIndex = -1): Pick<TypeDef, never> {
|
||||||
const { 'slice.type': vecTypeIndex } = id;
|
const { 'slice.type': vecTypeIndex } = id;
|
||||||
|
|
||||||
assert(!typeIndex || vecTypeIndex !== typeIndex, `MetaRegistry: self-referencing registry type at index ${typeIndex}`);
|
assert(!typeIndex || vecTypeIndex !== typeIndex, `MetaRegistry: self-referencing registry type at index ${typeIndex}`);
|
||||||
@@ -250,7 +250,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _typeDefForBuiltinVecFixed (id: MetaTypeIdVecFixed, typeIndex?: TypeIndex): Pick<TypeDef, never> {
|
private _typeDefForBuiltinVecFixed (id: MetaTypeIdVecFixed, typeIndex: TypeIndex = -1): Pick<TypeDef, never> {
|
||||||
const { 'array.len': vecLength, 'array.type': vecTypeIndex } = id;
|
const { 'array.len': vecLength, 'array.type': vecTypeIndex } = id;
|
||||||
|
|
||||||
assert(!vecLength || vecLength <= 256, 'MetaRegistry: Only support for [Type; <length>], where length <= 256');
|
assert(!vecLength || vecLength <= 256, 'MetaRegistry: Only support for [Type; <length>], where length <= 256');
|
||||||
@@ -301,7 +301,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public typeDefForOption (id: MetaTypeIdCustom, typeIndex?: TypeIndex): Pick<TypeDef, any> {
|
public typeDefForOption (id: MetaTypeIdCustom, typeIndex: TypeIndex = -1): Pick<TypeDef, any> {
|
||||||
assert(id['custom.params'] && id['custom.params'][0], `Invalid Option type defined at index ${typeIndex}`);
|
assert(id['custom.params'] && id['custom.params'][0], `Invalid Option type defined at index ${typeIndex}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -310,7 +310,7 @@ export default class MetaRegistry extends MetadataRegistryLookup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public typeDefForResult (id: MetaTypeIdCustom, typeIndex?: TypeIndex): Pick<TypeDef, any> {
|
public typeDefForResult (id: MetaTypeIdCustom, typeIndex: TypeIndex = -1): Pick<TypeDef, any> {
|
||||||
assert(id['custom.params'] && id['custom.params'][0] && id['custom.params'][1], `Invalid Result type defined at index ${typeIndex}`);
|
assert(id['custom.params'] && id['custom.params'][0] && id['custom.params'][1], `Invalid Result type defined at index ${typeIndex}`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export default class Blueprint<ApiType extends ApiTypes> extends BaseWithTx<ApiT
|
|||||||
assert(!!this.abi.constructors[constructorIndex], `Specified constructor index ${constructorIndex} does not exist`);
|
assert(!!this.abi.constructors[constructorIndex], `Specified constructor index ${constructorIndex} does not exist`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
signAndSend: this.decorateMethod(
|
signAndSend: this.decorateMethod(
|
||||||
(account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription<ApiType> => {
|
(account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription<ApiType> => {
|
||||||
return this._apiContracts
|
return this._apiContracts
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import { BaseWithTx } from './util';
|
|||||||
|
|
||||||
type CodePutCodeResultSubscription<ApiType extends ApiTypes> = Observable<CodePutCodeResult<ApiType>>;
|
type CodePutCodeResultSubscription<ApiType extends ApiTypes> = Observable<CodePutCodeResult<ApiType>>;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
|
|
||||||
export interface CodePutCode<ApiType extends ApiTypes> {
|
export interface CodePutCode<ApiType extends ApiTypes> {
|
||||||
signAndSend (account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription<ApiType>;
|
signAndSend (account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription<ApiType>;
|
||||||
}
|
}
|
||||||
@@ -46,6 +45,7 @@ export default class Code<ApiType extends ApiTypes> extends BaseWithTx<ApiType>
|
|||||||
|
|
||||||
public createBlueprint = (maxGas: number | BN): CodePutCode<ApiType> => {
|
public createBlueprint = (maxGas: number | BN): CodePutCode<ApiType> => {
|
||||||
return {
|
return {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
signAndSend: this.decorateMethod(
|
signAndSend: this.decorateMethod(
|
||||||
(account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription<ApiType> =>
|
(account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription<ApiType> =>
|
||||||
this._apiContracts
|
this._apiContracts
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ type ContractCallResultSubscription<ApiType extends ApiTypes, CallType extends C
|
|||||||
? Observable<ContractCallResult<CallType>>
|
? Observable<ContractCallResult<CallType>>
|
||||||
: Promise<ObsInnerType<ContractCallResult<CallType>>>;
|
: Promise<ObsInnerType<ContractCallResult<CallType>>>;
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
|
|
||||||
export interface ContractCall<ApiType extends ApiTypes, CallType extends ContractCallTypes> {
|
export interface ContractCall<ApiType extends ApiTypes, CallType extends ContractCallTypes> {
|
||||||
send (account: IKeyringPair | string | AccountId | Address): ContractCallResultSubscription<ApiType, CallType>;
|
send (account: IKeyringPair | string | AccountId | Address): ContractCallResultSubscription<ApiType, CallType>;
|
||||||
}
|
}
|
||||||
@@ -45,6 +44,7 @@ export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpc
|
|||||||
const { def, fn } = this.getMessage(message);
|
const { def, fn } = this.getMessage(message);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
send: this.decorateMethod(
|
send: this.decorateMethod(
|
||||||
as === 'rpc' && this.hasRpcContractsCall
|
as === 'rpc' && this.hasRpcContractsCall
|
||||||
? (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'rpc'> =>
|
? (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'rpc'> =>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export abstract class Base<ApiType extends ApiTypes> implements ContractBase<Api
|
|||||||
: 0;
|
: 0;
|
||||||
const def = this.abi.abi.contract.messages[index];
|
const def = this.abi.abi.contract.messages[index];
|
||||||
|
|
||||||
assert(!!def, `Attempted to access a contract message that does not exist: ${typeof nameOrIndex === 'number' ? `index ${nameOrIndex}` : nameOrIndex}`);
|
assert(!!def, `Attempted to access a contract message that does not exist: ${typeof nameOrIndex === 'number' ? `index ${nameOrIndex}` : (nameOrIndex || 'unknown')}`);
|
||||||
|
|
||||||
const fn = this.abi.messages[def.name] || this.abi.messages[stringCamelCase(def.name)];
|
const fn = this.abi.messages[def.name] || this.abi.messages[stringCamelCase(def.name)];
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export interface ContractBase<ApiType extends ApiTypes> {
|
|||||||
|
|
||||||
export interface ContractABITypePre {
|
export interface ContractABITypePre {
|
||||||
ty: TypeIndex;
|
ty: TypeIndex;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
display_name: StringIndex[];
|
display_name: StringIndex[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ export interface ContractABIMessageCommon {
|
|||||||
|
|
||||||
export interface ContractABIMessagePre extends ContractABIMessageCommon, ContractABIMessageBasePre {
|
export interface ContractABIMessagePre extends ContractABIMessageCommon, ContractABIMessageBasePre {
|
||||||
name: StringIndex;
|
name: StringIndex;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
return_type: ContractABITypePre | null;
|
return_type: ContractABITypePre | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +189,7 @@ export interface InterfaceAbi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface InterfaceContractCalls {
|
export interface InterfaceContractCalls {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
[index: string]: Function;
|
[index: string]: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@polkadot/api-derive",
|
"name": "@polkadot/api-derive",
|
||||||
"version": "1.14.1",
|
"version": "1.16.1",
|
||||||
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
|
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -28,17 +28,17 @@
|
|||||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.9.6",
|
"@babel/runtime": "^7.9.6",
|
||||||
"@polkadot/api": "1.14.1",
|
"@polkadot/api": "1.16.1",
|
||||||
"@polkadot/rpc-core": "1.14.1",
|
"@polkadot/rpc-core": "1.16.1",
|
||||||
"@polkadot/rpc-provider": "1.14.1",
|
"@polkadot/rpc-provider": "1.16.1",
|
||||||
"@polkadot/types": "1.14.1",
|
"@polkadot/types": "1.16.1",
|
||||||
"@polkadot/util": "^2.10.1",
|
"@polkadot/util": "^2.11.1",
|
||||||
"@polkadot/util-crypto": "^2.10.1",
|
"@polkadot/util-crypto": "^2.11.1",
|
||||||
"bn.js": "^5.1.1",
|
"bn.js": "^5.1.2",
|
||||||
"memoizee": "^0.4.14",
|
"memoizee": "^0.4.14",
|
||||||
"rxjs": "^6.5.5"
|
"rxjs": "^6.5.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/keyring": "^2.10.1"
|
"@polkadot/keyring": "^2.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { map, startWith } from 'rxjs/operators';
|
|||||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||||
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
|
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
|
||||||
import { Option, Vec } from '@polkadot/types';
|
import { Option, Vec } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ function query (api: ApiInterfaceRx, accountIndex: AccountIndex | string): Obser
|
|||||||
export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable<AccountId | undefined> {
|
export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable<AccountId | undefined> {
|
||||||
return memo((accountIndex: AccountIndex | string): Observable<AccountId | undefined> =>
|
return memo((accountIndex: AccountIndex | string): Observable<AccountId | undefined> =>
|
||||||
api.query.indices
|
api.query.indices
|
||||||
? api.query.indices.accounts
|
? isFunction(api.query.indices.accounts)
|
||||||
? query(api, accountIndex)
|
? query(api, accountIndex)
|
||||||
: queryEnumSet(api, accountIndex)
|
: queryEnumSet(api, accountIndex)
|
||||||
: of(undefined)
|
: of(undefined)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { Observable, of } from 'rxjs';
|
|||||||
import { map, startWith, switchMap } from 'rxjs/operators';
|
import { map, startWith, switchMap } from 'rxjs/operators';
|
||||||
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
|
import { ENUMSET_SIZE } from '@polkadot/types/generic/AccountIndex';
|
||||||
import { Vec } from '@polkadot/types';
|
import { Vec } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ function queryAccounts (api: ApiInterfaceRx): Observable<AccountIndexes> {
|
|||||||
export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes> {
|
export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes> {
|
||||||
return memo((): Observable<AccountIndexes> =>
|
return memo((): Observable<AccountIndexes> =>
|
||||||
(api.query.indices
|
(api.query.indices
|
||||||
? api.query.indices.accounts
|
? isFunction(api.query.indices.accounts)
|
||||||
? queryAccounts(api)
|
? queryAccounts(api)
|
||||||
: queryEnumSet(api)
|
: queryEnumSet(api)
|
||||||
: of({} as AccountIndexes)
|
: of({} as AccountIndexes)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { DeriveBalancesAccount } from '../types';
|
|||||||
import { Observable, combineLatest, of } from 'rxjs';
|
import { Observable, combineLatest, of } from 'rxjs';
|
||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -86,9 +87,9 @@ export function account (api: ApiInterfaceRx): (address: AccountIndex | AccountI
|
|||||||
(accountId
|
(accountId
|
||||||
? combineLatest([
|
? combineLatest([
|
||||||
of(accountId),
|
of(accountId),
|
||||||
api.query.system.account
|
isFunction(api.query.system.account)
|
||||||
? queryCurrent(api, accountId)
|
? queryCurrent(api, accountId)
|
||||||
: api.query.balances.account
|
: isFunction(api.query.balances.account)
|
||||||
? queryBalancesAccount(api, accountId)
|
? queryBalancesAccount(api, accountId)
|
||||||
: queryBalancesFree(api, accountId)
|
: queryBalancesFree(api, accountId)
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { Observable, combineLatest, of } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||||
import { Option, Vec } from '@polkadot/types';
|
import { Option, Vec } from '@polkadot/types';
|
||||||
import { bnMax } from '@polkadot/util';
|
import { bnMax, isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId |
|
|||||||
? combineLatest([
|
? combineLatest([
|
||||||
of(account),
|
of(account),
|
||||||
api.derive.chain.bestNumber(),
|
api.derive.chain.bestNumber(),
|
||||||
api.query.balances.account
|
isFunction(api.query.balances.account)
|
||||||
? queryCurrent(api, account.accountId)
|
? queryCurrent(api, account.accountId)
|
||||||
: queryOld(api, account.accountId)
|
: queryOld(api, account.accountId)
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ export function fees (api: ApiInterfaceRx): () => Observable<DeriveFees> {
|
|||||||
return memo((): Observable<DeriveFees> =>
|
return memo((): Observable<DeriveFees> =>
|
||||||
of([
|
of([
|
||||||
// deprecated - remove
|
// deprecated - remove
|
||||||
(api.consts.balances?.creationFee as Balance) || api.registry.createType('Balance'),
|
(api.consts.balances?.creationFee as unknown as Balance) || api.registry.createType('Balance'),
|
||||||
(api.consts.balances?.transferFee as Balance) || api.registry.createType('Balance'),
|
(api.consts.balances?.transferFee as unknown as Balance) || api.registry.createType('Balance'),
|
||||||
|
|
||||||
// current
|
// current
|
||||||
(api.consts.balances?.existentialDeposit as Balance) || api.registry.createType('Balance'),
|
(api.consts.balances?.existentialDeposit as Balance) || api.registry.createType('Balance'),
|
||||||
(api.consts.transactionPayment?.transactionBaseFee as Balance) || api.registry.createType('Balance'),
|
(api.consts.transactionPayment?.transactionBaseFee as unknown as Balance) || api.registry.createType('Balance'),
|
||||||
(api.consts.transactionPayment?.transactionByteFee as Balance) || api.registry.createType('Balance')
|
(api.consts.transactionPayment?.transactionByteFee as Balance) || api.registry.createType('Balance')
|
||||||
]).pipe(
|
]).pipe(
|
||||||
map(([creationFee, transferFee, existentialDeposit, transactionBaseFee, transactionByteFee]): DeriveFees => ({
|
map(([creationFee, transferFee, existentialDeposit, transactionBaseFee, transactionByteFee]): DeriveFees => ({
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { DeriveCollectiveProposal } from '../types';
|
|||||||
import { Observable, combineLatest, of } from 'rxjs';
|
import { Observable, combineLatest, of } from 'rxjs';
|
||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { Option } from '@polkadot/types';
|
import { Option } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ function parse ([hashes, proposals, votes]: Result): DeriveCollectiveProposal[]
|
|||||||
|
|
||||||
export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable<DeriveCollectiveProposal[]> {
|
export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable<DeriveCollectiveProposal[]> {
|
||||||
return memo((): Observable<DeriveCollectiveProposal[]> =>
|
return memo((): Observable<DeriveCollectiveProposal[]> =>
|
||||||
api.query[section]?.proposals
|
isFunction(api.query[section]?.proposals)
|
||||||
? api.query[section].proposals().pipe(
|
? api.query[section].proposals().pipe(
|
||||||
switchMap((hashes: Hash[]): Observable<Result> =>
|
switchMap((hashes: Hash[]): Observable<Result> =>
|
||||||
hashes.length
|
hashes.length
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { Observable, combineLatest, of } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||||
import { Option, Vec, u64 } from '@polkadot/types';
|
import { Option, Vec, u64 } from '@polkadot/types';
|
||||||
import { stringToHex } from '@polkadot/util';
|
import { isFunction, stringToHex } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ function queryScheduler (api: ApiInterfaceRx): Observable<DeriveDispatch[]> {
|
|||||||
|
|
||||||
export function dispatchQueue (api: ApiInterfaceRx): () => Observable<DeriveDispatch[]> {
|
export function dispatchQueue (api: ApiInterfaceRx): () => Observable<DeriveDispatch[]> {
|
||||||
return memo((): Observable<DeriveDispatch[]> =>
|
return memo((): Observable<DeriveDispatch[]> =>
|
||||||
api.query.scheduler?.agenda
|
isFunction(api.query.scheduler?.agenda)
|
||||||
? queryScheduler(api)
|
? queryScheduler(api)
|
||||||
: api.query.democracy.dispatchQueue
|
: api.query.democracy.dispatchQueue
|
||||||
? queryQueue(api)
|
? queryQueue(api)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export function referendumIds (api: ApiInterfaceRx): () => Observable<BN[]> {
|
|||||||
]).pipe(
|
]).pipe(
|
||||||
map(([first, total]): BN[] =>
|
map(([first, total]): BN[] =>
|
||||||
total.gt(first)
|
total.gt(first)
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
? [...Array(total.sub(first).toNumber())].map((_, i): BN => first.addn(i))
|
? [...Array(total.sub(first).toNumber())].map((_, i): BN => first.addn(i))
|
||||||
: []
|
: []
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import BN from 'bn.js';
|
|||||||
import { Observable, of, combineLatest } from 'rxjs';
|
import { Observable, of, combineLatest } from 'rxjs';
|
||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { Option, Vec } from '@polkadot/types';
|
import { Option, Vec } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
import { calcVotes, getStatus, parseImage } from './util';
|
import { calcVotes, getStatus, parseImage } from './util';
|
||||||
@@ -95,7 +96,7 @@ export function _referendumVotes (api: ApiInterfaceRx): (referendum: DeriveRefer
|
|||||||
return memo((referendum: DeriveReferendum): Observable<DeriveReferendumVotes> =>
|
return memo((referendum: DeriveReferendum): Observable<DeriveReferendumVotes> =>
|
||||||
combineLatest([
|
combineLatest([
|
||||||
api.derive.democracy.sqrtElectorate(),
|
api.derive.democracy.sqrtElectorate(),
|
||||||
api.query.democracy.votingOf
|
isFunction(api.query.democracy.votingOf)
|
||||||
? votesCurr(api, referendum.index)
|
? votesCurr(api, referendum.index)
|
||||||
: votesPrev(api, referendum.index)
|
: votesPrev(api, referendum.index)
|
||||||
]).pipe(
|
]).pipe(
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
// This software may be modified and distributed under the terms
|
// This software may be modified and distributed under the terms
|
||||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||||
|
|
||||||
import { Observable, from } from 'rxjs';
|
import { Observable, from } from 'rxjs';
|
||||||
import ApiRx from '@polkadot/api/rx/Api';
|
import ApiRx from '@polkadot/api/rx/Api';
|
||||||
import MockProvider from '@polkadot/rpc-provider/mock';
|
import MockProvider from '@polkadot/rpc-provider/mock';
|
||||||
@@ -33,7 +37,7 @@ describe('derive', (): void => {
|
|||||||
const api = new ApiRx({ provider: new MockProvider(registry), registry });
|
const api = new ApiRx({ provider: new MockProvider(registry), registry });
|
||||||
|
|
||||||
beforeAll((done): void => {
|
beforeAll((done): void => {
|
||||||
api.isReady.subscribe((): void => done());
|
api.isReady.subscribe(() => done());
|
||||||
});
|
});
|
||||||
|
|
||||||
testFunction(api)('accounts', 'idAndIndex', []);
|
testFunction(api)('accounts', 'idAndIndex', []);
|
||||||
|
|||||||
@@ -76,9 +76,11 @@ function injectFunctions<AllSections> (api: ApiInterfaceRx, allSections: AllSect
|
|||||||
.reduce((sectionAcc, _methodName): DeriveSection<typeof section> => {
|
.reduce((sectionAcc, _methodName): DeriveSection<typeof section> => {
|
||||||
const methodName = _methodName as keyof typeof section;
|
const methodName = _methodName as keyof typeof section;
|
||||||
// Not sure what to do here, casting as any. Though the final types are good
|
// Not sure what to do here, casting as any. Though the final types are good
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||||
const method = (section[methodName] as any)(api);
|
const method = (section[methodName] as any)(api);
|
||||||
|
|
||||||
// idem
|
// idem
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
|
||||||
(sectionAcc as any)[methodName] = method;
|
(sectionAcc as any)[methodName] = method;
|
||||||
|
|
||||||
return sectionAcc;
|
return sectionAcc;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { DeriveSessionIndexes } from '../types';
|
|||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { Option, u32 } from '@polkadot/types';
|
import { Option, u32 } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ export function indexes (api: ApiInterfaceRx): () => Observable<DeriveSessionInd
|
|||||||
return memo((): Observable<DeriveSessionIndexes> =>
|
return memo((): Observable<DeriveSessionIndexes> =>
|
||||||
(
|
(
|
||||||
api.query.session && api.query.staking
|
api.query.session && api.query.staking
|
||||||
? api.query.staking.activeEra
|
? isFunction(api.query.staking.activeEra)
|
||||||
? query(api)
|
? query(api)
|
||||||
: queryNoActive(api)
|
: queryNoActive(api)
|
||||||
: empty(api)
|
: empty(api)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Observable, combineLatest, of } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||||
import { Option, u64 } from '@polkadot/types';
|
import { Option, u64 } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -77,9 +78,10 @@ function queryBabeNoHistory (api: ApiInterfaceRx): Observable<[DeriveSessionInfo
|
|||||||
export function progress (api: ApiInterfaceRx): () => Observable<DeriveSessionProgress> {
|
export function progress (api: ApiInterfaceRx): () => Observable<DeriveSessionProgress> {
|
||||||
return memo((): Observable<DeriveSessionProgress> =>
|
return memo((): Observable<DeriveSessionProgress> =>
|
||||||
api.consts.babe
|
api.consts.babe
|
||||||
? (api.query.staking.erasStartSessionIndex
|
? (
|
||||||
? queryBabe(api) // 2.x with Babe
|
isFunction(api.query.staking.erasStartSessionIndex)
|
||||||
: queryBabeNoHistory(api)
|
? queryBabe(api) // 2.x with Babe
|
||||||
|
: queryBabeNoHistory(api)
|
||||||
).pipe(
|
).pipe(
|
||||||
map(([info, slots]: [DeriveSessionInfo, ResultSlotsFlat]): DeriveSessionProgress =>
|
map(([info, slots]: [DeriveSessionInfo, ResultSlotsFlat]): DeriveSessionProgress =>
|
||||||
createDerive(api, info, slots)
|
createDerive(api, info, slots)
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ import { Observable, combineLatest, of } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { StorageKey } from '@polkadot/types';
|
import { StorageKey } from '@polkadot/types';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { deriveCache, memo } from '../util';
|
||||||
|
|
||||||
type KeysAndExposures = [StorageKey, Exposure][];
|
type KeysAndExposures = [StorageKey, Exposure][];
|
||||||
|
|
||||||
|
const CACHE_KEY = 'eraExposure';
|
||||||
|
|
||||||
function mapStakers (era: EraIndex, stakers: KeysAndExposures): DeriveEraExposure {
|
function mapStakers (era: EraIndex, stakers: KeysAndExposures): DeriveEraExposure {
|
||||||
const nominators: DeriveEraNominatorExposure = {};
|
const nominators: DeriveEraNominatorExposure = {};
|
||||||
const validators: DeriveEraValidatorExposure = {};
|
const validators: DeriveEraValidatorExposure = {};
|
||||||
@@ -34,26 +36,45 @@ function mapStakers (era: EraIndex, stakers: KeysAndExposures): DeriveEraExposur
|
|||||||
return { era, nominators, validators };
|
return { era, nominators, validators };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function _eraExposure (api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable<DeriveEraExposure> {
|
||||||
|
return memo((era: EraIndex, withActive: boolean): Observable<DeriveEraExposure> => {
|
||||||
|
const cacheKey = `${CACHE_KEY}-${era.toString()}`;
|
||||||
|
const cached = withActive
|
||||||
|
? undefined
|
||||||
|
: deriveCache.get<DeriveEraExposure>(cacheKey);
|
||||||
|
|
||||||
|
return cached
|
||||||
|
? of(cached)
|
||||||
|
: api.query.staking.erasStakersClipped.entries(era).pipe(
|
||||||
|
map((stakers): DeriveEraExposure => {
|
||||||
|
const value = mapStakers(era, stakers);
|
||||||
|
|
||||||
|
!withActive && deriveCache.set(cacheKey, value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function eraExposure (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraExposure> {
|
export function eraExposure (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraExposure> {
|
||||||
return memo((era: EraIndex): Observable<DeriveEraExposure> =>
|
return memo((era: EraIndex): Observable<DeriveEraExposure> =>
|
||||||
api.query.staking.erasStakersClipped.entries(era).pipe(
|
api.derive.staking._eraExposure(era, true)
|
||||||
map((stakers) => mapStakers(era, stakers))
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _erasExposure (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraExposure[]> {
|
export function _erasExposure (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable<DeriveEraExposure[]> {
|
||||||
return memo((eras: EraIndex[]): Observable<DeriveEraExposure[]> =>
|
return memo((eras: EraIndex[], withActive: boolean): Observable<DeriveEraExposure[]> =>
|
||||||
eras.length
|
eras.length
|
||||||
? combineLatest(eras.map((era) => api.derive.staking.eraExposure(era)))
|
? combineLatest(eras.map((era) => api.derive.staking._eraExposure(era, withActive)))
|
||||||
: of([])
|
: of([])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function erasExposure (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraExposure[]> {
|
export function erasExposure (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraExposure[]> {
|
||||||
return memo((withActive?: boolean): Observable<DeriveEraExposure[]> =>
|
return memo((withActive = false): Observable<DeriveEraExposure[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._erasExposure(eras))
|
switchMap((eras) => api.derive.staking._erasExposure(eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import { DeriveEraPoints, DeriveEraValPoints } from '../types';
|
|||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { deriveCache, memo } from '../util';
|
||||||
|
|
||||||
|
const CACHE_KEY = 'eraPoints';
|
||||||
|
|
||||||
function mapValidators ({ individual }: EraRewardPoints): DeriveEraValPoints {
|
function mapValidators ({ individual }: EraRewardPoints): DeriveEraValPoints {
|
||||||
return [...individual.entries()]
|
return [...individual.entries()]
|
||||||
@@ -21,26 +23,48 @@ function mapValidators ({ individual }: EraRewardPoints): DeriveEraValPoints {
|
|||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _erasPoints (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraPoints[]> {
|
function mapPoints (eras: EraIndex[], points: EraRewardPoints[]): DeriveEraPoints[] {
|
||||||
return memo((eras: EraIndex[]): Observable<DeriveEraPoints[]> =>
|
return eras.map((era, index): DeriveEraPoints => ({
|
||||||
eras.length
|
era,
|
||||||
? api.query.staking.erasRewardPoints.multi<EraRewardPoints>(eras).pipe(
|
eraPoints: points[index].total,
|
||||||
map((points) =>
|
validators: mapValidators(points[index])
|
||||||
eras.map((era, index): DeriveEraPoints => ({
|
}));
|
||||||
era,
|
}
|
||||||
eraPoints: points[index].total,
|
|
||||||
validators: mapValidators(points[index])
|
export function _erasPoints (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable<DeriveEraPoints[]> {
|
||||||
}))
|
return memo((eras: EraIndex[], withActive: boolean): Observable<DeriveEraPoints[]> => {
|
||||||
)
|
if (!eras.length) {
|
||||||
)
|
return of([]);
|
||||||
: of([])
|
}
|
||||||
);
|
|
||||||
|
const cached: DeriveEraPoints[] = withActive
|
||||||
|
? []
|
||||||
|
: eras
|
||||||
|
.map((era) => deriveCache.get<DeriveEraPoints>(`${CACHE_KEY}-${era.toString()}`))
|
||||||
|
.filter((value): value is DeriveEraPoints => !!value);
|
||||||
|
const remaining = eras.filter((era) => !cached.some((cached) => era.eq(cached.era)));
|
||||||
|
|
||||||
|
return !remaining.length
|
||||||
|
? of(cached)
|
||||||
|
: api.query.staking.erasRewardPoints.multi<EraRewardPoints>(remaining).pipe(
|
||||||
|
map((points): DeriveEraPoints[] => {
|
||||||
|
const query = mapPoints(remaining, points);
|
||||||
|
|
||||||
|
!withActive && query.forEach((q) => deriveCache.set(`${CACHE_KEY}-${q.era.toString()}`, q));
|
||||||
|
|
||||||
|
return eras.map((era): DeriveEraPoints =>
|
||||||
|
cached.find((cached) => era.eq(cached.era)) ||
|
||||||
|
query.find((query) => era.eq(query.era)) as DeriveEraPoints
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function erasPoints (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraPoints[]> {
|
export function erasPoints (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraPoints[]> {
|
||||||
return memo((withActive?: boolean): Observable<DeriveEraPoints[]> =>
|
return memo((withActive = false): Observable<DeriveEraPoints[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._erasPoints(eras))
|
switchMap((eras) => api.derive.staking._erasPoints(eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import { Observable, combineLatest, of } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { StorageKey } from '@polkadot/types';
|
import { StorageKey } from '@polkadot/types';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { deriveCache, memo } from '../util';
|
||||||
|
|
||||||
|
const CACHE_KEY = 'eraPrefs';
|
||||||
|
|
||||||
function mapPrefs (era: EraIndex, all: [StorageKey, ValidatorPrefs][]): DeriveEraPrefs {
|
function mapPrefs (era: EraIndex, all: [StorageKey, ValidatorPrefs][]): DeriveEraPrefs {
|
||||||
const validators: DeriveEraValPrefs = {};
|
const validators: DeriveEraValPrefs = {};
|
||||||
@@ -22,26 +24,45 @@ function mapPrefs (era: EraIndex, all: [StorageKey, ValidatorPrefs][]): DeriveEr
|
|||||||
return { era, validators };
|
return { era, validators };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function _eraPrefs (api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable<DeriveEraPrefs> {
|
||||||
|
return memo((era: EraIndex, withActive: boolean): Observable<DeriveEraPrefs> => {
|
||||||
|
const cacheKey = `${CACHE_KEY}-${era.toString()}`;
|
||||||
|
const cached = withActive
|
||||||
|
? undefined
|
||||||
|
: deriveCache.get<DeriveEraPrefs>(cacheKey);
|
||||||
|
|
||||||
|
return cached
|
||||||
|
? of(cached)
|
||||||
|
: api.query.staking.erasValidatorPrefs.entries(era).pipe(
|
||||||
|
map((prefs): DeriveEraPrefs => {
|
||||||
|
const value = mapPrefs(era, prefs);
|
||||||
|
|
||||||
|
!withActive && deriveCache.set(cacheKey, value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function eraPrefs (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraPrefs> {
|
export function eraPrefs (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraPrefs> {
|
||||||
return memo((era: EraIndex): Observable<DeriveEraPrefs> =>
|
return memo((era: EraIndex): Observable<DeriveEraPrefs> =>
|
||||||
api.query.staking.erasValidatorPrefs.entries(era).pipe(
|
api.derive.staking._eraPrefs(era, true)
|
||||||
map((prefs) => mapPrefs(era, prefs))
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _erasPrefs (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraPrefs[]> {
|
export function _erasPrefs (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable<DeriveEraPrefs[]> {
|
||||||
return memo((eras: EraIndex[]): Observable<DeriveEraPrefs[]> =>
|
return memo((eras: EraIndex[], withActive: boolean): Observable<DeriveEraPrefs[]> =>
|
||||||
eras.length
|
eras.length
|
||||||
? combineLatest(eras.map((era) => api.derive.staking.eraPrefs(era)))
|
? combineLatest(eras.map((era) => api.derive.staking._eraPrefs(era, withActive)))
|
||||||
: of([])
|
: of([])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function erasPrefs (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraPrefs[]> {
|
export function erasPrefs (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraPrefs[]> {
|
||||||
return memo((withActive?: boolean): Observable<DeriveEraPrefs[]> =>
|
return memo((withActive = false): Observable<DeriveEraPrefs[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._erasPrefs(eras))
|
switchMap((eras) => api.derive.staking._erasPrefs(eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,25 +10,53 @@ import { Observable, of } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { Option } from '@polkadot/types';
|
import { Option } from '@polkadot/types';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { deriveCache, memo } from '../util';
|
||||||
|
|
||||||
export function _erasRewards (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraRewards[]> {
|
const CACHE_KEY = 'eraRewards';
|
||||||
return memo((eras: EraIndex[]): Observable<DeriveEraRewards[]> =>
|
|
||||||
eras.length
|
function mapRewards (eras: EraIndex[], optRewards: Option<Balance>[]): DeriveEraRewards[] {
|
||||||
? api.query.staking.erasValidatorReward.multi<Option<Balance>>(eras).pipe(
|
return eras.map((era, index): DeriveEraRewards => ({
|
||||||
map((rewards) => eras.map((era, index): DeriveEraRewards => ({
|
era,
|
||||||
era,
|
eraReward: optRewards[index].unwrapOrDefault()
|
||||||
eraReward: rewards[index].unwrapOrDefault()
|
}));
|
||||||
})))
|
}
|
||||||
)
|
|
||||||
: of([])
|
export function _erasRewards (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable<DeriveEraRewards[]> {
|
||||||
);
|
return memo((eras: EraIndex[], withActive: boolean): Observable<DeriveEraRewards[]> => {
|
||||||
|
if (!eras.length) {
|
||||||
|
return of([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cached: DeriveEraRewards[] = withActive
|
||||||
|
? []
|
||||||
|
: eras
|
||||||
|
.map((era) => deriveCache.get<DeriveEraRewards>(`${CACHE_KEY}-${era.toString()}`))
|
||||||
|
.filter((value): value is DeriveEraRewards => !!value);
|
||||||
|
const remaining = eras.filter((era) => !cached.some((cached) => era.eq(cached.era)));
|
||||||
|
|
||||||
|
if (!remaining.length) {
|
||||||
|
return of(cached);
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.query.staking.erasValidatorReward.multi<Option<Balance>>(remaining).pipe(
|
||||||
|
map((optRewards) => {
|
||||||
|
const query = mapRewards(remaining, optRewards);
|
||||||
|
|
||||||
|
!withActive && query.forEach((q) => deriveCache.set(`${CACHE_KEY}-${q.era.toString()}`, q));
|
||||||
|
|
||||||
|
return eras.map((era): DeriveEraRewards =>
|
||||||
|
cached.find((cached) => era.eq(cached.era)) ||
|
||||||
|
query.find((query) => era.eq(query.era)) as DeriveEraRewards
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function erasRewards (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraRewards[]> {
|
export function erasRewards (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraRewards[]> {
|
||||||
return memo((withActive?: boolean): Observable<DeriveEraRewards[]> =>
|
return memo((withActive = false): Observable<DeriveEraRewards[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._erasRewards(eras))
|
switchMap((eras) => api.derive.staking._erasRewards(eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ import { Observable, combineLatest, of } from 'rxjs';
|
|||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { Option, StorageKey } from '@polkadot/types';
|
import { Option, StorageKey } from '@polkadot/types';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { deriveCache, memo } from '../util';
|
||||||
|
|
||||||
|
const CACHE_KEY = 'eraSlashes';
|
||||||
|
|
||||||
function mapSlashes (era: EraIndex, noms: [StorageKey, Option<BalanceOf>][], vals: [StorageKey, Option<ITuple<[Perbill, BalanceOf]>>][]): DeriveEraSlashes {
|
function mapSlashes (era: EraIndex, noms: [StorageKey, Option<BalanceOf>][], vals: [StorageKey, Option<ITuple<[Perbill, BalanceOf]>>][]): DeriveEraSlashes {
|
||||||
const nominators: DeriveEraValSlash = {};
|
const nominators: DeriveEraValSlash = {};
|
||||||
@@ -28,31 +30,50 @@ function mapSlashes (era: EraIndex, noms: [StorageKey, Option<BalanceOf>][], val
|
|||||||
return { era, nominators, validators };
|
return { era, nominators, validators };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function _eraSlashes (api: ApiInterfaceRx): (era: EraIndex, withActive: boolean) => Observable<DeriveEraSlashes> {
|
||||||
|
return memo((era: EraIndex, withActive: boolean): Observable<DeriveEraSlashes> => {
|
||||||
|
const cacheKey = `${CACHE_KEY}-${era.toString()}`;
|
||||||
|
const cached = withActive
|
||||||
|
? undefined
|
||||||
|
: deriveCache.get<DeriveEraSlashes>(cacheKey);
|
||||||
|
|
||||||
|
return cached
|
||||||
|
? of(cached)
|
||||||
|
: combineLatest([
|
||||||
|
api.query.staking.nominatorSlashInEra.entries(era),
|
||||||
|
api.query.staking.validatorSlashInEra.entries(era)
|
||||||
|
]).pipe(
|
||||||
|
map(([noms, vals]): DeriveEraSlashes => {
|
||||||
|
const value = mapSlashes(era, noms, vals);
|
||||||
|
|
||||||
|
!withActive && deriveCache.set(cacheKey, value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function eraSlashes (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraSlashes> {
|
export function eraSlashes (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraSlashes> {
|
||||||
return memo((era: EraIndex): Observable<DeriveEraSlashes> =>
|
return memo((era: EraIndex): Observable<DeriveEraSlashes> =>
|
||||||
combineLatest([
|
api.derive.staking._eraSlashes(era, true)
|
||||||
api.query.staking.nominatorSlashInEra.entries(era),
|
|
||||||
api.query.staking.validatorSlashInEra.entries(era)
|
|
||||||
]).pipe(
|
|
||||||
map(([noms, vals]) => mapSlashes(era, noms, vals))
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _erasSlashes (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<DeriveEraSlashes[]> {
|
export function _erasSlashes (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable<DeriveEraSlashes[]> {
|
||||||
return memo((eras: EraIndex[]): Observable<DeriveEraSlashes[]> =>
|
return memo((eras: EraIndex[], withActive: boolean): Observable<DeriveEraSlashes[]> =>
|
||||||
eras.length
|
eras.length
|
||||||
? combineLatest(
|
? combineLatest(
|
||||||
eras.map((era) => api.derive.staking.eraSlashes(era))
|
eras.map((era) => api.derive.staking._eraSlashes(era, withActive))
|
||||||
)
|
)
|
||||||
: of([])
|
: of([])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function erasSlashes (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraSlashes[]> {
|
export function erasSlashes (api: ApiInterfaceRx): (withActive?: boolean) => Observable<DeriveEraSlashes[]> {
|
||||||
return memo((withActive?: boolean): Observable<DeriveEraSlashes[]> =>
|
return memo((withActive = false): Observable<DeriveEraSlashes[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._erasSlashes(eras))
|
switchMap((eras) => api.derive.staking._erasSlashes(eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { map, switchMap } from 'rxjs/operators';
|
|||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
export function ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerSlashes[]> {
|
export function ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerSlashes[]> {
|
||||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerSlashes[]> => {
|
return memo((accountId: Uint8Array | string, withActive = false): Observable<DeriveStakerSlashes[]> => {
|
||||||
return api.derive.staking.erasHistoric(withActive).pipe(
|
return api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) =>
|
switchMap((eras) =>
|
||||||
eras.length
|
eras.length
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { DeriveStakingQuery } from '../types';
|
|||||||
import { Observable, combineLatest, of } from 'rxjs';
|
import { Observable, combineLatest, of } from 'rxjs';
|
||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { Option, Vec } from '@polkadot/types';
|
import { Option, Vec } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ export function queryWithQueued (api: ApiInterfaceRx): (accountId: Uint8Array |
|
|||||||
const stashId = api.registry.createType('AccountId', accountId);
|
const stashId = api.registry.createType('AccountId', accountId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
api.query.staking.erasStakers
|
isFunction(api.query.staking.erasStakers)
|
||||||
? retrieveCurr(api, stashId)
|
? retrieveCurr(api, stashId)
|
||||||
: retrievePrev(api, stashId)
|
: retrievePrev(api, stashId)
|
||||||
).pipe(
|
).pipe(
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import { map, switchMap } from 'rxjs/operators';
|
|||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
export function _stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerExposure[]> {
|
export function _stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable<DeriveStakerExposure[]> {
|
||||||
return memo((accountId: Uint8Array | string, eras: EraIndex[]): Observable<DeriveStakerExposure[]> => {
|
return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable<DeriveStakerExposure[]> => {
|
||||||
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
||||||
|
|
||||||
return api.derive.staking._erasExposure(eras).pipe(
|
return api.derive.staking._erasExposure(eras, withActive).pipe(
|
||||||
map((exposures): DeriveStakerExposure[] =>
|
map((exposures): DeriveStakerExposure[] =>
|
||||||
exposures.map(({ era, nominators: allNominators, validators: allValidators }): DeriveStakerExposure => {
|
exposures.map(({ era, nominators: allNominators, validators: allValidators }): DeriveStakerExposure => {
|
||||||
const isValidator = !!allValidators[stakerId];
|
const isValidator = !!allValidators[stakerId];
|
||||||
@@ -38,9 +38,9 @@ export function _stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array |
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerExposure[]> {
|
export function stakerExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerExposure[]> {
|
||||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerExposure[]> =>
|
return memo((accountId: Uint8Array | string, withActive = false): Observable<DeriveStakerExposure[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._stakerExposure(accountId, eras))
|
switchMap((eras) => api.derive.staking._stakerExposure(accountId, eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import { map, switchMap } from 'rxjs/operators';
|
|||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
export function _stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerPoints[]> {
|
export function _stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable<DeriveStakerPoints[]> {
|
||||||
return memo((accountId: Uint8Array | string, eras: EraIndex[]): Observable<DeriveStakerPoints[]> => {
|
return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable<DeriveStakerPoints[]> => {
|
||||||
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
||||||
|
|
||||||
return api.derive.staking._erasPoints(eras).pipe(
|
return api.derive.staking._erasPoints(eras, withActive).pipe(
|
||||||
map((points): DeriveStakerPoints[] =>
|
map((points): DeriveStakerPoints[] =>
|
||||||
points.map(({ era, eraPoints, validators }): DeriveStakerPoints => ({
|
points.map(({ era, eraPoints, validators }): DeriveStakerPoints => ({
|
||||||
era,
|
era,
|
||||||
@@ -28,9 +28,9 @@ export function _stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | st
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerPoints[]> {
|
export function stakerPoints (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerPoints[]> {
|
||||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerPoints[]> =>
|
return memo((accountId: Uint8Array | string, withActive = false): Observable<DeriveStakerPoints[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._stakerPoints(accountId, eras))
|
switchMap((eras) => api.derive.staking._stakerPoints(accountId, eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,17 +10,18 @@ import BN from 'bn.js';
|
|||||||
import { Observable, combineLatest, of } from 'rxjs';
|
import { Observable, combineLatest, of } from 'rxjs';
|
||||||
import { map, switchMap } from 'rxjs/operators';
|
import { map, switchMap } from 'rxjs/operators';
|
||||||
import { Option } from '@polkadot/types';
|
import { Option } from '@polkadot/types';
|
||||||
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
type Result = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[], DeriveStakerExposure[]];
|
type ErasResult = [{ unwrapOr: (value: BN) => BN }, DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[]];
|
||||||
|
|
||||||
const ZERO = new BN(0);
|
const ZERO = new BN(0);
|
||||||
const MIN_ONE = new BN(-1);
|
const MIN_ONE = new BN(-1);
|
||||||
const COMM_DIV = new BN(1_000_000_000);
|
const COMM_DIV = new BN(1_000_000_000);
|
||||||
const MAX_ERAS = new BN(1_000_000_000);
|
const MAX_ERAS = new BN(1_000_000_000);
|
||||||
|
|
||||||
function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [erasPoints, erasPrefs, erasRewards, exposures]: Result): DeriveStakerReward[] {
|
function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [, erasPoints, erasPrefs, erasRewards]: ErasResult, exposures: DeriveStakerExposure[]): DeriveStakerReward[] {
|
||||||
return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => {
|
return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => {
|
||||||
const { eraPoints, validators: allValPoints } = erasPoints.find((p) => p.era.eq(era)) || { eraPoints: ZERO, validators: {} };
|
const { eraPoints, validators: allValPoints } = erasPoints.find((p) => p.era.eq(era)) || { eraPoints: ZERO, validators: {} };
|
||||||
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: api.registry.createType('Balance') };
|
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: api.registry.createType('Balance') };
|
||||||
@@ -97,28 +98,29 @@ function filterEras (eras: EraIndex[], stakingLedger: StakingLedger): EraIndex[]
|
|||||||
return eras.filter((era) => filterEra(era, stakingLedger));
|
return eras.filter((era) => filterEra(era, stakingLedger));
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], stakingLedger: StakingLedger, withActive?: boolean): Observable<DeriveStakerReward[]> {
|
function filterRewards (api: ApiInterfaceRx, eras: EraIndex[], migrateEra: BN, rewards: DeriveStakerReward[], stakingLedger: StakingLedger, withActive: boolean): Observable<DeriveStakerReward[]> {
|
||||||
if (withActive) {
|
if (withActive) {
|
||||||
return of(rewards);
|
return of(rewards);
|
||||||
}
|
}
|
||||||
|
|
||||||
const validators = uniqValidators(rewards);
|
const validators = uniqValidators(rewards);
|
||||||
|
|
||||||
return combineLatest([
|
return (
|
||||||
api.query.staking.migrateEra
|
isFunction(api.tx.staking.payoutStakers)
|
||||||
? api.query.staking.migrateEra<Option<EraIndex>>()
|
|
||||||
: of({ unwrapOr: () => api.tx.staking.payoutStakers ? ZERO : MAX_ERAS }),
|
|
||||||
api.tx.staking.payoutStakers
|
|
||||||
? api.derive.staking.queryMulti(validators)
|
? api.derive.staking.queryMulti(validators)
|
||||||
: of([])
|
: of([])
|
||||||
]).pipe(
|
).pipe(
|
||||||
map(([optMigrate, queryValidators]): DeriveStakerReward[] => {
|
map((queryValidators): DeriveStakerReward[] => {
|
||||||
const migrateEra: BN = optMigrate.unwrapOr(ZERO);
|
const filter = withActive
|
||||||
|
? eras
|
||||||
|
: filterEras(eras, stakingLedger);
|
||||||
|
|
||||||
return rewards
|
return rewards
|
||||||
.filter(({ isEmpty }) => !isEmpty)
|
.filter(({ isEmpty }) => !isEmpty)
|
||||||
.filter((reward): boolean => {
|
.filter((reward): boolean => {
|
||||||
if (reward.era.lt(migrateEra)) {
|
if (!filter.some((filter) => reward.era.eq(filter))) {
|
||||||
|
return false;
|
||||||
|
} else if (reward.era.lt(migrateEra)) {
|
||||||
// we filter again here, the actual ledger may have changed, e.g. something has been claimed
|
// we filter again here, the actual ledger may have changed, e.g. something has been claimed
|
||||||
return filterEra(reward.era, stakingLedger);
|
return filterEra(reward.era, stakingLedger);
|
||||||
}
|
}
|
||||||
@@ -154,35 +156,41 @@ function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], stak
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive?: boolean) => Observable<DeriveStakerReward[]> {
|
export function _stakerRewardsEras (api: ApiInterfaceRx): (eras: EraIndex[], withActive: boolean) => Observable<ErasResult> {
|
||||||
return memo((accountId: Uint8Array | string, _eras: EraIndex[], withActive?: boolean): Observable<DeriveStakerReward[]> =>
|
return memo((eras: EraIndex[], withActive: boolean): Observable<ErasResult> =>
|
||||||
api.derive.staking.query(accountId).pipe(
|
combineLatest([
|
||||||
switchMap(({ stakingLedger, stashId }): Observable<DeriveStakerReward[]> => {
|
isFunction(api.query.staking.migrateEra)
|
||||||
|
? api.query.staking.migrateEra<Option<EraIndex>>()
|
||||||
|
: of({ unwrapOr: () => isFunction(api.tx.staking.payoutStakers) ? ZERO : MAX_ERAS }),
|
||||||
|
api.derive.staking._erasPoints(eras, withActive),
|
||||||
|
api.derive.staking._erasPrefs(eras, withActive),
|
||||||
|
api.derive.staking._erasRewards(eras, withActive)
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable<DeriveStakerReward[]> {
|
||||||
|
return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable<DeriveStakerReward[]> =>
|
||||||
|
combineLatest([
|
||||||
|
api.derive.staking.query(accountId),
|
||||||
|
api.derive.staking._stakerExposure(accountId, eras, withActive),
|
||||||
|
api.derive.staking._stakerRewardsEras(eras, withActive)
|
||||||
|
]).pipe(
|
||||||
|
switchMap(([{ stakingLedger, stashId }, exposures, erasResult]): Observable<DeriveStakerReward[]> => {
|
||||||
|
const migrateEra: BN = erasResult[0].unwrapOr(ZERO);
|
||||||
|
|
||||||
if (!stashId || !stakingLedger) {
|
if (!stashId || !stakingLedger) {
|
||||||
return of([]);
|
return of([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const eras = withActive
|
return filterRewards(api, eras, migrateEra, parseRewards(api, stashId, erasResult, exposures), stakingLedger, withActive);
|
||||||
? _eras
|
|
||||||
: filterEras(_eras, stakingLedger);
|
|
||||||
|
|
||||||
return combineLatest([
|
|
||||||
api.derive.staking._erasPoints(eras),
|
|
||||||
api.derive.staking._erasPrefs(eras),
|
|
||||||
api.derive.staking._erasRewards(eras),
|
|
||||||
api.derive.staking._stakerExposure(stashId, eras)
|
|
||||||
]).pipe(
|
|
||||||
switchMap((result): Observable<DeriveStakerReward[]> =>
|
|
||||||
filterRewards(api, parseRewards(api, stashId, result), stakingLedger, withActive)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerReward[]> {
|
export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerReward[]> {
|
||||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerReward[]> =>
|
return memo((accountId: Uint8Array | string, withActive = false): Observable<DeriveStakerReward[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._stakerRewards(accountId, eras, withActive))
|
switchMap((eras) => api.derive.staking._stakerRewards(accountId, eras, withActive))
|
||||||
)
|
)
|
||||||
@@ -190,7 +198,7 @@ export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | st
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function stakerRewardsMulti (api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], withActive?: boolean) => Observable<DeriveStakerReward[][]> {
|
export function stakerRewardsMulti (api: ApiInterfaceRx): (accountIds: (Uint8Array | string)[], withActive?: boolean) => Observable<DeriveStakerReward[][]> {
|
||||||
return memo((accountIds: (Uint8Array | string)[], withActive?: boolean): Observable<DeriveStakerReward[][]> =>
|
return memo((accountIds: (Uint8Array | string)[], withActive = false): Observable<DeriveStakerReward[][]> =>
|
||||||
accountIds.length
|
accountIds.length
|
||||||
? api.derive.staking.erasHistoric(withActive).pipe(
|
? api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) =>
|
switchMap((eras) =>
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import { map, switchMap } from 'rxjs/operators';
|
|||||||
|
|
||||||
import { memo } from '../util';
|
import { memo } from '../util';
|
||||||
|
|
||||||
export function _stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[]) => Observable<DeriveStakerSlashes[]> {
|
export function _stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable<DeriveStakerSlashes[]> {
|
||||||
return memo((accountId: Uint8Array | string, eras: EraIndex[]): Observable<DeriveStakerSlashes[]> => {
|
return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable<DeriveStakerSlashes[]> => {
|
||||||
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
||||||
|
|
||||||
return api.derive.staking._erasSlashes(eras).pipe(
|
return api.derive.staking._erasSlashes(eras, withActive).pipe(
|
||||||
map((slashes): DeriveStakerSlashes[] =>
|
map((slashes): DeriveStakerSlashes[] =>
|
||||||
slashes.map(({ era, nominators, validators }): DeriveStakerSlashes => ({
|
slashes.map(({ era, nominators, validators }): DeriveStakerSlashes => ({
|
||||||
era,
|
era,
|
||||||
@@ -27,9 +27,9 @@ export function _stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | s
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerSlashes[]> {
|
export function stakerSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable<DeriveStakerSlashes[]> {
|
||||||
return memo((accountId: Uint8Array | string, withActive?: boolean): Observable<DeriveStakerSlashes[]> =>
|
return memo((accountId: Uint8Array | string, withActive = false): Observable<DeriveStakerSlashes[]> =>
|
||||||
api.derive.staking.erasHistoric(withActive).pipe(
|
api.derive.staking.erasHistoric(withActive).pipe(
|
||||||
switchMap((eras) => api.derive.staking._stakerSlashes(accountId, eras))
|
switchMap((eras) => api.derive.staking._stakerSlashes(accountId, eras, withActive))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import runtimeTypes from '@polkadot/types/interfaces/runtime/definitions';
|
|||||||
import { Struct } from '@polkadot/types';
|
import { Struct } from '@polkadot/types';
|
||||||
|
|
||||||
// We can ignore the properties, added via Struct.with
|
// We can ignore the properties, added via Struct.with
|
||||||
const _Header: Constructor<Header> = Struct.with(runtimeTypes.types.Header as any) as any;
|
const _Header = Struct.with(runtimeTypes.types.Header as any) as Constructor<Header>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name HeaderExtended
|
* @name HeaderExtended
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||||
|
// This software may be modified and distributed under the terms
|
||||||
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
|
import { DeriveCache } from './types';
|
||||||
|
|
||||||
|
import { deriveNoopCache } from './cacheImpl';
|
||||||
|
|
||||||
|
interface CacheValue<T> {
|
||||||
|
v: T;
|
||||||
|
x: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHACHE_EXPIRY = 7 * (24 * 60) * (60 * 1000);
|
||||||
|
|
||||||
|
let deriveCache: DeriveCache;
|
||||||
|
|
||||||
|
function wrapCache (keyStart: string, cache: DeriveCache): DeriveCache {
|
||||||
|
return {
|
||||||
|
del: (partial: string): void => cache.del(`${keyStart}${partial}`),
|
||||||
|
forEach: cache.forEach,
|
||||||
|
get: <T = any> (partial: string): T | undefined => {
|
||||||
|
const key = `${keyStart}${partial}`;
|
||||||
|
const cached = cache.get<CacheValue<T>>(key);
|
||||||
|
|
||||||
|
if (cached) {
|
||||||
|
cached.x = Date.now();
|
||||||
|
cache.set(key, cached);
|
||||||
|
|
||||||
|
return cached.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
set: (partial: string, v: unknown): void => {
|
||||||
|
cache.set(`${keyStart}${partial}`, { v, x: Date.now() });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCache (cache: DeriveCache): void {
|
||||||
|
// clear all expired values
|
||||||
|
const now = Date.now();
|
||||||
|
const all: any[] = [];
|
||||||
|
|
||||||
|
cache.forEach((key: string, { x }: CacheValue<any>): void => {
|
||||||
|
((now - x) > CHACHE_EXPIRY) && all.push(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
// don't do delete inside loop, just in-case
|
||||||
|
all.forEach((key) => cache.del(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setDeriveCache (prefix = '', cache?: DeriveCache): void {
|
||||||
|
deriveCache = cache
|
||||||
|
? wrapCache(`derive:${prefix}:`, cache)
|
||||||
|
: deriveNoopCache;
|
||||||
|
|
||||||
|
if (cache) {
|
||||||
|
clearCache(cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setDeriveCache();
|
||||||
|
|
||||||
|
export { deriveCache };
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||||
|
// This software may be modified and distributed under the terms
|
||||||
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
|
import { DeriveCache } from './types';
|
||||||
|
|
||||||
|
const mapCache = new Map<string, any>();
|
||||||
|
|
||||||
|
const deriveMapCache: DeriveCache = {
|
||||||
|
del: (key: string): void => {
|
||||||
|
mapCache.delete(key);
|
||||||
|
},
|
||||||
|
forEach: (cb: (key: string, value: any) => void): void => {
|
||||||
|
const entries = mapCache.entries();
|
||||||
|
|
||||||
|
for (const entry in entries) {
|
||||||
|
cb(entry[0], entry[1]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get: <T = any> (key: string): T | undefined => {
|
||||||
|
return mapCache.get(key) as T;
|
||||||
|
},
|
||||||
|
set: (key: string, value: any): void => {
|
||||||
|
mapCache.set(key, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deriveNoopCache: DeriveCache = {
|
||||||
|
del: (): void => undefined,
|
||||||
|
forEach: () => undefined,
|
||||||
|
get: (): undefined => undefined,
|
||||||
|
set: (_: string, value: unknown): unknown => value
|
||||||
|
};
|
||||||
|
|
||||||
|
export { deriveMapCache, deriveNoopCache };
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
import { drr } from '@polkadot/rpc-core/rxjs';
|
import { drr } from '@polkadot/rpc-core/rxjs';
|
||||||
|
|
||||||
export * from './approvalFlagsToBools';
|
export * from './approvalFlagsToBools';
|
||||||
|
export * from './cache';
|
||||||
|
export * from './cacheImpl';
|
||||||
export * from './memo';
|
export * from './memo';
|
||||||
|
|
||||||
export { drr };
|
export { drr };
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||||
|
// This software may be modified and distributed under the terms
|
||||||
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
|
export interface DeriveCache {
|
||||||
|
del: (key: string) => void;
|
||||||
|
forEach: (cb: (key: string, value: any) => void) => void;
|
||||||
|
get: <T = any> (key: string) => T | undefined;
|
||||||
|
set: (key: string, value: any) => void;
|
||||||
|
}
|
||||||
+13
-13
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@polkadot/api",
|
"name": "@polkadot/api",
|
||||||
"version": "1.14.1",
|
"version": "1.16.1",
|
||||||
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
|
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -27,20 +27,20 @@
|
|||||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.9.6",
|
"@babel/runtime": "^7.9.6",
|
||||||
"@polkadot/api-derive": "1.14.1",
|
"@polkadot/api-derive": "1.16.1",
|
||||||
"@polkadot/keyring": "^2.10.1",
|
"@polkadot/keyring": "^2.11.1",
|
||||||
"@polkadot/metadata": "1.14.1",
|
"@polkadot/metadata": "1.16.1",
|
||||||
"@polkadot/rpc-core": "1.14.1",
|
"@polkadot/rpc-core": "1.16.1",
|
||||||
"@polkadot/rpc-provider": "1.14.1",
|
"@polkadot/rpc-provider": "1.16.1",
|
||||||
"@polkadot/types": "1.14.1",
|
"@polkadot/types": "1.16.1",
|
||||||
"@polkadot/types-known": "1.14.1",
|
"@polkadot/types-known": "1.16.1",
|
||||||
"@polkadot/util": "^2.10.1",
|
"@polkadot/util": "^2.11.1",
|
||||||
"@polkadot/util-crypto": "^2.10.1",
|
"@polkadot/util-crypto": "^2.11.1",
|
||||||
"bn.js": "^5.1.1",
|
"bn.js": "^5.1.2",
|
||||||
"eventemitter3": "^4.0.1",
|
"eventemitter3": "^4.0.4",
|
||||||
"rxjs": "^6.5.5"
|
"rxjs": "^6.5.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/keyring": "^2.10.1"
|
"@polkadot/keyring": "^2.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
import { Codec } from '@polkadot/types/types';
|
import { Codec } from '@polkadot/types/types';
|
||||||
|
import { Vec } from '@polkadot/types/codec';
|
||||||
import { u32, u64 } from '@polkadot/types/primitive';
|
import { u32, u64 } from '@polkadot/types/primitive';
|
||||||
import { Balance, BalanceOf, BlockNumber, LockIdentifier, ModuleId, Moment, Percent, Permill, RuntimeDbWeight, Weight } from '@polkadot/types/interfaces/runtime';
|
import { Balance, BalanceOf, BlockNumber, LockIdentifier, ModuleId, Moment, Percent, Permill, RuntimeDbWeight, Weight } from '@polkadot/types/interfaces/runtime';
|
||||||
import { SessionIndex } from '@polkadot/types/interfaces/session';
|
import { SessionIndex } from '@polkadot/types/interfaces/session';
|
||||||
import { EraIndex } from '@polkadot/types/interfaces/staking';
|
import { EraIndex } from '@polkadot/types/interfaces/staking';
|
||||||
|
import { WeightToFeeCoefficient } from '@polkadot/types/interfaces/support';
|
||||||
|
|
||||||
declare module '@polkadot/metadata/Decorated/consts/types' {
|
declare module '@polkadot/metadata/Decorated/consts/types' {
|
||||||
export interface Constants {
|
export interface Constants {
|
||||||
@@ -102,6 +104,10 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
|||||||
* How often (in blocks) new public referenda are launched.
|
* How often (in blocks) new public referenda are launched.
|
||||||
**/
|
**/
|
||||||
launchPeriod: AugmentedConst<BlockNumber>;
|
launchPeriod: AugmentedConst<BlockNumber>;
|
||||||
|
/**
|
||||||
|
* The maximum number of votes for an account.
|
||||||
|
**/
|
||||||
|
maxVotes: AugmentedConst<u32>;
|
||||||
/**
|
/**
|
||||||
* The minimum amount to be used as a deposit for a public referendum proposal.
|
* The minimum amount to be used as a deposit for a public referendum proposal.
|
||||||
**/
|
**/
|
||||||
@@ -253,6 +259,10 @@ declare module '@polkadot/metadata/Decorated/consts/types' {
|
|||||||
* The fee to be paid for making a transaction; the per-byte portion.
|
* The fee to be paid for making a transaction; the per-byte portion.
|
||||||
**/
|
**/
|
||||||
transactionByteFee: AugmentedConst<BalanceOf>;
|
transactionByteFee: AugmentedConst<BalanceOf>;
|
||||||
|
/**
|
||||||
|
* The polynomial that is applied in order to derive fee from weight.
|
||||||
|
**/
|
||||||
|
weightToFee: AugmentedConst<Vec<WeightToFeeCoefficient>>;
|
||||||
};
|
};
|
||||||
treasury: {
|
treasury: {
|
||||||
[index: string]: AugmentedConst<object & Codec>;
|
[index: string]: AugmentedConst<object & Codec>;
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import { AnyNumber, ITuple, Observable } from '@polkadot/types/types';
|
|||||||
import { Option, U8aFixed, Vec } from '@polkadot/types/codec';
|
import { Option, U8aFixed, Vec } from '@polkadot/types/codec';
|
||||||
import { Bytes, Data, bool, u32, u64 } from '@polkadot/types/primitive';
|
import { Bytes, Data, bool, u32, u64 } from '@polkadot/types/primitive';
|
||||||
import { UncleEntryItem } from '@polkadot/types/interfaces/authorship';
|
import { UncleEntryItem } from '@polkadot/types/interfaces/authorship';
|
||||||
import { BabeAuthorityWeight, MaybeRandomness, Randomness } from '@polkadot/types/interfaces/babe';
|
import { BabeAuthorityWeight, MaybeRandomness, NextConfigDescriptor, Randomness } from '@polkadot/types/interfaces/babe';
|
||||||
import { AccountData, BalanceLock, ReleasesBalances } from '@polkadot/types/interfaces/balances';
|
import { AccountData, BalanceLock, ReleasesBalances } from '@polkadot/types/interfaces/balances';
|
||||||
import { ProposalIndex, Votes } from '@polkadot/types/interfaces/collective';
|
import { ProposalIndex, Votes } from '@polkadot/types/interfaces/collective';
|
||||||
import { AuthorityId } from '@polkadot/types/interfaces/consensus';
|
import { AuthorityId } from '@polkadot/types/interfaces/consensus';
|
||||||
import { CodeHash, ContractInfo, PrefabWasmModule, Schedule } from '@polkadot/types/interfaces/contracts';
|
import { CodeHash, ContractInfo, PrefabWasmModule, Schedule } from '@polkadot/types/interfaces/contracts';
|
||||||
import { PreimageStatus, PropIndex, Proposal, ProxyState, ReferendumIndex, ReferendumInfo, Voting } from '@polkadot/types/interfaces/democracy';
|
import { PreimageStatus, PropIndex, Proposal, ProxyState, ReferendumIndex, ReferendumInfo, ReleasesDemocracy, Voting } from '@polkadot/types/interfaces/democracy';
|
||||||
import { VoteThreshold } from '@polkadot/types/interfaces/elections';
|
import { VoteThreshold } from '@polkadot/types/interfaces/elections';
|
||||||
import { SetId, StoredPendingChange, StoredState } from '@polkadot/types/interfaces/grandpa';
|
import { SetId, StoredPendingChange, StoredState } from '@polkadot/types/interfaces/grandpa';
|
||||||
import { RegistrarInfo, Registration } from '@polkadot/types/interfaces/identity';
|
import { RegistrarInfo, Registration } from '@polkadot/types/interfaces/identity';
|
||||||
@@ -78,6 +78,10 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
* execution context should always yield zero.
|
* execution context should always yield zero.
|
||||||
**/
|
**/
|
||||||
lateness: AugmentedQuery<ApiType, () => Observable<BlockNumber>> & QueryableStorageEntry<ApiType>;
|
lateness: AugmentedQuery<ApiType, () => Observable<BlockNumber>> & QueryableStorageEntry<ApiType>;
|
||||||
|
/**
|
||||||
|
* Next epoch configuration, if changed.
|
||||||
|
**/
|
||||||
|
nextEpochConfig: AugmentedQuery<ApiType, () => Observable<Option<NextConfigDescriptor>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* Next epoch randomness.
|
* Next epoch randomness.
|
||||||
**/
|
**/
|
||||||
@@ -107,6 +111,9 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
* epoch.
|
* epoch.
|
||||||
**/
|
**/
|
||||||
segmentIndex: AugmentedQuery<ApiType, () => Observable<u32>> & QueryableStorageEntry<ApiType>;
|
segmentIndex: AugmentedQuery<ApiType, () => Observable<u32>> & QueryableStorageEntry<ApiType>;
|
||||||
|
/**
|
||||||
|
* TWOX-NOTE: `SegmentIndex` is an increasing integer, so this is okay.
|
||||||
|
**/
|
||||||
underConstruction: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Vec<Randomness>>> & QueryableStorageEntry<ApiType>;
|
underConstruction: AugmentedQuery<ApiType, (arg: u32 | AnyNumber | Uint8Array) => Observable<Vec<Randomness>>> & QueryableStorageEntry<ApiType>;
|
||||||
};
|
};
|
||||||
balances: {
|
balances: {
|
||||||
@@ -148,6 +155,8 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
codeStorage: AugmentedQuery<ApiType, (arg: CodeHash | string | Uint8Array) => Observable<Option<PrefabWasmModule>>> & QueryableStorageEntry<ApiType>;
|
codeStorage: AugmentedQuery<ApiType, (arg: CodeHash | string | Uint8Array) => Observable<Option<PrefabWasmModule>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* The code associated with a given account.
|
* The code associated with a given account.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: SAFE since `AccountId` is a secure hash.
|
||||||
**/
|
**/
|
||||||
contractInfoOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<ContractInfo>>> & QueryableStorageEntry<ApiType>;
|
contractInfoOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<ContractInfo>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
@@ -200,8 +209,10 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
cancellations: AugmentedQuery<ApiType, (arg: Hash | string | Uint8Array) => Observable<bool>> & QueryableStorageEntry<ApiType>;
|
cancellations: AugmentedQuery<ApiType, (arg: Hash | string | Uint8Array) => Observable<bool>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* Those who have locked a deposit.
|
* Those who have locked a deposit.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: Safe, as increasing integer keys are safe.
|
||||||
**/
|
**/
|
||||||
depositOf: AugmentedQuery<ApiType, (arg: PropIndex | AnyNumber | Uint8Array) => Observable<Option<ITuple<[BalanceOf, Vec<AccountId>]>>>> & QueryableStorageEntry<ApiType>;
|
depositOf: AugmentedQuery<ApiType, (arg: PropIndex | AnyNumber | Uint8Array) => Observable<Option<ITuple<[Vec<AccountId>, BalanceOf]>>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* True if the last referendum tabled was submitted externally. False if it was a public
|
* True if the last referendum tabled was submitted externally. False if it was a public
|
||||||
* proposal.
|
* proposal.
|
||||||
@@ -210,6 +221,8 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
/**
|
/**
|
||||||
* Accounts for which there are locks in action which may be removed at some point in the
|
* Accounts for which there are locks in action which may be removed at some point in the
|
||||||
* future. The value is the block number at which the lock expires and may be removed.
|
* future. The value is the block number at which the lock expires and may be removed.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: OK ― `AccountId` is a secure hash.
|
||||||
**/
|
**/
|
||||||
locks: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<BlockNumber>>> & QueryableStorageEntry<ApiType>;
|
locks: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<BlockNumber>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
@@ -232,6 +245,8 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
/**
|
/**
|
||||||
* Who is able to vote for whom. Value is the fund-holding account, key is the
|
* Who is able to vote for whom. Value is the fund-holding account, key is the
|
||||||
* vote-transaction-sending account.
|
* vote-transaction-sending account.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: OK ― `AccountId` is a secure hash.
|
||||||
**/
|
**/
|
||||||
proxy: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<ProxyState>>> & QueryableStorageEntry<ApiType>;
|
proxy: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<ProxyState>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
@@ -248,11 +263,21 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
referendumCount: AugmentedQuery<ApiType, () => Observable<ReferendumIndex>> & QueryableStorageEntry<ApiType>;
|
referendumCount: AugmentedQuery<ApiType, () => Observable<ReferendumIndex>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* Information concerning any given referendum.
|
* Information concerning any given referendum.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: SAFE as indexes are not under an attacker’s control.
|
||||||
**/
|
**/
|
||||||
referendumInfoOf: AugmentedQuery<ApiType, (arg: ReferendumIndex | AnyNumber | Uint8Array) => Observable<Option<ReferendumInfo>>> & QueryableStorageEntry<ApiType>;
|
referendumInfoOf: AugmentedQuery<ApiType, (arg: ReferendumIndex | AnyNumber | Uint8Array) => Observable<Option<ReferendumInfo>>> & QueryableStorageEntry<ApiType>;
|
||||||
|
/**
|
||||||
|
* Storage version of the pallet.
|
||||||
|
*
|
||||||
|
* New networks start with last version.
|
||||||
|
**/
|
||||||
|
storageVersion: AugmentedQuery<ApiType, () => Observable<Option<ReleasesDemocracy>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* All votes for a particular voter. We store the balance for the number of votes that we
|
* All votes for a particular voter. We store the balance for the number of votes that we
|
||||||
* have recorded. The second item is the total amount of delegations, that will be added.
|
* have recorded. The second item is the total amount of delegations, that will be added.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: SAFE as `AccountId`s are crypto hashes anyway.
|
||||||
**/
|
**/
|
||||||
votingOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Voting>> & QueryableStorageEntry<ApiType>;
|
votingOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Voting>> & QueryableStorageEntry<ApiType>;
|
||||||
};
|
};
|
||||||
@@ -277,6 +302,8 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
runnersUp: AugmentedQuery<ApiType, () => Observable<Vec<ITuple<[AccountId, BalanceOf]>>>> & QueryableStorageEntry<ApiType>;
|
runnersUp: AugmentedQuery<ApiType, () => Observable<Vec<ITuple<[AccountId, BalanceOf]>>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* Votes and locked stake of a particular voter.
|
* Votes and locked stake of a particular voter.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: SAFE as `AccountId` is a crypto hash
|
||||||
**/
|
**/
|
||||||
voting: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<ITuple<[BalanceOf, Vec<AccountId>]>>> & QueryableStorageEntry<ApiType>;
|
voting: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<ITuple<[BalanceOf, Vec<AccountId>]>>> & QueryableStorageEntry<ApiType>;
|
||||||
};
|
};
|
||||||
@@ -298,6 +325,8 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
/**
|
/**
|
||||||
* A mapping from grandpa set ID to the index of the *most recent* session for which its
|
* A mapping from grandpa set ID to the index of the *most recent* session for which its
|
||||||
* members were responsible.
|
* members were responsible.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: `SetId` is not under user control.
|
||||||
**/
|
**/
|
||||||
setIdSession: AugmentedQuery<ApiType, (arg: SetId | AnyNumber | Uint8Array) => Observable<Option<SessionIndex>>> & QueryableStorageEntry<ApiType>;
|
setIdSession: AugmentedQuery<ApiType, (arg: SetId | AnyNumber | Uint8Array) => Observable<Option<SessionIndex>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
@@ -313,6 +342,8 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
[index: string]: QueryableStorageEntry<ApiType>;
|
[index: string]: QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* Information that is pertinent to identify the entity behind an account.
|
* Information that is pertinent to identify the entity behind an account.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: OK ― `AccountId` is a secure hash.
|
||||||
**/
|
**/
|
||||||
identityOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<Registration>>> & QueryableStorageEntry<ApiType>;
|
identityOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<Registration>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
@@ -326,6 +357,8 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
* Alternative "sub" identities of this account.
|
* Alternative "sub" identities of this account.
|
||||||
*
|
*
|
||||||
* The first item is the deposit, the second is a vector of the accounts.
|
* The first item is the deposit, the second is a vector of the accounts.
|
||||||
|
*
|
||||||
|
* TWOX-NOTE: OK ― `AccountId` is a secure hash.
|
||||||
**/
|
**/
|
||||||
subsOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<ITuple<[BalanceOf, Vec<AccountId>]>>> & QueryableStorageEntry<ApiType>;
|
subsOf: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<ITuple<[BalanceOf, Vec<AccountId>]>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
@@ -753,14 +786,14 @@ declare module '@polkadot/api/types/storage' {
|
|||||||
* Total length (in bytes) for all extrinsics put together, for the current block.
|
* Total length (in bytes) for all extrinsics put together, for the current block.
|
||||||
**/
|
**/
|
||||||
allExtrinsicsLen: AugmentedQuery<ApiType, () => Observable<Option<u32>>> & QueryableStorageEntry<ApiType>;
|
allExtrinsicsLen: AugmentedQuery<ApiType, () => Observable<Option<u32>>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
|
||||||
* Total weight for all extrinsics for the current block.
|
|
||||||
**/
|
|
||||||
allExtrinsicsWeight: AugmentedQuery<ApiType, () => Observable<ExtrinsicsWeight>> & QueryableStorageEntry<ApiType>;
|
|
||||||
/**
|
/**
|
||||||
* Map of block numbers to block hashes.
|
* Map of block numbers to block hashes.
|
||||||
**/
|
**/
|
||||||
blockHash: AugmentedQuery<ApiType, (arg: BlockNumber | AnyNumber | Uint8Array) => Observable<Hash>> & QueryableStorageEntry<ApiType>;
|
blockHash: AugmentedQuery<ApiType, (arg: BlockNumber | AnyNumber | Uint8Array) => Observable<Hash>> & QueryableStorageEntry<ApiType>;
|
||||||
|
/**
|
||||||
|
* The current weight for the block.
|
||||||
|
**/
|
||||||
|
blockWeight: AugmentedQuery<ApiType, () => Observable<ExtrinsicsWeight>> & QueryableStorageEntry<ApiType>;
|
||||||
/**
|
/**
|
||||||
* Digest of the current block, also part of the block header.
|
* Digest of the current block, also part of the block header.
|
||||||
**/
|
**/
|
||||||
|
|||||||
+579
-161
File diff suppressed because it is too large
Load Diff
@@ -15,14 +15,13 @@ import { map, switchMap, take, tap, toArray } from 'rxjs/operators';
|
|||||||
import decorateDerive, { ExactDerive } from '@polkadot/api-derive';
|
import decorateDerive, { ExactDerive } from '@polkadot/api-derive';
|
||||||
import { memo } from '@polkadot/api-derive/util';
|
import { memo } from '@polkadot/api-derive/util';
|
||||||
import DecoratedMeta from '@polkadot/metadata/Decorated';
|
import DecoratedMeta from '@polkadot/metadata/Decorated';
|
||||||
import getHasher from '@polkadot/metadata/Decorated/storage/fromMetadata/getHasher';
|
|
||||||
import RpcCore from '@polkadot/rpc-core';
|
import RpcCore from '@polkadot/rpc-core';
|
||||||
import { WsProvider } from '@polkadot/rpc-provider';
|
import { WsProvider } from '@polkadot/rpc-provider';
|
||||||
import { Metadata, Null, Option, Raw, Text, TypeRegistry, u64 } from '@polkadot/types';
|
import { Metadata, Null, Option, Raw, Text, TypeRegistry, u64 } from '@polkadot/types';
|
||||||
import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage';
|
import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage';
|
||||||
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/extrinsic/constants';
|
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/extrinsic/constants';
|
||||||
import StorageKey, { StorageEntry, unwrapStorageType } from '@polkadot/types/primitive/StorageKey';
|
import StorageKey, { StorageEntry, unwrapStorageType } from '@polkadot/types/primitive/StorageKey';
|
||||||
import { assert, compactStripLength, isNull, isUndefined, logger, u8aConcat, u8aToHex } from '@polkadot/util';
|
import { assert, compactStripLength, logger, u8aToHex } from '@polkadot/util';
|
||||||
|
|
||||||
import { createSubmittable } from '../submittable';
|
import { createSubmittable } from '../submittable';
|
||||||
import augmentObject from '../util/augmentObject';
|
import augmentObject from '../util/augmentObject';
|
||||||
@@ -32,7 +31,7 @@ import Events from './Events';
|
|||||||
|
|
||||||
interface MetaDecoration {
|
interface MetaDecoration {
|
||||||
callIndex?: Uint8Array;
|
callIndex?: Uint8Array;
|
||||||
meta: any;
|
meta: Record<string, unknown>;
|
||||||
method: string;
|
method: string;
|
||||||
section: string;
|
section: string;
|
||||||
toJSON: () => any;
|
toJSON: () => any;
|
||||||
@@ -247,9 +246,9 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
)
|
)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
.forEach(([_, { method, section }]): void => {
|
.forEach(([_, { method, section }]): void => {
|
||||||
delete (this._rpc as any)[section][method];
|
delete (this._rpc as Record<string, Record<string, unknown>>)[section][method];
|
||||||
delete (this._rpcCore as any)[section][method];
|
delete (this._rpcCore as unknown as Record<string, Record<string, unknown>>)[section][method];
|
||||||
delete (this._rx.rpc as any)[section][method];
|
delete (this._rx.rpc as Record<string, Record<string, unknown>>)[section][method];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,11 +257,12 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
const sectionName = _sectionName as keyof DecoratedRpc<ApiType, RpcInterface>;
|
const sectionName = _sectionName as keyof DecoratedRpc<ApiType, RpcInterface>;
|
||||||
|
|
||||||
// out and section here are horrors to get right from a typing perspective :(
|
// out and section here are horrors to get right from a typing perspective :(
|
||||||
(out as any)[sectionName] = Object.entries(rpc[sectionName]).reduce((section, [methodName, method]): DecoratedRpcSection<ApiType, RpcInterface[typeof sectionName]> => {
|
(out as Record<string, unknown>)[sectionName] = Object.entries(rpc[sectionName]).reduce((section, [methodName, method]): DecoratedRpcSection<ApiType, RpcInterface[typeof sectionName]> => {
|
||||||
// skip subscriptions where we have a non-subscribe interface
|
// skip subscriptions where we have a non-subscribe interface
|
||||||
if (this.hasSubscriptions || !(methodName.startsWith('subscribe') || methodName.startsWith('unsubscribe'))) {
|
if (this.hasSubscriptions || !(methodName.startsWith('subscribe') || methodName.startsWith('unsubscribe'))) {
|
||||||
(section as any)[methodName] = decorateMethod(method, { methodName });
|
(section as Record<string, unknown>)[methodName] = decorateMethod(method, { methodName }) as unknown;
|
||||||
(section as any)[methodName].raw = decorateMethod(method.raw, { methodName });
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
|
(section as Record<string, { raw: unknown }>)[methodName].raw = decorateMethod(method.raw, { methodName }) as unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
return section;
|
return section;
|
||||||
@@ -273,10 +273,12 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected _decorateMulti<ApiType extends ApiTypes> (decorateMethod: DecorateMethod<ApiType>): QueryableStorageMulti<ApiType> {
|
protected _decorateMulti<ApiType extends ApiTypes> (decorateMethod: DecorateMethod<ApiType>): QueryableStorageMulti<ApiType> {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
return decorateMethod((calls: QueryableStorageMultiArg<ApiType>[]): Observable<Codec[]> =>
|
return decorateMethod((calls: QueryableStorageMultiArg<ApiType>[]): Observable<Codec[]> =>
|
||||||
this._rpcCore.state.subscribeStorage(
|
this._rpcCore.state.subscribeStorage(
|
||||||
calls.map((arg: QueryableStorageMultiArg<ApiType>): [QueryableStorageEntry<ApiType>, ...Arg[]] =>
|
calls.map((arg: QueryableStorageMultiArg<ApiType>): [QueryableStorageEntry<ApiType>, ...Arg[]] =>
|
||||||
// the input is a QueryableStorageEntry, convert to StorageEntry
|
// the input is a QueryableStorageEntry, convert to StorageEntry
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
Array.isArray(arg)
|
Array.isArray(arg)
|
||||||
? [arg[0].creator, ...arg.slice(1)]
|
? [arg[0].creator, ...arg.slice(1)]
|
||||||
: [arg.creator] as any)));
|
: [arg.creator] as any)));
|
||||||
@@ -300,7 +302,8 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
const decorated = (...params: Arg[]): SubmittableExtrinsic<ApiType> =>
|
const decorated = (...params: Arg[]): SubmittableExtrinsic<ApiType> =>
|
||||||
creator(method(...params));
|
creator(method(...params));
|
||||||
|
|
||||||
return this._decorateFunctionMeta(method, decorated as any) as SubmittableExtrinsicFunction<ApiType>;
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
|
return this._decorateFunctionMeta(method as any, decorated as any) as unknown as SubmittableExtrinsicFunction<ApiType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _decorateStorage<ApiType extends ApiTypes> (storage: Storage, decorateMethod: DecorateMethod<ApiType>): QueryableStorage<ApiType> {
|
protected _decorateStorage<ApiType extends ApiTypes> (storage: Storage, decorateMethod: DecorateMethod<ApiType>): QueryableStorage<ApiType> {
|
||||||
@@ -320,6 +323,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
const getArgs = (...args: any[]): any[] => extractStorageArgs(creator, args);
|
const getArgs = (...args: any[]): any[] => extractStorageArgs(creator, args);
|
||||||
|
|
||||||
// FIXME We probably want to be able to query the full list with non-subs as well
|
// FIXME We probably want to be able to query the full list with non-subs as well
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
const decorated = this.hasSubscriptions && creator.iterKey && creator.meta.type.isMap && creator.meta.type.asMap.linked.isTrue
|
const decorated = this.hasSubscriptions && creator.iterKey && creator.meta.type.isMap && creator.meta.type.asMap.linked.isTrue
|
||||||
? this._decorateStorageLinked(creator, decorateMethod)
|
? this._decorateStorageLinked(creator, decorateMethod)
|
||||||
: decorateMethod((...args: any[]): Observable<Codec> => (
|
: decorateMethod((...args: any[]): Observable<Codec> => (
|
||||||
@@ -333,32 +337,41 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
: this._rpcCore.state.getStorage(getArgs(...args))
|
: this._rpcCore.state.getStorage(getArgs(...args))
|
||||||
), { methodName: creator.method });
|
), { methodName: creator.method });
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
decorated.creator = creator;
|
decorated.creator = creator;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
decorated.at = decorateMethod((hash: Hash, arg1?: Arg, arg2?: Arg): Observable<Codec> =>
|
decorated.at = decorateMethod((hash: Hash, arg1?: Arg, arg2?: Arg): Observable<Codec> =>
|
||||||
this._rpcCore.state.getStorage(getArgs(arg1, arg2), hash));
|
this._rpcCore.state.getStorage(getArgs(arg1, arg2), hash));
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
decorated.hash = decorateMethod((arg1?: Arg, arg2?: Arg): Observable<Hash> =>
|
decorated.hash = decorateMethod((arg1?: Arg, arg2?: Arg): Observable<Hash> =>
|
||||||
this._rpcCore.state.getStorageHash(getArgs(arg1, arg2)));
|
this._rpcCore.state.getStorageHash(getArgs(arg1, arg2)));
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
decorated.key = (arg1?: Arg, arg2?: Arg): string =>
|
decorated.key = (arg1?: Arg, arg2?: Arg): string =>
|
||||||
u8aToHex(compactStripLength(creator(creator.meta.type.isDoubleMap ? [arg1, arg2] : arg1))[1]);
|
u8aToHex(compactStripLength(creator(creator.meta.type.isDoubleMap ? [arg1, arg2] : arg1))[1]);
|
||||||
|
|
||||||
decorated.keyPrefix = (): string =>
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
u8aToHex(creator.keyPrefix);
|
decorated.keyPrefix = (key1?: Arg): string =>
|
||||||
|
u8aToHex(creator.keyPrefix(key1));
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
decorated.range = decorateMethod((range: [Hash, Hash?], arg1?: Arg, arg2?: Arg): Observable<[Hash, Codec][]> =>
|
decorated.range = decorateMethod((range: [Hash, Hash?], arg1?: Arg, arg2?: Arg): Observable<[Hash, Codec][]> =>
|
||||||
this._decorateStorageRange(decorated, [arg1, arg2], range));
|
this._decorateStorageRange(decorated, [arg1, arg2], range));
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
decorated.size = decorateMethod((arg1?: Arg, arg2?: Arg): Observable<u64> =>
|
decorated.size = decorateMethod((arg1?: Arg, arg2?: Arg): Observable<u64> =>
|
||||||
this._rpcCore.state.getStorageSize(getArgs(arg1, arg2)));
|
this._rpcCore.state.getStorageSize(getArgs(arg1, arg2)));
|
||||||
|
|
||||||
// .keys() & .entries() only available on map types
|
// .keys() & .entries() only available on map types
|
||||||
if (creator.iterKey && (creator.meta.type.isMap || creator.meta.type.isDoubleMap)) {
|
if (creator.iterKey && (creator.meta.type.isMap || creator.meta.type.isDoubleMap)) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
decorated.entries = decorateMethod(
|
decorated.entries = decorateMethod(
|
||||||
memo((doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> =>
|
memo((doubleMapArg?: Arg): Observable<[StorageKey, Codec][]> =>
|
||||||
this._retrieveMapEntries(creator, doubleMapArg)));
|
this._retrieveMapEntries(creator, doubleMapArg)));
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
decorated.keys = decorateMethod(
|
decorated.keys = decorateMethod(
|
||||||
memo((doubleMapArg?: Arg): Observable<StorageKey[]> =>
|
memo((doubleMapArg?: Arg): Observable<StorageKey[]> =>
|
||||||
this._retrieveMapKeys(creator, doubleMapArg)));
|
this._retrieveMapKeys(creator, doubleMapArg)));
|
||||||
@@ -367,12 +380,13 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
// only support multi where subs are available
|
// only support multi where subs are available
|
||||||
if (this.hasSubscriptions) {
|
if (this.hasSubscriptions) {
|
||||||
// When using double map storage function, user need to pass double map key as an array
|
// When using double map storage function, user need to pass double map key as an array
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
decorated.multi = decorateMethod((args: (Arg | Arg[])[]): Observable<Codec[]> =>
|
decorated.multi = decorateMethod((args: (Arg | Arg[])[]): Observable<Codec[]> =>
|
||||||
this._rpcCore.state.subscribeStorage(
|
this._rpcCore.state.subscribeStorage(
|
||||||
args.map((arg: Arg[] | Arg): [StorageEntry, Arg | Arg[]] => [creator, arg])));
|
args.map((arg: Arg[] | Arg): [StorageEntry, Arg | Arg[]] => [creator, arg])));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._decorateFunctionMeta(creator, decorated) as unknown as QueryableStorageEntry<ApiType>;
|
return this._decorateFunctionMeta(creator as any, decorated) as unknown as QueryableStorageEntry<ApiType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _decorateStorageRange<ApiType extends ApiTypes> (decorated: QueryableStorageEntry<ApiType>, args: [Arg?, Arg?], range: [Hash, Hash?]): Observable<[Hash, Codec][]> {
|
private _decorateStorageRange<ApiType extends ApiTypes> (decorated: QueryableStorageEntry<ApiType>, args: [Arg?, Arg?], range: [Hash, Hash?]): Observable<[Hash, Codec][]> {
|
||||||
@@ -389,9 +403,12 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _decorateStorageLinked<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): ReturnType<DecorateMethod<ApiType>> {
|
private _decorateStorageLinked<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): ReturnType<DecorateMethod<ApiType>> {
|
||||||
const result: Map<Codec, ITuple<[Codec, Linkage<Codec>]> | null> = new Map();
|
const result = new Map<Codec, ITuple<[Codec, Linkage<Codec>]> | null>();
|
||||||
let subject: BehaviorSubject<LinkageResult>;
|
let subject: BehaviorSubject<LinkageResult>;
|
||||||
let head: Codec | null = null;
|
let head: Codec | null = null;
|
||||||
|
const iterKey = creator.iterKey;
|
||||||
|
|
||||||
|
assert(iterKey, 'iterKey field is missing');
|
||||||
|
|
||||||
// retrieve a value based on the key, iterating if it has a next entry. Since
|
// retrieve a value based on the key, iterating if it has a next entry. Since
|
||||||
// entries can be re-linked in the middle of a list, we subscribe here to make
|
// entries can be re-linked in the middle of a list, we subscribe here to make
|
||||||
@@ -449,13 +466,15 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
|
|
||||||
// this handles the case where the head changes effectively, i.e. a new entry
|
// this handles the case where the head changes effectively, i.e. a new entry
|
||||||
// appears at the top of the list, the new getNext gets kicked off
|
// appears at the top of the list, the new getNext gets kicked off
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
return decorateMethod((...args: any[]): Observable<LinkageResult | [Codec, Linkage<Codec>]> =>
|
return decorateMethod((...args: any[]): Observable<LinkageResult | [Codec, Linkage<Codec>]> =>
|
||||||
args.length
|
args.length
|
||||||
? this._rpcCore.state
|
? this._rpcCore.state
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
.subscribeStorage<[[Codec, Linkage<Codec>]]>([[creator, ...args]])
|
.subscribeStorage<[[Codec, Linkage<Codec>]]>([[creator, ...args]])
|
||||||
.pipe(map(([data]): [Codec, Linkage<Codec>] => data))
|
.pipe(map(([data]): [Codec, Linkage<Codec>] => data))
|
||||||
: this._rpcCore.state
|
: this._rpcCore.state
|
||||||
.subscribeStorage<[LinkageResult]>([creator.iterKey])
|
.subscribeStorage<[LinkageResult]>([iterKey()])
|
||||||
.pipe(switchMap(([key]): Observable<LinkageResult> => getNext(head = key)))
|
.pipe(switchMap(([key]): Observable<LinkageResult> => getNext(head = key)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -463,14 +482,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
|
|||||||
private _retrieveMapKeys ({ iterKey, meta }: StorageEntry, arg?: Arg): Observable<StorageKey[]> {
|
private _retrieveMapKeys ({ iterKey, meta }: StorageEntry, arg?: Arg): Observable<StorageKey[]> {
|
||||||
assert(iterKey && (meta.type.isMap || meta.type.isDoubleMap), 'keys can only be retrieved on maps, linked maps and double maps');
|
assert(iterKey && (meta.type.isMap || meta.type.isDoubleMap), 'keys can only be retrieved on maps, linked maps and double maps');
|
||||||
|
|
||||||
const headKey = this.createType('Raw', u8aConcat(
|
const headKey = iterKey(arg).toHex();
|
||||||
iterKey,
|
|
||||||
meta.type.isDoubleMap && !isUndefined(arg) && !isNull(arg)
|
|
||||||
? getHasher(meta.type.asDoubleMap.hasher)(
|
|
||||||
this.createType(meta.type.asDoubleMap.key1.toString() as 'Raw', arg).toU8a()
|
|
||||||
)
|
|
||||||
: new Uint8Array([])
|
|
||||||
)).toHex();
|
|
||||||
const startSubject = new BehaviorSubject<string>(headKey);
|
const startSubject = new BehaviorSubject<string>(headKey);
|
||||||
|
|
||||||
return this._rpcCore.state.getKeysPaged
|
return this._rpcCore.state.getKeysPaged
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
|||||||
// 'connected' event, then the `on('connected')` won't fire anymore. To
|
// 'connected' event, then the `on('connected')` won't fire anymore. To
|
||||||
// cater for this case, we call manually `this._onProviderConnect`.
|
// cater for this case, we call manually `this._onProviderConnect`.
|
||||||
if (this._rpcCore.provider.isConnected()) {
|
if (this._rpcCore.provider.isConnected()) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.#onProviderConnect();
|
this.#onProviderConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
|||||||
// manually build a list of all available methods in this RPC, we are
|
// manually build a list of all available methods in this RPC, we are
|
||||||
// going to filter on it to align the cloned RPC without making a call
|
// going to filter on it to align the cloned RPC without making a call
|
||||||
Object.keys(source.rpc).forEach((section): void => {
|
Object.keys(source.rpc).forEach((section): void => {
|
||||||
Object.keys((source.rpc as any)[section]).forEach((method): void => {
|
Object.keys((source.rpc as Record<string, Record<string, unknown>>)[section]).forEach((method): void => {
|
||||||
methods.push(`${section}_${method}`);
|
methods.push(`${section}_${method}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -130,7 +131,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
|||||||
? of(false)
|
? of(false)
|
||||||
: this._rpcCore.state.getMetadata().pipe(
|
: this._rpcCore.state.getMetadata().pipe(
|
||||||
map((metadata: Metadata): boolean => {
|
map((metadata: Metadata): boolean => {
|
||||||
l.log(`Runtime version updated to ${version.specVersion}`);
|
l.log(`Runtime version updated to spec=${version.specVersion.toString()}, tx=${version.transactionVersion.toString()}`);
|
||||||
|
|
||||||
this._runtimeMetadata = metadata;
|
this._runtimeMetadata = metadata;
|
||||||
this._runtimeVersion = version;
|
this._runtimeVersion = version;
|
||||||
@@ -167,7 +168,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
|||||||
await this._filterRpc();
|
await this._filterRpc();
|
||||||
|
|
||||||
// retrieve metadata, either from chain or as pass-in via options
|
// retrieve metadata, either from chain or as pass-in via options
|
||||||
const metadataKey = `${this._genesisHash}-${runtimeVersion.specVersion}`;
|
const metadataKey = `${this._genesisHash?.toHex() || '0x'}-${runtimeVersion.specVersion.toString()}`;
|
||||||
const metadata = metadataKey in optMetadata
|
const metadata = metadataKey in optMetadata
|
||||||
? new Metadata(this.registry, optMetadata[metadataKey])
|
? new Metadata(this.registry, optMetadata[metadataKey])
|
||||||
: await this._rpcCore.state.getMetadata().toPromise();
|
: await this._rpcCore.state.getMetadata().toPromise();
|
||||||
@@ -232,7 +233,7 @@ export default abstract class Init<ApiType extends ApiTypes> extends Decorate<Ap
|
|||||||
});
|
});
|
||||||
}, KEEPALIVE_INTERVAL);
|
}, KEEPALIVE_INTERVAL);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
const error = new Error(`FATAL: Unable to initialize the API: ${_error.message}`);
|
const error = new Error(`FATAL: Unable to initialize the API: ${(_error as Error).message}`);
|
||||||
|
|
||||||
l.error(error);
|
l.error(error);
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ interface PkgJson {
|
|||||||
let pkgJson: PkgJson = { name: '@polkadot/api', version: '-' };
|
let pkgJson: PkgJson = { name: '@polkadot/api', version: '-' };
|
||||||
|
|
||||||
import('../package.json')
|
import('../package.json')
|
||||||
.then((_pkgJson: any): void => {
|
.then((_pkgJson: unknown): void => {
|
||||||
pkgJson = _pkgJson;
|
pkgJson = _pkgJson as PkgJson;
|
||||||
})
|
})
|
||||||
.catch((): void => {
|
.catch((): void => {
|
||||||
// ignore
|
// ignore
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ async function query (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
|
|||||||
// check range types
|
// check range types
|
||||||
const entries = await api.query.system.events.range(['0x12345', '0x7890']);
|
const entries = await api.query.system.events.range(['0x12345', '0x7890']);
|
||||||
|
|
||||||
console.log(`Received ${entries.length} entries, ${entries.map(([hash, events]) => `${hash.toHex()}: ${events.length} events`)}`);
|
console.log(`Received ${entries.length} entries, ${entries.map(([hash, events]) => `${hash.toHex()}: ${events.length} events`).join(', ')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function rpc (api: ApiPromise): Promise<void> {
|
async function rpc (api: ApiPromise): Promise<void> {
|
||||||
@@ -105,6 +105,7 @@ async function rpc (api: ApiPromise): Promise<void> {
|
|||||||
await api.rpc.chain.getBlock.raw('0x123456');
|
await api.rpc.chain.getBlock.raw('0x123456');
|
||||||
|
|
||||||
// using raw subs
|
// using raw subs
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
api.rpc.chain.subscribeNewHeads.raw((result: Uint8Array): void => {
|
api.rpc.chain.subscribeNewHeads.raw((result: Uint8Array): void => {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
});
|
});
|
||||||
@@ -125,7 +126,7 @@ function types (api: ApiPromise): void {
|
|||||||
|
|
||||||
async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
|
async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
|
||||||
// transfer, also allows for BigInt inputs here
|
// transfer, also allows for BigInt inputs here
|
||||||
const transfer = api.tx.balances.transfer(keyring.bob.address, 123_456_789n);
|
const transfer = api.tx.balances.transfer(keyring.bob.address, 123456789n);
|
||||||
|
|
||||||
console.log('transfer as Call', transfer as IMethod);
|
console.log('transfer as Call', transfer as IMethod);
|
||||||
console.log('transfer as Extrinsic', transfer as IExtrinsic);
|
console.log('transfer as Extrinsic', transfer as IExtrinsic);
|
||||||
@@ -159,8 +160,9 @@ async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// it allows for query & then using the submittable
|
// it allows for query & then using the submittable
|
||||||
const second = api.tx.democracy.second(123);
|
const second = api.tx.democracy.second(123, 5);
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
second.signAndSend('123', (result): void => {
|
second.signAndSend('123', (result): void => {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
});
|
});
|
||||||
@@ -173,12 +175,15 @@ async function main (): Promise<void> {
|
|||||||
const api = await ApiPromise.create();
|
const api = await ApiPromise.create();
|
||||||
const keyring = testKeyring();
|
const keyring = testKeyring();
|
||||||
|
|
||||||
consts(api);
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
derive(api);
|
Promise.all([
|
||||||
query(api, keyring);
|
consts(api),
|
||||||
rpc(api);
|
derive(api),
|
||||||
types(api);
|
query(api, keyring),
|
||||||
tx(api, keyring);
|
rpc(api),
|
||||||
|
types(api),
|
||||||
|
tx(api, keyring)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { hexToU8a } from '@polkadot/util';
|
|||||||
import { SingleAccountSigner } from '../../test/util';
|
import { SingleAccountSigner } from '../../test/util';
|
||||||
import ApiPromise from './Api';
|
import ApiPromise from './Api';
|
||||||
|
|
||||||
const TRANSFER_SIG = '0xa1d493ab6b74550da434fbc153a739429be68c9d30e59e631fb5d08f348504deefb5577f4824e138741ad102f479109827e8fa9552812a3e5f505a24d10e820f';
|
const TRANSFER_SIG = '0x7a10e5ed9a14284eca7bea53f81631981dddda5a3d2dee973b136475947264801465726e4829ae3994d9058df638d959d4e043c7f1924299546790dda1dea20a';
|
||||||
|
|
||||||
describe('ApiPromise', (): void => {
|
describe('ApiPromise', (): void => {
|
||||||
const registry = new TypeRegistry();
|
const registry = new TypeRegistry();
|
||||||
@@ -39,7 +39,7 @@ describe('ApiPromise', (): void => {
|
|||||||
|
|
||||||
const signer = new SingleAccountSigner(registry, aliceEd);
|
const signer = new SingleAccountSigner(registry, aliceEd);
|
||||||
const api = await ApiPromise.create({ provider, registry, signer });
|
const api = await ApiPromise.create({ provider, registry, signer });
|
||||||
const transfer = api.tx.balances.transfer(keyring.getPair('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e').address, 321_564_789_876_512_345n);
|
const transfer = api.tx.balances.transfer(keyring.getPair('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e').address, 321564789876512345n);
|
||||||
|
|
||||||
return { api, transfer: await transfer.signAsync(aliceEd.address, {}) };
|
return { api, transfer: await transfer.signAsync(aliceEd.address, {}) };
|
||||||
}
|
}
|
||||||
@@ -57,8 +57,10 @@ describe('ApiPromise', (): void => {
|
|||||||
const metadata: any = {};
|
const metadata: any = {};
|
||||||
const key = `${genesisHash}-${specVersion}`;
|
const key = `${genesisHash}-${specVersion}`;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
metadata[key] = rpcData;
|
metadata[key] = rpcData;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
const api = await ApiPromise.create({ metadata, provider, registry } as ApiOptions);
|
const api = await ApiPromise.create({ metadata, provider, registry } as ApiOptions);
|
||||||
|
|
||||||
expect(api.genesisHash).toBeDefined();
|
expect(api.genesisHash).toBeDefined();
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ function extractArgs (args: any[], needsCallback: boolean): [any[], Callback<Cod
|
|||||||
// If the last arg is a function, we pop it, put it into callback.
|
// If the last arg is a function, we pop it, put it into callback.
|
||||||
// actualArgs will then hold the actual arguments to be passed to `method`
|
// actualArgs will then hold the actual arguments to be passed to `method`
|
||||||
if (args.length && isFunction(args[args.length - 1])) {
|
if (args.length && isFunction(args[args.length - 1])) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
callback = actualArgs.pop();
|
callback = actualArgs.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ function extractArgs (args: any[], needsCallback: boolean): [any[], Callback<Cod
|
|||||||
function promiseTracker (resolve: (value: () => void) => void, reject: (value: Error) => void): Tracker {
|
function promiseTracker (resolve: (value: () => void) => void, reject: (value: Error) => void): Tracker {
|
||||||
let isCompleted = false;
|
let isCompleted = false;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
const complete = (fn: Function, value: any): void => {
|
const complete = (fn: Function, value: any): void => {
|
||||||
if (!isCompleted) {
|
if (!isCompleted) {
|
||||||
isCompleted = true;
|
isCompleted = true;
|
||||||
@@ -68,24 +70,22 @@ export function decorateMethod<Method extends AnyFunction> (method: Method, opti
|
|||||||
const [actualArgs, callback] = extractArgs(args, !!needsCallback);
|
const [actualArgs, callback] = extractArgs(args, !!needsCallback);
|
||||||
|
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
return method(...actualArgs).pipe(first()).toPromise() as Promise<ObsInnerType<ReturnType<Method>>>;
|
return method(...actualArgs).pipe(first()).toPromise() as Promise<ObsInnerType<ReturnType<Method>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject): void => {
|
return new Promise((resolve, reject): void => {
|
||||||
const tracker = promiseTracker(resolve, reject);
|
const tracker = promiseTracker(resolve, reject);
|
||||||
const subscription = method(...actualArgs)
|
|
||||||
.pipe(
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
||||||
// if we find an error (invalid params, etc), reject the promise
|
const subscription: { unsubscribe: () => void } = method(...actualArgs).pipe(
|
||||||
catchError((error): Observable<never> =>
|
// if we find an error (invalid params, etc), reject the promise
|
||||||
tracker.reject(error)
|
catchError((error): Observable<never> => tracker.reject(error)),
|
||||||
),
|
// upon the first result, resolve with the unsub function
|
||||||
// upon the first result, resolve with the unsub function
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-return
|
||||||
tap((): void =>
|
tap(() => tracker.resolve(() => subscription.unsubscribe()))
|
||||||
tracker.resolve((): void => subscription.unsubscribe())
|
).subscribe(callback);
|
||||||
)
|
}) as UnsubscribePromise;
|
||||||
)
|
|
||||||
.subscribe(callback);
|
|
||||||
}) as any; // ???
|
|
||||||
} as StorageEntryPromiseOverloads;
|
} as StorageEntryPromiseOverloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default class Combinator<T extends any[] = any[]> {
|
|||||||
this.#fns.push(fn);
|
this.#fns.push(fn);
|
||||||
|
|
||||||
// Not quite 100% how to have a variable number at the front here
|
// Not quite 100% how to have a variable number at the front here
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/ban-types
|
||||||
return (fn as Function)(...args, this._createCallback(index));
|
return (fn as Function)(...args, this._createCallback(index));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -54,7 +55,7 @@ export default class Combinator<T extends any[] = any[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected _createCallback (index: number): (value: any) => void {
|
protected _createCallback (index: number): (value: any) => void {
|
||||||
return (value: any): void => {
|
return (value: unknown): void => {
|
||||||
this.#fired[index] = true;
|
this.#fired[index] = true;
|
||||||
this.#results[index] = value;
|
this.#results[index] = value;
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ export default class Combinator<T extends any[] = any[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
this.#callback(this.#results as T);
|
this.#callback(this.#results as T);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// swallow, we don't want the handler to trip us up
|
// swallow, we don't want the handler to trip us up
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
|||||||
const [allOptions] = this.#makeSignAndSendOptions(options);
|
const [allOptions] = this.#makeSignAndSendOptions(options);
|
||||||
const address = isKeyringPair(account) ? account.address : account.toString();
|
const address = isKeyringPair(account) ? account.address : account.toString();
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||||
return decorateMethod(
|
return decorateMethod(
|
||||||
(): Observable<RuntimeDispatchInfo> =>
|
(): Observable<RuntimeDispatchInfo> =>
|
||||||
api.derive.tx.signingInfo(address, allOptions.nonce, allOptions.era).pipe(
|
api.derive.tx.signingInfo(address, allOptions.nonce, allOptions.era).pipe(
|
||||||
@@ -70,6 +71,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
|||||||
//
|
//
|
||||||
// also supports signing through external signers
|
// also supports signing through external signers
|
||||||
public signAsync (account: AddressOrPair, optionsOrNonce?: Partial<SignerOptions>): SubmittableThis<ApiType, this> {
|
public signAsync (account: AddressOrPair, optionsOrNonce?: Partial<SignerOptions>): SubmittableThis<ApiType, this> {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||||
return decorateMethod(
|
return decorateMethod(
|
||||||
(): Observable<this> =>
|
(): Observable<this> =>
|
||||||
this.#observeSign(account, optionsOrNonce).pipe(mapTo(this))
|
this.#observeSign(account, optionsOrNonce).pipe(mapTo(this))
|
||||||
@@ -90,6 +92,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
|||||||
const [options, statusCb] = this.#makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
|
const [options, statusCb] = this.#makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
|
||||||
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||||
return decorateMethod(
|
return decorateMethod(
|
||||||
(): Observable<Codec> => (
|
(): Observable<Codec> => (
|
||||||
this.#observeSign(account, options).pipe(
|
this.#observeSign(account, options).pipe(
|
||||||
@@ -112,6 +115,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
|
|||||||
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||||
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||||
return decorateMethod(
|
return decorateMethod(
|
||||||
isSubscription
|
isSubscription
|
||||||
? this.#observeSubscribe
|
? this.#observeSubscribe
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ export default function createSubmittable<ApiType extends ApiTypes> (apiType: Ap
|
|||||||
Submittable = createClass<ApiType>({ api, apiType, decorateMethod });
|
Submittable = createClass<ApiType>({ api, apiType, decorateMethod });
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Submittable(api.registry, extrinsic);
|
return new Submittable(api.registry, extrinsic) as SubmittableExtrinsic<ApiType>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
import { AccountId, Address, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
import { AccountId, Address, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
|
||||||
import { AnyNumber, AnyU8a, Callback, Codec, IExtrinsicEra, IKeyringPair, SignatureOptions, Signer, ISubmittableResult } from '@polkadot/types/types';
|
import { AnyNumber, AnyU8a, Callback, Codec, IExtrinsicEra, IKeyringPair, Signer, ISubmittableResult } from '@polkadot/types/types';
|
||||||
import { ApiTypes } from '../types';
|
import { ApiTypes } from '../types';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
@@ -50,9 +50,9 @@ export interface SubmittableExtrinsic<ApiType extends ApiTypes> extends Extrinsi
|
|||||||
|
|
||||||
send(statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
send(statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||||
|
|
||||||
sign(account: IKeyringPair, _options?: Partial<SignatureOptions>): this;
|
sign(account: IKeyringPair, _options?: Partial<SignerOptions>): this;
|
||||||
|
|
||||||
signAsync(account: AddressOrPair, _options?: Partial<SignatureOptions>): SubmittableThis<ApiType, this>;
|
signAsync(account: AddressOrPair, _options?: Partial<SignerOptions>): SubmittableThis<ApiType, this>;
|
||||||
|
|
||||||
signAndSend(account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
signAndSend(account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export interface StorageEntryBase<ApiType extends ApiTypes, F extends AnyFunctio
|
|||||||
|
|
||||||
export interface StorageEntryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction> extends StorageEntryBase<ApiType, F> {
|
export interface StorageEntryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction> extends StorageEntryBase<ApiType, F> {
|
||||||
entries: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, T][]>;
|
entries: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, T][]>;
|
||||||
|
keyPrefix: (key1?: Parameters<F>[0]) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StorageEntryObservableMulti {
|
interface StorageEntryObservableMulti {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ describe('augmentObject', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach((): void => {
|
afterEach((): void => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
spy.mockClear();
|
spy.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ function extractMethods (src: Record<string, Record<string, any>>, dst: Record<s
|
|||||||
* already available, but rather just adds new missing ites into the result object.
|
* already available, but rather just adds new missing ites into the result object.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export default function augmentObject (prefix: string, src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>, fromEmpty = false): Record<string, Record<string, any>> {
|
export default function augmentObject (prefix: string, src: Record<string, Record<string, unknown>>, dst: Record<string, Record<string, unknown>>, fromEmpty = false): Record<string, Record<string, any>> {
|
||||||
if (fromEmpty) {
|
if (fromEmpty) {
|
||||||
Object.keys(dst).forEach((key): void => {
|
Object.keys(dst).forEach((key): void => {
|
||||||
delete dst[key];
|
delete dst[key];
|
||||||
@@ -88,12 +88,12 @@ export default function augmentObject (prefix: string, src: Record<string, Recor
|
|||||||
|
|
||||||
return Object
|
return Object
|
||||||
.keys(src)
|
.keys(src)
|
||||||
.reduce((newSection, sectionName): Record<string, Record<string, any>> => {
|
.reduce((newSection, sectionName): Record<string, Record<string, unknown>> => {
|
||||||
const section = src[sectionName];
|
const section = src[sectionName];
|
||||||
|
|
||||||
newSection[sectionName] = Object
|
newSection[sectionName] = Object
|
||||||
.keys(section)
|
.keys(section)
|
||||||
.reduce((result, methodName): Record<string, any> => {
|
.reduce((result, methodName): Record<string, unknown> => {
|
||||||
// TODO When it does match, check the actual details and warn when there are differences
|
// TODO When it does match, check the actual details and warn when there are differences
|
||||||
if (!result[methodName]) {
|
if (!result[methodName]) {
|
||||||
result[methodName] = section[methodName];
|
result[methodName] = section[methodName];
|
||||||
|
|||||||
@@ -14,17 +14,14 @@ export type DeriveAllSections<ApiType extends ApiTypes, AllSections extends AnyD
|
|||||||
|
|
||||||
// A technically unsafe version of Object.keys(obj) that assumes that
|
// A technically unsafe version of Object.keys(obj) that assumes that
|
||||||
// obj only has known properties of T
|
// obj only has known properties of T
|
||||||
function keys<T extends object> (obj: T): (keyof T)[] {
|
function keys<T extends Record<string, unknown>> (obj: T): (keyof T)[] {
|
||||||
return Object.keys(obj) as (keyof T)[];
|
return Object.keys(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a methods decorator which keeps all type information.
|
* This is a methods decorator which keeps all type information.
|
||||||
*/
|
*/
|
||||||
function decorateMethods<ApiType extends ApiTypes, Section extends Record<string, AnyFunction>> (
|
function decorateMethods<ApiType extends ApiTypes, Section extends Record<string, AnyFunction>> (section: Section, decorateMethod: DecorateMethod<ApiType>): DeriveSection<ApiType, Section> {
|
||||||
section: Section,
|
|
||||||
decorateMethod: DecorateMethod<ApiType>
|
|
||||||
): DeriveSection<ApiType, Section> {
|
|
||||||
return keys(section).reduce(
|
return keys(section).reduce(
|
||||||
<MethodName extends keyof Section>(
|
<MethodName extends keyof Section>(
|
||||||
acc: DeriveSection<ApiType, Section>,
|
acc: DeriveSection<ApiType, Section>,
|
||||||
@@ -32,7 +29,8 @@ function decorateMethods<ApiType extends ApiTypes, Section extends Record<string
|
|||||||
): DeriveSection<ApiType, Section> => {
|
): DeriveSection<ApiType, Section> => {
|
||||||
const method = section[methodName];
|
const method = section[methodName];
|
||||||
|
|
||||||
acc[methodName] = decorateMethod(method);
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
acc[methodName] = decorateMethod(method) as MethodResult<ApiType, Section[MethodName]>;
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default function filterEvents (extHash: H256, { block: { extrinsics, head
|
|||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
// only warn on filtering with isInBlock (finalization finalizes after)
|
// only warn on filtering with isInBlock (finalization finalizes after)
|
||||||
if (status.isInBlock) {
|
if (status.isInBlock) {
|
||||||
l.warn(`block ${header.hash}: Unable to find extrinsic ${myHash} inside ${allHashes}`);
|
l.warn(`block ${header.hash.toHex()}: Unable to find extrinsic ${myHash} inside ${allHashes.join(', ')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ describe('extractStorageArgs', (): void => {
|
|||||||
|
|
||||||
it('validates no-arg plain (failing when there are args)', (): void => {
|
it('validates no-arg plain (failing when there are args)', (): void => {
|
||||||
expect(
|
expect(
|
||||||
(): any[] =>
|
(): unknown => extractStorageArgs(storage.timestamp.now, [123, 456])
|
||||||
extractStorageArgs(storage.timestamp.now, [123, 456])
|
|
||||||
).toThrow('timestamp.now() does not take any arguments, 2 found');
|
).toThrow('timestamp.now() does not take any arguments, 2 found');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ function doMap (creator: StorageEntry, args: any[]): [StorageEntry] | [StorageEn
|
|||||||
|
|
||||||
// sets up the arguments in the form of [creator, args] ready to be used in a storage
|
// sets up the arguments in the form of [creator, args] ready to be used in a storage
|
||||||
// call. Additionally, it verifies that the correct number of arguments have been passed
|
// call. Additionally, it verifies that the correct number of arguments have been passed
|
||||||
export function extractStorageArgs (creator: StorageEntry, _args: any[]): any[] {
|
export function extractStorageArgs (creator: StorageEntry, _args: any[]): [StorageEntry, [any, any]] | [StorageEntry] | [StorageEntry, any] {
|
||||||
const args = _args.filter((arg) => !isUndefined(arg));
|
const args = _args.filter((arg) => !isUndefined(arg));
|
||||||
|
|
||||||
if (creator.meta.type.isDoubleMap) {
|
if (creator.meta.type.isDoubleMap) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { EventRecord } from '@polkadot/types/interfaces';
|
|||||||
import { SubmittableResult } from '../../src';
|
import { SubmittableResult } from '../../src';
|
||||||
|
|
||||||
// log all events for the transfers, calling done() when finalized
|
// log all events for the transfers, calling done() when finalized
|
||||||
export const logEvents = (done: () => {}): (r: SubmittableResult) => void =>
|
export const logEvents = (done: () => Record<string, unknown>): (r: SubmittableResult) => void =>
|
||||||
({ events, status }: SubmittableResult): void => {
|
({ events, status }: SubmittableResult): void => {
|
||||||
console.log('Transaction status:', status.type);
|
console.log('Transaction status:', status.type);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@polkadot/metadata",
|
"name": "@polkadot/metadata",
|
||||||
"version": "1.14.1",
|
"version": "1.16.1",
|
||||||
"description": "Helpers to extract information from runtime metadata",
|
"description": "Helpers to extract information from runtime metadata",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
@@ -27,13 +27,13 @@
|
|||||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-metadata#readme",
|
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-metadata#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.9.6",
|
"@babel/runtime": "^7.9.6",
|
||||||
"@polkadot/types": "1.14.1",
|
"@polkadot/types": "1.16.1",
|
||||||
"@polkadot/types-known": "1.14.1",
|
"@polkadot/types-known": "1.16.1",
|
||||||
"@polkadot/util": "^2.10.1",
|
"@polkadot/util": "^2.11.1",
|
||||||
"@polkadot/util-crypto": "^2.10.1",
|
"@polkadot/util-crypto": "^2.11.1",
|
||||||
"bn.js": "^5.1.1"
|
"bn.js": "^5.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/keyring": "^2.10.1"
|
"@polkadot/keyring": "^2.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import { Text, TypeRegistry } from '@polkadot/types';
|
import { Text, TypeRegistry } from '@polkadot/types';
|
||||||
import { StorageEntry } from '@polkadot/types/primitive/StorageKey';
|
import { StorageEntry } from '@polkadot/types/primitive/StorageKey';
|
||||||
import { stringToU8a, u8aConcat, u8aToHex } from '@polkadot/util';
|
import { assert, stringToU8a, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||||
|
|
||||||
import createFunction from './createFunction';
|
import createFunction from './createFunction';
|
||||||
|
|
||||||
@@ -14,6 +14,7 @@ describe('createFunction', (): void => {
|
|||||||
it('should create timestamp.now correctly', (): void => {
|
it('should create timestamp.now correctly', (): void => {
|
||||||
expect(
|
expect(
|
||||||
createFunction(registry, {
|
createFunction(registry, {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
meta: { type: {} } as any,
|
meta: { type: {} } as any,
|
||||||
method: 'Now',
|
method: 'Now',
|
||||||
prefix: 'Timestamp',
|
prefix: 'Timestamp',
|
||||||
@@ -29,6 +30,7 @@ describe('createFunction', (): void => {
|
|||||||
createFunction(
|
createFunction(
|
||||||
registry,
|
registry,
|
||||||
{
|
{
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
meta: { type: {} } as any,
|
meta: { type: {} } as any,
|
||||||
method: 'authorityCount',
|
method: 'authorityCount',
|
||||||
prefix: 'Substrate',
|
prefix: 'Substrate',
|
||||||
@@ -50,6 +52,7 @@ describe('createFunction', (): void => {
|
|||||||
createFunction(
|
createFunction(
|
||||||
registry,
|
registry,
|
||||||
{
|
{
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
meta: { type: {} } as any,
|
meta: { type: {} } as any,
|
||||||
method: 'authorityCount',
|
method: 'authorityCount',
|
||||||
prefix: 'Substrate',
|
prefix: 'Substrate',
|
||||||
@@ -74,6 +77,7 @@ describe('createFunction', (): void => {
|
|||||||
|
|
||||||
beforeAll((): void => {
|
beforeAll((): void => {
|
||||||
storageFn = createFunction(registry, {
|
storageFn = createFunction(registry, {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
meta: {
|
meta: {
|
||||||
name: 'metaName',
|
name: 'metaName',
|
||||||
type: {
|
type: {
|
||||||
@@ -104,10 +108,22 @@ describe('createFunction', (): void => {
|
|||||||
(): Uint8Array => storageFn(['5DXUeE5N5LtkW97F2PzqYPyqNkxqSWESdGSPTX6AvkUAhwKP'])
|
(): Uint8Array => storageFn(['5DXUeE5N5LtkW97F2PzqYPyqNkxqSWESdGSPTX6AvkUAhwKP'])
|
||||||
).toThrow(/requires two arguments/);
|
).toThrow(/requires two arguments/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('accepts an optional parameter for key construction', (): void => {
|
||||||
|
const iterKey = storageFn.iterKey;
|
||||||
|
|
||||||
|
assert(iterKey, 'storageFn.iterKey is undefined');
|
||||||
|
|
||||||
|
const result = iterKey('5DXUeE5N5LtkW97F2PzqYPyqNkxqSWESdGSPTX6AvkUAhwKP');
|
||||||
|
|
||||||
|
expect(u8aToHex(result)).toEqual('0x223416315e3dddca3b5a47fd0ac8e4916482b9ade7bc6657aaca787ba1add3b4c4303117deb55aad9858c8a873273280f78d172b398d5e77e43a2db5e42163e9');
|
||||||
|
expect(u8aToHex(iterKey())).toEqual('0x223416315e3dddca3b5a47fd0ac8e4916482b9ade7bc6657aaca787ba1add3b4');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows creates double map function with a Null type key', (): void => {
|
it('allows creates double map function with a Null type key', (): void => {
|
||||||
const storageFn = createFunction(registry, {
|
const storageFn = createFunction(registry, {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
meta: {
|
meta: {
|
||||||
type: {
|
type: {
|
||||||
asDoubleMap: {
|
asDoubleMap: {
|
||||||
@@ -133,6 +149,7 @@ describe('createFunction', (): void => {
|
|||||||
|
|
||||||
it('allows creating of known DoubleMap keys (with Bytes)', (): void => {
|
it('allows creating of known DoubleMap keys (with Bytes)', (): void => {
|
||||||
const storageFn = createFunction(registry, {
|
const storageFn = createFunction(registry, {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
meta: {
|
meta: {
|
||||||
type: {
|
type: {
|
||||||
asDoubleMap: {
|
asDoubleMap: {
|
||||||
|
|||||||
@@ -73,10 +73,7 @@ function createKeyDoubleMap (registry: Registry, itemFn: CreateItemFn, stringKey
|
|||||||
const { meta: { name, type } } = itemFn;
|
const { meta: { name, type } } = itemFn;
|
||||||
|
|
||||||
// since we are passing an almost-unknown through, trust, but verify
|
// since we are passing an almost-unknown through, trust, but verify
|
||||||
assert(
|
assert(Array.isArray(args) && !isUndefined(args[0]) && !isNull(args[0]) && !isUndefined(args[1]) && !isNull(args[1]), `${(name || 'unknown').toString()} is a DoubleMap and requires two arguments`);
|
||||||
Array.isArray(args) && !isUndefined(args[0]) && !isNull(args[0]) && !isUndefined(args[1]) && !isNull(args[1]),
|
|
||||||
`${name} is a DoubleMap and requires two arguments`
|
|
||||||
);
|
|
||||||
|
|
||||||
// if this fails, we have bigger issues
|
// if this fails, we have bigger issues
|
||||||
assert(!isUndefined(hasher2), '2 hashing functions should be defined for DoubleMaps');
|
assert(!isUndefined(hasher2), '2 hashing functions should be defined for DoubleMaps');
|
||||||
@@ -110,7 +107,7 @@ function createKey (registry: Registry, itemFn: CreateItemFn, stringKey: string,
|
|||||||
if (type.isMap) {
|
if (type.isMap) {
|
||||||
const map = type.asMap;
|
const map = type.asMap;
|
||||||
|
|
||||||
assert(!isUndefined(arg) && !isNull(arg), `${name} is a Map and requires one argument`);
|
assert(!isUndefined(arg) && !isNull(arg), `${name.toString()} is a Map and requires one argument`);
|
||||||
|
|
||||||
param = createTypeUnsafe(registry, map.key.toString(), [arg]).toU8a();
|
param = createTypeUnsafe(registry, map.key.toString(), [arg]).toU8a();
|
||||||
}
|
}
|
||||||
@@ -134,7 +131,7 @@ function expandWithMeta ({ meta, method, prefix, section }: CreateItemFn, storag
|
|||||||
// explicitly add the actual method in the toJSON, this gets used to determine caching and without it
|
// explicitly add the actual method in the toJSON, this gets used to determine caching and without it
|
||||||
// instances (e.g. collective) will not work since it is only matched on param meta
|
// instances (e.g. collective) will not work since it is only matched on param meta
|
||||||
storageFn.toJSON = (): any => ({
|
storageFn.toJSON = (): any => ({
|
||||||
...(meta.toJSON() as any),
|
...(meta.toJSON() as Record<string, unknown>),
|
||||||
storage: { method, prefix, section }
|
storage: { method, prefix, section }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -142,7 +139,7 @@ function expandWithMeta ({ meta, method, prefix, section }: CreateItemFn, storag
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
function extendHeadMeta (registry: Registry, { meta: { documentation, name, type }, section }: CreateItemFn, { method }: StorageEntry, iterFn: (arg?: any) => Raw): StorageKey {
|
function extendHeadMeta (registry: Registry, { meta: { documentation, name, type }, section }: CreateItemFn, { method }: StorageEntry, iterFn: (arg?: any) => Raw): (arg?: any) => StorageKey {
|
||||||
const outputType = type.isMap
|
const outputType = type.isMap
|
||||||
? type.asMap.key.toString()
|
? type.asMap.key.toString()
|
||||||
: type.asDoubleMap.key1.toString();
|
: type.asDoubleMap.key1.toString();
|
||||||
@@ -157,7 +154,12 @@ function extendHeadMeta (registry: Registry, { meta: { documentation, name, type
|
|||||||
type: registry.createType('StorageEntryTypeLatest', registry.createType('PlainTypeLatest', type.isMap ? type.asMap.key : type.asDoubleMap.key1), 0)
|
type: registry.createType('StorageEntryTypeLatest', registry.createType('PlainTypeLatest', type.isMap ? type.asMap.key : type.asDoubleMap.key1), 0)
|
||||||
});
|
});
|
||||||
|
|
||||||
return registry.createType('StorageKey', iterFn, { method, section });
|
const prefixKey = registry.createType('StorageKey', iterFn, { method, section });
|
||||||
|
|
||||||
|
return (arg?: any): StorageKey =>
|
||||||
|
!isUndefined(arg) && !isNull(arg)
|
||||||
|
? registry.createType('StorageKey', iterFn(arg), { method, section })
|
||||||
|
: prefixKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// attach the head key hashing for linked maps
|
// attach the head key hashing for linked maps
|
||||||
@@ -177,8 +179,12 @@ function extendLinkedMap (registry: Registry, itemFn: CreateItemFn, storageFn: S
|
|||||||
// attach the full list hashing for prefixed maps
|
// attach the full list hashing for prefixed maps
|
||||||
/** @internal */
|
/** @internal */
|
||||||
function extendPrefixedMap (registry: Registry, itemFn: CreateItemFn, storageFn: StorageEntry): StorageEntry {
|
function extendPrefixedMap (registry: Registry, itemFn: CreateItemFn, storageFn: StorageEntry): StorageEntry {
|
||||||
storageFn.iterKey = extendHeadMeta(registry, itemFn, storageFn, (): Raw =>
|
const { meta: { type } } = itemFn;
|
||||||
new Raw(registry, createPrefixedKey(itemFn))
|
|
||||||
|
storageFn.iterKey = extendHeadMeta(registry, itemFn, storageFn, (arg?: any): Raw =>
|
||||||
|
type.isDoubleMap && !isUndefined(arg) && !isNull(arg)
|
||||||
|
? new Raw(registry, u8aConcat(createPrefixedKey(itemFn), getHasher(type.asDoubleMap.hasher)(registry.createType(type.asDoubleMap.key1.toString() as 'Raw', arg).toU8a())))
|
||||||
|
: new Raw(registry, createPrefixedKey(itemFn))
|
||||||
);
|
);
|
||||||
|
|
||||||
return storageFn;
|
return storageFn;
|
||||||
@@ -219,7 +225,8 @@ export default function createFunction (registry: Registry, itemFn: CreateItemFn
|
|||||||
extendDoubleMap(registry, itemFn, storageFn);
|
extendDoubleMap(registry, itemFn, storageFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
storageFn.keyPrefix = storageFn.iterKey || compactStripLength(storageFn())[1];
|
storageFn.keyPrefix = (arg?: any): Uint8Array =>
|
||||||
|
(storageFn.iterKey && storageFn.iterKey(arg)) || compactStripLength(storageFn())[1];
|
||||||
|
|
||||||
return storageFn;
|
return storageFn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ export type HasherFunction = (data: HasherInput) => Uint8Array;
|
|||||||
const DEFAULT_FN = (data: HasherInput): Uint8Array => xxhashAsU8a(data, 128);
|
const DEFAULT_FN = (data: HasherInput): Uint8Array => xxhashAsU8a(data, 128);
|
||||||
|
|
||||||
const HASHERS: Record<keyof typeof AllHashers, HasherFunction> = {
|
const HASHERS: Record<keyof typeof AllHashers, HasherFunction> = {
|
||||||
Blake2_128: (data: HasherInput): Uint8Array => // eslint-disable-line @typescript-eslint/camelcase
|
Blake2_128: (data: HasherInput): Uint8Array => // eslint-disable-line camelcase
|
||||||
blake2AsU8a(data, 128),
|
blake2AsU8a(data, 128),
|
||||||
Blake2_128Concat: (data: HasherInput): Uint8Array => // eslint-disable-line @typescript-eslint/camelcase
|
Blake2_128Concat: (data: HasherInput): Uint8Array => // eslint-disable-line camelcase
|
||||||
u8aConcat(blake2AsU8a(data, 128), u8aToU8a(data)),
|
u8aConcat(blake2AsU8a(data, 128), u8aToU8a(data)),
|
||||||
Blake2_256: (data: HasherInput): Uint8Array => // eslint-disable-line @typescript-eslint/camelcase
|
Blake2_256: (data: HasherInput): Uint8Array => // eslint-disable-line camelcase
|
||||||
blake2AsU8a(data, 256),
|
blake2AsU8a(data, 256),
|
||||||
Identity: (data: HasherInput): Uint8Array =>
|
Identity: (data: HasherInput): Uint8Array =>
|
||||||
u8aToU8a(data),
|
u8aToU8a(data),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default function getStorage (registry: Registry, metaVersion: number): St
|
|||||||
substrate: Object
|
substrate: Object
|
||||||
.entries(substrate)
|
.entries(substrate)
|
||||||
.reduce((storage: Record<string, StorageEntry>, [key, fn]): Record<string, StorageEntry> => {
|
.reduce((storage: Record<string, StorageEntry>, [key, fn]): Record<string, StorageEntry> => {
|
||||||
(storage as any)[key] = fn(registry, metaVersion);
|
(storage as Record<string, unknown>)[key] = fn(registry, metaVersion);
|
||||||
|
|
||||||
return storage;
|
return storage;
|
||||||
}, {})
|
}, {})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// This software may be modified and distributed under the terms
|
// This software may be modified and distributed under the terms
|
||||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
import { Registry } from '@polkadot/types/types';
|
import { AnyNumber, Registry } from '@polkadot/types/types';
|
||||||
|
|
||||||
import { assert } from '@polkadot/util';
|
import { assert } from '@polkadot/util';
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ import U32 from '@polkadot/types/primitive/U32';
|
|||||||
export const MAGIC_NUMBER = 0x6174656d; // `meta`, reversed for Little Endian encoding
|
export const MAGIC_NUMBER = 0x6174656d; // `meta`, reversed for Little Endian encoding
|
||||||
|
|
||||||
export default class MagicNumber extends U32 {
|
export default class MagicNumber extends U32 {
|
||||||
constructor (registry: Registry, value?: any) {
|
constructor (registry: Registry, value?: AnyNumber) {
|
||||||
super(registry, value);
|
super(registry, value);
|
||||||
|
|
||||||
if (!this.isEmpty) {
|
if (!this.isEmpty) {
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ type MetaAsX = 'asV0' | 'asV1' | 'asV2' | 'asV3' | 'asV4' | 'asV5' | 'asV6' | 'a
|
|||||||
* The versioned runtime metadata as a decoded structure
|
* The versioned runtime metadata as a decoded structure
|
||||||
*/
|
*/
|
||||||
export default class MetadataVersioned extends Struct {
|
export default class MetadataVersioned extends Struct {
|
||||||
readonly #converted: Map<number, MetaMapped> = new Map();
|
readonly #converted = new Map<number, MetaMapped>();
|
||||||
|
|
||||||
constructor (registry: Registry, value?: any) {
|
constructor (registry: Registry, value?: unknown) {
|
||||||
super(registry, {
|
super(registry, {
|
||||||
magicNumber: MagicNumber,
|
magicNumber: MagicNumber,
|
||||||
metadata: 'MetadataAll'
|
metadata: 'MetadataAll'
|
||||||
}, value);
|
}, value as Map<unknown, unknown>);
|
||||||
|
|
||||||
registry.setMetadata(this);
|
registry.setMetadata(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
// This software may be modified and distributed under the terms
|
// This software may be modified and distributed under the terms
|
||||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
|
type Types = string | Types[];
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export default function flattenUniq (list: any[]): any[] {
|
export default function flattenUniq (list: Types[]): string[] {
|
||||||
const flat = list.reduce((result, entry): any[] => {
|
const flat = list.reduce((result: string[], entry): string[] => {
|
||||||
return result.concat(
|
return result.concat(
|
||||||
Array.isArray(entry)
|
Array.isArray(entry)
|
||||||
? flattenUniq(entry)
|
? flattenUniq(entry)
|
||||||
@@ -13,6 +15,6 @@ export default function flattenUniq (list: any[]): any[] {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return [...new Set(flat)]
|
return [...new Set(flat)]
|
||||||
.filter((value: any): any => value)
|
.filter((value: string) => value)
|
||||||
.sort();
|
.sort();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import getUniqTypes from './getUniqTypes';
|
|||||||
import Metadata from '../Metadata';
|
import Metadata from '../Metadata';
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function decodeLatestSubstrate<Modules extends Codec> (registry: Registry, version: number, rpcData: string, staticSubstrate: object): void {
|
export function decodeLatestSubstrate<Modules extends Codec> (registry: Registry, version: number, rpcData: string, staticSubstrate: Record<string, unknown>): void {
|
||||||
it('decodes latest substrate properly', (): void => {
|
it('decodes latest substrate properly', (): void => {
|
||||||
const metadata = new Metadata(registry, rpcData);
|
const metadata = new Metadata(registry, rpcData);
|
||||||
|
|
||||||
@@ -49,14 +49,14 @@ export function defaultValues (registry: Registry, rpcData: string, withThrow =
|
|||||||
metadata.asLatest.modules.filter(({ storage }): boolean => storage.isSome).forEach((mod): void => {
|
metadata.asLatest.modules.filter(({ storage }): boolean => storage.isSome).forEach((mod): void => {
|
||||||
mod.storage.unwrap().items.forEach(({ fallback, name, type }): void => {
|
mod.storage.unwrap().items.forEach(({ fallback, name, type }): void => {
|
||||||
const inner = unwrapStorageType(type);
|
const inner = unwrapStorageType(type);
|
||||||
const location = `${mod.name}.${name}: ${inner}`;
|
const location = `${mod.name.toString()}.${name.toString()}: ${inner}`;
|
||||||
|
|
||||||
it(`creates default types for ${location}`, (): void => {
|
it(`creates default types for ${location}`, (): void => {
|
||||||
expect((): void => {
|
expect((): void => {
|
||||||
try {
|
try {
|
||||||
registry.createType(inner, fallback);
|
registry.createType(inner, fallback);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = `${location}:: ${error.message}`;
|
const message = `${location}:: ${(error as Error).message}`;
|
||||||
|
|
||||||
if (withThrow) {
|
if (withThrow) {
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function mapCalls (registry: Registry, _calls: Option<Vec<FunctionMetadataLatest
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
);
|
) as Option<Vec<FunctionMetadataLatest>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import { getTypeDef } from '@polkadot/types/create';
|
|||||||
|
|
||||||
import flattenUniq from './flattenUniq';
|
import flattenUniq from './flattenUniq';
|
||||||
|
|
||||||
|
type Extracted = string | Extracted[];
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
function extractTypes (types: string[]): any[] {
|
function extractTypes (types: string[]): Extracted[] {
|
||||||
return types.map((type): any => {
|
return types.map((type): Extracted => {
|
||||||
const decoded = getTypeDef(type);
|
const decoded = getTypeDef(type);
|
||||||
|
|
||||||
switch (decoded.info) {
|
switch (decoded.info) {
|
||||||
@@ -38,12 +40,10 @@ function extractTypes (types: string[]): any[] {
|
|||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export default function validateTypes (registry: Registry, types: string[], throwError: boolean): void {
|
export default function validateTypes (registry: Registry, types: string[], throwError: boolean): void {
|
||||||
const missing = flattenUniq(extractTypes(types)).filter((type): boolean =>
|
const missing = flattenUniq(extractTypes(types)).filter((type) => !registry.hasType(type));
|
||||||
!registry.hasType(type)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (missing.length !== 0) {
|
if (missing.length !== 0) {
|
||||||
const message = `Unknown types found, no types for ${missing}`;
|
const message = `Unknown types found, no types for ${missing.join(', ')}`;
|
||||||
|
|
||||||
if (throwError) {
|
if (throwError) {
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@polkadot/rpc-core",
|
"name": "@polkadot/rpc-core",
|
||||||
"version": "1.14.1",
|
"version": "1.16.1",
|
||||||
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
|
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -27,14 +27,14 @@
|
|||||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-core#readme",
|
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-core#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.9.6",
|
"@babel/runtime": "^7.9.6",
|
||||||
"@polkadot/metadata": "1.14.1",
|
"@polkadot/metadata": "1.16.1",
|
||||||
"@polkadot/rpc-provider": "1.14.1",
|
"@polkadot/rpc-provider": "1.16.1",
|
||||||
"@polkadot/types": "1.14.1",
|
"@polkadot/types": "1.16.1",
|
||||||
"@polkadot/util": "^2.10.1",
|
"@polkadot/util": "^2.11.1",
|
||||||
"memoizee": "^0.4.14",
|
"memoizee": "^0.4.14",
|
||||||
"rxjs": "^6.5.5"
|
"rxjs": "^6.5.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/keyring": "^2.10.1"
|
"@polkadot/keyring": "^2.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ describe('Cached Observables', (): void => {
|
|||||||
|
|
||||||
it('creates different observables for different methods but same arguments', (): void => {
|
it('creates different observables for different methods but same arguments', (): void => {
|
||||||
// params do not match here
|
// params do not match here
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
const observable1 = (rpc.chain as any).subscribeNewHeads([123]);
|
const observable1 = (rpc.chain as any).subscribeNewHeads([123]);
|
||||||
const observable2 = rpc.state.subscribeStorage([123]);
|
const observable2 = rpc.state.subscribeStorage([123]);
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ function formattingTests (version: string, decorated: Metadata, encodedValues: [
|
|||||||
}
|
}
|
||||||
|
|
||||||
api.state
|
api.state
|
||||||
.subscribeStorage([iterKey])
|
.subscribeStorage([iterKey()])
|
||||||
.subscribe((value: Codec[]): void => {
|
.subscribe((value: Codec[]): void => {
|
||||||
expect(value).toHaveLength(1);
|
expect(value).toHaveLength(1);
|
||||||
// console.error('head fallback', value);
|
// console.error('head fallback', value);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ describe('Api', (): void => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
expect(isFunction((rpc as any).testing.foo)).toBe(true);
|
expect(isFunction((rpc as any).testing.foo)).toBe(true);
|
||||||
expect(rpc.sections.includes('testing')).toBe(true);
|
expect(rpc.sections.includes('testing')).toBe(true);
|
||||||
expect(rpc.mapping.get('testing_foo')).toEqual({
|
expect(rpc.mapping.get('testing_foo')).toEqual({
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ function logErrorMessage (method: string, { params, type }: DefinitionRpc, error
|
|||||||
export default class Rpc implements RpcInterface {
|
export default class Rpc implements RpcInterface {
|
||||||
readonly #storageCache = new Map<string, string | null>();
|
readonly #storageCache = new Map<string, string | null>();
|
||||||
|
|
||||||
public readonly mapping: Map<string, DefinitionRpcExt> = new Map();
|
public readonly mapping = new Map<string, DefinitionRpcExt>();
|
||||||
|
|
||||||
public readonly provider: ProviderInterface;
|
public readonly provider: ProviderInterface;
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ export default class Rpc implements RpcInterface {
|
|||||||
|
|
||||||
// decorate the sections with base and user methods
|
// decorate the sections with base and user methods
|
||||||
this.sections.forEach((sectionName): void => {
|
this.sections.forEach((sectionName): void => {
|
||||||
(this as any)[sectionName as Section] = {
|
(this as Record<string, unknown>)[sectionName as Section] = {
|
||||||
...this._createInterface(sectionName, jsonrpc[sectionName as 'babe'] || {}),
|
...this._createInterface(sectionName, jsonrpc[sectionName as 'babe'] || {}),
|
||||||
...this._createInterface(sectionName, userRpc[sectionName] || {})
|
...this._createInterface(sectionName, userRpc[sectionName] || {})
|
||||||
};
|
};
|
||||||
@@ -156,7 +156,7 @@ export default class Rpc implements RpcInterface {
|
|||||||
// `<S extends keyof RpcInterface, M extends keyof RpcInterface[S]>`
|
// `<S extends keyof RpcInterface, M extends keyof RpcInterface[S]>`
|
||||||
// Not doing so, because it makes this class a little bit less readable,
|
// Not doing so, because it makes this class a little bit less readable,
|
||||||
// and leaving it as-is doesn't harm much
|
// and leaving it as-is doesn't harm much
|
||||||
(exposed as any)[method] = isSubscription
|
(exposed as Record<string, unknown>)[method] = isSubscription
|
||||||
? this._createMethodSubscribe(section, method, def as DefinitionRpcSub)
|
? this._createMethodSubscribe(section, method, def as DefinitionRpcSub)
|
||||||
: this._createMethodSend(section, method, def);
|
: this._createMethodSend(section, method, def);
|
||||||
|
|
||||||
@@ -333,7 +333,7 @@ export default class Rpc implements RpcInterface {
|
|||||||
try {
|
try {
|
||||||
return this._formatStorageData(key, result);
|
return this._formatStorageData(key, result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Unable to decode storage ${key.section}.${key.method}:`, error.message);
|
console.error(`Unable to decode storage ${key.section || 'unknown'}.${key.method || 'unknown'}:`, (error as Error).message);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@@ -341,10 +341,10 @@ export default class Rpc implements RpcInterface {
|
|||||||
const keys = params[0] as Vec<StorageKey>;
|
const keys = params[0] as Vec<StorageKey>;
|
||||||
|
|
||||||
return keys
|
return keys
|
||||||
? this._formatStorageSet(keys, result.changes)
|
? this._formatStorageSet(keys, (result as { changes: [string, string | null][] }).changes)
|
||||||
: this.registry.createType('StorageChangeSet', result);
|
: this.registry.createType('StorageChangeSet', result);
|
||||||
} else if (rpc.type === 'Vec<StorageChangeSet>') {
|
} else if (rpc.type === 'Vec<StorageChangeSet>') {
|
||||||
const mapped = result.map(({ block, changes }: { block: string; changes: [string, string | null][] }): [Hash, Codec[]] => [
|
const mapped = (result as { block: string; changes: [string, string | null][] }[]).map(({ block, changes }): [Hash, Codec[]] => [
|
||||||
this.registry.createType('Hash', block),
|
this.registry.createType('Hash', block),
|
||||||
this._formatStorageSet(params[0] as Vec<StorageKey>, changes)
|
this._formatStorageSet(params[0] as Vec<StorageKey>, changes)
|
||||||
]);
|
]);
|
||||||
@@ -352,7 +352,7 @@ export default class Rpc implements RpcInterface {
|
|||||||
// we only query at a specific block, not a range - flatten
|
// we only query at a specific block, not a range - flatten
|
||||||
return method === 'queryStorageAt'
|
return method === 'queryStorageAt'
|
||||||
? mapped[0][1]
|
? mapped[0][1]
|
||||||
: mapped;
|
: mapped as unknown as Codec[];
|
||||||
}
|
}
|
||||||
|
|
||||||
return createTypeUnsafe(this.registry, rpc.type, [result]);
|
return createTypeUnsafe(this.registry, rpc.type, [result]);
|
||||||
@@ -404,7 +404,7 @@ export default class Rpc implements RpcInterface {
|
|||||||
try {
|
try {
|
||||||
results.push(this._formatStorageSetEntry(key, changes, withCache));
|
results.push(this._formatStorageSetEntry(key, changes, withCache));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Unable to decode storage ${key.section}.${key.method}:`, error.message);
|
console.error(`Unable to decode storage ${key.section || 'unknown'}.${key.method || 'unknown'}:`, (error as Error).message);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ describe('methodSend', (): void => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
provider = {
|
provider = {
|
||||||
send: jest.fn((method, params): Promise<any> => {
|
send: jest.fn((method, params: any[]): Promise<any> => {
|
||||||
return Promise.resolve(params[0]);
|
return Promise.resolve(params[0]);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@@ -41,8 +41,10 @@ describe('methodSend', (): void => {
|
|||||||
|
|
||||||
it('checks for mismatched parameters', (done): void => {
|
it('checks for mismatched parameters', (done): void => {
|
||||||
// private method
|
// private method
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
const method = (rpc as any)._createMethodSend('test', 'bleh', methods.bleh);
|
const method = (rpc as any)._createMethodSend('test', 'bleh', methods.bleh);
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
method(1).subscribe(
|
method(1).subscribe(
|
||||||
(): void => undefined,
|
(): void => undefined,
|
||||||
(error: Error): void => {
|
(error: Error): void => {
|
||||||
@@ -53,10 +55,13 @@ describe('methodSend', (): void => {
|
|||||||
|
|
||||||
it('calls the provider with the correct parameters', (done): void => {
|
it('calls the provider with the correct parameters', (done): void => {
|
||||||
// private method
|
// private method
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
const method = (rpc as any)._createMethodSend('test', 'blah', methods.blah);
|
const method = (rpc as any)._createMethodSend('test', 'blah', methods.blah);
|
||||||
|
|
||||||
// Args are length-prefixed, because it's a Bytes
|
// Args are length-prefixed, because it's a Bytes
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
method(new Uint8Array([2 << 2, 0x12, 0x34])).subscribe((): void => {
|
method(new Uint8Array([2 << 2, 0x12, 0x34])).subscribe((): void => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
expect(provider.send).toHaveBeenCalledWith('test_blah', ['0x1234']);
|
expect(provider.send).toHaveBeenCalledWith('test_blah', ['0x1234']);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ describe('replay', (): void => {
|
|||||||
|
|
||||||
it('subscribes via the rpc section', (done): void => {
|
it('subscribes via the rpc section', (done): void => {
|
||||||
// we don't honor types or number of params here
|
// we don't honor types or number of params here
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
(rpc.chain as any).getBlockHash = jest.fn((): Observable<number> => of(1));
|
(rpc.chain as any).getBlockHash = jest.fn((): Observable<number> => of(1));
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
(rpc.chain as any).getBlockHash(123, false).subscribe((): void => {
|
(rpc.chain as any).getBlockHash(123, false).subscribe((): void => {
|
||||||
expect(
|
expect(
|
||||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||||
@@ -32,6 +34,7 @@ describe('replay', (): void => {
|
|||||||
it('returns the observable value', (done): void => {
|
it('returns the observable value', (done): void => {
|
||||||
rpc.system.chain().subscribe((value: any): void => {
|
rpc.system.chain().subscribe((value: any): void => {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||||
expect(value.toString()).toEqual('mockChain'); // Defined in MockProvider
|
expect(value.toString()).toEqual('mockChain'); // Defined in MockProvider
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
@@ -40,9 +43,9 @@ describe('replay', (): void => {
|
|||||||
|
|
||||||
it('replay(1) works as expected', (done): void => {
|
it('replay(1) works as expected', (done): void => {
|
||||||
const observable = rpc.system.chain();
|
const observable = rpc.system.chain();
|
||||||
let a: string | undefined;
|
let a: any | undefined;
|
||||||
|
|
||||||
observable.subscribe((value: any): void => { a = value; });
|
observable.subscribe((value?: unknown): void => { a = value; });
|
||||||
|
|
||||||
setTimeout((): void => {
|
setTimeout((): void => {
|
||||||
// Subscribe again to the same observable, it should fire value immediately
|
// Subscribe again to the same observable, it should fire value immediately
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ interface Options {
|
|||||||
|
|
||||||
const l = logger('drr');
|
const l = logger('drr');
|
||||||
|
|
||||||
const CMP = (a: any, b: any): boolean =>
|
const CMP = (a: unknown, b: unknown): boolean =>
|
||||||
JSON.stringify({ t: a }) === JSON.stringify({ t: b });
|
JSON.stringify({ t: a }) === JSON.stringify({ t: b });
|
||||||
|
|
||||||
const ERR = (error: Error): Observable<never> => {
|
const ERR = (error: Error): Observable<never> => {
|
||||||
@@ -40,7 +40,7 @@ export const drr = ({ skipChange = false, skipTimeout = false }: Options = {}):
|
|||||||
catchError(ERR),
|
catchError(ERR),
|
||||||
skipChange
|
skipChange
|
||||||
? tap(NOOP)
|
? tap(NOOP)
|
||||||
: distinctUntilChanged(CMP),
|
: distinctUntilChanged<T>(CMP),
|
||||||
publishReplay(1),
|
publishReplay(1),
|
||||||
skipTimeout
|
skipTimeout
|
||||||
? refCount()
|
? refCount()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@polkadot/rpc-provider",
|
"name": "@polkadot/rpc-provider",
|
||||||
"version": "1.14.1",
|
"version": "1.16.1",
|
||||||
"description": "Transport providers for the API",
|
"description": "Transport providers for the API",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -27,17 +27,17 @@
|
|||||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
|
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.9.6",
|
"@babel/runtime": "^7.9.6",
|
||||||
"@polkadot/metadata": "1.14.1",
|
"@polkadot/metadata": "1.16.1",
|
||||||
"@polkadot/types": "1.14.1",
|
"@polkadot/types": "1.16.1",
|
||||||
"@polkadot/util": "^2.10.1",
|
"@polkadot/util": "^2.11.1",
|
||||||
"@polkadot/util-crypto": "^2.10.1",
|
"@polkadot/util-crypto": "^2.11.1",
|
||||||
"bn.js": "^5.1.1",
|
"bn.js": "^5.1.2",
|
||||||
"eventemitter3": "^4.0.1",
|
"eventemitter3": "^4.0.4",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"websocket": "^1.0.31"
|
"websocket": "^1.0.31"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/keyring": "^2.10.1",
|
"@polkadot/keyring": "^2.11.1",
|
||||||
"mock-socket": "^9.0.3",
|
"mock-socket": "^9.0.3",
|
||||||
"nock": "^12.0.3"
|
"nock": "^12.0.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ describe('encodeObject', (): void => {
|
|||||||
|
|
||||||
it('encodes a valid JsonRPC object', (): void => {
|
it('encodes a valid JsonRPC object', (): void => {
|
||||||
expect(
|
expect(
|
||||||
coder.encodeObject('method', 'params')
|
coder.encodeObject('method', ['a', 'b'])
|
||||||
).toEqual({
|
).toEqual({
|
||||||
id: 1,
|
id: 1,
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
method: 'method',
|
method: 'method',
|
||||||
params: 'params'
|
params: ['a', 'b']
|
||||||
});
|
});
|
||||||
expect(coder.getId()).toEqual(1);
|
expect(coder.getId()).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function formatErrorData (data?: string | number): string {
|
|||||||
export default class RpcCoder {
|
export default class RpcCoder {
|
||||||
#id = 0;
|
#id = 0;
|
||||||
|
|
||||||
public decodeResponse (response: JsonRpcResponse): any {
|
public decodeResponse (response: JsonRpcResponse): unknown {
|
||||||
assert(response, 'Empty response object received');
|
assert(response, 'Empty response object received');
|
||||||
assert(response.jsonrpc === '2.0', 'Invalid jsonrpc field in decoded object');
|
assert(response.jsonrpc === '2.0', 'Invalid jsonrpc field in decoded object');
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ export default class RpcCoder {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public encodeObject (method: string, params: any | any[]): JsonRpcRequest {
|
public encodeObject (method: string, params: unknown[]): JsonRpcRequest {
|
||||||
return {
|
return {
|
||||||
id: ++this.#id,
|
id: ++this.#id,
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ describe('Http', (): void => {
|
|||||||
return http.subscribe('', '', [], (cb): void => {
|
return http.subscribe('', '', [], (cb): void => {
|
||||||
expect(cb).toEqual(expect.anything());
|
expect(cb).toEqual(expect.anything());
|
||||||
}).catch((error): void => {
|
}).catch((error): void => {
|
||||||
expect(error.message).toMatch(/does not have subscriptions/);
|
expect((error as Error).message).toMatch(/does not have subscriptions/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not (yet) support unsubscribe', (): Promise<boolean | void> => {
|
it('does not (yet) support unsubscribe', (): Promise<boolean | void> => {
|
||||||
return http.unsubscribe('', '', 0).catch((error): void => {
|
return http.unsubscribe('', '', 0).catch((error): void => {
|
||||||
expect(error.message).toMatch(/does not have subscriptions/);
|
expect((error as Error).message).toMatch(/does not have subscriptions/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ export default class HttpProvider implements ProviderInterface {
|
|||||||
|
|
||||||
assert(response.ok, `[${response.status}]: ${response.statusText}`);
|
assert(response.ok, `[${response.status}]: ${response.statusText}`);
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
return this.#coder.decodeResponse(result);
|
return this.#coder.decodeResponse(result);
|
||||||
|
|||||||
@@ -10,14 +10,17 @@ describe('http/polyfill', (): void => {
|
|||||||
let origFetch: any;
|
let origFetch: any;
|
||||||
|
|
||||||
beforeEach((): void => {
|
beforeEach((): void => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
origFetch = global.fetch;
|
origFetch = global.fetch;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach((): void => {
|
afterEach((): void => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
global.fetch = origFetch;
|
global.fetch = origFetch;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('polyfills with no exceptions (without fetch)', (): void => {
|
it('polyfills with no exceptions (without fetch)', (): void => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
(global as any).fetch = undefined;
|
(global as any).fetch = undefined;
|
||||||
require('./polyfill');
|
require('./polyfill');
|
||||||
|
|
||||||
@@ -25,6 +28,7 @@ describe('http/polyfill', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('polyfills with no exceptions (with fetch)', (): void => {
|
it('polyfills with no exceptions (with fetch)', (): void => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
(global as any).fetch = (): boolean => true;
|
(global as any).fetch = (): boolean => true;
|
||||||
require('./polyfill');
|
require('./polyfill');
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ describe('send', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('passes the body through correctly', (): Promise<void> => {
|
it('passes the body through correctly', (): Promise<void> => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
mock = mockHttp([{
|
mock = mockHttp([{
|
||||||
method: 'test_body',
|
method: 'test_body',
|
||||||
reply: {
|
reply: {
|
||||||
@@ -31,6 +32,7 @@ describe('send', (): void => {
|
|||||||
return http
|
return http
|
||||||
.send('test_body', ['param'])
|
.send('test_body', ['param'])
|
||||||
.then((): void => {
|
.then((): void => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
expect((mock.body as any).test_body).toEqual({
|
expect((mock.body as any).test_body).toEqual({
|
||||||
id: 1,
|
id: 1,
|
||||||
jsonrpc: '2.0',
|
jsonrpc: '2.0',
|
||||||
@@ -41,6 +43,7 @@ describe('send', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws error when !response.ok', (): Promise<any> => {
|
it('throws error when !response.ok', (): Promise<any> => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
mock = mockHttp([{
|
mock = mockHttp([{
|
||||||
code: 500,
|
code: 500,
|
||||||
method: 'test_error'
|
method: 'test_error'
|
||||||
@@ -49,7 +52,7 @@ describe('send', (): void => {
|
|||||||
return http
|
return http
|
||||||
.send('test_error', [])
|
.send('test_error', [])
|
||||||
.catch((error): void => {
|
.catch((error): void => {
|
||||||
expect(error.message).toMatch(/\[500\]: Internal Server/);
|
expect((error as Error).message).toMatch(/\[500\]: Internal Server/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// This software may be modified and distributed under the terms
|
// This software may be modified and distributed under the terms
|
||||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
import { Header } from '@polkadot/types/interfaces';
|
import { Header } from '@polkadot/types/interfaces';
|
||||||
import { Codec, Registry } from '@polkadot/types/types';
|
import { Codec, Registry } from '@polkadot/types/types';
|
||||||
@@ -22,14 +22,15 @@ import { randomAsU8a } from '@polkadot/util-crypto';
|
|||||||
|
|
||||||
const INTERVAL = 1000;
|
const INTERVAL = 1000;
|
||||||
const SUBSCRIPTIONS: string[] = Array.prototype.concat.apply(
|
const SUBSCRIPTIONS: string[] = Array.prototype.concat.apply(
|
||||||
[], Object.values(jsonrpc).map((section): string[] =>
|
[],
|
||||||
|
Object.values(jsonrpc).map((section): string[] =>
|
||||||
Object
|
Object
|
||||||
.values(section)
|
.values(section)
|
||||||
.filter(({ isSubscription }) => isSubscription)
|
.filter(({ isSubscription }) => isSubscription)
|
||||||
.map(({ jsonrpc }) => jsonrpc)
|
.map(({ jsonrpc }) => jsonrpc)
|
||||||
.concat('chain_subscribeNewHead')
|
.concat('chain_subscribeNewHead')
|
||||||
)
|
)
|
||||||
);
|
) as string[];
|
||||||
|
|
||||||
const keyring = testKeyring({ type: 'ed25519' });
|
const keyring = testKeyring({ type: 'ed25519' });
|
||||||
const l = logger('api-mock');
|
const l = logger('api-mock');
|
||||||
@@ -50,12 +51,14 @@ export default class Mock implements ProviderInterface {
|
|||||||
|
|
||||||
private prevNumber = new BN(-1);
|
private prevNumber = new BN(-1);
|
||||||
|
|
||||||
private requests: Record<string, (...params: any[]) => any> = {
|
private requests: Record<string, (...params: any[]) => unknown> = {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-unsafe-member-access
|
||||||
chain_getBlock: (hash: string): any => this.registry.createType('SignedBlock', rpcSignedBlock.result).toJSON(),
|
chain_getBlock: (hash: string): any => this.registry.createType('SignedBlock', rpcSignedBlock.result).toJSON(),
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
chain_getBlockHash: (blockNumber: number): string => '0x1234',
|
chain_getBlockHash: (blockNumber: number): string => '0x1234',
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
chain_getFinalizedHead: () => this.registry.createType('Header', rpcHeader.result).hash,
|
chain_getFinalizedHead: () => this.registry.createType('Header', rpcHeader.result).hash,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||||
chain_getHeader: () => this.registry.createType('Header', rpcHeader.result).toJSON(),
|
chain_getHeader: () => this.registry.createType('Header', rpcHeader.result).toJSON(),
|
||||||
state_getKeys: (): string[] => [],
|
state_getKeys: (): string[] => [],
|
||||||
state_getKeysPaged: (): string[] => [],
|
state_getKeysPaged: (): string[] => [],
|
||||||
@@ -112,7 +115,7 @@ export default class Mock implements ProviderInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/require-await
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
public async send (method: string, params: any[]): Promise<any> {
|
public async send (method: string, params: any[]): Promise<unknown> {
|
||||||
if (!this.requests[method]) {
|
if (!this.requests[method]) {
|
||||||
throw new Error(`provider.send: Invalid method '${method}'`);
|
throw new Error(`provider.send: Invalid method '${method}'`);
|
||||||
}
|
}
|
||||||
@@ -121,11 +124,11 @@ export default class Mock implements ProviderInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/require-await
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
public async subscribe (type: string, method: string, ...params: any[]): Promise<number> {
|
public async subscribe (type: string, method: string, ...params: unknown[]): Promise<number> {
|
||||||
l.debug((): any => ['subscribe', method, params]);
|
l.debug((): any => ['subscribe', method, params]);
|
||||||
|
|
||||||
if (this.subscriptions[method]) {
|
if (this.subscriptions[method]) {
|
||||||
const callback: MockStateSubscriptionCallback = params.pop();
|
const callback = params.pop() as MockStateSubscriptionCallback;
|
||||||
const id = ++this.subscriptionId;
|
const id = ++this.subscriptionId;
|
||||||
|
|
||||||
this.subscriptions[method].callbacks[id] = callback;
|
this.subscriptions[method].callbacks[id] = callback;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ describe('send', (): void => {
|
|||||||
return mock
|
return mock
|
||||||
.send('something_invalid', [])
|
.send('something_invalid', [])
|
||||||
.catch((error): void => {
|
.catch((error): void => {
|
||||||
expect(error.message).toMatch(/Invalid method/);
|
expect((error as Error).message).toMatch(/Invalid method/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ describe('subscribe', (): void => {
|
|||||||
return mock
|
return mock
|
||||||
.subscribe('test', 'test_notFound')
|
.subscribe('test', 'test_notFound')
|
||||||
.catch((error): void => {
|
.catch((error): void => {
|
||||||
expect(error.message).toMatch(/Invalid method 'test_notFound'/);
|
expect((error as Error).message).toMatch(/Invalid method 'test_notFound'/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ describe('subscribe', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('calls back with new headers', (done): Promise<number> => {
|
it('calls back with new headers', (done): Promise<number> => {
|
||||||
return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: any): void => {
|
return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: { number: number }): void => {
|
||||||
if (header.number === 4) {
|
if (header.number === 4) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ describe('subscribe', (): void => {
|
|||||||
it('handles errors withing callbacks gracefully', (done): Promise<number> => {
|
it('handles errors withing callbacks gracefully', (done): Promise<number> => {
|
||||||
let hasThrown = false;
|
let hasThrown = false;
|
||||||
|
|
||||||
return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: any): void => {
|
return mock.subscribe('chain_newHead', 'chain_subscribeNewHead', (_: any, header: { number: number }): void => {
|
||||||
if (!hasThrown) {
|
if (!hasThrown) {
|
||||||
hasThrown = true;
|
hasThrown = true;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user