mina-attestations
Version:
Private Attestations on Mina
143 lines • 4.81 kB
JavaScript
import { Field, initializeBindings, } from 'o1js';
import { createUnsigned, hashCredential, Unsigned, } from "./credential.js";
import { createNative, Native, } from "./credential-native.js";
import { Imported, ImportedWitnessSpec, } from "./credential-imported.js";
import { assert, hasProperty } from "./util.js";
import { deserializeNestedProvable, deserializeNestedProvableValue, serializeNestedProvableType, serializeNestedProvableValue, } from "./serialize-provable.js";
import { Schema } from "./dynamic/schema.js";
import { credentialSpecWithVk, StoredCredentialSchema, } from "./validation.js";
export { Credential };
const Credential = {
Unsigned,
Native,
Imported,
/**
* Issue a "native" signed credential.
*/
sign: createNative,
/**
* Create a dummy credential with no owner and no signature.
*/
unsigned: createUnsigned,
/**
* Serialize a credential to a JSON string.
*/
toJSON(credential) {
let json = {
version: credential.version,
witness: credential.witness === undefined
? { type: 'unsigned' }
: serializeNestedProvableValue(credential.witness),
metadata: credential.metadata,
credential: serializeNestedProvableValue(credential.credential),
};
return JSON.stringify(json);
},
/**
* Deserialize a credential from a JSON string.
*/
async fromJSON(json) {
await initializeBindings();
let obj = JSON.parse(json);
let parsed = StoredCredentialSchema.parse(obj);
return {
version: parsed.version,
witness: deserializeNestedProvableValue(parsed.witness),
metadata: parsed.metadata,
credential: deserializeNestedProvableValue(parsed.credential),
};
},
/**
* Validate a credential.
*/
validate: validateCredential,
specToJSON,
specFromJSON,
/**
* Serialize the data input to a `signCredential()` call.
*
* The resulting string is accepted as input to `Credential.sign()`.
*
* Example
* ```ts
* let credentialData = { owner: publicKey, data: { name: 'Alice' } };
* let credentialDataJson = Credential.dataToJSON(credentialData);
*
* let credential = Credential.sign(privateKey, credentialDataJson);
* ```
*/
dataToJSON(credential) {
return JSON.stringify(serializeNestedProvableValue(credential));
},
importedToJSON,
importedFromJSON,
};
async function validateCredential(credential) {
let { version, witness, credential: { data }, } = credential;
assert(version === 'v0', `Unsupported credential version: ${version}`);
assert(knownWitness(witness), 'Unknown credential type');
let credHash = hashCredential(credential.credential);
if (witness.type === 'native') {
const spec = Native(Schema.nestedType(data));
await spec.validate(witness, credHash);
}
if (witness.type === 'imported') {
await Imported.Generic.validate(witness, credHash);
}
}
const witnessTypes = new Set([
'native',
'imported',
]);
function knownWitness(witness) {
return hasProperty(witness, 'type') && witnessTypes.has(witness.type);
}
/**
* Serialize a credential spec to a JSON value.
*/
function specToJSON(spec) {
return {
type: 'credential',
credentialType: spec.credentialType,
witness: spec.witness === undefined
? null
: ImportedWitnessSpec.toJSON(spec.witness),
data: serializeNestedProvableType(spec.data),
};
}
/**
* Deserialize a credential spec from a JSON value.
*/
function specFromJSON(json) {
let data = deserializeNestedProvable(json.data);
switch (json.credentialType) {
case 'native':
return Native(data);
case 'unsigned':
return Unsigned(data);
case 'imported':
assert(json.witness !== null, 'Missing witness');
let witness = ImportedWitnessSpec.fromJSON(json.witness);
return Imported.create({ data, witness });
default:
throw Error(`Unsupported credential id: ${json.credentialType}`);
}
}
function importedToJSON({ spec, verificationKey: vk, }) {
assert(vk !== undefined, 'Verification key not found');
return {
spec: specToJSON(spec),
verificationKey: { data: vk.data, hash: vk.hash.toString() },
};
}
function importedFromJSON(json) {
let { spec, verificationKey } = credentialSpecWithVk.parse(json);
return {
spec: specFromJSON(spec),
verificationKey: {
data: verificationKey.data,
hash: Field(verificationKey.hash),
},
};
}
//# sourceMappingURL=credential-index.js.map