UNPKG

@bsv/wallet-toolbox-client

Version:
116 lines 5.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseResults = exports.queryOverlay = exports.transformVerifiableCertificatesWithTrust = void 0; const sdk_1 = require("@bsv/sdk"); const OUTPUT_INDEX = 0; /** * Transforms an array of VerifiableCertificate instances according to the trust settings. * Only certificates whose grouped total trust meets the threshold are returned, * and each certificate is augmented with a certifierInfo property. * * @param trustSettings - the user's trust settings including trustLevel and trusted certifiers. * @param certificates - an array of VerifiableCertificate objects. * @returns a DiscoverCertificatesResult with totalCertificates and ordered certificates. */ const transformVerifiableCertificatesWithTrust = (trustSettings, certificates) => { // Group certificates by subject while accumulating trust. const identityGroups = {}; // Cache certifier lookups. const certifierCache = {}; certificates.forEach(cert => { const { subject, certifier } = cert; if (!subject || !certifier) return; // Lookup and cache certifier details from trustSettings. if (!certifierCache[certifier]) { const found = trustSettings.trustedCertifiers.find(x => x.identityKey === certifier); if (!found) return; // Skip this certificate if its certifier is not trusted. certifierCache[certifier] = found; } // Create the IdentityCertifier object that we want to attach. const certifierInfo = { name: certifierCache[certifier].name, iconUrl: certifierCache[certifier].iconUrl || '', description: certifierCache[certifier].description, trust: certifierCache[certifier].trust }; // Create an extended certificate that includes certifierInfo. // Note: We use object spread to copy over all properties from the original certificate. const extendedCert = { ...cert, signature: cert.signature, // We know it exists at this point decryptedFields: cert.decryptedFields, publiclyRevealedKeyring: cert.keyring, certifierInfo }; // Group certificates by subject. if (!identityGroups[subject]) { identityGroups[subject] = { totalTrust: 0, members: [] }; } identityGroups[subject].totalTrust += certifierInfo.trust; identityGroups[subject].members.push(extendedCert); }); // Filter out groups that do not meet the trust threshold and flatten the results. const finalResults = []; Object.values(identityGroups).forEach(group => { if (group.totalTrust >= trustSettings.trustLevel) { finalResults.push(...group.members); } }); // Sort the certificates by their certifier trust in descending order. finalResults.sort((a, b) => b.certifierInfo.trust - a.certifierInfo.trust); return { totalCertificates: finalResults.length, certificates: finalResults }; }; exports.transformVerifiableCertificatesWithTrust = transformVerifiableCertificatesWithTrust; /** * Performs an identity overlay service lookup query and returns the parsed results * * @param query * @returns */ const queryOverlay = async (query, resolver) => { const results = await resolver.query({ service: 'ls_identity', query }); return await (0, exports.parseResults)(results); }; exports.queryOverlay = queryOverlay; /** * Internal func: Parse the returned UTXOs Decrypt and verify the certificates and signatures Return the set of identity keys, certificates and decrypted certificate fields * * @param {Output[]} outputs * @returns {Promise<VerifiableCertificate[]>} */ const parseResults = async (lookupResult) => { if (lookupResult.type === 'output-list') { const parsedResults = []; for (const output of lookupResult.outputs) { try { const tx = sdk_1.Transaction.fromBEEF(output.beef); // Decode the Identity token fields from the Bitcoin outputScript const decodedOutput = sdk_1.PushDrop.decode(tx.outputs[output.outputIndex].lockingScript); // Parse out the certificate and relevant data const certificate = JSON.parse(sdk_1.Utils.toUTF8(decodedOutput.fields[0])); // TEST const verifiableCert = new sdk_1.VerifiableCertificate(certificate.type, certificate.serialNumber, certificate.subject, certificate.certifier, certificate.revocationOutpoint, certificate.fields, certificate.keyring, certificate.signature); const decryptedFields = await verifiableCert.decryptFields(new sdk_1.ProtoWallet('anyone')); // Verify the certificate signature is correct await verifiableCert.verify(); verifiableCert.decryptedFields = decryptedFields; parsedResults.push(verifiableCert); } catch (error) { console.error(error); // do nothing } } return parsedResults; } return []; }; exports.parseResults = parseResults; //# sourceMappingURL=identityUtils.js.map