mod famous;
pub mod tokens;
mod types;
pub mod utils;
use crate::{commands::wallet::CliState, errors::CliError};
use clap::Args;
use neo3::prelude::*;
use primitive_types::H160;
use std::{path::PathBuf, str::FromStr};
#[derive(Args, Debug, Clone)]
pub struct DefiArgs {
#[arg(short, long)]
pub wallet: Option<PathBuf>,
#[arg(short, long)]
pub password: Option<String>,
#[clap(subcommand)]
pub command: DefiCommands,
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum DefiCommands {
Token {
contract: String,
},
Balance {
contract: String,
address: String,
},
Transfer {
token: String,
to: String,
amount: String,
data: Option<String>,
},
Flamingo {
#[clap(subcommand)]
command: FlamingoCommands,
},
NeoBurger {
#[clap(subcommand)]
command: NeoBurgerCommands,
},
NeoCompound {
#[clap(subcommand)]
command: NeoCompoundCommands,
},
GrandShare {
#[clap(subcommand)]
command: GrandShareCommands,
},
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum FlamingoCommands {
Swap {
from_token: String,
to_token: String,
amount: String,
min_return: Option<String>,
},
AddLiquidity {
token_a: String,
token_b: String,
amount_a: String,
amount_b: String,
},
RemoveLiquidity {
token_a: String,
token_b: String,
liquidity: String,
},
Stake {
token: String,
amount: String,
},
ClaimRewards {},
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum NeoBurgerCommands {
Wrap {
amount: String,
},
Unwrap {
amount: String,
},
ClaimGas {},
GetRate {},
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum NeoCompoundCommands {
Deposit {
token: String,
amount: String,
},
Withdraw {
token: String,
amount: String,
},
Compound {
token: String,
},
GetAPY {
token: String,
},
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum GrandShareCommands {
SubmitProposal {
title: String,
description: String,
amount: String,
},
Vote {
proposal_id: i32,
#[arg(short, long)]
approve: bool,
},
FundProject {
project_id: i32,
amount: String,
},
ClaimFunds {
project_id: i32,
},
}
pub fn create_h160_param(value: &str) -> Result<ContractParameter, CliError> {
match Address::from_str(value) {
Ok(address) => {
match address.address_to_scripthash() {
Ok(script_hash) => return Ok(ContractParameter::h160(&script_hash)),
Err(e) => {
return Err(CliError::InvalidArgument(
format!("Failed to convert address to script hash: {}", value),
e.to_string(),
));
},
}
},
Err(_) => {
match H160::from_str(value) {
Ok(script_hash) => return Ok(ContractParameter::h160(&script_hash)),
Err(_) => {
match value.to_uppercase().as_str() {
"NEO" => {
return create_h160_param("ef4073a0f2b305a38ec4050e4d3d28bc40ea63f5")
},
"GAS" => {
return create_h160_param("d2a4cff31913016155e38e474a2c06d08be276cf")
},
_ => {
return Err(CliError::InvalidArgument(
format!("Invalid address or script hash: {}", value),
"Please provide a valid Neo address or script hash".to_string(),
));
},
}
},
}
},
}
}
pub async fn handle_defi_command(args: DefiArgs, state: &mut CliState) -> Result<(), CliError> {
match args.command {
DefiCommands::Token { contract } => tokens::get_token_info(&contract, state).await,
DefiCommands::Balance { contract, address } => {
tokens::get_token_balance(&contract, &address, state).await
},
DefiCommands::Transfer { token, to, amount, data: _ } => {
tokens::transfer_token(&token, &to, &amount, state).await
},
DefiCommands::Flamingo { command } => match command {
FlamingoCommands::Swap { from_token, to_token, amount, min_return } => {
famous::handle_flamingo_swap(
&from_token,
&to_token,
&amount,
min_return.as_deref(),
state,
)
.await
},
FlamingoCommands::AddLiquidity { token_a, token_b, amount_a, amount_b } => {
famous::handle_flamingo_add_liquidity(
&token_a, &token_b, &amount_a, &amount_b, state,
)
.await
},
FlamingoCommands::RemoveLiquidity { token_a, token_b, liquidity } => {
famous::handle_flamingo_remove_liquidity(&token_a, &token_b, &liquidity, state)
.await
},
FlamingoCommands::Stake { token, amount } => {
famous::handle_flamingo_stake(&token, &amount, state).await
},
FlamingoCommands::ClaimRewards {} => famous::handle_flamingo_claim_rewards(state).await,
},
DefiCommands::NeoBurger { command } => match command {
NeoBurgerCommands::Wrap { amount } => {
famous::handle_neoburger_wrap(&amount, state).await
},
NeoBurgerCommands::Unwrap { amount } => {
famous::handle_neoburger_unwrap(&amount, state).await
},
NeoBurgerCommands::ClaimGas {} => famous::handle_neoburger_claim_gas(state).await,
NeoBurgerCommands::GetRate {} => famous::handle_neoburger_get_rate(state).await,
},
DefiCommands::NeoCompound { command } => match command {
NeoCompoundCommands::Deposit { token, amount } => {
famous::handle_neocompound_deposit(&token, &amount, state).await
},
NeoCompoundCommands::Withdraw { token, amount } => {
famous::handle_neocompound_withdraw(&token, &amount, state).await
},
NeoCompoundCommands::Compound { token } => {
famous::handle_neocompound_compound(&token, state).await
},
NeoCompoundCommands::GetAPY { token } => {
famous::handle_neocompound_get_apy(&token, state).await
},
},
DefiCommands::GrandShare { command } => match command {
GrandShareCommands::SubmitProposal { title, description, amount } => {
famous::handle_grandshare_submit_proposal(&title, &description, &amount, state)
.await
},
GrandShareCommands::Vote { proposal_id, approve } => {
famous::handle_grandshare_vote(proposal_id, approve, state).await
},
GrandShareCommands::FundProject { project_id, amount } => {
famous::handle_grandshare_fund_project(project_id, &amount, state).await
},
GrandShareCommands::ClaimFunds { project_id } => {
famous::handle_grandshare_claim_funds(project_id, state).await
},
},
}
}