use alloy::hex;
use alloy::signers::local::PrivateKeySigner;
use ed25519_dalek::SigningKey;
use std::sync::Once;
const DEFAULT_BASE_URL: &str = "http://localhost:8080";
static INIT: Once = Once::new();
fn load_env() {
INIT.call_once(|| {
let _ = dotenvy::dotenv();
});
}
pub fn base_url() -> String {
load_env();
std::env::var("API_BASE_URL").unwrap_or_else(|_| DEFAULT_BASE_URL.to_string())
}
pub fn client() -> monaco_sdk::Client {
monaco_sdk::Client::new(&base_url())
}
pub fn authed_client(_session_private_key_hex: &str) -> monaco_sdk::Client {
monaco_sdk::Client::new(&base_url())
}
pub async fn authenticate() -> (String, String, PrivateKeySigner) {
let signer = PrivateKeySigner::random();
authenticate_with_signer(signer).await
}
pub async fn authenticate_funded() -> (String, String, PrivateKeySigner) {
load_env();
let key = std::env::var("PRIVATE_KEY")
.expect("PRIVATE_KEY env var required for order tests — set it in .env at repo root");
let signer: PrivateKeySigner = key.parse().unwrap();
authenticate_with_signer(signer).await
}
pub async fn authenticate_and_faucet() -> (
String,
String,
PrivateKeySigner,
monaco_sdk::types::MintTokensResponse,
) {
let (session_key, address, signer) = authenticate().await;
let authed = authed_client(&session_key);
let mint = authed
.mint_tokens()
.await
.expect("faucet mint_tokens failed")
.into_inner();
(session_key, address, signer, mint)
}
async fn authenticate_with_signer(signer: PrivateKeySigner) -> (String, String, PrivateKeySigner) {
let c = client();
let address = format!("{:?}", signer.address());
let session_key = SigningKey::from_bytes(&rand::random::<[u8; 32]>());
let session_public_key = hex::encode(session_key.verifying_key().to_bytes());
let challenge = c
.create_challenge(&monaco_sdk::types::ChallengeRequest {
address: address.parse().unwrap(),
chain_id: None,
client_id: None,
session_public_key: session_public_key.parse().unwrap(),
})
.await
.unwrap()
.into_inner();
let message = challenge.message.unwrap();
let nonce = challenge.nonce.unwrap();
let signature = alloy::signers::Signer::sign_message(&signer, message.as_bytes())
.await
.unwrap();
let sig_hex = format!("0x{}", hex::encode(signature.as_bytes()));
c.verify_signature(&monaco_sdk::types::VerifyRequest {
address: address.parse().unwrap(),
chain_id: None,
client_id: None,
nonce: nonce.parse().unwrap(),
referral_code: None,
signature: sig_hex.parse().unwrap(),
session_public_key: session_public_key.parse().unwrap(),
})
.await
.unwrap()
.into_inner();
(hex::encode(session_key.to_bytes()), address, signer)
}
pub async fn first_pair_id() -> String {
let pairs = client()
.list_trading_pairs(None, None, Some(true), None, None, None, None)
.await
.unwrap()
.into_inner();
pairs
.trading_pairs
.unwrap()
.into_iter()
.next()
.unwrap()
.id
.unwrap()
.to_string()
}