Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LNURL is a range of lightning-network standards that allow us to use lightning-n

1. Create an LNURLp (New Pay link)\
![create lnurlp](https://i.imgur.com/rhUBJFy.jpg)

- select your wallets
- make a small description
- enter amount
Expand All @@ -25,7 +24,6 @@ LNURL is a range of lightning-network standards that allow us to use lightning-n

2. Use the shareable link or view the LNURLp you just created\
![LNURLp](https://i.imgur.com/C8s1P0Q.jpg)

- you can now open your LNURLp and copy the LNURL, get the shareable link or print it\
![view lnurlp](https://i.imgur.com/4n41S7T.jpg)

Expand Down
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Pay Links",
"version": "1.2.0",
"version": "1.3.0",
"short_description": "Make reusable LNURL pay links",
"tile": "/lnurlp/static/image/lnurl-pay.png",
"min_lnbits_version": "1.4.0",
Expand Down
36 changes: 12 additions & 24 deletions migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ async def m001_initial(db):
"""
Initial pay table.
"""
await db.execute(
f"""
await db.execute(f"""
CREATE TABLE lnurlp.pay_links (
id {db.serial_primary_key},
wallet TEXT NOT NULL,
Expand All @@ -17,8 +16,7 @@ async def m001_initial(db):
served_meta INTEGER NOT NULL,
served_pr INTEGER NOT NULL
);
"""
)
""")


async def m002_webhooks_and_success_actions(db):
Expand All @@ -28,16 +26,14 @@ async def m002_webhooks_and_success_actions(db):
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_url TEXT;")
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN success_text TEXT;")
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN success_url TEXT;")
await db.execute(
f"""
await db.execute(f"""
CREATE TABLE lnurlp.invoices (
pay_link INTEGER NOT NULL REFERENCES {db.references_schema}pay_links (id),
payment_hash TEXT NOT NULL,
webhook_sent INT, -- null means not sent, otherwise store status
expiry INT
);
"""
)
""")


async def m003_min_max_comment_fiat(db):
Expand Down Expand Up @@ -86,8 +82,7 @@ async def m006_redux(db):
else:
# but we have to do this for sqlite
await db.execute("ALTER TABLE lnurlp.pay_links RENAME TO pay_links_old")
await db.execute(
f"""
await db.execute(f"""
CREATE TABLE lnurlp.pay_links (
id TEXT PRIMARY KEY,
wallet TEXT NOT NULL,
Expand All @@ -105,8 +100,7 @@ async def m006_redux(db):
webhook_headers TEXT,
webhook_body TEXT
);
"""
)
""")

for row in [
list(row) for row in await db.fetchall("SELECT * FROM lnurlp.pay_links_old")
Expand Down Expand Up @@ -172,13 +166,11 @@ async def m009_add_settings(db):
"""
Add extension settings table
"""
await db.execute(
"""
await db.execute("""
CREATE TABLE lnurlp.settings (
nostr_private_key TEXT NOT NULL
);
"""
)
""")


async def m010_add_pay_link_domain(db):
Expand All @@ -193,14 +185,10 @@ async def m011_add_created_at(db: Connection):
Add created_at to pay links
"""

await db.execute(
f"""ALTER TABLE lnurlp.pay_links ADD COLUMN
created_at TIMESTAMP DEFAULT {db.timestamp_column_default}"""
)
await db.execute(
f"""ALTER TABLE lnurlp.pay_links ADD COLUMN
updated_at TIMESTAMP DEFAULT {db.timestamp_column_default}"""
)
await db.execute(f"""ALTER TABLE lnurlp.pay_links ADD COLUMN
created_at TIMESTAMP DEFAULT {db.timestamp_column_default}""")
await db.execute(f"""ALTER TABLE lnurlp.pay_links ADD COLUMN
updated_at TIMESTAMP DEFAULT {db.timestamp_column_default}""")

now = int(time())
await db.execute(
Expand Down
19 changes: 11 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"prettier": "^3.2.5",
"pyright": "^1.1.358"
"prettier": "^3.7.4",
"pyright": "^1.1.407"
}
}
14 changes: 3 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ dependencies = ["lnbits>1"]
[tool.poetry]
package-mode = false

[tool.uv]
dev-dependencies = [
[dependency-groups]
dev = [
"black>=24.3.0",
"pytest-asyncio>=0.21.0",
"pytest>=7.3.2",
"mypy>=1.5.1",
"mypy==1.17.1",
"pre-commit>=3.2.2",
"ruff>=0.3.2",
"types-cffi>=1.16.0.20240331",
Expand All @@ -34,14 +34,6 @@ warn_untyped_fields = true
[[tool.mypy.overrides]]
module = [
"lnbits.*",
"lnurl.*",
"loguru.*",
"fastapi.*",
"pydantic.*",
"pyqrcode.*",
"shortuuid.*",
"httpx.*",
"websocket.*",
"pynostr.*",
]
ignore_missing_imports = "True"
Expand Down
11 changes: 11 additions & 0 deletions static/display.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
window.PageLnurlpPublic = {
template: '#page-lnurlp-public',
data() {
return {
url: ''
}
},
created() {
this.url = window.location.origin + '/lnurlp/' + this.$route.params.id
}
}
67 changes: 67 additions & 0 deletions static/display.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template id="page-lnurlp-public">
<div class="row q-col-gutter-md justify-center">
<div class="col-12 col-sm-6 col-md-5 col-lg-4">
<q-card class="q-pa-lg">
<q-card-section class="q-pa-none">
<div class="text-center">
<lnbits-qrcode-lnurl :url="url" :nfc="true"></lnbits-qrcode-lnurl>
</div>
</q-card-section>
</q-card>
</div>
<div class="col-12 col-sm-6 col-md-5 col-lg-4 q-gutter-y-md">
<q-card>
<q-card-section>
<h6 class="text-subtitle1 q-mb-sm q-mt-none">
LNbits LNURL-pay link
</h6>
<p class="q-my-none">
Use an LNURL compatible bitcoin wallet to pay.
</p>
</q-card-section>
<q-card-section class="q-pa-none">
<q-separator></q-separator>
<q-list>
<q-expansion-item
group="extras"
icon="info"
label="Powered by LNURL"
>
<q-card>
<q-card-section>
<p>
LNURL is a range of lightning-network standards that allow
us to use lightning-network differently. An LNURL-pay is a
link that wallets use to fetch an invoice from a server
on-demand. The link or QR code is fixed, but each time it is
read by a compatible wallet a new QR code is issued by the
service. It can be used to activate machines without them
having to maintain an electronic screen to generate and show
invoices locally, or to sell any predefined good or service
automatically.
</p>
<p>
Exploring LNURL and finding use cases, is really helping
inform lightning protocol development, rather than the
protocol dictating how lightning-network should be engaged
with.
</p>
<small
>Check
<a
class="text-secondary"
href="https://github.com/fiatjaf/awesome-lnurl"
target="_blank"
>Awesome LNURL</a
>
for further information.</small
>
</q-card-section>
</q-card>
</q-expansion-item>
</q-list>
</q-card-section>
</q-card>
</div>
</div>
</template>
66 changes: 27 additions & 39 deletions static/js/index.js → static/index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
/* globals Quasar, Vue, _, VueQrcode, windowMixin, LNbits, LOCALE */

const locationPath = [
window.location.protocol,
'//',
window.location.host,
window.location.pathname
].join('')

const mapPayLink = obj => {
obj._data = _.clone(obj)
obj.created_at = LNbits.utils.formatDateString(obj.created_at)
obj.updated_at = LNbits.utils.formatDateString(obj.updated_at)
if (obj.currency) {
obj.min = obj.min / obj.fiat_base_multiplier
obj.max = obj.max / obj.fiat_base_multiplier
}

obj.print_url = [locationPath, 'print/', obj.id].join('')
obj.pay_url = [locationPath, 'link/', obj.id].join('')
return obj
}

window.app = Vue.createApp({
el: '#vue',
mixins: [window.windowMixin],
window.PageLnurlp = {
template: '#page-lnurlp',
computed: {
endpoint: function () {
baseUrl() {
return window.location.origin + '/lnurlp/api/v1/links'
},
endpoint() {
return `/lnurlp/api/v1/settings?usr=${this.g.user.id}`
}
},
Expand All @@ -40,7 +19,6 @@ window.app = Vue.createApp({
}
],
domain: window.location.host,
currencies: [],
fiatRates: {},
payLinks: [],
payLinksTable: {
Expand Down Expand Up @@ -106,6 +84,24 @@ window.app = Vue.createApp({
}
},
methods: {
mapPayLink(obj) {
const locationPath = [
window.location.protocol,
'//',
window.location.host,
window.location.pathname
].join('')
obj._data = _.clone(obj)
obj.created_at = LNbits.utils.formatDate(obj.created_at)
obj.updated_at = LNbits.utils.formatDate(obj.updated_at)
if (obj.currency) {
obj.min = obj.min / obj.fiat_base_multiplier
obj.max = obj.max / obj.fiat_base_multiplier
}
obj.print_url = [locationPath, 'print/', obj.id].join('')
obj.pay_url = [locationPath, 'link/', obj.id].join('')
return obj
},
getPayLinks() {
LNbits.api
.request(
Expand All @@ -114,7 +110,7 @@ window.app = Vue.createApp({
this.g.user.wallets[0].inkey
)
.then(response => {
this.payLinks = response.data.map(mapPayLink)
this.payLinks = response.data.map(this.mapPayLink)
})
.catch(LNbits.utils.notifyApiError)
},
Expand Down Expand Up @@ -191,7 +187,7 @@ window.app = Vue.createApp({
)
.then(response => {
this.payLinks = _.reject(this.payLinks, obj => obj.id === data.id)
this.payLinks.push(mapPayLink(response.data))
this.payLinks.push(this.mapPayLink(response.data))
this.formDialog.show = false
this.resetFormData()
})
Expand Down Expand Up @@ -246,13 +242,5 @@ window.app = Vue.createApp({
if (this.g.user.wallets?.length) {
this.getPayLinks()
}
LNbits.api
.request('GET', '/api/v1/currencies')
.then(response => {
this.currencies = ['satoshis', ...response.data]
})
.catch(err => {
LNbits.utils.notifyApiError(err)
})
}
})
}
Loading