Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06418913e5 | ||
|
|
188363d407 | ||
|
|
ec79087bab | ||
|
|
155fd0f8b1 | ||
|
|
05b7def1a0 | ||
|
|
5671af8db7 | ||
|
|
6aebeec028 | ||
|
|
5b5d0a3fb8 | ||
|
|
d405ed1005 | ||
|
|
2be97310d3 | ||
|
|
1f44e4473f | ||
|
|
022c7ea645 | ||
|
|
fe078ca67c | ||
|
|
479c742471 | ||
|
|
a52c629ecf | ||
|
|
c077d0f2e7 | ||
|
|
679994a6fb | ||
|
|
8cc256fdcf | ||
|
|
b6b2f2beec | ||
|
|
6075a21efb | ||
|
|
fa98f8f06d | ||
|
|
ad570cac5a | ||
|
|
cb32acc409 | ||
|
|
3998b1bcbd | ||
|
|
3fd03b2498 | ||
|
|
cba5710fec | ||
|
|
1ffdba03b3 | ||
|
|
fcf89d1501 | ||
|
|
56dc116d92 | ||
|
|
2371d6a29c | ||
|
|
d39878c875 | ||
|
|
287ceb2ded | ||
|
|
7c04be6abc | ||
|
|
e601ae27a1 | ||
|
|
487ad475c7 | ||
|
|
506b042f8c | ||
|
|
0e037de1b1 | ||
|
|
8d3cb72189 | ||
|
|
f8b9615e6b | ||
|
|
7cc961f789 | ||
|
|
1d92b7bead | ||
|
|
2c44b5ca8a | ||
|
|
8d9b50a004 | ||
|
|
d41f6ec3ef | ||
|
|
6aff7db89a | ||
|
|
dc105e6b31 | ||
|
|
f41ad2eee7 | ||
|
|
276da86dbe | ||
|
|
5aa64dddf3 | ||
|
|
cf01c41b33 | ||
|
|
64bc3fbffa | ||
|
|
453aacb669 | ||
|
|
2f350e3bc2 | ||
|
|
8379689eaa | ||
|
|
2676909cd0 | ||
|
|
a53c924248 | ||
|
|
a044a959b6 | ||
|
|
7555a3a7ce | ||
|
|
0fac973645 | ||
|
|
f533f51003 | ||
|
|
b4c0875ebf | ||
|
|
8cab499a83 | ||
|
|
f2daae3986 | ||
|
|
41cf32c808 | ||
|
|
b0e970a815 | ||
|
|
fed9e8f7de | ||
|
|
d2e2d3be76 | ||
|
|
07b9cb1a16 | ||
|
|
4f24af6d8a | ||
|
|
a30d467618 | ||
|
|
3daf44bac2 | ||
|
|
b69d8ec789 | ||
|
|
d1b2664071 | ||
|
|
8d0f20c2a7 | ||
|
|
f200a348de | ||
|
|
fae67e72ee | ||
|
|
a23e71bfb0 | ||
|
|
6e96fd6a55 | ||
|
|
3ba2bbd581 | ||
|
|
f8084c2d12 | ||
|
|
1ad552f03d | ||
|
|
6b8d0207a6 |
+1
-1
@@ -1 +1 @@
|
||||
6
|
||||
8
|
||||
|
||||
@@ -14,6 +14,8 @@ jobs:
|
||||
node-version: [12.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
token: ${{ secrets.GH_PAT }}
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
@@ -27,7 +29,7 @@ jobs:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
CI_NO_BETA=true yarn polkadot-dev-ghact-build
|
||||
yarn polkadot-dev-ghact-build
|
||||
|
||||
build_docs:
|
||||
name: Build Docs
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
# 0.96.1
|
||||
|
||||
- Updated types for latest Kusama
|
||||
- Add `filterRecords` (in addition to `findRecord`) on submittable results
|
||||
- Various ABI v2 contract fixes
|
||||
- Update derive for elections (incl. RunnersUp) and heartbeat derives (with blocks & messages)
|
||||
- Add vesting totals & locked breakdowns to derive balances
|
||||
- Update council derives for the latest Substrate master support (with constants)
|
||||
- Derive cleanups, including sharing of instances between the API and internal to derives
|
||||
|
||||
# 0.95.2
|
||||
|
||||
- Temporary removal of `account_nextIndex` use, will be re-added in a future release
|
||||
|
||||
# 0.95.1
|
||||
|
||||
- Support Extrinsic V4 with additional signature indicator (Latest Polkadot/Substrate/Kusama)
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.95.2"
|
||||
"version": "0.96.1"
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.95.2",
|
||||
"version": "0.96.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"yarn": "^1.10.1"
|
||||
@@ -9,7 +9,7 @@
|
||||
],
|
||||
"resolutions": {
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"typescript": "^3.6.4"
|
||||
"typescript": "^3.7.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn build:interfaces && polkadot-dev-build-ts",
|
||||
@@ -28,10 +28,10 @@
|
||||
"test:watch": "jest --coverage --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.4",
|
||||
"@babel/register": "^7.6.2",
|
||||
"@babel/core": "^7.7.0",
|
||||
"@babel/register": "^7.7.0",
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@polkadot/dev": "^0.32.0-beta.11",
|
||||
"@polkadot/ts": "^0.1.82"
|
||||
"@polkadot/dev": "^0.32.0-beta.13",
|
||||
"@polkadot/ts": "^0.1.84"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api-contract",
|
||||
"version": "0.95.2",
|
||||
"version": "0.96.1",
|
||||
"description": "Interfaces for interacting with contracts and contract ABIs",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,7 +26,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-contract#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@polkadot/types": "^0.95.2"
|
||||
"@babel/runtime": "^7.7.1",
|
||||
"@polkadot/types": "^0.96.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import erc20Abi from '../test/contracts/Erc20.json';
|
||||
import incrementerAbi from '../test/contracts/incrementer.json';
|
||||
|
||||
import { Abi } from '.';
|
||||
|
||||
describe('Abi', (): void => {
|
||||
describe('erc20', (): void => {
|
||||
describe('incrementer', (): void => {
|
||||
let abi: Abi;
|
||||
|
||||
beforeEach((): void => {
|
||||
abi = new Abi(erc20Abi);
|
||||
abi = new Abi(incrementerAbi);
|
||||
});
|
||||
|
||||
it('has the attached methods', (): void => {
|
||||
expect(Object.keys(abi.messages)).toEqual(
|
||||
['totalSupply', 'balanceOf', 'allowance', 'transfer', 'approve', 'transferFrom']
|
||||
expect(Object.values(abi.abi.contract.messages).map(({ name }): string => name)).toEqual(
|
||||
['inc', 'get', 'compare']
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ContractABI, ContractABIPre, ContractABIFn, InterfaceAbi, AbiMessages } from './types';
|
||||
import { AbiConstructors, AbiMessages, ContractABI, ContractABIPre, ContractABIFn, InterfaceAbi } from './types';
|
||||
import { stringCamelCase } from '@polkadot/util';
|
||||
|
||||
import ContractRegistry from './ContractRegistry';
|
||||
@@ -10,11 +10,11 @@ import ContractRegistry from './ContractRegistry';
|
||||
export default class ContractAbi extends ContractRegistry implements InterfaceAbi {
|
||||
public readonly abi: ContractABI;
|
||||
|
||||
public readonly constructors: ContractABIFn[];
|
||||
public readonly constructors: AbiConstructors;
|
||||
|
||||
public readonly messages: AbiMessages = {};
|
||||
public readonly messages: AbiMessages;
|
||||
|
||||
public constructor (abi: ContractABIPre) {
|
||||
constructor (abi: ContractABIPre) {
|
||||
super(abi);
|
||||
[this.abi, this.constructors, this.messages] = this.decodeAbi(abi);
|
||||
}
|
||||
@@ -25,16 +25,21 @@ export default class ContractAbi extends ContractRegistry implements InterfaceAb
|
||||
const abi = this.convertAbi(abiPre);
|
||||
const constructors = abi.contract.constructors.map(
|
||||
(constructor, index): ContractABIFn => {
|
||||
return this.createMethod(`constructor ${index}`, constructor);
|
||||
return this.createMessage(`constructor ${index}`, constructor);
|
||||
}
|
||||
);
|
||||
|
||||
const messages: AbiMessages = {};
|
||||
abi.contract.messages.forEach((method): void => {
|
||||
const name = stringCamelCase(method.name);
|
||||
const messages: AbiMessages = abi.contract.messages.reduce(
|
||||
(result: AbiMessages, message): AbiMessages => {
|
||||
const name = stringCamelCase(message.name);
|
||||
|
||||
messages[name] = this.createMethod(`messages.${name}`, method);
|
||||
});
|
||||
return {
|
||||
...result,
|
||||
[name]: this.createMessage(`messages.${name}`, message)
|
||||
};
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
return [abi, constructors, messages];
|
||||
}
|
||||
|
||||
@@ -2,14 +2,54 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { CodecArg, TypeDef } from '@polkadot/types/types';
|
||||
import { ContractABIArgBasePre, ContractABIContract, ContractABIContractPre, ContractABIEvent, ContractABIEventPre, ContractABIFn, ContractABIFnArg, ContractABIMethod, ContractABIMethodBase, ContractABIMethodPre, ContractABI, ContractABIPre, ContractABIRange, ContractABIRangePre, ContractABIStorage, ContractABIStorageLayout, ContractABIStorageLayoutPre, ContractABIStoragePre, ContractABIStorageStruct, ContractABIStorageStructPre, ContractABITypePre } from './types';
|
||||
import { Compact } from '@polkadot/types';
|
||||
import { CodecArg, Constructor, TypeDef } from '@polkadot/types/types';
|
||||
import { ContractABIArgBasePre, ContractABIContract, ContractABIContractPre, ContractABIEvent, ContractABIEventPre, ContractABIFn, ContractABIFnArg, ContractABIMessage, ContractABIMessageBase, ContractABIMessagePre, ContractABI, ContractABIMessageCommon, ContractABIPre, ContractABIRange, ContractABIRangePre, ContractABIStorage, ContractABIStorageLayout, ContractABIStorageLayoutPre, ContractABIStoragePre, ContractABIStorageStruct, ContractABIStorageStructPre, ContractABITypePre } from './types';
|
||||
import { Compact, u32, createClass, createType, encodeType } from '@polkadot/types';
|
||||
|
||||
import { assert, isNumber, isString, isNull, isObject, isUndefined, stringCamelCase } from '@polkadot/util';
|
||||
import { assert, hexToU8a, isNumber, isString, isNull, isObject, isUndefined, stringCamelCase, isHex, hexToNumber } from '@polkadot/util';
|
||||
|
||||
import MetaRegistry from './MetaRegistry';
|
||||
import { createArgClass } from './method';
|
||||
|
||||
// parse a selector, this can be a number (older) or of [<hex>, <hex>, ...]. However,
|
||||
// just catch everything (since this is now non-standard for u32 anyway)
|
||||
function parseSelector (fnname: string, input: ContractABIMessageCommon['selector']): u32 {
|
||||
if (isNumber(input)) {
|
||||
return createType('u32', input);
|
||||
} else if (isHex(input)) {
|
||||
return createType('u32', hexToU8a(input));
|
||||
} else if (typeof input === 'string') {
|
||||
try {
|
||||
const array = JSON.parse(input);
|
||||
|
||||
assert(array.length === 4, `${fnname}: Invalid selector length`);
|
||||
|
||||
return createType('u32', Uint8Array.from(
|
||||
// the as number[] is here to pacify TS, it doesn't quite know how to handle the cb
|
||||
(array as number[]).map((value: string | number): number =>
|
||||
isHex(value)
|
||||
? hexToNumber(value.toString())
|
||||
: value
|
||||
)
|
||||
));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`${fnname}: Unable to parse selector`);
|
||||
}
|
||||
|
||||
function createArgClass (args: ContractABIFnArg[], baseDef: Record<string, string>): Constructor {
|
||||
return createClass(
|
||||
JSON.stringify(
|
||||
args.reduce((base: Record<string, any>, { name, type }): Record<string, any> => {
|
||||
base[name] = type.displayName || encodeType(type);
|
||||
|
||||
return base;
|
||||
}, baseDef)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default class ContractRegistry extends MetaRegistry {
|
||||
// Contract ABI helpers
|
||||
@@ -26,7 +66,7 @@ export default class ContractRegistry extends MetaRegistry {
|
||||
}
|
||||
|
||||
public validateConstructors ({ contract: { constructors } }: ContractABIPre): void {
|
||||
constructors.forEach((constructor: ContractABIMethodPre, index): void => {
|
||||
constructors.forEach((constructor: ContractABIMessagePre, index): void => {
|
||||
const unknownKeys = Object.keys(constructor).filter((key): boolean => !['args', 'docs', 'name', 'selector'].includes(key));
|
||||
|
||||
assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI constructor`);
|
||||
@@ -35,41 +75,46 @@ export default class ContractRegistry extends MetaRegistry {
|
||||
});
|
||||
}
|
||||
|
||||
public validateMethods ({ contract: { messages } }: ContractABIPre): void {
|
||||
messages.forEach((method): void => {
|
||||
const unknownKeys = Object.keys(method).filter((key): boolean => !['args', 'docs', 'mutates', 'name', 'selector', 'return_type'].includes(key));
|
||||
public validateMessages ({ contract: { messages } }: ContractABIPre): void {
|
||||
messages.forEach((message): void => {
|
||||
const unknownKeys = Object.keys(message).filter((key): boolean => !['args', 'docs', 'mutates', 'name', 'selector', 'return_type'].includes(key));
|
||||
const fnname = `messages.${message.name}`;
|
||||
|
||||
assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI args for messages.${method.name}`);
|
||||
const { name, selector, return_type: returnType } = method;
|
||||
assert(isNumber(name) && isString(this.stringAt(name)), `Expected name for messages.${method.name}`);
|
||||
assert(isNumber(selector), `Expected selector for messages.${method.name}`);
|
||||
assert(isNull(returnType) || (isNumber(returnType.ty) && isObject(this.typeDefAt(returnType.ty))), `Expected return_type for messages.${method.name}`);
|
||||
assert(unknownKeys.length === 0, `Unknown keys ${unknownKeys.join(', ')} found in ABI args for messages.${message.name}`);
|
||||
|
||||
this.validateArgs(`messages.${method.name}`, method.args);
|
||||
const { name, selector, return_type: returnType } = message;
|
||||
|
||||
assert(isNumber(name) && isString(this.stringAt(name)), `Expected name for ${fnname}`);
|
||||
assert(isNull(returnType) || (isNumber(returnType.ty) && isObject(this.typeDefAt(returnType.ty))), `Expected return_type for ${fnname}`);
|
||||
|
||||
parseSelector(fnname, selector);
|
||||
this.validateArgs(fnname, message.args);
|
||||
});
|
||||
}
|
||||
|
||||
public validateAbi (abi: ContractABIPre): void {
|
||||
const unknownKeys = Object.keys(abi.contract).filter((key): boolean => !['constructors', 'docs', 'events', 'messages', 'name'].includes(key));
|
||||
|
||||
assert(unknownKeys.length === 0, `Unknown fields ${unknownKeys.join(', ')} found in ABI`);
|
||||
|
||||
const { contract: { constructors, messages, name } } = abi;
|
||||
|
||||
assert(constructors && messages && isString(this.stringAt(name)), 'ABI should have constructors, messages & name sections');
|
||||
|
||||
this.validateConstructors(abi);
|
||||
this.validateMethods(abi);
|
||||
this.validateMessages(abi);
|
||||
}
|
||||
|
||||
public createMethod (name: string, method: Partial<ContractABIMethod> & ContractABIMethodBase): ContractABIFn {
|
||||
const args = method.args.map(({ name, type }): ContractABIFnArg => {
|
||||
public createMessage (name: string, message: Partial<ContractABIMessage> & ContractABIMessageBase): ContractABIFn {
|
||||
const args = message.args.map(({ name, type }): ContractABIFnArg => {
|
||||
assert(isObject(type), `Invalid type at index ${type}`);
|
||||
return {
|
||||
name: stringCamelCase(name),
|
||||
type
|
||||
};
|
||||
});
|
||||
const Clazz = createArgClass(args, isUndefined(method.selector) ? {} : { __selector: 'u32' });
|
||||
const baseStruct: { [index: string]: any } = { __selector: method.selector };
|
||||
const Clazz = createArgClass(args, isUndefined(message.selector) ? {} : { __selector: 'u32' });
|
||||
const baseStruct: { [index: string]: any } = { __selector: isUndefined(message.selector) ? undefined : parseSelector(name, message.selector) };
|
||||
const encoder = (...params: CodecArg[]): Uint8Array => {
|
||||
assert(params.length === args.length, `Expected ${args.length} arguments to contract ${name}, found ${params.length}`);
|
||||
|
||||
@@ -87,9 +132,8 @@ export default class ContractRegistry extends MetaRegistry {
|
||||
const fn = (encoder as ContractABIFn);
|
||||
|
||||
fn.args = args;
|
||||
fn.isConstant = !(method.mutates || false);
|
||||
fn.type = method.returnType || null;
|
||||
|
||||
fn.isConstant = !(message.mutates || false);
|
||||
fn.type = message.returnType || null;
|
||||
return fn;
|
||||
}
|
||||
|
||||
@@ -112,7 +156,7 @@ export default class ContractRegistry extends MetaRegistry {
|
||||
public convertContract ({ constructors, messages, name, events, ...contract }: ContractABIContractPre): ContractABIContract {
|
||||
return {
|
||||
constructors: this.convertConstructors(constructors),
|
||||
messages: messages.map(method => this.convertMethod(method)),
|
||||
messages: messages.map(message => this.convertMessage(message)),
|
||||
name: this.stringAt(name),
|
||||
...(events
|
||||
? { events: events.map(event => this.convertEvent(event)) }
|
||||
@@ -121,17 +165,17 @@ export default class ContractRegistry extends MetaRegistry {
|
||||
};
|
||||
}
|
||||
|
||||
public convertConstructors (constructors: ContractABIMethodPre[]): ContractABIMethod[] {
|
||||
public convertConstructors (constructors: ContractABIMessagePre[]): ContractABIMessage[] {
|
||||
return constructors.map(
|
||||
(constructor: ContractABIMethodPre): ContractABIMethod => {
|
||||
return this.convertMethod(constructor);
|
||||
(constructor: ContractABIMessagePre): ContractABIMessage => {
|
||||
return this.convertMessage(constructor);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public convertMethod ({ args, name, return_type: returnType, ...method }: ContractABIMethodPre): ContractABIMethod {
|
||||
public convertMessage ({ args, name, return_type: returnType, ...message }: ContractABIMessagePre): ContractABIMessage {
|
||||
return {
|
||||
...method,
|
||||
...message,
|
||||
args: this.convertArgs(args),
|
||||
name: this.stringAt(name),
|
||||
returnType: returnType ? this.convertType(returnType) : null
|
||||
|
||||
@@ -40,7 +40,7 @@ class MetadataRegistryLookup {
|
||||
|
||||
public typeDefs: TypeDef[] = [];
|
||||
|
||||
public constructor ({ registry: { strings, types } }: MetaRegistryJson) {
|
||||
constructor ({ registry: { strings, types } }: MetaRegistryJson) {
|
||||
this._strings = strings;
|
||||
this._types = types;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class MetadataRegistryLookup {
|
||||
}
|
||||
|
||||
export default class MetaRegistry extends MetadataRegistryLookup {
|
||||
public constructor (json: MetaRegistryJson) {
|
||||
constructor (json: MetaRegistryJson) {
|
||||
super(json);
|
||||
|
||||
// Generate TypeDefs for each provided registry type
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SubmittableModuleExtrinsics } from '@polkadot/api/types';
|
||||
import { ApiObject, ContractABIPre, ContractBase } from './types';
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import Abi from './Abi';
|
||||
|
||||
// NOTE Experimental, POC, bound to change
|
||||
export default abstract class RxBase implements ContractBase<'rxjs'> {
|
||||
public readonly abi: Abi;
|
||||
|
||||
public readonly api: ApiObject<'rxjs'>;
|
||||
|
||||
public readonly apiContracts: SubmittableModuleExtrinsics<'rxjs'>;
|
||||
|
||||
public constructor (api: ApiObject<'rxjs'>, abi: ContractABIPre | Abi) {
|
||||
this.abi = abi instanceof Abi
|
||||
? abi
|
||||
: new Abi(abi);
|
||||
this.api = api;
|
||||
|
||||
// cater for substrate 2.x & 1.x (in order)
|
||||
this.apiContracts = api.tx.contracts || api.tx.contract;
|
||||
|
||||
assert(this.apiContracts && this.apiContracts.putCode, 'You need to connect to a node with the contracts module, the metadata does not enable api.tx.contracts on this instance');
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SubmittableResultImpl } from '@polkadot/api/types';
|
||||
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
|
||||
import { IKeyringPair } from '@polkadot/types/types';
|
||||
import { ContractABIPre } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiRx, SubmittableResult } from '@polkadot/api';
|
||||
import { createType } from '@polkadot/types';
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import Abi from './Abi';
|
||||
import RxBase from './RxBase';
|
||||
import RxContract from './RxContract';
|
||||
|
||||
type BlueprintCreateResultSubscription = Observable<BlueprintCreateResult>;
|
||||
|
||||
export interface BlueprintCreate {
|
||||
signAndSend (account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription;
|
||||
}
|
||||
|
||||
class BlueprintCreateResult extends SubmittableResult {
|
||||
public readonly contract?: RxContract;
|
||||
|
||||
public constructor (result: SubmittableResultImpl, contract?: RxContract) {
|
||||
super(result);
|
||||
|
||||
this.contract = contract;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE Experimental, POC, bound to change
|
||||
export default class Blueprint extends RxBase {
|
||||
public readonly codeHash: Hash;
|
||||
|
||||
public constructor (api: ApiRx, abi: ContractABIPre | Abi, codeHash: string | Hash) {
|
||||
super(api, abi);
|
||||
|
||||
this.codeHash = createType('Hash', codeHash);
|
||||
}
|
||||
|
||||
public deployContract (constructorIndex = 0, endowment: number | BN, maxGas: number | BN, ...params: any[]): BlueprintCreate {
|
||||
assert(!!this.abi.constructors[constructorIndex], `Specified constructor index ${constructorIndex} does not exist`);
|
||||
const signAndSend = (account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription => {
|
||||
return this.apiContracts
|
||||
.create(endowment, maxGas, this.codeHash, this.abi.constructors[constructorIndex](...params))
|
||||
.signAndSend(account)
|
||||
.pipe(map(this.createResult));
|
||||
};
|
||||
|
||||
return { signAndSend };
|
||||
}
|
||||
|
||||
private createResult = (result: SubmittableResult): BlueprintCreateResult => {
|
||||
let contract: RxContract | undefined;
|
||||
|
||||
if (result.isFinalized) {
|
||||
const record = result.findRecord('contract', 'Instantiated');
|
||||
|
||||
if (record) {
|
||||
contract = new RxContract(this.api, this.abi, record.event.data[1] as Address);
|
||||
}
|
||||
}
|
||||
|
||||
return new BlueprintCreateResult(result, contract);
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SubmittableResultImpl } from '@polkadot/api/types';
|
||||
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
|
||||
import { IKeyringPair } from '@polkadot/types/types';
|
||||
import { ContractABIPre } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiRx, SubmittableResult } from '@polkadot/api';
|
||||
import { compactAddLength, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import Abi from './Abi';
|
||||
import RxBase from './RxBase';
|
||||
import RxBlueprint from './RxBlueprint';
|
||||
|
||||
// Ok, tried, failed, eventually ... well, we are only trying with RxJs as a
|
||||
// start, so take a big fat shortcut with this version, real intended version
|
||||
// follows this and is commented out
|
||||
type CodePutCodeResultSubscription = Observable<CodePutCodeResult>;
|
||||
// type ICodePutCodeResultSubscription<ApiType> =
|
||||
// ApiType extends 'rxjs'
|
||||
// ? Observable<CodePutCodeResult>
|
||||
// : Promise<() => void>;
|
||||
|
||||
// unlike the ISubmittableExtrinsic, it doesn't extend IExtrinsic and only
|
||||
// implements one var iant of signAndSend - this is purely done to see what
|
||||
// is hanging where, with the bare-mainimum from a simplicity perspective
|
||||
// Very obvious is that it supports only 1 version of signAndSend
|
||||
// (we need to revisit this, but probably ok for initial?)
|
||||
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
|
||||
export interface CodePutCode {
|
||||
signAndSend (account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription;
|
||||
}
|
||||
|
||||
class CodePutCodeResult extends SubmittableResult {
|
||||
public readonly blueprint?: RxBlueprint;
|
||||
|
||||
public constructor (result: SubmittableResultImpl, blueprint?: RxBlueprint) {
|
||||
super(result);
|
||||
|
||||
this.blueprint = blueprint;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE Experimental, POC, bound to change
|
||||
export default class RxCode extends RxBase {
|
||||
public readonly code: Uint8Array;
|
||||
|
||||
public constructor (api: ApiRx, abi: ContractABIPre | Abi, wasm: string | Uint8Array) {
|
||||
super(api, abi);
|
||||
|
||||
this.code = u8aToU8a(wasm);
|
||||
}
|
||||
|
||||
public createBlueprint (maxGas: number | BN): CodePutCode {
|
||||
const signAndSend = (account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription => {
|
||||
return this.apiContracts
|
||||
.putCode(maxGas, compactAddLength(this.code))
|
||||
.signAndSend(account)
|
||||
.pipe(map(this.createResult));
|
||||
};
|
||||
|
||||
return { signAndSend };
|
||||
}
|
||||
|
||||
private createResult = (result: SubmittableResultImpl): CodePutCodeResult => {
|
||||
let blueprint: RxBlueprint | undefined;
|
||||
|
||||
if (result.isFinalized) {
|
||||
const record = result.findRecord('contract', 'CodeStored');
|
||||
|
||||
if (record) {
|
||||
blueprint = new RxBlueprint(this.api, this.abi, record.event.data[0] as Hash);
|
||||
}
|
||||
}
|
||||
|
||||
return new CodePutCodeResult(result, blueprint);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, Address } from '@polkadot/types/interfaces';
|
||||
import { IKeyringPair } from '@polkadot/types/types';
|
||||
import { ContractABIPre, ContractABIFn, InterfaceContract, InterfaceContractCalls } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ApiRx, SubmittableResult } from '@polkadot/api';
|
||||
import { createType } from '@polkadot/types';
|
||||
import Abi from './Abi';
|
||||
import RxBase from './RxBase';
|
||||
|
||||
export type ContractCallResultSubscription = Observable<SubmittableResult>;
|
||||
|
||||
export interface ContractCall {
|
||||
signAndSend (account: IKeyringPair | string | AccountId | Address): ContractCallResultSubscription;
|
||||
}
|
||||
|
||||
type CallResult = (value: BN | number, maxGas: BN | number, ...params: any[]) => ContractCall;
|
||||
|
||||
// NOTE Experimental, POC, bound to change
|
||||
export default class RxContract extends RxBase implements InterfaceContract {
|
||||
public readonly address: Address;
|
||||
|
||||
public readonly calls: InterfaceContractCalls = {};
|
||||
|
||||
public constructor (api: ApiRx, abi: ContractABIPre | Abi, address: string | AccountId | Address) {
|
||||
super(api, abi);
|
||||
|
||||
this.address = createType('Address', address);
|
||||
|
||||
Object.entries(this.abi.messages).forEach(([name]): void => {
|
||||
this.calls[name] = (fn: ContractABIFn): CallResult =>
|
||||
(value: BN | number, maxGas: BN | number, ...params: any[]): ContractCall =>
|
||||
this.apiContracts.call(this.address, value, maxGas, fn(...params));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiTypes, DecorateMethod, SubmittableResultImpl } from '@polkadot/api/types';
|
||||
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
|
||||
import { IKeyringPair } from '@polkadot/types/types';
|
||||
import { ApiObject, ContractABIPre } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { createType } from '@polkadot/types';
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Contract from './Contract';
|
||||
import { BaseWithTx } from './util';
|
||||
|
||||
type BlueprintCreateResultSubscription<ApiType extends ApiTypes> = Observable<BlueprintCreateResult<ApiType>>;
|
||||
|
||||
export interface BlueprintCreate<ApiType extends ApiTypes> {
|
||||
signAndSend (account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription<ApiType>;
|
||||
}
|
||||
|
||||
class BlueprintCreateResult<ApiType extends ApiTypes> extends SubmittableResult {
|
||||
public readonly contract?: Contract<ApiType>;
|
||||
|
||||
constructor (result: SubmittableResultImpl, contract?: Contract<ApiType>) {
|
||||
super(result);
|
||||
|
||||
this.contract = contract;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE Experimental, POC, bound to change
|
||||
export default class Blueprint<ApiType extends ApiTypes> extends BaseWithTx<ApiType> {
|
||||
public readonly codeHash: Hash;
|
||||
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, codeHash: string | Hash) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
this.codeHash = createType('Hash', codeHash);
|
||||
}
|
||||
|
||||
public deployContract (constructorIndex = 0, endowment: number | BN, maxGas: number | BN, ...params: any[]): BlueprintCreate<ApiType> {
|
||||
assert(!!this.abi.constructors[constructorIndex], `Specified constructor index ${constructorIndex} does not exist`);
|
||||
|
||||
return {
|
||||
signAndSend: this.decorateMethod(
|
||||
(account: IKeyringPair | string | AccountId | Address): BlueprintCreateResultSubscription<ApiType> => {
|
||||
return this.apiContracts
|
||||
.create(endowment, maxGas, this.codeHash, this.abi.constructors[constructorIndex](...params))
|
||||
.signAndSend(account)
|
||||
.pipe(map(this.createResult));
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
private createResult = (result: SubmittableResult): BlueprintCreateResult<ApiType> => {
|
||||
let contract: Contract<ApiType> | undefined;
|
||||
|
||||
if (result.isFinalized) {
|
||||
const record = result.findRecord('contract', 'Instantiated');
|
||||
|
||||
if (record) {
|
||||
contract = new Contract<ApiType>(this.api, this.abi, this.decorateMethod, record.event.data[1] as Address);
|
||||
}
|
||||
}
|
||||
|
||||
return new BlueprintCreateResult(result, contract);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiTypes, DecorateMethod, SubmittableResultImpl } from '@polkadot/api/types';
|
||||
import { AccountId, Address, Hash } from '@polkadot/types/interfaces';
|
||||
import { IKeyringPair } from '@polkadot/types/types';
|
||||
import { ApiObject, ContractABIPre } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { compactAddLength, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Blueprint from './Blueprint';
|
||||
import { BaseWithTx } from './util';
|
||||
|
||||
type CodePutCodeResultSubscription<ApiType extends ApiTypes> = Observable<CodePutCodeResult<ApiType>>;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
|
||||
export interface CodePutCode<ApiType extends ApiTypes> {
|
||||
signAndSend (account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription<ApiType>;
|
||||
}
|
||||
|
||||
class CodePutCodeResult<ApiType extends ApiTypes> extends SubmittableResult {
|
||||
public readonly blueprint?: Blueprint<ApiType>;
|
||||
|
||||
constructor (result: SubmittableResultImpl, blueprint?: Blueprint<ApiType>) {
|
||||
super(result);
|
||||
|
||||
this.blueprint = blueprint;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE Experimental, POC, bound to change
|
||||
export default class Code<ApiType extends ApiTypes> extends BaseWithTx<ApiType> {
|
||||
public readonly code: Uint8Array;
|
||||
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, wasm: string | Uint8Array) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
this.code = u8aToU8a(wasm);
|
||||
}
|
||||
|
||||
public createBlueprint = (maxGas: number | BN): CodePutCode<ApiType> => {
|
||||
return {
|
||||
signAndSend: this.decorateMethod(
|
||||
(account: IKeyringPair | string | AccountId | Address): CodePutCodeResultSubscription<ApiType> => this.apiContracts
|
||||
.putCode(maxGas, compactAddLength(this.code))
|
||||
.signAndSend(account)
|
||||
.pipe(map(this.createResult))
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
private createResult = (result: SubmittableResultImpl): CodePutCodeResult<ApiType> => {
|
||||
let blueprint: Blueprint<ApiType> | undefined;
|
||||
|
||||
if (result.isFinalized) {
|
||||
const record = result.findRecord('contract', 'CodeStored');
|
||||
|
||||
if (record) {
|
||||
blueprint = new Blueprint<ApiType>(this.api, this.abi, this.decorateMethod, record.event.data[0] as Hash);
|
||||
}
|
||||
}
|
||||
|
||||
return new CodePutCodeResult(result, blueprint);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiTypes, DecorateMethod, ObsInnerType } from '@polkadot/api/types';
|
||||
import { AccountId, Address, ContractExecResult } from '@polkadot/types/interfaces';
|
||||
import { Codec, IKeyringPair } from '@polkadot/types/types';
|
||||
import { ApiObject, ContractABIMessage, ContractABIPre, ContractCallOutcome } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { createType } from '@polkadot/types';
|
||||
import Abi from '../Abi';
|
||||
import { formatData } from '../util';
|
||||
import { BaseWithTxAndRpcCall } from './util';
|
||||
|
||||
type ContractCallTypes = 'tx' | 'rpc';
|
||||
|
||||
type ContractCallResultSubscription<ApiType extends ApiTypes, CallType extends ContractCallTypes> = ApiType extends 'rxjs'
|
||||
? Observable<ContractCallResult<CallType>>
|
||||
: Promise<ObsInnerType<ContractCallResult<CallType>>>;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
|
||||
export interface ContractCall<ApiType extends ApiTypes, CallType extends ContractCallTypes> {
|
||||
send (account: IKeyringPair | string | AccountId | Address): ContractCallResultSubscription<ApiType, CallType>;
|
||||
}
|
||||
|
||||
export type ContractCallResult<CallType extends ContractCallTypes> = CallType extends 'rpc'
|
||||
? Observable<ContractCallOutcome>
|
||||
: Observable<SubmittableResult>;
|
||||
|
||||
export default class Contract<ApiType extends ApiTypes> extends BaseWithTxAndRpcCall<ApiType> {
|
||||
public readonly address: Address;
|
||||
|
||||
public call (as: 'rpc', message: string, value: BN | number, gasLimit: BN | number, ...params: any[]): ContractCall<ApiType, 'rpc'>;
|
||||
public call (as: 'tx', message: string, value: BN | number, gasLimit: BN | number, ...params: any[]): ContractCall<ApiType, 'tx'>;
|
||||
public call<CallType extends ContractCallTypes> (as: CallType, message: string, value: BN | number, gasLimit: BN | number, ...params: any[]): ContractCall<ApiType, CallType> {
|
||||
const { fn, def } = this.getMessage(message);
|
||||
|
||||
return {
|
||||
send: this.decorateMethod(
|
||||
as === 'rpc'
|
||||
? (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'rpc'> => {
|
||||
return this.rpcContractsCall(
|
||||
createType('ContractCallRequest', {
|
||||
origin: account,
|
||||
dest: this.address.toString(),
|
||||
value,
|
||||
gasLimit,
|
||||
inputData: fn(...params)
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
map((result: ContractExecResult): ContractCallOutcome =>
|
||||
this.createOutcome(result, createType('AccountId', account), def, params)
|
||||
)
|
||||
);
|
||||
}
|
||||
: (account: IKeyringPair | string | AccountId | Address): ContractCallResult<'tx'> => {
|
||||
return this.apiContracts
|
||||
.call(this.address, value, gasLimit, fn(...params))
|
||||
.signAndSend(account);
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
private createOutcome (result: ContractExecResult, origin: AccountId, message: ContractABIMessage, params: any[]): ContractCallOutcome {
|
||||
let output: Codec | null = null;
|
||||
|
||||
if (result.isSuccess) {
|
||||
const { data } = result.asSuccess;
|
||||
|
||||
output = message.returnType
|
||||
? formatData(data, message.returnType)
|
||||
: createType('Data', data);
|
||||
}
|
||||
|
||||
return {
|
||||
time: Date.now(),
|
||||
message,
|
||||
origin,
|
||||
params,
|
||||
result,
|
||||
isSuccess: result.isSuccess,
|
||||
output
|
||||
};
|
||||
}
|
||||
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>, address: string | AccountId | Address) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
this.address = createType('Address', address);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 2017-2019 @polkadot/api authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export { default as Blueprint } from './Blueprint';
|
||||
export { default as Code } from './Code';
|
||||
export { default as Contract } from './Contract';
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright 2017-2019 @polkadot/api authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiTypes, DecorateMethod, DecoratedRpc, SubmittableModuleExtrinsics } from '@polkadot/api/types';
|
||||
import { ApiObject, ContractABIMessage, ContractABIPre, ContractBase, ContractMessage } from '../types';
|
||||
import { RpcInterface } from '@polkadot/rpc-core/jsonrpc.types';
|
||||
|
||||
import { assert, stringCamelCase } from '@polkadot/util';
|
||||
import Abi from '../Abi';
|
||||
|
||||
export abstract class Base<ApiType extends ApiTypes> implements ContractBase<ApiType> {
|
||||
public readonly abi: Abi;
|
||||
|
||||
public readonly api: ApiObject<ApiType>;
|
||||
|
||||
public readonly decorateMethod: DecorateMethod<ApiType>;
|
||||
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>) {
|
||||
this.abi = abi instanceof Abi
|
||||
? abi
|
||||
: new Abi(abi);
|
||||
this.api = api;
|
||||
this.decorateMethod = decorateMethod;
|
||||
}
|
||||
|
||||
public get messages (): ContractMessage[] {
|
||||
return this.abi.abi.contract.messages
|
||||
.map(
|
||||
(def: ContractABIMessage, index): ContractMessage => ({
|
||||
index,
|
||||
def,
|
||||
fn: this.abi.messages[def.name] || this.abi.messages[stringCamelCase(name)]
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public getMessage (nameOrIndex?: string | number): ContractMessage {
|
||||
const index = nameOrIndex
|
||||
? typeof nameOrIndex === 'number'
|
||||
? nameOrIndex
|
||||
: this.abi.abi.contract.messages.findIndex((message): boolean => nameOrIndex === message.name || nameOrIndex === stringCamelCase(message.name))
|
||||
: 0;
|
||||
const def = this.abi.abi.contract.messages[index];
|
||||
assert(!!def, `Attempted to access a contract message that does not exist: ${typeof nameOrIndex === 'number' ? `index ${nameOrIndex}` : nameOrIndex}`);
|
||||
|
||||
const fn = this.abi.messages[def.name] || this.abi.messages[stringCamelCase(def.name)];
|
||||
return { index, def, fn };
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseWithTx<ApiType extends ApiTypes> extends Base<ApiType> {
|
||||
protected get apiContracts (): SubmittableModuleExtrinsics<'rxjs'> {
|
||||
return this.api.rx.tx.contracts;
|
||||
}
|
||||
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
assert(this.api.rx.tx.contracts && this.api.rx.tx.contracts.putCode, 'You need to connect to a node with the contracts module, the metadata does not enable api.tx.contracts on this instance');
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseWithTxAndRpcCall<ApiType extends ApiTypes> extends BaseWithTx<ApiType> {
|
||||
protected get rpcContractsCall (): DecoratedRpc<'rxjs', RpcInterface>['contracts']['call'] {
|
||||
return this.api.rx.rpc.contracts.call;
|
||||
}
|
||||
|
||||
constructor (api: ApiObject<ApiType>, abi: ContractABIPre | Abi, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super(api, abi, decorateMethod);
|
||||
|
||||
assert(this.api.rx.rpc.contracts && this.api.rx.tx.contracts.call, 'You need to connect to a node with the contracts module, the metadata does not enable api.rpc.contracts.call on this instance');
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,5 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export { default as Abi } from './Abi';
|
||||
export { default as RxBlueprint } from './RxBlueprint';
|
||||
export { default as RxCode } from './RxCode';
|
||||
export { default as RxContract } from './RxContract';
|
||||
export * from './rx';
|
||||
export * from './promise';
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Constructor } from '@polkadot/types/types';
|
||||
import { ContractABIFnArg } from './types';
|
||||
|
||||
import { createClass, encodeType } from '@polkadot/types';
|
||||
|
||||
export function createArgClass (args: ContractABIFnArg[], baseDef: Record<string, string>): Constructor {
|
||||
return createClass(
|
||||
JSON.stringify(
|
||||
args.reduce((base: Record<string, any>, { name, type }): Record<string, any> => {
|
||||
base[name] = encodeType(type);
|
||||
|
||||
return base;
|
||||
}, baseDef)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Hash } from '@polkadot/types/interfaces';
|
||||
import { ContractABIPre } from '../types';
|
||||
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/promise';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Blueprint from '../base/Blueprint';
|
||||
|
||||
export default class PromiseBlueprint extends Blueprint<'promise'> {
|
||||
constructor (api: ApiPromise, abi: ContractABIPre | Abi, codeHash: string | Hash) {
|
||||
super(api, abi, decorateMethod, codeHash);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ContractABIPre } from '../types';
|
||||
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/promise';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Code from '../base/Code';
|
||||
|
||||
export default class PromiseCode extends Code<'promise'> {
|
||||
constructor (api: ApiPromise, abi: ContractABIPre | Abi, wasm: string | Uint8Array) {
|
||||
super(api, abi, decorateMethod, wasm);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { ContractABIPre } from '../types';
|
||||
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/promise';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Contract from '../base/Contract';
|
||||
|
||||
export default class PromiseContract extends Contract<'promise'> {
|
||||
constructor (api: ApiPromise, abi: ContractABIPre | Abi, address: string | AccountId) {
|
||||
super(api, abi, decorateMethod, address);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export { default as PromiseBlueprint } from './PromiseBlueprint';
|
||||
export { default as PromiseCode } from './PromiseCode';
|
||||
export { default as PromiseContract } from './PromiseContract';
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Hash } from '@polkadot/types/interfaces';
|
||||
import { ContractABIPre } from '../types';
|
||||
|
||||
import { ApiRx } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/rx';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Blueprint from '../base/Blueprint';
|
||||
|
||||
export default class RxBlueprint extends Blueprint<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: ContractABIPre | Abi, codeHash: string | Hash) {
|
||||
super(api, abi, decorateMethod, codeHash);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ContractABIPre } from '../types';
|
||||
|
||||
import { ApiRx } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/rx';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Code from '../base/Code';
|
||||
|
||||
export default class RxCode extends Code<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: ContractABIPre | Abi, wasm: string | Uint8Array) {
|
||||
super(api, abi, decorateMethod, wasm);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { ContractABIPre } from '../types';
|
||||
|
||||
import { ApiRx } from '@polkadot/api';
|
||||
import { decorateMethod } from '@polkadot/api/rx';
|
||||
|
||||
import Abi from '../Abi';
|
||||
import Contract from '../base/Contract';
|
||||
|
||||
export default class RxContract extends Contract<'rxjs'> {
|
||||
constructor (api: ApiRx, abi: ContractABIPre | Abi, address: string | AccountId) {
|
||||
super(api, abi, decorateMethod, address);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 2017-2019 @polkadot/api-contract authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export { default as RxBlueprint } from './RxBlueprint';
|
||||
export { default as RxCode } from './RxCode';
|
||||
export { default as RxContract } from './RxContract';
|
||||
@@ -2,17 +2,26 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SubmittableModuleExtrinsics } from '@polkadot/api/types';
|
||||
import { Address } from '@polkadot/types/interfaces';
|
||||
import { CodecArg } from '@polkadot/types/types';
|
||||
import { ApiTypes, DecorateMethod } from '@polkadot/api/types';
|
||||
import { AccountId, Address, ContractExecResult } from '@polkadot/types/interfaces';
|
||||
import { Codec, CodecArg } from '@polkadot/types/types';
|
||||
import { MetaRegistryJson, StringIndex, TypeIndex, TypeDef } from '@polkadot/types/codec/create/types';
|
||||
|
||||
// import { Observable } from 'rxjs';
|
||||
import { ApiPromise, ApiRx } from '@polkadot/api';
|
||||
|
||||
export type ApiObject<ApiType> = ApiType extends 'rxjs'
|
||||
export type ApiObject<ApiType extends ApiTypes> = ApiType extends 'rxjs'
|
||||
? ApiRx
|
||||
: ApiPromise;
|
||||
|
||||
export interface ContractBase<ApiType extends ApiTypes> {
|
||||
readonly abi: InterfaceAbi;
|
||||
readonly api: ApiObject<ApiType>;
|
||||
readonly decorateMethod: DecorateMethod<ApiType>;
|
||||
getMessage: (name: string) => ContractMessage;
|
||||
messages: ContractMessage[];
|
||||
}
|
||||
|
||||
export interface ContractABITypePre {
|
||||
ty: TypeIndex;
|
||||
display_name: StringIndex[];
|
||||
@@ -28,31 +37,31 @@ export interface ContractABIArgBase {
|
||||
type: TypeDef;
|
||||
}
|
||||
|
||||
export type ContractABIMethodArgPre = ContractABIArgBasePre;
|
||||
export type ContractABIMessageArgPre = ContractABIArgBasePre;
|
||||
|
||||
export type ContractABIMethodArg = ContractABIArgBase;
|
||||
export type ContractABIMessageArg = ContractABIArgBase;
|
||||
|
||||
export interface ContractABIMethodBase {
|
||||
args: ContractABIMethodArg[];
|
||||
export interface ContractABIMessageBase {
|
||||
args: ContractABIMessageArg[];
|
||||
}
|
||||
|
||||
export interface ContractABIMethodBasePre {
|
||||
args: ContractABIMethodArgPre[];
|
||||
export interface ContractABIMessageBasePre {
|
||||
args: ContractABIMessageArgPre[];
|
||||
}
|
||||
|
||||
export interface ContractABIMethodCommon {
|
||||
export interface ContractABIMessageCommon {
|
||||
docs?: ContractABIDocs;
|
||||
mutates?: boolean;
|
||||
selector: number;
|
||||
selector: string | number;
|
||||
}
|
||||
|
||||
export interface ContractABIMethodPre extends ContractABIMethodCommon, ContractABIMethodBasePre {
|
||||
export interface ContractABIMessagePre extends ContractABIMessageCommon, ContractABIMessageBasePre {
|
||||
name: StringIndex;
|
||||
return_type: ContractABITypePre | null;
|
||||
}
|
||||
|
||||
export interface ContractABIMethod extends ContractABIMethodCommon {
|
||||
args: ContractABIMethodArg[];
|
||||
export interface ContractABIMessage extends ContractABIMessageCommon {
|
||||
args: ContractABIMessageArg[];
|
||||
name: string;
|
||||
returnType: TypeDef | null;
|
||||
}
|
||||
@@ -62,16 +71,16 @@ export interface ContractABIContractCommon {
|
||||
}
|
||||
|
||||
export interface ContractABIContractPre extends ContractABIContractCommon {
|
||||
constructors: ContractABIMethodPre[];
|
||||
messages: ContractABIMethodPre[];
|
||||
constructors: ContractABIMessagePre[];
|
||||
messages: ContractABIMessagePre[];
|
||||
name: StringIndex;
|
||||
events?: ContractABIEventPre[];
|
||||
docs?: ContractABIDocs;
|
||||
}
|
||||
|
||||
export interface ContractABIContract extends ContractABIContractCommon {
|
||||
constructors: ContractABIMethod[];
|
||||
messages: ContractABIMethod[];
|
||||
constructors: ContractABIMessage[];
|
||||
messages: ContractABIMessage[];
|
||||
name: string;
|
||||
events?: ContractABIEvent[];
|
||||
docs?: ContractABIDocs;
|
||||
@@ -121,7 +130,8 @@ export interface ContractABIEvent {
|
||||
}
|
||||
|
||||
export interface ContractABIRangeBase {
|
||||
'range.offset': number[];
|
||||
// can be number[] (old) or hex (new)
|
||||
'range.offset': number[] | string;
|
||||
'range.len': number;
|
||||
}
|
||||
|
||||
@@ -161,20 +171,22 @@ export type ContractABIStoragePre = ContractABIStorageStructPre;
|
||||
|
||||
export type ContractABIStorage = ContractABIStorageStruct;
|
||||
|
||||
export interface ContractMessage {
|
||||
index: number;
|
||||
fn: ContractABIFn;
|
||||
def: ContractABIMessage;
|
||||
}
|
||||
|
||||
export type AbiConstructors = ContractABIFn[];
|
||||
|
||||
export type AbiMessages = Record<string, ContractABIFn>;
|
||||
|
||||
export interface InterfaceAbi {
|
||||
readonly abi: ContractABI;
|
||||
readonly constructors: ContractABIFn[];
|
||||
readonly constructors: AbiConstructors;
|
||||
readonly messages: AbiMessages;
|
||||
}
|
||||
|
||||
export interface ContractBase<ApiType> {
|
||||
readonly abi: InterfaceAbi;
|
||||
readonly api: ApiObject<ApiType>;
|
||||
readonly apiContracts: SubmittableModuleExtrinsics<ApiType>;
|
||||
}
|
||||
|
||||
export interface InterfaceContractCalls {
|
||||
[index: string]: Function;
|
||||
}
|
||||
@@ -183,3 +195,13 @@ export interface InterfaceContract {
|
||||
readonly address: Address;
|
||||
readonly calls: InterfaceContractCalls;
|
||||
}
|
||||
|
||||
export interface ContractCallOutcome {
|
||||
time: number;
|
||||
result: ContractExecResult;
|
||||
origin: AccountId;
|
||||
output: Codec | null;
|
||||
params: any[];
|
||||
isSuccess: boolean;
|
||||
message: ContractABIMessage;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017-2019 @polkadot/rpc-core authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec, TypeDefInfo, TypeDef } from '@polkadot/types/types';
|
||||
|
||||
import { Data, Option, createClass } from '@polkadot/types';
|
||||
import { createTypeUnsafe } from '@polkadot/types/codec';
|
||||
|
||||
export function formatData (data: Data, { info, type }: TypeDef): Codec {
|
||||
const u8a = data.toU8a();
|
||||
|
||||
if (info === TypeDefInfo.Option) {
|
||||
return new Option(
|
||||
createClass(type),
|
||||
createTypeUnsafe(type, [u8a], true)
|
||||
);
|
||||
}
|
||||
|
||||
return createTypeUnsafe(type, [u8a], true);
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
[
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"total_supply\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u128>\"} }<u128>\", \"balances\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)\", \"Removed\": \"Null\"} }<([u8;32]), u128>>\"} }<([u8;32]), u128>\", \"allowances\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"} }<(AccountId, AccountId), u128>>\"} }<(AccountId, AccountId), u128>\"} }",
|
||||
"type": "{ \"total_supply\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u128>\" }<u128>\", \"balances\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)\", \"Removed\": \"Null\"\" }\" }<([u8;32]), u128>>\" }<([u8;32]), u128>\", \"allowances\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"\" }\" }<(AccountId, AccountId), u128>>\" }<(AccountId, AccountId), u128>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u128>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u128>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -54,15 +54,15 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)\", \"Removed\": \"Null\"} }<([u8;32]), u128>>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)\", \"Removed\": \"Null\"\" }\" }<([u8;32]), u128>>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -107,7 +107,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -136,7 +136,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -144,7 +144,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -205,7 +205,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -278,15 +278,15 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"} }<(AccountId, AccountId), u128>>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"\" }\" }<(AccountId, AccountId), u128>>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -331,7 +331,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -360,7 +360,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -368,7 +368,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -484,7 +484,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)"
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -615,11 +615,11 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u128>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u128>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -668,7 +668,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -740,15 +740,15 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)\", \"Removed\": \"Null\"} }<([u8;32]), u128>>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)\", \"Removed\": \"Null\"\" }\" }<([u8;32]), u128>>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -793,7 +793,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -822,7 +822,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -830,7 +830,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -891,7 +891,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -985,11 +985,11 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1038,7 +1038,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1073,7 +1073,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1102,7 +1102,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1110,7 +1110,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1171,7 +1171,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -1213,7 +1213,7 @@
|
||||
},
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1221,7 +1221,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1282,7 +1282,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\"} }<([u8;32]), u128>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"u128\" }<([u8;32]), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -1322,7 +1322,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1383,15 +1383,15 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"} }<(AccountId, AccountId), u128>>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"\" }\" }<(AccountId, AccountId), u128>>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1436,7 +1436,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1465,7 +1465,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1473,7 +1473,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1589,7 +1589,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)"
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -1764,7 +1764,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1793,7 +1793,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1801,7 +1801,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1917,7 +1917,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)"
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -1986,7 +1986,7 @@
|
||||
},
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1994,7 +1994,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -2110,7 +2110,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }<(AccountId, AccountId), u128>)"
|
||||
"type": "({ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }<(AccountId, AccountId), u128>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -2177,7 +2177,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\"} }",
|
||||
"type": "{ \"key\": \"(AccountId, AccountId)\", \"val\": \"u128\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
[
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"value\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::key"
|
||||
}
|
||||
],
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "value",
|
||||
"namespace": "ink_core::storage::value",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "Incrementer",
|
||||
"namespace": "incrementer::normal"
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::key"
|
||||
}
|
||||
],
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "Value",
|
||||
"namespace": "ink_core::storage::value",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32"
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"name": "cell",
|
||||
"namespace": "ink_core::storage::key"
|
||||
}
|
||||
],
|
||||
"name": "SyncCell",
|
||||
"namespace": "ink_core::storage::cell::sync_cell",
|
||||
"params": [
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"info": 10,
|
||||
"type": "([u8;32])",
|
||||
"sub": [
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"name": "Key",
|
||||
"namespace": "ink_core::storage::key"
|
||||
},
|
||||
{
|
||||
"info": 12,
|
||||
"type": "[u8;32]",
|
||||
"ext": {
|
||||
"length": 32,
|
||||
"type": "u8"
|
||||
},
|
||||
"sub": {
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
@@ -1,19 +1,19 @@
|
||||
[
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"mutators\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)\", \"Removed\": \"Null\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>>\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>\", \"vec\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"cells\": \"{ \"cells_key\": \"([u8;32])\"} }<i32>\"} }<i32>\"} }",
|
||||
"type": "{ \"mutators\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)\", \"Removed\": \"Null\"\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>>\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>\", \"vec\": \"{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"cells\": \"{ \"cells_key\": \"([u8;32])\" }<i32>\" }<i32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)\", \"Removed\": \"Null\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)\", \"Removed\": \"Null\"\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -58,7 +58,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -87,7 +87,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -95,7 +95,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -120,7 +120,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -183,7 +183,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -223,7 +223,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -257,7 +257,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -324,7 +324,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -364,15 +364,15 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"cells\": \"{ \"cells_key\": \"([u8;32])\"} }<i32>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"cells\": \"{ \"cells_key\": \"([u8;32])\" }<i32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -417,7 +417,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -466,15 +466,15 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\"} }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)\", \"Removed\": \"Null\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"entries\": \"{ \"cells_key\": \"([u8;32])\" }<{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)\", \"Removed\": \"Null\"\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -519,7 +519,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -548,7 +548,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -556,7 +556,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -581,7 +581,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -644,7 +644,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -684,7 +684,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -718,7 +718,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -785,7 +785,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -862,7 +862,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -919,11 +919,11 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -968,7 +968,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1024,7 +1024,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1053,7 +1053,7 @@
|
||||
"params": [
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1061,7 +1061,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1086,7 +1086,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1149,7 +1149,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1189,7 +1189,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -1223,7 +1223,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1265,7 +1265,7 @@
|
||||
},
|
||||
{
|
||||
"info": 3,
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)\", \"Removed\": \"Null\"} }",
|
||||
"type": "{ \"_enum\": { \"Occupied\": \"({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)\", \"Removed\": \"Null\"\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1273,7 +1273,7 @@
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1298,7 +1298,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1361,7 +1361,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1401,7 +1401,7 @@
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }>)"
|
||||
"type": "({ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }<([u8;32]), { \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }>)"
|
||||
},
|
||||
{
|
||||
"info": 6,
|
||||
@@ -1435,7 +1435,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1475,7 +1475,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }\"} }",
|
||||
"type": "{ \"key\": \"AccountId\", \"val\": \"{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1500,7 +1500,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1563,7 +1563,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\"} }",
|
||||
"type": "{ \"begin\": \"Option<u32><u32>\", \"end\": \"Option<u32><u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 5,
|
||||
@@ -1603,15 +1603,15 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }<u32>\", \"cells\": \"{ \"cells_key\": \"([u8;32])\"} }<i32>\"} }",
|
||||
"type": "{ \"len\": \"{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }<u32>\", \"cells\": \"{ \"cells_key\": \"([u8;32])\" }<i32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\"} }<u32>\"} }",
|
||||
"type": "{ \"cell\": \"{ \"cell\": \"([u8;32])\" }<u32>\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cell\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cell\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1656,7 +1656,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
@@ -1705,7 +1705,7 @@
|
||||
},
|
||||
{
|
||||
"info": 9,
|
||||
"type": "{ \"cells_key\": \"([u8;32])\"} }",
|
||||
"type": "{ \"cells_key\": \"([u8;32])\" }",
|
||||
"sub": [
|
||||
{
|
||||
"info": 10,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"name":"Incrementer","deploy":{"args":[{"name":"init_value","type":"u32"}]},"messages":[{"name":"inc","selector":257544423,"mutates":true,"args":[{"name":"by","type":"u32"}],"return_type":null},{"name":"get","selector":4266279973,"mutates":false,"args":[],"return_type":"u32"},{"name":"compare","selector":363906316,"mutates":false,"args":[{"name":"with","type":"u32"}],"return_type":"bool"}]}
|
||||
@@ -0,0 +1,233 @@
|
||||
{
|
||||
"registry": {
|
||||
"strings": [
|
||||
"Incrementer",
|
||||
"incrementer",
|
||||
"normal",
|
||||
"value",
|
||||
"Value",
|
||||
"ink_core",
|
||||
"storage",
|
||||
"cell",
|
||||
"SyncCell",
|
||||
"sync_cell",
|
||||
"Key",
|
||||
"key",
|
||||
"on_deploy",
|
||||
"init_value",
|
||||
"u32",
|
||||
"inc",
|
||||
"by",
|
||||
"get",
|
||||
"compare",
|
||||
"with",
|
||||
"bool"
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"id": {
|
||||
"custom.name": 1,
|
||||
"custom.namespace": [
|
||||
2,
|
||||
3
|
||||
],
|
||||
"custom.params": []
|
||||
},
|
||||
"def": {
|
||||
"struct.fields": [
|
||||
{
|
||||
"name": 4,
|
||||
"type": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": {
|
||||
"custom.name": 5,
|
||||
"custom.namespace": [
|
||||
6,
|
||||
7,
|
||||
4
|
||||
],
|
||||
"custom.params": [
|
||||
3
|
||||
]
|
||||
},
|
||||
"def": {
|
||||
"struct.fields": [
|
||||
{
|
||||
"name": 8,
|
||||
"type": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "u32",
|
||||
"def": "builtin"
|
||||
},
|
||||
{
|
||||
"id": {
|
||||
"custom.name": 9,
|
||||
"custom.namespace": [
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
10
|
||||
],
|
||||
"custom.params": [
|
||||
3
|
||||
]
|
||||
},
|
||||
"def": {
|
||||
"struct.fields": [
|
||||
{
|
||||
"name": 8,
|
||||
"type": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": {
|
||||
"custom.name": 11,
|
||||
"custom.namespace": [
|
||||
6,
|
||||
7,
|
||||
12
|
||||
],
|
||||
"custom.params": []
|
||||
},
|
||||
"def": {
|
||||
"tuple_struct.types": [
|
||||
6
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": {
|
||||
"array.len": 32,
|
||||
"array.type": 7
|
||||
},
|
||||
"def": "builtin"
|
||||
},
|
||||
{
|
||||
"id": "u8",
|
||||
"def": "builtin"
|
||||
},
|
||||
{
|
||||
"id": "bool",
|
||||
"def": "builtin"
|
||||
}
|
||||
]
|
||||
},
|
||||
"storage": {
|
||||
"struct.type": 1,
|
||||
"struct.fields": [
|
||||
{
|
||||
"name": 4,
|
||||
"layout": {
|
||||
"struct.type": 2,
|
||||
"struct.fields": [
|
||||
{
|
||||
"name": 8,
|
||||
"layout": {
|
||||
"range.offset": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"range.len": 1,
|
||||
"range.elem_type": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"contract": {
|
||||
"name": 1,
|
||||
"constructors": [
|
||||
{
|
||||
"name": 13,
|
||||
"selector": "[\"0x00\",\"0x00\",\"0x00\",\"0x00\"]",
|
||||
"args": [
|
||||
{
|
||||
"name": 14,
|
||||
"type": {
|
||||
"ty": 3,
|
||||
"display_name": [
|
||||
15
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": [
|
||||
"Initializes the value to the initial value."
|
||||
]
|
||||
}
|
||||
],
|
||||
"messages": [
|
||||
{
|
||||
"name": 16,
|
||||
"selector": "[\"0x0F\",\"0x59\",\"0xD0\",\"0xE7\"]",
|
||||
"mutates": true,
|
||||
"args": [
|
||||
{
|
||||
"name": 17,
|
||||
"type": {
|
||||
"ty": 3,
|
||||
"display_name": [
|
||||
15
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"return_type": null,
|
||||
"docs": [
|
||||
"Flips the current state of our smart contract."
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": 18,
|
||||
"selector": "[\"0xFE\",\"0x4A\",\"0x44\",\"0x25\"]",
|
||||
"mutates": false,
|
||||
"args": [],
|
||||
"return_type": {
|
||||
"ty": 3,
|
||||
"display_name": [
|
||||
15
|
||||
]
|
||||
},
|
||||
"docs": [
|
||||
"Returns the current state."
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": 19,
|
||||
"selector": "[\"0x15\",\"0xB0\",\"0xC5\",\"0x0C\"]",
|
||||
"mutates": false,
|
||||
"args": [
|
||||
{
|
||||
"name": 20,
|
||||
"type": {
|
||||
"ty": 3,
|
||||
"display_name": [
|
||||
15
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"return_type": {
|
||||
"ty": 8,
|
||||
"display_name": [
|
||||
21
|
||||
]
|
||||
},
|
||||
"docs": [
|
||||
"Returns `true` if the internal value is greater than or equal to the provided value."
|
||||
]
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"docs": []
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api-derive",
|
||||
"version": "0.95.2",
|
||||
"version": "0.96.1",
|
||||
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -27,11 +27,11 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@polkadot/api": "^0.95.2",
|
||||
"@polkadot/types": "^0.95.2"
|
||||
"@babel/runtime": "^7.7.1",
|
||||
"@polkadot/api": "^0.96.1",
|
||||
"@polkadot/types": "^0.96.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^1.6.1"
|
||||
"@polkadot/keyring": "^1.7.0-beta.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,17 +5,41 @@
|
||||
import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { isU8a } from '@polkadot/util';
|
||||
import { decodeAddress } from '@polkadot/util-crypto';
|
||||
import { createType } from '@polkadot/types';
|
||||
import { idToIndex } from './idToIndex';
|
||||
import { indexToId } from './indexToId';
|
||||
import { drr } from '../util/drr';
|
||||
|
||||
import { drr } from '../util';
|
||||
|
||||
export type AccountIdAndIndex = [AccountId?, AccountIndex?];
|
||||
|
||||
function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIndex | string | null | undefined): Observable<AccountIdAndIndex> {
|
||||
try {
|
||||
// yes, this can fail, don't care too much, catch will catch it
|
||||
const decoded = isU8a(address)
|
||||
? address
|
||||
: decodeAddress((address || '').toString());
|
||||
|
||||
if (decoded.length === 32) {
|
||||
const accountId = createType('AccountId', decoded);
|
||||
|
||||
return api.derive.accounts.idToIndex(accountId).pipe(
|
||||
map((accountIndex): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex)
|
||||
);
|
||||
}
|
||||
|
||||
const accountIndex = createType('AccountIndex', decoded);
|
||||
|
||||
return api.derive.accounts.indexToId(accountIndex).pipe(
|
||||
map((accountId): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex)
|
||||
);
|
||||
} catch (error) {
|
||||
return of([undefined, undefined] as AccountIdAndIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name idAndIndex
|
||||
* @param {(Address | AccountId | AccountIndex | string | null)} address - An accounts address in various formats.
|
||||
@@ -30,32 +54,6 @@ export type AccountIdAndIndex = [AccountId?, AccountIndex?];
|
||||
* ```
|
||||
*/
|
||||
export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable<AccountIdAndIndex> {
|
||||
return (address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> => {
|
||||
try {
|
||||
// yes, this can fail, don't care too much, catch will catch it
|
||||
const decoded = isU8a(address)
|
||||
? address
|
||||
: decodeAddress((address || '').toString());
|
||||
|
||||
if (decoded.length === 32) {
|
||||
const accountId = createType('AccountId', decoded);
|
||||
|
||||
return idToIndex(api)(accountId).pipe(
|
||||
startWith(undefined),
|
||||
map((accountIndex): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
const accountIndex = createType('AccountIndex', decoded);
|
||||
|
||||
return indexToId(api)(accountIndex).pipe(
|
||||
startWith(undefined),
|
||||
map((accountId): AccountIdAndIndex => [accountId, accountIndex] as AccountIdAndIndex),
|
||||
drr()
|
||||
);
|
||||
} catch (error) {
|
||||
return of([undefined, undefined] as AccountIdAndIndex).pipe(drr());
|
||||
}
|
||||
};
|
||||
return (address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> =>
|
||||
retrieve(api, address).pipe(drr());
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, AccountIndex } from '@polkadot/types/interfaces';
|
||||
import { AccountIndexes } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { indexes, AccountIndexes } from './indexes';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name idToIndex
|
||||
@@ -27,12 +27,11 @@ import { drr } from '../util/drr';
|
||||
*/
|
||||
export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable<AccountIndex | undefined> {
|
||||
return (accountId: AccountId | string): Observable<AccountIndex | undefined> =>
|
||||
indexes(api)()
|
||||
.pipe(
|
||||
startWith({}),
|
||||
map((indexes: AccountIndexes): AccountIndex | undefined =>
|
||||
(indexes || {})[accountId.toString()]
|
||||
),
|
||||
drr()
|
||||
);
|
||||
api.derive.accounts.indexes().pipe(
|
||||
startWith({}),
|
||||
map((indexes: AccountIndexes): AccountIndex | undefined =>
|
||||
(indexes || {})[accountId.toString()]
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,3 +6,4 @@ export * from './idAndIndex';
|
||||
export * from './idToIndex';
|
||||
export * from './indexToId';
|
||||
export * from './indexes';
|
||||
export * from './info';
|
||||
|
||||
@@ -10,7 +10,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
|
||||
import { createType, ClassOf, Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name indexToId
|
||||
@@ -26,19 +26,19 @@ import { drr } from '../util/drr';
|
||||
* ```
|
||||
*/
|
||||
export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable<AccountId | undefined> {
|
||||
const querySection = api.query.indices || api.query.balances;
|
||||
|
||||
return (_accountIndex: AccountIndex | string): Observable<AccountId | undefined> => {
|
||||
const querySection = api.query.indices || api.query.balances;
|
||||
const accountIndex = _accountIndex instanceof ClassOf('AccountIndex')
|
||||
? _accountIndex
|
||||
: createType('AccountIndex', _accountIndex);
|
||||
|
||||
return (querySection.enumSet<Vec<AccountId>>(accountIndex.div(ENUMSET_SIZE)))
|
||||
.pipe(
|
||||
startWith([]),
|
||||
map((accounts): AccountId | undefined =>
|
||||
(accounts || [])[accountIndex.mod(ENUMSET_SIZE).toNumber()]
|
||||
),
|
||||
drr()
|
||||
);
|
||||
return querySection.enumSet<Vec<AccountId>>(accountIndex.div(ENUMSET_SIZE)).pipe(
|
||||
startWith([]),
|
||||
map((accounts): AccountId | undefined =>
|
||||
(accounts || [])[accountIndex.mod(ENUMSET_SIZE).toNumber()]
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, AccountIndex } from '@polkadot/types/interfaces';
|
||||
import { AccountIndexes } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
|
||||
export type AccountIndexes = Record<string, AccountIndex>;
|
||||
import { drr } from '../util';
|
||||
|
||||
const enumsetSize = ENUMSET_SIZE.toNumber();
|
||||
|
||||
@@ -32,29 +31,27 @@ const enumsetSize = ENUMSET_SIZE.toNumber();
|
||||
* ```
|
||||
*/
|
||||
export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes> {
|
||||
return (): Observable<AccountIndexes> => {
|
||||
return (api.query.indices.nextEnumSet<AccountIndex>())
|
||||
.pipe(
|
||||
// use the nextEnumSet (which is a counter of the number of sets) to construct
|
||||
// a range of values to query [0, 1, 2, ...]. Retrieve the full enum set for the
|
||||
// specific index - each query can return up to ENUMSET_SIZE (64) records, each
|
||||
// containing an AccountId
|
||||
switchMap((next: AccountIndex): Observable<any> =>
|
||||
api.query.indices.enumSet.multi([...Array(next.toNumber() + 1).keys()]) as Observable<any>
|
||||
),
|
||||
map((all: (AccountId[] | undefined)[]): AccountIndexes =>
|
||||
(all || []).reduce((result, list, outerIndex): AccountIndexes => {
|
||||
(list || []).forEach((accountId, innerIndex): void => {
|
||||
// re-create the index based on position 0 is [0][0] and likewise
|
||||
// 64 (0..63 in first) is [1][0] (the first index value in set 2)
|
||||
const index = (outerIndex * enumsetSize) + innerIndex;
|
||||
return (): Observable<AccountIndexes> =>
|
||||
api.query.indices.nextEnumSet<AccountIndex>().pipe(
|
||||
// use the nextEnumSet (which is a counter of the number of sets) to construct
|
||||
// a range of values to query [0, 1, 2, ...]. Retrieve the full enum set for the
|
||||
// specific index - each query can return up to ENUMSET_SIZE (64) records, each
|
||||
// containing an AccountId
|
||||
switchMap((next: AccountIndex): Observable<any> =>
|
||||
api.query.indices.enumSet.multi([...Array(next.toNumber() + 1).keys()]) as Observable<any>
|
||||
),
|
||||
map((all: (AccountId[] | undefined)[]): AccountIndexes =>
|
||||
(all || []).reduce((result, list, outerIndex): AccountIndexes => {
|
||||
(list || []).forEach((accountId, innerIndex): void => {
|
||||
// re-create the index based on position 0 is [0][0] and likewise
|
||||
// 64 (0..63 in first) is [1][0] (the first index value in set 2)
|
||||
const index = (outerIndex * enumsetSize) + innerIndex;
|
||||
|
||||
result[accountId.toString()] = createType('AccountIndex', index);
|
||||
});
|
||||
result[accountId.toString()] = createType('AccountIndex', index);
|
||||
});
|
||||
|
||||
return result;
|
||||
}, {} as AccountIndexes)),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
return result;
|
||||
}, {} as AccountIndexes)),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, AccountIndex, Address, Balance } from '@polkadot/types/interfaces';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
import { DeriveAccountInfo } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Bytes, Option, u32 } from '@polkadot/types';
|
||||
import { u8aToString } from '@polkadot/util';
|
||||
|
||||
import { drr } from '../util';
|
||||
|
||||
function retrieveNick (api: ApiInterfaceRx, accountId?: AccountId): Observable<string | undefined> {
|
||||
return accountId && api.query.nicks
|
||||
? api.query.nicks
|
||||
.nameOf<Option<[Bytes, Balance] & Codec>>(accountId)
|
||||
.pipe(
|
||||
map((nameOf): string | undefined =>
|
||||
nameOf?.isSome
|
||||
? u8aToString(nameOf.unwrap()[0]).substr(0, (api.consts.nicks.maxLength as u32).toNumber())
|
||||
: undefined
|
||||
)
|
||||
)
|
||||
: of(undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name info
|
||||
* @description Returns aux. info with regards to an account, current that includes the accountId, accountIndex and nickname
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): (address?: AccountIndex | AccountId | Address | string | null) => Observable<DeriveAccountInfo> {
|
||||
return (address?: AccountIndex | AccountId | Address | string | null): Observable<DeriveAccountInfo> =>
|
||||
api.derive.accounts.idAndIndex(address).pipe(
|
||||
switchMap(([accountId, accountIndex]): Observable<[DeriveAccountInfo, string?]> =>
|
||||
combineLatest([
|
||||
of({ accountId, accountIndex }),
|
||||
retrieveNick(api, accountId)
|
||||
])
|
||||
),
|
||||
map(([{ accountId, accountIndex }, nickname]): DeriveAccountInfo => ({
|
||||
accountId, accountIndex, nickname
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, AccountIndex, Address, Balance, BalanceLock, BlockNumber, Index, VestingSchedule } from '@polkadot/types/interfaces';
|
||||
import { DerivedBalances } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { combineLatest, of, Observable } from 'rxjs';
|
||||
@@ -11,40 +12,30 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option, Vec, createType } from '@polkadot/types';
|
||||
import { bnMax } from '@polkadot/util';
|
||||
|
||||
import { idAndIndex } from '../accounts/idAndIndex';
|
||||
import { bestNumber } from '../chain/bestNumber';
|
||||
import { DerivedBalances } from '../types';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
type ResultBalance = [Balance, Balance, BalanceLock[], Option<VestingSchedule>];
|
||||
type Result = [AccountId, BlockNumber, ResultBalance, Index];
|
||||
|
||||
function calcBalances ([accountId, bestNumber, [freeBalance, reservedBalance, locks, vesting], accountNonce]: Result): DerivedBalances {
|
||||
let lockedBalance = createType('Balance');
|
||||
let lockedBreakdown: BalanceLock[] = [];
|
||||
|
||||
if (Array.isArray(locks)) {
|
||||
// only get the locks that are valid until passed the current block
|
||||
const totals = locks.filter((value): boolean => bestNumber && value.until.gt(bestNumber));
|
||||
lockedBreakdown = locks.filter(({ until }): boolean => bestNumber && until.gt(bestNumber));
|
||||
|
||||
// get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699
|
||||
lockedBalance = totals[0]
|
||||
? createType('Balance', bnMax(...totals.map(({ amount }): Balance => amount)))
|
||||
: createType('Balance');
|
||||
if (lockedBreakdown.length) {
|
||||
lockedBalance = createType('Balance', bnMax(...lockedBreakdown.map(({ amount }): Balance => amount)));
|
||||
}
|
||||
}
|
||||
|
||||
// offset = balance locked at genesis, perBlock is the unlock amount
|
||||
const { offset, perBlock } = vesting.unwrapOr(createType('VestingSchedule'));
|
||||
const { offset: vestingTotal, perBlock } = vesting.unwrapOr(createType('VestingSchedule'));
|
||||
const vestedNow = createType('Balance', perBlock.mul(bestNumber));
|
||||
const vestedBalance = vestedNow.gt(offset)
|
||||
? freeBalance
|
||||
: createType('Balance', freeBalance.sub(offset).add(vestedNow));
|
||||
|
||||
// NOTE Workaround for this account on Alex (one of a couple reported) -
|
||||
// 5F7BJL6Z4m8RLtK7nXEqqpEqhBbd535Z3CZeYF6ccvaQAY6N
|
||||
// The locked is > the vested and ended up with the locked > free,
|
||||
// i.e. related to https://github.com/paritytech/polkadot/issues/225
|
||||
// (most probably due to movements from stash -> controller -> free)
|
||||
const availableBalance = createType('Balance', bnMax(new BN(0), vestedBalance.sub(lockedBalance)));
|
||||
const vestedBalance = createType('Balance', vestedNow.gt(vestingTotal) ? new BN(0) : bnMax(new BN(0), freeBalance.sub(vestingTotal).add(vestedNow)));
|
||||
const availableBalance = createType('Balance', bnMax(new BN(0), (vestedBalance.gtn(0) ? vestedBalance : freeBalance).sub(lockedBalance)));
|
||||
|
||||
return {
|
||||
accountId,
|
||||
@@ -52,8 +43,10 @@ function calcBalances ([accountId, bestNumber, [freeBalance, reservedBalance, lo
|
||||
availableBalance,
|
||||
freeBalance,
|
||||
lockedBalance,
|
||||
lockedBreakdown,
|
||||
reservedBalance,
|
||||
vestedBalance,
|
||||
vestingTotal,
|
||||
votingBalance: createType('Balance', freeBalance.add(reservedBalance))
|
||||
};
|
||||
}
|
||||
@@ -83,13 +76,13 @@ function queryBalances (api: ApiInterfaceRx, accountId: AccountId): Observable<R
|
||||
* ```
|
||||
*/
|
||||
export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DerivedBalances> {
|
||||
return (address: AccountIndex | AccountId | Address | string): Observable<DerivedBalances> => {
|
||||
return idAndIndex(api)(address).pipe(
|
||||
switchMap(([accountId]): Observable<Result> =>
|
||||
return (address: AccountIndex | AccountId | Address | string): Observable<DerivedBalances> =>
|
||||
api.derive.accounts.info(address).pipe(
|
||||
switchMap(({ accountId }): Observable<Result> =>
|
||||
(accountId
|
||||
? combineLatest([
|
||||
of(accountId),
|
||||
bestNumber(api)(),
|
||||
api.derive.chain.bestNumber(),
|
||||
queryBalances(api, accountId),
|
||||
// FIXME This is having issues with Kusama, only use accountNonce atm
|
||||
// api.rpc.account && api.rpc.account.nextIndex
|
||||
@@ -104,5 +97,4 @@ export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId |
|
||||
map(calcBalances),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { DerivedFees } from '../types';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
type Result = [Balance, Balance, Balance, Balance, Balance];
|
||||
|
||||
@@ -52,12 +52,12 @@ function queryV1 (api: ApiInterfaceRx): Observable<Result> {
|
||||
* ```
|
||||
*/
|
||||
export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
|
||||
return (): Observable<DerivedFees> => {
|
||||
return (
|
||||
api.consts.balances
|
||||
? queryV2(api)
|
||||
: queryV1(api)
|
||||
).pipe(
|
||||
const query = api.consts.balances
|
||||
? queryV2
|
||||
: queryV1;
|
||||
|
||||
return (): Observable<DerivedFees> =>
|
||||
query(api).pipe(
|
||||
map(([creationFee, existentialDeposit, transferFee, transactionBaseFee, transactionByteFee]): DerivedFees => ({
|
||||
creationFee,
|
||||
existentialDeposit,
|
||||
@@ -67,5 +67,4 @@ export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,17 +8,18 @@ import { combineLatest, Observable, of } from 'rxjs';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { DerivedBalances } from '../types';
|
||||
import { drr } from '../util/drr';
|
||||
import { all } from './all';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable<DerivedBalances[]> {
|
||||
return (addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DerivedBalances[]> => {
|
||||
return (
|
||||
return (addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DerivedBalances[]> =>
|
||||
(
|
||||
!addresses || !addresses.length
|
||||
? of([] as DerivedBalances[])
|
||||
: combineLatest(addresses.map(all(api)))
|
||||
: combineLatest(
|
||||
addresses.map((accountId): Observable<DerivedBalances> =>
|
||||
api.derive.balances.all(accountId))
|
||||
)
|
||||
).pipe(
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,27 +3,26 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
|
||||
import { DerivedBalances } from '../types';
|
||||
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { idAndIndex } from '../accounts/idAndIndex';
|
||||
import { DerivedBalances } from '../types';
|
||||
import { drr } from '../util/drr';
|
||||
import { votingBalances } from './votingBalances';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function votingBalancesNominatorsFor (api: ApiInterfaceRx): (address: AccountId | AccountIndex | Address | string) => Observable<DerivedBalances[]> {
|
||||
return (address: AccountId | AccountIndex | Address | string): Observable<DerivedBalances[]> => {
|
||||
return idAndIndex(api)(address).pipe(
|
||||
switchMap(([accountId]): Observable<AccountId[]> =>
|
||||
return (address: AccountId | AccountIndex | Address | string): Observable<DerivedBalances[]> =>
|
||||
api.derive.accounts.info(address).pipe(
|
||||
switchMap(({ accountId }): Observable<AccountId[]> =>
|
||||
accountId
|
||||
? (api.query.staking.nominatorsFor<Vec<AccountId>>(accountId))
|
||||
? api.query.staking.nominatorsFor<Vec<AccountId>>(accountId)
|
||||
: of([] as AccountId[])
|
||||
),
|
||||
switchMap(votingBalances(api)),
|
||||
switchMap((accounts): Observable<DerivedBalances[]> =>
|
||||
api.derive.balances.votingBalances(accounts)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
import { BlockNumber, Header } from '@polkadot/types/interfaces';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name bestNumber
|
||||
@@ -24,8 +24,8 @@ import { drr } from '../util/drr';
|
||||
*/
|
||||
export function bestNumber (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
return (): Observable<BlockNumber> =>
|
||||
api.rpc.chain.subscribeNewHeads().pipe(
|
||||
map((header): BlockNumber => header.number.unwrap()),
|
||||
api.derive.chain.subscribeNewHeads().pipe(
|
||||
map((header: Header): BlockNumber => header.number.unwrap()),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name bestNumberFinalized
|
||||
|
||||
@@ -9,9 +9,7 @@ import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { bestNumber } from './bestNumber';
|
||||
import { bestNumberFinalized } from './bestNumberFinalized';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name bestNumberLag
|
||||
@@ -29,8 +27,8 @@ import { bestNumberFinalized } from './bestNumberFinalized';
|
||||
export function bestNumberLag (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
return (): Observable<BlockNumber> =>
|
||||
combineLatest([
|
||||
bestNumber(api)(),
|
||||
bestNumberFinalized(api)()
|
||||
api.derive.chain.bestNumber(),
|
||||
api.derive.chain.bestNumberFinalized()
|
||||
]).pipe(
|
||||
map(([bestNumber, bestNumberFinalized]): BlockNumber =>
|
||||
createType('BlockNumber', bestNumber.sub(bestNumberFinalized))
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { HeaderExtended } from '../type';
|
||||
import { drr } from '../util/drr';
|
||||
import { HeaderAndValidators } from './subscribeNewHeads';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name bestNumberFinalized
|
||||
@@ -26,12 +29,12 @@ import { HeaderAndValidators } from './subscribeNewHeads';
|
||||
*/
|
||||
export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<HeaderExtended | undefined> {
|
||||
return (hash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
|
||||
(combineLatest([
|
||||
combineLatest([
|
||||
api.rpc.chain.getHeader(hash),
|
||||
api.query.session
|
||||
? api.query.session.validators.at(hash)
|
||||
? api.query.session.validators.at(hash) as Observable<Vec<AccountId>>
|
||||
: of([])
|
||||
]) as Observable<HeaderAndValidators>).pipe(
|
||||
]).pipe(
|
||||
map(([header, validators]): HeaderExtended =>
|
||||
new HeaderExtended(header, validators)
|
||||
),
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, Header } from '@polkadot/types/interfaces';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { HeaderExtended } from '../type';
|
||||
import { drr } from '../util/drr';
|
||||
|
||||
export type HeaderAndValidators = [Header, AccountId[]];
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name subscribeNewHeads
|
||||
@@ -28,19 +25,11 @@ export type HeaderAndValidators = [Header, AccountId[]];
|
||||
*/
|
||||
export function subscribeNewHeads (api: ApiInterfaceRx): () => Observable<HeaderExtended> {
|
||||
return (): Observable<HeaderExtended> =>
|
||||
api.rpc.chain.subscribeNewHeads().pipe(
|
||||
switchMap((header: Header): Observable<HeaderAndValidators> =>
|
||||
(combineLatest([
|
||||
of(header),
|
||||
// theoretically we could combine at the first call with session.validators(), however
|
||||
// we make 100% sure we actually get the validators at a specific block so when these
|
||||
// change at an era boundary, we have the previous values to ensure our indexes are correct
|
||||
api.query.session
|
||||
? api.query.session.validators.at(header.hash)
|
||||
: of([])
|
||||
]) as Observable<HeaderAndValidators>)
|
||||
),
|
||||
map(([header, validators]): HeaderExtended =>
|
||||
combineLatest([
|
||||
api.rpc.chain.subscribeNewHeads(),
|
||||
api.derive.staking.validators()
|
||||
]).pipe(
|
||||
map(([header, { validators }]): HeaderExtended =>
|
||||
new HeaderExtended(header, validators)
|
||||
),
|
||||
drr()
|
||||
|
||||
@@ -9,7 +9,7 @@ import BN from 'bn.js';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
type ResultV2 = [BN, BN, BN, BN, BN, BN, BN, BN, BN, BN];
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Option } from '@polkadot/types';
|
||||
import { isNull } from '@polkadot/util';
|
||||
|
||||
import { ReferendumInfoExtended } from '../type';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function constructInfo (index: BN | number, optionInfo?: Option<ReferendumInfo>): Option<ReferendumInfoExtended> {
|
||||
const info = optionInfo
|
||||
@@ -28,13 +28,11 @@ export function constructInfo (index: BN | number, optionInfo?: Option<Referendu
|
||||
}
|
||||
|
||||
export function referendumInfo (api: ApiInterfaceRx): (index: BN | number) => Observable<Option<ReferendumInfoExtended>> {
|
||||
return (index: BN | number): Observable<Option<ReferendumInfoExtended>> => {
|
||||
return (api.query.democracy.referendumInfoOf<Option<ReferendumInfo>>(index))
|
||||
.pipe(
|
||||
map((optionInfo): Option<ReferendumInfoExtended> =>
|
||||
constructInfo(index, optionInfo)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
return (index: BN | number): Observable<Option<ReferendumInfoExtended>> =>
|
||||
api.query.democracy.referendumInfoOf<Option<ReferendumInfo>>(index).pipe(
|
||||
map((optionInfo): Option<ReferendumInfoExtended> =>
|
||||
constructInfo(index, optionInfo)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { ReferendumInfoExtended } from '../type';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
import { constructInfo } from './referendumInfo';
|
||||
|
||||
export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) => Observable<Option<ReferendumInfoExtended>[]> {
|
||||
return (ids: (BN | number)[] = []): Observable<Option<ReferendumInfoExtended>[]> => {
|
||||
return (
|
||||
return (ids: (BN | number)[] = []): Observable<Option<ReferendumInfoExtended>[]> =>
|
||||
(
|
||||
!ids || !ids.length
|
||||
? of([] as Option<ReferendumInfo>[])
|
||||
: api.query.democracy.referendumInfoOf.multi(ids) as Observable<Vec<Option<ReferendumInfo>>>
|
||||
@@ -28,5 +28,4 @@ export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) =
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,18 +11,16 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec, createType } from '@polkadot/types';
|
||||
|
||||
import { DerivedBalances, DerivedReferendumVote } from '../types';
|
||||
import { drr } from '../util/drr';
|
||||
import { votes } from './votes';
|
||||
import { votingBalances } from '../balances/votingBalances';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | number) => Observable<DerivedReferendumVote[]> {
|
||||
return (referendumId: BN | number): Observable<DerivedReferendumVote[]> =>
|
||||
(api.query.democracy.votersFor<Vec<AccountId>>(referendumId)).pipe(
|
||||
api.query.democracy.votersFor<Vec<AccountId>>(referendumId).pipe(
|
||||
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DerivedBalances[]]> =>
|
||||
combineLatest([
|
||||
of(votersFor),
|
||||
votes(api)(referendumId as BN, votersFor),
|
||||
votingBalances(api)(votersFor)
|
||||
api.derive.democracy.votes(referendumId as BN, votersFor),
|
||||
api.derive.balances.votingBalances(votersFor)
|
||||
])
|
||||
),
|
||||
map(([votersFor, votes, balances]): DerivedReferendumVote[] =>
|
||||
|
||||
@@ -11,18 +11,17 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { ReferendumInfoExtended } from '../type';
|
||||
import { drr } from '../util/drr';
|
||||
import { referendumInfos } from './referendumInfos';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function referendums (api: ApiInterfaceRx): () => Observable<Option<ReferendumInfoExtended>[]> {
|
||||
return (): Observable<Option<ReferendumInfoExtended>[]> =>
|
||||
(api.queryMulti([
|
||||
api.queryMulti<[ReferendumIndex, ReferendumIndex]>([
|
||||
api.query.democracy.nextTally,
|
||||
api.query.democracy.referendumCount
|
||||
]) as Observable<[ReferendumIndex?, ReferendumIndex?]>).pipe(
|
||||
]).pipe(
|
||||
switchMap(([nextTally, referendumCount]): Observable<Option<ReferendumInfoExtended>[]> =>
|
||||
referendumCount && nextTally && referendumCount.gt(nextTally) && referendumCount.gtn(0)
|
||||
? referendumInfos(api)(
|
||||
? api.derive.democracy.referendumInfos(
|
||||
[...Array(referendumCount.sub(nextTally).toNumber())].map((_, i): BN =>
|
||||
nextTally.addn(i)
|
||||
)
|
||||
|
||||
@@ -7,20 +7,18 @@ import { AccountId, Vote } from '@polkadot/types/interfaces';
|
||||
import BN from 'bn.js';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function votes (api: ApiInterfaceRx): (referendumId: BN, accountIds?: AccountId[]) => Observable<Vote[]> {
|
||||
return (referendumId: BN, accountIds: AccountId[] = []): Observable<Vote[]> => {
|
||||
return ((
|
||||
return (referendumId: BN, accountIds: AccountId[] = []): Observable<Vote[]> =>
|
||||
(
|
||||
!accountIds || !accountIds.length
|
||||
? of([])
|
||||
: api.query.democracy.voteOf.multi(
|
||||
? of([] as Vote[])
|
||||
: api.query.democracy.voteOf.multi<Vote>(
|
||||
accountIds.map((accountId): [BN, AccountId] =>
|
||||
[referendumId, accountId]
|
||||
)
|
||||
)
|
||||
) as Observable<Vec<Vote>>).pipe(drr());
|
||||
};
|
||||
).pipe(drr());
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Observable } from 'rxjs';
|
||||
import { Vec } from '@polkadot/types';
|
||||
import { switchMap, map } from 'rxjs/operators';
|
||||
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name approvalsOf
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name approvalsOfAt
|
||||
|
||||
@@ -2,30 +2,81 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, BlockNumber, SetIndex, VoteIndex } from '@polkadot/types/interfaces';
|
||||
import { AccountId, Balance, BlockNumber, SetIndex, VoteIndex } from '@polkadot/types/interfaces';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Vec, u32 } from '@polkadot/types';
|
||||
import { createType, Vec, u32 } from '@polkadot/types';
|
||||
|
||||
import { DerivedElectionsInfo } from '../types';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
type Result = [Vec<[AccountId, BlockNumber] & Codec>, Vec<AccountId>, u32, u32, SetIndex, BlockNumber, VoteIndex, SetIndex];
|
||||
type ResultElectionsInner = [u32, u32, Vec<[AccountId, BlockNumber] & Codec>, SetIndex, BlockNumber, VoteIndex, SetIndex];
|
||||
type ResultElections = [Vec<AccountId>, ResultElectionsInner];
|
||||
|
||||
function query (api: ApiInterfaceRx): Observable<Result> {
|
||||
return api.queryMulti<Result>([
|
||||
api.query.elections.members,
|
||||
api.query.elections.candidates,
|
||||
api.query.elections.candidateCount,
|
||||
api.query.elections.desiredSeats,
|
||||
api.query.elections.nextVoterSet,
|
||||
api.query.elections.termDuration,
|
||||
api.query.elections.voteCount,
|
||||
api.query.elections.voterCount
|
||||
]);
|
||||
function deriveElections ([candidates, [candidateCount, desiredSeats, members, nextVoterSet, termDuration, voteCount, voterCount]]: ResultElections): DerivedElectionsInfo {
|
||||
return {
|
||||
candidates,
|
||||
candidateCount,
|
||||
desiredSeats,
|
||||
nextVoterSet,
|
||||
members: members.map(([accountId]): [AccountId, Balance] => [accountId, createType('Balance')]),
|
||||
runnersUp: [],
|
||||
termDuration,
|
||||
voteCount,
|
||||
voterCount
|
||||
};
|
||||
}
|
||||
|
||||
function queryElections (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
|
||||
// NOTE We have an issue where candidates can return `null` for an empty array
|
||||
return combineLatest([
|
||||
api.query.elections.candidates<Vec<AccountId>>(),
|
||||
api.queryMulti<ResultElectionsInner>([
|
||||
api.query.elections.candidateCount,
|
||||
api.query.elections.desiredSeats,
|
||||
api.query.elections.members,
|
||||
api.query.elections.nextVoterSet,
|
||||
api.query.elections.termDuration,
|
||||
api.query.elections.voteCount,
|
||||
api.query.elections.voterCount
|
||||
])
|
||||
]).pipe(map(deriveElections));
|
||||
}
|
||||
|
||||
function derivePhragmen (candidates: AccountId[], members: [AccountId, Balance][], runnersUp: [AccountId, Balance][], candidacyBond: Balance, desiredSeats: u32, termDuration: BlockNumber, votingBond: Balance): DerivedElectionsInfo {
|
||||
return {
|
||||
candidates,
|
||||
candidateCount: createType('u32', candidates.length),
|
||||
candidacyBond,
|
||||
desiredSeats,
|
||||
members,
|
||||
runnersUp,
|
||||
termDuration,
|
||||
votingBond
|
||||
};
|
||||
}
|
||||
|
||||
function queryPhragmen (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
|
||||
// NOTE We have an issue where candidates can return `null` for an empty array, hence
|
||||
// we are not using multi queries here, so empty array is empty (instead of space-filled)
|
||||
return combineLatest([
|
||||
api.query.electionsPhragmen.candidates<Vec<AccountId>>(),
|
||||
api.query.electionsPhragmen.members<Vec<[AccountId, Balance] & Codec>>(),
|
||||
api.query.electionsPhragmen.runnersUp<Vec<[AccountId, Balance] & Codec>>()
|
||||
]).pipe(
|
||||
map(([candidates, members, runnersUp]): DerivedElectionsInfo => derivePhragmen(
|
||||
candidates,
|
||||
members,
|
||||
runnersUp,
|
||||
api.consts.electionsPhragmen.candidacyBond as Balance,
|
||||
api.consts.electionsPhragmen.desiredMembers as u32,
|
||||
api.consts.electionsPhragmen.termDuration as BlockNumber,
|
||||
api.consts.electionsPhragmen.votingBond as Balance
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,25 +93,10 @@ function query (api: ApiInterfaceRx): Observable<Result> {
|
||||
* ```
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): () => Observable<DerivedElectionsInfo> {
|
||||
return (): Observable<DerivedElectionsInfo> => {
|
||||
return query(api).pipe(
|
||||
map(([members, candidates, candidateCount, desiredSeats, nextVoterSet, termDuration, voteCount, voterCount]): DerivedElectionsInfo => ({
|
||||
members: members.reduce(
|
||||
(record: Record<string, BlockNumber>, [accountId, blockNumber]): Record<string, BlockNumber> => {
|
||||
record[accountId.toString()] = blockNumber;
|
||||
return record;
|
||||
},
|
||||
{}
|
||||
),
|
||||
candidates,
|
||||
candidateCount,
|
||||
desiredSeats,
|
||||
nextVoterSet,
|
||||
termDuration,
|
||||
voteCount,
|
||||
voterCount
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
const query = api.query.electionsPhragmen
|
||||
? queryPhragmen
|
||||
: queryElections;
|
||||
|
||||
return (): Observable<DerivedElectionsInfo> =>
|
||||
query(api).pipe(drr());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ import { DerivedVoterPositions } from '../types';
|
||||
import BN from 'bn.js';
|
||||
import { of, combineLatest, Observable } from 'rxjs';
|
||||
import { switchMap, map } from 'rxjs/operators';
|
||||
import { drr } from '../util/drr';
|
||||
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name voterPositions
|
||||
@@ -34,6 +35,7 @@ export function voterPositions (api: ApiInterfaceRx): () => Observable<DerivedVo
|
||||
)),
|
||||
map((result: [BN, Vec<Option<AccountId>>[]]): DerivedVoterPositions => {
|
||||
const [setSize, voters] = result;
|
||||
|
||||
return voters.reduce((result: DerivedVoterPositions, vec, setIndex): DerivedVoterPositions => {
|
||||
vec.forEach((e, index): void => {
|
||||
// re-create the index based on position 0 is [0][0] and likewise
|
||||
|
||||
@@ -10,8 +10,7 @@ import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { createType, Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { voterPositions } from './voterPositions';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @name voters
|
||||
@@ -27,15 +26,14 @@ import { voterPositions } from './voterPositions';
|
||||
*/
|
||||
export function voters (api: ApiInterfaceRx): () => Observable<Vec<AccountId>> {
|
||||
return (): Observable<Vec<AccountId>> =>
|
||||
voterPositions(api)().pipe(
|
||||
map(
|
||||
(voterPositions: DerivedVoterPositions): Vec<AccountId> =>
|
||||
createType(
|
||||
'Vec<AccountId>',
|
||||
Object.entries(voterPositions)
|
||||
.sort((a, b): 0 | 1 | -1 => a[1].globalIndex.cmp(b[1].globalIndex))
|
||||
.map(([accountId]): AccountId => createType('AccountId', accountId))
|
||||
)
|
||||
api.derive.elections.voterPositions().pipe(
|
||||
map((voterPositions: DerivedVoterPositions): Vec<AccountId> =>
|
||||
createType(
|
||||
'Vec<AccountId>',
|
||||
Object.entries(voterPositions)
|
||||
.sort((a, b): number => a[1].globalIndex.cmp(b[1].globalIndex))
|
||||
.map(([accountId]): AccountId => createType('AccountId', accountId))
|
||||
)
|
||||
),
|
||||
drr()
|
||||
);
|
||||
|
||||
@@ -3,36 +3,40 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DerivedHeartbeats } from '../types';
|
||||
|
||||
import { of, Observable } from 'rxjs';
|
||||
import { of, Observable, combineLatest } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Bytes, Vec } from '@polkadot/types';
|
||||
import { Bytes, Option, u32 } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @description Return a boolean array indicating whether the passed accounts had received heartbeats in the current session
|
||||
*/
|
||||
export function receivedHeartbeats (api: ApiInterfaceRx): (addresses: (AccountId | string)[]) => Observable<boolean[]> {
|
||||
return (addresses: (AccountId | string)[]): Observable<boolean[]> => {
|
||||
return api.query.imOnline && api.query.imOnline.receivedHeartbeats
|
||||
? api.queryMulti<[SessionIndex, Vec<AccountId>]>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.imOnline.keys
|
||||
]).pipe(
|
||||
switchMap(([currentIndex, keys]): Observable<Bytes[]> =>
|
||||
api.query.imOnline.receivedHeartbeats.multi(
|
||||
addresses.map((address): [SessionIndex, number] =>
|
||||
[currentIndex, keys.indexOf(address)]
|
||||
)
|
||||
)
|
||||
export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<DerivedHeartbeats> {
|
||||
return (): Observable<DerivedHeartbeats> =>
|
||||
api.query.imOnline?.receivedHeartbeats && api.query.imOnline.authoredBlocks
|
||||
? api.derive.staking.overview().pipe(
|
||||
switchMap(({ currentIndex, validators }): Observable<[AccountId[], Option<Bytes>[], u32[]]> =>
|
||||
combineLatest([
|
||||
of(validators),
|
||||
api.query.imOnline.receivedHeartbeats.multi<Option<Bytes>>(validators.map((_address, index): [SessionIndex, number] => [currentIndex, index])),
|
||||
api.query.imOnline.authoredBlocks.multi<u32>(validators.map((address): [SessionIndex, AccountId] => [currentIndex, address]))
|
||||
])
|
||||
),
|
||||
map((heartbeats): boolean[] =>
|
||||
heartbeats.map((heartbeat): boolean => !heartbeat.isEmpty)
|
||||
map(([validators, heartbeats, numBlocks]): DerivedHeartbeats =>
|
||||
validators.reduce((result: DerivedHeartbeats, validator, index): DerivedHeartbeats => ({
|
||||
...result,
|
||||
[validator.toString()]: {
|
||||
blockCount: numBlocks[index],
|
||||
hasMessage: !heartbeats[index].isEmpty,
|
||||
isOnline: !heartbeats[index].isEmpty || numBlocks[index].gtn(0)
|
||||
}
|
||||
}), {})
|
||||
),
|
||||
drr()
|
||||
)
|
||||
: of([...new Array(addresses.length).keys()].map((): boolean => false));
|
||||
};
|
||||
: of({});
|
||||
}
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { info } from './info';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function eraLength (api: ApiInterfaceRx): () => Observable<BN> {
|
||||
return (): Observable<BN> =>
|
||||
info(api)().pipe(
|
||||
map(({ eraLength }): BN => eraLength),
|
||||
export function eraLength (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
return (): Observable<BlockNumber> =>
|
||||
api.derive.session.info().pipe(
|
||||
map(({ eraLength }: DerivedSessionInfo): BlockNumber => eraLength),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { info } from './info';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function eraProgress (api: ApiInterfaceRx): () => Observable<BN> {
|
||||
return (): Observable<BN> =>
|
||||
info(api)().pipe(
|
||||
map(({ eraProgress }): BN => eraProgress),
|
||||
export function eraProgress (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
return (): Observable<BlockNumber> =>
|
||||
api.derive.session.info().pipe(
|
||||
map(({ eraProgress }: DerivedSessionInfo): BlockNumber => eraProgress),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
|
||||
export * from './eraLength';
|
||||
export * from './eraProgress';
|
||||
export * from './indexes';
|
||||
export * from './info';
|
||||
export * from './sessionProgress';
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { EraIndex, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DeriveSessionIndexes } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { u32 } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
|
||||
export function indexes (api: ApiInterfaceRx): () => Observable<DeriveSessionIndexes> {
|
||||
return (): Observable<DeriveSessionIndexes> =>
|
||||
api.queryMulti<[SessionIndex, EraIndex, u32]>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.currentEra,
|
||||
api.query.staking.validatorCount
|
||||
]).pipe(
|
||||
map(([currentIndex, currentEra, validatorCount]): DeriveSessionIndexes => ({
|
||||
currentIndex, currentEra, validatorCount
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
@@ -2,28 +2,26 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { BlockNumber, EraIndex, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo } from '../types';
|
||||
import { BlockNumber, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo, DeriveSessionIndexes } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option, u64, createType } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { bestNumber } from '../chain';
|
||||
import { drr } from '../util';
|
||||
|
||||
type Result94Session = [SessionIndex, Option<BlockNumber>, BlockNumber, BlockNumber, SessionIndex];
|
||||
type Result94 = [BlockNumber, Result94Session];
|
||||
type ResultV1Session = [Option<BlockNumber>, BlockNumber, BlockNumber, SessionIndex];
|
||||
type ResultV1 = [BlockNumber, DeriveSessionIndexes, ResultV1Session];
|
||||
|
||||
type ResultIndex = [SessionIndex, EraIndex];
|
||||
type ResultSlots = [u64, u64, u64];
|
||||
type ResultType = [boolean, boolean, u64, SessionIndex];
|
||||
type Result = [ResultType, ResultSlots, ResultIndex];
|
||||
type ResultSlots = [u64, u64, u64, SessionIndex];
|
||||
type ResultType = [boolean, u64, SessionIndex];
|
||||
type Result = [ResultType, DeriveSessionIndexes, ResultSlots];
|
||||
|
||||
// internal helper to just split the logic - take all inputs, do the calculations and combine
|
||||
function createDerived94 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result94): DerivedSessionInfo {
|
||||
const lastLengthChange = (_lastLengthChange && _lastLengthChange.unwrapOr(null)) || createType('BlockNumber');
|
||||
function createDerivedV1 ([bestNumber, { currentIndex, validatorCount }, [_lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: ResultV1): DerivedSessionInfo {
|
||||
const lastLengthChange = _lastLengthChange?.unwrapOr(null) || createType('BlockNumber');
|
||||
const sessionProgress = bestNumber
|
||||
.sub(lastLengthChange)
|
||||
.add(sessionLength)
|
||||
@@ -45,21 +43,17 @@ function createDerived94 ([bestNumber, [currentIndex, _lastLengthChange, session
|
||||
lastLengthChange,
|
||||
sessionLength,
|
||||
sessionsPerEra,
|
||||
sessionProgress: createType('BlockNumber', sessionProgress)
|
||||
sessionProgress: createType('BlockNumber', sessionProgress),
|
||||
validatorCount
|
||||
};
|
||||
}
|
||||
|
||||
function createDerivedLatest ([[hasBabe, isGenesisSlot, epochDuration, sessionsPerEra], [currentSlot, epochIndex, epochOrGenesisStartSlot], [currentIndex, currentEra]]: Result): DerivedSessionInfo {
|
||||
const epochStartSlot = isGenesisSlot
|
||||
? epochIndex
|
||||
.mul(epochDuration)
|
||||
.add(epochOrGenesisStartSlot)
|
||||
: epochOrGenesisStartSlot;
|
||||
function createDerivedLatest ([[hasBabe, epochDuration, sessionsPerEra], { currentIndex, currentEra, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, currentEraStartSessionIndex]]: Result): DerivedSessionInfo {
|
||||
const epochStartSlot = epochIndex.mul(epochDuration).add(epochOrGenesisStartSlot);
|
||||
const sessionProgress = currentSlot.sub(epochStartSlot);
|
||||
const eraProgress = epochIndex
|
||||
.mod(sessionsPerEra)
|
||||
.mul(epochDuration)
|
||||
.add(sessionProgress);
|
||||
const eraProgress = currentIndex.sub(currentEraStartSessionIndex).add(sessionProgress);
|
||||
|
||||
// console.log(sessionProgress);
|
||||
|
||||
return {
|
||||
currentEra,
|
||||
@@ -71,54 +65,55 @@ function createDerivedLatest ([[hasBabe, isGenesisSlot, epochDuration, sessionsP
|
||||
lastLengthChange: createType('BlockNumber', epochStartSlot),
|
||||
sessionLength: epochDuration,
|
||||
sessionsPerEra,
|
||||
sessionProgress: createType('BlockNumber', sessionProgress)
|
||||
sessionProgress: createType('BlockNumber', sessionProgress),
|
||||
validatorCount
|
||||
};
|
||||
}
|
||||
|
||||
function info94 (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
function infoV1 (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
return combineLatest([
|
||||
bestNumber(api)(),
|
||||
api.queryMulti<Result94Session>([
|
||||
api.query.session.currentIndex,
|
||||
api.derive.chain.bestNumber(),
|
||||
api.derive.session.indexes(),
|
||||
api.queryMulti<ResultV1Session>([
|
||||
api.query.session.lastLengthChange,
|
||||
api.query.session.sessionLength,
|
||||
api.query.staking.lastEraLengthChange,
|
||||
api.query.staking.sessionsPerEra
|
||||
])
|
||||
]).pipe(
|
||||
map(createDerived94),
|
||||
drr()
|
||||
map(createDerivedV1)
|
||||
);
|
||||
}
|
||||
|
||||
function infoLatest (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
const hasBabe = !!api.consts.babe;
|
||||
|
||||
return combineLatest([
|
||||
of([
|
||||
hasBabe,
|
||||
hasBabe && !!api.query.babe.genesisSlot,
|
||||
hasBabe
|
||||
? api.consts.babe.epochDuration as u64
|
||||
: createType('u64', 1),
|
||||
api.consts.staking.sessionsPerEra as SessionIndex
|
||||
] as ResultType),
|
||||
hasBabe
|
||||
? api.queryMulti<ResultSlots>([
|
||||
api.query.babe.currentSlot,
|
||||
api.query.babe.epochIndex,
|
||||
api.query.babe.genesisSlot
|
||||
? api.query.babe.genesisSlot
|
||||
: api.query.babe.epochStartSlot
|
||||
function infoLatestAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
return api.derive.session.indexes().pipe(
|
||||
map((indexes): DerivedSessionInfo =>
|
||||
createDerivedLatest([
|
||||
[false, createType('u64', 1), api.consts.staking.sessionsPerEra as SessionIndex],
|
||||
indexes,
|
||||
[createType('u64', 1), createType('u64', 1), createType('u64', 1), createType('SessionIndex', 1)]
|
||||
])
|
||||
: of([createType('u64', 1), createType('u64', 1), createType('u64', 1)] as ResultSlots),
|
||||
api.queryMulti<ResultIndex>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.staking.currentEra
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
return combineLatest([
|
||||
api.derive.session.indexes(),
|
||||
api.queryMulti<ResultSlots>([
|
||||
api.query.babe.currentSlot,
|
||||
api.query.babe.epochIndex,
|
||||
api.query.babe.genesisSlot,
|
||||
api.query.staking.currentEraStartSessionIndex
|
||||
])
|
||||
]).pipe(
|
||||
map(createDerivedLatest),
|
||||
drr()
|
||||
map(([indexes, slots]: [DeriveSessionIndexes, ResultSlots]): DerivedSessionInfo =>
|
||||
createDerivedLatest([
|
||||
[true, api.consts.babe.epochDuration as u64, api.consts.staking.sessionsPerEra as SessionIndex],
|
||||
indexes,
|
||||
slots
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -126,12 +121,12 @@ function infoLatest (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
|
||||
* @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo> {
|
||||
return (): Observable<DerivedSessionInfo> => {
|
||||
// With substrate `spec_version 94`, the era and session has been explicitly exposed as `parameter_types`.
|
||||
// pre-94 we had more info and needed to calculate (handle old/Alex first)
|
||||
// https://github.com/paritytech/substrate/commit/dbf322620948935d2bbae214504e6c668c3073ed#diff-c29f42d6b931fa93ba038dbbbfec3055
|
||||
return api.query.session.lastLengthChange
|
||||
? info94(api) // 1.x
|
||||
: infoLatest(api); // 2.x
|
||||
};
|
||||
const query = api.consts.staking
|
||||
? api.consts.babe
|
||||
? infoLatestBabe // 2.x with Babe
|
||||
: infoLatestAura // 2.x with Aura (not all info there)
|
||||
: infoV1;
|
||||
|
||||
return (): Observable<DerivedSessionInfo> =>
|
||||
query(api).pipe(drr());
|
||||
}
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
import { DerivedSessionInfo } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { info } from './info';
|
||||
import { drr } from '../util';
|
||||
|
||||
export function sessionProgress (api: ApiInterfaceRx): () => Observable<BN> {
|
||||
return (): Observable<BN> =>
|
||||
info(api)().pipe(
|
||||
map(({ sessionProgress }): BN => sessionProgress),
|
||||
export function sessionProgress (api: ApiInterfaceRx): () => Observable<BlockNumber> {
|
||||
return (): Observable<BlockNumber> =>
|
||||
api.derive.session.info().pipe(
|
||||
map(({ sessionProgress }: DerivedSessionInfo): BlockNumber => sessionProgress),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Option } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @description From the list of stash accounts, retrieve the list of controllers
|
||||
*/
|
||||
export function controllers (api: ApiInterfaceRx): () => Observable<[AccountId[], Option<AccountId>[]]> {
|
||||
return (): Observable<[AccountId[], Option<AccountId>[]]> =>
|
||||
api.query.staking
|
||||
.validators<[AccountId[]] & Codec>()
|
||||
.pipe(
|
||||
switchMap(([stashIds]): Observable<[AccountId[], Option<AccountId>[]]> =>
|
||||
combineLatest([
|
||||
of(stashIds),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
api.query.staking.bonded.multi(stashIds) as Observable<Option<AccountId>[]>
|
||||
])
|
||||
),
|
||||
drr()
|
||||
);
|
||||
api.query.staking.validators<[AccountId[]] & Codec>().pipe(
|
||||
switchMap(([stashIds]): Observable<[AccountId[], Option<AccountId>[]]> =>
|
||||
combineLatest([
|
||||
of(stashIds),
|
||||
// for V2, don't return all the controllers, we call bonded at a later point
|
||||
api.consts.session
|
||||
? of([])
|
||||
: api.query.staking.bonded.multi<Option<AccountId>>(stashIds)
|
||||
])
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,4 +4,6 @@
|
||||
|
||||
export * from './controllers';
|
||||
export * from './info';
|
||||
export * from './overview';
|
||||
export * from './recentlyOffline';
|
||||
export * from './validators';
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, Balance, BlockNumber } from '@polkadot/types/interfaces/runtime';
|
||||
import { Keys } from '@polkadot/types/interfaces/session';
|
||||
import { Exposure, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces/staking';
|
||||
import { AccountId, Balance, BlockNumber, Exposure, Keys, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DerivedStaking, DerivedUnlocking } from '../types';
|
||||
import { DerivedRecentlyOffline, DerivedStaking, DerivedUnlocking } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { combineLatest, Observable, of } from 'rxjs';
|
||||
@@ -17,14 +15,24 @@ import { createType, Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { isUndefined } from '@polkadot/util';
|
||||
|
||||
import { bestNumber } from '../chain/bestNumber';
|
||||
import { eraLength } from '../session/eraLength';
|
||||
import { recentlyOffline } from './recentlyOffline';
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
type MultiResult = [Option<Keys>, [
|
||||
Option<AccountId> | Vec<[AccountId, Keys] & Codec>, Option<StakingLedger>, [AccountId[]], RewardDestination, Exposure, [ValidatorPrefs]
|
||||
]];
|
||||
interface ParseInput {
|
||||
accountId: AccountId;
|
||||
bestNumber: BlockNumber;
|
||||
controllerId: AccountId;
|
||||
eraLength: BlockNumber;
|
||||
recentlyOffline?: DerivedRecentlyOffline;
|
||||
nominators: AccountId[];
|
||||
rewardDestination: RewardDestination;
|
||||
queuedKeys?: [AccountId, Keys][];
|
||||
stakers: Exposure;
|
||||
stakingLedger: Option<StakingLedger>;
|
||||
stashId: AccountId;
|
||||
validatorPrefs: ValidatorPrefs;
|
||||
nextKeys?: Option<Keys>;
|
||||
nextKeyFor?: Option<AccountId>;
|
||||
}
|
||||
|
||||
// groups the supplied chunks by era, i.e. { [era]: BN(total of values) }
|
||||
function groupByEra (list: UnlockChunk[]): Record<string, BN> {
|
||||
@@ -84,7 +92,7 @@ function redeemableSum (stakingLedger: StakingLedger | undefined, eraLength: BN,
|
||||
}, new BN(0)));
|
||||
}
|
||||
|
||||
function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | Vec<[AccountId, Keys] & Codec>, nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; nextSessionId?: AccountId; sessionIds: AccountId[]; sessionId?: AccountId } {
|
||||
function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | [AccountId, Keys][], nextKeys: Option<Keys>): { nextSessionIds: AccountId[]; sessionIds: AccountId[] } {
|
||||
// for 2.x we have a Vec<(ValidatorId,Keys)> of the keys
|
||||
if (Array.isArray(queuedKeys)) {
|
||||
const sessionIds = (queuedKeys.find(([currentId]): boolean =>
|
||||
@@ -93,9 +101,7 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | V
|
||||
const nextSessionIds = nextKeys.unwrapOr([] as AccountId[]);
|
||||
|
||||
return {
|
||||
nextSessionId: nextSessionIds[0],
|
||||
nextSessionIds,
|
||||
sessionId: sessionIds[0],
|
||||
sessionIds
|
||||
};
|
||||
}
|
||||
@@ -106,85 +112,112 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | V
|
||||
: [];
|
||||
|
||||
return {
|
||||
nextSessionId: nextSessionIds[0],
|
||||
nextSessionIds,
|
||||
sessionId: nextSessionIds[0],
|
||||
sessionIds: nextSessionIds
|
||||
};
|
||||
}
|
||||
|
||||
function retrieveMulti (api: ApiInterfaceRx, stashId: AccountId, controllerId: AccountId): Observable<MultiResult> {
|
||||
function parseResult ({ accountId, controllerId, stashId, eraLength, bestNumber, recentlyOffline = {}, nextKeyFor = createType('Option<AccountId>', null), queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys = createType('Option<Keys>', null) }: ParseInput): DerivedStaking {
|
||||
const _stakingLedger = stakingLedger.unwrapOr(undefined);
|
||||
|
||||
return {
|
||||
accountId,
|
||||
controllerId,
|
||||
nominators,
|
||||
offline: recentlyOffline[stashId.toString()],
|
||||
redeemable: redeemableSum(_stakingLedger, eraLength, bestNumber),
|
||||
rewardDestination,
|
||||
stakers,
|
||||
stakingLedger: _stakingLedger,
|
||||
stashId,
|
||||
unlocking: calculateUnlocking(_stakingLedger, eraLength, bestNumber),
|
||||
validatorPrefs,
|
||||
...unwrapSessionIds(stashId, queuedKeys || nextKeyFor, nextKeys)
|
||||
};
|
||||
}
|
||||
|
||||
type MultiResultV1 = [Option<AccountId>, Option<StakingLedger>, [Vec<AccountId>], RewardDestination, Exposure, [ValidatorPrefs] & Codec];
|
||||
|
||||
function retrieveInfoV1 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
|
||||
return combineLatest([
|
||||
// TODO We really want this as part of the multi, however can only do that
|
||||
// once we drop substrate 1.x support (nulti requires values for all)
|
||||
api.query.session.nextKeys
|
||||
? api.query.session.nextKeys<Option<Keys>>(api.consts.session.dedupKeyPrefix, stashId)
|
||||
: of(createType('Option<Keys>', null)),
|
||||
api.derive.chain.bestNumber(),
|
||||
api.derive.session.eraLength(),
|
||||
api.derive.staking.recentlyOffline(),
|
||||
api.queryMulti([
|
||||
api.query.session.queuedKeys
|
||||
? [api.query.session.queuedKeys]
|
||||
: [api.query.session.nextKeyFor, controllerId],
|
||||
[api.query.session.nextKeyFor, controllerId],
|
||||
[api.query.staking.ledger, controllerId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId]
|
||||
])
|
||||
]) as Observable<MultiResult>;
|
||||
]) as Observable<MultiResultV1>
|
||||
]).pipe(map(([
|
||||
bestNumber, eraLength, recentlyOffline,
|
||||
[nextKeyFor, stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]
|
||||
]: [BlockNumber, BlockNumber, DerivedRecentlyOffline, MultiResultV1]): DerivedStaking =>
|
||||
parseResult({
|
||||
accountId, controllerId, stashId, eraLength, bestNumber, recentlyOffline, nextKeyFor, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
function retrieveInfo (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
|
||||
return combineLatest([
|
||||
eraLength(api)(),
|
||||
bestNumber(api)(),
|
||||
recentlyOffline(api)(),
|
||||
retrieveMulti(api, stashId, controllerId)
|
||||
]).pipe(
|
||||
map(([eraLength, bestNumber, recentlyOffline, [nextKeys, [queuedKeys, _stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]]]): DerivedStaking => {
|
||||
const stakingLedger = _stakingLedger.unwrapOr(undefined);
|
||||
type MultiResultV2 = [Option<StakingLedger>, [Vec<AccountId>], RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>];
|
||||
|
||||
return {
|
||||
accountId,
|
||||
controllerId,
|
||||
nominators,
|
||||
offline: recentlyOffline[stashId.toString()],
|
||||
redeemable: redeemableSum(stakingLedger, eraLength, bestNumber),
|
||||
rewardDestination,
|
||||
stakers,
|
||||
stakingLedger,
|
||||
stashId,
|
||||
unlocking: calculateUnlocking(stakingLedger, eraLength, bestNumber),
|
||||
validatorPrefs,
|
||||
...unwrapSessionIds(stashId, queuedKeys, nextKeys)
|
||||
};
|
||||
function retrieveInfoV2 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
|
||||
return combineLatest([
|
||||
api.derive.chain.bestNumber(),
|
||||
api.derive.session.eraLength(),
|
||||
api.query.session.queuedKeys<Vec<[AccountId, Keys] & Codec>>(),
|
||||
api.queryMulti([
|
||||
[api.query.staking.ledger, controllerId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId],
|
||||
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
|
||||
]) as Observable<MultiResultV2>
|
||||
]).pipe(map(([
|
||||
bestNumber, eraLength, queuedKeys,
|
||||
[stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs], nextKeys]
|
||||
]: [BlockNumber, BlockNumber, [AccountId, Keys][], MultiResultV2]): DerivedStaking =>
|
||||
parseResult({
|
||||
accountId, controllerId, stashId, eraLength, bestNumber, queuedKeys, stakingLedger, nominators, rewardDestination, stakers, validatorPrefs, nextKeys
|
||||
})
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
function retrieveV1 (api: ApiInterfaceRx, controllerId: AccountId): Observable<DerivedStaking> {
|
||||
return api.query.staking
|
||||
.ledger<Option<StakingLedger>>(controllerId)
|
||||
.pipe(
|
||||
switchMap((stakingLedger): Observable<DerivedStaking> =>
|
||||
stakingLedger.isSome
|
||||
? retrieveInfoV1(api, controllerId, stakingLedger.unwrap().stash, controllerId)
|
||||
: of({ accountId: controllerId, nextSessionIds: [], sessionIds: [] })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function retrieveV2 (api: ApiInterfaceRx, stashId: AccountId): Observable<DerivedStaking> {
|
||||
return api.query.staking
|
||||
.bonded<Option<AccountId>>(stashId)
|
||||
.pipe(
|
||||
switchMap((controllerId): Observable<DerivedStaking> =>
|
||||
controllerId.isSome
|
||||
? retrieveInfoV2(api, stashId, stashId, controllerId.unwrap())
|
||||
: of({ accountId: stashId, nextSessionIds: [], sessionIds: [] })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description From a stash, retrieve the controllerId and fill in all the relevant staking details
|
||||
*/
|
||||
export function info (api: ApiInterfaceRx): (_accountId: Uint8Array | string) => Observable<DerivedStaking> {
|
||||
return (_accountId: Uint8Array | string): Observable<DerivedStaking> => {
|
||||
const accountId = createType('AccountId', _accountId);
|
||||
const query = api.consts.session
|
||||
? retrieveV2
|
||||
: retrieveV1;
|
||||
|
||||
return (
|
||||
// NOTE For 2.x-only support, only the first path is required, therefore we
|
||||
// can replace this with `.bonded<Option<AccountId>>(accountId)` - in 2.x
|
||||
// the session.validators return the stashes (as expected)
|
||||
api.queryMulti<[Option<AccountId>, Option<StakingLedger>]>([
|
||||
[api.query.staking.bonded, accountId], // try to map to controller
|
||||
[api.query.staking.ledger, accountId] // try to map to stash (1.x only)
|
||||
])
|
||||
).pipe(
|
||||
switchMap(([controllerId, stakingLedger]): Observable<DerivedStaking> =>
|
||||
controllerId.isSome
|
||||
? retrieveInfo(api, accountId, accountId, controllerId.unwrap())
|
||||
: stakingLedger.isSome
|
||||
? retrieveInfo(api, accountId, stakingLedger.unwrap().stash, accountId)
|
||||
: of({ accountId, nextSessionIds: [], sessionIds: [] })
|
||||
),
|
||||
drr()
|
||||
);
|
||||
};
|
||||
return (accountId: Uint8Array | string): Observable<DerivedStaking> =>
|
||||
query(api, createType('AccountId', accountId)).pipe(drr());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { AccountId, Exposure, Keys, RewardDestination, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { ITuple } from '@polkadot/types/types';
|
||||
import { DerivedStakingStash } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Option, Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
|
||||
// NOTE Unused ATM, preparing for V2-only
|
||||
|
||||
type Result = [Option<AccountId>, [Vec<AccountId>], RewardDestination, Exposure, ValidatorPrefs, Option<Keys>?];
|
||||
type ResultV1 = [Option<AccountId>, ITuple<[Vec<AccountId>]>, RewardDestination, Exposure, ValidatorPrefs];
|
||||
type ResultV2 = [Option<AccountId>, ITuple<[Vec<AccountId>]>, RewardDestination, Exposure, ValidatorPrefs, Option<Keys>];
|
||||
|
||||
function parse (stashId: AccountId, [_controllerId, [nominators], rewardDestination, stakers, validatorPrefs, _nextKeys]: Result): DerivedStakingStash {
|
||||
return {
|
||||
controllerId: _controllerId.unwrapOr(undefined),
|
||||
nextKeys: _nextKeys?.unwrapOr(undefined),
|
||||
nominators,
|
||||
rewardDestination,
|
||||
stakers,
|
||||
stashId,
|
||||
validatorPrefs
|
||||
};
|
||||
}
|
||||
|
||||
function retrieveV1 (api: ApiInterfaceRx, stashId: AccountId): Observable<Result> {
|
||||
return api.queryMulti<ResultV1>([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId]
|
||||
]);
|
||||
}
|
||||
|
||||
function retrieveV2 (api: ApiInterfaceRx, stashId: AccountId): Observable<Result> {
|
||||
return api.queryMulti<ResultV2>([
|
||||
[api.query.staking.bonded, stashId],
|
||||
[api.query.staking.nominators, stashId],
|
||||
[api.query.staking.payee, stashId],
|
||||
[api.query.staking.stakers, stashId],
|
||||
[api.query.staking.validators, stashId],
|
||||
[api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]
|
||||
]);
|
||||
}
|
||||
|
||||
export function infoStash (api: ApiInterfaceRx): (stashId: AccountId) => Observable<DerivedStakingStash> {
|
||||
const query = api.consts.session
|
||||
? retrieveV2
|
||||
: retrieveV1;
|
||||
|
||||
return (stashId: AccountId): Observable<DerivedStakingStash> =>
|
||||
query(api, stashId).pipe(
|
||||
map((result): DerivedStakingStash => parse(stashId, result)),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { EraPoints } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DerivedStakingOverview } from '../types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { createType } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @description Retrieve the staking overview, including elected and points earned
|
||||
*/
|
||||
export function overview (api: ApiInterfaceRx): () => Observable<DerivedStakingOverview> {
|
||||
return (): Observable<DerivedStakingOverview> =>
|
||||
combineLatest([
|
||||
api.derive.session.indexes(),
|
||||
api.derive.staking.validators()
|
||||
]).pipe(
|
||||
switchMap(([{ currentEra, currentIndex, validatorCount }, { currentElected, validators }]) =>
|
||||
combineLatest([
|
||||
of({ currentElected, currentEra, currentIndex, validators, validatorCount }),
|
||||
// this will change on a per block basis, keep it innermost (and it needs eraIndex)
|
||||
api.query.staking.currentEraPointsEarned
|
||||
? api.query.staking.currentEraPointsEarned<EraPoints>(currentEra)
|
||||
: of(createType('EraPoints'))
|
||||
])
|
||||
),
|
||||
map(([{ currentElected, currentEra, currentIndex, validators, validatorCount }, eraPoints]): DerivedStakingOverview => ({
|
||||
currentElected, currentEra, currentIndex, eraPoints, validators, validatorCount
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import { map } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DerivedRecentlyOffline } from '../types';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
import { drr } from '../util';
|
||||
|
||||
type OfflineResult = [AccountId, BlockNumber, BN][] & Codec;
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DeriveStakingValidators } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Vec } from '@polkadot/types';
|
||||
|
||||
import { drr } from '../util';
|
||||
|
||||
/**
|
||||
* @description Retrieve latest list of validators
|
||||
*/
|
||||
export function validators (api: ApiInterfaceRx): () => Observable<DeriveStakingValidators> {
|
||||
return (): Observable<DeriveStakingValidators> =>
|
||||
api.queryMulti<[Vec<AccountId>, Vec<AccountId>]>([
|
||||
api.query.session.validators,
|
||||
api.query.staking.currentElected
|
||||
]).pipe(
|
||||
map(([validators, currentElected]): DeriveStakingValidators => ({
|
||||
currentElected, validators
|
||||
})),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ const _Header: Constructor<Header> = Struct.with(runtimeTypes.types.Header as an
|
||||
export default class HeaderExtended extends _Header {
|
||||
private _author?: AccountId;
|
||||
|
||||
public constructor (header?: Header, sessionValidators?: AccountId[]) {
|
||||
constructor (header?: Header, sessionValidators?: AccountId[]) {
|
||||
super(header);
|
||||
|
||||
this._author = this.extractAuthor(sessionValidators);
|
||||
|
||||
@@ -20,7 +20,7 @@ const _ReferendumInfo: Constructor<ReferendumInfo> = Struct.with(democracyTypes.
|
||||
export default class ReferendumInfoExtended extends _ReferendumInfo {
|
||||
private _index: ReferendumIndex;
|
||||
|
||||
public constructor (value: ReferendumInfo | ReferendumInfoExtended, index?: BN | number) {
|
||||
constructor (value: ReferendumInfo | ReferendumInfoExtended, index?: BN | number) {
|
||||
super(value);
|
||||
|
||||
this._index = value instanceof ReferendumInfoExtended
|
||||
|
||||
@@ -2,20 +2,30 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, Balance, BlockNumber, EraIndex, Exposure, Index, RewardDestination, SessionIndex, SetIndex, StakingLedger, ValidatorPrefs, Vote, VoteIndex } from '@polkadot/types/interfaces';
|
||||
import { AccountId, AccountIndex, Balance, BalanceLock, BlockNumber, EraIndex, EraPoints, Exposure, Index, Keys, RewardDestination, SessionIndex, SetIndex, StakingLedger, ValidatorPrefs, Vote, VoteIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { u32 } from '@polkadot/types';
|
||||
|
||||
export type AccountIndexes = Record<string, AccountIndex>;
|
||||
|
||||
export interface DeriveAccountInfo {
|
||||
accountId?: AccountId;
|
||||
accountIndex?: AccountIndex;
|
||||
nickname?: string;
|
||||
}
|
||||
|
||||
export interface DerivedBalances {
|
||||
accountId: AccountId;
|
||||
accountNonce: Index;
|
||||
freeBalance: Balance;
|
||||
lockedBalance: Balance;
|
||||
lockedBreakdown: BalanceLock[];
|
||||
availableBalance: Balance;
|
||||
reservedBalance: Balance;
|
||||
votingBalance: Balance;
|
||||
vestedBalance: Balance;
|
||||
vestingTotal: Balance;
|
||||
}
|
||||
|
||||
export type DerivedBalancesMap = Record<string, DerivedBalances>;
|
||||
@@ -34,14 +44,17 @@ export interface DerivedContractFees {
|
||||
}
|
||||
|
||||
export interface DerivedElectionsInfo {
|
||||
members: Record<string, BlockNumber>;
|
||||
candidates: AccountId[];
|
||||
candidateCount: u32;
|
||||
candidacyBond?: Balance;
|
||||
desiredSeats: u32;
|
||||
nextVoterSet: SetIndex;
|
||||
members: [AccountId, Balance][];
|
||||
nextVoterSet?: SetIndex;
|
||||
runnersUp: [AccountId, Balance][];
|
||||
termDuration: BlockNumber;
|
||||
voteCount: VoteIndex;
|
||||
voterCount: SetIndex;
|
||||
voteCount?: VoteIndex;
|
||||
voterCount?: SetIndex;
|
||||
votingBond?: Balance;
|
||||
}
|
||||
|
||||
export interface DerivedFees {
|
||||
@@ -52,6 +65,14 @@ export interface DerivedFees {
|
||||
transferFee: Balance;
|
||||
}
|
||||
|
||||
export interface DerivedHeartbeatAuthor {
|
||||
blockCount: u32;
|
||||
hasMessage: boolean;
|
||||
isOnline: boolean;
|
||||
}
|
||||
|
||||
export type DerivedHeartbeats = Record<string, DerivedHeartbeatAuthor>;
|
||||
|
||||
export interface RecentlyOffline {
|
||||
blockNumber: BlockNumber;
|
||||
count: BN;
|
||||
@@ -65,9 +86,13 @@ export interface DerivedReferendumVote {
|
||||
vote: Vote;
|
||||
}
|
||||
|
||||
export interface DerivedSessionInfo {
|
||||
export interface DeriveSessionIndexes {
|
||||
currentEra: EraIndex;
|
||||
currentIndex: SessionIndex;
|
||||
validatorCount: u32;
|
||||
}
|
||||
|
||||
export interface DerivedSessionInfo extends DeriveSessionIndexes {
|
||||
eraLength: BlockNumber;
|
||||
eraProgress: BlockNumber;
|
||||
isEpoch: boolean;
|
||||
@@ -93,25 +118,36 @@ export interface DerivedStakingOnlineStatus {
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface DerivedStaking extends DerivedStakingOnlineStatus {
|
||||
accountId: AccountId;
|
||||
export interface DeriveStakingValidators {
|
||||
currentElected: AccountId[];
|
||||
validators: AccountId[];
|
||||
}
|
||||
|
||||
export interface DerivedStakingStash {
|
||||
controllerId?: AccountId;
|
||||
// @deprecated Use nextSessionIds instead
|
||||
nextSessionId?: AccountId;
|
||||
nextSessionIds: AccountId[];
|
||||
nominators?: AccountId[];
|
||||
redeemable?: Balance;
|
||||
rewardDestination?: RewardDestination;
|
||||
// @deprecated Use sessionIds instead
|
||||
sessionId?: AccountId;
|
||||
sessionIds: AccountId[];
|
||||
nextKeys?: Keys;
|
||||
stakers?: Exposure;
|
||||
stakingLedger?: StakingLedger;
|
||||
stashId?: AccountId;
|
||||
unlocking?: DerivedUnlocking[];
|
||||
validatorPrefs?: ValidatorPrefs;
|
||||
}
|
||||
|
||||
export interface DerivedStaking extends DerivedStakingOnlineStatus, DerivedStakingStash {
|
||||
accountId: AccountId;
|
||||
nextSessionIds: AccountId[];
|
||||
redeemable?: Balance;
|
||||
sessionIds: AccountId[];
|
||||
stakingLedger?: StakingLedger;
|
||||
unlocking?: DerivedUnlocking[];
|
||||
}
|
||||
|
||||
export interface DerivedStakingOverview extends DeriveSessionIndexes {
|
||||
currentElected: AccountId[];
|
||||
eraPoints: EraPoints;
|
||||
validators: AccountId[];
|
||||
}
|
||||
|
||||
export type DerivedUnlocking = { remainingBlocks: BlockNumber; value: Balance };
|
||||
|
||||
export interface VoterPosition {
|
||||
|
||||
@@ -2,29 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { catchError, distinctUntilChanged, publishReplay, refCount } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { logger } from '@polkadot/util';
|
||||
import { drr as drrBase, DrrResult } from '@polkadot/rpc-core/rxjs';
|
||||
|
||||
type DrrResult = <T> (source$: Observable<T>) => Observable<T>;
|
||||
|
||||
const l = logger('drr');
|
||||
|
||||
/**
|
||||
* Shorthand for distinctUntilChanged(), publishReplay(1) and refCount().
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
export const drr = (): DrrResult => <T> (source$: Observable<T>): Observable<T> =>
|
||||
source$.pipe(
|
||||
catchError((error): Observable<never> => {
|
||||
l.error(error);
|
||||
|
||||
throw error;
|
||||
}),
|
||||
distinctUntilChanged((a: any, b: any): boolean =>
|
||||
JSON.stringify({ value: a }) === JSON.stringify({ value: b })
|
||||
),
|
||||
publishReplay(1),
|
||||
refCount()
|
||||
);
|
||||
export const drr = (): DrrResult =>
|
||||
drrBase({ skipTimeout: true });
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export * from './approvalFlagsToBools';
|
||||
export * from './drr';
|
||||
export * from './memo';
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.v
|
||||
|
||||
import createMemo from 'memoizee';
|
||||
|
||||
export function memo <T extends Function> (fn: T, withoutJSON?: boolean): T {
|
||||
return withoutJSON
|
||||
? createMemo(fn)
|
||||
: createMemo(fn, {
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
normalizer: JSON.stringify
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api-metadata",
|
||||
"version": "0.95.2",
|
||||
"version": "0.96.1",
|
||||
"description": "Helpers to extract information from runtime metadata",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
@@ -26,12 +26,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/type-metadata#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@polkadot/types": "^0.95.2",
|
||||
"@polkadot/util": "^1.6.1",
|
||||
"@polkadot/util-crypto": "^1.6.1"
|
||||
"@babel/runtime": "^7.7.1",
|
||||
"@polkadot/types": "^0.96.1",
|
||||
"@polkadot/util": "^1.7.0-beta.5",
|
||||
"@polkadot/util-crypto": "^1.7.0-beta.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^1.6.1"
|
||||
"@polkadot/keyring": "^1.7.0-beta.5"
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/api",
|
||||
"version": "0.95.2",
|
||||
"version": "0.96.1",
|
||||
"description": "Promise and RxJS wrappers around the Polkadot JS RPC",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -26,16 +26,16 @@
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"@polkadot/api-derive": "^0.95.2",
|
||||
"@polkadot/api-metadata": "^0.95.2",
|
||||
"@polkadot/keyring": "^1.6.1",
|
||||
"@polkadot/rpc-core": "^0.95.2",
|
||||
"@polkadot/rpc-provider": "^0.95.2",
|
||||
"@polkadot/types": "^0.95.2",
|
||||
"@polkadot/util-crypto": "^1.6.1"
|
||||
"@babel/runtime": "^7.7.1",
|
||||
"@polkadot/api-derive": "^0.96.1",
|
||||
"@polkadot/api-metadata": "^0.96.1",
|
||||
"@polkadot/keyring": "^1.7.0-beta.5",
|
||||
"@polkadot/rpc-core": "^0.96.1",
|
||||
"@polkadot/rpc-provider": "^0.96.1",
|
||||
"@polkadot/types": "^0.96.1",
|
||||
"@polkadot/util-crypto": "^1.7.0-beta.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/keyring": "^1.6.1"
|
||||
"@polkadot/keyring": "^1.7.0-beta.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ interface MetaDecoration {
|
||||
toJSON: () => any;
|
||||
}
|
||||
|
||||
export default abstract class Decorate<ApiType> extends Events {
|
||||
export default abstract class Decorate<ApiType extends ApiTypes> extends Events {
|
||||
// HACK Use BN import so decorateDerive works... yes, wtf.
|
||||
protected __phantom = new BN(0);
|
||||
|
||||
@@ -111,7 +111,7 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
|
||||
constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super();
|
||||
|
||||
const thisProvider = options.source
|
||||
@@ -183,7 +183,7 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
});
|
||||
}
|
||||
|
||||
protected decorateRpc<ApiType> (rpc: RpcCore, decorateMethod: DecorateMethod<ApiType>): DecoratedRpc<ApiType, RpcInterface> {
|
||||
protected decorateRpc<ApiType extends ApiTypes> (rpc: RpcCore, decorateMethod: DecorateMethod<ApiType>): DecoratedRpc<ApiType, RpcInterface> {
|
||||
return rpc.sections.reduce((out, _sectionName): DecoratedRpc<ApiType, RpcInterface> => {
|
||||
const sectionName = _sectionName as keyof DecoratedRpc<ApiType, RpcInterface>;
|
||||
|
||||
@@ -201,7 +201,7 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
}, {} as unknown as DecoratedRpc<ApiType, RpcInterface>);
|
||||
}
|
||||
|
||||
protected decorateMulti<ApiType> (decorateMethod: DecorateMethod<ApiType>): QueryableStorageMulti<ApiType> {
|
||||
protected decorateMulti<ApiType extends ApiTypes> (decorateMethod: DecorateMethod<ApiType>): QueryableStorageMulti<ApiType> {
|
||||
return decorateMethod((calls: QueryableStorageMultiArg<ApiType>[]): Observable<Codec[]> =>
|
||||
this._rpcCore.state.subscribeStorage(
|
||||
calls.map((arg: QueryableStorageMultiArg<ApiType>): [QueryableStorageEntry<ApiType>, ...Arg[]] =>
|
||||
@@ -211,7 +211,7 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
: [arg.creator] as any)));
|
||||
}
|
||||
|
||||
protected decorateExtrinsics<ApiType> (extrinsics: ModulesWithCalls, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType> {
|
||||
protected decorateExtrinsics<ApiType extends ApiTypes> (extrinsics: ModulesWithCalls, decorateMethod: DecorateMethod<ApiType>): SubmittableExtrinsics<ApiType> {
|
||||
const creator = createSubmittable(this._type, this._rx as ApiInterfaceRx, decorateMethod);
|
||||
|
||||
return Object.entries(extrinsics).reduce((out, [name, section]): SubmittableExtrinsics<ApiType> => {
|
||||
@@ -225,14 +225,14 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
}, creator as unknown as SubmittableExtrinsics<ApiType>);
|
||||
}
|
||||
|
||||
private decorateExtrinsicEntry<ApiType> (method: CallFunction, creator: (value: Call | Uint8Array | string) => SubmittableExtrinsic<ApiType>): SubmittableExtrinsicFunction<ApiType> {
|
||||
private decorateExtrinsicEntry<ApiType extends ApiTypes> (method: CallFunction, creator: (value: Call | Uint8Array | string) => SubmittableExtrinsic<ApiType>): SubmittableExtrinsicFunction<ApiType> {
|
||||
const decorated = (...params: Arg[]): SubmittableExtrinsic<ApiType> =>
|
||||
creator(method(...params));
|
||||
|
||||
return this.decorateFunctionMeta(method, decorated as any) as SubmittableExtrinsicFunction<ApiType>;
|
||||
}
|
||||
|
||||
protected decorateStorage<ApiType> (storage: Storage, decorateMethod: DecorateMethod<ApiType>): QueryableStorage<ApiType> {
|
||||
protected decorateStorage<ApiType extends ApiTypes> (storage: Storage, decorateMethod: DecorateMethod<ApiType>): QueryableStorage<ApiType> {
|
||||
return Object.entries(storage).reduce((out, [name, section]): QueryableStorage<ApiType> => {
|
||||
out[name] = Object.entries(section).reduce((out, [name, method]): QueryableModuleStorage<ApiType> => {
|
||||
out[name] = this.decorateStorageEntry(method, decorateMethod);
|
||||
@@ -244,7 +244,7 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
}, {} as unknown as QueryableStorage<ApiType>);
|
||||
}
|
||||
|
||||
private decorateStorageEntry<ApiType> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): QueryableStorageEntry<ApiType> {
|
||||
private decorateStorageEntry<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): QueryableStorageEntry<ApiType> {
|
||||
// get the storage arguments, with DoubleMap as an array entry, otherwise spread
|
||||
const getArgs = (...args: any[]): any[] => creator.meta.type.isDoubleMap
|
||||
? [creator, args]
|
||||
@@ -288,7 +288,7 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
return this.decorateFunctionMeta(creator, decorated) as unknown as QueryableStorageEntry<ApiType>;
|
||||
}
|
||||
|
||||
private decorateStorageEntryLinked<ApiType> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): ReturnType<DecorateMethod<ApiType>> {
|
||||
private decorateStorageEntryLinked<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): ReturnType<DecorateMethod<ApiType>> {
|
||||
const result: Map<Codec, [Codec, Linkage<Codec>]> = new Map();
|
||||
let subject: BehaviorSubject<LinkageResult>;
|
||||
let head: Codec | null = null;
|
||||
@@ -356,11 +356,15 @@ export default abstract class Decorate<ApiType> extends Events {
|
||||
);
|
||||
}
|
||||
|
||||
protected decorateDerive (apiRx: ApiInterfaceRx, decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<ApiType, ExactDerive> {
|
||||
protected decorateDeriveRx (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<'rxjs', ExactDerive> {
|
||||
// Pull in derive from api-derive
|
||||
const derive = decorateDerive(apiRx, this._options.derives);
|
||||
const derive = decorateDerive(this._rx as ApiInterfaceRx, this._options.derives);
|
||||
|
||||
return decorateSections<ApiType, ExactDerive>(derive, decorateMethod);
|
||||
return decorateSections<'rxjs', ExactDerive>(derive, decorateMethod);
|
||||
}
|
||||
|
||||
protected decorateDerive (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<ApiType, ExactDerive> {
|
||||
return decorateSections<ApiType, ExactDerive>(this._rx.derive as DeriveAllSections<'rxjs', ExactDerive>, decorateMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { SignedBlock } from '@polkadot/types/interfaces';
|
||||
import { RegistryTypes } from '@polkadot/types/types';
|
||||
import { ApiBase, ApiInterfaceRx, ApiOptions, ApiTypes, DecorateMethod } from '../types';
|
||||
import { ApiBase, ApiOptions, ApiTypes, DecorateMethod } from '../types';
|
||||
|
||||
import constantsFromMeta from '@polkadot/api-metadata/consts/fromMetadata';
|
||||
import extrinsicsFromMeta from '@polkadot/api-metadata/extrinsics/fromMetadata';
|
||||
@@ -53,10 +53,10 @@ const TYPES_SPEC: Record<string, Record<string, string>> = {
|
||||
|
||||
const l = logger('api/decorator');
|
||||
|
||||
export default abstract class Init<ApiType> extends Decorate<ApiType> {
|
||||
export default abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {
|
||||
private _healthTimer: NodeJS.Timeout | null = null;
|
||||
|
||||
public constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
|
||||
constructor (options: ApiOptions, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super(options, type, decorateMethod);
|
||||
|
||||
if (!this.hasSubscriptions) {
|
||||
@@ -195,7 +195,8 @@ export default abstract class Init<ApiType> extends Decorate<ApiType> {
|
||||
this._rx.consts = constants;
|
||||
|
||||
// derive is last, since it uses the decorated rx
|
||||
this._derive = this.decorateDerive(this._rx as ApiInterfaceRx, this.decorateMethod);
|
||||
this._rx.derive = this.decorateDeriveRx(this.rxDecorateMethod);
|
||||
this._derive = this.decorateDerive(this.decorateMethod);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { RpcInterface } from '@polkadot/rpc-core/jsonrpc.types';
|
||||
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import { InterfaceRegistry } from '@polkadot/types/interfaceRegistry';
|
||||
import { CallFunction, InterfaceTypes, RegistryTypes, SignerPayloadRawBase } from '@polkadot/types/types';
|
||||
import { ApiOptions, ApiTypes, DecoratedRpc, DecorateMethod, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics, Signer } from '../types';
|
||||
import { ApiInterfaceRx, ApiOptions, ApiTypes, DecoratedRpc, DecorateMethod, QueryableStorage, QueryableStorageMulti, SubmittableExtrinsics, Signer } from '../types';
|
||||
|
||||
import { Constants } from '@polkadot/api-metadata/consts/types';
|
||||
import { GenericCall, Metadata, createType, getTypeRegistry } from '@polkadot/types';
|
||||
@@ -33,7 +33,7 @@ function assertResult<T> (value: T | undefined): T {
|
||||
return value as T;
|
||||
}
|
||||
|
||||
export default abstract class ApiBase<ApiType> extends Init<ApiType> {
|
||||
export default abstract class ApiBase<ApiType extends ApiTypes> extends Init<ApiType> {
|
||||
/**
|
||||
* @description Create an instance of the class
|
||||
*
|
||||
@@ -52,7 +52,7 @@ export default abstract class ApiBase<ApiType> extends Init<ApiType> {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public constructor (options: ApiOptions = {}, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
|
||||
constructor (options: ApiOptions = {}, type: ApiTypes, decorateMethod: DecorateMethod<ApiType>) {
|
||||
super(options, type, decorateMethod);
|
||||
}
|
||||
|
||||
@@ -192,6 +192,13 @@ export default abstract class ApiBase<ApiType> extends Init<ApiType> {
|
||||
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'
|
||||
*/
|
||||
|
||||
@@ -60,7 +60,7 @@ function promiseTracker (resolve: (value: () => void) => void, reject: (value: E
|
||||
/**
|
||||
* @description Decorate method for ApiPromise, where the results are converted to the Promise equivalent
|
||||
*/
|
||||
function decorateMethod<Method extends AnyFunction> (method: Method, options?: DecorateMethodOptions): StorageEntryPromiseOverloads {
|
||||
export function decorateMethod<Method extends AnyFunction> (method: Method, options?: DecorateMethodOptions): StorageEntryPromiseOverloads {
|
||||
const needsCallback = options && options.methodName && options.methodName.includes('subscribe');
|
||||
|
||||
return function (...args: any[]): Promise<ObsInnerType<ReturnType<Method>>> | UnsubscribePromise {
|
||||
@@ -213,7 +213,7 @@ export default class ApiPromise extends ApiBase<'promise'> {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public constructor (options?: ApiOptions) {
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'promise', decorateMethod);
|
||||
|
||||
this._isReadyPromise = new Promise((resolve): void => {
|
||||
|
||||
@@ -27,7 +27,7 @@ export default class Combinator {
|
||||
|
||||
protected _subscriptions: UnsubscribePromise[] = [];
|
||||
|
||||
public constructor (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback) {
|
||||
constructor (fns: (CombinatorFunction | [CombinatorFunction, ...any[]])[], callback: CombinatorCallback) {
|
||||
this._callback = callback;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import ApiPromise from './Api';
|
||||
import ApiPromise, { decorateMethod } from './Api';
|
||||
|
||||
export default ApiPromise;
|
||||
export { decorateMethod };
|
||||
|
||||
@@ -9,7 +9,7 @@ import { from, Observable } from 'rxjs';
|
||||
|
||||
import ApiBase from '../base';
|
||||
|
||||
function decorateMethod <Method extends AnyFunction> (method: Method): Method {
|
||||
export function decorateMethod <Method extends AnyFunction> (method: Method): Method {
|
||||
return method;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ export default class ApiRx extends ApiBase<'rxjs'> {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
public constructor (options?: ApiOptions) {
|
||||
constructor (options?: ApiOptions) {
|
||||
super(options, 'rxjs', decorateMethod);
|
||||
|
||||
this._isReadyRx = from(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import ApiRx from './Api';
|
||||
import ApiRx, { decorateMethod } from './Api';
|
||||
|
||||
export default ApiRx;
|
||||
export { decorateMethod };
|
||||
|
||||
@@ -10,7 +10,7 @@ export default class SubmittableResult implements SubmittableResultImpl {
|
||||
|
||||
public readonly status: ExtrinsicStatus;
|
||||
|
||||
public constructor ({ events, status }: SubmittableResultValue) {
|
||||
constructor ({ events, status }: SubmittableResultValue) {
|
||||
this.events = events || [];
|
||||
this.status = status;
|
||||
}
|
||||
@@ -27,6 +27,15 @@ export default class SubmittableResult implements SubmittableResultImpl {
|
||||
return this.status.isFinalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Filters EventRecords for the specified method & section (there could be multiple)
|
||||
*/
|
||||
public filterRecords (section: string, method: string): EventRecord[] {
|
||||
return this.events.filter(({ event }): boolean =>
|
||||
event.section === section && event.method === method
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Finds an EventRecord for the specified method & section
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { AccountId, Address, Call, Extrinsic, ExtrinsicEra, ExtrinsicStatus, Hash, Header, Index } from '@polkadot/types/interfaces';
|
||||
import { Callback, Codec, Constructor, IKeyringPair, SignatureOptions } from '@polkadot/types/types';
|
||||
import { ApiInterfaceRx, ApiTypes, SignerResult } from '../types';
|
||||
import { SignerOptions, SubmittableExtrinsic, SubmittableResultImpl, SubmitableResultResult, SubmitableResultSubscription } from './types';
|
||||
import { SignerOptions, SubmittableExtrinsic, SubmittableResultImpl, SubmittableResultResult, SubmittableResultSubscription } from './types';
|
||||
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { first, map, mergeMap, switchMap, tap } from 'rxjs/operators';
|
||||
@@ -17,7 +17,7 @@ import { filterEvents, isKeyringPair } from '../util';
|
||||
import ApiBase from '../base';
|
||||
import SubmittableResult from './Result';
|
||||
|
||||
interface SubmittableOptions<ApiType> {
|
||||
interface SubmittableOptions<ApiType extends ApiTypes> {
|
||||
api: ApiInterfaceRx;
|
||||
decorateMethod: ApiBase<ApiType>['decorateMethod'];
|
||||
type: ApiTypes;
|
||||
@@ -32,14 +32,14 @@ const DEFAULT_MORTAL_LENGTH = 5 * ONE_MINUTE;
|
||||
|
||||
const _Extrinsic: Constructor<Extrinsic> = ClassOf('Extrinsic');
|
||||
|
||||
export default class Submittable<ApiType> extends _Extrinsic implements SubmittableExtrinsic<ApiType> {
|
||||
export default class Submittable<ApiType extends ApiTypes> extends _Extrinsic implements SubmittableExtrinsic<ApiType> {
|
||||
private readonly _api: ApiInterfaceRx;
|
||||
|
||||
private readonly _decorateMethod: ApiBase<ApiType>['decorateMethod'];
|
||||
|
||||
private readonly _ignoreStatusCb: boolean;
|
||||
|
||||
public constructor (extrinsic: Call | Uint8Array | string, { api, decorateMethod, type }: SubmittableOptions<ApiType>) {
|
||||
constructor (extrinsic: Call | Uint8Array | string, { api, decorateMethod, type }: SubmittableOptions<ApiType>) {
|
||||
super(extrinsic, { version: api.extrinsicType });
|
||||
|
||||
this._api = api;
|
||||
@@ -61,16 +61,16 @@ export default class Submittable<ApiType> extends _Extrinsic implements Submitta
|
||||
}
|
||||
|
||||
// signAndSend with an immediate Hash result
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, options?: Partial<SignerOptions>): SubmitableResultResult<ApiType>;
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
||||
|
||||
// signAndSend with a subscription, i.e. callback provided
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, statusCb: Callback<SubmittableResultImpl>): SubmitableResultSubscription<ApiType>;
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// signAndSend with options and a callback
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmitableResultSubscription<ApiType>;
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// signAndSend implementation for all 3 cases above
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, optionsOrStatus?: Partial<SignerOptions> | Callback<SubmittableResultImpl>, optionalStatusCb?: Callback<SubmittableResultImpl>): SubmitableResultResult<ApiType> | SubmitableResultSubscription<ApiType> {
|
||||
public signAndSend (account: IKeyringPair | string | AccountId | Address, optionsOrStatus?: Partial<SignerOptions> | Callback<SubmittableResultImpl>, optionalStatusCb?: Callback<SubmittableResultImpl>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const [options, statusCb] = this._makeSignAndSendOptions(optionsOrStatus, optionalStatusCb);
|
||||
const isSubscription = this._api.hasSubscriptions && (this._ignoreStatusCb || !!statusCb);
|
||||
const address = isKeyringPair(account) ? account.address : account.toString();
|
||||
@@ -95,17 +95,17 @@ export default class Submittable<ApiType> extends _Extrinsic implements Submitta
|
||||
: this._sendObservable(updateId);
|
||||
})
|
||||
) as Observable<Codec>) // FIXME This is wrong, SubmittableResult is _not_ a codec
|
||||
)(statusCb) as SubmitableResultResult<ApiType> | SubmitableResultSubscription<ApiType>;
|
||||
)(statusCb) as SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType>;
|
||||
}
|
||||
|
||||
// send with an immediate Hash result
|
||||
public send (): SubmitableResultResult<ApiType>;
|
||||
public send (): SubmittableResultResult<ApiType>;
|
||||
|
||||
// send with a status callback
|
||||
public send (statusCb: Callback<SubmittableResultImpl>): SubmitableResultSubscription<ApiType>;
|
||||
public send (statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
// send implementation for both immediate Hash and statusCb variants
|
||||
public send (statusCb?: Callback<SubmittableResultImpl>): SubmitableResultResult<ApiType> | SubmitableResultSubscription<ApiType> {
|
||||
public send (statusCb?: Callback<SubmittableResultImpl>): SubmittableResultResult<ApiType> | SubmittableResultSubscription<ApiType> {
|
||||
const isSubscription = this._api.hasSubscriptions && (this._ignoreStatusCb || !!statusCb);
|
||||
|
||||
return this._decorateMethod(
|
||||
|
||||
@@ -9,11 +9,11 @@ import { SubmittableExtrinsic } from './types';
|
||||
|
||||
import ApiBase from '../base';
|
||||
|
||||
type Creator<ApiType> = (extrinsic: Call | Uint8Array | string) => SubmittableExtrinsic<ApiType>;
|
||||
type Creator<ApiType extends ApiTypes> = (extrinsic: Call | Uint8Array | string) => SubmittableExtrinsic<ApiType>;
|
||||
|
||||
let Submittable: Constructor<SubmittableExtrinsic<any>>;
|
||||
|
||||
export default function createSubmittable<ApiType> (type: ApiTypes, api: ApiInterfaceRx, decorateMethod: ApiBase<ApiType>['decorateMethod']): Creator<ApiType> {
|
||||
export default function createSubmittable<ApiType extends ApiTypes> (type: ApiTypes, api: ApiInterfaceRx, decorateMethod: ApiBase<ApiType>['decorateMethod']): Creator<ApiType> {
|
||||
return (extrinsic: Call | Uint8Array | string): SubmittableExtrinsic<ApiType> => {
|
||||
// HACK This is not great, but basically what we do here is to lazily only require the class
|
||||
// right at the point it is actually needed - delaying initialization
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import { AccountId, Address, ExtrinsicStatus, EventRecord, Hash } from '@polkadot/types/interfaces';
|
||||
import { AnyNumber, AnyU8a, Callback, IExtrinsic, IExtrinsicEra, IKeyringPair, SignatureOptions } from '@polkadot/types/types';
|
||||
import { ApiTypes } from '../types';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@@ -14,7 +15,8 @@ export interface SubmittableResultImpl {
|
||||
readonly isError: boolean;
|
||||
readonly isFinalized: boolean;
|
||||
|
||||
findRecord(section: string, method: string): EventRecord | undefined;
|
||||
filterRecords (section: string, method: string): EventRecord[];
|
||||
findRecord (section: string, method: string): EventRecord | undefined;
|
||||
}
|
||||
|
||||
export interface SubmittableResultValue {
|
||||
@@ -22,12 +24,12 @@ export interface SubmittableResultValue {
|
||||
status: ExtrinsicStatus;
|
||||
}
|
||||
|
||||
export type SubmitableResultResult<ApiType> =
|
||||
export type SubmittableResultResult<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? Observable<SubmittableResultImpl>
|
||||
: Promise<Hash>;
|
||||
|
||||
export type SubmitableResultSubscription<ApiType> =
|
||||
export type SubmittableResultSubscription<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? Observable<SubmittableResultImpl>
|
||||
: Promise<() => void>;
|
||||
@@ -39,16 +41,16 @@ export interface SignerOptions {
|
||||
tip?: AnyNumber;
|
||||
}
|
||||
|
||||
export interface SubmittableExtrinsic<ApiType> extends IExtrinsic {
|
||||
send(): SubmitableResultResult<ApiType>;
|
||||
export interface SubmittableExtrinsic<ApiType extends ApiTypes> extends IExtrinsic {
|
||||
send(): SubmittableResultResult<ApiType>;
|
||||
|
||||
send(statusCb: Callback<SubmittableResultImpl>): SubmitableResultSubscription<ApiType>;
|
||||
send(statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
sign(account: IKeyringPair, _options: Partial<SignatureOptions>): this;
|
||||
|
||||
signAndSend(account: IKeyringPair | string | AccountId | Address, options?: Partial<SignerOptions>): SubmitableResultResult<ApiType>;
|
||||
signAndSend(account: IKeyringPair | string | AccountId | Address, options?: Partial<SignerOptions>): SubmittableResultResult<ApiType>;
|
||||
|
||||
signAndSend(account: IKeyringPair | string | AccountId | Address, statusCb: Callback<SubmittableResultImpl>): SubmitableResultSubscription<ApiType>;
|
||||
signAndSend(account: IKeyringPair | string | AccountId | Address, statusCb: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
|
||||
signAndSend(account: IKeyringPair | string | AccountId | Address, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmitableResultSubscription<ApiType>;
|
||||
signAndSend(account: IKeyringPair | string | AccountId | Address, options: Partial<SignerOptions>, statusCb?: Callback<SubmittableResultImpl>): SubmittableResultSubscription<ApiType>;
|
||||
}
|
||||
|
||||
+23
-20
@@ -6,10 +6,11 @@ import { UserRpc } from '@polkadot/rpc-core/types';
|
||||
import { Hash, RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
import { AnyFunction, Callback, CallFunction, Codec, CodecArg, RegistryTypes, SignatureOptions, SignerPayloadJSON, SignerPayloadRaw } from '@polkadot/types/types';
|
||||
import { SubmittableResultImpl, SubmittableExtrinsic } from './submittable/types';
|
||||
import { DeriveAllSections } from './util/decorate';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DeriveCustom } from '@polkadot/api-derive';
|
||||
import { DeriveCustom, ExactDerive } from '@polkadot/api-derive';
|
||||
import { Constants } from '@polkadot/api-metadata/consts/types';
|
||||
import { RpcInterface } from '@polkadot/rpc-core/jsonrpc.types';
|
||||
import { ProviderInterface, ProviderInterfaceEmitted } from '@polkadot/rpc-provider/types';
|
||||
@@ -51,11 +52,11 @@ export interface DecorateMethodOptions {
|
||||
methodName?: string;
|
||||
}
|
||||
|
||||
export type DecorateMethod<ApiType> = <Method extends (...args: any[]) => Observable<any>>(method: Method, options?: DecorateMethodOptions) => any;
|
||||
export type DecorateMethod<ApiType extends ApiTypes> = <Method extends (...args: any[]) => Observable<any>>(method: Method, options?: DecorateMethodOptions) => any;
|
||||
|
||||
// Here are the return types of these parts of the api:
|
||||
// - api.query.*.*: no exact typings
|
||||
// - api.tx.*.*: SubmittableExtrinsic<ApiType>
|
||||
// - api.tx.*.*: SubmittableExtrinsic<ApiType extends ApiTypes>
|
||||
// - api.derive.*.*: MethodResult<ApiType, F>
|
||||
// - api.rpc.*.*: no exact typings (for now, FIXME: should be MethodResult<ApiType, F>, like in derive)
|
||||
|
||||
@@ -73,22 +74,22 @@ export interface PromiseResult<F extends AnyFunction> {
|
||||
}
|
||||
|
||||
// FIXME The day TS has higher-kinded types, we can remove this hardcoded stuff
|
||||
export type PromiseOrObs<ApiType, T> = ApiType extends 'rxjs'
|
||||
export type PromiseOrObs<ApiType extends ApiTypes, T> = ApiType extends 'rxjs'
|
||||
? Observable<T>
|
||||
: Promise<T>
|
||||
|
||||
// FIXME The day TS has higher-kinded types, we can remove this hardcoded stuff
|
||||
export type MethodResult<ApiType, F extends AnyFunction> = ApiType extends 'rxjs'
|
||||
export type MethodResult<ApiType extends ApiTypes, F extends AnyFunction> = ApiType extends 'rxjs'
|
||||
? RxResult<F>
|
||||
: PromiseResult<F>;
|
||||
|
||||
export type DecoratedRpcSection<ApiType, Section> = {
|
||||
export type DecoratedRpcSection<ApiType extends ApiTypes, Section> = {
|
||||
[Method in keyof Section]: Section[Method] extends AnyFunction
|
||||
? MethodResult<ApiType, Section[Method]>
|
||||
: never
|
||||
}
|
||||
|
||||
export type DecoratedRpc<ApiType, AllSections> = {
|
||||
export type DecoratedRpc<ApiType extends ApiTypes, AllSections> = {
|
||||
[Section in keyof AllSections]: DecoratedRpcSection<ApiType, AllSections[Section]>
|
||||
}
|
||||
|
||||
@@ -101,7 +102,7 @@ interface StorageEntryPromiseMulti {
|
||||
<T extends Codec>(args: (CodecArg[] | CodecArg)[], callback: Callback<T[]>): UnsubscribePromise;
|
||||
}
|
||||
|
||||
export interface StorageEntryBase<ApiType, F extends AnyFunction> {
|
||||
export interface StorageEntryBase<ApiType extends ApiTypes, F extends AnyFunction> {
|
||||
at: (hash: Hash | Uint8Array | string, ...args: Parameters<F>) => PromiseOrObs<ApiType, ObsInnerType<ReturnType<F>>>;
|
||||
creator: StorageEntry;
|
||||
hash: (...args: Parameters<F>) => PromiseOrObs<ApiType, Hash>;
|
||||
@@ -118,33 +119,33 @@ export interface StorageEntryPromiseOverloads {
|
||||
<T extends Codec>(arg1: CodecArg, arg2: CodecArg, callback: Callback<T>): UnsubscribePromise;
|
||||
}
|
||||
|
||||
export type StorageEntryExact<ApiType, F extends AnyFunction> = MethodResult<ApiType, F> & StorageEntryBase<ApiType, F>
|
||||
export type StorageEntryExact<ApiType extends ApiTypes, F extends AnyFunction> = MethodResult<ApiType, F> & StorageEntryBase<ApiType, F>
|
||||
|
||||
// This is the most generic typings we can have for a storage entry function
|
||||
type GenericStorageEntryFunction = (arg1?: CodecArg, arg2?: CodecArg) => Observable<Codec>
|
||||
|
||||
export type QueryableStorageEntry<ApiType> =
|
||||
export type QueryableStorageEntry<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? StorageEntryExact<'rxjs', GenericStorageEntryFunction>
|
||||
: StorageEntryExact<'promise', GenericStorageEntryFunction> & StorageEntryPromiseOverloads;
|
||||
|
||||
export interface QueryableModuleStorage<ApiType> {
|
||||
export interface QueryableModuleStorage<ApiType extends ApiTypes> {
|
||||
[index: string]: QueryableStorageEntry<ApiType>;
|
||||
}
|
||||
|
||||
export type QueryableStorageMultiArg<ApiType> =
|
||||
export type QueryableStorageMultiArg<ApiType extends ApiTypes> =
|
||||
QueryableStorageEntry<ApiType> |
|
||||
[QueryableStorageEntry<ApiType>, ...CodecArg[]];
|
||||
|
||||
export interface QueryableStorageMultiBase<ApiType> {
|
||||
export interface QueryableStorageMultiBase<ApiType extends ApiTypes> {
|
||||
<T extends Codec[]>(calls: QueryableStorageMultiArg<ApiType>[]): Observable<T>;
|
||||
}
|
||||
|
||||
export interface QueryableStorageMultiPromise<ApiType> {
|
||||
export interface QueryableStorageMultiPromise<ApiType extends ApiTypes> {
|
||||
<T extends Codec[]>(calls: QueryableStorageMultiArg<ApiType>[], callback: Callback<T>): UnsubscribePromise;
|
||||
}
|
||||
|
||||
export type QueryableStorageMulti<ApiType> =
|
||||
export type QueryableStorageMulti<ApiType extends ApiTypes> =
|
||||
ApiType extends 'rxjs'
|
||||
? QueryableStorageMultiBase<ApiType>
|
||||
: QueryableStorageMultiPromise<ApiType>;
|
||||
@@ -152,21 +153,21 @@ export type QueryableStorageMulti<ApiType> =
|
||||
// QueryableStorageExact will hold the exact typed api.query.*.* generated from
|
||||
// metadata. For now it's empty, it's ready to be module augmented.
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface QueryableStorageExact<ApiType> { }
|
||||
export interface QueryableStorageExact<ApiType extends ApiTypes> { }
|
||||
|
||||
export interface QueryableStorage<ApiType> extends QueryableStorageExact<ApiType> {
|
||||
export interface QueryableStorage<ApiType extends ApiTypes> extends QueryableStorageExact<ApiType> {
|
||||
[index: string]: QueryableModuleStorage<ApiType>;
|
||||
}
|
||||
|
||||
export interface SubmittableExtrinsicFunction<ApiType> extends CallFunction {
|
||||
export interface SubmittableExtrinsicFunction<ApiType extends ApiTypes> extends CallFunction {
|
||||
(...params: CodecArg[]): SubmittableExtrinsic<ApiType>;
|
||||
}
|
||||
|
||||
export interface SubmittableModuleExtrinsics<ApiType> {
|
||||
export interface SubmittableModuleExtrinsics<ApiType extends ApiTypes> {
|
||||
[index: string]: SubmittableExtrinsicFunction<ApiType>;
|
||||
}
|
||||
|
||||
export interface SubmittableExtrinsics<ApiType> {
|
||||
export interface SubmittableExtrinsics<ApiType extends ApiTypes> {
|
||||
(extrinsic: Uint8Array | string): SubmittableExtrinsic<ApiType>;
|
||||
[index: string]: SubmittableModuleExtrinsics<ApiType>;
|
||||
}
|
||||
@@ -216,6 +217,8 @@ export interface ApiOptions {
|
||||
// A smaller interface of ApiRx, used in derive and in SubmittableExtrinsic
|
||||
export interface ApiInterfaceRx {
|
||||
consts: Constants;
|
||||
// TODO This needs to be typed correctly
|
||||
derive: DeriveAllSections<'rxjs', ExactDerive>;
|
||||
extrinsicType: number;
|
||||
genesisHash: Hash;
|
||||
hasSubscriptions: boolean;
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AnyFunction } from '@polkadot/types/types';
|
||||
import { DecorateMethod, MethodResult } from '../types';
|
||||
import { ApiTypes, DecorateMethod, MethodResult } from '../types';
|
||||
|
||||
// Most generic typings for `api.derive.*.*`
|
||||
type AnyDerive = Record<string, Record<string, AnyFunction>>;
|
||||
// Exact typings for a particular section `api.derive.section.*`
|
||||
type DeriveSection<ApiType, Section extends Record<string, AnyFunction>> = { [MethodName in keyof Section]: MethodResult<ApiType, Section[MethodName]> };
|
||||
type DeriveSection<ApiType extends ApiTypes, Section extends Record<string, AnyFunction>> = { [MethodName in keyof Section]: MethodResult<ApiType, Section[MethodName]> };
|
||||
// Exact typings for all sections `api.derive.*.*`
|
||||
export type DeriveAllSections<ApiType, AllSections extends AnyDerive> = { [SectionName in keyof AllSections]: DeriveSection<ApiType, AllSections[SectionName]> };
|
||||
export type DeriveAllSections<ApiType extends ApiTypes, AllSections extends AnyDerive> = { [SectionName in keyof AllSections]: DeriveSection<ApiType, AllSections[SectionName]> };
|
||||
|
||||
// A technically unsafe version of Object.keys(obj) that assumes that
|
||||
// obj only has known properties of T
|
||||
@@ -21,7 +21,7 @@ function keys<T extends object> (obj: T): (keyof T)[] {
|
||||
/**
|
||||
* This is a methods decorator which keeps all type information.
|
||||
*/
|
||||
function decorateMethods<ApiType, Section extends Record<string, AnyFunction>> (
|
||||
function decorateMethods<ApiType extends ApiTypes, Section extends Record<string, AnyFunction>> (
|
||||
section: Section,
|
||||
decorateMethod: DecorateMethod<ApiType>
|
||||
): DeriveSection<ApiType, Section> {
|
||||
@@ -43,7 +43,7 @@ function decorateMethods<ApiType, Section extends Record<string, AnyFunction>> (
|
||||
/**
|
||||
* This is a section decorator which keeps all type information.
|
||||
*/
|
||||
export function decorateSections<ApiType, AllSections extends AnyDerive> (
|
||||
export function decorateSections<ApiType extends ApiTypes, AllSections extends AnyDerive> (
|
||||
allSections: AllSections,
|
||||
decorateMethod: DecorateMethod<ApiType>
|
||||
): DeriveAllSections<ApiType, AllSections> {
|
||||
|
||||
@@ -16,7 +16,7 @@ export class SingleAccountSigner implements Signer {
|
||||
|
||||
private signDelay: number;
|
||||
|
||||
public constructor (keyringPair: KeyringPair, signDelay = 0) {
|
||||
constructor (keyringPair: KeyringPair, signDelay = 0) {
|
||||
this.keyringPair = keyringPair;
|
||||
this.signDelay = signDelay;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user