@@ -46,6 +46,7 @@ pub mod cmds {
4646 // Inlined commands from the client.
4747 TxCustom ( TxCustom ) ,
4848 TxTransfer ( TxTransfer ) ,
49+ TxIbcTransfer ( TxIbcTransfer ) ,
4950 TxUpdateVp ( TxUpdateVp ) ,
5051 TxInitNft ( TxInitNft ) ,
5152 TxMintNft ( TxMintNft ) ,
@@ -61,6 +62,7 @@ pub mod cmds {
6162 . subcommand ( Ledger :: def ( ) )
6263 . subcommand ( TxCustom :: def ( ) )
6364 . subcommand ( TxTransfer :: def ( ) )
65+ . subcommand ( TxIbcTransfer :: def ( ) )
6466 . subcommand ( TxUpdateVp :: def ( ) )
6567 . subcommand ( TxInitNft :: def ( ) )
6668 . subcommand ( TxMintNft :: def ( ) )
@@ -75,6 +77,8 @@ pub mod cmds {
7577 let ledger = SubCmd :: parse ( matches) . map ( Self :: Ledger ) ;
7678 let tx_custom = SubCmd :: parse ( matches) . map ( Self :: TxCustom ) ;
7779 let tx_transfer = SubCmd :: parse ( matches) . map ( Self :: TxTransfer ) ;
80+ let tx_ibc_transfer =
81+ SubCmd :: parse ( matches) . map ( Self :: TxIbcTransfer ) ;
7882 let tx_update_vp = SubCmd :: parse ( matches) . map ( Self :: TxUpdateVp ) ;
7983 let tx_nft_create = SubCmd :: parse ( matches) . map ( Self :: TxInitNft ) ;
8084 let tx_nft_mint = SubCmd :: parse ( matches) . map ( Self :: TxMintNft ) ;
@@ -87,6 +91,7 @@ pub mod cmds {
8791 . or ( ledger)
8892 . or ( tx_custom)
8993 . or ( tx_transfer)
94+ . or ( tx_ibc_transfer)
9095 . or ( tx_update_vp)
9196 . or ( tx_nft_create)
9297 . or ( tx_nft_mint)
@@ -152,6 +157,7 @@ pub mod cmds {
152157 // Simple transactions
153158 . subcommand ( TxCustom :: def ( ) . display_order ( 1 ) )
154159 . subcommand ( TxTransfer :: def ( ) . display_order ( 1 ) )
160+ . subcommand ( TxIbcTransfer :: def ( ) . display_order ( 1 ) )
155161 . subcommand ( TxUpdateVp :: def ( ) . display_order ( 1 ) )
156162 . subcommand ( TxInitAccount :: def ( ) . display_order ( 1 ) )
157163 . subcommand ( TxInitValidator :: def ( ) . display_order ( 1 ) )
@@ -184,6 +190,7 @@ pub mod cmds {
184190 use AnomaClientWithContext :: * ;
185191 let tx_custom = Self :: parse_with_ctx ( matches, TxCustom ) ;
186192 let tx_transfer = Self :: parse_with_ctx ( matches, TxTransfer ) ;
193+ let tx_ibc_transfer = Self :: parse_with_ctx ( matches, TxIbcTransfer ) ;
187194 let tx_update_vp = Self :: parse_with_ctx ( matches, TxUpdateVp ) ;
188195 let tx_init_account = Self :: parse_with_ctx ( matches, TxInitAccount ) ;
189196 let tx_init_validator =
@@ -213,6 +220,7 @@ pub mod cmds {
213220 let utils = SubCmd :: parse ( matches) . map ( Self :: WithoutContext ) ;
214221 tx_custom
215222 . or ( tx_transfer)
223+ . or ( tx_ibc_transfer)
216224 . or ( tx_update_vp)
217225 . or ( tx_init_account)
218226 . or ( tx_init_validator)
@@ -271,6 +279,7 @@ pub mod cmds {
271279 // Ledger cmds
272280 TxCustom ( TxCustom ) ,
273281 TxTransfer ( TxTransfer ) ,
282+ TxIbcTransfer ( TxIbcTransfer ) ,
274283 QueryResult ( QueryResult ) ,
275284 TxUpdateVp ( TxUpdateVp ) ,
276285 TxInitAccount ( TxInitAccount ) ,
@@ -794,6 +803,25 @@ pub mod cmds {
794803 }
795804 }
796805
806+ #[ derive( Clone , Debug ) ]
807+ pub struct TxIbcTransfer ( pub args:: TxIbcTransfer ) ;
808+
809+ impl SubCmd for TxIbcTransfer {
810+ const CMD : & ' static str = "ibc-transfer" ;
811+
812+ fn parse ( matches : & ArgMatches ) -> Option < Self > {
813+ matches. subcommand_matches ( Self :: CMD ) . map ( |matches| {
814+ TxIbcTransfer ( args:: TxIbcTransfer :: parse ( matches) )
815+ } )
816+ }
817+
818+ fn def ( ) -> App {
819+ App :: new ( Self :: CMD )
820+ . about ( "Send a signed IBC transfer transaction." )
821+ . add_args :: < args:: TxIbcTransfer > ( )
822+ }
823+ }
824+
797825 #[ derive( Clone , Debug ) ]
798826 pub struct TxUpdateVp ( pub args:: TxUpdateVp ) ;
799827
@@ -1248,6 +1276,7 @@ pub mod args {
12481276 use std:: path:: PathBuf ;
12491277 use std:: str:: FromStr ;
12501278
1279+ use namada:: ibc:: core:: ics24_host:: identifier:: { ChannelId , PortId } ;
12511280 use namada:: types:: address:: Address ;
12521281 use namada:: types:: chain:: { ChainId , ChainIdPrefix } ;
12531282 use namada:: types:: governance:: ProposalVote ;
@@ -1281,6 +1310,7 @@ pub mod args {
12811310 const CHAIN_ID : Arg < ChainId > = arg ( "chain-id" ) ;
12821311 const CHAIN_ID_OPT : ArgOpt < ChainId > = CHAIN_ID . opt ( ) ;
12831312 const CHAIN_ID_PREFIX : Arg < ChainIdPrefix > = arg ( "chain-prefix" ) ;
1313+ const CHANNEL_ID : Arg < ChannelId > = arg ( "channel-id" ) ;
12841314 const CODE_PATH : Arg < PathBuf > = arg ( "code-path" ) ;
12851315 const CODE_PATH_OPT : ArgOpt < PathBuf > = CODE_PATH . opt ( ) ;
12861316 const CONSENSUS_TIMEOUT_COMMIT : ArgDefault < Timeout > = arg_default (
@@ -1318,6 +1348,10 @@ pub mod args {
13181348 const NET_ADDRESS : Arg < SocketAddr > = arg ( "net-address" ) ;
13191349 const NFT_ADDRESS : Arg < Address > = arg ( "nft-address" ) ;
13201350 const OWNER : ArgOpt < WalletAddress > = arg_opt ( "owner" ) ;
1351+ const PORT_ID : ArgDefault < PortId > = arg_default (
1352+ "port-id" ,
1353+ DefaultFn ( || PortId :: from_str ( "transfer" ) . unwrap ( ) ) ,
1354+ ) ;
13211355 const PROPOSAL_OFFLINE : ArgFlag = flag ( "offline" ) ;
13221356 const PROTOCOL_KEY : ArgOpt < WalletPublicKey > = arg_opt ( "protocol-key" ) ;
13231357 const PRE_GENESIS_PATH : ArgOpt < PathBuf > = arg_opt ( "pre-genesis-path" ) ;
@@ -1328,6 +1362,7 @@ pub mod args {
13281362 const RAW_ADDRESS : Arg < Address > = arg ( "address" ) ;
13291363 const RAW_ADDRESS_OPT : ArgOpt < Address > = RAW_ADDRESS . opt ( ) ;
13301364 const RAW_PUBLIC_KEY_OPT : ArgOpt < common:: PublicKey > = arg_opt ( "public-key" ) ;
1365+ const RECEIVER : Arg < String > = arg ( "receiver" ) ;
13311366 const REWARDS_CODE_PATH : ArgOpt < PathBuf > = arg_opt ( "rewards-code-path" ) ;
13321367 const REWARDS_KEY : ArgOpt < WalletPublicKey > = arg_opt ( "rewards-key" ) ;
13331368 const SCHEME : ArgDefault < SchemeType > =
@@ -1340,6 +1375,8 @@ pub mod args {
13401375 const STORAGE_KEY : Arg < storage:: Key > = arg ( "storage-key" ) ;
13411376 const SUB_PREFIX : ArgOpt < String > = arg_opt ( "sub-prefix" ) ;
13421377 const TARGET : Arg < WalletAddress > = arg ( "target" ) ;
1378+ const TIMEOUT_HEIGHT : ArgOpt < u64 > = arg_opt ( "timeout-height" ) ;
1379+ const TIMEOUT_SEC_OFFSET : ArgOpt < u64 > = arg_opt ( "timeout-sec-offset" ) ;
13431380 const TOKEN_OPT : ArgOpt < WalletAddress > = TOKEN . opt ( ) ;
13441381 const TOKEN : Arg < WalletAddress > = arg ( "token" ) ;
13451382 const TX_HASH : Arg < String > = arg ( "tx-hash" ) ;
@@ -1515,6 +1552,80 @@ pub mod args {
15151552 }
15161553 }
15171554
1555+ /// IBC transfer transaction arguments
1556+ #[ derive( Clone , Debug ) ]
1557+ pub struct TxIbcTransfer {
1558+ /// Common tx arguments
1559+ pub tx : Tx ,
1560+ /// Transfer source address
1561+ pub source : WalletAddress ,
1562+ /// Transfer target address
1563+ pub receiver : String ,
1564+ /// Transferred token address
1565+ pub token : WalletAddress ,
1566+ /// Transferred token address
1567+ pub sub_prefix : Option < String > ,
1568+ /// Transferred token amount
1569+ pub amount : token:: Amount ,
1570+ /// Port ID
1571+ pub port_id : PortId ,
1572+ /// Channel ID
1573+ pub channel_id : ChannelId ,
1574+ /// Timeout height of the destination chain
1575+ pub timeout_height : Option < u64 > ,
1576+ /// Timeout timestamp offset
1577+ pub timeout_sec_offset : Option < u64 > ,
1578+ }
1579+
1580+ impl Args for TxIbcTransfer {
1581+ fn parse ( matches : & ArgMatches ) -> Self {
1582+ let tx = Tx :: parse ( matches) ;
1583+ let source = SOURCE . parse ( matches) ;
1584+ let receiver = RECEIVER . parse ( matches) ;
1585+ let token = TOKEN . parse ( matches) ;
1586+ let sub_prefix = SUB_PREFIX . parse ( matches) ;
1587+ let amount = AMOUNT . parse ( matches) ;
1588+ let port_id = PORT_ID . parse ( matches) ;
1589+ let channel_id = CHANNEL_ID . parse ( matches) ;
1590+ let timeout_height = TIMEOUT_HEIGHT . parse ( matches) ;
1591+ let timeout_sec_offset = TIMEOUT_SEC_OFFSET . parse ( matches) ;
1592+ Self {
1593+ tx,
1594+ source,
1595+ receiver,
1596+ token,
1597+ sub_prefix,
1598+ amount,
1599+ port_id,
1600+ channel_id,
1601+ timeout_height,
1602+ timeout_sec_offset,
1603+ }
1604+ }
1605+
1606+ fn def ( app : App ) -> App {
1607+ app. add_args :: < Tx > ( )
1608+ . arg ( SOURCE . def ( ) . about (
1609+ "The source account address. The source's key is used to \
1610+ produce the signature.",
1611+ ) )
1612+ . arg ( RECEIVER . def ( ) . about (
1613+ "The receiver address on the destination chain as string." ,
1614+ ) )
1615+ . arg ( TOKEN . def ( ) . about ( "The transfer token." ) )
1616+ . arg ( SUB_PREFIX . def ( ) . about ( "The token's sub prefix." ) )
1617+ . arg ( AMOUNT . def ( ) . about ( "The amount to transfer in decimal." ) )
1618+ . arg ( PORT_ID . def ( ) . about ( "The port ID." ) )
1619+ . arg ( CHANNEL_ID . def ( ) . about ( "The channel ID." ) )
1620+ . arg (
1621+ TIMEOUT_HEIGHT
1622+ . def ( )
1623+ . about ( "The timeout height of the destination chain." ) ,
1624+ )
1625+ . arg ( TIMEOUT_SEC_OFFSET . def ( ) . about ( "The timeout as seconds." ) )
1626+ }
1627+ }
1628+
15181629 /// Transaction to initialize a new account
15191630 #[ derive( Clone , Debug ) ]
15201631 pub struct TxInitAccount {
0 commit comments