keri 0.0.0-dev.bf75350 → 0.0.0-dev.e00c3c1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cesr/__main__.d.ts +10 -0
- package/dist/cesr/__main__.js +11 -0
- package/dist/cesr/__main__.js.map +1 -0
- package/dist/cesr/array-utils.d.ts +3 -0
- package/dist/cesr/array-utils.js +29 -0
- package/dist/cesr/array-utils.js.map +1 -0
- package/dist/cesr/attachments-reader.d.ts +10 -0
- package/dist/cesr/attachments-reader.js +273 -0
- package/dist/cesr/attachments-reader.js.map +1 -0
- package/dist/cesr/attachments.d.ts +68 -0
- package/dist/cesr/attachments.js +116 -0
- package/dist/cesr/attachments.js.map +1 -0
- package/dist/cesr/codec.d.ts +26 -0
- package/dist/cesr/codec.js +26 -0
- package/dist/cesr/codec.js.map +1 -0
- package/dist/cesr/codes.d.ts +1208 -0
- package/dist/cesr/codes.js +309 -0
- package/dist/cesr/codes.js.map +1 -0
- package/dist/cesr/counter.d.ts +117 -0
- package/dist/cesr/counter.js +93 -0
- package/dist/cesr/counter.js.map +1 -0
- package/dist/cesr/frame.d.ts +36 -0
- package/dist/cesr/frame.js +97 -0
- package/dist/cesr/frame.js.map +1 -0
- package/dist/cesr/genus.d.ts +21 -0
- package/dist/cesr/genus.js +66 -0
- package/dist/cesr/genus.js.map +1 -0
- package/dist/cesr/groups/generic-map.d.ts +11 -0
- package/dist/cesr/groups/generic-map.js +59 -0
- package/dist/cesr/groups/generic-map.js.map +1 -0
- package/dist/cesr/indexer.d.ts +70 -0
- package/dist/cesr/indexer.js +177 -0
- package/dist/cesr/indexer.js.map +1 -0
- package/dist/cesr/matter.d.ts +163 -0
- package/dist/cesr/matter.js +311 -0
- package/dist/cesr/matter.js.map +1 -0
- package/dist/cesr/message.d.ts +17 -0
- package/dist/cesr/message.js +81 -0
- package/dist/cesr/message.js.map +1 -0
- package/dist/cesr/parse.d.ts +37 -0
- package/dist/cesr/parse.js +137 -0
- package/dist/cesr/parse.js.map +1 -0
- package/dist/cesr/shifting.d.ts +7 -0
- package/dist/cesr/shifting.js +10 -0
- package/dist/cesr/shifting.js.map +1 -0
- package/dist/cesr/version-string.d.ts +35 -0
- package/dist/cesr/version-string.js +147 -0
- package/dist/cesr/version-string.js.map +1 -0
- package/dist/cli/cli.d.ts +5 -0
- package/dist/cli/cli.js +73 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/input.d.ts +1 -0
- package/dist/cli/input.js +22 -0
- package/dist/cli/input.js.map +1 -0
- package/dist/cli/node-cli.d.ts +2 -0
- package/dist/cli/node-cli.js +19 -0
- package/dist/cli/node-cli.js.map +1 -0
- package/dist/controller/controller.d.ts +101 -0
- package/dist/controller/controller.js +549 -0
- package/dist/controller/controller.js.map +1 -0
- package/dist/controller/encrypt.d.ts +45 -0
- package/dist/controller/encrypt.js +120 -0
- package/dist/controller/encrypt.js.map +1 -0
- package/dist/core/credential-event.d.ts +54 -0
- package/dist/core/credential-event.js +28 -0
- package/dist/core/credential-event.js.map +1 -0
- package/dist/core/credential.d.ts +79 -0
- package/dist/core/credential.js +25 -0
- package/dist/core/credential.js.map +1 -0
- package/dist/core/digest.d.ts +1 -0
- package/dist/core/digest.js +7 -0
- package/dist/core/digest.js.map +1 -0
- package/dist/core/endpoint-discovery.d.ts +20 -0
- package/dist/core/endpoint-discovery.js +60 -0
- package/dist/core/endpoint-discovery.js.map +1 -0
- package/dist/core/events.d.ts +12 -0
- package/dist/core/events.js +25 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/kawa.d.ts +17 -0
- package/dist/core/kawa.js +87 -0
- package/dist/core/kawa.js.map +1 -0
- package/dist/core/key-event-log.d.ts +13 -0
- package/dist/core/key-event-log.js +153 -0
- package/dist/core/key-event-log.js.map +1 -0
- package/dist/core/key-event.d.ts +94 -0
- package/dist/core/key-event.js +88 -0
- package/dist/core/key-event.js.map +1 -0
- package/dist/core/keys.d.ts +9 -0
- package/dist/core/keys.js +17 -0
- package/dist/core/keys.js.map +1 -0
- package/dist/core/mailbox-client.d.ts +23 -0
- package/dist/core/mailbox-client.js +59 -0
- package/dist/core/mailbox-client.js.map +1 -0
- package/dist/core/main.d.ts +51 -0
- package/dist/core/main.js +43 -0
- package/dist/core/main.js.map +1 -0
- package/dist/core/receipt-event.d.ts +15 -0
- package/dist/core/receipt-event.js +13 -0
- package/dist/core/receipt-event.js.map +1 -0
- package/dist/core/registry-event.d.ts +26 -0
- package/dist/core/registry-event.js +18 -0
- package/dist/core/registry-event.js.map +1 -0
- package/dist/core/routed-event.d.ts +67 -0
- package/dist/core/routed-event.js +53 -0
- package/dist/core/routed-event.js.map +1 -0
- package/dist/core/said.d.ts +4 -0
- package/dist/core/said.js +26 -0
- package/dist/core/said.js.map +1 -0
- package/dist/core/sign.d.ts +5 -0
- package/dist/core/sign.js +10 -0
- package/dist/core/sign.js.map +1 -0
- package/dist/core/threshold.d.ts +6 -0
- package/dist/core/threshold.js +58 -0
- package/dist/core/threshold.js.map +1 -0
- package/dist/core/verify.d.ts +15 -0
- package/dist/core/verify.js +43 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/encoding/base64.d.ts +4 -0
- package/dist/encoding/base64.js +82 -0
- package/dist/encoding/base64.js.map +1 -0
- package/dist/encoding/utf8.d.ts +2 -0
- package/dist/encoding/utf8.js +9 -0
- package/dist/encoding/utf8.js.map +1 -0
- package/dist/main.d.ts +3 -6
- package/dist/main.js +3 -6
- package/dist/main.js.map +1 -1
- package/dist/nodejs-utils/serve.d.ts +5 -0
- package/dist/nodejs-utils/serve.js +77 -0
- package/dist/nodejs-utils/serve.js.map +1 -0
- package/dist/storage/credential-storage.d.ts +8 -0
- package/dist/storage/credential-storage.js +2 -0
- package/dist/storage/credential-storage.js.map +1 -0
- package/dist/storage/key-event-storage.d.ts +10 -0
- package/dist/storage/key-event-storage.js +2 -0
- package/dist/storage/key-event-storage.js.map +1 -0
- package/dist/storage/mailbox-storage.d.ts +4 -0
- package/dist/storage/mailbox-storage.js +2 -0
- package/dist/storage/mailbox-storage.js.map +1 -0
- package/dist/storage/private-key-storage.d.ts +5 -0
- package/dist/storage/private-key-storage.js +2 -0
- package/dist/storage/private-key-storage.js.map +1 -0
- package/dist/storage/sqlite/node-sqlite.d.ts +12 -0
- package/dist/storage/sqlite/node-sqlite.js +25 -0
- package/dist/storage/sqlite/node-sqlite.js.map +1 -0
- package/dist/storage/sqlite/schema.d.ts +2 -0
- package/dist/storage/sqlite/schema.js +55 -0
- package/dist/storage/sqlite/schema.js.map +1 -0
- package/dist/storage/sqlite/sqlite-database.d.ts +13 -0
- package/dist/storage/sqlite/sqlite-database.js +2 -0
- package/dist/storage/sqlite/sqlite-database.js.map +1 -0
- package/dist/storage/sqlite/storage-sqlite.d.ts +29 -0
- package/dist/storage/sqlite/storage-sqlite.js +213 -0
- package/dist/storage/sqlite/storage-sqlite.js.map +1 -0
- package/dist/witness/main.d.ts +2 -0
- package/dist/witness/main.js +3 -0
- package/dist/witness/main.js.map +1 -0
- package/dist/witness/parser.d.ts +3 -0
- package/dist/witness/parser.js +7 -0
- package/dist/witness/parser.js.map +1 -0
- package/dist/witness/seed.d.ts +1 -0
- package/dist/witness/seed.js +5 -0
- package/dist/witness/seed.js.map +1 -0
- package/dist/witness/witness-router.d.ts +2 -0
- package/dist/witness/witness-router.js +90 -0
- package/dist/witness/witness-router.js.map +1 -0
- package/dist/witness/witness.d.ts +23 -0
- package/dist/witness/witness.js +92 -0
- package/dist/witness/witness.js.map +1 -0
- package/package.json +36 -23
- package/dist/cli/main.d.ts +0 -2
- package/dist/cli/main.js +0 -177
- package/dist/cli/main.js.map +0 -1
- package/dist/client.d.ts +0 -21
- package/dist/client.js +0 -72
- package/dist/client.js.map +0 -1
- package/dist/controller.d.ts +0 -65
- package/dist/controller.js +0 -475
- package/dist/controller.js.map +0 -1
- package/dist/data-type.d.ts +0 -9
- package/dist/data-type.js +0 -2
- package/dist/data-type.js.map +0 -1
- package/dist/db/storage-sqlite.d.ts +0 -12
- package/dist/db/storage-sqlite.js +0 -57
- package/dist/db/storage-sqlite.js.map +0 -1
- package/dist/db/storage.d.ts +0 -18
- package/dist/db/storage.js +0 -37
- package/dist/db/storage.js.map +0 -1
- package/dist/events/event-store.d.ts +0 -133
- package/dist/events/event-store.js +0 -215
- package/dist/events/event-store.js.map +0 -1
- package/dist/events/events.d.ts +0 -251
- package/dist/events/events.js +0 -184
- package/dist/events/events.js.map +0 -1
- package/dist/keystore/encrypt.d.ts +0 -10
- package/dist/keystore/encrypt.js +0 -39
- package/dist/keystore/encrypt.js.map +0 -1
- package/dist/keystore/keystore.d.ts +0 -29
- package/dist/keystore/keystore.js +0 -72
- package/dist/keystore/keystore.js.map +0 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const PREFIX = new TextEncoder().encode("KJS1");
|
|
2
|
+
const SALT_LENGTH = 16;
|
|
3
|
+
const IV_LENGTH = 12;
|
|
4
|
+
const AUTH_TAG_LENGTH = 16;
|
|
5
|
+
const PBKDF2_ITERATIONS = 310000;
|
|
6
|
+
async function deriveKey(passphrase, salt) {
|
|
7
|
+
const encoder = new TextEncoder();
|
|
8
|
+
const encryptionKey = await crypto.subtle.importKey("raw", encoder.encode(passphrase), "PBKDF2", false, [
|
|
9
|
+
"deriveBits",
|
|
10
|
+
"deriveKey",
|
|
11
|
+
]);
|
|
12
|
+
const key = await crypto.subtle.deriveKey({
|
|
13
|
+
name: "PBKDF2",
|
|
14
|
+
salt: Uint8Array.from(salt),
|
|
15
|
+
iterations: PBKDF2_ITERATIONS,
|
|
16
|
+
hash: "SHA-256",
|
|
17
|
+
}, encryptionKey, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
|
|
18
|
+
return key;
|
|
19
|
+
}
|
|
20
|
+
function hasV1Prefix(ciphertext) {
|
|
21
|
+
if (ciphertext.length < PREFIX.length) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
for (let i = 0; i < PREFIX.length; i++) {
|
|
25
|
+
if (ciphertext[i] !== PREFIX[i]) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function parseCiphertext(ciphertext) {
|
|
32
|
+
if (!hasV1Prefix(ciphertext)) {
|
|
33
|
+
throw new Error("Invalid encrypted payload");
|
|
34
|
+
}
|
|
35
|
+
const headerLength = PREFIX.length + SALT_LENGTH + IV_LENGTH;
|
|
36
|
+
if (ciphertext.length < headerLength + AUTH_TAG_LENGTH) {
|
|
37
|
+
throw new Error("Invalid encrypted payload");
|
|
38
|
+
}
|
|
39
|
+
const saltStart = PREFIX.length;
|
|
40
|
+
const ivStart = saltStart + SALT_LENGTH;
|
|
41
|
+
const encryptedStart = ivStart + IV_LENGTH;
|
|
42
|
+
return {
|
|
43
|
+
salt: ciphertext.slice(saltStart, ivStart),
|
|
44
|
+
iv: ciphertext.slice(ivStart, encryptedStart),
|
|
45
|
+
encrypted: ciphertext.slice(encryptedStart),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function encrypt(data, passphrase) {
|
|
49
|
+
const salt = crypto.getRandomValues(new Uint8Array(SALT_LENGTH));
|
|
50
|
+
const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
|
|
51
|
+
const key = await deriveKey(passphrase, salt);
|
|
52
|
+
const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, Uint8Array.from(data));
|
|
53
|
+
const result = new Uint8Array(PREFIX.length + salt.byteLength + iv.byteLength + encrypted.byteLength);
|
|
54
|
+
result.set(PREFIX, 0);
|
|
55
|
+
result.set(salt, PREFIX.length);
|
|
56
|
+
result.set(iv, PREFIX.length + salt.byteLength);
|
|
57
|
+
result.set(new Uint8Array(encrypted), PREFIX.length + salt.byteLength + iv.byteLength);
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
async function decrypt(ciphertext, passphrase) {
|
|
61
|
+
const { salt, iv, encrypted } = parseCiphertext(ciphertext);
|
|
62
|
+
const key = await deriveKey(passphrase, salt);
|
|
63
|
+
try {
|
|
64
|
+
const result = await crypto.subtle.decrypt({ name: "AES-GCM", iv: new Uint8Array(iv) }, key, new Uint8Array(encrypted));
|
|
65
|
+
return new Uint8Array(result);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
throw new Error("Could not decrypt data", {
|
|
69
|
+
cause: err,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* TODO
|
|
75
|
+
*
|
|
76
|
+
* This implementation is intentionally minimal for MVP.
|
|
77
|
+
* It uses PBKDF2 (SHA-256, 310k iterations) + AES-256-GCM with
|
|
78
|
+
* random salt and IV. This is secure by modern standards, but
|
|
79
|
+
* not fully hardened.
|
|
80
|
+
*
|
|
81
|
+
* Planned improvements for next format version (e.g. "KJS2"):
|
|
82
|
+
*
|
|
83
|
+
* 1. KDF Upgrade
|
|
84
|
+
* - Replace PBKDF2 with Argon2id (memory-hard).
|
|
85
|
+
* - Alternatively support multiple KDFs via encoded KDF identifier.
|
|
86
|
+
*
|
|
87
|
+
* 2. Encode KDF Parameters
|
|
88
|
+
* - Store iteration count (and memory parameters if Argon2)
|
|
89
|
+
* inside ciphertext header for forward compatibility.
|
|
90
|
+
*
|
|
91
|
+
* 3. Header Authentication (AAD)
|
|
92
|
+
* - Include prefix + salt + IV as AES-GCM additional authenticated data
|
|
93
|
+
* to cryptographically bind structure.
|
|
94
|
+
*
|
|
95
|
+
* 4. Passphrase Handling
|
|
96
|
+
* - Avoid long-term caching of passphrase strings in memory.
|
|
97
|
+
* - Prefer short-lived Uint8Array or derived CryptoKey storage.
|
|
98
|
+
*
|
|
99
|
+
* 5. Key Separation (if expanded usage)
|
|
100
|
+
* - Derive distinct keys for encryption / MAC / wrapping
|
|
101
|
+
* using HKDF if additional primitives are added.
|
|
102
|
+
*
|
|
103
|
+
* IMPORTANT:
|
|
104
|
+
* Never change behavior under the "KJS1" prefix.
|
|
105
|
+
* All security upgrades must use a new version prefix
|
|
106
|
+
* to preserve backward compatibility.
|
|
107
|
+
*/
|
|
108
|
+
export class PassphraseEncrypter {
|
|
109
|
+
#passphrase;
|
|
110
|
+
constructor(passphrase) {
|
|
111
|
+
this.#passphrase = passphrase;
|
|
112
|
+
}
|
|
113
|
+
async encrypt(data) {
|
|
114
|
+
return await encrypt(data, this.#passphrase);
|
|
115
|
+
}
|
|
116
|
+
async decrypt(ciphertext) {
|
|
117
|
+
return await decrypt(ciphertext, this.#passphrase);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=encrypt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encrypt.js","sourceRoot":"","sources":["../../src/controller/encrypt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Message } from "../cesr/__main__.ts";
|
|
2
|
+
export interface IssueEventInit {
|
|
3
|
+
/**
|
|
4
|
+
* Credential SAID
|
|
5
|
+
*/
|
|
6
|
+
i: string;
|
|
7
|
+
/**
|
|
8
|
+
* Registry SAID
|
|
9
|
+
*/
|
|
10
|
+
ri: string;
|
|
11
|
+
dt?: string;
|
|
12
|
+
}
|
|
13
|
+
export type IssueEventBody = {
|
|
14
|
+
v: string;
|
|
15
|
+
t: "iss";
|
|
16
|
+
d: string;
|
|
17
|
+
/**
|
|
18
|
+
* Credential SAID
|
|
19
|
+
*/
|
|
20
|
+
i: string;
|
|
21
|
+
s: string;
|
|
22
|
+
/**
|
|
23
|
+
* Registry SAID
|
|
24
|
+
*/
|
|
25
|
+
ri: string;
|
|
26
|
+
dt: string;
|
|
27
|
+
};
|
|
28
|
+
export interface RevokeEventInit {
|
|
29
|
+
/**
|
|
30
|
+
* Credential SAID
|
|
31
|
+
*/
|
|
32
|
+
i: string;
|
|
33
|
+
/**
|
|
34
|
+
* Registry SAID
|
|
35
|
+
*/
|
|
36
|
+
ri: string;
|
|
37
|
+
/**
|
|
38
|
+
* Issuance event SAID
|
|
39
|
+
*/
|
|
40
|
+
p: string;
|
|
41
|
+
dt?: string;
|
|
42
|
+
}
|
|
43
|
+
export type RevokeEventBody = {
|
|
44
|
+
v: string;
|
|
45
|
+
t: "rev";
|
|
46
|
+
d: string;
|
|
47
|
+
i: string;
|
|
48
|
+
s: string;
|
|
49
|
+
ri: string;
|
|
50
|
+
p: string;
|
|
51
|
+
dt: string;
|
|
52
|
+
};
|
|
53
|
+
export declare function issue(args: IssueEventInit): Message<IssueEventBody>;
|
|
54
|
+
export declare function revoke(args: RevokeEventInit): Message<RevokeEventBody>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Message } from "../cesr/__main__.js";
|
|
2
|
+
import { DUMMY_VERSION, encodeEvent, formatDate } from "./events.js";
|
|
3
|
+
export function issue(args) {
|
|
4
|
+
const body = encodeEvent({
|
|
5
|
+
v: DUMMY_VERSION,
|
|
6
|
+
t: "iss",
|
|
7
|
+
d: "",
|
|
8
|
+
i: args.i,
|
|
9
|
+
s: "0",
|
|
10
|
+
ri: args.ri,
|
|
11
|
+
dt: args.dt ?? formatDate(new Date()),
|
|
12
|
+
}, { labels: ["d"] });
|
|
13
|
+
return new Message(body);
|
|
14
|
+
}
|
|
15
|
+
export function revoke(args) {
|
|
16
|
+
const body = encodeEvent({
|
|
17
|
+
v: DUMMY_VERSION,
|
|
18
|
+
t: "rev",
|
|
19
|
+
d: "",
|
|
20
|
+
i: args.i,
|
|
21
|
+
s: "1",
|
|
22
|
+
ri: args.ri,
|
|
23
|
+
p: args.p,
|
|
24
|
+
dt: args.dt ?? formatDate(new Date()),
|
|
25
|
+
}, { labels: ["d"] });
|
|
26
|
+
return new Message(body);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=credential-event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-event.js","sourceRoot":"","sources":["../../src/core/credential-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA8DrE,MAAM,UAAU,KAAK,CAAC,IAAoB;IACxC,MAAM,IAAI,GAAG,WAAW,CACtB;QACE,CAAC,EAAE,aAAa;QAChB,CAAC,EAAE,KAAK;QACR,CAAC,EAAE,EAAE;QACL,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,CAAC,EAAE,GAAG;QACN,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;KACtC,EACD,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAClB,CAAC;IAEF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAqB;IAC1C,MAAM,IAAI,GAAG,WAAW,CACtB;QACE,CAAC,EAAE,aAAa;QAChB,CAAC,EAAE,KAAK;QACR,CAAC,EAAE,EAAE;QACL,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,CAAC,EAAE,GAAG;QACN,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;KACtC,EACD,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAClB,CAAC;IAEF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Message } from "../cesr/__main__.ts";
|
|
2
|
+
export interface CredentialBodyInit {
|
|
3
|
+
/**
|
|
4
|
+
* Salty nonce
|
|
5
|
+
*/
|
|
6
|
+
u?: string;
|
|
7
|
+
i: string;
|
|
8
|
+
ri: string;
|
|
9
|
+
s: string;
|
|
10
|
+
a: {
|
|
11
|
+
i?: string;
|
|
12
|
+
dt?: string;
|
|
13
|
+
[key: string]: string | Record<string, unknown> | undefined;
|
|
14
|
+
};
|
|
15
|
+
r?: Record<string, unknown>;
|
|
16
|
+
e?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface CredentialSubject {
|
|
19
|
+
/**
|
|
20
|
+
* Subject SAID
|
|
21
|
+
*/
|
|
22
|
+
d: string;
|
|
23
|
+
/**
|
|
24
|
+
* Issuee AID
|
|
25
|
+
*/
|
|
26
|
+
i?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Issuance timestamp
|
|
29
|
+
*/
|
|
30
|
+
dt?: string;
|
|
31
|
+
[key: string]: string | undefined;
|
|
32
|
+
}
|
|
33
|
+
export interface CredentialRules {
|
|
34
|
+
/**
|
|
35
|
+
* Rules SAID
|
|
36
|
+
*/
|
|
37
|
+
d: string;
|
|
38
|
+
[key: string]: string | Record<string, unknown> | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface CredentialEdges {
|
|
41
|
+
/**
|
|
42
|
+
* Rules SAID
|
|
43
|
+
*/
|
|
44
|
+
d: string;
|
|
45
|
+
[key: string]: string | Record<string, unknown> | undefined;
|
|
46
|
+
}
|
|
47
|
+
export type CredentialBody = {
|
|
48
|
+
v: string;
|
|
49
|
+
/**
|
|
50
|
+
* Credential SAID
|
|
51
|
+
*/
|
|
52
|
+
d: string;
|
|
53
|
+
/**
|
|
54
|
+
* Issuer AID
|
|
55
|
+
*/
|
|
56
|
+
i: string;
|
|
57
|
+
/**
|
|
58
|
+
* Registry AID
|
|
59
|
+
*/
|
|
60
|
+
ri: string;
|
|
61
|
+
/**
|
|
62
|
+
* Schema SAID
|
|
63
|
+
*/
|
|
64
|
+
s: string;
|
|
65
|
+
/**
|
|
66
|
+
* Credential subject (claims)
|
|
67
|
+
*/
|
|
68
|
+
a: CredentialSubject;
|
|
69
|
+
/**
|
|
70
|
+
* Credential rules
|
|
71
|
+
*/
|
|
72
|
+
r: CredentialRules;
|
|
73
|
+
/**
|
|
74
|
+
* Credential edges
|
|
75
|
+
*/
|
|
76
|
+
e?: CredentialEdges;
|
|
77
|
+
};
|
|
78
|
+
export type Credential = Message<CredentialBody>;
|
|
79
|
+
export declare function createCredential(data: CredentialBodyInit): Credential;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Message, VersionString } from "../cesr/__main__.js";
|
|
2
|
+
import { encodeEvent } from "./events.js";
|
|
3
|
+
import { saidify } from "./said.js";
|
|
4
|
+
export function createCredential(data) {
|
|
5
|
+
const body = encodeEvent({
|
|
6
|
+
v: VersionString.encode({
|
|
7
|
+
protocol: "ACDC",
|
|
8
|
+
kind: "JSON",
|
|
9
|
+
legacy: true,
|
|
10
|
+
}),
|
|
11
|
+
d: "#".repeat(44),
|
|
12
|
+
...(data.u && { u: data.u }),
|
|
13
|
+
i: data.i,
|
|
14
|
+
ri: data.ri,
|
|
15
|
+
s: data.s,
|
|
16
|
+
a: saidify({
|
|
17
|
+
d: "#".repeat(44),
|
|
18
|
+
...data.a,
|
|
19
|
+
}, ["d"]),
|
|
20
|
+
...(data.e && { e: saidify({ d: "#".repeat(44), ...data.e }, ["d"]) }),
|
|
21
|
+
r: saidify({ d: "#".repeat(44), ...data.r }, ["d"]),
|
|
22
|
+
});
|
|
23
|
+
return new Message(body);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=credential.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../../src/core/credential.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgGpC,MAAM,UAAU,gBAAgB,CAAC,IAAwB;IACvD,MAAM,IAAI,GAAG,WAAW,CAAiB;QACvC,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC;YACtB,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,IAAI;SACb,CAAC;QACF,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACjB,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5B,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,CAAC,EAAE,OAAO,CACR;YACE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACjB,GAAG,IAAI,CAAC,CAAC;SACV,EACD,CAAC,GAAG,CAAC,CACN;QACD,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACtE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;KACpD,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAiB,IAAI,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function digest(input: string): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { blake3 } from "@noble/hashes/blake3.js";
|
|
2
|
+
import { cesr } from "../cesr/__main__.js";
|
|
3
|
+
export function digest(input) {
|
|
4
|
+
const digest = cesr.crypto.blake3_256(blake3.create({ dkLen: 32 }).update(new TextEncoder().encode(input)).digest());
|
|
5
|
+
return digest.text();
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/core/digest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACrH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Message } from "../cesr/__main__.ts";
|
|
2
|
+
import type { ReplyEventBody } from "./routed-event.ts";
|
|
3
|
+
export interface EndRoleRecord extends Record<string, unknown> {
|
|
4
|
+
cid: string;
|
|
5
|
+
role: string;
|
|
6
|
+
eid: string;
|
|
7
|
+
}
|
|
8
|
+
export interface LocationRecord extends Record<string, unknown> {
|
|
9
|
+
eid: string;
|
|
10
|
+
scheme: string;
|
|
11
|
+
url: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Endpoint {
|
|
14
|
+
aid: string;
|
|
15
|
+
url: string;
|
|
16
|
+
scheme: string;
|
|
17
|
+
role: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function resolveEndRole(replies: Iterable<Message<ReplyEventBody>>, cid: string, role: string): EndRoleRecord | null;
|
|
20
|
+
export declare function resolveLocation(replies: Iterable<Message<ReplyEventBody>>, eid: string): LocationRecord | null;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export function resolveEndRole(replies, cid, role) {
|
|
2
|
+
// TODO: Needs verify against a Key Event Log
|
|
3
|
+
// TODO: Needs to handle /end/role/cut
|
|
4
|
+
let selected = null;
|
|
5
|
+
for (const message of replies) {
|
|
6
|
+
if (message.body.t !== "rpy" || message.body.r !== "/end/role/add") {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
const record = message.body.a;
|
|
10
|
+
if (typeof record !== "object" ||
|
|
11
|
+
record === null ||
|
|
12
|
+
!("eid" in record) ||
|
|
13
|
+
typeof record.eid !== "string" ||
|
|
14
|
+
!("cid" in record) ||
|
|
15
|
+
typeof record.cid !== "string" ||
|
|
16
|
+
!("role" in record) ||
|
|
17
|
+
typeof record.role !== "string") {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (record.cid === cid && record.role === role) {
|
|
21
|
+
selected = {
|
|
22
|
+
cid: record.cid,
|
|
23
|
+
role: record.role,
|
|
24
|
+
eid: record.eid,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return selected;
|
|
29
|
+
}
|
|
30
|
+
export function resolveLocation(replies, eid) {
|
|
31
|
+
// TODO: Needs verify against a Key Event Log
|
|
32
|
+
for (const message of replies) {
|
|
33
|
+
if (message.body.t !== "rpy" || message.body.r !== "/loc/scheme") {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const record = message.body.a;
|
|
37
|
+
if (typeof record !== "object" ||
|
|
38
|
+
record === null ||
|
|
39
|
+
!("eid" in record) ||
|
|
40
|
+
typeof record.eid !== "string" ||
|
|
41
|
+
!("scheme" in record) ||
|
|
42
|
+
typeof record.scheme !== "string" ||
|
|
43
|
+
!("url" in record) ||
|
|
44
|
+
typeof record.url !== "string") {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (!["http", "https"].includes(record.scheme)) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (record.eid === eid) {
|
|
51
|
+
return {
|
|
52
|
+
eid: record.eid,
|
|
53
|
+
scheme: record.scheme,
|
|
54
|
+
url: record.url,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=endpoint-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-discovery.js","sourceRoot":"","sources":["../../src/core/endpoint-discovery.ts"],"names":[],"mappings":"AAsBA,MAAM,UAAU,cAAc,CAC5B,OAA0C,EAC1C,GAAW,EACX,IAAY;IAEZ,6CAA6C;IAC7C,sCAAsC;IACtC,IAAI,QAAQ,GAAyB,IAAI,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,eAAe,EAAE,CAAC;YACnE,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAE9B,IACE,OAAO,MAAM,KAAK,QAAQ;YAC1B,MAAM,KAAK,IAAI;YACf,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC;YAClB,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;YAC9B,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC;YAClB,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;YAC9B,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC;YACnB,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAC/B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC/C,QAAQ,GAAG;gBACT,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,EAAE,MAAM,CAAC,GAAG;aAChB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAA0C,EAAE,GAAW;IACrF,6CAA6C;IAC7C,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC;YACjE,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAE9B,IACE,OAAO,MAAM,KAAK,QAAQ;YAC1B,MAAM,KAAK,IAAI;YACf,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC;YAClB,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;YAC9B,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC;YACrB,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;YACjC,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC;YAClB,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,EAC9B,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/C,SAAS;QACX,CAAC;QAED,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACvB,OAAO;gBACL,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,GAAG,EAAE,MAAM,CAAC,GAAG;aAChB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const DUMMY_VERSION: string;
|
|
2
|
+
export declare function formatDate(date: Date): string;
|
|
3
|
+
export declare function randomNonce(): string;
|
|
4
|
+
interface EncodeEventArgs {
|
|
5
|
+
labels?: string[];
|
|
6
|
+
protocol?: string;
|
|
7
|
+
legacy?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function encodeEvent<T extends Record<string, unknown>>(data: T, args?: EncodeEventArgs): T & {
|
|
10
|
+
v: string;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Matter, Message, VersionString } from "../cesr/__main__.js";
|
|
2
|
+
import { saidify } from "./said.js";
|
|
3
|
+
export const DUMMY_VERSION = VersionString.encode({ protocol: "KERI", legacy: true, kind: "JSON" });
|
|
4
|
+
export function formatDate(date) {
|
|
5
|
+
return date.toISOString().replace("Z", "000+00:00");
|
|
6
|
+
}
|
|
7
|
+
export function randomNonce() {
|
|
8
|
+
return Matter.from(Matter.Code.Salt_128, crypto.getRandomValues(new Uint8Array(16))).text();
|
|
9
|
+
}
|
|
10
|
+
export function encodeEvent(data, args = {}) {
|
|
11
|
+
const labels = args.labels ?? ["d"];
|
|
12
|
+
for (const label of labels) {
|
|
13
|
+
if (!(label in data)) {
|
|
14
|
+
throw new Error(`Input missing label '${label}'`);
|
|
15
|
+
}
|
|
16
|
+
data[label] = "#".repeat(44);
|
|
17
|
+
}
|
|
18
|
+
const message = new Message({
|
|
19
|
+
v: VersionString.encode({ protocol: args.protocol ?? "KERI", legacy: args.legacy ?? true, kind: "JSON" }),
|
|
20
|
+
...data,
|
|
21
|
+
});
|
|
22
|
+
const result = saidify(message.body, labels);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/core/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAEpG,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9F,CAAC;AAQD,MAAM,UAAU,WAAW,CAAoC,IAAO,EAAE,OAAwB,EAAE;IAChG,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,GAAG,CAAC,CAAC;QACpD,CAAC;QAEA,IAAgC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;QAC1B,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACzG,GAAG,IAAI;KACR,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Message } from "../cesr/__main__.ts";
|
|
2
|
+
import type { KeyEventBody } from "./key-event.ts";
|
|
3
|
+
export interface WitnessEndpoint {
|
|
4
|
+
aid: string;
|
|
5
|
+
url: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* KERI Algorithm for Witness Agreement (KAWA).
|
|
9
|
+
*
|
|
10
|
+
* Collects receipts from all witnesses, then distributes those receipts back
|
|
11
|
+
* to all witnesses. The event must already have controller signatures attached.
|
|
12
|
+
*
|
|
13
|
+
* @param event Pre-signed key event (ControllerIdxSigs already on attachments)
|
|
14
|
+
* @param endpoints Pre-resolved endpoints for each witness
|
|
15
|
+
* @returns Indexed witness signatures (wigs)
|
|
16
|
+
*/
|
|
17
|
+
export declare function submitToWitnesses(event: Message<KeyEventBody>, endpoints: WitnessEndpoint[], fetch?: typeof globalThis.fetch): Promise<string[]>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { cesr, Indexer, Matter, Message, parse } from "../cesr/__main__.js";
|
|
2
|
+
import { MailboxClient } from "./mailbox-client.js";
|
|
3
|
+
import { verifyOrThrow } from "./verify.js";
|
|
4
|
+
class WitnessClient {
|
|
5
|
+
#url;
|
|
6
|
+
#fetch;
|
|
7
|
+
constructor(url, fetch) {
|
|
8
|
+
this.#url = url;
|
|
9
|
+
this.#fetch = fetch ?? globalThis.fetch;
|
|
10
|
+
}
|
|
11
|
+
async receipt(event) {
|
|
12
|
+
const url = new URL("/receipts", this.#url);
|
|
13
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
14
|
+
throw new Error(`Invalid protocol: ${url}`);
|
|
15
|
+
}
|
|
16
|
+
const fetchResponse = await this.#fetch(url, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
body: JSON.stringify(event.body),
|
|
19
|
+
headers: {
|
|
20
|
+
"Content-Type": "application/cesr+json",
|
|
21
|
+
"CESR-ATTACHMENT": event.attachments.text(),
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
if (!fetchResponse.ok || !fetchResponse.body) {
|
|
25
|
+
throw new Error(`Failed to submit event to witness: ${fetchResponse.status} ${fetchResponse.statusText}`);
|
|
26
|
+
}
|
|
27
|
+
for await (const incoming of parse(fetchResponse.body)) {
|
|
28
|
+
if (incoming.body.t === "rct" && incoming.body.d === event.body.d) {
|
|
29
|
+
for (const couple of incoming.attachments.NonTransReceiptCouples) {
|
|
30
|
+
const sig = Indexer.convert(Matter.parse(couple.sig), 0).text();
|
|
31
|
+
verifyOrThrow(event.raw, {
|
|
32
|
+
keys: [couple.prefix],
|
|
33
|
+
sigs: [sig],
|
|
34
|
+
threshold: "1",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return incoming;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`No receipt returned from ${this.#url}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* KERI Algorithm for Witness Agreement (KAWA).
|
|
45
|
+
*
|
|
46
|
+
* Collects receipts from all witnesses, then distributes those receipts back
|
|
47
|
+
* to all witnesses. The event must already have controller signatures attached.
|
|
48
|
+
*
|
|
49
|
+
* @param event Pre-signed key event (ControllerIdxSigs already on attachments)
|
|
50
|
+
* @param endpoints Pre-resolved endpoints for each witness
|
|
51
|
+
* @returns Indexed witness signatures (wigs)
|
|
52
|
+
*/
|
|
53
|
+
export async function submitToWitnesses(event, endpoints, fetch) {
|
|
54
|
+
// TODO: implement the spec's round-robin approach where receipts collected from
|
|
55
|
+
// earlier witnesses are forwarded to later ones in the same pass, reducing total
|
|
56
|
+
// network exchanges from N+(N×(N-1)) to at most 2×N.
|
|
57
|
+
const receipts = {};
|
|
58
|
+
const wigs = new Set();
|
|
59
|
+
const wits = endpoints.map((e) => e.aid);
|
|
60
|
+
for (const endpoint of endpoints) {
|
|
61
|
+
const client = new WitnessClient(endpoint.url, fetch);
|
|
62
|
+
const response = await client.receipt(event);
|
|
63
|
+
if (response.attachments.NonTransReceiptCouples.length > 0) {
|
|
64
|
+
const receiptCouple = response.attachments.NonTransReceiptCouples[0];
|
|
65
|
+
const witnessIndex = wits.indexOf(receiptCouple.prefix);
|
|
66
|
+
if (witnessIndex !== -1) {
|
|
67
|
+
const signature = Matter.parse(receiptCouple.sig);
|
|
68
|
+
wigs.add(cesr.index(signature, witnessIndex).text());
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
receipts[endpoint.aid] = response;
|
|
72
|
+
}
|
|
73
|
+
for (const endpoint of endpoints) {
|
|
74
|
+
const client = new MailboxClient({ id: endpoint.aid, url: endpoint.url, fetch });
|
|
75
|
+
for (const [other, receipt] of Object.entries(receipts)) {
|
|
76
|
+
if (other === endpoint.aid) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const message = new Message(receipt.body, {
|
|
80
|
+
NonTransReceiptCouples: receipt.attachments.NonTransReceiptCouples,
|
|
81
|
+
});
|
|
82
|
+
await client.sendMessage(message);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return Array.from(wigs);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=kawa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kawa.js","sourceRoot":"","sources":["../../src/core/kawa.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Message } from "../cesr/__main__.ts";
|
|
2
|
+
import type { InceptEventBody, InteractEventBody, KeyEventBody, KeyState, RotateEventBody } from "./key-event.ts";
|
|
3
|
+
export type { InceptEventBody as InceptEvent, InteractEventBody as InteractEvent, KeyState, RotateEventBody as RotateEvent, };
|
|
4
|
+
export declare class KeyEventLog {
|
|
5
|
+
#private;
|
|
6
|
+
private constructor();
|
|
7
|
+
static empty(): KeyEventLog;
|
|
8
|
+
static from(events: Iterable<Message<KeyEventBody>>): KeyEventLog;
|
|
9
|
+
static parse(stream: AsyncIterable<Uint8Array>): Promise<KeyEventLog>;
|
|
10
|
+
get state(): KeyState;
|
|
11
|
+
get events(): Message<KeyEventBody>[];
|
|
12
|
+
append(message: Message<KeyEventBody>): KeyEventLog;
|
|
13
|
+
}
|