mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-09 20:12:34 +02:00
feat: improve on admin ui funding tab (#1989)
* feat: improve on admin ui funding tab * now only shows settings of selected fundingsource. * refactor into vue component * use camel case * refactor: move admin js into .js file (#1990) * updateFundingData is redundent now --------- Co-authored-by: Vlad Stan <stan.v.vlad@gmail.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
// update cache version every time there is a new deployment
|
// update cache version every time there is a new deployment
|
||||||
// so the service worker reinitializes the cache
|
// so the service worker reinitializes the cache
|
||||||
const CACHE_VERSION = 61
|
const CACHE_VERSION = 62
|
||||||
const CURRENT_CACHE = `lnbits-${CACHE_VERSION}-`
|
const CURRENT_CACHE = `lnbits-${CACHE_VERSION}-`
|
||||||
|
|
||||||
const getApiKey = request => {
|
const getApiKey = request => {
|
||||||
|
@@ -25,117 +25,71 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div v-if="'{{LNBITS_NODE_UI_AVAILABLE}}' === 'True'">
|
{% if LNBITS_NODE_UI_AVAILABLE %}
|
||||||
<div>Node Management</div>
|
<p>Node Management</p>
|
||||||
<q-toggle
|
<q-toggle
|
||||||
label="Node UI"
|
label="Node UI"
|
||||||
v-model="formData.lnbits_node_ui"
|
v-model="formData.lnbits_node_ui"
|
||||||
></q-toggle>
|
></q-toggle>
|
||||||
<q-toggle
|
<q-toggle
|
||||||
v-if="formData.lnbits_node_ui"
|
v-if="formData.lnbits_node_ui"
|
||||||
label="Public node UI"
|
label="Public node UI"
|
||||||
v-model="formData.lnbits_public_node_ui"
|
v-model="formData.lnbits_public_node_ui"
|
||||||
></q-toggle>
|
></q-toggle>
|
||||||
<q-toggle
|
<br />
|
||||||
v-if="formData.lnbits_node_ui"
|
<q-toggle
|
||||||
label="Transactions Tab (Disable on large CLN nodes)"
|
v-if="formData.lnbits_node_ui"
|
||||||
v-model="formData.lnbits_node_ui_transactions"
|
label="Transactions Tab (Disable on large CLN nodes)"
|
||||||
></q-toggle>
|
v-model="formData.lnbits_node_ui_transactions"
|
||||||
<br />
|
></q-toggle>
|
||||||
</div>
|
{% else %}
|
||||||
<p v-else>Node Management not supported by active funding source</p>
|
<p>Node Management not supported by active funding source</p>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row q-col-gutter-md">
|
<div class="row q-col-gutter-md">
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-4">
|
||||||
<div class="row">
|
<p>Invoice Expiry</p>
|
||||||
<div class="col-12">
|
<q-input
|
||||||
<p>Active Funding<small> (Requires server restart)</small></p>
|
filled
|
||||||
<q-select
|
v-model.number="formData.lightning_invoice_expiry"
|
||||||
:disable="!isSuperUser"
|
type="number"
|
||||||
filled
|
label="Invoice expiry (seconds)"
|
||||||
v-model="formData.lnbits_backend_wallet_class"
|
mask="#######"
|
||||||
hint="Select the active funding wallet"
|
>
|
||||||
:options="settings.lnbits_allowed_funding_sources"
|
</q-input>
|
||||||
></q-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-8">
|
<div class="col-12 col-md-8">
|
||||||
|
<p>Fee reserve</p>
|
||||||
<div class="row q-col-gutter-md">
|
<div class="row q-col-gutter-md">
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-6">
|
||||||
<p>Invoice Expiry</p>
|
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
|
||||||
v-model.number="formData.lightning_invoice_expiry"
|
|
||||||
type="number"
|
type="number"
|
||||||
label="Invoice expiry (seconds)"
|
filled
|
||||||
mask="#######"
|
v-model="formData.lnbits_reserve_fee_min"
|
||||||
|
label="Reserve fee in msats"
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-8">
|
<div class="col-6">
|
||||||
<p>Fee reserve</p>
|
<q-input
|
||||||
<div class="row q-col-gutter-md">
|
type="number"
|
||||||
<div class="col-6">
|
filled
|
||||||
<q-input
|
name="lnbits_reserve_fee_percent"
|
||||||
type="number"
|
v-model="formData.lnbits_reserve_fee_percent"
|
||||||
filled
|
label="Reserve fee in percent"
|
||||||
v-model="formData.lnbits_reserve_fee_min"
|
step="0.1"
|
||||||
label="Reserve fee in msats"
|
></q-input>
|
||||||
>
|
|
||||||
</q-input>
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
|
||||||
<q-input
|
|
||||||
type="number"
|
|
||||||
filled
|
|
||||||
name="lnbits_reserve_fee_percent"
|
|
||||||
v-model="formData.lnbits_reserve_fee_percent"
|
|
||||||
label="Reserve fee in percent"
|
|
||||||
step="0.1"
|
|
||||||
></q-input>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isSuperUser">
|
<div v-if="isSuperUser">
|
||||||
<p class="q-my-md">
|
<lnbits-funding-sources
|
||||||
Funding Sources<small> (Requires server restart)</small>
|
:form-data="formData"
|
||||||
</p>
|
:allowed-funding-sources="settings.lnbits_allowed_funding_sources"
|
||||||
<q-list
|
/>
|
||||||
v-for="(fund, idx) in settings.lnbits_allowed_funding_sources"
|
|
||||||
:key="idx"
|
|
||||||
>
|
|
||||||
<q-expansion-item
|
|
||||||
expand-separator
|
|
||||||
icon="payments"
|
|
||||||
:label="prettyFunding.get(fund) || fund"
|
|
||||||
v-if="funding_sources.get(fund)"
|
|
||||||
>
|
|
||||||
<q-card>
|
|
||||||
<q-card-section
|
|
||||||
v-for="([key, prop], i) in Object.entries(funding_sources.get(fund))"
|
|
||||||
:key="i"
|
|
||||||
>
|
|
||||||
<q-input
|
|
||||||
dense
|
|
||||||
filled
|
|
||||||
type="text"
|
|
||||||
v-model="formData[key]"
|
|
||||||
:label="prop.label"
|
|
||||||
class="q-pr-md"
|
|
||||||
:hint="prop.hint"
|
|
||||||
></q-input>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
</q-expansion-item>
|
|
||||||
</q-list>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
@@ -164,537 +164,5 @@
|
|||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||||
<script>
|
<script src="/static/js/admin.js"></script>
|
||||||
new Vue({
|
|
||||||
el: '#vue',
|
|
||||||
mixins: [windowMixin],
|
|
||||||
data: function () {
|
|
||||||
return {
|
|
||||||
settings: {},
|
|
||||||
logs: [],
|
|
||||||
serverlogEnabled: false,
|
|
||||||
lnbits_theme_options: [
|
|
||||||
'classic',
|
|
||||||
'bitcoin',
|
|
||||||
'flamingo',
|
|
||||||
'cyber',
|
|
||||||
'freedom',
|
|
||||||
'mint',
|
|
||||||
'autumn',
|
|
||||||
'monochrome',
|
|
||||||
'salvador'
|
|
||||||
],
|
|
||||||
auditData: {},
|
|
||||||
statusData: {},
|
|
||||||
statusDataTable: {
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
name: 'date',
|
|
||||||
align: 'left',
|
|
||||||
label: this.$t('date'),
|
|
||||||
field: 'date'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'message',
|
|
||||||
align: 'left',
|
|
||||||
label: this.$t('memo'),
|
|
||||||
field: 'message'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
formData: {},
|
|
||||||
formAddAdmin: '',
|
|
||||||
formAddUser: '',
|
|
||||||
formAddExtensionsManifest: '',
|
|
||||||
formAllowedIPs: '',
|
|
||||||
formBlockedIPs: '',
|
|
||||||
isSuperUser: false,
|
|
||||||
wallet: {},
|
|
||||||
cancel: {},
|
|
||||||
topUpDialog: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
tab: 'funding',
|
|
||||||
needsRestart: false,
|
|
||||||
prettyFunding: new Map([
|
|
||||||
['VoidWallet', 'Void Wallet'],
|
|
||||||
['FakeWallet', 'Fake Wallet'],
|
|
||||||
['CoreLightningWallet', 'Core Lightning'],
|
|
||||||
['CoreLightningRestWallet', 'Core Lightning'],
|
|
||||||
['LndRestWallet', 'Lightning Network Daemon (LND Rest)'],
|
|
||||||
['LndWallet', 'Lightning Network Daemon (LND)'],
|
|
||||||
['LnTipsWallet', 'LN.Tips'],
|
|
||||||
['LNPayWallet', 'LN Pay'],
|
|
||||||
['EclairWallet', 'Eclair (ACINQ)'],
|
|
||||||
['LNbitsWallet', 'LNBits'],
|
|
||||||
['OpenNodeWallet', 'OpenNode'],
|
|
||||||
['ClicheWallet', 'Cliche (NBD)'],
|
|
||||||
['SparkWallet', 'Spark']
|
|
||||||
]),
|
|
||||||
funding_sources: new Map([
|
|
||||||
['VoidWallet', null],
|
|
||||||
[
|
|
||||||
'FakeWallet',
|
|
||||||
{
|
|
||||||
fake_wallet_secret: {
|
|
||||||
value: null,
|
|
||||||
label: 'Secret'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'CoreLightningWallet',
|
|
||||||
{
|
|
||||||
corelightning_rpc: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'CoreLightningRestWallet',
|
|
||||||
{
|
|
||||||
corelightning_rest_url: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
corelightning_rest_cert: {
|
|
||||||
value: null,
|
|
||||||
label: 'Certificate'
|
|
||||||
},
|
|
||||||
corelightning_rest_macaroon: {
|
|
||||||
value: null,
|
|
||||||
label: 'Macaroon'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'LndRestWallet',
|
|
||||||
{
|
|
||||||
lnd_rest_endpoint: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
lnd_rest_cert: {
|
|
||||||
value: null,
|
|
||||||
label: 'Certificate'
|
|
||||||
},
|
|
||||||
lnd_rest_macaroon: {
|
|
||||||
value: null,
|
|
||||||
label: 'Macaroon'
|
|
||||||
},
|
|
||||||
lnd_rest_macaroon_encrypted: {
|
|
||||||
value: null,
|
|
||||||
label: 'Encrypted Macaroon'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'LndWallet',
|
|
||||||
{
|
|
||||||
lnd_grpc_endpoint: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
lnd_grpc_cert: {
|
|
||||||
value: null,
|
|
||||||
label: 'Certificate'
|
|
||||||
},
|
|
||||||
lnd_grpc_port: {
|
|
||||||
value: null,
|
|
||||||
label: 'Port'
|
|
||||||
},
|
|
||||||
lnd_grpc_admin_macaroon: {
|
|
||||||
value: null,
|
|
||||||
label: 'Admin Macaroon'
|
|
||||||
},
|
|
||||||
lnd_grpc_macaroon_encrypted: {
|
|
||||||
value: null,
|
|
||||||
label: 'Encrypted Macaroon'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'LnTipsWallet',
|
|
||||||
{
|
|
||||||
lntips_api_endpoint: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
lntips_api_key: {
|
|
||||||
value: null,
|
|
||||||
label: 'API Key'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'LNPayWallet',
|
|
||||||
{
|
|
||||||
lnpay_api_endpoint: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
lnpay_api_key: {
|
|
||||||
value: null,
|
|
||||||
label: 'API Key'
|
|
||||||
},
|
|
||||||
lnpay_wallet_key: {
|
|
||||||
value: null,
|
|
||||||
label: 'Wallet Key'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'EclairWallet',
|
|
||||||
{
|
|
||||||
eclair_url: {
|
|
||||||
value: null,
|
|
||||||
label: 'URL'
|
|
||||||
},
|
|
||||||
eclair_pass: {
|
|
||||||
value: null,
|
|
||||||
label: 'Password'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'LNbitsWallet',
|
|
||||||
{
|
|
||||||
lnbits_endpoint: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
lnbits_key: {
|
|
||||||
value: null,
|
|
||||||
label: 'Admin Key'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'OpenNodeWallet',
|
|
||||||
{
|
|
||||||
opennode_api_endpoint: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
opennode_key: {
|
|
||||||
value: null,
|
|
||||||
label: 'Key'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'ClicheWallet',
|
|
||||||
{
|
|
||||||
cliche_endpoint: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'SparkWallet',
|
|
||||||
{
|
|
||||||
spark_url: {
|
|
||||||
value: null,
|
|
||||||
label: 'Endpoint'
|
|
||||||
},
|
|
||||||
spark_token: {
|
|
||||||
value: null,
|
|
||||||
label: 'Token'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
])
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getSettings()
|
|
||||||
this.getAudit()
|
|
||||||
this.balance = +'{{ balance|safe }}'
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
lnbitsVersion() {
|
|
||||||
return LNBITS_VERSION
|
|
||||||
},
|
|
||||||
checkChanges() {
|
|
||||||
return !_.isEqual(this.settings, this.formData)
|
|
||||||
},
|
|
||||||
updateAvailable() {
|
|
||||||
return LNBITS_VERSION !== this.statusData.version
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
addAdminUser() {
|
|
||||||
let addUser = this.formAddAdmin
|
|
||||||
let admin_users = this.formData.lnbits_admin_users
|
|
||||||
if (addUser && addUser.length && !admin_users.includes(addUser)) {
|
|
||||||
//admin_users = [...admin_users, addUser]
|
|
||||||
this.formData.lnbits_admin_users = [...admin_users, addUser]
|
|
||||||
this.formAddAdmin = ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeAdminUser(user) {
|
|
||||||
let admin_users = this.formData.lnbits_admin_users
|
|
||||||
this.formData.lnbits_admin_users = admin_users.filter(u => u !== user)
|
|
||||||
},
|
|
||||||
addAllowedUser() {
|
|
||||||
let addUser = this.formAddUser
|
|
||||||
let allowed_users = this.formData.lnbits_allowed_users
|
|
||||||
if (addUser && addUser.length && !allowed_users.includes(addUser)) {
|
|
||||||
this.formData.lnbits_allowed_users = [...allowed_users, addUser]
|
|
||||||
this.formAddUser = ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeAllowedUser(user) {
|
|
||||||
let allowed_users = this.formData.lnbits_allowed_users
|
|
||||||
this.formData.lnbits_allowed_users = allowed_users.filter(
|
|
||||||
u => u !== user
|
|
||||||
)
|
|
||||||
},
|
|
||||||
addExtensionsManifest() {
|
|
||||||
const addManifest = this.formAddExtensionsManifest.trim()
|
|
||||||
const manifests = this.formData.lnbits_extensions_manifests
|
|
||||||
if (
|
|
||||||
addManifest &&
|
|
||||||
addManifest.length &&
|
|
||||||
!manifests.includes(addManifest)
|
|
||||||
) {
|
|
||||||
this.formData.lnbits_extensions_manifests = [
|
|
||||||
...manifests,
|
|
||||||
addManifest
|
|
||||||
]
|
|
||||||
this.formAddExtensionsManifest = ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeExtensionsManifest(manifest) {
|
|
||||||
const manifests = this.formData.lnbits_extensions_manifests
|
|
||||||
this.formData.lnbits_extensions_manifests = manifests.filter(
|
|
||||||
m => m !== manifest
|
|
||||||
)
|
|
||||||
},
|
|
||||||
async toggleServerLog() {
|
|
||||||
this.serverlogEnabled = !this.serverlogEnabled
|
|
||||||
if (this.serverlogEnabled) {
|
|
||||||
const wsProto = location.protocol !== 'http:' ? 'wss://' : 'ws://'
|
|
||||||
const digestHex = await LNbits.utils.digestMessage(this.g.user.id)
|
|
||||||
const localUrl =
|
|
||||||
wsProto +
|
|
||||||
document.domain +
|
|
||||||
':' +
|
|
||||||
location.port +
|
|
||||||
'/api/v1/ws/' +
|
|
||||||
digestHex
|
|
||||||
this.ws = new WebSocket(localUrl)
|
|
||||||
this.ws.addEventListener('message', async ({data}) => {
|
|
||||||
this.logs.push(data.toString())
|
|
||||||
const scrollArea = this.$refs.logScroll
|
|
||||||
if (scrollArea) {
|
|
||||||
const scrollTarget = scrollArea.getScrollTarget()
|
|
||||||
const duration = 0
|
|
||||||
scrollArea.setScrollPosition(scrollTarget.scrollHeight, duration)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.ws.close()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addAllowedIPs() {
|
|
||||||
const allowedIPs = this.formAllowedIPs.trim()
|
|
||||||
const allowed_ips = this.formData.lnbits_allowed_ips
|
|
||||||
if (
|
|
||||||
allowedIPs &&
|
|
||||||
allowedIPs.length &&
|
|
||||||
!allowed_ips.includes(allowedIPs)
|
|
||||||
) {
|
|
||||||
this.formData.lnbits_allowed_ips = [...allowed_ips, allowedIPs]
|
|
||||||
this.formAllowedIPs = ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeAllowedIPs(allowed_ip) {
|
|
||||||
const allowed_ips = this.formData.lnbits_allowed_ips
|
|
||||||
this.formData.lnbits_allowed_ips = allowed_ips.filter(
|
|
||||||
a => a !== allowed_ip
|
|
||||||
)
|
|
||||||
},
|
|
||||||
addBlockedIPs() {
|
|
||||||
const blockedIPs = this.formBlockedIPs.trim()
|
|
||||||
const blocked_ips = this.formData.lnbits_blocked_ips
|
|
||||||
if (
|
|
||||||
blockedIPs &&
|
|
||||||
blockedIPs.length &&
|
|
||||||
!blocked_ips.includes(blockedIPs)
|
|
||||||
) {
|
|
||||||
this.formData.lnbits_blocked_ips = [...blocked_ips, blockedIPs]
|
|
||||||
this.formBlockedIPs = ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeBlockedIPs(blocked_ip) {
|
|
||||||
const blocked_ips = this.formData.lnbits_blocked_ips
|
|
||||||
this.formData.lnbits_blocked_ips = blocked_ips.filter(
|
|
||||||
b => b !== blocked_ip
|
|
||||||
)
|
|
||||||
},
|
|
||||||
restartServer() {
|
|
||||||
LNbits.api
|
|
||||||
.request('GET', '/admin/api/v1/restart/?usr=' + this.g.user.id)
|
|
||||||
.then(response => {
|
|
||||||
this.$q.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message: 'Success! Restarted Server',
|
|
||||||
icon: null
|
|
||||||
})
|
|
||||||
this.needsRestart = false
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
topupWallet() {
|
|
||||||
LNbits.api
|
|
||||||
.request(
|
|
||||||
'PUT',
|
|
||||||
'/admin/api/v1/topup/?usr=' + this.g.user.id,
|
|
||||||
this.g.user.wallets[0].adminkey,
|
|
||||||
this.wallet
|
|
||||||
)
|
|
||||||
.then(response => {
|
|
||||||
this.$q.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message:
|
|
||||||
'Success! Added ' +
|
|
||||||
this.wallet.amount +
|
|
||||||
' to ' +
|
|
||||||
this.wallet.id,
|
|
||||||
icon: null
|
|
||||||
})
|
|
||||||
this.wallet = {}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
updateFundingData() {
|
|
||||||
this.settings.lnbits_allowed_funding_sources.map(f => {
|
|
||||||
let opts = this.funding_sources.get(f)
|
|
||||||
if (!opts) return
|
|
||||||
Object.keys(opts).forEach(e => {
|
|
||||||
opts[e].value = this.settings[e]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
formatDate(date) {
|
|
||||||
return moment(date * 1000).fromNow()
|
|
||||||
},
|
|
||||||
getNotifications() {
|
|
||||||
if (this.settings.lnbits_notifications) {
|
|
||||||
axios
|
|
||||||
.get(this.settings.lnbits_status_manifest)
|
|
||||||
.then(response => {
|
|
||||||
this.statusData = response.data
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.formData.lnbits_notifications = false
|
|
||||||
error.response.data = {}
|
|
||||||
error.response.data.message = 'Could not fetch status manifest.'
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getAudit() {
|
|
||||||
LNbits.api
|
|
||||||
.request(
|
|
||||||
'GET',
|
|
||||||
'/admin/api/v1/audit/?usr=' + this.g.user.id,
|
|
||||||
this.g.user.wallets[0].adminkey
|
|
||||||
)
|
|
||||||
.then(response => {
|
|
||||||
this.auditData = response.data
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getSettings() {
|
|
||||||
LNbits.api
|
|
||||||
.request(
|
|
||||||
'GET',
|
|
||||||
'/admin/api/v1/settings/?usr=' + this.g.user.id,
|
|
||||||
this.g.user.wallets[0].adminkey
|
|
||||||
)
|
|
||||||
.then(response => {
|
|
||||||
this.isSuperUser = response.data.is_super_user || false
|
|
||||||
this.settings = response.data
|
|
||||||
this.formData = {...this.settings}
|
|
||||||
this.updateFundingData()
|
|
||||||
this.getNotifications()
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
updateSettings() {
|
|
||||||
let data = _.omit(this.formData, [
|
|
||||||
'is_super_user',
|
|
||||||
'lnbits_allowed_funding_sources'
|
|
||||||
])
|
|
||||||
LNbits.api
|
|
||||||
.request(
|
|
||||||
'PUT',
|
|
||||||
'/admin/api/v1/settings/?usr=' + this.g.user.id,
|
|
||||||
this.g.user.wallets[0].adminkey,
|
|
||||||
data
|
|
||||||
)
|
|
||||||
.then(response => {
|
|
||||||
this.needsRestart =
|
|
||||||
this.settings.lnbits_backend_wallet_class !==
|
|
||||||
this.formData.lnbits_backend_wallet_class ||
|
|
||||||
this.settings.lnbits_killswitch !==
|
|
||||||
this.formData.lnbits_killswitch
|
|
||||||
this.settings = this.formData
|
|
||||||
this.formData = _.clone(this.settings)
|
|
||||||
this.updateFundingData()
|
|
||||||
this.$q.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message: `Success! Settings changed! ${
|
|
||||||
this.needsRestart ? 'Restart required!' : ''
|
|
||||||
}`,
|
|
||||||
icon: null
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
deleteSettings() {
|
|
||||||
LNbits.utils
|
|
||||||
.confirmDialog(
|
|
||||||
'Are you sure you want to restore settings to default?'
|
|
||||||
)
|
|
||||||
.onOk(() => {
|
|
||||||
LNbits.api
|
|
||||||
.request(
|
|
||||||
'DELETE',
|
|
||||||
'/admin/api/v1/settings/?usr=' + this.g.user.id
|
|
||||||
)
|
|
||||||
.then(response => {
|
|
||||||
this.$q.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message:
|
|
||||||
'Success! Restored settings to defaults, restart required!',
|
|
||||||
icon: null
|
|
||||||
})
|
|
||||||
this.needsRestart = true
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
downloadBackup() {
|
|
||||||
window.open('/admin/api/v1/backup/?usr=' + this.g.user.id, '_blank')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
20
lnbits/static/bundle.min.js
vendored
20
lnbits/static/bundle.min.js
vendored
File diff suppressed because one or more lines are too long
316
lnbits/static/js/admin.js
Normal file
316
lnbits/static/js/admin.js
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
new Vue({
|
||||||
|
el: '#vue',
|
||||||
|
mixins: [windowMixin],
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
settings: {},
|
||||||
|
logs: [],
|
||||||
|
serverlogEnabled: false,
|
||||||
|
lnbits_theme_options: [
|
||||||
|
'classic',
|
||||||
|
'bitcoin',
|
||||||
|
'flamingo',
|
||||||
|
'cyber',
|
||||||
|
'freedom',
|
||||||
|
'mint',
|
||||||
|
'autumn',
|
||||||
|
'monochrome',
|
||||||
|
'salvador'
|
||||||
|
],
|
||||||
|
auditData: {},
|
||||||
|
statusData: {},
|
||||||
|
statusDataTable: {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'date',
|
||||||
|
align: 'left',
|
||||||
|
label: this.$t('date'),
|
||||||
|
field: 'date'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'message',
|
||||||
|
align: 'left',
|
||||||
|
label: this.$t('memo'),
|
||||||
|
field: 'message'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
formData: {},
|
||||||
|
formAddAdmin: '',
|
||||||
|
formAddUser: '',
|
||||||
|
formAddExtensionsManifest: '',
|
||||||
|
formAllowedIPs: '',
|
||||||
|
formBlockedIPs: '',
|
||||||
|
isSuperUser: false,
|
||||||
|
wallet: {},
|
||||||
|
cancel: {},
|
||||||
|
topUpDialog: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
tab: 'funding',
|
||||||
|
needsRestart: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getSettings()
|
||||||
|
this.getAudit()
|
||||||
|
this.balance = +'{{ balance|safe }}'
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
lnbitsVersion() {
|
||||||
|
return LNBITS_VERSION
|
||||||
|
},
|
||||||
|
checkChanges() {
|
||||||
|
return !_.isEqual(this.settings, this.formData)
|
||||||
|
},
|
||||||
|
updateAvailable() {
|
||||||
|
return LNBITS_VERSION !== this.statusData.version
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addAdminUser() {
|
||||||
|
let addUser = this.formAddAdmin
|
||||||
|
let admin_users = this.formData.lnbits_admin_users
|
||||||
|
if (addUser && addUser.length && !admin_users.includes(addUser)) {
|
||||||
|
//admin_users = [...admin_users, addUser]
|
||||||
|
this.formData.lnbits_admin_users = [...admin_users, addUser]
|
||||||
|
this.formAddAdmin = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeAdminUser(user) {
|
||||||
|
let admin_users = this.formData.lnbits_admin_users
|
||||||
|
this.formData.lnbits_admin_users = admin_users.filter(u => u !== user)
|
||||||
|
},
|
||||||
|
addAllowedUser() {
|
||||||
|
let addUser = this.formAddUser
|
||||||
|
let allowed_users = this.formData.lnbits_allowed_users
|
||||||
|
if (addUser && addUser.length && !allowed_users.includes(addUser)) {
|
||||||
|
this.formData.lnbits_allowed_users = [...allowed_users, addUser]
|
||||||
|
this.formAddUser = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeAllowedUser(user) {
|
||||||
|
let allowed_users = this.formData.lnbits_allowed_users
|
||||||
|
this.formData.lnbits_allowed_users = allowed_users.filter(u => u !== user)
|
||||||
|
},
|
||||||
|
addExtensionsManifest() {
|
||||||
|
const addManifest = this.formAddExtensionsManifest.trim()
|
||||||
|
const manifests = this.formData.lnbits_extensions_manifests
|
||||||
|
if (
|
||||||
|
addManifest &&
|
||||||
|
addManifest.length &&
|
||||||
|
!manifests.includes(addManifest)
|
||||||
|
) {
|
||||||
|
this.formData.lnbits_extensions_manifests = [...manifests, addManifest]
|
||||||
|
this.formAddExtensionsManifest = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeExtensionsManifest(manifest) {
|
||||||
|
const manifests = this.formData.lnbits_extensions_manifests
|
||||||
|
this.formData.lnbits_extensions_manifests = manifests.filter(
|
||||||
|
m => m !== manifest
|
||||||
|
)
|
||||||
|
},
|
||||||
|
async toggleServerLog() {
|
||||||
|
this.serverlogEnabled = !this.serverlogEnabled
|
||||||
|
if (this.serverlogEnabled) {
|
||||||
|
const wsProto = location.protocol !== 'http:' ? 'wss://' : 'ws://'
|
||||||
|
const digestHex = await LNbits.utils.digestMessage(this.g.user.id)
|
||||||
|
const localUrl =
|
||||||
|
wsProto +
|
||||||
|
document.domain +
|
||||||
|
':' +
|
||||||
|
location.port +
|
||||||
|
'/api/v1/ws/' +
|
||||||
|
digestHex
|
||||||
|
this.ws = new WebSocket(localUrl)
|
||||||
|
this.ws.addEventListener('message', async ({data}) => {
|
||||||
|
this.logs.push(data.toString())
|
||||||
|
const scrollArea = this.$refs.logScroll
|
||||||
|
if (scrollArea) {
|
||||||
|
const scrollTarget = scrollArea.getScrollTarget()
|
||||||
|
const duration = 0
|
||||||
|
scrollArea.setScrollPosition(scrollTarget.scrollHeight, duration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.ws.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addAllowedIPs() {
|
||||||
|
const allowedIPs = this.formAllowedIPs.trim()
|
||||||
|
const allowed_ips = this.formData.lnbits_allowed_ips
|
||||||
|
if (
|
||||||
|
allowedIPs &&
|
||||||
|
allowedIPs.length &&
|
||||||
|
!allowed_ips.includes(allowedIPs)
|
||||||
|
) {
|
||||||
|
this.formData.lnbits_allowed_ips = [...allowed_ips, allowedIPs]
|
||||||
|
this.formAllowedIPs = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeAllowedIPs(allowed_ip) {
|
||||||
|
const allowed_ips = this.formData.lnbits_allowed_ips
|
||||||
|
this.formData.lnbits_allowed_ips = allowed_ips.filter(
|
||||||
|
a => a !== allowed_ip
|
||||||
|
)
|
||||||
|
},
|
||||||
|
addBlockedIPs() {
|
||||||
|
const blockedIPs = this.formBlockedIPs.trim()
|
||||||
|
const blocked_ips = this.formData.lnbits_blocked_ips
|
||||||
|
if (
|
||||||
|
blockedIPs &&
|
||||||
|
blockedIPs.length &&
|
||||||
|
!blocked_ips.includes(blockedIPs)
|
||||||
|
) {
|
||||||
|
this.formData.lnbits_blocked_ips = [...blocked_ips, blockedIPs]
|
||||||
|
this.formBlockedIPs = ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeBlockedIPs(blocked_ip) {
|
||||||
|
const blocked_ips = this.formData.lnbits_blocked_ips
|
||||||
|
this.formData.lnbits_blocked_ips = blocked_ips.filter(
|
||||||
|
b => b !== blocked_ip
|
||||||
|
)
|
||||||
|
},
|
||||||
|
restartServer() {
|
||||||
|
LNbits.api
|
||||||
|
.request('GET', '/admin/api/v1/restart/?usr=' + this.g.user.id)
|
||||||
|
.then(response => {
|
||||||
|
this.$q.notify({
|
||||||
|
type: 'positive',
|
||||||
|
message: 'Success! Restarted Server',
|
||||||
|
icon: null
|
||||||
|
})
|
||||||
|
this.needsRestart = false
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
topupWallet() {
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'PUT',
|
||||||
|
'/admin/api/v1/topup/?usr=' + this.g.user.id,
|
||||||
|
this.g.user.wallets[0].adminkey,
|
||||||
|
this.wallet
|
||||||
|
)
|
||||||
|
.then(response => {
|
||||||
|
this.$q.notify({
|
||||||
|
type: 'positive',
|
||||||
|
message:
|
||||||
|
'Success! Added ' + this.wallet.amount + ' to ' + this.wallet.id,
|
||||||
|
icon: null
|
||||||
|
})
|
||||||
|
this.wallet = {}
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
formatDate(date) {
|
||||||
|
return moment(date * 1000).fromNow()
|
||||||
|
},
|
||||||
|
getNotifications() {
|
||||||
|
if (this.settings.lnbits_notifications) {
|
||||||
|
axios
|
||||||
|
.get(this.settings.lnbits_status_manifest)
|
||||||
|
.then(response => {
|
||||||
|
this.statusData = response.data
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.formData.lnbits_notifications = false
|
||||||
|
error.response.data = {}
|
||||||
|
error.response.data.message = 'Could not fetch status manifest.'
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getAudit() {
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'GET',
|
||||||
|
'/admin/api/v1/audit/?usr=' + this.g.user.id,
|
||||||
|
this.g.user.wallets[0].adminkey
|
||||||
|
)
|
||||||
|
.then(response => {
|
||||||
|
this.auditData = response.data
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getSettings() {
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'GET',
|
||||||
|
'/admin/api/v1/settings/?usr=' + this.g.user.id,
|
||||||
|
this.g.user.wallets[0].adminkey
|
||||||
|
)
|
||||||
|
.then(response => {
|
||||||
|
this.isSuperUser = response.data.is_super_user || false
|
||||||
|
this.settings = response.data
|
||||||
|
this.formData = {...this.settings}
|
||||||
|
this.getNotifications()
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updateSettings() {
|
||||||
|
let data = _.omit(this.formData, [
|
||||||
|
'is_super_user',
|
||||||
|
'lnbits_allowed_funding_sources'
|
||||||
|
])
|
||||||
|
LNbits.api
|
||||||
|
.request(
|
||||||
|
'PUT',
|
||||||
|
'/admin/api/v1/settings/?usr=' + this.g.user.id,
|
||||||
|
this.g.user.wallets[0].adminkey,
|
||||||
|
data
|
||||||
|
)
|
||||||
|
.then(response => {
|
||||||
|
this.needsRestart =
|
||||||
|
this.settings.lnbits_backend_wallet_class !==
|
||||||
|
this.formData.lnbits_backend_wallet_class ||
|
||||||
|
this.settings.lnbits_killswitch !== this.formData.lnbits_killswitch
|
||||||
|
this.settings = this.formData
|
||||||
|
this.formData = _.clone(this.settings)
|
||||||
|
this.$q.notify({
|
||||||
|
type: 'positive',
|
||||||
|
message: `Success! Settings changed! ${
|
||||||
|
this.needsRestart ? 'Restart required!' : ''
|
||||||
|
}`,
|
||||||
|
icon: null
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteSettings() {
|
||||||
|
LNbits.utils
|
||||||
|
.confirmDialog('Are you sure you want to restore settings to default?')
|
||||||
|
.onOk(() => {
|
||||||
|
LNbits.api
|
||||||
|
.request('DELETE', '/admin/api/v1/settings/?usr=' + this.g.user.id)
|
||||||
|
.then(response => {
|
||||||
|
this.$q.notify({
|
||||||
|
type: 'positive',
|
||||||
|
message:
|
||||||
|
'Success! Restored settings to defaults, restart required!',
|
||||||
|
icon: null
|
||||||
|
})
|
||||||
|
this.needsRestart = true
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
downloadBackup() {
|
||||||
|
window.open('/admin/api/v1/backup/?usr=' + this.g.user.id, '_blank')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
165
lnbits/static/js/components/lnbits-funding-sources.js
Normal file
165
lnbits/static/js/components/lnbits-funding-sources.js
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
Vue.component('lnbits-funding-sources', {
|
||||||
|
mixins: [windowMixin],
|
||||||
|
props: ['form-data', 'allowed-funding-sources'],
|
||||||
|
computed: {
|
||||||
|
fundingSources() {
|
||||||
|
let tmp = []
|
||||||
|
for (const [key, _, obj] of this.rawFundingSources) {
|
||||||
|
const tmpObj = {}
|
||||||
|
if (obj !== null) {
|
||||||
|
for (let [k, v] of Object.entries(obj)) {
|
||||||
|
tmpObj[k] = {label: v, value: null}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp.push([key, tmpObj])
|
||||||
|
}
|
||||||
|
return new Map(tmp)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
rawFundingSources: [
|
||||||
|
['VoidWallet', 'Void Wallet', null],
|
||||||
|
[
|
||||||
|
'FakeWallet',
|
||||||
|
'Fake Wallet',
|
||||||
|
{
|
||||||
|
fake_wallet_secret: 'Secret'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'CoreLightningWallet',
|
||||||
|
'Core Lightning',
|
||||||
|
{
|
||||||
|
corelightning_rpc: 'Endpoint'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'CoreLightningRestWallet',
|
||||||
|
'Core Lightning Rest',
|
||||||
|
{
|
||||||
|
corelightning_rest_url: 'Endpoint',
|
||||||
|
corelightning_rest_cert: 'Certificate',
|
||||||
|
corelightning_rest_macaroon: 'Macaroon'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'LndRestWallet',
|
||||||
|
'Lightning Network Daemon (LND Rest)',
|
||||||
|
{
|
||||||
|
lnd_rest_endpoint: 'Endpoint',
|
||||||
|
lnd_rest_cert: 'Certificate',
|
||||||
|
lnd_rest_macaroon: 'Macaroon',
|
||||||
|
lnd_rest_macaroon_encrypted: 'Encrypted Macaroon'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'LndWallet',
|
||||||
|
'Lightning Network Daemon (LND)',
|
||||||
|
{
|
||||||
|
lnd_grpc_endpoint: 'Endpoint',
|
||||||
|
lnd_grpc_cert: 'Certificate',
|
||||||
|
lnd_grpc_port: 'Port',
|
||||||
|
lnd_grpc_admin_macaroon: 'Admin Macaroon',
|
||||||
|
lnd_grpc_macaroon_encrypted: 'Encrypted Macaroon'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'LnTipsWallet',
|
||||||
|
'LN.Tips',
|
||||||
|
{
|
||||||
|
lntips_api_endpoint: 'Endpoint',
|
||||||
|
lntips_api_key: 'API Key'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'LNPayWallet',
|
||||||
|
'LN Pay',
|
||||||
|
{
|
||||||
|
lnpay_api_endpoint: 'Endpoint',
|
||||||
|
lnpay_api_key: 'API Key',
|
||||||
|
lnpay_wallet_key: 'Wallet Key'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'EclairWallet',
|
||||||
|
'Eclair (ACINQ)',
|
||||||
|
{
|
||||||
|
eclair_url: 'URL',
|
||||||
|
eclair_pass: 'Password'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'LNbitsWallet',
|
||||||
|
'LNBits',
|
||||||
|
{
|
||||||
|
lnbits_endpoint: 'Endpoint',
|
||||||
|
lnbits_key: 'Admin Key'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'OpenNodeWallet',
|
||||||
|
'OpenNode',
|
||||||
|
{
|
||||||
|
opennode_api_endpoint: 'Endpoint',
|
||||||
|
opennode_key: 'Key'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ClicheWallet',
|
||||||
|
'Cliche (NBD)',
|
||||||
|
{
|
||||||
|
cliche_endpoint: 'Endpoint'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'SparkWallet',
|
||||||
|
'Spark',
|
||||||
|
{
|
||||||
|
spark_url: 'Endpoint',
|
||||||
|
spark_token: 'Token'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<div class="funding-sources">
|
||||||
|
<h6 class="q-mt-xl q-mb-md">Funding Sources</h6>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<p>Active Funding<small> (Requires server restart)</small></p>
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
v-model="formData.lnbits_backend_wallet_class"
|
||||||
|
hint="Select the active funding wallet"
|
||||||
|
:options="allowedFundingSources"
|
||||||
|
></q-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-list
|
||||||
|
class="q-mt-md"
|
||||||
|
v-for="(fund, idx) in allowedFundingSources"
|
||||||
|
:key="idx"
|
||||||
|
>
|
||||||
|
<div v-if="fundingSources.get(fund) && fund === formData.lnbits_backend_wallet_class">
|
||||||
|
<div class="row"
|
||||||
|
v-for="([key, prop], i) in Object.entries(fundingSources.get(fund))"
|
||||||
|
:key="i"
|
||||||
|
>
|
||||||
|
<div class="col-12">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
type="text"
|
||||||
|
class="q-mt-sm"
|
||||||
|
v-model="formData[key]"
|
||||||
|
:label="prop.label"
|
||||||
|
:hint="prop.hint"
|
||||||
|
></q-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-list>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
})
|
@@ -31,6 +31,7 @@
|
|||||||
"/static/i18n/br.js",
|
"/static/i18n/br.js",
|
||||||
"/static/js/base.js",
|
"/static/js/base.js",
|
||||||
"/static/js/components.js",
|
"/static/js/components.js",
|
||||||
|
"/static/js/components/lnbits-funding-sources.js",
|
||||||
"/static/js/bolt11-decoder.js"
|
"/static/js/bolt11-decoder.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
|
@@ -80,6 +80,7 @@
|
|||||||
"/static/i18n/br.js",
|
"/static/i18n/br.js",
|
||||||
"/static/js/base.js",
|
"/static/js/base.js",
|
||||||
"/static/js/components.js",
|
"/static/js/components.js",
|
||||||
|
"/static/js/components/lnbits-funding-sources.js",
|
||||||
"/static/js/bolt11-decoder.js"
|
"/static/js/bolt11-decoder.js"
|
||||||
],
|
],
|
||||||
"css": [
|
"css": [
|
||||||
|
Reference in New Issue
Block a user