cojson 0.17.8 → 0.17.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 +13 -0
- package/dist/coValueCore/SessionMap.d.ts +44 -0
- package/dist/coValueCore/SessionMap.d.ts.map +1 -0
- package/dist/coValueCore/SessionMap.js +118 -0
- package/dist/coValueCore/SessionMap.js.map +1 -0
- package/dist/coValueCore/coValueCore.d.ts +1 -0
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +40 -61
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +14 -18
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +23 -86
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/account.d.ts +4 -0
- package/dist/coValues/account.d.ts.map +1 -1
- package/dist/coValues/account.js +24 -4
- package/dist/coValues/account.js.map +1 -1
- package/dist/crypto/PureJSCrypto.d.ts +31 -3
- package/dist/crypto/PureJSCrypto.d.ts.map +1 -1
- package/dist/crypto/PureJSCrypto.js +112 -0
- package/dist/crypto/PureJSCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.d.ts +23 -4
- package/dist/crypto/WasmCrypto.d.ts.map +1 -1
- package/dist/crypto/WasmCrypto.js +44 -2
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/crypto.d.ts +17 -1
- package/dist/crypto/crypto.d.ts.map +1 -1
- package/dist/crypto/crypto.js.map +1 -1
- package/dist/localNode.d.ts +1 -0
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +10 -5
- package/dist/localNode.js.map +1 -1
- package/dist/sync.d.ts +2 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +8 -1
- package/dist/sync.js.map +1 -1
- package/dist/tests/PureJSCrypto.test.d.ts +2 -0
- package/dist/tests/PureJSCrypto.test.d.ts.map +1 -0
- package/dist/tests/PureJSCrypto.test.js +88 -0
- package/dist/tests/PureJSCrypto.test.js.map +1 -0
- package/dist/tests/WasmCrypto.test.d.ts +2 -0
- package/dist/tests/WasmCrypto.test.d.ts.map +1 -0
- package/dist/tests/WasmCrypto.test.js +88 -0
- package/dist/tests/WasmCrypto.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +62 -187
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coreWasm.test.d.ts +2 -0
- package/dist/tests/coreWasm.test.d.ts.map +1 -0
- package/dist/tests/coreWasm.test.js +80 -0
- package/dist/tests/coreWasm.test.js.map +1 -0
- package/dist/tests/sync.test.js +19 -1
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts +3 -0
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +4 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +3 -3
- package/src/coValueCore/SessionMap.ts +230 -0
- package/src/coValueCore/coValueCore.ts +66 -91
- package/src/coValueCore/verifiedState.ts +60 -129
- package/src/coValues/account.ts +28 -4
- package/src/crypto/PureJSCrypto.ts +202 -2
- package/src/crypto/WasmCrypto.ts +95 -4
- package/src/crypto/crypto.ts +38 -1
- package/src/localNode.ts +18 -10
- package/src/sync.ts +10 -0
- package/src/tests/PureJSCrypto.test.ts +130 -0
- package/src/tests/WasmCrypto.test.ts +130 -0
- package/src/tests/coValueCore.test.ts +84 -292
- package/src/tests/coreWasm.test.ts +142 -0
- package/src/tests/sync.test.ts +32 -0
- package/src/tests/testUtils.ts +9 -1
|
@@ -27,6 +27,7 @@ import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfrom
|
|
|
27
27
|
import { expectGroup } from "../typeUtils/expectGroup.js";
|
|
28
28
|
import { getDependedOnCoValuesFromRawData } from "./utils.js";
|
|
29
29
|
import { CoValueHeader, Transaction, VerifiedState } from "./verifiedState.js";
|
|
30
|
+
import { SessionMap } from "./SessionMap.js";
|
|
30
31
|
|
|
31
32
|
export function idforHeader(
|
|
32
33
|
header: CoValueHeader,
|
|
@@ -95,12 +96,7 @@ export class CoValueCore {
|
|
|
95
96
|
this.crypto = node.crypto;
|
|
96
97
|
if ("header" in init) {
|
|
97
98
|
this.id = idforHeader(init.header, node.crypto);
|
|
98
|
-
this._verified = new VerifiedState(
|
|
99
|
-
this.id,
|
|
100
|
-
node.crypto,
|
|
101
|
-
init.header,
|
|
102
|
-
new Map(),
|
|
103
|
-
);
|
|
99
|
+
this._verified = new VerifiedState(this.id, node.crypto, init.header);
|
|
104
100
|
} else {
|
|
105
101
|
this.id = init.id;
|
|
106
102
|
this._verified = null;
|
|
@@ -298,7 +294,7 @@ export class CoValueCore {
|
|
|
298
294
|
this.id,
|
|
299
295
|
this.node.crypto,
|
|
300
296
|
header,
|
|
301
|
-
new
|
|
297
|
+
new SessionMap(this.id, this.node.crypto),
|
|
302
298
|
streamingKnownState,
|
|
303
299
|
);
|
|
304
300
|
|
|
@@ -467,19 +463,7 @@ export class CoValueCore {
|
|
|
467
463
|
);
|
|
468
464
|
|
|
469
465
|
if (result.isOk()) {
|
|
470
|
-
|
|
471
|
-
this._cachedContent &&
|
|
472
|
-
"processNewTransactions" in this._cachedContent &&
|
|
473
|
-
typeof this._cachedContent.processNewTransactions === "function"
|
|
474
|
-
) {
|
|
475
|
-
this._cachedContent.processNewTransactions();
|
|
476
|
-
} else {
|
|
477
|
-
this._cachedContent = undefined;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
this._cachedDependentOn = undefined;
|
|
481
|
-
|
|
482
|
-
this.notifyUpdate(notifyMode);
|
|
466
|
+
this.updateContentAndNotifyUpdate(notifyMode);
|
|
483
467
|
}
|
|
484
468
|
|
|
485
469
|
return result;
|
|
@@ -489,6 +473,22 @@ export class CoValueCore {
|
|
|
489
473
|
deferredUpdates = 0;
|
|
490
474
|
nextDeferredNotify: Promise<void> | undefined;
|
|
491
475
|
|
|
476
|
+
updateContentAndNotifyUpdate(notifyMode: "immediate" | "deferred") {
|
|
477
|
+
if (
|
|
478
|
+
this._cachedContent &&
|
|
479
|
+
"processNewTransactions" in this._cachedContent &&
|
|
480
|
+
typeof this._cachedContent.processNewTransactions === "function"
|
|
481
|
+
) {
|
|
482
|
+
this._cachedContent.processNewTransactions();
|
|
483
|
+
} else {
|
|
484
|
+
this._cachedContent = undefined;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
this._cachedDependentOn = undefined;
|
|
488
|
+
|
|
489
|
+
this.notifyUpdate(notifyMode);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
492
|
notifyUpdate(notifyMode: "immediate" | "deferred") {
|
|
493
493
|
if (this.listeners.size === 0) {
|
|
494
494
|
return;
|
|
@@ -556,9 +556,18 @@ export class CoValueCore {
|
|
|
556
556
|
);
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
-
|
|
559
|
+
// This is an ugly hack to get a unique but stable session ID for editing the current account
|
|
560
|
+
const sessionID =
|
|
561
|
+
this.verified.header.meta?.type === "account"
|
|
562
|
+
? (this.node.currentSessionID.replace(
|
|
563
|
+
this.node.getCurrentAgent().id,
|
|
564
|
+
this.node.getCurrentAgent().currentAgentID(),
|
|
565
|
+
) as SessionID)
|
|
566
|
+
: this.node.currentSessionID;
|
|
567
|
+
|
|
568
|
+
const signerAgent = this.node.getCurrentAgent();
|
|
560
569
|
|
|
561
|
-
let transaction: Transaction;
|
|
570
|
+
let result: { signature: Signature; transaction: Transaction };
|
|
562
571
|
|
|
563
572
|
if (privacy === "private") {
|
|
564
573
|
const { secret: keySecret, id: keyID } = this.getCurrentReadKey();
|
|
@@ -567,69 +576,42 @@ export class CoValueCore {
|
|
|
567
576
|
throw new Error("Can't make transaction without read key secret");
|
|
568
577
|
}
|
|
569
578
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
579
|
+
result = this.verified.makeNewPrivateTransaction(
|
|
580
|
+
sessionID,
|
|
581
|
+
signerAgent,
|
|
582
|
+
changes,
|
|
583
|
+
keyID,
|
|
584
|
+
keySecret,
|
|
585
|
+
);
|
|
576
586
|
|
|
577
|
-
transaction
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
keyUsed: keyID,
|
|
581
|
-
encryptedChanges: encrypted,
|
|
582
|
-
};
|
|
587
|
+
if (result.transaction.privacy === "private") {
|
|
588
|
+
this._decryptionCache[result.transaction.encryptedChanges] = changes;
|
|
589
|
+
}
|
|
583
590
|
} else {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
changes
|
|
588
|
-
|
|
591
|
+
result = this.verified.makeNewTrustingTransaction(
|
|
592
|
+
sessionID,
|
|
593
|
+
signerAgent,
|
|
594
|
+
changes,
|
|
595
|
+
);
|
|
589
596
|
}
|
|
590
597
|
|
|
591
|
-
|
|
592
|
-
const sessionID =
|
|
593
|
-
this.verified.header.meta?.type === "account"
|
|
594
|
-
? (this.node.currentSessionID.replace(
|
|
595
|
-
this.node.getCurrentAgent().id,
|
|
596
|
-
this.node.getCurrentAgent().currentAgentID(),
|
|
597
|
-
) as SessionID)
|
|
598
|
-
: this.node.currentSessionID;
|
|
598
|
+
const { transaction, signature } = result;
|
|
599
599
|
|
|
600
|
-
|
|
601
|
-
this.verified.expectedNewHashAfter(sessionID, [transaction]);
|
|
600
|
+
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
|
602
601
|
|
|
603
|
-
const
|
|
604
|
-
|
|
605
|
-
expectedNewHash,
|
|
606
|
-
);
|
|
602
|
+
const session = this.verified.sessions.get(sessionID);
|
|
603
|
+
const txIdx = session ? session.transactions.length - 1 : 0;
|
|
607
604
|
|
|
608
|
-
|
|
605
|
+
this.updateContentAndNotifyUpdate("immediate");
|
|
606
|
+
this.node.syncManager.syncLocalTransaction(
|
|
607
|
+
this.verified,
|
|
608
|
+
transaction,
|
|
609
609
|
sessionID,
|
|
610
|
-
[transaction],
|
|
611
|
-
expectedNewHash,
|
|
612
610
|
signature,
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
newStreamingHash,
|
|
616
|
-
)._unsafeUnwrap({ withStackTrace: true });
|
|
617
|
-
|
|
618
|
-
if (success) {
|
|
619
|
-
const session = this.verified.sessions.get(sessionID);
|
|
620
|
-
const txIdx = session ? session.transactions.length - 1 : 0;
|
|
621
|
-
|
|
622
|
-
this.node.syncManager.recordTransactionsSize([transaction], "local");
|
|
623
|
-
this.node.syncManager.syncLocalTransaction(
|
|
624
|
-
this.verified,
|
|
625
|
-
transaction,
|
|
626
|
-
sessionID,
|
|
627
|
-
signature,
|
|
628
|
-
txIdx,
|
|
629
|
-
);
|
|
630
|
-
}
|
|
611
|
+
txIdx,
|
|
612
|
+
);
|
|
631
613
|
|
|
632
|
-
return
|
|
614
|
+
return true;
|
|
633
615
|
}
|
|
634
616
|
|
|
635
617
|
getCurrentContent(options?: { ignorePrivateTransactions: true }): RawCoValue {
|
|
@@ -658,6 +640,12 @@ export class CoValueCore {
|
|
|
658
640
|
ignorePrivateTransactions: boolean;
|
|
659
641
|
knownTransactions?: CoValueKnownState["sessions"];
|
|
660
642
|
}): DecryptedTransaction[] {
|
|
643
|
+
if (!this.verified) {
|
|
644
|
+
throw new Error(
|
|
645
|
+
"CoValueCore: getValidTransactions called on coValue without verified state",
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
661
649
|
const validTransactions = determineValidTransactions(
|
|
662
650
|
this,
|
|
663
651
|
options?.knownTransactions,
|
|
@@ -701,25 +689,12 @@ export class CoValueCore {
|
|
|
701
689
|
let decryptedChanges = this._decryptionCache[tx.encryptedChanges];
|
|
702
690
|
|
|
703
691
|
if (!decryptedChanges) {
|
|
704
|
-
|
|
705
|
-
|
|
692
|
+
decryptedChanges = this.verified.decryptTransaction(
|
|
693
|
+
txID.sessionID,
|
|
694
|
+
txID.txIndex,
|
|
706
695
|
readKey,
|
|
707
|
-
{
|
|
708
|
-
in: this.id,
|
|
709
|
-
tx: txID,
|
|
710
|
-
},
|
|
711
696
|
);
|
|
712
697
|
|
|
713
|
-
try {
|
|
714
|
-
decryptedChanges = decryptedString && parseJSON(decryptedString);
|
|
715
|
-
} catch (e) {
|
|
716
|
-
logger.error("Failed to parse private transaction on " + this.id, {
|
|
717
|
-
err: e,
|
|
718
|
-
txID,
|
|
719
|
-
changes: decryptedString?.slice(0, 50),
|
|
720
|
-
});
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
698
|
this._decryptionCache[tx.encryptedChanges] = decryptedChanges;
|
|
724
699
|
}
|
|
725
700
|
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
Encrypted,
|
|
11
11
|
Hash,
|
|
12
12
|
KeyID,
|
|
13
|
+
KeySecret,
|
|
13
14
|
Signature,
|
|
14
15
|
SignerID,
|
|
15
16
|
StreamingHash,
|
|
@@ -21,6 +22,8 @@ import { PermissionsDef as RulesetDef } from "../permissions.js";
|
|
|
21
22
|
import { CoValueKnownState, NewContentMessage } from "../sync.js";
|
|
22
23
|
import { InvalidHashError, InvalidSignatureError } from "./coValueCore.js";
|
|
23
24
|
import { TryAddTransactionsError } from "./coValueCore.js";
|
|
25
|
+
import { SessionLog, SessionMap } from "./SessionMap.js";
|
|
26
|
+
import { ControlledAccountOrAgent } from "../coValues/account.js";
|
|
24
27
|
|
|
25
28
|
export type CoValueHeader = {
|
|
26
29
|
type: AnyRawCoValue["type"];
|
|
@@ -48,20 +51,11 @@ export type TrustingTransaction = {
|
|
|
48
51
|
|
|
49
52
|
export type Transaction = PrivateTransaction | TrustingTransaction;
|
|
50
53
|
|
|
51
|
-
type SessionLog = {
|
|
52
|
-
readonly transactions: Transaction[];
|
|
53
|
-
streamingHash?: StreamingHash;
|
|
54
|
-
readonly signatureAfter: { [txIdx: number]: Signature | undefined };
|
|
55
|
-
lastSignature: Signature;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export type ValidatedSessions = Map<SessionID, SessionLog>;
|
|
59
|
-
|
|
60
54
|
export class VerifiedState {
|
|
61
55
|
readonly id: RawCoID;
|
|
62
56
|
readonly crypto: CryptoProvider;
|
|
63
57
|
readonly header: CoValueHeader;
|
|
64
|
-
readonly sessions:
|
|
58
|
+
readonly sessions: SessionMap;
|
|
65
59
|
private _cachedKnownState?: CoValueKnownState;
|
|
66
60
|
private _cachedNewContentSinceEmpty: NewContentMessage[] | undefined;
|
|
67
61
|
private streamingKnownState?: CoValueKnownState["sessions"];
|
|
@@ -71,35 +65,25 @@ export class VerifiedState {
|
|
|
71
65
|
id: RawCoID,
|
|
72
66
|
crypto: CryptoProvider,
|
|
73
67
|
header: CoValueHeader,
|
|
74
|
-
sessions
|
|
68
|
+
sessions?: SessionMap,
|
|
75
69
|
streamingKnownState?: CoValueKnownState["sessions"],
|
|
76
70
|
) {
|
|
77
71
|
this.id = id;
|
|
78
72
|
this.crypto = crypto;
|
|
79
73
|
this.header = header;
|
|
80
|
-
this.sessions = sessions;
|
|
74
|
+
this.sessions = sessions ?? new SessionMap(id, crypto);
|
|
81
75
|
this.streamingKnownState = streamingKnownState
|
|
82
76
|
? { ...streamingKnownState }
|
|
83
77
|
: undefined;
|
|
84
78
|
}
|
|
85
79
|
|
|
86
80
|
clone(): VerifiedState {
|
|
87
|
-
// do a deep clone, including the sessions
|
|
88
|
-
const clonedSessions = new Map();
|
|
89
|
-
for (let [sessionID, sessionLog] of this.sessions) {
|
|
90
|
-
clonedSessions.set(sessionID, {
|
|
91
|
-
lastSignature: sessionLog.lastSignature,
|
|
92
|
-
streamingHash: sessionLog.streamingHash?.clone(),
|
|
93
|
-
signatureAfter: { ...sessionLog.signatureAfter },
|
|
94
|
-
transactions: sessionLog.transactions.slice(),
|
|
95
|
-
} satisfies SessionLog);
|
|
96
|
-
}
|
|
97
81
|
return new VerifiedState(
|
|
98
82
|
this.id,
|
|
99
83
|
this.crypto,
|
|
100
84
|
this.header,
|
|
101
|
-
|
|
102
|
-
this.streamingKnownState,
|
|
85
|
+
this.sessions.clone(),
|
|
86
|
+
this.streamingKnownState ? { ...this.streamingKnownState } : undefined,
|
|
103
87
|
);
|
|
104
88
|
}
|
|
105
89
|
|
|
@@ -112,130 +96,69 @@ export class VerifiedState {
|
|
|
112
96
|
skipVerify: boolean = false,
|
|
113
97
|
givenNewStreamingHash?: StreamingHash,
|
|
114
98
|
): Result<true, TryAddTransactionsError> {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
} else {
|
|
123
|
-
const { expectedNewHash, newStreamingHash } = this.expectedNewHashAfter(
|
|
124
|
-
sessionID,
|
|
125
|
-
newTransactions,
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
if (givenExpectedNewHash && givenExpectedNewHash !== expectedNewHash) {
|
|
129
|
-
return err({
|
|
130
|
-
type: "InvalidHash",
|
|
131
|
-
id: this.id,
|
|
132
|
-
expectedNewHash,
|
|
133
|
-
givenExpectedNewHash,
|
|
134
|
-
} satisfies InvalidHashError);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (!this.crypto.verify(newSignature, expectedNewHash, signerID)) {
|
|
138
|
-
return err({
|
|
139
|
-
type: "InvalidSignature",
|
|
140
|
-
id: this.id,
|
|
141
|
-
newSignature,
|
|
142
|
-
sessionID,
|
|
143
|
-
signerID,
|
|
144
|
-
} satisfies InvalidSignatureError);
|
|
145
|
-
}
|
|
99
|
+
const result = this.sessions.addTransaction(
|
|
100
|
+
sessionID,
|
|
101
|
+
signerID,
|
|
102
|
+
newTransactions,
|
|
103
|
+
newSignature,
|
|
104
|
+
skipVerify,
|
|
105
|
+
);
|
|
146
106
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
newSignature,
|
|
151
|
-
newStreamingHash,
|
|
152
|
-
);
|
|
107
|
+
if (result.isOk()) {
|
|
108
|
+
this._cachedNewContentSinceEmpty = undefined;
|
|
109
|
+
this._cachedKnownState = undefined;
|
|
153
110
|
}
|
|
154
111
|
|
|
155
|
-
return
|
|
112
|
+
return result;
|
|
156
113
|
}
|
|
157
114
|
|
|
158
|
-
|
|
159
|
-
|
|
115
|
+
makeNewTrustingTransaction(
|
|
116
|
+
sessionID: SessionID,
|
|
117
|
+
signerAgent: ControlledAccountOrAgent,
|
|
118
|
+
changes: JsonValue[],
|
|
119
|
+
) {
|
|
120
|
+
const result = this.sessions.makeNewTrustingTransaction(
|
|
121
|
+
sessionID,
|
|
122
|
+
signerAgent,
|
|
123
|
+
changes,
|
|
124
|
+
);
|
|
160
125
|
|
|
161
|
-
|
|
126
|
+
this._cachedNewContentSinceEmpty = undefined;
|
|
127
|
+
this._cachedKnownState = undefined;
|
|
162
128
|
|
|
163
|
-
return
|
|
164
|
-
(max, idx) => Math.max(max, parseInt(idx)),
|
|
165
|
-
-1,
|
|
166
|
-
);
|
|
129
|
+
return result;
|
|
167
130
|
}
|
|
168
131
|
|
|
169
|
-
|
|
132
|
+
makeNewPrivateTransaction(
|
|
170
133
|
sessionID: SessionID,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
134
|
+
signerAgent: ControlledAccountOrAgent,
|
|
135
|
+
changes: JsonValue[],
|
|
136
|
+
keyID: KeyID,
|
|
137
|
+
keySecret: KeySecret,
|
|
174
138
|
) {
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const signatureAfter = sessionLog?.signatureAfter ?? {};
|
|
183
|
-
const lastInbetweenSignatureIdx =
|
|
184
|
-
this.getLastSignatureCheckpoint(sessionID);
|
|
185
|
-
|
|
186
|
-
const sizeOfTxsSinceLastInbetweenSignature = transactions
|
|
187
|
-
.slice(lastInbetweenSignatureIdx + 1)
|
|
188
|
-
.reduce((sum, tx) => sum + getTransactionSize(tx), 0);
|
|
189
|
-
|
|
190
|
-
if (exceedsRecommendedSize(sizeOfTxsSinceLastInbetweenSignature)) {
|
|
191
|
-
signatureAfter[transactions.length - 1] = newSignature;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
this.sessions.set(sessionID, {
|
|
195
|
-
transactions,
|
|
196
|
-
streamingHash: newStreamingHash,
|
|
197
|
-
lastSignature: newSignature,
|
|
198
|
-
signatureAfter: signatureAfter,
|
|
199
|
-
});
|
|
139
|
+
const result = this.sessions.makeNewPrivateTransaction(
|
|
140
|
+
sessionID,
|
|
141
|
+
signerAgent,
|
|
142
|
+
changes,
|
|
143
|
+
keyID,
|
|
144
|
+
keySecret,
|
|
145
|
+
);
|
|
200
146
|
|
|
201
147
|
this._cachedNewContentSinceEmpty = undefined;
|
|
202
148
|
this._cachedKnownState = undefined;
|
|
149
|
+
|
|
150
|
+
return result;
|
|
203
151
|
}
|
|
204
152
|
|
|
205
|
-
|
|
206
|
-
sessionID: SessionID,
|
|
207
|
-
newTransactions: Transaction[],
|
|
208
|
-
): { expectedNewHash: Hash; newStreamingHash: StreamingHash } {
|
|
153
|
+
getLastSignatureCheckpoint(sessionID: SessionID): number {
|
|
209
154
|
const sessionLog = this.sessions.get(sessionID);
|
|
210
155
|
|
|
211
|
-
if (!sessionLog?.
|
|
212
|
-
const streamingHash = new StreamingHash(this.crypto);
|
|
213
|
-
const oldTransactions = sessionLog?.transactions ?? [];
|
|
214
|
-
|
|
215
|
-
for (const transaction of oldTransactions) {
|
|
216
|
-
streamingHash.update(transaction);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
for (const transaction of newTransactions) {
|
|
220
|
-
streamingHash.update(transaction);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
return {
|
|
224
|
-
expectedNewHash: streamingHash.digest(),
|
|
225
|
-
newStreamingHash: streamingHash,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const streamingHash = sessionLog.streamingHash.clone();
|
|
230
|
-
|
|
231
|
-
for (const transaction of newTransactions) {
|
|
232
|
-
streamingHash.update(transaction);
|
|
233
|
-
}
|
|
156
|
+
if (!sessionLog?.signatureAfter) return -1;
|
|
234
157
|
|
|
235
|
-
return
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
158
|
+
return Object.keys(sessionLog.signatureAfter).reduce(
|
|
159
|
+
(max, idx) => Math.max(max, parseInt(idx)),
|
|
160
|
+
-1,
|
|
161
|
+
);
|
|
239
162
|
}
|
|
240
163
|
|
|
241
164
|
newContentSince(
|
|
@@ -424,6 +347,14 @@ export class VerifiedState {
|
|
|
424
347
|
sessions,
|
|
425
348
|
};
|
|
426
349
|
}
|
|
350
|
+
|
|
351
|
+
decryptTransaction(
|
|
352
|
+
sessionID: SessionID,
|
|
353
|
+
txIndex: number,
|
|
354
|
+
keySecret: KeySecret,
|
|
355
|
+
): JsonValue[] | undefined {
|
|
356
|
+
return this.sessions.decryptTransaction(sessionID, txIndex, keySecret);
|
|
357
|
+
}
|
|
427
358
|
}
|
|
428
359
|
|
|
429
360
|
function getNextKnownSignatureIdx(
|
package/src/coValues/account.ts
CHANGED
|
@@ -92,6 +92,10 @@ export class ControlledAccount implements ControlledAccountOrAgent {
|
|
|
92
92
|
account: RawAccount<AccountMeta>;
|
|
93
93
|
agentSecret: AgentSecret;
|
|
94
94
|
_cachedCurrentAgentID: AgentID | undefined;
|
|
95
|
+
_cachedCurrentSignerID: SignerID | undefined;
|
|
96
|
+
_cachedCurrentSignerSecret: SignerSecret | undefined;
|
|
97
|
+
_cachedCurrentSealerID: SealerID | undefined;
|
|
98
|
+
_cachedCurrentSealerSecret: SealerSecret | undefined;
|
|
95
99
|
crypto: CryptoProvider;
|
|
96
100
|
|
|
97
101
|
constructor(account: RawAccount<AccountMeta>, agentSecret: AgentSecret) {
|
|
@@ -114,19 +118,39 @@ export class ControlledAccount implements ControlledAccountOrAgent {
|
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
currentSignerID() {
|
|
117
|
-
|
|
121
|
+
if (this._cachedCurrentSignerID) {
|
|
122
|
+
return this._cachedCurrentSignerID;
|
|
123
|
+
}
|
|
124
|
+
const signerID = this.crypto.getAgentSignerID(this.currentAgentID());
|
|
125
|
+
this._cachedCurrentSignerID = signerID;
|
|
126
|
+
return signerID;
|
|
118
127
|
}
|
|
119
128
|
|
|
120
129
|
currentSignerSecret(): SignerSecret {
|
|
121
|
-
|
|
130
|
+
if (this._cachedCurrentSignerSecret) {
|
|
131
|
+
return this._cachedCurrentSignerSecret;
|
|
132
|
+
}
|
|
133
|
+
const signerSecret = this.crypto.getAgentSignerSecret(this.agentSecret);
|
|
134
|
+
this._cachedCurrentSignerSecret = signerSecret;
|
|
135
|
+
return signerSecret;
|
|
122
136
|
}
|
|
123
137
|
|
|
124
138
|
currentSealerID() {
|
|
125
|
-
|
|
139
|
+
if (this._cachedCurrentSealerID) {
|
|
140
|
+
return this._cachedCurrentSealerID;
|
|
141
|
+
}
|
|
142
|
+
const sealerID = this.crypto.getAgentSealerID(this.currentAgentID());
|
|
143
|
+
this._cachedCurrentSealerID = sealerID;
|
|
144
|
+
return sealerID;
|
|
126
145
|
}
|
|
127
146
|
|
|
128
147
|
currentSealerSecret(): SealerSecret {
|
|
129
|
-
|
|
148
|
+
if (this._cachedCurrentSealerSecret) {
|
|
149
|
+
return this._cachedCurrentSealerSecret;
|
|
150
|
+
}
|
|
151
|
+
const sealerSecret = this.crypto.getAgentSealerSecret(this.agentSecret);
|
|
152
|
+
this._cachedCurrentSealerSecret = sealerSecret;
|
|
153
|
+
return sealerSecret;
|
|
130
154
|
}
|
|
131
155
|
}
|
|
132
156
|
|