mirror of
https://code.gri.mw/GUI/grim.git
synced 2026-07-13 10:18:54 +00:00
Merge branch 'refs/heads/master' into master-jasper
# Conflicts: # locales/zh-CN.yml
This commit is contained in:
@@ -16,7 +16,7 @@ jobs:
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
git submodule update --init --recursive --remote
|
||||
- name: Check commit
|
||||
id: check
|
||||
run: |
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
git submodule update --init --recursive --remote
|
||||
- name: Get version
|
||||
id: version
|
||||
run: |
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i -- 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
git submodule update --init --recursive --remote
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -188,7 +188,7 @@ jobs:
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
git submodule update --init --recursive --remote
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -255,7 +255,7 @@ jobs:
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
git submodule update --init --recursive --remote
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -307,7 +307,7 @@ jobs:
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i -- 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
git submodule update --init --recursive --remote
|
||||
- run: mkdir release
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
@@ -360,7 +360,7 @@ jobs:
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
(Get-content .gitmodules) | Foreach-Object {$_ -replace "https://code.gri.mw", "${{ secrets.REPO_HOST }}"} | Set-Content .gitmodules
|
||||
git submodule update --init
|
||||
git submodule update --init --recursive --remote
|
||||
- name: Update UpgradeCode
|
||||
shell: powershell
|
||||
run: |
|
||||
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
[submodule "node"]
|
||||
path = node
|
||||
url = https://code.gri.mw/ardocrat/node
|
||||
[submodule "wallet"]
|
||||
path = wallet
|
||||
url = https://code.gri.mw/ardocrat/wallet
|
||||
branch = grim
|
||||
branch = grim-staging
|
||||
[submodule "tor/webtunnel"]
|
||||
path = tor/webtunnel
|
||||
url = https://code.gri.mw/WEB/webtunnel
|
||||
|
||||
Generated
+509
-415
File diff suppressed because it is too large
Load Diff
+8
-14
@@ -29,14 +29,14 @@ panic = "abort"
|
||||
log = "0.4.27"
|
||||
|
||||
# node
|
||||
grin_api = { path = "node/api" }
|
||||
grin_chain = { path = "node/chain" }
|
||||
grin_config = { path = "node/config" }
|
||||
grin_core = { path = "node/core" }
|
||||
grin_p2p = { path = "node/p2p" }
|
||||
grin_servers = { path = "node/servers" }
|
||||
grin_keychain = { path = "node/keychain" }
|
||||
grin_util = { path = "node/util" }
|
||||
grin_api = { path = "wallet/grin/api" }
|
||||
grin_chain = { path = "wallet/grin/chain" }
|
||||
grin_config = { path = "wallet/grin/config" }
|
||||
grin_core = { path = "wallet/grin/core" }
|
||||
grin_p2p = { path = "wallet/grin/p2p" }
|
||||
grin_servers = { path = "wallet/grin/servers" }
|
||||
grin_keychain = { path = "wallet/grin/keychain" }
|
||||
grin_util = { path = "wallet/grin/util" }
|
||||
|
||||
# wallet
|
||||
grin_wallet_impls = { path = "wallet/impls" }
|
||||
@@ -53,10 +53,7 @@ rust-i18n = "3.1.5"
|
||||
|
||||
## other
|
||||
log4rs = "1.4.0"
|
||||
anyhow = "1.0.97"
|
||||
pin-project = "1.1.10"
|
||||
backtrace = "0.3.76"
|
||||
thiserror = "2.0.18"
|
||||
futures = "0.3.31"
|
||||
dirs = "6.0.0"
|
||||
sys-locale = "0.3.2"
|
||||
@@ -101,12 +98,9 @@ tor-hsrproxy = "0.43.0"
|
||||
tor-keymgr = "0.43.0"
|
||||
tor-llcrypto = "0.43.0"
|
||||
tor-hscrypto = "0.43.0"
|
||||
tor-error = "0.43.0"
|
||||
sha2 = "0.10.8"
|
||||
ed25519-dalek = "2.1.1"
|
||||
curve25519-dalek = "4.1.3"
|
||||
tls-api = "0.12.0"
|
||||
tls-api-native-tls = "0.12.1"
|
||||
safelog = "0.8.1"
|
||||
|
||||
## stratum server
|
||||
|
||||
@@ -152,6 +152,7 @@ transport:
|
||||
conn_error: Verbindungsproblem
|
||||
disconnected: Verbindung getrennt
|
||||
receiver_address: 'Empfängeraddresse:'
|
||||
sender_address: 'Absenderadresse:'
|
||||
incorrect_addr_err: 'Eingegebene Addresse ist inkorrekt:'
|
||||
tor_send_error: Beim Senden über Tor ist ein Fehler aufgetreten. Stellen Sie sicher, dass der Empfänger online ist. Die Transaktion wurde abgebrochen.
|
||||
tor_autorun_desc: Gibt an, ob beim Öffnen des Wallets der Tor-Dienst gestartet werden soll, um Transaktionen synchron zu empfangen.
|
||||
|
||||
@@ -152,6 +152,7 @@ transport:
|
||||
conn_error: Connection error
|
||||
disconnected: Disconnected
|
||||
receiver_address: 'Address of the receiver:'
|
||||
sender_address: 'Address of the sender:'
|
||||
incorrect_addr_err: 'Entered address is incorrect:'
|
||||
tor_send_error: An error occurred during sending over Tor, make sure receiver is online, transaction was canceled.
|
||||
tor_autorun_desc: Whether to launch Tor service on wallet opening to receive transactions synchronously.
|
||||
|
||||
@@ -152,6 +152,7 @@ transport:
|
||||
conn_error: Erreur de connexion
|
||||
disconnected: Déconnecté
|
||||
receiver_address: 'Adresse du destinataire:'
|
||||
sender_address: "Adresse de l'expéditeur:"
|
||||
incorrect_addr_err: 'Adresse entrée incorrecte:'
|
||||
tor_send_error: "Une erreur s'est produite lors de l'envoi via Tor. Assurez-vous que le destinataire est en ligne, la transaction a été annulée."
|
||||
tor_autorun_desc: "Lancer automatiquement le service Tor à l'ouverture du portefeuille pour recevoir les transactions de manière synchronisée."
|
||||
|
||||
@@ -152,6 +152,7 @@ transport:
|
||||
conn_error: Ошибка подключения
|
||||
disconnected: Отключено
|
||||
receiver_address: 'Адрес получателя:'
|
||||
sender_address: 'Адрес отправителя:'
|
||||
incorrect_addr_err: 'Введённый адрес неверен:'
|
||||
tor_send_error: Во время отправки через Tor произошла ошибка, убедитесь, что получатель находится онлайн, транзакция была отменена.
|
||||
tor_autorun_desc: Запускать ли Tor сервис при открытии кошелька для синхронного получения транзакций.
|
||||
|
||||
@@ -152,6 +152,7 @@ transport:
|
||||
conn_error: Bagalanti hatasi
|
||||
disconnected: Baglanti yok
|
||||
receiver_address: 'Alicinin adresi:'
|
||||
sender_address: 'Gönderici adresi:'
|
||||
incorrect_addr_err: 'Girilen adres hatali:'
|
||||
tor_send_error: Tor adresi uzerinden gonderimde aksaklik olustu, alici online olmasi gerek, islem iptal edildi.
|
||||
tor_autorun_desc: Islemleri Tor adresi olarak AL,bunun için cuzdan acilisinda Tor hizmetinin baslatilip baslatilmayacagi.
|
||||
|
||||
+27
-26
@@ -152,6 +152,7 @@ transport:
|
||||
conn_error: 连接错误
|
||||
disconnected: 已断开
|
||||
receiver_address: '接收方地址:'
|
||||
sender_address: '发送方地址:'
|
||||
incorrect_addr_err: '输入的地址不正确:'
|
||||
tor_send_error: 通过 Tor 发送时发生错误,请确认接收方在线,交易已取消。
|
||||
tor_autorun_desc: 是否在打开钱包时启动 Tor 服务以同步接收交易。
|
||||
@@ -325,35 +326,35 @@ keyboard:
|
||||
9: 9
|
||||
0: 0
|
||||
01: '-'
|
||||
q: q
|
||||
w: w
|
||||
e: e
|
||||
r: r
|
||||
t: t
|
||||
y: y
|
||||
u: u
|
||||
i: i
|
||||
o: o
|
||||
p: p
|
||||
q: 手
|
||||
w: 田
|
||||
e: 水
|
||||
r: 口
|
||||
t: 廿
|
||||
y: 卜
|
||||
u: 山
|
||||
i: 戈
|
||||
o: 人
|
||||
p: 心
|
||||
p1: '"'
|
||||
a: a
|
||||
s: s
|
||||
d: d
|
||||
f: f
|
||||
g: g
|
||||
h: h
|
||||
j: j
|
||||
k: k
|
||||
l: l
|
||||
a: 日
|
||||
s: 尸
|
||||
d: 木
|
||||
f: 火
|
||||
g: 土
|
||||
h: 竹
|
||||
j: 十
|
||||
k: 大
|
||||
l: 中
|
||||
l1: \
|
||||
l2: ':'
|
||||
z: z
|
||||
x: x
|
||||
c: c
|
||||
v: v
|
||||
b: b
|
||||
n: n
|
||||
m: m
|
||||
z: 重
|
||||
x: 難
|
||||
c: 金
|
||||
v: 女
|
||||
b: 月
|
||||
n: 弓
|
||||
m: 一
|
||||
m1: ','
|
||||
m2: .
|
||||
m3: /
|
||||
|
||||
-1
Submodule node deleted from bce5a7144b
+37
-1
@@ -25,8 +25,8 @@ use std::thread;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::CAMERA_ROTATE;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::View;
|
||||
use crate::gui::views::types::{QrScanResult, QrScanState};
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::wallet::WalletUtils;
|
||||
use crate::wallet::types::PhraseSize;
|
||||
|
||||
@@ -88,6 +88,42 @@ impl CameraContent {
|
||||
ui.ctx().request_repaint();
|
||||
}
|
||||
|
||||
/// Draw modal camera content.
|
||||
pub fn modal_ui(
|
||||
&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
cb: &dyn PlatformCallbacks,
|
||||
mut on_result: impl FnMut(Option<QrScanResult>),
|
||||
) {
|
||||
if let Some(result) = self.qr_scan_result() {
|
||||
on_result(Some(result));
|
||||
} else {
|
||||
ui.add_space(6.0);
|
||||
self.ui(ui, cb);
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Setup spacing between buttons.
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
|
||||
|
||||
// Show buttons to close modal or come back to sending input.
|
||||
ui.columns(2, |cols| {
|
||||
cols[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("close"), Colors::white_or_black(false), || {
|
||||
cb.stop_camera();
|
||||
on_result(None);
|
||||
Modal::close();
|
||||
});
|
||||
});
|
||||
cols[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("back"), Colors::white_or_black(false), || {
|
||||
on_result(None);
|
||||
});
|
||||
});
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw camera image.
|
||||
fn image_ui(&mut self, ui: &mut egui::Ui, mut img: DynamicImage, rotation: u32) -> Rect {
|
||||
// Setup image rotation.
|
||||
|
||||
@@ -12,25 +12,36 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::{Id, RichText};
|
||||
use grin_core::core::{amount_from_hr_string, amount_to_hr_string};
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, TextEdit, View};
|
||||
use crate::gui::views::{CameraContent, Modal, TextEdit, View};
|
||||
use crate::wallet::Wallet;
|
||||
use crate::wallet::types::WalletTask;
|
||||
use egui::{Id, RichText};
|
||||
use grin_core::core::{amount_from_hr_string, amount_to_hr_string};
|
||||
use grin_wallet_libwallet::SlatepackAddress;
|
||||
|
||||
/// Invoice request creation content.
|
||||
pub struct InvoiceRequestContent {
|
||||
/// Amount to receive.
|
||||
amount_edit: String,
|
||||
|
||||
/// Sender address.
|
||||
address_edit: String,
|
||||
/// Flag to check if entered address is incorrect.
|
||||
address_error: bool,
|
||||
|
||||
/// Address QR code scanner content.
|
||||
address_scan_content: Option<CameraContent>,
|
||||
}
|
||||
|
||||
impl Default for InvoiceRequestContent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
amount_edit: "".to_string(),
|
||||
address_edit: "".to_string(),
|
||||
address_error: false,
|
||||
address_scan_content: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,14 +61,36 @@ impl InvoiceRequestContent {
|
||||
return;
|
||||
}
|
||||
if let Ok(a) = amount_from_hr_string(m.amount_edit.as_str()) {
|
||||
m.amount_edit = "".to_string();
|
||||
wallet.task(WalletTask::Receive(a));
|
||||
let addr_str = m.address_edit.as_str();
|
||||
let addr = if let Ok(r) = SlatepackAddress::try_from(addr_str.trim()) {
|
||||
Some(r)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
wallet.task(WalletTask::Receive(a, addr));
|
||||
Modal::close();
|
||||
}
|
||||
};
|
||||
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Draw QR code scanner content if requested.
|
||||
if let Some(content) = self.address_scan_content.as_mut() {
|
||||
let mut close_scan = true;
|
||||
content.modal_ui(ui, cb, |result| {
|
||||
if let Some(result) = result {
|
||||
self.address_edit = result.text();
|
||||
} else {
|
||||
modal.enable_closing();
|
||||
close_scan = true;
|
||||
}
|
||||
});
|
||||
if close_scan {
|
||||
self.address_scan_content = None;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw amount input content.
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(
|
||||
@@ -72,11 +105,9 @@ impl InvoiceRequestContent {
|
||||
let amount_edit_before = self.amount_edit.clone();
|
||||
let mut amount_edit = TextEdit::new(Id::from(modal.id).with(wallet.get_config().id))
|
||||
.h_center()
|
||||
.numeric();
|
||||
.numeric()
|
||||
.focus(Modal::first_draw());
|
||||
amount_edit.ui(ui, &mut self.amount_edit, cb);
|
||||
if amount_edit.enter_pressed {
|
||||
on_continue(self);
|
||||
}
|
||||
|
||||
// Check value if input was changed.
|
||||
if amount_edit_before != self.amount_edit {
|
||||
@@ -109,7 +140,54 @@ impl InvoiceRequestContent {
|
||||
}
|
||||
}
|
||||
|
||||
ui.add_space(8.0);
|
||||
|
||||
// Show address error or input description.
|
||||
ui.vertical_centered(|ui| {
|
||||
if self.address_error {
|
||||
ui.label(
|
||||
RichText::new(t!("transport.incorrect_addr_err"))
|
||||
.size(17.0)
|
||||
.color(Colors::red()),
|
||||
);
|
||||
} else {
|
||||
ui.label(
|
||||
RichText::new(t!("transport.sender_address"))
|
||||
.size(17.0)
|
||||
.color(Colors::gray()),
|
||||
);
|
||||
}
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show address text edit.
|
||||
let addr_edit_before = self.address_edit.clone();
|
||||
let address_edit_id = Id::from(modal.id)
|
||||
.with("_address")
|
||||
.with(wallet.get_config().id);
|
||||
let mut address_edit = TextEdit::new(address_edit_id)
|
||||
.paste()
|
||||
.focus(false)
|
||||
.scan_qr();
|
||||
if amount_edit.enter_pressed {
|
||||
address_edit.focus_request();
|
||||
}
|
||||
address_edit.ui(ui, &mut self.address_edit, cb);
|
||||
// Check if scan button was pressed.
|
||||
if address_edit.scan_pressed {
|
||||
modal.disable_closing();
|
||||
self.address_scan_content = Some(CameraContent::default());
|
||||
}
|
||||
|
||||
ui.add_space(12.0);
|
||||
// Check value if input was changed.
|
||||
if addr_edit_before != self.address_edit {
|
||||
self.address_error = false;
|
||||
}
|
||||
// Continue on Enter press.
|
||||
if address_edit.enter_pressed {
|
||||
on_continue(self);
|
||||
}
|
||||
|
||||
// Setup spacing between buttons.
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
|
||||
@@ -121,7 +199,6 @@ impl InvoiceRequestContent {
|
||||
t!("modal.cancel"),
|
||||
Colors::white_or_black(false),
|
||||
|| {
|
||||
self.amount_edit = "".to_string();
|
||||
Modal::close();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -90,40 +90,18 @@ impl SendRequestContent {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Draw QR code scanner content if requested.
|
||||
if let Some(scanner) = self.address_scan_content.as_mut() {
|
||||
let on_stop = || {
|
||||
cb.stop_camera();
|
||||
modal.enable_closing();
|
||||
};
|
||||
|
||||
if let Some(result) = scanner.qr_scan_result() {
|
||||
self.address_edit = result.text();
|
||||
on_stop();
|
||||
if let Some(content) = self.address_scan_content.as_mut() {
|
||||
let mut close_scan = true;
|
||||
content.modal_ui(ui, cb, |result| {
|
||||
if let Some(result) = result {
|
||||
self.address_edit = result.text();
|
||||
} else {
|
||||
modal.enable_closing();
|
||||
close_scan = true;
|
||||
}
|
||||
});
|
||||
if close_scan {
|
||||
self.address_scan_content = None;
|
||||
} else {
|
||||
ui.add_space(6.0);
|
||||
scanner.ui(ui, cb);
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Setup spacing between buttons.
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
|
||||
|
||||
// Show buttons to close modal or come back to sending input.
|
||||
ui.columns(2, |cols| {
|
||||
cols[0].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("close"), Colors::white_or_black(false), || {
|
||||
on_stop();
|
||||
self.close();
|
||||
});
|
||||
});
|
||||
cols[1].vertical_centered_justified(|ui| {
|
||||
View::button(ui, t!("back"), Colors::white_or_black(false), || {
|
||||
on_stop();
|
||||
self.address_scan_content = None;
|
||||
});
|
||||
});
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -633,24 +633,20 @@ impl WalletTransactionsContent {
|
||||
View::item_button(ui, rounding, icon, color, || {
|
||||
if repost {
|
||||
wallet.task(WalletTask::Post(tx.data.id));
|
||||
return;
|
||||
} else if let Some(action) = tx.action.as_ref() {
|
||||
match action {
|
||||
WalletTxAction::Finalizing => {
|
||||
wallet.task(WalletTask::Finalize(tx.data.id));
|
||||
}
|
||||
WalletTxAction::Posting => {
|
||||
wallet.task(WalletTask::Post(tx.data.id));
|
||||
}
|
||||
_ => {
|
||||
if let Some(a) = &tx.receiver {
|
||||
wallet.task(WalletTask::SendTor(tx.data.clone(), a.clone()));
|
||||
}
|
||||
}
|
||||
if action == &WalletTxAction::Finalizing {
|
||||
wallet.task(WalletTask::Finalize(tx.data.id));
|
||||
return;
|
||||
} else if action == &WalletTxAction::Posting {
|
||||
wallet.task(WalletTask::Post(tx.data.id));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let Some(a) = &tx.receiver {
|
||||
wallet.task(WalletTask::SendTor(tx.data.clone(), a.clone()));
|
||||
} else {
|
||||
if let Some(a) = &tx.receiver {
|
||||
wallet.task(WalletTask::SendTor(tx.data.clone(), a.clone()));
|
||||
}
|
||||
wallet.task(WalletTask::FinalizeTor(tx.data.clone()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,13 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
use egui::{Align, CornerRadius, Id, Layout, RichText, ScrollArea, StrokeKind};
|
||||
use grin_core::core::amount_to_hr_string;
|
||||
use grin_util::ToHex;
|
||||
use grin_wallet_libwallet::TxLogEntryType;
|
||||
use std::fs;
|
||||
|
||||
use crate::AppConfig;
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::{
|
||||
@@ -34,6 +27,13 @@ use crate::gui::views::{Modal, QrCodeContent, View};
|
||||
use crate::wallet::Wallet;
|
||||
use crate::wallet::types::{WalletTask, WalletTx};
|
||||
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
use egui::{Align, CornerRadius, Id, Layout, RichText, ScrollArea, StrokeKind};
|
||||
use grin_core::core::amount_to_hr_string;
|
||||
use grin_util::ToHex;
|
||||
use grin_wallet_libwallet::TxLogEntryType;
|
||||
use std::fs;
|
||||
|
||||
/// Transaction information [`Modal`] content.
|
||||
pub struct WalletTransactionContent {
|
||||
/// Transaction identifier.
|
||||
@@ -168,10 +168,12 @@ impl WalletTransactionContent {
|
||||
cb: &dyn PlatformCallbacks,
|
||||
) {
|
||||
if self.message.is_none() {
|
||||
let slatepack_path = wallet
|
||||
.get_config()
|
||||
.get_slate_path(tx.data.tx_slate_id.unwrap(), &tx.state);
|
||||
self.message = Some(fs::read_to_string(slatepack_path).unwrap_or("".to_string()));
|
||||
if let Some(slate_state) = tx.data.tx_slate_state.as_ref() {
|
||||
let slatepack_path = wallet
|
||||
.get_config()
|
||||
.get_slate_path(tx.data.tx_slate_id.unwrap(), slate_state);
|
||||
self.message = Some(fs::read_to_string(slatepack_path).unwrap_or("".to_string()));
|
||||
}
|
||||
}
|
||||
if let Some(m) = &self.message {
|
||||
if m.is_empty() {
|
||||
@@ -260,29 +262,31 @@ impl WalletTransactionContent {
|
||||
});
|
||||
|
||||
// Draw button to share response as file.
|
||||
ui.add_space(8.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
let share_text = format!("{} {}", FILE_TEXT, t!("share"));
|
||||
View::colored_text_button(
|
||||
ui,
|
||||
share_text,
|
||||
Colors::blue(),
|
||||
Colors::white_or_black(false),
|
||||
|| {
|
||||
if let Some(slate_id) = tx.data.tx_slate_id {
|
||||
let name = format!("{}.{}.slatepack", slate_id, tx.state);
|
||||
let data = m.as_bytes().to_vec();
|
||||
cb.share_data(name, data).unwrap_or_default();
|
||||
// Show message input or close modal.
|
||||
if tx.can_finalize() {
|
||||
finalization_needed = true;
|
||||
} else {
|
||||
Modal::close();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
if let Some(slate_id) = tx.data.tx_slate_id {
|
||||
if let Some(slate_state) = tx.data.tx_slate_state.as_ref() {
|
||||
ui.add_space(8.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
let share_text = format!("{} {}", FILE_TEXT, t!("share"));
|
||||
View::colored_text_button(
|
||||
ui,
|
||||
share_text,
|
||||
Colors::blue(),
|
||||
Colors::white_or_black(false),
|
||||
|| {
|
||||
let name = format!("{}.{}.slatepack", slate_id, slate_state);
|
||||
let data = m.as_bytes().to_vec();
|
||||
cb.share_data(name, data).unwrap_or_default();
|
||||
// Show message input or close modal.
|
||||
if tx.can_finalize() {
|
||||
finalization_needed = true;
|
||||
} else {
|
||||
Modal::close();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if finalization_needed {
|
||||
Modal::new(MessageInputContent::MODAL_ID)
|
||||
@@ -370,13 +374,13 @@ impl WalletTransactionContent {
|
||||
info_item_ui(ui, kernel.0.to_hex(), label, true, cb);
|
||||
}
|
||||
// Show receiver or sender address.
|
||||
let addr = if tx.data.tx_type == TxLogEntryType::TxSent {
|
||||
&tx.receiver
|
||||
let (addr, label) = if tx.data.tx_type == TxLogEntryType::TxSent {
|
||||
(&tx.receiver, t!("transport.receiver_address"))
|
||||
} else {
|
||||
&tx.sender
|
||||
(&tx.sender, t!("transport.sender_address"))
|
||||
};
|
||||
if let Some(addr) = addr {
|
||||
let label = format!("{} {}", CIRCLE_HALF, t!("network_mining.address"));
|
||||
let label = format!("{} {}", CIRCLE_HALF, label.replace(":", ""));
|
||||
info_item_ui(ui, addr.to_string(), label, true, cb);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -323,7 +323,7 @@ impl Tor {
|
||||
.block_on(async move {
|
||||
let res = c
|
||||
.runtime()
|
||||
.timeout(Duration::from_millis(600000), async {
|
||||
.timeout(Duration::from_millis(60000), async {
|
||||
if let Ok(stream) = c
|
||||
.connect((uri.host().unwrap(), uri.port_u16().unwrap_or(80)))
|
||||
.await
|
||||
|
||||
+9
-18
@@ -213,8 +213,6 @@ pub enum WalletTxAction {
|
||||
pub struct WalletTx {
|
||||
/// Information from database.
|
||||
pub data: TxLogEntry,
|
||||
/// State of transaction Slate.
|
||||
pub state: SlateState,
|
||||
/// Payment proof.
|
||||
pub(crate) proof: Option<PaymentProof>,
|
||||
|
||||
@@ -240,7 +238,6 @@ impl WalletTx {
|
||||
pub fn new(
|
||||
tx: TxLogEntry,
|
||||
proof: Option<PaymentProof>,
|
||||
wallet: &Wallet,
|
||||
height: Option<u64>,
|
||||
broadcasting_height: Option<u64>,
|
||||
action: Option<WalletTxAction>,
|
||||
@@ -263,9 +260,8 @@ impl WalletTx {
|
||||
sender = Some(addr);
|
||||
}
|
||||
}
|
||||
let mut t = Self {
|
||||
let t = Self {
|
||||
data: tx,
|
||||
state: SlateState::Unknown,
|
||||
proof,
|
||||
amount,
|
||||
receiver,
|
||||
@@ -275,15 +271,6 @@ impl WalletTx {
|
||||
action,
|
||||
action_error,
|
||||
};
|
||||
// Update Slate state for unconfirmed.
|
||||
if !t.data.confirmed
|
||||
&& (t.data.tx_type == TxLogEntryType::TxSent
|
||||
|| t.data.tx_type == TxLogEntryType::TxReceived)
|
||||
{
|
||||
if let Some(slate_id) = t.data.tx_slate_id {
|
||||
t.state = wallet.get_slate_state(slate_id, &t.data.tx_type)
|
||||
}
|
||||
}
|
||||
t
|
||||
}
|
||||
|
||||
@@ -294,15 +281,16 @@ impl WalletTx {
|
||||
&& (!self.sending_tor() || self.action_error.is_some())
|
||||
&& (self.data.tx_type == TxLogEntryType::TxSent
|
||||
|| self.data.tx_type == TxLogEntryType::TxReceived)
|
||||
&& (self.state == SlateState::Invoice1 || self.state == SlateState::Standard1)
|
||||
&& (self.data.tx_slate_state == Some(SlateState::Invoice1)
|
||||
|| self.data.tx_slate_state == Some(SlateState::Standard1))
|
||||
}
|
||||
|
||||
/// Check if transaction was finalized.
|
||||
pub fn finalized(&self) -> bool {
|
||||
(self.data.tx_type == TxLogEntryType::TxSent
|
||||
|| self.data.tx_type == TxLogEntryType::TxReceived)
|
||||
&& self.state == SlateState::Invoice3
|
||||
|| self.state == SlateState::Standard3
|
||||
&& self.data.tx_slate_state == Some(SlateState::Invoice3)
|
||||
|| self.data.tx_slate_state == Some(SlateState::Standard3)
|
||||
}
|
||||
|
||||
/// Check if transaction is sending over Tor.
|
||||
@@ -418,9 +406,12 @@ pub enum WalletTask {
|
||||
/// * tx
|
||||
/// * receiver
|
||||
SendTor(TxLogEntry, SlatepackAddress),
|
||||
/// Finalize over Tor.
|
||||
/// * tx
|
||||
FinalizeTor(TxLogEntry),
|
||||
/// Invoice creation.
|
||||
/// * amount
|
||||
Receive(u64),
|
||||
Receive(u64, Option<SlatepackAddress>),
|
||||
/// Transaction finalization.
|
||||
/// * tx id
|
||||
Finalize(u32),
|
||||
|
||||
+135
-92
@@ -39,6 +39,7 @@ use grin_wallet_impls::{DefaultLCProvider, DefaultWalletImpl, HTTPNodeClient};
|
||||
use grin_wallet_libwallet::api_impl::owner::{
|
||||
cancel_tx, init_send_tx, retrieve_summary_info, retrieve_txs, verify_payment_proof,
|
||||
};
|
||||
use grin_wallet_libwallet::api_impl::types::update_tx_slate_state;
|
||||
use grin_wallet_libwallet::{
|
||||
Error, InitTxArgs, IssueInvoiceTxArgs, NodeClient, PaymentProof, Slate, SlateState,
|
||||
SlateVersion, SlatepackAddress, StatusMessage, StoredProofInfo, TxLogEntry, TxLogEntryType,
|
||||
@@ -936,7 +937,7 @@ impl Wallet {
|
||||
fn create_slatepack_message(
|
||||
&self,
|
||||
slate: &Slate,
|
||||
_: Option<SlatepackAddress>,
|
||||
address: Option<SlatepackAddress>,
|
||||
) -> Result<String, Error> {
|
||||
let mut message = "".to_string();
|
||||
let r_inst = self.instance.as_ref().read();
|
||||
@@ -947,11 +948,11 @@ impl Wallet {
|
||||
self.keychain_mask().as_ref(),
|
||||
Some(&mut api),
|
||||
|api, m| {
|
||||
// let recipients = match dest {
|
||||
// Some(a) => vec![a],
|
||||
// None => vec![],
|
||||
// };
|
||||
message = api.create_slatepack_message(m, &slate, Some(0), vec![])?;
|
||||
let addrs = match address {
|
||||
Some(a) => vec![a],
|
||||
None => vec![],
|
||||
};
|
||||
message = api.create_slatepack_message(m, &slate, Some(0), addrs)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
@@ -970,40 +971,6 @@ impl Wallet {
|
||||
fs::exists(slatepack_path).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Get possible state from tx type.
|
||||
pub fn get_slate_state(&self, slate_id: Uuid, tx_type: &TxLogEntryType) -> SlateState {
|
||||
let mut slate = Slate::blank(1, false);
|
||||
slate.id = slate_id;
|
||||
slate.state = match tx_type {
|
||||
TxLogEntryType::TxReceived => SlateState::Invoice3,
|
||||
_ => SlateState::Standard3,
|
||||
};
|
||||
// Transaction was finalized.
|
||||
if self.slatepack_exists(&slate) {
|
||||
slate.state
|
||||
} else {
|
||||
slate.state = match tx_type {
|
||||
TxLogEntryType::TxReceived => SlateState::Standard2,
|
||||
_ => SlateState::Invoice2,
|
||||
};
|
||||
// Transaction signed to be finalized.
|
||||
if self.slatepack_exists(&slate) {
|
||||
slate.state
|
||||
} else {
|
||||
// Transaction just was created.
|
||||
slate.state = match tx_type {
|
||||
TxLogEntryType::TxReceived => SlateState::Invoice1,
|
||||
_ => SlateState::Standard1,
|
||||
};
|
||||
if self.slatepack_exists(&slate) {
|
||||
slate.state
|
||||
} else {
|
||||
SlateState::Unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate transaction fee for provided amount.
|
||||
fn calculate_fee(&self, a: u64) -> Result<u64, Error> {
|
||||
let r_inst = self.instance.as_ref().read();
|
||||
@@ -1057,7 +1024,7 @@ impl Wallet {
|
||||
controller::owner_single_use(None, keychain_mask.as_ref(), Some(&mut api), |api, m| {
|
||||
let s = api.init_send_tx(m, args)?;
|
||||
// Create Slatepack message response.
|
||||
let _ = self.create_slatepack_message(&s, dest)?;
|
||||
let _ = self.create_slatepack_message(&s, None)?;
|
||||
// Lock outputs to for this transaction.
|
||||
api.tx_lock_outputs(m, &s)?;
|
||||
slate = Some(s);
|
||||
@@ -1070,27 +1037,47 @@ impl Wallet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Send slate to Tor address.
|
||||
async fn send_tor(&self, id: u32, s: &Slate, addr: &SlatepackAddress) -> Result<Slate, Error> {
|
||||
/// Send slate to Tor address. When `finalize` is true, posts the slate to the
|
||||
/// peer's foreign-api `finalize_tx` (used by the invoice-flow payer to push the
|
||||
/// signed Invoice2 back to the merchant for broadcast); otherwise posts to
|
||||
/// `receive_tx` (standard send flow).
|
||||
async fn send_tor(
|
||||
&self,
|
||||
id: u32,
|
||||
s: &Slate,
|
||||
addr: &SlatepackAddress,
|
||||
finalize: bool,
|
||||
) -> Result<Slate, Error> {
|
||||
self.on_tx_action(id, Some(WalletTxAction::SendingTor));
|
||||
|
||||
let tor_addr = OnionV3Address::try_from(addr).unwrap().to_http_str();
|
||||
let url = format!("{}/v2/foreign", tor_addr);
|
||||
let slate_send = VersionedSlate::into_version(s.clone(), SlateVersion::V4)?;
|
||||
let body = json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "receive_tx",
|
||||
"id": 1,
|
||||
"params": [
|
||||
slate_send,
|
||||
null,
|
||||
null
|
||||
]
|
||||
})
|
||||
let body = if finalize {
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "finalize_tx",
|
||||
"id": 1,
|
||||
"params": [slate_send]
|
||||
})
|
||||
} else {
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"method": "receive_tx",
|
||||
"id": 1,
|
||||
"params": [
|
||||
slate_send,
|
||||
null,
|
||||
null
|
||||
]
|
||||
})
|
||||
}
|
||||
.to_string();
|
||||
// Wait Tor service to launch.
|
||||
while Tor::is_service_starting(&self.identifier()) {
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
while !Tor::is_service_running(&self.identifier()) {
|
||||
return Err(Error::GenericError(
|
||||
"Tor service is not running".to_string(),
|
||||
));
|
||||
}
|
||||
// Send request to receiver.
|
||||
let req_res = Tor::post(body, url).await;
|
||||
@@ -1118,7 +1105,11 @@ impl Wallet {
|
||||
}
|
||||
|
||||
/// Initialize an invoice transaction to receive amount, return request for funds sender.
|
||||
fn issue_invoice(&self, amount: u64) -> Result<Slate, Error> {
|
||||
fn issue_invoice(
|
||||
&self,
|
||||
amount: u64,
|
||||
address: Option<SlatepackAddress>,
|
||||
) -> Result<Slate, Error> {
|
||||
let args = IssueInvoiceTxArgs {
|
||||
dest_acct_name: None,
|
||||
amount,
|
||||
@@ -1130,13 +1121,13 @@ impl Wallet {
|
||||
let slate = api.issue_invoice_tx(self.keychain_mask().as_ref(), args)?;
|
||||
|
||||
// Create Slatepack message response.
|
||||
let _ = self.create_slatepack_message(&slate, None)?;
|
||||
let _ = self.create_slatepack_message(&slate, address)?;
|
||||
|
||||
Ok(slate)
|
||||
}
|
||||
|
||||
/// Handle message from the invoice issuer to send founds, return response for funds receiver.
|
||||
fn pay(&self, slate: &Slate) -> Result<Slate, Error> {
|
||||
fn pay(&self, slate: &Slate, dest: Option<SlatepackAddress>) -> Result<Slate, Error> {
|
||||
let config = self.get_config();
|
||||
let args = InitTxArgs {
|
||||
src_acct_name: None,
|
||||
@@ -1151,8 +1142,9 @@ impl Wallet {
|
||||
let slate = api.process_invoice_tx(self.keychain_mask().as_ref(), &slate, args)?;
|
||||
api.tx_lock_outputs(self.keychain_mask().as_ref(), &slate)?;
|
||||
|
||||
// Create Slatepack message response.
|
||||
let _ = self.create_slatepack_message(&slate, None)?;
|
||||
// Create Slatepack message response (kept as on-disk paste-back fallback even
|
||||
// when an auto-Tor reply is attempted by the caller).
|
||||
let _ = self.create_slatepack_message(&slate, dest)?;
|
||||
|
||||
Ok(slate)
|
||||
}
|
||||
@@ -1310,20 +1302,33 @@ impl Wallet {
|
||||
}
|
||||
|
||||
/// Get stored transaction Slate.
|
||||
fn get_tx_slate(&self, tx_id: u32) -> Option<Slate> {
|
||||
fn get_tx_slate(&self, tx_id: u32) -> Option<(Slate, Option<SlatepackAddress>)> {
|
||||
if let Some(tx) = self.retrieve_tx_by_id(Some(tx_id), None) {
|
||||
if let Some(slate_id) = tx.tx_slate_id {
|
||||
let slate_state = self.get_slate_state(slate_id, &tx.tx_type);
|
||||
let slatepack_path = self.get_config().get_slate_path(slate_id, &slate_state);
|
||||
let msg = fs::read_to_string(slatepack_path).unwrap_or("".to_string());
|
||||
if let Ok((slate, _)) = self.parse_slatepack(&msg) {
|
||||
return Some(slate);
|
||||
if let Some(slate_state) = tx.tx_slate_state {
|
||||
let slatepack_path = self.get_config().get_slate_path(slate_id, &slate_state);
|
||||
let msg = fs::read_to_string(slatepack_path).unwrap_or("".to_string());
|
||||
if let Ok((slate, dest)) = self.parse_slatepack(&msg) {
|
||||
return Some((slate, dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Update transaction slate state.
|
||||
fn update_slate_state(&self, slate: &Slate) -> Result<(), Error> {
|
||||
let r_inst = self.instance.as_ref().read();
|
||||
let instance = r_inst.clone().unwrap();
|
||||
let mut w_lock = instance.lock();
|
||||
let w = w_lock.lc_provider()?.wallet_inst()?;
|
||||
let keychain_mask = self.keychain_mask();
|
||||
let parent_key = w.parent_key_id();
|
||||
update_tx_slate_state(w, keychain_mask.as_ref(), &parent_key, slate)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Delete transaction from database.
|
||||
fn delete_tx(&self, id: u32) -> Result<(), Error> {
|
||||
self.on_tx_action(id, Some(WalletTxAction::Deleting));
|
||||
@@ -1341,7 +1346,7 @@ impl Wallet {
|
||||
batch.commit()?;
|
||||
|
||||
// Delete transaction files.
|
||||
if let Some(s) = slate {
|
||||
if let Some((s, _)) = slate {
|
||||
let slatepack_path = self.get_config().get_slate_path(s.id, &s.state);
|
||||
fs::remove_file(&slatepack_path).unwrap_or_default();
|
||||
let path = path::Path::new(&self.get_config().get_data_path())
|
||||
@@ -1743,8 +1748,9 @@ fn start_sync(wallet: Wallet) -> Thread {
|
||||
|
||||
/// Handle wallet task.
|
||||
async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
// Send amount over Tor.
|
||||
let send_tor = async |tx: TxLogEntry, s: &Slate, r: &SlatepackAddress| match w
|
||||
.send_tor(tx.id, &s, r)
|
||||
.send_tor(tx.id, &s, r, false)
|
||||
.await
|
||||
{
|
||||
Ok(s) => match w.finalize(&s, tx.id) {
|
||||
@@ -1754,17 +1760,35 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
w.on_task_result(Some(tx), &t);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("send tor post error: {:?}", e);
|
||||
error!("Send Tor post error: {:?}", e);
|
||||
w.on_tx_error(tx.id, Some(e));
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("send tor finalize error: {:?}", e);
|
||||
error!("Send Tor finalize error: {:?}", e);
|
||||
w.task(WalletTask::Cancel(tx.id));
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("send tor error: {:?}", e);
|
||||
error!("Send Tor error: {:?}", e);
|
||||
w.on_tx_error(tx.id, Some(e));
|
||||
w.on_task_result(Some(tx), &t);
|
||||
}
|
||||
};
|
||||
// Finalize tx over Tor.
|
||||
let finalize_tor = async |tx: TxLogEntry, s: &Slate, r: &SlatepackAddress| match w
|
||||
.send_tor(tx.id, &s, r, true)
|
||||
.await
|
||||
{
|
||||
Ok(s) => {
|
||||
w.on_tx_action(tx.id, None);
|
||||
let _ = w.update_slate_state(&s);
|
||||
let _ = w.create_slatepack_message(&s, None);
|
||||
sync_wallet_data(&w, false);
|
||||
w.on_task_result(Some(tx), &t);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Finalize Tor error: {:?}", e);
|
||||
w.on_tx_error(tx.id, Some(e));
|
||||
w.on_task_result(Some(tx), &t);
|
||||
}
|
||||
@@ -1800,21 +1824,34 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
w.message_opening.store(false, Ordering::Relaxed);
|
||||
return;
|
||||
}
|
||||
// Finalize over Tor if service is running.
|
||||
let maybe_finalize_tor = async |s: Slate| {
|
||||
sync_wallet_data(&w, false);
|
||||
let tx = w.retrieve_tx_by_id(None, Some(s.id));
|
||||
let id = w.identifier();
|
||||
if Tor::is_service_running(&id) {
|
||||
if let Some(tx) = tx.as_ref() {
|
||||
if let Some(addr) = dest {
|
||||
w.message_opening.store(false, Ordering::Relaxed);
|
||||
finalize_tor(tx.clone(), &s, &addr).await;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// Create response or finalize.
|
||||
match s.state {
|
||||
SlateState::Standard1 | SlateState::Invoice1 => {
|
||||
if s.state != SlateState::Standard1 {
|
||||
if let Ok(_) = w.pay(&s) {
|
||||
sync_wallet_data(&w, false);
|
||||
let tx = w.retrieve_tx_by_id(None, Some(s.id));
|
||||
w.on_task_result(tx, &t);
|
||||
}
|
||||
} else {
|
||||
if let Ok(_) = w.receive(&s, dest) {
|
||||
sync_wallet_data(&w, false);
|
||||
let tx = w.retrieve_tx_by_id(None, Some(s.id));
|
||||
w.on_task_result(tx, &t);
|
||||
}
|
||||
SlateState::Standard1 => {
|
||||
if let Ok(s) = w.receive(&s, None) {
|
||||
maybe_finalize_tor(s).await;
|
||||
w.on_task_result(tx, &t);
|
||||
}
|
||||
}
|
||||
SlateState::Invoice1 => {
|
||||
if let Ok(s) = w.pay(&s, None) {
|
||||
sync_wallet_data(&w, false);
|
||||
maybe_finalize_tor(s).await;
|
||||
w.on_task_result(tx, &t);
|
||||
}
|
||||
}
|
||||
SlateState::Standard2 | SlateState::Invoice2 => {
|
||||
@@ -1870,7 +1907,7 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
if let Some(tx) = tx {
|
||||
if let Some(addr) = r {
|
||||
let id = w.identifier();
|
||||
if Tor::is_service_running(&id) || Tor::is_service_starting(&id) {
|
||||
if Tor::is_service_running(&id) {
|
||||
w.send_creating.store(false, Ordering::Relaxed);
|
||||
send_tor(tx, &s, addr).await;
|
||||
return;
|
||||
@@ -1885,13 +1922,20 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
w.send_creating.store(false, Ordering::Relaxed);
|
||||
}
|
||||
WalletTask::SendTor(tx, r) => {
|
||||
if let Some(s) = w.get_tx_slate(tx.id) {
|
||||
send_tor(tx.clone(), &s, r).await;
|
||||
if let Some((slate, _)) = w.get_tx_slate(tx.id) {
|
||||
send_tor(tx.clone(), &slate, r).await;
|
||||
}
|
||||
}
|
||||
WalletTask::Receive(a) => {
|
||||
WalletTask::FinalizeTor(tx) => {
|
||||
if let Some((slate, dest)) = w.get_tx_slate(tx.id) {
|
||||
if let Some(dest) = dest {
|
||||
finalize_tor(tx.clone(), &slate, &dest).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
WalletTask::Receive(amount, address) => {
|
||||
w.invoice_creating.store(true, Ordering::Relaxed);
|
||||
if let Ok(s) = w.issue_invoice(*a) {
|
||||
if let Ok(s) = w.issue_invoice(*amount, address.clone()) {
|
||||
sync_wallet_data(&w, false);
|
||||
let tx = w.retrieve_tx_by_id(None, Some(s.id));
|
||||
if let Some(tx) = tx {
|
||||
@@ -1901,7 +1945,7 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
w.invoice_creating.store(false, Ordering::Relaxed);
|
||||
}
|
||||
WalletTask::Finalize(id) => {
|
||||
if let Some(s) = w.get_tx_slate(*id) {
|
||||
if let Some((s, _)) = w.get_tx_slate(*id) {
|
||||
w.on_tx_error(*id, None);
|
||||
match w.finalize(&s, *id) {
|
||||
Ok(s) => match w.post(&s, Some(*id)) {
|
||||
@@ -1924,7 +1968,7 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
}
|
||||
}
|
||||
WalletTask::Post(id) => {
|
||||
if let Some(s) = w.get_tx_slate(*id) {
|
||||
if let Some((s, _)) = w.get_tx_slate(*id) {
|
||||
w.on_tx_error(*id, None);
|
||||
// Cleanup broadcasting tx height.
|
||||
let tx_height_store = TxHeightStore::new(w.get_config().get_extra_db_path());
|
||||
@@ -2143,7 +2187,6 @@ fn update_txs(wallet: &Wallet, mut txs_limit: u32) -> Result<(), Error> {
|
||||
let mut new = WalletTx::new(
|
||||
tx.clone(),
|
||||
proof.clone(),
|
||||
wallet,
|
||||
height,
|
||||
broadcasting_height,
|
||||
action,
|
||||
|
||||
+1
-1
Submodule wallet updated: c2db754552...5c54e7cf8d
Reference in New Issue
Block a user