From ec14bb16c668b5f9d28ca497fa9c5f27589f3568 Mon Sep 17 00:00:00 2001 From: Padreug Date: Thu, 14 May 2026 15:24:53 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20rename=20grossSats=20=E2=86=92=20pr?= =?UTF-8?q?incipalSats=20for=20terminology=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Gross" was operator-vs-customer ambiguous (cash-out: customer's gross payment = principal + commission, not the variable's value). atm-tui already settled on "principal" for the same quantity (bitspire/atm-tui src/db.zig:166-171, src/main.zig:98,716), and #44's Payment.extra proposal will surface it as `principal_sats` on the kind-21000 wire. Aligning the internal name removes one translation step across DB → TUI → state machine → wire envelope. Pure mechanical rename — no behavioral change. Also rewrites the computeFeeSats JSDoc to drop the "gross"/"net" framing and document the principalSats / on-wire satsAmount relationship explicitly. Refs aiolabs/lamassu-next#44 Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/machine/src/stores/atm.ts | 23 +++++++++++++---------- apps/machine/src/views/CashInView.vue | 6 +++--- packages/state-machine/src/machine.ts | 18 +++++++++--------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/apps/machine/src/stores/atm.ts b/apps/machine/src/stores/atm.ts index 7955f9f..f6c9380 100644 --- a/apps/machine/src/stores/atm.ts +++ b/apps/machine/src/stores/atm.ts @@ -28,13 +28,16 @@ const isElectron = typeof window !== 'undefined' && window.electronAPI !== undef /** * Compute fee in sats from context. - * Cash-in: customer gets net (gross - fee). Cash-out: customer pays gross + fee. + * + * principalSats = market-rate sats for the fiat amount (fiat × exchangeRate, no commission). + * Cash-in: on-wire satsAmount = principalSats - feeSats (customer receives less than principal) + * Cash-out: on-wire satsAmount = principalSats + feeSats (customer pays more than principal) */ function computeFeeSats(ctx: ATMContext, isCashIn: boolean): number { - const grossSats = ctx.exchangeRate > 0 ? Math.floor((ctx.fiatCents / 100) * ctx.exchangeRate) : 0 + const principalSats = ctx.exchangeRate > 0 ? Math.floor((ctx.fiatCents / 100) * ctx.exchangeRate) : 0 const feeSats = isCashIn - ? grossSats - ctx.satsAmount // cash-in: customer gets net - : ctx.satsAmount - grossSats // cash-out: customer pays gross + fee + ? principalSats - ctx.satsAmount // cash-in: customer receives less than principal + : ctx.satsAmount - principalSats // cash-out: customer pays more than principal return Math.max(0, feeSats) } @@ -850,9 +853,9 @@ export const useAtmStore = defineStore('atm', () => { // Calculate what the new sats amount would be const newFiatCents = ctx.fiatCents + denomination * 100 const newFiatUnits = newFiatCents / 100 - const grossSats = Math.floor(newFiatUnits * ctx.exchangeRate) - const fee = Math.floor(grossSats * ctx.feePercent) - const newSatsAmount = grossSats - fee + const principalSats = Math.floor(newFiatUnits * ctx.exchangeRate) + const fee = Math.floor(principalSats * ctx.feePercent) + const newSatsAmount = principalSats - fee // Check against available balance if (newSatsAmount > ctx.availableBalance) { @@ -1106,9 +1109,9 @@ export const useAtmStore = defineStore('atm', () => { // Calculate if this bill would exceed available balance const newFiatCents = ctx.fiatCents + denomination * 100 const newFiatUnits = newFiatCents / 100 - const grossSats = Math.floor(newFiatUnits * ctx.exchangeRate) - const fee = Math.floor(grossSats * ctx.feePercent) - const newSatsAmount = grossSats - fee + const principalSats = Math.floor(newFiatUnits * ctx.exchangeRate) + const fee = Math.floor(principalSats * ctx.feePercent) + const newSatsAmount = principalSats - fee if (newSatsAmount > ctx.availableBalance) { console.log( diff --git a/apps/machine/src/views/CashInView.vue b/apps/machine/src/views/CashInView.vue index 7956ca7..2a150b2 100644 --- a/apps/machine/src/views/CashInView.vue +++ b/apps/machine/src/views/CashInView.vue @@ -120,9 +120,9 @@ function canAcceptBill(denomination: number): boolean { if (!ctx) return false if (ctx.availableBalance <= 0 || ctx.exchangeRate === 0) return true const newFiatCents = ctx.fiatCents + denomination * 100 - const grossSats = Math.floor((newFiatCents / 100) * ctx.exchangeRate) - const fee = Math.floor(grossSats * ctx.feePercent) - return grossSats - fee <= ctx.availableBalance + const principalSats = Math.floor((newFiatCents / 100) * ctx.exchangeRate) + const fee = Math.floor(principalSats * ctx.feePercent) + return principalSats - fee <= ctx.availableBalance } const balanceLimitReached = computed(() => { diff --git a/packages/state-machine/src/machine.ts b/packages/state-machine/src/machine.ts index ebb3916..828eb39 100644 --- a/packages/state-machine/src/machine.ts +++ b/packages/state-machine/src/machine.ts @@ -189,9 +189,9 @@ export function createATMMachine( satsAmount: ({ context }) => { if (context.exchangeRate === 0) return 0 const fiatDollars = context.fiatCents / 100 - const grossSats = Math.floor(fiatDollars * context.exchangeRate) - const fee = Math.floor(grossSats * context.feePercent) - return grossSats - fee + const principalSats = Math.floor(fiatDollars * context.exchangeRate) + const fee = Math.floor(principalSats * context.feePercent) + return principalSats - fee }, }), calculateDispenseAmounts: assign({ @@ -324,10 +324,10 @@ export function createATMMachine( satsAmount: ({ context }) => { if (context.exchangeRate === 0) return 0 const fiatDollars = context.fiatCents / 100 - const grossSats = Math.floor(fiatDollars * context.exchangeRate) + const principalSats = Math.floor(fiatDollars * context.exchangeRate) // For cash-out, user pays the sats, so fee is added - const fee = Math.floor(grossSats * context.feePercent) - return grossSats + fee + const fee = Math.floor(principalSats * context.feePercent) + return principalSats + fee }, }), calculateDispenseFromSelection: assign({ @@ -372,9 +372,9 @@ export function createATMMachine( // cash we can't cover with sats if (context.availableBalance <= 0 || context.exchangeRate === 0) return false const newFiatCents = context.fiatCents + event.denomination * 100 - const grossSats = Math.floor((newFiatCents / 100) * context.exchangeRate) - const fee = Math.floor(grossSats * context.feePercent) - return grossSats - fee <= context.availableBalance + const principalSats = Math.floor((newFiatCents / 100) * context.exchangeRate) + const fee = Math.floor(principalSats * context.feePercent) + return principalSats - fee <= context.availableBalance }, // Cash-out guards hasSelectedAmount: ({ context }) => context.cashOutSelection.length > 0,