@bcts/frost-hubert 1.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +48 -0
- package/README.md +35 -0
- package/dist/bin/frost.cjs +109 -0
- package/dist/bin/frost.cjs.map +1 -0
- package/dist/bin/frost.d.cts +1 -0
- package/dist/bin/frost.d.mts +1 -0
- package/dist/bin/frost.mjs +109 -0
- package/dist/bin/frost.mjs.map +1 -0
- package/dist/chunk-CQwRTUmo.cjs +53 -0
- package/dist/chunk-D3JzZLW2.mjs +21 -0
- package/dist/cmd/index.cjs +45 -0
- package/dist/cmd/index.d.cts +4 -0
- package/dist/cmd/index.d.mts +4 -0
- package/dist/cmd/index.mjs +7 -0
- package/dist/cmd-C8pmNd28.mjs +4664 -0
- package/dist/cmd-C8pmNd28.mjs.map +1 -0
- package/dist/cmd-CxUgryx_.cjs +4803 -0
- package/dist/cmd-CxUgryx_.cjs.map +1 -0
- package/dist/dkg/index.cjs +7 -0
- package/dist/dkg/index.d.cts +2 -0
- package/dist/dkg/index.d.mts +2 -0
- package/dist/dkg/index.mjs +3 -0
- package/dist/dkg-D4RcblWl.cjs +364 -0
- package/dist/dkg-D4RcblWl.cjs.map +1 -0
- package/dist/dkg-DqGrAV81.mjs +334 -0
- package/dist/dkg-DqGrAV81.mjs.map +1 -0
- package/dist/frost/index.cjs +37 -0
- package/dist/frost/index.d.cts +207 -0
- package/dist/frost/index.d.cts.map +1 -0
- package/dist/frost/index.d.mts +207 -0
- package/dist/frost/index.d.mts.map +1 -0
- package/dist/frost/index.mjs +3 -0
- package/dist/frost-CMH1K0Cw.cjs +511 -0
- package/dist/frost-CMH1K0Cw.cjs.map +1 -0
- package/dist/frost-Csp0IOrd.mjs +326 -0
- package/dist/frost-Csp0IOrd.mjs.map +1 -0
- package/dist/index-BGVoWW5P.d.cts +172 -0
- package/dist/index-BGVoWW5P.d.cts.map +1 -0
- package/dist/index-BJeUYrdE.d.mts +396 -0
- package/dist/index-BJeUYrdE.d.mts.map +1 -0
- package/dist/index-ByMDUYKw.d.mts +1098 -0
- package/dist/index-ByMDUYKw.d.mts.map +1 -0
- package/dist/index-DejLkr_F.d.mts +172 -0
- package/dist/index-DejLkr_F.d.mts.map +1 -0
- package/dist/index-Dib1OE-e.d.cts +1098 -0
- package/dist/index-Dib1OE-e.d.cts.map +1 -0
- package/dist/index-DnvBKgec.d.cts +396 -0
- package/dist/index-DnvBKgec.d.cts.map +1 -0
- package/dist/index.cjs +85 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +15 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +24 -0
- package/dist/index.mjs.map +1 -0
- package/dist/registry/index.cjs +13 -0
- package/dist/registry/index.d.cts +2 -0
- package/dist/registry/index.d.mts +2 -0
- package/dist/registry/index.mjs +3 -0
- package/dist/registry-CBjRRqNv.mjs +144 -0
- package/dist/registry-CBjRRqNv.mjs.map +1 -0
- package/dist/registry-CWp2amuo.mjs +789 -0
- package/dist/registry-CWp2amuo.mjs.map +1 -0
- package/dist/registry-D5yh293y.cjs +857 -0
- package/dist/registry-D5yh293y.cjs.map +1 -0
- package/dist/registry-DNUNW6SH.cjs +163 -0
- package/dist/registry-DNUNW6SH.cjs.map +1 -0
- package/package.json +119 -0
- package/src/bin/frost.ts +218 -0
- package/src/cmd/busy.ts +64 -0
- package/src/cmd/check.ts +20 -0
- package/src/cmd/common.ts +40 -0
- package/src/cmd/dkg/common.ts +275 -0
- package/src/cmd/dkg/coordinator/finalize.ts +592 -0
- package/src/cmd/dkg/coordinator/index.ts +12 -0
- package/src/cmd/dkg/coordinator/invite.ts +217 -0
- package/src/cmd/dkg/coordinator/round1.ts +889 -0
- package/src/cmd/dkg/coordinator/round2.ts +959 -0
- package/src/cmd/dkg/index.ts +11 -0
- package/src/cmd/dkg/participant/finalize.ts +575 -0
- package/src/cmd/dkg/participant/index.ts +12 -0
- package/src/cmd/dkg/participant/receive.ts +348 -0
- package/src/cmd/dkg/participant/round1.ts +464 -0
- package/src/cmd/dkg/participant/round2.ts +627 -0
- package/src/cmd/index.ts +18 -0
- package/src/cmd/parallel.ts +334 -0
- package/src/cmd/registry/index.ts +88 -0
- package/src/cmd/registry/owner/index.ts +9 -0
- package/src/cmd/registry/owner/set.ts +70 -0
- package/src/cmd/registry/participant/add.ts +70 -0
- package/src/cmd/registry/participant/index.ts +9 -0
- package/src/cmd/sign/common.ts +108 -0
- package/src/cmd/sign/coordinator/index.ts +11 -0
- package/src/cmd/sign/coordinator/invite.ts +431 -0
- package/src/cmd/sign/coordinator/round1.ts +751 -0
- package/src/cmd/sign/coordinator/round2.ts +836 -0
- package/src/cmd/sign/index.ts +11 -0
- package/src/cmd/sign/participant/finalize.ts +823 -0
- package/src/cmd/sign/participant/index.ts +12 -0
- package/src/cmd/sign/participant/receive.ts +378 -0
- package/src/cmd/sign/participant/round1.ts +479 -0
- package/src/cmd/sign/participant/round2.ts +748 -0
- package/src/cmd/storage.ts +116 -0
- package/src/dkg/group-invite.ts +414 -0
- package/src/dkg/index.ts +10 -0
- package/src/dkg/proposed-participant.ts +132 -0
- package/src/frost/index.ts +456 -0
- package/src/index.ts +45 -0
- package/src/registry/group-record.ts +392 -0
- package/src/registry/index.ts +12 -0
- package/src/registry/owner-record.ts +146 -0
- package/src/registry/participant-record.ts +186 -0
- package/src/registry/registry-impl.ts +364 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DKG coordinator invite command.
|
|
3
|
+
*
|
|
4
|
+
* Port of cmd/dkg/coordinator/invite.rs from frost-hubert-rust.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import * as fs from "node:fs";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
|
|
12
|
+
import { ARID, type XID } from "@bcts/components";
|
|
13
|
+
|
|
14
|
+
import { DkgInvite } from "../../../dkg/index.js";
|
|
15
|
+
import {
|
|
16
|
+
GroupParticipant,
|
|
17
|
+
GroupRecord,
|
|
18
|
+
PendingRequests,
|
|
19
|
+
Registry,
|
|
20
|
+
resolveRegistryPath,
|
|
21
|
+
} from "../../../registry/index.js";
|
|
22
|
+
import { putWithIndicator } from "../../busy.js";
|
|
23
|
+
import { type StorageClient } from "../../storage.js";
|
|
24
|
+
import { dkgStateDir, resolveParticipants, resolveSender } from "../common.js";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Options for the DKG invite command.
|
|
28
|
+
*/
|
|
29
|
+
export interface DkgInviteOptions {
|
|
30
|
+
registryPath?: string;
|
|
31
|
+
minSigners?: number;
|
|
32
|
+
charter: string;
|
|
33
|
+
validDays: number;
|
|
34
|
+
participantNames: string[];
|
|
35
|
+
verbose?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Result of the DKG invite command.
|
|
40
|
+
*/
|
|
41
|
+
export interface DkgInviteResult {
|
|
42
|
+
groupId: ARID;
|
|
43
|
+
requestId: ARID;
|
|
44
|
+
envelopeUr: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Internal data structure for building an invite.
|
|
49
|
+
*
|
|
50
|
+
* Port of `InviteData` struct from cmd/dkg/coordinator/invite.rs lines 122-126.
|
|
51
|
+
*/
|
|
52
|
+
interface InviteData {
|
|
53
|
+
invite: DkgInvite;
|
|
54
|
+
participantXids: XID[];
|
|
55
|
+
pendingRequests: PendingRequests;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Build the DKG invite with validation.
|
|
60
|
+
*
|
|
61
|
+
* Port of `build_invite()` from cmd/dkg/coordinator/invite.rs lines 128-181.
|
|
62
|
+
*/
|
|
63
|
+
function buildInvite(
|
|
64
|
+
registry: Registry,
|
|
65
|
+
minSignersArg: number | undefined,
|
|
66
|
+
charter: string,
|
|
67
|
+
participantNames: string[],
|
|
68
|
+
validDays: number,
|
|
69
|
+
): InviteData {
|
|
70
|
+
// Resolve participants using the common utility
|
|
71
|
+
const resolved = resolveParticipants(registry, participantNames);
|
|
72
|
+
const participantDocs: string[] = resolved.map(([, record]) => record.xidDocumentUr());
|
|
73
|
+
const participantXids: XID[] = resolved.map(([xid]) => xid);
|
|
74
|
+
|
|
75
|
+
// These are the ARIDs where participants will post their invite responses
|
|
76
|
+
const collectFromArids: ARID[] = participantDocs.map(() => ARID.new());
|
|
77
|
+
|
|
78
|
+
// Build pending_requests: coordinator will collect invite responses from these ARIDs
|
|
79
|
+
const pendingRequests = new PendingRequests();
|
|
80
|
+
for (let i = 0; i < participantXids.length; i++) {
|
|
81
|
+
pendingRequests.addCollectOnly(participantXids[i], collectFromArids[i]);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Validate participant count
|
|
85
|
+
const participantCount = participantDocs.length;
|
|
86
|
+
if (participantCount < 2) {
|
|
87
|
+
throw new Error("At least two participants are required for a DKG invite");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Validate and default minSigners
|
|
91
|
+
const minSigners = minSignersArg ?? participantCount;
|
|
92
|
+
if (minSigners < 2) {
|
|
93
|
+
throw new Error("--min-signers must be at least 2");
|
|
94
|
+
}
|
|
95
|
+
if (minSigners > participantCount) {
|
|
96
|
+
throw new Error("--min-signers cannot exceed participant count");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Get sender (registry owner)
|
|
100
|
+
const sender = resolveSender(registry);
|
|
101
|
+
|
|
102
|
+
// Calculate dates
|
|
103
|
+
const now = new Date();
|
|
104
|
+
const validUntil = new Date(Date.now() + validDays * 24 * 60 * 60 * 1000);
|
|
105
|
+
|
|
106
|
+
// Create the invite
|
|
107
|
+
const invite = DkgInvite.create(
|
|
108
|
+
ARID.new(), // requestId
|
|
109
|
+
sender,
|
|
110
|
+
ARID.new(), // groupId
|
|
111
|
+
now,
|
|
112
|
+
validUntil,
|
|
113
|
+
minSigners,
|
|
114
|
+
charter,
|
|
115
|
+
participantDocs,
|
|
116
|
+
collectFromArids,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
return { invite, participantXids, pendingRequests };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Execute the DKG invite command.
|
|
124
|
+
*
|
|
125
|
+
* Port of `invite()` from cmd/dkg/coordinator/invite.rs.
|
|
126
|
+
*/
|
|
127
|
+
export async function invite(
|
|
128
|
+
client: StorageClient,
|
|
129
|
+
options: DkgInviteOptions,
|
|
130
|
+
cwd: string,
|
|
131
|
+
): Promise<DkgInviteResult> {
|
|
132
|
+
const registryPath = resolveRegistryPath(options.registryPath, cwd);
|
|
133
|
+
const registry = Registry.load(registryPath);
|
|
134
|
+
|
|
135
|
+
// Build the invite with validation
|
|
136
|
+
const inviteData = buildInvite(
|
|
137
|
+
registry,
|
|
138
|
+
options.minSigners,
|
|
139
|
+
options.charter,
|
|
140
|
+
options.participantNames,
|
|
141
|
+
options.validDays,
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const { invite: dkgInvite, participantXids, pendingRequests } = inviteData;
|
|
145
|
+
const groupId = dkgInvite.groupId();
|
|
146
|
+
const requestId = dkgInvite.requestId();
|
|
147
|
+
|
|
148
|
+
// Create sealed envelope
|
|
149
|
+
const envelope = dkgInvite.toEnvelope();
|
|
150
|
+
|
|
151
|
+
// Send to storage
|
|
152
|
+
const startArid = ARID.new();
|
|
153
|
+
await putWithIndicator(
|
|
154
|
+
client,
|
|
155
|
+
startArid,
|
|
156
|
+
envelope,
|
|
157
|
+
"Sending DKG invite",
|
|
158
|
+
options.verbose ?? false,
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
// Save group record to registry
|
|
162
|
+
const owner = registry.owner();
|
|
163
|
+
if (!owner) {
|
|
164
|
+
throw new Error("Registry owner is required to issue invites");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const coordinator = new GroupParticipant(owner.xid());
|
|
168
|
+
const groupParticipants = participantXids.map((xid) => new GroupParticipant(xid));
|
|
169
|
+
|
|
170
|
+
const groupRecord = new GroupRecord(
|
|
171
|
+
options.charter,
|
|
172
|
+
dkgInvite.minSigners(),
|
|
173
|
+
coordinator,
|
|
174
|
+
groupParticipants,
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// Track pending requests
|
|
178
|
+
groupRecord.setPendingRequests(pendingRequests);
|
|
179
|
+
|
|
180
|
+
// Use recordGroup() for proper merge behavior
|
|
181
|
+
registry.recordGroup(groupId, groupRecord);
|
|
182
|
+
registry.save(registryPath);
|
|
183
|
+
|
|
184
|
+
// Save invite state
|
|
185
|
+
const stateDir = dkgStateDir(registryPath, groupId.hex());
|
|
186
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
187
|
+
|
|
188
|
+
const inviteState: {
|
|
189
|
+
group: string;
|
|
190
|
+
request_id: string;
|
|
191
|
+
start_arid: string;
|
|
192
|
+
valid_until: string;
|
|
193
|
+
participants: { xid: string; response_arid: string }[];
|
|
194
|
+
} = {
|
|
195
|
+
group: groupId.urString(),
|
|
196
|
+
request_id: requestId.urString(),
|
|
197
|
+
start_arid: startArid.urString(),
|
|
198
|
+
valid_until: dkgInvite.validUntil().toISOString(),
|
|
199
|
+
participants: dkgInvite.participants().map((p) => ({
|
|
200
|
+
xid: p.xid().urString(),
|
|
201
|
+
response_arid: p.responseArid().urString(),
|
|
202
|
+
})),
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
fs.writeFileSync(path.join(stateDir, "invite.json"), JSON.stringify(inviteState, null, 2));
|
|
206
|
+
|
|
207
|
+
if (options.verbose === true) {
|
|
208
|
+
console.log(`Group ID: ${groupId.urString()}`);
|
|
209
|
+
console.log(`Start ARID: ${startArid.urString()}`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
groupId,
|
|
214
|
+
requestId,
|
|
215
|
+
envelopeUr: envelope.urString(),
|
|
216
|
+
};
|
|
217
|
+
}
|