Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25288f664a | ||
|
|
879c5d7b44 | ||
|
|
cdaec1953c | ||
|
|
f4bf7a9c52 | ||
|
|
7b46c6aa15 | ||
|
|
d28f4ccfa0 | ||
|
|
e5b05dc700 | ||
|
|
bf9831753e | ||
|
|
5e1670dbae | ||
|
|
0d0a230c86 | ||
|
|
9989b69b46 | ||
|
|
66693253ef | ||
|
|
cbffc37dcf | ||
|
|
74ee42ed66 | ||
|
|
f642e2399f | ||
|
|
8cefb055db | ||
|
|
1f31756019 | ||
|
|
4d6a1da6d5 | ||
|
|
d62e720627 | ||
|
|
4af4470998 | ||
|
|
8bb6218132 | ||
|
|
f4197f8752 | ||
|
|
7cfad3b1c4 | ||
|
|
ff67a659b6 | ||
|
|
a5c69a42fc | ||
|
|
3facbf00eb | ||
|
|
5a6eece6d6 | ||
|
|
9219fa3197 | ||
|
|
32b9a39b1e | ||
|
|
61a7fe6307 | ||
|
|
ca755d3e0d | ||
|
|
442dba42ba | ||
|
|
ba80dd8873 | ||
|
|
1d35302dca | ||
|
|
39c3121437 | ||
|
|
d7de1d84fb | ||
|
|
0ee1dfb353 | ||
|
|
0a6f1d87d4 | ||
|
|
b7c563391c | ||
|
|
b648c4ba6c | ||
|
|
0eb995c9a1 | ||
|
|
936d14ffea | ||
|
|
72c7a0a34b | ||
|
|
8402013e97 | ||
|
|
fde6b72974 | ||
|
|
d98d4d6908 | ||
|
|
ed384666ee | ||
|
|
4e64e3d654 | ||
|
|
72b4b51915 | ||
|
|
81f5bf96f5 | ||
|
|
e935281b77 | ||
|
|
e132330c0b | ||
|
|
21594aa660 | ||
|
|
6fb7989b41 | ||
|
|
1f38a38bd5 | ||
|
|
e918aa8b14 | ||
|
|
4a33b18ac4 | ||
|
|
cb97fd1a48 | ||
|
|
51600bc560 | ||
|
|
12344ed980 | ||
|
|
0b6773a744 | ||
|
|
17a38e9c09 | ||
|
|
70499fe6ac | ||
|
|
64493e0091 | ||
|
|
ae3efb31f8 | ||
|
|
6da58d0698 | ||
|
|
07f40c1429 | ||
|
|
f5f67e795e | ||
|
|
5b0652c272 | ||
|
|
53ef5f7c56 | ||
|
|
71f99875e4 | ||
|
|
a097075bfe | ||
|
|
527f840950 | ||
|
|
7fadc7eedb | ||
|
|
35663319d9 | ||
|
|
b9d9670d18 | ||
|
|
fd027f452c | ||
|
|
10a6e03f85 | ||
|
|
522eb8359f | ||
|
|
d1fd7f75af | ||
|
|
bb61b1e6ac | ||
|
|
7c17baa5be | ||
|
|
9e7c0a1959 | ||
|
|
db2e97bf66 | ||
|
|
057f6b6041 | ||
|
|
ca82336087 | ||
|
|
761ceaeaa3 | ||
|
|
0cbca0adb8 | ||
|
|
d24db4fd6a | ||
|
|
4a893b9feb | ||
|
|
71a0a84f26 | ||
|
|
44d241f489 | ||
|
|
a4cb5f558d | ||
|
|
aef4d07c48 | ||
|
|
6a5f1bbbf4 | ||
|
|
e60ef2d677 | ||
|
|
f4622d05db | ||
|
|
47d7900809 | ||
|
|
2c86e9347b | ||
|
|
5827d298ad | ||
|
|
60e0f69920 | ||
|
|
97f1ee17b0 | ||
|
|
85215a308d | ||
|
|
89fa4edcf7 | ||
|
|
ec42fb9bff | ||
|
|
96d696dbf3 | ||
|
|
b7992ecc0b | ||
|
|
0acae6e158 | ||
|
|
6afea5043e | ||
|
|
c9ee8d9942 | ||
|
|
55f4e150c0 | ||
|
|
3e3e9c5f5a | ||
|
|
66215890dd | ||
|
|
bf6c7ee0c3 | ||
|
|
f726edf725 | ||
|
|
d917861a77 | ||
|
|
12a54efde5 | ||
|
|
9ae87bed78 | ||
|
|
7f5a52258c | ||
|
|
2c212e6b4d | ||
|
|
3d75744a20 | ||
|
|
d2ff259989 | ||
|
|
cac2ef30a1 | ||
|
|
ea38dedcc1 | ||
|
|
0bd632e612 | ||
|
|
4ce7163bb1 | ||
|
|
72fbd3f829 | ||
|
|
f20fadb51c | ||
|
|
0e0183dc99 | ||
|
|
fa71e129c2 | ||
|
|
cb68842da6 | ||
|
|
44f348ecc5 | ||
|
|
891a6106f0 | ||
|
|
90fcc234a9 | ||
|
|
72fcd97cdb | ||
|
|
2ded2052b7 | ||
|
|
a8da5707f2 | ||
|
|
f508668c46 | ||
|
|
15ed0723f1 | ||
|
|
c9b0502542 | ||
|
|
0d5a841a81 | ||
|
|
e47b8c1e73 | ||
|
|
50fe50d1a8 | ||
|
|
9e4669b8b4 | ||
|
|
1e383315e2 | ||
|
|
6f66eb2b66 | ||
|
|
0864340ae2 |
+3
-1
@@ -40,4 +40,6 @@
|
||||
6.0.5
|
||||
6.1.2
|
||||
|
||||
6.4.2
|
||||
6.4.2
|
||||
6.5.2
|
||||
6.7.2
|
||||
@@ -1,5 +1,101 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 6.8.1 Nov 11, 2021
|
||||
|
||||
Upgrade priority: Low. Recommended for chains with non-MultiSignature variants where `paymentInfo` is required.
|
||||
|
||||
Changes:
|
||||
|
||||
- Adjust `paymentInfo` signatures to cater for non-MultiSignature variants
|
||||
- Remove `::generic::` from names & namespaces under metadata v14
|
||||
- Add Polkadot 9122 upgrade block
|
||||
- Cleanup Polkadot/Kusama/Westend/Rococo known types (>= v14 metadata)
|
||||
- Internal `decorateMethod{Promise, Rx}` renamed to `to{Promise, Rx}Method`
|
||||
- Add RPC provider-level LRU for historic requests
|
||||
- Add optional known runtime version param to internal `rx.queryAt`
|
||||
|
||||
|
||||
## 6.7.2 Nov 9, 2021
|
||||
|
||||
Upgrade priority: Low. Recommended for chains on metadata v14 with non-default `Address` implementations.
|
||||
|
||||
Changes:
|
||||
|
||||
- Detect `AccountId` & `Address` types via `SpRuntime*` definitions
|
||||
- Adjust api-derive call ordering when using `.queryAt`
|
||||
|
||||
|
||||
## 6.7.1 Nov 7, 2021
|
||||
|
||||
Upgrade priority: Low. Internal maintenance updates, focussed on internal optimizations.
|
||||
|
||||
Changelog:
|
||||
|
||||
- Optimize Extrinsic & block handling (Thanks to https://github.com/nazar-pc)
|
||||
- Add `account::AccountId20` mapping (Thanks to https://github.com/joelamouche)
|
||||
|
||||
Changes:
|
||||
|
||||
- Use new-gen `voteLockingPeriod` in democracy derives (as available)
|
||||
- Dynamically inject getters for `Extrinsic` payloads
|
||||
- Optimize caching for complex constructed type classes per registry
|
||||
- Convert metadata, rpc and api to use lazy decoration
|
||||
- Split u8a decoding paths for `Vec` (different from general path)
|
||||
- Keep track of initial u8a decoded length inside base Codecs
|
||||
- Extract multi property assignments for `Struct`, `Set`, `Json` & `Enum`
|
||||
- Move `PortableRegistry` location inside `@polkadot/types/metadata`
|
||||
- Bump static metadata for latest Substrate, Polkadot & Kusama
|
||||
|
||||
|
||||
## 6.6.1 Nov 1, 2021
|
||||
|
||||
Upgrade priority: Low. Internal maintenance updates.
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix construction for `palletVersion` keys with correct prefix
|
||||
- Add Polkadot `EthereumAddress` as a known `PortableRegistry` override
|
||||
- De-dupe `PortableRegistry` namespace splitting operations
|
||||
- Optimize internal `AbstractArray` & `Struct` u8a decoding
|
||||
- Shortcut `Struct` construction from `Struct` instance
|
||||
- Use internal `lookupName` in `createClass` (allows deeply recursive lookups)
|
||||
- Codec `toHex()` will now correctly return the TS `HexString` type
|
||||
- Update known upgrade blocks for Westend & Kusama
|
||||
- Bump static metadata for latest Substrate, Polkadot & Kusama
|
||||
|
||||
|
||||
## 6.5.2 Oct 26, 2021
|
||||
|
||||
Upgrade priority: Low. Recommended for users with `.at` queries on unknown blocks.
|
||||
|
||||
Changes:
|
||||
|
||||
- Adjust `toHuman` on `Call` to return names & (not only) values
|
||||
- Allow for optional known `RuntimeVersion` to short-circuit `api.at`
|
||||
- Ensure `Struct` decodes fully on `null` input (equivalent to `undefined` & `{}`)
|
||||
|
||||
|
||||
## 6.5.1 Oct 24, 2021
|
||||
|
||||
Upgrade priority: Low. Internal maintenance upgrades.
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add `Auction` to Polkadot pre-0.9.11 `ProxyType` (Thanks to https://github.com/wirednkod)
|
||||
|
||||
Changes:
|
||||
|
||||
- Ecah module now exposes the Substrate-added `palletVersion` storage item
|
||||
- Adjust Websocket `maxReceivedFrameSize` under Node
|
||||
- `TypeDef` structures now contain the `typeName` from metadata v14 on fields
|
||||
- Fix browser bundle imports for xcm-mapping (move to `types-known`)
|
||||
- Expose all extracted type names in `PortableRegistry`
|
||||
- Adjust `toJSON` (Ascii) output detection on `Raw`
|
||||
- Adjust `api.rpc.*.*.raw(..args)` return to the actual over-the-wire JSON result
|
||||
- Remove `api.rpc.*.*.json(..args)` since it now overlaps with new `.raw`
|
||||
- Bump static metadata for latest Substrate, Polkadot & Kusama
|
||||
|
||||
|
||||
## 6.4.2 Oct 18, 2021
|
||||
|
||||
Upgrade priority: Low. Recommended for Westmint runtime 500+
|
||||
|
||||
+19
-13
@@ -1,40 +1,46 @@
|
||||
{
|
||||
"repository": "https://github.com/polkadot-js/api",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api#readme",
|
||||
"license": "Apache-2",
|
||||
"packageManager": "yarn@3.0.1",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "commonjs",
|
||||
"version": "6.8.1",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"resolutions": {
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn build:interfaces && polkadot-dev-build-ts",
|
||||
"build:extra": "(cd packages/typegen && copyfiles scripts/* build)",
|
||||
"build:interfaces": "polkadot-types-internal-interfaces",
|
||||
"build:release": "polkadot-ci-ghact-build",
|
||||
"build:rollup": "polkadot-exec-rollup --config",
|
||||
"docs:metadata": "polkadot-types-internal-metadata",
|
||||
"chain:info": "polkadot-types-chain-info",
|
||||
"lint": "polkadot-dev-run-lint",
|
||||
"clean": "polkadot-dev-clean-build",
|
||||
"docs:metadata": "polkadot-types-internal-metadata",
|
||||
"lint": "polkadot-dev-run-lint",
|
||||
"postinstall": "polkadot-dev-yarn-only",
|
||||
"test": "polkadot-dev-run-test --coverage --forceExit --runInBand --testPathIgnorePatterns e2e",
|
||||
"test:one": "polkadot-dev-run-test --detectOpenHandles --forceExit",
|
||||
"test:watch": "polkadot-dev-run-test --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.8",
|
||||
"@babel/register": "^7.15.3",
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/dev": "^0.63.3",
|
||||
"@polkadot/ts": "^0.4.9",
|
||||
"@babel/core": "^7.16.0",
|
||||
"@babel/register": "^7.16.0",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/dev": "^0.63.27",
|
||||
"@polkadot/ts": "^0.4.13",
|
||||
"@polkadot/typegen": "workspace:packages/typegen",
|
||||
"@types/jest": "^27.0.2",
|
||||
"copyfiles": "^2.4.1"
|
||||
},
|
||||
"version": "6.4.2",
|
||||
"packageManager": "yarn@3.0.1"
|
||||
"resolutions": {
|
||||
"typescript": "^4.4.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
{
|
||||
"name": "@polkadot/api-contract",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Interfaces for interacting with contracts and contract ABIs",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/api-contract",
|
||||
"repository": {
|
||||
"directory": "packages/api-contract",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/api": "6.4.2",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"@polkadot/util": "^7.5.1",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/api": "6.8.1",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"@polkadot/util": "^7.8.2",
|
||||
"rxjs": "^7.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2021 @polkadot/api-contract authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Bytes } from '@polkadot/types';
|
||||
import type { Bytes, PortableRegistry } from '@polkadot/types';
|
||||
import type { ChainProperties, ContractConstructorSpec, ContractEventSpec, ContractMessageParamSpec, ContractMessageSpec, ContractMetadataLatest, ContractProjectInfo } from '@polkadot/types/interfaces';
|
||||
import type { AnyJson, Codec, Registry } from '@polkadot/types/types';
|
||||
import type { AbiConstructor, AbiEvent, AbiMessage, AbiParam, DecodedEvent, DecodedMessage } from '../types';
|
||||
@@ -45,7 +45,7 @@ function parseJson (json: AnyJson, chainProperties?: ChainProperties): [AnyJson,
|
||||
const latest = metadata.isV0
|
||||
? toLatest(registry, metadata.asV0)
|
||||
: metadata.asV1;
|
||||
const lookup = registry.createType('PortableRegistry', { types: latest.types });
|
||||
const lookup = registry.createType<PortableRegistry>('PortableRegistry', { types: latest.types });
|
||||
|
||||
// attach the lookup to the registry - now the types are known
|
||||
registry.setLookup(lookup);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { ContractMetadataLatest, ContractMetadataV0 } from '@polkadot/types/interfaces';
|
||||
import type { Registry } from '@polkadot/types/types';
|
||||
|
||||
import { convertSiV0toV1 } from '@polkadot/types/generic/PortableRegistry';
|
||||
import { convertSiV0toV1 } from '@polkadot/types';
|
||||
|
||||
export function toLatest (registry: Registry, v0: ContractMetadataV0): ContractMetadataLatest {
|
||||
return registry.createType('ContractMetadataLatest', {
|
||||
|
||||
@@ -23,7 +23,8 @@ export abstract class Base<ApiType extends ApiTypes> {
|
||||
this.api = api;
|
||||
this._decorateMethod = decorateMethod;
|
||||
|
||||
assert(!!(api && api.isConnected && api.tx && api.tx.contracts && Object.keys(api.tx.contracts).length), 'Your API has not been initialized correctly and it not decorated with the runtime interfaces for contracts as retrieved from the on-chain runtime');
|
||||
assert(!!(api && api.isConnected && api.tx), 'Your API has not been initialized correctly and is not connected to a chain');
|
||||
assert(!!(api.tx.contracts && Object.keys(api.tx.contracts).length), 'You need to connect to a chain with a runtime that supports contracts');
|
||||
assert(isFunction(api.tx.contracts.instantiateWithCode), 'You need to connect to a chain with a runtime with a V3 contracts module. The runtime does not expose api.tx.contracts.instantiateWithCode');
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { AnyJson } from '@polkadot/types/types';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { decorateMethodPromise } from '@polkadot/api';
|
||||
import { toPromiseMethod } from '@polkadot/api';
|
||||
|
||||
import v0contractFlipper from '../../test/contracts/ink/v0/flipper.contract.json';
|
||||
import v0abiFlipper from '../../test/contracts/ink/v0/flipper.json';
|
||||
@@ -19,19 +19,19 @@ const v0wasmFlipper = fs.readFileSync(path.join(__dirname, '../../test/contracts
|
||||
describe('Code', (): void => {
|
||||
it('can construct with an individual ABI/WASM combo', (): void => {
|
||||
expect(
|
||||
() => new Code(mockApi, v0abiFlipper as AnyJson, v0wasmFlipper, decorateMethodPromise)
|
||||
() => new Code(mockApi, v0abiFlipper as AnyJson, v0wasmFlipper, toPromiseMethod)
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('can construct with an .contract ABI (v0)', (): void => {
|
||||
expect(
|
||||
() => new Code(mockApi, v0contractFlipper as AnyJson, null, decorateMethodPromise)
|
||||
() => new Code(mockApi, v0contractFlipper as AnyJson, null, toPromiseMethod)
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it.only('can construct with an .contract ABI (v1)', (): void => {
|
||||
expect(
|
||||
() => new Code(mockApi, v1contractFlipper as AnyJson, null, decorateMethodPromise)
|
||||
() => new Code(mockApi, v1contractFlipper as AnyJson, null, toPromiseMethod)
|
||||
).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/api-contract', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/api-contract', version: '6.8.1' };
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import type { Hash } from '@polkadot/types/interfaces';
|
||||
import type { AnyJson } from '@polkadot/types/types';
|
||||
|
||||
import { ApiPromise, decorateMethodPromise } from '@polkadot/api';
|
||||
import { ApiPromise, toPromiseMethod } from '@polkadot/api';
|
||||
|
||||
import { Abi } from '../Abi';
|
||||
import { Blueprint as BaseBlueprint } from '../base';
|
||||
|
||||
export class Blueprint extends BaseBlueprint<'promise'> {
|
||||
constructor (api: ApiPromise, abi: AnyJson | Abi, codeHash: string | Hash) {
|
||||
super(api, abi, codeHash, decorateMethodPromise);
|
||||
super(api, abi, codeHash, toPromiseMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import type { ApiPromise } from '@polkadot/api';
|
||||
import type { AnyJson } from '@polkadot/types/types';
|
||||
|
||||
import { decorateMethodPromise } from '@polkadot/api';
|
||||
import { toPromiseMethod } from '@polkadot/api';
|
||||
|
||||
import { Abi } from '../Abi';
|
||||
import { Code as BaseCode } from '../base';
|
||||
|
||||
export class Code extends BaseCode<'promise'> {
|
||||
constructor (api: ApiPromise, abi: AnyJson | Abi, wasm: Uint8Array | string | Buffer | null | undefined) {
|
||||
super(api, abi, wasm, decorateMethodPromise);
|
||||
super(api, abi, wasm, toPromiseMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import type { AccountId } from '@polkadot/types/interfaces';
|
||||
import type { AnyJson } from '@polkadot/types/types';
|
||||
|
||||
import { ApiPromise, decorateMethodPromise } from '@polkadot/api';
|
||||
import { ApiPromise, toPromiseMethod } from '@polkadot/api';
|
||||
|
||||
import { Abi } from '../Abi';
|
||||
import { Contract as BaseContract } from '../base';
|
||||
|
||||
export class Contract extends BaseContract<'promise'> {
|
||||
constructor (api: ApiPromise, abi: AnyJson | Abi, address: string | AccountId) {
|
||||
super(api, abi, address, decorateMethodPromise);
|
||||
super(api, abi, address, toPromiseMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import type { Hash } from '@polkadot/types/interfaces';
|
||||
import type { AnyJson } from '@polkadot/types/types';
|
||||
|
||||
import { ApiRx, decorateMethodRx } from '@polkadot/api';
|
||||
import { ApiRx, toRxMethod } from '@polkadot/api';
|
||||
|
||||
import { Abi } from '../Abi';
|
||||
import { Blueprint as BaseBlueprint } from '../base';
|
||||
|
||||
export class Blueprint extends BaseBlueprint<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: AnyJson | Abi, codeHash: string | Hash) {
|
||||
super(api, abi, codeHash, decorateMethodRx);
|
||||
super(api, abi, codeHash, toRxMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import type { ApiRx } from '@polkadot/api';
|
||||
import type { AnyJson } from '@polkadot/types/types';
|
||||
|
||||
import { decorateMethodRx } from '@polkadot/api';
|
||||
import { toRxMethod } from '@polkadot/api';
|
||||
|
||||
import { Abi } from '../Abi';
|
||||
import { Code as BaseCode } from '../base';
|
||||
|
||||
export class Code extends BaseCode<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: AnyJson | Abi, wasm: Uint8Array | string | Buffer | null | undefined) {
|
||||
super(api, abi, wasm, decorateMethodRx);
|
||||
super(api, abi, wasm, toRxMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
import type { AccountId } from '@polkadot/types/interfaces';
|
||||
import type { AnyJson } from '@polkadot/types/types';
|
||||
|
||||
import { ApiRx, decorateMethodRx } from '@polkadot/api';
|
||||
import { ApiRx, toRxMethod } from '@polkadot/api';
|
||||
|
||||
import { Abi } from '../Abi';
|
||||
import { Contract as BaseContract } from '../base';
|
||||
|
||||
export class Contract extends BaseContract<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: AnyJson | Abi, address: string | AccountId) {
|
||||
super(api, abi, address, decorateMethodRx);
|
||||
super(api, abi, address, toRxMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"lookupIndex": 1,
|
||||
"lookupName": "RecursiveMyEnum",
|
||||
"type": "Lookup1",
|
||||
"typeName": "MyEnum",
|
||||
"index": 1,
|
||||
"name": "B"
|
||||
}
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
{
|
||||
"name": "@polkadot/api-derive",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/api-derive",
|
||||
"repository": {
|
||||
"directory": "packages/api-derive",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/api": "6.4.2",
|
||||
"@polkadot/rpc-core": "6.4.2",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"@polkadot/util": "^7.5.1",
|
||||
"@polkadot/util-crypto": "^7.5.1",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/api": "6.8.1",
|
||||
"@polkadot/rpc-core": "6.8.1",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"@polkadot/util": "^7.8.2",
|
||||
"@polkadot/util-crypto": "^7.8.2",
|
||||
"rxjs": "^7.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^7.5.1",
|
||||
"@polkadot/rpc-provider": "6.4.2"
|
||||
"@polkadot/keyring": "^7.8.2",
|
||||
"@polkadot/rpc-provider": "6.8.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { Observable } from 'rxjs';
|
||||
import type { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import type { AnyFunction } from '@polkadot/types/types';
|
||||
|
||||
import { lazyDeriveSection } from './util/lazy';
|
||||
import * as accounts from './accounts';
|
||||
import * as balances from './balances';
|
||||
import * as bounties from './bounties';
|
||||
@@ -32,6 +33,8 @@ interface Avail {
|
||||
withDetect?: boolean;
|
||||
}
|
||||
|
||||
export { lazyDeriveSection };
|
||||
|
||||
export const derive = { accounts, balances, bounties, chain, contracts, council, crowdloan, democracy, elections, imOnline, membership, parachains, session, society, staking, technicalCommittee, treasury, tx };
|
||||
|
||||
type DeriveSection<Section> = {
|
||||
@@ -66,49 +69,60 @@ const checks: Record<string, Avail> = {
|
||||
treasury: { instances: ['treasury'] }
|
||||
};
|
||||
|
||||
function getModuleInstances (api: ApiInterfaceRx, specName: string, moduleName: string): string[] {
|
||||
return api.registry.getModuleInstances(specName, moduleName) || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object that will inject `api` into all the functions inside
|
||||
* `allSections`, and keep the object architecture of `allSections`.
|
||||
*/
|
||||
/** @internal */
|
||||
function injectFunctions<AllSections> (instanceId: string, api: ApiInterfaceRx, allSections: AllSections): DeriveAllSections<AllSections> {
|
||||
function injectFunctions (instanceId: string, api: ApiInterfaceRx, derives: DeriveCustom): ExactDerive {
|
||||
const queryKeys = Object.keys(api.query);
|
||||
const specName = api.runtimeVersion.specName.toString();
|
||||
|
||||
return Object
|
||||
.keys(allSections)
|
||||
.filter((sectionName) =>
|
||||
!checks[sectionName] ||
|
||||
checks[sectionName].instances.some((q) => queryKeys.includes(q)) ||
|
||||
(
|
||||
checks[sectionName].withDetect &&
|
||||
checks[sectionName].instances.some((q) =>
|
||||
(api.registry.getModuleInstances(specName, q) || []).some((q) => queryKeys.includes(q))
|
||||
)
|
||||
)
|
||||
const filterQueryKeys = (q: string) =>
|
||||
queryKeys.includes(q);
|
||||
|
||||
const filterInstances = (q: string) =>
|
||||
getModuleInstances(api, specName, q).some(filterQueryKeys);
|
||||
|
||||
const isIncluded = (s: string) => (
|
||||
!checks[s] ||
|
||||
checks[s].instances.some(filterQueryKeys) ||
|
||||
(
|
||||
checks[s].withDetect &&
|
||||
checks[s].instances.some(filterInstances)
|
||||
)
|
||||
.reduce((derives, sectionName): DeriveAllSections<AllSections> => {
|
||||
const section = allSections[sectionName as keyof AllSections];
|
||||
);
|
||||
|
||||
derives[sectionName as keyof AllSections] = Object
|
||||
.entries(section)
|
||||
.reduce((methods, [methodName, creator]): DeriveSection<typeof section> => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
||||
methods[methodName as keyof typeof section] = creator(instanceId, api);
|
||||
const getKeys = (section: string) =>
|
||||
Object.keys(derives[section]);
|
||||
|
||||
return methods;
|
||||
}, {} as DeriveSection<typeof section>);
|
||||
const creator = (section: string, method: string) =>
|
||||
derives[section][method](instanceId, api);
|
||||
|
||||
return derives;
|
||||
}, {} as DeriveAllSections<AllSections>);
|
||||
const result: Record<string, Record<string, AnyFunction>> = {};
|
||||
const names = Object.keys(derives);
|
||||
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
const name = names[i];
|
||||
|
||||
if (isIncluded(name)) {
|
||||
lazyDeriveSection(result, name, getKeys, creator);
|
||||
}
|
||||
}
|
||||
|
||||
return result as ExactDerive;
|
||||
}
|
||||
|
||||
// FIXME The return type of this function should be {...ExactDerive, ...DeriveCustom}
|
||||
// For now we just drop the custom derive typings
|
||||
/** @internal */
|
||||
export function decorateDerive (instanceId: string, api: ApiInterfaceRx, custom: DeriveCustom = {}): ExactDerive {
|
||||
export function getAvailableDerives (instanceId: string, api: ApiInterfaceRx, custom: DeriveCustom = {}): ExactDerive {
|
||||
return {
|
||||
...injectFunctions(instanceId, api, derive),
|
||||
...injectFunctions(instanceId, api, derive as DeriveCustom),
|
||||
...injectFunctions(instanceId, api, custom)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,17 +25,20 @@ import { memo } from '../util';
|
||||
*/
|
||||
export function getBlock (instanceId: string, api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<SignedBlockExtended | undefined> {
|
||||
return memo(instanceId, (blockHash: Uint8Array | string): Observable<SignedBlockExtended | undefined> =>
|
||||
api.queryAt(blockHash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
combineLatest([
|
||||
api.rpc.chain.getBlock(blockHash),
|
||||
queryAt.system.events(),
|
||||
queryAt.session
|
||||
? queryAt.session.validators()
|
||||
: of([])
|
||||
])
|
||||
),
|
||||
map(([signedBlock, events, validators]) =>
|
||||
combineLatest([
|
||||
api.rpc.chain.getBlock(blockHash),
|
||||
api.queryAt(blockHash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
combineLatest([
|
||||
queryAt.system.events(),
|
||||
queryAt.session
|
||||
? queryAt.session.validators()
|
||||
: of([])
|
||||
])
|
||||
)
|
||||
)
|
||||
]).pipe(
|
||||
map(([signedBlock, [events, validators]]) =>
|
||||
createSignedBlockExtended(api.registry, signedBlock, events, validators)
|
||||
),
|
||||
catchError((): Observable<undefined> =>
|
||||
|
||||
@@ -25,17 +25,18 @@ import { memo } from '../util';
|
||||
* console.log(`block #${number} was authored by ${author}`);
|
||||
* ```
|
||||
*/
|
||||
export function getHeader (instanceId: string, api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<HeaderExtended | undefined> {
|
||||
return memo(instanceId, (hash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
|
||||
api.queryAt(hash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
combineLatest([
|
||||
api.rpc.chain.getHeader(hash),
|
||||
export function getHeader (instanceId: string, api: ApiInterfaceRx): (blockHash: Uint8Array | string) => Observable<HeaderExtended | undefined> {
|
||||
return memo(instanceId, (blockHash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
|
||||
combineLatest([
|
||||
api.rpc.chain.getHeader(blockHash),
|
||||
api.queryAt(blockHash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
queryAt.session
|
||||
? queryAt.session.validators()
|
||||
: of([] as AccountId[])
|
||||
])
|
||||
),
|
||||
)
|
||||
)
|
||||
]).pipe(
|
||||
map(([header, validators]) =>
|
||||
createHeaderExtended(header.registry, header, validators)
|
||||
),
|
||||
|
||||
@@ -21,15 +21,15 @@ export function subscribeNewBlocks (instanceId: string, api: ApiInterfaceRx): ()
|
||||
const blockHash = header.createdAtHash || header.hash;
|
||||
|
||||
// we get the block first, setting up the registry
|
||||
return api.queryAt(blockHash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
combineLatest([
|
||||
of(header),
|
||||
api.rpc.chain.getBlock(blockHash),
|
||||
return combineLatest([
|
||||
of(header),
|
||||
api.rpc.chain.getBlock(blockHash),
|
||||
api.queryAt(blockHash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
queryAt.system.events()
|
||||
])
|
||||
)
|
||||
)
|
||||
);
|
||||
]);
|
||||
}),
|
||||
map(([header, block, events]) =>
|
||||
createSignedBlockExtended(block.registry, block, events, header.validators)
|
||||
|
||||
@@ -25,7 +25,11 @@ function parseEnd (api: ApiInterfaceRx, vote: Vote, { approved, end }: Referendu
|
||||
return [
|
||||
end,
|
||||
(approved.isTrue && vote.isAye) || (approved.isFalse && vote.isNay)
|
||||
? end.add(api.consts.democracy.enactmentPeriod.muln(LOCKUPS[vote.conviction.index]))
|
||||
? end.add(
|
||||
(
|
||||
api.consts.democracy.voteLockingPeriod ||
|
||||
api.consts.democracy.enactmentPeriod
|
||||
).muln(LOCKUPS[vote.conviction.index]))
|
||||
: BN_ZERO
|
||||
];
|
||||
}
|
||||
@@ -50,7 +54,11 @@ function delegateLocks (api: ApiInterfaceRx, { balance, conviction, target }: Vo
|
||||
referendumId,
|
||||
unlockAt: unlockAt.isZero()
|
||||
? unlockAt
|
||||
: referendumEnd.add(api.consts.democracy.enactmentPeriod.muln(LOCKUPS[conviction.index])),
|
||||
: referendumEnd.add(
|
||||
(
|
||||
api.consts.democracy.voteLockingPeriod ||
|
||||
api.consts.democracy.enactmentPeriod
|
||||
).muln(LOCKUPS[conviction.index])),
|
||||
vote: api.registry.createType('Vote', { aye: vote.isAye, conviction })
|
||||
}))
|
||||
)
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/api-derive', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/api-derive', version: '6.8.1' };
|
||||
|
||||
@@ -16,13 +16,14 @@ interface Result {
|
||||
|
||||
export function events (instanceId: string, api: ApiInterfaceRx): (at: Hash) => Observable<Result> {
|
||||
return memo(instanceId, (blockHash: Hash) =>
|
||||
api.queryAt(blockHash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
combineLatest([
|
||||
api.rpc.chain.getBlock(blockHash),
|
||||
combineLatest([
|
||||
api.rpc.chain.getBlock(blockHash),
|
||||
api.queryAt(blockHash).pipe(
|
||||
switchMap((queryAt) =>
|
||||
queryAt.system.events()
|
||||
])
|
||||
),
|
||||
)
|
||||
)
|
||||
]).pipe(
|
||||
map(([block, events]): Result => ({ block, events }))
|
||||
)
|
||||
);
|
||||
|
||||
@@ -32,20 +32,23 @@ function nextNonce (api: ApiInterfaceRx, address: string): Observable<Index> {
|
||||
|
||||
function signingHeader (api: ApiInterfaceRx): Observable<Header> {
|
||||
return combineLatest([
|
||||
api.rpc.chain.getHeader(),
|
||||
api.rpc.chain.getFinalizedHead()
|
||||
]).pipe(
|
||||
switchMap(([bestHeader, finHash]) =>
|
||||
// retrieve the headers - in the case of the current block, we use the parent
|
||||
// to minimize (not completely remove) the impact that forks do have on the system
|
||||
// (when at genesis, just return the current header as the last known)
|
||||
bestHeader.parentHash.isEmpty
|
||||
? of([bestHeader, bestHeader])
|
||||
: combineLatest([
|
||||
api.rpc.chain.getHeader(bestHeader.parentHash),
|
||||
api.rpc.chain.getHeader(finHash)
|
||||
])
|
||||
api.rpc.chain.getHeader().pipe(
|
||||
switchMap((header) =>
|
||||
// check for chains at genesis (until block 1 is produced, e.g. 6s), since
|
||||
// we do need to allow transactions at chain start (also dev/seal chains)
|
||||
header.parentHash.isEmpty
|
||||
? of(header)
|
||||
// in the case of the current block, we use the parent to minimize the
|
||||
// impact of forks on the system, but not completely remove it
|
||||
: api.rpc.chain.getHeader(header.parentHash)
|
||||
)
|
||||
),
|
||||
api.rpc.chain.getFinalizedHead().pipe(
|
||||
switchMap((hash) =>
|
||||
api.rpc.chain.getHeader(hash)
|
||||
)
|
||||
)
|
||||
]).pipe(
|
||||
map(([current, finalized]) =>
|
||||
// determine the hash to use, current when lag > max, else finalized
|
||||
current.number.unwrap().sub(finalized.number.unwrap()).gt(MAX_FINALITY_LAG)
|
||||
|
||||
@@ -8,14 +8,14 @@ import type { ApprovalFlag } from '@polkadot/types/interfaces/elections';
|
||||
export function approvalFlagsToBools (flags: Vec<ApprovalFlag> | ApprovalFlag[]): boolean[] {
|
||||
const bools: boolean[] = [];
|
||||
|
||||
flags.forEach((flag: ApprovalFlag): void => {
|
||||
const str = flag.toString(2);
|
||||
for (let i = 0; i < flags.length; i++) {
|
||||
const str = flags[i].toString(2);
|
||||
|
||||
// read from lowest bit to highest
|
||||
for (const bit of str.split('').reverse()) {
|
||||
bools.push(!!parseInt(bit, 10));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// slice off trailing "false" values, as in substrate
|
||||
const lastApproval = bools.lastIndexOf(true);
|
||||
|
||||
@@ -10,10 +10,8 @@ export const deriveMapCache: DeriveCache = {
|
||||
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]);
|
||||
for (const [k, v] of mapCache.entries()) {
|
||||
cb(k, v);
|
||||
}
|
||||
},
|
||||
get: <T = any> (key: string): T | undefined => {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017-2021 @polkadot/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { lazyMethod, lazyMethods } from '@polkadot/util';
|
||||
|
||||
type LazySection <T> = Record<string, T>;
|
||||
|
||||
type LazyRecord <T> = Record<string, LazySection<T>>;
|
||||
|
||||
export function lazyDeriveSection <T> (result: LazyRecord<T>, section: string, getKeys: (s: string) => string[], creator: (s: string, m: string) => T): void {
|
||||
lazyMethod(result, section, () =>
|
||||
lazyMethods({}, getKeys(section), (method: string) =>
|
||||
creator(section, method)
|
||||
)
|
||||
);
|
||||
}
|
||||
+27
-23
@@ -1,33 +1,37 @@
|
||||
{
|
||||
"name": "@polkadot/api",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/api",
|
||||
"repository": {
|
||||
"directory": "packages/api",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/api-derive": "6.4.2",
|
||||
"@polkadot/keyring": "^7.5.1",
|
||||
"@polkadot/rpc-core": "6.4.2",
|
||||
"@polkadot/rpc-provider": "6.4.2",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"@polkadot/types-known": "6.4.2",
|
||||
"@polkadot/util": "^7.5.1",
|
||||
"@polkadot/util-crypto": "^7.5.1",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/api-derive": "6.8.1",
|
||||
"@polkadot/keyring": "^7.8.2",
|
||||
"@polkadot/rpc-core": "6.8.1",
|
||||
"@polkadot/rpc-provider": "6.8.1",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"@polkadot/types-known": "6.8.1",
|
||||
"@polkadot/util": "^7.8.2",
|
||||
"@polkadot/util-crypto": "^7.8.2",
|
||||
"eventemitter3": "^4.0.7",
|
||||
"rxjs": "^7.4.0"
|
||||
}
|
||||
|
||||
@@ -1237,6 +1237,10 @@ declare module '@polkadot/api/types/errors' {
|
||||
[key: string]: AugmentedError<ApiType>;
|
||||
};
|
||||
system: {
|
||||
/**
|
||||
* The origin filter prevent the call to be dispatched.
|
||||
**/
|
||||
CallFiltered: AugmentedError<ApiType>;
|
||||
/**
|
||||
* Failed to extract the runtime version from the new runtime.
|
||||
*
|
||||
|
||||
@@ -108,7 +108,8 @@ declare module '@polkadot/api/types/events' {
|
||||
**/
|
||||
BalanceSet: AugmentedEvent<ApiType, [AccountId32, u128, u128]>;
|
||||
/**
|
||||
* Some amount was deposited (e.g. for transaction fees). \[who, deposit\]
|
||||
* Some amount was deposited into the account (e.g. for transaction fees). \[who,
|
||||
* deposit\]
|
||||
**/
|
||||
Deposit: AugmentedEvent<ApiType, [AccountId32, u128]>;
|
||||
/**
|
||||
@@ -130,6 +131,11 @@ declare module '@polkadot/api/types/events' {
|
||||
* \[from, to, balance, destination_status\]
|
||||
**/
|
||||
ReserveRepatriated: AugmentedEvent<ApiType, [AccountId32, AccountId32, u128, FrameSupportTokensMiscBalanceStatus]>;
|
||||
/**
|
||||
* Some amount was removed from the account (e.g. for misbehavior). \[who,
|
||||
* amount_slashed\]
|
||||
**/
|
||||
Slashed: AugmentedEvent<ApiType, [AccountId32, u128]>;
|
||||
/**
|
||||
* Transfer succeeded. \[from, to, value\]
|
||||
**/
|
||||
@@ -138,6 +144,10 @@ declare module '@polkadot/api/types/events' {
|
||||
* Some balance was unreserved (moved from reserved to free). \[who, value\]
|
||||
**/
|
||||
Unreserved: AugmentedEvent<ApiType, [AccountId32, u128]>;
|
||||
/**
|
||||
* Some amount was withdrawn from the account (e.g. for transaction fees). \[who, value\]
|
||||
**/
|
||||
Withdraw: AugmentedEvent<ApiType, [AccountId32, u128]>;
|
||||
/**
|
||||
* Generic event
|
||||
**/
|
||||
@@ -572,7 +582,7 @@ declare module '@polkadot/api/types/events' {
|
||||
**/
|
||||
MultisigApproval: AugmentedEvent<ApiType, [AccountId32, PalletMultisigTimepoint, AccountId32, U8aFixed]>;
|
||||
/**
|
||||
* A multisig operation has been cancelled. \[cancelling, timepoint, multisig, call_hash\]
|
||||
* A multisig operation has been cancelled. \[canceling, timepoint, multisig, call_hash\]
|
||||
**/
|
||||
MultisigCancelled: AugmentedEvent<ApiType, [AccountId32, PalletMultisigTimepoint, AccountId32, U8aFixed]>;
|
||||
/**
|
||||
@@ -1136,6 +1146,10 @@ declare module '@polkadot/api/types/events' {
|
||||
* well as the error. \[index, error\]
|
||||
**/
|
||||
BatchInterrupted: AugmentedEvent<ApiType, [u32, SpRuntimeDispatchError]>;
|
||||
/**
|
||||
* A call was dispatched. \[result\]
|
||||
**/
|
||||
DispatchedAs: AugmentedEvent<ApiType, [Result<Null, SpRuntimeDispatchError>]>;
|
||||
/**
|
||||
* A single item within a Batch of dispatches has completed with no error.
|
||||
**/
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { ApiTypes } from '@polkadot/api/types';
|
||||
import type { BTreeMap, Bytes, Data, Null, Option, U8aFixed, Vec, WrapperOpaque, bool, u128, u32, u64, u8 } from '@polkadot/types';
|
||||
import type { AccountId32, Call, H256, Perbill, Percent } from '@polkadot/types/interfaces/runtime';
|
||||
import type { FrameSupportWeightsPerDispatchClassU64, FrameSystemAccountInfo, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, NodeRuntimeSessionKeys, PalletAssetsApproval, PalletAssetsAssetBalance, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletAuthorshipUncleEntryItem, PalletBagsListListBag, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReleases, PalletBalancesReserveData, PalletBountiesBounty, PalletCollectiveVotes, PalletContractsStorageDeletedContract, PalletContractsStorageRawContractInfo, PalletContractsWasmPrefabWasmModule, PalletDemocracyPreimageStatus, PalletDemocracyReferendumInfo, PalletDemocracyReleases, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletGiltActiveGilt, PalletGiltActiveGiltsTotal, PalletGiltGiltBid, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineBoundedOpaqueNetworkState, PalletImOnlineSr25519AppSr25519Public, PalletLotteryLotteryConfig, PalletMultisigMultisig, PalletProxyAnnouncement, PalletProxyProxyDefinition, PalletRecoveryActiveRecovery, PalletRecoveryRecoveryConfig, PalletSchedulerReleases, PalletSchedulerScheduledV2, PalletSocietyBid, PalletSocietyBidKind, PalletSocietyVote, PalletSocietyVouchingStatus, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingExposure, PalletStakingForcing, PalletStakingNominations, PalletStakingReleases, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingValidatorPrefs, PalletTipsOpenTip, PalletTransactionPaymentReleases, PalletTransactionStorageTransactionInfo, PalletTreasuryProposal, PalletUniquesClassDetails, PalletUniquesClassMetadata, PalletUniquesInstanceDetails, PalletUniquesInstanceMetadata, PalletVestingReleases, PalletVestingVestingInfo, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpCoreCryptoKeyTypeId, SpRuntimeGenericDigest, SpStakingOffenceOffenceDetails } from '@polkadot/types/lookup';
|
||||
import type { FrameSupportWeightsPerDispatchClassU64, FrameSystemAccountInfo, FrameSystemEventRecord, FrameSystemLastRuntimeUpgradeInfo, FrameSystemPhase, NodeRuntimeSessionKeys, PalletAssetsApproval, PalletAssetsAssetBalance, PalletAssetsAssetDetails, PalletAssetsAssetMetadata, PalletAuthorshipUncleEntryItem, PalletBagsListListBag, PalletBagsListListNode, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesReleases, PalletBalancesReserveData, PalletBountiesBounty, PalletCollectiveVotes, PalletContractsStorageDeletedContract, PalletContractsStorageRawContractInfo, PalletContractsWasmPrefabWasmModule, PalletDemocracyPreimageStatus, PalletDemocracyReferendumInfo, PalletDemocracyReleases, PalletDemocracyVoteThreshold, PalletDemocracyVoteVoting, PalletElectionProviderMultiPhasePhase, PalletElectionProviderMultiPhaseReadySolution, PalletElectionProviderMultiPhaseRoundSnapshot, PalletElectionProviderMultiPhaseSignedSignedSubmission, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenSeatHolder, PalletElectionsPhragmenVoter, PalletGiltActiveGilt, PalletGiltActiveGiltsTotal, PalletGiltGiltBid, PalletGrandpaStoredPendingChange, PalletGrandpaStoredState, PalletIdentityRegistrarInfo, PalletIdentityRegistration, PalletImOnlineBoundedOpaqueNetworkState, PalletImOnlineSr25519AppSr25519Public, PalletLotteryLotteryConfig, PalletMultisigMultisig, PalletProxyAnnouncement, PalletProxyProxyDefinition, PalletRecoveryActiveRecovery, PalletRecoveryRecoveryConfig, PalletSchedulerReleases, PalletSchedulerScheduledV2, PalletSocietyBid, PalletSocietyBidKind, PalletSocietyVote, PalletSocietyVouchingStatus, PalletStakingActiveEraInfo, PalletStakingEraRewardPoints, PalletStakingExposure, PalletStakingForcing, PalletStakingNominations, PalletStakingReleases, PalletStakingRewardDestination, PalletStakingSlashingSlashingSpans, PalletStakingSlashingSpanRecord, PalletStakingStakingLedger, PalletStakingUnappliedSlash, PalletStakingValidatorPrefs, PalletTipsOpenTip, PalletTransactionPaymentReleases, PalletTransactionStorageTransactionInfo, PalletTreasuryProposal, PalletUniquesClassDetails, PalletUniquesClassMetadata, PalletUniquesInstanceDetails, PalletUniquesInstanceMetadata, PalletVestingReleases, PalletVestingVestingInfo, SpAuthorityDiscoveryAppPublic, SpConsensusBabeAppPublic, SpConsensusBabeBabeEpochConfiguration, SpConsensusBabeDigestsNextConfigDescriptor, SpCoreCryptoKeyTypeId, SpRuntimeDigest, SpStakingOffenceOffenceDetails } from '@polkadot/types/lookup';
|
||||
import type { AnyNumber, ITuple, Observable } from '@polkadot/types/types';
|
||||
|
||||
declare module '@polkadot/api/types/storage' {
|
||||
@@ -33,6 +33,20 @@ declare module '@polkadot/api/types/storage' {
|
||||
**/
|
||||
[key: string]: QueryableStorageEntry<ApiType>;
|
||||
};
|
||||
authorityDiscovery: {
|
||||
/**
|
||||
* Keys of the current authority set.
|
||||
**/
|
||||
keys: AugmentedQuery<ApiType, () => Observable<Vec<SpAuthorityDiscoveryAppPublic>>, []> & QueryableStorageEntry<ApiType, []>;
|
||||
/**
|
||||
* Keys of the next authority set.
|
||||
**/
|
||||
nextKeys: AugmentedQuery<ApiType, () => Observable<Vec<SpAuthorityDiscoveryAppPublic>>, []> & QueryableStorageEntry<ApiType, []>;
|
||||
/**
|
||||
* Generic query
|
||||
**/
|
||||
[key: string]: QueryableStorageEntry<ApiType>;
|
||||
};
|
||||
authorship: {
|
||||
/**
|
||||
* Author of current block.
|
||||
@@ -135,7 +149,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
/**
|
||||
* Randomness under construction.
|
||||
*
|
||||
* We make a tradeoff between storage accesses and list length.
|
||||
* We make a trade-off between storage accesses and list length.
|
||||
* We store the under-construction randomness in segments of up to
|
||||
* `UNDER_CONSTRUCTION_SEGMENT_LENGTH`.
|
||||
*
|
||||
@@ -1149,7 +1163,7 @@ declare module '@polkadot/api/types/storage' {
|
||||
/**
|
||||
* Digest of the current block, also part of the block header.
|
||||
**/
|
||||
digest: AugmentedQuery<ApiType, () => Observable<SpRuntimeGenericDigest>, []> & QueryableStorageEntry<ApiType, []>;
|
||||
digest: AugmentedQuery<ApiType, () => Observable<SpRuntimeDigest>, []> & QueryableStorageEntry<ApiType, []>;
|
||||
/**
|
||||
* The number of events in the `Events<T>` list.
|
||||
**/
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { ApiTypes, SubmittableExtrinsic } from '@polkadot/api/types';
|
||||
import type { Bytes, Compact, Data, Option, U8aFixed, Vec, bool, u128, u16, u32, u64, u8 } from '@polkadot/types';
|
||||
import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';
|
||||
import type { AccountId32, Call, H256, MultiAddress, Perbill, Percent, Perquintill } from '@polkadot/types/interfaces/runtime';
|
||||
import type { NodeRuntimeProxyType, NodeRuntimeSessionKeys, PalletAssetsDestroyWitness, PalletDemocracyConviction, PalletDemocracyVoteAccountVote, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenRenouncing, PalletIdentityBitFlags, PalletIdentityIdentityInfo, PalletIdentityJudgement, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Signature, PalletMultisigTimepoint, PalletSocietyJudgement, PalletStakingRewardDestination, PalletStakingValidatorPrefs, PalletUniquesDestroyWitness, PalletVestingVestingInfo, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusSlotsEquivocationProof, SpCoreChangesTrieChangesTrieConfiguration, SpFinalityGrandpaEquivocationProof, SpNposElectionsSupport, SpRuntimeGenericHeader, SpSessionMembershipProof, SpTransactionStorageProofTransactionStorageProof } from '@polkadot/types/lookup';
|
||||
import type { NodeRuntimeOriginCaller, NodeRuntimeProxyType, NodeRuntimeSessionKeys, PalletAssetsDestroyWitness, PalletDemocracyConviction, PalletDemocracyVoteAccountVote, PalletElectionProviderMultiPhaseRawSolution, PalletElectionProviderMultiPhaseSolutionOrSnapshotSize, PalletElectionsPhragmenRenouncing, PalletIdentityBitFlags, PalletIdentityIdentityInfo, PalletIdentityJudgement, PalletImOnlineHeartbeat, PalletImOnlineSr25519AppSr25519Signature, PalletMultisigTimepoint, PalletSocietyJudgement, PalletStakingRewardDestination, PalletStakingValidatorPrefs, PalletUniquesDestroyWitness, PalletVestingVestingInfo, SpConsensusBabeDigestsNextConfigDescriptor, SpConsensusSlotsEquivocationProof, SpCoreChangesTrieChangesTrieConfiguration, SpFinalityGrandpaEquivocationProof, SpNposElectionsSupport, SpRuntimeHeader, SpSessionMembershipProof, SpTransactionStorageProofTransactionStorageProof } from '@polkadot/types/lookup';
|
||||
import type { AnyNumber, ITuple } from '@polkadot/types/types';
|
||||
|
||||
declare module '@polkadot/api/types/submittable' {
|
||||
@@ -425,7 +425,7 @@ declare module '@polkadot/api/types/submittable' {
|
||||
/**
|
||||
* Provide a set of uncles.
|
||||
**/
|
||||
setUncles: AugmentedSubmittable<(newUncles: Vec<SpRuntimeGenericHeader> | (SpRuntimeGenericHeader | { parentHash?: any; number?: any; stateRoot?: any; extrinsicsRoot?: any; digest?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [Vec<SpRuntimeGenericHeader>]>;
|
||||
setUncles: AugmentedSubmittable<(newUncles: Vec<SpRuntimeHeader> | (SpRuntimeHeader | { parentHash?: any; number?: any; stateRoot?: any; extrinsicsRoot?: any; digest?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [Vec<SpRuntimeHeader>]>;
|
||||
/**
|
||||
* Generic tx
|
||||
**/
|
||||
@@ -2567,9 +2567,13 @@ declare module '@polkadot/api/types/submittable' {
|
||||
session: {
|
||||
/**
|
||||
* Removes any session key(s) of the function caller.
|
||||
*
|
||||
* This doesn't take effect until the next session.
|
||||
*
|
||||
* The dispatch origin of this function must be signed.
|
||||
* The dispatch origin of this function must be Signed and the account must be either be
|
||||
* convertible to a validator ID using the chain's typical addressing system (this usually
|
||||
* means being a controller account) or directly convertible into a validator ID (which
|
||||
* usually means being a stash account).
|
||||
*
|
||||
* # <weight>
|
||||
* - Complexity: `O(1)` in number of key types. Actual cost depends on the number of length
|
||||
@@ -4388,6 +4392,19 @@ declare module '@polkadot/api/types/submittable' {
|
||||
* # </weight>
|
||||
**/
|
||||
batchAll: AugmentedSubmittable<(calls: Vec<Call> | (Call | { callIndex?: any; args?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [Vec<Call>]>;
|
||||
/**
|
||||
* Dispatches a function call with a provided origin.
|
||||
*
|
||||
* The dispatch origin for this call must be _Root_.
|
||||
*
|
||||
* # <weight>
|
||||
* - O(1).
|
||||
* - Limited storage reads.
|
||||
* - One DB write (event).
|
||||
* - Weight of derivative `call` execution + T::WeightInfo::dispatch_as().
|
||||
* # </weight>
|
||||
**/
|
||||
dispatchAs: AugmentedSubmittable<(asOrigin: NodeRuntimeOriginCaller | { system: any } | { Void: any } | { Council: any } | { TechnicalCommittee: any } | string | Uint8Array, call: Call | { callIndex?: any; args?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [NodeRuntimeOriginCaller, Call]>;
|
||||
/**
|
||||
* Generic tx
|
||||
**/
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { DeriveCustom } from '@polkadot/api-derive';
|
||||
import type { RpcInterface } from '@polkadot/rpc-core/types';
|
||||
import type { Option, Raw, StorageKey, Text, u64 } from '@polkadot/types';
|
||||
import type { Call, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
@@ -9,20 +10,20 @@ import type { DecoratedMeta } from '@polkadot/types/metadata/decorate/types';
|
||||
import type { StorageEntry } from '@polkadot/types/primitive/types';
|
||||
import type { AnyFunction, AnyTuple, CallFunction, Codec, DefinitionRpc, DefinitionRpcSub, DetectCodec, IMethod, IStorageKey, Registry, RegistryError, RegistryTypes } from '@polkadot/types/types';
|
||||
import type { SubmittableExtrinsic } from '../submittable/types';
|
||||
import type { ApiDecoration, ApiInterfaceRx, ApiOptions, ApiTypes, AugmentedQuery, DecoratedErrors, DecoratedEvents, DecoratedRpc, DecoratedRpcSection, DecorateMethod, GenericStorageEntryFunction, PaginationOptions, QueryableConsts, QueryableModuleStorage, QueryableModuleStorageAt, QueryableStorage, QueryableStorageAt, QueryableStorageEntry, QueryableStorageEntryAt, QueryableStorageMulti, QueryableStorageMultiArg, SubmittableExtrinsicFunction, SubmittableExtrinsics, SubmittableModuleExtrinsics } from '../types';
|
||||
import type { ApiDecoration, ApiInterfaceRx, ApiOptions, ApiTypes, AugmentedQuery, DecoratedErrors, DecoratedEvents, DecoratedRpc, DecorateMethod, GenericStorageEntryFunction, PaginationOptions, QueryableConsts, QueryableStorage, QueryableStorageEntry, QueryableStorageEntryAt, QueryableStorageMulti, QueryableStorageMultiArg, SubmittableExtrinsicFunction, SubmittableExtrinsics } from '../types';
|
||||
import type { VersionedRegistry } from './types';
|
||||
|
||||
import { BehaviorSubject, combineLatest, from, map, of, switchMap, tap, toArray } from 'rxjs';
|
||||
|
||||
import { decorateDerive, ExactDerive } from '@polkadot/api-derive';
|
||||
import { ExactDerive, getAvailableDerives } from '@polkadot/api-derive';
|
||||
import { memo, RpcCore } from '@polkadot/rpc-core';
|
||||
import { WsProvider } from '@polkadot/rpc-provider';
|
||||
import { expandMetadata, Metadata, TypeRegistry, unwrapStorageType } from '@polkadot/types';
|
||||
import { arrayChunk, arrayFlatten, assert, BN, BN_ZERO, compactStripLength, logger, u8aToHex } from '@polkadot/util';
|
||||
import { arrayChunk, arrayFlatten, assert, BN, BN_ZERO, compactStripLength, lazyMethod, lazyMethods, logger, objectSpread, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { createSubmittable } from '../submittable';
|
||||
import { augmentObject } from '../util/augmentObject';
|
||||
import { decorateSections, DeriveAllSections } from '../util/decorate';
|
||||
import { decorateDeriveSections, DeriveAllSections } from '../util/decorate';
|
||||
import { extractStorageArgs } from '../util/validate';
|
||||
import { Events } from './Events';
|
||||
import { findCall, findError } from './find';
|
||||
@@ -145,8 +146,8 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
|
||||
this.#instanceId = `${++instanceCounter}`;
|
||||
this.#registry = options.source?.registry || options.registry || new TypeRegistry();
|
||||
this._rx.queryAt = (blockHash: Uint8Array | string) =>
|
||||
from(this.at(blockHash)).pipe(map((a) => a.rx.query));
|
||||
this._rx.queryAt = (blockHash: Uint8Array | string, knownVersion?: RuntimeVersion) =>
|
||||
from(this.at(blockHash, knownVersion)).pipe(map((a) => a.rx.query));
|
||||
this._rx.registry = this.#registry;
|
||||
|
||||
const thisProvider = options.source
|
||||
@@ -163,7 +164,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
this._rx.hasSubscriptions = this._rpcCore.provider.hasSubscriptions;
|
||||
}
|
||||
|
||||
public abstract at (blockHash: Uint8Array | string): Promise<ApiDecoration<ApiType>>;
|
||||
public abstract at (blockHash: Uint8Array | string, knownVersion?: RuntimeVersion): Promise<ApiDecoration<ApiType>>;
|
||||
|
||||
/**
|
||||
* @description Return the current used registry
|
||||
@@ -200,7 +201,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
return this._rpcCore.provider.hasSubscriptions || !!this._rpcCore.state.queryStorageAt;
|
||||
}
|
||||
|
||||
protected _createDecorated (registry: VersionedRegistry<ApiType>, fromEmpty?: boolean, blockHash?: Uint8Array | null, decoratedApi?: ApiDecoration<ApiType>): FullDecoration<ApiType> {
|
||||
protected _createDecorated (registry: VersionedRegistry<ApiType>, fromEmpty: boolean, decoratedApi: ApiDecoration<ApiType> | null, blockHash?: Uint8Array): FullDecoration<ApiType> {
|
||||
if (!decoratedApi) {
|
||||
decoratedApi = {
|
||||
consts: {},
|
||||
@@ -218,18 +219,12 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
registry.decoratedMeta = expandMetadata(registry.registry, registry.metadata);
|
||||
}
|
||||
|
||||
// adjust the versioned registry
|
||||
const storage = this._decorateStorage(registry.decoratedMeta, this._decorateMethod, blockHash);
|
||||
const storageRx = this._decorateStorage(registry.decoratedMeta, this._rxDecorateMethod, blockHash);
|
||||
|
||||
augmentObject('consts', registry.decoratedMeta.consts, decoratedApi.consts, fromEmpty);
|
||||
augmentObject('errors', registry.decoratedMeta.errors, decoratedApi.errors, fromEmpty);
|
||||
augmentObject('events', registry.decoratedMeta.events, decoratedApi.events, fromEmpty);
|
||||
|
||||
const storage = blockHash
|
||||
? this._decorateStorageAt(registry.decoratedMeta, this._decorateMethod, blockHash)
|
||||
: this._decorateStorage(registry.decoratedMeta, this._decorateMethod);
|
||||
const storageRx = blockHash
|
||||
? this._decorateStorageAt(registry.decoratedMeta, this._rxDecorateMethod, blockHash)
|
||||
: this._decorateStorage(registry.decoratedMeta, this._rxDecorateMethod);
|
||||
|
||||
augmentObject('query', storage, decoratedApi.query, fromEmpty);
|
||||
augmentObject('query', storageRx, decoratedApi.rx.query, fromEmpty);
|
||||
|
||||
@@ -247,7 +242,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
};
|
||||
}
|
||||
|
||||
protected _injectMetadata (registry: VersionedRegistry<ApiType>, fromEmpty?: boolean): void {
|
||||
protected _injectMetadata (registry: VersionedRegistry<ApiType>, fromEmpty = false): void {
|
||||
// clear the decoration, we are redoing it here
|
||||
if (fromEmpty || !registry.decoratedApi) {
|
||||
registry.decoratedApi = {
|
||||
@@ -262,7 +257,7 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
} as ApiDecoration<ApiType>;
|
||||
}
|
||||
|
||||
const { decoratedApi, decoratedMeta } = this._createDecorated(registry, fromEmpty, null, registry.decoratedApi);
|
||||
const { decoratedApi, decoratedMeta } = this._createDecorated(registry, fromEmpty, registry.decoratedApi);
|
||||
|
||||
this._consts = decoratedApi.consts;
|
||||
this._errors = decoratedApi.errors;
|
||||
@@ -270,12 +265,15 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
this._query = decoratedApi.query;
|
||||
this._rx.query = decoratedApi.rx.query;
|
||||
|
||||
const tx = this._decorateExtrinsics(decoratedMeta, this._decorateMethod);
|
||||
const rxtx = this._decorateExtrinsics(decoratedMeta, this._rxDecorateMethod);
|
||||
|
||||
if (fromEmpty || !this._extrinsics) {
|
||||
this._extrinsics = this._decorateExtrinsics(decoratedMeta, this._decorateMethod);
|
||||
this._rx.tx = this._decorateExtrinsics(decoratedMeta, this._rxDecorateMethod);
|
||||
this._extrinsics = tx;
|
||||
this._rx.tx = rxtx;
|
||||
} else {
|
||||
augmentObject('tx', this._decorateExtrinsics(decoratedMeta, this._decorateMethod), this._extrinsics, false);
|
||||
augmentObject(null, this._decorateExtrinsics(decoratedMeta, this._rxDecorateMethod), this._rx.tx, false);
|
||||
augmentObject('tx', tx, this._extrinsics, false);
|
||||
augmentObject(null, rxtx, this._rx.tx, false);
|
||||
}
|
||||
|
||||
augmentObject(null, decoratedMeta.consts, this._rx.consts, fromEmpty);
|
||||
@@ -322,7 +320,11 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
protected _filterRpcMethods (exposed: string[]): void {
|
||||
const hasResults = exposed.length !== 0;
|
||||
const allKnown = [...this._rpcCore.mapping.entries()];
|
||||
const allKeys = allKnown.reduce((allKeys: string[], [, { alias, endpoint, method, pubsub, section }]): string[] => {
|
||||
const allKeys: string[] = [];
|
||||
|
||||
for (let i = 0; i < allKnown.length; i++) {
|
||||
const [, { alias, endpoint, method, pubsub, section }] = allKnown[i];
|
||||
|
||||
allKeys.push(`${section}_${method}`);
|
||||
|
||||
if (pubsub) {
|
||||
@@ -337,11 +339,10 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
if (endpoint) {
|
||||
allKeys.push(endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
return allKeys;
|
||||
}, []);
|
||||
const unknown = exposed.filter((k) => !allKeys.includes(k));
|
||||
const deletion = allKnown.filter(([k]) => hasResults && !exposed.includes(k) && k !== 'rpc_methods');
|
||||
const filterKey = (k: string) => !allKeys.includes(k);
|
||||
const unknown = exposed.filter(filterKey);
|
||||
|
||||
if (unknown.length) {
|
||||
l.warn(`RPC methods not decorated: ${unknown.join(', ')}`);
|
||||
@@ -349,36 +350,54 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
|
||||
// loop through all entries we have (populated in decorate) and filter as required
|
||||
// only remove when we have results and method missing, or with no results if optional
|
||||
deletion.forEach(([, { method, section }]): void => {
|
||||
delete (this._rpc as Record<string, Record<string, unknown>>)[section][method];
|
||||
delete (this._rx.rpc as Record<string, Record<string, unknown>>)[section][method];
|
||||
});
|
||||
for (let i = 0; i < allKnown.length; i++) {
|
||||
const [k, { method, section }] = allKnown[i];
|
||||
|
||||
if (hasResults && !exposed.includes(k) && k !== 'rpc_methods') {
|
||||
delete (this._rpc as Record<string, Record<string, unknown>>)[section][method];
|
||||
delete (this._rx.rpc as Record<string, Record<string, unknown>>)[section][method];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected _decorateRpc<ApiType extends ApiTypes> (rpc: RpcCore & RpcInterface, decorateMethod: DecorateMethod<ApiType>, input: Partial<DecoratedRpc<ApiType, RpcInterface>> = {}): DecoratedRpc<ApiType, RpcInterface> {
|
||||
return rpc.sections.reduce((out, _sectionName): DecoratedRpc<ApiType, RpcInterface> => {
|
||||
const sectionName = _sectionName as keyof DecoratedRpc<ApiType, RpcInterface>;
|
||||
const out: Record<string, Record<string, unknown>> = input;
|
||||
|
||||
const decorateFn = (section: string, method: string): unknown => {
|
||||
const source = rpc[section as 'chain'][method as 'getHeader'];
|
||||
const fn = decorateMethod(source, { methodName: method }) as Record<string, unknown>;
|
||||
|
||||
fn.meta = source.meta;
|
||||
fn.raw = decorateMethod(source.raw, { methodName: method }) as unknown;
|
||||
|
||||
return fn;
|
||||
};
|
||||
|
||||
for (let s = 0; s < rpc.sections.length; s++) {
|
||||
const section = rpc.sections[s];
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(out, section)) {
|
||||
const methods = Object.keys(rpc[section as 'chain']);
|
||||
|
||||
const decorateInternal = (method: string) =>
|
||||
decorateFn(section, method);
|
||||
|
||||
for (let m = 0; m < methods.length; m++) {
|
||||
const method = methods[m];
|
||||
|
||||
if (!(out as Record<string, unknown>)[sectionName]) {
|
||||
// out and section here are horrors to get right from a typing perspective :(
|
||||
(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
|
||||
if (this.hasSubscriptions || !(methodName.startsWith('subscribe') || methodName.startsWith('unsubscribe'))) {
|
||||
(section as Record<string, unknown>)[methodName] = decorateMethod(method, { methodName }) as unknown;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
(section as Record<string, { json: unknown }>)[methodName].json = decorateMethod(method.json, { methodName }) as unknown;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
(section as Record<string, { raw: unknown }>)[methodName].raw = decorateMethod(method.raw, { methodName }) as unknown;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
(section as Record<string, { meta: unknown }>)[methodName].meta = method.meta;
|
||||
if (this.hasSubscriptions || !(method.startsWith('subscribe') || method.startsWith('unsubscribe'))) {
|
||||
if (!Object.prototype.hasOwnProperty.call(out, section)) {
|
||||
out[section] = {};
|
||||
}
|
||||
|
||||
lazyMethod(out[section], method, decorateInternal);
|
||||
}
|
||||
|
||||
return section;
|
||||
}, {} as DecoratedRpcSection<ApiType, RpcInterface[typeof sectionName]>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}, input as DecoratedRpc<ApiType, RpcInterface>);
|
||||
return out as DecoratedRpc<ApiType, RpcInterface>;
|
||||
}
|
||||
|
||||
// only be called if supportMulti is true
|
||||
@@ -419,17 +438,20 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
}
|
||||
|
||||
protected _decorateExtrinsics<ApiType extends ApiTypes> ({ tx }: DecoratedMeta, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType> {
|
||||
const creator = createSubmittable(this._type, this._rx, decorateMethod);
|
||||
const result = createSubmittable(this._type, this._rx, decorateMethod) as SubmittableExtrinsics<ApiType>;
|
||||
|
||||
return Object.entries(tx).reduce((out, [name, section]): SubmittableExtrinsics<ApiType> => {
|
||||
out[name] = Object.entries(section).reduce((out, [name, method]): SubmittableModuleExtrinsics<ApiType> => {
|
||||
out[name] = this._decorateExtrinsicEntry(method, creator);
|
||||
const lazySection = (section: string) =>
|
||||
lazyMethods({}, Object.keys(tx[section]), (method: string) =>
|
||||
this._decorateExtrinsicEntry(tx[section][method], result)
|
||||
);
|
||||
|
||||
return out;
|
||||
}, {} as SubmittableModuleExtrinsics<ApiType>);
|
||||
const sections = Object.keys(tx);
|
||||
|
||||
return out;
|
||||
}, creator as SubmittableExtrinsics<ApiType>);
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
lazyMethod(result, sections[i], lazySection);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private _decorateExtrinsicEntry<ApiType extends ApiTypes> (method: CallFunction, creator: (value: Call | Uint8Array | string) => SubmittableExtrinsic<ApiType>): SubmittableExtrinsicFunction<ApiType> {
|
||||
@@ -444,28 +466,23 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
return this._decorateFunctionMeta(method as unknown as MetaDecoration, decorated as unknown as MetaDecoration) as unknown as SubmittableExtrinsicFunction<ApiType>;
|
||||
}
|
||||
|
||||
protected _decorateStorage<ApiType extends ApiTypes> ({ query }: DecoratedMeta, decorateMethod: DecorateMethod<ApiType>): QueryableStorage<ApiType> {
|
||||
return Object.entries(query).reduce((out, [name, section]): QueryableStorage<ApiType> => {
|
||||
out[name] = Object.entries(section).reduce((out, [name, method]): QueryableModuleStorage<ApiType> => {
|
||||
out[name] = this._decorateStorageEntry(method, decorateMethod);
|
||||
protected _decorateStorage<ApiType extends ApiTypes> ({ query, registry }: DecoratedMeta, decorateMethod: DecorateMethod<ApiType>, blockHash?: Uint8Array): QueryableStorage<ApiType> {
|
||||
const result = {} as QueryableStorage<ApiType>;
|
||||
|
||||
return out;
|
||||
}, {} as QueryableModuleStorage<ApiType>);
|
||||
const lazySection = (section: string) =>
|
||||
lazyMethods({}, Object.keys(query[section]), (method: string) =>
|
||||
blockHash
|
||||
? this._decorateStorageEntryAt(registry, query[section][method], decorateMethod, blockHash)
|
||||
: this._decorateStorageEntry(query[section][method], decorateMethod)
|
||||
);
|
||||
|
||||
return out;
|
||||
}, {} as QueryableStorage<ApiType>);
|
||||
}
|
||||
const sections = Object.keys(query);
|
||||
|
||||
protected _decorateStorageAt<ApiType extends ApiTypes> ({ query, registry }: DecoratedMeta, decorateMethod: DecorateMethod<ApiType>, blockHash: Uint8Array): QueryableStorageAt<ApiType> {
|
||||
return Object.entries(query).reduce((out, [name, section]): QueryableStorageAt<ApiType> => {
|
||||
out[name] = Object.entries(section).reduce((out, [name, method]): QueryableModuleStorageAt<ApiType> => {
|
||||
out[name] = this._decorateStorageEntryAt(registry, method, decorateMethod, blockHash);
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
lazyMethod(result, sections[i], lazySection);
|
||||
}
|
||||
|
||||
return out;
|
||||
}, {} as QueryableModuleStorageAt<ApiType>);
|
||||
|
||||
return out;
|
||||
}, {} as QueryableStorageAt<ApiType>);
|
||||
return result;
|
||||
}
|
||||
|
||||
private _decorateStorageEntry<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): QueryableStorageEntry<ApiType> {
|
||||
@@ -622,9 +639,9 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
return this._rpcCore.state
|
||||
.queryStorage<[Option<Raw>]>([decorated.key(...args)], ...range)
|
||||
.pipe(map((result: [Hash, [Option<Raw>]][]): [Hash, Codec][] =>
|
||||
result.map(([blockHash, [value]]): [Hash, Codec] => [
|
||||
result.map(([blockHash, [value]]) => [
|
||||
blockHash,
|
||||
this.createType(outputType, value.isSome ? value.unwrap().toHex() : undefined)
|
||||
this.createType<Codec>(outputType, value.isSome ? value.unwrap().toHex() : undefined)
|
||||
])
|
||||
));
|
||||
}
|
||||
@@ -654,10 +671,11 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
const queryCall = at
|
||||
? (startKey: string) => this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_K, startKey, at)
|
||||
: (startKey: string) => this._rpcCore.state.getKeysPaged(headKey, PAGE_SIZE_K, startKey);
|
||||
const setMeta = (key: StorageKey) => key.setMeta(meta, section, method);
|
||||
|
||||
return startSubject.pipe(
|
||||
switchMap(queryCall),
|
||||
map((keys) => keys.map((key) => key.setMeta(meta, section, method))),
|
||||
map((keys) => keys.map(setMeta)),
|
||||
tap((keys): void => {
|
||||
setTimeout((): void => {
|
||||
keys.length === PAGE_SIZE_K
|
||||
@@ -674,9 +692,10 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
assert(iterKey && meta.type.isMap, 'keys can only be retrieved on maps');
|
||||
|
||||
const headKey = iterKey(...opts.args).toHex();
|
||||
const setMeta = (key: StorageKey) => key.setMeta(meta, section, method);
|
||||
|
||||
return this._rpcCore.state.getKeysPaged(headKey, opts.pageSize, opts.startKey || headKey).pipe(
|
||||
map((keys) => keys.map((key) => key.setMeta(meta, section, method)))
|
||||
map((keys) => keys.map(setMeta))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -714,19 +733,15 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
|
||||
protected _decorateDeriveRx (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<'rxjs', ExactDerive> {
|
||||
const specName = this._runtimeVersion?.specName.toString();
|
||||
const derives = {
|
||||
...this._options.derives,
|
||||
...(this._options.typesBundle?.spec?.[specName || '']?.derives || {})
|
||||
};
|
||||
|
||||
// Pull in derive from api-derive
|
||||
const derive = decorateDerive(this.#instanceId, this._rx, derives);
|
||||
const available = getAvailableDerives(this.#instanceId, this._rx, objectSpread<DeriveCustom>({}, this._options.derives, this._options.typesBundle?.spec?.[specName || '']?.derives));
|
||||
|
||||
return decorateSections<'rxjs', ExactDerive>(derive, decorateMethod);
|
||||
return decorateDeriveSections<'rxjs', ExactDerive>(decorateMethod, available);
|
||||
}
|
||||
|
||||
protected _decorateDerive (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<ApiType, ExactDerive> {
|
||||
return decorateSections<ApiType, ExactDerive>(this._rx.derive, decorateMethod);
|
||||
return decorateDeriveSections<ApiType, ExactDerive>(decorateMethod, this._rx.derive);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable, Subscription } from 'rxjs';
|
||||
import type { RpcInterfaceMethod } from '@polkadot/rpc-core/types';
|
||||
import type { Text } from '@polkadot/types';
|
||||
import type { ChainProperties, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import type { ExtDef } from '@polkadot/types/extrinsic/signedExtensions/types';
|
||||
import type { ChainProperties, Hash, RuntimeVersion, RuntimeVersionPartial } from '@polkadot/types/interfaces';
|
||||
import type { Registry } from '@polkadot/types/types';
|
||||
import type { BN } from '@polkadot/util';
|
||||
import type { ApiBase, ApiDecoration, ApiOptions, ApiTypes, DecorateMethod } from '../types';
|
||||
@@ -14,7 +14,7 @@ import { firstValueFrom, map, of, switchMap } from 'rxjs';
|
||||
|
||||
import { Metadata, TypeRegistry } from '@polkadot/types';
|
||||
import { getSpecAlias, getSpecExtensions, getSpecHasher, getSpecRpc, getSpecTypes, getUpgradeVersion } from '@polkadot/types-known';
|
||||
import { assert, BN_ZERO, isUndefined, logger, stringify, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { assert, BN_ZERO, isUndefined, logger, objectSpread, stringify, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { cryptoWaitReady } from '@polkadot/util-crypto';
|
||||
|
||||
import { detectedCapabilities } from './capabilities';
|
||||
@@ -24,6 +24,10 @@ const KEEPALIVE_INTERVAL = 10000;
|
||||
|
||||
const l = logger('api/init');
|
||||
|
||||
function textToString (t: Text): string {
|
||||
return t.toString();
|
||||
}
|
||||
|
||||
export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
#healthTimer: NodeJS.Timeout | null = null;
|
||||
|
||||
@@ -91,10 +95,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
registry.knownTypes.typesAlias = getSpecAlias(registry, chain, version.specName);
|
||||
}
|
||||
|
||||
registry.setMetadata(metadata, undefined, {
|
||||
...getSpecExtensions(registry, chain, version.specName),
|
||||
...(this._options.signedExtensions || {})
|
||||
});
|
||||
registry.setMetadata(metadata, undefined, objectSpread<ExtDef>({}, getSpecExtensions(registry, chain, version.specName), this._options.signedExtensions));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,13 +113,32 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
/**
|
||||
* @description Returns a decorated API instance at a specific point in time
|
||||
*/
|
||||
public async at (blockHash: Uint8Array | string): Promise<ApiDecoration<ApiType>> {
|
||||
public async at (blockHash: Uint8Array | string, knownVersion?: RuntimeVersion): Promise<ApiDecoration<ApiType>> {
|
||||
const u8aHash = u8aToU8a(blockHash);
|
||||
const registry = await this.getBlockRegistry(u8aHash);
|
||||
const registry = await this.getBlockRegistry(u8aHash, knownVersion);
|
||||
|
||||
// always create a new decoration - since we are pointing to a specific hash, this
|
||||
// means that all queries needs to use that hash (not a previous one already existing)
|
||||
return this._createDecorated(registry, true, u8aHash).decoratedApi;
|
||||
return this._createDecorated(registry, true, null, u8aHash).decoratedApi;
|
||||
}
|
||||
|
||||
private _getBlockRegistryViaVersion (blockHash: Uint8Array, version?: RuntimeVersionPartial): VersionedRegistry<ApiType> | null {
|
||||
if (version) {
|
||||
// check for pre-existing registries. We also check specName, e.g. it
|
||||
// could be changed like in Westmint with upgrade from shell -> westmint
|
||||
const existingViaVersion = this.#registries.find(({ specName, specVersion }) =>
|
||||
specName.eq(version.specName) &&
|
||||
specVersion.eq(version.specVersion)
|
||||
);
|
||||
|
||||
if (existingViaVersion) {
|
||||
existingViaVersion.lastBlockHash = blockHash;
|
||||
|
||||
return existingViaVersion;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private async _getBlockRegistry (blockHash: Uint8Array): Promise<VersionedRegistry<ApiType>> {
|
||||
@@ -130,7 +150,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
const header = this.registry.createType('HeaderPartial',
|
||||
this._genesisHash.eq(blockHash)
|
||||
? { number: BN_ZERO, parentHash: this._genesisHash }
|
||||
: await firstValueFrom((this._rpcCore.chain.getHeader as RpcInterfaceMethod).json(blockHash))
|
||||
: await firstValueFrom(this._rpcCore.chain.getHeader.raw(blockHash))
|
||||
);
|
||||
|
||||
assert(!header.parentHash.isEmpty, 'Unable to retrieve header and parent from supplied hash');
|
||||
@@ -140,26 +160,19 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
const version = this.registry.createType('RuntimeVersionPartial',
|
||||
(firstVersion && (lastVersion || firstVersion.specVersion.eq(this._runtimeVersion.specVersion)))
|
||||
? { specName: this._runtimeVersion.specName, specVersion: firstVersion.specVersion }
|
||||
: await firstValueFrom((this._rpcCore.state.getRuntimeVersion as RpcInterfaceMethod).json(header.parentHash))
|
||||
: await firstValueFrom(this._rpcCore.state.getRuntimeVersion.raw(header.parentHash))
|
||||
);
|
||||
|
||||
// check for pre-existing registries. We also check specName, e.g. it
|
||||
// could be changed like in Westmint with upgrade from shell -> westmint
|
||||
const existingViaVersion = this.#registries.find(({ specName, specVersion }) =>
|
||||
specName.eq(version.specName) &&
|
||||
specVersion.eq(version.specVersion)
|
||||
);
|
||||
const existingViaVersion = this._getBlockRegistryViaVersion(blockHash, version);
|
||||
|
||||
if (existingViaVersion) {
|
||||
existingViaVersion.lastBlockHash = blockHash;
|
||||
|
||||
return existingViaVersion;
|
||||
}
|
||||
|
||||
// nothing has been found, construct new
|
||||
const registry = new TypeRegistry(blockHash);
|
||||
const metadata = new Metadata(registry,
|
||||
await firstValueFrom((this._rpcCore.state.getMetadata as RpcInterfaceMethod).raw(header.parentHash))
|
||||
await firstValueFrom(this._rpcCore.state.getMetadata.raw<string>(header.parentHash))
|
||||
);
|
||||
|
||||
this._initRegistry(registry, this._runtimeChain as Text, version, metadata);
|
||||
@@ -175,7 +188,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
/**
|
||||
* @description Sets up a registry based on the block hash defined
|
||||
*/
|
||||
public async getBlockRegistry (blockHash: Uint8Array): Promise<VersionedRegistry<ApiType>> {
|
||||
public async getBlockRegistry (blockHash: Uint8Array, knownVersion?: RuntimeVersion): Promise<VersionedRegistry<ApiType>> {
|
||||
const existingViaHash = this.#registries.find(({ lastBlockHash }) =>
|
||||
lastBlockHash && u8aEq(lastBlockHash, blockHash)
|
||||
);
|
||||
@@ -184,6 +197,12 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
return existingViaHash;
|
||||
}
|
||||
|
||||
const existingViaVersion = this._getBlockRegistryViaVersion(blockHash, knownVersion);
|
||||
|
||||
if (existingViaVersion) {
|
||||
return existingViaVersion;
|
||||
}
|
||||
|
||||
const blockHashHex = u8aToHex(blockHash);
|
||||
let waiting = this.#waitingRegistries[blockHashHex];
|
||||
|
||||
@@ -225,17 +244,21 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
this._runtimeChain = source.runtimeChain;
|
||||
this._runtimeVersion = source.runtimeVersion;
|
||||
|
||||
const methods: string[] = [];
|
||||
|
||||
// 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
|
||||
Object.keys(source.rpc).forEach((section): void => {
|
||||
Object.keys((source.rpc as Record<string, Record<string, unknown>>)[section]).forEach((method): void => {
|
||||
methods.push(`${section}_${method}`);
|
||||
});
|
||||
});
|
||||
const sections = Object.keys(source.rpc);
|
||||
const rpcs: string[] = [];
|
||||
|
||||
this._filterRpc(methods, getSpecRpc(this.registry, source.runtimeChain, source.runtimeVersion.specName));
|
||||
for (let s = 0; s < sections.length; s++) {
|
||||
const section = sections[s];
|
||||
const methods = Object.keys((source.rpc as Record<string, Record<string, unknown>>)[section]);
|
||||
|
||||
for (let m = 0; m < methods.length; m++) {
|
||||
rpcs.push(`${section}_${methods[m]}`);
|
||||
}
|
||||
}
|
||||
|
||||
this._filterRpc(rpcs, getSpecRpc(this.registry, source.runtimeChain, source.runtimeVersion.specName));
|
||||
|
||||
return [source.genesisHash, source.runtimeMetadata];
|
||||
}
|
||||
@@ -318,7 +341,7 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
|
||||
// initializes the registry & RPC
|
||||
this._initRegistry(this.registry, chain, runtimeVersion, metadata, chainProps);
|
||||
this._filterRpc(rpcMethods.methods.map((t) => t.toString()), getSpecRpc(this.registry, chain, runtimeVersion.specName));
|
||||
this._filterRpc(rpcMethods.methods.map(textToString), getSpecRpc(this.registry, chain, runtimeVersion.specName));
|
||||
this._subscribeUpdates();
|
||||
|
||||
// setup the initial registry, when we have none
|
||||
|
||||
@@ -182,7 +182,7 @@ export function detectedCapabilities (api: ApiInterfaceRx, blockHash?: Uint8Arra
|
||||
},
|
||||
extractResults<ExtractedC>(cResults, consts),
|
||||
extractResults<ExtractedQ>(qResults, queries),
|
||||
extractResults<ExtractedR>(rResults, raws)
|
||||
extractResults<ExtractedR>(rResults.map((r) => api.registry.createType('Raw', r)), raws)
|
||||
)
|
||||
),
|
||||
take(1),
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { SignerPayloadRawBase } from '@polkadot/types/types';
|
||||
import type { ApiOptions, ApiTypes, DecorateMethod, Signer } from '../types';
|
||||
|
||||
import { assert, isString, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { assert, isString, objectSpread, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { Getters } from './Getters';
|
||||
|
||||
@@ -72,11 +72,9 @@ export abstract class ApiBase<ApiType extends ApiTypes> extends Getters<ApiType>
|
||||
assert(_signer?.signRaw, 'No signer exists with a signRaw interface. You possibly need to pass through an explicit keypair for the origin so it can be used for signing.');
|
||||
|
||||
return (
|
||||
await _signer.signRaw({
|
||||
type: 'bytes',
|
||||
...data,
|
||||
address
|
||||
})
|
||||
await _signer.signRaw(
|
||||
objectSpread({ type: 'bytes' }, data, { address })
|
||||
)
|
||||
).signature;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,6 @@ export { Keyring } from '@polkadot/keyring';
|
||||
export { WsProvider, HttpProvider } from '@polkadot/rpc-provider';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
export { ApiPromise, decorateMethod as decorateMethodPromise } from './promise';
|
||||
export * from './promise';
|
||||
export { SubmittableResult } from './submittable';
|
||||
export { ApiRx, decorateMethod as decorateMethodRx } from './rx';
|
||||
export * from './rx';
|
||||
|
||||
@@ -177,12 +177,10 @@ async function rpc (api: ApiPromise): Promise<void> {
|
||||
});
|
||||
|
||||
// using json & raw
|
||||
await api.rpc.chain.getBlock.json('0x123456');
|
||||
await api.rpc.chain.getBlock.raw('0x123456');
|
||||
|
||||
// using raw subs
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
api.rpc.chain.subscribeNewHeads.raw((result: Uint8Array): void => {
|
||||
await api.rpc.chain.subscribeNewHeads.raw((result: Uint8Array): void => {
|
||||
console.log(result);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/api', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/api', version: '6.8.1' };
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ApiOptions, UnsubscribePromise } from '../types';
|
||||
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
import { ApiBase } from '../base';
|
||||
import { Combinator, CombinatorCallback, CombinatorFunction } from './Combinator';
|
||||
import { promiseTracker, toPromiseMethod } from './decorateMethod';
|
||||
|
||||
/**
|
||||
* # @polkadot/api/promise
|
||||
*
|
||||
* ## Overview
|
||||
*
|
||||
* @name ApiPromise
|
||||
* @description
|
||||
* ApiPromise is a standard JavaScript wrapper around the RPC and interfaces on the Polkadot network. As a full Promise-based, all interface calls return Promises, including the static `.create(...)`. Subscription calls utilise `(value) => {}` callbacks to pass through the latest values.
|
||||
*
|
||||
* The API is well suited to real-time applications where either the single-shot state is needed or use is to be made of the subscription-based features of Polkadot (and Substrate) clients.
|
||||
*
|
||||
* @see [[ApiRx]]
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* Making rpc calls -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import ApiPromise from '@polkadot/api/promise';
|
||||
*
|
||||
* // initialise via static create
|
||||
* const api = await ApiPromise.create();
|
||||
*
|
||||
* // make a subscription to the network head
|
||||
* api.rpc.chain.subscribeNewHeads((header) => {
|
||||
* console.log(`Chain is at #${header.number}`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Subscribing to chain state -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { ApiPromise, WsProvider } from '@polkadot/api';
|
||||
*
|
||||
* // initialise a provider with a specific endpoint
|
||||
* const provider = new WsProvider('wss://example.com:9944')
|
||||
*
|
||||
* // initialise via isReady & new with specific provider
|
||||
* const api = await new ApiPromise({ provider }).isReady;
|
||||
*
|
||||
* // retrieve the block target time
|
||||
* const blockPeriod = await api.query.timestamp.blockPeriod().toNumber();
|
||||
* let last = 0;
|
||||
*
|
||||
* // subscribe to the current block timestamp, updates automatically (callback provided)
|
||||
* api.query.timestamp.now((timestamp) => {
|
||||
* const elapsed = last
|
||||
* ? `, ${timestamp.toNumber() - last}s since last`
|
||||
* : '';
|
||||
*
|
||||
* last = timestamp.toNumber();
|
||||
* console.log(`timestamp ${timestamp}${elapsed} (${blockPeriod}s target)`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Submitting a transaction -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import ApiPromise from '@polkadot/api/promise';
|
||||
*
|
||||
* ApiPromise.create().then((api) => {
|
||||
* const [nonce] = await api.query.system.account(keyring.alice.address);
|
||||
*
|
||||
* api.tx.balances
|
||||
* // create transfer
|
||||
* transfer(keyring.bob.address, 12345)
|
||||
* // sign the transcation
|
||||
* .sign(keyring.alice, { nonce })
|
||||
* // send the transaction (optional status callback)
|
||||
* .send((status) => {
|
||||
* console.log(`current status ${status.type}`);
|
||||
* })
|
||||
* // retrieve the submitted extrinsic hash
|
||||
* .then((hash) => {
|
||||
* console.log(`submitted with hash ${hash}`);
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export class ApiPromise extends ApiBase<'promise'> {
|
||||
#isReadyPromise: Promise<ApiPromise>;
|
||||
#isReadyOrErrorPromise: Promise<ApiPromise>;
|
||||
|
||||
/**
|
||||
* @description Creates an instance of the ApiPromise class
|
||||
* @param options Options to create an instance. This can be either [[ApiOptions]] or
|
||||
* an [[WsProvider]].
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import Api from '@polkadot/api/promise';
|
||||
*
|
||||
* new Api().isReady.then((api) => {
|
||||
* api.rpc.subscribeNewHeads((header) => {
|
||||
* console.log(`new block #${header.number.toNumber()}`);
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'promise', toPromiseMethod);
|
||||
|
||||
this.#isReadyPromise = new Promise((resolve): void => {
|
||||
super.once('ready', () => resolve(this));
|
||||
});
|
||||
|
||||
this.#isReadyOrErrorPromise = new Promise((resolve, reject): void => {
|
||||
const tracker = promiseTracker(resolve, reject);
|
||||
|
||||
super.once('ready', () => tracker.resolve(this));
|
||||
super.once('error', (error: Error) => tracker.reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates an ApiPromise instance using the supplied provider. Returns an Promise containing the actual Api instance.
|
||||
* @param options options that is passed to the class contructor. Can be either [[ApiOptions]] or a
|
||||
* provider (see the constructor arguments)
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import Api from '@polkadot/api/promise';
|
||||
*
|
||||
* Api.create().then(async (api) => {
|
||||
* const timestamp = await api.query.timestamp.now();
|
||||
*
|
||||
* console.log(`lastest block timestamp ${timestamp}`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public static create (options?: ApiOptions): Promise<ApiPromise> {
|
||||
const instance = new ApiPromise(options);
|
||||
|
||||
if (options && options.throwOnConnect) {
|
||||
return instance.isReadyOrError;
|
||||
}
|
||||
|
||||
// Swallow any rejections on isReadyOrError
|
||||
// (in Node 15.x this creates issues, when not being looked at)
|
||||
instance.isReadyOrError.catch(() => {
|
||||
// ignore
|
||||
});
|
||||
|
||||
return instance.isReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Promise that resolves the first time we are connected and loaded
|
||||
*/
|
||||
public get isReady (): Promise<ApiPromise> {
|
||||
return this.#isReadyPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Promise that resolves if we can connect, or reject if there is an error
|
||||
*/
|
||||
public get isReadyOrError (): Promise<ApiPromise> {
|
||||
return this.#isReadyOrErrorPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns a clone of this ApiPromise instance (new underlying provider connection)
|
||||
*/
|
||||
public clone (): ApiPromise {
|
||||
return new ApiPromise(
|
||||
objectSpread({}, this._options, { source: this })
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates a combinator that can be used to combine the latest results from multiple subscriptions
|
||||
* @param fns An array of function to combine, each in the form of `(cb: (value: void)) => void`
|
||||
* @param callback A callback that will return an Array of all the values this combinator has been applied to
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* const address = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFacT7';
|
||||
*
|
||||
* // combines values from balance & nonce as it updates
|
||||
* api.combineLatest([
|
||||
* api.rpc.chain.subscribeNewHeads,
|
||||
* (cb) => api.query.system.account(address, cb)
|
||||
* ], ([head, [balance, nonce]]) => {
|
||||
* console.log(`#${head.number}: You have ${balance.free} units, with ${nonce} transactions sent`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
public async combineLatest <T extends any[] = any[]> (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback<T>): UnsubscribePromise {
|
||||
const combinator = new Combinator(fns, callback);
|
||||
|
||||
return (): void => {
|
||||
combinator.unsubscribe();
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { Callback, Codec } from '@polkadot/types/types';
|
||||
import type { DecorateFn, DecorateMethodOptions, ObsInnerType, StorageEntryPromiseOverloads, UnsubscribePromise, VoidFn } from '../types';
|
||||
|
||||
import { catchError, EMPTY, Subscription, tap } from 'rxjs';
|
||||
|
||||
import { assert, isFunction } from '@polkadot/util';
|
||||
|
||||
interface Tracker<T> {
|
||||
reject: (value: Error) => Observable<never>;
|
||||
resolve: (value: T) => void;
|
||||
}
|
||||
|
||||
// a Promise completion tracker, wrapping an isComplete variable that ensures the promise only resolves once
|
||||
export function promiseTracker<T> (resolve: (value: T) => void, reject: (value: Error) => void): Tracker<T> {
|
||||
let isCompleted = false;
|
||||
|
||||
return {
|
||||
reject: (error: Error): Observable<never> => {
|
||||
if (!isCompleted) {
|
||||
isCompleted = true;
|
||||
|
||||
reject(error);
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
},
|
||||
resolve: (value: T): void => {
|
||||
if (!isCompleted) {
|
||||
isCompleted = true;
|
||||
|
||||
resolve(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// extract the arguments and callback params from a value array possibly containing a callback
|
||||
function extractArgs (args: unknown[], needsCallback: boolean): [unknown[], Callback<Codec> | undefined] {
|
||||
let callback: Callback<Codec> | undefined;
|
||||
const actualArgs = args.slice();
|
||||
|
||||
// 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`
|
||||
if (args.length && isFunction(args[args.length - 1])) {
|
||||
callback = actualArgs.pop() as Callback<Codec>;
|
||||
}
|
||||
|
||||
// When we need a subscription, ensure that a valid callback is actually passed
|
||||
assert(!needsCallback || isFunction(callback), 'Expected a callback to be passed with subscriptions');
|
||||
|
||||
return [actualArgs, callback];
|
||||
}
|
||||
|
||||
// Decorate a call for a single-shot result - retrieve and then immediate unsubscribe
|
||||
function decorateCall<M extends DecorateFn<ObsInnerType<ReturnType<M>>>> (method: M, args: unknown[]): Promise<ObsInnerType<ReturnType<M>>> {
|
||||
return new Promise((resolve, reject): void => {
|
||||
// single result tracker - either reject with Error or resolve with Codec result
|
||||
const tracker = promiseTracker(resolve, reject);
|
||||
|
||||
// encoding errors reject immediately, any result unsubscribes and resolves
|
||||
const subscription: Subscription = method(...args)
|
||||
.pipe(
|
||||
catchError((error: Error) => tracker.reject(error))
|
||||
)
|
||||
.subscribe((result): void => {
|
||||
tracker.resolve(result);
|
||||
setTimeout(() => subscription.unsubscribe(), 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Decorate a subscription where we have a result callback specified
|
||||
function decorateSubscribe<M extends DecorateFn<ObsInnerType<ReturnType<M>>>> (method: M, args: unknown[], resultCb: Callback<Codec>): UnsubscribePromise {
|
||||
return new Promise<VoidFn>((resolve, reject): void => {
|
||||
// either reject with error or resolve with unsubscribe callback
|
||||
const tracker = promiseTracker(resolve, reject);
|
||||
|
||||
// errors reject immediately, the first result resolves with an unsubscribe promise, all results via callback
|
||||
const subscription: Subscription = method(...args)
|
||||
.pipe(
|
||||
catchError((error: Error) => tracker.reject(error)),
|
||||
tap(() => tracker.resolve(() => subscription.unsubscribe()))
|
||||
)
|
||||
.subscribe((result): void => {
|
||||
// queue result (back of queue to clear current)
|
||||
setTimeout(() => resultCb(result) as void, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Decorate method for ApiPromise, where the results are converted to the Promise equivalent
|
||||
*/
|
||||
export function toPromiseMethod<M extends DecorateFn<ObsInnerType<ReturnType<M>>>> (method: M, options?: DecorateMethodOptions): StorageEntryPromiseOverloads {
|
||||
const needsCallback = !!(options && options.methodName && options.methodName.includes('subscribe'));
|
||||
|
||||
return function (...args: unknown[]): Promise<ObsInnerType<ReturnType<M>>> | UnsubscribePromise {
|
||||
const [actualArgs, resultCb] = extractArgs(args, needsCallback);
|
||||
|
||||
return resultCb
|
||||
? decorateSubscribe(method, actualArgs, resultCb)
|
||||
: decorateCall((options?.overrideNoSub as M) || method, actualArgs);
|
||||
} as StorageEntryPromiseOverloads;
|
||||
}
|
||||
@@ -1,313 +1,5 @@
|
||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { Callback, Codec } from '@polkadot/types/types';
|
||||
import type { ApiOptions, DecorateFn, DecorateMethodOptions, ObsInnerType, StorageEntryPromiseOverloads, UnsubscribePromise, VoidFn } from '../types';
|
||||
|
||||
import { catchError, EMPTY, Subscription, tap } from 'rxjs';
|
||||
|
||||
import { assert, isFunction } from '@polkadot/util';
|
||||
|
||||
import { ApiBase } from '../base';
|
||||
import { Combinator, CombinatorCallback, CombinatorFunction } from './Combinator';
|
||||
|
||||
interface Tracker<T> {
|
||||
reject: (value: Error) => Observable<never>;
|
||||
resolve: (value: T) => void;
|
||||
}
|
||||
|
||||
// extract the arguments and callback params from a value array possibly containing a callback
|
||||
function extractArgs (args: unknown[], needsCallback: boolean): [unknown[], Callback<Codec> | undefined] {
|
||||
let callback: Callback<Codec> | undefined;
|
||||
const actualArgs = args.slice();
|
||||
|
||||
// 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`
|
||||
if (args.length && isFunction(args[args.length - 1])) {
|
||||
callback = actualArgs.pop() as Callback<Codec>;
|
||||
}
|
||||
|
||||
// When we need a subscription, ensure that a valid callback is actually passed
|
||||
assert(!needsCallback || isFunction(callback), 'Expected a callback to be passed with subscriptions');
|
||||
|
||||
return [actualArgs, callback];
|
||||
}
|
||||
|
||||
// a Promise completion tracker, wrapping an isComplete variable that ensures the promise only resolves once
|
||||
function promiseTracker<T> (resolve: (value: T) => void, reject: (value: Error) => void): Tracker<T> {
|
||||
let isCompleted = false;
|
||||
|
||||
return {
|
||||
reject: (error: Error): Observable<never> => {
|
||||
if (!isCompleted) {
|
||||
isCompleted = true;
|
||||
|
||||
reject(error);
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
},
|
||||
resolve: (value: T): void => {
|
||||
if (!isCompleted) {
|
||||
isCompleted = true;
|
||||
|
||||
resolve(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Decorate a call for a single-shot result - retrieve and then immediate unsubscribe
|
||||
function decorateCall<Method extends DecorateFn<ObsInnerType<ReturnType<Method>>>> (method: Method, actualArgs: unknown[]): Promise<ObsInnerType<ReturnType<Method>>> {
|
||||
return new Promise((resolve, reject): void => {
|
||||
// single result tracker - either reject with Error or resolve with Codec result
|
||||
const tracker = promiseTracker(resolve, reject);
|
||||
|
||||
// encoding errors reject immediately, any result unsubscribes and resolves
|
||||
const subscription: Subscription = method(...actualArgs).pipe(
|
||||
catchError((error: Error) => tracker.reject(error))
|
||||
).subscribe((result): void => {
|
||||
tracker.resolve(result);
|
||||
setTimeout(() => subscription.unsubscribe(), 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Decorate a subscription where we have a result callback specified
|
||||
function decorateSubscribe<Method extends DecorateFn<ObsInnerType<ReturnType<Method>>>> (method: Method, actualArgs: unknown[], resultCb: Callback<Codec>): UnsubscribePromise {
|
||||
return new Promise<VoidFn>((resolve, reject): void => {
|
||||
// either reject with error or resolve with unsubscribe callback
|
||||
const tracker = promiseTracker(resolve, reject);
|
||||
|
||||
// errors reject immediately, the first result resolves with an unsubscribe promise, all results via callback
|
||||
const subscription: Subscription = method(...actualArgs).pipe(
|
||||
catchError((error: Error) => tracker.reject(error)),
|
||||
tap(() => tracker.resolve(() => subscription.unsubscribe()))
|
||||
).subscribe((result): void => {
|
||||
// queue result (back of queue to clear current)
|
||||
setTimeout(() => resultCb(result) as void, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Decorate method for ApiPromise, where the results are converted to the Promise equivalent
|
||||
*/
|
||||
export function decorateMethod<Method extends DecorateFn<ObsInnerType<ReturnType<Method>>>> (method: Method, options?: DecorateMethodOptions): StorageEntryPromiseOverloads {
|
||||
const needsCallback = options && options.methodName && options.methodName.includes('subscribe');
|
||||
|
||||
return function (...args: unknown[]): Promise<ObsInnerType<ReturnType<Method>>> | UnsubscribePromise {
|
||||
const [actualArgs, resultCb] = extractArgs(args, !!needsCallback);
|
||||
|
||||
return resultCb
|
||||
? decorateSubscribe(method, actualArgs, resultCb)
|
||||
: decorateCall((options?.overrideNoSub as Method) || method, actualArgs);
|
||||
} as StorageEntryPromiseOverloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* # @polkadot/api/promise
|
||||
*
|
||||
* ## Overview
|
||||
*
|
||||
* @name ApiPromise
|
||||
* @description
|
||||
* ApiPromise is a standard JavaScript wrapper around the RPC and interfaces on the Polkadot network. As a full Promise-based, all interface calls return Promises, including the static `.create(...)`. Subscription calls utilise `(value) => {}` callbacks to pass through the latest values.
|
||||
*
|
||||
* The API is well suited to real-time applications where either the single-shot state is needed or use is to be made of the subscription-based features of Polkadot (and Substrate) clients.
|
||||
*
|
||||
* @see [[ApiRx]]
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* Making rpc calls -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import ApiPromise from '@polkadot/api/promise';
|
||||
*
|
||||
* // initialise via static create
|
||||
* const api = await ApiPromise.create();
|
||||
*
|
||||
* // make a subscription to the network head
|
||||
* api.rpc.chain.subscribeNewHeads((header) => {
|
||||
* console.log(`Chain is at #${header.number}`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Subscribing to chain state -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { ApiPromise, WsProvider } from '@polkadot/api';
|
||||
*
|
||||
* // initialise a provider with a specific endpoint
|
||||
* const provider = new WsProvider('wss://example.com:9944')
|
||||
*
|
||||
* // initialise via isReady & new with specific provider
|
||||
* const api = await new ApiPromise({ provider }).isReady;
|
||||
*
|
||||
* // retrieve the block target time
|
||||
* const blockPeriod = await api.query.timestamp.blockPeriod().toNumber();
|
||||
* let last = 0;
|
||||
*
|
||||
* // subscribe to the current block timestamp, updates automatically (callback provided)
|
||||
* api.query.timestamp.now((timestamp) => {
|
||||
* const elapsed = last
|
||||
* ? `, ${timestamp.toNumber() - last}s since last`
|
||||
* : '';
|
||||
*
|
||||
* last = timestamp.toNumber();
|
||||
* console.log(`timestamp ${timestamp}${elapsed} (${blockPeriod}s target)`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Submitting a transaction -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import ApiPromise from '@polkadot/api/promise';
|
||||
*
|
||||
* ApiPromise.create().then((api) => {
|
||||
* const [nonce] = await api.query.system.account(keyring.alice.address);
|
||||
*
|
||||
* api.tx.balances
|
||||
* // create transfer
|
||||
* transfer(keyring.bob.address, 12345)
|
||||
* // sign the transcation
|
||||
* .sign(keyring.alice, { nonce })
|
||||
* // send the transaction (optional status callback)
|
||||
* .send((status) => {
|
||||
* console.log(`current status ${status.type}`);
|
||||
* })
|
||||
* // retrieve the submitted extrinsic hash
|
||||
* .then((hash) => {
|
||||
* console.log(`submitted with hash ${hash}`);
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export class ApiPromise extends ApiBase<'promise'> {
|
||||
#isReadyPromise: Promise<ApiPromise>;
|
||||
#isReadyOrErrorPromise: Promise<ApiPromise>;
|
||||
|
||||
/**
|
||||
* @description Creates an ApiPromise instance using the supplied provider. Returns an Promise containing the actual Api instance.
|
||||
* @param options options that is passed to the class contructor. Can be either [[ApiOptions]] or a
|
||||
* provider (see the constructor arguments)
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import Api from '@polkadot/api/promise';
|
||||
*
|
||||
* Api.create().then(async (api) => {
|
||||
* const timestamp = await api.query.timestamp.now();
|
||||
*
|
||||
* console.log(`lastest block timestamp ${timestamp}`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public static create (options?: ApiOptions): Promise<ApiPromise> {
|
||||
const instance = new ApiPromise(options);
|
||||
|
||||
if (options && options.throwOnConnect) {
|
||||
return instance.isReadyOrError;
|
||||
}
|
||||
|
||||
// Swallow any rejections on isReadyOrError
|
||||
// (in Node 15.x this creates issues, when not being looked at)
|
||||
instance.isReadyOrError.catch(() => {
|
||||
// ignore
|
||||
});
|
||||
|
||||
return instance.isReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates an instance of the ApiPromise class
|
||||
* @param options Options to create an instance. This can be either [[ApiOptions]] or
|
||||
* an [[WsProvider]].
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import Api from '@polkadot/api/promise';
|
||||
*
|
||||
* new Api().isReady.then((api) => {
|
||||
* api.rpc.subscribeNewHeads((header) => {
|
||||
* console.log(`new block #${header.number.toNumber()}`);
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'promise', decorateMethod);
|
||||
|
||||
this.#isReadyPromise = new Promise((resolve): void => {
|
||||
super.once('ready', () => resolve(this));
|
||||
});
|
||||
|
||||
this.#isReadyOrErrorPromise = new Promise((resolve, reject): void => {
|
||||
const tracker = promiseTracker(resolve, reject);
|
||||
|
||||
super.once('ready', () => tracker.resolve(this));
|
||||
super.once('error', (error: Error) => tracker.reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Promise that resolves the first time we are connected and loaded
|
||||
*/
|
||||
public get isReady (): Promise<ApiPromise> {
|
||||
return this.#isReadyPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Promise that resolves if we can connect, or reject if there is an error
|
||||
*/
|
||||
public get isReadyOrError (): Promise<ApiPromise> {
|
||||
return this.#isReadyOrErrorPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns a clone of this ApiPromise instance (new underlying provider connection)
|
||||
*/
|
||||
public clone (): ApiPromise {
|
||||
return new ApiPromise({
|
||||
...this._options,
|
||||
source: this
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates a combinator that can be used to combine the latest results from multiple subscriptions
|
||||
* @param fns An array of function to combine, each in the form of `(cb: (value: void)) => void`
|
||||
* @param callback A callback that will return an Array of all the values this combinator has been applied to
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* const address = '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFacT7';
|
||||
*
|
||||
* // combines values from balance & nonce as it updates
|
||||
* api.combineLatest([
|
||||
* api.rpc.chain.subscribeNewHeads,
|
||||
* (cb) => api.query.system.account(address, cb)
|
||||
* ], ([head, [balance, nonce]]) => {
|
||||
* console.log(`#${head.number}: You have ${balance.free} units, with ${nonce} transactions sent`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
public async combineLatest <T extends any[] = any[]> (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback<T>): UnsubscribePromise {
|
||||
const combinator = new Combinator(fns, callback);
|
||||
|
||||
return (): void => {
|
||||
combinator.unsubscribe();
|
||||
};
|
||||
}
|
||||
}
|
||||
export { ApiPromise } from './Api';
|
||||
export { toPromiseMethod } from './decorateMethod';
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ApiOptions } from '../types';
|
||||
|
||||
import { from, Observable } from 'rxjs';
|
||||
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
import { ApiBase } from '../base';
|
||||
import { toRxMethod } from './decorateMethod';
|
||||
|
||||
/**
|
||||
* # @polkadot/api/rx
|
||||
*
|
||||
* ## Overview
|
||||
*
|
||||
* @name ApiRx
|
||||
*
|
||||
* @description
|
||||
* ApiRx is a powerful RxJS Observable wrapper around the RPC and interfaces on the Polkadot network. As a full Observable API, all interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion and subscription-based methods return long-running Observables that update with the latest values.
|
||||
*
|
||||
* The API is well suited to real-time applications where the latest state is needed, unlocking the subscription-based features of Polkadot (and Substrate) clients. Some familiarity with RxJS is a requirement to use the API, however just understanding `.subscribe` and `.pipe` on Observables will unlock full-scale use thereof.
|
||||
*
|
||||
* @see [[ApiPromise]]
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* Making rpc calls -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import ApiRx from '@polkadot/api/rx';
|
||||
*
|
||||
* // initialize via Promise & static create
|
||||
* const api = await ApiRx.create().toPromise();
|
||||
*
|
||||
* // make a call to retrieve the current network head
|
||||
* api.rpc.chain.subscribeNewHeads().subscribe((header) => {
|
||||
* console.log(`Chain is at #${header.number}`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Subscribing to chain state -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { combineLatest, pairwise, switchMap } from 'rxjs';
|
||||
* import { ApiRx, WsProvider } from '@polkadot/api';
|
||||
*
|
||||
*
|
||||
* // initialize a provider with a specific endpoint
|
||||
* const provider = new WsProvider('wss://example.com:9944')
|
||||
*
|
||||
* // initialize via isReady & new with specific provider
|
||||
* new ApiRx({ provider })
|
||||
* .isReady
|
||||
* .pipe(
|
||||
* switchMap((api) =>
|
||||
* combineLatest([
|
||||
* api.query.timestamp.blockPeriod(),
|
||||
* api.query.timestamp.now().pipe(pairwise())
|
||||
* ])
|
||||
* )
|
||||
* )
|
||||
* .subscribe(([blockPeriod, timestamp]) => {
|
||||
* const elapsed = timestamp[1].toNumber() - timestamp[0].toNumber();
|
||||
* console.log(`timestamp ${timestamp[1]} \nelapsed ${elapsed} \n(${blockPeriod}s target)`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Submitting a transaction -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { first, switchMap } from 'rxjs';
|
||||
* import ApiRx from '@polkadot/api/rx';
|
||||
*
|
||||
* // import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
|
||||
* import testingPairs from '@polkadot/keyring/testingPairs';
|
||||
* const keyring = testingPairs();
|
||||
*
|
||||
* // get api via Promise
|
||||
* const api = await ApiRx.create().toPromise();
|
||||
*
|
||||
* // retrieve nonce for the account
|
||||
* api.query.system
|
||||
* .account(keyring.alice.address)
|
||||
* .pipe(
|
||||
* first(),
|
||||
* // pipe nonce into transfer
|
||||
* switchMap(([nonce]) =>
|
||||
* api.tx.balances
|
||||
* // create transfer
|
||||
* .transfer(keyring.bob.address, 12345)
|
||||
* // sign the transaction
|
||||
* .sign(keyring.alice, { nonce })
|
||||
* // send the transaction
|
||||
* .send()
|
||||
* )
|
||||
* )
|
||||
* // subscribe to overall result
|
||||
* .subscribe(({ status }) => {
|
||||
* if (status.isInBlock) {
|
||||
* console.log('Completed at block hash', status.asFinalized.toHex());
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export class ApiRx extends ApiBase<'rxjs'> {
|
||||
#isReadyRx: Observable<ApiRx>;
|
||||
|
||||
/**
|
||||
* @description Create an instance of the ApiRx class
|
||||
* @param options Options to create an instance. Can be either [[ApiOptions]] or [[WsProvider]]
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { switchMap } from 'rxjs';
|
||||
* import Api from '@polkadot/api/rx';
|
||||
*
|
||||
* new Api().isReady
|
||||
* .pipe(
|
||||
* switchMap((api) =>
|
||||
* api.rpc.chain.subscribeNewHeads()
|
||||
* ))
|
||||
* .subscribe((header) => {
|
||||
* console.log(`new block #${header.number.toNumber()}`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'rxjs', toRxMethod);
|
||||
|
||||
this.#isReadyRx = from<Promise<ApiRx>>(
|
||||
// You can create an observable from an event, however my mind groks this form better
|
||||
new Promise((resolve): void => {
|
||||
super.on('ready', () => resolve(this));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Creates an ApiRx instance using the supplied provider. Returns an Observable containing the actual Api instance.
|
||||
* @param options options that is passed to the class constructor. Can be either [[ApiOptions]] or [[WsProvider]]
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { switchMap } from 'rxjs';
|
||||
* import Api from '@polkadot/api/rx';
|
||||
*
|
||||
* Api.create()
|
||||
* .pipe(
|
||||
* switchMap((api) =>
|
||||
* api.rpc.chain.subscribeNewHeads()
|
||||
* ))
|
||||
* .subscribe((header) => {
|
||||
* console.log(`new block #${header.number.toNumber()}`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public static create (options?: ApiOptions): Observable<ApiRx> {
|
||||
return new ApiRx(options).isReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Observable that returns the first time we are connected and loaded
|
||||
*/
|
||||
public get isReady (): Observable<ApiRx> {
|
||||
return this.#isReadyRx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns a clone of this ApiRx instance (new underlying provider connection)
|
||||
*/
|
||||
public clone (): ApiRx {
|
||||
return new ApiRx(
|
||||
objectSpread({}, this._options, { source: this })
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Codec } from '@polkadot/types/types';
|
||||
import type { DecorateFn } from '../types';
|
||||
|
||||
export function toRxMethod <M extends DecorateFn<Codec>> (method: M): M {
|
||||
return method;
|
||||
}
|
||||
@@ -1,188 +1,5 @@
|
||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Codec } from '@polkadot/types/types';
|
||||
import type { ApiOptions, DecorateFn } from '../types';
|
||||
|
||||
import { from, Observable } from 'rxjs';
|
||||
|
||||
import { ApiBase } from '../base';
|
||||
|
||||
export function decorateMethod <Method extends DecorateFn<Codec>> (method: Method): Method {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* # @polkadot/api/rx
|
||||
*
|
||||
* ## Overview
|
||||
*
|
||||
* @name ApiRx
|
||||
*
|
||||
* @description
|
||||
* ApiRx is a powerful RxJS Observable wrapper around the RPC and interfaces on the Polkadot network. As a full Observable API, all interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion and subscription-based methods return long-running Observables that update with the latest values.
|
||||
*
|
||||
* The API is well suited to real-time applications where the latest state is needed, unlocking the subscription-based features of Polkadot (and Substrate) clients. Some familiarity with RxJS is a requirement to use the API, however just understanding `.subscribe` and `.pipe` on Observables will unlock full-scale use thereof.
|
||||
*
|
||||
* @see [[ApiPromise]]
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* Making rpc calls -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import ApiRx from '@polkadot/api/rx';
|
||||
*
|
||||
* // initialize via Promise & static create
|
||||
* const api = await ApiRx.create().toPromise();
|
||||
*
|
||||
* // make a call to retrieve the current network head
|
||||
* api.rpc.chain.subscribeNewHeads().subscribe((header) => {
|
||||
* console.log(`Chain is at #${header.number}`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Subscribing to chain state -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { combineLatest, pairwise, switchMap } from 'rxjs';
|
||||
* import { ApiRx, WsProvider } from '@polkadot/api';
|
||||
*
|
||||
*
|
||||
* // initialize a provider with a specific endpoint
|
||||
* const provider = new WsProvider('wss://example.com:9944')
|
||||
*
|
||||
* // initialize via isReady & new with specific provider
|
||||
* new ApiRx({ provider })
|
||||
* .isReady
|
||||
* .pipe(
|
||||
* switchMap((api) =>
|
||||
* combineLatest([
|
||||
* api.query.timestamp.blockPeriod(),
|
||||
* api.query.timestamp.now().pipe(pairwise())
|
||||
* ])
|
||||
* )
|
||||
* )
|
||||
* .subscribe(([blockPeriod, timestamp]) => {
|
||||
* const elapsed = timestamp[1].toNumber() - timestamp[0].toNumber();
|
||||
* console.log(`timestamp ${timestamp[1]} \nelapsed ${elapsed} \n(${blockPeriod}s target)`);
|
||||
* });
|
||||
* ```
|
||||
* <BR>
|
||||
*
|
||||
* Submitting a transaction -
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { first, switchMap } from 'rxjs';
|
||||
* import ApiRx from '@polkadot/api/rx';
|
||||
*
|
||||
* // import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
|
||||
* import testingPairs from '@polkadot/keyring/testingPairs';
|
||||
* const keyring = testingPairs();
|
||||
*
|
||||
* // get api via Promise
|
||||
* const api = await ApiRx.create().toPromise();
|
||||
*
|
||||
* // retrieve nonce for the account
|
||||
* api.query.system
|
||||
* .account(keyring.alice.address)
|
||||
* .pipe(
|
||||
* first(),
|
||||
* // pipe nonce into transfer
|
||||
* switchMap(([nonce]) =>
|
||||
* api.tx.balances
|
||||
* // create transfer
|
||||
* .transfer(keyring.bob.address, 12345)
|
||||
* // sign the transaction
|
||||
* .sign(keyring.alice, { nonce })
|
||||
* // send the transaction
|
||||
* .send()
|
||||
* )
|
||||
* )
|
||||
* // subscribe to overall result
|
||||
* .subscribe(({ status }) => {
|
||||
* if (status.isInBlock) {
|
||||
* console.log('Completed at block hash', status.asFinalized.toHex());
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export class ApiRx extends ApiBase<'rxjs'> {
|
||||
#isReadyRx: Observable<ApiRx>;
|
||||
|
||||
/**
|
||||
* @description Creates an ApiRx instance using the supplied provider. Returns an Observable containing the actual Api instance.
|
||||
* @param options options that is passed to the class constructor. Can be either [[ApiOptions]] or [[WsProvider]]
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { switchMap } from 'rxjs';
|
||||
* import Api from '@polkadot/api/rx';
|
||||
*
|
||||
* Api.create()
|
||||
* .pipe(
|
||||
* switchMap((api) =>
|
||||
* api.rpc.chain.subscribeNewHeads()
|
||||
* ))
|
||||
* .subscribe((header) => {
|
||||
* console.log(`new block #${header.number.toNumber()}`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public static create (options?: ApiOptions): Observable<ApiRx> {
|
||||
return new ApiRx(options).isReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Create an instance of the ApiRx class
|
||||
* @param options Options to create an instance. Can be either [[ApiOptions]] or [[WsProvider]]
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { switchMap } from 'rxjs';
|
||||
* import Api from '@polkadot/api/rx';
|
||||
*
|
||||
* new Api().isReady
|
||||
* .pipe(
|
||||
* switchMap((api) =>
|
||||
* api.rpc.chain.subscribeNewHeads()
|
||||
* ))
|
||||
* .subscribe((header) => {
|
||||
* console.log(`new block #${header.number.toNumber()}`);
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'rxjs', decorateMethod);
|
||||
|
||||
this.#isReadyRx = from<Promise<ApiRx>>(
|
||||
// You can create an observable from an event, however my mind groks this form better
|
||||
new Promise((resolve): void => {
|
||||
super.on('ready', () => resolve(this));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Observable that returns the first time we are connected and loaded
|
||||
*/
|
||||
public get isReady (): Observable<ApiRx> {
|
||||
return this.#isReadyRx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns a clone of this ApiRx instance (new underlying provider connection)
|
||||
*/
|
||||
public clone (): ApiRx {
|
||||
return new ApiRx({
|
||||
...this._options,
|
||||
source: this
|
||||
});
|
||||
}
|
||||
}
|
||||
export { ApiRx } from './Api';
|
||||
export { toRxMethod } from './decorateMethod';
|
||||
|
||||
@@ -9,22 +9,29 @@ const recordIdentity = (record: EventRecord) => record;
|
||||
|
||||
function filterAndApply <T> (events: EventRecord[], section: string, methods: string[], onFound: (record: EventRecord) => T): T[] {
|
||||
return events
|
||||
.filter(({ event }) => section === event.section && methods.includes(event.method))
|
||||
.filter(({ event }) =>
|
||||
section === event.section &&
|
||||
methods.includes(event.method)
|
||||
)
|
||||
.map((record) => onFound(record));
|
||||
}
|
||||
|
||||
function getDispatchError ({ event: { data: [dispatchError] } }: EventRecord): DispatchError {
|
||||
return dispatchError as DispatchError;
|
||||
}
|
||||
|
||||
function getDispatchInfo ({ event: { data, method } }: EventRecord): DispatchInfo {
|
||||
return method === 'ExtrinsicSuccess'
|
||||
? data[0] as DispatchInfo
|
||||
: data[1] as DispatchInfo;
|
||||
}
|
||||
|
||||
function extractError (events: EventRecord[] = []): DispatchError | undefined {
|
||||
return filterAndApply(events, 'system', ['ExtrinsicFailed'], ({ event: { data } }) =>
|
||||
data[0] as DispatchError
|
||||
)[0];
|
||||
return filterAndApply(events, 'system', ['ExtrinsicFailed'], getDispatchError)[0];
|
||||
}
|
||||
|
||||
function extractInfo (events: EventRecord[] = []): DispatchInfo | undefined {
|
||||
return filterAndApply(events, 'system', ['ExtrinsicFailed', 'ExtrinsicSuccess'], ({ event: { data, method } }) =>
|
||||
method === 'ExtrinsicSuccess'
|
||||
? data[0] as DispatchInfo
|
||||
: data[1] as DispatchInfo
|
||||
)[0];
|
||||
return filterAndApply(events, 'system', ['ExtrinsicFailed', 'ExtrinsicSuccess'], getDispatchInfo)[0];
|
||||
}
|
||||
|
||||
export class SubmittableResult implements ISubmittableResult {
|
||||
@@ -87,7 +94,7 @@ export class SubmittableResult implements ISubmittableResult {
|
||||
return {
|
||||
dispatchError: this.dispatchError?.toHuman(),
|
||||
dispatchInfo: this.dispatchInfo?.toHuman(),
|
||||
events: this.events.map((event) => event.toHuman(isExtended)),
|
||||
events: this.events.map((e) => e.toHuman(isExtended)),
|
||||
internalError: this.internalError?.message.toString(),
|
||||
status: this.status.toHuman(isExtended)
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { AddressOrPair, SignerOptions, SubmittableDryRunResult, Submittable
|
||||
|
||||
import { catchError, first, map, mapTo, mergeMap, of, switchMap, tap } from 'rxjs';
|
||||
|
||||
import { assert, isBn, isFunction, isNumber, isString, isU8a } from '@polkadot/util';
|
||||
import { assert, isBn, isFunction, isNumber, isString, isU8a, objectSpread } from '@polkadot/util';
|
||||
|
||||
import { ApiBase } from '../base';
|
||||
import { filterEvents, isKeyringPair } from '../util';
|
||||
@@ -25,6 +25,55 @@ interface SubmittableOptions<ApiType extends ApiTypes> {
|
||||
|
||||
const identity = <T> (input: T): T => input;
|
||||
|
||||
function makeEraOptions (api: ApiInterfaceRx, registry: Registry, partialOptions: Partial<SignerOptions>, { header, mortalLength, nonce }: { header: Header | null; mortalLength: number; nonce: Index }): SignatureOptions {
|
||||
if (!header) {
|
||||
if (isNumber(partialOptions.era)) {
|
||||
// since we have no header, it is immortal, remove any option overrides
|
||||
// so we only supply the genesisHash and no era to the construction
|
||||
delete partialOptions.era;
|
||||
delete partialOptions.blockHash;
|
||||
}
|
||||
|
||||
return makeSignOptions(api, partialOptions, { nonce });
|
||||
}
|
||||
|
||||
return makeSignOptions(api, partialOptions, {
|
||||
blockHash: header.hash,
|
||||
era: registry.createType('ExtrinsicEra', {
|
||||
current: header.number,
|
||||
period: partialOptions.era || mortalLength
|
||||
}),
|
||||
nonce
|
||||
});
|
||||
}
|
||||
|
||||
function makeSignAndSendOptions (partialOptions?: Partial<SignerOptions> | Callback<ISubmittableResult>, statusCb?: Callback<ISubmittableResult>): [Partial<SignerOptions>, Callback<ISubmittableResult>?] {
|
||||
let options: Partial<SignerOptions> = {};
|
||||
|
||||
if (isFunction(partialOptions)) {
|
||||
statusCb = partialOptions;
|
||||
} else {
|
||||
options = objectSpread({}, partialOptions);
|
||||
}
|
||||
|
||||
return [options, statusCb];
|
||||
}
|
||||
|
||||
function makeSignOptions (api: ApiInterfaceRx, partialOptions: Partial<SignerOptions>, extras: { blockHash?: Hash; era?: ExtrinsicEra; nonce?: Index }): SignatureOptions {
|
||||
return objectSpread(
|
||||
{ blockHash: api.genesisHash, genesisHash: api.genesisHash },
|
||||
partialOptions,
|
||||
extras,
|
||||
{ runtimeVersion: api.runtimeVersion, signedExtensions: api.registry.signedExtensions, version: api.extrinsicType }
|
||||
);
|
||||
}
|
||||
|
||||
function optionsOrNonce (partialOptions: Partial<SignerOptions> = {}): Partial<SignerOptions> {
|
||||
return isBn(partialOptions) || isNumber(partialOptions)
|
||||
? { nonce: partialOptions }
|
||||
: partialOptions;
|
||||
}
|
||||
|
||||
export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorateMethod }: SubmittableOptions<ApiType>): Constructor<SubmittableExtrinsic<ApiType>> {
|
||||
// an instance of the base extrinsic for us to extend
|
||||
const ExtrinsicBase = api.registry.createClass('Extrinsic');
|
||||
@@ -67,7 +116,7 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
);
|
||||
}
|
||||
|
||||
const [allOptions] = this.#makeSignAndSendOptions(optionsOrHash);
|
||||
const [allOptions] = makeSignAndSendOptions(optionsOrHash);
|
||||
const address = isKeyringPair(account) ? account.address : account.toString();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||
@@ -77,8 +126,8 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
first(),
|
||||
switchMap((signingInfo): Observable<RuntimeDispatchInfo> => {
|
||||
// setup our options (same way as in signAndSend)
|
||||
const eraOptions = this.#makeEraOptions(allOptions, signingInfo);
|
||||
const signOptions = this.#makeSignOptions(eraOptions, {});
|
||||
const eraOptions = makeEraOptions(api, this.registry, allOptions, signingInfo);
|
||||
const signOptions = makeSignOptions(api, eraOptions, {});
|
||||
|
||||
this.signFake(address, signOptions);
|
||||
|
||||
@@ -110,8 +159,8 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
* @description Sign a transaction, returning the this to allow chaining, i.e. .sign(...).send(). When options, e.g. nonce/blockHash are not specified, it will be inferred. To retrieve eg. nonce use `signAsync` (the preferred interface, this is provided for backwards compatibility)
|
||||
* @deprecated
|
||||
*/
|
||||
public override sign (account: IKeyringPair, optionsOrNonce?: Partial<SignerOptions>): this {
|
||||
super.sign(account, this.#makeSignOptions(this.#optionsOrNonce(optionsOrNonce), {}));
|
||||
public override sign (account: IKeyringPair, partialOptions?: Partial<SignerOptions>): this {
|
||||
super.sign(account, makeSignOptions(api, optionsOrNonce(partialOptions), {}));
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -119,26 +168,28 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
/**
|
||||
* @description Signs a transaction, returning `this` to allow chaining. E.g.: `sign(...).send()`. Like `.signAndSend` this will retrieve the nonce and blockHash to send the tx with.
|
||||
*/
|
||||
public signAsync (account: AddressOrPair, optionsOrNonce?: Partial<SignerOptions>): SubmittableThis<ApiType, this> {
|
||||
public signAsync (account: AddressOrPair, partialOptions?: Partial<SignerOptions>): SubmittableThis<ApiType, this> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||
return decorateMethod(
|
||||
(): Observable<this> =>
|
||||
this.#observeSign(account, optionsOrNonce).pipe(mapTo(this) as OperatorFunction<number | undefined, this>)
|
||||
this.#observeSign(account, partialOptions).pipe(
|
||||
mapTo<number | undefined, this>(this)
|
||||
)
|
||||
)();
|
||||
}
|
||||
|
||||
// signAndSend with an immediate Hash result
|
||||
public signAndSend (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
||||
public signAndSend (account: AddressOrPair, partialOptions?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
||||
|
||||
// signAndSend with a subscription, i.e. callback provided
|
||||
public signAndSend (account: AddressOrPair, statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// signAndSend with options and a callback
|
||||
public signAndSend (account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
public signAndSend (account: AddressOrPair, partialOptions: Partial<SignerOptions>, statusCb?: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// signAndSend implementation for all 3 cases above
|
||||
public signAndSend (account: AddressOrPair, optionsOrStatus?: Partial<SignerOptions> | Callback<ISubmittableResult>, optionalStatusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const [options, statusCb] = this.#makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
|
||||
public signAndSend (account: AddressOrPair, partialOptions?: Partial<SignerOptions> | Callback<ISubmittableResult>, optionalStatusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const [options, statusCb] = makeSignAndSendOptions(partialOptions, optionalStatusCb);
|
||||
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||
@@ -161,61 +212,15 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
return this;
|
||||
}
|
||||
|
||||
#makeEraOptions = (options: Partial<SignerOptions>, { header, mortalLength, nonce }: { header: Header | null; mortalLength: number; nonce: Index }): SignatureOptions => {
|
||||
if (!header) {
|
||||
if (isNumber(options.era)) {
|
||||
// since we have no header, it is immortal, remove any option overrides
|
||||
// so we only supply the genesisHash and no era to the construction
|
||||
delete options.era;
|
||||
delete options.blockHash;
|
||||
}
|
||||
|
||||
return this.#makeSignOptions(options, { nonce });
|
||||
}
|
||||
|
||||
return this.#makeSignOptions(options, {
|
||||
blockHash: header.hash,
|
||||
era: this.registry.createType('ExtrinsicEra', {
|
||||
current: header.number,
|
||||
period: options.era || mortalLength
|
||||
}),
|
||||
nonce
|
||||
});
|
||||
};
|
||||
|
||||
#makeSignOptions = (options: Partial<SignerOptions>, extras: { blockHash?: Hash; era?: ExtrinsicEra; nonce?: Index }): SignatureOptions => {
|
||||
return {
|
||||
blockHash: api.genesisHash,
|
||||
genesisHash: api.genesisHash,
|
||||
...options,
|
||||
...extras,
|
||||
runtimeVersion: api.runtimeVersion,
|
||||
signedExtensions: api.registry.signedExtensions,
|
||||
version: api.extrinsicType
|
||||
} as SignatureOptions;
|
||||
};
|
||||
|
||||
#makeSignAndSendOptions = (optionsOrStatus?: Partial<SignerOptions> | Callback<ISubmittableResult>, statusCb?: Callback<ISubmittableResult>): [Partial<SignerOptions>, Callback<ISubmittableResult>?] => {
|
||||
let options: Partial<SignerOptions> = {};
|
||||
|
||||
if (isFunction(optionsOrStatus)) {
|
||||
statusCb = optionsOrStatus;
|
||||
} else {
|
||||
options = { ...optionsOrStatus };
|
||||
}
|
||||
|
||||
return [options, statusCb];
|
||||
};
|
||||
|
||||
#observeSign = (account: AddressOrPair, optionsOrNonce?: Partial<SignerOptions>): Observable<number | undefined> => {
|
||||
#observeSign = (account: AddressOrPair, partialOptions?: Partial<SignerOptions>): Observable<number | undefined> => {
|
||||
const address = isKeyringPair(account) ? account.address : account.toString();
|
||||
const options = this.#optionsOrNonce(optionsOrNonce);
|
||||
const options = optionsOrNonce(partialOptions);
|
||||
let updateId: number | undefined;
|
||||
|
||||
return api.derive.tx.signingInfo(address, options.nonce, options.era).pipe(
|
||||
first(),
|
||||
mergeMap(async (signingInfo): Promise<void> => {
|
||||
const eraOptions = this.#makeEraOptions(options, signingInfo);
|
||||
const eraOptions = makeEraOptions(api, this.registry, options, signingInfo);
|
||||
|
||||
if (isKeyringPair(account)) {
|
||||
this.sign(account, eraOptions);
|
||||
@@ -229,7 +234,9 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
|
||||
#observeStatus = (hash: Hash, status: ExtrinsicStatus): Observable<ISubmittableResult> => {
|
||||
if (!status.isFinalized && !status.isInBlock) {
|
||||
return of(this.#transformResult(new SubmittableResult({ status })));
|
||||
return of(this.#transformResult(new SubmittableResult({
|
||||
status
|
||||
})));
|
||||
}
|
||||
|
||||
const blockHash = status.isInBlock
|
||||
@@ -244,7 +251,10 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
}))
|
||||
),
|
||||
catchError((internalError: Error) =>
|
||||
of(this.#transformResult(new SubmittableResult({ internalError, status })))
|
||||
of(this.#transformResult(new SubmittableResult({
|
||||
internalError,
|
||||
status
|
||||
})))
|
||||
)
|
||||
);
|
||||
};
|
||||
@@ -270,25 +280,16 @@ export function createClass <ApiType extends ApiTypes> ({ api, apiType, decorate
|
||||
);
|
||||
};
|
||||
|
||||
// NOTE here we actually override nonce if it was specified (backwards compat for
|
||||
// the previous signature - don't let user space break, but allow then time to upgrade)
|
||||
#optionsOrNonce = (optionsOrNonce: Partial<SignerOptions> = {}): Partial<SignerOptions> => {
|
||||
return isBn(optionsOrNonce) || isNumber(optionsOrNonce)
|
||||
? { nonce: optionsOrNonce }
|
||||
: optionsOrNonce;
|
||||
};
|
||||
|
||||
#signViaSigner = async (address: Address | string | Uint8Array, options: SignatureOptions, header: Header | null): Promise<number> => {
|
||||
const signer = options.signer || api.signer;
|
||||
|
||||
assert(signer, 'No signer specified, either via api.setSigner or via sign options. You possibly need to pass through an explicit keypair for the origin so it can be used for signing.');
|
||||
|
||||
const payload = this.registry.createType('SignerPayload', {
|
||||
...options,
|
||||
const payload = this.registry.createType('SignerPayload', objectSpread({}, options, {
|
||||
address,
|
||||
blockNumber: header ? header.number : 0,
|
||||
method: this.method
|
||||
});
|
||||
}));
|
||||
let result: SignerResult;
|
||||
|
||||
if (signer.signPayload) {
|
||||
|
||||
@@ -64,4 +64,5 @@ export interface PaginationOptions<A = unknown> {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export type DecorateMethod<ApiType extends ApiTypes> = <Method extends (...args: any[]) => Observable<any>>(method: Method, options?: DecorateMethodOptions) => any;
|
||||
export type DecorateMethod<ApiType extends ApiTypes, T = any> =
|
||||
<M extends (...args: any[]) => Observable<any>>(method: M, options?: DecorateMethodOptions) => T;
|
||||
|
||||
@@ -95,7 +95,7 @@ export interface ApiInterfaceRx {
|
||||
runtimeMetadata: Metadata;
|
||||
runtimeVersion: RuntimeVersion;
|
||||
query: QueryableStorage<'rxjs'>;
|
||||
queryAt: (blockHash: Uint8Array | string) => Observable<QueryableStorage<'rxjs'>>;
|
||||
queryAt: (blockHash: Uint8Array | string, knownVersion?: RuntimeVersion) => Observable<QueryableStorage<'rxjs'>>;
|
||||
queryMulti: QueryableStorageMulti<'rxjs'>;
|
||||
rpc: DecoratedRpc<'rxjs', RpcInterface>;
|
||||
tx: SubmittableExtrinsics<'rxjs'>;
|
||||
|
||||
@@ -2,23 +2,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { Json, Raw } from '@polkadot/types/codec';
|
||||
import type { AnyFunction, Callback, DefinitionRpc } from '@polkadot/types/types';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { ApiTypes, PromiseResult, Push, RxResult, UnsubscribePromise } from './base';
|
||||
|
||||
export interface RpcRxResult<F extends AnyFunction> extends RxResult<F> {
|
||||
json (...args: Parameters<F>): Observable<Json>;
|
||||
raw (...args: Parameters<F>): Observable<Raw>;
|
||||
raw <T> (...args: Parameters<F>): Observable<T>;
|
||||
meta: DefinitionRpc;
|
||||
}
|
||||
|
||||
export interface RpcPromiseResult<F extends AnyFunction> extends PromiseResult<F> {
|
||||
json (...args: Parameters<F>): Promise<Json>;
|
||||
json (...args: Push<Parameters<F>, Callback<Json>>): UnsubscribePromise;
|
||||
raw (...args: Parameters<F>): Promise<Raw>;
|
||||
raw (...args: Push<Parameters<F>, Callback<Raw>>): UnsubscribePromise;
|
||||
raw <T> (...args: Parameters<F>): Promise<T>;
|
||||
raw <T> (...args: Push<Parameters<F>, Callback<T>>): UnsubscribePromise;
|
||||
meta: DefinitionRpc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
// Copyright 2017-2021 @polkadot/api authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { logger } from '@polkadot/util';
|
||||
import { lazyMethod, logger, objectClear } from '@polkadot/util';
|
||||
|
||||
type Sections <T> = Record<string, Methods<T>>;
|
||||
|
||||
type Methods <T> = Record<string, T>;
|
||||
|
||||
type StringsStrings = [string[], string[]];
|
||||
|
||||
@@ -26,16 +30,17 @@ function warn (prefix: string, type: 'calls' | 'modules', [added, removed]: Stri
|
||||
}
|
||||
}
|
||||
|
||||
function extractKeys (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
|
||||
return [Object.keys(src), Object.keys(dst)];
|
||||
}
|
||||
|
||||
function findSectionExcludes (a: string[], b: string[]): string[] {
|
||||
return a.filter((section) => !b.includes(section));
|
||||
return a.filter((s) => !b.includes(s));
|
||||
}
|
||||
|
||||
function extractSections (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
|
||||
const [srcSections, dstSections] = extractKeys(src, dst);
|
||||
function findSectionIncludes (a: string[], b: string[]): string[] {
|
||||
return a.filter((s) => b.includes(s));
|
||||
}
|
||||
|
||||
function extractSections <T> (src: Sections<T>, dst: Sections<T>): StringsStrings {
|
||||
const srcSections = Object.keys(src);
|
||||
const dstSections = Object.keys(dst);
|
||||
|
||||
return [
|
||||
findSectionExcludes(srcSections, dstSections),
|
||||
@@ -43,64 +48,78 @@ function extractSections (src: Record<string, Record<string, any>>, dst: Record<
|
||||
];
|
||||
}
|
||||
|
||||
function findMethodExcludes (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): string[] {
|
||||
function findMethodExcludes <T> (src: Sections<T>, dst: Sections<T>): string[] {
|
||||
const srcSections = Object.keys(src);
|
||||
const dstSections = Object.keys(dst);
|
||||
const dstSections = findSectionIncludes(Object.keys(dst), srcSections);
|
||||
const excludes: string[] = [];
|
||||
|
||||
return dstSections
|
||||
.filter((section) => srcSections.includes(section))
|
||||
.reduce((rmMethods: string[], section): string[] => {
|
||||
const srcMethods = Object.keys(src[section]);
|
||||
for (let s = 0; s < dstSections.length; s++) {
|
||||
const section = dstSections[s];
|
||||
const srcMethods = Object.keys(src[section]);
|
||||
const dstMethods = Object.keys(dst[section]);
|
||||
|
||||
return rmMethods.concat(
|
||||
...Object
|
||||
.keys(dst[section])
|
||||
.filter((method) => !srcMethods.includes(method))
|
||||
.map((method) => `${section}.${method}`)
|
||||
);
|
||||
}, []);
|
||||
excludes.push(
|
||||
...dstMethods
|
||||
.filter((m) => !srcMethods.includes(m))
|
||||
.map((m) => `${section}.${m}`)
|
||||
);
|
||||
}
|
||||
|
||||
return excludes;
|
||||
}
|
||||
|
||||
function extractMethods (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
|
||||
function extractMethods <T> (src: Sections<T>, dst: Sections<T>): StringsStrings {
|
||||
return [
|
||||
findMethodExcludes(dst, src),
|
||||
findMethodExcludes(src, dst)
|
||||
];
|
||||
}
|
||||
|
||||
function lazySection <T> (src: Methods<T>, dst: Methods<T>): void {
|
||||
const creator = (m: string) => src[m];
|
||||
const methods = Object.keys(src);
|
||||
|
||||
for (let i = 0; i < methods.length; i++) {
|
||||
const method = methods[i];
|
||||
|
||||
// We use hasOwnproperty here to only check for the existence of the key,
|
||||
// instead of reading dst[section][method] which will evaluate when already
|
||||
// set as a lazy value previously
|
||||
if (!Object.prototype.hasOwnProperty.call(dst, method)) {
|
||||
lazyMethod(dst, method, creator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a decorated api section (e.g. api.tx) and augment it with the details. It does not override what is
|
||||
* already available, but rather just adds new missing ites into the result object.
|
||||
* @description Takes a decorated api section (e.g. api.tx) and augment it with the details. It does not override what is
|
||||
* already available, but rather just adds new missing items into the result object.
|
||||
* @internal
|
||||
*/
|
||||
export function augmentObject (prefix: string | null, src: Record<string, Record<string, unknown>>, dst: Record<string, Record<string, unknown>>, fromEmpty = false): Record<string, Record<string, any>> {
|
||||
if (fromEmpty) {
|
||||
Object.keys(dst).forEach((key): void => {
|
||||
delete dst[key];
|
||||
});
|
||||
}
|
||||
export function augmentObject <T> (prefix: string | null, src: Sections<T>, dst: Sections<T>, fromEmpty = false): Sections<T> {
|
||||
fromEmpty && objectClear(dst);
|
||||
|
||||
// NOTE: This part is slightly problematic since it will get the
|
||||
// values for at least all the sections and the names of the methods
|
||||
// (Since methods won't be decorated before lazy, this _may_ be ok)
|
||||
if (prefix && Object.keys(dst).length) {
|
||||
warn(prefix, 'modules', extractSections(src, dst));
|
||||
warn(prefix, 'calls', extractMethods(src, dst));
|
||||
}
|
||||
|
||||
return Object
|
||||
.keys(src)
|
||||
.reduce((newSection, sectionName): Record<string, Record<string, unknown>> => {
|
||||
const section = src[sectionName];
|
||||
const sections = Object.keys(src);
|
||||
|
||||
newSection[sectionName] = Object
|
||||
.keys(section)
|
||||
.reduce((result, methodName): Record<string, unknown> => {
|
||||
// TODO When it does match, check the actual details and warn when there are differences
|
||||
if (!result[methodName]) {
|
||||
result[methodName] = section[methodName];
|
||||
}
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
const section = sections[i];
|
||||
|
||||
return result;
|
||||
}, dst[sectionName] || {});
|
||||
// We don't set here with a lazy interface, we decorate based
|
||||
// on the top-level structure (this bypasses adding lazy onto lazy)
|
||||
if (!dst[section]) {
|
||||
dst[section] = {};
|
||||
}
|
||||
|
||||
return newSection;
|
||||
}, dst);
|
||||
lazySection(src[section], dst[section]);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -4,55 +4,39 @@
|
||||
import type { AnyFunction } from '@polkadot/types/types';
|
||||
import type { ApiTypes, DecorateMethod, MethodResult } from '../types';
|
||||
|
||||
import { lazyDeriveSection } from '@polkadot/api-derive';
|
||||
|
||||
type AnyDeriveSection = Record<string, AnyFunction>;
|
||||
|
||||
// Most generic typings for `api.derive.*.*`
|
||||
type AnyDerive = Record<string, Record<string, AnyFunction>>;
|
||||
type AnyDerive = Record<string, AnyDeriveSection>;
|
||||
|
||||
// Exact typings for a particular section `api.derive.section.*`
|
||||
type DeriveSection<ApiType extends ApiTypes, Section extends Record<string, AnyFunction>> = { [MethodName in keyof Section]: MethodResult<ApiType, Section[MethodName]> };
|
||||
type DeriveSection<ApiType extends ApiTypes, Section extends AnyDeriveSection> = {
|
||||
[MethodName in keyof Section]: MethodResult<ApiType, Section[MethodName]>
|
||||
};
|
||||
|
||||
// Exact typings for all sections `api.derive.*.*`
|
||||
export type DeriveAllSections<ApiType extends ApiTypes, AllSections extends AnyDerive> = { [SectionName in keyof AllSections]: DeriveSection<ApiType, AllSections[SectionName]> };
|
||||
|
||||
// A technically unsafe version of Object.keys(obj) that assumes that
|
||||
// obj only has known properties of T
|
||||
function keys<T extends Record<string, unknown>> (obj: T): (keyof T)[] {
|
||||
return Object.keys(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a methods decorator which keeps all type information.
|
||||
*/
|
||||
function decorateMethods<ApiType extends ApiTypes, Section extends Record<string, AnyFunction>> (section: Section, decorateMethod: DecorateMethod<ApiType>): DeriveSection<ApiType, Section> {
|
||||
return keys(section).reduce(
|
||||
<MethodName extends keyof Section>(
|
||||
acc: DeriveSection<ApiType, Section>,
|
||||
methodName: MethodName
|
||||
): DeriveSection<ApiType, Section> => {
|
||||
const method = section[methodName];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
acc[methodName] = decorateMethod(method) as MethodResult<ApiType, Section[MethodName]>;
|
||||
|
||||
return acc;
|
||||
},
|
||||
{} as DeriveSection<ApiType, Section>
|
||||
);
|
||||
}
|
||||
export type DeriveAllSections<ApiType extends ApiTypes, AllSections extends AnyDerive> = {
|
||||
[SectionName in keyof AllSections]: DeriveSection<ApiType, AllSections[SectionName]>
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a section decorator which keeps all type information.
|
||||
*/
|
||||
export function decorateSections<ApiType extends ApiTypes, AllSections extends AnyDerive> (
|
||||
allSections: AllSections,
|
||||
decorateMethod: DecorateMethod<ApiType>
|
||||
): DeriveAllSections<ApiType, AllSections> {
|
||||
return keys(allSections).reduce(
|
||||
<MethodName extends keyof AllSections>(
|
||||
acc: DeriveAllSections<ApiType, AllSections>,
|
||||
sectionName: MethodName
|
||||
): DeriveAllSections<ApiType, AllSections> => {
|
||||
acc[sectionName] = decorateMethods(allSections[sectionName], decorateMethod);
|
||||
export function decorateDeriveSections<ApiType extends ApiTypes, A extends AnyDerive> (decorateMethod: DecorateMethod<ApiType>, derives: AnyDerive): DeriveAllSections<ApiType, A> {
|
||||
const getKeys = (s: string) =>
|
||||
Object.keys(derives[s]);
|
||||
|
||||
return acc;
|
||||
},
|
||||
{} as DeriveAllSections<ApiType, AllSections>
|
||||
);
|
||||
const creator = (s: string, m: string) =>
|
||||
decorateMethod(derives[s][m]) as AnyFunction;
|
||||
|
||||
const result: AnyDerive = {};
|
||||
const names = Object.keys(derives);
|
||||
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
lazyDeriveSection(result, names[i], getKeys, creator);
|
||||
}
|
||||
|
||||
return result as DeriveAllSections<ApiType, A>;
|
||||
}
|
||||
|
||||
@@ -7,24 +7,22 @@ import { l } from './logging';
|
||||
|
||||
export function filterEvents (extHash: H256, { block: { extrinsics, header } }: SignedBlock, allEvents: EventRecord[], status: ExtrinsicStatus): EventRecord[] | undefined {
|
||||
// extrinsics to hashes
|
||||
const myHash = extHash.toHex();
|
||||
const allHashes = extrinsics.map((ext): string => ext.hash.toHex());
|
||||
|
||||
// find the index of our extrinsic in the block
|
||||
const index = allHashes.indexOf(myHash);
|
||||
|
||||
// if we do get the block after finalized, it _should_ be there
|
||||
if (index === -1) {
|
||||
// only warn on filtering with isInBlock (finalization finalizes after)
|
||||
if (status.isInBlock) {
|
||||
l.warn(`block ${header.hash.toHex()}: Unable to find extrinsic ${myHash} inside ${allHashes.join(', ')}`);
|
||||
for (const [index, extrinsic] of extrinsics.entries()) {
|
||||
if (extrinsic.hash.eq(extHash)) {
|
||||
return allEvents.filter(({ phase }) =>
|
||||
// only ApplyExtrinsic has the extrinsic index
|
||||
phase.isApplyExtrinsic && phase.asApplyExtrinsic.eqn(index)
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return allEvents.filter(({ phase }) =>
|
||||
// only ApplyExtrinsic has the extrinsic index
|
||||
phase.isApplyExtrinsic && phase.asApplyExtrinsic.eqn(index)
|
||||
);
|
||||
// if we do get the block after finalized, it _should_ be there
|
||||
// only warn on filtering with isInBlock (finalization finalizes after)
|
||||
if (status.isInBlock) {
|
||||
const allHashes = extrinsics.map((ext): string => ext.hash.toHex());
|
||||
|
||||
l.warn(`block ${header.hash.toHex()}: Unable to find extrinsic ${extHash.toHex()} inside ${allHashes.join(', ')}`);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,31 +1,35 @@
|
||||
{
|
||||
"name": "@polkadot/rpc-core",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "A JavaScript wrapper for the Polkadot JsonRPC interface",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-core#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/rpc-core",
|
||||
"repository": {
|
||||
"directory": "packages/rpc-core",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-core#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/rpc-provider": "6.4.2",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"@polkadot/util": "^7.5.1",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/rpc-provider": "6.8.1",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"@polkadot/util": "^7.8.2",
|
||||
"rxjs": "^7.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^7.5.1"
|
||||
"@polkadot/keyring": "^7.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ import type { StorageKey, Vec } from '@polkadot/types';
|
||||
import type { Hash } from '@polkadot/types/interfaces';
|
||||
import type { AnyJson, Codec, DefinitionRpc, DefinitionRpcExt, DefinitionRpcSub, Registry } from '@polkadot/types/types';
|
||||
import type { Memoized } from '@polkadot/util/types';
|
||||
import type { RpcInterface, RpcInterfaceMethod } from './types';
|
||||
import type { RpcInterfaceMethod } from './types';
|
||||
|
||||
import { Observable, publishReplay, refCount } from 'rxjs';
|
||||
|
||||
import { rpcDefinitions } from '@polkadot/types';
|
||||
import { assert, hexToU8a, isFunction, isNull, isUndefined, logger, memoize, u8aToU8a } from '@polkadot/util';
|
||||
import { assert, hexToU8a, isFunction, isNull, isUndefined, lazyMethod, logger, memoize, objectSpread, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { drr, refCountDelay } from './util';
|
||||
|
||||
@@ -24,8 +24,6 @@ interface StorageChangeSetJSON {
|
||||
changes: [string, string | null][];
|
||||
}
|
||||
|
||||
type OutputType = 'json' | 'raw' | 'scale';
|
||||
|
||||
const l = logger('rpc-core');
|
||||
|
||||
const EMPTY_META = {
|
||||
@@ -143,84 +141,79 @@ export class RpcCore {
|
||||
});
|
||||
}
|
||||
|
||||
public addUserInterfaces<Section extends keyof RpcInterface> (userRpc: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>>): void {
|
||||
public addUserInterfaces (userRpc: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>>): void {
|
||||
// add any extra user-defined sections
|
||||
this.sections.push(...Object.keys(userRpc).filter((key) => !this.sections.includes(key)));
|
||||
this.sections.push(...Object.keys(userRpc).filter((k) => !this.sections.includes(k)));
|
||||
|
||||
// decorate the sections with base and user methods
|
||||
this.sections.forEach((sectionName): void => {
|
||||
(this as Record<string, unknown>)[sectionName as Section] ||= {};
|
||||
for (let s = 0; s < this.sections.length; s++) {
|
||||
const section = this.sections[s];
|
||||
const defs = objectSpread<Record<string, DefinitionRpc | DefinitionRpcSub>>({}, rpcDefinitions[section as 'babe'], userRpc[section]);
|
||||
const methods = Object.keys(defs);
|
||||
|
||||
const section = (this as Record<string, unknown>)[sectionName as Section] as Record<string, unknown>;
|
||||
for (let m = 0; m < methods.length; m++) {
|
||||
const method = methods[m];
|
||||
const def = defs[method];
|
||||
const jsonrpc = def.endpoint || `${section}_${method}`;
|
||||
|
||||
Object
|
||||
.entries({
|
||||
...this._createInterface(sectionName, rpcDefinitions[sectionName as 'babe'] || {}),
|
||||
...this._createInterface(sectionName, userRpc[sectionName] || {})
|
||||
})
|
||||
.forEach(([key, value]): void => {
|
||||
section[key] ||= value;
|
||||
});
|
||||
});
|
||||
if (!this.mapping.has(jsonrpc)) {
|
||||
const isSubscription = !!(def as DefinitionRpcSub).pubsub;
|
||||
|
||||
if (!(this as Record<string, unknown>)[section]) {
|
||||
(this as Record<string, unknown>)[section] = {};
|
||||
}
|
||||
|
||||
this.mapping.set(jsonrpc, objectSpread({}, def, { isSubscription, jsonrpc, method, section }));
|
||||
|
||||
lazyMethod(this[section as 'connect'], method, () =>
|
||||
isSubscription
|
||||
? this._createMethodSubscribe(section, method, def as DefinitionRpcSub)
|
||||
: this._createMethodSend(section, method, def)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _createInterface<Section extends keyof RpcInterface> (section: string, methods: Record<string, DefinitionRpc | DefinitionRpcSub>): RpcInterface[Section] {
|
||||
return Object
|
||||
.entries(methods)
|
||||
.filter(([method, { endpoint }]) => !this.mapping.has(endpoint || `${section}_${method}`))
|
||||
.reduce((exposed, [method, { endpoint }]): RpcInterface[Section] => {
|
||||
const def = methods[method];
|
||||
const isSubscription = !!(def as DefinitionRpcSub).pubsub;
|
||||
const jsonrpc = endpoint || `${section}_${method}`;
|
||||
private _memomize (creator: <T> (isScale: boolean) => (...values: unknown[]) => Observable<T>, def: DefinitionRpc): Memoized<RpcInterfaceMethod> {
|
||||
const memoOpts = { getInstanceId: () => this.#instanceId };
|
||||
const memoized = memoize(creator(true) as RpcInterfaceMethod, memoOpts);
|
||||
|
||||
this.mapping.set(jsonrpc, { ...def, isSubscription, jsonrpc, method, section });
|
||||
|
||||
(exposed as Record<string, unknown>)[method] = isSubscription
|
||||
? this._createMethodSubscribe(section, method, def as DefinitionRpcSub)
|
||||
: this._createMethodSend(section, method, def);
|
||||
|
||||
return exposed;
|
||||
}, {} as RpcInterface[Section]);
|
||||
}
|
||||
|
||||
private _memomize (creator: <T> (outputAs: OutputType) => (...values: unknown[]) => Observable<T>, def: DefinitionRpc): Memoized<RpcInterfaceMethod> {
|
||||
const memoized = memoize(creator('scale') as RpcInterfaceMethod, {
|
||||
getInstanceId: () => this.#instanceId
|
||||
});
|
||||
|
||||
memoized.json = creator('json');
|
||||
memoized.raw = creator('raw');
|
||||
memoized.raw = memoize(creator(false), memoOpts);
|
||||
memoized.meta = def;
|
||||
|
||||
return memoized;
|
||||
}
|
||||
|
||||
private _formatResult <T> (isScale: boolean, registry: Registry, blockHash: string | Uint8Array | null | undefined, method: string, def: DefinitionRpc, params: Codec[], result: unknown): T {
|
||||
return isScale
|
||||
? this._formatOutput(registry, blockHash, method, def, params, result) as unknown as T
|
||||
: result as T;
|
||||
}
|
||||
|
||||
private _createMethodSend (section: string, method: string, def: DefinitionRpc): RpcInterfaceMethod {
|
||||
const rpcName = def.endpoint || `${section}_${method}`;
|
||||
const hashIndex = def.params.findIndex(({ isHistoric }) => isHistoric);
|
||||
let memoized: null | Memoized<RpcInterfaceMethod> = null;
|
||||
|
||||
// execute the RPC call, doing a registry swap for historic as applicable
|
||||
const callWithRegistry = async <T> (outputAs: OutputType, values: unknown[]): Promise<T> => {
|
||||
const callWithRegistry = async <T> (isScale: boolean, values: unknown[]): Promise<T> => {
|
||||
const blockHash = hashIndex === -1
|
||||
? null
|
||||
: values[hashIndex] as (Uint8Array | string | null | undefined);
|
||||
const { registry } = outputAs === 'scale' && blockHash && this.#getBlockRegistry
|
||||
const { registry } = isScale && blockHash && this.#getBlockRegistry
|
||||
? await this.#getBlockRegistry(u8aToU8a(blockHash))
|
||||
: { registry: this.#registryDefault };
|
||||
const params = this._formatInputs(registry, null, def, values);
|
||||
const data = await this.provider.send<AnyJson>(rpcName, params.map((param) => param.toJSON()));
|
||||
const result = await this.provider.send<AnyJson>(rpcName, params.map((p) => p.toJSON()), !!blockHash);
|
||||
|
||||
return outputAs === 'scale'
|
||||
? this._formatOutput(registry, blockHash, method, def, params, data) as unknown as T
|
||||
: registry.createType(outputAs === 'raw' ? 'Raw' : 'Json', data) as unknown as T;
|
||||
return this._formatResult(isScale, registry, blockHash, method, def, params, result);
|
||||
};
|
||||
|
||||
const creator = <T> (outputAs: OutputType) => (...values: unknown[]): Observable<T> => {
|
||||
const isDelayed = outputAs === 'scale' && hashIndex !== -1 && !!values[hashIndex];
|
||||
const creator = <T> (isScale: boolean) => (...values: unknown[]): Observable<T> => {
|
||||
const isDelayed = isScale && hashIndex !== -1 && !!values[hashIndex];
|
||||
|
||||
return new Observable((observer: Observer<T>): VoidCallback => {
|
||||
callWithRegistry<T>(outputAs, values)
|
||||
callWithRegistry<T>(isScale, values)
|
||||
.then((value): void => {
|
||||
observer.next(value);
|
||||
observer.complete();
|
||||
@@ -269,7 +262,7 @@ export class RpcCore {
|
||||
const subType = `${section}_${updateType}`;
|
||||
let memoized: null | Memoized<RpcInterfaceMethod> = null;
|
||||
|
||||
const creator = <T> (outputAs: OutputType) => (...values: unknown[]): Observable<T> => {
|
||||
const creator = <T> (isScale: boolean) => (...values: unknown[]): Observable<T> => {
|
||||
return new Observable((observer: Observer<T>): VoidCallback => {
|
||||
// Have at least an empty promise, as used in the unsubscribe
|
||||
let subscriptionPromise: Promise<number | string | null> = Promise.resolve(null);
|
||||
@@ -283,9 +276,9 @@ export class RpcCore {
|
||||
|
||||
try {
|
||||
const params = this._formatInputs(registry, null, def, values);
|
||||
const paramsJson = params.map((param) => param.toJSON());
|
||||
const paramsJson = params.map((p) => p.toJSON());
|
||||
|
||||
const update = (error?: Error | null, result?: T): void => {
|
||||
const update = (error?: Error | null, result?: unknown): void => {
|
||||
if (error) {
|
||||
logErrorMessage(method, def, error);
|
||||
|
||||
@@ -293,11 +286,7 @@ export class RpcCore {
|
||||
}
|
||||
|
||||
try {
|
||||
observer.next(
|
||||
outputAs === 'scale'
|
||||
? this._formatOutput(registry, null, method, def, params, result) as unknown as T
|
||||
: registry.createType(outputAs === 'raw' ? 'Raw' : 'Json', result) as unknown as T
|
||||
);
|
||||
observer.next(this._formatResult(isScale, registry, null, method, def, params, result));
|
||||
} catch (error) {
|
||||
observer.error(error);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ describe('methodSend', (): void => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||
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'], false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/rpc-core', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/rpc-core', version: '6.8.1' };
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
// Copyright 2017-2021 @polkadot/rpc-core authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { RpcInterface } from '@polkadot/rpc-core/types.jsonrpc';
|
||||
|
||||
import { of } from 'rxjs';
|
||||
|
||||
import { MockProvider } from '@polkadot/rpc-provider/mock';
|
||||
import { TypeRegistry } from '@polkadot/types/create';
|
||||
|
||||
@@ -25,21 +22,6 @@ describe('replay', (): void => {
|
||||
await provider.disconnect();
|
||||
});
|
||||
|
||||
it('subscribes via the rpc section', (done): void => {
|
||||
// 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));
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
||||
(rpc.chain as any).getBlockHash(123, false).subscribe((): void => {
|
||||
expect(
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
rpc.chain.getBlockHash
|
||||
).toHaveBeenCalledWith(123, false);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the observable value', (done): void => {
|
||||
rpc.system.chain().subscribe((value: any): void => {
|
||||
if (value) {
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
|
||||
// FIXME, this whole file needs to move to API
|
||||
|
||||
import type { AnyFunction } from '@polkadot/types/types';
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { AnyFunction, DefinitionRpc } from '@polkadot/types/types';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface RpcInterface {}
|
||||
|
||||
export type AugmentedRpc<F extends AnyFunction> = F;
|
||||
export type AugmentedRpc<F extends AnyFunction> = F & {
|
||||
raw: <T> (...params: Parameters<F>) => Observable<T>;
|
||||
meta: DefinitionRpc;
|
||||
};
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { Json, Raw } from '@polkadot/types';
|
||||
import type { Codec, DefinitionRpc } from '@polkadot/types/types';
|
||||
|
||||
export * from './types.jsonrpc';
|
||||
|
||||
export interface RpcInterfaceMethod {
|
||||
<T extends Codec> (...params: unknown[]): Observable<T>;
|
||||
json (...params: unknown[]): Observable<Json>;
|
||||
raw (...params: unknown[]): Observable<Raw>;
|
||||
raw (...params: unknown[]): Observable<unknown>;
|
||||
meta: DefinitionRpc;
|
||||
}
|
||||
|
||||
@@ -1,37 +1,41 @@
|
||||
{
|
||||
"name": "@polkadot/rpc-provider",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Transport providers for the API",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/rpc-provider",
|
||||
"repository": {
|
||||
"directory": "packages/rpc-provider",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/rpc-provider#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"@polkadot/util": "^7.5.1",
|
||||
"@polkadot/util-crypto": "^7.5.1",
|
||||
"@polkadot/x-fetch": "^7.5.1",
|
||||
"@polkadot/x-global": "^7.5.1",
|
||||
"@polkadot/x-ws": "^7.5.1",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"@polkadot/util": "^7.8.2",
|
||||
"@polkadot/util-crypto": "^7.8.2",
|
||||
"@polkadot/x-fetch": "^7.8.2",
|
||||
"@polkadot/x-global": "^7.8.2",
|
||||
"@polkadot/x-ws": "^7.8.2",
|
||||
"eventemitter3": "^4.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^7.5.1",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"mock-socket": "^9.0.5",
|
||||
"nock": "^13.1.3"
|
||||
"@polkadot/keyring": "^7.8.2",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"mock-socket": "^9.0.7",
|
||||
"nock": "^13.1.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { fetch } from '@polkadot/x-fetch';
|
||||
|
||||
import { RpcCoder } from '../coder';
|
||||
import defaults from '../defaults';
|
||||
import { LRUCache } from '../lru';
|
||||
|
||||
const ERROR_SUBSCRIBE = 'HTTP Provider does not have subscriptions, use WebSockets instead';
|
||||
|
||||
@@ -34,6 +35,8 @@ const l = logger('api-http');
|
||||
* @see [[WsProvider]]
|
||||
*/
|
||||
export class HttpProvider implements ProviderInterface {
|
||||
readonly #callCache = new LRUCache();
|
||||
|
||||
readonly #coder: RpcCoder;
|
||||
|
||||
readonly #endpoint: string;
|
||||
@@ -103,8 +106,24 @@ export class HttpProvider implements ProviderInterface {
|
||||
/**
|
||||
* @summary Send HTTP POST Request with Body to configured HTTP Endpoint.
|
||||
*/
|
||||
public async send <T> (method: string, params: unknown[]): Promise<T> {
|
||||
public async send <T> (method: string, params: unknown[], isCacheable?: boolean): Promise<T> {
|
||||
const body = this.#coder.encodeJson(method, params);
|
||||
let resultPromise: Promise<T> | null = isCacheable
|
||||
? this.#callCache.get(body) as Promise<T>
|
||||
: null;
|
||||
|
||||
if (!resultPromise) {
|
||||
resultPromise = this.#send(body);
|
||||
|
||||
if (isCacheable) {
|
||||
this.#callCache.set(body, resultPromise);
|
||||
}
|
||||
}
|
||||
|
||||
return resultPromise;
|
||||
}
|
||||
|
||||
async #send <T> (body: string): Promise<T> {
|
||||
const response = await fetch(this.#endpoint, {
|
||||
body,
|
||||
headers: {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2017-2021 @polkadot/rpc-provider authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { LRUCache } from './lru';
|
||||
|
||||
describe('LRUCache', (): void => {
|
||||
it('allows getting of items below capacity', (): void => {
|
||||
const keys = ['1', '2', '3', '4'];
|
||||
const lru = new LRUCache(4);
|
||||
|
||||
keys.forEach((k) => lru.set(k, `${k}${k}${k}`));
|
||||
|
||||
expect(lru.keys().join(', ')).toEqual(keys.reverse().join(', '));
|
||||
expect(lru.length === lru.lengthData && lru.length === lru.lengthRefs).toBe(true);
|
||||
|
||||
keys.forEach((k) => expect(lru.get(k)).toEqual(`${k}${k}${k}`));
|
||||
});
|
||||
|
||||
it('drops items when at capacity', (): void => {
|
||||
const keys = ['1', '2', '3', '4', '5', '6'];
|
||||
const lru = new LRUCache(4);
|
||||
|
||||
keys.forEach((k) => lru.set(k, `${k}${k}${k}`));
|
||||
|
||||
expect(lru.keys().join(', ')).toEqual(keys.slice(2).reverse().join(', '));
|
||||
expect(lru.length === lru.lengthData && lru.length === lru.lengthRefs).toBe(true);
|
||||
|
||||
keys.slice(2).forEach((k) => expect(lru.get(k)).toEqual(`${k}${k}${k}`));
|
||||
});
|
||||
|
||||
it('adjusts the order as they are used', (): void => {
|
||||
const keys = ['1', '2', '3', '4', '5'];
|
||||
const lru = new LRUCache(4);
|
||||
|
||||
keys.forEach((k) => lru.set(k, `${k}${k}${k}`));
|
||||
|
||||
expect(lru.entries()).toEqual([['5', '555'], ['4', '444'], ['3', '333'], ['2', '222']]);
|
||||
expect(lru.length === lru.lengthData && lru.length === lru.lengthRefs).toBe(true);
|
||||
|
||||
lru.get('3');
|
||||
|
||||
expect(lru.entries()).toEqual([['3', '333'], ['5', '555'], ['4', '444'], ['2', '222']]);
|
||||
expect(lru.length === lru.lengthData && lru.length === lru.lengthRefs).toBe(true);
|
||||
|
||||
lru.set('4', '4433');
|
||||
|
||||
expect(lru.entries()).toEqual([['4', '4433'], ['3', '333'], ['5', '555'], ['2', '222']]);
|
||||
expect(lru.length === lru.lengthData && lru.length === lru.lengthRefs).toBe(true);
|
||||
|
||||
lru.set('6', '666');
|
||||
|
||||
expect(lru.entries()).toEqual([['6', '666'], ['4', '4433'], ['3', '333'], ['5', '555']]);
|
||||
expect(lru.length === lru.lengthData && lru.length === lru.lengthRefs).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright 2017-2021 @polkadot/rpc-provider authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
const DEFAULT_CAPACITY = 2048;
|
||||
|
||||
class LRUNode {
|
||||
public readonly key: string;
|
||||
|
||||
public next: LRUNode;
|
||||
public prev: LRUNode;
|
||||
|
||||
constructor (key: string) {
|
||||
this.key = key;
|
||||
this.next = this.prev = this;
|
||||
}
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU
|
||||
export class LRUCache {
|
||||
readonly capacity: number;
|
||||
readonly #data: Map<string, unknown> = new Map();
|
||||
readonly #refs: Map<string, LRUNode> = new Map();
|
||||
|
||||
#length = 0;
|
||||
#head: LRUNode;
|
||||
#tail: LRUNode;
|
||||
|
||||
constructor (capacity = DEFAULT_CAPACITY) {
|
||||
this.capacity = capacity;
|
||||
this.#head = this.#tail = new LRUNode('<empty>');
|
||||
}
|
||||
|
||||
get length (): number {
|
||||
return this.#length;
|
||||
}
|
||||
|
||||
get lengthData (): number {
|
||||
return this.#data.size;
|
||||
}
|
||||
|
||||
get lengthRefs (): number {
|
||||
return this.#refs.size;
|
||||
}
|
||||
|
||||
entries (): [string, unknown][] {
|
||||
const keys = this.keys();
|
||||
const entries = new Array<[string, unknown]>(keys.length);
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
|
||||
entries[i] = [key, this.#data.get(key)];
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
keys (): string[] {
|
||||
const keys: string[] = [];
|
||||
|
||||
if (this.#length) {
|
||||
let curr = this.#head;
|
||||
|
||||
while (curr !== this.#tail) {
|
||||
keys.push(curr.key);
|
||||
curr = curr.next;
|
||||
}
|
||||
|
||||
keys.push(curr.key);
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
get <T> (key: string): T | null {
|
||||
const data = this.#data.get(key);
|
||||
|
||||
if (data) {
|
||||
this.#toHead(key);
|
||||
|
||||
return data as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
set <T> (key: string, value: T): void {
|
||||
if (this.#data.has(key)) {
|
||||
this.#toHead(key);
|
||||
} else {
|
||||
const node = new LRUNode(key);
|
||||
|
||||
this.#refs.set(node.key, node);
|
||||
|
||||
if (this.length === 0) {
|
||||
this.#head = this.#tail = node;
|
||||
} else {
|
||||
this.#head.prev = node;
|
||||
node.next = this.#head;
|
||||
this.#head = node;
|
||||
}
|
||||
|
||||
if (this.#length === this.capacity) {
|
||||
this.#data.delete(this.#tail.key);
|
||||
this.#refs.delete(this.#tail.key);
|
||||
|
||||
this.#tail = this.#tail.prev;
|
||||
} else {
|
||||
this.#length += 1;
|
||||
}
|
||||
}
|
||||
|
||||
this.#data.set(key, value);
|
||||
}
|
||||
|
||||
#toHead (key: string): void {
|
||||
const ref = this.#refs.get(key);
|
||||
|
||||
if (ref && ref !== this.#head) {
|
||||
ref.prev.next = ref.next;
|
||||
ref.next.prev = ref.prev;
|
||||
ref.next = this.#head;
|
||||
|
||||
this.#head.prev = ref;
|
||||
this.#head = ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/rpc-provider', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/rpc-provider', version: '6.8.1' };
|
||||
|
||||
@@ -49,7 +49,7 @@ export interface ProviderInterface {
|
||||
connect (): Promise<void>;
|
||||
disconnect (): Promise<void>;
|
||||
on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void;
|
||||
send <T = any> (method: string, params: unknown[]): Promise<T>;
|
||||
send <T = any> (method: string, params: unknown[], isCacheable?: boolean): Promise<T>;
|
||||
subscribe (type: string, method: string, params: unknown[], cb: ProviderInterfaceCallback): Promise<number | string>;
|
||||
unsubscribe (type: string, method: string, id: number | string): Promise<boolean>;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,13 @@ import type { JsonRpcResponse, ProviderInterface, ProviderInterfaceCallback, Pro
|
||||
|
||||
import EventEmitter from 'eventemitter3';
|
||||
|
||||
import { assert, isChildClass, isNull, isUndefined, logger } from '@polkadot/util';
|
||||
import { assert, isChildClass, isNull, isUndefined, logger, objectSpread } from '@polkadot/util';
|
||||
import { xglobal } from '@polkadot/x-global';
|
||||
import { WebSocket } from '@polkadot/x-ws';
|
||||
|
||||
import { RpcCoder } from '../coder';
|
||||
import defaults from '../defaults';
|
||||
import { LRUCache } from '../lru';
|
||||
import { getWSErrorString } from './errors';
|
||||
|
||||
interface SubscriptionHandler {
|
||||
@@ -40,6 +41,8 @@ const ALIASES: { [index: string]: string } = {
|
||||
|
||||
const RETRY_DELAY = 2500;
|
||||
|
||||
const MEGABYTE = 1024 * 1024;
|
||||
|
||||
const l = logger('api-ws');
|
||||
|
||||
function eraseRecord<T> (record: Record<string, T>, cb?: (item: T) => void): void {
|
||||
@@ -73,6 +76,8 @@ function eraseRecord<T> (record: Record<string, T>, cb?: (item: T) => void): voi
|
||||
* @see [[HttpProvider]]
|
||||
*/
|
||||
export class WsProvider implements ProviderInterface {
|
||||
readonly #callCache = new LRUCache();
|
||||
|
||||
readonly #coder: RpcCoder;
|
||||
|
||||
readonly #endpoints: string[];
|
||||
@@ -179,9 +184,11 @@ export class WsProvider implements ProviderInterface {
|
||||
// default: true
|
||||
fragmentOutgoingMessages: true,
|
||||
// default: 16K (bump, the Node has issues with too many fragments, e.g. on setCode)
|
||||
fragmentationThreshold: 256 * 1024,
|
||||
// default: 8MB (however Polkadot api.query.staking.erasStakers.entries(356) is over that)
|
||||
maxReceivedMessageSize: 16 * 1024 * 1024
|
||||
fragmentationThreshold: 1 * MEGABYTE,
|
||||
// default: 1MiB (also align with maxReceivedMessageSize)
|
||||
maxReceivedFrameSize: 24 * MEGABYTE,
|
||||
// default: 8MB (however Polkadot api.query.staking.erasStakers.entries(356) is over that, 16M is ok there)
|
||||
maxReceivedMessageSize: 24 * MEGABYTE
|
||||
});
|
||||
|
||||
this.#websocket.onclose = this.#onSocketClose;
|
||||
@@ -256,12 +263,28 @@ export class WsProvider implements ProviderInterface {
|
||||
* @param params Encoded parameters as applicable for the method
|
||||
* @param subscription Subscription details (internally used)
|
||||
*/
|
||||
public send <T = any> (method: string, params: unknown[], subscription?: SubscriptionHandler): Promise<T> {
|
||||
public send <T = any> (method: string, params: unknown[], isCacheable?: boolean, subscription?: SubscriptionHandler): Promise<T> {
|
||||
const body = this.#coder.encodeJson(method, params);
|
||||
let resultPromise: Promise<T> | null = isCacheable
|
||||
? this.#callCache.get(body) as Promise<T>
|
||||
: null;
|
||||
|
||||
if (!resultPromise) {
|
||||
resultPromise = this.#send(body, method, params, subscription);
|
||||
|
||||
if (isCacheable) {
|
||||
this.#callCache.set(body, resultPromise);
|
||||
}
|
||||
}
|
||||
|
||||
return resultPromise;
|
||||
}
|
||||
|
||||
async #send <T> (json: string, method: string, params: unknown[], subscription?: SubscriptionHandler): Promise<T> {
|
||||
return new Promise<T>((resolve, reject): void => {
|
||||
try {
|
||||
assert(this.isConnected && !isNull(this.#websocket), 'WebSocket is not connected');
|
||||
|
||||
const json = this.#coder.encodeJson(method, params);
|
||||
const id = this.#coder.getId();
|
||||
|
||||
const callback = (error?: Error | null, result?: T): void => {
|
||||
@@ -305,7 +328,7 @@ export class WsProvider implements ProviderInterface {
|
||||
* ```
|
||||
*/
|
||||
public subscribe (type: string, method: string, params: unknown[], callback: ProviderInterfaceCallback): Promise<number | string> {
|
||||
return this.send<number | string>(method, params, { callback, type });
|
||||
return this.send<number | string>(method, params, false, { callback, type });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,11 +429,10 @@ export class WsProvider implements ProviderInterface {
|
||||
if (subscription) {
|
||||
const subId = `${subscription.type}::${result}`;
|
||||
|
||||
this.#subscriptions[subId] = {
|
||||
...subscription,
|
||||
this.#subscriptions[subId] = objectSpread({}, subscription, {
|
||||
method,
|
||||
params
|
||||
};
|
||||
});
|
||||
|
||||
// if we have a result waiting for this subscription already
|
||||
if (this.#waitingForId[subId]) {
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
{
|
||||
"name": "@polkadot/typegen",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Type generation scripts",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/typegen#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/typegen",
|
||||
"repository": {
|
||||
"directory": "packages/typegen",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"polkadot-types-chain-info": "./scripts/polkadot-types-chain-info.cjs",
|
||||
"polkadot-types-from-chain": "./scripts/polkadot-types-from-chain.cjs",
|
||||
@@ -18,28 +29,21 @@
|
||||
"polkadot-types-internal-interfaces": "./scripts/polkadot-types-internal-interfaces.cjs",
|
||||
"polkadot-types-internal-metadata": "./scripts/polkadot-types-internal-metadata.cjs"
|
||||
},
|
||||
"repository": "github:polkadot-js/api",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/typegen#readme",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.15.8",
|
||||
"@babel/register": "^7.15.3",
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/api": "6.4.2",
|
||||
"@polkadot/rpc-provider": "6.4.2",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"@polkadot/types-support": "6.4.2",
|
||||
"@polkadot/util": "^7.5.1",
|
||||
"@babel/core": "^7.16.0",
|
||||
"@babel/register": "^7.16.0",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/api": "6.8.1",
|
||||
"@polkadot/rpc-provider": "6.8.1",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"@polkadot/types-support": "6.8.1",
|
||||
"@polkadot/util": "^7.8.2",
|
||||
"handlebars": "^4.7.7",
|
||||
"websocket": "^1.0.34",
|
||||
"yargs": "^17.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/websocket": "^1.0.4",
|
||||
"@types/yargs": "^17.0.4"
|
||||
"@types/yargs": "^17.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright 2017-2021 @polkadot/typegen authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { PortableRegistry, PortableType, SiLookupTypeId, SiPath, SiTypeParameter } from '@polkadot/types/interfaces';
|
||||
import type { PortableType, SiLookupTypeId, SiPath, SiTypeParameter } from '@polkadot/types/interfaces';
|
||||
import type { PortableRegistry } from '@polkadot/types/metadata';
|
||||
import type { TypeDef } from '@polkadot/types/types';
|
||||
|
||||
import Handlebars from 'handlebars';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2017-2021 @polkadot/typegen authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { PortableRegistry, StorageEntryMetadataLatest } from '@polkadot/types/interfaces/metadata';
|
||||
import type { Metadata } from '@polkadot/types/metadata/Metadata';
|
||||
import type { StorageEntryMetadataLatest } from '@polkadot/types/interfaces';
|
||||
import type { Metadata, PortableRegistry } from '@polkadot/types/metadata';
|
||||
import type { Registry } from '@polkadot/types/types';
|
||||
import type { ExtraTypes } from './types';
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright 2017-2021 @polkadot/typegen authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { MetadataLatest, PortableRegistry, SiLookupTypeId } from '@polkadot/types/interfaces';
|
||||
import type { MetadataLatest, SiLookupTypeId } from '@polkadot/types/interfaces';
|
||||
import type { PortableRegistry } from '@polkadot/types/metadata';
|
||||
import type { Codec, DefinitionRpcParam } from '@polkadot/types/types';
|
||||
|
||||
import fs from 'fs';
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/typegen', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/typegen', version: '6.8.1' };
|
||||
|
||||
@@ -44,7 +44,7 @@ export function setImports (allDefs: Record<string, ModuleTypes>, imports: TypeI
|
||||
// do nothing
|
||||
} else if (['AnyNumber', 'CallFunction', 'Codec', 'IExtrinsic', 'ITuple'].includes(type)) {
|
||||
typesTypes[type] = true;
|
||||
} else if (type === 'Metadata') {
|
||||
} else if (['Metadata', 'PortableRegistry'].includes(type)) {
|
||||
metadataTypes[type] = true;
|
||||
} else if ((codecClasses as Record<string, unknown>)[type]) {
|
||||
codecTypes[type] = true;
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
{
|
||||
"name": "@polkadot/types-known",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Known type definitions",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types-known#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/types-known",
|
||||
"repository": {
|
||||
"directory": "packages/types-known",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types-known#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/networks": "^7.5.1",
|
||||
"@polkadot/types": "6.4.2",
|
||||
"@polkadot/util": "^7.5.1"
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/networks": "^7.8.2",
|
||||
"@polkadot/types": "6.8.1",
|
||||
"@polkadot/util": "^7.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { Hash } from '@polkadot/types/interfaces';
|
||||
import type { ChainUpgradeVersion, CodecHasher, DefinitionRpc, DefinitionRpcSub, OverrideModuleType, OverrideVersionedType, Registry, RegistryTypes } from '@polkadot/types/types';
|
||||
import type { BN } from '@polkadot/util';
|
||||
|
||||
import { bnToBn, isNull, isUndefined } from '@polkadot/util';
|
||||
import { bnToBn, isNull, isUndefined, objectSpread } from '@polkadot/util';
|
||||
|
||||
import typesChain from './chain';
|
||||
import typesModules from './modules';
|
||||
@@ -16,6 +16,7 @@ import upgrades from './upgrades';
|
||||
|
||||
export { knownOrigins } from './knownOrigins';
|
||||
export { packageInfo } from './packageInfo';
|
||||
export { mapXcmTypes } from './xcm';
|
||||
|
||||
// flatten a VersionedType[] into a Record<string, string>
|
||||
/** @internal */
|
||||
@@ -25,20 +26,16 @@ function filterVersions (versions: OverrideVersionedType[] = [], specVersion: nu
|
||||
(isUndefined(min) || isNull(min) || specVersion >= min) &&
|
||||
(isUndefined(max) || isNull(max) || specVersion <= max)
|
||||
)
|
||||
.reduce((result: RegistryTypes, { types }): RegistryTypes => ({
|
||||
...result,
|
||||
...types
|
||||
}), {});
|
||||
.reduce((result: RegistryTypes, { types }): RegistryTypes =>
|
||||
objectSpread(result, types), {}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Get types for specific modules (metadata override)
|
||||
*/
|
||||
export function getModuleTypes ({ knownTypes }: Registry, section: string): OverrideModuleType {
|
||||
return {
|
||||
...(typesModules[section] || {}),
|
||||
...(knownTypes.typesAlias?.[section] || {})
|
||||
};
|
||||
return objectSpread({}, typesModules[section], knownTypes.typesAlias?.[section]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,10 +45,10 @@ export function getSpecExtensions ({ knownTypes }: Registry, chainName: Text | s
|
||||
const _chainName = chainName.toString();
|
||||
const _specName = specName.toString();
|
||||
|
||||
return {
|
||||
...(knownTypes.typesBundle?.spec?.[_specName]?.signedExtensions || {}),
|
||||
...(knownTypes.typesBundle?.chain?.[_chainName]?.signedExtensions || {})
|
||||
};
|
||||
return objectSpread({},
|
||||
knownTypes.typesBundle?.spec?.[_specName]?.signedExtensions,
|
||||
knownTypes.typesBundle?.chain?.[_chainName]?.signedExtensions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,15 +63,15 @@ export function getSpecTypes ({ knownTypes }: Registry, chainName: Text | string
|
||||
// - spec then chain
|
||||
// - typesBundle takes higher precedence
|
||||
// - types is the final catch-all override
|
||||
return {
|
||||
...filterVersions(typesSpec[_specName], _specVersion),
|
||||
...filterVersions(typesChain[_chainName], _specVersion),
|
||||
...filterVersions(knownTypes.typesBundle?.spec?.[_specName]?.types, _specVersion),
|
||||
...filterVersions(knownTypes.typesBundle?.chain?.[_chainName]?.types, _specVersion),
|
||||
...(knownTypes.typesSpec?.[_specName] || {}),
|
||||
...(knownTypes.typesChain?.[_chainName] || {}),
|
||||
...(knownTypes.types || {})
|
||||
};
|
||||
return objectSpread({},
|
||||
filterVersions(typesSpec[_specName], _specVersion),
|
||||
filterVersions(typesChain[_chainName], _specVersion),
|
||||
filterVersions(knownTypes.typesBundle?.spec?.[_specName]?.types, _specVersion),
|
||||
filterVersions(knownTypes.typesBundle?.chain?.[_chainName]?.types, _specVersion),
|
||||
knownTypes.typesSpec?.[_specName],
|
||||
knownTypes.typesChain?.[_chainName],
|
||||
knownTypes.types
|
||||
);
|
||||
}
|
||||
|
||||
export function getSpecHasher ({ knownTypes }: Registry, chainName: Text | string, specName: Text | string): CodecHasher | null {
|
||||
@@ -91,10 +88,10 @@ export function getSpecRpc ({ knownTypes }: Registry, chainName: Text | string,
|
||||
const _chainName = chainName.toString();
|
||||
const _specName = specName.toString();
|
||||
|
||||
return {
|
||||
...(knownTypes.typesBundle?.spec?.[_specName]?.rpc || {}),
|
||||
...(knownTypes.typesBundle?.chain?.[_chainName]?.rpc || {})
|
||||
};
|
||||
return objectSpread({},
|
||||
knownTypes.typesBundle?.spec?.[_specName]?.rpc,
|
||||
knownTypes.typesBundle?.chain?.[_chainName]?.rpc
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,11 +102,11 @@ export function getSpecAlias ({ knownTypes }: Registry, chainName: Text | string
|
||||
const _specName = specName.toString();
|
||||
|
||||
// as per versions, first spec, then chain then finally non-versioned
|
||||
return {
|
||||
...(knownTypes.typesBundle?.spec?.[_specName]?.alias || {}),
|
||||
...(knownTypes.typesBundle?.chain?.[_chainName]?.alias || {}),
|
||||
...(knownTypes.typesAlias || {})
|
||||
};
|
||||
return objectSpread({},
|
||||
knownTypes.typesBundle?.spec?.[_specName]?.alias,
|
||||
knownTypes.typesBundle?.chain?.[_chainName]?.alias,
|
||||
knownTypes.typesAlias
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +117,7 @@ export function getUpgradeVersion (genesisHash: Hash, blockNumber: BN): [ChainUp
|
||||
|
||||
return known
|
||||
? [
|
||||
known.versions.reduce((last: ChainUpgradeVersion | undefined, version): ChainUpgradeVersion | undefined => {
|
||||
known.versions.reduce<ChainUpgradeVersion | undefined>((last, version) => {
|
||||
return blockNumber.gt(version.blockNumber)
|
||||
? version
|
||||
: last;
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/types-known', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/types-known', version: '6.8.1' };
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
import type { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
const sharedTypes = {
|
||||
// Anchor
|
||||
AnchorData: {
|
||||
@@ -79,20 +81,18 @@ const sharedTypes = {
|
||||
}
|
||||
};
|
||||
|
||||
const standaloneTypes = {
|
||||
...sharedTypes,
|
||||
const standaloneTypes = objectSpread({}, sharedTypes, {
|
||||
AccountInfo: 'AccountInfoWithRefCount',
|
||||
Address: 'LookupSource',
|
||||
LookupSource: 'IndicesLookupSource',
|
||||
Multiplier: 'Fixed64',
|
||||
RefCount: 'RefCountTo259'
|
||||
};
|
||||
});
|
||||
|
||||
const versioned: OverrideVersionedType[] = [
|
||||
{
|
||||
minmax: [240, 243],
|
||||
types: {
|
||||
...standaloneTypes,
|
||||
types: objectSpread({}, standaloneTypes, {
|
||||
ProxyType: {
|
||||
_enum: [
|
||||
'Any',
|
||||
@@ -102,19 +102,15 @@ const versioned: OverrideVersionedType[] = [
|
||||
'Vesting'
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [244, 999],
|
||||
types: {
|
||||
...standaloneTypes
|
||||
}
|
||||
types: objectSpread({}, standaloneTypes)
|
||||
},
|
||||
{
|
||||
minmax: [1000, undefined],
|
||||
types: {
|
||||
...sharedTypes
|
||||
}
|
||||
types: objectSpread({}, sharedTypes)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
|
||||
import type { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
import { mapXcm } from '@polkadot/types/interfaces/xcm/definitions';
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
import { mapXcmTypes } from '../xcm';
|
||||
|
||||
const sharedTypes = {
|
||||
CompactAssignments: 'CompactAssignmentsWith24',
|
||||
@@ -40,8 +42,7 @@ const versioned: OverrideVersionedType[] = [
|
||||
{
|
||||
// 1020 is first CC3
|
||||
minmax: [1019, 1031],
|
||||
types: {
|
||||
...addrIndicesTypes,
|
||||
types: objectSpread({}, addrIndicesTypes, {
|
||||
BalanceLock: 'BalanceLockTo212',
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchError: 'DispatchErrorTo198',
|
||||
@@ -57,12 +58,11 @@ const versioned: OverrideVersionedType[] = [
|
||||
StakingLedger: 'StakingLedgerTo223',
|
||||
Votes: 'VotesTo230',
|
||||
Weight: 'u32'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [1032, 1042],
|
||||
types: {
|
||||
...addrIndicesTypes,
|
||||
types: objectSpread({}, addrIndicesTypes, {
|
||||
BalanceLock: 'BalanceLockTo212',
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
@@ -76,13 +76,12 @@ const versioned: OverrideVersionedType[] = [
|
||||
StakingLedger: 'StakingLedgerTo223',
|
||||
Votes: 'VotesTo230',
|
||||
Weight: 'u32'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
// actual at 1045 (1043-1044 is dev)
|
||||
minmax: [1043, 1045],
|
||||
types: {
|
||||
...addrIndicesTypes,
|
||||
types: objectSpread({}, addrIndicesTypes, {
|
||||
BalanceLock: 'BalanceLockTo212',
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
@@ -95,14 +94,11 @@ const versioned: OverrideVersionedType[] = [
|
||||
StakingLedger: 'StakingLedgerTo223',
|
||||
Votes: 'VotesTo230',
|
||||
Weight: 'u32'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [1046, 1054],
|
||||
types: {
|
||||
// Indices optional, not in transaction
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
Heartbeat: 'HeartbeatTo244',
|
||||
@@ -112,13 +108,11 @@ const versioned: OverrideVersionedType[] = [
|
||||
ReferendumInfo: 'ReferendumInfoTo239',
|
||||
StakingLedger: 'StakingLedgerTo240',
|
||||
Weight: 'u32'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [1055, 1056],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
Heartbeat: 'HeartbeatTo244',
|
||||
@@ -127,92 +121,71 @@ const versioned: OverrideVersionedType[] = [
|
||||
RefCount: 'RefCountTo259',
|
||||
StakingLedger: 'StakingLedgerTo240',
|
||||
Weight: 'u32'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [1057, 1061],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
Heartbeat: 'HeartbeatTo244',
|
||||
OpenTip: 'OpenTipTo225',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [1062, 2012],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
OpenTip: 'OpenTipTo225',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [2013, 2022],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [2023, 2024],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [2025, 2027],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes)
|
||||
},
|
||||
{
|
||||
minmax: [2028, 2029],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
types: objectSpread({}, sharedTypes, {
|
||||
AccountInfo: 'AccountInfoWithDualRefCount',
|
||||
CompactAssignments: 'CompactAssignmentsWith16',
|
||||
RawSolution: 'RawSolutionWith16'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [2030, 9000],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
types: objectSpread({}, sharedTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsWith16',
|
||||
RawSolution: 'RawSolutionWith16'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [9010, 9099],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V0')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V0'))
|
||||
},
|
||||
{
|
||||
// jump from 9100 to 9110, however align with Rococo
|
||||
minmax: [9100, 9105],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V1')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V1'))
|
||||
},
|
||||
{
|
||||
// metadata v14
|
||||
minmax: [9106, undefined],
|
||||
types: {
|
||||
...sharedTypes
|
||||
}
|
||||
types: {}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
import type { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
const sharedTypes = {
|
||||
CompactAssignments: 'CompactAssignmentsWith16',
|
||||
RawSolution: 'RawSolutionWith16',
|
||||
@@ -17,7 +19,8 @@ const sharedTypes = {
|
||||
Staking: 3,
|
||||
UnusedSudoBalances: 4,
|
||||
IdentityJudgement: 5,
|
||||
CancelProxy: 6
|
||||
CancelProxy: 6,
|
||||
Auction: 7
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -34,57 +37,43 @@ const addrAccountIdTypes = {
|
||||
const versioned: OverrideVersionedType[] = [
|
||||
{
|
||||
minmax: [0, 12],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
OpenTip: 'OpenTipTo225',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [13, 22],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [23, 24],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [25, 27],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes)
|
||||
},
|
||||
{
|
||||
minmax: [28, 29],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
types: objectSpread({}, sharedTypes, {
|
||||
AccountInfo: 'AccountInfoWithDualRefCount'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [30, 9109],
|
||||
types: {
|
||||
...sharedTypes
|
||||
}
|
||||
types: objectSpread({}, sharedTypes)
|
||||
},
|
||||
{
|
||||
// metadata v14
|
||||
minmax: [9110, undefined],
|
||||
types: {
|
||||
...sharedTypes
|
||||
}
|
||||
types: {}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
|
||||
import type { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
import { mapXcm } from '@polkadot/types/interfaces/xcm/definitions';
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
import { mapXcmTypes } from '../xcm';
|
||||
|
||||
// structs need to be in order
|
||||
/* eslint-disable sort-keys */
|
||||
@@ -18,47 +20,36 @@ const sharedTypes = {
|
||||
const versioned: OverrideVersionedType[] = [
|
||||
{
|
||||
minmax: [0, 200],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
types: objectSpread({}, sharedTypes, {
|
||||
AccountInfo: 'AccountInfoWithDualRefCount',
|
||||
Address: 'AccountId',
|
||||
LookupSource: 'AccountId'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [201, 214],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
types: objectSpread({}, sharedTypes, {
|
||||
AccountInfo: 'AccountInfoWithDualRefCount'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [215, 228],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
types: objectSpread({}, sharedTypes, {
|
||||
Keys: 'SessionKeys6'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [229, 9099],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V0')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V0'))
|
||||
},
|
||||
{
|
||||
minmax: [9100, 9105],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V1')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V1'))
|
||||
},
|
||||
{
|
||||
// metadata v14
|
||||
minmax: [9106, undefined],
|
||||
types: {
|
||||
...sharedTypes
|
||||
}
|
||||
types: {}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
|
||||
import type { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
import { mapXcm } from '@polkadot/types/interfaces/xcm/definitions';
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
import { mapXcmTypes } from '../xcm';
|
||||
|
||||
const sharedTypes = {
|
||||
TAssetBalance: 'u128',
|
||||
@@ -26,24 +28,16 @@ const sharedTypes = {
|
||||
const versioned: OverrideVersionedType[] = [
|
||||
{
|
||||
minmax: [0, 3],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V0')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V0'))
|
||||
},
|
||||
{
|
||||
minmax: [4, 5],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V1')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V1'))
|
||||
},
|
||||
{
|
||||
// metadata V14
|
||||
minmax: [500, undefined],
|
||||
types: {
|
||||
...sharedTypes
|
||||
}
|
||||
types: {}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
|
||||
import type { OverrideVersionedType } from '@polkadot/types/types';
|
||||
|
||||
import { mapXcm } from '@polkadot/types/interfaces/xcm/definitions';
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
import { mapXcmTypes } from '../xcm';
|
||||
|
||||
const sharedTypes = {
|
||||
// 16 validators
|
||||
@@ -31,9 +33,7 @@ const addrAccountIdTypes = {
|
||||
const versioned: OverrideVersionedType[] = [
|
||||
{
|
||||
minmax: [1, 2],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
Heartbeat: 'HeartbeatTo244',
|
||||
@@ -41,75 +41,57 @@ const versioned: OverrideVersionedType[] = [
|
||||
OpenTip: 'OpenTipTo225',
|
||||
RefCount: 'RefCountTo259',
|
||||
Weight: 'u32'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [3, 22],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
Heartbeat: 'HeartbeatTo244',
|
||||
OpenTip: 'OpenTipTo225',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [23, 42],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
CompactAssignments: 'CompactAssignmentsTo257',
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
Heartbeat: 'HeartbeatTo244',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [43, 44],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes,
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes, {
|
||||
DispatchInfo: 'DispatchInfoTo244',
|
||||
Heartbeat: 'HeartbeatTo244',
|
||||
RefCount: 'RefCountTo259'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [45, 47],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...addrAccountIdTypes
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, addrAccountIdTypes)
|
||||
},
|
||||
{
|
||||
minmax: [48, 49],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
types: objectSpread({}, sharedTypes, {
|
||||
AccountInfo: 'AccountInfoWithDualRefCount'
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
minmax: [50, 9099],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V0')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V0'))
|
||||
},
|
||||
{
|
||||
minmax: [9100, 9105],
|
||||
types: {
|
||||
...sharedTypes,
|
||||
...mapXcm('V1')
|
||||
}
|
||||
types: objectSpread({}, sharedTypes, mapXcmTypes('V1'))
|
||||
},
|
||||
{
|
||||
// metadata v14
|
||||
minmax: [9106, undefined],
|
||||
types: {
|
||||
...sharedTypes
|
||||
}
|
||||
types: {}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ const upgrades: ChainUpgradesRaw = [
|
||||
[3860281, 2023], [4143129, 2024], [4401242, 2025], [4841367, 2026], [5961600, 2027],
|
||||
[6137912, 2028], [6561855, 2029], [7100891, 2030], [7468792, 9010], [7668600, 9030],
|
||||
[7812476, 9040], [8010981, 9050], [8073833, 9070], [8555825, 9080], [8945245, 9090],
|
||||
[9611377, 9100], [9625129, 9111]
|
||||
[9611377, 9100], [9625129, 9111], [9866422, 9122]
|
||||
];
|
||||
|
||||
export default upgrades;
|
||||
|
||||
@@ -9,7 +9,7 @@ const upgrades: ChainUpgradesRaw = [
|
||||
[528470, 13], [687751, 14], [746085, 15], [787923, 16], [799302, 17],
|
||||
[1205128, 18], [1603423, 23], [1733218, 24], [2005673, 25], [2436698, 26],
|
||||
[3613564, 27], [3899547, 28], [4345767, 29], [4876134, 30], [5661442, 9050],
|
||||
[6321619, 9080], [6713249, 9090], [7217907, 9100], [7229126, 9110]
|
||||
[6321619, 9080], [6713249, 9090], [7217907, 9100], [7229126, 9110], [7560558, 9122]
|
||||
];
|
||||
|
||||
export default upgrades;
|
||||
|
||||
@@ -11,7 +11,8 @@ const upgrades: ChainUpgradesRaw = [
|
||||
[2549864, 45], [3925782, 46], [3925843, 47], [4207800, 48], [4627944, 49],
|
||||
[5124076, 50], [5478664, 900], [5482450, 9000], [5584305, 9010], [5784566, 9030],
|
||||
[5879822, 9031], [5896856, 9032], [5897316, 9033], [6117927, 9050], [6210274, 9070],
|
||||
[6379314, 9080], [6979141, 9090], [7568453, 9100], [7766392, 9111]
|
||||
[6379314, 9080], [6979141, 9090], [7568453, 9100], [7766394, 9111], [7911691, 9120],
|
||||
[7968866, 9121], [7982889, 9122]
|
||||
];
|
||||
|
||||
export default upgrades;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright 2017-2021 @polkadot/types-known authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
export const XCM_MAPPINGS = ['AssetInstance', 'Fungibility', 'Junction', 'Junctions', 'MultiAsset', 'MultiAssetFilter', 'MultiLocation', 'Response', 'WildFungibility', 'WildMultiAsset', 'Xcm', 'XcmError', 'XcmOrder'];
|
||||
|
||||
export function mapXcmTypes (version: 'V0' | 'V1' | 'V2'): Record<string, string> {
|
||||
return XCM_MAPPINGS.reduce<Record<string, string>>((all, key) =>
|
||||
objectSpread(all, { [key]: `${key}${version}` }), {}
|
||||
);
|
||||
}
|
||||
@@ -1,25 +1,29 @@
|
||||
{
|
||||
"name": "@polkadot/types-support",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Supporting files for types, mostly for testing",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types-support#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/types-support",
|
||||
"repository": {
|
||||
"directory": "packages/types-support",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types-support#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/util": "^7.5.1"
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/util": "^7.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,4 +3,4 @@
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/types-support', version: '6.4.2' };
|
||||
export const packageInfo = { name: '@polkadot/types-support', version: '6.8.1' };
|
||||
|
||||
+23
-19
@@ -1,32 +1,36 @@
|
||||
{
|
||||
"name": "@polkadot/types",
|
||||
"version": "6.4.2",
|
||||
"type": "module",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"contributors": [],
|
||||
"description": "Implementation of the Parity codec",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/types",
|
||||
"repository": {
|
||||
"directory": "packages/types",
|
||||
"type": "git",
|
||||
"url": "https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:polkadot-js/api",
|
||||
"bugs": "https://github.com/polkadot-js/api/issues",
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/types#readme",
|
||||
"type": "module",
|
||||
"version": "6.8.1",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@polkadot/util": "^7.5.1",
|
||||
"@polkadot/util-crypto": "^7.5.1",
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@polkadot/util": "^7.8.2",
|
||||
"@polkadot/util-crypto": "^7.8.2",
|
||||
"rxjs": "^7.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^7.5.1",
|
||||
"@polkadot/types-support": "6.4.2",
|
||||
"@polkadot/keyring": "^7.8.2",
|
||||
"@polkadot/types-support": "6.8.1",
|
||||
"@types/bn.js": "^4.11.6",
|
||||
"bn.js": "^4.12.0"
|
||||
}
|
||||
|
||||
@@ -3,17 +3,15 @@
|
||||
|
||||
import type { Definitions } from '../../types';
|
||||
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
|
||||
import kusama from './kusama';
|
||||
import polkadot from './polkadot';
|
||||
import substrate from './substrate';
|
||||
|
||||
export default {
|
||||
rpc: {},
|
||||
types: {
|
||||
// Not 100% sure it is relevant, however the order here is the same
|
||||
// as exposed in the typegen lookup order
|
||||
...substrate,
|
||||
...polkadot,
|
||||
...kusama
|
||||
}
|
||||
// Not 100% sure it is relevant, however the order here is the same
|
||||
// as exposed in the typegen lookup order
|
||||
types: objectSpread({}, substrate, polkadot, kusama)
|
||||
} as Definitions;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user