@metalabel/dfos-protocol 0.10.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 +7 -7
- package/dist/chain/index.d.ts +28 -31
- package/dist/chain/index.js +25 -7
- package/dist/{chunk-GZ7ZAIRD.js → chunk-SDUOUFTF.js} +99 -70
- package/dist/credentials/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +25 -7
- package/dist/{schemas-BhikXSf_.d.ts → schemas-Myod8ES9.d.ts} +58 -12
- package/examples/identity-services.json +38 -0
- package/package.json +2 -2
- 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, h as Signer, V as VerifiedIdentity, S as ServiceEntry, b as ContentOperation, c as CountersignPayload, a as ArtifactPayload } from '../schemas-Myod8ES9.js';
|
|
2
|
+
export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, M as MAX_ARTIFACT_PAYLOAD_SIZE, d as MAX_SERVICES_ENTRIES, e as MAX_SERVICES_PAYLOAD_SIZE, f as MultikeyPublicKey, R as RevocationPayload, g as ServicesArray } from '../schemas-Myod8ES9.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,30 +1,39 @@
|
|
|
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_SERVICES_ENTRIES,
|
|
10
|
+
MAX_SERVICES_PAYLOAD_SIZE,
|
|
8
11
|
MultikeyPublicKey,
|
|
12
|
+
RECOGNIZED_SERVICE_TYPES,
|
|
9
13
|
RevocationPayload,
|
|
14
|
+
ServiceEntry,
|
|
15
|
+
ServicesArray,
|
|
10
16
|
VerifiedIdentity,
|
|
17
|
+
anchorsByLabel,
|
|
18
|
+
assertServicesWithinCap,
|
|
19
|
+
classifyAnchor,
|
|
11
20
|
deriveChainIdentifier,
|
|
12
21
|
deriveContentId,
|
|
22
|
+
isRecognizedServiceType,
|
|
23
|
+
relayEndpoints,
|
|
13
24
|
signArtifact,
|
|
14
|
-
signBeacon,
|
|
15
25
|
signContentOperation,
|
|
16
26
|
signCountersignature,
|
|
17
27
|
signIdentityOperation,
|
|
18
28
|
signRevocation,
|
|
19
29
|
verifyArtifact,
|
|
20
|
-
verifyBeacon,
|
|
21
30
|
verifyContentChain,
|
|
22
31
|
verifyContentExtensionFromTrustedState,
|
|
23
32
|
verifyCountersignature,
|
|
24
33
|
verifyIdentityChain,
|
|
25
34
|
verifyIdentityExtensionFromTrustedState,
|
|
26
35
|
verifyRevocation
|
|
27
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-SDUOUFTF.js";
|
|
28
37
|
import {
|
|
29
38
|
ED25519_PRIV_MULTICODEC,
|
|
30
39
|
ED25519_PUB_MULTICODEC,
|
|
@@ -33,29 +42,38 @@ import {
|
|
|
33
42
|
} from "../chunk-LQFOBE6X.js";
|
|
34
43
|
import "../chunk-GQOZJKKO.js";
|
|
35
44
|
export {
|
|
45
|
+
ARTIFACT_CID_ANCHOR_RE,
|
|
36
46
|
ArtifactPayload,
|
|
37
|
-
|
|
47
|
+
CONTENT_ID_ANCHOR_RE,
|
|
38
48
|
ContentOperation,
|
|
39
49
|
CountersignPayload,
|
|
40
50
|
ED25519_PRIV_MULTICODEC,
|
|
41
51
|
ED25519_PUB_MULTICODEC,
|
|
42
52
|
IdentityOperation,
|
|
43
53
|
MAX_ARTIFACT_PAYLOAD_SIZE,
|
|
54
|
+
MAX_SERVICES_ENTRIES,
|
|
55
|
+
MAX_SERVICES_PAYLOAD_SIZE,
|
|
44
56
|
MultikeyPublicKey,
|
|
57
|
+
RECOGNIZED_SERVICE_TYPES,
|
|
45
58
|
RevocationPayload,
|
|
59
|
+
ServiceEntry,
|
|
60
|
+
ServicesArray,
|
|
46
61
|
VerifiedIdentity,
|
|
62
|
+
anchorsByLabel,
|
|
63
|
+
assertServicesWithinCap,
|
|
64
|
+
classifyAnchor,
|
|
47
65
|
decodeMultikey,
|
|
48
66
|
deriveChainIdentifier,
|
|
49
67
|
deriveContentId,
|
|
50
68
|
encodeEd25519Multikey,
|
|
69
|
+
isRecognizedServiceType,
|
|
70
|
+
relayEndpoints,
|
|
51
71
|
signArtifact,
|
|
52
|
-
signBeacon,
|
|
53
72
|
signContentOperation,
|
|
54
73
|
signCountersignature,
|
|
55
74
|
signIdentityOperation,
|
|
56
75
|
signRevocation,
|
|
57
76
|
verifyArtifact,
|
|
58
|
-
verifyBeacon,
|
|
59
77
|
verifyContentChain,
|
|
60
78
|
verifyContentExtensionFromTrustedState,
|
|
61
79
|
verifyCountersignature,
|
|
@@ -21,11 +21,49 @@ var MAX_CID = 256;
|
|
|
21
21
|
var MAX_NOTE = 256;
|
|
22
22
|
var MAX_KEYS_PER_ROLE = 16;
|
|
23
23
|
var MAX_DID = 256;
|
|
24
|
+
var MAX_SERVICE_ID = 64;
|
|
25
|
+
var MAX_SERVICE_TYPE = 64;
|
|
26
|
+
var MAX_SERVICE_STRING = 512;
|
|
27
|
+
var MAX_RELATION = 64;
|
|
28
|
+
var MAX_SERVICES_ENTRIES = 16;
|
|
29
|
+
var MAX_SERVICES_PAYLOAD_SIZE = 8192;
|
|
24
30
|
var MultikeyPublicKey = z.strictObject({
|
|
25
31
|
id: z.string().max(MAX_KEY_ID),
|
|
26
32
|
type: z.literal("Multikey"),
|
|
27
33
|
publicKeyMultibase: z.string().max(MAX_PUBLIC_KEY_MULTIBASE)
|
|
28
34
|
});
|
|
35
|
+
var CONTENT_ID_ANCHOR_RE = /^[2346789acdefhknrtvz]{31}$/;
|
|
36
|
+
var ARTIFACT_CID_ANCHOR_RE = /^baf[a-z2-7]{20,}$/;
|
|
37
|
+
var ServiceEntry = z.object({
|
|
38
|
+
id: z.string().min(1).max(MAX_SERVICE_ID),
|
|
39
|
+
type: z.string().min(1).max(MAX_SERVICE_TYPE)
|
|
40
|
+
}).catchall(z.unknown()).superRefine((entry, ctx) => {
|
|
41
|
+
if (entry.type === "DfosRelay") {
|
|
42
|
+
const endpoint = entry["endpoint"];
|
|
43
|
+
if (typeof endpoint !== "string" || endpoint.length < 1 || endpoint.length > MAX_SERVICE_STRING) {
|
|
44
|
+
ctx.addIssue({ code: "custom", message: "DfosRelay requires a non-empty endpoint string" });
|
|
45
|
+
}
|
|
46
|
+
} else if (entry.type === "ContentAnchor") {
|
|
47
|
+
const label = entry["label"];
|
|
48
|
+
const anchor = entry["anchor"];
|
|
49
|
+
if (typeof label !== "string" || label.length < 1 || label.length > MAX_SERVICE_STRING) {
|
|
50
|
+
ctx.addIssue({
|
|
51
|
+
code: "custom",
|
|
52
|
+
message: "ContentAnchor requires a non-empty label string"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (typeof anchor !== "string" || !(CONTENT_ID_ANCHOR_RE.test(anchor) || ARTIFACT_CID_ANCHOR_RE.test(anchor))) {
|
|
56
|
+
ctx.addIssue({
|
|
57
|
+
code: "custom",
|
|
58
|
+
message: "ContentAnchor anchor must be a 31-char contentId or a CIDv1 artifact CID"
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
var ServicesArray = z.array(ServiceEntry).max(MAX_SERVICES_ENTRIES).refine(
|
|
64
|
+
(arr) => new Set(arr.map((e) => e.id)).size === arr.length,
|
|
65
|
+
"service entry ids must be unique"
|
|
66
|
+
);
|
|
29
67
|
var Iso8601 = z.iso.datetime({ offset: false, precision: 3 });
|
|
30
68
|
var CIDString = z.string().max(MAX_CID);
|
|
31
69
|
var IdentityCreate = z.strictObject({
|
|
@@ -34,6 +72,9 @@ var IdentityCreate = z.strictObject({
|
|
|
34
72
|
authKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
35
73
|
assertKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
36
74
|
controllerKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
75
|
+
// Full-state discovery vocabulary. Optional so ops without services encode
|
|
76
|
+
// identically (undefined strips under canonical CBOR — CID-neutral).
|
|
77
|
+
services: ServicesArray.optional(),
|
|
37
78
|
createdAt: Iso8601
|
|
38
79
|
});
|
|
39
80
|
var IdentityUpdate = z.strictObject({
|
|
@@ -43,6 +84,8 @@ var IdentityUpdate = z.strictObject({
|
|
|
43
84
|
authKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
44
85
|
assertKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
45
86
|
controllerKeys: z.array(MultikeyPublicKey).min(1, "update must have at least one controller key").max(MAX_KEYS_PER_ROLE),
|
|
87
|
+
// Full-state: an update REPLACES the entire services set (omit to clear).
|
|
88
|
+
services: ServicesArray.optional(),
|
|
46
89
|
createdAt: Iso8601
|
|
47
90
|
});
|
|
48
91
|
var IdentityDelete = z.strictObject({
|
|
@@ -61,7 +104,9 @@ var VerifiedIdentity = z.strictObject({
|
|
|
61
104
|
isDeleted: z.boolean(),
|
|
62
105
|
authKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
63
106
|
assertKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
64
|
-
controllerKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE)
|
|
107
|
+
controllerKeys: z.array(MultikeyPublicKey).max(MAX_KEYS_PER_ROLE),
|
|
108
|
+
/** Resolved discovery vocabulary — projection of the winning head's services */
|
|
109
|
+
services: ServicesArray
|
|
65
110
|
});
|
|
66
111
|
var ContentCreate = z.strictObject({
|
|
67
112
|
version: z.literal(1),
|
|
@@ -99,13 +144,6 @@ var ContentOperation = z.discriminatedUnion("type", [
|
|
|
99
144
|
ContentUpdate,
|
|
100
145
|
ContentDelete
|
|
101
146
|
]);
|
|
102
|
-
var BeaconPayload = z.strictObject({
|
|
103
|
-
version: z.literal(1),
|
|
104
|
-
type: z.literal("beacon"),
|
|
105
|
-
did: z.string().max(MAX_DID),
|
|
106
|
-
manifestContentId: z.string().max(MAX_CID),
|
|
107
|
-
createdAt: Iso8601
|
|
108
|
-
});
|
|
109
147
|
var MAX_SCHEMA = 256;
|
|
110
148
|
var MAX_ARTIFACT_PAYLOAD_SIZE = 16384;
|
|
111
149
|
var ArtifactContent = z.object({ $schema: z.string().max(MAX_SCHEMA) }).catchall(z.unknown());
|
|
@@ -121,6 +159,7 @@ var CountersignPayload = z.strictObject({
|
|
|
121
159
|
type: z.literal("countersign"),
|
|
122
160
|
did: z.string().max(MAX_DID),
|
|
123
161
|
targetCID: CIDString,
|
|
162
|
+
relation: z.string().min(1).max(MAX_RELATION).optional(),
|
|
124
163
|
createdAt: Iso8601
|
|
125
164
|
});
|
|
126
165
|
var RevocationPayload = z.strictObject({
|
|
@@ -140,6 +179,27 @@ var deriveContentId = (cidBytes) => {
|
|
|
140
179
|
return generateIdNoPrefix({ seed: cidBytes });
|
|
141
180
|
};
|
|
142
181
|
|
|
182
|
+
// src/chain/services.ts
|
|
183
|
+
var assertServicesWithinCap = async (services) => {
|
|
184
|
+
const encoded = await dagCborCanonicalEncode(services);
|
|
185
|
+
if (encoded.bytes.length > MAX_SERVICES_PAYLOAD_SIZE) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
`services payload exceeds max size: ${encoded.bytes.length} > ${MAX_SERVICES_PAYLOAD_SIZE}`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var classifyAnchor = (anchor) => {
|
|
192
|
+
if (CONTENT_ID_ANCHOR_RE.test(anchor)) return "chain";
|
|
193
|
+
if (ARTIFACT_CID_ANCHOR_RE.test(anchor)) return "artifact";
|
|
194
|
+
return "invalid";
|
|
195
|
+
};
|
|
196
|
+
var RECOGNIZED_SERVICE_TYPES = ["DfosRelay", "ContentAnchor"];
|
|
197
|
+
var isRecognizedServiceType = (type) => RECOGNIZED_SERVICE_TYPES.includes(type);
|
|
198
|
+
var relayEndpoints = (services) => services.filter((e) => e.type === "DfosRelay").map((e) => e["endpoint"]).filter((v) => typeof v === "string");
|
|
199
|
+
var anchorsByLabel = (services, label) => services.filter(
|
|
200
|
+
(e) => e.type === "ContentAnchor" && e["label"] === label
|
|
201
|
+
);
|
|
202
|
+
|
|
143
203
|
// src/chain/identity-chain.ts
|
|
144
204
|
var signIdentityOperation = async (input) => {
|
|
145
205
|
const kid = input.identityDID ? `${input.identityDID}#${input.keyId}` : input.keyId;
|
|
@@ -162,6 +222,7 @@ var verifyIdentityChain = async (input) => {
|
|
|
162
222
|
authKeys: [],
|
|
163
223
|
assertKeys: [],
|
|
164
224
|
controllerKeys: [],
|
|
225
|
+
services: [],
|
|
165
226
|
seenKeys: /* @__PURE__ */ new Map()
|
|
166
227
|
};
|
|
167
228
|
for (const [idx, jwsToken] of input.log.entries()) {
|
|
@@ -190,6 +251,7 @@ var verifyIdentityChain = async (input) => {
|
|
|
190
251
|
state.authKeys = op.authKeys;
|
|
191
252
|
state.assertKeys = op.assertKeys;
|
|
192
253
|
state.controllerKeys = op.controllerKeys;
|
|
254
|
+
state.services = op.services ?? [];
|
|
193
255
|
}
|
|
194
256
|
if (op.type === "update" || op.type === "delete") {
|
|
195
257
|
if (op.previousOperationCID !== state.previousOperationCID) {
|
|
@@ -217,6 +279,13 @@ var verifyIdentityChain = async (input) => {
|
|
|
217
279
|
throw new Error(`log[${idx}]: cannot repeat key ids in same usage`);
|
|
218
280
|
}
|
|
219
281
|
});
|
|
282
|
+
if (op.services) {
|
|
283
|
+
try {
|
|
284
|
+
await assertServicesWithinCap(op.services);
|
|
285
|
+
} catch (e) {
|
|
286
|
+
throw new Error(`log[${idx}]: ${e.message}`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
220
289
|
}
|
|
221
290
|
const encoded = await dagCborCanonicalEncode(op);
|
|
222
291
|
const operationCID = encoded.cid.toString();
|
|
@@ -271,6 +340,7 @@ var verifyIdentityChain = async (input) => {
|
|
|
271
340
|
state.authKeys = op.authKeys;
|
|
272
341
|
state.assertKeys = op.assertKeys;
|
|
273
342
|
state.controllerKeys = op.controllerKeys;
|
|
343
|
+
state.services = op.services ?? [];
|
|
274
344
|
break;
|
|
275
345
|
case "delete":
|
|
276
346
|
state.isDeleted = true;
|
|
@@ -283,7 +353,8 @@ var verifyIdentityChain = async (input) => {
|
|
|
283
353
|
isDeleted: state.isDeleted,
|
|
284
354
|
authKeys: state.authKeys,
|
|
285
355
|
assertKeys: state.assertKeys,
|
|
286
|
-
controllerKeys: state.controllerKeys
|
|
356
|
+
controllerKeys: state.controllerKeys,
|
|
357
|
+
services: state.services
|
|
287
358
|
};
|
|
288
359
|
};
|
|
289
360
|
var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
@@ -342,19 +413,22 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
|
|
|
342
413
|
throw new Error("cannot repeat key ids in same usage");
|
|
343
414
|
}
|
|
344
415
|
});
|
|
416
|
+
if (op.services) await assertServicesWithinCap(op.services);
|
|
345
417
|
}
|
|
346
418
|
const newState = op.type === "update" ? {
|
|
347
419
|
did: currentState.did,
|
|
348
420
|
isDeleted: false,
|
|
349
421
|
authKeys: op.authKeys,
|
|
350
422
|
assertKeys: op.assertKeys,
|
|
351
|
-
controllerKeys: op.controllerKeys
|
|
423
|
+
controllerKeys: op.controllerKeys,
|
|
424
|
+
services: op.services ?? []
|
|
352
425
|
} : {
|
|
353
426
|
did: currentState.did,
|
|
354
427
|
isDeleted: true,
|
|
355
428
|
authKeys: currentState.authKeys,
|
|
356
429
|
assertKeys: currentState.assertKeys,
|
|
357
|
-
controllerKeys: currentState.controllerKeys
|
|
430
|
+
controllerKeys: currentState.controllerKeys,
|
|
431
|
+
services: currentState.services
|
|
358
432
|
};
|
|
359
433
|
return { state: newState, operationCID, createdAt: op.createdAt };
|
|
360
434
|
};
|
|
@@ -599,61 +673,6 @@ var verifyContentExtensionFromTrustedState = async (input) => {
|
|
|
599
673
|
return { state: newState, operationCID, createdAt: op.createdAt };
|
|
600
674
|
};
|
|
601
675
|
|
|
602
|
-
// src/chain/beacon.ts
|
|
603
|
-
var signBeacon = async (input) => {
|
|
604
|
-
const encoded = await dagCborCanonicalEncode(input.payload);
|
|
605
|
-
const beaconCID = encoded.cid.toString();
|
|
606
|
-
const jwsToken = await createJws({
|
|
607
|
-
header: { alg: "EdDSA", typ: "did:dfos:beacon", kid: input.kid, cid: beaconCID },
|
|
608
|
-
payload: input.payload,
|
|
609
|
-
sign: input.signer
|
|
610
|
-
});
|
|
611
|
-
return { jwsToken, beaconCID };
|
|
612
|
-
};
|
|
613
|
-
var MAX_FUTURE_MS = 5 * 60 * 1e3;
|
|
614
|
-
var verifyBeacon = async (input) => {
|
|
615
|
-
const decoded = decodeJwsUnsafe(input.jwsToken);
|
|
616
|
-
if (!decoded) throw new Error("failed to decode beacon JWS");
|
|
617
|
-
const result = BeaconPayload.safeParse(decoded.payload);
|
|
618
|
-
if (!result.success) {
|
|
619
|
-
const messages = result.error.issues.map((e) => e.message).join(", ");
|
|
620
|
-
throw new Error(`invalid beacon payload: ${messages}`);
|
|
621
|
-
}
|
|
622
|
-
const payload = result.data;
|
|
623
|
-
if (decoded.header.typ !== "did:dfos:beacon") {
|
|
624
|
-
throw new Error(`invalid beacon typ: ${decoded.header.typ}`);
|
|
625
|
-
}
|
|
626
|
-
const kid = decoded.header.kid;
|
|
627
|
-
const hashIdx = kid.indexOf("#");
|
|
628
|
-
if (hashIdx < 0) throw new Error("beacon kid must be a DID URL");
|
|
629
|
-
const kidDid = kid.substring(0, hashIdx);
|
|
630
|
-
if (kidDid !== payload.did) {
|
|
631
|
-
throw new Error("beacon kid DID does not match payload did");
|
|
632
|
-
}
|
|
633
|
-
const publicKey = await input.resolveKey(kid);
|
|
634
|
-
try {
|
|
635
|
-
verifyJws({ token: input.jwsToken, publicKey });
|
|
636
|
-
} catch {
|
|
637
|
-
throw new Error("invalid beacon signature");
|
|
638
|
-
}
|
|
639
|
-
const encoded = await dagCborCanonicalEncode(payload);
|
|
640
|
-
const beaconCID = encoded.cid.toString();
|
|
641
|
-
if (!decoded.header.cid) throw new Error("missing cid in beacon header");
|
|
642
|
-
if (decoded.header.cid !== beaconCID) throw new Error("beacon cid mismatch");
|
|
643
|
-
const now = input.now ?? Date.now();
|
|
644
|
-
const beaconTime = new Date(payload.createdAt).getTime();
|
|
645
|
-
if (beaconTime > now + MAX_FUTURE_MS) {
|
|
646
|
-
throw new Error("beacon createdAt is too far in the future");
|
|
647
|
-
}
|
|
648
|
-
return {
|
|
649
|
-
did: payload.did,
|
|
650
|
-
manifestContentId: payload.manifestContentId,
|
|
651
|
-
createdAt: payload.createdAt,
|
|
652
|
-
signerKeyId: kid,
|
|
653
|
-
beaconCID
|
|
654
|
-
};
|
|
655
|
-
};
|
|
656
|
-
|
|
657
676
|
// src/chain/countersign.ts
|
|
658
677
|
var signCountersignature = async (input) => {
|
|
659
678
|
const encoded = await dagCborCanonicalEncode(input.payload);
|
|
@@ -697,7 +716,8 @@ var verifyCountersignature = async (input) => {
|
|
|
697
716
|
return {
|
|
698
717
|
countersignCID,
|
|
699
718
|
witnessDID: payload.did,
|
|
700
|
-
targetCID: payload.targetCID
|
|
719
|
+
targetCID: payload.targetCID,
|
|
720
|
+
...payload.relation !== void 0 ? { relation: payload.relation } : {}
|
|
701
721
|
};
|
|
702
722
|
};
|
|
703
723
|
|
|
@@ -813,25 +833,34 @@ var verifyRevocation = async (input) => {
|
|
|
813
833
|
};
|
|
814
834
|
|
|
815
835
|
export {
|
|
836
|
+
MAX_SERVICES_ENTRIES,
|
|
837
|
+
MAX_SERVICES_PAYLOAD_SIZE,
|
|
816
838
|
MultikeyPublicKey,
|
|
839
|
+
CONTENT_ID_ANCHOR_RE,
|
|
840
|
+
ARTIFACT_CID_ANCHOR_RE,
|
|
841
|
+
ServiceEntry,
|
|
842
|
+
ServicesArray,
|
|
817
843
|
IdentityOperation,
|
|
818
844
|
VerifiedIdentity,
|
|
819
845
|
ContentOperation,
|
|
820
|
-
BeaconPayload,
|
|
821
846
|
MAX_ARTIFACT_PAYLOAD_SIZE,
|
|
822
847
|
ArtifactPayload,
|
|
823
848
|
CountersignPayload,
|
|
824
849
|
RevocationPayload,
|
|
825
850
|
deriveChainIdentifier,
|
|
826
851
|
deriveContentId,
|
|
852
|
+
assertServicesWithinCap,
|
|
853
|
+
classifyAnchor,
|
|
854
|
+
RECOGNIZED_SERVICE_TYPES,
|
|
855
|
+
isRecognizedServiceType,
|
|
856
|
+
relayEndpoints,
|
|
857
|
+
anchorsByLabel,
|
|
827
858
|
signIdentityOperation,
|
|
828
859
|
verifyIdentityChain,
|
|
829
860
|
verifyIdentityExtensionFromTrustedState,
|
|
830
861
|
signContentOperation,
|
|
831
862
|
verifyContentChain,
|
|
832
863
|
verifyContentExtensionFromTrustedState,
|
|
833
|
-
signBeacon,
|
|
834
|
-
verifyBeacon,
|
|
835
864
|
signCountersignature,
|
|
836
865
|
verifyCountersignature,
|
|
837
866
|
signArtifact,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { JwsHeader, JwsVerificationError, JwtClaims, JwtCreateOptions, JwtHeader, JwtVerificationError, JwtVerifyOptions, PrefixedID, assertJwsProfile, base64urlDecode, base64urlEncode, createJws, createJwt, createNewEd25519Keypair, dagCborCanonicalEncode, decodeJwsUnsafe, decodeJwtUnsafe, generateId, generateIdNoPrefix, importEd25519Keypair, isCanonicallyEqual, isValidEd25519Signature, isValidId, normalizedId, parseDagCborCID, signPayloadEd25519, verifyJws, verifyJwt } from './crypto/index.js';
|
|
2
|
-
export { A as
|
|
3
|
-
export { ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC,
|
|
2
|
+
export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, C as CONTENT_ID_ANCHOR_RE, b as ContentOperation, c as CountersignPayload, I as IdentityOperation, M as MAX_ARTIFACT_PAYLOAD_SIZE, d as MAX_SERVICES_ENTRIES, e as MAX_SERVICES_PAYLOAD_SIZE, f as MultikeyPublicKey, R as RevocationPayload, S as ServiceEntry, g as ServicesArray, h as Signer, V as VerifiedIdentity } from './schemas-Myod8ES9.js';
|
|
3
|
+
export { AnchorKind, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedRevocation, anchorsByLabel, assertServicesWithinCap, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation } from './chain/index.js';
|
|
4
4
|
export { Attenuation, AuthTokenClaims, AuthTokenCreateOptions, AuthTokenVerificationError, AuthTokenVerifyOptions, CredentialVerificationError, DFOSCredentialPayload, VerifiedAuthToken, VerifiedDFOSCredential, VerifiedDelegationChain, createAuthToken, createDFOSCredential, decodeDFOSCredentialUnsafe, isAttenuated, matchesResource, verifyAuthToken, verifyDFOSCredential, verifyDelegationChain } from './credentials/index.js';
|
|
5
5
|
import 'multiformats';
|
|
6
6
|
import 'multiformats/cid';
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,39 @@
|
|
|
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_SERVICES_ENTRIES,
|
|
10
|
+
MAX_SERVICES_PAYLOAD_SIZE,
|
|
8
11
|
MultikeyPublicKey,
|
|
12
|
+
RECOGNIZED_SERVICE_TYPES,
|
|
9
13
|
RevocationPayload,
|
|
14
|
+
ServiceEntry,
|
|
15
|
+
ServicesArray,
|
|
10
16
|
VerifiedIdentity,
|
|
17
|
+
anchorsByLabel,
|
|
18
|
+
assertServicesWithinCap,
|
|
19
|
+
classifyAnchor,
|
|
11
20
|
deriveChainIdentifier,
|
|
12
21
|
deriveContentId,
|
|
22
|
+
isRecognizedServiceType,
|
|
23
|
+
relayEndpoints,
|
|
13
24
|
signArtifact,
|
|
14
|
-
signBeacon,
|
|
15
25
|
signContentOperation,
|
|
16
26
|
signCountersignature,
|
|
17
27
|
signIdentityOperation,
|
|
18
28
|
signRevocation,
|
|
19
29
|
verifyArtifact,
|
|
20
|
-
verifyBeacon,
|
|
21
30
|
verifyContentChain,
|
|
22
31
|
verifyContentExtensionFromTrustedState,
|
|
23
32
|
verifyCountersignature,
|
|
24
33
|
verifyIdentityChain,
|
|
25
34
|
verifyIdentityExtensionFromTrustedState,
|
|
26
35
|
verifyRevocation
|
|
27
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-SDUOUFTF.js";
|
|
28
37
|
import {
|
|
29
38
|
Attenuation,
|
|
30
39
|
AuthTokenClaims,
|
|
@@ -69,11 +78,12 @@ import {
|
|
|
69
78
|
verifyJwt
|
|
70
79
|
} from "./chunk-GQOZJKKO.js";
|
|
71
80
|
export {
|
|
81
|
+
ARTIFACT_CID_ANCHOR_RE,
|
|
72
82
|
ArtifactPayload,
|
|
73
83
|
Attenuation,
|
|
74
84
|
AuthTokenClaims,
|
|
75
85
|
AuthTokenVerificationError,
|
|
76
|
-
|
|
86
|
+
CONTENT_ID_ANCHOR_RE,
|
|
77
87
|
ContentOperation,
|
|
78
88
|
CountersignPayload,
|
|
79
89
|
CredentialVerificationError,
|
|
@@ -84,12 +94,20 @@ export {
|
|
|
84
94
|
JwsVerificationError,
|
|
85
95
|
JwtVerificationError,
|
|
86
96
|
MAX_ARTIFACT_PAYLOAD_SIZE,
|
|
97
|
+
MAX_SERVICES_ENTRIES,
|
|
98
|
+
MAX_SERVICES_PAYLOAD_SIZE,
|
|
87
99
|
MultikeyPublicKey,
|
|
100
|
+
RECOGNIZED_SERVICE_TYPES,
|
|
88
101
|
RevocationPayload,
|
|
102
|
+
ServiceEntry,
|
|
103
|
+
ServicesArray,
|
|
89
104
|
VerifiedIdentity,
|
|
105
|
+
anchorsByLabel,
|
|
90
106
|
assertJwsProfile,
|
|
107
|
+
assertServicesWithinCap,
|
|
91
108
|
base64urlDecode,
|
|
92
109
|
base64urlEncode,
|
|
110
|
+
classifyAnchor,
|
|
93
111
|
createAuthToken,
|
|
94
112
|
createDFOSCredential,
|
|
95
113
|
createJws,
|
|
@@ -108,13 +126,14 @@ export {
|
|
|
108
126
|
importEd25519Keypair,
|
|
109
127
|
isAttenuated,
|
|
110
128
|
isCanonicallyEqual,
|
|
129
|
+
isRecognizedServiceType,
|
|
111
130
|
isValidEd25519Signature,
|
|
112
131
|
isValidId,
|
|
113
132
|
matchesResource,
|
|
114
133
|
normalizedId,
|
|
115
134
|
parseDagCborCID,
|
|
135
|
+
relayEndpoints,
|
|
116
136
|
signArtifact,
|
|
117
|
-
signBeacon,
|
|
118
137
|
signContentOperation,
|
|
119
138
|
signCountersignature,
|
|
120
139
|
signIdentityOperation,
|
|
@@ -122,7 +141,6 @@ export {
|
|
|
122
141
|
signRevocation,
|
|
123
142
|
verifyArtifact,
|
|
124
143
|
verifyAuthToken,
|
|
125
|
-
verifyBeacon,
|
|
126
144
|
verifyContentChain,
|
|
127
145
|
verifyContentExtensionFromTrustedState,
|
|
128
146
|
verifyCountersignature,
|
|
@@ -2,12 +2,46 @@ import { z } from 'zod';
|
|
|
2
2
|
|
|
3
3
|
/** Function that signs a byte array and returns a signature */
|
|
4
4
|
type Signer = (message: Uint8Array) => Promise<Uint8Array>;
|
|
5
|
+
/** Max number of service entries in an identity's services state */
|
|
6
|
+
declare const MAX_SERVICES_ENTRIES = 16;
|
|
7
|
+
/** Max CBOR-encoded size of the services array (bytes) — protocol constant */
|
|
8
|
+
declare const MAX_SERVICES_PAYLOAD_SIZE = 8192;
|
|
5
9
|
declare const MultikeyPublicKey: z.ZodObject<{
|
|
6
10
|
id: z.ZodString;
|
|
7
11
|
type: z.ZodLiteral<"Multikey">;
|
|
8
12
|
publicKeyMultibase: z.ZodString;
|
|
9
13
|
}, z.core.$strict>;
|
|
10
14
|
type MultikeyPublicKey = z.infer<typeof MultikeyPublicKey>;
|
|
15
|
+
/**
|
|
16
|
+
* Anchor target shapes — a ContentAnchor references a STABLE content
|
|
17
|
+
* identifier, dispatched by structural form:
|
|
18
|
+
* - 31-char contentId (content chain) → mutable, gateable
|
|
19
|
+
* - CIDv1 base32 (artifact) → immutable, public
|
|
20
|
+
* Both are stable; a chain HEAD CID (also base32 but resolves to a non-artifact
|
|
21
|
+
* op) is rejected by the shape-dispatch + resolution type check, never anchored.
|
|
22
|
+
*/
|
|
23
|
+
declare const CONTENT_ID_ANCHOR_RE: RegExp;
|
|
24
|
+
declare const ARTIFACT_CID_ANCHOR_RE: RegExp;
|
|
25
|
+
/**
|
|
26
|
+
* Service entry — discovery vocabulary in identity-chain state.
|
|
27
|
+
*
|
|
28
|
+
* Open namespace: `type` is an arbitrary bounded string. Recognized types
|
|
29
|
+
* (`DfosRelay`, `ContentAnchor`) are structurally validated; UNRECOGNIZED types
|
|
30
|
+
* are preserved verbatim and ignored (MUST-ignore-unknown) — only the common
|
|
31
|
+
* envelope (id + type) and the byte cap apply. New service types therefore
|
|
32
|
+
* never require a protocol/cross-language change.
|
|
33
|
+
*/
|
|
34
|
+
declare const ServiceEntry: z.ZodObject<{
|
|
35
|
+
id: z.ZodString;
|
|
36
|
+
type: z.ZodString;
|
|
37
|
+
}, z.core.$catchall<z.ZodUnknown>>;
|
|
38
|
+
type ServiceEntry = z.infer<typeof ServiceEntry>;
|
|
39
|
+
/** Identity services state — full-state, bounded, unique entry ids */
|
|
40
|
+
declare const ServicesArray: z.ZodArray<z.ZodObject<{
|
|
41
|
+
id: z.ZodString;
|
|
42
|
+
type: z.ZodString;
|
|
43
|
+
}, z.core.$catchall<z.ZodUnknown>>>;
|
|
44
|
+
type ServicesArray = z.infer<typeof ServicesArray>;
|
|
11
45
|
declare const IdentityOperation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
12
46
|
version: z.ZodLiteral<1>;
|
|
13
47
|
type: z.ZodLiteral<"create">;
|
|
@@ -26,6 +60,10 @@ declare const IdentityOperation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
26
60
|
type: z.ZodLiteral<"Multikey">;
|
|
27
61
|
publicKeyMultibase: z.ZodString;
|
|
28
62
|
}, z.core.$strict>>;
|
|
63
|
+
services: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
64
|
+
id: z.ZodString;
|
|
65
|
+
type: z.ZodString;
|
|
66
|
+
}, z.core.$catchall<z.ZodUnknown>>>>;
|
|
29
67
|
createdAt: z.ZodISODateTime;
|
|
30
68
|
}, z.core.$strict>, z.ZodObject<{
|
|
31
69
|
version: z.ZodLiteral<1>;
|
|
@@ -46,6 +84,10 @@ declare const IdentityOperation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
46
84
|
type: z.ZodLiteral<"Multikey">;
|
|
47
85
|
publicKeyMultibase: z.ZodString;
|
|
48
86
|
}, z.core.$strict>>;
|
|
87
|
+
services: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
88
|
+
id: z.ZodString;
|
|
89
|
+
type: z.ZodString;
|
|
90
|
+
}, z.core.$catchall<z.ZodUnknown>>>>;
|
|
49
91
|
createdAt: z.ZodISODateTime;
|
|
50
92
|
}, z.core.$strict>, z.ZodObject<{
|
|
51
93
|
version: z.ZodLiteral<1>;
|
|
@@ -72,6 +114,10 @@ declare const VerifiedIdentity: z.ZodObject<{
|
|
|
72
114
|
type: z.ZodLiteral<"Multikey">;
|
|
73
115
|
publicKeyMultibase: z.ZodString;
|
|
74
116
|
}, z.core.$strict>>;
|
|
117
|
+
services: z.ZodArray<z.ZodObject<{
|
|
118
|
+
id: z.ZodString;
|
|
119
|
+
type: z.ZodString;
|
|
120
|
+
}, z.core.$catchall<z.ZodUnknown>>>;
|
|
75
121
|
}, z.core.$strict>;
|
|
76
122
|
type VerifiedIdentity = z.infer<typeof VerifiedIdentity>;
|
|
77
123
|
declare const ContentOperation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -102,15 +148,6 @@ declare const ContentOperation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
102
148
|
authorization: z.ZodOptional<z.ZodString>;
|
|
103
149
|
}, z.core.$strict>], "type">;
|
|
104
150
|
type ContentOperation = z.infer<typeof ContentOperation>;
|
|
105
|
-
/** Beacon: floating signed manifest pointer announcement */
|
|
106
|
-
declare const BeaconPayload: z.ZodObject<{
|
|
107
|
-
version: z.ZodLiteral<1>;
|
|
108
|
-
type: z.ZodLiteral<"beacon">;
|
|
109
|
-
did: z.ZodString;
|
|
110
|
-
manifestContentId: z.ZodString;
|
|
111
|
-
createdAt: z.ZodISODateTime;
|
|
112
|
-
}, z.core.$strict>;
|
|
113
|
-
type BeaconPayload = z.infer<typeof BeaconPayload>;
|
|
114
151
|
/** Max CBOR-encoded payload size for artifacts (bytes) — protocol constant */
|
|
115
152
|
declare const MAX_ARTIFACT_PAYLOAD_SIZE = 16384;
|
|
116
153
|
/** Artifact: standalone signed inline document, immutable, CID-addressable */
|
|
@@ -124,16 +161,25 @@ declare const ArtifactPayload: z.ZodObject<{
|
|
|
124
161
|
createdAt: z.ZodISODateTime;
|
|
125
162
|
}, z.core.$strict>;
|
|
126
163
|
type ArtifactPayload = z.infer<typeof ArtifactPayload>;
|
|
127
|
-
/**
|
|
164
|
+
/**
|
|
165
|
+
* Countersign: standalone witness attestation referencing a target operation by CID.
|
|
166
|
+
*
|
|
167
|
+
* `relation` is an OPEN-namespace tag naming the nature of the attestation
|
|
168
|
+
* (e.g. `coauthors`, `endorses`, `witnessed`, `holds`, `received`). It is an
|
|
169
|
+
* arbitrary bounded string — recognized values carry social meaning to clients,
|
|
170
|
+
* unrecognized values MUST be preserved and ignored. Optional, so a bare witness
|
|
171
|
+
* attestation (no relation) encodes identically (CID-neutral).
|
|
172
|
+
*/
|
|
128
173
|
declare const CountersignPayload: z.ZodObject<{
|
|
129
174
|
version: z.ZodLiteral<1>;
|
|
130
175
|
type: z.ZodLiteral<"countersign">;
|
|
131
176
|
did: z.ZodString;
|
|
132
177
|
targetCID: z.ZodString;
|
|
178
|
+
relation: z.ZodOptional<z.ZodString>;
|
|
133
179
|
createdAt: z.ZodISODateTime;
|
|
134
180
|
}, z.core.$strict>;
|
|
135
181
|
type CountersignPayload = z.infer<typeof CountersignPayload>;
|
|
136
|
-
/** Revocation: signed credential revocation artifact, gossiped
|
|
182
|
+
/** Revocation: signed credential revocation artifact, gossiped on the proof plane */
|
|
137
183
|
declare const RevocationPayload: z.ZodObject<{
|
|
138
184
|
version: z.ZodLiteral<1>;
|
|
139
185
|
type: z.ZodLiteral<"revocation">;
|
|
@@ -143,4 +189,4 @@ declare const RevocationPayload: z.ZodObject<{
|
|
|
143
189
|
}, z.core.$strict>;
|
|
144
190
|
type RevocationPayload = z.infer<typeof RevocationPayload>;
|
|
145
191
|
|
|
146
|
-
export {
|
|
192
|
+
export { ARTIFACT_CID_ANCHOR_RE as A, CONTENT_ID_ANCHOR_RE as C, IdentityOperation as I, MAX_ARTIFACT_PAYLOAD_SIZE as M, RevocationPayload as R, ServiceEntry as S, VerifiedIdentity as V, ArtifactPayload as a, ContentOperation as b, CountersignPayload as c, MAX_SERVICES_ENTRIES as d, MAX_SERVICES_PAYLOAD_SIZE as e, MultikeyPublicKey as f, ServicesArray as g, type Signer as h };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Identity chain: genesis publishing a services set (relay locator + content/artifact anchors)",
|
|
3
|
+
"type": "identity",
|
|
4
|
+
"chain": [
|
|
5
|
+
"eyJhbGciOiJFZERTQSIsInR5cCI6ImRpZDpkZm9zOmlkZW50aXR5LW9wIiwia2lkIjoia2V5X3I5ZXYzNGZ2YzIzejk5OXZlYWFmdDgzbm4yOXp2aGUiLCJjaWQiOiJiYWZ5cmVpZGkzcXBzM3F0dHFwMjJtM3kzM2JkYmYyaXlrYnE1cjQ1ampod2EzN21nZXNvdjdzZGd6ZSJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiY3JlYXRlIiwiYXV0aEtleXMiOlt7ImlkIjoia2V5X3I5ZXYzNGZ2YzIzejk5OXZlYWFmdDgzbm4yOXp2aGUiLCJ0eXBlIjoiTXVsdGlrZXkiLCJwdWJsaWNLZXlNdWx0aWJhc2UiOiJ6Nk1rcnpMTU53b0pTVjRQM1ljY1djYnRrOHZkOUx0Z01LbkxlYURMVXFMdUFTamIifV0sImFzc2VydEtleXMiOlt7ImlkIjoia2V5X3I5ZXYzNGZ2YzIzejk5OXZlYWFmdDgzbm4yOXp2aGUiLCJ0eXBlIjoiTXVsdGlrZXkiLCJwdWJsaWNLZXlNdWx0aWJhc2UiOiJ6Nk1rcnpMTU53b0pTVjRQM1ljY1djYnRrOHZkOUx0Z01LbkxlYURMVXFMdUFTamIifV0sImNvbnRyb2xsZXJLZXlzIjpbeyJpZCI6ImtleV9yOWV2MzRmdmMyM3o5OTl2ZWFhZnQ4M25uMjl6dmhlIiwidHlwZSI6Ik11bHRpa2V5IiwicHVibGljS2V5TXVsdGliYXNlIjoiejZNa3J6TE1Od29KU1Y0UDNZY2NXY2J0azh2ZDlMdGdNS25MZWFETFVxTHVBU2piIn1dLCJzZXJ2aWNlcyI6W3siaWQiOiJyZWxheSIsInR5cGUiOiJEZm9zUmVsYXkiLCJlbmRwb2ludCI6Imh0dHBzOi8vcmVsYXkuZGZvcy5jb20ifSx7ImlkIjoicHJvZmlsZSIsInR5cGUiOiJDb250ZW50QW5jaG9yIiwibGFiZWwiOiJwcm9maWxlIiwiYW5jaG9yIjoiY3Y3bjh2a3ZyNjRjY3RmMzI5NGg5azRlYW5oZmY4eiJ9LHsiaWQiOiJhdmF0YXIiLCJ0eXBlIjoiQ29udGVudEFuY2hvciIsImxhYmVsIjoiYXZhdGFyIiwiYW5jaG9yIjoiYmFmeXJlaWV2Y3FybXZ0ejJwaXM1dGRpenQ3c2pvdG9xcW9nbDZ2cnJxZ2E2NHcydG53a3Eycm51ZHkifV0sImNyZWF0ZWRBdCI6IjIwMjYtMDMtMDdUMDA6MDU6MDAuMDAwWiJ9.HCzVJXcUzL62lxtC8omBlit1JNSWk4b4kQKjjjWT00honzZ9-k3dKusIRuhTV6gjT1M74bLVZYUxPb8kJvhHAw"
|
|
6
|
+
],
|
|
7
|
+
"controllerPublicKey": "z6MkrzLMNwoJSV4P3YccWcbtk8vd9LtgMKnLeaDLUqLuASjb",
|
|
8
|
+
"expected": {
|
|
9
|
+
"did": "did:dfos:zhkrrzrd7z623ha8tt7dt699de8r3ar",
|
|
10
|
+
"isDeleted": false,
|
|
11
|
+
"controllerKeys": [
|
|
12
|
+
{
|
|
13
|
+
"id": "key_r9ev34fvc23z999veaaft83nn29zvhe",
|
|
14
|
+
"type": "Multikey",
|
|
15
|
+
"publicKeyMultibase": "z6MkrzLMNwoJSV4P3YccWcbtk8vd9LtgMKnLeaDLUqLuASjb"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"services": [
|
|
19
|
+
{
|
|
20
|
+
"id": "relay",
|
|
21
|
+
"type": "DfosRelay",
|
|
22
|
+
"endpoint": "https://relay.dfos.com"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "profile",
|
|
26
|
+
"type": "ContentAnchor",
|
|
27
|
+
"label": "profile",
|
|
28
|
+
"anchor": "cv7n8vkvr64cctf3294h9k4eanhff8z"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "avatar",
|
|
32
|
+
"type": "ContentAnchor",
|
|
33
|
+
"label": "avatar",
|
|
34
|
+
"anchor": "bafyreievcqrmvtz2pis5tdizt7sjotoqqogl6vrrqga64w2tnwkq2rnudy"
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metalabel/dfos-protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "DFOS Protocol — Ed25519 signed chain primitives,
|
|
5
|
+
"description": "DFOS Protocol — Ed25519 signed chain primitives, services, credentials, and verification",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Metalabel <hello@metalabel.com> (https://metalabel.com)",
|
|
8
8
|
"repository": {
|
package/examples/beacon.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"description": "Beacon: signed manifest content ID announcement with witness countersignature",
|
|
3
|
-
"type": "beacon",
|
|
4
|
-
"controllerJws": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRpZDpkZm9zOmJlYWNvbiIsImtpZCI6ImRpZDpkZm9zOmNubm5mdDlmOGEycm45MzhkNm5rejM4cjg0N3Yya3Ija2V5X3I5ZXYzNGZ2YzIzejk5OXZlYWFmdDgzbm4yOXp2aGUiLCJjaWQiOiJiYWZ5cmVpYjR3MnAydTZ0bHc3N3NidGtwdnc3ZnF2d3ZrNnJ3MzdweWFtM29zb2JvNXhwM29vZWt1cSJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiYmVhY29uIiwiZGlkIjoiZGlkOmRmb3M6Y25ubmZ0OWY4YTJybjkzOGQ2bmt6MzhyODQ3djJrciIsIm1hbmlmZXN0Q29udGVudElkIjoiY3Y3bjh2a3ZyNjRjY3RmMzI5NGg5azRlYW5oZmY4eiIsImNyZWF0ZWRBdCI6IjIwMjYtMDMtMDdUMDA6MDU6MDAuMDAwWiJ9.exr0Dfb_asVXeMpnUOaql9ppeO2pifzEdId8ocXHQ6-v_XUwccQdJaL4MhKzJGUbRAa0hfRVSFRndhjJ4NN1DA",
|
|
5
|
-
"witnessJws": "eyJhbGciOiJFZERTQSIsInR5cCI6ImRpZDpkZm9zOmJlYWNvbiIsImtpZCI6ImRpZDpkZm9zOmNubm5mdDlmOGEycm45MzhkNm5rejM4cjg0N3Yya3Ija2V5X2V6OWE4NzR0Y2tyM2R2OTMzZDNja2RuN3o2enJjdDgiLCJjaWQiOiJiYWZ5cmVpYjR3MnAydTZ0bHc3N3NidGtwdnc3ZnF2d3ZrNnJ3MzdweWFtM29zb2JvNXhwM29vZWt1cSJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiYmVhY29uIiwiZGlkIjoiZGlkOmRmb3M6Y25ubmZ0OWY4YTJybjkzOGQ2bmt6MzhyODQ3djJrciIsIm1hbmlmZXN0Q29udGVudElkIjoiY3Y3bjh2a3ZyNjRjY3RmMzI5NGg5azRlYW5oZmY4eiIsImNyZWF0ZWRBdCI6IjIwMjYtMDMtMDdUMDA6MDU6MDAuMDAwWiJ9.-49R4npkmKMJtnK4sVS_x7MFOgB1RhjkZAzwycLp80g_o6y0gV0JjnUAj12as8NglccBXEk_5DdZTFs17ygKCA",
|
|
6
|
-
"controllerPublicKey": "z6MkrzLMNwoJSV4P3YccWcbtk8vd9LtgMKnLeaDLUqLuASjb",
|
|
7
|
-
"witnessPublicKey": "z6MkfUd65JrAhfdgFuMCccU9ThQvjB2fJAMUHkuuajF992gK",
|
|
8
|
-
"expected": {
|
|
9
|
-
"beaconCID": "bafyreib4w2p2u6tlw77sbtkpvw7fqvwvk6rw37pyam3osobo5xp3ooekuq",
|
|
10
|
-
"did": "did:dfos:cnnnft9f8a2rn938d6nkz38r847v2kr",
|
|
11
|
-
"manifestContentId": "cv7n8vkvr64cctf3294h9k4eanhff8z",
|
|
12
|
-
"createdAt": "2026-03-07T00:05:00.000Z"
|
|
13
|
-
}
|
|
14
|
-
}
|
package/schemas/manifest.v1.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://schemas.dfos.com/manifest/v1",
|
|
4
|
-
"title": "Manifest",
|
|
5
|
-
"description": "A manifest — a named map of protocol object references for semantic navigation. Keys are path-like labels. Values are protocol references: content chain identifiers (31-char bare hash), DIDs (did:dfos:...), or CIDs (bafyrei...). The document layer of the dark forest. Discovery is social or out-of-band.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["$schema", "entries"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"$schema": {
|
|
10
|
-
"const": "https://schemas.dfos.com/manifest/v1"
|
|
11
|
-
},
|
|
12
|
-
"entries": {
|
|
13
|
-
"type": "object",
|
|
14
|
-
"propertyNames": {
|
|
15
|
-
"pattern": "^[a-z0-9][a-z0-9._/-]*[a-z0-9]$",
|
|
16
|
-
"minLength": 2,
|
|
17
|
-
"maxLength": 128
|
|
18
|
-
},
|
|
19
|
-
"additionalProperties": {
|
|
20
|
-
"type": "string",
|
|
21
|
-
"pattern": "^[a-z0-9][a-z0-9:._/-]*$",
|
|
22
|
-
"minLength": 1,
|
|
23
|
-
"maxLength": 512
|
|
24
|
-
},
|
|
25
|
-
"description": "Named entries mapping path-like keys to protocol object references (contentId, DID, or CID)."
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"additionalProperties": false
|
|
29
|
-
}
|