Merge branch 'main' into smtp
This commit is contained in:
commit
878be3d019
11
lnbits/extensions/deezy/README.md
Normal file
11
lnbits/extensions/deezy/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Deezy: Home for Lightning Liquidity
|
||||
Swap lightning bitcoin for on-chain bitcoin to get inbound liquidity. Or get an on-chain deposit address for your lightning address.
|
||||
* [Website](https://deezy.io)
|
||||
* [Lightning Node](https://amboss.space/node/024bfaf0cabe7f874fd33ebf7c6f4e5385971fc504ef3f492432e9e3ec77e1b5cf)
|
||||
* [Documentation](https://docs.deezy.io)
|
||||
* [Discord](https://discord.gg/nEBbrUAvPy)
|
||||
|
||||
# Usage
|
||||
This extension lets you swap lightning btc for on-chain btc and vice versa.
|
||||
* Swap Lightning -> BTC to get inbound liquidity
|
||||
* Swap BTC -> Lightning to generate an on-chain deposit address for your lightning address
|
25
lnbits/extensions/deezy/__init__.py
Normal file
25
lnbits/extensions/deezy/__init__.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
from fastapi import APIRouter
|
||||
from starlette.staticfiles import StaticFiles
|
||||
|
||||
from lnbits.db import Database
|
||||
from lnbits.helpers import template_renderer
|
||||
|
||||
db = Database("ext_deezy")
|
||||
|
||||
deezy_ext: APIRouter = APIRouter(prefix="/deezy", tags=["deezy"])
|
||||
|
||||
deezy_static_files = [
|
||||
{
|
||||
"path": "/deezy/static",
|
||||
"app": StaticFiles(directory="lnbits/extensions/deezy/static"),
|
||||
"name": "deezy_static",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def deezy_renderer():
|
||||
return template_renderer(["lnbits/extensions/deezy/templates"])
|
||||
|
||||
|
||||
from .views import * # noqa
|
||||
from .views_api import * # noqa
|
6
lnbits/extensions/deezy/config.json
Normal file
6
lnbits/extensions/deezy/config.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "Deezy",
|
||||
"short_description": "LN to onchain, onchain to LN swaps",
|
||||
"tile": "/deezy/static/deezy.png",
|
||||
"contributors": ["Uthpala"]
|
||||
}
|
115
lnbits/extensions/deezy/crud.py
Normal file
115
lnbits/extensions/deezy/crud.py
Normal file
|
@ -0,0 +1,115 @@
|
|||
from http import HTTPStatus
|
||||
from typing import List, Optional
|
||||
|
||||
from . import db
|
||||
from .models import BtcToLnSwap, LnToBtcSwap, Token, UpdateLnToBtcSwap
|
||||
|
||||
|
||||
async def get_ln_to_btc() -> List[LnToBtcSwap]:
|
||||
|
||||
rows = await db.fetchall(
|
||||
f"SELECT * FROM deezy.ln_to_btc_swap ORDER BY created_at DESC",
|
||||
)
|
||||
|
||||
return [LnToBtcSwap(**row) for row in rows]
|
||||
|
||||
|
||||
async def get_btc_to_ln() -> List[BtcToLnSwap]:
|
||||
|
||||
rows = await db.fetchall(
|
||||
f"SELECT * FROM deezy.btc_to_ln_swap ORDER BY created_at DESC",
|
||||
)
|
||||
|
||||
return [BtcToLnSwap(**row) for row in rows]
|
||||
|
||||
|
||||
async def get_token() -> Optional[Token]:
|
||||
|
||||
row = await db.fetchone(
|
||||
f"SELECT * FROM deezy.token ORDER BY created_at DESC",
|
||||
)
|
||||
|
||||
return Token(**row) if row else None
|
||||
|
||||
|
||||
async def save_token(
|
||||
data: Token,
|
||||
) -> Token:
|
||||
|
||||
await db.execute(
|
||||
"""
|
||||
INSERT INTO deezy.token (
|
||||
deezy_token
|
||||
)
|
||||
VALUES (?)
|
||||
""",
|
||||
(data.deezy_token,),
|
||||
)
|
||||
return data
|
||||
|
||||
|
||||
async def save_ln_to_btc(
|
||||
data: LnToBtcSwap,
|
||||
) -> LnToBtcSwap:
|
||||
|
||||
return await db.execute(
|
||||
"""
|
||||
INSERT INTO deezy.ln_to_btc_swap (
|
||||
amount_sats,
|
||||
on_chain_address,
|
||||
on_chain_sats_per_vbyte,
|
||||
bolt11_invoice,
|
||||
fee_sats,
|
||||
txid,
|
||||
tx_hex
|
||||
)
|
||||
VALUES (?,?,?,?,?,?,?)
|
||||
""",
|
||||
(
|
||||
data.amount_sats,
|
||||
data.on_chain_address,
|
||||
data.on_chain_sats_per_vbyte,
|
||||
data.bolt11_invoice,
|
||||
data.fee_sats,
|
||||
data.txid,
|
||||
data.tx_hex,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def update_ln_to_btc(data: UpdateLnToBtcSwap) -> str:
|
||||
await db.execute(
|
||||
"""
|
||||
UPDATE deezy.ln_to_btc_swap
|
||||
SET txid = ?, tx_hex = ?
|
||||
WHERE bolt11_invoice = ?
|
||||
""",
|
||||
(data.txid, data.tx_hex, data.bolt11_invoice),
|
||||
)
|
||||
|
||||
return data.txid
|
||||
|
||||
|
||||
async def save_btc_to_ln(
|
||||
data: BtcToLnSwap,
|
||||
) -> BtcToLnSwap:
|
||||
|
||||
return await db.execute(
|
||||
"""
|
||||
INSERT INTO deezy.btc_to_ln_swap (
|
||||
ln_address,
|
||||
on_chain_address,
|
||||
secret_access_key,
|
||||
commitment,
|
||||
signature
|
||||
)
|
||||
VALUES (?,?,?,?,?)
|
||||
""",
|
||||
(
|
||||
data.ln_address,
|
||||
data.on_chain_address,
|
||||
data.secret_access_key,
|
||||
data.commitment,
|
||||
data.signature,
|
||||
),
|
||||
)
|
37
lnbits/extensions/deezy/migrations.py
Normal file
37
lnbits/extensions/deezy/migrations.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
async def m001_initial(db):
|
||||
await db.execute(
|
||||
f"""
|
||||
CREATE TABLE deezy.ln_to_btc_swap (
|
||||
id TEXT PRIMARY KEY,
|
||||
amount_sats {db.big_int} NOT NULL,
|
||||
on_chain_address TEXT NOT NULL,
|
||||
on_chain_sats_per_vbyte INT NOT NULL,
|
||||
bolt11_invoice TEXT NOT NULL,
|
||||
fee_sats {db.big_int} NOT NULL,
|
||||
txid TEXT NULL,
|
||||
tx_hex TEXT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
"""
|
||||
)
|
||||
await db.execute(
|
||||
f"""
|
||||
CREATE TABLE deezy.btc_to_ln_swap (
|
||||
id TEXT PRIMARY KEY,
|
||||
ln_address TEXT NOT NULL,
|
||||
on_chain_address TEXT NOT NULL,
|
||||
secret_access_key TEXT NOT NULL,
|
||||
commitment TEXT NOT NULL,
|
||||
signature TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
"""
|
||||
)
|
||||
await db.execute(
|
||||
f"""
|
||||
CREATE TABLE deezy.token (
|
||||
deezy_token TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
"""
|
||||
)
|
34
lnbits/extensions/deezy/models.py
Normal file
34
lnbits/extensions/deezy/models.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from typing import Optional
|
||||
|
||||
from pydantic.main import BaseModel
|
||||
from sqlalchemy.engine import base # type: ignore
|
||||
|
||||
|
||||
class Token(BaseModel):
|
||||
deezy_token: str
|
||||
|
||||
|
||||
class LnToBtcSwap(BaseModel):
|
||||
amount_sats: int
|
||||
on_chain_address: str
|
||||
on_chain_sats_per_vbyte: int
|
||||
bolt11_invoice: str
|
||||
fee_sats: int
|
||||
txid: str = ""
|
||||
tx_hex: str = ""
|
||||
created_at: str = ""
|
||||
|
||||
|
||||
class UpdateLnToBtcSwap(BaseModel):
|
||||
txid: str
|
||||
tx_hex: str
|
||||
bolt11_invoice: str
|
||||
|
||||
|
||||
class BtcToLnSwap(BaseModel):
|
||||
ln_address: str
|
||||
on_chain_address: str
|
||||
secret_access_key: str
|
||||
commitment: str
|
||||
signature: str
|
||||
created_at: str = ""
|
BIN
lnbits/extensions/deezy/static/deezy.png
Normal file
BIN
lnbits/extensions/deezy/static/deezy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
253
lnbits/extensions/deezy/templates/deezy/_api_docs.html
Normal file
253
lnbits/extensions/deezy/templates/deezy/_api_docs.html
Normal file
|
@ -0,0 +1,253 @@
|
|||
<q-expansion-item
|
||||
group="extras"
|
||||
icon="swap_vertical_circle"
|
||||
label="About Deezy"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<img
|
||||
alt=""
|
||||
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgNTMwLjA5IDEzNi43MyI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7fS5jbHMtMntmaWxsLXJ1bGU6ZXZlbm9kZDtmaWxsOnVybCgjbGluZWFyLWdyYWRpZW50KTt9LmNscy0ze2ZpbGw6I2ZmYzkyYjt9PC9zdHlsZT48bGluZWFyR3JhZGllbnQgaWQ9ImxpbmVhci1ncmFkaWVudCIgeDE9IjUxLjY5IiB5MT0iMzEuNjciIHgyPSIxODAuMjMiIHkyPSIxMDUuMTIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYyMWYiLz48c3RvcCBvZmZzZXQ9IjAuMjkiIHN0b3AtY29sb3I9IiNmZmNkMmQiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmNzkyMzMiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iTGF5ZXJfMS0yIiBkYXRhLW5hbWU9IkxheWVyIDEiPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTYxLjg5LDBoNTcuNTVDMTMzLjksMCwxNDUsMS40NCwxNTIuOTIsNC4zM2MxNC4yMSw1LjA1LDIzLjYsMTQuMTgsMjguNjYsMjcuNjRMMTUyLjY4LDQ2LjRsLS4yMy0uNDhjLTIuMTgtNi43NC01LjA2LTExLjU0LTguNDMtMTQuOUEyNS40MywyNS40MywwLDAsMCwxMzIsMjUuNDlsLS4yNC0yLjg5LTMuMTMsMi4xNmE1NC4xMSw1NC4xMSwwLDAsMC05LjE2LS40OEg5MC43OVY1MUw2MS44OSw3MC42OFptMTI1LDU0LjgxQTEyNC43NiwxMjQuNzYsMCwwLDEsMTg3LjYsNjhhMTA4LjM4LDEwOC4zOCwwLDAsMS01LjMsMzQuNjJjLTMuMzcsMTEuMy05LjM5LDE5LjQ3LTE3LjU4LDI0Ljc2YTQ2LjE4LDQ2LjE4LDAsMCwxLTE3LjA5LDYuNDljLTYsMS4yLTE1LjQxLDEuNjgtMjguMTksMS42OEg2MS44OVY5OS4yOWwyOC45LTE0LjQzdjI2LjY5aDExLjU2bC4yNCwyLjE2LDMuMzctMi4xNmgxMy40OGMxMi43OCwwLDIxLjQ0LTIuODksMjYuMjYtOC40MiwzLjEzLTMuNiw1LjU0LTguNDEsNy4yMi0xNC45YTU0LjI4LDU0LjI4LDAsMCwwLDIuNDEtMTEuM1oiLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iMCAxMjIuMTMgMTI1LjcxIDM1LjU4IDEyOC44NSA2Ni41OSAyMzEuOTIgMTQuNjcgMTA4LjM3IDEwMC45NyAxMDQuNzYgNjkuNzEgMCAxMjIuMTMiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0yNjYuNjksMjguNjhoMTN2ODRoLTEzVjEwNHEtNy4zMiwxMC4yLTIxLDEwLjJhMjguMTQsMjguMTQsMCwwLDEtMjEuMTItOS4xOCwzMS4yMSwzMS4yMSwwLDAsMS04Ljc2LTIyLjM4LDMxLjE1LDMxLjE1LDAsMCwxLDguNzYtMjIuNDQsMjguMjMsMjguMjMsMCwwLDEsMjEuMTItOS4xMnExMy42OCwwLDIxLDEwLjA4Wk0yMzQuMTcsOTYuNDJhMTkuNTcsMTkuNTcsMCwwLDAsMjcuMTIsMCwxOC43NCwxOC43NCwwLDAsMCw1LjQtMTMuNzQsMTguNzQsMTguNzQsMCwwLDAtNS40LTEzLjc0LDE5LjU3LDE5LjU3LDAsMCwwLTI3LjEyLDAsMTguNzQsMTguNzQsMCwwLDAtNS40LDEzLjc0QTE4Ljc0LDE4Ljc0LDAsMCwwLDIzNC4xNyw5Ni40MloiLz48cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Ik0zMDIsODguMmExNi40OCwxNi40OCwwLDAsMCw2LjYsMTAuNSwyMS4yMiwyMS4yMiwwLDAsMCwxMi42LDMuNjZxMTAuMzIsMCwxNS40OC03LjQ0bDEwLjY4LDYuMjRxLTguODgsMTMuMDgtMjYuMjgsMTMuMDgtMTQuNjQsMC0yMy42NC04Ljk0dC05LTIyLjYycTAtMTMuNDQsOC44OC0yMi41dDIyLjgtOS4wNnExMy4yLDAsMjEuNjYsOS4yNGEzMiwzMiwwLDAsMSw4LjQ2LDIyLjQ0LDQwLjA5LDQwLjA5LDAsMCwxLS40OCw1LjRabS0uMTItMTAuNTZoMzUuMjhxLTEuMzItNy4zMi02LjA2LTExQTE3LjQ1LDE3LjQ1LDAsMCwwLDMyMCw2Mi44OGExOC4yMywxOC4yMywwLDAsMC0xMiw0QTE3Ljg2LDE3Ljg2LDAsMCwwLDMwMS44NSw3Ny42NFoiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0zNjguNDUsODguMmExNi40OCwxNi40OCwwLDAsMCw2LjYsMTAuNSwyMS4yMiwyMS4yMiwwLDAsMCwxMi42LDMuNjZxMTAuMzIsMCwxNS40OC03LjQ0bDEwLjY4LDYuMjRxLTguODgsMTMuMDgtMjYuMjgsMTMuMDgtMTQuNjQsMC0yMy42NC04Ljk0dC05LTIyLjYycTAtMTMuNDQsOC44OC0yMi41dDIyLjgtOS4wNnExMy4yLDAsMjEuNjYsOS4yNGEzMiwzMiwwLDAsMSw4LjQ2LDIyLjQ0LDQwLjA5LDQwLjA5LDAsMCwxLS40OCw1LjRabS0uMTItMTAuNTZoMzUuMjhxLTEuMzItNy4zMi02LjA2LTExYTE3LjQ1LDE3LjQ1LDAsMCwwLTExLjEtMy43MiwxOC4yMywxOC4yMywwLDAsMC0xMiw0QTE3Ljg2LDE3Ljg2LDAsMCwwLDM2OC4zMyw3Ny42NFoiLz48cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Ik00MzcuNTgsMTAwLjQ0aDI5LjE2djEyLjI0SDQxOS45M1YxMDRMNDQ4LDY0LjkySDQyMS4xM1Y1Mi42OGg0NC4zOXY4LjYzWiIvPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTUxNi4yOSw1Mi42OGgxMy44bC0yMyw2MS45MnEtOC42NCwyMy4yOC0yOS4yOCwyMi4wOFYxMjQuNTZxNi4xMi4zNiw5Ljg0LTIuNTh0Ni4xMi05LjE4bC42LTEuMkw0NjguODksNTIuNjhoMTQuMTZsMTcuODksNDMuNTVaIi8+PC9nPjwvZz48L3N2Zz4="
|
||||
height="40"
|
||||
class="d-inline-block align-top my-2"
|
||||
/>
|
||||
<h5 class="text-subtitle1 q-my-none">
|
||||
Deezy.io: Do onchain to offchain and vice-versa swaps
|
||||
</h5>
|
||||
<p>
|
||||
Link :
|
||||
<a class="text-light-blue" target="_blank" href="https://deezy.io/">
|
||||
https://deezy.io/
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a class="text-light-blue" target="_blank" href="https://docs.deezy.io/"
|
||||
>API DOCS</a
|
||||
>
|
||||
</p>
|
||||
<p>
|
||||
<small
|
||||
>Created by,
|
||||
<a
|
||||
class="text-light-blue"
|
||||
target="_blank"
|
||||
href="https://twitter.com/Uthpala_419"
|
||||
>Uthpala</a
|
||||
></small
|
||||
>
|
||||
</p>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="extras"
|
||||
icon="swap_vertical_circle"
|
||||
label="API info"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-expansion-item
|
||||
group="swap-ln-to-btc"
|
||||
dense
|
||||
expand-separator
|
||||
label="Swap (LIGHTNING TO BTC)"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-expansion-item group="ln-to-btc" dense expand-separator label="GET Info">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Get the current info about the swap service for converting LN btc to
|
||||
on-chain BTC.
|
||||
</h5>
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">GET (mainnet)</span>
|
||||
https://api.deezy.io/v1/swap/info
|
||||
</code>
|
||||
<br />
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">GET (testnet)</span>
|
||||
https://api-testnet.deezy.io/v1/swap/info
|
||||
</code>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Response</h6>
|
||||
<pre>
|
||||
{
|
||||
"liquidity_fee_ppm": 2000,
|
||||
"on_chain_bytes_estimate": 300,
|
||||
"max_swap_amount_sats": 100000000,
|
||||
"min_swap_amount_sats": 100000,
|
||||
"available": true
|
||||
}
|
||||
</pre>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="ln-to-btc"
|
||||
dense
|
||||
expand-separator
|
||||
label="POST New (LN to BTC) Swap"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Initiate a new swap to send lightning btc in exchange for on-chain
|
||||
btc
|
||||
</h5>
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">POST (mainnet)</span>
|
||||
https://api.deezy.io/v1/swap
|
||||
</code>
|
||||
<br />
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">POST (testnet)</span>
|
||||
https://api-testnet.deezy.io/v1/swap
|
||||
</code>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Payload</h6>
|
||||
<pre>
|
||||
{
|
||||
"amount_sats": 500000,
|
||||
"on_chain_address": "tb1qrcdhlm0m...",
|
||||
"on_chain_sats_per_vbyte": 2
|
||||
}
|
||||
</pre>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Response</h6>
|
||||
<pre>
|
||||
{
|
||||
"bolt11_invoice": "lntb603u1p3vmxj7p...",
|
||||
"fee_sats": 600
|
||||
}
|
||||
</pre>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="ln-to-btc"
|
||||
dense
|
||||
expand-separator
|
||||
label="GET Lookup (LN to BTC) Swap"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Lookup the on-chain transaction information for an existing swap
|
||||
</h5>
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">GET (mainnet)</span>
|
||||
https://api.deezy.io/v1/swap/lookup
|
||||
</code>
|
||||
<br />
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">GET (testnet)</span>
|
||||
https://api-testnet.deezy.io/v1/swap/lookup
|
||||
</code>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Query Parameter</h6>
|
||||
<pre>
|
||||
"bolt11_invoice": "lntb603u1p3vmxj7pp54...",
|
||||
</pre>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Response</h6>
|
||||
<pre>
|
||||
{
|
||||
"on_chain_txid": "string",
|
||||
"tx_hex": "string"
|
||||
}
|
||||
</pre>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="swap-btc-to-ln"
|
||||
dense
|
||||
expand-separator
|
||||
label="Swap (BTC TO LIGHTNING)"
|
||||
:content-inset-level="0.5"
|
||||
>
|
||||
<q-expansion-item
|
||||
group="btc-to-ln"
|
||||
dense
|
||||
expand-separator
|
||||
label="POST New On-Chain Deposit Address"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Generate an on-chain deposit address for your lnurl or lightning
|
||||
address.
|
||||
</h5>
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">POST (mainnet)</span>
|
||||
https://api.deezy.io/v1/source
|
||||
</code>
|
||||
<br />
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">POST (testnet)</span>
|
||||
https://api-testnet.deezy.io/v1/source
|
||||
</code>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Payload</h6>
|
||||
<pre>
|
||||
{
|
||||
"lnurl_or_lnaddress": "LNURL1DP68GURN8GHJ...",
|
||||
"secret_access_key": "b3c6056d2845867fa7..",
|
||||
"webhook_url": "https://your.website.com/dee.."
|
||||
}
|
||||
</pre>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Response</h6>
|
||||
<pre>
|
||||
{
|
||||
"address": "bc1qkceyc5...",
|
||||
"secret_access_key": "b3c6056d28458...",
|
||||
"commitment": "for any satoshis sent to bc1..",
|
||||
"signature": "d69j6aj1ssz5egmsr..",
|
||||
"webhook_url": "https://your.website.com/deez.."
|
||||
}
|
||||
</pre>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
<q-expansion-item
|
||||
group="btc-to-ln"
|
||||
dense
|
||||
expand-separator
|
||||
label="GET Lookup (BTC to LN) Swaps"
|
||||
>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-caption q-mt-sm q-mb-none">
|
||||
Lookup (BTC to LN) swaps
|
||||
</h5>
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">GET (mainnet)</span>
|
||||
https://api.deezy.io/v1/source/lookup
|
||||
</code>
|
||||
<br />
|
||||
<code class="text-light-blue">
|
||||
<span class="text-white">GET (testnet)</span>
|
||||
https://api-testnet.deezy.io/v1/source/lookup
|
||||
</code>
|
||||
<h6 class="text-caption q-mt-sm q-mb-none">Response</h6>
|
||||
<pre>
|
||||
{
|
||||
"swaps": [
|
||||
{
|
||||
"lnurl_or_lnaddress": "string",
|
||||
"deposit_address": "string",
|
||||
"utxo_key": "string",
|
||||
"deposit_amount_sats": 0,
|
||||
"target_payout_amount_sats": 0,
|
||||
"paid_amount_sats": 0,
|
||||
"deezy_fee_sats": 0,
|
||||
"status": "string"
|
||||
}
|
||||
],
|
||||
"total_sent_sats": 0,
|
||||
"total_received_sats": 0,
|
||||
"total_pending_payout_sats": 0,
|
||||
"total_deezy_fees_sats": 0
|
||||
}
|
||||
</pre>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-expansion-item>
|
||||
</q-expansion-item>
|
||||
</q-expansion-item>
|
588
lnbits/extensions/deezy/templates/deezy/index.html
Normal file
588
lnbits/extensions/deezy/templates/deezy/index.html
Normal file
|
@ -0,0 +1,588 @@
|
|||
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
|
||||
%} {% block page %}
|
||||
<div class="row q-col-gutter-md">
|
||||
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h5 class="text-subtitle1 q-mt-none q-mb-md">Deezy</h5>
|
||||
<p class="text-subtitle2 q-mt-none q-mb-md">
|
||||
An access token is required to use the swap service. Email
|
||||
support@deezy.io or contact @dannydeezy on telegram to get one.
|
||||
</p>
|
||||
<div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span>Deezy token </span>
|
||||
<q-btn
|
||||
type="button"
|
||||
@click="showDeezyTokenForm = !showDeezyTokenForm"
|
||||
>Add or Update token</q-btn
|
||||
>
|
||||
</div>
|
||||
<p v-if="storedDeezyToken" v-text="storedDeezyToken"></p>
|
||||
</div>
|
||||
<q-form
|
||||
v-if="showDeezyTokenForm"
|
||||
@submit="storeDeezyToken"
|
||||
class="q-gutter-md q-mt-lg"
|
||||
>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
:placeholder="storedDeezyToken"
|
||||
v-model.trim="deezyToken"
|
||||
label="Deezy Token"
|
||||
type="text"
|
||||
></q-input>
|
||||
<q-btn color="grey" type="submit" label="Store Deezy Token"></q-btn>
|
||||
</q-form>
|
||||
<q-separator class="q-my-lg"></q-separator>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<q-btn
|
||||
label="SWAP (LIGHTNING -> BTC)"
|
||||
unelevated
|
||||
color="primary"
|
||||
@click="showLnToBtcForm"
|
||||
:disabled="!storedDeezyToken"
|
||||
>
|
||||
<q-tooltip class="bg-grey-8" anchor="bottom left" self="top left">
|
||||
Send lightning btc and receive on-chain btc
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
label="SWAP (BTC -> LIGHTNING)"
|
||||
unelevated
|
||||
color="primary"
|
||||
@click="swapBtcToLn.show = true; swapLnToBtc.show = false;"
|
||||
:disabled="!storedDeezyToken"
|
||||
>
|
||||
<q-tooltip class="bg-grey-8" anchor="bottom left" self="top left">
|
||||
Send on-chain btc and receive via lightning
|
||||
</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<div
|
||||
v-show="swapLnToBtc.show"
|
||||
class="q-pa-lg q-pt-xl lnbits__dialog-card"
|
||||
>
|
||||
<h6 class="q-mt-none">LIGHTNING BTC -> BTC</h6>
|
||||
<q-form @submit="sendLnToBtc" class="q-gutter-md">
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
v-model.trim="swapLnToBtc.data.amount"
|
||||
label="Amount (sats)"
|
||||
type="number"
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
v-model.trim="swapLnToBtc.data.on_chain_address"
|
||||
type="string"
|
||||
label="Onchain address to receive funds"
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
v-model.trim="swapLnToBtc.data.on_chain_sats_per_vbyte"
|
||||
label="On chain fee rate (sats/vbyte)"
|
||||
min="1"
|
||||
type="number"
|
||||
:hint="swapLnToBtc.suggested_fees && `Economy Fee - ${swapLnToBtc.suggested_fees?.economyFee} | Half an hour fee - ${swapLnToBtc.suggested_fees?.halfHourFee} | Fastest fee - ${swapLnToBtc.suggested_fees?.fastestFee}`"
|
||||
>
|
||||
</q-input>
|
||||
<q-btn
|
||||
unelevated
|
||||
color="primary"
|
||||
type="submit"
|
||||
label="Create Swap"
|
||||
></q-btn>
|
||||
<q-btn flat color="grey" class="q-ml-auto" @click="resetSwapLnToBtc"
|
||||
>Cancel</q-btn
|
||||
>
|
||||
</q-form>
|
||||
<q-dialog v-model="swapLnToBtc.showInvoice" persistent>
|
||||
<q-card flat bordered class="my-card">
|
||||
<q-card-section>
|
||||
<div class="flex justify-between">
|
||||
<div class="text-h6">Pay invoice to complete swap</div>
|
||||
<q-btn flat v-close-popup>
|
||||
<q-icon name="close" />
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pt-none">
|
||||
<qrcode
|
||||
:value="swapLnToBtc.response"
|
||||
:options="{width: 360}"
|
||||
class="rounded-borders"
|
||||
></qrcode>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-btn
|
||||
outline
|
||||
@click="copyLnInvoice"
|
||||
label="Copy"
|
||||
color="primary"
|
||||
></q-btn>
|
||||
<q-input
|
||||
v-model="swapLnToBtc.response"
|
||||
type="textarea"
|
||||
readonly
|
||||
@click="$event.target.select()"
|
||||
/>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
<div
|
||||
v-show="swapBtcToLn.show"
|
||||
class="q-pa-lg q-pt-xl lnbits__dialog-card"
|
||||
>
|
||||
<h6 class="q-mt-none">BTC -> LIGHTNING BTC</h6>
|
||||
<q-form @submit="sendBtcToLn" class="q-gutter-md">
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
emit-value
|
||||
v-model.trim="swapBtcToLn.data.lnurl_or_lnaddress"
|
||||
label="Lnurl or Lightning Address"
|
||||
type="string"
|
||||
></q-input>
|
||||
<q-btn
|
||||
unelevated
|
||||
color="primary"
|
||||
type="submit"
|
||||
label="Generate Onchain Address"
|
||||
></q-btn>
|
||||
<q-btn flat color="grey" class="q-ml-auto" @click="resetSwapBtcToLn"
|
||||
>Cancel</q-btn
|
||||
>
|
||||
</q-form>
|
||||
<q-dialog v-model="swapBtcToLn.showDetails" persistent>
|
||||
<q-card flat bordered class="my-card">
|
||||
<q-card-section>
|
||||
<div class="flex justify-between">
|
||||
<div class="text-h6">Onchain Address</div>
|
||||
<q-btn flat v-close-popup>
|
||||
<q-icon name="close" />
|
||||
</q-btn>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
v-model="swapBtcToLn.response.address"
|
||||
type="textarea"
|
||||
readonly
|
||||
@click="$event.target.select()"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-btn
|
||||
outline
|
||||
@click="copyBtcToLnBtcAddress"
|
||||
label="Copy Address"
|
||||
color="primary"
|
||||
></q-btn>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
v-model="swapBtcToLn.response.commitment"
|
||||
type="textarea"
|
||||
readonly
|
||||
@click="$event.target.select()"
|
||||
/>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
{% raw %}
|
||||
<q-dialog v-model="swapLnToBtc.invoicePaid">
|
||||
<q-card class="bg-teal text-white" style="width: 400px">
|
||||
<q-card-section>
|
||||
<div class="text-h6">Success Bitcoin is on its way</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section class="q-pt-none">
|
||||
Onchain tx id {{ swapLnToBtc.onchainTxId }}
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right" class="bg-white text-teal">
|
||||
<q-btn flat label="OK" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
{% endraw %}
|
||||
</div>
|
||||
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-my-none">{{SITE_TITLE}} Boltz extension</h6>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-separator></q-separator>
|
||||
<q-list> {% include "deezy/_api_docs.html" %} </q-list>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="q-pa-md full-width">
|
||||
<q-table
|
||||
title="Swaps Lightning -> BTC"
|
||||
:data="rowsLnToBtc"
|
||||
:columns="columnsLnToBtc"
|
||||
row-key="name"
|
||||
/>
|
||||
</div>
|
||||
<div class="q-pa-md full-width">
|
||||
<q-table
|
||||
title="Swaps BTC -> Lightning"
|
||||
:data="rowsBtcToLn"
|
||||
:columns="columnsBtcToLn"
|
||||
row-key="name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||
<script>
|
||||
Vue.component(VueQrcode.name, VueQrcode)
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
columnsLnToBtc: [
|
||||
{
|
||||
name: 'amount_sats',
|
||||
label: 'Amount Sats',
|
||||
align: 'left',
|
||||
field: 'amount_sats',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'on_chain_address',
|
||||
align: 'left',
|
||||
label: 'On chain address',
|
||||
field: 'on_chain_address'
|
||||
},
|
||||
{
|
||||
name: 'on_chain_sats_per_vbyte',
|
||||
align: 'left',
|
||||
label: 'Onchin sats per vbyte',
|
||||
field: 'on_chain_sats_per_vbyte',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'fee_sats',
|
||||
label: 'Fee sats',
|
||||
align: 'left',
|
||||
field: 'fee_sats'
|
||||
},
|
||||
{name: 'txid', label: 'Tx Id', align: 'left', field: 'txid'},
|
||||
{name: 'tx_hex', label: 'Tx Hex', align: 'left', field: 'tx_hex'},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: 'Created at',
|
||||
align: 'left',
|
||||
field: 'created_at',
|
||||
sortable: true,
|
||||
sort: true
|
||||
}
|
||||
],
|
||||
rowsLnToBtc: [],
|
||||
columnsBtcToLn: [
|
||||
{
|
||||
name: 'ln_address',
|
||||
align: 'left',
|
||||
label: 'Ln Address or Invoice',
|
||||
field: 'ln_address'
|
||||
},
|
||||
{
|
||||
name: 'on_chain_address',
|
||||
align: 'left',
|
||||
label: 'Onchain Address',
|
||||
field: 'on_chain_address'
|
||||
},
|
||||
{
|
||||
name: 'secret_access_key',
|
||||
align: 'left',
|
||||
label: 'Secret Access Key',
|
||||
field: 'secret_access_key'
|
||||
},
|
||||
{
|
||||
name: 'commitment',
|
||||
align: 'left',
|
||||
label: 'Commitment',
|
||||
field: 'commitment'
|
||||
},
|
||||
{
|
||||
name: 'signature',
|
||||
align: 'left',
|
||||
label: 'Signature',
|
||||
field: 'signature'
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: 'Created at',
|
||||
field: 'created_at',
|
||||
align: 'left',
|
||||
sortable: true,
|
||||
sort: true
|
||||
}
|
||||
],
|
||||
rowsBtcToLn: [],
|
||||
showDeezyTokenForm: false,
|
||||
storedDeezyToken: null,
|
||||
deezyToken: null,
|
||||
lightning_btc: '',
|
||||
tools: [],
|
||||
swapLnToBtc: {
|
||||
show: false,
|
||||
showInvoice: false,
|
||||
data: {
|
||||
on_chain_sats_per_vbyte: 1
|
||||
},
|
||||
suggested_fees: null,
|
||||
response: null,
|
||||
invoicePaid: false,
|
||||
onchainTxId: null
|
||||
},
|
||||
swapBtcToLn: {
|
||||
show: false,
|
||||
showDetails: false,
|
||||
data: {},
|
||||
response: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
created: async function () {
|
||||
this.getToken()
|
||||
this.getLnToBtc()
|
||||
this.getBtcToLn()
|
||||
},
|
||||
methods: {
|
||||
updateLnToBtc(payload) {
|
||||
var self = this
|
||||
return axios
|
||||
.post('/deezy/api/v1/update-ln-to-btc', {
|
||||
...payload
|
||||
})
|
||||
.then(function (response) {
|
||||
console.log('btc to ln is update', response)
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
getToken() {
|
||||
var self = this
|
||||
axios({
|
||||
method: 'GET',
|
||||
url: '/deezy/api/v1/token'
|
||||
}).then(function (response) {
|
||||
self.storedDeezyToken = response.data.deezy_token
|
||||
if (!self.storeDeezyToken) {
|
||||
showDeezyTokenForm = true
|
||||
}
|
||||
})
|
||||
},
|
||||
getLnToBtc() {
|
||||
var self = this
|
||||
axios.get('/deezy/api/v1/ln-to-btc').then(function (response) {
|
||||
if (response.data.length) {
|
||||
self.rowsLnToBtc = response.data
|
||||
}
|
||||
})
|
||||
},
|
||||
getBtcToLn() {
|
||||
var self = this
|
||||
axios.get('/deezy/api/v1/btc-to-ln').then(function (response) {
|
||||
if (response.data.length) {
|
||||
self.rowsBtcToLn = response.data
|
||||
}
|
||||
})
|
||||
},
|
||||
showLnToBtcForm() {
|
||||
if (!this.swapLnToBtc.show) {
|
||||
this.getSuggestedOnChainFees()
|
||||
}
|
||||
this.swapLnToBtc.show = true
|
||||
this.swapBtcToLn.show = false
|
||||
},
|
||||
getSuggestedOnChainFees() {
|
||||
axios
|
||||
.get('https://mempool.space/api/v1/fees/recommended')
|
||||
.then(result => {
|
||||
this.swapLnToBtc.suggested_fees = result.data
|
||||
})
|
||||
},
|
||||
checkIfInvoiceIsPaid() {
|
||||
if (this.swapLnToBtc.response && !this.swapLnToBtc.invoicePaid) {
|
||||
var self = this
|
||||
let interval = setInterval(() => {
|
||||
axios
|
||||
.get(
|
||||
`https://api.deezy.io/v1/swap/lookup?bolt11_invoice=${self.swapLnToBtc.response}`
|
||||
)
|
||||
.then(async function (response) {
|
||||
if (response.data.on_chain_txid) {
|
||||
self.swapLnToBtc = {
|
||||
...self.swapLnToBtc,
|
||||
invoicePaid: true,
|
||||
onchainTxId: response.data.on_chain_txid
|
||||
}
|
||||
self
|
||||
.updateLnToBtc({
|
||||
txid: response.data.on_chain_txid,
|
||||
tx_hex: response.data.tx_hex,
|
||||
bolt11_invoice: self.swapLnToBtc.response
|
||||
})
|
||||
.then(() => {
|
||||
self.getLnToBtc()
|
||||
})
|
||||
clearInterval(interval)
|
||||
}
|
||||
})
|
||||
}, 4000)
|
||||
}
|
||||
},
|
||||
copyLnInvoice() {
|
||||
Quasar.utils.copyToClipboard(this.swapLnToBtc.response)
|
||||
},
|
||||
copyBtcToLnBtcAddress() {
|
||||
Quasar.utils.copyToClipboard(this.swapBtcToLn.response.address)
|
||||
},
|
||||
sendLnToBtc() {
|
||||
var self = this
|
||||
axios
|
||||
.post(
|
||||
'https://api.deezy.io/v1/swap',
|
||||
{
|
||||
amount_sats: parseInt(self.swapLnToBtc.data.amount),
|
||||
on_chain_address: self.swapLnToBtc.data.on_chain_address,
|
||||
on_chain_sats_per_vbyte: parseInt(
|
||||
self.swapLnToBtc.data.on_chain_sats_per_vbyte
|
||||
)
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'x-api-token': self.storedDeezyToken
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(function (response) {
|
||||
self.swapLnToBtc = {
|
||||
...self.swapLnToBtc,
|
||||
showInvoice: true,
|
||||
response: response.data.bolt11_invoice
|
||||
}
|
||||
const payload = {
|
||||
amount_sats: parseInt(self.swapLnToBtc.data.amount),
|
||||
on_chain_address: self.swapLnToBtc.data.on_chain_address,
|
||||
on_chain_sats_per_vbyte:
|
||||
self.swapLnToBtc.data.on_chain_sats_per_vbyte,
|
||||
bolt11_invoice: response.data.bolt11_invoice,
|
||||
fee_sats: response.data.fee_sats
|
||||
}
|
||||
self.storeLnToBtc(payload)
|
||||
self.checkIfInvoiceIsPaid()
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
sendBtcToLn() {
|
||||
var self = this
|
||||
axios
|
||||
.post(
|
||||
'https://api.deezy.io/v1/source',
|
||||
{
|
||||
lnurl_or_lnaddress: self.swapBtcToLn.data.lnurl_or_lnaddress
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
'x-api-token': self.storedDeezyToken
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(function (response) {
|
||||
self.swapBtcToLn = {
|
||||
...self.swapBtcToLn,
|
||||
response: response.data,
|
||||
showDetails: true
|
||||
}
|
||||
const payload = {
|
||||
ln_address: self.swapBtcToLn.data.lnurl_or_lnaddress,
|
||||
on_chain_address: response.data.address,
|
||||
secret_access_key: response.data.secret_access_key,
|
||||
commitment: response.data.commitment,
|
||||
signature: response.data.signature
|
||||
}
|
||||
self.storeBtcToLn(payload)
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
storeBtcToLn(payload) {
|
||||
var self = this
|
||||
axios
|
||||
.post('/deezy/api/v1/store-btc-to-ln', {
|
||||
...payload
|
||||
})
|
||||
.then(function (response) {
|
||||
console.log('btc to ln is stored', response)
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
storeLnToBtc(payload) {
|
||||
var self = this
|
||||
axios
|
||||
.post('/deezy/api/v1/store-ln-to-btc', {
|
||||
...payload
|
||||
})
|
||||
.then(function (response) {
|
||||
console.log('ln to btc is stored', response)
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
storeDeezyToken() {
|
||||
var self = this
|
||||
axios
|
||||
.post('/deezy/api/v1/store-token', {
|
||||
deezy_token: self.deezyToken
|
||||
})
|
||||
.then(function (response) {
|
||||
self.storedDeezyToken = response.data
|
||||
self.showDeezyTokenForm = false
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error)
|
||||
})
|
||||
},
|
||||
resetSwapBtcToLn() {
|
||||
this.swapBtcToLn = {
|
||||
...this.swapBtcToLn,
|
||||
data: {}
|
||||
}
|
||||
},
|
||||
resetSwapLnToBtc() {
|
||||
this.swapLnToBtc = {
|
||||
...this.swapLnToBtc,
|
||||
data: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
21
lnbits/extensions/deezy/views.py
Normal file
21
lnbits/extensions/deezy/views.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from fastapi import FastAPI, Request
|
||||
from fastapi.params import Depends
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from starlette.responses import HTMLResponse
|
||||
|
||||
from lnbits.core.models import User
|
||||
from lnbits.decorators import check_user_exists
|
||||
|
||||
from . import deezy_ext, deezy_renderer
|
||||
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
||||
|
||||
@deezy_ext.get("/", response_class=HTMLResponse)
|
||||
async def index(
|
||||
request: Request,
|
||||
user: User = Depends(check_user_exists), # type: ignore
|
||||
):
|
||||
return deezy_renderer().TemplateResponse(
|
||||
"deezy/index.html", {"request": request, "user": user.dict()}
|
||||
)
|
65
lnbits/extensions/deezy/views_api.py
Normal file
65
lnbits/extensions/deezy/views_api.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
# views_api.py is for you API endpoints that could be hit by another service
|
||||
|
||||
# add your dependencies here
|
||||
|
||||
# import httpx
|
||||
# (use httpx just like requests, except instead of response.ok there's only the
|
||||
# response.is_error that is its inverse)
|
||||
|
||||
from . import deezy_ext
|
||||
from .crud import (
|
||||
get_btc_to_ln,
|
||||
get_ln_to_btc,
|
||||
get_token,
|
||||
save_btc_to_ln,
|
||||
save_ln_to_btc,
|
||||
save_token,
|
||||
update_ln_to_btc,
|
||||
)
|
||||
from .models import BtcToLnSwap, LnToBtcSwap, Token, UpdateLnToBtcSwap
|
||||
|
||||
|
||||
@deezy_ext.get("/api/v1/token")
|
||||
async def api_deezy_get_token():
|
||||
rows = await get_token()
|
||||
return rows
|
||||
|
||||
|
||||
@deezy_ext.get("/api/v1/ln-to-btc")
|
||||
async def api_deezy_get_ln_to_btc():
|
||||
rows = await get_ln_to_btc()
|
||||
return rows
|
||||
|
||||
|
||||
@deezy_ext.get("/api/v1/btc-to-ln")
|
||||
async def api_deezy_get_btc_to_ln():
|
||||
rows = await get_btc_to_ln()
|
||||
return rows
|
||||
|
||||
|
||||
@deezy_ext.post("/api/v1/store-token")
|
||||
async def api_deezy_save_toke(data: Token):
|
||||
await save_token(data)
|
||||
|
||||
return data.deezy_token
|
||||
|
||||
|
||||
@deezy_ext.post("/api/v1/store-ln-to-btc")
|
||||
async def api_deezy_save_ln_to_btc(data: LnToBtcSwap):
|
||||
response = await save_ln_to_btc(data)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@deezy_ext.post("/api/v1/update-ln-to-btc")
|
||||
async def api_deezy_update_ln_to_btc(data: UpdateLnToBtcSwap):
|
||||
response = await update_ln_to_btc(data)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@deezy_ext.post("/api/v1/store-btc-to-ln")
|
||||
async def api_deezy_save_btc_to_ln(data: BtcToLnSwap):
|
||||
response = await save_btc_to_ln(data)
|
||||
|
||||
return response
|
|
@ -201,7 +201,7 @@
|
|||
dense
|
||||
v-model.trim="formDialog.data.amount"
|
||||
label="Amount"
|
||||
placeholder="10.00"
|
||||
placeholder="How much do you want to charge?"
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
|
@ -293,6 +293,7 @@
|
|||
domains: [],
|
||||
addresses: [],
|
||||
currencyOptions: [
|
||||
'Satoshis',
|
||||
'USD',
|
||||
'EUR',
|
||||
'GBP',
|
||||
|
|
|
@ -196,7 +196,12 @@ async def api_address_create(
|
|||
)
|
||||
|
||||
address = await create_address_internal(domain_id=domain_id, data=post_data)
|
||||
price_in_sats = await fiat_amount_as_satoshis(domain.amount / 100, domain.currency)
|
||||
if domain.currency == "Satoshis":
|
||||
price_in_sats = domain.amount
|
||||
else:
|
||||
price_in_sats = await fiat_amount_as_satoshis(
|
||||
domain.amount / 100, domain.currency
|
||||
)
|
||||
|
||||
try:
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user