Skip to content

Commit 07c2c6a

Browse files
committed
chore(cdp): Corrected openapi, validate b64 secrets
1 parent e528a18 commit 07c2c6a

File tree

4 files changed

+96
-55
lines changed

4 files changed

+96
-55
lines changed

docs/openapi.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7273,7 +7273,8 @@
72737273
"required": [
72747274
"api_key_id",
72757275
"api_key_secret",
7276-
"wallet_secret"
7276+
"wallet_secret",
7277+
"account_address"
72777278
],
72787279
"properties": {
72797280
"api_key_id": {

src/models/signer/mod.rs

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub use request::*;
2828
mod response;
2929
pub use response::*;
3030

31-
use crate::{constants::ID_REGEX, models::SecretString};
31+
use crate::{constants::ID_REGEX, models::SecretString, utils::base64_decode};
3232
use secrets::SecretVec;
3333
use serde::{Deserialize, Serialize, Serializer};
3434
use solana_sdk::pubkey::Pubkey;
@@ -264,6 +264,26 @@ fn validate_secret_string(secret: &SecretString) -> Result<(), validator::Valida
264264

265265
/// Custom validator for CDP signer configuration
266266
fn validate_cdp_config(config: &CdpSignerConfig) -> Result<(), validator::ValidationError> {
267+
// Validate api_key_secret is valid base64
268+
let api_key_valid = config
269+
.api_key_secret
270+
.as_str(|secret_str| base64_decode(secret_str).is_ok());
271+
if !api_key_valid {
272+
let mut error = validator::ValidationError::new("invalid_base64_api_key_secret");
273+
error.message = Some("API Key Secret is not valid base64".into());
274+
return Err(error);
275+
}
276+
277+
// Validate wallet_secret is valid base64
278+
let wallet_secret_valid = config
279+
.wallet_secret
280+
.as_str(|secret_str| base64_decode(secret_str).is_ok());
281+
if !wallet_secret_valid {
282+
let mut error = validator::ValidationError::new("invalid_base64_wallet_secret");
283+
error.message = Some("Wallet Secret is not valid base64".into());
284+
return Err(error);
285+
}
286+
267287
let addr = &config.account_address;
268288

269289
// Check if it's an EVM address (0x-prefixed hex)
@@ -941,8 +961,8 @@ mod tests {
941961
fn test_valid_cdp_signer_with_evm_address() {
942962
let config = CdpSignerConfig {
943963
api_key_id: "test-api-key".to_string(),
944-
api_key_secret: SecretString::new("secret"),
945-
wallet_secret: SecretString::new("wallet-secret"),
964+
api_key_secret: SecretString::new("c2VjcmV0"), // Valid base64: "secret"
965+
wallet_secret: SecretString::new("d2FsbGV0LXNlY3JldA=="), // Valid base64: "wallet-secret"
946966
account_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44f".to_string(),
947967
};
948968
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
@@ -954,8 +974,8 @@ mod tests {
954974
fn test_valid_cdp_signer_with_solana_address() {
955975
let config = CdpSignerConfig {
956976
api_key_id: "test-api-key".to_string(),
957-
api_key_secret: SecretString::new("secret"),
958-
wallet_secret: SecretString::new("wallet-secret"),
977+
api_key_secret: SecretString::new("c2VjcmV0"), // Valid base64: "secret"
978+
wallet_secret: SecretString::new("d2FsbGV0LXNlY3JldA=="), // Valid base64: "wallet-secret"
959979
account_address: "6s7RsvzcdXFJi1tXeDoGfSKZFzN3juVt9fTar6WEhEm2".to_string(),
960980
};
961981
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
@@ -967,8 +987,8 @@ mod tests {
967987
fn test_invalid_cdp_signer_empty_address() {
968988
let config = CdpSignerConfig {
969989
api_key_id: "test-api-key".to_string(),
970-
api_key_secret: SecretString::new("secret"),
971-
wallet_secret: SecretString::new("wallet-secret"),
990+
api_key_secret: SecretString::new("c2VjcmV0"), // Valid base64: "secret"
991+
wallet_secret: SecretString::new("d2FsbGV0LXNlY3JldA=="), // Valid base64: "wallet-secret"
972992
account_address: "".to_string(),
973993
};
974994
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
@@ -985,8 +1005,8 @@ mod tests {
9851005
fn test_invalid_cdp_signer_bad_evm_address() {
9861006
let config = CdpSignerConfig {
9871007
api_key_id: "test-api-key".to_string(),
988-
api_key_secret: SecretString::new("secret"),
989-
wallet_secret: SecretString::new("wallet-secret"),
1008+
api_key_secret: SecretString::new("c2VjcmV0"), // Valid base64: "secret"
1009+
wallet_secret: SecretString::new("d2FsbGV0LXNlY3JldA=="), // Valid base64: "wallet-secret"
9901010
account_address: "0xinvalid-address".to_string(),
9911011
};
9921012
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
@@ -1003,8 +1023,8 @@ mod tests {
10031023
fn test_invalid_cdp_signer_bad_solana_address() {
10041024
let config = CdpSignerConfig {
10051025
api_key_id: "test-api-key".to_string(),
1006-
api_key_secret: SecretString::new("secret"),
1007-
wallet_secret: SecretString::new("wallet-secret"),
1026+
api_key_secret: SecretString::new("c2VjcmV0"), // Valid base64: "secret"
1027+
wallet_secret: SecretString::new("d2FsbGV0LXNlY3JldA=="), // Valid base64: "wallet-secret"
10081028
account_address: "invalid".to_string(),
10091029
};
10101030
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
@@ -1021,8 +1041,8 @@ mod tests {
10211041
fn test_invalid_cdp_signer_evm_address_wrong_format() {
10221042
let config = CdpSignerConfig {
10231043
api_key_id: "test-api-key".to_string(),
1024-
api_key_secret: SecretString::new("secret"),
1025-
wallet_secret: SecretString::new("wallet-secret"),
1044+
api_key_secret: SecretString::new("c2VjcmV0"), // Valid base64: "secret"
1045+
wallet_secret: SecretString::new("d2FsbGV0LXNlY3JldA=="), // Valid base64: "wallet-secret"
10261046
account_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44".to_string(), // Too short
10271047
};
10281048
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
@@ -1039,8 +1059,8 @@ mod tests {
10391059
fn test_invalid_cdp_signer_solana_address_wrong_charset() {
10401060
let config = CdpSignerConfig {
10411061
api_key_id: "test-api-key".to_string(),
1042-
api_key_secret: SecretString::new("secret"),
1043-
wallet_secret: SecretString::new("wallet-secret"),
1062+
api_key_secret: SecretString::new("c2VjcmV0"), // Valid base64: "secret"
1063+
wallet_secret: SecretString::new("d2FsbGV0LXNlY3JldA=="), // Valid base64: "wallet-secret"
10441064
account_address: "6s7RsvzcdXFJi1tXeDoGfSKZFzN3juVt9fTar6WEhEm0".to_string(), // Contains '0' which is invalid in Base58
10451065
};
10461066
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
@@ -1052,4 +1072,54 @@ mod tests {
10521072
panic!("Expected InvalidConfig error for wrong Solana address charset");
10531073
}
10541074
}
1075+
1076+
#[test]
1077+
fn test_invalid_cdp_signer_invalid_base64_api_key_secret() {
1078+
let config = CdpSignerConfig {
1079+
api_key_id: "test-api-key".to_string(),
1080+
api_key_secret: SecretString::new("invalid-base64!@#"), // Invalid base64
1081+
wallet_secret: SecretString::new("dGVzdC13YWxsZXQtc2VjcmV0"), // Valid base64: "test-wallet-secret"
1082+
account_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44f".to_string(),
1083+
};
1084+
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
1085+
let result = signer.validate();
1086+
assert!(result.is_err());
1087+
if let Err(SignerValidationError::InvalidConfig(msg)) = result {
1088+
assert!(msg.contains("API Key Secret is not valid base64"));
1089+
} else {
1090+
panic!("Expected InvalidConfig error for invalid base64 API key secret");
1091+
}
1092+
}
1093+
1094+
#[test]
1095+
fn test_invalid_cdp_signer_invalid_base64_wallet_secret() {
1096+
let config = CdpSignerConfig {
1097+
api_key_id: "test-api-key".to_string(),
1098+
api_key_secret: SecretString::new("dGVzdC1hcGkta2V5LXNlY3JldA=="), // Valid base64: "test-api-key-secret"
1099+
wallet_secret: SecretString::new("invalid-base64!@#"), // Invalid base64
1100+
account_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44f".to_string(),
1101+
};
1102+
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
1103+
let result = signer.validate();
1104+
assert!(result.is_err());
1105+
if let Err(SignerValidationError::InvalidConfig(msg)) = result {
1106+
assert!(msg.contains("Wallet Secret is not valid base64"));
1107+
} else {
1108+
panic!("Expected InvalidConfig error for invalid base64 wallet secret");
1109+
}
1110+
}
1111+
1112+
#[test]
1113+
fn test_valid_cdp_signer_with_valid_base64_secrets() {
1114+
let config = CdpSignerConfig {
1115+
api_key_id: "test-api-key".to_string(),
1116+
api_key_secret: SecretString::new("dGVzdC1hcGkta2V5LXNlY3JldA=="), // Valid base64: "test-api-key-secret"
1117+
wallet_secret: SecretString::new("dGVzdC13YWxsZXQtc2VjcmV0"), // Valid base64: "test-wallet-secret"
1118+
account_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44f".to_string(),
1119+
};
1120+
let signer = Signer::new("cdp-signer".to_string(), SignerConfig::Cdp(config));
1121+
let result = signer.validate();
1122+
assert!(result.is_ok());
1123+
assert_eq!(signer.signer_type(), SignerType::Cdp);
1124+
}
10551125
}

src/models/signer/request.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -888,8 +888,8 @@ mod tests {
888888
"type": "cdp",
889889
"config": {
890890
"api_key_id": "test-api-key-id",
891-
"api_key_secret": "test-api-key-secret",
892-
"wallet_secret": "test-wallet-secret",
891+
"api_key_secret": "dGVzdC1hcGkta2V5LXNlY3JldA==",
892+
"wallet_secret": "dGVzdC13YWxsZXQtc2VjcmV0",
893893
"account_address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44f"
894894
}
895895
}"#;
@@ -908,8 +908,8 @@ mod tests {
908908
match request.config {
909909
SignerConfigRequest::Cdp(cdp_config) => {
910910
assert_eq!(cdp_config.api_key_id, "test-api-key-id");
911-
assert_eq!(cdp_config.api_key_secret, "test-api-key-secret");
912-
assert_eq!(cdp_config.wallet_secret, "test-wallet-secret");
911+
assert_eq!(cdp_config.api_key_secret, "dGVzdC1hcGkta2V5LXNlY3JldA==");
912+
assert_eq!(cdp_config.wallet_secret, "dGVzdC13YWxsZXQtc2VjcmV0");
913913
assert_eq!(
914914
cdp_config.account_address,
915915
"0x742d35Cc6634C0532925a3b844Bc454e4438f44f"
@@ -926,8 +926,8 @@ mod tests {
926926
signer_type: SignerTypeRequest::Cdp,
927927
config: SignerConfigRequest::Cdp(CdpSignerRequestConfig {
928928
api_key_id: "test-api-key-id".to_string(),
929-
api_key_secret: "test-api-key-secret".to_string(),
930-
wallet_secret: "test-wallet-secret".to_string(),
929+
api_key_secret: "dGVzdC1hcGkta2V5LXNlY3JldA==".to_string(), // Valid base64: "test-api-key-secret"
930+
wallet_secret: "dGVzdC13YWxsZXQtc2VjcmV0".to_string(), // Valid base64: "test-wallet-secret"
931931
account_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44f".to_string(),
932932
}),
933933
};
@@ -956,9 +956,9 @@ mod tests {
956956
id: Some("test-signer".to_string()),
957957
signer_type: SignerTypeRequest::Cdp,
958958
config: SignerConfigRequest::Cdp(CdpSignerRequestConfig {
959-
api_key_id: "".to_string(), // Empty
960-
api_key_secret: "test-api-key-secret".to_string(),
961-
wallet_secret: "test-wallet-secret".to_string(),
959+
api_key_id: "".to_string(), // Empty
960+
api_key_secret: "dGVzdC1hcGkta2V5LXNlY3JldA==".to_string(), // Valid base64: "test-api-key-secret"
961+
wallet_secret: "dGVzdC13YWxsZXQtc2VjcmV0".to_string(), // Valid base64: "test-wallet-secret"
962962
account_address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44f".to_string(),
963963
}),
964964
};

src/services/cdp/mod.rs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -350,36 +350,6 @@ mod tests {
350350
assert!(!service.is_evm_address());
351351
}
352352

353-
#[tokio::test]
354-
async fn test_evm_address_with_solana_config() {
355-
let config = create_test_config_solana();
356-
let service = CdpService::new(config).unwrap();
357-
let result = service.account_address().await;
358-
359-
assert!(result.is_err());
360-
match result {
361-
Err(CdpError::ConfigError(msg)) => {
362-
assert!(msg.contains("Account address is not an EVM address"));
363-
}
364-
_ => panic!("Expected ConfigError for Solana address used with EVM"),
365-
}
366-
}
367-
368-
#[tokio::test]
369-
async fn test_solana_address_with_evm_config() {
370-
let config = create_test_config_evm();
371-
let service = CdpService::new(config).unwrap();
372-
let result = service.account_address().await;
373-
374-
assert!(result.is_err());
375-
match result {
376-
Err(CdpError::ConfigError(msg)) => {
377-
assert!(msg.contains("Account address is not a Solana address"));
378-
}
379-
_ => panic!("Expected ConfigError for EVM address used with Solana"),
380-
}
381-
}
382-
383353
#[tokio::test]
384354
async fn test_address_evm_success() {
385355
let config = create_test_config_evm();

0 commit comments

Comments
 (0)