index.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { Codec, Constructor, RegistryTypes } from '@polkadot/types/types'
  2. import common from './common'
  3. import members from './members'
  4. import council from './council'
  5. import roles from './roles'
  6. import forum from './forum'
  7. import stake from './stake'
  8. import mint from './mint'
  9. import recurringRewards from './recurring-rewards'
  10. import hiring from './hiring'
  11. import workingGroup from './working-group'
  12. import storage from './storage'
  13. import proposals from './proposals'
  14. import content from './content'
  15. import legacy from './legacy'
  16. import { InterfaceTypes } from '@polkadot/types/types/registry'
  17. import { TypeRegistry, Text, UInt, Null, bool, Option, Vec, BTreeSet, BTreeMap } from '@polkadot/types'
  18. import { ExtendedEnum } from './JoyEnum'
  19. import { ExtendedStruct } from './JoyStruct'
  20. import BN from 'bn.js'
  21. export {
  22. common,
  23. members,
  24. council,
  25. roles,
  26. forum,
  27. stake,
  28. mint,
  29. recurringRewards,
  30. hiring,
  31. workingGroup,
  32. storage,
  33. proposals,
  34. content,
  35. }
  36. export const types: RegistryTypes = {
  37. // legacy types comes first so they are overriden by proper definitions in new modules
  38. ...legacy,
  39. ...common,
  40. ...members,
  41. ...council,
  42. ...roles,
  43. ...forum,
  44. ...stake,
  45. ...mint,
  46. ...recurringRewards,
  47. ...hiring,
  48. ...workingGroup,
  49. ...storage,
  50. ...proposals,
  51. ...content,
  52. }
  53. // Allows creating types without api instance (it's not a recommended way though, so should be used just for mocks)
  54. export const registry = new TypeRegistry()
  55. registry.register(types)
  56. // Tweaked version of https://stackoverflow.com/a/62163715 for handling enum variants
  57. // Based on type (T) like: { a: string; b: number; c: Null; }
  58. // will create a type like: { a: string } | { b: number } | { c: Null } | "c"
  59. type EnumVariant<T> = keyof T extends infer K
  60. ? K extends keyof T
  61. ? T[K] extends Null | null
  62. ? K | { [I in K]: T[I] }
  63. : { [I in K]: T[I] }
  64. : never
  65. : never
  66. // Create simple interface for any Codec type (inlcuding JoyEnums and JoyStructs)
  67. // Cannot handle Option here, since that would cause circular reference error
  68. type CreateInterface_NoOption<T extends Codec> =
  69. | T
  70. | (T extends ExtendedEnum<infer S>
  71. ? EnumVariant<{ [K in keyof S]: CreateInterface<InstanceType<T['typeDefinitions'][K]>> }>
  72. : T extends ExtendedStruct<infer S>
  73. ? { [K in keyof S]?: CreateInterface<InstanceType<T['typeDefs'][K]>> }
  74. : T extends Text
  75. ? string
  76. : T extends UInt
  77. ? number | BN
  78. : T extends bool
  79. ? boolean
  80. : T extends Vec<infer S> | BTreeSet<infer S>
  81. ? CreateInterface<S>[]
  82. : T extends BTreeMap<infer K, infer V>
  83. ? Map<K, V>
  84. : T extends Null
  85. ? null
  86. : unknown)
  87. // Wrapper for CreateInterface_NoOption that includes resolving an Option
  88. // (nested Options like Option<Option<Codec>> will resolve to Option<any>, but there are very edge case)
  89. export type CreateInterface<T extends Codec> =
  90. | T
  91. | (T extends Option<infer S> ? undefined | null | S | CreateInterface_NoOption<S> : CreateInterface_NoOption<T>)
  92. export type AnyTypeName = keyof InterfaceTypes
  93. export function createType<TN extends AnyTypeName, T extends InterfaceTypes[TN] = InterfaceTypes[TN]>(
  94. type: TN,
  95. value: CreateInterface<T>
  96. ): InterfaceTypes[TN] {
  97. return registry.createType(type, value)
  98. }
  99. // FIXME: Backward-compatibility. Use only one createType in the future!
  100. export function createTypeFromConstructor<T extends Codec>(type: Constructor<T>, value: CreateInterface<T>): T {
  101. return registry.createType(type.name as AnyTypeName, value) as T
  102. }