Skip to content
Snippets Groups Projects
Select Git revision
  • c8d178fd8981995f7077dfc910d00a00367e757f
  • master default protected
  • feat/1/increase-antispam-limits
  • duniter-v2s-issue-123-industrialize-releases
  • fix/1/test-cgeek
  • fix/1/add_get_transactions_for_bma
6 results

wallets.rs

Blame
  • wallets.rs 7.54 KiB
    //  Copyright (C) 2020 Éloïs SANCHEZ.
    //
    // This program is free software: you can redistribute it and/or modify
    // it under the terms of the GNU Affero General Public License as
    // published by the Free Software Foundation, either version 3 of the
    // License, or (at your option) any later version.
    //
    // This program is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    // GNU Affero General Public License for more details.
    //
    // You should have received a copy of the GNU Affero General Public License
    // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    
    use crate::*;
    use async_graphql::connection::*;
    use duniter_gva_dbs_reader::{
        wallets::{WalletSingleSigWithIdtyOpt, WalletWithIdtyOpt},
        PagedData,
    };
    
    #[derive(Default)]
    pub(crate) struct WalletsQuery;
    #[async_graphql::Object]
    impl WalletsQuery {
        /// Universal dividends issued by a public key
        #[allow(clippy::clippy::too_many_arguments)]
        async fn wallets(
            &self,
            ctx: &async_graphql::Context<'_>,
            #[graphql(desc = "minimal balance")] min_balance: Option<i64>,
            #[graphql(desc = "pagination", default)] pagination: Pagination,
            #[graphql(desc = "Wallet type filter", default)] wallet_type_filter: WalletTypeFilter,
        ) -> async_graphql::Result<Connection<String, Wallet, AggregateSum, EmptyFields>> {
            let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?;
    
            let data = ctx.data::<GvaSchemaData>()?;
            let dbs_reader = data.dbs_reader();
    
            let current_base =
                if let Some(current_ud) = data.cm_accessor.get_current_meta(|cm| cm.current_ud).await {
                    current_ud.base()
                } else {
                    0
                };
            let min_balance_opt = min_balance.map(|amount| SourceAmount::new(amount, current_base));
    
            let PagedData {
                data,
                has_next_page,
                has_previous_page,
            }: PagedData<Vec<Wallet>> = match wallet_type_filter {
                WalletTypeFilter::OnlyComplex => {
                    let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;
                    data.dbs_pool
                        .execute(move |_| dbs_reader.wallets(true, min_balance_opt, pagination))
                        .await??
                        .map(|data| {
                            data.into_iter()
                                .map(|script_with_sa| Wallet {
                                    script: script_with_sa.0.to_string(),
                                    balance: AmountWithBase::from(script_with_sa.1),
                                    idty: None,
                                })
                                .collect()
                        })
                }
                WalletTypeFilter::OnlySimple => {
                    let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;
                    if ctx
                        .look_ahead()
                        .field("edges")
                        .field("node")
                        .field("idty")
                        .exists()
                    {
                        data.dbs_pool
                            .execute(move |shared_dbs| {
                                dbs_reader.wallets_single_sig_with_idty_opt(
                                    &shared_dbs.bc_db_ro,
                                    min_balance_opt,
                                    pagination,
                                )
                            })
                            .await??
                            .map(|data| {
                                data.into_iter()
                                    .map(|WalletSingleSigWithIdtyOpt(pk_with_sa, idty_opt)| Wallet {
                                        script: pk_with_sa.0.to_string(),
                                        balance: AmountWithBase::from(pk_with_sa.1),
                                        idty: idty_opt.map(|idty_db| Identity {
                                            is_member: idty_db.is_member,
                                            username: idty_db.username,
                                        }),
                                    })
                                    .collect()
                            })
                    } else {
                        data.dbs_pool
                            .execute(move |_| {
                                dbs_reader.wallets_single_sig(min_balance_opt, pagination)
                            })
                            .await??
                            .map(|data| {
                                data.into_iter()
                                    .map(|pk_with_sa| Wallet {
                                        script: pk_with_sa.0.to_string(),
                                        balance: AmountWithBase::from(pk_with_sa.1),
                                        idty: None,
                                    })
                                    .collect()
                            })
                    }
                }
                WalletTypeFilter::All => {
                    let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;
                    if ctx
                        .look_ahead()
                        .field("edges")
                        .field("node")
                        .field("idty")
                        .exists()
                    {
                        data.dbs_pool
                            .execute(move |shared_dbs| {
                                dbs_reader.wallets_with_idty_opt(
                                    &shared_dbs.bc_db_ro,
                                    min_balance_opt,
                                    pagination,
                                )
                            })
                            .await??
                            .map(|data| {
                                data.into_iter()
                                    .map(|WalletWithIdtyOpt(script_with_sa, idty_opt)| Wallet {
                                        script: script_with_sa.0.to_string(),
                                        balance: AmountWithBase::from(script_with_sa.1),
                                        idty: idty_opt.map(|idty_db| Identity {
                                            is_member: idty_db.is_member,
                                            username: idty_db.username,
                                        }),
                                    })
                                    .collect()
                            })
                    } else {
                        data.dbs_pool
                            .execute(move |_| dbs_reader.wallets(false, min_balance_opt, pagination))
                            .await??
                            .map(|data| {
                                data.into_iter()
                                    .map(|script_with_sa| Wallet {
                                        script: script_with_sa.0.to_string(),
                                        balance: AmountWithBase::from(script_with_sa.1),
                                        idty: None,
                                    })
                                    .collect()
                            })
                    }
                }
            };
    
            let sum = if ctx.look_ahead().field("aggregate").field("sum").exists() {
                data.iter().map(|wallet| wallet.balance).sum()
            } else {
                AmountWithBase::default()
            };
    
            let mut conn = Connection::with_additional_fields(
                has_previous_page,
                has_next_page,
                AggregateSum {
                    aggregate: Sum { sum },
                },
            );
    
            conn.append(
                data.into_iter()
                    .map(|wallet| Edge::new(wallet.script.clone(), wallet)),
            );
    
            Ok(conn)
        }
    }