예제 #1
0
        public bool AddWalletAddress(WalletAddress address, bool mergePast, out bool empty)
        {
            empty = true;
            if (!AddAddress(address))
            {
                return(false);
            }

            if (address.HDKeySet != null)
            {
                KeyDataTable.GetChild(address.WalletName, address.HDKeySet.Name).Create(Encode(address.ScriptPubKey), address.HDKey, false);
            }

            var entry = address.CreateWalletRuleEntry();

            Indexer.AddWalletRule(entry.WalletId, entry.Rule);
            if (mergePast)
            {
                CancellationTokenSource cancel = new CancellationTokenSource();
                cancel.CancelAfter(10000);
                empty = !Indexer.MergeIntoWallet(address.WalletName, address, entry.Rule, cancel.Token);
            }
            if (!empty)
            {
                GetBalanceSummaryCacheTable(address.WalletName, true).Delete();
                GetBalanceSummaryCacheTable(address.WalletName, false).Delete();
            }
            return(true);
        }
예제 #2
0
        public async Task <bool> SignAsync(
            IAddressBasedTransaction tx,
            WalletAddress address,
            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, cancellationToken)
                             .ConfigureAwait(false);

            if (signResult)
            {
                Log.Verbose("Transaction {@id} successfully signed", tx.Id);
            }
            else
            {
                Log.Error("Transaction {@id} signing error", tx.Id);
            }

            return(signResult);
        }
예제 #3
0
 public override decimal GetRedeemFee(WalletAddress toAddress = null)
 {
     return(RedeemFee.ToTez() + RevealFee.ToTez() + MicroTezReserve.ToTez() +  //todo: define another value for revealed
            (toAddress.AvailableBalance() > 0
             ? 0
             : ActivationStorage / StorageFeeMultiplier));
 }
예제 #4
0
        public Task <bool> TryInsertAddressAsync(WalletAddress walletAddress)
        {
            try
            {
                lock (_syncRoot)
                {
                    using var db = new LiteDatabase(ConnectionString, _bsonMapper);

                    var addresses = db.GetCollection(AddressesCollectionName);
                    addresses.EnsureIndex(IndexKey);
                    addresses.EnsureIndex(CurrencyKey);
                    addresses.EnsureIndex(AddressKey);

                    if (!addresses.Exists(Query.EQ(IdKey, walletAddress.UniqueId)))
                    {
                        var document = _bsonMapper.ToDocument(walletAddress);

                        var id = addresses.Insert(document);

                        return(Task.FromResult(id != null));
                    }

                    return(Task.FromResult(false));
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Error updating address");
            }

            return(Task.FromResult(false));
        }
예제 #5
0
        public Task <bool> UpsertAddressAsync(WalletAddress walletAddress)
        {
            try
            {
                lock (_syncRoot)
                {
                    using var db = new LiteDatabase(ConnectionString, _bsonMapper);

                    var document = _bsonMapper.ToDocument(walletAddress);

                    var addresses = db.GetCollection(AddressesCollectionName);
                    addresses.EnsureIndex(IndexKey);
                    addresses.EnsureIndex(CurrencyKey);
                    addresses.EnsureIndex(AddressKey);
                    var result = addresses.Upsert(document);

                    return(Task.FromResult(result));
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Error updating address");
            }

            return(Task.FromResult(false));
        }
예제 #6
0
        async void CheckFreeUsage()
        {
            if (IsBandwidthWarningDismissed || (LastCheckBandwidthTime.AddSeconds(15) >= DateTime.Now))
            {
                return;
            }

            LastCheckBandwidthTime = DateTime.Now;

            try
            {
                var account = await _tronConnection.Client.GetAccountAsync(new Protocol.Account
                {
                    Address = ByteString.CopyFrom(WalletAddress.Decode58Check(_walletManager.Wallet.Address))
                });

                var accountNet = await _tronConnection.Client.GetAccountNetAsync(new Protocol.Account
                {
                    Address = ByteString.CopyFrom(WalletAddress.Decode58Check(_walletManager.Wallet.Address))
                });

                if (account != null && !account.Address.IsEmpty)
                {
                    var isBandwidthAvailable = false;
                    var token = await _tronConnection.Client.GetAssetIssueByIdAsync(new BytesMessage { Value = ByteString.CopyFromUtf8(AppConstants.TokenID) });


                    if (token != null && !token.OwnerAddress.IsEmpty)
                    {
                        // Check account free usage
                        if (accountNet.AssetNetUsed.ContainsKey(AppConstants.TokenID))
                        {
                            isBandwidthAvailable = (token.PublicFreeAssetNetLimit - accountNet.AssetNetUsed[AppConstants.TokenID]) >= 1000;
                        }
                        else
                        {
                            isBandwidthAvailable = false;
                        }

                        if (isBandwidthAvailable)
                        {
                            // Check total token free bandwidth
                            isBandwidthAvailable = token.FreeAssetNetLimit - token.PublicFreeAssetNetUsage >= 2500;
                        }

                        // Check own account bandwidth and balance
                        if (!isBandwidthAvailable)
                        {
                            isBandwidthAvailable = (accountNet.NetLimit + accountNet.FreeNetLimit - accountNet.NetUsed - accountNet.FreeNetUsed) >= 1000 || account.Balance > 20 * 1000;
                        }

                        IsBandwidthWarningVisible = !isBandwidthAvailable && !IsBandwidthWarningDismissed;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
예제 #7
0
        private async Task <decimal> GetRewardForRedeemAsync(
            WalletAddress walletAddress,
            CancellationToken cancellationToken = default)
        {
            var currency = _account
                           .Currencies
                           .GetByName(walletAddress.Currency);

            var feeCurrency = currency.FeeCurrencyName;

            var feeCurrencyAddress = await _account
                                     .GetAddressAsync(feeCurrency, walletAddress.Address, cancellationToken)
                                     .ConfigureAwait(false);

            if (feeCurrencyAddress == null)
            {
                feeCurrencyAddress = await _account
                                     .DivideAddressAsync(
                    currency : feeCurrency,
                    chain : walletAddress.KeyIndex.Chain,
                    index : walletAddress.KeyIndex.Index)
                                     .ConfigureAwait(false);

                if (feeCurrencyAddress == null)
                {
                    throw new Exception($"Can't get/devide {currency.Name} address {walletAddress.Address} for {feeCurrency}");
                }
            }

            var redeemFee = currency.GetRedeemFee(walletAddress);

            return(feeCurrencyAddress.AvailableBalance() < redeemFee
                ? currency.GetRewardForRedeem()
                : 0);
        }
예제 #8
0
        private async Task <EthereumTransaction> CreateApproveTx(
            WalletAddress walletAddress,
            BigInteger nonce,
            BigInteger value)
        {
            var erc20 = Erc20;

            var message = new ERC20ApproveFunctionMessage
            {
                Spender     = erc20.SwapContractAddress,
                Value       = value,
                FromAddress = walletAddress.Address,
                GasPrice    = Atomex.Ethereum.GweiToWei(erc20.GasPriceInGwei),
                Nonce       = nonce,
            };

            message.Gas = await EstimateGasAsync(message, new BigInteger(erc20.ApproveGasLimit))
                          .ConfigureAwait(false);

            var txInput = message.CreateTransactionInput(erc20.ERC20ContractAddress);

            return(new EthereumTransaction(erc20, txInput)
            {
                Type = BlockchainTransactionType.Output | BlockchainTransactionType.TokenApprove
            });
        }
예제 #9
0
        private async Task <IBitcoinBasedTransaction> SignRedeemTxAsync(
            Swap swap,
            IBitcoinBasedTransaction redeemTx,
            IBitcoinBasedTransaction paymentTx,
            WalletAddress redeemAddress,
            byte[] redeemScript)
        {
            var tx = await new BitcoinBasedSwapSigner(_account)
                     .SignRedeemTxAsync(
                redeemTx: redeemTx,
                paymentTx: paymentTx,
                redeemAddress: redeemAddress,
                secret: swap.Secret,
                redeemScript: redeemScript)
                     .ConfigureAwait(false);

            if (tx == null)
            {
                throw new InternalException(
                          code: Errors.TransactionSigningError,
                          description: $"Redeem tx sign error for swap {swap.Id}");
            }

            return(tx);
        }
        public virtual Task <bool> TryInsertAddressAsync(WalletAddress walletAddress)
        {
            lock (_sync)
            {
                var           walletId = $"{walletAddress.Currency}:{walletAddress.Address}";
                WalletAddress existsAddress;

                if (!_addresses.TryGetValue(walletId, out existsAddress))
                {
                    _addresses[walletId] = walletAddress.Copy();

                    var data = Convert.ToBase64String(BsonSerializer.Serialize(_bsonMapper.ToDocument(walletAddress)));
                    SaveDataCallback?.Invoke(AvailableDataType.WalletAddress, walletId, data);
                    return(Task.FromResult(true));
                }

                if (existsAddress.KeyType != walletAddress.KeyType)
                {
                    existsAddress.KeyType          = walletAddress.KeyType;
                    existsAddress.KeyIndex.Chain   = walletAddress.KeyIndex.Chain;
                    existsAddress.KeyIndex.Index   = walletAddress.KeyIndex.Index;
                    existsAddress.KeyIndex.Account = walletAddress.KeyIndex.Account;
                    _addresses[walletId]           = existsAddress.Copy();

                    var data = Convert.ToBase64String(BsonSerializer.Serialize(_bsonMapper.ToDocument(existsAddress)));
                    SaveDataCallback?.Invoke(AvailableDataType.WalletAddress, walletId, data);
                    return(Task.FromResult(true));
                }

                return(Task.FromResult(false));
            }
        }
예제 #11
0
 public Task <IBitcoinBasedTransaction> SignRefundTxAsync(
     IBitcoinBasedTransaction refundTx,
     IBitcoinBasedTransaction paymentTx,
     WalletAddress refundAddress,
     byte[] redeemScript)
 {
     return(SignHtlcSwapRefundForP2ShTxAsync(refundTx, paymentTx, refundAddress, redeemScript));
 }
예제 #12
0
    //public void FetchCurrentInfoOf(WorkerAddress worker)
    //{
    //    if (worker == null)
    //        return;
    //   // Push(new EthMineRequest_Workers(worker.GetAddress(), worker.GetWorkerName()));


    //}
    public void FetchWorkersOf(WalletAddress wallet)
    {
        if (wallet == null)
        {
            return;
        }
        Push(new EthMineRequest_Workers(wallet.GetAddress()));
    }
        public async Task <IBitcoinBasedTransaction> SignRefundTxAsync(
            IBitcoinBasedTransaction refundTx,
            IBitcoinBasedTransaction paymentTx,
            WalletAddress refundAddress)
        {
            var tx = refundTx.Clone();

            if (tx.Inputs.Length != 1)
            {
                Log.Error("Refund transaction has zero or more than one input");
                return(null);
            }

            var spentOutput = paymentTx.Outputs.FirstOrDefault(o => o.IsSwapPayment);

            if (spentOutput == null)
            {
                Log.Error("Payment transaction hasn't swap output");
                return(null);
            }

            // firstly check, if transaction is already signed
            if (tx.Verify(spentOutput))
            {
                return(tx);
            }

            // clean any signature, if exists
            tx.NonStandardSign(Script.Empty, 0);

            var sigHash = tx.GetSignatureHash(spentOutput);

            var signature = await Account.Wallet
                            .SignHashAsync(
                hash : sigHash,
                address : refundAddress)
                            .ConfigureAwait(false);

            if (signature == null)
            {
                Log.Error("Refund transaction signature error");
                return(null);
            }

            var refundScript = BitcoinBasedSwapTemplate.GenerateHtlcSwapRefund(
                aliceRefundSig: signature,
                aliceRefundPubKey: refundAddress.PublicKeyBytes());

            tx.NonStandardSign(refundScript, spentOutput);

            if (!tx.Verify(spentOutput, out var errors))
            {
                Log.Error("Refund transaction verify errors: {errors}", errors);
                return(null);
            }

            return(tx);
        }
        async void OpenChatCommandExecuted()
        {
            IsBusy = true;
            _userDialogs.ShowLoading(maskType: MaskType.Black);
            try
            {
                await Task.Delay(1000);

                var addressBytes = WalletAddress.Decode58Check(Address);
                if (addressBytes != null)
                {
                    var account = await _tronConnection.Client.GetAccountAsync(new Protocol.Account {
                        Address = ByteString.CopyFrom(addressBytes)
                    });

                    if (!account.Address.IsEmpty)
                    {
                        var group = await _syncServer.GetGroupAsync(Address, _walletManager.Wallet.Address);

                        if (group != null)
                        {
                            var navParams = new NavigationParameters();
                            navParams.Add("group", group);
                            await _navigationService.NavigateAsync("GroupPopupPage", navParams);
                        }
                        else
                        {
                            var user = await _syncServer.GetUserAsync(Address);

                            if (user != null)
                            {
                                var navParams = new NavigationParameters();
                                navParams.Add("address", Address);
                                await _navigationService.NavigateAsync("ChatPage", navParams);
                            }
                            else
                            {
                                _userDialogs.Toast("User is not registered or unable to load");
                            }
                        }
                    }
                    else
                    {
                        _userDialogs.Toast("User or Group is not yet activated");
                    }
                }
                else
                {
                    _userDialogs.Toast("Not an user or group address");
                }
            }
            catch (RpcException ex)
            {
                _userDialogs.Toast("Unable to load user");
            }
            _userDialogs.HideLoading();
            IsBusy = false;
        }
예제 #15
0
        public override async Task <decimal> GetRedeemFeeAsync(
            WalletAddress toAddress             = null,
            CancellationToken cancellationToken = default)
        {
            var feeRate = await GetFeeRateAsync(cancellationToken : cancellationToken)
                          .ConfigureAwait(false);

            return(feeRate * DefaultRedeemTxSize / DigitsMultiplier);
        }
 public WalletAddressViewModel(
     WalletAddress walletAddress,
     string currencyFormat,
     bool isFreeAddress = false)
 {
     WalletAddress  = walletAddress;
     CurrencyFormat = currencyFormat;
     IsFreeAddress  = isFreeAddress;
 }
예제 #17
0
        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));
        }
예제 #18
0
        public void TestPlaceWithdrawal(WalletAddress address, Money amount, string description = null, Money?customFee = null, string authToken = null)
        {
            var p = IsType <IWithdrawalPlacementProvider>();

            if (p.Success)
            {
                PlaceWithdrawal(p.Provider, address, amount, description, customFee, authToken);
            }
        }
예제 #19
0
 public static WalletRuleEntry CreateWalletRuleEntry(this WalletAddress address)
 {
     return(new WalletRuleEntry(address.WalletName, new ScriptRule()
     {
         CustomData = Serializer.ToString(address),
         ScriptPubKey = address.ScriptPubKey,
         RedeemScript = address.RedeemScript
     }));
 }
 public void SetWith(WalletAddress addressName, string workerName)
 {
     if (addressName == null || string.IsNullOrEmpty(addressName.GetAddress()) || string.IsNullOrEmpty(workerName))
     {
         return;
     }
     m_workerName  = workerName;
     m_addressName = addressName;
 }
예제 #21
0
        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));
        }
예제 #22
0
        protected WalletAddress ResolvePublicKey(WalletAddress address)
        {
            address.PublicKey = Wallet.GetAddress(
                currency: Currency,
                chain: address.KeyIndex.Chain,
                index: address.KeyIndex.Index)
                                .PublicKey;

            return(address);
        }
예제 #23
0
 public AddressViewModel(WalletAddress address, IMessenger messenger)
 {
     _Messenger = messenger;
     Address    = address.Address.ToString();
     if (address.KeysetData != null)
     {
         Keyset = address.KeysetData.KeySet.Name;
         Path   = address.KeysetData.State.CurrentPath.ToString();
     }
 }
예제 #24
0
        public WalletAddress GenerateWalletAddress()
        {
            var           keys   = KeySignature.GenerateKeyPairs();
            WalletAddress wallet = new WalletAddress()
            {
                Address    = keys.PublicKey,
                PrivateKey = keys.PrivateKey
            };

            return(wallet);
        }
예제 #25
0
        public static WalletAddress ToWalletAddress(string walletName, KeySetData keysetData, HDKeyData key)
        {
            WalletAddress address = new WalletAddress();

            address.WalletName   = walletName;
            address.RedeemScript = key.RedeemScript;
            address.Address      = key.Address;
            address.HDKey        = key;
            address.HDKeySet     = keysetData.KeySet;
            return(address);
        }
예제 #26
0
        private static JObject ToAdditionalInformation(WalletAddress address, Dictionary <string, JObject> properties)
        {
            JObject obj = new JObject();

            obj.Add("userData", address.UserData ?? new JValue(""));
            foreach (var kv in properties)
            {
                obj.Add(kv.Key, kv.Value);
            }
            return(obj);
        }
        public virtual Task <bool> UpsertAddressAsync(WalletAddress walletAddress)
        {
            lock (_sync)
            {
                var walletId = $"{walletAddress.Currency}:{walletAddress.Address}";

                _addresses[walletId] = walletAddress; // todo: copy?

                return(Task.FromResult(true));
            }
        }
예제 #28
0
        private bool AddAddress(WalletAddress address)
        {
            if (address.Address == null)
            {
                throw new ArgumentException("Address should not be null", "address.Address");
            }

            return(WalletAddressesTable
                   .GetChild(address.WalletName)
                   .Create(address.Address.ToString(), address, false));
        }
예제 #29
0
        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));
        }
예제 #30
0
        public async Task <bool> SignDelegationOperationAsync(
            IKeyStorage keyStorage,
            WalletAddress address,
            CancellationToken cancellationToken = default)
        {
            var xtz = (Atomex.Tezos)Currency;

            if (address.KeyIndex == null)
            {
                Log.Error("Can't find private key for address {@address}", address);
                return(false);
            }

            using var securePrivateKey = keyStorage
                                         .GetPrivateKey(Currency, address.KeyIndex);

            if (securePrivateKey == null)
            {
                Log.Error("Can't find private key for address {@address}", address);
                return(false);
            }

            using var privateKey = securePrivateKey.ToUnsecuredBytes();

            var rpc = new Rpc(xtz.RpcNodeUri);

            Head = await rpc
                   .GetHeader()
                   .ConfigureAwait(false);

            var forgedOpGroup = await rpc
                                .ForgeOperations(Head, Operations)
                                .ConfigureAwait(false);

            var forgedOpGroupLocal = Forge.ForgeOperationsLocal(Head, Operations);

            if (true)  //if (config.CheckForge == true) add option for higher security tezos mode to config
            {
                if (forgedOpGroupLocal.ToString() != forgedOpGroup.ToString())
                {
                    Log.Error("Local and remote forge results differ");
                    return(false);
                }
            }

            SignedMessage = TezosSigner.SignHash(
                data: Hex.FromString(forgedOpGroup.ToString()),
                privateKey: privateKey,
                watermark: Watermark.Generic,
                isExtendedKey: privateKey.Length == 64);

            return(true);
        }