Skip to content

Commit

Permalink
feat: d3 connect support
Browse files Browse the repository at this point in the history
  • Loading branch information
sevenzing committed Oct 25, 2024
1 parent 5cbb3ac commit 349e5ba
Show file tree
Hide file tree
Showing 10 changed files with 530 additions and 390 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ getrandom = { version = "0.2", features = ["js"] }
tokio = { version = "1.34.0", features = ["macros", "rt-multi-thread"] }
alloy = { version = "0.1", features = ["full"] }
anyhow = "1.0.75"
pretty_assertions = "1.4.1"
rstest = "0.23.0"
16 changes: 13 additions & 3 deletions examples/offchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,30 @@ async fn main() -> Result<()> {
let rpc = alloy_ccip_read::consts::DEFAULT_ETHEREUM_RPC_URL;
let provider = ProviderBuilder::new().on_http(rpc.parse().unwrap());
let reader = CCIPReader::new(provider.boxed());
let registry_address = None;
for ens_name in [
"1.offchainexample.eth",
"levvv.xyz",
"itslev.cb.id",
"llev.me",
] {
println!("\nresolving name: {}", ens_name);
let resolver_address = reader.get_resolver(ens_name).await.unwrap();

let resolver_address =
alloy_ccip_read::ens::get_resolver_wildcarded(&reader, registry_address, ens_name)
.await
.unwrap();
println!("resolver_address: {:?}", resolver_address);

let supports_wildcard = reader.supports_wildcard(resolver_address).await.unwrap();
let supports_wildcard = alloy_ccip_read::ens::supports_wildcard(&reader, resolver_address)
.await
.unwrap();
println!("supports_wildcard: {:?}", supports_wildcard);

let resolved_address = reader.resolve_name(ens_name).await.unwrap();
let resolved_address =
alloy_ccip_read::ens::resolve_name(&reader, registry_address, ens_name)
.await
.unwrap();
println!("resolved_address: {:?}", resolved_address);
}

Expand Down
9 changes: 9 additions & 0 deletions src/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,12 @@ sol! {
) external view returns (bool);
}
}

sol! {
#[allow(missing_docs)]
#[sol(rpc)]
interface D3Connect {
function resolve(string name, string network) view returns (address);
function reverseResolve(address addr, string network) view returns (string);
}
}
2 changes: 1 addition & 1 deletion src/domain_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/// however this crate provider a way to generate domain ids using other algorithms.
use alloy::primitives::{keccak256, B256};

pub trait DomainIdProvider: Clone {
pub trait DomainIdProvider: Clone + Send + Sync {
fn generate(&self, name: &str) -> B256;
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
pub use ccip::handle_ccip;
pub use domain_id::{namehash, DomainIdProvider, NamehashIdProvider};
pub use errors::*;
pub use protocols::*;
pub use reader::CCIPReader;
pub use types::*;

Expand All @@ -13,6 +14,7 @@ pub mod consts;
mod contracts;
mod domain_id;
mod errors;
mod protocols;
mod reader;
mod types;
pub mod utils;
106 changes: 106 additions & 0 deletions src/protocols/d3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use super::ens;
use crate::{
contracts, CCIPReader, CCIPReaderError, CCIPType, DomainIdProvider, ResolveResult,
ReverseResolveResult,
};
use alloy::{primitives::Address, providers::Provider};

pub async fn resolve_d3_name<P: Provider, D: DomainIdProvider>(
reader: &CCIPReader<P, D>,
resolver_address: Address,
name: &str,
network: &str,
) -> Result<ResolveResult, CCIPReaderError> {
let call = contracts::D3Connect::resolveCall {
name: name.to_string(),
network: network.to_string(),
};
let mut ccip_read_used = false;
let (result, requests) =
ens::query_resolver_non_wildcarded(reader, resolver_address, call).await?;
ccip_read_used |= !requests.is_empty();
let addr = CCIPType {
value: result._0,
requests,
};
Ok(ResolveResult {
addr,
ccip_read_used,
wildcard_used: false,
})
}

pub async fn reverse_resolve_d3_name<P: Provider, D: DomainIdProvider>(
reader: &CCIPReader<P, D>,
address: Address,
resolver_address: Address,
) -> Result<ReverseResolveResult, CCIPReaderError> {
let call = contracts::D3Connect::reverseResolveCall {
addr: address,
network: "".to_string(),
};
let mut ccip_read_used = false;
let (result, requests) =
ens::query_resolver_non_wildcarded(reader, resolver_address, call).await?;
ccip_read_used |= !requests.is_empty();
let name = CCIPType {
value: result._0,
requests,
};
Ok(ReverseResolveResult {
name,
ccip_read_used,
})
}

#[cfg(test)]
mod tests {
use crate::{CCIPReader, NamehashIdProvider};
use alloy::{
providers::{ProviderBuilder, RootProvider},
transports::BoxTransport,
};
use rstest::{fixture, rstest};

use super::*;

#[fixture]
#[once]
fn reader() -> CCIPReader<RootProvider<BoxTransport>, NamehashIdProvider> {
let shibarium = ProviderBuilder::default()
.on_http("https://puppynet.shibrpc.com".parse().unwrap())
.boxed();
CCIPReader::new(shibarium)
}

#[rstest]
#[tokio::test]
#[case(
"0x91c2d22ca1028B2E55e3097096494Eb34b7fc81c",
"d3connect.shib",
"",
"0x7309E26de18FD96A34aBBE6063a0b08d78c947C5"
)]
async fn test_shibarium_d3connect(
#[case] resolver_address: Address,
#[case] name: &str,
#[case] network: &str,
#[case] address: Address,
reader: &CCIPReader<RootProvider<BoxTransport>, NamehashIdProvider>,
) {
let result = resolve_d3_name(reader, resolver_address, name, network)
.await
.unwrap();
assert_eq!(
result.addr.value,
"0x7309E26de18FD96A34aBBE6063a0b08d78c947C5"
.parse::<Address>()
.unwrap()
);

let result = reverse_resolve_d3_name(reader, address, resolver_address)
.await
.unwrap();
assert_eq!(result.name.value, "d3connect.shib");
}
}
Loading

0 comments on commit 349e5ba

Please sign in to comment.