capacity-attest 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/eas.d.ts CHANGED
@@ -4,10 +4,44 @@ import { verifyClaim } from "./signing.js";
4
4
  import type { ClaimSource } from "./discovery.js";
5
5
  export declare const EAS_ADDRESS = "0x4200000000000000000000000000000000000021";
6
6
  export declare const SCHEMA_REGISTRY_ADDRESS = "0x4200000000000000000000000000000000000020";
7
- export declare const EAS_EXPLORER: {
8
- readonly 8453: "https://base.easscan.org";
9
- readonly 84532: "https://base-sepolia.easscan.org";
10
- };
7
+ /** One chain's EAS deployment: both contract addresses, plus a human-facing explorer base URL. */
8
+ export interface EasDeployment {
9
+ chainId: number;
10
+ name: string;
11
+ easAddress: string;
12
+ schemaRegistryAddress: string;
13
+ explorer: string;
14
+ }
15
+ /**
16
+ * Known EAS deployments, keyed by chainId. Every address was independently
17
+ * verified (EAS's own deployment records AND a live eth_getCode call)
18
+ * before being added here -- the OP-Stack-predeploy pattern is CONFIRMED
19
+ * true for Optimism specifically below, never applied to a new chain just
20
+ * because it sounds plausible.
21
+ */
22
+ export declare const EAS_DEPLOYMENTS: Record<number, EasDeployment>;
23
+ /** Backward-compatible: existing callers (examples/eas-live-demo.ts) look up an explorer URL by chainId this way. Derived FROM EAS_DEPLOYMENTS so there is exactly one source of truth, not two tables that could quietly drift apart. */
24
+ export declare const EAS_EXPLORER: Record<number, string>;
25
+ interface AttestRequest {
26
+ schema: string;
27
+ data: {
28
+ recipient: string;
29
+ expirationTime: bigint;
30
+ revocable: boolean;
31
+ refUID: string;
32
+ data: string;
33
+ value: bigint;
34
+ };
35
+ }
36
+ interface EasWriteContract {
37
+ attest(request: AttestRequest): Promise<ethers.ContractTransactionResponse>;
38
+ }
39
+ interface SchemaRegistryContract {
40
+ getSchema(uid: string): Promise<{
41
+ uid: string;
42
+ }>;
43
+ register(schema: string, resolver: string, revocable: boolean): Promise<ethers.ContractTransactionResponse>;
44
+ }
11
45
  export declare const SCHEMA_STRING = "bytes32 claimId,string claim";
12
46
  /** Deterministic schema UID: keccak256(abi.encodePacked(schema, resolver, revocable)). */
13
47
  export declare function computeSchemaUID(schema?: string, resolver?: string, revocable?: boolean): string;
@@ -22,18 +56,36 @@ export declare function encodeClaimData(claim: DeliveryClaim): string;
22
56
  * own claimId, so a mismatch is dropped here as malformed.
23
57
  */
24
58
  export declare function decodeClaimData(data: string): DeliveryClaim | null;
59
+ /**
60
+ * Builds the SchemaRegistry write contract. Split out as an injection seam
61
+ * (same DI pattern as erc8004.ts's ContractFactory and this file's own
62
+ * AttestationReader below) so ensureSchema's CHAIN-TARGETING logic --
63
+ * "does it use the address I told it to, for a chain that is not Base" --
64
+ * is unit-testable without a live signer or network, not just assumed.
65
+ */
66
+ export type SchemaRegistryContractFactory = (schemaRegistryAddress: string, signer: ethers.Signer) => SchemaRegistryContract;
25
67
  /**
26
68
  * Register our schema if it does not already exist on this chain. The schema
27
69
  * UID is deterministic, so a duplicate register() reverts with AlreadyExists;
28
70
  * we check first via getSchema and only register when absent. Requires a
29
71
  * funded signer. Returns the schema UID.
72
+ *
73
+ * `opts.schemaRegistryAddress` defaults to SCHEMA_REGISTRY_ADDRESS (Base's,
74
+ * unchanged from before this function took an opts argument at all): pass
75
+ * `EAS_DEPLOYMENTS[1].schemaRegistryAddress` for Ethereum mainnet, or any
76
+ * other chain's own address, to target that chain instead.
30
77
  */
31
- export declare function ensureSchema(signer: ethers.Signer): Promise<string>;
78
+ export declare function ensureSchema(signer: ethers.Signer, opts?: {
79
+ schemaRegistryAddress?: string;
80
+ contractFactory?: SchemaRegistryContractFactory;
81
+ }): Promise<string>;
32
82
  export interface PublishResult {
33
83
  uid: string;
34
84
  txHash: string;
35
85
  recipient: string;
36
86
  }
87
+ /** Same injection-seam purpose as SchemaRegistryContractFactory above, for the EAS write contract itself. */
88
+ export type EasWriteContractFactory = (easAddress: string, signer: ethers.Signer) => EasWriteContract;
37
89
  /**
38
90
  * Publish one claim to EAS as an attestation with recipient = sellerAddress, so
39
91
  * it is discoverable by that seller. `signer` only pays gas and writes the
@@ -43,8 +95,16 @@ export interface PublishResult {
43
95
  * (easSource, discoverDeliveryHistory) ever looks at who published the
44
96
  * attestation, only at what the claim itself proves. Requires a funded signer.
45
97
  * Returns the new attestation UID and tx hash.
98
+ *
99
+ * `opts.easAddress` defaults to EAS_ADDRESS (Base's, unchanged from before
100
+ * this function took an opts argument at all): pass
101
+ * `EAS_DEPLOYMENTS[1].easAddress` for Ethereum mainnet, or any other
102
+ * chain's own address, to target that chain instead.
46
103
  */
47
- export declare function publishClaim(signer: ethers.Signer, claim: DeliveryClaim): Promise<PublishResult>;
104
+ export declare function publishClaim(signer: ethers.Signer, claim: DeliveryClaim, opts?: {
105
+ easAddress?: string;
106
+ contractFactory?: EasWriteContractFactory;
107
+ }): Promise<PublishResult>;
48
108
  /**
49
109
  * The minimal on-chain read surface easSource needs. Split out as an injection
50
110
  * seam so the decode/aggregation path is unit-testable without a live chain
@@ -56,11 +116,30 @@ export interface AttestationReader {
56
116
  uidsForSeller(sellerAddress: string): Promise<string[]>;
57
117
  /** The raw ABI-encoded `data` field of one attestation. */
58
118
  dataForUid(uid: string): Promise<string>;
119
+ /** Max concurrent dataForUid calls easSource should keep in flight. Readers that do not set this get DEFAULT_CONCURRENCY. */
120
+ concurrency?: number;
59
121
  }
60
- /** Build a real AttestationReader over a JSON-RPC endpoint (getLogs + getAttestation). */
122
+ /**
123
+ * Pure block-range windowing, split out so the chunking math is unit-testable
124
+ * without a real or mocked RPC provider. [fromBlock, latest] inclusive,
125
+ * chunked into <= blockRange-wide, non-overlapping, gap-free windows in
126
+ * ascending order. Returns [] when fromBlock > latest (nothing to scan).
127
+ */
128
+ export declare function blockWindows(fromBlock: number, latest: number, blockRange: number): Array<[number, number]>;
129
+ /**
130
+ * Build a real AttestationReader over a JSON-RPC endpoint (getLogs +
131
+ * getAttestation). `opts.easAddress` defaults to EAS_ADDRESS (Base's,
132
+ * unchanged from before WP2): pass `EAS_DEPLOYMENTS[1].easAddress` for
133
+ * Ethereum mainnet, or any other chain's own address, to read that chain
134
+ * instead. rpcUrl itself already told this function which CHAIN to talk to;
135
+ * easAddress tells it WHERE on that chain the EAS contract lives.
136
+ */
61
137
  export declare function rpcAttestationReader(rpcUrl: string, opts?: {
62
138
  fromBlock?: number;
63
139
  schemaUID?: string;
140
+ blockRange?: number;
141
+ concurrency?: number;
142
+ easAddress?: string;
64
143
  }): AttestationReader;
65
144
  /**
66
145
  * An untrusted ClaimSource backed by EAS. fetchForSeller reads the seller's
@@ -76,6 +155,9 @@ export declare function easSourceFromRpc(rpcUrl: string, opts?: {
76
155
  fromBlock?: number;
77
156
  schemaUID?: string;
78
157
  name?: string;
158
+ blockRange?: number;
159
+ concurrency?: number;
160
+ easAddress?: string;
79
161
  }): ClaimSource;
80
162
  export { verifyClaim };
81
163
  //# sourceMappingURL=eas.d.ts.map
package/dist/eas.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"eas.d.ts","sourceRoot":"","sources":["../src/eas.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,eAAO,MAAM,WAAW,+CAA+C,CAAC;AACxE,eAAO,MAAM,uBAAuB,+CAA+C,CAAC;AAEpF,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAqCX,eAAO,MAAM,aAAa,iCAAiC,CAAC;AAG5D,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,MAAM,SAAgB,EAAE,QAAQ,SAAqB,EAAE,SAAS,UAAmB,GAAG,MAAM,CAE5H;AAED,eAAO,MAAM,UAAU,QAAqB,CAAC;AAI7C,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAE5D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAgBlE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUzE;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CA6BtG;AAMD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxD,2DAA2D;IAC3D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,iBAAiB,CAqB7H;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,SAAQ,GAAG,WAAW,CAmB9E;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,CAElI;AAID,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"eas.d.ts","sourceRoot":"","sources":["../src/eas.ts"],"names":[],"mappings":"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"}
package/dist/eas.js CHANGED
@@ -1,27 +1,57 @@
1
1
  // eas.ts — publish a delivery claim to, and discover it from, the Ethereum
2
- // Attestation Service (EAS) on Base. This is the concrete, host-independent
2
+ // Attestation Service (EAS). This is the concrete, host-independent
3
3
  // substrate D-005/D-012 pointed at: a public chain anyone can read, so a buyer
4
4
  // on one installation can find a claim another buyer published, and verify it
5
5
  // locally (discovery.ts re-verifies every claim, so EAS is just an untrusted
6
6
  // ClaimSource like any other).
7
7
  //
8
- // Plain ethers only, no eas-sdk dependency. EAS is an OP-Stack predeploy, so
9
- // the contract addresses are identical on Base mainnet (8453) and Base Sepolia
10
- // (84532). Everything here is caller-parameterised (rpcUrl, signer): this
8
+ // Originally wired to Base only. Generalized here (WP2, see
9
+ // docs/NLNET-SELFBUILD-PLAN-2026-09-28.md) to support any EAS deployment:
10
+ // discovery.ts's own header comment always described the substrate as "EAS
11
+ // on Base", not "EAS, forever only Base". Optimism and Ethereum mainnet are
12
+ // equally real EAS deployments, just with different contract addresses:
13
+ // Optimism, being an OP-Stack chain like Base, happens to share Base's exact
14
+ // predeploy addresses; Ethereum mainnet does not, since it is the underlying
15
+ // L1, not an OP-Stack chain. That distinction was verified, not assumed --
16
+ // see EAS_DEPLOYMENTS below.
17
+ //
18
+ // Plain ethers only, no eas-sdk dependency. Everything here is
19
+ // caller-parameterised (rpcUrl, signer, and now chain addresses too): this
11
20
  // package never bundles an RPC, a key, or gas, and never becomes the index.
12
21
  //
13
- // Verified against the EAS contract sources (IEAS.sol, Common.sol,
14
- // SchemaRegistry.sol) and the base / base-sepolia deployment artifacts, 2026-09-06.
22
+ // Base's addresses verified against the EAS contract sources (IEAS.sol,
23
+ // Common.sol, SchemaRegistry.sol) and the base / base-sepolia deployment
24
+ // artifacts, 2026-09-06. Optimism and Ethereum mainnet addresses verified
25
+ // 2026-09-28 against EAS's own official deployment records
26
+ // (github.com/ethereum-attestation-service/eas-contracts, the
27
+ // deployments/optimism and deployments/mainnet JSON files, cross-checked
28
+ // against docs.attest.org's own contracts table) AND independently
29
+ // re-confirmed with a direct eth_getCode call against each chain's real,
30
+ // live RPC: real bytecode present at every address below, not just "found
31
+ // in a document".
15
32
  import { ethers } from "ethers";
16
33
  import { DeliveryClaimSchema } from "./schema.js";
17
34
  import { verifyClaim } from "./signing.js";
18
- // OP-Stack predeploys: same on every Base network.
35
+ // OP-Stack predeploys: identical on every OP-Stack chain (Base, Optimism).
36
+ // Kept as the module-level default for every function below, so a caller who
37
+ // passes nothing still gets exactly today's, unchanged, Base behavior.
19
38
  export const EAS_ADDRESS = "0x4200000000000000000000000000000000000021";
20
39
  export const SCHEMA_REGISTRY_ADDRESS = "0x4200000000000000000000000000000000000020";
21
- export const EAS_EXPLORER = {
22
- 8453: "https://base.easscan.org",
23
- 84532: "https://base-sepolia.easscan.org",
40
+ /**
41
+ * Known EAS deployments, keyed by chainId. Every address was independently
42
+ * verified (EAS's own deployment records AND a live eth_getCode call)
43
+ * before being added here -- the OP-Stack-predeploy pattern is CONFIRMED
44
+ * true for Optimism specifically below, never applied to a new chain just
45
+ * because it sounds plausible.
46
+ */
47
+ export const EAS_DEPLOYMENTS = {
48
+ 8453: { chainId: 8453, name: "Base", easAddress: EAS_ADDRESS, schemaRegistryAddress: SCHEMA_REGISTRY_ADDRESS, explorer: "https://base.easscan.org" },
49
+ 84532: { chainId: 84532, name: "Base Sepolia", easAddress: EAS_ADDRESS, schemaRegistryAddress: SCHEMA_REGISTRY_ADDRESS, explorer: "https://base-sepolia.easscan.org" },
50
+ 10: { chainId: 10, name: "Optimism", easAddress: EAS_ADDRESS, schemaRegistryAddress: SCHEMA_REGISTRY_ADDRESS, explorer: "https://optimism.easscan.org" },
51
+ 1: { chainId: 1, name: "Ethereum", easAddress: "0xA1207F3BBa224E2c9c3c6D5aF63D0eb1582Ce587", schemaRegistryAddress: "0xA7b39296258348C78294F95B872b282326A97BDF", explorer: "https://easscan.org" },
24
52
  };
53
+ /** Backward-compatible: existing callers (examples/eas-live-demo.ts) look up an explorer URL by chainId this way. Derived FROM EAS_DEPLOYMENTS so there is exactly one source of truth, not two tables that could quietly drift apart. */
54
+ export const EAS_EXPLORER = Object.fromEntries(Object.entries(EAS_DEPLOYMENTS).map(([chainId, d]) => [chainId, d.explorer]));
25
55
  const EAS_ABI = [
26
56
  "function attest((bytes32 schema,(address recipient,uint64 expirationTime,bool revocable,bytes32 refUID,bytes data,uint256 value) data) request) payable returns (bytes32)",
27
57
  "function getAttestation(bytes32 uid) view returns ((bytes32 uid,bytes32 schema,uint64 time,uint64 expirationTime,uint64 revocationTime,bytes32 refUID,address recipient,address attester,bool revocable,bytes data))",
@@ -75,14 +105,22 @@ export function decodeClaimData(data) {
75
105
  return null;
76
106
  return parsed;
77
107
  }
108
+ const defaultSchemaRegistryContractFactory = (schemaRegistryAddress, signer) => new ethers.Contract(schemaRegistryAddress, SCHEMA_REGISTRY_ABI, signer);
78
109
  /**
79
110
  * Register our schema if it does not already exist on this chain. The schema
80
111
  * UID is deterministic, so a duplicate register() reverts with AlreadyExists;
81
112
  * we check first via getSchema and only register when absent. Requires a
82
113
  * funded signer. Returns the schema UID.
114
+ *
115
+ * `opts.schemaRegistryAddress` defaults to SCHEMA_REGISTRY_ADDRESS (Base's,
116
+ * unchanged from before this function took an opts argument at all): pass
117
+ * `EAS_DEPLOYMENTS[1].schemaRegistryAddress` for Ethereum mainnet, or any
118
+ * other chain's own address, to target that chain instead.
83
119
  */
84
- export async function ensureSchema(signer) {
85
- const registry = new ethers.Contract(SCHEMA_REGISTRY_ADDRESS, SCHEMA_REGISTRY_ABI, signer);
120
+ export async function ensureSchema(signer, opts = {}) {
121
+ const schemaRegistryAddress = opts.schemaRegistryAddress ?? SCHEMA_REGISTRY_ADDRESS;
122
+ const contractFactory = opts.contractFactory ?? defaultSchemaRegistryContractFactory;
123
+ const registry = contractFactory(schemaRegistryAddress, signer);
86
124
  const existing = await registry.getSchema(SCHEMA_UID);
87
125
  // getSchema returns a zero-uid struct when the schema is not registered.
88
126
  if (existing && existing.uid && existing.uid.toLowerCase() === SCHEMA_UID.toLowerCase()) {
@@ -92,6 +130,7 @@ export async function ensureSchema(signer) {
92
130
  await tx.wait();
93
131
  return SCHEMA_UID;
94
132
  }
133
+ const defaultEasWriteContractFactory = (easAddress, signer) => new ethers.Contract(easAddress, EAS_ABI, signer);
95
134
  /**
96
135
  * Publish one claim to EAS as an attestation with recipient = sellerAddress, so
97
136
  * it is discoverable by that seller. `signer` only pays gas and writes the
@@ -101,9 +140,16 @@ export async function ensureSchema(signer) {
101
140
  * (easSource, discoverDeliveryHistory) ever looks at who published the
102
141
  * attestation, only at what the claim itself proves. Requires a funded signer.
103
142
  * Returns the new attestation UID and tx hash.
143
+ *
144
+ * `opts.easAddress` defaults to EAS_ADDRESS (Base's, unchanged from before
145
+ * this function took an opts argument at all): pass
146
+ * `EAS_DEPLOYMENTS[1].easAddress` for Ethereum mainnet, or any other
147
+ * chain's own address, to target that chain instead.
104
148
  */
105
- export async function publishClaim(signer, claim) {
106
- const eas = new ethers.Contract(EAS_ADDRESS, EAS_ABI, signer);
149
+ export async function publishClaim(signer, claim, opts = {}) {
150
+ const easAddress = opts.easAddress ?? EAS_ADDRESS;
151
+ const contractFactory = opts.contractFactory ?? defaultEasWriteContractFactory;
152
+ const eas = contractFactory(easAddress, signer);
107
153
  const tx = await eas.attest({
108
154
  schema: SCHEMA_UID,
109
155
  data: {
@@ -134,27 +180,83 @@ export async function publishClaim(signer, claim) {
134
180
  }
135
181
  return { uid, txHash: receipt.hash, recipient: claim.sellerAddress };
136
182
  }
137
- /** Build a real AttestationReader over a JSON-RPC endpoint (getLogs + getAttestation). */
183
+ // Most public RPC providers cap a single eth_getLogs call to a bounded block
184
+ // range (2,000-10,000 blocks is typical; some reject an unbounded fromBlock=0
185
+ // outright). A single call from genesis to "latest" therefore either errors
186
+ // out or silently degrades depending on the provider, and degrades further as
187
+ // the chain ages and the range grows. Default window chosen conservatively
188
+ // below the tightest commonly-seen provider limit; callers on a more
189
+ // permissive RPC can raise it via opts.blockRange.
190
+ const DEFAULT_BLOCK_RANGE = 2_000;
191
+ // Bound how many attestation bodies rpcAttestationReader fetches CONCURRENTLY
192
+ // per uidsForSeller/dataForUid fan-out. discoverDeliveryHistory's own
193
+ // MAX_CLAIMS_PER_SOURCE bounds how many claims are ultimately ACCEPTED from a
194
+ // source; this bounds how many in-flight RPC requests a single source's read
195
+ // can open at once, so a seller with many attestations does not open
196
+ // thousands of simultaneous connections against the RPC endpoint.
197
+ const DEFAULT_CONCURRENCY = 10;
198
+ /**
199
+ * Pure block-range windowing, split out so the chunking math is unit-testable
200
+ * without a real or mocked RPC provider. [fromBlock, latest] inclusive,
201
+ * chunked into <= blockRange-wide, non-overlapping, gap-free windows in
202
+ * ascending order. Returns [] when fromBlock > latest (nothing to scan).
203
+ */
204
+ export function blockWindows(fromBlock, latest, blockRange) {
205
+ if (blockRange < 1)
206
+ throw new Error(`blockRange must be >= 1, got ${blockRange}`);
207
+ const windows = [];
208
+ for (let from = fromBlock; from <= latest; from += blockRange) {
209
+ windows.push([from, Math.min(from + blockRange - 1, latest)]);
210
+ }
211
+ return windows;
212
+ }
213
+ /**
214
+ * Build a real AttestationReader over a JSON-RPC endpoint (getLogs +
215
+ * getAttestation). `opts.easAddress` defaults to EAS_ADDRESS (Base's,
216
+ * unchanged from before WP2): pass `EAS_DEPLOYMENTS[1].easAddress` for
217
+ * Ethereum mainnet, or any other chain's own address, to read that chain
218
+ * instead. rpcUrl itself already told this function which CHAIN to talk to;
219
+ * easAddress tells it WHERE on that chain the EAS contract lives.
220
+ */
138
221
  export function rpcAttestationReader(rpcUrl, opts = {}) {
139
222
  const provider = new ethers.JsonRpcProvider(rpcUrl);
140
- const eas = new ethers.Contract(EAS_ADDRESS, EAS_ABI, provider);
223
+ const easAddress = opts.easAddress ?? EAS_ADDRESS;
224
+ const eas = new ethers.Contract(easAddress, EAS_ABI, provider);
141
225
  const schemaUID = opts.schemaUID ?? SCHEMA_UID;
142
226
  const attestedTopic0 = ethers.id("Attested(address,address,bytes32,bytes32)");
227
+ const blockRange = opts.blockRange ?? DEFAULT_BLOCK_RANGE;
228
+ const concurrency = opts.concurrency ?? DEFAULT_CONCURRENCY;
143
229
  return {
144
230
  uidsForSeller: async (sellerAddress) => {
145
- const logs = await provider.getLogs({
146
- address: EAS_ADDRESS,
147
- topics: [attestedTopic0, ethers.zeroPadValue(sellerAddress, 32), null, schemaUID],
148
- fromBlock: opts.fromBlock ?? 0,
149
- toBlock: "latest",
150
- });
151
- // uid is the only non-indexed value: it sits in log.data.
152
- return logs.map((l) => l.data);
231
+ const latest = await provider.getBlockNumber();
232
+ const windows = blockWindows(opts.fromBlock ?? 0, latest, blockRange);
233
+ const uids = [];
234
+ // Walk the chain in bounded windows instead of one fromBlock=0..latest
235
+ // call. A window that itself errors (provider-side limit stricter than
236
+ // blockRange) is not swallowed here: it propagates, same as today's
237
+ // single-call behaviour, so a caller who needs resilience against a
238
+ // flaky/stricter provider passes a smaller blockRange, not a silent
239
+ // partial result.
240
+ for (const [from, to] of windows) {
241
+ const logs = await provider.getLogs({
242
+ address: easAddress,
243
+ topics: [attestedTopic0, ethers.zeroPadValue(sellerAddress, 32), null, schemaUID],
244
+ fromBlock: from,
245
+ toBlock: to,
246
+ });
247
+ // uid is the only non-indexed value: it sits in log.data.
248
+ for (const l of logs)
249
+ uids.push(l.data);
250
+ }
251
+ return uids;
153
252
  },
154
253
  dataForUid: async (uid) => {
155
254
  const att = await eas.getAttestation(uid);
156
255
  return att.data;
157
256
  },
257
+ // Exposed so easSource's fan-out can bound concurrency without
258
+ // hardcoding a number that belongs to the reader's own configuration.
259
+ concurrency,
158
260
  };
159
261
  }
160
262
  /**
@@ -170,19 +272,34 @@ export function easSource(reader, name = "eas") {
170
272
  name,
171
273
  fetchForSeller: async (sellerAddress) => {
172
274
  const uids = await reader.uidsForSeller(sellerAddress);
275
+ const concurrency = Math.max(1, reader.concurrency ?? DEFAULT_CONCURRENCY);
173
276
  const claims = [];
174
- for (const uid of uids) {
175
- let data;
176
- try {
177
- data = await reader.dataForUid(uid);
178
- }
179
- catch {
180
- continue; // unreadable attestation, skip
277
+ // Bounded-concurrency fan-out: at most `concurrency` dataForUid calls
278
+ // in flight at once, instead of either one-at-a-time (slow for a
279
+ // seller with many attestations) or fully unbounded (many simultaneous
280
+ // requests against one RPC endpoint). Order of `claims` does not need
281
+ // to match `uids`; discoverDeliveryHistory sorts the final aggregate by
282
+ // timestamp regardless of source order.
283
+ let next = 0;
284
+ async function worker() {
285
+ for (;;) {
286
+ const i = next++;
287
+ if (i >= uids.length)
288
+ return;
289
+ const uid = uids[i];
290
+ let data;
291
+ try {
292
+ data = await reader.dataForUid(uid);
293
+ }
294
+ catch {
295
+ continue; // unreadable attestation, skip
296
+ }
297
+ const claim = decodeClaimData(data);
298
+ if (claim)
299
+ claims.push(claim);
181
300
  }
182
- const claim = decodeClaimData(data);
183
- if (claim)
184
- claims.push(claim);
185
301
  }
302
+ await Promise.all(Array.from({ length: Math.min(concurrency, uids.length) }, worker));
186
303
  return claims;
187
304
  },
188
305
  };
package/dist/eas.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"eas.js","sourceRoot":"","sources":["../src/eas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eas.js","sourceRoot":"","sources":["../src/eas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=http-source.bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-source.bench.d.ts","sourceRoot":"","sources":["../src/http-source.bench.ts"],"names":[],"mappings":""}
@@ -0,0 +1,65 @@
1
+ // http-source.bench.ts — quantifies two things for the new httpClaimSource
2
+ // (WP1's second, non-EAS production-grade source):
3
+ // 1. Real end-to-end throughput through discoverDeliveryHistory at volume,
4
+ // the same question discovery.bench.ts already answers for the
5
+ // aggregation layer itself. (eas.bench.ts answers a narrower, different
6
+ // question: it benchmarks easSource.fetchForSeller() in isolation, at a
7
+ // fixed small volume, to compare concurrency=1 vs 10 vs 25 -- the PR
8
+ // #15 fan-out fix -- not throughput through discoverDeliveryHistory.)
9
+ // 2. Whether the byte-bounded streaming read (readBounded, the defense
10
+ // against an oversized/hostile response) costs anything meaningful
11
+ // compared to a naive "buffer everything, then check the size"
12
+ // implementation. readBounded is module-private, so this compares two
13
+ // full fetchForSeller() calls with IDENTICAL post-read work (JSON.parse
14
+ // included in both arms) and only the read strategy itself differing --
15
+ // an earlier version of this benchmark compared readBounded's full
16
+ // fetchForSeller() against a bare response.text() with no JSON.parse,
17
+ // which bundled parse cost into only one arm and overstated the
18
+ // streaming mechanism's true overhead.
19
+ // Run with: npx vitest bench src/http-source.bench.ts
20
+ import { bench, describe } from "vitest";
21
+ import { httpClaimSource } from "./http-source.js";
22
+ import { discoverDeliveryHistory } from "./discovery.js";
23
+ import { generateClaims, BENCH_SELLER } from "./bench-helpers.js";
24
+ const CLAIM_COUNT = 1_000;
25
+ const claims = await generateClaims(CLAIM_COUNT);
26
+ const body = JSON.stringify(claims);
27
+ function fixedResponseFetch() {
28
+ return (async () => new Response(body, { status: 200 }));
29
+ }
30
+ describe(`discoverDeliveryHistory via httpClaimSource, ${CLAIM_COUNT} claims in one response`, () => {
31
+ bench("end to end (fetch + bounded read + JSON.parse + verify all)", async () => {
32
+ const source = httpClaimSource("https://example.invalid/claims", { fetchImpl: fixedResponseFetch() });
33
+ await discoverDeliveryHistory(BENCH_SELLER, [source]);
34
+ });
35
+ });
36
+ // A deliberately naive re-implementation of exactly what httpClaimSource does,
37
+ // EXCEPT the read step is `await response.text()` (buffer everything, then
38
+ // check the length) instead of readBounded's stream-and-cap-as-you-go. Same
39
+ // URL building, same JSON.parse, same Array.isArray check, same cast -- so
40
+ // the ONLY thing this isolates against the real httpClaimSource is the read
41
+ // strategy itself, not an unrelated extra JSON.parse.
42
+ async function naiveFetchForSeller(sellerAddress) {
43
+ const response = await (fixedResponseFetch())("https://example.invalid/claims", {});
44
+ const text = await response.text();
45
+ if (Buffer.byteLength(text, "utf-8") > body.length * 2)
46
+ throw new Error("too large");
47
+ const parsed = JSON.parse(text);
48
+ if (!Array.isArray(parsed))
49
+ throw new Error("not an array");
50
+ void sellerAddress;
51
+ return parsed;
52
+ }
53
+ describe(`read strategy only: readBounded (streams+caps) vs naive response.text()+length-check, same ${CLAIM_COUNT}-claim payload (${(body.length / 1024).toFixed(0)} KiB), identical JSON.parse in both arms`, () => {
54
+ bench("naive: response.text() then check length, then JSON.parse", async () => {
55
+ await naiveFetchForSeller(BENCH_SELLER);
56
+ });
57
+ bench("readBounded via httpClaimSource: stream + cap-as-you-go, then JSON.parse", async () => {
58
+ const source = httpClaimSource("https://example.invalid/claims", {
59
+ fetchImpl: fixedResponseFetch(),
60
+ maxResponseBytes: body.length * 2, // generous, so this measures the mechanism's overhead, not a refusal
61
+ });
62
+ await source.fetchForSeller(BENCH_SELLER);
63
+ });
64
+ });
65
+ //# sourceMappingURL=http-source.bench.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-source.bench.js","sourceRoot":"","sources":["../src/http-source.bench.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { ClaimSource } from "./discovery.js";
2
+ export declare class HttpSourceError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export interface HttpClaimSourceOptions {
6
+ name?: string;
7
+ /** Per-request timeout in ms. Independent of, and typically tighter than, discoverDeliveryHistory's own sourceTimeoutMs. */
8
+ timeoutMs?: number;
9
+ /** Refuse a response body larger than this many bytes, checked WHILE streaming, before JSON.parse ever runs. */
10
+ maxResponseBytes?: number;
11
+ /** Injection seam for tests: a fetch-shaped function. Defaults to the global fetch. */
12
+ fetchImpl?: typeof fetch;
13
+ }
14
+ /**
15
+ * A ClaimSource over a plain HTTP endpoint. GETs
16
+ * `${endpointUrl}?seller=<sellerAddress>` and expects a JSON array back.
17
+ * Deliberately does NO verification and NO per-entry shape checking itself
18
+ * (same division of responsibility as staticSource/easSource):
19
+ * discoverDeliveryHistory re-verifies every claim from every source
20
+ * uniformly. A malformed sellerAddress, a non-2xx status, a request that
21
+ * times out or fails at the network level, a body over the size cap, or a
22
+ * body that is not JSON or not a JSON array, all become a thrown
23
+ * HttpSourceError — which discoverDeliveryHistory's existing per-source
24
+ * try/catch already turns into a SourceReport.error, never a crash of the
25
+ * whole aggregation.
26
+ */
27
+ export declare function httpClaimSource(endpointUrl: string, opts?: HttpClaimSourceOptions): ClaimSource;
28
+ //# sourceMappingURL=http-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-source.d.ts","sourceRoot":"","sources":["../src/http-source.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AA8BD,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4HAA4H;IAC5H,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gHAAgH;IAChH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uFAAuF;IACvF,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AA4BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B,GAAG,WAAW,CAwDnG"}