re-create @iWarpBTC commit ID a9df953990ea454e8cafc87f64395efc1929c321

This commit is contained in:
Lee Salminen 2022-08-14 10:48:23 -06:00
parent f8d4c39b1e
commit 4c758f4665
3 changed files with 138 additions and 22 deletions

View file

@ -1,10 +1,31 @@
<h1>Bolt cards (NXP NTAG) Extension</h1> # Bolt cards (NXP NTAG) Extension
This extension allows you to link your Bolt card with a LNbits instance and use it more securely then just with a static LNURLw on it. A technology called [Secure Unique NFC](https://mishka-scan.com/blog/secure-unique-nfc) is utilized in this workflow. This extension allows you to link your Bolt card with a LNbits instance and use it more securely then just with a static LNURLw on it. A technology called [Secure Unique NFC](https://mishka-scan.com/blog/secure-unique-nfc) is utilized in this workflow.
**In order to use this extension you need to be able setup your card first.** There's a [guide](https://www.whitewolftech.com/articles/payment-card/) to set it up with your computer. Hopefully a mobile app is to come to do this. ***In order to use this extension you need to be able setup your card first.*** There's a [guide](https://www.whitewolftech.com/articles/payment-card/) to set it up with your computer. Or it can be done with [https://play.google.com/store/apps/details?id=com.nxp.nfc.tagwriter](TagWriter app by NXP) Android app.
<h2>Setting the outside the extension</h2> ## Setting the outside the extension - android
- Write tags
- New Data Set > Link
- Set URI type to Custom URL
- URL should look like lnurlw://YOUR_LNBITS_DOMAIN/boltcards/api/v1/scane?e=00000000000000000000000000000000&c=0000000000000000
- click Configure mirroring options
- Select Card Type NTAG 424 DNA
- Check Enable SDM Mirroring
- Select SDM Meta Read Access Right to 01
- Check Enable UID Mirroring
- Check Enable Counter Mirroring
- Set SDM Counter Retrieval Key to 0E
- Set PICC Data Offset to immediately after e=
- Set Derivation Key for CMAC Calculation to 00
- Set SDM MAC Input Offset to immediately after c=
- Set SDM MAC Offset to immediately after c=
- Save & Write
- Scan with compatible Wallet
## Setting the outside the extension - computer
Follow the guide.
The URI should be `lnurlw://YOUR-DOMAIN.COM/boltcards/api/v1/scane/?e=00000000000000000000000000000000&c=0000000000000000` The URI should be `lnurlw://YOUR-DOMAIN.COM/boltcards/api/v1/scane/?e=00000000000000000000000000000000&c=0000000000000000`
@ -12,7 +33,7 @@ The URI should be `lnurlw://YOUR-DOMAIN.COM/boltcards/api/v1/scane/?e=0000000000
Choose and note your Meta key and File key. Choose and note your Meta key and File key.
<h2>Adding the into the extension</h2> ## Adding the into the extension
Create a withdraw link within the LNURLw extension before adding a card. Enable the `Use unique withdraw QR codes to reduce 'assmilking'` option. Create a withdraw link within the LNURLw extension before adding a card. Enable the `Use unique withdraw QR codes to reduce 'assmilking'` option.

View file

@ -26,7 +26,7 @@ async def create_card(data: CreateCardData, wallet_id: str) -> Card:
( (
card_id, card_id,
wallet_id, wallet_id,
data.name, data.card_name,
data.uid, data.uid,
data.counter, data.counter,
data.withdraw, data.withdraw,

View file

@ -33,27 +33,15 @@
{% raw %} {% raw %}
<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 v-for="col in props.cols" :key="col.name" :props="props"> <q-th v-for="col in props.cols" :key="col.name" :props="props">
{{ col.label }} {{ col.label }}
</q-th> </q-th>
<q-th auto-width></q-th> <q-th auto-width></q-th>
<q-th auto-width></q-th>
</q-tr> </q-tr>
</template> </template>
<template v-slot:body="props"> <template v-slot:body="props">
<q-tr :props="props"> <q-tr :props="props">
<q-td auto-width>
<q-btn
unelevated
dense
size="xs"
icon="link"
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
type="a"
:href="props.row.displayUrl"
target="_blank"
></q-btn>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props"> <q-td v-for="col in props.cols" :key="col.name" :props="props">
{{ col.value }} {{ col.value }}
</q-td> </q-td>
@ -84,6 +72,45 @@
</q-table> </q-table>
</q-card-section> </q-card-section>
</q-card> </q-card>
<q-card>
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Hits</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportCardsCSV"
>Export to CSV</q-btn
>
</div>
</div>
<q-table
dense
flat
:data="hits"
row-key="id"
:columns="hitsTable.columns"
:pagination.sync="hitsTable.pagination"
>
{% raw %}
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
{{ col.label }}
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td v-for="col in props.cols" :key="col.name" :props="props">
{{ col.value }}
</q-td>
</q-tr>
</template>
{% endraw %}
</q-table>
</q-card-section>
</q-card>
</div> </div>
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md"> <div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
<q-card> <q-card>
@ -98,7 +125,7 @@
</q-card-section> </q-card-section>
</q-card> </q-card>
</div> </div>
<q-dialog v-model="cardDialog.show" position="top"> <q-dialog v-model="cardDialog.show" position="top" @hide="closeFormDialog">
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card"> <q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
<q-form @submit="sendFormData" class="q-gutter-md"> <q-form @submit="sendFormData" class="q-gutter-md">
<q-select <q-select
@ -196,7 +223,6 @@
'YYYY-MM-DD HH:mm' 'YYYY-MM-DD HH:mm'
) )
obj.displayUrl = ['/boltcards/', obj.id].join('')
return obj return obj
} }
@ -206,6 +232,7 @@
data: function () { data: function () {
return { return {
cards: [], cards: [],
hits: [],
withdrawsOptions: [], withdrawsOptions: [],
cardDialog: { cardDialog: {
show: false, show: false,
@ -235,6 +262,51 @@
pagination: { pagination: {
rowsPerPage: 10 rowsPerPage: 10
} }
},
hitsTable: {
columns: [
{
name: 'card_name',
align: 'left',
label: 'Card name',
field: 'card_name'
},
{
name: 'old_ctr',
align: 'left',
label: 'Old counter',
field: 'old_ctr'
},
{
name: 'new_ctr',
align: 'left',
label: 'New counter',
field: 'new_ctr'
},
{
name: 'date',
align: 'left',
label: 'Time',
field: 'date'
},
{
name: 'ip',
align: 'left',
label: 'IP',
field: 'ip'
},
{
name: 'useragent',
align: 'left',
label: 'User agent',
field: 'useragent'
}
],
pagination: {
rowsPerPage: 10,
sortBy: 'date',
descending: true
}
} }
} }
}, },
@ -255,6 +327,25 @@
console.log(self.cards) console.log(self.cards)
}) })
}, },
getHits: function () {
var self = this
LNbits.api
.request(
'GET',
'/boltcards/api/v1/hits?all_wallets=true',
this.g.user.wallets[0].inkey
)
.then(function (response) {
self.hits = response.data.map(function (obj) {
obj.card_name = self.cards.find(
d => d.id == obj.card_id
).card_name
return mapCards(obj)
})
console.log(self.hits)
})
},
getWithdraws: function () { getWithdraws: function () {
var self = this var self = this
@ -274,6 +365,9 @@
console.log(self.withdraws) console.log(self.withdraws)
}) })
}, },
closeFormDialog: function () {
this.cardDialog.data = {}
},
sendFormData: function () { sendFormData: function () {
let wallet = _.findWhere(this.g.user.wallets, { let wallet = _.findWhere(this.g.user.wallets, {
id: this.cardDialog.data.wallet id: this.cardDialog.data.wallet
@ -358,6 +452,7 @@
created: function () { created: function () {
if (this.g.user.wallets.length) { if (this.g.user.wallets.length) {
this.getCards() this.getCards()
this.getHits()
this.getWithdraws() this.getWithdraws()
} }
} }