Cleaned up watchonly

This commit is contained in:
Ben Arc
2021-04-04 13:17:24 +01:00
parent ae5d45a73e
commit 69ef4d7e63
6 changed files with 130 additions and 272 deletions

View File

@@ -92,16 +92,18 @@ async def get_fresh_address(wallet_id: str) -> Addresses:
address = await get_derive_address(wallet_id, wallet[4] + 1) address = await get_derive_address(wallet_id, wallet[4] + 1)
await update_watch_wallet(wallet_id = wallet_id, address_no = wallet[4] + 1) await update_watch_wallet(wallet_id = wallet_id, address_no = wallet[4] + 1)
masterpub_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO addresses ( INSERT INTO addresses (
id,
address, address,
wallet, wallet,
amount amount
) )
VALUES (?, ?, ?) VALUES (?, ?, ?, ?)
""", """,
(address, wallet_id, 0), (masterpub_id, address, wallet_id, 0),
) )
return await get_address(address) return await get_address(address)

View File

@@ -18,7 +18,8 @@ async def m001_initial(db):
await db.execute( await db.execute(
""" """
CREATE TABLE IF NOT EXISTS addresses ( CREATE TABLE IF NOT EXISTS addresses (
address TEXT NOT NULL PRIMARY KEY, id TEXT NOT NULL PRIMARY KEY,
address TEXT NOT NULL,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
amount INTEGER NOT NULL amount INTEGER NOT NULL
); );

View File

@@ -23,6 +23,7 @@ class Mempool(NamedTuple):
return cls(**dict(row)) return cls(**dict(row))
class Addresses(NamedTuple): class Addresses(NamedTuple):
id: str
address: str address: str
wallet: str wallet: str
amount: int amount: int

View File

@@ -1,9 +1,10 @@
<q-card> <q-card>
<q-card-section> <q-card-section>
<p>The WatchOnly extension uses mempool.space for blockchain data.<br /> <p>Watch Only extension uses mempool.space<br />
For use with "account Extended Public Key" <a href="https://iancoleman.io/bip39/">https://iancoleman.io/bip39/</a>
<small> <small>
Created by, <a href="https://github.com/benarc">Ben Arc</a></small <br />Created by, <a target="_blank" href="https://github.com/arcbtc">Ben Arc</a> (using, <a target="_blank" href="https://github.com/diybitcoinhardware/embit">Embit</a></small
> >)
</p> </p>
</q-card-section> </q-card-section>
@@ -15,31 +16,31 @@
label="API info" label="API info"
:content-inset-level="0.5" :content-inset-level="0.5"
> >
<q-expansion-item group="api" dense expand-separator label="List pay links"> <q-expansion-item group="api" dense expand-separator label="List wallets">
<q-card> <q-card>
<q-card-section> <q-card-section>
<code><span class="text-blue">GET</span> /pay/api/v1/links</code> <code><span class="text-blue">GET</span> /watchonly/api/v1/wallet</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5> <h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<h5 class="text-caption q-mt-sm q-mb-none"> <h5 class="text-caption q-mt-sm q-mb-none">
Returns 200 OK (application/json) Returns 200 OK (application/json)
</h5> </h5>
<code>[&lt;pay_link_object&gt;, ...]</code> <code>[&lt;wallets_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X GET {{ request.url_root }}pay/api/v1/links -H "X-Api-Key: {{ >curl -X GET {{ request.url_root }}api/v1/wallet -H "X-Api-Key: {{
g.user.wallets[0].inkey }}" g.user.wallets[0].inkey }}"
</code> </code>
</q-card-section> </q-card-section>
</q-card> </q-card>
</q-expansion-item> </q-expansion-item>
<q-expansion-item group="api" dense expand-separator label="Get a pay link"> <q-expansion-item group="api" dense expand-separator label="Get wallet details">
<q-card> <q-card>
<q-card-section> <q-card-section>
<code <code
><span class="text-blue">GET</span> ><span class="text-blue">GET</span>
/pay/api/v1/links/&lt;pay_id&gt;</code /watchonly/api/v1/wallet/&lt;wallet_id&gt;</code
> >
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
@@ -47,10 +48,10 @@
<h5 class="text-caption q-mt-sm q-mb-none"> <h5 class="text-caption q-mt-sm q-mb-none">
Returns 201 CREATED (application/json) Returns 201 CREATED (application/json)
</h5> </h5>
<code>{"lnurl": &lt;string&gt;}</code> <code>[&lt;wallet_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X GET {{ request.url_root }}pay/api/v1/links/&lt;pay_id&gt; -H >curl -X GET {{ request.url_root }}api/v1/wallet/&lt;wallet_id&gt; -H
"X-Api-Key: {{ g.user.wallets[0].inkey }}" "X-Api-Key: {{ g.user.wallets[0].inkey }}"
</code> </code>
</q-card-section> </q-card-section>
@@ -60,24 +61,22 @@
group="api" group="api"
dense dense
expand-separator expand-separator
label="Create a charge link" label="Create wallet"
> >
<q-card> <q-card>
<q-card-section> <q-card-section>
<code><span class="text-green">POST</span> /pay/api/v1/links</code> <code><span class="text-green">POST</span> /watchonly/api/v1/wallet</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5> <h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<code>{"description": &lt;string&gt; "amount": &lt;integer&gt;}</code>
<h5 class="text-caption q-mt-sm q-mb-none"> <h5 class="text-caption q-mt-sm q-mb-none">
Returns 201 CREATED (application/json) Returns 201 CREATED (application/json)
</h5> </h5>
<code>{"lnurl": &lt;string&gt;}</code> <code>[&lt;wallet_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X POST {{ request.url_root }}pay/api/v1/links -d >curl -X POST {{ request.url_root }}api/v1/wallet -d
'{"description": &lt;string&gt;, "amount": &lt;integer&gt;}' -H '{"title": &lt;string&gt;, "masterpub": &lt;string&gt;}' -H
"Content-type: application/json" -H "X-Api-Key: {{ "Content-type: application/json" -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}" g.user.wallets[0].adminkey }}"
</code> </code>
@@ -88,44 +87,14 @@
group="api" group="api"
dense dense
expand-separator expand-separator
label="Update a pay link" label="Delete wallet"
>
<q-card>
<q-card-section>
<code
><span class="text-green">PUT</span>
/pay/api/v1/links/&lt;pay_id&gt;</code
>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<code>{"description": &lt;string&gt;, "amount": &lt;integer&gt;}</code>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 200 OK (application/json)
</h5>
<code>{"lnurl": &lt;string&gt;}</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X PUT {{ request.url_root }}pay/api/v1/links/&lt;pay_id&gt; -d
'{"description": &lt;string&gt;, "amount": &lt;integer&gt;}' -H
"Content-type: application/json" -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item
group="api"
dense
expand-separator
label="Delete a pay link"
class="q-pb-md" class="q-pb-md"
> >
<q-card> <q-card>
<q-card-section> <q-card-section>
<code <code
><span class="text-pink">DELETE</span> ><span class="text-pink">DELETE</span>
/pay/api/v1/links/&lt;pay_id&gt;</code /watchonly/api/v1/wallet/&lt;wallet_id&gt;</code
> >
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
@@ -133,10 +102,95 @@
<code></code> <code></code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X DELETE {{ request.url_root }}pay/api/v1/links/&lt;pay_id&gt; >curl -X DELETE {{ request.url_root }}api/v1/wallet/&lt;wallet_id&gt;
-H "X-Api-Key: {{ g.user.wallets[0].adminkey }}" -H "X-Api-Key: {{ g.user.wallets[0].adminkey }}"
</code> </code>
</q-card-section> </q-card-section>
</q-card> </q-card>
</q-expansion-item> </q-expansion-item>
<q-expansion-item group="api" dense expand-separator label="List addresses">
<q-card>
<q-card-section>
<code><span class="text-blue">GET</span> /watchonly/api/v1/addresses/&lt;wallet_id&gt;</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 200 OK (application/json)
</h5>
<code>[&lt;address_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X GET {{ request.url_root }}api/v1/addresses/&lt;wallet_id&gt; -H "X-Api-Key: {{
g.user.wallets[0].inkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item group="api" dense expand-separator label="Get fresh address" class="q-pb-md">
<q-card>
<q-card-section>
<code><span class="text-blue">GET</span> /watchonly/api/v1/address/&lt;wallet_id&gt;</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 200 OK (application/json)
</h5>
<code>[&lt;address_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X GET {{ request.url_root }}api/v1/address/&lt;wallet_id&gt; -H "X-Api-Key: {{
g.user.wallets[0].inkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item group="api" dense expand-separator label="Get mempool.space details">
<q-card>
<q-card-section>
<code><span class="text-blue">GET</span> /watchonly/api/v1/mempool</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 200 OK (application/json)
</h5>
<code>[&lt;mempool_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X GET {{ request.url_root }}api/v1/mempool -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item group="api" dense expand-separator label="Update mempool.space" class="q-pb-md">
<q-card>
<q-card-section>
<code><span class="text-green">POST</span> /watchonly/api/v1/mempool</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 201 CREATED (application/json)
</h5>
<code>[&lt;mempool_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X PUT {{ request.url_root }}api/v1/mempool -d
'{"endpoint": &lt;string&gt;}' -H
"Content-type: application/json" -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
</q-expansion-item> </q-expansion-item>

View File

@@ -66,14 +66,8 @@
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th auto-width></q-th> <q-th auto-width></q-th>
<q-th v-for="col in props.cols" :key="col.name" :props="props" auto-width> <q-th v-for="col in props.cols" :key="col.name" :props="props" auto-width>
<div v-if="col.name == 'id'"></div>
<div v-else>
{{ col.label }} {{ col.label }}
</div>
</q-th> </q-th>
<q-th auto-width></q-th> <q-th auto-width></q-th>
</q-tr> </q-tr>
@@ -96,14 +90,6 @@
Adresses Adresses
</q-tooltip> </q-tooltip>
</q-btn> </q-btn>
<q-btn
flat
dense
size="xs"
@click="openUpdateDialog(props.row.id)"
icon="edit"
color="light-blue"
></q-btn>
<q-btn <q-btn
flat flat
dense dense
@@ -117,10 +103,7 @@
</q-td> </q-td>
</q-td> </q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props" auto-width> <q-td v-for="col in props.cols" :key="col.name" :props="props" auto-width>
<div v-if="col.name == 'id'"></div>
<div v-else>
{{ col.value }} {{ col.value }}
</div>
</q-td> </q-td>
@@ -137,7 +120,7 @@
<q-card> <q-card>
<q-card-section> <q-card-section>
<h6 class="text-subtitle1 q-my-none"> <h6 class="text-subtitle1 q-my-none">
LNbits WatchOnly Extension LNbits Watch Only Extension
</h6> </h6>
</q-card-section> </q-card-section>
<q-card-section class="q-pa-none"> <q-card-section class="q-pa-none">
@@ -165,20 +148,11 @@
v-model="formDialog.data.masterpub" v-model="formDialog.data.masterpub"
height="50px" height="50px"
autogrow autogrow
label="Master Public Key, either xpub, ypub, zpub" label="Account Extended Public Key; xpub, ypub, zpub"
></q-input> ></q-input>
<div class="row q-mt-lg"> <div class="row q-mt-lg">
<q-btn <q-btn
v-if="formDialog.data.id"
unelevated
color="deep-purple"
type="submit"
>Update Watch-only Wallet</q-btn
>
<q-btn
v-else
unelevated unelevated
color="deep-purple" color="deep-purple"
:disable=" :disable="
@@ -293,23 +267,6 @@
) )
return obj return obj
} }
var mapTxs = function (obj) {
obj._data = _.clone(obj)
obj.date = Quasar.utils.date.formatDate(
new Date(obj.time * 1000),
'YYYY-MM-DD HH:mm'
)
return obj
}
var mapCharge = function (obj) {
obj._data = _.clone(obj)
obj.date = Quasar.utils.date.formatDate(
new Date(obj.time * 1000),
'YYYY-MM-DD HH:mm'
)
return obj
}
new Vue({ new Vue({
el: '#vue', el: '#vue',
@@ -321,8 +278,6 @@
checker: null, checker: null,
walletLinks: [], walletLinks: [],
AddressesLinks: [], AddressesLinks: [],
txsLinks: [],
ChargeLinks: [],
currentaddress: "", currentaddress: "",
Addresses: { Addresses: {
show: false, show: false,
@@ -351,50 +306,6 @@
rowsPerPage: 10 rowsPerPage: 10
} }
}, },
ChargesTable: {
columns: [
{name: 'id', align: 'left', label: 'ID', field: 'id'},
{
name: 'title',
align: 'left',
label: 'Title',
field: 'title'
},
{
name: 'amount',
align: 'left',
label: 'Amount to pay',
field: 'amount'
},
{
name: 'balance',
align: 'left',
label: 'Balance',
field: 'amount_paid'
},
{
name: 'address',
align: 'left',
label: 'Address',
field: 'address'
},
{
name: 'time to pay',
align: 'left',
label: 'Time to Pay',
field: 'time_to_pay'
},
{
name: 'timeleft',
align: 'left',
label: 'Time left',
field: 'timeleft'
},
],
pagination: {
rowsPerPage: 10
}
},
formDialog: { formDialog: {
show: false, show: false,
data: {} data: {}
@@ -424,26 +335,6 @@
LNbits.utils.notifyApiError(error) LNbits.utils.notifyApiError(error)
}) })
}, },
getAddressTxs: function (address){
LNbits.api
.request(
'GET',
'/watchonly/api/v1/mempool/txs/' + address,
this.g.user.wallets[0].inkey
)
.then(function (response) {
self.txsLinks = response.data.map(function (obj) {
console.log(obj)
return mapTxs(obj)
})
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
},
getAddresses: function (walletID) { getAddresses: function (walletID) {
var self = this var self = this
LNbits.api LNbits.api
@@ -488,7 +379,7 @@
.request( .request(
'GET', 'GET',
'/watchonly/api/v1/mempool', '/watchonly/api/v1/mempool',
this.g.user.wallets[0].inkey this.g.user.wallets[0].adminkey
) )
.then(function (response) { .then(function (response) {
self.mempool.endpoint = response.data.endpoint self.mempool.endpoint = response.data.endpoint
@@ -505,7 +396,7 @@
.request( .request(
'PUT', 'PUT',
'/watchonly/api/v1/mempool', '/watchonly/api/v1/mempool',
wallet.inkey, self.mempool) wallet.adminkey, self.mempool)
.then(function (response) { .then(function (response) {
self.mempool.endpoint = response.data.endpoint self.mempool.endpoint = response.data.endpoint
self.walletLinks.push(mapwalletLink(response.data)) self.walletLinks.push(mapwalletLink(response.data))
@@ -549,47 +440,17 @@
self.current = linkId self.current = linkId
self.Addresses.show = true self.Addresses.show = true
}, },
openUpdateDialog: function (linkId) {
var link = _.findWhere(this.walletLinks, {id: linkId})
this.formDialog.data = _.clone(link._data)
this.formDialog.show = true
},
sendFormData: function () { sendFormData: function () {
var wallet = this.g.user.wallets[0] var wallet = this.g.user.wallets[0]
var data = _.omit(this.formDialog.data, 'wallet') var data = _.omit(this.formDialog.data, 'wallet')
if (data.id) {
this.updateWalletLink(wallet, data)
} else {
this.createWalletLink(wallet, data) this.createWalletLink(wallet, data)
}
},
updateWalletLink: function (wallet, data) {
var self = this
LNbits.api
.request(
'PUT',
'/watchonly/api/v1/wallet/' + data.id,
wallet.inkey, data)
.then(function (response) {
self.walletLinks = _.reject(self.walletLinks, function (obj) {
return obj.id === data.id
})
self.walletLinks.push(mapWalletLink(response.data))
self.formDialog.show = false
})
.catch(function (error) {
LNbits.utils.notifyApiError(error)
})
}, },
createWalletLink: function (wallet, data) { createWalletLink: function (wallet, data) {
var self = this var self = this
LNbits.api LNbits.api
.request('POST', '/watchonly/api/v1/wallet', wallet.inkey, data) .request('POST', '/watchonly/api/v1/wallet', wallet.adminkey, data)
.then(function (response) { .then(function (response) {
self.walletLinks.push(mapWalletLink(response.data)) self.walletLinks.push(mapWalletLink(response.data))
self.formDialog.show = false self.formDialog.show = false
@@ -608,7 +469,7 @@
.request( .request(
'DELETE', 'DELETE',
'/watchonly/api/v1/wallet/' + linkId, '/watchonly/api/v1/wallet/' + linkId,
self.g.user.wallets[0].inkey self.g.user.wallets[0].adminkey
) )
.then(function (response) { .then(function (response) {
self.walletLinks = _.reject(self.walletLinks, function (obj) { self.walletLinks = _.reject(self.walletLinks, function (obj) {

View File

@@ -37,17 +37,15 @@ async def api_wallets_retrieve():
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_wallet_retrieve(wallet_id): async def api_wallet_retrieve(wallet_id):
wallet = await get_watch_wallet(wallet_id) wallet = await get_watch_wallet(wallet_id)
addresses = await api_get_addresses(wallet_id)
if not wallet: if not wallet:
return jsonify({"message": "wallet does not exist"}), HTTPStatus.NOT_FOUND return jsonify({"message": "wallet does not exist"}), HTTPStatus.NOT_FOUND
return jsonify({wallet}), HTTPStatus.OK return jsonify(wallet._asdict()), HTTPStatus.OK
@watchonly_ext.route("/api/v1/wallet", methods=["POST"]) @watchonly_ext.route("/api/v1/wallet", methods=["POST"])
@watchonly_ext.route("/api/v1/wallet/<wallet_id>", methods=["PUT"]) @api_check_wallet_key("admin")
@api_check_wallet_key("invoice")
@api_validate_post_request( @api_validate_post_request(
schema={ schema={
"masterpub": {"type": "string", "empty": False, "required": True}, "masterpub": {"type": "string", "empty": False, "required": True},
@@ -55,20 +53,15 @@ async def api_wallet_retrieve(wallet_id):
} }
) )
async def api_wallet_create_or_update(wallet_id=None): async def api_wallet_create_or_update(wallet_id=None):
print("g.data")
if not wallet_id:
wallet = await create_watch_wallet(user=g.wallet.user, masterpub=g.data["masterpub"], title=g.data["title"]) wallet = await create_watch_wallet(user=g.wallet.user, masterpub=g.data["masterpub"], title=g.data["title"])
mempool = await get_mempool(g.wallet.user) mempool = await get_mempool(g.wallet.user)
if not mempool: if not mempool:
create_mempool(user=g.wallet.user) create_mempool(user=g.wallet.user)
return jsonify(wallet._asdict()), HTTPStatus.CREATED return jsonify(wallet._asdict()), HTTPStatus.CREATED
else:
wallet = await update_watch_wallet(wallet_id=wallet_id, **g.data)
return jsonify(wallet._asdict()), HTTPStatus.OK
@watchonly_ext.route("/api/v1/wallet/<wallet_id>", methods=["DELETE"]) @watchonly_ext.route("/api/v1/wallet/<wallet_id>", methods=["DELETE"])
@api_check_wallet_key("invoice") @api_check_wallet_key("admin")
async def api_wallet_delete(wallet_id): async def api_wallet_delete(wallet_id):
wallet = await get_watch_wallet(wallet_id) wallet = await get_watch_wallet(wallet_id)
@@ -114,7 +107,7 @@ async def api_get_addresses(wallet_id):
#############################MEMPOOL########################## #############################MEMPOOL##########################
@watchonly_ext.route("/api/v1/mempool", methods=["PUT"]) @watchonly_ext.route("/api/v1/mempool", methods=["PUT"])
@api_check_wallet_key("invoice") @api_check_wallet_key("admin")
@api_validate_post_request( @api_validate_post_request(
schema={ schema={
"endpoint": {"type": "string", "empty": False, "required": True}, "endpoint": {"type": "string", "empty": False, "required": True},
@@ -125,67 +118,13 @@ async def api_update_mempool():
return jsonify(mempool._asdict()), HTTPStatus.OK return jsonify(mempool._asdict()), HTTPStatus.OK
@watchonly_ext.route("/api/v1/mempool", methods=["GET"]) @watchonly_ext.route("/api/v1/mempool", methods=["GET"])
@api_check_wallet_key("invoice") @api_check_wallet_key("admin")
async def api_get_mempool(): async def api_get_mempool():
mempool = await get_mempool(g.wallet.user) mempool = await get_mempool(g.wallet.user)
if not mempool: if not mempool:
mempool = await create_mempool(user=g.wallet.user) mempool = await create_mempool(user=g.wallet.user)
return jsonify(mempool._asdict()), HTTPStatus.OK return jsonify(mempool._asdict()), HTTPStatus.OK
@watchonly_ext.route("/api/v1/mempool/<address>", methods=["GET"])
@api_check_wallet_key("invoice")
async def api_get_mempool_wallet_balance(address):
mempool = await get_mempool(g.wallet.user)
if not mempool:
mempool = await create_mempool(user=g.wallet.user)
url = (
mempool.endpoint
+ "/api/address/"
+ address
)
header = {
"Content-Type": "application/json",
}
async with httpx.AsyncClient() as client:
try:
r = await client.get(
url,
headers=header,
timeout=40,
)
mp_response = json.loads(r.text)
print(mp_response)
except AssertionError:
mp_response = "Error occured"
return jsonify(mp_response), HTTPStatus.OK
@watchonly_ext.route("/api/v1/mempool/txs/<address>", methods=["GET"])
@api_check_wallet_key("invoice")
async def api_get_mempool_wallet_txs(address):
mempool = await get_mempool(g.wallet.user)
if not mempool:
mempool = await create_mempool(user=g.wallet.user)
url = (
mempool.endpoint
+ "/api/address/"
+ address
+ "/txs"
)
header = {
"Content-Type": "application/json",
}
async with httpx.AsyncClient() as client:
try:
r = await client.get(
url,
headers=header,
timeout=40,
)
mp_response = json.loads(r.text)
print(mp_response)
except AssertionError:
mp_response = "Error occured"
return jsonify(mp_response), HTTPStatus.OK