Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/cairo2 #54

Merged
merged 21 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
starknet = { git = "https://github.com/Th0rgal/starknet-rs.git", branch = "feat/starknet-id" }
starknet = { git = "https://github.com/xJonathanLEI/starknet-rs", rev = "c974e5cb42e8d8344cee910b76005ec46b4dd3ed" }
starknet-id = { git = "https://github.com/starknet-id/starknetid.rs", rev = "2b30c2453b96789a628c86d2edebb1023fa2e77d" }
axum_auto_routes = { git = "https://github.com/Th0rgal/axum_auto_routes.git", rev = "f9e1d2083e887cd264642359c4aa851938da6f09" }
axum = "0.6.18"
futures = "0.3.28"
mongodb = "2.5.0"
Expand All @@ -16,10 +18,13 @@ tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] }
toml = "0.7.4"
tower-http = { version = "0.4.0", features = ["cors"] }
chrono = "0.4.24"
reqwest = "0.11.20"
reqwest = { version = "0.11.20", features = ["json"] }
ark-ff = "0.4.2"
hex = "0.4.3"
error-stack = "0.4.1"
anyhow = "1.0.75"
lazy_static = "1.4.0"
regex = "1.10.2"
bs58 = "0.5.0"
ed25519-dalek = "2.1.0"
ctor = "0.2.6"
56 changes: 56 additions & 0 deletions src/endpoints/addr_has_rev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::{
models::AppState,
utils::{get_error, to_hex},
};
use axum::{
extract::{Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use mongodb::bson::doc;
use serde::{Deserialize, Serialize};
use starknet::core::types::FieldElement;
use std::sync::Arc;

#[derive(Serialize)]
pub struct AddrToDomainData {
has_rev: bool,
}

#[derive(Deserialize)]
pub struct AddrHasRevQuery {
addr: FieldElement,
}

#[route(get, "/addr_has_rev", crate::endpoints::addr_has_rev)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<AddrHasRevQuery>,
) -> impl IntoResponse {
let domains = state
.starknetid_db
.collection::<mongodb::bson::Document>("domains");
let hex_addr = to_hex(&query.addr);
let document = domains
.find_one(
doc! {
"_cursor.to" : null,
"rev_address" : hex_addr
},
None,
)
.await;

match document {
Ok(doc) => (
StatusCode::OK,
Json(AddrToDomainData {
has_rev: doc.is_some(),
}),
)
.into_response(),
Err(_) => get_error("Error while fetching from database".to_string()),
}
}
13 changes: 11 additions & 2 deletions src/endpoints/addr_to_available_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use axum::{
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use futures::StreamExt;
use mongodb::bson::doc;
use serde::{Deserialize, Serialize};
Expand All @@ -25,17 +26,25 @@ pub struct AddrQuery {
addr: FieldElement,
}

#[route(get, "/addr_to_available_ids", crate::endpoints::addr_to_available_ids)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<AddrQuery>,
) -> impl IntoResponse {
let starknet_ids = state.starknetid_db.collection::<mongodb::bson::Document>("id_owners");
let domains = state.starknetid_db.collection::<mongodb::bson::Document>("domains");
let starknet_ids = state
.starknetid_db
.collection::<mongodb::bson::Document>("id_owners");
let domains = state
.starknetid_db
.collection::<mongodb::bson::Document>("domains");
let addr = to_hex(&query.addr);
let documents = starknet_ids
.find(
doc! {
"owner": &addr,
"id" : {
"$ne" : null
},
"_cursor.to": null,
},
None,
Expand Down
155 changes: 127 additions & 28 deletions src/endpoints/addr_to_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,158 @@ use crate::{
models::AppState,
utils::{get_error, to_hex},
};
use anyhow::{bail, Result};
use axum::{
extract::{Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use mongodb::bson::{doc, Bson};
use axum_auto_routes::route;
use futures::StreamExt;
use mongodb::{
bson::{doc, Document},
options::AggregateOptions,
Cursor,
};
use serde::{Deserialize, Serialize};
use starknet::core::types::FieldElement;
use std::sync::Arc;

#[derive(Serialize)]
pub struct AddrToDomainData {
domain: String,
domain_expiry: i64,
domain_expiry: Option<i64>,
}

#[derive(Deserialize)]
pub struct AddrToDomainQuery {
addr: FieldElement,
}

async fn read_cursor(mut cursor: Cursor<Document>) -> Result<AddrToDomainData> {
while let Some(result) = cursor.next().await {
let doc = result?;
let domain = doc.get_str("domain").unwrap_or_default().to_owned();
let domain_expiry = doc.get_i64("domain_expiry").ok();
return Ok(AddrToDomainData {
domain,
domain_expiry,
});
}
bail!("No document found for the given address")
}

async fn aggregate_data(
collection: mongodb::Collection<Document>,
pipeline: Vec<Document>,
) -> Result<AddrToDomainData> {
let cursor = collection
.aggregate(pipeline, AggregateOptions::default())
.await?;
read_cursor(cursor).await
}

#[route(get, "/addr_to_domain", crate::endpoints::addr_to_domain)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<AddrToDomainQuery>,
) -> impl IntoResponse {
let domains = state.starknetid_db.collection::<mongodb::bson::Document>("domains");
let hex_addr = to_hex(&query.addr);
let document = domains
.find_one(
doc! {
"legacy_address": &hex_addr,
"rev_address": &hex_addr,
"_cursor.to": Bson::Null,
},
None,
)
.await;

match document {
Ok(doc) => {
if let Some(doc) = doc {
let domain = doc.get_str("domain").unwrap_or_default().to_owned();
let expiry = doc.get_i64("expiry").unwrap_or_default();
let data = AddrToDomainData {
domain,
domain_expiry: expiry,
};
(StatusCode::OK, Json(data)).into_response()
} else {
get_error("No domain found".to_string())
}
let domains_collection = state.starknetid_db.collection::<Document>("domains");
let id_owners_collection = state.starknetid_db.collection::<Document>("id_owners");

let legacy_pipeline = create_legacy_pipeline(&hex_addr);
let normal_pipeline = create_normal_pipeline(&hex_addr);
let main_id_pipeline = create_main_id_pipeline(&hex_addr);

let results = [
aggregate_data(domains_collection.clone(), legacy_pipeline),
aggregate_data(domains_collection.clone(), normal_pipeline),
aggregate_data(id_owners_collection, main_id_pipeline),
];

for result in results {
match result.await {
Ok(data) => return (StatusCode::OK, Json(data)).into_response(),
Err(_) => continue,
}
Err(_) => get_error("Error while fetching from database".to_string()),
}

get_error("No data found for the given address".to_string())
}

fn create_legacy_pipeline(address: &String) -> Vec<Document> {
vec![
doc! { "$match": { "_cursor.to": null, "rev_address": address, "$expr": {
"$eq": ["$rev_address", "$legacy_address"]
} } },
doc! { "$project": {
"domain": 1,
"domain_expiry" : "$expiry"
}},
]
}

fn create_normal_pipeline(address: &String) -> Vec<Document> {
vec![
doc! { "$match": { "_cursor.to": null, "rev_address": address } },
doc! { "$lookup": {
"from": "id_owners",
"let": { "rev_address": "$rev_address" },
"pipeline": [
{ "$match": {
"$or": [
{ "_cursor.to": null },
{ "_cursor.to": { "$exists": false } }
],
"$expr": { "$eq": ["$owner", "$$rev_address"] }
} }
],
"as": "identity"
}},
doc! { "$unwind": "$identity" },
doc! { "$lookup": {
"from": "id_user_data",
"let": { "id": "$identity.id" },
"pipeline": [
doc! { "$match": {
"_cursor.to": { "$exists": false },
"field": "0x000000000000000000000000000000000000000000000000737461726b6e6574",
"$expr": { "$eq": ["$id", "$$id"] }
} }
],
"as": "starknet_data"
}},
doc! { "$unwind": "$starknet_data" },
doc! { "$match": {
"$expr": { "$eq": ["$rev_address", "$starknet_data.data"] }
}},
doc! { "$project": {
"domain": 1,
"domain_expiry" : "$expiry"
}},
]
}

fn create_main_id_pipeline(address: &String) -> Vec<Document> {
vec![
doc! { "$match": { "_cursor.to": null, "owner": address, "main": true } },
doc! { "$lookup": {
"from": "domains",
"let": { "id": "$id" },
"pipeline": [
doc! { "$match": {
"_cursor.to": { "$exists": false },
"$expr": { "$eq": ["$id", "$$id"] }
} }
],
"as": "domain_data"
}},
doc! { "$unwind": "$domain_data" },
doc! { "$project": {
"domain": "$domain_data.domain",
"domain_expiry" : "$domain_data.expiry"
}},
]
}
6 changes: 6 additions & 0 deletions src/endpoints/addr_to_external_domains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use axum::{
http::{HeaderMap, HeaderValue, StatusCode},
response::IntoResponse,
};
use axum_auto_routes::route;
use futures::StreamExt;
use mongodb::bson::doc;
use serde::{Deserialize, Serialize};
Expand All @@ -23,6 +24,11 @@ pub struct DomainQuery {
addr: FieldElement,
}

#[route(
get,
"/addr_to_external_domains",
crate::endpoints::addr_to_external_domains
)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<DomainQuery>,
Expand Down
5 changes: 5 additions & 0 deletions src/endpoints/addr_to_full_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use axum::{
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use futures::future::join_all;
use futures::stream::StreamExt;
use mongodb::{
Expand Down Expand Up @@ -52,6 +53,7 @@ pub struct FullIdResponse {
full_ids: Vec<FullId>,
}

#[route(get, "/addr_to_full_ids", crate::endpoints::addr_to_full_ids)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<AddrQuery>,
Expand All @@ -64,6 +66,9 @@ pub async fn handler(
doc! {
"$match": doc! {
"owner": to_hex(&query.addr),
"id" : {
"$ne" : null
},
"_cursor.to": Bson::Null
}
},
Expand Down
2 changes: 2 additions & 0 deletions src/endpoints/addr_to_token_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use axum::{
http::{HeaderMap, HeaderValue, StatusCode},
response::{IntoResponse, Json},
};
use axum_auto_routes::route;
use mongodb::bson::{doc, Bson};
use serde::{Deserialize, Serialize};
use starknet::core::types::FieldElement;
Expand All @@ -22,6 +23,7 @@ pub struct TokenIdQuery {
addr: FieldElement,
}

#[route(get, "/addr_to_token_id", crate::endpoints::addr_to_token_id)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<TokenIdQuery>,
Expand Down
Loading