Merge branch 'main' into diagon-alley
This commit is contained in:
commit
93d61a7ac5
18 changed files with 215 additions and 45 deletions
13
.github/workflows/formatting.yml
vendored
13
.github/workflows/formatting.yml
vendored
|
|
@ -9,9 +9,20 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
checks:
|
checks:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: poetry install
|
run: poetry install
|
||||||
- name: Check black
|
- name: Check black
|
||||||
|
|
|
||||||
8
.github/workflows/migrations.yml
vendored
8
.github/workflows/migrations.yml
vendored
|
|
@ -22,14 +22,18 @@ jobs:
|
||||||
--health-retries 5
|
--health-retries 5
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
poetry install
|
poetry install
|
||||||
|
|
|
||||||
8
.github/workflows/mypy.yml
vendored
8
.github/workflows/mypy.yml
vendored
|
|
@ -7,14 +7,18 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
poetry install
|
poetry install
|
||||||
|
|
|
||||||
24
.github/workflows/regtest.yml
vendored
24
.github/workflows/regtest.yml
vendored
|
|
@ -7,14 +7,18 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Setup Regtest
|
- name: Setup Regtest
|
||||||
run: |
|
run: |
|
||||||
docker build -t lnbitsdocker/lnbits-legend .
|
docker build -t lnbitsdocker/lnbits-legend .
|
||||||
|
|
@ -46,14 +50,18 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Setup Regtest
|
- name: Setup Regtest
|
||||||
run: |
|
run: |
|
||||||
docker build -t lnbitsdocker/lnbits-legend .
|
docker build -t lnbitsdocker/lnbits-legend .
|
||||||
|
|
@ -86,14 +94,18 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Setup Regtest
|
- name: Setup Regtest
|
||||||
run: |
|
run: |
|
||||||
docker build -t lnbitsdocker/lnbits-legend .
|
docker build -t lnbitsdocker/lnbits-legend .
|
||||||
|
|
|
||||||
19
.github/workflows/tests.yml
vendored
19
.github/workflows/tests.yml
vendored
|
|
@ -7,7 +7,8 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
|
@ -29,14 +30,18 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
env:
|
env:
|
||||||
VIRTUAL_ENV: ./venv
|
VIRTUAL_ENV: ./venv
|
||||||
|
|
@ -64,14 +69,18 @@ jobs:
|
||||||
--health-retries 5
|
--health-retries 5
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.9]
|
python-version: ["3.9"]
|
||||||
|
poetry-version: ["1.2.1"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- uses: abatilo/actions-poetry@v2.1.3
|
- name: Set up Poetry ${{ matrix.poetry-version }}
|
||||||
|
uses: abatilo/actions-poetry@v2
|
||||||
|
with:
|
||||||
|
poetry-version: ${{ matrix.poetry-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
poetry install
|
poetry install
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,43 @@ Save the file and run the following commands:
|
||||||
sudo systemctl enable lnbits.service
|
sudo systemctl enable lnbits.service
|
||||||
sudo systemctl start lnbits.service
|
sudo systemctl start lnbits.service
|
||||||
```
|
```
|
||||||
|
## Reverse proxy with automatic https using Caddy
|
||||||
|
|
||||||
|
Use Caddy to make your LNbits install accessible over clearnet with a domain and https cert.
|
||||||
|
|
||||||
|
Point your domain at the IP of the server you're running LNbits on, by making an `A` record.
|
||||||
|
|
||||||
|
Install Caddy on the server
|
||||||
|
https://caddyserver.com/docs/install#debian-ubuntu-raspbian
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo caddy stop
|
||||||
|
```
|
||||||
|
Create a Caddyfile
|
||||||
|
```
|
||||||
|
sudo nano Caddyfile
|
||||||
|
```
|
||||||
|
Assuming your LNbits is running on port `5000` add:
|
||||||
|
```
|
||||||
|
yourdomain.com {
|
||||||
|
handle /api/v1/payments/sse* {
|
||||||
|
reverse_proxy 0.0.0.0:5000 {
|
||||||
|
header_up X-Forwarded-Host yourdomain.com
|
||||||
|
transport http {
|
||||||
|
keepalive off
|
||||||
|
compression off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reverse_proxy 0.0.0.0:5000 {
|
||||||
|
header_up X-Forwarded-Host yourdomain.com
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Save and exit `CTRL + x`
|
||||||
|
```
|
||||||
|
sudo caddy start
|
||||||
|
```
|
||||||
|
|
||||||
## Running behind an apache2 reverse proxy over https
|
## Running behind an apache2 reverse proxy over https
|
||||||
Install apache2 and enable apache2 mods
|
Install apache2 and enable apache2 mods
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,11 @@ const CACHE_VERSION = 1
|
||||||
const CURRENT_CACHE = `lnbits-${CACHE_VERSION}-`
|
const CURRENT_CACHE = `lnbits-${CACHE_VERSION}-`
|
||||||
|
|
||||||
const getApiKey = request => {
|
const getApiKey = request => {
|
||||||
return request.headers.get('X-Api-Key') || 'none'
|
let api_key = request.headers.get('X-Api-Key')
|
||||||
|
if (!api_key || api_key == 'undefined') {
|
||||||
|
api_key = 'no_api_key'
|
||||||
|
}
|
||||||
|
return api_key
|
||||||
}
|
}
|
||||||
|
|
||||||
// on activation we clean up the previously registered service workers
|
// on activation we clean up the previously registered service workers
|
||||||
|
|
@ -26,8 +30,10 @@ self.addEventListener('activate', evt =>
|
||||||
// If no response is found, it populates the runtime cache with the response
|
// If no response is found, it populates the runtime cache with the response
|
||||||
// from the network before returning it to the page.
|
// from the network before returning it to the page.
|
||||||
self.addEventListener('fetch', event => {
|
self.addEventListener('fetch', event => {
|
||||||
// Skip cross-origin requests, like those for Google Analytics.
|
|
||||||
if (
|
if (
|
||||||
|
!event.request.url.startsWith(
|
||||||
|
self.location.origin + '/api/v1/payments/sse'
|
||||||
|
) &&
|
||||||
event.request.url.startsWith(self.location.origin) &&
|
event.request.url.startsWith(self.location.origin) &&
|
||||||
event.request.method == 'GET'
|
event.request.method == 'GET'
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,21 @@
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h6 class="text-subtitle1 q-my-none">{{SITE_TITLE}} Scrub extension</h6>
|
<h6 class="text-subtitle1 q-my-none">{{SITE_TITLE}} Scrub extension</h6>
|
||||||
|
<p>
|
||||||
|
Automatically forward funds (Scrub) that get paid to the LNbits
|
||||||
|
wallet, to an LNURLpay or Lightning Address.
|
||||||
|
<br />
|
||||||
|
More info in Scrub's
|
||||||
|
<a
|
||||||
|
href="https://github.com/lnbits/lnbits/blob/main/lnbits/extensions/scrub/README.md#scrub"
|
||||||
|
target="_blank"
|
||||||
|
>readme</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
<p style="font-size: 90%">
|
||||||
|
<strong>Important: </strong>wallet will need a float to account for
|
||||||
|
any fees, before being able to push a payment
|
||||||
|
</p>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ class CreatePsbt(BaseModel):
|
||||||
class ExtractPsbt(BaseModel):
|
class ExtractPsbt(BaseModel):
|
||||||
psbtBase64 = "" # // todo snake case
|
psbtBase64 = "" # // todo snake case
|
||||||
inputs: List[TransactionInput]
|
inputs: List[TransactionInput]
|
||||||
|
network = "Mainnet"
|
||||||
|
|
||||||
|
|
||||||
class SignedTransaction(BaseModel):
|
class SignedTransaction(BaseModel):
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<send-to
|
<send-to
|
||||||
:data.sync="sendToList"
|
:data.sync="sendToList"
|
||||||
:fee-rate="feeRate"
|
:fee-rate="feeRate"
|
||||||
:tx-size="txSizeNoChange"
|
:tx-size="txSize"
|
||||||
:selected-amount="selectedAmount"
|
:selected-amount="selectedAmount"
|
||||||
:sats-denominated="satsDenominated"
|
:sats-denominated="satsDenominated"
|
||||||
@update:outputs="handleOutputsChange"
|
@update:outputs="handleOutputsChange"
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ async function payment(path) {
|
||||||
'mempool-endpoint',
|
'mempool-endpoint',
|
||||||
'sats-denominated',
|
'sats-denominated',
|
||||||
'serial-signer-ref',
|
'serial-signer-ref',
|
||||||
'adminkey'
|
'adminkey',
|
||||||
|
'network'
|
||||||
],
|
],
|
||||||
watch: {
|
watch: {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
|
@ -279,7 +280,8 @@ async function payment(path) {
|
||||||
this.adminkey,
|
this.adminkey,
|
||||||
{
|
{
|
||||||
psbtBase64,
|
psbtBase64,
|
||||||
inputs: this.tx.inputs
|
inputs: this.tx.inputs,
|
||||||
|
network: this.network
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return data
|
return data
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
<q-item
|
<q-item
|
||||||
v-for="device in pairedDevices"
|
v-for="device in pairedDevices"
|
||||||
:key="device.id"
|
:key="device.id"
|
||||||
v-if="!selectedPort"
|
v-if="!selectedPort && showPairedDevices"
|
||||||
clickable
|
clickable
|
||||||
v-close-popup
|
v-close-popup
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ async function serialSigner(path) {
|
||||||
receivedData: '',
|
receivedData: '',
|
||||||
config: {},
|
config: {},
|
||||||
decryptionKey: null,
|
decryptionKey: null,
|
||||||
sharedSecret: null, // todo: store in secure local storage
|
sharedSecret: null,
|
||||||
|
|
||||||
hww: {
|
hww: {
|
||||||
password: null,
|
password: null,
|
||||||
|
|
@ -51,12 +51,14 @@ async function serialSigner(path) {
|
||||||
},
|
},
|
||||||
tx: null, // todo: move to hww
|
tx: null, // todo: move to hww
|
||||||
|
|
||||||
showConsole: false
|
showConsole: false,
|
||||||
|
showPairedDevices: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
pairedDevices: {
|
pairedDevices: {
|
||||||
|
cache: false,
|
||||||
get: function () {
|
get: function () {
|
||||||
return (
|
return (
|
||||||
JSON.parse(window.localStorage.getItem('lnbits-paired-devices')) ||
|
JSON.parse(window.localStorage.getItem('lnbits-paired-devices')) ||
|
||||||
|
|
@ -109,7 +111,10 @@ async function serialSigner(path) {
|
||||||
|
|
||||||
// Wait for the serial port to open.
|
// Wait for the serial port to open.
|
||||||
await this.selectedPort.open(config)
|
await this.selectedPort.open(config)
|
||||||
|
// do not await
|
||||||
this.startSerialPortReading()
|
this.startSerialPortReading()
|
||||||
|
// wait to init
|
||||||
|
sleep(1000)
|
||||||
|
|
||||||
const textEncoder = new TextEncoderStream()
|
const textEncoder = new TextEncoderStream()
|
||||||
this.writableStreamClosed = textEncoder.readable.pipeTo(
|
this.writableStreamClosed = textEncoder.readable.pipeTo(
|
||||||
|
|
@ -225,8 +230,9 @@ async function serialSigner(path) {
|
||||||
while (true) {
|
while (true) {
|
||||||
const {value, done} = await readStringUntil('\n')
|
const {value, done} = await readStringUntil('\n')
|
||||||
if (value) {
|
if (value) {
|
||||||
this.handleSerialPortResponse(value)
|
const {command, commandData} = await this.extractCommand(value)
|
||||||
this.updateSerialPortConsole(value)
|
this.handleSerialPortResponse(command, commandData)
|
||||||
|
this.updateSerialPortConsole(command)
|
||||||
}
|
}
|
||||||
if (done) return
|
if (done) return
|
||||||
}
|
}
|
||||||
|
|
@ -240,8 +246,7 @@ async function serialSigner(path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSerialPortResponse: async function (value) {
|
handleSerialPortResponse: async function (command, commandData) {
|
||||||
const {command, commandData} = await this.extractCommand(value)
|
|
||||||
this.logPublicCommandsResponse(command, commandData)
|
this.logPublicCommandsResponse(command, commandData)
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
|
@ -282,7 +287,7 @@ async function serialSigner(path) {
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
console.log(` %c${value}`, 'background: #222; color: red')
|
console.log(` %c${command}`, 'background: #222; color: red')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logPublicCommandsResponse: function (command, commandData) {
|
logPublicCommandsResponse: function (command, commandData) {
|
||||||
|
|
@ -307,6 +312,8 @@ async function serialSigner(path) {
|
||||||
},
|
},
|
||||||
hwwPing: async function () {
|
hwwPing: async function () {
|
||||||
try {
|
try {
|
||||||
|
// Send an empty ping. The serial port buffer might have some jubk data. Flush it.
|
||||||
|
await this.sendCommandClearText(COMMAND_PING)
|
||||||
await this.sendCommandClearText(COMMAND_PING, [window.location.host])
|
await this.sendCommandClearText(COMMAND_PING, [window.location.host])
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
|
|
@ -582,7 +589,7 @@ async function serialSigner(path) {
|
||||||
hwwCheckPairing: async function () {
|
hwwCheckPairing: async function () {
|
||||||
const iv = window.crypto.getRandomValues(new Uint8Array(16))
|
const iv = window.crypto.getRandomValues(new Uint8Array(16))
|
||||||
const encrypted = await this.encryptMessage(
|
const encrypted = await this.encryptMessage(
|
||||||
this.sharedSecret,
|
this.sharedSecret, // todo: revisit
|
||||||
iv,
|
iv,
|
||||||
PAIRING_CONTROL_TEXT.length + ' ' + PAIRING_CONTROL_TEXT
|
PAIRING_CONTROL_TEXT.length + ' ' + PAIRING_CONTROL_TEXT
|
||||||
)
|
)
|
||||||
|
|
@ -603,10 +610,10 @@ async function serialSigner(path) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleCheckPairingResponse: async function (res = '') {
|
handleCheckPairingResponse: async function (res = '') {
|
||||||
const [statusCode, encryptedMessage] = res.split(' ')
|
const [statusCode, message] = res.split(' ')
|
||||||
switch (statusCode) {
|
switch (statusCode) {
|
||||||
case '0':
|
case '0':
|
||||||
const controlText = await this.decryptData(encryptedMessage)
|
const controlText = await this.decryptData(message)
|
||||||
if (controlText == PAIRING_CONTROL_TEXT) {
|
if (controlText == PAIRING_CONTROL_TEXT) {
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
|
|
@ -622,6 +629,16 @@ async function serialSigner(path) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case '1':
|
||||||
|
this.closeSerialPort()
|
||||||
|
this.$q.notify({
|
||||||
|
type: 'warning',
|
||||||
|
message:
|
||||||
|
'Re-pairing failed. Remove (forget) device and try again!',
|
||||||
|
caption: `Error: ${message}`,
|
||||||
|
timeout: 10000
|
||||||
|
})
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
// noting to do here yet
|
// noting to do here yet
|
||||||
break
|
break
|
||||||
|
|
@ -746,7 +763,7 @@ async function serialSigner(path) {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Failed to ask for help!',
|
message: 'Failed to wipe!',
|
||||||
caption: `${error}`,
|
caption: `${error}`,
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
})
|
})
|
||||||
|
|
@ -862,6 +879,11 @@ async function serialSigner(path) {
|
||||||
sendCommandSecure: async function (command, attrs = []) {
|
sendCommandSecure: async function (command, attrs = []) {
|
||||||
const message = [command].concat(attrs).join(' ')
|
const message = [command].concat(attrs).join(' ')
|
||||||
const iv = window.crypto.getRandomValues(new Uint8Array(16))
|
const iv = window.crypto.getRandomValues(new Uint8Array(16))
|
||||||
|
if (!this.sharedSecret || !this.sharedSecret.length) {
|
||||||
|
throw new Error(
|
||||||
|
`Secure connection not estabileshed. Tried to run command: ${command}`
|
||||||
|
)
|
||||||
|
}
|
||||||
const encrypted = await this.encryptMessage(
|
const encrypted = await this.encryptMessage(
|
||||||
this.sharedSecret,
|
this.sharedSecret,
|
||||||
iv,
|
iv,
|
||||||
|
|
@ -901,6 +923,7 @@ async function serialSigner(path) {
|
||||||
},
|
},
|
||||||
decryptData: async function (value) {
|
decryptData: async function (value) {
|
||||||
if (!this.sharedSecret) {
|
if (!this.sharedSecret) {
|
||||||
|
console.log('/error Secure session not established!')
|
||||||
return '/error Secure session not established!'
|
return '/error Secure session not established!'
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
@ -921,6 +944,7 @@ async function serialSigner(path) {
|
||||||
.trim()
|
.trim()
|
||||||
return command
|
return command
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log('/error Failed to decrypt message from device!')
|
||||||
return '/error Failed to decrypt message from device!'
|
return '/error Failed to decrypt message from device!'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -949,6 +973,11 @@ async function serialSigner(path) {
|
||||||
devices.splice(deviceIndex, 1)
|
devices.splice(deviceIndex, 1)
|
||||||
}
|
}
|
||||||
this.pairedDevices = devices
|
this.pairedDevices = devices
|
||||||
|
this.showPairedDevices = false
|
||||||
|
setTimeout(() => {
|
||||||
|
// force UI refresh
|
||||||
|
this.showPairedDevices = true
|
||||||
|
})
|
||||||
},
|
},
|
||||||
addPairedDevice: function (deviceId, sharedSecretHex, config) {
|
addPairedDevice: function (deviceId, sharedSecretHex, config) {
|
||||||
const devices = this.pairedDevices
|
const devices = this.pairedDevices
|
||||||
|
|
@ -960,6 +989,11 @@ async function serialSigner(path) {
|
||||||
config
|
config
|
||||||
})
|
})
|
||||||
this.pairedDevices = devices
|
this.pairedDevices = devices
|
||||||
|
this.showPairedDevices = false
|
||||||
|
setTimeout(() => {
|
||||||
|
// force UI refresh
|
||||||
|
this.showPairedDevices = true
|
||||||
|
})
|
||||||
},
|
},
|
||||||
updatePairedDeviceConfig(deviceId, config) {
|
updatePairedDeviceConfig(deviceId, config) {
|
||||||
const device = this.getPairedDevice(deviceId)
|
const device = this.getPairedDevice(deviceId)
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,21 @@
|
||||||
>directly from browser</a
|
>directly from browser</a
|
||||||
>
|
>
|
||||||
<small>
|
<small>
|
||||||
<br />Created by,
|
<br />Created by
|
||||||
<a target="_blank" style="color: unset" href="https://github.com/arcbtc"
|
<a target="_blank" style="color: unset" href="https://github.com/arcbtc"
|
||||||
>Ben Arc</a
|
>Ben Arc</a
|
||||||
|
>,
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
style="color: unset"
|
||||||
|
href="https://github.com/talvasconcelos"
|
||||||
|
>Tiago Vasconcelos</a
|
||||||
|
>,
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
style="color: unset"
|
||||||
|
href="https://github.com/motorina0"
|
||||||
|
>motorina0</a
|
||||||
>
|
>
|
||||||
(using,
|
(using,
|
||||||
<a
|
<a
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@
|
||||||
:adminkey="g.user.wallets[0].adminkey"
|
:adminkey="g.user.wallets[0].adminkey"
|
||||||
:serial-signer-ref="$refs.serialSigner"
|
:serial-signer-ref="$refs.serialSigner"
|
||||||
:sats-denominated="config.sats_denominated"
|
:sats-denominated="config.sats_denominated"
|
||||||
|
:network="config.network"
|
||||||
@broadcast-done="handleBroadcastSuccess"
|
@broadcast-done="handleBroadcastSuccess"
|
||||||
></payment>
|
></payment>
|
||||||
<!-- todo: no more utxos.data -->
|
<!-- todo: no more utxos.data -->
|
||||||
|
|
@ -149,7 +150,7 @@
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<h6 class="text-subtitle1 q-my-none">
|
<h6 class="text-subtitle1 q-my-none">
|
||||||
{{SITE_TITLE}} Onchain Wallet (watch-only) Extension
|
{{SITE_TITLE}} Onchain Wallet (watch-only) Extension
|
||||||
<small>(v0.2)</small>
|
<small>(v0.3)</small>
|
||||||
</h6>
|
</h6>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="q-pa-none">
|
<q-card-section class="q-pa-none">
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from http import HTTPStatus
|
||||||
import httpx
|
import httpx
|
||||||
from embit import finalizer, script
|
from embit import finalizer, script
|
||||||
from embit.ec import PublicKey
|
from embit.ec import PublicKey
|
||||||
|
from embit.networks import NETWORKS
|
||||||
from embit.psbt import PSBT, DerivationPath
|
from embit.psbt import PSBT, DerivationPath
|
||||||
from embit.transaction import Transaction, TransactionInput, TransactionOutput
|
from embit.transaction import Transaction, TransactionInput, TransactionOutput
|
||||||
from fastapi import Query, Request
|
from fastapi import Query, Request
|
||||||
|
|
@ -295,6 +296,7 @@ async def api_psbt_create(
|
||||||
async def api_psbt_extract_tx(
|
async def api_psbt_extract_tx(
|
||||||
data: ExtractPsbt, w: WalletTypeInfo = Depends(require_admin_key)
|
data: ExtractPsbt, w: WalletTypeInfo = Depends(require_admin_key)
|
||||||
):
|
):
|
||||||
|
network = NETWORKS["main"] if data.network == "Mainnet" else NETWORKS["test"]
|
||||||
res = SignedTransaction()
|
res = SignedTransaction()
|
||||||
try:
|
try:
|
||||||
psbt = PSBT.from_base64(data.psbtBase64)
|
psbt = PSBT.from_base64(data.psbtBase64)
|
||||||
|
|
@ -316,7 +318,7 @@ async def api_psbt_extract_tx(
|
||||||
|
|
||||||
for out in transaction.vout:
|
for out in transaction.vout:
|
||||||
tx["outputs"].append(
|
tx["outputs"].append(
|
||||||
{"amount": out.value, "address": out.script_pubkey.address()}
|
{"amount": out.value, "address": out.script_pubkey.address(network)}
|
||||||
)
|
)
|
||||||
res.tx_json = json.dumps(tx)
|
res.tx_json = json.dumps(tx)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
36
poetry.lock
generated
36
poetry.lock
generated
|
|
@ -118,6 +118,9 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7"
|
python-versions = ">=2.7"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
setuptools = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "certifi"
|
name = "certifi"
|
||||||
version = "2021.5.30"
|
version = "2021.5.30"
|
||||||
|
|
@ -206,7 +209,7 @@ python-versions = ">=3.6"
|
||||||
cffi = ">=1.12"
|
cffi = ">=1.12"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
|
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx_rtd_theme"]
|
||||||
docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
|
docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
|
||||||
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
||||||
sdist = ["setuptools_rust (>=0.11.4)"]
|
sdist = ["setuptools_rust (>=0.11.4)"]
|
||||||
|
|
@ -638,7 +641,7 @@ python-versions = ">=3.7,<4.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyln-client"
|
name = "pyln-client"
|
||||||
version = "0.12.0.post1"
|
version = "0.11.1"
|
||||||
description = "Client library and plugin library for Core Lightning"
|
description = "Client library and plugin library for Core Lightning"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
|
|
@ -707,7 +710,7 @@ pathlib2 = "*"
|
||||||
six = "*"
|
six = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pysocks"
|
name = "PySocks"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information."
|
description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information."
|
||||||
category = "main"
|
category = "main"
|
||||||
|
|
@ -823,6 +826,19 @@ python-versions = "*"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
cffi = ">=1.3.0"
|
cffi = ">=1.3.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "setuptools"
|
||||||
|
version = "65.4.0"
|
||||||
|
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||||
|
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
|
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shortuuid"
|
name = "shortuuid"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
@ -860,7 +876,7 @@ mssql = ["pyodbc"]
|
||||||
mssql_pymssql = ["pymssql"]
|
mssql_pymssql = ["pymssql"]
|
||||||
mssql_pyodbc = ["pyodbc"]
|
mssql_pyodbc = ["pyodbc"]
|
||||||
mysql = ["mysqlclient"]
|
mysql = ["mysqlclient"]
|
||||||
oracle = ["cx-oracle"]
|
oracle = ["cx_oracle"]
|
||||||
postgresql = ["psycopg2"]
|
postgresql = ["psycopg2"]
|
||||||
postgresql_pg8000 = ["pg8000 (<1.16.6)"]
|
postgresql_pg8000 = ["pg8000 (<1.16.6)"]
|
||||||
postgresql_psycopg2binary = ["psycopg2-binary"]
|
postgresql_psycopg2binary = ["psycopg2-binary"]
|
||||||
|
|
@ -1024,7 +1040,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black (
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.10 | ^3.9 | ^3.8 | ^3.7"
|
python-versions = "^3.10 | ^3.9 | ^3.8 | ^3.7"
|
||||||
content-hash = "d0556d4a307864ba04a1e5da517884e523396c98a00ae09d9192c37b1d2c555b"
|
content-hash = "72e4462285d0bc5e2cb83c88c613726beced959b268bd30b984d8baaeff178ea"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiofiles = [
|
aiofiles = [
|
||||||
|
|
@ -1661,8 +1677,8 @@ pyln-bolt7 = [
|
||||||
{file = "pyln_bolt7-1.0.246-py3-none-any.whl", hash = "sha256:54d48ec27fdc8751762cb068b0a9f2757a58fb57933c6d8f8255d02c27eb63c5"},
|
{file = "pyln_bolt7-1.0.246-py3-none-any.whl", hash = "sha256:54d48ec27fdc8751762cb068b0a9f2757a58fb57933c6d8f8255d02c27eb63c5"},
|
||||||
]
|
]
|
||||||
pyln-client = [
|
pyln-client = [
|
||||||
{file = "pyln-client-0.12.0.post1.tar.gz", hash = "sha256:c80338e8e9f435720c0e5f552dc4016fc8fba16d4b79764f881067e0fcd5d5c7"},
|
{file = "pyln-client-0.11.1.tar.gz", hash = "sha256:f5ea648840b030e2bbcf8c66ee72d25a5817f89854434a28d30e887547138c8e"},
|
||||||
{file = "pyln_client-0.12.0.post1-py3-none-any.whl", hash = "sha256:cfe3404eb88f294015145e668d774dd754b3baec36b44fe773fa354f1e1e48c1"},
|
{file = "pyln_client-0.11.1-py3-none-any.whl", hash = "sha256:497db443406b80c98c0434e2938eb1b2a17e88fd9aa63b018124068198df6141"},
|
||||||
]
|
]
|
||||||
pyln-proto = [
|
pyln-proto = [
|
||||||
{file = "pyln-proto-0.11.1.tar.gz", hash = "sha256:9bed240f41917c4fd526b767218a77d0fbe69242876eef72c35a856796f922d6"},
|
{file = "pyln-proto-0.11.1.tar.gz", hash = "sha256:9bed240f41917c4fd526b767218a77d0fbe69242876eef72c35a856796f922d6"},
|
||||||
|
|
@ -1682,7 +1698,7 @@ pyqrcode = [
|
||||||
pyscss = [
|
pyscss = [
|
||||||
{file = "pyScss-1.4.0.tar.gz", hash = "sha256:8f35521ffe36afa8b34c7d6f3195088a7057c185c2b8f15ee459ab19748669ff"},
|
{file = "pyScss-1.4.0.tar.gz", hash = "sha256:8f35521ffe36afa8b34c7d6f3195088a7057c185c2b8f15ee459ab19748669ff"},
|
||||||
]
|
]
|
||||||
pysocks = [
|
PySocks = [
|
||||||
{file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"},
|
{file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"},
|
||||||
{file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"},
|
{file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"},
|
||||||
{file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"},
|
{file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"},
|
||||||
|
|
@ -1767,6 +1783,10 @@ secp256k1 = [
|
||||||
{file = "secp256k1-0.14.0-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c9e7c024ff17e9b9d7c392bb2a917da231d6cb40ab119389ff1f51dca10339a4"},
|
{file = "secp256k1-0.14.0-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c9e7c024ff17e9b9d7c392bb2a917da231d6cb40ab119389ff1f51dca10339a4"},
|
||||||
{file = "secp256k1-0.14.0.tar.gz", hash = "sha256:82c06712d69ef945220c8b53c1a0d424c2ff6a1f64aee609030df79ad8383397"},
|
{file = "secp256k1-0.14.0.tar.gz", hash = "sha256:82c06712d69ef945220c8b53c1a0d424c2ff6a1f64aee609030df79ad8383397"},
|
||||||
]
|
]
|
||||||
|
setuptools = [
|
||||||
|
{file = "setuptools-65.4.0-py3-none-any.whl", hash = "sha256:c2d2709550f15aab6c9110196ea312f468f41cd546bceb24127a1be6fdcaeeb1"},
|
||||||
|
{file = "setuptools-65.4.0.tar.gz", hash = "sha256:a8f6e213b4b0661f590ccf40de95d28a177cd747d098624ad3f69c40287297e9"},
|
||||||
|
]
|
||||||
shortuuid = [
|
shortuuid = [
|
||||||
{file = "shortuuid-1.0.1-py3-none-any.whl", hash = "sha256:492c7402ff91beb1342a5898bd61ea953985bf24a41cd9f247409aa2e03c8f77"},
|
{file = "shortuuid-1.0.1-py3-none-any.whl", hash = "sha256:492c7402ff91beb1342a5898bd61ea953985bf24a41cd9f247409aa2e03c8f77"},
|
||||||
{file = "shortuuid-1.0.1.tar.gz", hash = "sha256:3c11d2007b915c43bee3e10625f068d8a349e04f0d81f08f5fa08507427ebf1f"},
|
{file = "shortuuid-1.0.1.tar.gz", hash = "sha256:3c11d2007b915c43bee3e10625f068d8a349e04f0d81f08f5fa08507427ebf1f"},
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ cffi = "1.15.0"
|
||||||
websocket-client = "1.3.3"
|
websocket-client = "1.3.3"
|
||||||
grpcio = "^1.49.1"
|
grpcio = "^1.49.1"
|
||||||
protobuf = "^4.21.6"
|
protobuf = "^4.21.6"
|
||||||
pyln-client = "^0.12.0"
|
pyln-client = "0.11.1"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
isort = "^5.10.1"
|
isort = "^5.10.1"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue