using System.Net.Http.Headers; using System.Text.Json; using System.Text; using System.Text.Json.Nodes; using System.Security.Cryptography; using System.Runtime.InteropServices; using spworlds.Types; using System.Text.Json.Serialization; using Newtonsoft.Json.Converters; namespace spworlds; public class SPWorlds { private readonly HttpClient client; private string token; public SPWorlds(string id, string token) { client = new HttpClient(); var BearerToken = $"{id}:{token}"; this.token = token; string Base64BearerToken = Convert.ToBase64String(Encoding.UTF8.GetBytes(BearerToken)); client.BaseAddress = new Uri("https://spworlds.ru/api/public/"); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Base64BearerToken); } /// /// Validating wenhook from site /// /// Body of request /// X-Body-Hash /// public bool ValidateWebhook(string requestBody, string base64Hash) { byte[] requestData = Encoding.UTF8.GetBytes(requestBody); using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(token))) { byte[] hashBytes = hmac.ComputeHash(requestData); string computedHash = Convert.ToBase64String(hashBytes); return base64Hash.Equals(computedHash); } } private async Task SendRequest(string endpoint, bool getResult = true, HttpMethod method = null, object body = null) { method ??= body == null ? HttpMethod.Get : HttpMethod.Post; HttpResponseMessage message; using (var requestMessage = new HttpRequestMessage(method, client.BaseAddress + endpoint)) { requestMessage.Content = new StringContent( JsonSerializer.Serialize(body), Encoding.UTF8, "application/json" ); requestMessage.Headers.Authorization = client.DefaultRequestHeaders.Authorization; message = await client.SendAsync(requestMessage); } if (getResult) return await message.Content.ReadAsStringAsync(); else return null; } /// /// Get card from spworlds /// /// public async Task GetCard() => Deserialize.DeserializeObject(await SendRequest("card")); /// /// Create transaction /// /// receiver card /// amount of AR /// comment to transaction /// balance of card public async Task CreateTransaction(string receiver, int amount, string comment) { var transitionInfo = new Dictionary { { "receiver", receiver }, { "amount", amount }, { "comment", comment } }; var response = JsonObject.Parse(await SendRequest(endpoint: "transactions", body: transitionInfo, getResult: true)); return (int)response["balance"]; } /// /// Get user cards by nickname /// /// Username of player /// Array of cards public async Task GetUserCardsAsync(string username) => Deserialize.DeserializeObject(await SendRequest($"accounts/{username}/cards")); /// /// Get user info from site /// /// Discord id of user /// public async Task GetUser(string discordId) => Deserialize.DeserializeObject(await SendRequest($"users/{discordId}")); /// /// Create payment url /// /// List of items /// User will be redirected to this url /// Webhook will be sended to this url /// Data, returned with webhook /// public async Task InitPayment(Item[] items, string redirectUrl, string webhookUrl, string data) { var paymentInfo = new Dictionary { { "items", JsonSerializer.Serialize(items)}, { "redirectUrl", redirectUrl }, { "webhookUrl", webhookUrl }, { "data", data } }; var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: paymentInfo)); var url = payment["url"]; return (string)url; } /// /// Create payment url /// /// /// public async Task InitPayment(PaymentData paymentData) { var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: JsonSerializer.Serialize(paymentData))); return (string)payment["url"]; } /// /// Setting up a webhook to card /// /// Url of webhook /// public async Task SetWebhook(string webhookUrl) => Deserialize.DeserializeObject( await SendRequest( "card/webhook", true, HttpMethod.Put, new Dictionary() { { "url", webhookUrl } } ) ); public async Task GetMeAsync() => Deserialize.DeserializeObject(await SendRequest("accounts/me")); }