@zkp2p/indexer-schema
v0.22.0
Published
ZKP2P Indexer GraphQL schema and TypeScript types
Keywords
Readme
@zkp2p/indexer-schema
Consumer-facing GraphQL domain schema and TypeScript types for the ZKP2P indexer. The package is generated from schema/domain.graphql; raw audit-event entities are available in the live indexer but are not exported here.
Install
pnpm add @zkp2p/indexer-schemaSource vs Published Package
This repository currently declares 0.22.0. Publishing is an autonomous OIDC workflow after the focused version PR is merged and tagged; merging a schema change alone does not update npm.
Before depending on a newly merged entity or field, compare both versions:
jq -r .version packages/indexer-schema/package.json
npm view @zkp2p/indexer-schema versionVersion 0.22.0 stabilizes the schema published as 0.22.0-rc.4. Do not assume the stable version or its reviewed documentation exists in the installed package until the trusted publish workflow completes.
Usage
import { schemaSDL } from "@zkp2p/indexer-schema";
import type {
DisputeProtectionIntent,
Deposit,
Intent,
QuoteCandidate,
} from "@zkp2p/indexer-schema/types";The raw SDL is also exported at @zkp2p/indexer-schema/schema.graphql.
Exported types
- Orders and quotes:
Deposit,DepositPaymentMethod,MethodCurrency,Intent,QuoteCandidate,OrderbookEntry,WhitelistEntry,ReferralFeeDistribution - Statistics and activity: taker, maker, manager, platform, global, deposit, price, profit, referral, and daily cursor entities
- Delegated rates:
RateManager,RateManagerRate,ManagerStats,ManagerAggregateStats,ManagerDailySnapshot - Stake custody:
TakerStakeState,StakeAccountState,ClaimAccountState,TakerStakeAuthorization,StakeLock,StakeActivity,StakeVaultConfig - V3 disputes:
DisputeProtectionIntent,DepositDisputeProtectionConfig,DisputeProtectionRiskWindow,DisputeProtectionPolicyState,IntentLifecycleHookState - V3 registry state:
OrchestratorRegistrationState - Payment binding:
PaymentIntentBinding - Whitelist policy:
AddressGroup,AddressGroupMember,DepositWhitelistPolicy,DepositWhitelistedAddress,DepositAllowedGroup
Transaction attribution
Version 0.20.0-rc.1 exposed canonical ERC-8021 attribution on deposit creation as well as every newly signaled V2, V2.1, V2.2, and V3 intent:
Deposit.attributionCodesandDeposit.attributionSourceidentify the client that created the seller's deposit.Intent.attributionCodespreserves all decoded attribution codes in calldata order.Intent.attributionSourceis the first code other than ZKP2P's Base builder code (bc_nbn6qkni), ornullwhen no client/referrer code is present.- Version
0.21.0-rc.0retains at most five ordered codes and decodes either direct calldata or the address-matched ERC-4337 user operation's ERC-7579 execution payload. - Missing, malformed, ambiguous, or unsupported suffixes fail closed to an empty code list and
nullsource.
These fields replace calldata parsing in analytics consumers. They do not change deposit or intent identity, lifecycle, amounts, payment method, or fulfillment semantics.
Intent guardian
Version 0.21.0-rc.1 adds Deposit.intentGuardian and QuoteCandidate.intentGuardian for the guardian selected when a deposit was created:
- Both fields are lowercase-normalized.
- Legacy V2 deposits use the zero address as the non-null guardian sentinel.
QuoteCandidate.intentGuardianis indexed for exact-equality and_infiltering with lowercase address values.
Orderbook gating service
Version 0.20.0 stabilizes the schema published and production-exercised as 0.20.0-rc.2, including OrderbookEntry.intentGatingService, projected from QuoteCandidate.intentGatingService:
- It is non-null. The zero address is the ungated sentinel, so "no gating service" never collapses with "value absent".
- It is lowercase-normalized, unlike its
QuoteCandidatesource, so consumers can compare addresses with exact equality. - A non-zero value means the deposit's intents must be authorized by that gating service, so consumers that cannot produce its signature should exclude the row.
Method-scoped dispute protection and liquidity aggregates
Version 0.22.0 stabilizes the schema published as 0.22.0-rc.4, synchronizing the consumer projection with the method-scoped dispute stack and removing the retired Peer Curator accounting surface:
QuoteCandidate.disputeProtectionOptedInandOrderbookEntry.disputeProtectionOptedInare hard-renamed todisputeProtectionOptedOut.- Dispute protection is default-on for payment methods with a nonzero active-policy risk window. Only an explicit active-policy
enabled: falserow is opted out; missing config andenabled: trueare not opted out. - Projection fan-out is gated to the configured active policy. Passive or predecessor policy events retain raw/config rows without changing quote or orderbook admission.
- Staging and production now bind the dedicated-vault method-scoped dispute stack from contracts #293-#295 (fresh
StakeVault), using@zkp2p/[email protected]. CurrencyLiquidityand its deduplicatedDepositCurrencyLiquiditycontributions aggregate immediately available token liquidity by fiat currency.TokenLiquidityand its deduplicatedDepositTokenLiquiditycontributions aggregate immediately available liquidity by deposited token.CurrencyPlatformLiquidityand its deduplicatedDepositCurrencyPlatformLiquiditycontributions aggregate immediately available token liquidity by fiat currency and payment platform.MakerPeerPayStatsis removed.MakerPlatformStats.totalAmountTakenPreEarnCutoveris removed.- Generic
AddressGroupand method-scoped whitelist-policy entities remain supported for the Peer Pay merchant group.
Version 0.22.0-rc.2 scopes whitelist-group admission and dispute-protection opt-in to a deposit/payment-method tuple:
DepositWhitelistPolicy,DepositAllowedGroup, andDepositDisputeProtectionConfigIDs now includepaymentMethodHash.DepositWhitelistPolicy.paymentMethodHash,DepositAllowedGroup.paymentMethodHash, andDepositDisputeProtectionConfig.paymentMethodHashare required.- Direct
DepositWhitelistedAddressrows remain deposit-wide and no longer expose the invalid tuple-policypolicyEntityId;whitelistedAddressCountis the deposit-wide count repeated on each method policy. - Only the matching payment-method rows in
QuoteCandidateandOrderbookEntryare refreshed by policy events.
Version 0.22.0-rc.1 made the dispute-admission projection a hard cut and added stable staking/dispute pagination fields. Its explicit opt-in semantics are superseded by 0.22.0-rc.3:
- The rc.1 fields represented explicit opt-in; rc.3 replaces them with the default-on
disputeProtectionOptedOutprojection described above. QuoteCandidate.disputeProtectionRequiresStakeandOrderbookEntry.disputeProtectionRequiresStakeare true only when the tuple is not opted out and has a nonzero active-policy risk window for the row's payment method.- Staging and production bind only their configured active policy and vault; retired deployments are not indexed.
DisputeProtectionIntent.disputedAtBlockNumberanddisputedAtLogIndexrecord the exactDisputeResolvedevent cursor and remain null before a dispute.- Stake and finalized-dispute records expose indexed fields for stable keyset pagination; page validation and query execution remain consumer responsibilities.
Missing DepositDisputeProtectionConfig rows are not opted out. An explicit active-policy enabled: false config records opt-out; enabled: true undoes it. Missing or zero payment-method risk windows do not require stake. The contracts remain authoritative for admission, collateral, maturity, attestation verification, and dispute settlement.
Merchant stake and dispute pagination
StakeLockpages require exactchainId,vaultAddress, andstakeOwnerfilters plus optional status. Advance the opaque keyset withid > afterIdandidascending.maturesAtremains a surfaced UI value, but it is mutable and therefore not the cursor.StakeActivitypages require exactchainIdandvaultAddress, merchant relevance(stakeOwner == merchant OR taker == merchant), and optional kind. Order(blockNumber, logIndex, id)ascending. After cursor(b, l, i), continue withblockNumber > b OR (blockNumber = b AND logIndex > l) OR (blockNumber = b AND logIndex = l AND id > i). StakeActivity cursor stability comes from immutable append-only event positions.- Finalized dispute pages require exact
chainId,status = DISPUTED, and the activepolicyAddress, with no merchant-address predicate. Order(disputedAtBlockNumber, disputedAtLogIndex, id)ascending. After cursor(b, l, i), continue withdisputedAtBlockNumber > b OR (disputedAtBlockNumber = b AND disputedAtLogIndex > l) OR (disputedAtBlockNumber = b AND disputedAtLogIndex = l AND id > i). The two event cursor fields are non-null for rows admitted by theDISPUTEDfilter even though they remain nullable before dispute. Finalized DISPUTED cursor stability comes from terminal rows and immutable dispute event positions.
These keysets guarantee strict forward progress; use no offset pagination. Page sizes 1..100 are validated by the clients SDK; the indexer schema does not enforce a page-size limit.
V3 dispute boundary
Version 0.19.0-rc.0 was the contracts PR #219 hard cut:
RiskManagerentities, enums, intent-extension projections, deferred settlement state, and risk-exposure aggregates are removed.DisputeProtectionIntentrecords thePENDING -> CANCELLED | SETTLED -> RELEASED | DISPUTEDlifecycle.DisputeProtectionRiskWindowrecords future-admission minimum holds per policy and payment method.DisputeProtectionPolicyStateis the current pause flag plus the normalized, sorted set of authorized lifecycle hooks for one Policy deployment.OrchestratorRegistrationStateis current Orchestrator membership in one registry deployment; removal overwrites the same row withregistered: false.IntentLifecycleHookStaterecords the hook snapshotted byOrchestratorV3.PaymentIntentBindingremains the canonical(chainId, registryAddress, nullifier) -> intentHashrelationship.
TakerStakeState.selectedStakeOwner preserves the emitted preference. selectionAuthorized and
stakeOwner are effective state: authorization makes the selection active, revocation immediately
falls back to the taker's own stake, and unrelated authorization updates do not rewrite the row.
These current-state, split dispute-projection, and cursor fields require a clean staging and production reindex. Do not deploy a consumer that treats a missing field as opt-out against an older database.
EscrowIntentPeriodState remains part of the V2.2 Escrow surface and is not a DisputeProtectionPolicy or RiskManager entity.
See the bundled docs/schema-field-reference.md and llms.txt for identity and field semantics.
Breaking-change detection
The indexer CI runs check-schema-breaking.cjs on every PR that touches schema/. It fails if any fields, types, or enum values are removed or have incompatible type changes unless the package advances to a later RC on the same unreleased line, or to the next minor after a stable release.
When making intentional breaking changes:
- Advance the RC while the release line is unstable; after stable, bump the minor version
- Update downstream consumers before merging
- Confirm the CI check reports the intentional version bump
Codegen Example
# codegen.yml
schema: node_modules/@zkp2p/indexer-schema/dist/schema.graphql
generates:
src/__generated__/types.ts:
plugins:
- typescript
- typescript-operationsDevelopment and release
From the repository root:
pnpm install --frozen-lockfile
pnpm build:schema
pnpm schema-package:build
pnpm --dir packages/indexer-schema verify:release
cd packages/indexer-schema && npm pack --dry-runPublishing is performed only by the protected GitHub Actions trusted-publishing workflow. It uses npm OIDC without a long-lived npm token and adds provenance whenever the source repository is public. See the release runbook.
