Skip to content

Commit

Permalink
feat: add braavos x realms quest
Browse files Browse the repository at this point in the history
  • Loading branch information
irisdv committed Jan 25, 2024
1 parent 33cbe43 commit 4a22f78
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/endpoints/quests/braavos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod starknetid;
pub mod wallet;
pub mod pyramid;
pub mod zklend;
pub mod realms;
109 changes: 109 additions & 0 deletions src/endpoints/quests/braavos/realms/claimable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use crate::models::{AppState, CompletedTaskDocument, Reward, RewardResponse};
use crate::utils::{get_error, get_nft};
use axum::{
extract::{Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use futures::StreamExt;
use mongodb::bson::doc;
use serde::Deserialize;
use starknet::{
core::types::FieldElement,
signers::{LocalWallet, SigningKey},
};
use std::sync::Arc;

const QUEST_ID: u32 = 106;
const TASK_IDS: &[u32] = &[118, 119, 120, 121, 122];
const LAST_TASK: u32 = TASK_IDS[4];
const NFT_LEVEL: u32 = 36;

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

#[route(
get,
"/quests/braavos/realms/claimable",
crate::endpoints::quests::braavos::realms::claimable
)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<ClaimableQuery>,
) -> impl IntoResponse {
let collection = state
.db
.collection::<CompletedTaskDocument>("completed_tasks");

let pipeline = vec![
doc! {
"$match": {
"address": &query.addr.to_string(),
"task_id": { "$in": TASK_IDS },
},
},
doc! {
"$lookup": {
"from": "tasks",
"localField": "task_id",
"foreignField": "id",
"as": "task",
},
},
doc! {
"$match": {
"task.quest_id": QUEST_ID,
},
},
doc! {
"$group": {
"_id": "$address",
"completed_tasks": { "$push": "$task_id" },
},
},
doc! {
"$match": {
"completed_tasks": { "$all": TASK_IDS },
},
},
];

let completed_tasks = collection.aggregate(pipeline, None).await;
match completed_tasks {
Ok(mut tasks_cursor) => {
if tasks_cursor.next().await.is_none() {
return get_error("User hasn't completed all tasks".into());
}

let signer = LocalWallet::from(SigningKey::from_secret_scalar(
state.conf.nft_contract.private_key,
));

let mut rewards = vec![];

let Ok((token_id, sig)) =
get_nft(QUEST_ID, LAST_TASK, &query.addr, NFT_LEVEL, &signer).await
else {
return get_error("Signature failed".into());
};

rewards.push(Reward {
task_id: LAST_TASK,
nft_contract: state.conf.nft_contract.address.clone(),
token_id: token_id.to_string(),
sig: (sig.r, sig.s),
});

if rewards.is_empty() {
get_error("No rewards found for this user".into())
} else {
(StatusCode::OK, Json(RewardResponse { rewards })).into_response()
}
}
Err(_) => get_error("Error querying rewards".into()),
}
}
6 changes: 6 additions & 0 deletions src/endpoints/quests/braavos/realms/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod claimable;
pub mod verify_has_domain;
pub mod verify_has_played;
pub mod verify_twitter_fw_realms;
pub mod verify_twitter_fw_braavos;
pub mod verify_twitter_rt;
22 changes: 22 additions & 0 deletions src/endpoints/quests/braavos/realms/verify_has_domain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::{
common::verify_has_root_or_braavos_domain::verify_has_root_or_braavos_domain,
models::{AppState, VerifyQuery},
};
use axum::{
extract::{Query, State},
response::IntoResponse,
};
use axum_auto_routes::route;
use std::sync::Arc;

#[route(
get,
"/quests/braavos/realms/verify_has_domain",
crate::endpoints::quests::braavos::realms::verify_has_domain
)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<VerifyQuery>,
) -> impl IntoResponse {
verify_has_root_or_braavos_domain(state, &query.addr, 118).await
}
30 changes: 30 additions & 0 deletions src/endpoints/quests/braavos/realms/verify_has_played.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::sync::Arc;

use crate::{
models::{AppState, VerifyQuery},
utils::{get_error, CompletedTasksTrait},
};
use axum::{
extract::{Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use serde_json::json;

#[route(
get,
"/quests/braavos/realms/verify_has_played",
crate::endpoints::quests::braavos::realms::verify_has_played
)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<VerifyQuery>,
) -> impl IntoResponse {
let task_id = 121;
match state.upsert_completed_task(query.addr, task_id).await {
Ok(_) => (StatusCode::OK, Json(json!({"res": true}))).into_response(),
Err(e) => get_error(format!("{}", e)),
}
}
30 changes: 30 additions & 0 deletions src/endpoints/quests/braavos/realms/verify_twitter_fw_braavos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::sync::Arc;

use crate::{
models::{AppState, VerifyQuery},
utils::{get_error, CompletedTasksTrait},
};
use axum::{
extract::{Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use serde_json::json;

#[route(
get,
"/quests/braavos/realms/verify_twitter_fw_braavos",
crate::endpoints::quests::braavos::realms::verify_twitter_fw_braavos
)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<VerifyQuery>,
) -> impl IntoResponse {
let task_id = 119;
match state.upsert_completed_task(query.addr, task_id).await {
Ok(_) => (StatusCode::OK, Json(json!({"res": true}))).into_response(),
Err(e) => get_error(format!("{}", e)),
}
}
30 changes: 30 additions & 0 deletions src/endpoints/quests/braavos/realms/verify_twitter_fw_realms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::sync::Arc;

use crate::{
models::{AppState, VerifyQuery},
utils::{get_error, CompletedTasksTrait},
};
use axum::{
extract::{Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use serde_json::json;

#[route(
get,
"/quests/braavos/realms/verify_twitter_fw_realms",
crate::endpoints::quests::braavos::realms::verify_twitter_fw_realms
)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<VerifyQuery>,
) -> impl IntoResponse {
let task_id = 120;
match state.upsert_completed_task(query.addr, task_id).await {
Ok(_) => (StatusCode::OK, Json(json!({"res": true}))).into_response(),
Err(e) => get_error(format!("{}", e)),
}
}
30 changes: 30 additions & 0 deletions src/endpoints/quests/braavos/realms/verify_twitter_rt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::sync::Arc;

use crate::{
models::{AppState, VerifyQuery},
utils::{get_error, CompletedTasksTrait},
};
use axum::{
extract::{Query, State},
http::StatusCode,
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use serde_json::json;

#[route(
get,
"/quests/braavos/realms/verify_twitter_rt",
crate::endpoints::quests::braavos::realms::verify_twitter_rt
)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<VerifyQuery>,
) -> impl IntoResponse {
let task_id = 122;
match state.upsert_completed_task(query.addr, task_id).await {
Ok(_) => (StatusCode::OK, Json(json!({"res": true}))).into_response(),
Err(e) => get_error(format!("{}", e)),
}
}
10 changes: 10 additions & 0 deletions src/endpoints/quests/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,16 @@ pub async fn handler(
}),
).into_response(),

Some(36) => (
StatusCode::OK,
Json(TokenURI {
name: "Starknet Pro Score x Realms: Loot Survivor Quest NFT".into(),
description: "This Starknet commemorative Non-Fungible Token represents the first steps into the Starknet universe. By playing Loot Survivor, the first Loot adventure game exploring the Play2Die mechanic on Starknet, you are building solid foundations for your Starknet experience.".into(),
image: format!("{}/braavos/realms.webp", state.conf.variables.app_link),
attributes: None,
}),
).into_response(),

_ => get_error("Error, this level is not correct".into()),
}
}

0 comments on commit 4a22f78

Please sign in to comment.