Merge remote-tracking branch 'origin/main' into add-satoshis-currency-option-nip5
This commit is contained in:
commit
cf03ae0a5f
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
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user