rpc-client/dist/util.js

91 lines
3.0 KiB
JavaScript
Raw Normal View History

2022-12-04 07:42:04 +00:00
// @ts-ignore
import stringify from "json-stringify-deterministic";
// @ts-ignore
import crypto from "hypercore-crypto";
2022-12-04 10:39:59 +00:00
// @ts-ignore
import sodium from "sodium-universal";
2022-12-04 07:42:04 +00:00
import b4a from "b4a";
2023-03-19 14:35:54 +00:00
import RPC from "@lumeweb/rpc";
2023-03-19 15:10:57 +00:00
export const RPC_PROTOCOL_SYMBOL = Symbol.for("lumeweb");
2022-12-04 07:42:04 +00:00
export function isPromise(obj) {
return (!!obj &&
(typeof obj === "object" || typeof obj === "function") &&
typeof obj.then === "function");
2022-08-01 03:02:03 +00:00
}
/*
Forked from https://github.com/hughsk/flat
*/
export function flatten(target, opts = {}) {
opts = opts || {};
const delimiter = opts.delimiter || ".";
const maxDepth = opts.maxDepth;
const transformKey = opts.transformKey || ((key) => (isNaN(parseInt(key)) ? key : ""));
const output = [];
function step(object, prev, currentDepth) {
currentDepth = currentDepth || 1;
2022-08-01 03:11:31 +00:00
if (!Array.isArray(object)) {
2022-08-14 13:27:02 +00:00
object = Object.keys(object ?? {});
2022-08-01 03:11:31 +00:00
}
object.forEach(function (key) {
2022-08-01 03:02:03 +00:00
const value = object[key];
const isarray = opts.safe && Array.isArray(value);
const type = Object.prototype.toString.call(value);
2022-12-04 07:42:04 +00:00
const isbuffer = b4a.isBuffer(value);
2022-08-01 03:02:03 +00:00
const isobject = type === "[object Object]" || type === "[object Array]";
const newKey = prev
? prev + delimiter + transformKey(key)
: transformKey(key);
if (!isarray &&
!isbuffer &&
isobject &&
Object.keys(value).length &&
(!opts.maxDepth || currentDepth < maxDepth)) {
return step(value, newKey, currentDepth + 1);
}
output.push(`${newKey}=${value}`);
});
}
step(target);
return output;
}
2022-12-04 07:42:04 +00:00
export function validateResponse(relay, response, timestamped = false) {
const field = response.signedField || "data";
// @ts-ignore
2023-03-18 16:11:41 +00:00
let json = response[field];
2022-12-04 07:42:04 +00:00
if (typeof json !== "string") {
json = stringify(json);
}
const updated = response.updated;
if (timestamped && updated) {
json = updated.toString() + json;
}
return !!crypto.verify(b4a.from(json), b4a.from(response.signature, "hex"), relay);
}
export function validateTimestampedResponse(relay, response) {
return validateResponse(relay, response, true);
2022-08-27 19:13:00 +00:00
}
2022-12-04 10:39:59 +00:00
export function hashQuery(query) {
const clonedQuery = {
module: query.module,
method: query.method,
data: query.data,
};
const queryHash = Buffer.allocUnsafe(32);
sodium.crypto_generichash(queryHash, Buffer.from(stringify(clonedQuery)));
return queryHash.toString("hex");
}
2023-03-18 16:11:41 +00:00
export function createHash(data) {
const buffer = b4a.from(data);
let hash = b4a.allocUnsafe(32);
sodium.crypto_generichash(hash, buffer);
return hash;
}
2023-03-19 14:35:54 +00:00
export function setupStream(stream) {
const existing = stream[RPC_PROTOCOL_SYMBOL];
if (existing) {
return existing;
}
stream[RPC_PROTOCOL_SYMBOL] = new RPC(stream);
return stream[RPC_PROTOCOL_SYMBOL];
}