Skip to content

Commit

Permalink
Adding all necessary for UR code offline signing in both directions
Browse files Browse the repository at this point in the history
	and needs to get enabled with `WITH_OTS_UR` to compile with UR.

	This update depends on [monero
	PR](monero-project/monero#9492).
	It cannot work without modifications on monero core!

	@tobtoht also mentions that build with static Qt5 will not
	work. I compiled and tested exclusively with ubuntu 24.04
	in Qt Creator with Qt 5.15.2
  • Loading branch information
DiosDelRayo committed Sep 27, 2024
1 parent 08e2eaf commit b515b6b
Show file tree
Hide file tree
Showing 97 changed files with 13,408 additions and 42 deletions.
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ option(STATIC "Link libraries statically, requires static Qt")

option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
option(WITH_SCANNER "Enable webcam QR scanner" OFF)
option(WITH_OTS_UR "Enable offline transaction signing via UR" OFF)
option(WITH_DESKTOP_ENTRY "Ask to install desktop entry on first startup" ON)
option(WITH_UPDATER "Regularly check for new updates" ON)
option(DEV_MODE "Checkout latest monero master on build" OFF)
Expand Down Expand Up @@ -80,9 +81,12 @@ include(VersionGui)

message(STATUS "${CMAKE_MODULE_PATH}")

if(WITH_SCANNER)
if(WITH_SCANNER AND NOT WITH_OTS_UR)
add_definitions(-DWITH_SCANNER)
endif()
if(WITH_OTS_UR)
add_definitions(-DWITH_OTS_UR)
endif()

if(WITH_DESKTOP_ENTRY)
add_definitions(-DWITH_DESKTOP_ENTRY)
Expand Down Expand Up @@ -122,7 +126,7 @@ set(QT5_LIBRARIES
Qt5Xml
)

if(WITH_SCANNER)
if(WITH_SCANNER OR OTS_UR_WITH_QTQUICK)
list(APPEND QT5_LIBRARIES Qt5Multimedia)
endif()

Expand Down Expand Up @@ -241,7 +245,7 @@ if(STATIC)
modelsplugin
)

if(WITH_SCANNER)
if(WITH_SCANNER OR OTS_UR_WITH_QTQUICK)
list(APPEND QT5_EXTRA_LIBRARIES_LIST
declarative_multimedia
Qt5MultimediaQuick
Expand Down
16 changes: 14 additions & 2 deletions components/QRCodeScanner.qml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import QtQuick 2.9
import QtMultimedia 5.4
import QtQuick.Dialogs 1.2
import "../components" as MoneroComponents
import moneroComponents.QRCodeScanner 1.0

Rectangle {
Expand All @@ -51,7 +52,7 @@ Rectangle {
name: "Capture"
StateChangeScript {
script: {
root.visible = true
root.visible = true
camera.captureMode = Camera.CaptureStillImage
camera.cameraState = Camera.ActiveState
camera.start()
Expand All @@ -64,7 +65,7 @@ Rectangle {
StateChangeScript {
script: {
camera.stop()
root.visible = false
root.visible = false
finder.enabled = false
camera.cameraState = Camera.UnloadedState
}
Expand Down Expand Up @@ -135,6 +136,17 @@ Rectangle {
}
}

MoneroComponents.StandardButton {
id: btnClose
text: qsTr("Cancel")
z: viewfinder.z + 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.topMargin: 20
onClicked: root.state = "Stopped"
}

MessageDialog {
id: messageDialog
title: qsTr("QrCode Scanned") + translationManager.emptyString
Expand Down
4 changes: 3 additions & 1 deletion components/TxConfirmationDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,12 @@ Rectangle {
fontFamily: "Arial"
horizontalAlignment: Text.AlignHCenter
text: {
if (appWindow.viewOnly) {
if (appWindow.viewOnly && !persistentSettings.useURCode) {
return qsTr("Create transaction file") + translationManager.emptyString;
} else if (root.sweepUnmixable) {
return qsTr("Sweep unmixable outputs") + translationManager.emptyString;
} else if (appWindow.viewOnly && persistentSettings.useURCode) { // intentionally behind sweepUnmixable
return qsTr("Create transaction") + translationManager.emptyString;
} else {
return qsTr("Confirm send") + translationManager.emptyString;
}
Expand Down
165 changes: 165 additions & 0 deletions components/UrCode.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import QtQuick 2.9
import QtMultimedia 5.4
import OtsUr 0.1
import "." as MoneroComponents

Rectangle {
id : root

x: 0
y: 0
z: parent.z+1
width: parent.width
height: parent.height

property bool active: false
property bool ur: true

visible: root.active
focus: root.active
color: "black"

Image {
id: qrCodeImage
cache: false
width: qrCodeImage.height
height: Math.max(300, Math.min(parent.height - frameInfo.height - displayType.height - 240, parent.width - 40))
anchors.centerIn: parent
function reload() {
var tmp = qrCodeImage.source
qrCodeImage.source = ""
qrCodeImage.source = tmp
}
}

Rectangle {
id: frameInfo
visible: textFrameInfo.visible
height: textFrameInfo.height + 5
width: textFrameInfo.width + 20
z: parent.z + 1
radius: 16
color: "#FA6800"
anchors.centerIn: textFrameInfo
opacity: 0.4
}

Text {
id: textFrameInfo
z: frameInfo.z + 1
visible: textFrameInfo.text !== ""
text: urSender.currentFrameInfo
anchors.top: parent.top
anchors.horizontalCenter: qrCodeImage.horizontalCenter
anchors.margins: 30
font.pixelSize: 22
color: "white"
opacity: 0.7
}

Rectangle {
id: displayType
visible: textDisplayType.text !== ""
height: textDisplayType.height + 5
width: textDisplayType.width + 20
z: parent.z + 1
radius: 16
color: "#FA6800"
anchors.centerIn: textDisplayType
opacity: 0.4
}

Text {
id: textDisplayType
visible: displayType.visible
z: displayType.z + 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: btnClose.top
anchors.margins: 30
text: ""
font.pixelSize: 22
color: "white"
opacity: 0.7
}

MoneroComponents.StandardButton {
id: btnClose
text: qsTr("Close")
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.topMargin: 20
focus: true
onClicked: root.close()
}

Connections {
target: urSender
function onUpdateQrCode() {
qrCodeImage.reload()
}
}

MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onDoubleClicked: {
root.close()
}
}

function showQr(text) {
urSender.sendQrCode(text)
root.ur = false
root.active = true
}

function showWalletData(address, spendKey, viewKey, mnemonic, height) {
textDisplayType.text = qsTr("Wallet")
urSender.sendWallet(address, spendKey, viewKey, mnemonic, height)
root.ur = false
root.active = true
}

function showTxData(address, amount, paymentId, recipient, description) {
textDisplayType.text = qsTr("TX Data")
urSender.sendTx(address, amount, paymentId, recipient, description)
root.ur = false
root.active = true
}

function showOutputs(outputs) {
textDisplayType.text = qsTr("Outputs")
urSender.sendOutputs(outputs)
root.active = true
}

function showKeyImages(keyImages) {
textDisplayType.text = qsTr("Key Images")
urSender.sendKeyImages(keyImages)
root.active = true
}

function showUnsignedTx(tx) {
textDisplayType.text = qsTr("Unsigned TX")
urSender.sendTxUnsigned(tx)
root.active = true
}

function showSignedTx(tx) {
textDisplayType.text = qsTr("Signed TX")
urSender.sendTxSigned(tx)
root.active = true
}

function close() {
textDisplayType.text = ""
urSender.sendClear()
root.ur = true
root.active = false
}

Component.onCompleted: {
qrCodeImage.source = "image://urcode/qr"
}
}
Loading

0 comments on commit b515b6b

Please sign in to comment.