Skip to content

Commit b555a59

Browse files
committed
feat: account assets REST handler
Signed-off-by: William Hankins <[email protected]>
1 parent 959680d commit b555a59

File tree

1 file changed

+100
-5
lines changed

1 file changed

+100
-5
lines changed

modules/rest_blockfrost/src/handlers/accounts.rs

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use caryatid_sdk::Context;
1717

1818
use crate::handlers_config::HandlersConfig;
1919
use crate::types::{
20-
AccountAddressREST, AccountRewardREST, AccountUTxOREST, AccountWithdrawalREST,
20+
AccountAddressREST, AccountRewardREST, AccountUTxOREST, AccountWithdrawalREST, AmountList,
2121
DelegationUpdateREST, RegistrationUpdateREST,
2222
};
2323

@@ -640,11 +640,106 @@ pub async fn handle_account_addresses_blockfrost(
640640

641641
/// Handle `/accounts/{stake_address}/addresses/assets` Blockfrost-compatible endpoint
642642
pub async fn handle_account_assets_blockfrost(
643-
_context: Arc<Context<Message>>,
644-
_params: Vec<String>,
645-
_handlers_config: Arc<HandlersConfig>,
643+
context: Arc<Context<Message>>,
644+
params: Vec<String>,
645+
handlers_config: Arc<HandlersConfig>,
646646
) -> Result<RESTResponse> {
647-
Ok(RESTResponse::with_text(501, "Not implemented"))
647+
let account = match parse_stake_address(&params) {
648+
Ok(addr) => addr,
649+
Err(resp) => return Ok(resp),
650+
};
651+
652+
// Get addresses from historical accounts state
653+
let msg = Arc::new(Message::StateQuery(StateQuery::Accounts(
654+
AccountsStateQuery::GetAccountAssociatedAddresses { account },
655+
)));
656+
let addresses = query_state(
657+
&context,
658+
&handlers_config.historical_accounts_query_topic,
659+
msg,
660+
|message| match message {
661+
Message::StateQueryResponse(StateQueryResponse::Accounts(
662+
AccountsStateQueryResponse::AccountAssociatedAddresses(addresses),
663+
)) => Ok(Some(addresses)),
664+
Message::StateQueryResponse(StateQueryResponse::Accounts(
665+
AccountsStateQueryResponse::NotFound,
666+
)) => Ok(None),
667+
Message::StateQueryResponse(StateQueryResponse::Accounts(
668+
AccountsStateQueryResponse::Error(e),
669+
)) => Err(anyhow::anyhow!(
670+
"Internal server error while retrieving account addresses: {e}"
671+
)),
672+
_ => Err(anyhow::anyhow!(
673+
"Unexpected message type while retrieving account addresses"
674+
)),
675+
},
676+
)
677+
.await?;
678+
679+
let Some(addresses) = addresses else {
680+
return Ok(RESTResponse::with_text(404, "Account not found"));
681+
};
682+
683+
// Get utxos from address state
684+
let msg = Arc::new(Message::StateQuery(StateQuery::Addresses(
685+
AddressStateQuery::GetAddressesUTxOs { addresses },
686+
)));
687+
let utxo_identifiers = query_state(
688+
&context,
689+
&handlers_config.addresses_query_topic,
690+
msg,
691+
|message| match message {
692+
Message::StateQueryResponse(StateQueryResponse::Addresses(
693+
AddressStateQueryResponse::AddressesUTxOs(utxos),
694+
)) => Ok(utxos),
695+
Message::StateQueryResponse(StateQueryResponse::Addresses(
696+
AddressStateQueryResponse::Error(e),
697+
)) => Err(anyhow::anyhow!(
698+
"Internal server error while retrieving account UTxOs: {e}"
699+
)),
700+
_ => Err(anyhow::anyhow!(
701+
"Unexpected message type while retrieving account UTxOs"
702+
)),
703+
},
704+
)
705+
.await?;
706+
707+
// Get utxo balance sum from utxo state
708+
let msg = Arc::new(Message::StateQuery(StateQuery::UTxOs(
709+
UTxOStateQuery::GetUTxOsSum { utxo_identifiers },
710+
)));
711+
let utxos_balance = query_state(
712+
&context,
713+
&handlers_config.addresses_query_topic,
714+
msg,
715+
|message| match message {
716+
Message::StateQueryResponse(StateQueryResponse::UTxOs(
717+
UTxOStateQueryResponse::UTxOsSum(sum),
718+
)) => Ok(sum),
719+
Message::StateQueryResponse(StateQueryResponse::UTxOs(
720+
UTxOStateQueryResponse::Error(e),
721+
)) => Err(anyhow::anyhow!(
722+
"Internal server error while retrieving account UTxOs: {e}"
723+
)),
724+
_ => Err(anyhow::anyhow!(
725+
"Unexpected message type while retrieving account UTxOs"
726+
)),
727+
},
728+
)
729+
.await?;
730+
731+
let mut rest_response = AmountList::from(utxos_balance).0;
732+
if !rest_response.is_empty() {
733+
rest_response.drain(..1);
734+
}
735+
736+
match serde_json::to_string_pretty(&rest_response) {
737+
Ok(json) => Ok(RESTResponse::with_json(200, &json)),
738+
Err(e) => Ok(RESTResponse::with_text(
739+
500,
740+
&format!("Internal server error while serializing addresses: {e}"),
741+
)),
742+
}
648743
}
649744

650745
/// Handle `/accounts/{stake_address}/addresses/total` Blockfrost-compatible endpoint

0 commit comments

Comments
 (0)