@metalabel/dfos-web-relay 0.9.0 → 0.11.0

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/dist/serve.js CHANGED
@@ -1,11 +1,38 @@
1
1
  // src/serve.ts
2
2
  import { createServer } from "http";
3
+ var MAX_STREAM_BODY_BYTES = (16 << 20) + (1 << 20);
3
4
  var serve = (app, options = {}) => {
4
5
  const { port = 4444, hostname } = options;
5
6
  const server = createServer(async (req, res) => {
6
7
  const url = new URL(req.url ?? "/", `http://${hostname ?? "localhost"}:${port}`);
8
+ const reject413 = () => {
9
+ if (res.headersSent) return;
10
+ res.writeHead(413, {
11
+ "content-type": "application/json",
12
+ connection: "close"
13
+ });
14
+ res.end(JSON.stringify({ error: "request body too large" }));
15
+ };
16
+ const declaredLength = Number(req.headers["content-length"]);
17
+ if (Number.isFinite(declaredLength) && declaredLength > MAX_STREAM_BODY_BYTES) {
18
+ reject413();
19
+ return;
20
+ }
7
21
  const chunks = [];
8
- for await (const chunk of req) chunks.push(chunk);
22
+ let total = 0;
23
+ let aborted = false;
24
+ for await (const chunk of req) {
25
+ total += chunk.length;
26
+ if (total > MAX_STREAM_BODY_BYTES) {
27
+ aborted = true;
28
+ break;
29
+ }
30
+ chunks.push(chunk);
31
+ }
32
+ if (aborted) {
33
+ reject413();
34
+ return;
35
+ }
9
36
  const body = Buffer.concat(chunks);
10
37
  const headers = new Headers();
11
38
  for (const [k, v] of Object.entries(req.headers)) {
package/openapi.yaml CHANGED
@@ -1,13 +1,13 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: DFOS Web Relay
4
- version: 0.1.0
4
+ version: 0.9.0
5
5
  description: |
6
6
  HTTP relay for the DFOS protocol. Receives, verifies, stores, and serves
7
- identity chains, content chains, beacons, countersignatures, and content blobs.
7
+ identity chains, content chains, countersignatures, and content blobs.
8
8
 
9
9
  Two data planes:
10
- - **Proof plane** (public): signed chain operations, beacons, countersignatures
10
+ - **Proof plane** (public): signed chain operations, countersignatures
11
11
  - **Content plane** (authenticated): raw content blobs gated by DID auth tokens and DFOS credentials
12
12
 
13
13
  servers:
@@ -66,7 +66,7 @@ paths:
66
66
  summary: Submit operations for ingestion
67
67
  description: |
68
68
  Accept a batch of JWS tokens — identity operations, content operations,
69
- beacons, and countersignatures. The relay classifies, dependency-sorts,
69
+ and countersignatures. The relay classifies, dependency-sorts,
70
70
  verifies, and stores each token.
71
71
  tags: [Proof Plane]
72
72
  requestBody:
@@ -185,7 +185,7 @@ paths:
185
185
  required: true
186
186
  schema:
187
187
  type: string
188
- description: Content identifier (22-char hash)
188
+ description: Content identifier (31-char hash)
189
189
  responses:
190
190
  '200':
191
191
  description: Content chain state and log
@@ -416,6 +416,62 @@ paths:
416
416
  '501':
417
417
  description: Documents capability not enabled
418
418
 
419
+ /log:
420
+ get:
421
+ operationId: getLog
422
+ summary: Paginated global log of all accepted operations
423
+ description: |
424
+ Returns every operation the relay has accepted — across all identity and
425
+ content chains, plus countersignatures — in acceptance order.
426
+ Cursor-based pagination. Used by peer relays to background-sync. Available
427
+ only when the relay advertises the `log` capability; otherwise returns 501.
428
+ tags: [Proof Plane]
429
+ parameters:
430
+ - name: after
431
+ in: query
432
+ required: false
433
+ schema:
434
+ type: string
435
+ description: CID cursor — start after this operation CID
436
+ - name: limit
437
+ in: query
438
+ required: false
439
+ schema:
440
+ type: integer
441
+ default: 100
442
+ maximum: 1000
443
+ responses:
444
+ '200':
445
+ description: Global log entries
446
+ content:
447
+ application/json:
448
+ schema:
449
+ type: object
450
+ required: [entries, cursor]
451
+ properties:
452
+ entries:
453
+ type: array
454
+ items:
455
+ type: object
456
+ required: [cid, jwsToken, kind, chainId]
457
+ properties:
458
+ cid:
459
+ type: string
460
+ jwsToken:
461
+ type: string
462
+ kind:
463
+ type: string
464
+ enum:
465
+ [identity-op, content-op, artifact, countersign, revocation, credential]
466
+ chainId:
467
+ type: string
468
+ description: Chain identifier (DID or contentId)
469
+ cursor:
470
+ type: string
471
+ nullable: true
472
+ '501':
473
+ description: Global log capability not enabled
474
+
419
475
  /identities/{did}/log:
420
476
  get:
421
477
  operationId: getIdentityLog
@@ -483,7 +539,7 @@ paths:
483
539
  required: true
484
540
  schema:
485
541
  type: string
486
- description: Content identifier (22-char hash)
542
+ description: Content identifier (31-char hash)
487
543
  - name: after
488
544
  in: query
489
545
  required: false
@@ -525,7 +581,7 @@ paths:
525
581
  /countersignatures/{cid}:
526
582
  get:
527
583
  operationId: getCountersignaturesByCID
528
- summary: Get countersignatures for any CID (operation or beacon)
584
+ summary: Get countersignatures for an operation CID
529
585
  tags: [Proof Plane]
530
586
  parameters:
531
587
  - name: cid
@@ -533,7 +589,7 @@ paths:
533
589
  required: true
534
590
  schema:
535
591
  type: string
536
- description: CIDv1 of the operation or beacon
592
+ description: CIDv1 of the operation
537
593
  responses:
538
594
  '200':
539
595
  description: Countersignatures
@@ -553,27 +609,6 @@ paths:
553
609
  '404':
554
610
  $ref: '#/components/responses/NotFound'
555
611
 
556
- /beacons/{did}:
557
- get:
558
- operationId: getBeacon
559
- summary: Get the latest beacon for a DID
560
- tags: [Proof Plane]
561
- parameters:
562
- - name: did
563
- in: path
564
- required: true
565
- schema:
566
- type: string
567
- responses:
568
- '200':
569
- description: Latest beacon
570
- content:
571
- application/json:
572
- schema:
573
- $ref: '#/components/schemas/BeaconResponse'
574
- '404':
575
- $ref: '#/components/responses/NotFound'
576
-
577
612
  components:
578
613
  securitySchemes:
579
614
  BearerAuth:
@@ -597,7 +632,7 @@ components:
597
632
  description: Error message if rejected
598
633
  kind:
599
634
  type: string
600
- enum: [identity-op, content-op, beacon, artifact, countersign, revocation, credential]
635
+ enum: [identity-op, content-op, artifact, countersign, revocation, credential]
601
636
  chainId:
602
637
  type: string
603
638
  description: Chain identifier (DID or contentId)
@@ -612,7 +647,7 @@ components:
612
647
  type: string
613
648
  chainType:
614
649
  type: string
615
- enum: [identity, content, artifact, beacon, countersign, revocation, credential]
650
+ enum: [identity, content, artifact, countersign, revocation, credential]
616
651
  chainId:
617
652
  type: string
618
653
 
@@ -627,7 +662,7 @@ components:
627
662
  description: CID of the current head operation
628
663
  state:
629
664
  type: object
630
- required: [did, isDeleted, authKeys, assertKeys, controllerKeys]
665
+ required: [did, isDeleted, authKeys, assertKeys, controllerKeys, services]
631
666
  properties:
632
667
  did:
633
668
  type: string
@@ -645,6 +680,22 @@ components:
645
680
  type: array
646
681
  items:
647
682
  $ref: '#/components/schemas/MultikeyPublicKey'
683
+ services:
684
+ type: array
685
+ description: >-
686
+ Resolved discovery vocabulary (controller-signed). Each entry has
687
+ a common envelope {id, type}; recognized types DfosRelay and
688
+ ContentAnchor carry type-specific fields. The namespace is open —
689
+ unrecognized types are preserved verbatim.
690
+ items:
691
+ type: object
692
+ required: [id, type]
693
+ properties:
694
+ id:
695
+ type: string
696
+ type:
697
+ type: string
698
+ additionalProperties: true
648
699
 
649
700
  ContentChainResponse:
650
701
  type: object
@@ -679,23 +730,6 @@ components:
679
730
  creatorDID:
680
731
  type: string
681
732
 
682
- BeaconResponse:
683
- type: object
684
- required: [did, jwsToken, beaconCID, manifestContentId, createdAt]
685
- properties:
686
- did:
687
- type: string
688
- jwsToken:
689
- type: string
690
- beaconCID:
691
- type: string
692
- manifestContentId:
693
- type: string
694
- description: Content ID of the manifest chain
695
- createdAt:
696
- type: string
697
- format: date-time
698
-
699
733
  MultikeyPublicKey:
700
734
  type: object
701
735
  required: [id, type, publicKeyMultibase]
@@ -745,6 +779,6 @@ tags:
745
779
  - name: Meta
746
780
  description: Relay metadata and discovery
747
781
  - name: Proof Plane
748
- description: Public routes for signed chain operations, beacons, and countersignatures
782
+ description: Public routes for signed chain operations and countersignatures
749
783
  - name: Content Plane
750
784
  description: Authenticated routes for content blob storage and retrieval
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@metalabel/dfos-web-relay",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
- "description": "DFOS Web Relay — verifying HTTP relay for identity chains, content chains, beacons, and content blobs",
5
+ "description": "DFOS Web Relay — verifying HTTP relay for identity chains, content chains, and content blobs",
6
6
  "license": "MIT",
7
7
  "author": "Metalabel <hello@metalabel.com> (https://metalabel.com)",
8
8
  "repository": {
@@ -41,18 +41,18 @@
41
41
  "README.md"
42
42
  ],
43
43
  "dependencies": {
44
- "hono": "^4.12.9",
45
- "zod": "^4.3.6"
44
+ "hono": "^4.12.23",
45
+ "zod": "^4.4.3"
46
46
  },
47
47
  "peerDependencies": {
48
- "@metalabel/dfos-protocol": "^0.6.0"
48
+ "@metalabel/dfos-protocol": "^0.11.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^24.10.4",
52
52
  "tsup": "^8.5.1",
53
- "tsx": "^4.20.3",
54
- "vitest": "^4.1.2",
55
- "@metalabel/dfos-protocol": "0.9.0"
53
+ "tsx": "^4.22.4",
54
+ "vitest": "^4.1.8",
55
+ "@metalabel/dfos-protocol": "0.11.0"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsup",