@dvmkit/sdk 0.5.0-rc.1 → 0.6.0-rc.1

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 (32) hide show
  1. package/README.md +100 -0
  2. package/dist/chunk-AFV77S4C.js +258 -0
  3. package/dist/chunk-BQJIFRAZ.js +36 -0
  4. package/dist/{chunk-PB4FYZET.js → chunk-EQLA4FFY.js} +54 -4
  5. package/dist/{chunk-TZ2WKCDD.js → chunk-HCLVYZUZ.js} +2 -2
  6. package/dist/{chunk-EYTHFFFU.js → chunk-HHBDBMEO.js} +159 -34
  7. package/dist/{chunk-O5AT6S5T.js → chunk-IV6Q7NRW.js} +25 -195
  8. package/dist/{chunk-Z4KLECAC.js → chunk-N5RZ5HVB.js} +1 -1
  9. package/dist/{chunk-TUA7PYH7.js → chunk-OQA7IHI4.js} +124 -124
  10. package/dist/{chunk-6DOGTAHA.js → chunk-QR2EF2NI.js} +9 -43
  11. package/dist/{chunk-A4YFWZ7R.js → chunk-RCM3P2HE.js} +1 -1
  12. package/dist/content-retention-BTGSQRfP.d.ts +78 -0
  13. package/dist/{credit-menu-CAfqe8IY.d.ts → credit-menu-BAsrRu3z.d.ts} +98 -5
  14. package/dist/{fx-D9nsN3n4.d.ts → fx-BgDmyTdd.d.ts} +1 -1
  15. package/dist/index.d.ts +5 -5
  16. package/dist/index.js +3 -3
  17. package/dist/internal/caller.d.ts +16 -15
  18. package/dist/internal/caller.js +7 -5
  19. package/dist/internal/server.d.ts +8 -99
  20. package/dist/internal/server.js +12 -9
  21. package/dist/{job-store-Bx-VFRjg.d.ts → job-store-BVeF5_Jq.d.ts} +1 -1
  22. package/dist/{lightning-backend-BAx2Y8pP.d.ts → lightning-backend-40fIzz1W.d.ts} +1 -1
  23. package/dist/{postgres-consumed-credential-store-CUQJKRSL.js → postgres-consumed-credential-store-BUVCAPLS.js} +13 -0
  24. package/dist/{postgres-job-store-VLXLWXUQ.js → postgres-job-store-VHLQBJZC.js} +3 -1
  25. package/dist/server/index.d.ts +28 -10
  26. package/dist/server/index.js +22 -9
  27. package/dist/{step-cache-QG_h5-3G.d.ts → step-cache-CPdH1hei.d.ts} +2 -2
  28. package/dist/testing/index.d.ts +9 -2
  29. package/dist/testing/index.js +6 -3
  30. package/dist/{usd-EwRqCPF-.d.ts → usd-AWlrwlM5.d.ts} +1 -1
  31. package/package.json +3 -2
  32. package/recipes/postgres/financial-export-v1.sql +137 -0
@@ -1,4 +1,4 @@
1
- import { W as JsonValue } from './step-cache-QG_h5-3G.js';
1
+ import { W as JsonValue } from './step-cache-CPdH1hei.js';
2
2
 
3
3
  declare const lockPubkeyBrand: unique symbol;
4
4
  /**
@@ -51,6 +51,19 @@ var PostgresConsumedCredentialStore = class {
51
51
  );
52
52
  return (rowCount ?? 0) > 0;
53
53
  }
54
+ async consume(realm, challengeId, ttlSeconds) {
55
+ const now = this.now();
56
+ const { rowCount } = await this.pool.query(
57
+ `INSERT INTO ${this.tableName}(realm,challenge_id,expires_at) VALUES($1,$2,$3)
58
+ ON CONFLICT(realm,challenge_id) DO UPDATE SET expires_at=EXCLUDED.expires_at
59
+ WHERE ${this.tableName}.expires_at <= $4`,
60
+ [realm, challengeId, now + ttlSeconds * 1e3, now]
61
+ );
62
+ if (rowCount === 1 && this.gcSampleRate > 0 && Math.random() < this.gcSampleRate) {
63
+ this.gcSweep(now);
64
+ }
65
+ return rowCount === 1;
66
+ }
54
67
  async mark(realm, challengeId, ttlSeconds) {
55
68
  const now = this.now();
56
69
  const expiresAt = now + ttlSeconds * 1e3;
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  PostgresJobStore
3
- } from "./chunk-PB4FYZET.js";
3
+ } from "./chunk-EQLA4FFY.js";
4
+ import "./chunk-AFV77S4C.js";
5
+ import "./chunk-BQJIFRAZ.js";
4
6
  import "./chunk-COYKJRMM.js";
5
7
  import "./chunk-ETXDTUJO.js";
6
8
  export {
@@ -1,21 +1,24 @@
1
- import { ac as CashuMode, bK as CreditDrainEnqueue, bL as HostedSettlementReportObligations, R as ResolvedCreditConfig, bM as DVMAuthScheme, z as SignedRequestDomain, bN as CreditLedgerLike, bO as X402RefundSettlementGate, bP as CreditSnapshot, bQ as DrawResult, bR as X402SettlementStatus, bS as X402UnresolvedRefund, bT as GrownDrawResult, bU as DrawResolution, bV as FundingRecord, X as FundingReceipt, bW as CreditInvoiceRecord, bX as InvoiceSettlement, bY as BlockedInvoiceCursor, bZ as InvoiceReconciliation, b_ as InvoiceWriteOff, b$ as DrawRecord, c0 as StalePendingDrawCursor, c1 as TempoCreditLossEvidence, c2 as CreditLedgerQuerier, c3 as TempoCreditLoss, c4 as X402CreditLossEvidence, c5 as X402CreditLoss, c6 as DrainMethod, c7 as DrainRequestResult, c8 as BitcoinDepositLiability, bo as FundingLot, c9 as CreditDrainRecord, ca as ChannelDrainCursor, cb as DrainWriteOff, cc as DrainReleaseResult, cd as DrainFulfilment, ce as DrainTransitionResult, cf as HostingCleanupFence, Y as JobReceipt, a1 as Message, K as KVStore, F as SignedRequestReplayStore, Z as ZodLike, a as DVMDescriptor } from '../step-cache-QG_h5-3G.js';
2
- export { cg as CLIENT_COMPATIBILITY_HEADERS, d as CanonicalEnvelope, ch as ClientCompatibility, ci as ClientCompatibilityEnv, cj as ClientCompatibilityGate, ck as ClientCompatibilityRequirement, cl as ClientSemVer, e as CreateSignedRequestVerifierOpts, cm as CreditFundingBasis, cn as CreditInvoiceStatus, co as CreditLedger, cp as CreditLedgerError, cq as CreditLedgerErrorCode, cr as CreditLedgerErrorDetails, cs as CreditLedgerPool, ct as CreditStatus, cu as DRAIN_DELIVERY_RESERVE_SATS, cv as DVM_PROTOCOL_VERSION, cw as DrainConflictReason, cx as DrawRailValue, cy as DrawStatus, cz as JobCostReportPayload, cA as JobTerminalReportPayload, cB as PostgresX402ChannelStorage, cC as ReplayStoreBackend, cD as RevenueSkippedNoRailPayload, cE as RevenueSkippedNoRailReason, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, cF as Secp256k1AuthOpts, y as SignedRequestAudience, B as SignedRequestError, E as SignedRequestFailure, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, M as SignedRequestVerifier, cG as X402ChannelStorageOpts, cH as X402RelayLockHolder, cI as X402RelaySubmissionLock, cJ as X402RelaySubmissionLockError, cK as allocateDrawValue, cL as clientCompatibilityAttributes, cM as clientCompatibilityMiddleware, cN as clientUpgradeRequired, N as createSignedRequestVerifier, cO as parseClientCapabilities, cP as parseClientCompatibility, cQ as parseDvmClient, cR as parseProtocolVersion, cS as requireClientCompatibility, cT as secp256k1Auth, cU as signedRequestInput, T as signedRequestStatementHeader } from '../step-cache-QG_h5-3G.js';
1
+ import { ac as CashuMode, bK as CreditDrainEnqueue, bL as HostedSettlementReportObligations, R as ResolvedCreditConfig, bM as DVMAuthScheme, z as SignedRequestDomain, bN as CreditLedgerLike, bO as X402RefundSettlementGate, bP as CreditSnapshot, bQ as DrawResult, bR as X402SettlementStatus, bS as X402UnresolvedRefund, bT as GrownDrawResult, bU as DrawResolution, bV as FundingRecord, X as FundingReceipt, bW as CreditInvoiceRecord, bX as InvoiceSettlement, bY as BlockedInvoiceCursor, bZ as InvoiceReconciliation, b_ as InvoiceWriteOff, b$ as DrawRecord, c0 as StalePendingDrawCursor, c1 as TempoCreditLossEvidence, c2 as CreditLedgerQuerier, c3 as TempoCreditLoss, c4 as X402CreditLossEvidence, c5 as X402CreditLoss, c6 as DrainMethod, c7 as DrainRequestResult, c8 as BitcoinDepositLiability, bo as FundingLot, c9 as CreditDrainRecord, ca as ChannelDrainCursor, cb as DrainWriteOff, cc as DrainReleaseResult, cd as DrainFulfilment, ce as DrainTransitionResult, cf as HostingCleanupFence, Y as JobReceipt, a1 as Message, K as KVStore, F as SignedRequestReplayStore, Z as ZodLike, a as DVMDescriptor } from '../step-cache-CPdH1hei.js';
2
+ export { cg as CLIENT_COMPATIBILITY_HEADERS, d as CanonicalEnvelope, ch as ClientCompatibility, ci as ClientCompatibilityEnv, cj as ClientCompatibilityGate, ck as ClientCompatibilityRequirement, cl as ClientSemVer, e as CreateSignedRequestVerifierOpts, cm as CreditFundingBasis, cn as CreditInvoiceStatus, co as CreditLedger, cp as CreditLedgerError, cq as CreditLedgerErrorCode, cr as CreditLedgerErrorDetails, cs as CreditLedgerPool, ct as CreditStatus, cu as DRAIN_DELIVERY_RESERVE_SATS, cv as DVM_PROTOCOL_VERSION, cw as DrainConflictReason, cx as DrawRailValue, cy as DrawStatus, cz as JobCostReportPayload, cA as JobTerminalReportPayload, cB as PostgresX402ChannelStorage, cC as ReplayStoreBackend, cD as RevenueSkippedNoRailPayload, cE as RevenueSkippedNoRailReason, w as SIGNED_REQUEST_AUTH_ID, x as SIGNED_REQUEST_STATEMENT_VERSION, cF as Secp256k1AuthOpts, y as SignedRequestAudience, B as SignedRequestError, E as SignedRequestFailure, G as SignedRequestSignOpts, H as SignedRequestStatementHeader, M as SignedRequestVerifier, cG as X402ChannelStorageOpts, cH as X402RelayLockHolder, cI as X402RelaySubmissionLock, cJ as X402RelaySubmissionLockError, cK as allocateDrawValue, cL as clientCompatibilityAttributes, cM as clientCompatibilityMiddleware, cN as clientUpgradeRequired, N as createSignedRequestVerifier, cO as parseClientCapabilities, cP as parseClientCompatibility, cQ as parseDvmClient, cR as parseProtocolVersion, cS as requireClientCompatibility, cT as secp256k1Auth, cU as signedRequestInput, T as signedRequestStatementHeader } from '../step-cache-CPdH1hei.js';
3
3
  import { Pool } from 'pg';
4
- import { al as CreditMenu, b as AppEnv, U as UpfrontPaymentOpts, h as PaymentInfo, am as ReceiptIssuer, an as LightningReceive, ao as TempoSettlementReadiness, ap as DVMHostOpts, aq as DVMServeResult } from '../credit-menu-CAfqe8IY.js';
5
- export { ar as BuildCreditMenuArgs, as as BuilderIdentity, at as CREDIT_ENVELOPE_KEYS, C as ConsumedCredentialStore, au as CreateX402BatchSettlementServerOpts, av as CreditEnvelope, aw as CreditEnvelopeError, ax as CreditFundCommitment, ay as CreditTerms, az as DEFAULT_INVOICE_TTL_SECONDS, aA as DVMHost, aB as HostingClosureCommand, aC as HostingClosureEvidence, aD as HostingControlCommand, aE as HostingControlConfig, aF as HostingControlStatus, aG as JobManager, aH as JobManagerOpts, aI as LightningReceiveConfig, aJ as MIN_INVOICE_TTL_SECONDS, aK as MemoryConsumedCredentialStore, aL as MemoryConsumedCredentialStoreOpts, aM as MemoryProcessedPaymentStore, aN as MemoryX402ExactSettlementStore, aO as MountOpts, aP as OwnerDisplay, aQ as PaidJobCompletion, aR as PaymentMode, aS as PlatformReporterOpts, aT as PostgresProcessedPaymentStore, aU as PostgresX402ExactSettlementStore, aV as PriceFiat, aW as ProcessedPaymentQuerier, aX as ProcessedPaymentRail, aY as ProcessedPaymentRecord, aZ as ProcessedPaymentReplayError, a_ as ProcessedPaymentStore, a$ as X402BatchAcceptance, b0 as X402BatchFunding, b1 as X402BatchRefusal, b2 as X402BatchSettlementServer, b3 as X402ExactAcceptance, b4 as X402ExactIntentConflictError, b5 as X402ExactSettlementAttempt, b6 as X402ExactSettlementChainEvidence, b7 as X402ExactSettlementEffect, b8 as X402ExactSettlementEvidenceMissingError, b9 as X402ExactSettlementEvidenceReader, ba as X402ExactSettlementIntent, bb as X402ExactSettlementNotReadyError, bc as X402ExactSettlementServer, bd as X402ExactSettlementServerOpts, be as X402ExactSettlementStatus, bf as X402ExactSettlementStore, bg as X402SettlementChainEvidence, bh as X402SettlementEvidenceReader, bi as X402SettlementSubmissionError, bj as X402_BATCH_AUTO_SETTLEMENT, bk as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bl as X402_BATCH_SETTLEMENT_NETWORK, bm as attachCreditMenu, bn as buildCreditMenu, bo as createDVMHost, bp as createX402BatchSettlementServer, bq as creditEnvelopeIgnoreFields, br as drawSettlementRef, bs as extractCreditEnvelope, bt as fundingCommitment, bu as selectPrimaryCredit, bv as signHostingClosure, bw as signHostingControl, bx as stripCreditEnvelope, by as toCreditView } from '../credit-menu-CAfqe8IY.js';
6
- import { Context } from 'hono';
4
+ import { au as CreditMenu, a as AppEnv, U as UpfrontPaymentOpts, i as PaymentInfo, av as ReceiptIssuer, aw as LightningReceive, ax as TempoSettlementReadiness, ay as DVMHostOpts, az as DVMServeResult, L as LockPubkeyStateLoader, C as ConsumedCredentialStore } from '../credit-menu-BAsrRu3z.js';
5
+ export { aA as BuildCreditMenuArgs, aB as BuilderIdentity, aC as CREDIT_ENVELOPE_KEYS, aD as CreateX402BatchSettlementServerOpts, aE as CreditEnvelope, aF as CreditEnvelopeError, aG as CreditFundCommitment, aH as CreditTerms, aI as DEFAULT_INVOICE_TTL_SECONDS, aJ as DVMHost, aK as HostingClosureCommand, aL as HostingClosureEvidence, aM as HostingControlCommand, aN as HostingControlConfig, aO as HostingControlStatus, aP as JobManager, aQ as JobManagerOpts, aR as LightningReceiveConfig, aS as MIN_INVOICE_TTL_SECONDS, aT as MemoryConsumedCredentialStore, aU as MemoryConsumedCredentialStoreOpts, aV as MemoryProcessedPaymentStore, aW as MemoryX402ExactSettlementStore, aX as MountOpts, aY as OwnerDisplay, aZ as PaidJobCompletion, a_ as PaymentMode, a$ as PlatformReporterOpts, b0 as PostgresProcessedPaymentStore, b1 as PostgresX402ExactSettlementStore, b2 as PriceFiat, b3 as ProcessedPaymentQuerier, b4 as ProcessedPaymentRail, b5 as ProcessedPaymentRecord, b6 as ProcessedPaymentReplayError, b7 as ProcessedPaymentStore, b8 as X402BatchAcceptance, b9 as X402BatchFunding, ba as X402BatchRefusal, bb as X402BatchSettlementServer, bc as X402ExactAcceptance, bd as X402ExactIntentConflictError, be as X402ExactSettlementAttempt, bf as X402ExactSettlementChainEvidence, bg as X402ExactSettlementEffect, bh as X402ExactSettlementEvidenceMissingError, bi as X402ExactSettlementEvidenceReader, bj as X402ExactSettlementIntent, bk as X402ExactSettlementNotReadyError, bl as X402ExactSettlementServer, bm as X402ExactSettlementServerOpts, bn as X402ExactSettlementStatus, bo as X402ExactSettlementStore, bp as X402SettlementChainEvidence, bq as X402SettlementEvidenceReader, br as X402SettlementSubmissionError, bs as X402_BATCH_AUTO_SETTLEMENT, bt as X402_BATCH_MIN_WITHDRAW_DELAY_SECONDS, bu as X402_BATCH_SETTLEMENT_NETWORK, bv as attachCreditMenu, bw as buildCreditMenu, bx as createDVMHost, by as createX402BatchSettlementServer, bz as creditEnvelopeIgnoreFields, bA as drawSettlementRef, bB as extractCreditEnvelope, bC as fundingCommitment, bD as selectPrimaryCredit, bE as signHostingClosure, bF as signHostingControl, bG as stripCreditEnvelope, bH as toCreditView } from '../credit-menu-BAsrRu3z.js';
6
+ import { Context, Hono } from 'hono';
7
7
  import { z } from 'zod';
8
- import { F as FxFetcher } from '../fx-D9nsN3n4.js';
9
- import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-Bx-VFRjg.js';
10
- export { a as JobStatus, b as JobStore, h as isStreamableJobStore } from '../job-store-Bx-VFRjg.js';
8
+ import { F as FxFetcher } from '../fx-BgDmyTdd.js';
9
+ import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters, b as JobStore } from '../job-store-BVeF5_Jq.js';
10
+ export { a as JobStatus, h as isStreamableJobStore } from '../job-store-BVeF5_Jq.js';
11
+ import { C as ContentHoldHistory, a as ContentHoldMutation } from '../content-retention-BTGSQRfP.js';
12
+ export { b as ContentHold, c as ContentHoldError, d as ContentHoldEvent, e as ContentHoldStore, f as ContentHoldsResponse, J as JobContentMetadata, g as baselineContentExpiry, h as contentMetadata, i as isContentHoldStore } from '../content-retention-BTGSQRfP.js';
11
13
  export { P as PinnedFetch, S as SSRFError, a as SSRFGuardOpts, b as SSRFReason, c as SSRFResolver, d as assertSafeUrl, e as createPinnedFetch } from '../ssrf-dMooihtY.js';
14
+ import { Env, BlankSchema } from 'hono/types';
12
15
  import 'mppx';
13
16
  import '@x402/core/server';
14
17
  import '@x402/evm/batch-settlement/server';
15
18
  import '@x402/core/types';
16
19
  import 'viem';
20
+ import '../lightning-backend-40fIzz1W.js';
17
21
  import '@cashu/cashu-ts';
18
- import '../lightning-backend-BAx2Y8pP.js';
19
22
 
20
23
  /** Lifetime of a per-call implicit credit before the ledger refuses new draws. */
21
24
  declare const IMPLICIT_CREDIT_TTL_MS: number;
@@ -395,6 +398,11 @@ declare class PostgresJobStore implements StreamableJobStore, ReceiptIssuingStor
395
398
  expectedLastActivityAt: number;
396
399
  redactedAt: number;
397
400
  }): Promise<boolean>;
401
+ getContentSnapshot(jobId: string, dvmId?: string): Promise<{
402
+ job: JobRecord;
403
+ history: ContentHoldHistory;
404
+ } | undefined>;
405
+ mutateContentHold(jobId: string, mutation: ContentHoldMutation, dvmId?: string): Promise<ContentHoldHistory>;
398
406
  claimReceiptSeq(jobId: string): Promise<number>;
399
407
  saveReceipt(jobId: string, receipt: JobReceipt): Promise<JobReceipt | undefined>;
400
408
  appendOutgoing(jobId: string, message: OutgoingMessage, opts?: AppendOutgoingOptions): Promise<number>;
@@ -513,4 +521,14 @@ declare function hasInvalidRequestId(data: unknown): boolean;
513
521
  /** Single-DVM host. Use createDVMHost for multiple mounts with distinct prefixes. */
514
522
  declare function serve<State, InputSchema extends ZodLike | undefined = undefined>(descriptor: DVMDescriptor<State, InputSchema>, opts?: DVMHostOpts): Promise<DVMServeResult>;
515
523
 
516
- export { BitcoinDepositLiability, BlockedInvoiceCursor, CREDIT_REQUEST_SCHEMA, CreditInvoiceRecord, CreditLedgerLike, CreditLedgerQuerier, CreditMenu, type CreditRequest, type CreditRouteDeps, CreditSnapshot, DVMAuthScheme, DVMHostOpts, DVMServeResult, DrawRecord, DrawResolution, DrawResult, FundingRecord, GrownDrawResult, IMPLICIT_CREDIT_TTL_MS, type InitLockPool, InvoiceReconciliation, InvoiceSettlement, InvoiceWriteOff, JobRecord, LightningReceive, MemoryCreditLedger, PostgresJobStore, PostgresKVStore, PostgresReplayStore, type PostgresReplayStoreOpts, REQUEST_ID_FIELD, type ResolvedCashuOpts, SDK_INIT_ADVISORY_LOCK, SignedRequestDomain, SignedRequestReplayStore, StalePendingDrawCursor, StreamableJobStore, handleCreditRequest, hasInvalidRequestId, protocolEnvelopeIgnoreFields, requestIdFromEnvelope, resolveCashuOptsFromEnv, serve, stripProtocolEnvelope, withSdkInitLock };
524
+ interface InstallAdminContentRoutesOpts {
525
+ dvmId: string;
526
+ store: JobStore;
527
+ retentionDays: number;
528
+ getLockPubkeyState: LockPubkeyStateLoader;
529
+ nonceStore: ConsumedCredentialStore;
530
+ now?: () => number;
531
+ }
532
+ declare function installAdminContentRoutes<E extends Env = Env, S extends BlankSchema = BlankSchema>(app: Hono<E, S>, opts: InstallAdminContentRoutesOpts): void;
533
+
534
+ export { BitcoinDepositLiability, BlockedInvoiceCursor, CREDIT_REQUEST_SCHEMA, ConsumedCredentialStore, ContentHoldHistory, ContentHoldMutation, CreditInvoiceRecord, CreditLedgerLike, CreditLedgerQuerier, CreditMenu, type CreditRequest, type CreditRouteDeps, CreditSnapshot, DVMAuthScheme, DVMHostOpts, DVMServeResult, DrawRecord, DrawResolution, DrawResult, FundingRecord, GrownDrawResult, IMPLICIT_CREDIT_TTL_MS, type InitLockPool, type InstallAdminContentRoutesOpts, InvoiceReconciliation, InvoiceSettlement, InvoiceWriteOff, JobRecord, JobStore, LightningReceive, MemoryCreditLedger, PostgresJobStore, PostgresKVStore, PostgresReplayStore, type PostgresReplayStoreOpts, REQUEST_ID_FIELD, type ResolvedCashuOpts, SDK_INIT_ADVISORY_LOCK, SignedRequestDomain, SignedRequestReplayStore, StalePendingDrawCursor, StreamableJobStore, handleCreditRequest, hasInvalidRequestId, installAdminContentRoutes, protocolEnvelopeIgnoreFields, requestIdFromEnvelope, resolveCashuOptsFromEnv, serve, stripProtocolEnvelope, withSdkInitLock };
@@ -62,6 +62,7 @@ import {
62
62
  hasInvalidRequestId,
63
63
  initLockPubkeyTable,
64
64
  initWalletAccumulatorTable,
65
+ installAdminContentRoutes,
65
66
  parseClientCapabilities,
66
67
  parseClientCompatibility,
67
68
  parseDvmClient,
@@ -78,7 +79,7 @@ import {
78
79
  stripProtocolEnvelope,
79
80
  toCreditView,
80
81
  unknownRouteNotFound
81
- } from "../chunk-EYTHFFFU.js";
82
+ } from "../chunk-HHBDBMEO.js";
82
83
  import {
83
84
  MemoryProcessedPaymentStore,
84
85
  PostgresProcessedPaymentStore,
@@ -90,22 +91,28 @@ import {
90
91
  } from "../chunk-FYRR2UEZ.js";
91
92
  import {
92
93
  PostgresJobStore
93
- } from "../chunk-PB4FYZET.js";
94
+ } from "../chunk-EQLA4FFY.js";
94
95
  import "../chunk-YG7G4DPZ.js";
95
96
  import {
96
97
  SignedRequestError,
97
98
  createDefaultReplayStore,
98
99
  createSignedRequestVerifier,
99
100
  signedRequestInput
100
- } from "../chunk-Z4KLECAC.js";
101
+ } from "../chunk-N5RZ5HVB.js";
101
102
  import {
102
103
  isStreamableJobStore
103
- } from "../chunk-O5AT6S5T.js";
104
+ } from "../chunk-IV6Q7NRW.js";
105
+ import {
106
+ ContentHoldError,
107
+ baselineContentExpiry,
108
+ contentMetadata,
109
+ isContentHoldStore
110
+ } from "../chunk-AFV77S4C.js";
104
111
  import {
105
112
  generateEphemeralReceiptKey,
106
113
  isTestMintUrl,
107
114
  receiptPubkeyFromSecret
108
- } from "../chunk-TUA7PYH7.js";
115
+ } from "../chunk-OQA7IHI4.js";
109
116
  import {
110
117
  X402_DEFAULT_FACILITATOR,
111
118
  X402_DEFAULT_NETWORK,
@@ -121,13 +128,14 @@ import {
121
128
  SIGNED_REQUEST_AUTH_ID,
122
129
  SIGNED_REQUEST_STATEMENT_VERSION,
123
130
  signedRequestStatementHeader
124
- } from "../chunk-A4YFWZ7R.js";
131
+ } from "../chunk-RCM3P2HE.js";
125
132
  import "../chunk-OFVV37XC.js";
126
133
  import {
127
134
  initLoggers
128
- } from "../chunk-6DOGTAHA.js";
135
+ } from "../chunk-QR2EF2NI.js";
129
136
  import "../chunk-66HGCPBU.js";
130
137
  import "../chunk-FUJ36YDV.js";
138
+ import "../chunk-BQJIFRAZ.js";
131
139
  import "../chunk-BYCEKO65.js";
132
140
  import "../chunk-AT6V3SY7.js";
133
141
  import {
@@ -1145,7 +1153,7 @@ function createDVMHost(opts = {}) {
1145
1153
  });
1146
1154
  applyRetryToPool(pool, "dvm-host");
1147
1155
  pgPool = pool;
1148
- const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-VLXLWXUQ.js");
1156
+ const { PostgresJobStore: PostgresJobStore2 } = await import("../postgres-job-store-VHLQBJZC.js");
1149
1157
  const pgJobStore = new PostgresJobStore2(pool);
1150
1158
  pendingInits.push(pgJobStore.init(), pgJobStore.initStreaming());
1151
1159
  jobStore = pgJobStore;
@@ -1453,7 +1461,7 @@ ${config.facilitatorAuth?.keyId ?? ""}`;
1453
1461
  }
1454
1462
  let sharedPgConsumedStore;
1455
1463
  if (pgPool) {
1456
- const { PostgresConsumedCredentialStore } = await import("../postgres-consumed-credential-store-CUQJKRSL.js");
1464
+ const { PostgresConsumedCredentialStore } = await import("../postgres-consumed-credential-store-BUVCAPLS.js");
1457
1465
  const consumedStore = new PostgresConsumedCredentialStore(pgPool);
1458
1466
  pendingInits.push(consumedStore.init());
1459
1467
  sharedPgConsumedStore = consumedStore;
@@ -2096,6 +2104,7 @@ export {
2096
2104
  CLIENT_COMPATIBILITY_HEADERS,
2097
2105
  CREDIT_ENVELOPE_KEYS,
2098
2106
  CREDIT_REQUEST_SCHEMA,
2107
+ ContentHoldError,
2099
2108
  CreditEnvelopeError,
2100
2109
  CreditLedger,
2101
2110
  CreditLedgerError,
@@ -2135,10 +2144,12 @@ export {
2135
2144
  allocateDrawValue,
2136
2145
  assertSafeUrl,
2137
2146
  attachCreditMenu,
2147
+ baselineContentExpiry,
2138
2148
  buildCreditMenu,
2139
2149
  clientCompatibilityAttributes,
2140
2150
  clientCompatibilityMiddleware,
2141
2151
  clientUpgradeRequired,
2152
+ contentMetadata,
2142
2153
  createDVMHost,
2143
2154
  createPinnedFetch,
2144
2155
  createSignedRequestVerifier,
@@ -2149,6 +2160,8 @@ export {
2149
2160
  fundingCommitment,
2150
2161
  handleCreditRequest,
2151
2162
  hasInvalidRequestId,
2163
+ installAdminContentRoutes,
2164
+ isContentHoldStore,
2152
2165
  isStreamableJobStore,
2153
2166
  parseClientCapabilities,
2154
2167
  parseClientCompatibility,
@@ -5427,7 +5427,7 @@ declare const DEFAULT_CREDIT_MAX: PriceValue;
5427
5427
  /** Platform default for {@link CreditConfig.ttl}: 30 days. */
5428
5428
  declare const DEFAULT_CREDIT_TTL_SECONDS: number;
5429
5429
  /** Default lifetime of caller-controlled job content before it is redacted. */
5430
- declare const DEFAULT_JOB_RETENTION_DAYS = 90;
5430
+ declare const DEFAULT_JOB_RETENTION_DAYS = 730;
5431
5431
  /**
5432
5432
  * Per-capability configuration for the multi-capability shape.
5433
5433
  * Each capability is an independent unit a caller pays for: its own input
@@ -5591,7 +5591,7 @@ interface DVMConfig<State = Record<string, unknown>, InputSchema extends ZodLike
5591
5591
  /**
5592
5592
  * Days terminal job content remains available before the SDK redacts it.
5593
5593
  * The durable row, payment linkage, and signed receipt remain for accounting
5594
- * and request-id safety. Default: 90. Set to `0` to disable automatic
5594
+ * and request-id safety. Default: 730. Set to `0` to disable automatic
5595
5595
  * redaction.
5596
5596
  */
5597
5597
  jobRetentionDays?: number;
@@ -1,5 +1,6 @@
1
- import { Y as JobReceipt, a1 as Message, a2 as MessageType, K as KVStore, L as Logger, u as ResponseContent, P as PaymentContent, S as SDKJobContext } from '../step-cache-QG_h5-3G.js';
2
- import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-Bx-VFRjg.js';
1
+ import { C as ContentHoldHistory, a as ContentHoldMutation } from '../content-retention-BTGSQRfP.js';
2
+ import { Y as JobReceipt, a1 as Message, a2 as MessageType, K as KVStore, L as Logger, u as ResponseContent, P as PaymentContent, S as SDKJobContext } from '../step-cache-CPdH1hei.js';
3
+ import { c as StreamableJobStore, R as ReceiptIssuingStore, J as JobRecord, d as RequestIdClaim, e as RequestIdClaimResult, f as JobRetentionCursor, O as OutgoingMessage, A as AppendOutgoingOptions, P as PaymentCreditDelta, V as VerifyAndCreditResult, g as JobCounters } from '../job-store-BVeF5_Jq.js';
3
4
  import 'hono';
4
5
  import 'mppx';
5
6
  import '@x402/core/server';
@@ -16,6 +17,7 @@ import '@cashu/cashu-ts';
16
17
  * concurrency control beyond JS's single-threaded execution.
17
18
  */
18
19
  declare class MemoryJobStore implements StreamableJobStore, ReceiptIssuingStore {
20
+ private contentHolds;
19
21
  private data;
20
22
  private messages;
21
23
  private nextSeq;
@@ -44,6 +46,11 @@ declare class MemoryJobStore implements StreamableJobStore, ReceiptIssuingStore
44
46
  expectedLastActivityAt: number;
45
47
  redactedAt: number;
46
48
  }): Promise<boolean>;
49
+ getContentSnapshot(jobId: string): Promise<{
50
+ job: JobRecord;
51
+ history: ContentHoldHistory;
52
+ } | undefined>;
53
+ mutateContentHold(jobId: string, mutation: ContentHoldMutation): Promise<ContentHoldHistory>;
47
54
  claimReceiptSeq(jobId: string): Promise<number>;
48
55
  saveReceipt(jobId: string, receipt: JobReceipt): Promise<JobReceipt | undefined>;
49
56
  appendOutgoing(jobId: string, message: OutgoingMessage, opts?: AppendOutgoingOptions): Promise<number>;
@@ -2,15 +2,18 @@ import {
2
2
  MemoryKVStore
3
3
  } from "../chunk-SDK6KDJN.js";
4
4
  import {
5
- JobCancelledError,
6
5
  MemoryJobStore,
7
6
  createInstrumentedFetch
8
- } from "../chunk-O5AT6S5T.js";
7
+ } from "../chunk-IV6Q7NRW.js";
8
+ import {
9
+ JobCancelledError
10
+ } from "../chunk-AFV77S4C.js";
9
11
  import {
10
12
  createNoopLogger
11
- } from "../chunk-6DOGTAHA.js";
13
+ } from "../chunk-QR2EF2NI.js";
12
14
  import "../chunk-66HGCPBU.js";
13
15
  import "../chunk-FUJ36YDV.js";
16
+ import "../chunk-BQJIFRAZ.js";
14
17
  import {
15
18
  validateCurrency
16
19
  } from "../chunk-BYCEKO65.js";
@@ -1,4 +1,4 @@
1
- import { C as Currency } from './step-cache-QG_h5-3G.js';
1
+ import { C as Currency } from './step-cache-CPdH1hei.js';
2
2
 
3
3
  /**
4
4
  * Thrown by `fiatToSatsCeil` / `satsToFiat` when the supplied `ratePerBtc` is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvmkit/sdk",
3
- "version": "0.5.0-rc.1",
3
+ "version": "0.6.0-rc.1",
4
4
  "description": "SDK for building accountless, pay-per-use Digital Vending Machines",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -36,7 +36,8 @@
36
36
  },
37
37
  "files": [
38
38
  "dist",
39
- "NOTICE"
39
+ "NOTICE",
40
+ "recipes"
40
41
  ],
41
42
  "engines": {
42
43
  "node": ">=22"
@@ -0,0 +1,137 @@
1
+ -- Run with psql -X -q -t -A -v ON_ERROR_STOP=1 -f financial-export-v1.sql > financial-evidence.json
2
+ -- The transaction gives every table one consistent snapshot. Optional rail tables
3
+ -- absent from this service are empty arrays. Keep this file with the export.
4
+ -- Receipts are signed over every field. Reject unsupported shapes instead of
5
+ -- removing signed extensions and silently producing unverifiable evidence.
6
+ CREATE OR REPLACE FUNCTION pg_temp.receipt_v1(value jsonb) RETURNS jsonb LANGUAGE plpgsql IMMUTABLE AS $$
7
+ DECLARE allowed text[]; nested_allowed text[]; item record; nested_item record;
8
+ BEGIN
9
+ IF value IS NULL OR value = 'null'::jsonb THEN RETURN value; END IF;
10
+ IF jsonb_typeof(value) <> 'object' OR value->'v' IS DISTINCT FROM '1'::jsonb THEN
11
+ RAISE EXCEPTION 'financial export v1: unsupported receipt version or shape';
12
+ END IF;
13
+ CASE value->>'kind'
14
+ WHEN 'credit_funding' THEN allowed := ARRAY['v','kind','credit_id','fund_id','funded_micro','balance_after_micro','ledger_seq','issued_at','caller_pubkey','dvm_id','dvm','receipt_pubkey','signature'];
15
+ WHEN 'credit_drain' THEN allowed := ARRAY['v','kind','credit_id','drain_id','event','method','amount_micro','balance_after_micro','ledger_seq','issued_at','caller_pubkey','dvm_id','dvm','receipt_pubkey','signature'];
16
+ ELSE
17
+ IF value ? 'kind' THEN RAISE EXCEPTION 'financial export v1: unsupported receipt kind'; END IF;
18
+ allowed := ARRAY['v','job_id','dvm_id','dvm','capability','outcome','reason','ended_by','seq','issued_at','requester_pubkey','result_hash','receipt_pubkey','signature','paid','timing','credit'];
19
+ END CASE;
20
+ FOR item IN SELECT key,val FROM jsonb_each(value) AS e(key,val) LOOP
21
+ IF NOT item.key = ANY(allowed) THEN
22
+ RAISE EXCEPTION 'financial export v1: unsupported signed receipt extension';
23
+ END IF;
24
+ IF item.key = ANY(ARRAY['paid','timing','credit']) THEN
25
+ IF jsonb_typeof(item.val) <> 'object' THEN
26
+ RAISE EXCEPTION 'financial export v1: unsupported receipt block';
27
+ END IF;
28
+ nested_allowed := CASE item.key
29
+ WHEN 'paid' THEN ARRAY['msats','rail','native_amount','native_asset','tx_hash','mint']
30
+ WHEN 'timing' THEN ARRAY['accepted_at_ms','terminal_at_ms','caller_wait_ms']
31
+ WHEN 'credit' THEN ARRAY['credit_id','draw_id','amount','balance_after','ledger_seq'] END;
32
+ FOR nested_item IN SELECT key,val FROM jsonb_each(item.val) AS n(key,val) LOOP
33
+ IF NOT nested_item.key = ANY(nested_allowed) OR jsonb_typeof(nested_item.val) = ANY(ARRAY['object','array']) THEN
34
+ RAISE EXCEPTION 'financial export v1: unsupported signed receipt block extension';
35
+ END IF;
36
+ END LOOP;
37
+ ELSIF jsonb_typeof(item.val) = ANY(ARRAY['object','array']) THEN
38
+ RAISE EXCEPTION 'financial export v1: unsupported receipt field shape';
39
+ END IF;
40
+ END LOOP;
41
+ RETURN value;
42
+ END
43
+ $$;
44
+ -- Unsigned evidence uses explicit scalar projections. Objects/arrays in scalar
45
+ -- positions are excluded, including inside the supported nested financial blocks.
46
+ CREATE OR REPLACE FUNCTION pg_temp.scalars_v1(value jsonb, strings text[], numbers text[], booleans text[] DEFAULT ARRAY[]::text[]) RETURNS jsonb LANGUAGE sql IMMUTABLE AS $$
47
+ SELECT CASE WHEN jsonb_typeof(value) <> 'object' THEN NULL ELSE
48
+ (SELECT COALESCE(jsonb_object_agg(key,val), '{}'::jsonb) FROM jsonb_each(value) AS e(key,val)
49
+ WHERE (key=ANY(strings) AND jsonb_typeof(val) IN ('string','null'))
50
+ OR (key=ANY(numbers) AND (jsonb_typeof(val) IN ('number','null') OR (jsonb_typeof(val)='string' AND val #>> '{}' ~ '^-?[0-9]+$')))
51
+ OR (key=ANY(booleans) AND jsonb_typeof(val) IN ('boolean','null'))) END
52
+ $$;
53
+ CREATE OR REPLACE FUNCTION pg_temp.settlement_v1(value jsonb) RETURNS jsonb LANGUAGE sql IMMUTABLE AS $$
54
+ SELECT pg_temp.scalars_v1(value,
55
+ ARRAY['tx_hash','transaction','channel_id','network','repair_kind','payer'],
56
+ ARRAY['settledAmount','settled_amount','amount','refunded_native','debited_native','surplus_native'], ARRAY['success','repaired'])
57
+ $$;
58
+ CREATE OR REPLACE FUNCTION pg_temp.fulfilment_v1(value jsonb) RETURNS jsonb LANGUAGE sql IMMUTABLE AS $$
59
+ SELECT pg_temp.scalars_v1(value, ARRAY['source','mintUrl','quoteId'], ARRAY['faceSats','reserveSats','invoiceMsats','routingFeeMsats'])
60
+ $$;
61
+ CREATE OR REPLACE FUNCTION pg_temp.lot_debits_v1(value jsonb) RETURNS jsonb LANGUAGE sql IMMUTABLE AS $$
62
+ SELECT CASE WHEN jsonb_typeof(value) <> 'array' THEN NULL ELSE
63
+ (SELECT COALESCE(jsonb_agg(pg_temp.scalars_v1(item, ARRAY['lotId'], ARRAY['micro','sats'])), '[]'::jsonb)
64
+ FROM jsonb_array_elements(value) item WHERE jsonb_typeof(item)='object') END
65
+ $$;
66
+ CREATE OR REPLACE FUNCTION pg_temp.effect_v1(value jsonb) RETURNS jsonb LANGUAGE sql IMMUTABLE AS $$
67
+ SELECT pg_temp.scalars_v1(value, ARRAY['callerId','dvmId','jobId'],
68
+ ARRAY['requiredMsats','paidMsats','fundedMicro','nativeAmount','topUpCapMicro'], ARRAY['drawBasis','askSatisfied','midJob'])
69
+ || jsonb_strip_nulls(jsonb_build_object(
70
+ 'priceFiat', pg_temp.scalars_v1(value->'priceFiat', ARRAY['currency'], ARRAY['amountMicro']),
71
+ 'fundOnly', pg_temp.scalars_v1(value->'fundOnly', ARRAY['creditId','fundId'], ARRAY[]::text[]),
72
+ 'topUp', pg_temp.scalars_v1(value->'topUp', ARRAY['creditId','drawId'], ARRAY[]::text[]),
73
+ 'creditEnvelope', pg_temp.scalars_v1(value->'creditEnvelope', ARRAY['creditId','drawId'], ARRAY[]::text[])))
74
+ $$;
75
+ CREATE OR REPLACE FUNCTION pg_temp.channel_config_v1(value jsonb) RETURNS jsonb LANGUAGE sql IMMUTABLE AS $$
76
+ SELECT pg_temp.scalars_v1(value, ARRAY['payer','payerAuthorizer','receiver','receiverAuthorizer'], ARRAY['withdrawDelay'])
77
+ || CASE WHEN value->>'token' ~ '^0x[0-9a-fA-F]{40}$' THEN jsonb_build_object('token',value->'token') ELSE '{}'::jsonb END
78
+ $$;
79
+ CREATE OR REPLACE FUNCTION pg_temp.tempo_state_v1(value jsonb) RETURNS jsonb LANGUAGE plpgsql IMMUTABLE AS $$
80
+ DECLARE state jsonb; amounts jsonb;
81
+ BEGIN
82
+ IF value IS NULL OR value='null'::jsonb THEN RETURN NULL; END IF;
83
+ IF jsonb_typeof(value)<>'string' THEN RETURN NULL; END IF;
84
+ BEGIN state := (value #>> '{}')::jsonb;
85
+ EXCEPTION WHEN OTHERS THEN RAISE EXCEPTION 'financial export v1: unsupported Tempo state'; END;
86
+ IF jsonb_typeof(state)<>'object' THEN RETURN NULL; END IF;
87
+ -- Normalize the store's tagged bigints without retaining vouchers or signatures.
88
+ SELECT COALESCE(jsonb_object_agg(key, regexp_replace(val #>> '{}', '#__bigint$', '')), '{}'::jsonb) INTO amounts
89
+ FROM jsonb_each(state) AS e(key,val)
90
+ WHERE key=ANY(ARRAY['deposit','spent','settledOnChain','highestVoucherAmount','closeRequestedAt'])
91
+ AND jsonb_typeof(val) IN ('number','string') AND val #>> '{}' ~ '^[0-9]+(#__bigint)?$';
92
+ RETURN pg_temp.scalars_v1(state, ARRAY['channelId','escrowContract','payee','payer'], ARRAY['chainId','units'], ARRAY['finalized']) || amounts
93
+ || CASE WHEN state->>'token' ~ '^0x[0-9a-fA-F]{40}$' THEN jsonb_build_object('token',state->'token') ELSE '{}'::jsonb END;
94
+ END
95
+ $$;
96
+ CREATE OR REPLACE FUNCTION pg_temp.financial_rows_v1(table_name text, columns text[]) RETURNS jsonb LANGUAGE plpgsql AS $$
97
+ DECLARE result jsonb;
98
+ BEGIN
99
+ IF to_regclass(table_name) IS NULL THEN RETURN '[]'::jsonb; END IF;
100
+ EXECUTE format('SELECT COALESCE(jsonb_agg(projected ORDER BY projected::text), ''[]''::jsonb) FROM (
101
+ SELECT (SELECT COALESCE(jsonb_object_agg(key,
102
+ CASE WHEN key=ANY(ARRAY[''sent_ref'',''settle_response'']) THEN pg_temp.settlement_v1(value)
103
+ WHEN key=''fulfilment'' THEN pg_temp.fulfilment_v1(value)
104
+ WHEN key=''lot_debits'' THEN pg_temp.lot_debits_v1(value)
105
+ WHEN key=''state_json'' THEN pg_temp.tempo_state_v1(value)
106
+ WHEN key=''channel_config'' THEN pg_temp.channel_config_v1(value)
107
+ WHEN key=''effect'' THEN pg_temp.effect_v1(value)
108
+ WHEN key=''receipt'' THEN pg_temp.receipt_v1(value)
109
+ WHEN key=''receipts'' THEN (SELECT COALESCE(jsonb_agg(pg_temp.receipt_v1(r)), ''[]''::jsonb) FROM jsonb_array_elements(value) r)
110
+ ELSE CASE WHEN jsonb_typeof(value) NOT IN (''object'',''array'') THEN value ELSE NULL END END), ''{}''::jsonb)
111
+ FROM jsonb_each(to_jsonb(t)) WHERE key=ANY($1)) projected FROM %I t) rows', table_name)
112
+ INTO result USING columns;
113
+ RETURN result;
114
+ END
115
+ $$;
116
+ BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY;
117
+ SELECT jsonb_build_object(
118
+ 'format', 'dvmkit-financial-evidence', 'version', 1,
119
+ 'jobs', pg_temp.financial_rows_v1('jobs', ARRAY['id','dvm_id','request_id','requester_pubkey','capability','status','created_at','last_activity_at','terminal_at_ms','ended_by','receipt','receipt_seq','paid_msats','payment_rail','payment_tx_hash','payment_transaction_hash','native_amount','native_asset','credit_id','draw_id','cost_amount_micro','cost_currency']),
120
+ 'credits', pg_temp.financial_rows_v1('credits', ARRAY['credit_id','caller_pubkey','currency','balance_micro','expiry_ms','status','last_ledger_seq','created_at','rail','native_asset','funding_ref','tempo_channel_id','x402_channel_id','msats_remaining','native_remaining']),
121
+ 'fundings', pg_temp.financial_rows_v1('credit_fundings', ARRAY['credit_id','fund_id','caller_pubkey','amount_micro','rail','created_at','balance_after_micro','ledger_seq','receipt']),
122
+ 'funding_lots', pg_temp.financial_rows_v1('credit_funding_lots', ARRAY['lot_id','credit_id','rail','sats_funded','credited_micro','remaining_micro','funding_ref','created_at']),
123
+ 'draws', pg_temp.financial_rows_v1('credit_draws', ARRAY['credit_id','draw_id','job_id','amount_micro','ledger_seq','status','balance_after_micro','created_at','resolved_at','draw_msats','allocated_msats','draw_native','grown_micro']),
124
+ 'drains', pg_temp.financial_rows_v1('credit_drains', ARRAY['credit_id','drain_id','method','amount_micro','balance_after_micro','drained_msats','drained_native','owed_sats','ledger_seq','status','receipts','sent_ref','fulfilment','lot_debits','created_at','parked_at','picked_up_at','sent_at','released_at','written_off_at']),
125
+ 'invoices', pg_temp.financial_rows_v1('credit_invoices', ARRAY['credit_id','fund_id','caller_pubkey','currency','amount_micro','amount_msats','payment_hash','status','expires_at','created_at','settled_at','reconciled_credit_id','reconciled_fund_id','resolved_at']),
126
+ 'expiry_releases', pg_temp.financial_rows_v1('credit_expiry_releases', ARRAY['credit_id','release_id','caller_pubkey','currency','rail','amount_micro','expiry_ms','released_at','reversed_at']),
127
+ 'tempo_channels', pg_temp.financial_rows_v1('mpp_tempo_channels', ARRAY['channel_key','state_json','updated_at']),
128
+ 'tempo_channel_tombstones', pg_temp.financial_rows_v1('mpp_tempo_channel_tombstones', ARRAY['channel_key','state_json','deleted_at_ms']),
129
+ 'tempo_close_intents', pg_temp.financial_rows_v1('mpp_tempo_close_intents', ARRAY['channel_id','drain_id','reference','forecast_pending','updated_at']),
130
+ 'x402_channels', pg_temp.financial_rows_v1('x402_batch_channels', ARRAY['channel_id','channel_config','charged_cumulative_amount','signed_max_claimable','balance','total_claimed','withdraw_requested_at','refund_nonce','onchain_synced_at','last_request_timestamp']),
131
+ 'x402_channel_tombstones', pg_temp.financial_rows_v1('x402_batch_channel_tombstones', ARRAY['channel_id','charged_cumulative_amount','signed_max_claimable','refund_nonce','deleted_at_ms']),
132
+ 'x402_batch_settlements', pg_temp.financial_rows_v1('x402_batch_settlements', ARRAY['settlement_id','channel_id','operation','effect_id','payment_id','status','submission_block','settle_response','created_at','updated_at','resolved_at']),
133
+ 'x402_exact_settlements', pg_temp.financial_rows_v1('x402_exact_settlement_intents', ARRAY['dvm_id','intent_id','network','asset','authorizer','recipient','value','status','effect','submission_block','transaction','settle_response','last_outcome','created_at','updated_at','resolved_at']),
134
+ 'tempo_losses', pg_temp.financial_rows_v1('tempo_credit_losses', ARRAY['credit_id','channel_id','caller_pubkey','currency','former_balance_micro','settled_on_chain_native','highest_voucher_native','consumed_service_micro','consumed_native','observed_at']),
135
+ 'x402_losses', pg_temp.financial_rows_v1('x402_credit_losses', ARRAY['credit_id','channel_id','caller_pubkey','currency','former_balance_micro','channel_balance_native','total_claimed_native','consumed_service_micro','observed_at'])
136
+ );
137
+ ROLLBACK;