Started fixing endpoints

This commit is contained in:
Ben Arc 2021-04-05 00:10:54 +01:00
parent 55748b427b
commit 744662fb63
3 changed files with 236 additions and 197 deletions

View File

@ -1,156 +1,169 @@
<q-card> <q-card>
<q-card-section> <q-card-section>
<p>SatsPay: Create Onchain/LN charges. Includes webhooks!<br /> <p>
<small> SatsPay: Create Onchain/LN charges. Includes webhooks!<br />
Created by, <a href="https://github.com/benarc">Ben Arc</a></small <small>
> Created by, <a href="https://github.com/benarc">Ben Arc</a></small
</p> >
</q-card-section> </p>
</q-card-section>
<q-expansion-item
group="extras"
icon="swap_vertical_circle"
label="API info"
:content-inset-level="0.5"
>
<q-expansion-item group="api" dense expand-separator label="List pay links">
<q-card>
<q-card-section>
<code><span class="text-blue">GET</span> /pay/api/v1/links</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;pay_link_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X GET {{ request.url_root }}pay/api/v1/links -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 a pay link">
<q-card>
<q-card-section>
<code
><span class="text-blue">GET</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;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 201 CREATED (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 GET {{ request.url_root }}pay/api/v1/links/&lt;pay_id&gt; -H
"X-Api-Key: {{ g.user.wallets[0].inkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item <q-expansion-item
group="api" group="extras"
dense icon="swap_vertical_circle"
expand-separator label="API info"
label="Create a charge link" :content-inset-level="0.5"
> >
<q-card> <q-expansion-item group="api" dense expand-separator label="Create charge">
<q-card-section> <q-card>
<code><span class="text-green">POST</span> /pay/api/v1/links</code> <q-card-section>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5> <code
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br /> ><span class="text-blue">POST</span> /satspay/api/v1/charge</code
<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">Headers</h5>
<h5 class="text-caption q-mt-sm q-mb-none"> <code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
Returns 201 CREATED (application/json) <h5 class="text-caption q-mt-sm q-mb-none">
</h5> Body (application/json)
<code> { </h5>
"deliveryId": &lt;string&gt;, <h5 class="text-caption q-mt-sm q-mb-none">
"description": &lt;string&gt;, Returns 200 OK (application/json)
"webhookId": &lt;string&gt;, </h5>
"originalDeliveryId": &lt;string&gt;, <code>[&lt;charge_object&gt;, ...]</code>
"isRedelivery": &lt;boolean&gt;, <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
"type": &lt;string&gt;, <code
"timestamp": &lt;int&gt;, >curl -X POST {{ request.url_root }}api/v1/charge -d
"paytime": &lt;int&gt;, '{"onchainwallet": &lt;string, watchonly_wallet_id&gt;,
"storeId": &lt;string&gt;, "description": &lt;string&gt;, "webhook":&lt;string&gt;, "time":
"invoiceId": &lt;string&gt;, &lt;integer&gt;, "amount": &lt;integer&gt;, "lnbitswallet":
"manuallyMarked": &lt;boolean&gt;, &lt;string, lnbits_wallet_id&gt;}' -H "Content-type:
"overPaid": &lt;boolean&gt;, application/json" -H "X-Api-Key: {{g.user.wallets[0].adminkey }}"
"afterExpiration": &lt;boolean&gt;, </code>
"partiallyPaid": &lt;boolean&gt; </q-card-section>
}<br/><small>"type" can be InvoiceReceivedPayment, InvoicePaidInFull, InvoiceExpired, InvoiceConfirmed, and InvoiceInvalid</small> </code> </q-card>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> </q-expansion-item>
<code <q-expansion-item group="api" dense expand-separator label="Get a pay link">
>curl -X POST {{ request.url_root }}pay/api/v1/links -d <q-card>
'{"description": &lt;string&gt;, "amount": &lt;integer&gt;}' -H <q-card-section>
"Content-type: application/json" -H "X-Api-Key: {{ <code
g.user.wallets[0].adminkey }}" ><span class="text-blue">GET</span>
</code> /pay/api/v1/links/&lt;pay_id&gt;</code
</q-card-section> >
</q-card> <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 201 CREATED (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 GET {{ request.url_root }}pay/api/v1/links/&lt;pay_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="Create a charge link"
>
<q-card>
<q-card-section>
<code><span class="text-green">POST</span> /pay/api/v1/links</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>
<code>{"description": &lt;string&gt; "amount": &lt;integer&gt;}</code>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 201 CREATED (application/json)
</h5>
<code>
{ "deliveryId": &lt;string&gt;, "description": &lt;string&gt;,
"webhookId": &lt;string&gt;, "originalDeliveryId": &lt;string&gt;,
"isRedelivery": &lt;boolean&gt;, "type": &lt;string&gt;,
"timestamp": &lt;int&gt;, "paytime": &lt;int&gt;, "storeId":
&lt;string&gt;, "invoiceId": &lt;string&gt;, "manuallyMarked":
&lt;boolean&gt;, "overPaid": &lt;boolean&gt;, "afterExpiration":
&lt;boolean&gt;, "partiallyPaid": &lt;boolean&gt; }<br /><small
>"type" can be InvoiceReceivedPayment, InvoicePaidInFull,
InvoiceExpired, InvoiceConfirmed, and InvoiceInvalid</small
>
</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X POST {{ request.url_root }}pay/api/v1/links -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="Update a pay link"
>
<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"
>
<q-card>
<q-card-section>
<code
><span class="text-pink">DELETE</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">Returns 204 NO CONTENT</h5>
<code></code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X DELETE {{ request.url_root
}}pay/api/v1/links/&lt;pay_id&gt; -H "X-Api-Key: {{
g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
</q-expansion-item> </q-expansion-item>
<q-expansion-item </q-card>
group="api"
dense
expand-separator
label="Update a pay link"
>
<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"
>
<q-card>
<q-card-section>
<code
><span class="text-pink">DELETE</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">Returns 204 NO CONTENT</h5>
<code></code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X DELETE {{ request.url_root }}pay/api/v1/links/&lt;pay_id&gt;
-H "X-Api-Key: {{ g.user.wallets[0].adminkey }}"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
</q-expansion-item>

View File

@ -324,6 +324,18 @@
ChargesTable: { ChargesTable: {
columns: [ columns: [
{
name: 'timeleft',
align: 'left',
label: 'Time left',
field: 'countdown'
},
{
name: 'id',
align: 'left',
label: 'ID',
field: 'id'
},
{ {
name: 'description', name: 'description',
align: 'left', align: 'left',
@ -360,12 +372,6 @@
label: 'Time to Pay', label: 'Time to Pay',
field: 'time' field: 'time'
}, },
{
name: 'timeleft',
align: 'left',
label: 'Time left',
field: 'date'
},
], ],
pagination: { pagination: {
rowsPerPage: 10 rowsPerPage: 10
@ -386,8 +392,19 @@
} }
}, },
computed: {
updateCountdowns() {
console.log("whatever")
Object.mapWalletLink(this.data).forEach(row => {
let datem = moment(row.time).format('YYYY-MM-DD HH:mm');
row.countdown = countdown(new Date(datem).getTime()).toString();
})
}
},
methods: { methods: {
getWalletLinks: function () { getWalletLinks: function () {
var self = this var self = this
@ -466,8 +483,8 @@
} }
self.ChargeLinks = response.data.map(function (obj) { self.ChargeLinks = response.data.map(function (obj) {
console.log(obj.timestamp)
console.log(Date.now()/1000)
return mapCharge(obj) return mapCharge(obj)
}) })
}) })
@ -637,6 +654,8 @@
} }
}, 5000); }, 5000);
getCharges() getCharges()
} }
}) })
</script> </script>

View File

@ -17,19 +17,31 @@ from .crud import (
) )
#############################CHARGES########################## #############################CHARGES##########################
@satspay_ext.route("/api/v1/charges/balance/<charge_id>", methods=["GET"])
@api_check_wallet_key("invoice")
async def api_charges_balance(charge_id):
charge = await check_address_balance(charge_id)
if not charge: @satspay_ext.route("/api/v1/charge", methods=["POST"])
return ( @satspay_ext.route("/api/v1/charge/<charge_id>", methods=["PUT"])
jsonify(""), @api_check_wallet_key("admin")
HTTPStatus.OK @api_validate_post_request(
) schema={
"onchainwallet": {"type": "string"},
"lnbitswallet": {"type": "string"},
"description": {"type": "string", "empty": False, "required": True},
"webhook": {"type": "string", "empty": False, "required": True},
"time": {"type": "integer", "min": 1, "required": True},
"amount": {"type": "integer", "min": 1, "required": True},
}
)
async def api_charge_create_or_update(charge_id=None):
if not charge_id:
charge = await create_charge(user=g.wallet.user, **g.data)
return jsonify(charge._asdict()), HTTPStatus.CREATED
else: else:
charge = await update_charge(user=g.wallet.user, **g.data)
return jsonify(charge._asdict()), HTTPStatus.OK return jsonify(charge._asdict()), HTTPStatus.OK
@satspay_ext.route("/api/v1/charges", methods=["GET"]) @satspay_ext.route("/api/v1/charges", methods=["GET"])
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_charges_retrieve(): async def api_charges_retrieve():
@ -47,37 +59,14 @@ async def api_charges_retrieve():
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["GET"]) @satspay_ext.route("/api/v1/charge/<charge_id>", methods=["GET"])
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_charge_retrieve(charge_id): async def api_charge_retrieve(charge_id):
charge = get_charge(charge_id) charge = get_charge(charge_id)
if not charge: if not charge:
return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND
return jsonify({charge}), HTTPStatus.OK return jsonify({charge}), HTTPStatus.OK
@satspay_ext.route("/api/v1/charge", methods=["POST"])
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["PUT"])
@api_check_wallet_key("invoice")
@api_validate_post_request(
schema={
"onchainwallet": {"type": "string"},
"lnbitswallet": {"type": "string"},
"description": {"type": "string", "empty": False, "required": True},
"webhook": {"type": "string", "empty": False, "required": True},
"time": {"type": "integer", "min": 1, "required": True},
"amount": {"type": "integer", "min": 1, "required": True},
}
)
async def api_charge_create_or_update(charge_id=None):
if not charge_id:
charge = await create_charge(user = g.wallet.user, **g.data)
return jsonify(charge), HTTPStatus.CREATED
else:
charge = await update_charge(user = g.wallet.user, **g.data)
return jsonify(charge), HTTPStatus.OK
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["DELETE"]) @satspay_ext.route("/api/v1/charge/<charge_id>", methods=["DELETE"])
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_charge_delete(charge_id): async def api_charge_delete(charge_id):
@ -90,8 +79,25 @@ async def api_charge_delete(charge_id):
return "", HTTPStatus.NO_CONTENT return "", HTTPStatus.NO_CONTENT
#############################BALANCE##########################
@satspay_ext.route("/api/v1/charges/balance/<charge_id>", methods=["GET"])
@api_check_wallet_key("invoice")
async def api_charges_balance(charge_id):
charge = await check_address_balance(charge_id)
if not charge:
return (
jsonify(""),
HTTPStatus.OK
)
else:
return jsonify(charge._asdict()), HTTPStatus.OK
#############################MEMPOOL########################## #############################MEMPOOL##########################
@satspay_ext.route("/api/v1/mempool", methods=["PUT"]) @satspay_ext.route("/api/v1/mempool", methods=["PUT"])
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
@api_validate_post_request( @api_validate_post_request(
@ -101,12 +107,13 @@ async def api_charge_delete(charge_id):
) )
async def api_update_mempool(): async def api_update_mempool():
mempool = await update_mempool(user=g.wallet.user, **g.data) mempool = await update_mempool(user=g.wallet.user, **g.data)
return jsonify(mempool._asdict()), HTTPStatus.OK return jsonify(mempool._asdict()), HTTPStatus.OK
@satspay_ext.route("/api/v1/mempool", methods=["GET"]) @satspay_ext.route("/api/v1/mempool", methods=["GET"])
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
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