zkc-core
Version:
Work with Zero-Knowledge Credentials
175 lines • 16.4 kB
JavaScript
import { TransformationGraph } from "./graph.js";
import sortKeys from "sort-keys";
export class Preparator {
constructor() {
this.graph = new TransformationGraph();
this.extendGraph = this.graph.extend.bind(this.graph);
this.transform = this.graph.transform.bind(this.graph);
this.sort = sortAttributes;
}
getPreparedAttributes(cred, selector) {
const _selector = selector ? selector : { proof: { index: 0 }, schema: "default" };
const { attributeSchema } = this.selectProof(cred, _selector);
return this.prepareAttributes({
attributes: cred.attributes,
attributesSchema: attributeSchema
});
}
prepareAttributes(args) {
const targetAttr = {
...args.attributes
};
const sortedAttr = sortAttributes(targetAttr);
const sortedSchema = sortAttributes(args.attributesSchema);
const pathValueList = toPathValueList(sortedAttr);
return pathValueList.reduce((result, { value, path }) => {
const links = getByPath(sortedSchema, path);
const transformed = this.graph.transform(value, links);
const lastNode = this.graph.toLastNode(links);
if (lastNode?.spread)
transformed.forEach((it) => result.push(it));
else
result.push(transformed);
return result;
}, []);
}
getPreparedSign(cred, selector) {
const _selector = selector ? selector : { proof: { index: 0 }, schema: "default" };
const { proof: { signature }, signSchema } = this.selectProof(cred, _selector);
return this.prepareSign({
signSchema: signSchema,
signAttributes: signature
});
}
prepareSign(args) {
const sortedSignature = sortSignature(args.signAttributes);
const sortedSchema = sortSignature(args.signSchema);
const pathValueList = toPathValueList(sortedSignature);
return pathValueList.reduce((result, { value, path }) => {
const links = getByPath(sortedSchema, path);
const transformed = this.graph.transform(value, links);
const lastNode = this.graph.toLastNode(links);
if (lastNode?.spread)
transformed.forEach((it) => result.push(it));
else
result.push(transformed);
return result;
}, []);
}
selectProof(cred, selector) {
const _selector = selector ? selector : { proof: { index: 0 }, schema: "default" };
const { proof: { index, id, issuer, type }, schema: schemaName } = _selector;
let proof = undefined;
if (index === 0 || index) {
proof = cred.proofs[index];
}
else if (id) {
proof = cred.proofs.find((it) => it.id === id);
}
else if (issuer && type) {
proof = cred.proofs.find((it) => it.signature.isr.id.t === issuer.id.t &&
it.signature.isr.id.k === issuer.id.k &&
it.type === type);
}
else if (issuer)
proof = cred.proofs.find((it) => it.signature.isr.id.t === issuer.id.t &&
it.signature.isr.id.k === issuer.id.k);
else if (type)
proof = cred.proofs.find((it) => it.type === type);
if (!proof) {
throw new Error(`Can not find proof by selector = ${JSON.stringify(selector)}`);
}
const _schemaName = schemaName ? schemaName : "default";
const attributeSchema = proof.attributeSchemas[_schemaName];
if (!attributeSchema) {
throw new Error(`Can not find transformation schema by selector = ${JSON.stringify(selector)}`);
}
const signSchema = proof.signatureSchemas[_schemaName]
? proof.signatureSchemas[_schemaName]
: proof.signatureSchemas["default"];
if (!signSchema) {
throw new Error(`Can not find sign schema by selector = ${JSON.stringify(selector)}`);
}
return { proof, attributeSchema: attributeSchema, signSchema: signSchema };
}
}
export function toPathValueList(obj) {
return Object.keys(obj).reduce((vector, key) => {
vector.concat(getPathValues(obj, key, vector));
return vector;
}, []);
}
function getPathValues(obj, key, vector, path) {
let target = obj[key];
path = !path ? [key] : path;
if (Array.isArray(target))
target = arrToObj(target);
if (typeof target === "object" && target !== null) {
Object.keys(target).forEach((localKey) => {
getPathValues(target, localKey, vector, path.concat(localKey));
});
}
if (isPrimitive(target)) {
vector.push({ value: target, path: path });
}
return vector;
}
function arrToObj(list) {
return list.reduce((prev, value, index) => {
prev[index] = value;
return prev;
}, {});
}
function isPrimitive(value) {
return ["string", "number", "bigint", "boolean"].includes(typeof value);
}
function getByPath(obj, path) {
let current = obj;
path.forEach((key) => {
current = current[key];
});
return current;
}
function sortAttributes(credential) {
const target = {};
target["sch"] = credential.sch;
target["isd"] = credential.isd;
target["exd"] = credential.exd;
const sbjProps = Object.keys(credential.sbj)
.filter((key) => key !== "id")
.reduce((sbjProps, prop) => {
//@ts-ignore
sbjProps[prop] = credential.sbj[prop];
return sbjProps;
}, {});
target["sbj"] = {
id: {
t: credential.sbj.id.t,
k: credential.sbj.id.k
},
...sortKeys(sbjProps, { deep: true })
};
const otherAttributes = Object.keys(credential)
.filter((key) => !(["isr", "sch", "isd", "exd", "sbj"].includes(key)))
.reduce((result, attribute) => {
// @ts-ignore
result[attribute] = credential[attribute];
return result;
}, {});
return {
...target,
...sortKeys(otherAttributes, { deep: true })
};
}
function sortSignature(attributes) {
const target = {};
target["sign"] = attributes.sign;
target["isr"] = {
id: {
t: attributes.isr.id.t,
k: attributes.isr.id.k
}
};
return target;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlcGFyYXRvci5qcyIsInNvdXJjZVJvb3QiOiIuL3NyYy8iLCJzb3VyY2VzIjpbInByZXBhcmF0b3IvcHJlcGFyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDakQsT0FBTyxRQUFRLE1BQU0sV0FBVyxDQUFDO0FBZ0JqQyxNQUFNLE9BQU8sVUFBVTtJQUF2QjtRQUVtQixVQUFLLEdBQUcsSUFBSSxtQkFBbUIsRUFBRSxDQUFDO1FBRW5ELGdCQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRCxjQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsRCxTQUFJLEdBQUcsY0FBYyxDQUFDO0lBeUh4QixDQUFDO0lBdkhDLHFCQUFxQixDQUduQixJQUFXLEVBQUUsUUFBbUI7UUFDaEMsTUFBTSxTQUFTLEdBQWEsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQztRQUM3RixNQUFNLEVBQUUsZUFBZSxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDOUQsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQU87WUFDbEMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLGdCQUFnQixFQUFFLGVBQWU7U0FDbEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGlCQUFpQixDQUdmLElBR0Q7UUFDQyxNQUFNLFVBQVUsR0FBa0I7WUFDaEMsR0FBRyxJQUFJLENBQUMsVUFBVTtTQUNuQixDQUFDO1FBQ0Ys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