Requêtes GraphQL à WotWizard

Comme annoncé dans ce post, Le nœud https://wotwizard.coinduf.eu/ expose son API GraphQL à l’adresse https://wwgql.coinduf.eu/. Comme annoncé dans ce post, l’API peut être testée sur le playground GraphIQL https://ww2.coinduf.eu/ .

Je propose ce fil pour montrer des exemples de requêtes GraphQL ou poser des questions à @gerard94 . Cela permettra à @Paidge ou @hypericum de construire plus facilement des clients.

3 « J'aime »

Le typesystem de wotwizard peut être trouvé dans le dossier Help sur https://git.duniter.org/gerard94/WotWizard. Le voici :

# WotWizard GraphQL TypeSystem

type Query {
	
	"'identities' lists all identities whose status is 'status' and whose uids is between 'start' (included) and 'end' (excluded), in increasing order and sorted by 'sortedBy'; if 'start' is absent or null, the list starts at the beginning, and stops at the end if 'end' is absent or null"
	identities (status: Identity_Status! = MEMBER, sortedBy: Identity_Order! = UID, start: String! = "", end: String! = ""): [Identity!]!
	
	"'idSearch' displays the list of identities whose pseudos or public keys begin with 'with.hint' and whose status is in 'with.status_list'."
	idSearch (with: IdSearchInput! = {}): IdSearchOutput!
	
	"'idFromHash' retreives the 'Identity' whose hash is 'hash'; it returns null if this identity doesn't exist"
	idFromHash (hash: Hash!): Identity
	
	"Threshold for numbers of sent and received certifications to become sentry"
	sentryThreshold: Int!
	
	"List of sentries, sorted by increasing uids"
	sentries: [Identity!]!
	
	"Present block"
	now: Block!

	"'wwFile' displays the WotWizard file, complete if 'full', or else with Dossier(s) containing at least 'Query.parameter(name: sigQty)' certifications only"
	wwFile (full: Boolean! = false): File!
	
	"'wwResult' displays the content of the WotWizard window"
	wwResult: WWResult!
	
	"'memEnds' displays the list of members who are about to loose their memberships, in the order of event dates (bct); 'startFromNow' gives the period before the beginning of the list (0 if absent or null) , and 'period' gives the period covered by the list (infinite if absent or null)"
	memEnds (startFromNow: Int64, period: Int64): [Identity!]!
	
	"'missEnds' displays the list of identities who are MISSING and about to be revoked, in the order of event dates (bct); 'startFromNow' gives the period before the beginning of the list (0 if absent or null) , and 'period' gives the period covered by the list (infinite if absent or null)"
	missEnds (startFromNow: Int64, period: Int64): [Identity!]!
	
	"'certEnds' displays the list of identities who are MEMBER or (possibly) MISSING and about to loose their 'ParameterName.sigQty'th oldest certification, in the order of event dates (bct); 'startFromNow' gives the period before the beginning of the list (0 if absent or null) , and 'period' gives the period covered by the list (infinite if absent or null)"
	certEnds (startFromNow: Int64, period: Int64, missingIncluded: Boolean! = true): [Identity!]!
	
	"'countMin' gives the first block of the blockchain"
	countMin: Block!
	
	"'countMax' gives the last present block of the blockchain"
	countMax: Block!
	
	"'membersCount' displays the number of active members, sorted by dates (utc0) of events (in or out the wot); if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	membersCount (start: Int64, end: Int64): [Event!]!
	
	"'membersFlux' displays the flux of active members by <timeUnit (s)>; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	membersFlux (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'membersFluxPM' displays the flux of active members by <timeUnit (s)> and by member; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	membersFluxPM (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'fECount' displays the number of first entries into the wot, sorted by dates (utc0) of events (entries); if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	fECount (start: Int64, end: Int64): [Event!]!
	
	"'fEFlux' displays the flux of first entries by <timeUnit (s)>; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	fEFlux (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'fEFluxPM' displays the flux of first entries by <timeUnit (s)> and by member; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	fEFluxPM (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'lossCount' displays the number of members exiting the wot, minus the number of reentries (losses), sorted by dates (utc0) of events (in or out the wot); if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	lossCount (start: Int64, end: Int64): [Event!]!
	
	"'lossFlux' displays the flux of losses by <timeUnit (s)>; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	lossFlux (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'lossFluxPM' displays the flux of losses by <timeUnit (s)> and by member; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	lossFluxPM (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'allParameters' displays all parameters of the money"
	allParameters: [Parameter!]!
	
	"'parameter' displays the parameter of the money whose name is 'name''"
	parameter (name: ParameterName): Parameter
	
	"'version' returns a string describing the version of the graphQL server"
	version: String!

} #Query

type Mutation {
	
	"'stopSubscription' erases the subscription whose name is 'name', which sends results at address 'returnAddr'; 'varVals' is a JSON object whose fields keys are the names of the variables (without '$') used in the subscription and whose fields values are their values"
	stopSubscription (returnAddr: String!, name: String!, varVals: String): Void

} #Mutation

type Subscription {
	
	"'now' installs a subscription for the update of 'Query.now' at every new block"
	now: Block!

	"'wwFile' installs a subscription for the update of 'Query.wwFile' at every new block"
	wwFile (full: Boolean! = false): FileS!
	
	"'wwResult' installs a subscription for the update of 'Query.wwResult' at every new block"
	wwResult: WWResultS!
	
	"'memEnds' installs a subscription for the update of 'Query.memEnds' at every new block"
	memEnds (startFromNow: Int64, period: Int64): [Identity!]!
	
	"'missEnds' installs a subscription for the update of 'Query.missEnds' at every new block"
	missEnds (startFromNow: Int64, period: Int64): [Identity!]!
	
	"'certEnds' installs a subscription for the update of 'Query.certEnds' at every new block"
	certEnds (startFromNow: Int64, period: Int64, missingIncluded: Boolean! = true): [Identity!]!

} #Subscription

"WoT identity"
type Identity {
	
	"Public key"
	pubkey: Pubkey!
	
	"Pseudo"
	uid: String!
	
	"Hash"
	hash: Hash!
	
	"Status: REVOKED, MISSING, MEMBER or NEWCOMER"
	status: Identity_Status!
	
	"Identity waiting for new membership (MISSING, MEMBER or NEWCOMER; false for REVOKED)"
	membership_pending: Boolean!
	
	"Block of new membership application; null if not membership_pending"
	membership_pending_block: Block
	
	"Limit date of new membership application; null if not membership_pending"
	membership_pending_limitDate: Int64
	
	"Block where the identity is written (entry into the web of trust); null for NEWCOMER"
	id_written_block: Block
	
	"Block of last membership application (joiners, actives, leavers), null for NEWCOMER"
	lastApplication: Block
	
	"Limit date of the membership application; null for REVOKED; limit date before revocation for MISSING"
	limitDate: Int64
	
	"Member is leaving? null for REVOKED or NEWCOMER"
	isLeaving: Boolean
	
	"Is a sentry? null if not MEMBER"
	sentry: Boolean
	
	"Active received certifications, sorted by increasing pubkeys"
	received_certifications: Received_Certifications!
	
	"Active sent certifications, sorted by increasing pubkeys"
	sent_certifications: [Certification!]!
	
	"All certifiers, old or present, but not REVOKED (empty list for NEWCOMER)"
	all_certifiers: [Identity!]!
	
	"All certified identities, old or present, but not REVOKED (empty list for NEWCOMER)"
	all_certified: [Identity!]!
	
	"All certifiers, old or present (empty list for NEWCOMER), with blocks of certification validity inputs and outputs"
	all_certifiersIO: [CertHist!]!
	
	"All certified identities, old or present (empty list for NEWCOMER), with blocks of certification validity inputs and outputs"
	all_certifiedIO: [CertHist!]!
	
	"State of the identity's distance rule"
	distance: Distance!
	
	"Identity's quality (percent)"
	quality: Float!
	
	"Identity's degree of centrality (percent)"
	centrality: Float!
	
	"History of identity's entries into and exits out of the WoT (empty list for NEWCOMER)"
	history: [HistoryEvent!]!
	
	"Minimum date of next sent certification; null if not MEMBER"
	minDate: Int64
	
	"Minimum date of next sent certification is passed; null if not MEMBER"
	minDatePassed: Boolean

} #Identity

"Status of an identity in WoT"
enum Identity_Status {
	
	"The identity has been revoked"
	REVOKED
	
	"The identity is no more member but not revoked yet"
	MISSING
	
	"The identity is a member of the WoT"
	MEMBER
	
	"Newcomer waiting for membership"
	NEWCOMER

} #Identity_Status

"Sorting order"
enum Identity_Order {
	
	"Sorting by uid"
	UID
	
	"Sorting by pubkey"
	PUBKEY

} #Identity_Order

"Used by 'Query.idSearch'"
input IdSearchInput {
	
	"Prefix of searched keys (uid or pubkey)"
	hint: String! = ""
	
	"List of searched statuses"
	status_list: [Identity_Status!]! = [REVOKED, MISSING, MEMBER, NEWCOMER]
	
} #IdSearchInput

"Result of 'Query.idSearch'"
type IdSearchOutput {
	
	"Number of REVOKED identities corresponding to 'IdSearchInput.hint'"
	revokedNb: Int!
	
	"Number of MISSING identities corresponding to 'IdSearchInput.hint'"
	missingNb: Int!
	
	"Number of MEMBER identities corresponding to 'IdSearchInput.hint'"
	memberNb: Int!
	
	"Number of NEWCOMER identities corresponding to 'IdSearchInput.hint'"
	newcomerNb: Int!
	
	"All identities corresponding to 'IdSearchInput'"
	ids: [Identity!]!
	
} #IdSearchOutput

"Certifications received by an identity"
type Received_Certifications {
	
	"List of all valid received certifications"
	certifications: [Certification!]!
	
	"Limit date of the 'ParameterName.sigQty'th oldest received certification; or null if less than 'ParameterName.sigQty' certifications received"
	limit: Int64
	
} #received_Certifications

"Certification sent by 'from' and received by 'to'"
type Certification {
	
	"Sender"
	from: Identity!
	
	"Receiver"
	to: Identity!
	
	"Is certification in sandbox?"
	pending: Boolean!
	
	"Registration block"
	block: Block
	
	"Limit date (bct) of validity"
	expires_on: Int64!
	
} #Certification

"Result of distance rule evaluation"
type Distance {
	
	"Proportion of sentries reached in 'ParameterName.stepMax' steps or less (percent)"
	value: Float!
	
	"Is 'value' greater than 'ParameterName.xpercent' or equal?"
	dist_ok: Boolean!
	
} #Distance

"History of entries into the WoT and exits of an identity"
type HistoryEvent {
	
	"Entry?"
	in: Boolean!
	
	"Registration block"
	block: Block!
	
} #HistoryEvent

"History of certifications from or to an identity"
type CertHist {
	
	"Certifier or certified identity"
	id: Identity!
	
	"Beginning and ending blocks of certifications validities"
	hist: [CertEvent!]!

} #CertHist

"Beginning or ending block of a certification validity"
type CertEvent {
	
	"Beginning?"
	in: Boolean!
	
	"Beginning or ending block"
	block: Block!

} #CertEvent

"Number & dates of a block"
type Block {
	
	"Block number"
	number: Int!
	
	"Blockchain time"
	bct: Int64!
	
	"UTC+0 real time"
	utc0: Int64!

} #Block

"Differentiation filter parameters (Savitzky-Golay filter)"
input DifferParams {

	"Number of points over which the filter is calculated"
	pointsNb: Int! = 80
	
	"Degree of polynomial used by the filter (usually 2 or 4)"
	degree: Int! = 2
	
} #DifferParams

"Set of internal certifications and membership application dossiers available in sandbox"
interface File {

	"List of internal certifications and membership application dossiers"
	certifs_dossiers: [CertifOrDossier!]!
	
	"Number of dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!

} #File

"Set of internal certifications and membership application dossiers available in sandbox; dated"
type FileS implements File {
	
	"Present block"
	now: Block!

	"List of internal certifications and membership application dossiers"
	certifs_dossiers: [CertifOrDossier!]!
	
	"Number of dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!

} #FileS

"Internal certification or membership application dossier"
union CertifOrDossier = MarkedDatedCertification | MarkedDossier

"Inserted type used to distinguish 'DatedCertification'(s) and 'Dossier'(s) in 'CertifOrDossier'"
type MarkedDatedCertification {
	datedCertification: DatedCertification!
} #MarkedDatedCertification

"Inserted type used to distinguish 'DatedCertification'(s) and 'Dossier'(s) in 'CertifOrDossier'"
type MarkedDossier {
	dossier: Dossier!
} #MarkedDossier

"Certification in a 'File'"
type DatedCertification {
	
	certification: Certification!
	
	"Date of availability"
	date: Int64!

} #DatedCertification

"Newcomer's membership application dossier"
type Dossier {
	
	newcomer: Identity!
	
	"Minimum number of certifications needed to fulfill the distance rule"
	main_certifs: Int!
	
	"External certifications"
	certifications: [DatedCertification!]!
	
	"'ParameterName.msPeriod' after the last membership application (or 0 if none)"
	minDate: Int64!
	
	"Date of availability"
	date: Int64!
	
	"Expiration date"
	limit: Int64!

} #Dossier

"Result of 'Query.wwResult'"
interface WWResult {
	
	"Total time of computation, 'File' included"
	computation_duration: Int!
	
	"Number of permutations used; this number may be very big"
	permutations_nb: Int!
	
	"Number of NEWCOMER(s)' dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!
	
	"'permutations' displays the list of WotWizard permutations; their number may be very big"
	permutations: [WeightedPermutation!]!
	
	"Forecasts of NEWCOMER(s)' entries, sorted by dates of entries"
	forecastsByDates: [Forecast!]!
	
	"Forecasts of entries of the NEWCOMER(s) whose uid(s) begin with the 'with' parameter (or of all NEWCOMER(s) if 'with' is absent or null); the selection is not case sensitive"
	forecastsByNames (with: String! = ""): [Forecast!]!
	
} #WWResult

"Result of 'Subscription.wwResult; dated'"
type WWResultS implements WWResult {
	
	"Present block"
	now: Block!
	
	"Total time of computation, 'File' included"
	computation_duration: Int!
	
	"Number of permutations used; this number may be very big"
	permutations_nb: Int!
	
	"Number of NEWCOMER(s)' dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!
	
	"'permutations' displays the list of WotWizard permutations; their number may be very big"
	permutations: [WeightedPermutation!]!
	
	"Forecasts of NEWCOMER(s)' entries, sorted by dates of entries"
	forecastsByDates: [Forecast!]!
	
	"Forecasts of entries of the NEWCOMER(s) whose uid(s) begin with the 'with' parameter (or of all NEWCOMER(s) if 'with' is absent or null); the selection is not case sensitive"
	forecastsByNames (with: String! = ""): [Forecast!]!
	
} #WWResultS

"A permutation weighted by a probability"
type WeightedPermutation {
	
	"Probability of occurrence"
	proba: Float!
	
	"Ordered list of NEWCOMER(s)' entries"
	permutation: [PermutationElem!]!
	
} #WeightedPermutation

"An expected NEWCOMER's entry"
type PermutationElem {
	
	id: Identity!
	
	"Expected date of entry"
	date: Int64!
	
	"The expected date of entry may be later than 'date' (the computing was interrupted by lack of memory space)"
	after: Boolean!
	
} #PermutationElem

"Forecast of a NEWCOMER's entry"
type Forecast {
	
	id: Identity!
	
	"Expected date of entry"
	date: Int64!
	
	"The expected date of entry may be later than 'date' (the computing was interrupted by lack of memory space)"
	after: Boolean!
	
	"Probability of the forecast"
	proba: Float!
	
} #Forecast

"Entry or exit of an identity"
type EventId {
	
	id: Identity!
	
	"Entry or exit; true if entry"
	inOut: Boolean!
	
} #EventId

"Entries and exits of identities happening in a block"
type Event {
	
	"List of concerned identities"
	idList: [EventId!]!
	
	"Block where the event happens"
	block: Block!
	
	"Number of concerned identities in the WoT after the event"
	number: Int!
	
} #Event

"An event with non-integer value, typically a flux of entries/exits"
type FluxEvent {
	
	"Block where the event happens"
	block: Block!
	
	"Value of the flux at the event"
	value: Float!
} #FluxEvent

"A parameter of the money"
type Parameter {
	
	name: ParameterName!
	
	par_type: ParameterType!
	
	value: Number!
	
	comment: String
	
} #Parameter

enum ParameterType {
	INTEGER
	FLOAT
	DURATION
	DATE
} #ParameterType

enum ParameterName {
	
	"The relative growth of the UD every [dtReeval] period"
	c
	
	"Time period between two UD"
	dt
	
	"UD(0), i.e. initial Universal Dividend"
	ud0
	
	"Minimum delay between two certifications of a same issuer"
	sigPeriod
	
	"Maximum quantity of active certifications made by member"
	sigStock
	
	"Maximum delay a certification can wait before being expired for non-writing"
	sigWindow
	
	"Maximum age of an active certification"
	sigValidity
	
	"Minimum delay before replaying a certification"
	sigReplay
	
	"Minimum quantity of signatures to be part of the WoT"
	sigQty
	
	"Maximum delay an identity can wait before being expired for non-writing"
	idtyWindow
	
	"Maximum delay a membership can wait before being expired for non-writing"
	msWindow
	
	"Minimum delay between 2 memberships of a same issuer"
	msPeriod
	
	"Minimum percent of sentries to reach to match the distance rule"
	xpercent
	
	"Maximum age of an active membership"
	msValidity
	
	"Maximum distance between a WOT member and [xpercent] of sentries"
	stepMax
	
	"Number of blocks used for calculating median time"
	medianTimeBlocks
	
	"The average time for writing 1 block (wished time)"
	avgGenTime
	
	"The number of blocks required to evaluate again PoWMin value"
	dtDiffEval
	
	"The proportion of calculating members not excluded from the proof of work"
	percentRot
	
	"Time of first UD"
	udTime0
	
	"Time of first reevaluation of the UD"
	udReevalTime0
	
	"Time period between two re-evaluation of the UD"
	dtReeval
	
	"Maximum delay a transaction can wait before being expired for non-writing"
	txWindow

} #ParameterName

"64 bits signed integer"
scalar Int64

"Avatar of String"
scalar Hash

"Avatar of String"
scalar Pubkey

"Empty result"
scalar Void

"Int, Int64 or Float"
scalar Number

La requête la plus simple est la requête {version}. Elle retourne en ce moment :

{
  "data": {
    "version": "5.5.0"
  }
}

Capture d’écran 2021-12-11 à 17.58.01

On peut demander le nombre de membres aujourd’hui avec :

{
  membersCount(start: 1639240000, end: 1639241000) {
    number
  }
}

réponse :

{
  "data": {
    "membersCount": [
      {
        "number": 3943
      }
    ]
  }
}

Merci, super intéressant d’avoir accès à cette interface avec toutes ces informations requêtable. Ça va me permettre d’enrichir Silkaj. Dommage que ça n’ait pas fait part de plus de publicité plus tôt.

2 « J'aime »

Obtenir les pseudo des dernières entrées (true) et sorties (false) entre hier et aujourd’hui.

{
  membersCount(start: 1639100000, end: 1639241000) {
    idList {
      id {
        uid
      }
      inOut
    }
  }
}

Réponse :

{
  "data": {
    "membersCount": [
      {
        "idList": [
          {
            "id": {
              "uid": "Nathy"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Pierroots"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Laulotte84600"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "ElenaMoshkina"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "MichelLamour"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Adalgonce"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "MMM"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "DenisL"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Did84"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Gerard61"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "tano"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Elle"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "CATHERINEG"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Energie"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "JF13"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Zatalyz"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Vincent"
            },
            "inOut": false
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "Cynthia"
            },
            "inOut": true
          }
        ]
      },
      {
        "idList": [
          {
            "id": {
              "uid": "lagoet73"
            },
            "inOut": true
          }
        ]
      }
    ]
  }
}

C’est vrai que j’ai mis ça en place en février 2019 mais ensuite il y a eu une période… un peu trouble.

1 « J'aime »

Le système de types sur gitlab est en retard sur la version qui fonctionne sur coinduf.eu. Je mets tout cela à jour très bientôt, ce week-end, je pense.

1 « J'aime »

Obtenir l’uid et le hash et le status des identités dont le pseudo commence par « mou » :

{
  idSearch(with: {hint: "mou"}) {
    ids {
      uid
      hash
      status
    }
  }
}
{
  "data": {
    "idSearch": {
      "ids": [
        {
          "uid": "moul",
          "hash": "F2E8EE9CAD512394565C988837E7B87BF1262144D6DDB59FEE713A6C792C12A4",
          "status": "MEMBER"
        },
        {
          "uid": "MoulinMuriel",
          "hash": "62753278D6633318FA0EE41B26834EF188E8503DF3A18A5F03EF210657D2E18E",
          "status": "MEMBER"
        },
        {
          "uid": "Moussa",
          "hash": "33219A56A34F5683E8BFE6B91957C566911AE7F3A06397D3818A9F949B8029AC",
          "status": "MEMBER"
        },
        {
          "uid": "Moussy",
          "hash": "CF52788BE3453FA694D2DD521BC5C4C217337FA3A9FDC69A2E29F35E1440427A",
          "status": "MISSING"
        },
        {
          "uid": "Moustic",
          "hash": "A16236969C54F3B22E8CEA66CF2342464A8E16CFBD735A5B64510C36ABF5B693",
          "status": "MEMBER"
        },
        {
          "uid": "Moutarde",
          "hash": "640D743A37C46E9C7E3F849429F56502FE68036D36CF725B6F89B128F7A250A4",
          "status": "REVOKED"
        }
      ]
    }
  }
}

Question à @gerard94 : pourquoi

{
  idFromHash(
    hash: "F2E8EE9CAD512394565C988837E7B87BF1262144D6DDB59FEE713A6C792C12A4"
  ) {
    distance {
      dist_ok
    }
  }
}

retourne

{
  "data": {
    "idFromHash": {
      "distance": {
        "dist_ok": true
      }
    }
  }
}

mais

{
  idFromHash(
    hash: "F2E8EE9CAD512394565C988837E7B87BF1262144D6DDB59FEE713A6C792C12A4"
  ) {
    distance {
      value
    }
  }
}

retourne

{
  "errors": [
    {
      "message": "{\n  idFromHash(\n    hash: \"F2E8EE9CAD512394565C988837E7B87BF1262144D6DDB59FEE713A6C792C12A4\"\n  ) {\n    distance {\n      value\n    }\n  }\n}",
      "location": {
        "position": 0,
        "line": 1,
        "column": 1
      }
    },
    {
      "message": "Missing subselection of value (OBJECT, INTERFACE or UNION)",
      "location": {
        "position": 121,
        "line": 6,
        "column": 7
      }
    }
  ]
}

Connaître le bloc d’écriture de l’identité moul :

{
  idFromHash(
    hash: "F2E8EE9CAD512394565C988837E7B87BF1262144D6DDB59FEE713A6C792C12A4"
  ) {
    uid
    id_written_block {
      number
      utc0
    }
  }
}

Moul est là depuis le bloc zéro (ça fait un moment, le 2017-03-08 à 15:32:07).

{
  "data": {
    "idFromHash": {
      "uid": "moul",
      "id_written_block": {
        "number": 0,
        "utc0": 1488987127
      }
    }
  }
}

Bref. Je m’arrête là, je pense qu’il y a assez pour comprendre le principe. Le mieux pour s’entraîner est de jouer sur le playground, c’est pour ça qu’il est là.

1 « J'aime »

parce que :

1 « J'aime »

Du coup, je vous colle la bonne version :

# WotWizard GraphQL TypeSystem

type Query {
	
	"'filterGroup' returns the list of uid(s) in 'group' dispatched to three parts: those whose statuses are among 'status_list', those who are not, and those whose identities are not known; if a known identity appears several times in group, every duplicate is returned in a fourth part."
	filterGroup (group: [String!]!, status_list: [Identity_Status!]! = [REVOKED, MISSING, MEMBER, NEWCOMER]): GroupFilter!
	
	"'identities' lists identities in 'group' whose status is in 'status_list' and whose uids is between 'start' (included) and 'end' (excluded), in increasing order and sorted by 'sortedBy'; if 'start' is absent or null, the list starts at the beginning, and stops at the end if 'end' is absent or null; if 'group' is null, all known identities are used (but not if 'group' is empty); if an identity in 'group' is unknown, an error is raised, and the value returned is null."
	identities (group: [String!], status_list: [Identity_Status!]! = [REVOKED, MISSING, MEMBER, NEWCOMER], sortedBy: Identity_Order! = UID, start: String! = "", end: String! = ""): [Identity!]
	
	"'idSearch' displays the list of identities whose pseudos or public keys begin with 'with.hint' and whose status is in 'with.status_list'."
	idSearch (with: IdSearchInput! = {}): IdSearchOutput!
	
	"'idFromHash' retreives the 'Identity' whose hash is 'hash'; it returns null if this identity doesn't exist"
	idFromHash (hash: Hash!): Identity
	
	"Threshold for numbers of sent and received certifications to become sentry"
	sentryThreshold: Int!
	
	"List of sentries, sorted by increasing uids"
	sentries: [Identity!]!
	
	"Present block"
	now: Block!

	"'wwFile' displays the WotWizard file, complete if 'full', or else with Dossier(s) containing at least 'Query.parameter(name: sigQty)' certifications only"
	wwFile (full: Boolean! = false): File!
	
	"'wwResult' displays the content of the WotWizard window"
	wwResult: WWResult!
	
	"'memEnds' displays the list of members, among the reference list 'group', who are about to loose their memberships, in the increasing order of event dates (bct); 'startFromNow' gives the period (in seconds) before the beginning of the list (0 if absent or null) , and 'period' gives the period covered by the list (infinite if absent or null).  If 'group' is null or empty, the reference list is the whole Web Of Trust; if any string in 'group' is empty or doesn't refer to a known identity, it's not taken into account for the calculation, and, furthermore, if it is not empty and unknown, an error is raised"
	memEnds (group: [String!], startFromNow: Int64, period: Int64): [Identity!]!
	
	"'missEnds' displays the list of identities, among the reference list 'group', who are MISSING and about to be revoked, in the increasing order of event dates (bct); 'startFromNow' gives the period (in seconds) before the beginning of the list (0 if absent or null) , and 'period' gives the period covered by the list (infinite if absent or null).  If 'group' is null or empty, the reference list is the whole Web Of Trust; if any string in 'group' is empty or doesn't refer to a known identity, it's not taken into account for the calculation, and, furthermore, if it is not empty and unknown, an error is raised"
	missEnds (group: [String!], startFromNow: Int64, period: Int64): [Identity!]!
	
	"'certEnds' displays the list of identities , among the reference list 'group', who are MEMBER or (possibly) MISSING and about to loose their 'ParameterName.sigQty'th oldest certification, in the increasing order of event dates (bct); 'startFromNow' gives the period (in seconds) before the beginning of the list (0 if absent or null) , and 'period' gives the period covered by the list (infinite if absent or null).  If 'group' is null or empty, the reference list is the whole Web Of Trust; if any string in 'group' is empty or doesn't refer to a known identity, it's not taken into account for the calculation, and, furthermore, if it is not empty and unknown, an error is raised"
	certEnds (group: [String!], startFromNow: Int64, period: Int64, missingIncluded: Boolean! = true): [DatedIdentity!]!
	
	"'countMin' gives the first block of the blockchain"
	countMin: Block!
	
	"'countMax' gives the last present block of the blockchain"
	countMax: Block!
	
	"'membersCount' displays the number of active members, sorted by dates (utc0) of events (in or out the wot); if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	membersCount (start: Int64, end: Int64): [Event!]!
	
	"'membersFlux' displays the flux of active members by <timeUnit (s)>; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	membersFlux (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'membersFluxPM' displays the flux of active members by <timeUnit (s)> and by member; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	membersFluxPM (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'fECount' displays the number of first entries into the wot, sorted by dates (utc0) of events (entries); if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	fECount (start: Int64, end: Int64): [Event!]!
	
	"'fEFlux' displays the flux of first entries by <timeUnit (s)>; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	fEFlux (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'fEFluxPM' displays the flux of first entries by <timeUnit (s)> and by member; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	fEFluxPM (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'lossCount' displays the number of members exiting the wot, minus the number of reentries (losses), sorted by dates (utc0) of events (in or out the wot); if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	lossCount (start: Int64, end: Int64): [Event!]!
	
	"'lossFlux' displays the flux of losses by <timeUnit (s)>; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	lossFlux (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'lossFluxPM' displays the flux of losses by <timeUnit (s)> and by member; if 'start' is absent or null, the display starts at 'countMin', and ends at 'countMax' if 'end' is absent or null"
	lossFluxPM (start: Int64, end: Int64, timeUnit: Int64! = 2629800, diffPars: DifferParams! = {}): [FluxEvent!]!
	
	"'allParameters' displays all parameters of the money"
	allParameters: [Parameter!]!
	
	"'parameter' displays the parameter of the money whose name is 'name''"
	parameter (name: ParameterName): Parameter
	
	"'version' returns a string describing the version of the graphQL server"
	version: String!
	
	"'calcDist' returns the distance of the identity whose pseudo is 'uid' when the members 'certifiers' are added to her own certifiers. 'uid' may be any string, even null or empty; if 'uid' is null or empty or doesn't refer to a known identity, it's not taken into account for the calculation, and, furthermore, if it is not null, not empty and unknown, an error is raised; the same for any string in 'certifiers'"
	calcDist (uid: String, certifiers: [String!]): Distance!
	
	"'calcQual' returns the quality of the identity whose pseudo is 'uid' when the members 'certifiers' are added to her own certifiers. 'uid' may be any string, even null or empty; if 'uid' is null or empty or doesn't refer to a known identity, it's not taken into account for the calculation, and, furthermore, if it is not null, not empty and unknown, an error is raised; the same for any string in 'certifiers'"
	calcQual (uid: String, certifiers: [String!]): Fraction!
	
	"'bestDist' returns a list of members, among the reference list 'group', who could certify the identity whose pseudo is 'uid', together with the distance such a certification would give to the identity. 'certifiers' is a list of members supposed having already certified the identity in addition to her own certifiers. If 'group' is null or empty, the reference list is the whole Web Of Trust. 'uid' may be any string, even null or empty; if 'uid' is null or empty or doesn't refer to a known identity, it's not taken into account for the calculation, and, furthermore, if it is not null, not empty and unknown, an error is raised; the same for any string in 'group' or 'certifiers', and, furthermore, if the latter is not empty, it should refer to a member. 'answerNb' is the greatest number of answers in the result. If 'answerNb' is null, zero or negative, all answers are returned. Answers are sorted in the decreasing order of 'IdDist.dist.value.ratio'"
	bestDist (group: [String!], uid: String, certifiers: [String!], answerNb: Int): [IdDist!]!
	
	"'bestQual' returns a list of members, among the reference list 'group', who could certify the identity whose pseudo is 'uid', together with the quality such a certification would give to the identity. 'certifiers' is a list of members supposed having already certified the identity in addition to her own certifiers. If 'group' is null or empty, the reference list is the whole Web Of Trust. 'uid' may be any string, even null or empty; if 'uid' is null or empty or doesn't refer to a known identity, it's not taken into account for the calculation, and, furthermore, if it is not null, not empty and unknown, an error is raised; the same for any string in 'group' or 'certifiers', and, furthermore, if the latter is not empty, it should refer to a member. 'answerNb' is the greatest number of answers in the result. If 'answerNb' is null, zero or negative, all answers are returned. Answers are sorted in the decreasing order of 'IdQual.qual.ratio'"
	bestQual (group: [String!], uid: String, certifiers: [String!], answerNb: Int): [IdQual!]!

} #Query

type Mutation {
	
	"'stopSubscription' erases the subscription whose name is 'name', which sends results at address 'returnAddr'; 'varVals' is a JSON object whose fields keys are the names of the variables (without '$') used in the subscription and whose fields values are their values"
	stopSubscription (returnAddr: String!, name: String!, varVals: String): Void

} #Mutation

type Subscription {
	
	"'now' installs a subscription for the update of 'Query.now' at every new block"
	now: Block!

	"'wwFile' installs a subscription for the update of 'Query.wwFile' at every new block"
	wwFile (full: Boolean! = false): FileS!
	
	"'wwResult' installs a subscription for the update of 'Query.wwResult' at every new block"
	wwResult: WWResultS!
	
	"'memEnds' installs a subscription for the update of 'Query.memEnds' at every new block"
	memEnds (startFromNow: Int64, period: Int64): [Identity!]!
	
	"'missEnds' installs a subscription for the update of 'Query.missEnds' at every new block"
	missEnds (startFromNow: Int64, period: Int64): [Identity!]!
	
	"'certEnds' installs a subscription for the update of 'Query.certEnds' at every new block"
	certEnds (startFromNow: Int64, period: Int64, missingIncluded: Boolean! = true): [Identity!]!

} #Subscription

"Output of Query.filterGroup, used with a list of statuses; 'selected' owns the uid(s) of identities whose statuses are in the list, 'others' owns those who are not in the list, and 'unknown' corresponds to unknown identities."
type GroupFilter {
	selected: [String!]!
	others: [Error!]!
	unknown: [Error!]!
	duplicate: [Error!]!
} #Group_Filter

type Error {
	mes: String!
	path: [FieldOrRank!]!
} #Error

union FieldOrRank = Field | Rank

type Field {
	name: String!
} #Field

type Rank {
	index: Int!
} #Rank

"WoT identity"
type Identity {
	
	"Public key"
	pubkey: Pubkey!
	
	"Pseudo"
	uid: String!
	
	"Hash"
	hash: Hash!
	
	"Status: REVOKED, MISSING, MEMBER or NEWCOMER"
	status: Identity_Status!
	
	"Identity waiting for new membership (MISSING, MEMBER or NEWCOMER; false for REVOKED)"
	membership_pending: Boolean!
	
	"Block of new membership application; null if not membership_pending"
	membership_pending_block: Block
	
	"Limit date of new membership application; null if not membership_pending"
	membership_pending_limitDate: Int64
	
	"Block where the identity is written (entry into the web of trust); null for NEWCOMER"
	id_written_block: Block
	
	"Block of last membership application (joiners, actives, leavers), null for NEWCOMER"
	lastApplication: Block
	
	"Limit date of the membership application; null for REVOKED; limit date before revocation for MISSING"
	limitDate: Int64
	
	"Member is leaving? null for REVOKED or NEWCOMER"
	isLeaving: Boolean
	
	"Is a sentry? null if not MEMBER"
	sentry: Boolean
	
	"Active received certifications, sorted by increasing pubkeys"
	received_certifications: Received_Certifications!
	
	"Active sent certifications, sorted by increasing pubkeys"
	sent_certifications: [Certification!]!
	
	"All certifiers, old or present, but not REVOKED (empty list for NEWCOMER)"
	all_certifiers: [Identity!]!
	
	"All certified identities, old or present, but not REVOKED (empty list for NEWCOMER)"
	all_certified: [Identity!]!
	
	"All certifiers, old or present (empty list for NEWCOMER), with blocks of certification validity inputs and outputs"
	all_certifiersIO: [CertHist!]!
	
	"All certified identities, old or present (empty list for NEWCOMER), with blocks of certification validity inputs and outputs"
	all_certifiedIO: [CertHist!]!
	
	"State of the identity's distance rule"
	distance: Distance!
	
	"Expected state of the identity's distance rule, after pending certifications are aquired"
	distanceE: Distance!
	
	"Identity's quality"
	quality: Fraction!
	
	"Identity's expected quality, after pending certifications are aquired"
	qualityE: Fraction!
	
	"Identity's degree of centrality (percent)"
	centrality: Float!
	
	"History of identity's entries into and exits out of the WoT (empty list for NEWCOMER)"
	history: [HistoryEvent!]!
	
	"Minimum date of next sent certification; null if not MEMBER"
	minDate: Int64
	
	"Minimum date of next sent certification is passed; null if not MEMBER"
	minDatePassed: Boolean

} #Identity

"The association of 'Identity' and date"
type DatedIdentity {
	
	"Identity"
	id: Identity!
	
	"Associated date"
	date: Int64!

}

"Status of an identity in WoT"
enum Identity_Status {
	
	"The identity has been revoked"
	REVOKED
	
	"The identity is no more member but not revoked yet"
	MISSING
	
	"The identity is a member of the WoT"
	MEMBER
	
	"Newcomer waiting for membership"
	NEWCOMER

} #Identity_Status

"Sorting order"
enum Identity_Order {
	
	"Sorting by uid"
	UID
	
	"Sorting by pubkey"
	PUBKEY

} #Identity_Order

"Used by 'Query.idSearch'"
input IdSearchInput {
	
	"Prefix of searched keys (uid or pubkey)"
	hint: String! = ""
	
	"List of searched statuses"
	status_list: [Identity_Status!]! = [REVOKED, MISSING, MEMBER, NEWCOMER]
	
} #IdSearchInput

"Result of 'Query.idSearch'"
type IdSearchOutput {
	
	"Number of REVOKED identities corresponding to 'IdSearchInput.hint'"
	revokedNb: Int!
	
	"Number of MISSING identities corresponding to 'IdSearchInput.hint'"
	missingNb: Int!
	
	"Number of MEMBER identities corresponding to 'IdSearchInput.hint'"
	memberNb: Int!
	
	"Number of NEWCOMER identities corresponding to 'IdSearchInput.hint'"
	newcomerNb: Int!
	
	"All identities corresponding to 'IdSearchInput'"
	ids: [Identity!]!
	
} #IdSearchOutput

"Certifications received by an identity"
type Received_Certifications {
	
	"List of all valid received certifications"
	certifications: [Certification!]!
	
	"Limit date of the 'ParameterName.sigQty'th oldest received certification; or null if less than 'ParameterName.sigQty' certifications received"
	limit: Int64
	
} #received_Certifications

"Certification sent by 'from' and received by 'to'"
type Certification {
	
	"Sender"
	from: Identity!
	
	"Receiver"
	to: Identity!
	
	"Is certification in sandbox?"
	pending: Boolean!
	
	"Registration block"
	block: Block
	
	"Limit date (bct) of validity"
	expires_on: Int64!
	
} #Certification

"Result of distance rule evaluation"
type Distance {
	
	"Proportion of sentries reached in 'ParameterName.stepMax' steps or less (percent)"
	value: Fraction!
	
	"Is 'value' greater than 'ParameterName.xpercent' or equal?"
	dist_ok: Boolean!
	
} #Distance

"Result type of 'Query.bestDist' and 'Query.bestQual'"
type IdDist {
	
	"Identity of the certifier"
	id: Identity!
	
	"Distance or quality the certification, in addition to all the previous ones, gives to the certified identity"
	dist: Distance!

} #IdDist

"Result type of 'Query.bestDist' and 'Query.bestQual'"
type IdQual {
	
	"Identity of the certifier"
	id: Identity!
	
	"Distance or quality the certification, in addition to all the previous ones, gives to the certified identity"
	qual: Fraction!

} #IdQual

"History of entries into the WoT and exits of an identity"
type HistoryEvent {
	
	"Entry?"
	in: Boolean!
	
	"Registration block"
	block: Block!
	
} #HistoryEvent

"History of certifications from or to an identity"
type CertHist {
	
	"Certifier or certified identity"
	id: Identity!
	
	"Beginning and ending blocks of certifications validities"
	hist: [CertEvent!]!

} #CertHist

"Beginning or ending block of a certification validity"
type CertEvent {
	
	"Beginning?"
	in: Boolean!
	
	"Beginning or ending block"
	block: Block!

} #CertEvent

"Number & dates of a block"
type Block {
	
	"Block number"
	number: Int!
	
	"Blockchain time"
	bct: Int64!
	
	"UTC+0 real time"
	utc0: Int64!

} #Block

"Differentiation filter parameters (Savitzky-Golay filter)"
input DifferParams {

	"Number of points over which the filter is calculated"
	pointsNb: Int! = 80
	
	"Degree of polynomial used by the filter (usually 2 or 4)"
	degree: Int! = 2
	
} #DifferParams

"Set of internal certifications and membership application dossiers available in sandbox"
interface File {

	"List of internal certifications and membership application dossiers"
	certifs_dossiers: [CertifOrDossier!]!
	
	"Number of dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!

} #File

"Set of internal certifications and membership application dossiers available in sandbox; dated"
type FileS implements File {
	
	"Present block"
	now: Block!

	"List of internal certifications and membership application dossiers"
	certifs_dossiers: [CertifOrDossier!]!
	
	"Number of dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!

} #FileS

"Internal certification or membership application dossier"
union CertifOrDossier = MarkedDatedCertification | MarkedDossier

"Inserted type used to distinguish 'DatedCertification'(s) and 'Dossier'(s) in 'CertifOrDossier'"
type MarkedDatedCertification {
	datedCertification: DatedCertification!
} #MarkedDatedCertification

"Inserted type used to distinguish 'DatedCertification'(s) and 'Dossier'(s) in 'CertifOrDossier'"
type MarkedDossier {
	dossier: Dossier!
} #MarkedDossier

"Certification in a 'File'"
type DatedCertification {
	
	certification: Certification!
	
	"Date of availability"
	date: Int64!

} #DatedCertification

"Newcomer's membership application dossier"
type Dossier {
	
	newcomer: Identity!
	
	"Minimum number of certifications needed to fulfill the distance rule"
	main_certifs: Int!
	
	"External certifications"
	certifications: [DatedCertification!]!
	
	"'ParameterName.msPeriod' after the last membership application (or 0 if none)"
	minDate: Int64!
	
	"Date of availability"
	date: Int64!
	
	"Expiration date"
	limit: Int64!

} #Dossier

"Result of 'Query.wwResult'"
interface WWResult {
	
	"Total time of computation, 'File' included"
	computation_duration: Int!
	
	"Number of permutations used; this number may be very big"
	permutations_nb: Int!
	
	"Number of NEWCOMER(s)' dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!
	
	"'permutations' displays the list of WotWizard permutations; their number may be very big"
	permutations: [WeightedPermutation!]!
	
	"Forecasts of NEWCOMER(s)' entries, sorted by dates of entries"
	forecastsByDates: [Forecast!]!
	
	"Forecasts of entries of the NEWCOMER(s) whose uid(s) begin with the 'with' parameter (or of all NEWCOMER(s) if 'with' is absent or null); the selection is not case sensitive"
	forecastsByNames (with: String! = ""): [Forecast!]!
	
} #WWResult

"Result of 'Subscription.wwResult; dated'"
type WWResultS implements WWResult {
	
	"Present block"
	now: Block!
	
	"Total time of computation, 'File' included"
	computation_duration: Int!
	
	"Number of permutations used; this number may be very big"
	permutations_nb: Int!
	
	"Number of NEWCOMER(s)' dossiers"
	dossiers_nb: Int!
	
	"Number of internal certifications"
	certifs_nb: Int!
	
	"'permutations' displays the list of WotWizard permutations; their number may be very big"
	permutations: [WeightedPermutation!]!
	
	"Forecasts of NEWCOMER(s)' entries, sorted by dates of entries"
	forecastsByDates: [Forecast!]!
	
	"Forecasts of entries of the NEWCOMER(s) whose uid(s) begin with the 'with' parameter (or of all NEWCOMER(s) if 'with' is absent or null); the selection is not case sensitive"
	forecastsByNames (with: String! = ""): [Forecast!]!
	
} #WWResultS

"A permutation weighted by a probability"
type WeightedPermutation {
	
	"Probability of occurrence"
	proba: Float!
	
	"Ordered list of NEWCOMER(s)' entries"
	permutation: [PermutationElem!]!
	
} #WeightedPermutation

"An expected NEWCOMER's entry"
type PermutationElem {
	
	id: Identity!
	
	"Expected date of entry"
	date: Int64!
	
	"The expected date of entry may be later than 'date' (the computing was interrupted by lack of memory space)"
	after: Boolean!
	
} #PermutationElem

"Forecast of a NEWCOMER's entry"
type Forecast {
	
	id: Identity!
	
	"Expected date of entry"
	date: Int64!
	
	"The expected date of entry may be later than 'date' (the computing was interrupted by lack of memory space)"
	after: Boolean!
	
	"Probability of the forecast"
	proba: Float!
	
} #Forecast

"Entry or exit of an identity"
type EventId {
	
	id: Identity!
	
	"Entry or exit; true if entry"
	inOut: Boolean!
	
} #EventId

"Entries and exits of identities happening in a block"
type Event {
	
	"List of concerned identities"
	idList: [EventId!]!
	
	"Block where the event happens"
	block: Block!
	
	"Number of concerned identities in the WoT after the event"
	number: Int!
	
} #Event

"An event with non-integer value, typically a flux of entries/exits"
type FluxEvent {
	
	"Block where the event happens"
	block: Block!
	
	"Value of the flux at the event"
	value: Float!
} #FluxEvent

"A parameter of the money"
type Parameter {
	
	name: ParameterName!
	
	par_type: ParameterType!
	
	value: Number!
	
	comment: String
	
} #Parameter

enum ParameterType {
	INTEGER
	FLOAT
	DURATION
	DATE
} #ParameterType

enum ParameterName {
	
	"The relative growth of the UD every [dtReeval] period"
	c
	
	"Time period between two UD"
	dt
	
	"UD(0), i.e. initial Universal Dividend"
	ud0
	
	"Minimum delay between two certifications of a same issuer"
	sigPeriod
	
	"Maximum quantity of active certifications made by member"
	sigStock
	
	"Maximum delay a certification can wait before being expired for non-writing"
	sigWindow
	
	"Maximum age of an active certification"
	sigValidity
	
	"Minimum delay before replaying a certification"
	sigReplay
	
	"Minimum quantity of signatures to be part of the WoT"
	sigQty
	
	"Maximum delay an identity can wait before being expired for non-writing"
	idtyWindow
	
	"Maximum delay a membership can wait before being expired for non-writing"
	msWindow
	
	"Minimum delay between 2 memberships of a same issuer"
	msPeriod
	
	"Minimum percent of sentries to reach to match the distance rule"
	xpercent
	
	"Maximum age of an active membership"
	msValidity
	
	"Maximum distance between a WOT member and [xpercent] of sentries"
	stepMax
	
	"Number of blocks used for calculating median time"
	medianTimeBlocks
	
	"The average time for writing 1 block (wished time)"
	avgGenTime
	
	"The number of blocks required to evaluate again PoWMin value"
	dtDiffEval
	
	"The proportion of calculating members not excluded from the proof of work"
	percentRot
	
	"Time of first UD"
	udTime0
	
	"Time of first reevaluation of the UD"
	udReevalTime0
	
	"Time period between two re-evaluation of the UD"
	dtReeval
	
	"Maximum delay a transaction can wait before being expired for non-writing"
	txWindow

} #ParameterName

"Fraction"
type Fraction {
	
	"Numerator"
	num: Int!
	
	"Denominator"
	denom: Int!
	
	"Value of 'num' / 'denom'"
	ratio: Float!

} #fraction

"64 bits signed integer"
scalar Int64

"Avatar of String"
scalar Hash

"Avatar of String"
scalar Pubkey

"Empty result"
scalar Void

"Int, Int64 or Float"
scalar Number
1 « J'aime »

Il n’est pas nécessaire avec GraphQL de faire une documentation. L’api dispose d’un mode d’introspection qui permet de requêter le schema complet.

Voici un guide en anglais :

Mais attention, si vous voulez une API sécurisée, il est déconseillé de laisser l’introspection activée :

Mouais… C’est encore tenter d’assurer la sécurité par l’opacité. On sait que ça ne marche pas.

1 « J'aime »

Il s’agit juste d’exemples pour commencer, je suis sûr que ça peut aider certaines personnes comme @hypericum et @paidge.

Je sais bien, et ça devrait permettre d’avoir le typesystem et l’autocomplétion directement dans le playground, mais il nous manque un tout petit bout avant que ce soit fonctionnel, si tu veux proposer les corrections nécessaires dans wotwizard, n’hésites pas.

Pour info, les deux premiers liens donnés pour l’API affiche une erreur 502 Bad Gateway.
Le troisième un playground avec une erreur (il semble ne pas pouvoir afficher le schéma et donc la documentation).

Je ne peux pas aider en golang ni en vieux pascal. Désolé.

On dirait que vous avez copié-collé une lib GraphQL. Peut-être utiliser un framework clef en main ?
Sinon je vous met ce lien pour info et je retourne à mon python :wink: :

Hope it heps !

Je pense que @gerard94 doit être en train de faire une mise à jour sur wotwizard, ce qui expliquerait l’indisponibilité. Il faut revenir à un autre moment, désolé :slight_smile:

1 « J'aime »

Oui, j’ai des problèmes. Il y a un fork, et je suis en train de récupérer les morceaux. C’est long !!!

1 « J'aime »

Salut,

Est-ce qu’on trouve quelque part quelque chose pour expliquer la syntaxe, qui semble hiérarchiser les différents paramètres de la requête?

J’ai essayé de remplacer des valeurs en bidouillant (mais pas en prenant énormément de temps non plus): je n’ai que des messages d’erreur.

Pour comprendre le typesystem je bidouille, mais la bidouille ne marche même pas.
Je ne comprends pas toujours très bien les commentaires non plus, et comment il faut syntaxer tout ça.

Je vais rtfmiser demain, il y a quelques trucs à lire que j’ai pas lus.

Syntaxe en EBNF3 : Il s’agit de la version graphQL de juin 2018, ce qui correspond à la version actuelle de WotWizard.
Sinon, pour des explications supplémentaires, c’est ici.

1 « J'aime »