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.
- package/esm/src/adapters/async-iterable.js +8 -0
- package/esm/src/adapters/effection.js +6 -0
- package/esm/src/annotate/annotator.js +12 -0
- package/esm/src/annotate/cli.js +12 -0
- package/esm/src/annotate/comments.js +5 -1
- package/esm/src/annotate/denot.js +6 -0
- package/esm/src/annotate/render.js +15 -3
- package/esm/src/core/bytes.js +9 -0
- package/esm/src/core/errors.js +3 -0
- package/esm/src/core/parser-engine.js +1 -1
- package/esm/src/core/parser-frame-parser.js +22 -18
- package/esm/src/core/vocabulary.js +47 -0
- package/esm/src/index.js +5 -0
- package/esm/src/parser/attachment-parser.js +4 -0
- package/esm/src/parser/cold-start.js +6 -0
- package/esm/src/parser/group-dispatch.js +2 -2
- package/esm/src/primitives/aggor.js +374 -30
- package/esm/src/primitives/bexter.js +2 -3
- package/esm/src/primitives/blinder.js +6 -0
- package/esm/src/primitives/byte-like.js +19 -0
- package/esm/src/primitives/cigar.js +17 -3
- package/esm/src/primitives/cipher.js +91 -6
- package/esm/src/primitives/codex.js +39 -6
- package/esm/src/primitives/compactor.js +307 -3
- package/esm/src/primitives/counter.js +6 -2
- package/esm/src/primitives/dater.js +1 -2
- package/esm/src/primitives/decimer.js +7 -11
- package/esm/src/primitives/decrypter.js +123 -7
- package/esm/src/primitives/diger.js +57 -3
- package/esm/src/primitives/disclosure.js +300 -0
- package/esm/src/primitives/encrypter.js +130 -7
- package/esm/src/primitives/hydrate.js +49 -0
- package/esm/src/primitives/ilker.js +2 -3
- package/esm/src/primitives/indexer.js +21 -4
- package/esm/src/primitives/labeler.js +1 -2
- package/esm/src/primitives/mapper.js +612 -35
- package/esm/src/primitives/matter.js +133 -3
- package/esm/src/primitives/mediar.js +6 -0
- package/esm/src/primitives/noncer.js +2 -3
- package/esm/src/primitives/number.js +1 -2
- package/esm/src/primitives/pather.js +102 -5
- package/esm/src/primitives/prefixer.js +1 -2
- package/esm/src/primitives/primitive.js +14 -0
- package/esm/src/primitives/registry.js +2 -0
- package/esm/src/primitives/saider.js +80 -3
- package/esm/src/primitives/salter.js +96 -2
- package/esm/src/primitives/sealed-box.js +41 -0
- package/esm/src/primitives/seqner.js +1 -2
- package/esm/src/primitives/siger.js +58 -3
- package/esm/src/primitives/signer.js +243 -9
- package/esm/src/primitives/streamer.js +28 -0
- package/esm/src/primitives/structing.js +727 -0
- package/esm/src/primitives/structor.js +20 -0
- package/esm/src/primitives/tagger.js +1 -2
- package/esm/src/primitives/texter.js +1 -2
- package/esm/src/primitives/tholder.js +552 -10
- package/esm/src/primitives/traitor.js +2 -3
- package/esm/src/primitives/verfer.js +50 -6
- package/esm/src/primitives/verser.js +16 -6
- package/esm/src/router/router-stub.js +1 -0
- package/esm/src/serder/native.js +1326 -0
- package/esm/src/serder/serder.js +1558 -59
- package/esm/src/serder/serdery.js +92 -7
- package/esm/src/serder/smell.js +26 -1
- package/esm/src/tables/codex-utils.js +2 -0
- package/esm/src/tables/counter-codex.js +2 -0
- package/esm/src/tables/counter-groups.js +6 -0
- package/esm/src/tables/versions.js +4 -0
- package/esm/src/version.js +5 -2
- package/package.json +5 -2
- package/types/src/adapters/async-iterable.d.ts +8 -0
- package/types/src/adapters/async-iterable.d.ts.map +1 -1
- package/types/src/adapters/effection.d.ts +7 -0
- package/types/src/adapters/effection.d.ts.map +1 -1
- package/types/src/annotate/annotator.d.ts +12 -0
- package/types/src/annotate/annotator.d.ts.map +1 -1
- package/types/src/annotate/cli.d.ts +13 -0
- package/types/src/annotate/cli.d.ts.map +1 -1
- package/types/src/annotate/comments.d.ts +4 -0
- package/types/src/annotate/comments.d.ts.map +1 -1
- package/types/src/annotate/denot.d.ts +6 -0
- package/types/src/annotate/denot.d.ts.map +1 -1
- package/types/src/annotate/render.d.ts.map +1 -1
- package/types/src/annotate/types.d.ts +2 -0
- package/types/src/annotate/types.d.ts.map +1 -1
- package/types/src/bench/parser-benchmark.d.ts +3 -0
- package/types/src/bench/parser-benchmark.d.ts.map +1 -1
- package/types/src/core/bytes.d.ts +9 -0
- package/types/src/core/bytes.d.ts.map +1 -1
- package/types/src/core/errors.d.ts +3 -0
- package/types/src/core/errors.d.ts.map +1 -1
- package/types/src/core/parser-engine.d.ts +4 -0
- package/types/src/core/parser-engine.d.ts.map +1 -1
- package/types/src/core/parser-frame-parser.d.ts.map +1 -1
- package/types/src/core/types.d.ts +2 -0
- package/types/src/core/types.d.ts.map +1 -1
- package/types/src/core/vocabulary.d.ts +48 -0
- package/types/src/core/vocabulary.d.ts.map +1 -0
- package/types/src/index.d.ts +5 -0
- package/types/src/index.d.ts.map +1 -1
- package/types/src/parser/attachment-parser.d.ts +4 -0
- package/types/src/parser/attachment-parser.d.ts.map +1 -1
- package/types/src/parser/cold-start.d.ts +6 -0
- package/types/src/parser/cold-start.d.ts.map +1 -1
- package/types/src/parser/group-dispatch.d.ts.map +1 -1
- package/types/src/primitives/aggor.d.ts +100 -13
- package/types/src/primitives/aggor.d.ts.map +1 -1
- package/types/src/primitives/bexter.d.ts.map +1 -1
- package/types/src/primitives/blinder.d.ts +6 -0
- package/types/src/primitives/blinder.d.ts.map +1 -1
- package/types/src/primitives/byte-like.d.ts +7 -0
- package/types/src/primitives/byte-like.d.ts.map +1 -0
- package/types/src/primitives/cigar.d.ts +11 -1
- package/types/src/primitives/cigar.d.ts.map +1 -1
- package/types/src/primitives/cipher.d.ts +73 -2
- package/types/src/primitives/cipher.d.ts.map +1 -1
- package/types/src/primitives/codex.d.ts +34 -4
- package/types/src/primitives/codex.d.ts.map +1 -1
- package/types/src/primitives/compactor.d.ts +94 -2
- package/types/src/primitives/compactor.d.ts.map +1 -1
- package/types/src/primitives/counter.d.ts.map +1 -1
- package/types/src/primitives/dater.d.ts.map +1 -1
- package/types/src/primitives/decimer.d.ts.map +1 -1
- package/types/src/primitives/decrypter.d.ts +64 -3
- package/types/src/primitives/decrypter.d.ts.map +1 -1
- package/types/src/primitives/diger.d.ts +16 -0
- package/types/src/primitives/diger.d.ts.map +1 -1
- package/types/src/primitives/disclosure.d.ts +201 -0
- package/types/src/primitives/disclosure.d.ts.map +1 -0
- package/types/src/primitives/encrypter.d.ts +66 -4
- package/types/src/primitives/encrypter.d.ts.map +1 -1
- package/types/src/primitives/hydrate.d.ts +20 -0
- package/types/src/primitives/hydrate.d.ts.map +1 -0
- package/types/src/primitives/ilker.d.ts.map +1 -1
- package/types/src/primitives/indexer.d.ts.map +1 -1
- package/types/src/primitives/labeler.d.ts.map +1 -1
- package/types/src/primitives/mapper.d.ts +132 -11
- package/types/src/primitives/mapper.d.ts.map +1 -1
- package/types/src/primitives/matter.d.ts +33 -1
- package/types/src/primitives/matter.d.ts.map +1 -1
- package/types/src/primitives/mediar.d.ts +6 -0
- package/types/src/primitives/mediar.d.ts.map +1 -1
- package/types/src/primitives/noncer.d.ts.map +1 -1
- package/types/src/primitives/number.d.ts.map +1 -1
- package/types/src/primitives/pather.d.ts +21 -0
- package/types/src/primitives/pather.d.ts.map +1 -1
- package/types/src/primitives/prefixer.d.ts.map +1 -1
- package/types/src/primitives/primitive.d.ts +26 -0
- package/types/src/primitives/primitive.d.ts.map +1 -1
- package/types/src/primitives/registry.d.ts +3 -0
- package/types/src/primitives/registry.d.ts.map +1 -1
- package/types/src/primitives/saider.d.ts +41 -0
- package/types/src/primitives/saider.d.ts.map +1 -1
- package/types/src/primitives/salter.d.ts +56 -1
- package/types/src/primitives/salter.d.ts.map +1 -1
- package/types/src/primitives/sealed-box.d.ts +29 -0
- package/types/src/primitives/sealed-box.d.ts.map +1 -0
- package/types/src/primitives/seqner.d.ts.map +1 -1
- package/types/src/primitives/siger.d.ts +14 -0
- package/types/src/primitives/siger.d.ts.map +1 -1
- package/types/src/primitives/signer.d.ts +80 -4
- package/types/src/primitives/signer.d.ts.map +1 -1
- package/types/src/primitives/streamer.d.ts +31 -0
- package/types/src/primitives/streamer.d.ts.map +1 -0
- package/types/src/primitives/structing.d.ts +4114 -0
- package/types/src/primitives/structing.d.ts.map +1 -0
- package/types/src/primitives/structor.d.ts +6 -0
- package/types/src/primitives/structor.d.ts.map +1 -1
- package/types/src/primitives/tagger.d.ts.map +1 -1
- package/types/src/primitives/texter.d.ts.map +1 -1
- package/types/src/primitives/tholder.d.ts +150 -5
- package/types/src/primitives/tholder.d.ts.map +1 -1
- package/types/src/primitives/traitor.d.ts.map +1 -1
- package/types/src/primitives/unknown.d.ts +1 -0
- package/types/src/primitives/unknown.d.ts.map +1 -1
- package/types/src/primitives/verfer.d.ts +12 -0
- package/types/src/primitives/verfer.d.ts.map +1 -1
- package/types/src/primitives/verser.d.ts +14 -3
- package/types/src/primitives/verser.d.ts.map +1 -1
- package/types/src/router/router-stub.d.ts +3 -0
- package/types/src/router/router-stub.d.ts.map +1 -1
- package/types/src/serder/native.d.ts +115 -0
- package/types/src/serder/native.d.ts.map +1 -0
- package/types/src/serder/serder.d.ts +187 -9
- package/types/src/serder/serder.d.ts.map +1 -1
- package/types/src/serder/serdery.d.ts +42 -0
- package/types/src/serder/serdery.d.ts.map +1 -1
- package/types/src/serder/smell.d.ts +22 -0
- package/types/src/serder/smell.d.ts.map +1 -1
- package/types/src/tables/codex-utils.d.ts +3 -0
- package/types/src/tables/codex-utils.d.ts.map +1 -1
- package/types/src/tables/counter-codex.d.ts +4 -0
- package/types/src/tables/counter-codex.d.ts.map +1 -1
- package/types/src/tables/counter-groups.d.ts +6 -0
- package/types/src/tables/counter-groups.d.ts.map +1 -1
- package/types/src/tables/counter.tables.generated.d.ts.map +1 -1
- package/types/src/tables/indexer.codex.generated.d.ts.map +1 -1
- package/types/src/tables/matter.codex.generated.d.ts.map +1 -1
- package/types/src/tables/table-types.d.ts +6 -0
- package/types/src/tables/table-types.d.ts.map +1 -1
- package/types/src/tables/versions.d.ts +6 -0
- package/types/src/tables/versions.d.ts.map +1 -1
- package/types/src/version.d.ts +5 -2
- package/types/src/version.d.ts.map +1 -1
package/esm/src/serder/serder.js
CHANGED
|
@@ -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 {
|
|
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
|
|
52
|
-
*
|
|
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, "
|
|
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, "
|
|
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
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
206
|
-
|
|
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 (
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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 (
|
|
218
|
-
|
|
1672
|
+
if (this.pvrsn.major === 1) {
|
|
1673
|
+
return typeof this.ked.ri === "string" ? this.ked.ri : null;
|
|
219
1674
|
}
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
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
|
|
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);
|