Skip to content

Commit faab2ca

Browse files
committed
feat: account addresses REST handler
Signed-off-by: William Hankins <william@sundae.fi>
1 parent 19c6211 commit faab2ca

File tree

3 files changed

+93
-4
lines changed

3 files changed

+93
-4
lines changed

modules/rest_blockfrost/src/handlers/accounts.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use caryatid_sdk::Context;
1414

1515
use crate::handlers_config::HandlersConfig;
1616
use crate::types::{
17-
AccountRewardREST, AccountWithdrawalREST, DelegationUpdateREST, RegistrationUpdateREST,
17+
AccountAddressREST, AccountRewardREST, AccountWithdrawalREST, DelegationUpdateREST,
18+
RegistrationUpdateREST,
1819
};
1920

2021
#[derive(serde::Serialize)]
@@ -564,6 +565,76 @@ pub async fn handle_account_rewards_blockfrost(
564565
}
565566
}
566567

568+
pub async fn handle_account_addresses_blockfrost(
569+
context: Arc<Context<Message>>,
570+
params: Vec<String>,
571+
handlers_config: Arc<HandlersConfig>,
572+
) -> Result<RESTResponse> {
573+
let account = match parse_stake_address(&params) {
574+
Ok(addr) => addr,
575+
Err(resp) => return Ok(resp),
576+
};
577+
578+
// Prepare the message
579+
let msg = Arc::new(Message::StateQuery(StateQuery::Accounts(
580+
AccountsStateQuery::GetAccountAssociatedAddresses { account },
581+
)));
582+
583+
// Get addresses from historical accounts state
584+
let addresses = query_state(
585+
&context,
586+
&handlers_config.historical_accounts_query_topic,
587+
msg,
588+
|message| match message {
589+
Message::StateQueryResponse(StateQueryResponse::Accounts(
590+
AccountsStateQueryResponse::AccountAssociatedAddresses(addresses),
591+
)) => Ok(Some(addresses)),
592+
Message::StateQueryResponse(StateQueryResponse::Accounts(
593+
AccountsStateQueryResponse::NotFound,
594+
)) => Ok(None),
595+
Message::StateQueryResponse(StateQueryResponse::Accounts(
596+
AccountsStateQueryResponse::Error(e),
597+
)) => Err(anyhow::anyhow!(
598+
"Internal server error while retrieving account addresses: {e}"
599+
)),
600+
_ => Err(anyhow::anyhow!(
601+
"Unexpected message type while retrieving account addresses"
602+
)),
603+
},
604+
)
605+
.await?;
606+
607+
let Some(addresses) = addresses else {
608+
return Ok(RESTResponse::with_text(404, "Account not found"));
609+
};
610+
611+
let rest_response = match addresses
612+
.iter()
613+
.map(|r| {
614+
Ok::<_, anyhow::Error>(AccountAddressREST {
615+
address: r.to_string().map_err(|e| anyhow!("invalid address: {e}"))?,
616+
})
617+
})
618+
.collect::<Result<Vec<AccountAddressREST>, _>>()
619+
{
620+
Ok(v) => v,
621+
Err(e) => {
622+
return Ok(RESTResponse::with_text(
623+
500,
624+
&format!("Failed to convert address entry: {e}"),
625+
));
626+
}
627+
};
628+
629+
match serde_json::to_string_pretty(&rest_response) {
630+
Ok(json) => Ok(RESTResponse::with_json(200, &json)),
631+
Err(e) => Ok(RESTResponse::with_text(
632+
500,
633+
&format!("Internal server error while serializing addresses: {e}"),
634+
)),
635+
}
636+
}
637+
567638
fn parse_stake_address(params: &[String]) -> Result<StakeAddress, RESTResponse> {
568639
let Some(stake_key) = params.first() else {
569640
return Err(RESTResponse::with_text(

modules/rest_blockfrost/src/rest_blockfrost.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ mod types;
1717
mod utils;
1818
use handlers::{
1919
accounts::{
20-
handle_account_delegations_blockfrost, handle_account_mirs_blockfrost,
21-
handle_account_registrations_blockfrost, handle_account_rewards_blockfrost,
22-
handle_account_withdrawals_blockfrost, handle_single_account_blockfrost,
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,
2324
},
2425
addresses::{
2526
handle_address_asset_utxos_blockfrost, handle_address_extended_blockfrost,
@@ -85,6 +86,10 @@ const DEFAULT_HANDLE_ACCOUNT_REWARDS_TOPIC: (&str, &str) = (
8586
"handle-topic-account-rewards",
8687
"rest.get.accounts.*.rewards",
8788
);
89+
const DEFAULT_HANDLE_ACCOUNT_ADDRESSES_TOPIC: (&str, &str) = (
90+
"handle-topic-account-addresses",
91+
"rest.get.accounts.*.addresses",
92+
);
8893

8994
// Blocks topics
9095
const DEFAULT_HANDLE_BLOCKS_LATEST_HASH_NUMBER_TOPIC: (&str, &str) =
@@ -311,6 +316,14 @@ impl BlockfrostREST {
311316
handle_account_rewards_blockfrost,
312317
);
313318

319+
// Handler for /accounts/{stake_address}/addresses
320+
register_handler(
321+
context.clone(),
322+
DEFAULT_HANDLE_ACCOUNT_ADDRESSES_TOPIC,
323+
handlers_config.clone(),
324+
handle_account_addresses_blockfrost,
325+
);
326+
314327
// Handler for /blocks/latest, /blocks/{hash_or_number}
315328
register_handler(
316329
context.clone(),

modules/rest_blockfrost/src/types.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,3 +894,8 @@ impl TryFrom<&AccountReward> for AccountRewardREST {
894894
})
895895
}
896896
}
897+
898+
#[derive(Serialize)]
899+
pub struct AccountAddressREST {
900+
pub address: String,
901+
}

0 commit comments

Comments
 (0)