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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::{
api::message_builder::ClientMessageBuilder,
node::{OutputType, OutputsOptions},
Client, Result,
};
use bee_message::constants::INPUT_OUTPUT_COUNT_MAX;
use crypto::keys::slip10::Seed;
use std::ops::Range;
pub async fn consolidate_funds(
client: &Client,
seed: &Seed,
account_index: usize,
address_range: Range<usize>,
) -> Result<String> {
let addresses = client
.get_addresses(seed)
.with_account_index(account_index)
.with_range(address_range.clone())
.finish()
.await?;
let consolidation_address = addresses[0].clone();
let mut last_transfer_index = address_range.start;
let offset = address_range.start;
'consolidation: loop {
let mut message_ids = Vec::new();
for (index, address) in addresses.iter().enumerate().rev() {
let index = index + offset;
let signature_locked_outputs = client
.get_address()
.outputs(
address,
OutputsOptions {
include_spent: false,
output_type: Some(OutputType::SignatureLockedSingle),
},
)
.await?;
let dust_allowance_outputs = client
.get_address()
.outputs(
address,
OutputsOptions {
include_spent: false,
output_type: Some(OutputType::SignatureLockedDustAllowance),
},
)
.await?;
let mut output_with_metadata = Vec::new();
for out in signature_locked_outputs.iter().chain(dust_allowance_outputs.iter()) {
let output_metadata = client.get_output(out).await?;
let (amount, _output_address, _check_treshold) =
ClientMessageBuilder::get_output_amount_and_address(&output_metadata.output)?;
output_with_metadata.push((out.clone(), amount));
}
if !output_with_metadata.is_empty() {
if last_transfer_index == index {
if output_with_metadata.len() < 2 {
break 'consolidation;
}
} else {
last_transfer_index = index;
}
}
let outputs_chunks = output_with_metadata.chunks(INPUT_OUTPUT_COUNT_MAX);
for chunk in outputs_chunks {
let mut message_builder = client.message().with_seed(seed);
let mut total_amount = 0;
for (input, amount) in chunk {
message_builder = message_builder.with_input(input.clone());
total_amount += amount;
}
let message = message_builder
.with_input_range(index..index + 1)
.with_output(&consolidation_address, total_amount)?
.with_initial_address_index(0)
.finish()
.await?;
message_ids.push(message.id().0);
}
}
if message_ids.is_empty() {
break 'consolidation;
}
for message_id in message_ids {
let _ = client.retry_until_included(&message_id, None, None).await?;
}
}
Ok(consolidation_address)
}