public static CurrencyViewModel CreateViewModel( CurrencyConfig currencyConfig, bool subscribeToUpdates) { var result = currencyConfig.Name switch { "BTC" => (CurrencyViewModel) new BitcoinCurrencyViewModel(currencyConfig), "LTC" => new LitecoinCurrencyViewModel(currencyConfig), "USDT" => new TetherCurrencyViewModel(currencyConfig), "TBTC" => new TbtcCurrencyViewModel(currencyConfig), "WBTC" => new WbtcCurrencyViewModel(currencyConfig), "ETH" => new EthereumCurrencyViewModel(currencyConfig), "TZBTC" => new TzbtcCurrencyViewModel(currencyConfig), "KUSD" => new KusdCurrencyViewModel(currencyConfig), "XTZ" => new TezosCurrencyViewModel(currencyConfig), _ => throw new NotSupportedException( $"Can't create currency view model for {currencyConfig.Name}. This currency is not supported.") }; if (!subscribeToUpdates) { return(result); } result.SubscribeToUpdates(App.AtomexApp.Account); result.SubscribeToRatesProvider(App.AtomexApp.QuotesProvider); result.UpdateInBackgroundAsync(); return(result); } }
public TransactionViewModel(IBlockchainTransaction tx, CurrencyConfig currencyConfig, decimal amount, decimal fee) { Transaction = tx ?? throw new ArgumentNullException(nameof(tx)); Id = Transaction.Id; Currency = currencyConfig; State = Transaction.State; Type = GetType(Transaction.Type); //Type = Transaction.Type; Amount = amount; TxExplorerUri = $"{Currency.TxExplorerUri}{Id}"; ToastService = DependencyService.Get <IToastService>(); var netAmount = amount + fee; AmountFormat = currencyConfig.Format; CurrencyCode = currencyConfig.Name; Time = tx.CreationTime ?? DateTime.UtcNow; CanBeRemoved = tx.State == BlockchainTransactionState.Failed || tx.State == BlockchainTransactionState.Pending || tx.State == BlockchainTransactionState.Unknown || tx.State == BlockchainTransactionState.Unconfirmed; Description = GetDescription( type: tx.Type, amount: Amount, netAmount: netAmount, amountDigits: currencyConfig.Digits, currencyCode: currencyConfig.Name); }
public static async Task <Result <byte[]> > IsRedeemedAsync( Swap swap, CurrencyConfig currency, int attempts, int attemptIntervalInSec, CancellationToken cancellationToken = default) { var attempt = 0; while (!cancellationToken.IsCancellationRequested && attempt < attempts) { ++attempt; var isRedeemedResult = await IsRedeemedAsync( swap : swap, currency : currency, cancellationToken : cancellationToken) .ConfigureAwait(false); if (isRedeemedResult.HasError && isRedeemedResult.Error.Code != Errors.RequestError) // has error { return(isRedeemedResult); } if (!isRedeemedResult.HasError) { return(isRedeemedResult); } await Task.Delay(TimeSpan.FromSeconds(attemptIntervalInSec), cancellationToken) .ConfigureAwait(false); } return(new Error(Errors.MaxAttemptsCountReached, "Max attempts count reached for redeem check")); }
public static Symbol SymbolByCurrencies( this IEnumerable <Symbol> symbols, CurrencyConfig from, CurrencyConfig to) { return(SymbolByCurrencies(symbols, from.Name, to.Name)); }
public async Task <bool> SignAsync( IAddressBasedTransaction tx, WalletAddress address, CurrencyConfig currencyConfig, CancellationToken cancellationToken = default) { if (tx == null) { throw new ArgumentNullException(nameof(tx)); } Log.Verbose("Sign request for transaction {@id}", tx.Id); if (IsLocked) { Log.Warning("Wallet locked"); return(false); } var signResult = await tx .SignAsync(KeyStorage, address, currencyConfig, cancellationToken) .ConfigureAwait(false); if (signResult) { Log.Verbose("Transaction {@id} successfully signed", tx.Id); } else { Log.Error("Transaction {@id} signing error", tx.Id); } return(signResult); }
public Fisher(BaseBot Bot, Command command, _userInfo User, CurrencyConfig currency) { this.Bot = Bot; this.command = command; this.User = User; this.currency = currency; }
public static ICurrencySwap Create( CurrencyConfig currency, IAccount account) { return(currency switch { BitcoinBasedConfig _ => new BitcoinBasedSwap( account: account.GetCurrencyAccount <BitcoinBasedAccount>(currency.Name), currencies: account.Currencies), Erc20Config _ => new Erc20Swap( account: account.GetCurrencyAccount <Erc20Account>(currency.Name), ethereumAccount: account.GetCurrencyAccount <EthereumAccount>("ETH"), currencies: account.Currencies), EthereumConfig _ => new EthereumSwap( account: account.GetCurrencyAccount <EthereumAccount>(currency.Name), currencies: account.Currencies), Fa12Config _ => new Fa12Swap( account: account.GetCurrencyAccount <Fa12Account>(currency.Name), tezosAccount: account.GetCurrencyAccount <TezosAccount>(TezosConfig.Xtz), currencies: account.Currencies), TezosConfig _ => new TezosSwap( account: account.GetCurrencyAccount <TezosAccount>(currency.Name), currencies: account.Currencies), _ => throw new NotSupportedException($"Not supported currency {currency.Name}") });
public FA2SendViewModel( IAtomexApp app, IDialogViewer dialogViewer, CurrencyConfig currency) : base(app, dialogViewer, currency) { }
public WalletAddress GetAddress( CurrencyConfig currency, uint account, uint chain, uint index, int keyType) { using var securePublicKey = KeyStorage.GetPublicKey( currency: currency, account: account, chain: chain, index: index, keyType: keyType); if (securePublicKey == null) { return(null); } using var publicKey = securePublicKey.ToUnsecuredBytes(); var address = currency.AddressFromKey(publicKey); return(new WalletAddress { Currency = currency.Name, Address = address, PublicKey = Convert.ToBase64String(publicKey), KeyIndex = new KeyIndex { Account = account, Chain = chain, Index = index }, KeyType = keyType }); }
public static IWalletViewModel CreateViewModel( IAtomexApp app, IDialogViewer dialogViewer, IMenuSelector menuSelector, IConversionViewModel conversionViewModel, CurrencyConfig currency) { return(currency switch { BitcoinBasedConfig _ or Erc20Config _ or EthereumConfig _ => new WalletViewModel( app: app, dialogViewer: dialogViewer, menuSelector: menuSelector, conversionViewModel: conversionViewModel, currency: currency), Fa12Config _ => new Fa12WalletViewModel( app: app, dialogViewer: dialogViewer, menuSelector: menuSelector, conversionViewModel: conversionViewModel, currency: currency), TezosConfig _ => new TezosWalletViewModel( app: app, dialogViewer: dialogViewer, menuSelector: menuSelector, conversionViewModel: conversionViewModel, currency: currency), _ => throw new NotSupportedException($"Can't create wallet view model for {currency.Name}. This currency is not supported."), });
/// <summary> /// 消耗货币 /// </summary> public void costCurrency(int type, long value, int way) { if (value <= 0) { return; } long[] currencies; long v = (currencies = _d.currencies)[type]; if ((v -= value) < 0) { value = v; v = 0; } currencies[type] = v; toLogCostCurrency(type, value, way); me.dispatch(GameEventType.RefreshCurrency, type); if (CommonSetting.isClientDriveLogic && CurrencyConfig.get(type).needAddRecord) { me.quest.taskEvent(TaskType.TotalCostCurrency, type, (int)(_d.totalAddCurrencies[type] - _d.currencies[type])); } onCostCurrency(type, value); }
public static async Task <Result <IBlockchainTransaction> > TryToFindPaymentAsync( Swap swap, CurrencyConfig currency, CancellationToken cancellationToken = default) { var tezos = currency as TezosConfig; if (swap.PaymentTx is not TezosTransaction paymentTx) { return(new Error(Errors.SwapError, "Saved tx is null")); } var lockTimeInSeconds = swap.IsInitiator ? CurrencySwap.DefaultInitiatorLockTimeInSeconds : CurrencySwap.DefaultAcceptorLockTimeInSeconds; var refundTime = new DateTimeOffset(swap.TimeStamp.ToUniversalTime().AddSeconds(lockTimeInSeconds)) .ToString("yyyy-MM-ddTHH:mm:ssZ"); var rewardForRedeemInMtz = swap.IsInitiator ? swap.PartyRewardForRedeem.ToMicroTez() : 0; var parameters = "entrypoint=initiate" + $"¶meter.participant={swap.PartyAddress}" + $"¶meter.settings.refund_time={refundTime}" + $"¶meter.settings.hashed_secret={swap.SecretHash.ToHexString()}" + $"¶meter.settings.payoff={(long)rewardForRedeemInMtz}"; var api = tezos.BlockchainApi as ITezosBlockchainApi; var txsResult = await api .TryGetTransactionsAsync( from : paymentTx.From, to : tezos.SwapContractAddress, parameters : parameters, cancellationToken : cancellationToken) .ConfigureAwait(false); if (txsResult == null) { return(new Error(Errors.RequestError, "Can't get Tezos swap contract transactions")); } if (txsResult.HasError) { return(txsResult.Error); } foreach (var tx in txsResult.Value) { if (tx.State != BlockchainTransactionState.Failed) { return(tx); } } return(new Result <IBlockchainTransaction>((IBlockchainTransaction)null)); }
public static Task StartSwapInitiatedControlAsync( Swap swap, CurrencyConfig currency, long refundTimeStamp, TimeSpan interval, Func <Swap, CancellationToken, Task> initiatedHandler = null, Func <Swap, CancellationToken, Task> canceledHandler = null, CancellationToken cancellationToken = default) { return(Task.Run(async() => { try { while (!cancellationToken.IsCancellationRequested) { if (swap.IsCanceled) { await canceledHandler.Invoke(swap, cancellationToken) .ConfigureAwait(false); break; } var isInitiatedResult = await IsInitiatedAsync( swap: swap, currency: currency, refundTimeStamp: refundTimeStamp, cancellationToken: cancellationToken) .ConfigureAwait(false); if (isInitiatedResult.HasError && isInitiatedResult.Error.Code != Errors.RequestError) { await canceledHandler.Invoke(swap, cancellationToken) .ConfigureAwait(false); break; } else if (!isInitiatedResult.HasError && isInitiatedResult.Value) { await initiatedHandler.Invoke(swap, cancellationToken) .ConfigureAwait(false); break; } await Task.Delay(interval, cancellationToken) .ConfigureAwait(false); } } catch (OperationCanceledException) { Log.Debug("StartSwapInitiatedControlAsync canceled."); } catch (Exception e) { Log.Error(e, "StartSwapInitiatedControlAsync error."); } }, cancellationToken)); }
public static bool AddFisher(BaseBot Bot, Command command, _userInfo User, CurrencyConfig currency) { if (FisherMen.Count(x => x.Key.User.user.user.Equals(User.user.user) && x.Key.currency.Id == currency.Id) == 0) { FisherMen.Add(new Fisher(Bot, command, User, currency), DateTime.Now); return(true); } return(false); }
public static Type OutputType(this CurrencyConfig currency) { if (currency is BitcoinBasedConfig) { return(typeof(BitcoinBasedTxOutput)); } throw new NotSupportedException($"Not supported currency {currency.Name}"); }
public static async Task <decimal> EstimateAsync( IAccount account, ICurrencyQuotesProvider quotesProvider, Func <string, Quote> feeCurrencyQuotesProvider, CurrencyConfig redeemableCurrency, WalletAddress redeemFromAddress = null, CancellationToken cancellationToken = default) { if (redeemableCurrency is BitcoinBasedConfig) { return(0m); } var feeCurrency = redeemableCurrency.FeeCurrencyName; var feeCurrencyAddress = redeemFromAddress != null ? await account .GetAddressAsync(feeCurrency, redeemFromAddress.Address, cancellationToken) .ConfigureAwait(false) : null; var redeemFee = await redeemableCurrency .GetRedeemFeeAsync(redeemFromAddress, cancellationToken) .ConfigureAwait(false); if (feeCurrencyAddress != null && feeCurrencyAddress.AvailableBalance() >= redeemFee) { return(0m); } var feeCurrencyToBaseQuote = redeemableCurrency.FeeCurrencyToBaseSymbol != null ? quotesProvider?.GetQuote(redeemableCurrency.FeeCurrencyToBaseSymbol) : null; var feeCurrencyToBasePrice = feeCurrencyToBaseQuote != null ? feeCurrencyToBaseQuote.GetMiddlePrice() : 0m; var feeCurrencyQuote = redeemableCurrency.FeeCurrencySymbol != null ? feeCurrencyQuotesProvider.Invoke(redeemableCurrency.FeeCurrencySymbol) : null; var feeCurrencyPrice = feeCurrencyQuote != null ? feeCurrencyQuote.GetMiddlePrice() : 0m; return(await redeemableCurrency .GetRewardForRedeemAsync( maxRewardPercent : redeemableCurrency.MaxRewardPercent, maxRewardPercentInBase : redeemableCurrency.MaxRewardPercentInBase, feeCurrencyToBaseSymbol : redeemableCurrency.FeeCurrencyToBaseSymbol, feeCurrencyToBasePrice : feeCurrencyToBasePrice, feeCurrencySymbol : redeemableCurrency.FeeCurrencySymbol, feeCurrencyPrice : feeCurrencyPrice, cancellationToken : cancellationToken) .ConfigureAwait(false)); }
public Task <byte[]> SignAsync( byte[] data, WalletAddress address, CurrencyConfig currency, CancellationToken cancellationToken = default) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (address == null) { throw new ArgumentNullException(nameof(address)); } Log.Verbose("Sign request for data {@data} with key for address {@address}", data.ToHexString(), address.Address); if (IsLocked) { Log.Warning("Wallet locked"); return(Task.FromResult <byte[]>(null)); } if (address.KeyIndex == null) { Log.Error($"Can't find private key for address {address.Address}"); return(Task.FromResult <byte[]>(null)); } var signature = KeyStorage.SignMessage( currency: currency, data: data, keyIndex: address.KeyIndex, keyType: address.KeyType); Log.Verbose("Data signature in base64: {@signature}", Convert.ToBase64String(signature)); if (!KeyStorage.VerifyMessage( currency: currency, data: data, signature: signature, keyIndex: address.KeyIndex, keyType: address.KeyType)) { Log.Error("Signature verify error"); return(Task.FromResult <byte[]>(null)); } Log.Verbose("Data successfully signed"); return(Task.FromResult(signature)); }
public static void MessageRewardUser(_userInfo User) { CurrencyConfig C = CacheHandler.FindCurrency(User.currency); if (CanReward(User, C)) { User.balance += C.MessageReward; User.Update(); } }
public GamblingConfig() { BetRoll = new BetRollConfig(); WheelOfFortune = new WheelOfFortuneSettings(); Waifu = new WaifuConfig(); Currency = new CurrencyConfig(); BetFlip = new BetFlipConfig(); Generation = new GenerationConfig(); Timely = new TimelyConfig(); Decay = new DecayConfig(); }
public WalletAddress GetAddress( CurrencyConfig currency, KeyIndex keyIndex, int keyType) { return(GetAddress( currency: currency, account: keyIndex.Account, chain: keyIndex.Chain, index: keyIndex.Index, keyType: keyType)); }
public SecureBytes GetPublicKey( CurrencyConfig currency, KeyIndex keyIndex, int keyType) { return(GetPublicKey( currency: currency, account: keyIndex.Account, chain: keyIndex.Chain, index: keyIndex.Index, keyType: keyType)); }
public Task <byte[]> SignHashAsync( byte[] hash, WalletAddress address, CurrencyConfig currencyConfig, CancellationToken cancellationToken = default) { if (hash == null) { throw new ArgumentNullException(nameof(hash)); } if (address == null) { throw new ArgumentNullException(nameof(address)); } Log.Verbose("Sign request for hash {@hash}", hash.ToHexString()); if (IsLocked) { Log.Warning("Wallet locked"); return(Task.FromResult <byte[]>(null)); } if (address.KeyIndex == null) { Log.Error($"Can't find private key for address {address.Address}"); return(Task.FromResult <byte[]>(null)); } var signature = KeyStorage.SignHash( currency: currencyConfig, hash: hash, keyIndex: address.KeyIndex, keyType: address.KeyType); Log.Verbose("Hash signature in base64: {@signature}", Convert.ToBase64String(signature)); if (!KeyStorage.VerifyHash( currency: currencyConfig, hash: hash, signature: signature, keyIndex: address.KeyIndex, keyType: address.KeyType)) { Log.Error("Signature verify error"); return(Task.FromResult <byte[]>(null)); } Log.Verbose("Hash successfully signed"); return(Task.FromResult(signature)); }
public static async Task <Result <byte[]> > IsRedeemedAsync( Swap swap, CurrencyConfig currency, CancellationToken cancellationToken = default) { try { Log.Debug("Ethereum: check redeem event"); var ethereum = (Atomex.EthereumConfig)currency; var api = new EtherScanApi(ethereum); var redeemEventsResult = await api .GetContractEventsAsync( address : ethereum.SwapContractAddress, fromBlock : ethereum.SwapContractBlockNumber, toBlock : ulong.MaxValue, topic0 : EventSignatureExtractor.GetSignatureHash <RedeemedEventDTO>(), topic1 : "0x" + swap.SecretHash.ToHexString(), cancellationToken : cancellationToken) .ConfigureAwait(false); if (redeemEventsResult == null) { return(new Error(Errors.RequestError, $"Connection error while getting contract {ethereum.SwapContractAddress} redeem events")); } if (redeemEventsResult.HasError) { return(redeemEventsResult.Error); } var events = redeemEventsResult.Value?.ToList(); if (events == null || !events.Any()) { return((byte[])null); } var secret = events.First().ParseRedeemedEvent().Secret; Log.Debug("Redeem event received with secret {@secret}", Convert.ToBase64String(secret)); return(secret); } catch (Exception e) { Log.Error(e, "Ethereum redeem control task error"); return(new Error(Errors.InternalError, e.Message)); } }
public static async Task <Result <ConfirmationCheckResult> > IsTransactionConfirmed( this CurrencyConfig currency, string txId, CancellationToken cancellationToken = default) { try { var txResult = await currency.BlockchainApi .TryGetTransactionAsync(txId, cancellationToken : cancellationToken) .ConfigureAwait(false); if (txResult != null && txResult.HasError) { if (txResult.Error.Code == (int)HttpStatusCode.NotFound || txResult.Error.Code == (int)HttpStatusCode.GatewayTimeout || txResult.Error.Code == (int)HttpStatusCode.ServiceUnavailable || txResult.Error.Code == (int)HttpStatusCode.InternalServerError || txResult.Error.Code == HttpHelper.SslHandshakeFailed || txResult.Error.Code == Errors.RequestError) { return(new ConfirmationCheckResult(false, null)); } Log.Error("Error while get {@currency} transaction {@txId}. Code: {@code}. Description: {@desc}", currency.Name, txId, txResult.Error.Code, txResult.Error.Description); return(txResult.Error); } var tx = txResult.Value; if (tx != null && tx.State == BlockchainTransactionState.Failed) { return(new ConfirmationCheckResult(false, tx)); } if (tx == null || tx.BlockInfo == null || tx.BlockInfo.Confirmations < NumberOfConfirmations) { return(new ConfirmationCheckResult(false, null)); } return(new ConfirmationCheckResult(true, tx)); } catch (Exception e) { Log.Error(e, "Transaction confirmation check error"); return(new Error(Errors.InternalError, e.Message)); } }
public static async Task <List <BigInteger> > GetTransferValuesAsync( CurrencyConfig currency, string from, string to, string blockNumber, CancellationToken cancellationToken = default) { try { Log.Debug("Ethereum ERC20: check transfer event"); var erc20 = (EthereumTokens.Erc20Config)currency; var api = new EtherScanApi(erc20); var transferEventsResult = await api .GetContractEventsAsync( address : erc20.ERC20ContractAddress, fromBlock : (ulong)new HexBigInteger(blockNumber).Value, toBlock : ulong.MaxValue, topic0 : EventSignatureExtractor.GetSignatureHash <ERC20TransferEventDTO>(), topic1 : "0x000000000000000000000000" + from, topic2 : "0x000000000000000000000000" + to, cancellationToken : cancellationToken) .ConfigureAwait(false); if (transferEventsResult == null) { return(new List <BigInteger>()); } if (transferEventsResult.HasError) { return(new List <BigInteger>()); } var events = transferEventsResult.Value?.ToList(); if (events == null || !events.Any()) { return(new List <BigInteger>()); } return(events.Select(e => e.ParseERC20TransferEvent().Value).ToList()); } catch (Exception e) { Log.Error(e, "Ethereum ERC20 get transfer value task error"); return(new List <BigInteger>()); } }
public SecureBytes GetPrivateKey( CurrencyConfig currency, KeyIndex keyIndex, int keyType) { using var extKey = GetExtKey( currency: currency, purpose: Bip44.Purpose, keyIndex: keyIndex, keyType: keyType); return(extKey.GetPrivateKey()); }
/// <summary> /// Whether the provided <paramref name="record"/> matches the given <paramref name="matchType"/>/> /// </summary> /// <param name="record">Record to be matched</param> /// <param name="matchType">Match Type to check against</param> /// <param name="config">Currency configurations that defines all matching rules</param> /// <typeparam name="T">Type of Plugin Record we are dealing with</typeparam> /// <returns>Return true if match is successful.</returns> public static bool Matches <T>(this T record, MatchType matchType, CurrencyConfig config) where T : IContainerGetter { // TODO : Just do exact name matches as proof of concept for now. var matchName = config.MatchCriteria.Name; var query = record.Name?.String; return(matchType switch { MatchType.Normal => matchName.GetMatchType(query) == MatchType.Normal, MatchType.Dwemer => matchName.GetMatchType(query) == MatchType.Dwemer, MatchType.Nordic => matchName.GetMatchType(query) == MatchType.Nordic, _ => false });
public LitecoinCurrencyViewModel(CurrencyConfig currency) : base(currency) { Header = Currency.Description; IconBrush = new ImageBrush(new BitmapImage(new Uri(PathToImage("litecoin_90x90.png")))); IconMaskBrush = new ImageBrush(new BitmapImage(new Uri(PathToImage("litecoin_mask.png")))); AccentColor = Color.FromRgb(r: 191, g: 191, b: 191); AmountColor = Color.FromRgb(r: 231, g: 231, b: 231); UnselectedIconBrush = Brushes.White; IconPath = PathToImage("litecoin.png"); LargeIconPath = PathToImage("litecoin_90x90.png"); FeeName = Resources.SvMiningFee; }
public EthereumCurrencyViewModel(CurrencyConfig currency) : base(currency) { Header = Currency.Description; IconBrush = new ImageBrush(new BitmapImage(new Uri(PathToImage("ethereum_90x90.png")))); IconMaskBrush = new ImageBrush(new BitmapImage(new Uri(PathToImage("ethereum_mask.png")))); AccentColor = Color.FromRgb(r: 73, g: 114, b: 143); AmountColor = Color.FromRgb(r: 183, g: 208, b: 225); UnselectedIconBrush = Brushes.White; IconPath = PathToImage("ethereum.png"); LargeIconPath = PathToImage("ethereum_90x90.png"); FeeName = Resources.SvGasLimit; }
public FA2CurrencyViewModel(CurrencyConfig currency) : base(currency) { Header = Currency.Description; IconBrush = new ImageBrush(new BitmapImage(new Uri(PathToImage("tezos.png")))); IconMaskBrush = new ImageBrush(new BitmapImage(new Uri(PathToImage("tezos_mask.png")))); AccentColor = Color.FromRgb(r: 7, g: 82, b: 192); AmountColor = Color.FromRgb(r: 188, g: 212, b: 247); UnselectedIconBrush = Brushes.White; IconPath = PathToImage("tezos.png"); LargeIconPath = PathToImage("tezos_90x90.png"); FeeName = Resources.SvMiningFee; }