@ensnode/ponder-sdk 0.0.0-next-20260204111615
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/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/index.cjs +125 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +58 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 NameHash
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
PonderClient: () => PonderClient
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/deserialize/indexing-status.ts
|
|
28
|
+
var import_v43 = require("zod/v4");
|
|
29
|
+
|
|
30
|
+
// src/blocks.ts
|
|
31
|
+
var import_v42 = require("zod/v4");
|
|
32
|
+
|
|
33
|
+
// src/numbers.ts
|
|
34
|
+
var import_v4 = require("zod/v4");
|
|
35
|
+
var numberSchema = import_v4.z.number({ error: `Value must be a number` });
|
|
36
|
+
var integerSchema = numberSchema.int({ error: `Value must be an integer` });
|
|
37
|
+
var nonnegativeNumberSchema = numberSchema.nonnegative({
|
|
38
|
+
error: `Value must be non-negative`
|
|
39
|
+
});
|
|
40
|
+
var positiveNumberSchema = numberSchema.positive({ error: `Value must be positive` });
|
|
41
|
+
var nonnegativeIntegerSchema = integerSchema.nonnegative({
|
|
42
|
+
error: `Value must be a non-negative integer`
|
|
43
|
+
});
|
|
44
|
+
var positiveIntegerSchema = integerSchema.positive({
|
|
45
|
+
error: `Value must be a positive integer`
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// src/time.ts
|
|
49
|
+
var unixTimestampSchema = integerSchema;
|
|
50
|
+
|
|
51
|
+
// src/blocks.ts
|
|
52
|
+
var blockNumberSchema = nonnegativeIntegerSchema;
|
|
53
|
+
var blockRefSchema = import_v42.z.object({
|
|
54
|
+
number: blockNumberSchema,
|
|
55
|
+
timestamp: unixTimestampSchema
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// src/chains.ts
|
|
59
|
+
var chainIdSchema = positiveIntegerSchema;
|
|
60
|
+
|
|
61
|
+
// src/deserialize/indexing-status.ts
|
|
62
|
+
var schemaSerializedChainName = import_v43.z.string();
|
|
63
|
+
var schemaSerializedChainBlockRef = import_v43.z.object({
|
|
64
|
+
id: chainIdSchema,
|
|
65
|
+
block: blockRefSchema
|
|
66
|
+
});
|
|
67
|
+
function invariant_includesAtLeastOneIndexedChain(ctx) {
|
|
68
|
+
const records = ctx.value;
|
|
69
|
+
if (Object.keys(records).length === 0) {
|
|
70
|
+
ctx.issues.push({
|
|
71
|
+
code: "custom",
|
|
72
|
+
input: ctx.value,
|
|
73
|
+
message: "Ponder Indexing Status must include at least one indexed chain."
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
var schemaSerializedPonderIndexingStatus = import_v43.z.record(schemaSerializedChainName, schemaSerializedChainBlockRef).check(invariant_includesAtLeastOneIndexedChain);
|
|
78
|
+
function buildPonderIndexingStatus(data) {
|
|
79
|
+
const chains = /* @__PURE__ */ new Map();
|
|
80
|
+
for (const [, chainData] of Object.entries(data)) {
|
|
81
|
+
chains.set(chainData.id, chainData.block);
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
chains
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function deserializePonderIndexingStatus(data) {
|
|
88
|
+
const validation = schemaSerializedPonderIndexingStatus.safeParse(data);
|
|
89
|
+
if (!validation.success) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Invalid serialized Ponder Indexing Status: ${(0, import_v43.prettifyError)(validation.error)}`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
return buildPonderIndexingStatus(validation.data);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/client.ts
|
|
98
|
+
var PonderClient = class {
|
|
99
|
+
constructor(baseUrl) {
|
|
100
|
+
this.baseUrl = baseUrl;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get Ponder Indexing Status
|
|
104
|
+
*
|
|
105
|
+
* @returns Ponder Indexing Status.
|
|
106
|
+
* @throws Error if the response could not be fetched or was invalid.
|
|
107
|
+
*/
|
|
108
|
+
async status() {
|
|
109
|
+
const requestUrl = new URL("/status", this.baseUrl);
|
|
110
|
+
const response = await fetch(requestUrl);
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Failed to fetch Ponder Indexing Status response: ${response.status} ${response.statusText}`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
let responseData;
|
|
117
|
+
try {
|
|
118
|
+
responseData = await response.json();
|
|
119
|
+
} catch {
|
|
120
|
+
throw new Error("Failed to parse Ponder Indexing Status response as JSON");
|
|
121
|
+
}
|
|
122
|
+
return deserializePonderIndexingStatus(responseData);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/deserialize/indexing-status.ts","../src/blocks.ts","../src/numbers.ts","../src/time.ts","../src/chains.ts","../src/client.ts"],"sourcesContent":["export * from \"./client\";\n","/**\n * Ponder Indexing Status\n *\n * Defines the structure and validation for the Ponder Indexing Status response\n * from `GET /status` endpoint.\n * @see https://ponder.sh/docs/advanced/observability#indexing-status\n */\n\nimport { prettifyError, z } from \"zod/v4\";\nimport type { ParsePayload } from \"zod/v4/core\";\n\nimport type { BlockRef } from \"../blocks\";\nimport { blockRefSchema } from \"../blocks\";\nimport type { ChainId } from \"../chains\";\nimport { chainIdSchema } from \"../chains\";\nimport type { PonderIndexingStatus } from \"../indexing-status\";\n\nconst schemaSerializedChainName = z.string();\n\nconst schemaSerializedChainBlockRef = z.object({\n id: chainIdSchema,\n block: blockRefSchema,\n});\n\nfunction invariant_includesAtLeastOneIndexedChain(\n ctx: ParsePayload<SerializedPonderIndexingStatus>,\n) {\n const records = ctx.value;\n if (Object.keys(records).length === 0) {\n ctx.issues.push({\n code: \"custom\",\n input: ctx.value,\n message: \"Ponder Indexing Status must include at least one indexed chain.\",\n });\n }\n}\n\n/**\n * Schema describing the response of fetching `GET /status` from a Ponder app.\n */\nconst schemaSerializedPonderIndexingStatus = z\n .record(schemaSerializedChainName, schemaSerializedChainBlockRef)\n .check(invariant_includesAtLeastOneIndexedChain);\n\n/**\n * Serialized Ponder Indexing Status.\n */\nexport type SerializedPonderIndexingStatus = z.infer<typeof schemaSerializedPonderIndexingStatus>;\n\n/**\n * Build Ponder Indexing Status\n *\n * @param data Validated serialized Ponder Indexing Status.\n * @returns Ponder Indexing Status.\n */\nfunction buildPonderIndexingStatus(data: SerializedPonderIndexingStatus): PonderIndexingStatus {\n const chains = new Map<ChainId, BlockRef>();\n\n for (const [, chainData] of Object.entries(data)) {\n chains.set(chainData.id, chainData.block);\n }\n\n return {\n chains,\n };\n}\n\n/**\n * Deserialize and validate a Serialized Ponder Indexing Status.\n *\n * @param data Maybe a Serialized Ponder Indexing Status.\n * @returns Deserialized and validated Ponder Indexing Status.\n * @throws Error if data cannot be deserialized into a valid Ponder Indexing Status.\n */\nexport function deserializePonderIndexingStatus(\n data: SerializedPonderIndexingStatus | unknown,\n): PonderIndexingStatus {\n const validation = schemaSerializedPonderIndexingStatus.safeParse(data);\n\n if (!validation.success) {\n throw new Error(\n `Invalid serialized Ponder Indexing Status: ${prettifyError(validation.error)}`,\n );\n }\n\n return buildPonderIndexingStatus(validation.data);\n}\n","import { z } from \"zod/v4\";\n\nimport { nonnegativeIntegerSchema } from \"./numbers\";\nimport { unixTimestampSchema } from \"./time\";\n\n//// Block Number\n\nexport const blockNumberSchema = nonnegativeIntegerSchema;\n\n/**\n * Block Number\n *\n * Guaranteed to be a non-negative integer.\n */\nexport type BlockNumber = z.infer<typeof blockNumberSchema>;\n\nexport const blockRefSchema = z.object({\n number: blockNumberSchema,\n timestamp: unixTimestampSchema,\n});\n\n/**\n * BlockRef\n *\n * Reference to a block.\n */\nexport type BlockRef = z.infer<typeof blockRefSchema>;\n","import { z } from \"zod/v4\";\n\n// Numbers\n\n/**\n * Any finite number. Rejects non-finite numbers such as `NaN` and `Infinity`.\n */\nexport const numberSchema = z.number({ error: `Value must be a number` });\n\nexport const integerSchema = numberSchema.int({ error: `Value must be an integer` });\n\nexport const nonnegativeNumberSchema = numberSchema.nonnegative({\n error: `Value must be non-negative`,\n});\n\nexport const positiveNumberSchema = numberSchema.positive({ error: `Value must be positive` });\n\nexport const nonnegativeIntegerSchema = integerSchema.nonnegative({\n error: `Value must be a non-negative integer`,\n});\n\nexport const positiveIntegerSchema = integerSchema.positive({\n error: `Value must be a positive integer`,\n});\n","import type { z } from \"zod/v4\";\n\nimport { integerSchema } from \"./numbers\";\n\n//// Unix Timestamp\nexport const unixTimestampSchema = integerSchema;\n\n/**\n * Unix timestamp value\n *\n * Represents the number of seconds that have elapsed\n * since January 1, 1970 (midnight UTC/GMT).\n *\n * Guaranteed to be an integer. May be zero or negative to represent a time at or\n * before Jan 1, 1970.\n */\nexport type UnixTimestamp = z.infer<typeof unixTimestampSchema>;\n","import type { z } from \"zod/v4\";\n\nimport { positiveIntegerSchema } from \"./numbers\";\n\n// Chain ID\n\nexport const chainIdSchema = positiveIntegerSchema;\n\n/**\n * Chain ID\n *\n * Represents a unique identifier for a chain.\n * Guaranteed to be a positive integer.\n *\n * Chain id standards are organized by the Ethereum Community @ https://github.com/ethereum-lists/chains\n **/\nexport type ChainId = z.infer<typeof chainIdSchema>;\n","import { deserializePonderIndexingStatus } from \"./deserialize/indexing-status\";\nimport type { PonderIndexingStatus } from \"./indexing-status\";\n\n/**\n * PonderClient for fetching data from Ponder apps.\n */\nexport class PonderClient {\n constructor(private baseUrl: URL) {}\n\n /**\n * Get Ponder Indexing Status\n *\n * @returns Ponder Indexing Status.\n * @throws Error if the response could not be fetched or was invalid.\n */\n async status(): Promise<PonderIndexingStatus> {\n const requestUrl = new URL(\"/status\", this.baseUrl);\n const response = await fetch(requestUrl);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch Ponder Indexing Status response: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n\n try {\n responseData = await response.json();\n } catch {\n throw new Error(\"Failed to parse Ponder Indexing Status response as JSON\");\n }\n\n return deserializePonderIndexingStatus(responseData);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQA,IAAAA,aAAiC;;;ACRjC,IAAAC,aAAkB;;;ACAlB,gBAAkB;AAOX,IAAM,eAAe,YAAE,OAAO,EAAE,OAAO,yBAAyB,CAAC;AAEjE,IAAM,gBAAgB,aAAa,IAAI,EAAE,OAAO,2BAA2B,CAAC;AAE5E,IAAM,0BAA0B,aAAa,YAAY;AAAA,EAC9D,OAAO;AACT,CAAC;AAEM,IAAM,uBAAuB,aAAa,SAAS,EAAE,OAAO,yBAAyB,CAAC;AAEtF,IAAM,2BAA2B,cAAc,YAAY;AAAA,EAChE,OAAO;AACT,CAAC;AAEM,IAAM,wBAAwB,cAAc,SAAS;AAAA,EAC1D,OAAO;AACT,CAAC;;;AClBM,IAAM,sBAAsB;;;AFE5B,IAAM,oBAAoB;AAS1B,IAAM,iBAAiB,aAAE,OAAO;AAAA,EACrC,QAAQ;AAAA,EACR,WAAW;AACb,CAAC;;;AGbM,IAAM,gBAAgB;;;AJW7B,IAAM,4BAA4B,aAAE,OAAO;AAE3C,IAAM,gCAAgC,aAAE,OAAO;AAAA,EAC7C,IAAI;AAAA,EACJ,OAAO;AACT,CAAC;AAED,SAAS,yCACP,KACA;AACA,QAAM,UAAU,IAAI;AACpB,MAAI,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACrC,QAAI,OAAO,KAAK;AAAA,MACd,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,MACX,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAKA,IAAM,uCAAuC,aAC1C,OAAO,2BAA2B,6BAA6B,EAC/D,MAAM,wCAAwC;AAajD,SAAS,0BAA0B,MAA4D;AAC7F,QAAM,SAAS,oBAAI,IAAuB;AAE1C,aAAW,CAAC,EAAE,SAAS,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,WAAO,IAAI,UAAU,IAAI,UAAU,KAAK;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;AASO,SAAS,gCACd,MACsB;AACtB,QAAM,aAAa,qCAAqC,UAAU,IAAI;AAEtE,MAAI,CAAC,WAAW,SAAS;AACvB,UAAM,IAAI;AAAA,MACR,kDAA8C,0BAAc,WAAW,KAAK,CAAC;AAAA,IAC/E;AAAA,EACF;AAEA,SAAO,0BAA0B,WAAW,IAAI;AAClD;;;AKhFO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,SAAc;AAAd;AAAA,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQnC,MAAM,SAAwC;AAC5C,UAAM,aAAa,IAAI,IAAI,WAAW,KAAK,OAAO;AAClD,UAAM,WAAW,MAAM,MAAM,UAAU;AAEvC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR,oDAAoD,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,MAC5F;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI;AACF,qBAAe,MAAM,SAAS,KAAK;AAAA,IACrC,QAAQ;AACN,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AAEA,WAAO,gCAAgC,YAAY;AAAA,EACrD;AACF;","names":["import_v4","import_v4"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
declare const blockRefSchema: z.ZodObject<{
|
|
4
|
+
number: z.ZodNumber;
|
|
5
|
+
timestamp: z.ZodNumber;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
/**
|
|
8
|
+
* BlockRef
|
|
9
|
+
*
|
|
10
|
+
* Reference to a block.
|
|
11
|
+
*/
|
|
12
|
+
type BlockRef = z.infer<typeof blockRefSchema>;
|
|
13
|
+
|
|
14
|
+
declare const chainIdSchema: z.ZodNumber;
|
|
15
|
+
/**
|
|
16
|
+
* Chain ID
|
|
17
|
+
*
|
|
18
|
+
* Represents a unique identifier for a chain.
|
|
19
|
+
* Guaranteed to be a positive integer.
|
|
20
|
+
*
|
|
21
|
+
* Chain id standards are organized by the Ethereum Community @ https://github.com/ethereum-lists/chains
|
|
22
|
+
**/
|
|
23
|
+
type ChainId = z.infer<typeof chainIdSchema>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Ponder Indexing Status
|
|
27
|
+
*
|
|
28
|
+
* Represents the chain indexing status in a Ponder application.
|
|
29
|
+
*/
|
|
30
|
+
interface PonderIndexingStatus {
|
|
31
|
+
/**
|
|
32
|
+
* Map of indexed chain IDs to their block reference.
|
|
33
|
+
*
|
|
34
|
+
* Guarantees:
|
|
35
|
+
* - Includes entry for at least one indexed chain.
|
|
36
|
+
* - BlockRef corresponds to either:
|
|
37
|
+
* - The first block to be indexed (when chain indexing is currently queued).
|
|
38
|
+
* - The last indexed block (when chain indexing is currently in progress).
|
|
39
|
+
*/
|
|
40
|
+
chains: Map<ChainId, BlockRef>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* PonderClient for fetching data from Ponder apps.
|
|
45
|
+
*/
|
|
46
|
+
declare class PonderClient {
|
|
47
|
+
private baseUrl;
|
|
48
|
+
constructor(baseUrl: URL);
|
|
49
|
+
/**
|
|
50
|
+
* Get Ponder Indexing Status
|
|
51
|
+
*
|
|
52
|
+
* @returns Ponder Indexing Status.
|
|
53
|
+
* @throws Error if the response could not be fetched or was invalid.
|
|
54
|
+
*/
|
|
55
|
+
status(): Promise<PonderIndexingStatus>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { PonderClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
declare const blockRefSchema: z.ZodObject<{
|
|
4
|
+
number: z.ZodNumber;
|
|
5
|
+
timestamp: z.ZodNumber;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
/**
|
|
8
|
+
* BlockRef
|
|
9
|
+
*
|
|
10
|
+
* Reference to a block.
|
|
11
|
+
*/
|
|
12
|
+
type BlockRef = z.infer<typeof blockRefSchema>;
|
|
13
|
+
|
|
14
|
+
declare const chainIdSchema: z.ZodNumber;
|
|
15
|
+
/**
|
|
16
|
+
* Chain ID
|
|
17
|
+
*
|
|
18
|
+
* Represents a unique identifier for a chain.
|
|
19
|
+
* Guaranteed to be a positive integer.
|
|
20
|
+
*
|
|
21
|
+
* Chain id standards are organized by the Ethereum Community @ https://github.com/ethereum-lists/chains
|
|
22
|
+
**/
|
|
23
|
+
type ChainId = z.infer<typeof chainIdSchema>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Ponder Indexing Status
|
|
27
|
+
*
|
|
28
|
+
* Represents the chain indexing status in a Ponder application.
|
|
29
|
+
*/
|
|
30
|
+
interface PonderIndexingStatus {
|
|
31
|
+
/**
|
|
32
|
+
* Map of indexed chain IDs to their block reference.
|
|
33
|
+
*
|
|
34
|
+
* Guarantees:
|
|
35
|
+
* - Includes entry for at least one indexed chain.
|
|
36
|
+
* - BlockRef corresponds to either:
|
|
37
|
+
* - The first block to be indexed (when chain indexing is currently queued).
|
|
38
|
+
* - The last indexed block (when chain indexing is currently in progress).
|
|
39
|
+
*/
|
|
40
|
+
chains: Map<ChainId, BlockRef>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* PonderClient for fetching data from Ponder apps.
|
|
45
|
+
*/
|
|
46
|
+
declare class PonderClient {
|
|
47
|
+
private baseUrl;
|
|
48
|
+
constructor(baseUrl: URL);
|
|
49
|
+
/**
|
|
50
|
+
* Get Ponder Indexing Status
|
|
51
|
+
*
|
|
52
|
+
* @returns Ponder Indexing Status.
|
|
53
|
+
* @throws Error if the response could not be fetched or was invalid.
|
|
54
|
+
*/
|
|
55
|
+
status(): Promise<PonderIndexingStatus>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { PonderClient };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// src/deserialize/indexing-status.ts
|
|
2
|
+
import { prettifyError, z as z3 } from "zod/v4";
|
|
3
|
+
|
|
4
|
+
// src/blocks.ts
|
|
5
|
+
import { z as z2 } from "zod/v4";
|
|
6
|
+
|
|
7
|
+
// src/numbers.ts
|
|
8
|
+
import { z } from "zod/v4";
|
|
9
|
+
var numberSchema = z.number({ error: `Value must be a number` });
|
|
10
|
+
var integerSchema = numberSchema.int({ error: `Value must be an integer` });
|
|
11
|
+
var nonnegativeNumberSchema = numberSchema.nonnegative({
|
|
12
|
+
error: `Value must be non-negative`
|
|
13
|
+
});
|
|
14
|
+
var positiveNumberSchema = numberSchema.positive({ error: `Value must be positive` });
|
|
15
|
+
var nonnegativeIntegerSchema = integerSchema.nonnegative({
|
|
16
|
+
error: `Value must be a non-negative integer`
|
|
17
|
+
});
|
|
18
|
+
var positiveIntegerSchema = integerSchema.positive({
|
|
19
|
+
error: `Value must be a positive integer`
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// src/time.ts
|
|
23
|
+
var unixTimestampSchema = integerSchema;
|
|
24
|
+
|
|
25
|
+
// src/blocks.ts
|
|
26
|
+
var blockNumberSchema = nonnegativeIntegerSchema;
|
|
27
|
+
var blockRefSchema = z2.object({
|
|
28
|
+
number: blockNumberSchema,
|
|
29
|
+
timestamp: unixTimestampSchema
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// src/chains.ts
|
|
33
|
+
var chainIdSchema = positiveIntegerSchema;
|
|
34
|
+
|
|
35
|
+
// src/deserialize/indexing-status.ts
|
|
36
|
+
var schemaSerializedChainName = z3.string();
|
|
37
|
+
var schemaSerializedChainBlockRef = z3.object({
|
|
38
|
+
id: chainIdSchema,
|
|
39
|
+
block: blockRefSchema
|
|
40
|
+
});
|
|
41
|
+
function invariant_includesAtLeastOneIndexedChain(ctx) {
|
|
42
|
+
const records = ctx.value;
|
|
43
|
+
if (Object.keys(records).length === 0) {
|
|
44
|
+
ctx.issues.push({
|
|
45
|
+
code: "custom",
|
|
46
|
+
input: ctx.value,
|
|
47
|
+
message: "Ponder Indexing Status must include at least one indexed chain."
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
var schemaSerializedPonderIndexingStatus = z3.record(schemaSerializedChainName, schemaSerializedChainBlockRef).check(invariant_includesAtLeastOneIndexedChain);
|
|
52
|
+
function buildPonderIndexingStatus(data) {
|
|
53
|
+
const chains = /* @__PURE__ */ new Map();
|
|
54
|
+
for (const [, chainData] of Object.entries(data)) {
|
|
55
|
+
chains.set(chainData.id, chainData.block);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
chains
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function deserializePonderIndexingStatus(data) {
|
|
62
|
+
const validation = schemaSerializedPonderIndexingStatus.safeParse(data);
|
|
63
|
+
if (!validation.success) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Invalid serialized Ponder Indexing Status: ${prettifyError(validation.error)}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return buildPonderIndexingStatus(validation.data);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/client.ts
|
|
72
|
+
var PonderClient = class {
|
|
73
|
+
constructor(baseUrl) {
|
|
74
|
+
this.baseUrl = baseUrl;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get Ponder Indexing Status
|
|
78
|
+
*
|
|
79
|
+
* @returns Ponder Indexing Status.
|
|
80
|
+
* @throws Error if the response could not be fetched or was invalid.
|
|
81
|
+
*/
|
|
82
|
+
async status() {
|
|
83
|
+
const requestUrl = new URL("/status", this.baseUrl);
|
|
84
|
+
const response = await fetch(requestUrl);
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Failed to fetch Ponder Indexing Status response: ${response.status} ${response.statusText}`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
let responseData;
|
|
91
|
+
try {
|
|
92
|
+
responseData = await response.json();
|
|
93
|
+
} catch {
|
|
94
|
+
throw new Error("Failed to parse Ponder Indexing Status response as JSON");
|
|
95
|
+
}
|
|
96
|
+
return deserializePonderIndexingStatus(responseData);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
export {
|
|
100
|
+
PonderClient
|
|
101
|
+
};
|
|
102
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/deserialize/indexing-status.ts","../src/blocks.ts","../src/numbers.ts","../src/time.ts","../src/chains.ts","../src/client.ts"],"sourcesContent":["/**\n * Ponder Indexing Status\n *\n * Defines the structure and validation for the Ponder Indexing Status response\n * from `GET /status` endpoint.\n * @see https://ponder.sh/docs/advanced/observability#indexing-status\n */\n\nimport { prettifyError, z } from \"zod/v4\";\nimport type { ParsePayload } from \"zod/v4/core\";\n\nimport type { BlockRef } from \"../blocks\";\nimport { blockRefSchema } from \"../blocks\";\nimport type { ChainId } from \"../chains\";\nimport { chainIdSchema } from \"../chains\";\nimport type { PonderIndexingStatus } from \"../indexing-status\";\n\nconst schemaSerializedChainName = z.string();\n\nconst schemaSerializedChainBlockRef = z.object({\n id: chainIdSchema,\n block: blockRefSchema,\n});\n\nfunction invariant_includesAtLeastOneIndexedChain(\n ctx: ParsePayload<SerializedPonderIndexingStatus>,\n) {\n const records = ctx.value;\n if (Object.keys(records).length === 0) {\n ctx.issues.push({\n code: \"custom\",\n input: ctx.value,\n message: \"Ponder Indexing Status must include at least one indexed chain.\",\n });\n }\n}\n\n/**\n * Schema describing the response of fetching `GET /status` from a Ponder app.\n */\nconst schemaSerializedPonderIndexingStatus = z\n .record(schemaSerializedChainName, schemaSerializedChainBlockRef)\n .check(invariant_includesAtLeastOneIndexedChain);\n\n/**\n * Serialized Ponder Indexing Status.\n */\nexport type SerializedPonderIndexingStatus = z.infer<typeof schemaSerializedPonderIndexingStatus>;\n\n/**\n * Build Ponder Indexing Status\n *\n * @param data Validated serialized Ponder Indexing Status.\n * @returns Ponder Indexing Status.\n */\nfunction buildPonderIndexingStatus(data: SerializedPonderIndexingStatus): PonderIndexingStatus {\n const chains = new Map<ChainId, BlockRef>();\n\n for (const [, chainData] of Object.entries(data)) {\n chains.set(chainData.id, chainData.block);\n }\n\n return {\n chains,\n };\n}\n\n/**\n * Deserialize and validate a Serialized Ponder Indexing Status.\n *\n * @param data Maybe a Serialized Ponder Indexing Status.\n * @returns Deserialized and validated Ponder Indexing Status.\n * @throws Error if data cannot be deserialized into a valid Ponder Indexing Status.\n */\nexport function deserializePonderIndexingStatus(\n data: SerializedPonderIndexingStatus | unknown,\n): PonderIndexingStatus {\n const validation = schemaSerializedPonderIndexingStatus.safeParse(data);\n\n if (!validation.success) {\n throw new Error(\n `Invalid serialized Ponder Indexing Status: ${prettifyError(validation.error)}`,\n );\n }\n\n return buildPonderIndexingStatus(validation.data);\n}\n","import { z } from \"zod/v4\";\n\nimport { nonnegativeIntegerSchema } from \"./numbers\";\nimport { unixTimestampSchema } from \"./time\";\n\n//// Block Number\n\nexport const blockNumberSchema = nonnegativeIntegerSchema;\n\n/**\n * Block Number\n *\n * Guaranteed to be a non-negative integer.\n */\nexport type BlockNumber = z.infer<typeof blockNumberSchema>;\n\nexport const blockRefSchema = z.object({\n number: blockNumberSchema,\n timestamp: unixTimestampSchema,\n});\n\n/**\n * BlockRef\n *\n * Reference to a block.\n */\nexport type BlockRef = z.infer<typeof blockRefSchema>;\n","import { z } from \"zod/v4\";\n\n// Numbers\n\n/**\n * Any finite number. Rejects non-finite numbers such as `NaN` and `Infinity`.\n */\nexport const numberSchema = z.number({ error: `Value must be a number` });\n\nexport const integerSchema = numberSchema.int({ error: `Value must be an integer` });\n\nexport const nonnegativeNumberSchema = numberSchema.nonnegative({\n error: `Value must be non-negative`,\n});\n\nexport const positiveNumberSchema = numberSchema.positive({ error: `Value must be positive` });\n\nexport const nonnegativeIntegerSchema = integerSchema.nonnegative({\n error: `Value must be a non-negative integer`,\n});\n\nexport const positiveIntegerSchema = integerSchema.positive({\n error: `Value must be a positive integer`,\n});\n","import type { z } from \"zod/v4\";\n\nimport { integerSchema } from \"./numbers\";\n\n//// Unix Timestamp\nexport const unixTimestampSchema = integerSchema;\n\n/**\n * Unix timestamp value\n *\n * Represents the number of seconds that have elapsed\n * since January 1, 1970 (midnight UTC/GMT).\n *\n * Guaranteed to be an integer. May be zero or negative to represent a time at or\n * before Jan 1, 1970.\n */\nexport type UnixTimestamp = z.infer<typeof unixTimestampSchema>;\n","import type { z } from \"zod/v4\";\n\nimport { positiveIntegerSchema } from \"./numbers\";\n\n// Chain ID\n\nexport const chainIdSchema = positiveIntegerSchema;\n\n/**\n * Chain ID\n *\n * Represents a unique identifier for a chain.\n * Guaranteed to be a positive integer.\n *\n * Chain id standards are organized by the Ethereum Community @ https://github.com/ethereum-lists/chains\n **/\nexport type ChainId = z.infer<typeof chainIdSchema>;\n","import { deserializePonderIndexingStatus } from \"./deserialize/indexing-status\";\nimport type { PonderIndexingStatus } from \"./indexing-status\";\n\n/**\n * PonderClient for fetching data from Ponder apps.\n */\nexport class PonderClient {\n constructor(private baseUrl: URL) {}\n\n /**\n * Get Ponder Indexing Status\n *\n * @returns Ponder Indexing Status.\n * @throws Error if the response could not be fetched or was invalid.\n */\n async status(): Promise<PonderIndexingStatus> {\n const requestUrl = new URL(\"/status\", this.baseUrl);\n const response = await fetch(requestUrl);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch Ponder Indexing Status response: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n\n try {\n responseData = await response.json();\n } catch {\n throw new Error(\"Failed to parse Ponder Indexing Status response as JSON\");\n }\n\n return deserializePonderIndexingStatus(responseData);\n }\n}\n"],"mappings":";AAQA,SAAS,eAAe,KAAAA,UAAS;;;ACRjC,SAAS,KAAAC,UAAS;;;ACAlB,SAAS,SAAS;AAOX,IAAM,eAAe,EAAE,OAAO,EAAE,OAAO,yBAAyB,CAAC;AAEjE,IAAM,gBAAgB,aAAa,IAAI,EAAE,OAAO,2BAA2B,CAAC;AAE5E,IAAM,0BAA0B,aAAa,YAAY;AAAA,EAC9D,OAAO;AACT,CAAC;AAEM,IAAM,uBAAuB,aAAa,SAAS,EAAE,OAAO,yBAAyB,CAAC;AAEtF,IAAM,2BAA2B,cAAc,YAAY;AAAA,EAChE,OAAO;AACT,CAAC;AAEM,IAAM,wBAAwB,cAAc,SAAS;AAAA,EAC1D,OAAO;AACT,CAAC;;;AClBM,IAAM,sBAAsB;;;AFE5B,IAAM,oBAAoB;AAS1B,IAAM,iBAAiBC,GAAE,OAAO;AAAA,EACrC,QAAQ;AAAA,EACR,WAAW;AACb,CAAC;;;AGbM,IAAM,gBAAgB;;;AJW7B,IAAM,4BAA4BC,GAAE,OAAO;AAE3C,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EAC7C,IAAI;AAAA,EACJ,OAAO;AACT,CAAC;AAED,SAAS,yCACP,KACA;AACA,QAAM,UAAU,IAAI;AACpB,MAAI,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACrC,QAAI,OAAO,KAAK;AAAA,MACd,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,MACX,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAKA,IAAM,uCAAuCA,GAC1C,OAAO,2BAA2B,6BAA6B,EAC/D,MAAM,wCAAwC;AAajD,SAAS,0BAA0B,MAA4D;AAC7F,QAAM,SAAS,oBAAI,IAAuB;AAE1C,aAAW,CAAC,EAAE,SAAS,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,WAAO,IAAI,UAAU,IAAI,UAAU,KAAK;AAAA,EAC1C;AAEA,SAAO;AAAA,IACL;AAAA,EACF;AACF;AASO,SAAS,gCACd,MACsB;AACtB,QAAM,aAAa,qCAAqC,UAAU,IAAI;AAEtE,MAAI,CAAC,WAAW,SAAS;AACvB,UAAM,IAAI;AAAA,MACR,8CAA8C,cAAc,WAAW,KAAK,CAAC;AAAA,IAC/E;AAAA,EACF;AAEA,SAAO,0BAA0B,WAAW,IAAI;AAClD;;;AKhFO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,SAAc;AAAd;AAAA,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQnC,MAAM,SAAwC;AAC5C,UAAM,aAAa,IAAI,IAAI,WAAW,KAAK,OAAO;AAClD,UAAM,WAAW,MAAM,MAAM,UAAU;AAEvC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR,oDAAoD,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,MAC5F;AAAA,IACF;AAEA,QAAI;AAEJ,QAAI;AACF,qBAAe,MAAM,SAAS,KAAK;AAAA,IACrC,QAAQ;AACN,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AAEA,WAAO,gCAAgC,YAAY;AAAA,EACrD;AACF;","names":["z","z","z","z"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ensnode/ponder-sdk",
|
|
3
|
+
"version": "0.0.0-next-20260204111615",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A utility library for interacting with Ponder apps and data.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/namehash/ensnode.git",
|
|
10
|
+
"directory": "packages/ponder-sdk"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/namehash/ensnode/tree/main/packages/ponder-sdk",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"ENSNode",
|
|
15
|
+
"Ponder"
|
|
16
|
+
],
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/index.d.cts",
|
|
28
|
+
"default": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "24.10.9",
|
|
37
|
+
"tsup": "^8.3.6",
|
|
38
|
+
"typescript": "^5.7.3",
|
|
39
|
+
"vitest": "^4.0.2",
|
|
40
|
+
"zod": "^4.3.6",
|
|
41
|
+
"@ensnode/shared-configs": "0.0.0-next-20260204111615"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"zod": "^4.3.6"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"prepublish": "tsup",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "vitest",
|
|
50
|
+
"lint": "biome check --write .",
|
|
51
|
+
"lint:ci": "biome ci"
|
|
52
|
+
},
|
|
53
|
+
"main": "./dist/index.cjs",
|
|
54
|
+
"module": "./dist/index.js",
|
|
55
|
+
"types": "./dist/index.d.ts"
|
|
56
|
+
}
|