mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-08-27 04:11:08 +00:00
feat(wallet): reclaim an account atomically
This commit is contained in:
@@ -23,7 +23,8 @@ use crate::{
|
||||
programs::{
|
||||
amm::AmmProgramAgnosticSubcommand, ata::AtaSubcommand, bridge::BridgeSubcommand,
|
||||
native_token_transfer::AuthTransferSubcommand, pinata::PinataProgramAgnosticSubcommand,
|
||||
token::TokenProgramAgnosticSubcommand, vault::VaultSubcommand,
|
||||
system_program::SystemSubcommand, token::TokenProgramAgnosticSubcommand,
|
||||
vault::VaultSubcommand,
|
||||
},
|
||||
statistics::StatisticsSubcommand,
|
||||
},
|
||||
@@ -73,6 +74,9 @@ pub enum Command {
|
||||
/// Vault program interaction subcommand.
|
||||
#[command(subcommand)]
|
||||
Vault(VaultSubcommand),
|
||||
/// System Program interaction subcommand (e.g. reclaim an account).
|
||||
#[command(subcommand)]
|
||||
System(SystemSubcommand),
|
||||
/// Bridge program interaction subcommand.
|
||||
#[command(subcommand)]
|
||||
Bridge(BridgeSubcommand),
|
||||
@@ -218,6 +222,10 @@ impl Default for CliAccountMention {
|
||||
}
|
||||
}
|
||||
|
||||
#[expect(
|
||||
clippy::cognitive_complexity,
|
||||
reason = "flat dispatch over every CLI command"
|
||||
)]
|
||||
pub async fn execute_subcommand(
|
||||
wallet_core: &mut WalletCore,
|
||||
command: Command,
|
||||
@@ -235,6 +243,9 @@ pub async fn execute_subcommand(
|
||||
Command::Pinata(pinata_subcommand) => {
|
||||
pinata_subcommand.handle_subcommand(wallet_core).await?
|
||||
}
|
||||
Command::System(system_subcommand) => {
|
||||
system_subcommand.handle_subcommand(wallet_core).await?
|
||||
}
|
||||
Command::CheckHealth => {
|
||||
let remote_program_ids = wallet_core
|
||||
.get_program_ids()
|
||||
|
||||
@@ -3,5 +3,6 @@ pub mod ata;
|
||||
pub mod bridge;
|
||||
pub mod native_token_transfer;
|
||||
pub mod pinata;
|
||||
pub mod system_program;
|
||||
pub mod token;
|
||||
pub mod vault;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use lee::AccountId;
|
||||
|
||||
use crate::{
|
||||
WalletCore,
|
||||
account::AccountIdWithPrivacy,
|
||||
cli::{CliAccountMention, SubcommandReturnValue, WalletSubcommand},
|
||||
program_facades::system_program::SystemProgram,
|
||||
};
|
||||
|
||||
/// Represents generic CLI subcommand for a wallet working with the System Program.
|
||||
#[derive(Subcommand, Debug, Clone)]
|
||||
pub enum SystemSubcommand {
|
||||
/// !!!WARNING!!! Reclaim an account: wipe all of its data and hand it to a new owner,
|
||||
/// bypassing the program that currently owns it. Balance is preserved.
|
||||
///
|
||||
/// The account authorizes its own reset. Only public accounts are supported.
|
||||
Reclaim {
|
||||
/// Account to reclaim. Must have authorization.
|
||||
#[arg(long)]
|
||||
account_id: CliAccountMention,
|
||||
/// New owner - valid 32 byte base58 string WITHOUT privacy prefix. Defaults to the
|
||||
/// authenticated transfer program, which keeps the balance spendable.
|
||||
#[arg(long)]
|
||||
new_owner: Option<AccountId>,
|
||||
},
|
||||
}
|
||||
|
||||
impl WalletSubcommand for SystemSubcommand {
|
||||
async fn handle_subcommand(
|
||||
self,
|
||||
wallet_core: &mut WalletCore,
|
||||
) -> Result<SubcommandReturnValue> {
|
||||
match self {
|
||||
Self::Reclaim {
|
||||
account_id,
|
||||
new_owner,
|
||||
} => {
|
||||
let resolved = account_id.resolve(wallet_core.storage())?;
|
||||
let AccountIdWithPrivacy::Public(pub_account_id) = resolved else {
|
||||
anyhow::bail!(
|
||||
"Shielded reclaim is not yet supported; only public accounts can be reclaimed"
|
||||
);
|
||||
};
|
||||
let new_owner = Some(
|
||||
new_owner.unwrap_or_else(|| programs::authenticated_transfer().id().into()),
|
||||
);
|
||||
|
||||
let tx_hash = SystemProgram(wallet_core)
|
||||
.clear(
|
||||
account_id.into_public_identity(pub_account_id, true),
|
||||
new_owner,
|
||||
)
|
||||
.await?;
|
||||
|
||||
wallet_core
|
||||
.poll_and_finalize_public_transaction(tx_hash)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,5 +6,6 @@ pub mod ata;
|
||||
pub mod bridge;
|
||||
pub mod native_token_transfer;
|
||||
pub mod pinata;
|
||||
pub mod system_program;
|
||||
pub mod token;
|
||||
pub mod vault;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
use common::HashType;
|
||||
use lee::{AccountId, program::Program};
|
||||
use lee_core::program::{DEFAULT_PROGRAM_ID, SystemInstruction};
|
||||
|
||||
use crate::{AccountIdentity, ExecutionFailureKind, WalletCore};
|
||||
|
||||
pub struct SystemProgram<'wallet>(pub &'wallet WalletCore);
|
||||
|
||||
impl SystemProgram<'_> {
|
||||
pub async fn clear(
|
||||
&self,
|
||||
account: AccountIdentity,
|
||||
new_owner: Option<AccountId>,
|
||||
) -> Result<HashType, ExecutionFailureKind> {
|
||||
let instruction = SystemInstruction::Clear { new_owner };
|
||||
let instruction_data =
|
||||
Program::serialize_instruction(instruction).expect("Instruction should serialize");
|
||||
|
||||
self.0
|
||||
.send_pub_tx(vec![account], instruction_data, DEFAULT_PROGRAM_ID)
|
||||
.await
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user