1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use std::str::FromStr as _;

use crate::rpc::{self, prelude::*};
use crate::shim::address::{Address, StrictAddress};
use crate::shim::econ::TokenAmount;
use crate::shim::message::{Message, METHOD_SEND};
use anyhow::Context as _;
use num::Zero as _;

use crate::cli::humantoken;

#[derive(Debug, clap::Args)]
pub struct SendCommand {
    /// optionally specify the account to send funds from (otherwise the default
    /// one will be used)
    #[arg(long)]
    from: Option<String>,
    target_address: String,
    #[arg(value_parser = humantoken::parse)]
    amount: TokenAmount,
    #[arg(long, value_parser = humantoken::parse, default_value_t = TokenAmount::zero())]
    gas_feecap: TokenAmount,
    /// In milliGas
    #[arg(long, default_value_t = 0)]
    gas_limit: i64,
    #[arg(long, value_parser = humantoken::parse, default_value_t = TokenAmount::zero())]
    gas_premium: TokenAmount,
}

impl SendCommand {
    pub async fn run(self, client: rpc::Client) -> anyhow::Result<()> {
        eprintln!(
            "This command has been deprecated and will be removed in the future.\n\
             Please use the 'forest-wallet' executable instead."
        );

        let from: Address = if let Some(from) = &self.from {
            StrictAddress::from_str(from)?.into()
        } else {
            WalletDefaultAddress::call(&client, ())
                .await?
                .context("No default wallet address selected. Please set a default address.")?
        };

        let message = Message {
            from,
            to: StrictAddress::from_str(&self.target_address)?.into(),
            value: self.amount.clone(),
            method_num: METHOD_SEND,
            gas_limit: self.gas_limit as u64,
            gas_fee_cap: self.gas_feecap.clone(),
            gas_premium: self.gas_premium.clone(),
            // JANK(aatifsyed): Why are we using a testing build of fvm_shared?
            ..Default::default()
        };

        let signed_msg = MpoolPushMessage::call(&client, (message, None)).await?;

        println!("{}", signed_msg.cid());

        Ok(())
    }
}