Add Privy type wallet

This commit is contained in:
2025-03-05 10:36:54 +07:00
parent 30bf9d26f6
commit 988cc9eb61
21 changed files with 287 additions and 53 deletions

View File

@@ -0,0 +1,11 @@
using Managing.Infrastructure.Evm.Models;
namespace Managing.Infrastructure.Evm.Abstractions;
public interface IPrivyService
{
Task<PrivyWallet> CreateWalletAsync(string chainType = "ethereum");
Task<HttpResponseMessage> SendTransactionAsync(string walletId, string recipientAddress, long value,
string caip2 = "eip155:84532");
}

View File

@@ -0,0 +1,7 @@
namespace Managing.Infrastructure.Evm.Abstractions;
public interface IPrivySettings
{
string AppId { get; set; }
string AppSecret { get; set; }
}

View File

@@ -37,6 +37,7 @@ public class EvmManager : IEvmManager
private readonly IEnumerable<ISubgraphPrices> _subgraphs;
private Dictionary<string, Dictionary<string, decimal>> _geckoPrices;
private readonly GmxV2Service _gmxV2Service;
private readonly IPrivyService _privyService;
private readonly List<Ticker> _eligibleTickers = new List<Ticker>()
{
@@ -44,12 +45,13 @@ public class EvmManager : IEvmManager
Ticker.PEPE, Ticker.DOGE, Ticker.UNI
};
public EvmManager(IEnumerable<ISubgraphPrices> subgraphs)
public EvmManager(IEnumerable<ISubgraphPrices> subgraphs, IPrivyService privyService)
{
var defaultChain = ChainService.GetEthereum();
_web3 = new Web3(defaultChain.RpcUrl);
_httpClient = new HttpClient();
_subgraphs = subgraphs;
_privyService = privyService;
_geckoPrices = _geckoPrices != null && _geckoPrices.Any()
? _geckoPrices
: new Dictionary<string, Dictionary<string, decimal>>();
@@ -657,4 +659,11 @@ public class EvmManager : IEvmManager
var chain = ChainService.GetChain(Constants.Chains.Arbitrum);
return new Web3(wallet, chain.RpcUrl);
}
public async Task<(string Id, string Address)> CreatePrivyWallet()
{
var privyWallet = await _privyService.CreateWalletAsync();
return (privyWallet.Id, privyWallet.Address);
}
}

View File

@@ -0,0 +1,9 @@
using Managing.Infrastructure.Evm.Abstractions;
namespace Managing.Infrastructure.Evm.Models.Privy;
public class PrivySettings : IPrivySettings
{
public string AppId { get; set; }
public string AppSecret { get; set; }
}

View File

@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace Managing.Infrastructure.Evm.Models;
public class PrivyWallet
{
[JsonPropertyName("id")] public string Id { get; set; }
[JsonPropertyName("address")] public string Address { get; set; }
[JsonPropertyName("chain_type")] public string ChainType { get; set; }
}

View File

@@ -793,6 +793,7 @@ public class GmxV2Service
var exchangeRouterService = new ExchangeRouterService(web3, Arbitrum.AddressV2.ExchangeRouter);
var receipt = await exchangeRouterService.MulticallRequestAndWaitForReceiptAsync(multiCallFunction);
// Call privy api instead and send the txn
var trade = new Trade(DateTime.UtcNow,
direction,
Enums.TradeStatus.Requested,

View File

@@ -0,0 +1,85 @@
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using Managing.Infrastructure.Evm.Abstractions;
using Managing.Infrastructure.Evm.Models;
public class PrivyService : IPrivyService
{
private readonly HttpClient _privyClient;
private readonly string _appId;
private readonly string _appSecret;
public PrivyService(IPrivySettings settings)
{
_privyClient = new HttpClient();
_appId = settings.AppId;
_appSecret = settings.AppSecret;
ConfigureHttpClient();
}
private void ConfigureHttpClient()
{
_privyClient.BaseAddress = new Uri("https://api.privy.io/");
var authToken = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_appId}:{_appSecret}"));
// _privyClient.DefaultRequestHeaders.Authorization =
// new AuthenticationHeaderValue("Basic", $"{_appId}:{_appSecret}");
_privyClient.DefaultRequestHeaders.Add("privy-app-id", _appId);
// add custom header
_privyClient.DefaultRequestHeaders.Add("Authorization", authToken);
_privyClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<PrivyWallet> CreateWalletAsync(string chainType = "ethereum")
{
try
{
var json = JsonSerializer.Serialize(new { chain_type = chainType });
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _privyClient.PostAsJsonAsync("/v1/wallets", content);
var result = new PrivyWallet();
if (response.IsSuccessStatusCode)
{
result = await response.Content.ReadFromJsonAsync<PrivyWallet>();
}
else
{
throw new Exception(await response.Content.ReadAsStringAsync());
}
return result;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
public async Task<HttpResponseMessage> SendTransactionAsync(string walletId, string recipientAddress, long value,
string caip2 = "eip155:84532")
{
var requestBody = new
{
method = "eth_sendTransaction",
caip2,
@params = new
{
transaction = new
{
to = recipientAddress,
value
}
}
};
return await _privyClient.PostAsJsonAsync(
$"/v1/wallets/{walletId}/rpc",
requestBody
);
}
}