@metalabel/dfos-protocol 0.26.0 → 0.28.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
@@ -26,19 +26,25 @@ import { createJws, dagCborCanonicalEncode, verifyJws } from '@metalabel/dfos-pr
26
26
 
27
27
  ## Subpath Exports
28
28
 
29
- | Export | Description |
30
- | -------------------------------------- | ---------------------------------------------------------------------------------------- |
31
- | `@metalabel/dfos-protocol/chain` | Identity & content chains, services, artifacts, countersigns, revocations, credit claims |
32
- | `@metalabel/dfos-protocol/credentials` | Auth tokens (DID-signed JWT) and DFOS credentials for authorization |
33
- | `@metalabel/dfos-protocol/crypto` | Ed25519, JWS, JWT, dag-cbor, base64url, ID generation |
29
+ | Export | Description |
30
+ | -------------------------------------- | ------------------------------------------------------------------------------------------------------- |
31
+ | `@metalabel/dfos-protocol/chain` | Identity & content chains, services, artifacts, countersigns, revocations, credit claims, sign requests |
32
+ | `@metalabel/dfos-protocol/credentials` | Auth tokens (DID-signed JWT) and DFOS credentials for authorization |
33
+ | `@metalabel/dfos-protocol/crypto` | Ed25519, JWS, JWT, dag-cbor, base64url, ID generation |
34
+ | `@metalabel/dfos-protocol/fold` | Canonical linearization and LWW-map folds for index documents |
34
35
 
35
36
  ## Specifications
36
37
 
37
- | Document | Description |
38
- | ------------------------------------------------ | -------------------------------------------------------------- |
39
- | [PROTOCOL.md](../../specs/PROTOCOL.md) | Core protocol — chains, signatures, verification, test vectors |
40
- | [DID-METHOD.md](../../specs/DID-METHOD.md) | W3C DID method specification for `did:dfos` |
41
- | [CONTENT-MODEL.md](../../specs/CONTENT-MODEL.md) | Standard content schemas (post, profile) |
38
+ | Document | Description |
39
+ | ------------------------------------------------ | --------------------------------------------------------------------------------- |
40
+ | [PROTOCOL.md](../../specs/PROTOCOL.md) | Core protocol — chains, signatures, verification, test vectors |
41
+ | [DID-METHOD.md](../../specs/DID-METHOD.md) | W3C DID method specification for `did:dfos` |
42
+ | [CONTENT-MODEL.md](../../specs/CONTENT-MODEL.md) | Standard content schemas (post, profile) |
43
+ | [CREDENTIALS.md](../../specs/CREDENTIALS.md) | UCAN-style authorization credentials for the DFOS protocol |
44
+ | [CREDITS.md](../../specs/CREDITS.md) | Verifiable attribution for DFOS content |
45
+ | [SIGNING.md](../../specs/SIGNING.md) | A transport-agnostic way for one party to ask another to produce a DFOS signature |
46
+
47
+ Release history lives at https://github.com/metalabel/dfos/releases.
42
48
 
43
49
  ## Examples
44
50
 
@@ -1,5 +1,5 @@
1
- import { I as IdentityOperation, q as Signer, s as VerifiedIdentity, S as ServiceEntry, d as ContentOperation, R as RevocationChecker, e as CountersignPayload, a as ArtifactPayload } from '../dfos-credential-CAYCqUCP.js';
2
- export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, g as CreditClaimPayload, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as MultikeyPublicKey, o as RevocationPayload, p as ServicesArray, x as parseProtocolTimestampUnix } from '../dfos-credential-CAYCqUCP.js';
1
+ import { I as IdentityOperation, t as Signer, v as VerifiedIdentity, S as ServiceEntry, d as ContentOperation, R as RevocationChecker, e as CountersignPayload, a as ArtifactPayload } from '../dfos-credential-DU7WvoHE.js';
2
+ export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, g as CreditClaimPayload, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as MAX_SIGN_REQUEST_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_SIZE, p as MultikeyPublicKey, q as RevocationPayload, r as ServicesArray, s as SignRequestPayload, B as parseProtocolTimestampUnix } from '../dfos-credential-DU7WvoHE.js';
3
3
  import 'zod';
4
4
 
5
5
  /** Ed25519 public key multicodec value */
@@ -437,4 +437,69 @@ declare const verifyCreditEntry: (entry: CreditEntry, options: {
437
437
  contentId: string;
438
438
  }) => Promise<VerifiedCreditEntry>;
439
439
 
440
- export { type AnchorKind, ArtifactPayload, ContentOperation, CountersignPayload, type CreditClaimFailureReason, CreditClaimVerifyError, type CreditEntry, type CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, IdentityOperation, RECOGNIZED_SERVICE_TYPES, ServiceEntry, Signer, type VerifiedArtifact, type VerifiedContentChain, type VerifiedCountersignature, type VerifiedCreditClaim, type VerifiedCreditEntry, VerifiedIdentity, type VerifiedRevocation, anchorsByLabel, assertServicesWithinCap, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation };
440
+ interface VerifiedSignRequest {
441
+ /** Requester DID */
442
+ did: string;
443
+ /** The one identity being asked to sign */
444
+ subject: string;
445
+ /** JWS typ the produced artifact must carry */
446
+ payloadTyp: string;
447
+ /** Exact decoded target bytes; never re-serialized by the envelope path */
448
+ payloadBytes: Uint8Array;
449
+ createdAt: string;
450
+ expiresAt: string;
451
+ /** kid from the JWS header */
452
+ signerKeyId: string;
453
+ /** CID of the sign-request payload */
454
+ requestCID: string;
455
+ }
456
+ type SignRequestFailureReason = 'invalid' | 'unverifiable';
457
+ /**
458
+ * Thrown by sign-request verification and canonical-payload refusal paths.
459
+ * Consumers branch on `reason`, never on diagnostic message text.
460
+ */
461
+ declare class SignRequestVerifyError extends Error {
462
+ readonly reason: SignRequestFailureReason;
463
+ constructor(reason: SignRequestFailureReason, message: string);
464
+ }
465
+ /**
466
+ * Build a sign-request envelope around exact target bytes.
467
+ *
468
+ * The kid is derived from `did` + `keyId`, so a requester mismatch is
469
+ * unrepresentable on the build path. Both timestamps, including overrides, are
470
+ * floor-normalized to whole seconds before signing.
471
+ */
472
+ declare const buildSignRequest: (input: {
473
+ did: string;
474
+ subject: string;
475
+ payloadTyp: string;
476
+ payload: Uint8Array;
477
+ expiresAt: string;
478
+ createdAt?: string;
479
+ signer: Signer;
480
+ keyId: string;
481
+ }) => Promise<{
482
+ jwsToken: string;
483
+ requestCID: string;
484
+ }>;
485
+ /**
486
+ * Verify a sign-request envelope in SIGNING.md's exact 1–9 order.
487
+ *
488
+ * `resolveIdentity` supplies CURRENT identity state. A missing identity or
489
+ * resolver failure is `unverifiable`; a deleted identity, missing current key,
490
+ * or any checked-and-failed condition is `invalid`.
491
+ */
492
+ declare const verifySignRequest: (jwsToken: string, options: {
493
+ resolveIdentity: (did: string) => Promise<VerifiedIdentity | undefined>;
494
+ /** Unix milliseconds; defaults to Date.now() */
495
+ now?: number;
496
+ }) => Promise<VerifiedSignRequest>;
497
+ /**
498
+ * Assert that exact target bytes are the unique canonical representation the
499
+ * signer understands. SIGNING 0.1 implements only `did:dfos:credit-claim`.
500
+ */
501
+ declare const assertCanonicalSignRequestPayload: (payloadTyp: string, payloadBytes: Uint8Array, context: {
502
+ subject: string;
503
+ }) => void;
504
+
505
+ export { type AnchorKind, ArtifactPayload, ContentOperation, CountersignPayload, type CreditClaimFailureReason, CreditClaimVerifyError, type CreditEntry, type CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, IdentityOperation, RECOGNIZED_SERVICE_TYPES, ServiceEntry, type SignRequestFailureReason, SignRequestVerifyError, Signer, type VerifiedArtifact, type VerifiedContentChain, type VerifiedCountersignature, type VerifiedCreditClaim, type VerifiedCreditEntry, VerifiedIdentity, type VerifiedRevocation, type VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest };
@@ -13,14 +13,20 @@ import {
13
13
  MAX_OPERATION_SIZE,
14
14
  MAX_SERVICES_ENTRIES,
15
15
  MAX_SERVICES_PAYLOAD_SIZE,
16
+ MAX_SIGN_REQUEST_PAYLOAD_SIZE,
17
+ MAX_SIGN_REQUEST_SIZE,
16
18
  MultikeyPublicKey,
17
19
  RECOGNIZED_SERVICE_TYPES,
18
20
  RevocationPayload,
19
21
  ServiceEntry,
20
22
  ServicesArray,
23
+ SignRequestPayload,
24
+ SignRequestVerifyError,
21
25
  VerifiedIdentity,
22
26
  anchorsByLabel,
27
+ assertCanonicalSignRequestPayload,
23
28
  assertServicesWithinCap,
29
+ buildSignRequest,
24
30
  classifyAnchor,
25
31
  deriveChainIdentifier,
26
32
  deriveContentId,
@@ -41,14 +47,15 @@ import {
41
47
  verifyCreditEntry,
42
48
  verifyIdentityChain,
43
49
  verifyIdentityExtensionFromTrustedState,
44
- verifyRevocation
45
- } from "../chunk-3USIENKC.js";
50
+ verifyRevocation,
51
+ verifySignRequest
52
+ } from "../chunk-W4ESJVMO.js";
46
53
  import {
47
54
  ED25519_PRIV_MULTICODEC,
48
55
  ED25519_PUB_MULTICODEC,
49
56
  decodeMultikey,
50
57
  encodeEd25519Multikey
51
- } from "../chunk-PGFHCBGH.js";
58
+ } from "../chunk-6HVYO5OS.js";
52
59
  import "../chunk-4QQ5HK5M.js";
53
60
  export {
54
61
  ARTIFACT_CID_ANCHOR_RE,
@@ -67,14 +74,20 @@ export {
67
74
  MAX_OPERATION_SIZE,
68
75
  MAX_SERVICES_ENTRIES,
69
76
  MAX_SERVICES_PAYLOAD_SIZE,
77
+ MAX_SIGN_REQUEST_PAYLOAD_SIZE,
78
+ MAX_SIGN_REQUEST_SIZE,
70
79
  MultikeyPublicKey,
71
80
  RECOGNIZED_SERVICE_TYPES,
72
81
  RevocationPayload,
73
82
  ServiceEntry,
74
83
  ServicesArray,
84
+ SignRequestPayload,
85
+ SignRequestVerifyError,
75
86
  VerifiedIdentity,
76
87
  anchorsByLabel,
88
+ assertCanonicalSignRequestPayload,
77
89
  assertServicesWithinCap,
90
+ buildSignRequest,
78
91
  classifyAnchor,
79
92
  decodeMultikey,
80
93
  deriveChainIdentifier,
@@ -97,5 +110,6 @@ export {
97
110
  verifyCreditEntry,
98
111
  verifyIdentityChain,
99
112
  verifyIdentityExtensionFromTrustedState,
100
- verifyRevocation
113
+ verifyRevocation,
114
+ verifySignRequest
101
115
  };
@@ -323,6 +323,9 @@ var isAttenuated = (parentAtt, childAtt) => {
323
323
  if (childRes.type === "chain" && parentRes.type === "chain") {
324
324
  return childRes.id === parentRes.id;
325
325
  }
326
+ if (childRes.type !== "chain" && parentRes.type !== "chain") {
327
+ return childEntry.resource === parentEntry.resource;
328
+ }
326
329
  return false;
327
330
  });
328
331
  });
@@ -5,8 +5,11 @@ import {
5
5
  matchesResource,
6
6
  verifyDFOSCredential,
7
7
  verifyDelegationChain
8
- } from "./chunk-PGFHCBGH.js";
8
+ } from "./chunk-6HVYO5OS.js";
9
9
  import {
10
+ assertJwsProfile,
11
+ base64urlDecode,
12
+ base64urlEncode,
10
13
  createJws,
11
14
  dagCborCanonicalEncode,
12
15
  decodeJwsUnsafe,
@@ -93,10 +96,17 @@ var IdentityDelete = z.looseObject({
93
96
  previousOperationCID: CIDString,
94
97
  createdAt: Iso8601
95
98
  });
99
+ var IdentityRestore = z.looseObject({
100
+ version: z.literal(1),
101
+ type: z.literal("restore"),
102
+ previousOperationCID: CIDString,
103
+ createdAt: Iso8601
104
+ });
96
105
  var IdentityOperation = z.discriminatedUnion("type", [
97
106
  IdentityCreate,
98
107
  IdentityUpdate,
99
- IdentityDelete
108
+ IdentityDelete,
109
+ IdentityRestore
100
110
  ]);
101
111
  var VerifiedIdentity = z.strictObject({
102
112
  did: z.string(),
@@ -174,6 +184,18 @@ var CreditClaimPayload = z.looseObject({
174
184
  createdAt: Iso8601,
175
185
  asOfDocumentCID: CIDString.min(1, "asOfDocumentCID must be non-empty when present").optional()
176
186
  });
187
+ var MAX_SIGN_REQUEST_SIZE = 8192;
188
+ var MAX_SIGN_REQUEST_PAYLOAD_SIZE = 4096;
189
+ var SignRequestPayload = z.looseObject({
190
+ version: z.literal(1),
191
+ type: z.literal("sign-request"),
192
+ did: z.string().regex(/^did:/, "did must be a DID (did: prefix)"),
193
+ subject: z.string().regex(/^did:/, "subject must be a DID (did: prefix)"),
194
+ payloadTyp: z.string().min(1),
195
+ payload: z.string().min(1),
196
+ createdAt: Iso8601,
197
+ expiresAt: Iso8601
198
+ });
177
199
 
178
200
  // src/chain/derivation.ts
179
201
  var deriveChainIdentifier = (cidBytes, prefix) => {
@@ -242,7 +264,12 @@ var verifyIdentityChain = async (input) => {
242
264
  if (decoded.header.typ !== "did:dfos:identity-op") {
243
265
  throw new Error(`log[${idx}]: invalid typ: ${decoded.header.typ}`);
244
266
  }
245
- if (state.isDeleted) throw new Error(`log[${idx}]: cannot modify a deleted identity`);
267
+ if (state.isDeleted && op.type !== "restore") {
268
+ throw new Error(`log[${idx}]: cannot modify a deleted identity`);
269
+ }
270
+ if (!state.isDeleted && op.type === "restore") {
271
+ throw new Error(`log[${idx}]: restore must immediately follow delete`);
272
+ }
246
273
  if (idx === 0 && op.type !== "create") {
247
274
  throw new Error(`log[${idx}]: first operation must be create`);
248
275
  }
@@ -258,7 +285,7 @@ var verifyIdentityChain = async (input) => {
258
285
  state.controllerKeys = op.controllerKeys;
259
286
  state.services = op.services ?? [];
260
287
  }
261
- if (op.type === "update" || op.type === "delete") {
288
+ if (op.type !== "create") {
262
289
  if (op.previousOperationCID !== state.previousOperationCID) {
263
290
  throw new Error(`log[${idx}]: previousCID is incorrect`);
264
291
  }
@@ -355,6 +382,9 @@ var verifyIdentityChain = async (input) => {
355
382
  case "delete":
356
383
  state.isDeleted = true;
357
384
  break;
385
+ case "restore":
386
+ state.isDeleted = false;
387
+ break;
358
388
  }
359
389
  }
360
390
  if (!state.did) throw new Error("did is not set");
@@ -369,9 +399,6 @@ var verifyIdentityChain = async (input) => {
369
399
  };
370
400
  var verifyIdentityExtensionFromTrustedState = async (input) => {
371
401
  const { currentState, headCID, lastCreatedAt, newOp } = input;
372
- if (currentState.isDeleted) {
373
- throw new Error("cannot extend a deleted identity");
374
- }
375
402
  const decoded = decodeJwsUnsafe(newOp);
376
403
  if (!decoded) throw new Error("failed to decode JWS");
377
404
  const result = IdentityOperation.safeParse(decoded.payload);
@@ -380,6 +407,12 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
380
407
  throw new Error(messages);
381
408
  }
382
409
  const op = result.data;
410
+ if (currentState.isDeleted && op.type !== "restore") {
411
+ throw new Error("cannot extend a deleted identity");
412
+ }
413
+ if (!currentState.isDeleted && op.type === "restore") {
414
+ throw new Error("restore must immediately follow delete");
415
+ }
383
416
  if (decoded.header.typ !== "did:dfos:identity-op") {
384
417
  throw new Error(`invalid typ: ${decoded.header.typ}`);
385
418
  }
@@ -428,21 +461,37 @@ var verifyIdentityExtensionFromTrustedState = async (input) => {
428
461
  });
429
462
  if (op.services) await assertServicesWithinCap(op.services);
430
463
  }
431
- const newState = op.type === "update" ? {
432
- did: currentState.did,
433
- isDeleted: false,
434
- authKeys: op.authKeys,
435
- assertKeys: op.assertKeys,
436
- controllerKeys: op.controllerKeys,
437
- services: op.services ?? []
438
- } : {
439
- did: currentState.did,
440
- isDeleted: true,
441
- authKeys: currentState.authKeys,
442
- assertKeys: currentState.assertKeys,
443
- controllerKeys: currentState.controllerKeys,
444
- services: currentState.services
445
- };
464
+ const newState = (() => {
465
+ switch (op.type) {
466
+ case "update":
467
+ return {
468
+ did: currentState.did,
469
+ isDeleted: false,
470
+ authKeys: op.authKeys,
471
+ assertKeys: op.assertKeys,
472
+ controllerKeys: op.controllerKeys,
473
+ services: op.services ?? []
474
+ };
475
+ case "delete":
476
+ return {
477
+ did: currentState.did,
478
+ isDeleted: true,
479
+ authKeys: currentState.authKeys,
480
+ assertKeys: currentState.assertKeys,
481
+ controllerKeys: currentState.controllerKeys,
482
+ services: currentState.services
483
+ };
484
+ case "restore":
485
+ return {
486
+ did: currentState.did,
487
+ isDeleted: false,
488
+ authKeys: currentState.authKeys,
489
+ assertKeys: currentState.assertKeys,
490
+ controllerKeys: currentState.controllerKeys,
491
+ services: currentState.services
492
+ };
493
+ }
494
+ })();
446
495
  return { state: newState, operationCID, createdAt: op.createdAt };
447
496
  };
448
497
 
@@ -1045,6 +1094,248 @@ var verifyCreditEntry = async (entry, options) => {
1045
1094
  };
1046
1095
  };
1047
1096
 
1097
+ // src/chain/sign-request.ts
1098
+ var SignRequestVerifyError = class extends Error {
1099
+ reason;
1100
+ constructor(reason, message) {
1101
+ super(message);
1102
+ this.name = "SignRequestVerifyError";
1103
+ this.reason = reason;
1104
+ }
1105
+ };
1106
+ var invalid2 = (message) => new SignRequestVerifyError("invalid", message);
1107
+ var unverifiable2 = (message) => new SignRequestVerifyError("unverifiable", message);
1108
+ var normalizeSignRequestTimestamp = (value, field) => {
1109
+ if (value === void 0) {
1110
+ return (/* @__PURE__ */ new Date()).toISOString().replace(/\d{3}Z$/, "000Z");
1111
+ }
1112
+ const ms = Date.parse(value);
1113
+ if (Number.isNaN(ms)) {
1114
+ throw new Error(`invalid sign request payload: unparseable ${field}: ${value}`);
1115
+ }
1116
+ return new Date(Math.floor(ms / 1e3) * 1e3).toISOString();
1117
+ };
1118
+ var assertTemporalWindow = (createdAt, expiresAt, makeError) => {
1119
+ const createdMs = Date.parse(createdAt);
1120
+ const expiresMs = Date.parse(expiresAt);
1121
+ if (expiresMs <= createdMs) {
1122
+ throw makeError("sign request expiresAt must be strictly after createdAt");
1123
+ }
1124
+ if (expiresMs - createdMs > 6048e5) {
1125
+ throw makeError("sign request validity window exceeds 604800 seconds");
1126
+ }
1127
+ };
1128
+ var decodeTargetPayload = (encoded) => {
1129
+ if (!/^[A-Za-z0-9_-]+$/.test(encoded)) {
1130
+ throw invalid2("sign request payload must be unpadded base64url");
1131
+ }
1132
+ let decoded;
1133
+ try {
1134
+ decoded = base64urlDecode(encoded);
1135
+ } catch {
1136
+ throw invalid2("sign request payload is not valid base64url");
1137
+ }
1138
+ if (base64urlEncode(decoded) !== encoded) {
1139
+ throw invalid2("sign request payload is not canonical unpadded base64url");
1140
+ }
1141
+ if (decoded.length === 0) {
1142
+ throw invalid2("sign request payload must decode to non-empty bytes");
1143
+ }
1144
+ if (decoded.length > MAX_SIGN_REQUEST_PAYLOAD_SIZE) {
1145
+ throw invalid2(
1146
+ `sign request payload exceeds max decoded size: ${decoded.length} > ${MAX_SIGN_REQUEST_PAYLOAD_SIZE}`
1147
+ );
1148
+ }
1149
+ return decoded;
1150
+ };
1151
+ var resolveCurrentKey = (identity, kid) => {
1152
+ const hashIdx = kid.indexOf("#");
1153
+ if (hashIdx < 0) throw invalid2("sign request kid must be a DID URL");
1154
+ const keyId = kid.substring(hashIdx + 1);
1155
+ const key = [...identity.authKeys, ...identity.assertKeys, ...identity.controllerKeys].find(
1156
+ (candidate) => candidate.id === keyId
1157
+ );
1158
+ if (!key) throw invalid2(`key ${keyId} not found on current identity ${identity.did}`);
1159
+ try {
1160
+ return decodeMultikey(key.publicKeyMultibase).keyBytes;
1161
+ } catch {
1162
+ throw invalid2(`key ${keyId} on identity ${identity.did} is not a valid Ed25519 multikey`);
1163
+ }
1164
+ };
1165
+ var buildSignRequest = async (input) => {
1166
+ if (input.payload.length === 0) {
1167
+ throw new Error("invalid sign request payload: target payload must be non-empty");
1168
+ }
1169
+ if (input.payload.length > MAX_SIGN_REQUEST_PAYLOAD_SIZE) {
1170
+ throw new Error(
1171
+ `sign request payload exceeds max decoded size: ${input.payload.length} > ${MAX_SIGN_REQUEST_PAYLOAD_SIZE}`
1172
+ );
1173
+ }
1174
+ const createdAt = normalizeSignRequestTimestamp(input.createdAt, "createdAt");
1175
+ const expiresAt = normalizeSignRequestTimestamp(input.expiresAt, "expiresAt");
1176
+ assertTemporalWindow(createdAt, expiresAt, (message) => new Error(message));
1177
+ const payload = {
1178
+ version: 1,
1179
+ type: "sign-request",
1180
+ did: input.did,
1181
+ subject: input.subject,
1182
+ payloadTyp: input.payloadTyp,
1183
+ payload: base64urlEncode(input.payload),
1184
+ createdAt,
1185
+ expiresAt
1186
+ };
1187
+ const parsed = SignRequestPayload.safeParse(payload);
1188
+ if (!parsed.success) {
1189
+ const messages = parsed.error.issues.map((issue) => issue.message).join(", ");
1190
+ throw new Error(`invalid sign request payload: ${messages}`);
1191
+ }
1192
+ const encoded = await dagCborCanonicalEncode(payload);
1193
+ const requestCID = encoded.cid.toString();
1194
+ const jwsToken = await createJws({
1195
+ header: {
1196
+ alg: "EdDSA",
1197
+ typ: "did:dfos:sign-request",
1198
+ kid: `${input.did}#${input.keyId}`,
1199
+ cid: requestCID
1200
+ },
1201
+ payload,
1202
+ sign: input.signer
1203
+ });
1204
+ if (new TextEncoder().encode(jwsToken).length > MAX_SIGN_REQUEST_SIZE) {
1205
+ throw new Error(
1206
+ `sign request exceeds max size: ${new TextEncoder().encode(jwsToken).length} > ${MAX_SIGN_REQUEST_SIZE}`
1207
+ );
1208
+ }
1209
+ return { jwsToken, requestCID };
1210
+ };
1211
+ var verifySignRequest = async (jwsToken, options) => {
1212
+ try {
1213
+ const tokenSize = new TextEncoder().encode(jwsToken).length;
1214
+ if (tokenSize > MAX_SIGN_REQUEST_SIZE) {
1215
+ throw invalid2(`sign request exceeds max size: ${tokenSize} > ${MAX_SIGN_REQUEST_SIZE}`);
1216
+ }
1217
+ const decoded = decodeJwsUnsafe(jwsToken);
1218
+ if (!decoded) throw invalid2("failed to decode sign request JWS");
1219
+ const rawHeader = decoded.header;
1220
+ if (typeof rawHeader !== "object" || rawHeader === null || Array.isArray(rawHeader)) {
1221
+ throw invalid2("sign request protected header must be an object");
1222
+ }
1223
+ assertJwsProfile(rawHeader, invalid2);
1224
+ if (typeof rawHeader["typ"] !== "string" || typeof rawHeader["kid"] !== "string") {
1225
+ throw invalid2("sign request header must carry a string typ and kid");
1226
+ }
1227
+ if (decoded.header.typ !== "did:dfos:sign-request") {
1228
+ throw invalid2(`invalid sign request typ: ${decoded.header.typ}`);
1229
+ }
1230
+ const parsed = SignRequestPayload.safeParse(decoded.payload);
1231
+ if (!parsed.success) {
1232
+ const messages = parsed.error.issues.map((issue) => issue.message).join(", ");
1233
+ throw invalid2(`invalid sign request payload: ${messages}`);
1234
+ }
1235
+ const payload = parsed.data;
1236
+ const payloadBytes = decodeTargetPayload(payload.payload);
1237
+ const kid = decoded.header.kid;
1238
+ const hashIdx = kid.indexOf("#");
1239
+ if (hashIdx < 0) throw invalid2("sign request kid must be a DID URL");
1240
+ if (kid.substring(0, hashIdx) !== payload.did) {
1241
+ throw invalid2("sign request kid DID does not match payload did");
1242
+ }
1243
+ let identity;
1244
+ try {
1245
+ identity = await options.resolveIdentity(payload.did);
1246
+ } catch (error) {
1247
+ const detail = error instanceof Error ? error.message : String(error);
1248
+ throw unverifiable2(`could not resolve requester identity ${payload.did}: ${detail}`);
1249
+ }
1250
+ if (!identity) throw unverifiable2(`requester identity not found: ${payload.did}`);
1251
+ if (identity.isDeleted) throw invalid2(`requester identity is deleted: ${payload.did}`);
1252
+ const publicKey = resolveCurrentKey(identity, kid);
1253
+ try {
1254
+ verifyJws({ token: jwsToken, publicKey });
1255
+ } catch {
1256
+ throw invalid2("invalid sign request signature");
1257
+ }
1258
+ let encoded;
1259
+ try {
1260
+ encoded = await dagCborCanonicalEncode(payload);
1261
+ } catch (error) {
1262
+ const detail = error instanceof Error ? error.message : String(error);
1263
+ throw invalid2(`failed to derive sign request CID: ${detail}`);
1264
+ }
1265
+ const requestCID = encoded.cid.toString();
1266
+ if (decoded.header.cid !== requestCID) throw invalid2("sign request cid mismatch");
1267
+ assertTemporalWindow(payload.createdAt, payload.expiresAt, invalid2);
1268
+ if ((options.now ?? Date.now()) >= Date.parse(payload.expiresAt)) {
1269
+ throw invalid2("sign request is expired");
1270
+ }
1271
+ return {
1272
+ did: payload.did,
1273
+ subject: payload.subject,
1274
+ payloadTyp: payload.payloadTyp,
1275
+ payloadBytes,
1276
+ createdAt: payload.createdAt,
1277
+ expiresAt: payload.expiresAt,
1278
+ signerKeyId: kid,
1279
+ requestCID
1280
+ };
1281
+ } catch (error) {
1282
+ if (error instanceof SignRequestVerifyError) throw error;
1283
+ const detail = error instanceof Error ? error.message : String(error);
1284
+ throw unverifiable2(`sign request verification could not complete: ${detail}`);
1285
+ }
1286
+ };
1287
+ var assertCanonicalSignRequestPayload = (payloadTyp, payloadBytes, context) => {
1288
+ if (payloadTyp !== "did:dfos:credit-claim") {
1289
+ throw invalid2(`unsupported sign request payloadTyp: ${payloadTyp}`);
1290
+ }
1291
+ let source;
1292
+ try {
1293
+ source = new TextDecoder("utf-8", { fatal: true }).decode(payloadBytes);
1294
+ } catch {
1295
+ throw invalid2("sign request payload is not valid UTF-8 JSON");
1296
+ }
1297
+ if (source.startsWith("\uFEFF")) {
1298
+ throw invalid2("sign request payload must not carry a UTF-8 BOM");
1299
+ }
1300
+ let raw;
1301
+ try {
1302
+ raw = JSON.parse(source);
1303
+ } catch {
1304
+ throw invalid2("sign request payload is not valid JSON");
1305
+ }
1306
+ const parsed = CreditClaimPayload.strict().safeParse(raw);
1307
+ if (!parsed.success) {
1308
+ const messages = parsed.error.issues.map((issue) => issue.message).join(", ");
1309
+ throw invalid2(`invalid canonical credit-claim payload: ${messages}`);
1310
+ }
1311
+ const payload = parsed.data;
1312
+ if (!payload.createdAt.endsWith(".000Z")) {
1313
+ throw invalid2("credit-claim createdAt must be normalized to whole seconds");
1314
+ }
1315
+ if (payload.asOfDocumentCID !== void 0 && payload.asOfDocumentCID.length === 0) {
1316
+ throw invalid2("credit-claim asOfDocumentCID must be non-empty when present");
1317
+ }
1318
+ if (payload.did !== context.subject) {
1319
+ throw invalid2("credit-claim payload did does not match sign request subject");
1320
+ }
1321
+ if (/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/.test(payload.role)) {
1322
+ throw invalid2("credit-claim role is not well-formed unicode (lone surrogate)");
1323
+ }
1324
+ const canonical = JSON.stringify({
1325
+ version: payload.version,
1326
+ type: payload.type,
1327
+ contentId: payload.contentId,
1328
+ did: payload.did,
1329
+ role: payload.role,
1330
+ createdAt: payload.createdAt,
1331
+ ...payload.asOfDocumentCID !== void 0 ? { asOfDocumentCID: payload.asOfDocumentCID } : {}
1332
+ });
1333
+ const canonicalBytes = new TextEncoder().encode(canonical);
1334
+ if (canonicalBytes.length !== payloadBytes.length || !canonicalBytes.every((byte, index) => byte === payloadBytes[index])) {
1335
+ throw invalid2("credit-claim payload bytes are not canonical");
1336
+ }
1337
+ };
1338
+
1048
1339
  export {
1049
1340
  MAX_SERVICES_ENTRIES,
1050
1341
  MAX_SERVICES_PAYLOAD_SIZE,
@@ -1065,6 +1356,9 @@ export {
1065
1356
  RevocationPayload,
1066
1357
  MAX_CREDIT_CLAIM_SIZE,
1067
1358
  CreditClaimPayload,
1359
+ MAX_SIGN_REQUEST_SIZE,
1360
+ MAX_SIGN_REQUEST_PAYLOAD_SIZE,
1361
+ SignRequestPayload,
1068
1362
  deriveChainIdentifier,
1069
1363
  deriveContentId,
1070
1364
  assertServicesWithinCap,
@@ -1088,5 +1382,9 @@ export {
1088
1382
  CreditClaimVerifyError,
1089
1383
  signCreditClaim,
1090
1384
  verifyCreditClaim,
1091
- verifyCreditEntry
1385
+ verifyCreditEntry,
1386
+ SignRequestVerifyError,
1387
+ buildSignRequest,
1388
+ verifySignRequest,
1389
+ assertCanonicalSignRequestPayload
1092
1390
  };
@@ -1,4 +1,4 @@
1
- export { b as Attenuation, c as AuthTokenClaims, f as CredentialVerificationError, D as DFOSCredentialPayload, i as MAX_CREDENTIAL_SIZE, R as RevocationChecker, V as VerifiedDFOSCredential, r as VerifiedDelegationChain, t as createDFOSCredential, u as decodeDFOSCredentialUnsafe, v as isAttenuated, w as matchesResource, y as verifyDFOSCredential, z as verifyDelegationChain } from '../dfos-credential-CAYCqUCP.js';
1
+ export { b as Attenuation, c as AuthTokenClaims, f as CredentialVerificationError, D as DFOSCredentialPayload, i as MAX_CREDENTIAL_SIZE, R as RevocationChecker, V as VerifiedDFOSCredential, u as VerifiedDelegationChain, w as createDFOSCredential, x as decodeDFOSCredentialUnsafe, y as isAttenuated, z as matchesResource, E as verifyDFOSCredential, F as verifyDelegationChain } from '../dfos-credential-DU7WvoHE.js';
2
2
  import 'zod';
3
3
 
4
4
  interface AuthTokenCreateOptions {
@@ -13,7 +13,7 @@ import {
13
13
  verifyAuthToken,
14
14
  verifyDFOSCredential,
15
15
  verifyDelegationChain
16
- } from "../chunk-PGFHCBGH.js";
16
+ } from "../chunk-6HVYO5OS.js";
17
17
  import "../chunk-4QQ5HK5M.js";
18
18
  export {
19
19
  Attenuation,
@@ -148,6 +148,11 @@ declare const IdentityOperation: z.ZodDiscriminatedUnion<[z.ZodObject<{
148
148
  type: z.ZodLiteral<"delete">;
149
149
  previousOperationCID: z.ZodString;
150
150
  createdAt: z.ZodISODateTime;
151
+ }, z.core.$loose>, z.ZodObject<{
152
+ version: z.ZodLiteral<1>;
153
+ type: z.ZodLiteral<"restore">;
154
+ previousOperationCID: z.ZodString;
155
+ createdAt: z.ZodISODateTime;
151
156
  }, z.core.$loose>], "type">;
152
157
  type IdentityOperation = z.infer<typeof IdentityOperation>;
153
158
  declare const VerifiedIdentity: z.ZodObject<{
@@ -295,6 +300,37 @@ declare const CreditClaimPayload: z.ZodObject<{
295
300
  asOfDocumentCID: z.ZodOptional<z.ZodString>;
296
301
  }, z.core.$loose>;
297
302
  type CreditClaimPayload = z.infer<typeof CreditClaimPayload>;
303
+ /**
304
+ * Max byte length of a sign-request JWS token. Checked before any decode on the
305
+ * verify path and after construction on the build path. VALIDITY-determining:
306
+ * MUST match maxSignRequestSize in the Go reference.
307
+ */
308
+ declare const MAX_SIGN_REQUEST_SIZE = 8192;
309
+ /**
310
+ * Max decoded byte length of the exact target payload carried by a sign request.
311
+ * This is the single aggregate cap on target bytes; there are no per-field caps.
312
+ * VALIDITY-determining: MUST match maxSignRequestPayloadSize in Go.
313
+ */
314
+ declare const MAX_SIGN_REQUEST_PAYLOAD_SIZE = 4096;
315
+ /**
316
+ * Sign request: a requester's signed ask that one subject sign exact target bytes
317
+ * as one named artifact type before a bounded deadline.
318
+ *
319
+ * Unknown envelope fields are preserved-and-ignored, matching every other wire
320
+ * payload in this file. The signer-side target-payload check is deliberately
321
+ * strict instead: a signer refuses fields it cannot render (see SIGNING.md).
322
+ */
323
+ declare const SignRequestPayload: z.ZodObject<{
324
+ version: z.ZodLiteral<1>;
325
+ type: z.ZodLiteral<"sign-request">;
326
+ did: z.ZodString;
327
+ subject: z.ZodString;
328
+ payloadTyp: z.ZodString;
329
+ payload: z.ZodString;
330
+ createdAt: z.ZodISODateTime;
331
+ expiresAt: z.ZodISODateTime;
332
+ }, z.core.$loose>;
333
+ type SignRequestPayload = z.infer<typeof SignRequestPayload>;
298
334
 
299
335
  /**
300
336
  * Max byte length of a credential JWS token — the credential's analog of
@@ -462,6 +498,11 @@ declare const verifyDelegationChain: (credential: VerifiedDFOSCredential, option
462
498
  * - `chain:X` covered by `chain:*` (narrowing from wildcard — valid)
463
499
  * - `chain:*` covered by `chain:*` (exact match)
464
500
  * - `chain:*` NOT covered by `chain:X` (widening — invalid)
501
+ * - Non-`chain` types (`mailbox:<id>`, and any form a future capability
502
+ * registers): exact byte equality of the full resource string, nothing else.
503
+ * The wildcard is a `chain:`-only concept — a literal `*` id in any other
504
+ * type is an ordinary id covering only itself — and coverage never crosses
505
+ * resource types. See CREDENTIALS.md "Resource Types".
465
506
  * - Actions: child action set must be a subset of parent action set
466
507
  */
467
508
  declare const isAttenuated: (parentAtt: Attenuation[], childAtt: Attenuation[]) => boolean;
@@ -490,4 +531,4 @@ declare class CredentialVerificationError extends Error {
490
531
  constructor(message: string);
491
532
  }
492
533
 
493
- export { ARTIFACT_CID_ANCHOR_RE as A, CONTENT_ID_ANCHOR_RE as C, DFOSCredentialPayload as D, IdentityOperation as I, MAX_ARTIFACT_PAYLOAD_SIZE as M, type RevocationChecker as R, ServiceEntry as S, type VerifiedDFOSCredential as V, ArtifactPayload as a, Attenuation as b, AuthTokenClaims as c, ContentOperation as d, CountersignPayload as e, CredentialVerificationError as f, CreditClaimPayload as g, Iso8601 as h, MAX_CREDENTIAL_SIZE as i, MAX_CREDIT_CLAIM_SIZE as j, MAX_OPERATION_SIZE as k, MAX_SERVICES_ENTRIES as l, MAX_SERVICES_PAYLOAD_SIZE as m, MultikeyPublicKey as n, RevocationPayload as o, ServicesArray as p, type Signer as q, type VerifiedDelegationChain as r, VerifiedIdentity as s, createDFOSCredential as t, decodeDFOSCredentialUnsafe as u, isAttenuated as v, matchesResource as w, parseProtocolTimestampUnix as x, verifyDFOSCredential as y, verifyDelegationChain as z };
534
+ export { ARTIFACT_CID_ANCHOR_RE as A, parseProtocolTimestampUnix as B, CONTENT_ID_ANCHOR_RE as C, DFOSCredentialPayload as D, verifyDFOSCredential as E, verifyDelegationChain as F, IdentityOperation as I, MAX_ARTIFACT_PAYLOAD_SIZE as M, type RevocationChecker as R, ServiceEntry as S, type VerifiedDFOSCredential as V, ArtifactPayload as a, Attenuation as b, AuthTokenClaims as c, ContentOperation as d, CountersignPayload as e, CredentialVerificationError as f, CreditClaimPayload as g, Iso8601 as h, MAX_CREDENTIAL_SIZE as i, MAX_CREDIT_CLAIM_SIZE as j, MAX_OPERATION_SIZE as k, MAX_SERVICES_ENTRIES as l, MAX_SERVICES_PAYLOAD_SIZE as m, MAX_SIGN_REQUEST_PAYLOAD_SIZE as n, MAX_SIGN_REQUEST_SIZE as o, MultikeyPublicKey as p, RevocationPayload as q, ServicesArray as r, SignRequestPayload as s, type Signer as t, type VerifiedDelegationChain as u, VerifiedIdentity as v, createDFOSCredential as w, decodeDFOSCredentialUnsafe as x, isAttenuated as y, matchesResource as z };
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 ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation, c as AuthTokenClaims, C as CONTENT_ID_ANCHOR_RE, d as ContentOperation, e as CountersignPayload, f as CredentialVerificationError, g as CreditClaimPayload, D as DFOSCredentialPayload, I as IdentityOperation, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, i as MAX_CREDENTIAL_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as MultikeyPublicKey, R as RevocationChecker, o as RevocationPayload, S as ServiceEntry, p as ServicesArray, q as Signer, V as VerifiedDFOSCredential, r as VerifiedDelegationChain, s as VerifiedIdentity, t as createDFOSCredential, u as decodeDFOSCredentialUnsafe, v as isAttenuated, w as matchesResource, x as parseProtocolTimestampUnix, y as verifyDFOSCredential, z as verifyDelegationChain } from './dfos-credential-CAYCqUCP.js';
3
- export { AnchorKind, CreditClaimFailureReason, CreditClaimVerifyError, CreditEntry, CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedCreditClaim, VerifiedCreditEntry, VerifiedRevocation, anchorsByLabel, assertServicesWithinCap, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation } from './chain/index.js';
2
+ export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation, c as AuthTokenClaims, C as CONTENT_ID_ANCHOR_RE, d as ContentOperation, e as CountersignPayload, f as CredentialVerificationError, g as CreditClaimPayload, D as DFOSCredentialPayload, I as IdentityOperation, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, i as MAX_CREDENTIAL_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as MAX_SIGN_REQUEST_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_SIZE, p as MultikeyPublicKey, R as RevocationChecker, q as RevocationPayload, S as ServiceEntry, r as ServicesArray, s as SignRequestPayload, t as Signer, V as VerifiedDFOSCredential, u as VerifiedDelegationChain, v as VerifiedIdentity, w as createDFOSCredential, x as decodeDFOSCredentialUnsafe, y as isAttenuated, z as matchesResource, B as parseProtocolTimestampUnix, E as verifyDFOSCredential, F as verifyDelegationChain } from './dfos-credential-DU7WvoHE.js';
3
+ export { AnchorKind, CreditClaimFailureReason, CreditClaimVerifyError, CreditEntry, CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, SignRequestFailureReason, SignRequestVerifyError, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedCreditClaim, VerifiedCreditEntry, VerifiedRevocation, VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest } from './chain/index.js';
4
4
  export { AuthTokenCreateOptions, AuthTokenVerificationError, AuthTokenVerifyOptions, VerifiedAuthToken, createAuthToken, verifyAuthToken } from './credentials/index.js';
5
5
  export { FoldOperation, INDEX_V1_SCHEMA, IndexDelta, IndexDocument, IndexEntry, LwwDelta, OrderKey, byteCompare, compareHeadPreference, compareLinear, foldIndexV1, foldLwwMap, linearize } from './fold/index.js';
6
6
  import 'multiformats';
package/dist/index.js CHANGED
@@ -13,14 +13,20 @@ import {
13
13
  MAX_OPERATION_SIZE,
14
14
  MAX_SERVICES_ENTRIES,
15
15
  MAX_SERVICES_PAYLOAD_SIZE,
16
+ MAX_SIGN_REQUEST_PAYLOAD_SIZE,
17
+ MAX_SIGN_REQUEST_SIZE,
16
18
  MultikeyPublicKey,
17
19
  RECOGNIZED_SERVICE_TYPES,
18
20
  RevocationPayload,
19
21
  ServiceEntry,
20
22
  ServicesArray,
23
+ SignRequestPayload,
24
+ SignRequestVerifyError,
21
25
  VerifiedIdentity,
22
26
  anchorsByLabel,
27
+ assertCanonicalSignRequestPayload,
23
28
  assertServicesWithinCap,
29
+ buildSignRequest,
24
30
  classifyAnchor,
25
31
  deriveChainIdentifier,
26
32
  deriveContentId,
@@ -41,8 +47,9 @@ import {
41
47
  verifyCreditEntry,
42
48
  verifyIdentityChain,
43
49
  verifyIdentityExtensionFromTrustedState,
44
- verifyRevocation
45
- } from "./chunk-3USIENKC.js";
50
+ verifyRevocation,
51
+ verifySignRequest
52
+ } from "./chunk-W4ESJVMO.js";
46
53
  import {
47
54
  Attenuation,
48
55
  AuthTokenClaims,
@@ -62,7 +69,7 @@ import {
62
69
  verifyAuthToken,
63
70
  verifyDFOSCredential,
64
71
  verifyDelegationChain
65
- } from "./chunk-PGFHCBGH.js";
72
+ } from "./chunk-6HVYO5OS.js";
66
73
  import {
67
74
  JwsVerificationError,
68
75
  JwtVerificationError,
@@ -122,17 +129,23 @@ export {
122
129
  MAX_OPERATION_SIZE,
123
130
  MAX_SERVICES_ENTRIES,
124
131
  MAX_SERVICES_PAYLOAD_SIZE,
132
+ MAX_SIGN_REQUEST_PAYLOAD_SIZE,
133
+ MAX_SIGN_REQUEST_SIZE,
125
134
  MultikeyPublicKey,
126
135
  RECOGNIZED_SERVICE_TYPES,
127
136
  RevocationPayload,
128
137
  ServiceEntry,
129
138
  ServicesArray,
139
+ SignRequestPayload,
140
+ SignRequestVerifyError,
130
141
  VerifiedIdentity,
131
142
  anchorsByLabel,
143
+ assertCanonicalSignRequestPayload,
132
144
  assertJwsProfile,
133
145
  assertServicesWithinCap,
134
146
  base64urlDecode,
135
147
  base64urlEncode,
148
+ buildSignRequest,
136
149
  byteCompare,
137
150
  classifyAnchor,
138
151
  compareHeadPreference,
@@ -186,5 +199,6 @@ export {
186
199
  verifyIdentityExtensionFromTrustedState,
187
200
  verifyJws,
188
201
  verifyJwt,
189
- verifyRevocation
202
+ verifyRevocation,
203
+ verifySignRequest
190
204
  };
@@ -0,0 +1,21 @@
1
+ {
2
+ "description": "Identity chain: genesis + key rotation + delete + restore",
3
+ "type": "identity",
4
+ "chain": [
5
+ "eyJhbGciOiJFZERTQSIsInR5cCI6ImRpZDpkZm9zOmlkZW50aXR5LW9wIiwia2lkIjoia2V5X3I5ZXYzNGZ2YzIzejk5OXZlYWFmdDgzbm4yOXp2aGUiLCJjaWQiOiJiYWZ5cmVpY29naHZqem52bGl1bG94eG1iZjU0dHB6cXdhaG5xcGlsazduY3hlcGppbmVkcGtnYTNuZSJ9.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiY3JlYXRlIiwiYXV0aEtleXMiOlt7ImlkIjoia2V5X3I5ZXYzNGZ2YzIzejk5OXZlYWFmdDgzbm4yOXp2aGUiLCJ0eXBlIjoiTXVsdGlrZXkiLCJwdWJsaWNLZXlNdWx0aWJhc2UiOiJ6Nk1rcnpMTU53b0pTVjRQM1ljY1djYnRrOHZkOUx0Z01LbkxlYURMVXFMdUFTamIifV0sImFzc2VydEtleXMiOlt7ImlkIjoia2V5X3I5ZXYzNGZ2YzIzejk5OXZlYWFmdDgzbm4yOXp2aGUiLCJ0eXBlIjoiTXVsdGlrZXkiLCJwdWJsaWNLZXlNdWx0aWJhc2UiOiJ6Nk1rcnpMTU53b0pTVjRQM1ljY1djYnRrOHZkOUx0Z01LbkxlYURMVXFMdUFTamIifV0sImNvbnRyb2xsZXJLZXlzIjpbeyJpZCI6ImtleV9yOWV2MzRmdmMyM3o5OTl2ZWFhZnQ4M25uMjl6dmhlIiwidHlwZSI6Ik11bHRpa2V5IiwicHVibGljS2V5TXVsdGliYXNlIjoiejZNa3J6TE1Od29KU1Y0UDNZY2NXY2J0azh2ZDlMdGdNS25MZWFETFVxTHVBU2piIn1dLCJjcmVhdGVkQXQiOiIyMDI2LTAzLTA3VDAwOjAwOjAwLjAwMFoifQ.TeznHnzrtKOGTr0FzkDL2z-luMWnAbKXrmDbi-Exgw_xMPCnYwGHORMjw-BM28f0RoTirIAeD7d20W5RSuGuBg",
6
+ "eyJhbGciOiJFZERTQSIsInR5cCI6ImRpZDpkZm9zOmlkZW50aXR5LW9wIiwia2lkIjoiZGlkOmRmb3M6Y25ubmZ0OWY4YTJybjkzOGQ2bmt6MzhyODQ3djJrciNrZXlfcjlldjM0ZnZjMjN6OTk5dmVhYWZ0ODNubjI5enZoZSIsImNpZCI6ImJhZnlyZWliZnVoNjN1djMzaTJpNWVvb2UzYm9pdDJydXlqZWh1YnNyeWVtdXV6Nm1ydGxlajI2cmVpIn0.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoidXBkYXRlIiwicHJldmlvdXNPcGVyYXRpb25DSUQiOiJiYWZ5cmVpY29naHZqem52bGl1bG94eG1iZjU0dHB6cXdhaG5xcGlsazduY3hlcGppbmVkcGtnYTNuZSIsImF1dGhLZXlzIjpbeyJpZCI6ImtleV9lejlhODc0dGNrcjNkdjkzM2QzY2tkbjd6NnpyY3Q4IiwidHlwZSI6Ik11bHRpa2V5IiwicHVibGljS2V5TXVsdGliYXNlIjoiejZNa2ZVZDY1SnJBaGZkZ0Z1TUNjY1U5VGhRdmpCMmZKQU1VSGt1dWFqRjk5MmdLIn1dLCJhc3NlcnRLZXlzIjpbeyJpZCI6ImtleV9lejlhODc0dGNrcjNkdjkzM2QzY2tkbjd6NnpyY3Q4IiwidHlwZSI6Ik11bHRpa2V5IiwicHVibGljS2V5TXVsdGliYXNlIjoiejZNa2ZVZDY1SnJBaGZkZ0Z1TUNjY1U5VGhRdmpCMmZKQU1VSGt1dWFqRjk5MmdLIn1dLCJjb250cm9sbGVyS2V5cyI6W3siaWQiOiJrZXlfZXo5YTg3NHRja3IzZHY5MzNkM2NrZG43ejZ6cmN0OCIsInR5cGUiOiJNdWx0aWtleSIsInB1YmxpY0tleU11bHRpYmFzZSI6Ino2TWtmVWQ2NUpyQWhmZGdGdU1DY2NVOVRoUXZqQjJmSkFNVUhrdXVhakY5OTJnSyJ9XSwiY3JlYXRlZEF0IjoiMjAyNi0wMy0wN1QwMDowMTowMC4wMDBaIn0.7fqvWGEVYW9atA1uqpp7lIUOWp4dATLpLjOmFWzJN-8gTL-QnXDCeyGcBu5AXhHzO52fauwUavh1KrB6wBYuCw",
7
+ "eyJhbGciOiJFZERTQSIsInR5cCI6ImRpZDpkZm9zOmlkZW50aXR5LW9wIiwia2lkIjoiZGlkOmRmb3M6Y25ubmZ0OWY4YTJybjkzOGQ2bmt6MzhyODQ3djJrciNrZXlfZXo5YTg3NHRja3IzZHY5MzNkM2NrZG43ejZ6cmN0OCIsImNpZCI6ImJhZnlyZWljbDNhMnQ2dmh6NXZndnM1b2pkdzV3Y3dnb3ozdGF4cXF3ZXhwYnBsdG0yZ2gzcTQyenlpIn0.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiZGVsZXRlIiwicHJldmlvdXNPcGVyYXRpb25DSUQiOiJiYWZ5cmVpYmZ1aDYzdXYzM2kyaTVlb29lM2JvaXQycnV5amVodWJzcnllbXV1ejZtcnRsZWoyNnJlaSIsImNyZWF0ZWRBdCI6IjIwMjYtMDMtMDdUMDA6MDI6MDAuMDAwWiJ9.00Dy7qeK7I0hC3P1yvERLJINBLNiEV9LhG8BXdUMIGGLTsxuMcuhn3Yquq96SQa8mzl-BztzD5LMxBohYZxQAg",
8
+ "eyJhbGciOiJFZERTQSIsInR5cCI6ImRpZDpkZm9zOmlkZW50aXR5LW9wIiwia2lkIjoiZGlkOmRmb3M6Y25ubmZ0OWY4YTJybjkzOGQ2bmt6MzhyODQ3djJrciNrZXlfZXo5YTg3NHRja3IzZHY5MzNkM2NrZG43ejZ6cmN0OCIsImNpZCI6ImJhZnlyZWlleWF2dWU2dnh6dDYzdWxrcXB3ZXRmd3F2Znpka2VxNnQzcTNnd3JqbnFnaG1panJneWJhIn0.eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoicmVzdG9yZSIsInByZXZpb3VzT3BlcmF0aW9uQ0lEIjoiYmFmeXJlaWNsM2EydDZ2aHo1dmd2czVvamR3NXdjd2dvejN0YXhxcXdleHBicGx0bTJnaDNxNDJ6eWkiLCJjcmVhdGVkQXQiOiIyMDI2LTAzLTA3VDAwOjAzOjAwLjAwMFoifQ.lVKZj34IGmyf-0Un7TELSPP3i57gWMe8j5d4d06gFnh8r4hpf5_1VHMUrwwkt7CFnWcd4Ui4CdeXPKS8jpIeAg"
9
+ ],
10
+ "expected": {
11
+ "did": "did:dfos:cnnnft9f8a2rn938d6nkz38r847v2kr",
12
+ "isDeleted": false,
13
+ "controllerKeys": [
14
+ {
15
+ "id": "key_ez9a874tckr3dv933d3ckdn7z6zrct8",
16
+ "type": "Multikey",
17
+ "publicKeyMultibase": "z6MkfUd65JrAhfdgFuMCccU9ThQvjB2fJAMUHkuuajF992gK"
18
+ }
19
+ ]
20
+ }
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metalabel/dfos-protocol",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "type": "module",
5
5
  "description": "DFOS Protocol — Ed25519 signed chain primitives, services, credentials, and verification",
6
6
  "license": "MIT",