allow custom Extrinsic implementation (#739)
* refactor: allow custom Extrinsic implementation * decorate Extrinsic into SubmittableExtrinsic * per comments * avoid cyclical dependency * try to make codeclimate happy * code clean up * fix after rebase master
This commit is contained in:
@@ -23,13 +23,13 @@ import extrinsicsFromMeta from '@polkadot/extrinsics/fromMetadata';
|
||||
import RpcBase from '@polkadot/rpc-core/index';
|
||||
import RpcRx from '@polkadot/rpc-rx/index';
|
||||
import storageFromMeta from '@polkadot/storage/fromMetadata';
|
||||
import { Event, Hash, Metadata, Method, RuntimeVersion, typeRegistry } from '@polkadot/types/index';
|
||||
import { Event, getTypeRegistry, Hash, Metadata, Method, RuntimeVersion } from '@polkadot/types/index';
|
||||
import { MethodFunction, ModulesWithMethods } from '@polkadot/types/primitive/Method';
|
||||
import { StorageFunction } from '@polkadot/types/primitive/StorageKey';
|
||||
import { assert, compactStripLength, isFunction, isObject, isUndefined, logger, u8aToHex } from '@polkadot/util';
|
||||
import { cryptoWaitReady } from '@polkadot/util-crypto';
|
||||
|
||||
import SubmittableExtrinsic from './SubmittableExtrinsic';
|
||||
import { createSubmittableExtrinsic, SubmittableExtrinsic } from './SubmittableExtrinsic';
|
||||
|
||||
type MetaDecoration = {
|
||||
callIndex?: Uint8Array,
|
||||
@@ -319,7 +319,7 @@ export default abstract class ApiBase<CodecResult, SubscriptionResult> implement
|
||||
*/
|
||||
registerTypes (types?: RegistryTypes): void {
|
||||
if (types) {
|
||||
typeRegistry.register(types);
|
||||
getTypeRegistry().register(types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ export default abstract class ApiBase<CodecResult, SubscriptionResult> implement
|
||||
|
||||
private decorateExtrinsicEntry<C, S> (method: MethodFunction, onCall: OnCallDefinition<C, S>): SubmittableExtrinsicFunction<C, S> {
|
||||
const decorated: any = (...params: Array<CodecArg>): SubmittableExtrinsic<C, S> =>
|
||||
new SubmittableExtrinsic(this.type, this._rx as ApiInterface$Rx, onCall, method(...params));
|
||||
createSubmittableExtrinsic(this.type, this._rx as ApiInterface$Rx, onCall, method(...params));
|
||||
|
||||
return this.decorateFunctionMeta(method, decorated) as SubmittableExtrinsicFunction<C, S>;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeyringPair } from '@polkadot/keyring/types';
|
||||
import { AccountId, Address, Extrinsic, ExtrinsicStatus, EventRecord, Hash, Index, Method, SignedBlock, Struct, Text, Vector } from '@polkadot/types/index';
|
||||
import { Codec, CodecCallback, SignatureOptions } from '@polkadot/types/types';
|
||||
import { AccountId, Address, ExtrinsicStatus, EventRecord, getTypeRegistry, Hash, Index, Method, SignedBlock, Struct, Text, Vector } from '@polkadot/types/index';
|
||||
import { Codec, CodecCallback, IExtrinsic, SignatureOptions } from '@polkadot/types/types';
|
||||
import { ApiInterface$Rx, ApiType, OnCallDefinition, Signer } from './types';
|
||||
|
||||
import { Observable, of, combineLatest } from 'rxjs';
|
||||
@@ -18,7 +18,7 @@ type StatusCb = (result: SubmittableResult) => any;
|
||||
type SumbitableResultResult<CodecResult, SubscriptionResult> =
|
||||
CodecResult extends Observable<any>
|
||||
? Observable<SubmittableResult>
|
||||
: Promise<Hash>;
|
||||
: Promise<Hash>;
|
||||
|
||||
type SumbitableResultSubscription<CodecResult, SubscriptionResult> =
|
||||
SubscriptionResult extends Observable<any>
|
||||
@@ -56,26 +56,29 @@ export class SubmittableResult extends Struct {
|
||||
}
|
||||
}
|
||||
|
||||
export default class SubmittableExtrinsic<CodecResult, SubscriptionResult> extends Extrinsic {
|
||||
private _api: ApiInterface$Rx;
|
||||
private _onCall: OnCallDefinition<CodecResult, SubscriptionResult>;
|
||||
private _noStatusCb?: boolean;
|
||||
export interface SubmittableExtrinsic<CodecResult, SubscriptionResult> extends IExtrinsic {
|
||||
send (): SumbitableResultResult<CodecResult, SubscriptionResult>;
|
||||
|
||||
constructor (type: ApiType, api: ApiInterface$Rx, onCall: OnCallDefinition<CodecResult, SubscriptionResult>, extrinsic: Extrinsic | Method) {
|
||||
super(extrinsic);
|
||||
send (statusCb: (result: SubmittableResult) => any): SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
|
||||
this._noStatusCb = type === 'rxjs';
|
||||
this._api = api;
|
||||
this._onCall = onCall;
|
||||
}
|
||||
sign (account: KeyringPair, _options: Partial<SignatureOptions>): this;
|
||||
|
||||
private updateSigner (updateId: number, status: Hash | SubmittableResult): void {
|
||||
if ((updateId !== -1) && this._api.signer && this._api.signer.update) {
|
||||
this._api.signer.update(updateId, status);
|
||||
signAndSend (account: KeyringPair | string | AccountId | Address, options?: Partial<Partial<SignatureOptions>>): SumbitableResultResult<CodecResult, SubscriptionResult>;
|
||||
|
||||
signAndSend (account: KeyringPair | string | AccountId | Address, statusCb: StatusCb): SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
}
|
||||
|
||||
export function createSubmittableExtrinsic<CodecResult, SubscriptionResult> (type: ApiType, api: ApiInterface$Rx, onCall: OnCallDefinition<CodecResult, SubscriptionResult>, extrinsic: Method): SubmittableExtrinsic<CodecResult, SubscriptionResult> {
|
||||
const _extrinsic = new (getTypeRegistry().getOrThrow('Extrinsic'))(extrinsic) as SubmittableExtrinsic<CodecResult, SubscriptionResult>;
|
||||
const _noStatusCb = type === 'rxjs';
|
||||
|
||||
function updateSigner (updateId: number, status: Hash | SubmittableResult): void {
|
||||
if ((updateId !== -1) && api.signer && api.signer.update) {
|
||||
api.signer.update(updateId, status);
|
||||
}
|
||||
}
|
||||
|
||||
private statusObservable (status: ExtrinsicStatus): Observable<SubmittableResult> {
|
||||
function statusObservable (status: ExtrinsicStatus): Observable<SubmittableResult> {
|
||||
if (status.type !== 'Finalised') {
|
||||
return of(
|
||||
new SubmittableResult({
|
||||
@@ -88,12 +91,12 @@ export default class SubmittableExtrinsic<CodecResult, SubscriptionResult> exten
|
||||
const blockHash = status.asFinalised;
|
||||
|
||||
return combineLatest(
|
||||
this._api.rpc.chain.getBlock(blockHash) as Observable<SignedBlock>,
|
||||
this._api.query.system.events.at(blockHash) as Observable<Vector<EventRecord>>
|
||||
api.rpc.chain.getBlock(blockHash) as Observable<SignedBlock>,
|
||||
api.query.system.events.at(blockHash) as Observable<Vector<EventRecord>>
|
||||
).pipe(
|
||||
map(([signedBlock, allEvents]) =>
|
||||
new SubmittableResult({
|
||||
events: filterEvents(this.hash, signedBlock, allEvents),
|
||||
events: filterEvents(_extrinsic.hash, signedBlock, allEvents),
|
||||
status,
|
||||
type: status.type
|
||||
})
|
||||
@@ -101,108 +104,116 @@ export default class SubmittableExtrinsic<CodecResult, SubscriptionResult> exten
|
||||
);
|
||||
}
|
||||
|
||||
private sendObservable (updateId: number = -1): Observable<Hash> {
|
||||
return (this._api.rpc.author
|
||||
.submitExtrinsic(this) as Observable<Hash>)
|
||||
function sendObservable (updateId: number = -1): Observable<Hash> {
|
||||
return (api.rpc.author
|
||||
.submitExtrinsic(_extrinsic) as Observable<Hash>)
|
||||
.pipe(
|
||||
tap((hash) => {
|
||||
this.updateSigner(updateId, hash);
|
||||
updateSigner(updateId, hash);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private subscribeObservable (updateId: number = -1): Observable<SubmittableResult> {
|
||||
return (this._api.rpc.author
|
||||
.submitAndWatchExtrinsic(this) as Observable<ExtrinsicStatus>)
|
||||
function subscribeObservable (updateId: number = -1): Observable<SubmittableResult> {
|
||||
return (api.rpc.author
|
||||
.submitAndWatchExtrinsic(_extrinsic) as Observable<ExtrinsicStatus>)
|
||||
.pipe(
|
||||
switchMap((status) =>
|
||||
this.statusObservable(status)
|
||||
statusObservable(status)
|
||||
),
|
||||
tap((status) => {
|
||||
this.updateSigner(updateId, status);
|
||||
updateSigner(updateId, status);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private expandOptions (options: Partial<SignatureOptions>): SignatureOptions {
|
||||
function expandOptions (options: Partial<SignatureOptions>): SignatureOptions {
|
||||
return {
|
||||
blockHash: this._api.genesisHash,
|
||||
version: this._api.runtimeVersion,
|
||||
blockHash: api.genesisHash,
|
||||
version: api.runtimeVersion,
|
||||
...options
|
||||
} as SignatureOptions;
|
||||
}
|
||||
|
||||
send (): SumbitableResultResult<CodecResult, SubscriptionResult>;
|
||||
send (statusCb: (result: SubmittableResult) => any): SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
send (statusCb?: (result: SubmittableResult) => any): SumbitableResultResult<CodecResult, SubscriptionResult> | SumbitableResultSubscription<CodecResult, SubscriptionResult> {
|
||||
const isSubscription = this._noStatusCb || !!statusCb;
|
||||
const signOrigin = _extrinsic.sign;
|
||||
Object.defineProperties(
|
||||
_extrinsic,
|
||||
{
|
||||
send: {
|
||||
value: function (statusCb?: (result: SubmittableResult) => any): SumbitableResultResult<CodecResult, SubscriptionResult> | SumbitableResultSubscription<CodecResult, SubscriptionResult> {
|
||||
const isSubscription = _noStatusCb || !!statusCb;
|
||||
|
||||
return this._onCall(
|
||||
() => isSubscription
|
||||
? this.subscribeObservable()
|
||||
: this.sendObservable(),
|
||||
[],
|
||||
statusCb as CodecCallback,
|
||||
isSubscription
|
||||
) as unknown as SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
}
|
||||
return onCall(
|
||||
() => isSubscription
|
||||
? subscribeObservable()
|
||||
: sendObservable(),
|
||||
[],
|
||||
statusCb as CodecCallback,
|
||||
isSubscription
|
||||
) as unknown as SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
}
|
||||
},
|
||||
sign: {
|
||||
value: function (account: KeyringPair, _options: Partial<SignatureOptions>): SubmittableExtrinsic<CodecResult, SubscriptionResult> {
|
||||
// HACK here we actually override nonce if it was specified (backwards compat for
|
||||
// the previous signature - don't let userspace break, but allow then time to upgrade)
|
||||
const options: Partial<SignatureOptions> = isBn(_options) || isNumber(_options)
|
||||
? { nonce: _options as any as number }
|
||||
: _options;
|
||||
|
||||
// NOTE with the nonce hack, we don't add a signature overload for 2 reasons -
|
||||
// - it makes it incompatible with the base Extrinsic
|
||||
// - for those using TS, we would like to move them towards the new version
|
||||
sign (account: KeyringPair, _options: Partial<SignatureOptions>): SubmittableExtrinsic<CodecResult, SubscriptionResult> {
|
||||
// HACK here we actually override nonce if it was specified (backwards compat for
|
||||
// the previous signature - don't let userspace break, but allow then time to upgrade)
|
||||
const options: Partial<SignatureOptions> = isBn(_options) || isNumber(_options)
|
||||
? { nonce: _options as any as number }
|
||||
: _options;
|
||||
signOrigin.apply(_extrinsic, [account, expandOptions(options)]);
|
||||
|
||||
super.sign(account, this.expandOptions(options));
|
||||
return this;
|
||||
}
|
||||
},
|
||||
signAndSend: {
|
||||
value: function (account: KeyringPair | string | AccountId | Address, _options?: Partial<Partial<SignatureOptions>> | StatusCb, statusCb?: StatusCb): SumbitableResultResult<CodecResult, SubscriptionResult> | SumbitableResultSubscription<CodecResult, SubscriptionResult> {
|
||||
let options: Partial<Partial<SignatureOptions>> = {};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
signAndSend (account: KeyringPair | string | AccountId | Address, options?: Partial<Partial<SignatureOptions>>): SumbitableResultResult<CodecResult, SubscriptionResult>;
|
||||
signAndSend (account: KeyringPair | string | AccountId | Address, statusCb: StatusCb): SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
signAndSend (account: KeyringPair | string | AccountId | Address, _options?: Partial<Partial<SignatureOptions>> | StatusCb, statusCb?: StatusCb): SumbitableResultResult<CodecResult, SubscriptionResult> | SumbitableResultSubscription<CodecResult, SubscriptionResult> {
|
||||
let options: Partial<Partial<SignatureOptions>> = {};
|
||||
|
||||
if (isFunction(_options)) {
|
||||
statusCb = _options;
|
||||
} else {
|
||||
options = _options || {};
|
||||
}
|
||||
|
||||
const isSubscription = this._noStatusCb || !!statusCb;
|
||||
const isKeyringPair = isFunction((account as KeyringPair).address) && isFunction((account as KeyringPair).sign);
|
||||
const address = isKeyringPair ? (account as KeyringPair).address() : account.toString();
|
||||
let updateId: number | undefined;
|
||||
|
||||
return this._onCall(
|
||||
() => ((
|
||||
isUndefined(options.nonce)
|
||||
? this._api.query.system.accountNonce(address) as Observable<Index>
|
||||
: of(new Index(options.nonce))
|
||||
).pipe(
|
||||
first(),
|
||||
mergeMap(async (nonce) => {
|
||||
if (isKeyringPair) {
|
||||
this.sign(account as KeyringPair, { ...options, nonce });
|
||||
if (isFunction(_options)) {
|
||||
statusCb = _options;
|
||||
} else {
|
||||
assert(this._api.signer, 'no signer exists');
|
||||
|
||||
updateId = await (this._api.signer as Signer).sign(this, address, this.expandOptions({ ...options, nonce }));
|
||||
options = _options || {};
|
||||
}
|
||||
}),
|
||||
switchMap(() => {
|
||||
return isSubscription
|
||||
? this.subscribeObservable(updateId)
|
||||
: this.sendObservable(updateId) as any; // ???
|
||||
})
|
||||
) as Observable<Codec>),
|
||||
[],
|
||||
statusCb as CodecCallback,
|
||||
isSubscription
|
||||
) as unknown as SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
}
|
||||
|
||||
const isSubscription = _noStatusCb || !!statusCb;
|
||||
const isKeyringPair = isFunction((account as KeyringPair).address) && isFunction((account as KeyringPair).sign);
|
||||
const address = isKeyringPair ? (account as KeyringPair).address() : account.toString();
|
||||
let updateId: number | undefined;
|
||||
|
||||
return onCall(
|
||||
() => ((
|
||||
isUndefined(options.nonce)
|
||||
? api.query.system.accountNonce(address) as Observable<Index>
|
||||
: of(new Index(options.nonce))
|
||||
).pipe(
|
||||
first(),
|
||||
mergeMap(async (nonce) => {
|
||||
if (isKeyringPair) {
|
||||
this.sign(account as KeyringPair, { ...options, nonce });
|
||||
} else {
|
||||
assert(api.signer, 'no signer exists');
|
||||
|
||||
updateId = await (api.signer as Signer).sign(_extrinsic, address, expandOptions({
|
||||
...options,
|
||||
nonce
|
||||
}));
|
||||
}
|
||||
}),
|
||||
switchMap(() => {
|
||||
return isSubscription
|
||||
? subscribeObservable(updateId)
|
||||
: sendObservable(updateId) as any; // ???
|
||||
})
|
||||
) as Observable<Codec>),
|
||||
[],
|
||||
statusCb as CodecCallback,
|
||||
isSubscription
|
||||
) as unknown as SumbitableResultSubscription<CodecResult, SubscriptionResult>;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return _extrinsic;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Codec } from '@polkadot/types/types';
|
||||
import { QueryableStorageFunction as QueryableStorageFunctionBase, SubmittableExtrinsicFunction as SubmittableExtrinsicFunctionBase } from '../types';
|
||||
|
||||
import ApiBase from '../Base';
|
||||
import SubmittableExtrinsicBase from '../SubmittableExtrinsic';
|
||||
import { SubmittableExtrinsic as SubmittableExtrinsicBase } from '../SubmittableExtrinsic';
|
||||
|
||||
export type SubscriptionResult = Promise<() => any>;
|
||||
|
||||
|
||||
@@ -6,13 +6,19 @@ import { Observable } from 'rxjs';
|
||||
import { DeriveCustom } from '@polkadot/api-derive/index';
|
||||
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
||||
import { RpcRxInterface$Events } from '@polkadot/rpc-rx/types';
|
||||
import { Extrinsic, Hash, Metadata, RuntimeVersion, u64 as U64 } from '@polkadot/types/index';
|
||||
import { CodecArg, CodecCallback, RegistryTypes, SignatureOptions } from '@polkadot/types/types';
|
||||
import { Hash, Metadata, RuntimeVersion, u64 as U64 } from '@polkadot/types/index';
|
||||
import {
|
||||
CodecArg,
|
||||
CodecCallback,
|
||||
IExtrinsic,
|
||||
RegistryTypes,
|
||||
SignatureOptions
|
||||
} from '@polkadot/types/types';
|
||||
import { MethodFunction } from '@polkadot/types/primitive/Method';
|
||||
import { StorageFunction } from '@polkadot/types/primitive/StorageKey';
|
||||
|
||||
import { RxResult } from './rx/types';
|
||||
import SubmittableExtrinsic, { SubmittableResult } from './SubmittableExtrinsic';
|
||||
import { SubmittableResult, SubmittableExtrinsic } from './SubmittableExtrinsic';
|
||||
import ApiBase from './Base';
|
||||
|
||||
export type OnCallDefinition<CodecResult, SubscriptionResult> = (method: OnCallFunction<RxResult, RxResult>, params?: Array<CodecArg>, callback?: CodecCallback, needsCallback?: boolean) => CodecResult | SubscriptionResult;
|
||||
@@ -163,7 +169,7 @@ export interface Signer {
|
||||
/**
|
||||
* @description Signs an extrinsic, returning an id (>0) that can be used to retrieve updates
|
||||
*/
|
||||
sign (extrinsic: Extrinsic, address: string, options: SignatureOptions): Promise<number>;
|
||||
sign (extrinsic: IExtrinsic, address: string, options: SignatureOptions): Promise<number>;
|
||||
|
||||
/**
|
||||
* @description Receives an update for the extrinsic signed by a `signer.sign`
|
||||
|
||||
@@ -2,11 +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 { EventRecord, Hash, SignedBlock } from '@polkadot/types/index';
|
||||
import { EventRecord, SignedBlock, U8a } from '@polkadot/types/index';
|
||||
|
||||
import l from './logging';
|
||||
|
||||
export default function filterEvents (extHash: Hash, { block: { extrinsics, header } }: SignedBlock, allEvents: Array<EventRecord>): Array<EventRecord> | undefined {
|
||||
export default function filterEvents (extHash: U8a, { block: { extrinsics, header } }: SignedBlock, allEvents: Array<EventRecord>): Array<EventRecord> | undefined {
|
||||
// extrinsics to hashes
|
||||
const myHash = extHash.toHex();
|
||||
const allHashes = extrinsics.map((ext) => ext.hash.toHex());
|
||||
|
||||
@@ -6,6 +6,7 @@ import { isUndefined } from '@polkadot/util';
|
||||
|
||||
import { getTypeDef, TypeDef, TypeDefInfo } from '../../codec/createType';
|
||||
import flattenUniq from './flattenUniq';
|
||||
import { getTypeRegistry } from '../../codec';
|
||||
|
||||
export default function validateTypes (types: Array<string>, throwError: boolean): void {
|
||||
const extractTypes = (types: Array<string>): Array<any> => {
|
||||
@@ -32,9 +33,9 @@ export default function validateTypes (types: Array<string>, throwError: boolean
|
||||
});
|
||||
};
|
||||
|
||||
const allTypes = require('../../index');
|
||||
const typeRegistry = getTypeRegistry();
|
||||
const missing = flattenUniq(extractTypes(types)).filter((type) =>
|
||||
isUndefined(allTypes[type])
|
||||
isUndefined(typeRegistry.get(type))
|
||||
);
|
||||
|
||||
if (missing.length !== 0) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import Struct from './Struct';
|
||||
import Tuple from './Tuple';
|
||||
import UInt from './UInt';
|
||||
import Vector from './Vector';
|
||||
import registry from './typeRegistry';
|
||||
import getRegistry from './typeRegistry';
|
||||
|
||||
export enum TypeDefInfo {
|
||||
Compact,
|
||||
@@ -137,6 +137,10 @@ export function getTypeDef (_type: Text | string, name?: string): TypeDef {
|
||||
|
||||
// Returns the type Class for construction
|
||||
export function getTypeClass (value: TypeDef): Constructor {
|
||||
const Type = getRegistry().get(value.type);
|
||||
if (Type) {
|
||||
return Type;
|
||||
}
|
||||
if (value.info === TypeDefInfo.Compact) {
|
||||
assert(value.sub && !Array.isArray(value.sub), 'Expected subtype for Compact');
|
||||
|
||||
@@ -183,13 +187,7 @@ export function getTypeClass (value: TypeDef): Constructor {
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE We only load types via require - we have to avoid circular deps between type usage and creation
|
||||
const Types = require('../index.types');
|
||||
const Type = registry.get(value.type) || Types[value.type];
|
||||
|
||||
assert(Type, `Unable to determine type from '${value.type}'`);
|
||||
|
||||
return Type;
|
||||
throw new Error(`Unable to determine type from '${value.type}'`);
|
||||
}
|
||||
|
||||
export function createClass (type: Text | string, value?: any): Constructor {
|
||||
|
||||
@@ -23,4 +23,4 @@ export { default as UInt } from './UInt';
|
||||
|
||||
// Type management helper functions
|
||||
export { default as createType, createClass, getTypeClass, getTypeDef, TypeDef, TypeDefInfo } from './createType';
|
||||
export { default as typeRegistry } from './typeRegistry';
|
||||
export { default as getTypeRegistry } from './typeRegistry';
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { isFunction, isString, isUndefined } from '@polkadot/util';
|
||||
|
||||
import { Constructor, RegistryTypes } from '../types';
|
||||
|
||||
import { isFunction, isString } from '@polkadot/util';
|
||||
|
||||
import { createClass } from './createType';
|
||||
|
||||
export class TypeRegistry {
|
||||
@@ -31,15 +30,17 @@ export class TypeRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
private registerObject (obj: RegistryTypes) {
|
||||
private registerObject (obj: RegistryTypes, overwrite: boolean = true) {
|
||||
Object.entries(obj).forEach(([name, type]) => {
|
||||
if (isString(type)) {
|
||||
this._registry.set(name, createClass(type));
|
||||
} else if (isFunction(type)) {
|
||||
// This _looks_ a bit funny, but `typeof Clazz === 'function'
|
||||
this._registry.set(name, type);
|
||||
} else {
|
||||
this._registry.set(name, createClass(JSON.stringify(type)));
|
||||
if (overwrite || !this.get(name)) {
|
||||
if (isString(type)) {
|
||||
this._registry.set(name, createClass(type));
|
||||
} else if (isFunction(type)) {
|
||||
// This _looks_ a bit funny, but `typeof Clazz === 'function'
|
||||
this._registry.set(name, type);
|
||||
} else {
|
||||
this._registry.set(name, createClass(JSON.stringify(type)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -47,6 +48,25 @@ export class TypeRegistry {
|
||||
get (name: string): Constructor | undefined {
|
||||
return this._registry.get(name);
|
||||
}
|
||||
|
||||
getOrThrow (name: string, msg?: string): Constructor {
|
||||
const type = this.get(name);
|
||||
if (isUndefined(type)) {
|
||||
throw new Error(msg || `type ${name} not found`);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
export default TypeRegistry.defaultRegistry;
|
||||
let defaultRegistry: TypeRegistry;
|
||||
|
||||
export default function getDefaultRegistry () {
|
||||
if (!defaultRegistry) {
|
||||
const defaultTypes = require('../index.types');
|
||||
defaultRegistry = new TypeRegistry();
|
||||
defaultRegistry.register({ ...defaultTypes });
|
||||
}
|
||||
|
||||
return defaultRegistry;
|
||||
}
|
||||
|
||||
@@ -2,7 +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 { KeyringPair } from '@polkadot/keyring/types';
|
||||
import BN from 'bn.js';
|
||||
import Method from './primitive/Method';
|
||||
import Address from './type/Address';
|
||||
import U8a from './codec/U8a';
|
||||
|
||||
export type CodecArg = Codec | BN | Boolean | String | Uint8Array | boolean | number | string | undefined | CodecArgArray | CodecArgObject;
|
||||
|
||||
@@ -94,3 +98,16 @@ export type SignatureOptions = {
|
||||
nonce: AnyNumber,
|
||||
version?: RuntimeVersionInterface
|
||||
};
|
||||
|
||||
export interface IHash extends U8a {}
|
||||
|
||||
export interface ISignature extends Codec {}
|
||||
|
||||
export interface IExtrinsic extends Codec {
|
||||
hash: IHash;
|
||||
isSigned: boolean;
|
||||
method: Method;
|
||||
signature: ISignature;
|
||||
addSignature (signer: Address | Uint8Array, signature: Uint8Array, nonce: AnyNumber, era?: Uint8Array): this;
|
||||
sign (account: KeyringPair, options: SignatureOptions): this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user