@bcts/frost-hubert 1.0.0-alpha.23 → 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.
Files changed (165) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/frost.cjs +344 -72
  3. package/dist/bin/frost.cjs.map +1 -1
  4. package/dist/bin/frost.mjs +344 -71
  5. package/dist/bin/frost.mjs.map +1 -1
  6. package/dist/busy-B_h0bNAJ.cjs +38 -0
  7. package/dist/busy-B_h0bNAJ.cjs.map +1 -0
  8. package/dist/busy-BlU8_pS2.mjs +27 -0
  9. package/dist/busy-BlU8_pS2.mjs.map +1 -0
  10. package/dist/cmd/index.cjs +27 -22
  11. package/dist/cmd/index.d.cts +2 -2
  12. package/dist/cmd/index.d.mts +2 -2
  13. package/dist/cmd/index.mjs +6 -3
  14. package/dist/cmd-CCVhHzG7.cjs +129 -0
  15. package/dist/cmd-CCVhHzG7.cjs.map +1 -0
  16. package/dist/cmd-DNsHd19v.mjs +112 -0
  17. package/dist/cmd-DNsHd19v.mjs.map +1 -0
  18. package/dist/common-7-BOgaTt.cjs +113 -0
  19. package/dist/common-7-BOgaTt.cjs.map +1 -0
  20. package/dist/common-Cf1UvJaP.mjs +282 -0
  21. package/dist/common-Cf1UvJaP.mjs.map +1 -0
  22. package/dist/common-CnvAUC2b.cjs +372 -0
  23. package/dist/common-CnvAUC2b.cjs.map +1 -0
  24. package/dist/common-DNrD_-EI.mjs +96 -0
  25. package/dist/common-DNrD_-EI.mjs.map +1 -0
  26. package/dist/dkg/index.cjs +6 -103
  27. package/dist/dkg/index.cjs.map +1 -1
  28. package/dist/dkg/index.d.cts +2 -2
  29. package/dist/dkg/index.d.mts +2 -2
  30. package/dist/dkg/index.mjs +4 -101
  31. package/dist/dkg/index.mjs.map +1 -1
  32. package/dist/finalize-BpC0rz93.mjs +389 -0
  33. package/dist/finalize-BpC0rz93.mjs.map +1 -0
  34. package/dist/finalize-Cb0obTSo.cjs +402 -0
  35. package/dist/finalize-Cb0obTSo.cjs.map +1 -0
  36. package/dist/finalize-DHEnKobp.cjs +303 -0
  37. package/dist/finalize-DHEnKobp.cjs.map +1 -0
  38. package/dist/finalize-DQ0VGUHO.cjs +265 -0
  39. package/dist/finalize-DQ0VGUHO.cjs.map +1 -0
  40. package/dist/finalize-DtRxHZ7H.mjs +290 -0
  41. package/dist/finalize-DtRxHZ7H.mjs.map +1 -0
  42. package/dist/finalize-T83Ko8nG.mjs +252 -0
  43. package/dist/finalize-T83Ko8nG.mjs.map +1 -0
  44. package/dist/frost/index.cjs +1 -1
  45. package/dist/frost/index.cjs.map +1 -1
  46. package/dist/frost/index.d.cts.map +1 -1
  47. package/dist/frost/index.d.mts.map +1 -1
  48. package/dist/frost/index.mjs +1 -1
  49. package/dist/frost/index.mjs.map +1 -1
  50. package/dist/{index-BJlwbPYu.d.cts → index-BErX9AZF.d.cts} +101 -79
  51. package/dist/index-BErX9AZF.d.cts.map +1 -0
  52. package/dist/{index-BkqLimZT.d.mts → index-BaUVw4b1.d.mts} +25 -2
  53. package/dist/index-BaUVw4b1.d.mts.map +1 -0
  54. package/dist/{index-BMbPgH0W.d.cts → index-CD50Qtgw.d.cts} +46 -2
  55. package/dist/index-CD50Qtgw.d.cts.map +1 -0
  56. package/dist/{index-DoV5HFvV.d.mts → index-CD50Qtgw.d.mts} +46 -2
  57. package/dist/index-CD50Qtgw.d.mts.map +1 -0
  58. package/dist/{index-Dzm1v4_4.d.mts → index-Drklne-Y.d.mts} +101 -79
  59. package/dist/index-Drklne-Y.d.mts.map +1 -0
  60. package/dist/{index-DmxfT59Y.d.cts → index-gkmZzEuD.d.cts} +25 -2
  61. package/dist/index-gkmZzEuD.d.cts.map +1 -0
  62. package/dist/index.cjs +30 -23
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.cts +4 -4
  65. package/dist/index.d.cts.map +1 -1
  66. package/dist/index.d.mts +4 -4
  67. package/dist/index.d.mts.map +1 -1
  68. package/dist/index.mjs +8 -4
  69. package/dist/index.mjs.map +1 -1
  70. package/dist/invite-1tzg0B0P.cjs +274 -0
  71. package/dist/invite-1tzg0B0P.cjs.map +1 -0
  72. package/dist/invite-BLwtexAu.cjs +109 -0
  73. package/dist/invite-BLwtexAu.cjs.map +1 -0
  74. package/dist/invite-Be2v2SVc.mjs +96 -0
  75. package/dist/invite-Be2v2SVc.mjs.map +1 -0
  76. package/dist/invite-D8mQSnFz.mjs +219 -0
  77. package/dist/invite-D8mQSnFz.mjs.map +1 -0
  78. package/dist/parallel-PZiwHZT8.mjs +235 -0
  79. package/dist/parallel-PZiwHZT8.mjs.map +1 -0
  80. package/dist/parallel-szwYx-bi.cjs +318 -0
  81. package/dist/parallel-szwYx-bi.cjs.map +1 -0
  82. package/dist/proposed-participant-BvHNnpcZ.cjs +140 -0
  83. package/dist/proposed-participant-BvHNnpcZ.cjs.map +1 -0
  84. package/dist/proposed-participant-Detb823_.mjs +129 -0
  85. package/dist/proposed-participant-Detb823_.mjs.map +1 -0
  86. package/dist/receive-BR-knnGv.cjs +213 -0
  87. package/dist/receive-BR-knnGv.cjs.map +1 -0
  88. package/dist/receive-D_r4Mryr.cjs +190 -0
  89. package/dist/receive-D_r4Mryr.cjs.map +1 -0
  90. package/dist/receive-dkSCSGpl.mjs +188 -0
  91. package/dist/receive-dkSCSGpl.mjs.map +1 -0
  92. package/dist/receive-g8EhZF2Y.mjs +177 -0
  93. package/dist/receive-g8EhZF2Y.mjs.map +1 -0
  94. package/dist/registry/index.cjs +86 -11
  95. package/dist/registry/index.cjs.map +1 -1
  96. package/dist/registry/index.d.cts +1 -1
  97. package/dist/registry/index.d.mts +1 -1
  98. package/dist/registry/index.mjs +85 -10
  99. package/dist/registry/index.mjs.map +1 -1
  100. package/dist/{registry-loI1_Mh1.cjs → registry-CkIbA7nt.cjs} +79 -2
  101. package/dist/registry-CkIbA7nt.cjs.map +1 -0
  102. package/dist/{registry-CgrCZ4En.mjs → registry-DGjs4qDK.mjs} +74 -3
  103. package/dist/registry-DGjs4qDK.mjs.map +1 -0
  104. package/dist/round1-9FAqFvL5.cjs +465 -0
  105. package/dist/round1-9FAqFvL5.cjs.map +1 -0
  106. package/dist/round1-B8haiMM8.mjs +208 -0
  107. package/dist/round1-B8haiMM8.mjs.map +1 -0
  108. package/dist/round1-BOIE1E4O.mjs +452 -0
  109. package/dist/round1-BOIE1E4O.mjs.map +1 -0
  110. package/dist/round1-Bq0vweyQ.cjs +422 -0
  111. package/dist/round1-Bq0vweyQ.cjs.map +1 -0
  112. package/dist/round1-CXkXoVQU.cjs +208 -0
  113. package/dist/round1-CXkXoVQU.cjs.map +1 -0
  114. package/dist/round1-D8t7EzIo.mjs +373 -0
  115. package/dist/round1-D8t7EzIo.mjs.map +1 -0
  116. package/dist/round1-DriPu15x.cjs +221 -0
  117. package/dist/round1-DriPu15x.cjs.map +1 -0
  118. package/dist/round1-Y2kcVwnR.mjs +195 -0
  119. package/dist/round1-Y2kcVwnR.mjs.map +1 -0
  120. package/dist/round2-AMDYMUIg.cjs +305 -0
  121. package/dist/round2-AMDYMUIg.cjs.map +1 -0
  122. package/dist/round2-BHQKVJFo.cjs +410 -0
  123. package/dist/round2-BHQKVJFo.cjs.map +1 -0
  124. package/dist/round2-BfetYacV.mjs +450 -0
  125. package/dist/round2-BfetYacV.mjs.map +1 -0
  126. package/dist/round2-Cf5CJc_8.mjs +397 -0
  127. package/dist/round2-Cf5CJc_8.mjs.map +1 -0
  128. package/dist/round2-CvrmylN1.cjs +293 -0
  129. package/dist/round2-CvrmylN1.cjs.map +1 -0
  130. package/dist/round2-Dk_w97nl.cjs +499 -0
  131. package/dist/round2-Dk_w97nl.cjs.map +1 -0
  132. package/dist/round2-Z2JhMwxc.mjs +292 -0
  133. package/dist/round2-Z2JhMwxc.mjs.map +1 -0
  134. package/dist/round2-mF6UlkT-.mjs +280 -0
  135. package/dist/round2-mF6UlkT-.mjs.map +1 -0
  136. package/package.json +14 -14
  137. package/src/bin/frost.ts +849 -128
  138. package/src/cmd/common.ts +19 -1
  139. package/src/cmd/dkg/common.ts +97 -10
  140. package/src/cmd/dkg/coordinator/invite.ts +5 -2
  141. package/src/cmd/dkg/participant/finalize.ts +51 -17
  142. package/src/cmd/dkg/participant/round1.ts +39 -38
  143. package/src/cmd/dkg/participant/round2.ts +60 -26
  144. package/src/cmd/sign/coordinator/round2.ts +5 -1
  145. package/src/cmd/sign/participant/finalize.ts +6 -2
  146. package/src/cmd/sign/participant/receive.ts +5 -2
  147. package/src/dkg/group-invite.ts +12 -2
  148. package/src/dkg/proposed-participant.ts +32 -3
  149. package/src/registry/owner-record.ts +12 -0
  150. package/src/registry/participant-record.ts +35 -2
  151. package/src/registry/registry-impl.ts +74 -18
  152. package/dist/cmd-5yLeC_QL.mjs +0 -4708
  153. package/dist/cmd-5yLeC_QL.mjs.map +0 -1
  154. package/dist/cmd-BfZjC3Uh.cjs +0 -4847
  155. package/dist/cmd-BfZjC3Uh.cjs.map +0 -1
  156. package/dist/index-BJlwbPYu.d.cts.map +0 -1
  157. package/dist/index-BMbPgH0W.d.cts.map +0 -1
  158. package/dist/index-BkqLimZT.d.mts.map +0 -1
  159. package/dist/index-DmxfT59Y.d.cts.map +0 -1
  160. package/dist/index-DoV5HFvV.d.mts.map +0 -1
  161. package/dist/index-Dzm1v4_4.d.mts.map +0 -1
  162. package/dist/registry-CgrCZ4En.mjs.map +0 -1
  163. package/dist/registry-loI1_Mh1.cjs.map +0 -1
  164. /package/dist/{chunk-CZWwpsFl.cjs → chunk-DakpK96I.cjs} +0 -0
  165. /package/dist/{chunk-CjcI7cDX.mjs → chunk-z9aeyW2b.mjs} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common-CnvAUC2b.cjs","names":["UR","GroupParticipant","compareXidBytes","path","path"],"sources":["../src/cmd/dkg/common.ts","../src/cmd/common.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for DKG commands.\n *\n * Port of cmd/dkg/common.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as path from \"node:path\";\n\nimport { type ARID, type XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../dkg/proposed-participant.js\";\nimport { type Envelope } from \"@bcts/envelope\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport {\n GroupParticipant,\n type OwnerRecord,\n type ParticipantRecord,\n type Registry,\n} from \"../../registry/index.js\";\n\n// Re-export cross-cutting utilities for convenience\nexport { groupStateDir } from \"../common.js\";\n\n/**\n * Parse an ARID from a UR string.\n *\n * Mirrors Rust `parse_arid_ur` (`cmd/common.rs:27-43`):\n *\n * 1. Trim and reject empty input.\n * 2. Parse as a UR; require `ur_type` of `\"arid\"`.\n * 3. Try `ARID::try_from(cbor)` (the tagged-CBOR form).\n * 4. If that fails, fall back to interpreting the CBOR as a bare\n * byte string and constructing the ARID from those bytes via\n * `ARID::from_data_ref`.\n *\n * The earlier port only accepted the tagged form; this matches Rust\n * by accepting the byte-string fallback too.\n */\nexport function parseAridUr(urString: string): ARID {\n const trimmed = urString.trim();\n if (trimmed.length === 0) {\n throw new Error(\"ARID is required\");\n }\n const ur = UR.fromURString(trimmed);\n\n if (ur.urTypeStr() !== \"arid\") {\n throw new Error(`Expected a ur:arid, found ur:${ur.urTypeStr()}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { ARID: ARIDClass } = require(\"@bcts/components\");\n const cbor = ur.cbor();\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return ARIDClass.fromTaggedCbor(cbor);\n } catch {\n // Fall back to a bare byte string payload, mirroring Rust's\n // `CBOR::try_into_byte_string(cbor) → ARID::from_data_ref(bytes)`.\n const bytes = (cbor as { asByteString(): Uint8Array | undefined }).asByteString?.();\n if (bytes === undefined) {\n throw new Error(\"Invalid ARID payload\");\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return ARIDClass.fromData(bytes);\n }\n}\n\n/**\n * Parse an envelope from a UR string.\n *\n * Port of `parse_envelope_ur()` from cmd/dkg/common.rs.\n */\nexport function parseEnvelopeUr(urString: string): Envelope {\n const ur = UR.fromURString(urString.trim());\n\n if (ur.urTypeStr() !== \"envelope\") {\n throw new Error(`Expected ur:envelope, found ur:${ur.urTypeStr()}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { Envelope: EnvelopeClass } = require(\"@bcts/envelope\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return EnvelopeClass.fromCbor(ur.cbor());\n}\n\n/**\n * Resolve the registry owner's XID document.\n *\n * The earlier port called this `resolveSender(registry)`, but its\n * behaviour — \"give me the owner\" — has nothing in common with Rust's\n * `resolve_sender(registry, input)` (which resolves an arbitrary\n * named sender). This helper is renamed to its actual behaviour;\n * the Rust-equivalent `resolveSender(registry, input)` lives below.\n */\nexport function resolveOwnerXidDocument(registry: Registry): XIDDocument {\n const owner = registry.owner();\n\n if (!owner) {\n throw new Error(\"No owner set in registry. Run 'registry owner set' first.\");\n }\n\n return owner.xidDocument();\n}\n\n/**\n * Resolve a sender XID document from the registry by UR or pet name.\n *\n * Mirrors Rust `resolve_sender(registry, input)`\n * (`cmd/dkg/common.rs:76-94`):\n *\n * 1. Trim and reject empty input.\n * 2. Try parsing the input as a `ur:xid`. If that succeeds, look it\n * up via `registry.participant(xid)`; if no record is found,\n * error with `Sender with XID {ur} not found`.\n * 3. Otherwise look it up by pet name via\n * `registry.participantByPetName(name)`; if no record is found,\n * error with `Sender with pet name '{name}' not found`.\n *\n * Note Rust does NOT check the owner here — only the participants\n * map. The earlier inline duplicate in `participant/round1.ts` did\n * an extra owner-check fallback which is removed to match Rust.\n */\nexport function resolveSender(registry: Registry, input: string): XIDDocument {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Sender is required\");\n }\n\n // Try parsing as an XID UR string first. `XID.fromURString` throws\n // when the input isn't a `ur:xid`; that's the signal to fall back\n // to pet-name lookup.\n let xid: XID | undefined;\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { XID: XIDClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n xid = XIDClass.fromURString(trimmed) as XID;\n } catch {\n xid = undefined;\n }\n\n if (xid !== undefined) {\n const record = registry.participant(xid);\n if (record !== undefined) {\n return record.xidDocument();\n }\n throw new Error(`Sender with XID ${xid.urString()} not found`);\n }\n\n const result = registry.participantByPetName(trimmed);\n if (result !== undefined) {\n const [, record] = result;\n return record.xidDocument();\n }\n throw new Error(`Sender with pet name '${trimmed}' not found`);\n}\n\n// -----------------------------------------------------------------------------\n// Participant resolution\n// -----------------------------------------------------------------------------\n\n/**\n * Resolve participant identifiers (XID URs or pet names) to records.\n *\n * Port of `resolve_participants()` from cmd/dkg/common.rs lines 29-74.\n */\nexport function resolveParticipants(\n registry: Registry,\n inputs: string[],\n): [XID, ParticipantRecord][] {\n const seenArgs = new Set<string>();\n const seenXids = new Set<string>();\n const resolved: [XID, ParticipantRecord][] = [];\n\n for (const raw of inputs) {\n const trimmed = raw.trim();\n if (trimmed === \"\") {\n throw new Error(\"Participant identifier cannot be empty\");\n }\n if (seenArgs.has(trimmed)) {\n throw new Error(`Duplicate participant argument: ${trimmed}`);\n }\n seenArgs.add(trimmed);\n\n let xid: XID;\n let record: ParticipantRecord;\n\n // Try parsing as XID UR first\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { XID: XIDClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n xid = XIDClass.fromURString(trimmed) as XID;\n\n const foundRecord = registry.participant(xid);\n if (!foundRecord) {\n throw new Error(`Participant with XID ${xid.urString()} not found in registry`);\n }\n record = foundRecord;\n } catch {\n // Try looking up by pet name\n const result = registry.participantByPetName(trimmed);\n if (!result) {\n throw new Error(`Participant with pet name '${trimmed}' not found`);\n }\n [xid, record] = result;\n }\n\n const xidUr = xid.urString();\n if (seenXids.has(xidUr)) {\n throw new Error(`Duplicate participant specified; multiple inputs resolve to ${xidUr}`);\n }\n seenXids.add(xidUr);\n\n resolved.push([xid, record]);\n }\n\n return resolved;\n}\n\n/**\n * Get display name for sender from registry.\n *\n * Port of `resolve_sender_name()` from cmd/dkg/common.rs lines 96-116.\n */\nexport function resolveSenderName(registry: Registry, sender: XIDDocument): string | undefined {\n const owner = registry.owner();\n const senderXid = sender.xid();\n\n // Check if sender is the owner\n if (owner?.xidDocument().xid().urString() === senderXid.urString()) {\n const name = owner.petName() ?? senderXid.urString();\n return formatNameWithOwnerMarker(name, true);\n }\n\n // Look up in participants\n const record = registry.participant(senderXid);\n if (record) {\n const name = record.petName() ?? record.xid().urString();\n return formatNameWithOwnerMarker(name, false);\n }\n\n return undefined;\n}\n\n// -----------------------------------------------------------------------------\n// Group participant building\n// -----------------------------------------------------------------------------\n\n/**\n * Build GroupParticipant[] from XIDDocuments using registry lookups.\n *\n * Port of `build_group_participants()` from cmd/dkg/common.rs lines 122-131.\n */\nexport function buildGroupParticipants(\n registry: Registry,\n owner: OwnerRecord,\n participants: XIDDocument[],\n): GroupParticipant[] {\n return participants.map((doc) => groupParticipantFromRegistry(registry, owner, doc));\n}\n\n/**\n * Create a GroupParticipant from a XIDDocument, validating against the registry.\n *\n * Port of `group_participant_from_registry()` from cmd/dkg/common.rs lines 133-149.\n */\nexport function groupParticipantFromRegistry(\n registry: Registry,\n owner: OwnerRecord,\n document: XIDDocument,\n): GroupParticipant {\n const xid = document.xid();\n\n // If the document is the owner, allow it\n if (xid.urString() === owner.xid().urString()) {\n return new GroupParticipant(xid);\n }\n\n // Otherwise, verify the participant is in the registry\n if (!registry.participant(xid)) {\n throw new Error(`Invite participant not found in registry: ${xid.urString()}`);\n }\n\n return new GroupParticipant(xid);\n}\n\n// -----------------------------------------------------------------------------\n// Name formatting\n// -----------------------------------------------------------------------------\n\n/**\n * Format a participant name with owner marker if applicable.\n *\n * Port of `format_name_with_owner_marker()` from cmd/dkg/common.rs lines 155-157.\n */\nexport function formatNameWithOwnerMarker(name: string, isOwner: boolean): string {\n return isOwner ? `* ${name}` : name;\n}\n\n/**\n * Get display names for participants, sorted by XID, with owner marked.\n *\n * Port of `participant_names_from_registry()` from cmd/dkg/common.rs lines 159-191.\n */\nexport function participantNamesFromRegistry(\n registry: Registry,\n participants: XIDDocument[],\n ownerXid: XID,\n ownerPetName: string | undefined,\n): string[] {\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used\n // `urString().localeCompare(...)`, which diverges from byte order\n // for bytes ≥ 0x80 and is locale-aware.\n const sorted = [...participants].sort((a, b) =>\n compareXidBytes(a.xid().toData(), b.xid().toData()),\n );\n\n return sorted.map((document) => {\n const xid = document.xid();\n const isOwner = xid.urString() === ownerXid.urString();\n\n let name: string;\n if (isOwner) {\n name = ownerPetName ?? xid.urString();\n } else {\n const record = registry.participant(xid);\n if (!record) {\n throw new Error(`Invite participant not found in registry: ${xid.urString()}`);\n }\n name = record.petName() ?? xid.urString();\n }\n\n return formatNameWithOwnerMarker(name, isOwner);\n });\n}\n\n/**\n * Get the DKG state directory for a given registry path and group ID.\n *\n * Port of `dkg_state_dir()` from cmd/dkg/common.rs.\n */\nexport function dkgStateDir(registryPath: string, groupIdHex: string): string {\n const base = path.dirname(registryPath);\n return path.join(base, \"group-state\", groupIdHex, \"dkg\");\n}\n\n/**\n * Convert a verifying key bytes to a SigningPublicKey.\n *\n * Port of `signing_key_from_verifying()` from cmd/dkg/common.rs.\n */\nexport function signingKeyFromVerifying(verifyingKeyBytes: Uint8Array): unknown {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { SigningPublicKey: SigningPublicKeyClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return SigningPublicKeyClass.fromBytes(verifyingKeyBytes);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for commands.\n *\n * Port of `cmd/common.rs` from `frost-hubert-rust`.\n *\n * Rust's `cmd::common` exports four cross-cutting helpers used by\n * both the DKG and signing subcommand trees:\n *\n * - `parse_arid_ur` / `signing_key_from_verifying` — re-exported\n * here so the TS module layout matches Rust. The implementations\n * live alongside their other DKG-specific siblings in\n * `cmd/dkg/common.ts` so callers in either tree can keep using\n * them; this file just surfaces them at the parallel-to-Rust\n * import path (`@bcts/frost-hubert/cmd/common`).\n * - `group_state_dir` and the verbose-flag helpers are TS-native here.\n *\n * `OptionalStorageSelector` is intentionally not ported: it's a\n * `clap`-specific argument struct and the TS port surfaces the same\n * effect via the `StorageSelection` string-literal union — see the\n * `parity audit` for context.\n *\n * @module\n */\n\nimport * as path from \"node:path\";\n\nexport { parseAridUr, signingKeyFromVerifying } from \"./dkg/common.js\";\n\n/**\n * Get the group state directory for a given registry path and group ID.\n *\n * Port of `group_state_dir()` from cmd/common.rs.\n */\nexport function groupStateDir(registryPath: string, groupIdHex: string): string {\n const base = path.dirname(registryPath);\n return path.join(base, \"group-state\", groupIdHex);\n}\n\n/**\n * Global verbose flag.\n */\nlet verboseFlag = false;\n\n/**\n * Set the verbose flag.\n */\nexport function setVerbose(value: boolean): void {\n verboseFlag = value;\n}\n\n/**\n * Check if verbose mode is enabled.\n *\n * Port of `is_verbose()` from cmd/common.rs.\n */\nexport function isVerbose(): boolean {\n return verboseFlag;\n}\n"],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import { t as groupStateDir } from "./common-Cf1UvJaP.mjs";
2
+ import { Envelope } from "@bcts/envelope";
3
+ //#region src/cmd/sign/common.ts
4
+ /**
5
+ * Copyright © 2023-2026 Blockchain Commons, LLC
6
+ * Copyright © 2025-2026 Parity Technologies
7
+ *
8
+ *
9
+ * Common utilities for sign commands.
10
+ *
11
+ * Port of cmd/sign/common.rs from frost-hubert-rust.
12
+ *
13
+ * @module
14
+ */
15
+ /**
16
+ * Get the signing state directory for a group (without session).
17
+ *
18
+ * Path: `{registry_dir}/group-state/{group_id.hex()}/signing`
19
+ *
20
+ * Port of `signing_state_dir_for_group()` from cmd/sign/common.rs.
21
+ */
22
+ function signingStateDirForGroup(registryPath, groupIdHex) {
23
+ return `${groupStateDir(registryPath, groupIdHex)}/signing`;
24
+ }
25
+ /**
26
+ * Get the signing state directory for a given registry path, group ID, and session ID.
27
+ *
28
+ * Path: `{registry_dir}/group-state/{group_id.hex()}/signing/{session_id.hex()}`
29
+ *
30
+ * Port of `signing_state_dir()` from cmd/sign/common.rs.
31
+ */
32
+ function signingStateDir(registryPath, groupIdHex, sessionIdHex) {
33
+ return `${signingStateDirForGroup(registryPath, groupIdHex)}/${sessionIdHex}`;
34
+ }
35
+ /**
36
+ * Content wrapper for signFinalize events.
37
+ *
38
+ * This wraps an envelope with a unit subject and type assertion
39
+ * "signFinalize", implementing the traits required by SealedEvent<T>.
40
+ *
41
+ * Port of `struct SignFinalizeContent` from cmd/sign/common.rs.
42
+ */
43
+ var SignFinalizeContent = class SignFinalizeContent {
44
+ _envelope;
45
+ constructor(envelope) {
46
+ this._envelope = envelope;
47
+ }
48
+ /**
49
+ * Creates a new SignFinalizeContent with a unit subject and type assertion.
50
+ *
51
+ * Port of `SignFinalizeContent::new()` from cmd/sign/common.rs.
52
+ */
53
+ static new() {
54
+ return new SignFinalizeContent(Envelope.unit().addType("signFinalize"));
55
+ }
56
+ /**
57
+ * Adds an assertion to the content envelope.
58
+ *
59
+ * Port of `SignFinalizeContent::add_assertion()` from cmd/sign/common.rs.
60
+ */
61
+ addAssertion(predicate, object) {
62
+ return new SignFinalizeContent(this._envelope.addAssertion(predicate, object));
63
+ }
64
+ /**
65
+ * Returns the inner envelope.
66
+ *
67
+ * Port of `SignFinalizeContent::envelope()` from cmd/sign/common.rs.
68
+ */
69
+ envelope() {
70
+ return this._envelope;
71
+ }
72
+ /**
73
+ * Creates a SignFinalizeContent from an envelope with validation.
74
+ *
75
+ * Validates that the envelope has a unit subject and type "signFinalize".
76
+ *
77
+ * Port of `TryFrom<Envelope> for SignFinalizeContent` from cmd/sign/common.rs.
78
+ */
79
+ static fromEnvelope(envelope) {
80
+ envelope.checkSubjectUnit();
81
+ envelope.checkType("signFinalize");
82
+ return new SignFinalizeContent(envelope);
83
+ }
84
+ /**
85
+ * Converts this SignFinalizeContent to an Envelope.
86
+ *
87
+ * Port of `From<SignFinalizeContent> for Envelope` from cmd/sign/common.rs.
88
+ */
89
+ toEnvelope() {
90
+ return this._envelope;
91
+ }
92
+ };
93
+ //#endregion
94
+ export { signingStateDir as n, signingStateDirForGroup as r, SignFinalizeContent as t };
95
+
96
+ //# sourceMappingURL=common-DNrD_-EI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common-DNrD_-EI.mjs","names":[],"sources":["../src/cmd/sign/common.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for sign commands.\n *\n * Port of cmd/sign/common.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { Envelope, type EnvelopeEncodableValue } from \"@bcts/envelope\";\n\nimport { groupStateDir } from \"../common\";\n\n/**\n * Get the signing state directory for a group (without session).\n *\n * Path: `{registry_dir}/group-state/{group_id.hex()}/signing`\n *\n * Port of `signing_state_dir_for_group()` from cmd/sign/common.rs.\n */\nexport function signingStateDirForGroup(registryPath: string, groupIdHex: string): string {\n return `${groupStateDir(registryPath, groupIdHex)}/signing`;\n}\n\n/**\n * Get the signing state directory for a given registry path, group ID, and session ID.\n *\n * Path: `{registry_dir}/group-state/{group_id.hex()}/signing/{session_id.hex()}`\n *\n * Port of `signing_state_dir()` from cmd/sign/common.rs.\n */\nexport function signingStateDir(\n registryPath: string,\n groupIdHex: string,\n sessionIdHex: string,\n): string {\n return `${signingStateDirForGroup(registryPath, groupIdHex)}/${sessionIdHex}`;\n}\n\n/**\n * Content wrapper for signFinalize events.\n *\n * This wraps an envelope with a unit subject and type assertion\n * \"signFinalize\", implementing the traits required by SealedEvent<T>.\n *\n * Port of `struct SignFinalizeContent` from cmd/sign/common.rs.\n */\nexport class SignFinalizeContent {\n private readonly _envelope: Envelope;\n\n private constructor(envelope: Envelope) {\n this._envelope = envelope;\n }\n\n /**\n * Creates a new SignFinalizeContent with a unit subject and type assertion.\n *\n * Port of `SignFinalizeContent::new()` from cmd/sign/common.rs.\n */\n static new(): SignFinalizeContent {\n const envelope = Envelope.unit().addType(\"signFinalize\");\n return new SignFinalizeContent(envelope);\n }\n\n /**\n * Adds an assertion to the content envelope.\n *\n * Port of `SignFinalizeContent::add_assertion()` from cmd/sign/common.rs.\n */\n addAssertion(\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue,\n ): SignFinalizeContent {\n const newEnvelope = this._envelope.addAssertion(predicate, object);\n return new SignFinalizeContent(newEnvelope);\n }\n\n /**\n * Returns the inner envelope.\n *\n * Port of `SignFinalizeContent::envelope()` from cmd/sign/common.rs.\n */\n envelope(): Envelope {\n return this._envelope;\n }\n\n /**\n * Creates a SignFinalizeContent from an envelope with validation.\n *\n * Validates that the envelope has a unit subject and type \"signFinalize\".\n *\n * Port of `TryFrom<Envelope> for SignFinalizeContent` from cmd/sign/common.rs.\n */\n static fromEnvelope(envelope: Envelope): SignFinalizeContent {\n // Validate it has a unit subject and type \"signFinalize\"\n envelope.checkSubjectUnit();\n envelope.checkType(\"signFinalize\");\n return new SignFinalizeContent(envelope);\n }\n\n /**\n * Converts this SignFinalizeContent to an Envelope.\n *\n * Port of `From<SignFinalizeContent> for Envelope` from cmd/sign/common.rs.\n */\n toEnvelope(): Envelope {\n return this._envelope;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,wBAAwB,cAAsB,YAA4B;CACxF,OAAO,GAAG,cAAc,cAAc,UAAU,EAAE;AACpD;;;;;;;;AASA,SAAgB,gBACd,cACA,YACA,cACQ;CACR,OAAO,GAAG,wBAAwB,cAAc,UAAU,EAAE,GAAG;AACjE;;;;;;;;;AAUA,IAAa,sBAAb,MAAa,oBAAoB;CAC/B;CAEA,YAAoB,UAAoB;EACtC,KAAK,YAAY;CACnB;;;;;;CAOA,OAAO,MAA2B;EAEhC,OAAO,IAAI,oBADM,SAAS,KAAK,EAAE,QAAQ,cACH,CAAC;CACzC;;;;;;CAOA,aACE,WACA,QACqB;EAErB,OAAO,IAAI,oBADS,KAAK,UAAU,aAAa,WAAW,MAClB,CAAC;CAC5C;;;;;;CAOA,WAAqB;EACnB,OAAO,KAAK;CACd;;;;;;;;CASA,OAAO,aAAa,UAAyC;EAE3D,SAAS,iBAAiB;EAC1B,SAAS,UAAU,cAAc;EACjC,OAAO,IAAI,oBAAoB,QAAQ;CACzC;;;;;;CAOA,aAAuB;EACrB,OAAO,KAAK;CACd;AACF"}
@@ -1,108 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- require("../chunk-CZWwpsFl.cjs");
2
+ const require_proposed_participant = require("../proposed-participant-BvHNnpcZ.cjs");
3
3
  let _bcts_components = require("@bcts/components");
4
4
  let _bcts_dcbor = require("@bcts/dcbor");
5
5
  let _bcts_envelope = require("@bcts/envelope");
6
6
  let _bcts_gstp = require("@bcts/gstp");
7
7
  let _bcts_xid = require("@bcts/xid");
8
- let _bcts_uniform_resources = require("@bcts/uniform-resources");
9
- //#region src/dkg/proposed-participant.ts
10
- /**
11
- * A proposed participant in a DKG session.
12
- *
13
- * Port of `struct DkgProposedParticipant` from proposed_participant.rs lines 8-13.
14
- */
15
- var DkgProposedParticipant = class DkgProposedParticipant {
16
- _urString;
17
- _envelope;
18
- _document;
19
- _responseArid;
20
- constructor(urString, envelope, document, responseArid) {
21
- this._urString = urString;
22
- this._envelope = envelope;
23
- this._document = document;
24
- this._responseArid = responseArid;
25
- }
26
- /**
27
- * Create a new DkgProposedParticipant from a UR string and response ARID.
28
- *
29
- * Port of `DkgProposedParticipant::new()` from proposed_participant.rs lines 22-26.
30
- */
31
- static create(urString, responseArid) {
32
- const [envelope, document] = parseXidEnvelope(urString);
33
- return new DkgProposedParticipant(urString, envelope, document, responseArid);
34
- }
35
- /**
36
- * Get the XID of this participant.
37
- *
38
- * Port of `DkgProposedParticipant::xid()` from proposed_participant.rs line 28.
39
- */
40
- xid() {
41
- return this._document.xid();
42
- }
43
- /**
44
- * Get the XID document of this participant.
45
- *
46
- * Port of `DkgProposedParticipant::xid_document()` from proposed_participant.rs line 30.
47
- */
48
- xidDocument() {
49
- return this._document;
50
- }
51
- /**
52
- * Get the UR string of the XID document.
53
- *
54
- * Port of `DkgProposedParticipant::xid_document_ur()` from proposed_participant.rs line 32.
55
- */
56
- xidDocumentUr() {
57
- return this._urString;
58
- }
59
- /**
60
- * Get the envelope containing the XID document.
61
- *
62
- * Port of `DkgProposedParticipant::xid_document_envelope()` from proposed_participant.rs line 34.
63
- */
64
- xidDocumentEnvelope() {
65
- return this._envelope;
66
- }
67
- /**
68
- * Get the response ARID for this participant.
69
- *
70
- * Port of `DkgProposedParticipant::response_arid()` from proposed_participant.rs line 36.
71
- */
72
- responseArid() {
73
- return this._responseArid;
74
- }
75
- /**
76
- * Compare participants by XID for sorting.
77
- */
78
- compareTo(other) {
79
- const thisXid = this.xid().toString();
80
- const otherXid = other.xid().toString();
81
- return thisXid.localeCompare(otherXid);
82
- }
83
- };
84
- /**
85
- * Parse a XID envelope from a UR string.
86
- *
87
- * Port of `parse_xid_envelope()` from proposed_participant.rs lines 39-60.
88
- */
89
- function parseXidEnvelope(input) {
90
- const trimmed = input.trim();
91
- if (trimmed.length === 0) throw new Error("XID document is required");
92
- const ur = _bcts_uniform_resources.UR.fromURString(trimmed);
93
- const urType = ur.urTypeStr();
94
- if (urType !== "xid" && urType !== "envelope") throw new Error(`Expected a ur:xid document, found ur:${urType}`);
95
- const envelopeCbor = ur.cbor();
96
- let envelope;
97
- try {
98
- envelope = _bcts_envelope.Envelope.fromTaggedCbor(envelopeCbor);
99
- } catch {
100
- envelope = _bcts_envelope.Envelope.fromUntaggedCbor(envelopeCbor);
101
- }
102
- const document = _bcts_xid.XIDDocument.fromEnvelope(envelope, void 0, _bcts_xid.XIDVerifySignature.Inception);
103
- return [envelope, document];
104
- }
105
- //#endregion
106
8
  //#region src/dkg/group-invite.ts
107
9
  /**
108
10
  * Copyright © 2023-2026 Blockchain Commons, LLC
@@ -162,7 +64,7 @@ var DkgInvite = class DkgInvite {
162
64
  static create(requestId, sender, groupId, date, validUntil, minSigners, charter, participants, responseArids) {
163
65
  if (participants.length !== responseArids.length) throw new Error(`Number of participants (${participants.length}) does not match number of response ARIDs (${responseArids.length})`);
164
66
  if (minSigners < 2) throw new Error("min_signers must be at least 2");
165
- const orderedParticipants = participants.map((urString, i) => DkgProposedParticipant.create(urString, responseArids[i]));
67
+ const orderedParticipants = participants.map((urString, i) => require_proposed_participant.DkgProposedParticipant.create(urString, responseArids[i]));
166
68
  if (minSigners > orderedParticipants.length) throw new Error("min_signers cannot exceed number of participants");
167
69
  orderedParticipants.sort((a, b) => a.compareTo(b));
168
70
  return new DkgInvite(requestId, sender, groupId, date, validUntil, minSigners, charter, orderedParticipants);
@@ -313,7 +215,7 @@ var DkgInvitation = class DkgInvitation {
313
215
  const recipientPrivateKeys = recipient.inceptionPrivateKeys();
314
216
  if (recipientPrivateKeys === void 0) throw new Error("Recipient XID document has no inception private keys");
315
217
  const sealedRequest = _bcts_gstp.SealedRequest.tryFromEnvelope(invite, void 0, now, recipientPrivateKeys);
316
- if (expectedSender !== void 0 && sealedRequest.sender().xid() !== expectedSender.xid()) throw new Error("Invite sender does not match expected sender");
218
+ if (expectedSender !== void 0 && !sealedRequest.sender().xid().equals(expectedSender.xid())) throw new Error("Invite sender does not match expected sender");
317
219
  if (!sealedRequest.request().function().equals(_bcts_envelope.Function.fromString("dkgInvite"))) throw new Error("Unexpected invite function");
318
220
  const validUntil = sealedRequest.extractObjectForParameter("validUntil");
319
221
  if (validUntil <= now) throw new Error("Invitation expired");
@@ -326,7 +228,7 @@ var DkgInvitation = class DkgInvitation {
326
228
  if (minSigners > participantObjects.length) throw new Error("min_signers exceeds participant count");
327
229
  for (const participant of participantObjects) {
328
230
  const xidDocumentEnvelope = participant.tryUnwrap();
329
- if (_bcts_xid.XIDDocument.fromEnvelope(xidDocumentEnvelope, void 0, _bcts_xid.XIDVerifySignature.Inception).xid() !== recipientXid) continue;
231
+ if (!_bcts_xid.XIDDocument.fromEnvelope(xidDocumentEnvelope, void 0, _bcts_xid.XIDVerifySignature.Inception).xid().equals(recipientXid)) continue;
330
232
  return new DkgInvitation(participant.objectForPredicate("response_arid").decryptToRecipient(recipientPrivateKeys).extractSubject((cbor) => _bcts_components.ARID.fromTaggedCbor(cbor)), validUntil, sealedRequest.sender(), sealedRequest.request().id(), sealedRequest.peerContinuation(), minSigners, charter, groupId);
331
233
  }
332
234
  throw new Error("Recipient not found in invite");
@@ -335,8 +237,9 @@ var DkgInvitation = class DkgInvitation {
335
237
  //#endregion
336
238
  exports.DkgInvitation = DkgInvitation;
337
239
  exports.DkgInvite = DkgInvite;
338
- exports.DkgProposedParticipant = DkgProposedParticipant;
240
+ exports.DkgProposedParticipant = require_proposed_participant.DkgProposedParticipant;
339
241
  exports.accepted = accepted;
242
+ exports.compareXidBytes = require_proposed_participant.compareXidBytes;
340
243
  exports.declined = declined;
341
244
 
342
245
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["UR","Envelope","XIDDocument","XIDVerifySignature","SealedRequest","CborDate","Envelope","SealedResponse","EnvelopeFunction","XIDDocument","XIDVerifySignature","ARID"],"sources":["../../src/dkg/proposed-participant.ts","../../src/dkg/group-invite.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG Proposed Participant.\n *\n * Port of dkg/proposed_participant.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { type ARID, type XID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { XIDDocument, XIDVerifySignature } from \"@bcts/xid\";\n\n/**\n * A proposed participant in a DKG session.\n *\n * Port of `struct DkgProposedParticipant` from proposed_participant.rs lines 8-13.\n */\nexport class DkgProposedParticipant {\n private readonly _urString: string;\n private readonly _envelope: Envelope;\n private readonly _document: XIDDocument;\n private readonly _responseArid: ARID;\n\n private constructor(\n urString: string,\n envelope: Envelope,\n document: XIDDocument,\n responseArid: ARID,\n ) {\n this._urString = urString;\n this._envelope = envelope;\n this._document = document;\n this._responseArid = responseArid;\n }\n\n /**\n * Create a new DkgProposedParticipant from a UR string and response ARID.\n *\n * Port of `DkgProposedParticipant::new()` from proposed_participant.rs lines 22-26.\n */\n static create(urString: string, responseArid: ARID): DkgProposedParticipant {\n const [envelope, document] = parseXidEnvelope(urString);\n return new DkgProposedParticipant(urString, envelope, document, responseArid);\n }\n\n /**\n * Get the XID of this participant.\n *\n * Port of `DkgProposedParticipant::xid()` from proposed_participant.rs line 28.\n */\n xid(): XID {\n return this._document.xid();\n }\n\n /**\n * Get the XID document of this participant.\n *\n * Port of `DkgProposedParticipant::xid_document()` from proposed_participant.rs line 30.\n */\n xidDocument(): XIDDocument {\n return this._document;\n }\n\n /**\n * Get the UR string of the XID document.\n *\n * Port of `DkgProposedParticipant::xid_document_ur()` from proposed_participant.rs line 32.\n */\n xidDocumentUr(): string {\n return this._urString;\n }\n\n /**\n * Get the envelope containing the XID document.\n *\n * Port of `DkgProposedParticipant::xid_document_envelope()` from proposed_participant.rs line 34.\n */\n xidDocumentEnvelope(): Envelope {\n return this._envelope;\n }\n\n /**\n * Get the response ARID for this participant.\n *\n * Port of `DkgProposedParticipant::response_arid()` from proposed_participant.rs line 36.\n */\n responseArid(): ARID {\n return this._responseArid;\n }\n\n /**\n * Compare participants by XID for sorting.\n */\n compareTo(other: DkgProposedParticipant): number {\n const thisXid = this.xid().toString();\n const otherXid = other.xid().toString();\n return thisXid.localeCompare(otherXid);\n }\n}\n\n/**\n * Parse a XID envelope from a UR string.\n *\n * Port of `parse_xid_envelope()` from proposed_participant.rs lines 39-60.\n */\nfunction parseXidEnvelope(input: string): [Envelope, XIDDocument] {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"XID document is required\");\n }\n\n const ur = UR.fromURString(trimmed);\n const urType = ur.urTypeStr();\n if (urType !== \"xid\" && urType !== \"envelope\") {\n throw new Error(`Expected a ur:xid document, found ur:${urType}`);\n }\n\n const envelopeCbor = ur.cbor();\n // Try tagged CBOR first, then untagged\n let envelope: Envelope;\n try {\n envelope = Envelope.fromTaggedCbor(envelopeCbor);\n } catch {\n envelope = Envelope.fromUntaggedCbor(envelopeCbor);\n }\n\n const document = XIDDocument.fromEnvelope(envelope, undefined, XIDVerifySignature.Inception);\n\n return [envelope, document];\n}\n","/**\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 if (expectedSender !== undefined && sealedRequest.sender().xid() !== expectedSender.xid()) {\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 if (xidDocument.xid() !== 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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"}
@@ -1,2 +1,2 @@
1
- import { a as declined, i as accepted, n as DkgInvitationResult, o as DkgProposedParticipant, r as DkgInvite, t as DkgInvitation } from "../index-DmxfT59Y.cjs";
2
- export { DkgInvitation, DkgInvitationResult, DkgInvite, DkgProposedParticipant, accepted, declined };
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
+ export { DkgInvitation, DkgInvitationResult, DkgInvite, DkgProposedParticipant, accepted, compareXidBytes, declined };
@@ -1,2 +1,2 @@
1
- import { a as declined, i as accepted, n as DkgInvitationResult, o as DkgProposedParticipant, r as DkgInvite, t as DkgInvitation } from "../index-BkqLimZT.mjs";
2
- export { DkgInvitation, DkgInvitationResult, DkgInvite, DkgProposedParticipant, accepted, declined };
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
+ export { DkgInvitation, DkgInvitationResult, DkgInvite, DkgProposedParticipant, accepted, compareXidBytes, declined };
@@ -1,106 +1,9 @@
1
+ import { n as compareXidBytes, t as DkgProposedParticipant } from "../proposed-participant-Detb823_.mjs";
1
2
  import { ARID } from "@bcts/components";
2
3
  import { CborDate } from "@bcts/dcbor";
3
4
  import { Envelope, Function } from "@bcts/envelope";
4
5
  import { SealedRequest, SealedResponse } from "@bcts/gstp";
5
6
  import { XIDDocument, XIDVerifySignature } from "@bcts/xid";
6
- import { UR } from "@bcts/uniform-resources";
7
- //#region src/dkg/proposed-participant.ts
8
- /**
9
- * A proposed participant in a DKG session.
10
- *
11
- * Port of `struct DkgProposedParticipant` from proposed_participant.rs lines 8-13.
12
- */
13
- var DkgProposedParticipant = class DkgProposedParticipant {
14
- _urString;
15
- _envelope;
16
- _document;
17
- _responseArid;
18
- constructor(urString, envelope, document, responseArid) {
19
- this._urString = urString;
20
- this._envelope = envelope;
21
- this._document = document;
22
- this._responseArid = responseArid;
23
- }
24
- /**
25
- * Create a new DkgProposedParticipant from a UR string and response ARID.
26
- *
27
- * Port of `DkgProposedParticipant::new()` from proposed_participant.rs lines 22-26.
28
- */
29
- static create(urString, responseArid) {
30
- const [envelope, document] = parseXidEnvelope(urString);
31
- return new DkgProposedParticipant(urString, envelope, document, responseArid);
32
- }
33
- /**
34
- * Get the XID of this participant.
35
- *
36
- * Port of `DkgProposedParticipant::xid()` from proposed_participant.rs line 28.
37
- */
38
- xid() {
39
- return this._document.xid();
40
- }
41
- /**
42
- * Get the XID document of this participant.
43
- *
44
- * Port of `DkgProposedParticipant::xid_document()` from proposed_participant.rs line 30.
45
- */
46
- xidDocument() {
47
- return this._document;
48
- }
49
- /**
50
- * Get the UR string of the XID document.
51
- *
52
- * Port of `DkgProposedParticipant::xid_document_ur()` from proposed_participant.rs line 32.
53
- */
54
- xidDocumentUr() {
55
- return this._urString;
56
- }
57
- /**
58
- * Get the envelope containing the XID document.
59
- *
60
- * Port of `DkgProposedParticipant::xid_document_envelope()` from proposed_participant.rs line 34.
61
- */
62
- xidDocumentEnvelope() {
63
- return this._envelope;
64
- }
65
- /**
66
- * Get the response ARID for this participant.
67
- *
68
- * Port of `DkgProposedParticipant::response_arid()` from proposed_participant.rs line 36.
69
- */
70
- responseArid() {
71
- return this._responseArid;
72
- }
73
- /**
74
- * Compare participants by XID for sorting.
75
- */
76
- compareTo(other) {
77
- const thisXid = this.xid().toString();
78
- const otherXid = other.xid().toString();
79
- return thisXid.localeCompare(otherXid);
80
- }
81
- };
82
- /**
83
- * Parse a XID envelope from a UR string.
84
- *
85
- * Port of `parse_xid_envelope()` from proposed_participant.rs lines 39-60.
86
- */
87
- function parseXidEnvelope(input) {
88
- const trimmed = input.trim();
89
- if (trimmed.length === 0) throw new Error("XID document is required");
90
- const ur = UR.fromURString(trimmed);
91
- const urType = ur.urTypeStr();
92
- if (urType !== "xid" && urType !== "envelope") throw new Error(`Expected a ur:xid document, found ur:${urType}`);
93
- const envelopeCbor = ur.cbor();
94
- let envelope;
95
- try {
96
- envelope = Envelope.fromTaggedCbor(envelopeCbor);
97
- } catch {
98
- envelope = Envelope.fromUntaggedCbor(envelopeCbor);
99
- }
100
- const document = XIDDocument.fromEnvelope(envelope, void 0, XIDVerifySignature.Inception);
101
- return [envelope, document];
102
- }
103
- //#endregion
104
7
  //#region src/dkg/group-invite.ts
105
8
  /**
106
9
  * Copyright © 2023-2026 Blockchain Commons, LLC
@@ -311,7 +214,7 @@ var DkgInvitation = class DkgInvitation {
311
214
  const recipientPrivateKeys = recipient.inceptionPrivateKeys();
312
215
  if (recipientPrivateKeys === void 0) throw new Error("Recipient XID document has no inception private keys");
313
216
  const sealedRequest = SealedRequest.tryFromEnvelope(invite, void 0, now, recipientPrivateKeys);
314
- if (expectedSender !== void 0 && sealedRequest.sender().xid() !== expectedSender.xid()) throw new Error("Invite sender does not match expected sender");
217
+ if (expectedSender !== void 0 && !sealedRequest.sender().xid().equals(expectedSender.xid())) throw new Error("Invite sender does not match expected sender");
315
218
  if (!sealedRequest.request().function().equals(Function.fromString("dkgInvite"))) throw new Error("Unexpected invite function");
316
219
  const validUntil = sealedRequest.extractObjectForParameter("validUntil");
317
220
  if (validUntil <= now) throw new Error("Invitation expired");
@@ -324,13 +227,13 @@ var DkgInvitation = class DkgInvitation {
324
227
  if (minSigners > participantObjects.length) throw new Error("min_signers exceeds participant count");
325
228
  for (const participant of participantObjects) {
326
229
  const xidDocumentEnvelope = participant.tryUnwrap();
327
- if (XIDDocument.fromEnvelope(xidDocumentEnvelope, void 0, XIDVerifySignature.Inception).xid() !== recipientXid) continue;
230
+ if (!XIDDocument.fromEnvelope(xidDocumentEnvelope, void 0, XIDVerifySignature.Inception).xid().equals(recipientXid)) continue;
328
231
  return new DkgInvitation(participant.objectForPredicate("response_arid").decryptToRecipient(recipientPrivateKeys).extractSubject((cbor) => ARID.fromTaggedCbor(cbor)), validUntil, sealedRequest.sender(), sealedRequest.request().id(), sealedRequest.peerContinuation(), minSigners, charter, groupId);
329
232
  }
330
233
  throw new Error("Recipient not found in invite");
331
234
  }
332
235
  };
333
236
  //#endregion
334
- export { DkgInvitation, DkgInvite, DkgProposedParticipant, accepted, declined };
237
+ export { DkgInvitation, DkgInvite, DkgProposedParticipant, accepted, compareXidBytes, declined };
335
238
 
336
239
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["EnvelopeFunction"],"sources":["../../src/dkg/proposed-participant.ts","../../src/dkg/group-invite.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG Proposed Participant.\n *\n * Port of dkg/proposed_participant.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { type ARID, type XID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { XIDDocument, XIDVerifySignature } from \"@bcts/xid\";\n\n/**\n * A proposed participant in a DKG session.\n *\n * Port of `struct DkgProposedParticipant` from proposed_participant.rs lines 8-13.\n */\nexport class DkgProposedParticipant {\n private readonly _urString: string;\n private readonly _envelope: Envelope;\n private readonly _document: XIDDocument;\n private readonly _responseArid: ARID;\n\n private constructor(\n urString: string,\n envelope: Envelope,\n document: XIDDocument,\n responseArid: ARID,\n ) {\n this._urString = urString;\n this._envelope = envelope;\n this._document = document;\n this._responseArid = responseArid;\n }\n\n /**\n * Create a new DkgProposedParticipant from a UR string and response ARID.\n *\n * Port of `DkgProposedParticipant::new()` from proposed_participant.rs lines 22-26.\n */\n static create(urString: string, responseArid: ARID): DkgProposedParticipant {\n const [envelope, document] = parseXidEnvelope(urString);\n return new DkgProposedParticipant(urString, envelope, document, responseArid);\n }\n\n /**\n * Get the XID of this participant.\n *\n * Port of `DkgProposedParticipant::xid()` from proposed_participant.rs line 28.\n */\n xid(): XID {\n return this._document.xid();\n }\n\n /**\n * Get the XID document of this participant.\n *\n * Port of `DkgProposedParticipant::xid_document()` from proposed_participant.rs line 30.\n */\n xidDocument(): XIDDocument {\n return this._document;\n }\n\n /**\n * Get the UR string of the XID document.\n *\n * Port of `DkgProposedParticipant::xid_document_ur()` from proposed_participant.rs line 32.\n */\n xidDocumentUr(): string {\n return this._urString;\n }\n\n /**\n * Get the envelope containing the XID document.\n *\n * Port of `DkgProposedParticipant::xid_document_envelope()` from proposed_participant.rs line 34.\n */\n xidDocumentEnvelope(): Envelope {\n return this._envelope;\n }\n\n /**\n * Get the response ARID for this participant.\n *\n * Port of `DkgProposedParticipant::response_arid()` from proposed_participant.rs line 36.\n */\n responseArid(): ARID {\n return this._responseArid;\n }\n\n /**\n * Compare participants by XID for sorting.\n */\n compareTo(other: DkgProposedParticipant): number {\n const thisXid = this.xid().toString();\n const otherXid = other.xid().toString();\n return thisXid.localeCompare(otherXid);\n }\n}\n\n/**\n * Parse a XID envelope from a UR string.\n *\n * Port of `parse_xid_envelope()` from proposed_participant.rs lines 39-60.\n */\nfunction parseXidEnvelope(input: string): [Envelope, XIDDocument] {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"XID document is required\");\n }\n\n const ur = UR.fromURString(trimmed);\n const urType = ur.urTypeStr();\n if (urType !== \"xid\" && urType !== \"envelope\") {\n throw new Error(`Expected a ur:xid document, found ur:${urType}`);\n }\n\n const envelopeCbor = ur.cbor();\n // Try tagged CBOR first, then untagged\n let envelope: Envelope;\n try {\n envelope = Envelope.fromTaggedCbor(envelopeCbor);\n } catch {\n envelope = Envelope.fromUntaggedCbor(envelopeCbor);\n }\n\n const document = XIDDocument.fromEnvelope(envelope, undefined, XIDVerifySignature.Inception);\n\n return [envelope, document];\n}\n","/**\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 if (expectedSender !== undefined && sealedRequest.sender().xid() !== expectedSender.xid()) {\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 if (xidDocument.xid() !== 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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"}