mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-06-26 17:09:35 +00:00
92 lines
3.0 KiB
Rust
92 lines
3.0 KiB
Rust
//! Bridge program functions (deposit/withdraw between L1 Bedrock and L2).
|
|
|
|
use std::{ffi::CString, ptr};
|
|
|
|
use lee::AccountId;
|
|
use wallet::program_facades::bridge::Bridge;
|
|
|
|
use crate::{
|
|
block_on,
|
|
error::{print_error, WalletFfiError},
|
|
map_execution_error,
|
|
types::{FfiBytes32, FfiTransferResult, WalletHandle},
|
|
wallet::get_wallet,
|
|
};
|
|
|
|
/// Withdraw native tokens from a public account to Bedrock (L1) through the bridge.
|
|
///
|
|
/// # Parameters
|
|
/// - `handle`: Valid wallet handle
|
|
/// - `from`: Source public account ID (must be owned by this wallet). Bridge withdrawals only
|
|
/// support public sender accounts.
|
|
/// - `amount`: Amount of native tokens to withdraw
|
|
/// - `bedrock_account_pk`: Recipient's Bedrock (L1) public key, 32 bytes
|
|
/// - `out_result`: Output pointer for the withdraw result
|
|
///
|
|
/// # Returns
|
|
/// - `Success` if the withdraw transaction was submitted successfully
|
|
/// - `InsufficientFunds` if the source account doesn't have enough balance
|
|
/// - `KeyNotFound` if the source account's signing key is not in this wallet
|
|
/// - Error code on other failures
|
|
///
|
|
/// # Memory
|
|
/// The result must be freed with `wallet_ffi_free_transfer_result()`.
|
|
///
|
|
/// # Safety
|
|
/// - `handle` must be a valid wallet handle from `wallet_ffi_create_new` or `wallet_ffi_open`
|
|
/// - `from` must be a valid pointer to a `FfiBytes32` struct
|
|
/// - `bedrock_account_pk` must be a valid pointer to a `FfiBytes32` struct
|
|
/// - `out_result` must be a valid pointer to a `FfiTransferResult` struct
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn wallet_ffi_bridge_withdraw(
|
|
handle: *mut WalletHandle,
|
|
from: *const FfiBytes32,
|
|
amount: u64,
|
|
bedrock_account_pk: *const FfiBytes32,
|
|
out_result: *mut FfiTransferResult,
|
|
) -> WalletFfiError {
|
|
let wrapper = match get_wallet(handle) {
|
|
Ok(w) => w,
|
|
Err(e) => return e,
|
|
};
|
|
|
|
if from.is_null() || bedrock_account_pk.is_null() || out_result.is_null() {
|
|
print_error("Null pointer argument");
|
|
return WalletFfiError::NullPointer;
|
|
}
|
|
|
|
let wallet = match wrapper.core.lock() {
|
|
Ok(w) => w,
|
|
Err(e) => {
|
|
print_error(format!("Failed to lock wallet: {e}"));
|
|
return WalletFfiError::InternalError;
|
|
}
|
|
};
|
|
|
|
let from_id = AccountId::new(unsafe { (*from).data });
|
|
let bedrock_account_pk = unsafe { (*bedrock_account_pk).data };
|
|
|
|
let bridge = Bridge(&wallet);
|
|
|
|
match block_on(bridge.send_withdraw(from_id, amount, bedrock_account_pk)) {
|
|
Ok(tx_hash) => {
|
|
let tx_hash = CString::new(tx_hash.to_string())
|
|
.map_or(ptr::null_mut(), std::ffi::CString::into_raw);
|
|
|
|
unsafe {
|
|
(*out_result).tx_hash = tx_hash;
|
|
(*out_result).success = true;
|
|
}
|
|
WalletFfiError::Success
|
|
}
|
|
Err(e) => {
|
|
print_error(format!("Bridge withdraw failed: {e:?}"));
|
|
unsafe {
|
|
(*out_result).tx_hash = ptr::null_mut();
|
|
(*out_result).success = false;
|
|
}
|
|
map_execution_error(e)
|
|
}
|
|
}
|
|
}
|