# Proof Explorer Data Schema + API Docs The proof explorer is a frontend that displays useful information about the Saturn proof aggregation contract. Here is a rough sketch of the information it should display: ![](https://hackmd.io/_uploads/SkcG0crfa.png) ## Information Flow 1. [The Graph Protocol](https://thegraph.com/docs/en/developing/creating-a-subgraph/) will dump contract data into a PostgresQL database. 2. The Graph Protocol also makes this database easily queryable via GraphQL, according to a schema we define in the [GraphQL Schema](#GraphQL-Schema) section. 3. Our custom `data-fetcher` TypeScript package wraps useful GraphQL queries. This package can then be used by the frontend. See [here](https://github.com/NebraZKP/Saturn/tree/main/data-fetcher) for an outdated example of a `data-fetcher` package. Preliminary API for the `data-fetcher` package in the [data-fetcher](#Data-Fetcher-API) section. ## GraphQL Schema Therefore, we also set our GraphQL schema this way. The `ProofData` entity consists of: 1. An `id` which is its `proofId` 2. `submitProofBlockTimestamp` is the timestamp of the block in which this proof was submitted to the `Saturn` contract. 3. `circuitId`. 4. `proofIdx` 5. `publicInputs` 6. `verifiedProofBlockTimestamp` is timestamp of block which this proof was verified OR null if it has not been verified. 7. `verifiedProofTxHash` is tx hash of proof verification tx OR null if proof has not been verified. ```graphql! type ProofData @entity { id: Bytes! # proofId submittedProofBlockTimestamp: BigInt! circuitId: Bytes! proofIdx: BigInt! publicInputs: [BigInt!] verifiedProofBlockTimestamp: BigInt verifiedProofTxHash: Bytes # txHash } type CircuitState @entity { id: Bytes! # circuitId lastVerifiedProofIdx: BigInt! } ``` ## Data Fetcher API ```typescript= // Used for getting data within a certain block timestamp range // Allows us to NOT reload all data on every query // Instead we query for all data since last queried timestamp enum SupportedNetwork { SEPOLIA = "sepolia", HARDHAT = "hardhat", } type TimestampOptions = { blockTimestamp?: Date; blockTimestampGte?: Date; blockTimestampLte?: Date; }; type ProofDataResponse = { id: string; submitProofBlockTimestamp: BigInt; circuitId: string; proofIdx: BigInt; publicInputs: BigInt[]; verifiedProofBlockTimestamp: BigInt | null; verifiedProofTxHash: string | null; }; type CircuitStateResponse = { id: string; lastVerifiedProofIdx: BigInt; }; /** * Returns CircuitState for a given circuitId. Useful for getting lastVerifiedProofIdx. * @param circuitId Circuit ID. Expected to be hex string. */ async getCircuitState(circuitId: string): Promise<CircuitStateResponse> /** * @param circuitId Circuit ID. Expected to be hex string. * @param lastVerifiedProofIdx Last verified proof index for the circuitId. * @param first Number of proofs to fetch (max 1000). * @param skip Number of proofs to skip (useful if need to query in batches) * @param options Options to select the pending proofs timetamp parameters. * @returns List of pending proofs by circuitId */ async getPendingProofsByCircuitId( circuitId: string, lastVerifiedProofIdx: BigInt, options: TimestampOptions = {}, first: number = 1000, skip: number = 0 ): Promise<ProofDataResponse[]> /** * @param circuitId Circuit ID. Expected to be hex string. * @param lastVerifiedProofIdx Last verified proof index for the circuitId. * @param first Number of proofs to fetch (max 1000). * @param skip Number of proofs to skip (useful if need to query in batches) * @param options Options to select the proofs timetamp parameters. * @returns List of rejected proofs by circuitId */ async getRejectedProofsByCircuitId( circuitId: string, lastVerifiedProofIdx: BigInt, options: TimestampOptions = {}, first: number = 1000, skip: number = 0 ): Promise<ProofDataResponse[]> /** * @param first Number of proofs to fetch (max 1000). * @param skip Number of proofs to skip (useful if need to query in batches) * @param options Options to select the proofs timetamp parameters. * @returns List of verified proofs */ async getVerifiedProofs( options: TimestampOptions = {}, first: number = 1000, skip: number = 0 ): Promise<ProofDataResponse[]> /** * @param proofId * @returns proof with a particular proofId */ async getProofByProofId(proofId: string): Promise<ProofDataResponse> /** * @param circuitId * @param first Number of proofs to fetch. * @param skip Number of proofs to skip (useful if need to query in batches) * @returns proofs with a particular circuitId */ async getProofsByCircuitId( circuitId: string, first: number = 1000, skip: number = 0 ): Promise<ProofDataResponse[]> ```