Skip to content

Commit

Permalink
Misc cleanup (#29)
Browse files Browse the repository at this point in the history
* Update .env.example

* Cleanup

* Misc improvements

* Universal resolver call paralelization (WIP)

* Misc updates

* Things

* Remove unused code

* Fix shared Cargo.toml

* Update Cargo.lock

* Rebase master & fix conflicts
  • Loading branch information
Antony1060 authored Dec 7, 2023
1 parent b293ccb commit b68f03a
Show file tree
Hide file tree
Showing 25 changed files with 154 additions and 116 deletions.
1 change: 1 addition & 0 deletions server/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
REDIS_URL=redis://localhost:6379
RPC_URL=https://rpc.ankr.com/eth
OPENSEA_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Optionally you can specify a comma-seperated list PROFILE_RECORDS, however if not provided there are sensible defaults
# PROFILE_RECORDS=com.discord,com.twitter
12 changes: 6 additions & 6 deletions server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions server/src/routes/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ use enstate_shared::models::profile::Profile;
use crate::cache;
use crate::routes::{http_simple_status_error, profile_http_error_mapper, FreshQuery, RouteError};

// TODO: figure out UNPROCESSABLE_ENTITY
// Reverse record not owned by this address.
#[utoipa::path(
get,
path = "/a/{address}",
responses(
(status = 200, description = "Successfully found address", body = ENSProfile),
(status = 200, description = "Successfully found address.", body = ENSProfile),
(status = BAD_REQUEST, description = "Invalid address.", body = ErrorResponse),
(status = NOT_FOUND, description = "No name was associated with this address.", body = ErrorResponse),
(status = UNPROCESSABLE_ENTITY, description = "Reverse record not owned by this address.", body = ErrorResponse),
),
params(
("address" = String, Path, description = "Address to lookup name data for"),
Expand All @@ -44,7 +43,7 @@ pub async fn get(

let profile = Profile::from_address(
address,
query.fresh.unwrap_or(false),
query.fresh,
cache,
rpc,
opensea_api_key,
Expand Down
8 changes: 4 additions & 4 deletions server/src/routes/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::routes::{
// TODO: figure out body
// (status = 200, description = "Successfully found name or address.", body = ENSProfile),
// (status = NOT_FOUND, description = "No name or address could be found."),
// (status = UNPROCESSABLE_ENTITY, description = "Reverse record not owned by this address.", body = ErrorResponse),
// ),
// params(
// ("name_or_address" = String, Path, description = "Name or address to lookup the header for."),
Expand All @@ -32,10 +33,9 @@ pub async fn get(
.ok_or_else(|| http_simple_status_error(StatusCode::INTERNAL_SERVER_ERROR))?
.clone();

let profile =
universal_profile_resolve(&name_or_address, query.fresh.unwrap_or(false), rpc, &state)
.await
.map_err(profile_http_error_mapper)?;
let profile = universal_profile_resolve(&name_or_address, query.fresh, rpc, &state)
.await
.map_err(profile_http_error_mapper)?;

let Some(header) = profile.header else {
return Err(http_simple_status_error(StatusCode::NOT_FOUND));
Expand Down
8 changes: 4 additions & 4 deletions server/src/routes/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::routes::{
// TODO: figure out body
// (status = 200, description = "Successfully found name or address.", body = ENSProfile),
// (status = NOT_FOUND, description = "No name or address could be found."),
// (status = UNPROCESSABLE_ENTITY, description = "Reverse record not owned by this address.", body = ErrorResponse),
// ),
// params(
// ("name_or_address" = String, Path, description = "Name or address to lookup the image for."),
Expand All @@ -32,10 +33,9 @@ pub async fn get(
.ok_or_else(|| http_simple_status_error(StatusCode::INTERNAL_SERVER_ERROR))?
.clone();

let profile =
universal_profile_resolve(&name_or_address, query.fresh.unwrap_or(false), rpc, &state)
.await
.map_err(profile_http_error_mapper)?;
let profile = universal_profile_resolve(&name_or_address, query.fresh, rpc, &state)
.await
.map_err(profile_http_error_mapper)?;

let Some(avatar) = profile.avatar else {
return Err(http_simple_status_error(StatusCode::NOT_FOUND));
Expand Down
22 changes: 17 additions & 5 deletions server/src/routes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,45 @@ use axum::http::StatusCode;
use axum::Json;
use enstate_shared::models::profile::error::ProfileError;
use enstate_shared::models::profile::Profile;
use ethers::prelude::ProviderError;
use ethers::providers::{Http, Provider};
use ethers_core::types::Address;
use serde::Deserialize;
use serde::{Deserialize, Deserializer};

use crate::cache;
use crate::models::error::ErrorResponse;

pub mod address;
pub mod four_oh_four;
pub mod header;
pub mod image;
pub mod name;
pub mod root;
pub mod universal;

pub mod four_oh_four;

#[derive(Deserialize)]
pub struct FreshQuery {
fresh: Option<bool>,
#[serde(default, deserialize_with = "bool_or_false")]
fresh: bool,
}

#[allow(clippy::unnecessary_wraps)]
fn bool_or_false<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,
{
let value: Result<bool, D::Error> = Deserialize::deserialize(deserializer);
Ok(value.unwrap_or_default())
}

pub type RouteError = (StatusCode, Json<ErrorResponse>);

pub fn profile_http_error_mapper(err: ProfileError) -> RouteError {
pub fn profile_http_error_mapper<T: AsRef<ProfileError>>(err: T) -> RouteError {
let err = err.as_ref();
let status = match err {
ProfileError::NotFound => StatusCode::NOT_FOUND,
ProfileError::CCIPError(_) => StatusCode::BAD_GATEWAY,
ProfileError::RPCError(ProviderError::EnsNotOwned(_)) => StatusCode::UNPROCESSABLE_ENTITY,
_ => StatusCode::INTERNAL_SERVER_ERROR,
};

Expand Down
2 changes: 1 addition & 1 deletion server/src/routes/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub async fn get(

let profile = Profile::from_name(
&name,
query.fresh.unwrap_or(false),
query.fresh,
cache,
rpc,
opensea_api_key,
Expand Down
8 changes: 4 additions & 4 deletions server/src/routes/universal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::routes::{
responses(
(status = 200, description = "Successfully found name or address.", body = ENSProfile),
(status = NOT_FOUND, description = "No name or address could be found.", body = ErrorResponse),
(status = UNPROCESSABLE_ENTITY, description = "Reverse record not owned by this address.", body = ErrorResponse),
),
params(
("name_or_address" = String, Path, description = "Name or address to lookup the name data for."),
Expand All @@ -34,10 +35,9 @@ pub async fn get(
.ok_or_else(|| http_simple_status_error(StatusCode::INTERNAL_SERVER_ERROR))?
.clone();

let profile =
universal_profile_resolve(&name_or_address, query.fresh.unwrap_or(false), rpc, &state)
.await
.map_err(profile_http_error_mapper)?;
let profile = universal_profile_resolve(&name_or_address, query.fresh, rpc, &state)
.await
.map_err(profile_http_error_mapper)?;

Ok(Json(profile))
}
10 changes: 5 additions & 5 deletions shared/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions shared/src/models/lookup/addr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::sync::Arc;

use async_trait::async_trait;
use ethers_core::{
abi::{ParamType, Token},
Expand All @@ -23,7 +21,7 @@ impl ENSLookup for Addr {
[fn_selector, data].concat()
}

async fn decode(&self, data: &[u8], _: Arc<LookupState>) -> Result<String, ENSLookupError> {
async fn decode(&self, data: &[u8], _: &LookupState) -> Result<String, ENSLookupError> {
let decoded_abi = ethers_core::abi::decode(&[ParamType::Address], data)
.map_err(|_| ENSLookupError::AbiDecodeError)?;

Expand Down
35 changes: 21 additions & 14 deletions shared/src/models/lookup/image.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::sync::Arc;

use async_trait::async_trait;
use ethers_core::types::U256;
use ethers_core::{
Expand Down Expand Up @@ -56,36 +54,43 @@ impl ENSLookup for Image {
[fn_selector, data].concat()
}

async fn decode(&self, data: &[u8], state: Arc<LookupState>) -> Result<String, ENSLookupError> {
async fn decode(&self, data: &[u8], state: &LookupState) -> Result<String, ENSLookupError> {
let decoded_abi = abi_decode_universal_ccip(data, &[ParamType::String])?;
let value = decoded_abi.get(0).ok_or(ENSLookupError::AbiDecodeError)?;
let value = value.to_string();

let Some(Token::String(value)) = decoded_abi.get(0) else {
return Err(ENSLookupError::AbiDecodeError);
};

let opensea_api_key = state.opensea_api_key.clone();

if let Some(captures) = IPFS_REGEX.captures(&value) {
if let Some(captures) = IPFS_REGEX.captures(value) {
let hash = captures.get(1).unwrap().as_str();

return Ok(format!("{}{hash}", self.ipfs_gateway));
}

let Some(captures) = EIP155_REGEX.captures(&value) else {
return Ok(value);
let Some(captures) = EIP155_REGEX.captures(value) else {
return Ok(value.to_string());
};

let chain_id = captures.get(1).unwrap().as_str();
let contract_type = captures.get(2).unwrap().as_str();
let contract_address = captures.get(3).unwrap().as_str();
let token_id = captures.get(4).unwrap().as_str();
let (Some(chain_id), Some(contract_type), Some(contract_address), Some(token_id)) = (
captures.get(1),
captures.get(2),
captures.get(3),
captures.get(4),
) else {
return Err(ENSLookupError::AbiDecodeError);
};

let chain_id = chain_id
.as_str()
.parse::<u64>()
.map_err(|err| ImageLookupError::FormatError(err.to_string()))?;

let token_id = U256::from_dec_str(token_id)
let token_id = U256::from_dec_str(token_id.as_str())
.map_err(|err| ImageLookupError::FormatError(err.to_string()))?;

let contract_type = match contract_type {
let contract_type = match contract_type.as_str() {
"erc721" => EIP155ContractType::ERC721,
"erc1155" => EIP155ContractType::ERC1155,
_ => {
Expand All @@ -95,6 +100,8 @@ impl ENSLookup for Image {
}
};

let contract_address = contract_address.as_str();

info!(
"Encountered Avatar: {chain_id} {contract_type} {contract_address} {token_id}",
chain_id = chain_id,
Expand Down
2 changes: 1 addition & 1 deletion shared/src/models/lookup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub enum ENSLookupError {
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait ENSLookup {
fn calldata(&self, namehash: &H256) -> Vec<u8>;
async fn decode(&self, data: &[u8], state: Arc<LookupState>) -> Result<String, ENSLookupError>;
async fn decode(&self, data: &[u8], state: &LookupState) -> Result<String, ENSLookupError>;
fn name(&self) -> String;

fn to_boxed(self) -> Box<Self>
Expand Down
18 changes: 6 additions & 12 deletions shared/src/models/lookup/multicoin.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::sync::Arc;

use async_trait::async_trait;
use ethers_core::{
abi::{ParamType, Token},
Expand Down Expand Up @@ -29,22 +27,18 @@ impl ENSLookup for Multicoin {
[fn_selector, data].concat()
}

async fn decode(&self, data: &[u8], _: Arc<LookupState>) -> Result<String, ENSLookupError> {
async fn decode(&self, data: &[u8], _: &LookupState) -> Result<String, ENSLookupError> {
let decoded_abi = abi_decode_universal_ccip(data, &[ParamType::Bytes])?;

let value = decoded_abi
.get(0)
.ok_or(ENSLookupError::AbiDecodeError)?
.clone()
.into_bytes()
.expect("token should be bytes");
let Some(Token::Bytes(bytes)) = decoded_abi.get(0) else {
return Err(ENSLookupError::AbiDecodeError);
};

if value.is_empty() {
// Empty field
if bytes.is_empty() {
return Ok(String::new());
}

Ok(self.coin_type.decode(&value)?)
Ok(self.coin_type.decode(bytes.as_ref())?)
}

fn name(&self) -> String {
Expand Down
12 changes: 6 additions & 6 deletions shared/src/models/lookup/text.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::sync::Arc;

use async_trait::async_trait;
use ethers_core::{
abi::{ParamType, Token},
Expand Down Expand Up @@ -41,12 +39,14 @@ impl ENSLookup for Text {
[fn_selector, data].concat()
}

async fn decode(&self, data: &[u8], _: Arc<LookupState>) -> Result<String, ENSLookupError> {
async fn decode(&self, data: &[u8], _: &LookupState) -> Result<String, ENSLookupError> {
let decoded_abi = abi_decode_universal_ccip(data, &[ParamType::String])?;
let value = decoded_abi.get(0).ok_or(ENSLookupError::AbiDecodeError)?;
let value = value.to_string();

Ok(value)
let Some(Token::String(value)) = decoded_abi.get(0) else {
return Err(ENSLookupError::AbiDecodeError);
};

Ok(value.to_string())
}

fn name(&self) -> String {
Expand Down
Loading

0 comments on commit b68f03a

Please sign in to comment.