Compare commits
3 Commits
v0.1.0-dev
...
v0.1.0-dev
Author | SHA1 | Date |
---|---|---|
semantic-release-bot | 236bae5a90 | |
Derrick Hammer | 68f9c91c62 | |
Derrick Hammer | aea236067e |
|
@ -1,3 +1,10 @@
|
||||||
|
# [0.1.0-develop.16](https://git.lumeweb.com/LumeWeb/s5-js/compare/v0.1.0-develop.15...v0.1.0-develop.16) (2023-12-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add getEntry and update createEntry to use it ([aea2360](https://git.lumeweb.com/LumeWeb/s5-js/commit/aea236067e6011502f6df2ec9856597b9fe5b1a9))
|
||||||
|
|
||||||
# [0.1.0-develop.15](https://git.lumeweb.com/LumeWeb/s5-js/compare/v0.1.0-develop.14...v0.1.0-develop.15) (2023-12-12)
|
# [0.1.0-develop.15](https://git.lumeweb.com/LumeWeb/s5-js/compare/v0.1.0-develop.14...v0.1.0-develop.15) (2023-12-12)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@lumeweb/s5-js",
|
"name": "@lumeweb/s5-js",
|
||||||
"version": "0.1.0-develop.15",
|
"version": "0.1.0-develop.16",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@lumeweb/s5-js",
|
"name": "@lumeweb/s5-js",
|
||||||
"version": "0.1.0-develop.15",
|
"version": "0.1.0-develop.16",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lumeweb/libs5": "^0.1.0-develop.81",
|
"@lumeweb/libs5": "^0.1.0-develop.81",
|
||||||
"@noble/hashes": "^1.3.2",
|
"@noble/hashes": "^1.3.2",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@lumeweb/s5-js",
|
"name": "@lumeweb/s5-js",
|
||||||
"version": "0.1.0-develop.15",
|
"version": "0.1.0-develop.16",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "lib/index.js",
|
"module": "lib/index.js",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
|
|
|
@ -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,
|
|
||||||
data: cid.toRegistryEntry(),
|
|
||||||
revision,
|
|
||||||
};
|
|
||||||
|
|
||||||
const signedEntry = signRegistryEntry(entry);
|
if (!entry) {
|
||||||
|
entry = {
|
||||||
|
pk: sk,
|
||||||
|
data: cid.toRegistryEntry(),
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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