@dvmkit/sdk 0.1.0-rc.1 → 0.1.0-rc.2
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/dist/{chunk-RPXHKMYE.js → chunk-365P52XQ.js} +346 -33
- package/dist/{chunk-NTK5DJ6R.js → chunk-OJ5WFIB2.js} +11 -1
- package/dist/{credit-ledger-EDMEZSA2.js → credit-ledger-RO4FGSHG.js} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/{job-store-C5n6bhap.d.ts → job-store-6gR4pZRP.d.ts} +279 -19
- package/dist/{memory-credit-ledger-7TTZDSRS.js → memory-credit-ledger-I2G64DDK.js} +2 -2
- package/dist/payout-reporter-4TNWRS5F.js +753 -0
- package/dist/{revenue-reporter-M35KP6V7.js → revenue-reporter-GB4WKLDC.js} +77 -2
- package/dist/server/index.d.ts +64 -4
- package/dist/server/index.js +203 -25
- package/dist/{ssrf-BdHsrrIb.d.ts → ssrf-DZi-xJyn.d.ts} +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -739,7 +739,12 @@ type NonChannelBitcoinRail = (typeof NON_CHANNEL_BITCOIN_RAILS)[number];
|
|
|
739
739
|
* bought, with however much of that micro is still unspent.
|
|
740
740
|
*
|
|
741
741
|
* `remainingMicro` is depleted FIFO by settled draws and by reclaims, so the
|
|
742
|
-
* sum of a credit's lots tracks `credits.balance_micro` exactly
|
|
742
|
+
* sum of a credit's lots tracks `credits.balance_micro` exactly — with one
|
|
743
|
+
* deliberate exception: an expiry release (internal-review) zeroes the balance and
|
|
744
|
+
* leaves the lots standing, because a revival restores that balance and its
|
|
745
|
+
* in-kind basis has to still be there. A released credit is excluded from the
|
|
746
|
+
* sweep floor by `BITCOIN_CREDIT_PREDICATE`'s own `balance_micro > 0`, so the
|
|
747
|
+
* over-coverage is never counted as sats the builder owes back.
|
|
743
748
|
*/
|
|
744
749
|
interface FundingLot {
|
|
745
750
|
lotId: string;
|
|
@@ -855,6 +860,14 @@ interface CreditDepositPayload {
|
|
|
855
860
|
/** 32-byte channel id, `0x`-prefixed and lowercased. */
|
|
856
861
|
channelId: string;
|
|
857
862
|
};
|
|
863
|
+
/**
|
|
864
|
+
* Set by the blocked-invoice repair (internal-review): this deposit is a paid
|
|
865
|
+
* Lightning invoice the builder's agent reconciled onto a credit. The money
|
|
866
|
+
* landed in the receive wallet at payment time and this deposit is the one
|
|
867
|
+
* row it gets, so the settlements table types it `repair` off this flag
|
|
868
|
+
* rather than off a second row.
|
|
869
|
+
*/
|
|
870
|
+
repaired?: boolean;
|
|
858
871
|
}
|
|
859
872
|
/**
|
|
860
873
|
* JSON wire shape POSTed to the platform's `/_internal/credit-draw-release`
|
|
@@ -944,6 +957,64 @@ type CreditDrawReleaseEnqueue = (tx: RevenueReporterQuerier, payload: CreditDraw
|
|
|
944
957
|
* it before committing the status CAS that moved the money.
|
|
945
958
|
*/
|
|
946
959
|
type CreditDrainEnqueue = (tx: RevenueReporterQuerier, payload: CreditDrainPayload) => Promise<void>;
|
|
960
|
+
/**
|
|
961
|
+
* JSON wire shape POSTed to the platform's `/_internal/credit-expiry-release`
|
|
962
|
+
* endpoint (internal-review). A prepaid credit that reaches its TTL with an undrawn
|
|
963
|
+
* remainder RELEASES that remainder to the builder: on cashu, Lightning and
|
|
964
|
+
* x402 the funding value reached builder custody at funding time or on the
|
|
965
|
+
* settlement cycle, so expiry extinguishes the caller's remaining claim.
|
|
966
|
+
* Reported so committed value nets to
|
|
967
|
+
* `deposited − drawn − drained − released`; without it an expired credit is
|
|
968
|
+
* owed forever on paper, exactly like an unreported drain.
|
|
969
|
+
*
|
|
970
|
+
* Never sent for a Tempo credit. Tempo balances are channel-backed and undrawn
|
|
971
|
+
* channel value returns to the *caller* at exit, so no release exists on that
|
|
972
|
+
* rail — the sweep skips them and the platform refuses one outright.
|
|
973
|
+
*
|
|
974
|
+
* Two reports share this shape, distinguished only by `reversedAt`:
|
|
975
|
+
*
|
|
976
|
+
* - **The release**, written by the expiry sweep with `reversedAt` absent.
|
|
977
|
+
* - **The reversal**, written when a later funding revives the credit
|
|
978
|
+
* (`CreditLedger.fund` overwrites `expiry_ms`, so the recorded remainder is
|
|
979
|
+
* no longer final). It repeats the whole payload rather than sending a
|
|
980
|
+
* reference, because the retry loop can deliver the two out of order and the
|
|
981
|
+
* platform's upsert must be able to land either one first.
|
|
982
|
+
*
|
|
983
|
+
* Idempotent on `(dvmId, creditId, releaseId)`, so the shared retry loop can
|
|
984
|
+
* redeliver freely.
|
|
985
|
+
*/
|
|
986
|
+
interface CreditExpiryReleasePayload {
|
|
987
|
+
/** Required. Platform DVM record ID (`dvms.id`); must match the bearer token's DVM. */
|
|
988
|
+
dvmId: string;
|
|
989
|
+
/** Required. Credit whose remainder expired. */
|
|
990
|
+
creditId: string;
|
|
991
|
+
/** Required. Per-expiry-episode key; the platform idempotency key with DVM and credit. */
|
|
992
|
+
releaseId: string;
|
|
993
|
+
/** Required. Caller whose claim on the remainder ended. */
|
|
994
|
+
callerPubkey: string;
|
|
995
|
+
/** Funding rail. `null` on a credit funded before the basis became mandatory. */
|
|
996
|
+
rail: string | null;
|
|
997
|
+
/** Required. Fiat micro released — the liability this expiry extinguishes. */
|
|
998
|
+
amountMicro: number;
|
|
999
|
+
/** Required. Currency `amountMicro` is 1e-6 of. */
|
|
1000
|
+
creditCurrency: string;
|
|
1001
|
+
/** Required. When the credit's TTL ran out (epoch ms) — when the liability ended. */
|
|
1002
|
+
expiryMs: number;
|
|
1003
|
+
/** Required. When the sweep observed the expiry (epoch ms). */
|
|
1004
|
+
releasedAt: number;
|
|
1005
|
+
/** Set only on the reversal report: when the revival funding landed (epoch ms). */
|
|
1006
|
+
reversedAt?: number | null;
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Transactional expiry-release outbox seam, threaded through the sweep's insert
|
|
1010
|
+
* and through the funding that reverses a release (internal-review).
|
|
1011
|
+
*
|
|
1012
|
+
* Implemented by {@link RevenueReporter.enqueueCreditExpiryRelease}; callers
|
|
1013
|
+
* must await it before committing the write that made the release (or its
|
|
1014
|
+
* reversal) true, for the same reason the drain seam does — a report lost
|
|
1015
|
+
* between the two overstates or understates committed value forever.
|
|
1016
|
+
*/
|
|
1017
|
+
type CreditExpiryReleaseEnqueue = (tx: RevenueReporterQuerier, payload: CreditExpiryReleasePayload) => Promise<void>;
|
|
947
1018
|
/** Distinct causes for a settled credit draw that could not book revenue. */
|
|
948
1019
|
type RevenueSkippedNoRailReason = "credit_rail_null" | "credit_rail_unrecognized" | "job_rail_missing" | "ledger_not_configured";
|
|
949
1020
|
/**
|
|
@@ -1451,6 +1522,7 @@ declare class CreditLedger {
|
|
|
1451
1522
|
*/
|
|
1452
1523
|
readonly durable = true;
|
|
1453
1524
|
private x402Settlements?;
|
|
1525
|
+
private expiryReleaseOutbox?;
|
|
1454
1526
|
constructor(pool: CreditLedgerPool, tempoSessionStore?: TempoSessionSettlementStore | undefined);
|
|
1455
1527
|
/**
|
|
1456
1528
|
* Bind the durable x402 settlement state this ledger gates spending on
|
|
@@ -1462,6 +1534,22 @@ declare class CreditLedger {
|
|
|
1462
1534
|
* channel storage, where no settlement row can exist to wedge.
|
|
1463
1535
|
*/
|
|
1464
1536
|
useX402SettlementGate(gate: X402RefundSettlementGate): void;
|
|
1537
|
+
/**
|
|
1538
|
+
* Bind the durable outbox that reports credit-expiry releases and their
|
|
1539
|
+
* revivals to the platform (internal-review).
|
|
1540
|
+
*
|
|
1541
|
+
* Held on the ledger rather than threaded through {@link fund} for the same
|
|
1542
|
+
* reason as the gate above: the revival half fires from *every* funding path
|
|
1543
|
+
* — Cashu commit, x402 exact and channel, Tempo, the Lightning invoice
|
|
1544
|
+
* settle, the implicit N=1 per-call payment — and a seam each of those has to
|
|
1545
|
+
* remember to pass is a seam one of them will eventually forget.
|
|
1546
|
+
*
|
|
1547
|
+
* Unbound (a `dvmctl dev` server, a self-hosted builder, a test host) the
|
|
1548
|
+
* sweep and the reversal still run and still write the ledger's own rows;
|
|
1549
|
+
* only the platform report is skipped. Reporting is bookkeeping and must
|
|
1550
|
+
* never gate the ledger.
|
|
1551
|
+
*/
|
|
1552
|
+
useCreditExpiryReleaseOutbox(outbox: CreditExpiryReleaseOutbox): void;
|
|
1465
1553
|
/** Create the `credits` / `credit_draws` tables if absent. Call once at SDK boot. */
|
|
1466
1554
|
init(): Promise<void>;
|
|
1467
1555
|
/** The boot DDL itself — always runs under {@link withSdkInitLock} (internal-review). */
|
|
@@ -1499,9 +1587,15 @@ declare class CreditLedger {
|
|
|
1499
1587
|
*
|
|
1500
1588
|
* Pass `tx` (a client inside a caller-owned `BEGIN`) to commit the rail
|
|
1501
1589
|
* receive and the ledger credit atomically (spec condition 3 — the internal-review
|
|
1502
|
-
* verifier does this). The ledger issues **no** transaction control on `tx
|
|
1503
|
-
*
|
|
1504
|
-
*
|
|
1590
|
+
* verifier does this). The ledger issues **no** transaction control on `tx`.
|
|
1591
|
+
*
|
|
1592
|
+
* Without `tx` it opens one of its own, because a funding is no longer a
|
|
1593
|
+
* single statement: it upserts the credit, records its funding lot
|
|
1594
|
+
* (internal-review), and reverses any standing expiry release (internal-review) — and that
|
|
1595
|
+
* last leg restores balance and queues a report. A crash between the upsert
|
|
1596
|
+
* and the reversal would leave a revived credit whose release still stands,
|
|
1597
|
+
* which the sweep's own exclusion then makes permanent: `balance_micro > 0`
|
|
1598
|
+
* but a standing release means it is neither drainable nor re-releasable.
|
|
1505
1599
|
*
|
|
1506
1600
|
* `basis` records the rail value behind the fiat (internal-review) so each draw can
|
|
1507
1601
|
* be allocated its share of the rail-native amount actually received. A
|
|
@@ -1538,21 +1632,110 @@ declare class CreditLedger {
|
|
|
1538
1632
|
* below. This method is the authority on that rule, as it is on the binding
|
|
1539
1633
|
* rules above; every door preflights it where a refusal is still free.
|
|
1540
1634
|
*/
|
|
1541
|
-
fund(args:
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1635
|
+
fund(args: CreditFundArgs): Promise<CreditSnapshot>;
|
|
1636
|
+
/**
|
|
1637
|
+
* The funding itself, on whichever handle {@link fund} chose. Every refusal
|
|
1638
|
+
* it raises is the caller's to see unchanged; a self-opened transaction rolls
|
|
1639
|
+
* back around it.
|
|
1640
|
+
*/
|
|
1641
|
+
private fundOn;
|
|
1642
|
+
/**
|
|
1643
|
+
* Undo any expiry release this credit still carries, because a funding just
|
|
1644
|
+
* landed on it (internal-review — the revival rule), restoring the balance the
|
|
1645
|
+
* release took.
|
|
1646
|
+
*
|
|
1647
|
+
* A release records the credit's **final** undrawn remainder and zeroes it
|
|
1648
|
+
* (see {@link releaseExpiredCreditLocked}). Funding adds to the balance and
|
|
1649
|
+
* overwrites `expiry_ms` (spec §5 carry-forward: the credit is a rolling
|
|
1650
|
+
* buffer), so the moment money arrives the recorded remainder is no longer
|
|
1651
|
+
* final: the release stops counting and its micro come back.
|
|
1652
|
+
*
|
|
1653
|
+
* Deliberately unconditional on the incoming expiry rather than gated on
|
|
1654
|
+
* `expiryMs > nowMs`. A release exists only for a credit that had already
|
|
1655
|
+
* lapsed, so any funding that reaches one is money the release did not
|
|
1656
|
+
* account for — and a funding that arrives with an already-past expiry leaves
|
|
1657
|
+
* a credit the very next sweep re-releases at its new, larger remainder. One
|
|
1658
|
+
* rule, self-healing in both directions, and it never needs to read the
|
|
1659
|
+
* pre-funding expiry the upsert has already overwritten.
|
|
1660
|
+
*
|
|
1661
|
+
* Runs on the funding's own handle — which {@link fund} now guarantees is a
|
|
1662
|
+
* transaction — so the reversal, the restored balance and the report commit
|
|
1663
|
+
* with the money or not at all. A reversal that committed without its report
|
|
1664
|
+
* would be unrecoverable: `WHERE reversed_at IS NULL` means no later pass
|
|
1665
|
+
* re-derives it.
|
|
1666
|
+
*
|
|
1667
|
+
* @returns the credit row as the restore left it, or undefined when there was
|
|
1668
|
+
* nothing to reverse. The caller reads its snapshot off this rather than off
|
|
1669
|
+
* the funding upsert's `RETURNING`, which predates the restore.
|
|
1670
|
+
*/
|
|
1671
|
+
private reverseExpiryReleases;
|
|
1672
|
+
/**
|
|
1673
|
+
* Release the undrawn remainder of every credit whose TTL has run out
|
|
1674
|
+
* (internal-review). Returns the releases this pass recorded.
|
|
1675
|
+
*
|
|
1676
|
+
* **What is released.** The credit's whole `balance_micro`. Expiry ends
|
|
1677
|
+
* spending but never ownership of the record, so the balance stays readable;
|
|
1678
|
+
* what ends is the caller's claim on it, and on the prepaid rails the value
|
|
1679
|
+
* behind it is already in builder custody.
|
|
1680
|
+
*
|
|
1681
|
+
* **Tempo is excluded**, at both of its markers (`tempo_channel_id` and a
|
|
1682
|
+
* `tempo` rail). A Tempo credit is channel-backed and its undrawn value
|
|
1683
|
+
* returns to the *caller* at channel exit, so releasing it would book the
|
|
1684
|
+
* builder money the chain is about to hand back.
|
|
1685
|
+
*
|
|
1686
|
+
* **A credit with a pending hold is skipped, not partially released.** A draw
|
|
1687
|
+
* placed before expiry stays settleable afterwards (`draw`'s replay lookup
|
|
1688
|
+
* runs above the expiry check, so a lost response is still recoverable), so
|
|
1689
|
+
* the remainder is not final while a hold is outstanding. Skipping costs one
|
|
1690
|
+
* sweep interval and keeps the released figure exactly "what nothing bought";
|
|
1691
|
+
* holds do resolve — the orphan-draw watchdog (internal-review) is what guarantees
|
|
1692
|
+
* a stranded one still reaches a terminal state.
|
|
1693
|
+
*
|
|
1694
|
+
* **Idempotent** two ways. `release_id` is derived from the expiry instant,
|
|
1695
|
+
* so a re-sweep after a crash between the insert and its report collides on
|
|
1696
|
+
* the same primary key instead of writing a second row; and the candidate
|
|
1697
|
+
* scan excludes any credit that already has an un-reversed release.
|
|
1698
|
+
*
|
|
1699
|
+
* Each candidate is re-checked under the credit row lock every
|
|
1700
|
+
* `credit_draws` write is taken under, so a draw racing the sweep either
|
|
1701
|
+
* loses the race (its credit is already released and it would have been
|
|
1702
|
+
* refused `credit_expired` anyway) or wins it and leaves a pending hold the
|
|
1703
|
+
* locked re-check sees.
|
|
1704
|
+
*/
|
|
1705
|
+
sweepExpiredCredits(args?: {
|
|
1554
1706
|
nowMs?: number;
|
|
1555
|
-
|
|
1707
|
+
/** Credits released per pass. Bounds the work a long-idle DVM does at boot. */
|
|
1708
|
+
limit?: number;
|
|
1709
|
+
}): Promise<{
|
|
1710
|
+
released: CreditExpiryRelease[];
|
|
1711
|
+
}>;
|
|
1712
|
+
/**
|
|
1713
|
+
* Write one credit's expiry release under its row lock, zero the balance it
|
|
1714
|
+
* released, and re-assert every condition the unlocked candidate scan tested.
|
|
1715
|
+
* Returns undefined when the credit no longer qualifies — funded, drawn
|
|
1716
|
+
* against, or already released between the scan and the lock.
|
|
1717
|
+
*
|
|
1718
|
+
* **Zeroing the balance is what makes the release real**, and it is the whole
|
|
1719
|
+
* reason this runs under the lock rather than as a bare INSERT. The row alone
|
|
1720
|
+
* records that the caller's claim ended; it does not *end* it. `requestDrain`
|
|
1721
|
+
* has no expiry check by design (expiry gates new draws, not reclaims), so a
|
|
1722
|
+
* credit whose remainder had been released and reported was still fully
|
|
1723
|
+
* drainable: the DVM would pay out money the platform had already booked as
|
|
1724
|
+
* the builder's, and `deposited - drawn - drained - released` would go
|
|
1725
|
+
* negative on the same micro. With the balance at zero, `requestDrain`'s
|
|
1726
|
+
* existing `availableMicro <= 0` guard refuses with `nothing_to_drain` and no
|
|
1727
|
+
* new check is needed anywhere. {@link reverseExpiryReleases} puts the
|
|
1728
|
+
* balance back when a funding revives the credit.
|
|
1729
|
+
*
|
|
1730
|
+
* `status` deliberately stays `active`: a released credit must remain
|
|
1731
|
+
* fundable, or the revival rule has nothing to revive.
|
|
1732
|
+
*
|
|
1733
|
+
* The zeroed balance also takes the credit out of `BITCOIN_CREDIT_PREDICATE`
|
|
1734
|
+
* (`balance_micro > 0`), so the in-kind sweep floor stops counting sats the
|
|
1735
|
+
* builder no longer owes back — and counts them again after a revival, with
|
|
1736
|
+
* the credit's funding lots untouched throughout.
|
|
1737
|
+
*/
|
|
1738
|
+
private releaseExpiredCreditLocked;
|
|
1556
1739
|
/**
|
|
1557
1740
|
* Record this funding's in-kind basis as a lot (internal-review).
|
|
1558
1741
|
*
|
|
@@ -2054,7 +2237,15 @@ declare class CreditLedger {
|
|
|
2054
2237
|
listTempoCreditLosses(args?: {
|
|
2055
2238
|
limit?: number;
|
|
2056
2239
|
}): Promise<TempoCreditLoss[]>;
|
|
2057
|
-
/**
|
|
2240
|
+
/**
|
|
2241
|
+
* Reconcile the credit bound to a chain-proven empty x402 channel.
|
|
2242
|
+
*
|
|
2243
|
+
* A channel with no unclaimed backing makes every remaining customer
|
|
2244
|
+
* liability unsafe, so those credits become terminal. A fully settled credit
|
|
2245
|
+
* has neither a balance nor an unfinished drain and is safe to retain for a
|
|
2246
|
+
* later deposit. This also repairs a zero-liability row an older build
|
|
2247
|
+
* terminalized from the same observation.
|
|
2248
|
+
*/
|
|
2058
2249
|
terminalizeX402Credit(evidence: X402CreditLossEvidence, tx?: CreditLedgerQuerier): Promise<X402CreditLoss[]>;
|
|
2059
2250
|
private terminalizeX402CreditLocked;
|
|
2060
2251
|
/** List terminal x402 credit losses, newest observation first. */
|
|
@@ -2386,6 +2577,27 @@ interface CreditLedgerLike {
|
|
|
2386
2577
|
* {@link CreditLedger.useX402SettlementGate}.
|
|
2387
2578
|
*/
|
|
2388
2579
|
useX402SettlementGate?(gate: X402RefundSettlementGate): void;
|
|
2580
|
+
/**
|
|
2581
|
+
* Bind the outbox that reports credit-expiry releases and their revivals
|
|
2582
|
+
* (internal-review).
|
|
2583
|
+
*
|
|
2584
|
+
* Optional, and absent on `MemoryCreditLedger`: an expiry release is a
|
|
2585
|
+
* durable liability fact, and a ledger whose balances do not survive a
|
|
2586
|
+
* restart has none to report. A host on a non-durable ledger simply never
|
|
2587
|
+
* sweeps. See {@link CreditLedger.useCreditExpiryReleaseOutbox}.
|
|
2588
|
+
*/
|
|
2589
|
+
useCreditExpiryReleaseOutbox?(outbox: CreditExpiryReleaseOutbox): void;
|
|
2590
|
+
/**
|
|
2591
|
+
* Release the undrawn remainder of every credit past its TTL (internal-review).
|
|
2592
|
+
* Optional on the same terms as the binder above. See
|
|
2593
|
+
* {@link CreditLedger.sweepExpiredCredits}.
|
|
2594
|
+
*/
|
|
2595
|
+
sweepExpiredCredits?(args?: {
|
|
2596
|
+
nowMs?: number;
|
|
2597
|
+
limit?: number;
|
|
2598
|
+
}): Promise<{
|
|
2599
|
+
released: CreditExpiryRelease[];
|
|
2600
|
+
}>;
|
|
2389
2601
|
/**
|
|
2390
2602
|
* Ask that gate directly, so a route can refuse a wedged channel **before**
|
|
2391
2603
|
* the rail moves anything (internal-review). Optional on the same terms as the
|
|
@@ -2641,6 +2853,38 @@ interface CreditDrawReleaseOutbox {
|
|
|
2641
2853
|
/** Reporter-owned insert executed through the ledger transaction. */
|
|
2642
2854
|
enqueue: CreditDrawReleaseEnqueue;
|
|
2643
2855
|
}
|
|
2856
|
+
/** Reporter seam for credit-expiry releases and the revivals that reverse them (internal-review). */
|
|
2857
|
+
interface CreditExpiryReleaseOutbox {
|
|
2858
|
+
/** Platform DVM record ID bound into the report. */
|
|
2859
|
+
dvmId: string;
|
|
2860
|
+
/** Reporter-owned insert executed through the ledger transaction. */
|
|
2861
|
+
enqueue: CreditExpiryReleaseEnqueue;
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* One recorded expiry episode: a credit's undrawn remainder passing to the
|
|
2865
|
+
* builder when its TTL ran out (internal-review).
|
|
2866
|
+
*
|
|
2867
|
+
* `reversedAt` is set when a later funding revived the credit, at which point
|
|
2868
|
+
* the release stops counting against committed value — the row stays as the
|
|
2869
|
+
* record that it once did.
|
|
2870
|
+
*/
|
|
2871
|
+
interface CreditExpiryRelease {
|
|
2872
|
+
creditId: string;
|
|
2873
|
+
/** Per-expiry-episode key, derived from {@link CreditExpiryRelease.expiryMs}. */
|
|
2874
|
+
releaseId: string;
|
|
2875
|
+
callerPubkey: string;
|
|
2876
|
+
currency: string;
|
|
2877
|
+
/** Funding rail, or `null` on a credit funded before the basis was mandatory. */
|
|
2878
|
+
rail: string | null;
|
|
2879
|
+
/** Fiat micro released, 1e-6 of `currency`. */
|
|
2880
|
+
amountMicro: number;
|
|
2881
|
+
/** When the credit's TTL ran out — when the liability ended. */
|
|
2882
|
+
expiryMs: number;
|
|
2883
|
+
/** When the sweep observed the expiry. */
|
|
2884
|
+
releasedAt: number;
|
|
2885
|
+
/** When a funding revived the credit and undid this release. */
|
|
2886
|
+
reversedAt: number | null;
|
|
2887
|
+
}
|
|
2644
2888
|
/** Pool-shaped handle (`query` + `connect`). Required for the locked write paths. */
|
|
2645
2889
|
type CreditLedgerPool = Pick<Pool, "query" | "connect">;
|
|
2646
2890
|
/**
|
|
@@ -3059,6 +3303,22 @@ interface CreditFundingBasis {
|
|
|
3059
3303
|
maxClaimableAmount: string;
|
|
3060
3304
|
};
|
|
3061
3305
|
}
|
|
3306
|
+
/** What {@link CreditLedger.fund} takes. Named so the private body can share the shape. */
|
|
3307
|
+
interface CreditFundArgs {
|
|
3308
|
+
/** Omit to mint a fresh credit id; provide to top up (or idempotently create). */
|
|
3309
|
+
creditId?: string;
|
|
3310
|
+
callerPubkey: string;
|
|
3311
|
+
/** The DVM's pricing currency; `amountMicro` is 1e-6 of it. */
|
|
3312
|
+
currency: string;
|
|
3313
|
+
amountMicro: number;
|
|
3314
|
+
/** Absolute expiry, ms since epoch. Overwrites the previous value on top-up. */
|
|
3315
|
+
expiryMs: number;
|
|
3316
|
+
/** Rail-value basis this funding contributes (internal-review, required by internal-review). */
|
|
3317
|
+
basis: CreditFundingBasis;
|
|
3318
|
+
/** External transaction handle — caller owns BEGIN/COMMIT (spec condition 3). */
|
|
3319
|
+
tx?: CreditLedgerQuerier;
|
|
3320
|
+
nowMs?: number;
|
|
3321
|
+
}
|
|
3062
3322
|
/**
|
|
3063
3323
|
* Allocate a draw's share of a credit's unspent rail value (internal-review). Pure —
|
|
3064
3324
|
* shared by the Postgres and in-memory ledgers so the two can't drift.
|