feat(machine,state-machine): stamp Payment.extra per lamassu-next#44
Cash-out invoices created via `lnbits.createInvoice()` now carry the principal / commission / exchange-rate metadata satmachineadmin needs to drive DCA distribution without back-deriving from a stored rate. Closes the wire-format side of `aiolabs/lamassu-next#44`. Wire payload (matches the canonical names agreed in #44 comments #598/#599/#600 — `principal_sats` not `net_sats`, `fee_percent` not `fee_pct`): extra: { source: 'bitspire', type: 'cash_out', txid: context.txid, principal_sats: floor((fiatCents / 100) * exchangeRate), fee_sats: max(0, satsAmount - principal_sats), fee_percent: feePercent * 100, exchange_rate: context.exchangeRate, // raw market rate, sats/fiat currency: context.currency, // customer-paid currency } `bills` / `cassettes` deferred — they're meaningful for cash-in and partial-dispense reconciliation, neither of which is wired on the satmachineadmin side yet (#22, #3). Plumbing: - `ATMServices.generateInvoice` signature changes from `(amountMsat: number) => Promise<string>` to `(context: ATMContext) => Promise<string>`. The on-wire BOLT11 amount is derived inside the service as `satsAmount * 1000` msats; the rest of the context drives the extra payload. - State-machine `generatingInvoice` actor passes the full context instead of just msats. - Dev mock in `apps/machine/src/stores/atm.ts` updated to match. All 18 state-machine tests pass. Typecheck clean across the app. Two `// pragma: allowlist secret` markers added to lightning.ts on existing doc-comment lines that mention "private key" — the dev-env pre-commit secret scanner flagged them as false positives (every prior commit touching this file had bypassed via --no-verify). Cash-in (`generateLnurlWithdraw`) intentionally left alone for now — satmachineadmin's listener doesn't handle the outbound LNURL-withdraw flow yet (`aiolabs/satmachineadmin#22`), so stamping metadata it won't read would be premature. Will land alongside that issue.
This commit is contained in:
parent
ec14bb16c6
commit
b7cfb5d09b
4 changed files with 77 additions and 12 deletions
|
|
@ -46,7 +46,7 @@ export function createATMMachine(
|
|||
}
|
||||
return services.generateLnurlWithdraw(input)
|
||||
}),
|
||||
generateInvoice: fromPromise(async ({ input }: { input: number }) => {
|
||||
generateInvoice: fromPromise(async ({ input }: { input: ATMContext }) => {
|
||||
if (!services.generateInvoice) {
|
||||
throw new Error('generateInvoice service not provided')
|
||||
}
|
||||
|
|
@ -662,7 +662,12 @@ export function createATMMachine(
|
|||
generatingInvoice: {
|
||||
invoke: {
|
||||
src: 'generateInvoice',
|
||||
input: ({ context }) => context.satsAmount * 1000, // sats to msats
|
||||
// Pass the full context so the implementation can stamp
|
||||
// principal/fee/exchange-rate/etc. onto Payment.extra
|
||||
// (lamassu-next#44 / satmachineadmin#19). The on-wire
|
||||
// BOLT11 amount is derived inside the service as
|
||||
// `context.satsAmount * 1000` msats.
|
||||
input: ({ context }) => context,
|
||||
onDone: {
|
||||
target: 'displayingInvoice',
|
||||
actions: assign({
|
||||
|
|
|
|||
|
|
@ -199,8 +199,17 @@ export interface ATMServices {
|
|||
generateNdebit: (context: ATMContext) => Promise<string>
|
||||
/** Generate an LNURL-withdraw link (for cash-in - customer receives sats) - legacy */
|
||||
generateLnurlWithdraw: (context: ATMContext) => Promise<string>
|
||||
/** Generate a Lightning invoice */
|
||||
generateInvoice: (amountMsat: number) => Promise<string>
|
||||
/**
|
||||
* Generate a Lightning invoice (cash-out flow). Takes the full
|
||||
* `ATMContext` rather than a bare amount so the implementation can
|
||||
* populate `Payment.extra` with the principal/commission split,
|
||||
* exchange rate, currency, etc. — consumed by `satmachineadmin`
|
||||
* downstream (`aiolabs/lamassu-next#44`,
|
||||
* `aiolabs/satmachineadmin#19`). The on-wire BOLT11 amount is still
|
||||
* `context.satsAmount * 1000` msats (principal + commission for
|
||||
* cash-out); the extras are metadata only.
|
||||
*/
|
||||
generateInvoice: (context: ATMContext) => Promise<string>
|
||||
/** Send receipt via Nostr */
|
||||
sendNostrReceipt: (context: ATMContext) => Promise<void>
|
||||
/** Dispense cash (always resolves with result, never throws) */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue