@ocap/types 1.29.5 → 1.29.7

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.
@@ -252,3 +252,29 @@ export type {
252
252
  // Main interface
253
253
  IResolver,
254
254
  } from './resolver';
255
+
256
+ // Ledger types (VLedger - Verifiable Ledger Kernel)
257
+ export type {
258
+ // Entry types
259
+ ILedgerEntry,
260
+ ILedgerEntryRow,
261
+ // Checkpoint types
262
+ ICheckpoint,
263
+ ICheckpointRow,
264
+ // Merkle types
265
+ IMerkleProof,
266
+ // Configuration types
267
+ ICheckpointConfig,
268
+ ILedgerCapabilities,
269
+ // Input types
270
+ ISignedTransactionInput,
271
+ // Storage interface
272
+ ILedgerStorage,
273
+ // Main interface
274
+ ILedger,
275
+ // Factory interface
276
+ ILedgerFactory,
277
+ // Table type mappings
278
+ LedgerTableTypeMap,
279
+ LedgerTableName,
280
+ } from './ledger';
@@ -441,4 +441,10 @@ export interface IIndexDB {
441
441
  * Should be called after all tables are initialized
442
442
  */
443
443
  attachReadyListeners(): void;
444
+
445
+ /**
446
+ * Close the database connection and release all resources.
447
+ * Must be called during graceful shutdown.
448
+ */
449
+ close(): Promise<void>;
444
450
  }
@@ -0,0 +1,376 @@
1
+ // core/types/interfaces/ledger.ts
2
+ // Ledger state and operation types for Ledger - Verifiable Ledger Kernel
3
+
4
+ // ============================================================================
5
+ // Ledger Entry Types
6
+ // ============================================================================
7
+
8
+ /**
9
+ * Ledger Entry - Immutable record of a signed transaction
10
+ */
11
+ export interface ILedgerEntry {
12
+ /** Global incrementing sequence number */
13
+ sequence: number;
14
+
15
+ /** Transaction hash (0x + 64 hex chars) */
16
+ hash: string;
17
+
18
+ /** Signer DID */
19
+ from: string;
20
+
21
+ /** Anti-replay nonce */
22
+ nonce: number;
23
+
24
+ /** Public key */
25
+ pk: string;
26
+
27
+ /** Signature */
28
+ signature: string;
29
+
30
+ /** Base64 encoded raw transaction bytes */
31
+ txRaw: string;
32
+
33
+ /** Decoded JSON object (redundant storage for querying) */
34
+ tx: Record<string, unknown>;
35
+
36
+ /** Transaction type (e.g., 'fg:t:transfer') */
37
+ txType: string;
38
+
39
+ /** Entry timestamp (ms) */
40
+ timestamp: number;
41
+
42
+ /** Chain DID this entry belongs to */
43
+ chainId: string;
44
+
45
+ /** hash(sequence + txRaw) for Merkle Tree leaf */
46
+ entryHash: string;
47
+
48
+ /** Transaction verification context (passkey, gasStakeHeaders, etc.) */
49
+ txExtra?: Record<string, unknown>;
50
+
51
+ /** State commit hash (e.g. Dolt commit) that contains this tx's state changes */
52
+ stateCommitHash?: string;
53
+
54
+ /** Whether the entry has been finalized (stateCommitHash set and entryHash recomputed) */
55
+ finalized: boolean;
56
+ }
57
+
58
+ /**
59
+ * Storage row type for ledger entries (used by adapters)
60
+ * Uses camelCase to match TypeScript conventions and statedb-dolt patterns
61
+ */
62
+ export interface ILedgerEntryRow {
63
+ sequence: number;
64
+ hash: string;
65
+ from: string;
66
+ nonce: number;
67
+ pk: string;
68
+ signature: string;
69
+ txRaw: string;
70
+ tx: string; // JSON string
71
+ txType: string;
72
+ timestamp: number;
73
+ chainId: string;
74
+ entryHash: string;
75
+ txExtra: string | null; // JSON string for verification context
76
+ stateCommitHash: string | null;
77
+ finalized: number; // 0 or 1 for SQL compatibility
78
+ }
79
+
80
+ // ============================================================================
81
+ // Checkpoint Types
82
+ // ============================================================================
83
+
84
+ /**
85
+ * Checkpoint - Verifiable snapshot proof at a Ledger position
86
+ */
87
+ export interface ICheckpoint {
88
+ /** Checkpoint incrementing number */
89
+ height: number;
90
+
91
+ /** Checkpoint's own hash */
92
+ hash: string;
93
+
94
+ /** Last entry sequence covered */
95
+ sequence: number;
96
+
97
+ /** Previous checkpoint's sequence */
98
+ prevSequence: number;
99
+
100
+ /** Merkle root of ledger entries */
101
+ txRoot: string;
102
+
103
+ /** Cumulative transaction count */
104
+ txCount: number;
105
+
106
+ /** State root (optional, e.g., Dolt commit hash) */
107
+ stateRoot?: string;
108
+
109
+ /** Creation timestamp (ms) */
110
+ timestamp: number;
111
+
112
+ /** Previous checkpoint hash */
113
+ prevCheckpoint: string | null;
114
+
115
+ /** Proposer DID */
116
+ proposer: string;
117
+
118
+ /** Proposer signature */
119
+ signature: string;
120
+ }
121
+
122
+ /**
123
+ * Storage row type for checkpoints (used by adapters)
124
+ * Uses camelCase to match TypeScript conventions and statedb-dolt patterns
125
+ */
126
+ export interface ICheckpointRow {
127
+ height: number;
128
+ hash: string;
129
+ sequence: number;
130
+ prevSequence: number;
131
+ txRoot: string;
132
+ txCount: number;
133
+ stateRoot: string | null;
134
+ timestamp: number;
135
+ prevCheckpoint: string | null;
136
+ proposer: string;
137
+ signature: string;
138
+ }
139
+
140
+ // ============================================================================
141
+ // Merkle Proof Types
142
+ // ============================================================================
143
+
144
+ /**
145
+ * Merkle Proof - Proves an entry belongs to a checkpoint
146
+ */
147
+ export interface IMerkleProof {
148
+ /** Entry position (sequence - 1) */
149
+ index: number;
150
+
151
+ /** Entry hash (leaf) */
152
+ leaf: string;
153
+
154
+ /** Merkle path (sibling hashes) */
155
+ proof: string[];
156
+
157
+ /** Checkpoint's txRoot */
158
+ root: string;
159
+ }
160
+
161
+ // ============================================================================
162
+ // Configuration Types
163
+ // ============================================================================
164
+
165
+ /**
166
+ * Checkpoint configuration
167
+ */
168
+ export interface ICheckpointConfig {
169
+ /** Trigger batch size: create checkpoint every N transactions */
170
+ batchSize: number;
171
+
172
+ /** Time trigger: max time since last checkpoint (ms) */
173
+ timeoutMs: number;
174
+
175
+ /** Enable auto checkpoint */
176
+ auto: boolean;
177
+ }
178
+
179
+ /**
180
+ * Ledger capabilities for testing
181
+ */
182
+ export interface ILedgerCapabilities {
183
+ /** Persistent storage */
184
+ persistence: boolean;
185
+
186
+ /** True transaction semantics */
187
+ transaction: boolean;
188
+
189
+ /** Supports stateRoot */
190
+ stateRoot: boolean;
191
+
192
+ /** Supports schema migration */
193
+ migration: boolean;
194
+ }
195
+
196
+ // ============================================================================
197
+ // Input Types
198
+ // ============================================================================
199
+
200
+ /**
201
+ * Signed transaction input for ledger.append()
202
+ */
203
+ export interface ISignedTransactionInput {
204
+ txRaw: string;
205
+ tx: Record<string, unknown>;
206
+ txHash: string;
207
+ txType: string;
208
+ from: string;
209
+ nonce: number;
210
+ pk: string;
211
+ signature: string;
212
+ chainId: string;
213
+ timestamp: number;
214
+ /** Transaction verification context (passkey, gasStakeHeaders, etc.) */
215
+ txExtra?: Record<string, unknown>;
216
+ }
217
+
218
+ // ============================================================================
219
+ // Storage Interface
220
+ // ============================================================================
221
+
222
+ /**
223
+ * Storage adapter interface - SQLite/Dolt implement this
224
+ */
225
+ export interface ILedgerStorage {
226
+ // Entry operations
227
+ appendEntries(entries: ILedgerEntry[]): Promise<void>;
228
+
229
+ /**
230
+ * Atomically append an entry with database-generated sequence and entryHash.
231
+ * This method is concurrency-safe: sequence is generated within a transaction
232
+ * using MAX(sequence)+1, ensuring no conflicts under multi-instance writes.
233
+ *
234
+ * The entry is created with finalized=false. Call finalizeEntry() after
235
+ * statedb commit to set stateCommitHash, recompute entryHash, and mark finalized.
236
+ *
237
+ * @param entry - Entry data without sequence, entryHash, and finalized (set by storage)
238
+ * @returns Complete entry with sequence, entryHash, and finalized=false
239
+ */
240
+ appendEntryAtomic(entry: Omit<ILedgerEntry, 'sequence' | 'entryHash' | 'finalized'>): Promise<ILedgerEntry>;
241
+ getEntryByHash(hash: string): Promise<ILedgerEntry | null>;
242
+ getEntryBySequence(seq: number): Promise<ILedgerEntry | null>;
243
+ getEntriesByRange(from: number, to: number): Promise<ILedgerEntry[]>;
244
+ getLatestSequence(): Promise<number>;
245
+ /**
246
+ * Iterate entry hashes in a sequence range (inclusive).
247
+ *
248
+ * @param fromSeq - Start sequence (inclusive)
249
+ * @param toSeq - End sequence (inclusive)
250
+ * @param callback - Called for each entry in ascending sequence order
251
+ */
252
+ iterateEntryHashes(
253
+ fromSeq: number,
254
+ toSeq: number,
255
+ callback: (seq: number, entryHash: string) => Promise<void>
256
+ ): Promise<void>;
257
+
258
+ /**
259
+ * Finalize an entry: set stateCommitHash, recompute entryHash, mark as finalized.
260
+ *
261
+ * @param txHash - Transaction hash identifying the entry
262
+ * @param stateCommitHash - State commit hash from statedb
263
+ * @param sequence - Entry sequence (needed for entryHash recomputation)
264
+ * @param txRaw - Raw transaction bytes (needed for entryHash recomputation)
265
+ */
266
+ finalizeEntry(txHash: string, stateCommitHash: string, sequence: number, txRaw: string): Promise<void>;
267
+
268
+ /**
269
+ * Check if there are any unfinalized entries in the given sequence range (inclusive).
270
+ *
271
+ * @returns true if at least one entry in [fromSeq, toSeq] has finalized=false
272
+ */
273
+ hasUnfinalizedInRange(fromSeq: number, toSeq: number): Promise<boolean>;
274
+
275
+ // Checkpoint operations
276
+ saveCheckpoint(checkpoint: ICheckpoint): Promise<void>;
277
+ getCheckpointByHeight(height: number): Promise<ICheckpoint | null>;
278
+ getLatestCheckpoint(): Promise<ICheckpoint | null>;
279
+ getCheckpointForSequence(seq: number): Promise<ICheckpoint | null>;
280
+
281
+ // Schema migration
282
+ getMigrationVersion(): Promise<number>;
283
+ runMigrations(): Promise<void>;
284
+ rollbackMigration(targetVersion: number): Promise<void>;
285
+
286
+ // Lifecycle
287
+ init(): Promise<void>;
288
+ close(): Promise<void>;
289
+ reset(): Promise<void>;
290
+ }
291
+
292
+ // ============================================================================
293
+ // Ledger Interface
294
+ // ============================================================================
295
+
296
+ /**
297
+ * Ledger interface - Main API
298
+ */
299
+ export interface ILedger {
300
+ readonly chainId: string;
301
+
302
+ // Write (Append-only)
303
+ append(tx: ISignedTransactionInput): Promise<ILedgerEntry>;
304
+
305
+ /**
306
+ * Batch append for offline / single-process scenarios (e.g. data migration, import).
307
+ *
308
+ * NOT concurrency-safe: sequences are computed in memory from a single
309
+ * getLatestSequence() call, so concurrent writers would produce conflicts.
310
+ * Use `append()` for online multi-instance workloads.
311
+ */
312
+ appendBatch(txs: ISignedTransactionInput[]): Promise<ILedgerEntry[]>;
313
+
314
+ // Read
315
+ get(hash: string): Promise<ILedgerEntry | null>;
316
+ getBySequence(seq: number): Promise<ILedgerEntry | null>;
317
+ getRange(from: number, to: number): Promise<ILedgerEntry[]>;
318
+
319
+ // Metadata
320
+ getLatestSequence(): Promise<number>;
321
+
322
+ // State commit hash
323
+ /**
324
+ * Finalize a ledger entry: set stateCommitHash, recompute entryHash, mark finalized.
325
+ *
326
+ * @param txHash - Transaction hash identifying the entry
327
+ * @param stateCommitHash - State commit hash from statedb
328
+ * @param sequence - Entry sequence (needed for entryHash recomputation)
329
+ * @param txRaw - Raw transaction bytes (needed for entryHash recomputation)
330
+ */
331
+ finalizeEntry(txHash: string, stateCommitHash: string, sequence: number, txRaw: string): Promise<void>;
332
+
333
+ // Checkpoint
334
+ createCheckpoint(): Promise<ICheckpoint>;
335
+ /** Create a checkpoint if batchSize/timeoutMs threshold is reached. Returns checkpoint or null. */
336
+ createCheckpointIfNeeded(): Promise<ICheckpoint | null>;
337
+ /** Get checkpoint by height, or latest if height is undefined */
338
+ getCheckpoint(height?: number): Promise<ICheckpoint | null>;
339
+ getCheckpointForSequence(seq: number): Promise<ICheckpoint | null>;
340
+
341
+ // Merkle
342
+ getMerkleProof(sequence: number): Promise<IMerkleProof>;
343
+ verifyMerkleProof(proof: IMerkleProof): boolean;
344
+
345
+ // Lifecycle
346
+ initialize(): Promise<void>;
347
+ close(): Promise<void>;
348
+ }
349
+
350
+ // ============================================================================
351
+ // Factory Interface
352
+ // ============================================================================
353
+
354
+ /**
355
+ * Ledger factory interface for testing
356
+ */
357
+ export interface ILedgerFactory {
358
+ name: string;
359
+ capabilities: ILedgerCapabilities;
360
+ create(): Promise<ILedger>;
361
+ cleanup(ledger: ILedger): Promise<void>;
362
+ }
363
+
364
+ // ============================================================================
365
+ // Table Type Mapping
366
+ // ============================================================================
367
+
368
+ /**
369
+ * Maps ledger table names to their row types
370
+ */
371
+ export type LedgerTableTypeMap = {
372
+ entries: ILedgerEntryRow;
373
+ checkpoints: ICheckpointRow;
374
+ };
375
+
376
+ export type LedgerTableName = keyof LedgerTableTypeMap;
@@ -18,6 +18,8 @@
18
18
  // type DelegateContext = IReadyContext<TDelegateTx> & IWithSender & IWithReceiver & IWithDelegation;
19
19
  //
20
20
 
21
+ import type { ILedger } from './ledger';
22
+
21
23
  import type { TTokenInput, TTransactionReceipt } from '../lib/type_pb';
22
24
  import type { BN } from './base';
23
25
  import type { IAny } from './base';
@@ -195,6 +197,12 @@ export interface IBaseContext<TItx = unknown> {
195
197
  /** @internal Type parameter placeholder */
196
198
  readonly __itxType?: TItx;
197
199
 
200
+ /** Verifiable ledger instance for append-only transaction log */
201
+ ledger: ILedger;
202
+
203
+ /** Ledger sequence number (set by WriteLedger pipe, used in Phase 6) */
204
+ ledgerSequence?: number;
205
+
198
206
  /** Index signature for IOperationContext compatibility and dynamic property access */
199
207
  [key: string]: unknown;
200
208
  }
@@ -500,4 +500,10 @@ export interface IResolver {
500
500
  args: Partial<TRequestVerifyAccountRisk>,
501
501
  ctx?: IResolverContext
502
502
  ): Promise<TVerifyAccountRiskResult | null> | null;
503
+
504
+ // ============ Lifecycle ============
505
+ /**
506
+ * Graceful shutdown: drain the transaction queue and stop accepting new requests.
507
+ */
508
+ shutdown(): Promise<void>;
503
509
  }
@@ -190,4 +190,10 @@ export interface IStateDB extends IReady {
190
190
 
191
191
  /** Get table by name - use this for dynamic table access */
192
192
  getTable?(name: StateDBTableName): IStateTable<unknown>;
193
+
194
+ /**
195
+ * Close the database connection and release all resources.
196
+ * Must be called during graceful shutdown.
197
+ */
198
+ close(): Promise<void>;
193
199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ocap/types",
3
- "version": "1.29.5",
3
+ "version": "1.29.7",
4
4
  "description": "Typescript definitions generated from protobuf",
5
5
  "keywords": [
6
6
  "ocap",