use crate::models::prelude::*;
pub mod find_payment_paths_request;
pub mod list_strict_receive_payment_paths_request;
pub mod list_strict_send_payment_paths_request;
pub mod response;
pub(crate) static PATHS_PATH: &str = "paths"; pub(crate) static PATHS_STRICT_RECEIVE_PATH: &str = "strict-receive";
pub(crate) static PATHS_STRICT_SEND_PATH: &str = "strict-send";
#[derive(Default, Clone, Debug)]
pub struct NoDestinationAsset;
#[derive(Default, Clone, Debug)]
pub struct DestinationAsset(AssetType);
#[derive(Default, Clone, Debug)]
pub struct NoDestinationAmount;
#[derive(Default, Clone, Debug)]
pub struct DestinationAmount(String);
#[derive(Default, Clone, Debug)]
pub struct NoSourceAccount;
#[derive(Default, Clone, Debug)]
pub struct SourceAccount(String);
#[derive(Default, Clone, Debug)]
pub enum IssuedOrNative {
#[default]
Native,
Issued(AssetData),
}
pub mod prelude {
pub use super::find_payment_paths_request::*;
pub use super::list_strict_receive_payment_paths_request::*;
pub use super::list_strict_send_payment_paths_request::*;
pub use super::response::*;
pub use super::{
DestinationAmount, DestinationAsset, NoDestinationAmount, NoDestinationAsset,
NoSourceAccount, SourceAccount,
};
}
#[cfg(test)]
mod tests {
use super::prelude::*;
use super::{AssetType, IssuedOrNative};
use crate::models::prelude::*;
use crate::{horizon_client::HorizonClient, models::*};
const SOURCE_ASSET_TYPE: &str = "native";
const SOURCE_AMOUNT: &str = "100.0000000";
const DESTINATION_ASSET_TYPE: &str = "native";
const DESTINATION_AMOUNT: &str = "100.0000000";
#[tokio::test]
async fn test_find_payment_paths_request() {
use crate::paths::PATHS_PATH;
let request = FindPaymentsPathRequest::new()
.set_destination_asset(AssetType::Alphanumeric4(AssetData {
asset_code: "USDC".to_string(),
asset_issuer: "GBJJ5OCBXNZWHSJJ4YQ6ECK24MBJSZMLEMINHKGGEWUA5RU2EDMPN6MS"
.to_string(),
}))
.unwrap()
.set_destination_amount("42".to_string())
.unwrap()
.set_source_account(
"GBAC4BTW6UIJOCCUOZ7QATQPVWX6UQVH3ESQ6NEHBMCXJ3MVP4GMT77H".to_string(),
)
.unwrap()
.set_destination_account(
"GBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4".to_string(),
)
.unwrap();
let expected_parameters =
"?destination_asset_type=credit_alphanum4&destination_asset_code=USDC&destination_asset_issuer=GBJJ5OCBXNZWHSJJ4YQ6ECK24MBJSZMLEMINHKGGEWUA5RU2EDMPN6MS&destination_amount=42&destination_account=GBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4&source_account=GBAC4BTW6UIJOCCUOZ7QATQPVWX6UQVH3ESQ6NEHBMCXJ3MVP4GMT77H";
assert_eq!(expected_parameters, request.get_query_parameters());
let url = "base_url";
assert_eq!(
format!("{}/{}{}", url, PATHS_PATH, request.get_query_parameters()),
request.build_url(url)
);
let horizon_client = HorizonClient::new("https://horizon-testnet.stellar.org").unwrap();
let response = horizon_client.get_find_payment_paths(&request).await;
assert!(response.clone().is_ok());
let request = FindPaymentsPathRequest::new()
.set_destination_asset(AssetType::Native)
.unwrap()
.set_destination_amount("100".to_string())
.unwrap()
.set_source_account(
"GCDE6MVFIOYF7YZCSVA6V7MDCFTNWMIOF5PQU3DWPH27AHNX4ERY6AKS".to_string(),
)
.unwrap();
let expected_parameters: &str =
"?destination_asset_type=native&destination_amount=100&source_account=GCDE6MVFIOYF7YZCSVA6V7MDCFTNWMIOF5PQU3DWPH27AHNX4ERY6AKS";
assert_eq!(request.get_query_parameters(), expected_parameters);
let url = "base_url";
assert_eq!(
format!("{}/{}{}", url, PATHS_PATH, request.get_query_parameters()),
request.build_url(url)
);
let response = horizon_client.get_find_payment_paths(&request).await;
assert!(response.clone().is_ok());
let binding = response.unwrap();
let response = &binding.embedded().records()[0];
assert_eq!(response.source_asset_type(), SOURCE_ASSET_TYPE);
assert_eq!(response.source_amount(), SOURCE_AMOUNT);
assert_eq!(response.destination_asset_type(), DESTINATION_ASSET_TYPE);
assert_eq!(response.destination_amount(), DESTINATION_AMOUNT);
let request = FindPaymentsPathRequest::new()
.set_destination_asset(AssetType::Native)
.unwrap()
.set_destination_amount("42".to_string())
.unwrap()
.set_source_account("invalid_account_id".to_string());
assert_eq!(
request.err().unwrap(),
"Public key must be 56 characters long"
);
}
#[tokio::test]
async fn test_list_strict_receive_payment_paths_request() {
use crate::paths::{PATHS_PATH, PATHS_STRICT_RECEIVE_PATH};
let request = ListStrictReceivePaymentPathsRequest::new()
.set_destination_asset(AssetType::Alphanumeric4(AssetData {
asset_code: "USDC".to_string(),
asset_issuer: "GBJJ5OCBXNZWHSJJ4YQ6ECK24MBJSZMLEMINHKGGEWUA5RU2EDMPN6MS"
.to_string(),
}))
.unwrap()
.set_destination_amount("42".to_string())
.unwrap()
.set_source(Source::SourceAssets(vec![
IssuedOrNative::Native,
IssuedOrNative::Native,
IssuedOrNative::Issued(AssetData {
asset_code: "USDC".to_string(),
asset_issuer: "GBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4"
.to_string(),
}),
]))
.unwrap();
let expected_parameters: &str =
"?destination_asset_type=credit_alphanum4&destination_asset_issuer=GBJJ5OCBXNZWHSJJ4YQ6ECK24MBJSZMLEMINHKGGEWUA5RU2EDMPN6MS&destination_asset_code=USDC&destination_amount=42&source_assets=native%2Cnative%2CUSDC%3AGBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4";
assert_eq!(request.get_query_parameters(), expected_parameters);
let url = "base_url";
assert_eq!(
format!(
"{}/{}/{}{}",
url,
PATHS_PATH,
PATHS_STRICT_RECEIVE_PATH,
request.get_query_parameters()
),
request.build_url(url)
);
let horizon_client = HorizonClient::new("https://horizon-testnet.stellar.org").unwrap();
let response = horizon_client
.get_list_strict_receive_payment_paths(&request)
.await;
assert!(response.clone().is_ok());
let request = ListStrictReceivePaymentPathsRequest::new()
.set_destination_asset(AssetType::Native)
.unwrap()
.set_destination_amount("100".to_string())
.unwrap()
.set_source(Source::SourceAccount(
"GCDE6MVFIOYF7YZCSVA6V7MDCFTNWMIOF5PQU3DWPH27AHNX4ERY6AKS".to_string(),
))
.unwrap();
let expected_parameters: &str =
"?destination_asset_type=native&destination_amount=100&source_account=GCDE6MVFIOYF7YZCSVA6V7MDCFTNWMIOF5PQU3DWPH27AHNX4ERY6AKS";
assert_eq!(request.get_query_parameters(), expected_parameters);
let url = "base_url";
assert_eq!(
format!(
"{}/{}/{}{}",
url,
PATHS_PATH,
PATHS_STRICT_RECEIVE_PATH,
request.get_query_parameters()
),
request.build_url(url)
);
let response = horizon_client
.get_list_strict_receive_payment_paths(&request)
.await;
assert!(response.clone().is_ok());
let binding = response.unwrap();
let response = &binding.embedded().records()[0];
assert_eq!(response.source_asset_type(), SOURCE_ASSET_TYPE);
assert_eq!(response.source_amount(), SOURCE_AMOUNT);
assert_eq!(response.destination_asset_type(), DESTINATION_ASSET_TYPE);
assert_eq!(response.destination_amount(), DESTINATION_AMOUNT);
let request = ListStrictReceivePaymentPathsRequest::new()
.set_destination_asset(AssetType::Native)
.unwrap()
.set_destination_amount("42".to_string())
.unwrap()
.set_source(Source::SourceAssets(Vec::new()));
assert_eq!(request.err().unwrap(), "SourceAssets cannot be empty");
let request = ListStrictReceivePaymentPathsRequest::new()
.set_destination_asset(AssetType::Native)
.unwrap()
.set_destination_amount("42".to_string())
.unwrap()
.set_source(Source::SourceAccount("invalid_account_id".to_string()));
assert_eq!(
request.err().unwrap(),
"Public key must be 56 characters long"
);
let request = ListStrictReceivePaymentPathsRequest::new()
.set_destination_asset(AssetType::Native)
.unwrap()
.set_destination_amount("42".to_string())
.unwrap()
.set_source(Source::SourceAssets(vec![IssuedOrNative::Native]))
.unwrap()
.set_destination_account("invalid_account_id");
assert_eq!(
request.err().unwrap(),
"Public key must be 56 characters long"
);
}
#[tokio::test]
async fn test_list_strict_send_payment_paths_request() {
use crate::paths::{PATHS_PATH, PATHS_STRICT_SEND_PATH};
let request = ListStrictSendPaymentPathsRequest::new()
.set_source_asset(AssetType::Alphanumeric4(AssetData {
asset_code: "USDC".to_string(),
asset_issuer: "GBJJ5OCBXNZWHSJJ4YQ6ECK24MBJSZMLEMINHKGGEWUA5RU2EDMPN6MS"
.to_string(),
}))
.unwrap()
.set_source_amount("42".to_string())
.unwrap()
.set_destination(Destination::DestinationAssets(vec![
IssuedOrNative::Native,
IssuedOrNative::Native,
IssuedOrNative::Issued(AssetData {
asset_code: "USDC".to_string(),
asset_issuer: "GBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4"
.to_string(),
}),
]))
.unwrap();
let expected_parameters: &str =
"?source_amount=42&destination_assets=native%2Cnative%2CUSDC%3AGBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4&source_asset_type=credit_alphanum4&source_asset_issuer=GBJJ5OCBXNZWHSJJ4YQ6ECK24MBJSZMLEMINHKGGEWUA5RU2EDMPN6MS&source_asset_code=USDC";
assert_eq!(request.get_query_parameters(), expected_parameters);
let url = "base_url";
assert_eq!(
format!(
"{}/{}/{}{}",
url,
PATHS_PATH,
PATHS_STRICT_SEND_PATH,
request.get_query_parameters()
),
request.build_url(url)
);
let horizon_client = HorizonClient::new("https://horizon-testnet.stellar.org").unwrap();
let response = horizon_client
.get_list_strict_send_payment_paths(&request)
.await;
assert!(response.clone().is_ok());
let request = ListStrictSendPaymentPathsRequest::new()
.set_source_asset(AssetType::Native)
.unwrap()
.set_source_amount("100".to_string())
.unwrap()
.set_destination(Destination::DestinationAccount(
"GBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4".to_string(),
))
.unwrap();
let expected_parameters: &str =
"?source_amount=100&destination_account=GBAKINTNEGR7PO6Z6XW2S5ITT5VARNW6DZ5K4OYSLFNEA2CSMUM2UEF4&source_asset_type=native";
assert_eq!(request.get_query_parameters(), expected_parameters);
let url = "base_url";
assert_eq!(
format!(
"{}/{}/{}{}",
url,
PATHS_PATH,
PATHS_STRICT_SEND_PATH,
request.get_query_parameters()
),
request.build_url(url)
);
let response = horizon_client
.get_list_strict_send_payment_paths(&request)
.await;
assert!(response.clone().is_ok());
let binding = response.unwrap();
let response = &binding.embedded().records()[0];
assert_eq!(response.source_asset_type(), SOURCE_ASSET_TYPE);
assert_eq!(response.source_amount(), SOURCE_AMOUNT);
assert_eq!(response.destination_asset_type(), DESTINATION_ASSET_TYPE);
assert_eq!(response.destination_amount(), DESTINATION_AMOUNT);
let request = ListStrictSendPaymentPathsRequest::new()
.set_source_asset(AssetType::Native)
.unwrap()
.set_source_amount("42".to_string())
.unwrap()
.set_destination(Destination::DestinationAssets(Vec::new()));
assert_eq!(request.err().unwrap(), "DestinationAssets cannot be empty");
let request = ListStrictSendPaymentPathsRequest::new()
.set_source_asset(AssetType::Native)
.unwrap()
.set_source_amount("42".to_string())
.unwrap()
.set_destination(Destination::DestinationAccount(
"invalid_account_id".to_string(),
));
assert_eq!(
request.err().unwrap(),
"Public key must be 56 characters long"
);
let request = ListStrictSendPaymentPathsRequest::new()
.set_source_asset(AssetType::Native)
.unwrap()
.set_source_amount("42".to_string())
.unwrap()
.set_destination(Destination::DestinationAccount(
"invalid_account_id".to_string(),
));
assert_eq!(
request.err().unwrap(),
"Public key must be 56 characters long"
);
}
}