cojson 0.17.9 → 0.17.11

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 (86) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +18 -0
  3. package/dist/coValueCore/SessionMap.d.ts +45 -0
  4. package/dist/coValueCore/SessionMap.d.ts.map +1 -0
  5. package/dist/coValueCore/SessionMap.js +118 -0
  6. package/dist/coValueCore/SessionMap.js.map +1 -0
  7. package/dist/coValueCore/coValueCore.d.ts +10 -4
  8. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  9. package/dist/coValueCore/coValueCore.js +55 -68
  10. package/dist/coValueCore/coValueCore.js.map +1 -1
  11. package/dist/coValueCore/verifiedState.d.ts +15 -19
  12. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  13. package/dist/coValueCore/verifiedState.js +24 -87
  14. package/dist/coValueCore/verifiedState.js.map +1 -1
  15. package/dist/coValues/account.d.ts +4 -0
  16. package/dist/coValues/account.d.ts.map +1 -1
  17. package/dist/coValues/account.js +24 -4
  18. package/dist/coValues/account.js.map +1 -1
  19. package/dist/coValues/group.d.ts.map +1 -1
  20. package/dist/coValues/group.js +6 -2
  21. package/dist/coValues/group.js.map +1 -1
  22. package/dist/crypto/PureJSCrypto.d.ts +31 -3
  23. package/dist/crypto/PureJSCrypto.d.ts.map +1 -1
  24. package/dist/crypto/PureJSCrypto.js +115 -0
  25. package/dist/crypto/PureJSCrypto.js.map +1 -1
  26. package/dist/crypto/WasmCrypto.d.ts +23 -4
  27. package/dist/crypto/WasmCrypto.d.ts.map +1 -1
  28. package/dist/crypto/WasmCrypto.js +44 -2
  29. package/dist/crypto/WasmCrypto.js.map +1 -1
  30. package/dist/crypto/crypto.d.ts +17 -1
  31. package/dist/crypto/crypto.d.ts.map +1 -1
  32. package/dist/crypto/crypto.js.map +1 -1
  33. package/dist/localNode.d.ts +1 -0
  34. package/dist/localNode.d.ts.map +1 -1
  35. package/dist/localNode.js +10 -5
  36. package/dist/localNode.js.map +1 -1
  37. package/dist/permissions.d.ts +17 -1
  38. package/dist/permissions.d.ts.map +1 -1
  39. package/dist/permissions.js.map +1 -1
  40. package/dist/sync.d.ts.map +1 -1
  41. package/dist/sync.js +55 -49
  42. package/dist/sync.js.map +1 -1
  43. package/dist/tests/PureJSCrypto.test.d.ts +2 -0
  44. package/dist/tests/PureJSCrypto.test.d.ts.map +1 -0
  45. package/dist/tests/PureJSCrypto.test.js +102 -0
  46. package/dist/tests/PureJSCrypto.test.js.map +1 -0
  47. package/dist/tests/WasmCrypto.test.d.ts +2 -0
  48. package/dist/tests/WasmCrypto.test.d.ts.map +1 -0
  49. package/dist/tests/WasmCrypto.test.js +88 -0
  50. package/dist/tests/WasmCrypto.test.js.map +1 -0
  51. package/dist/tests/coValueCore.test.js +62 -187
  52. package/dist/tests/coValueCore.test.js.map +1 -1
  53. package/dist/tests/coreWasm.test.d.ts +2 -0
  54. package/dist/tests/coreWasm.test.d.ts.map +1 -0
  55. package/dist/tests/coreWasm.test.js +80 -0
  56. package/dist/tests/coreWasm.test.js.map +1 -0
  57. package/dist/tests/group.addMember.test.js +6 -11
  58. package/dist/tests/group.addMember.test.js.map +1 -1
  59. package/dist/tests/sync.load.test.js +40 -1
  60. package/dist/tests/sync.load.test.js.map +1 -1
  61. package/dist/tests/sync.test.js +1 -1
  62. package/dist/tests/sync.test.js.map +1 -1
  63. package/dist/tests/testUtils.d.ts +3 -0
  64. package/dist/tests/testUtils.d.ts.map +1 -1
  65. package/dist/tests/testUtils.js +4 -1
  66. package/dist/tests/testUtils.js.map +1 -1
  67. package/package.json +3 -3
  68. package/src/coValueCore/SessionMap.ts +229 -0
  69. package/src/coValueCore/coValueCore.ts +106 -121
  70. package/src/coValueCore/verifiedState.ts +61 -132
  71. package/src/coValues/account.ts +28 -4
  72. package/src/coValues/group.ts +10 -2
  73. package/src/crypto/PureJSCrypto.ts +206 -2
  74. package/src/crypto/WasmCrypto.ts +95 -4
  75. package/src/crypto/crypto.ts +38 -1
  76. package/src/localNode.ts +18 -10
  77. package/src/permissions.ts +17 -1
  78. package/src/sync.ts +63 -59
  79. package/src/tests/PureJSCrypto.test.ts +153 -0
  80. package/src/tests/WasmCrypto.test.ts +128 -0
  81. package/src/tests/coValueCore.test.ts +81 -293
  82. package/src/tests/coreWasm.test.ts +142 -0
  83. package/src/tests/group.addMember.test.ts +69 -63
  84. package/src/tests/sync.load.test.ts +52 -0
  85. package/src/tests/sync.test.ts +0 -2
  86. package/src/tests/testUtils.ts +9 -1
@@ -0,0 +1,229 @@
1
+ import { Result, err, ok } from "neverthrow";
2
+ import { ControlledAccountOrAgent } from "../coValues/account.js";
3
+ import type {
4
+ CryptoProvider,
5
+ Hash,
6
+ KeyID,
7
+ KeySecret,
8
+ SessionLogImpl,
9
+ Signature,
10
+ SignerID,
11
+ } from "../crypto/crypto.js";
12
+ import { RawCoID, SessionID } from "../ids.js";
13
+ import { parseJSON, stableStringify, Stringified } from "../jsonStringify.js";
14
+ import { JsonValue } from "../jsonValue.js";
15
+ import { CoValueKnownState } from "../sync.js";
16
+ import { TryAddTransactionsError } from "./coValueCore.js";
17
+ import { Transaction } from "./verifiedState.js";
18
+ import { exceedsRecommendedSize } from "../coValueContentMessage.js";
19
+
20
+ export type SessionLog = {
21
+ signerID?: SignerID;
22
+ impl: SessionLogImpl;
23
+ transactions: Transaction[];
24
+ lastSignature: Signature | undefined;
25
+ signatureAfter: { [txIdx: number]: Signature | undefined };
26
+ txSizeSinceLastInbetweenSignature: number;
27
+ };
28
+
29
+ export class SessionMap {
30
+ sessions: Map<SessionID, SessionLog> = new Map();
31
+
32
+ constructor(
33
+ private readonly id: RawCoID,
34
+ private readonly crypto: CryptoProvider,
35
+ ) {}
36
+
37
+ get(sessionID: SessionID): SessionLog | undefined {
38
+ return this.sessions.get(sessionID);
39
+ }
40
+
41
+ private getOrCreateSessionLog(
42
+ sessionID: SessionID,
43
+ signerID?: SignerID,
44
+ ): SessionLog {
45
+ let sessionLog = this.sessions.get(sessionID);
46
+ if (!sessionLog) {
47
+ sessionLog = {
48
+ signerID,
49
+ impl: this.crypto.createSessionLog(this.id, sessionID, signerID),
50
+ transactions: [],
51
+ lastSignature: undefined,
52
+ signatureAfter: {},
53
+ txSizeSinceLastInbetweenSignature: 0,
54
+ };
55
+ this.sessions.set(sessionID, sessionLog);
56
+ }
57
+
58
+ return sessionLog;
59
+ }
60
+
61
+ signerID: SignerID | undefined;
62
+ addTransaction(
63
+ sessionID: SessionID,
64
+ signerID: SignerID | undefined,
65
+ newTransactions: Transaction[],
66
+ newSignature: Signature,
67
+ skipVerify: boolean = false,
68
+ ): Result<true, TryAddTransactionsError> {
69
+ const sessionLog = this.getOrCreateSessionLog(sessionID, signerID);
70
+
71
+ try {
72
+ sessionLog.impl.tryAdd(newTransactions, newSignature, skipVerify);
73
+
74
+ this.addTransactionsToJsLog(sessionLog, newTransactions, newSignature);
75
+
76
+ return ok(true as const);
77
+ } catch (e) {
78
+ return err({
79
+ type: "InvalidSignature",
80
+ id: this.id,
81
+ sessionID,
82
+ newSignature,
83
+ signerID,
84
+ } satisfies TryAddTransactionsError);
85
+ }
86
+ }
87
+
88
+ makeNewPrivateTransaction(
89
+ sessionID: SessionID,
90
+ signerAgent: ControlledAccountOrAgent,
91
+ changes: JsonValue[],
92
+ keyID: KeyID,
93
+ keySecret: KeySecret,
94
+ ): { signature: Signature; transaction: Transaction } {
95
+ const sessionLog = this.getOrCreateSessionLog(
96
+ sessionID,
97
+ signerAgent.currentSignerID(),
98
+ );
99
+ const madeAt = Date.now();
100
+
101
+ const result = sessionLog.impl.addNewPrivateTransaction(
102
+ signerAgent,
103
+ changes,
104
+ keyID,
105
+ keySecret,
106
+ madeAt,
107
+ );
108
+
109
+ this.addTransactionsToJsLog(
110
+ sessionLog,
111
+ [result.transaction],
112
+ result.signature,
113
+ );
114
+
115
+ return result;
116
+ }
117
+
118
+ makeNewTrustingTransaction(
119
+ sessionID: SessionID,
120
+ signerAgent: ControlledAccountOrAgent,
121
+ changes: JsonValue[],
122
+ ): { signature: Signature; transaction: Transaction } {
123
+ const sessionLog = this.getOrCreateSessionLog(
124
+ sessionID,
125
+ signerAgent.currentSignerID(),
126
+ );
127
+ const madeAt = Date.now();
128
+
129
+ const result = sessionLog.impl.addNewTrustingTransaction(
130
+ signerAgent,
131
+ changes,
132
+ madeAt,
133
+ );
134
+
135
+ this.addTransactionsToJsLog(
136
+ sessionLog,
137
+ [result.transaction],
138
+ result.signature,
139
+ );
140
+
141
+ return result;
142
+ }
143
+
144
+ private addTransactionsToJsLog(
145
+ sessionLog: SessionLog,
146
+ newTransactions: Transaction[],
147
+ signature: Signature,
148
+ ) {
149
+ for (const tx of newTransactions) {
150
+ sessionLog.transactions.push(tx);
151
+ }
152
+ sessionLog.lastSignature = signature;
153
+
154
+ sessionLog.txSizeSinceLastInbetweenSignature += newTransactions.reduce(
155
+ (sum, tx) =>
156
+ sum +
157
+ (tx.privacy === "private"
158
+ ? tx.encryptedChanges.length
159
+ : tx.changes.length),
160
+ 0,
161
+ );
162
+
163
+ if (exceedsRecommendedSize(sessionLog.txSizeSinceLastInbetweenSignature)) {
164
+ sessionLog.signatureAfter[sessionLog.transactions.length - 1] = signature;
165
+ sessionLog.txSizeSinceLastInbetweenSignature = 0;
166
+ }
167
+ }
168
+
169
+ knownState(): CoValueKnownState {
170
+ const sessions: CoValueKnownState["sessions"] = {};
171
+ for (const [sessionID, sessionLog] of this.sessions.entries()) {
172
+ sessions[sessionID] = sessionLog.transactions.length;
173
+ }
174
+ return { id: this.id, header: true, sessions };
175
+ }
176
+
177
+ decryptTransaction(
178
+ sessionID: SessionID,
179
+ txIndex: number,
180
+ keySecret: KeySecret,
181
+ ): JsonValue[] | undefined {
182
+ const sessionLog = this.sessions.get(sessionID);
183
+ if (!sessionLog) {
184
+ return undefined;
185
+ }
186
+ const decrypted = sessionLog.impl.decryptNextTransactionChangesJson(
187
+ txIndex,
188
+ keySecret,
189
+ );
190
+ if (!decrypted) {
191
+ return undefined;
192
+ }
193
+ return parseJSON(decrypted as Stringified<JsonValue[] | undefined>);
194
+ }
195
+
196
+ get size() {
197
+ return this.sessions.size;
198
+ }
199
+
200
+ entries() {
201
+ return this.sessions.entries();
202
+ }
203
+
204
+ values() {
205
+ return this.sessions.values();
206
+ }
207
+
208
+ keys() {
209
+ return this.sessions.keys();
210
+ }
211
+
212
+ clone(): SessionMap {
213
+ const clone = new SessionMap(this.id, this.crypto);
214
+
215
+ for (const [sessionID, sessionLog] of this.sessions) {
216
+ clone.sessions.set(sessionID, {
217
+ impl: sessionLog.impl.clone(),
218
+ transactions: sessionLog.transactions.slice(),
219
+ lastSignature: sessionLog.lastSignature,
220
+ signatureAfter: { ...sessionLog.signatureAfter },
221
+ txSizeSinceLastInbetweenSignature:
222
+ sessionLog.txSizeSinceLastInbetweenSignature,
223
+ signerID: sessionLog.signerID,
224
+ });
225
+ }
226
+
227
+ return clone;
228
+ }
229
+ }
@@ -1,5 +1,5 @@
1
1
  import { UpDownCounter, ValueType, metrics } from "@opentelemetry/api";
2
- import { Result, err } from "neverthrow";
2
+ import { Result, err, ok } from "neverthrow";
3
3
  import type { PeerState } from "../PeerState.js";
4
4
  import type { RawCoValue } from "../coValue.js";
5
5
  import type { ControlledAccountOrAgent } from "../coValues/account.js";
@@ -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 Map(),
297
+ new SessionMap(this.id, this.node.crypto),
302
298
  streamingKnownState,
303
299
  );
304
300
 
@@ -435,60 +431,67 @@ export class CoValueCore {
435
431
  tryAddTransactions(
436
432
  sessionID: SessionID,
437
433
  newTransactions: Transaction[],
438
- givenExpectedNewHash: Hash | undefined,
439
434
  newSignature: Signature,
440
- notifyMode: "immediate" | "deferred",
441
435
  skipVerify: boolean = false,
442
- givenNewStreamingHash?: StreamingHash,
443
436
  ): Result<true, TryAddTransactionsError> {
444
- return this.node
445
- .resolveAccountAgent(
446
- accountOrAgentIDfromSessionID(sessionID),
447
- "Expected to know signer of transaction",
448
- )
449
- .andThen((agent) => {
450
- if (!this.verified) {
451
- return err({
452
- type: "TriedToAddTransactionsWithoutVerifiedState",
453
- id: this.id,
454
- } satisfies TriedToAddTransactionsWithoutVerifiedStateErrpr);
455
- }
437
+ let result: Result<SignerID | undefined, TryAddTransactionsError>;
456
438
 
457
- const signerID = this.crypto.getAgentSignerID(agent);
458
-
459
- const result = this.verified.tryAddTransactions(
460
- sessionID,
461
- signerID,
462
- newTransactions,
463
- givenExpectedNewHash,
464
- newSignature,
465
- skipVerify,
466
- givenNewStreamingHash,
467
- );
439
+ if (skipVerify) {
440
+ result = ok(undefined);
441
+ } else {
442
+ result = this.node
443
+ .resolveAccountAgent(
444
+ accountOrAgentIDfromSessionID(sessionID),
445
+ "Expected to know signer of transaction",
446
+ )
447
+ .andThen((agent) => {
448
+ return ok(this.crypto.getAgentSignerID(agent));
449
+ });
450
+ }
468
451
 
469
- if (result.isOk()) {
470
- if (
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
- }
452
+ return result.andThen((signerID) => {
453
+ if (!this.verified) {
454
+ return err({
455
+ type: "TriedToAddTransactionsWithoutVerifiedState",
456
+ id: this.id,
457
+ } satisfies TriedToAddTransactionsWithoutVerifiedStateErrpr);
458
+ }
479
459
 
480
- this._cachedDependentOn = undefined;
460
+ const result = this.verified.tryAddTransactions(
461
+ sessionID,
462
+ signerID,
463
+ newTransactions,
464
+ newSignature,
465
+ skipVerify,
466
+ );
481
467
 
482
- this.notifyUpdate(notifyMode);
483
- }
468
+ if (result.isOk()) {
469
+ this.updateContentAndNotifyUpdate("immediate");
470
+ }
484
471
 
485
- return result;
486
- });
472
+ return result;
473
+ });
487
474
  }
488
475
 
489
476
  deferredUpdates = 0;
490
477
  nextDeferredNotify: Promise<void> | undefined;
491
478
 
479
+ updateContentAndNotifyUpdate(notifyMode: "immediate" | "deferred") {
480
+ if (
481
+ this._cachedContent &&
482
+ "processNewTransactions" in this._cachedContent &&
483
+ typeof this._cachedContent.processNewTransactions === "function"
484
+ ) {
485
+ this._cachedContent.processNewTransactions();
486
+ } else {
487
+ this._cachedContent = undefined;
488
+ }
489
+
490
+ this._cachedDependentOn = undefined;
491
+
492
+ this.notifyUpdate(notifyMode);
493
+ }
494
+
492
495
  notifyUpdate(notifyMode: "immediate" | "deferred") {
493
496
  if (this.listeners.size === 0) {
494
497
  return;
@@ -556,9 +559,18 @@ export class CoValueCore {
556
559
  );
557
560
  }
558
561
 
559
- const madeAt = Date.now();
562
+ // This is an ugly hack to get a unique but stable session ID for editing the current account
563
+ const sessionID =
564
+ this.verified.header.meta?.type === "account"
565
+ ? (this.node.currentSessionID.replace(
566
+ this.node.getCurrentAgent().id,
567
+ this.node.getCurrentAgent().currentAgentID(),
568
+ ) as SessionID)
569
+ : this.node.currentSessionID;
570
+
571
+ const signerAgent = this.node.getCurrentAgent();
560
572
 
561
- let transaction: Transaction;
573
+ let result: { signature: Signature; transaction: Transaction };
562
574
 
563
575
  if (privacy === "private") {
564
576
  const { secret: keySecret, id: keyID } = this.getCurrentReadKey();
@@ -567,69 +579,42 @@ export class CoValueCore {
567
579
  throw new Error("Can't make transaction without read key secret");
568
580
  }
569
581
 
570
- const encrypted = this.crypto.encryptForTransaction(changes, keySecret, {
571
- in: this.id,
572
- tx: this.nextTransactionID(),
573
- });
574
-
575
- this._decryptionCache[encrypted] = changes;
582
+ result = this.verified.makeNewPrivateTransaction(
583
+ sessionID,
584
+ signerAgent,
585
+ changes,
586
+ keyID,
587
+ keySecret,
588
+ );
576
589
 
577
- transaction = {
578
- privacy: "private",
579
- madeAt,
580
- keyUsed: keyID,
581
- encryptedChanges: encrypted,
582
- };
590
+ if (result.transaction.privacy === "private") {
591
+ this._decryptionCache[result.transaction.encryptedChanges] = changes;
592
+ }
583
593
  } else {
584
- transaction = {
585
- privacy: "trusting",
586
- madeAt,
587
- changes: stableStringify(changes),
588
- };
594
+ result = this.verified.makeNewTrustingTransaction(
595
+ sessionID,
596
+ signerAgent,
597
+ changes,
598
+ );
589
599
  }
590
600
 
591
- // This is an ugly hack to get a unique but stable session ID for editing the current account
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;
601
+ const { transaction, signature } = result;
599
602
 
600
- const { expectedNewHash, newStreamingHash } =
601
- this.verified.expectedNewHashAfter(sessionID, [transaction]);
603
+ this.node.syncManager.recordTransactionsSize([transaction], "local");
602
604
 
603
- const signature = this.crypto.sign(
604
- this.node.getCurrentAgent().currentSignerSecret(),
605
- expectedNewHash,
606
- );
605
+ const session = this.verified.sessions.get(sessionID);
606
+ const txIdx = session ? session.transactions.length - 1 : 0;
607
607
 
608
- const success = this.tryAddTransactions(
608
+ this.updateContentAndNotifyUpdate("immediate");
609
+ this.node.syncManager.syncLocalTransaction(
610
+ this.verified,
611
+ transaction,
609
612
  sessionID,
610
- [transaction],
611
- expectedNewHash,
612
613
  signature,
613
- "immediate",
614
- true,
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
- }
614
+ txIdx,
615
+ );
631
616
 
632
- return success;
617
+ return true;
633
618
  }
634
619
 
635
620
  getCurrentContent(options?: { ignorePrivateTransactions: true }): RawCoValue {
@@ -658,6 +643,12 @@ export class CoValueCore {
658
643
  ignorePrivateTransactions: boolean;
659
644
  knownTransactions?: CoValueKnownState["sessions"];
660
645
  }): DecryptedTransaction[] {
646
+ if (!this.verified) {
647
+ throw new Error(
648
+ "CoValueCore: getValidTransactions called on coValue without verified state",
649
+ );
650
+ }
651
+
661
652
  const validTransactions = determineValidTransactions(
662
653
  this,
663
654
  options?.knownTransactions,
@@ -701,25 +692,12 @@ export class CoValueCore {
701
692
  let decryptedChanges = this._decryptionCache[tx.encryptedChanges];
702
693
 
703
694
  if (!decryptedChanges) {
704
- const decryptedString = this.crypto.decryptRawForTransaction(
705
- tx.encryptedChanges,
695
+ decryptedChanges = this.verified.decryptTransaction(
696
+ txID.sessionID,
697
+ txID.txIndex,
706
698
  readKey,
707
- {
708
- in: this.id,
709
- tx: txID,
710
- },
711
699
  );
712
700
 
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
701
  this._decryptionCache[tx.encryptedChanges] = decryptedChanges;
724
702
  }
725
703
 
@@ -998,7 +976,7 @@ export type InvalidSignatureError = {
998
976
  id: RawCoID;
999
977
  newSignature: Signature;
1000
978
  sessionID: SessionID;
1001
- signerID: SignerID;
979
+ signerID: SignerID | undefined;
1002
980
  };
1003
981
 
1004
982
  export type TriedToAddTransactionsWithoutVerifiedStateErrpr = {
@@ -1006,8 +984,15 @@ export type TriedToAddTransactionsWithoutVerifiedStateErrpr = {
1006
984
  id: RawCoID;
1007
985
  };
1008
986
 
987
+ export type TriedToAddTransactionsWithoutSignerIDError = {
988
+ type: "TriedToAddTransactionsWithoutSignerID";
989
+ id: RawCoID;
990
+ sessionID: SessionID;
991
+ };
992
+
1009
993
  export type TryAddTransactionsError =
1010
994
  | TriedToAddTransactionsWithoutVerifiedStateErrpr
995
+ | TriedToAddTransactionsWithoutSignerIDError
1011
996
  | ResolveAccountAgentError
1012
997
  | InvalidHashError
1013
998
  | InvalidSignatureError;