(merchantId, lenderId) is the active view, and the chain preserves the full history.
This is the per-order evidence schema. It powers the attestationCoveragePctBps field on /v2/merchant/orders — the fraction of credit-leg-bearing orders that have a corresponding Schema C attestation, in basis points.
| Schema name | RepaymentHistoryAttestation |
| EAS revocable | no — append-only |
| Expiry semantics | none |
| Issued by | A wallet currently ACTIVE in LenderRegistry |
| Subject | Merchant (subjectRootUid) |
| MCP tool | verify_repayment_history |
| Verifier API | GET /v2/attestations/repayment-history/:merchantId |
| Composite read | GET /v2/underwriting-signals/:merchantId |
Why append-only
Schema C is registered asrevocable: false on chain. Corrections are issued as a new attestation with updated counts; the chain preserves the full history; latest-by-attestedAt per (merchantId, lenderId) wins for read-time queries. The counters are monotonically non-decreasing — settledOnTimeCount, lateCount, defaultCount, totalLinesUsdCents all only ever go up.
Network & UIDs
| Network | EAS contract | Schema UID | Explorer |
|---|---|---|---|
| Base mainnet | 0x4200000000000000000000000000000000000021 | 0x090a64afc751696ba228f82225f084f73949644921e286108c86d3ea4d37f24c | basescan · easscan schema |
| Base Sepolia | 0x4200000000000000000000000000000000000021 | resolve via chain field on /v2/attestations/repayment-history/:merchantId | sepolia.basescan |
Field reference
ABI schema string:| Field | Solidity type | Semantic | Mutability |
|---|---|---|---|
subjectRootUid | string | Subject anchor. Production form: "merchant:<merchantId>". | immutable per attestation |
totalLinesUsdCents | uint64 | Running total credit drawn across the merchant-lender relationship. Monotonically non-decreasing. | snapshot — monotonic across the chain of attestations |
settledOnTimeCount | uint32 | Running count of settlement events that settled within term. Monotonically non-decreasing. | snapshot — monotonic |
lateCount | uint32 | Running count of settlements past expectedRepaymentDate but within the default cutoff (default 30d post-due). Monotonically non-decreasing. | snapshot — monotonic |
defaultCount | uint32 | Running count of credit lines that defaulted (>30d past due or written off). Monotonically non-decreasing. | snapshot — monotonic |
lastSettlementAt | uint256 | Unix seconds of the most recent settlement event captured by this row. Read consumers compute “freshest signal per lender” via MAX(lastSettlementAt). | snapshot |
| Envelope field | Type | Semantic |
|---|---|---|
uid | bytes32 | Attestation UID. |
schema | bytes32 | Schema UID (above). |
attester | address | Lender’s on-chain signing wallet. |
recipient | address | Conventionally merchant wallet or 0x0. |
time | uint64 | Block-mined attestedAt. |
expirationTime | uint64 | 0 (no expiry). |
revocationTime | uint64 | Always 0 — Schema C is non-revocable. |
revocable | bool | false. |
data | bytes | ABI-encoded payload per the schema string above. |
Order-level evidence — attestationCoveragePctBps
The merchant orders endpoint exposes a top-line coverage metric derived from Schema C:
9650 bps = 96.50% of credit-leg-bearing orders have a matching Schema C attestation (via orderId cross-reference). A drop in coverage means the lender’s settlement-event emitter is lagging or has stopped — it’s a freshness probe for the merchant’s underwriting signal stream.
Reading running totals: snapshot vs delta
A single Schema C row is a cumulative snapshot as oflastSettlementAt. To compute the delta added by the most recent settlement, fetch the previous attestation for the same (merchantId, lenderId) and subtract counters. The Droplinked API’s verify_repayment_history already does this aggregation:
Read via Droplinked API
Read via viem (TypeScript)
Read via ethers (TypeScript)
Read via Cast (Foundry)
Indexer access (EAS GraphQL)
- Base mainnet: https://base.easscan.org/graphql
- Base Sepolia: https://base-sepolia.easscan.org/graphql
orderId is part of the off-chain mirror, not the EAS payload. Use GET /v2/attestations/repayment-history/:merchantId and filter client-side on orderId, or use the Droplinked-side admin lineage endpoint.
Trust assumptions
A Schema C attestation is authoritative if and only if:- The on-chain
schemamatches the mainnet UID above. - The on-chain
attesterisACTIVEinLenderRegistry. revocable == false(sanity check — a Schema C row that claimsrevocable == trueis malformed).- Counters are monotonically non-decreasing relative to the prior attestation in the same
(merchantId, lenderId)chain. A row that decreases any counter is either malformed or a write-bug; do not honor it. The Droplinked-side issuer enforces this off-chain monotonic guard before mint.
Schema C does not have a
lenderCurrentStatus mirror (Schema C is append-only history, so a status flip on a lender doesn’t change a historical fact). To assess whether to consume a lender’s Schema C stream right now, consult GET /v2/lenders/:lenderId directly.