Complexity cleanups (#1303)
* Complexity cleanups * Revert spread * Sig wrapping * Use InterfaceTypes in rpc definitions * Types for rpc definitions
This commit is contained in:
@@ -6,13 +6,77 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { DerivedContractFees } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { combineLatest, Observable, of } from 'rxjs';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { drr } from '../util/drr';
|
||||
|
||||
const ZERO = new BN(0);
|
||||
|
||||
// Only for 1.0 support. rentByteFee, rentDepositOffset, tombstoneDeposit are not available in substrate 1.0.
|
||||
// TODO remove this once 1.0 support is dropped
|
||||
function queryV1 (api: ApiInterfaceRx): Observable<DerivedContractFees> {
|
||||
return (
|
||||
api.queryMulti([
|
||||
api.query.contract.callBaseFee,
|
||||
api.query.contract.contractFee,
|
||||
api.query.contract.createBaseFee,
|
||||
api.query.contract.creationFee,
|
||||
api.query.contract.transactionBaseFee,
|
||||
api.query.contract.transactionByteFee,
|
||||
api.query.contract.transferFee
|
||||
]) as unknown as Observable<BN[]>
|
||||
).pipe(
|
||||
map(([callBaseFee, contractFee, createBaseFee, creationFee, transactionBaseFee, transactionByteFee, transferFee]): DerivedContractFees => ({
|
||||
callBaseFee,
|
||||
contractFee,
|
||||
createBaseFee,
|
||||
creationFee,
|
||||
rentByteFee: ZERO,
|
||||
rentDepositOffset: ZERO,
|
||||
tombstoneDeposit: ZERO,
|
||||
transactionBaseFee,
|
||||
transactionByteFee,
|
||||
transferFee
|
||||
} as unknown as DerivedContractFees)),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
// query via query (early v2, non-current, support to be dropped])
|
||||
function queryQuery (api: ApiInterfaceRx): Observable<BN[]> {
|
||||
const queryBase = api.query.contracts || api.query.contract;
|
||||
|
||||
return api.queryMulti([
|
||||
queryBase.callBaseFee,
|
||||
queryBase.contractFee,
|
||||
queryBase.createBaseFee,
|
||||
queryBase.creationFee,
|
||||
queryBase.rentByteFee,
|
||||
queryBase.rentDepositOffset,
|
||||
queryBase.tombstoneDeposit,
|
||||
queryBase.transactionBaseFee,
|
||||
queryBase.transactionByteFee,
|
||||
queryBase.transferFee
|
||||
]) as unknown as Observable<BN[]>;
|
||||
}
|
||||
|
||||
// query via constants (current applicable path)
|
||||
function queryConstants (api: ApiInterfaceRx): Observable<BN[]> {
|
||||
return of([
|
||||
api.consts.contracts.callBaseFee,
|
||||
api.consts.contracts.contractFee,
|
||||
api.consts.contracts.createBaseFee,
|
||||
api.consts.contracts.creationFee,
|
||||
api.consts.contracts.rentByteFee,
|
||||
api.consts.contracts.rentDepositOffset,
|
||||
api.consts.contracts.tombstoneDeposit,
|
||||
api.consts.contracts.transactionBaseFee,
|
||||
api.consts.contracts.transactionByteFee,
|
||||
api.consts.contracts.transferFee
|
||||
]) as unknown as Observable<BN[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name fees
|
||||
* @returns An object containing the combined results of the queries for
|
||||
@@ -28,71 +92,14 @@ const ZERO = new BN(0);
|
||||
*/
|
||||
export function fees (api: ApiInterfaceRx): () => Observable<DerivedContractFees> {
|
||||
return (): Observable<DerivedContractFees> => {
|
||||
const queryBase = api.query.contracts || api.query.contract;
|
||||
|
||||
if (api.query.contract && !api.query.contract.rentByteFee) {
|
||||
// Only for 1.0 support. rentByteFee, rentDepositOffset, tombstoneDeposit are not available in substrate 1.0.
|
||||
// @TODO remove this once 1.0 support is dropped
|
||||
return (combineLatest([
|
||||
of([ZERO, ZERO, ZERO]),
|
||||
api.queryMulti([
|
||||
queryBase.callBaseFee,
|
||||
queryBase.contractFee,
|
||||
queryBase.createBaseFee,
|
||||
queryBase.creationFee,
|
||||
queryBase.transactionBaseFee,
|
||||
queryBase.transactionByteFee,
|
||||
queryBase.transferFee
|
||||
])
|
||||
]) as unknown as Observable<BN[][]>).pipe(
|
||||
map(([
|
||||
[rentByteFee, rentDepositOffset, tombstoneDeposit],
|
||||
[callBaseFee, contractFee, createBaseFee, creationFee, transactionBaseFee, transactionByteFee, transferFee]
|
||||
]): DerivedContractFees => ({
|
||||
callBaseFee,
|
||||
contractFee,
|
||||
createBaseFee,
|
||||
creationFee,
|
||||
rentByteFee,
|
||||
rentDepositOffset,
|
||||
tombstoneDeposit,
|
||||
transactionBaseFee,
|
||||
transactionByteFee,
|
||||
transferFee
|
||||
} as unknown as DerivedContractFees)),
|
||||
drr()
|
||||
);
|
||||
return queryV1(api);
|
||||
}
|
||||
|
||||
return (
|
||||
api.consts.contracts
|
||||
// get values from api.const for substrate versions post spec_version: 101
|
||||
// https://github.com/paritytech/substrate/pull/2883/files#diff-5e5e1c3aec9ddfde0a9054d062ab3db9R131
|
||||
? of([
|
||||
api.consts.contracts.callBaseFee,
|
||||
api.consts.contracts.contractFee,
|
||||
api.consts.contracts.createBaseFee,
|
||||
api.consts.contracts.creationFee,
|
||||
api.consts.contracts.rentByteFee,
|
||||
api.consts.contracts.rentDepositOffset,
|
||||
api.consts.contracts.tombstoneDeposit,
|
||||
api.consts.contracts.transactionBaseFee,
|
||||
api.consts.contracts.transactionByteFee,
|
||||
api.consts.contracts.transferFee
|
||||
]) as unknown as Observable<BN[]>
|
||||
// Support versions pre spec_version 101 and get values from storage
|
||||
: api.queryMulti([
|
||||
queryBase.callBaseFee,
|
||||
queryBase.contractFee,
|
||||
queryBase.createBaseFee,
|
||||
queryBase.creationFee,
|
||||
queryBase.rentByteFee,
|
||||
queryBase.rentDepositOffset,
|
||||
queryBase.tombstoneDeposit,
|
||||
queryBase.transactionBaseFee,
|
||||
queryBase.transactionByteFee,
|
||||
queryBase.transferFee
|
||||
]) as unknown as Observable<BN[]>
|
||||
? queryConstants(api)
|
||||
: queryQuery(api)
|
||||
).pipe(
|
||||
map(
|
||||
([callBaseFee, contractFee, createBaseFee, creationFee, rentByteFee, rentDepositOffset, tombstoneDeposit, transactionBaseFee, transactionByteFee, transferFee]): DerivedContractFees => ({
|
||||
|
||||
@@ -12,7 +12,6 @@ import createParam from './create/param';
|
||||
const getHeader: RpcMethodOpt = {
|
||||
description: 'Retrieves the header for a specific block',
|
||||
params: [
|
||||
// @ts-ignore srml types
|
||||
createParam('hash', 'Hash', { isOptional: true })
|
||||
],
|
||||
type: 'Header'
|
||||
@@ -21,7 +20,6 @@ const getHeader: RpcMethodOpt = {
|
||||
const getBlock: RpcMethodOpt = {
|
||||
description: 'Get header and body of a relay chain block',
|
||||
params: [
|
||||
// @ts-ignore srml types
|
||||
createParam('hash', 'Hash', { isOptional: true })
|
||||
],
|
||||
type: 'SignedBlock'
|
||||
@@ -30,24 +28,20 @@ const getBlock: RpcMethodOpt = {
|
||||
const getBlockHash: RpcMethodOpt = {
|
||||
description: 'Get the block hash for a specific block',
|
||||
params: [
|
||||
// @ts-ignore This whould be fixed if we can get types from srml strings
|
||||
createParam('blockNumber', 'BlockNumber', { isOptional: true })
|
||||
],
|
||||
// @ts-ignore srml types
|
||||
type: 'Hash'
|
||||
};
|
||||
|
||||
const getFinalizedHead: RpcMethodOpt = {
|
||||
description: 'Get hash of the last finalized block in the canon chain',
|
||||
params: [],
|
||||
// @ts-ignore srml types
|
||||
type: 'Hash'
|
||||
};
|
||||
|
||||
const getRuntimeVersion: RpcMethodOpt = {
|
||||
description: 'Get the runtime version (alias of state_getRuntimeVersion)',
|
||||
params: [
|
||||
// @ts-ignore srml types
|
||||
createParam('hash', 'Hash', { isOptional: true })
|
||||
],
|
||||
type: 'RuntimeVersion'
|
||||
@@ -99,11 +93,9 @@ export default {
|
||||
methods: {
|
||||
getBlock: createMethod(section, 'getBlock', getBlock),
|
||||
getBlockHash: createMethod(section, 'getBlockHash', getBlockHash),
|
||||
// TODO US spelling
|
||||
getFinalizedHead: createMethod(section, 'getFinalizedHead', getFinalizedHead),
|
||||
getHeader: createMethod(section, 'getHeader', getHeader),
|
||||
getRuntimeVersion: createMethod(section, 'getRuntimeVersion', getRuntimeVersion),
|
||||
// TODO US spelling
|
||||
subscribeFinalizedHeads: createMethod(section, 'subscribeFinalizedHeads', subscribeFinalizedHeads),
|
||||
subscribeRuntimeVersion: createMethod(section, 'subscribeRuntimeVersion', subscribeRuntimeVersion),
|
||||
subscribeNewHead: createMethod(section, 'subscribeNewHead', subscribeNewHead)
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
// FIXME Can be one of the injected types (as type below)
|
||||
// import { CodecTypes } from '@polkadot/types/classes';
|
||||
import { InterfaceTypes } from '@polkadot/types/types';
|
||||
import { RpcParam } from '../types';
|
||||
|
||||
interface RpcParamOptions {
|
||||
isOptional?: boolean;
|
||||
}
|
||||
|
||||
export default function createParam (name: string, type: string, { isOptional = false }: RpcParamOptions = { isOptional: false }): RpcParam {
|
||||
export default function createParam (name: string, type: InterfaceTypes, { isOptional = false }: RpcParamOptions = { isOptional: false }): RpcParam {
|
||||
return {
|
||||
isOptional,
|
||||
name,
|
||||
|
||||
@@ -14,113 +14,82 @@ const call: RpcMethodOpt = {
|
||||
params: [
|
||||
createParam('method', 'Text'),
|
||||
createParam('data', 'Bytes'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
type: 'Bytes'
|
||||
};
|
||||
|
||||
const KEY_QUERY_PARAMS = [
|
||||
createParam('key', 'StorageKey'),
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
];
|
||||
|
||||
const getKeys: RpcMethodOpt = {
|
||||
description: 'Retrieves the keys with a certain prefix',
|
||||
params: [
|
||||
createParam('prefix', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
// @ts-ignore The Vec<> wrap is fine
|
||||
params: KEY_QUERY_PARAMS,
|
||||
type: 'Vec<StorageKey>'
|
||||
};
|
||||
|
||||
const getStorage: RpcMethodOpt = {
|
||||
description: 'Retrieves the storage for a key',
|
||||
params: [
|
||||
createParam('key', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
params: KEY_QUERY_PARAMS,
|
||||
type: 'StorageData'
|
||||
};
|
||||
|
||||
const getStorageHash: RpcMethodOpt = {
|
||||
description: 'Retrieves the storage hash',
|
||||
params: [
|
||||
createParam('key', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
// @ts-ignore srml types
|
||||
params: KEY_QUERY_PARAMS,
|
||||
type: 'Hash'
|
||||
};
|
||||
|
||||
const getStorageSize: RpcMethodOpt = {
|
||||
description: 'Retrieves the storage size',
|
||||
params: [
|
||||
createParam('key', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
params: KEY_QUERY_PARAMS,
|
||||
type: 'u64'
|
||||
};
|
||||
|
||||
const CHILD_QUERY_PARAMS = [
|
||||
createParam('childStorageKey', 'StorageKey'),
|
||||
createParam('key', 'StorageKey'),
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
];
|
||||
|
||||
const getChildKeys: RpcMethodOpt = {
|
||||
description: 'Retrieves the keys with prefix of a specific child storage',
|
||||
params: [
|
||||
createParam('childStorageKey', 'StorageKey'),
|
||||
createParam('prefix', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
// @ts-ignore The Vec<> wrap is fine
|
||||
params: CHILD_QUERY_PARAMS,
|
||||
type: 'Vec<StorageKey>'
|
||||
};
|
||||
|
||||
const getChildStorage: RpcMethodOpt = {
|
||||
description: 'Retrieves the child storage for a key',
|
||||
params: [
|
||||
createParam('childStorageKey', 'StorageKey'),
|
||||
createParam('key', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
params: CHILD_QUERY_PARAMS,
|
||||
type: 'StorageData'
|
||||
};
|
||||
|
||||
const getChildStorageHash: RpcMethodOpt = {
|
||||
description: 'Retrieves the child storage hash',
|
||||
params: [
|
||||
createParam('childStorageKey', 'StorageKey'),
|
||||
createParam('key', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
// @ts-ignore srml types
|
||||
params: CHILD_QUERY_PARAMS,
|
||||
type: 'Hash'
|
||||
};
|
||||
|
||||
const getChildStorageSize: RpcMethodOpt = {
|
||||
description: 'Retrieves the child storage size',
|
||||
params: [
|
||||
createParam('childStorageKey', 'StorageKey'),
|
||||
createParam('key', 'StorageKey'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
params: CHILD_QUERY_PARAMS,
|
||||
type: 'u64'
|
||||
};
|
||||
|
||||
const getMetadata: RpcMethodOpt = {
|
||||
description: 'Returns the runtime metadata',
|
||||
params: [
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
// @ts-ignore This is not part of InterfaceTypes
|
||||
type: 'Metadata'
|
||||
};
|
||||
|
||||
const getRuntimeVersion: RpcMethodOpt = {
|
||||
description: 'Get the runtime version',
|
||||
params: [
|
||||
// @ts-ignore srml types
|
||||
createParam('hash', 'Hash', { isOptional: true })
|
||||
],
|
||||
type: 'RuntimeVersion'
|
||||
@@ -129,21 +98,16 @@ const getRuntimeVersion: RpcMethodOpt = {
|
||||
const queryStorage: RpcMethodOpt = {
|
||||
description: 'Query historical storage entries (by key) starting from a start block',
|
||||
params: [
|
||||
// @ts-ignore The Vec<> wrap is fine
|
||||
createParam('keys', 'Vec<StorageKey>'),
|
||||
// @ts-ignore srml types
|
||||
createParam('startBlock', 'Hash'),
|
||||
// @ts-ignore srml types
|
||||
createParam('block', 'Hash', { isOptional: true })
|
||||
],
|
||||
// @ts-ignore The Vec<> wrap is fine
|
||||
type: 'Vec<StorageChangeSet>'
|
||||
};
|
||||
|
||||
const subscribeStorage: RpcMethodOpt = {
|
||||
description: 'Subscribes to storage changes for the provided keys',
|
||||
params: [
|
||||
// @ts-ignore The Vec<> wrap is fine
|
||||
createParam('keys', 'Vec<StorageKey>')
|
||||
],
|
||||
pubsub: [
|
||||
|
||||
@@ -41,7 +41,6 @@ const health: RpcMethodOpt = {
|
||||
const peers: RpcMethodOpt = {
|
||||
description: 'Returns the currently connected peers',
|
||||
params: [],
|
||||
// @ts-ignore the Vec<> wrap is fine
|
||||
type: 'Vec<PeerInfo>'
|
||||
};
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
// import { CodecTypes } from '@polkadot/types/classes';
|
||||
import { InterfaceTypes } from '@polkadot/types/types';
|
||||
|
||||
type PubSub = [string, string, string];
|
||||
|
||||
export interface RpcParam {
|
||||
isOptional: boolean;
|
||||
name: string;
|
||||
type: string; // CodecTypes;
|
||||
type: InterfaceTypes;
|
||||
}
|
||||
|
||||
export interface RpcMethodOpt {
|
||||
@@ -20,7 +20,7 @@ export interface RpcMethodOpt {
|
||||
isSubscription?: boolean;
|
||||
params: RpcParam[];
|
||||
pubsub?: PubSub;
|
||||
type: string; // CodecTypes;
|
||||
type: InterfaceTypes;
|
||||
}
|
||||
|
||||
export interface RpcMethod {
|
||||
@@ -34,7 +34,7 @@ export interface RpcMethod {
|
||||
params: RpcParam[];
|
||||
pubsub: PubSub;
|
||||
section: string;
|
||||
type: string; // CodecTypes;
|
||||
type: InterfaceTypes;
|
||||
}
|
||||
|
||||
export interface RpcSection {
|
||||
|
||||
@@ -244,6 +244,12 @@ describe('createType', (): void => {
|
||||
});
|
||||
});
|
||||
|
||||
it('allows creation of a Tuple', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('(Balance,u32)', [[1234, 5678]]).toJSON()
|
||||
).toEqual([1234, 5678]);
|
||||
});
|
||||
|
||||
it('allows creation of a Enum (simple)', (): void => {
|
||||
expect(
|
||||
createTypeUnsafe('{"_enum": ["A", "B", "C"]}', [1]).toJSON()
|
||||
|
||||
@@ -99,16 +99,65 @@ function _decodeSet (value: TypeDef, details: Record<string, number>): TypeDef {
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a struct, set or enum
|
||||
function _decodeStruct (type: string, value: TypeDef): TypeDef {
|
||||
const parsed = JSON.parse(type);
|
||||
const keys = Object.keys(parsed);
|
||||
|
||||
if (keys.length === 1 && keys[0] === '_enum') {
|
||||
return _decodeEnum(value, parsed[keys[0]]);
|
||||
} else if (keys.length === 1 && keys[0] === '_set') {
|
||||
return _decodeSet(value, parsed[keys[0]]);
|
||||
}
|
||||
|
||||
value.info = TypeDefInfo.Struct;
|
||||
value.sub = keys.map((name): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(parsed[name], name)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a fixed vector, e.g. [u8;32]
|
||||
function _decodeFixedVec (type: string, value: TypeDef): TypeDef {
|
||||
const [vecType, _vecLen] = type.substr(1, type.length - 2).split(';');
|
||||
const vecLen = parseInt(_vecLen.trim(), 10);
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(vecLen <= 256, `${type}: Only support for [Type; <length>], where length <= 256`);
|
||||
|
||||
value.info = TypeDefInfo.VecFixed;
|
||||
value.ext = { length: vecLen, type: vecType } as unknown as TypeDefExtVecFixed;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// decode a tuple
|
||||
function _decodeTuple (subType: string, value: TypeDef): TypeDef {
|
||||
value.info = TypeDefInfo.Tuple;
|
||||
value.sub = typeSplit(subType).map((inner): TypeDef =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
getTypeDef(inner)
|
||||
);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
const simpleExtraction: [string, string, TypeDefInfo][] = [
|
||||
['Compact<', '>', TypeDefInfo.Compact],
|
||||
['Option<', '>', TypeDefInfo.Option],
|
||||
['Vec<', '>', TypeDefInfo.Vec],
|
||||
['Linkage<', '>', TypeDefInfo.Linkage],
|
||||
['DoubleMap<', '>', TypeDefInfo.DoubleMap]
|
||||
];
|
||||
|
||||
export function getTypeDef (_type: string, name?: string): TypeDef {
|
||||
const type = _type.toString().trim();
|
||||
const value: TypeDef = {
|
||||
info: TypeDefInfo.Plain,
|
||||
name,
|
||||
type
|
||||
};
|
||||
const value: TypeDef = { info: TypeDefInfo.Plain, name, type };
|
||||
let subType = '';
|
||||
|
||||
const startingWith = (type: string, start: string, end: string): boolean => {
|
||||
const _hasWrapper = (type: string, start: string, end: string): boolean => {
|
||||
if (type.substr(0, start.length) !== start) {
|
||||
return false;
|
||||
}
|
||||
@@ -120,45 +169,18 @@ export function getTypeDef (_type: string, name?: string): TypeDef {
|
||||
return true;
|
||||
};
|
||||
|
||||
if (startingWith(type, '(', ')')) {
|
||||
value.info = TypeDefInfo.Tuple;
|
||||
value.sub = typeSplit(subType).map((inner): TypeDef => getTypeDef(inner));
|
||||
} else if (startingWith(type, '[', ']')) {
|
||||
// this handles e.g. [u8;32]
|
||||
const [vecType, _vecLen] = type.substr(1, type.length - 2).split(';');
|
||||
const vecLen = parseInt(_vecLen.trim(), 10);
|
||||
if (_hasWrapper(type, '[', ']')) {
|
||||
return _decodeFixedVec(type, value);
|
||||
} else if (_hasWrapper(type, '{', '}')) {
|
||||
return _decodeStruct(type, value);
|
||||
} else if (_hasWrapper(type, '(', ')')) {
|
||||
return _decodeTuple(subType, value);
|
||||
}
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(vecLen <= 256, `${type}: Only support for [Type; <length>], where length <= 256`);
|
||||
const extracted = simpleExtraction.find(([start, end]): boolean => _hasWrapper(type, start, end));
|
||||
|
||||
value.info = TypeDefInfo.VecFixed;
|
||||
value.ext = { length: vecLen, type: vecType } as unknown as TypeDefExtVecFixed;
|
||||
} else if (startingWith(type, '{', '}')) {
|
||||
const parsed = JSON.parse(type);
|
||||
const keys = Object.keys(parsed);
|
||||
|
||||
if (keys.length === 1 && keys[0] === '_enum') {
|
||||
_decodeEnum(value, parsed[keys[0]]);
|
||||
} else if (keys.length === 1 && keys[0] === '_set') {
|
||||
_decodeSet(value, parsed[keys[0]]);
|
||||
} else {
|
||||
value.info = TypeDefInfo.Struct;
|
||||
value.sub = keys.map((name): TypeDef => getTypeDef(parsed[name], name));
|
||||
}
|
||||
} else if (startingWith(type, 'Compact<', '>')) {
|
||||
value.info = TypeDefInfo.Compact;
|
||||
value.sub = getTypeDef(subType);
|
||||
} else if (startingWith(type, 'Option<', '>')) {
|
||||
value.info = TypeDefInfo.Option;
|
||||
value.sub = getTypeDef(subType);
|
||||
} else if (startingWith(type, 'Vec<', '>')) {
|
||||
value.info = TypeDefInfo.Vec;
|
||||
value.sub = getTypeDef(subType);
|
||||
} else if (startingWith(type, 'Linkage<', '>')) {
|
||||
value.info = TypeDefInfo.Linkage;
|
||||
value.sub = getTypeDef(subType);
|
||||
} else if (startingWith(type, 'DoubleMap<', '>')) {
|
||||
value.info = TypeDefInfo.DoubleMap;
|
||||
if (extracted) {
|
||||
value.info = extracted[2];
|
||||
value.sub = getTypeDef(subType);
|
||||
}
|
||||
|
||||
@@ -168,7 +190,6 @@ export function getTypeDef (_type: string, name?: string): TypeDef {
|
||||
export function createClass<T extends Codec = Codec, K extends string = string> (
|
||||
type: K
|
||||
): Constructor<FromReg<T, K>> {
|
||||
// return memoizedCreateClass(type);
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
return getTypeClass<FromReg<T, K>>(getTypeDef(type));
|
||||
}
|
||||
@@ -319,11 +340,7 @@ function initType<T extends Codec = Codec, K extends string = string> (Type: Con
|
||||
// An unsafe version of the `createType` below. It's unsafe because the `type`
|
||||
// argument here can be any string, which, if not parseable, will yield a
|
||||
// runtime error.
|
||||
export function createTypeUnsafe<T extends Codec = Codec, K extends string = string> (
|
||||
type: K,
|
||||
params: any[] = [],
|
||||
isPedantic?: boolean
|
||||
): FromReg<T, K> {
|
||||
export function createTypeUnsafe<T extends Codec = Codec, K extends string = string> (type: K, params: any[] = [], isPedantic?: boolean): FromReg<T, K> {
|
||||
try {
|
||||
return initType(createClass<T, K>(type), params, isPedantic);
|
||||
} catch (error) {
|
||||
@@ -332,17 +349,11 @@ export function createTypeUnsafe<T extends Codec = Codec, K extends string = str
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of a `type` with a given `value`.
|
||||
* Create an instance of a `type` with a given `params`.
|
||||
* @param type - A recognizable string representing the type to create an
|
||||
* instance from
|
||||
* @param value - The value to instantiate the type with
|
||||
* @param isPedantic - Double-check that the input's encoding matches the
|
||||
* output's one. Slower, but ensures that we have a 100% grasp on the actual
|
||||
* provided value
|
||||
* @param params - The value to instantiate the type with
|
||||
*/
|
||||
export default function createType<K extends InterfaceTypes> (
|
||||
type: K,
|
||||
...params: any[]
|
||||
): InterfaceRegistry[K] {
|
||||
export default function createType<K extends InterfaceTypes> (type: K, ...params: any[]): InterfaceRegistry[K] {
|
||||
return createTypeUnsafe<Codec, K>(type, params) as InterfaceRegistry[K];
|
||||
}
|
||||
|
||||
@@ -48,9 +48,7 @@ export default class Vote extends U8aFixed {
|
||||
} else if (value instanceof Boolean) {
|
||||
return Vote.decodeVote(value.valueOf());
|
||||
} else if (isNumber(value)) {
|
||||
return value < 0
|
||||
? new Uint8Array([AYE_BITS | DEF_CONV])
|
||||
: new Uint8Array([NAY_BITS]);
|
||||
return Vote.decodeVote(value < 0);
|
||||
} else if (isU8a(value)) {
|
||||
return value.length
|
||||
? value.subarray(0, 1)
|
||||
|
||||
Reference in New Issue
Block a user