Skip to content
This repository has been archived by the owner on Sep 6, 2024. It is now read-only.

Commit

Permalink
[+] add send transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
heng30 committed Dec 30, 2023
1 parent 61b89dc commit e99d2c0
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

build-evn=SLINT_STYLE=fluent
run-evn=RUST_LOG=error,warn,info,debug
run-evn=RUST_LOG=error,warn,info,sqlx=off,reqwest=off

all:
$(build-evn) cargo build --release
Expand Down
1 change: 1 addition & 0 deletions bitbox/src/db/activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub async fn insert(uuid: &str, network: &str, data: &str) -> Result<()> {
Ok(())
}

#[allow(dead_code)]
pub async fn select_all() -> Result<Vec<Activity>> {
Ok(sqlx::query_as::<_, Activity>("SELECT * FROM activity")
.fetch_all(&pool())
Expand Down
1 change: 1 addition & 0 deletions bitbox/src/db/address_book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub async fn insert(uuid: &str, network: &str, data: &str) -> Result<()> {
Ok(())
}

#[allow(dead_code)]
pub async fn select_all() -> Result<Vec<AddressBook>> {
Ok(
sqlx::query_as::<_, AddressBook>("SELECT * FROM address_book")
Expand Down
1 change: 1 addition & 0 deletions bitbox/src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub async fn is_table_exist(table_name: &str) -> Result<()> {
Ok(())
}

#[allow(dead_code)]
pub async fn drop_table(table_name: &str) -> Result<()> {
sqlx::query(&format!("DROP TABLE {}", table_name))
.execute(&pool())
Expand Down
80 changes: 72 additions & 8 deletions bitbox/src/logic/send_tx.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use crate::config;
use crate::db;
use crate::message::{async_message_success, async_message_warn};
use crate::password_dialog::is_password_verify;
use crate::slint_generatedAppWindow::{AddressBookItem, AppWindow, Logic, Store};
use crate::slint_generatedAppWindow::{AppWindow, Logic, Store, TxDetail};
use crate::util::translator::tr;
use crate::wallet::{
account::{address, sendinfo, tx},
transaction::blockstream,
};
use crate::{message_success, message_warn};
use crate::{config, db, message_warn};
use serde_json::Value;
use slint::{ComponentHandle, Weak};
use slint::ComponentHandle;
use tokio::task::spawn;
use uuid::Uuid;

Check warning on line 13 in bitbox/src/logic/send_tx.rs

View workflow job for this annotation

GitHub Actions / action-run

unused import: `uuid::Uuid`

Expand All @@ -30,6 +28,13 @@ pub fn init(ui: &AppWindow) {
return;
}

let btc_price: f64 = ui
.global::<Store>()
.get_btc_info()
.price
.parse()
.unwrap_or(0_f64);

let ui = ui.as_weak();
spawn(async move {
if !is_password_verify(uuid.clone(), password.clone()).await {
Expand Down Expand Up @@ -68,14 +73,49 @@ pub fn init(ui: &AppWindow) {
)
.unwrap();

let mut tx_detail = TxDetail {
show: true,
network: address_info.network.clone().into(),
receive_address: receive_address.clone().into(),
send_amount_usd: slint::format!(
"{:.2}",
btc_price * send_amount.parse::<f64>().unwrap_or(0_f64)
),
send_amount_btc: send_amount.into(),
send_address: if address_info.network == "main" {
address_info.address.0.clone().into()
} else {
address_info.address.1.clone().into()
},
..Default::default()
};

match tx::build(&password, address_info, send_info).await {
Err(e) => async_message_warn(
ui.clone(),
format!("{}. {}: {e:?}", tr("生成交易失败"), tr("原因")),
),
Ok(tx_detail) => {
log::debug!("{tx_detail:?}");
// TODO
Ok(detail) => {
tx_detail.fee_amount_usd = slint::format!(
"{:.2}",
detail.fee_amount as f64 * btc_price / 1e8
);

tx_detail.fee_amount_btc =
slint::format!("{}", detail.fee_amount as f64 / 1e8);

tx_detail.detail_raw = tx::parse_tx(&detail.tx_hex)
.unwrap_or(String::default())
.into();

tx_detail.detail_hex = detail.tx_hex.into();

let _ = slint::invoke_from_event_loop(move || {
ui.clone()
.unwrap()
.global::<Store>()
.set_tx_detail_dialog(tx_detail);
});
}
}
}
Expand All @@ -88,4 +128,28 @@ pub fn init(ui: &AppWindow) {
});
},
);

let ui_handle = ui.as_weak();
ui.global::<Logic>()
.on_broadcast_tx(move |network, tx_hex| {
let ui = ui_handle.clone();
let network = network.to_string();
let tx_hex = tx_hex.to_string();

spawn(async move {
match blockstream::broadcast_transaction(&network, tx_hex).await {
Err(e) => async_message_warn(
ui.clone(),
format!("{}. {}: {e:?}", tr("发送交易失败"), tr("原因")),
),
Ok(txid) => {
// TODO
async_message_success(
ui.clone(),
format!("{}. txid: {txid}", tr("发送交易成功")),
);
}
}
});
});
}
1 change: 1 addition & 0 deletions bitbox/src/util/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub fn hash(text: &str) -> String {
)
}

#[allow(dead_code)]
pub fn random_string(length: usize) -> String {
let mut rng = rand::thread_rng();
let chars: Vec<char> = ('a'..'z').collect();
Expand Down
1 change: 1 addition & 0 deletions bitbox/src/util/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::Result;
use std::path::PathBuf;
use std::{env, fs, io};

#[allow(dead_code)]
pub fn working_dir() -> Result<PathBuf> {
let mut dir = env::current_exe()?;
dir.pop();
Expand Down
4 changes: 3 additions & 1 deletion bitbox/src/util/translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ pub fn tr(text: &str) -> String {
items.insert("恢复账户失败", "Recover account failed");
items.insert("切换网络成功", "Switch network success");
items.insert("非法输入", "Invalid input");
items.insert("生成交易失败", "Generate translation failed");
items.insert("生成交易失败", "Generate transaction failed");
items.insert("发送交易成功", "Send transaction success");
items.insert("发送交易失败", "Send transaction failed");
items.insert("刷新...", "Flush...");
items.insert("在线", "Online");
items.insert("正忙", "Busy");
Expand Down
10 changes: 8 additions & 2 deletions bitbox/ui/appwindow.slint
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BaseLogic } from "./base/logic.slint";
import { Store } from "./store.slint";
import { AddressBookItem } from "./store.slint";
import { ActivityItem } from "./store.slint";
import { TxDetail } from "./store.slint";
import { Account } from "./store.slint";
import { Util } from "./util.slint";
import { Translator } from "./translator.slint";
Expand All @@ -13,6 +14,7 @@ import { Blanket } from "./base/blanket.slint";
import { Panel } from "./panel/panel.slint";
import { Message } from "./base/message.slint";
import { SettingDialog } from "./dialog/setting/dialog.slint";
import { TxDetailDialog } from "./dialog/tx-detail.slint";
import { PasswordDialog } from "./dialog/password.slint";
import { ChangePasswordDialog } from "./dialog/change-password.slint";
import { AddressBookAddItemDialog } from "./dialog/address-book-add-item.slint";
Expand Down Expand Up @@ -87,7 +89,7 @@ export component AppWindow inherits Window {
}
}

if address-book-add-item-dialog.visible || address-book-qrcode-dialog.visible || address-book-dialog.visible || setting-dialog.visible || oc-dialog.visible || about-dialog.visible || help-dialog.visible || password-dialog.visible || new-account-dialog.visible || show-mnemonic-dialog.visible || change-password-dialog.visible : low-modal := Blanket { }
if address-book-add-item-dialog.visible || address-book-qrcode-dialog.visible || address-book-dialog.visible || setting-dialog.visible || oc-dialog.visible || about-dialog.visible || help-dialog.visible || password-dialog.visible || new-account-dialog.visible || show-mnemonic-dialog.visible || tx-detail-dialog.visible || change-password-dialog.visible : low-modal := Blanket { }

address-book-add-item-dialog := AddressBookAddItemDialog {
width: root.dialog-max-width;
Expand All @@ -113,6 +115,10 @@ export component AppWindow inherits Window {
width: root.dialog-max-width;
}

tx-detail-dialog := TxDetailDialog {
width: root.dialog-max-width;
}

setting-dialog := SettingDialog {
width: root.dialog-max-width;
}
Expand Down Expand Up @@ -140,4 +146,4 @@ export component AppWindow inherits Window {
}
}

export { Util, Logic, BaseLogic, Store, Account, ActivityItem, AddressBookItem }
export { Util, Logic, BaseLogic, Store, Account, ActivityItem, AddressBookItem, TxDetail }
107 changes: 107 additions & 0 deletions bitbox/ui/dialog/tx-detail.slint
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { ComboBox, TextEdit, LineEdit } from "std-widgets.slint";
import { Theme } from "../theme.slint";
import { Store } from "../store.slint";
import { Logic } from "../logic.slint";
import { IconBtn } from "../base/icon-btn.slint";
import { CenterLayout } from "../base/center-layout.slint";
import { Label } from "../base/label.slint";
import { CDialog } from "../base/cdialog.slint";

export component TxDetailDialog inherits CDialog {
visible: Store.tx-detail-dialog.show;
title: Store.translator.tx-detail-dialog-title;

property<length> label-width: Theme.default-label-width;

VerticalLayout {
alignment: start;
padding: Theme.padding * 4;
spacing: Theme.spacing * 4;

HorizontalLayout {
spacing: Theme.spacing;
Label {
width: label-width;
text: Store.translator.tx-detail-dialog-network + ":";
}
Label {
text: Store.tx-detail-dialog.network == "main" ? Store.translator.tip-main-network : Store.translator.tip-test-network;
}
}

HorizontalLayout {
spacing: Theme.spacing;
Label {
width: label-width;
text: Store.translator.tx-detail-dialog-send-address + ":";
}
Label {
text: Store.tx-detail-dialog.send-address;
}
}

HorizontalLayout {
spacing: Theme.spacing;
Label {
width: label-width;
text: Store.translator.tx-detail-dialog-receive-address + ":";
}
Label {
text: Store.tx-detail-dialog.receive-address;
}
}

HorizontalLayout {
spacing: Theme.spacing;
Label {
width: label-width;
text: Store.translator.tx-detail-dialog-send-amount + ":";
}
Label {
text: Store.tx-detail-dialog.send-amount-btc + " BTC" + " / " + Store.tx-detail-dialog.send-amount-usd + " USD";
}
}

HorizontalLayout {
spacing: Theme.spacing;
Label {
width: label-width;
text: Store.translator.tx-detail-dialog-fee-amount + ":";
}
Label {
text: Store.tx-detail-dialog.fee-amount-btc + " BTC" + " / " + Store.tx-detail-dialog.fee-amount-usd + " USD";
}
}

VerticalLayout {
spacing: Theme.spacing;
detail-combox := ComboBox {
model: [Store.translator.tx-detail-dialog-tx-hex, Store.translator.tx-detail-dialog-tx-raw];
current-value: self.model[0];
current-index: 0;
}

if detail-combox.current-index == 0 : TextEdit {
height: 150px;
read-only: true;
text: Store.tx-detail-dialog.detail-hex;
}

if detail-combox.current-index == 1 : TextEdit {
height: 150px;
read-only: true;
text: Store.tx-detail-dialog.detail-raw;
}
}
}

ok-clicked => {
Logic.broadcast-tx(Store.tx-detail-dialog.network, Store.tx-detail-dialog.detail_hex);
Store.tx-detail-dialog.show = false;
}

cancel-clicked => {
Store.tx-detail-dialog.show = false;
}
}

1 change: 1 addition & 0 deletions bitbox/ui/logic.slint
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export global Logic {
callback switch-network(string, string); // argument: uuid, network

callback send-tx(string, string, string, string, string); // argument: uuid, password, receive-address, amount, feerate
callback broadcast-tx(string, string); // argument: network, tx-hex

callback set-receive-address(string); // argument: address
callback address-book-add-item(string, string, string); // argument: name, address, network
Expand Down
25 changes: 21 additions & 4 deletions bitbox/ui/store.slint
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ export struct ActivityItem {
status: string,
}

export struct TxDetail {
show: bool,
network: string,
send-address: string,
receive-address: string,
send-amount-btc: string,
send-amount-usd: string,
fee-amount-btc: string,
fee-amount-usd: string,
detail-hex: string,
detail-raw: string,
}

export struct AddressBookItem {
uuid: string,
name: string,
Expand Down Expand Up @@ -97,6 +110,10 @@ export global Store {
in-out property<bool> is-show-new-account-dialog: false;
in-out property<string> account-mnemonic;

in-out property<TxDetail> tx-detail-dialog: {
show: false,
};

in-out property<bool> is-show-address-book-add-item-dialog: false;
in-out property<bool> is-show-address-book-qrcode-dialog: false;
in-out property<bool> is-show-address-book-dialog: false;
Expand All @@ -123,17 +140,17 @@ export global Store {
uuid: "uuid-1",
time: "12-10 23:45:12",
txid: "31040072e777e124e120f6f157fdec1482062fb10055ba684e6dfc7b112f8241",
operate: "发送",
operate: "send",
amount: "0.12",
status: "未确认",
status: "unconfirm",
},
{
uuid: "uuid-2",
time: "12-10 22:43:12",
txid: "31040072e777e124e120f6f157fdec1482062fb10055ba684e6dfc7b112f8241",
operate: "发送",
operate: "send",
amount: "0.2",
status: "已确认",
status: "confirm",
}
];

Expand Down
Loading

0 comments on commit e99d2c0

Please sign in to comment.