@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
package/dist/dkg/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["DkgProposedParticipant","SealedRequest","CborDate","Envelope","SealedResponse","EnvelopeFunction","XIDDocument","XIDVerifySignature","ARID"],"sources":["../../src/dkg/group-invite.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG Group Invite structures.\n *\n * Port of dkg/group_invite.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { ARID } from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport { XIDDocument, XIDVerifySignature } from \"@bcts/xid\";\n\nimport { DkgProposedParticipant } from \"./proposed-participant.js\";\n\n/**\n * Result of a DKG invitation.\n *\n * Port of `enum DkgInvitationResult` from group_invite.rs lines 170-173.\n */\nexport type DkgInvitationResult = { type: \"accepted\" } | { type: \"declined\"; reason: string };\n\n/**\n * Helper to create an accepted result.\n */\nexport function accepted(): DkgInvitationResult {\n return { type: \"accepted\" };\n}\n\n/**\n * Helper to create a declined result.\n */\nexport function declined(reason: string): DkgInvitationResult {\n return { type: \"declined\", reason };\n}\n\n/**\n * DKG Invite - represents an invitation to participate in a DKG session.\n *\n * Port of `struct DkgInvite` from group_invite.rs lines 11-27.\n */\nexport class DkgInvite {\n private readonly _requestId: ARID;\n private readonly _sender: XIDDocument;\n private readonly _groupId: ARID;\n private readonly _date: Date;\n private readonly _validUntil: Date;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _orderedParticipants: DkgProposedParticipant[];\n\n private constructor(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n orderedParticipants: DkgProposedParticipant[],\n ) {\n this._requestId = requestId;\n this._sender = sender;\n this._groupId = groupId;\n this._date = date;\n this._validUntil = validUntil;\n this._minSigners = minSigners;\n this._charter = charter;\n this._orderedParticipants = orderedParticipants;\n }\n\n /**\n * Create a new DKG invite.\n *\n * Port of `DkgInvite::new()` from group_invite.rs lines 30-67.\n */\n static create(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n participants: string[],\n responseArids: ARID[],\n ): DkgInvite {\n if (participants.length !== responseArids.length) {\n throw new Error(\n `Number of participants (${participants.length}) does not match number of response ARIDs (${responseArids.length})`,\n );\n }\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n const orderedParticipants = participants.map((urString, i) =>\n DkgProposedParticipant.create(urString, responseArids[i]),\n );\n\n if (minSigners > orderedParticipants.length) {\n throw new Error(\"min_signers cannot exceed number of participants\");\n }\n\n // Sort by XID\n orderedParticipants.sort((a, b) => a.compareTo(b));\n\n return new DkgInvite(\n requestId,\n sender,\n groupId,\n date,\n validUntil,\n minSigners,\n charter,\n orderedParticipants,\n );\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n date(): Date {\n return this._date;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n participants(): DkgProposedParticipant[] {\n return this._orderedParticipants;\n }\n\n /**\n * Create a GSTP sealed request from this invite.\n *\n * Port of `DkgInvite::to_request()` from group_invite.rs lines 87-121.\n */\n toRequest(): SealedRequest {\n let request = SealedRequest.new(\"dkgInvite\", this.requestId(), this.sender())\n .withParameter(\"group\", this.groupId())\n .withParameter(\"minSigners\", BigInt(this.minSigners()))\n .withParameter(\"charter\", this.charter())\n .withDate(this.date())\n .withParameter(\"validUntil\", CborDate.fromDatetime(this.validUntil()));\n\n for (const participant of this.participants()) {\n const xidDocumentEnvelope = participant.xidDocumentEnvelope();\n const responseArid = participant.responseArid();\n const encryptionKey = participant.xidDocument().encryptionKey();\n\n if (encryptionKey === undefined) {\n throw new Error(\"Participant XID document has no encryption key\");\n }\n\n const encryptedResponseArid = Envelope.new(responseArid).encryptToRecipients([encryptionKey]);\n\n const participantEnvelope = xidDocumentEnvelope\n .wrap()\n .addAssertion(\"response_arid\", encryptedResponseArid);\n\n request = request.withParameter(\"participant\", participantEnvelope);\n }\n\n return request;\n }\n\n /**\n * Creates a signed but unencrypted envelope for auditing/preview.\n *\n * Port of `DkgInvite::to_unsealed_envelope()` from group_invite.rs lines 124-139.\n */\n toUnsealedEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n return request.toEnvelope(\n this.validUntil(),\n signerPrivateKeys,\n undefined, // No recipient = signed but not encrypted\n );\n }\n\n /**\n * Creates a sealed envelope encrypted to all participants.\n *\n * Port of `DkgInvite::to_envelope()` from group_invite.rs lines 142-166.\n */\n toEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n const recipients = this.participants().map((p) => p.xidDocument());\n\n return request.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n}\n\n/**\n * DKG Invitation - represents a received invitation from a participant's perspective.\n *\n * Port of `struct DkgInvitation` from group_invite.rs lines 175-186.\n */\nexport class DkgInvitation {\n private readonly _responseArid: ARID;\n private readonly _validUntil: Date;\n private readonly _sender: XIDDocument;\n private readonly _requestId: ARID;\n private readonly _peerContinuation: Envelope | undefined;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _groupId: ARID;\n\n private constructor(\n responseArid: ARID,\n validUntil: Date,\n sender: XIDDocument,\n requestId: ARID,\n peerContinuation: Envelope | undefined,\n minSigners: number,\n charter: string,\n groupId: ARID,\n ) {\n this._responseArid = responseArid;\n this._validUntil = validUntil;\n this._sender = sender;\n this._requestId = requestId;\n this._peerContinuation = peerContinuation;\n this._minSigners = minSigners;\n this._charter = charter;\n this._groupId = groupId;\n }\n\n responseArid(): ARID {\n return this._responseArid;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n peerContinuation(): Envelope | undefined {\n return this._peerContinuation;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n /**\n * Build a GSTP response for this invitation result.\n *\n * Port of `DkgInvitation::to_response()` from group_invite.rs lines 207-224.\n */\n toResponse(response: DkgInvitationResult, recipient: XIDDocument): SealedResponse {\n let base: SealedResponse;\n if (response.type === \"accepted\") {\n base = SealedResponse.newSuccess(this.requestId(), recipient);\n } else {\n base = SealedResponse.newFailure(this.requestId(), recipient).withError(response.reason);\n }\n\n return base.withPeerContinuation(this.peerContinuation());\n }\n\n /**\n * Create a signed/encrypted GSTP envelope containing the response for the coordinator.\n *\n * Port of `DkgInvitation::to_envelope()` from group_invite.rs lines 228-244.\n */\n toEnvelope(response: DkgInvitationResult, recipient: XIDDocument): Envelope {\n const responseObj = this.toResponse(response, recipient);\n const signerPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no signing keys\");\n }\n\n const recipients = [this.sender()];\n\n return responseObj.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n\n /**\n * Parse a DKG invitation from an invite envelope.\n *\n * Port of `DkgInvitation::from_invite()` from group_invite.rs lines 255-344.\n */\n static fromInvite(\n invite: Envelope,\n now: Date,\n expectedSender: XIDDocument | undefined,\n recipient: XIDDocument,\n ): DkgInvitation {\n const recipientPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (recipientPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no inception private keys\");\n }\n\n const sealedRequest = SealedRequest.tryFromEnvelope(\n invite,\n undefined,\n now,\n recipientPrivateKeys,\n );\n\n // Rust `group_invite.rs:275-279` uses `!=` on `XID`, which is the\n // derived `PartialEq` (byte-wise compare on the 32-byte ARID). TS\n // `!==` is reference identity — two distinct XID instances with\n // the same bytes would fail. Compare via hex equality instead.\n if (\n expectedSender !== undefined &&\n !sealedRequest.sender().xid().equals(expectedSender.xid())\n ) {\n throw new Error(\"Invite sender does not match expected sender\");\n }\n\n if (!sealedRequest.request().function().equals(EnvelopeFunction.fromString(\"dkgInvite\"))) {\n throw new Error(\"Unexpected invite function\");\n }\n\n const validUntil = sealedRequest.extractObjectForParameter<Date>(\"validUntil\");\n\n if (validUntil <= now) {\n throw new Error(\"Invitation expired\");\n }\n\n const recipientXid = recipient.xid();\n const minSigners = sealedRequest.extractObjectForParameter<number>(\"minSigners\");\n const charter = sealedRequest.extractObjectForParameter<string>(\"charter\");\n const groupId = sealedRequest.extractObjectForParameter<ARID>(\"group\");\n const participantObjects = sealedRequest.objectsForParameter(\"participant\");\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n if (minSigners > participantObjects.length) {\n throw new Error(\"min_signers exceeds participant count\");\n }\n\n for (const participant of participantObjects) {\n const xidDocumentEnvelope = participant.tryUnwrap();\n const xidDocument = XIDDocument.fromEnvelope(\n xidDocumentEnvelope,\n undefined,\n XIDVerifySignature.Inception,\n );\n\n // Rust `group_invite.rs` compares via `XID::PartialEq` (byte-wise).\n // TS reference identity would never match for two distinct\n // `XID` instances representing the same identity.\n if (!xidDocument.xid().equals(recipientXid)) {\n continue;\n }\n\n const encryptedResponseArid = participant.objectForPredicate(\"response_arid\");\n const responseAridEnvelope = encryptedResponseArid.decryptToRecipient(recipientPrivateKeys);\n const responseArid: ARID = responseAridEnvelope.extractSubject((cbor) =>\n ARID.fromTaggedCbor(cbor),\n );\n\n return new DkgInvitation(\n responseArid,\n validUntil,\n sealedRequest.sender(),\n sealedRequest.request().id(),\n sealedRequest.peerContinuation(),\n minSigners,\n charter,\n groupId,\n );\n }\n\n throw new Error(\"Recipient not found in invite\");\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["DkgProposedParticipant","SealedRequest","CborDate","Envelope","SealedResponse","EnvelopeFunction","XIDDocument","XIDVerifySignature","ARID"],"sources":["../../src/dkg/group-invite.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG Group Invite structures.\n *\n * Port of dkg/group_invite.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { ARID } from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport { XIDDocument, XIDVerifySignature } from \"@bcts/xid\";\n\nimport { DkgProposedParticipant } from \"./proposed-participant.js\";\n\n/**\n * Result of a DKG invitation.\n *\n * Port of `enum DkgInvitationResult` from group_invite.rs lines 170-173.\n */\nexport type DkgInvitationResult = { type: \"accepted\" } | { type: \"declined\"; reason: string };\n\n/**\n * Helper to create an accepted result.\n */\nexport function accepted(): DkgInvitationResult {\n return { type: \"accepted\" };\n}\n\n/**\n * Helper to create a declined result.\n */\nexport function declined(reason: string): DkgInvitationResult {\n return { type: \"declined\", reason };\n}\n\n/**\n * DKG Invite - represents an invitation to participate in a DKG session.\n *\n * Port of `struct DkgInvite` from group_invite.rs lines 11-27.\n */\nexport class DkgInvite {\n private readonly _requestId: ARID;\n private readonly _sender: XIDDocument;\n private readonly _groupId: ARID;\n private readonly _date: Date;\n private readonly _validUntil: Date;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _orderedParticipants: DkgProposedParticipant[];\n\n private constructor(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n orderedParticipants: DkgProposedParticipant[],\n ) {\n this._requestId = requestId;\n this._sender = sender;\n this._groupId = groupId;\n this._date = date;\n this._validUntil = validUntil;\n this._minSigners = minSigners;\n this._charter = charter;\n this._orderedParticipants = orderedParticipants;\n }\n\n /**\n * Create a new DKG invite.\n *\n * Port of `DkgInvite::new()` from group_invite.rs lines 30-67.\n */\n static create(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n participants: string[],\n responseArids: ARID[],\n ): DkgInvite {\n if (participants.length !== responseArids.length) {\n throw new Error(\n `Number of participants (${participants.length}) does not match number of response ARIDs (${responseArids.length})`,\n );\n }\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n const orderedParticipants = participants.map((urString, i) =>\n DkgProposedParticipant.create(urString, responseArids[i]),\n );\n\n if (minSigners > orderedParticipants.length) {\n throw new Error(\"min_signers cannot exceed number of participants\");\n }\n\n // Sort by XID\n orderedParticipants.sort((a, b) => a.compareTo(b));\n\n return new DkgInvite(\n requestId,\n sender,\n groupId,\n date,\n validUntil,\n minSigners,\n charter,\n orderedParticipants,\n );\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n date(): Date {\n return this._date;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n participants(): DkgProposedParticipant[] {\n return this._orderedParticipants;\n }\n\n /**\n * Create a GSTP sealed request from this invite.\n *\n * Port of `DkgInvite::to_request()` from group_invite.rs lines 87-121.\n */\n toRequest(): SealedRequest {\n let request = SealedRequest.new(\"dkgInvite\", this.requestId(), this.sender())\n .withParameter(\"group\", this.groupId())\n .withParameter(\"minSigners\", BigInt(this.minSigners()))\n .withParameter(\"charter\", this.charter())\n .withDate(this.date())\n .withParameter(\"validUntil\", CborDate.fromDatetime(this.validUntil()));\n\n for (const participant of this.participants()) {\n const xidDocumentEnvelope = participant.xidDocumentEnvelope();\n const responseArid = participant.responseArid();\n const encryptionKey = participant.xidDocument().encryptionKey();\n\n if (encryptionKey === undefined) {\n throw new Error(\"Participant XID document has no encryption key\");\n }\n\n const encryptedResponseArid = Envelope.new(responseArid).encryptToRecipients([encryptionKey]);\n\n const participantEnvelope = xidDocumentEnvelope\n .wrap()\n .addAssertion(\"response_arid\", encryptedResponseArid);\n\n request = request.withParameter(\"participant\", participantEnvelope);\n }\n\n return request;\n }\n\n /**\n * Creates a signed but unencrypted envelope for auditing/preview.\n *\n * Port of `DkgInvite::to_unsealed_envelope()` from group_invite.rs lines 124-139.\n */\n toUnsealedEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n return request.toEnvelope(\n this.validUntil(),\n signerPrivateKeys,\n undefined, // No recipient = signed but not encrypted\n );\n }\n\n /**\n * Creates a sealed envelope encrypted to all participants.\n *\n * Port of `DkgInvite::to_envelope()` from group_invite.rs lines 142-166.\n */\n toEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n const recipients = this.participants().map((p) => p.xidDocument());\n\n return request.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n}\n\n/**\n * DKG Invitation - represents a received invitation from a participant's perspective.\n *\n * Port of `struct DkgInvitation` from group_invite.rs lines 175-186.\n */\nexport class DkgInvitation {\n private readonly _responseArid: ARID;\n private readonly _validUntil: Date;\n private readonly _sender: XIDDocument;\n private readonly _requestId: ARID;\n private readonly _peerContinuation: Envelope | undefined;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _groupId: ARID;\n\n private constructor(\n responseArid: ARID,\n validUntil: Date,\n sender: XIDDocument,\n requestId: ARID,\n peerContinuation: Envelope | undefined,\n minSigners: number,\n charter: string,\n groupId: ARID,\n ) {\n this._responseArid = responseArid;\n this._validUntil = validUntil;\n this._sender = sender;\n this._requestId = requestId;\n this._peerContinuation = peerContinuation;\n this._minSigners = minSigners;\n this._charter = charter;\n this._groupId = groupId;\n }\n\n responseArid(): ARID {\n return this._responseArid;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n peerContinuation(): Envelope | undefined {\n return this._peerContinuation;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n /**\n * Build a GSTP response for this invitation result.\n *\n * Port of `DkgInvitation::to_response()` from group_invite.rs lines 207-224.\n */\n toResponse(response: DkgInvitationResult, recipient: XIDDocument): SealedResponse {\n let base: SealedResponse;\n if (response.type === \"accepted\") {\n base = SealedResponse.newSuccess(this.requestId(), recipient);\n } else {\n base = SealedResponse.newFailure(this.requestId(), recipient).withError(response.reason);\n }\n\n return base.withPeerContinuation(this.peerContinuation());\n }\n\n /**\n * Create a signed/encrypted GSTP envelope containing the response for the coordinator.\n *\n * Port of `DkgInvitation::to_envelope()` from group_invite.rs lines 228-244.\n */\n toEnvelope(response: DkgInvitationResult, recipient: XIDDocument): Envelope {\n const responseObj = this.toResponse(response, recipient);\n const signerPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no signing keys\");\n }\n\n const recipients = [this.sender()];\n\n return responseObj.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n\n /**\n * Parse a DKG invitation from an invite envelope.\n *\n * Port of `DkgInvitation::from_invite()` from group_invite.rs lines 255-344.\n */\n static fromInvite(\n invite: Envelope,\n now: Date,\n expectedSender: XIDDocument | undefined,\n recipient: XIDDocument,\n ): DkgInvitation {\n const recipientPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (recipientPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no inception private keys\");\n }\n\n const sealedRequest = SealedRequest.tryFromEnvelope(\n invite,\n undefined,\n now,\n recipientPrivateKeys,\n );\n\n // Rust `group_invite.rs:275-279` uses `!=` on `XID`, which is the\n // derived `PartialEq` (byte-wise compare on the 32-byte ARID). TS\n // `!==` is reference identity — two distinct XID instances with\n // the same bytes would fail. Compare via hex equality instead.\n if (\n expectedSender !== undefined &&\n !sealedRequest.sender().xid().equals(expectedSender.xid())\n ) {\n throw new Error(\"Invite sender does not match expected sender\");\n }\n\n if (!sealedRequest.request().function().equals(EnvelopeFunction.fromString(\"dkgInvite\"))) {\n throw new Error(\"Unexpected invite function\");\n }\n\n const validUntil = sealedRequest.extractObjectForParameter<Date>(\"validUntil\");\n\n if (validUntil <= now) {\n throw new Error(\"Invitation expired\");\n }\n\n const recipientXid = recipient.xid();\n const minSigners = sealedRequest.extractObjectForParameter<number>(\"minSigners\");\n const charter = sealedRequest.extractObjectForParameter<string>(\"charter\");\n const groupId = sealedRequest.extractObjectForParameter<ARID>(\"group\");\n const participantObjects = sealedRequest.objectsForParameter(\"participant\");\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n if (minSigners > participantObjects.length) {\n throw new Error(\"min_signers exceeds participant count\");\n }\n\n for (const participant of participantObjects) {\n const xidDocumentEnvelope = participant.tryUnwrap();\n const xidDocument = XIDDocument.fromEnvelope(\n xidDocumentEnvelope,\n undefined,\n XIDVerifySignature.Inception,\n );\n\n // Rust `group_invite.rs` compares via `XID::PartialEq` (byte-wise).\n // TS reference identity would never match for two distinct\n // `XID` instances representing the same identity.\n if (!xidDocument.xid().equals(recipientXid)) {\n continue;\n }\n\n const encryptedResponseArid = participant.objectForPredicate(\"response_arid\");\n const responseAridEnvelope = encryptedResponseArid.decryptToRecipient(recipientPrivateKeys);\n const responseArid: ARID = responseAridEnvelope.extractSubject((cbor) =>\n ARID.fromTaggedCbor(cbor),\n );\n\n return new DkgInvitation(\n responseArid,\n validUntil,\n sealedRequest.sender(),\n sealedRequest.request().id(),\n sealedRequest.peerContinuation(),\n minSigners,\n charter,\n groupId,\n );\n }\n\n throw new Error(\"Recipient not found in invite\");\n }\n}\n"],"mappings":"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"}
|
package/dist/dkg/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as declined, i as accepted, n as DkgInvitationResult, o as DkgProposedParticipant, r as DkgInvite, s as compareXidBytes, t as DkgInvitation } from "../index-
|
|
1
|
+
import { a as declined, i as accepted, n as DkgInvitationResult, o as DkgProposedParticipant, r as DkgInvite, s as compareXidBytes, t as DkgInvitation } from "../index-gkmZzEuD.cjs";
|
|
2
2
|
export { DkgInvitation, DkgInvitationResult, DkgInvite, DkgProposedParticipant, accepted, compareXidBytes, declined };
|
package/dist/dkg/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as declined, i as accepted, n as DkgInvitationResult, o as DkgProposedParticipant, r as DkgInvite, s as compareXidBytes, t as DkgInvitation } from "../index-
|
|
1
|
+
import { a as declined, i as accepted, n as DkgInvitationResult, o as DkgProposedParticipant, r as DkgInvite, s as compareXidBytes, t as DkgInvitation } from "../index-BaUVw4b1.mjs";
|
|
2
2
|
export { DkgInvitation, DkgInvitationResult, DkgInvite, DkgProposedParticipant, accepted, compareXidBytes, declined };
|
package/dist/dkg/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as compareXidBytes, t as DkgProposedParticipant } from "../proposed-participant-
|
|
1
|
+
import { n as compareXidBytes, t as DkgProposedParticipant } from "../proposed-participant-Detb823_.mjs";
|
|
2
2
|
import { ARID } from "@bcts/components";
|
|
3
3
|
import { CborDate } from "@bcts/dcbor";
|
|
4
4
|
import { Envelope, Function } from "@bcts/envelope";
|
package/dist/dkg/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["EnvelopeFunction"],"sources":["../../src/dkg/group-invite.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG Group Invite structures.\n *\n * Port of dkg/group_invite.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { ARID } from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport { XIDDocument, XIDVerifySignature } from \"@bcts/xid\";\n\nimport { DkgProposedParticipant } from \"./proposed-participant.js\";\n\n/**\n * Result of a DKG invitation.\n *\n * Port of `enum DkgInvitationResult` from group_invite.rs lines 170-173.\n */\nexport type DkgInvitationResult = { type: \"accepted\" } | { type: \"declined\"; reason: string };\n\n/**\n * Helper to create an accepted result.\n */\nexport function accepted(): DkgInvitationResult {\n return { type: \"accepted\" };\n}\n\n/**\n * Helper to create a declined result.\n */\nexport function declined(reason: string): DkgInvitationResult {\n return { type: \"declined\", reason };\n}\n\n/**\n * DKG Invite - represents an invitation to participate in a DKG session.\n *\n * Port of `struct DkgInvite` from group_invite.rs lines 11-27.\n */\nexport class DkgInvite {\n private readonly _requestId: ARID;\n private readonly _sender: XIDDocument;\n private readonly _groupId: ARID;\n private readonly _date: Date;\n private readonly _validUntil: Date;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _orderedParticipants: DkgProposedParticipant[];\n\n private constructor(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n orderedParticipants: DkgProposedParticipant[],\n ) {\n this._requestId = requestId;\n this._sender = sender;\n this._groupId = groupId;\n this._date = date;\n this._validUntil = validUntil;\n this._minSigners = minSigners;\n this._charter = charter;\n this._orderedParticipants = orderedParticipants;\n }\n\n /**\n * Create a new DKG invite.\n *\n * Port of `DkgInvite::new()` from group_invite.rs lines 30-67.\n */\n static create(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n participants: string[],\n responseArids: ARID[],\n ): DkgInvite {\n if (participants.length !== responseArids.length) {\n throw new Error(\n `Number of participants (${participants.length}) does not match number of response ARIDs (${responseArids.length})`,\n );\n }\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n const orderedParticipants = participants.map((urString, i) =>\n DkgProposedParticipant.create(urString, responseArids[i]),\n );\n\n if (minSigners > orderedParticipants.length) {\n throw new Error(\"min_signers cannot exceed number of participants\");\n }\n\n // Sort by XID\n orderedParticipants.sort((a, b) => a.compareTo(b));\n\n return new DkgInvite(\n requestId,\n sender,\n groupId,\n date,\n validUntil,\n minSigners,\n charter,\n orderedParticipants,\n );\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n date(): Date {\n return this._date;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n participants(): DkgProposedParticipant[] {\n return this._orderedParticipants;\n }\n\n /**\n * Create a GSTP sealed request from this invite.\n *\n * Port of `DkgInvite::to_request()` from group_invite.rs lines 87-121.\n */\n toRequest(): SealedRequest {\n let request = SealedRequest.new(\"dkgInvite\", this.requestId(), this.sender())\n .withParameter(\"group\", this.groupId())\n .withParameter(\"minSigners\", BigInt(this.minSigners()))\n .withParameter(\"charter\", this.charter())\n .withDate(this.date())\n .withParameter(\"validUntil\", CborDate.fromDatetime(this.validUntil()));\n\n for (const participant of this.participants()) {\n const xidDocumentEnvelope = participant.xidDocumentEnvelope();\n const responseArid = participant.responseArid();\n const encryptionKey = participant.xidDocument().encryptionKey();\n\n if (encryptionKey === undefined) {\n throw new Error(\"Participant XID document has no encryption key\");\n }\n\n const encryptedResponseArid = Envelope.new(responseArid).encryptToRecipients([encryptionKey]);\n\n const participantEnvelope = xidDocumentEnvelope\n .wrap()\n .addAssertion(\"response_arid\", encryptedResponseArid);\n\n request = request.withParameter(\"participant\", participantEnvelope);\n }\n\n return request;\n }\n\n /**\n * Creates a signed but unencrypted envelope for auditing/preview.\n *\n * Port of `DkgInvite::to_unsealed_envelope()` from group_invite.rs lines 124-139.\n */\n toUnsealedEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n return request.toEnvelope(\n this.validUntil(),\n signerPrivateKeys,\n undefined, // No recipient = signed but not encrypted\n );\n }\n\n /**\n * Creates a sealed envelope encrypted to all participants.\n *\n * Port of `DkgInvite::to_envelope()` from group_invite.rs lines 142-166.\n */\n toEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n const recipients = this.participants().map((p) => p.xidDocument());\n\n return request.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n}\n\n/**\n * DKG Invitation - represents a received invitation from a participant's perspective.\n *\n * Port of `struct DkgInvitation` from group_invite.rs lines 175-186.\n */\nexport class DkgInvitation {\n private readonly _responseArid: ARID;\n private readonly _validUntil: Date;\n private readonly _sender: XIDDocument;\n private readonly _requestId: ARID;\n private readonly _peerContinuation: Envelope | undefined;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _groupId: ARID;\n\n private constructor(\n responseArid: ARID,\n validUntil: Date,\n sender: XIDDocument,\n requestId: ARID,\n peerContinuation: Envelope | undefined,\n minSigners: number,\n charter: string,\n groupId: ARID,\n ) {\n this._responseArid = responseArid;\n this._validUntil = validUntil;\n this._sender = sender;\n this._requestId = requestId;\n this._peerContinuation = peerContinuation;\n this._minSigners = minSigners;\n this._charter = charter;\n this._groupId = groupId;\n }\n\n responseArid(): ARID {\n return this._responseArid;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n peerContinuation(): Envelope | undefined {\n return this._peerContinuation;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n /**\n * Build a GSTP response for this invitation result.\n *\n * Port of `DkgInvitation::to_response()` from group_invite.rs lines 207-224.\n */\n toResponse(response: DkgInvitationResult, recipient: XIDDocument): SealedResponse {\n let base: SealedResponse;\n if (response.type === \"accepted\") {\n base = SealedResponse.newSuccess(this.requestId(), recipient);\n } else {\n base = SealedResponse.newFailure(this.requestId(), recipient).withError(response.reason);\n }\n\n return base.withPeerContinuation(this.peerContinuation());\n }\n\n /**\n * Create a signed/encrypted GSTP envelope containing the response for the coordinator.\n *\n * Port of `DkgInvitation::to_envelope()` from group_invite.rs lines 228-244.\n */\n toEnvelope(response: DkgInvitationResult, recipient: XIDDocument): Envelope {\n const responseObj = this.toResponse(response, recipient);\n const signerPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no signing keys\");\n }\n\n const recipients = [this.sender()];\n\n return responseObj.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n\n /**\n * Parse a DKG invitation from an invite envelope.\n *\n * Port of `DkgInvitation::from_invite()` from group_invite.rs lines 255-344.\n */\n static fromInvite(\n invite: Envelope,\n now: Date,\n expectedSender: XIDDocument | undefined,\n recipient: XIDDocument,\n ): DkgInvitation {\n const recipientPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (recipientPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no inception private keys\");\n }\n\n const sealedRequest = SealedRequest.tryFromEnvelope(\n invite,\n undefined,\n now,\n recipientPrivateKeys,\n );\n\n // Rust `group_invite.rs:275-279` uses `!=` on `XID`, which is the\n // derived `PartialEq` (byte-wise compare on the 32-byte ARID). TS\n // `!==` is reference identity — two distinct XID instances with\n // the same bytes would fail. Compare via hex equality instead.\n if (\n expectedSender !== undefined &&\n !sealedRequest.sender().xid().equals(expectedSender.xid())\n ) {\n throw new Error(\"Invite sender does not match expected sender\");\n }\n\n if (!sealedRequest.request().function().equals(EnvelopeFunction.fromString(\"dkgInvite\"))) {\n throw new Error(\"Unexpected invite function\");\n }\n\n const validUntil = sealedRequest.extractObjectForParameter<Date>(\"validUntil\");\n\n if (validUntil <= now) {\n throw new Error(\"Invitation expired\");\n }\n\n const recipientXid = recipient.xid();\n const minSigners = sealedRequest.extractObjectForParameter<number>(\"minSigners\");\n const charter = sealedRequest.extractObjectForParameter<string>(\"charter\");\n const groupId = sealedRequest.extractObjectForParameter<ARID>(\"group\");\n const participantObjects = sealedRequest.objectsForParameter(\"participant\");\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n if (minSigners > participantObjects.length) {\n throw new Error(\"min_signers exceeds participant count\");\n }\n\n for (const participant of participantObjects) {\n const xidDocumentEnvelope = participant.tryUnwrap();\n const xidDocument = XIDDocument.fromEnvelope(\n xidDocumentEnvelope,\n undefined,\n XIDVerifySignature.Inception,\n );\n\n // Rust `group_invite.rs` compares via `XID::PartialEq` (byte-wise).\n // TS reference identity would never match for two distinct\n // `XID` instances representing the same identity.\n if (!xidDocument.xid().equals(recipientXid)) {\n continue;\n }\n\n const encryptedResponseArid = participant.objectForPredicate(\"response_arid\");\n const responseAridEnvelope = encryptedResponseArid.decryptToRecipient(recipientPrivateKeys);\n const responseArid: ARID = responseAridEnvelope.extractSubject((cbor) =>\n ARID.fromTaggedCbor(cbor),\n );\n\n return new DkgInvitation(\n responseArid,\n validUntil,\n sealedRequest.sender(),\n sealedRequest.request().id(),\n sealedRequest.peerContinuation(),\n minSigners,\n charter,\n groupId,\n );\n }\n\n throw new Error(\"Recipient not found in invite\");\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["EnvelopeFunction"],"sources":["../../src/dkg/group-invite.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG Group Invite structures.\n *\n * Port of dkg/group_invite.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { ARID } from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport { XIDDocument, XIDVerifySignature } from \"@bcts/xid\";\n\nimport { DkgProposedParticipant } from \"./proposed-participant.js\";\n\n/**\n * Result of a DKG invitation.\n *\n * Port of `enum DkgInvitationResult` from group_invite.rs lines 170-173.\n */\nexport type DkgInvitationResult = { type: \"accepted\" } | { type: \"declined\"; reason: string };\n\n/**\n * Helper to create an accepted result.\n */\nexport function accepted(): DkgInvitationResult {\n return { type: \"accepted\" };\n}\n\n/**\n * Helper to create a declined result.\n */\nexport function declined(reason: string): DkgInvitationResult {\n return { type: \"declined\", reason };\n}\n\n/**\n * DKG Invite - represents an invitation to participate in a DKG session.\n *\n * Port of `struct DkgInvite` from group_invite.rs lines 11-27.\n */\nexport class DkgInvite {\n private readonly _requestId: ARID;\n private readonly _sender: XIDDocument;\n private readonly _groupId: ARID;\n private readonly _date: Date;\n private readonly _validUntil: Date;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _orderedParticipants: DkgProposedParticipant[];\n\n private constructor(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n orderedParticipants: DkgProposedParticipant[],\n ) {\n this._requestId = requestId;\n this._sender = sender;\n this._groupId = groupId;\n this._date = date;\n this._validUntil = validUntil;\n this._minSigners = minSigners;\n this._charter = charter;\n this._orderedParticipants = orderedParticipants;\n }\n\n /**\n * Create a new DKG invite.\n *\n * Port of `DkgInvite::new()` from group_invite.rs lines 30-67.\n */\n static create(\n requestId: ARID,\n sender: XIDDocument,\n groupId: ARID,\n date: Date,\n validUntil: Date,\n minSigners: number,\n charter: string,\n participants: string[],\n responseArids: ARID[],\n ): DkgInvite {\n if (participants.length !== responseArids.length) {\n throw new Error(\n `Number of participants (${participants.length}) does not match number of response ARIDs (${responseArids.length})`,\n );\n }\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n const orderedParticipants = participants.map((urString, i) =>\n DkgProposedParticipant.create(urString, responseArids[i]),\n );\n\n if (minSigners > orderedParticipants.length) {\n throw new Error(\"min_signers cannot exceed number of participants\");\n }\n\n // Sort by XID\n orderedParticipants.sort((a, b) => a.compareTo(b));\n\n return new DkgInvite(\n requestId,\n sender,\n groupId,\n date,\n validUntil,\n minSigners,\n charter,\n orderedParticipants,\n );\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n date(): Date {\n return this._date;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n participants(): DkgProposedParticipant[] {\n return this._orderedParticipants;\n }\n\n /**\n * Create a GSTP sealed request from this invite.\n *\n * Port of `DkgInvite::to_request()` from group_invite.rs lines 87-121.\n */\n toRequest(): SealedRequest {\n let request = SealedRequest.new(\"dkgInvite\", this.requestId(), this.sender())\n .withParameter(\"group\", this.groupId())\n .withParameter(\"minSigners\", BigInt(this.minSigners()))\n .withParameter(\"charter\", this.charter())\n .withDate(this.date())\n .withParameter(\"validUntil\", CborDate.fromDatetime(this.validUntil()));\n\n for (const participant of this.participants()) {\n const xidDocumentEnvelope = participant.xidDocumentEnvelope();\n const responseArid = participant.responseArid();\n const encryptionKey = participant.xidDocument().encryptionKey();\n\n if (encryptionKey === undefined) {\n throw new Error(\"Participant XID document has no encryption key\");\n }\n\n const encryptedResponseArid = Envelope.new(responseArid).encryptToRecipients([encryptionKey]);\n\n const participantEnvelope = xidDocumentEnvelope\n .wrap()\n .addAssertion(\"response_arid\", encryptedResponseArid);\n\n request = request.withParameter(\"participant\", participantEnvelope);\n }\n\n return request;\n }\n\n /**\n * Creates a signed but unencrypted envelope for auditing/preview.\n *\n * Port of `DkgInvite::to_unsealed_envelope()` from group_invite.rs lines 124-139.\n */\n toUnsealedEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n return request.toEnvelope(\n this.validUntil(),\n signerPrivateKeys,\n undefined, // No recipient = signed but not encrypted\n );\n }\n\n /**\n * Creates a sealed envelope encrypted to all participants.\n *\n * Port of `DkgInvite::to_envelope()` from group_invite.rs lines 142-166.\n */\n toEnvelope(): Envelope {\n const request = this.toRequest();\n const sender = this.sender();\n const signerPrivateKeys = sender.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Sender XID document has no inception signing key\");\n }\n\n const recipients = this.participants().map((p) => p.xidDocument());\n\n return request.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n}\n\n/**\n * DKG Invitation - represents a received invitation from a participant's perspective.\n *\n * Port of `struct DkgInvitation` from group_invite.rs lines 175-186.\n */\nexport class DkgInvitation {\n private readonly _responseArid: ARID;\n private readonly _validUntil: Date;\n private readonly _sender: XIDDocument;\n private readonly _requestId: ARID;\n private readonly _peerContinuation: Envelope | undefined;\n private readonly _minSigners: number;\n private readonly _charter: string;\n private readonly _groupId: ARID;\n\n private constructor(\n responseArid: ARID,\n validUntil: Date,\n sender: XIDDocument,\n requestId: ARID,\n peerContinuation: Envelope | undefined,\n minSigners: number,\n charter: string,\n groupId: ARID,\n ) {\n this._responseArid = responseArid;\n this._validUntil = validUntil;\n this._sender = sender;\n this._requestId = requestId;\n this._peerContinuation = peerContinuation;\n this._minSigners = minSigners;\n this._charter = charter;\n this._groupId = groupId;\n }\n\n responseArid(): ARID {\n return this._responseArid;\n }\n\n validUntil(): Date {\n return this._validUntil;\n }\n\n sender(): XIDDocument {\n return this._sender;\n }\n\n requestId(): ARID {\n return this._requestId;\n }\n\n peerContinuation(): Envelope | undefined {\n return this._peerContinuation;\n }\n\n minSigners(): number {\n return this._minSigners;\n }\n\n charter(): string {\n return this._charter;\n }\n\n groupId(): ARID {\n return this._groupId;\n }\n\n /**\n * Build a GSTP response for this invitation result.\n *\n * Port of `DkgInvitation::to_response()` from group_invite.rs lines 207-224.\n */\n toResponse(response: DkgInvitationResult, recipient: XIDDocument): SealedResponse {\n let base: SealedResponse;\n if (response.type === \"accepted\") {\n base = SealedResponse.newSuccess(this.requestId(), recipient);\n } else {\n base = SealedResponse.newFailure(this.requestId(), recipient).withError(response.reason);\n }\n\n return base.withPeerContinuation(this.peerContinuation());\n }\n\n /**\n * Create a signed/encrypted GSTP envelope containing the response for the coordinator.\n *\n * Port of `DkgInvitation::to_envelope()` from group_invite.rs lines 228-244.\n */\n toEnvelope(response: DkgInvitationResult, recipient: XIDDocument): Envelope {\n const responseObj = this.toResponse(response, recipient);\n const signerPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no signing keys\");\n }\n\n const recipients = [this.sender()];\n\n return responseObj.toEnvelopeForRecipients(this.validUntil(), signerPrivateKeys, recipients);\n }\n\n /**\n * Parse a DKG invitation from an invite envelope.\n *\n * Port of `DkgInvitation::from_invite()` from group_invite.rs lines 255-344.\n */\n static fromInvite(\n invite: Envelope,\n now: Date,\n expectedSender: XIDDocument | undefined,\n recipient: XIDDocument,\n ): DkgInvitation {\n const recipientPrivateKeys = recipient.inceptionPrivateKeys();\n\n if (recipientPrivateKeys === undefined) {\n throw new Error(\"Recipient XID document has no inception private keys\");\n }\n\n const sealedRequest = SealedRequest.tryFromEnvelope(\n invite,\n undefined,\n now,\n recipientPrivateKeys,\n );\n\n // Rust `group_invite.rs:275-279` uses `!=` on `XID`, which is the\n // derived `PartialEq` (byte-wise compare on the 32-byte ARID). TS\n // `!==` is reference identity — two distinct XID instances with\n // the same bytes would fail. Compare via hex equality instead.\n if (\n expectedSender !== undefined &&\n !sealedRequest.sender().xid().equals(expectedSender.xid())\n ) {\n throw new Error(\"Invite sender does not match expected sender\");\n }\n\n if (!sealedRequest.request().function().equals(EnvelopeFunction.fromString(\"dkgInvite\"))) {\n throw new Error(\"Unexpected invite function\");\n }\n\n const validUntil = sealedRequest.extractObjectForParameter<Date>(\"validUntil\");\n\n if (validUntil <= now) {\n throw new Error(\"Invitation expired\");\n }\n\n const recipientXid = recipient.xid();\n const minSigners = sealedRequest.extractObjectForParameter<number>(\"minSigners\");\n const charter = sealedRequest.extractObjectForParameter<string>(\"charter\");\n const groupId = sealedRequest.extractObjectForParameter<ARID>(\"group\");\n const participantObjects = sealedRequest.objectsForParameter(\"participant\");\n\n if (minSigners < 2) {\n throw new Error(\"min_signers must be at least 2\");\n }\n\n if (minSigners > participantObjects.length) {\n throw new Error(\"min_signers exceeds participant count\");\n }\n\n for (const participant of participantObjects) {\n const xidDocumentEnvelope = participant.tryUnwrap();\n const xidDocument = XIDDocument.fromEnvelope(\n xidDocumentEnvelope,\n undefined,\n XIDVerifySignature.Inception,\n );\n\n // Rust `group_invite.rs` compares via `XID::PartialEq` (byte-wise).\n // TS reference identity would never match for two distinct\n // `XID` instances representing the same identity.\n if (!xidDocument.xid().equals(recipientXid)) {\n continue;\n }\n\n const encryptedResponseArid = participant.objectForPredicate(\"response_arid\");\n const responseAridEnvelope = encryptedResponseArid.decryptToRecipient(recipientPrivateKeys);\n const responseArid: ARID = responseAridEnvelope.extractSubject((cbor) =>\n ARID.fromTaggedCbor(cbor),\n );\n\n return new DkgInvitation(\n responseArid,\n validUntil,\n sealedRequest.sender(),\n sealedRequest.request().id(),\n sealedRequest.peerContinuation(),\n minSigners,\n charter,\n groupId,\n );\n }\n\n throw new Error(\"Recipient not found in invite\");\n }\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 { Registry, resolveRegistryPath } from "./registry/index.mjs";
|
|
4
|
-
import { c as parseAridUr, h as signingKeyFromVerifying, n as isVerbose } from "./common-
|
|
5
|
-
import { t as getWithIndicator } from "./busy-
|
|
4
|
+
import { c as parseAridUr, h as signingKeyFromVerifying, n as isVerbose } from "./common-Cf1UvJaP.mjs";
|
|
5
|
+
import { t as getWithIndicator } from "./busy-BlU8_pS2.mjs";
|
|
6
6
|
import { aggregateSignatures, createSigningPackage, deserializePublicKeyPackage, deserializeSignatureShare, deserializeSigningCommitments, hexToBytes, identifierFromU16, serializeSignature, serializeSignatureShare, serializeSigningCommitments } from "./frost/index.mjs";
|
|
7
|
-
import { n as signingStateDir, t as SignFinalizeContent } from "./common-
|
|
7
|
+
import { n as signingStateDir, t as SignFinalizeContent } from "./common-DNrD_-EI.mjs";
|
|
8
8
|
import { ARID, Signature, XID } from "@bcts/components";
|
|
9
9
|
import { Envelope } from "@bcts/envelope";
|
|
10
10
|
import { SealedEvent } from "@bcts/gstp";
|
|
@@ -386,4 +386,4 @@ async function finalize(client, options, cwd) {
|
|
|
386
386
|
//#endregion
|
|
387
387
|
export { finalize_exports as n, finalize as t };
|
|
388
388
|
|
|
389
|
-
//# sourceMappingURL=finalize-
|
|
389
|
+
//# sourceMappingURL=finalize-BpC0rz93.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finalize-CNTDj6aS.mjs","names":["serialized"],"sources":["../src/cmd/sign/participant/finalize.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant finalize command.\n *\n * Port of cmd/sign/participant/finalize.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, type Digest, Signature, type SigningPublicKey, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { SealedEvent } from \"@bcts/gstp\";\n\nimport {\n Registry,\n resolveRegistryPath,\n type GroupRecord,\n type OwnerRecord,\n} from \"../../../registry/index.js\";\nimport { getWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr, signingKeyFromVerifying } from \"../../dkg/common.js\";\nimport { signingStateDir, SignFinalizeContent } from \"../common.js\";\nimport {\n aggregateSignatures,\n createSigningPackage,\n deserializePublicKeyPackage,\n deserializeSignatureShare,\n deserializeSigningCommitments,\n identifierFromU16,\n hexToBytes,\n serializeSignature,\n serializeSignatureShare,\n serializeSigningCommitments,\n type FrostIdentifier,\n type FrostPublicKeyPackage,\n type Ed25519SignatureShare,\n type Ed25519SigningCommitments,\n type SerializedPublicKeyPackage,\n type SerializedSigningCommitments,\n} from \"../../../frost/index.js\";\nimport { isVerbose } from \"../../common.js\";\n\n/**\n * Options for the sign finalize command.\n */\nexport interface SignFinalizeOptions {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign finalize command.\n */\nexport interface SignFinalizeResult {\n signature: string;\n signedEnvelope: string;\n}\n\n/**\n * State from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/finalize.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n coordinator: XID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * State from share.json.\n *\n * Port of `struct ShareState` from cmd/sign/participant/finalize.rs.\n */\ninterface ShareState {\n finalizeArid: ARID;\n signatureShare: Ed25519SignatureShare;\n commitments: Map<string, Ed25519SigningCommitments>; // XID UR string -> commitments\n}\n\n/**\n * Load the receive state for a signing session.\n *\n * Searches for sign_receive.json in group-state directories.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadReceiveState(\n registryPath: string,\n sessionId: ARID,\n groupHint: ARID | undefined,\n): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Build list of group directories to search\n const groupDirs: [ARID, string][] = [];\n if (groupHint !== undefined) {\n groupDirs.push([groupHint, path.join(groupStateDir, groupHint.hex())]);\n } else {\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n const name = entry.name;\n // Check if it's a valid 64-char hex string (ARID)\n if (name.length === 64 && /^[0-9a-f]+$/i.test(name)) {\n const groupId = ARID.fromHex(name);\n groupDirs.push([groupId, path.join(groupStateDir, name)]);\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 const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in sign_receive.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\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.hex() !== groupId.hex()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n const coordinator = XID.fromURString(getStr(\"coordinator\"));\n\n const participantsVal = raw[\"participants\"];\n if (!Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\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(XID.fromURString(entry));\n }\n\n const minSignersVal = raw[\"min_signers\"];\n if (typeof minSignersVal !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n const minSigners = minSignersVal;\n\n const targetUr = getStr(\"target\");\n\n // Sort participants by XID byte order — mirrors Rust `XID::cmp`.\n // The earlier port used `urString().localeCompare(...)`, which\n // diverges from byte order for bytes ≥ 0x80 and is locale-aware,\n // producing a different signing-package order than Rust.\n participants.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n return {\n groupId,\n coordinator,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load the share state for a signing session.\n *\n * Port of `load_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadShareState(registryPath: string, groupId: ARID, sessionId: ARID): ShareState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const filePath = path.join(dir, \"share.json\");\n\n if (!fs.existsSync(filePath)) {\n throw new Error(\n `Signature share state not found at ${filePath}. Run \\`frost sign participant share\\` first.`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in share.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\n throw new Error(\n `Session ${sessionInState.urString()} in share.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const finalizeArid = parseAridUr(getStr(\"finalize_arid\"));\n\n const signatureShareHex = getStr(\"signature_share\");\n const signatureShare = deserializeSignatureShare(signatureShareHex);\n\n const commitmentsVal = raw[\"commitments\"];\n if (typeof commitmentsVal !== \"object\" || commitmentsVal === null) {\n throw new Error(\"Missing commitments map in share.json\");\n }\n\n const commitments = new Map<string, Ed25519SigningCommitments>();\n for (const [xidStr, value] of Object.entries(commitmentsVal as Record<string, unknown>)) {\n const serialized = value as SerializedSigningCommitments;\n const commits = deserializeSigningCommitments(serialized);\n commitments.set(xidStr, commits);\n }\n\n return { finalizeArid, signatureShare, commitments };\n}\n\n/**\n * Validate that session state is consistent with registry and owner.\n *\n * Port of `validate_session_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSessionState(\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n owner: OwnerRecord,\n): void {\n if (receiveState.coordinator.urString() !== groupRecord.coordinator().xid().urString()) {\n throw new Error(\"Coordinator in session state does not match registry\");\n }\n\n const ownerXidStr = owner.xid().urString();\n const isParticipant = receiveState.participants.some((p) => p.urString() === ownerXidStr);\n if (!isParticipant) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\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\n/**\n * Validate share state against receive state and registry.\n *\n * Port of `validate_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateShareState(\n shareState: ShareState,\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n): void {\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\n \"No listening ARID for signFinalize. Did you run `frost sign participant share`?\",\n );\n }\n\n if (shareState.finalizeArid.hex() !== listeningAtArid.hex()) {\n throw new Error(\n `Registry listening ARID (${listeningAtArid.urString()}) does not match persisted finalize ARID (${shareState.finalizeArid.urString()})`,\n );\n }\n\n // Check that commitments match session participants\n const commitParticipants = new Set(shareState.commitments.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (commitParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Commitments do not match session participants\");\n }\n for (const p of commitParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Commitments do not match session participants\");\n }\n }\n}\n\n/**\n * Validate the finalize event.\n *\n * Port of `validate_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateFinalizeEvent(\n sealedEvent: SealedEvent<Envelope>,\n sessionId: ARID,\n groupRecord: GroupRecord,\n): void {\n // Get the content envelope (which is the SignFinalizeContent envelope)\n const contentEnvelope = sealedEvent.content();\n\n // Validate the session predicate - extract ARID from the session assertion\n const sessionEnvelope = contentEnvelope.objectForPredicate(\"session\");\n if (sessionEnvelope === undefined) {\n throw new Error(\"Missing session in finalize event\");\n }\n const eventSession = ARID.fromTaggedCbor(sessionEnvelope.subject().tryLeaf());\n if (eventSession.hex() !== sessionId.hex()) {\n throw new Error(\n `Event session ${eventSession.urString()} does not match expected ${sessionId.urString()}`,\n );\n }\n\n const expectedCoordinator = groupRecord.coordinator().xid();\n if (sealedEvent.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected event sender: ${sealedEvent.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Validate signature shares from the finalize event.\n *\n * Port of `validate_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSignatureShares(\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n receiveState: ReceiveState,\n _shareState: ShareState,\n owner: OwnerRecord,\n): void {\n if (signatureSharesByXid.size < receiveState.minSigners) {\n throw new Error(\n `Finalize package contains ${signatureSharesByXid.size} signature shares but requires at least ${receiveState.minSigners}`,\n );\n }\n\n // Check that share participants match session participants\n const sharesParticipants = new Set(signatureSharesByXid.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (sharesParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n for (const p of sharesParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n }\n\n // Verify our own share matches\n const ownerXidStr = owner.xid().urString();\n const myShare = signatureSharesByXid.get(ownerXidStr);\n if (myShare === undefined) {\n throw new Error(\"Finalize package is missing this participant's signature share\");\n }\n\n // Compare shares (serialize both and compare hex strings)\n // Note: This assumes signature shares can be compared by their serialized form\n // The Rust code compares them directly via PartialEq\n}\n\n/**\n * Fetch and parse the finalize event from storage.\n *\n * Port of `fetch_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nasync function fetchFinalizeEvent(\n client: StorageClient,\n finalizeArid: ARID,\n timeout: number | undefined,\n owner: OwnerRecord,\n): Promise<SealedEvent<Envelope>> {\n if (isVerbose()) {\n console.error(\"Fetching finalize package from Hubert...\");\n }\n\n const finalizeEnvelope = await getWithIndicator(\n client,\n finalizeArid,\n \"Finalize package\",\n timeout,\n isVerbose(),\n );\n\n if (finalizeEnvelope === null || finalizeEnvelope === undefined) {\n throw new Error(\"Finalize package not found in Hubert storage\");\n }\n\n const signerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerKeys === undefined) {\n throw new Error(\"Owner XID document has no inception private keys\");\n }\n\n // Parse as SealedEvent<Envelope> - the content is the SignFinalizeContent envelope\n const sealedEvent = SealedEvent.tryFromEnvelope<Envelope>(\n finalizeEnvelope,\n undefined, // No expected ID for events\n undefined, // No date validation needed\n signerKeys,\n (env: Envelope) => {\n // Validate it's a SignFinalizeContent envelope (has unit subject and type \"signFinalize\")\n SignFinalizeContent.fromEnvelope(env);\n return env;\n },\n );\n\n return sealedEvent;\n}\n\n/**\n * Parse signature shares from the finalize event.\n *\n * Port of `parse_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction parseSignatureShares(event: SealedEvent<Envelope>): Map<string, Ed25519SignatureShare> {\n const contentEnvelope = event.content();\n\n const shares = new Map<string, Ed25519SignatureShare>();\n const entries = contentEnvelope.objectsForPredicate(\"signature_share\");\n\n for (const entry of entries) {\n // Extract XID from subject\n const xid = XID.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract share hex string from \"share\" predicate\n const shareEnvelope = entry.objectForPredicate(\"share\");\n if (shareEnvelope === undefined) {\n throw new Error(\"Missing share in signature_share entry\");\n }\n const shareJson = shareEnvelope.extractString();\n const share = deserializeSignatureShare(shareJson);\n\n const xidStr = xid.urString();\n if (shares.has(xidStr)) {\n throw new Error(`Duplicate signature share for participant ${xidStr}`);\n }\n shares.set(xidStr, share);\n }\n\n if (shares.size === 0) {\n throw new Error(\"Finalize package contains no signature shares\");\n }\n\n return shares;\n}\n\n/**\n * Build a mapping from XID to FROST identifier.\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/finalize.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 xid = participants[i];\n const identifier = identifierFromU16(i + 1);\n map.set(xid.urString(), identifier);\n }\n return map;\n}\n\n/**\n * Convert commitments from XID-keyed to Identifier-keyed map.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/participant/finalize.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 [xidStr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Convert signature shares from XID-keyed to Identifier-keyed map.\n *\n * Port of `signature_shares_with_identifiers()` from cmd/sign/participant/finalize.rs.\n */\nfunction signatureSharesWithIdentifiers(\n shares: Map<string, Ed25519SignatureShare>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SignatureShare> {\n const mapped = new Map<FrostIdentifier, Ed25519SignatureShare>();\n for (const [xidStr, share] of shares) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, share);\n }\n return mapped;\n}\n\n/**\n * Result of loading a public key package.\n */\ninterface LoadedPublicKeyPackage {\n package: FrostPublicKeyPackage;\n verifyingKeyHex: string;\n}\n\n/**\n * Load the public key package for a group.\n *\n * Port of `load_public_key_package()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadPublicKeyPackage(registryPath: string, groupId: ARID): LoadedPublicKeyPackage {\n const base = path.dirname(registryPath);\n\n // Try direct path first\n const directPath = path.join(base, \"group-state\", groupId.hex(), \"public_key_package.json\");\n if (fs.existsSync(directPath)) {\n const raw = JSON.parse(fs.readFileSync(directPath, \"utf-8\")) as SerializedPublicKeyPackage;\n return {\n package: deserializePublicKeyPackage(raw),\n verifyingKeyHex: raw.verifyingKey,\n };\n }\n\n // Fallback to collected_finalize.json (coordinator)\n const collectedPath = path.join(base, \"group-state\", groupId.hex(), \"collected_finalize.json\");\n if (fs.existsSync(collectedPath)) {\n const raw = JSON.parse(fs.readFileSync(collectedPath, \"utf-8\")) as Record<string, unknown>;\n const firstEntry = Object.values(raw)[0] as Record<string, unknown> | undefined;\n if (firstEntry === undefined) {\n throw new Error(\"collected_finalize.json is empty\");\n }\n const publicKeyValue = firstEntry[\"public_key_package\"] as\n | SerializedPublicKeyPackage\n | undefined;\n if (publicKeyValue === undefined) {\n throw new Error(\"public_key_package missing in collected_finalize.json\");\n }\n return {\n package: deserializePublicKeyPackage(publicKeyValue),\n verifyingKeyHex: publicKeyValue.verifyingKey,\n };\n }\n\n throw new Error(\n `Public key package not found for group ${groupId.urString()}; run finalize respond/collect first`,\n );\n}\n\n/**\n * Aggregate signature shares and verify the result.\n *\n * Port of `aggregate_and_verify_signature()` from cmd/sign/participant/finalize.rs.\n */\nfunction aggregateAndVerifySignature(\n registryPath: string,\n groupId: ARID,\n participants: XID[],\n commitments: Map<string, Ed25519SigningCommitments>,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n targetEnvelope: Envelope,\n targetDigest: Digest,\n): [Signature, Envelope, SigningPublicKey] {\n const xidToIdentifier = xidIdentifierMap(participants);\n const signingCommitments = commitmentsWithIdentifiers(commitments, xidToIdentifier);\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n const signatureSharesByIdentifier = signatureSharesWithIdentifiers(\n signatureSharesByXid,\n xidToIdentifier,\n );\n\n const { package: publicKeyPackage, verifyingKeyHex } = loadPublicKeyPackage(\n registryPath,\n groupId,\n );\n\n // Get verifying key from public key package\n const verifyingKeyBytes = hexToBytes(verifyingKeyHex);\n const verifyingKey = signingKeyFromVerifying(verifyingKeyBytes) as SigningPublicKey;\n\n // Aggregate the signature shares\n const aggregatedSignature = aggregateSignatures(\n signingPackage,\n signatureSharesByIdentifier,\n publicKeyPackage,\n );\n\n // Serialize the aggregated signature\n const sigBytes = serializeSignature(aggregatedSignature);\n if (sigBytes.length !== 64) {\n throw new Error(\"Aggregated signature is not 64 bytes\");\n }\n const finalSignature = Signature.ed25519FromData(sigBytes);\n\n // Verify signature against target digest\n if (!verifyingKey.verify(finalSignature, targetDigest.data())) {\n throw new Error(\"Aggregated signature failed verification against target digest\");\n }\n\n // Create signed envelope\n const signedEnvelope = targetEnvelope.addAssertion(\"signed\", finalSignature);\n\n // Verify signature on envelope\n signedEnvelope.verifySignatureFrom(verifyingKey);\n\n return [finalSignature, signedEnvelope, verifyingKey];\n}\n\n/**\n * Update the registry verifying key if needed.\n *\n * Port of `update_registry_verifying_key()` from cmd/sign/participant/finalize.rs.\n */\nfunction updateRegistryVerifyingKey(\n registry: Registry,\n registryPath: string,\n groupId: ARID,\n verifyingKey: SigningPublicKey,\n groupRecord: GroupRecord,\n): void {\n const existing = groupRecord.verifyingKey();\n if (existing !== undefined) {\n if (existing.urString() !== verifyingKey.urString()) {\n throw new Error(\"Registry verifying key does not match finalize package\");\n }\n } else {\n const mutableGroup = registry.group(groupId);\n if (mutableGroup === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n mutableGroup.setVerifyingKey(verifyingKey);\n registry.save(registryPath);\n }\n}\n\n/**\n * Persist the final state to disk.\n *\n * Port of `persist_final_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction persistFinalState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n signature: Signature,\n signedEnvelope: Envelope,\n signatureShares: Map<string, Ed25519SignatureShare>,\n shareState: ShareState,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n const finalPath = path.join(dir, \"final.json\");\n\n // Load existing state if present\n let root: Record<string, unknown> = {};\n if (fs.existsSync(finalPath)) {\n root = JSON.parse(fs.readFileSync(finalPath, \"utf-8\")) as Record<string, unknown>;\n }\n\n // Build shares JSON\n const sharesJson: Record<string, string> = {};\n for (const [xidStr, share] of signatureShares) {\n sharesJson[xidStr] = serializeSignatureShare(share);\n }\n\n // Build commitments JSON\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidStr, commits] of shareState.commitments) {\n commitmentsJson[xidStr] = serializeSigningCommitments(commits);\n }\n\n root[\"group\"] = groupId.urString();\n root[\"session\"] = sessionId.urString();\n root[\"signature\"] = signature.urString();\n root[\"signature_shares\"] = sharesJson;\n root[\"commitments\"] = commitmentsJson;\n root[\"finalize_arid\"] = shareState.finalizeArid.urString();\n root[\"signed_target\"] = signedEnvelope.urString();\n\n fs.writeFileSync(finalPath, JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant finalize command.\n *\n * Receives the finalize event with aggregated signature.\n *\n * Port of `finalize()` from cmd/sign/participant/finalize.rs.\n */\nexport async function finalize(\n client: StorageClient,\n options: SignFinalizeOptions,\n cwd: string,\n): Promise<SignFinalizeResult> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint =\n options.groupId !== undefined && options.groupId !== \"\"\n ? parseAridUr(options.groupId)\n : undefined;\n\n // Load and validate session state\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n const groupRecord = registry.group(groupId);\n\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n validateSessionState(receiveState, groupRecord, owner);\n\n const shareState = loadShareState(registryPath, groupId, sessionId);\n validateShareState(shareState, receiveState, groupRecord);\n\n // Fetch finalize event\n const sealedEvent = await fetchFinalizeEvent(\n client,\n shareState.finalizeArid,\n options.timeoutSeconds,\n owner,\n );\n\n // Validate event\n validateFinalizeEvent(sealedEvent, sessionId, groupRecord);\n\n // Extract and validate signature shares\n const signatureSharesByXid = parseSignatureShares(sealedEvent);\n validateSignatureShares(signatureSharesByXid, receiveState, shareState, owner);\n\n // Load target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest = targetEnvelope.subject().digest();\n\n // Aggregate signature\n const [finalSignature, signedEnvelope, verifyingKey] = aggregateAndVerifySignature(\n registryPath,\n groupId,\n receiveState.participants,\n shareState.commitments,\n signatureSharesByXid,\n targetEnvelope,\n targetDigest,\n );\n\n // Update registry verifying key if needed\n updateRegistryVerifyingKey(registry, registryPath, groupId, verifyingKey, groupRecord);\n\n // Persist final state\n persistFinalState(\n registryPath,\n groupId,\n sessionId,\n finalSignature,\n signedEnvelope,\n signatureSharesByXid,\n shareState,\n );\n\n // Clear listening ARID\n const mutableGroupRecord = registry.group(groupId);\n if (mutableGroupRecord !== undefined) {\n mutableGroupRecord.clearListeningAtArid();\n registry.save(registryPath);\n }\n\n const signatureStr = finalSignature.urString();\n const signedEnvelopeStr = signedEnvelope.urString();\n\n if (options.verbose === true) {\n console.log(signatureStr);\n console.log(signedEnvelopeStr);\n }\n\n return {\n signature: signatureStr,\n signedEnvelope: signedEnvelopeStr,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"finalize-BpC0rz93.mjs","names":["serialized"],"sources":["../src/cmd/sign/participant/finalize.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant finalize command.\n *\n * Port of cmd/sign/participant/finalize.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, type Digest, Signature, type SigningPublicKey, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { SealedEvent } from \"@bcts/gstp\";\n\nimport {\n Registry,\n resolveRegistryPath,\n type GroupRecord,\n type OwnerRecord,\n} from \"../../../registry/index.js\";\nimport { getWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr, signingKeyFromVerifying } from \"../../dkg/common.js\";\nimport { signingStateDir, SignFinalizeContent } from \"../common.js\";\nimport {\n aggregateSignatures,\n createSigningPackage,\n deserializePublicKeyPackage,\n deserializeSignatureShare,\n deserializeSigningCommitments,\n identifierFromU16,\n hexToBytes,\n serializeSignature,\n serializeSignatureShare,\n serializeSigningCommitments,\n type FrostIdentifier,\n type FrostPublicKeyPackage,\n type Ed25519SignatureShare,\n type Ed25519SigningCommitments,\n type SerializedPublicKeyPackage,\n type SerializedSigningCommitments,\n} from \"../../../frost/index.js\";\nimport { isVerbose } from \"../../common.js\";\n\n/**\n * Options for the sign finalize command.\n */\nexport interface SignFinalizeOptions {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign finalize command.\n */\nexport interface SignFinalizeResult {\n signature: string;\n signedEnvelope: string;\n}\n\n/**\n * State from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/finalize.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n coordinator: XID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * State from share.json.\n *\n * Port of `struct ShareState` from cmd/sign/participant/finalize.rs.\n */\ninterface ShareState {\n finalizeArid: ARID;\n signatureShare: Ed25519SignatureShare;\n commitments: Map<string, Ed25519SigningCommitments>; // XID UR string -> commitments\n}\n\n/**\n * Load the receive state for a signing session.\n *\n * Searches for sign_receive.json in group-state directories.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadReceiveState(\n registryPath: string,\n sessionId: ARID,\n groupHint: ARID | undefined,\n): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Build list of group directories to search\n const groupDirs: [ARID, string][] = [];\n if (groupHint !== undefined) {\n groupDirs.push([groupHint, path.join(groupStateDir, groupHint.hex())]);\n } else {\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n const name = entry.name;\n // Check if it's a valid 64-char hex string (ARID)\n if (name.length === 64 && /^[0-9a-f]+$/i.test(name)) {\n const groupId = ARID.fromHex(name);\n groupDirs.push([groupId, path.join(groupStateDir, name)]);\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 const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in sign_receive.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\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.hex() !== groupId.hex()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n const coordinator = XID.fromURString(getStr(\"coordinator\"));\n\n const participantsVal = raw[\"participants\"];\n if (!Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\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(XID.fromURString(entry));\n }\n\n const minSignersVal = raw[\"min_signers\"];\n if (typeof minSignersVal !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n const minSigners = minSignersVal;\n\n const targetUr = getStr(\"target\");\n\n // Sort participants by XID byte order — mirrors Rust `XID::cmp`.\n // The earlier port used `urString().localeCompare(...)`, which\n // diverges from byte order for bytes ≥ 0x80 and is locale-aware,\n // producing a different signing-package order than Rust.\n participants.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n return {\n groupId,\n coordinator,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load the share state for a signing session.\n *\n * Port of `load_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadShareState(registryPath: string, groupId: ARID, sessionId: ARID): ShareState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const filePath = path.join(dir, \"share.json\");\n\n if (!fs.existsSync(filePath)) {\n throw new Error(\n `Signature share state not found at ${filePath}. Run \\`frost sign participant share\\` first.`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in share.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\n throw new Error(\n `Session ${sessionInState.urString()} in share.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const finalizeArid = parseAridUr(getStr(\"finalize_arid\"));\n\n const signatureShareHex = getStr(\"signature_share\");\n const signatureShare = deserializeSignatureShare(signatureShareHex);\n\n const commitmentsVal = raw[\"commitments\"];\n if (typeof commitmentsVal !== \"object\" || commitmentsVal === null) {\n throw new Error(\"Missing commitments map in share.json\");\n }\n\n const commitments = new Map<string, Ed25519SigningCommitments>();\n for (const [xidStr, value] of Object.entries(commitmentsVal as Record<string, unknown>)) {\n const serialized = value as SerializedSigningCommitments;\n const commits = deserializeSigningCommitments(serialized);\n commitments.set(xidStr, commits);\n }\n\n return { finalizeArid, signatureShare, commitments };\n}\n\n/**\n * Validate that session state is consistent with registry and owner.\n *\n * Port of `validate_session_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSessionState(\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n owner: OwnerRecord,\n): void {\n if (receiveState.coordinator.urString() !== groupRecord.coordinator().xid().urString()) {\n throw new Error(\"Coordinator in session state does not match registry\");\n }\n\n const ownerXidStr = owner.xid().urString();\n const isParticipant = receiveState.participants.some((p) => p.urString() === ownerXidStr);\n if (!isParticipant) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\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\n/**\n * Validate share state against receive state and registry.\n *\n * Port of `validate_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateShareState(\n shareState: ShareState,\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n): void {\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\n \"No listening ARID for signFinalize. Did you run `frost sign participant share`?\",\n );\n }\n\n if (shareState.finalizeArid.hex() !== listeningAtArid.hex()) {\n throw new Error(\n `Registry listening ARID (${listeningAtArid.urString()}) does not match persisted finalize ARID (${shareState.finalizeArid.urString()})`,\n );\n }\n\n // Check that commitments match session participants\n const commitParticipants = new Set(shareState.commitments.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (commitParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Commitments do not match session participants\");\n }\n for (const p of commitParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Commitments do not match session participants\");\n }\n }\n}\n\n/**\n * Validate the finalize event.\n *\n * Port of `validate_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateFinalizeEvent(\n sealedEvent: SealedEvent<Envelope>,\n sessionId: ARID,\n groupRecord: GroupRecord,\n): void {\n // Get the content envelope (which is the SignFinalizeContent envelope)\n const contentEnvelope = sealedEvent.content();\n\n // Validate the session predicate - extract ARID from the session assertion\n const sessionEnvelope = contentEnvelope.objectForPredicate(\"session\");\n if (sessionEnvelope === undefined) {\n throw new Error(\"Missing session in finalize event\");\n }\n const eventSession = ARID.fromTaggedCbor(sessionEnvelope.subject().tryLeaf());\n if (eventSession.hex() !== sessionId.hex()) {\n throw new Error(\n `Event session ${eventSession.urString()} does not match expected ${sessionId.urString()}`,\n );\n }\n\n const expectedCoordinator = groupRecord.coordinator().xid();\n if (sealedEvent.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected event sender: ${sealedEvent.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Validate signature shares from the finalize event.\n *\n * Port of `validate_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSignatureShares(\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n receiveState: ReceiveState,\n _shareState: ShareState,\n owner: OwnerRecord,\n): void {\n if (signatureSharesByXid.size < receiveState.minSigners) {\n throw new Error(\n `Finalize package contains ${signatureSharesByXid.size} signature shares but requires at least ${receiveState.minSigners}`,\n );\n }\n\n // Check that share participants match session participants\n const sharesParticipants = new Set(signatureSharesByXid.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (sharesParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n for (const p of sharesParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n }\n\n // Verify our own share matches\n const ownerXidStr = owner.xid().urString();\n const myShare = signatureSharesByXid.get(ownerXidStr);\n if (myShare === undefined) {\n throw new Error(\"Finalize package is missing this participant's signature share\");\n }\n\n // Compare shares (serialize both and compare hex strings)\n // Note: This assumes signature shares can be compared by their serialized form\n // The Rust code compares them directly via PartialEq\n}\n\n/**\n * Fetch and parse the finalize event from storage.\n *\n * Port of `fetch_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nasync function fetchFinalizeEvent(\n client: StorageClient,\n finalizeArid: ARID,\n timeout: number | undefined,\n owner: OwnerRecord,\n): Promise<SealedEvent<Envelope>> {\n if (isVerbose()) {\n console.error(\"Fetching finalize package from Hubert...\");\n }\n\n const finalizeEnvelope = await getWithIndicator(\n client,\n finalizeArid,\n \"Finalize package\",\n timeout,\n isVerbose(),\n );\n\n if (finalizeEnvelope === null || finalizeEnvelope === undefined) {\n throw new Error(\"Finalize package not found in Hubert storage\");\n }\n\n const signerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerKeys === undefined) {\n throw new Error(\"Owner XID document has no inception private keys\");\n }\n\n // Parse as SealedEvent<Envelope> - the content is the SignFinalizeContent envelope\n const sealedEvent = SealedEvent.tryFromEnvelope<Envelope>(\n finalizeEnvelope,\n undefined, // No expected ID for events\n undefined, // No date validation needed\n signerKeys,\n (env: Envelope) => {\n // Validate it's a SignFinalizeContent envelope (has unit subject and type \"signFinalize\")\n SignFinalizeContent.fromEnvelope(env);\n return env;\n },\n );\n\n return sealedEvent;\n}\n\n/**\n * Parse signature shares from the finalize event.\n *\n * Port of `parse_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction parseSignatureShares(event: SealedEvent<Envelope>): Map<string, Ed25519SignatureShare> {\n const contentEnvelope = event.content();\n\n const shares = new Map<string, Ed25519SignatureShare>();\n const entries = contentEnvelope.objectsForPredicate(\"signature_share\");\n\n for (const entry of entries) {\n // Extract XID from subject\n const xid = XID.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract share hex string from \"share\" predicate\n const shareEnvelope = entry.objectForPredicate(\"share\");\n if (shareEnvelope === undefined) {\n throw new Error(\"Missing share in signature_share entry\");\n }\n const shareJson = shareEnvelope.extractString();\n const share = deserializeSignatureShare(shareJson);\n\n const xidStr = xid.urString();\n if (shares.has(xidStr)) {\n throw new Error(`Duplicate signature share for participant ${xidStr}`);\n }\n shares.set(xidStr, share);\n }\n\n if (shares.size === 0) {\n throw new Error(\"Finalize package contains no signature shares\");\n }\n\n return shares;\n}\n\n/**\n * Build a mapping from XID to FROST identifier.\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/finalize.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 xid = participants[i];\n const identifier = identifierFromU16(i + 1);\n map.set(xid.urString(), identifier);\n }\n return map;\n}\n\n/**\n * Convert commitments from XID-keyed to Identifier-keyed map.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/participant/finalize.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 [xidStr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Convert signature shares from XID-keyed to Identifier-keyed map.\n *\n * Port of `signature_shares_with_identifiers()` from cmd/sign/participant/finalize.rs.\n */\nfunction signatureSharesWithIdentifiers(\n shares: Map<string, Ed25519SignatureShare>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SignatureShare> {\n const mapped = new Map<FrostIdentifier, Ed25519SignatureShare>();\n for (const [xidStr, share] of shares) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, share);\n }\n return mapped;\n}\n\n/**\n * Result of loading a public key package.\n */\ninterface LoadedPublicKeyPackage {\n package: FrostPublicKeyPackage;\n verifyingKeyHex: string;\n}\n\n/**\n * Load the public key package for a group.\n *\n * Port of `load_public_key_package()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadPublicKeyPackage(registryPath: string, groupId: ARID): LoadedPublicKeyPackage {\n const base = path.dirname(registryPath);\n\n // Try direct path first\n const directPath = path.join(base, \"group-state\", groupId.hex(), \"public_key_package.json\");\n if (fs.existsSync(directPath)) {\n const raw = JSON.parse(fs.readFileSync(directPath, \"utf-8\")) as SerializedPublicKeyPackage;\n return {\n package: deserializePublicKeyPackage(raw),\n verifyingKeyHex: raw.verifyingKey,\n };\n }\n\n // Fallback to collected_finalize.json (coordinator)\n const collectedPath = path.join(base, \"group-state\", groupId.hex(), \"collected_finalize.json\");\n if (fs.existsSync(collectedPath)) {\n const raw = JSON.parse(fs.readFileSync(collectedPath, \"utf-8\")) as Record<string, unknown>;\n const firstEntry = Object.values(raw)[0] as Record<string, unknown> | undefined;\n if (firstEntry === undefined) {\n throw new Error(\"collected_finalize.json is empty\");\n }\n const publicKeyValue = firstEntry[\"public_key_package\"] as\n | SerializedPublicKeyPackage\n | undefined;\n if (publicKeyValue === undefined) {\n throw new Error(\"public_key_package missing in collected_finalize.json\");\n }\n return {\n package: deserializePublicKeyPackage(publicKeyValue),\n verifyingKeyHex: publicKeyValue.verifyingKey,\n };\n }\n\n throw new Error(\n `Public key package not found for group ${groupId.urString()}; run finalize respond/collect first`,\n );\n}\n\n/**\n * Aggregate signature shares and verify the result.\n *\n * Port of `aggregate_and_verify_signature()` from cmd/sign/participant/finalize.rs.\n */\nfunction aggregateAndVerifySignature(\n registryPath: string,\n groupId: ARID,\n participants: XID[],\n commitments: Map<string, Ed25519SigningCommitments>,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n targetEnvelope: Envelope,\n targetDigest: Digest,\n): [Signature, Envelope, SigningPublicKey] {\n const xidToIdentifier = xidIdentifierMap(participants);\n const signingCommitments = commitmentsWithIdentifiers(commitments, xidToIdentifier);\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n const signatureSharesByIdentifier = signatureSharesWithIdentifiers(\n signatureSharesByXid,\n xidToIdentifier,\n );\n\n const { package: publicKeyPackage, verifyingKeyHex } = loadPublicKeyPackage(\n registryPath,\n groupId,\n );\n\n // Get verifying key from public key package\n const verifyingKeyBytes = hexToBytes(verifyingKeyHex);\n const verifyingKey = signingKeyFromVerifying(verifyingKeyBytes) as SigningPublicKey;\n\n // Aggregate the signature shares\n const aggregatedSignature = aggregateSignatures(\n signingPackage,\n signatureSharesByIdentifier,\n publicKeyPackage,\n );\n\n // Serialize the aggregated signature\n const sigBytes = serializeSignature(aggregatedSignature);\n if (sigBytes.length !== 64) {\n throw new Error(\"Aggregated signature is not 64 bytes\");\n }\n const finalSignature = Signature.ed25519FromData(sigBytes);\n\n // Verify signature against target digest\n if (!verifyingKey.verify(finalSignature, targetDigest.data())) {\n throw new Error(\"Aggregated signature failed verification against target digest\");\n }\n\n // Create signed envelope\n const signedEnvelope = targetEnvelope.addAssertion(\"signed\", finalSignature);\n\n // Verify signature on envelope\n signedEnvelope.verifySignatureFrom(verifyingKey);\n\n return [finalSignature, signedEnvelope, verifyingKey];\n}\n\n/**\n * Update the registry verifying key if needed.\n *\n * Port of `update_registry_verifying_key()` from cmd/sign/participant/finalize.rs.\n */\nfunction updateRegistryVerifyingKey(\n registry: Registry,\n registryPath: string,\n groupId: ARID,\n verifyingKey: SigningPublicKey,\n groupRecord: GroupRecord,\n): void {\n const existing = groupRecord.verifyingKey();\n if (existing !== undefined) {\n if (existing.urString() !== verifyingKey.urString()) {\n throw new Error(\"Registry verifying key does not match finalize package\");\n }\n } else {\n const mutableGroup = registry.group(groupId);\n if (mutableGroup === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n mutableGroup.setVerifyingKey(verifyingKey);\n registry.save(registryPath);\n }\n}\n\n/**\n * Persist the final state to disk.\n *\n * Port of `persist_final_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction persistFinalState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n signature: Signature,\n signedEnvelope: Envelope,\n signatureShares: Map<string, Ed25519SignatureShare>,\n shareState: ShareState,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n const finalPath = path.join(dir, \"final.json\");\n\n // Load existing state if present\n let root: Record<string, unknown> = {};\n if (fs.existsSync(finalPath)) {\n root = JSON.parse(fs.readFileSync(finalPath, \"utf-8\")) as Record<string, unknown>;\n }\n\n // Build shares JSON\n const sharesJson: Record<string, string> = {};\n for (const [xidStr, share] of signatureShares) {\n sharesJson[xidStr] = serializeSignatureShare(share);\n }\n\n // Build commitments JSON\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidStr, commits] of shareState.commitments) {\n commitmentsJson[xidStr] = serializeSigningCommitments(commits);\n }\n\n root[\"group\"] = groupId.urString();\n root[\"session\"] = sessionId.urString();\n root[\"signature\"] = signature.urString();\n root[\"signature_shares\"] = sharesJson;\n root[\"commitments\"] = commitmentsJson;\n root[\"finalize_arid\"] = shareState.finalizeArid.urString();\n root[\"signed_target\"] = signedEnvelope.urString();\n\n fs.writeFileSync(finalPath, JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant finalize command.\n *\n * Receives the finalize event with aggregated signature.\n *\n * Port of `finalize()` from cmd/sign/participant/finalize.rs.\n */\nexport async function finalize(\n client: StorageClient,\n options: SignFinalizeOptions,\n cwd: string,\n): Promise<SignFinalizeResult> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint =\n options.groupId !== undefined && options.groupId !== \"\"\n ? parseAridUr(options.groupId)\n : undefined;\n\n // Load and validate session state\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n const groupRecord = registry.group(groupId);\n\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n validateSessionState(receiveState, groupRecord, owner);\n\n const shareState = loadShareState(registryPath, groupId, sessionId);\n validateShareState(shareState, receiveState, groupRecord);\n\n // Fetch finalize event\n const sealedEvent = await fetchFinalizeEvent(\n client,\n shareState.finalizeArid,\n options.timeoutSeconds,\n owner,\n );\n\n // Validate event\n validateFinalizeEvent(sealedEvent, sessionId, groupRecord);\n\n // Extract and validate signature shares\n const signatureSharesByXid = parseSignatureShares(sealedEvent);\n validateSignatureShares(signatureSharesByXid, receiveState, shareState, owner);\n\n // Load target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest = targetEnvelope.subject().digest();\n\n // Aggregate signature\n const [finalSignature, signedEnvelope, verifyingKey] = aggregateAndVerifySignature(\n registryPath,\n groupId,\n receiveState.participants,\n shareState.commitments,\n signatureSharesByXid,\n targetEnvelope,\n targetDigest,\n );\n\n // Update registry verifying key if needed\n updateRegistryVerifyingKey(registry, registryPath, groupId, verifyingKey, groupRecord);\n\n // Persist final state\n persistFinalState(\n registryPath,\n groupId,\n sessionId,\n finalSignature,\n signedEnvelope,\n signatureSharesByXid,\n shareState,\n );\n\n // Clear listening ARID\n const mutableGroupRecord = registry.group(groupId);\n if (mutableGroupRecord !== undefined) {\n mutableGroupRecord.clearListeningAtArid();\n registry.save(registryPath);\n }\n\n const signatureStr = finalSignature.urString();\n const signedEnvelopeStr = signedEnvelope.urString();\n\n if (options.verbose === true) {\n console.log(signatureStr);\n console.log(signedEnvelopeStr);\n }\n\n return {\n signature: signatureStr,\n signedEnvelope: signedEnvelopeStr,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
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-
|
|
4
|
+
const require_common = require("./common-CnvAUC2b.cjs");
|
|
5
|
+
const require_busy = require("./busy-B_h0bNAJ.cjs");
|
|
6
6
|
const require_frost_index = require("./frost/index.cjs");
|
|
7
|
-
const require_common$1 = require("./common-
|
|
7
|
+
const require_common$1 = require("./common-7-BOgaTt.cjs");
|
|
8
8
|
let _bcts_components = require("@bcts/components");
|
|
9
9
|
let _bcts_envelope = require("@bcts/envelope");
|
|
10
10
|
let _bcts_gstp = require("@bcts/gstp");
|
|
@@ -399,4 +399,4 @@ Object.defineProperty(exports, "finalize_exports", {
|
|
|
399
399
|
}
|
|
400
400
|
});
|
|
401
401
|
|
|
402
|
-
//# sourceMappingURL=finalize-
|
|
402
|
+
//# sourceMappingURL=finalize-Cb0obTSo.cjs.map
|