Пример #1
0
        private async Task <decimal> FeeByType(
            BlockchainTransactionType type,
            string from,
            bool isFirstTx,
            CancellationToken cancellationToken = default)
        {
            var xtz = Xtz;

            var isRevealed = await IsRevealedSourceAsync(from, cancellationToken)
                             .ConfigureAwait(false);

            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && isFirstTx)
            {
                return(xtz.InitiateFee.ToTez() + (isRevealed ? 0 : xtz.RevealFee.ToTez()));
            }
            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && !isFirstTx)
            {
                return(xtz.AddFee.ToTez() + (isRevealed ? 0 : xtz.RevealFee.ToTez()));
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(xtz.RefundFee.ToTez() + (isRevealed ? 0 : xtz.RevealFee.ToTez()));
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(xtz.RedeemFee.ToTez() + (isRevealed ? 0 : xtz.RevealFee.ToTez()));
            }

            return(xtz.Fee.ToTez() + (isRevealed ? 0 : xtz.RevealFee.ToTez()));
        }
Пример #2
0
        private decimal StorageFeeByType(BlockchainTransactionType type)
        {
            var fa12 = Fa12Config;

            if (type.HasFlag(BlockchainTransactionType.TokenApprove))
            {
                return(fa12.ApproveStorageLimit.ToTez());
            }

            if (type.HasFlag(BlockchainTransactionType.SwapPayment))
            {
                return(((fa12.ApproveStorageLimit * 2 + fa12.InitiateStorageLimit) * fa12.StorageFeeMultiplier).ToTez());
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(((fa12.RefundStorageLimit - fa12.ActivationStorage) * fa12.StorageFeeMultiplier).ToTez());
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(((fa12.RedeemStorageLimit - fa12.ActivationStorage) * fa12.StorageFeeMultiplier).ToTez());
            }

            return(((fa12.TransferStorageLimit - fa12.ActivationStorage) * fa12.StorageFeeMultiplier).ToTez());
        }
Пример #3
0
        private decimal GasLimitByType(BlockchainTransactionType type)
        {
            var erc20 = Erc20Config;

            if (type.HasFlag(BlockchainTransactionType.TokenApprove))
            {
                return(erc20.ApproveGasLimit);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapPayment)) // todo: recheck
            {
                return(erc20.ApproveGasLimit * 2 + erc20.InitiateWithRewardGasLimit);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(erc20.RefundGasLimit);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(erc20.RedeemGasLimit);
            }

            return(erc20.TransferGasLimit);
        }
Пример #4
0
 public abstract Task <(decimal, decimal, decimal)> EstimateMaxAmountToSendAsync(
     string to,
     BlockchainTransactionType type,
     decimal fee      = 0,
     decimal feePrice = 0,
     bool reserve     = false,
     CancellationToken cancellationToken = default);
Пример #5
0
        private async Task <decimal> FeeByType(
            BlockchainTransactionType type,
            string from,
            CancellationToken cancellationToken = default)
        {
            var xtz = Config;

            var isRevealed = await IsRevealedSourceAsync(from, cancellationToken)
                             .ConfigureAwait(false);

            var revealFeeInTez = !isRevealed
                ? xtz.RevealFee.ToTez()
                : 0;

            if (type.HasFlag(BlockchainTransactionType.SwapPayment))
            {
                return(xtz.InitiateFee.ToTez() + revealFeeInTez);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(xtz.RefundFee.ToTez() + revealFeeInTez);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(xtz.RedeemFee.ToTez() + revealFeeInTez);
            }

            return(xtz.Fee.ToTez() + revealFeeInTez);
        }
Пример #6
0
 public abstract Task <decimal?> EstimateFeeAsync(
     string to,
     decimal amount,
     BlockchainTransactionType type,
     decimal fee      = 0,
     decimal feePrice = 0,
     CancellationToken cancellationToken = default);
Пример #7
0
        private decimal StorageFeeByTypeAsync(
            BlockchainTransactionType type,
            bool isFirstTx)
        {
            var fa12 = Fa12;

            if (type.HasFlag(BlockchainTransactionType.TokenApprove))
            {
                return(fa12.ApproveStorageLimit);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && isFirstTx)
            {
                return((fa12.ApproveStorageLimit * 2 + fa12.InitiateStorageLimit) / fa12.StorageFeeMultiplier);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && !isFirstTx)
            {
                return((fa12.ApproveStorageLimit * 2 + fa12.AddStorageLimit) / fa12.StorageFeeMultiplier);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return((fa12.RefundStorageLimit - fa12.ActivationStorage) / fa12.StorageFeeMultiplier);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return((fa12.RedeemStorageLimit - fa12.ActivationStorage) / fa12.StorageFeeMultiplier);
            }

            return((fa12.TransferStorageLimit - fa12.ActivationStorage) / fa12.StorageFeeMultiplier);
        }
Пример #8
0
        private async Task <decimal> FeeByType(
            BlockchainTransactionType type,
            string from,
            CancellationToken cancellationToken = default)
        {
            var fa2 = FA2;

            var isRevealed = await IsRevealedSourceAsync(from, cancellationToken)
                             .ConfigureAwait(false);

            if (type.HasFlag(BlockchainTransactionType.TokenApprove))
            {
                return(fa2.ApproveFee.ToTez());
            }
            if (type.HasFlag(BlockchainTransactionType.SwapPayment))
            {
                return(fa2.ApproveFee.ToTez() + fa2.InitiateFee.ToTez() + (isRevealed ? 0 : fa2.RevealFee.ToTez()));
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(fa2.RefundFee.ToTez() + (isRevealed ? 0 : fa2.RevealFee.ToTez()));
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(fa2.RedeemFee.ToTez() + (isRevealed ? 0 : fa2.RevealFee.ToTez()));
            }

            return(fa2.TransferFee.ToTez() + (isRevealed ? 0 : fa2.RevealFee.ToTez()));
        }
Пример #9
0
        public override async Task <IEnumerable <WalletAddress> > GetUnspentAddressesAsync(
            string toAddress,
            decimal amount,
            decimal fee,
            decimal feePrice,
            FeeUsagePolicy feeUsagePolicy,
            AddressUsagePolicy addressUsagePolicy,
            BlockchainTransactionType transactionType,
            CancellationToken cancellationToken = default)
        {
            var unspentAddresses = (await DataRepository
                                    .GetUnspentAddressesAsync(Currency)
                                    .ConfigureAwait(false))
                                   .ToList();

            var selectedAddresses = (await SelectUnspentAddresses(
                                         from: unspentAddresses,
                                         amount: amount,
                                         fee: fee,
                                         feePrice: feePrice,
                                         feeUsagePolicy: feeUsagePolicy,
                                         addressUsagePolicy: addressUsagePolicy,
                                         transactionType: transactionType)
                                     .ConfigureAwait(false))
                                    .ToList();

            if (toAddress != null && selectedAddresses.Any(a => a.WalletAddress.Address == toAddress))
            {
                selectedAddresses.RemoveAll(a => a.WalletAddress.Address != toAddress);
            }

            return(ResolvePublicKeys(selectedAddresses
                                     .Select(w => w.WalletAddress)
                                     .ToList()));
        }
Пример #10
0
 public virtual Task <decimal> EstimateMaxFeeAsync(
     string to,
     decimal amount,
     BlockchainTransactionType type,
     CancellationToken cancellationToken = default)
 {
     return(Task.FromResult(0m));
 }
Пример #11
0
 public abstract Task <IEnumerable <WalletAddress> > GetUnspentAddressesAsync(
     string toAddress,
     decimal amount,
     decimal fee,
     decimal feePrice,
     FeeUsagePolicy feeUsagePolicy,
     AddressUsagePolicy addressUsagePolicy,
     BlockchainTransactionType transactionType,
     CancellationToken cancellationToken = default);
Пример #12
0
        public async Task <decimal> EstimateFeeAsync(
            BlockchainTransactionType type,
            CancellationToken cancellationToken = default)
        {
            var gasPrice = Math.Floor(await EthConfig
                                      .GetGasPriceAsync(cancellationToken)
                                      .ConfigureAwait(false));

            return(EthConfig.GetFeeAmount(GasLimitByType(type), gasPrice));
        }
Пример #13
0
 public Task <decimal> EstimateMaxFeeAsync(
     string currency,
     string to,
     decimal amount,
     BlockchainTransactionType type,
     CancellationToken cancellationToken = default)
 {
     return(GetCurrencyAccount(currency)
            .EstimateMaxFeeAsync(to, amount, type, cancellationToken));
 }
Пример #14
0
 public Task <(decimal, decimal, decimal)> EstimateMaxAmountToSendAsync(
     string currency,
     string to,
     BlockchainTransactionType type,
     decimal fee      = 0,
     decimal feePrice = 0,
     bool reserve     = false,
     CancellationToken cancellationToken = default)
 {
     return(GetCurrencyAccount(currency)
            .EstimateMaxAmountToSendAsync(to, type, fee, feePrice, reserve, cancellationToken));
 }
Пример #15
0
        public async Task <SelectedWalletAddress> CalculateFundsUsageAsync(
            string from,
            string to,
            decimal amount,
            decimal fee,
            FeeUsagePolicy feeUsagePolicy,
            BlockchainTransactionType transactionType,
            CancellationToken cancellationToken = default)
        {
            var xtz = Config;

            var fromAddress = await GetAddressAsync(from, cancellationToken)
                              .ConfigureAwait(false);

            if (fromAddress == null)
            {
                return(null); // invalid address
            }
            var txFeeInTez = feeUsagePolicy == FeeUsagePolicy.EstimatedFee
                ? await FeeByType(
                type : transactionType,
                from : fromAddress.Address,
                cancellationToken : cancellationToken)
                             .ConfigureAwait(false)
                : fee;

            var storageFeeInTez = await StorageFeeByTypeAsync(
                type : transactionType,
                to : to,
                cancellationToken : cancellationToken)
                                  .ConfigureAwait(false);

            var restBalanceInTez = fromAddress.AvailableBalance() -
                                   amount -
                                   txFeeInTez -
                                   storageFeeInTez -
                                   xtz.MicroTezReserve.ToTez();

            if (restBalanceInTez < 0)
            {
                return(null); // insufficient funds
            }
            return(new SelectedWalletAddress
            {
                WalletAddress = fromAddress,
                UsedAmount = amount,
                UsedFee = txFeeInTez,
                UsedStorageFee = storageFeeInTez
            });
        }
Пример #16
0
        public async Task <decimal> EstimateFeeAsync(
            string from,
            BlockchainTransactionType type,
            CancellationToken cancellationToken = default)
        {
            var txFeeInTez = await FeeByType(
                type : type,
                from : from,
                cancellationToken : cancellationToken)
                             .ConfigureAwait(false);

            var storageFeeInTez = StorageFeeByType(type);

            return(txFeeInTez + storageFeeInTez);
        }
Пример #17
0
        public async Task <FundsUsageEstimation> EstimateMaxAmountAsync(
            string to,
            BlockchainTransactionType type,
            CancellationToken cancellationToken = default)
        {
            var currency = BtcBasedCurrency;

            var unspentOutputs = (await DataRepository
                                  .GetAvailableOutputsAsync(Currency, currency.OutputType(), currency.TransactionType)
                                  .ConfigureAwait(false))
                                 .ToList();

            if (!unspentOutputs.Any())
            {
                return(null);
            }

            var availableAmountInSatoshi = unspentOutputs.Sum(o => o.Value);
            var estimatedSigSize         = BitcoinBasedCurrency.EstimateSigSize(unspentOutputs);

            var testTx = currency
                         .CreatePaymentTx(
                unspentOutputs: unspentOutputs,
                destinationAddress: currency.TestAddress(),
                changeAddress: currency.TestAddress(),
                amount: availableAmountInSatoshi,
                fee: 0,
                lockTime: DateTimeOffset.MinValue);

            // requiredFee = txSize * feeRate without dust, because all coins must be send to one address
            var requiredFeeInSatoshi = (long)((testTx.VirtualSize() + estimatedSigSize) * currency.FeeRate);

            var amount = currency.SatoshiToCoin(Math.Max(availableAmountInSatoshi - requiredFeeInSatoshi, 0));
            var fee    = currency.SatoshiToCoin(requiredFeeInSatoshi);

            return(new FundsUsageEstimation
            {
                TotalAmount = amount,
                TotalFee = fee,
                UsedAddresses = unspentOutputs.Select(o => new AddressUsageEstimation
                {
                    Address = $"{o.TxId}:{o.Index}",
                    Amount = currency.SatoshiToCoin(o.Value)
                })
            });
        }
Пример #18
0
        public override async Task <decimal> EstimateMaxFeeAsync(
            string to,
            decimal amount,
            BlockchainTransactionType type,
            CancellationToken cancellationToken = default)
        {
            var eth   = Eth;
            var erc20 = Erc20;

            var unspentAddresses = (await DataRepository
                                    .GetUnspentAddressesAsync(Currency)
                                    .ConfigureAwait(false))
                                   .ToList();

            if (!unspentAddresses.Any())
            {
                return(0m); // insufficient funds
            }
            var selectedAddresses = (await SelectUnspentAddresses(
                                         from: unspentAddresses,
                                         amount: amount,
                                         fee: 0,
                                         feePrice: erc20.GasPriceInGwei,
                                         feeUsagePolicy: FeeUsagePolicy.EstimatedFee,
                                         addressUsagePolicy: AddressUsagePolicy.UseMaximumChainBalanceFirst, //todo: calc efficiency for UseMaximumBalanceFirst
                                         transactionType: type)
                                     .ConfigureAwait(false))
                                    .ToList();

            if (!selectedAddresses.Any())
            {
                return(0m); // insufficient funds
            }
            decimal maxTxFee = 0m;

            foreach (var addr in selectedAddresses)
            {
                var ethAddress = await DataRepository
                                 .GetWalletAddressAsync(eth.Name, addr.WalletAddress.Address)
                                 .ConfigureAwait(false);

                maxTxFee = maxTxFee > 0 ? Math.Min(maxTxFee, ethAddress.AvailableBalance()) : ethAddress.AvailableBalance();
            }

            return(maxTxFee * selectedAddresses.Count());
        }
Пример #19
0
        public static TransactionType GetType(BlockchainTransactionType type)
        {
            if (type.HasFlag(BlockchainTransactionType.SwapPayment))
            {
                return(TransactionType.SwapPayment);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(TransactionType.SwapRedeem);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(TransactionType.SwapRefund);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapCall))
            {
                return(TransactionType.SwapCall);
            }

            if (type.HasFlag(BlockchainTransactionType.TokenCall))
            {
                return(TransactionType.TokenCall);
            }

            if (type.HasFlag(BlockchainTransactionType.TokenApprove))
            {
                return(TransactionType.TokenApprove);
            }

            if (type.HasFlag(BlockchainTransactionType.Input) &&
                type.HasFlag(BlockchainTransactionType.Output))
            {
                return(TransactionType.Output);
            }

            if (type.HasFlag(BlockchainTransactionType.Input))
            {
                return(TransactionType.Input);
            }

            return(TransactionType.Output);
        }
Пример #20
0
        public override async Task <decimal?> EstimateFeeAsync(
            string to,
            decimal amount,
            BlockchainTransactionType type,
            decimal fee      = 0,
            decimal feePrice = 0,
            CancellationToken cancellationToken = default)
        {
            var unspentAddresses = (await DataRepository
                                    .GetUnspentAddressesAsync(Currency)
                                    .ConfigureAwait(false))
                                   .ToList();

            if (!type.HasFlag(BlockchainTransactionType.SwapRedeem) &&
                !type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                unspentAddresses = unspentAddresses
                                   .Where(w => w.Address != to)
                                   .ToList();
            }

            if (!unspentAddresses.Any())
            {
                return(null); // insufficient funds
            }
            var selectedAddresses = (await SelectUnspentAddressesAsync(
                                         from: unspentAddresses,
                                         to: to,
                                         amount: amount,
                                         fee: fee,
                                         feePrice: 0,
                                         feeUsagePolicy: fee == 0 ? FeeUsagePolicy.EstimatedFee : FeeUsagePolicy.FeeForAllTransactions,
                                         addressUsagePolicy: AddressUsagePolicy.UseMinimalBalanceFirst,
                                         transactionType: type,
                                         cancellationToken: cancellationToken)
                                     .ConfigureAwait(false))
                                    .ToList();

            if (!selectedAddresses.Any())
            {
                return(null); // insufficient funds
            }
            return(selectedAddresses.Sum(s => s.UsedFee));
        }
Пример #21
0
 public static string GetDescription(
     BlockchainTransactionType type,
     decimal amount,
     decimal netAmount,
     int amountDigits,
     string currencyCode)
 {
     if (type.HasFlag(BlockchainTransactionType.SwapPayment))
     {
         return($"Swap payment {Math.Abs(amount).ToString("0." + new string('#', amountDigits))} {currencyCode}");
     }
     else if (type.HasFlag(BlockchainTransactionType.SwapRefund))
     {
         return($"Swap refund {Math.Abs(netAmount).ToString("0." + new string('#', amountDigits))} {currencyCode}");
     }
     else if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
     {
         return($"Swap redeem {Math.Abs(netAmount).ToString("0." + new string('#', amountDigits))} {currencyCode}");
     }
     else if (type.HasFlag(BlockchainTransactionType.TokenApprove))
     {
         return($"Token approve");
     }
     else if (type.HasFlag(BlockchainTransactionType.TokenCall))
     {
         return($"Token call");
     }
     else if (type.HasFlag(BlockchainTransactionType.SwapCall))
     {
         return($"Token swap call");
     }
     else if (amount <= 0)
     {
         return($"Sent {Math.Abs(netAmount).ToString("0." + new string('#', amountDigits))} {currencyCode}");
     }
     else if (amount > 0)
     {
         return($"Received {Math.Abs(netAmount).ToString("0." + new string('#', amountDigits))} {currencyCode}");
     }
     else
     {
         return("Unknown transaction");
     }
 }
Пример #22
0
        public override async Task <(decimal, decimal, decimal)> EstimateMaxAmountToSendAsync(
            string to,
            BlockchainTransactionType type,
            decimal fee      = 0,
            decimal feePrice = 0,
            bool reserve     = false,
            CancellationToken cancellationToken = default)
        {
            var currency = BtcBasedCurrency;

            var unspentOutputs = (await DataRepository
                                  .GetAvailableOutputsAsync(Currency, currency.OutputType(), currency.TransactionType)
                                  .ConfigureAwait(false))
                                 .ToList();

            if (!unspentOutputs.Any())
            {
                return(0m, 0m, 0m);
            }

            var availableAmountInSatoshi = unspentOutputs.Sum(o => o.Value);
            var estimatedSigSize         = BitcoinBasedCurrency.EstimateSigSize(unspentOutputs);

            var testTx = currency
                         .CreatePaymentTx(
                unspentOutputs: unspentOutputs,
                destinationAddress: currency.TestAddress(),
                changeAddress: currency.TestAddress(),
                amount: availableAmountInSatoshi,
                fee: 0,
                lockTime: DateTimeOffset.MinValue);

            // requiredFee = txSize * feeRate without dust, because all coins must be send to one address
            var requiredFeeInSatoshi = (long)((testTx.VirtualSize() + estimatedSigSize) * currency.FeeRate);

            var amount = currency.SatoshiToCoin(Math.Max(availableAmountInSatoshi - requiredFeeInSatoshi, 0));

            fee = currency.SatoshiToCoin(requiredFeeInSatoshi);

            return(amount, fee, 0m);
        }
Пример #23
0
        private decimal GasLimitByType(BlockchainTransactionType type)
        {
            var eth = EthConfig;

            if (type.HasFlag(BlockchainTransactionType.SwapPayment))
            {
                return(eth.InitiateWithRewardGasLimit);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(eth.RefundGasLimit);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(eth.RedeemGasLimit);
            }

            return(eth.GasLimit);
        }
Пример #24
0
 public Task <IEnumerable <WalletAddress> > GetUnspentAddressesAsync(
     string currency,
     string toAddress,
     decimal amount,
     decimal fee,
     decimal feePrice,
     FeeUsagePolicy feeUsagePolicy,
     AddressUsagePolicy addressUsagePolicy,
     BlockchainTransactionType transactionType,
     CancellationToken cancellationToken = default)
 {
     return(GetCurrencyAccount(currency)
            .GetUnspentAddressesAsync(
                toAddress: toAddress,
                amount: amount,
                fee: fee,
                feePrice: feePrice,
                feeUsagePolicy: feeUsagePolicy,
                addressUsagePolicy: addressUsagePolicy,
                transactionType: transactionType,
                cancellationToken: cancellationToken));
 }
Пример #25
0
        public override async Task <IEnumerable <WalletAddress> > GetUnspentAddressesAsync(
            string toAddress,
            decimal amount,
            decimal fee,
            decimal feePrice,
            FeeUsagePolicy feeUsagePolicy,
            AddressUsagePolicy addressUsagePolicy,
            BlockchainTransactionType transactionType,
            CancellationToken cancellationToken = default)
        {
            var unspentAddresses = (await DataRepository
                                    .GetUnspentAddressesAsync(Currency)
                                    .ConfigureAwait(false))
                                   .ToList();

            if (!transactionType.HasFlag(BlockchainTransactionType.SwapRedeem) &&
                !transactionType.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                unspentAddresses = unspentAddresses
                                   .Where(w => w.Address != toAddress)
                                   .ToList();
            }

            var selectedAddresses = await SelectUnspentAddressesAsync(
                from : unspentAddresses,
                to : toAddress,
                amount : amount,
                fee : fee,
                feePrice : 0,
                feeUsagePolicy : feeUsagePolicy,
                addressUsagePolicy : addressUsagePolicy,
                transactionType : transactionType,
                cancellationToken : cancellationToken)
                                    .ConfigureAwait(false);

            return(ResolvePublicKeys(selectedAddresses
                                     .Select(w => w.WalletAddress)
                                     .ToList()));
        }
Пример #26
0
        private async Task <decimal> StorageFeeByTypeAsync(
            BlockchainTransactionType type,
            string to,
            bool isFirstTx,
            CancellationToken cancellationToken = default)
        {
            var xtz = Xtz;

            var isActive = to != null
                ? await IsAllocatedDestinationAsync(type, to, cancellationToken)
                           .ConfigureAwait(false)
                : false;

            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && isFirstTx)
            {
                return(xtz.InitiateStorageLimit / xtz.StorageFeeMultiplier);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && !isFirstTx)
            {
                return(xtz.AddStorageLimit / xtz.StorageFeeMultiplier);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(isActive
                    ? Math.Max((xtz.RefundStorageLimit - xtz.ActivationStorage) / xtz.StorageFeeMultiplier, 0) // without activation storage fee
                    : xtz.RefundStorageLimit / xtz.StorageFeeMultiplier);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(isActive
                    ? Math.Max((xtz.RedeemStorageLimit - xtz.ActivationStorage) / xtz.StorageFeeMultiplier, 0) // without activation storage fee
                    : xtz.RedeemStorageLimit / xtz.StorageFeeMultiplier);
            }

            return(isActive || !isFirstTx
                ? Math.Max((xtz.StorageLimit - xtz.ActivationStorage) / xtz.StorageFeeMultiplier, 0) // without activation storage fee
                : xtz.StorageLimit / xtz.StorageFeeMultiplier);
        }
Пример #27
0
        private decimal GasLimitByType(BlockchainTransactionType type, bool isFirstTx)
        {
            var eth = Eth;

            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && isFirstTx)
            {
                return(eth.InitiateWithRewardGasLimit);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapPayment) && !isFirstTx)
            {
                return(eth.AddGasLimit);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(eth.RefundGasLimit);
            }
            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(eth.RedeemGasLimit);
            }

            return(eth.GasLimit);
        }
Пример #28
0
        public async Task <bool> IsAllocatedDestinationAsync(
            BlockchainTransactionType type,
            string to,
            CancellationToken cancellationToken = default)
        {
            if (to != null)
            {
                return(await _tezosAllocationChecker
                       .IsAllocatedAsync(to, cancellationToken)
                       .ConfigureAwait(false));
            }

            if (type == BlockchainTransactionType.SwapRedeem) // || type == BlockchainTransactionType.SwapRefund)
            {
                return(false);
            }
            else if (type == BlockchainTransactionType.SwapRefund)
            {
                return(false);
            }

            return(false);
        }
Пример #29
0
        private async Task <decimal> FeeByType(
            BlockchainTransactionType type,
            string from,
            CancellationToken cancellationToken = default)
        {
            var fa12 = Fa12Config;

            var isRevealed = from != null && await _tezosAccount
                             .IsRevealedSourceAsync(from, cancellationToken)
                             .ConfigureAwait(false);

            var revealFeeInTez = !isRevealed
                ? fa12.RevealFee.ToTez()
                : 0;

            if (type.HasFlag(BlockchainTransactionType.TokenApprove))
            {
                return(fa12.ApproveFee.ToTez());
            }

            if (type.HasFlag(BlockchainTransactionType.SwapPayment))
            {
                return(fa12.ApproveFee.ToTez() * 2 + fa12.InitiateFee.ToTez() + revealFeeInTez);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return(fa12.RefundFee.ToTez() + revealFeeInTez);
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return(fa12.RedeemFee.ToTez() + revealFeeInTez);
            }

            return(fa12.TransferFee.ToTez() + revealFeeInTez);
        }
Пример #30
0
        private async Task <decimal> StorageFeeByTypeAsync(
            BlockchainTransactionType type,
            string to,
            CancellationToken cancellationToken = default)
        {
            var xtz = Config;

            var isActive = await IsAllocatedDestinationAsync(to, cancellationToken)
                           .ConfigureAwait(false);

            if (type.HasFlag(BlockchainTransactionType.SwapPayment))
            {
                return((xtz.InitiateStorageLimit * xtz.StorageFeeMultiplier).ToTez());
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRefund))
            {
                return((isActive
                    ? Math.Max((xtz.RefundStorageLimit - xtz.ActivationStorage) * xtz.StorageFeeMultiplier, 0) // without activation storage fee
                    : xtz.RefundStorageLimit *xtz.StorageFeeMultiplier)
                       .ToTez());
            }

            if (type.HasFlag(BlockchainTransactionType.SwapRedeem))
            {
                return((isActive
                    ? Math.Max((xtz.RedeemStorageLimit - xtz.ActivationStorage) * xtz.StorageFeeMultiplier, 0) // without activation storage fee
                    : xtz.RedeemStorageLimit *xtz.StorageFeeMultiplier)
                       .ToTez());
            }

            return((isActive
                ? Math.Max((xtz.StorageLimit - xtz.ActivationStorage) * xtz.StorageFeeMultiplier, 0) // without activation storage fee
                : xtz.StorageLimit *xtz.StorageFeeMultiplier)
                   .ToTez());
        }