mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-11-24 18:03:08 -05:00
feat(gui): DFX.swiss integration (#451)
* feat(gui): Monero wallet
* progress
* refactor
* progress, dont delete wallet, re-fetch approvals and background periodically
* show transaction history correctly
* Enable fetching tx hashes
* Try add the wallet listener event callbacks, not working
* fix: Redeem XMR to internal main wallet, not temp wallet
* feat(monero-sys): Support signing messages
* feat(gui): DFX.swiss integration
* refactor: format, slight refactorings
* progress
* type safety
* refactoring of callback system
* make free floating functions generic
* refactor: Format files
* refactor(gui): Split wallet components and redesign balanceOverview component
* refactor(gui): Add action buttons and transaction section
* wrapper event listener
* progress, compiles
* works!
* WORKS! Event received on balance change
* refactor: format and slight refactorings and comments
* refactor(gui): Start with implementation of send dialog
- new number input
- new button variant and size
* add @tauri-apps/plugin-dialog
* feat(gui): Add permissions for file dialog
* fix(monero-harness): Compile issue
* feat(gui): Extract seed from Monero wallet and use for derivation, allow opening existing wallet file
* feat(gui): Always refresh the approval list from frontend when resolving
* fix(monero-rpc-pool): Implement Into<String> for ServerInfo
* fix(monero-sys): Use oneshot channel for all wallets
* feat(gui, monero-sys): Display recently opened wallets
* small refactors
* fix(gui): Enable background_sync, display temp "Loading..." if values are null
* feat(gui): Remove headers from pages, show selected navigation item
* feat(gui): Explicitly tell user if no swaps have been made yet
* feat(gui): send sync and history updates
* feat(gui): Fetch monero wallet details when context becomes availiable
* feat(gui): Display Monero primary address without modal
* feat(gui): Make "swap" button on wallet page take you to "/swap"
* feat(gui): Rework send modal, adjust number input, added send to field
* feat(gui): set block restore height, not working
* refactor(gui): Optimize number input and add support for switching between currency
* feat(gui): Display real fiat currency prices in send modal
* feat(gui): Add error message for too high send amount
* feat(gui): Modern UI for SeedSelectionDialog
* feat(gui): Wrap MoneroWalletActions
* wip
* refactoring approval callback
* feat(gui): Send Direction of Transaction in History to Frontend
* feat(gui): Let user approve transaction before publishing
* feat: Display 8 digits for Monero amounts by default
* feat(monero-sys): Store pending (non published) transactions in Mutex map inside wallet thread
This allows seperating signing and publishing transactions cleanly
* dprint fmt
* fix(gui): Refresh Monero wallet history C++ struct before serializing
* feat(monero-rpc-pool): Fail after three JSON-RPC errors
* feat(monero-sys): Add wrapper around verify_wallet_password
* feat(gui): Allow opening password-protected Wallets
* refactor: fmt, remove receive button
* fix(gui): Convert to XMR before converting into Fiat
* feat(gui): Add dialog for setting restore height
* feat(gui): block height can be changed, blocks when too low
* refactor(monero-sys): Remove old WalletListener code
* feat(gui): Continually ask for user to select wallet and enter password, if user rejects, offer to select different wallet
* refactor(swap): Extract "select Monero wallet" into own function
* refactor(tauri): Dont kill monero-wallet-rpc
* refactor(tauri): Avoid multiple concurrent Contexts starting
* refactor: Change "Cancel" to "Change wallet" on PasswordEntryDialog
* feat(gui): show curent block height, fix blockage
* Cargo.lock update
* refactor(monero-sys): Use match instead of is_err() and expect(...)
* refactor: better context for WalletHandle constructor method errors handling
* refactor(monero-sys): Common open_with<F>(path: String, daemon: Daemon, wallet_op: F) function
* feat: check empty password before requeston password for wallet
* feat: Remove "Checking for available remote nodes" from frontend
* feat(gui): Allow sweeping entire Monero balance
* feat(monero-rpc-pool): Keep alive TCP connections, do not record JSON-RPC errors as failure if >=3 nodes failed
If >=3 nodes failed we assume it was an actual issue on our side, not an issue with the node
* refactor(swap): Remove dead code
* add comment to WalletHandleListener::on_refreshed{...}
* feat(gui): show current block height in the field
* refactor: remove unused UserCancelledError;
* refactor: No Arc<Mutex<_>> for Pending TXs map
* refactor: remove redundant } catch (error) {
* feat: add our new crates to `OUR_CRATES` in tracing util
* fix(gui): Add math.ceil to piconero conversion to ensure integer
* fix(gui): Close menu when option is clicked
* review and improve/reduce uses of unsafe, also remove unique_ptr wrapper around TransactionHistory to avoid double free
* fix(gui): Use monero amount from units.tsx
* fix(gui): Use PromiseInvokeButton for simplification for approving of send transaction
* update comment, rename function
* refactor(gui): Fix alignment of amounts
* refactor(gui): Remove sending and refreshing states from wallet
* fix(cli, gui): use old seed flow on no tauri, fix minor issues in gui
* fix: use the new named function
* refactor(gui): Add skeletons for monero wallet when still loading
* fix
* get working
* feat(gui): Add tooltip to buy monero button
* refactor: Format files
* refactor(gui): Do not store logs in redux-persist
---------
Co-authored-by: Maksim Kirillov <maksim.kirillov@staticlabs.de>
Co-authored-by: b-enedict <benedict.seuss@gmail.com>
Co-authored-by: einliterflasche <einliterflasche@pm.me>
This commit is contained in:
parent
591d0b8e20
commit
69ddd2486d
15 changed files with 658 additions and 81 deletions
|
|
@ -29,9 +29,12 @@ tauri-plugin-process = "^2.0.0"
|
|||
tauri-plugin-shell = "^2.0.0"
|
||||
tauri-plugin-store = "^2.0.0"
|
||||
tauri-plugin-updater = "^2.0.0"
|
||||
tokio = { workspace = true, features = ["rt"] }
|
||||
tokio-util = { version = "0.7", features = ["rt"] }
|
||||
tracing = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
zip = "4.0.0"
|
||||
dfx-swiss-sdk = { git = "https://github.com/eigenwallet/dfx-swiss-rs", subdir = "dfx-swiss-sdk" }
|
||||
|
||||
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
|
||||
tauri-plugin-cli = "^2.0.0"
|
||||
|
|
|
|||
|
|
@ -8,13 +8,14 @@ use swap::cli::{
|
|||
request::{
|
||||
BalanceArgs, BuyXmrArgs, CancelAndRefundArgs, CheckElectrumNodeArgs,
|
||||
CheckElectrumNodeResponse, CheckMoneroNodeArgs, CheckMoneroNodeResponse, CheckSeedArgs,
|
||||
CheckSeedResponse, ExportBitcoinWalletArgs, GetCurrentSwapArgs, GetDataDirArgs,
|
||||
GetHistoryArgs, GetLogsArgs, GetMoneroAddressesArgs, GetMoneroBalanceArgs,
|
||||
GetMoneroHistoryArgs, GetMoneroMainAddressArgs, GetMoneroSyncProgressArgs,
|
||||
GetPendingApprovalsResponse, GetRestoreHeightArgs, GetSwapInfoArgs,
|
||||
GetSwapInfosAllArgs, ListSellersArgs, MoneroRecoveryArgs, RedactArgs,
|
||||
RejectApprovalArgs, RejectApprovalResponse, ResolveApprovalArgs, ResumeSwapArgs,
|
||||
SendMoneroArgs, SetRestoreHeightArgs, SuspendCurrentSwapArgs, WithdrawBtcArgs,
|
||||
CheckSeedResponse, DfxAuthenticateResponse, ExportBitcoinWalletArgs,
|
||||
GetCurrentSwapArgs, GetDataDirArgs, GetHistoryArgs, GetLogsArgs,
|
||||
GetMoneroAddressesArgs, GetMoneroBalanceArgs, GetMoneroHistoryArgs,
|
||||
GetMoneroMainAddressArgs, GetMoneroSyncProgressArgs, GetPendingApprovalsResponse,
|
||||
GetRestoreHeightArgs, GetSwapInfoArgs, GetSwapInfosAllArgs, ListSellersArgs,
|
||||
MoneroRecoveryArgs, RedactArgs, RejectApprovalArgs, RejectApprovalResponse,
|
||||
ResolveApprovalArgs, ResumeSwapArgs, SendMoneroArgs, SetRestoreHeightArgs,
|
||||
SuspendCurrentSwapArgs, WithdrawBtcArgs,
|
||||
},
|
||||
tauri_bindings::{TauriContextStatusEvent, TauriEmitter, TauriHandle, TauriSettings},
|
||||
Context, ContextBuilder,
|
||||
|
|
@ -209,7 +210,8 @@ pub fn run() {
|
|||
get_pending_approvals,
|
||||
set_monero_restore_height,
|
||||
reject_approval_request,
|
||||
get_restore_height
|
||||
get_restore_height,
|
||||
dfx_authenticate,
|
||||
])
|
||||
.setup(setup)
|
||||
.build(tauri::generate_context!())
|
||||
|
|
@ -461,3 +463,92 @@ async fn initialize_context(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn dfx_authenticate(
|
||||
state: tauri::State<'_, State>,
|
||||
) -> Result<DfxAuthenticateResponse, String> {
|
||||
use dfx_swiss_sdk::{DfxClient, SignRequest};
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use tokio_util::task::AbortOnDropHandle;
|
||||
|
||||
let context = state.try_get_context()?;
|
||||
|
||||
// Get the monero wallet manager
|
||||
let monero_manager = context
|
||||
.monero_manager
|
||||
.as_ref()
|
||||
.ok_or("Monero wallet manager not available for DFX authentication")?;
|
||||
|
||||
let wallet = monero_manager.main_wallet().await;
|
||||
let address = wallet.main_address().await.to_string();
|
||||
|
||||
// Create channel for authentication
|
||||
let (auth_tx, mut auth_rx) = mpsc::channel::<(SignRequest, oneshot::Sender<String>)>(10);
|
||||
|
||||
// Create DFX client
|
||||
let mut client = DfxClient::new(address, Some("https://api.dfx.swiss".to_string()), auth_tx);
|
||||
|
||||
// Start signing task with AbortOnDropHandle
|
||||
let signing_task = tokio::spawn(async move {
|
||||
tracing::info!("DFX signing service started and listening for requests");
|
||||
|
||||
while let Some((sign_request, response_tx)) = auth_rx.recv().await {
|
||||
tracing::debug!(
|
||||
message = %sign_request.message,
|
||||
blockchains = ?sign_request.blockchains,
|
||||
"Received DFX signing request"
|
||||
);
|
||||
|
||||
// Sign the message using the main Monero wallet
|
||||
let signature = match wallet
|
||||
.sign_message(&sign_request.message, None, false)
|
||||
.await
|
||||
{
|
||||
Ok(sig) => {
|
||||
tracing::debug!(
|
||||
signature_preview = %&sig[..std::cmp::min(50, sig.len())],
|
||||
"Message signed successfully for DFX"
|
||||
);
|
||||
sig
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!(error = ?e, "Failed to sign message for DFX");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// Send signature back to DFX client
|
||||
if let Err(_) = response_tx.send(signature) {
|
||||
tracing::warn!("Failed to send signature response through channel to DFX client");
|
||||
}
|
||||
}
|
||||
|
||||
tracing::info!("DFX signing service stopped");
|
||||
});
|
||||
|
||||
// Create AbortOnDropHandle so the task gets cleaned up
|
||||
let _abort_handle = AbortOnDropHandle::new(signing_task);
|
||||
|
||||
// Authenticate with DFX
|
||||
tracing::info!("Starting DFX authentication...");
|
||||
client
|
||||
.authenticate()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to authenticate with DFX: {}", e))?;
|
||||
|
||||
let access_token = client
|
||||
.access_token
|
||||
.as_ref()
|
||||
.ok_or("No access token available after authentication")?
|
||||
.clone();
|
||||
|
||||
let kyc_url = format!("https://app.dfx.swiss/buy?session={}", access_token);
|
||||
|
||||
tracing::info!("DFX authentication completed successfully");
|
||||
|
||||
Ok(DfxAuthenticateResponse {
|
||||
access_token,
|
||||
kyc_url,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue