Skip to content
This repository was archived by the owner on Jun 1, 2026. It is now read-only.

Commit 58e5f5d

Browse files
committed
Migrate okx to /swaps
1 parent 3b92c5f commit 58e5f5d

25 files changed

Lines changed: 772 additions & 76 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Settings.yaml

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -201,24 +201,12 @@ chains:
201201
url: https://rpc.stable.xyz
202202

203203
swap:
204-
jupiter:
205-
url: "https://quote-api.jup.ag"
206-
key: ""
207-
fee:
208-
percent: 0
209-
address: ""
210-
thorchain:
211-
url: "https://thornode.ninerealms.com"
212-
key: ""
213-
fee:
214-
percent: 0
215-
address: ""
216-
aftermath:
217-
url: "https://aftermath.finance/api"
218-
key: ""
219-
fee:
220-
percent: 0
221-
address: ""
204+
okx:
205+
key:
206+
public: ""
207+
secret: ""
208+
passphrase: ""
209+
project: ""
222210
scan:
223211
timeout: 1200ms
224212
goplus:

apps/api/src/main.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use settings::Settings;
5151
use settings_chain::{ChainProviders, ProviderFactory};
5252
use storage::Database;
5353
use streamer::{StreamProducer, StreamProducerConfig};
54-
use swap::SwapClient;
54+
use swap::{OkxApiClient, SwapClient};
5555
use swapper::swapper::GemSwapper;
5656
use webhooks::WebhooksClient;
5757
use websocket_prices::PriceObserverConfig;
@@ -96,6 +96,8 @@ fn mount_routes(rocket: Rocket<Build>, admin_enabled: bool) -> Rocket<Build> {
9696
chain::transaction::get_transaction,
9797
referral::get_rewards_leaderboard,
9898
swap::post_near_intents_quote,
99+
swap::okx::post_okx_quote,
100+
swap::okx::post_okx_quote_data,
99101
],
100102
)
101103
.mount(
@@ -184,7 +186,8 @@ async fn rocket_api(settings: Settings) -> Result<Rocket<Build>, Box<dyn std::er
184186
let chain_client = chain::ChainClient::new(ChainProviders::new(ProviderFactory::new_providers(&settings)));
185187
let portfolio_client = PortfolioClient::new(database.clone(), price_config);
186188
let endpoints = ProviderFactory::get_chain_endpoints(&settings);
187-
let swapper = Arc::new(GemSwapper::new(Arc::new(swapper::NativeProvider::new_with_endpoints(endpoints))));
189+
let native_provider = Arc::new(swapper::NativeProvider::new_with_endpoints(endpoints));
190+
let swapper = Arc::new(GemSwapper::new(native_provider.clone()));
188191

189192
let retry = streamer::Retry::new(settings.rabbitmq.retry.delay, settings.rabbitmq.retry.timeout);
190193
let rabbitmq_config = StreamProducerConfig::new(settings.rabbitmq.url.clone(), retry);
@@ -231,6 +234,15 @@ async fn rocket_api(settings: Settings) -> Result<Rocket<Build>, Box<dyn std::er
231234
let redemption_client = RewardsRedemptionClient::new(database.clone(), stream_producer.clone());
232235
let notifications_client = NotificationsClient::new(database.clone());
233236
let near_intents_client = swap::NearIntentsProxyClient::new(cacher_client.clone());
237+
let okx_api_client = OkxApiClient::new(
238+
swapper::okx::OkxClientConfig {
239+
api_key: settings.swap.okx.key.public.clone(),
240+
secret_key: settings.swap.okx.key.secret.clone(),
241+
passphrase: settings.swap.okx.passphrase.clone(),
242+
project: settings.swap.okx.project.clone(),
243+
},
244+
native_provider.clone(),
245+
);
234246
let jwt_config = devices::auth_config::JwtConfig {
235247
secret: settings.api.auth.jwt.secret.clone(),
236248
expiry: settings.api.auth.jwt.expiry,
@@ -264,6 +276,7 @@ async fn rocket_api(settings: Settings) -> Result<Rocket<Build>, Box<dyn std::er
264276
.manage(Mutex::new(wallets_client))
265277
.manage(Mutex::new(notifications_client))
266278
.manage(Mutex::new(near_intents_client))
279+
.manage(okx_api_client)
267280
.manage(Mutex::new(portfolio_client))
268281
.manage(auth_client)
269282
.manage(stream_producer);

apps/api/src/swap/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
pub mod client;
22
pub mod near_intents;
3+
pub mod okx;
34

45
pub use client::SwapClient;
56
pub use near_intents::NearIntentsProxyClient;
7+
pub use okx::OkxApiClient;
68

79
use crate::responders::{ApiError, ApiResponse};
810
use primitives::FiatAssets;

apps/api/src/swap/okx.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use gem_client::ReqwestClient;
2+
use primitives::swap::{ProxyQuote, ProxyQuoteRequest, SwapQuoteData};
3+
use rocket::serde::json::Json;
4+
use std::sync::Arc;
5+
use swapper::{
6+
RpcProvider,
7+
okx::{BASE_URL, OkxClientConfig, OkxProvider},
8+
proxy::ProxyResponse,
9+
};
10+
11+
pub struct OkxApiClient {
12+
provider: OkxProvider<ReqwestClient>,
13+
}
14+
15+
impl OkxApiClient {
16+
pub fn new(config: OkxClientConfig, rpc_provider: Arc<dyn RpcProvider>) -> Self {
17+
let http = ReqwestClient::new(BASE_URL.to_string(), reqwest::Client::new());
18+
Self {
19+
provider: OkxProvider::new(http, config, rpc_provider),
20+
}
21+
}
22+
}
23+
24+
#[rocket::post("/swaps/providers/okx/quote", data = "<body>")]
25+
pub async fn post_okx_quote(body: Json<ProxyQuoteRequest>, client: &rocket::State<OkxApiClient>) -> Json<ProxyResponse<ProxyQuote>> {
26+
Json(client.provider.compute_quote(body.into_inner()).await.into())
27+
}
28+
29+
#[rocket::post("/swaps/providers/okx/quote_data", data = "<body>")]
30+
pub async fn post_okx_quote_data(body: Json<ProxyQuote>, client: &rocket::State<OkxApiClient>) -> Json<ProxyResponse<SwapQuoteData>> {
31+
Json(client.provider.compute_quote_data(body.into_inner()).await.into())
32+
}

crates/settings/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ pub struct Settings {
2727
pub paybis: Paybis,
2828
pub flashnet: UrlKeySettings,
2929

30+
pub swap: Swap,
31+
3032
pub prices: Prices,
3133
pub coingecko: CoinGecko,
3234
pub charter: Charter,
@@ -394,6 +396,18 @@ pub struct Claude {
394396
pub key: KeySecret,
395397
}
396398

399+
#[derive(Debug, Deserialize, Clone)]
400+
pub struct Swap {
401+
pub okx: Okx,
402+
}
403+
404+
#[derive(Debug, Deserialize, Clone)]
405+
pub struct Okx {
406+
pub key: Key,
407+
pub passphrase: String,
408+
pub project: String,
409+
}
410+
397411
#[cfg(feature = "testkit")]
398412
pub mod testkit;
399413

crates/swapper/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ num-integer.workspace = true
4444
num-traits.workspace = true
4545
futures.workspace = true
4646
bs58 = { workspace = true }
47+
base64 = { workspace = true }
48+
hmac = { workspace = true }
49+
sha2 = { workspace = true }
4750
solana-primitives = "0.2.3"
4851
bigdecimal.workspace = true
4952
rand.workspace = true

crates/swapper/src/chainflip/default.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use super::{broker::BrokerClient, client::ChainflipClient, provider::ChainflipProvider};
22
use crate::{
33
alien::{RpcClient, RpcProvider},
4-
config::get_swap_api_url,
4+
config::get_swap_proxy_url,
55
};
66
use gem_jsonrpc::client::JsonRpcClient;
77
use std::sync::Arc;
88

99
impl ChainflipProvider<RpcClient, RpcClient> {
1010
pub fn new(rpc_provider: Arc<dyn RpcProvider>) -> Self {
11-
let api_url = get_swap_api_url("chainflip-swap");
12-
let broker_url = get_swap_api_url("chainflip-broker/rpc");
11+
let api_url = get_swap_proxy_url("chainflip-swap");
12+
let broker_url = get_swap_proxy_url("chainflip-broker/rpc");
1313

1414
let api_client = RpcClient::new(api_url, rpc_provider.clone());
1515
let chainflip_client = ChainflipClient::new(api_client.clone());

crates/swapper/src/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ pub const DEFAULT_SWAP_FEE_BPS: u32 = 50;
99
pub const DEFAULT_CHAINFLIP_FEE_BPS: u32 = 45;
1010
pub const DEFAULT_STABLE_SWAP_REFERRAL_BPS: u32 = 25;
1111

12-
pub const API_BASE_URL: &str = "https://api.gemwallet.com/proxy/swap";
12+
pub const API_BASE_URL: &str = "https://api.gemwallet.com";
1313

14-
pub fn get_swap_api_url(path: &str) -> String {
15-
format!("{API_BASE_URL}/{path}")
14+
pub fn get_swap_proxy_url(path: &str) -> String {
15+
format!("{API_BASE_URL}/proxy/swap/{path}")
1616
}
1717

1818
#[derive(Debug, Clone, PartialEq)]

crates/swapper/src/jupiter/default.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::sync::Arc;
99

1010
impl Jupiter<RpcClient, RpcClient> {
1111
pub fn new(provider: Arc<dyn RpcProvider>) -> Self {
12-
let url = config::get_swap_api_url("jupiter");
12+
let url = config::get_swap_proxy_url("jupiter");
1313
let http_client = JupiterClient::new(RpcClient::new(url, provider.clone()));
1414
let solana_endpoint = provider.get_endpoint(Chain::Solana).expect("Failed to get Solana endpoint for Jupiter provider");
1515
let rpc_client = JsonRpcClient::new(RpcClient::new(solana_endpoint, provider));

0 commit comments

Comments
 (0)