Merge pull request #507 from lnbits/fakewallet-demo
Makes sats denomination customisable for FakeWallet
This commit is contained in:
commit
18ae455824
|
@ -75,4 +75,5 @@ OPENNODE_API_ENDPOINT=https://api.opennode.com/
|
|||
OPENNODE_KEY=OPENNODE_ADMIN_KEY
|
||||
|
||||
# FakeWallet
|
||||
FAKE_WALLET_KEY=E9873D79C6D87DC0FB6A5778633389F4453213303DA61F20BD67FC233AA33262
|
||||
FAKE_WALLET_SECRET="ToTheMoon1"
|
||||
LNBITS_DENOMINATION=sats
|
|
@ -161,14 +161,14 @@ new Vue({
|
|||
{
|
||||
name: 'sat',
|
||||
align: 'right',
|
||||
label: 'Amount (sat)',
|
||||
label: 'Amount (' + LNBITS_DENOMINATION + ')',
|
||||
field: 'sat',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'fee',
|
||||
align: 'right',
|
||||
label: 'Fee (msat)',
|
||||
label: 'Fee (m' + LNBITS_DENOMINATION + ')',
|
||||
field: 'fee'
|
||||
}
|
||||
],
|
||||
|
@ -191,7 +191,11 @@ new Vue({
|
|||
},
|
||||
computed: {
|
||||
formattedBalance: function () {
|
||||
return LNbits.utils.formatSat(this.balance || this.g.wallet.sat)
|
||||
if (LNBITS_DENOMINATION != 'sats') {
|
||||
return this.balance / 100
|
||||
} else {
|
||||
return LNbits.utils.formatSat(this.balance || this.g.wallet.sat)
|
||||
}
|
||||
},
|
||||
filteredPayments: function () {
|
||||
var q = this.paymentsTable.filter
|
||||
|
@ -250,28 +254,27 @@ new Vue({
|
|||
this.parse.data.paymentChecker = null
|
||||
this.parse.camera.show = false
|
||||
},
|
||||
updateBalance: function(credit){
|
||||
updateBalance: function (credit) {
|
||||
if (LNBITS_DENOMINATION != 'sats') {
|
||||
credit = credit * 100
|
||||
}
|
||||
LNbits.api
|
||||
.request(
|
||||
'PUT',
|
||||
'/api/v1/wallet/balance/' + credit,
|
||||
this.g.wallet.inkey
|
||||
)
|
||||
.catch(err => {
|
||||
LNbits.utils.notifyApiError(err)
|
||||
})
|
||||
.then(response => {
|
||||
let data = response.data
|
||||
if (data.status === 'ERROR') {
|
||||
this.$q.notify({
|
||||
timeout: 5000,
|
||||
type: 'warning',
|
||||
message: `Failed to update.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
this.balance = this.balance + data.balance
|
||||
})
|
||||
.request('PUT', '/api/v1/wallet/balance/' + credit, this.g.wallet.inkey)
|
||||
.catch(err => {
|
||||
LNbits.utils.notifyApiError(err)
|
||||
})
|
||||
.then(response => {
|
||||
let data = response.data
|
||||
if (data.status === 'ERROR') {
|
||||
this.$q.notify({
|
||||
timeout: 5000,
|
||||
type: 'warning',
|
||||
message: `Failed to update.`
|
||||
})
|
||||
return
|
||||
}
|
||||
this.balance = this.balance + data.balance
|
||||
})
|
||||
},
|
||||
closeReceiveDialog: function () {
|
||||
setTimeout(() => {
|
||||
|
@ -295,7 +298,9 @@ new Vue({
|
|||
},
|
||||
createInvoice: function () {
|
||||
this.receive.status = 'loading'
|
||||
|
||||
if (LNBITS_DENOMINATION != 'sats') {
|
||||
this.receive.data.amount = this.receive.data.amount * 100
|
||||
}
|
||||
LNbits.api
|
||||
.createInvoice(
|
||||
this.g.wallet,
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
<q-card>
|
||||
<q-card-section>
|
||||
<h3 class="q-my-none">
|
||||
<strong>{% raw %}{{ formattedBalance }}{% endraw %} </strong>
|
||||
sat
|
||||
<strong>{% raw %}{{ formattedBalance }} {% endraw %}</strong>
|
||||
{{LNBITS_DENOMINATION}}
|
||||
<q-btn
|
||||
v-if="'{{user.admin}}' == 'True'"
|
||||
flat
|
||||
|
@ -35,7 +35,9 @@
|
|||
v-model="scope.value"
|
||||
dense
|
||||
autofocus
|
||||
type="number"
|
||||
mask="#.##"
|
||||
fill-mask="0"
|
||||
reverse-fill-mask
|
||||
@keyup.enter="updateBalance(scope.value)"
|
||||
>
|
||||
<template v-slot:append>
|
||||
|
@ -169,7 +171,17 @@
|
|||
<q-tooltip>{{ props.row.date }}</q-tooltip>
|
||||
{{ props.row.dateFrom }}
|
||||
</q-td>
|
||||
<q-td auto-width key="sat" :props="props">
|
||||
{% endraw %}
|
||||
<q-td
|
||||
auto-width
|
||||
key="sat"
|
||||
v-if="'{{LNBITS_DENOMINATION}}' != 'sats'"
|
||||
:props="props"
|
||||
>{% raw %} {{ parseFloat(String(props.row.fsat).replaceAll(",",
|
||||
"")) / 100 }}
|
||||
</q-td>
|
||||
|
||||
<q-td auto-width key="sat" v-else :props="props">
|
||||
{{ props.row.fsat }}
|
||||
</q-td>
|
||||
<q-td auto-width key="fee" :props="props">
|
||||
|
@ -251,7 +263,7 @@
|
|||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-mt-none q-mb-sm">
|
||||
{{ SITE_TITLE }} wallet: <strong><em>{{ wallet.name }}</em></strong>
|
||||
{{ SITE_TITLE }} Wallet: <strong><em>{{ wallet.name }}</em></strong>
|
||||
</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
|
@ -365,7 +377,20 @@
|
|||
<p v-if="receive.lnurl" class="text-h6 text-center q-my-none">
|
||||
<b>{{receive.lnurl.domain}}</b> is requesting an invoice:
|
||||
</p>
|
||||
|
||||
{% endraw %} {% if LNBITS_DENOMINATION != 'sats' %}
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="receive.data.amount"
|
||||
label="Amount ({{LNBITS_DENOMINATION}}) *"
|
||||
mask="#.##"
|
||||
fill-mask="0"
|
||||
reverse-fill-mask
|
||||
:min="receive.minMax[0]"
|
||||
:max="receive.minMax[1]"
|
||||
:readonly="receive.lnurl && receive.lnurl.fixed"
|
||||
></q-input>
|
||||
{% else %}
|
||||
<q-select
|
||||
filled
|
||||
dense
|
||||
|
@ -379,22 +404,24 @@
|
|||
dense
|
||||
v-model.number="receive.data.amount"
|
||||
type="number"
|
||||
:label="`Amount (${receive.unit}) *`"
|
||||
label="Amount ({{LNBITS_DENOMINATION}}) *"
|
||||
:step="receive.unit != 'sat' ? '0.001' : '1'"
|
||||
:min="receive.minMax[0]"
|
||||
:max="receive.minMax[1]"
|
||||
:readonly="receive.lnurl && receive.lnurl.fixed"
|
||||
></q-input>
|
||||
{% endif %}
|
||||
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.trim="receive.data.memo"
|
||||
label="Memo *"
|
||||
placeholder="LNbits invoice"
|
||||
label="Memo"
|
||||
></q-input>
|
||||
{% raw %}
|
||||
<div v-if="receive.status == 'pending'" class="row q-mt-lg">
|
||||
<q-btn
|
||||
unelevated
|
||||
unelevatedamountamount
|
||||
color="primary"
|
||||
:disable="receive.data.memo == null || receive.data.amount == null || receive.data.amount <= 0"
|
||||
type="submit"
|
||||
|
@ -438,8 +465,13 @@
|
|||
<q-dialog v-model="parse.show" @hide="closeParseDialog">
|
||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||
<div v-if="parse.invoice">
|
||||
{% raw %}
|
||||
<h6 class="q-my-none">{{ parse.invoice.fsat }} sat</h6>
|
||||
<h6 v-if="'{{LNBITS_DENOMINATION}}' != 'sats'" class="q-my-none">
|
||||
{% raw %} {{ parseFloat(String(parse.invoice.fsat).replaceAll(",", ""))
|
||||
/ 100 }} {% endraw %} {{LNBITS_DENOMINATION}} {% raw %}
|
||||
</h6>
|
||||
<h6 v-else class="q-my-none">
|
||||
{{ parse.invoice.fsat }}{% endraw %} {{LNBITS_DENOMINATION}} {% raw %}
|
||||
</h6>
|
||||
<q-separator class="q-my-sm"></q-separator>
|
||||
<p class="text-wrap">
|
||||
<strong>Description:</strong> {{ parse.invoice.description }}<br />
|
||||
|
@ -489,7 +521,7 @@
|
|||
<q-form @submit="payLnurl" class="q-gutter-md">
|
||||
<p v-if="parse.lnurlpay.fixed" class="q-my-none text-h6">
|
||||
<b>{{ parse.lnurlpay.domain }}</b> is requesting {{
|
||||
parse.lnurlpay.maxSendable | msatoshiFormat }} sat
|
||||
parse.lnurlpay.maxSendable | msatoshiFormat }} {{LNBITS_DENOMINATION}}
|
||||
<span v-if="parse.lnurlpay.commentAllowed > 0">
|
||||
<br />
|
||||
and a {{parse.lnurlpay.commentAllowed}}-char comment
|
||||
|
@ -499,7 +531,8 @@
|
|||
<b>{{ parse.lnurlpay.targetUser || parse.lnurlpay.domain }}</b> is
|
||||
requesting <br />
|
||||
between <b>{{ parse.lnurlpay.minSendable | msatoshiFormat }}</b> and
|
||||
<b>{{ parse.lnurlpay.maxSendable | msatoshiFormat }}</b> sat
|
||||
<b>{{ parse.lnurlpay.maxSendable | msatoshiFormat }}</b>
|
||||
{% endraw %} {{LNBITS_DENOMINATION}} {% raw %}
|
||||
<span v-if="parse.lnurlpay.commentAllowed > 0">
|
||||
<br />
|
||||
and a {{parse.lnurlpay.commentAllowed}}-char comment
|
||||
|
@ -516,16 +549,18 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{% endraw %}
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.number="parse.data.amount"
|
||||
type="number"
|
||||
label="Amount (sat) *"
|
||||
label="Amount ({{LNBITS_DENOMINATION}}) *"
|
||||
:min="parse.lnurlpay.minSendable / 1000"
|
||||
:max="parse.lnurlpay.maxSendable / 1000"
|
||||
:readonly="parse.lnurlpay.fixed"
|
||||
></q-input>
|
||||
{% raw %}
|
||||
</div>
|
||||
<div class="col-8 q-pl-md" v-if="parse.lnurlpay.commentAllowed > 0">
|
||||
<q-input
|
||||
|
@ -539,7 +574,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn unelevated color="primary" type="submit">Send satoshis</q-btn>
|
||||
<q-btn unelevated color="primary" type="submit"
|
||||
>Send {{LNBITS_DENOMINATION}}</q-btn
|
||||
>
|
||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||
>Cancel</q-btn
|
||||
>
|
||||
|
|
|
@ -156,6 +156,7 @@ def template_renderer(additional_folders: List = []) -> Jinja2Templates:
|
|||
)
|
||||
)
|
||||
t.env.globals["SITE_TITLE"] = settings.LNBITS_SITE_TITLE
|
||||
t.env.globals["LNBITS_DENOMINATION"] = settings.LNBITS_DENOMINATION
|
||||
t.env.globals["SITE_TAGLINE"] = settings.LNBITS_SITE_TAGLINE
|
||||
t.env.globals["SITE_DESCRIPTION"] = settings.LNBITS_SITE_DESCRIPTION
|
||||
t.env.globals["LNBITS_THEME_OPTIONS"] = settings.LNBITS_THEME_OPTIONS
|
||||
|
|
|
@ -34,6 +34,7 @@ LNBITS_DISABLED_EXTENSIONS: List[str] = env.list(
|
|||
)
|
||||
|
||||
LNBITS_SITE_TITLE = env.str("LNBITS_SITE_TITLE", default="LNbits")
|
||||
LNBITS_DENOMINATION = env.str("LNBITS_DENOMINATION", default="sats")
|
||||
LNBITS_SITE_TAGLINE = env.str(
|
||||
"LNBITS_SITE_TAGLINE", default="free and open-source lightning wallet"
|
||||
)
|
||||
|
|
|
@ -22,7 +22,8 @@ Vue.component('lnbits-wallet-list', {
|
|||
activeWallet: null,
|
||||
activeBalance: [],
|
||||
showForm: false,
|
||||
walletName: ''
|
||||
walletName: '',
|
||||
LNBITS_DENOMINATION: LNBITS_DENOMINATION
|
||||
}
|
||||
},
|
||||
template: `
|
||||
|
@ -43,7 +44,8 @@ Vue.component('lnbits-wallet-list', {
|
|||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label lines="1">{{ wallet.name }}</q-item-label>
|
||||
<q-item-label caption>{{ wallet.live_fsat }} sat</q-item-label>
|
||||
<q-item-label v-if="LNBITS_DENOMINATION != 'sats'" caption>{{ parseFloat(String(wallet.live_fsat).replaceAll(",", "")) / 100 }} {{ LNBITS_DENOMINATION }}</q-item-label>
|
||||
<q-item-label v-else caption>{{ wallet.live_fsat }} {{ LNBITS_DENOMINATION }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side v-show="activeWallet && activeWallet.id === wallet.id">
|
||||
<q-icon name="chevron_right" color="grey-5" size="md"></q-icon>
|
||||
|
@ -194,11 +196,11 @@ Vue.component('lnbits-payment-details', {
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3"><b>Amount</b>:</div>
|
||||
<div class="col-9">{{ (payment.amount / 1000).toFixed(3) }} sat</div>
|
||||
<div class="col-9">{{ (payment.amount / 1000).toFixed(3) }} {{LNBITS_DENOMINATION}}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3"><b>Fee</b>:</div>
|
||||
<div class="col-9">{{ (payment.fee / 1000).toFixed(3) }} sat</div>
|
||||
<div class="col-9">{{ (payment.fee / 1000).toFixed(3) }} {{LNBITS_DENOMINATION}}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3"><b>Payment hash</b>:</div>
|
||||
|
|
|
@ -192,6 +192,8 @@
|
|||
<script src="/static/js/components.js"></script>
|
||||
<script type="text/javascript">
|
||||
const themes = {{ LNBITS_THEME_OPTIONS | tojson }}
|
||||
const LNBITS_DENOMINATION = {{ LNBITS_DENOMINATION | tojson}}
|
||||
console.log(LNBITS_DENOMINATION)
|
||||
if(themes && themes.length) {
|
||||
window.allowedThemes = themes.map(str => str.trim())
|
||||
}
|
||||
|
|
|
@ -31,11 +31,12 @@ class FakeWallet(Wallet):
|
|||
memo: Optional[str] = None,
|
||||
description_hash: Optional[bytes] = None,
|
||||
) -> InvoiceResponse:
|
||||
secret = getenv("FAKE_WALLET_SECRET")
|
||||
data: Dict = {
|
||||
"out": False,
|
||||
"amount": amount,
|
||||
"currency": "bc",
|
||||
"privkey": getenv("FAKE_WALLET_KEY"),
|
||||
"privkey": hashlib.pbkdf2_hmac('sha256', secret.encode("utf-8"), ("FakeWallet").encode("utf-8"), 2048, 32).hex(),
|
||||
"memo": None,
|
||||
"description_hash": None,
|
||||
"description": "",
|
||||
|
@ -52,9 +53,9 @@ class FakeWallet(Wallet):
|
|||
data["tags_set"] = ["d"]
|
||||
data["memo"] = memo
|
||||
data["description"] = memo
|
||||
randomHash = hashlib.sha256(
|
||||
randomHash = data["privkey"][:6] + hashlib.sha256(
|
||||
str(random.getrandbits(256)).encode("utf-8")
|
||||
).hexdigest()
|
||||
).hexdigest()[6:]
|
||||
data["paymenthash"] = randomHash
|
||||
payment_request = encode(data)
|
||||
checking_id = randomHash
|
||||
|
@ -62,8 +63,12 @@ class FakeWallet(Wallet):
|
|||
return InvoiceResponse(True, checking_id, payment_request)
|
||||
|
||||
async def pay_invoice(self, bolt11: str) -> PaymentResponse:
|
||||
invoice = decode(bolt11)
|
||||
return PaymentResponse(True, invoice.payment_hash, 0)
|
||||
invoice = decode(bolt11)
|
||||
if hasattr(invoice, 'checking_id') and invoice.checking_id[6:] == data["privkey"][:6]:
|
||||
return PaymentResponse(True, invoice.payment_hash, 0)
|
||||
else:
|
||||
return PaymentResponse(ok = False, error_message="Only internal invoices can be used!")
|
||||
|
||||
|
||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
return PaymentStatus(False)
|
||||
|
|
Loading…
Reference in New Issue
Block a user