Merge pull request #1010 from motorina0/fix_usb_coonect

Fix USB connect
This commit is contained in:
Arc 2022-09-28 16:24:53 +01:00 committed by GitHub
commit 8fbaee37fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 70 additions and 18 deletions

View File

@ -80,6 +80,7 @@ class CreatePsbt(BaseModel):
class ExtractPsbt(BaseModel):
psbtBase64 = "" # // todo snake case
inputs: List[TransactionInput]
network = "Mainnet"
class SignedTransaction(BaseModel):

View File

@ -5,7 +5,7 @@
<send-to
:data.sync="sendToList"
:fee-rate="feeRate"
:tx-size="txSizeNoChange"
:tx-size="txSize"
:selected-amount="selectedAmount"
:sats-denominated="satsDenominated"
@update:outputs="handleOutputsChange"

View File

@ -11,7 +11,8 @@ async function payment(path) {
'mempool-endpoint',
'sats-denominated',
'serial-signer-ref',
'adminkey'
'adminkey',
'network'
],
watch: {
immediate: true,
@ -279,7 +280,8 @@ async function payment(path) {
this.adminkey,
{
psbtBase64,
inputs: this.tx.inputs
inputs: this.tx.inputs,
network: this.network
}
)
return data

View File

@ -49,7 +49,7 @@
<q-item
v-for="device in pairedDevices"
:key="device.id"
v-if="!selectedPort"
v-if="!selectedPort && showPairedDevices"
clickable
v-close-popup
>

View File

@ -15,7 +15,7 @@ async function serialSigner(path) {
receivedData: '',
config: {},
decryptionKey: null,
sharedSecret: null, // todo: store in secure local storage
sharedSecret: null,
hww: {
password: null,
@ -51,12 +51,14 @@ async function serialSigner(path) {
},
tx: null, // todo: move to hww
showConsole: false
showConsole: false,
showPairedDevices: true
}
},
computed: {
pairedDevices: {
cache: false,
get: function () {
return (
JSON.parse(window.localStorage.getItem('lnbits-paired-devices')) ||
@ -109,7 +111,10 @@ async function serialSigner(path) {
// Wait for the serial port to open.
await this.selectedPort.open(config)
// do not await
this.startSerialPortReading()
// wait to init
sleep(1000)
const textEncoder = new TextEncoderStream()
this.writableStreamClosed = textEncoder.readable.pipeTo(
@ -225,8 +230,9 @@ async function serialSigner(path) {
while (true) {
const {value, done} = await readStringUntil('\n')
if (value) {
this.handleSerialPortResponse(value)
this.updateSerialPortConsole(value)
const {command, commandData} = await this.extractCommand(value)
this.handleSerialPortResponse(command, commandData)
this.updateSerialPortConsole(command)
}
if (done) return
}
@ -240,8 +246,7 @@ async function serialSigner(path) {
}
}
},
handleSerialPortResponse: async function (value) {
const {command, commandData} = await this.extractCommand(value)
handleSerialPortResponse: async function (command, commandData) {
this.logPublicCommandsResponse(command, commandData)
switch (command) {
@ -282,7 +287,7 @@ async function serialSigner(path) {
)
break
default:
console.log(` %c${value}`, 'background: #222; color: red')
console.log(` %c${command}`, 'background: #222; color: red')
}
},
logPublicCommandsResponse: function (command, commandData) {
@ -307,6 +312,8 @@ async function serialSigner(path) {
},
hwwPing: async function () {
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])
} catch (error) {
this.$q.notify({
@ -582,7 +589,7 @@ async function serialSigner(path) {
hwwCheckPairing: async function () {
const iv = window.crypto.getRandomValues(new Uint8Array(16))
const encrypted = await this.encryptMessage(
this.sharedSecret,
this.sharedSecret, // todo: revisit
iv,
PAIRING_CONTROL_TEXT.length + ' ' + PAIRING_CONTROL_TEXT
)
@ -603,10 +610,10 @@ async function serialSigner(path) {
}
},
handleCheckPairingResponse: async function (res = '') {
const [statusCode, encryptedMessage] = res.split(' ')
const [statusCode, message] = res.split(' ')
switch (statusCode) {
case '0':
const controlText = await this.decryptData(encryptedMessage)
const controlText = await this.decryptData(message)
if (controlText == PAIRING_CONTROL_TEXT) {
this.$q.notify({
type: 'positive',
@ -622,6 +629,16 @@ async function serialSigner(path) {
})
}
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:
// noting to do here yet
break
@ -746,7 +763,7 @@ async function serialSigner(path) {
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to ask for help!',
message: 'Failed to wipe!',
caption: `${error}`,
timeout: 10000
})
@ -862,6 +879,11 @@ async function serialSigner(path) {
sendCommandSecure: async function (command, attrs = []) {
const message = [command].concat(attrs).join(' ')
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(
this.sharedSecret,
iv,
@ -901,6 +923,7 @@ async function serialSigner(path) {
},
decryptData: async function (value) {
if (!this.sharedSecret) {
console.log('/error Secure session not established!')
return '/error Secure session not established!'
}
try {
@ -921,6 +944,7 @@ async function serialSigner(path) {
.trim()
return command
} catch (error) {
console.log('/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)
}
this.pairedDevices = devices
this.showPairedDevices = false
setTimeout(() => {
// force UI refresh
this.showPairedDevices = true
})
},
addPairedDevice: function (deviceId, sharedSecretHex, config) {
const devices = this.pairedDevices
@ -960,6 +989,11 @@ async function serialSigner(path) {
config
})
this.pairedDevices = devices
this.showPairedDevices = false
setTimeout(() => {
// force UI refresh
this.showPairedDevices = true
})
},
updatePairedDeviceConfig(deviceId, config) {
const device = this.getPairedDevice(deviceId)

View File

@ -18,9 +18,21 @@
>directly from browser</a
>
<small>
<br />Created by,
<br />Created by
<a target="_blank" style="color: unset" href="https://github.com/arcbtc"
>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,
<a

View File

@ -136,6 +136,7 @@
:adminkey="g.user.wallets[0].adminkey"
:serial-signer-ref="$refs.serialSigner"
:sats-denominated="config.sats_denominated"
:network="config.network"
@broadcast-done="handleBroadcastSuccess"
></payment>
<!-- todo: no more utxos.data -->
@ -149,7 +150,7 @@
<q-card-section>
<h6 class="text-subtitle1 q-my-none">
{{SITE_TITLE}} Onchain Wallet (watch-only) Extension
<small>(v0.2)</small>
<small>(v0.3)</small>
</h6>
</q-card-section>
<q-card-section class="q-pa-none">

View File

@ -4,6 +4,7 @@ from http import HTTPStatus
import httpx
from embit import finalizer, script
from embit.ec import PublicKey
from embit.networks import NETWORKS
from embit.psbt import PSBT, DerivationPath
from embit.transaction import Transaction, TransactionInput, TransactionOutput
from fastapi import Query, Request
@ -295,6 +296,7 @@ async def api_psbt_create(
async def api_psbt_extract_tx(
data: ExtractPsbt, w: WalletTypeInfo = Depends(require_admin_key)
):
network = NETWORKS["main"] if data.network == "Mainnet" else NETWORKS["test"]
res = SignedTransaction()
try:
psbt = PSBT.from_base64(data.psbtBase64)
@ -316,7 +318,7 @@ async def api_psbt_extract_tx(
for out in transaction.vout:
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)
except Exception as e: