private static async Task CreateIndexesAsync(string settingsUrl) { if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _)) { Console.WriteLine($"{SettingsUrl} should be a valid uri"); return; } var logFactory = LogFactory.Create() .AddConsole(); var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, p => { }).Nested(x => x.BlockchainWalletsService.Db.DataConnString); var defaultWalletsRepository = (WalletRepository)WalletRepository.Create(settings, logFactory); string continuationToken = null; Console.WriteLine("Creating Indexes..."); var progressCounter = 0; do { try { IEnumerable <WalletDto> wallets; (wallets, continuationToken) = await defaultWalletsRepository.GetAllAsync(100, continuationToken); foreach (var defaultWallet in wallets) { await defaultWalletsRepository.AddAsync ( defaultWallet.BlockchainType, defaultWallet.AssetId, defaultWallet.ClientId, defaultWallet.Address ); Console.SetCursorPosition(0, Console.CursorTop); Console.Write($"{++progressCounter} indexes created"); } } catch (Exception e) { Console.WriteLine(e.StackTrace + " " + e.Message); } } while (continuationToken != null); if (progressCounter == 0) { Console.WriteLine("Nothing to create"); } else { Console.WriteLine(); Console.WriteLine($"Added indexes to {progressCounter} wallets"); } }
private static async Task ConvertAddresses(string settingsUrl) { if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _)) { Console.WriteLine($"{SettingsUrl} should be a valid uri"); return; } var logFactory = LogFactory.Create() .AddConsole(); var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, p => {}).Nested(p => p.LiteCoinAPI); var oldStorage = AzureTableStorage <ObservableWalletEntity> .Create(settings.Nested(p => p.Db.DataConnString), "ObservableWallets", logFactory); var newStorage = AzureTableStorage <ObservableWalletEntity> .Create(settings.Nested(p => p.Db.DataConnString), "ObservableWalletsRef", logFactory); string continuationToken = null; var progressCounter = 0; Console.WriteLine("Converting wallets..."); var batchSize = 10; do { var rangeQuery = new TableQuery <ObservableWalletEntity> { TakeCount = batchSize }; var queryResult = await oldStorage.GetDataWithContinuationTokenAsync(rangeQuery, continuationToken); if (queryResult.Entities.Any()) { var entitiesToInsert = queryResult.Entities.Select(ObservableWalletEntity.Create).ToList(); foreach (var observableWalletEntity in entitiesToInsert) { await newStorage.InsertOrReplaceAsync(observableWalletEntity); } progressCounter += entitiesToInsert.Count; continuationToken = queryResult.ContinuationToken; } else { continuationToken = null; } Console.SetCursorPosition(0, Console.CursorTop); Console.Write($"{progressCounter} wallets converted"); } while (continuationToken != null); }
private static async Task ConvertAddressesAsync(string settingsUrl, string integrationId, string assetId) { if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _)) { Console.WriteLine($"{SettingsUrl} should be a valid uri"); return; } var logFactory = LogFactory.Create() .AddConsole(); var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, p => { }).Nested(x => x.BlockchainWalletsService.Db.DataConnString); var defaultWalletsRepository = (WalletRepository)WalletRepository.Create(settings, logFactory); string continuationToken = null; Console.WriteLine("Converting wallets..."); var progressCounter = 0; do { IEnumerable <WalletDto> defaultWallets; (defaultWallets, continuationToken) = await defaultWalletsRepository.GetAsync(integrationId, assetId, 100, continuationToken); foreach (var defaultWallet in defaultWallets) { await defaultWalletsRepository.DeleteIfExistsAsync ( defaultWallet.BlockchainType, defaultWallet.AssetId, defaultWallet.ClientId ); Console.SetCursorPosition(0, Console.CursorTop); Console.Write($"{++progressCounter} wallets converted"); } } while (continuationToken != null); if (progressCounter == 0) { Console.WriteLine("Nothing to convert"); } else { Console.WriteLine(); Console.WriteLine("Conversion completed"); } }
private static void Run( Options options) { var settings = new SettingsServiceReloadingManager <AppSettings> ( options.NeoGasDistributorSettingsUrl, opt => { } ); var containerBuilder = new ContainerBuilder(); var diModule = new DIModule(options.BalanceLogsFolderPath, settings); containerBuilder.RegisterModule(diModule); using (var container = containerBuilder.Build()) { var balanceImporter = container.Resolve <BalanceUpdateImporter>(); balanceImporter .ImportBalancesAsync() .Wait(); } }
public static void Main(string[] args) { if (args == null || !args.Any()) { throw new Exception("Specify parameters! url to EtherteumCore service"); } var exit = false; string settingsArg = args.First(); var settings = new SettingsServiceReloadingManager <AppSettings>(settingsArg); SaveSettings(settings); ContainerBuilder containerBuilder = new ContainerBuilder(); IServiceCollection collection = new Microsoft.Extensions.DependencyInjection.ServiceCollection(); containerBuilder.RegisterInstance(settings); containerBuilder.RegisterInstance <IBaseSettings>(settings.CurrentValue.EthereumCore); containerBuilder.RegisterInstance <ISlackNotificationSettings>(settings.CurrentValue.SlackNotifications); containerBuilder.RegisterInstance(settings.Nested(x => x.EthereumCore)); containerBuilder.RegisterInstance(settings.CurrentValue); var consoleLogger = new LogToConsole(); collection.AddSingleton <ILog>(consoleLogger); //TODO: Uncomment and fix registrations RegisterReposExt.RegisterAzureQueues(containerBuilder, settings.Nested(x => x.EthereumCore.Db.DataConnString), settings.Nested(x => x.SlackNotifications)); RegisterReposExt.RegisterAzureStorages(containerBuilder, settings.Nested(x => x.EthereumCore), settings.Nested(x => x.SlackNotifications), consoleLogger); RegisterRabbitQueueEx.RegisterRabbitQueue(collection, settings.Nested(x => x.EthereumCore.RabbitMq), settings.Nested(x => x.EthereumCore.Db.DataConnString), consoleLogger); RegisterDependency.RegisterServices(collection); RegisterDependency.RegisterServices(containerBuilder); //Lykke.Job.EthereumCore.Config.RegisterDependency.RegisterJobs(collection); //var web3 = ServiceProvider.GetService<Web3>(); //web3.Eth.GetBalance.SendRequestAsync(""); // web3.Eth.Transactions.SendTransaction.SendRequestAsync(new Nethereum.RPC.Eth.DTOs.TransactionInput() //{ // //}).Result; //var key = EthECKey.GenerateKey().GetPrivateKeyAsBytes(); //var stringKey = Encoding.Unicode.GetString(key); GetAllContractInJson(); containerBuilder.Populate(collection); ServiceProvider = containerBuilder.Build(); ServiceProvider.ActivateRequestInterceptor(); //var signApi = ServiceProvider.Resolve<ILykkeSigningAPI>(); //var signed = signApi.ApiEthereumSignPostWithHttpMessagesAsync(new EthereumTransactionSignRequest() //{ // FromProperty = "0x406561F72e25af10fD28b41200FA3D52badC5A21", // Transaction = "f86b8201618483215600830186a094db6ea754f2afb4257b9bea0828771b19504aeac380b844a9059cbb00000000000000000000000033c6b8907d65d5a53cc301c544abf99f2e783242000000000000000000000000000000000000000000000000000000000000000c808080" //}).Result; //var xa = 1; //var lykkeSigningAPI = ServiceProvider.Resolve<ILykkeSigningAPI>(); //var key1 = lykkeSigningAPI.ApiEthereumKeyGetAsync().Result; //var eventService = ServiceProvider.GetService<ITransactionEventsService>(); //eventService.IndexCashinEventsForAdapter("0x1c4ca817d1c61f9c47ce2bec9d7106393ff981ce", // "0x512867d36f1d6ee43f2056a7c41606133bce514fbc8e911c1834eeae80800ceb").Wait(); //#region EmissiveErc223 TOKEN //string tokenAddress = ""; //string depositAddress = ""; //Contract contract; //var web3 = ServiceProvider.Resolve<IWeb3>(); //{ // var abi = GetFileContent("Erc20DepositContract.abi"); // var bytecode = GetFileContent("Erc20DepositContract.bin"); // depositAddress = string.IsNullOrEmpty(depositAddress) ? // ServiceProvider.Resolve<IContractService>() // .CreateContract(abi, // bytecode, // 4000000) // .Result : depositAddress; //} //{ // //address issuer, // //string tokenName, // //uint8 divisibility, // //string tokenSymbol, // //string version // var abi = GetFileContent("EmissiveErc223Token.abi"); // var bytecode = GetFileContent("EmissiveErc223Token.bin"); // tokenAddress = string.IsNullOrEmpty(tokenAddress) ? // ServiceProvider.Resolve<IContractService>() // .CreateContract(abi, // bytecode, // 4000000, // settings.CurrentValue.EthereumCore.EthereumMainAccount, // "LykkeErc223Token", // 18, // "LTE223", // "1.0.0") // .Result : tokenAddress; // contract = web3.Eth.GetContract(abi, tokenAddress); //} //{ // //Transfer to the deposit contract // var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>(); // var balanceOld = erc20Service.GetBalanceForExternalTokenAsync(depositAddress, tokenAddress).Result; // var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount, // depositAddress, System.Numerics.BigInteger.Parse("1000000000000000000")).Result; // WaitForTransactionCompleation(web3, transactionHash); // var balance = erc20Service.GetBalanceForExternalTokenAsync(depositAddress, tokenAddress).Result; // var isPossibleToWithdrawWithTokenFallback = erc20Service.CheckTokenFallback(depositAddress).Result; // var isPossibleToWithdrawToExternal = // erc20Service.CheckTokenFallback("0x856924997fa22efad8dc75e83acfa916490989a4").Result; //} //{ // //Transfer to the account managed by external private key // var toAddress = "0x856924997fa22efad8dc75e83acfa916490989a4"; // var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>(); // var balanceOld = erc20Service.GetBalanceForExternalTokenAsync(toAddress, tokenAddress).Result; // var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount, // toAddress, System.Numerics.BigInteger.Parse("1000000000000000000")).Result; // WaitForTransactionCompleation(web3, transactionHash); // var balance = erc20Service.GetBalanceForExternalTokenAsync(toAddress, tokenAddress).Result; //} //{ // //Transfer to the contract without fallback function // string contractWithoutFallback = "0xd6ff42fa358403e0f9462c08e78c4baea1093945"; // var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>(); // var balanceOld = erc20Service.GetBalanceForExternalTokenAsync(contractWithoutFallback, tokenAddress).Result; // var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount, // contractWithoutFallback, System.Numerics.BigInteger.Parse("1000000000000000000")).Result; // WaitForTransactionCompleation(web3, transactionHash); // var balance = erc20Service.GetBalanceForExternalTokenAsync(contractWithoutFallback, tokenAddress).Result; // var isPossibleToWithdrawWithoutTokenFallback = erc20Service.CheckTokenFallback(contractWithoutFallback).Result; //} //#endregion //#region DBE TOKEN //{ // //var abi = GetFileContent("Erc20DepositContract.abi"); // //var bytecode = GetFileContent("Erc20DepositContract.bin"); // //depositAddress = // // ServiceProvider.Resolve<IContractService>() // // .CreateContract(abi, bytecode, 4000000) // // .Result; //} //{ // var abi = GetFileContent("debtoken.abi"); // var bytecode = GetFileContent("debtoken.bin"); // //tokenAddress = // // ServiceProvider.Resolve<IContractService>() // // .CreateContract(abi, bytecode, 4000000) // // .Result; // contract = web3.Eth.GetContract(abi, tokenAddress); //} //{ // //var unfreezeFunc = contract.GetFunction("unfreeze"); // //var transactionHash = unfreezeFunc.SendTransactionAsync(settings.CurrentValue.EthereumCore.EthereumMainAccount, // // new HexBigInteger(BigInteger.Parse("200000")), new HexBigInteger(0)).Result; //} //{ // var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>(); // var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount, // depositAddress, System.Numerics.BigInteger.Parse("1000000000000000000")).Result; //} //#endregion //#region StatusExamples ////var service = ServiceProvider.GetService<ICoinTransactionService>(); ////{ //// //fail //// var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage() //// { //// TransactionHash = "0xf86efe1b8de285b8255519ca7d0ac76088132e6c5306f88dfc27312c6d7127ea", //// }).Result; ////} ////{ //// //ok //// var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage() //// { //// TransactionHash = "0xa237230df97a0d6710241597a0186662928afa373c13b8d4eac86f36aa678985", //// }).Result; ////} ////{ //// //fail //// var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage() //// { //// TransactionHash = "0xb63ac4f94006cbbfe58a1d651e173c56dc74a45e4d1141ac57fc51a0d4202e95", //// }).Result; ////} ////{ //// //fail //// var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage() //// { //// TransactionHash = "0x1df50ee79d0af8b433f7f0be2a84cbb5dc3e29e5822e78b9c6a7ec33d027e286", //// }).Result; ////} ////{ //// //fail //// var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage() //// { //// TransactionHash = "0xa3d4c1da523273371fe45c928b9236b353976e7b9e6d2b31e659f7a4c781a764", //// }).Result; ////} //#endregion //0xf86efe1b8de285b8255519ca7d0ac76088132e6c5306f88dfc27312c6d7127ea 0x0 //0xa237230df97a0d6710241597a0186662928afa373c13b8d4eac86f36aa678985 0x1 //0xb63ac4f94006cbbfe58a1d651e173c56dc74a45e4d1141ac57fc51a0d4202e95 //var service = ServiceProvider.Resolve<IErcInterfaceService>(); //service.Transfer("0x5adbf411faf2595698d80b7f93d570dd16d7f4b2", settings.CurrentValue.EthereumCore.EthereumMainAccount, // "0xae4d8b0c887508750ddb6b32752a82431941e2e7", System.Numerics.BigInteger.Parse("10000000000000000000")).Wait(); //var paymentService = ServiceProvider.GetService<IPaymentService>(); // string result = paymentService.SendEthereum(settings.EthereumMainAccount, // "0xbb0a9c08030898cdaf1f28633f0d3c8556155482", new System.Numerics.BigInteger(5000000000000000)).Result; //var coinEv = ServiceProvider.GetService<ICoinEventService>(); //var ev1 = coinEv.GetCoinEvent("0xbfb8d6a561c1a088c347efb989e19cb02c1028b34a337e001b146fd1360dc714").Result; //var ev2 = coinEv.GetCoinEvent("0xa0876a676d695ab145fcf70ac0b2ae02e8b00351a5193352ffb37ad37dce6848").Result; //coinEv.InsertAsync(ev1).Wait(); //coinEv.InsertAsync(ev2).Wait(); //var paymentService = ServiceProvider.GetService<ICoinTransactionService>(); //paymentService.PutTransactionToQueue("0xbfb8d6a561c1a088c347efb989e19cb02c1028b34a337e001b146fd1360dc714").Wait(); //paymentService.PutTransactionToQueue("0xa0876a676d695ab145fcf70ac0b2ae02e8b00351a5193352ffb37ad37dce6848").Wait(); //var pendingOperationService = ServiceProvider.GetService<IPendingOperationService>(); //var op = pendingOperationService.GetOperationAsync("40017691-1656-4d71-a8a6-4187200dca73").Result; //pendingOperationService.CreateOperation(op).Wait(); //var op2 = pendingOperationService.GetOperationAsync("41e19fd5-2660-469b-9315-b768f701e742").Result; //pendingOperationService.CreateOperation(op2).Wait(); while (!exit) { Console.WriteLine("Choose number: "); //Console.WriteLine("1. Deploy main contract from local json file"); Console.WriteLine("2. Deploy main exchange contract"); Console.WriteLine("3. Deploy coin contract using local json file"); Console.WriteLine("4. Deploy transfer"); Console.WriteLine("5. Deploy BCAP Token"); Console.WriteLine("6. Deploy main exchange contract with multiple owners!(Make sure that jobs are stopped)"); Console.WriteLine("7. Add more owners to Main Exchange Contract with multiple owners!(Add addresses with some eth on it)"); Console.WriteLine("9. Deploy And Migrate To NM!(Make sure that jobs are stopped)"); Console.WriteLine("10. Send transaction to MainExchange!(Make sure that jobs are stopped)"); Console.WriteLine("0. Exit"); var input = Console.ReadLine(); switch (input) { case "2": DeployMainExchangeContract().Wait(); break; case "3": //DeployCoinContract().Wait(); break; case "4": DeployTokenTransferContract().Wait(); break; case "0": exit = true; break; case "5": DeployBCAP().Wait(); break; case "6": DeployAndMigrateMainExchangeContractWithMultipleOwners().Wait(); break; case "7": AddOwners().Wait(); break; //case "8": // MigrateAdapter(,).Wait(); // break; case "9": DeployAndMigrateToNM().Wait(); break; case "10": SendTransactionFromMainExchange().Wait(); break; default: Console.WriteLine("Bad input!"); continue; } Console.WriteLine("Done!"); } }
private static async Task Execute(string settingsUrl) { if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _)) { Console.WriteLine($"{SettingsUrl}: {settingsUrl} should be a valid uri"); return; } var logFactory = LogFactory.Create().AddConsole(); var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl).Nested(x => x.BitcoinCashApi); BCash.Instance.EnsureRegistered(); var network = Network.GetNetwork(settings.CurrentValue.Network); var bcashNetwork = network == Network.Main ? BCash.Instance.Mainnet : BCash.Instance.Regtest; var addressValidator = new AddressValidator(network, bcashNetwork); var observableWalletRepository = new ObservableWalletRepository(AzureTableStorage <ObservableWalletEntity> .Create( settings.Nested(p => p.Db.DataConnString), "ObservableWallets", logFactory)); var observableWalletV2Repository = new ObservableWalletRepository(AzureTableStorage <ObservableWalletEntity> .Create( settings.Nested(p => p.Db.DataConnString), "ObservableWalletsV2", logFactory)); var walletBalanceV2Repo = new WalletBalanceRepository( AzureTableStorage <WalletBalanceEntity> .Create(settings.Nested(p => p.Db.DataConnString), "WalletBalancesV2", logFactory)); var bcProvider = new RpcBlockchainProvider(new RPCClient( new NetworkCredential(settings.CurrentValue.Rpc.UserName, settings.CurrentValue.Rpc.Password), new Uri(settings.CurrentValue.Rpc.Host), bcashNetwork), addressValidator, logFactory.CreateLog("temp")); var walletBalanceService = new WalletBalanceService(walletBalanceV2Repo, observableWalletV2Repository, bcProvider, new OperationsConfirmationsSettings { MinConfirmationsToDetectOperation = settings.CurrentValue.MinConfirmationsToDetectOperation }); Console.WriteLine("Retrieving observable wallets"); var observableWallets = (await observableWalletRepository.GetAll()).ToList(); var obserwabletWalletsTransformation = observableWallets.ToDictionary(observableWallet => observableWallet.Address, observableWallet => { var addr = addressValidator.GetBitcoinAddress(observableWallet.Address); if (addr == null) { throw new ArgumentException($"Unable to recognize address {observableWallet.Address}", nameof(observableWallet.Address)); } var oldAdrr = addr.ScriptPubKey.GetDestinationAddress(network).ToString(); var newAddr = addr.ScriptPubKey.GetDestinationAddress(bcashNetwork).ToString(); if (!string.Equals(observableWallet.Address, oldAdrr, StringComparison.InvariantCultureIgnoreCase)) { var prevColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"{observableWallet.Address} not in obsolete format. Old format: {oldAdrr} | New Format {newAddr}"); Console.ForegroundColor = prevColor; } return(newAddr); }); var refillingProgress = 0; Console.WriteLine("Filling table ObservableWalletsV2"); await observableWallets.ForEachAsyncSemaphore(8, async observableWallet => { var progress = Interlocked.Increment(ref refillingProgress); var newAddress = obserwabletWalletsTransformation[observableWallet.Address]; Console.WriteLine($"Inserting obserwablewallet record {observableWallet.Address} => {newAddress} " + $"-- {progress} of {observableWallets.Count}"); await observableWalletV2Repository.Insert(ObservableWallet.Create(newAddress)); }); var updatingBalanceProgress = 0; Console.WriteLine("Filling table WalletBalancesV2"); await observableWallets.ForEachAsyncSemaphore(8, async observableWallet => { var progress = Interlocked.Increment(ref updatingBalanceProgress); var newAddress = obserwabletWalletsTransformation[observableWallet.Address]; Console.WriteLine($"Updating balance record {observableWallet.Address} => {newAddress} " + $"-- {progress} of {observableWallets.Count}"); await walletBalanceService.UpdateBalance(newAddress); }); Console.WriteLine("All done!"); }
private static async Task Import(string settingsUrl, string hotwallet, string timestamp, string batchSize) { if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _)) { Console.WriteLine($"{SettingsUrl}: {settingsUrl} should be a valid uri"); return; } DateTime timeStampTyped; if (!DateTime.TryParse(timestamp, out timeStampTyped)) { Console.WriteLine($"{Timestamp}: {timestamp} should be Date time "); return; } if (!DateTime.TryParse(timestamp, out timeStampTyped)) { Console.WriteLine($"{Timestamp}: {timestamp} should be a valid Date time "); return; } if (!int.TryParse(batchSize, out var batchSizeTyped)) { Console.WriteLine($"{BatchSize}: {batchSize} should be a valid integer "); return; } var logFactory = LogFactory.Create().AddConsole(); var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl).Nested(x => x.BitcoinCashApi); var network = Network.GetNetwork(settings.CurrentValue.Network); var bcashNetwork = network == Network.Main ? BCash.Instance.Mainnet : BCash.Instance.Regtest; var addressValidator = new AddressValidator(network, bcashNetwork); var hotwalletTyped = addressValidator.GetBitcoinAddress(hotwallet); if (hotwalletTyped == null) { Console.WriteLine($"{HotWallet}: {hotwallet} should be a valid bitcoin address"); return; } var authTokenBytes = Encoding.ASCII.GetBytes($"{settings.CurrentValue.Rpc.UserName}:{settings.CurrentValue.Rpc.Password}"); var authToken = Convert.ToBase64String(authTokenBytes); var httpClient = new HttpClient { BaseAddress = new Uri(settings.CurrentValue.Rpc.Host), Timeout = TimeSpan.FromMinutes(30), DefaultRequestHeaders = { Authorization = new AuthenticationHeaderValue("Basic", authToken) } }; var observableWalletRepository = new ObservableWalletRepository(AzureTableStorage <ObservableWalletEntity> .Create( settings.Nested(p => p.Db.DataConnString), "ObservableWalletsV2", logFactory)); Console.WriteLine("Retrieving observable wallets"); var observableWallets = await observableWalletRepository.GetAll(); var walletsToImport = observableWallets .Select(p => addressValidator.GetBitcoinAddress(p.Address)) .Concat(new[] { hotwalletTyped }) .ToList(); Console.WriteLine($"Importing {walletsToImport.Count} addresses in node started at {DateTime.UtcNow}. Timestamp {timeStampTyped}. Batch size {batchSize}"); var batchNum = 1; foreach (var batch in walletsToImport.Batch(batchSizeTyped)) { Console.WriteLine($"{DateTime.UtcNow} Importing batch {batchNum++}..."); var payload = new { jsonrpc = "1.0", id = Guid.NewGuid().ToString(), method = "importmulti", @params = new object[] { batch.Select(address => new { scriptPubKey = new ImportMultiAddress.ScriptPubKeyObject(address), timestamp = Utils.DateTimeToUnixTime(new DateTimeOffset(timeStampTyped)) }), new { rescan = true } } }; await Policy .Handle <Exception>() .RetryAsync(5, (e, i) => { Console.WriteLine($"Retrying ({i})..."); }) .ExecuteAsync(async() => { using (var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json")) { using (var response = await httpClient.PostAsync("", content)) { if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine($"Failed to execute RPC call. Response: {response.StatusCode}"); throw new InvalidOperationException($"Failed to execute RPC call. Response: {response.StatusCode}, {await response.Content.ReadAsStringAsync()}"); } } } }); Console.WriteLine($"{DateTime.UtcNow} Batch imported"); } Console.WriteLine($"Import completed at {DateTime.UtcNow}"); }