@glowlabs-org/events-sdk 0.1.1 → 1.0.1
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/README.md +311 -151
- package/dist/admin.d.ts +7 -6
- package/dist/admin.js +6 -6
- package/dist/base-event.d.ts +65 -0
- package/dist/base-event.js +22 -0
- package/dist/emitter.d.ts +17 -0
- package/dist/emitter.js +67 -0
- package/dist/event-registry.d.ts +2 -0
- package/dist/event-registry.js +27 -0
- package/dist/index.d.ts +2 -5
- package/dist/index.js +2 -5
- package/dist/listener.d.ts +14 -0
- package/dist/listener.js +88 -0
- package/dist/schemas/application-created.v1.d.ts +25 -0
- package/dist/schemas/application-created.v1.js +12 -0
- package/dist/schemas/audit-pfees-paid.v1.d.ts +15 -0
- package/dist/schemas/audit-pfees-paid.v1.js +14 -0
- package/dist/schemas/audit-pfees-paid.v2.d.ts +15 -0
- package/dist/schemas/audit-pfees-paid.v2.js +14 -0
- package/dist/schemas/audit-pushed.v1.d.ts +15 -0
- package/dist/schemas/audit-pushed.v1.js +13 -0
- package/dist/schemas/audit-slashed.v1.d.ts +12 -0
- package/dist/schemas/audit-slashed.v1.js +10 -0
- package/dist/types.d.ts +32 -21
- package/dist/utils.d.ts +20 -0
- package/dist/utils.js +45 -0
- package/dist/zones.d.ts +7 -0
- package/dist/zones.js +8 -0
- package/package.json +1 -1
- package/dist/consumer.d.ts +0 -14
- package/dist/consumer.js +0 -84
- package/dist/glow-listener.d.ts +0 -31
- package/dist/glow-listener.js +0 -74
- package/dist/producer.d.ts +0 -8
- package/dist/producer.js +0 -46
- package/dist/schemas/auditPushed.d.ts +0 -69
- package/dist/schemas/auditPushed.js +0 -42
- package/dist/typed-emitter.d.ts +0 -7
- package/dist/typed-emitter.js +0 -17
@@ -0,0 +1,65 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
import { ZoneName } from "./zones";
|
3
|
+
export declare const baseEventZ: z.ZodObject<{
|
4
|
+
id: z.ZodString;
|
5
|
+
zoneId: z.ZodEffects<z.ZodNumber, number, number>;
|
6
|
+
zoneName: z.ZodEnum<[string, ...string[]]>;
|
7
|
+
schemaVersion: z.ZodEffects<z.ZodNumber, 1 | 2, number>;
|
8
|
+
eventType: z.ZodEnum<["audit.pushed", "audit.slashed", "audit.pfees.paid"]>;
|
9
|
+
timeStamp: z.ZodNumber;
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
11
|
+
id: string;
|
12
|
+
zoneId: number;
|
13
|
+
zoneName: string;
|
14
|
+
schemaVersion: 1 | 2;
|
15
|
+
eventType: "audit.pushed" | "audit.slashed" | "audit.pfees.paid";
|
16
|
+
timeStamp: number;
|
17
|
+
}, {
|
18
|
+
id: string;
|
19
|
+
zoneId: number;
|
20
|
+
zoneName: string;
|
21
|
+
schemaVersion: number;
|
22
|
+
eventType: "audit.pushed" | "audit.slashed" | "audit.pfees.paid";
|
23
|
+
timeStamp: number;
|
24
|
+
}>;
|
25
|
+
export interface BaseEventAuditPushedV1 {
|
26
|
+
id: string;
|
27
|
+
zoneId: number;
|
28
|
+
zoneName: ZoneName;
|
29
|
+
schemaVersion: 1;
|
30
|
+
eventType: "audit.pushed";
|
31
|
+
timeStamp: number;
|
32
|
+
}
|
33
|
+
export interface BaseEventAuditSlashedV1 {
|
34
|
+
id: string;
|
35
|
+
zoneId: number;
|
36
|
+
zoneName: ZoneName;
|
37
|
+
schemaVersion: 1;
|
38
|
+
eventType: "audit.slashed";
|
39
|
+
timeStamp: number;
|
40
|
+
}
|
41
|
+
export interface BaseEventAuditPfeesPaidV1 {
|
42
|
+
id: string;
|
43
|
+
zoneId: number;
|
44
|
+
zoneName: ZoneName;
|
45
|
+
schemaVersion: 1;
|
46
|
+
eventType: "audit.pfees.paid";
|
47
|
+
timeStamp: number;
|
48
|
+
}
|
49
|
+
export interface BaseEventAuditPfeesPaidV2 {
|
50
|
+
id: string;
|
51
|
+
zoneId: number;
|
52
|
+
zoneName: ZoneName;
|
53
|
+
schemaVersion: 2;
|
54
|
+
eventType: "audit.pfees.paid";
|
55
|
+
timeStamp: number;
|
56
|
+
}
|
57
|
+
export interface BaseEventApplicationCreatedV1 {
|
58
|
+
id: string;
|
59
|
+
zoneId: number;
|
60
|
+
zoneName: ZoneName;
|
61
|
+
schemaVersion: 1;
|
62
|
+
eventType: "application.created";
|
63
|
+
timeStamp: number;
|
64
|
+
}
|
65
|
+
export type BaseEvent = BaseEventAuditPushedV1 | BaseEventAuditSlashedV1 | BaseEventAuditPfeesPaidV1 | BaseEventAuditPfeesPaidV2 | BaseEventApplicationCreatedV1;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.baseEventZ = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
const zones_1 = require("./zones");
|
6
|
+
const zoneIdNumbers = Object.keys(zones_1.zoneMap).map(Number);
|
7
|
+
const zoneNames = Object.values(zones_1.zoneMap);
|
8
|
+
exports.baseEventZ = zod_1.z.object({
|
9
|
+
id: zod_1.z.string().uuid(),
|
10
|
+
zoneId: zod_1.z.number().refine((id) => zoneIdNumbers.includes(id), {
|
11
|
+
message: "Invalid zoneId",
|
12
|
+
}),
|
13
|
+
zoneName: zod_1.z.enum(zoneNames),
|
14
|
+
schemaVersion: zod_1.z
|
15
|
+
.number()
|
16
|
+
.int()
|
17
|
+
.refine((v) => v === 1 || v === 2, {
|
18
|
+
message: "Invalid schemaVersion",
|
19
|
+
}),
|
20
|
+
eventType: zod_1.z.enum(["audit.pushed", "audit.slashed", "audit.pfees.paid"]),
|
21
|
+
timeStamp: zod_1.z.number().int(),
|
22
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { EventPayload, EventType, EventVersion } from "./types";
|
2
|
+
interface CreateGlowEventEmitterOptions {
|
3
|
+
username: string;
|
4
|
+
password: string;
|
5
|
+
zoneId: number;
|
6
|
+
exchangePrefix?: string;
|
7
|
+
}
|
8
|
+
interface EmitEventArgs<T extends EventType, V extends EventVersion<T>> {
|
9
|
+
eventType: T;
|
10
|
+
schemaVersion: V;
|
11
|
+
payload: EventPayload<T, V>;
|
12
|
+
}
|
13
|
+
export declare function createGlowEventEmitter({ username, password, zoneId, exchangePrefix, }: CreateGlowEventEmitterOptions): {
|
14
|
+
emit: <T extends EventType, V extends EventVersion<T>>(args: EmitEventArgs<T, V>) => Promise<void>;
|
15
|
+
disconnect: () => Promise<void>;
|
16
|
+
};
|
17
|
+
export {};
|
package/dist/emitter.js
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.createGlowEventEmitter = createGlowEventEmitter;
|
7
|
+
const amqplib_1 = __importDefault(require("amqplib"));
|
8
|
+
const utils_1 = require("./utils");
|
9
|
+
const uuid_1 = require("uuid");
|
10
|
+
const zones_1 = require("./zones");
|
11
|
+
function createGlowEventEmitter({ username, password, zoneId, exchangePrefix = "glow.zone-", }) {
|
12
|
+
let amqpConnection = null;
|
13
|
+
let amqpChannel = null;
|
14
|
+
// Exchanges for global and specific zone
|
15
|
+
const globalExchangeName = `${exchangePrefix}0.events`;
|
16
|
+
const zoneExchangeName = `${exchangePrefix}${zoneId}.events`;
|
17
|
+
function buildAmqpUrl() {
|
18
|
+
const url = new URL(`amqp://${username}:${password}@turntable.proxy.rlwy.net:50784`);
|
19
|
+
return url.toString();
|
20
|
+
}
|
21
|
+
async function connectIfNeeded() {
|
22
|
+
if (!amqpConnection) {
|
23
|
+
amqpConnection = (await amqplib_1.default.connect(buildAmqpUrl()));
|
24
|
+
amqpChannel = (await amqpConnection.createChannel());
|
25
|
+
}
|
26
|
+
if (amqpChannel) {
|
27
|
+
await amqpChannel.assertExchange(globalExchangeName, "topic", {
|
28
|
+
durable: true,
|
29
|
+
});
|
30
|
+
await amqpChannel.assertExchange(zoneExchangeName, "topic", {
|
31
|
+
durable: true,
|
32
|
+
});
|
33
|
+
}
|
34
|
+
}
|
35
|
+
async function emit(args) {
|
36
|
+
const { eventType, schemaVersion, payload } = args;
|
37
|
+
const zoneName = zones_1.zoneMap[String(zoneId)];
|
38
|
+
if (!zoneName)
|
39
|
+
throw new Error(`Invalid zoneId: ${zoneId}`);
|
40
|
+
if (zoneId === 0)
|
41
|
+
throw new Error("Cannot emit events with zoneId 0. Use a specific zone emitter.");
|
42
|
+
const event = {
|
43
|
+
id: (0, uuid_1.v4)(),
|
44
|
+
eventType,
|
45
|
+
schemaVersion,
|
46
|
+
zoneId,
|
47
|
+
zoneName,
|
48
|
+
timeStamp: Date.now(),
|
49
|
+
payload,
|
50
|
+
};
|
51
|
+
(0, utils_1.validateZoneNameAndId)(event.zoneId, event.zoneName);
|
52
|
+
(0, utils_1.validateEventPayload)(event.eventType, event.schemaVersion, event);
|
53
|
+
const routingKey = `${event.eventType}.v${event.schemaVersion}`;
|
54
|
+
await connectIfNeeded();
|
55
|
+
// Emit to both the global and the specific zone exchange
|
56
|
+
amqpChannel.publish(globalExchangeName, routingKey, Buffer.from(JSON.stringify(event)), { persistent: true });
|
57
|
+
amqpChannel.publish(zoneExchangeName, routingKey, Buffer.from(JSON.stringify(event)), { persistent: true });
|
58
|
+
}
|
59
|
+
async function disconnect() {
|
60
|
+
if (amqpConnection) {
|
61
|
+
await amqpConnection.close();
|
62
|
+
amqpConnection = null;
|
63
|
+
amqpChannel = null;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
return { emit, disconnect };
|
67
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getEventSchema = getEventSchema;
|
4
|
+
const audit_pushed_v1_1 = require("./schemas/audit-pushed.v1");
|
5
|
+
const audit_slashed_v1_1 = require("./schemas/audit-slashed.v1");
|
6
|
+
const audit_pfees_paid_v1_1 = require("./schemas/audit-pfees-paid.v1");
|
7
|
+
const audit_pfees_paid_v2_1 = require("./schemas/audit-pfees-paid.v2");
|
8
|
+
const base_event_1 = require("./base-event");
|
9
|
+
const application_created_v1_1 = require("./schemas/application-created.v1");
|
10
|
+
const eventTypeRegistry = {
|
11
|
+
"audit.pushed:v1": base_event_1.baseEventZ.extend({ payload: audit_pushed_v1_1.auditPushedV1PayloadZ }),
|
12
|
+
"audit.slashed:v1": base_event_1.baseEventZ.extend({ payload: audit_slashed_v1_1.auditSlashedV1PayloadZ }),
|
13
|
+
"audit.pfees.paid:v1": base_event_1.baseEventZ.extend({
|
14
|
+
payload: audit_pfees_paid_v1_1.auditPfeesPaidV1PayloadZ,
|
15
|
+
}),
|
16
|
+
"audit.pfees.paid:v2": base_event_1.baseEventZ.extend({
|
17
|
+
payload: audit_pfees_paid_v2_1.auditPfeesPaidV2PayloadZ,
|
18
|
+
}),
|
19
|
+
"application.created:v1": base_event_1.baseEventZ.extend({
|
20
|
+
payload: application_created_v1_1.applicationCreatedV1PayloadZ,
|
21
|
+
}),
|
22
|
+
// Add more event types/versions here
|
23
|
+
};
|
24
|
+
function getEventSchema(eventType, version) {
|
25
|
+
const key = `${eventType}:v${version}`;
|
26
|
+
return eventTypeRegistry[key];
|
27
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
@@ -14,9 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
15
|
};
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
-
__exportStar(require("./
|
18
|
-
__exportStar(require("./
|
19
|
-
__exportStar(require("./schemas/auditPushed"), exports);
|
20
|
-
__exportStar(require("./glow-listener"), exports);
|
21
|
-
__exportStar(require("./types"), exports);
|
17
|
+
__exportStar(require("./emitter"), exports);
|
18
|
+
__exportStar(require("./listener"), exports);
|
22
19
|
__exportStar(require("./admin"), exports);
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import type { EventType, EventVersion, EventPayload, GlowEvent } from "./types";
|
2
|
+
interface CreateGlowEventListenerOptions {
|
3
|
+
username: string;
|
4
|
+
password: string;
|
5
|
+
zoneId: number;
|
6
|
+
queueName?: string;
|
7
|
+
exchangePrefix?: string;
|
8
|
+
}
|
9
|
+
export declare function createGlowEventListener({ username, password, zoneId, queueName, exchangePrefix, }: CreateGlowEventListenerOptions): {
|
10
|
+
onEvent: <T extends EventType, V extends EventVersion<T>>(eventType: T, schemaVersion: V, handler: (event: GlowEvent<EventPayload<T, V>>) => void) => void;
|
11
|
+
start: () => Promise<void>;
|
12
|
+
stop: () => Promise<void>;
|
13
|
+
};
|
14
|
+
export {};
|
package/dist/listener.js
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.createGlowEventListener = createGlowEventListener;
|
7
|
+
const amqplib_1 = __importDefault(require("amqplib"));
|
8
|
+
const event_registry_1 = require("./event-registry");
|
9
|
+
const utils_1 = require("./utils");
|
10
|
+
function createGlowEventListener({ username, password, zoneId, queueName, exchangePrefix = "glow.zone-", }) {
|
11
|
+
let amqpConnection = null;
|
12
|
+
let amqpChannel = null;
|
13
|
+
let internalQueueName;
|
14
|
+
let consumerTag = null;
|
15
|
+
// Use a special exchange for all zones if zoneId is 0
|
16
|
+
const exchangeName = `${exchangePrefix}${zoneId}.events`;
|
17
|
+
const eventHandlers = [];
|
18
|
+
function buildAmqpUrl() {
|
19
|
+
const url = new URL(`amqp://${username}:${password}@turntable.proxy.rlwy.net:50784`);
|
20
|
+
return url.toString();
|
21
|
+
}
|
22
|
+
async function connectIfNeeded(bindingPattern) {
|
23
|
+
if (!amqpConnection) {
|
24
|
+
amqpConnection = (await amqplib_1.default.connect(buildAmqpUrl()));
|
25
|
+
amqpChannel = (await amqpConnection.createChannel());
|
26
|
+
}
|
27
|
+
if (amqpChannel) {
|
28
|
+
if (queueName) {
|
29
|
+
internalQueueName = queueName;
|
30
|
+
}
|
31
|
+
else {
|
32
|
+
await amqpChannel.assertExchange(exchangeName, "topic", {
|
33
|
+
durable: true,
|
34
|
+
});
|
35
|
+
const q = await amqpChannel.assertQueue("", { exclusive: true });
|
36
|
+
internalQueueName = q.queue;
|
37
|
+
await amqpChannel.bindQueue(internalQueueName, exchangeName, bindingPattern);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
function onEvent(eventType, schemaVersion, handler) {
|
42
|
+
const bindingPattern = `${String(eventType)}.v${String(schemaVersion)}`;
|
43
|
+
eventHandlers.push({
|
44
|
+
bindingPattern,
|
45
|
+
handler: (event, meta) => handler(event),
|
46
|
+
});
|
47
|
+
}
|
48
|
+
async function start() {
|
49
|
+
for (const { bindingPattern } of eventHandlers) {
|
50
|
+
await connectIfNeeded(bindingPattern);
|
51
|
+
}
|
52
|
+
if (!internalQueueName)
|
53
|
+
throw new Error("Queue not initialized");
|
54
|
+
consumerTag = (await amqpChannel.consume(internalQueueName, (msg) => {
|
55
|
+
if (msg) {
|
56
|
+
try {
|
57
|
+
const decoded = JSON.parse(msg.content.toString());
|
58
|
+
const [eventType, versionStr] = msg.fields.routingKey.split(".v");
|
59
|
+
const schemaVersion = Number(versionStr);
|
60
|
+
(0, utils_1.validateZoneNameAndId)(decoded.zoneId, decoded.zoneName);
|
61
|
+
(0, utils_1.validateEventPayload)(eventType, schemaVersion, decoded);
|
62
|
+
const event = (0, event_registry_1.getEventSchema)(eventType, schemaVersion).parse(decoded);
|
63
|
+
const handlerEntry = eventHandlers.find((h) => h.bindingPattern === `${eventType}.v${schemaVersion}`);
|
64
|
+
if (handlerEntry)
|
65
|
+
handlerEntry.handler(event, { eventType, schemaVersion });
|
66
|
+
amqpChannel.ack(msg);
|
67
|
+
}
|
68
|
+
catch (error) {
|
69
|
+
console.error("Failed to process event:", error);
|
70
|
+
amqpChannel.nack(msg, false, false);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}, { noAck: false })).consumerTag;
|
74
|
+
}
|
75
|
+
async function stop() {
|
76
|
+
if (amqpChannel && consumerTag && internalQueueName) {
|
77
|
+
await amqpChannel.cancel(consumerTag);
|
78
|
+
consumerTag = null;
|
79
|
+
}
|
80
|
+
if (amqpConnection) {
|
81
|
+
await amqpConnection.close();
|
82
|
+
amqpConnection = null;
|
83
|
+
amqpChannel = null;
|
84
|
+
internalQueueName = undefined;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
return { onEvent, start, stop };
|
88
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
export declare const applicationCreatedV1PayloadZ: z.ZodObject<{
|
3
|
+
gcaAddress: z.ZodString;
|
4
|
+
lat: z.ZodNumber;
|
5
|
+
lng: z.ZodNumber;
|
6
|
+
estimatedCostOfPowerPerKWh: z.ZodNumber;
|
7
|
+
estimatedKWhGeneratedPerYear: z.ZodNumber;
|
8
|
+
installerCompanyName: z.ZodString;
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
10
|
+
gcaAddress: string;
|
11
|
+
lat: number;
|
12
|
+
lng: number;
|
13
|
+
estimatedCostOfPowerPerKWh: number;
|
14
|
+
estimatedKWhGeneratedPerYear: number;
|
15
|
+
installerCompanyName: string;
|
16
|
+
}, {
|
17
|
+
gcaAddress: string;
|
18
|
+
lat: number;
|
19
|
+
lng: number;
|
20
|
+
estimatedCostOfPowerPerKWh: number;
|
21
|
+
estimatedKWhGeneratedPerYear: number;
|
22
|
+
installerCompanyName: string;
|
23
|
+
}>;
|
24
|
+
export interface ApplicationCreatedV1Payload extends z.infer<typeof applicationCreatedV1PayloadZ> {
|
25
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.applicationCreatedV1PayloadZ = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
exports.applicationCreatedV1PayloadZ = zod_1.z.object({
|
6
|
+
gcaAddress: zod_1.z.string().regex(/^0x[a-fA-F0-9]{40}$/), // eth address
|
7
|
+
lat: zod_1.z.number(),
|
8
|
+
lng: zod_1.z.number(),
|
9
|
+
estimatedCostOfPowerPerKWh: zod_1.z.number(),
|
10
|
+
estimatedKWhGeneratedPerYear: zod_1.z.number(),
|
11
|
+
installerCompanyName: zod_1.z.string(),
|
12
|
+
});
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
export declare const auditPfeesPaidV1PayloadZ: z.ZodObject<{
|
3
|
+
applicationId: z.ZodString;
|
4
|
+
payer: z.ZodString;
|
5
|
+
amount_12Decimals: z.ZodString;
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
7
|
+
applicationId: string;
|
8
|
+
payer: string;
|
9
|
+
amount_12Decimals: string;
|
10
|
+
}, {
|
11
|
+
applicationId: string;
|
12
|
+
payer: string;
|
13
|
+
amount_12Decimals: string;
|
14
|
+
}>;
|
15
|
+
export type AuditPfeesPaidV1Payload = z.infer<typeof auditPfeesPaidV1PayloadZ>;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.auditPfeesPaidV1PayloadZ = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
const hexBytes32 = /^0x[0-9a-fA-F]{64}$/;
|
6
|
+
const ethAddress = /^0x[0-9a-fA-F]{40}$/;
|
7
|
+
const uint256 = /^[0-9]+$/;
|
8
|
+
exports.auditPfeesPaidV1PayloadZ = zod_1.z.object({
|
9
|
+
applicationId: zod_1.z.string().regex(hexBytes32, "bytes32 hex string"),
|
10
|
+
payer: zod_1.z.string().regex(ethAddress, "Ethereum address"),
|
11
|
+
amount_12Decimals: zod_1.z
|
12
|
+
.string()
|
13
|
+
.regex(uint256, "uint256 (decimal) − 12 implied decimals"),
|
14
|
+
});
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
export declare const auditPfeesPaidV2PayloadZ: z.ZodObject<{
|
3
|
+
farmId: z.ZodString;
|
4
|
+
payer: z.ZodString;
|
5
|
+
amount_12Decimals: z.ZodString;
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
7
|
+
farmId: string;
|
8
|
+
payer: string;
|
9
|
+
amount_12Decimals: string;
|
10
|
+
}, {
|
11
|
+
farmId: string;
|
12
|
+
payer: string;
|
13
|
+
amount_12Decimals: string;
|
14
|
+
}>;
|
15
|
+
export type AuditPfeesPaidV2Payload = z.infer<typeof auditPfeesPaidV2PayloadZ>;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.auditPfeesPaidV2PayloadZ = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
const hexBytes32 = /^0x[0-9a-fA-F]{64}$/;
|
6
|
+
const ethAddress = /^0x[0-9a-fA-F]{40}$/;
|
7
|
+
const uint256 = /^[0-9]+$/;
|
8
|
+
exports.auditPfeesPaidV2PayloadZ = zod_1.z.object({
|
9
|
+
farmId: zod_1.z.string().regex(hexBytes32, "bytes32 hex string"),
|
10
|
+
payer: zod_1.z.string().regex(ethAddress, "Ethereum address"),
|
11
|
+
amount_12Decimals: zod_1.z
|
12
|
+
.string()
|
13
|
+
.regex(uint256, "uint256 (decimal) − 12 implied decimals"),
|
14
|
+
});
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
export declare const auditPushedV1PayloadZ: z.ZodObject<{
|
3
|
+
farmId: z.ZodString;
|
4
|
+
protocolFeeUSDPrice_12Decimals: z.ZodString;
|
5
|
+
expectedProduction_12Decimals: z.ZodString;
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
7
|
+
farmId: string;
|
8
|
+
protocolFeeUSDPrice_12Decimals: string;
|
9
|
+
expectedProduction_12Decimals: string;
|
10
|
+
}, {
|
11
|
+
farmId: string;
|
12
|
+
protocolFeeUSDPrice_12Decimals: string;
|
13
|
+
expectedProduction_12Decimals: string;
|
14
|
+
}>;
|
15
|
+
export type AuditPushedV1Payload = z.infer<typeof auditPushedV1PayloadZ>;
|
@@ -0,0 +1,13 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.auditPushedV1PayloadZ = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
const hexBytes32 = /^0x[0-9a-fA-F]{64}$/;
|
6
|
+
const uint256 = /^[0-9]+$/; // unsigned big‑int as decimal string
|
7
|
+
exports.auditPushedV1PayloadZ = zod_1.z.object({
|
8
|
+
farmId: zod_1.z.string().regex(hexBytes32, "bytes32 hex string"),
|
9
|
+
protocolFeeUSDPrice_12Decimals: zod_1.z
|
10
|
+
.string()
|
11
|
+
.regex(uint256, "uint256 (decimal) − 12 implied decimals"),
|
12
|
+
expectedProduction_12Decimals: zod_1.z.string().regex(uint256),
|
13
|
+
});
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
export declare const auditSlashedV1PayloadZ: z.ZodObject<{
|
3
|
+
farmId: z.ZodString;
|
4
|
+
slasher: z.ZodString;
|
5
|
+
}, "strip", z.ZodTypeAny, {
|
6
|
+
farmId: string;
|
7
|
+
slasher: string;
|
8
|
+
}, {
|
9
|
+
farmId: string;
|
10
|
+
slasher: string;
|
11
|
+
}>;
|
12
|
+
export type AuditSlashedV1Payload = z.infer<typeof auditSlashedV1PayloadZ>;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.auditSlashedV1PayloadZ = void 0;
|
4
|
+
const zod_1 = require("zod");
|
5
|
+
const hexBytes32 = /^0x[0-9a-fA-F]{64}$/;
|
6
|
+
const ethAddress = /^0x[0-9a-fA-F]{40}$/;
|
7
|
+
exports.auditSlashedV1PayloadZ = zod_1.z.object({
|
8
|
+
farmId: zod_1.z.string().regex(hexBytes32, "bytes32 hex string"),
|
9
|
+
slasher: zod_1.z.string().regex(ethAddress, "Ethereum address"),
|
10
|
+
});
|
package/dist/types.d.ts
CHANGED
@@ -1,23 +1,34 @@
|
|
1
|
-
import type {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
import type { BaseEvent } from "./base-event";
|
2
|
+
import type { AuditPushedV1Payload } from "./schemas/audit-pushed.v1";
|
3
|
+
import type { AuditSlashedV1Payload } from "./schemas/audit-slashed.v1";
|
4
|
+
import type { AuditPfeesPaidV1Payload } from "./schemas/audit-pfees-paid.v1";
|
5
|
+
import type { AuditPfeesPaidV2Payload } from "./schemas/audit-pfees-paid.v2";
|
6
|
+
import type { ApplicationCreatedV1Payload } from "./schemas/application-created.v1";
|
7
|
+
export type EventType = BaseEvent["eventType"];
|
8
|
+
type EventTypeToVersion = {
|
9
|
+
"audit.pushed": 1;
|
10
|
+
"audit.slashed": 1;
|
11
|
+
"audit.pfees.paid": 1 | 2;
|
12
|
+
"application.created": 1;
|
13
|
+
};
|
14
|
+
export type EventVersion<T extends EventType> = T extends keyof EventTypeToVersion ? EventTypeToVersion[T] : never;
|
15
|
+
export interface EventPayloadMap {
|
16
|
+
"audit.pushed": {
|
17
|
+
1: AuditPushedV1Payload;
|
18
|
+
};
|
19
|
+
"audit.slashed": {
|
20
|
+
1: AuditSlashedV1Payload;
|
21
|
+
};
|
22
|
+
"audit.pfees.paid": {
|
23
|
+
1: AuditPfeesPaidV1Payload;
|
24
|
+
2: AuditPfeesPaidV2Payload;
|
25
|
+
};
|
26
|
+
"application.created": {
|
27
|
+
1: ApplicationCreatedV1Payload;
|
28
|
+
};
|
8
29
|
}
|
9
|
-
export type
|
10
|
-
export interface
|
11
|
-
|
12
|
-
password: string;
|
13
|
-
permissions: SdkPermission[];
|
14
|
-
}
|
15
|
-
export type GlowListenerEvent = "AuditPushed" | "AuditSlashed";
|
16
|
-
export interface GlowListener {
|
17
|
-
on: <K extends GlowListenerEvent>(event: K, listener: (...args: GlowEvents[K]) => void) => () => void;
|
18
|
-
off: <K extends GlowListenerEvent>(event: K, listener: (...args: GlowEvents[K]) => void) => void;
|
19
|
-
emitAuditPushed?: (data: AuditPushedEvent) => Promise<void>;
|
20
|
-
emitAuditSlashed?: (id: AuditSlashedId) => void;
|
21
|
-
startListener: () => Promise<void>;
|
22
|
-
stopListener: () => Promise<void>;
|
30
|
+
export type EventPayload<T extends EventType, V extends EventVersion<T>> = T extends keyof EventPayloadMap ? V extends keyof EventPayloadMap[T] ? EventPayloadMap[T][V] : never : never;
|
31
|
+
export interface GlowEvent<TPayload> extends Omit<BaseEvent, "payload"> {
|
32
|
+
payload: TPayload;
|
23
33
|
}
|
34
|
+
export {};
|
package/dist/utils.d.ts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
/**
|
2
|
+
* Validates that the zoneName matches the zoneId using the zoneMap.
|
3
|
+
* Throws an error if the values are inconsistent.
|
4
|
+
*/
|
5
|
+
export declare function validateZoneNameAndId(zoneId: number, zoneName: string): void;
|
6
|
+
/**
|
7
|
+
* Validates the event payload against the schema for the given eventType and schemaVersion.
|
8
|
+
* Throws an error if the schema does not exist or the payload is invalid.
|
9
|
+
*/
|
10
|
+
export declare function validateEventPayload(eventType: string, schemaVersion: number, payload: any): void;
|
11
|
+
/**
|
12
|
+
* Processes a message object as the listener would, validating zone and schema.
|
13
|
+
* Throws if validation fails, returns the parsed event otherwise.
|
14
|
+
*/
|
15
|
+
export declare function processEventMessage(msg: {
|
16
|
+
content: Buffer;
|
17
|
+
fields: {
|
18
|
+
routingKey: string;
|
19
|
+
};
|
20
|
+
}): any;
|
package/dist/utils.js
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.validateZoneNameAndId = validateZoneNameAndId;
|
4
|
+
exports.validateEventPayload = validateEventPayload;
|
5
|
+
exports.processEventMessage = processEventMessage;
|
6
|
+
const event_registry_1 = require("./event-registry");
|
7
|
+
const zones_1 = require("./zones");
|
8
|
+
/**
|
9
|
+
* Validates that the zoneName matches the zoneId using the zoneMap.
|
10
|
+
* Throws an error if the values are inconsistent.
|
11
|
+
*/
|
12
|
+
function validateZoneNameAndId(zoneId, zoneName) {
|
13
|
+
if (typeof zoneId === "number" &&
|
14
|
+
String(zoneId) in zones_1.zoneMap &&
|
15
|
+
zoneName !== zones_1.zoneMap[String(zoneId)]) {
|
16
|
+
throw new Error(`zoneName '${zoneName}' does not match zoneId '${zoneId}' (expected '${zones_1.zoneMap[String(zoneId)]}')`);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
/**
|
20
|
+
* Validates the event payload against the schema for the given eventType and schemaVersion.
|
21
|
+
* Throws an error if the schema does not exist or the payload is invalid.
|
22
|
+
*/
|
23
|
+
function validateEventPayload(eventType, schemaVersion, payload) {
|
24
|
+
const schema = (0, event_registry_1.getEventSchema)(eventType, schemaVersion);
|
25
|
+
if (!schema)
|
26
|
+
throw new Error(`No schema for event: ${eventType} v${schemaVersion}`);
|
27
|
+
try {
|
28
|
+
schema.parse(payload);
|
29
|
+
}
|
30
|
+
catch (err) {
|
31
|
+
throw new Error(`Payload does not match schema for event: ${eventType} v${schemaVersion}: ${err.message}`);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
/**
|
35
|
+
* Processes a message object as the listener would, validating zone and schema.
|
36
|
+
* Throws if validation fails, returns the parsed event otherwise.
|
37
|
+
*/
|
38
|
+
function processEventMessage(msg) {
|
39
|
+
const decoded = JSON.parse(msg.content.toString());
|
40
|
+
const [eventType, versionStr] = msg.fields.routingKey.split(".v");
|
41
|
+
const schemaVersion = Number(versionStr);
|
42
|
+
validateZoneNameAndId(decoded.zoneId, decoded.zoneName);
|
43
|
+
validateEventPayload(eventType, schemaVersion, decoded);
|
44
|
+
return (0, event_registry_1.getEventSchema)(eventType, schemaVersion).parse(decoded);
|
45
|
+
}
|
package/dist/zones.d.ts
ADDED
package/dist/zones.js
ADDED