示例#1
0
        private async Task <Result <FeeResponse, ErrorResponse> > getFeeAsync(ECurrency currency)
        {
            var    result     = new Result <FeeResponse, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/{currency}/Fee";

            try
            {
                using (HttpClient httpClient = new HttpClient())
                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        FeeResponse feeResponse = await response.Content.ReadAsAsync <FeeResponse>();

                        if (response.IsSuccessStatusCode)
                        {
                            result.IsSuccess = true;
                            result.Data      = feeResponse;

                            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);
        }
示例#2
0
        /// <summary>
        /// Cancel an order.
        /// </summary>
        /// <param name="apiKey">Your apiKey.</param>
        /// <param name="apiSecret">Your apiSecretKey.</param>
        /// <param name="ID">Order ID.</param>
        /// <response code="200">Order is canceled.</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">Not authorized to use this endpoint.</response>
        /// <response code="404">Order is not found.</response>
        /// <response code="409">Cannot be canceled.</response>
        /// <response code="500">Server error.</response>
        /// <returns></returns>
        public async Task <Result <bool, ErrorResponse> > CancelOrderAsync(string apiKey, string apiSecret, Guid?ID)
        {
            #region
            if (ID == null || ID == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(ID));
            }
            #endregion

            string token = getAuthToken(apiKey, apiSecret);

            var    result     = new Result <bool, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/Orders/{ID}";

            CancelOrderRequest bodyParams = new CancelOrderRequest();

            string        json    = bodyParams.ToJson();
            StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

            HttpRequestMessage request = new HttpRequestMessage
            {
                Method     = new HttpMethod("PATCH"),
                RequestUri = new Uri(requestUri),
                Content    = content
            };

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(AUTHORIZATION, $"{BASIC} {token}");

                    using (HttpResponseMessage response = await httpClient.SendAsync(request))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            result.IsSuccess = true;
                            result.Data      = true;

                            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);
        }
示例#3
0
        /// <summary>
        /// Get an accepted quote with ID.
        /// </summary>
        /// <param name="currency">The source currency of the quote.</param>
        /// <param name="privateKey">The privateKey of the sending address of the quote.</param>
        /// <param name="ID">ID of the accepted quote.</param>
        /// <response code="200">The quote with a specified ID.</response>
        /// <response code="400_InvalidUrlParameters">Invalid URL parameters.</response>
        /// <response code="403_SignatureMissing">X-REQUEST-SIGNATURE header is missing.</response>
        /// <response code="403_SignatureExpired">X-REQUEST-SIGNATURE has expired.</response>
        /// <response code="403_InvalidSignature">Invalid X-REQUEST-SIGNATURE.</response>
        /// <response code="404">Quote is not found.</response>
        /// <response code="500">Server error.</response>
        /// <returns></returns>
        public async Task <Result <GetQuoteResponse, ErrorResponse> > GetQuoteAsync(ECurrency currency, string privateKey, Guid?ID)
        {
            #region
            if (!currency.IsGluwaExchangeCurrency())
            {
                throw new ArgumentOutOfRangeException($"Unsupported currency: {currency}");
            }

            if (ID == null || ID == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(ID));
            }
            #endregion

            var    result     = new Result <GetQuoteResponse, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/Quotes/{ID}";

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(X_REQUEST_SIGNATURE, GluwaService.GetAddressSignature(privateKey, currency, mEnv));

                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            GetQuoteResponse quoteResponse = await response.Content.ReadAsAsync <GetQuoteResponse>();

                            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);
        }
示例#4
0
        /// <summary>
        /// Get balance for specified currency.
        /// </summary>
        /// <param name="currency">Currency type.</param>
        /// <param name="address">Your public Address.</param>
        /// <param name="includeUnspentOutputs">(For BTC only) if "true", the response includes unspent outputs for the address. "false" by default.</param>
        /// <response code="200">Balance and associated currency.</response>
        /// <response code="400">Invalid address format.</response>
        /// <response code="500">Server error.</response>
        /// <response code="503">Service unavailable for the specified currency or temporarily.</response>
        public async Task <Result <BalanceResponse, ErrorResponse> > GetBalanceAsync(ECurrency currency, string address, bool includeUnspentOutputs = false)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException(nameof(address));
            }

            var    result     = new Result <BalanceResponse, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/{currency}/Addresses/{address}";

            List <string> queryParams = new List <string>();

            queryParams.Add($"includeUnspentOutputs={includeUnspentOutputs}");

            if (queryParams.Any())
            {
                requestUri = $"{requestUri}?{string.Join("&", queryParams)}";
            }

            try
            {
                using (HttpClient httpClient = new HttpClient())
                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            BalanceResponse balanceResponse = await response.Content.ReadAsAsync <BalanceResponse>();

                            result.IsSuccess = true;
                            result.Data      = balanceResponse;

                            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);
        }
示例#5
0
        /// <summary>
        /// Retrieve an order with specified ID.
        /// </summary>
        /// <param name="apiKey">Your apiKey.</param>
        /// <param name="apiSecret">Your apiSecretKey.</param>
        /// <param name="ID">The ID of an order.</param>
        /// <response code="200">The order with a specified ID.</response>
        /// <response code="400_InvalidUrlParameters">Invalid URL parameters.</response>
        /// <response code="403">Not authorized to use this endpoint.</response>
        /// <response code="404">Order is not found.</response>
        /// <response code="500">Server error.</response>
        /// <returns></returns>
        public async Task <Result <GetOrderResponse, ErrorResponse> > GetOrderAsync(string apiKey, string apiSecret, Guid?ID)
        {
            #region
            if (ID == null || ID == Guid.Empty)
            {
                throw new ArgumentNullException(nameof(ID));
            }
            #endregion

            string token = getAuthToken(apiKey, apiSecret);

            var    result     = new Result <GetOrderResponse, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/Orders/{ID}";

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(AUTHORIZATION, $"{BASIC} {token}");

                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            GetOrderResponse orderResponse = await response.Content.ReadAsAsync <GetOrderResponse>();

                            result.IsSuccess = true;
                            result.Data      = orderResponse;

                            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);
        }
示例#6
0
        /// <summary>
        /// Get bitcoin or gluwacoin transaction by hash.
        /// </summary>
        /// <param name="currency">Currency type</param>
        /// <param name="privateKey">Your Private Key.</param>
        /// <param name="txnHash">Hash of the transaction on the blockchain.</param>
        /// <response code="200">Transaction response.</response>
        /// <response code="400">Invalid transaction hash format.</response>
        /// <response code="403">Request signature header is not valid.</response>
        /// <response code="404">Tranasction not found.</response>
        /// <response code="500">Server error.</response>
        /// <response code="503">Service unavailable.</response>
        public async Task <Result <TransactionResponse, ErrorResponse> > GetTransactionDetailsAsync(ECurrency currency, string privateKey, string txnHash)
        {
            if (string.IsNullOrWhiteSpace(privateKey))
            {
                throw new ArgumentNullException(nameof(privateKey));
            }
            else if (string.IsNullOrWhiteSpace(txnHash))
            {
                throw new ArgumentNullException(nameof(txnHash));
            }

            var    result     = new Result <TransactionResponse, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/{currency}/Transactions/{txnHash}";

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(X_REQUEST_SIGNATURE, GluwaService.GetAddressSignature(privateKey, currency, mEnv));

                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            TransactionResponse transactionResponse = await response.Content.ReadAsAsync <TransactionResponse>();

                            result.IsSuccess = true;
                            result.Data      = transactionResponse;

                            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);
        }
示例#7
0
        /// <summary>
        /// Get current order book.
        /// </summary>
        /// <param name="conversion">Conversion symbol.</param>
        /// <param name="limit">Number of orders to include in the result. Ordered by descending price (best price first). Defaults to 100, maximum of 1000.</param>
        /// <response code="200">List of active orders</response>
        /// <response code="400">Invalid request parameters.</response>
        /// <returns></returns>
        public async Task <Result <List <GetOrderBookResponse>, ErrorResponse> > GetOrderBook(EConversion conversion, uint limit = 100)
        {
            var    result     = new Result <List <GetOrderBookResponse>, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/OrderBook/{conversion}";

            List <string> queryParams = new List <string>();

            queryParams.Add($"limit={limit}");

            if (queryParams.Any())
            {
                requestUri = $"{requestUri}?{string.Join("&", queryParams)}";
            }

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            List <GetOrderBookResponse> orderBookResponse = await response.Content.ReadAsAsync <List <GetOrderBookResponse> >();

                            result.IsSuccess = true;
                            result.Data      = orderBookResponse;

                            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);
        }
示例#8
0
        /// <summary>
        /// Generates a one-time use QR code for merchants, used for making a payment transaction. Returns an image in a .jpg or .png format.
        /// </summary>
        /// <param name="apiKey">Your API Key.</param>
        /// <param name="secret">Your API Secret.</param>
        /// <param name="address">Your public address.</param>
        /// <param name="privateKey">Your private Key.</param>
        /// <param name="currency">Currency type.</param>
        /// <param name="amount">Payment amount. Fee will be deducted from this amount when payment request is made.</param>
        /// <param name="format">Desired image format, optional. Defaults to base64 string</param>
        /// <param name="note">Additional information, used by the merchant user. optional.</param>
        /// <param name="merchantOrderID">Identifier for the payment, used by the merchant user. optional.</param>
        /// <param name="expiry">Time of expiry for the QR code in seconds. Payment request must be made with this QR code before this time. optional. Defaults to 1800</param>
        /// <response code="200">QR code image in a .png by default or .jpg depending on the format query parameter.</response>
        /// <response code="400">Validation error. Please see inner errors for more details. or API Key and secret request header is missing or invalid.</response>
        /// <response code="403">Combination of Api Key and Api Secret was not found.</response>
        /// <response code="500">Server error.</response>
        /// <response code="503">Service unavailable for the provided currency.</response>
        public async Task <Result <string, ErrorResponse> > GetPaymentQRCodeAsync(
            string apiKey,
            string secret,
            string address,
            string privateKey,
            EPaymentCurrency currency,
            string amount,
            string format          = null,
            string note            = null,
            string merchantOrderID = null,
            int expiry             = 1800
            )
        {
            if (string.IsNullOrWhiteSpace(apiKey))
            {
                throw new ArgumentNullException(nameof(apiKey));
            }
            else if (string.IsNullOrWhiteSpace(secret))
            {
                throw new ArgumentNullException(nameof(secret));
            }
            else if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException(nameof(address));
            }
            else if (string.IsNullOrWhiteSpace(privateKey))
            {
                throw new ArgumentNullException(nameof(privateKey));
            }
            else if (string.IsNullOrWhiteSpace(amount))
            {
                throw new ArgumentNullException(nameof(amount));
            }

            var result     = new Result <string, ErrorResponse>();
            var requestUri = $"{mEnv.BaseUrl}/v1/QRCode";

            var queryParams = new List <string>();

            if (format != null)
            {
                queryParams.Add($"format={format}");
                requestUri = $"{requestUri}?{string.Join("&", queryParams)}";
            }

            QRCodeRequest bodyParams = new QRCodeRequest()
            {
                Signature       = getTimestampSignature(privateKey),
                Currency        = currency,
                Target          = address,
                Amount          = amount,
                Expiry          = expiry,
                Note            = note,
                MerchantOrderID = merchantOrderID
            };

            string        json    = bodyParams.ToJson();
            StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

            byte[] authenticationBytes = Encoding.ASCII.GetBytes($"{apiKey}:{secret}");
            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic",
                                                                                                                           System.Convert.ToBase64String(authenticationBytes));
                    using (HttpResponseMessage response = await httpClient.PostAsync(requestUri, content))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            result.IsSuccess = true;
                            result.Data      = await response.Content.ReadAsStringAsync();

                            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);
        }
示例#9
0
        /// <summary>
        /// Accept an exchange request.
        /// <param name="apiKey">Your apiKey.</param>
        /// <param name="apiSecret">Your apiSecretKey.</param>
        /// <param name="address"/>The address that funds the source amount.</parm>
        /// <param name="privateKey">The privateKey of the sending address.</param>
        /// </summary>
        /// <returns></returns>
        public async Task <Result <bool, ErrorResponse> > AcceptExchangeRequestAsync(
            string apiKey,
            string apiSecret,
            string address,
            string privateKey,
            AcceptExchangeRequest exchangeRequest)
        {
            #region
            IEnumerable <ValidationResult> validation = exchangeRequest.Validate();

            if (validation.Any())
            {
                foreach (var item in validation)
                {
                    throw new ArgumentNullException(item.ErrorMessage);
                }
            }

            if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException(address);
            }
            else if (string.IsNullOrWhiteSpace(privateKey))
            {
                throw new ArgumentNullException(nameof(privateKey));
            }
            #endregion

            string token = getAuthToken(apiKey, apiSecret);

            var    result     = new Result <bool, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/ExchangeRequests/{exchangeRequest.ID}";

            string     reserveTxnSinatrue  = null;
            string     executeTxnSignature = null;
            string     reclaimTxnSignature = null;
            BigInteger nonce = BigInteger.Parse(GluwaService.GetNonceString());

            if (exchangeRequest.Conversion.Value.IsSourceCurrencyBtc())
            {
                BtcTxnSignature txnSignature = await getBtcTxnSignaturesAsync(
                    exchangeRequest.Conversion.Value.ToSourceCurrency(),
                    address,
                    exchangeRequest.SourceAmount,
                    exchangeRequest.Fee,
                    exchangeRequest.DestinationAddress,
                    exchangeRequest.ReservedFundsAddress,
                    exchangeRequest.ReservedFundsRedeemScript,
                    privateKey);

                reserveTxnSinatrue  = txnSignature.ReserveTxnSignature;
                executeTxnSignature = txnSignature.ExecuteTxnSignature;
                reclaimTxnSignature = txnSignature.ReclaimTxnSignature;
            }
            else
            {
                BigInteger convertExpiryBlockNumber = BigInteger.Parse(exchangeRequest.ExpiryBlockNumber.ToString());

                reserveTxnSinatrue = getGluwacoinReserveTxnSignature(
                    exchangeRequest.Conversion.Value.ToSourceCurrency(),
                    address,
                    exchangeRequest.SourceAmount,
                    exchangeRequest.Fee,
                    exchangeRequest.DestinationAddress,
                    exchangeRequest.Executor,
                    nonce,
                    convertExpiryBlockNumber,
                    privateKey);
            }

            PatchExchangeRequest bodyParams = new PatchExchangeRequest()
            {
                SendingAddress      = address,
                ReserveTxnSignature = reserveTxnSinatrue,
                Nonce = nonce.ToString(),
                ExecuteTxnSignature = executeTxnSignature,
                ReclaimTxnSignature = reclaimTxnSignature
            };

            string        json    = bodyParams.ToJson();
            StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

            HttpRequestMessage request = new HttpRequestMessage
            {
                Method     = new HttpMethod("PATCH"),
                RequestUri = new Uri(requestUri),
                Content    = content
            };

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(AUTHORIZATION, $"{BASIC} {token}");

                    using (HttpResponseMessage response = await httpClient.SendAsync(request))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            result.IsSuccess = true;
                            result.Data      = true;

                            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);
        }
示例#10
0
        /// <summary>
        /// Get Quote for currency exchange.
        /// </summary>
        /// <param name="sendingAddressPrivateKey">The privateKey of the sending address.</param>
        /// <param name="receivingAddressPrivateKey">The privateKey of the receiving address.</param>
        /// <param name="quoteRequest">Request body.</param>
        /// <response code="200">Newly generated quote.</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="404">No matching orders available.</response>
        /// <response code="500">Server error.</response>
        /// <returns></returns>
        public async Task <Result <QuoteResponse, ErrorResponse> > GetPendingQuoteAsync(
            string sendingAddressPrivateKey,
            string receivingAddressPrivateKey,
            GetPendingQuoteRequest quoteRequest)
        {
            #region
            IEnumerable <ValidationResult> validation = quoteRequest.Validate();

            if (validation.Any())
            {
                foreach (var item in validation)
                {
                    throw new ArgumentNullException(item.ErrorMessage);
                }
            }

            if (string.IsNullOrWhiteSpace(sendingAddressPrivateKey))
            {
                throw new ArgumentNullException(nameof(sendingAddressPrivateKey));
            }
            else if (string.IsNullOrWhiteSpace(receivingAddressPrivateKey))
            {
                throw new ArgumentNullException(nameof(receivingAddressPrivateKey));
            }
            #endregion

            var    result     = new Result <QuoteResponse, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/Quote";

            string btcPublicKey = null;

            if (quoteRequest.Conversion.Value.IsSourceCurrencyBtc())
            {
                btcPublicKey = Key.Parse(sendingAddressPrivateKey, mEnv.Network).PubKey.ToString();
            }

            string sendingAddressSignature   = GluwaService.GetAddressSignature(sendingAddressPrivateKey, quoteRequest.Conversion.Value.ToSourceCurrency(), mEnv);
            string receivingAddressSignature = GluwaService.GetAddressSignature(receivingAddressPrivateKey, quoteRequest.Conversion.Value.ToTargetCurrency(), mEnv);

            PostQuoteRequest bodyParams = new PostQuoteRequest()
            {
                Amount                    = quoteRequest.Amount,
                Conversion                = quoteRequest.Conversion,
                SendingAddress            = quoteRequest.SendingAddress,
                SendingAddressSignature   = sendingAddressSignature,
                ReceivingAddress          = quoteRequest.ReceivingAddress,
                ReceivingAddressSignature = receivingAddressSignature,
                BtcPublicKey              = btcPublicKey
            };

            string        json    = bodyParams.ToJson();
            StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

            try
            {
                using (HttpClient httpClient = new HttpClient())
                    using (HttpResponseMessage response = await httpClient.PostAsync(requestUri, content))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            QuoteResponse quoteResponse = await response.Content.ReadAsAsync <QuoteResponse>();

                            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);
        }
示例#11
0
        /// <summary>
        /// Create a new order.
        /// </summary>
        /// <param name="apiKey">Your apiKey.</param>
        /// <param name="apiSecret">Your apiSecretKey.</param>
        /// <param name="sendingAddressPrivateKey">The privateKey of the sending address.</param>
        /// <param name="receivingAddressPrivateKey">The privateKey of the receiving address.</param>
        /// <param name="orderRequest">Request body.</param>
        /// <response code="201">Newly created order.</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_Forbidden">Not authorized to use this endpoint.</response>
        /// <response code="403_WebhookNotFound">Webhook URL to send exchange request is unavailable.</response>
        /// <response code="500">Server error.</response>
        /// <response code="503">Service unavailable for the specified conversion.</response>
        /// <returns></returns>
        public async Task <Result <CreateOrderResponse, ErrorResponse> > CreateOrderAsync(
            string apiKey,
            string apiSecret,
            string sendingAddressPrivateKey,
            string receivingAddressPrivateKey,
            CreateOrderRequest orderRequest)
        {
            #region
            IEnumerable <ValidationResult> validation = orderRequest.Validate();

            if (validation.Any())
            {
                foreach (var item in validation)
                {
                    throw new ArgumentNullException(item.ErrorMessage);
                }
            }

            if (string.IsNullOrWhiteSpace(sendingAddressPrivateKey))
            {
                throw new ArgumentNullException(nameof(sendingAddressPrivateKey));
            }
            else if (string.IsNullOrWhiteSpace(receivingAddressPrivateKey))
            {
                throw new ArgumentNullException(nameof(receivingAddressPrivateKey));
            }
            #endregion

            string token = getAuthToken(apiKey, apiSecret);

            var    result     = new Result <CreateOrderResponse, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/Orders";

            string btcpublicKey = null;

            if (orderRequest.Conversion.Value.IsSourceCurrencyBtc())
            {
                btcpublicKey = Key.Parse(sendingAddressPrivateKey, mEnv.Network).PubKey.ToString();
            }

            PostOrderRequest bodyParams = new PostOrderRequest()
            {
                Conversion                = orderRequest.Conversion.ToString(),
                SendingAddress            = orderRequest.SendingAddress,
                SendingAddressSignature   = GluwaService.GetAddressSignature(sendingAddressPrivateKey, orderRequest.Conversion.Value.ToSourceCurrency(), mEnv),
                ReceivingAddress          = orderRequest.ReceivingAddress,
                ReceivingAddressSignature = GluwaService.GetAddressSignature(receivingAddressPrivateKey, orderRequest.Conversion.Value.ToTargetCurrency(), mEnv),
                SourceAmount              = orderRequest.SourceAmount,
                Price        = orderRequest.Price,
                BtcPublicKey = btcpublicKey
            };

            string        json    = bodyParams.ToJson();
            StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(AUTHORIZATION, $"{BASIC} {token}");

                    using (HttpResponseMessage response = await httpClient.PostAsync(requestUri, content))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            CreateOrderResponse orderResponse = await response.Content.ReadAsAsync <CreateOrderResponse>();

                            result.IsSuccess = true;
                            result.Data      = orderResponse;

                            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);
        }
示例#12
0
        /// <summary>
        /// Retrieve all orders.
        /// </summary>
        /// <param name="apiKey">Your apiKey.</param>
        /// <param name="apiSecret">Your apiSecretKey.</param>
        /// <param name="options">Request body.</param>
        /// <response code="200">List of orders.</response>
        /// <response code="400_InvalidUrlParameters">Invalid URL parameters.</response>
        /// <response code="403">Not authorized to use this endpoint.</response>
        /// <response code="500">Server error.</response>
        /// <returns></returns>
        public async Task <Result <List <GetOrdersResponse>, ErrorResponse> > GetOrdersAsync(string apiKey, string apiSecret, GetOrdersOptions options)
        {
            #region
            IEnumerable <ValidationResult> validation = options.Validate();

            if (validation.Any())
            {
                foreach (var item in validation)
                {
                    throw new ArgumentNullException(item.ErrorMessage);
                }
            }
            #endregion

            string token = getAuthToken(apiKey, apiSecret);

            var    result     = new Result <List <GetOrdersResponse>, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/Orders";

            var queryParams = new List <string>();
            if (options.StartDateTime.HasValue)
            {
                queryParams.Add($"startDateTime={options.StartDateTime.Value.ToString("o")}");
            }
            if (options.EndDateTime.HasValue)
            {
                queryParams.Add($"endDateTime={options.EndDateTime.Value.ToString("o")}");
            }
            if (options.Status.HasValue)
            {
                queryParams.Add($"status={options.Status}");
            }

            queryParams.Add($"offset={options.Offset}");
            queryParams.Add($"limit={options.Limit}");
            requestUri = $"{requestUri}?{string.Join("&", queryParams)}";

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(AUTHORIZATION, $"{BASIC} {token}");

                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            List <GetOrdersResponse> orderResponse = await response.Content.ReadAsAsync <List <GetOrdersResponse> >();

                            result.IsSuccess = true;
                            result.Data      = orderResponse;

                            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);
        }
示例#13
0
        /// <summary>
        /// Get a list of accepted quotes.
        /// </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="options">Request body.</param>
        /// <response code="200">array of Quotes.</response>
        /// <response code="400_InvalidUrlParameters">Invalid URL parameters.</response>
        /// <response code="403_SignatureMissing">X-REQUEST-SIGNATURE header is missing.</response>
        /// <response code="403_SignatureExpired">X-REQUEST-SIGNATURE has expired.</response>
        /// <response code="403_InvalidSignature">Invalid X-REQUEST-SIGNATURE.</response>
        /// <response code="500">Server error.</response>
        /// <returns></returns>
        public async Task <Result <List <GetQuotesResponse>, ErrorResponse> > GetQuotesAsync(
            ECurrency currency,
            string address,
            string privateKey,
            GetQuotesOptions options)
        {
            #region
            if (!currency.IsGluwaExchangeCurrency())
            {
                throw new ArgumentOutOfRangeException($"Unsupported currency: {currency}");
            }

            IEnumerable <ValidationResult> validation = options.Validate();

            if (validation.Any())
            {
                foreach (var item in validation)
                {
                    throw new ArgumentNullException(item.ErrorMessage);
                }
            }

            if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException(nameof(address));
            }
            #endregion

            var    result     = new Result <List <GetQuotesResponse>, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/{currency}/Addresses/{address}/Quotes";

            var queryParams = new List <string>();
            if (options.StartDateTime.HasValue)
            {
                queryParams.Add($"startDateTime={options.StartDateTime.Value.ToString("o")}");
            }
            if (options.EndDateTime.HasValue)
            {
                queryParams.Add($"endDateTime={options.EndDateTime.Value.ToString("o")}");
            }
            if (options.Status.HasValue)
            {
                queryParams.Add($"status={options.Status}");
            }

            queryParams.Add($"offset={options.Offset}");
            queryParams.Add($"limit={options.Limit}");
            requestUri = $"{requestUri}?{string.Join("&", queryParams)}";

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(X_REQUEST_SIGNATURE, GluwaService.GetAddressSignature(privateKey, currency, mEnv));

                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            List <GetQuotesResponse> quoteResponse = await response.Content.ReadAsAsync <List <GetQuotesResponse> >();

                            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);
        }
示例#14
0
        /// <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);
        }
示例#15
0
        /// <summary>
        /// Create a new Bitcoin or Gluwacoin transaction.
        /// </summary>
        /// <param name="currency">Currency type</param>
        /// <param name="address">Your public Address.</param>
        /// <param name="privateKey">Your Private Key.</param>
        /// <param name="amount">Transaction amount, not including the fee.</param>
        /// <param name="target">The address that the transaction will be sent to.</param>
        /// <param name="merchantOrderID">Identifier for the transaction that was provided by the merchant user. Optional.</param>
        /// <param name="note">Additional information about the transaction that a user can provide. Optional.</param>
        /// <param name="nonce">Nonce for the transaction. For Gluwacoin currencies only.</param>
        /// <param name="idem">Idempotent key for the transaction to prevent duplicate transactions.</param>
        /// <param name="paymentID">ID for the QR code payment.</param>
        /// <param name="paymentSig">Signature of the QR code payment.Required if PaymentID is not null.</param>
        /// <response code="202">Newly accepted transaction.</response>
        /// <response code="400">Invalid request. or Validation error. See inner errors for more details. or (BTC only) Signed BTC transaction could not be verified.</response>
        /// <response code="403">For payments, payment signature could not be verified.</response>
        /// <response code="409">A transaction with the same transaction hash, payment ID, or idem already exists.</response>
        /// <response code="500">Server error.</response>
        /// <response code="503">Service unavailable.</response>
        public async Task <Result <bool, ErrorResponse> > CreateTransactionAsync(
            ECurrency currency,
            string address,
            string privateKey,
            string amount,
            string target,
            string merchantOrderID = null,
            string note            = null,
            string nonce           = null,
            Guid?idem         = null,
            Guid?paymentID    = null,
            string paymentSig = null)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException(nameof(address));
            }
            else if (string.IsNullOrWhiteSpace(privateKey))
            {
                throw new ArgumentNullException(nameof(privateKey));
            }
            else if (string.IsNullOrWhiteSpace(amount))
            {
                throw new ArgumentNullException(nameof(amount));
            }
            else if (string.IsNullOrWhiteSpace(target))
            {
                throw new ArgumentNullException(nameof(target));
            }
            else if (paymentID != null)
            {
                if (string.IsNullOrWhiteSpace(paymentSig))
                {
                    throw new ArgumentException(nameof(paymentSig));
                }
            }

            var result     = new Result <bool, ErrorResponse>();
            var requestUri = $"{mEnv.BaseUrl}/v1/Transactions";

            Result <FeeResponse, ErrorResponse> getFee = await getFeeAsync(currency);

            if (getFee.IsFailure)
            {
                result.Error = getFee.Error;

                return(result);
            }

            string fee       = getFee.Data.MinimumFee;
            string signature = null;

            if (currency == ECurrency.BTC)
            {
                signature = await getBtcTransactionSignatureAsync(currency, address, amount, fee, target, privateKey);
            }
            else
            {
                if (nonce == null)
                {
                    nonce = GluwaService.GetNonceString();
                }

                signature = getGluwacoinTransactionSignature(currency, amount, fee, nonce, address, target, privateKey);
            }

            TransactionRequest bodyParams = new TransactionRequest
            {
                Signature       = signature,
                Currency        = currency,
                Target          = target,
                Amount          = amount,
                Fee             = getFee.Data.MinimumFee,
                Source          = address,
                Nonce           = nonce,
                MerchantOrderID = merchantOrderID,
                Note            = note,
                Idem            = idem,
                PaymentID       = paymentID,
                PaymentSig      = paymentSig
            };

            string        json    = bodyParams.ToJson();
            StringContent content = new StringContent(json, Encoding.UTF8, "application/json");

            try
            {
                using (HttpClient httpClient = new HttpClient())
                    using (var response = await httpClient.PostAsync(requestUri, content))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            result.IsSuccess = true;
                            result.Data      = true;

                            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);
        }
示例#16
0
        /// <summary>
        /// Get a list of transactions for specified currency.
        /// </summary>
        /// <param name="currency">Currency type.</param>
        /// <param name="address">Your public Address.</param>
        /// <param name="privateKey">Your Private Key.</param>
        /// <param name="limit">Number of transactions to include in the result. optional. Defaults to 100.</param>
        /// <param name="status">Filter by transaction status. Optional. Defaults to Confimred.</param>
        /// <param name="offset">Number of transactions to skip; used for pagination. Optional. Default to 0.</param>
        /// <response code="200">List of transactions associated with the address.</response>
        /// <response code="400">Invalid request or Address does not have a valid format.</response>
        /// <response code="403">Request signature header is not valid.</response>
        /// <response code="500">Server error.</response>
        /// <response code="503">Service unavailable.</response>
        public async Task <Result <List <TransactionResponse>, ErrorResponse> > GetTransactionListAsync(
            ECurrency currency,
            string address,
            string privateKey,
            uint limit = 100,
            ETransactionStatusFilter status = ETransactionStatusFilter.Confirmed,
            uint offset = 0)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException(nameof(address));
            }
            else if (string.IsNullOrWhiteSpace(privateKey))
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            var    result     = new Result <List <TransactionResponse>, ErrorResponse>();
            string requestUri = $"{mEnv.BaseUrl}/v1/{currency}/Addresses/{address}/Transactions";

            var queryParams = new List <string>();

            if (offset > 0)
            {
                queryParams.Add($"offset={offset}");
            }
            if (limit > 0)
            {
                queryParams.Add($"limit={limit}");
            }
            if (queryParams.Any())
            {
                queryParams.Add($"status={status}");
                requestUri = $"{requestUri}?{string.Join("&", queryParams)}";
            }

            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Add(X_REQUEST_SIGNATURE, GluwaService.GetAddressSignature(privateKey, currency, mEnv));

                    using (HttpResponseMessage response = await httpClient.GetAsync(requestUri))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            List <TransactionResponse> transactionResponse = await response.Content.ReadAsAsync <List <TransactionResponse> >();

                            result.IsSuccess = true;
                            result.Data      = transactionResponse;

                            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);
        }