Skip to content

Commit

Permalink
fix: implement feedbacks from review
Browse files Browse the repository at this point in the history
  • Loading branch information
irisdv committed May 10, 2024
1 parent dd64067 commit c361ed5
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 39 deletions.
7 changes: 7 additions & 0 deletions config.template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ argent_multicall = "0xXXXXXXXXXXXX"
[variables]
rpc_url = "xxxxxx"
refresh_delay = 60 # in seconds
ipfs_gateway = "https://gateway.pinata.cloud/ipfs/" # or https://ipfs.io/ipfs/

[starkscan]
api_url = "https://api-testnet.starkscan.co/api/v0"
Expand Down Expand Up @@ -77,3 +78,9 @@ uri = [

[evm]
private_key = "0xXXXXXXXXXXXX"

[evm_networks]
polygon = 2147483785
optimism = 2147483658
base = 2147492101
arbitrum = 2147525809
11 changes: 11 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use serde::de::{MapAccess, Visitor};
use serde::{Deserialize, Deserializer};
use starknet::core::types::FieldElement;
use starknet::core::utils::cairo_short_string_to_felt;
use std::collections::HashMap;
use std::env;
use std::fs;
Expand Down Expand Up @@ -71,6 +72,7 @@ pub_struct!(Clone, Debug; Altcoins {
pub_struct!(Clone, Debug, Deserialize; Variables {
rpc_url: String,
refresh_delay: f64,
ipfs_gateway: String,
});

#[derive(Deserialize)]
Expand Down Expand Up @@ -104,6 +106,7 @@ struct RawConfig {
altcoins: Altcoins,
offchain_resolvers: OffchainResolvers,
evm: Evm,
evm_networks: HashMap<String, u64>,
}

pub_struct!(Clone, Deserialize; Config {
Expand All @@ -118,6 +121,7 @@ pub_struct!(Clone, Deserialize; Config {
altcoins: Altcoins,
offchain_resolvers: OffchainResolvers,
evm: Evm,
evm_networks: HashMap<u64, FieldElement>,
});

impl Altcoins {
Expand Down Expand Up @@ -206,6 +210,12 @@ impl From<RawConfig> for Config {
}
}

let mut reversed_evm_networks = HashMap::new();
for (key, value) in &raw.evm_networks {
let chain_name = cairo_short_string_to_felt(&key.clone()).unwrap();
reversed_evm_networks.insert(*value, chain_name);
}

Config {
server: raw.server,
databases: raw.databases,
Expand All @@ -218,6 +228,7 @@ impl From<RawConfig> for Config {
altcoins: raw.altcoins,
offchain_resolvers: raw.offchain_resolvers,
evm: raw.evm,
evm_networks: reversed_evm_networks,
}
}
}
Expand Down
18 changes: 6 additions & 12 deletions src/endpoints/crosschain/ethereum/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, str::FromStr, sync::Arc};
use std::{str::FromStr, sync::Arc};

use crate::{
endpoints::crosschain::ethereum::{
Expand Down Expand Up @@ -93,14 +93,6 @@ where
}

lazy_static! {
static ref NETWORK_NAMES: HashMap<u64, FieldElement> = {
let mut map = HashMap::new();
map.insert(2147483785, short_string!("polygon"));
map.insert(2147483658, short_string!("optimism"));
map.insert(2147492101, short_string!("base"));
map.insert(2147525809, short_string!("arbitrum"));
map
};
static ref EVM_ADDRESS: FieldElement = short_string!("evm-address");
static ref ETHEREUM: FieldElement = short_string!("ethereum");
}
Expand Down Expand Up @@ -158,6 +150,7 @@ pub async fn handler(State(state): State<Arc<AppState>>, query: Query) -> impl I
// Records available "com.discord" "com.github" "com.twitter"
"url" => {
match get_profile_picture(
&state.conf,
&provider,
state.starknetid_db.collection::<mongodb::bson::Document>(
"id_verifier_data",
Expand All @@ -168,10 +161,12 @@ pub async fn handler(State(state): State<Arc<AppState>>, query: Query) -> impl I
.await
{
Some(pfp) => vec![Token::String(pfp)],
None => return get_error(
None => {
return get_error(
"No profile picture specified for this domain"
.to_string(),
)
}
}
}
_ => {
Expand Down Expand Up @@ -219,9 +214,8 @@ pub async fn handler(State(state): State<Arc<AppState>>, query: Query) -> impl I
}
} else {
// evm chain
match NETWORK_NAMES.get(&chain) {
match state.conf.evm_networks.get(&chain) {
Some(field_name) => {
println!("Chain: {:?}", name);
match get_user_data_multicall(
&provider,
&state.conf,
Expand Down
38 changes: 22 additions & 16 deletions src/endpoints/crosschain/ethereum/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use ethers::{
use futures::StreamExt;
use lazy_static::lazy_static;
use mongodb::{
bson::{doc, Bson, Document},
bson::{doc, from_document, Document},
Collection,
};
use starknet::{
Expand All @@ -24,6 +24,7 @@ use std::fmt::Write;

use crate::{
config::Config,
endpoints::uri::VerifierData,
utils::{fetch_image_url, parse_base64_image, to_hex},
};

Expand Down Expand Up @@ -261,6 +262,7 @@ pub async fn domain_to_address(

// Profile picture metadata utils
pub async fn get_profile_picture(
config: &Config,
provider: &JsonRpcClient<HttpTransport>,
verifier_data_collection: Collection<Document>,
pfp_verifier: FieldElement,
Expand All @@ -277,19 +279,16 @@ pub async fn get_profile_picture(
Ok(mut cursor) => {
let mut contract_addr: String = String::new();
let mut token_id: (String, String) = (String::new(), String::new());
while let Some(doc) = cursor.next().await {
if let Ok(doc) = doc {
let field = &doc.get_str("field").unwrap_or_default().to_owned();
if *field == *NFT_PP_CONTRACT {
contract_addr = doc.get_str("data").unwrap_or_default().to_owned();
} else if *field == *NFT_PP_ID {
if let Ok(extended_data) = doc.get_array("extended_data") {
if let (Some(Bson::String(first)), Some(Bson::String(second))) =
(extended_data.get(0), extended_data.get(1))
{
token_id = (first.clone(), second.clone());
} else {
println!("Error: extended_data array does not contain two strings");
while let Some(result) = cursor.next().await {
if let Ok(doc) = result {
if let Ok(verifier_data) = from_document::<VerifierData>(doc) {
if *verifier_data.field == *NFT_PP_CONTRACT {
if let Some(addr) = verifier_data.data {
contract_addr = addr;
}
} else if *verifier_data.field == *NFT_PP_ID {
if let Some(token_id_arr) = verifier_data.extended_data {
token_id = (token_id_arr[0].clone(), token_id_arr[1].clone());
}
} else {
println!("Error: failed to get 'extended_data' as array");
Expand Down Expand Up @@ -323,7 +322,13 @@ pub async fn get_profile_picture(
.filter_map(|val| parse_cairo_short_string(val).ok())
.collect::<Vec<String>>() // Collect into a vector of strings
.join("");
match get_profile_picture_uri(Some(&pfp_metadata), true, &id.to_string()).await
match get_profile_picture_uri(
config,
Some(&pfp_metadata),
true,
&id.to_string(),
)
.await
{
Some(pfp) => {
println!("Profile picture fetched successfully {}", pfp);
Expand All @@ -349,13 +354,14 @@ pub async fn get_profile_picture(
}

pub async fn get_profile_picture_uri(
config: &Config,
uri: Option<&str>,
use_default_pfp: bool,
id: &str,
) -> Option<String> {
match uri {
Some(u) if u.contains("base64") => Some(parse_base64_image(u)),
Some(u) => Some(fetch_image_url(u).await),
Some(u) => Some(fetch_image_url(config, u).await),
None if use_default_pfp => Some(format!("https://starknet.id/api/identicons/{}", id)),
_ => None,
}
Expand Down
10 changes: 5 additions & 5 deletions src/endpoints/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ pub struct TokenIdQuery {
id: FieldElement,
}

#[derive(Serialize, Debug)]
#[derive(Serialize, Debug, Deserialize)]
pub struct VerifierData {
verifier: String,
field: String,
data: Option<String>,
extended_data: Option<Vec<String>>,
pub verifier: String,
pub field: String,
pub data: Option<String>,
pub extended_data: Option<Vec<String>>,
}

const NFT_PP_CONTRACT: &'static str =
Expand Down
12 changes: 6 additions & 6 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use serde_json::Value;
use starknet::core::types::FieldElement;
use std::{fmt::Write, str, sync::Arc};

use crate::models::AppState;
use crate::{config::Config, models::AppState};

#[derive(Serialize)]
pub struct ErrorMessage {
Expand Down Expand Up @@ -148,19 +148,19 @@ pub fn parse_base64_image(metadata: &str) -> String {
v["image"].as_str().unwrap_or("").to_string()
}

fn parse_image_url(url: &str) -> String {
fn parse_image_url(config: &Config, url: &str) -> String {
if url.starts_with("ipfs://") {
url.replace("ipfs://", "https://gateway.pinata.cloud/ipfs/")
url.replace("ipfs://", config.variables.ipfs_gateway.as_str())
} else {
url.to_string()
}
}

pub async fn fetch_image_url(url: &str) -> String {
let parsed_url = parse_image_url(url);
pub async fn fetch_image_url(config: &Config, url: &str) -> String {
let parsed_url = parse_image_url(config, url);
match reqwest::get(&parsed_url).await {
Ok(resp) => match resp.json::<Value>().await {
Ok(data) => parse_image_url(data["image"].as_str().unwrap_or("")),
Ok(data) => parse_image_url(config, data["image"].as_str().unwrap_or("")),
Err(_) => "Error fetching data".to_string(),
},
Err(_) => "Error fetching data".to_string(),
Expand Down

0 comments on commit c361ed5

Please sign in to comment.