From a1ab21a7024817085da54cee39031d030793a97c Mon Sep 17 00:00:00 2001 From: silverpill Date: Sun, 18 Sep 2022 00:23:20 +0000 Subject: [PATCH] Store requested payment amount for each invoice --- docs/openapi.yaml | 8 ++++++++ migrations/V0033__invoice__add_amount.sql | 2 ++ migrations/schema.sql | 1 + src/mastodon_api/subscriptions/types.rs | 3 +++ src/mastodon_api/subscriptions/views.rs | 4 ++++ src/models/invoices/queries.rs | 10 ++++++++-- src/models/invoices/types.rs | 1 + 7 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 migrations/V0033__invoice__add_amount.sql diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 62f3bcb..c8b7eec 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -761,6 +761,10 @@ paths: description: Recipient ID. type: string format: uuid + amount: + description: Requested payment amount (in atomic units). + type: integer + example: 100000000 responses: 200: description: Invoice created. @@ -1082,6 +1086,10 @@ components: payment_address: description: Payment address. type: string + amount: + description: Requested payment amount (in atomic units). + type: integer + example: 100000000 status: description: Invoice status. type: string diff --git a/migrations/V0033__invoice__add_amount.sql b/migrations/V0033__invoice__add_amount.sql new file mode 100644 index 0000000..1fd9cfc --- /dev/null +++ b/migrations/V0033__invoice__add_amount.sql @@ -0,0 +1,2 @@ +ALTER TABLE invoice ADD COLUMN amount BIGINT NOT NULL DEFAULT 0 CHECK (amount >= 0); +ALTER TABLE invoice ALTER COLUMN amount DROP DEFAULT; diff --git a/migrations/schema.sql b/migrations/schema.sql index 2eb7901..648f63a 100644 --- a/migrations/schema.sql +++ b/migrations/schema.sql @@ -143,6 +143,7 @@ CREATE TABLE invoice ( recipient_id UUID NOT NULL REFERENCES user_account (id) ON DELETE CASCADE, chain_id VARCHAR(50) NOT NULL, payment_address VARCHAR(200) NOT NULL, + amount BIGINT NOT NULL CHECK (amount >= 0), invoice_status SMALLINT NOT NULL DEFAULT 1, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE (chain_id, payment_address) diff --git a/src/mastodon_api/subscriptions/types.rs b/src/mastodon_api/subscriptions/types.rs index 5adf523..c10a0f3 100644 --- a/src/mastodon_api/subscriptions/types.rs +++ b/src/mastodon_api/subscriptions/types.rs @@ -9,6 +9,7 @@ use crate::models::profiles::types::PaymentOption; pub struct InvoiceData { pub sender_id: Uuid, pub recipient_id: Uuid, + pub amount: i64, } #[derive(Serialize)] @@ -17,6 +18,7 @@ pub struct Invoice { pub sender_id: Uuid, pub recipient_id: Uuid, pub payment_address: String, + pub amount: i64, pub status: String, } @@ -33,6 +35,7 @@ impl From for Invoice { sender_id: value.sender_id, recipient_id: value.recipient_id, payment_address: value.payment_address, + amount: value.amount, status: status.to_string(), } } diff --git a/src/mastodon_api/subscriptions/views.rs b/src/mastodon_api/subscriptions/views.rs index 87e9204..99b4329 100644 --- a/src/mastodon_api/subscriptions/views.rs +++ b/src/mastodon_api/subscriptions/views.rs @@ -178,6 +178,9 @@ async fn create_invoice_view( if invoice_data.sender_id == invoice_data.recipient_id { return Err(ValidationError("sender must be different from recipient").into()); }; + if invoice_data.amount <= 0 { + return Err(ValidationError("amount must be positive").into()); + }; let db_client = &**get_database_client(&db_pool).await?; let sender = get_profile_by_id(db_client, &invoice_data.sender_id).await?; let recipient = get_user_by_id(db_client, &invoice_data.recipient_id).await?; @@ -190,6 +193,7 @@ async fn create_invoice_view( &recipient.id, &monero_config.chain_id, &payment_address, + invoice_data.amount, ).await?; let invoice = Invoice::from(db_invoice); Ok(HttpResponse::Ok().json(invoice)) diff --git a/src/models/invoices/queries.rs b/src/models/invoices/queries.rs index 1ccee08..e793b98 100644 --- a/src/models/invoices/queries.rs +++ b/src/models/invoices/queries.rs @@ -13,6 +13,7 @@ pub async fn create_invoice( recipient_id: &Uuid, chain_id: &ChainId, payment_address: &str, + amount: i64, ) -> Result { let invoice_id = new_uuid(); let row = db_client.query_one( @@ -22,9 +23,10 @@ pub async fn create_invoice( sender_id, recipient_id, chain_id, - payment_address + payment_address, + amount ) - VALUES ($1, $2, $3, $4, $5) + VALUES ($1, $2, $3, $4, $5, $6) RETURNING invoice ", &[ @@ -33,6 +35,7 @@ pub async fn create_invoice( &recipient_id, &chain_id, &payment_address, + &amount, ], ).await.map_err(catch_unique_violation("invoice"))?; let invoice = row.try_get("invoice")?; @@ -139,17 +142,20 @@ mod tests { reference: "mainnet".to_string(), }; let payment_address = "8MxABajuo71BZya9"; + let amount = 100000000000109212; let invoice = create_invoice( db_client, &sender.id, &recipient.id, &chain_id, payment_address, + amount, ).await.unwrap(); assert_eq!(invoice.sender_id, sender.id); assert_eq!(invoice.recipient_id, recipient.id); assert_eq!(invoice.chain_id, chain_id); assert_eq!(invoice.payment_address, payment_address); + assert_eq!(invoice.amount, amount); assert!(matches!(invoice.invoice_status, InvoiceStatus::Open)); } } diff --git a/src/models/invoices/types.rs b/src/models/invoices/types.rs index b6b6f39..7029ae0 100644 --- a/src/models/invoices/types.rs +++ b/src/models/invoices/types.rs @@ -53,6 +53,7 @@ pub struct DbInvoice { pub recipient_id: Uuid, pub chain_id: ChainId, pub payment_address: String, + pub amount: i64, // requested payment amount pub invoice_status: InvoiceStatus, pub created_at: DateTime, }