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

Enhance coin retrieval logic in Iota client #1472

Merged
Merged
Changes from 3 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
52 changes: 41 additions & 11 deletions identity_iota_core/src/rebased/client/full_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use async_trait::async_trait;
use fastcrypto::ed25519::Ed25519PublicKey;
use fastcrypto::traits::ToFromBytes;
use identity_verification::jwk::Jwk;
use iota_sdk::rpc_types::Coin;
use iota_sdk::rpc_types::IotaExecutionStatus;
use iota_sdk::rpc_types::IotaObjectData;
use iota_sdk::rpc_types::IotaObjectDataFilter;
Expand Down Expand Up @@ -47,6 +48,11 @@ use crate::rebased::Error;
use super::get_object_id_from_did;
use super::IdentityClientReadOnly;

/// The minimum balance required to execute a transaction.
///
/// TBD: A temporary value,
itsyaasir marked this conversation as resolved.
Show resolved Hide resolved
pub(crate) const MINIMUM_BALANCE: u64 = 100_000_000;

/// A signature which is used to sign transactions.
pub struct IotaKeySignature {
/// The public key of the signature.
Expand Down Expand Up @@ -253,18 +259,42 @@ impl<S> IdentityClient<S> {
Ok(budget)
}

async fn get_coin_for_transaction(&self) -> Result<iota_sdk::rpc_types::Coin, Error> {
let coins = self
.coin_read_api()
.get_coins(self.sender_address(), None, None, None)
.await
.map_err(|err| Error::GasIssue(format!("could not get coins; {err}")))?;
async fn get_coin_for_transaction(&self) -> Result<Coin, Error> {
itsyaasir marked this conversation as resolved.
Show resolved Hide resolved
const LIMIT: usize = 10;
let mut cursor = None;

loop {
let coins = self
.coin_read_api()
.get_coins(self.sender_address(), None, cursor, Some(LIMIT))
.await?;

if coins.data.is_empty() {
return Err(Error::GasIssue("no coins found for address".to_string()));
}

if let Some(coin) = coins.data.into_iter().max_by_key(|coin| coin.balance) {
if coin.balance >= MINIMUM_BALANCE {
return Ok(coin);
}

return Err(Error::GasIssue(format!(
"highest balance coin ({}) is below minimum required balance of {}",
coin.balance, MINIMUM_BALANCE
)));
wulfraem marked this conversation as resolved.
Show resolved Hide resolved
}

if !coins.has_next_page {
break;
}

cursor = coins.next_cursor;
}

coins
.data
.into_iter()
.next()
.ok_or_else(|| Error::GasIssue("could not find coins".to_string()))
Err(Error::GasIssue(format!(
"no coin found with minimum required balance of {}",
UMR1352 marked this conversation as resolved.
Show resolved Hide resolved
MINIMUM_BALANCE
)))
}

async fn get_transaction_data(
Expand Down
Loading