Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/chain_primitives/src/balance_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl SwapMapper {
to_asset: received_diff.asset_id.clone(),
to_value: to_value.to_string(),
provider,
swap_result: None,
})
}

Expand Down
1 change: 1 addition & 0 deletions crates/gem_evm/src/rpc/swap_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ impl SwapMapper {
from_value,
to_value,
provider: Some(provider.to_string()),
swap_result: None,
});
}
None
Expand Down
4 changes: 4 additions & 0 deletions crates/gem_solana/src/provider/transaction_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ pub fn map_transaction(transaction: &BlockTransaction, block_time: i64) -> Optio
to_asset: to_asset.clone(),
to_value: to_value.clone().to_string(),
provider: Some(SwapProvider::Jupiter.id().to_owned()),
swap_result: None,
};

let transaction = Transaction::new(
Expand Down Expand Up @@ -205,6 +206,7 @@ mod tests {
to_asset: Chain::Solana.as_asset_id(),
to_value: "139512057".to_string(),
provider: Some(SwapProvider::Jupiter.id().to_owned()),
swap_result: None,
};

assert_eq!(transaction.metadata, Some(serde_json::to_value(expected).unwrap()));
Expand All @@ -222,6 +224,7 @@ mod tests {
to_asset: AssetId::from_token(Chain::Solana, "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"),
to_value: "999932".to_string(),
provider: Some(SwapProvider::Jupiter.id().to_owned()),
swap_result: None,
};

assert_eq!(transaction.metadata, Some(serde_json::to_value(expected).unwrap()));
Expand All @@ -239,6 +242,7 @@ mod tests {
to_asset: AssetId::from_token(Chain::Solana, "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"),
to_value: "1678930".to_string(),
provider: Some(SwapProvider::Jupiter.id().to_owned()),
swap_result: None,
};

assert_eq!(transaction.metadata, Some(serde_json::to_value(expected).unwrap()));
Expand Down
2 changes: 1 addition & 1 deletion crates/primitives/src/explorers/near_intents.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::block_explorer::BlockExplorer;
use super::near::NEAR_BLOCKS_BASE_URL;
use crate::block_explorer::BlockExplorer;

pub struct NearIntents;

Expand Down
4 changes: 3 additions & 1 deletion crates/primitives/src/transaction_metadata_types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use typeshare::typeshare;

use crate::{AssetId, NFTAssetId, PerpetualDirection, PerpetualProvider};
use crate::{AssetId, NFTAssetId, PerpetualDirection, PerpetualProvider, swap::SwapResult};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[typeshare(swift = "Sendable")]
Expand All @@ -22,6 +22,8 @@ pub struct TransactionSwapMetadata {
pub to_asset: AssetId,
pub to_value: String,
pub provider: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub swap_result: Option<SwapResult>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
19 changes: 16 additions & 3 deletions crates/swapper/src/across/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use primitives::{Chain, swap::SwapStatus};
use serde::{Deserialize, Serialize};
use std::sync::Arc;

const FUNDS_DEPOSITED_TOPIC: &str = "0x32ed1a409ef04c7b0227189c3a103dc5ac10e775a15b785dcc510201f7c25ad3";

#[derive(Debug, Clone)]
pub struct AcrossApi {
pub url: String,
Expand Down Expand Up @@ -50,11 +52,22 @@ impl AcrossApi {
.await
.map_err(SwapperError::from)?;

if receipt.logs.len() < 2 || receipt.logs[1].topics.len() < 3 {
return Err(SwapperError::NetworkError("invalid tx receipt".into()));
let deposit_log = receipt
.logs
.iter()
.find(|log| {
log.topics
.first()
.map(|topic| topic.eq_ignore_ascii_case(FUNDS_DEPOSITED_TOPIC))
.unwrap_or(false)
})
.ok_or_else(|| SwapperError::NetworkError("FundsDeposited event not found".into()))?;

if deposit_log.topics.len() < 3 {
return Err(SwapperError::NetworkError("invalid FundsDeposited topics".into()));
}
// The deposit ID is in topics[2] (topics[0] is event signature, topics[1] is destination chain ID)
let deposit_id_hex = receipt.logs[1].topics[2].clone();
let deposit_id_hex = deposit_log.topics[2].clone();

// Convert hex deposit ID to decimal string
let deposit_id = if let Some(stripped) = deposit_id_hex.strip_prefix("0x") {
Expand Down
17 changes: 16 additions & 1 deletion crates/swapper/src/hyperliquid/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use async_trait::async_trait;
use gem_hypercore::core::{HYPE_SYSTEM_ADDRESS, HYPERCORE_HYPE_TOKEN, actions::user::spot_send::SpotSend, hypercore::transfer_to_hyper_evm_typed_data};
use number_formatter::BigNumberFormatter;

use primitives::Chain;
use primitives::{
Chain,
swap::{SwapResult, SwapStatus},
};

use crate::{
FetchQuoteData, ProviderData, ProviderType, Quote, QuoteRequest, Route, Swapper, SwapperChainAsset, SwapperError, SwapperProvider, SwapperQuoteData,
Expand Down Expand Up @@ -93,4 +96,16 @@ impl Swapper for HyperCoreBridge {
_ => Err(SwapperError::NotSupportedChain),
}
}

async fn get_swap_result(&self, chain: Chain, transaction_hash: &str) -> Result<SwapResult, SwapperError> {
let from_chain = chain;
let to_chain = if chain == Chain::HyperCore { Chain::Hyperliquid } else { Chain::HyperCore };
Ok(SwapResult {
status: SwapStatus::Completed,
from_chain,
from_tx_hash: transaction_hash.to_string(),
to_chain: Some(to_chain),
to_tx_hash: None,
})
}
}
23 changes: 14 additions & 9 deletions crates/swapper/src/models.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use super::permit2_data::Permit2Data;
use crate::{
SwapperMode, SwapperProvider, SwapperProviderMode, SwapperQuoteAsset, SwapperSlippage,
SwapperMode, SwapperProvider, SwapperQuoteAsset, SwapperSlippage,
config::{DEFAULT_SLIPPAGE_BPS, ReferralFees},
};
pub use primitives::swap::SwapResult;
use primitives::{AssetId, Chain, swap::ApprovalData};
use primitives::{
AssetId, Chain,
swap::{ApprovalData, SwapProviderMode},
};
use std::fmt::Debug;

#[derive(Debug, Clone, PartialEq)]
Expand All @@ -13,6 +16,7 @@ pub struct ProviderType {
pub name: String,
pub protocol: String,
pub protocol_id: String,
pub mode: SwapProviderMode,
}

impl ProviderType {
Expand All @@ -22,11 +26,12 @@ impl ProviderType {
name: id.name().to_string(),
protocol: id.protocol_name().to_string(),
protocol_id: id.id().to_string(),
mode: ProviderType::mode(id),
}
}

pub fn mode(&self) -> SwapperProviderMode {
match self.id {
pub fn mode(id: SwapperProvider) -> SwapProviderMode {
match id {
SwapperProvider::UniswapV3
| SwapperProvider::UniswapV4
| SwapperProvider::PancakeswapV3
Expand All @@ -39,11 +44,11 @@ impl ProviderType {
| SwapperProvider::StonfiV2
| SwapperProvider::Reservoir
| SwapperProvider::Aerodrome
| SwapperProvider::Orca => SwapperProviderMode::OnChain,
SwapperProvider::Mayan | SwapperProvider::Chainflip | SwapperProvider::NearIntents => SwapperProviderMode::CrossChain,
SwapperProvider::Thorchain => SwapperProviderMode::OmniChain(vec![Chain::Thorchain, Chain::Tron]),
SwapperProvider::Relay => SwapperProviderMode::OmniChain(vec![Chain::Hyperliquid, Chain::Manta, Chain::Berachain]),
SwapperProvider::Across | SwapperProvider::Hyperliquid => SwapperProviderMode::Bridge,
| SwapperProvider::Orca => SwapProviderMode::OnChain,
SwapperProvider::Mayan | SwapperProvider::Chainflip | SwapperProvider::NearIntents => SwapProviderMode::CrossChain,
SwapperProvider::Thorchain => SwapProviderMode::OmniChain(vec![Chain::Thorchain, Chain::Tron]),
SwapperProvider::Relay => SwapProviderMode::OmniChain(vec![Chain::Hyperliquid, Chain::Manta, Chain::Berachain]),
SwapperProvider::Across | SwapperProvider::Hyperliquid => SwapProviderMode::Bridge,
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions crates/swapper/src/near_intents/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ pub struct SwapDetails {
#[serde(default)]
pub amount_out: Option<String>,
#[serde(default)]
pub slippage: Option<u32>,
#[serde(default)]
pub origin_chain_tx_hashes: Vec<TransactionDetails>,
#[serde(default)]
pub destination_chain_tx_hashes: Vec<TransactionDetails>,
Expand Down
2 changes: 1 addition & 1 deletion crates/swapper/src/proxy/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ where
}
// For OnChain providers, use the default implementation
_ => {
if self.provider.mode() == SwapperProviderMode::OnChain {
if self.provider.mode == SwapperProviderMode::OnChain {
Ok(self.get_onchain_swap_status(chain, transaction_hash))
} else {
Err(SwapperError::NotImplemented)
Expand Down
14 changes: 7 additions & 7 deletions crates/swapper/src/swapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct GemSwapper {

impl GemSwapper {
// filter provider types that does not support cross chain / bridge swaps
fn filter_by_provider_mode(mode: SwapperProviderMode, from_chain: Chain, to_chain: Chain) -> bool {
fn filter_by_provider_mode(mode: &SwapperProviderMode, from_chain: Chain, to_chain: Chain) -> bool {
match mode {
SwapperProviderMode::OnChain => from_chain == to_chain,
SwapperProviderMode::Bridge | SwapperProviderMode::CrossChain => from_chain != to_chain,
Expand Down Expand Up @@ -145,7 +145,7 @@ impl GemSwapper {
let providers = self
.swappers
.iter()
.filter(|x| Self::filter_by_provider_mode(x.provider().mode(), from_chain, to_chain))
.filter(|x| Self::filter_by_provider_mode(&x.provider().mode, from_chain, to_chain))
.filter(|x| Self::filter_by_supported_chains(x.supported_chains(), from_chain, to_chain))
.filter(|x| Self::filter_by_preferred_providers(preferred_providers, &x.provider().id))
.collect::<Vec<_>>();
Expand Down Expand Up @@ -256,7 +256,7 @@ mod tests {
// Cross chain swaps (same chain will be filtered out)
let filtered = providers
.iter()
.filter(|x| GemSwapper::filter_by_provider_mode(ProviderType::new(**x).mode(), Chain::Ethereum, Chain::Optimism))
.filter(|x| GemSwapper::filter_by_provider_mode(&ProviderType::new(**x).mode, Chain::Ethereum, Chain::Optimism))
.cloned()
.collect::<Vec<_>>();

Expand All @@ -278,7 +278,7 @@ mod tests {

let filtered = swappers
.iter()
.filter(|x| GemSwapper::filter_by_provider_mode(x.provider().mode(), from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_provider_mode(&x.provider().mode, from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_supported_chains(x.supported_chains(), from_chain, to_chain))
.collect::<Vec<_>>();

Expand All @@ -289,7 +289,7 @@ mod tests {

let filtered = swappers
.iter()
.filter(|x| GemSwapper::filter_by_provider_mode(x.provider().mode(), from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_provider_mode(&x.provider().mode, from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_supported_chains(x.supported_chains(), from_chain, to_chain))
.collect::<Vec<_>>();

Expand All @@ -304,7 +304,7 @@ mod tests {

let filtered = swappers
.iter()
.filter(|x| GemSwapper::filter_by_provider_mode(x.provider().mode(), from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_provider_mode(&x.provider().mode, from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_supported_chains(x.supported_chains(), from_chain, to_chain))
.collect::<Vec<_>>();

Expand All @@ -316,7 +316,7 @@ mod tests {

let filtered = swappers
.iter()
.filter(|x| GemSwapper::filter_by_provider_mode(x.provider().mode(), from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_provider_mode(&x.provider().mode, from_chain, to_chain))
.filter(|x| GemSwapper::filter_by_supported_chains(x.supported_chains(), from_chain, to_chain))
.collect::<Vec<_>>();

Expand Down
2 changes: 1 addition & 1 deletion crates/swapper/src/swapper_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub trait Swapper: Send + Sync + Debug {
}
async fn fetch_quote_data(&self, quote: &Quote, data: FetchQuoteData) -> Result<SwapperQuoteData, SwapperError>;
async fn get_swap_result(&self, chain: Chain, transaction_hash: &str) -> Result<SwapResult, SwapperError> {
if self.provider().mode() == SwapperProviderMode::OnChain {
if self.provider().mode == SwapperProviderMode::OnChain {
Ok(self.get_onchain_swap_status(chain, transaction_hash))
} else {
Err(SwapperError::NotImplemented)
Expand Down
1 change: 1 addition & 0 deletions gemstone/src/gem_swapper/remote_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub struct SwapperProviderType {
pub name: String,
pub protocol: String,
pub protocol_id: String,
pub mode: SwapperProviderMode,
}

#[uniffi::remote(Record)]
Expand Down
Loading