Skip to content

Commit f735cb7

Browse files
committed
feat: account assets, utxos, and totals REST handlers (WIP)
Signed-off-by: William Hankins <[email protected]>
1 parent 084ed31 commit f735cb7

File tree

3 files changed

+117
-34
lines changed

3 files changed

+117
-34
lines changed

common/src/queries/accounts.rs

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@ pub const DEFAULT_HISTORICAL_ACCOUNTS_QUERY_TOPIC: (&str, &str) = (
1515
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
1616
pub enum AccountsStateQuery {
1717
GetAccountInfo { account: StakeAddress },
18+
GetAccountsUtxoValuesMap { stake_addresses: Vec<StakeAddress> },
19+
GetAccountsUtxoValuesSum { stake_addresses: Vec<StakeAddress> },
20+
GetAccountsBalancesMap { stake_addresses: Vec<StakeAddress> },
21+
GetAccountsBalancesSum { stake_addresses: Vec<StakeAddress> },
22+
23+
// Served from historical accounts state
1824
GetAccountRewardHistory { account: StakeAddress },
1925
GetAccountHistory { stake_key: Vec<u8> },
2026
GetAccountRegistrationHistory { account: StakeAddress },
2127
GetAccountDelegationHistory { account: StakeAddress },
2228
GetAccountMIRHistory { account: StakeAddress },
2329
GetAccountWithdrawalHistory { account: StakeAddress },
2430
GetAccountAssociatedAddresses { account: StakeAddress },
25-
GetAccountAssets { stake_key: Vec<u8> },
26-
GetAccountAssetsTotals { stake_key: Vec<u8> },
27-
GetAccountUTxOs { stake_key: Vec<u8> },
28-
GetAccountsUtxoValuesMap { stake_addresses: Vec<StakeAddress> },
29-
GetAccountsUtxoValuesSum { stake_addresses: Vec<StakeAddress> },
30-
GetAccountsBalancesMap { stake_addresses: Vec<StakeAddress> },
31-
GetAccountsBalancesSum { stake_addresses: Vec<StakeAddress> },
3231

3332
// Epochs-related queries
3433
GetActiveStakes {},
@@ -49,20 +48,19 @@ pub enum AccountsStateQuery {
4948
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
5049
pub enum AccountsStateQueryResponse {
5150
AccountInfo(AccountInfo),
51+
AccountsUtxoValuesMap(HashMap<StakeAddress, u64>),
52+
AccountsUtxoValuesSum(u64),
53+
AccountsBalancesMap(HashMap<StakeAddress, u64>),
54+
AccountsBalancesSum(u64),
55+
56+
// Served from historical accounts state
5257
AccountRewardHistory(Vec<AccountReward>),
5358
AccountHistory(AccountHistory),
5459
AccountRegistrationHistory(Vec<RegistrationUpdate>),
5560
AccountDelegationHistory(Vec<DelegationUpdate>),
5661
AccountMIRHistory(Vec<AccountWithdrawal>),
5762
AccountWithdrawalHistory(Vec<AccountWithdrawal>),
5863
AccountAssociatedAddresses(Vec<ShelleyAddress>),
59-
AccountAssets(AccountAssets),
60-
AccountAssetsTotals(AccountAssetsTotals),
61-
AccountUTxOs(AccountUTxOs),
62-
AccountsUtxoValuesMap(HashMap<StakeAddress, u64>),
63-
AccountsUtxoValuesSum(u64),
64-
AccountsBalancesMap(HashMap<StakeAddress, u64>),
65-
AccountsBalancesSum(u64),
6664

6765
// Epochs-related responses
6866
ActiveStakes(u64),
@@ -163,21 +161,6 @@ pub struct AccountReward {
163161
pub reward_type: RewardType,
164162
}
165163

166-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
167-
pub struct AccountWithdrawalHistory {}
168-
169-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
170-
pub struct AccountAssociatedAddresses {}
171-
172-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
173-
pub struct AccountAssets {}
174-
175-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
176-
pub struct AccountAssetsTotals {}
177-
178-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
179-
pub struct AccountUTxOs {}
180-
181164
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
182165
pub struct OptimalPoolSizing {
183166
pub total_supply: u64, // total_supply - reserves

modules/rest_blockfrost/src/handlers/accounts.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use acropolis_common::queries::blocks::{
88
};
99
use acropolis_common::queries::utils::query_state;
1010
use acropolis_common::serialization::{Bech32Conversion, Bech32WithHrp};
11-
use acropolis_common::{DRepChoice, StakeAddress};
11+
use acropolis_common::{DRepChoice, ShelleyAddress, StakeAddress};
1212
use anyhow::{anyhow, Result};
1313
use caryatid_sdk::Context;
1414

@@ -635,6 +635,71 @@ pub async fn handle_account_addresses_blockfrost(
635635
}
636636
}
637637

638+
/// Handle `/accounts/{stake_address}/addresses/assets` Blockfrost-compatible endpoint
639+
pub async fn handle_account_assets_blockfrost(
640+
_context: Arc<Context<Message>>,
641+
_params: Vec<String>,
642+
_handlers_config: Arc<HandlersConfig>,
643+
) -> Result<RESTResponse> {
644+
Ok(RESTResponse::with_text(501, "Not implemented"))
645+
}
646+
647+
/// Handle `/accounts/{stake_address}/addresses/total` Blockfrost-compatible endpoint
648+
pub async fn handle_account_totals_blockfrost(
649+
context: Arc<Context<Message>>,
650+
params: Vec<String>,
651+
handlers_config: Arc<HandlersConfig>,
652+
) -> Result<RESTResponse> {
653+
let account = match parse_stake_address(&params) {
654+
Ok(addr) => addr,
655+
Err(resp) => return Ok(resp),
656+
};
657+
658+
// Prepare the message
659+
let msg = Arc::new(Message::StateQuery(StateQuery::Accounts(
660+
AccountsStateQuery::GetAccountAssociatedAddresses { account },
661+
)));
662+
663+
// Get addresses from historical accounts state
664+
let addresses = query_state(
665+
&context,
666+
&handlers_config.historical_accounts_query_topic,
667+
msg,
668+
|message| match message {
669+
Message::StateQueryResponse(StateQueryResponse::Accounts(
670+
AccountsStateQueryResponse::AccountAssociatedAddresses(addresses),
671+
)) => Ok(Some(addresses)),
672+
Message::StateQueryResponse(StateQueryResponse::Accounts(
673+
AccountsStateQueryResponse::NotFound,
674+
)) => Ok(None),
675+
Message::StateQueryResponse(StateQueryResponse::Accounts(
676+
AccountsStateQueryResponse::Error(e),
677+
)) => Err(anyhow::anyhow!(
678+
"Internal server error while retrieving account addresses: {e}"
679+
)),
680+
_ => Err(anyhow::anyhow!(
681+
"Unexpected message type while retrieving account addresses"
682+
)),
683+
},
684+
)
685+
.await?;
686+
687+
let Some(addresses) = addresses else {
688+
return Ok(RESTResponse::with_text(404, "Account not found"));
689+
};
690+
691+
Ok(RESTResponse::with_text(501, "Not implemented"))
692+
}
693+
694+
/// Handle `/accounts/{stake_address}/utxos` Blockfrost-compatible endpoint
695+
pub async fn handle_account_utxos_blockfrost(
696+
_context: Arc<Context<Message>>,
697+
_params: Vec<String>,
698+
_handlers_config: Arc<HandlersConfig>,
699+
) -> Result<RESTResponse> {
700+
Ok(RESTResponse::with_text(501, "Not implemented"))
701+
}
702+
638703
fn parse_stake_address(params: &[String]) -> Result<StakeAddress, RESTResponse> {
639704
let Some(stake_key) = params.first() else {
640705
return Err(RESTResponse::with_text(

modules/rest_blockfrost/src/rest_blockfrost.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ mod types;
1717
mod utils;
1818
use handlers::{
1919
accounts::{
20-
handle_account_addresses_blockfrost, handle_account_delegations_blockfrost,
21-
handle_account_mirs_blockfrost, handle_account_registrations_blockfrost,
22-
handle_account_rewards_blockfrost, handle_account_withdrawals_blockfrost,
23-
handle_single_account_blockfrost,
20+
handle_account_addresses_blockfrost, handle_account_assets_blockfrost,
21+
handle_account_delegations_blockfrost, handle_account_mirs_blockfrost,
22+
handle_account_registrations_blockfrost, handle_account_rewards_blockfrost,
23+
handle_account_totals_blockfrost, handle_account_utxos_blockfrost,
24+
handle_account_withdrawals_blockfrost, handle_single_account_blockfrost,
2425
},
2526
addresses::{
2627
handle_address_asset_utxos_blockfrost, handle_address_extended_blockfrost,
@@ -90,6 +91,16 @@ const DEFAULT_HANDLE_ACCOUNT_ADDRESSES_TOPIC: (&str, &str) = (
9091
"handle-topic-account-addresses",
9192
"rest.get.accounts.*.addresses",
9293
);
94+
const DEFAULT_HANDLE_ACCOUNT_ASSETS_TOPIC: (&str, &str) = (
95+
"handle-topic-account-assets",
96+
"rest.get.accounts.*.addresses.assets",
97+
);
98+
const DEFAULT_HANDLE_ACCOUNT_TOTALS_TOPIC: (&str, &str) = (
99+
"handle-topic-account-totals",
100+
"rest.get.accounts.*.addresses.total",
101+
);
102+
const DEFAULT_HANDLE_ACCOUNT_UTXOS_TOPIC: (&str, &str) =
103+
("handle-topic-account-utxos", "rest.get.accounts.*.utxos");
93104

94105
// Blocks topics
95106
const DEFAULT_HANDLE_BLOCKS_LATEST_HASH_NUMBER_TOPIC: (&str, &str) =
@@ -324,6 +335,30 @@ impl BlockfrostREST {
324335
handle_account_addresses_blockfrost,
325336
);
326337

338+
// Handler for /accounts/{stake_address}/addresses/assets
339+
register_handler(
340+
context.clone(),
341+
DEFAULT_HANDLE_ACCOUNT_ASSETS_TOPIC,
342+
handlers_config.clone(),
343+
handle_account_assets_blockfrost,
344+
);
345+
346+
// Handler for /accounts/{stake_address}/addreesses/total
347+
register_handler(
348+
context.clone(),
349+
DEFAULT_HANDLE_ACCOUNT_TOTALS_TOPIC,
350+
handlers_config.clone(),
351+
handle_account_totals_blockfrost,
352+
);
353+
354+
// Handler for /accounts/{stake_address}/utxos
355+
register_handler(
356+
context.clone(),
357+
DEFAULT_HANDLE_ACCOUNT_UTXOS_TOPIC,
358+
handlers_config.clone(),
359+
handle_account_utxos_blockfrost,
360+
);
361+
327362
// Handler for /blocks/latest, /blocks/{hash_or_number}
328363
register_handler(
329364
context.clone(),

0 commit comments

Comments
 (0)