Select Git revision
CONTRIBUTING.md
-
Pascal Engélibert authoredPascal Engélibert authored
After you've reviewed these contribution guidelines, you'll be all set to
contribute to this project.
schema.graphql 10.09 KiB
# === this part of the schema comes from giant squid ===
# https://github.com/subsquid-labs/giant-squid-explorer/blob/main/schema.graphql
# Block / Extrinsic / Call / Event
type Block @entity {
"BlockHeight-blockHash - e.g. 0001812319-0001c"
id: ID!
height: Int! @index
hash: Bytes! @index
parentHash: Bytes!
stateRoot: Bytes!
extrinsicsicRoot: Bytes!
specName: String!
specVersion: Int! @index
implName: String!
implVersion: Int!
timestamp: DateTime! @index
validator: Bytes @index
extrinsicsCount: Int!
callsCount: Int!
eventsCount: Int!
extrinsics: [Extrinsic]! @derivedFrom(field: "block") @cardinality(value: 1000)
calls: [Call]! @derivedFrom(field: "block") @cardinality(value: 1000)
events: [Event]! @derivedFrom(field: "block") @cardinality(value: 1000)
}
type ExtrinsicSignature {
address: JSON
signature: JSON
signedExtensions: JSON
}
type Extrinsic @entity {
id: ID!
block: Block!
call: Call!
index: Int!
version: Int!
signature: ExtrinsicSignature
tip: BigInt
fee: BigInt
success: Boolean @index
error: JSON
hash: Bytes! @index
calls: [Call]! @derivedFrom(field: "extrinsic")
events: [Event]! @derivedFrom(field: "extrinsic")
}
type Call @entity @index(fields: ["id", "pallet", "name"]) {
id: ID!
block: Block!
extrinsic: Extrinsic
parent: Call
address: [Int!]!
success: Boolean! @index
error: JSON
pallet: String! @index
name: String! @index
args: JSON
argsStr: [String]
subcalls: [Call]! @derivedFrom(field: "parent")
events: [Event]! @derivedFrom(field: "call")
}
type Event @entity @index(fields: ["id", "pallet", "name"]) {
"Event id - e.g. 0000000001-000000-272d6"
id: ID!
block: Block!
extrinsic: Extrinsic
call: Call
index: Int!
phase: String!
pallet: String! @index
name: String! @index
args: JSON
argsStr: [String]
}
enum CounterLevel {
Global
Pallet
Item
}
enum ItemType {
Extrinsics
Calls
Events
}
type ItemsCounter @entity {
id: ID!
type: ItemType! @index
level: CounterLevel! @index
total: Int! @index
}
# === this part of the schema is for substrate pallets ===
# Balances /
"Account table identified by its ss58 address"
type Account @entity {
"Account address is SS58 format"
id: ID!
"current account for the identity"
identity: Identity @derivedFrom(field: "account")
"removed identities on this account"
# they are handled apart to avoid dropping the @unique constraint of account
removedIdentities: [Identity] @derivedFrom(field: "accountRemoved")
"was once account of the identity"
wasIdentity: [ChangeOwnerKey!] @derivedFrom(field: "previous") # there should be at most one
"linked to the identity"
linkedIdentity: Identity
"transfers issued by this account"
transfersIssued: [Transfer!] @derivedFrom(field: "from")
"transfers received by this account"
transfersReceived: [Transfer!] @derivedFrom(field: "to")
"comments issued"
commentsIssued: [TxComment!] @derivedFrom(field: "author")
"is currently active"
isActive: Boolean!
}
"Since identities can change owner key, validator table helps track which smith is forging the block"
# this could be removed if we fix the following issues
# https://git.duniter.org/nodes/rust/duniter-v2s/-/issues/197
# https://git.duniter.org/nodes/rust/duniter-v2s/-/issues/245
type Validator @entity {
"SS58 of pubkey used at least once to compute a block"
id: ID!
"Identity index of Smith who owned this pubkey"
index: Int! @index
}
"Transfers"
type Transfer @entity {
"Block number of the transfer"
blockNumber: Int! @index
"Timestamp of the transfer (duplicate of block timestamp)"
timestamp: DateTime! @index
"Transfer issuer"
from: Account!
"Transfer receiver"
to: Account!
"Integer amount of the transfer"
amount: BigInt! @index
"Event the transfer was created in" # allows to find the call and block
event: Event!
"Optional comment linked to the transfer"
comment: TxComment
}
type Smith @entity {
"Identity index"
index: Int! @index @unique
identity: Identity! @unique
"Smith certifications issued"
smithCertIssued: [SmithCert!] @derivedFrom(field: "issuer")
"Smith certifications received"
smithCertReceived: [SmithCert!] @derivedFrom(field: "receiver")
"Smith status of the identity"
smithStatus: SmithStatus
"history of the smith changes events"
smithHistory: [SmithEvent] @derivedFrom(field: "smith")
"Last status change"
lastChanged: Int
"Number of forged blocks"
forged: Int!
"Last forged block"
lastForged: Int
}
# === this part of the schema is for Duniter pallets ===
#
"Identity"
type Identity @entity {
"Identity index"
index: Int! @index @unique
"Current account"
# should be null for a removed identity and only in this case
account: Account @unique
"Let track the account in case identity was removed"
# should be non null for a removed identity and only in this case
accountRemoved: Account
"Name"
name: String! @index
"Status of the identity"
# mixes identity pallet status (Unconfirmed, Unvalidated, Revoked)
# and membership pallet status (Member, WasMember)
# and a special status "Removed" specific to the indexer
status: IdentityStatus! @index
"Block number of identity creation event"
createdOn: Int!
"Event corresponding of identity creation event"
createdIn: Event!
"Block number of last identity, changeOwnerKey and membership event"
lastChangeOn: Int!
"Certifications issued"
certIssued: [Cert!] @derivedFrom(field: "issuer")
"Certifications received"
certReceived: [Cert!] @derivedFrom(field: "receiver")
"True if the identity is a member"
isMember: Boolean!
"the current expireOn value"
# can be in the future if membership is active
# or in the past if membership is removed
expireOn: Int!
"history of the membership changes events"
membershipHistory: [MembershipEvent] @derivedFrom(field: "identity")
"Owner key changes"
ownerKeyChange: [ChangeOwnerKey!] @derivedFrom(field: "identity")
"linked accounts"
linkedAccount: [Account!] @derivedFrom(field: "linkedIdentity")
"Smith information"
smith: Smith @derivedFrom(field: "identity")
"Universal Dividend history"
udHistory: [UdHistory!] @derivedFrom(field: "identity")
}
"identity status directly linked to Duniter IdtyStatus"
enum IdentityStatus {
Unconfirmed
Unvalidated
Member
NotMember
Revoked
# this status is added because the indexer keeps track of the history
# and does not remove an identity event when it is remove from Duniter
Removed
}
"smith status directly linked to Duniter SmithStatus" # used as a nullable field because most identities are not smith as well
enum SmithStatus {
Invited
Pending
Smith
Excluded
}
"owner key change"
type ChangeOwnerKey @entity {
identity: Identity!
previous: Account!
next: Account!
blockNumber: Int!
}
"Certification"
type Cert @entity {
issuer: Identity! @index
receiver: Identity! @index
"whether the certification is currently active or not" # helper to avoid compare expireOn to current block number
isActive: Boolean!
"the first block number of the certification creation" # helper field to avoid looking for all CertCreation
createdOn: Int!
"the event corresponding to the first certification creation"
createdIn: Event!
"the last block number of the certification renewal"
updatedOn: Int!
"the event corresponding to the last certification renewal"
updatedIn: Event!
"the current expireOn value" # helper field to avoid looking for all CertRenewal and search for the last one
expireOn: Int!
certHistory: [CertEvent!] @derivedFrom(field: "cert")
}
"Certification event"
type CertEvent @entity {
cert: Cert! @index
event: Event!
blockNumber: Int! @index
eventType: EventType!
}
"Smith certification"
type SmithCert @entity {
issuer: Smith!
receiver: Smith!
createdOn: Int!
}
type SmithEvent @entity {
smith: Smith! @index
eventType: SmithEventType!
event: Event!
blockNumber: Int! @index
}
enum SmithEventType {
Invited
Accepted
Promoted
Excluded
}
type MembershipEvent @entity {
identity: Identity! @index
eventType: EventType!
event: Event!
blockNumber: Int! @index
}
"event type used for certification and membership"
enum EventType {
"creation event"
Creation
"renewal event"
Renewal
"removal event"
Removal
}
"Each Universal Dividend created since the beginning of the blockchain"
type UniversalDividend @entity {
blockNumber: Int!
event: Event!
timestamp: DateTime!
amount: BigInt!
monetaryMass: BigInt!
membersCount: Int!
}
"List of reevaluation of Universal Dividend based on changes in monetary mass and number of members. Every 6 months in Ğ1"
type UdReeval @entity {
blockNumber: Int!
event: Event!
timestamp: DateTime!
newUdAmount: BigInt!
monetaryMass: BigInt!
membersCount: Int!
}
"History of Universal Dividend received by an member identity."
type UdHistory @entity {
identity: Identity! @index
amount: Int!
blockNumber: Int!
timestamp: DateTime!
}
"transaction comment"
type TxComment @entity {
"Block number of the comment" # allows easy sorting
blockNumber: Int!
"Author of the comment"
author: Account!
"Event where the comment comes from"
event: Event!
"Raw remark as present on the blockchain"
remarkBytes: Bytes!
"Remark decoded as string"
remark: String!
"Blake two 256 hash published by the blockchain in the remark event"
# not used at the moment, will be changed in Duniter
hash: String!
"Type of the comment"
# now classified by the indexer, can later appear in Duniter
type: CommentType!
}
"type of the tx comment"
# by order of preference
enum CommentType {
"bytes look like a CID"
Cid
"bytes can be decoded to printable ascii"
Ascii
"bytes can be decoded to printable utf8"
Unicode
"no known type, raw bytes"
Raw
}
"History of the blockchain population."
type PopulationHistory @entity {
"The count of smiths at this point in the history."
smithCount: Int!
"The count of members at this point in the history."
memberCount: Int!
"The count of active accounts at this point in the history."
activeAccountCount: Int!
"The block number at which this history record was created."
blockNumber: Int! @index @unique
}