feat: add getEntry and update createEntry to use it
This commit is contained in:
parent
6a3eea92b7
commit
aea236067e
|
@ -33,6 +33,7 @@ import {
|
||||||
} from "./request.js";
|
} from "./request.js";
|
||||||
import {
|
import {
|
||||||
createEntry,
|
createEntry,
|
||||||
|
getEntry,
|
||||||
publishEntry,
|
publishEntry,
|
||||||
subscribeToEntry,
|
subscribeToEntry,
|
||||||
} from "./methods/registry.js";
|
} from "./methods/registry.js";
|
||||||
|
@ -143,6 +144,7 @@ export class S5Client {
|
||||||
subscribeToEntry = subscribeToEntry;
|
subscribeToEntry = subscribeToEntry;
|
||||||
publishEntry = publishEntry;
|
publishEntry = publishEntry;
|
||||||
createEntry = createEntry;
|
createEntry = createEntry;
|
||||||
|
getEntry = getEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The S5 Client which can be used to access S5-net.
|
* The S5 Client which can be used to access S5-net.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { DEFAULT_BASE_OPTIONS } from "../utils/options.js";
|
import { DEFAULT_BASE_OPTIONS } from "../utils/options.js";
|
||||||
import { CustomClientOptions, S5Client } from "../client.js";
|
import { CustomClientOptions, S5Client } from "../client.js";
|
||||||
import { ensureBytes } from "@noble/curves/abstract/utils";
|
import { ensureBytes, equalBytes } from "@noble/curves/abstract/utils";
|
||||||
|
|
||||||
import WS from "isomorphic-ws";
|
import WS from "isomorphic-ws";
|
||||||
import { buildRequestUrl } from "#request.js";
|
import { buildRequestUrl, ExecuteRequestError } from "#request.js";
|
||||||
import {
|
import {
|
||||||
CID,
|
CID,
|
||||||
createKeyPair,
|
createKeyPair,
|
||||||
|
@ -19,6 +19,7 @@ import {
|
||||||
import { Buffer } from "buffer";
|
import { Buffer } from "buffer";
|
||||||
import { throwValidationError } from "../utils/validation.js";
|
import { throwValidationError } from "../utils/validation.js";
|
||||||
import { base64url } from "multiformats/bases/base64";
|
import { base64url } from "multiformats/bases/base64";
|
||||||
|
|
||||||
export const DEFAULT_GET_ENTRY_OPTIONS = {
|
export const DEFAULT_GET_ENTRY_OPTIONS = {
|
||||||
...DEFAULT_BASE_OPTIONS,
|
...DEFAULT_BASE_OPTIONS,
|
||||||
endpointGetEntry: "/s5/registry",
|
endpointGetEntry: "/s5/registry",
|
||||||
|
@ -91,6 +92,7 @@ export async function subscribeToEntry(
|
||||||
}
|
}
|
||||||
|
|
||||||
const base64urlEncode = (d: Uint8Array) => base64url.encode(d).substring(1);
|
const base64urlEncode = (d: Uint8Array) => base64url.encode(d).substring(1);
|
||||||
|
const base64urlDecode = (d: string) => base64url.decode(`u${d}`);
|
||||||
|
|
||||||
export async function publishEntry(
|
export async function publishEntry(
|
||||||
this: S5Client,
|
this: S5Client,
|
||||||
|
@ -135,15 +137,81 @@ export async function createEntry(
|
||||||
sk = createKeyPair(sk);
|
sk = createKeyPair(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
const entry = {
|
let entry = await this.getEntry(sk.publicKey);
|
||||||
kp: sk,
|
|
||||||
|
if (!entry) {
|
||||||
|
entry = {
|
||||||
|
pk: sk,
|
||||||
data: cid.toRegistryEntry(),
|
data: cid.toRegistryEntry(),
|
||||||
revision,
|
revision,
|
||||||
};
|
} as unknown as SignedRegistryEntry;
|
||||||
|
} else {
|
||||||
|
if (!equalBytes(sk.publicKey, entry.pk)) {
|
||||||
|
throwValidationError(
|
||||||
|
"entry.pk", // name of the variable
|
||||||
|
Buffer.from(entry.pk).toString("hex"), // actual value
|
||||||
|
"result", // valueKind (assuming it's a function parameter)
|
||||||
|
Buffer.from(sk.publicKey).toString("hex"), // expected description
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const signedEntry = signRegistryEntry(entry);
|
entry.revision++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const signedEntry = signRegistryEntry({
|
||||||
|
kp: sk,
|
||||||
|
data: entry.data,
|
||||||
|
revision: entry.revision,
|
||||||
|
});
|
||||||
|
|
||||||
await this.publishEntry(signedEntry);
|
await this.publishEntry(signedEntry);
|
||||||
|
|
||||||
return signedEntry;
|
return signedEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getEntry(
|
||||||
|
this: S5Client,
|
||||||
|
publicKey: Uint8Array,
|
||||||
|
customOptions?: CustomRegistryOptions,
|
||||||
|
) {
|
||||||
|
const opts = {
|
||||||
|
...DEFAULT_GET_ENTRY_OPTIONS,
|
||||||
|
...this.customOptions,
|
||||||
|
...customOptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ret = await this.executeRequest({
|
||||||
|
...opts,
|
||||||
|
endpointPath: opts.endpointGetEntry,
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
pk: base64urlEncode(publicKey),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const signedEntry = {
|
||||||
|
pk: base64urlDecode(ret.data.pk),
|
||||||
|
revision: ret.data.revision,
|
||||||
|
data: base64urlDecode(ret.data.data),
|
||||||
|
signature: base64urlDecode(ret.data.signature),
|
||||||
|
} as SignedRegistryEntry;
|
||||||
|
|
||||||
|
if (!verifyRegistryEntry(signedEntry)) {
|
||||||
|
throwValidationError(
|
||||||
|
"signedEntry", // name of the variable
|
||||||
|
signedEntry, // actual value
|
||||||
|
"result", // valueKind (assuming it's a function parameter)
|
||||||
|
"a valid signed registry entry", // expected description
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedEntry;
|
||||||
|
} catch (e) {
|
||||||
|
if ((e as ExecuteRequestError).responseStatus === 404) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue