cesr-ts 0.4.0 → 0.6.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.
Files changed (204) hide show
  1. package/esm/src/adapters/async-iterable.js +8 -0
  2. package/esm/src/adapters/effection.js +6 -0
  3. package/esm/src/annotate/annotator.js +12 -0
  4. package/esm/src/annotate/cli.js +12 -0
  5. package/esm/src/annotate/comments.js +5 -1
  6. package/esm/src/annotate/denot.js +6 -0
  7. package/esm/src/annotate/render.js +15 -3
  8. package/esm/src/core/bytes.js +9 -0
  9. package/esm/src/core/errors.js +3 -0
  10. package/esm/src/core/parser-engine.js +1 -1
  11. package/esm/src/core/parser-frame-parser.js +22 -18
  12. package/esm/src/core/vocabulary.js +47 -0
  13. package/esm/src/index.js +5 -0
  14. package/esm/src/parser/attachment-parser.js +4 -0
  15. package/esm/src/parser/cold-start.js +6 -0
  16. package/esm/src/parser/group-dispatch.js +2 -2
  17. package/esm/src/primitives/aggor.js +374 -30
  18. package/esm/src/primitives/bexter.js +2 -3
  19. package/esm/src/primitives/blinder.js +6 -0
  20. package/esm/src/primitives/byte-like.js +19 -0
  21. package/esm/src/primitives/cigar.js +17 -3
  22. package/esm/src/primitives/cipher.js +91 -6
  23. package/esm/src/primitives/codex.js +39 -6
  24. package/esm/src/primitives/compactor.js +307 -3
  25. package/esm/src/primitives/counter.js +6 -2
  26. package/esm/src/primitives/dater.js +1 -2
  27. package/esm/src/primitives/decimer.js +7 -11
  28. package/esm/src/primitives/decrypter.js +123 -7
  29. package/esm/src/primitives/diger.js +57 -3
  30. package/esm/src/primitives/disclosure.js +300 -0
  31. package/esm/src/primitives/encrypter.js +130 -7
  32. package/esm/src/primitives/hydrate.js +49 -0
  33. package/esm/src/primitives/ilker.js +2 -3
  34. package/esm/src/primitives/indexer.js +21 -4
  35. package/esm/src/primitives/labeler.js +1 -2
  36. package/esm/src/primitives/mapper.js +612 -35
  37. package/esm/src/primitives/matter.js +133 -3
  38. package/esm/src/primitives/mediar.js +6 -0
  39. package/esm/src/primitives/noncer.js +2 -3
  40. package/esm/src/primitives/number.js +1 -2
  41. package/esm/src/primitives/pather.js +102 -5
  42. package/esm/src/primitives/prefixer.js +1 -2
  43. package/esm/src/primitives/primitive.js +14 -0
  44. package/esm/src/primitives/registry.js +2 -0
  45. package/esm/src/primitives/saider.js +80 -3
  46. package/esm/src/primitives/salter.js +96 -2
  47. package/esm/src/primitives/sealed-box.js +41 -0
  48. package/esm/src/primitives/seqner.js +1 -2
  49. package/esm/src/primitives/siger.js +58 -3
  50. package/esm/src/primitives/signer.js +243 -9
  51. package/esm/src/primitives/streamer.js +28 -0
  52. package/esm/src/primitives/structing.js +727 -0
  53. package/esm/src/primitives/structor.js +20 -0
  54. package/esm/src/primitives/tagger.js +1 -2
  55. package/esm/src/primitives/texter.js +1 -2
  56. package/esm/src/primitives/tholder.js +552 -10
  57. package/esm/src/primitives/traitor.js +2 -3
  58. package/esm/src/primitives/verfer.js +50 -6
  59. package/esm/src/primitives/verser.js +16 -6
  60. package/esm/src/router/router-stub.js +1 -0
  61. package/esm/src/serder/native.js +1326 -0
  62. package/esm/src/serder/serder.js +1558 -59
  63. package/esm/src/serder/serdery.js +92 -7
  64. package/esm/src/serder/smell.js +26 -1
  65. package/esm/src/tables/codex-utils.js +2 -0
  66. package/esm/src/tables/counter-codex.js +2 -0
  67. package/esm/src/tables/counter-groups.js +6 -0
  68. package/esm/src/tables/versions.js +4 -0
  69. package/esm/src/version.js +5 -2
  70. package/package.json +5 -2
  71. package/types/src/adapters/async-iterable.d.ts +8 -0
  72. package/types/src/adapters/async-iterable.d.ts.map +1 -1
  73. package/types/src/adapters/effection.d.ts +7 -0
  74. package/types/src/adapters/effection.d.ts.map +1 -1
  75. package/types/src/annotate/annotator.d.ts +12 -0
  76. package/types/src/annotate/annotator.d.ts.map +1 -1
  77. package/types/src/annotate/cli.d.ts +13 -0
  78. package/types/src/annotate/cli.d.ts.map +1 -1
  79. package/types/src/annotate/comments.d.ts +4 -0
  80. package/types/src/annotate/comments.d.ts.map +1 -1
  81. package/types/src/annotate/denot.d.ts +6 -0
  82. package/types/src/annotate/denot.d.ts.map +1 -1
  83. package/types/src/annotate/render.d.ts.map +1 -1
  84. package/types/src/annotate/types.d.ts +2 -0
  85. package/types/src/annotate/types.d.ts.map +1 -1
  86. package/types/src/bench/parser-benchmark.d.ts +3 -0
  87. package/types/src/bench/parser-benchmark.d.ts.map +1 -1
  88. package/types/src/core/bytes.d.ts +9 -0
  89. package/types/src/core/bytes.d.ts.map +1 -1
  90. package/types/src/core/errors.d.ts +3 -0
  91. package/types/src/core/errors.d.ts.map +1 -1
  92. package/types/src/core/parser-engine.d.ts +4 -0
  93. package/types/src/core/parser-engine.d.ts.map +1 -1
  94. package/types/src/core/parser-frame-parser.d.ts.map +1 -1
  95. package/types/src/core/types.d.ts +2 -0
  96. package/types/src/core/types.d.ts.map +1 -1
  97. package/types/src/core/vocabulary.d.ts +48 -0
  98. package/types/src/core/vocabulary.d.ts.map +1 -0
  99. package/types/src/index.d.ts +5 -0
  100. package/types/src/index.d.ts.map +1 -1
  101. package/types/src/parser/attachment-parser.d.ts +4 -0
  102. package/types/src/parser/attachment-parser.d.ts.map +1 -1
  103. package/types/src/parser/cold-start.d.ts +6 -0
  104. package/types/src/parser/cold-start.d.ts.map +1 -1
  105. package/types/src/parser/group-dispatch.d.ts.map +1 -1
  106. package/types/src/primitives/aggor.d.ts +100 -13
  107. package/types/src/primitives/aggor.d.ts.map +1 -1
  108. package/types/src/primitives/bexter.d.ts.map +1 -1
  109. package/types/src/primitives/blinder.d.ts +6 -0
  110. package/types/src/primitives/blinder.d.ts.map +1 -1
  111. package/types/src/primitives/byte-like.d.ts +7 -0
  112. package/types/src/primitives/byte-like.d.ts.map +1 -0
  113. package/types/src/primitives/cigar.d.ts +11 -1
  114. package/types/src/primitives/cigar.d.ts.map +1 -1
  115. package/types/src/primitives/cipher.d.ts +73 -2
  116. package/types/src/primitives/cipher.d.ts.map +1 -1
  117. package/types/src/primitives/codex.d.ts +34 -4
  118. package/types/src/primitives/codex.d.ts.map +1 -1
  119. package/types/src/primitives/compactor.d.ts +94 -2
  120. package/types/src/primitives/compactor.d.ts.map +1 -1
  121. package/types/src/primitives/counter.d.ts.map +1 -1
  122. package/types/src/primitives/dater.d.ts.map +1 -1
  123. package/types/src/primitives/decimer.d.ts.map +1 -1
  124. package/types/src/primitives/decrypter.d.ts +64 -3
  125. package/types/src/primitives/decrypter.d.ts.map +1 -1
  126. package/types/src/primitives/diger.d.ts +16 -0
  127. package/types/src/primitives/diger.d.ts.map +1 -1
  128. package/types/src/primitives/disclosure.d.ts +201 -0
  129. package/types/src/primitives/disclosure.d.ts.map +1 -0
  130. package/types/src/primitives/encrypter.d.ts +66 -4
  131. package/types/src/primitives/encrypter.d.ts.map +1 -1
  132. package/types/src/primitives/hydrate.d.ts +20 -0
  133. package/types/src/primitives/hydrate.d.ts.map +1 -0
  134. package/types/src/primitives/ilker.d.ts.map +1 -1
  135. package/types/src/primitives/indexer.d.ts.map +1 -1
  136. package/types/src/primitives/labeler.d.ts.map +1 -1
  137. package/types/src/primitives/mapper.d.ts +132 -11
  138. package/types/src/primitives/mapper.d.ts.map +1 -1
  139. package/types/src/primitives/matter.d.ts +33 -1
  140. package/types/src/primitives/matter.d.ts.map +1 -1
  141. package/types/src/primitives/mediar.d.ts +6 -0
  142. package/types/src/primitives/mediar.d.ts.map +1 -1
  143. package/types/src/primitives/noncer.d.ts.map +1 -1
  144. package/types/src/primitives/number.d.ts.map +1 -1
  145. package/types/src/primitives/pather.d.ts +21 -0
  146. package/types/src/primitives/pather.d.ts.map +1 -1
  147. package/types/src/primitives/prefixer.d.ts.map +1 -1
  148. package/types/src/primitives/primitive.d.ts +26 -0
  149. package/types/src/primitives/primitive.d.ts.map +1 -1
  150. package/types/src/primitives/registry.d.ts +3 -0
  151. package/types/src/primitives/registry.d.ts.map +1 -1
  152. package/types/src/primitives/saider.d.ts +41 -0
  153. package/types/src/primitives/saider.d.ts.map +1 -1
  154. package/types/src/primitives/salter.d.ts +56 -1
  155. package/types/src/primitives/salter.d.ts.map +1 -1
  156. package/types/src/primitives/sealed-box.d.ts +29 -0
  157. package/types/src/primitives/sealed-box.d.ts.map +1 -0
  158. package/types/src/primitives/seqner.d.ts.map +1 -1
  159. package/types/src/primitives/siger.d.ts +14 -0
  160. package/types/src/primitives/siger.d.ts.map +1 -1
  161. package/types/src/primitives/signer.d.ts +80 -4
  162. package/types/src/primitives/signer.d.ts.map +1 -1
  163. package/types/src/primitives/streamer.d.ts +31 -0
  164. package/types/src/primitives/streamer.d.ts.map +1 -0
  165. package/types/src/primitives/structing.d.ts +4114 -0
  166. package/types/src/primitives/structing.d.ts.map +1 -0
  167. package/types/src/primitives/structor.d.ts +6 -0
  168. package/types/src/primitives/structor.d.ts.map +1 -1
  169. package/types/src/primitives/tagger.d.ts.map +1 -1
  170. package/types/src/primitives/texter.d.ts.map +1 -1
  171. package/types/src/primitives/tholder.d.ts +150 -5
  172. package/types/src/primitives/tholder.d.ts.map +1 -1
  173. package/types/src/primitives/traitor.d.ts.map +1 -1
  174. package/types/src/primitives/unknown.d.ts +1 -0
  175. package/types/src/primitives/unknown.d.ts.map +1 -1
  176. package/types/src/primitives/verfer.d.ts +12 -0
  177. package/types/src/primitives/verfer.d.ts.map +1 -1
  178. package/types/src/primitives/verser.d.ts +14 -3
  179. package/types/src/primitives/verser.d.ts.map +1 -1
  180. package/types/src/router/router-stub.d.ts +3 -0
  181. package/types/src/router/router-stub.d.ts.map +1 -1
  182. package/types/src/serder/native.d.ts +115 -0
  183. package/types/src/serder/native.d.ts.map +1 -0
  184. package/types/src/serder/serder.d.ts +187 -9
  185. package/types/src/serder/serder.d.ts.map +1 -1
  186. package/types/src/serder/serdery.d.ts +42 -0
  187. package/types/src/serder/serdery.d.ts.map +1 -1
  188. package/types/src/serder/smell.d.ts +22 -0
  189. package/types/src/serder/smell.d.ts.map +1 -1
  190. package/types/src/tables/codex-utils.d.ts +3 -0
  191. package/types/src/tables/codex-utils.d.ts.map +1 -1
  192. package/types/src/tables/counter-codex.d.ts +4 -0
  193. package/types/src/tables/counter-codex.d.ts.map +1 -1
  194. package/types/src/tables/counter-groups.d.ts +6 -0
  195. package/types/src/tables/counter-groups.d.ts.map +1 -1
  196. package/types/src/tables/counter.tables.generated.d.ts.map +1 -1
  197. package/types/src/tables/indexer.codex.generated.d.ts.map +1 -1
  198. package/types/src/tables/matter.codex.generated.d.ts.map +1 -1
  199. package/types/src/tables/table-types.d.ts +6 -0
  200. package/types/src/tables/table-types.d.ts.map +1 -1
  201. package/types/src/tables/versions.d.ts +6 -0
  202. package/types/src/tables/versions.d.ts.map +1 -1
  203. package/types/src/version.d.ts +5 -2
  204. package/types/src/version.d.ts.map +1 -1
@@ -1,13 +1,160 @@
1
- import { decode as decodeMsgpack } from "@msgpack/msgpack";
2
- import { t } from "../core/bytes.js";
3
- import { decodeKeriCbor } from "../core/cbor.js";
4
- import { DeserializeError } from "../core/errors.js";
1
+ import { decode as decodeMsgpack, encode as encodeMsgpack } from "@msgpack/msgpack";
2
+ import { b, t } from "../core/bytes.js";
3
+ import { decodeKeriCbor, encodeKeriCbor } from "../core/cbor.js";
4
+ import { DeserializeError, SerializeError } from "../core/errors.js";
5
+ import { Ilks } from "../core/vocabulary.js";
5
6
  import { Aggor, isAggorCode } from "../primitives/aggor.js";
6
7
  import { Blinder, isBlinderCode } from "../primitives/blinder.js";
8
+ import { DigDex, DIGEST_CODES, NON_DIGEST_PREFIX_CODES, NON_TRANSFERABLE_CODES, PREFIX_CODES, } from "../primitives/codex.js";
9
+ import { Compactor } from "../primitives/compactor.js";
10
+ import { Diger } from "../primitives/diger.js";
11
+ import { parseMatter } from "../primitives/matter.js";
7
12
  import { isMediarCode, Mediar } from "../primitives/mediar.js";
13
+ import { NumberPrimitive } from "../primitives/number.js";
8
14
  import { isCounterGroupLike, isPrimitiveTuple, } from "../primitives/primitive.js";
15
+ import { Saider } from "../primitives/saider.js";
9
16
  import { isSealerCode, Sealer } from "../primitives/sealer.js";
10
- import { Protocols } from "../tables/versions.js";
17
+ import { SealDescriptors } from "../primitives/structing.js";
18
+ import { Tholder } from "../primitives/tholder.js";
19
+ import { Verfer } from "../primitives/verfer.js";
20
+ import { resolveMUDex } from "../tables/counter-version-registry.js";
21
+ import { MATTER_SIZES } from "../tables/matter.tables.generated.js";
22
+ import { Kinds, Protocols, Vrsn_1_0, Vrsn_2_0 } from "../tables/versions.js";
23
+ import { dumpCesrNativeSad, parseCesrNativeKed } from "./native.js";
24
+ import { smell, versify } from "./smell.js";
25
+ const ACDC_COMPACT_TOP_LEVEL_ILKS = new Set([
26
+ Ilks.acm,
27
+ Ilks.ace,
28
+ Ilks.act,
29
+ Ilks.acg,
30
+ ]);
31
+ const ACDC_PARTIAL_SECTION_ILKS = new Set([
32
+ Ilks.sch,
33
+ Ilks.att,
34
+ Ilks.agg,
35
+ Ilks.edg,
36
+ Ilks.rul,
37
+ ]);
38
+ const KERI_ESTABLISHMENT_ILKS = new Set([
39
+ Ilks.icp,
40
+ Ilks.rot,
41
+ Ilks.dip,
42
+ Ilks.drt,
43
+ ]);
44
+ const ACDC_SAIDIVE_TOP_LEVEL_ILKS = new Set([
45
+ Ilks.acm,
46
+ Ilks.ace,
47
+ Ilks.act,
48
+ Ilks.acg,
49
+ Ilks.rip,
50
+ ]);
51
+ /**
52
+ * Shared CESR genus mapping for protocol messages.
53
+ *
54
+ * KERIpy keeps this indirection as `GenDex` + `ProGen`: today both KERI and
55
+ * ACDC messages ride the shared KERI message-universal genus `-_AAA`, while
56
+ * the reserved ACDC genus remains unused for serder framing.
57
+ */
58
+ const MESSAGE_GENUS_BY_PROTOCOL = Object
59
+ .freeze({
60
+ [Protocols.keri]: "-_AAA",
61
+ [Protocols.acdc]: "-_AAA",
62
+ });
63
+ function versionKey(version) {
64
+ return `${version.major}.${version.minor}`;
65
+ }
66
+ function cloneDefault(value) {
67
+ if (Array.isArray(value)) {
68
+ return value.map((entry) => cloneDefault(entry));
69
+ }
70
+ if (value && typeof value === "object") {
71
+ return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, cloneDefault(v)]));
72
+ }
73
+ return value;
74
+ }
75
+ const NUMBER_CAPACITIES = [
76
+ { code: "M", rawSize: 2 },
77
+ { code: "0H", rawSize: 4 },
78
+ { code: "R", rawSize: 5 },
79
+ { code: "N", rawSize: 8 },
80
+ { code: "S", rawSize: 11 },
81
+ { code: "T", rawSize: 14 },
82
+ { code: "0A", rawSize: 16 },
83
+ { code: "U", rawSize: 17 },
84
+ ];
85
+ function bigintToBytes(value) {
86
+ if (value < 0n) {
87
+ throw new SerializeError(`Negative CESR number=${value}`);
88
+ }
89
+ if (value === 0n) {
90
+ return new Uint8Array([0]);
91
+ }
92
+ const bytes = [];
93
+ let working = value;
94
+ while (working > 0n) {
95
+ bytes.unshift(Number(working & 0xffn));
96
+ working >>= 8n;
97
+ }
98
+ return new Uint8Array(bytes);
99
+ }
100
+ function makeNumberPrimitive(value) {
101
+ if (value === null || value === undefined) {
102
+ return null;
103
+ }
104
+ const bigint = typeof value === "string"
105
+ ? BigInt(`0x${value || "0"}`)
106
+ : typeof value === "number"
107
+ ? (() => {
108
+ if (!Number.isInteger(value) || value < 0) {
109
+ throw new SerializeError(`Invalid numeric CESR number=${value}`);
110
+ }
111
+ return BigInt(value);
112
+ })()
113
+ : (() => {
114
+ if (value < 0n) {
115
+ throw new SerializeError(`Negative CESR number=${value}`);
116
+ }
117
+ return value;
118
+ })();
119
+ const raw = bigintToBytes(bigint);
120
+ const entry = NUMBER_CAPACITIES.find(({ rawSize }) => raw.length <= rawSize);
121
+ if (!entry) {
122
+ throw new SerializeError(`Unsupported number width=${raw.length}`);
123
+ }
124
+ const padded = new Uint8Array(entry.rawSize);
125
+ padded.set(raw, entry.rawSize - raw.length);
126
+ return new NumberPrimitive({ code: entry.code, raw: padded });
127
+ }
128
+ function isPlainSadObject(value) {
129
+ return typeof value === "object" && value !== null && !Array.isArray(value);
130
+ }
131
+ const SEAL_PROJECTION_DESCRIPTORS = SealDescriptors;
132
+ function parseSealRecord(value, index) {
133
+ if (!isPlainSadObject(value)) {
134
+ throw new DeserializeError(`Invalid seal at a[${index}]: expected plain object.`);
135
+ }
136
+ for (const descriptor of SEAL_PROJECTION_DESCRIPTORS) {
137
+ if (descriptor.isSad(value)) {
138
+ return descriptor.fromSad(value);
139
+ }
140
+ }
141
+ throw new DeserializeError(`Invalid seal at a[${index}]: no known KERI seal shape matched.`);
142
+ }
143
+ function isSealEventRecord(value) {
144
+ return "i" in value && "s" in value && "d" in value;
145
+ }
146
+ /** Convert semantic `sith` content back into a `Tholder` wrapper when possible. */
147
+ function makeThreshold(value) {
148
+ if (value === null || value === undefined) {
149
+ return null;
150
+ }
151
+ try {
152
+ return new Tholder({ sith: value });
153
+ }
154
+ catch {
155
+ return null;
156
+ }
157
+ }
11
158
  function normalizeDecodedMap(value, kind) {
12
159
  if (value && typeof value === "object" && !Array.isArray(value)) {
13
160
  if (value instanceof Map) {
@@ -24,6 +171,898 @@ function normalizeDecodedMap(value, kind) {
24
171
  }
25
172
  throw new DeserializeError(`${kind} root must be a map/object`);
26
173
  }
174
+ /**
175
+ * Serialize one KERI/ACDC body using the requested wire kind.
176
+ *
177
+ * Mirrors KERIpy's `dumps()` helper: this is a format utility, not a `Serder`
178
+ * instance method, so upper layers can size or saidify SADs before they have a
179
+ * body object.
180
+ */
181
+ export function dumps(ked, kind) {
182
+ if (kind === "JSON") {
183
+ return b(JSON.stringify(ked));
184
+ }
185
+ if (kind === "MGPK") {
186
+ return encodeMsgpack(ked);
187
+ }
188
+ if (kind === "CBOR") {
189
+ return encodeKeriCbor(ked);
190
+ }
191
+ if (kind === "CESR") {
192
+ if (!ked || typeof ked !== "object" || Array.isArray(ked)) {
193
+ throw new SerializeError("CESR native body must be a map/object");
194
+ }
195
+ // Native emit is factored out so `Serder`, `Serdery`, and parser-native
196
+ // hydration all share one CESR-native serialization contract.
197
+ return dumpCesrNativeSad(ked);
198
+ }
199
+ throw new SerializeError(`Unsupported serialization kind: ${kind}`);
200
+ }
201
+ /**
202
+ * Measure one versioned SAD and rewrite its embedded version string size.
203
+ *
204
+ * Mirrors KERIpy's `sizeify()` utility closely enough for local parity work:
205
+ * callers provide a mutable SAD carrying a `v` field, optionally override the
206
+ * serialization kind, and receive the updated raw bytes plus parsed version
207
+ * metadata.
208
+ */
209
+ export function sizeify(ked, kind) {
210
+ if (typeof ked.v !== "string" || ked.v.length === 0) {
211
+ throw new SerializeError("Missing or empty version string in SAD");
212
+ }
213
+ const { smellage } = (() => {
214
+ try {
215
+ return {
216
+ smellage: parseVersionString(ked.v),
217
+ };
218
+ }
219
+ catch (error) {
220
+ throw new SerializeError(`Invalid version string in SAD: ${ked.v}`, undefined, error instanceof Error ? error.message : undefined);
221
+ }
222
+ })();
223
+ const actualKind = kind ?? smellage.kind;
224
+ let raw = dumps(ked, actualKind);
225
+ const size = raw.length;
226
+ const vs = versify({
227
+ proto: smellage.proto,
228
+ pvrsn: smellage.pvrsn,
229
+ gvrsn: smellage.gvrsn,
230
+ kind: actualKind,
231
+ size,
232
+ });
233
+ ked.v = vs;
234
+ raw = dumps(ked, actualKind);
235
+ if (raw.length !== size) {
236
+ throw new SerializeError(`Malformed version string size for ${vs}`);
237
+ }
238
+ return {
239
+ raw,
240
+ proto: smellage.proto,
241
+ kind: actualKind,
242
+ ked,
243
+ pvrsn: smellage.pvrsn,
244
+ gvrsn: smellage.gvrsn,
245
+ };
246
+ }
247
+ function parseVersionString(vs) {
248
+ return smell(b(vs)).smellage;
249
+ }
250
+ function versionFields(entries) {
251
+ return Object.fromEntries(Object.entries(entries).map(([ilk, dom]) => [
252
+ ilk,
253
+ {
254
+ alls: dom.alls,
255
+ opts: dom.opts ?? {},
256
+ alts: dom.alts ?? {},
257
+ saids: dom.saids ?? {},
258
+ strict: dom.strict ?? true,
259
+ },
260
+ ]));
261
+ }
262
+ const FIELDS = {
263
+ [Protocols.keri]: {
264
+ [versionKey(Vrsn_1_0)]: versionFields({
265
+ icp: {
266
+ alls: {
267
+ v: "",
268
+ t: "",
269
+ d: "",
270
+ i: "",
271
+ s: "0",
272
+ kt: "0",
273
+ k: [],
274
+ nt: "0",
275
+ n: [],
276
+ bt: "0",
277
+ b: [],
278
+ c: [],
279
+ a: [],
280
+ },
281
+ saids: { d: DigDex.Blake3_256, i: DigDex.Blake3_256 },
282
+ },
283
+ rot: {
284
+ alls: {
285
+ v: "",
286
+ t: "",
287
+ d: "",
288
+ i: "",
289
+ s: "0",
290
+ p: "",
291
+ kt: "0",
292
+ k: [],
293
+ nt: "0",
294
+ n: [],
295
+ bt: "0",
296
+ br: [],
297
+ ba: [],
298
+ a: [],
299
+ },
300
+ saids: { d: DigDex.Blake3_256 },
301
+ },
302
+ ixn: {
303
+ alls: { v: "", t: "", d: "", i: "", s: "0", p: "", a: [] },
304
+ saids: { d: DigDex.Blake3_256 },
305
+ },
306
+ dip: {
307
+ alls: {
308
+ v: "",
309
+ t: "",
310
+ d: "",
311
+ i: "",
312
+ s: "0",
313
+ kt: "0",
314
+ k: [],
315
+ nt: "0",
316
+ n: [],
317
+ bt: "0",
318
+ b: [],
319
+ c: [],
320
+ a: [],
321
+ di: "",
322
+ },
323
+ saids: { d: DigDex.Blake3_256, i: DigDex.Blake3_256 },
324
+ },
325
+ drt: {
326
+ alls: {
327
+ v: "",
328
+ t: "",
329
+ d: "",
330
+ i: "",
331
+ s: "0",
332
+ p: "",
333
+ kt: "0",
334
+ k: [],
335
+ nt: "0",
336
+ n: [],
337
+ bt: "0",
338
+ br: [],
339
+ ba: [],
340
+ a: [],
341
+ },
342
+ saids: { d: DigDex.Blake3_256 },
343
+ },
344
+ rct: { alls: { v: "", t: "", d: "", i: "", s: "0" } },
345
+ qry: {
346
+ alls: { v: "", t: "", d: "", dt: "", r: "", rr: "", q: {} },
347
+ saids: { d: DigDex.Blake3_256 },
348
+ },
349
+ rpy: {
350
+ alls: { v: "", t: "", d: "", dt: "", r: "", a: [] },
351
+ saids: { d: DigDex.Blake3_256 },
352
+ },
353
+ pro: {
354
+ alls: { v: "", t: "", d: "", dt: "", r: "", rr: "", q: {} },
355
+ saids: { d: DigDex.Blake3_256 },
356
+ },
357
+ bar: {
358
+ alls: { v: "", t: "", d: "", dt: "", r: "", a: [] },
359
+ saids: { d: DigDex.Blake3_256 },
360
+ },
361
+ exn: {
362
+ alls: {
363
+ v: "",
364
+ t: "",
365
+ d: "",
366
+ i: "",
367
+ rp: "",
368
+ p: "",
369
+ dt: "",
370
+ r: "",
371
+ q: {},
372
+ a: [],
373
+ e: {},
374
+ },
375
+ saids: { d: DigDex.Blake3_256 },
376
+ },
377
+ vcp: {
378
+ alls: {
379
+ v: "",
380
+ t: "",
381
+ d: "",
382
+ i: "",
383
+ ii: "",
384
+ s: "0",
385
+ c: [],
386
+ bt: "0",
387
+ b: [],
388
+ n: "",
389
+ },
390
+ saids: { d: DigDex.Blake3_256, i: DigDex.Blake3_256 },
391
+ },
392
+ vrt: {
393
+ alls: {
394
+ v: "",
395
+ t: "",
396
+ d: "",
397
+ i: "",
398
+ p: "",
399
+ s: "0",
400
+ bt: "0",
401
+ br: [],
402
+ ba: [],
403
+ },
404
+ saids: { d: DigDex.Blake3_256 },
405
+ },
406
+ iss: {
407
+ alls: { v: "", t: "", d: "", i: "", s: "0", ri: "", dt: "" },
408
+ saids: { d: DigDex.Blake3_256 },
409
+ },
410
+ rev: {
411
+ alls: { v: "", t: "", d: "", i: "", s: "0", ri: "", p: "", dt: "" },
412
+ saids: { d: DigDex.Blake3_256 },
413
+ },
414
+ bis: {
415
+ alls: { v: "", t: "", d: "", i: "", ii: "", s: "0", ra: {}, dt: "" },
416
+ saids: { d: DigDex.Blake3_256 },
417
+ },
418
+ brv: {
419
+ alls: { v: "", t: "", d: "", i: "", s: "0", p: "", ra: {}, dt: "" },
420
+ saids: { d: DigDex.Blake3_256 },
421
+ },
422
+ }),
423
+ [versionKey(Vrsn_2_0)]: versionFields({
424
+ icp: {
425
+ alls: {
426
+ v: "",
427
+ t: "",
428
+ d: "",
429
+ i: "",
430
+ s: "0",
431
+ kt: "0",
432
+ k: [],
433
+ nt: "0",
434
+ n: [],
435
+ bt: "0",
436
+ b: [],
437
+ c: [],
438
+ a: [],
439
+ },
440
+ saids: { d: DigDex.Blake3_256, i: DigDex.Blake3_256 },
441
+ },
442
+ rot: {
443
+ alls: {
444
+ v: "",
445
+ t: "",
446
+ d: "",
447
+ i: "",
448
+ s: "0",
449
+ p: "",
450
+ kt: "0",
451
+ k: [],
452
+ nt: "0",
453
+ n: [],
454
+ bt: "0",
455
+ br: [],
456
+ ba: [],
457
+ c: [],
458
+ a: [],
459
+ },
460
+ saids: { d: DigDex.Blake3_256 },
461
+ },
462
+ ixn: {
463
+ alls: { v: "", t: "", d: "", i: "", s: "0", p: "", a: [] },
464
+ saids: { d: DigDex.Blake3_256 },
465
+ },
466
+ dip: {
467
+ alls: {
468
+ v: "",
469
+ t: "",
470
+ d: "",
471
+ i: "",
472
+ s: "0",
473
+ kt: "0",
474
+ k: [],
475
+ nt: "0",
476
+ n: [],
477
+ bt: "0",
478
+ b: [],
479
+ c: [],
480
+ a: [],
481
+ di: "",
482
+ },
483
+ saids: { d: DigDex.Blake3_256, i: DigDex.Blake3_256 },
484
+ },
485
+ drt: {
486
+ alls: {
487
+ v: "",
488
+ t: "",
489
+ d: "",
490
+ i: "",
491
+ s: "0",
492
+ p: "",
493
+ kt: "0",
494
+ k: [],
495
+ nt: "0",
496
+ n: [],
497
+ bt: "0",
498
+ br: [],
499
+ ba: [],
500
+ c: [],
501
+ a: [],
502
+ },
503
+ saids: { d: DigDex.Blake3_256 },
504
+ },
505
+ rct: { alls: { v: "", t: "", d: "", i: "", s: "0" } },
506
+ qry: {
507
+ alls: { v: "", t: "", d: "", i: "", dt: "", r: "", rr: "", q: {} },
508
+ saids: { d: DigDex.Blake3_256 },
509
+ },
510
+ rpy: {
511
+ alls: { v: "", t: "", d: "", i: "", dt: "", r: "", a: {} },
512
+ saids: { d: DigDex.Blake3_256 },
513
+ },
514
+ pro: {
515
+ alls: { v: "", t: "", d: "", i: "", dt: "", r: "", rr: "", q: {} },
516
+ saids: { d: DigDex.Blake3_256 },
517
+ },
518
+ bar: {
519
+ alls: { v: "", t: "", d: "", i: "", dt: "", r: "", a: {} },
520
+ saids: { d: DigDex.Blake3_256 },
521
+ },
522
+ xip: {
523
+ alls: {
524
+ v: "",
525
+ t: "",
526
+ d: "",
527
+ u: "",
528
+ i: "",
529
+ ri: "",
530
+ dt: "",
531
+ r: "",
532
+ q: {},
533
+ a: {},
534
+ },
535
+ saids: { d: DigDex.Blake3_256 },
536
+ },
537
+ exn: {
538
+ alls: {
539
+ v: "",
540
+ t: "",
541
+ d: "",
542
+ i: "",
543
+ ri: "",
544
+ x: "",
545
+ p: "",
546
+ dt: "",
547
+ r: "",
548
+ q: {},
549
+ a: {},
550
+ },
551
+ saids: { d: DigDex.Blake3_256 },
552
+ },
553
+ }),
554
+ },
555
+ [Protocols.acdc]: {
556
+ [versionKey(Vrsn_1_0)]: versionFields({
557
+ "<none>": {
558
+ alls: {
559
+ v: "",
560
+ d: "",
561
+ u: "",
562
+ i: "",
563
+ ri: "",
564
+ s: "",
565
+ a: "",
566
+ A: "",
567
+ e: "",
568
+ r: "",
569
+ },
570
+ opts: { u: "", ri: "", a: "", A: "", e: "", r: "" },
571
+ alts: { a: "A", A: "a" },
572
+ saids: { d: DigDex.Blake3_256 },
573
+ },
574
+ ace: {
575
+ alls: {
576
+ v: "",
577
+ t: "",
578
+ d: "",
579
+ u: "",
580
+ i: "",
581
+ ri: "",
582
+ s: "",
583
+ a: "",
584
+ A: "",
585
+ e: "",
586
+ r: "",
587
+ },
588
+ opts: { u: "", ri: "", a: "", A: "", e: "", r: "" },
589
+ alts: { a: "A", A: "a" },
590
+ saids: { d: DigDex.Blake3_256 },
591
+ strict: false,
592
+ },
593
+ }),
594
+ [versionKey(Vrsn_2_0)]: versionFields({
595
+ "<none>": {
596
+ alls: {
597
+ v: "",
598
+ d: "",
599
+ u: "",
600
+ i: "",
601
+ rd: "",
602
+ s: "",
603
+ a: "",
604
+ A: "",
605
+ e: "",
606
+ r: "",
607
+ },
608
+ opts: { u: "", rd: "", a: "", A: "", e: "", r: "" },
609
+ alts: { a: "A", A: "a" },
610
+ saids: { d: DigDex.Blake3_256 },
611
+ },
612
+ acm: {
613
+ alls: {
614
+ v: "",
615
+ t: "",
616
+ d: "",
617
+ u: "",
618
+ i: "",
619
+ rd: "",
620
+ s: "",
621
+ a: "",
622
+ A: "",
623
+ e: "",
624
+ r: "",
625
+ },
626
+ opts: { t: "", u: "", rd: "", a: "", A: "", e: "", r: "" },
627
+ alts: { a: "A", A: "a" },
628
+ saids: { d: DigDex.Blake3_256 },
629
+ },
630
+ ace: {
631
+ alls: {
632
+ v: "",
633
+ t: "",
634
+ d: "",
635
+ u: "",
636
+ i: "",
637
+ ri: "",
638
+ s: "",
639
+ a: "",
640
+ A: "",
641
+ e: "",
642
+ r: "",
643
+ },
644
+ opts: { u: "", ri: "", a: "", A: "", e: "", r: "" },
645
+ alts: { a: "A", A: "a" },
646
+ saids: { d: DigDex.Blake3_256 },
647
+ strict: false,
648
+ },
649
+ act: {
650
+ alls: {
651
+ v: "",
652
+ t: "",
653
+ d: "",
654
+ u: "",
655
+ i: "",
656
+ rd: "",
657
+ s: "",
658
+ a: "",
659
+ e: "",
660
+ r: "",
661
+ },
662
+ saids: { d: DigDex.Blake3_256 },
663
+ },
664
+ acg: {
665
+ alls: {
666
+ v: "",
667
+ t: "",
668
+ d: "",
669
+ u: "",
670
+ i: "",
671
+ rd: "",
672
+ s: "",
673
+ A: "",
674
+ e: "",
675
+ r: "",
676
+ },
677
+ saids: { d: DigDex.Blake3_256 },
678
+ },
679
+ sch: {
680
+ alls: { v: "", t: "", d: "", s: "" },
681
+ saids: { d: DigDex.Blake3_256 },
682
+ },
683
+ att: {
684
+ alls: { v: "", t: "", d: "", a: "" },
685
+ saids: { d: DigDex.Blake3_256 },
686
+ },
687
+ agg: {
688
+ alls: { v: "", t: "", d: "", A: "" },
689
+ saids: { d: DigDex.Blake3_256 },
690
+ },
691
+ edg: {
692
+ alls: { v: "", t: "", d: "", e: "" },
693
+ saids: { d: DigDex.Blake3_256 },
694
+ },
695
+ rul: {
696
+ alls: { v: "", t: "", d: "", r: "" },
697
+ saids: { d: DigDex.Blake3_256 },
698
+ },
699
+ rip: {
700
+ alls: { v: "", t: "", d: "", u: "", i: "", n: "", dt: "" },
701
+ saids: { d: DigDex.Blake3_256 },
702
+ },
703
+ bup: {
704
+ alls: { v: "", t: "", d: "", rd: "", n: "", p: "", dt: "", b: "" },
705
+ saids: { d: DigDex.Blake3_256 },
706
+ },
707
+ upd: {
708
+ alls: {
709
+ v: "",
710
+ t: "",
711
+ d: "",
712
+ rd: "",
713
+ n: "",
714
+ p: "",
715
+ dt: "",
716
+ td: "",
717
+ ts: "",
718
+ },
719
+ saids: { d: DigDex.Blake3_256 },
720
+ },
721
+ }),
722
+ },
723
+ };
724
+ function isHydratedInit(init) {
725
+ return "smellage" in init && "ked" in init && "ilk" in init && "said" in init;
726
+ }
727
+ function isRawInit(init) {
728
+ return "raw" in init && !isHydratedInit(init) && !("sad" in init);
729
+ }
730
+ function nativeSmellage(proto, pvrsn, gvrsn, size) {
731
+ return {
732
+ proto,
733
+ pvrsn,
734
+ gvrsn,
735
+ kind: Kinds.cesr,
736
+ size,
737
+ };
738
+ }
739
+ function fieldMapKey(ilk) {
740
+ return ilk ?? "<none>";
741
+ }
742
+ /** Resolve the field-domain contract for one protocol/version/ilk combination. */
743
+ function getFieldDom(registry, proto, pvrsn, ilk) {
744
+ const protoFields = registry[proto];
745
+ if (!protoFields) {
746
+ throw new SerializeError(`Invalid protocol=${proto}`);
747
+ }
748
+ const versionFields = protoFields[versionKey(pvrsn)];
749
+ if (!versionFields) {
750
+ throw new SerializeError(`Invalid version=${versionKey(pvrsn)} for protocol=${proto}`);
751
+ }
752
+ const fields = versionFields[fieldMapKey(ilk)];
753
+ if (!fields) {
754
+ throw new SerializeError(`Invalid packet type (ilk)=${String(ilk)} for protocol=${proto}`);
755
+ }
756
+ return fields;
757
+ }
758
+ /** Decode raw serialized bytes into a protocol SAD plus projected ilk/said fields. */
759
+ function parseRawToKed(raw, smellage) {
760
+ const { kind } = smellage;
761
+ let ked = null;
762
+ let ilk = null;
763
+ let said = null;
764
+ try {
765
+ if (kind === "JSON") {
766
+ ked = JSON.parse(t(raw));
767
+ }
768
+ else if (kind === "MGPK") {
769
+ ked = normalizeDecodedMap(decodeMsgpack(raw), kind);
770
+ }
771
+ else if (kind === "CBOR") {
772
+ ked = normalizeDecodedMap(decodeKeriCbor(raw), kind);
773
+ }
774
+ else if (kind === "CESR") {
775
+ // Native inhale is delegated to the shared helper layer because CESR
776
+ // bodies are not self-describing through `smell()` the same way
777
+ // JSON/CBOR/MGPK bodies are.
778
+ const native = parseCesrNativeKed(raw, smellage);
779
+ ked = native.ked;
780
+ ilk = native.ilk;
781
+ said = native.said;
782
+ }
783
+ }
784
+ catch (error) {
785
+ if (error instanceof DeserializeError) {
786
+ throw new DeserializeError(`Failed to decode ${kind} Serder: ${String(error.message)}`);
787
+ }
788
+ if (kind === "JSON" && error instanceof SyntaxError) {
789
+ throw new DeserializeError(`Failed to decode JSON Serder: ${String(error)}`);
790
+ }
791
+ throw new DeserializeError(`Failed to decode ${kind} Serder: ${String(error)}`);
792
+ }
793
+ if (ked) {
794
+ ilk = typeof ked.t === "string" ? ked.t : null;
795
+ said = typeof ked.d === "string" ? ked.d : null;
796
+ }
797
+ return { ked, ilk, said };
798
+ }
799
+ function coerceMatterCode(value) {
800
+ if (typeof value !== "string" || value.length === 0) {
801
+ return null;
802
+ }
803
+ try {
804
+ return parseMatter(b(value), "txt").code;
805
+ }
806
+ catch {
807
+ return null;
808
+ }
809
+ }
810
+ function shallowCloneSad(sad) {
811
+ return Object.fromEntries(Object.entries(sad).map(([k, v]) => [k, cloneDefault(v)]));
812
+ }
813
+ /** True when the top-level ACDC ilk participates in KERIpy's most-compact SAID rule. */
814
+ function isAcdcCompactiveIlk(ilk) {
815
+ return ilk === null || ACDC_COMPACT_TOP_LEVEL_ILKS.has(ilk);
816
+ }
817
+ /** True when the message is an ACDC section-message that must verify embedded section ids. */
818
+ function isAcdcPartialSectionIlk(ilk) {
819
+ return ACDC_PARTIAL_SECTION_ILKS.has(ilk ?? "");
820
+ }
821
+ /** Map ACDC section labels onto the saidive policy KERIpy applies to that section family. */
822
+ function acdcSectionConfig(label) {
823
+ if (label === "s") {
824
+ return {
825
+ strict: false,
826
+ saids: { $id: DigDex.Blake3_256 },
827
+ };
828
+ }
829
+ if (label === "a" || label === "e" || label === "r") {
830
+ return {
831
+ strict: true,
832
+ saids: { d: DigDex.Blake3_256 },
833
+ };
834
+ }
835
+ return null;
836
+ }
837
+ /** Ensure the section carries the saidive placeholder label KERIpy computes over. */
838
+ function withAcdcSectionPlaceholder(label, value) {
839
+ const copy = shallowCloneSad(value);
840
+ if (label === "s" && !("$id" in copy)) {
841
+ copy.$id = "";
842
+ }
843
+ if ((label === "a" || label === "e" || label === "r") && !("d" in copy)) {
844
+ copy.d = "";
845
+ }
846
+ return copy;
847
+ }
848
+ /**
849
+ * Build the "display" and "compact" variants of one ACDC section field.
850
+ *
851
+ * Maintainer model:
852
+ * - `display` is what the caller-visible SAD should keep
853
+ * - `compact` is what top-level `d` must be hashed over for compactive ilks
854
+ *
855
+ * This is the seam that translates plain semantic section data into the shared
856
+ * native primitives:
857
+ * - `Compactor` for `s`/`a`/`e`/`r`
858
+ * - `Aggor` for `A`
859
+ */
860
+ function computeAcdcFieldVariants(label, value, kind, topLevelCompactable, compactify, partialSection) {
861
+ const sectionConfig = acdcSectionConfig(label);
862
+ if (sectionConfig && value && typeof value === "object" && !Array.isArray(value)) {
863
+ const expanded = new Compactor({
864
+ mad: withAcdcSectionPlaceholder(label, value),
865
+ kind,
866
+ verify: false,
867
+ saidive: true,
868
+ strict: sectionConfig.strict,
869
+ saids: sectionConfig.saids,
870
+ makify: true,
871
+ });
872
+ expanded.trace(true);
873
+ if (!topLevelCompactable) {
874
+ return {
875
+ display: expanded.mad,
876
+ compact: expanded.mad,
877
+ };
878
+ }
879
+ const compacted = new Compactor({
880
+ mad: withAcdcSectionPlaceholder(label, value),
881
+ kind,
882
+ verify: false,
883
+ saidive: true,
884
+ strict: sectionConfig.strict,
885
+ saids: sectionConfig.saids,
886
+ makify: true,
887
+ });
888
+ compacted.compact();
889
+ return {
890
+ display: compactify ? (compacted.said ?? compacted.mad) : expanded.mad,
891
+ compact: compacted.said ?? compacted.mad,
892
+ };
893
+ }
894
+ if (label === "A" && Array.isArray(value)) {
895
+ const aggor = new Aggor({
896
+ ael: cloneDefault(value),
897
+ kind,
898
+ makify: true,
899
+ verify: false,
900
+ });
901
+ if (!topLevelCompactable || partialSection) {
902
+ return {
903
+ display: aggor.ael,
904
+ compact: aggor.ael,
905
+ };
906
+ }
907
+ return {
908
+ display: compactify ? (aggor.agid ?? aggor.ael) : aggor.ael,
909
+ compact: aggor.agid ?? aggor.ael,
910
+ };
911
+ }
912
+ return { display: cloneDefault(value), compact: cloneDefault(value) };
913
+ }
914
+ function computeAcdcSad(sad, { kind, saids, compactify, }) {
915
+ // This is the heart of ACDC compactification parity. KERIpy's rule is not
916
+ // "hash the visible sad"; it is "hash the most compact sad, while optionally
917
+ // preserving an expanded caller-visible sad".
918
+ const displaySad = shallowCloneSad(sad);
919
+ const compactSad = shallowCloneSad(sad);
920
+ const ilk = typeof sad.t === "string" ? sad.t : null;
921
+ const topLevelCompactable = isAcdcCompactiveIlk(ilk);
922
+ const partialSection = isAcdcPartialSectionIlk(ilk);
923
+ for (const label of ["s", "a", "A", "e", "r"]) {
924
+ if (!(label in sad)) {
925
+ continue;
926
+ }
927
+ const variants = computeAcdcFieldVariants(label, sad[label], kind, topLevelCompactable, compactify, partialSection);
928
+ displaySad[label] = variants.display;
929
+ compactSad[label] = variants.compact;
930
+ }
931
+ const code = saids.d ?? DigDex.Blake3_256;
932
+ const sizage = MATTER_SIZES.get(code);
933
+ if (!sizage?.fs) {
934
+ throw new SerializeError(`Unsupported ACDC SAID code=${code}`);
935
+ }
936
+ const hashSad = shallowCloneSad(compactSad);
937
+ hashSad.d = "#".repeat(sizage.fs);
938
+ // `sizeify()` must happen before digesting because non-native version strings
939
+ // include size, so the hashed serialization has to already carry the final
940
+ // version-string span.
941
+ sizeify(hashSad, kind);
942
+ const digestRaw = dumps(hashSad, kind);
943
+ const said = new Diger({ code, raw: Diger.digest(digestRaw, code) }).qb64;
944
+ compactSad.d = said;
945
+ displaySad.d = said;
946
+ const sizedDisplay = shallowCloneSad(displaySad);
947
+ const { raw } = sizeify(sizedDisplay, kind);
948
+ return {
949
+ sad: sizedDisplay,
950
+ raw,
951
+ compactSad,
952
+ };
953
+ }
954
+ function validateSadAgainstFieldDom(ctor, serder) {
955
+ // This helper centralizes the generic field-domain checks used by both base
956
+ // `Serder` verification and the ACDC-specific override. Keeping it separate
957
+ // prevents the ACDC path from drifting on required/optional/order rules while
958
+ // still letting it customize SAID verification semantics afterward.
959
+ if (!serder.ked) {
960
+ throw new DeserializeError("Cannot verify Serder without decoded SAD.");
961
+ }
962
+ if (ctor.Protocol && serder.proto !== ctor.Protocol) {
963
+ throw new DeserializeError(`Required protocol=${ctor.Protocol}, got ${serder.proto}`);
964
+ }
965
+ const ked = serder.ked;
966
+ const fields = getFieldDom(ctor.Fields, serder.proto, serder.pvrsn, serder.ilk);
967
+ const currentKeys = Object.keys(ked);
968
+ const allowedKeys = Object.keys(fields.alls);
969
+ const extraKeys = currentKeys.filter((key) => !allowedKeys.includes(key));
970
+ if (extraKeys.length > 0 && (fields.strict ?? true)) {
971
+ throw new DeserializeError(`Unallowed extra field(s)=${extraKeys.join(",")}`);
972
+ }
973
+ const optional = new Set(Object.keys(fields.opts ?? {}));
974
+ const required = allowedKeys.filter((key) => !optional.has(key));
975
+ for (const label of required) {
976
+ if (!(label in ked)) {
977
+ throw new DeserializeError(`Missing required field=${label}`);
978
+ }
979
+ }
980
+ const orderWithoutExtras = currentKeys.filter((key) => allowedKeys.includes(key));
981
+ const expectedOrder = allowedKeys.filter((key) => key in ked);
982
+ if (orderWithoutExtras.join("|") !== expectedOrder.join("|")) {
983
+ throw new DeserializeError("Missing or out-of-order fields in SAD.");
984
+ }
985
+ for (const [label, alt] of Object.entries(fields.alts ?? {})) {
986
+ if (label in ked && alt in ked) {
987
+ throw new DeserializeError(`Unallowed alternate fields '${label}' and '${alt}' both present.`);
988
+ }
989
+ }
990
+ const saids = { ...(fields.saids ?? {}) };
991
+ for (const label of Object.keys(saids)) {
992
+ const code = coerceMatterCode(ked[label]);
993
+ if (code) {
994
+ saids[label] = code;
995
+ }
996
+ }
997
+ return { fields, saids, ked };
998
+ }
999
+ /** Fill default field values and normalize insertion order against one field-domain contract. */
1000
+ function normalizeSadWithFieldDom(sad, fields) {
1001
+ const working = shallowCloneSad(sad ?? {});
1002
+ const optional = new Set(Object.keys(fields.opts ?? {}));
1003
+ for (const [label, value] of Object.entries(fields.alls)) {
1004
+ if (!(label in working) && !optional.has(label)) {
1005
+ working[label] = cloneDefault(value);
1006
+ }
1007
+ }
1008
+ const ordered = {};
1009
+ for (const label of Object.keys(fields.alls)) {
1010
+ if (label in working) {
1011
+ ordered[label] = working[label];
1012
+ }
1013
+ }
1014
+ for (const [label, value] of Object.entries(working)) {
1015
+ if (!(label in ordered)) {
1016
+ ordered[label] = value;
1017
+ }
1018
+ }
1019
+ return ordered;
1020
+ }
1021
+ /** Choose protocol/version/kind defaults for semantic serder construction from SAD input. */
1022
+ function resolveProtocolDefaults(ctor, init) {
1023
+ const sad = shallowCloneSad(init.sad ?? {});
1024
+ let smelled = null;
1025
+ if (typeof sad.v === "string" && sad.v.length > 0) {
1026
+ try {
1027
+ smelled = parseVersionString(sad.v);
1028
+ }
1029
+ catch {
1030
+ smelled = null;
1031
+ }
1032
+ }
1033
+ const proto = init.proto ?? smelled?.proto ?? ctor.Proto;
1034
+ const pvrsn = init.pvrsn ?? smelled?.pvrsn ?? ctor.PVrsn;
1035
+ const gvrsn = init.gvrsn ?? smelled?.gvrsn
1036
+ ?? (pvrsn.major >= 2 ? ctor.GVrsn : null);
1037
+ const kind = init.kind ?? smelled?.kind ?? ctor.Kind;
1038
+ const versionFields = ctor.Fields[proto]?.[versionKey(pvrsn)];
1039
+ if (!versionFields) {
1040
+ throw new SerializeError(`Invalid version=${versionKey(pvrsn)} for protocol=${proto}`);
1041
+ }
1042
+ const defaultIlk = Object.keys(versionFields)[0] ?? "<none>";
1043
+ const ilk = init.ilk ?? (typeof sad.t === "string" ? sad.t : null)
1044
+ ?? (defaultIlk === "<none>" ? null : defaultIlk);
1045
+ const fields = getFieldDom(ctor.Fields, proto, pvrsn, ilk);
1046
+ const normalized = normalizeSadWithFieldDom(sad, fields);
1047
+ if (ilk !== null) {
1048
+ normalized.t = ilk;
1049
+ }
1050
+ normalized.v = versify({ proto, pvrsn, gvrsn, kind, size: 0 });
1051
+ const saids = { ...(fields.saids ?? {}) };
1052
+ for (const [label, code] of Object.entries(init.saids ?? {})) {
1053
+ saids[label] = code;
1054
+ }
1055
+ for (const label of Object.keys(saids)) {
1056
+ if (label in (init.saids ?? {})) {
1057
+ continue;
1058
+ }
1059
+ const valueCode = coerceMatterCode(normalized[label]);
1060
+ if (valueCode) {
1061
+ saids[label] = valueCode;
1062
+ }
1063
+ }
1064
+ return { sad: normalized, proto, pvrsn, gvrsn, kind, ilk, saids };
1065
+ }
27
1066
  function collectNestedGroups(entries, out) {
28
1067
  for (const entry of entries) {
29
1068
  if (isPrimitiveTuple(entry)) {
@@ -48,23 +1087,18 @@ function collectMessageGroups(message) {
48
1087
  /**
49
1088
  * Base Serder body class.
50
1089
  *
51
- * KERIpy substance: Serders carry raw serialized event bytes plus decoded KED
52
- * projections (`ilk`/`said`) and protocol/version metadata.
1090
+ * KERIpy substance: Serders own both halves of the message-body contract:
1091
+ * serialization (`sad` -> `raw`) and deserialization (`raw` -> `sad`) plus
1092
+ * verification of saidive fields against the serialized body bytes.
53
1093
  */
54
1094
  export class Serder {
55
- constructor(init) {
1095
+ constructor(init = { makify: true }) {
56
1096
  Object.defineProperty(this, "raw", {
57
1097
  enumerable: true,
58
1098
  configurable: true,
59
1099
  writable: true,
60
1100
  value: void 0
61
1101
  });
62
- Object.defineProperty(this, "ked", {
63
- enumerable: true,
64
- configurable: true,
65
- writable: true,
66
- value: void 0
67
- });
68
1102
  Object.defineProperty(this, "kind", {
69
1103
  enumerable: true,
70
1104
  configurable: true,
@@ -101,27 +1135,147 @@ export class Serder {
101
1135
  writable: true,
102
1136
  value: void 0
103
1137
  });
104
- Object.defineProperty(this, "said", {
1138
+ Object.defineProperty(this, "native", {
105
1139
  enumerable: true,
106
1140
  configurable: true,
107
1141
  writable: true,
108
1142
  value: void 0
109
1143
  });
110
- Object.defineProperty(this, "native", {
1144
+ Object.defineProperty(this, "_ked", {
111
1145
  enumerable: true,
112
1146
  configurable: true,
113
1147
  writable: true,
114
1148
  value: void 0
115
1149
  });
116
- this.raw = init.raw;
117
- this.ked = init.ked;
118
- this.kind = init.smellage.kind;
119
- this.size = init.smellage.size;
120
- this.proto = init.smellage.proto;
121
- this.pvrsn = init.smellage.pvrsn;
122
- this.gvrsn = init.smellage.gvrsn;
123
- this.ilk = init.ilk;
124
- this.said = init.said;
1150
+ Object.defineProperty(this, "_said", {
1151
+ enumerable: true,
1152
+ configurable: true,
1153
+ writable: true,
1154
+ value: void 0
1155
+ });
1156
+ if (isHydratedInit(init)) {
1157
+ this.raw = init.raw;
1158
+ this.kind = init.smellage.kind;
1159
+ this.size = init.smellage.size;
1160
+ this.proto = init.smellage.proto;
1161
+ this.pvrsn = init.smellage.pvrsn;
1162
+ this.gvrsn = init.smellage.gvrsn;
1163
+ this.ilk = init.ilk;
1164
+ this._ked = init.ked;
1165
+ this._said = init.said;
1166
+ return;
1167
+ }
1168
+ if (isRawInit(init)) {
1169
+ const smellage = init.smellage ?? smell(init.raw).smellage;
1170
+ const raw = init.raw.length === smellage.size
1171
+ ? init.raw
1172
+ : init.raw.slice(0, smellage.size);
1173
+ const parsed = parseRawToKed(raw, smellage);
1174
+ this.raw = raw;
1175
+ this.kind = smellage.kind;
1176
+ this.size = smellage.size;
1177
+ this.proto = smellage.proto;
1178
+ this.pvrsn = smellage.pvrsn;
1179
+ this.gvrsn = smellage.gvrsn;
1180
+ this.ilk = parsed.ilk;
1181
+ this._ked = parsed.ked;
1182
+ this._said = parsed.said;
1183
+ if (init.verify ?? true) {
1184
+ this._verify();
1185
+ }
1186
+ return;
1187
+ }
1188
+ const ctor = this.constructor;
1189
+ const resolved = resolveProtocolDefaults(ctor, init);
1190
+ const fields = getFieldDom(ctor.Fields, resolved.proto, resolved.pvrsn, resolved.ilk);
1191
+ const normalized = normalizeSadWithFieldDom(resolved.sad, fields);
1192
+ if (resolved.ilk !== null) {
1193
+ normalized.t = resolved.ilk;
1194
+ }
1195
+ normalized.v = versify({
1196
+ proto: resolved.proto,
1197
+ pvrsn: resolved.pvrsn,
1198
+ gvrsn: resolved.gvrsn,
1199
+ kind: resolved.kind,
1200
+ size: 0,
1201
+ });
1202
+ const actual = (init.makify ?? false)
1203
+ ? resolved.proto === Protocols.acdc
1204
+ ? computeAcdcSad(normalized, {
1205
+ kind: resolved.kind,
1206
+ saids: resolved.saids,
1207
+ compactify: init.compactify ?? false,
1208
+ })
1209
+ : Saider.saidifyFields(normalized, {
1210
+ kind: resolved.kind,
1211
+ saids: resolved.saids,
1212
+ digest: Diger.digest,
1213
+ })
1214
+ : (() => {
1215
+ const existing = shallowCloneSad(normalized);
1216
+ const { raw } = sizeify(existing, resolved.kind);
1217
+ return { sad: existing, raw, saiders: {} };
1218
+ })();
1219
+ const smellage = resolved.kind === Kinds.cesr
1220
+ ? nativeSmellage(resolved.proto, resolved.pvrsn, resolved.gvrsn, actual.raw.length)
1221
+ : smell(actual.raw).smellage;
1222
+ this.raw = actual.raw;
1223
+ this.kind = smellage.kind;
1224
+ this.size = smellage.size;
1225
+ this.proto = smellage.proto;
1226
+ this.pvrsn = smellage.pvrsn;
1227
+ this.gvrsn = smellage.gvrsn;
1228
+ this.ilk = typeof actual.sad.t === "string" ? actual.sad.t : resolved.ilk;
1229
+ this._ked = actual.sad;
1230
+ this._said = typeof actual.sad.d === "string" ? actual.sad.d : null;
1231
+ if (init.verify ?? true) {
1232
+ this._verify();
1233
+ }
1234
+ }
1235
+ get ked() {
1236
+ return this._ked;
1237
+ }
1238
+ get sad() {
1239
+ return this._ked ? shallowCloneSad(this._ked) : null;
1240
+ }
1241
+ get verstr() {
1242
+ return this._ked && typeof this._ked.v === "string" ? this._ked.v : null;
1243
+ }
1244
+ /** CESR message-universal genus code backing this serder's native framing. */
1245
+ get genus() {
1246
+ return MESSAGE_GENUS_BY_PROTOCOL[this.proto];
1247
+ }
1248
+ get protocol() {
1249
+ return this.proto;
1250
+ }
1251
+ /**
1252
+ * Message-universal counter codex selected by the serder's genus version.
1253
+ *
1254
+ * This mirrors KERIpy's `serder.mucodes`: native body-group parsing and emit
1255
+ * use the latest compatible counter table for the active genus major/minor.
1256
+ * Non-native legacy messages without `gvrsn` do not have a meaningful
1257
+ * message-universal codex, so this accessor rejects that misuse explicitly.
1258
+ */
1259
+ get mucodes() {
1260
+ if (!this.gvrsn) {
1261
+ throw new DeserializeError("mucodes requires a CESR genus version.");
1262
+ }
1263
+ return resolveMUDex(this.gvrsn);
1264
+ }
1265
+ get said() {
1266
+ if (this._ked
1267
+ && this.ilk !== null
1268
+ && Object.keys(getFieldDom(this.constructor.Fields, this.proto, this.pvrsn, this.ilk).saids ?? {}).length === 0
1269
+ && typeof this._ked.d === "string") {
1270
+ return this._ked.d;
1271
+ }
1272
+ return this._said;
1273
+ }
1274
+ get saidb() {
1275
+ return this.said ? b(this.said) : null;
1276
+ }
1277
+ get stamp() {
1278
+ return this._ked && typeof this._ked.dt === "string" ? this._ked.dt : null;
125
1279
  }
126
1280
  /** True when this body belongs to KERI protocol domain. */
127
1281
  get isKeri() {
@@ -131,6 +1285,59 @@ export class Serder {
131
1285
  get isAcdc() {
132
1286
  return this.proto === Protocols.acdc;
133
1287
  }
1288
+ verify() {
1289
+ try {
1290
+ this._verify();
1291
+ return true;
1292
+ }
1293
+ catch {
1294
+ return false;
1295
+ }
1296
+ }
1297
+ _verify() {
1298
+ const ctor = this.constructor;
1299
+ const { saids, ked } = validateSadAgainstFieldDom(ctor, this);
1300
+ const working = shallowCloneSad(ked);
1301
+ const actual = Saider.saidifyFields(working, {
1302
+ kind: this.kind,
1303
+ saids,
1304
+ digest: Diger.digest,
1305
+ });
1306
+ if (t(actual.raw) !== t(this.raw)) {
1307
+ throw new DeserializeError("Invalid round trip of SAD against raw.");
1308
+ }
1309
+ const actualSmellage = this.kind === Kinds.cesr
1310
+ ? nativeSmellage(this.proto, this.pvrsn, this.gvrsn, actual.raw.length)
1311
+ : smell(actual.raw).smellage;
1312
+ if (actualSmellage.proto !== this.proto) {
1313
+ throw new DeserializeError("Inconsistent protocol after verification.");
1314
+ }
1315
+ if (actualSmellage.pvrsn.major !== this.pvrsn.major
1316
+ || actualSmellage.pvrsn.minor !== this.pvrsn.minor) {
1317
+ throw new DeserializeError("Inconsistent protocol version after verification.");
1318
+ }
1319
+ if (actualSmellage.kind !== this.kind) {
1320
+ throw new DeserializeError("Inconsistent serialization kind after verification.");
1321
+ }
1322
+ if (actualSmellage.size !== this.size || actual.raw.length !== this.size) {
1323
+ throw new DeserializeError("Inconsistent serialized size after verification.");
1324
+ }
1325
+ if ((actualSmellage.gvrsn?.major ?? -1) !== (this.gvrsn?.major ?? -1)
1326
+ || (actualSmellage.gvrsn?.minor ?? -1) !== (this.gvrsn?.minor ?? -1)) {
1327
+ throw new DeserializeError("Inconsistent genus version after verification.");
1328
+ }
1329
+ }
1330
+ compare(said) {
1331
+ if (!said || !this.saidb) {
1332
+ throw new DeserializeError("Uncomparable saids.");
1333
+ }
1334
+ const other = typeof said === "string" ? b(said) : said;
1335
+ return t(other) === t(this.saidb);
1336
+ }
1337
+ pretty(opts = {}) {
1338
+ const pretty = JSON.stringify(this._ked, null, 1);
1339
+ return opts.size ? pretty.slice(0, opts.size) : pretty;
1340
+ }
134
1341
  /**
135
1342
  * Project counted attachment groups into structor subclasses.
136
1343
  *
@@ -168,71 +1375,363 @@ export class Serder {
168
1375
  return projection;
169
1376
  }
170
1377
  }
1378
+ Object.defineProperty(Serder, "Protocol", {
1379
+ enumerable: true,
1380
+ configurable: true,
1381
+ writable: true,
1382
+ value: null
1383
+ });
1384
+ Object.defineProperty(Serder, "Proto", {
1385
+ enumerable: true,
1386
+ configurable: true,
1387
+ writable: true,
1388
+ value: Protocols.keri
1389
+ });
1390
+ Object.defineProperty(Serder, "PVrsn", {
1391
+ enumerable: true,
1392
+ configurable: true,
1393
+ writable: true,
1394
+ value: Vrsn_1_0
1395
+ });
1396
+ Object.defineProperty(Serder, "GVrsn", {
1397
+ enumerable: true,
1398
+ configurable: true,
1399
+ writable: true,
1400
+ value: Vrsn_2_0
1401
+ });
1402
+ Object.defineProperty(Serder, "Kind", {
1403
+ enumerable: true,
1404
+ configurable: true,
1405
+ writable: true,
1406
+ value: "JSON"
1407
+ });
1408
+ Object.defineProperty(Serder, "Fields", {
1409
+ enumerable: true,
1410
+ configurable: true,
1411
+ writable: true,
1412
+ value: FIELDS
1413
+ });
171
1414
  /** KERI-protocol Serder subtype (`proto=KERI`). */
172
1415
  export class SerderKERI extends Serder {
173
- constructor(init) {
1416
+ constructor(init = { makify: true }) {
174
1417
  super(init);
175
1418
  if (!this.isKeri) {
176
1419
  throw new DeserializeError(`Expected KERI protocol serder, got ${this.proto}`);
177
1420
  }
178
1421
  }
1422
+ _verify() {
1423
+ super._verify();
1424
+ const sad = this.ked;
1425
+ if (!sad) {
1426
+ throw new DeserializeError("Missing decoded KERI SAD.");
1427
+ }
1428
+ const allowedKeys = Object.keys(getFieldDom(FIELDS, this.proto, this.pvrsn, this.ilk).alls);
1429
+ const actualKeys = Object.keys(sad);
1430
+ if (allowedKeys.join("|") !== actualKeys.join("|")) {
1431
+ throw new DeserializeError(`Invalid top level field list. Expected ${allowedKeys.join(",")} got ${actualKeys.join(",")}.`);
1432
+ }
1433
+ const pre = this.pre;
1434
+ if (pre && PREFIX_CODES.has(coerceMatterCode(pre) ?? "")) {
1435
+ const code = coerceMatterCode(pre);
1436
+ if (this.ilk === Ilks.dip && !DIGEST_CODES.has(code)) {
1437
+ throw new DeserializeError(`Delegated inception requires digestive prefix code, got ${code}.`);
1438
+ }
1439
+ if (this.ilk === Ilks.icp || this.ilk === Ilks.dip) {
1440
+ if (NON_DIGEST_PREFIX_CODES.has(code)) {
1441
+ if (this.keys.length !== 1) {
1442
+ throw new DeserializeError(`Non-digestive prefix ${code} requires exactly one key.`);
1443
+ }
1444
+ if (this.tholder?.num !== 1n || this.tholder.weighted) {
1445
+ throw new DeserializeError(`Non-digestive prefix ${code} requires signing threshold 1.`);
1446
+ }
1447
+ if (pre !== this.keys[0]) {
1448
+ throw new DeserializeError(`Non-digestive prefix ${code} must equal the zeroth key.`);
1449
+ }
1450
+ }
1451
+ if (NON_TRANSFERABLE_CODES.has(code)) {
1452
+ if (this.ndigs.length > 0) {
1453
+ throw new DeserializeError(`Non-transferable prefix ${code} requires empty nxt digests.`);
1454
+ }
1455
+ if (this.backs.length > 0) {
1456
+ throw new DeserializeError(`Non-transferable prefix ${code} requires no backers.`);
1457
+ }
1458
+ if (this.seals.length > 0) {
1459
+ throw new DeserializeError(`Non-transferable prefix ${code} requires no seals/data.`);
1460
+ }
1461
+ }
1462
+ }
1463
+ }
1464
+ if (this.ilk === Ilks.dip && this.delpre) {
1465
+ const delCode = coerceMatterCode(this.delpre);
1466
+ if (!delCode || !PREFIX_CODES.has(delCode) || !DIGEST_CODES.has(delCode)) {
1467
+ throw new DeserializeError(`Invalid delegator/delegate prefix code=${String(delCode)}.`);
1468
+ }
1469
+ }
1470
+ }
1471
+ get estive() {
1472
+ return KERI_ESTABLISHMENT_ILKS.has(this.ilk ?? "");
1473
+ }
1474
+ get pre() {
1475
+ return this.ked && typeof this.ked.i === "string" ? this.ked.i : null;
1476
+ }
1477
+ get preb() {
1478
+ return this.pre ? b(this.pre) : null;
1479
+ }
1480
+ get sner() {
1481
+ return makeNumberPrimitive(this.snh);
1482
+ }
1483
+ get sn() {
1484
+ return this.sner ? Number(this.sner.num) : null;
1485
+ }
1486
+ get snh() {
1487
+ return this.ked && typeof this.ked.s === "string" ? this.ked.s : null;
1488
+ }
1489
+ /**
1490
+ * Raw top-level `a` field from the decoded KERI SAD.
1491
+ *
1492
+ * Do not assume this is always a seal list. KERI reuses `a` for multiple
1493
+ * semantic roles, which is why typed seal projection is exposed separately.
1494
+ */
1495
+ get a() {
1496
+ return this.ked?.a;
1497
+ }
1498
+ /**
1499
+ * Raw KERI `a` list as decoded from the SAD.
1500
+ *
1501
+ * This accessor intentionally stays raw for KERIpy parity. The same label `a`
1502
+ * is used in KERI for more than one semantic purpose, so eager typing here
1503
+ * would conflate raw SAD decoding with higher-level interpretation.
1504
+ */
1505
+ get seals() {
1506
+ return Array.isArray(this.ked?.a) ? [...this.ked.a] : [];
1507
+ }
1508
+ /**
1509
+ * Typed seal projection built from raw KERI `a` SAD entries.
1510
+ *
1511
+ * Boundary rule:
1512
+ * - `seals` stays raw and untyped for KERIpy parity
1513
+ * - `sealRecords` is the explicit semantic projection and therefore rejects
1514
+ * malformed or unknown seal dictionaries instead of silently skipping them
1515
+ */
1516
+ get sealRecords() {
1517
+ return this.seals.map((seal, index) => parseSealRecord(seal, index));
1518
+ }
1519
+ /**
1520
+ * Narrow `sealRecords` to event-style seals used for anchoring and delegation.
1521
+ *
1522
+ * Use this when the caller needs semantic seal fields (`i`, `s`, `d`) instead
1523
+ * of raw `a` dictionaries.
1524
+ */
1525
+ get eventSeals() {
1526
+ return this.sealRecords.filter(isSealEventRecord);
1527
+ }
1528
+ get traits() {
1529
+ return Array.isArray(this.ked?.c)
1530
+ ? this.ked.c.filter((value) => typeof value === "string")
1531
+ : [];
1532
+ }
1533
+ get tholder() {
1534
+ return makeThreshold(this.ked?.kt ?? null);
1535
+ }
1536
+ get keys() {
1537
+ return Array.isArray(this.ked?.k)
1538
+ ? this.ked.k.filter((value) => typeof value === "string")
1539
+ : [];
1540
+ }
1541
+ get verfers() {
1542
+ return this.keys.map((key) => new Verfer({ qb64: key }));
1543
+ }
1544
+ get ndigs() {
1545
+ return Array.isArray(this.ked?.n)
1546
+ ? this.ked.n.filter((value) => typeof value === "string")
1547
+ : [];
1548
+ }
1549
+ get ntholder() {
1550
+ return makeThreshold(this.ked?.nt ?? null);
1551
+ }
1552
+ get ndigers() {
1553
+ return this.ndigs.map((dig) => new Diger({ qb64: dig }));
1554
+ }
1555
+ get bner() {
1556
+ return makeNumberPrimitive(this.ked
1557
+ && (typeof this.ked.bt === "string" || typeof this.ked.bt === "number"
1558
+ || typeof this.ked.bt === "bigint")
1559
+ ? this.ked.bt
1560
+ : null);
1561
+ }
1562
+ get bn() {
1563
+ return this.bner ? Number(this.bner.num) : null;
1564
+ }
1565
+ get backs() {
1566
+ return Array.isArray(this.ked?.b)
1567
+ ? this.ked.b.filter((value) => typeof value === "string")
1568
+ : [];
1569
+ }
1570
+ get berfers() {
1571
+ return this.backs.map((back) => new Verfer({ qb64: back }));
1572
+ }
1573
+ get prior() {
1574
+ return this.ked && typeof this.ked.p === "string" ? this.ked.p : null;
1575
+ }
1576
+ get priorb() {
1577
+ return this.prior ? b(this.prior) : null;
1578
+ }
1579
+ get cuts() {
1580
+ return Array.isArray(this.ked?.br)
1581
+ ? this.ked.br.filter((value) => typeof value === "string")
1582
+ : [];
1583
+ }
1584
+ get adds() {
1585
+ return Array.isArray(this.ked?.ba)
1586
+ ? this.ked.ba.filter((value) => typeof value === "string")
1587
+ : [];
1588
+ }
1589
+ get delpre() {
1590
+ return this.ked && typeof this.ked.di === "string" ? this.ked.di : null;
1591
+ }
1592
+ get delpreb() {
1593
+ return this.delpre ? b(this.delpre) : null;
1594
+ }
1595
+ get route() {
1596
+ return this.ked && typeof this.ked.r === "string" ? this.ked.r : null;
1597
+ }
1598
+ get uuid() {
1599
+ return this.ked && typeof this.ked.u === "string" ? this.ked.u : null;
1600
+ }
1601
+ get nonce() {
1602
+ if (this.pvrsn.major < 2 && this.pvrsn.minor < 1 && this.ilk === Ilks.vcp) {
1603
+ return this.ked && typeof this.ked.n === "string" ? this.ked.n : null;
1604
+ }
1605
+ return this.uuid;
1606
+ }
179
1607
  }
1608
+ Object.defineProperty(SerderKERI, "Protocol", {
1609
+ enumerable: true,
1610
+ configurable: true,
1611
+ writable: true,
1612
+ value: Protocols.keri
1613
+ });
1614
+ Object.defineProperty(SerderKERI, "Proto", {
1615
+ enumerable: true,
1616
+ configurable: true,
1617
+ writable: true,
1618
+ value: Protocols.keri
1619
+ });
180
1620
  /** ACDC-protocol Serder subtype (`proto=ACDC`). */
181
1621
  export class SerderACDC extends Serder {
182
- constructor(init) {
1622
+ constructor(init = { makify: true }) {
183
1623
  super(init);
184
1624
  if (!this.isAcdc) {
185
1625
  throw new DeserializeError(`Expected ACDC protocol serder, got ${this.proto}`);
186
1626
  }
187
1627
  }
188
- }
189
- /**
190
- * Parse one raw Serder body and hydrate protocol-specific Serder subclasses.
191
- */
192
- export function parseSerder(raw, smellage) {
193
- const { proto, kind, pvrsn, gvrsn, size } = smellage;
194
- let ked = null;
195
- let ilk = null;
196
- let said = null;
197
- try {
198
- if (kind === "JSON") {
199
- const text = t(raw);
200
- ked = JSON.parse(text);
201
- }
202
- else if (kind === "MGPK") {
203
- ked = normalizeDecodedMap(decodeMsgpack(raw), kind);
1628
+ _verify() {
1629
+ const ctor = this.constructor;
1630
+ const { ked, saids } = validateSadAgainstFieldDom(ctor, this);
1631
+ const actual = computeAcdcSad(shallowCloneSad(ked), {
1632
+ kind: this.kind,
1633
+ saids,
1634
+ compactify: false,
1635
+ });
1636
+ if (typeof ked.d !== "string" || actual.sad.d !== ked.d) {
1637
+ throw new DeserializeError("Invalid compact-form ACDC SAID.");
204
1638
  }
205
- else if (kind === "CBOR") {
206
- ked = normalizeDecodedMap(decodeKeriCbor(raw), kind);
1639
+ const serialized = shallowCloneSad(ked);
1640
+ const { raw } = sizeify(serialized, this.kind);
1641
+ if (t(raw) !== t(this.raw)) {
1642
+ throw new DeserializeError("Invalid ACDC raw serialization against SAD.");
207
1643
  }
208
- if (ked) {
209
- ilk = typeof ked.t === "string" ? ked.t : null;
210
- said = typeof ked.d === "string" ? ked.d : null;
1644
+ if (this.ilk === null
1645
+ || ACDC_SAIDIVE_TOP_LEVEL_ILKS.has(this.ilk)) {
1646
+ const issuer = this.issuer;
1647
+ if (!issuer) {
1648
+ throw new DeserializeError("Invalid issuer AID.");
1649
+ }
1650
+ const code = coerceMatterCode(issuer);
1651
+ if (!code || !PREFIX_CODES.has(code)) {
1652
+ throw new DeserializeError(`Invalid issuer AID code=${String(code)}.`);
1653
+ }
211
1654
  }
212
1655
  }
213
- catch (error) {
214
- if (error instanceof DeserializeError) {
215
- throw new DeserializeError(`Failed to decode ${kind} Serder: ${String(error.message)}`);
1656
+ get uuid() {
1657
+ return this.ked && typeof this.ked.u === "string" ? this.ked.u : null;
1658
+ }
1659
+ get uuidb() {
1660
+ return this.uuid ? b(this.uuid) : null;
1661
+ }
1662
+ get issuer() {
1663
+ return this.ked && typeof this.ked.i === "string" ? this.ked.i : null;
1664
+ }
1665
+ get issuerb() {
1666
+ return this.issuer ? b(this.issuer) : null;
1667
+ }
1668
+ get regid() {
1669
+ if (!this.ked) {
1670
+ return null;
216
1671
  }
217
- if (kind === "JSON" && error instanceof SyntaxError) {
218
- throw new DeserializeError(`Failed to decode JSON Serder: ${String(error)}`);
1672
+ if (this.pvrsn.major === 1) {
1673
+ return typeof this.ked.ri === "string" ? this.ked.ri : null;
219
1674
  }
220
- if (kind === "MGPK" || kind === "CBOR") {
221
- throw new DeserializeError(`Failed to decode ${kind} Serder: ${String(error)}`);
1675
+ return typeof this.ked.rd === "string" ? this.ked.rd : null;
1676
+ }
1677
+ get regidb() {
1678
+ return this.regid ? b(this.regid) : null;
1679
+ }
1680
+ get schema() {
1681
+ return this.ked?.s;
1682
+ }
1683
+ get attrib() {
1684
+ return this.ked?.a;
1685
+ }
1686
+ get issuee() {
1687
+ const attrib = this.attrib;
1688
+ if (attrib && typeof attrib === "object" && !Array.isArray(attrib)) {
1689
+ const issuee = attrib.i;
1690
+ return typeof issuee === "string" ? issuee : null;
222
1691
  }
223
- throw error;
1692
+ return null;
224
1693
  }
1694
+ get issueeb() {
1695
+ return this.issuee ? b(this.issuee) : null;
1696
+ }
1697
+ get aggreg() {
1698
+ return this.ked?.A;
1699
+ }
1700
+ get edge() {
1701
+ return this.ked?.e;
1702
+ }
1703
+ get rule() {
1704
+ return this.ked?.r;
1705
+ }
1706
+ }
1707
+ Object.defineProperty(SerderACDC, "Protocol", {
1708
+ enumerable: true,
1709
+ configurable: true,
1710
+ writable: true,
1711
+ value: Protocols.acdc
1712
+ });
1713
+ Object.defineProperty(SerderACDC, "Proto", {
1714
+ enumerable: true,
1715
+ configurable: true,
1716
+ writable: true,
1717
+ value: Protocols.acdc
1718
+ });
1719
+ /**
1720
+ * Parse one raw Serder body and hydrate protocol-specific Serder subclasses.
1721
+ */
1722
+ export function parseSerder(raw, smellage) {
1723
+ const { ked, ilk, said } = parseRawToKed(raw, smellage);
225
1724
  const init = {
226
1725
  raw,
227
- smellage: { proto, kind, pvrsn, gvrsn, size },
1726
+ smellage,
228
1727
  ked,
229
1728
  ilk,
230
1729
  said,
231
1730
  };
232
- if (proto === Protocols.keri) {
1731
+ if (smellage.proto === Protocols.keri) {
233
1732
  return new SerderKERI(init);
234
1733
  }
235
- if (proto === Protocols.acdc) {
1734
+ if (smellage.proto === Protocols.acdc) {
236
1735
  return new SerderACDC(init);
237
1736
  }
238
1737
  return new Serder(init);