diff --git a/contracts/IAdapter.json b/contracts/IAdapter.json index 12cda06..5109f14 100644 --- a/contracts/IAdapter.json +++ b/contracts/IAdapter.json @@ -1,7 +1,7 @@ { "_format": "hh-sol-artifact-1", "contractName": "IAdapter", - "sourceName": "contracts/IAdapter.sol", + "sourceName": "contracts/interfaces/IAdapter.sol", "abi": [ { "inputs": [], @@ -23,6 +23,11 @@ "name": "recipient", "type": "address" }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, { "internalType": "uint8", "name": "v", diff --git a/contracts/ISubscription.json b/contracts/ISubscription.json index b1ee744..ae55cce 100644 --- a/contracts/ISubscription.json +++ b/contracts/ISubscription.json @@ -1,7 +1,7 @@ { "_format": "hh-sol-artifact-1", "contractName": "ISubscription", - "sourceName": "contracts/ISubscription.sol", + "sourceName": "contracts/interfaces/ISubscription.sol", "abi": [ { "anonymous": false, diff --git a/docs/openapi.yaml b/docs/openapi.yaml index f0ed1a5..7d56301 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -141,6 +141,13 @@ paths: /api/v1/accounts/authorize_subscription: get: summary: Get authorization for setting up paid subscription. + parameters: + - name: price + in: query + description: Subscription price + required: true + schema: + type: number responses: 200: description: Signature created diff --git a/src/ethereum/signatures.rs b/src/ethereum/signatures.rs index 5049eb6..ecf56ad 100644 --- a/src/ethereum/signatures.rs +++ b/src/ethereum/signatures.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use secp256k1::{Error as KeyError, SecretKey, rand::rngs::OsRng}; use serde::Serialize; -use web3::ethabi::{token::Token, encode}; +use web3::ethabi::{token::Token, encode as encode_tokens}; use web3::signing::{ keccak256, recover, @@ -12,7 +12,7 @@ use web3::signing::{ SecretKeyRef, SigningError, }; -use web3::types::{Address, H256, Recovery, U256}; +use web3::types::{Address, H256, Recovery}; /// Generates signing key pub fn generate_ecdsa_key() -> SecretKey { @@ -129,6 +129,11 @@ pub fn recover_address( pub type CallArgs = Vec>>; +pub fn encode_uint256(value: u64) -> Vec { + let token = Token::Uint(value.into()); + encode_tokens(&[token]) +} + pub fn sign_contract_call( signing_key: &str, chain_id: u32, @@ -136,9 +141,7 @@ pub fn sign_contract_call( method_name: &str, method_args: CallArgs, ) -> Result { - let chain_id: U256 = chain_id.into(); - let chain_id_token = Token::Uint(chain_id); - let chain_id_bin = encode(&[chain_id_token]); + let chain_id_bin = encode_uint256(chain_id.into()); let contract_address = Address::from_str(contract_address) .map_err(|_| SignatureError::InvalidData)?; let mut message = [ diff --git a/src/ethereum/subscriptions.rs b/src/ethereum/subscriptions.rs index eee7876..ec546ca 100644 --- a/src/ethereum/subscriptions.rs +++ b/src/ethereum/subscriptions.rs @@ -25,7 +25,12 @@ use crate::models::subscriptions::queries::{ }; use crate::models::users::queries::get_user_by_wallet_address; use super::errors::EthereumError; -use super::signatures::{sign_contract_call, CallArgs, SignatureData}; +use super::signatures::{ + encode_uint256, + sign_contract_call, + CallArgs, + SignatureData, +}; use super::sync::{save_current_block_number, SyncState}; use super::utils::{address_to_string, parse_address}; @@ -197,9 +202,13 @@ pub async fn check_subscriptions( pub fn create_subscription_signature( blockchain_config: &BlockchainConfig, user_address: &str, + price: u64, ) -> Result { let user_address = parse_address(user_address)?; - let call_args: CallArgs = vec![Box::new(user_address)]; + let call_args: CallArgs = vec![ + Box::new(user_address), + Box::new(encode_uint256(price)), + ]; let signature = sign_contract_call( &blockchain_config.signing_key, blockchain_config.ethereum_chain_id(), diff --git a/src/mastodon_api/accounts/types.rs b/src/mastodon_api/accounts/types.rs index afafec9..e18d593 100644 --- a/src/mastodon_api/accounts/types.rs +++ b/src/mastodon_api/accounts/types.rs @@ -228,6 +228,11 @@ pub struct IdentityProofData { pub signature: String, } +#[derive(Deserialize)] +pub struct SubscriptionQueryParams { + pub price: u64, +} + // TODO: actix currently doesn't support parameter arrays // https://github.com/actix/actix-web/issues/2044 #[derive(Deserialize)] diff --git a/src/mastodon_api/accounts/views.rs b/src/mastodon_api/accounts/views.rs index e513d54..2dd46d4 100644 --- a/src/mastodon_api/accounts/views.rs +++ b/src/mastodon_api/accounts/views.rs @@ -63,6 +63,7 @@ use super::types::{ IdentityProofData, RelationshipQueryParams, StatusListQueryParams, + SubscriptionQueryParams, }; #[post("")] @@ -285,6 +286,7 @@ async fn authorize_subscription( auth: BearerAuth, config: web::Data, db_pool: web::Data, + query_params: web::Query, ) -> Result { let db_client = &**get_database_client(&db_pool).await?; let current_user = get_current_user(db_client, auth.token()).await?; @@ -297,6 +299,7 @@ async fn authorize_subscription( let signature = create_subscription_signature( blockchain_config, &wallet_address, + query_params.price, ).map_err(|_| HttpError::InternalError)?; Ok(HttpResponse::Ok().json(signature)) }