Adds fiat currency support for expenses

Extends expense entry functionality to support fiat currencies.

Users can now specify a currency (e.g., EUR, USD) when creating expense entries. The specified amount is converted to satoshis using exchange rates. The converted amount and currency information are stored in the journal entry metadata. Also adds an API endpoint to retrieve allowed currencies and updates the UI to allow currency selection when creating expense entries.
This commit is contained in:
padreug 2025-10-22 13:32:10 +02:00
parent 4bd83d6937
commit cd083114b4
5 changed files with 97 additions and 10 deletions

View file

@ -10,6 +10,7 @@ window.app = Vue.createApp({
balance: null,
transactions: [],
accounts: [],
currencies: [],
expenseDialog: {
show: false,
description: '',
@ -17,6 +18,7 @@ window.app = Vue.createApp({
expenseAccount: '',
isEquity: false,
reference: '',
currency: null,
loading: false
},
payDialog: {
@ -29,6 +31,19 @@ window.app = Vue.createApp({
computed: {
expenseAccounts() {
return this.accounts.filter(a => a.account_type === 'expense')
},
amountLabel() {
if (this.expenseDialog.currency) {
return `Amount (${this.expenseDialog.currency}) *`
}
return 'Amount (sats) *'
},
currencyOptions() {
const options = [{label: 'Satoshis (default)', value: null}]
this.currencies.forEach(curr => {
options.push({label: curr, value: curr})
})
return options
}
},
methods: {
@ -68,6 +83,18 @@ window.app = Vue.createApp({
LNbits.utils.notifyApiError(error)
}
},
async loadCurrencies() {
try {
const response = await LNbits.api.request(
'GET',
'/castle/api/v1/currencies',
this.g.user.wallets[0].inkey
)
this.currencies = response.data
} catch (error) {
LNbits.utils.notifyApiError(error)
}
},
async submitExpense() {
this.expenseDialog.loading = true
try {
@ -81,7 +108,8 @@ window.app = Vue.createApp({
expense_account: this.expenseDialog.expenseAccount,
is_equity: this.expenseDialog.isEquity,
user_wallet: this.g.user.wallets[0].id,
reference: this.expenseDialog.reference || null
reference: this.expenseDialog.reference || null,
currency: this.expenseDialog.currency || null
}
)
this.$q.notify({
@ -142,6 +170,7 @@ window.app = Vue.createApp({
this.expenseDialog.expenseAccount = ''
this.expenseDialog.isEquity = false
this.expenseDialog.reference = ''
this.expenseDialog.currency = null
},
formatSats(amount) {
return new Intl.NumberFormat().format(amount)
@ -158,5 +187,6 @@ window.app = Vue.createApp({
await this.loadBalance()
await this.loadTransactions()
await this.loadAccounts()
await this.loadCurrencies()
}
})