Skip to content

Commit

Permalink
Add delegation to balance (#1456)
Browse files Browse the repository at this point in the history
* add fields

* qualify + format

* include delegation outputs in balance computation

* Update bindings

* Nits

* Update bindings/nodejs/lib/types/wallet/wallet.ts

---------

Co-authored-by: Thoralf Müller <[email protected]>
Co-authored-by: Thibault Martinez <[email protected]>
Co-authored-by: Thoralf-M <[email protected]>
  • Loading branch information
4 people authored Nov 27, 2023
1 parent 94c5d35 commit e56c6af
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 77 deletions.
12 changes: 8 additions & 4 deletions bindings/nodejs/lib/types/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ export interface Balance {
requiredStorageDeposit: RequiredStorageDeposit;
/** The balance of the native tokens */
nativeTokens: NativeTokenBalance[];
/** Nft outputs */
nfts: string[];
/** Account outputs */
accounts: string[];
/** Foundry outputs */
foundries: string[];
/** Nft outputs */
nfts: string[];
/** Delegation outputs */
delegations: string[];
/**
* Outputs with multiple unlock conditions and if they can currently be spent or not. If there is a
* TimelockUnlockCondition or ExpirationUnlockCondition this can change at any time
Expand All @@ -56,14 +58,16 @@ export interface BaseCoinBalance {

/** The required storage deposit per output type */
export interface RequiredStorageDeposit {
/** The required amount for Alias outputs. */
account: u64;
/** The required amount for Basic outputs. */
basic: u64;
/** The required amount for Account outputs. */
account: u64;
/** The required amount for Foundry outputs. */
foundry: u64;
/** The required amount for NFT outputs. */
nft: u64;
/** The required amount for Delegation outputs. */
delegation: u64;
}

/** The balance of a native token */
Expand Down
16 changes: 11 additions & 5 deletions bindings/python/iota_sdk/types/balance.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,16 @@ class RequiredStorageDeposit:
"""Required storage deposit for the outputs in the account.
Attributes:
account: The required amount for account outputs.
basic: The required amount for basic outputs.
account: The required amount for account outputs.
foundry: The required amount for foundry outputs.
nft: The required amount for nft outputs.
delegation: The required amount for delegation outputs.
"""
account: int = field(metadata=config(
basic: int = field(metadata=config(
encoder=str
))
basic: int = field(metadata=config(
account: int = field(metadata=config(
encoder=str
))
foundry: int = field(metadata=config(
Expand All @@ -48,6 +49,9 @@ class RequiredStorageDeposit:
nft: int = field(metadata=config(
encoder=str
))
delegation: int = field(metadata=config(
encoder=str
))


@json
Expand Down Expand Up @@ -82,15 +86,17 @@ class Balance:
base_coin: The base coin balance.
required_storage_deposit: The required storage deposit.
native_tokens: The balances of all native tokens.
nfts: All owned NFTs.
accounts: All owned accounts.
foundries: All owned foundries.
nfts: All owned NFTs.
delegations: All owned delegation outputs.
potentially_locked_outputs: A list of potentially locked outputs.
"""
base_coin: BaseCoinBalance
required_storage_deposit: RequiredStorageDeposit
native_tokens: List[NativeTokensBalance]
nfts: List[HexStr]
accounts: List[HexStr]
foundries: List[HexStr]
nfts: List[HexStr]
delegations: List[HexStr]
potentially_locked_outputs: dict[HexStr, bool]
32 changes: 21 additions & 11 deletions sdk/src/wallet/operations/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,24 @@ where
let output = &output_data.output;
let storage_cost = output.minimum_amount(storage_score_params);

// Add account and foundry outputs here because they can't have a
// Add account, foundry, and delegation outputs here because they can't have a
// [`StorageDepositReturnUnlockCondition`] or time related unlock conditions
match output {
Output::Account(output) => {
Output::Account(account) => {
// Add amount
balance.base_coin.total += output.amount();
balance.base_coin.total += account.amount();
// Add storage deposit
balance.required_storage_deposit.account += storage_cost;
if !wallet_data.locked_outputs.contains(output_id) {
total_storage_cost += storage_cost;
}

let account_id = output.account_id_non_null(output_id);
let account_id = account.account_id_non_null(output_id);
balance.accounts.push(account_id);
}
Output::Foundry(output) => {
Output::Foundry(foundry) => {
// Add amount
balance.base_coin.total += output.amount();
balance.base_coin.total += foundry.amount();
// Add storage deposit
balance.required_storage_deposit.foundry += storage_cost;
if !wallet_data.locked_outputs.contains(output_id) {
Expand All @@ -91,7 +91,19 @@ where
total_native_tokens.add_native_token(*native_token)?;
}

balance.foundries.push(output.id());
balance.foundries.push(foundry.id());
}
Output::Delegation(delegation) => {
// Add amount
balance.base_coin.total += delegation.amount();
// Add storage deposit
balance.required_storage_deposit.delegation += storage_cost;
if !wallet_data.locked_outputs.contains(output_id) {
total_storage_cost += storage_cost;
}

let delegation_id = delegation.delegation_id_non_null(output_id);
balance.delegations.push(delegation_id);
}
_ => {
// If there is only an [AddressUnlockCondition], then we can spend the output at any time
Expand All @@ -102,8 +114,8 @@ where
.as_ref()
{
// add nft_id for nft outputs
if let Output::Nft(output) = &output {
let nft_id = output.nft_id_non_null(output_id);
if let Output::Nft(nft) = &output {
let nft_id = nft.nft_id_non_null(output_id);
balance.nfts.push(nft_id);
}

Expand Down Expand Up @@ -223,9 +235,7 @@ where
}
}
}
// }
}
// }

self.finish(
balance,
Expand Down
15 changes: 13 additions & 2 deletions sdk/src/wallet/types/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use primitive_types::U256;
use serde::{Deserialize, Serialize};

use crate::{
types::block::output::{feature::MetadataFeature, AccountId, FoundryId, NftId, OutputId, TokenId},
types::block::output::{feature::MetadataFeature, AccountId, DelegationId, FoundryId, NftId, OutputId, TokenId},
utils::serde::string,
};

Expand All @@ -30,6 +30,8 @@ pub struct Balance {
pub(crate) foundries: Vec<FoundryId>,
/// Nfts
pub(crate) nfts: Vec<NftId>,
/// Delegations
pub(crate) delegations: Vec<DelegationId>,
/// Outputs with multiple unlock conditions and if they can currently be spent or not. If there is a
/// [`TimelockUnlockCondition`](crate::types::block::output::unlock_condition::TimelockUnlockCondition) or
/// [`ExpirationUnlockCondition`](crate::types::block::output::unlock_condition::ExpirationUnlockCondition) this
Expand Down Expand Up @@ -57,6 +59,7 @@ impl std::ops::AddAssign for Balance {
self.accounts.extend(rhs.accounts);
self.foundries.extend(rhs.foundries);
self.nfts.extend(rhs.nfts);
self.delegations.extend(rhs.delegations);
}
}

Expand Down Expand Up @@ -99,6 +102,8 @@ pub struct RequiredStorageDeposit {
pub(crate) foundry: u64,
#[serde(with = "crate::utils::serde::string")]
pub(crate) nft: u64,
#[serde(with = "crate::utils::serde::string")]
pub(crate) delegation: u64,
}

impl std::ops::AddAssign for RequiredStorageDeposit {
Expand All @@ -107,6 +112,7 @@ impl std::ops::AddAssign for RequiredStorageDeposit {
self.account += rhs.account;
self.foundry += rhs.foundry;
self.nft += rhs.nft;
self.delegation += rhs.delegation;
}
}

Expand Down Expand Up @@ -152,7 +158,7 @@ impl std::ops::AddAssign for NativeTokensBalance {

#[cfg(feature = "rand")]
impl Balance {
pub fn rand_mock() -> Self {
pub fn rand() -> Self {
use rand::Rng;

use crate::types::block::rand::bytes::rand_bytes_array;
Expand Down Expand Up @@ -199,6 +205,9 @@ impl Balance {
let foundries = std::iter::repeat_with(|| FoundryId::from(rand_bytes_array()))
.take(rand::thread_rng().gen_range(0..10))
.collect::<Vec<_>>();
let delegations = std::iter::repeat_with(|| DelegationId::from(rand_bytes_array()))
.take(rand::thread_rng().gen_range(0..10))
.collect::<Vec<_>>();

Self {
base_coin: BaseCoinBalance {
Expand All @@ -212,11 +221,13 @@ impl Balance {
account: total / 16,
foundry: total / 4,
nft: total / 2,
delegation: total / 16,
},
native_tokens,
accounts,
foundries,
nfts,
delegations,
..Default::default()
}
}
Expand Down
Loading

0 comments on commit e56c6af

Please sign in to comment.