internal static string GetAddressSignature(string privateKey, ECurrency currency, Environment environment) { if (string.IsNullOrWhiteSpace(privateKey)) { throw new ArgumentNullException(nameof(privateKey)); } string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(); string signature = null; if (currency == ECurrency.BTC) { BitcoinSecret secret = new BitcoinSecret(privateKey, environment.Network); signature = secret.PrivateKey.SignMessage(timestamp); } else if (currency.IsGluwaCoinCurrency()) { var signer = new EthereumMessageSigner(); signature = signer.EncodeUTF8AndSign(timestamp, new EthECKey(privateKey)); } else { throw new ArgumentOutOfRangeException($"Unsupported currency: {currency}"); } string signatureToEncode = $"{timestamp}.{signature}"; byte[] signatureByte = Encoding.UTF8.GetBytes(signatureToEncode); string encodedData = Convert.ToBase64String(signatureByte); return(encodedData); }
/// <summary> /// Accept quote received from POST /v1/Quote endpoint. /// </summary> /// <param name="currency">The source currency of the quote.</param> /// <param name="address">The sending address of the quote.</param> /// <param name="privateKey">The privateKey of the sending address.</param> /// <param name="quoteRequest">Request body.</param> /// <response code="202">Quote is accepted.</response> /// <response code="400_InvalidUrlParameters">Invalid URL parameters.</response> /// <response code="400_MissingBody">Request body is missing.</response> /// <response code="400_InvalidBody">Request validation errors. See InnerErrors.</response> /// <response code="400_ValidationError">Request validation errors. See InnerErrors.</response> /// <response code="403">Invalid checksum. Checksum may be wrong or expired.</response> /// <response code="404">One of the matched orders are no longer available.</response> /// <response code="500">Server error.</response> /// <returns></returns> public async Task <Result <AcceptQuoteResponse, ErrorResponse> > AcceptQuoteAsync( ECurrency currency, string address, string privateKey, AcceptQuoteRequest quoteRequest) { #region if (!currency.IsGluwaExchangeCurrency()) { throw new ArgumentOutOfRangeException($"Unsupported currency: {currency}"); } foreach (var order in quoteRequest.MatchedOrders) { IEnumerable <ValidationResult> validation = quoteRequest.Validate(currency); if (validation.Any()) { foreach (var item in validation) { throw new ArgumentNullException(item.ErrorMessage); } } } if (string.IsNullOrWhiteSpace(address)) { throw new ArgumentNullException(nameof(address)); } else if (string.IsNullOrWhiteSpace(privateKey)) { throw new ArgumentNullException(nameof(privateKey)); } #endregion var result = new Result <AcceptQuoteResponse, ErrorResponse>(); string requestUri = $"{mEnv.BaseUrl}/v1/Quote"; List <MatchedOrderRequest> matchedOrders = new List <MatchedOrderRequest>(); foreach (var matchedOrder in quoteRequest.MatchedOrders) { if (currency.IsGluwaCoinCurrency()) { BigInteger nonce = BigInteger.Parse(GluwaService.GetNonceString()); BigInteger convertExpiryBlockNumber = BigInteger.Parse(matchedOrder.ExpiryBlockNumber); string signature = getGluwacoinReserveTxnSignature( currency, address, matchedOrder.SourceAmount, matchedOrder.Fee, matchedOrder.DestinationAddress, matchedOrder.Executor, nonce, convertExpiryBlockNumber, privateKey); MatchedOrderRequest matchedOrderRequest = new MatchedOrderRequest() { OrderID = matchedOrder.OrderID, ReserveTxnSignature = signature, Nonce = nonce.ToString() }; matchedOrders.Add(matchedOrderRequest); } else { BtcTxnSignature txnSignature = await getBtcTxnSignaturesAsync( currency, address, matchedOrder.SourceAmount, matchedOrder.Fee, matchedOrder.DestinationAddress, matchedOrder.ReservedFundsAddress, matchedOrder.ReservedFundsRedeemScript, privateKey); MatchedOrderRequest matchedOrderRequest = new MatchedOrderRequest() { OrderID = matchedOrder.OrderID, ReserveTxnSignature = txnSignature.ReserveTxnSignature, ExecuteTxnSignature = txnSignature.ExecuteTxnSignature, ReclaimTxnSignature = txnSignature.ReclaimTxnSignature }; matchedOrders.Add(matchedOrderRequest); } } PutQuoteRequest bodyParams = new PutQuoteRequest() { MatchedOrders = matchedOrders, Checksum = quoteRequest.Checksum }; string json = bodyParams.ToJson(); StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); try { using (HttpClient httpClient = new HttpClient()) using (HttpResponseMessage response = await httpClient.PutAsync(requestUri, content)) { if (response.IsSuccessStatusCode) { AcceptQuoteResponse quoteResponse = await response.Content.ReadAsAsync <AcceptQuoteResponse>(); result.IsSuccess = true; result.Data = quoteResponse; return(result); } string contentString = await response.Content.ReadAsStringAsync(); result.Error = ResponseHandler.GetError(response.StatusCode, requestUri, contentString); } } catch (HttpRequestException) { result.IsSuccess = false; result.Error = ResponseHandler.GetExceptionError(); } return(result); }