2024-11-13 12:23:58 +07:00

106 lines
3.4 KiB
TypeScript

import { createEncoder, createDecoder, type LightNode, type CreateWakuNodeOptions } from "@waku/sdk";
import protobuf from 'protobufjs';
export const WAKU_NODE_OPTIONS: CreateWakuNodeOptions = { defaultBootstrap: true, nodeToUse: {store: "/dns4/boot-01.do-ams3.status.staging.status.im/tcp/443/wss/p2p/16Uiu2HAmEqqio4UR1SWqAc7KY19t6qyDvtmyjreZpzUBJvb4u65R"} };
export type Signature = {
address: `0x${string}`;
signature: string;
};
export type BlockPayload = {
chainUUID: string;
blockUUID: string;
title: string;
description: string;
signedMessage: string;
timestamp: number;
signatures: Signature[];
parentBlockUUID: string | null;
}
const contentTopic = "/buddybook-devcon/1/chain/proto";
export const encoder = createEncoder({
contentTopic: contentTopic,
ephemeral: false
});
export const decoder = createDecoder(contentTopic);
export const block = new protobuf.Type("block")
.add(new protobuf.Field("chainUUID", 1, "string"))
.add(new protobuf.Field("blockUUID", 2, "string"))
.add(new protobuf.Field("title", 3, "string"))
.add(new protobuf.Field("description", 4, "string"))
.add(new protobuf.Field("signedMessage", 5, "string"))
.add(new protobuf.Field("timestamp", 6, "uint64"))
.add(new protobuf.Field("signatures", 7, "string", "repeated"))
.add(new protobuf.Field("parentBlockUUID", 8, "string"));
export function createMessage({
chainUUID,
blockUUID,
title,
description,
signedMessage,
timestamp,
signatures,
parentBlockUUID
}: BlockPayload) {
const protoMessage = block.create({
chainUUID,
blockUUID,
title,
description,
signedMessage,
timestamp,
signatures: signatures.map(s => JSON.stringify(s)),
parentBlockUUID
});
const payload = block.encode(protoMessage).finish();
return { payload: payload };
}
export async function* getMessagesFromStore(node: LightNode) {
console.time("getMessagesFromStore")
try {
for await (const messagePromises of node.store.queryGenerator([decoder])) {
const messages = await Promise.all(messagePromises);
for (const message of messages) {
if (!message?.payload) continue;
const blockPayload = block.decode(message.payload) as unknown as BlockPayload;
blockPayload.signatures = blockPayload.signatures.map(s => JSON.parse(s as unknown as string) as Signature);
yield blockPayload;
}
}
} finally {
console.timeEnd("getMessagesFromStore")
}
}
export async function subscribeToFilter(node: LightNode, callback: (message: BlockPayload) => void) {
const {error, subscription, results} = await node.filter.subscribe(
[decoder],
(message) => {
console.log('message received from filter', message)
if (message.payload) {
const blockPayload = block.decode(message.payload) as unknown as BlockPayload;
blockPayload.signatures = blockPayload.signatures.map(s => JSON.parse(s as unknown as string) as Signature);
callback(blockPayload);
}
}
);
console.log("results", results)
if (error) {
console.log("Error subscribing to filter", error)
}
if (!subscription || error || results.successes.length === 0 || results.failures.length > 0) {
throw new Error("Failed to subscribe to filter")
}
}