@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":"round1-DQ0fnc1H.cjs","names":["path","fs","ARID","parseAridUr","XID","Envelope","CborDate","SealedRequest","EnvelopeFunction","serializeSigningCommitments","JSONWrapper","signingStateDir","serializeSigningNonces","resolveRegistryPath","Registry","deserializeKeyPackage","SealedResponse","signingRound1","createRng","createStorageClient","putWithIndicator"],"sources":["../src/cmd/sign/participant/round1.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant round 1 command.\n *\n * Port of cmd/sign/participant/round1.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, type PrivateKeys, XID } from \"@bcts/components\";\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 { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { putWithIndicator } from \"../../busy.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { parseAridUr } from \"../../dkg/common.js\";\nimport { signingStateDir } from \"../common.js\";\nimport {\n signingRound1,\n deserializeKeyPackage,\n serializeSigningNonces,\n serializeSigningCommitments,\n createRng,\n type SerializedKeyPackage,\n type SerializedSigningNonces,\n type SerializedSigningCommitments,\n type Ed25519SigningNonces,\n type Ed25519SigningCommitments,\n} from \"../../../frost/index.js\";\n\n/**\n * Options for the sign round1 command.\n */\nexport interface SignRound1Options {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n preview?: boolean;\n rejectReason?: string;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round1 command.\n */\nexport interface SignRound1Result {\n accepted: boolean;\n listeningArid?: string;\n envelopeUr?: string;\n}\n\n/**\n * Persisted receive state from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/round1.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n coordinatorDoc: XIDDocument;\n responseArid: ARID;\n targetUr: string;\n participants: XID[];\n requestEnvelope: Envelope;\n}\n\n/**\n * Load receive state from persisted sign_receive.json.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/round1.rs lines 285-411.\n */\nfunction loadReceiveState(\n registryPath: string,\n sessionId: ARID,\n groupHint: ARID | undefined,\n registry: Registry,\n): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Collect candidate directories\n let groupDirs: [ARID, string][];\n if (groupHint !== undefined) {\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()) {\n const dirName = entry.name;\n // Check if it's a 64-character hex string (ARID hex)\n if (dirName.length === 64 && /^[0-9a-fA-F]+$/.test(dirName)) {\n const groupId = ARID.fromHex(dirName);\n groupDirs.push([groupId, path.join(groupStateDir, dirName)]);\n }\n }\n }\n }\n }\n\n // Search for sign_receive.json\n const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, filePath] = candidates[0];\n\n // Parse the JSON file\n interface SignReceiveJson {\n session: string;\n group: string;\n response_arid: string;\n target: string;\n coordinator: string;\n participants: string[];\n request_envelope: string;\n }\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as SignReceiveJson;\n\n // Validate session matches\n const sessionInState = parseAridUr(raw.session);\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const responseArid = parseAridUr(raw.response_arid);\n const targetUr = raw.target;\n const coordinatorUr = raw.coordinator;\n const coordinatorXid = XID.fromURString(coordinatorUr);\n\n // Resolve coordinator document from registry\n let coordinatorDoc: XIDDocument;\n const participantRecord = registry.participant(coordinatorXid);\n if (participantRecord !== null && participantRecord !== undefined) {\n coordinatorDoc = participantRecord.xidDocument();\n } else {\n const owner = registry.owner();\n if (owner?.xid().urString() === coordinatorXid.urString()) {\n coordinatorDoc = owner.xidDocument();\n } else {\n throw new Error(\n `Coordinator ${coordinatorXid.urString()} not found in registry and cannot resolve encryption key`,\n );\n }\n }\n\n // Parse request envelope\n const requestEnvelope = Envelope.fromURString(raw.request_envelope);\n\n // Parse participants\n const participants: XID[] = raw.participants.map((s: string) => XID.fromURString(s));\n\n return {\n groupId,\n coordinatorDoc,\n responseArid,\n targetUr,\n participants,\n requestEnvelope,\n };\n}\n\n/**\n * Validate the commit request from persisted state.\n *\n * Port of request validation in `CommandArgs::exec()` from cmd/sign/participant/round1.rs lines 100-138.\n */\nfunction validateCommitRequest(\n receiveState: ReceiveState,\n sessionId: ARID,\n ownerXid: XID,\n ownerPrivateKeys: PrivateKeys,\n): SealedRequest {\n const now = CborDate.now();\n\n // Decrypt and parse the request\n const sealedRequest = SealedRequest.tryFromEnvelope(\n receiveState.requestEnvelope,\n undefined,\n now.datetime(),\n ownerPrivateKeys,\n );\n\n // Validate function\n if (!sealedRequest.request().function().equals(EnvelopeFunction.fromString(\"signInvite\"))) {\n throw new Error(`Unexpected request function: ${String(sealedRequest.request().function())}`);\n }\n\n // Validate session ID\n if (sealedRequest.request().id().urString() !== sessionId.urString()) {\n throw new Error(\n `Session ID mismatch (state ${sessionId.urString()}, request ${sealedRequest.request().id().urString()})`,\n );\n }\n\n // Validate group ID\n const requestGroup = sealedRequest.extractObjectForParameter<ARID>(\"group\");\n if (requestGroup.urString() !== receiveState.groupId.urString()) {\n throw new Error(\n `Group ID mismatch (state ${receiveState.groupId.urString()}, request ${requestGroup.urString()})`,\n );\n }\n\n // Validate participant is included\n const participantUrStrings = receiveState.participants.map((p) => p.urString());\n if (!participantUrStrings.includes(ownerXid.urString())) {\n throw new Error(\"Persisted signInvite request does not include this participant\");\n }\n\n return sealedRequest;\n}\n\n/**\n * Build the response body envelope.\n *\n * Port of response body building from cmd/sign/participant/round1.rs lines 191-195.\n */\nfunction buildResponseBody(\n sessionId: ARID,\n commitments: Ed25519SigningCommitments,\n responseArid: ARID,\n): Envelope {\n // Serialize commitments to JSON and wrap as CBOR JSON\n const serializedCommitments = serializeSigningCommitments(commitments);\n const jsonStr = JSON.stringify(serializedCommitments);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const commitmentsJson = JSONWrapper.fromData(jsonBytes);\n\n // Build response body: unit subject with type and assertions\n return Envelope.unit()\n .addType(\"signRound1Response\")\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"commitments\", commitmentsJson.taggedCborData())\n .addAssertion(\"response_arid\", responseArid);\n}\n\n/**\n * Persist commit state (nonces and commitments) to disk.\n *\n * Port of `persist_commit_state()` from cmd/sign/participant/round1.rs lines 413-461.\n */\nfunction persistCommitState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n receiveState: ReceiveState,\n signingNonces: Ed25519SigningNonces,\n signingCommitments: Ed25519SigningCommitments,\n targetEnvelope: Envelope,\n nextShareArid: ARID,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Serialize nonces and commitments\n const serializedNonces = serializeSigningNonces(signingNonces);\n const serializedCommitments = serializeSigningCommitments(signingCommitments);\n\n // Build commit state JSON\n const commitState: {\n session: string;\n response_arid: string;\n next_share_arid: string;\n target: string;\n signing_nonces: SerializedSigningNonces;\n signing_commitments: SerializedSigningCommitments;\n } = {\n session: sessionId.urString(),\n response_arid: receiveState.responseArid.urString(),\n next_share_arid: nextShareArid.urString(),\n target: targetEnvelope.urString(),\n signing_nonces: serializedNonces,\n signing_commitments: serializedCommitments,\n };\n\n fs.writeFileSync(path.join(dir, \"commit.json\"), JSON.stringify(commitState, null, 2));\n}\n\n/**\n * Execute the sign participant round 1 command.\n *\n * Responds to the sign invite with signing commitments.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/participant/round1.rs lines 58-273.\n */\nexport async function round1(\n _client: StorageClient | undefined,\n options: SignRound1Options,\n cwd: string,\n): Promise<SignRound1Result> {\n // Validate options\n if (options.storageSelection === undefined && options.preview !== true) {\n throw new Error(\"Hubert storage is required for sign commit\");\n }\n if (options.storageSelection !== undefined && options.preview === true) {\n throw new Error(\"--preview cannot be used with Hubert storage options\");\n }\n\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 !== undefined ? parseAridUr(options.groupId) : undefined;\n\n // Load receive state\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint, registry);\n const groupId = receiveState.groupId;\n\n // Get group record\n const groupRecord = registry.group(groupId);\n if (groupRecord === null || groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Get owner private keys\n const ownerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (ownerKeys === undefined) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n // Validate the commit request\n const sealedRequest = validateCommitRequest(receiveState, sessionId, owner.xid(), ownerKeys);\n\n // Load key package\n const contributions = groupRecord.contributions();\n if (contributions === null || contributions === undefined) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n const keyPackagePath = contributions.keyPackage;\n if (keyPackagePath === undefined) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n\n interface KeyPackageFile {\n group: string;\n key_package: SerializedKeyPackage;\n }\n\n const keyPackageFile = JSON.parse(fs.readFileSync(keyPackagePath, \"utf-8\")) as KeyPackageFile;\n const keyPackage = deserializeKeyPackage(keyPackageFile.key_package);\n\n // Parse target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\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 let sealedResponse: SealedResponse;\n let nextShareArid: ARID | undefined;\n\n if (options.rejectReason !== undefined) {\n // Build rejection response\n const errorBody = Envelope.new(\"signCommitReject\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"reason\", options.rejectReason);\n\n sealedResponse = SealedResponse.newFailure(sealedRequest.request().id(), owner.xidDocument())\n .withError(errorBody)\n .withPeerContinuation(sealedRequest.peerContinuation());\n } else {\n // Run signing round 1 - generate nonces and commitments\n const rng = createRng();\n const [signingNonces, signingCommitments] = signingRound1(keyPackage, rng);\n\n const nextShare = ARID.new();\n nextShareArid = nextShare;\n\n // Build response body\n const responseBody = buildResponseBody(sessionId, signingCommitments, nextShare);\n\n // Persist commit state (unless preview mode)\n if (options.preview !== true) {\n persistCommitState(\n registryPath,\n groupId,\n sessionId,\n receiveState,\n signingNonces,\n signingCommitments,\n targetEnvelope,\n nextShare,\n );\n\n // Update listening ARID for next request\n const groupRecordMut = registry.group(groupId);\n if (groupRecordMut !== null && groupRecordMut !== undefined) {\n groupRecordMut.setListeningAtArid(nextShare);\n registry.save(registryPath);\n }\n }\n\n sealedResponse = SealedResponse.newSuccess(sealedRequest.request().id(), owner.xidDocument())\n .withResult(responseBody)\n .withPeerContinuation(sealedRequest.peerContinuation());\n }\n\n // Handle preview mode\n if (options.preview === true) {\n const unsealed = sealedResponse.toEnvelope(undefined, signerPrivateKeys, undefined);\n const envelopeUr = unsealed.urString();\n console.log(envelopeUr);\n return {\n accepted: options.rejectReason === undefined,\n envelopeUr,\n };\n }\n\n // Build encrypted response envelope\n const validUntil = new Date(Date.now() + 60 * 60 * 1000); // 1 hour from now\n const responseEnvelope = sealedResponse.toEnvelope(\n validUntil,\n signerPrivateKeys,\n receiveState.coordinatorDoc,\n );\n\n // Post response to Hubert storage\n if (options.storageSelection === undefined) {\n throw new Error(\"Storage selection is required to post response\");\n }\n const client = await createStorageClient(options.storageSelection);\n\n if (options.verbose === true) {\n console.error(`Posting signInvite response to ${receiveState.responseArid.urString()}`);\n }\n\n await putWithIndicator(\n client,\n receiveState.responseArid,\n responseEnvelope,\n \"Commitments\",\n options.verbose ?? false,\n );\n\n // On reject, clear listening ARID\n if (options.rejectReason !== undefined) {\n const groupRecordMut = registry.group(groupId);\n if (groupRecordMut !== null && groupRecordMut !== undefined) {\n groupRecordMut.clearListeningAtArid();\n registry.save(registryPath);\n }\n }\n\n const result: SignRound1Result = {\n accepted: options.rejectReason === undefined,\n };\n if (nextShareArid !== undefined) {\n result.listeningArid = nextShareArid.urString();\n }\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"round1-DriPu15x.cjs","names":["path","fs","ARID","parseAridUr","XID","Envelope","CborDate","SealedRequest","EnvelopeFunction","serializeSigningCommitments","JSONWrapper","signingStateDir","serializeSigningNonces","resolveRegistryPath","Registry","deserializeKeyPackage","SealedResponse","signingRound1","createRng","createStorageClient","putWithIndicator"],"sources":["../src/cmd/sign/participant/round1.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant round 1 command.\n *\n * Port of cmd/sign/participant/round1.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, type PrivateKeys, XID } from \"@bcts/components\";\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 { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { putWithIndicator } from \"../../busy.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { parseAridUr } from \"../../dkg/common.js\";\nimport { signingStateDir } from \"../common.js\";\nimport {\n signingRound1,\n deserializeKeyPackage,\n serializeSigningNonces,\n serializeSigningCommitments,\n createRng,\n type SerializedKeyPackage,\n type SerializedSigningNonces,\n type SerializedSigningCommitments,\n type Ed25519SigningNonces,\n type Ed25519SigningCommitments,\n} from \"../../../frost/index.js\";\n\n/**\n * Options for the sign round1 command.\n */\nexport interface SignRound1Options {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n preview?: boolean;\n rejectReason?: string;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round1 command.\n */\nexport interface SignRound1Result {\n accepted: boolean;\n listeningArid?: string;\n envelopeUr?: string;\n}\n\n/**\n * Persisted receive state from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/round1.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n coordinatorDoc: XIDDocument;\n responseArid: ARID;\n targetUr: string;\n participants: XID[];\n requestEnvelope: Envelope;\n}\n\n/**\n * Load receive state from persisted sign_receive.json.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/round1.rs lines 285-411.\n */\nfunction loadReceiveState(\n registryPath: string,\n sessionId: ARID,\n groupHint: ARID | undefined,\n registry: Registry,\n): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Collect candidate directories\n let groupDirs: [ARID, string][];\n if (groupHint !== undefined) {\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()) {\n const dirName = entry.name;\n // Check if it's a 64-character hex string (ARID hex)\n if (dirName.length === 64 && /^[0-9a-fA-F]+$/.test(dirName)) {\n const groupId = ARID.fromHex(dirName);\n groupDirs.push([groupId, path.join(groupStateDir, dirName)]);\n }\n }\n }\n }\n }\n\n // Search for sign_receive.json\n const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, filePath] = candidates[0];\n\n // Parse the JSON file\n interface SignReceiveJson {\n session: string;\n group: string;\n response_arid: string;\n target: string;\n coordinator: string;\n participants: string[];\n request_envelope: string;\n }\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as SignReceiveJson;\n\n // Validate session matches\n const sessionInState = parseAridUr(raw.session);\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const responseArid = parseAridUr(raw.response_arid);\n const targetUr = raw.target;\n const coordinatorUr = raw.coordinator;\n const coordinatorXid = XID.fromURString(coordinatorUr);\n\n // Resolve coordinator document from registry\n let coordinatorDoc: XIDDocument;\n const participantRecord = registry.participant(coordinatorXid);\n if (participantRecord !== null && participantRecord !== undefined) {\n coordinatorDoc = participantRecord.xidDocument();\n } else {\n const owner = registry.owner();\n if (owner?.xid().urString() === coordinatorXid.urString()) {\n coordinatorDoc = owner.xidDocument();\n } else {\n throw new Error(\n `Coordinator ${coordinatorXid.urString()} not found in registry and cannot resolve encryption key`,\n );\n }\n }\n\n // Parse request envelope\n const requestEnvelope = Envelope.fromURString(raw.request_envelope);\n\n // Parse participants\n const participants: XID[] = raw.participants.map((s: string) => XID.fromURString(s));\n\n return {\n groupId,\n coordinatorDoc,\n responseArid,\n targetUr,\n participants,\n requestEnvelope,\n };\n}\n\n/**\n * Validate the commit request from persisted state.\n *\n * Port of request validation in `CommandArgs::exec()` from cmd/sign/participant/round1.rs lines 100-138.\n */\nfunction validateCommitRequest(\n receiveState: ReceiveState,\n sessionId: ARID,\n ownerXid: XID,\n ownerPrivateKeys: PrivateKeys,\n): SealedRequest {\n const now = CborDate.now();\n\n // Decrypt and parse the request\n const sealedRequest = SealedRequest.tryFromEnvelope(\n receiveState.requestEnvelope,\n undefined,\n now.datetime(),\n ownerPrivateKeys,\n );\n\n // Validate function\n if (!sealedRequest.request().function().equals(EnvelopeFunction.fromString(\"signInvite\"))) {\n throw new Error(`Unexpected request function: ${String(sealedRequest.request().function())}`);\n }\n\n // Validate session ID\n if (sealedRequest.request().id().urString() !== sessionId.urString()) {\n throw new Error(\n `Session ID mismatch (state ${sessionId.urString()}, request ${sealedRequest.request().id().urString()})`,\n );\n }\n\n // Validate group ID\n const requestGroup = sealedRequest.extractObjectForParameter<ARID>(\"group\");\n if (requestGroup.urString() !== receiveState.groupId.urString()) {\n throw new Error(\n `Group ID mismatch (state ${receiveState.groupId.urString()}, request ${requestGroup.urString()})`,\n );\n }\n\n // Validate participant is included\n const participantUrStrings = receiveState.participants.map((p) => p.urString());\n if (!participantUrStrings.includes(ownerXid.urString())) {\n throw new Error(\"Persisted signInvite request does not include this participant\");\n }\n\n return sealedRequest;\n}\n\n/**\n * Build the response body envelope.\n *\n * Port of response body building from cmd/sign/participant/round1.rs lines 191-195.\n */\nfunction buildResponseBody(\n sessionId: ARID,\n commitments: Ed25519SigningCommitments,\n responseArid: ARID,\n): Envelope {\n // Serialize commitments to JSON and wrap as CBOR JSON\n const serializedCommitments = serializeSigningCommitments(commitments);\n const jsonStr = JSON.stringify(serializedCommitments);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const commitmentsJson = JSONWrapper.fromData(jsonBytes);\n\n // Build response body: unit subject with type and assertions\n return Envelope.unit()\n .addType(\"signRound1Response\")\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"commitments\", commitmentsJson.taggedCborData())\n .addAssertion(\"response_arid\", responseArid);\n}\n\n/**\n * Persist commit state (nonces and commitments) to disk.\n *\n * Port of `persist_commit_state()` from cmd/sign/participant/round1.rs lines 413-461.\n */\nfunction persistCommitState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n receiveState: ReceiveState,\n signingNonces: Ed25519SigningNonces,\n signingCommitments: Ed25519SigningCommitments,\n targetEnvelope: Envelope,\n nextShareArid: ARID,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Serialize nonces and commitments\n const serializedNonces = serializeSigningNonces(signingNonces);\n const serializedCommitments = serializeSigningCommitments(signingCommitments);\n\n // Build commit state JSON\n const commitState: {\n session: string;\n response_arid: string;\n next_share_arid: string;\n target: string;\n signing_nonces: SerializedSigningNonces;\n signing_commitments: SerializedSigningCommitments;\n } = {\n session: sessionId.urString(),\n response_arid: receiveState.responseArid.urString(),\n next_share_arid: nextShareArid.urString(),\n target: targetEnvelope.urString(),\n signing_nonces: serializedNonces,\n signing_commitments: serializedCommitments,\n };\n\n fs.writeFileSync(path.join(dir, \"commit.json\"), JSON.stringify(commitState, null, 2));\n}\n\n/**\n * Execute the sign participant round 1 command.\n *\n * Responds to the sign invite with signing commitments.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/participant/round1.rs lines 58-273.\n */\nexport async function round1(\n _client: StorageClient | undefined,\n options: SignRound1Options,\n cwd: string,\n): Promise<SignRound1Result> {\n // Validate options\n if (options.storageSelection === undefined && options.preview !== true) {\n throw new Error(\"Hubert storage is required for sign commit\");\n }\n if (options.storageSelection !== undefined && options.preview === true) {\n throw new Error(\"--preview cannot be used with Hubert storage options\");\n }\n\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 !== undefined ? parseAridUr(options.groupId) : undefined;\n\n // Load receive state\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint, registry);\n const groupId = receiveState.groupId;\n\n // Get group record\n const groupRecord = registry.group(groupId);\n if (groupRecord === null || groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Get owner private keys\n const ownerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (ownerKeys === undefined) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n // Validate the commit request\n const sealedRequest = validateCommitRequest(receiveState, sessionId, owner.xid(), ownerKeys);\n\n // Load key package\n const contributions = groupRecord.contributions();\n if (contributions === null || contributions === undefined) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n const keyPackagePath = contributions.keyPackage;\n if (keyPackagePath === undefined) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n\n interface KeyPackageFile {\n group: string;\n key_package: SerializedKeyPackage;\n }\n\n const keyPackageFile = JSON.parse(fs.readFileSync(keyPackagePath, \"utf-8\")) as KeyPackageFile;\n const keyPackage = deserializeKeyPackage(keyPackageFile.key_package);\n\n // Parse target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\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 let sealedResponse: SealedResponse;\n let nextShareArid: ARID | undefined;\n\n if (options.rejectReason !== undefined) {\n // Build rejection response\n const errorBody = Envelope.new(\"signCommitReject\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"reason\", options.rejectReason);\n\n sealedResponse = SealedResponse.newFailure(sealedRequest.request().id(), owner.xidDocument())\n .withError(errorBody)\n .withPeerContinuation(sealedRequest.peerContinuation());\n } else {\n // Run signing round 1 - generate nonces and commitments\n const rng = createRng();\n const [signingNonces, signingCommitments] = signingRound1(keyPackage, rng);\n\n const nextShare = ARID.new();\n nextShareArid = nextShare;\n\n // Build response body\n const responseBody = buildResponseBody(sessionId, signingCommitments, nextShare);\n\n // Persist commit state (unless preview mode)\n if (options.preview !== true) {\n persistCommitState(\n registryPath,\n groupId,\n sessionId,\n receiveState,\n signingNonces,\n signingCommitments,\n targetEnvelope,\n nextShare,\n );\n\n // Update listening ARID for next request\n const groupRecordMut = registry.group(groupId);\n if (groupRecordMut !== null && groupRecordMut !== undefined) {\n groupRecordMut.setListeningAtArid(nextShare);\n registry.save(registryPath);\n }\n }\n\n sealedResponse = SealedResponse.newSuccess(sealedRequest.request().id(), owner.xidDocument())\n .withResult(responseBody)\n .withPeerContinuation(sealedRequest.peerContinuation());\n }\n\n // Handle preview mode\n if (options.preview === true) {\n const unsealed = sealedResponse.toEnvelope(undefined, signerPrivateKeys, undefined);\n const envelopeUr = unsealed.urString();\n console.log(envelopeUr);\n return {\n accepted: options.rejectReason === undefined,\n envelopeUr,\n };\n }\n\n // Build encrypted response envelope\n const validUntil = new Date(Date.now() + 60 * 60 * 1000); // 1 hour from now\n const responseEnvelope = sealedResponse.toEnvelope(\n validUntil,\n signerPrivateKeys,\n receiveState.coordinatorDoc,\n );\n\n // Post response to Hubert storage\n if (options.storageSelection === undefined) {\n throw new Error(\"Storage selection is required to post response\");\n }\n const client = await createStorageClient(options.storageSelection);\n\n if (options.verbose === true) {\n console.error(`Posting signInvite response to ${receiveState.responseArid.urString()}`);\n }\n\n await putWithIndicator(\n client,\n receiveState.responseArid,\n responseEnvelope,\n \"Commitments\",\n options.verbose ?? false,\n );\n\n // On reject, clear listening ARID\n if (options.rejectReason !== undefined) {\n const groupRecordMut = registry.group(groupId);\n if (groupRecordMut !== null && groupRecordMut !== undefined) {\n groupRecordMut.clearListeningAtArid();\n registry.save(registryPath);\n }\n }\n\n const result: SignRound1Result = {\n accepted: options.rejectReason === undefined,\n };\n if (nextShareArid !== undefined) {\n result.listeningArid = nextShareArid.urString();\n }\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as __exportAll } from "./chunk-
|
|
2
|
-
import { n as compareXidBytes } from "./proposed-participant-
|
|
1
|
+
import { t as __exportAll } from "./chunk-z9aeyW2b.mjs";
|
|
2
|
+
import { n as compareXidBytes } from "./proposed-participant-Detb823_.mjs";
|
|
3
3
|
import { ContributionPaths, GroupRecord, Registry, resolveRegistryPath } from "./registry/index.mjs";
|
|
4
|
-
import { c as parseAridUr, i as buildGroupParticipants, l as parseEnvelopeUr, p as resolveSender, s as groupParticipantFromRegistry, t as groupStateDir } from "./common-
|
|
5
|
-
import { n as putWithIndicator, t as getWithIndicator } from "./busy-
|
|
6
|
-
import {
|
|
7
|
-
import { t as decodeInviteDetails } from "./receive-
|
|
4
|
+
import { c as parseAridUr, i as buildGroupParticipants, l as parseEnvelopeUr, p as resolveSender, s as groupParticipantFromRegistry, t as groupStateDir } from "./common-Cf1UvJaP.mjs";
|
|
5
|
+
import { n as putWithIndicator, t as getWithIndicator } from "./busy-BlU8_pS2.mjs";
|
|
6
|
+
import { i as createStorageClient } from "./registry-DGjs4qDK.mjs";
|
|
7
|
+
import { t as decodeInviteDetails } from "./receive-dkSCSGpl.mjs";
|
|
8
8
|
import { bytesToHex, createRng, dkgPart1, identifierFromU16 } from "./frost/index.mjs";
|
|
9
9
|
import { ARID, JSON } from "@bcts/components";
|
|
10
10
|
import { CborDate } from "@bcts/dcbor";
|
|
@@ -192,4 +192,4 @@ async function round1(_client, options, cwd) {
|
|
|
192
192
|
//#endregion
|
|
193
193
|
export { round1_exports as n, round1 as t };
|
|
194
194
|
|
|
195
|
-
//# sourceMappingURL=round1-
|
|
195
|
+
//# sourceMappingURL=round1-Y2kcVwnR.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round1-CMLKN2RR.mjs","names":["JSONWrapper"],"sources":["../src/cmd/dkg/participant/round1.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG participant round 1 command.\n *\n * Port of cmd/dkg/participant/round1.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, type XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { SealedResponse } from \"@bcts/gstp\";\nimport type { XIDDocument } from \"@bcts/xid\";\n\nimport {\n ContributionPaths,\n GroupRecord,\n Registry,\n resolveRegistryPath,\n} from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { groupStateDir } from \"../../common.js\";\nimport {\n buildGroupParticipants,\n groupParticipantFromRegistry,\n parseAridUr,\n parseEnvelopeUr,\n resolveSender,\n} from \"../common.js\";\nimport {\n dkgPart1,\n identifierFromU16,\n createRng,\n bytesToHex,\n type DkgRound1Package,\n type DkgRound1SecretPackage,\n} from \"../../../frost/index.js\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\nimport { decodeInviteDetails } from \"./receive.js\";\nimport { CborDate } from \"@bcts/dcbor\";\n\n/**\n * Options for the DKG round1 command.\n */\nexport interface DkgRound1Options {\n registryPath?: string;\n timeoutSeconds?: number;\n responseArid?: string;\n preview?: boolean;\n rejectReason?: string;\n sender?: string;\n invite: string;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the DKG round1 command.\n */\nexport interface DkgRound1Result {\n accepted: boolean;\n listeningArid?: string;\n envelopeUr?: string;\n}\n\n/**\n * Resolve an invite envelope from either storage (ARID) or direct UR.\n *\n * Port of `resolve_invite_envelope()` from cmd/dkg/participant/round1.rs lines 256-288.\n */\nasync function resolveInviteEnvelope(\n selection: StorageSelection | undefined,\n invite: string,\n timeout?: number,\n): Promise<Envelope> {\n if (selection !== undefined) {\n // Try to parse as ARID\n try {\n const arid = parseAridUr(invite);\n const client = await createStorageClient(selection);\n const envelope = await getWithIndicator(client, arid, \"Invite\", timeout, false);\n if (envelope === null || envelope === undefined) {\n throw new Error(\"Invite not found in Hubert storage\");\n }\n return envelope;\n } catch (e) {\n // Not an ARID, fall through to envelope parsing\n if (e instanceof Error && e.message.includes(\"Invite not found in Hubert storage\")) {\n throw e;\n }\n }\n\n if (timeout !== undefined) {\n throw new Error(\"--timeout is only valid when retrieving invites from Hubert\");\n }\n\n return parseEnvelopeUr(invite);\n }\n\n // No storage selection\n try {\n parseAridUr(invite);\n throw new Error(\"Hubert storage parameters are required to retrieve invites by ARID\");\n } catch (e) {\n // Not an ARID, parse as envelope\n if (e instanceof Error && e.message.includes(\"Hubert storage parameters are required\")) {\n throw e;\n }\n }\n\n return parseEnvelopeUr(invite);\n}\n\n/**\n * Build the response body envelope.\n *\n * Port of `build_response_body()` from cmd/dkg/participant/round1.rs lines 290-308.\n */\nfunction buildResponseBody(\n groupId: ARID,\n participant: XID,\n responseArid: ARID,\n round1Package: DkgRound1Package | undefined,\n): Envelope {\n let envelope = Envelope.unit()\n .addType(\"dkgRound1Response\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"participant\", participant)\n .addAssertion(\"response_arid\", responseArid);\n\n if (round1Package !== undefined) {\n // Serialize the package to JSON and wrap as CBOR JSON\n const packageJson = serde.round1PackageToJson(round1Package);\n const jsonStr = globalThis.JSON.stringify(packageJson);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const jsonWrapper = JSONWrapper.fromData(jsonBytes);\n // Pass the JSONWrapper directly - it implements CborTaggedEncodable\n envelope = envelope.addAssertion(\"round1_package\", jsonWrapper);\n }\n\n return envelope;\n}\n\n/**\n * Serialize round 1 secret package to JSON-compatible format.\n *\n * The @frosts/ed25519 serde module doesn't provide a serializer for SecretPackage,\n * so we manually serialize it here.\n */\nfunction serializeRound1SecretPackage(secret: DkgRound1SecretPackage): Record<string, unknown> {\n // Mirrors the on-disk shape produced by Rust\n // `serde_json::to_vec_pretty(&frost::keys::dkg::round1::SecretPackage)`\n // (see `frost-rust/frost-core/src/keys/dkg.rs:120-139`):\n //\n // {\n // \"identifier\": \"<lowercase hex scalar>\",\n // \"coefficients\": [\"<hex>\", \"<hex>\", ...],\n // \"commitment\": [\"<hex>\", \"<hex>\", ...],\n // \"min_signers\": <u16>,\n // \"max_signers\": <u16>\n // }\n //\n // `frost::keys::dkg::round1::SecretPackage` is `#[serde(deny_unknown_fields)]`\n // and has no `header` field (the secret package is private to the\n // participant). The earlier port emitted a top-level `header` which\n // would fail `deny_unknown_fields` validation if Rust ever loaded\n // the file.\n //\n // `Identifier`/`SerializableScalar` serialize via\n // `serdect::array::serialize_hex_lower_or_bin` → lowercase hex for\n // JSON, which `bytesToHex` produces.\n const coefficients = secret.coefficients();\n const serializedCoefficients = coefficients.map((c: unknown) =>\n bytesToHex(\n Ed25519Sha512.serializeScalar(c as Parameters<typeof Ed25519Sha512.serializeScalar>[0]),\n ),\n );\n\n const commitment = secret.commitment;\n const commitmentCoefficients = commitment.serialize().map((c: Uint8Array) => bytesToHex(c));\n\n return {\n identifier: bytesToHex(secret.identifier.serialize()),\n coefficients: serializedCoefficients,\n commitment: commitmentCoefficients,\n min_signers: secret.minSigners,\n max_signers: secret.maxSigners,\n };\n}\n\n/**\n * Persist round 1 state to disk.\n *\n * Port of `persist_round1_state()` from cmd/dkg/participant/round1.rs lines 310-337.\n */\nfunction persistRound1State(\n registryPath: string,\n groupId: ARID,\n round1Secret: DkgRound1SecretPackage,\n round1Package: DkgRound1Package,\n): ContributionPaths {\n const dir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n const secretPath = path.join(dir, \"round1_secret.json\");\n const packagePath = path.join(dir, \"round1_package.json\");\n\n // Serialize the secret package manually since serde doesn't provide it\n const secretJson = serializeRound1SecretPackage(round1Secret);\n // Serialize the public package using the standard serde function\n const packageJson = serde.round1PackageToJson(round1Package);\n\n fs.writeFileSync(secretPath, globalThis.JSON.stringify(secretJson, null, 2));\n fs.writeFileSync(packagePath, globalThis.JSON.stringify(packageJson, null, 2));\n\n return new ContributionPaths({\n round1Secret: secretPath,\n round1Package: packagePath,\n round2Secret: undefined,\n keyPackage: undefined,\n });\n}\n\n/**\n * Execute the DKG participant round 1 command.\n *\n * Responds to the DKG invite with commitment packages.\n *\n * Port of `CommandArgs::exec()` from cmd/dkg/participant/round1.rs lines 66-254.\n */\nexport async function round1(\n _client: StorageClient | undefined,\n options: DkgRound1Options,\n cwd: string,\n): Promise<DkgRound1Result> {\n // Validate options\n if (options.storageSelection === undefined && options.timeoutSeconds !== undefined) {\n throw new Error(\"--timeout requires Hubert storage parameters\");\n }\n if (options.storageSelection !== undefined && options.preview === true) {\n throw new Error(\"--preview cannot be used with Hubert storage options\");\n }\n\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 with private keys is required\");\n }\n\n // Resolve expected sender if provided. Uses the shared helper from\n // `cmd/dkg/common.ts` (mirrors Rust `resolve_sender`); the\n // duplicated inline implementation that this previously called has\n // been removed.\n let expectedSender: XIDDocument | undefined;\n if (options.sender !== undefined) {\n expectedSender = resolveSender(registry, options.sender);\n }\n\n const nextResponseArid =\n options.responseArid !== undefined ? parseAridUr(options.responseArid) : ARID.new();\n\n // Resolve the invite envelope\n const inviteEnvelope = await resolveInviteEnvelope(\n options.storageSelection,\n options.invite,\n options.timeoutSeconds,\n );\n\n // Decode the invite details\n const now = CborDate.now().datetime();\n const details = decodeInviteDetails(\n inviteEnvelope,\n now,\n registry,\n owner.xidDocument(),\n expectedSender,\n );\n\n // Sort participants by XID byte order (mirrors Rust `XID::cmp` —\n // raw 32-byte lex compare). The earlier port used\n // `xid.urString().localeCompare(...)`, which differs from byte\n // order when bytes ≥ 0x80 are present and is locale-aware,\n // producing different FROST identifier assignments and therefore\n // different secret shares than Rust.\n const sortedParticipants = [...details.participants].sort((a, b) =>\n compareXidBytes(a.xid().toData(), b.xid().toData()),\n );\n\n const ownerIndex = sortedParticipants.findIndex(\n (doc) => doc.xid().urString() === owner.xid().urString(),\n );\n if (ownerIndex === -1) {\n throw new Error(\"Invite does not include the registry owner\");\n }\n\n const identifierIndex = ownerIndex + 1; // FROST uses 1-indexed identifiers\n if (identifierIndex > 65535) {\n throw new Error(\"Too many participants for identifiers\");\n }\n const identifier = identifierFromU16(identifierIndex);\n\n const total = sortedParticipants.length;\n if (total > 65535) {\n throw new Error(\"Too many participants for FROST identifiers\");\n }\n\n const minSigners = details.invitation.minSigners();\n if (minSigners > 65535) {\n throw new Error(\"min_signers does not fit into identifier space\");\n }\n\n // Build group participants for the registry\n const groupParticipants = buildGroupParticipants(registry, owner, sortedParticipants);\n const coordinator = groupParticipantFromRegistry(registry, owner, details.invitation.sender());\n\n // Check if we're posting to storage\n const isPosting = options.storageSelection !== undefined;\n\n // Build the response body\n let responseBody: Envelope;\n let contributions: ContributionPaths | undefined;\n\n if (options.rejectReason === undefined && isPosting) {\n // Actually posting - generate and persist round1 state\n const [round1Secret, round1Package] = dkgPart1(identifier, total, minSigners, createRng());\n\n contributions = persistRound1State(\n registryPath,\n details.invitation.groupId(),\n round1Secret,\n round1Package,\n );\n\n responseBody = buildResponseBody(\n details.invitation.groupId(),\n owner.xid(),\n nextResponseArid,\n round1Package,\n );\n\n // Create and save group record\n const groupRecord = new GroupRecord(\n details.invitation.charter(),\n details.invitation.minSigners(),\n coordinator,\n groupParticipants,\n );\n groupRecord.setContributions(contributions);\n groupRecord.setListeningAtArid(nextResponseArid);\n\n registry.recordGroup(details.invitation.groupId(), groupRecord);\n registry.save(registryPath);\n } else if (options.rejectReason === undefined) {\n // Preview mode - generate dummy round1 for envelope structure only\n const [, round1Package] = dkgPart1(identifier, total, minSigners, createRng());\n\n responseBody = buildResponseBody(\n details.invitation.groupId(),\n owner.xid(),\n nextResponseArid,\n round1Package,\n );\n } else {\n // Rejecting - no round1 needed\n responseBody = buildResponseBody(\n details.invitation.groupId(),\n owner.xid(),\n nextResponseArid,\n undefined,\n );\n }\n\n // Build the sealed response\n const signerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no signing keys\");\n }\n\n let sealed: SealedResponse;\n if (options.rejectReason !== undefined) {\n // Build rejection error body\n const errorBody = Envelope.new(\"dkgInviteReject\")\n .addAssertion(\"group\", details.invitation.groupId())\n .addAssertion(\"response_arid\", nextResponseArid)\n .addAssertion(\"reason\", options.rejectReason);\n\n sealed = SealedResponse.newFailure(details.invitation.requestId(), owner.xidDocument())\n .withError(errorBody)\n .withState(nextResponseArid);\n } else {\n sealed = SealedResponse.newSuccess(details.invitation.requestId(), owner.xidDocument())\n .withResult(responseBody)\n .withState(nextResponseArid);\n }\n\n // Add peer continuation if present\n const peerContinuation = details.invitation.peerContinuation();\n if (peerContinuation !== undefined) {\n sealed = sealed.withPeerContinuation(peerContinuation);\n }\n\n // Handle output based on storage selection\n if (options.storageSelection !== undefined) {\n const responseEnvelope = sealed.toEnvelope(\n details.invitation.validUntil(),\n signerPrivateKeys,\n details.invitation.sender(),\n );\n\n const responseTarget = details.invitation.responseArid();\n const client = await createStorageClient(options.storageSelection);\n\n await putWithIndicator(\n client,\n responseTarget,\n responseEnvelope,\n \"Round 1 Response\",\n options.verbose ?? false,\n );\n\n if (options.verbose === true) {\n console.log(`Sent round 1 response`);\n console.log(`Listening at: ${nextResponseArid.urString()}`);\n }\n\n return {\n accepted: options.rejectReason === undefined,\n listeningArid: nextResponseArid.urString(),\n };\n } else if (options.preview === true) {\n // Show the GSTP response structure without encryption\n const unsealedEnvelope = sealed.toEnvelope(undefined, signerPrivateKeys, undefined);\n const envelopeUr = unsealedEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n accepted: options.rejectReason === undefined,\n envelopeUr,\n };\n } else {\n // Print the sealed envelope\n const responseEnvelope = sealed.toEnvelope(\n details.invitation.validUntil(),\n signerPrivateKeys,\n details.invitation.sender(),\n );\n const envelopeUr = responseEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n accepted: options.rejectReason === undefined,\n envelopeUr,\n };\n }\n}\n\n// `resolveSenderXidDocument` removed — it was an inline duplicate of\n// Rust `resolve_sender(registry, input)`. The shared helper now lives\n// in `cmd/dkg/common.ts` and is imported above.\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"round1-Y2kcVwnR.mjs","names":["JSONWrapper"],"sources":["../src/cmd/dkg/participant/round1.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG participant round 1 command.\n *\n * Port of cmd/dkg/participant/round1.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, type XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { SealedResponse } from \"@bcts/gstp\";\nimport type { XIDDocument } from \"@bcts/xid\";\n\nimport {\n ContributionPaths,\n GroupRecord,\n Registry,\n resolveRegistryPath,\n} from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { groupStateDir } from \"../../common.js\";\nimport {\n buildGroupParticipants,\n groupParticipantFromRegistry,\n parseAridUr,\n parseEnvelopeUr,\n resolveSender,\n} from \"../common.js\";\nimport {\n dkgPart1,\n identifierFromU16,\n createRng,\n bytesToHex,\n type DkgRound1Package,\n type DkgRound1SecretPackage,\n} from \"../../../frost/index.js\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\nimport { decodeInviteDetails } from \"./receive.js\";\nimport { CborDate } from \"@bcts/dcbor\";\n\n/**\n * Options for the DKG round1 command.\n */\nexport interface DkgRound1Options {\n registryPath?: string;\n timeoutSeconds?: number;\n responseArid?: string;\n preview?: boolean;\n rejectReason?: string;\n sender?: string;\n invite: string;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the DKG round1 command.\n */\nexport interface DkgRound1Result {\n accepted: boolean;\n listeningArid?: string;\n envelopeUr?: string;\n}\n\n/**\n * Resolve an invite envelope from either storage (ARID) or direct UR.\n *\n * Port of `resolve_invite_envelope()` from cmd/dkg/participant/round1.rs lines 256-288.\n */\nasync function resolveInviteEnvelope(\n selection: StorageSelection | undefined,\n invite: string,\n timeout?: number,\n): Promise<Envelope> {\n if (selection !== undefined) {\n // Try to parse as ARID\n try {\n const arid = parseAridUr(invite);\n const client = await createStorageClient(selection);\n const envelope = await getWithIndicator(client, arid, \"Invite\", timeout, false);\n if (envelope === null || envelope === undefined) {\n throw new Error(\"Invite not found in Hubert storage\");\n }\n return envelope;\n } catch (e) {\n // Not an ARID, fall through to envelope parsing\n if (e instanceof Error && e.message.includes(\"Invite not found in Hubert storage\")) {\n throw e;\n }\n }\n\n if (timeout !== undefined) {\n throw new Error(\"--timeout is only valid when retrieving invites from Hubert\");\n }\n\n return parseEnvelopeUr(invite);\n }\n\n // No storage selection\n try {\n parseAridUr(invite);\n throw new Error(\"Hubert storage parameters are required to retrieve invites by ARID\");\n } catch (e) {\n // Not an ARID, parse as envelope\n if (e instanceof Error && e.message.includes(\"Hubert storage parameters are required\")) {\n throw e;\n }\n }\n\n return parseEnvelopeUr(invite);\n}\n\n/**\n * Build the response body envelope.\n *\n * Port of `build_response_body()` from cmd/dkg/participant/round1.rs lines 290-308.\n */\nfunction buildResponseBody(\n groupId: ARID,\n participant: XID,\n responseArid: ARID,\n round1Package: DkgRound1Package | undefined,\n): Envelope {\n let envelope = Envelope.unit()\n .addType(\"dkgRound1Response\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"participant\", participant)\n .addAssertion(\"response_arid\", responseArid);\n\n if (round1Package !== undefined) {\n // Serialize the package to JSON and wrap as CBOR JSON\n const packageJson = serde.round1PackageToJson(round1Package);\n const jsonStr = globalThis.JSON.stringify(packageJson);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const jsonWrapper = JSONWrapper.fromData(jsonBytes);\n // Pass the JSONWrapper directly - it implements CborTaggedEncodable\n envelope = envelope.addAssertion(\"round1_package\", jsonWrapper);\n }\n\n return envelope;\n}\n\n/**\n * Serialize round 1 secret package to JSON-compatible format.\n *\n * The @frosts/ed25519 serde module doesn't provide a serializer for SecretPackage,\n * so we manually serialize it here.\n */\nfunction serializeRound1SecretPackage(secret: DkgRound1SecretPackage): Record<string, unknown> {\n // Mirrors the on-disk shape produced by Rust\n // `serde_json::to_vec_pretty(&frost::keys::dkg::round1::SecretPackage)`\n // (see `frost-rust/frost-core/src/keys/dkg.rs:120-139`):\n //\n // {\n // \"identifier\": \"<lowercase hex scalar>\",\n // \"coefficients\": [\"<hex>\", \"<hex>\", ...],\n // \"commitment\": [\"<hex>\", \"<hex>\", ...],\n // \"min_signers\": <u16>,\n // \"max_signers\": <u16>\n // }\n //\n // `frost::keys::dkg::round1::SecretPackage` is `#[serde(deny_unknown_fields)]`\n // and has no `header` field (the secret package is private to the\n // participant). The earlier port emitted a top-level `header` which\n // would fail `deny_unknown_fields` validation if Rust ever loaded\n // the file.\n //\n // `Identifier`/`SerializableScalar` serialize via\n // `serdect::array::serialize_hex_lower_or_bin` → lowercase hex for\n // JSON, which `bytesToHex` produces.\n const coefficients = secret.coefficients();\n const serializedCoefficients = coefficients.map((c: unknown) =>\n bytesToHex(\n Ed25519Sha512.serializeScalar(c as Parameters<typeof Ed25519Sha512.serializeScalar>[0]),\n ),\n );\n\n const commitment = secret.commitment;\n const commitmentCoefficients = commitment.serialize().map((c: Uint8Array) => bytesToHex(c));\n\n return {\n identifier: bytesToHex(secret.identifier.serialize()),\n coefficients: serializedCoefficients,\n commitment: commitmentCoefficients,\n min_signers: secret.minSigners,\n max_signers: secret.maxSigners,\n };\n}\n\n/**\n * Persist round 1 state to disk.\n *\n * Port of `persist_round1_state()` from cmd/dkg/participant/round1.rs lines 310-337.\n */\nfunction persistRound1State(\n registryPath: string,\n groupId: ARID,\n round1Secret: DkgRound1SecretPackage,\n round1Package: DkgRound1Package,\n): ContributionPaths {\n const dir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n const secretPath = path.join(dir, \"round1_secret.json\");\n const packagePath = path.join(dir, \"round1_package.json\");\n\n // Serialize the secret package manually since serde doesn't provide it\n const secretJson = serializeRound1SecretPackage(round1Secret);\n // Serialize the public package using the standard serde function\n const packageJson = serde.round1PackageToJson(round1Package);\n\n fs.writeFileSync(secretPath, globalThis.JSON.stringify(secretJson, null, 2));\n fs.writeFileSync(packagePath, globalThis.JSON.stringify(packageJson, null, 2));\n\n return new ContributionPaths({\n round1Secret: secretPath,\n round1Package: packagePath,\n round2Secret: undefined,\n keyPackage: undefined,\n });\n}\n\n/**\n * Execute the DKG participant round 1 command.\n *\n * Responds to the DKG invite with commitment packages.\n *\n * Port of `CommandArgs::exec()` from cmd/dkg/participant/round1.rs lines 66-254.\n */\nexport async function round1(\n _client: StorageClient | undefined,\n options: DkgRound1Options,\n cwd: string,\n): Promise<DkgRound1Result> {\n // Validate options\n if (options.storageSelection === undefined && options.timeoutSeconds !== undefined) {\n throw new Error(\"--timeout requires Hubert storage parameters\");\n }\n if (options.storageSelection !== undefined && options.preview === true) {\n throw new Error(\"--preview cannot be used with Hubert storage options\");\n }\n\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 with private keys is required\");\n }\n\n // Resolve expected sender if provided. Uses the shared helper from\n // `cmd/dkg/common.ts` (mirrors Rust `resolve_sender`); the\n // duplicated inline implementation that this previously called has\n // been removed.\n let expectedSender: XIDDocument | undefined;\n if (options.sender !== undefined) {\n expectedSender = resolveSender(registry, options.sender);\n }\n\n const nextResponseArid =\n options.responseArid !== undefined ? parseAridUr(options.responseArid) : ARID.new();\n\n // Resolve the invite envelope\n const inviteEnvelope = await resolveInviteEnvelope(\n options.storageSelection,\n options.invite,\n options.timeoutSeconds,\n );\n\n // Decode the invite details\n const now = CborDate.now().datetime();\n const details = decodeInviteDetails(\n inviteEnvelope,\n now,\n registry,\n owner.xidDocument(),\n expectedSender,\n );\n\n // Sort participants by XID byte order (mirrors Rust `XID::cmp` —\n // raw 32-byte lex compare). The earlier port used\n // `xid.urString().localeCompare(...)`, which differs from byte\n // order when bytes ≥ 0x80 are present and is locale-aware,\n // producing different FROST identifier assignments and therefore\n // different secret shares than Rust.\n const sortedParticipants = [...details.participants].sort((a, b) =>\n compareXidBytes(a.xid().toData(), b.xid().toData()),\n );\n\n const ownerIndex = sortedParticipants.findIndex(\n (doc) => doc.xid().urString() === owner.xid().urString(),\n );\n if (ownerIndex === -1) {\n throw new Error(\"Invite does not include the registry owner\");\n }\n\n const identifierIndex = ownerIndex + 1; // FROST uses 1-indexed identifiers\n if (identifierIndex > 65535) {\n throw new Error(\"Too many participants for identifiers\");\n }\n const identifier = identifierFromU16(identifierIndex);\n\n const total = sortedParticipants.length;\n if (total > 65535) {\n throw new Error(\"Too many participants for FROST identifiers\");\n }\n\n const minSigners = details.invitation.minSigners();\n if (minSigners > 65535) {\n throw new Error(\"min_signers does not fit into identifier space\");\n }\n\n // Build group participants for the registry\n const groupParticipants = buildGroupParticipants(registry, owner, sortedParticipants);\n const coordinator = groupParticipantFromRegistry(registry, owner, details.invitation.sender());\n\n // Check if we're posting to storage\n const isPosting = options.storageSelection !== undefined;\n\n // Build the response body\n let responseBody: Envelope;\n let contributions: ContributionPaths | undefined;\n\n if (options.rejectReason === undefined && isPosting) {\n // Actually posting - generate and persist round1 state\n const [round1Secret, round1Package] = dkgPart1(identifier, total, minSigners, createRng());\n\n contributions = persistRound1State(\n registryPath,\n details.invitation.groupId(),\n round1Secret,\n round1Package,\n );\n\n responseBody = buildResponseBody(\n details.invitation.groupId(),\n owner.xid(),\n nextResponseArid,\n round1Package,\n );\n\n // Create and save group record\n const groupRecord = new GroupRecord(\n details.invitation.charter(),\n details.invitation.minSigners(),\n coordinator,\n groupParticipants,\n );\n groupRecord.setContributions(contributions);\n groupRecord.setListeningAtArid(nextResponseArid);\n\n registry.recordGroup(details.invitation.groupId(), groupRecord);\n registry.save(registryPath);\n } else if (options.rejectReason === undefined) {\n // Preview mode - generate dummy round1 for envelope structure only\n const [, round1Package] = dkgPart1(identifier, total, minSigners, createRng());\n\n responseBody = buildResponseBody(\n details.invitation.groupId(),\n owner.xid(),\n nextResponseArid,\n round1Package,\n );\n } else {\n // Rejecting - no round1 needed\n responseBody = buildResponseBody(\n details.invitation.groupId(),\n owner.xid(),\n nextResponseArid,\n undefined,\n );\n }\n\n // Build the sealed response\n const signerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no signing keys\");\n }\n\n let sealed: SealedResponse;\n if (options.rejectReason !== undefined) {\n // Build rejection error body\n const errorBody = Envelope.new(\"dkgInviteReject\")\n .addAssertion(\"group\", details.invitation.groupId())\n .addAssertion(\"response_arid\", nextResponseArid)\n .addAssertion(\"reason\", options.rejectReason);\n\n sealed = SealedResponse.newFailure(details.invitation.requestId(), owner.xidDocument())\n .withError(errorBody)\n .withState(nextResponseArid);\n } else {\n sealed = SealedResponse.newSuccess(details.invitation.requestId(), owner.xidDocument())\n .withResult(responseBody)\n .withState(nextResponseArid);\n }\n\n // Add peer continuation if present\n const peerContinuation = details.invitation.peerContinuation();\n if (peerContinuation !== undefined) {\n sealed = sealed.withPeerContinuation(peerContinuation);\n }\n\n // Handle output based on storage selection\n if (options.storageSelection !== undefined) {\n const responseEnvelope = sealed.toEnvelope(\n details.invitation.validUntil(),\n signerPrivateKeys,\n details.invitation.sender(),\n );\n\n const responseTarget = details.invitation.responseArid();\n const client = await createStorageClient(options.storageSelection);\n\n await putWithIndicator(\n client,\n responseTarget,\n responseEnvelope,\n \"Round 1 Response\",\n options.verbose ?? false,\n );\n\n if (options.verbose === true) {\n console.log(`Sent round 1 response`);\n console.log(`Listening at: ${nextResponseArid.urString()}`);\n }\n\n return {\n accepted: options.rejectReason === undefined,\n listeningArid: nextResponseArid.urString(),\n };\n } else if (options.preview === true) {\n // Show the GSTP response structure without encryption\n const unsealedEnvelope = sealed.toEnvelope(undefined, signerPrivateKeys, undefined);\n const envelopeUr = unsealedEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n accepted: options.rejectReason === undefined,\n envelopeUr,\n };\n } else {\n // Print the sealed envelope\n const responseEnvelope = sealed.toEnvelope(\n details.invitation.validUntil(),\n signerPrivateKeys,\n details.invitation.sender(),\n );\n const envelopeUr = responseEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n accepted: options.rejectReason === undefined,\n envelopeUr,\n };\n }\n}\n\n// `resolveSenderXidDocument` removed — it was an inline duplicate of\n// Rust `resolve_sender(registry, input)`. The shared helper now lives\n// in `cmd/dkg/common.ts` and is imported above.\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
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-
|
|
3
|
+
const require_common = require("./common-CnvAUC2b.cjs");
|
|
4
|
+
const require_busy = require("./busy-B_h0bNAJ.cjs");
|
|
5
5
|
const require_frost_index = require("./frost/index.cjs");
|
|
6
|
-
const require_common$1 = require("./common-
|
|
6
|
+
const require_common$1 = require("./common-7-BOgaTt.cjs");
|
|
7
7
|
let _bcts_components = require("@bcts/components");
|
|
8
8
|
let _bcts_dcbor = require("@bcts/dcbor");
|
|
9
9
|
let _bcts_envelope = require("@bcts/envelope");
|
|
@@ -302,4 +302,4 @@ Object.defineProperty(exports, "round2_exports", {
|
|
|
302
302
|
}
|
|
303
303
|
});
|
|
304
304
|
|
|
305
|
-
//# sourceMappingURL=round2-
|
|
305
|
+
//# sourceMappingURL=round2-AMDYMUIg.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round2-BWz9SQIi.cjs","names":["path","fs","ARIDClass","parseAridUr","XIDClass","signingStateDir","Nonce","Ed25519Sha512","serde","SigningNonces","deserializeSigningCommitments","EnvelopeFunction","JSONComponent","identifierFromU16","serializeSignatureShare","Envelope","serializeSigningCommitments","resolveRegistryPath","Registry","deserializeKeyPackage","getWithIndicator","CborDate","signingRound2","createSigningPackage","putWithIndicator"],"sources":["../src/cmd/sign/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant round 2 command.\n *\n * Port of cmd/sign/participant/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 JSON as JSONComponent,\n type Digest,\n} from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr } from \"../../dkg/common.js\";\nimport { signingStateDir } from \"../common.js\";\nimport {\n signingRound2,\n createSigningPackage,\n deserializeKeyPackage,\n deserializeSigningCommitments,\n serializeSignatureShare,\n serializeSigningCommitments,\n identifierFromU16,\n type SerializedKeyPackage,\n type SerializedSigningCommitments,\n type FrostIdentifier,\n type FrostKeyPackage,\n type Ed25519SigningCommitments,\n type Ed25519SignatureShare,\n} from \"../../../frost/index.js\";\n\n// Import nonces from @frosts/core\nimport { Nonce, SigningNonces } from \"@frosts/core\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\n\n/**\n * Options for the sign round2 command.\n */\nexport interface SignRound2Options {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n preview?: boolean;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round2 command.\n */\nexport interface SignRound2Result {\n listeningArid: string;\n}\n\n/**\n * ReceiveState loaded from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/round2.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * CommitState loaded from commit.json.\n *\n * Port of `struct CommitState` from cmd/sign/participant/round2.rs.\n */\ninterface CommitState {\n nextShareArid: ARID;\n targetUr: string;\n signingNonces: SigningNonces<typeof Ed25519Sha512>;\n signingCommitments: Ed25519SigningCommitments;\n}\n\n/**\n * Sealed request interface for GSTP.\n */\ninterface SealedRequestInstance {\n function: () => unknown;\n id: () => ARID;\n sender: () => { xid: () => XID };\n extractObjectForParameter: <T>(name: string) => T;\n objectsForParameter: (name: string) => Envelope[];\n}\n\n/**\n * Load receive state from sign_receive.json.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadReceiveState(registryPath: string, sessionId: ARID, groupHint?: ARID): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Find candidate paths\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 const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, statePath] = candidates[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 sign_receive.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n // Validate group matches\n const groupInState = parseAridUr(getStr(\"group\"));\n if (groupInState.urString() !== groupId.urString()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n // Parse participants\n const participantsVal = raw[\"participants\"] as string[] | undefined;\n if (!participantsVal || !Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\n }\n\n const participants: XID[] = [];\n for (const entry of participantsVal) {\n if (typeof entry !== \"string\") {\n throw new Error(\"Invalid participant entry in sign_receive.json\");\n }\n participants.push(XIDClass.fromURString(entry));\n }\n\n // Parse min_signers\n const minSigners = raw[\"min_signers\"];\n if (typeof minSigners !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n\n const targetUr = getStr(\"target\");\n\n return {\n groupId,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load commit state from commit.json (includes nonces).\n *\n * Port of `load_commit_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadCommitState(registryPath: string, groupId: ARID, sessionId: ARID): CommitState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const statePath = path.join(dir, \"commit.json\");\n\n if (!fs.existsSync(statePath)) {\n throw new Error(\n `Commit state not found at ${statePath}. Run \\`frost sign participant commit\\` 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 commit.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in commit.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const nextShareArid = parseAridUr(getStr(\"next_share_arid\"));\n const targetUr = getStr(\"target\");\n\n // Deserialize signing nonces\n const noncesRaw = raw[\"signing_nonces\"] as Record<string, string> | undefined;\n if (!noncesRaw) {\n throw new Error(\"Missing signing_nonces in commit.json\");\n }\n\n const hidingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"hiding\"]));\n const bindingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"binding\"]));\n const signingNonces = SigningNonces.fromNonces(Ed25519Sha512, hidingNonce, bindingNonce);\n\n // Deserialize signing commitments\n const commitmentsRaw = raw[\"signing_commitments\"] as SerializedSigningCommitments | undefined;\n if (!commitmentsRaw) {\n throw new Error(\"Missing signing_commitments in commit.json\");\n }\n const signingCommitments = deserializeSigningCommitments(commitmentsRaw);\n\n return {\n nextShareArid,\n targetUr,\n signingNonces,\n signingCommitments,\n };\n}\n\n/**\n * Validate the incoming GSTP request.\n *\n * Port of request validation logic from cmd/sign/participant/round2.rs.\n */\nfunction validateShareRequest(\n sealedRequest: SealedRequestInstance,\n sessionId: ARID,\n expectedCoordinator: XID,\n): void {\n // Check function\n const expectedFunction = EnvelopeFunction.fromString(\"signRound2\");\n const actualFunction = sealedRequest.function();\n // @ts-expect-error - function() returns unknown, but it should have .equals()\n if (actualFunction.equals(expectedFunction) !== true) {\n throw new Error(`Unexpected request function: ${String(sealedRequest.function())}`);\n }\n\n // Check session ID\n if (sealedRequest.id().urString() !== sessionId.urString()) {\n throw new Error(\n `Session ID mismatch (request ${sealedRequest.id().urString()}, expected ${sessionId.urString()})`,\n );\n }\n\n // Check sender (coordinator)\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Extract all commitments from the signRound2 request.\n *\n * Port of `parse_commitments()` from cmd/sign/participant/round2.rs.\n */\nfunction extractCommitments(\n sealedRequest: SealedRequestInstance,\n receiveState: ReceiveState,\n): Map<string, Ed25519SigningCommitments> {\n const commitments = new Map<string, Ed25519SigningCommitments>();\n\n const commitmentObjects = sealedRequest.objectsForParameter(\"commitment\");\n\n for (const entry of commitmentObjects) {\n // Extract XID subject\n const xid = XIDClass.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract commitments from the \"commitments\" predicate\n const commitmentsObjects = entry.objectsForPredicate(\"commitments\");\n if (commitmentsObjects.length === 0) {\n throw new Error(`Missing commitments for participant ${xid.urString()}`);\n }\n\n const commitmentsJson = JSONComponent.fromTaggedCbor(commitmentsObjects[0].subject().tryLeaf());\n const serializedCommitments = JSON.parse(\n commitmentsJson.asStr(),\n ) as SerializedSigningCommitments;\n const signingCommitments = deserializeSigningCommitments(serializedCommitments);\n\n const xidUr = xid.urString();\n if (commitments.has(xidUr)) {\n throw new Error(`Duplicate commitments for participant ${xidUr}`);\n }\n commitments.set(xidUr, signingCommitments);\n }\n\n if (commitments.size === 0) {\n throw new Error(\"signRound2 request contains no commitments\");\n }\n\n // Validate expected participant set\n const expectedSet = new Set(receiveState.participants.map((p) => p.urString()));\n const actualSet = new Set(commitments.keys());\n\n const missing: string[] = [];\n const extra: string[] = [];\n\n for (const xid of expectedSet) {\n if (!actualSet.has(xid)) {\n missing.push(xid);\n }\n }\n for (const xid of actualSet) {\n if (!expectedSet.has(xid)) {\n extra.push(xid);\n }\n }\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `signRound2 commitments do not match session participants (missing: ${missing.join(\", \")}; extra: ${extra.join(\", \")})`,\n );\n }\n\n return commitments;\n}\n\n/**\n * Build a map from XID to FROST identifier (sorted participant order).\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/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/participant/round2.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, Ed25519SigningCommitments>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidUr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(`Unknown participant ${xidUr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Build the signRound2Response body envelope.\n *\n * Port of response body construction from cmd/sign/participant/round2.rs.\n */\nfunction buildResponseBody(\n sessionId: ARID,\n signatureShare: Ed25519SignatureShare,\n finalizeArid: ARID,\n): Envelope {\n const shareHex = serializeSignatureShare(signatureShare);\n const shareJson = JSONComponent.fromString(JSON.stringify({ share: shareHex }));\n\n return Envelope.unit()\n .addType(\"signRound2Response\")\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"signature_share\", shareJson)\n .addAssertion(\"response_arid\", finalizeArid);\n}\n\n/**\n * Persist share state to share.json.\n *\n * Port of `persist_share_state()` from cmd/sign/participant/round2.rs.\n */\nfunction persistShareState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n responseArid: ARID,\n finalizeArid: ARID,\n signatureShare: Ed25519SignatureShare,\n commitments: Map<string, Ed25519SigningCommitments>,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Build commitments JSON object\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidUr, commits] of commitments) {\n commitmentsJson[xidUr] = serializeSigningCommitments(commits);\n }\n\n // Build root JSON object\n const root = {\n session: sessionId.urString(),\n response_arid: responseArid.urString(),\n finalize_arid: finalizeArid.urString(),\n signature_share: { share: serializeSignatureShare(signatureShare) },\n commitments: commitmentsJson,\n };\n\n fs.writeFileSync(path.join(dir, \"share.json\"), JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant round 2 command.\n *\n * Receives round 2 request and sends signature share.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/participant/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 const ownerXidDocument = owner.xidDocument();\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint = options.groupId ? parseAridUr(options.groupId) : undefined;\n\n // Load receive state (finds group automatically if not specified)\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n\n const groupRecord = registry.group(groupId);\n if (!groupRecord) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Validate min_signers matches\n if (groupRecord.minSigners() !== receiveState.minSigners) {\n throw new Error(\n `Session min_signers ${receiveState.minSigners} does not match registry ${groupRecord.minSigners()}`,\n );\n }\n\n // Validate participants match\n const registryParticipants = new Set(groupRecord.participants().map((p) => p.xid().urString()));\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (\n registryParticipants.size !== sessionParticipants.size ||\n ![...registryParticipants].every((p) => sessionParticipants.has(p))\n ) {\n throw new Error(\"Session participants do not match registry group participants\");\n }\n\n // Validate owner participates in this session\n if (!sessionParticipants.has(owner.xid().urString())) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\n // Get listening ARID from registry\n const listeningAtArid = groupRecord.listeningAtArid();\n if (!listeningAtArid) {\n throw new Error(\n \"No listening ARID for signRound2. Did you run `frost sign participant commit`?\",\n );\n }\n\n // Load commit state and validate\n const commitState = loadCommitState(registryPath, groupId, sessionId);\n\n if (commitState.nextShareArid.urString() !== listeningAtArid.urString()) {\n throw new Error(\n `Listening ARID in registry (${listeningAtArid.urString()}) does not match persisted commit state (${commitState.nextShareArid.urString()})`,\n );\n }\n\n if (commitState.targetUr !== receiveState.targetUr) {\n throw new Error(\"Target envelope in commit state does not match persisted signInvite request\");\n }\n\n // Load key package\n const keyPackagePath = groupRecord.contributions().keyPackage;\n if (!keyPackagePath) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n\n interface KeyPackageFile {\n group?: string;\n key_package: SerializedKeyPackage;\n }\n\n const keyPackageFile = JSON.parse(fs.readFileSync(keyPackagePath, \"utf-8\")) as KeyPackageFile;\n const keyPackage: FrostKeyPackage = deserializeKeyPackage(keyPackageFile.key_package);\n\n // Create finalize ARID\n const finalizeArid = ARIDClass.new();\n\n // Compute target digest from persisted target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest: Digest = targetEnvelope.subject().digest();\n\n if (options.verbose === true) {\n console.error(\"Fetching signRound2 request from Hubert...\");\n }\n\n // Fetch request from storage\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"signRound2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (!requestEnvelope) {\n throw new Error(\"signRound2 request not found in Hubert storage\");\n }\n\n // Parse sealed request\n const signerPrivateKeys = ownerXidDocument.inceptionPrivateKeys();\n if (!signerPrivateKeys) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedRequest: SealedRequestClass } = require(\"@bcts/gstp\") as {\n SealedRequest: {\n tryFromEnvelope: (\n envelope: Envelope,\n expectedSender: XID | undefined,\n now: CborDate,\n recipientPrivateKeys: unknown,\n ) => SealedRequestInstance;\n };\n };\n\n const now = CborDate.now();\n const sealedRequest = SealedRequestClass.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n signerPrivateKeys,\n );\n\n // Validate request\n const expectedCoordinator = groupRecord.coordinator().xid();\n validateShareRequest(sealedRequest, sessionId, expectedCoordinator);\n\n // Extract response ARID from request\n const responseArid: ARID = sealedRequest.extractObjectForParameter(\"response_arid\");\n\n // Extract and validate commitments\n const commitmentsByXid = extractCommitments(sealedRequest, receiveState);\n\n // Verify our commitments match\n const myCommitments = commitmentsByXid.get(owner.xid().urString());\n if (!myCommitments) {\n throw new Error(\"signRound2 request missing commitments for this participant\");\n }\n\n // Compare commitments using serialized form\n const myCommitmentsSerialized = serializeSigningCommitments(myCommitments);\n const storedCommitmentsSerialized = serializeSigningCommitments(commitState.signingCommitments);\n\n if (\n myCommitmentsSerialized.hiding !== storedCommitmentsSerialized.hiding ||\n myCommitmentsSerialized.binding !== storedCommitmentsSerialized.binding\n ) {\n throw new Error(\"signRound2 request commitments do not match locally stored commitments\");\n }\n\n // Build XID to identifier map (sorted participant order)\n const xidToIdentifier = xidIdentifierMap(receiveState.participants);\n\n // Verify our identifier matches key package\n const myIdentifier = xidToIdentifier.get(owner.xid().urString());\n if (!myIdentifier) {\n throw new Error(\"Identifier for participant not found\");\n }\n\n // Verify key package min_signers matches\n if (keyPackage.minSigners !== receiveState.minSigners) {\n throw new Error(\n `Key package min_signers ${keyPackage.minSigners} does not match session ${receiveState.minSigners}`,\n );\n }\n\n // Verify enough commitments\n if (commitmentsByXid.size < receiveState.minSigners) {\n throw new Error(\n `signRound2 request contained ${commitmentsByXid.size} commitments but requires at least ${receiveState.minSigners} signers`,\n );\n }\n\n // Build signing commitments with identifiers\n const signingCommitments = commitmentsWithIdentifiers(commitmentsByXid, xidToIdentifier);\n\n // Create signing package\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n // Generate signature share using FROST round 2\n const signatureShare = signingRound2(signingPackage, commitState.signingNonces, keyPackage);\n\n // Build response body\n const responseBody = buildResponseBody(sessionId, signatureShare, finalizeArid);\n\n // Build sealed response\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedResponse: SealedResponseClass } = require(\"@bcts/gstp\") as {\n SealedResponse: {\n newSuccess: (\n requestId: ARID,\n sender: XIDDocument,\n ) => {\n withResult: (result: Envelope) => {\n withPeerContinuation: (continuation: unknown) => {\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n };\n };\n };\n\n const sealedResponse = SealedResponseClass.newSuccess(\n sealedRequest.id(),\n ownerXidDocument,\n ).withResult(responseBody);\n\n // Preview mode - print unsealed response\n if (options.preview === true) {\n const unsealed = sealedResponse.toEnvelope(undefined, signerPrivateKeys, undefined);\n console.log(unsealed.urString());\n return {\n listeningArid: finalizeArid.urString(),\n };\n }\n\n // Get coordinator XID document for encryption\n let coordinatorDoc: XIDDocument;\n if (expectedCoordinator.urString() === owner.xid().urString()) {\n coordinatorDoc = ownerXidDocument;\n } else {\n const coordinatorRecord = registry.participant(expectedCoordinator);\n if (!coordinatorRecord) {\n throw new Error(`Coordinator ${expectedCoordinator.urString()} not found in registry`);\n }\n coordinatorDoc = coordinatorRecord.xidDocument();\n }\n\n // Create response envelope with expiry\n const expiry = CborDate.withDurationFromNow(60 * 60); // 1 hour\n const responseEnvelope = sealedResponse.toEnvelope(expiry, signerPrivateKeys, coordinatorDoc);\n\n // Send response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Signature Share\",\n options.verbose ?? false,\n );\n\n // Persist share state\n persistShareState(\n registryPath,\n groupId,\n sessionId,\n responseArid,\n finalizeArid,\n signatureShare,\n commitmentsByXid,\n );\n\n // Update registry with finalize listening ARID\n const groupRecordMutable = registry.group(groupId);\n if (groupRecordMutable) {\n groupRecordMutable.setListeningAtArid(finalizeArid);\n registry.save(registryPath);\n }\n\n if (options.verbose === true) {\n console.error(`Posted signature share to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: finalizeArid.urString(),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"round2-AMDYMUIg.cjs","names":["path","fs","ARIDClass","parseAridUr","XIDClass","signingStateDir","Nonce","Ed25519Sha512","serde","SigningNonces","deserializeSigningCommitments","EnvelopeFunction","JSONComponent","identifierFromU16","serializeSignatureShare","Envelope","serializeSigningCommitments","resolveRegistryPath","Registry","deserializeKeyPackage","getWithIndicator","CborDate","signingRound2","createSigningPackage","putWithIndicator"],"sources":["../src/cmd/sign/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant round 2 command.\n *\n * Port of cmd/sign/participant/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 JSON as JSONComponent,\n type Digest,\n} from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr } from \"../../dkg/common.js\";\nimport { signingStateDir } from \"../common.js\";\nimport {\n signingRound2,\n createSigningPackage,\n deserializeKeyPackage,\n deserializeSigningCommitments,\n serializeSignatureShare,\n serializeSigningCommitments,\n identifierFromU16,\n type SerializedKeyPackage,\n type SerializedSigningCommitments,\n type FrostIdentifier,\n type FrostKeyPackage,\n type Ed25519SigningCommitments,\n type Ed25519SignatureShare,\n} from \"../../../frost/index.js\";\n\n// Import nonces from @frosts/core\nimport { Nonce, SigningNonces } from \"@frosts/core\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\n\n/**\n * Options for the sign round2 command.\n */\nexport interface SignRound2Options {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n preview?: boolean;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round2 command.\n */\nexport interface SignRound2Result {\n listeningArid: string;\n}\n\n/**\n * ReceiveState loaded from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/round2.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * CommitState loaded from commit.json.\n *\n * Port of `struct CommitState` from cmd/sign/participant/round2.rs.\n */\ninterface CommitState {\n nextShareArid: ARID;\n targetUr: string;\n signingNonces: SigningNonces<typeof Ed25519Sha512>;\n signingCommitments: Ed25519SigningCommitments;\n}\n\n/**\n * Sealed request interface for GSTP.\n */\ninterface SealedRequestInstance {\n function: () => unknown;\n id: () => ARID;\n sender: () => { xid: () => XID };\n extractObjectForParameter: <T>(name: string) => T;\n objectsForParameter: (name: string) => Envelope[];\n}\n\n/**\n * Load receive state from sign_receive.json.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadReceiveState(registryPath: string, sessionId: ARID, groupHint?: ARID): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Find candidate paths\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 const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, statePath] = candidates[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 sign_receive.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n // Validate group matches\n const groupInState = parseAridUr(getStr(\"group\"));\n if (groupInState.urString() !== groupId.urString()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n // Parse participants\n const participantsVal = raw[\"participants\"] as string[] | undefined;\n if (!participantsVal || !Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\n }\n\n const participants: XID[] = [];\n for (const entry of participantsVal) {\n if (typeof entry !== \"string\") {\n throw new Error(\"Invalid participant entry in sign_receive.json\");\n }\n participants.push(XIDClass.fromURString(entry));\n }\n\n // Parse min_signers\n const minSigners = raw[\"min_signers\"];\n if (typeof minSigners !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n\n const targetUr = getStr(\"target\");\n\n return {\n groupId,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load commit state from commit.json (includes nonces).\n *\n * Port of `load_commit_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadCommitState(registryPath: string, groupId: ARID, sessionId: ARID): CommitState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const statePath = path.join(dir, \"commit.json\");\n\n if (!fs.existsSync(statePath)) {\n throw new Error(\n `Commit state not found at ${statePath}. Run \\`frost sign participant commit\\` 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 commit.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in commit.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const nextShareArid = parseAridUr(getStr(\"next_share_arid\"));\n const targetUr = getStr(\"target\");\n\n // Deserialize signing nonces\n const noncesRaw = raw[\"signing_nonces\"] as Record<string, string> | undefined;\n if (!noncesRaw) {\n throw new Error(\"Missing signing_nonces in commit.json\");\n }\n\n const hidingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"hiding\"]));\n const bindingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"binding\"]));\n const signingNonces = SigningNonces.fromNonces(Ed25519Sha512, hidingNonce, bindingNonce);\n\n // Deserialize signing commitments\n const commitmentsRaw = raw[\"signing_commitments\"] as SerializedSigningCommitments | undefined;\n if (!commitmentsRaw) {\n throw new Error(\"Missing signing_commitments in commit.json\");\n }\n const signingCommitments = deserializeSigningCommitments(commitmentsRaw);\n\n return {\n nextShareArid,\n targetUr,\n signingNonces,\n signingCommitments,\n };\n}\n\n/**\n * Validate the incoming GSTP request.\n *\n * Port of request validation logic from cmd/sign/participant/round2.rs.\n */\nfunction validateShareRequest(\n sealedRequest: SealedRequestInstance,\n sessionId: ARID,\n expectedCoordinator: XID,\n): void {\n // Check function\n const expectedFunction = EnvelopeFunction.fromString(\"signRound2\");\n const actualFunction = sealedRequest.function();\n // @ts-expect-error - function() returns unknown, but it should have .equals()\n if (actualFunction.equals(expectedFunction) !== true) {\n throw new Error(`Unexpected request function: ${String(sealedRequest.function())}`);\n }\n\n // Check session ID\n if (sealedRequest.id().urString() !== sessionId.urString()) {\n throw new Error(\n `Session ID mismatch (request ${sealedRequest.id().urString()}, expected ${sessionId.urString()})`,\n );\n }\n\n // Check sender (coordinator)\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Extract all commitments from the signRound2 request.\n *\n * Port of `parse_commitments()` from cmd/sign/participant/round2.rs.\n */\nfunction extractCommitments(\n sealedRequest: SealedRequestInstance,\n receiveState: ReceiveState,\n): Map<string, Ed25519SigningCommitments> {\n const commitments = new Map<string, Ed25519SigningCommitments>();\n\n const commitmentObjects = sealedRequest.objectsForParameter(\"commitment\");\n\n for (const entry of commitmentObjects) {\n // Extract XID subject\n const xid = XIDClass.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract commitments from the \"commitments\" predicate\n const commitmentsObjects = entry.objectsForPredicate(\"commitments\");\n if (commitmentsObjects.length === 0) {\n throw new Error(`Missing commitments for participant ${xid.urString()}`);\n }\n\n const commitmentsJson = JSONComponent.fromTaggedCbor(commitmentsObjects[0].subject().tryLeaf());\n const serializedCommitments = JSON.parse(\n commitmentsJson.asStr(),\n ) as SerializedSigningCommitments;\n const signingCommitments = deserializeSigningCommitments(serializedCommitments);\n\n const xidUr = xid.urString();\n if (commitments.has(xidUr)) {\n throw new Error(`Duplicate commitments for participant ${xidUr}`);\n }\n commitments.set(xidUr, signingCommitments);\n }\n\n if (commitments.size === 0) {\n throw new Error(\"signRound2 request contains no commitments\");\n }\n\n // Validate expected participant set\n const expectedSet = new Set(receiveState.participants.map((p) => p.urString()));\n const actualSet = new Set(commitments.keys());\n\n const missing: string[] = [];\n const extra: string[] = [];\n\n for (const xid of expectedSet) {\n if (!actualSet.has(xid)) {\n missing.push(xid);\n }\n }\n for (const xid of actualSet) {\n if (!expectedSet.has(xid)) {\n extra.push(xid);\n }\n }\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `signRound2 commitments do not match session participants (missing: ${missing.join(\", \")}; extra: ${extra.join(\", \")})`,\n );\n }\n\n return commitments;\n}\n\n/**\n * Build a map from XID to FROST identifier (sorted participant order).\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/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/participant/round2.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, Ed25519SigningCommitments>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidUr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(`Unknown participant ${xidUr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Build the signRound2Response body envelope.\n *\n * Port of response body construction from cmd/sign/participant/round2.rs.\n */\nfunction buildResponseBody(\n sessionId: ARID,\n signatureShare: Ed25519SignatureShare,\n finalizeArid: ARID,\n): Envelope {\n const shareHex = serializeSignatureShare(signatureShare);\n const shareJson = JSONComponent.fromString(JSON.stringify({ share: shareHex }));\n\n return Envelope.unit()\n .addType(\"signRound2Response\")\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"signature_share\", shareJson)\n .addAssertion(\"response_arid\", finalizeArid);\n}\n\n/**\n * Persist share state to share.json.\n *\n * Port of `persist_share_state()` from cmd/sign/participant/round2.rs.\n */\nfunction persistShareState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n responseArid: ARID,\n finalizeArid: ARID,\n signatureShare: Ed25519SignatureShare,\n commitments: Map<string, Ed25519SigningCommitments>,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Build commitments JSON object\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidUr, commits] of commitments) {\n commitmentsJson[xidUr] = serializeSigningCommitments(commits);\n }\n\n // Build root JSON object\n const root = {\n session: sessionId.urString(),\n response_arid: responseArid.urString(),\n finalize_arid: finalizeArid.urString(),\n signature_share: { share: serializeSignatureShare(signatureShare) },\n commitments: commitmentsJson,\n };\n\n fs.writeFileSync(path.join(dir, \"share.json\"), JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant round 2 command.\n *\n * Receives round 2 request and sends signature share.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/participant/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 const ownerXidDocument = owner.xidDocument();\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint = options.groupId ? parseAridUr(options.groupId) : undefined;\n\n // Load receive state (finds group automatically if not specified)\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n\n const groupRecord = registry.group(groupId);\n if (!groupRecord) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Validate min_signers matches\n if (groupRecord.minSigners() !== receiveState.minSigners) {\n throw new Error(\n `Session min_signers ${receiveState.minSigners} does not match registry ${groupRecord.minSigners()}`,\n );\n }\n\n // Validate participants match\n const registryParticipants = new Set(groupRecord.participants().map((p) => p.xid().urString()));\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (\n registryParticipants.size !== sessionParticipants.size ||\n ![...registryParticipants].every((p) => sessionParticipants.has(p))\n ) {\n throw new Error(\"Session participants do not match registry group participants\");\n }\n\n // Validate owner participates in this session\n if (!sessionParticipants.has(owner.xid().urString())) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\n // Get listening ARID from registry\n const listeningAtArid = groupRecord.listeningAtArid();\n if (!listeningAtArid) {\n throw new Error(\n \"No listening ARID for signRound2. Did you run `frost sign participant commit`?\",\n );\n }\n\n // Load commit state and validate\n const commitState = loadCommitState(registryPath, groupId, sessionId);\n\n if (commitState.nextShareArid.urString() !== listeningAtArid.urString()) {\n throw new Error(\n `Listening ARID in registry (${listeningAtArid.urString()}) does not match persisted commit state (${commitState.nextShareArid.urString()})`,\n );\n }\n\n if (commitState.targetUr !== receiveState.targetUr) {\n throw new Error(\"Target envelope in commit state does not match persisted signInvite request\");\n }\n\n // Load key package\n const keyPackagePath = groupRecord.contributions().keyPackage;\n if (!keyPackagePath) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n\n interface KeyPackageFile {\n group?: string;\n key_package: SerializedKeyPackage;\n }\n\n const keyPackageFile = JSON.parse(fs.readFileSync(keyPackagePath, \"utf-8\")) as KeyPackageFile;\n const keyPackage: FrostKeyPackage = deserializeKeyPackage(keyPackageFile.key_package);\n\n // Create finalize ARID\n const finalizeArid = ARIDClass.new();\n\n // Compute target digest from persisted target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest: Digest = targetEnvelope.subject().digest();\n\n if (options.verbose === true) {\n console.error(\"Fetching signRound2 request from Hubert...\");\n }\n\n // Fetch request from storage\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"signRound2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (!requestEnvelope) {\n throw new Error(\"signRound2 request not found in Hubert storage\");\n }\n\n // Parse sealed request\n const signerPrivateKeys = ownerXidDocument.inceptionPrivateKeys();\n if (!signerPrivateKeys) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedRequest: SealedRequestClass } = require(\"@bcts/gstp\") as {\n SealedRequest: {\n tryFromEnvelope: (\n envelope: Envelope,\n expectedSender: XID | undefined,\n now: CborDate,\n recipientPrivateKeys: unknown,\n ) => SealedRequestInstance;\n };\n };\n\n const now = CborDate.now();\n const sealedRequest = SealedRequestClass.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n signerPrivateKeys,\n );\n\n // Validate request\n const expectedCoordinator = groupRecord.coordinator().xid();\n validateShareRequest(sealedRequest, sessionId, expectedCoordinator);\n\n // Extract response ARID from request\n const responseArid: ARID = sealedRequest.extractObjectForParameter(\"response_arid\");\n\n // Extract and validate commitments\n const commitmentsByXid = extractCommitments(sealedRequest, receiveState);\n\n // Verify our commitments match\n const myCommitments = commitmentsByXid.get(owner.xid().urString());\n if (!myCommitments) {\n throw new Error(\"signRound2 request missing commitments for this participant\");\n }\n\n // Compare commitments using serialized form\n const myCommitmentsSerialized = serializeSigningCommitments(myCommitments);\n const storedCommitmentsSerialized = serializeSigningCommitments(commitState.signingCommitments);\n\n if (\n myCommitmentsSerialized.hiding !== storedCommitmentsSerialized.hiding ||\n myCommitmentsSerialized.binding !== storedCommitmentsSerialized.binding\n ) {\n throw new Error(\"signRound2 request commitments do not match locally stored commitments\");\n }\n\n // Build XID to identifier map (sorted participant order)\n const xidToIdentifier = xidIdentifierMap(receiveState.participants);\n\n // Verify our identifier matches key package\n const myIdentifier = xidToIdentifier.get(owner.xid().urString());\n if (!myIdentifier) {\n throw new Error(\"Identifier for participant not found\");\n }\n\n // Verify key package min_signers matches\n if (keyPackage.minSigners !== receiveState.minSigners) {\n throw new Error(\n `Key package min_signers ${keyPackage.minSigners} does not match session ${receiveState.minSigners}`,\n );\n }\n\n // Verify enough commitments\n if (commitmentsByXid.size < receiveState.minSigners) {\n throw new Error(\n `signRound2 request contained ${commitmentsByXid.size} commitments but requires at least ${receiveState.minSigners} signers`,\n );\n }\n\n // Build signing commitments with identifiers\n const signingCommitments = commitmentsWithIdentifiers(commitmentsByXid, xidToIdentifier);\n\n // Create signing package\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n // Generate signature share using FROST round 2\n const signatureShare = signingRound2(signingPackage, commitState.signingNonces, keyPackage);\n\n // Build response body\n const responseBody = buildResponseBody(sessionId, signatureShare, finalizeArid);\n\n // Build sealed response\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedResponse: SealedResponseClass } = require(\"@bcts/gstp\") as {\n SealedResponse: {\n newSuccess: (\n requestId: ARID,\n sender: XIDDocument,\n ) => {\n withResult: (result: Envelope) => {\n withPeerContinuation: (continuation: unknown) => {\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n };\n };\n };\n\n const sealedResponse = SealedResponseClass.newSuccess(\n sealedRequest.id(),\n ownerXidDocument,\n ).withResult(responseBody);\n\n // Preview mode - print unsealed response\n if (options.preview === true) {\n const unsealed = sealedResponse.toEnvelope(undefined, signerPrivateKeys, undefined);\n console.log(unsealed.urString());\n return {\n listeningArid: finalizeArid.urString(),\n };\n }\n\n // Get coordinator XID document for encryption\n let coordinatorDoc: XIDDocument;\n if (expectedCoordinator.urString() === owner.xid().urString()) {\n coordinatorDoc = ownerXidDocument;\n } else {\n const coordinatorRecord = registry.participant(expectedCoordinator);\n if (!coordinatorRecord) {\n throw new Error(`Coordinator ${expectedCoordinator.urString()} not found in registry`);\n }\n coordinatorDoc = coordinatorRecord.xidDocument();\n }\n\n // Create response envelope with expiry\n const expiry = CborDate.withDurationFromNow(60 * 60); // 1 hour\n const responseEnvelope = sealedResponse.toEnvelope(expiry, signerPrivateKeys, coordinatorDoc);\n\n // Send response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Signature Share\",\n options.verbose ?? false,\n );\n\n // Persist share state\n persistShareState(\n registryPath,\n groupId,\n sessionId,\n responseArid,\n finalizeArid,\n signatureShare,\n commitmentsByXid,\n );\n\n // Update registry with finalize listening ARID\n const groupRecordMutable = registry.group(groupId);\n if (groupRecordMutable) {\n groupRecordMutable.setListeningAtArid(finalizeArid);\n registry.save(registryPath);\n }\n\n if (options.verbose === true) {\n console.error(`Posted signature share to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: finalizeArid.urString(),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiHA,SAAS,iBAAiB,cAAsB,WAAiB,WAAgC;CAC/F,MAAM,OAAOA,UAAK,QAAQ,YAAY;CACtC,MAAM,gBAAgBA,UAAK,KAAK,MAAM,aAAa;CAGnD,IAAI;CAEJ,IAAI,WACF,YAAY,CAAC,CAAC,WAAWA,UAAK,KAAK,eAAe,UAAU,IAAI,CAAC,CAAC,CAAC;MAC9D;EACL,YAAY,CAAC;EACb,IAAIC,QAAG,WAAW,aAAa;QACxB,MAAM,SAASA,QAAG,YAAY,eAAe,EAAE,eAAe,KAAK,CAAC,GACvE,IAAI,MAAM,YAAY,KAAK,MAAM,KAAK,WAAW,MAAM,eAAe,KAAK,MAAM,IAAI,GAAG;IACtF,MAAM,UAAUC,iBAAAA,KAAU,QAAQ,MAAM,IAAI;IAC5C,UAAU,KAAK,CAAC,SAASF,UAAK,KAAK,eAAe,MAAM,IAAI,CAAC,CAAC;GAChE;;CAGN;CAEA,MAAM,aAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,SAAS,aAAa,WAAW;EAC3C,MAAM,YAAYA,UAAK,KAAK,UAAU,WAAW,UAAU,IAAI,GAAG,mBAAmB;EACrF,IAAIC,QAAG,WAAW,SAAS,GACzB,WAAW,KAAK,CAAC,SAAS,SAAS,CAAC;CAExC;CAEA,IAAI,WAAW,WAAW,GACxB,MAAM,IAAI,MACR,yFACF;CAEF,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MAAM,mEAAmE;CAGrF,MAAM,CAAC,SAAS,aAAa,WAAW;CACxC,MAAM,MAAM,KAAK,MAAMA,QAAG,aAAa,WAAW,OAAO,CAAC;CAE1D,MAAM,UAAU,QAAwB;EACtC,MAAM,QAAQ,IAAI;EAClB,IAAI,OAAO,UAAU,UACnB,MAAM,IAAI,MAAM,sBAAsB,IAAI,sBAAsB;EAElE,OAAO;CACT;CAGA,MAAM,iBAAiBE,eAAAA,YAAY,OAAO,SAAS,CAAC;CACpD,IAAI,eAAe,SAAS,MAAM,UAAU,SAAS,GACnD,MAAM,IAAI,MACR,WAAW,eAAe,SAAS,EAAE,yDAAyD,UAAU,SAAS,GACnH;CAIF,MAAM,eAAeA,eAAAA,YAAY,OAAO,OAAO,CAAC;CAChD,IAAI,aAAa,SAAS,MAAM,QAAQ,SAAS,GAC/C,MAAM,IAAI,MACR,SAAS,aAAa,SAAS,EAAE,uDAAuD,QAAQ,SAAS,GAC3G;CAIF,MAAM,kBAAkB,IAAI;CAC5B,IAAI,CAAC,mBAAmB,CAAC,MAAM,QAAQ,eAAe,GACpD,MAAM,IAAI,MAAM,2CAA2C;CAG7D,MAAM,eAAsB,CAAC;CAC7B,KAAK,MAAM,SAAS,iBAAiB;EACnC,IAAI,OAAO,UAAU,UACnB,MAAM,IAAI,MAAM,gDAAgD;EAElE,aAAa,KAAKC,iBAAAA,IAAS,aAAa,KAAK,CAAC;CAChD;CAGA,MAAM,aAAa,IAAI;CACvB,IAAI,OAAO,eAAe,UACxB,MAAM,IAAI,MAAM,0CAA0C;CAK5D,OAAO;EACL;EACA;EACA;EACA,UANe,OAAO,QAMf;CACT;AACF;;;;;;AAOA,SAAS,gBAAgB,cAAsB,SAAe,WAA8B;CAC1F,MAAM,MAAMC,iBAAAA,gBAAgB,cAAc,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;CACxE,MAAM,YAAYL,UAAK,KAAK,KAAK,aAAa;CAE9C,IAAI,CAACC,QAAG,WAAW,SAAS,GAC1B,MAAM,IAAI,MACR,6BAA6B,UAAU,+CACzC;CAGF,MAAM,MAAM,KAAK,MAAMA,QAAG,aAAa,WAAW,OAAO,CAAC;CAE1D,MAAM,UAAU,QAAwB;EACtC,MAAM,QAAQ,IAAI;EAClB,IAAI,OAAO,UAAU,UACnB,MAAM,IAAI,MAAM,sBAAsB,IAAI,gBAAgB;EAE5D,OAAO;CACT;CAGA,MAAM,iBAAiBE,eAAAA,YAAY,OAAO,SAAS,CAAC;CACpD,IAAI,eAAe,SAAS,MAAM,UAAU,SAAS,GACnD,MAAM,IAAI,MACR,WAAW,eAAe,SAAS,EAAE,mDAAmD,UAAU,SAAS,GAC7G;CAGF,MAAM,gBAAgBA,eAAAA,YAAY,OAAO,iBAAiB,CAAC;CAC3D,MAAM,WAAW,OAAO,QAAQ;CAGhC,MAAM,YAAY,IAAI;CACtB,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,uCAAuC;CAGzD,MAAM,cAAcG,aAAAA,MAAM,YAAYC,gBAAAA,eAAeC,gBAAAA,MAAM,WAAW,UAAU,SAAS,CAAC;CAC1F,MAAM,eAAeF,aAAAA,MAAM,YAAYC,gBAAAA,eAAeC,gBAAAA,MAAM,WAAW,UAAU,UAAU,CAAC;CAC5F,MAAM,gBAAgBC,aAAAA,cAAc,WAAWF,gBAAAA,eAAe,aAAa,YAAY;CAGvF,MAAM,iBAAiB,IAAI;CAC3B,IAAI,CAAC,gBACH,MAAM,IAAI,MAAM,4CAA4C;CAI9D,OAAO;EACL;EACA;EACA;EACA,oBANyBG,oBAAAA,8BAA8B,cAMtC;CACnB;AACF;;;;;;AAOA,SAAS,qBACP,eACA,WACA,qBACM;CAEN,MAAM,mBAAmBC,eAAAA,SAAiB,WAAW,YAAY;CAGjE,IAFuB,cAAc,SAEpB,EAAE,OAAO,gBAAgB,MAAM,MAC9C,MAAM,IAAI,MAAM,gCAAgC,OAAO,cAAc,SAAS,CAAC,GAAG;CAIpF,IAAI,cAAc,GAAG,EAAE,SAAS,MAAM,UAAU,SAAS,GACvD,MAAM,IAAI,MACR,gCAAgC,cAAc,GAAG,EAAE,SAAS,EAAE,aAAa,UAAU,SAAS,EAAE,EAClG;CAIF,IAAI,cAAc,OAAO,EAAE,IAAI,EAAE,SAAS,MAAM,oBAAoB,SAAS,GAC3E,MAAM,IAAI,MACR,8BAA8B,cAAc,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,yBAAyB,oBAAoB,SAAS,EAAE,EAChI;AAEJ;;;;;;AAOA,SAAS,mBACP,eACA,cACwC;CACxC,MAAM,8BAAc,IAAI,IAAuC;CAE/D,MAAM,oBAAoB,cAAc,oBAAoB,YAAY;CAExE,KAAK,MAAM,SAAS,mBAAmB;EAErC,MAAM,MAAMP,iBAAAA,IAAS,eAAe,MAAM,QAAQ,EAAE,QAAQ,CAAC;EAG7D,MAAM,qBAAqB,MAAM,oBAAoB,aAAa;EAClE,IAAI,mBAAmB,WAAW,GAChC,MAAM,IAAI,MAAM,uCAAuC,IAAI,SAAS,GAAG;EAGzE,MAAM,kBAAkBQ,iBAAAA,KAAc,eAAe,mBAAmB,GAAG,QAAQ,EAAE,QAAQ,CAAC;EAI9F,MAAM,qBAAqBF,oBAAAA,8BAHG,KAAK,MACjC,gBAAgB,MAAM,CAEqD,CAAC;EAE9E,MAAM,QAAQ,IAAI,SAAS;EAC3B,IAAI,YAAY,IAAI,KAAK,GACvB,MAAM,IAAI,MAAM,yCAAyC,OAAO;EAElE,YAAY,IAAI,OAAO,kBAAkB;CAC3C;CAEA,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,MAAM,4CAA4C;CAI9D,MAAM,cAAc,IAAI,IAAI,aAAa,aAAa,KAAK,MAAM,EAAE,SAAS,CAAC,CAAC;CAC9E,MAAM,YAAY,IAAI,IAAI,YAAY,KAAK,CAAC;CAE5C,MAAM,UAAoB,CAAC;CAC3B,MAAM,QAAkB,CAAC;CAEzB,KAAK,MAAM,OAAO,aAChB,IAAI,CAAC,UAAU,IAAI,GAAG,GACpB,QAAQ,KAAK,GAAG;CAGpB,KAAK,MAAM,OAAO,WAChB,IAAI,CAAC,YAAY,IAAI,GAAG,GACtB,MAAM,KAAK,GAAG;CAIlB,IAAI,QAAQ,SAAS,KAAK,MAAM,SAAS,GACvC,MAAM,IAAI,MACR,sEAAsE,QAAQ,KAAK,IAAI,EAAE,WAAW,MAAM,KAAK,IAAI,EAAE,EACvH;CAGF,OAAO;AACT;;;;;;AAOA,SAAS,iBAAiB,cAAmD;CAC3E,MAAM,sBAAM,IAAI,IAA6B;CAC7C,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;EAC5C,MAAM,aAAaG,oBAAAA,kBAAkB,IAAI,CAAC;EAC1C,IAAI,IAAI,aAAa,GAAG,SAAS,GAAG,UAAU;CAChD;CACA,OAAO;AACT;;;;;;AAOA,SAAS,2BACP,aACA,iBACiD;CACjD,MAAM,yBAAS,IAAI,IAAgD;CACnE,KAAK,MAAM,CAAC,OAAO,YAAY,aAAa;EAC1C,MAAM,aAAa,gBAAgB,IAAI,KAAK;EAC5C,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,uBAAuB,OAAO;EAEhD,OAAO,IAAI,YAAY,OAAO;CAChC;CACA,OAAO;AACT;;;;;;AAOA,SAAS,kBACP,WACA,gBACA,cACU;CACV,MAAM,WAAWC,oBAAAA,wBAAwB,cAAc;CACvD,MAAM,YAAYF,iBAAAA,KAAc,WAAW,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC,CAAC;CAE9E,OAAOG,eAAAA,SAAS,KAAK,EAClB,QAAQ,oBAAoB,EAC5B,aAAa,WAAW,SAAS,EACjC,aAAa,mBAAmB,SAAS,EACzC,aAAa,iBAAiB,YAAY;AAC/C;;;;;;AAOA,SAAS,kBACP,cACA,SACA,WACA,cACA,cACA,gBACA,aACM;CACN,MAAM,MAAMV,iBAAAA,gBAAgB,cAAc,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;CACxE,QAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;CAGrC,MAAM,kBAAgE,CAAC;CACvE,KAAK,MAAM,CAAC,OAAO,YAAY,aAC7B,gBAAgB,SAASW,oBAAAA,4BAA4B,OAAO;CAI9D,MAAM,OAAO;EACX,SAAS,UAAU,SAAS;EAC5B,eAAe,aAAa,SAAS;EACrC,eAAe,aAAa,SAAS;EACrC,iBAAiB,EAAE,OAAOF,oBAAAA,wBAAwB,cAAc,EAAE;EAClE,aAAa;CACf;CAEA,QAAG,cAAcd,UAAK,KAAK,KAAK,YAAY,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAC9E;;;;;;;;AASA,eAAsB,OACpB,QACA,SACA,KAC2B;CAC3B,MAAM,eAAeiB,uBAAAA,oBAAoB,QAAQ,cAAc,GAAG;CAClE,MAAM,WAAWC,uBAAAA,SAAS,KAAK,YAAY;CAE3C,MAAM,QAAQ,SAAS,MAAM;CAC7B,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,4BAA4B;CAE9C,MAAM,mBAAmB,MAAM,YAAY;CAE3C,MAAM,YAAYf,eAAAA,YAAY,QAAQ,SAAS;CAI/C,MAAM,eAAe,iBAAiB,cAAc,WAHlC,QAAQ,UAAUA,eAAAA,YAAY,QAAQ,OAAO,IAAI,KAAA,CAGK;CACxE,MAAM,UAAU,aAAa;CAE7B,MAAM,cAAc,SAAS,MAAM,OAAO;CAC1C,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,6BAA6B;CAI/C,IAAI,YAAY,WAAW,MAAM,aAAa,YAC5C,MAAM,IAAI,MACR,uBAAuB,aAAa,WAAW,2BAA2B,YAAY,WAAW,GACnG;CAIF,MAAM,uBAAuB,IAAI,IAAI,YAAY,aAAa,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;CAC9F,MAAM,sBAAsB,IAAI,IAAI,aAAa,aAAa,KAAK,MAAM,EAAE,SAAS,CAAC,CAAC;CAEtF,IACE,qBAAqB,SAAS,oBAAoB,QAClD,CAAC,CAAC,GAAG,oBAAoB,EAAE,OAAO,MAAM,oBAAoB,IAAI,CAAC,CAAC,GAElE,MAAM,IAAI,MAAM,+DAA+D;CAIjF,IAAI,CAAC,oBAAoB,IAAI,MAAM,IAAI,EAAE,SAAS,CAAC,GACjD,MAAM,IAAI,MAAM,qDAAqD;CAIvE,MAAM,kBAAkB,YAAY,gBAAgB;CACpD,IAAI,CAAC,iBACH,MAAM,IAAI,MACR,gFACF;CAIF,MAAM,cAAc,gBAAgB,cAAc,SAAS,SAAS;CAEpE,IAAI,YAAY,cAAc,SAAS,MAAM,gBAAgB,SAAS,GACpE,MAAM,IAAI,MACR,+BAA+B,gBAAgB,SAAS,EAAE,2CAA2C,YAAY,cAAc,SAAS,EAAE,EAC5I;CAGF,IAAI,YAAY,aAAa,aAAa,UACxC,MAAM,IAAI,MAAM,6EAA6E;CAI/F,MAAM,iBAAiB,YAAY,cAAc,EAAE;CACnD,IAAI,CAAC,gBACH,MAAM,IAAI,MAAM,iDAAiD;CASnE,MAAM,aAA8BgB,oBAAAA,sBADb,KAAK,MAAMlB,QAAG,aAAa,gBAAgB,OAAO,CACF,EAAE,WAAW;CAGpF,MAAM,eAAeC,iBAAAA,KAAU,IAAI;CAInC,MAAM,eADiBa,eAAAA,SAAS,aAAa,aAAa,QAChB,EAAE,QAAQ,EAAE,OAAO;CAE7D,IAAI,QAAQ,YAAY,MACtB,QAAQ,MAAM,4CAA4C;CAI5D,MAAM,kBAAkB,MAAMK,aAAAA,iBAC5B,QACA,iBACA,sBACA,QAAQ,gBACR,QAAQ,WAAW,KACrB;CAEA,IAAI,CAAC,iBACH,MAAM,IAAI,MAAM,gDAAgD;CAIlE,MAAM,oBAAoB,iBAAiB,qBAAqB;CAChE,IAAI,CAAC,mBACH,MAAM,IAAI,MAAM,wCAAwC;CAI1D,MAAM,EAAE,eAAe,uBAAuB,QAAQ,YAAY;CAWlE,MAAM,MAAMC,YAAAA,SAAS,IAAI;CACzB,MAAM,gBAAgB,mBAAmB,gBACvC,iBACA,KAAA,GACA,KACA,iBACF;CAGA,MAAM,sBAAsB,YAAY,YAAY,EAAE,IAAI;CAC1D,qBAAqB,eAAe,WAAW,mBAAmB;CAGlE,MAAM,eAAqB,cAAc,0BAA0B,eAAe;CAGlF,MAAM,mBAAmB,mBAAmB,eAAe,YAAY;CAGvE,MAAM,gBAAgB,iBAAiB,IAAI,MAAM,IAAI,EAAE,SAAS,CAAC;CACjE,IAAI,CAAC,eACH,MAAM,IAAI,MAAM,6DAA6D;CAI/E,MAAM,0BAA0BL,oBAAAA,4BAA4B,aAAa;CACzE,MAAM,8BAA8BA,oBAAAA,4BAA4B,YAAY,kBAAkB;CAE9F,IACE,wBAAwB,WAAW,4BAA4B,UAC/D,wBAAwB,YAAY,4BAA4B,SAEhE,MAAM,IAAI,MAAM,wEAAwE;CAI1F,MAAM,kBAAkB,iBAAiB,aAAa,YAAY;CAIlE,IAAI,CADiB,gBAAgB,IAAI,MAAM,IAAI,EAAE,SAAS,CAC9C,GACd,MAAM,IAAI,MAAM,sCAAsC;CAIxD,IAAI,WAAW,eAAe,aAAa,YACzC,MAAM,IAAI,MACR,2BAA2B,WAAW,WAAW,0BAA0B,aAAa,YAC1F;CAIF,IAAI,iBAAiB,OAAO,aAAa,YACvC,MAAM,IAAI,MACR,gCAAgC,iBAAiB,KAAK,qCAAqC,aAAa,WAAW,SACrH;CAUF,MAAM,iBAAiBM,oBAAAA,cAHAC,oBAAAA,qBAHI,2BAA2B,kBAAkB,eAGX,GAAG,aAAa,KAAK,CAGhC,GAAG,YAAY,eAAe,UAAU;CAG1F,MAAM,eAAe,kBAAkB,WAAW,gBAAgB,YAAY;CAI9E,MAAM,EAAE,gBAAgB,wBAAwB,QAAQ,YAAY;CAwBpE,MAAM,iBAAiB,oBAAoB,WACzC,cAAc,GAAG,GACjB,gBACF,EAAE,WAAW,YAAY;CAGzB,IAAI,QAAQ,YAAY,MAAM;EAC5B,MAAM,WAAW,eAAe,WAAW,KAAA,GAAW,mBAAmB,KAAA,CAAS;EAClF,QAAQ,IAAI,SAAS,SAAS,CAAC;EAC/B,OAAO,EACL,eAAe,aAAa,SAAS,EACvC;CACF;CAGA,IAAI;CACJ,IAAI,oBAAoB,SAAS,MAAM,MAAM,IAAI,EAAE,SAAS,GAC1D,iBAAiB;MACZ;EACL,MAAM,oBAAoB,SAAS,YAAY,mBAAmB;EAClE,IAAI,CAAC,mBACH,MAAM,IAAI,MAAM,eAAe,oBAAoB,SAAS,EAAE,uBAAuB;EAEvF,iBAAiB,kBAAkB,YAAY;CACjD;CAGA,MAAM,SAASF,YAAAA,SAAS,oBAAoB,IAAO;CAInD,MAAMG,aAAAA,iBACJ,QACA,cALuB,eAAe,WAAW,QAAQ,mBAAmB,cAM7D,GACf,mBACA,QAAQ,WAAW,KACrB;CAGA,kBACE,cACA,SACA,WACA,cACA,cACA,gBACA,gBACF;CAGA,MAAM,qBAAqB,SAAS,MAAM,OAAO;CACjD,IAAI,oBAAoB;EACtB,mBAAmB,mBAAmB,YAAY;EAClD,SAAS,KAAK,YAAY;CAC5B;CAEA,IAAI,QAAQ,YAAY,MACtB,QAAQ,MAAM,6BAA6B,aAAa,SAAS,GAAG;CAGtE,OAAO,EACL,eAAe,aAAa,SAAS,EACvC;AACF"}
|
|
@@ -1,11 +1,11 @@
|
|
|
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 require_parallel = require("./parallel-
|
|
4
|
+
const require_common = require("./common-CnvAUC2b.cjs");
|
|
5
|
+
const require_busy = require("./busy-B_h0bNAJ.cjs");
|
|
6
|
+
const require_parallel = require("./parallel-szwYx-bi.cjs");
|
|
7
7
|
const require_frost_index = require("./frost/index.cjs");
|
|
8
|
-
const require_common$1 = require("./common-
|
|
8
|
+
const require_common$1 = require("./common-7-BOgaTt.cjs");
|
|
9
9
|
let _bcts_components = require("@bcts/components");
|
|
10
10
|
let _bcts_envelope = require("@bcts/envelope");
|
|
11
11
|
let node_fs = require("node:fs");
|
|
@@ -407,4 +407,4 @@ Object.defineProperty(exports, "round2_exports", {
|
|
|
407
407
|
}
|
|
408
408
|
});
|
|
409
409
|
|
|
410
|
-
//# sourceMappingURL=round2-
|
|
410
|
+
//# sourceMappingURL=round2-BHQKVJFo.cjs.map
|