Skip to content
Snippets Groups Projects
Commit a1288dc1 authored by Éloïs's avatar Éloïs
Browse files

[feat] gva: add query balances

parent fa9e1550
No related branches found
No related tags found
No related merge requests found
...@@ -19,7 +19,9 @@ use crate::*; ...@@ -19,7 +19,9 @@ use crate::*;
pub(crate) struct AccountBalanceQuery; pub(crate) struct AccountBalanceQuery;
#[async_graphql::Object] #[async_graphql::Object]
impl AccountBalanceQuery { impl AccountBalanceQuery {
/// Account balance /// Get the balance of an account identified by a public key or a script.
///
/// If the balance is null, the account has never been used. If the balance is zero, the account has already transited money in the past.
async fn balance( async fn balance(
&self, &self,
ctx: &async_graphql::Context<'_>, ctx: &async_graphql::Context<'_>,
...@@ -43,6 +45,49 @@ impl AccountBalanceQuery { ...@@ -43,6 +45,49 @@ impl AccountBalanceQuery {
base: balance.0.base() as i32, base: balance.0.base() as i32,
})) }))
} }
/// Get the balance of several accounts in a single request
///
/// Each account can be identified by a public key or a script. It is possible to mix the two in the same request.
/// The balances are returned in the order of the accounts provided as input. Each account has a balance,
/// which is null if the account does not exist.
async fn balances(
&self,
ctx: &async_graphql::Context<'_>,
#[graphql(desc = "Accounts scripts or publics keys")] scripts: Vec<String>,
) -> async_graphql::Result<Vec<Option<AmountWithBase>>> {
let accounts_scripts = scripts
.into_iter()
.map(|script| {
if let Ok(pubkey) = PublicKey::from_base58(&script) {
Ok(WalletScriptV10::single_sig(pubkey))
} else {
dubp::documents_parser::wallet_script_from_str(&script)
}
})
.collect::<Result<Vec<_>, _>>()?;
let data = ctx.data::<GvaSchemaData>()?;
let dbs_reader = data.dbs_reader();
Ok(data
.dbs_pool
.execute(move |_| {
accounts_scripts
.iter()
.map(|account_script| {
dbs_reader
.get_account_balance(account_script)
.map(|balance_opt| {
balance_opt.map(|balance| AmountWithBase {
amount: balance.0.amount() as i32,
base: balance.0.base() as i32,
})
})
})
.collect::<Result<Vec<_>, _>>()
})
.await??)
}
} }
#[cfg(test)] #[cfg(test)]
...@@ -81,4 +126,35 @@ mod tests { ...@@ -81,4 +126,35 @@ mod tests {
); );
Ok(()) Ok(())
} }
#[tokio::test]
async fn query_balances() -> anyhow::Result<()> {
let mut dbs_reader = MockDbsReader::new();
dbs_reader
.expect_get_account_balance()
.withf(|s| {
s == &WalletScriptV10::single_sig(
PublicKey::from_base58("DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP")
.expect("wrong pubkey"),
)
})
.times(1)
.returning(|_| Ok(Some(SourceAmountValV2(SourceAmount::with_base0(38)))));
let schema = create_schema(dbs_reader)?;
assert_eq!(
exec_graphql_request(
&schema,
r#"{ balances(scripts: ["DnjL6hYA1k7FavGHbbir79PKQbmzw63d6bsamBBdUULP"]) {amount} }"#
)
.await?,
serde_json::json!({
"data": {
"balances": [{
"amount": 38
}]
}
})
);
Ok(())
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment