This commit is contained in:
yawaflua
2024-04-18 18:38:00 +03:00
parent 2a1317d393
commit 2df80a4c4b
14 changed files with 324 additions and 83 deletions

View File

@@ -6,8 +6,11 @@ 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;
@@ -24,49 +27,65 @@ public class SPWorlds
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Base64BearerToken);
}
private async Task<bool> ValidateWebHook(string webHook, string bodyHash)
/// <summary>
/// Validating wenhook from site
/// </summary>
/// <param name="requestBody">Body of request</param>
/// <param name="base64Hash">X-Body-Hash</param>
/// <returns></returns>
public bool ValidateWebhook(string requestBody, string base64Hash)
{
byte[] body = Encoding.UTF8.GetBytes(bodyHash);
byte[] webhook = Encoding.UTF8.GetBytes(webHook);
var key = new HMACSHA256(Encoding.UTF8.GetBytes(token));
string webhook64 = Convert.ToBase64String(key.ComputeHash(webhook));
return webhook64.Equals(body);
}
private async Task<string> SendRequest(string endpoint, Boolean getResult = true, Dictionary<string, object>? body = null)
{
string respond;
string jsonBody;
if (body == null)
byte[] requestData = Encoding.UTF8.GetBytes(requestBody);
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(token)))
{
return respond = client.GetAsync(endpoint).Result.Content.ReadAsStringAsync().Result;
byte[] hashBytes = hmac.ComputeHash(requestData);
string computedHash = Convert.ToBase64String(hashBytes);
return base64Hash.Equals(computedHash);
}
}
private async Task<string> 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
{
jsonBody = JsonSerializer.Serialize(body);
var payload = new StringContent(jsonBody, Encoding.UTF8, "application/json");
return null;
if (getResult)
return respond = client.PostAsync(endpoint, payload).Result.Content.ReadAsStringAsync().Result;
else
await client.PostAsync(endpoint, payload);
}
return null;
}
public async Task<int> GetBalance()
{
string respond = await SendRequest("card");
var card = JsonObject.Parse(respond);
var balance = card["balance"];
/// <summary>
/// Get card from spworlds
/// </summary>
/// <returns></returns>
public async Task<Card> GetCard()
=> Deserialize.DeserializeObject<Card>(await SendRequest("card"));
return (int)balance;
}
public async Task CreateTransaction(string receiver, int amount, string comment)
/// <summary>
/// Create transaction
/// </summary>
/// <param name="receiver">receiver card</param>
/// <param name="amount">amount of AR</param>
/// <param name="comment">comment to transaction</param>
/// <returns>balance of card</returns>
public async Task<int> CreateTransaction(string receiver, int amount, string comment)
{
var transitionInfo = new Dictionary<string, object>
{
@@ -75,21 +94,41 @@ public class SPWorlds
{ "comment", comment }
};
await SendRequest(endpoint: "transactions", body: transitionInfo);
var response = JsonObject.Parse(await SendRequest(endpoint: "transactions", body: transitionInfo, getResult: true));
return (int)response["balance"];
}
/// <summary>
/// Get user cards by nickname
/// </summary>
/// <param name="username">Username of player</param>
/// <returns>Array of cards</returns>
public async Task<UserCard[]> GetUserCardsAsync(string username)
=> Deserialize.DeserializeObject<UserCard[]>(await SendRequest($"accounts/{username}/cards"));
/// <summary>
/// Get user info from site
/// </summary>
/// <param name="discordId">Discord id of user</param>
/// <returns></returns>
public async Task<User> GetUser(string discordId)
{
string userName = (string)JsonObject.Parse(await SendRequest($"users/{discordId}"))["username"];
User user = await User.CreateUser(userName);
return (User)user;
}
public async Task<string> InitPayment(int amount, string redirectUrl, string webhookUrl, string data)
=> Deserialize.DeserializeObject<User>(await SendRequest($"users/{discordId}"));
/// <summary>
/// Create payment url
/// </summary>
/// <param name="items">List of items</param>
/// <param name="redirectUrl">User will be redirected to this url</param>
/// <param name="webhookUrl">Webhook will be sended to this url</param>
/// <param name="data">Data, returned with webhook</param>
/// <returns></returns>
public async Task<string> InitPayment(Item[] items, string redirectUrl, string webhookUrl, string data)
{
var paymentInfo = new Dictionary<string, object>
{
{ "amount", amount },
{ "items", JsonSerializer.Serialize(items)},
{ "redirectUrl", redirectUrl },
{ "webhookUrl", webhookUrl },
{ "data", data }
@@ -101,20 +140,34 @@ public class SPWorlds
return (string)url;
}
/// <summary>
/// Create payment url
/// </summary>
/// <param name="paymentData"></param>
/// <returns></returns>
public async Task<string> InitPayment(PaymentData paymentData)
{
var paymentInfo = new Dictionary<string, object>
{
{ "amount", paymentData.Amount },
{ "redirectUrl", paymentData.RedirectUrl },
{ "webhookUrl", paymentData.WebHookUrl },
{ "data", paymentData.Data }
};
var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: paymentInfo));
var url = payment["url"];
return (string)url;
var payment = JsonObject.Parse(await SendRequest(endpoint: $"payment", body: JsonSerializer.Serialize(paymentData)));
return (string)payment["url"];
}
/// <summary>
/// Setting up a webhook to card
/// </summary>
/// <param name="webhookUrl">Url of webhook</param>
/// <returns></returns>
public async Task<WebhookResponse> SetWebhook(string webhookUrl)
=> Deserialize.DeserializeObject<WebhookResponse>(
await SendRequest(
"card/webhook",
true,
HttpMethod.Put,
new Dictionary<string, string>()
{
{ "url", webhookUrl }
}
)
);
public async Task<UserAccount> GetMeAsync()
=> Deserialize.DeserializeObject<UserAccount>(await SendRequest("accounts/me"));
}