@@ -4415,7 +4415,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
4415
4415
. takes_value ( true )
4416
4416
. global ( true )
4417
4417
. validator ( is_url)
4418
- . help ( "Helium JSON RPC URL to use only for the proprietary getPriorityFeeEstimate RPC method" ) ,
4418
+ . help ( "Helius JSON RPC URL to use only for the proprietary getPriorityFeeEstimate RPC method" ) ,
4419
4419
)
4420
4420
. arg (
4421
4421
Arg :: with_name ( "verbose" )
@@ -5129,7 +5129,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
5129
5129
. setting ( AppSettings :: InferSubcommands )
5130
5130
. subcommand (
5131
5131
SubCommand :: with_name ( "swap" )
5132
- . about ( "Swap lots in the local database only " )
5132
+ . about ( "Swap lots" )
5133
5133
. arg (
5134
5134
Arg :: with_name ( "lot_number1" )
5135
5135
. value_name ( "LOT NUMBER" )
@@ -5147,6 +5147,27 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
5147
5147
. help ( "Second lot number" ) ,
5148
5148
)
5149
5149
)
5150
+ . subcommand (
5151
+ SubCommand :: with_name ( "collect" )
5152
+ . about ( "Collect non-disposed lots of a desired type into an address" )
5153
+ . arg (
5154
+ Arg :: with_name ( "token" )
5155
+ . value_name ( "SOL or SPL Token" )
5156
+ . takes_value ( true )
5157
+ . required ( true )
5158
+ . validator ( is_valid_token_or_sol)
5159
+ . help ( "Token type" ) ,
5160
+ )
5161
+ . arg (
5162
+ Arg :: with_name ( "address" )
5163
+ . value_name ( "ADDRESS" )
5164
+ . takes_value ( true )
5165
+ . required ( true )
5166
+ . validator ( is_valid_pubkey)
5167
+ . help ( "Account address" ) ,
5168
+ )
5169
+ . arg ( lot_selection_arg ( ) )
5170
+ )
5150
5171
. subcommand (
5151
5172
SubCommand :: with_name ( "delete" )
5152
5173
. about ( "Delete a lot from the local database only. \
@@ -5169,7 +5190,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
5169
5190
)
5170
5191
. subcommand (
5171
5192
SubCommand :: with_name ( "move" )
5172
- . about ( "Move a lot to a new addresses in the local database only . \
5193
+ . about ( "Move a lot to a new address . \
5173
5194
Useful if the on-chain state is out of sync with the database")
5174
5195
. arg (
5175
5196
Arg :: with_name ( "lot_number" )
@@ -6145,6 +6166,56 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
6145
6166
println ! ( "Swapping lots {lot_number1} and {lot_number2}" ) ;
6146
6167
db. swap_lots ( lot_number1, lot_number2) ?;
6147
6168
}
6169
+ ( "collect" , Some ( arg_matches) ) => {
6170
+ let address = pubkey_of ( arg_matches, "address" ) . unwrap ( ) ;
6171
+ let token = MaybeToken :: from ( value_t ! ( arg_matches, "token" , Token ) . ok ( ) ) ;
6172
+ let lot_selection_method =
6173
+ value_t_or_exit ! ( arg_matches, "lot_selection" , LotSelectionMethod ) ;
6174
+
6175
+ println ! (
6176
+ "Collecting {lot_selection_method:?} lots for {address} ({})" ,
6177
+ token. name( )
6178
+ ) ;
6179
+ loop {
6180
+ let mut current_lots = vec ! [ ] ;
6181
+ let mut candidate_lots = vec ! [ ] ;
6182
+ for account in db. get_accounts ( ) {
6183
+ if ( account. token == token)
6184
+ || ( token. is_sol_or_wsol ( ) && account. token . is_sol_or_wsol ( ) )
6185
+ {
6186
+ if account. address == address && account. token == token {
6187
+ assert ! ( current_lots. is_empty( ) ) ;
6188
+ current_lots = account. lots ;
6189
+ } else {
6190
+ candidate_lots. extend ( account. lots ) ;
6191
+ }
6192
+ }
6193
+ }
6194
+
6195
+ sort_lots_by_selection_method ( & mut current_lots, lot_selection_method) ;
6196
+ sort_lots_by_selection_method ( & mut candidate_lots, lot_selection_method) ;
6197
+
6198
+ while !current_lots. is_empty ( ) && !candidate_lots. is_empty ( ) {
6199
+ if lot_selection_method. cmp_lots ( & current_lots[ 0 ] , & candidate_lots[ 0 ] )
6200
+ == std:: cmp:: Ordering :: Greater
6201
+ {
6202
+ break ;
6203
+ }
6204
+ current_lots. remove ( 0 ) ;
6205
+ }
6206
+
6207
+ if current_lots. is_empty ( ) || candidate_lots. is_empty ( ) {
6208
+ println ! ( "Done" ) ;
6209
+ break ;
6210
+ }
6211
+
6212
+ println ! (
6213
+ "Swapping lots {} and {}" ,
6214
+ current_lots[ 0 ] . lot_number, candidate_lots[ 0 ] . lot_number
6215
+ ) ;
6216
+ db. swap_lots ( current_lots[ 0 ] . lot_number , candidate_lots[ 0 ] . lot_number ) ?;
6217
+ }
6218
+ }
6148
6219
( "move" , Some ( arg_matches) ) => {
6149
6220
let lot_number = value_t_or_exit ! ( arg_matches, "lot_number" , usize ) ;
6150
6221
let to_address =
0 commit comments