Fetch available currencies from LNbits core API

- Call /api/v1/currencies endpoint on LNbits core (not nostrmarket extension)
- Ensure 'sat' is always first in the currency list and used as default
- Add loading state for currency dropdown
- Add key prop to Select component for proper reactivity

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
padreug 2026-01-06 18:48:05 +01:00
parent 2ac584b1d6
commit b7db9bba5a
2 changed files with 45 additions and 19 deletions

View file

@ -47,10 +47,14 @@
<FormField v-slot="{ componentField }" name="currency">
<FormItem>
<FormLabel>Currency *</FormLabel>
<Select :disabled="isCreating" v-bind="componentField">
<Select
:key="`currency-select-${availableCurrencies.length}`"
:disabled="isCreating || isLoadingCurrencies"
v-bind="componentField"
>
<FormControl>
<SelectTrigger class="w-full">
<SelectValue placeholder="Select currency" />
<SelectValue :placeholder="isLoadingCurrencies ? 'Loading...' : 'Select currency'" />
</SelectTrigger>
</FormControl>
<SelectContent>
@ -275,6 +279,7 @@ const toast = useToast()
// Local state
const isCreating = ref(false)
const createError = ref<string | null>(null)
const isLoadingCurrencies = ref(false)
const availableCurrencies = ref<string[]>(['sat'])
const availableZones = ref<Zone[]>([])
const showNewZoneForm = ref(false)
@ -331,11 +336,27 @@ const onSubmit = form.handleSubmit(async (values) => {
// Methods
const loadAvailableCurrencies = async () => {
isLoadingCurrencies.value = true
try {
const currencies = await nostrmarketAPI.getCurrencies()
availableCurrencies.value = currencies
if (currencies.length > 0) {
// Ensure 'sat' is always first in the list
const satIndex = currencies.indexOf('sat')
if (satIndex === -1) {
// Add 'sat' at the beginning if not present
availableCurrencies.value = ['sat', ...currencies]
} else if (satIndex > 0) {
// Move 'sat' to the beginning if present but not first
const withoutSat = currencies.filter(c => c !== 'sat')
availableCurrencies.value = ['sat', ...withoutSat]
} else {
availableCurrencies.value = currencies
}
}
} catch (error) {
console.error('Failed to load currencies:', error)
} finally {
isLoadingCurrencies.value = false
}
}

View file

@ -371,30 +371,35 @@ export class NostrmarketAPI extends BaseService {
}
/**
* Get available currencies
* Get available currencies from the LNbits core API
* This endpoint returns currencies allowed by the server configuration
*/
async getCurrencies(): Promise<string[]> {
const baseCurrencies = ['sat']
// Call the LNbits core API directly (not under /nostrmarket)
const url = `${this.baseUrl}/api/v1/currencies`
try {
const apiCurrencies = await this.request<string[]>(
'/api/v1/currencies',
'', // No authentication needed for currencies endpoint
{ method: 'GET' }
)
const response = await fetch(url, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
if (apiCurrencies && Array.isArray(apiCurrencies)) {
// Combine base currencies with API currencies, removing duplicates
const allCurrencies = [...baseCurrencies, ...apiCurrencies.filter(currency => !baseCurrencies.includes(currency))]
this.debug('Retrieved currencies:', { count: allCurrencies.length, currencies: allCurrencies })
return allCurrencies
if (!response.ok) {
throw new Error(`Failed to fetch currencies: ${response.status}`)
}
this.debug('No API currencies returned, using base currencies only')
return baseCurrencies
const apiCurrencies = await response.json()
if (apiCurrencies && Array.isArray(apiCurrencies)) {
this.debug('Retrieved currencies from LNbits core:', { count: apiCurrencies.length, currencies: apiCurrencies })
return apiCurrencies
}
this.debug('No currencies returned from server, using default')
return ['sat']
} catch (error) {
this.debug('Failed to get currencies, falling back to base currencies:', error)
return baseCurrencies
this.debug('Failed to get currencies, using default:', error)
return ['sat']
}
}