Skip to content

Commit

Permalink
feat(CA): adding metadata into the route endpoint response (#831)
Browse files Browse the repository at this point in the history
  • Loading branch information
geekbrother authored Nov 8, 2024
1 parent f3fb070 commit 6e00ba4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 16 deletions.
14 changes: 11 additions & 3 deletions integration/chain_orchestrator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@ describe('Chain abstraction orchestrator', () => {
const from_address_with_funds = "0x2aae531a81461f029cd55cb46703211c9227ba05";
const usdc_funds_on_base = 3_000_000;
const usdc_funds_on_optimism = 1_057_151;
const usdc_token_symbol = "USDC";
// Amount to send to Optimism
const amount_to_send = 3_000_000
// Amount bridging multiplier
const amount_multiplier = 5; // +5% topup
// How much needs to be topped up
const amount_to_topup = (amount_to_send - usdc_funds_on_optimism) * (100 + amount_multiplier) / 100;
const amount_to_topup = Math.round((amount_to_send - usdc_funds_on_optimism) * (100 + amount_multiplier) / 100);
// Default gas esimation is default with 6x increase
const gas_estimate = "0xf9e82";

const receiver_address = "0x739ff389c8eBd9339E69611d46Eec6212179BB67";
const chain_id_optimism = "eip155:10";
const chain_id_base = "eip155:8453";
const usdc_contract_optimism = "0x0b2c639c533813f4aa9d7837caf62653d097ff85";
const chain_id_base = "eip155:8453";
const usdc_contract_base = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";

let orchestration_id = "";

Expand Down Expand Up @@ -195,7 +197,7 @@ describe('Chain abstraction orchestrator', () => {
expect(approvalTransaction.nonce).not.toBe("0x00")
expect(approvalTransaction.gas).toBe(gas_estimate)
const decodedData = erc20Interface.decodeFunctionData('approve', approvalTransaction.data);
expect(decodedData.amount.toString()).toBe(amount_to_topup.toString().split('.')[0])
expect(decodedData.amount.toString()).toBe(amount_to_topup.toString())

// Second transaction expected to be the bridging to the Base
const bridgingTransaction = data.transactions[1]
Expand All @@ -207,6 +209,12 @@ describe('Chain abstraction orchestrator', () => {
const initialTransaction = data.transactions[2]
expect(initialTransaction.data).toBe(transactionObj.transaction.data)

// Check the metadata fundingFrom
const fundingFrom = data.metadata.fundingFrom[0]
expect(fundingFrom.chainId).toBe(chain_id_base)
expect(fundingFrom.symbol).toBe(usdc_token_symbol)
expect(fundingFrom.tokenContract).toBe(usdc_contract_base)
expect(fundingFrom.amount).toBe("0x" + amount_to_topup.toString(16))
// Set the Orchestration ID for the next test
orchestration_id = data.orchestrationId;
})
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/chain_agnostic/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ async fn handler_internal(
+ (erc20_topup_value * U256::from(BRIDGING_AMOUNT_MULTIPLIER)) / U256::from(100);

// Check for possible bridging by iterating over supported assets
if let Some((bridge_chain_id, bridge_contract)) =
if let Some((bridge_chain_id, _, bridge_contract)) =
check_bridging_for_erc20_transfer(query_params.project_id, erc20_topup_value, from_address)
.await?
{
Expand Down
14 changes: 8 additions & 6 deletions src/handlers/chain_agnostic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,25 @@ pub async fn check_erc20_balances(
Ok(balances)
}

/// Check available assets for bridging and return
/// the chain_id, token symbol and contract_address
pub async fn check_bridging_for_erc20_transfer(
rpc_project_id: String,
value: U256,
sender: Address,
) -> Result<Option<(String, Address)>, RpcError> {
) -> Result<Option<(String, String, Address)>, RpcError> {
// Check ERC20 tokens balance for each of supported assets
let mut contracts_per_chain: HashMap<String, Vec<String>> = HashMap::new();
for (_, chain_map) in BRIDGING_AVAILABLE_ASSETS.entries() {
let mut contracts_per_chain: HashMap<(String, String), Vec<String>> = HashMap::new();
for (token_symbol, chain_map) in BRIDGING_AVAILABLE_ASSETS.entries() {
for (chain_id, contract_address) in chain_map.entries() {
contracts_per_chain
.entry((*chain_id).to_string())
.entry((token_symbol.to_string(), (*chain_id).to_string()))
.or_default()
.push((*contract_address).to_string());
}
}
// Making the check for each chain_id
for (chain_id, contracts) in contracts_per_chain {
for ((token_symbol, chain_id), contracts) in contracts_per_chain {
let erc20_balances = check_erc20_balances(
rpc_project_id.clone(),
sender,
Expand All @@ -100,7 +102,7 @@ pub async fn check_bridging_for_erc20_transfer(
.await?;
for (contract, balance) in erc20_balances {
if balance >= value {
return Ok(Some((chain_id, contract)));
return Ok(Some((chain_id, token_symbol, contract)));
}
}
}
Expand Down
37 changes: 31 additions & 6 deletions src/handlers/chain_agnostic/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ pub struct RequiresMultiChainResponse {
pub struct RouteResponse {
orchestration_id: String,
transactions: Vec<Transaction>,
metadata: Metadata,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Metadata {
funding_from: Vec<FundingMetadata>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FundingMetadata {
chain_id: String,
token_contract: Address,
symbol: String,
amount: String,
}

pub async fn handler(
Expand Down Expand Up @@ -147,12 +163,13 @@ async fn handler_internal(
+ (erc20_topup_value * U256::from(BRIDGING_AMOUNT_MULTIPLIER)) / U256::from(100);

// Check for possible bridging by iterating over supported assets
if let Some((bridge_chain_id, bridge_contract)) = check_bridging_for_erc20_transfer(
query_params.project_id.clone(),
erc20_topup_value,
from_address,
)
.await?
if let Some((bridge_chain_id, bridge_token_symbol, bridge_contract)) =
check_bridging_for_erc20_transfer(
query_params.project_id.clone(),
erc20_topup_value,
from_address,
)
.await?
{
// Skip bridging if that's the same chainId and contract address
if bridge_chain_id == request_payload.transaction.chain_id && bridge_contract == to_address
Expand Down Expand Up @@ -300,6 +317,14 @@ async fn handler_internal(
return Ok(Json(RouteResponse {
orchestration_id,
transactions: routes,
metadata: Metadata {
funding_from: vec![FundingMetadata {
chain_id: bridge_chain_id,
token_contract: bridge_contract,
symbol: bridge_token_symbol,
amount: format!("0x{:x}", erc20_topup_value),
}],
},
})
.into_response());
}
Expand Down

0 comments on commit 6e00ba4

Please sign in to comment.