@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/README.md +12 -13
- package/dist/index.d.ts +59 -23
- package/dist/index.js +322 -174
- package/dist/serve.js +28 -1
- package/openapi.yaml +84 -50
- package/package.json +8 -8
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
|
-
|
|
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.
|
|
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,
|
|
7
|
+
identity chains, content chains, countersignatures, and content blobs.
|
|
8
8
|
|
|
9
9
|
Two data planes:
|
|
10
|
-
- **Proof plane** (public): signed chain operations,
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "DFOS Web Relay — verifying HTTP relay for identity chains, content chains,
|
|
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.
|
|
45
|
-
"zod": "^4.3
|
|
44
|
+
"hono": "^4.12.23",
|
|
45
|
+
"zod": "^4.4.3"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@metalabel/dfos-protocol": "^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.
|
|
54
|
-
"vitest": "^4.1.
|
|
55
|
-
"@metalabel/dfos-protocol": "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",
|