cojson 0.8.12 → 0.8.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/CHANGELOG.md +95 -83
  2. package/dist/native/PeerKnownStates.js +6 -1
  3. package/dist/native/PeerKnownStates.js.map +1 -1
  4. package/dist/native/PeerState.js +4 -3
  5. package/dist/native/PeerState.js.map +1 -1
  6. package/dist/native/PriorityBasedMessageQueue.js +1 -10
  7. package/dist/native/PriorityBasedMessageQueue.js.map +1 -1
  8. package/dist/native/SyncStateSubscriptionManager.js +70 -0
  9. package/dist/native/SyncStateSubscriptionManager.js.map +1 -0
  10. package/dist/native/base64url.js.map +1 -1
  11. package/dist/native/base64url.test.js +1 -1
  12. package/dist/native/base64url.test.js.map +1 -1
  13. package/dist/native/coValue.js.map +1 -1
  14. package/dist/native/coValueCore.js +141 -149
  15. package/dist/native/coValueCore.js.map +1 -1
  16. package/dist/native/coValueState.js.map +1 -1
  17. package/dist/native/coValues/account.js +6 -6
  18. package/dist/native/coValues/account.js.map +1 -1
  19. package/dist/native/coValues/coList.js +2 -3
  20. package/dist/native/coValues/coList.js.map +1 -1
  21. package/dist/native/coValues/coMap.js +1 -1
  22. package/dist/native/coValues/coMap.js.map +1 -1
  23. package/dist/native/coValues/coStream.js +3 -5
  24. package/dist/native/coValues/coStream.js.map +1 -1
  25. package/dist/native/coValues/group.js +11 -11
  26. package/dist/native/coValues/group.js.map +1 -1
  27. package/dist/native/coreToCoValue.js +2 -2
  28. package/dist/native/coreToCoValue.js.map +1 -1
  29. package/dist/native/crypto/PureJSCrypto.js +4 -4
  30. package/dist/native/crypto/PureJSCrypto.js.map +1 -1
  31. package/dist/native/crypto/crypto.js.map +1 -1
  32. package/dist/native/exports.js +12 -12
  33. package/dist/native/exports.js.map +1 -1
  34. package/dist/native/ids.js.map +1 -1
  35. package/dist/native/jsonStringify.js.map +1 -1
  36. package/dist/native/localNode.js +5 -7
  37. package/dist/native/localNode.js.map +1 -1
  38. package/dist/native/permissions.js +4 -7
  39. package/dist/native/permissions.js.map +1 -1
  40. package/dist/native/priority.js.map +1 -1
  41. package/dist/native/storage/FileSystem.js.map +1 -1
  42. package/dist/native/storage/chunksAndKnownStates.js +2 -4
  43. package/dist/native/storage/chunksAndKnownStates.js.map +1 -1
  44. package/dist/native/storage/index.js +6 -15
  45. package/dist/native/storage/index.js.map +1 -1
  46. package/dist/native/streamUtils.js.map +1 -1
  47. package/dist/native/sync.js +57 -7
  48. package/dist/native/sync.js.map +1 -1
  49. package/dist/native/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
  50. package/dist/native/typeUtils/expectGroup.js.map +1 -1
  51. package/dist/native/typeUtils/isAccountID.js.map +1 -1
  52. package/dist/native/typeUtils/isCoValue.js +1 -1
  53. package/dist/native/typeUtils/isCoValue.js.map +1 -1
  54. package/dist/web/PeerKnownStates.js +6 -1
  55. package/dist/web/PeerKnownStates.js.map +1 -1
  56. package/dist/web/PeerState.js +4 -3
  57. package/dist/web/PeerState.js.map +1 -1
  58. package/dist/web/PriorityBasedMessageQueue.js +1 -10
  59. package/dist/web/PriorityBasedMessageQueue.js.map +1 -1
  60. package/dist/web/SyncStateSubscriptionManager.js +70 -0
  61. package/dist/web/SyncStateSubscriptionManager.js.map +1 -0
  62. package/dist/web/base64url.js.map +1 -1
  63. package/dist/web/base64url.test.js +1 -1
  64. package/dist/web/base64url.test.js.map +1 -1
  65. package/dist/web/coValue.js.map +1 -1
  66. package/dist/web/coValueCore.js +141 -149
  67. package/dist/web/coValueCore.js.map +1 -1
  68. package/dist/web/coValueState.js.map +1 -1
  69. package/dist/web/coValues/account.js +6 -6
  70. package/dist/web/coValues/account.js.map +1 -1
  71. package/dist/web/coValues/coList.js +2 -3
  72. package/dist/web/coValues/coList.js.map +1 -1
  73. package/dist/web/coValues/coMap.js +1 -1
  74. package/dist/web/coValues/coMap.js.map +1 -1
  75. package/dist/web/coValues/coStream.js +3 -5
  76. package/dist/web/coValues/coStream.js.map +1 -1
  77. package/dist/web/coValues/group.js +11 -11
  78. package/dist/web/coValues/group.js.map +1 -1
  79. package/dist/web/coreToCoValue.js +2 -2
  80. package/dist/web/coreToCoValue.js.map +1 -1
  81. package/dist/web/crypto/PureJSCrypto.js +4 -4
  82. package/dist/web/crypto/PureJSCrypto.js.map +1 -1
  83. package/dist/web/crypto/WasmCrypto.js +5 -5
  84. package/dist/web/crypto/WasmCrypto.js.map +1 -1
  85. package/dist/web/crypto/crypto.js.map +1 -1
  86. package/dist/web/exports.js +12 -12
  87. package/dist/web/exports.js.map +1 -1
  88. package/dist/web/ids.js.map +1 -1
  89. package/dist/web/jsonStringify.js.map +1 -1
  90. package/dist/web/localNode.js +5 -7
  91. package/dist/web/localNode.js.map +1 -1
  92. package/dist/web/permissions.js +4 -7
  93. package/dist/web/permissions.js.map +1 -1
  94. package/dist/web/priority.js.map +1 -1
  95. package/dist/web/storage/FileSystem.js.map +1 -1
  96. package/dist/web/storage/chunksAndKnownStates.js +2 -4
  97. package/dist/web/storage/chunksAndKnownStates.js.map +1 -1
  98. package/dist/web/storage/index.js +6 -15
  99. package/dist/web/storage/index.js.map +1 -1
  100. package/dist/web/streamUtils.js.map +1 -1
  101. package/dist/web/sync.js +57 -7
  102. package/dist/web/sync.js.map +1 -1
  103. package/dist/web/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
  104. package/dist/web/typeUtils/expectGroup.js.map +1 -1
  105. package/dist/web/typeUtils/isAccountID.js.map +1 -1
  106. package/dist/web/typeUtils/isCoValue.js +1 -1
  107. package/dist/web/typeUtils/isCoValue.js.map +1 -1
  108. package/package.json +4 -14
  109. package/src/PeerKnownStates.ts +98 -90
  110. package/src/PeerState.ts +92 -73
  111. package/src/PriorityBasedMessageQueue.ts +42 -49
  112. package/src/SyncStateSubscriptionManager.ts +124 -0
  113. package/src/base64url.test.ts +24 -24
  114. package/src/base64url.ts +44 -45
  115. package/src/coValue.ts +45 -45
  116. package/src/coValueCore.ts +746 -785
  117. package/src/coValueState.ts +82 -72
  118. package/src/coValues/account.ts +143 -150
  119. package/src/coValues/coList.ts +520 -522
  120. package/src/coValues/coMap.ts +283 -285
  121. package/src/coValues/coStream.ts +320 -324
  122. package/src/coValues/group.ts +306 -305
  123. package/src/coreToCoValue.ts +28 -31
  124. package/src/crypto/PureJSCrypto.ts +188 -194
  125. package/src/crypto/WasmCrypto.ts +236 -254
  126. package/src/crypto/crypto.ts +302 -309
  127. package/src/exports.ts +116 -116
  128. package/src/ids.ts +9 -9
  129. package/src/jsonStringify.ts +46 -46
  130. package/src/jsonValue.ts +24 -10
  131. package/src/localNode.ts +635 -660
  132. package/src/media.ts +3 -3
  133. package/src/permissions.ts +272 -278
  134. package/src/priority.ts +21 -19
  135. package/src/storage/FileSystem.ts +91 -99
  136. package/src/storage/chunksAndKnownStates.ts +110 -115
  137. package/src/storage/index.ts +466 -497
  138. package/src/streamUtils.ts +60 -60
  139. package/src/sync.ts +656 -608
  140. package/src/tests/PeerKnownStates.test.ts +38 -34
  141. package/src/tests/PeerState.test.ts +101 -64
  142. package/src/tests/PriorityBasedMessageQueue.test.ts +91 -91
  143. package/src/tests/SyncStateSubscriptionManager.test.ts +232 -0
  144. package/src/tests/account.test.ts +59 -59
  145. package/src/tests/coList.test.ts +65 -65
  146. package/src/tests/coMap.test.ts +137 -137
  147. package/src/tests/coStream.test.ts +254 -257
  148. package/src/tests/coValueCore.test.ts +153 -156
  149. package/src/tests/crypto.test.ts +136 -144
  150. package/src/tests/cryptoImpl.test.ts +205 -197
  151. package/src/tests/group.test.ts +24 -24
  152. package/src/tests/permissions.test.ts +1306 -1371
  153. package/src/tests/priority.test.ts +65 -82
  154. package/src/tests/sync.test.ts +1573 -1263
  155. package/src/tests/testUtils.ts +85 -53
  156. package/src/typeUtils/accountOrAgentIDfromSessionID.ts +4 -4
  157. package/src/typeUtils/expectGroup.ts +9 -9
  158. package/src/typeUtils/isAccountID.ts +1 -1
  159. package/src/typeUtils/isCoValue.ts +9 -9
  160. package/tsconfig.json +4 -6
  161. package/tsconfig.native.json +9 -11
  162. package/tsconfig.web.json +4 -10
  163. package/.eslintrc.cjs +0 -25
  164. package/.prettierrc.js +0 -9
@@ -1,9 +1,9 @@
1
- import { JsonValue } from "../jsonValue.js";
2
1
  import { base58 } from "@scure/base";
3
- import { AgentID, RawCoID, TransactionID } from "../ids.js";
4
- import { Stringified, parseJSON, stableStringify } from "../jsonStringify.js";
5
2
  import { RawAccountID } from "../coValues/account.js";
3
+ import { AgentID, RawCoID, TransactionID } from "../ids.js";
6
4
  import { SessionID } from "../ids.js";
5
+ import { Stringified, parseJSON, stableStringify } from "../jsonStringify.js";
6
+ import { JsonValue } from "../jsonValue.js";
7
7
 
8
8
  export type SignerSecret = `signerSecret_z${string}`;
9
9
  export type SignerID = `signer_z${string}`;
@@ -20,324 +20,317 @@ export const textDecoder = new TextDecoder();
20
20
 
21
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
22
  export abstract class CryptoProvider<Blake3State = any> {
23
- abstract randomBytes(length: number): Uint8Array;
24
-
25
- abstract newEd25519SigningKey(): Uint8Array;
26
-
27
- newRandomSigner(): SignerSecret {
28
- return `signerSecret_z${base58.encode(this.newEd25519SigningKey())}`;
29
- }
30
-
31
- signerSecretToBytes(secret: SignerSecret): Uint8Array {
32
- return base58.decode(secret.substring("signerSecret_z".length));
33
- }
34
-
35
- signerSecretFromBytes(bytes: Uint8Array): SignerSecret {
36
- return `signerSecret_z${base58.encode(bytes)}`;
37
- }
38
-
39
- abstract getSignerID(secret: SignerSecret): SignerID;
40
-
41
- abstract sign(secret: SignerSecret, message: JsonValue): Signature;
42
-
43
- abstract verify(
44
- signature: Signature,
45
- message: JsonValue,
46
- id: SignerID,
47
- ): boolean;
48
-
49
- abstract newX25519StaticSecret(): Uint8Array;
50
-
51
- newRandomSealer(): SealerSecret {
52
- return `sealerSecret_z${base58.encode(this.newX25519StaticSecret())}`;
53
- }
54
-
55
- sealerSecretToBytes(secret: SealerSecret): Uint8Array {
56
- return base58.decode(secret.substring("sealerSecret_z".length));
57
- }
58
-
59
- sealerSecretFromBytes(bytes: Uint8Array): SealerSecret {
60
- return `sealerSecret_z${base58.encode(bytes)}`;
61
- }
62
-
63
- abstract getSealerID(secret: SealerSecret): SealerID;
64
-
65
- newRandomAgentSecret(): AgentSecret {
66
- return `${this.newRandomSealer()}/${this.newRandomSigner()}`;
67
- }
68
-
69
- agentSecretToBytes(secret: AgentSecret): Uint8Array {
70
- const [sealerSecret, signerSecret] = secret.split("/");
71
- return new Uint8Array([
72
- ...this.sealerSecretToBytes(sealerSecret as SealerSecret),
73
- ...this.signerSecretToBytes(signerSecret as SignerSecret),
74
- ]);
75
- }
76
-
77
- agentSecretFromBytes(bytes: Uint8Array): AgentSecret {
78
- const sealerSecret = this.sealerSecretFromBytes(bytes.slice(0, 32));
79
- const signerSecret = this.signerSecretFromBytes(bytes.slice(32));
80
- return `${sealerSecret}/${signerSecret}`;
81
- }
82
-
83
- getAgentID(secret: AgentSecret): AgentID {
84
- const [sealerSecret, signerSecret] = secret.split("/");
85
- return `${this.getSealerID(
86
- sealerSecret as SealerSecret,
87
- )}/${this.getSignerID(signerSecret as SignerSecret)}`;
88
- }
89
-
90
- getAgentSignerID(agentId: AgentID): SignerID {
91
- return agentId.split("/")[1] as SignerID;
92
- }
93
-
94
- getAgentSignerSecret(agentSecret: AgentSecret): SignerSecret {
95
- return agentSecret.split("/")[1] as SignerSecret;
96
- }
97
-
98
- getAgentSealerID(agentId: AgentID): SealerID {
99
- return agentId.split("/")[0] as SealerID;
100
- }
101
-
102
- getAgentSealerSecret(agentSecret: AgentSecret): SealerSecret {
103
- return agentSecret.split("/")[0] as SealerSecret;
104
- }
105
-
106
- abstract emptyBlake3State(): Blake3State;
107
- abstract cloneBlake3State(state: Blake3State): Blake3State;
108
- abstract blake3HashOnce(data: Uint8Array): Uint8Array;
109
- abstract blake3HashOnceWithContext(
110
- data: Uint8Array,
111
- { context }: { context: Uint8Array },
112
- ): Uint8Array;
113
- abstract blake3IncrementalUpdate(
114
- state: Blake3State,
115
- data: Uint8Array,
116
- ): Blake3State;
117
- abstract blake3DigestForState(state: Blake3State): Uint8Array;
118
-
119
- secureHash(value: JsonValue): Hash {
120
- return `hash_z${base58.encode(
121
- this.blake3HashOnce(textEncoder.encode(stableStringify(value))),
122
- )}`;
123
- }
124
-
125
- shortHash(value: JsonValue): ShortHash {
126
- return `shortHash_z${base58.encode(
127
- this.blake3HashOnce(
128
- textEncoder.encode(stableStringify(value)),
129
- ).slice(0, shortHashLength),
130
- )}`;
131
- }
132
-
133
- abstract encrypt<T extends JsonValue, N extends JsonValue>(
134
- value: T,
135
- keySecret: KeySecret,
136
- nOnceMaterial: N,
137
- ): Encrypted<T, N>;
138
-
139
- encryptForTransaction<T extends JsonValue>(
140
- value: T,
141
- keySecret: KeySecret,
142
- nOnceMaterial: { in: RawCoID; tx: TransactionID },
143
- ): Encrypted<T, { in: RawCoID; tx: TransactionID }> {
144
- return this.encrypt(value, keySecret, nOnceMaterial);
145
- }
146
-
147
- abstract decryptRaw<T extends JsonValue, N extends JsonValue>(
148
- encrypted: Encrypted<T, N>,
149
- keySecret: KeySecret,
150
- nOnceMaterial: N,
151
- ): Stringified<T>;
152
-
153
- decrypt<T extends JsonValue, N extends JsonValue>(
154
- encrypted: Encrypted<T, N>,
155
- keySecret: KeySecret,
156
- nOnceMaterial: N,
157
- ): T | undefined {
158
- try {
159
- return parseJSON(
160
- this.decryptRaw(encrypted, keySecret, nOnceMaterial),
161
- );
162
- } catch (e) {
163
- console.error("Decryption error", e);
164
- return undefined;
165
- }
166
- }
167
-
168
- newRandomKeySecret(): { secret: KeySecret; id: KeyID } {
169
- return {
170
- secret: `keySecret_z${base58.encode(this.randomBytes(32))}`,
171
- id: `key_z${base58.encode(this.randomBytes(12))}`,
172
- };
173
- }
174
-
175
- decryptRawForTransaction<T extends JsonValue>(
176
- encrypted: Encrypted<T, { in: RawCoID; tx: TransactionID }>,
177
- keySecret: KeySecret,
178
- nOnceMaterial: { in: RawCoID; tx: TransactionID },
179
- ): Stringified<T> | undefined {
180
- return this.decryptRaw(encrypted, keySecret, nOnceMaterial);
181
- }
182
-
183
- decryptForTransaction<T extends JsonValue>(
184
- encrypted: Encrypted<T, { in: RawCoID; tx: TransactionID }>,
185
- keySecret: KeySecret,
186
- nOnceMaterial: { in: RawCoID; tx: TransactionID },
187
- ): T | undefined {
188
- return this.decrypt(encrypted, keySecret, nOnceMaterial);
189
- }
190
-
191
- encryptKeySecret(keys: {
192
- toEncrypt: { id: KeyID; secret: KeySecret };
193
- encrypting: { id: KeyID; secret: KeySecret };
194
- }): {
195
- encryptedID: KeyID;
196
- encryptingID: KeyID;
197
- encrypted: Encrypted<
198
- KeySecret,
199
- { encryptedID: KeyID; encryptingID: KeyID }
200
- >;
201
- } {
202
- const nOnceMaterial = {
203
- encryptedID: keys.toEncrypt.id,
204
- encryptingID: keys.encrypting.id,
205
- };
206
-
207
- return {
208
- encryptedID: keys.toEncrypt.id,
209
- encryptingID: keys.encrypting.id,
210
- encrypted: this.encrypt(
211
- keys.toEncrypt.secret,
212
- keys.encrypting.secret,
213
- nOnceMaterial,
214
- ),
215
- };
216
- }
217
-
218
- decryptKeySecret(
219
- encryptedInfo: {
220
- encryptedID: KeyID;
221
- encryptingID: KeyID;
222
- encrypted: Encrypted<
223
- KeySecret,
224
- { encryptedID: KeyID; encryptingID: KeyID }
225
- >;
226
- },
227
- sealingSecret: KeySecret,
228
- ): KeySecret | undefined {
229
- const nOnceMaterial = {
230
- encryptedID: encryptedInfo.encryptedID,
231
- encryptingID: encryptedInfo.encryptingID,
232
- };
233
-
234
- return this.decrypt(
235
- encryptedInfo.encrypted,
236
- sealingSecret,
237
- nOnceMaterial,
238
- );
239
- }
240
-
241
- abstract seal<T extends JsonValue>({
242
- message,
243
- from,
244
- to,
23
+ abstract randomBytes(length: number): Uint8Array;
24
+
25
+ abstract newEd25519SigningKey(): Uint8Array;
26
+
27
+ newRandomSigner(): SignerSecret {
28
+ return `signerSecret_z${base58.encode(this.newEd25519SigningKey())}`;
29
+ }
30
+
31
+ signerSecretToBytes(secret: SignerSecret): Uint8Array {
32
+ return base58.decode(secret.substring("signerSecret_z".length));
33
+ }
34
+
35
+ signerSecretFromBytes(bytes: Uint8Array): SignerSecret {
36
+ return `signerSecret_z${base58.encode(bytes)}`;
37
+ }
38
+
39
+ abstract getSignerID(secret: SignerSecret): SignerID;
40
+
41
+ abstract sign(secret: SignerSecret, message: JsonValue): Signature;
42
+
43
+ abstract verify(
44
+ signature: Signature,
45
+ message: JsonValue,
46
+ id: SignerID,
47
+ ): boolean;
48
+
49
+ abstract newX25519StaticSecret(): Uint8Array;
50
+
51
+ newRandomSealer(): SealerSecret {
52
+ return `sealerSecret_z${base58.encode(this.newX25519StaticSecret())}`;
53
+ }
54
+
55
+ sealerSecretToBytes(secret: SealerSecret): Uint8Array {
56
+ return base58.decode(secret.substring("sealerSecret_z".length));
57
+ }
58
+
59
+ sealerSecretFromBytes(bytes: Uint8Array): SealerSecret {
60
+ return `sealerSecret_z${base58.encode(bytes)}`;
61
+ }
62
+
63
+ abstract getSealerID(secret: SealerSecret): SealerID;
64
+
65
+ newRandomAgentSecret(): AgentSecret {
66
+ return `${this.newRandomSealer()}/${this.newRandomSigner()}`;
67
+ }
68
+
69
+ agentSecretToBytes(secret: AgentSecret): Uint8Array {
70
+ const [sealerSecret, signerSecret] = secret.split("/");
71
+ return new Uint8Array([
72
+ ...this.sealerSecretToBytes(sealerSecret as SealerSecret),
73
+ ...this.signerSecretToBytes(signerSecret as SignerSecret),
74
+ ]);
75
+ }
76
+
77
+ agentSecretFromBytes(bytes: Uint8Array): AgentSecret {
78
+ const sealerSecret = this.sealerSecretFromBytes(bytes.slice(0, 32));
79
+ const signerSecret = this.signerSecretFromBytes(bytes.slice(32));
80
+ return `${sealerSecret}/${signerSecret}`;
81
+ }
82
+
83
+ getAgentID(secret: AgentSecret): AgentID {
84
+ const [sealerSecret, signerSecret] = secret.split("/");
85
+ return `${this.getSealerID(
86
+ sealerSecret as SealerSecret,
87
+ )}/${this.getSignerID(signerSecret as SignerSecret)}`;
88
+ }
89
+
90
+ getAgentSignerID(agentId: AgentID): SignerID {
91
+ return agentId.split("/")[1] as SignerID;
92
+ }
93
+
94
+ getAgentSignerSecret(agentSecret: AgentSecret): SignerSecret {
95
+ return agentSecret.split("/")[1] as SignerSecret;
96
+ }
97
+
98
+ getAgentSealerID(agentId: AgentID): SealerID {
99
+ return agentId.split("/")[0] as SealerID;
100
+ }
101
+
102
+ getAgentSealerSecret(agentSecret: AgentSecret): SealerSecret {
103
+ return agentSecret.split("/")[0] as SealerSecret;
104
+ }
105
+
106
+ abstract emptyBlake3State(): Blake3State;
107
+ abstract cloneBlake3State(state: Blake3State): Blake3State;
108
+ abstract blake3HashOnce(data: Uint8Array): Uint8Array;
109
+ abstract blake3HashOnceWithContext(
110
+ data: Uint8Array,
111
+ { context }: { context: Uint8Array },
112
+ ): Uint8Array;
113
+ abstract blake3IncrementalUpdate(
114
+ state: Blake3State,
115
+ data: Uint8Array,
116
+ ): Blake3State;
117
+ abstract blake3DigestForState(state: Blake3State): Uint8Array;
118
+
119
+ secureHash(value: JsonValue): Hash {
120
+ return `hash_z${base58.encode(
121
+ this.blake3HashOnce(textEncoder.encode(stableStringify(value))),
122
+ )}`;
123
+ }
124
+
125
+ shortHash(value: JsonValue): ShortHash {
126
+ return `shortHash_z${base58.encode(
127
+ this.blake3HashOnce(textEncoder.encode(stableStringify(value))).slice(
128
+ 0,
129
+ shortHashLength,
130
+ ),
131
+ )}`;
132
+ }
133
+
134
+ abstract encrypt<T extends JsonValue, N extends JsonValue>(
135
+ value: T,
136
+ keySecret: KeySecret,
137
+ nOnceMaterial: N,
138
+ ): Encrypted<T, N>;
139
+
140
+ encryptForTransaction<T extends JsonValue>(
141
+ value: T,
142
+ keySecret: KeySecret,
143
+ nOnceMaterial: { in: RawCoID; tx: TransactionID },
144
+ ): Encrypted<T, { in: RawCoID; tx: TransactionID }> {
145
+ return this.encrypt(value, keySecret, nOnceMaterial);
146
+ }
147
+
148
+ abstract decryptRaw<T extends JsonValue, N extends JsonValue>(
149
+ encrypted: Encrypted<T, N>,
150
+ keySecret: KeySecret,
151
+ nOnceMaterial: N,
152
+ ): Stringified<T>;
153
+
154
+ decrypt<T extends JsonValue, N extends JsonValue>(
155
+ encrypted: Encrypted<T, N>,
156
+ keySecret: KeySecret,
157
+ nOnceMaterial: N,
158
+ ): T | undefined {
159
+ try {
160
+ return parseJSON(this.decryptRaw(encrypted, keySecret, nOnceMaterial));
161
+ } catch (e) {
162
+ console.error("Decryption error", e);
163
+ return undefined;
164
+ }
165
+ }
166
+
167
+ newRandomKeySecret(): { secret: KeySecret; id: KeyID } {
168
+ return {
169
+ secret: `keySecret_z${base58.encode(this.randomBytes(32))}`,
170
+ id: `key_z${base58.encode(this.randomBytes(12))}`,
171
+ };
172
+ }
173
+
174
+ decryptRawForTransaction<T extends JsonValue>(
175
+ encrypted: Encrypted<T, { in: RawCoID; tx: TransactionID }>,
176
+ keySecret: KeySecret,
177
+ nOnceMaterial: { in: RawCoID; tx: TransactionID },
178
+ ): Stringified<T> | undefined {
179
+ return this.decryptRaw(encrypted, keySecret, nOnceMaterial);
180
+ }
181
+
182
+ decryptForTransaction<T extends JsonValue>(
183
+ encrypted: Encrypted<T, { in: RawCoID; tx: TransactionID }>,
184
+ keySecret: KeySecret,
185
+ nOnceMaterial: { in: RawCoID; tx: TransactionID },
186
+ ): T | undefined {
187
+ return this.decrypt(encrypted, keySecret, nOnceMaterial);
188
+ }
189
+
190
+ encryptKeySecret(keys: {
191
+ toEncrypt: { id: KeyID; secret: KeySecret };
192
+ encrypting: { id: KeyID; secret: KeySecret };
193
+ }): {
194
+ encryptedID: KeyID;
195
+ encryptingID: KeyID;
196
+ encrypted: Encrypted<
197
+ KeySecret,
198
+ { encryptedID: KeyID; encryptingID: KeyID }
199
+ >;
200
+ } {
201
+ const nOnceMaterial = {
202
+ encryptedID: keys.toEncrypt.id,
203
+ encryptingID: keys.encrypting.id,
204
+ };
205
+
206
+ return {
207
+ encryptedID: keys.toEncrypt.id,
208
+ encryptingID: keys.encrypting.id,
209
+ encrypted: this.encrypt(
210
+ keys.toEncrypt.secret,
211
+ keys.encrypting.secret,
245
212
  nOnceMaterial,
246
- }: {
247
- message: T;
248
- from: SealerSecret;
249
- to: SealerID;
250
- nOnceMaterial: { in: RawCoID; tx: TransactionID };
251
- }): Sealed<T>;
252
-
253
- abstract unseal<T extends JsonValue>(
254
- sealed: Sealed<T>,
255
- sealer: SealerSecret,
256
- from: SealerID,
257
- nOnceMaterial: { in: RawCoID; tx: TransactionID },
258
- ): T | undefined;
259
-
260
- uniquenessForHeader(): `z${string}` {
261
- return `z${base58.encode(this.randomBytes(12))}`;
262
- }
263
-
264
- createdNowUnique(): {
265
- createdAt: `2${string}`;
266
- uniqueness: `z${string}`;
267
- } {
268
- const createdAt = new Date().toISOString() as `2${string}`;
269
- return {
270
- createdAt,
271
- uniqueness: this.uniquenessForHeader(),
272
- };
273
- }
274
-
275
- newRandomSecretSeed(): Uint8Array {
276
- return this.randomBytes(secretSeedLength);
277
- }
278
-
279
- agentSecretFromSecretSeed(secretSeed: Uint8Array): AgentSecret {
280
- if (secretSeed.length !== secretSeedLength) {
281
- throw new Error(
282
- `Secret seed needs to be ${secretSeedLength} bytes long`,
283
- );
284
- }
285
-
286
- return `sealerSecret_z${base58.encode(
287
- this.blake3HashOnceWithContext(secretSeed, {
288
- context: textEncoder.encode("seal"),
289
- }),
290
- )}/signerSecret_z${base58.encode(
291
- this.blake3HashOnceWithContext(secretSeed, {
292
- context: textEncoder.encode("sign"),
293
- }),
294
- )}`;
295
- }
296
-
297
- newRandomSessionID(accountID: RawAccountID | AgentID): SessionID {
298
- return `${accountID}_session_z${base58.encode(this.randomBytes(8))}`;
299
- }
213
+ ),
214
+ };
215
+ }
216
+
217
+ decryptKeySecret(
218
+ encryptedInfo: {
219
+ encryptedID: KeyID;
220
+ encryptingID: KeyID;
221
+ encrypted: Encrypted<
222
+ KeySecret,
223
+ { encryptedID: KeyID; encryptingID: KeyID }
224
+ >;
225
+ },
226
+ sealingSecret: KeySecret,
227
+ ): KeySecret | undefined {
228
+ const nOnceMaterial = {
229
+ encryptedID: encryptedInfo.encryptedID,
230
+ encryptingID: encryptedInfo.encryptingID,
231
+ };
232
+
233
+ return this.decrypt(encryptedInfo.encrypted, sealingSecret, nOnceMaterial);
234
+ }
235
+
236
+ abstract seal<T extends JsonValue>({
237
+ message,
238
+ from,
239
+ to,
240
+ nOnceMaterial,
241
+ }: {
242
+ message: T;
243
+ from: SealerSecret;
244
+ to: SealerID;
245
+ nOnceMaterial: { in: RawCoID; tx: TransactionID };
246
+ }): Sealed<T>;
247
+
248
+ abstract unseal<T extends JsonValue>(
249
+ sealed: Sealed<T>,
250
+ sealer: SealerSecret,
251
+ from: SealerID,
252
+ nOnceMaterial: { in: RawCoID; tx: TransactionID },
253
+ ): T | undefined;
254
+
255
+ uniquenessForHeader(): `z${string}` {
256
+ return `z${base58.encode(this.randomBytes(12))}`;
257
+ }
258
+
259
+ createdNowUnique(): {
260
+ createdAt: `2${string}`;
261
+ uniqueness: `z${string}`;
262
+ } {
263
+ const createdAt = new Date().toISOString() as `2${string}`;
264
+ return {
265
+ createdAt,
266
+ uniqueness: this.uniquenessForHeader(),
267
+ };
268
+ }
269
+
270
+ newRandomSecretSeed(): Uint8Array {
271
+ return this.randomBytes(secretSeedLength);
272
+ }
273
+
274
+ agentSecretFromSecretSeed(secretSeed: Uint8Array): AgentSecret {
275
+ if (secretSeed.length !== secretSeedLength) {
276
+ throw new Error(`Secret seed needs to be ${secretSeedLength} bytes long`);
277
+ }
278
+
279
+ return `sealerSecret_z${base58.encode(
280
+ this.blake3HashOnceWithContext(secretSeed, {
281
+ context: textEncoder.encode("seal"),
282
+ }),
283
+ )}/signerSecret_z${base58.encode(
284
+ this.blake3HashOnceWithContext(secretSeed, {
285
+ context: textEncoder.encode("sign"),
286
+ }),
287
+ )}`;
288
+ }
289
+
290
+ newRandomSessionID(accountID: RawAccountID | AgentID): SessionID {
291
+ return `${accountID}_session_z${base58.encode(this.randomBytes(8))}`;
292
+ }
300
293
  }
301
294
 
302
295
  export type Hash = `hash_z${string}`;
303
296
 
304
297
  export class StreamingHash {
305
- state: Uint8Array;
306
- crypto: CryptoProvider;
307
-
308
- constructor(crypto: CryptoProvider, fromClone?: Uint8Array) {
309
- this.state = fromClone || crypto.emptyBlake3State();
310
- this.crypto = crypto;
311
- }
312
-
313
- update(value: JsonValue): Uint8Array {
314
- const encoded = textEncoder.encode(stableStringify(value));
315
- // const before = performance.now();
316
- this.state = this.crypto.blake3IncrementalUpdate(this.state, encoded);
317
- // const after = performance.now();
318
- // console.log(`Hashing throughput in MB/s`, 1000 * (encoded.length / (after - before)) / (1024 * 1024));
319
- return encoded;
320
- }
321
-
322
- digest(): Hash {
323
- const hash = this.crypto.blake3DigestForState(this.state);
324
- return `hash_z${base58.encode(hash)}`;
325
- }
326
-
327
- clone(): StreamingHash {
328
- return new StreamingHash(
329
- this.crypto,
330
- this.crypto.cloneBlake3State(this.state),
331
- );
332
- }
298
+ state: Uint8Array;
299
+ crypto: CryptoProvider;
300
+
301
+ constructor(crypto: CryptoProvider, fromClone?: Uint8Array) {
302
+ this.state = fromClone || crypto.emptyBlake3State();
303
+ this.crypto = crypto;
304
+ }
305
+
306
+ update(value: JsonValue): Uint8Array {
307
+ const encoded = textEncoder.encode(stableStringify(value));
308
+ // const before = performance.now();
309
+ this.state = this.crypto.blake3IncrementalUpdate(this.state, encoded);
310
+ // const after = performance.now();
311
+ // console.log(`Hashing throughput in MB/s`, 1000 * (encoded.length / (after - before)) / (1024 * 1024));
312
+ return encoded;
313
+ }
314
+
315
+ digest(): Hash {
316
+ const hash = this.crypto.blake3DigestForState(this.state);
317
+ return `hash_z${base58.encode(hash)}`;
318
+ }
319
+
320
+ clone(): StreamingHash {
321
+ return new StreamingHash(
322
+ this.crypto,
323
+ this.crypto.cloneBlake3State(this.state),
324
+ );
325
+ }
333
326
  }
334
327
 
335
328
  export type ShortHash = `shortHash_z${string}`;
336
329
  export const shortHashLength = 19;
337
330
 
338
331
  export type Encrypted<
339
- T extends JsonValue,
340
- N extends JsonValue,
332
+ T extends JsonValue,
333
+ N extends JsonValue,
341
334
  > = `encrypted_U${string}` & { __type: T; __nOnceMaterial: N };
342
335
 
343
336
  export type KeySecret = `keySecret_z${string}`;