@metalabel/dfos-protocol 0.10.0 → 0.12.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 CHANGED
@@ -21,11 +21,11 @@ import { createJws, dagCborCanonicalEncode, verifyJws } from '@metalabel/dfos-pr
21
21
 
22
22
  ## Subpath Exports
23
23
 
24
- | Export | Description |
25
- | -------------------------------------- | ----------------------------------------------------------------------- |
26
- | `@metalabel/dfos-protocol/chain` | Identity and content chain signing, verification, beacons, countersigns |
27
- | `@metalabel/dfos-protocol/credentials` | Auth tokens (DID-signed JWT) and DFOS credentials for authorization |
28
- | `@metalabel/dfos-protocol/crypto` | Ed25519, JWS, JWT, dag-cbor, base64url, ID generation |
24
+ | Export | Description |
25
+ | -------------------------------------- | ------------------------------------------------------------------------- |
26
+ | `@metalabel/dfos-protocol/chain` | Identity & content chains, services, artifacts, countersigns, revocations |
27
+ | `@metalabel/dfos-protocol/credentials` | Auth tokens (DID-signed JWT) and DFOS credentials for authorization |
28
+ | `@metalabel/dfos-protocol/crypto` | Ed25519, JWS, JWT, dag-cbor, base64url, ID generation |
29
29
 
30
30
  ## Specifications
31
31
 
@@ -33,7 +33,7 @@ import { createJws, dagCborCanonicalEncode, verifyJws } from '@metalabel/dfos-pr
33
33
  | ------------------------------------------------ | -------------------------------------------------------------- |
34
34
  | [PROTOCOL.md](../../specs/PROTOCOL.md) | Core protocol — chains, signatures, verification, test vectors |
35
35
  | [DID-METHOD.md](../../specs/DID-METHOD.md) | W3C DID method specification for `did:dfos` |
36
- | [CONTENT-MODEL.md](../../specs/CONTENT-MODEL.md) | Standard content schemas (post, profile, manifest) |
36
+ | [CONTENT-MODEL.md](../../specs/CONTENT-MODEL.md) | Standard content schemas (post, profile) |
37
37
 
38
38
  ## Examples
39
39
 
@@ -47,7 +47,7 @@ The `examples/` directory contains deterministic reference fixtures that can be
47
47
  - `content-delegated.json` — creator genesis + delegated update with DFOS write credential
48
48
  - `credential-write.json` — DFOS write credential (broad + content-narrowed)
49
49
  - `credential-read.json` — DFOS read credential
50
- - `beacon.json` — signed manifest pointer announcement with witness countersignature
50
+ - `identity-services.json` — genesis publishing a services set (relay locator + content/artifact anchors)
51
51
 
52
52
  ## License
53
53
 
@@ -1,5 +1,5 @@
1
- import { I as IdentityOperation, S as Signer, V as VerifiedIdentity, C as ContentOperation, B as BeaconPayload, a as CountersignPayload, A as ArtifactPayload } from '../schemas-BhikXSf_.js';
2
- export { M as MAX_ARTIFACT_PAYLOAD_SIZE, b as MultikeyPublicKey, R as RevocationPayload } from '../schemas-BhikXSf_.js';
1
+ import { I as IdentityOperation, i as Signer, V as VerifiedIdentity, S as ServiceEntry, b as ContentOperation, c as CountersignPayload, a as ArtifactPayload } from '../schemas-Bb_9P8_s.js';
2
+ export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, M as MAX_ARTIFACT_PAYLOAD_SIZE, d as MAX_OPERATION_SIZE, e as MAX_SERVICES_ENTRIES, f as MAX_SERVICES_PAYLOAD_SIZE, g as MultikeyPublicKey, R as RevocationPayload, h as ServicesArray } from '../schemas-Bb_9P8_s.js';
3
3
  import 'zod';
4
4
 
5
5
  /** Ed25519 public key multicodec value */
@@ -88,6 +88,29 @@ declare const verifyIdentityExtensionFromTrustedState: (input: {
88
88
  createdAt: string;
89
89
  }>;
90
90
 
91
+ type AnchorKind = 'chain' | 'artifact' | 'invalid';
92
+ /**
93
+ * Enforce the services byte cap on the CBOR-encoded array — same encoding the
94
+ * wire uses, so the bound is identical across implementations. Mirrors the
95
+ * artifact payload size check.
96
+ */
97
+ declare const assertServicesWithinCap: (services: ServiceEntry[]) => Promise<void>;
98
+ /**
99
+ * Classify a ContentAnchor target by structural form. Resolvers dispatch on the
100
+ * result: 'chain' → resolve a content chain by contentId; 'artifact' → fetch by
101
+ * CID and require type:"artifact"; 'invalid' → reject (e.g. a bare head CID is
102
+ * 'artifact'-shaped but fails the resolution-time type check).
103
+ */
104
+ declare const classifyAnchor: (anchor: string) => AnchorKind;
105
+ /** Recognized (core-blessed) service types. All other types are valid but opaque. */
106
+ declare const RECOGNIZED_SERVICE_TYPES: readonly ["DfosRelay", "ContentAnchor"];
107
+ /** Whether the core assigns structural semantics to this service type. */
108
+ declare const isRecognizedServiceType: (type: string) => boolean;
109
+ /** Select the DfosRelay transport endpoints from a services set, in entry order. */
110
+ declare const relayEndpoints: (services: ServiceEntry[]) => string[];
111
+ /** Select ContentAnchor entries matching a client label (e.g. "profile"). */
112
+ declare const anchorsByLabel: (services: ServiceEntry[], label: string) => ServiceEntry[];
113
+
91
114
  interface VerifiedContentChain {
92
115
  /** Content identifier — bare 31-char hash derived from genesis CID */
93
116
  contentId: string;
@@ -178,34 +201,6 @@ declare const verifyContentExtensionFromTrustedState: (input: {
178
201
  createdAt: string;
179
202
  }>;
180
203
 
181
- interface VerifiedBeacon {
182
- did: string;
183
- manifestContentId: string;
184
- createdAt: string;
185
- signerKeyId: string;
186
- beaconCID: string;
187
- }
188
- /**
189
- * Sign a beacon announcement as a JWS
190
- */
191
- declare const signBeacon: (input: {
192
- payload: BeaconPayload;
193
- signer: Signer;
194
- kid: string;
195
- }) => Promise<{
196
- jwsToken: string;
197
- beaconCID: string;
198
- }>;
199
- /**
200
- * Verify a beacon JWS — signature, CID, payload schema, clock skew
201
- */
202
- declare const verifyBeacon: (input: {
203
- jwsToken: string;
204
- resolveKey: (kid: string) => Promise<Uint8Array>;
205
- /** Current time for clock skew check (defaults to Date.now()) */
206
- now?: number;
207
- }) => Promise<VerifiedBeacon>;
208
-
209
204
  interface VerifiedCountersignature {
210
205
  /** CID of this countersign operation (distinct from the target) */
211
206
  countersignCID: string;
@@ -213,6 +208,8 @@ interface VerifiedCountersignature {
213
208
  witnessDID: string;
214
209
  /** The CID being attested to */
215
210
  targetCID: string;
211
+ /** Open-namespace relation tag, if present (e.g. "endorses", "coauthors") */
212
+ relation?: string;
216
213
  }
217
214
  /**
218
215
  * Sign a countersignature attesting to a target operation by CID
@@ -294,4 +291,4 @@ declare const verifyRevocation: (input: {
294
291
  resolveKey: (kid: string) => Promise<Uint8Array>;
295
292
  }) => Promise<VerifiedRevocation>;
296
293
 
297
- export { ArtifactPayload, BeaconPayload, ContentOperation, CountersignPayload, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, IdentityOperation, Signer, type VerifiedArtifact, type VerifiedBeacon, type VerifiedContentChain, type VerifiedCountersignature, VerifiedIdentity, type VerifiedRevocation, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, signArtifact, signBeacon, signContentOperation, signCountersignature, signIdentityOperation, signRevocation, verifyArtifact, verifyBeacon, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation };
294
+ export { type AnchorKind, ArtifactPayload, ContentOperation, CountersignPayload, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, IdentityOperation, RECOGNIZED_SERVICE_TYPES, ServiceEntry, Signer, type VerifiedArtifact, type VerifiedContentChain, type VerifiedCountersignature, VerifiedIdentity, type VerifiedRevocation, anchorsByLabel, assertServicesWithinCap, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation };
@@ -1,61 +1,81 @@
1
1
  import {
2
+ ARTIFACT_CID_ANCHOR_RE,
2
3
  ArtifactPayload,
3
- BeaconPayload,
4
+ CONTENT_ID_ANCHOR_RE,
4
5
  ContentOperation,
5
6
  CountersignPayload,
6
7
  IdentityOperation,
7
8
  MAX_ARTIFACT_PAYLOAD_SIZE,
9
+ MAX_OPERATION_SIZE,
10
+ MAX_SERVICES_ENTRIES,
11
+ MAX_SERVICES_PAYLOAD_SIZE,
8
12
  MultikeyPublicKey,
13
+ RECOGNIZED_SERVICE_TYPES,
9
14
  RevocationPayload,
15
+ ServiceEntry,
16
+ ServicesArray,
10
17
  VerifiedIdentity,
18
+ anchorsByLabel,
19
+ assertServicesWithinCap,
20
+ classifyAnchor,
11
21
  deriveChainIdentifier,
12
22
  deriveContentId,
23
+ isRecognizedServiceType,
24
+ relayEndpoints,
13
25
  signArtifact,
14
- signBeacon,
15
26
  signContentOperation,
16
27
  signCountersignature,
17
28
  signIdentityOperation,
18
29
  signRevocation,
19
30
  verifyArtifact,
20
- verifyBeacon,
21
31
  verifyContentChain,
22
32
  verifyContentExtensionFromTrustedState,
23
33
  verifyCountersignature,
24
34
  verifyIdentityChain,
25
35
  verifyIdentityExtensionFromTrustedState,
26
36
  verifyRevocation
27
- } from "../chunk-GZ7ZAIRD.js";
37
+ } from "../chunk-J5C4OXL4.js";
28
38
  import {
29
39
  ED25519_PRIV_MULTICODEC,
30
40
  ED25519_PUB_MULTICODEC,
31
41
  decodeMultikey,
32
42
  encodeEd25519Multikey
33
- } from "../chunk-LQFOBE6X.js";
34
- import "../chunk-GQOZJKKO.js";
43
+ } from "../chunk-J3XXF6F5.js";
44
+ import "../chunk-4QQ5HK5M.js";
35
45
  export {
46
+ ARTIFACT_CID_ANCHOR_RE,
36
47
  ArtifactPayload,
37
- BeaconPayload,
48
+ CONTENT_ID_ANCHOR_RE,
38
49
  ContentOperation,
39
50
  CountersignPayload,
40
51
  ED25519_PRIV_MULTICODEC,
41
52
  ED25519_PUB_MULTICODEC,
42
53
  IdentityOperation,
43
54
  MAX_ARTIFACT_PAYLOAD_SIZE,
55
+ MAX_OPERATION_SIZE,
56
+ MAX_SERVICES_ENTRIES,
57
+ MAX_SERVICES_PAYLOAD_SIZE,
44
58
  MultikeyPublicKey,
59
+ RECOGNIZED_SERVICE_TYPES,
45
60
  RevocationPayload,
61
+ ServiceEntry,
62
+ ServicesArray,
46
63
  VerifiedIdentity,
64
+ anchorsByLabel,
65
+ assertServicesWithinCap,
66
+ classifyAnchor,
47
67
  decodeMultikey,
48
68
  deriveChainIdentifier,
49
69
  deriveContentId,
50
70
  encodeEd25519Multikey,
71
+ isRecognizedServiceType,
72
+ relayEndpoints,
51
73
  signArtifact,
52
- signBeacon,
53
74
  signContentOperation,
54
75
  signCountersignature,
55
76
  signIdentityOperation,
56
77
  signRevocation,
57
78
  verifyArtifact,
58
- verifyBeacon,
59
79
  verifyContentChain,
60
80
  verifyContentExtensionFromTrustedState,
61
81
  verifyCountersignature,
@@ -239,7 +239,11 @@ var dagCborCanonicalEncode = async (value) => {
239
239
  });
240
240
  };
241
241
  var MAX_SAFE_CANONICAL_INTEGER = 9007199254740991;
242
- var assertCanonicalNumbers = (value) => {
242
+ var MAX_CANONICAL_DEPTH = 1024;
243
+ var assertCanonicalNumbers = (value, depth = 0) => {
244
+ if (depth > MAX_CANONICAL_DEPTH) {
245
+ throw new Error(`value nesting exceeds max depth ${MAX_CANONICAL_DEPTH}`);
246
+ }
243
247
  if (typeof value === "number") {
244
248
  if (!Number.isFinite(value)) {
245
249
  throw new Error(`non-finite number is not canonicalizable: ${value}`);
@@ -257,11 +261,11 @@ var assertCanonicalNumbers = (value) => {
257
261
  return;
258
262
  }
259
263
  if (Array.isArray(value)) {
260
- for (const entry of value) assertCanonicalNumbers(entry);
264
+ for (const entry of value) assertCanonicalNumbers(entry, depth + 1);
261
265
  return;
262
266
  }
263
267
  if (value !== null && typeof value === "object") {
264
- for (const entry of Object.values(value)) assertCanonicalNumbers(entry);
268
+ for (const entry of Object.values(value)) assertCanonicalNumbers(entry, depth + 1);
265
269
  }
266
270
  };
267
271
  var parseDagCborCID = (cid) => {
@@ -5,27 +5,24 @@ import {
5
5
  decodeJwsUnsafe,
6
6
  verifyJws,
7
7
  verifyJwt
8
- } from "./chunk-GQOZJKKO.js";
8
+ } from "./chunk-4QQ5HK5M.js";
9
9
 
10
10
  // src/credentials/schemas.ts
11
11
  import { z } from "zod";
12
- var MAX_DID = 256;
13
- var MAX_AUD = 512;
14
- var MAX_RESOURCE = 512;
15
- var MAX_ACTION = 64;
16
12
  var MAX_ATT = 32;
17
13
  var MAX_PRF = 1;
18
- var Attenuation = z.strictObject({
19
- resource: z.string().min(1).max(MAX_RESOURCE),
20
- action: z.string().min(1).max(MAX_ACTION)
14
+ var MAX_CREDENTIAL_SIZE = 262144;
15
+ var Attenuation = z.looseObject({
16
+ resource: z.string().min(1),
17
+ action: z.string().min(1)
21
18
  });
22
- var DFOSCredentialPayload = z.strictObject({
19
+ var DFOSCredentialPayload = z.looseObject({
23
20
  version: z.literal(1),
24
21
  type: z.literal("DFOSCredential"),
25
22
  /** Issuer DID */
26
- iss: z.string().min(1).max(MAX_DID),
23
+ iss: z.string().min(1),
27
24
  /** Audience DID or "*" for public credentials */
28
- aud: z.string().min(1).max(MAX_AUD),
25
+ aud: z.string().min(1),
29
26
  /** Attenuations — resource + action pairs */
30
27
  att: z.array(Attenuation).min(1).max(MAX_ATT),
31
28
  /** Parent credential JWS tokens (for delegation chains) */
@@ -35,13 +32,13 @@ var DFOSCredentialPayload = z.strictObject({
35
32
  /** Issued at — unix seconds */
36
33
  iat: z.number().int().positive()
37
34
  });
38
- var AuthTokenClaims = z.strictObject({
35
+ var AuthTokenClaims = z.looseObject({
39
36
  /** Issuer — the DID proving identity */
40
- iss: z.string().max(MAX_DID),
37
+ iss: z.string(),
41
38
  /** Subject — same as iss for auth tokens */
42
- sub: z.string().max(MAX_DID),
39
+ sub: z.string(),
43
40
  /** Audience — target relay hostname (prevents cross-relay replay) */
44
- aud: z.string().max(MAX_AUD),
41
+ aud: z.string(),
45
42
  /** Expiration — unix seconds, short-lived (minutes) */
46
43
  exp: z.number().int().positive(),
47
44
  /** Issued at — unix seconds */
@@ -187,6 +184,11 @@ var createDFOSCredential = async (options) => {
187
184
  return jwsToken;
188
185
  };
189
186
  var verifyDFOSCredential = async (jwsToken, options) => {
187
+ if (jwsToken.length > MAX_CREDENTIAL_SIZE) {
188
+ throw new CredentialVerificationError(
189
+ `credential exceeds max size: ${jwsToken.length} > ${MAX_CREDENTIAL_SIZE}`
190
+ );
191
+ }
190
192
  const decoded = decodeJwsUnsafe(jwsToken);
191
193
  if (!decoded) throw new CredentialVerificationError("failed to decode credential JWS");
192
194
  if (decoded.header.typ !== "did:dfos:credential") {
@@ -372,6 +374,7 @@ export {
372
374
  ED25519_PRIV_MULTICODEC,
373
375
  encodeEd25519Multikey,
374
376
  decodeMultikey,
377
+ MAX_CREDENTIAL_SIZE,
375
378
  Attenuation,
376
379
  DFOSCredentialPayload,
377
380
  AuthTokenClaims,