diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/user_wallets/get_or_create_session_artcraft_wallet_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/user_wallets/get_or_create_session_artcraft_wallet_handler.rs new file mode 100644 index 0000000000..5dc02dfcd8 --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/user_wallets/get_or_create_session_artcraft_wallet_handler.rs @@ -0,0 +1,100 @@ +use std::sync::Arc; + +use crate::http_server::common_responses::common_web_error::CommonWebError; +use crate::state::server_state::ServerState; +use actix_web::web::Json; +use actix_web::{web, HttpRequest}; +use enums::common::payments_namespace::PaymentsNamespace; +use log::{error, warn}; +use mysql_queries::queries::wallets::create_new_artcraft_wallet_for_owner_user::create_new_artcraft_wallet_for_owner_user; +use mysql_queries::queries::wallets::find_primary_wallet_token_for_owner::find_primary_wallet_token_for_owner_using_transaction; +use serde::{Deserialize, Serialize}; +use sqlx::Acquire; +use tokens::tokens::wallets::WalletToken; +use utoipa::ToSchema; + +#[derive(Serialize, Deserialize, ToSchema)] +pub struct GetOrCreateSessionArtcraftWalletResponse { + pub success: bool, + pub wallet_token: WalletToken, +} + +#[utoipa::path( + post, + tag = "Wallets", + path = "/v1/wallets/session_artcraft_wallet", + responses( + (status = 200, description = "Success", body = GetOrCreateSessionArtcraftWalletResponse), + ), +)] +pub async fn get_or_create_session_artcraft_wallet_handler( + http_request: HttpRequest, + server_state: web::Data>, +) -> Result, CommonWebError> { + let mut mysql_connection = server_state.mysql_pool + .acquire() + .await + .map_err(|err| { + error!("Error acquiring MySQL connection: {:?}", err); + CommonWebError::ServerError + })?; + + let maybe_user_session = server_state + .session_checker + .maybe_get_user_session_from_connection(&http_request, &mut mysql_connection) + .await + .map_err(|e| { + warn!("Session checker error: {:?}", e); + CommonWebError::ServerError + })?; + + let user_token = match maybe_user_session { + Some(session) => session.user_token, + None => return Err(CommonWebError::NotAuthorized), + }; + + let mut transaction = mysql_connection + .begin() + .await + .map_err(|err| { + error!("Error starting MySQL transaction: {:?}", err); + CommonWebError::ServerError + })?; + + let maybe_wallet_token = find_primary_wallet_token_for_owner_using_transaction( + &user_token, + PaymentsNamespace::Artcraft, + &mut transaction, + ).await.map_err(|err| { + error!("Error finding primary artcraft wallet for user {:?}: {:?}", user_token, err); + CommonWebError::ServerError + })?; + + if let Some(wallet_token) = maybe_wallet_token { + return Ok(Json(GetOrCreateSessionArtcraftWalletResponse { + success: true, + wallet_token, + })); + } + + let wallet_token = create_new_artcraft_wallet_for_owner_user( + &user_token, + &mut transaction, + ).await.map_err(|err| { + error!("Error creating artcraft wallet for user {:?}: {:?}", user_token, err); + CommonWebError::ServerError + })?; + + transaction + .commit() + .await + .map_err(|err| { + error!("Error committing MySQL transaction: {:?}", err); + CommonWebError::ServerError + })?; + + Ok(Json(GetOrCreateSessionArtcraftWalletResponse { + success: true, + wallet_token, + })) +} diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/user_wallets/mod.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/user_wallets/mod.rs index e69de29bb2..4e3921332e 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/user_wallets/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/user_wallets/mod.rs @@ -0,0 +1 @@ +pub mod get_or_create_session_artcraft_wallet_handler; diff --git a/crates/service/web/storyteller_web/src/http_server/routes/application_routes/add_application_routes.rs b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/add_application_routes.rs index cf4551187b..6fd2482086 100644 --- a/crates/service/web/storyteller_web/src/http_server/routes/application_routes/add_application_routes.rs +++ b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/add_application_routes.rs @@ -13,6 +13,7 @@ use crate::http_server::routes::application_routes::tag_routes::add_tag_routes; use crate::http_server::routes::application_routes::user_bookmarks_routes::add_user_bookmarks_routes; use crate::http_server::routes::application_routes::user_rating_routes::add_user_rating_routes; use crate::http_server::routes::application_routes::user_routes::add_user_routes; +use crate::http_server::routes::application_routes::wallet_routes::add_wallet_routes; use crate::http_server::routes::application_routes::webhook_routes::add_webhook_routes; use crate::http_server::routes::application_routes::weights_routes::add_weights_routes; use actix_http::body::MessageBody; @@ -62,6 +63,7 @@ where app = add_user_routes(app); // /create_account, /session, /login, /logout, etc. // Artcraft Billing pieces + app = add_wallet_routes(app); // /v1/wallets/... app = add_credits_routes(app); // /v1/credits/... app = add_stripe_artcraft_routes(app); // /v1/stripe_artcraft/... app = add_subscription_routes(app); // /v1/subscriptions/... diff --git a/crates/service/web/storyteller_web/src/http_server/routes/application_routes/mod.rs b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/mod.rs index 39dd09fa98..161119bb56 100644 --- a/crates/service/web/storyteller_web/src/http_server/routes/application_routes/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/mod.rs @@ -1,3 +1,4 @@ +mod analytics_routes; mod comments_routes; mod credits_routes; mod featured_item_routes; @@ -5,14 +6,14 @@ mod generate_routes; mod job_routes; mod media_files_routes; mod moderation_routes; +mod prompts_routes; mod stripe_artcraft_routes; mod subscription_routes; mod tag_routes; mod user_bookmarks_routes; mod user_rating_routes; mod user_routes; +mod wallet_routes; mod webhook_routes; mod weights_routes; -pub (super) mod add_application_routes; -mod prompts_routes; -mod analytics_routes; \ No newline at end of file +pub (super) mod add_application_routes; \ No newline at end of file diff --git a/crates/service/web/storyteller_web/src/http_server/routes/application_routes/wallet_routes.rs b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/wallet_routes.rs new file mode 100644 index 0000000000..4015e2c4d8 --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/routes/application_routes/wallet_routes.rs @@ -0,0 +1,24 @@ +use crate::http_server::endpoints::user_wallets::get_or_create_session_artcraft_wallet_handler::get_or_create_session_artcraft_wallet_handler; +use actix_http::body::MessageBody; +use actix_service::ServiceFactory; +use actix_web::dev::{ServiceRequest, ServiceResponse}; +use actix_web::{web, App, Error, HttpResponse}; + +pub fn add_wallet_routes(app: App) -> App +where + B: MessageBody, + T: ServiceFactory< + ServiceRequest, + Config = (), + Response = ServiceResponse, + Error = Error, + InitError = (), + >, +{ + app.service(web::scope("/v1/wallets") + .service(web::resource("/session_artcraft_wallet") + .route(web::post().to(get_or_create_session_artcraft_wallet_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) + ) +}