Skip to content

Commit d4a4e5e

Browse files
rockstardevb0l0k
authored andcommitted
Adding server settings for USDT ETH
1 parent 06e1533 commit d4a4e5e

5 files changed

Lines changed: 206 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using System;
2+
using System.Linq;
3+
using System.Threading.Tasks;
4+
using BTCPayServer.Abstractions.Constants;
5+
using BTCPayServer.Abstractions.Contracts;
6+
using BTCPayServer.Client;
7+
using BTCPayServer.Filters;
8+
using BTCPayServer.Plugins.USDt.Configuration;
9+
using BTCPayServer.Plugins.USDt.Configuration.Ethereum;
10+
using BTCPayServer.Plugins.USDt.Controllers.ViewModels;
11+
using BTCPayServer.Plugins.USDt.Services.Events;
12+
using Microsoft.AspNetCore.Authorization;
13+
using Microsoft.AspNetCore.Mvc;
14+
using Microsoft.Extensions.Configuration;
15+
using NBXplorer;
16+
17+
namespace BTCPayServer.Plugins.USDt.Controllers;
18+
19+
[Route("server/ethErc20like")]
20+
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
21+
[Authorize(Policy = Policies.CanModifyServerSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
22+
public class UIEthErc20LikeServerController(
23+
IConfiguration configuration,
24+
ISettingsRepository settingsRepository,
25+
NBXplorerNetworkProvider nbXplorerNetworkProvider,
26+
USDtPluginConfiguration usdtPluginConfiguration,
27+
EventAggregator eventAggregator) : Controller
28+
{
29+
[HttpGet]
30+
public async Task<IActionResult> GetServerConfig()
31+
{
32+
var ethConfiguration = usdtPluginConfiguration.EthereumErc20LikeConfigurationItems.SingleOrDefault().Value;
33+
if (ethConfiguration is null)
34+
throw new InvalidOperationException();
35+
36+
var defaultConfiguration = USDtPlugin.GetEthUSDtLikeDefaultConfigurationItem(nbXplorerNetworkProvider, configuration);
37+
var serverSettings = await settingsRepository.GetSettingAsync<EthUSDtLikeServerSettings>(USDtPlugin.ServerSettingsKey(ethConfiguration));
38+
39+
var viewModel = new EthErc20LikeServerConfigViewModel
40+
{
41+
DefaultSmartContractAddress = defaultConfiguration.SmartContractAddress,
42+
DefaultJsonRpcUri = defaultConfiguration.JsonRpcUri,
43+
44+
SmartContractAddress = serverSettings?.SmartContractAddress,
45+
JsonRpcUri = serverSettings?.JsonRpcUri?.AbsoluteUri
46+
};
47+
return View(viewModel);
48+
}
49+
50+
[HttpPost]
51+
[ValidateAntiForgeryToken]
52+
public async Task<IActionResult> GetServerConfig(EthErc20LikeServerConfigViewModel viewModel)
53+
{
54+
var currentConfiguration = usdtPluginConfiguration.EthereumErc20LikeConfigurationItems.SingleOrDefault().Value;
55+
if (currentConfiguration is null)
56+
throw new InvalidOperationException();
57+
58+
var defaultConfiguration = USDtPlugin.GetEthUSDtLikeDefaultConfigurationItem(nbXplorerNetworkProvider, configuration);
59+
if (!ModelState.IsValid)
60+
{
61+
viewModel.DefaultSmartContractAddress = defaultConfiguration.SmartContractAddress;
62+
viewModel.DefaultJsonRpcUri = defaultConfiguration.JsonRpcUri;
63+
return View(viewModel);
64+
}
65+
66+
var serverSettings = new EthUSDtLikeServerSettings
67+
{
68+
SmartContractAddress = string.IsNullOrWhiteSpace(viewModel.SmartContractAddress) ? null : viewModel.SmartContractAddress,
69+
JsonRpcUri = string.IsNullOrWhiteSpace(viewModel.JsonRpcUri) ? null : new Uri(viewModel.JsonRpcUri)
70+
};
71+
72+
await settingsRepository.UpdateSetting(serverSettings, USDtPlugin.ServerSettingsKey(currentConfiguration));
73+
74+
usdtPluginConfiguration.EthereumErc20LikeConfigurationItems[currentConfiguration.GetPaymentMethodId()] =
75+
USDtPlugin.OverrideWithServerSettings(defaultConfiguration, settingsRepository);
76+
77+
eventAggregator.Publish(new EthErc20SettingsChanged());
78+
79+
return RedirectToAction("GetServerConfig");
80+
}
81+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using BTCPayServer.Validation;
3+
4+
namespace BTCPayServer.Plugins.USDt.Controllers.ViewModels;
5+
6+
public class EthErc20LikeServerConfigViewModel
7+
{
8+
// No checksum enforcement here; we normalize to lowercase elsewhere
9+
public string? SmartContractAddress { get; init; }
10+
public string? DefaultSmartContractAddress { get; set; }
11+
12+
[Uri]
13+
public string? JsonRpcUri { get; init; }
14+
public Uri? DefaultJsonRpcUri { get; set; }
15+
}

BTCPayServer.Plugins.USDt/USDtPlugin.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ private void RegisterServices(IServiceCollection services)
125125
// Store UI extensions for ETH ERC20 (addresses management & checkout)
126126
services.AddUIExtension("store-wallets-nav", "EthErc20/StoreWalletsNavEthErc20Extension");
127127
services.AddUIExtension("checkout-payment-method", "EthErc20/EmptyCheckoutPaymentMethodExtension");
128+
129+
// Server settings navigation
130+
services.AddUIExtension("server-nav","EthErc20/ServerNavEthErc20Extension");
128131
}
129132

130133
services.AddSingleton<ISwaggerProvider, SwaggerProvider>();
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@using BTCPayServer
2+
@using BTCPayServer.Abstractions.Contracts
3+
@using BTCPayServer.Abstractions.Extensions
4+
@using BTCPayServer.Client
5+
@using BTCPayServer.Data
6+
@using BTCPayServer.Plugins.USDt.Configuration
7+
@using BTCPayServer.Plugins.USDt.Controllers
8+
@using BTCPayServer.Views.Server
9+
@using Microsoft.AspNetCore.Identity
10+
@using Microsoft.AspNetCore.Mvc.TagHelpers
11+
@inject SignInManager<ApplicationUser> SignInManager;
12+
@inject USDtPluginConfiguration USDtPluginConfiguration;
13+
@inject IScopeProvider ScopeProvider
14+
@{
15+
var storeId = ScopeProvider.GetCurrentStoreId();
16+
var isSettingsActive = ViewData.IsCategoryActive(typeof(ServerNavPages)) && !ViewData.IsPageActive([ServerNavPages.Plugins]);
17+
var isActive = !string.IsNullOrEmpty(storeId) && ViewContext.RouteData.Values.TryGetValue("Controller", out var controller) && controller is not null &&
18+
nameof(UIEthErc20LikeServerController).StartsWith(controller.ToString() ?? string.Empty, StringComparison.InvariantCultureIgnoreCase);
19+
}
20+
21+
@if ((isSettingsActive && SignInManager.IsSignedIn(User) && User.IsInRole(Roles.ServerAdmin) && USDtPluginConfiguration.EthereumErc20LikeConfigurationItems.Any()) || isActive)
22+
{
23+
<li class="nav-item nav-item-sub" permission="@Policies.CanModifyServerSettings">
24+
<a asp-controller="UIEthErc20LikeServer" class="nav-link @(isActive ? "active" : string.Empty)" asp-action="GetServerConfig">USDon ETHEREUM</a>
25+
</li>
26+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
@using BTCPayServer.Abstractions.Extensions
2+
@using Microsoft.AspNetCore.Mvc.TagHelpers
3+
@model BTCPayServer.Plugins.USDt.Controllers.ViewModels.EthErc20LikeServerConfigViewModel;
4+
@{
5+
ViewData.SetActivePage("USD\u20ae on ETHEREUM server settings", "USD\u20ae on ETHEREUM server settings", "USD\u20ae on ETHEREUM server settings");
6+
ViewData["NavPartialName"] = "../UIStores/_Nav";
7+
}
8+
9+
<form method="post" enctype="multipart/form-data">
10+
<div class="sticky-header">
11+
<h2>USD₮ on ETHEREUM server settings</h2>
12+
<button id="SaveButton" type="submit" class="btn btn-primary" name="command" value="Save">Save</button>
13+
</div>
14+
<div class="row">
15+
<div class="col-md-6">
16+
<div asp-validation-summary="All"></div>
17+
</div>
18+
</div>
19+
<partial name="_StatusMessage"/>
20+
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
21+
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
22+
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
23+
</symbol>
24+
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
25+
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
26+
</symbol>
27+
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
28+
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
29+
</symbol>
30+
</svg>
31+
<div class="row">
32+
<div class="col-md-8">
33+
<h4>Node connection</h4>
34+
<div class="form-group">
35+
<div class="d-flex flex-wrap align-items-center justify-content-between gap-3">
36+
<label asp-for="JsonRpcUri" class="form-label">JSON-RPC API Uri</label>
37+
</div>
38+
<input asp-for="JsonRpcUri" type="text" class="form-control" placeholder="@ViewData.Model.DefaultJsonRpcUri" style="flex: 1 1 14rem">
39+
<span asp-validation-for="JsonRpcUri" class="text-danger"></span>
40+
<div class="form-text">
41+
Please provide the URL of the JSON-RPC API
42+
<small>
43+
<a href="https://ethereum.org/en/developers/docs/apis/json-rpc/" target="_blank" rel="noreferrer noopener">
44+
<vc:icon symbol="info"/>
45+
</a>
46+
</small> of the node you wish to use for the connection with the Ethereum chain. By default, it uses a public node.
47+
</div>
48+
</div>
49+
<h4>Advanced</h4>
50+
<div class="alert alert-warning d-flex align-items-center" role="alert">
51+
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Warning:">
52+
<use xlink:href="#exclamation-triangle-fill"/>
53+
</svg>
54+
<div>
55+
Only change this parameter if YOU KNOW WHAT YOU ARE DOING. It can cause <b>security</b> and reliability issues.
56+
</div>
57+
</div>
58+
<div class="form-group">
59+
<div class="d-flex flex-wrap align-items-center justify-content-between gap-3">
60+
<label asp-for="SmartContractAddress" class="form-label">Smart contract address</label>
61+
</div>
62+
<input asp-for="SmartContractAddress" type="text" class="form-control" placeholder="@ViewData.Model.DefaultSmartContractAddress" style="flex: 1 1 14rem">
63+
<span asp-validation-for="SmartContractAddress" class="text-danger"></span>
64+
<div class="form-text">
65+
Please provide the address of the USDT smart contract on Ethereum
66+
<small>
67+
<a href="https://tether.to/en/supported-protocols" target="_blank" rel="noreferrer noopener">
68+
<vc:icon symbol="info"/>
69+
</a>
70+
</small>. By default, it uses the official mainnet contract.
71+
</div>
72+
</div>
73+
</div>
74+
</div>
75+
</form>
76+
77+
@* ReSharper disable once Razor.SectionNotResolved *@
78+
79+
@section PageFootContent {
80+
@await Html.PartialAsync("_ValidationScriptsPartial")
81+
}

0 commit comments

Comments
 (0)