Skip to content

Commit

Permalink
Merge pull request #1 from MutinyWallet/federated-addresses
Browse files Browse the repository at this point in the history
Federated Addresses
  • Loading branch information
TonyGiorgio authored Feb 22, 2024
2 parents b5ab778 + 356f77a commit bd57b9d
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 20 deletions.
24 changes: 24 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1.12.0", features = ["full"] }
tower-http = { version = "0.4.0", features = ["cors"] }
async-trait = "0.1.59"
lazy-regex = "3.1.0"

[dev-dependencies]
mockall = "0.11.2"
Expand Down
3 changes: 1 addition & 2 deletions migrations/2024-02-20-210617_user_info/up.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
CREATE TABLE app_user (
id SERIAL PRIMARY KEY,
pubkey VARCHAR(64) NOT NULL,
name VARCHAR(20) NOT NULL,
dm_type VARCHAR(5) NOT NULL,
name VARCHAR(255) NOT NULL UNIQUE,
federation_id VARCHAR(64) NOT NULL,
federation_invite_code VARCHAR(255) NOT NULL
);
Expand Down
18 changes: 12 additions & 6 deletions src/db.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
use diesel::{pg::PgConnection, r2d2::ConnectionManager, r2d2::Pool, Connection};
use diesel::{pg::PgConnection, r2d2::ConnectionManager, r2d2::Pool};
use std::sync::Arc;

#[cfg(test)]
use mockall::{automock, predicate::*};

use crate::models::app_user::{AppUser, NewAppUser};

#[cfg_attr(test, automock)]
pub(crate) trait DBConnection {
// fn get_services(&self) -> anyhow::Result<Vec<Service>>;
fn check_name_available(&self, name: String) -> anyhow::Result<bool>;
fn insert_new_user(&self, name: NewAppUser) -> anyhow::Result<AppUser>;
}

pub(crate) struct PostgresConnection {
db: Pool<ConnectionManager<PgConnection>>,
}

impl DBConnection for PostgresConnection {
/*
fn get_services(&self) -> anyhow::Result<Vec<Service>> {
fn check_name_available(&self, name: String) -> anyhow::Result<bool> {
let conn = &mut self.db.get()?;
AppUser::check_available_name(conn, name)
}

fn insert_new_user(&self, new_user: NewAppUser) -> anyhow::Result<AppUser> {
let conn = &mut self.db.get()?;
Service::get_services(conn)
new_user.insert(conn)
}
*/
}

pub(crate) fn setup_db(url: String) -> Arc<dyn DBConnection + Send + Sync> {
Expand Down
10 changes: 6 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
use axum::extract::DefaultBodyLimit;
use axum::headers::Origin;
use axum::http::{request::Parts, HeaderValue, Method, StatusCode, Uri};
use axum::routing::{get, post};
use axum::routing::get;
use axum::{http, Extension, Router, TypedHeader};
use log::{error, info};
use secp256k1::{All, PublicKey, Secp256k1};
use std::collections::HashMap;
use secp256k1::{All, Secp256k1};
use std::sync::Arc;
use tokio::signal::unix::{signal, SignalKind};
use tokio::sync::oneshot;
use tower_http::cors::{AllowOrigin, CorsLayer};

use crate::{
db::{setup_db, DBConnection},
routes::{health_check, valid_origin, validate_cors},
routes::{check_username, health_check, valid_origin, validate_cors},
};

mod db;
mod models;
mod register;
mod routes;

const ALLOWED_ORIGINS: [&str; 6] = [
Expand Down Expand Up @@ -81,6 +82,7 @@ async fn main() -> anyhow::Result<()> {

let server_router = Router::new()
.route("/health-check", get(health_check))
.route("/check-username/:username", get(check_username))
.fallback(fallback)
.layer(
CorsLayer::new()
Expand Down
72 changes: 72 additions & 0 deletions src/models/app_user.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use crate::models::schema::app_user;
use diesel::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(
QueryableByName, Queryable, AsChangeset, Serialize, Deserialize, Debug, Clone, PartialEq,
)]
#[diesel(check_for_backend(diesel::pg::Pg))]
#[diesel(table_name = app_user)]
pub struct AppUser {
pub id: i32,
pub pubkey: String,
pub name: String,
pub federation_id: String,
pub federation_invite_code: String,
}

impl AppUser {
pub fn get_app_users(conn: &mut PgConnection) -> anyhow::Result<Vec<AppUser>> {
Ok(app_user::table.load::<Self>(conn)?)
}

pub fn get_by_id(conn: &mut PgConnection, user_id: i32) -> anyhow::Result<Option<AppUser>> {
Ok(app_user::table
.filter(app_user::id.eq(user_id))
.first::<AppUser>(conn)
.optional()?)
}

pub fn get_by_name(conn: &mut PgConnection, name: String) -> anyhow::Result<Option<AppUser>> {
Ok(app_user::table
.filter(app_user::name.eq(name))
.first::<AppUser>(conn)
.optional()?)
}

pub fn check_available_name(conn: &mut PgConnection, name: String) -> anyhow::Result<bool> {
Ok(app_user::table
.filter(app_user::name.eq(name))
.count()
.get_result::<i64>(conn)?
== 0)
}

pub fn get_by_pubkey(
conn: &mut PgConnection,
pubkey: String,
) -> anyhow::Result<Option<AppUser>> {
Ok(app_user::table
.filter(app_user::pubkey.eq(pubkey))
.first::<AppUser>(conn)
.optional()?)
}
}

#[derive(Insertable)]
#[diesel(table_name = app_user)]
pub struct NewAppUser {
pub pubkey: String,
pub name: String,
pub federation_id: String,
pub federation_invite_code: String,
}

impl NewAppUser {
pub fn insert(&self, conn: &mut PgConnection) -> anyhow::Result<AppUser> {
diesel::insert_into(app_user::table)
.values(self)
.get_result::<AppUser>(conn)
.map_err(|e| e.into())
}
}
64 changes: 64 additions & 0 deletions src/models/invoice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::models::schema::invoice;
use diesel::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(
QueryableByName,
Queryable,
Insertable,
AsChangeset,
Serialize,
Deserialize,
Debug,
Clone,
PartialEq,
)]
#[diesel(check_for_backend(diesel::pg::Pg))]
#[diesel(table_name = invoice)]
pub struct Invoice {
pub id: i32,
pub federation_id: String,
pub op_id: String,
pub app_user_id: i32,
pub bolt11: String,
pub amount: i64,
pub state: i32,
}

impl Invoice {
pub fn insert(&self, conn: &mut PgConnection) -> anyhow::Result<()> {
diesel::insert_into(invoice::table)
.values(self)
.execute(conn)?;

Ok(())
}

pub fn get_invoices(conn: &mut PgConnection) -> anyhow::Result<Vec<Invoice>> {
Ok(invoice::table.load::<Self>(conn)?)
}

pub fn get_by_id(conn: &mut PgConnection, user_id: i32) -> anyhow::Result<Option<Invoice>> {
Ok(invoice::table
.filter(invoice::id.eq(user_id))
.first::<Invoice>(conn)
.optional()?)
}

pub fn get_by_operation(
conn: &mut PgConnection,
op_id: String,
) -> anyhow::Result<Option<Invoice>> {
Ok(invoice::table
.filter(invoice::op_id.eq(op_id))
.first::<Invoice>(conn)
.optional()?)
}

pub fn get_by_state(conn: &mut PgConnection, state: i32) -> anyhow::Result<Option<Invoice>> {
Ok(invoice::table
.filter(invoice::state.eq(state))
.first::<Invoice>(conn)
.optional()?)
}
}
4 changes: 4 additions & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod app_user;
pub mod invoice;
mod schema;
pub mod zaps;
4 changes: 1 addition & 3 deletions src/models/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ diesel::table! {
id -> Int4,
#[max_length = 64]
pubkey -> Varchar,
#[max_length = 20]
#[max_length = 255]
name -> Varchar,
#[max_length = 5]
dm_type -> Varchar,
#[max_length = 64]
federation_id -> Varchar,
#[max_length = 255]
Expand Down
52 changes: 52 additions & 0 deletions src/models/zaps.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::models::schema::zaps;
use diesel::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(
QueryableByName,
Queryable,
Insertable,
AsChangeset,
Serialize,
Deserialize,
Debug,
Clone,
PartialEq,
)]
#[diesel(check_for_backend(diesel::pg::Pg))]
#[diesel(table_name = zaps)]
pub struct Zap {
pub id: i32,
pub request: String,
pub event_id: Option<String>,
}

impl Zap {
pub fn insert(&self, conn: &mut PgConnection) -> anyhow::Result<()> {
diesel::insert_into(zaps::table)
.values(self)
.execute(conn)?;

Ok(())
}

pub fn get_zaps(conn: &mut PgConnection) -> anyhow::Result<Vec<Zap>> {
Ok(zaps::table.load::<Self>(conn)?)
}

pub fn get_by_id(conn: &mut PgConnection, zap_id: i32) -> anyhow::Result<Option<Zap>> {
Ok(zaps::table
.filter(zaps::id.eq(zap_id))
.first::<Zap>(conn)
.optional()?)
}

pub fn set_event_id(&self, conn: &mut PgConnection, event_id: String) -> anyhow::Result<()> {
diesel::update(zaps::table)
.filter(zaps::id.eq(self.id))
.set(zaps::event_id.eq(event_id))
.execute(conn)?;

Ok(())
}
}
Loading

0 comments on commit bd57b9d

Please sign in to comment.