update ff

This commit is contained in:
Kukks
2023-05-23 12:12:44 +02:00
parent 26cae41a82
commit bee805f545
12 changed files with 172 additions and 122 deletions

View File

@@ -9,7 +9,7 @@
<PropertyGroup>
<Product>FixedFloat</Product>
<Description>Allows you to embed a FixedFloat conversion screen to allow customers to pay with altcoins.</Description>
<Version>1.0.6</Version>
<Version>1.1.0</Version>
</PropertyGroup>
<!-- Plugin development properties -->
<PropertyGroup>
@@ -29,11 +29,11 @@
<ItemGroup>
<EmbeddedResource Include="Resources\**"/>
<ProjectReference Include="..\..\submodules\btcpayserver\BTCPayServer\BTCPayServer.csproj"/>
<EmbeddedResource Include="Resources\**" />
<ProjectReference Include="..\..\submodules\btcpayserver\BTCPayServer\BTCPayServer.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources"/>
<Folder Include="Resources" />
</ItemGroup>
</Project>

View File

@@ -12,45 +12,31 @@ namespace BTCPayServer.Plugins.FixedFloat
[Route("plugins/{storeId}/FixedFloat")]
public class FixedFloatController : Controller
{
private readonly BTCPayServerClient _btcPayServerClient;
private readonly FixedFloatService _FixedFloatService;
public FixedFloatController(BTCPayServerClient btcPayServerClient, FixedFloatService FixedFloatService)
public FixedFloatController(FixedFloatService FixedFloatService)
{
_btcPayServerClient = btcPayServerClient;
_FixedFloatService = FixedFloatService;
}
[HttpGet("")]
public async Task<IActionResult> UpdateFixedFloatSettings(string storeId)
{
var store = await _btcPayServerClient.GetStore(storeId);
UpdateFixedFloatSettingsViewModel vm = new UpdateFixedFloatSettingsViewModel();
vm.StoreName = store.Name;
FixedFloatSettings FixedFloat = null;
FixedFloatSettings settings = null;
try
{
FixedFloat = await _FixedFloatService.GetFixedFloatForStore(storeId);
settings = await _FixedFloatService.GetFixedFloatForStore(storeId);
}
catch (Exception)
{
// ignored
}
SetExistingValues(FixedFloat, vm);
return View(vm);
}
private void SetExistingValues(FixedFloatSettings existing, UpdateFixedFloatSettingsViewModel vm)
{
if (existing == null)
return;
vm.Enabled = existing.Enabled;
return View(settings);
}
[HttpPost("")]
public async Task<IActionResult> UpdateFixedFloatSettings(string storeId, UpdateFixedFloatSettingsViewModel vm,
public async Task<IActionResult> UpdateFixedFloatSettings(string storeId, FixedFloatSettings vm,
string command)
{
if (vm.Enabled)
@@ -61,15 +47,10 @@ namespace BTCPayServer.Plugins.FixedFloat
}
}
var FixedFloatSettings = new FixedFloatSettings()
{
Enabled = vm.Enabled,
};
switch (command)
{
case "save":
await _FixedFloatService.SetFixedFloatForStore(storeId, FixedFloatSettings);
await _FixedFloatService.SetFixedFloatForStore(storeId, vm);
TempData["SuccessMessage"] = "FixedFloat settings modified";
return RedirectToAction(nameof(UpdateFixedFloatSettings), new {storeId});

View File

@@ -9,15 +9,13 @@ namespace BTCPayServer.Plugins.FixedFloat
{
public override IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } =
{
new() { Identifier = nameof(BTCPayServer), Condition = ">=1.7.4" }
new() { Identifier = nameof(BTCPayServer), Condition = ">=1.9.0" }
};
public override void Execute(IServiceCollection applicationBuilder)
{
applicationBuilder.AddSingleton<FixedFloatService>();
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("FixedFloat/FixedFloatNav",
"store-integrations-nav"));
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("FixedFloat/StoreIntegrationFixedFloatOption",
"store-integrations-list"));
// Checkout v2
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("FixedFloat/CheckoutPaymentMethodExtension",
"checkout-payment-method"));

View File

@@ -1,8 +1,75 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace BTCPayServer.Plugins.FixedFloat
{
public class FixedFloatSettings
{
public bool Enabled { get; set; }
public decimal AmountMarkupPercentage { get; set; } = 0;
public string? PreferredTargetPaymentMethodId { get; set; }
public string[] ExplicitMethods { get; set; }
public bool OnlyShowExplicitMethods { get; set; } = false;
public static Dictionary<string, string> AllowedSendingOptions = new()
{
{"AAVEETH", "Aave (ERC20)"},
{"ADA", "Cardano"},
{"ATOM", "Cosmos"},
{"AVAX", "Avalanche (C-Chain)"},
{"BAT", "Basic Attention (ERC20)"},
{"BCH", "Bitcoin Cash"},
{"BNB", "BNB Beacon Chain (BEP2)"},
{"BSC", "BNB Smart Chain (BEP20)"},
{"BTC", "Bitcoin"},
{"BTCLN", "Bitcoin (Lightning)"},
{"BTT", "BitTorrent"},
{"BUSD", "Binance USD (BEP2)"},
{"BUSDBSC", "Binance USD (BEP20)"},
{"BUSDETH", "Binance USD (ERC20)"},
{"CAKE", "PancakeSwap (BEP20)"},
{"DAIETH", "DAI (ERC20)"},
{"DOGE", "Dogecoin"},
{"DOT", "Polkadot"},
{"EOS", "EOS"},
{"ETC", "Ethereum Classic"},
{"ETH", "Ethereum"},
{"FTM", "Fantom"},
{"LINK", "Chainlink (ERC20)"},
{"LTC", "Litecoin"},
{"MANAETH", "Decentraland (ERC20)"},
{"MATIC", "Polygon"},
{"MATICETH", "Polygon (ERC20)"},
{"MKR", "Maker (ERC20)"},
{"SHIB", "SHIBA INU (ERC20)"},
{"SOL", "Solana"},
{"TON", "Toncoin"},
{"TRX", "Tron"},
{"TUSD", "TrueUSD (ERC20)"},
{"TWT", "Trust Wallet Token (BEP2)"},
{"TWTBSC", "Trust Wallet Token (BEP20)"},
{"USDCETH", "USD Coin (ERC20)"},
{"USDCSOL", "USD Coin (Solana)"},
{"USDCTRC", "USD Coin (TRC20)"},
{"USDP", "Pax Dollar (ERC20)"},
{"USDT", "Tether (ERC20)"},
{"USDTSOL", "Tether (Solana)"},
{"USDTTRC", "Tether (TRC20)"},
{"VET", "VeChain"},
{"XMR", "Monero"},
{"XRP", "Ripple"},
{"XTZ", "Tezos"},
{"ZEC", "Zcash"},
{"ZRX", "0x (ERC20)"}
};
public static List<SelectListItem> AllowedSendingOptionsList => AllowedSendingOptions.Select(o => new SelectListItem(o.Value, o.Key)).ToList();
}
}

View File

@@ -1,8 +0,0 @@
namespace BTCPayServer.Plugins.FixedFloat
{
public class UpdateFixedFloatSettingsViewModel
{
public bool Enabled { get; set; }
public string StoreName { get; set; }
}
}

View File

@@ -1,11 +1,20 @@
@using BTCPayServer.Abstractions.Extensions
@using BTCPayServer
@using BTCPayServer.Abstractions.Extensions
@using BTCPayServer.Data
@using BTCPayServer.Plugins.FixedFloat
@using BTCPayServer.Services.Stores
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model BTCPayServer.Plugins.FixedFloat.UpdateFixedFloatSettingsViewModel
@model BTCPayServer.Plugins.FixedFloat.FixedFloatSettings
@inject BTCPayNetworkProvider BTCPayNetworkProvider
@{
ViewData.SetActivePage("FixedFloat", "FixedFloat", "FixedFloat");
var store = Context.GetStoreData();
var allowedPaymentMethods = store.GetEnabledPaymentIds(BTCPayNetworkProvider)
.Select(pmi => new SelectListItem(pmi.ToPrettyString(), pmi.ToString()))
.Prepend(new SelectListItem("Any", ""));
}
<partial name="_StatusMessage" />
<partial name="_StatusMessage"/>
<h2 class="mb-4">@ViewData["Title"]</h2>
@@ -22,6 +31,21 @@
<label asp-for="Enabled" class="form-label mb-0 me-1"></label>
</div>
</div>
<div class="form-group">
<label asp-for="PreferredTargetPaymentMethodId" class="form-label" data-required>Convert always to this payment method, if possible</label>
<select asp-for="PreferredTargetPaymentMethodId" asp-items="allowedPaymentMethods" class="form-select"></select>
</div>
<div class="form-group">
<label asp-for="ExplicitMethods" class="form-label" data-required>Show these conversion options as individual payment methods</label>
<select style="min-height: 500px;" multiple asp-for="ExplicitMethods" asp-items="@FixedFloatSettings.AllowedSendingOptionsList" class="form-select"></select>
</div>
<div class="form-group">
<div class="d-flex align-items-center">
<input asp-for="OnlyShowExplicitMethods" type="checkbox" class="btcpay-toggle me-2"/>
<label asp-for="OnlyShowExplicitMethods" class="form-label mb-0 me-1">Only show explicit methods</label>
</div>
</div>
<button name="command" type="submit" value="save" class="btn btn-primary">Submit</button>
</form>
</div>

View File

@@ -1,10 +1,10 @@
@using BTCPayServer.Plugins.FixedFloat
@using Newtonsoft.Json
@using Newtonsoft.Json.Linq
@model BTCPayServer.Models.InvoicingModels.PaymentModel
@inject FixedFloatService FixedFloatService
@{
var storeId = ((JObject)JObject.Parse(JsonConvert.SerializeObject(Model)))["StoreId"].Value<string>();
var storeId = Model.StoreId;
var settings = await FixedFloatService.GetFixedFloatForStore(storeId);
if (settings?.Enabled is true)
{
<div id="FixedFloat" class="bp-view payment manual-flow" style="padding:0" :class="{ active: currentTab == 'undefined' || currentTab == 'FixedFloat' }">

View File

@@ -1,28 +1,58 @@
@using BTCPayServer.Plugins.FixedFloat
@using Newtonsoft.Json
@using Newtonsoft.Json.Linq
@inject FixedFloatService FixedFloatService
@model BTCPayServer.Models.InvoicingModels.PaymentModel
@{
var storeId = ((JObject)JObject.Parse(JsonConvert.SerializeObject(Model)))["StoreId"].Value<string>();
var storeId = Model.StoreId;
var settings = await FixedFloatService.GetFixedFloatForStore(storeId);
var preferredTargetPaymentMethodId = string.IsNullOrEmpty(settings.PreferredTargetPaymentMethodId) ? null : Model.AvailableCryptos.Any(crypto => crypto.PaymentMethodId == settings.PreferredTargetPaymentMethodId) ? settings.PreferredTargetPaymentMethodId : null;
}
@if (settings?.Enabled is true)
{
<template id="fixed-float-checkout-template">
<iframe :src="url" style="min-height:600px;width:100%;border:none" allowtransparency="true"></iframe>
<iframe v-if="shown" :src="url" style="min-height:600px;width:100%;border:none" allowtransparency="true" ref="iframe"></iframe>
</template>
<script>
const markupPercentage = @settings.AmountMarkupPercentage;
Vue.component("FixedFloatCheckout", {
template: "#fixed-float-checkout-template",
props: ["model"],
data: function() {
return {
explicitId: "",
preferredToCurrency: @Json.Serialize(preferredTargetPaymentMethodId),
}
},
created () {
const self = this;
setInterval(function() {
if ( self.explicitId === window.ffExplicitId) {
return;
}
self.explicitId = window.ffExplicitId;
},200)
},
computed: {
shown (){
const result = this.$parent.paymentMethodId === "FixedFloat";
if(this.preferredToCurrency && this.model.paymentMethodId !== this.preferredToCurrency){
this.$parent.paymentMethodId = this.preferredToCurrency;
this.$parent.fetchData().then(()=> {
this.$parent.paymentMethodId = "FixedFloat";
});
return false;
}
return result;
},
url () {
return "https://widget.fixedfloat.com/?" +
`to=${this.settleMethodId}` +
"&lockReceive=true&ref=fkbyt39c" +
`&address=${this.model.btcAddress}` +
this.amountQuery;
this.amountQuery +
this.explicitQuery;
},
currency () {
return this.model.paymentMethodId;
@@ -32,6 +62,11 @@
? 'BTCLN'
: this.currency.replace('_BTCLike', '').replace('_MoneroLike', '').replace('_ZcashLike', '').toUpperCase();
},
explicitQuery (){
const isExplicit = !!this.explicitId;
const explicitFrom = isExplicit ? this.explicitId: null;
return isExplicit? `&from=${explicitFrom}&lockSend=true` : '';
},
amountQuery () {
return this.model.isUnsetTopUp
? ''

View File

@@ -1,16 +1,28 @@
@using BTCPayServer.Plugins.FixedFloat
@using Newtonsoft.Json
@using Newtonsoft.Json.Linq
@model BTCPayServer.Models.InvoicingModels.PaymentModel
@inject FixedFloatService FixedFloatService
@{
const string id = "FixedFloat";
var storeId = ((JObject)JObject.Parse(JsonConvert.SerializeObject(Model)))["StoreId"].Value<string>();
var storeId = Model.StoreId;
var settings = await FixedFloatService.GetFixedFloatForStore(storeId);
if (settings?.Enabled is true)
{
<a href="#@id" class="btcpay-pill m-0 payment-method" :class="{ active: pmId === '@id' }" v-on:click.prevent="changePaymentMethod('@id')">
@id
</a>
if (settings.ExplicitMethods?.Any() is true)
{
foreach (var explicitMethod in settings.ExplicitMethods)
{
<a href="#@id" class="btcpay-pill m-0 payment-method" :class="{ active: pmId === '@id' && window.ffExplicitId === '@explicitMethod'}" v-on:click.prevent="()=>{ window.ffExplicitId = '@explicitMethod'; changePaymentMethod('@id'); }">
@FixedFloatSettings.AllowedSendingOptions[explicitMethod]
</a>
}
}
if (!settings.OnlyShowExplicitMethods || settings.ExplicitMethods?.Any() is not true)
{
<a href="#@id" class="btcpay-pill m-0 payment-method" :class="{ active: pmId === '@id' && !window.ffExplicitId }" v-on:click.prevent="()=>{ window.ffExplicitId = null; changePaymentMethod('@id'); }">
@id
</a>
}
}
}

View File

@@ -1,13 +1,12 @@
@using BTCPayServer.Plugins.FixedFloat
@using Newtonsoft.Json
@using Newtonsoft.Json.Linq
@model BTCPayServer.Models.InvoicingModels.PaymentModel
@inject FixedFloatService FixedFloatService
@{
var storeId = ((JObject)JObject.Parse(JsonConvert.SerializeObject(Model)))["StoreId"].Value<string>();
var storeId = Model.StoreId;
var settings = await FixedFloatService.GetFixedFloatForStore(storeId);
if (settings?.Enabled is true)
{
<div class="payment-tabs__tab py-0" id="FixedFloat-tab" v-on:click="switchTab('FixedFloat')" v-bind:class="{ 'active': currentTab == 'FixedFloat'}" v-if="!srvModel.paymentMethodId.endsWith('LNURLPAY')">
<div class="payment-tabs__tab py-0" id="FixedFloat-tab" v-on:click="switchTab('FixedFloat')" v-bind:class="{ 'active': currentTab == 'FixedFloat'}">
<span>{{$t("Altcoins (FixedFloat)")}}</span>
</div>
}

View File

@@ -1,58 +0,0 @@
@using BTCPayServer.Abstractions.Contracts
@using BTCPayServer.Plugins.FixedFloat
@using Microsoft.AspNetCore.Routing
@inject FixedFloatService FixedFloatService
@inject IScopeProvider ScopeProvider
@{
var storeId = ScopeProvider.GetCurrentStoreId();
FixedFloatSettings settings = null;
if (!string.IsNullOrEmpty(storeId))
{
try
{
settings = await FixedFloatService.GetFixedFloatForStore(storeId);
}
catch (Exception)
{
}
}
}
@if (!string.IsNullOrEmpty(storeId))
{
<li class="list-group-item bg-tile ">
<div class="d-flex align-items-center">
<span class="d-flex flex-wrap flex-fill flex-column flex-sm-row">
<strong class="me-3">
FixedFloat
</strong>
<span title="" class="d-flex me-3">
<span class="text-secondary">Allows your customers to pay with altcoins that are not supported by BTCPay Server.</span>
</span>
</span>
<span class="d-flex align-items-center fw-semibold">
@if (settings?.Enabled is true)
{
<span class="d-flex align-items-center text-success">
<span class="me-2 btcpay-status btcpay-status--enabled"></span>
Enabled
</span>
<span class="text-light ms-3 me-2">|</span>
<a lass="btn btn-link px-1 py-1 fw-semibold" asp-controller="FixedFloat" asp-action="UpdateFixedFloatSettings" asp-route-storeId="@storeId">
Modify
</a>
}
else
{
<span class="d-flex align-items-center text-danger">
<span class="me-2 btcpay-status btcpay-status--disabled"></span>
Disabled
</span>
<a class="btn btn-primary btn-sm ms-4 px-3 py-1 fw-semibold" asp-controller="FixedFloat" asp-action="UpdateFixedFloatSettings" asp-route-storeId="@storeId">
Setup
</a>
}
</span>
</div>
</li>
}