refactor: rename fiatAmount to fiatCents for clarity
The field was always stored in cents but the name was ambiguous. Rename to fiatCents across state machine, store, and views. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
99ae5ab3de
commit
473834a363
6 changed files with 61 additions and 47 deletions
|
|
@ -271,7 +271,7 @@ export const useAtmStore = defineStore('atm', () => {
|
||||||
persistTransaction({
|
persistTransaction({
|
||||||
txid: ctx.txid,
|
txid: ctx.txid,
|
||||||
type: isCashInTx ? 'cash_in' : 'cash_out',
|
type: isCashInTx ? 'cash_in' : 'cash_out',
|
||||||
fiatCents: ctx.fiatAmount,
|
fiatCents: ctx.fiatCents,
|
||||||
sats: ctx.satsAmount,
|
sats: ctx.satsAmount,
|
||||||
bills,
|
bills,
|
||||||
})
|
})
|
||||||
|
|
@ -626,7 +626,7 @@ export const useAtmStore = defineStore('atm', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate what the new sats amount would be
|
// Calculate what the new sats amount would be
|
||||||
const newFiatCents = ctx.fiatAmount + denomination * 100
|
const newFiatCents = ctx.fiatCents + denomination * 100
|
||||||
const newFiatUnits = newFiatCents / 100
|
const newFiatUnits = newFiatCents / 100
|
||||||
const grossSats = Math.floor(newFiatUnits * ctx.exchangeRate)
|
const grossSats = Math.floor(newFiatUnits * ctx.exchangeRate)
|
||||||
const fee = Math.floor(grossSats * ctx.feePercent)
|
const fee = Math.floor(grossSats * ctx.feePercent)
|
||||||
|
|
@ -846,7 +846,7 @@ export const useAtmStore = defineStore('atm', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate if this bill would exceed available balance
|
// Calculate if this bill would exceed available balance
|
||||||
const newFiatCents = ctx.fiatAmount + denomination * 100
|
const newFiatCents = ctx.fiatCents + denomination * 100
|
||||||
const newFiatUnits = newFiatCents / 100
|
const newFiatUnits = newFiatCents / 100
|
||||||
const grossSats = Math.floor(newFiatUnits * ctx.exchangeRate)
|
const grossSats = Math.floor(newFiatUnits * ctx.exchangeRate)
|
||||||
const fee = Math.floor(grossSats * ctx.feePercent)
|
const fee = Math.floor(grossSats * ctx.feePercent)
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ function canAcceptBill(denomination: number): boolean {
|
||||||
const ctx = context.value
|
const ctx = context.value
|
||||||
if (!ctx) return false
|
if (!ctx) return false
|
||||||
if (ctx.availableBalance <= 0 || ctx.exchangeRate === 0) return true
|
if (ctx.availableBalance <= 0 || ctx.exchangeRate === 0) return true
|
||||||
const newFiatCents = ctx.fiatAmount + denomination * 100
|
const newFiatCents = ctx.fiatCents + denomination * 100
|
||||||
const grossSats = Math.floor((newFiatCents / 100) * ctx.exchangeRate)
|
const grossSats = Math.floor((newFiatCents / 100) * ctx.exchangeRate)
|
||||||
const fee = Math.floor(grossSats * ctx.feePercent)
|
const fee = Math.floor(grossSats * ctx.feePercent)
|
||||||
return grossSats - fee <= ctx.availableBalance
|
return grossSats - fee <= ctx.availableBalance
|
||||||
|
|
@ -214,7 +214,7 @@ const isProcessing = computed(() => atmStore.isPayingInvoice)
|
||||||
<!-- Amount display -->
|
<!-- Amount display -->
|
||||||
<div v-if="context">
|
<div v-if="context">
|
||||||
<p class="text-3xl lg:text-[6vh] font-bold text-success leading-tight">
|
<p class="text-3xl lg:text-[6vh] font-bold text-success leading-tight">
|
||||||
{{ atmStore.fiatSymbol }}{{ (context.fiatAmount / 100).toFixed(2) }}
|
{{ atmStore.fiatSymbol }}{{ (context.fiatCents / 100).toFixed(2) }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xl lg:text-[3.5vh] font-semibold text-bitcoin">
|
<p class="text-xl lg:text-[3.5vh] font-semibold text-bitcoin">
|
||||||
{{ formatSats(context.satsAmount) }} sats
|
{{ formatSats(context.satsAmount) }} sats
|
||||||
|
|
@ -322,7 +322,7 @@ const isProcessing = computed(() => atmStore.isPayingInvoice)
|
||||||
{{ formatSats(context?.satsAmount || 0) }} sats
|
{{ formatSats(context?.satsAmount || 0) }} sats
|
||||||
</p>
|
</p>
|
||||||
<p class="text-lg lg:text-2xl text-muted-foreground">
|
<p class="text-lg lg:text-2xl text-muted-foreground">
|
||||||
{{ atmStore.fiatSymbol }}{{ ((context?.fiatAmount || 0) / 100).toFixed(2) }}
|
{{ atmStore.fiatSymbol }}{{ ((context?.fiatCents || 0) / 100).toFixed(2) }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Waiting indicator -->
|
<!-- Waiting indicator -->
|
||||||
|
|
@ -388,7 +388,7 @@ const isProcessing = computed(() => atmStore.isPayingInvoice)
|
||||||
<h3 class="text-2xl lg:text-[3rem] font-bold text-destructive">Cash Already Accepted</h3>
|
<h3 class="text-2xl lg:text-[3rem] font-bold text-destructive">Cash Already Accepted</h3>
|
||||||
<p class="max-w-lg text-center text-base lg:text-2xl text-muted-foreground">
|
<p class="max-w-lg text-center text-base lg:text-2xl text-muted-foreground">
|
||||||
Your {{ atmStore.fiatSymbol
|
Your {{ atmStore.fiatSymbol
|
||||||
}}{{ context ? (context.fiatAmount / 100).toLocaleString() : '' }} has been accepted and
|
}}{{ context ? (context.fiatCents / 100).toLocaleString() : '' }} has been accepted and
|
||||||
cannot be returned. Please scan the QR code to receive your Bitcoin.
|
cannot be returned. Please scan the QR code to receive your Bitcoin.
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -428,7 +428,7 @@ const isProcessing = computed(() => atmStore.isPayingInvoice)
|
||||||
<div class="flex justify-between text-base lg:text-2xl">
|
<div class="flex justify-between text-base lg:text-2xl">
|
||||||
<span class="text-muted-foreground">Inserted</span>
|
<span class="text-muted-foreground">Inserted</span>
|
||||||
<span class="font-semibold"
|
<span class="font-semibold"
|
||||||
>{{ atmStore.fiatSymbol }}{{ (context.fiatAmount / 100).toFixed(2) }}</span
|
>{{ atmStore.fiatSymbol }}{{ (context.fiatCents / 100).toFixed(2) }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between text-base lg:text-2xl">
|
<div class="flex justify-between text-base lg:text-2xl">
|
||||||
|
|
@ -445,7 +445,7 @@ const isProcessing = computed(() => atmStore.isPayingInvoice)
|
||||||
>{{
|
>{{
|
||||||
formatSats(
|
formatSats(
|
||||||
Math.floor(
|
Math.floor(
|
||||||
Math.floor((context.fiatAmount / 100) * context.exchangeRate) *
|
Math.floor((context.fiatCents / 100) * context.exchangeRate) *
|
||||||
context.feePercent
|
context.feePercent
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ function formatFiat(cents: number): string {
|
||||||
<div class="text-center py-2 lg:py-4">
|
<div class="text-center py-2 lg:py-4">
|
||||||
<p class="text-sm lg:text-xl text-muted-foreground">You will receive</p>
|
<p class="text-sm lg:text-xl text-muted-foreground">You will receive</p>
|
||||||
<p class="text-4xl lg:text-[7vh] font-bold text-success leading-tight">
|
<p class="text-4xl lg:text-[7vh] font-bold text-success leading-tight">
|
||||||
{{ atmStore.fiatSymbol }}{{ context ? formatFiat(context.fiatAmount) : '0.00' }}
|
{{ atmStore.fiatSymbol }}{{ context ? formatFiat(context.fiatCents) : '0.00' }}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-1 lg:mt-2 text-lg lg:text-2xl text-muted-foreground">
|
<p class="mt-1 lg:mt-2 text-lg lg:text-2xl text-muted-foreground">
|
||||||
You pay:
|
You pay:
|
||||||
|
|
@ -291,7 +291,7 @@ function formatFiat(cents: number): string {
|
||||||
<p class="text-lg lg:text-2xl text-muted-foreground">
|
<p class="text-lg lg:text-2xl text-muted-foreground">
|
||||||
to receive
|
to receive
|
||||||
<Badge class="bg-success text-success-foreground text-lg lg:text-2xl">
|
<Badge class="bg-success text-success-foreground text-lg lg:text-2xl">
|
||||||
{{ atmStore.fiatSymbol }}{{ context ? formatFiat(context.fiatAmount) : '0.00' }}
|
{{ atmStore.fiatSymbol }}{{ context ? formatFiat(context.fiatCents) : '0.00' }}
|
||||||
</Badge>
|
</Badge>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -363,7 +363,7 @@ function formatFiat(cents: number): string {
|
||||||
<p v-if="context" class="text-lg lg:text-2xl">
|
<p v-if="context" class="text-lg lg:text-2xl">
|
||||||
Please take your
|
Please take your
|
||||||
<Badge class="bg-success text-success-foreground text-2xl"
|
<Badge class="bg-success text-success-foreground text-2xl"
|
||||||
>{{ atmStore.fiatSymbol }}{{ formatFiat(context.fiatAmount) }}</Badge
|
>{{ atmStore.fiatSymbol }}{{ formatFiat(context.fiatCents) }}</Badge
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -411,7 +411,7 @@ function formatFiat(cents: number): string {
|
||||||
formatSats(
|
formatSats(
|
||||||
Math.abs(
|
Math.abs(
|
||||||
context.satsAmount -
|
context.satsAmount -
|
||||||
Math.floor((context.fiatAmount / 100) * context.exchangeRate)
|
Math.floor((context.fiatCents / 100) * context.exchangeRate)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|
@ -422,7 +422,7 @@ function formatFiat(cents: number): string {
|
||||||
<div class="flex justify-between text-xl lg:text-[1.8rem] font-bold">
|
<div class="flex justify-between text-xl lg:text-[1.8rem] font-bold">
|
||||||
<span class="text-success">Cash received</span>
|
<span class="text-success">Cash received</span>
|
||||||
<span class="text-success"
|
<span class="text-success"
|
||||||
>{{ atmStore.fiatSymbol }}{{ formatFiat(context.fiatAmount) }}</span
|
>{{ atmStore.fiatSymbol }}{{ formatFiat(context.fiatCents) }}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ describe('ATM State Machine', () => {
|
||||||
actor.start()
|
actor.start()
|
||||||
|
|
||||||
const context = actor.getSnapshot().context
|
const context = actor.getSnapshot().context
|
||||||
expect(context.fiatAmount).toBe(0)
|
expect(context.fiatCents).toBe(0)
|
||||||
expect(context.satsAmount).toBe(0)
|
expect(context.satsAmount).toBe(0)
|
||||||
expect(context.billsInserted).toEqual([])
|
expect(context.billsInserted).toEqual([])
|
||||||
expect(context.error).toBeNull()
|
expect(context.error).toBeNull()
|
||||||
|
|
@ -78,7 +78,7 @@ describe('ATM State Machine', () => {
|
||||||
|
|
||||||
const context = actor.getSnapshot().context
|
const context = actor.getSnapshot().context
|
||||||
expect(context.billsInserted).toEqual([20, 10])
|
expect(context.billsInserted).toEqual([20, 10])
|
||||||
expect(context.fiatAmount).toBe(3000) // $30 in cents
|
expect(context.fiatCents).toBe(3000) // $30 in cents
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return to idle on CANCEL', async () => {
|
it('should return to idle on CANCEL', async () => {
|
||||||
|
|
@ -141,14 +141,14 @@ describe('ATM State Machine', () => {
|
||||||
|
|
||||||
let state = actor.getSnapshot()
|
let state = actor.getSnapshot()
|
||||||
expect(state.context.cashOutSelection).toEqual([20, 20, 20])
|
expect(state.context.cashOutSelection).toEqual([20, 20, 20])
|
||||||
expect(state.context.fiatAmount).toBe(6000) // $60 in cents
|
expect(state.context.fiatCents).toBe(6000) // $60 in cents
|
||||||
|
|
||||||
// Remove one
|
// Remove one
|
||||||
actor.send({ type: 'REMOVE_DENOMINATION', denomination: 20 })
|
actor.send({ type: 'REMOVE_DENOMINATION', denomination: 20 })
|
||||||
|
|
||||||
state = actor.getSnapshot()
|
state = actor.getSnapshot()
|
||||||
expect(state.context.cashOutSelection).toEqual([20, 20])
|
expect(state.context.cashOutSelection).toEqual([20, 20])
|
||||||
expect(state.context.fiatAmount).toBe(4000) // $40 in cents
|
expect(state.context.fiatCents).toBe(4000) // $40 in cents
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should calculate sats amount from fiat with fee', async () => {
|
it('should calculate sats amount from fiat with fee', async () => {
|
||||||
|
|
@ -164,8 +164,8 @@ describe('ATM State Machine', () => {
|
||||||
|
|
||||||
const state = actor.getSnapshot()
|
const state = actor.getSnapshot()
|
||||||
// $20 at 2500 sats/USD = 50,000 sats
|
// $20 at 2500 sats/USD = 50,000 sats
|
||||||
// Plus 2% fee = 51,000 sats
|
// Plus 7.77% cash-out fee = floor(50000 * 0.0777) = 3,885 → 53,885 sats
|
||||||
expect(state.context.satsAmount).toBe(51000)
|
expect(state.context.satsAmount).toBe(53885)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should generate invoice after confirming amount', async () => {
|
it('should generate invoice after confirming amount', async () => {
|
||||||
|
|
@ -396,7 +396,7 @@ describe('ATM State Machine', () => {
|
||||||
actor.send({ type: 'RETRY' })
|
actor.send({ type: 'RETRY' })
|
||||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||||
|
|
||||||
// Should have retried and succeeded
|
// Rate fetch failed → retry goes to fetchingRate → succeeds → insertingBills
|
||||||
const state = actor.getSnapshot()
|
const state = actor.getSnapshot()
|
||||||
expect(state.value).toMatchObject({ cashIn: 'insertingBills' })
|
expect(state.value).toMatchObject({ cashIn: 'insertingBills' })
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -180,17 +180,16 @@ export function createATMMachine(
|
||||||
if (event.type !== 'BILL_INSERTED') return context.billsInserted
|
if (event.type !== 'BILL_INSERTED') return context.billsInserted
|
||||||
return [...context.billsInserted, event.denomination]
|
return [...context.billsInserted, event.denomination]
|
||||||
},
|
},
|
||||||
fiatAmount: ({ context, event }) => {
|
fiatCents: ({ context, event }) => {
|
||||||
if (event.type !== 'BILL_INSERTED') return context.fiatAmount
|
if (event.type !== 'BILL_INSERTED') return context.fiatCents
|
||||||
// denomination is in dollars, fiatAmount is in cents
|
return context.fiatCents + event.denomination * 100
|
||||||
return context.fiatAmount + event.denomination * 100
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
calculateSats: assign({
|
calculateSats: assign({
|
||||||
satsAmount: ({ context }) => {
|
satsAmount: ({ context }) => {
|
||||||
if (context.exchangeRate === 0) return 0
|
if (context.exchangeRate === 0) return 0
|
||||||
const fiatUnits = context.fiatAmount / 100 // cents to dollars
|
const fiatDollars = context.fiatCents / 100
|
||||||
const grossSats = Math.floor(fiatUnits * context.exchangeRate)
|
const grossSats = Math.floor(fiatDollars * context.exchangeRate)
|
||||||
const fee = Math.floor(grossSats * context.feePercent)
|
const fee = Math.floor(grossSats * context.feePercent)
|
||||||
return grossSats - fee
|
return grossSats - fee
|
||||||
},
|
},
|
||||||
|
|
@ -200,7 +199,7 @@ export function createATMMachine(
|
||||||
// Calculate bills to dispense for cash-out
|
// Calculate bills to dispense for cash-out
|
||||||
// Simple algorithm: use largest denominations first
|
// Simple algorithm: use largest denominations first
|
||||||
const denominations = [100, 50, 20, 10, 5, 1]
|
const denominations = [100, 50, 20, 10, 5, 1]
|
||||||
let remaining = context.fiatAmount / 100 // cents to dollars
|
let remaining = context.fiatCents / 100
|
||||||
const amounts: { denomination: number; count: number }[] = []
|
const amounts: { denomination: number; count: number }[] = []
|
||||||
|
|
||||||
for (const denom of denominations) {
|
for (const denom of denominations) {
|
||||||
|
|
@ -278,7 +277,7 @@ export function createATMMachine(
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
setAmount: assign({
|
setAmount: assign({
|
||||||
fiatAmount: ({ event }) => {
|
fiatCents: ({ event }) => {
|
||||||
if (event.type !== 'SELECT_AMOUNT') return 0
|
if (event.type !== 'SELECT_AMOUNT') return 0
|
||||||
return event.amount * 100 // dollars to cents
|
return event.amount * 100 // dollars to cents
|
||||||
},
|
},
|
||||||
|
|
@ -296,9 +295,9 @@ export function createATMMachine(
|
||||||
if (event.type !== 'ADD_DENOMINATION') return context.cashOutSelection
|
if (event.type !== 'ADD_DENOMINATION') return context.cashOutSelection
|
||||||
return [...context.cashOutSelection, event.denomination]
|
return [...context.cashOutSelection, event.denomination]
|
||||||
},
|
},
|
||||||
fiatAmount: ({ context, event }) => {
|
fiatCents: ({ context, event }) => {
|
||||||
if (event.type !== 'ADD_DENOMINATION') return context.fiatAmount
|
if (event.type !== 'ADD_DENOMINATION') return context.fiatCents
|
||||||
return context.fiatAmount + event.denomination * 100 // dollars to cents
|
return context.fiatCents + event.denomination * 100
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
removeDenomination: assign({
|
removeDenomination: assign({
|
||||||
|
|
@ -310,21 +309,21 @@ export function createATMMachine(
|
||||||
newSelection.splice(idx, 1)
|
newSelection.splice(idx, 1)
|
||||||
return newSelection
|
return newSelection
|
||||||
},
|
},
|
||||||
fiatAmount: ({ context, event }) => {
|
fiatCents: ({ context, event }) => {
|
||||||
if (event.type !== 'REMOVE_DENOMINATION') return context.fiatAmount
|
if (event.type !== 'REMOVE_DENOMINATION') return context.fiatCents
|
||||||
if (!context.cashOutSelection.includes(event.denomination)) return context.fiatAmount
|
if (!context.cashOutSelection.includes(event.denomination)) return context.fiatCents
|
||||||
return context.fiatAmount - event.denomination * 100 // dollars to cents
|
return context.fiatCents - event.denomination * 100
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
clearCashOutSelection: assign({
|
clearCashOutSelection: assign({
|
||||||
cashOutSelection: () => [],
|
cashOutSelection: () => [],
|
||||||
fiatAmount: () => 0,
|
fiatCents: () => 0,
|
||||||
satsAmount: () => 0,
|
satsAmount: () => 0,
|
||||||
}),
|
}),
|
||||||
calculateSatsFromFiat: assign({
|
calculateSatsFromFiat: assign({
|
||||||
satsAmount: ({ context }) => {
|
satsAmount: ({ context }) => {
|
||||||
if (context.exchangeRate === 0) return 0
|
if (context.exchangeRate === 0) return 0
|
||||||
const fiatDollars = context.fiatAmount / 100 // cents to dollars
|
const fiatDollars = context.fiatCents / 100
|
||||||
const grossSats = Math.floor(fiatDollars * context.exchangeRate)
|
const grossSats = Math.floor(fiatDollars * context.exchangeRate)
|
||||||
// For cash-out, user pays the sats, so fee is added
|
// For cash-out, user pays the sats, so fee is added
|
||||||
const fee = Math.floor(grossSats * context.feePercent)
|
const fee = Math.floor(grossSats * context.feePercent)
|
||||||
|
|
@ -362,7 +361,7 @@ export function createATMMachine(
|
||||||
},
|
},
|
||||||
guards: {
|
guards: {
|
||||||
hasInsertedBills: ({ context }) => context.billsInserted.length > 0,
|
hasInsertedBills: ({ context }) => context.billsInserted.length > 0,
|
||||||
hasSufficientAmount: ({ context }) => context.fiatAmount >= 100, // $1 minimum
|
hasSufficientAmount: ({ context }) => context.fiatCents >= 100, // $1 minimum
|
||||||
hasExchangeRate: ({ context }) => context.exchangeRate > 0,
|
hasExchangeRate: ({ context }) => context.exchangeRate > 0,
|
||||||
canRetry: ({ context }) => context.retryCount < 3,
|
canRetry: ({ context }) => context.retryCount < 3,
|
||||||
hasUserNpub: ({ context }) => context.userNpub !== null,
|
hasUserNpub: ({ context }) => context.userNpub !== null,
|
||||||
|
|
@ -370,7 +369,7 @@ export function createATMMachine(
|
||||||
billWithinBalance: ({ context, event }) => {
|
billWithinBalance: ({ context, event }) => {
|
||||||
if (event.type !== 'BILL_INSERTED') return false
|
if (event.type !== 'BILL_INSERTED') return false
|
||||||
if (context.availableBalance <= 0 || context.exchangeRate === 0) return true
|
if (context.availableBalance <= 0 || context.exchangeRate === 0) return true
|
||||||
const newFiatCents = context.fiatAmount + event.denomination * 100
|
const newFiatCents = context.fiatCents + event.denomination * 100
|
||||||
const grossSats = Math.floor((newFiatCents / 100) * context.exchangeRate)
|
const grossSats = Math.floor((newFiatCents / 100) * context.exchangeRate)
|
||||||
const fee = Math.floor(grossSats * context.feePercent)
|
const fee = Math.floor(grossSats * context.feePercent)
|
||||||
return grossSats - fee <= context.availableBalance
|
return grossSats - fee <= context.availableBalance
|
||||||
|
|
@ -543,11 +542,26 @@ export function createATMMachine(
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
on: {
|
on: {
|
||||||
RETRY: {
|
RETRY: [
|
||||||
guard: 'canRetry',
|
{
|
||||||
target: 'generatingNdebit',
|
// Rate never loaded: retry from rate fetch
|
||||||
actions: 'incrementRetry',
|
guard: ({ context }) => context.retryCount < 3 && context.exchangeRate === 0,
|
||||||
},
|
target: 'fetchingRate',
|
||||||
|
actions: 'incrementRetry',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Ndebit failed before QR was shown: retry generation
|
||||||
|
guard: ({ context }) => context.retryCount < 3 && context.ndebitUri === null,
|
||||||
|
target: 'generatingNdebit',
|
||||||
|
actions: 'incrementRetry',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Payment failed but QR/LNURL still valid: show QR again
|
||||||
|
guard: 'canRetry',
|
||||||
|
target: 'displayingQR',
|
||||||
|
actions: 'incrementRetry',
|
||||||
|
},
|
||||||
|
],
|
||||||
CANCEL: [
|
CANCEL: [
|
||||||
{
|
{
|
||||||
// No bills inserted: safe to cancel
|
// No bills inserted: safe to cancel
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export interface OfferRequestEvent {
|
||||||
export interface ATMContext {
|
export interface ATMContext {
|
||||||
// Transaction details
|
// Transaction details
|
||||||
/** Fiat amount in cents */
|
/** Fiat amount in cents */
|
||||||
fiatAmount: number
|
fiatCents: number
|
||||||
/** Satoshi amount */
|
/** Satoshi amount */
|
||||||
satsAmount: number
|
satsAmount: number
|
||||||
/** Fiat currency code */
|
/** Fiat currency code */
|
||||||
|
|
@ -141,7 +141,7 @@ export type ATMEvent =
|
||||||
|
|
||||||
/** Initial context values */
|
/** Initial context values */
|
||||||
export const initialContext: ATMContext = {
|
export const initialContext: ATMContext = {
|
||||||
fiatAmount: 0,
|
fiatCents: 0,
|
||||||
satsAmount: 0,
|
satsAmount: 0,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
exchangeRate: 0,
|
exchangeRate: 0,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue