Skip to main content

cast/cmd/tip20/
mod.rs

1use crate::tx::{SendTxOpts, TxParams};
2use alloy_ens::NameOrAddress;
3use alloy_primitives::{Address, B256};
4use clap::Parser;
5use std::str::FromStr;
6
7mod create;
8pub(crate) use create::iso4217_warning_message;
9pub(crate) mod mine;
10
11/// TIP-20 token operations (Tempo).
12#[derive(Debug, Parser, Clone)]
13pub enum Tip20Subcommand {
14    /// Create a new TIP-20 token via the TIP20Factory.
15    #[command(visible_alias = "c")]
16    Create {
17        /// The token name (e.g. "US Dollar Coin").
18        name: String,
19
20        /// The token symbol (e.g. "USDC").
21        symbol: String,
22
23        /// The ISO 4217 currency code (e.g. "USD", "EUR", "GBP").
24        /// This field is IMMUTABLE after creation and affects fee payment
25        /// eligibility, DEX routing, and quote token pairing.
26        currency: String,
27
28        /// The TIP-20 quote token address used for exchange pricing.
29        #[arg(value_parser = NameOrAddress::from_str)]
30        quote_token: NameOrAddress,
31
32        /// The admin address to receive DEFAULT_ADMIN_ROLE on the new token.
33        #[arg(value_parser = NameOrAddress::from_str)]
34        admin: NameOrAddress,
35
36        /// A unique salt for deterministic address derivation (hex-encoded bytes32).
37        salt: B256,
38
39        /// Skip the ISO 4217 currency code validation warning.
40        #[arg(long)]
41        force: bool,
42
43        #[command(flatten)]
44        send_tx: SendTxOpts,
45
46        #[command(flatten)]
47        tx: TxParams,
48    },
49
50    /// Mine a TIP-1022 salt for virtual address' master registration on Tempo.
51    #[command(visible_alias = "m")]
52    Mine {
53        /// Address that will call `registerVirtualMaster(bytes32)`.
54        #[arg(value_name = "ADDRESS")]
55        master: Address,
56
57        /// Salt to validate directly instead of mining one.
58        #[arg(long, conflicts_with_all = ["seed", "no_random"], value_name = "HEX")]
59        salt: Option<B256>,
60
61        /// Number of threads to use. Specifying 0 defaults to the number of logical cores.
62        #[arg(global = true, long, short = 'j', visible_alias = "jobs")]
63        threads: Option<usize>,
64
65        /// The random number generator's seed, used to initialize the salt search.
66        #[arg(long, value_name = "HEX")]
67        seed: Option<B256>,
68
69        /// Don't initialize the salt with a random value, and instead use the default value of 0.
70        #[arg(long, conflicts_with = "seed")]
71        no_random: bool,
72
73        /// Submit `registerVirtualMaster(bytes32)` on Tempo after finding or validating the salt.
74        #[arg(long, conflicts_with_all = ["seed", "no_random"])]
75        register: bool,
76
77        #[command(flatten)]
78        send_tx: SendTxOpts,
79
80        #[command(flatten)]
81        tx: TxParams,
82    },
83}
84
85impl Tip20Subcommand {
86    pub async fn run(self) -> eyre::Result<()> {
87        match self {
88            Self::Create {
89                name,
90                symbol,
91                currency,
92                quote_token,
93                admin,
94                salt,
95                force,
96                send_tx,
97                tx,
98            } => {
99                create::run(name, symbol, currency, quote_token, admin, salt, force, send_tx, tx)
100                    .await?;
101            }
102            Self::Mine { master, salt, threads, seed, no_random, register, send_tx, tx } => {
103                let output = mine::run(master, salt, threads, seed, no_random)?;
104                if register {
105                    mine::register(master, output.salt, send_tx, tx).await?;
106                }
107            }
108        }
109        Ok(())
110    }
111}