token_address_extractor/
lib.rs

1mod ethereum_based;
2mod solana;
3mod tron;
4
5pub use ethereum_based::extract_ethereum_based_address;
6pub use solana::extract_solana_address;
7pub use tron::extract_tron_address;
8
9/// A collection of functions that extract blockchain addresses.
10///
11/// Currently supports Ethereum-based, Solana, and Tron addresses.
12/// Note: These functions only extract the "address" portion and do not fully extract
13/// ERC20/SPL token contract addresses.
14///
15/// TODO: Improve extraction to handle ERC20/SPL token address and not just any addrss..
16pub static FUNCTIONS: &[fn(&str) -> Option<String>] = &[
17    extract_ethereum_based_address,
18    extract_solana_address,
19    extract_tron_address,
20];
21
22/// Extracts the first token address (Ethereum-based, Solana, or Tron) found in a given text.
23///
24/// This function iterates through different blockchain address extraction functions
25/// and returns the first valid match found.
26///
27/// # Arguments
28///
29/// * `text` - A string slice containing the input text to search.
30///
31/// # Returns
32///
33/// * `Some(String)` containing the first valid blockchain address found.
34/// * `None` if no valid address is found.
35///
36/// # Examples
37///
38/// ```
39/// let text = "Some text with an Ethereum address: 0xAb5801a7D398351b8bE11C439e05C5b3259aec9B";
40/// let result = extract_token_address_from_message_text(text);
41/// assert_eq!(result, Some("0xAb5801a7D398351b8bE11C439e05C5b3259aec9B".to_string()));
42/// ```
43pub fn extract_token_address_from_message_text(text: &str) -> Option<String> {
44    let mut final_token_address: Option<String> = None;
45    let len = FUNCTIONS.len();
46
47    for i in 0..len {
48        let extractor_function = FUNCTIONS.get(i);
49        let extracted_address_option = extractor_function.unwrap()(text);
50        final_token_address = extracted_address_option;
51
52        if final_token_address.is_some() {
53            break;
54        }
55    }
56
57    final_token_address
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_extract_ethereum_address() {
66        let ethereum_text =
67            "Check this Ethereum address 0x5f8F8E1dbB5bF65E3aF5F5dF8F8F8F8F8F8F8F8F test test test";
68        let expected_address = Some("0x5f8F8E1dbB5bF65E3aF5F5dF8F8F8F8F8F8F8F8F".to_string());
69
70        let result = extract_token_address_from_message_text(ethereum_text);
71
72        assert_eq!(result, expected_address);
73    }
74
75    #[test]
76    fn test_extract_solana_address() {
77        let solana_text =
78            "Solana address: 3KZs8bDozYngwMY52VrggD2nzAeNGiDTzKpHWZ4gN1Fq test test test";
79        let expected_address = Some("3KZs8bDozYngwMY52VrggD2nzAeNGiDTzKpHWZ4gN1Fq".to_string());
80
81        let result = extract_token_address_from_message_text(solana_text);
82
83        assert_eq!(result, expected_address);
84    }
85
86    #[test]
87    fn test_extract_tron_address() {
88        let tron_text = "Tron address: TQ7r4rYjTnso3j7KwhZZfnZZG2eDZ6fvB7 test test test";
89        let expected_address = Some("TQ7r4rYjTnso3j7KwhZZfnZZG2eDZ6fvB7".to_string());
90
91        let result = extract_token_address_from_message_text(tron_text);
92
93        assert_eq!(result, expected_address);
94    }
95
96    #[test]
97    fn test_extract_token_address_from_message_text_no_address() {
98        let text = "No valid address here!";
99
100        let result = extract_token_address_from_message_text(text);
101
102        assert_eq!(result, None);
103    }
104}