mina-attestations
Version:
Private Attestations on Mina
232 lines • 7.58 kB
JavaScript
import { Claim, Constant } from "./program-spec.js";
import { serializeNestedProvableType, serializeProvableValue, serializeProvableType, deserializeNestedProvable, deserializeProvableValue, deserializeProvableType, } from "./serialize-provable.js";
import { assert, mapObject } from "./util.js";
import { Credential } from "./credential-index.js";
export { serializeNode, deserializeNode, serializeInput, deserializeInput, serializeSpec, deserializeSpec, };
function serializeSpec(spec) {
return {
inputs: mapObject(spec.inputs, (input) => serializeInput(input)),
assert: serializeNode(spec.assert),
outputClaim: serializeNode(spec.outputClaim),
};
}
function deserializeSpec(spec) {
let inputs = mapObject(spec.inputs, (input) => deserializeInput(input));
return {
inputs,
assert: deserializeNode(inputs, spec.assert),
outputClaim: deserializeNode(inputs, spec.outputClaim),
};
}
function serializeInput(input) {
switch (input.type) {
case 'constant': {
return {
type: 'constant',
data: serializeProvableType(input.data),
value: serializeProvableValue(input.value).value,
};
}
case 'claim': {
return {
type: 'claim',
data: serializeNestedProvableType(input.data),
};
}
default: {
assert('credentialType' in input, 'Invalid input type');
return Credential.specToJSON(input);
}
}
}
function deserializeInput(input) {
let type = input.type;
switch (input.type) {
case 'constant':
return Constant(deserializeProvableType(input.data), deserializeProvableValue({ ...input.data, value: input.value }));
case 'claim':
return Claim(deserializeNestedProvable(input.data));
case 'credential': {
return Credential.specFromJSON(input);
}
default:
throw Error(`Invalid input type: ${type}`);
}
}
function serializeNode(node) {
switch (node.type) {
case 'constant': {
return {
type: 'constant',
data: serializeProvableValue(node.data),
};
}
case 'root': {
return { type: 'root' };
}
case 'owner':
case 'credential':
case 'issuer':
case 'issuerPublicKey':
case 'verificationKeyHash':
case 'publicInput':
return node;
case 'property': {
return {
type: 'property',
key: node.key,
inner: serializeNode(node.inner),
};
}
case 'and':
return {
type: node.type,
inputs: node.inputs.map(serializeNode),
};
case 'equals':
case 'lessThan':
case 'lessThanEq':
case 'or':
case 'add':
case 'sub':
case 'mul':
case 'div':
return {
type: node.type,
left: serializeNode(node.left),
right: serializeNode(node.right),
};
case 'equalsOneOf': {
return {
type: 'equalsOneOf',
input: serializeNode(node.input),
options: Array.isArray(node.options)
? node.options.map(serializeNode)
: serializeNode(node.options),
};
}
case 'hash':
return {
type: node.type,
inputs: node.inputs.map(serializeNode),
prefix: node.prefix ?? null,
};
case 'not':
return {
type: node.type,
inner: serializeNode(node.inner),
};
case 'ifThenElse':
return {
type: 'ifThenElse',
condition: serializeNode(node.condition),
thenNode: serializeNode(node.thenNode),
elseNode: serializeNode(node.elseNode),
};
case 'record': {
const serializedData = {};
for (const [key, value] of Object.entries(node.data)) {
serializedData[key] = serializeNode(value);
}
return {
type: 'record',
data: serializedData,
};
}
case 'compute':
throw Error('Cannot serialize compute node');
default:
node;
throw Error(`Invalid node type: ${node.type}`);
}
}
function deserializeNode(root, node) {
let type = node.type;
switch (node.type) {
case 'constant':
return {
type: 'constant',
data: deserializeProvableValue(node.data),
};
case 'root':
return { type: 'root', input: root };
case 'owner':
case 'credential':
case 'issuer':
case 'issuerPublicKey':
case 'verificationKeyHash':
case 'publicInput':
return node;
case 'property':
return {
type: 'property',
key: node.key,
inner: deserializeNode(root, node.inner),
};
case 'equals':
case 'lessThan':
case 'lessThanEq':
return {
type: node.type,
left: deserializeNode(root, node.left),
right: deserializeNode(root, node.right),
};
case 'equalsOneOf': {
return {
type: 'equalsOneOf',
input: deserializeNode(root, node.input),
options: Array.isArray(node.options)
? node.options.map((o) => deserializeNode(root, o))
: deserializeNode(root, node.options),
};
}
case 'and':
return {
type: node.type,
inputs: node.inputs.map((i) => deserializeNode(root, i)),
};
case 'or':
case 'add':
case 'sub':
case 'mul':
case 'div':
return {
type: node.type,
left: deserializeNode(root, node.left),
right: deserializeNode(root, node.right),
};
case 'hash':
let result = {
type: node.type,
inputs: node.inputs.map((i) => deserializeNode(root, i)),
};
if (node.prefix !== null)
result.prefix = node.prefix;
return result;
case 'not':
return {
type: node.type,
inner: deserializeNode(root, node.inner),
};
case 'ifThenElse':
return {
type: 'ifThenElse',
condition: deserializeNode(root, node.condition),
thenNode: deserializeNode(root, node.thenNode),
elseNode: deserializeNode(root, node.elseNode),
};
case 'record':
const deserializedData = {};
for (const [key, value] of Object.entries(node.data)) {
deserializedData[key] = deserializeNode(root, value);
}
return {
type: 'record',
data: deserializedData,
};
default:
node;
throw Error(`Invalid node type: ${type}`);
}
}
//# sourceMappingURL=serialize-spec.js.map