@real-life/trust-protocol 0.3.1 → 0.4.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/CHANGELOG.md +32 -0
- package/README.md +187 -78
- package/dist/ack.d.ts +84 -0
- package/dist/ack.d.ts.map +1 -0
- package/dist/ack.js +114 -0
- package/dist/ack.js.map +1 -0
- package/dist/adapters/vti-mediator.d.ts +154 -0
- package/dist/adapters/vti-mediator.d.ts.map +1 -0
- package/dist/adapters/vti-mediator.js +621 -0
- package/dist/adapters/vti-mediator.js.map +1 -0
- package/dist/anchor.d.ts +226 -0
- package/dist/anchor.d.ts.map +1 -0
- package/dist/anchor.js +347 -0
- package/dist/anchor.js.map +1 -0
- package/dist/{holder.d.ts → carrier-holder.d.ts} +1 -1
- package/dist/carrier-holder.d.ts.map +1 -0
- package/dist/{holder.js → carrier-holder.js} +5 -4
- package/dist/carrier-holder.js.map +1 -0
- package/dist/carrier-identity.js +4 -4
- package/dist/carrier-identity.js.map +1 -1
- package/dist/carrier.d.ts.map +1 -1
- package/dist/carrier.js +4 -3
- package/dist/carrier.js.map +1 -1
- package/dist/ceremony.d.ts +3 -2
- package/dist/ceremony.d.ts.map +1 -1
- package/dist/ceremony.js +16 -26
- package/dist/ceremony.js.map +1 -1
- package/dist/codec.d.ts +46 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +410 -0
- package/dist/codec.js.map +1 -0
- package/dist/continuity.d.ts +67 -0
- package/dist/continuity.d.ts.map +1 -0
- package/dist/continuity.js +110 -0
- package/dist/continuity.js.map +1 -0
- package/dist/core.d.ts +4 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js.map +1 -1
- package/dist/crypto.d.ts +23 -7
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +54 -20
- package/dist/crypto.js.map +1 -1
- package/dist/delivery.d.ts +31 -3
- package/dist/delivery.d.ts.map +1 -1
- package/dist/delivery.js +75 -28
- package/dist/delivery.js.map +1 -1
- package/dist/encounter/ceremony.d.ts +37 -0
- package/dist/encounter/ceremony.d.ts.map +1 -0
- package/dist/encounter/ceremony.js +662 -0
- package/dist/encounter/ceremony.js.map +1 -0
- package/dist/encounter.d.ts +91 -1
- package/dist/encounter.d.ts.map +1 -1
- package/dist/encounter.js +191 -12
- package/dist/encounter.js.map +1 -1
- package/dist/engine.d.ts +291 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1395 -0
- package/dist/engine.js.map +1 -0
- package/dist/entropy.d.ts +28 -0
- package/dist/entropy.d.ts.map +1 -0
- package/dist/entropy.js +96 -0
- package/dist/entropy.js.map +1 -0
- package/dist/events.d.ts +177 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/fixtures.d.ts +30 -0
- package/dist/fixtures.d.ts.map +1 -0
- package/dist/fixtures.js +155 -0
- package/dist/fixtures.js.map +1 -0
- package/dist/forge.d.ts +47 -0
- package/dist/forge.d.ts.map +1 -0
- package/dist/forge.js +20 -0
- package/dist/forge.js.map +1 -0
- package/dist/group-star.d.ts +251 -0
- package/dist/group-star.d.ts.map +1 -0
- package/dist/group-star.js +348 -0
- package/dist/group-star.js.map +1 -0
- package/dist/holder-api.d.ts +137 -0
- package/dist/holder-api.d.ts.map +1 -0
- package/dist/holder-api.js +132 -0
- package/dist/holder-api.js.map +1 -0
- package/dist/holder-state-v1.d.ts +801 -0
- package/dist/holder-state-v1.d.ts.map +1 -0
- package/dist/holder-state-v1.js +2 -0
- package/dist/holder-state-v1.js.map +1 -0
- package/dist/identity-state.d.ts +43 -0
- package/dist/identity-state.d.ts.map +1 -0
- package/dist/identity-state.js +345 -0
- package/dist/identity-state.js.map +1 -0
- package/dist/identity.d.ts +24 -2
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +70 -11
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +77 -29
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +36 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +22 -0
- package/dist/internal.js.map +1 -0
- package/dist/introduction/holder.d.ts +18 -0
- package/dist/introduction/holder.d.ts.map +1 -0
- package/dist/introduction/holder.js +757 -0
- package/dist/introduction/holder.js.map +1 -0
- package/dist/introduction.d.ts +101 -0
- package/dist/introduction.d.ts.map +1 -0
- package/dist/introduction.js +132 -0
- package/dist/introduction.js.map +1 -0
- package/dist/invariants.d.ts +43 -0
- package/dist/invariants.d.ts.map +1 -0
- package/dist/invariants.js +883 -0
- package/dist/invariants.js.map +1 -0
- package/dist/keys-seed.d.ts +7 -0
- package/dist/keys-seed.d.ts.map +1 -0
- package/dist/keys-seed.js +133 -0
- package/dist/keys-seed.js.map +1 -0
- package/dist/log-memory.d.ts +12 -0
- package/dist/log-memory.d.ts.map +1 -0
- package/dist/log-memory.js +101 -0
- package/dist/log-memory.js.map +1 -0
- package/dist/membership/holder.d.ts +35 -0
- package/dist/membership/holder.d.ts.map +1 -0
- package/dist/membership/holder.js +852 -0
- package/dist/membership/holder.js.map +1 -0
- package/dist/membership.d.ts +92 -0
- package/dist/membership.d.ts.map +1 -0
- package/dist/membership.js +157 -0
- package/dist/membership.js.map +1 -0
- package/dist/ports.d.ts +237 -0
- package/dist/ports.d.ts.map +1 -0
- package/dist/ports.js +2 -0
- package/dist/ports.js.map +1 -0
- package/dist/profile.d.ts +56 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +193 -0
- package/dist/profile.js.map +1 -0
- package/dist/prompts.d.ts +14 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +69 -0
- package/dist/prompts.js.map +1 -0
- package/dist/receive.d.ts +133 -0
- package/dist/receive.d.ts.map +1 -0
- package/dist/receive.js +298 -0
- package/dist/receive.js.map +1 -0
- package/dist/results.d.ts +158 -0
- package/dist/results.d.ts.map +1 -0
- package/dist/results.js +21 -0
- package/dist/results.js.map +1 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +42 -38
- package/dist/schemas.js.map +1 -1
- package/dist/sha256.d.ts +3 -0
- package/dist/sha256.d.ts.map +1 -0
- package/dist/sha256.js +69 -0
- package/dist/sha256.js.map +1 -0
- package/dist/star.d.ts +31 -0
- package/dist/star.d.ts.map +1 -0
- package/dist/star.js +56 -0
- package/dist/star.js.map +1 -0
- package/dist/state-builder.d.ts +42 -0
- package/dist/state-builder.d.ts.map +1 -0
- package/dist/state-builder.js +100 -0
- package/dist/state-builder.js.map +1 -0
- package/dist/state.d.ts +853 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +36 -0
- package/dist/state.js.map +1 -0
- package/dist/store-contract.d.ts +11 -0
- package/dist/store-contract.d.ts.map +1 -0
- package/dist/store-contract.js +189 -0
- package/dist/store-contract.js.map +1 -0
- package/dist/store-memory.d.ts +8 -0
- package/dist/store-memory.d.ts.map +1 -0
- package/dist/store-memory.js +17 -0
- package/dist/store-memory.js.map +1 -0
- package/dist/testing.d.ts +22 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +21 -0
- package/dist/testing.js.map +1 -0
- package/dist/trust/continuity.d.ts +71 -0
- package/dist/trust/continuity.d.ts.map +1 -0
- package/dist/trust/continuity.js +1216 -0
- package/dist/trust/continuity.js.map +1 -0
- package/dist/trust/duties.d.ts +67 -0
- package/dist/trust/duties.d.ts.map +1 -0
- package/dist/trust/duties.js +179 -0
- package/dist/trust/duties.js.map +1 -0
- package/dist/trust/entries.d.ts +139 -0
- package/dist/trust/entries.d.ts.map +1 -0
- package/dist/trust/entries.js +694 -0
- package/dist/trust/entries.js.map +1 -0
- package/dist/trust/group-star.d.ts +43 -0
- package/dist/trust/group-star.d.ts.map +1 -0
- package/dist/trust/group-star.js +188 -0
- package/dist/trust/group-star.js.map +1 -0
- package/dist/trust/mapping.d.ts +56 -0
- package/dist/trust/mapping.d.ts.map +1 -0
- package/dist/trust/mapping.js +584 -0
- package/dist/trust/mapping.js.map +1 -0
- package/dist/trust/profile.d.ts +25 -0
- package/dist/trust/profile.d.ts.map +1 -0
- package/dist/trust/profile.js +249 -0
- package/dist/trust/profile.js.map +1 -0
- package/dist/trust/star.d.ts +208 -0
- package/dist/trust/star.d.ts.map +1 -0
- package/dist/trust/star.js +588 -0
- package/dist/trust/star.js.map +1 -0
- package/dist/trust/state.d.ts +83 -0
- package/dist/trust/state.d.ts.map +1 -0
- package/dist/trust/state.js +154 -0
- package/dist/trust/state.js.map +1 -0
- package/dist/util-freeze.d.ts +3 -0
- package/dist/util-freeze.d.ts.map +1 -0
- package/dist/util-freeze.js +11 -0
- package/dist/util-freeze.js.map +1 -0
- package/dist/views.d.ts +147 -0
- package/dist/views.d.ts.map +1 -0
- package/dist/views.js +268 -0
- package/dist/views.js.map +1 -0
- package/dist/visibility.d.ts +5 -5
- package/dist/visibility.d.ts.map +1 -1
- package/dist/visibility.js +22 -28
- package/dist/visibility.js.map +1 -1
- package/dist/wire.d.ts +178 -84
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js.map +1 -1
- package/package.json +58 -11
- package/schemas/holder-state-v1.schema.json +3880 -0
- package/dist/holder.d.ts.map +0 -1
- package/dist/holder.js.map +0 -1
- package/dist/probe/acks.d.ts +0 -27
- package/dist/probe/acks.d.ts.map +0 -1
- package/dist/probe/acks.js +0 -152
- package/dist/probe/acks.js.map +0 -1
- package/dist/probe/continuity.d.ts +0 -20
- package/dist/probe/continuity.d.ts.map +0 -1
- package/dist/probe/continuity.js +0 -805
- package/dist/probe/continuity.js.map +0 -1
- package/dist/probe/deps.d.ts +0 -61
- package/dist/probe/deps.d.ts.map +0 -1
- package/dist/probe/deps.js +0 -54
- package/dist/probe/deps.js.map +0 -1
- package/dist/probe/encounter.d.ts +0 -26
- package/dist/probe/encounter.d.ts.map +0 -1
- package/dist/probe/encounter.js +0 -938
- package/dist/probe/encounter.js.map +0 -1
- package/dist/probe/introduce.d.ts +0 -70
- package/dist/probe/introduce.d.ts.map +0 -1
- package/dist/probe/introduce.js +0 -295
- package/dist/probe/introduce.js.map +0 -1
- package/dist/probe/membership.d.ts +0 -90
- package/dist/probe/membership.d.ts.map +0 -1
- package/dist/probe/membership.js +0 -450
- package/dist/probe/membership.js.map +0 -1
- package/dist/probe/trust.d.ts +0 -156
- package/dist/probe/trust.d.ts.map +0 -1
- package/dist/probe/trust.js +0 -1233
- package/dist/probe/trust.js.map +0 -1
- package/dist/probe.d.ts +0 -7
- package/dist/probe.d.ts.map +0 -1
- package/dist/probe.js +0 -42
- package/dist/probe.js.map +0 -1
package/dist/sha256.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sha256.d.ts","sourceRoot":"","sources":["../src/sha256.ts"],"names":[],"mappings":"AAqBA,2DAA2D;AAC3D,wBAAgB,SAAS,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiC/C"}
|
package/dist/sha256.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// sha256 — a synchronous SHA-256 (FIPS 180-4) over UTF-8 text: a
|
|
2
|
+
// deliberately scoped exception to "WebCrypto only" (README). It digests
|
|
3
|
+
// local state only — the reconciliation views of 5.4 that a pure,
|
|
4
|
+
// synchronous transition compares (trust/star.ts, used for the star and
|
|
5
|
+
// the group star) — and never wire bytes, keys or MACs; WebCrypto's digest
|
|
6
|
+
// is asynchronous and cannot serve there. test/sha256.test.mjs checks it
|
|
7
|
+
// differentially against node:crypto and that no other module imports it.
|
|
8
|
+
const K = new Uint32Array([
|
|
9
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
10
|
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
11
|
+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
12
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
13
|
+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
14
|
+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
15
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
16
|
+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
17
|
+
]);
|
|
18
|
+
const te = new TextEncoder();
|
|
19
|
+
/** SHA-256 of the UTF-8 bytes of `text`, lowercase hex. */
|
|
20
|
+
export function sha256Hex(text) {
|
|
21
|
+
const msg = te.encode(text);
|
|
22
|
+
const bitLen = msg.length * 8;
|
|
23
|
+
const padded = new Uint8Array(((msg.length + 9 + 63) >> 6) << 6);
|
|
24
|
+
padded.set(msg);
|
|
25
|
+
padded[msg.length] = 0x80;
|
|
26
|
+
const dv = new DataView(padded.buffer);
|
|
27
|
+
dv.setUint32(padded.length - 8, Math.floor(bitLen / 0x100000000));
|
|
28
|
+
dv.setUint32(padded.length - 4, bitLen >>> 0);
|
|
29
|
+
const H = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]);
|
|
30
|
+
const W = new Uint32Array(64);
|
|
31
|
+
for (let off = 0; off < padded.length; off += 64) {
|
|
32
|
+
for (let i = 0; i < 16; i++)
|
|
33
|
+
W[i] = dv.getUint32(off + i * 4);
|
|
34
|
+
for (let i = 16; i < 64; i++) {
|
|
35
|
+
const a = W[i - 15], b = W[i - 2];
|
|
36
|
+
const s0 = ((a >>> 7) | (a << 25)) ^ ((a >>> 18) | (a << 14)) ^ (a >>> 3);
|
|
37
|
+
const s1 = ((b >>> 17) | (b << 15)) ^ ((b >>> 19) | (b << 13)) ^ (b >>> 10);
|
|
38
|
+
W[i] = (W[i - 16] + s0 + W[i - 7] + s1) >>> 0;
|
|
39
|
+
}
|
|
40
|
+
let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7];
|
|
41
|
+
for (let i = 0; i < 64; i++) {
|
|
42
|
+
const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
|
|
43
|
+
const t1 = (h + S1 + ((e & f) ^ (~e & g)) + K[i] + W[i]) >>> 0;
|
|
44
|
+
const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
|
|
45
|
+
const t2 = (S0 + ((a & b) ^ (a & c) ^ (b & c))) >>> 0;
|
|
46
|
+
h = g;
|
|
47
|
+
g = f;
|
|
48
|
+
f = e;
|
|
49
|
+
e = (d + t1) >>> 0;
|
|
50
|
+
d = c;
|
|
51
|
+
c = b;
|
|
52
|
+
b = a;
|
|
53
|
+
a = (t1 + t2) >>> 0;
|
|
54
|
+
}
|
|
55
|
+
H[0] = (H[0] + a) >>> 0;
|
|
56
|
+
H[1] = (H[1] + b) >>> 0;
|
|
57
|
+
H[2] = (H[2] + c) >>> 0;
|
|
58
|
+
H[3] = (H[3] + d) >>> 0;
|
|
59
|
+
H[4] = (H[4] + e) >>> 0;
|
|
60
|
+
H[5] = (H[5] + f) >>> 0;
|
|
61
|
+
H[6] = (H[6] + g) >>> 0;
|
|
62
|
+
H[7] = (H[7] + h) >>> 0;
|
|
63
|
+
}
|
|
64
|
+
let out = '';
|
|
65
|
+
for (const x of H)
|
|
66
|
+
out += x.toString(16).padStart(8, '0');
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=sha256.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sha256.js","sourceRoot":"","sources":["../src/sha256.ts"],"names":[],"mappings":"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","sourcesContent":["// sha256 — a synchronous SHA-256 (FIPS 180-4) over UTF-8 text: a\n// deliberately scoped exception to \"WebCrypto only\" (README). It digests\n// local state only — the reconciliation views of 5.4 that a pure,\n// synchronous transition compares (trust/star.ts, used for the star and\n// the group star) — and never wire bytes, keys or MACs; WebCrypto's digest\n// is asynchronous and cannot serve there. test/sha256.test.mjs checks it\n// differentially against node:crypto and that no other module imports it.\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n])\n\nconst te = new TextEncoder()\n\n/** SHA-256 of the UTF-8 bytes of `text`, lowercase hex. */\nexport function sha256Hex (text: string): string {\n const msg = te.encode(text)\n const bitLen = msg.length * 8\n const padded = new Uint8Array(((msg.length + 9 + 63) >> 6) << 6)\n padded.set(msg)\n padded[msg.length] = 0x80\n const dv = new DataView(padded.buffer)\n dv.setUint32(padded.length - 8, Math.floor(bitLen / 0x100000000))\n dv.setUint32(padded.length - 4, bitLen >>> 0)\n const H = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19])\n const W = new Uint32Array(64)\n for (let off = 0; off < padded.length; off += 64) {\n for (let i = 0; i < 16; i++) W[i] = dv.getUint32(off + i * 4)\n for (let i = 16; i < 64; i++) {\n const a = W[i - 15], b = W[i - 2]\n const s0 = ((a >>> 7) | (a << 25)) ^ ((a >>> 18) | (a << 14)) ^ (a >>> 3)\n const s1 = ((b >>> 17) | (b << 15)) ^ ((b >>> 19) | (b << 13)) ^ (b >>> 10)\n W[i] = (W[i - 16] + s0 + W[i - 7] + s1) >>> 0\n }\n let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7]\n for (let i = 0; i < 64; i++) {\n const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7))\n const t1 = (h + S1 + ((e & f) ^ (~e & g)) + K[i] + W[i]) >>> 0\n const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10))\n const t2 = (S0 + ((a & b) ^ (a & c) ^ (b & c))) >>> 0\n h = g; g = f; f = e; e = (d + t1) >>> 0; d = c; c = b; b = a; a = (t1 + t2) >>> 0\n }\n H[0] = (H[0] + a) >>> 0; H[1] = (H[1] + b) >>> 0; H[2] = (H[2] + c) >>> 0; H[3] = (H[3] + d) >>> 0\n H[4] = (H[4] + e) >>> 0; H[5] = (H[5] + f) >>> 0; H[6] = (H[6] + g) >>> 0; H[7] = (H[7] + h) >>> 0\n }\n let out = ''\n for (const x of H) out += x.toString(16).padStart(8, '0')\n return out\n}\n"]}
|
package/dist/star.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** At most this many entries per chunk (5200). */
|
|
2
|
+
export declare const STAR_CHUNK = 1024;
|
|
3
|
+
/** The Delivery Contract's plaintext limit a chunk's document stays within (5190). */
|
|
4
|
+
export declare const PLAINTEXT_MAX = 65536;
|
|
5
|
+
export type StarChunk = {
|
|
6
|
+
body: {
|
|
7
|
+
type: 'star@2';
|
|
8
|
+
salt: string;
|
|
9
|
+
seq: string;
|
|
10
|
+
last: boolean;
|
|
11
|
+
blinded: string[];
|
|
12
|
+
};
|
|
13
|
+
proof: {
|
|
14
|
+
mac: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
/** k of one direction from the pair secret (5160); salt in its wire string form. */
|
|
18
|
+
export declare function starKeyOf(shared: Uint8Array, sender: string, recipient: string, salt: string, subtle?: SubtleCrypto): Promise<Uint8Array>;
|
|
19
|
+
/** One blinded entry: HMAC(k, anchor) in its u form (5010). */
|
|
20
|
+
export declare const blindAnchor: (k: Uint8Array, anchor: string, subtle?: SubtleCrypto) => Promise<string>;
|
|
21
|
+
/** The chunks of one delivery: every anchor once, blinded, sorted once,
|
|
22
|
+
* sliced by STAR_CHUNK (5010, 5050, 5200, 5220). */
|
|
23
|
+
export declare function buildStarChunks(k: Uint8Array, salt: string, anchors: Iterable<string>, subtle?: SubtleCrypto): Promise<StarChunk[]>;
|
|
24
|
+
/** Is this a schema-valid star@2 chunk (visibility-star.schema.json)? */
|
|
25
|
+
export declare const starChunkOk: (chunk: unknown) => boolean;
|
|
26
|
+
/** Does the chunk's MAC verify under k (5080)? */
|
|
27
|
+
export declare function starChunkMacOk(k: Uint8Array, chunk: StarChunk, subtle?: SubtleCrypto): Promise<boolean>;
|
|
28
|
+
/** The assembled union is strictly ascending: sorted and free of
|
|
29
|
+
* duplicates in one check (5300, 5310). */
|
|
30
|
+
export declare const strictlyAscending: (xs: readonly string[]) => boolean;
|
|
31
|
+
//# sourceMappingURL=star.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"star.d.ts","sourceRoot":"","sources":["../src/star.ts"],"names":[],"mappings":"AAqBA,kDAAkD;AAClD,eAAO,MAAM,UAAU,OAAO,CAAA;AAC9B,sFAAsF;AACtF,eAAO,MAAM,aAAa,QAAS,CAAA;AAEnC,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAA;AAEzI,oFAAoF;AACpF,wBAAsB,SAAS,CAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,YAA+B,GAAG,OAAO,CAAC,UAAU,CAAC,CAGlK;AAED,+DAA+D;AAC/D,eAAO,MAAM,WAAW,GAAI,GAAG,UAAU,EAAE,QAAQ,MAAM,EAAE,SAAS,YAAY,KAAG,OAAO,CAAC,MAAM,CAA4B,CAAA;AAE7H;qDACqD;AACrD,wBAAsB,eAAe,CAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAE,YAA+B,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAW5J;AAED,yEAAyE;AACzE,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,OACuE,CAAA;AAEpH,kDAAkD;AAClD,wBAAsB,cAAc,CAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9G;AAED;4CAC4C;AAC5C,eAAO,MAAM,iBAAiB,GAAI,IAAI,SAAS,MAAM,EAAE,KAAG,OAAwD,CAAA"}
|
package/dist/star.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// star — star@2, the blinded star with its 5.2a chunks (Trust Layer 0.31
|
|
2
|
+
// §5.1–5.2a, task star/0.2): the pure wire constructions over a raw
|
|
3
|
+
// X25519 shared secret (lib Stage 2, PR 4b). The holder's trust module
|
|
4
|
+
// (trust/star.ts) builds and receives through these. Byte-compatible with
|
|
5
|
+
// the star of vectors/visibility.json (vectors3.test.mjs).
|
|
6
|
+
//
|
|
7
|
+
// k = HKDF(X25519(pairX_sender, pairX_recipient),
|
|
8
|
+
// "rltp/visibility/blind/star/" || senderPair || "/" || recipientPair || "/" || salt) (5160)
|
|
9
|
+
// entry = HMAC(k, anchor bytes) (5010)
|
|
10
|
+
// chunk = { body: { type: "star@2", salt, seq, last, blinded }, proof: { mac: HMAC(k, JCS(body)) } } (5070, 5080)
|
|
11
|
+
//
|
|
12
|
+
// The union of entries is deduplicated (5050), sorted once and sliced
|
|
13
|
+
// into chunks of at most 1024 entries (5200, 5220); an empty star is one
|
|
14
|
+
// chunk with no entry.
|
|
15
|
+
import { jcs, makeValidator } from './core.js';
|
|
16
|
+
import { SCHEMAS } from './schemas.js';
|
|
17
|
+
import { hkdf, platformSubtle } from './crypto.js';
|
|
18
|
+
import { macU } from './anchor.js';
|
|
19
|
+
const VAL = makeValidator(SCHEMAS);
|
|
20
|
+
/** At most this many entries per chunk (5200). */
|
|
21
|
+
export const STAR_CHUNK = 1024;
|
|
22
|
+
/** The Delivery Contract's plaintext limit a chunk's document stays within (5190). */
|
|
23
|
+
export const PLAINTEXT_MAX = 65_536;
|
|
24
|
+
/** k of one direction from the pair secret (5160); salt in its wire string form. */
|
|
25
|
+
export async function starKeyOf(shared, sender, recipient, salt, subtle = platformSubtle()) {
|
|
26
|
+
if (shared.every((b) => b === 0))
|
|
27
|
+
throw new Error('all-zero shared secret (Trust §2.1)');
|
|
28
|
+
return hkdf(shared, `rltp/visibility/blind/star/${sender}/${recipient}/${salt}`, 32, subtle);
|
|
29
|
+
}
|
|
30
|
+
/** One blinded entry: HMAC(k, anchor) in its u form (5010). */
|
|
31
|
+
export const blindAnchor = (k, anchor, subtle) => macU(k, anchor, subtle);
|
|
32
|
+
/** The chunks of one delivery: every anchor once, blinded, sorted once,
|
|
33
|
+
* sliced by STAR_CHUNK (5010, 5050, 5200, 5220). */
|
|
34
|
+
export async function buildStarChunks(k, salt, anchors, subtle = platformSubtle()) {
|
|
35
|
+
const blinded = [];
|
|
36
|
+
for (const anchor of new Set(anchors))
|
|
37
|
+
blinded.push(await blindAnchor(k, anchor, subtle));
|
|
38
|
+
blinded.sort();
|
|
39
|
+
const n = Math.max(1, Math.ceil(blinded.length / STAR_CHUNK));
|
|
40
|
+
const chunks = [];
|
|
41
|
+
for (let i = 0; i < n; i++) {
|
|
42
|
+
const body = { type: 'star@2', salt, seq: String(i + 1), last: i === n - 1, blinded: blinded.slice(i * STAR_CHUNK, (i + 1) * STAR_CHUNK) };
|
|
43
|
+
chunks.push({ body, proof: { mac: await macU(k, jcs(body), subtle) } });
|
|
44
|
+
}
|
|
45
|
+
return chunks;
|
|
46
|
+
}
|
|
47
|
+
/** Is this a schema-valid star@2 chunk (visibility-star.schema.json)? */
|
|
48
|
+
export const starChunkOk = (chunk) => VAL.validate(chunk, SCHEMAS['visibility-star.schema.json'], SCHEMAS['visibility-star.schema.json']).length === 0;
|
|
49
|
+
/** Does the chunk's MAC verify under k (5080)? */
|
|
50
|
+
export async function starChunkMacOk(k, chunk, subtle) {
|
|
51
|
+
return (await macU(k, jcs(chunk.body), subtle)) === chunk.proof.mac;
|
|
52
|
+
}
|
|
53
|
+
/** The assembled union is strictly ascending: sorted and free of
|
|
54
|
+
* duplicates in one check (5300, 5310). */
|
|
55
|
+
export const strictlyAscending = (xs) => xs.every((x, i) => i === 0 || xs[i - 1] < x);
|
|
56
|
+
//# sourceMappingURL=star.js.map
|
package/dist/star.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"star.js","sourceRoot":"","sources":["../src/star.ts"],"names":[],"mappings":"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","sourcesContent":["// star — star@2, the blinded star with its 5.2a chunks (Trust Layer 0.31\n// §5.1–5.2a, task star/0.2): the pure wire constructions over a raw\n// X25519 shared secret (lib Stage 2, PR 4b). The holder's trust module\n// (trust/star.ts) builds and receives through these. Byte-compatible with\n// the star of vectors/visibility.json (vectors3.test.mjs).\n//\n// k = HKDF(X25519(pairX_sender, pairX_recipient),\n// \"rltp/visibility/blind/star/\" || senderPair || \"/\" || recipientPair || \"/\" || salt) (5160)\n// entry = HMAC(k, anchor bytes) (5010)\n// chunk = { body: { type: \"star@2\", salt, seq, last, blinded }, proof: { mac: HMAC(k, JCS(body)) } } (5070, 5080)\n//\n// The union of entries is deduplicated (5050), sorted once and sliced\n// into chunks of at most 1024 entries (5200, 5220); an empty star is one\n// chunk with no entry.\nimport { jcs, makeValidator } from './core.js'\nimport { SCHEMAS } from './schemas.js'\nimport { hkdf, platformSubtle } from './crypto.js'\nimport { macU } from './anchor.js'\n\nconst VAL = makeValidator(SCHEMAS)\n\n/** At most this many entries per chunk (5200). */\nexport const STAR_CHUNK = 1024\n/** The Delivery Contract's plaintext limit a chunk's document stays within (5190). */\nexport const PLAINTEXT_MAX = 65_536\n\nexport type StarChunk = { body: { type: 'star@2', salt: string, seq: string, last: boolean, blinded: string[] }, proof: { mac: string } }\n\n/** k of one direction from the pair secret (5160); salt in its wire string form. */\nexport async function starKeyOf (shared: Uint8Array, sender: string, recipient: string, salt: string, subtle: SubtleCrypto = platformSubtle()): Promise<Uint8Array> {\n if (shared.every((b) => b === 0)) throw new Error('all-zero shared secret (Trust §2.1)')\n return hkdf(shared, `rltp/visibility/blind/star/${sender}/${recipient}/${salt}`, 32, subtle)\n}\n\n/** One blinded entry: HMAC(k, anchor) in its u form (5010). */\nexport const blindAnchor = (k: Uint8Array, anchor: string, subtle?: SubtleCrypto): Promise<string> => macU(k, anchor, subtle)\n\n/** The chunks of one delivery: every anchor once, blinded, sorted once,\n * sliced by STAR_CHUNK (5010, 5050, 5200, 5220). */\nexport async function buildStarChunks (k: Uint8Array, salt: string, anchors: Iterable<string>, subtle: SubtleCrypto = platformSubtle()): Promise<StarChunk[]> {\n const blinded: string[] = []\n for (const anchor of new Set(anchors)) blinded.push(await blindAnchor(k, anchor, subtle))\n blinded.sort()\n const n = Math.max(1, Math.ceil(blinded.length / STAR_CHUNK))\n const chunks: StarChunk[] = []\n for (let i = 0; i < n; i++) {\n const body = { type: 'star@2' as const, salt, seq: String(i + 1), last: i === n - 1, blinded: blinded.slice(i * STAR_CHUNK, (i + 1) * STAR_CHUNK) }\n chunks.push({ body, proof: { mac: await macU(k, jcs(body), subtle) } })\n }\n return chunks\n}\n\n/** Is this a schema-valid star@2 chunk (visibility-star.schema.json)? */\nexport const starChunkOk = (chunk: unknown): boolean =>\n VAL.validate(chunk, SCHEMAS['visibility-star.schema.json']!, SCHEMAS['visibility-star.schema.json']!).length === 0\n\n/** Does the chunk's MAC verify under k (5080)? */\nexport async function starChunkMacOk (k: Uint8Array, chunk: StarChunk, subtle?: SubtleCrypto): Promise<boolean> {\n return (await macU(k, jcs(chunk.body), subtle)) === chunk.proof.mac\n}\n\n/** The assembled union is strictly ascending: sorted and free of\n * duplicates in one check (5300, 5310). */\nexport const strictlyAscending = (xs: readonly string[]): boolean => xs.every((x, i) => i === 0 || xs[i - 1]! < x)\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Contact, Duty, HolderState, Millis, Relationship, Setting, TrustClass, Tuple } from './state.js';
|
|
2
|
+
/** A tuple as the builder takes it: the four keys of 6.4 and the rkid;
|
|
3
|
+
* every other field may be given, else it starts empty. */
|
|
4
|
+
export type TupleSpec = Pick<Tuple, 'ownPairLabel' | 'counterpartAnchor' | 'counterpartKeyAgreement' | 'rkid'> & Partial<Tuple>;
|
|
5
|
+
/** A relationship as the builder takes it; `activeHead` defaults to the last tuple. */
|
|
6
|
+
export type RelationshipSpec = {
|
|
7
|
+
contactId: string;
|
|
8
|
+
tuples: TupleSpec[];
|
|
9
|
+
} & Partial<Omit<Relationship, 'id' | 'contactId' | 'tuples'>>;
|
|
10
|
+
export interface StateBuilder {
|
|
11
|
+
/** register.community: the personal community's genesis digest and head generation */
|
|
12
|
+
community(genesis: string, head?: string): StateBuilder;
|
|
13
|
+
/** register.lineage: the holder's own anchor-rotation@2 artifacts, chain order */
|
|
14
|
+
lineage(rotations: HolderState['register']['lineage']): StateBuilder;
|
|
15
|
+
/** a contact, created or merged (fields given replace the held ones) */
|
|
16
|
+
contact(id: string, fields?: Partial<Omit<Contact, 'id'>>): StateBuilder;
|
|
17
|
+
/** a relationship with its tuples (see the header) */
|
|
18
|
+
relationship(id: string, spec: RelationshipSpec): StateBuilder;
|
|
19
|
+
/** an entry commit for the contact at the next position (2120) */
|
|
20
|
+
entry(contactId: string, opts?: {
|
|
21
|
+
status?: 'admitted' | 'pending';
|
|
22
|
+
}): StateBuilder;
|
|
23
|
+
/** class settings toward a contact (2810) */
|
|
24
|
+
settings(contactId: string, settings: Partial<Record<TrustClass, Setting>>): StateBuilder;
|
|
25
|
+
/** an address key (Delivery §5) */
|
|
26
|
+
address(rkid: string, label: string, lastShown?: Millis): StateBuilder;
|
|
27
|
+
duty(d: Duty): StateBuilder;
|
|
28
|
+
/** the raw draft, for anything the methods do not cover */
|
|
29
|
+
with(fn: (draft: HolderState) => void): StateBuilder;
|
|
30
|
+
/** the validated state, an independent copy */
|
|
31
|
+
build(): HolderState;
|
|
32
|
+
}
|
|
33
|
+
/** A tuple with every per-tuple scope empty (6250: nothing migrates into it). */
|
|
34
|
+
export declare const emptyTuple: (spec: TupleSpec & {
|
|
35
|
+
entryId: string;
|
|
36
|
+
}) => Tuple;
|
|
37
|
+
/** A fluent builder of valid HolderStates; `at` is the time it stamps
|
|
38
|
+
* (provenance, address lastShown), default 0. */
|
|
39
|
+
export declare function stateBuilder(opts?: {
|
|
40
|
+
at?: Millis;
|
|
41
|
+
}): StateBuilder;
|
|
42
|
+
//# sourceMappingURL=state-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-builder.d.ts","sourceRoot":"","sources":["../src/state-builder.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAE9G;4DAC4D;AAC5D,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,cAAc,GAAG,mBAAmB,GAAG,yBAAyB,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;AAE/H,uFAAuF;AACvF,MAAM,MAAM,gBAAgB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAA;AAEtI,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,SAAS,CAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,CAAA;IACxD,kFAAkF;IAClF,OAAO,CAAE,SAAS,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,GAAG,YAAY,CAAA;IACrE,wEAAwE;IACxE,OAAO,CAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,YAAY,CAAA;IACzE,sDAAsD;IACtD,YAAY,CAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAAA;IAC/D,kEAAkE;IAClE,KAAK,CAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE,GAAG,YAAY,CAAA;IACnF,6CAA6C;IAC7C,QAAQ,CAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,GAAG,YAAY,CAAA;IAC1F,mCAAmC;IACnC,OAAO,CAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAAA;IACvE,IAAI,CAAE,CAAC,EAAE,IAAI,GAAG,YAAY,CAAA;IAC5B,2DAA2D;IAC3D,IAAI,CAAE,EAAE,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,YAAY,CAAA;IACrD,+CAA+C;IAC/C,KAAK,IAAK,WAAW,CAAA;CACtB;AAKD,iFAAiF;AACjF,eAAO,MAAM,UAAU,GAAI,MAAM,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,KAYjE,CAAA;AAIF;kDACkD;AAClD,wBAAgB,YAAY,CAAE,IAAI,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CA6CtE"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// state-builder — valid HolderStates for tests, vectors and adapter
|
|
2
|
+
// authors (lib Stage 2, note §4.6 ./testing). Not for production holders:
|
|
3
|
+
// a real holder's state arises from its acts.
|
|
4
|
+
//
|
|
5
|
+
// A fluent builder over plain data: anchors, key-agreement keys and labels
|
|
6
|
+
// are strings the caller derives (seedKeys(seed).anchorOf(label)), so the
|
|
7
|
+
// builder stays synchronous and key-free. build() validates the result
|
|
8
|
+
// with the codec (encodeState) and hands out an independent copy; every
|
|
9
|
+
// call before it may be chained.
|
|
10
|
+
//
|
|
11
|
+
// stateBuilder()
|
|
12
|
+
// .community(genesis, '2') register.community
|
|
13
|
+
// .lineage([rotation1to2]) register.lineage
|
|
14
|
+
// .relationship('r1', { contactId: 'c1', tuples: [{ ownPairLabel,
|
|
15
|
+
// counterpartAnchor, counterpartKeyAgreement, rkid }] })
|
|
16
|
+
// the contact (created at
|
|
17
|
+
// status 'none' if new), the
|
|
18
|
+
// tuple's label in the
|
|
19
|
+
// register, its rkid live in
|
|
20
|
+
// addresses, the active head
|
|
21
|
+
// in entryOrder.heads (2180)
|
|
22
|
+
// .entry('c1') an entry commit (2120): the
|
|
23
|
+
// next position, 'admitted'
|
|
24
|
+
// (or { status: 'pending' })
|
|
25
|
+
// .settings('c1', { anchorMapping: 'on' }) class settings (2810)
|
|
26
|
+
// .duty({ kind: 'class-on', … }) an open duty
|
|
27
|
+
// .with((s) => { … }) anything else, on the draft
|
|
28
|
+
// .build()
|
|
29
|
+
import { CODEC, encodeState } from './codec.js';
|
|
30
|
+
import { emptyState } from './state.js';
|
|
31
|
+
const seqOut = () => ({ lastSalt: '0', exhausted: false, hwm: '0', snapshot: null, snapshotDigest: null, inflight: {} });
|
|
32
|
+
const seqIn = () => ({ hwm: '0', lowerBound: '0', assembly: null, accepted: null });
|
|
33
|
+
/** A tuple with every per-tuple scope empty (6250: nothing migrates into it). */
|
|
34
|
+
export const emptyTuple = (spec) => ({
|
|
35
|
+
priorCandidates: [],
|
|
36
|
+
starOut: seqOut(), starIn: seqIn(), groupStarOut: seqOut(), groupStarIn: seqIn(),
|
|
37
|
+
probeOut: { seq: '0', inflight: {}, done: false }, probeIn: { hwm: '0', lowerBound: '0', assembly: null },
|
|
38
|
+
continuityOut: { rev: '0', body: null, proof: null, sent: [], align: false, chosen: null, reported: null, aligned: false, due: null },
|
|
39
|
+
continuityIn: { rev: '0', body: null, recordPrior: null },
|
|
40
|
+
mappingOut: { rev: '0', body: null, underAnchor: null },
|
|
41
|
+
mappingIn: { rev: '0', body: null, self: null, card: null },
|
|
42
|
+
profileOut: { rev: '0' },
|
|
43
|
+
profileIn: { rev: '0', body: null, verifiedSeq: '0' },
|
|
44
|
+
deactivated: false,
|
|
45
|
+
...spec,
|
|
46
|
+
});
|
|
47
|
+
const DEFAULTS = { star: 'default', groupStar: 'default', anchorMapping: 'default', sealedGroupStar: 'default', profile: 'default' };
|
|
48
|
+
/** A fluent builder of valid HolderStates; `at` is the time it stamps
|
|
49
|
+
* (provenance, address lastShown), default 0. */
|
|
50
|
+
export function stateBuilder(opts = {}) {
|
|
51
|
+
const at = opts.at ?? 0;
|
|
52
|
+
const s = emptyState(CODEC);
|
|
53
|
+
const contactOf = (id) => {
|
|
54
|
+
if (!Object.hasOwn(s.contacts, id)) {
|
|
55
|
+
s.contacts[id] = { id, pos: null, status: 'none', aliases: [], relIds: [], anchorHead: null, settings: { ...DEFAULTS }, groupSettings: {} };
|
|
56
|
+
}
|
|
57
|
+
return s.contacts[id];
|
|
58
|
+
};
|
|
59
|
+
const b = {
|
|
60
|
+
community(genesis, head = '1') { s.register.community = { genesis, head }; return b; },
|
|
61
|
+
lineage(rotations) { s.register.lineage = structuredClone(rotations); return b; },
|
|
62
|
+
contact(id, fields = {}) { Object.assign(contactOf(id), structuredClone(fields)); return b; },
|
|
63
|
+
relationship(id, spec) {
|
|
64
|
+
const { contactId, tuples, ...rest } = structuredClone(spec);
|
|
65
|
+
const c = contactOf(contactId);
|
|
66
|
+
if (!c.relIds.includes(id))
|
|
67
|
+
c.relIds.push(id);
|
|
68
|
+
const full = tuples.map((t) => emptyTuple({ entryId: contactId, ...t }));
|
|
69
|
+
for (const t of full) {
|
|
70
|
+
if (!s.register.labels.includes(t.ownPairLabel))
|
|
71
|
+
s.register.labels.push(t.ownPairLabel);
|
|
72
|
+
if (!Object.hasOwn(s.addresses.keys, t.rkid))
|
|
73
|
+
s.addresses.keys[t.rkid] = { label: t.ownPairLabel, lastShown: at };
|
|
74
|
+
}
|
|
75
|
+
s.relationships[id] = {
|
|
76
|
+
id, contactId, tuples: full, activeHead: full[full.length - 1].ownPairLabel,
|
|
77
|
+
earliestAnchor: null, links: [], bindings: {}, heldCounterpartHead: null, memory: {},
|
|
78
|
+
provenance: { kind: 'ceremony', at }, chainedInto: null, firstVerified: null,
|
|
79
|
+
...rest,
|
|
80
|
+
};
|
|
81
|
+
if (!s.entryOrder.heads.includes(id))
|
|
82
|
+
s.entryOrder.heads.push(id);
|
|
83
|
+
return b;
|
|
84
|
+
},
|
|
85
|
+
entry(contactId, o = {}) {
|
|
86
|
+
const c = contactOf(contactId);
|
|
87
|
+
c.pos = s.entryOrder.nextPos;
|
|
88
|
+
c.status = o.status ?? 'admitted';
|
|
89
|
+
s.entryOrder.nextPos = (BigInt(s.entryOrder.nextPos) + 1n).toString();
|
|
90
|
+
return b;
|
|
91
|
+
},
|
|
92
|
+
settings(contactId, settings) { Object.assign(contactOf(contactId).settings, settings); return b; },
|
|
93
|
+
address(rkid, label, lastShown = at) { s.addresses.keys[rkid] = { label, lastShown }; return b; },
|
|
94
|
+
duty(d) { s.duties[d.id] = structuredClone(d); return b; },
|
|
95
|
+
with(fn) { fn(s); return b; },
|
|
96
|
+
build() { return JSON.parse(encodeState(s)); },
|
|
97
|
+
};
|
|
98
|
+
return b;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=state-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-builder.js","sourceRoot":"","sources":["../src/state-builder.ts"],"names":[],"mappings":"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","sourcesContent":["// state-builder — valid HolderStates for tests, vectors and adapter\n// authors (lib Stage 2, note §4.6 ./testing). Not for production holders:\n// a real holder's state arises from its acts.\n//\n// A fluent builder over plain data: anchors, key-agreement keys and labels\n// are strings the caller derives (seedKeys(seed).anchorOf(label)), so the\n// builder stays synchronous and key-free. build() validates the result\n// with the codec (encodeState) and hands out an independent copy; every\n// call before it may be chained.\n//\n// stateBuilder()\n// .community(genesis, '2') register.community\n// .lineage([rotation1to2]) register.lineage\n// .relationship('r1', { contactId: 'c1', tuples: [{ ownPairLabel,\n// counterpartAnchor, counterpartKeyAgreement, rkid }] })\n// the contact (created at\n// status 'none' if new), the\n// tuple's label in the\n// register, its rkid live in\n// addresses, the active head\n// in entryOrder.heads (2180)\n// .entry('c1') an entry commit (2120): the\n// next position, 'admitted'\n// (or { status: 'pending' })\n// .settings('c1', { anchorMapping: 'on' }) class settings (2810)\n// .duty({ kind: 'class-on', … }) an open duty\n// .with((s) => { … }) anything else, on the draft\n// .build()\nimport { CODEC, encodeState } from './codec.js'\nimport { emptyState } from './state.js'\nimport type { Contact, Duty, HolderState, Millis, Relationship, Setting, TrustClass, Tuple } from './state.js'\n\n/** A tuple as the builder takes it: the four keys of 6.4 and the rkid;\n * every other field may be given, else it starts empty. */\nexport type TupleSpec = Pick<Tuple, 'ownPairLabel' | 'counterpartAnchor' | 'counterpartKeyAgreement' | 'rkid'> & Partial<Tuple>\n\n/** A relationship as the builder takes it; `activeHead` defaults to the last tuple. */\nexport type RelationshipSpec = { contactId: string, tuples: TupleSpec[] } & Partial<Omit<Relationship, 'id' | 'contactId' | 'tuples'>>\n\nexport interface StateBuilder {\n /** register.community: the personal community's genesis digest and head generation */\n community (genesis: string, head?: string): StateBuilder\n /** register.lineage: the holder's own anchor-rotation@2 artifacts, chain order */\n lineage (rotations: HolderState['register']['lineage']): StateBuilder\n /** a contact, created or merged (fields given replace the held ones) */\n contact (id: string, fields?: Partial<Omit<Contact, 'id'>>): StateBuilder\n /** a relationship with its tuples (see the header) */\n relationship (id: string, spec: RelationshipSpec): StateBuilder\n /** an entry commit for the contact at the next position (2120) */\n entry (contactId: string, opts?: { status?: 'admitted' | 'pending' }): StateBuilder\n /** class settings toward a contact (2810) */\n settings (contactId: string, settings: Partial<Record<TrustClass, Setting>>): StateBuilder\n /** an address key (Delivery §5) */\n address (rkid: string, label: string, lastShown?: Millis): StateBuilder\n duty (d: Duty): StateBuilder\n /** the raw draft, for anything the methods do not cover */\n with (fn: (draft: HolderState) => void): StateBuilder\n /** the validated state, an independent copy */\n build (): HolderState\n}\n\nconst seqOut = () => ({ lastSalt: '0', exhausted: false, hwm: '0', snapshot: null, snapshotDigest: null, inflight: {} })\nconst seqIn = () => ({ hwm: '0', lowerBound: '0', assembly: null, accepted: null })\n\n/** A tuple with every per-tuple scope empty (6250: nothing migrates into it). */\nexport const emptyTuple = (spec: TupleSpec & { entryId: string }): Tuple => ({\n priorCandidates: [],\n starOut: seqOut(), starIn: seqIn(), groupStarOut: seqOut(), groupStarIn: seqIn(),\n probeOut: { seq: '0', inflight: {}, done: false }, probeIn: { hwm: '0', lowerBound: '0', assembly: null },\n continuityOut: { rev: '0', body: null, proof: null, sent: [], align: false, chosen: null, reported: null, aligned: false, due: null },\n continuityIn: { rev: '0', body: null, recordPrior: null },\n mappingOut: { rev: '0', body: null, underAnchor: null },\n mappingIn: { rev: '0', body: null, self: null, card: null },\n profileOut: { rev: '0' },\n profileIn: { rev: '0', body: null, verifiedSeq: '0' },\n deactivated: false,\n ...spec,\n})\n\nconst DEFAULTS: Record<TrustClass, Setting> = { star: 'default', groupStar: 'default', anchorMapping: 'default', sealedGroupStar: 'default', profile: 'default' }\n\n/** A fluent builder of valid HolderStates; `at` is the time it stamps\n * (provenance, address lastShown), default 0. */\nexport function stateBuilder (opts: { at?: Millis } = {}): StateBuilder {\n const at = opts.at ?? 0\n const s = emptyState(CODEC)\n const contactOf = (id: string): Contact => {\n if (!Object.hasOwn(s.contacts, id)) {\n s.contacts[id] = { id, pos: null, status: 'none', aliases: [], relIds: [], anchorHead: null, settings: { ...DEFAULTS }, groupSettings: {} }\n }\n return s.contacts[id]\n }\n const b: StateBuilder = {\n community (genesis, head = '1') { s.register.community = { genesis, head }; return b },\n lineage (rotations) { s.register.lineage = structuredClone(rotations); return b },\n contact (id, fields = {}) { Object.assign(contactOf(id), structuredClone(fields)); return b },\n relationship (id, spec) {\n const { contactId, tuples, ...rest } = structuredClone(spec)\n const c = contactOf(contactId)\n if (!c.relIds.includes(id)) c.relIds.push(id)\n const full = tuples.map((t) => emptyTuple({ entryId: contactId, ...t }))\n for (const t of full) {\n if (!s.register.labels.includes(t.ownPairLabel)) s.register.labels.push(t.ownPairLabel)\n if (!Object.hasOwn(s.addresses.keys, t.rkid)) s.addresses.keys[t.rkid] = { label: t.ownPairLabel, lastShown: at }\n }\n s.relationships[id] = {\n id, contactId, tuples: full, activeHead: full[full.length - 1].ownPairLabel,\n earliestAnchor: null, links: [], bindings: {}, heldCounterpartHead: null, memory: {},\n provenance: { kind: 'ceremony', at }, chainedInto: null, firstVerified: null,\n ...rest,\n }\n if (!s.entryOrder.heads.includes(id)) s.entryOrder.heads.push(id)\n return b\n },\n entry (contactId, o = {}) {\n const c = contactOf(contactId)\n c.pos = s.entryOrder.nextPos\n c.status = o.status ?? 'admitted'\n s.entryOrder.nextPos = (BigInt(s.entryOrder.nextPos) + 1n).toString()\n return b\n },\n settings (contactId, settings) { Object.assign(contactOf(contactId).settings, settings); return b },\n address (rkid, label, lastShown = at) { s.addresses.keys[rkid] = { label, lastShown }; return b },\n duty (d) { s.duties[d.id] = structuredClone(d); return b },\n with (fn) { fn(s); return b },\n build () { return JSON.parse(encodeState(s)) as HolderState },\n }\n return b\n}\n"]}
|