From d69bf74a88069e74e13801f0bf74e941c470da1c Mon Sep 17 00:00:00 2001 From: alexey Date: Mon, 28 Oct 2024 19:12:09 +0000 Subject: [PATCH 1/3] added airdrop script --- addresses | 1 + src/bin/airdrop.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 addresses create mode 100644 src/bin/airdrop.rs diff --git a/addresses b/addresses new file mode 100644 index 0000000..a179b8f --- /dev/null +++ b/addresses @@ -0,0 +1 @@ +0xc503C3126DF86b38133D813A440877A14f4fbb5D25219e0673b66248d9011c9d \ No newline at end of file diff --git a/src/bin/airdrop.rs b/src/bin/airdrop.rs new file mode 100644 index 0000000..72b1fae --- /dev/null +++ b/src/bin/airdrop.rs @@ -0,0 +1,81 @@ +use dotenv::dotenv; +use std::env; + +use fuels::{ + accounts::{provider::Provider, wallet::WalletUnlocked, Account}, + types::{bech32::Bech32Address, transaction::TxPolicies, Address}, +}; +use std::str::FromStr; + +use std::error::Error; + +const ASSET_ID: &str = "0x0000000000000000000000000000000000000000000000000000000000000000"; +const AMOUNT: u64 = 100; + +#[tokio::main] +async fn main() -> Result<(), Box> { + dotenv().ok(); + + // Environment variables + let mnemonic = env::var("MNEMONIC")?; + let provider = Provider::connect("testnet.fuel.network").await?; + + let main_wallet = + WalletUnlocked::new_from_mnemonic_phrase(&mnemonic, Some(provider.clone())).unwrap(); + + let addresses = read_addresses_from_file("addresses")?; + + println!( + "Starting airdrop of {} tokens to {} addresses", + AMOUNT, + addresses.len() + ); + + for address in addresses { + match main_wallet + .transfer( + &Bech32Address::from(Address::from_str(&address).unwrap()), + AMOUNT, + ASSET_ID.parse().unwrap(), + TxPolicies::default(), + ) + .await + { + Ok(_) => { + println!("Successfully sent {} tokens to {}", AMOUNT, address); + } + Err(e) => { + println!("Failed to send tokens to {}: {}", address, e); + } + } + } + + println!("Airdrop completed!"); + + Ok(()) +} + +//Файл должен содержать адреса Fuel кошельков, по одному адресу на строку. Пустые строки игнорируются. +pub fn read_addresses_from_file(file_path: &str) -> Result, std::io::Error> { + use std::fs::File; + use std::io::{BufRead, BufReader}; + + let file = File::open(file_path)?; + let reader = BufReader::new(file); + let addresses: Vec = reader + .lines() + .filter_map(|line| line.ok()) + .map(|line| line.trim().to_string()) + .filter(|line| !line.is_empty()) + .collect(); + + Ok(addresses) +} + +pub fn format_value_with_decimals(value: u64, decimals: u32) -> u64 { + value * 10u64.pow(decimals) +} + +pub fn format_to_readble_value(value: u64, decimals: u32) -> f64 { + value as f64 / 10u64.pow(decimals) as f64 +} From 4257887ce6242500cc731f0dbe324dd6f29f6fbc Mon Sep 17 00:00:00 2001 From: alexey Date: Wed, 30 Oct 2024 12:51:21 +0000 Subject: [PATCH 2/3] added fill_orderbook --- .DS_Store | Bin 0 -> 6148 bytes .idea/.gitignore | 5 + .idea/modules.xml | 8 ++ .idea/spark-rust-sdk-examples.iml | 12 +++ .idea/vcs.xml | 6 ++ addresses | 1 + src/bin/airdrop.rs | 13 ++- src/bin/fill_orderbook.rs | 152 ++++++++++++++++++++++++++++++ 8 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 .DS_Store create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/spark-rust-sdk-examples.iml create mode 100644 .idea/vcs.xml create mode 100644 src/bin/fill_orderbook.rs diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + + + + + \ No newline at end of file diff --git a/.idea/spark-rust-sdk-examples.iml b/.idea/spark-rust-sdk-examples.iml new file mode 100644 index 0000000..bbe0a70 --- /dev/null +++ b/.idea/spark-rust-sdk-examples.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/addresses b/addresses index a179b8f..3577307 100644 --- a/addresses +++ b/addresses @@ -1 +1,2 @@ +0xc503C3126DF86b38133D813A440877A14f4fbb5D25219e0673b66248d9011c9d 0xc503C3126DF86b38133D813A440877A14f4fbb5D25219e0673b66248d9011c9d \ No newline at end of file diff --git a/src/bin/airdrop.rs b/src/bin/airdrop.rs index 72b1fae..c1517a0 100644 --- a/src/bin/airdrop.rs +++ b/src/bin/airdrop.rs @@ -3,6 +3,7 @@ use std::env; use fuels::{ accounts::{provider::Provider, wallet::WalletUnlocked, Account}, + crypto::SecretKey, types::{bech32::Bech32Address, transaction::TxPolicies, Address}, }; use std::str::FromStr; @@ -10,19 +11,21 @@ use std::str::FromStr; use std::error::Error; const ASSET_ID: &str = "0x0000000000000000000000000000000000000000000000000000000000000000"; -const AMOUNT: u64 = 100; +const AMOUNT: u64 = 1; #[tokio::main] async fn main() -> Result<(), Box> { dotenv().ok(); // Environment variables - let mnemonic = env::var("MNEMONIC")?; + let private_key = env::var("PRIVATE_KEY")?; let provider = Provider::connect("testnet.fuel.network").await?; - let main_wallet = - WalletUnlocked::new_from_mnemonic_phrase(&mnemonic, Some(provider.clone())).unwrap(); - + let main_wallet = WalletUnlocked::new_from_private_key( + SecretKey::from_str(&private_key).unwrap(), + Some(provider.clone()), + ); + println!("Main wallet: {:?}", main_wallet.address()); let addresses = read_addresses_from_file("addresses")?; println!( diff --git a/src/bin/fill_orderbook.rs b/src/bin/fill_orderbook.rs new file mode 100644 index 0000000..863e8ae --- /dev/null +++ b/src/bin/fill_orderbook.rs @@ -0,0 +1,152 @@ +use dotenv::dotenv; +use std::env; + +use fuels::{ + accounts::{provider::Provider, wallet::WalletUnlocked, ViewOnlyAccount}, + crypto::SecretKey, + programs::calls::CallHandler, + types::{AssetId, ContractId, Identity}, +}; +use std::str::FromStr; +use rand::Rng; + +use spark_market_sdk::{OrderType, SparkMarketContract}; +use std::error::Error; + +pub fn format_value_with_decimals(value: u64, decimals: u32) -> u64 { + value * 10u64.pow(decimals) +} + +pub fn format_to_readble_value(value: u64, decimals: u32) -> f64 { + value as f64 / 10u64.pow(decimals) as f64 +} + +const START_PRICE: u64 = 5_000_000_000; +const MIN_PRICE_STEP: u64 = 10_000; +const MAX_PRICE_STEP: u64 = 10_000_000; +const MIN_AMOUNT: u64 = 10_000_000; +const MAX_AMOUNT: u64 = 1_000_000_000; +const ORDER_COUNT: u64 = 1000; +const MARKET_CONTRACT: &str = "0x12a5f8666279f841e5900500297ce3c8bcf40103dd191c56dd3ec86f92b9217b"; +const BASE_TOKEN: &str = "0x0b2d808a898cdae8b8661d398a98f8ff45e1e0f536ba2e498f6c7e53a71932cd"; +const QUOTE_TOKEN: &str = "0x368f9275e7d072794527b57d5b54688300008a400f41d926a013195e7074029c"; + +#[tokio::main] +async fn main() -> Result<(), Box> { + dotenv().ok(); + + // Environment variables + let pk = env::var("PRIVATE_KEY")?; + + // Connect to provider + let provider = Provider::connect("mainnet.fuel.network").await?; + + let main_wallet = WalletUnlocked::new_from_private_key( + SecretKey::from_str(&pk).unwrap(), + Some(provider.clone()), + ); + let contract_id = ContractId::from_str(MARKET_CONTRACT)?; + let market = SparkMarketContract::new(contract_id.clone(), main_wallet.clone()).await; + + // Fuel wallet address + let wallet_id: Identity = main_wallet.address().into(); + println!("wallet {:?}", main_wallet.address().to_string()); + + let base_id: AssetId = AssetId::from_str(BASE_TOKEN)?; + let quote_id: AssetId = AssetId::from_str(QUOTE_TOKEN)?; + + // Getting asset balances + let account = market.account(wallet_id).await.unwrap().value; + println!("account balance: {:?}", account); + // Get base token balance + let base_balance = main_wallet.get_asset_balance(&base_id).await.unwrap(); + if base_balance > 0 { + println!( + "Depositing {} BASE", + format_to_readble_value(base_balance, 9) + ); + match market.deposit(base_balance, base_id).await { + Ok(_) => { + println!("Base Deposit Success"); + Ok(()) + } + Err(e) => { + print!("Base Deposit error: {:?}", e); + Err(e) + } + } + .unwrap(); + } + + // Get quote token balance + let quote_balance = main_wallet.get_asset_balance("e_id).await.unwrap(); + if quote_balance > 0 { + println!( + "Depositing {} QUOTE", + format_to_readble_value(quote_balance, 9) + ); + match market.deposit(quote_balance, quote_id).await { + Ok(_) => { + println!("Quote Deposit Success"); + Ok(()) + } + Err(e) => { + print!("Quote Deposit error: {:?}", e); + Err(e) + } + } + .unwrap(); + } + + let mut rng = rand::thread_rng(); + + // Iterate through ORDER_COUNT steps from START_PRICE + for i in 0..ORDER_COUNT { + let mut multi_call_handler = CallHandler::new_multi_call(main_wallet.clone()); + + // Random price step and amounts for each iteration + let price_step = rng.gen_range(MIN_PRICE_STEP..=MAX_PRICE_STEP); + let base_amount = rng.gen_range(MIN_AMOUNT..=MAX_AMOUNT); + let quote_amount = rng.gen_range(MIN_AMOUNT..=MAX_AMOUNT); + + // Buy Order - decreasing price + let buy_price = START_PRICE - (i * price_step); + + let order_type: OrderType = OrderType::Buy; + println!( + "Opening Buy Order: {} BASE at {} BASE/QUOTE", + format_to_readble_value(base_amount, 9), + format_to_readble_value(buy_price, 9) + ); + + let buy_order_call = market + .open_order_call_handler(base_amount, order_type, buy_price) + .await; + multi_call_handler = multi_call_handler.add_call(buy_order_call); + + // Sell Order - increasing price + let sell_price = START_PRICE + (i * price_step); + + let order_type: OrderType = OrderType::Sell; + println!( + "Opening Sell Order: {} BASE at {} BASE/QUOTE", + format_to_readble_value(quote_amount, 9), + format_to_readble_value(sell_price, 9) + ); + + let sell_order_call = market + .open_order_call_handler(quote_amount, order_type, sell_price) + .await; + multi_call_handler = multi_call_handler.add_call(sell_order_call); + + match multi_call_handler.submit().await { + Ok(_) => println!("Multicall orders submitted successfully"), + Err(e) => println!("Multicall orders error: {:?}", e), + } + } + + let orders = market.user_orders(wallet_id).await?.value; + println!("orders {:?}", orders); + + Ok(()) +} From 88c2c662de5b9eda613c7ef8f2d6f490d57c0c29 Mon Sep 17 00:00:00 2001 From: alexey Date: Wed, 30 Oct 2024 12:52:57 +0000 Subject: [PATCH 3/3] added .DS_Store and .idea to gitignore --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 4 +++- .idea/.gitignore | 5 ----- .idea/modules.xml | 8 -------- .idea/spark-rust-sdk-examples.iml | 12 ------------ .idea/vcs.xml | 6 ------ 6 files changed, 3 insertions(+), 32 deletions(-) delete mode 100644 .DS_Store delete mode 100644 .idea/.gitignore delete mode 100644 .idea/modules.xml delete mode 100644 .idea/spark-rust-sdk-examples.iml delete mode 100644 .idea/vcs.xml diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 - - - - - - - \ No newline at end of file diff --git a/.idea/spark-rust-sdk-examples.iml b/.idea/spark-rust-sdk-examples.iml deleted file mode 100644 index bbe0a70..0000000 --- a/.idea/spark-rust-sdk-examples.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file