cojson 0.19.7 → 0.19.10
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +27 -3
- package/dist/coValueCore/coValueCore.d.ts +2 -2
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +50 -35
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/crypto/RNCrypto.d.ts +38 -0
- package/dist/crypto/RNCrypto.d.ts.map +1 -0
- package/dist/crypto/RNCrypto.js +129 -0
- package/dist/crypto/RNCrypto.js.map +1 -0
- package/dist/exports.d.ts +5 -3
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +3 -1
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts +1 -0
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +7 -2
- package/dist/localNode.js.map +1 -1
- package/dist/tests/coValueCore.test.js +109 -26
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/package.json +10 -3
- package/src/coValueCore/coValueCore.ts +62 -43
- package/src/crypto/RNCrypto.ts +307 -0
- package/src/exports.ts +9 -1
- package/src/localNode.ts +8 -2
- package/src/tests/coValueCore.test.ts +148 -32
|
@@ -379,11 +379,6 @@ export class CoValueCore {
|
|
|
379
379
|
|
|
380
380
|
this.counter.add(-1, { state: this.loadingState });
|
|
381
381
|
|
|
382
|
-
if (this.groupInvalidationSubscription) {
|
|
383
|
-
this.groupInvalidationSubscription();
|
|
384
|
-
this.groupInvalidationSubscription = undefined;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
382
|
this.node.internalDeleteCoValue(this.id);
|
|
388
383
|
|
|
389
384
|
return true;
|
|
@@ -517,38 +512,6 @@ export class CoValueCore {
|
|
|
517
512
|
this.scheduleNotifyUpdate();
|
|
518
513
|
}
|
|
519
514
|
|
|
520
|
-
groupInvalidationSubscription?: () => void;
|
|
521
|
-
|
|
522
|
-
subscribeToGroupInvalidation() {
|
|
523
|
-
if (!this.verified) {
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (this.groupInvalidationSubscription) {
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
const header = this.verified.header;
|
|
532
|
-
|
|
533
|
-
if (header.ruleset.type == "ownedByGroup") {
|
|
534
|
-
const groupId = header.ruleset.group;
|
|
535
|
-
const entry = this.node.getCoValue(groupId);
|
|
536
|
-
|
|
537
|
-
if (entry.isAvailable()) {
|
|
538
|
-
this.groupInvalidationSubscription = entry.subscribe((_groupUpdate) => {
|
|
539
|
-
// When the group is updated, we need to reset the cached content because the transactions validity might have changed
|
|
540
|
-
this.resetParsedTransactions();
|
|
541
|
-
this.scheduleNotifyUpdate();
|
|
542
|
-
}, false);
|
|
543
|
-
} else {
|
|
544
|
-
logger.error("CoValueCore: Owner group not available", {
|
|
545
|
-
id: this.id,
|
|
546
|
-
groupId,
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
515
|
contentInClonedNodeWithDifferentAccount(account: ControlledAccountOrAgent) {
|
|
553
516
|
return this.node
|
|
554
517
|
.loadCoValueAsDifferentAgent(this.id, account.agentSecret, account.id)
|
|
@@ -656,11 +619,34 @@ export class CoValueCore {
|
|
|
656
619
|
|
|
657
620
|
this.processNewTransactions();
|
|
658
621
|
this.scheduleNotifyUpdate();
|
|
622
|
+
this.invalidateDependants();
|
|
659
623
|
} catch (e) {
|
|
660
624
|
return { type: "InvalidSignature", id: this.id, error: e } as const;
|
|
661
625
|
}
|
|
662
626
|
}
|
|
663
627
|
|
|
628
|
+
notifyDependants() {
|
|
629
|
+
if (!this.isGroup()) {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
for (const dependency of this.dependant) {
|
|
634
|
+
this.node.getCoValue(dependency).scheduleNotifyUpdate();
|
|
635
|
+
this.node.getCoValue(dependency).notifyDependants();
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
invalidateDependants() {
|
|
640
|
+
if (!this.isGroup()) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
for (const dependency of this.dependant) {
|
|
645
|
+
this.node.getCoValue(dependency).resetParsedTransactions();
|
|
646
|
+
this.node.getCoValue(dependency).invalidateDependants();
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
664
650
|
private processNewTransactions() {
|
|
665
651
|
if (this._cachedContent) {
|
|
666
652
|
this._cachedContent.processNewTransactions();
|
|
@@ -807,6 +793,19 @@ export class CoValueCore {
|
|
|
807
793
|
this.notifyUpdate();
|
|
808
794
|
this.node.syncManager.syncLocalTransaction(this.verified, knownStateBefore);
|
|
809
795
|
|
|
796
|
+
if (madeAt === undefined) {
|
|
797
|
+
// We don't revalidate the dependants transactions because we assume that transactions that you are
|
|
798
|
+
// creating "now" on groups don't affect the validity of transactions you already have in memory.
|
|
799
|
+
// For validity I mean:
|
|
800
|
+
// - ability to decrypt a transaction
|
|
801
|
+
// - that the account that made the transaction had enough rights to do so
|
|
802
|
+
this.notifyDependants();
|
|
803
|
+
} else {
|
|
804
|
+
// If the transaction is not made "now", we need to revalidate the dependants transactions
|
|
805
|
+
// because the new transaction might affect the validity of the dependants transactions
|
|
806
|
+
this.invalidateDependants();
|
|
807
|
+
}
|
|
808
|
+
|
|
810
809
|
return true;
|
|
811
810
|
}
|
|
812
811
|
|
|
@@ -833,8 +832,6 @@ export class CoValueCore {
|
|
|
833
832
|
|
|
834
833
|
const newContent = coreToCoValue(this as AvailableCoValueCore, options);
|
|
835
834
|
|
|
836
|
-
this.subscribeToGroupInvalidation();
|
|
837
|
-
|
|
838
835
|
if (!options?.ignorePrivateTransactions) {
|
|
839
836
|
this._cachedContent = newContent;
|
|
840
837
|
}
|
|
@@ -853,19 +850,41 @@ export class CoValueCore {
|
|
|
853
850
|
|
|
854
851
|
// Reset the parsed transactions and branches, to validate them again from scratch when the group is updated
|
|
855
852
|
resetParsedTransactions() {
|
|
853
|
+
const verifiedTransactions = this.verifiedTransactions;
|
|
854
|
+
|
|
855
|
+
if (verifiedTransactions.length === 0) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
|
|
856
859
|
this.branchStart = undefined;
|
|
857
860
|
this.mergeCommits = [];
|
|
858
861
|
|
|
859
|
-
|
|
862
|
+
// Store the validity of the transactions before resetting the parsed transactions
|
|
863
|
+
const validityBeforeReset = new Array<boolean>(verifiedTransactions.length);
|
|
864
|
+
this.verifiedTransactions.forEach((transaction, index) => {
|
|
860
865
|
transaction.isValidated = false;
|
|
861
|
-
|
|
866
|
+
validityBeforeReset[index] = transaction.isValidTransactionWithChanges();
|
|
867
|
+
});
|
|
862
868
|
|
|
863
|
-
this.toValidateTransactions =
|
|
869
|
+
this.toValidateTransactions = verifiedTransactions.slice();
|
|
864
870
|
this.toProcessTransactions = [];
|
|
865
871
|
this.toDecryptTransactions = [];
|
|
866
872
|
this.toParseMetaTransactions = [];
|
|
867
873
|
|
|
868
|
-
this.
|
|
874
|
+
this.parseNewTransactions(false);
|
|
875
|
+
|
|
876
|
+
// Check if the validity of the transactions has changed after resetting the parsed transactions
|
|
877
|
+
// If it has, we need to rebuild the content to reflect the new validity
|
|
878
|
+
const sameAsBefore = validityBeforeReset.every(
|
|
879
|
+
(valid, index) =>
|
|
880
|
+
valid === verifiedTransactions[index]?.isValidTransactionWithChanges(),
|
|
881
|
+
);
|
|
882
|
+
|
|
883
|
+
if (!sameAsBefore) {
|
|
884
|
+
this._cachedContent?.rebuildFromCore();
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
this.scheduleNotifyUpdate();
|
|
869
888
|
}
|
|
870
889
|
|
|
871
890
|
verifiedTransactions: VerifiedTransaction[] = [];
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import {
|
|
2
|
+
JsonValue,
|
|
3
|
+
RawCoID,
|
|
4
|
+
SessionID,
|
|
5
|
+
Stringified,
|
|
6
|
+
base64URLtoBytes,
|
|
7
|
+
bytesToBase64url,
|
|
8
|
+
} from "../exports.js";
|
|
9
|
+
import { CojsonInternalTypes } from "../exports.js";
|
|
10
|
+
import { TransactionID } from "../ids.js";
|
|
11
|
+
import { stableStringify } from "../jsonStringify.js";
|
|
12
|
+
import { JsonObject } from "../jsonValue.js";
|
|
13
|
+
import { logger } from "../logger.js";
|
|
14
|
+
import { ControlledAccountOrAgent } from "../coValues/account.js";
|
|
15
|
+
import {
|
|
16
|
+
PrivateTransaction,
|
|
17
|
+
Transaction,
|
|
18
|
+
TrustingTransaction,
|
|
19
|
+
} from "../coValueCore/verifiedState.js";
|
|
20
|
+
import {
|
|
21
|
+
CryptoProvider,
|
|
22
|
+
KeyID,
|
|
23
|
+
KeySecret,
|
|
24
|
+
Sealed,
|
|
25
|
+
SealerID,
|
|
26
|
+
SealerSecret,
|
|
27
|
+
SessionLogImpl,
|
|
28
|
+
Signature,
|
|
29
|
+
SignerID,
|
|
30
|
+
SignerSecret,
|
|
31
|
+
textDecoder,
|
|
32
|
+
textEncoder,
|
|
33
|
+
} from "./crypto.js";
|
|
34
|
+
import {
|
|
35
|
+
blake3HashOnce,
|
|
36
|
+
blake3HashOnceWithContext,
|
|
37
|
+
verify,
|
|
38
|
+
encrypt,
|
|
39
|
+
decrypt,
|
|
40
|
+
newEd25519SigningKey,
|
|
41
|
+
newX25519PrivateKey,
|
|
42
|
+
getSealerId,
|
|
43
|
+
getSignerId,
|
|
44
|
+
sign,
|
|
45
|
+
seal,
|
|
46
|
+
unseal,
|
|
47
|
+
Blake3Hasher,
|
|
48
|
+
SessionLog,
|
|
49
|
+
} from "cojson-core-rn";
|
|
50
|
+
|
|
51
|
+
type Blake3State = Blake3Hasher;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @param view - The Uint8Array to convert to an ArrayBuffer.
|
|
56
|
+
* @returns The ArrayBuffer.
|
|
57
|
+
*/
|
|
58
|
+
function toArrayBuffer(view: Uint8Array): ArrayBuffer {
|
|
59
|
+
if (
|
|
60
|
+
view.byteOffset === 0 &&
|
|
61
|
+
view.byteLength === view.buffer.byteLength &&
|
|
62
|
+
view.buffer instanceof ArrayBuffer
|
|
63
|
+
) {
|
|
64
|
+
return view.buffer;
|
|
65
|
+
}
|
|
66
|
+
const buffer = new ArrayBuffer(view.byteLength);
|
|
67
|
+
new Uint8Array(buffer).set(view);
|
|
68
|
+
return buffer;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export class RNCrypto extends CryptoProvider<Blake3State> {
|
|
72
|
+
private constructor() {
|
|
73
|
+
super();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getSignerID(secret: SignerSecret): SignerID {
|
|
77
|
+
return getSignerId(secret) as SignerID;
|
|
78
|
+
}
|
|
79
|
+
newX25519StaticSecret(): Uint8Array {
|
|
80
|
+
return new Uint8Array(newX25519PrivateKey());
|
|
81
|
+
}
|
|
82
|
+
getSealerID(secret: SealerSecret): SealerID {
|
|
83
|
+
return getSealerId(secret) as SealerID;
|
|
84
|
+
}
|
|
85
|
+
blake3HashOnce(data: Uint8Array): Uint8Array {
|
|
86
|
+
return new Uint8Array(blake3HashOnce(toArrayBuffer(data)));
|
|
87
|
+
}
|
|
88
|
+
blake3HashOnceWithContext(
|
|
89
|
+
data: Uint8Array,
|
|
90
|
+
{ context }: { context: Uint8Array },
|
|
91
|
+
): Uint8Array {
|
|
92
|
+
return new Uint8Array(
|
|
93
|
+
blake3HashOnceWithContext(toArrayBuffer(data), toArrayBuffer(context)),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
seal<T extends JsonValue>({
|
|
97
|
+
message,
|
|
98
|
+
from,
|
|
99
|
+
to,
|
|
100
|
+
nOnceMaterial,
|
|
101
|
+
}: {
|
|
102
|
+
message: T;
|
|
103
|
+
from: SealerSecret;
|
|
104
|
+
to: SealerID;
|
|
105
|
+
nOnceMaterial: { in: RawCoID; tx: TransactionID };
|
|
106
|
+
}): Sealed<T> {
|
|
107
|
+
const messageBuffer = toArrayBuffer(
|
|
108
|
+
textEncoder.encode(stableStringify(message)),
|
|
109
|
+
);
|
|
110
|
+
const nOnceBuffer = toArrayBuffer(
|
|
111
|
+
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return `sealed_U${bytesToBase64url(
|
|
115
|
+
new Uint8Array(seal(messageBuffer, from, to, nOnceBuffer)),
|
|
116
|
+
)}` as Sealed<T>;
|
|
117
|
+
}
|
|
118
|
+
unseal<T extends JsonValue>(
|
|
119
|
+
sealed: Sealed<T>,
|
|
120
|
+
sealer: SealerSecret,
|
|
121
|
+
from: SealerID,
|
|
122
|
+
nOnceMaterial: { in: RawCoID; tx: TransactionID },
|
|
123
|
+
): T | undefined {
|
|
124
|
+
const sealedBytes = base64URLtoBytes(sealed.substring("sealed_U".length));
|
|
125
|
+
const nonceBuffer = toArrayBuffer(
|
|
126
|
+
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const plaintext = textDecoder.decode(
|
|
130
|
+
unseal(toArrayBuffer(sealedBytes), sealer, from, nonceBuffer),
|
|
131
|
+
);
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(plaintext) as T;
|
|
134
|
+
} catch (e) {
|
|
135
|
+
logger.error("Failed to decrypt/parse sealed message", { err: e });
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
createSessionLog(
|
|
140
|
+
coID: RawCoID,
|
|
141
|
+
sessionID: SessionID,
|
|
142
|
+
signerID?: SignerID,
|
|
143
|
+
): SessionLogImpl {
|
|
144
|
+
return new SessionLogAdapter(new SessionLog(coID, sessionID, signerID));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static async create(): Promise<RNCrypto> {
|
|
148
|
+
return new RNCrypto();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
newEd25519SigningKey(): Uint8Array {
|
|
152
|
+
return new Uint8Array(newEd25519SigningKey());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
sign(
|
|
156
|
+
secret: CojsonInternalTypes.SignerSecret,
|
|
157
|
+
message: JsonValue,
|
|
158
|
+
): CojsonInternalTypes.Signature {
|
|
159
|
+
return sign(
|
|
160
|
+
toArrayBuffer(textEncoder.encode(stableStringify(message))),
|
|
161
|
+
secret,
|
|
162
|
+
) as CojsonInternalTypes.Signature;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
verify(
|
|
166
|
+
signature: CojsonInternalTypes.Signature,
|
|
167
|
+
message: JsonValue,
|
|
168
|
+
id: CojsonInternalTypes.SignerID,
|
|
169
|
+
): boolean {
|
|
170
|
+
const result = verify(
|
|
171
|
+
signature,
|
|
172
|
+
toArrayBuffer(textEncoder.encode(stableStringify(message))),
|
|
173
|
+
id,
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
encrypt<T extends JsonValue, N extends JsonValue>(
|
|
180
|
+
value: T,
|
|
181
|
+
keySecret: CojsonInternalTypes.KeySecret,
|
|
182
|
+
nOnceMaterial: N,
|
|
183
|
+
): CojsonInternalTypes.Encrypted<T, N> {
|
|
184
|
+
const valueBytes = toArrayBuffer(
|
|
185
|
+
textEncoder.encode(stableStringify(value)),
|
|
186
|
+
);
|
|
187
|
+
const nOnceBytes = toArrayBuffer(
|
|
188
|
+
textEncoder.encode(stableStringify(nOnceMaterial)),
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const encrypted = `encrypted_U${bytesToBase64url(
|
|
192
|
+
new Uint8Array(encrypt(valueBytes, keySecret, nOnceBytes)),
|
|
193
|
+
)}` as CojsonInternalTypes.Encrypted<T, N>;
|
|
194
|
+
return encrypted;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
decryptRaw<T extends JsonValue, N extends JsonValue>(
|
|
198
|
+
encrypted: CojsonInternalTypes.Encrypted<T, N>,
|
|
199
|
+
keySecret: CojsonInternalTypes.KeySecret,
|
|
200
|
+
nOnceMaterial: N,
|
|
201
|
+
): Stringified<T> {
|
|
202
|
+
const buffer = base64URLtoBytes(encrypted.substring("encrypted_U".length));
|
|
203
|
+
|
|
204
|
+
const decrypted = textDecoder.decode(
|
|
205
|
+
decrypt(
|
|
206
|
+
toArrayBuffer(buffer),
|
|
207
|
+
keySecret,
|
|
208
|
+
toArrayBuffer(textEncoder.encode(stableStringify(nOnceMaterial))),
|
|
209
|
+
),
|
|
210
|
+
) as Stringified<T>;
|
|
211
|
+
|
|
212
|
+
return decrypted;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
class SessionLogAdapter implements SessionLogImpl {
|
|
217
|
+
constructor(private readonly sessionLog: SessionLog) {}
|
|
218
|
+
|
|
219
|
+
tryAdd(
|
|
220
|
+
transactions: Transaction[],
|
|
221
|
+
newSignature: Signature,
|
|
222
|
+
skipVerify: boolean,
|
|
223
|
+
): void {
|
|
224
|
+
this.sessionLog.tryAdd(
|
|
225
|
+
transactions.map((tx) => stableStringify(tx)),
|
|
226
|
+
newSignature,
|
|
227
|
+
skipVerify,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
addNewPrivateTransaction(
|
|
232
|
+
signerAgent: ControlledAccountOrAgent,
|
|
233
|
+
changes: JsonValue[],
|
|
234
|
+
keyID: KeyID,
|
|
235
|
+
keySecret: KeySecret,
|
|
236
|
+
madeAt: number,
|
|
237
|
+
meta: JsonObject | undefined,
|
|
238
|
+
) {
|
|
239
|
+
const output = this.sessionLog.addNewPrivateTransaction(
|
|
240
|
+
stableStringify(changes),
|
|
241
|
+
signerAgent.currentSignerSecret(),
|
|
242
|
+
keySecret,
|
|
243
|
+
keyID,
|
|
244
|
+
madeAt,
|
|
245
|
+
meta ? stableStringify(meta) : undefined,
|
|
246
|
+
);
|
|
247
|
+
const parsedOutput = JSON.parse(output);
|
|
248
|
+
const transaction: PrivateTransaction = {
|
|
249
|
+
privacy: "private",
|
|
250
|
+
madeAt,
|
|
251
|
+
encryptedChanges: parsedOutput.encrypted_changes,
|
|
252
|
+
keyUsed: keyID,
|
|
253
|
+
meta: parsedOutput.meta,
|
|
254
|
+
};
|
|
255
|
+
return { signature: parsedOutput.signature as Signature, transaction };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
addNewTrustingTransaction(
|
|
259
|
+
signerAgent: ControlledAccountOrAgent,
|
|
260
|
+
changes: JsonValue[],
|
|
261
|
+
madeAt: number,
|
|
262
|
+
meta: JsonObject | undefined,
|
|
263
|
+
) {
|
|
264
|
+
const stringifiedChanges = stableStringify(changes);
|
|
265
|
+
const stringifiedMeta = meta ? stableStringify(meta) : undefined;
|
|
266
|
+
const output = this.sessionLog.addNewTrustingTransaction(
|
|
267
|
+
stringifiedChanges,
|
|
268
|
+
signerAgent.currentSignerSecret(),
|
|
269
|
+
madeAt,
|
|
270
|
+
stringifiedMeta,
|
|
271
|
+
);
|
|
272
|
+
const transaction: TrustingTransaction = {
|
|
273
|
+
privacy: "trusting",
|
|
274
|
+
madeAt,
|
|
275
|
+
changes: stringifiedChanges,
|
|
276
|
+
meta: stringifiedMeta,
|
|
277
|
+
};
|
|
278
|
+
return { signature: output as Signature, transaction };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
decryptNextTransactionChangesJson(
|
|
282
|
+
txIndex: number,
|
|
283
|
+
keySecret: KeySecret,
|
|
284
|
+
): string {
|
|
285
|
+
return this.sessionLog.decryptNextTransactionChangesJson(
|
|
286
|
+
txIndex,
|
|
287
|
+
keySecret,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
decryptNextTransactionMetaJson(
|
|
292
|
+
txIndex: number,
|
|
293
|
+
keySecret: KeySecret,
|
|
294
|
+
): string | undefined {
|
|
295
|
+
return this.sessionLog.decryptNextTransactionMetaJson(txIndex, keySecret);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
free(): void {
|
|
299
|
+
this.sessionLog.uniffiDestroy();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
clone(): SessionLogImpl {
|
|
303
|
+
return new SessionLogAdapter(
|
|
304
|
+
this.sessionLog.cloneSessionLog() as SessionLog,
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
}
|
package/src/exports.ts
CHANGED
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
enablePermissionErrors,
|
|
7
7
|
type AvailableCoValueCore,
|
|
8
8
|
} from "./coValueCore/coValueCore.js";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
CoValueHeader,
|
|
11
|
+
CoValueUniqueness,
|
|
12
|
+
} from "./coValueCore/verifiedState.js";
|
|
10
13
|
import {
|
|
11
14
|
ControlledAccount,
|
|
12
15
|
ControlledAgent,
|
|
@@ -78,7 +81,9 @@ import { getDependedOnCoValuesFromRawData } from "./coValueCore/utils.js";
|
|
|
78
81
|
import {
|
|
79
82
|
CO_VALUE_LOADING_CONFIG,
|
|
80
83
|
TRANSACTION_CONFIG,
|
|
84
|
+
setCoValueLoadingMaxRetries,
|
|
81
85
|
setCoValueLoadingRetryDelay,
|
|
86
|
+
setCoValueLoadingTimeout,
|
|
82
87
|
setIncomingMessagesTimeBudget,
|
|
83
88
|
setMaxRecommendedTxSize,
|
|
84
89
|
} from "./config.js";
|
|
@@ -118,6 +123,8 @@ export const cojsonInternals = {
|
|
|
118
123
|
CO_VALUE_PRIORITY,
|
|
119
124
|
setIncomingMessagesTimeBudget,
|
|
120
125
|
setCoValueLoadingRetryDelay,
|
|
126
|
+
setCoValueLoadingMaxRetries,
|
|
127
|
+
setCoValueLoadingTimeout,
|
|
121
128
|
ConnectedPeerChannel,
|
|
122
129
|
textEncoder,
|
|
123
130
|
textDecoder,
|
|
@@ -186,6 +193,7 @@ export type {
|
|
|
186
193
|
AccountRole,
|
|
187
194
|
AvailableCoValueCore,
|
|
188
195
|
PeerState,
|
|
196
|
+
CoValueHeader,
|
|
189
197
|
};
|
|
190
198
|
|
|
191
199
|
export * from "./storage/index.js";
|
package/src/localNode.ts
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
} from "./coValues/group.js";
|
|
32
32
|
import { CO_VALUE_LOADING_CONFIG } from "./config.js";
|
|
33
33
|
import { AgentSecret, CryptoProvider } from "./crypto/crypto.js";
|
|
34
|
-
import { AgentID, RawCoID, SessionID, isAgentID } from "./ids.js";
|
|
34
|
+
import { AgentID, RawCoID, SessionID, isAgentID, isRawCoID } from "./ids.js";
|
|
35
35
|
import { logger } from "./logger.js";
|
|
36
36
|
import { StorageAPI } from "./storage/index.js";
|
|
37
37
|
import { Peer, PeerID, SyncManager } from "./sync.js";
|
|
@@ -387,13 +387,17 @@ export class LocalNode {
|
|
|
387
387
|
return coValue;
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
hasLoadingSources(id: RawCoID) {
|
|
391
|
+
return this.storage || this.syncManager.getServerPeers(id).length > 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
390
394
|
/** @internal */
|
|
391
395
|
async loadCoValueCore(
|
|
392
396
|
id: RawCoID,
|
|
393
397
|
skipLoadingFromPeer?: PeerID,
|
|
394
398
|
skipRetry?: boolean,
|
|
395
399
|
): Promise<CoValueCore> {
|
|
396
|
-
if (
|
|
400
|
+
if (!isRawCoID(id)) {
|
|
397
401
|
throw new TypeError(
|
|
398
402
|
`Trying to load CoValue with invalid id ${Array.isArray(id) ? JSON.stringify(id) : id}`,
|
|
399
403
|
);
|
|
@@ -421,6 +425,8 @@ export class LocalNode {
|
|
|
421
425
|
const peers = this.syncManager.getServerPeers(id, skipLoadingFromPeer);
|
|
422
426
|
|
|
423
427
|
if (!this.storage && peers.length === 0) {
|
|
428
|
+
// Flags the coValue as unavailable
|
|
429
|
+
coValue.markNotFoundInPeer("storage");
|
|
424
430
|
return coValue;
|
|
425
431
|
}
|
|
426
432
|
|