Skip to content
Snippets Groups Projects
types.ts 3.83 KiB
import { CID } from 'multiformats'
import { BASE } from './consts'

export interface Pointer<T> {
  value: T
}

/// index request
// the CID of this document is sent through pubsub
// so that collectors could add it to their AMT
// and indexer could add it to their database
export interface IndexRequest {
  /// pubkey of the author of the document
  // used to verify signature, should be in a format handeled by the datapod (ex: ss58 address, base58 pubkey...)
  pubkey: string
  /// timestamp of the document
  // used as u64 in the signature
  // note that the user can send whatever timestamp it wants
  // but the collector can choose to reject document if the timestamp differs too much from his local time
  time: number
  /// kind of the document, arbitrary string interpreted by the datapod
  // can be a CID of the document format description
  // allows to filter documents based on kinds of interest
  kind: string
  /// data coming with the index request is separed from it
  // when null, it means there is no data, for example in the case of a document deletion
  data: CID | null
  /// signature of the following byte payload :
  /// ["dd" prefix for 'duniter datapods' | timestamp as u64 bytes | kind bytes | data bytes or 0x00]
  // can be null in the case where the signature is inside the data (C+ profile formats for example)
  sig: string | null
}

// internal node
export interface IndexInode {
  /// children
  // the length of the children array is equal to the BASE
  children: (null | [string, CID])[]
  // string is the key
  // we use a string here for demo since javascript does not support easy u32 bitwise operation
  // but in real world, we will use a bitvector, likely in base16, groups of 4 bits
  /// context about the key prefix of the node
  ctx: string
  /// count of elements below this node
  count: number
}
// default constructor
export function emptyInode(ctx: string): IndexInode {
  return {
    children: new Array(BASE).fill(null),
    ctx,
    count: 0
  }
}
// root node has no ctx
export function emptyRootInode(): IndexInode {
  return emptyInode('')
}

// virtual internal node
// same as IndexInode but mutable and only in memory
// allows to process batch insert without having to change all intermediate nodes (including root node) each time
export interface IndexVinode {
  // same as IndexInode
  children: (null | [string, IndexVinode | IndexLeaf])[]
  ctx: string
}
// default constructor
export function emptyVinode(ctx: string): IndexVinode {
  return {
    children: new Array(BASE).fill(null),
    ctx
  }
}

// leaf
export interface IndexLeaf {
  // array of cid, expected to be quite small, without duplicates, and sorted
  leaf: CID[]
  // key of this leaf
  key: string
}

export function emptyLeaf(key: string): IndexLeaf {
  return {
    leaf: [],
    key
  }
}

// index history
export interface IndexHist {
  // cid of the latest tracked history
  // or null if beginning of the history (number 0)
  last_history: CID | null
  // cid of the current root node
  current_index: CID
  // block number
  number: number
  // timestamp
  timestamp: number
}

// =================== cplus

// for reference see
// https://doc.e-is.pro/cesium-plus-pod/REST_API.html
export interface CplusProfile {
  version: number
  title: string
  description: string
  time: number
  issuer: string
  hash: string
  signature: string
  city?: string
  geoPoint?: Geoloc
  socials?: Social[]
  tags?: string[]
  avatar?: Avatar | CID
}

// social
interface Social {
  type: string
  url: string
}

// avatar field will be managed as an IPFS file
export interface Avatar {
  _content_type: string // image/png for instance
  _content: string // base64 encoded
}

// geoloc
interface Geoloc {
  lat: number
  lon: number
}
// ================== tx comment

export interface TxComment {
  /// extrinsic hash as string
  tx_id: string
  /// comment
  comment: string
}