-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
961 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.0.32126.317 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ETH.API", "ETH.API\ETH.API.csproj", "{590AF4A5-5CE9-4FD9-BB92-21A561143326}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {D01C005F-6245-42C0-B846-573C4A9D7779} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
| ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.0.32126.317 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ETH.API", "CryptoCurrency.API\ETH.API.csproj", "{590AF4A5-5CE9-4FD9-BB92-21A561143326}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{590AF4A5-5CE9-4FD9-BB92-21A561143326}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {D01C005F-6245-42C0-B846-573C4A9D7779} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"version": 1, | ||
"isRoot": true, | ||
"tools": { | ||
"dotnet-ef": { | ||
"version": "6.0.0", | ||
"commands": [ | ||
"dotnet-ef" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
using ETH.API.Data.Repositories; | ||
using ETH.API.Models; | ||
using ETH.API.Models.Enum; | ||
using ETH.API.Models.Tables; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Nethereum.Hex.HexConvertors.Extensions; | ||
using Nethereum.Hex.HexTypes; | ||
using Nethereum.RPC.Eth.DTOs; | ||
using Nethereum.Util; | ||
using Nethereum.Web3; | ||
using Nethereum.Web3.Accounts; | ||
using Nethereum.Web3.Accounts.Managed; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Numerics; | ||
using System.Threading.Tasks; | ||
|
||
using System; | ||
using Moralis.Web3Api.Interfaces; | ||
using Moralis.Web3Api; | ||
using Moralis.Web3Api.Models; | ||
using Transaction = Moralis.Web3Api.Models.Transaction; | ||
using System.Reflection.Emit; | ||
using Microsoft.OpenApi.Extensions; | ||
using ETH.API.Services; | ||
using Nethereum.ABI; | ||
|
||
namespace ETH.API.Controllers | ||
{ | ||
[ApiController] | ||
[Route("[controller]/[action]")] | ||
public class ETHController : ControllerBase | ||
{ | ||
private OutcomeTransactionRepository _outcomeTransactionRepository; | ||
private AccountsRepository _accountRepository; | ||
private WalletRepository _walletRepository; | ||
private TransactionETHRepository _transactionETHRepository; | ||
private IncomeTransactionRepository _incomeTransactionRepository; | ||
private MoralisService _moralisService; | ||
|
||
public ETHController(OutcomeTransactionRepository outcomeTransactionRepository, | ||
AccountsRepository accountRepository, | ||
WalletRepository walletRepository, | ||
TransactionETHRepository transactionETHRepository, | ||
IncomeTransactionRepository incomeTransactionRepository, | ||
MoralisService moralisService) | ||
{ | ||
_outcomeTransactionRepository = outcomeTransactionRepository; | ||
_accountRepository = accountRepository; | ||
_walletRepository = walletRepository; | ||
_transactionETHRepository = transactionETHRepository; | ||
_moralisService = moralisService; | ||
_incomeTransactionRepository = incomeTransactionRepository; | ||
} | ||
|
||
[HttpGet] | ||
public async Task<string> GetNewAddress(string label) | ||
{ | ||
var web3 = new Web3(); | ||
var address = await web3.Personal.NewAccount.SendRequestAsync(label); | ||
|
||
await _accountRepository.CreateAccountAsync(new AccountsTableModel | ||
{ | ||
Address = address, | ||
Label = label, | ||
Value = 0, | ||
State = (int)AccountState.Created | ||
}); | ||
|
||
return address; | ||
} | ||
|
||
[HttpGet] | ||
public async Task<List<IncomeTransactionTableModel>> GetNewTransactions(string userId) | ||
{ | ||
var result = new List<IncomeTransactionTableModel>(); | ||
try | ||
{ | ||
var incomeWallets = await _walletRepository.GetUserIncomeWalletsAsync(userId); | ||
foreach (var incomeWallet in incomeWallets) | ||
{ | ||
var newTransactions = await _moralisService.GetTransactions(incomeWallet.Address); | ||
foreach (var transaction in newTransactions) | ||
{ | ||
if (transaction.ToAddress.ToLower() == incomeWallet.Address.ToLower()) | ||
{ | ||
var operationResult = await _transactionETHRepository.SaveTransactionETHAsync(transaction); | ||
|
||
var value = decimal.Parse(transaction.Value); | ||
|
||
if (value > 0) | ||
{ | ||
var wallet = await _walletRepository.GetUserWalletAsync(userId, "ETH"); | ||
|
||
decimal gasPrice = decimal.Parse(transaction.GasPrice); | ||
decimal gas = decimal.Parse(transaction.Gas); | ||
decimal fee = gasPrice * gas; | ||
|
||
var incomeTransaction = new IncomeTransactionTableModel() | ||
{ | ||
CurrencyAcronim = "ETH", | ||
TransactionId = transaction.Hash, | ||
Amount = value, | ||
TransactionFee = fee, | ||
PlatformCommission = null, | ||
FromAddress = transaction.FromAddress, | ||
ToAddress = transaction.ToAddress, | ||
CreatedDate = DateTime.Parse(transaction.BlockTimestamp), | ||
Date = 0, | ||
UserId = userId, | ||
WalletId = wallet.Id, | ||
}; | ||
result.Add(incomeTransaction); | ||
} | ||
else | ||
{ | ||
continue; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
|
||
} | ||
|
||
return result; | ||
} | ||
|
||
[HttpGet] | ||
public async Task<ExecuteTransactionModel> ExecuteTransaction(long outcomeTransactionId) | ||
{ | ||
OutcomeTransactionTableModel tr = await _outcomeTransactionRepository.GetOutcomeTransactionAsync(outcomeTransactionId); | ||
try | ||
{ | ||
AccountsTableModel account; | ||
if (tr.FixedCommission.HasValue) | ||
{ | ||
account = await _accountRepository.GetAccountByValueAsync(tr.Value + tr.FixedCommission.Value);// берём адрес, учитывая комисию | ||
} | ||
else | ||
{ | ||
account = await _accountRepository.GetAccountByValueAsync(tr.Value); | ||
} | ||
|
||
if (account != null) | ||
{ | ||
var accountWeb3 = new ManagedAccount(account.Address, account.Label); | ||
var web3 = new Web3(accountWeb3); | ||
|
||
var value = Web3.Convert.ToWei(new BigDecimal(tr.Value)); | ||
var transactionHash = await web3.TransactionManager.SendTransactionAsync(account.Address, tr.ToAddress, new HexBigInteger(value)); | ||
var trBlockchain = await web3.Eth.Transactions.GetTransactionByHash.SendRequestAsync(transactionHash); | ||
|
||
//decimal commission = Web3.Convert.FromWei(trBlockchain.Gas.Value * trBlockchain.GasPrice.Value); | ||
var balance = await web3.Eth.GetBalance.SendRequestAsync(account.Address); | ||
var balanceETH = Web3.Convert.FromWei(balance.Value); | ||
decimal commission = account.Value - (balanceETH + tr.Value); | ||
|
||
account.Value -= (tr.Value + commission); | ||
|
||
await _accountRepository.UpdateAccountAsync(account); // сделать отдельную процедурку которая обновляет только баланс | ||
|
||
return new ExecuteTransactionModel() | ||
{ | ||
IsSuccess = true, | ||
OutcomeTransactionState = (int)OutcomeTransactionStateEnum.Finished, | ||
CommissionBlockchain = commission, | ||
Value = tr.Value, | ||
FromAddressBlockchain = account.Address, | ||
ToAddressBlockchain = tr.ToAddress, | ||
TransactionHash = transactionHash, | ||
ErrorText = null | ||
}; | ||
} | ||
else | ||
{ | ||
return new ExecuteTransactionModel() | ||
{ | ||
IsSuccess = false, | ||
OutcomeTransactionState = (int)OutcomeTransactionStateEnum.Error, | ||
ErrorText = "Operation must be performed manually" // нету счёта с которого можно выветси 1 транзакцией | ||
}; | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
return new ExecuteTransactionModel() | ||
{ | ||
IsSuccess = false, | ||
OutcomeTransactionState = (int)OutcomeTransactionStateEnum.Error, | ||
ErrorText = ex.Message | ||
}; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using Dapper; | ||
using ETH.API.Models.Tables; | ||
using Microsoft.Extensions.Configuration; | ||
using System; | ||
using System.Data; | ||
using System.Data.SqlClient; | ||
using System.Threading.Tasks; | ||
|
||
namespace ETH.API.Data.Repositories | ||
{ | ||
public class AccountsRepository | ||
{ | ||
private readonly IDbConnection _db; | ||
|
||
public AccountsRepository(IConfiguration configuration) | ||
{ | ||
_db = new SqlConnection(configuration.GetConnectionString("ETHConnection")); | ||
} | ||
|
||
public async Task<AccountsTableModel> GetAccountAsync(string address) | ||
{ | ||
try | ||
{ | ||
return (await _db.QueryFirstOrDefaultAsync<AccountsTableModel>("GetAccount", | ||
new | ||
{ | ||
address = address | ||
}, | ||
commandType: CommandType.StoredProcedure | ||
)); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return null; | ||
} | ||
} | ||
|
||
public async Task<AccountsTableModel> GetAccountByValueAsync(decimal value) | ||
{ | ||
try | ||
{ | ||
return (await _db.QueryFirstOrDefaultAsync<AccountsTableModel>("GetAccountByValue", | ||
new | ||
{ | ||
value = value | ||
}, | ||
commandType: CommandType.StoredProcedure | ||
)); | ||
} | ||
catch (Exception ex) | ||
{ | ||
return null; | ||
} | ||
} | ||
|
||
public async Task CreateAccountAsync(AccountsTableModel address) | ||
{ | ||
try | ||
{ | ||
var p = new DynamicParameters(); | ||
p.Add("address", address.Address); | ||
p.Add("label", address.Label); | ||
p.Add("value", address.Value); | ||
p.Add("state", address.State); | ||
|
||
await _db.QueryAsync("CreateAccount", p, commandType: CommandType.StoredProcedure); | ||
} | ||
catch (Exception ex) { } | ||
} | ||
|
||
public async Task UpdateAccountAsync(AccountsTableModel address) | ||
{ | ||
try | ||
{ | ||
var p = new DynamicParameters(); | ||
p.Add("id", address.Address); | ||
p.Add("address", address.Address); | ||
p.Add("label", address.Label); | ||
p.Add("value", address.Value); | ||
p.Add("state", address.State); | ||
|
||
await _db.QueryAsync("UpdateAccount", p, commandType: CommandType.StoredProcedure); | ||
} | ||
catch (Exception ex) { } | ||
} | ||
} | ||
} |
Oops, something went wrong.