From 4e0f14df4cf33dfcde59b658f444e9d2534669da Mon Sep 17 00:00:00 2001 From: silverpill Date: Wed, 26 Jan 2022 14:59:15 +0000 Subject: [PATCH] Add API method for getting authorization of paid subscription setup transaction --- docs/openapi.yaml | 42 +++++++++++++++++++++--------- src/ethereum/mod.rs | 1 + src/ethereum/subscriptions.rs | 20 ++++++++++++++ src/mastodon_api/accounts/views.rs | 21 +++++++++++++++ 4 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 src/ethereum/subscriptions.rs diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 1b8e109..26921e9 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -87,6 +87,20 @@ paths: $ref: '#/components/schemas/Account' 400: description: Invalid user data + /api/v1/accounts/authorize_subscription: + get: + summary: Get authorization for setting up paid subscription. + responses: + 200: + description: Signature created + content: + application/json: + schema: + $ref: '#/components/schemas/Signature' + 403: + description: User's wallet address is not known + 418: + description: Blockchain integration is not enabled /api/v1/accounts/relationships: get: summary: Find out whether a given actor is followed, blocked, muted, etc. @@ -431,24 +445,13 @@ paths: content: application/json: schema: - type: object - properties: - v: - type: integer - format: int64 - example: 27 - r: - type: string - example: '6f61670e67bf72...' - s: - type: string - example: '6a5cb313907cd3...' + $ref: '#/components/schemas/Signature' 403: description: Post does not belong to user, is not public or not saved to IPFS, or user's wallet address is not known 404: description: Post not found 418: - description: Ethereum integration is not enabled + description: Blockchain integration is not enabled /api/v1/statuses/{status_id}/token_minted: post: summary: Register transaction that mints a token @@ -648,6 +651,19 @@ components: requested: description: Do you have a pending follow request for this user? type: boolean + Signature: + type: object + properties: + v: + type: integer + format: int64 + example: 27 + r: + type: string + example: '6f61670e67bf72...' + s: + type: string + example: '6a5cb313907cd3...' Status: type: object properties: diff --git a/src/ethereum/mod.rs b/src/ethereum/mod.rs index 7fc2b47..da2c757 100644 --- a/src/ethereum/mod.rs +++ b/src/ethereum/mod.rs @@ -4,4 +4,5 @@ mod errors; pub mod gate; pub mod nft; pub mod signatures; +pub mod subscriptions; pub mod utils; diff --git a/src/ethereum/subscriptions.rs b/src/ethereum/subscriptions.rs new file mode 100644 index 0000000..f3e14d3 --- /dev/null +++ b/src/ethereum/subscriptions.rs @@ -0,0 +1,20 @@ +use crate::config::BlockchainConfig; +use super::errors::EthereumError; +use super::signatures::{sign_contract_call, CallArgs, SignatureData}; +use super::utils::parse_address; + +pub fn create_subscription_signature( + blockchain_config: &BlockchainConfig, + user_address: &str, +) -> Result { + let user_address = parse_address(user_address)?; + let call_args: CallArgs = vec![Box::new(user_address)]; + let signature = sign_contract_call( + &blockchain_config.signing_key, + blockchain_config.ethereum_chain_id(), + &blockchain_config.contract_address, + "configureSubscription", + call_args, + )?; + Ok(signature) +} diff --git a/src/mastodon_api/accounts/views.rs b/src/mastodon_api/accounts/views.rs index 99a0505..28edf97 100644 --- a/src/mastodon_api/accounts/views.rs +++ b/src/mastodon_api/accounts/views.rs @@ -14,6 +14,7 @@ use crate::config::Config; use crate::database::{Pool, get_database_client}; use crate::errors::{DatabaseError, HttpError, ValidationError}; use crate::ethereum::gate::is_allowed_user; +use crate::ethereum::subscriptions::create_subscription_signature; use crate::mastodon_api::oauth::auth::get_current_user; use crate::models::posts::helpers::{ get_actions_for_posts, @@ -171,6 +172,25 @@ async fn update_credentials( Ok(HttpResponse::Ok().json(account)) } +#[get("/authorize_subscription")] +async fn authorize_subscription( + auth: BearerAuth, + config: web::Data, + db_pool: web::Data, +) -> Result { + let db_client = &**get_database_client(&db_pool).await?; + let current_user = get_current_user(db_client, auth.token()).await?; + let blockchain_config = config.blockchain.as_ref() + .ok_or(HttpError::NotSupported)?; + let wallet_address = current_user.wallet_address + .ok_or(HttpError::PermissionError)?; + let signature = create_subscription_signature( + blockchain_config, + &wallet_address, + ).map_err(|_| HttpError::InternalError)?; + Ok(HttpResponse::Ok().json(signature)) +} + // TODO: actix currently doesn't support parameter arrays // https://github.com/actix/actix-web/issues/2044 #[derive(Deserialize)] @@ -384,6 +404,7 @@ pub fn account_api_scope() -> Scope { .service(get_relationships_view) .service(verify_credentials) .service(update_credentials) + .service(authorize_subscription) // Routes with account ID .service(get_account) .service(follow_account)