From fa04bb5e3066ed8efba083db55f31145c21f41ee Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Fri, 1 Sep 2023 08:33:32 -0400 Subject: [PATCH] feat: add getRegistryEntry, setRegistryEntry, registrySubscription --- npm-shrinkwrap.json | 16 ++++---- package.json | 2 +- src/index.ts | 96 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index e6dc91a..9e2f60f 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -11,7 +11,7 @@ "@lumeweb/kernel-protomux-client": "^0.0.2-develop.16", "@lumeweb/kernel-swarm-client": "^0.1.0-develop.5", "@lumeweb/libkernel": "^0.1.0-develop.36", - "@lumeweb/libs5-transport-hyper": "^0.1.0-develop.10", + "@lumeweb/libs5-transport-hyper": "^0.1.0-develop.16", "whatwg-url": "^13.0.0" }, "devDependencies": { @@ -1747,9 +1747,9 @@ } }, "node_modules/@lumeweb/libs5": { - "version": "0.1.0-develop.17", - "resolved": "https://registry.npmjs.org/@lumeweb/libs5/-/libs5-0.1.0-develop.17.tgz", - "integrity": "sha512-P+tno8umL8ir5ZxMnBG0SOn1Y9x5e6ar1jSDDJpj+gfyskvMFygzzqQlvcQa39pLHxLkQg48X6xjziPjEarVew==", + "version": "0.1.0-develop.24", + "resolved": "https://registry.npmjs.org/@lumeweb/libs5/-/libs5-0.1.0-develop.24.tgz", + "integrity": "sha512-d2QP9t6/+Cilzt102Jk1baJW/sSXKOOd0tFyR7EnkFVry6HA/6HCoOGXy6/V1IpFPo0JfH63M/bi4nLNfPfcjg==", "dependencies": { "@noble/curves": "^1.1.0", "@noble/hashes": "^1.3.1", @@ -1761,11 +1761,11 @@ } }, "node_modules/@lumeweb/libs5-transport-hyper": { - "version": "0.1.0-develop.10", - "resolved": "https://registry.npmjs.org/@lumeweb/libs5-transport-hyper/-/libs5-transport-hyper-0.1.0-develop.10.tgz", - "integrity": "sha512-LYuyWBOrbhg3jR18hF/ZttARApsqsXWrFTNYCbV/H3weYLahAZX+I5Ko943d3ApbWhUPTEFo0Gbe5T5/Ajc0Eg==", + "version": "0.1.0-develop.16", + "resolved": "https://registry.npmjs.org/@lumeweb/libs5-transport-hyper/-/libs5-transport-hyper-0.1.0-develop.16.tgz", + "integrity": "sha512-3Qo0lPF6oK3Uxh+cxxLSSyn+5ZyAd4zSp1SmJhifn76yypvhID5Rc9zwpAV+4m8EHWO4CBwu4xCn25wArLKKNA==", "dependencies": { - "@lumeweb/libs5": "^0.1.0-develop.17", + "@lumeweb/libs5": "^0.1.0-develop.24", "streamx": "^2.15.1" } }, diff --git a/package.json b/package.json index 9837b4a..4cab251 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@lumeweb/kernel-protomux-client": "^0.0.2-develop.16", "@lumeweb/kernel-swarm-client": "^0.1.0-develop.5", "@lumeweb/libkernel": "^0.1.0-develop.36", - "@lumeweb/libs5-transport-hyper": "^0.1.0-develop.10", + "@lumeweb/libs5-transport-hyper": "^0.1.0-develop.16", "whatwg-url": "^13.0.0" }, "devDependencies": { diff --git a/src/index.ts b/src/index.ts index 1d8f6a4..8b7236d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { concatBytes } from "@lumeweb/libkernel"; +import { concatBytes, ensureBytes } from "@lumeweb/libkernel"; import { addHandler, defer, @@ -6,7 +6,10 @@ import { handlePresentKey as handlePresentKeyModule, } from "@lumeweb/libkernel/module"; import type { ActiveQuery } from "@lumeweb/libkernel/module"; -import { createClient as createSwarmClient } from "@lumeweb/kernel-swarm-client"; +import { + createClient as createSwarmClient, + SwarmClient, +} from "@lumeweb/kernel-swarm-client"; import Protomux from "@lumeweb/kernel-protomux-client"; import { createKeyPair, @@ -14,7 +17,9 @@ import { NodeId, S5NodeConfig, } from "@lumeweb/libs5"; -import { mkeyEd25519 } from "@lumeweb/libs5/lib/constants.js"; +import { mkeyEd25519 } from "@lumeweb/libs5"; +import type { S5Node } from "@lumeweb/libs5"; +import KeyPairEd25519 from "@lumeweb/libs5/lib/ed25519.js"; import { Level } from "level"; import HyperTransportPeer from "@lumeweb/libs5-transport-hyper"; @@ -22,10 +27,16 @@ const PROTOCOL = "lumeweb.service.s5"; const moduleReadyDefer = defer(); -let swarm; +let swarm: SwarmClient; +let node: S5Node; addHandler("presentKey", handlePresentKey); addHandler("ready", ready); +addHandler("getRegistryEntry", handleGetRegistryEntry); +addHandler("setRegistryEntry", handleSetRegistryEntry); +addHandler("registrySubscription", handleRegistrySubscription, { + receiveUpdates: true, +}); async function handlePresentKey(aq: ActiveQuery) { handlePresentKeyModule({ @@ -58,7 +69,7 @@ async function setup() { await swarm.start(); await swarm.ready(); - const node = createNode(config); + node = createNode(config); await node.start(); @@ -78,8 +89,83 @@ async function setup() { node.services.p2p.onNewPeer(s5peer, true); }); } + async function ready(aq: ActiveQuery) { await moduleReadyDefer.promise; aq.respond(); } + +async function handleGetRegistryEntry(aq: ActiveQuery) { + if (!("pubkey" in aq.callerInput)) { + aq.reject("pubkey required"); + } + + await moduleReadyDefer.promise; + + let { pubkey } = aq.callerInput; + + pubkey = ensureBytes("registry entry ", pubkey, 32); + + const ret = await node.services.registry.get(pubkey); + + if (!ret) { + aq.reject("could not find registry entry"); + return; + } + + aq.respond(ret); +} +async function handleSetRegistryEntry(aq: ActiveQuery) { + for (const field of ["key", "data", "revision"]) { + if (!(field in aq.callerInput)) { + aq.reject(`${field} required`); + return; + } + } + + await moduleReadyDefer.promise; + + let { key, data, revision } = aq.callerInput; + + key = ensureBytes("registry entry private key", key, 32); + + const sre = node.services.registry.signRegistryEntry({ + kp: new KeyPairEd25519(key), + data, + revision, + }); + + try { + await node.services.registry.set(sre); + aq.respond(sre); + } catch (e) { + aq.reject(e); + } +} + +async function handleRegistrySubscription(aq: ActiveQuery) { + if (!("pubkey" in aq.callerInput)) { + aq.reject("pubkey required"); + } + + await moduleReadyDefer.promise; + + let { pubkey } = aq.callerInput; + + pubkey = ensureBytes("registry entry ", pubkey, 32); + + const wait = defer(); + + const done = node.services.registry.listen(pubkey, (sre) => { + aq.sendUpdate(sre); + }); + + aq.setReceiveUpdate?.(() => { + done(); + wait.resolve(); + }); + + await wait.promise; + aq.respond(); +}