Skip to content

Commit

Permalink
Improve error handling in fireblocks crate
Browse files Browse the repository at this point in the history
  • Loading branch information
pablodeymo committed Sep 18, 2024
1 parent b9f4edf commit 3d09230
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 164 deletions.
17 changes: 5 additions & 12 deletions crates/chainio/clients/fireblocks/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,11 @@ impl Client {
body_hash,
};

let encoding_key_result = EncodingKey::from_rsa_pem(self.private_key.as_bytes());
match encoding_key_result {
Ok(encoding_key) => {
let token_result = encode(&Header::new(Algorithm::RS256), &claims, &encoding_key);

match token_result {
Ok(token) => Ok(token),
Err(e) => Err(FireBlockError::JsonWebTokenError(e)),
}
}
Err(e) => Err(FireBlockError::JsonWebTokenError(e)),
}
let encoding_key = EncodingKey::from_rsa_pem(self.private_key.as_bytes())
.map_err(FireBlockError::JsonWebTokenError)?;

encode(&Header::new(Algorithm::RS256), &claims, &encoding_key)
.map_err(FireBlockError::JsonWebTokenError)
}

/// GET : Request to the fireblocks endpoint using the given path.
Expand Down
13 changes: 3 additions & 10 deletions crates/chainio/clients/fireblocks/src/contract_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,10 @@ impl ContractCall for Client {
serde_json::to_string(&transaction_request).map_err(FireBlockError::SerdeError)?;

// Call POST request
let contract_call_result = self
let contract_call = self
.post_request("/v1/transactions/", Some(&transaction_json.to_string()))
.await;
match contract_call_result {
Ok(contract_call) => {
let contract_call_req: TransactionResponse =
serde_json::from_str(&contract_call).unwrap();
Ok(contract_call_req)
}
Err(e) => Err(e),
}
.await?;
serde_json::from_str(&contract_call).map_err(FireBlockError::SerdeError)
}
}

Expand Down
18 changes: 3 additions & 15 deletions crates/chainio/clients/fireblocks/src/get_asset_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,14 @@ impl GetAssetAddresses for Client {
vault_id: String,
asset_id: AssetID,
) -> Result<AddressesResponse, FireBlockError> {
let asset_addresses_result = self
let asset_addresses = self
.get_request(&format!(
"/v1/vault/accounts/{}/{}/addresses_paginated",
vault_id, asset_id
))
.await;
.await?;

match asset_addresses_result {
Ok(asset_addresses) => {
let asset_address_result: Result<AddressesResponse, _> =
serde_json::from_str(&asset_addresses);

match asset_address_result {
Ok(asset_address) => Ok(asset_address),

Err(e) => Err(FireBlockError::SerdeError(e)),
}
}
Err(e) => Err(e),
}
serde_json::from_str(&asset_addresses).map_err(FireBlockError::SerdeError)
}
}

Expand Down
17 changes: 3 additions & 14 deletions crates/chainio/clients/fireblocks/src/get_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,11 @@ pub trait GetTransaction {

impl GetTransaction for Client {
async fn get_transaction(&self, tx_id: String) -> Result<Transaction, FireBlockError> {
let transaction_object_result = self
let transaction = self
.get_request(&format!("/v1/transactions/{}", tx_id))
.await;
.await?;

match transaction_object_result {
Ok(transaction) => {
let serialized_tx_result: Result<Transaction, _> =
serde_json::from_str(&transaction);

match serialized_tx_result {
Ok(serialized_tx) => Ok(serialized_tx),
Err(e) => Err(FireBlockError::SerdeError(e)),
}
}
Err(e) => Err(e),
}
serde_json::from_str(&transaction).map_err(FireBlockError::SerdeError)
}
}

Expand Down
112 changes: 44 additions & 68 deletions crates/chainio/clients/fireblocks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,43 +53,35 @@ impl FireblocksWallet {
vault_account_name: String,
) -> Result<FireblocksWallet, error::FireBlockError> {
let provider_ = get_provider(&provider);
let chain_id_result = provider_.get_chain_id().await;
let chain_id = provider_.get_chain_id().await.map_err(|e| {
FireBlockError::AlloyContractError(alloy_contract::Error::TransportError(e))
})?;

match chain_id_result {
Ok(chain_id) => Ok(Self {
fireblocks_client,
vault_account_name,
chain_id,
provider,
vault_account: None,
whitelisted_accounts: HashMap::new(),
whitelisted_contracts: HashMap::new(),
tx_id_to_nonce: HashMap::new(),
}),
Err(e) => Err(FireBlockError::AlloyContractError(
alloy_contract::Error::TransportError(e),
)),
}
Ok(Self {
fireblocks_client,
vault_account_name,
chain_id,
provider,
vault_account: None,
whitelisted_accounts: HashMap::new(),
whitelisted_contracts: HashMap::new(),
tx_id_to_nonce: HashMap::new(),
})
}

/// Get Vault Accounts
pub async fn get_account(&mut self) -> Result<Option<VaultAccount>, FireBlockError> {
match &self.vault_account {
None => {
let accounts_result = self.fireblocks_client.list_vault_accounts().await;
let accounts = self.fireblocks_client.list_vault_accounts().await?;

match accounts_result {
Ok(accounts) => {
for account in accounts.vault_accounts().iter() {
if account.name().eq(&self.vault_account_name) {
self.vault_account = Some(account.clone());
break;
}
}
Ok(self.vault_account.clone())
for account in accounts.vault_accounts().iter() {
if account.name().eq(&self.vault_account_name) {
self.vault_account = Some(account.clone());
break;
}
Err(e) => Err(e),
}
Ok(self.vault_account.clone())
}
Some(account) => Ok(Some(account.clone())),
}
Expand All @@ -114,29 +106,23 @@ impl FireblocksWallet {
}
false => {
let whitelisted_accounts;
let accounts_result = self.fireblocks_client.list_external_accounts().await;
let accounts = self.fireblocks_client.list_external_accounts().await?;

match accounts_result {
Ok(accounts) => {
for account in accounts.iter() {
for asset in account.assets.iter() {
if asset.address.as_ref().unwrap().eq(&address.to_string())
&& asset.status.as_ref().unwrap().as_str() == "APPROVED"
&& *asset.id.as_ref().unwrap()
== *ASSET_ID_BY_CHAIN.get(&self.chain_id).unwrap()
{
self.whitelisted_accounts
.insert(address, account.clone());
whitelisted_accounts = account;
return Ok(whitelisted_accounts.clone());
}
}
for account in accounts.iter() {
for asset in account.assets.iter() {
if asset.address.as_ref().unwrap().eq(&address.to_string())
&& asset.status.as_ref().unwrap().as_str() == "APPROVED"
&& *asset.id.as_ref().unwrap()
== *ASSET_ID_BY_CHAIN.get(&self.chain_id).unwrap()
{
self.whitelisted_accounts.insert(address, account.clone());
whitelisted_accounts = account;
return Ok(whitelisted_accounts.clone());
}

Ok(WhitelistedAccount::default())
}
Err(e) => Err(e),
}

Ok(WhitelistedAccount::default())
}
}
}
Expand Down Expand Up @@ -203,34 +189,24 @@ impl FireblocksWallet {
.fireblocks_client
.get_transaction(tx_id.clone())
.await?;

match fireblocks_tx.status() {
Status::Completed => {
let provider = get_provider(&self.provider);
let hash_result =
alloy_primitives::FixedBytes::<32>::from_str(&fireblocks_tx.tx_hash());
match hash_result {
Ok(hash) => {
let tx_hash_result = provider.get_transaction_receipt(hash).await;
let hash = alloy_primitives::FixedBytes::<32>::from_str(&fireblocks_tx.tx_hash())
.map_err(|e| FireBlockError::OtherError(e.to_string()))?;

match tx_hash_result {
Ok(tx_hash) => {
if let Some(tx) = tx_hash {
if self.tx_id_to_nonce.contains_key(&tx_id) {
self.tx_id_to_nonce.remove(&tx_id);
}
Ok(tx)
} else {
Err(FireBlockError::TransactionReceiptNotFound(tx_id))
}
}
Err(e) => Err(FireBlockError::AlloyContractError(
alloy_contract::Error::TransportError(e),
)),
}
}
let tx_hash = provider.get_transaction_receipt(hash).await.map_err(|e| {
FireBlockError::AlloyContractError(alloy_contract::Error::TransportError(e))
})?;

let tx =
tx_hash.ok_or(FireBlockError::TransactionReceiptNotFound(tx_id.clone()))?;

Err(e) => Err(FireBlockError::OtherError(e.to_string())),
if self.tx_id_to_nonce.contains_key(&tx_id) {
self.tx_id_to_nonce.remove(&tx_id);
}
Ok(tx)
}
Status::Failed | Status::Rejected | Status::Cancelled | Status::Blocked => {
Err(FireBlockError::TransactionFailed(
Expand Down
27 changes: 11 additions & 16 deletions crates/chainio/clients/fireblocks/src/list_contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,18 @@ pub trait ListContracts {

impl ListContracts for Client {
async fn list_contracts(&self) -> Result<WhitelistedContractResponse, FireBlockError> {
let list_contracts_result = self.get_request("/v1/contracts").await;
match list_contracts_result {
Ok(list_contracts_object) => {
if list_contracts_object.trim() == "[]" {
return Ok(WhitelistedContractResponse {
contracts: Vec::new(),
});
}
let serialized_tx: Result<Vec<WhitelistedContract>, _> =
serde_json::from_str(&list_contracts_object);
match serialized_tx {
Ok(contracts) => Ok(WhitelistedContractResponse { contracts }),
Err(e) => Err(FireBlockError::SerdeError(e)),
}
}
Err(e) => Err(e),
let list_contracts_object = self.get_request("/v1/contracts").await?;

if list_contracts_object.trim() == "[]" {
return Ok(WhitelistedContractResponse {
contracts: Vec::new(),
});
}

let contracts: Vec<WhitelistedContract> =
serde_json::from_str(&list_contracts_object).map_err(FireBlockError::SerdeError)?;

Ok(WhitelistedContractResponse { contracts })
}
}

Expand Down
20 changes: 5 additions & 15 deletions crates/chainio/clients/fireblocks/src/list_external_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,13 @@ pub trait ListExternalAccounts {

impl ListExternalAccounts for Client {
async fn list_external_accounts(&self) -> Result<Vec<WhitelistedAccount>, FireBlockError> {
let list_external_accounts_result = self.get_request("/v1/external_wallets").await;
let list_external_accounts = self.get_request("/v1/external_wallets").await?;

match list_external_accounts_result {
Ok(list_external_accounts) => {
if list_external_accounts.trim() == "[]" {
let default_accounts = vec![WhitelistedAccount::default()];
return Ok(default_accounts);
}
let serialized_tx: Result<Vec<WhitelistedAccount>, _> =
serde_json::from_str(&list_external_accounts);
match serialized_tx {
Ok(whitelisted_accounts) => Ok(whitelisted_accounts),
Err(e) => Err(FireBlockError::SerdeError(e)),
}
}
Err(e) => Err(e),
if list_external_accounts.trim() == "[]" {
let default_accounts = vec![WhitelistedAccount::default()];
return Ok(default_accounts);
}
serde_json::from_str(&list_external_accounts).map_err(FireBlockError::SerdeError)
}
}

Expand Down
16 changes: 2 additions & 14 deletions crates/chainio/clients/fireblocks/src/list_vault_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,8 @@ pub trait ListVaultAccounts {

impl ListVaultAccounts for Client {
async fn list_vault_accounts(&self) -> Result<VaultAccountResponse, FireBlockError> {
let list_vault_accounts_result = self.get_request("/v1/vault/accounts_paged").await;

match list_vault_accounts_result {
Ok(list_vault_accounts) => {
let vault_accounts_result: Result<VaultAccountResponse, _> =
serde_json::from_str(&list_vault_accounts);

match vault_accounts_result {
Ok(vault_accounts) => Ok(vault_accounts),
Err(e) => Err(FireBlockError::SerdeError(e)),
}
}
Err(e) => Err(e),
}
let list_vault_accounts = self.get_request("/v1/vault/accounts_paged").await?;
serde_json::from_str(&list_vault_accounts).map_err(FireBlockError::SerdeError)
}
}

Expand Down

0 comments on commit 3d09230

Please sign in to comment.