common.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import {
  2. GenericAccountId,
  3. Struct,
  4. Option,
  5. Text,
  6. bool,
  7. u16,
  8. u32,
  9. u64,
  10. Null,
  11. U8aFixed,
  12. BTreeSet,
  13. UInt,
  14. Compact,
  15. } from '@polkadot/types'
  16. import { BlockNumber, Hash as PolkadotHash, Moment } from '@polkadot/types/interfaces'
  17. import { Codec, Constructor, RegistryTypes } from '@polkadot/types/types'
  18. import { u8aConcat, u8aToHex } from '@polkadot/util'
  19. // we get 'moment' because it is a dependency of @polkadot/util, via @polkadot/keyring
  20. import moment from 'moment'
  21. import { JoyStructCustom, JoyStructDecorated } from './JoyStruct'
  22. import { JoyEnum } from './JoyEnum'
  23. export { JoyEnum, JoyStructCustom, JoyStructDecorated }
  24. // Adds sorting during BTreeSet toU8a encoding (required by the runtime)
  25. // Currently only supports values that extend UInt
  26. // FIXME: Will not cover cases where BTreeSet is part of extrinsic args metadata
  27. export interface ExtendedBTreeSet<V extends UInt> extends BTreeSet<V> {
  28. toArray(): V[]
  29. }
  30. export function JoyBTreeSet<V extends UInt>(valType: Constructor<V>): Constructor<ExtendedBTreeSet<V>> {
  31. return class extends BTreeSet.with(valType) {
  32. public toArray(): V[] {
  33. return Array.from(this)
  34. }
  35. public toU8a(isBare?: boolean): Uint8Array {
  36. const encoded = new Array<Uint8Array>()
  37. if (!isBare) {
  38. encoded.push(Compact.encodeU8a(this.size))
  39. }
  40. const sorted = Array.from(this).sort((a, b) => (a.lt(b) ? -1 : 1))
  41. sorted.forEach((v: V) => {
  42. encoded.push(v.toU8a(isBare))
  43. })
  44. return u8aConcat(...encoded)
  45. }
  46. public toHex(): string {
  47. return u8aToHex(this.toU8a())
  48. }
  49. }
  50. }
  51. export class ActorId extends u64 {}
  52. export class MemberId extends u64 {}
  53. // Indentical type names for Forum and Proposal Discussions modules
  54. // Ensure they are both configured in runtime to have same type
  55. export class ThreadId extends u64 {}
  56. export class PostId extends u64 {}
  57. // Which module uses this?
  58. export class Hash extends U8aFixed implements PolkadotHash {}
  59. export type BlockAndTimeType = {
  60. block: BlockNumber
  61. time: Moment
  62. }
  63. export class BlockAndTime extends JoyStructDecorated({ block: u32, time: u64 }) implements BlockAndTimeType {
  64. get momentDate(): moment.Moment {
  65. const YEAR_2000_MILLISECONDS = 946684801000
  66. // overflowing in ~270,000 years
  67. const timestamp = this.time.toNumber()
  68. // TODO: remove once https://github.com/Joystream/joystream/issues/705 is resolved
  69. // due to a bug, timestamp can be either in seconds or milliseconds
  70. let timestampInMillis = timestamp
  71. if (timestamp < YEAR_2000_MILLISECONDS) {
  72. // timestamp is in seconds
  73. timestampInMillis = timestamp * 1000
  74. }
  75. return moment(timestampInMillis)
  76. }
  77. }
  78. export function getTextPropAsString(struct: Struct, fieldName: string): string {
  79. return (struct.get(fieldName) as Text).toString()
  80. }
  81. export function getBoolPropAsBoolean(struct: Struct, fieldName: string): boolean {
  82. return (struct.get(fieldName) as bool).valueOf()
  83. }
  84. export function getOptionPropOrUndefined<T extends Codec>(struct: Struct, fieldName: string): T | undefined {
  85. return (struct.get(fieldName) as Option<T>).unwrapOr(undefined)
  86. }
  87. export class OptionText extends Option.with(Text) {}
  88. export type InputValidationLengthConstraintType = {
  89. min: u16
  90. max_min_diff: u16
  91. }
  92. export class InputValidationLengthConstraint
  93. extends JoyStructDecorated({
  94. min: u16,
  95. max_min_diff: u16,
  96. })
  97. implements InputValidationLengthConstraintType {
  98. get max(): u16 {
  99. return this.registry.createType('u16', this.min.add(this.max_min_diff))
  100. }
  101. }
  102. export const WorkingGroupDef = {
  103. Forum: Null,
  104. Storage: Null,
  105. Content: Null,
  106. Membership: Null,
  107. } as const
  108. export type WorkingGroupKey = keyof typeof WorkingGroupDef
  109. export class WorkingGroup extends JoyEnum(WorkingGroupDef) {}
  110. export class MemoText extends Text {}
  111. // @polkadot/types overrides required since migration to Substrate 2.0,
  112. // see: https://polkadot.js.org/docs/api/FAQ#i-cannot-send-transactions-sending-yields-address-decoding-failures
  113. export class AccountId extends GenericAccountId {}
  114. export class Address extends AccountId {}
  115. export class LookupSource extends AccountId {}
  116. export const commonTypes: RegistryTypes = {
  117. ActorId,
  118. MemberId,
  119. BlockAndTime,
  120. ThreadId,
  121. PostId,
  122. InputValidationLengthConstraint,
  123. WorkingGroup,
  124. MemoText,
  125. // Customize Address type for joystream chain
  126. Address,
  127. LookupSource,
  128. }
  129. export default commonTypes