diff --git a/web3_proxy/src/bin/web3_proxy_cli.rs b/web3_proxy/src/bin/web3_proxy_cli.rs index 775c2175..15d7fb81 100644 --- a/web3_proxy/src/bin/web3_proxy_cli.rs +++ b/web3_proxy/src/bin/web3_proxy_cli.rs @@ -68,6 +68,7 @@ enum SubCommand { CreateKey(sub_commands::CreateKeySubCommand), CreateUser(sub_commands::CreateUserSubCommand), DropMigrationLock(sub_commands::DropMigrationLockSubCommand), + GrantCreditsToAddress(sub_commands::GrantCreditsToAddress), MassGrantCredits(sub_commands::MassGrantCredits), MigrateStatsToV2(sub_commands::MigrateStatsToV2SubCommand), Pagerduty(sub_commands::PagerdutySubCommand), @@ -81,7 +82,6 @@ enum SubCommand { UserImport(sub_commands::UserImportSubCommand), // TODO: sub command to downgrade migrations? sea-orm has this but doing downgrades here would be easier+safer // TODO: sub command to add new api keys to an existing user? - // TODO: sub command to change a user's tier } fn main() -> anyhow::Result<()> { @@ -376,6 +376,15 @@ fn main() -> anyhow::Result<()> { x.main(&db_conn).await } + SubCommand::GrantCreditsToAddress(x) => { + let db_url = cli_config + .db_url + .expect("'--config' (with a db) or '--db-url' is required to run create_user"); + + let db_conn = get_migrated_db(db_url, 1, 1).await?; + + x.main(&db_conn).await + } SubCommand::Proxyd(x) => { let top_config = top_config.expect("--config is required to run proxyd"); let top_config_path = diff --git a/web3_proxy/src/sub_commands/grant_credits_to_address.rs b/web3_proxy/src/sub_commands/grant_credits_to_address.rs new file mode 100644 index 00000000..89ad1228 --- /dev/null +++ b/web3_proxy/src/sub_commands/grant_credits_to_address.rs @@ -0,0 +1,79 @@ +// TODO: a lot of this is copy/paste of the admin frontend endpoint for granting credits. +// that's easier than refactoring right now. +// it could be cleaned up, but this is a script that runs once so isn't worth spending tons of time on. + +use crate::balance::Balance; +use anyhow::Context; +use argh::FromArgs; +use entities::{admin_increase_balance_receipt, user, user_tier}; +use ethers::types::Address; +use migration::sea_orm::{ + self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, + QueryFilter, TransactionTrait, +}; +use rust_decimal::Decimal; +use serde_json::json; +use tracing::info; + +#[derive(FromArgs, PartialEq, Debug)] +/// Grant credits to all the users in a tier (and change their tier to premium). +#[argh(subcommand, name = "grant_credits_to_address")] +pub struct GrantCreditsToAddress { + #[argh(positional)] + /// the address of the user tier whose users will be upgraded to premium + user_address: Address, + + #[argh(positional)] + /// how many credits to give. "0" to just see their balance + credits: Decimal, +} + +impl GrantCreditsToAddress { + pub async fn main(self, db_conn: &DatabaseConnection) -> anyhow::Result<()> { + let premium_user_tier = user_tier::Entity::find() + .filter(user_tier::Column::Title.like("Premium")) + .one(db_conn) + .await? + .context("no Premium user tier found")?; + + let user = user::Entity::find() + .filter(user::Column::Address.eq(self.user_address.as_bytes())) + .one(db_conn) + .await? + .context("no user")?; + + let user_id = user.id; + + let txn = db_conn.begin().await?; + + if self.credits > 0.into() { + let increase_balance_receipt = admin_increase_balance_receipt::ActiveModel { + amount: sea_orm::Set(self.credits), + // TODO: allow customizing the admin id + admin_id: sea_orm::Set(1), + deposit_to_user_id: sea_orm::Set(user_id), + note: sea_orm::Set("grant credits to address".into()), + ..Default::default() + }; + increase_balance_receipt.save(&txn).await?; + } + + let mut user = user.into_active_model(); + + user.user_tier_id = sea_orm::Set(premium_user_tier.id); + + if user.is_changed() { + user.save(&txn).await?; + } + + txn.commit().await?; + + let balance = Balance::try_from_db(db_conn, user_id) + .await? + .context("no balance")?; + + info!("{:?} balance: {:#}", self.user_address, json!(balance)); + + Ok(()) + } +} diff --git a/web3_proxy/src/sub_commands/mod.rs b/web3_proxy/src/sub_commands/mod.rs index e5c2b3bc..3e8489a8 100644 --- a/web3_proxy/src/sub_commands/mod.rs +++ b/web3_proxy/src/sub_commands/mod.rs @@ -8,6 +8,7 @@ mod count_users; mod create_key; mod create_user; mod drop_migration_lock; +mod grant_credits_to_address; mod mass_grant_credits; mod migrate_stats_to_v2; mod pagerduty; @@ -30,6 +31,7 @@ pub use self::count_users::CountUsersSubCommand; pub use self::create_key::CreateKeySubCommand; pub use self::create_user::CreateUserSubCommand; pub use self::drop_migration_lock::DropMigrationLockSubCommand; +pub use self::grant_credits_to_address::GrantCreditsToAddress; pub use self::mass_grant_credits::MassGrantCredits; pub use self::migrate_stats_to_v2::MigrateStatsToV2SubCommand; pub use self::pagerduty::PagerdutySubCommand;