Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex6323 committed Apr 30, 2024
1 parent 5de120c commit a9100c3
Show file tree
Hide file tree
Showing 26 changed files with 204 additions and 236 deletions.
2 changes: 1 addition & 1 deletion bindings/python/iota_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
from .types.native_token import *
from .types.node_info import *
from .types.output import *
from .types.output_data import *
from .types.output_id import *
from .types.output_id_proof import *
from .types.output_metadata import *
from .types.output_params import *
from .types.output_with_extended_metadata import *
from .types.payload import *
from .types.send_params import *
from .types.slot import *
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/iota_sdk/wallet/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
from iota_sdk.types.filter_options import FilterOptions
from iota_sdk.types.native_token import NativeToken
from iota_sdk.types.output import BasicOutput, NftOutput, Output, deserialize_output
from iota_sdk.types.output_data import OutputData
from iota_sdk.types.output_id import OutputId
from iota_sdk.types.output_params import OutputParams
from iota_sdk.types.output_with_extended_metadata import OutputData
from iota_sdk.types.transaction_data import PreparedTransactionData, SignedTransactionData
from iota_sdk.types.transaction_id import TransactionId
from iota_sdk.types.send_params import BeginStakingParams, CreateAccountOutputParams, CreateDelegationParams, CreateNativeTokenParams, MintNftParams, SendManaParams, SendNativeTokenParams, SendNftParams, SendParams
Expand Down
34 changes: 15 additions & 19 deletions cli/src/wallet_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1389,38 +1389,38 @@ async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> {
let mut delegations = Vec::new();
let mut anchors = Vec::new();

for output_with_ext_metadata in wallet.ledger().await.unspent_outputs().values() {
let output_id = output_with_ext_metadata.output_id;
for output_data in wallet.ledger().await.unspent_outputs().values() {
let output_id = output_data.output_id;
output_ids.push(output_id);

// Output might be associated with the address, but can't be unlocked by it, so we check that here.
let required_address = &output_with_ext_metadata
let required_address = &output_data
.output
.required_address(slot_index, protocol_parameters.committable_age_range())?;

if required_address
.as_ref()
.is_some_and(|required_address| required_address == address.inner())
{
if let Some(nt) = output_with_ext_metadata.output.native_token() {
if let Some(nt) = output_data.output.native_token() {
native_tokens.add_native_token(*nt)?;
}
match &output_with_ext_metadata.output {
match &output_data.output {
Output::Basic(_) => {}
Output::Account(account) => accounts.push(account.account_id_non_null(&output_id)),
Output::Foundry(foundry) => foundries.push(foundry.id()),
Output::Nft(nft) => nfts.push(nft.nft_id_non_null(&output_id)),
Output::Delegation(delegation) => delegations.push(delegation.delegation_id_non_null(&output_id)),
Output::Anchor(anchor) => anchors.push(anchor.anchor_id_non_null(&output_id)),
}
let sdr_amount = output_with_ext_metadata
let sdr_amount = output_data
.output
.unlock_conditions()
.storage_deposit_return()
.map(|sdr| sdr.amount())
.unwrap_or(0);

amount += output_with_ext_metadata.output.amount() - sdr_amount;
amount += output_data.output.amount() - sdr_amount;
}
}

Expand Down Expand Up @@ -1765,30 +1765,26 @@ pub async fn prompt_internal(
Ok(PromptResponse::Reprompt)
}

fn print_outputs(mut outputs_with_ext_metadata: Vec<OutputData>, title: &str) -> Result<(), Error> {
if outputs_with_ext_metadata.is_empty() {
fn print_outputs(mut outputs_data: Vec<OutputData>, title: &str) -> Result<(), Error> {
if outputs_data.is_empty() {
println_log_info!("No outputs found");
} else {
println_log_info!("{title}");
outputs_with_ext_metadata.sort_unstable_by_key(|o| o.output_id);
outputs_data.sort_unstable_by_key(|o| o.output_id);

for (i, output_with_ext_metadata) in outputs_with_ext_metadata.into_iter().enumerate() {
let kind_str = if output_with_ext_metadata.output.is_implicit_account() {
for (i, output_data) in outputs_data.into_iter().enumerate() {
let kind_str = if output_data.output.is_implicit_account() {
"ImplicitAccount"
} else {
output_with_ext_metadata.output.kind_str()
output_data.output.kind_str()
};

println_log_info!(
"{:<5}{} {:<16}{}",
i,
&output_with_ext_metadata.output_id,
&output_data.output_id,
kind_str,
if output_with_ext_metadata.is_spent() {
"Spent"
} else {
"Unspent"
},
if output_data.is_spent() { "Spent" } else { "Unspent" },
);
}
}
Expand Down
12 changes: 6 additions & 6 deletions sdk/examples/how_tos/wallet/consolidate_outputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.unspent_outputs()
.values()
.enumerate()
.for_each(|(i, output_with_ext_metadata)| {
.for_each(|(i, output_data)| {
println!("OUTPUT #{i}");
println!(
"- amount: {:?}\n- native tokens: {:?}",
output_with_ext_metadata.output.amount(),
output_with_ext_metadata.output.native_token()
output_data.output.amount(),
output_data.output.native_token()
)
});

Expand Down Expand Up @@ -91,12 +91,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.unspent_outputs()
.values()
.enumerate()
.for_each(|(i, output_with_ext_metadata)| {
.for_each(|(i, output_data)| {
println!("OUTPUT #{i}");
println!(
"- amount: {:?}\n- native tokens: {:?}",
output_with_ext_metadata.output.amount(),
output_with_ext_metadata.output.native_token()
output_data.output.amount(),
output_data.output.native_token()
)
});

Expand Down
10 changes: 5 additions & 5 deletions sdk/src/wallet/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,14 @@ impl WalletLedger {
pub fn implicit_accounts(&self) -> impl Iterator<Item = &OutputData> {
self.unspent_outputs
.values()
.filter(|output_with_ext_metadata| output_with_ext_metadata.output.is_implicit_account())
.filter(|output_data| output_data.output.is_implicit_account())
}

/// Returns accounts of the wallet.
pub fn accounts(&self) -> impl Iterator<Item = &OutputData> {
self.unspent_outputs
.values()
.filter(|output_with_ext_metadata| output_with_ext_metadata.output.is_account())
.filter(|output_data| output_data.output.is_account())
}

// Returns the first possible unexpired block issuer Account id, which can be an implicit account.
Expand Down Expand Up @@ -382,10 +382,10 @@ impl<S: 'static + SecretManage> Wallet<S> {
pub async fn get_foundry_output(&self, native_token_id: TokenId) -> Result<Output, WalletError> {
let foundry_id = FoundryId::from(native_token_id);

for output_with_ext_metadata in self.ledger.read().await.outputs.values() {
if let Output::Foundry(foundry_output) = &output_with_ext_metadata.output {
for output_data in self.ledger.read().await.outputs.values() {
if let Output::Foundry(foundry_output) = &output_data.output {
if foundry_output.id() == foundry_id {
return Ok(output_with_ext_metadata.output.clone());
return Ok(output_data.output.clone());
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions sdk/src/wallet/operations/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ impl<S: 'static + SecretManage> Wallet<S> {

let mut reward_outputs = HashSet::new();

for (output_id, output_with_ext_metadata) in &wallet_ledger.unspent_outputs {
for (output_id, output_data) in &wallet_ledger.unspent_outputs {
// Check if output is from the network we're currently connected to
if output_with_ext_metadata.network_id != network_id {
if output_data.network_id != network_id {
continue;
}

let output = &output_with_ext_metadata.output;
let output = &output_data.output;
let storage_cost = output.minimum_amount(storage_score_params);

// Add account, foundry, and delegation outputs here because they can't have a
Expand Down Expand Up @@ -266,17 +266,17 @@ impl<S: 'static + SecretManage> Wallet<S> {
if balance.potentially_locked_outputs.contains_key(locked_output) {
continue;
}
if let Some(output_with_ext_metadata) = wallet_ledger.unspent_outputs.get(locked_output) {
if let Some(output_data) = wallet_ledger.unspent_outputs.get(locked_output) {
// Only check outputs that are in this network
if output_with_ext_metadata.network_id == network_id {
locked_amount += output_with_ext_metadata.output.amount();
locked_mana += output_with_ext_metadata.output.decayed_mana(
if output_data.network_id == network_id {
locked_amount += output_data.output.amount();
locked_mana += output_data.output.decayed_mana(
&protocol_parameters,
output_with_ext_metadata.output_id.transaction_id().slot_index(),
output_data.output_id.transaction_id().slot_index(),
slot_index,
)?;

if let Some(native_token) = output_with_ext_metadata.output.native_token() {
if let Some(native_token) = output_data.output.native_token() {
locked_native_tokens.add_native_token(*native_token)?;
}
}
Expand Down
6 changes: 3 additions & 3 deletions sdk/src/wallet/operations/helpers/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ use crate::{
// Check if an output can be unlocked by one of the provided addresses at the current time
pub(crate) fn can_output_be_unlocked_now(
controlled_addresses: &HashSet<Address>,
output_with_ext_metadata: &OutputData,
output_data: &OutputData,
commitment_slot_index: impl Into<SlotIndex> + Copy,
committable_age_range: CommittableAgeRange,
) -> Result<bool, WalletError> {
if output_with_ext_metadata
if output_data
.output
.unlock_conditions()
.is_timelocked(commitment_slot_index, committable_age_range.min)
{
return Ok(false);
}

let required_address = output_with_ext_metadata
let required_address = output_data
.output
.required_address(commitment_slot_index.into(), committable_age_range)?;

Expand Down
54 changes: 25 additions & 29 deletions sdk/src/wallet/operations/output_claiming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl WalletLedger {

// Get outputs for the claim
let mut output_ids_to_claim: HashSet<OutputId> = HashSet::new();
for (output_id, output_with_ext_metadata) in self
for (output_id, output_data) in self
.unspent_outputs
.iter()
.filter(|(_, o)| o.output.is_basic() || o.output.is_nft())
Expand All @@ -68,71 +68,67 @@ impl WalletLedger {
// If there is a single [UnlockCondition], then it's an
// [AddressUnlockCondition] and we own it already without
// further restrictions
if output_with_ext_metadata.output.unlock_conditions().len() != 1
if output_data.output.unlock_conditions().len() != 1
&& can_output_be_unlocked_now(
// We use the addresses with unspent outputs, because other addresses of the
// account without unspent outputs can't be related to this output
&controlled_addresses,
output_with_ext_metadata,
output_data,
slot_index,
protocol_parameters.committable_age_range(),
)?
{
match outputs_to_claim {
OutputsToClaim::MicroTransactions => {
if let Some(sdr) = output_with_ext_metadata
.output
.unlock_conditions()
.storage_deposit_return()
{
if let Some(sdr) = output_data.output.unlock_conditions().storage_deposit_return() {
// If expired, it's not a micro transaction anymore
match output_with_ext_metadata
match output_data
.output
.unlock_conditions()
.is_expired(slot_index, protocol_parameters.committable_age_range())
{
Some(false) => {
// Only micro transaction if not the same amount needs to be returned
// (resulting in 0 amount to claim)
if sdr.amount() != output_with_ext_metadata.output.amount() {
output_ids_to_claim.insert(output_with_ext_metadata.output_id);
if sdr.amount() != output_data.output.amount() {
output_ids_to_claim.insert(output_data.output_id);
}
}
_ => continue,
}
}
}
OutputsToClaim::NativeTokens => {
if output_with_ext_metadata.output.native_token().is_some() {
output_ids_to_claim.insert(output_with_ext_metadata.output_id);
if output_data.output.native_token().is_some() {
output_ids_to_claim.insert(output_data.output_id);
}
}
OutputsToClaim::Nfts => {
if output_with_ext_metadata.output.is_nft() {
output_ids_to_claim.insert(output_with_ext_metadata.output_id);
if output_data.output.is_nft() {
output_ids_to_claim.insert(output_data.output_id);
}
}
OutputsToClaim::Amount => {
let mut claimable_amount = output_with_ext_metadata.output.amount();
if output_with_ext_metadata
let mut claimable_amount = output_data.output.amount();
if output_data
.output
.unlock_conditions()
.is_expired(slot_index, protocol_parameters.committable_age_range())
== Some(false)
{
claimable_amount -= output_with_ext_metadata
claimable_amount -= output_data
.output
.unlock_conditions()
.storage_deposit_return()
.map(|s| s.amount())
.unwrap_or_default()
};
if claimable_amount > 0 {
output_ids_to_claim.insert(output_with_ext_metadata.output_id);
output_ids_to_claim.insert(output_data.output_id);
}
}
OutputsToClaim::All => {
output_ids_to_claim.insert(output_with_ext_metadata.output_id);
output_ids_to_claim.insert(output_data.output_id);
}
}
}
Expand Down Expand Up @@ -201,11 +197,11 @@ where

// Get basic outputs only with AddressUnlockCondition and no other unlock condition
let mut basic_outputs: Vec<OutputData> = Vec::new();
for (output_id, output_with_ext_metadata) in &wallet_ledger.unspent_outputs {
for (output_id, output_data) in &wallet_ledger.unspent_outputs {
#[cfg(feature = "participation")]
if let Some(ref voting_output) = voting_output {
// Remove voting output from inputs, because we don't want to spent it to claim something else.
if output_with_ext_metadata.output_id == voting_output.output_id {
if output_data.output_id == voting_output.output_id {
continue;
}
}
Expand All @@ -218,7 +214,7 @@ where
if !a.address().is_implicit_account_creation() {
// Store outputs with [`AddressUnlockCondition`] alone, because they could be used as
// additional input, if required
basic_outputs.push(output_with_ext_metadata.clone());
basic_outputs.push(output_data.clone());
}
}
}
Expand Down Expand Up @@ -269,9 +265,9 @@ where

let mut outputs_to_claim = Vec::new();
for output_id in output_ids_to_claim {
if let Some(output_with_extended_metadata) = wallet_ledger.unspent_outputs.get(&output_id) {
if let Some(output_data) = wallet_ledger.unspent_outputs.get(&output_id) {
if !wallet_ledger.locked_outputs.contains(&output_id) {
outputs_to_claim.push(output_with_extended_metadata.clone());
outputs_to_claim.push(output_data.clone());
}
}
}
Expand All @@ -295,22 +291,22 @@ where
.sum::<u64>()
>= BasicOutput::minimum_amount(&Address::from(Ed25519Address::null()), storage_score_params);

for output_with_ext_metadata in &outputs_to_claim {
if let Output::Nft(nft_output) = &output_with_ext_metadata.output {
for output_data in &outputs_to_claim {
if let Output::Nft(nft_output) = &output_data.output {
// build new output with same amount, nft_id, immutable/feature blocks and native tokens, just
// updated address unlock conditions

let nft_output = if !enough_amount_for_basic_output {
// Only update address and nft id if we have no additional inputs which can provide the storage
// deposit for the remaining amount and possible native tokens
NftOutputBuilder::from(nft_output)
.with_nft_id(nft_output.nft_id_non_null(&output_with_ext_metadata.output_id))
.with_nft_id(nft_output.nft_id_non_null(&output_data.output_id))
.with_unlock_conditions([AddressUnlockCondition::new(&wallet_address)])
.finish_output()?
} else {
NftOutputBuilder::from(nft_output)
.with_minimum_amount(storage_score_params)
.with_nft_id(nft_output.nft_id_non_null(&output_with_ext_metadata.output_id))
.with_nft_id(nft_output.nft_id_non_null(&output_data.output_id))
.with_unlock_conditions([AddressUnlockCondition::new(&wallet_address)])
.finish_output()?
};
Expand Down
Loading

0 comments on commit a9100c3

Please sign in to comment.