@@ -3,7 +3,8 @@ use solana_client::rpc_config::RpcSendTransactionConfig;
33use solana_sdk:: { commitment_config:: CommitmentLevel , compute_budget:: ComputeBudgetInstruction } ;
44use solend_program:: {
55 instruction:: {
6- liquidate_obligation_and_redeem_reserve_collateral, refresh_obligation, refresh_reserve,
6+ liquidate_obligation_and_redeem_reserve_collateral, redeem_reserve_collateral,
7+ refresh_obligation, refresh_reserve,
78 } ,
89 state:: Obligation ,
910} ;
@@ -282,6 +283,27 @@ fn main() {
282283 . help ( "amount of ctokens to withdraw" ) ,
283284 )
284285 )
286+ . subcommand (
287+ SubCommand :: with_name ( "redeem-collateral" )
288+ . about ( "Redeem ctokens for tokens" )
289+ // @TODO: use is_valid_signer
290+ . arg (
291+ Arg :: with_name ( "redeem-reserve" )
292+ . long ( "redeem-reserve" )
293+ . value_name ( "RESERVE_PUBKEY" )
294+ . takes_value ( true )
295+ . required ( true )
296+ . help ( "reserve pubkey" ) ,
297+ )
298+ . arg (
299+ Arg :: with_name ( "collateral-amount" )
300+ . long ( "redeem-amount" )
301+ . value_name ( "AMOUNT" )
302+ . takes_value ( true )
303+ . required ( true )
304+ . help ( "amount of ctokens to redeem" ) ,
305+ )
306+ )
285307 . subcommand (
286308 SubCommand :: with_name ( "add-reserve" )
287309 . about ( "Add a reserve to a lending market" )
@@ -771,6 +793,12 @@ fn main() {
771793
772794 command_withdraw_collateral ( & config, obligation, withdraw_reserve, collateral_amount)
773795 }
796+ ( "redeem-collateral" , Some ( arg_matches) ) => {
797+ let redeem_reserve = pubkey_of ( arg_matches, "redeem-reserve" ) . unwrap ( ) ;
798+ let collateral_amount = value_of ( arg_matches, "collateral-amount" ) . unwrap ( ) ;
799+
800+ command_redeem_collateral ( & config, & redeem_reserve, collateral_amount)
801+ }
774802 ( "add-reserve" , Some ( arg_matches) ) => {
775803 let lending_market_owner_keypair =
776804 keypair_of ( arg_matches, "lending_market_owner" ) . unwrap ( ) ;
@@ -986,6 +1014,51 @@ fn command_create_lending_market(
9861014 Ok ( ( ) )
9871015}
9881016
1017+ #[ allow( clippy:: too_many_arguments) ]
1018+ fn command_redeem_collateral (
1019+ config : & Config ,
1020+ redeem_reserve_pubkey : & Pubkey ,
1021+ collateral_amount : u64 ,
1022+ ) -> CommandResult {
1023+ let redeem_reserve = {
1024+ let data = config
1025+ . rpc_client
1026+ . get_account ( redeem_reserve_pubkey)
1027+ . unwrap ( ) ;
1028+ Reserve :: unpack ( & data. data ) . unwrap ( )
1029+ } ;
1030+
1031+ let source_ata =
1032+ get_or_create_associated_token_address ( config, & redeem_reserve. collateral . mint_pubkey ) ;
1033+ let dest_ata =
1034+ get_or_create_associated_token_address ( config, & redeem_reserve. liquidity . mint_pubkey ) ;
1035+
1036+ let recent_blockhash = config. rpc_client . get_latest_blockhash ( ) ?;
1037+ let transaction = Transaction :: new (
1038+ & vec ! [ config. fee_payer. as_ref( ) ] ,
1039+ Message :: new_with_blockhash (
1040+ & [ redeem_reserve_collateral (
1041+ config. lending_program_id ,
1042+ collateral_amount,
1043+ source_ata,
1044+ dest_ata,
1045+ * redeem_reserve_pubkey,
1046+ redeem_reserve. collateral . mint_pubkey ,
1047+ redeem_reserve. liquidity . supply_pubkey ,
1048+ redeem_reserve. lending_market ,
1049+ config. fee_payer . pubkey ( ) ,
1050+ ) ] ,
1051+ Some ( & config. fee_payer . pubkey ( ) ) ,
1052+ & recent_blockhash,
1053+ ) ,
1054+ recent_blockhash,
1055+ ) ;
1056+
1057+ send_transaction ( config, transaction) ?;
1058+
1059+ Ok ( ( ) )
1060+ }
1061+
9891062#[ allow( clippy:: too_many_arguments) ]
9901063fn command_withdraw_collateral (
9911064 config : & Config ,
@@ -1658,7 +1731,7 @@ fn send_transaction(
16581731 CommitmentConfig :: confirmed ( ) ,
16591732 RpcSendTransactionConfig {
16601733 preflight_commitment : Some ( CommitmentLevel :: Processed ) ,
1661- skip_preflight : false ,
1734+ skip_preflight : true ,
16621735 encoding : None ,
16631736 max_retries : None ,
16641737 } ,
@@ -1687,11 +1760,9 @@ fn quote_currency_of(matches: &ArgMatches<'_>, name: &str) -> Option<[u8; 32]> {
16871760fn get_or_create_associated_token_address ( config : & Config , mint : & Pubkey ) -> Pubkey {
16881761 let ata = get_associated_token_address ( & config. fee_payer . pubkey ( ) , mint) ;
16891762
1690- if let Err ( e) = config. rpc_client . get_account ( & ata) {
1691- println ! ( "{:?}" , e) ;
1692-
1693- // create the ata
1763+ if config. rpc_client . get_account ( & ata) . is_err ( ) {
16941764 println ! ( "Creating ATA for mint {:?}" , mint) ;
1765+
16951766 let recent_blockhash = config. rpc_client . get_latest_blockhash ( ) . unwrap ( ) ;
16961767 let transaction = Transaction :: new (
16971768 & vec ! [ config. fee_payer. as_ref( ) ] ,
0 commit comments