mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2024-11-19 18:11:30 +01:00
Merge pull request #1010 from motorina0/fix_usb_coonect
Fix USB connect
This commit is contained in:
commit
8fbaee37fb
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user