@bcts/frost-hubert 1.0.0-beta.0 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bin/frost.cjs +17 -19
- package/dist/bin/frost.cjs.map +1 -1
- package/dist/bin/frost.mjs +16 -17
- package/dist/bin/frost.mjs.map +1 -1
- package/dist/{busy-EZU7EKr6.cjs → busy-B_h0bNAJ.cjs} +1 -1
- package/dist/{busy-DkM2jAIZ.mjs.map → busy-B_h0bNAJ.cjs.map} +1 -1
- package/dist/{busy-DkM2jAIZ.mjs → busy-BlU8_pS2.mjs} +1 -1
- package/dist/{busy-EZU7EKr6.cjs.map → busy-BlU8_pS2.mjs.map} +1 -1
- package/dist/cmd/index.cjs +6 -7
- package/dist/cmd/index.d.cts +1 -1
- package/dist/cmd/index.d.mts +1 -1
- package/dist/cmd/index.mjs +5 -6
- package/dist/{cmd-Bw9_i2_f.cjs → cmd-CCVhHzG7.cjs} +20 -21
- package/dist/{cmd-Bw9_i2_f.cjs.map → cmd-CCVhHzG7.cjs.map} +1 -1
- package/dist/{cmd-CS1uJtuD.mjs → cmd-DNsHd19v.mjs} +20 -21
- package/dist/{cmd-CS1uJtuD.mjs.map → cmd-DNsHd19v.mjs.map} +1 -1
- package/dist/{common-lThIvJmZ.cjs → common-7-BOgaTt.cjs} +2 -3
- package/dist/{common-lThIvJmZ.cjs.map → common-7-BOgaTt.cjs.map} +1 -1
- package/dist/{common-CvH6dFvQ.mjs → common-Cf1UvJaP.mjs} +3 -3
- package/dist/{common-CvH6dFvQ.mjs.map → common-Cf1UvJaP.mjs.map} +1 -1
- package/dist/{common-lKP5EzHy.cjs → common-CnvAUC2b.cjs} +3 -3
- package/dist/{common-lKP5EzHy.cjs.map → common-CnvAUC2b.cjs.map} +1 -1
- package/dist/{common-DUWvtc08.mjs → common-DNrD_-EI.mjs} +2 -2
- package/dist/{common-DUWvtc08.mjs.map → common-DNrD_-EI.mjs.map} +1 -1
- package/dist/dkg/index.cjs +1 -2
- package/dist/dkg/index.cjs.map +1 -1
- package/dist/dkg/index.d.cts +1 -1
- package/dist/dkg/index.d.mts +1 -1
- package/dist/dkg/index.mjs +1 -1
- package/dist/dkg/index.mjs.map +1 -1
- package/dist/{finalize-CNTDj6aS.mjs → finalize-BpC0rz93.mjs} +6 -6
- package/dist/{finalize-CNTDj6aS.mjs.map → finalize-BpC0rz93.mjs.map} +1 -1
- package/dist/{finalize-BRgJK-Xv.cjs → finalize-Cb0obTSo.cjs} +6 -6
- package/dist/{finalize-BRgJK-Xv.cjs.map → finalize-Cb0obTSo.cjs.map} +1 -1
- package/dist/{finalize-BfLgzn8f.cjs → finalize-DHEnKobp.cjs} +5 -5
- package/dist/{finalize-BfLgzn8f.cjs.map → finalize-DHEnKobp.cjs.map} +1 -1
- package/dist/{finalize-UPyI1yb1.cjs → finalize-DQ0VGUHO.cjs} +7 -7
- package/dist/{finalize-UPyI1yb1.cjs.map → finalize-DQ0VGUHO.cjs.map} +1 -1
- package/dist/{finalize-IA01t_Qq.mjs → finalize-DtRxHZ7H.mjs} +5 -5
- package/dist/{finalize-IA01t_Qq.mjs.map → finalize-DtRxHZ7H.mjs.map} +1 -1
- package/dist/{finalize-EC3ikHQq.mjs → finalize-T83Ko8nG.mjs} +6 -6
- package/dist/{finalize-EC3ikHQq.mjs.map → finalize-T83Ko8nG.mjs.map} +1 -1
- package/dist/frost/index.cjs +1 -1
- package/dist/frost/index.cjs.map +1 -1
- package/dist/frost/index.d.cts.map +1 -1
- package/dist/frost/index.d.mts.map +1 -1
- package/dist/frost/index.mjs +1 -1
- package/dist/frost/index.mjs.map +1 -1
- package/dist/{index-F1iNEAJR.d.cts → index-BErX9AZF.d.cts} +3 -3
- package/dist/index-BErX9AZF.d.cts.map +1 -0
- package/dist/{index-B3c-80VS.d.cts → index-BaUVw4b1.d.mts} +2 -2
- package/dist/index-BaUVw4b1.d.mts.map +1 -0
- package/dist/{index-C8QeHNwa.d.cts → index-CD50Qtgw.d.cts} +1 -1
- package/dist/index-CD50Qtgw.d.cts.map +1 -0
- package/dist/{index-DVbWyOs7.d.mts → index-CD50Qtgw.d.mts} +1 -1
- package/dist/index-CD50Qtgw.d.mts.map +1 -0
- package/dist/{index-BgbSGpxn.d.mts → index-Drklne-Y.d.mts} +3 -3
- package/dist/index-Drklne-Y.d.mts.map +1 -0
- package/dist/{index-D3QTWkEm.d.mts → index-gkmZzEuD.d.cts} +2 -2
- package/dist/index-gkmZzEuD.d.cts.map +1 -0
- package/dist/index.cjs +7 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +6 -7
- package/dist/index.mjs.map +1 -1
- package/dist/{invite-5277FQVT.cjs → invite-1tzg0B0P.cjs} +5 -5
- package/dist/{invite-5277FQVT.cjs.map → invite-1tzg0B0P.cjs.map} +1 -1
- package/dist/{invite-DUTcfTgX.cjs → invite-BLwtexAu.cjs} +4 -4
- package/dist/{invite-DUTcfTgX.cjs.map → invite-BLwtexAu.cjs.map} +1 -1
- package/dist/{invite-IU4n0dq2.mjs → invite-Be2v2SVc.mjs} +4 -4
- package/dist/{invite-IU4n0dq2.mjs.map → invite-Be2v2SVc.mjs.map} +1 -1
- package/dist/{invite-RU-OXTNS.mjs → invite-D8mQSnFz.mjs} +5 -5
- package/dist/{invite-RU-OXTNS.mjs.map → invite-D8mQSnFz.mjs.map} +1 -1
- package/dist/{parallel-D6zc6VW4.mjs → parallel-PZiwHZT8.mjs} +1 -1
- package/dist/{parallel-D1R6ZGlY.cjs.map → parallel-PZiwHZT8.mjs.map} +1 -1
- package/dist/{parallel-D1R6ZGlY.cjs → parallel-szwYx-bi.cjs} +1 -1
- package/dist/{parallel-D6zc6VW4.mjs.map → parallel-szwYx-bi.cjs.map} +1 -1
- package/dist/{proposed-participant-Dm1Eq6mX.cjs → proposed-participant-BvHNnpcZ.cjs} +1 -2
- package/dist/{proposed-participant-Dm1Eq6mX.cjs.map → proposed-participant-BvHNnpcZ.cjs.map} +1 -1
- package/dist/{proposed-participant-cWM7iUrO.mjs → proposed-participant-Detb823_.mjs} +1 -1
- package/dist/{proposed-participant-cWM7iUrO.mjs.map → proposed-participant-Detb823_.mjs.map} +1 -1
- package/dist/{receive-CAI-x4II.cjs → receive-BR-knnGv.cjs} +6 -6
- package/dist/{receive-CAI-x4II.cjs.map → receive-BR-knnGv.cjs.map} +1 -1
- package/dist/{receive-kZMsXhbK.cjs → receive-D_r4Mryr.cjs} +6 -6
- package/dist/{receive-kZMsXhbK.cjs.map → receive-D_r4Mryr.cjs.map} +1 -1
- package/dist/{receive-D2Nn68L7.mjs → receive-dkSCSGpl.mjs} +5 -5
- package/dist/{receive-D2Nn68L7.mjs.map → receive-dkSCSGpl.mjs.map} +1 -1
- package/dist/{receive-DA_KQEgk.mjs → receive-g8EhZF2Y.mjs} +6 -6
- package/dist/{receive-DA_KQEgk.mjs.map → receive-g8EhZF2Y.mjs.map} +1 -1
- package/dist/registry/index.cjs +1 -1
- package/dist/registry/index.cjs.map +1 -1
- package/dist/registry/index.d.cts +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs.map +1 -1
- package/dist/{registry-9puTaRrD.cjs → registry-CkIbA7nt.cjs} +79 -2
- package/dist/registry-CkIbA7nt.cjs.map +1 -0
- package/dist/{registry-BpCwtrRt.mjs → registry-DGjs4qDK.mjs} +74 -3
- package/dist/registry-DGjs4qDK.mjs.map +1 -0
- package/dist/{round1-BHBjru1m.cjs → round1-9FAqFvL5.cjs} +5 -5
- package/dist/{round1-BHBjru1m.cjs.map → round1-9FAqFvL5.cjs.map} +1 -1
- package/dist/{round1-CcQCGlIT.mjs → round1-B8haiMM8.mjs} +6 -6
- package/dist/{round1-CcQCGlIT.mjs.map → round1-B8haiMM8.mjs.map} +1 -1
- package/dist/{round1-Cgm7j1kI.mjs → round1-BOIE1E4O.mjs} +5 -5
- package/dist/{round1-Cgm7j1kI.mjs.map → round1-BOIE1E4O.mjs.map} +1 -1
- package/dist/{round1-4Hyx8w0x.cjs → round1-Bq0vweyQ.cjs} +5 -5
- package/dist/{round1-4Hyx8w0x.cjs.map → round1-Bq0vweyQ.cjs.map} +1 -1
- package/dist/{round1-CWSXZx5R.cjs → round1-CXkXoVQU.cjs} +9 -9
- package/dist/{round1-CWSXZx5R.cjs.map → round1-CXkXoVQU.cjs.map} +1 -1
- package/dist/{round1-7v9LlE11.mjs → round1-D8t7EzIo.mjs} +5 -5
- package/dist/{round1-7v9LlE11.mjs.map → round1-D8t7EzIo.mjs.map} +1 -1
- package/dist/{round1-DQ0fnc1H.cjs → round1-DriPu15x.cjs} +7 -7
- package/dist/{round1-DQ0fnc1H.cjs.map → round1-DriPu15x.cjs.map} +1 -1
- package/dist/{round1-CMLKN2RR.mjs → round1-Y2kcVwnR.mjs} +7 -7
- package/dist/{round1-CMLKN2RR.mjs.map → round1-Y2kcVwnR.mjs.map} +1 -1
- package/dist/{round2-BWz9SQIi.cjs → round2-AMDYMUIg.cjs} +5 -5
- package/dist/{round2-BWz9SQIi.cjs.map → round2-AMDYMUIg.cjs.map} +1 -1
- package/dist/{round2-o2Q-GMbX.cjs → round2-BHQKVJFo.cjs} +7 -7
- package/dist/{round2-o2Q-GMbX.cjs.map → round2-BHQKVJFo.cjs.map} +1 -1
- package/dist/{round2-Bl2uK93U.mjs → round2-BfetYacV.mjs} +5 -5
- package/dist/{round2-Bl2uK93U.mjs.map → round2-BfetYacV.mjs.map} +1 -1
- package/dist/{round2-Dg24w-TU.mjs → round2-Cf5CJc_8.mjs} +7 -7
- package/dist/{round2-Dg24w-TU.mjs.map → round2-Cf5CJc_8.mjs.map} +1 -1
- package/dist/{round2-LylCa84n.cjs → round2-CvrmylN1.cjs} +7 -7
- package/dist/{round2-LylCa84n.cjs.map → round2-CvrmylN1.cjs.map} +1 -1
- package/dist/{round2-CdUT-AhH.cjs → round2-Dk_w97nl.cjs} +5 -5
- package/dist/{round2-CdUT-AhH.cjs.map → round2-Dk_w97nl.cjs.map} +1 -1
- package/dist/{round2-BkNRCXgS.mjs → round2-Z2JhMwxc.mjs} +5 -5
- package/dist/{round2-BkNRCXgS.mjs.map → round2-Z2JhMwxc.mjs.map} +1 -1
- package/dist/{round2-DOA3rnV-.mjs → round2-mF6UlkT-.mjs} +6 -6
- package/dist/{round2-DOA3rnV-.mjs.map → round2-mF6UlkT-.mjs.map} +1 -1
- package/package.json +14 -14
- package/dist/index-B3c-80VS.d.cts.map +0 -1
- package/dist/index-BgbSGpxn.d.mts.map +0 -1
- package/dist/index-C8QeHNwa.d.cts.map +0 -1
- package/dist/index-D3QTWkEm.d.mts.map +0 -1
- package/dist/index-DVbWyOs7.d.mts.map +0 -1
- package/dist/index-F1iNEAJR.d.cts.map +0 -1
- package/dist/registry-9puTaRrD.cjs.map +0 -1
- package/dist/registry-BpCwtrRt.mjs.map +0 -1
- package/dist/storage-B-Gu68-O.cjs +0 -79
- package/dist/storage-B-Gu68-O.cjs.map +0 -1
- package/dist/storage-Bkkliz0K.mjs +0 -74
- package/dist/storage-Bkkliz0K.mjs.map +0 -1
- /package/dist/{chunk-CZWwpsFl.cjs → chunk-DakpK96I.cjs} +0 -0
- /package/dist/{chunk-CjcI7cDX.mjs → chunk-z9aeyW2b.mjs} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round2-Dg24w-TU.mjs","names":["ARIDClass","XIDClass","JSONComponent"],"sources":["../src/cmd/sign/coordinator/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign coordinator round 2 command.\n *\n * Port of cmd/sign/coordinator/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n type ARID,\n type XID,\n XID as XIDClass,\n ARID as ARIDClass,\n Signature,\n type PrivateKeys,\n JSON as JSONComponent,\n} from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { parallelFetch, parallelSend, type CollectionResult } from \"../../parallel.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr, signingKeyFromVerifying } from \"../../dkg/common.js\";\nimport { signingStateDir, SignFinalizeContent } from \"../common.js\";\nimport { putWithIndicator } from \"../../busy.js\";\nimport {\n aggregateSignatures,\n createSigningPackage,\n deserializeSigningCommitments,\n deserializeSignatureShare,\n deserializePublicKeyPackage,\n identifierFromU16,\n serializeSignature,\n serializeSignatureShare,\n type SerializedPublicKeyPackage,\n type SerializedSigningCommitments,\n type FrostIdentifier,\n type Ed25519SigningCommitments,\n type Ed25519SignatureShare,\n type FrostPublicKeyPackage,\n} from \"../../../frost/index.js\";\n\n/**\n * Options for the sign round2 command.\n */\nexport interface SignRound2Options {\n registryPath?: string;\n groupId?: string;\n sessionId: string;\n parallel?: boolean;\n timeoutSeconds?: number;\n previewFinalize?: boolean;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round2 command.\n */\nexport interface SignRound2Result {\n signature: string;\n signedEnvelope: string;\n accepted: number;\n rejected: number;\n errors: number;\n timeouts: number;\n}\n\n/**\n * Data extracted from a successful signature share response.\n *\n * Port of `struct SignRound2ResponseData` from cmd/sign/coordinator/round2.rs.\n */\ninterface SignRound2ResponseData {\n signatureShare: Ed25519SignatureShare;\n finalizeArid: ARID;\n}\n\n/**\n * State loaded from start.json.\n *\n * Port of `struct StartState` from cmd/sign/coordinator/round2.rs.\n */\ninterface StartState {\n groupId: ARID;\n minSigners: number;\n participants: XID[];\n targetUr: string;\n}\n\n/**\n * Individual participant's commitment data.\n *\n * Port of `struct ParticipantCommitment` from cmd/sign/coordinator/round2.rs.\n */\ninterface ParticipantCommitment {\n commitments: Ed25519SigningCommitments;\n shareArid: ARID;\n}\n\n/**\n * State loaded from commitments.json.\n *\n * Port of `struct CommitmentsState` from cmd/sign/coordinator/round2.rs.\n */\ninterface CommitmentsState {\n commitments: Map<string, ParticipantCommitment>; // XID UR string -> commitment\n}\n\n/**\n * Validate envelope and extract signature share data (for parallel fetch).\n *\n * Port of `validate_and_extract_share_response()` from cmd/sign/coordinator/round2.rs.\n */\nfunction validateAndExtractShareResponse(\n envelope: Envelope,\n _coordinatorKeys: PrivateKeys,\n expectedSender: XID,\n expectedSessionId: ARID,\n): SignRound2ResponseData | { rejected: string } {\n // In the full implementation, we would decrypt the sealed response here\n // For now, we extract the data from the envelope directly\n\n try {\n // Check the response type\n envelope.checkSubjectUnit();\n envelope.checkType(\"signRound2Response\");\n\n // Extract session ID using objectsForPredicate and then extract subjects\n const sessionObjects = envelope.objectsForPredicate(\"session\");\n if (sessionObjects.length === 0) {\n return { rejected: \"Missing session in response\" };\n }\n const responseSession = ARIDClass.fromTaggedCbor(sessionObjects[0].subject().tryLeaf());\n if (responseSession.urString() !== expectedSessionId.urString()) {\n return {\n rejected: `Response session ${responseSession.urString()} does not match expected ${expectedSessionId.urString()}`,\n };\n }\n\n // Extract participant XID (sender check)\n const participantObjects = envelope.objectsForPredicate(\"participant\");\n if (participantObjects.length === 0) {\n return { rejected: \"Missing participant in response\" };\n }\n const participantXid = XIDClass.fromTaggedCbor(participantObjects[0].subject().tryLeaf());\n if (participantXid.urString() !== expectedSender.urString()) {\n return {\n rejected: `Unexpected response sender: ${participantXid.urString()} (expected ${expectedSender.urString()})`,\n };\n }\n\n // Extract signature share (JSON-serialized)\n const shareObjects = envelope.objectsForPredicate(\"signature_share\");\n if (shareObjects.length === 0) {\n return { rejected: \"Missing signature_share in response\" };\n }\n const signatureShareJson = JSONComponent.fromTaggedCbor(shareObjects[0].subject().tryLeaf());\n const signatureShareData = JSON.parse(signatureShareJson.toString()) as { share: string };\n const signatureShare = deserializeSignatureShare(signatureShareData.share);\n\n // Extract finalize ARID (response_arid)\n const responseAridObjects = envelope.objectsForPredicate(\"response_arid\");\n if (responseAridObjects.length === 0) {\n return { rejected: \"Missing response_arid in response\" };\n }\n const finalizeArid = ARIDClass.fromTaggedCbor(responseAridObjects[0].subject().tryLeaf());\n\n return { signatureShare, finalizeArid };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { rejected: `Failed to parse response: ${message}` };\n }\n}\n\n/**\n * Collect signature shares in parallel with progress display.\n *\n * Port of `collect_shares_parallel()` from cmd/sign/coordinator/round2.rs.\n */\nasync function collectSharesParallel(\n client: StorageClient,\n registry: Registry,\n commitmentsState: CommitmentsState,\n coordinator: XIDDocument,\n sessionId: ARID,\n timeoutSeconds?: number,\n): Promise<CollectionResult<SignRound2ResponseData>> {\n // Build requests from commitments\n const requests: [XID, ARID, string][] = [];\n\n for (const [xidUr, entry] of commitmentsState.commitments) {\n const xid = XIDClass.fromURString(xidUr);\n const participant = registry.participant(xid);\n const name = participant?.petName() ?? xid.urString();\n requests.push([xid, entry.shareArid, name]);\n }\n\n const coordinatorKeys = coordinator.inceptionPrivateKeys();\n if (!coordinatorKeys) {\n throw new Error(\"Coordinator XID document has no inception private keys\");\n }\n\n const session = sessionId;\n\n return parallelFetch(\n client,\n requests,\n (envelope: Envelope, xid: XID) => {\n return validateAndExtractShareResponse(envelope, coordinatorKeys, xid, session);\n },\n {\n timeoutSeconds,\n verbose: false,\n },\n );\n}\n\n/**\n * Build a finalize event containing all signature shares.\n *\n * Port of `build_finalize_event()` from cmd/sign/coordinator/round2.rs.\n */\nfunction buildFinalizeEvent(\n _sender: XIDDocument,\n sessionId: ARID,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n): SignFinalizeContent {\n // Build the content with session and all signature shares\n let content = SignFinalizeContent.new().addAssertion(\"session\", sessionId);\n\n for (const [xidUr, share] of signatureSharesByXid) {\n const xid = XIDClass.fromURString(xidUr);\n const shareHex = serializeSignatureShare(share);\n const shareJson = JSONComponent.fromString(JSON.stringify({ share: shareHex }));\n const entry = Envelope.new(xid).addAssertion(\"share\", shareJson);\n content = content.addAssertion(\"signature_share\", entry);\n }\n\n return content;\n}\n\n/**\n * Aggregate signature shares and verify the result.\n *\n * Port of signature aggregation logic from cmd/sign/coordinator/round2.rs.\n */\nfunction aggregateAndVerifySignature(\n signingCommitments: Map<FrostIdentifier, Ed25519SigningCommitments>,\n signatureSharesByIdentifier: Map<FrostIdentifier, Ed25519SignatureShare>,\n publicKeyPackage: FrostPublicKeyPackage,\n targetDigest: Uint8Array,\n): { signature: Signature; signatureUr: string } {\n // Create signing package\n const signingPackage = createSigningPackage(signingCommitments, targetDigest);\n\n // Aggregate signature shares\n const aggregatedSignature = aggregateSignatures(\n signingPackage,\n signatureSharesByIdentifier,\n publicKeyPackage,\n );\n\n // Serialize the aggregated signature\n const signatureBytes = serializeSignature(aggregatedSignature);\n\n // Verify the signature is 64 bytes\n if (signatureBytes.length !== 64) {\n throw new Error(\"Aggregated signature is not 64 bytes\");\n }\n\n // Create bc-components Signature\n const signature = Signature.ed25519FromData(signatureBytes);\n const signatureUr = signature.urString();\n\n return { signature, signatureUr };\n}\n\n/**\n * Persist final signing state to disk.\n *\n * Port of `persist_final_state()` from cmd/sign/coordinator/round2.rs.\n */\nfunction persistSigningState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n signature: Signature,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n finalizeArids: Map<string, ARID>,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Build signature shares JSON object\n const sharesJson: Record<string, unknown> = {};\n for (const [xidUr, share] of signatureSharesByXid) {\n sharesJson[xidUr] = { share: serializeSignatureShare(share) };\n }\n\n // Build finalize ARIDs JSON object\n const finalizeJson: Record<string, string> = {};\n for (const [xidUr, arid] of finalizeArids) {\n finalizeJson[xidUr] = arid.urString();\n }\n\n // Build root JSON object\n const root = {\n group: groupId.urString(),\n session: sessionId.urString(),\n signature: signature.urString(),\n signature_shares: sharesJson,\n finalize_arids: finalizeJson,\n };\n\n fs.writeFileSync(path.join(dir, \"final.json\"), JSON.stringify(root, null, 2));\n}\n\n/**\n * Load start state from disk.\n *\n * Port of `load_start_state()` from cmd/sign/coordinator/round2.rs.\n */\nfunction loadStartState(registryPath: string, sessionId: ARID, groupHint?: ARID): StartState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Find candidate paths\n const candidatePaths: [ARID, string][] = [];\n let groupDirs: [ARID, string][];\n\n if (groupHint) {\n groupDirs = [[groupHint, path.join(groupStateDir, groupHint.hex())]];\n } else {\n groupDirs = [];\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory() && entry.name.length === 64 && /^[0-9a-f]+$/i.test(entry.name)) {\n const groupId = ARIDClass.fromHex(entry.name);\n groupDirs.push([groupId, path.join(groupStateDir, entry.name)]);\n }\n }\n }\n }\n\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"start.json\");\n if (fs.existsSync(candidate)) {\n candidatePaths.push([groupId, candidate]);\n }\n }\n\n if (candidatePaths.length === 0) {\n throw new Error(\"No sign start state found; run `frost sign coordinator start` first\");\n }\n if (candidatePaths.length > 1) {\n throw new Error(\"Multiple signing sessions found; specify --group to disambiguate\");\n }\n\n const [groupId, statePath] = candidatePaths[0];\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in start.json`);\n }\n return value;\n };\n\n const sessionInState = parseAridUr(getStr(\"session_id\"));\n const groupInState = parseAridUr(getStr(\"group\"));\n\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `start.json session ${sessionInState.urString()} does not match requested session ${sessionId.urString()}`,\n );\n }\n if (groupInState.urString() !== groupId.urString()) {\n throw new Error(\n `start.json group ${groupInState.urString()} does not match directory group ${groupId.urString()}`,\n );\n }\n\n const minSigners = raw[\"min_signers\"];\n if (typeof minSigners !== \"number\") {\n throw new Error(\"Missing min_signers in start.json\");\n }\n\n const participantsVal = raw[\"participants\"] as Record<string, unknown> | undefined;\n if (!participantsVal || typeof participantsVal !== \"object\") {\n throw new Error(\"Missing participants in start.json\");\n }\n\n const participants: XID[] = [];\n for (const xidStr of Object.keys(participantsVal)) {\n participants.push(XIDClass.fromURString(xidStr));\n }\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used\n // `urString().localeCompare(...)`, which diverges for bytes ≥ 0x80.\n participants.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n const targetUr = getStr(\"target\");\n\n return { groupId, minSigners, participants, targetUr };\n}\n\n/**\n * Load commitments state from disk.\n *\n * Port of `load_commitments_state()` from cmd/sign/coordinator/round2.rs.\n */\nfunction loadCommitmentsState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n): CommitmentsState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const statePath = path.join(dir, \"commitments.json\");\n\n if (!fs.existsSync(statePath)) {\n throw new Error(\n `Commitments not found at ${statePath}. Run \\`frost sign coordinator collect\\` first`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in commitments.json`);\n }\n return value;\n };\n\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `commitments.json session ${sessionInState.urString()} does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const commitmentsVal = raw[\"commitments\"] as Record<string, unknown> | undefined;\n if (!commitmentsVal || typeof commitmentsVal !== \"object\") {\n throw new Error(\"Missing commitments map in commitments.json\");\n }\n\n const commitments = new Map<string, ParticipantCommitment>();\n\n for (const [xidStr, value] of Object.entries(commitmentsVal)) {\n const obj = value as Record<string, unknown>;\n const commitValue = obj[\"commitments\"] as SerializedSigningCommitments | undefined;\n if (!commitValue) {\n throw new Error(\"Missing commitments value in commitments.json\");\n }\n const commitmentsDeserialized = deserializeSigningCommitments(commitValue);\n\n const shareAridRaw = obj[\"share_arid\"];\n if (typeof shareAridRaw !== \"string\") {\n throw new Error(\"Missing share_arid in commitments.json\");\n }\n const shareArid = parseAridUr(shareAridRaw);\n\n commitments.set(xidStr, {\n commitments: commitmentsDeserialized,\n shareArid,\n });\n }\n\n return { commitments };\n}\n\n/**\n * Load public key package from collected_finalize.json.\n *\n * Port of `load_public_key_package()` from cmd/sign/coordinator/round2.rs.\n */\nfunction loadPublicKeyPackage(registryPath: string, groupId: ARID): FrostPublicKeyPackage {\n const base = path.dirname(registryPath);\n const pkgPath = path.join(base, \"group-state\", groupId.hex(), \"collected_finalize.json\");\n\n if (!fs.existsSync(pkgPath)) {\n throw new Error(\n `collected_finalize.json not found at ${pkgPath}. Run \\`frost dkg coordinator finalize collect\\` first`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n const firstEntry = Object.values(raw)[0] as Record<string, unknown> | undefined;\n\n if (!firstEntry) {\n throw new Error(\"collected_finalize.json is empty\");\n }\n\n const publicKeyValue = firstEntry[\"public_key_package\"] as SerializedPublicKeyPackage | undefined;\n if (!publicKeyValue) {\n throw new Error(\"public_key_package missing in collected_finalize.json\");\n }\n\n return deserializePublicKeyPackage(publicKeyValue);\n}\n\n/**\n * Build a map from XID to FROST identifier.\n *\n * Port of `xid_identifier_map()` from cmd/sign/coordinator/round2.rs.\n */\nfunction xidIdentifierMap(participants: XID[]): Map<string, FrostIdentifier> {\n const map = new Map<string, FrostIdentifier>();\n for (let i = 0; i < participants.length; i++) {\n const identifier = identifierFromU16(i + 1);\n map.set(participants[i].urString(), identifier);\n }\n return map;\n}\n\n/**\n * Build signing commitments with identifiers.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/coordinator/round2.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, ParticipantCommitment>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidUr, entry] of commitments) {\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(`Unknown participant ${xidUr}`);\n }\n mapped.set(identifier, entry.commitments);\n }\n return mapped;\n}\n\n/**\n * Execute the sign coordinator round 2 command.\n *\n * Collects signature shares, aggregates the signature, and posts finalize packages.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/coordinator/round2.rs.\n */\nexport async function round2(\n client: StorageClient,\n options: SignRound2Options,\n cwd: string,\n): Promise<SignRound2Result> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (!owner) {\n throw new Error(\"Registry owner is required\");\n }\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint = options.groupId ? parseAridUr(options.groupId) : undefined;\n\n // Load start state (finds group automatically if not specified)\n const startState = loadStartState(registryPath, sessionId, groupHint);\n const groupId = startState.groupId;\n\n const groupRecord = registry.group(groupId);\n if (!groupRecord) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Verify coordinator ownership\n if (groupRecord.coordinator().xid().urString() !== owner.xid().urString()) {\n throw new Error(\n `Only the coordinator can finalize signing. Coordinator: ${groupRecord.coordinator().xid().urString()}, Owner: ${owner.xid().urString()}`,\n );\n }\n\n // Load commitments state\n const commitmentsState = loadCommitmentsState(registryPath, groupId, sessionId);\n\n // Build XID to identifier map\n const xidToIdentifier = xidIdentifierMap(startState.participants);\n\n // Collect signature shares\n let signatureSharesByIdentifier: Map<FrostIdentifier, Ed25519SignatureShare>;\n let signatureSharesByXid: Map<string, Ed25519SignatureShare>;\n let finalizeArids: Map<string, ARID>;\n\n if (options.parallel === true) {\n // Parallel collection path\n const collection = await collectSharesParallel(\n client,\n registry,\n commitmentsState,\n owner.xidDocument(),\n sessionId,\n options.timeoutSeconds,\n );\n\n if (!collection.allSucceeded()) {\n // Report failures\n if (collection.rejections.length > 0) {\n console.error(\"\\nRejections:\");\n for (const [xid, reason] of collection.rejections) {\n console.error(` ${xid.urString()}: ${reason}`);\n }\n }\n if (collection.errors.length > 0) {\n console.error(\"\\nErrors:\");\n for (const [xid, error] of collection.errors) {\n console.error(` ${xid.urString()}: ${error}`);\n }\n }\n if (collection.timeouts.length > 0) {\n console.error(\"\\nTimeouts:\");\n for (const xid of collection.timeouts) {\n console.error(` ${xid.urString()}`);\n }\n }\n throw new Error(\n `Signature share collection incomplete: ${collection.successes.length} succeeded, ` +\n `${collection.rejections.length} rejected, ${collection.errors.length} errors, ` +\n `${collection.timeouts.length} timeouts`,\n );\n }\n\n // Convert collection to maps\n signatureSharesByIdentifier = new Map();\n signatureSharesByXid = new Map();\n finalizeArids = new Map();\n\n for (const [xid, data] of collection.successes) {\n const xidUr = xid.urString();\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(\"Identifier mapping missing for participant\");\n }\n signatureSharesByIdentifier.set(identifier, data.signatureShare);\n signatureSharesByXid.set(xidUr, data.signatureShare);\n finalizeArids.set(xidUr, data.finalizeArid);\n }\n } else {\n // Sequential collection path\n if (options.verbose === true) {\n console.error(\n `Collecting signature shares for session ${sessionId.urString()} from ${commitmentsState.commitments.size} participants...`,\n );\n }\n\n signatureSharesByIdentifier = new Map();\n signatureSharesByXid = new Map();\n finalizeArids = new Map();\n\n for (const [xidUr, entry] of commitmentsState.commitments) {\n const xid = XIDClass.fromURString(xidUr);\n const participant = registry.participant(xid);\n const participantName = participant?.petName() ?? xid.urString();\n\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(\"Identifier mapping missing for participant\");\n }\n\n // Fetch the response\n const envelope = await client.get(entry.shareArid, options.timeoutSeconds);\n if (!envelope) {\n throw new Error(`Signature share response not found for ${participantName}`);\n }\n\n const coordinatorKeys = owner.xidDocument().inceptionPrivateKeys();\n if (!coordinatorKeys) {\n throw new Error(\"Coordinator XID document has no inception private keys\");\n }\n\n const result = validateAndExtractShareResponse(envelope, coordinatorKeys, xid, sessionId);\n if (\"rejected\" in result) {\n throw new Error(`Participant rejected signRound2: ${result.rejected}`);\n }\n\n signatureSharesByIdentifier.set(identifier, result.signatureShare);\n signatureSharesByXid.set(xidUr, result.signatureShare);\n finalizeArids.set(xidUr, result.finalizeArid);\n }\n }\n\n // Verify we have enough shares\n if (signatureSharesByIdentifier.size < startState.minSigners) {\n throw new Error(\n `Only collected ${signatureSharesByIdentifier.size} signature shares, need at least ${startState.minSigners}`,\n );\n }\n\n // Build signing commitments with identifiers\n const signingCommitments = commitmentsWithIdentifiers(\n commitmentsState.commitments,\n xidToIdentifier,\n );\n\n // Get target digest\n const targetEnvelope = Envelope.fromURString(startState.targetUr);\n const targetDigest = targetEnvelope.subject().digest().data();\n\n // Load public key package\n const publicKeyPackage = loadPublicKeyPackage(registryPath, groupId);\n const verifyingKey = signingKeyFromVerifying(publicKeyPackage.verifyingKey);\n\n // Aggregate and verify signature\n const { signature, signatureUr } = aggregateAndVerifySignature(\n signingCommitments,\n signatureSharesByIdentifier,\n publicKeyPackage,\n targetDigest,\n );\n\n // Verify signature against target digest\n // @ts-expect-error - verifyingKey type mismatch\n if (verifyingKey.verify(signature, targetDigest) !== true) {\n throw new Error(\"Aggregated signature failed verification against target digest\");\n }\n\n // Attach signature to target and verify\n\n const signedEnvelope = Envelope.fromURString(startState.targetUr).addAssertion(\n \"signed\",\n signature,\n );\n const signedEnvelopeUr = signedEnvelope.urString();\n\n // Persist final state\n persistSigningState(\n registryPath,\n groupId,\n sessionId,\n signature,\n signatureSharesByXid,\n finalizeArids,\n );\n\n if (options.verbose === true) {\n console.error();\n console.error(\n `Aggregated signature for session ${sessionId.urString()} and prepared ${finalizeArids.size} finalize packages.`,\n );\n console.error(\"Signature verified against target and group key.\");\n }\n\n // Dispatch finalize events to participants\n const signerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (!signerKeys) {\n throw new Error(\"Coordinator XID document has no signing keys\");\n }\n\n if (options.verbose === true) {\n console.error(`Dispatching finalize packages to ${finalizeArids.size} participants...`);\n } else {\n // Blank line to separate get phase from put phase\n console.error();\n }\n\n // Build finalize messages\n const messages: [XID, ARID, Envelope, string][] = [];\n let previewPrinted = false;\n\n for (const [xidUr, finalizeArid] of finalizeArids) {\n const participantXid = XIDClass.fromURString(xidUr);\n const participant = registry.participant(participantXid);\n const participantName = participant?.petName() ?? xidUr;\n\n const recipientDoc =\n xidUr === owner.xid().urString() ? owner.xidDocument() : participant?.xidDocument();\n\n if (!recipientDoc) {\n throw new Error(`Participant ${xidUr} not found in registry`);\n }\n\n const event = buildFinalizeEvent(owner.xidDocument(), sessionId, signatureSharesByXid);\n\n if (options.previewFinalize === true && !previewPrinted) {\n // Preview as unsigned, unencrypted envelope\n console.log(`# signFinalize preview for ${participantXid.urString()}`);\n console.log(event.envelope().format());\n previewPrinted = true;\n }\n\n // For now, use the plain envelope (GSTP sealing would be applied in full implementation)\n const sealed = event.envelope();\n\n messages.push([participantXid, finalizeArid, sealed, participantName]);\n }\n\n // Dispatch messages\n if (options.parallel === true) {\n // Parallel send\n console.error();\n const results = await parallelSend(client, messages, options.verbose === true);\n\n // Check for errors\n const errors: string[] = [];\n for (const [xid, result] of results) {\n if (result !== null) {\n const participant = registry.participant(xid);\n const name = participant?.petName() ?? xid.urString();\n errors.push(`${name}: ${result.message}`);\n }\n }\n if (errors.length > 0) {\n throw new Error(`Failed to send finalize packages: ${errors.join(\"; \")}`);\n }\n } else {\n // Sequential send\n for (const [_xid, finalizeArid, sealed, participantName] of messages) {\n await putWithIndicator(\n client,\n finalizeArid,\n sealed,\n participantName,\n options.verbose ?? false,\n );\n }\n }\n\n // Print final signature and signed envelope UR\n console.log(signatureUr);\n console.log(signedEnvelopeUr);\n\n return {\n signature: signatureUr,\n signedEnvelope: signedEnvelopeUr,\n accepted: signatureSharesByIdentifier.size,\n rejected: 0,\n errors: 0,\n timeouts: 0,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"round2-Cf5CJc_8.mjs","names":["ARIDClass","XIDClass","JSONComponent"],"sources":["../src/cmd/sign/coordinator/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign coordinator round 2 command.\n *\n * Port of cmd/sign/coordinator/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n type ARID,\n type XID,\n XID as XIDClass,\n ARID as ARIDClass,\n Signature,\n type PrivateKeys,\n JSON as JSONComponent,\n} from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { parallelFetch, parallelSend, type CollectionResult } from \"../../parallel.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr, signingKeyFromVerifying } from \"../../dkg/common.js\";\nimport { signingStateDir, SignFinalizeContent } from \"../common.js\";\nimport { putWithIndicator } from \"../../busy.js\";\nimport {\n aggregateSignatures,\n createSigningPackage,\n deserializeSigningCommitments,\n deserializeSignatureShare,\n deserializePublicKeyPackage,\n identifierFromU16,\n serializeSignature,\n serializeSignatureShare,\n type SerializedPublicKeyPackage,\n type SerializedSigningCommitments,\n type FrostIdentifier,\n type Ed25519SigningCommitments,\n type Ed25519SignatureShare,\n type FrostPublicKeyPackage,\n} from \"../../../frost/index.js\";\n\n/**\n * Options for the sign round2 command.\n */\nexport interface SignRound2Options {\n registryPath?: string;\n groupId?: string;\n sessionId: string;\n parallel?: boolean;\n timeoutSeconds?: number;\n previewFinalize?: boolean;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round2 command.\n */\nexport interface SignRound2Result {\n signature: string;\n signedEnvelope: string;\n accepted: number;\n rejected: number;\n errors: number;\n timeouts: number;\n}\n\n/**\n * Data extracted from a successful signature share response.\n *\n * Port of `struct SignRound2ResponseData` from cmd/sign/coordinator/round2.rs.\n */\ninterface SignRound2ResponseData {\n signatureShare: Ed25519SignatureShare;\n finalizeArid: ARID;\n}\n\n/**\n * State loaded from start.json.\n *\n * Port of `struct StartState` from cmd/sign/coordinator/round2.rs.\n */\ninterface StartState {\n groupId: ARID;\n minSigners: number;\n participants: XID[];\n targetUr: string;\n}\n\n/**\n * Individual participant's commitment data.\n *\n * Port of `struct ParticipantCommitment` from cmd/sign/coordinator/round2.rs.\n */\ninterface ParticipantCommitment {\n commitments: Ed25519SigningCommitments;\n shareArid: ARID;\n}\n\n/**\n * State loaded from commitments.json.\n *\n * Port of `struct CommitmentsState` from cmd/sign/coordinator/round2.rs.\n */\ninterface CommitmentsState {\n commitments: Map<string, ParticipantCommitment>; // XID UR string -> commitment\n}\n\n/**\n * Validate envelope and extract signature share data (for parallel fetch).\n *\n * Port of `validate_and_extract_share_response()` from cmd/sign/coordinator/round2.rs.\n */\nfunction validateAndExtractShareResponse(\n envelope: Envelope,\n _coordinatorKeys: PrivateKeys,\n expectedSender: XID,\n expectedSessionId: ARID,\n): SignRound2ResponseData | { rejected: string } {\n // In the full implementation, we would decrypt the sealed response here\n // For now, we extract the data from the envelope directly\n\n try {\n // Check the response type\n envelope.checkSubjectUnit();\n envelope.checkType(\"signRound2Response\");\n\n // Extract session ID using objectsForPredicate and then extract subjects\n const sessionObjects = envelope.objectsForPredicate(\"session\");\n if (sessionObjects.length === 0) {\n return { rejected: \"Missing session in response\" };\n }\n const responseSession = ARIDClass.fromTaggedCbor(sessionObjects[0].subject().tryLeaf());\n if (responseSession.urString() !== expectedSessionId.urString()) {\n return {\n rejected: `Response session ${responseSession.urString()} does not match expected ${expectedSessionId.urString()}`,\n };\n }\n\n // Extract participant XID (sender check)\n const participantObjects = envelope.objectsForPredicate(\"participant\");\n if (participantObjects.length === 0) {\n return { rejected: \"Missing participant in response\" };\n }\n const participantXid = XIDClass.fromTaggedCbor(participantObjects[0].subject().tryLeaf());\n if (participantXid.urString() !== expectedSender.urString()) {\n return {\n rejected: `Unexpected response sender: ${participantXid.urString()} (expected ${expectedSender.urString()})`,\n };\n }\n\n // Extract signature share (JSON-serialized)\n const shareObjects = envelope.objectsForPredicate(\"signature_share\");\n if (shareObjects.length === 0) {\n return { rejected: \"Missing signature_share in response\" };\n }\n const signatureShareJson = JSONComponent.fromTaggedCbor(shareObjects[0].subject().tryLeaf());\n const signatureShareData = JSON.parse(signatureShareJson.toString()) as { share: string };\n const signatureShare = deserializeSignatureShare(signatureShareData.share);\n\n // Extract finalize ARID (response_arid)\n const responseAridObjects = envelope.objectsForPredicate(\"response_arid\");\n if (responseAridObjects.length === 0) {\n return { rejected: \"Missing response_arid in response\" };\n }\n const finalizeArid = ARIDClass.fromTaggedCbor(responseAridObjects[0].subject().tryLeaf());\n\n return { signatureShare, finalizeArid };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { rejected: `Failed to parse response: ${message}` };\n }\n}\n\n/**\n * Collect signature shares in parallel with progress display.\n *\n * Port of `collect_shares_parallel()` from cmd/sign/coordinator/round2.rs.\n */\nasync function collectSharesParallel(\n client: StorageClient,\n registry: Registry,\n commitmentsState: CommitmentsState,\n coordinator: XIDDocument,\n sessionId: ARID,\n timeoutSeconds?: number,\n): Promise<CollectionResult<SignRound2ResponseData>> {\n // Build requests from commitments\n const requests: [XID, ARID, string][] = [];\n\n for (const [xidUr, entry] of commitmentsState.commitments) {\n const xid = XIDClass.fromURString(xidUr);\n const participant = registry.participant(xid);\n const name = participant?.petName() ?? xid.urString();\n requests.push([xid, entry.shareArid, name]);\n }\n\n const coordinatorKeys = coordinator.inceptionPrivateKeys();\n if (!coordinatorKeys) {\n throw new Error(\"Coordinator XID document has no inception private keys\");\n }\n\n const session = sessionId;\n\n return parallelFetch(\n client,\n requests,\n (envelope: Envelope, xid: XID) => {\n return validateAndExtractShareResponse(envelope, coordinatorKeys, xid, session);\n },\n {\n timeoutSeconds,\n verbose: false,\n },\n );\n}\n\n/**\n * Build a finalize event containing all signature shares.\n *\n * Port of `build_finalize_event()` from cmd/sign/coordinator/round2.rs.\n */\nfunction buildFinalizeEvent(\n _sender: XIDDocument,\n sessionId: ARID,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n): SignFinalizeContent {\n // Build the content with session and all signature shares\n let content = SignFinalizeContent.new().addAssertion(\"session\", sessionId);\n\n for (const [xidUr, share] of signatureSharesByXid) {\n const xid = XIDClass.fromURString(xidUr);\n const shareHex = serializeSignatureShare(share);\n const shareJson = JSONComponent.fromString(JSON.stringify({ share: shareHex }));\n const entry = Envelope.new(xid).addAssertion(\"share\", shareJson);\n content = content.addAssertion(\"signature_share\", entry);\n }\n\n return content;\n}\n\n/**\n * Aggregate signature shares and verify the result.\n *\n * Port of signature aggregation logic from cmd/sign/coordinator/round2.rs.\n */\nfunction aggregateAndVerifySignature(\n signingCommitments: Map<FrostIdentifier, Ed25519SigningCommitments>,\n signatureSharesByIdentifier: Map<FrostIdentifier, Ed25519SignatureShare>,\n publicKeyPackage: FrostPublicKeyPackage,\n targetDigest: Uint8Array,\n): { signature: Signature; signatureUr: string } {\n // Create signing package\n const signingPackage = createSigningPackage(signingCommitments, targetDigest);\n\n // Aggregate signature shares\n const aggregatedSignature = aggregateSignatures(\n signingPackage,\n signatureSharesByIdentifier,\n publicKeyPackage,\n );\n\n // Serialize the aggregated signature\n const signatureBytes = serializeSignature(aggregatedSignature);\n\n // Verify the signature is 64 bytes\n if (signatureBytes.length !== 64) {\n throw new Error(\"Aggregated signature is not 64 bytes\");\n }\n\n // Create bc-components Signature\n const signature = Signature.ed25519FromData(signatureBytes);\n const signatureUr = signature.urString();\n\n return { signature, signatureUr };\n}\n\n/**\n * Persist final signing state to disk.\n *\n * Port of `persist_final_state()` from cmd/sign/coordinator/round2.rs.\n */\nfunction persistSigningState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n signature: Signature,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n finalizeArids: Map<string, ARID>,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Build signature shares JSON object\n const sharesJson: Record<string, unknown> = {};\n for (const [xidUr, share] of signatureSharesByXid) {\n sharesJson[xidUr] = { share: serializeSignatureShare(share) };\n }\n\n // Build finalize ARIDs JSON object\n const finalizeJson: Record<string, string> = {};\n for (const [xidUr, arid] of finalizeArids) {\n finalizeJson[xidUr] = arid.urString();\n }\n\n // Build root JSON object\n const root = {\n group: groupId.urString(),\n session: sessionId.urString(),\n signature: signature.urString(),\n signature_shares: sharesJson,\n finalize_arids: finalizeJson,\n };\n\n fs.writeFileSync(path.join(dir, \"final.json\"), JSON.stringify(root, null, 2));\n}\n\n/**\n * Load start state from disk.\n *\n * Port of `load_start_state()` from cmd/sign/coordinator/round2.rs.\n */\nfunction loadStartState(registryPath: string, sessionId: ARID, groupHint?: ARID): StartState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Find candidate paths\n const candidatePaths: [ARID, string][] = [];\n let groupDirs: [ARID, string][];\n\n if (groupHint) {\n groupDirs = [[groupHint, path.join(groupStateDir, groupHint.hex())]];\n } else {\n groupDirs = [];\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory() && entry.name.length === 64 && /^[0-9a-f]+$/i.test(entry.name)) {\n const groupId = ARIDClass.fromHex(entry.name);\n groupDirs.push([groupId, path.join(groupStateDir, entry.name)]);\n }\n }\n }\n }\n\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"start.json\");\n if (fs.existsSync(candidate)) {\n candidatePaths.push([groupId, candidate]);\n }\n }\n\n if (candidatePaths.length === 0) {\n throw new Error(\"No sign start state found; run `frost sign coordinator start` first\");\n }\n if (candidatePaths.length > 1) {\n throw new Error(\"Multiple signing sessions found; specify --group to disambiguate\");\n }\n\n const [groupId, statePath] = candidatePaths[0];\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in start.json`);\n }\n return value;\n };\n\n const sessionInState = parseAridUr(getStr(\"session_id\"));\n const groupInState = parseAridUr(getStr(\"group\"));\n\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `start.json session ${sessionInState.urString()} does not match requested session ${sessionId.urString()}`,\n );\n }\n if (groupInState.urString() !== groupId.urString()) {\n throw new Error(\n `start.json group ${groupInState.urString()} does not match directory group ${groupId.urString()}`,\n );\n }\n\n const minSigners = raw[\"min_signers\"];\n if (typeof minSigners !== \"number\") {\n throw new Error(\"Missing min_signers in start.json\");\n }\n\n const participantsVal = raw[\"participants\"] as Record<string, unknown> | undefined;\n if (!participantsVal || typeof participantsVal !== \"object\") {\n throw new Error(\"Missing participants in start.json\");\n }\n\n const participants: XID[] = [];\n for (const xidStr of Object.keys(participantsVal)) {\n participants.push(XIDClass.fromURString(xidStr));\n }\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used\n // `urString().localeCompare(...)`, which diverges for bytes ≥ 0x80.\n participants.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n const targetUr = getStr(\"target\");\n\n return { groupId, minSigners, participants, targetUr };\n}\n\n/**\n * Load commitments state from disk.\n *\n * Port of `load_commitments_state()` from cmd/sign/coordinator/round2.rs.\n */\nfunction loadCommitmentsState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n): CommitmentsState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const statePath = path.join(dir, \"commitments.json\");\n\n if (!fs.existsSync(statePath)) {\n throw new Error(\n `Commitments not found at ${statePath}. Run \\`frost sign coordinator collect\\` first`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in commitments.json`);\n }\n return value;\n };\n\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `commitments.json session ${sessionInState.urString()} does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const commitmentsVal = raw[\"commitments\"] as Record<string, unknown> | undefined;\n if (!commitmentsVal || typeof commitmentsVal !== \"object\") {\n throw new Error(\"Missing commitments map in commitments.json\");\n }\n\n const commitments = new Map<string, ParticipantCommitment>();\n\n for (const [xidStr, value] of Object.entries(commitmentsVal)) {\n const obj = value as Record<string, unknown>;\n const commitValue = obj[\"commitments\"] as SerializedSigningCommitments | undefined;\n if (!commitValue) {\n throw new Error(\"Missing commitments value in commitments.json\");\n }\n const commitmentsDeserialized = deserializeSigningCommitments(commitValue);\n\n const shareAridRaw = obj[\"share_arid\"];\n if (typeof shareAridRaw !== \"string\") {\n throw new Error(\"Missing share_arid in commitments.json\");\n }\n const shareArid = parseAridUr(shareAridRaw);\n\n commitments.set(xidStr, {\n commitments: commitmentsDeserialized,\n shareArid,\n });\n }\n\n return { commitments };\n}\n\n/**\n * Load public key package from collected_finalize.json.\n *\n * Port of `load_public_key_package()` from cmd/sign/coordinator/round2.rs.\n */\nfunction loadPublicKeyPackage(registryPath: string, groupId: ARID): FrostPublicKeyPackage {\n const base = path.dirname(registryPath);\n const pkgPath = path.join(base, \"group-state\", groupId.hex(), \"collected_finalize.json\");\n\n if (!fs.existsSync(pkgPath)) {\n throw new Error(\n `collected_finalize.json not found at ${pkgPath}. Run \\`frost dkg coordinator finalize collect\\` first`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n const firstEntry = Object.values(raw)[0] as Record<string, unknown> | undefined;\n\n if (!firstEntry) {\n throw new Error(\"collected_finalize.json is empty\");\n }\n\n const publicKeyValue = firstEntry[\"public_key_package\"] as SerializedPublicKeyPackage | undefined;\n if (!publicKeyValue) {\n throw new Error(\"public_key_package missing in collected_finalize.json\");\n }\n\n return deserializePublicKeyPackage(publicKeyValue);\n}\n\n/**\n * Build a map from XID to FROST identifier.\n *\n * Port of `xid_identifier_map()` from cmd/sign/coordinator/round2.rs.\n */\nfunction xidIdentifierMap(participants: XID[]): Map<string, FrostIdentifier> {\n const map = new Map<string, FrostIdentifier>();\n for (let i = 0; i < participants.length; i++) {\n const identifier = identifierFromU16(i + 1);\n map.set(participants[i].urString(), identifier);\n }\n return map;\n}\n\n/**\n * Build signing commitments with identifiers.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/coordinator/round2.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, ParticipantCommitment>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidUr, entry] of commitments) {\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(`Unknown participant ${xidUr}`);\n }\n mapped.set(identifier, entry.commitments);\n }\n return mapped;\n}\n\n/**\n * Execute the sign coordinator round 2 command.\n *\n * Collects signature shares, aggregates the signature, and posts finalize packages.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/coordinator/round2.rs.\n */\nexport async function round2(\n client: StorageClient,\n options: SignRound2Options,\n cwd: string,\n): Promise<SignRound2Result> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (!owner) {\n throw new Error(\"Registry owner is required\");\n }\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint = options.groupId ? parseAridUr(options.groupId) : undefined;\n\n // Load start state (finds group automatically if not specified)\n const startState = loadStartState(registryPath, sessionId, groupHint);\n const groupId = startState.groupId;\n\n const groupRecord = registry.group(groupId);\n if (!groupRecord) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Verify coordinator ownership\n if (groupRecord.coordinator().xid().urString() !== owner.xid().urString()) {\n throw new Error(\n `Only the coordinator can finalize signing. Coordinator: ${groupRecord.coordinator().xid().urString()}, Owner: ${owner.xid().urString()}`,\n );\n }\n\n // Load commitments state\n const commitmentsState = loadCommitmentsState(registryPath, groupId, sessionId);\n\n // Build XID to identifier map\n const xidToIdentifier = xidIdentifierMap(startState.participants);\n\n // Collect signature shares\n let signatureSharesByIdentifier: Map<FrostIdentifier, Ed25519SignatureShare>;\n let signatureSharesByXid: Map<string, Ed25519SignatureShare>;\n let finalizeArids: Map<string, ARID>;\n\n if (options.parallel === true) {\n // Parallel collection path\n const collection = await collectSharesParallel(\n client,\n registry,\n commitmentsState,\n owner.xidDocument(),\n sessionId,\n options.timeoutSeconds,\n );\n\n if (!collection.allSucceeded()) {\n // Report failures\n if (collection.rejections.length > 0) {\n console.error(\"\\nRejections:\");\n for (const [xid, reason] of collection.rejections) {\n console.error(` ${xid.urString()}: ${reason}`);\n }\n }\n if (collection.errors.length > 0) {\n console.error(\"\\nErrors:\");\n for (const [xid, error] of collection.errors) {\n console.error(` ${xid.urString()}: ${error}`);\n }\n }\n if (collection.timeouts.length > 0) {\n console.error(\"\\nTimeouts:\");\n for (const xid of collection.timeouts) {\n console.error(` ${xid.urString()}`);\n }\n }\n throw new Error(\n `Signature share collection incomplete: ${collection.successes.length} succeeded, ` +\n `${collection.rejections.length} rejected, ${collection.errors.length} errors, ` +\n `${collection.timeouts.length} timeouts`,\n );\n }\n\n // Convert collection to maps\n signatureSharesByIdentifier = new Map();\n signatureSharesByXid = new Map();\n finalizeArids = new Map();\n\n for (const [xid, data] of collection.successes) {\n const xidUr = xid.urString();\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(\"Identifier mapping missing for participant\");\n }\n signatureSharesByIdentifier.set(identifier, data.signatureShare);\n signatureSharesByXid.set(xidUr, data.signatureShare);\n finalizeArids.set(xidUr, data.finalizeArid);\n }\n } else {\n // Sequential collection path\n if (options.verbose === true) {\n console.error(\n `Collecting signature shares for session ${sessionId.urString()} from ${commitmentsState.commitments.size} participants...`,\n );\n }\n\n signatureSharesByIdentifier = new Map();\n signatureSharesByXid = new Map();\n finalizeArids = new Map();\n\n for (const [xidUr, entry] of commitmentsState.commitments) {\n const xid = XIDClass.fromURString(xidUr);\n const participant = registry.participant(xid);\n const participantName = participant?.petName() ?? xid.urString();\n\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(\"Identifier mapping missing for participant\");\n }\n\n // Fetch the response\n const envelope = await client.get(entry.shareArid, options.timeoutSeconds);\n if (!envelope) {\n throw new Error(`Signature share response not found for ${participantName}`);\n }\n\n const coordinatorKeys = owner.xidDocument().inceptionPrivateKeys();\n if (!coordinatorKeys) {\n throw new Error(\"Coordinator XID document has no inception private keys\");\n }\n\n const result = validateAndExtractShareResponse(envelope, coordinatorKeys, xid, sessionId);\n if (\"rejected\" in result) {\n throw new Error(`Participant rejected signRound2: ${result.rejected}`);\n }\n\n signatureSharesByIdentifier.set(identifier, result.signatureShare);\n signatureSharesByXid.set(xidUr, result.signatureShare);\n finalizeArids.set(xidUr, result.finalizeArid);\n }\n }\n\n // Verify we have enough shares\n if (signatureSharesByIdentifier.size < startState.minSigners) {\n throw new Error(\n `Only collected ${signatureSharesByIdentifier.size} signature shares, need at least ${startState.minSigners}`,\n );\n }\n\n // Build signing commitments with identifiers\n const signingCommitments = commitmentsWithIdentifiers(\n commitmentsState.commitments,\n xidToIdentifier,\n );\n\n // Get target digest\n const targetEnvelope = Envelope.fromURString(startState.targetUr);\n const targetDigest = targetEnvelope.subject().digest().data();\n\n // Load public key package\n const publicKeyPackage = loadPublicKeyPackage(registryPath, groupId);\n const verifyingKey = signingKeyFromVerifying(publicKeyPackage.verifyingKey);\n\n // Aggregate and verify signature\n const { signature, signatureUr } = aggregateAndVerifySignature(\n signingCommitments,\n signatureSharesByIdentifier,\n publicKeyPackage,\n targetDigest,\n );\n\n // Verify signature against target digest\n // @ts-expect-error - verifyingKey type mismatch\n if (verifyingKey.verify(signature, targetDigest) !== true) {\n throw new Error(\"Aggregated signature failed verification against target digest\");\n }\n\n // Attach signature to target and verify\n\n const signedEnvelope = Envelope.fromURString(startState.targetUr).addAssertion(\n \"signed\",\n signature,\n );\n const signedEnvelopeUr = signedEnvelope.urString();\n\n // Persist final state\n persistSigningState(\n registryPath,\n groupId,\n sessionId,\n signature,\n signatureSharesByXid,\n finalizeArids,\n );\n\n if (options.verbose === true) {\n console.error();\n console.error(\n `Aggregated signature for session ${sessionId.urString()} and prepared ${finalizeArids.size} finalize packages.`,\n );\n console.error(\"Signature verified against target and group key.\");\n }\n\n // Dispatch finalize events to participants\n const signerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (!signerKeys) {\n throw new Error(\"Coordinator XID document has no signing keys\");\n }\n\n if (options.verbose === true) {\n console.error(`Dispatching finalize packages to ${finalizeArids.size} participants...`);\n } else {\n // Blank line to separate get phase from put phase\n console.error();\n }\n\n // Build finalize messages\n const messages: [XID, ARID, Envelope, string][] = [];\n let previewPrinted = false;\n\n for (const [xidUr, finalizeArid] of finalizeArids) {\n const participantXid = XIDClass.fromURString(xidUr);\n const participant = registry.participant(participantXid);\n const participantName = participant?.petName() ?? xidUr;\n\n const recipientDoc =\n xidUr === owner.xid().urString() ? owner.xidDocument() : participant?.xidDocument();\n\n if (!recipientDoc) {\n throw new Error(`Participant ${xidUr} not found in registry`);\n }\n\n const event = buildFinalizeEvent(owner.xidDocument(), sessionId, signatureSharesByXid);\n\n if (options.previewFinalize === true && !previewPrinted) {\n // Preview as unsigned, unencrypted envelope\n console.log(`# signFinalize preview for ${participantXid.urString()}`);\n console.log(event.envelope().format());\n previewPrinted = true;\n }\n\n // For now, use the plain envelope (GSTP sealing would be applied in full implementation)\n const sealed = event.envelope();\n\n messages.push([participantXid, finalizeArid, sealed, participantName]);\n }\n\n // Dispatch messages\n if (options.parallel === true) {\n // Parallel send\n console.error();\n const results = await parallelSend(client, messages, options.verbose === true);\n\n // Check for errors\n const errors: string[] = [];\n for (const [xid, result] of results) {\n if (result !== null) {\n const participant = registry.participant(xid);\n const name = participant?.petName() ?? xid.urString();\n errors.push(`${name}: ${result.message}`);\n }\n }\n if (errors.length > 0) {\n throw new Error(`Failed to send finalize packages: ${errors.join(\"; \")}`);\n }\n } else {\n // Sequential send\n for (const [_xid, finalizeArid, sealed, participantName] of messages) {\n await putWithIndicator(\n client,\n finalizeArid,\n sealed,\n participantName,\n options.verbose ?? false,\n );\n }\n }\n\n // Print final signature and signed envelope UR\n console.log(signatureUr);\n console.log(signedEnvelopeUr);\n\n return {\n signature: signatureUr,\n signedEnvelope: signedEnvelopeUr,\n accepted: signatureSharesByIdentifier.size,\n rejected: 0,\n errors: 0,\n timeouts: 0,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const require_chunk = require("./chunk-
|
|
2
|
-
const require_proposed_participant = require("./proposed-participant-
|
|
1
|
+
const require_chunk = require("./chunk-DakpK96I.cjs");
|
|
2
|
+
const require_proposed_participant = require("./proposed-participant-BvHNnpcZ.cjs");
|
|
3
3
|
const require_registry_index = require("./registry/index.cjs");
|
|
4
|
-
const require_common = require("./common-
|
|
5
|
-
const require_busy = require("./busy-
|
|
6
|
-
const
|
|
4
|
+
const require_common = require("./common-CnvAUC2b.cjs");
|
|
5
|
+
const require_busy = require("./busy-B_h0bNAJ.cjs");
|
|
6
|
+
const require_registry = require("./registry-CkIbA7nt.cjs");
|
|
7
7
|
const require_frost_index = require("./frost/index.cjs");
|
|
8
8
|
let _bcts_components = require("@bcts/components");
|
|
9
9
|
let _bcts_dcbor = require("@bcts/dcbor");
|
|
@@ -218,7 +218,7 @@ async function round2(_client, options, cwd) {
|
|
|
218
218
|
if (listeningAtArid === void 0) throw new Error("No listening ARID for this group. Did you respond to the invite?");
|
|
219
219
|
const round1State = loadRound1State(registryPath, groupId);
|
|
220
220
|
if (require_common.isVerbose() || options.verbose === true) console.error("Fetching Round 2 request from Hubert...");
|
|
221
|
-
const client = await
|
|
221
|
+
const client = await require_registry.createStorageClient(options.storageSelection);
|
|
222
222
|
const requestEnvelope = await require_busy.getWithIndicator(client, listeningAtArid, "Round 2 request", options.timeoutSeconds, options.verbose ?? false);
|
|
223
223
|
if (requestEnvelope === null || requestEnvelope === void 0) throw new Error("Round 2 request not found in Hubert storage");
|
|
224
224
|
const ownerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();
|
|
@@ -290,4 +290,4 @@ Object.defineProperty(exports, "round2_exports", {
|
|
|
290
290
|
}
|
|
291
291
|
});
|
|
292
292
|
|
|
293
|
-
//# sourceMappingURL=round2-
|
|
293
|
+
//# sourceMappingURL=round2-CvrmylN1.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round2-LylCa84n.cjs","names":["groupStateDir","path","fs","Ed25519Sha512","hexToBytes","VerifiableSecretSharingCommitment","CoefficientCommitment","identifierFromU16","round1","serde","EnvelopeFunction","ARID","compareXidBytes","XID","JSONWrapper","identifierToHex","Envelope","serializeDkgRound2Package","bytesToHex","resolveRegistryPath","Registry","parseAridUr","isVerbose","createStorageClient","getWithIndicator","CborDate","SealedRequest","dkgPart2","SealedResponse","putWithIndicator"],"sources":["../src/cmd/dkg/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG participant round 2 command.\n *\n * Port of cmd/dkg/participant/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { ARID, JSON as JSONWrapper, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport type { XIDDocument } from \"@bcts/xid\";\n\nimport { type GroupRecord, Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { groupStateDir, isVerbose } from \"../../common.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { parseAridUr } from \"../common.js\";\nimport {\n dkgPart2,\n serializeDkgRound2Package,\n identifierFromU16,\n identifierToHex,\n hexToBytes,\n bytesToHex,\n type DkgRound1Package,\n type DkgRound1SecretPackage,\n type DkgRound2SecretPackage,\n type FrostIdentifier,\n} from \"../../../frost/index.js\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\nimport { round1, CoefficientCommitment, VerifiableSecretSharingCommitment } from \"@frosts/core\";\n\n/**\n * Options for the DKG round2 command.\n */\nexport interface DkgRound2Options {\n registryPath?: string;\n groupId: string;\n timeoutSeconds?: number;\n preview?: boolean;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the DKG round2 command.\n */\nexport interface DkgRound2Result {\n listeningArid: string;\n envelopeUr?: string;\n}\n\n/**\n * Persisted round 1 state loaded from disk.\n */\ninterface Round1State {\n secretPackage: DkgRound1SecretPackage;\n ourRound1Package: DkgRound1Package;\n}\n\n/**\n * Extracted round 1 packages from coordinator request.\n */\ntype Round1Packages = [Map<FrostIdentifier, DkgRound1Package>, [XID, DkgRound1Package][]];\n\n/**\n * Load persisted round 1 state from disk.\n *\n * Port of round1_secret loading from cmd/dkg/participant/round2.rs lines 86-97.\n */\nfunction loadRound1State(registryPath: string, groupId: ARID): Round1State {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n const round1SecretPath = path.join(packagesDir, \"round1_secret.json\");\n\n if (!fs.existsSync(round1SecretPath)) {\n throw new Error(\n `Round 1 secret not found at ${round1SecretPath}. Did you respond to the invite?`,\n );\n }\n\n // Mirrors Rust `frost::keys::dkg::round1::SecretPackage` JSON\n // (`frost-rust/frost-core/src/keys/dkg.rs:120-139`): no `header`,\n // snake_case `min_signers` / `max_signers`, identifier and\n // coefficients as lowercase hex strings, commitment as a flat array\n // of hex strings.\n const secretJson = JSON.parse(fs.readFileSync(round1SecretPath, \"utf-8\")) as {\n identifier: string;\n coefficients: string[];\n commitment: string[];\n min_signers: number;\n max_signers: number;\n };\n\n // Deserialize coefficients (scalars)\n const coefficients = secretJson.coefficients.map((hex) =>\n Ed25519Sha512.deserializeScalar(hexToBytes(hex)),\n );\n\n // Deserialize commitment (coefficient commitments)\n const coefficientCommitments = secretJson.commitment.map((hex) =>\n CoefficientCommitment.deserialize(Ed25519Sha512, hexToBytes(hex)),\n );\n\n const commitment = new VerifiableSecretSharingCommitment(Ed25519Sha512, coefficientCommitments);\n\n // Create the secret package\n // Need to find the actual identifier u16 value from the coefficients array length or saved state\n // The identifier is typically serialized as a scalar, but we need the u16 value\n // Parse it from the hex string - first 2 bytes as little-endian u16\n const idBytes = hexToBytes(secretJson.identifier);\n let identifierU16 = 1;\n if (idBytes.length >= 2) {\n identifierU16 = idBytes[0] | (idBytes[1] << 8);\n }\n if (identifierU16 === 0) {\n identifierU16 = 1; // Default to 1 if parsing failed\n }\n\n const parsedIdentifier = identifierFromU16(identifierU16);\n\n const secretPackage: DkgRound1SecretPackage = new round1.SecretPackage(\n Ed25519Sha512,\n parsedIdentifier,\n coefficients,\n commitment,\n secretJson.min_signers,\n secretJson.max_signers,\n );\n\n // Load the round 1 package as well\n const round1PackagePath = path.join(packagesDir, \"round1_package.json\");\n const packageJson = JSON.parse(fs.readFileSync(round1PackagePath, \"utf-8\")) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const ourRound1Package = serde.round1PackageFromJson(packageJson);\n\n return { secretPackage, ourRound1Package };\n}\n\n/**\n * Validate the round 2 request from the coordinator.\n *\n * Port of request validation from cmd/dkg/participant/round2.rs lines 118-158.\n */\nfunction validateRound2Request(\n sealedRequest: SealedRequest,\n groupId: ARID,\n expectedCoordinator: XID,\n): ARID {\n // Validate the request function\n if (!sealedRequest.function().equals(EnvelopeFunction.fromString(\"dkgRound2\"))) {\n throw new Error(`Unexpected request function: ${sealedRequest.function().toString()}`);\n }\n\n // Validate the sender is the expected coordinator\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} ` +\n `(expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n\n // Validate the group ID matches\n const requestGroupIdEnvelope = sealedRequest.objectForParameter(\"group\");\n if (requestGroupIdEnvelope === undefined) {\n throw new Error(\"Request missing group parameter\");\n }\n const requestGroupId = requestGroupIdEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n if (requestGroupId.urString() !== groupId.urString()) {\n throw new Error(\n `Request group ID ${requestGroupId.urString()} does not match expected ${groupId.urString()}`,\n );\n }\n\n // Extract where we should post our response\n const responseAridEnvelope = sealedRequest.objectForParameter(\"responseArid\");\n if (responseAridEnvelope === undefined) {\n throw new Error(\"Request missing responseArid parameter\");\n }\n const responseArid = responseAridEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n\n return responseArid;\n}\n\n/**\n * Extract round 1 packages from the request and convert to Map<Identifier, Package>.\n *\n * Port of `extract_round1_packages()` from cmd/dkg/participant/round2.rs lines 291-366.\n */\nfunction extractRound1Packages(\n request: SealedRequest,\n groupRecord: GroupRecord,\n ownerXid: XID,\n): Round1Packages {\n // Build XID -> Identifier mapping based on sorted participant order\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add owner if not already in list\n const ownerUrString = ownerXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === ownerUrString)) {\n sortedXids.push(ownerXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build XID -> Identifier mapping (1-indexed)\n const xidToIdentifier = new Map<string, FrostIdentifier>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n xidToIdentifier.set(deduped[i].urString(), identifier);\n }\n\n const myXidStr = ownerXid.urString();\n\n // Extract all round1Package parameters\n const packages = new Map<FrostIdentifier, DkgRound1Package>();\n const packagesByXid: [XID, DkgRound1Package][] = [];\n\n const packageEnvelopes = request.objectsForParameter(\"round1Package\");\n for (const packageEnvelope of packageEnvelopes) {\n // Extract participant XID from the envelope\n const participantEnvelope = packageEnvelope.objectForPredicate(\"participant\");\n if (participantEnvelope === undefined) {\n throw new Error(\"round1Package missing participant predicate\");\n }\n const participantXid = participantEnvelope.extractSubject((cbor) => XID.fromTaggedCbor(cbor));\n\n // Skip our own package\n if (participantXid.urString() === myXidStr) {\n continue;\n }\n\n // Extract the package bytes (stored as JSON tag)\n const packageJson = packageEnvelope.extractSubject((cbor) => JSONWrapper.fromTaggedCbor(cbor));\n const packageData = JSON.parse(new TextDecoder().decode(packageJson.toData())) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const pkg = serde.round1PackageFromJson(packageData);\n\n // Get the identifier for this participant\n const identifier = xidToIdentifier.get(participantXid.urString());\n if (identifier === undefined) {\n throw new Error(`Unknown participant XID in round1Package: ${participantXid.urString()}`);\n }\n\n packages.set(identifier, pkg);\n packagesByXid.push([participantXid, pkg]);\n }\n\n // Validate we have the expected number of packages\n const expectedPackages = xidToIdentifier.size - 1; // Exclude ourselves\n if (packages.size !== expectedPackages) {\n throw new Error(`Expected ${expectedPackages} Round 1 packages, found ${packages.size}`);\n }\n\n return [packages, packagesByXid];\n}\n\n/**\n * Build the response body containing Round 2 packages.\n *\n * Port of `build_response_body()` from cmd/dkg/participant/round2.rs lines 373-425.\n */\nfunction buildResponseBody(\n groupId: ARID,\n participantXid: XID,\n responseArid: ARID,\n round2Packages: Map<FrostIdentifier, unknown>,\n groupRecord: GroupRecord,\n): Envelope {\n // Build Identifier -> XID mapping\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add participant if not already in list\n const participantUrString = participantXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === participantUrString)) {\n sortedXids.push(participantXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build Identifier -> XID mapping (1-indexed)\n const identifierToXid = new Map<string, XID>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n identifierToXid.set(identifierToHex(identifier), deduped[i]);\n }\n\n let envelope = Envelope.unit()\n .addType(\"dkgRound2Response\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"participant\", participantXid)\n .addAssertion(\"response_arid\", responseArid);\n\n // Add each Round 2 package with the recipient's XID\n for (const [identifier, pkg] of round2Packages) {\n const idHex = identifierToHex(identifier);\n const recipientXid = identifierToXid.get(idHex);\n if (recipientXid === undefined) {\n throw new Error(\"Unknown identifier in round2_packages\");\n }\n\n // Serialize package to JSON and wrap in CBOR JSON tag\n const serialized = serializeDkgRound2Package(\n pkg as Parameters<typeof serializeDkgRound2Package>[0],\n );\n const jsonStr = JSON.stringify(serialized);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const jsonWrapper = JSONWrapper.fromData(jsonBytes);\n\n const packageEnvelope = Envelope.new(jsonWrapper).addAssertion(\"recipient\", recipientXid);\n\n envelope = envelope.addAssertion(\"round2Package\", packageEnvelope);\n }\n\n return envelope;\n}\n\n/**\n * Serialize round 2 secret package to JSON format for persistence.\n *\n * Mirrors the on-disk shape produced by Rust\n * `serde_json::to_vec_pretty(&frost::keys::dkg::round2::SecretPackage)`\n * (see `frost-rust/frost-core/src/keys/dkg.rs:269-287`):\n *\n * ```json\n * {\n * \"identifier\": \"<lowercase hex scalar>\",\n * \"commitment\": [\"<hex>\", \"<hex>\", ...],\n * \"secret_share\": \"<hex>\",\n * \"min_signers\": <u16>,\n * \"max_signers\": <u16>\n * }\n * ```\n *\n * `frost::keys::dkg::round2::SecretPackage` is\n * `#[serde(deny_unknown_fields)]`. The earlier port emitted\n * camelCase keys (`secretShare`, `minSigners`, `maxSigners`), a\n * nested `commitment.coefficients` shape, and a numeric\n * `identifier` — all of which Rust's standard derive would\n * reject and which had no chance of round-tripping with Rust.\n *\n * `participantIndex` is unused now that the identifier comes\n * directly from `secret.identifier.serialize()`; we keep it in the\n * signature for source-level parity with the call sites.\n */\nfunction serializeRound2SecretPackage(\n secret: DkgRound2SecretPackage,\n _participantIndex: number,\n): Record<string, unknown> {\n const commitment = secret.commitment;\n const commitmentCoefficients = commitment.serialize().map((c: Uint8Array) => bytesToHex(c));\n const secretShare = bytesToHex(Ed25519Sha512.serializeScalar(secret.secretShare()));\n\n return {\n identifier: bytesToHex(secret.identifier.serialize()),\n commitment: commitmentCoefficients,\n secret_share: secretShare,\n min_signers: secret.minSigners,\n max_signers: secret.maxSigners,\n };\n}\n\n/**\n * Persist round 2 state to disk.\n *\n * Port of round 2 secret persistence from cmd/dkg/participant/round2.rs lines 229-251.\n */\nfunction persistRound2State(\n registryPath: string,\n groupId: ARID,\n round2Secret: DkgRound2SecretPackage,\n round1PackagesByXid: [XID, DkgRound1Package][],\n participantIndex: number,\n): string {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(packagesDir, { recursive: true });\n\n // Persist Round 2 secret\n const round2SecretPath = path.join(packagesDir, \"round2_secret.json\");\n const round2SecretJson = serializeRound2SecretPackage(round2Secret, participantIndex);\n fs.writeFileSync(round2SecretPath, JSON.stringify(round2SecretJson, null, 2));\n\n // Persist received Round 1 packages for finalize phase\n const round1PackagesPath = path.join(packagesDir, \"collected_round1.json\");\n const round1Json: Record<string, unknown> = {};\n for (const [xid, pkg] of round1PackagesByXid) {\n const packageJson = serde.round1PackageToJson(pkg);\n round1Json[xid.urString()] = packageJson;\n }\n fs.writeFileSync(round1PackagesPath, JSON.stringify(round1Json, null, 2));\n\n return round2SecretPath;\n}\n\n/**\n * Execute the DKG participant round 2 command.\n *\n * Responds to the Round 2 request from the coordinator, runs FROST DKG part2\n * to generate Round 2 packages, and posts the response back.\n *\n * Port of `CommandArgs::exec()` from cmd/dkg/participant/round2.rs lines 55-288.\n */\nexport async function round2(\n _client: StorageClient | undefined,\n options: DkgRound2Options,\n cwd: string,\n): Promise<DkgRound2Result> {\n if (options.storageSelection === undefined) {\n throw new Error(\"Hubert storage is required for round2\");\n }\n\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const groupId = parseAridUr(options.groupId);\n const groupRecord = registry.group(groupId);\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Get the ARID where we're listening for the Round 2 request\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\"No listening ARID for this group. Did you respond to the invite?\");\n }\n\n // Load our Round 1 secret\n const round1State = loadRound1State(registryPath, groupId);\n\n if (isVerbose() || options.verbose === true) {\n console.error(\"Fetching Round 2 request from Hubert...\");\n }\n\n const client = await createStorageClient(options.storageSelection);\n\n // Fetch the Round 2 request from where we're listening\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"Round 2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (requestEnvelope === null || requestEnvelope === undefined) {\n throw new Error(\"Round 2 request not found in Hubert storage\");\n }\n\n // Decrypt and validate the request\n const ownerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (ownerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n const now = CborDate.now().datetime();\n const sealedRequest = SealedRequest.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n ownerPrivateKeys,\n );\n\n // Validate the request and extract response ARID\n const expectedCoordinator = groupRecord.coordinator().xid();\n const responseArid = validateRound2Request(sealedRequest, groupId, expectedCoordinator);\n\n // Extract Round 1 packages from the request\n const [round1Packages, round1PackagesByXid] = extractRound1Packages(\n sealedRequest,\n groupRecord,\n owner.xid(),\n );\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Received ${round1Packages.size} Round 1 packages. Running DKG part2...`);\n }\n\n // Allocate next response ARID for the finalize phase\n const nextResponseArid = ARID.new();\n\n // Run FROST DKG part2\n // Convert Map<Identifier, Package> to Map<string, Package> for dkgPart2\n const round1PackagesHex = new Map<string, DkgRound1Package>();\n for (const [id, pkg] of round1Packages) {\n round1PackagesHex.set(identifierToHex(id), pkg);\n }\n\n const [round2Secret, round2Packages] = dkgPart2(round1State.secretPackage, round1PackagesHex);\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Generated ${round2Packages.size} Round 2 packages.`);\n }\n\n // Convert round2Packages back to use Identifier keys for buildResponseBody\n const round2PackagesById = new Map<FrostIdentifier, unknown>();\n for (const [idHex, pkg] of round2Packages) {\n // Find the identifier that matches this hex\n for (const [id] of round1Packages) {\n if (identifierToHex(id) === idHex) {\n round2PackagesById.set(id, pkg);\n break;\n }\n }\n }\n\n // Build response with Round 2 packages\n const responseBody = buildResponseBody(\n groupId,\n owner.xid(),\n nextResponseArid,\n round2PackagesById,\n groupRecord,\n );\n\n const signerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no signing keys\");\n }\n\n // Get coordinator's XID document for encryption\n const coordinatorXid = groupRecord.coordinator().xid();\n const coordinatorRecord = registry.participant(coordinatorXid);\n let coordinatorDoc: XIDDocument;\n if (coordinatorRecord !== undefined) {\n coordinatorDoc = coordinatorRecord.xidDocument();\n } else {\n // Check if coordinator is the owner\n if (owner.xid().urString() === coordinatorXid.urString()) {\n coordinatorDoc = owner.xidDocument();\n } else {\n throw new Error(`Coordinator ${coordinatorXid.urString()} not found in registry`);\n }\n }\n\n // Get peer continuation from the request\n const peerContinuation = sealedRequest.peerContinuation();\n\n let sealed = SealedResponse.newSuccess(sealedRequest.id(), owner.xidDocument()).withResult(\n responseBody,\n );\n\n if (peerContinuation !== undefined) {\n sealed = sealed.withPeerContinuation(peerContinuation);\n }\n\n if (options.preview === true) {\n // Show the response envelope structure without encryption\n const unsealedEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n undefined,\n );\n const envelopeUr = unsealedEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n listeningArid: nextResponseArid.urString(),\n envelopeUr,\n };\n }\n\n // Calculate participant index for serialization. Sort by XID byte\n // order (mirrors Rust `XID::cmp`) so the 1-indexed position matches\n // what the coordinator used when assigning FROST identifiers. The\n // earlier port sorted by UR string via `Array.sort()` (default JS\n // string compare), which diverges from Rust byte order for any\n // byte ≥ 0x80.\n const sortedParticipantXids: XID[] = groupRecord.participants().map((p) => p.xid());\n const ownerXid = owner.xid();\n const ownerXidStr = ownerXid.urString();\n if (!sortedParticipantXids.some((x) => x.urString() === ownerXidStr)) {\n sortedParticipantXids.push(ownerXid);\n }\n sortedParticipantXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n const participantIndex = sortedParticipantXids.findIndex((x) => x.urString() === ownerXidStr) + 1; // 1-indexed\n\n // Persist Round 2 secret and collected round1 packages\n const round2SecretPath = persistRound2State(\n registryPath,\n groupId,\n round2Secret,\n round1PackagesByXid,\n participantIndex,\n );\n\n const responseEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n coordinatorDoc,\n );\n\n // Post the response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Round 2 Response\",\n options.verbose ?? false,\n );\n\n // Update contributions in registry\n const updatedGroupRecord = registry.group(groupId);\n if (updatedGroupRecord !== undefined) {\n const contributions = updatedGroupRecord.contributions();\n contributions.round2Secret = round2SecretPath;\n updatedGroupRecord.setContributions(contributions);\n // Set new listening ARID for finalize phase\n updatedGroupRecord.setListeningAtArid(nextResponseArid);\n registry.save(registryPath);\n }\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Posted Round 2 response to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: nextResponseArid.urString(),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,SAAS,gBAAgB,cAAsB,SAA4B;CACzE,MAAM,cAAcA,eAAAA,cAAc,cAAc,QAAQ,KAAK,CAAC;CAC9D,MAAM,mBAAmBC,UAAK,KAAK,aAAa,qBAAqB;AAErE,KAAI,CAACC,QAAG,WAAW,iBAAiB,CAClC,OAAM,IAAI,MACR,+BAA+B,iBAAiB,kCACjD;CAQH,MAAM,aAAa,KAAK,MAAMA,QAAG,aAAa,kBAAkB,QAAQ,CAAC;CASzE,MAAM,eAAe,WAAW,aAAa,KAAK,QAChDC,gBAAAA,cAAc,kBAAkBC,oBAAAA,WAAW,IAAI,CAAC,CACjD;CAOD,MAAM,aAAa,IAAIC,aAAAA,kCAAkCF,gBAAAA,eAJ1B,WAAW,WAAW,KAAK,QACxDG,aAAAA,sBAAsB,YAAYH,gBAAAA,eAAeC,oBAAAA,WAAW,IAAI,CAAC,CAG2B,CAAC;CAM/F,MAAM,UAAUA,oBAAAA,WAAW,WAAW,WAAW;CACjD,IAAI,gBAAgB;AACpB,KAAI,QAAQ,UAAU,EACpB,iBAAgB,QAAQ,KAAM,QAAQ,MAAM;AAE9C,KAAI,kBAAkB,EACpB,iBAAgB;CAGlB,MAAM,mBAAmBG,oBAAAA,kBAAkB,cAAc;CAEzD,MAAM,gBAAwC,IAAIC,aAAAA,OAAO,cACvDL,gBAAAA,eACA,kBACA,cACA,YACA,WAAW,aACX,WAAW,YACZ;CAGD,MAAM,oBAAoBF,UAAK,KAAK,aAAa,sBAAsB;CACvE,MAAM,cAAc,KAAK,MAAMC,QAAG,aAAa,mBAAmB,QAAQ,CAAC;AAQ3E,QAAO;EAAE;EAAe,kBAFCO,gBAAAA,MAAM,sBAAsB,YAEb;EAAE;;;;;;;AAQ5C,SAAS,sBACP,eACA,SACA,qBACM;AAEN,KAAI,CAAC,cAAc,UAAU,CAAC,OAAOC,eAAAA,SAAiB,WAAW,YAAY,CAAC,CAC5E,OAAM,IAAI,MAAM,gCAAgC,cAAc,UAAU,CAAC,UAAU,GAAG;AAIxF,KAAI,cAAc,QAAQ,CAAC,KAAK,CAAC,UAAU,KAAK,oBAAoB,UAAU,CAC5E,OAAM,IAAI,MACR,8BAA8B,cAAc,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,yBAC3C,oBAAoB,UAAU,CAAC,GAC3D;CAIH,MAAM,yBAAyB,cAAc,mBAAmB,QAAQ;AACxE,KAAI,2BAA2B,KAAA,EAC7B,OAAM,IAAI,MAAM,kCAAkC;CAEpD,MAAM,iBAAiB,uBAAuB,gBAAgB,SAASC,iBAAAA,KAAK,eAAe,KAAK,CAAC;AACjG,KAAI,eAAe,UAAU,KAAK,QAAQ,UAAU,CAClD,OAAM,IAAI,MACR,oBAAoB,eAAe,UAAU,CAAC,2BAA2B,QAAQ,UAAU,GAC5F;CAIH,MAAM,uBAAuB,cAAc,mBAAmB,eAAe;AAC7E,KAAI,yBAAyB,KAAA,EAC3B,OAAM,IAAI,MAAM,yCAAyC;AAI3D,QAFqB,qBAAqB,gBAAgB,SAASA,iBAAAA,KAAK,eAAe,KAAK,CAEzE;;;;;;;AAQrB,SAAS,sBACP,SACA,aACA,UACgB;CAEhB,MAAM,aAAoB,YAAY,cAAc,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC;CAGxE,MAAM,gBAAgB,SAAS,UAAU;AACzC,KAAI,CAAC,WAAW,MAAM,QAAQ,IAAI,UAAU,KAAK,cAAc,CAC7D,YAAW,KAAK,SAAS;AAO3B,YAAW,MAAM,GAAG,MAAMC,6BAAAA,gBAAgB,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;CAGlE,MAAM,UAAiB,EAAE;AACzB,MAAK,MAAM,OAAO,WAChB,KAAI,QAAQ,WAAW,KAAK,QAAQ,QAAQ,SAAS,GAAG,UAAU,KAAK,IAAI,UAAU,CACnF,SAAQ,KAAK,IAAI;CAKrB,MAAM,kCAAkB,IAAI,KAA8B;AAC1D,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,aAAaL,oBAAAA,kBAAkB,IAAI,EAAE;AAC3C,kBAAgB,IAAI,QAAQ,GAAG,UAAU,EAAE,WAAW;;CAGxD,MAAM,WAAW,SAAS,UAAU;CAGpC,MAAM,2BAAW,IAAI,KAAwC;CAC7D,MAAM,gBAA2C,EAAE;CAEnD,MAAM,mBAAmB,QAAQ,oBAAoB,gBAAgB;AACrE,MAAK,MAAM,mBAAmB,kBAAkB;EAE9C,MAAM,sBAAsB,gBAAgB,mBAAmB,cAAc;AAC7E,MAAI,wBAAwB,KAAA,EAC1B,OAAM,IAAI,MAAM,8CAA8C;EAEhE,MAAM,iBAAiB,oBAAoB,gBAAgB,SAASM,iBAAAA,IAAI,eAAe,KAAK,CAAC;AAG7F,MAAI,eAAe,UAAU,KAAK,SAChC;EAIF,MAAM,cAAc,gBAAgB,gBAAgB,SAASC,iBAAAA,KAAY,eAAe,KAAK,CAAC;EAC9F,MAAM,cAAc,KAAK,MAAM,IAAI,aAAa,CAAC,OAAO,YAAY,QAAQ,CAAC,CAAC;EAM9E,MAAM,MAAML,gBAAAA,MAAM,sBAAsB,YAAY;EAGpD,MAAM,aAAa,gBAAgB,IAAI,eAAe,UAAU,CAAC;AACjE,MAAI,eAAe,KAAA,EACjB,OAAM,IAAI,MAAM,6CAA6C,eAAe,UAAU,GAAG;AAG3F,WAAS,IAAI,YAAY,IAAI;AAC7B,gBAAc,KAAK,CAAC,gBAAgB,IAAI,CAAC;;CAI3C,MAAM,mBAAmB,gBAAgB,OAAO;AAChD,KAAI,SAAS,SAAS,iBACpB,OAAM,IAAI,MAAM,YAAY,iBAAiB,2BAA2B,SAAS,OAAO;AAG1F,QAAO,CAAC,UAAU,cAAc;;;;;;;AAQlC,SAAS,kBACP,SACA,gBACA,cACA,gBACA,aACU;CAEV,MAAM,aAAoB,YAAY,cAAc,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC;CAGxE,MAAM,sBAAsB,eAAe,UAAU;AACrD,KAAI,CAAC,WAAW,MAAM,QAAQ,IAAI,UAAU,KAAK,oBAAoB,CACnE,YAAW,KAAK,eAAe;AAOjC,YAAW,MAAM,GAAG,MAAMG,6BAAAA,gBAAgB,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;CAGlE,MAAM,UAAiB,EAAE;AACzB,MAAK,MAAM,OAAO,WAChB,KAAI,QAAQ,WAAW,KAAK,QAAQ,QAAQ,SAAS,GAAG,UAAU,KAAK,IAAI,UAAU,CACnF,SAAQ,KAAK,IAAI;CAKrB,MAAM,kCAAkB,IAAI,KAAkB;AAC9C,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,aAAaL,oBAAAA,kBAAkB,IAAI,EAAE;AAC3C,kBAAgB,IAAIQ,oBAAAA,gBAAgB,WAAW,EAAE,QAAQ,GAAG;;CAG9D,IAAI,WAAWC,eAAAA,SAAS,MAAM,CAC3B,QAAQ,oBAAoB,CAC5B,aAAa,SAAS,QAAQ,CAC9B,aAAa,eAAe,eAAe,CAC3C,aAAa,iBAAiB,aAAa;AAG9C,MAAK,MAAM,CAAC,YAAY,QAAQ,gBAAgB;EAC9C,MAAM,QAAQD,oBAAAA,gBAAgB,WAAW;EACzC,MAAM,eAAe,gBAAgB,IAAI,MAAM;AAC/C,MAAI,iBAAiB,KAAA,EACnB,OAAM,IAAI,MAAM,wCAAwC;EAI1D,MAAM,aAAaE,oBAAAA,0BACjB,IACD;EACD,MAAM,UAAU,KAAK,UAAU,WAAW;EAC1C,MAAM,YAAY,IAAI,aAAa,CAAC,OAAO,QAAQ;EACnD,MAAM,cAAcH,iBAAAA,KAAY,SAAS,UAAU;EAEnD,MAAM,kBAAkBE,eAAAA,SAAS,IAAI,YAAY,CAAC,aAAa,aAAa,aAAa;AAEzF,aAAW,SAAS,aAAa,iBAAiB,gBAAgB;;AAGpE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BT,SAAS,6BACP,QACA,mBACyB;CAEzB,MAAM,yBADa,OAAO,WACgB,WAAW,CAAC,KAAK,MAAkBE,oBAAAA,WAAW,EAAE,CAAC;CAC3F,MAAM,cAAcA,oBAAAA,WAAWf,gBAAAA,cAAc,gBAAgB,OAAO,aAAa,CAAC,CAAC;AAEnF,QAAO;EACL,YAAYe,oBAAAA,WAAW,OAAO,WAAW,WAAW,CAAC;EACrD,YAAY;EACZ,cAAc;EACd,aAAa,OAAO;EACpB,aAAa,OAAO;EACrB;;;;;;;AAQH,SAAS,mBACP,cACA,SACA,cACA,qBACA,kBACQ;CACR,MAAM,cAAclB,eAAAA,cAAc,cAAc,QAAQ,KAAK,CAAC;AAC9D,SAAG,UAAU,aAAa,EAAE,WAAW,MAAM,CAAC;CAG9C,MAAM,mBAAmBC,UAAK,KAAK,aAAa,qBAAqB;CACrE,MAAM,mBAAmB,6BAA6B,cAAc,iBAAiB;AACrF,SAAG,cAAc,kBAAkB,KAAK,UAAU,kBAAkB,MAAM,EAAE,CAAC;CAG7E,MAAM,qBAAqBA,UAAK,KAAK,aAAa,wBAAwB;CAC1E,MAAM,aAAsC,EAAE;AAC9C,MAAK,MAAM,CAAC,KAAK,QAAQ,qBAAqB;EAC5C,MAAM,cAAcQ,gBAAAA,MAAM,oBAAoB,IAAI;AAClD,aAAW,IAAI,UAAU,IAAI;;AAE/B,SAAG,cAAc,oBAAoB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AAEzE,QAAO;;;;;;;;;;AAWT,eAAsB,OACpB,SACA,SACA,KAC0B;AAC1B,KAAI,QAAQ,qBAAqB,KAAA,EAC/B,OAAM,IAAI,MAAM,wCAAwC;CAG1D,MAAM,eAAeU,uBAAAA,oBAAoB,QAAQ,cAAc,IAAI;CACnE,MAAM,WAAWC,uBAAAA,SAAS,KAAK,aAAa;CAE5C,MAAM,QAAQ,SAAS,OAAO;AAC9B,KAAI,UAAU,KAAA,EACZ,OAAM,IAAI,MAAM,6BAA6B;CAG/C,MAAM,UAAUC,eAAAA,YAAY,QAAQ,QAAQ;CAC5C,MAAM,cAAc,SAAS,MAAM,QAAQ;AAC3C,KAAI,gBAAgB,KAAA,EAClB,OAAM,IAAI,MAAM,8BAA8B;CAIhD,MAAM,kBAAkB,YAAY,iBAAiB;AACrD,KAAI,oBAAoB,KAAA,EACtB,OAAM,IAAI,MAAM,mEAAmE;CAIrF,MAAM,cAAc,gBAAgB,cAAc,QAAQ;AAE1D,KAAIC,eAAAA,WAAW,IAAI,QAAQ,YAAY,KACrC,SAAQ,MAAM,0CAA0C;CAG1D,MAAM,SAAS,MAAMC,gBAAAA,oBAAoB,QAAQ,iBAAiB;CAGlE,MAAM,kBAAkB,MAAMC,aAAAA,iBAC5B,QACA,iBACA,mBACA,QAAQ,gBACR,QAAQ,WAAW,MACpB;AAED,KAAI,oBAAoB,QAAQ,oBAAoB,KAAA,EAClD,OAAM,IAAI,MAAM,8CAA8C;CAIhE,MAAM,mBAAmB,MAAM,aAAa,CAAC,sBAAsB;AACnE,KAAI,qBAAqB,KAAA,EACvB,OAAM,IAAI,MAAM,yCAAyC;CAG3D,MAAM,MAAMC,YAAAA,SAAS,KAAK,CAAC,UAAU;CACrC,MAAM,gBAAgBC,WAAAA,cAAc,gBAClC,iBACA,KAAA,GACA,KACA,iBACD;CAID,MAAM,eAAe,sBAAsB,eAAe,SAD9B,YAAY,aAAa,CAAC,KACgC,CAAC;CAGvF,MAAM,CAAC,gBAAgB,uBAAuB,sBAC5C,eACA,aACA,MAAM,KAAK,CACZ;AAED,KAAIJ,eAAAA,WAAW,IAAI,QAAQ,YAAY,KACrC,SAAQ,MAAM,YAAY,eAAe,KAAK,yCAAyC;CAIzF,MAAM,mBAAmBX,iBAAAA,KAAK,KAAK;CAInC,MAAM,oCAAoB,IAAI,KAA+B;AAC7D,MAAK,MAAM,CAAC,IAAI,QAAQ,eACtB,mBAAkB,IAAII,oBAAAA,gBAAgB,GAAG,EAAE,IAAI;CAGjD,MAAM,CAAC,cAAc,kBAAkBY,oBAAAA,SAAS,YAAY,eAAe,kBAAkB;AAE7F,KAAIL,eAAAA,WAAW,IAAI,QAAQ,YAAY,KACrC,SAAQ,MAAM,aAAa,eAAe,KAAK,oBAAoB;CAIrE,MAAM,qCAAqB,IAAI,KAA+B;AAC9D,MAAK,MAAM,CAAC,OAAO,QAAQ,eAEzB,MAAK,MAAM,CAAC,OAAO,eACjB,KAAIP,oBAAAA,gBAAgB,GAAG,KAAK,OAAO;AACjC,qBAAmB,IAAI,IAAI,IAAI;AAC/B;;CAMN,MAAM,eAAe,kBACnB,SACA,MAAM,KAAK,EACX,kBACA,oBACA,YACD;CAED,MAAM,oBAAoB,MAAM,aAAa,CAAC,sBAAsB;AACpE,KAAI,sBAAsB,KAAA,EACxB,OAAM,IAAI,MAAM,yCAAyC;CAI3D,MAAM,iBAAiB,YAAY,aAAa,CAAC,KAAK;CACtD,MAAM,oBAAoB,SAAS,YAAY,eAAe;CAC9D,IAAI;AACJ,KAAI,sBAAsB,KAAA,EACxB,kBAAiB,kBAAkB,aAAa;UAG5C,MAAM,KAAK,CAAC,UAAU,KAAK,eAAe,UAAU,CACtD,kBAAiB,MAAM,aAAa;KAEpC,OAAM,IAAI,MAAM,eAAe,eAAe,UAAU,CAAC,wBAAwB;CAKrF,MAAM,mBAAmB,cAAc,kBAAkB;CAEzD,IAAI,SAASa,WAAAA,eAAe,WAAW,cAAc,IAAI,EAAE,MAAM,aAAa,CAAC,CAAC,WAC9E,aACD;AAED,KAAI,qBAAqB,KAAA,EACvB,UAAS,OAAO,qBAAqB,iBAAiB;AAGxD,KAAI,QAAQ,YAAY,MAAM;EAO5B,MAAM,aALmB,OAAO,WAC9B,KAAA,GACA,mBACA,KAAA,EAEiC,CAAC,UAAU;AAC9C,UAAQ,IAAI,WAAW;AAEvB,SAAO;GACL,eAAe,iBAAiB,UAAU;GAC1C;GACD;;CASH,MAAM,wBAA+B,YAAY,cAAc,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC;CACnF,MAAM,WAAW,MAAM,KAAK;CAC5B,MAAM,cAAc,SAAS,UAAU;AACvC,KAAI,CAAC,sBAAsB,MAAM,MAAM,EAAE,UAAU,KAAK,YAAY,CAClE,uBAAsB,KAAK,SAAS;AAEtC,uBAAsB,MAAM,GAAG,MAAMhB,6BAAAA,gBAAgB,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;CAI7E,MAAM,mBAAmB,mBACvB,cACA,SACA,cACA,qBAPuB,sBAAsB,WAAW,MAAM,EAAE,UAAU,KAAK,YAAY,GAAG,EAS/F;AASD,OAAMiB,aAAAA,iBACJ,QACA,cATuB,OAAO,WAC9B,KAAA,GACA,mBACA,eAOgB,EAChB,oBACA,QAAQ,WAAW,MACpB;CAGD,MAAM,qBAAqB,SAAS,MAAM,QAAQ;AAClD,KAAI,uBAAuB,KAAA,GAAW;EACpC,MAAM,gBAAgB,mBAAmB,eAAe;AACxD,gBAAc,eAAe;AAC7B,qBAAmB,iBAAiB,cAAc;AAElD,qBAAmB,mBAAmB,iBAAiB;AACvD,WAAS,KAAK,aAAa;;AAG7B,KAAIP,eAAAA,WAAW,IAAI,QAAQ,YAAY,KACrC,SAAQ,MAAM,8BAA8B,aAAa,UAAU,GAAG;AAGxE,QAAO,EACL,eAAe,iBAAiB,UAAU,EAC3C"}
|
|
1
|
+
{"version":3,"file":"round2-CvrmylN1.cjs","names":["groupStateDir","path","fs","Ed25519Sha512","hexToBytes","VerifiableSecretSharingCommitment","CoefficientCommitment","identifierFromU16","round1","serde","EnvelopeFunction","ARID","compareXidBytes","XID","JSONWrapper","identifierToHex","Envelope","serializeDkgRound2Package","bytesToHex","resolveRegistryPath","Registry","parseAridUr","isVerbose","createStorageClient","getWithIndicator","CborDate","SealedRequest","dkgPart2","SealedResponse","putWithIndicator"],"sources":["../src/cmd/dkg/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG participant round 2 command.\n *\n * Port of cmd/dkg/participant/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { ARID, JSON as JSONWrapper, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport type { XIDDocument } from \"@bcts/xid\";\n\nimport { type GroupRecord, Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { groupStateDir, isVerbose } from \"../../common.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { parseAridUr } from \"../common.js\";\nimport {\n dkgPart2,\n serializeDkgRound2Package,\n identifierFromU16,\n identifierToHex,\n hexToBytes,\n bytesToHex,\n type DkgRound1Package,\n type DkgRound1SecretPackage,\n type DkgRound2SecretPackage,\n type FrostIdentifier,\n} from \"../../../frost/index.js\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\nimport { round1, CoefficientCommitment, VerifiableSecretSharingCommitment } from \"@frosts/core\";\n\n/**\n * Options for the DKG round2 command.\n */\nexport interface DkgRound2Options {\n registryPath?: string;\n groupId: string;\n timeoutSeconds?: number;\n preview?: boolean;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the DKG round2 command.\n */\nexport interface DkgRound2Result {\n listeningArid: string;\n envelopeUr?: string;\n}\n\n/**\n * Persisted round 1 state loaded from disk.\n */\ninterface Round1State {\n secretPackage: DkgRound1SecretPackage;\n ourRound1Package: DkgRound1Package;\n}\n\n/**\n * Extracted round 1 packages from coordinator request.\n */\ntype Round1Packages = [Map<FrostIdentifier, DkgRound1Package>, [XID, DkgRound1Package][]];\n\n/**\n * Load persisted round 1 state from disk.\n *\n * Port of round1_secret loading from cmd/dkg/participant/round2.rs lines 86-97.\n */\nfunction loadRound1State(registryPath: string, groupId: ARID): Round1State {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n const round1SecretPath = path.join(packagesDir, \"round1_secret.json\");\n\n if (!fs.existsSync(round1SecretPath)) {\n throw new Error(\n `Round 1 secret not found at ${round1SecretPath}. Did you respond to the invite?`,\n );\n }\n\n // Mirrors Rust `frost::keys::dkg::round1::SecretPackage` JSON\n // (`frost-rust/frost-core/src/keys/dkg.rs:120-139`): no `header`,\n // snake_case `min_signers` / `max_signers`, identifier and\n // coefficients as lowercase hex strings, commitment as a flat array\n // of hex strings.\n const secretJson = JSON.parse(fs.readFileSync(round1SecretPath, \"utf-8\")) as {\n identifier: string;\n coefficients: string[];\n commitment: string[];\n min_signers: number;\n max_signers: number;\n };\n\n // Deserialize coefficients (scalars)\n const coefficients = secretJson.coefficients.map((hex) =>\n Ed25519Sha512.deserializeScalar(hexToBytes(hex)),\n );\n\n // Deserialize commitment (coefficient commitments)\n const coefficientCommitments = secretJson.commitment.map((hex) =>\n CoefficientCommitment.deserialize(Ed25519Sha512, hexToBytes(hex)),\n );\n\n const commitment = new VerifiableSecretSharingCommitment(Ed25519Sha512, coefficientCommitments);\n\n // Create the secret package\n // Need to find the actual identifier u16 value from the coefficients array length or saved state\n // The identifier is typically serialized as a scalar, but we need the u16 value\n // Parse it from the hex string - first 2 bytes as little-endian u16\n const idBytes = hexToBytes(secretJson.identifier);\n let identifierU16 = 1;\n if (idBytes.length >= 2) {\n identifierU16 = idBytes[0] | (idBytes[1] << 8);\n }\n if (identifierU16 === 0) {\n identifierU16 = 1; // Default to 1 if parsing failed\n }\n\n const parsedIdentifier = identifierFromU16(identifierU16);\n\n const secretPackage: DkgRound1SecretPackage = new round1.SecretPackage(\n Ed25519Sha512,\n parsedIdentifier,\n coefficients,\n commitment,\n secretJson.min_signers,\n secretJson.max_signers,\n );\n\n // Load the round 1 package as well\n const round1PackagePath = path.join(packagesDir, \"round1_package.json\");\n const packageJson = JSON.parse(fs.readFileSync(round1PackagePath, \"utf-8\")) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const ourRound1Package = serde.round1PackageFromJson(packageJson);\n\n return { secretPackage, ourRound1Package };\n}\n\n/**\n * Validate the round 2 request from the coordinator.\n *\n * Port of request validation from cmd/dkg/participant/round2.rs lines 118-158.\n */\nfunction validateRound2Request(\n sealedRequest: SealedRequest,\n groupId: ARID,\n expectedCoordinator: XID,\n): ARID {\n // Validate the request function\n if (!sealedRequest.function().equals(EnvelopeFunction.fromString(\"dkgRound2\"))) {\n throw new Error(`Unexpected request function: ${sealedRequest.function().toString()}`);\n }\n\n // Validate the sender is the expected coordinator\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} ` +\n `(expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n\n // Validate the group ID matches\n const requestGroupIdEnvelope = sealedRequest.objectForParameter(\"group\");\n if (requestGroupIdEnvelope === undefined) {\n throw new Error(\"Request missing group parameter\");\n }\n const requestGroupId = requestGroupIdEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n if (requestGroupId.urString() !== groupId.urString()) {\n throw new Error(\n `Request group ID ${requestGroupId.urString()} does not match expected ${groupId.urString()}`,\n );\n }\n\n // Extract where we should post our response\n const responseAridEnvelope = sealedRequest.objectForParameter(\"responseArid\");\n if (responseAridEnvelope === undefined) {\n throw new Error(\"Request missing responseArid parameter\");\n }\n const responseArid = responseAridEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n\n return responseArid;\n}\n\n/**\n * Extract round 1 packages from the request and convert to Map<Identifier, Package>.\n *\n * Port of `extract_round1_packages()` from cmd/dkg/participant/round2.rs lines 291-366.\n */\nfunction extractRound1Packages(\n request: SealedRequest,\n groupRecord: GroupRecord,\n ownerXid: XID,\n): Round1Packages {\n // Build XID -> Identifier mapping based on sorted participant order\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add owner if not already in list\n const ownerUrString = ownerXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === ownerUrString)) {\n sortedXids.push(ownerXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build XID -> Identifier mapping (1-indexed)\n const xidToIdentifier = new Map<string, FrostIdentifier>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n xidToIdentifier.set(deduped[i].urString(), identifier);\n }\n\n const myXidStr = ownerXid.urString();\n\n // Extract all round1Package parameters\n const packages = new Map<FrostIdentifier, DkgRound1Package>();\n const packagesByXid: [XID, DkgRound1Package][] = [];\n\n const packageEnvelopes = request.objectsForParameter(\"round1Package\");\n for (const packageEnvelope of packageEnvelopes) {\n // Extract participant XID from the envelope\n const participantEnvelope = packageEnvelope.objectForPredicate(\"participant\");\n if (participantEnvelope === undefined) {\n throw new Error(\"round1Package missing participant predicate\");\n }\n const participantXid = participantEnvelope.extractSubject((cbor) => XID.fromTaggedCbor(cbor));\n\n // Skip our own package\n if (participantXid.urString() === myXidStr) {\n continue;\n }\n\n // Extract the package bytes (stored as JSON tag)\n const packageJson = packageEnvelope.extractSubject((cbor) => JSONWrapper.fromTaggedCbor(cbor));\n const packageData = JSON.parse(new TextDecoder().decode(packageJson.toData())) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const pkg = serde.round1PackageFromJson(packageData);\n\n // Get the identifier for this participant\n const identifier = xidToIdentifier.get(participantXid.urString());\n if (identifier === undefined) {\n throw new Error(`Unknown participant XID in round1Package: ${participantXid.urString()}`);\n }\n\n packages.set(identifier, pkg);\n packagesByXid.push([participantXid, pkg]);\n }\n\n // Validate we have the expected number of packages\n const expectedPackages = xidToIdentifier.size - 1; // Exclude ourselves\n if (packages.size !== expectedPackages) {\n throw new Error(`Expected ${expectedPackages} Round 1 packages, found ${packages.size}`);\n }\n\n return [packages, packagesByXid];\n}\n\n/**\n * Build the response body containing Round 2 packages.\n *\n * Port of `build_response_body()` from cmd/dkg/participant/round2.rs lines 373-425.\n */\nfunction buildResponseBody(\n groupId: ARID,\n participantXid: XID,\n responseArid: ARID,\n round2Packages: Map<FrostIdentifier, unknown>,\n groupRecord: GroupRecord,\n): Envelope {\n // Build Identifier -> XID mapping\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add participant if not already in list\n const participantUrString = participantXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === participantUrString)) {\n sortedXids.push(participantXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build Identifier -> XID mapping (1-indexed)\n const identifierToXid = new Map<string, XID>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n identifierToXid.set(identifierToHex(identifier), deduped[i]);\n }\n\n let envelope = Envelope.unit()\n .addType(\"dkgRound2Response\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"participant\", participantXid)\n .addAssertion(\"response_arid\", responseArid);\n\n // Add each Round 2 package with the recipient's XID\n for (const [identifier, pkg] of round2Packages) {\n const idHex = identifierToHex(identifier);\n const recipientXid = identifierToXid.get(idHex);\n if (recipientXid === undefined) {\n throw new Error(\"Unknown identifier in round2_packages\");\n }\n\n // Serialize package to JSON and wrap in CBOR JSON tag\n const serialized = serializeDkgRound2Package(\n pkg as Parameters<typeof serializeDkgRound2Package>[0],\n );\n const jsonStr = JSON.stringify(serialized);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const jsonWrapper = JSONWrapper.fromData(jsonBytes);\n\n const packageEnvelope = Envelope.new(jsonWrapper).addAssertion(\"recipient\", recipientXid);\n\n envelope = envelope.addAssertion(\"round2Package\", packageEnvelope);\n }\n\n return envelope;\n}\n\n/**\n * Serialize round 2 secret package to JSON format for persistence.\n *\n * Mirrors the on-disk shape produced by Rust\n * `serde_json::to_vec_pretty(&frost::keys::dkg::round2::SecretPackage)`\n * (see `frost-rust/frost-core/src/keys/dkg.rs:269-287`):\n *\n * ```json\n * {\n * \"identifier\": \"<lowercase hex scalar>\",\n * \"commitment\": [\"<hex>\", \"<hex>\", ...],\n * \"secret_share\": \"<hex>\",\n * \"min_signers\": <u16>,\n * \"max_signers\": <u16>\n * }\n * ```\n *\n * `frost::keys::dkg::round2::SecretPackage` is\n * `#[serde(deny_unknown_fields)]`. The earlier port emitted\n * camelCase keys (`secretShare`, `minSigners`, `maxSigners`), a\n * nested `commitment.coefficients` shape, and a numeric\n * `identifier` — all of which Rust's standard derive would\n * reject and which had no chance of round-tripping with Rust.\n *\n * `participantIndex` is unused now that the identifier comes\n * directly from `secret.identifier.serialize()`; we keep it in the\n * signature for source-level parity with the call sites.\n */\nfunction serializeRound2SecretPackage(\n secret: DkgRound2SecretPackage,\n _participantIndex: number,\n): Record<string, unknown> {\n const commitment = secret.commitment;\n const commitmentCoefficients = commitment.serialize().map((c: Uint8Array) => bytesToHex(c));\n const secretShare = bytesToHex(Ed25519Sha512.serializeScalar(secret.secretShare()));\n\n return {\n identifier: bytesToHex(secret.identifier.serialize()),\n commitment: commitmentCoefficients,\n secret_share: secretShare,\n min_signers: secret.minSigners,\n max_signers: secret.maxSigners,\n };\n}\n\n/**\n * Persist round 2 state to disk.\n *\n * Port of round 2 secret persistence from cmd/dkg/participant/round2.rs lines 229-251.\n */\nfunction persistRound2State(\n registryPath: string,\n groupId: ARID,\n round2Secret: DkgRound2SecretPackage,\n round1PackagesByXid: [XID, DkgRound1Package][],\n participantIndex: number,\n): string {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(packagesDir, { recursive: true });\n\n // Persist Round 2 secret\n const round2SecretPath = path.join(packagesDir, \"round2_secret.json\");\n const round2SecretJson = serializeRound2SecretPackage(round2Secret, participantIndex);\n fs.writeFileSync(round2SecretPath, JSON.stringify(round2SecretJson, null, 2));\n\n // Persist received Round 1 packages for finalize phase\n const round1PackagesPath = path.join(packagesDir, \"collected_round1.json\");\n const round1Json: Record<string, unknown> = {};\n for (const [xid, pkg] of round1PackagesByXid) {\n const packageJson = serde.round1PackageToJson(pkg);\n round1Json[xid.urString()] = packageJson;\n }\n fs.writeFileSync(round1PackagesPath, JSON.stringify(round1Json, null, 2));\n\n return round2SecretPath;\n}\n\n/**\n * Execute the DKG participant round 2 command.\n *\n * Responds to the Round 2 request from the coordinator, runs FROST DKG part2\n * to generate Round 2 packages, and posts the response back.\n *\n * Port of `CommandArgs::exec()` from cmd/dkg/participant/round2.rs lines 55-288.\n */\nexport async function round2(\n _client: StorageClient | undefined,\n options: DkgRound2Options,\n cwd: string,\n): Promise<DkgRound2Result> {\n if (options.storageSelection === undefined) {\n throw new Error(\"Hubert storage is required for round2\");\n }\n\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const groupId = parseAridUr(options.groupId);\n const groupRecord = registry.group(groupId);\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Get the ARID where we're listening for the Round 2 request\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\"No listening ARID for this group. Did you respond to the invite?\");\n }\n\n // Load our Round 1 secret\n const round1State = loadRound1State(registryPath, groupId);\n\n if (isVerbose() || options.verbose === true) {\n console.error(\"Fetching Round 2 request from Hubert...\");\n }\n\n const client = await createStorageClient(options.storageSelection);\n\n // Fetch the Round 2 request from where we're listening\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"Round 2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (requestEnvelope === null || requestEnvelope === undefined) {\n throw new Error(\"Round 2 request not found in Hubert storage\");\n }\n\n // Decrypt and validate the request\n const ownerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (ownerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n const now = CborDate.now().datetime();\n const sealedRequest = SealedRequest.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n ownerPrivateKeys,\n );\n\n // Validate the request and extract response ARID\n const expectedCoordinator = groupRecord.coordinator().xid();\n const responseArid = validateRound2Request(sealedRequest, groupId, expectedCoordinator);\n\n // Extract Round 1 packages from the request\n const [round1Packages, round1PackagesByXid] = extractRound1Packages(\n sealedRequest,\n groupRecord,\n owner.xid(),\n );\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Received ${round1Packages.size} Round 1 packages. Running DKG part2...`);\n }\n\n // Allocate next response ARID for the finalize phase\n const nextResponseArid = ARID.new();\n\n // Run FROST DKG part2\n // Convert Map<Identifier, Package> to Map<string, Package> for dkgPart2\n const round1PackagesHex = new Map<string, DkgRound1Package>();\n for (const [id, pkg] of round1Packages) {\n round1PackagesHex.set(identifierToHex(id), pkg);\n }\n\n const [round2Secret, round2Packages] = dkgPart2(round1State.secretPackage, round1PackagesHex);\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Generated ${round2Packages.size} Round 2 packages.`);\n }\n\n // Convert round2Packages back to use Identifier keys for buildResponseBody\n const round2PackagesById = new Map<FrostIdentifier, unknown>();\n for (const [idHex, pkg] of round2Packages) {\n // Find the identifier that matches this hex\n for (const [id] of round1Packages) {\n if (identifierToHex(id) === idHex) {\n round2PackagesById.set(id, pkg);\n break;\n }\n }\n }\n\n // Build response with Round 2 packages\n const responseBody = buildResponseBody(\n groupId,\n owner.xid(),\n nextResponseArid,\n round2PackagesById,\n groupRecord,\n );\n\n const signerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no signing keys\");\n }\n\n // Get coordinator's XID document for encryption\n const coordinatorXid = groupRecord.coordinator().xid();\n const coordinatorRecord = registry.participant(coordinatorXid);\n let coordinatorDoc: XIDDocument;\n if (coordinatorRecord !== undefined) {\n coordinatorDoc = coordinatorRecord.xidDocument();\n } else {\n // Check if coordinator is the owner\n if (owner.xid().urString() === coordinatorXid.urString()) {\n coordinatorDoc = owner.xidDocument();\n } else {\n throw new Error(`Coordinator ${coordinatorXid.urString()} not found in registry`);\n }\n }\n\n // Get peer continuation from the request\n const peerContinuation = sealedRequest.peerContinuation();\n\n let sealed = SealedResponse.newSuccess(sealedRequest.id(), owner.xidDocument()).withResult(\n responseBody,\n );\n\n if (peerContinuation !== undefined) {\n sealed = sealed.withPeerContinuation(peerContinuation);\n }\n\n if (options.preview === true) {\n // Show the response envelope structure without encryption\n const unsealedEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n undefined,\n );\n const envelopeUr = unsealedEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n listeningArid: nextResponseArid.urString(),\n envelopeUr,\n };\n }\n\n // Calculate participant index for serialization. Sort by XID byte\n // order (mirrors Rust `XID::cmp`) so the 1-indexed position matches\n // what the coordinator used when assigning FROST identifiers. The\n // earlier port sorted by UR string via `Array.sort()` (default JS\n // string compare), which diverges from Rust byte order for any\n // byte ≥ 0x80.\n const sortedParticipantXids: XID[] = groupRecord.participants().map((p) => p.xid());\n const ownerXid = owner.xid();\n const ownerXidStr = ownerXid.urString();\n if (!sortedParticipantXids.some((x) => x.urString() === ownerXidStr)) {\n sortedParticipantXids.push(ownerXid);\n }\n sortedParticipantXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n const participantIndex = sortedParticipantXids.findIndex((x) => x.urString() === ownerXidStr) + 1; // 1-indexed\n\n // Persist Round 2 secret and collected round1 packages\n const round2SecretPath = persistRound2State(\n registryPath,\n groupId,\n round2Secret,\n round1PackagesByXid,\n participantIndex,\n );\n\n const responseEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n coordinatorDoc,\n );\n\n // Post the response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Round 2 Response\",\n options.verbose ?? false,\n );\n\n // Update contributions in registry\n const updatedGroupRecord = registry.group(groupId);\n if (updatedGroupRecord !== undefined) {\n const contributions = updatedGroupRecord.contributions();\n contributions.round2Secret = round2SecretPath;\n updatedGroupRecord.setContributions(contributions);\n // Set new listening ARID for finalize phase\n updatedGroupRecord.setListeningAtArid(nextResponseArid);\n registry.save(registryPath);\n }\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Posted Round 2 response to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: nextResponseArid.urString(),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,SAAS,gBAAgB,cAAsB,SAA4B;CACzE,MAAM,cAAcA,eAAAA,cAAc,cAAc,QAAQ,IAAI,CAAC;CAC7D,MAAM,mBAAmBC,UAAK,KAAK,aAAa,oBAAoB;CAEpE,IAAI,CAACC,QAAG,WAAW,gBAAgB,GACjC,MAAM,IAAI,MACR,+BAA+B,iBAAiB,iCAClD;CAQF,MAAM,aAAa,KAAK,MAAMA,QAAG,aAAa,kBAAkB,OAAO,CAAC;CASxE,MAAM,eAAe,WAAW,aAAa,KAAK,QAChDC,gBAAAA,cAAc,kBAAkBC,oBAAAA,WAAW,GAAG,CAAC,CACjD;CAOA,MAAM,aAAa,IAAIC,aAAAA,kCAAkCF,gBAAAA,eAJ1B,WAAW,WAAW,KAAK,QACxDG,aAAAA,sBAAsB,YAAYH,gBAAAA,eAAeC,oBAAAA,WAAW,GAAG,CAAC,CAG2B,CAAC;CAM9F,MAAM,UAAUA,oBAAAA,WAAW,WAAW,UAAU;CAChD,IAAI,gBAAgB;CACpB,IAAI,QAAQ,UAAU,GACpB,gBAAgB,QAAQ,KAAM,QAAQ,MAAM;CAE9C,IAAI,kBAAkB,GACpB,gBAAgB;CAGlB,MAAM,mBAAmBG,oBAAAA,kBAAkB,aAAa;CAExD,MAAM,gBAAwC,IAAIC,aAAAA,OAAO,cACvDL,gBAAAA,eACA,kBACA,cACA,YACA,WAAW,aACX,WAAW,WACb;CAGA,MAAM,oBAAoBF,UAAK,KAAK,aAAa,qBAAqB;CACtE,MAAM,cAAc,KAAK,MAAMC,QAAG,aAAa,mBAAmB,OAAO,CAAC;CAQ1E,OAAO;EAAE;EAAe,kBAFCO,gBAAAA,MAAM,sBAAsB,WAEd;CAAE;AAC3C;;;;;;AAOA,SAAS,sBACP,eACA,SACA,qBACM;CAEN,IAAI,CAAC,cAAc,SAAS,EAAE,OAAOC,eAAAA,SAAiB,WAAW,WAAW,CAAC,GAC3E,MAAM,IAAI,MAAM,gCAAgC,cAAc,SAAS,EAAE,SAAS,GAAG;CAIvF,IAAI,cAAc,OAAO,EAAE,IAAI,EAAE,SAAS,MAAM,oBAAoB,SAAS,GAC3E,MAAM,IAAI,MACR,8BAA8B,cAAc,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,yBAC3C,oBAAoB,SAAS,EAAE,EAC5D;CAIF,MAAM,yBAAyB,cAAc,mBAAmB,OAAO;CACvE,IAAI,2BAA2B,KAAA,GAC7B,MAAM,IAAI,MAAM,iCAAiC;CAEnD,MAAM,iBAAiB,uBAAuB,gBAAgB,SAASC,iBAAAA,KAAK,eAAe,IAAI,CAAC;CAChG,IAAI,eAAe,SAAS,MAAM,QAAQ,SAAS,GACjD,MAAM,IAAI,MACR,oBAAoB,eAAe,SAAS,EAAE,2BAA2B,QAAQ,SAAS,GAC5F;CAIF,MAAM,uBAAuB,cAAc,mBAAmB,cAAc;CAC5E,IAAI,yBAAyB,KAAA,GAC3B,MAAM,IAAI,MAAM,wCAAwC;CAI1D,OAFqB,qBAAqB,gBAAgB,SAASA,iBAAAA,KAAK,eAAe,IAAI,CAEzE;AACpB;;;;;;AAOA,SAAS,sBACP,SACA,aACA,UACgB;CAEhB,MAAM,aAAoB,YAAY,aAAa,EAAE,KAAK,MAAM,EAAE,IAAI,CAAC;CAGvE,MAAM,gBAAgB,SAAS,SAAS;CACxC,IAAI,CAAC,WAAW,MAAM,QAAQ,IAAI,SAAS,MAAM,aAAa,GAC5D,WAAW,KAAK,QAAQ;CAO1B,WAAW,MAAM,GAAG,MAAMC,6BAAAA,gBAAgB,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;CAGjE,MAAM,UAAiB,CAAC;CACxB,KAAK,MAAM,OAAO,YAChB,IAAI,QAAQ,WAAW,KAAK,QAAQ,QAAQ,SAAS,GAAG,SAAS,MAAM,IAAI,SAAS,GAClF,QAAQ,KAAK,GAAG;CAKpB,MAAM,kCAAkB,IAAI,IAA6B;CACzD,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,aAAaL,oBAAAA,kBAAkB,IAAI,CAAC;EAC1C,gBAAgB,IAAI,QAAQ,GAAG,SAAS,GAAG,UAAU;CACvD;CAEA,MAAM,WAAW,SAAS,SAAS;CAGnC,MAAM,2BAAW,IAAI,IAAuC;CAC5D,MAAM,gBAA2C,CAAC;CAElD,MAAM,mBAAmB,QAAQ,oBAAoB,eAAe;CACpE,KAAK,MAAM,mBAAmB,kBAAkB;EAE9C,MAAM,sBAAsB,gBAAgB,mBAAmB,aAAa;EAC5E,IAAI,wBAAwB,KAAA,GAC1B,MAAM,IAAI,MAAM,6CAA6C;EAE/D,MAAM,iBAAiB,oBAAoB,gBAAgB,SAASM,iBAAAA,IAAI,eAAe,IAAI,CAAC;EAG5F,IAAI,eAAe,SAAS,MAAM,UAChC;EAIF,MAAM,cAAc,gBAAgB,gBAAgB,SAASC,iBAAAA,KAAY,eAAe,IAAI,CAAC;EAC7F,MAAM,cAAc,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,YAAY,OAAO,CAAC,CAAC;EAM7E,MAAM,MAAML,gBAAAA,MAAM,sBAAsB,WAAW;EAGnD,MAAM,aAAa,gBAAgB,IAAI,eAAe,SAAS,CAAC;EAChE,IAAI,eAAe,KAAA,GACjB,MAAM,IAAI,MAAM,6CAA6C,eAAe,SAAS,GAAG;EAG1F,SAAS,IAAI,YAAY,GAAG;EAC5B,cAAc,KAAK,CAAC,gBAAgB,GAAG,CAAC;CAC1C;CAGA,MAAM,mBAAmB,gBAAgB,OAAO;CAChD,IAAI,SAAS,SAAS,kBACpB,MAAM,IAAI,MAAM,YAAY,iBAAiB,2BAA2B,SAAS,MAAM;CAGzF,OAAO,CAAC,UAAU,aAAa;AACjC;;;;;;AAOA,SAAS,kBACP,SACA,gBACA,cACA,gBACA,aACU;CAEV,MAAM,aAAoB,YAAY,aAAa,EAAE,KAAK,MAAM,EAAE,IAAI,CAAC;CAGvE,MAAM,sBAAsB,eAAe,SAAS;CACpD,IAAI,CAAC,WAAW,MAAM,QAAQ,IAAI,SAAS,MAAM,mBAAmB,GAClE,WAAW,KAAK,cAAc;CAOhC,WAAW,MAAM,GAAG,MAAMG,6BAAAA,gBAAgB,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;CAGjE,MAAM,UAAiB,CAAC;CACxB,KAAK,MAAM,OAAO,YAChB,IAAI,QAAQ,WAAW,KAAK,QAAQ,QAAQ,SAAS,GAAG,SAAS,MAAM,IAAI,SAAS,GAClF,QAAQ,KAAK,GAAG;CAKpB,MAAM,kCAAkB,IAAI,IAAiB;CAC7C,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,aAAaL,oBAAAA,kBAAkB,IAAI,CAAC;EAC1C,gBAAgB,IAAIQ,oBAAAA,gBAAgB,UAAU,GAAG,QAAQ,EAAE;CAC7D;CAEA,IAAI,WAAWC,eAAAA,SAAS,KAAK,EAC1B,QAAQ,mBAAmB,EAC3B,aAAa,SAAS,OAAO,EAC7B,aAAa,eAAe,cAAc,EAC1C,aAAa,iBAAiB,YAAY;CAG7C,KAAK,MAAM,CAAC,YAAY,QAAQ,gBAAgB;EAC9C,MAAM,QAAQD,oBAAAA,gBAAgB,UAAU;EACxC,MAAM,eAAe,gBAAgB,IAAI,KAAK;EAC9C,IAAI,iBAAiB,KAAA,GACnB,MAAM,IAAI,MAAM,uCAAuC;EAIzD,MAAM,aAAaE,oBAAAA,0BACjB,GACF;EACA,MAAM,UAAU,KAAK,UAAU,UAAU;EACzC,MAAM,YAAY,IAAI,YAAY,EAAE,OAAO,OAAO;EAClD,MAAM,cAAcH,iBAAAA,KAAY,SAAS,SAAS;EAElD,MAAM,kBAAkBE,eAAAA,SAAS,IAAI,WAAW,EAAE,aAAa,aAAa,YAAY;EAExF,WAAW,SAAS,aAAa,iBAAiB,eAAe;CACnE;CAEA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAS,6BACP,QACA,mBACyB;CAEzB,MAAM,yBADa,OAAO,WACgB,UAAU,EAAE,KAAK,MAAkBE,oBAAAA,WAAW,CAAC,CAAC;CAC1F,MAAM,cAAcA,oBAAAA,WAAWf,gBAAAA,cAAc,gBAAgB,OAAO,YAAY,CAAC,CAAC;CAElF,OAAO;EACL,YAAYe,oBAAAA,WAAW,OAAO,WAAW,UAAU,CAAC;EACpD,YAAY;EACZ,cAAc;EACd,aAAa,OAAO;EACpB,aAAa,OAAO;CACtB;AACF;;;;;;AAOA,SAAS,mBACP,cACA,SACA,cACA,qBACA,kBACQ;CACR,MAAM,cAAclB,eAAAA,cAAc,cAAc,QAAQ,IAAI,CAAC;CAC7D,QAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;CAG7C,MAAM,mBAAmBC,UAAK,KAAK,aAAa,oBAAoB;CACpE,MAAM,mBAAmB,6BAA6B,cAAc,gBAAgB;CACpF,QAAG,cAAc,kBAAkB,KAAK,UAAU,kBAAkB,MAAM,CAAC,CAAC;CAG5E,MAAM,qBAAqBA,UAAK,KAAK,aAAa,uBAAuB;CACzE,MAAM,aAAsC,CAAC;CAC7C,KAAK,MAAM,CAAC,KAAK,QAAQ,qBAAqB;EAC5C,MAAM,cAAcQ,gBAAAA,MAAM,oBAAoB,GAAG;EACjD,WAAW,IAAI,SAAS,KAAK;CAC/B;CACA,QAAG,cAAc,oBAAoB,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;CAExE,OAAO;AACT;;;;;;;;;AAUA,eAAsB,OACpB,SACA,SACA,KAC0B;CAC1B,IAAI,QAAQ,qBAAqB,KAAA,GAC/B,MAAM,IAAI,MAAM,uCAAuC;CAGzD,MAAM,eAAeU,uBAAAA,oBAAoB,QAAQ,cAAc,GAAG;CAClE,MAAM,WAAWC,uBAAAA,SAAS,KAAK,YAAY;CAE3C,MAAM,QAAQ,SAAS,MAAM;CAC7B,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,4BAA4B;CAG9C,MAAM,UAAUC,eAAAA,YAAY,QAAQ,OAAO;CAC3C,MAAM,cAAc,SAAS,MAAM,OAAO;CAC1C,IAAI,gBAAgB,KAAA,GAClB,MAAM,IAAI,MAAM,6BAA6B;CAI/C,MAAM,kBAAkB,YAAY,gBAAgB;CACpD,IAAI,oBAAoB,KAAA,GACtB,MAAM,IAAI,MAAM,kEAAkE;CAIpF,MAAM,cAAc,gBAAgB,cAAc,OAAO;CAEzD,IAAIC,eAAAA,UAAU,KAAK,QAAQ,YAAY,MACrC,QAAQ,MAAM,yCAAyC;CAGzD,MAAM,SAAS,MAAMC,iBAAAA,oBAAoB,QAAQ,gBAAgB;CAGjE,MAAM,kBAAkB,MAAMC,aAAAA,iBAC5B,QACA,iBACA,mBACA,QAAQ,gBACR,QAAQ,WAAW,KACrB;CAEA,IAAI,oBAAoB,QAAQ,oBAAoB,KAAA,GAClD,MAAM,IAAI,MAAM,6CAA6C;CAI/D,MAAM,mBAAmB,MAAM,YAAY,EAAE,qBAAqB;CAClE,IAAI,qBAAqB,KAAA,GACvB,MAAM,IAAI,MAAM,wCAAwC;CAG1D,MAAM,MAAMC,YAAAA,SAAS,IAAI,EAAE,SAAS;CACpC,MAAM,gBAAgBC,WAAAA,cAAc,gBAClC,iBACA,KAAA,GACA,KACA,gBACF;CAIA,MAAM,eAAe,sBAAsB,eAAe,SAD9B,YAAY,YAAY,EAAE,IAC+B,CAAC;CAGtF,MAAM,CAAC,gBAAgB,uBAAuB,sBAC5C,eACA,aACA,MAAM,IAAI,CACZ;CAEA,IAAIJ,eAAAA,UAAU,KAAK,QAAQ,YAAY,MACrC,QAAQ,MAAM,YAAY,eAAe,KAAK,wCAAwC;CAIxF,MAAM,mBAAmBX,iBAAAA,KAAK,IAAI;CAIlC,MAAM,oCAAoB,IAAI,IAA8B;CAC5D,KAAK,MAAM,CAAC,IAAI,QAAQ,gBACtB,kBAAkB,IAAII,oBAAAA,gBAAgB,EAAE,GAAG,GAAG;CAGhD,MAAM,CAAC,cAAc,kBAAkBY,oBAAAA,SAAS,YAAY,eAAe,iBAAiB;CAE5F,IAAIL,eAAAA,UAAU,KAAK,QAAQ,YAAY,MACrC,QAAQ,MAAM,aAAa,eAAe,KAAK,mBAAmB;CAIpE,MAAM,qCAAqB,IAAI,IAA8B;CAC7D,KAAK,MAAM,CAAC,OAAO,QAAQ,gBAEzB,KAAK,MAAM,CAAC,OAAO,gBACjB,IAAIP,oBAAAA,gBAAgB,EAAE,MAAM,OAAO;EACjC,mBAAmB,IAAI,IAAI,GAAG;EAC9B;CACF;CAKJ,MAAM,eAAe,kBACnB,SACA,MAAM,IAAI,GACV,kBACA,oBACA,WACF;CAEA,MAAM,oBAAoB,MAAM,YAAY,EAAE,qBAAqB;CACnE,IAAI,sBAAsB,KAAA,GACxB,MAAM,IAAI,MAAM,wCAAwC;CAI1D,MAAM,iBAAiB,YAAY,YAAY,EAAE,IAAI;CACrD,MAAM,oBAAoB,SAAS,YAAY,cAAc;CAC7D,IAAI;CACJ,IAAI,sBAAsB,KAAA,GACxB,iBAAiB,kBAAkB,YAAY;MAG/C,IAAI,MAAM,IAAI,EAAE,SAAS,MAAM,eAAe,SAAS,GACrD,iBAAiB,MAAM,YAAY;MAEnC,MAAM,IAAI,MAAM,eAAe,eAAe,SAAS,EAAE,uBAAuB;CAKpF,MAAM,mBAAmB,cAAc,iBAAiB;CAExD,IAAI,SAASa,WAAAA,eAAe,WAAW,cAAc,GAAG,GAAG,MAAM,YAAY,CAAC,EAAE,WAC9E,YACF;CAEA,IAAI,qBAAqB,KAAA,GACvB,SAAS,OAAO,qBAAqB,gBAAgB;CAGvD,IAAI,QAAQ,YAAY,MAAM;EAO5B,MAAM,aALmB,OAAO,WAC9B,KAAA,GACA,mBACA,KAAA,CAEgC,EAAE,SAAS;EAC7C,QAAQ,IAAI,UAAU;EAEtB,OAAO;GACL,eAAe,iBAAiB,SAAS;GACzC;EACF;CACF;CAQA,MAAM,wBAA+B,YAAY,aAAa,EAAE,KAAK,MAAM,EAAE,IAAI,CAAC;CAClF,MAAM,WAAW,MAAM,IAAI;CAC3B,MAAM,cAAc,SAAS,SAAS;CACtC,IAAI,CAAC,sBAAsB,MAAM,MAAM,EAAE,SAAS,MAAM,WAAW,GACjE,sBAAsB,KAAK,QAAQ;CAErC,sBAAsB,MAAM,GAAG,MAAMhB,6BAAAA,gBAAgB,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;CAI5E,MAAM,mBAAmB,mBACvB,cACA,SACA,cACA,qBAPuB,sBAAsB,WAAW,MAAM,EAAE,SAAS,MAAM,WAAW,IAAI,CAShG;CASA,MAAMiB,aAAAA,iBACJ,QACA,cATuB,OAAO,WAC9B,KAAA,GACA,mBACA,cAOe,GACf,oBACA,QAAQ,WAAW,KACrB;CAGA,MAAM,qBAAqB,SAAS,MAAM,OAAO;CACjD,IAAI,uBAAuB,KAAA,GAAW;EACpC,MAAM,gBAAgB,mBAAmB,cAAc;EACvD,cAAc,eAAe;EAC7B,mBAAmB,iBAAiB,aAAa;EAEjD,mBAAmB,mBAAmB,gBAAgB;EACtD,SAAS,KAAK,YAAY;CAC5B;CAEA,IAAIP,eAAAA,UAAU,KAAK,QAAQ,YAAY,MACrC,QAAQ,MAAM,8BAA8B,aAAa,SAAS,GAAG;CAGvE,OAAO,EACL,eAAe,iBAAiB,SAAS,EAC3C;AACF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const require_chunk = require("./chunk-
|
|
1
|
+
const require_chunk = require("./chunk-DakpK96I.cjs");
|
|
2
2
|
const require_registry_index = require("./registry/index.cjs");
|
|
3
|
-
const require_common = require("./common-
|
|
4
|
-
const require_busy = require("./busy-
|
|
5
|
-
const require_parallel = require("./parallel-
|
|
3
|
+
const require_common = require("./common-CnvAUC2b.cjs");
|
|
4
|
+
const require_busy = require("./busy-B_h0bNAJ.cjs");
|
|
5
|
+
const require_parallel = require("./parallel-szwYx-bi.cjs");
|
|
6
6
|
let _bcts_components = require("@bcts/components");
|
|
7
7
|
let _bcts_envelope = require("@bcts/envelope");
|
|
8
8
|
let _bcts_gstp = require("@bcts/gstp");
|
|
@@ -496,4 +496,4 @@ Object.defineProperty(exports, "validateAndExtractRound2Response", {
|
|
|
496
496
|
}
|
|
497
497
|
});
|
|
498
498
|
|
|
499
|
-
//# sourceMappingURL=round2-
|
|
499
|
+
//# sourceMappingURL=round2-Dk_w97nl.cjs.map
|