Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/project-history-from-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@cashu/coco-core': major
'@cashu/coco-react': major
'@cashu/coco-indexeddb': major
'@cashu/coco-expo-sqlite': major
'@cashu/coco-sqlite': major
'@cashu/coco-sqlite-bun': major
'@cashu/coco-adapter-tests': major
---

Project history entries from operation repositories instead of maintaining a
mutable history table.

History entries now use deterministic `type:operationId` ids for operation
rows, expose `source`, `updatedAt`, and `operationId` on operation-backed
entries, and retain legacy table rows behind `legacy:*` ids for migration
compatibility. The old history repository mutation contract has been removed;
persistent adapters now read history by merging operation rows with legacy rows
and de-duplicating legacy records that map to an operation.
24 changes: 12 additions & 12 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions packages/adapter-tests/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,7 @@ export async function runIntegrationTests<TRepositories extends Repositories = R

it('should create melt history entry when a melt operation is prepared', async () => {
const invoice = createFakeInvoice(15);
const historyPromise = waitForMeltHistoryState(mgr!, 'UNPAID');
const historyPromise = waitForMeltHistoryState(mgr!, 'prepared');
const prepared = await mgr!.ops.melt.prepare({
mintUrl,
method: 'bolt11',
Expand All @@ -1152,7 +1152,7 @@ export async function runIntegrationTests<TRepositories extends Repositories = R
if (meltEntry?.type === 'melt') {
expect(meltEntry.operationId).toBe(prepared.id);
expect(await mgr!.history.getOperationIdForHistoryEntry(meltEntry.id)).toBe(prepared.id);
expect(meltEntry.state).toBe('UNPAID');
expect(meltEntry.state).toBe('prepared');
expectAmountEquals(expect, meltEntry.amount, prepared.amount);
}
});
Expand Down Expand Up @@ -1326,7 +1326,7 @@ export async function runIntegrationTests<TRepositories extends Repositories = R
expect(amountAfterRollback).toBeGreaterThan(amountAfterSend);
});

it('should update history state to rolledBack on rollback', async () => {
it('should update history state to rolled_back on rollback', async () => {
const sendAmount = 35;
const pendingPromise = waitForEvent<{ operationId: string }>(mgr!, 'send:pending');
const pendingHistoryPromise = waitForSendHistoryState(mgr!, 'pending', {
Expand All @@ -1346,7 +1346,7 @@ export async function runIntegrationTests<TRepositories extends Repositories = R
expect((sendEntry as any).state).toBe('pending');

// Rollback
const rolledBackHistoryPromise = waitForSendHistoryState(mgr!, 'rolledBack', {
const rolledBackHistoryPromise = waitForSendHistoryState(mgr!, 'rolled_back', {
operationId,
});
await mgr!.ops.send.reclaim(operationId!);
Expand All @@ -1358,7 +1358,7 @@ export async function runIntegrationTests<TRepositories extends Repositories = R
(e) => e.type === 'send' && (e as any).operationId === operationId,
);
expect(sendEntry).toBeDefined();
expect((sendEntry as any).state).toBe('rolledBack');
expect((sendEntry as any).state).toBe('rolled_back');
});

it('should finalize a pending send operation when proofs are spent', async () => {
Expand Down
12 changes: 6 additions & 6 deletions packages/core/Manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,12 +722,6 @@ export class Manager {
meltQuoteLogger,
);

const historyService = new HistoryService(
repositories.historyRepository,
this.eventBus,
historyLogger,
);

const mintScopedLock = new MintScopedLock();

const sendOperationLogger = this.getChildLogger('SendOperationService');
Expand Down Expand Up @@ -800,6 +794,12 @@ export class Manager {
);
const mintOperationRepository = repositories.mintOperationRepository;

const historyService = new HistoryService(
repositories.historyRepository,
this.eventBus,
historyLogger,
);

const mintQuoteRepository = repositories.mintQuoteRepository;

const paymentRequestLogger = this.getChildLogger('PaymentRequestService');
Expand Down
Loading
Loading