diff --git a/src/client.ts b/src/client.ts index f78f564..5aa405b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -31,7 +31,7 @@ import { ExecuteRequestError, Headers, } from "./request.js"; -import { subscribeToEntry } from "./methods/registry.js"; +import { publishEntry, subscribeToEntry } from "./methods/registry.js"; /** * Custom client options. @@ -137,6 +137,7 @@ export class S5Client { // Registry subscribeToEntry = subscribeToEntry; + publishEntry = publishEntry; /** * The S5 Client which can be used to access S5-net. diff --git a/src/methods/registry.ts b/src/methods/registry.ts index 1cfa112..d71e286 100644 --- a/src/methods/registry.ts +++ b/src/methods/registry.ts @@ -5,8 +5,13 @@ import { ensureBytes } from "@noble/curves/abstract/utils"; import WS from "isomorphic-ws"; import { buildRequestUrl } from "#request.js"; import { Packer, SignedRegistryEntry } from "@lumeweb/libs5"; -import { deserializeRegistryEntry } from "@lumeweb/libs5/lib/service/registry.js"; +import { + deserializeRegistryEntry, + verifyRegistryEntry, +} from "@lumeweb/libs5/lib/service/registry.js"; import { Buffer } from "buffer"; +import { throwValidationError } from "../utils/validation.js"; +import { base64url } from "multiformats/bases/base64"; export const DEFAULT_GET_ENTRY_OPTIONS = { ...DEFAULT_BASE_OPTIONS, endpointGetEntry: "/s5/registry", @@ -23,10 +28,16 @@ export const DEFAULT_SUBSCRIBE_ENTRY_OPTIONS = { endpointSubscribeEntry: "/s5/registry/subscription", }; +export const DEFAULT_PUBLISH_ENTRY_OPTIONS = { + ...DEFAULT_BASE_OPTIONS, + endpointPublishEntry: "/s5/registry", +}; + export type BaseCustomOptions = CustomClientOptions; export type CustomRegistryOptions = BaseCustomOptions & { endpointSubscribeEntry?: string; + endpointPublishEntry?: string; }; export async function subscribeToEntry( @@ -71,3 +82,36 @@ export async function subscribeToEntry( }, }; } + +export async function publishEntry( + this: S5Client, + signedEntry: SignedRegistryEntry, + customOptions?: CustomRegistryOptions, +) { + const opts = { + ...DEFAULT_PUBLISH_ENTRY_OPTIONS, + ...this.customOptions, + ...customOptions, + }; + + if (!verifyRegistryEntry(signedEntry)) { + throwValidationError( + "signedEntry", // name of the variable + signedEntry, // actual value + "parameter", // valueKind (assuming it's a function parameter) + "a valid signed registry entry", // expected description + ); + } + + return await this.executeRequest({ + ...opts, + endpointPath: opts.endpointPublishEntry, + method: "post", + data: { + pk: base64url.encode(signedEntry.pk), + revision: signedEntry.revision, + data: base64url.encode(signedEntry.data), + signature: base64url.encode(signedEntry.signature), + }, + }); +}