Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove NativeTokens #2073

Closed
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 15 additions & 19 deletions cli/src/wallet_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

mod completer;

use std::str::FromStr;
use std::{collections::BTreeMap, str::FromStr};

use clap::{CommandFactory, Parser, Subcommand};
use colored::Colorize;
Expand All @@ -15,8 +15,7 @@ use iota_sdk::{
output::{
feature::{BlockIssuerKeySource, MetadataFeature},
unlock_condition::AddressUnlockCondition,
AccountId, BasicOutputBuilder, DelegationId, FoundryId, NativeToken, NativeTokensBuilder, NftId, Output,
OutputId, TokenId,
AccountId, BasicOutputBuilder, DelegationId, FoundryId, NativeToken, NftId, Output, OutputId, TokenId,
},
payload::signed_transaction::TransactionId,
slot::SlotIndex,
Expand Down Expand Up @@ -1302,7 +1301,7 @@ async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> {
let address = wallet.address().await;

let mut log = format!(
"Address:\n{:<9}{}\n{:<9}{:?}",
"Address:\n{:<9}{}\n{:<9}{:?}\n",
"Bech32:",
address,
"Hex:",
Expand All @@ -1314,7 +1313,7 @@ async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> {

let mut output_ids = Vec::new();
let mut amount = 0;
let mut native_tokens = NativeTokensBuilder::new();
let mut native_tokens = BTreeMap::<TokenId, U256>::new();
let mut accounts = Vec::new();
let mut foundries = Vec::new();
let mut nfts = Vec::new();
Expand All @@ -1335,7 +1334,7 @@ async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> {
.is_some_and(|required_address| required_address == address.inner())
{
if let Some(nt) = output_data.output.native_token() {
native_tokens.add_native_token(*nt)?;
(*native_tokens.entry(*nt.token_id()).or_default()) += nt.amount();
}
match &output_data.output {
Output::Basic(_) => {}
Expand All @@ -1359,19 +1358,16 @@ async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> {
}

let bip_path = wallet.bip_path().await;
log = format!("{log}\nBIP path: {bip_path:?}");

log = format!(
"{log}\nOutputs: {:#?}\nBase coin amount: {}\nNative Tokens: {:?}\nAccounts: {:?}\nFoundries: {:?}\nNFTs: {:?}\nDelegations: {:?}\nAnchors: {:?}\n",
output_ids,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe split this up or something ew

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we just push the strings rather than the weird formatting thing?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or even just log them one at a time??

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pleasssee

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thibault-martinez want to do this?

amount,
native_tokens.finish_vec()?,
accounts,
foundries,
nfts,
delegations,
anchors
);

log = format!("{log}BIP path: {bip_path:?}\n");
log = format!("{log}Outputs: {output_ids:#?}\n");
log = format!("{log}Base coin amount: {amount:#?}\n");
log = format!("{log}Native Tokens: {native_tokens:#?}\n");
log = format!("{log}Accounts: {accounts:#?}\n");
log = format!("{log}Foundries: {foundries:#?}\n");
log = format!("{log}NFTs: {nfts:#?}\n");
log = format!("{log}Delegations: {delegations:#?}\n");
log = format!("{log}Anchors: {anchors:#?}\n");

println_log_info!("{log}");

Expand Down
13 changes: 7 additions & 6 deletions sdk/examples/client/02_address_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
//! cargo run --release --example 02_address_balance
//! ```

use std::collections::BTreeMap;

use iota_sdk::{
client::{
api::GetAddressesOptions, node_api::indexer::query_parameters::BasicOutputQueryParameters,
secret::SecretManager, Client, Result,
},
types::block::output::NativeTokensBuilder,
types::block::output::TokenId,
};
use primitive_types::U256;

#[tokio::main]
async fn main() -> Result<()> {
Expand Down Expand Up @@ -57,19 +60,17 @@ async fn main() -> Result<()> {

// Calculate the total amount and native tokens
let mut total_amount = 0;
let mut total_native_tokens = NativeTokensBuilder::new();
let mut total_native_tokens = BTreeMap::<TokenId, U256>::new();
for output in outputs {
if let Some(native_token) = output.output.native_token() {
total_native_tokens.add_native_token(*native_token)?;
(*total_native_tokens.entry(*native_token.token_id()).or_default()) += native_token.amount();
}
total_amount += output.output.amount();
}

println!(
"Outputs controlled by {} have: {:?}i and native tokens:\n{:#?}",
first_address,
total_amount,
total_native_tokens.finish_vec()?
first_address, total_amount, total_native_tokens
);
Ok(())
}
21 changes: 11 additions & 10 deletions sdk/src/client/api/block_builder/input_selection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ pub(crate) mod remainder;
pub(crate) mod requirement;
pub(crate) mod transition;

use alloc::collections::BTreeMap;
use core::ops::Deref;
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashMap, HashSet};

use packable::PackableExt;
use primitive_types::U256;

use self::requirement::account::is_account_with_id;
pub use self::{burn::Burn, error::Error, requirement::Requirement};
Expand All @@ -29,7 +28,7 @@ use crate::{
mana::ManaAllotment,
output::{
AccountId, AccountOutput, AccountOutputBuilder, AnchorOutputBuilder, BasicOutputBuilder, FoundryOutput,
NativeTokensBuilder, NftOutput, NftOutputBuilder, Output, OutputId, OUTPUT_COUNT_RANGE,
NftOutput, NftOutputBuilder, Output, OutputId, TokenId, OUTPUT_COUNT_RANGE,
},
payload::{
signed_transaction::{Transaction, TransactionCapabilities},
Expand Down Expand Up @@ -647,16 +646,16 @@ impl InputSelection {
}

fn validate_transitions(inputs: &[InputSigningData], outputs: &[Output]) -> Result<(), Error> {
let mut input_native_tokens_builder = NativeTokensBuilder::new();
let mut output_native_tokens_builder = NativeTokensBuilder::new();
let mut input_native_tokens_builder = BTreeMap::<TokenId, U256>::new();
let mut output_native_tokens_builder = BTreeMap::<TokenId, U256>::new();
let mut input_accounts = Vec::new();
let mut input_chains_foundries = hashbrown::HashMap::new();
let mut input_foundries = Vec::new();
let mut input_nfts = Vec::new();

for input in inputs {
if let Some(native_token) = input.output.native_token() {
input_native_tokens_builder.add_native_token(*native_token)?;
(*input_native_tokens_builder.entry(*native_token.token_id()).or_default()) += native_token.amount();
}
match &input.output {
Output::Basic(basic) => {
Expand All @@ -680,7 +679,9 @@ impl InputSelection {

for output in outputs {
if let Some(native_token) = output.native_token() {
output_native_tokens_builder.add_native_token(*native_token)?;
(*output_native_tokens_builder
.entry(*native_token.token_id())
.or_default()) += native_token.amount();
}
}

Expand Down Expand Up @@ -733,8 +734,8 @@ impl InputSelection {
if let Err(err) = FoundryOutput::transition_inner(
foundry_input.output.as_foundry(),
foundry_output,
input_native_tokens_builder.deref(),
output_native_tokens_builder.deref(),
&input_native_tokens_builder,
&output_native_tokens_builder,
// We use `all` capabilities here because this transition may be burning
// native tokens, and validation will fail without the capability.
&TransactionCapabilities::all(),
Expand Down
50 changes: 15 additions & 35 deletions sdk/src/client/api/block_builder/input_selection/remainder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@ use alloc::collections::BTreeMap;
use std::collections::HashMap;

use crypto::keys::bip44::Bip44;
use primitive_types::U256;

use super::{Error, InputSelection};
use crate::{
client::api::{
input_selection::requirement::native_tokens::{get_native_tokens, get_native_tokens_diff},
RemainderData,
},
client::api::{input_selection::requirement::native_tokens::get_native_tokens_diff, RemainderData},
types::block::{
address::{Address, Ed25519Address},
output::{
unlock_condition::AddressUnlockCondition, AccountOutput, AnchorOutput, BasicOutput, BasicOutputBuilder,
NativeTokens, NativeTokensBuilder, NftOutput, Output, StorageScoreParameters,
NativeToken, NftOutput, Output, StorageScoreParameters, TokenId,
},
Error as BlockError,
},
Expand Down Expand Up @@ -71,16 +69,7 @@ impl InputSelection {
}

pub(crate) fn remainder_amount(&self) -> Result<(u64, bool, bool), Error> {
let mut input_native_tokens = get_native_tokens(self.selected_inputs.iter().map(|input| &input.output))?;
let mut output_native_tokens = get_native_tokens(self.non_remainder_outputs())?;
let (minted_native_tokens, melted_native_tokens) = self.get_minted_and_melted_native_tokens()?;

input_native_tokens.merge(minted_native_tokens)?;
output_native_tokens.merge(melted_native_tokens)?;

if let Some(burn) = self.burn.as_ref() {
output_native_tokens.merge(NativeTokensBuilder::from(burn.native_tokens.clone()))?;
}
let (input_native_tokens, output_native_tokens) = self.input_output_native_tokens()?;

let native_tokens_diff = get_native_tokens_diff(&input_native_tokens, &output_native_tokens)?;

Expand Down Expand Up @@ -110,17 +99,7 @@ impl InputSelection {
}
}

let mut input_native_tokens = get_native_tokens(self.selected_inputs.iter().map(|input| &input.output))?;
let mut output_native_tokens = get_native_tokens(self.non_remainder_outputs())?;
let (minted_native_tokens, melted_native_tokens) = self.get_minted_and_melted_native_tokens()?;

input_native_tokens.merge(minted_native_tokens)?;
output_native_tokens.merge(melted_native_tokens)?;

if let Some(burn) = self.burn.as_ref() {
output_native_tokens.merge(NativeTokensBuilder::from(burn.native_tokens.clone()))?;
}

let (input_native_tokens, output_native_tokens) = self.input_output_native_tokens()?;
let native_tokens_diff = get_native_tokens_diff(&input_native_tokens, &output_native_tokens)?;

let (input_mana, output_mana) = self.mana_sums(false)?;
Expand Down Expand Up @@ -210,7 +189,7 @@ impl InputSelection {
/// tokens are remaining) and returns if there are native tokens as remainder.
pub(crate) fn required_remainder_amount(
&self,
remainder_native_tokens: Option<NativeTokens>,
remainder_native_tokens: Option<BTreeMap<TokenId, U256>>,
) -> Result<(u64, bool, bool), Error> {
let native_tokens_remainder = remainder_native_tokens.is_some();

Expand All @@ -221,8 +200,9 @@ impl InputSelection {
))));

let remainder_amount = if let Some(native_tokens) = remainder_native_tokens {
let entry = native_tokens.first_key_value().unwrap();
let nt_remainder_amount = remainder_builder
.with_native_token(*native_tokens.first().unwrap())
.with_native_token(NativeToken::new(*entry.0, entry.1)?)
.finish_output()?
.amount();
// Amount can be just multiplied, because all remainder outputs with a native token have the same storage
Expand All @@ -249,7 +229,7 @@ impl InputSelection {
fn create_remainder_outputs(
amount_diff: u64,
mana_diff: u64,
native_tokens_diff: Option<NativeTokens>,
native_tokens_diff: Option<BTreeMap<TokenId, U256>>,
remainder_address: Address,
remainder_address_chain: Option<Bip44>,
storage_score_parameters: StorageScoreParameters,
Expand All @@ -259,15 +239,15 @@ fn create_remainder_outputs(
let mut catchall_native_token = None;

// Start with the native tokens
if let Some(native_tokens) = native_tokens_diff {
if let Some((last, nts)) = native_tokens.split_last() {
if let Some(mut native_tokens) = native_tokens_diff {
if let Some(last) = native_tokens.pop_last() {
// Save this one for the catchall
catchall_native_token.replace(*last);
catchall_native_token.replace(last);
// Create remainder outputs with min amount
for native_token in nts {
for native_token in native_tokens {
let output = BasicOutputBuilder::new_with_minimum_amount(storage_score_parameters)
.add_unlock_condition(AddressUnlockCondition::new(remainder_address.clone()))
.with_native_token(*native_token)
.with_native_token(NativeToken::new(native_token.0, native_token.1)?)
.finish_output()?;
log::debug!(
"Created remainder output of amount {}, mana {} and native token {native_token:?} for {remainder_address:?}",
Expand All @@ -283,7 +263,7 @@ fn create_remainder_outputs(
.with_mana(mana_diff)
.add_unlock_condition(AddressUnlockCondition::new(remainder_address.clone()));
if let Some(native_token) = catchall_native_token {
catchall = catchall.with_native_token(native_token);
catchall = catchall.with_native_token(NativeToken::new(native_token.0, native_token.1)?);
}
let catchall = catchall.finish_output()?;
catchall.verify_storage_deposit(storage_score_parameters)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ impl AmountSelection {
}

pub(crate) fn remainder_amount(&self, input_selection: &InputSelection) -> Result<(u64, bool, bool), Error> {
let input_native_tokens =
get_native_tokens(self.newly_selected_inputs.values().map(|input| &input.output))?.finish()?;
let input_native_tokens = get_native_tokens(self.newly_selected_inputs.values().map(|input| &input.output))?;

input_selection.required_remainder_amount(Some(input_native_tokens))
}
Expand Down
Loading
Loading