Fetches and applies real-time exchange rate

Fetches the current BTC/EUR exchange rate from the CoinGecko API and uses it to calculate fiat values.

This ensures more accurate currency conversions, especially for expenses and payments. A fallback to a default rate is included in case the API is unavailable.
This commit is contained in:
padreug 2025-10-23 10:04:37 +02:00
parent 60aba90e00
commit 176501211d

View file

@ -19,6 +19,7 @@ window.app = Vue.createApp({
isSuperUser: false, isSuperUser: false,
castleWalletConfigured: false, castleWalletConfigured: false,
userWalletConfigured: false, userWalletConfigured: false,
currentExchangeRate: null, // BTC/EUR rate (sats per EUR)
expenseDialog: { expenseDialog: {
show: false, show: false,
description: '', description: '',
@ -97,7 +98,7 @@ window.app = Vue.createApp({
paymentHash: null, paymentHash: null,
checkWalletKey: null, checkWalletKey: null,
pollIntervalId: null, pollIntervalId: null,
exchangeRate: 3571.43, // sats per EUR (TODO: fetch from API) exchangeRate: null, // Will be set from currentExchangeRate
originalCurrency: 'BTC' // Track original receivable currency originalCurrency: 'BTC' // Track original receivable currency
}, },
payUserDialog: { payUserDialog: {
@ -113,7 +114,7 @@ window.app = Vue.createApp({
reference: '', reference: '',
loading: false, loading: false,
paymentSuccess: false, paymentSuccess: false,
exchangeRate: 3571.43, exchangeRate: null, // Will be set from currentExchangeRate
originalCurrency: 'BTC' originalCurrency: 'BTC'
} }
} }
@ -1012,7 +1013,7 @@ window.app = Vue.createApp({
paymentHash: null, paymentHash: null,
checkWalletKey: null, checkWalletKey: null,
pollIntervalId: null, pollIntervalId: null,
exchangeRate: fiatAmount > 0 ? Math.abs(userBalance.balance) / fiatAmount : 3571.43, // Calculate rate from actual amounts exchangeRate: fiatAmount > 0 ? Math.abs(userBalance.balance) / fiatAmount : (this.currentExchangeRate || 3571.43), // Calculate rate from actual amounts or use current rate
originalCurrency: fiatCurrency || 'BTC' originalCurrency: fiatCurrency || 'BTC'
} }
}, },
@ -1213,7 +1214,7 @@ window.app = Vue.createApp({
reference: '', reference: '',
loading: false, loading: false,
paymentSuccess: false, paymentSuccess: false,
exchangeRate: fiatAmount > 0 ? userBalance.balance / fiatAmount : 3571.43, exchangeRate: fiatAmount > 0 ? userBalance.balance / fiatAmount : (this.currentExchangeRate || 3571.43),
originalCurrency: fiatCurrency || 'BTC' originalCurrency: fiatCurrency || 'BTC'
} }
}, },
@ -1357,6 +1358,27 @@ window.app = Vue.createApp({
return null return null
} }
}, },
async loadExchangeRate() {
try {
// Fetch current BTC/EUR rate from CoinGecko API
const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=eur')
const data = await response.json()
if (data && data.bitcoin && data.bitcoin.eur) {
// Convert BTC/EUR to sats/EUR (1 BTC = 100,000,000 sats)
const btcPerEur = 1 / data.bitcoin.eur
this.currentExchangeRate = Math.round(btcPerEur * 100000000)
console.log('Exchange rate loaded:', this.currentExchangeRate, 'sats per EUR')
} else {
throw new Error('Invalid response from exchange rate API')
}
} catch (error) {
console.error('Error loading exchange rate:', error)
// Fallback to a reasonable default if API fails
this.currentExchangeRate = 3571.43
console.log('Using fallback exchange rate:', this.currentExchangeRate)
}
},
formatSats(amount) { formatSats(amount) {
return new Intl.NumberFormat().format(amount) return new Intl.NumberFormat().format(amount)
}, },
@ -1425,6 +1447,7 @@ window.app = Vue.createApp({
// Load settings first to determine if user is super user // Load settings first to determine if user is super user
await this.loadSettings() await this.loadSettings()
await this.loadUserWallet() await this.loadUserWallet()
await this.loadExchangeRate()
await this.loadBalance() await this.loadBalance()
await this.loadTransactions() await this.loadTransactions()
await this.loadAccounts() await this.loadAccounts()