private static IClientTrade[] CreateTradeRecordForClientWithVolumes(LimitQueueItem.LimitTradeInfo trade, ILimitOrder limitOrder, string btcTransactionId, IWalletCredentials walletCredentialsLimitA, IWalletCredentials walletCredentialsLimitB, double limitVolume, double oppositeLimitVolume) { var clientId = walletCredentialsLimitA?.ClientId ?? limitOrder.ClientId; var mutlisig = walletCredentialsLimitA?.MultiSig; var fromMultisig = walletCredentialsLimitB?.MultiSig; var depositAssetRecord = CreateCommonPartForTradeRecord(trade, limitOrder, btcTransactionId); var withdrawAssetRecord = CreateCommonPartForTradeRecord(trade, limitOrder, btcTransactionId); depositAssetRecord.ClientId = withdrawAssetRecord.ClientId = clientId; depositAssetRecord.AddressFrom = withdrawAssetRecord.AddressFrom = fromMultisig; depositAssetRecord.AddressTo = withdrawAssetRecord.AddressTo = mutlisig; depositAssetRecord.Multisig = withdrawAssetRecord.Multisig = mutlisig; depositAssetRecord.Amount = oppositeLimitVolume; depositAssetRecord.AssetId = trade.OppositeAsset; withdrawAssetRecord.Amount = -1 * limitVolume; withdrawAssetRecord.AssetId = trade.Asset; depositAssetRecord.Id = Utils.GenerateRecordId(depositAssetRecord.DateTime); withdrawAssetRecord.Id = Utils.GenerateRecordId(withdrawAssetRecord.DateTime); return(new IClientTrade[] { depositAssetRecord, withdrawAssetRecord }); }
public static IClientTrade[] ToDomainOffchain(this TradeQueueItem item, IWalletCredentials walletCredentialsMarket, IWalletCredentials walletCredentialsLimit, IReadOnlyCollection <IAsset> assets) { var trade = item.Trades[0]; var marketVolume = item.Trades.Sum(x => x.MarketVolume); var limitVolume = item.Trades.Sum(x => x.LimitVolume); var result = new List <IClientTrade>(); result.AddRange(CreateTradeRecordsForClientWithVolumes(trade, item.Order, item.Order.ExternalId, walletCredentialsMarket, walletCredentialsLimit, true, marketVolume, limitVolume)); foreach (var clientTrade in result) { var isBtcAsset = IsBitcoinAsset(assets, clientTrade.AssetId); // if client guarantee transaction, then it is already settled if (clientTrade.ClientId == item.Order.ClientId && clientTrade.Amount < 0) { clientTrade.State = TransactionStates.SettledOffchain; } else { clientTrade.State = isBtcAsset ? TransactionStates.InProcessOnchain : TransactionStates.InProcessOffchain; } } return(result.ToArray()); }
public static string GetDepositAddressForAsset(this IWalletCredentials walletCredentials, Asset asset) { if (asset.Blockchain == Lykke.Service.Assets.Client.Models.Blockchain.Ethereum) { return(null); } switch (asset.Id) { case "BTC": return(walletCredentials.MultiSig); case "SLR": return(walletCredentials.SolarCoinWalletAddress); case "TIME": return(walletCredentials.ChronoBankContract); case "QNT": return(walletCredentials.QuantaContract); default: return(walletCredentials.ColoredMultiSig); } }
public static string GetDepositAddressForAsset(this IWalletCredentials walletCredentials, Asset asset) { if (asset.Blockchain == Blockchain.Ethereum) { return(null); } switch (asset.Id) { case LykkeConstants.BitcoinAssetId: return(walletCredentials.MultiSig); case LykkeConstants.SolarAssetId: return(walletCredentials.SolarCoinWalletAddress); case LykkeConstants.ChronoBankAssetId: return(walletCredentials.ChronoBankContract); case LykkeConstants.QuantaAssetId: return(walletCredentials.QuantaContract); default: return(walletCredentials.ColoredMultiSig); } }
public IEnumerable <string> GetAddresses(IWalletCredentials wallet) { if (IsValidAddress(wallet.EthAddress)) { yield return(wallet.MultiSig); } }
private async Task <OffchainResult> ProcessTransfer(IWalletCredentials credentials, IOffchainTransfer offchainTransfer, string revokePubKey, string encryptedRevokePrivakeKey, string signedCommitment) { var result = await _bitcoinApiClient.Finalize(new FinalizeData { ClientPubKey = credentials.PublicKey, AssetId = offchainTransfer.AssetId, ClientRevokePubKey = revokePubKey, SignedByClientHubCommitment = signedCommitment, ExternalTransferId = offchainTransfer.ExternalTransferId, OffchainTransferId = offchainTransfer.Id }); await _offchainEncryptedKeysRepository.UpdateKey(credentials.ClientId, offchainTransfer.AssetId, encryptedRevokePrivakeKey); if (result.HasError) { return(await InternalErrorProcessing(nameof(ProcessTransfer), result.Error, credentials, offchainTransfer, required : false)); } await _offchainTransferRepository.CompleteTransfer(offchainTransfer.Id, blockchainHash : result.TxHash); await _offchainFinalizeCommandProducer.ProduceFinalize(offchainTransfer.Id, credentials.ClientId, result.TxHash); return(new OffchainResult { TransferId = offchainTransfer.Id, TransactionHex = "0x0", //result.Transaction, OperationResult = OffchainOperationResult.ClientCommitment }); }
public static WalletCredentialsEntity CreateNew(IWalletCredentials src) { var entity = Create(src); entity.PartitionKey = GeneratePartitionKey(); entity.RowKey = GenerateRowKey(src.MultiSig); return(entity); }
public static WalletCredentialsEntity CreateNew(IWalletCredentials src) { var entity = Create(src); entity.PartitionKey = GeneratePartitionKey(); entity.RowKey = GenerateRowKey(src.EthConversionWalletAddress); return(entity); }
public static WalletCredentialsEntity CreateNew(IWalletCredentials src) { var entity = Create(src); entity.PartitionKey = GeneratePartitionKey(); entity.RowKey = GenerateRowKey(src.ChronoBankContract); return(entity); }
public static IClientTrade[] GetTradeRecords(this TradeQueueItem.TradeInfo trade, IMarketOrder marketOrder, string btcTransactionId, IWalletCredentials walletCredentialsMarket, IWalletCredentials walletCredentialsLimit) { var result = new List <IClientTrade>(); result.AddRange(CreateTradeRecordsForClient(trade, marketOrder, btcTransactionId, walletCredentialsMarket, walletCredentialsLimit, true)); result.AddRange(CreateTradeRecordsForClient(trade, marketOrder, btcTransactionId, walletCredentialsMarket, walletCredentialsLimit, false)); return(result.ToArray()); }
public IEnumerable <string> GetAddresses(IWalletCredentials wallet) { if (IsBtcAddress(wallet.MultiSig)) { yield return(wallet.MultiSig); } if (IsBtcAddress(wallet.ColoredMultiSig)) { yield return(wallet.ColoredMultiSig); } }
public Task SaveAsync(IWalletCredentials walletCredentials) { var newByClientEntity = WalletCredentialsEntity.ByClientId.CreateNew(walletCredentials); var newByMultisigEntity = WalletCredentialsEntity.ByMultisig.CreateNew(walletCredentials); var newByColoredEntity = WalletCredentialsEntity.ByColoredMultisig.CreateNew(walletCredentials); var insertByEthTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.EthConversionWalletAddress)) { var newByEthWalletEntity = WalletCredentialsEntity.ByEthContract.CreateNew(walletCredentials); insertByEthTask = _walletCredentialsWalletTable.InsertAsync(newByEthWalletEntity); } var insertBySolarTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.SolarCoinWalletAddress)) { var newBySolarWalletEntity = WalletCredentialsEntity.BySolarCoinWallet.CreateNew(walletCredentials); insertBySolarTask = _walletCredentialsWalletTable.InsertAsync(newBySolarWalletEntity); } var insertByChronoBankTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.ChronoBankContract)) { var newByChronoContractEntity = WalletCredentialsEntity.ByChronoBankContract.CreateNew(walletCredentials); insertByChronoBankTask = _walletCredentialsWalletTable.InsertAsync(newByChronoContractEntity); } var insertByQuantaTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.QuantaContract)) { var newByQuantaContractEntity = WalletCredentialsEntity.ByQuantaContract.CreateNew(walletCredentials); insertByQuantaTask = _walletCredentialsWalletTable.InsertAsync(newByQuantaContractEntity); } var insertMultisigTask = newByMultisigEntity.MultiSig != null? _walletCredentialsWalletTable.InsertAsync(newByMultisigEntity) : Task.CompletedTask; return(Task.WhenAll( _walletCredentialsWalletTable.InsertAsync(newByClientEntity), insertMultisigTask, _walletCredentialsWalletTable.InsertAsync(newByColoredEntity), insertByEthTask, insertBySolarTask, insertByChronoBankTask, insertByQuantaTask )); }
public Task MergeAsync(IWalletCredentials walletCredentials) { var newByClientEntity = WalletCredentialsEntity.ByClientId.CreateNew(walletCredentials); var newByMultisigEntity = WalletCredentialsEntity.ByMultisig.CreateNew(walletCredentials); var newByColoredEntity = WalletCredentialsEntity.ByColoredMultisig.CreateNew(walletCredentials); var insertByEthTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.EthConversionWalletAddress)) { var newByEthWalletEntity = WalletCredentialsEntity.ByEthContract.CreateNew(walletCredentials); insertByEthTask = _tableStorage.InsertOrMergeAsync(newByEthWalletEntity); } var insertBySolarTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.SolarCoinWalletAddress)) { var newBySolarWalletEntity = WalletCredentialsEntity.BySolarCoinWallet.CreateNew(walletCredentials); insertBySolarTask = _tableStorage.InsertOrMergeAsync(newBySolarWalletEntity); } var insertByChronoBankTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.ChronoBankContract)) { var newByChronoContractEntity = WalletCredentialsEntity.ByChronoBankContract.CreateNew(walletCredentials); insertByChronoBankTask = _tableStorage.InsertOrMergeAsync(newByChronoContractEntity); } var insertByQuantaTask = Task.CompletedTask; if (!string.IsNullOrEmpty(walletCredentials.QuantaContract)) { var newByQuantaEntity = WalletCredentialsEntity.ByQuantaContract.CreateNew(walletCredentials); insertByQuantaTask = _tableStorage.InsertOrMergeAsync(newByQuantaEntity); } return(Task.WhenAll( _tableStorage.InsertOrMergeAsync(newByClientEntity), _tableStorage.InsertOrMergeAsync(newByMultisigEntity), _tableStorage.InsertOrMergeAsync(newByColoredEntity), insertByEthTask, insertBySolarTask, insertByChronoBankTask, insertByQuantaTask)); }
public static async Task <IPrivateWallet> GetPrivateWallet(this IPrivateWalletsRepository repo, string address, IWalletCredentials walletCreds, string defaultWalletName) { var wallet = await repo.GetStoredWallet(address); if (wallet == null && walletCreds.Address == address) { wallet = new PrivateWallet { ClientId = walletCreds.ClientId, WalletAddress = walletCreds.Address, WalletName = defaultWalletName }; } return(wallet); }
private async Task <OffchainResult> CreateChannel(IWalletCredentials credentials, IOffchainTransfer offchainTransfer, bool required) { if (offchainTransfer == null || offchainTransfer.ClientId != credentials.ClientId || offchainTransfer.Completed) { throw new OffchainException(ErrorCode.Exception, offchainTransfer?.AssetId); } var fromClient = offchainTransfer.Type == OffchainTransferType.DirectTransferFromClient; var result = await _bitcoinApiClient.CreateChannelAsync(new CreateChannelData { AssetId = offchainTransfer.AssetId, ClientPubKey = credentials.PublicKey, ClientAmount = fromClient ? offchainTransfer.Amount : 0, HubAmount = 0, Required = required, ExternalTransferId = offchainTransfer.ExternalTransferId }); var offchainTransferInfo = (new { offchainTransfer.ClientId, Asset = offchainTransfer.AssetId, offchainTransfer.Amount, offchainTransfer.Type }).ToJson(); if (!result.HasError) { await _offchainTransferRepository.UpdateTransfer(offchainTransfer.Id, result.TransferId?.ToString(), closing : result.ChannelClosing, onchain : true); var offchainResult = new OffchainResult { TransferId = offchainTransfer.Id, TransactionHex = result.Transaction, OperationResult = result.ChannelClosing ? OffchainOperationResult.Transfer : OffchainOperationResult.CreateChannel }; await _logger.WriteInfoAsync("CreateChannel", offchainTransferInfo, $"Offchain channel successfully created: {(new { offchainResult.TransferId, offchainResult.OperationResult }).ToJson()}"); return(offchainResult); } await _logger.WriteErrorAsync("CreateChannel", offchainTransferInfo, new Exception($"{result.Error.Message}, Code: {result.Error.Code} ")); throw new OffchainException(result.Error.ErrorCode, result.Error.Message, result.Error.Code, offchainTransfer.AssetId); }
public static void Update(WalletCredentialsEntity src, IWalletCredentials changed) { src.ClientId = changed.ClientId; src.PrivateKey = changed.PrivateKey; src.Address = changed.Address; src.MultiSig = changed.MultiSig; src.ColoredMultiSig = changed.ColoredMultiSig; src.PreventTxDetection = changed.PreventTxDetection; src.EncodedPrivateKey = changed.EncodedPrivateKey; src.PublicKey = changed.PublicKey; src.BtcConvertionWalletPrivateKey = changed.BtcConvertionWalletPrivateKey; src.BtcConvertionWalletAddress = changed.BtcConvertionWalletAddress; src.EthConversionWalletAddress = changed.EthConversionWalletAddress; src.EthAddress = changed.EthAddress; src.EthPublicKey = changed.EthPublicKey; src.SolarCoinWalletAddress = changed.SolarCoinWalletAddress; src.ChronoBankContract = changed.ChronoBankContract; src.QuantaContract = changed.QuantaContract; }
public static WalletCredentials Create(IWalletCredentials src) { return(new WalletCredentials { ClientId = src.ClientId, Address = src.Address, PrivateKey = src.PrivateKey, MultiSig = src.MultiSig, ColoredMultiSig = src.ColoredMultiSig, PreventTxDetection = src.PreventTxDetection, EncodedPrivateKey = src.EncodedPrivateKey, PublicKey = src.PublicKey, BtcConvertionWalletPrivateKey = src.BtcConvertionWalletPrivateKey, BtcConvertionWalletAddress = src.BtcConvertionWalletAddress, EthConversionWalletAddress = src.EthConversionWalletAddress, EthAddress = src.EthAddress, EthPublicKey = src.EthPublicKey }); }
public static string GetDepositAddressForAsset(this IWalletCredentials walletCredentials, string assetId) { switch (assetId) { case SpecialAssetIds.BitcoinAssetId: return(walletCredentials.MultiSig); case SpecialAssetIds.SolarAssetId: return(walletCredentials.SolarCoinWalletAddress); case SpecialAssetIds.ChronoBankAssetId: return(walletCredentials.ChronoBankContract); case SpecialAssetIds.QuantaAssetId: return(walletCredentials.QuantaContract); default: return(walletCredentials.ColoredMultiSig); } }
public static WalletCredentialsEntity Create(IWalletCredentials src) { return(new WalletCredentialsEntity { ClientId = src.ClientId, PrivateKey = src.PrivateKey, Address = src.Address, MultiSig = src.MultiSig, ColoredMultiSig = src.ColoredMultiSig, PreventTxDetection = src.PreventTxDetection, EncodedPrivateKey = src.EncodedPrivateKey, PublicKey = src.PublicKey, BtcConvertionWalletPrivateKey = src.BtcConvertionWalletPrivateKey, BtcConvertionWalletAddress = src.BtcConvertionWalletAddress, EthConversionWalletAddress = src.EthConversionWalletAddress, EthAddress = src.EthAddress, EthPublicKey = src.EthPublicKey, SolarCoinWalletAddress = src.SolarCoinWalletAddress, ChronoBankContract = src.ChronoBankContract }); }
public static WalletCredentialsHistoryRecord Create(IWalletCredentials creds) { return(new WalletCredentialsHistoryRecord { Address = creds.Address, ClientId = creds.ClientId, ColoredMultiSig = creds.ColoredMultiSig, EncodedPrivateKey = creds.EncodedPrivateKey, MultiSig = creds.MultiSig, PublicKey = creds.PublicKey, PrivateKey = creds.PrivateKey, PreventTxDetection = creds.PreventTxDetection, PartitionKey = GeneratePartitionKey(creds.ClientId), BtcConvertionWalletPrivateKey = creds.BtcConvertionWalletPrivateKey, BtcConvertionWalletAddress = creds.BtcConvertionWalletAddress, EthConversionWalletAddress = creds.EthConversionWalletAddress, EthAddress = creds.EthAddress, EthPublicKey = creds.EthPublicKey, SolarCoinWalletAddress = creds.SolarCoinWalletAddress, ChronoBankContract = creds.ChronoBankContract, QuantaContract = creds.QuantaContract }); }
public static async Task <IEnumerable <IPrivateWallet> > GetAllPrivateWallets(this IPrivateWalletsRepository repo, string clientId, IWalletCredentials walletCreds, string defaultWalletName = "default") { var storedWallets = (await repo.GetStoredWallets(clientId))?.ToArray(); var wallets = new List <IPrivateWallet>((storedWallets?.Length ?? 0) + 1); if (walletCreds != null) { wallets.Add(new PrivateWallet { ClientId = walletCreds.ClientId, WalletAddress = walletCreds.Address, BlockchainType = Lykke.Service.Assets.Client.Models.Blockchain.Bitcoin, WalletName = defaultWalletName, }); } if (storedWallets != null) { wallets.AddRange(storedWallets); } return(wallets); }
private async Task <OffchainResult> InternalErrorProcessing(string process, ErrorResponse error, IWalletCredentials credentials, IOffchainTransfer offchainTransfer, bool required) { if (error.ErrorCode == ErrorCode.ShouldOpenNewChannel) { return(await CreateChannel(credentials, offchainTransfer, required)); } var offchainTransferInfo = (new { offchainTransfer.ClientId, Asset = offchainTransfer.AssetId, offchainTransfer.Amount, offchainTransfer.Type }).ToJson(); await _logger.WriteErrorAsync(process, offchainTransferInfo, new Exception($"{error.Message}, Code: {error.Code}")); throw new OffchainException(error.ErrorCode, error.Message, error.Code, offchainTransfer.AssetId); }
public static IClientTrade[] ToDomainOffchain(this LimitQueueItem.LimitOrderWithTrades item, string btcTransactionId, IWalletCredentials walletCredentialsLimitA, IWalletCredentials walletCredentialsLimitB) { var trade = item.Trades[0]; var limitVolume = item.Trades.Sum(x => x.Volume); var oppositeLimitVolume = item.Trades.Sum(x => x.OppositeVolume); var result = new List <IClientTrade>(); result.AddRange(CreateTradeRecordForClientWithVolumes(trade, item.Order, btcTransactionId, walletCredentialsLimitA, walletCredentialsLimitB, limitVolume, oppositeLimitVolume)); foreach (var clientTrade in result) { clientTrade.State = clientTrade.Amount < 0 ? TransactionStates.SettledOffchain : TransactionStates.InProcessOffchain; } return(result.ToArray()); }
private static IClientTrade[] CreateTradeRecordsForClientWithVolumes(TradeQueueItem.TradeInfo trade, IMarketOrder marketOrder, string btcTransactionId, IWalletCredentials walletCredentialsMarket, IWalletCredentials walletCredentialsLimit, bool isMarketClient, double marketVolume, double limitVolume) { var clientId = isMarketClient ? walletCredentialsMarket?.ClientId : walletCredentialsLimit?.ClientId; if (!isMarketClient && string.IsNullOrWhiteSpace(clientId)) { return(new IClientTrade[0]); } clientId = clientId ?? marketOrder.ClientId; var mutlisig = isMarketClient ? walletCredentialsMarket?.MultiSig : walletCredentialsLimit?.MultiSig; var fromMultisig = isMarketClient ? walletCredentialsLimit?.MultiSig : walletCredentialsMarket?.MultiSig; var marketAssetRecord = CreateCommonPartForTradeRecord(trade, marketOrder, btcTransactionId); var limitAssetRecord = CreateCommonPartForTradeRecord(trade, marketOrder, btcTransactionId); marketAssetRecord.ClientId = limitAssetRecord.ClientId = clientId; marketAssetRecord.AddressFrom = limitAssetRecord.AddressFrom = fromMultisig; marketAssetRecord.AddressTo = limitAssetRecord.AddressTo = mutlisig; marketAssetRecord.Multisig = limitAssetRecord.Multisig = mutlisig; marketAssetRecord.Amount = marketVolume * (isMarketClient ? -1 : 1); marketAssetRecord.AssetId = trade.MarketAsset; limitAssetRecord.Amount = limitVolume * (isMarketClient ? 1 : -1); limitAssetRecord.AssetId = trade.LimitAsset; marketAssetRecord.Id = Utils.GenerateRecordId(marketAssetRecord.DateTime); limitAssetRecord.Id = Utils.GenerateRecordId(limitAssetRecord.DateTime); return(new IClientTrade[] { marketAssetRecord, limitAssetRecord }); }
private static IClientTrade[] CreateTradeRecordsForClient(TradeQueueItem.TradeInfo trade, IMarketOrder marketOrder, string btcTransactionId, IWalletCredentials walletCredentialsMarket, IWalletCredentials walletCredentialsLimit, bool isMarketClient) { return(CreateTradeRecordsForClientWithVolumes(trade, marketOrder, btcTransactionId, walletCredentialsMarket, walletCredentialsLimit, isMarketClient, trade.MarketVolume, trade.LimitVolume)); }
public async Task InsertHistoryRecord(IWalletCredentials oldWalletCredentials) { var entity = WalletCredentialsHistoryRecord.Create(oldWalletCredentials); await _tableStorage.InsertAndGenerateRowKeyAsDateTimeAsync(entity, DateTime.UtcNow); }
public async Task <IBcnCredentialsRecord> GenerateWallets(Guid clientId) { var network = _btcSettings.NetworkType == NetworkType.Main ? Network.Main : Network.TestNet; var wallets = await GetWalletsForPubKey(); IBcnCredentialsRecord bcnCreds; var currentWalletCreds = await _walletCredentialsRepository.GetAsync(clientId); if (currentWalletCreds == null) { var btcConvertionWallet = GetNewAddressAndPrivateKey(network); IWalletCredentials walletCreds = WalletCredentials.Create( clientId.ToString(), null, null, null, wallets.ColoredMultiSigAddress, btcConvertionWallet.PrivateKey, btcConvertionWallet.Address, encodedPk: "", pubKey: ""); bcnCreds = BcnCredentialsRecord.Create(SpecialAssetIds.BitcoinAssetId, clientId.ToString(), null, wallets.SegwitAddress, ""); await Task.WhenAll( _walletCredentialsRepository.SaveAsync(walletCreds), _walletCredentialsRepository.SaveAsync(bcnCreds) ); } else { //walletCreds = WalletCredentials.Create( // clientId.ToString(), // null, // null, // null, // wallets.ColoredMultiSigAddress, // null, // null, // encodedPk: "", // pubKey: ""); bcnCreds = await _walletCredentialsRepository.GetBcnCredsAsync(SpecialAssetIds.BitcoinAssetId, clientId); if (bcnCreds == null) { bcnCreds = BcnCredentialsRecord.Create( SpecialAssetIds.BitcoinAssetId, clientId.ToString(), null, wallets.SegwitAddress, "" ); await _walletCredentialsRepository.SaveAsync(bcnCreds); } //await _walletCredentialsHistoryRepository.InsertHistoryRecord(currentWalletCreds); //await _walletCredentialsRepository.Merge(walletCreds); } return(bcnCreds); }
public static async Task <IEnumerable <IPrivateWallet> > GetAllPrivateWallets(this IPrivateWalletsRepository repo, string clientId, IWalletCredentials walletCreds, string defaultWalletName) { var wallets = (await repo.GetStoredWallets(clientId)).ToList(); IPrivateWallet defaultWallet = new PrivateWallet { ClientId = walletCreds.ClientId, WalletAddress = walletCreds.Address, WalletName = defaultWalletName }; wallets.Add(defaultWallet); return(wallets); }