diff --git a/packages/state-machine/src/machine.ts b/packages/state-machine/src/machine.ts index 480f741..2e0d918 100644 --- a/packages/state-machine/src/machine.ts +++ b/packages/state-machine/src/machine.ts @@ -68,6 +68,17 @@ export function createATMMachine(services: Partial = {}) { } return services.getExchangeRate(input) }), + // Fetch both exchange rate and available balance in parallel for cash-in + getRateAndBalance: fromPromise(async ({ input }: { input: string }) => { + if (!services.getExchangeRate) { + throw new Error('getExchangeRate service not provided') + } + const [exchangeRate, availableBalance] = await Promise.all([ + services.getExchangeRate(input), + services.getAvailableBalance ? services.getAvailableBalance() : Promise.resolve(0), + ]) + return { exchangeRate, availableBalance } + }), generateNoffer: fromPromise(async () => { if (!services.generateNoffer) { throw new Error('generateNoffer service not provided') @@ -363,12 +374,13 @@ export function createATMMachine(services: Partial = {}) { states: { fetchingRate: { invoke: { - src: 'getExchangeRate', + src: 'getRateAndBalance', input: ({ context }) => context.currency, onDone: { target: 'insertingBills', actions: assign({ - exchangeRate: ({ event }) => event.output, + exchangeRate: ({ event }) => event.output.exchangeRate, + availableBalance: ({ event }) => event.output.availableBalance, }), }, onError: { diff --git a/packages/state-machine/src/types.ts b/packages/state-machine/src/types.ts index a61f5f6..02f7f49 100644 --- a/packages/state-machine/src/types.ts +++ b/packages/state-machine/src/types.ts @@ -33,6 +33,8 @@ export interface ATMContext { exchangeRate: number /** Fee percentage (0.02 = 2%) */ feePercent: number + /** ATM's available balance in sats (for limiting cash-in transactions) */ + availableBalance: number // Payment /** BOLT11 invoice for payment */ @@ -128,6 +130,7 @@ export const initialContext: ATMContext = { currency: 'USD', exchangeRate: 0, feePercent: 0.02, + availableBalance: 0, invoice: null, clinkOffer: null, nofferString: null, @@ -167,6 +170,8 @@ export interface ATMServices { dispenseCash: (amounts: { denomination: number; count: number }[]) => Promise /** Get current exchange rate */ getExchangeRate: (currency: string) => Promise + /** Get ATM's available balance in sats (for limiting cash-in transactions) */ + getAvailableBalance: () => Promise /** Generate noffer string for cash-out (static payment code) */ generateNoffer: () => Promise /**