diff --git a/tig-utils/src/eth.rs b/tig-utils/src/eth.rs index 34963e9..90c5acb 100644 --- a/tig-utils/src/eth.rs +++ b/tig-utils/src/eth.rs @@ -88,21 +88,21 @@ mod web3_feature { pub const GNOSIS_SAFE_ABI: &str = r#"[ { "inputs": [ - { - "name": "_dataHash", - "type": "bytes32" - }, - { - "name": "_signature", - "type": "bytes" - } + { + "name": "_dataHash", + "type": "bytes32" + }, + { + "name": "_signature", + "type": "bytes" + } ], "name": "isValidSignature", "outputs": [ - { - "name": "", - "type": "bytes4" - } + { + "name": "", + "type": "bytes4" + } ], "payable": false, "stateMutability": "view", @@ -142,6 +142,53 @@ mod web3_feature { Err(e) => Err(anyhow!("Failed query isValidSignature: {:?}", e)), } } + + pub const ENS_REVERSE_RECORDS_ADDRESS: &str = "0x3671aE578E63FdF66ad4F3E12CC0c0d71Ac7510C"; + pub const ENS_REVERSE_RECORDS_ABI: &str = r#"[ + { + "inputs": [ + { + "internalType": "address[]", + "name": "addresses", + "type": "address[]" + } + ], + "name": "getNames", + "outputs": [ + { + "internalType": "string[]", + "name": "r", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ]"#; + + pub async fn lookup_ens_name(rpc_url: &str, address: &str) -> Result { + let transport = web3::transports::Http::new(rpc_url)?; + let eth = web3::Web3::new(transport).eth(); + + let reverse_records = Contract::from_json( + eth.clone(), + H160::from_str(ENS_REVERSE_RECORDS_ADDRESS)?, + ENS_REVERSE_RECORDS_ABI.as_bytes(), + )?; + + let addresses = vec![H160::from_str(address.trim_start_matches("0x"))?]; + + let names: Vec = reverse_records + .query("getNames", (addresses,), None, Options::default(), None) + .await?; + + // Return first name or address if empty + Ok(if !names[0].is_empty() { + names[0].clone() + } else { + address.to_string() + }) + } } #[cfg(feature = "web3")] diff --git a/tig-utils/tests/eth.rs b/tig-utils/tests/eth.rs index 4fb3302..42bd1c2 100644 --- a/tig-utils/tests/eth.rs +++ b/tig-utils/tests/eth.rs @@ -89,4 +89,35 @@ mod tests { } ); } + + #[tokio::test] + async fn test_lookup_ens_name() { + assert_eq!( + tig_utils::lookup_ens_name( + "https://eth-mainnet.public.blastapi.io", + "0x225f137127d9067788314bc7fcc1f36746a3c3B5", + ) + .await + .unwrap(), + "luc.eth".to_string() + ); + assert_eq!( + tig_utils::lookup_ens_name( + "https://eth-mainnet.public.blastapi.io", + "0x0532d3971666953bc2db8619b89d546b3938a535", + ) + .await + .unwrap(), + "harrisandtrotter.eth".to_string() + ); + assert_eq!( + tig_utils::lookup_ens_name( + "https://eth-mainnet.public.blastapi.io", + "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", + ) + .await + .unwrap(), + "vitalik.eth".to_string() + ); + } }