import './augment/types-lookup' import './augment/registry' import './augment/augment-api' import './augment/augment-types' import { AnyU8a, Codec, DetectCodec, ITuple, Observable } from '@polkadot/types/types' import { Text, UInt, Null, bool, Option, Vec, BTreeSet, BTreeMap, Tuple, Enum, Struct, Bytes, TypeRegistry, Raw, } from '@polkadot/types' import defs from './augment/lookup' import BN from 'bn.js' import { AugmentedQuery } from '@polkadot/api/types' // Tweaked version of https://stackoverflow.com/a/62163715 for handling enum variants // Based on type (T) like: { a: string; b: number; c: Null; } // will create a type like: { a: string } | { b: number } | { c: Null } | "c" export type EnumVariant = keyof T extends infer K ? K extends keyof T ? T[K] extends Null | null ? K | { [I in K]: T[I] } : { [I in K]: T[I] } : never : never // Other enum utility types: type EnumAccessors = { [K in `as${T}`]?: unknown } type DecoratedEnum = Omit & { type: T } & EnumAccessors // If `asX` is defined - we want the returned codec type, otherwise it's Null (and `isX` is defined instead) type CodecOrNull = T extends Codec ? T : Null type EnumDefs, T extends string> = { [K in T]: CodecOrNull } // Struct utility types type StructDefs = Omit type KeyOf = T extends DecoratedEnum ? keyof EnumDefs : T extends Struct ? keyof StructDefs : unknown[] type AsRecord = K extends string ? Record : K extends number ? Record : never /** * Recursively create typesafe interface representing valid input for constructing any Codec type * (inlcuding complex types with a lot of nesting) * * Some examples: * * CreateInterface> = Option | u128 | number | BN | null | undefined * * CreateInterface = * PalletCommonBalanceKind | * 'Positive' | * 'Negative' | * { Positive: null } | * { Negative: null } * * CreateInterface = * PalletContentPermissionsContentActor | * 'Lead' | * { Lead: null } | * { Curator: ITuple<[u64, u64]> | [u64 | BN | number, u64 | BN | number] } * { Member: u64 | BN | number } * * CreateInterface = * PalletContentLimitPerPeriod | * { limit: u64 | BN | number, blockNumberPeriod: u32 | BN | number } */ export type CreateInterface = | T | (T extends Option ? null | undefined | CreateInterface : T extends DecoratedEnum ? EnumVariant<{ [K in keyof EnumDefs]: CreateInterface[K]> }> : T extends Struct ? { [K in keyof StructDefs]: CreateInterface[K]> } : T extends Text ? string : T extends Bytes | Raw ? AnyU8a : T extends UInt ? number | BN : T extends bool ? boolean : T extends Vec ? CreateInterface[] : T extends BTreeSet ? CreateInterface[] | Set> : T extends ITuple ? S extends Tuple ? unknown[] : { [K in keyof S]: CreateInterface } : T extends BTreeMap ? Map, CreateInterface> | AsRecord, CreateInterface> : T extends Null ? null : unknown) export const registry = new TypeRegistry() registry.register(defs as any) export function createType( typeName: TN, value: CreateInterface> ): Codec extends DetectCodec ? unknown : DetectCodec { return registry.createType(typeName, value) } export function keysOf(typeName: TN): KeyOf[] { return registry.createType(typeName).defKeys as KeyOf[] } export async function entriesByIds( apiMethod: AugmentedQuery<'promise', (key: IDType) => Observable, [IDType]> ): Promise<[IDType, AsCodec][]> { const entries: [IDType, AsCodec][] = (await apiMethod.entries()).map(([storageKey, value]) => [ storageKey.args[0] as IDType, value, ]) return entries.sort((a, b) => a[0].toNumber() - b[0].toNumber()) } export type AsCodec = T extends Codec ? T : Codec export const JOYSTREAM_ADDRESS_PREFIX = 126