@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 +7 -7
- package/dist/chain/index.d.ts +28 -31
- package/dist/chain/index.js +29 -9
- package/dist/{chunk-GQOZJKKO.js → chunk-4QQ5HK5M.js} +7 -3
- package/dist/{chunk-LQFOBE6X.js → chunk-J3XXF6F5.js} +18 -15
- package/dist/{chunk-GZ7ZAIRD.js → chunk-J5C4OXL4.js} +154 -103
- package/dist/credentials/index.d.ts +17 -6
- package/dist/credentials/index.js +4 -2
- package/dist/crypto/index.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +31 -9
- package/dist/schemas-Bb_9P8_s.d.ts +213 -0
- package/examples/identity-services.json +38 -0
- package/package.json +2 -2
- package/dist/schemas-BhikXSf_.d.ts +0 -146
- package/examples/beacon.json +0 -14
- package/schemas/manifest.v1.json +0 -29
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
|
|
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
|
|
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
|
-
- `
|
|
50
|
+
- `identity-services.json` — genesis publishing a services set (relay locator + content/artifact anchors)
|
|
51
51
|
|
|
52
52
|
## License
|
|
53
53
|
|
package/dist/chain/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IdentityOperation,
|
|
2
|
-
export { M as MAX_ARTIFACT_PAYLOAD_SIZE,
|
|
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 {
|
|
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 };
|
package/dist/chain/index.js
CHANGED
|
@@ -1,61 +1,81 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ARTIFACT_CID_ANCHOR_RE,
|
|
2
3
|
ArtifactPayload,
|
|
3
|
-
|
|
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-
|
|
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-
|
|
34
|
-
import "../chunk-
|
|
43
|
+
} from "../chunk-J3XXF6F5.js";
|
|
44
|
+
import "../chunk-4QQ5HK5M.js";
|
|
35
45
|
export {
|
|
46
|
+
ARTIFACT_CID_ANCHOR_RE,
|
|
36
47
|
ArtifactPayload,
|
|
37
|
-
|
|
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
|
|
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-
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
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.
|
|
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)
|
|
23
|
+
iss: z.string().min(1),
|
|
27
24
|
/** Audience DID or "*" for public credentials */
|
|
28
|
-
aud: z.string().min(1)
|
|
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.
|
|
35
|
+
var AuthTokenClaims = z.looseObject({
|
|
39
36
|
/** Issuer — the DID proving identity */
|
|
40
|
-
iss: z.string()
|
|
37
|
+
iss: z.string(),
|
|
41
38
|
/** Subject — same as iss for auth tokens */
|
|
42
|
-
sub: z.string()
|
|
39
|
+
sub: z.string(),
|
|
43
40
|
/** Audience — target relay hostname (prevents cross-relay replay) */
|
|
44
|
-
aud: z.string()
|
|
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,
|