public async Task TestCommentAsync() { var url = "https://dealer.devnet.lyra.live:7070"; var dealer = new DealerClient(new Uri(new Uri(url), "/api/dealer/")); var(pvt, pub) = Signatures.GenerateWallet(); var tradid = "L8FufT33KuUrAsHYgCC1zo4gVRdZA8WBS7SMM8Tevq74B4N4wemz5mBh8CqCmgS3vKa4TiTsVH5kMi49Gn4962hfn8JcT7"; var cfg = new CommentConfig(); cfg.TradeId = tradid; cfg.Content = "hahaha"; cfg.Title = "title"; cfg.ByAccountId = pub; cfg.Created = DateTime.UtcNow; cfg.EncContent = Convert.ToBase64String(Encoding.UTF8.GetBytes(cfg.Content)); cfg.EncTitle = Convert.ToBase64String(Encoding.UTF8.GetBytes(cfg.Title)); cfg.Sign(pvt, pub); //var result = await dealer.CommentTradeAsync(cfg); //Assert.IsTrue(result.Successful(), $"comment failed: {result.ResultCode}"); //var cmnts = await dealer.GetCommentsForTradeAsync(tradid); //Assert.IsTrue(cmnts.Count == 1, $"no comment found."); //Assert.IsTrue(cmnts.First().Content == cfg.Content); }
public async Task TestGetPriceAsync() { var url = "https://dealer.devnet.lyra.live:7070"; var dealer = new DealerClient(new Uri(new Uri(url), "/api/dealer/")); var prices = await dealer.GetPricesAsync(); Assert.IsTrue(prices.ContainsKey("LYR")); Assert.IsTrue(prices.ContainsKey("BTC")); Assert.IsTrue(prices.ContainsKey("LYR_INT")); }
public async Task TestGetFiatAsync() { var url = "https://dealer.devnet.lyra.live:7070"; var dealer = new DealerClient(new Uri(new Uri(url), "/api/dealer/")); var usd = await dealer.GetFiatAsync("USD"); Assert.IsNotNull(usd); Assert.AreEqual("US Dollar", usd.name); var ddd = await dealer.GetFiatAsync("DDD"); Assert.IsNull(ddd); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 4 || !send.Tags.ContainsKey("tradeid") || string.IsNullOrWhiteSpace(send.Tags["tradeid"]) || !send.Tags.ContainsKey("orderid") || string.IsNullOrWhiteSpace(send.Tags["orderid"]) || !send.Tags.ContainsKey("daoid") || string.IsNullOrWhiteSpace(send.Tags["daoid"]) ) { return(APIResultCodes.InvalidBlockTags); } var tradeid = send.Tags["tradeid"]; var orderid = send.Tags["orderid"]; var daoid = send.Tags["daoid"]; var tradeblk = await sys.Storage.FindLatestBlockAsync(tradeid); var daoblk = await sys.Storage.FindLatestBlockAsync((tradeblk as IOtcTrade).Trade.daoId); if (daoblk == null || tradeblk == null || (daoblk as TransactionBlock).AccountID != daoid || (tradeblk as IOtcTrade).Trade.daoId != (daoblk as TransactionBlock).AccountID) { return(APIResultCodes.InvalidTrade); } if ((tradeblk as IBrokerAccount).OwnerAccountId != send.AccountID) { return(APIResultCodes.InvalidTrade); } if ((tradeblk as IOtcTrade).OTStatus != OTCTradeStatus.Open) { return(APIResultCodes.InvalidTrade); } var orderblk = await sys.Storage.FindLatestBlockAsync(orderid); if (orderblk == null || (tradeblk as IOtcTrade).Trade.orderId != orderid || (tradeblk as IOtcTrade).Trade.daoId != daoid) { return(APIResultCodes.InvalidTrade); } if (Settings.Default.LyraNode.Lyra.NetworkId != "xtest") { // check if trade is cancellable var lsb = sys.Storage.GetLastServiceBlock(); var wallet = sys.PosWallet; var sign = Signatures.GetSignature(wallet.PrivateKey, lsb.Hash, wallet.AccountId); var dlrblk = await sys.Storage.FindLatestBlockAsync((tradeblk as IOtcTrade).Trade.dealerId); var uri = new Uri(new Uri((dlrblk as IDealer).Endpoint), "/api/dealer/"); var dealer = new DealerClient(uri); var ret = await dealer.GetTradeBriefAsync(tradeid, wallet.AccountId, sign); if (!ret.Successful() || !ret.Deserialize <TradeBrief>().IsCancellable) { return(APIResultCodes.InvalidOperation); } } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 2 || !send.Tags.ContainsKey("data") || string.IsNullOrWhiteSpace(send.Tags["data"]) ) { return(APIResultCodes.InvalidBlockTags); } OTCTrade trade; try { trade = JsonConvert.DeserializeObject <OTCTrade>(send.Tags["data"]); } catch (Exception ex) { return(APIResultCodes.InvalidBlockTags); } // daoId var dao = await sys.Storage.FindLatestBlockAsync(trade.daoId); if (dao == null || (dao as TransactionBlock).AccountID != send.DestinationAccountId) { return(APIResultCodes.InvalidOrgnization); } // orderId var orderblk = await sys.Storage.FindLatestBlockAsync(trade.orderId) as IOtcOrder; if (orderblk == null) { return(APIResultCodes.InvalidOrder); } var order = orderblk.Order; if (order.daoId != trade.daoId || order.dealerId != trade.dealerId || order.crypto != trade.crypto || order.fiat != trade.fiat || order.price != trade.price || order.amount < trade.amount || order.dir == trade.dir || orderblk.OwnerAccountId != trade.orderOwnerId || trade.pay > order.limitMax || trade.pay < order.limitMin || !order.payBy.Contains(trade.payVia) ) { return(APIResultCodes.InvalidTrade); } // pay if (trade.pay != Math.Round(trade.pay, 2)) { return(APIResultCodes.InvalidTradeAmount); } var got = Math.Round(trade.pay / order.price, 8); if (got != trade.amount) { return(APIResultCodes.InvalidTradeAmount); } // verify collateral var chgs = send.GetBalanceChanges(last); if (!chgs.Changes.ContainsKey(LyraGlobal.OFFICIALTICKERCODE) || chgs.Changes[LyraGlobal.OFFICIALTICKERCODE] < trade.collateral) { return(APIResultCodes.InvalidCollateral); } // check the price of order and collateral. var dlrblk = await sys.Storage.FindLatestBlockAsync(trade.dealerId); var uri = new Uri(new Uri((dlrblk as IDealer).Endpoint), "/api/dealer/"); var dealer = new DealerClient(uri); var prices = await dealer.GetPricesAsync(); var tokenSymbol = order.crypto.Split('/')[1]; if (trade.collateral * prices["LYR"] < prices[tokenSymbol] * trade.amount * ((dao as IDao).BuyerPar / 100)) { return(APIResultCodes.CollateralNotEnough); } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 2 || !send.Tags.ContainsKey("data") || string.IsNullOrWhiteSpace(send.Tags["data"]) ) { return(APIResultCodes.InvalidBlockTags); } OTCOrder order; try { order = JsonConvert.DeserializeObject <OTCOrder>(send.Tags["data"]); } catch (Exception ex) { return(APIResultCodes.InvalidBlockTags); } // daoid var dao = await sys.Storage.FindLatestBlockAsync(order.daoId); if (string.IsNullOrEmpty(order.daoId) || dao == null || (dao as TransactionBlock).AccountID != send.DestinationAccountId) { return(APIResultCodes.InvalidOrgnization); } // verify Dealer exists var dlr = await sys.Storage.FindLatestBlockAsync(order.dealerId); if (string.IsNullOrEmpty(order.dealerId) || dlr == null || dlr is not DealerGenesisBlock) { return(APIResultCodes.InvalidDealerServer); } // check every field of Order // dir, priceType if (order.dir != TradeDirection.Sell || order.priceType != PriceType.Fixed) { return(APIResultCodes.InvalidTagParameters); } // crypto var tokenGenesis = await sys.Storage.FindTokenGenesisBlockAsync(null, order.crypto); if (tokenGenesis == null) { return(APIResultCodes.TokenNotFound); } // fiat if (!FIATS.Contains(order.fiat)) { return(APIResultCodes.Unsupported); } // price, amount if (order.price <= 0.00001m || order.amount < 0.0001m) { return(APIResultCodes.InvalidAmount); } // payBy if (order.payBy == null || order.payBy.Length == 0) { return(APIResultCodes.InvalidOrder); } // verify collateral var chgs = send.GetBalanceChanges(last); if (!chgs.Changes.ContainsKey(LyraGlobal.OFFICIALTICKERCODE) || chgs.Changes[LyraGlobal.OFFICIALTICKERCODE] < order.collateral) { return(APIResultCodes.InvalidCollateral); } // check the price of order and collateral. var dlrblk = await sys.Storage.FindLatestBlockAsync(order.dealerId); var uri = new Uri(new Uri((dlrblk as IDealer).Endpoint), "/api/dealer/"); var dealer = new DealerClient(uri); var prices = await dealer.GetPricesAsync(); var tokenSymbol = order.crypto.Split('/')[1]; if (order.collateralPrice != prices["LYR"] || order.fiatPrice != prices[order.fiat.ToLower()]) { return(APIResultCodes.PriceChanged); } if (order.collateral * prices["LYR"] < prices[tokenSymbol] * order.amount * ((dao as IDao).SellerPar / 100)) { return(APIResultCodes.CollateralNotEnough); } if (order.collateralPrice != prices["LYR"]) { return(APIResultCodes.PriceChanged); } decimal usdprice = 0; if (tokenSymbol == "ETH") { usdprice = prices["ETH"]; } if (tokenSymbol == "BTC") { usdprice = prices["BTC"]; } if (tokenSymbol == "USDT") { usdprice = prices["USDT"]; } var selcryptoprice = Math.Round(usdprice / prices[order.fiat.ToLower()], 2); var total = selcryptoprice * order.amount; // limit if (order.limitMin <= 0 || order.limitMax < order.limitMin || order.limitMax > total) { return(APIResultCodes.InvalidArgument); } return(APIResultCodes.Success); }