@kubun/plugin-p2p 0.12.1 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/context/group.js +3 -0
- package/lib/context/join.js +3 -0
- package/lib/context/peer.js +7 -2
- package/lib/context/sync.js +63 -5
- package/lib/context/types.d.ts +14 -1
- package/lib/context/types.js +12 -0
- package/lib/groups/access-default-apply.d.ts +42 -0
- package/lib/groups/access-default-apply.js +75 -0
- package/lib/groups/broadcast-codec.d.ts +1 -1
- package/lib/groups/broadcast-message.d.ts +240 -0
- package/lib/groups/broadcast-message.js +1 -0
- package/lib/groups/broadcast.d.ts +19 -266
- package/lib/groups/broadcast.js +30 -204
- package/lib/groups/credential-apply.d.ts +82 -0
- package/lib/groups/credential-apply.js +410 -0
- package/lib/groups/credential-grant-token.d.ts +42 -0
- package/lib/groups/credential-grant-token.js +51 -0
- package/lib/groups/credential-grant.d.ts +98 -0
- package/lib/groups/credential-grant.js +165 -0
- package/lib/groups/group-handlers.js +25 -2
- package/lib/groups/group-mls.d.ts +5 -0
- package/lib/groups/group-mls.js +4 -1
- package/lib/groups/group-peer-manager.d.ts +7 -1
- package/lib/groups/group-peer-manager.js +44 -1
- package/lib/groups/group-protocols.d.ts +227 -0
- package/lib/groups/group-protocols.js +146 -0
- package/lib/groups/join-utils.d.ts +5 -0
- package/lib/groups/join-utils.js +5 -1
- package/lib/groups/ledger-adopt.d.ts +84 -0
- package/lib/groups/ledger-adopt.js +142 -0
- package/lib/groups/ledger-commit-fold.d.ts +3 -1
- package/lib/groups/ledger-commit-fold.js +3 -0
- package/lib/groups/ledger-ingest.d.ts +23 -1
- package/lib/groups/ledger-ingest.js +30 -1
- package/lib/groups/manager.d.ts +5 -0
- package/lib/groups/manager.js +6 -1
- package/lib/groups/peer-presence.d.ts +9 -2
- package/lib/groups/peer-presence.js +14 -2
- package/lib/groups/peer-selection.d.ts +9 -0
- package/lib/groups/peer-selection.js +10 -0
- package/lib/hub/wiring.d.ts +6 -1
- package/lib/hub/wiring.js +2 -1
- package/lib/index.d.ts +5 -1
- package/lib/index.js +58 -6
- package/lib/peer/blob-fetch.d.ts +45 -0
- package/lib/peer/blob-fetch.js +89 -0
- package/lib/peer/blob-handlers.d.ts +11 -0
- package/lib/peer/blob-handlers.js +123 -0
- package/lib/peer/controller-fetch.d.ts +6 -0
- package/lib/peer/controller-fetch.js +59 -0
- package/lib/peer/controller-handlers.d.ts +10 -0
- package/lib/peer/controller-handlers.js +28 -0
- package/lib/protocol.d.ts +279 -0
- package/lib/protocol.js +358 -0
- package/lib/sync/access-default-sender.d.ts +1 -1
- package/lib/sync/broadcast-queue.d.ts +1 -1
- package/lib/sync/forwarder.d.ts +1 -1
- package/lib/sync/handlers.js +98 -1
- package/lib/sync/sync-manager.d.ts +10 -1
- package/lib/sync/sync-manager.js +24 -2
- package/lib/types.d.ts +18 -0
- package/package.json +44 -35
package/lib/protocol.d.ts
CHANGED
|
@@ -203,6 +203,170 @@ export declare const syncProtocol: {
|
|
|
203
203
|
readonly additionalProperties: false;
|
|
204
204
|
};
|
|
205
205
|
};
|
|
206
|
+
readonly 'sync/reconcile-credentials': {
|
|
207
|
+
readonly type: "request";
|
|
208
|
+
readonly param: {
|
|
209
|
+
readonly type: "object";
|
|
210
|
+
readonly properties: {
|
|
211
|
+
readonly held: {
|
|
212
|
+
readonly type: "array";
|
|
213
|
+
readonly items: {
|
|
214
|
+
readonly type: "object";
|
|
215
|
+
readonly properties: {
|
|
216
|
+
readonly subjectKind: {
|
|
217
|
+
readonly type: "string";
|
|
218
|
+
readonly enum: readonly ["key", "wrapping", "entry"];
|
|
219
|
+
};
|
|
220
|
+
readonly subjectID: {
|
|
221
|
+
readonly type: "string";
|
|
222
|
+
};
|
|
223
|
+
readonly opHash: {
|
|
224
|
+
readonly type: "string";
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
readonly required: readonly ["subjectKind", "subjectID", "opHash"];
|
|
228
|
+
readonly additionalProperties: false;
|
|
229
|
+
};
|
|
230
|
+
readonly description: "Signed subject states the caller holds, for updates and revocation GC";
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
readonly required: readonly ["held"];
|
|
234
|
+
readonly additionalProperties: false;
|
|
235
|
+
};
|
|
236
|
+
readonly result: {
|
|
237
|
+
readonly type: "object";
|
|
238
|
+
readonly properties: {
|
|
239
|
+
readonly bundles: {
|
|
240
|
+
readonly type: "array";
|
|
241
|
+
readonly items: {
|
|
242
|
+
readonly type: "object";
|
|
243
|
+
readonly properties: {
|
|
244
|
+
readonly keyID: {
|
|
245
|
+
readonly type: "string";
|
|
246
|
+
};
|
|
247
|
+
readonly keyVersion: {
|
|
248
|
+
readonly type: "number";
|
|
249
|
+
};
|
|
250
|
+
readonly suite: {
|
|
251
|
+
readonly type: "number";
|
|
252
|
+
};
|
|
253
|
+
readonly ownerDID: {
|
|
254
|
+
readonly type: "string";
|
|
255
|
+
};
|
|
256
|
+
readonly keyOp: {
|
|
257
|
+
readonly type: "string";
|
|
258
|
+
};
|
|
259
|
+
readonly keyBranches: {
|
|
260
|
+
readonly type: "array";
|
|
261
|
+
readonly items: {
|
|
262
|
+
readonly type: "string";
|
|
263
|
+
};
|
|
264
|
+
readonly description: "The proven key-op JWTs that introduced this key version's branches.";
|
|
265
|
+
};
|
|
266
|
+
readonly wrapping: {
|
|
267
|
+
readonly type: "object";
|
|
268
|
+
readonly properties: {
|
|
269
|
+
readonly wrappingID: {
|
|
270
|
+
readonly type: "string";
|
|
271
|
+
};
|
|
272
|
+
readonly factors: {
|
|
273
|
+
readonly type: "array";
|
|
274
|
+
readonly items: {
|
|
275
|
+
readonly type: "object";
|
|
276
|
+
readonly properties: {
|
|
277
|
+
readonly kind: {
|
|
278
|
+
readonly type: "string";
|
|
279
|
+
};
|
|
280
|
+
readonly params: {
|
|
281
|
+
readonly type: "object";
|
|
282
|
+
readonly additionalProperties: true;
|
|
283
|
+
};
|
|
284
|
+
};
|
|
285
|
+
readonly required: readonly ["kind", "params"];
|
|
286
|
+
readonly additionalProperties: false;
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
readonly iv: {
|
|
290
|
+
readonly type: "string";
|
|
291
|
+
};
|
|
292
|
+
readonly wrappedKey: {
|
|
293
|
+
readonly type: "string";
|
|
294
|
+
};
|
|
295
|
+
readonly recipientDID: {
|
|
296
|
+
readonly type: "string";
|
|
297
|
+
};
|
|
298
|
+
readonly op: {
|
|
299
|
+
readonly type: "string";
|
|
300
|
+
};
|
|
301
|
+
};
|
|
302
|
+
readonly required: readonly ["wrappingID", "factors", "iv", "wrappedKey", "recipientDID", "op"];
|
|
303
|
+
readonly additionalProperties: false;
|
|
304
|
+
};
|
|
305
|
+
readonly entries: {
|
|
306
|
+
readonly type: "array";
|
|
307
|
+
readonly items: {
|
|
308
|
+
readonly type: "object";
|
|
309
|
+
readonly properties: {
|
|
310
|
+
readonly entryID: {
|
|
311
|
+
readonly type: "string";
|
|
312
|
+
};
|
|
313
|
+
readonly iv: {
|
|
314
|
+
readonly type: "string";
|
|
315
|
+
};
|
|
316
|
+
readonly ciphertext: {
|
|
317
|
+
readonly type: "string";
|
|
318
|
+
};
|
|
319
|
+
readonly hlc: {
|
|
320
|
+
readonly type: "string";
|
|
321
|
+
};
|
|
322
|
+
readonly op: {
|
|
323
|
+
readonly type: "string";
|
|
324
|
+
};
|
|
325
|
+
};
|
|
326
|
+
readonly required: readonly ["entryID", "iv", "ciphertext", "hlc", "op"];
|
|
327
|
+
readonly additionalProperties: false;
|
|
328
|
+
};
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
readonly required: readonly ["keyID", "keyVersion", "suite", "ownerDID", "keyOp", "keyBranches", "wrapping", "entries"];
|
|
332
|
+
readonly additionalProperties: false;
|
|
333
|
+
};
|
|
334
|
+
readonly description: "The caller's recipient-scoped catch-up bundles (missed grants and entry top-ups)";
|
|
335
|
+
};
|
|
336
|
+
readonly tombstones: {
|
|
337
|
+
readonly type: "array";
|
|
338
|
+
readonly items: {
|
|
339
|
+
readonly type: "object";
|
|
340
|
+
readonly properties: {
|
|
341
|
+
readonly keyID: {
|
|
342
|
+
readonly type: "string";
|
|
343
|
+
};
|
|
344
|
+
readonly authorDID: {
|
|
345
|
+
readonly type: "string";
|
|
346
|
+
};
|
|
347
|
+
readonly hlc: {
|
|
348
|
+
readonly type: "string";
|
|
349
|
+
};
|
|
350
|
+
readonly opJWT: {
|
|
351
|
+
readonly type: "string";
|
|
352
|
+
};
|
|
353
|
+
readonly opHash: {
|
|
354
|
+
readonly type: "string";
|
|
355
|
+
};
|
|
356
|
+
readonly subjectID: {
|
|
357
|
+
readonly type: "string";
|
|
358
|
+
};
|
|
359
|
+
};
|
|
360
|
+
readonly required: readonly ["keyID", "authorDID", "hlc", "opJWT", "opHash", "subjectID"];
|
|
361
|
+
readonly additionalProperties: false;
|
|
362
|
+
};
|
|
363
|
+
readonly description: "Tombstones for advertised held IDs that are now revoked (GC)";
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
readonly required: readonly ["bundles", "tombstones"];
|
|
367
|
+
readonly additionalProperties: false;
|
|
368
|
+
};
|
|
369
|
+
};
|
|
206
370
|
};
|
|
207
371
|
export type SyncProtocol = typeof syncProtocol;
|
|
208
372
|
/**
|
|
@@ -406,6 +570,113 @@ export declare const peerProtocol: {
|
|
|
406
570
|
readonly additionalProperties: false;
|
|
407
571
|
};
|
|
408
572
|
};
|
|
573
|
+
readonly 'blob/query-haves': {
|
|
574
|
+
readonly type: "request";
|
|
575
|
+
readonly param: {
|
|
576
|
+
readonly type: "object";
|
|
577
|
+
readonly properties: {
|
|
578
|
+
readonly attachmentIDs: {
|
|
579
|
+
readonly type: "array";
|
|
580
|
+
readonly items: {
|
|
581
|
+
readonly type: "string";
|
|
582
|
+
};
|
|
583
|
+
readonly description: "Candidate AttachmentIDs the caller wants to locate";
|
|
584
|
+
};
|
|
585
|
+
};
|
|
586
|
+
readonly required: readonly ["attachmentIDs"];
|
|
587
|
+
readonly additionalProperties: false;
|
|
588
|
+
};
|
|
589
|
+
readonly result: {
|
|
590
|
+
readonly type: "object";
|
|
591
|
+
readonly properties: {
|
|
592
|
+
readonly have: {
|
|
593
|
+
readonly type: "array";
|
|
594
|
+
readonly items: {
|
|
595
|
+
readonly type: "string";
|
|
596
|
+
};
|
|
597
|
+
readonly description: "The subset this node holds with all bytes local";
|
|
598
|
+
};
|
|
599
|
+
};
|
|
600
|
+
readonly required: readonly ["have"];
|
|
601
|
+
readonly additionalProperties: false;
|
|
602
|
+
};
|
|
603
|
+
};
|
|
604
|
+
readonly 'blob/manifest': {
|
|
605
|
+
readonly type: "request";
|
|
606
|
+
readonly param: {
|
|
607
|
+
readonly type: "object";
|
|
608
|
+
readonly properties: {
|
|
609
|
+
readonly attachmentID: {
|
|
610
|
+
readonly type: "string";
|
|
611
|
+
};
|
|
612
|
+
readonly delegationTokens: {
|
|
613
|
+
readonly type: "array";
|
|
614
|
+
readonly items: {
|
|
615
|
+
readonly type: "string";
|
|
616
|
+
};
|
|
617
|
+
readonly description: "The caller's read-delegation tokens, for scope authorization";
|
|
618
|
+
};
|
|
619
|
+
};
|
|
620
|
+
readonly required: readonly ["attachmentID", "delegationTokens"];
|
|
621
|
+
readonly additionalProperties: false;
|
|
622
|
+
};
|
|
623
|
+
readonly result: {
|
|
624
|
+
readonly type: "object";
|
|
625
|
+
readonly properties: {
|
|
626
|
+
readonly chunkSize: {
|
|
627
|
+
readonly type: "number";
|
|
628
|
+
};
|
|
629
|
+
readonly chunkCount: {
|
|
630
|
+
readonly type: "number";
|
|
631
|
+
};
|
|
632
|
+
readonly contentLength: {
|
|
633
|
+
readonly type: "number";
|
|
634
|
+
};
|
|
635
|
+
readonly chunkDigests: {
|
|
636
|
+
readonly type: "array";
|
|
637
|
+
readonly items: {
|
|
638
|
+
readonly type: "string";
|
|
639
|
+
};
|
|
640
|
+
readonly description: "Per-chunk blake3 digests, base64, ordered by index";
|
|
641
|
+
};
|
|
642
|
+
readonly capability: {
|
|
643
|
+
readonly type: "string";
|
|
644
|
+
readonly description: "Short-TTL signed fetch capability for the data-plane GET";
|
|
645
|
+
};
|
|
646
|
+
};
|
|
647
|
+
readonly required: readonly ["chunkSize", "chunkCount", "contentLength", "chunkDigests", "capability"];
|
|
648
|
+
readonly additionalProperties: false;
|
|
649
|
+
};
|
|
650
|
+
};
|
|
651
|
+
readonly 'controller/get-log': {
|
|
652
|
+
readonly type: "request";
|
|
653
|
+
readonly param: {
|
|
654
|
+
readonly type: "object";
|
|
655
|
+
readonly properties: {
|
|
656
|
+
readonly did: {
|
|
657
|
+
readonly type: "string";
|
|
658
|
+
readonly description: "The did:kokuin: controller whose log is requested";
|
|
659
|
+
};
|
|
660
|
+
};
|
|
661
|
+
readonly required: readonly ["did"];
|
|
662
|
+
readonly additionalProperties: false;
|
|
663
|
+
};
|
|
664
|
+
readonly result: {
|
|
665
|
+
readonly type: "object";
|
|
666
|
+
readonly properties: {
|
|
667
|
+
readonly events: {
|
|
668
|
+
readonly type: "array";
|
|
669
|
+
readonly items: {
|
|
670
|
+
readonly type: "object";
|
|
671
|
+
readonly additionalProperties: true;
|
|
672
|
+
};
|
|
673
|
+
readonly description: "The controller's signed key-event log";
|
|
674
|
+
};
|
|
675
|
+
};
|
|
676
|
+
readonly required: readonly ["events"];
|
|
677
|
+
readonly additionalProperties: false;
|
|
678
|
+
};
|
|
679
|
+
};
|
|
409
680
|
};
|
|
410
681
|
export type PeerProtocol = typeof peerProtocol;
|
|
411
682
|
export type PeerGroupsResult = FromSchema<PeerProtocol['peer/groups']['result']>;
|
|
@@ -416,12 +687,20 @@ export type GroupInviteParam = FromSchema<PeerProtocol['group/invite']['param']>
|
|
|
416
687
|
export type GroupInviteResult = FromSchema<PeerProtocol['group/invite']['result']>;
|
|
417
688
|
export type PushControlParam = FromSchema<PeerProtocol['group/push-control']['param']>;
|
|
418
689
|
export type PushControlResult = FromSchema<PeerProtocol['group/push-control']['result']>;
|
|
690
|
+
export type BlobQueryHavesParam = FromSchema<PeerProtocol['blob/query-haves']['param']>;
|
|
691
|
+
export type BlobQueryHavesResult = FromSchema<PeerProtocol['blob/query-haves']['result']>;
|
|
692
|
+
export type BlobManifestParam = FromSchema<PeerProtocol['blob/manifest']['param']>;
|
|
693
|
+
export type BlobManifestResult = FromSchema<PeerProtocol['blob/manifest']['result']>;
|
|
694
|
+
export type ControllerGetLogParam = FromSchema<PeerProtocol['controller/get-log']['param']>;
|
|
695
|
+
export type ControllerGetLogResult = FromSchema<PeerProtocol['controller/get-log']['result']>;
|
|
419
696
|
export type SyncNegotiateParams = FromSchema<SyncProtocol['sync/negotiate']['param']>;
|
|
420
697
|
export type SyncNegotiateResult = FromSchema<SyncProtocol['sync/negotiate']['result']>;
|
|
421
698
|
export type SyncMerkleSyncParams = FromSchema<SyncProtocol['sync/merkle-sync']['param']>;
|
|
422
699
|
export type SyncMerkleSyncSend = FromSchema<SyncProtocol['sync/merkle-sync']['send']>;
|
|
423
700
|
export type SyncMerkleSyncReceive = FromSchema<SyncProtocol['sync/merkle-sync']['receive']>;
|
|
424
701
|
export type SyncMerkleSyncResult = FromSchema<SyncProtocol['sync/merkle-sync']['result']>;
|
|
702
|
+
export type SyncReconcileCredentialsParam = FromSchema<SyncProtocol['sync/reconcile-credentials']['param']>;
|
|
703
|
+
export type SyncReconcileCredentialsResult = FromSchema<SyncProtocol['sync/reconcile-credentials']['result']>;
|
|
425
704
|
export type SyncDirection = 'push' | 'pull' | 'both';
|
|
426
705
|
export type SyncClientMessage = AnyClientMessageOf<SyncProtocol>;
|
|
427
706
|
export type SyncServerMessage = AnyServerMessageOf<SyncProtocol>;
|
package/lib/protocol.js
CHANGED
|
@@ -247,6 +247,224 @@ export const syncProtocol = {
|
|
|
247
247
|
],
|
|
248
248
|
additionalProperties: false
|
|
249
249
|
}
|
|
250
|
+
},
|
|
251
|
+
// Credential catch-up + revocation GC in one round, served over the same
|
|
252
|
+
// doc-sync session. The caller advertises the signed subject states it holds so
|
|
253
|
+
// the server can send missing or updated rows and name tombstones for held rows
|
|
254
|
+
// that are now revoked — a wrapping tombstone addresses no recipient once its
|
|
255
|
+
// row is gone, so it can only travel when the caller names the id. `bundles`
|
|
256
|
+
// carries the row BYTES of the keys the caller is a recipient of and was
|
|
257
|
+
// missing, shaped like a `credential:key-grant` minus its `auth` envelope: each
|
|
258
|
+
// row self-authenticates through its own `op`, and recipient scoping is
|
|
259
|
+
// enforced server-side.
|
|
260
|
+
'sync/reconcile-credentials': {
|
|
261
|
+
type: 'request',
|
|
262
|
+
param: {
|
|
263
|
+
type: 'object',
|
|
264
|
+
properties: {
|
|
265
|
+
held: {
|
|
266
|
+
type: 'array',
|
|
267
|
+
items: {
|
|
268
|
+
type: 'object',
|
|
269
|
+
properties: {
|
|
270
|
+
subjectKind: {
|
|
271
|
+
type: 'string',
|
|
272
|
+
enum: [
|
|
273
|
+
'key',
|
|
274
|
+
'wrapping',
|
|
275
|
+
'entry'
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
subjectID: {
|
|
279
|
+
type: 'string'
|
|
280
|
+
},
|
|
281
|
+
opHash: {
|
|
282
|
+
type: 'string'
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
required: [
|
|
286
|
+
'subjectKind',
|
|
287
|
+
'subjectID',
|
|
288
|
+
'opHash'
|
|
289
|
+
],
|
|
290
|
+
additionalProperties: false
|
|
291
|
+
},
|
|
292
|
+
description: 'Signed subject states the caller holds, for updates and revocation GC'
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
required: [
|
|
296
|
+
'held'
|
|
297
|
+
],
|
|
298
|
+
additionalProperties: false
|
|
299
|
+
},
|
|
300
|
+
result: {
|
|
301
|
+
type: 'object',
|
|
302
|
+
properties: {
|
|
303
|
+
bundles: {
|
|
304
|
+
type: 'array',
|
|
305
|
+
items: {
|
|
306
|
+
type: 'object',
|
|
307
|
+
properties: {
|
|
308
|
+
keyID: {
|
|
309
|
+
type: 'string'
|
|
310
|
+
},
|
|
311
|
+
keyVersion: {
|
|
312
|
+
type: 'number'
|
|
313
|
+
},
|
|
314
|
+
suite: {
|
|
315
|
+
type: 'number'
|
|
316
|
+
},
|
|
317
|
+
ownerDID: {
|
|
318
|
+
type: 'string'
|
|
319
|
+
},
|
|
320
|
+
keyOp: {
|
|
321
|
+
type: 'string'
|
|
322
|
+
},
|
|
323
|
+
keyBranches: {
|
|
324
|
+
type: 'array',
|
|
325
|
+
items: {
|
|
326
|
+
type: 'string'
|
|
327
|
+
},
|
|
328
|
+
description: "The proven key-op JWTs that introduced this key version's branches."
|
|
329
|
+
},
|
|
330
|
+
wrapping: {
|
|
331
|
+
type: 'object',
|
|
332
|
+
properties: {
|
|
333
|
+
wrappingID: {
|
|
334
|
+
type: 'string'
|
|
335
|
+
},
|
|
336
|
+
factors: {
|
|
337
|
+
type: 'array',
|
|
338
|
+
items: {
|
|
339
|
+
type: 'object',
|
|
340
|
+
properties: {
|
|
341
|
+
kind: {
|
|
342
|
+
type: 'string'
|
|
343
|
+
},
|
|
344
|
+
params: {
|
|
345
|
+
type: 'object',
|
|
346
|
+
additionalProperties: true
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
required: [
|
|
350
|
+
'kind',
|
|
351
|
+
'params'
|
|
352
|
+
],
|
|
353
|
+
additionalProperties: false
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
iv: {
|
|
357
|
+
type: 'string'
|
|
358
|
+
},
|
|
359
|
+
wrappedKey: {
|
|
360
|
+
type: 'string'
|
|
361
|
+
},
|
|
362
|
+
recipientDID: {
|
|
363
|
+
type: 'string'
|
|
364
|
+
},
|
|
365
|
+
op: {
|
|
366
|
+
type: 'string'
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
required: [
|
|
370
|
+
'wrappingID',
|
|
371
|
+
'factors',
|
|
372
|
+
'iv',
|
|
373
|
+
'wrappedKey',
|
|
374
|
+
'recipientDID',
|
|
375
|
+
'op'
|
|
376
|
+
],
|
|
377
|
+
additionalProperties: false
|
|
378
|
+
},
|
|
379
|
+
entries: {
|
|
380
|
+
type: 'array',
|
|
381
|
+
items: {
|
|
382
|
+
type: 'object',
|
|
383
|
+
properties: {
|
|
384
|
+
entryID: {
|
|
385
|
+
type: 'string'
|
|
386
|
+
},
|
|
387
|
+
iv: {
|
|
388
|
+
type: 'string'
|
|
389
|
+
},
|
|
390
|
+
ciphertext: {
|
|
391
|
+
type: 'string'
|
|
392
|
+
},
|
|
393
|
+
hlc: {
|
|
394
|
+
type: 'string'
|
|
395
|
+
},
|
|
396
|
+
op: {
|
|
397
|
+
type: 'string'
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
required: [
|
|
401
|
+
'entryID',
|
|
402
|
+
'iv',
|
|
403
|
+
'ciphertext',
|
|
404
|
+
'hlc',
|
|
405
|
+
'op'
|
|
406
|
+
],
|
|
407
|
+
additionalProperties: false
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
required: [
|
|
412
|
+
'keyID',
|
|
413
|
+
'keyVersion',
|
|
414
|
+
'suite',
|
|
415
|
+
'ownerDID',
|
|
416
|
+
'keyOp',
|
|
417
|
+
'keyBranches',
|
|
418
|
+
'wrapping',
|
|
419
|
+
'entries'
|
|
420
|
+
],
|
|
421
|
+
additionalProperties: false
|
|
422
|
+
},
|
|
423
|
+
description: "The caller's recipient-scoped catch-up bundles (missed grants and entry top-ups)"
|
|
424
|
+
},
|
|
425
|
+
tombstones: {
|
|
426
|
+
type: 'array',
|
|
427
|
+
items: {
|
|
428
|
+
type: 'object',
|
|
429
|
+
properties: {
|
|
430
|
+
keyID: {
|
|
431
|
+
type: 'string'
|
|
432
|
+
},
|
|
433
|
+
authorDID: {
|
|
434
|
+
type: 'string'
|
|
435
|
+
},
|
|
436
|
+
hlc: {
|
|
437
|
+
type: 'string'
|
|
438
|
+
},
|
|
439
|
+
opJWT: {
|
|
440
|
+
type: 'string'
|
|
441
|
+
},
|
|
442
|
+
opHash: {
|
|
443
|
+
type: 'string'
|
|
444
|
+
},
|
|
445
|
+
subjectID: {
|
|
446
|
+
type: 'string'
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
required: [
|
|
450
|
+
'keyID',
|
|
451
|
+
'authorDID',
|
|
452
|
+
'hlc',
|
|
453
|
+
'opJWT',
|
|
454
|
+
'opHash',
|
|
455
|
+
'subjectID'
|
|
456
|
+
],
|
|
457
|
+
additionalProperties: false
|
|
458
|
+
},
|
|
459
|
+
description: 'Tombstones for advertised held IDs that are now revoked (GC)'
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
required: [
|
|
463
|
+
'bundles',
|
|
464
|
+
'tombstones'
|
|
465
|
+
],
|
|
466
|
+
additionalProperties: false
|
|
467
|
+
}
|
|
250
468
|
}
|
|
251
469
|
};
|
|
252
470
|
/**
|
|
@@ -515,5 +733,145 @@ export const syncProtocol = {
|
|
|
515
733
|
],
|
|
516
734
|
additionalProperties: false
|
|
517
735
|
}
|
|
736
|
+
},
|
|
737
|
+
// Blob transfer lane — control plane. Bytes never ride these; they carry
|
|
738
|
+
// discovery + a signed fetch capability. The data plane is raw HTTP Range.
|
|
739
|
+
// Gated coarsely (checkPeerAccess): just reports which bytes this node holds.
|
|
740
|
+
'blob/query-haves': {
|
|
741
|
+
type: 'request',
|
|
742
|
+
param: {
|
|
743
|
+
type: 'object',
|
|
744
|
+
properties: {
|
|
745
|
+
attachmentIDs: {
|
|
746
|
+
type: 'array',
|
|
747
|
+
items: {
|
|
748
|
+
type: 'string'
|
|
749
|
+
},
|
|
750
|
+
description: 'Candidate AttachmentIDs the caller wants to locate'
|
|
751
|
+
}
|
|
752
|
+
},
|
|
753
|
+
required: [
|
|
754
|
+
'attachmentIDs'
|
|
755
|
+
],
|
|
756
|
+
additionalProperties: false
|
|
757
|
+
},
|
|
758
|
+
result: {
|
|
759
|
+
type: 'object',
|
|
760
|
+
properties: {
|
|
761
|
+
have: {
|
|
762
|
+
type: 'array',
|
|
763
|
+
items: {
|
|
764
|
+
type: 'string'
|
|
765
|
+
},
|
|
766
|
+
description: 'The subset this node holds with all bytes local'
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
required: [
|
|
770
|
+
'have'
|
|
771
|
+
],
|
|
772
|
+
additionalProperties: false
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
// Returns the chunk manifest for one blob and mints a short-TTL fetch
|
|
776
|
+
// capability the caller presents to the data-plane HTTP route. Scope-gated:
|
|
777
|
+
// the caller must have a document in scope referencing the blob (D19), and
|
|
778
|
+
// presents its own read-delegation tokens to prove it.
|
|
779
|
+
'blob/manifest': {
|
|
780
|
+
type: 'request',
|
|
781
|
+
param: {
|
|
782
|
+
type: 'object',
|
|
783
|
+
properties: {
|
|
784
|
+
attachmentID: {
|
|
785
|
+
type: 'string'
|
|
786
|
+
},
|
|
787
|
+
delegationTokens: {
|
|
788
|
+
type: 'array',
|
|
789
|
+
items: {
|
|
790
|
+
type: 'string'
|
|
791
|
+
},
|
|
792
|
+
description: "The caller's read-delegation tokens, for scope authorization"
|
|
793
|
+
}
|
|
794
|
+
},
|
|
795
|
+
required: [
|
|
796
|
+
'attachmentID',
|
|
797
|
+
'delegationTokens'
|
|
798
|
+
],
|
|
799
|
+
additionalProperties: false
|
|
800
|
+
},
|
|
801
|
+
result: {
|
|
802
|
+
type: 'object',
|
|
803
|
+
properties: {
|
|
804
|
+
chunkSize: {
|
|
805
|
+
type: 'number'
|
|
806
|
+
},
|
|
807
|
+
chunkCount: {
|
|
808
|
+
type: 'number'
|
|
809
|
+
},
|
|
810
|
+
contentLength: {
|
|
811
|
+
type: 'number'
|
|
812
|
+
},
|
|
813
|
+
chunkDigests: {
|
|
814
|
+
type: 'array',
|
|
815
|
+
items: {
|
|
816
|
+
type: 'string'
|
|
817
|
+
},
|
|
818
|
+
description: 'Per-chunk blake3 digests, base64, ordered by index'
|
|
819
|
+
},
|
|
820
|
+
capability: {
|
|
821
|
+
type: 'string',
|
|
822
|
+
description: 'Short-TTL signed fetch capability for the data-plane GET'
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
required: [
|
|
826
|
+
'chunkSize',
|
|
827
|
+
'chunkCount',
|
|
828
|
+
'contentLength',
|
|
829
|
+
'chunkDigests',
|
|
830
|
+
'capability'
|
|
831
|
+
],
|
|
832
|
+
additionalProperties: false
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
// Controller log sharing. Serves a `did:kokuin:` controller's stored key-event
|
|
836
|
+
// log inline (logs are small — no blob-style data plane). Gated coarsely by
|
|
837
|
+
// `checkPeerAccess`: the log you need is that of a DID whose documents you
|
|
838
|
+
// already sync, and those are group/catalog scoped. The events are
|
|
839
|
+
// self-authenticating (inception digest == DID, every event signed), so the
|
|
840
|
+
// recipient folds + verifies them independently — the wire schema stays
|
|
841
|
+
// permissive and the fold on receipt is the real check.
|
|
842
|
+
'controller/get-log': {
|
|
843
|
+
type: 'request',
|
|
844
|
+
param: {
|
|
845
|
+
type: 'object',
|
|
846
|
+
properties: {
|
|
847
|
+
did: {
|
|
848
|
+
type: 'string',
|
|
849
|
+
description: 'The did:kokuin: controller whose log is requested'
|
|
850
|
+
}
|
|
851
|
+
},
|
|
852
|
+
required: [
|
|
853
|
+
'did'
|
|
854
|
+
],
|
|
855
|
+
additionalProperties: false
|
|
856
|
+
},
|
|
857
|
+
result: {
|
|
858
|
+
type: 'object',
|
|
859
|
+
properties: {
|
|
860
|
+
events: {
|
|
861
|
+
type: 'array',
|
|
862
|
+
// A SignedEvent is a nested object re-verified on receipt; the wire
|
|
863
|
+
// carries it opaquely rather than reproducing its structure.
|
|
864
|
+
items: {
|
|
865
|
+
type: 'object',
|
|
866
|
+
additionalProperties: true
|
|
867
|
+
},
|
|
868
|
+
description: "The controller's signed key-event log"
|
|
869
|
+
}
|
|
870
|
+
},
|
|
871
|
+
required: [
|
|
872
|
+
'events'
|
|
873
|
+
],
|
|
874
|
+
additionalProperties: false
|
|
875
|
+
}
|
|
518
876
|
}
|
|
519
877
|
};
|
|
@@ -2,7 +2,7 @@ import type { OwnIdentity } from '@kokuin/token';
|
|
|
2
2
|
import type { KubunDB } from '@kubun/db';
|
|
3
3
|
import type { EngineEventBus, EngineEvents } from '@kubun/engine';
|
|
4
4
|
import type { Logger } from '@kubun/logger';
|
|
5
|
-
import type { GroupBroadcastMessage } from '../groups/broadcast.js';
|
|
5
|
+
import type { GroupBroadcastMessage } from '../groups/broadcast-message.js';
|
|
6
6
|
export type AccessDefaultSenderParams = {
|
|
7
7
|
db: KubunDB;
|
|
8
8
|
eventBus: EngineEventBus<EngineEvents>;
|