Add API method for generating invoices
This commit is contained in:
parent
084e0064be
commit
cd09fe0801
5 changed files with 131 additions and 4 deletions
|
@ -684,6 +684,34 @@ paths:
|
||||||
description: User's wallet address is not known or not verified
|
description: User's wallet address is not known or not verified
|
||||||
418:
|
418:
|
||||||
description: Blockchain integration is not enabled
|
description: Blockchain integration is not enabled
|
||||||
|
/api/v1/subscriptions/invoices:
|
||||||
|
post:
|
||||||
|
summary: Create invoice
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sender:
|
||||||
|
description: Sender actor address (webfinger account URI).
|
||||||
|
type: string
|
||||||
|
example: user@example.org
|
||||||
|
recipient:
|
||||||
|
description: Recipient ID.
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Invoice created.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Invoice'
|
||||||
|
404:
|
||||||
|
description: Sender or recipient not found.
|
||||||
|
418:
|
||||||
|
description: Blockchain integration is not enabled.
|
||||||
/api/v1/timelines/public:
|
/api/v1/timelines/public:
|
||||||
get:
|
get:
|
||||||
summary: View local public posts.
|
summary: View local public posts.
|
||||||
|
@ -924,6 +952,24 @@ components:
|
||||||
description: IPFS gateway URL.
|
description: IPFS gateway URL.
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
|
Invoice:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
description: Invoice ID.
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
sender_id:
|
||||||
|
description: The profile ID of the sender.
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
recipient_id:
|
||||||
|
description: The profile ID of the recipient.
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
payment_address:
|
||||||
|
description: Payment address.
|
||||||
|
type: string
|
||||||
Mention:
|
Mention:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|
|
@ -1,4 +1,32 @@
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::models::invoices::types::DbInvoice;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct InvoiceData {
|
||||||
|
pub sender: String, // acct
|
||||||
|
pub recipient: Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct Invoice {
|
||||||
|
pub id: Uuid,
|
||||||
|
pub sender_id: Uuid,
|
||||||
|
pub recipient_id: Uuid,
|
||||||
|
pub payment_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DbInvoice> for Invoice {
|
||||||
|
fn from(value: DbInvoice) -> Self {
|
||||||
|
Self {
|
||||||
|
id: value.id,
|
||||||
|
sender_id: value.sender_id,
|
||||||
|
recipient_id: value.recipient_id,
|
||||||
|
payment_address: value.payment_address,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct SubscriptionQueryParams {
|
pub struct SubscriptionQueryParams {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use actix_web::{web, HttpResponse, Scope};
|
use actix_web::{post, web, HttpResponse, Scope};
|
||||||
use actix_web_httpauth::extractors::bearer::BearerAuth;
|
use actix_web_httpauth::extractors::bearer::BearerAuth;
|
||||||
|
|
||||||
use crate::activitypub::builders::update_person::prepare_update_person;
|
use crate::activitypub::builders::update_person::prepare_update_person;
|
||||||
|
@ -12,15 +12,23 @@ use crate::ethereum::subscriptions::{
|
||||||
};
|
};
|
||||||
use crate::mastodon_api::accounts::types::Account;
|
use crate::mastodon_api::accounts::types::Account;
|
||||||
use crate::mastodon_api::oauth::auth::get_current_user;
|
use crate::mastodon_api::oauth::auth::get_current_user;
|
||||||
use crate::models::profiles::queries::update_profile;
|
use crate::models::invoices::queries::create_invoice;
|
||||||
|
use crate::models::profiles::queries::{
|
||||||
|
get_profile_by_acct,
|
||||||
|
update_profile,
|
||||||
|
};
|
||||||
use crate::models::profiles::types::{
|
use crate::models::profiles::types::{
|
||||||
MoneroSubscription,
|
MoneroSubscription,
|
||||||
PaymentOption,
|
PaymentOption,
|
||||||
PaymentType,
|
PaymentType,
|
||||||
ProfileUpdateData,
|
ProfileUpdateData,
|
||||||
};
|
};
|
||||||
|
use crate::models::users::queries::get_user_by_id;
|
||||||
|
use crate::monero::wallet::create_monero_address;
|
||||||
use crate::utils::currencies::Currency;
|
use crate::utils::currencies::Currency;
|
||||||
use super::types::{
|
use super::types::{
|
||||||
|
Invoice,
|
||||||
|
InvoiceData,
|
||||||
SubscriptionQueryParams,
|
SubscriptionQueryParams,
|
||||||
SubscriptionSettings,
|
SubscriptionSettings,
|
||||||
};
|
};
|
||||||
|
@ -123,8 +131,36 @@ pub async fn subscriptions_enabled(
|
||||||
Ok(HttpResponse::Ok().json(account))
|
Ok(HttpResponse::Ok().json(account))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/invoices")]
|
||||||
|
async fn create_invoice_view(
|
||||||
|
config: web::Data<Config>,
|
||||||
|
db_pool: web::Data<Pool>,
|
||||||
|
invoice_data: web::Json<InvoiceData>,
|
||||||
|
) -> Result<HttpResponse, HttpError> {
|
||||||
|
let monero_config = config.blockchain()
|
||||||
|
.ok_or(HttpError::NotSupported)?
|
||||||
|
.monero_config()
|
||||||
|
.ok_or(HttpError::NotSupported)?;
|
||||||
|
let db_client = &**get_database_client(&db_pool).await?;
|
||||||
|
let sender = get_profile_by_acct(db_client, &invoice_data.sender).await?;
|
||||||
|
let recipient = get_user_by_id(db_client, &invoice_data.recipient).await?;
|
||||||
|
let payment_address = create_monero_address(monero_config).await
|
||||||
|
.map_err(|_| HttpError::InternalError)?
|
||||||
|
.to_string();
|
||||||
|
let db_invoice = create_invoice(
|
||||||
|
db_client,
|
||||||
|
&sender.id,
|
||||||
|
&recipient.id,
|
||||||
|
&monero_config.chain_id,
|
||||||
|
&payment_address,
|
||||||
|
).await?;
|
||||||
|
let invoice = Invoice::from(db_invoice);
|
||||||
|
Ok(HttpResponse::Ok().json(invoice))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn subscription_api_scope() -> Scope {
|
pub fn subscription_api_scope() -> Scope {
|
||||||
web::scope("/api/v1/subscriptions")
|
web::scope("/api/v1/subscriptions")
|
||||||
.route("/authorize", web::get().to(authorize_subscription))
|
.route("/authorize", web::get().to(authorize_subscription))
|
||||||
.route("/enable", web::post().to(subscriptions_enabled))
|
.route("/enable", web::post().to(subscriptions_enabled))
|
||||||
|
.service(create_invoice_view)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
pub mod queries;
|
pub mod queries;
|
||||||
mod types;
|
pub mod types;
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
use monero_rpc::RpcClient;
|
use monero_rpc::RpcClient;
|
||||||
|
use monero_rpc::monero::Address;
|
||||||
|
|
||||||
use crate::config::MoneroConfig;
|
use crate::config::MoneroConfig;
|
||||||
|
|
||||||
|
const DEFAULT_ACCOUNT: u32 = 0;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum MoneroError {
|
pub enum MoneroError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -19,3 +22,17 @@ pub async fn create_monero_wallet(
|
||||||
wallet_client.create_wallet(name, password, language).await?;
|
wallet_client.create_wallet(name, password, language).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn create_monero_address(
|
||||||
|
config: &MoneroConfig,
|
||||||
|
) -> Result<Address, MoneroError> {
|
||||||
|
let wallet_client = RpcClient::new(config.wallet_url.clone()).wallet();
|
||||||
|
wallet_client.open_wallet(
|
||||||
|
config.wallet_name.clone(),
|
||||||
|
config.wallet_password.clone(),
|
||||||
|
).await?;
|
||||||
|
let (address, address_index) =
|
||||||
|
wallet_client.create_address(DEFAULT_ACCOUNT, None).await?;
|
||||||
|
log::info!("created monero address {}/{}", DEFAULT_ACCOUNT, address_index);
|
||||||
|
Ok(address)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue