Compare commits

...
46 Commits
Author SHA1 Message Date
Github Actions cb791d3963 [CI Skip] release/stable 2.5.1
skip-checks: true
2020-11-02 11:30:30 +00:00
Jaco Greeff bc49e75e61 CHANGELOG for 2.5.1 2020-11-02 12:22:24 +01:00
Jaco Greeff 67f8dcafdb 2.5 (#2813) 2020-11-02 11:45:57 +01:00
Github Actions e95117839b [CI Skip] release/beta 2.4.2-20
skip-checks: true
2020-10-31 12:27:54 +00:00
Jaco Greeff 9f60a8cd5f Add decoded contract events to execution (#2812)
* Cleanup assignments

* Small adjustments

* Add decoded contract events to execution

* Adjust all applyOnEvent
2020-10-31 13:19:57 +01:00
Github Actions e23fae86d5 [CI Skip] release/beta 2.4.2-19
skip-checks: true
2020-10-31 11:58:34 +00:00
Jaco Greeff 94a4594d32 Cleanup assignments (#2811)
* Cleanup assignments

* Small adjustments

* Cleanup AnyJson results

* Event toHuman
2020-10-31 12:50:44 +01:00
Github Actions 5be8ef8f0d [CI Skip] release/beta 2.4.2-18
skip-checks: true
2020-10-31 10:25:53 +00:00
Jaco Greeff e855d5a9d4 Cater for new/old contracts_call results (#2810)
* Cater for new/old contracts_call results

* Update packages/types/src/interfaces/contracts/definitions.ts

* Allow RPC layer to output JSON

* Typing for json outputs

* Convert results

* RPC compat mapping

* Ensure RPC .json is exposed

* Remove compat layer

* Old error detection

* Map to unknown

* Update packages/rpc-core/src/index.ts

* linting
2020-10-31 11:18:58 +01:00
Github Actions 2a0e481710 [CI Skip] release/beta 2.4.2-17
skip-checks: true
2020-10-30 13:37:09 +00:00
Jaco Greeff 161c121cb2 Cleanups for maintainability (#2809)
* Cleanups for maintainability

* Split referendumsInfo

* Extract didUpdate -> bool

* Era filtering

* Default to council

* Points cache

* Remove cache

* Move map arg
2020-10-30 14:28:38 +01:00
Github Actions de38735498 [CI Skip] release/beta 2.4.2-16
skip-checks: true
2020-10-30 11:17:23 +00:00
Jaco Greeff ce1e6615e3 Add derive for single council proposal (#2808) 2020-10-30 12:09:12 +01:00
Github Actions 3ebe9f5243 [CI Skip] release/beta 2.4.2-15
skip-checks: true
2020-10-30 09:54:52 +00:00
Jaco Greeff f686cfcce7 Cleanup always primitive (caters for solang) (#2807)
* Cleanup always primitive (caters for solang)

* Compare (with primitive)
2020-10-30 10:47:18 +01:00
Github Actions c27e49c6f5 [CI Skip] release/beta 2.4.2-14
skip-checks: true
2020-10-30 09:25:37 +00:00
Jaco Greeff 5c69f78676 Expand Call errors with actual callIndex info (#2806)
* Expand Call errors with actutl callIndex info

* Update test expectation

* casing
2020-10-30 10:17:19 +01:00
Github Actions 8f00351405 [CI Skip] release/beta 2.4.2-13
skip-checks: true
2020-10-29 16:25:25 +00:00
Jaco Greeff 1f6c8c2eb8 Use assertReturn to cleanup (#2804)
* Use assertReturn to cleanup

* Remove Uint/Int duplication

* Adjust

* ws errors, part 2

* .

* Adj. manual

* adj

* switchMap

* Revert "switchMap"

This reverts commit edfa4a2258f09042b61a27fd3812f0c53039fe4f.

* Revert.

* Revert.

* protected constructor

* Correct isHexJson flag

* Remove isHexJson (always detect)

* Adjust

* Flags
2020-10-29 17:17:22 +01:00
Github Actions 9bb1343255 [CI Skip] release/beta 2.4.2-12
skip-checks: true
2020-10-29 13:27:28 +00:00
Jaco Greeff 94ebb321f1 Complexity adjustments (#2803)
* Complexity adjustments

* cleanups

* Small cleanups

* Additional

* revert era

* ExtrinsicEra
2020-10-29 14:20:10 +01:00
Github Actions 63fd5baa8f [CI Skip] release/beta 2.4.2-11
skip-checks: true
2020-10-29 11:08:09 +00:00
Jaco Greeff ea3ee428d8 Rework asLatest update (#2802)
* Revert "[CI Skip] release/beta 2.4.2-10"

This reverts commit 5cb1c2d33a.

* Revert "Use asLatest in metadata extraction (#2800)"

This reverts commit 600666de1c.

* Bumps

* Expansion

* Flatten

* Metadata class imports

* Cleanup Decorate exports

* Move Metadata to top-level

* Swap logger on ABI

* Adjust imports

* Cleanups

* Updates
2020-10-29 11:59:37 +01:00
Github Actions 5cb1c2d33a [CI Skip] release/beta 2.4.2-10
skip-checks: true
2020-10-29 08:13:14 +00:00
Jaco Greeff 600666de1c Use asLatest in metadata extraction (#2800)
* User asLatest in metadata extraction

* Cleanup Decorated, bump

* linting

* cleanup decorate

* Remove registry arg from Decorated
2020-10-29 09:05:53 +01:00
Github Actions 524885e8de [CI Skip] release/beta 2.4.2-9
skip-checks: true
2020-10-28 13:37:25 +00:00
Jaco Greeff 1476e5e5e9 Bump common, string* with String (#2799)
* Bump common, string* with String

* Linting, TS 4.0.5
2020-10-28 14:28:49 +01:00
Github Actions 3f48b3c29f [CI Skip] release/beta 2.4.2-8
skip-checks: true
2020-10-28 12:34:15 +00:00
Jaco Greeff 9debb854f9 syncState RPCs (#2797)
* syncState RPCs

* Use endpoint override as available

* Allow Json construction, update syncstate_get def
2020-10-28 13:26:37 +01:00
Github Actions db3fe7d103 [CI Skip] release/beta 2.4.2-7
skip-checks: true
2020-10-28 09:40:45 +00:00
Jaco Greeff a93063c6fb Know-types for Rococo v1 (#2795) 2020-10-28 10:31:32 +01:00
Github Actions 8e4bbd2b23 [CI Skip] release/beta 2.4.2-6
skip-checks: true
2020-10-27 14:27:45 +00:00
Jaco Greeff cf1c2ea58a Add dryRun capability on Submittable (#2793)
* Add dryRun capability on Submittable

* Ordering, add to interface

* Dry run with signing

* Revert paymentInfo changes
2020-10-27 15:19:00 +01:00
Github Actions ca2909e4ba [CI Skip] release/beta 2.4.2-5
skip-checks: true
2020-10-27 12:55:21 +00:00
Jaco Greeff cc9ea53e1a Registry hash returns H256 object (#2791)
* Use logger in error/warning messages

* Update packages/types/src/codec/BTreeSet.ts

* Update expectation

* Some additional type tests

* resgirty.hash returns H256

* Additional override test
2020-10-27 13:47:18 +01:00
Github Actions d876e19fa1 [CI Skip] release/beta 2.4.2-4
skip-checks: true
2020-10-27 12:22:14 +00:00
Jaco Greeff bb7b94dc35 Use logger in error/warning messages (#2790)
* Use logger in error/warning messages

* Update packages/types/src/codec/BTreeSet.ts

* Update expectation

* Some additional type tests
2020-10-27 13:14:03 +01:00
Github Actions be1deb1a75 [CI Skip] release/beta 2.4.2-3
skip-checks: true
2020-10-27 11:30:53 +00:00
Jaco Greeff 14026fef42 Format similar types transparently (#2788)
* Format similar types transparently

* Adjust test expectations

* Remove console.error

* Adjust getTypeDef for check-only
2020-10-27 12:23:18 +01:00
Github Actions b2ea2da6aa [CI Skip] release/beta 2.4.2-2
skip-checks: true
2020-10-27 09:07:26 +00:00
Jaco Greeff f1d21847db Bump deps (util) (#2787) 2020-10-27 09:59:27 +01:00
Github Actions b1fcfd11f4 [CI Skip] release/beta 2.4.2-1
skip-checks: true
2020-10-26 21:44:52 +00:00
Jeremías Díaz 7d1f0e2900 fix(typegen): dedupe similar types (#2786) 2020-10-26 22:37:09 +01:00
Jaco Greeff fb377fb0d4 Adjust index WS imports (#2785) 2020-10-26 22:36:03 +01:00
Github Actions 26de59ed79 [CI Skip] release/beta 2.4.2-0
skip-checks: true
2020-10-26 14:51:50 +00:00
Jaco Greeff 964bd33bb1 Bump GH actions, root cleanups (#2783)
* Bump GH actions, root cleanups

* Remove copy scripts
2020-10-26 15:42:51 +01:00
218 changed files with 2181 additions and 3011 deletions
-4
View File
@@ -1,4 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
module.exports = require('./babel.config.js');
-5
View File
@@ -1,5 +0,0 @@
.eslintrc.js
**/build/*
**/coverage/*
**/node_modules/*
docs/examples/promise/90_typegen/*
+9
View File
@@ -5,6 +5,15 @@ const base = require('@polkadot/dev/config/eslint');
module.exports = {
...base,
ignorePatterns: [
'.eslintrc.js',
'.github/**',
'.vscode/**',
'.yarn/**',
'**/build/*',
'**/coverage/*',
'**/node_modules/*'
],
parserOptions: {
...base.parserOptions,
project: [
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
name: ${{ matrix.step }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: ${{ matrix.step }}
run: |
yarn install --immutable | grep -v 'YN0013'
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
if: "! startsWith(github.event.head_commit.message, '[CI Skip]') && github.repository == 'polkadot-js/api'"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
with:
token: ${{ secrets.GH_PAT }}
- name: ${{ matrix.step }}
+1 -1
View File
@@ -1 +1 @@
10
12
+24
View File
@@ -1,5 +1,29 @@
# CHANGELOG
## 2.5.1 Nov 2, 2020
Upgrade priority: Low. Recommended for `api-contract` developers.
- **Breaking change** Substrate changed the `ContractExecResult` from `api.rpc.contracts.call`. The API does have pass-through support for both old and new variants via the `Contract` interface, however it means the structure has changed to accommodate the new Substrate structure. Refer to the [docs for the latest interface](https://polkadot.js.org/docs/api-contract/start/contract.read) (including `isSuccess/isError` -> `isOk/isErr`, and the availability of the `gasConsumed`)
Contributed:
- Dedup similar types on generation (Thanks to https://github.com/monitz87)
Changes:
- `Contract` execution will now return contract events decoded in the result
- Add `.dryRun` on extrinsics (alongside `.paymentInfo` usage)
- Add `system_syncState` and `syncstate_genSyncSpec` RPCs
- Enhance error reporting, `Call` indicates explicit call as found
- Adjust internal metadata decoration and use as exposed from `@types/metadata`
- Expand Rococo known types to cater for v1 (specVersion 10)
- `registry.hash` now returns an `H256` object (as opposed to raw Uint8Array)
- Use utility logger in all relevant error messages (consistency in logging)
- Add `derive.council.proposal(<hash>)` for retrieval of a single (expanded) proposal
- Correctly and transparently format type generation types (allowing for nested variants)
## 2.4.1 Oct 26, 2020
Upgrade priority: Low. No breaking changes, however it does move `api-contract` forward with additional features.
-25
View File
@@ -1,25 +0,0 @@
#!/usr/bin/env bash
# Copyright 2017-2020 @polkadot/api authors & contributors
# SPDX-License-Identifier: Apache-2.0
function copy_folder () {
SRC="packages/$1/build"
DST="../apps/node_modules/@polkadot/$1"
echo "** Copying $SRC to $DST"
rm -rf $DST
cp -r $SRC $DST
}
yarn polkadot-dev-build-ts
copy_folder "api"
copy_folder "api-contract"
copy_folder "api-derive"
copy_folder "metadata"
copy_folder "rpc-core"
copy_folder "rpc-provider"
copy_folder "types"
copy_folder "types-known"
copy_folder "typegen"
-25
View File
@@ -1,25 +0,0 @@
#!/usr/bin/env bash
# Copyright 2017-2020 @polkadot/api authors & contributors
# SPDX-License-Identifier: Apache-2.0
function copy_folder () {
SRC="packages/$1/build"
DST="../test/js-test/node_modules/@polkadot/$1"
echo "** Copying $SRC to $DST"
rm -rf $DST
cp -r $SRC $DST
}
yarn polkadot-dev-build-ts
copy_folder "api"
copy_folder "api-contract"
copy_folder "api-derive"
copy_folder "metadata"
copy_folder "rpc-core"
copy_folder "rpc-provider"
copy_folder "types"
copy_folder "types-known"
copy_folder "typegen"
+1 -1
View File
@@ -25,5 +25,5 @@ module.exports = Object.assign({}, config, {
'<rootDir>/packages/types/build',
'<rootDir>/packages/types-known/build'
],
resolver: './jest.resolver.js'
resolver: '@polkadot/dev/config/jest-resolver'
});
-12
View File
@@ -1,12 +0,0 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
const path = require('path');
module.exports = function resolver (file, config) {
if (file.includes('package.json')) {
return path.join(config.basedir.replace('/src', '/'), file);
}
return config.defaultResolver(file, config);
};
+4 -4
View File
@@ -8,7 +8,7 @@
],
"resolutions": {
"babel-core": "^7.0.0-bridge.0",
"typescript": "^4.0.3"
"typescript": "^4.0.5"
},
"scripts": {
"build": "yarn build:interfaces && polkadot-dev-build-ts && (cd packages/typegen && copyfiles scripts/* build)",
@@ -27,11 +27,11 @@
"@babel/core": "^7.12.3",
"@babel/register": "^7.12.1",
"@babel/runtime": "^7.12.1",
"@polkadot/dev": "^0.59.6",
"@polkadot/ts": "^0.3.51",
"@polkadot/dev": "^0.59.14",
"@polkadot/ts": "^0.3.53",
"@polkadot/typegen": "workspace:packages/typegen",
"@types/jest": "^26.0.15",
"copyfiles": "^2.4.0"
},
"version": "2.4.1"
"version": "2.5.1"
}
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-contract",
"version": "2.4.1",
"version": "2.5.1",
"description": "Interfaces for interacting with contracts and contract ABIs",
"main": "index.js",
"keywords": [
@@ -27,10 +27,10 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/api": "^2.4.1",
"@polkadot/rpc-core": "^2.4.1",
"@polkadot/types": "^2.4.1",
"@polkadot/util": "^3.6.1",
"@polkadot/api": "^2.5.1",
"@polkadot/rpc-core": "^2.5.1",
"@polkadot/types": "^2.5.1",
"@polkadot/util": "^3.7.1",
"bn.js": "^5.1.3",
"rxjs": "^6.6.3"
}
+6 -6
View File
@@ -5,10 +5,12 @@ import { AnyJson, Codec, CodecArg } from '@polkadot/types/types';
import { ChainProperties, ContractConstructorSpec, ContractEventSpec, ContractMessageSpec, ContractMessageParamSpec, ContractProject } from '@polkadot/types/interfaces';
import { AbiConstructor, AbiEvent, AbiMessage, AbiParam, DecodedEvent, DecodedMessage } from './types';
import { assert, compactAddLength, compactStripLength, isNumber, isObject, isString, stringCamelCase, u8aConcat, u8aToHex } from '@polkadot/util';
import { assert, assertReturn, compactAddLength, compactStripLength, isNumber, isObject, isString, logger, stringCamelCase, u8aConcat, u8aToHex } from '@polkadot/util';
import MetaRegistry from './MetaRegistry';
const l = logger('Abi');
function findMessage <T extends AbiMessage> (list: T[], messageOrId: T | string | number): T {
const message = isNumber(messageOrId)
? list[messageOrId]
@@ -16,9 +18,7 @@ function findMessage <T extends AbiMessage> (list: T[], messageOrId: T | string
? list.find(({ identifier }) => [identifier, stringCamelCase(identifier)].includes(messageOrId.toString()))
: messageOrId;
assert(message, `Attempted to call an invalid contract interface, ${JSON.stringify(messageOrId)}`);
return message;
return assertReturn(message, `Attempted to call an invalid contract interface, ${JSON.stringify(messageOrId)}`);
}
export default class Abi {
@@ -111,11 +111,11 @@ export default class Abi {
assert(isObject(arg.type), 'Invalid type definition found');
return {
name: stringCamelCase(arg.name.toString()),
name: stringCamelCase(arg.name),
type: this.registry.getMetaTypeDef(arg.type)
};
} catch (error) {
console.error(`Error expanding argument ${index} in ${JSON.stringify(spec)}`);
l.error(`Error expanding argument ${index} in ${JSON.stringify(spec)}`);
throw error;
}
+6 -4
View File
@@ -22,6 +22,8 @@ const PRIMITIVE_ALIAS: Record<string, keyof InterfaceTypes> = {
Str: 'Text'
};
const PRIMITIVE_ALWAYS = ['AccountId', 'AccountIndex', 'Address', 'Balance'];
export default class MetaRegistry extends TypeRegistry {
public readonly metaTypeDefs: TypeDef[] = [];
@@ -56,8 +58,8 @@ export default class MetaRegistry extends TypeRegistry {
typeDef = {
...typeDef,
displayName,
type: ['Balance'].includes(displayName)
? 'Balance'
type: PRIMITIVE_ALWAYS.includes(displayName)
? displayName
: typeDef.type
};
}
@@ -84,10 +86,10 @@ export default class MetaRegistry extends TypeRegistry {
#extract = (type: SiType, id: SiLookupTypeId): TypeDef => {
const path = [...type.path];
const pathFinal = path.length ? path[path.length - 1].toString() : '';
let typeDef: Omit<TypeDef, 'type'>;
// TODO solang?
if (type.path.join('::').startsWith('ink_env::types::')) {
if (type.path.join('::').startsWith('ink_env::types::') || PRIMITIVE_ALWAYS.includes(pathFinal)) {
typeDef = this.#extractPrimitivePath(type);
} else if (type.def.isPrimitive) {
typeDef = this.#extractPrimitive(type);
+1 -1
View File
@@ -56,7 +56,7 @@ export default class Blueprint<ApiType extends ApiTypes> extends Base<ApiType> {
return this.api.tx.contracts
.instantiate(endowment, gasLimit, this.codeHash, this.abi.findConstructor(constructorOrId).toU8a(params))
.withResultTransform((result: ISubmittableResult) =>
new BlueprintSubmittableResult(result, applyOnEvent(result, 'Instantiated', (record: EventRecord) =>
new BlueprintSubmittableResult(result, applyOnEvent(result, 'Instantiated', ([record]: EventRecord[]) =>
new Contract<ApiType>(this.api, this.abi, record.event.data[1] as AccountId, this._decorateMethod)
))
);
+1 -1
View File
@@ -38,7 +38,7 @@ export default class Code<ApiType extends ApiTypes> extends Base<ApiType> {
return this.api.tx.contracts
.putCode(compactAddLength(this.code))
.withResultTransform((result: ISubmittableResult) =>
new CodeSubmittableResult(result, applyOnEvent(result, 'CodeStored', (record: EventRecord) =>
new CodeSubmittableResult(result, applyOnEvent(result, 'CodeStored', ([record]: EventRecord[]) =>
new Blueprint<ApiType>(this.api, this.abi, record.event.data[0] as Hash, this._decorateMethod)
))
);
+72 -13
View File
@@ -3,21 +3,60 @@
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
import { SubmittableExtrinsic } from '@polkadot/api/submittable/types';
import { AccountId, ContractExecResult } from '@polkadot/types/interfaces';
import { AnyJson, CodecArg } from '@polkadot/types/types';
import { AbiMessage, ContractCallOutcome } from '../types';
import { AccountId, ContractExecResult, EventRecord } from '@polkadot/types/interfaces';
import { AnyJson, CodecArg, ISubmittableResult, Registry } from '@polkadot/types/types';
import { AbiMessage, ContractCallOutcome, DecodedEvent } from '../types';
import { ContractRead, MapMessageExec, MapMessageRead } from './types';
import BN from 'bn.js';
import { map } from 'rxjs/operators';
import { SubmittableResult } from '@polkadot/api';
import ApiBase from '@polkadot/api/base';
import { assert, bnToBn, isFunction, isUndefined, stringCamelCase } from '@polkadot/util';
import { assert, bnToBn, isFunction, isUndefined, logger, stringCamelCase } from '@polkadot/util';
import Abi from '../Abi';
import { formatData } from '../util';
import { applyOnEvent, formatData } from '../util';
import Base from './Base';
const ERROR_NO_CALL = 'Your node does not expose the contracts.call RPC. This is most probably due to a runtime configuration.';
const l = logger('Contract');
export class ContractSubmittableResult extends SubmittableResult {
public readonly contractEvents?: DecodedEvent[];
constructor (result: ISubmittableResult, contractEvents?: DecodedEvent[]) {
super(result);
this.contractEvents = contractEvents;
}
}
// map from a JSON result to current-style ContractExecResult
function mapExecResult (registry: Registry, json: Record<string, AnyJson>): ContractExecResult {
if (!Object.keys(json).some((key) => ['error', 'success'].includes(key))) {
return registry.createType('ContractExecResult', json);
}
const from = registry.createType('ContractExecResultTo260', json);
if (from.isSuccess) {
const s = from.asSuccess;
return registry.createType('ContractExecResult', {
gasConsumed: s.gasConsumed,
result: {
ok: {
data: s.data,
flags: s.flags
}
}
});
}
// in the old format error has no additional information,
// map it as-is with an "unknown" error
return registry.createType('ContractExecResult', { result: { err: { other: 'unknown' } } });
}
export default class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
public readonly address: AccountId;
@@ -69,7 +108,23 @@ export default class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
}
#exec = (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, params: CodecArg[]): SubmittableExtrinsic<ApiType> => {
return this.api.tx.contracts.call(this.address, value, this.#getGas(gasLimit), this.abi.findMessage(messageOrId).toU8a(params));
return this.api.tx.contracts
.call(this.address, value, this.#getGas(gasLimit), this.abi.findMessage(messageOrId).toU8a(params))
.withResultTransform((result: ISubmittableResult) =>
new ContractSubmittableResult(result, applyOnEvent(result, 'ContractExecution', (records: EventRecord[]) =>
records
.map(({ event: { data: [, data] } }): DecodedEvent | null => {
try {
return this.abi.decodeEvent(data.toU8a());
} catch (error) {
l.error(`Unable to decode contract event: ${(error as Error).message}`);
return null;
}
})
.filter((decoded): decoded is DecodedEvent => !!decoded)
))
);
}
#read = (messageOrId: AbiMessage | string | number, value: BigInt | BN | string | number, gasLimit: BigInt | BN | string | number, params: CodecArg[]): ContractRead<ApiType> => {
@@ -80,20 +135,24 @@ export default class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
return {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
send: this._decorateMethod((origin: string | AccountId | Uint8Array) =>
this.api.rx.rpc.contracts.call({
this.api.rx.rpc.contracts.call.json({
dest: this.address,
gasLimit: this.#getGas(gasLimit),
inputData: message.toU8a(params),
origin,
value
}).pipe(
map((result: ContractExecResult): ContractCallOutcome => ({
output: result.isSuccess && message.returnType
? formatData(this.registry, result.asSuccess.data, message.returnType)
}).pipe(map((json): ContractCallOutcome => {
const { debugMessage, gasConsumed, result } = mapExecResult(this.registry, json.toJSON());
return {
debugMessage,
gasConsumed,
output: result.isOk && message.returnType
? formatData(this.registry, result.asOk.data, message.returnType)
: null,
result
}))
)
};
}))
)
};
}
+6 -2
View File
@@ -2,10 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
import { ApiTypes } from '@polkadot/api/types';
import { ContractExecResult, ContractSelector } from '@polkadot/types/interfaces';
import { ContractExecResultResult, ContractSelector } from '@polkadot/types/interfaces';
import { Codec, CodecArg, TypeDef } from '@polkadot/types/types';
import ApiBase from '@polkadot/api/base';
import { Text, u64 } from '@polkadot/types';
import Abi from './Abi';
export interface ContractBase<ApiType extends ApiTypes> {
@@ -51,8 +53,10 @@ export interface InterfaceContractCalls {
}
export interface ContractCallOutcome {
debugMessage: Text;
gasConsumed: u64;
output: Codec | null;
result: ContractExecResult;
result: ContractExecResultResult;
}
export interface DecodedEvent {
+6 -4
View File
@@ -7,16 +7,18 @@ import { Codec, Registry, TypeDef } from '@polkadot/types/types';
import { Raw, createTypeUnsafe } from '@polkadot/types';
type ContractEvents = 'CodeStored' | 'ContractExecution' | 'Instantiated';
export function formatData (registry: Registry, data: Raw, { type }: TypeDef): Codec {
return createTypeUnsafe(registry, type, [data], true);
}
export function applyOnEvent <T> (result: SubmittableResult, type: 'CodeStored' | 'Instantiated', fn: (record: EventRecord) => T): T | undefined {
export function applyOnEvent <T> (result: SubmittableResult, type: ContractEvents, fn: (records: EventRecord[]) => T): T | undefined {
if (result.isInBlock || result.isFinalized) {
const record = result.findRecord('contracts', type);
const records = result.filterRecords('contracts', type);
if (record) {
return fn(record);
if (records.length) {
return fn(records);
}
}
@@ -0,0 +1,28 @@
[
{
"info": 6,
"type": "u256"
},
{
"info": 6,
"type": "u8"
},
{
"info": 12,
"length": 32,
"sub": {
"info": 6,
"type": "u8"
},
"type": "[u8;32]"
},
{
"displayName": "AccountId",
"info": 6,
"type": "AccountId"
},
{
"info": 6,
"type": "Text"
}
]
@@ -0,0 +1,299 @@
{
"contract": {
"authors": [
"unknown"
],
"name": "AssetTransfer",
"version": "0.0.1"
},
"metadataVersion": "0.1.0",
"source": {
"compiler": "solang 0.1.4",
"hash": "0x7d163f445bec3d33e90d0f60bda40acd42f2760dbc1b731616af70a6001e05c7",
"language": "Solidity 0.1.4"
},
"spec": {
"constructors": [
{
"args": [],
"docs": [
""
],
"name": "new",
"selector": "0x861731d5"
}
],
"events": [
{
"args": [
{
"indexed": false,
"name": "_newUser",
"type": {
"display_name": [
"AccountId"
],
"type": 4
}
}
],
"docs": [
""
],
"name": "successfulRegistration"
},
{
"args": [
{
"indexed": false,
"name": "sender",
"type": {
"display_name": [
"AccountId"
],
"type": 4
}
},
{
"indexed": false,
"name": "_hexAsset",
"type": {
"display_name": [
"String"
],
"type": 5
}
}
],
"docs": [
""
],
"name": "addedAsset"
},
{
"args": [
{
"indexed": false,
"name": "sender",
"type": {
"display_name": [
"AccountId"
],
"type": 4
}
},
{
"indexed": false,
"name": "receiver",
"type": {
"display_name": [
"AccountId"
],
"type": 4
}
},
{
"indexed": false,
"name": "hexOfAsset",
"type": {
"display_name": [
"String"
],
"type": 5
}
}
],
"docs": [
""
],
"name": "assetSent"
}
],
"messages": [
{
"args": [
{
"name": "_user",
"type": {
"display_name": [
"AccountId"
],
"type": 4
}
}
],
"docs": [
""
],
"mutates": false,
"name": "viewBalance",
"payable": false,
"return_type": {
"display_name": [
"u256"
],
"type": 1
},
"selector": "0xc1a13d1a"
},
{
"args": [
{
"name": "_assetHex",
"type": {
"display_name": [
"String"
],
"type": 5
}
}
],
"docs": [
""
],
"mutates": false,
"name": "findOwner",
"payable": false,
"return_type": {
"display_name": [
"AccountId"
],
"type": 4
},
"selector": "0x63560a8e"
},
{
"args": [
{
"name": "_hexAsset",
"type": {
"display_name": [
"String"
],
"type": 5
}
}
],
"docs": [
""
],
"mutates": true,
"name": "addAsset",
"payable": false,
"return_type": null,
"selector": "0xa7c6b52e"
},
{
"args": [],
"docs": [
""
],
"mutates": true,
"name": "receiveAsset",
"payable": false,
"return_type": {
"display_name": [
"String"
],
"type": 5
},
"selector": "0xb2f3b5bc"
},
{
"args": [
{
"name": "_assetHex",
"type": {
"display_name": [
"String"
],
"type": 5
}
},
{
"name": "_receiver",
"type": {
"display_name": [
"AccountId"
],
"type": 4
}
}
],
"docs": [
""
],
"mutates": true,
"name": "sendAsset",
"payable": false,
"return_type": null,
"selector": "0xd6e5288f"
},
{
"args": [
{
"name": "_newUser",
"type": {
"display_name": [
"AccountId"
],
"type": 4
}
}
],
"docs": [
""
],
"mutates": true,
"name": "register",
"payable": false,
"return_type": null,
"selector": "0x4420e486"
}
]
},
"storage": {
"struct": {
"fields": []
}
},
"types": [
{
"def": {
"primitive": "u256"
}
},
{
"def": {
"primitive": "u8"
}
},
{
"def": {
"array": {
"len": 32,
"type": 2
}
}
},
{
"def": {
"composite": {
"fields": [
{
"type": 3
}
]
}
},
"path": [
"AccountId"
]
},
{
"def": {
"primitive": "str"
}
}
]
}
@@ -1,4 +1,5 @@
// Copyright 2017-2020 @polkadot/api-contract authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { default as assetTransfer } from './assetTransfer.json';
export { default as withString } from './withString.json';
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api-derive",
"version": "2.4.1",
"version": "2.5.1",
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
"main": "index.js",
"keywords": [
@@ -28,17 +28,17 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/api": "^2.4.1",
"@polkadot/rpc-core": "^2.4.1",
"@polkadot/rpc-provider": "^2.4.1",
"@polkadot/types": "^2.4.1",
"@polkadot/util": "^3.6.1",
"@polkadot/util-crypto": "^3.6.1",
"@polkadot/api": "^2.5.1",
"@polkadot/rpc-core": "^2.5.1",
"@polkadot/rpc-provider": "^2.5.1",
"@polkadot/types": "^2.5.1",
"@polkadot/util": "^3.7.1",
"@polkadot/util-crypto": "^3.7.1",
"bn.js": "^5.1.3",
"memoizee": "^0.4.14",
"rxjs": "^6.6.3"
},
"devDependencies": {
"@polkadot/keyring": "^3.6.1"
"@polkadot/keyring": "^3.7.1"
}
}
@@ -6,7 +6,7 @@ import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { isU8a, assert } from '@polkadot/util';
import { isU8a, assertReturn } from '@polkadot/util';
import { decodeAddress } from '@polkadot/util-crypto';
import { memo } from '../util';
@@ -23,11 +23,7 @@ function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIn
const accountIndex = api.registry.createType('AccountIndex', decoded);
return api.derive.accounts.indexToId(accountIndex.toString()).pipe(
map((accountId) => {
assert(accountId, 'Unable to retrieve accountId');
return accountId;
})
map((accountId) => assertReturn(accountId, 'Unable to retrieve accountId'))
);
}
+29 -32
View File
@@ -20,9 +20,17 @@ type FlagsIntermediate = [
AccountId | undefined
];
function isIncludedFn (accountId: AccountId | Address | string): (_: AccountId | Address |string) => boolean {
return function (id: AccountId | Address | string): boolean {
return id.toString() === accountId.toString();
function parseFlags (address: AccountId | Address | string | null | undefined, [electionsMembers, councilMembers, technicalCommitteeMembers, societyMembers, sudoKey]: FlagsIntermediate): DeriveAccountFlags {
const isIncluded = (id: AccountId | Address | string) =>
address
? id.toString() === address.toString()
: false;
return {
isCouncil: (electionsMembers?.map(([id]: ITuple<[AccountId, Balance]>) => id) || councilMembers || []).some(isIncluded),
isSociety: (societyMembers || []).some(isIncluded),
isSudo: sudoKey?.toString() === address?.toString(),
isTechCommittee: (technicalCommitteeMembers || []).some(isIncluded)
};
}
@@ -34,35 +42,24 @@ export function flags (instanceId: string, api: ApiInterfaceRx): (address?: Acco
return memo(instanceId, (address?: AccountId | Address | string | null): Observable<DeriveAccountFlags> => {
const councilSection = api.query.electionsPhragmen ? 'electionsPhragmen' : 'elections';
return (
combineLatest([
address && api.query[councilSection]?.members
? api.query[councilSection].members()
: of(undefined),
address && api.query.council?.members
? api.query.council.members()
: of([]),
address && api.query.technicalCommittee?.members
? api.query.technicalCommittee.members()
: of([]),
address && api.query.society?.members
? api.query.society.members()
: of([]),
address && api.query.sudo?.key
? api.query.sudo.key()
: of(undefined)
]) as Observable<FlagsIntermediate>
).pipe(
map(([electionsMembers, councilMembers, technicalCommitteeMembers, societyMembers, sudoKey]): DeriveAccountFlags => {
const isIncluded = address ? isIncludedFn(address) : (): boolean => false;
return {
isCouncil: (electionsMembers?.map(([id]: ITuple<[AccountId, Balance]>) => id) || councilMembers || []).some(isIncluded),
isSociety: (societyMembers || []).some(isIncluded),
isSudo: sudoKey?.toString() === address?.toString(),
isTechCommittee: (technicalCommitteeMembers || []).some(isIncluded)
};
})
return combineLatest<FlagsIntermediate>([
address && api.query[councilSection]?.members
? api.query[councilSection].members()
: of(undefined),
address && api.query.council?.members
? api.query.council.members()
: of([]),
address && api.query.technicalCommittee?.members
? api.query.technicalCommittee.members()
: of([]),
address && api.query.society?.members
? api.query.society.members()
: of([]),
address && api.query.sudo?.key
? api.query.sudo.key()
: of(undefined)
]).pipe(
map((result) => parseFlags(address, result))
);
});
}
+21 -23
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import { ApiInterfaceRx } from '@polkadot/api/types';
import { AccountId, AccountIndex, Address, Balance, Registration } from '@polkadot/types/interfaces';
import { AccountId, AccountIndex, Address, Balance, IdentityInfoAdditional, Registration } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveAccountInfo, DeriveAccountRegistration } from '../types';
@@ -13,6 +13,8 @@ import { u8aToString } from '@polkadot/util';
import { memo } from '../util';
const UNDEF_HEX = { toHex: () => undefined };
function dataAsString (data: Data): string | undefined {
return data.isRaw
? u8aToString(data.asRaw.toU8a(true))
@@ -35,6 +37,19 @@ function retrieveNick (api: ApiInterfaceRx, accountId?: AccountId): Observable<s
);
}
function extractOther (additional: IdentityInfoAdditional[]): Record<string, string> {
return additional.reduce((other: Record<string, string>, [_key, _value]): Record<string, string> => {
const key = dataAsString(_key);
const value = dataAsString(_value);
if (key && value) {
other[key] = value;
}
return other;
}, {});
}
function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [AccountId, Data]): DeriveAccountRegistration {
if (!identityOfOpt?.isSome) {
return { judgements: [] };
@@ -44,32 +59,15 @@ function extractIdentity (identityOfOpt?: Option<Registration>, superOf?: [Accou
const topDisplay = dataAsString(info.display);
return {
display: superOf
? dataAsString(superOf[1]) || topDisplay
: topDisplay,
displayParent: superOf
? topDisplay
: undefined,
display: (superOf && dataAsString(superOf[1])) || topDisplay,
displayParent: superOf && topDisplay,
email: dataAsString(info.email),
image: dataAsString(info.image),
judgements,
legal: dataAsString(info.legal),
other: info.additional.reduce((other: Record<string, string>, [_key, _value]): Record<string, string> => {
const key = dataAsString(_key);
const value = dataAsString(_value);
if (key && value) {
other[key] = value;
}
return other;
}, {}),
parent: superOf
? superOf[0]
: undefined,
pgp: info.pgpFingerprint.isSome
? info.pgpFingerprint.unwrap().toHex()
: undefined,
other: extractOther(info.additional),
parent: superOf && superOf[0],
pgp: info.pgpFingerprint.unwrapOr(UNDEF_HEX).toHex(),
riot: dataAsString(info.riot),
twitter: dataAsString(info.twitter),
web: dataAsString(info.web)
+15 -4
View File
@@ -16,9 +16,16 @@ import { memo } from '../util';
type ResultBalance = [VestingInfo | null, (BalanceLock | BalanceLockTo212)[]];
type Result = [DeriveBalancesAccount, BlockNumber, ResultBalance];
interface AllLocked {
allLocked: boolean,
lockedBalance: Balance,
lockedBreakdown: (BalanceLock | BalanceLockTo212)[],
vestingLocked: Balance
}
const VESTING_ID = '0x76657374696e6720';
function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBalance, frozenFee, frozenMisc, reservedBalance, votingBalance }, bestNumber, [vesting, locks]]: Result): DeriveBalancesAll {
function calcLocked (api: ApiInterfaceRx, bestNumber: BlockNumber, locks: (BalanceLock | BalanceLockTo212)[]): AllLocked {
let lockedBalance = api.registry.createType('Balance');
let lockedBreakdown: (BalanceLock | BalanceLockTo212)[] = [];
let vestingLocked = api.registry.createType('Balance');
@@ -27,18 +34,22 @@ function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBala
if (Array.isArray(locks)) {
// only get the locks that are valid until passed the current block
lockedBreakdown = (locks as BalanceLockTo212[]).filter(({ until }): boolean => !until || (bestNumber && until.gt(bestNumber)));
const notAll = lockedBreakdown.filter(({ amount }) => !amount.isMax());
allLocked = lockedBreakdown.some(({ amount }) => amount.isMax());
vestingLocked = api.registry.createType('Balance', lockedBreakdown.filter(({ id }) => id.eq(VESTING_ID)).reduce((result: BN, { amount }) => result.iadd(amount), new BN(0)));
// get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699
const notAll = lockedBreakdown.filter(({ amount }) => !amount.isMax());
if (notAll.length) {
lockedBalance = api.registry.createType('Balance', bnMax(...notAll.map(({ amount }): Balance => amount)));
}
}
return { allLocked, lockedBalance, lockedBreakdown, vestingLocked };
}
function calcBalances (api: ApiInterfaceRx, [{ accountId, accountNonce, freeBalance, frozenFee, frozenMisc, reservedBalance, votingBalance }, bestNumber, [vesting, locks]]: Result): DeriveBalancesAll {
const { allLocked, lockedBalance, lockedBreakdown, vestingLocked } = calcLocked(api, bestNumber, locks);
// Calculate the vesting balances,
// - offset = balance locked at startingBlock
// - perBlock is the unlock amount
+34 -14
View File
@@ -12,14 +12,14 @@ import { isFunction } from '@polkadot/util';
import { memo } from '../util';
type Result = [Hash[], Option<Proposal>[], Option<Votes>[]];
type Result = [(Hash | Uint8Array | string)[], Option<Proposal>[], Option<Votes>[]];
function parse ([hashes, proposals, votes]: Result): DeriveCollectiveProposal[] {
function parse (api: ApiInterfaceRx, [hashes, proposals, votes]: Result): DeriveCollectiveProposal[] {
return proposals
.map((proposalOpt, index): DeriveCollectiveProposal | null =>
proposalOpt.isSome
? {
hash: hashes[index],
hash: api.registry.createType('Hash', hashes[index]),
proposal: proposalOpt.unwrap(),
votes: votes[index].unwrapOr(null)
}
@@ -28,21 +28,41 @@ function parse ([hashes, proposals, votes]: Result): DeriveCollectiveProposal[]
.filter((proposal): proposal is DeriveCollectiveProposal => !!proposal);
}
export function proposals (instanceId: string, api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable<DeriveCollectiveProposal[]> {
function _proposalsFrom (instanceId: string, api: ApiInterfaceRx, section: 'council' | 'technicalCommittee' = 'council'): (hashes: (Hash | Uint8Array | string)[]) => Observable<DeriveCollectiveProposal[]> {
return memo(instanceId, (hashes: (Hash | Uint8Array | string)[]): Observable<DeriveCollectiveProposal[]> =>
(isFunction(api.query[section]?.proposals) && hashes.length
? combineLatest<Result>([
of(hashes),
api.query[section].proposalOf.multi<Option<Proposal>>(hashes),
api.query[section].voting.multi<Option<Votes>>(hashes)
])
: of([[], [], []] as Result)
).pipe(
map((result) => parse(api, result))
)
);
}
export function proposals (instanceId: string, api: ApiInterfaceRx, section: 'council' | 'technicalCommittee' = 'council'): () => Observable<DeriveCollectiveProposal[]> {
const proposalsFrom = _proposalsFrom(instanceId, api, section);
return memo(instanceId, (): Observable<DeriveCollectiveProposal[]> =>
isFunction(api.query[section]?.proposals)
? api.query[section].proposals().pipe(
switchMap((hashes: Hash[]): Observable<Result> =>
hashes.length
? combineLatest([
of(hashes),
api.query[section].proposalOf.multi<Option<Proposal>>(hashes),
api.query[section].voting.multi<Option<Votes>>(hashes)
])
: of([[], [], []])
),
map(parse)
switchMap(proposalsFrom)
)
: of([] as DeriveCollectiveProposal[])
);
}
export function proposal (instanceId: string, api: ApiInterfaceRx, section: 'council' | 'technicalCommittee' = 'council'): (hash: Hash | Uint8Array | string) => Observable<DeriveCollectiveProposal | null> {
const proposalsFrom = _proposalsFrom(instanceId, api, section);
return memo(instanceId, (hash: Hash | Uint8Array | string): Observable<DeriveCollectiveProposal | null> =>
isFunction(api.query[section]?.proposals)
? proposalsFrom([hash]).pipe(
map(([proposal]) => proposal)
)
: of(null)
);
}
+9 -4
View File
@@ -2,12 +2,17 @@
// SPDX-License-Identifier: Apache-2.0
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveCollectiveProposals } from '../types';
import { Hash } from '@polkadot/types/interfaces';
import { DeriveCollectiveProposal } from '../types';
import { Observable } from 'rxjs';
import { proposals as collectiveProposals } from '../collective';
import { proposal as collectiveProposal, proposals as collectiveProposals } from '../collective';
import { memo } from '../util';
export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable<DeriveCollectiveProposals> {
return memo(instanceId, collectiveProposals(instanceId, api, 'council'));
export function proposal (instanceId: string, api: ApiInterfaceRx): (hash: Hash | Uint8Array | string) => Observable<DeriveCollectiveProposal | null> {
return memo(instanceId, collectiveProposal(instanceId, api));
}
export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable<DeriveCollectiveProposal[]> {
return memo(instanceId, collectiveProposals(instanceId, api));
}
+14 -15
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { AccountId, ReferendumInfo, ReferendumInfoTo239, VotingDelegating, VotingDirect, VotingDirectVote } from '@polkadot/types/interfaces';
import { AccountId, ReferendumInfo, ReferendumInfoFinished, ReferendumInfoTo239, Vote, VotingDelegating, VotingDirect, VotingDirectVote } from '@polkadot/types/interfaces';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveDemocracyLock } from '../types';
@@ -9,27 +9,26 @@ import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { isUndefined } from '@polkadot/util';
import { BN_ZERO, isUndefined } from '@polkadot/util';
import { memo } from '../util';
const LOCKUPS = [0, 1, 2, 4, 8, 16, 32];
const ZERO = new BN(0);
function parseEnd (api: ApiInterfaceRx, vote: Vote, { approved, end }: ReferendumInfoFinished): [BN, BN] {
return [
end,
(approved.isTrue && vote.isAye) || (approved.isFalse && vote.isNay)
? end.add(api.consts.democracy.enactmentPeriod.muln(LOCKUPS[vote.conviction.index]))
: BN_ZERO
];
}
function parseLock (api: ApiInterfaceRx, [referendumId, accountVote]: VotingDirectVote, referendum: ReferendumInfo): DeriveDemocracyLock {
const { balance, vote } = accountVote.asStandard;
let unlockAt = ZERO;
let referendumEnd = ZERO;
if (referendum.isFinished) {
const { approved, end } = referendum.asFinished;
referendumEnd = end;
if ((approved.isTrue && vote.isAye) || (approved.isFalse && vote.isNay)) {
unlockAt = end.add(api.consts.democracy.enactmentPeriod.muln(LOCKUPS[vote.conviction.index]));
}
}
const [referendumEnd, unlockAt] = referendum.isFinished
? parseEnd(api, vote, referendum.asFinished)
: [BN_ZERO, BN_ZERO];
return { balance, isDelegated: false, isFinished: referendum.isFinished, referendumEnd, referendumId, unlockAt, vote };
}
@@ -40,31 +40,35 @@ function votesPrev (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveRef
);
}
function extractVotes (mapped: [AccountId, Voting][], referendumId: BN): DeriveReferendumVote[] {
return mapped
.filter(([, voting]) => voting.isDirect)
.map(([accountId, voting]): [AccountId, VotingDirectVote[]] => [
accountId,
voting.asDirect.votes.filter(([idx]) => idx.eq(referendumId))
])
.filter(([, directVotes]) => !!directVotes.length)
.reduce((result: DeriveReferendumVote[], [accountId, votes]) =>
// FIXME We are ignoring split votes
votes.reduce((result: DeriveReferendumVote[], [, vote]): DeriveReferendumVote[] => {
if (vote.isStandard) {
result.push({
accountId,
isDelegating: false,
...vote.asStandard
});
}
return result;
}, result), []
);
}
function votesCurr (api: ApiInterfaceRx, referendumId: BN): Observable<DeriveReferendumVote[]> {
return api.query.democracy.votingOf.entries<Voting>().pipe(
map((allVoting): DeriveReferendumVote[] => {
const mapped = allVoting.map(([key, voting]): [AccountId, Voting] => [key.args[0] as AccountId, voting]);
const votes = mapped
.filter(([, voting]) => voting.isDirect)
.map(([accountId, voting]): [AccountId, VotingDirectVote[]] => [
accountId,
voting.asDirect.votes.filter(([idx]) => idx.eq(referendumId))
])
.filter(([, directVotes]) => !!directVotes.length)
.reduce((result: DeriveReferendumVote[], [accountId, votes]) =>
// FIXME We are ignoring split votes
votes.reduce((result: DeriveReferendumVote[], [, vote]): DeriveReferendumVote[] => {
if (vote.isStandard) {
result.push({
accountId,
isDelegating: false,
...vote.asStandard
});
}
return result;
}, result), []
);
const votes = extractVotes(mapped, referendumId);
const delegations = mapped
.filter(([, voting]) => voting.isDelegating)
.map(([accountId, voting]): [AccountId, VotingDelegating] => [accountId, voting.asDelegating]);
+11 -16
View File
@@ -58,16 +58,20 @@ export function compareRationals (n1: BN, d1: BN, n2: BN, d2: BN): boolean {
}
}
export function calcPassing (threshold: VoteThreshold, sqrtElectorate: BN, { votedAye, votedNay, votedTotal }: ApproxState): boolean {
function calcPassingOther (threshold: VoteThreshold, sqrtElectorate: BN, { votedAye, votedNay, votedTotal }: ApproxState): boolean {
const sqrtVoters = bnSqrt(votedTotal);
return sqrtVoters.isZero()
? false
: threshold.isSimplemajority
? votedAye.gt(votedNay)
: threshold.isSupermajorityapproval
? compareRationals(votedNay, sqrtVoters, votedAye, sqrtElectorate)
: compareRationals(votedNay, sqrtElectorate, votedAye, sqrtVoters);
: threshold.isSupermajorityapproval
? compareRationals(votedNay, sqrtVoters, votedAye, sqrtElectorate)
: compareRationals(votedNay, sqrtElectorate, votedAye, sqrtVoters);
}
export function calcPassing (threshold: VoteThreshold, sqrtElectorate: BN, state: ApproxState): boolean {
return threshold.isSimplemajority
? state.votedAye.gt(state.votedNay)
: calcPassingOther(threshold, sqrtElectorate, state);
}
function calcVotesPrev (votesFor: DeriveReferendumVote[]): DeriveReferendumVoteState {
@@ -92,16 +96,7 @@ function calcVotesPrev (votesFor: DeriveReferendumVote[]): DeriveReferendumVoteS
state.votedTotal.iadd(counted);
return state;
}, {
allAye: [],
allNay: [],
voteCount: 0,
voteCountAye: 0,
voteCountNay: 0,
votedAye: new BN(0),
votedNay: new BN(0),
votedTotal: new BN(0)
});
}, { allAye: [], allNay: [], voteCount: 0, voteCountAye: 0, voteCountNay: 0, votedAye: new BN(0), votedNay: new BN(0), votedTotal: new BN(0) });
}
function calcVotesCurrent (tally: Tally, votes: DeriveReferendumVote[]): DeriveReferendumVoteState {
+7 -9
View File
@@ -10,6 +10,7 @@ import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { memo } from '../util';
import { didUpdateToBool } from './util';
type Result = [
Active,
@@ -23,7 +24,7 @@ type Result = [
];
function parseActive (id: ParaId, active: Active): DeriveParachainActive | null {
const found = active.find(([paraId]): boolean => paraId === id);
const found = active.find(([paraId]) => paraId === id);
if (found && found[1].isSome) {
const [collatorId, retriable] = found[1].unwrap();
@@ -48,12 +49,11 @@ function parseActive (id: ParaId, active: Active): DeriveParachainActive | null
}
function parseCollators (id: ParaId, collatorQueue: SelectedThreads | RetryQueue): (CollatorId | null)[] {
return collatorQueue
.map((queue): CollatorId | null => {
const found = queue.find(([paraId]): boolean => paraId === id);
return collatorQueue.map((queue): CollatorId | null => {
const found = queue.find(([paraId]) => paraId === id);
return found ? found[1] : null;
});
return found ? found[1] : null;
});
}
function parse (id: ParaId, [active, retryQueue, selectedThreads, didUpdate, info, pendingSwap, heads, relayDispatchQueue]: Result): DeriveParachainFull | null {
@@ -63,9 +63,7 @@ function parse (id: ParaId, [active, retryQueue, selectedThreads, didUpdate, inf
return {
active: parseActive(id, active),
didUpdate: didUpdate.isSome
? !!didUpdate.unwrap().some((paraId): boolean => paraId.eq(id))
: false,
didUpdate: didUpdateToBool(didUpdate, id),
heads,
id,
info: { id, ...info.unwrap() } as DeriveParachainInfo,
+9 -14
View File
@@ -10,6 +10,7 @@ import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { memo } from '../util';
import { didUpdateToBool } from './util';
type Result = [
ParaId[],
@@ -20,17 +21,13 @@ type Result = [
];
function parse ([ids, didUpdate, infos, pendingSwaps, relayDispatchQueueSizes]: Result): DeriveParachain[] {
return ids.map((id, index): DeriveParachain => {
return {
didUpdate: didUpdate.isSome
? !!didUpdate.unwrap().some((paraId): boolean => paraId.eq(id))
: false,
id,
info: { id, ...infos[index].unwrapOr(null) } as DeriveParachainInfo,
pendingSwapId: pendingSwaps[index].unwrapOr(null),
relayDispatchQueueSize: relayDispatchQueueSizes[index][0].toNumber()
};
});
return ids.map((id, index): DeriveParachain => ({
didUpdate: didUpdateToBool(didUpdate, id),
id,
info: { id, ...infos[index].unwrapOr(null) } as DeriveParachainInfo,
pendingSwapId: pendingSwaps[index].unwrapOr(null),
relayDispatchQueueSize: relayDispatchQueueSizes[index][0].toNumber()
}));
}
export function overview (instanceId: string, api: ApiInterfaceRx): () => Observable<DeriveParachain[]> {
@@ -46,9 +43,7 @@ export function overview (instanceId: string, api: ApiInterfaceRx): () => Observ
api.query.parachains.relayDispatchQueueSize.multi<RelayDispatchQueueSize>(paraIds)
])
),
map((result: Result): DeriveParachain[] =>
parse(result)
)
map(parse)
)
: of([] as DeriveParachain[])
);
@@ -0,0 +1,11 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { ParaId } from '@polkadot/types/interfaces';
import { DidUpdate } from './types';
export function didUpdateToBool (didUpdate: DidUpdate, id: ParaId): boolean {
return didUpdate.isSome
? didUpdate.unwrap().some((paraId) => paraId.eq(id))
: false;
}
@@ -10,6 +10,7 @@ import { map, switchMap } from 'rxjs/operators';
import { BN_ZERO } from '@polkadot/util';
import { deriveCache, memo } from '../util';
import { filterEras } from './util';
const CACHE_KEY = 'eraPoints';
@@ -42,7 +43,7 @@ export function _erasPoints (instanceId: string, api: ApiInterfaceRx): (eras: Er
: eras
.map((era) => deriveCache.get<DeriveEraPoints>(`${CACHE_KEY}-${era.toString()}`))
.filter((value): value is DeriveEraPoints => !!value);
const remaining = eras.filter((era) => !cached.some((cached) => era.eq(cached.era)));
const remaining = filterEras(eras, cached);
return !remaining.length
? of(cached)
@@ -10,6 +10,7 @@ import { map, switchMap } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { deriveCache, memo } from '../util';
import { filterEras } from './util';
const CACHE_KEY = 'eraRewards';
@@ -31,7 +32,7 @@ export function _erasRewards (instanceId: string, api: ApiInterfaceRx): (eras: E
: eras
.map((era) => deriveCache.get<DeriveEraRewards>(`${CACHE_KEY}-${era.toString()}`))
.filter((value): value is DeriveEraRewards => !!value);
const remaining = eras.filter((era) => !cached.some((cached) => era.eq(cached.era)));
const remaining = filterEras(eras, cached);
if (!remaining.length) {
return of(cached);
@@ -12,6 +12,7 @@ import { Option } from '@polkadot/types';
import { isFunction } from '@polkadot/util';
import { memo } from '../util';
import { DeriveStakingQuery } from './types';
type ErasResult = [{ unwrapOr: (value: BN) => BN }, DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[]];
@@ -99,24 +100,37 @@ function filterEras (eras: EraIndex[], stakingLedger: StakingLedger): EraIndex[]
return eras.filter((era) => filterEra(era, stakingLedger));
}
function filterRewards (api: ApiInterfaceRx, eras: EraIndex[], migrateEra: BN, rewards: DeriveStakerReward[], stakingLedger: StakingLedger, withActive: boolean): Observable<DeriveStakerReward[]> {
if (withActive) {
return of(rewards);
}
function removeClaimed (validators: string[], queryValidators: DeriveStakingQuery[], reward: DeriveStakerReward): void {
const rm: string[] = [];
Object.keys(reward.validators).forEach((validatorId): void => {
const index = validators.indexOf(validatorId);
if (index !== -1) {
const valLedger = queryValidators[index].stakingLedger;
if (valLedger?.claimedRewards.some((era) => reward.era.eq(era))) {
rm.push(validatorId);
}
}
});
rm.forEach((validatorId): void => {
delete reward.validators[validatorId];
});
}
function filterRewards (api: ApiInterfaceRx, eras: EraIndex[], { migrateEra, rewards, stakingLedger }: { migrateEra: BN, rewards: DeriveStakerReward[]; stakingLedger: StakingLedger }): Observable<DeriveStakerReward[]> {
const validators = uniqValidators(rewards);
const filter = filterEras(eras, stakingLedger);
return (
isFunction(api.tx.staking.payoutStakers)
? api.derive.staking.queryMulti(validators)
: of([])
).pipe(
map((queryValidators): DeriveStakerReward[] => {
const filter = withActive
? eras
: filterEras(eras, stakingLedger);
return rewards
map((queryValidators): DeriveStakerReward[] =>
rewards
.filter(({ isEmpty }) => !isEmpty)
.filter((reward): boolean => {
if (!filter.some((filter) => reward.era.eq(filter))) {
@@ -128,32 +142,16 @@ function filterRewards (api: ApiInterfaceRx, eras: EraIndex[], migrateEra: BN, r
reward.isStakerPayout = true;
const rm: string[] = [];
Object.keys(reward.validators).forEach((validatorId): void => {
const index = validators.indexOf(validatorId);
if (index !== -1) {
const valLedger = queryValidators[index].stakingLedger;
if (valLedger?.claimedRewards.some((era) => reward.era.eq(era))) {
rm.push(validatorId);
}
}
});
rm.forEach((validatorId): void => {
delete reward.validators[validatorId];
});
removeClaimed(validators, queryValidators, reward);
return true;
})
.filter(({ validators }) => Object.keys(validators).length !== 0)
.map((reward) => ({
...reward,
nominators: reward.nominating.filter(({ validatorId }) => !!reward.validators[validatorId])
}));
})
nominators: reward.nominating.filter((n) => !!reward.validators[n.validatorId])
}))
)
);
}
@@ -178,13 +176,15 @@ export function _stakerRewards (instanceId: string, api: ApiInterfaceRx): (accou
api.derive.staking._stakerRewardsEras(eras, withActive)
]).pipe(
switchMap(([{ stakingLedger, stashId }, exposures, erasResult]): Observable<DeriveStakerReward[]> => {
const migrateEra: BN = erasResult[0].unwrapOr(ZERO);
if (!stashId || !stakingLedger) {
return of([]);
}
return filterRewards(api, eras, migrateEra, parseRewards(api, stashId, erasResult, exposures), stakingLedger, withActive);
const rewards = parseRewards(api, stashId, erasResult, exposures);
return withActive
? of(rewards)
: filterRewards(api, eras, { migrateEra: erasResult[0].unwrapOr(ZERO), rewards, stakingLedger });
})
)
);
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { EraIndex } from '@polkadot/types/interfaces';
export function filterEras <T extends { era: EraIndex }> (eras: EraIndex[], list: T[]): EraIndex[] {
return eras.filter((era) => !list.some((entry) => era.eq(entry.era)));
}
@@ -2,12 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DeriveCollectiveProposals } from '../types';
import { DeriveCollectiveProposal } from '../types';
import { Observable } from 'rxjs';
import { proposals as collectiveProposals } from '../collective';
import { memo } from '../util';
export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable<DeriveCollectiveProposals> {
export function proposals (instanceId: string, api: ApiInterfaceRx): () => Observable<DeriveCollectiveProposal[]> {
return memo(instanceId, collectiveProposals(instanceId, api, 'technicalCommittee'));
}
@@ -3,7 +3,7 @@
import { ApiInterfaceRx } from '@polkadot/api/types';
import { ProposalIndex, TreasuryProposal } from '@polkadot/types/interfaces';
import { DeriveCollectiveProposals, DeriveTreasuryProposal, DeriveTreasuryProposals } from '../types';
import { DeriveCollectiveProposal, DeriveTreasuryProposal, DeriveTreasuryProposals } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
@@ -15,7 +15,7 @@ interface Result {
allIds: ProposalIndex[];
allProposals: Option<TreasuryProposal>[];
approvalIds: ProposalIndex[];
councilProposals: DeriveCollectiveProposals;
councilProposals: DeriveCollectiveProposal[];
proposalCount: ProposalIndex;
}
@@ -51,9 +51,7 @@ function retrieveProposals (api: ApiInterfaceRx, proposalCount: ProposalIndex, a
const count = proposalCount.toNumber();
for (let index = 0; index < count; index++) {
const isApproval = approvalIds.some((id): boolean => id.eqn(index));
if (!isApproval) {
if (!approvalIds.some((id) => id.eqn(index))) {
proposalIds.push(api.registry.createType('ProposalIndex', index));
}
}
@@ -64,7 +62,7 @@ function retrieveProposals (api: ApiInterfaceRx, proposalCount: ProposalIndex, a
api.query.treasury.proposals.multi<Option<TreasuryProposal>>(allIds),
api.derive.council.proposals()
]).pipe(
map(([allProposals, councilProposals]: [Option<TreasuryProposal>[], DeriveCollectiveProposals]): DeriveTreasuryProposals =>
map(([allProposals, councilProposals]: [Option<TreasuryProposal>[], DeriveCollectiveProposal[]]): DeriveTreasuryProposals =>
parseResult(api, { allIds, allProposals, approvalIds, councilProposals, proposalCount })
)
);
@@ -36,9 +36,9 @@ export default class HeaderExtended extends _Header {
/**
* @description Creates a human-friendly JSON representation
*/
public toHuman (isExtended?: boolean): AnyJson {
public toHuman (isExtended?: boolean): Record<string, AnyJson> {
return {
...super.toHuman(isExtended) as { [index: string]: AnyJson },
...super.toHuman(isExtended),
author: this.author
? this.author.toHuman()
: undefined
@@ -48,9 +48,9 @@ export default class HeaderExtended extends _Header {
/**
* @description Creates the JSON representation
*/
public toJSON (): AnyJson {
public toJSON (): Record<string, AnyJson> {
return {
...super.toJSON() as { [index: string]: AnyJson },
...super.toJSON(),
author: this.author
? this.author.toJSON()
: undefined
@@ -36,9 +36,9 @@ export default class BlockExtended extends _SignedBlock {
/**
* @description Creates a human-friendly JSON representation
*/
public toHuman (isExtended?: boolean): AnyJson {
public toHuman (isExtended?: boolean): Record<string, AnyJson> {
return {
...super.toHuman(isExtended) as { [index: string]: AnyJson },
...super.toHuman(isExtended),
author: this.author
? this.author.toHuman()
: undefined
@@ -48,9 +48,9 @@ export default class BlockExtended extends _SignedBlock {
/**
* @description Creates the JSON representation
*/
public toJSON (): AnyJson {
public toJSON (): Record<string, AnyJson> {
return {
...super.toJSON() as { [index: string]: AnyJson },
...super.toJSON(),
author: this.author
? this.author.toJSON()
: undefined
-2
View File
@@ -60,8 +60,6 @@ export interface DeriveCollectiveProposal {
votes: Votes | null;
}
export type DeriveCollectiveProposals = DeriveCollectiveProposal[];
export interface DeriveFees {
creationFee: Balance;
existentialDeposit: Balance;
+11 -11
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/api",
"version": "2.4.1",
"version": "2.5.1",
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
"main": "index.js",
"keywords": [
@@ -27,20 +27,20 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/api-derive": "^2.4.1",
"@polkadot/keyring": "^3.6.1",
"@polkadot/metadata": "^2.4.1",
"@polkadot/rpc-core": "^2.4.1",
"@polkadot/rpc-provider": "^2.4.1",
"@polkadot/types": "^2.4.1",
"@polkadot/types-known": "^2.4.1",
"@polkadot/util": "^3.6.1",
"@polkadot/util-crypto": "^3.6.1",
"@polkadot/api-derive": "^2.5.1",
"@polkadot/keyring": "^3.7.1",
"@polkadot/metadata": "^2.5.1",
"@polkadot/rpc-core": "^2.5.1",
"@polkadot/rpc-provider": "^2.5.1",
"@polkadot/types": "^2.5.1",
"@polkadot/types-known": "^2.5.1",
"@polkadot/util": "^3.7.1",
"@polkadot/util-crypto": "^3.7.1",
"bn.js": "^5.1.3",
"eventemitter3": "^4.0.7",
"rxjs": "^6.6.3"
},
"devDependencies": {
"@polkadot/keyring": "^3.6.1"
"@polkadot/keyring": "^3.7.1"
}
}
+14 -4
View File
@@ -2,7 +2,7 @@
/* eslint-disable */
import { AnyNumber, Codec, IExtrinsic, Observable } from '@polkadot/types/types';
import { HashMap, Option, Vec } from '@polkadot/types/codec';
import { HashMap, Json, Option, Vec } from '@polkadot/types/codec';
import { Bytes, Null, StorageKey, Text, bool, u32, u64 } from '@polkadot/types/primitive';
import { Metadata } from '@polkadot/types';
import { ExtrinsicOrHash, ExtrinsicStatus } from '@polkadot/types/interfaces/author';
@@ -19,7 +19,7 @@ import { RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';
import { RpcMethods } from '@polkadot/types/interfaces/rpc';
import { AccountId, BlockNumber, H256, Hash, Header, Index, Justification, KeyValue, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';
import { ReadProof, RuntimeVersion } from '@polkadot/types/interfaces/state';
import { ApplyExtrinsicResult, ChainProperties, ChainType, Health, NetworkState, NodeRole, PeerInfo } from '@polkadot/types/interfaces/system';
import { ApplyExtrinsicResult, ChainProperties, ChainType, Health, NetworkState, NodeRole, PeerInfo, SyncState } from '@polkadot/types/interfaces/system';
declare module '@polkadot/rpc-core/types.jsonrpc' {
export interface RpcInterface {
@@ -153,11 +153,11 @@ declare module '@polkadot/rpc-core/types.jsonrpc' {
/**
* Get offchain local storage under given key and prefix
**/
localStorageGet: AugmentedRpc<(kind: StorageKind | '__UNUSED'|'PERSISTENT'|'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array) => Observable<Option<Bytes>>>;
localStorageGet: AugmentedRpc<(kind: StorageKind | '__UNUSED' | 'PERSISTENT' | 'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array) => Observable<Option<Bytes>>>;
/**
* Set offchain local storage under given key and prefix
**/
localStorageSet: AugmentedRpc<(kind: StorageKind | '__UNUSED'|'PERSISTENT'|'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array, value: Bytes | string | Uint8Array) => Observable<Null>>;
localStorageSet: AugmentedRpc<(kind: StorageKind | '__UNUSED' | 'PERSISTENT' | 'LOCAL' | number | Uint8Array, key: Bytes | string | Uint8Array, value: Bytes | string | Uint8Array) => Observable<Null>>;
};
payment: {
/**
@@ -245,6 +245,12 @@ declare module '@polkadot/rpc-core/types.jsonrpc' {
**/
subscribeStorage: AugmentedRpc<<T = Codec[]>(keys?: Vec<StorageKey> | (StorageKey | string | Uint8Array | any)[]) => Observable<T>>;
};
syncstate: {
/**
* Returns the json-serialized chainspec running the node, with a sync state.
**/
genSyncSpec: AugmentedRpc<(raw: bool | boolean | Uint8Array) => Observable<Json>>;
};
system: {
/**
* Retrieves the next accountIndex as available on the node
@@ -302,6 +308,10 @@ declare module '@polkadot/rpc-core/types.jsonrpc' {
* Remove a reserved peer
**/
removeReservedPeer: AugmentedRpc<(peerId: Text | string) => Observable<Text>>;
/**
* Returns the state of the syncing of the node
**/
syncState: AugmentedRpc<() => Observable<SyncState>>;
/**
* Retrieves the version of the node
**/
+29 -29
View File
@@ -65,7 +65,7 @@ declare module '@polkadot/api/types/submittable' {
* not assumed to be in the overlay.
* # </weight>
**/
forceTransfer: AugmentedSubmittable<(source: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, dest: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, value: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
forceTransfer: AugmentedSubmittable<(source: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, dest: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, value: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Set the balances of a given account.
*
@@ -86,7 +86,7 @@ declare module '@polkadot/api/types/submittable' {
* - DB Weight: 1 Read, 1 Write to `who`
* # </weight>
**/
setBalance: AugmentedSubmittable<(who: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, newFree: Compact<Balance> | AnyNumber | Uint8Array, newReserved: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
setBalance: AugmentedSubmittable<(who: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, newFree: Compact<Balance> | AnyNumber | Uint8Array, newReserved: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Transfer some liquid free balance to another account.
*
@@ -116,7 +116,7 @@ declare module '@polkadot/api/types/submittable' {
* - Origin account is already in memory, so no DB operations for them.
* # </weight>
**/
transfer: AugmentedSubmittable<(dest: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, value: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
transfer: AugmentedSubmittable<(dest: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, value: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Same as the [`transfer`] call, but with a check that the transfer will not kill the
* origin account.
@@ -130,7 +130,7 @@ declare module '@polkadot/api/types/submittable' {
* - DB Weight: 1 Read and 1 Write to dest (sender is in overlay already)
* #</weight>
**/
transferKeepAlive: AugmentedSubmittable<(dest: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, value: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
transferKeepAlive: AugmentedSubmittable<(dest: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, value: Compact<Balance> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
};
contracts: {
[key: string]: SubmittableExtrinsicFunction<ApiType>;
@@ -143,7 +143,7 @@ declare module '@polkadot/api/types/submittable' {
* * If no account exists and the call value is not less than `existential_deposit`,
* a regular account will be created and any value will be transferred.
**/
call: AugmentedSubmittable<(dest: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, value: Compact<BalanceOf> | AnyNumber | Uint8Array, gasLimit: Compact<Gas> | AnyNumber | Uint8Array, data: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
call: AugmentedSubmittable<(dest: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, value: Compact<BalanceOf> | AnyNumber | Uint8Array, gasLimit: Compact<Gas> | AnyNumber | Uint8Array, data: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Allows block producers to claim a small reward for evicting a contract. If a block producer
* fails to do so, a regular users will be allowed to claim the reward.
@@ -391,7 +391,7 @@ declare module '@polkadot/api/types/submittable' {
* Weight: `O(R)` where R is the number of referendums the voter delegating to has
* voted on. Weight is charged as if maximum votes.
**/
delegate: AugmentedSubmittable<(to: AccountId | string | Uint8Array, conviction: Conviction | 'None'|'Locked1x'|'Locked2x'|'Locked3x'|'Locked4x'|'Locked5x'|'Locked6x' | number | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
delegate: AugmentedSubmittable<(to: AccountId | string | Uint8Array, conviction: Conviction | 'None' | 'Locked1x' | 'Locked2x' | 'Locked3x' | 'Locked4x' | 'Locked5x' | 'Locked6x' | number | Uint8Array, balance: BalanceOf | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Schedule an emergency cancellation of a referendum. Cannot happen twice to the same
* referendum.
@@ -666,7 +666,7 @@ declare module '@polkadot/api/types/submittable' {
* Else, since this is a root call and will go into phragmen, we assume full block for now.
* # </weight>
**/
removeMember: AugmentedSubmittable<(who: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, hasReplacement: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>>;
removeMember: AugmentedSubmittable<(who: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, hasReplacement: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Remove `origin` as a voter. This removes the lock and returns the bond.
*
@@ -872,7 +872,7 @@ declare module '@polkadot/api/types/submittable' {
* The dispatch origin for this call must be _Signed_ and the sender must have a registered
* sub identity of `sub`.
**/
addSub: AugmentedSubmittable<(sub: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, data: Data | { None: any } | { Raw: any } | { BlakeTwo256: any } | { Sha256: any } | { Keccak256: any } | { ShaThree256: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
addSub: AugmentedSubmittable<(sub: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, data: Data | { None: any } | { Raw: any } | { BlakeTwo256: any } | { Sha256: any } | { Keccak256: any } | { ShaThree256: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Cancel a previous request.
*
@@ -935,7 +935,7 @@ declare module '@polkadot/api/types/submittable' {
* - One event.
* # </weight>
**/
killIdentity: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
killIdentity: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Provide a judgement for an account's identity.
*
@@ -957,7 +957,7 @@ declare module '@polkadot/api/types/submittable' {
* - One event.
* # </weight>
**/
provideJudgement: AugmentedSubmittable<(regIndex: Compact<RegistrarIndex> | AnyNumber | Uint8Array, target: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, judgement: IdentityJudgement | { Unknown: any } | { FeePaid: any } | { Reasonable: any } | { KnownGood: any } | { OutOfDate: any } | { LowQuality: any } | { Erroneous: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
provideJudgement: AugmentedSubmittable<(regIndex: Compact<RegistrarIndex> | AnyNumber | Uint8Array, target: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, judgement: IdentityJudgement | { Unknown: any } | { FeePaid: any } | { Reasonable: any } | { KnownGood: any } | { OutOfDate: any } | { LowQuality: any } | { Erroneous: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Remove the sender as a sub-account.
*
@@ -980,14 +980,14 @@ declare module '@polkadot/api/types/submittable' {
* The dispatch origin for this call must be _Signed_ and the sender must have a registered
* sub identity of `sub`.
**/
removeSub: AugmentedSubmittable<(sub: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
removeSub: AugmentedSubmittable<(sub: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Alter the associated name of the given sub-account.
*
* The dispatch origin for this call must be _Signed_ and the sender must have a registered
* sub identity of `sub`.
**/
renameSub: AugmentedSubmittable<(sub: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, data: Data | { None: any } | { Raw: any } | { BlakeTwo256: any } | { Sha256: any } | { Keccak256: any } | { ShaThree256: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
renameSub: AugmentedSubmittable<(sub: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, data: Data | { None: any } | { Raw: any } | { BlakeTwo256: any } | { Sha256: any } | { Keccak256: any } | { ShaThree256: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Request a judgement from a registrar.
*
@@ -1392,7 +1392,7 @@ declare module '@polkadot/api/types/submittable' {
* Weight is a function of the number of proxies the user has (P).
* # </weight>
**/
addProxy: AugmentedSubmittable<(delegate: AccountId | string | Uint8Array, proxyType: ProxyType | 'Any'|'NonTransfer'|'Governance'|'Staking' | number | Uint8Array, delay: BlockNumber | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
addProxy: AugmentedSubmittable<(delegate: AccountId | string | Uint8Array, proxyType: ProxyType | 'Any' | 'NonTransfer' | 'Governance' | 'Staking' | number | Uint8Array, delay: BlockNumber | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Publish the hash of a proxy-call that will be made in the future.
*
@@ -1442,7 +1442,7 @@ declare module '@polkadot/api/types/submittable' {
* # </weight>
* TODO: Might be over counting 1 read
**/
anonymous: AugmentedSubmittable<(proxyType: ProxyType | 'Any'|'NonTransfer'|'Governance'|'Staking' | number | Uint8Array, delay: BlockNumber | AnyNumber | Uint8Array, index: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
anonymous: AugmentedSubmittable<(proxyType: ProxyType | 'Any' | 'NonTransfer' | 'Governance' | 'Staking' | number | Uint8Array, delay: BlockNumber | AnyNumber | Uint8Array, index: u16 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Removes a previously spawned anonymous proxy.
*
@@ -1465,7 +1465,7 @@ declare module '@polkadot/api/types/submittable' {
* Weight is a function of the number of proxies the user has (P).
* # </weight>
**/
killAnonymous: AugmentedSubmittable<(spawner: AccountId | string | Uint8Array, proxyType: ProxyType | 'Any'|'NonTransfer'|'Governance'|'Staking' | number | Uint8Array, index: u16 | AnyNumber | Uint8Array, height: Compact<BlockNumber> | AnyNumber | Uint8Array, extIndex: Compact<u32> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
killAnonymous: AugmentedSubmittable<(spawner: AccountId | string | Uint8Array, proxyType: ProxyType | 'Any' | 'NonTransfer' | 'Governance' | 'Staking' | number | Uint8Array, index: u16 | AnyNumber | Uint8Array, height: Compact<BlockNumber> | AnyNumber | Uint8Array, extIndex: Compact<u32> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Dispatch the given `call` from an account that the sender is authorised for through
* `add_proxy`.
@@ -1568,7 +1568,7 @@ declare module '@polkadot/api/types/submittable' {
* Weight is a function of the number of proxies the user has (P).
* # </weight>
**/
removeProxy: AugmentedSubmittable<(delegate: AccountId | string | Uint8Array, proxyType: ProxyType | 'Any'|'NonTransfer'|'Governance'|'Staking' | number | Uint8Array, delay: BlockNumber | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
removeProxy: AugmentedSubmittable<(delegate: AccountId | string | Uint8Array, proxyType: ProxyType | 'Any' | 'NonTransfer' | 'Governance' | 'Staking' | number | Uint8Array, delay: BlockNumber | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
};
recovery: {
[key: string]: SubmittableExtrinsicFunction<ApiType>;
@@ -1999,7 +1999,7 @@ declare module '@polkadot/api/types/submittable' {
* Total Complexity: O(M + logM + B + X)
* # </weight>
**/
judgeSuspendedCandidate: AugmentedSubmittable<(who: AccountId | string | Uint8Array, judgement: SocietyJudgement | 'Rebid'|'Reject'|'Approve' | number | Uint8Array) => SubmittableExtrinsic<ApiType>>;
judgeSuspendedCandidate: AugmentedSubmittable<(who: AccountId | string | Uint8Array, judgement: SocietyJudgement | 'Rebid' | 'Reject' | 'Approve' | number | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Allow suspension judgement origin to make judgement on a suspended member.
*
@@ -2149,7 +2149,7 @@ declare module '@polkadot/api/types/submittable' {
* Total Complexity: O(M + logM + C)
* # </weight>
**/
vote: AugmentedSubmittable<(candidate: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, approve: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>>;
vote: AugmentedSubmittable<(candidate: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, approve: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* As a member, vouch for someone to join society by placing a bid on their behalf.
*
@@ -2224,7 +2224,7 @@ declare module '@polkadot/api/types/submittable' {
* - Write: Bonded, Payee, [Origin Account], Locks, Ledger
* # </weight>
**/
bond: AugmentedSubmittable<(controller: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, value: Compact<BalanceOf> | AnyNumber | Uint8Array, payee: RewardDestination | { Staked: any } | { Stash: any } | { Controller: any } | { Account: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
bond: AugmentedSubmittable<(controller: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, value: Compact<BalanceOf> | AnyNumber | Uint8Array, payee: RewardDestination | { Staked: any } | { Stash: any } | { Controller: any } | { Account: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Add some extra amount that have appeared in the stash `free_balance` into the balance up
* for staking.
@@ -2365,7 +2365,7 @@ declare module '@polkadot/api/types/submittable' {
* - Writes: Validators, Nominators
* # </weight>
**/
nominate: AugmentedSubmittable<(targets: Vec<LookupSource> | (LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>>;
nominate: AugmentedSubmittable<(targets: Vec<LookupSource> | (LookupSource | Address | AccountId | AccountIndex | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>>;
/**
* Pay out all the stakers behind a single validator for a single era.
*
@@ -2460,7 +2460,7 @@ declare module '@polkadot/api/types/submittable' {
* - Write: Bonded, Ledger New Controller, Ledger Old Controller
* # </weight>
**/
setController: AugmentedSubmittable<(controller: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
setController: AugmentedSubmittable<(controller: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Set `HistoryDepth` value. This function will delete any history information
* when `HistoryDepth` is reduced.
@@ -2693,7 +2693,7 @@ declare module '@polkadot/api/types/submittable' {
* - One DB change.
* # </weight>
**/
setKey: AugmentedSubmittable<(updated: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
setKey: AugmentedSubmittable<(updated: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Authenticates the sudo key and dispatches a function call with `Root` origin.
*
@@ -2720,7 +2720,7 @@ declare module '@polkadot/api/types/submittable' {
* - Weight of derivative `call` execution + 10,000.
* # </weight>
**/
sudoAs: AugmentedSubmittable<(who: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, call: Call | { callIndex?: any; args?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
sudoAs: AugmentedSubmittable<(who: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, call: Call | { callIndex?: any; args?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Authenticates the sudo key and dispatches a function call with `Root` origin.
* This function does not check the weight of the call, and instead allows the
@@ -3103,7 +3103,7 @@ declare module '@polkadot/api/types/submittable' {
* - `bounty_id`: Bounty ID to award.
* - `beneficiary`: The beneficiary account whom will receive the payout.
**/
awardBounty: AugmentedSubmittable<(bountyId: Compact<ProposalIndex> | AnyNumber | Uint8Array, beneficiary: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
awardBounty: AugmentedSubmittable<(bountyId: Compact<ProposalIndex> | AnyNumber | Uint8Array, beneficiary: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Claim the payout from an awarded bounty after payout delay.
*
@@ -3176,7 +3176,7 @@ declare module '@polkadot/api/types/submittable' {
* - One DB change.
* # </weight>
**/
proposeCurator: AugmentedSubmittable<(bountyId: Compact<ProposalIndex> | AnyNumber | Uint8Array, curator: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, fee: Compact<BalanceOf> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
proposeCurator: AugmentedSubmittable<(bountyId: Compact<ProposalIndex> | AnyNumber | Uint8Array, curator: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, fee: Compact<BalanceOf> | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Put forward a suggestion for spending. A deposit proportional to the value
* is reserved and slashed if the proposal is rejected. It is returned once the
@@ -3188,7 +3188,7 @@ declare module '@polkadot/api/types/submittable' {
* - DbWrites: `ProposalCount`, `Proposals`, `origin account`
* # </weight>
**/
proposeSpend: AugmentedSubmittable<(value: Compact<BalanceOf> | AnyNumber | Uint8Array, beneficiary: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
proposeSpend: AugmentedSubmittable<(value: Compact<BalanceOf> | AnyNumber | Uint8Array, beneficiary: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Reject a proposed spend. The original deposit will be slashed.
*
@@ -3385,7 +3385,7 @@ declare module '@polkadot/api/types/submittable' {
* - Writes: Vesting Storage, Balances Locks, Target Account, Source Account
* # </weight>
**/
forceVestedTransfer: AugmentedSubmittable<(source: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, target: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, schedule: VestingInfo | { locked?: any; perBlock?: any; startingBlock?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
forceVestedTransfer: AugmentedSubmittable<(source: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, target: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, schedule: VestingInfo | { locked?: any; perBlock?: any; startingBlock?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Unlock any vested funds of the sender account.
*
@@ -3419,7 +3419,7 @@ declare module '@polkadot/api/types/submittable' {
* - Writes: Vesting Storage, Balances Locks, Target Account
* # </weight>
**/
vestOther: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
vestOther: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
/**
* Create a vested transfer.
*
@@ -3438,7 +3438,7 @@ declare module '@polkadot/api/types/submittable' {
* - Writes: Vesting Storage, Balances Locks, Target Account, [Sender Account]
* # </weight>
**/
vestedTransfer: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | LookupSource | string | Uint8Array, schedule: VestingInfo | { locked?: any; perBlock?: any; startingBlock?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
vestedTransfer: AugmentedSubmittable<(target: LookupSource | Address | AccountId | AccountIndex | string | Uint8Array, schedule: VestingInfo | { locked?: any; perBlock?: any; startingBlock?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>>;
};
}
+29 -25
View File
@@ -1,10 +1,10 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { Constants, Storage } from '@polkadot/metadata/Decorated/types';
import { Constants, DecoratedMeta } from '@polkadot/metadata/decorate/types';
import { RpcInterface } from '@polkadot/rpc-core/types';
import { Call, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { AnyFunction, CallFunction, Codec, CodecArg as Arg, InterfaceTypes, ModulesWithCalls, Registry, RegistryTypes } from '@polkadot/types/types';
import { AnyFunction, CallFunction, Codec, CodecArg as Arg, InterfaceTypes, Registry, RegistryTypes } from '@polkadot/types/types';
import { SubmittableExtrinsic } from '../submittable/types';
import { ApiInterfaceRx, ApiOptions, ApiTypes, DecorateMethod, DecoratedRpc, DecoratedRpcSection, PaginationOptions, QueryableConsts, QueryableModuleStorage, QueryableStorage, QueryableStorageEntry, QueryableStorageMulti, QueryableStorageMultiArg, SubmittableExtrinsicFunction, SubmittableExtrinsics, SubmittableModuleExtrinsics } from '../types';
@@ -13,7 +13,7 @@ import { BehaviorSubject, Observable, combineLatest, of } from 'rxjs';
import { map, switchMap, take, tap, toArray } from 'rxjs/operators';
import decorateDerive, { ExactDerive } from '@polkadot/api-derive';
import { memo } from '@polkadot/api-derive/util';
import DecoratedMeta from '@polkadot/metadata/Decorated';
import { expandMetadata } from '@polkadot/metadata';
import RpcCore from '@polkadot/rpc-core';
import { WsProvider } from '@polkadot/rpc-provider';
import { Metadata, Option, Raw, Text, TypeRegistry, u64 } from '@polkadot/types';
@@ -172,22 +172,22 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
}
public injectMetadata (metadata: Metadata, fromEmpty?: boolean, registry?: Registry): void {
const decoratedMeta = new DecoratedMeta(registry || this.#registry, metadata);
const decoratedMeta = expandMetadata(registry || this.#registry, metadata);
if (fromEmpty || !this._extrinsics) {
this._extrinsics = this._decorateExtrinsics(decoratedMeta.tx, this._decorateMethod);
this._rx.tx = this._decorateExtrinsics(decoratedMeta.tx, this._rxDecorateMethod);
this._extrinsics = this._decorateExtrinsics(decoratedMeta, this._decorateMethod);
this._rx.tx = this._decorateExtrinsics(decoratedMeta, this._rxDecorateMethod);
} else {
augmentObject('tx', this._decorateExtrinsics(decoratedMeta.tx, this._decorateMethod), this._extrinsics, false);
augmentObject(null, this._decorateExtrinsics(decoratedMeta.tx, this._rxDecorateMethod), this._rx.tx, false);
augmentObject('tx', this._decorateExtrinsics(decoratedMeta, this._decorateMethod), this._extrinsics, false);
augmentObject(null, this._decorateExtrinsics(decoratedMeta, this._rxDecorateMethod), this._rx.tx, false);
}
// this API
augmentObject('query', this._decorateStorage(decoratedMeta.query, this._decorateMethod), this._query, fromEmpty);
augmentObject('query', this._decorateStorage(decoratedMeta, this._decorateMethod), this._query, fromEmpty);
augmentObject('consts', decoratedMeta.consts, this._consts, fromEmpty);
// rx
augmentObject(null, this._decorateStorage(decoratedMeta.query, this._rxDecorateMethod), this._rx.query, fromEmpty);
augmentObject(null, this._decorateStorage(decoratedMeta, this._rxDecorateMethod), this._rx.query, fromEmpty);
augmentObject(null, decoratedMeta.consts, this._rx.consts, fromEmpty);
}
@@ -225,7 +225,7 @@ export default 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, method, pubsub, section }]): string[] => {
const allKeys = allKnown.reduce((allKeys: string[], [, { alias, endpoint, method, pubsub, section }]): string[] => {
allKeys.push(`${section}_${method}`);
if (pubsub) {
@@ -237,6 +237,10 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
allKeys.push(...alias);
}
if (endpoint) {
allKeys.push(endpoint);
}
return allKeys;
}, []);
const unknown = exposed.filter((key) => !allKeys.includes(key));
@@ -270,6 +274,8 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
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;
}
@@ -284,18 +290,16 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return decorateMethod((calls: QueryableStorageMultiArg<ApiType>[]): Observable<Codec[]> =>
this._rpcCore.state.subscribeStorage(
calls.map((arg: QueryableStorageMultiArg<ApiType>): [QueryableStorageEntry<ApiType>, ...Arg[]] =>
// the input is a QueryableStorageEntry, convert to StorageEntry
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
calls.map((arg: QueryableStorageMultiArg<ApiType>) =>
Array.isArray(arg)
? [arg[0].creator, ...arg.slice(1)]
: [arg.creator] as any)));
: [arg.creator])));
}
protected _decorateExtrinsics<ApiType extends ApiTypes> (extrinsics: ModulesWithCalls, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType> {
protected _decorateExtrinsics<ApiType extends ApiTypes> ({ tx }: DecoratedMeta, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType> {
const creator = createSubmittable(this._type, this._rx, decorateMethod);
return Object.entries(extrinsics).reduce((out, [name, section]): 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);
@@ -314,8 +318,8 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
return this._decorateFunctionMeta(method as any, decorated as any) as unknown as SubmittableExtrinsicFunction<ApiType>;
}
protected _decorateStorage<ApiType extends ApiTypes> (storage: Storage, decorateMethod: DecorateMethod<ApiType>): QueryableStorage<ApiType> {
return Object.entries(storage).reduce((out, [name, section]): QueryableStorage<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);
@@ -424,7 +428,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
));
}
private _retrieveMapKeys ({ iterKey, meta }: StorageEntry, at: Hash | Uint8Array | string | null, arg?: Arg): Observable<StorageKey[]> {
private _retrieveMapKeys ({ iterKey, meta, method, section }: StorageEntry, at: Hash | Uint8Array | string | null, arg?: Arg): Observable<StorageKey[]> {
assert(iterKey && (meta.type.isMap || meta.type.isDoubleMap), 'keys can only be retrieved on maps, linked maps and double maps');
const headKey = iterKey(arg).toHex();
@@ -436,7 +440,7 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
return startSubject.pipe(
switchMap((startKey) =>
query(startKey).pipe(
map((keys) => keys.map((key) => key.setMeta(meta)))
map((keys) => keys.map((key) => key.setMeta(meta, section, method)))
)
),
tap((keys): void => {
@@ -449,19 +453,19 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
);
}
private _retrieveMapKeysPaged ({ iterKey, meta }: StorageEntry, opts: PaginationOptions): Observable<StorageKey[]> {
private _retrieveMapKeysPaged ({ iterKey, meta, method, section }: StorageEntry, opts: PaginationOptions): Observable<StorageKey[]> {
assert(iterKey && (meta.type.isMap || meta.type.isDoubleMap), 'keys can only be retrieved on maps, linked maps and double maps');
const headKey = iterKey(opts.arg).toHex();
return this._rpcCore.state.getKeysPaged(headKey, opts.pageSize, opts.startKey || headKey).pipe(
map((keys) => keys.map((key) => key.setMeta(meta)))
map((keys) => keys.map((key) => key.setMeta(meta, section, method)))
);
}
private _retrieveMapEntries (entry: StorageEntry, at: Hash | Uint8Array | string | null, arg?: Arg): Observable<[StorageKey, Codec][]> {
const query = at
? this._rpcCore.state.queryStorageAt
const query = this._rpcCore.state.queryStorageAt
? at
? (keyset: StorageKey[]) => this._rpcCore.state.queryStorageAt<Codec[]>(keyset, at)
: (keyset: StorageKey[]) => this._rpcCore.state.queryStorageAt<Codec[]>(keyset)
// this is horrible, but need older support (which now doesn't work with at)
+214
View File
@@ -0,0 +1,214 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { RpcInterface } from '@polkadot/rpc-core/types';
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { ApiInterfaceRx, ApiTypes, DecoratedRpc, QueryableConsts, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics } from '../types';
import { Metadata, Text } from '@polkadot/types';
import { assertReturn } from '@polkadot/util';
import Init from './Init';
interface PkgJson {
name: string;
version: string;
}
let pkgJson: PkgJson = { name: '@polkadot/api', version: '-' };
import('../package.json')
.then((_pkgJson: unknown): void => {
pkgJson = _pkgJson as PkgJson;
})
.catch((): void => {
// ignore
});
function assertResult<T> (value: T | undefined): T {
return assertReturn(value, 'Api needs to be initialized before using, listen on \'ready\'');
}
export default abstract class Getters<ApiType extends ApiTypes> extends Init<ApiType> {
/**
* @description Contains the parameter types (constants) of all modules.
*
* The values are instances of the appropriate type and are accessible using `section`.`constantName`,
*
* @example
* <BR>
*
* ```javascript
* console.log(api.consts.democracy.enactmentPeriod.toString())
* ```
*/
public get consts (): QueryableConsts<ApiType> {
return assertResult(this._consts);
}
/**
* @description Derived results that are injected into the API, allowing for combinations of various query results.
*
* @example
* <BR>
*
* ```javascript
* api.derive.chain.bestNumber((number) => {
* console.log('best number', number);
* });
* ```
*/
public get derive (): ReturnType<Getters<ApiType>['_decorateDerive']> {
return assertResult(this._derive);
}
/**
* @description Returns the version of extrinsics in-use on this chain
*/
public get extrinsicVersion (): number {
return this._extrinsicType;
}
/**
* @description Contains the genesis Hash of the attached chain. Apart from being useful to determine the actual chain, it can also be used to sign immortal transactions.
*/
public get genesisHash (): Hash {
return assertResult(this._genesisHash);
}
/**
* @description `true` when subscriptions are supported
*/
public get hasSubscriptions (): boolean {
return this._rpcCore.provider.hasSubscriptions;
}
/**
* @description true is the underlying provider is connected
*/
public get isConnected (): boolean {
return this._isConnected.getValue();
}
/**
* @description The library information name & version (from package.json)
*/
public get libraryInfo (): string {
return `${pkgJson.name} v${pkgJson.version}`;
}
/**
* @description Contains all the chain state modules and their subsequent methods in the API. These are attached dynamically from the runtime metadata.
*
* All calls inside the namespace, is denoted by `section`.`method` and may take an optional query parameter. As an example, `api.query.timestamp.now()` (current block timestamp) does not take parameters, while `api.query.system.account(<accountId>)` (retrieving the associated nonce & balances for an account), takes the `AccountId` as a parameter.
*
* @example
* <BR>
*
* ```javascript
* api.query.system.account(<accountId>, ([nonce, balance]) => {
* console.log('new free balance', balance.free, 'new nonce', nonce);
* });
* ```
*/
public get query (): QueryableStorage<ApiType> {
return assertResult(this._query);
}
/**
* @description Allows for the querying of multiple storage entries and the combination thereof into a single result. This is a very optimal way to make multiple queries since it only makes a single connection to the node and retrieves the data over one subscription.
*
* @example
* <BR>
*
* ```javascript
* const unsub = await api.queryMulti(
* [
* // you can include the storage without any parameters
* api.query.balances.totalIssuance,
* // or you can pass parameters to the storage query
* [api.query.system.account, '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY']
* ],
* ([existential, [, { free }]]) => {
* console.log(`You have ${free.sub(existential)} more than the existential deposit`);
*
* unsub();
* }
* );
* ```
*/
public get queryMulti (): QueryableStorageMulti<ApiType> {
return assertResult(this._queryMulti);
}
/**
* @description Contains all the raw rpc sections and their subsequent methods in the API as defined by the jsonrpc interface definitions. Unlike the dynamic `api.query` and `api.tx` sections, these methods are fixed (although extensible with node upgrades) and not determined by the runtime.
*
* RPC endpoints available here allow for the query of chain, node and system information, in addition to providing interfaces for the raw queries of state (using known keys) and the submission of transactions.
*
* @example
* <BR>
*
* ```javascript
* api.rpc.chain.subscribeNewHeads((header) => {
* console.log('new header', header);
* });
* ```
*/
public get rpc (): DecoratedRpc<ApiType, RpcInterface> {
return assertResult(this._rpc);
}
/**
* @description Contains the chain information for the current node.
*/
public get runtimeChain (): Text {
return assertResult(this._runtimeChain);
}
/**
* @description Yields the current attached runtime metadata. Generally this is only used to construct extrinsics & storage, but is useful for current runtime inspection.
*/
public get runtimeMetadata (): Metadata {
return assertResult(this._runtimeMetadata);
}
/**
* @description Contains the version information for the current runtime.
*/
public get runtimeVersion (): RuntimeVersion {
return assertResult(this._runtimeVersion);
}
/**
* @description The underlying Rx API interface
*/
public get rx (): Pick<ApiInterfaceRx, 'tx' | 'rpc'> {
return assertResult(this._rx as Pick<ApiInterfaceRx, 'tx' | 'rpc'>);
}
/**
* @description The type of this API instance, either 'rxjs' or 'promise'
*/
public get type (): ApiTypes {
return this._type;
}
/**
* @description Contains all the extrinsic modules and their subsequent methods in the API. It allows for the construction of transactions and the submission thereof. These are attached dynamically from the runtime metadata.
*
* @example
* <BR>
*
* ```javascript
* api.tx.balances
* .transfer(<recipientId>, <balance>)
* .signAndSend(<keyPair>, ({status}) => {
* console.log('tx status', status.asFinalized.toHex());
* });
* ```
*/
public get tx (): SubmittableExtrinsics<ApiType> {
return assertResult(this._extrinsics);
}
}
+4 -210
View File
@@ -1,15 +1,12 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { RpcInterface } from '@polkadot/rpc-core/types';
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { CallFunction, RegistryError, SignerPayloadRawBase } from '@polkadot/types/types';
import { ApiInterfaceRx, ApiOptions, ApiTypes, DecoratedRpc, DecorateMethod, QueryableConsts, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics, Signer } from '../types';
import { ApiOptions, ApiTypes, DecorateMethod, Signer } from '../types';
import { Metadata, Text } from '@polkadot/types';
import { assert, isString, isUndefined, u8aToHex, u8aToU8a } from '@polkadot/util';
import { assert, isString, u8aToHex, u8aToU8a } from '@polkadot/util';
import Init from './Init';
import Getters from './Getters';
interface KeyringSigner {
sign (message: Uint8Array): Uint8Array;
@@ -19,28 +16,7 @@ interface SignerRawOptions {
signer?: Signer;
}
interface PkgJson {
name: string;
version: string;
}
let pkgJson: PkgJson = { name: '@polkadot/api', version: '-' };
import('../package.json')
.then((_pkgJson: unknown): void => {
pkgJson = _pkgJson as PkgJson;
})
.catch((): void => {
// ignore
});
function assertResult<T> (value: T | undefined): T {
assert(!isUndefined(value), 'Api needs to be initialized before using, listen on \'ready\'');
return value;
}
export default abstract class ApiBase<ApiType extends ApiTypes> extends Init<ApiType> {
export default abstract class ApiBase<ApiType extends ApiTypes> extends Getters<ApiType> {
/**
* @description Create an instance of the class
*
@@ -63,188 +39,6 @@ export default abstract class ApiBase<ApiType extends ApiTypes> extends Init<Api
super(options, type, decorateMethod);
}
/**
* @description Contains the parameter types (constants) of all modules.
*
* The values are instances of the appropriate type and are accessible using `section`.`constantName`,
*
* @example
* <BR>
*
* ```javascript
* console.log(api.consts.democracy.enactmentPeriod.toString())
* ```
*/
public get consts (): QueryableConsts<ApiType> {
return assertResult(this._consts);
}
/**
* @description Derived results that are injected into the API, allowing for combinations of various query results.
*
* @example
* <BR>
*
* ```javascript
* api.derive.chain.bestNumber((number) => {
* console.log('best number', number);
* });
* ```
*/
public get derive (): ReturnType<ApiBase<ApiType>['_decorateDerive']> {
return assertResult(this._derive);
}
/**
* @description Returns the version of extrinsics in-use on this chain
*/
public get extrinsicVersion (): number {
return this._extrinsicType;
}
/**
* @description Contains the genesis Hash of the attached chain. Apart from being useful to determine the actual chain, it can also be used to sign immortal transactions.
*/
public get genesisHash (): Hash {
return assertResult(this._genesisHash);
}
/**
* @description `true` when subscriptions are supported
*/
public get hasSubscriptions (): boolean {
return this._rpcCore.provider.hasSubscriptions;
}
/**
* @description true is the underlying provider is connected
*/
public get isConnected (): boolean {
return this._isConnected.getValue();
}
/**
* @description The library information name & version (from package.json)
*/
public get libraryInfo (): string {
return `${pkgJson.name} v${pkgJson.version}`;
}
/**
* @description Contains all the chain state modules and their subsequent methods in the API. These are attached dynamically from the runtime metadata.
*
* All calls inside the namespace, is denoted by `section`.`method` and may take an optional query parameter. As an example, `api.query.timestamp.now()` (current block timestamp) does not take parameters, while `api.query.system.account(<accountId>)` (retrieving the associated nonce & balances for an account), takes the `AccountId` as a parameter.
*
* @example
* <BR>
*
* ```javascript
* api.query.system.account(<accountId>, ([nonce, balance]) => {
* console.log('new free balance', balance.free, 'new nonce', nonce);
* });
* ```
*/
public get query (): QueryableStorage<ApiType> {
return assertResult(this._query);
}
/**
* @description Allows for the querying of multiple storage entries and the combination thereof into a single result. This is a very optimal way to make multiple queries since it only makes a single connection to the node and retrieves the data over one subscription.
*
* @example
* <BR>
*
* ```javascript
* const unsub = await api.queryMulti(
* [
* // you can include the storage without any parameters
* api.query.balances.totalIssuance,
* // or you can pass parameters to the storage query
* [api.query.system.account, '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY']
* ],
* ([existential, [, { free }]]) => {
* console.log(`You have ${free.sub(existential)} more than the existential deposit`);
*
* unsub();
* }
* );
* ```
*/
public get queryMulti (): QueryableStorageMulti<ApiType> {
return assertResult(this._queryMulti);
}
/**
* @description Contains all the raw rpc sections and their subsequent methods in the API as defined by the jsonrpc interface definitions. Unlike the dynamic `api.query` and `api.tx` sections, these methods are fixed (although extensible with node upgrades) and not determined by the runtime.
*
* RPC endpoints available here allow for the query of chain, node and system information, in addition to providing interfaces for the raw queries of state (using known keys) and the submission of transactions.
*
* @example
* <BR>
*
* ```javascript
* api.rpc.chain.subscribeNewHeads((header) => {
* console.log('new header', header);
* });
* ```
*/
public get rpc (): DecoratedRpc<ApiType, RpcInterface> {
return assertResult(this._rpc);
}
/**
* @description Contains the chain information for the current node.
*/
public get runtimeChain (): Text {
return assertResult(this._runtimeChain);
}
/**
* @description Yields the current attached runtime metadata. Generally this is only used to construct extrinsics & storage, but is useful for current runtime inspection.
*/
public get runtimeMetadata (): Metadata {
return assertResult(this._runtimeMetadata);
}
/**
* @description Contains the version information for the current runtime.
*/
public get runtimeVersion (): RuntimeVersion {
return assertResult(this._runtimeVersion);
}
/**
* @description The underlying Rx API interface
*/
public get rx (): Pick<ApiInterfaceRx, 'tx' | 'rpc'> {
return assertResult(this._rx as Pick<ApiInterfaceRx, 'tx' | 'rpc'>);
}
/**
* @description The type of this API instance, either 'rxjs' or 'promise'
*/
public get type (): ApiTypes {
return this._type;
}
/**
* @description Contains all the extrinsic modules and their subsequent methods in the API. It allows for the construction of transactions and the submission thereof. These are attached dynamically from the runtime metadata.
*
* @example
* <BR>
*
* ```javascript
* api.tx.balances
* .transfer(<recipientId>, <balance>)
* .signAndSend(<keyPair>, ({status}) => {
* console.log('tx status', status.asFinalized.toHex());
* });
* ```
*/
public get tx (): SubmittableExtrinsics<ApiType> {
return assertResult(this._extrinsics);
}
/**
* @description Connect from the underlying provider, halting all network traffic
*/
+1 -1
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { Constants } from '@polkadot/metadata/Decorated/types';
import { Constants } from '@polkadot/metadata/decorate/types';
import { Metadata } from '@polkadot/types';
import { Registry } from '@polkadot/types/types';
+11 -13
View File
@@ -53,9 +53,8 @@ async function query (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
// check multi for unsub
const multiUnsub = await api.queryMulti([
[api.query.system.account, keyring.eve.address],
// older chains only
[api.query.system.accountNonce, keyring.bob.address]
[api.query.staking.validators],
[api.query.system.events]
], (values): void => {
console.log('values', values);
@@ -66,11 +65,13 @@ async function query (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
const multiRes = await api.queryMulti([
[api.query.system.account, keyring.eve.address],
// older chains only
[api.query.system.accountNonce, keyring.bob.address]
[api.query.system.accountNonce, keyring.eve.address]
]);
console.log(multiRes);
}
async function queryExtra (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
// events destructing
await api.query.system.events((records): void => {
records.forEach(({ event, phase }): void => {
@@ -114,7 +115,8 @@ async function rpc (api: ApiPromise): Promise<void> {
console.log('current balance:', balance.toString());
});
// using raw
// using json & raw
await api.rpc.chain.getBlock.json('0x123456');
await api.rpc.chain.getBlock.raw('0x123456');
// using raw subs
@@ -141,8 +143,7 @@ async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
// transfer, also allows for BigInt inputs here
const transfer = api.tx.balances.transfer(keyring.bob.address, 123456789n);
console.log('transfer as Call', transfer as IMethod);
console.log('transfer as Extrinsic', transfer as IExtrinsic);
console.log('transfer casted', transfer as IMethod, transfer as IExtrinsic);
// simple "return the hash" variant
console.log('hash:', (await transfer.signAndSend(keyring.alice)).toHex());
@@ -158,9 +159,7 @@ async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
// just with the callback
await api.tx.balances
.transfer(keyring.bob.address, 12345)
.signAndSend(keyring.alice, ({ status }: SubmittableResult): void => {
console.log('transfer status:', status.type);
});
.signAndSend(keyring.alice, ({ status }: SubmittableResult) => console.log(status.type));
// with options and the callback
const nonce2 = await api.query.system.accountNonce(keyring.alice.address);
@@ -176,9 +175,7 @@ async function tx (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
const second = api.tx.democracy.second(123, 5);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
second.signAndSend('123', (result): void => {
console.log(result);
});
await second.signAndSend('123', (result) => console.log(result));
// it handles enum inputs correctly
await api.tx.democracy.proxyVote(123, { Split: { nay: 456, yay: 123 } }).signAndSend(keyring.alice);
@@ -193,6 +190,7 @@ async function main (): Promise<void> {
consts(api),
derive(api),
query(api, keyring),
queryExtra(api, keyring),
rpc(api),
types(api),
tx(api, keyring)
+1 -1
View File
@@ -8,7 +8,7 @@ import { detectPackage } from '@polkadot/util';
detectPackage(require('./package.json'), typeof __dirname !== 'undefined' && __dirname);
export { Keyring } from '@polkadot/keyring';
export { WsProvider } from '@polkadot/rpc-provider';
export { default as WsProvider } from '@polkadot/rpc-provider/ws';
export { default as ApiPromise } from './promise';
export { default as ApiRx } from './rx';
+1 -3
View File
@@ -46,9 +46,7 @@ export default class Combinator<T extends any[] = any[]> {
}
protected _allHasFired (): boolean {
if (!this.#allHasFired) {
this.#allHasFired = this.#fired.filter((hasFired): boolean => !hasFired).length === 0;
}
this.#allHasFired ||= this.#fired.filter((hasFired): boolean => !hasFired).length === 0;
return this.#allHasFired;
}
+40 -23
View File
@@ -3,10 +3,10 @@
/* eslint-disable no-dupe-class-members */
import { Address, Call, Extrinsic, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
import { Address, ApplyExtrinsicResult, Call, Extrinsic, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
import { Callback, Codec, Constructor, IKeyringPair, Registry, SignatureOptions, ISubmittableResult } from '@polkadot/types/types';
import { ApiInterfaceRx, ApiTypes, SignerResult } from '../types';
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittablePaymentResult, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
import { AddressOrPair, SignerOptions, SubmittableExtrinsic, SubmittableDryRunResult, SubmittablePaymentResult, SubmittableResultResult, SubmittableResultSubscription, SubmittableThis } from './types';
import { Observable, of } from 'rxjs';
import { first, map, mapTo, mergeMap, switchMap, tap } from 'rxjs/operators';
@@ -39,11 +39,22 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
this.#ignoreStatusCb = apiType === 'rxjs';
}
// adds a transform to the result, applied before result is returned
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this {
this.#transformResult = transform;
// dry run an extrinsic
public dryRun (account: AddressOrPair, optionsOrHash?: Partial<SignerOptions> | Uint8Array | string): SubmittableDryRunResult<ApiType> {
if (isString(optionsOrHash) || isU8a(optionsOrHash)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return decorateMethod(
() => api.rpc.system.dryRun(this.toHex(), optionsOrHash)
);
}
return this;
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
return decorateMethod(
(): Observable<ApplyExtrinsicResult> =>
this.#observeSign(account, optionsOrHash).pipe(
switchMap(() => api.rpc.system.dryRun(this.toHex()))
)
)();
}
// calculate the payment info for this transaction (if signed and submitted)
@@ -51,7 +62,7 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
if (isString(optionsOrHash) || isU8a(optionsOrHash)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return decorateMethod(
() => api.rpc.payment.queryInfo(this.toHex(), optionsOrHash)
(): Observable<RuntimeDispatchInfo> => api.rpc.payment.queryInfo(this.toHex(), optionsOrHash)
);
}
@@ -68,7 +79,6 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
const eraOptions = this.#makeEraOptions(allOptions, signingInfo);
const signOptions = this.#makeSignOptions(eraOptions, {});
// add a fake signature to the extrinsic
this.signFake(address, signOptions);
return api.rpc.payment.queryInfo(this.toHex());
@@ -77,6 +87,24 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
)();
}
// send with an immediate Hash result
public send (): SubmittableResultResult<ApiType>;
// send with a status callback
public send (statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
// send implementation for both immediate Hash and statusCb variants
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
return decorateMethod(
isSubscription
? this.#observeSubscribe
: this.#observeSend
)(statusCb);
}
/**
* @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
@@ -125,22 +153,11 @@ export default function createClass <ApiType extends ApiTypes> ({ api, apiType,
)(statusCb);
}
// send with an immediate Hash result
public send (): SubmittableResultResult<ApiType>;
// adds a transform to the result, applied before result is returned
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this {
this.#transformResult = transform;
// send with a status callback
public send (statusCb: Callback<ISubmittableResult>): SubmittableResultSubscription<ApiType>;
// send implementation for both immediate Hash and statusCb variants
public send (statusCb?: Callback<ISubmittableResult>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
const isSubscription = api.hasSubscriptions && (this.#ignoreStatusCb || !!statusCb);
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
return decorateMethod(
isSubscription
? this.#observeSubscribe
: this.#observeSend
)(statusCb);
return this;
}
#makeEraOptions = (options: Partial<SignerOptions>, { header, mortalLength, nonce }: { header: Header | null; mortalLength: number; nonce: Index }): SignatureOptions => {
+16 -9
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { AccountId, Address, DispatchError, DispatchInfo, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
import { AccountId, Address, ApplyExtrinsicResult, DispatchError, DispatchInfo, Extrinsic, ExtrinsicStatus, EventRecord, Hash, RuntimeDispatchInfo } from '@polkadot/types/interfaces';
import { AnyNumber, Callback, Codec, IExtrinsicEra, IKeyringPair, Signer, ISubmittableResult } from '@polkadot/types/types';
import { ApiTypes } from '../types';
@@ -14,6 +14,11 @@ export interface SubmittableResultValue {
status: ExtrinsicStatus;
}
export type SubmittableDryRunResult<ApiType extends ApiTypes> =
ApiType extends 'rxjs'
? Observable<ApplyExtrinsicResult>
: Promise<ApplyExtrinsicResult>;
export type SubmittablePaymentResult<ApiType extends ApiTypes> =
ApiType extends 'rxjs'
? Observable<RuntimeDispatchInfo>
@@ -45,24 +50,26 @@ export interface SignerOptions {
export type AddressOrPair = IKeyringPair | string | AccountId | Address;
export interface SubmittableExtrinsic<ApiType extends ApiTypes, R extends ISubmittableResult = ISubmittableResult> extends Extrinsic {
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this;
dryRun (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableDryRunResult<ApiType>;
paymentInfo (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittablePaymentResult<ApiType>;
send(): SubmittableResultResult<ApiType>;
send (): SubmittableResultResult<ApiType>;
send(statusCb: Callback<R>): SubmittableResultSubscription<ApiType, R>;
send (statusCb: Callback<R>): SubmittableResultSubscription<ApiType, R>;
/**
* @deprecated
*/
sign(account: IKeyringPair, _options?: Partial<SignerOptions>): this;
sign (account: IKeyringPair, _options?: Partial<SignerOptions>): this;
signAsync(account: AddressOrPair, _options?: Partial<SignerOptions>): SubmittableThis<ApiType, this>;
signAsync (account: AddressOrPair, _options?: Partial<SignerOptions>): SubmittableThis<ApiType, this>;
signAndSend(account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType, R>;
signAndSend (account: AddressOrPair, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType, R>;
signAndSend(account: AddressOrPair, statusCb: Callback<R>): SubmittableResultSubscription<ApiType>;
signAndSend (account: AddressOrPair, statusCb: Callback<R>): SubmittableResultSubscription<ApiType>;
signAndSend(account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<R>): SubmittableResultSubscription<ApiType, R>;
signAndSend (account: AddressOrPair, options: Partial<SignerOptions>, statusCb?: Callback<R>): SubmittableResultSubscription<ApiType, R>;
withResultTransform (transform: (input: ISubmittableResult) => ISubmittableResult): this;
}
+8 -6
View File
@@ -1,24 +1,26 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { AnyFunction, Callback, Codec } from '@polkadot/types/types';
import { AnyFunction, Callback } from '@polkadot/types/types';
import { Observable } from 'rxjs';
import { Json, Raw } from '@polkadot/types/codec';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { ApiTypes, Push, PromiseResult, RxResult, UnsubscribePromise } from './base';
export interface RpcRxResult<F extends AnyFunction> extends RxResult<F> {
raw (...args: Parameters<F>): Observable<Uint8Array & Codec>;
json (...args: Parameters<F>): Observable<Json>;
raw (...args: Parameters<F>): Observable<Raw>;
}
export interface RpcPromiseResult<F extends AnyFunction> extends PromiseResult<F> {
raw (...args: Parameters<F>): Promise<Uint8Array & Codec>;
raw (...args: Push<Parameters<F>, Callback<Uint8Array & Codec>>): UnsubscribePromise;
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;
}
// FIXME The day TS has higher-kinded types, we can remove this hardcoded stuff
export type RpcMethodResult<ApiType extends ApiTypes, F extends AnyFunction> = ApiType extends 'rxjs'
? RpcRxResult<F>
: RpcPromiseResult<F>;
+3 -4
View File
@@ -1,11 +1,10 @@
// Copyright 2017-2019 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { Storage } from '@polkadot/metadata/Decorated/types';
import { Storage } from '@polkadot/metadata/decorate/types';
import storageFromMeta from '@polkadot/metadata/Decorated/storage/fromMetadata';
import Metadata from '@polkadot/metadata/Metadata';
import metaStatic from '@polkadot/metadata/Metadata/static';
import Metadata, { storageFromMeta } from '@polkadot/metadata';
import metaStatic from '@polkadot/metadata/static';
import { TypeRegistry } from '@polkadot/types';
import { extractStorageArgs } from './validate';
@@ -5,7 +5,7 @@ import { Signer, SignerResult } from '@polkadot/api/types';
import { KeyringPair } from '@polkadot/keyring/types';
import { Registry, SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types';
import { hexToU8a, u8aToHex } from '@polkadot/util';
import { assert, hexToU8a, u8aToHex } from '@polkadot/util';
let id = 0;
@@ -23,9 +23,7 @@ export class SingleAccountSigner implements Signer {
}
public async signPayload (payload: SignerPayloadJSON): Promise<SignerResult> {
if (payload.address !== this.#keyringPair.address) {
throw new Error('does not have the keyringPair');
}
assert(payload.address === this.#keyringPair.address, 'Signer does not have the keyringPair');
return new Promise((resolve): void => {
setTimeout((): void => {
@@ -40,9 +38,7 @@ export class SingleAccountSigner implements Signer {
}
public async signRaw ({ address, data }: SignerPayloadRaw): Promise<SignerResult> {
if (address !== this.#keyringPair.address) {
throw new Error('does not have the keyringPair');
}
assert(address === this.#keyringPair.address, 'Signer does not have the keyringPair');
return new Promise((resolve): void => {
setTimeout((): void => {
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/metadata",
"version": "2.4.1",
"version": "2.5.1",
"description": "Helpers to extract information from runtime metadata",
"main": "index.js",
"publishConfig": {
@@ -27,13 +27,13 @@
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-metadata#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/types": "^2.4.1",
"@polkadot/types-known": "^2.4.1",
"@polkadot/util": "^3.6.1",
"@polkadot/util-crypto": "^3.6.1",
"@polkadot/types": "^2.5.1",
"@polkadot/types-known": "^2.5.1",
"@polkadot/util": "^3.7.1",
"@polkadot/util-crypto": "^3.7.1",
"bn.js": "^5.1.3"
},
"devDependencies": {
"@polkadot/keyring": "^3.6.1"
"@polkadot/keyring": "^3.7.1"
}
}
@@ -1,41 +0,0 @@
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { ModulesWithCalls, Registry } from '@polkadot/types/types';
import { Constants, Storage } from './types';
import { assert } from '@polkadot/util';
import Metadata from '../Metadata';
import constantsFromMeta from './consts/fromMetadata';
import extrinsicsFromMeta from './extrinsics/fromMetadata';
import storageFromMeta from './storage/fromMetadata';
/**
* This class represents a decorated wrapper over the [[Metadata]]. The
* [[Metadata]] type is a Codec type returned by the node, and `Decorated`
* composes it and populates the `.query`, `.tx` and `.consts` sections.
*/
export default class Decorated {
public readonly consts: Constants;
public readonly metadata: Metadata;
public readonly registry: Registry;
public readonly query: Storage;
public readonly tx: ModulesWithCalls;
constructor (registry: Registry, value: Metadata) {
assert(value instanceof Metadata, 'You need to pass a valid Metadata instance to Decorated');
this.registry = registry;
this.metadata = value;
// decoration
this.tx = extrinsicsFromMeta(registry, this.metadata);
this.query = storageFromMeta(registry, this.metadata);
this.consts = constantsFromMeta(registry, this.metadata);
}
}
@@ -1,3 +0,0 @@
# @polkadot/metadata/consts
A base interface to the parameter types
@@ -1,3 +0,0 @@
# @polkadot/metadata/extrinsics
Base extrinsic definitions & codecs
-6
View File
@@ -1,6 +0,0 @@
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// SPDX-License-Identifier: Apache-2.0
import Decorated from './Decorated';
export default Decorated;
@@ -1,3 +0,0 @@
# @polkadot/metadata/storage
A base interface to the storage layer
-6
View File
@@ -1,6 +0,0 @@
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// SPDX-License-Identifier: Apache-2.0
import Metadata from './Metadata';
export default Metadata;
@@ -1,13 +1,13 @@
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { Constants } from '../../types';
import { Constants } from '../types';
import { Metadata, TypeRegistry } from '@polkadot/types';
import rpcMetadata from '../../../Metadata/static';
import rpcMetadataV10 from '../../../Metadata/v10/static';
import fromMetadata from '../fromMetadata';
import rpcMetadata from '../../static';
import rpcMetadataV10 from '../../v10/static';
import fromMetadata from './fromMetadata';
function init (meta: string): [Constants, TypeRegistry] {
const registry = new TypeRegistry();
@@ -28,7 +28,7 @@ describe('fromMetadata', (): void => {
});
// removed from session
it('correctly handles bytes', (): void => {
it('correctly handles bytes (V10)', (): void => {
const [consts] = init(rpcMetadataV10);
// 0x34 removes as the length prefix removed
@@ -2,12 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
import { Registry } from '@polkadot/types/types';
import { Constants, ConstantCodec, ModuleConstants } from '../../types';
import { Constants, ConstantCodec, ModuleConstants } from '../types';
import { createTypeUnsafe } from '@polkadot/types/create';
import { hexToU8a, stringCamelCase } from '@polkadot/util';
import Metadata from '../../../Metadata';
import Metadata from '../..';
/** @internal */
export default function fromMetadata (registry: Registry, metadata: Metadata): Constants {
@@ -19,13 +19,13 @@ export default function fromMetadata (registry: Registry, metadata: Metadata): C
const { name } = moduleMetadata;
// For access, we change the index names, i.e. Democracy.EnactmentPeriod -> democracy.enactmentPeriod
result[stringCamelCase(name.toString())] = moduleMetadata.constants.reduce((newModule: ModuleConstants, meta): ModuleConstants => {
result[stringCamelCase(name)] = moduleMetadata.constants.reduce((newModule: ModuleConstants, meta): ModuleConstants => {
// convert to the natural type as received
const type = meta.type.toString();
const codec: ConstantCodec = createTypeUnsafe(registry, type, [hexToU8a(meta.value.toHex())]);
codec.meta = meta;
newModule[stringCamelCase(meta.name.toString())] = codec;
newModule[stringCamelCase(meta.name)] = codec;
return newModule;
}, {} as ModuleConstants);
@@ -7,16 +7,12 @@ import { AnyJson, CallFunction, Registry, RegistryMetadataCall } from '@polkadot
import { assert, stringCamelCase } from '@polkadot/util';
/** @internal */
export default function createDescriptor (registry: Registry, section: string, sectionIndex: number, methodIndex: number, callMetadata: RegistryMetadataCall): CallFunction {
const callIndex = new Uint8Array([sectionIndex, methodIndex]);
export default function createDescriptor (registry: Registry, section: string, callIndex: Uint8Array, callMetadata: RegistryMetadataCall): CallFunction {
const expectedArgs = callMetadata.args;
const funcName = stringCamelCase(callMetadata.name.toString());
const funcName = stringCamelCase(callMetadata.name);
const extrinsicFn = (...args: any[]): Call => {
assert(
expectedArgs.length.valueOf() === args.length,
`Extrinsic ${section}.${funcName} expects ${expectedArgs.length.valueOf()} arguments, got ${args.length}.`
);
assert(expectedArgs.length === args.length, `Extrinsic ${section}.${funcName} expects ${expectedArgs.length.valueOf()} arguments, got ${args.length}.`);
return registry.createType('Call', {
args,
@@ -3,8 +3,8 @@
import { Metadata, TypeRegistry } from '@polkadot/types';
import json from '../../../Metadata/static';
import fromMetadata from '.';
import json from '../../static';
import fromMetadata from './fromMetadata';
// Use the pre-generated metadata
const registry = new TypeRegistry();
@@ -5,7 +5,7 @@ import { Calls, ModulesWithCalls, Registry, RegistryMetadata, RegistryMetadataMo
import { stringCamelCase } from '@polkadot/util';
import extrinsics from '../';
import extrinsics from './';
import createUnchecked from './createUnchecked';
/** @internal */
@@ -19,12 +19,12 @@ export default function fromMetadata (registry: Registry, metadata: RegistryMeta
const sectionIndex = isIndexed
? index.toNumber()
: _sectionIndex;
const section = stringCamelCase(name.toString());
const section = stringCamelCase(name);
result[section] = calls.unwrap().reduce((newModule: Calls, callMetadata, methodIndex): Calls => {
const method = stringCamelCase(callMetadata.name.toString());
const method = stringCamelCase(callMetadata.name);
newModule[method] = createUnchecked(registry, section, sectionIndex, methodIndex, callMetadata);
newModule[method] = createUnchecked(registry, section, new Uint8Array([sectionIndex, methodIndex]), callMetadata);
return newModule;
}, {});
@@ -5,7 +5,7 @@ import BN from 'bn.js';
import testingPairs from '@polkadot/keyring/testingPairs';
import { Metadata, TypeRegistry } from '@polkadot/types';
import metadataStatic from '../../Metadata/static';
import metadataStatic from '../../static';
import fromMetadata from './fromMetadata';
const keyring = testingPairs({ type: 'ed25519' }, false);
@@ -4,22 +4,22 @@
import { TypeRegistry } from '@polkadot/types/create';
import { u8aToHex } from '@polkadot/util';
import Metadata from '../Metadata';
import json from '../Metadata/static';
import Decorated from './Decorated';
import Metadata from '..';
import json from '../static';
import { constantsFromMeta, extrinsicsFromMeta, storageFromMeta } from './';
const registry = new TypeRegistry();
const metadata = new Metadata(registry, json);
registry.setMetadata(metadata);
const decorated = new Decorated(registry, metadata);
describe('Decorated', () => {
it('should correctly get Alice\'s nonce storage key (u8a)', (): void => {
const query = storageFromMeta(registry, metadata);
expect(
u8aToHex(
decorated.query.system.account('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
query.system.account('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
)
).toEqual(
'0x410126aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d'
@@ -27,8 +27,10 @@ describe('Decorated', () => {
});
it('should return properly-encoded transactions', (): void => {
const tx = extrinsicsFromMeta(registry, metadata);
expect(
registry.createType('Extrinsic', decorated.tx.timestamp.set([10101])).toU8a()
registry.createType('Extrinsic', tx.timestamp.set([10101])).toU8a()
).toEqual(
new Uint8Array([
// length (encoded)
@@ -44,7 +46,9 @@ describe('Decorated', () => {
});
it('should return constants with the correct type and value', (): void => {
expect(decorated.consts.democracy.cooloffPeriod).toBeInstanceOf(registry.createClass('BlockNumber'));
expect(decorated.consts.democracy.cooloffPeriod.toHex()).toEqual('0x000c4e00');
const consts = constantsFromMeta(registry, metadata);
expect(consts.democracy.cooloffPeriod).toBeInstanceOf(registry.createClass('BlockNumber'));
expect(consts.democracy.cooloffPeriod.toHex()).toEqual('0x000c4e00');
});
});
+27
View File
@@ -0,0 +1,27 @@
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { Registry } from '@polkadot/types/types';
import { DecoratedMeta } from './types';
import { assert } from '@polkadot/util';
import Metadata from '..';
import constantsFromMeta from './consts/fromMetadata';
import extrinsicsFromMeta from './extrinsics/fromMetadata';
import storageFromMeta from './storage/fromMetadata';
/**
* Expands the metadata by decoration int consts, query and tx sections
*/
export default function expandMetadata (registry: Registry, value: Metadata): DecoratedMeta {
assert(value instanceof Metadata, 'You need to pass a valid Metadata instance to Decorated');
return {
consts: constantsFromMeta(registry, value),
query: storageFromMeta(registry, value),
tx: extrinsicsFromMeta(registry, value)
};
}
export { constantsFromMeta, extrinsicsFromMeta, storageFromMeta };
@@ -31,19 +31,11 @@ interface IterFn {
meta: StorageEntryMetadataLatest;
}
type CreateArgType = boolean | string | number | null | BN | Uint8Array | Codec;
type CreateArgType = boolean | string | number | null | BN | BigInt | Uint8Array | Codec;
const EMPTY_U8A = new Uint8Array([]);
const NULL_HASHER = (value: Uint8Array): Uint8Array => value;
// with the prefix, method & options, create both the string & raw keys
/** @internal */
function expandKey ({ method, prefix }: CreateItemFn, options: CreateItemOptions): string {
return options.key
? options.key
: `${prefix} ${method}`;
}
// get the hashers, the base (and in the case of DoubleMap), the second key
/** @internal */
function getHashers ({ meta: { type } }: CreateItemFn): [HasherFunction, HasherFunction?] {
@@ -68,7 +60,7 @@ function createPrefixedKey ({ method, prefix }: CreateItemFn): Uint8Array {
// create a key for a DoubleMap type
/** @internal */
function createKeyDoubleMap (registry: Registry, itemFn: CreateItemFn, stringKey: string, args: [CreateArgType, CreateArgType], [hasher1, hasher2]: [HasherFunction, HasherFunction?]): Uint8Array {
function createKeyDoubleMap (registry: Registry, itemFn: CreateItemFn, args: [CreateArgType, CreateArgType], [hasher1, hasher2]: [HasherFunction, HasherFunction?]): Uint8Array {
const { meta: { name, type } } = itemFn;
// since we are passing an almost-unknown through, trust, but verify
@@ -92,7 +84,7 @@ function createKeyDoubleMap (registry: Registry, itemFn: CreateItemFn, stringKey
// create a key for either a map or a plain value
/** @internal */
function createKey (registry: Registry, itemFn: CreateItemFn, stringKey: string, arg: CreateArgType, hasher: (value: Uint8Array) => Uint8Array): Uint8Array {
function createKey (registry: Registry, itemFn: CreateItemFn, arg: CreateArgType, hasher: (value: Uint8Array) => Uint8Array): Uint8Array {
const { meta: { name, type } } = itemFn;
let param: Uint8Array = EMPTY_U8A;
@@ -115,7 +107,9 @@ function createKey (registry: Registry, itemFn: CreateItemFn, stringKey: string,
// attach the metadata to expand to a StorageFunction
/** @internal */
function expandWithMeta ({ meta, method, prefix, section }: CreateItemFn, storageFn: StorageEntry): StorageEntry {
function expandWithMeta ({ meta, method, prefix, section }: CreateItemFn, _storageFn: (arg?: CreateArgType | [CreateArgType?, CreateArgType?]) => Uint8Array): StorageEntry {
const storageFn = _storageFn as StorageEntry;
storageFn.meta = meta;
storageFn.method = stringLowerFirst(method);
storageFn.prefix = prefix;
@@ -149,7 +143,7 @@ function extendHeadMeta (registry: Registry, { meta: { documentation, name, type
const prefixKey = registry.createType('StorageKey', iterFn, { method, section });
return (arg?: any): StorageKey =>
return (arg?: any) =>
!isUndefined(arg) && !isNull(arg)
? registry.createType('StorageKey', iterFn(arg), { method, section })
: prefixKey;
@@ -163,41 +157,39 @@ function extendPrefixedMap (registry: Registry, itemFn: CreateItemFn, storageFn:
storageFn.iterKey = extendHeadMeta(registry, itemFn, storageFn, (arg?: any): Raw => {
assert(type.isDoubleMap || isUndefined(arg), 'Filtering arguments for keys/entries are only valid on double maps');
return type.isDoubleMap && !isUndefined(arg) && !isNull(arg)
? new Raw(registry, u8aConcat(createPrefixedKey(itemFn), getHasher(type.asDoubleMap.hasher)(registry.createType(type.asDoubleMap.key1.toString() as 'Raw', arg).toU8a())))
: new Raw(registry, createPrefixedKey(itemFn));
return new Raw(
registry,
type.isDoubleMap && !isUndefined(arg) && !isNull(arg)
? u8aConcat(
createPrefixedKey(itemFn),
getHasher(type.asDoubleMap.hasher)(
registry.createType(type.asDoubleMap.key1.toString() as 'Raw', arg).toU8a()
)
)
: createPrefixedKey(itemFn)
);
});
return storageFn;
}
// attach the full list hashing for double maps
/** @internal */
function extendDoubleMap (registry: Registry, itemFn: CreateItemFn, storageFn: StorageEntry): StorageEntry {
return extendPrefixedMap(registry, itemFn, storageFn);
}
/** @internal */
export default function createFunction (registry: Registry, itemFn: CreateItemFn, options: CreateItemOptions): StorageEntry {
const { meta: { type } } = itemFn;
const stringKey = expandKey(itemFn, options);
const [hasher, key2Hasher] = getHashers(itemFn);
// Can only have zero or one argument:
// - storage.system.account(address)
// - storage.timestamp.blockPeriod()
// For doublemap queries the params is passed in as an tuple, [key1, key2]
const _storageFn = (arg?: CreateArgType | [CreateArgType?, CreateArgType?]): Uint8Array =>
const storageFn = expandWithMeta(itemFn, (arg?: CreateArgType | [CreateArgType?, CreateArgType?]): Uint8Array =>
type.isDoubleMap
? createKeyDoubleMap(registry, itemFn, stringKey, arg as [CreateArgType, CreateArgType], [hasher, key2Hasher])
: createKey(registry, itemFn, stringKey, arg as CreateArgType, options.skipHashing ? NULL_HASHER : hasher);
? createKeyDoubleMap(registry, itemFn, arg as [CreateArgType, CreateArgType], [hasher, key2Hasher])
: createKey(registry, itemFn, arg as CreateArgType, options.skipHashing ? NULL_HASHER : hasher)
);
const storageFn = expandWithMeta(itemFn, _storageFn as StorageEntry);
if (type.isMap) {
if (type.isMap || type.isDoubleMap) {
extendPrefixedMap(registry, itemFn, storageFn);
} else if (type.isDoubleMap) {
extendDoubleMap(registry, itemFn, storageFn);
}
storageFn.keyPrefix = (arg?: any): Uint8Array =>
@@ -5,9 +5,9 @@ import testingPairs from '@polkadot/keyring/testingPairs';
import { TypeRegistry } from '@polkadot/types';
import { u8aToHex } from '@polkadot/util';
import Metadata from '../../../Metadata';
import rpcMetadata from '../../../Metadata/static';
import Decorated from '../../Decorated';
import Metadata from '../../';
import rpcMetadata from '../../static';
import { storageFromMeta } from '../';
const keyring = testingPairs({ type: 'ed25519' });
@@ -18,20 +18,20 @@ describe('fromMetadata', (): void => {
registry.setMetadata(metadata);
const decorated = new Decorated(registry, metadata);
const query = storageFromMeta(registry, metadata);
it('should throw if the storage function expects an argument', (): void => {
expect((): any => decorated.query.balances.account()).toThrowError(/requires one argument/);
expect((): any => query.balances.account()).toThrowError(/requires one argument/);
});
it('should return a value if the storage function does not expect an argument', (): void => {
expect((): any => decorated.query.timestamp.now()).not.toThrow();
expect((): any => query.timestamp.now()).not.toThrow();
});
it('should return the correct length-prefixed storage key', (): void => {
expect(
u8aToHex(
decorated.query.system.account(keyring.alice.address)
query.system.account(keyring.alice.address)
)
).toEqual(
'0x410126aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d'
@@ -2,23 +2,23 @@
// SPDX-License-Identifier: Apache-2.0
import { Registry } from '@polkadot/types/types';
import { ModuleStorage, Storage } from '../../types';
import { ModuleStorage, Storage } from '../types';
import { stringCamelCase, stringLowerFirst } from '@polkadot/util';
import Metadata from '../../../Metadata';
import Metadata from '../../Metadata';
import createFunction from './createFunction';
import getStorage from './storage';
/** @internal */
export default function fromMetadata (registry: Registry, metadata: Metadata): Storage {
return metadata.asLatest.modules.reduce((result, moduleMetadata): Storage => {
return metadata.asLatest.modules.reduce((result: Storage, moduleMetadata): Storage => {
if (moduleMetadata.storage.isNone) {
return result;
}
const { name } = moduleMetadata;
const section = stringCamelCase(name.toString());
const section = stringCamelCase(name);
const unwrapped = moduleMetadata.storage.unwrap();
const prefix = unwrapped.prefix.toString();
@@ -1,6 +1,6 @@
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// SPDX-License-Identifier: Apache-2.0
import getStorage from './fromMetadata/storage';
import getStorage from './storage';
export default getStorage;
@@ -3,7 +3,7 @@
import { StorageEntry } from '@polkadot/types/primitive/StorageKey';
import { Registry } from '@polkadot/types/types';
import { Storage } from '../../types';
import { Storage } from '../types';
import * as substrate from './substrate';
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import { AugmentedConst, QueryableConsts, QueryableModuleConsts } from '@polkadot/api/types/consts';
import { Codec } from '@polkadot/types/types';
import { Codec, ModulesWithCalls } from '@polkadot/types/types';
import { StorageEntry } from '@polkadot/types/primitive/StorageKey';
export interface ModuleStorage {
@@ -19,3 +19,9 @@ export interface Storage {
[key: string]: ModuleStorage;
substrate: ModuleStorage;
}
export interface DecoratedMeta {
consts: Constants;
query: Storage;
tx: ModulesWithCalls
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright 2017-2020 @polkadot/metadata authors & contributors
// SPDX-License-Identifier: Apache-2.0
import expandMetadata, { constantsFromMeta, extrinsicsFromMeta, storageFromMeta } from './decorate';
import Metadata from './Metadata';
export default Metadata;
export { constantsFromMeta, expandMetadata, extrinsicsFromMeta, storageFromMeta };
@@ -27,7 +27,7 @@ export default function extractTypes (types: string[]): Extracted[] {
case TypeDefInfo.HashMap:
case TypeDefInfo.Result:
case TypeDefInfo.Tuple:
return extractTypes((decoded.sub as TypeDef[]).map((sub): string => sub.type));
return extractTypes((decoded.sub as TypeDef[]).map(({ type }) => type));
default:
throw new Error(`Unhandled: Unable to create and validate type from ${type}`);

Some files were not shown because too many files have changed in this diff Show More