diff --git a/.changelog/unreleased/improvements/1173-token-balance-query.md b/.changelog/unreleased/improvements/1173-token-balance-query.md new file mode 100644 index 0000000000..e5a9ea2322 --- /dev/null +++ b/.changelog/unreleased/improvements/1173-token-balance-query.md @@ -0,0 +1,2 @@ +- Added a reusable token balance query method. + ([\#1173](https://github.com/anoma/namada/pull/1173)) \ No newline at end of file diff --git a/apps/src/lib/client/rpc.rs b/apps/src/lib/client/rpc.rs index cab86cfdd1..236bafb57d 100644 --- a/apps/src/lib/client/rpc.rs +++ b/apps/src/lib/client/rpc.rs @@ -1098,7 +1098,7 @@ pub async fn get_token_balance( client: &C, token: &Address, owner: &Address, -) -> Option { +) -> token::Amount { namada::ledger::rpc::get_token_balance(client, token, owner).await } diff --git a/apps/src/lib/client/tx.rs b/apps/src/lib/client/tx.rs index a68738c479..4e534ece8f 100644 --- a/apps/src/lib/client/tx.rs +++ b/apps/src/lib/client/tx.rs @@ -700,8 +700,7 @@ where let balance = rpc::get_token_balance(client, &ctx.native_token, &proposal.author) - .await - .unwrap_or_default(); + .await; if balance < token::Amount::from_uint( governance_parameters.min_proposal_fund, diff --git a/shared/src/ledger/queries/vp/token.rs b/shared/src/ledger/queries/vp/token.rs index cbad27005f..1a2ab3a1bd 100644 --- a/shared/src/ledger/queries/vp/token.rs +++ b/shared/src/ledger/queries/vp/token.rs @@ -1,3 +1,5 @@ +//! Token validity predicate queries + use namada_core::ledger::storage::{DBIter, StorageHasher, DB}; use namada_core::ledger::storage_api; use namada_core::ledger::storage_api::token::read_denom; @@ -41,3 +43,40 @@ where { read_denom(ctx.wl_storage, &addr, None) } + +#[cfg(any(test, feature = "async-client"))] +pub mod client_only_methods { + use borsh::BorshDeserialize; + + use super::Token; + use crate::ledger::queries::{Client, RPC}; + use crate::types::address::Address; + use crate::types::token; + + impl Token { + /// Get the balance of the given `token` belonging to the given `owner`. + pub async fn balance( + &self, + client: &CLIENT, + token: &Address, + owner: &Address, + ) -> Result::Error> + where + CLIENT: Client + Sync, + { + let balance_key = token::balance_key(token, owner); + let response = RPC + .shell() + .storage_value(client, None, None, false, &balance_key) + .await?; + + let balance = if response.data.is_empty() { + token::Amount::default() + } else { + token::Amount::try_from_slice(&response.data) + .unwrap_or_default() + }; + Ok(balance) + } + } +} diff --git a/shared/src/ledger/rpc.rs b/shared/src/ledger/rpc.rs index 38e8777c0a..1ccbd20484 100644 --- a/shared/src/ledger/rpc.rs +++ b/shared/src/ledger/rpc.rs @@ -39,7 +39,6 @@ use crate::types::governance::{ProposalVote, VotePower}; use crate::types::hash::Hash; use crate::types::key::*; use crate::types::storage::{BlockHeight, BlockResults, Epoch, PrefixValue}; -use crate::types::token::balance_key; use crate::types::{storage, token}; /// Query the status of a given transaction. @@ -140,9 +139,10 @@ pub async fn get_token_balance( client: &C, token: &Address, owner: &Address, -) -> Option { - let balance_key = balance_key(token, owner); - query_storage_value(client, &balance_key).await +) -> token::Amount { + unwrap_client_response::( + RPC.vp().token().balance(client, token, owner).await, + ) } /// Get account's public key stored in its storage sub-space