Types bundle derive (#2932)

* added derives typesBundle overrides

* fix lint
This commit is contained in:
Alex D
2020-12-09 11:01:33 +01:00
committed by GitHub
parent a48eba101c
commit 6b4fd110a1
3 changed files with 249 additions and 2 deletions
+7 -2
View File
@@ -14,7 +14,7 @@ import BN from 'bn.js';
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
import { map, switchMap, take, tap, toArray } from 'rxjs/operators';
import { decorateDerive, ExactDerive } from '@polkadot/api-derive';
import { decorateDerive, DeriveCustom, ExactDerive } from '@polkadot/api-derive';
import { memo } from '@polkadot/api-derive/util';
import { expandMetadata, Metadata } from '@polkadot/metadata';
import { RpcCore } from '@polkadot/rpc-core';
@@ -542,8 +542,13 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
}
protected _decorateDeriveRx (decorateMethod: DecorateMethod<ApiType>): DeriveAllSections<'rxjs', ExactDerive> {
const specName = this._runtimeVersion?.specName.toString();
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const derives = { ...this._options.derives, ...(this._options.typesBundle?.spec?.[specName ?? '']?.derives as DeriveCustom) }; // use typesBundle
// Pull in derive from api-derive
const derive = decorateDerive(this.#instanceId, this._rx, this._options.derives);
const derive = decorateDerive(this.#instanceId, this._rx, derives);
return decorateSections<'rxjs', ExactDerive>(derive, decorateMethod);
}
+239
View File
@@ -0,0 +1,239 @@
// Copyright 2017-2020 @polkadot/api authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Observable } from 'rxjs';
import type { ApiInterfaceRx } from '@polkadot/api/types';
import type { Enum, Struct } from '@polkadot/types';
import type { Option } from '@polkadot/types/codec';
import type { AccountId, AccountIndex, AccountInfo, Address, Balance, BlockNumber, Index } from '@polkadot/types/interfaces';
import { combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiPromise, WsProvider } from '@polkadot/api';
import { memo } from '@polkadot/api-derive/util/memo';
interface VestingInfo extends Struct {
readonly locked: Balance;
readonly perBlock: Balance;
readonly startingBlock: BlockNumber;
}
interface SignedBalance extends Enum {
readonly isPositive: boolean;
readonly asPositive: Balance;
readonly isNegative: boolean;
readonly asNegative: Balance;
}
export interface EQDeriveBalancesAll {
freeBalance: Balance;
reservedBalance: Balance;
vestingLocked: Balance;
lockedBalance: Balance;
accountId: AccountId;
accountNonce: Index;
lockedBreakdown: unknown[];
}
type Result = [Balance, Balance, Balance, Index];
type RawResult = [
SignedBalance,
Option<Balance>,
Option<VestingInfo>,
AccountInfo
];
type EQDeriveBalancesQuery = (
address: AccountIndex | AccountId | Address | string
) => Observable<EQDeriveBalancesAll>;
const typesBundle = {
spec: {
Equilibrium: {
derives: {
balances: {
all: (
instanceId: string,
api: ApiInterfaceRx
): EQDeriveBalancesQuery =>
memo(
instanceId,
(address: AccountIndex | AccountId | Address | string) =>
api.derive.accounts.accountId(address).pipe(
switchMap(
(accountId): Observable<[AccountId, Result]> =>
accountId
? combineLatest([
of(accountId),
api
.queryMulti([
[api.query.balances.account, [accountId, 'EQ']],
[api.query.eqVesting.vested, accountId],
[api.query.eqVesting.vesting, accountId],
[api.query.system.account, accountId]
])
.pipe(
map(
(raw): Result => {
if (raw.length < 4) {
throw new Error('4 members expected');
}
const res = raw as RawResult;
const freeBalance = res[0].asPositive;
let reservedBalance = api.registry.createType(
'Balance'
);
let vestingLocked = api.registry.createType(
'Balance'
);
if (res[1].isSome && res[2].isSome) {
const vested = res[1].unwrap();
const info = res[2].unwrap();
vestingLocked = info.locked;
reservedBalance = api.registry.createType(
'Balance',
vestingLocked.sub(vested)
);
}
return [
freeBalance,
reservedBalance,
vestingLocked,
res[3].nonce
];
}
)
)
])
: of([
api.registry.createType('AccountId'),
[
api.registry.createType('Balance'),
api.registry.createType('Balance'),
api.registry.createType('Balance'),
api.registry.createType('Index')
]
])
),
map(
([
accountId,
[
freeBalance,
reservedBalance,
vestingLocked,
accountNonce
]
]): EQDeriveBalancesAll => ({
accountId,
accountNonce,
freeBalance,
lockedBalance: vestingLocked,
lockedBreakdown: [],
reservedBalance,
vestingLocked
})
)
)
)
}
},
types: [
{
minmax: [0, undefined] as [number?, number?],
types: {
Balance: 'u64',
BalanceOf: 'Balance',
BalancesAggregate: {
total_debt: 'Balance',
total_issuance: 'Balance'
},
BlockNumber: 'u64',
Currency: {
_enum: ['Unknown', 'Usd', 'EQ', 'Eth', 'Btc', 'Eos', 'Dot']
},
DataPoint: {
account_id: 'AccountId',
block_number: 'BlockNumber',
price: 'u64',
timestamp: 'u64'
},
FixedI64: 'i64',
Keys: 'SessionKeys3',
LookupSource: 'AccountId',
PricePeriod: {
_enum: ['Min', 'TenMin', 'Hour', 'FourHour', 'Day']
},
PricePoint: {
block_number: 'BlockNumber',
data_points: 'Vec<DataPoint>',
price: 'u64',
timestamp: 'u64'
},
ReinitRequest: {
account: 'AccountId',
authority_index: 'AuthIndex',
block_num: 'BlockNumber',
validators_len: 'u32'
},
SignedBalance: {
_enum: {
Negative: 'Balance',
Positive: 'Balance'
}
},
TotalAggregates: {
collateral: 'Balance',
debt: 'Balance'
},
TransferReason: {
_enum: [
'Common',
'InterestFee',
'MarginCall',
'BailsmenRedistribution',
'TreasuryEqBuyout',
'TreasuryBuyEq'
]
},
UserGroup: {
_enum: ['Unknown', 'Balances', 'Bailsman']
},
VestingInfo: {
locked: 'Balance',
perBlock: 'Balance',
startingBlock: 'BlockNumber'
}
}
}
]
}
}
};
function createApi (): Promise<ApiPromise> {
jest.setTimeout(30000);
const provider = new WsProvider('wss://tge.equilibrium.io');
return new ApiPromise({ provider, typesBundle }).isReady;
}
describe.skip('equilibrium api', () => {
it.skip('does not fail on derive.balances.all', async () => {
const api = await createApi();
await api.derive.balances.all(
'5DnoYz3koaRcMZ9Hj4FmQ2nNRKQfS73yBmEzzM9SsPn9cLtb'
);
});
});
+3
View File
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { Observable } from 'rxjs';
import { H256 } from '../interfaces/runtime';
import { ChainProperties } from '../interfaces/system';
@@ -101,9 +102,11 @@ export interface OverrideVersionedType {
}
export type OverrideModuleType = Record<string, string>;
export type DeriveCustom = Record<string, Record<string, (instanceId: string, api: any) => (...args: any[]) => Observable<any>>>;
export interface OverrideBundleDefinition {
alias?: Record<string, OverrideModuleType>;
derives?: DeriveCustom;
rpc?: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>>;
types?: OverrideVersionedType[];
}