Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RawTransactionModal for TRX processes #168

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/Angor/Client/Components/RawTransactionModal.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@using Angor.Shared.Models
@inject IClipboardService ClipboardService

@if (IsVisible)
{
<div class="modal-wrapper">
<div class="modal fade show d-block">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Raw Transaction JSON</h5>
<span type="button" @onclick="CloseModal" aria-label="Close">
<Icon IconName="close-circle"/>
<i @onclick="CopyToClipboard" class="ms-auto cursor-pointer user-select-none">
<Icon IconName="copy"></Icon>
</i>
</span>
</div>
<div class="modal-body">
<pre>@RawTransactionJson</pre>
</div>
</div>
</div>
</div>
</div>
}

@code {
[Parameter] public string RawTransactionJson { get; set; }
[Parameter] public bool IsVisible { get; set; }
[Parameter] public EventCallback<bool> IsVisibleChanged { get; set; }

private async Task CloseModal()
{
await IsVisibleChanged.InvokeAsync(false);
}

private async Task CopyToClipboard()
{
await ClipboardService.WriteTextAsync(RawTransactionJson);
}
}
58 changes: 55 additions & 3 deletions src/Angor/Client/Pages/Invest.razor
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
@using Nostr.Client.Keys
@using System.Diagnostics
@using Angor.Client.Models
@using System.Text.Json


@inherits BaseComponent

Expand Down Expand Up @@ -242,6 +244,11 @@
}
</button>
</div>
<button class="btn btn-primary" @onclick="ShowTransactionJsonModal">
Show Transaction Details
</button>

<RawTransactionModal RawTransactionJson="@transactionJson" IsVisible="@showTransactionJsonModal" IsVisibleChanged="HandleTransactionJsonModalVisibility"/>
</div>
</div>
</div>
Expand Down Expand Up @@ -353,7 +360,8 @@ else
private bool investSpinner = false;
private bool publishSpinner = false;
private bool refreshSpinner = false;

private bool showTransactionJsonModal = false;
private string transactionJson;

public InvestmentModel Investment { get; set; } = new InvestmentModel { InvestmentAmount = 10 };
private bool IsSeederTimePassed { get; set; }
Expand All @@ -364,7 +372,7 @@ else
private bool showCreateModal;
TransactionInfo? signedTransaction;
Transaction unSignedTransaction;


private FeeData feeData = new();

Expand Down Expand Up @@ -531,12 +539,19 @@ else
{
if (Investment.IsSeeder)
{
var minSeederAmount = 2;
var minSeederAmount = 0.01m;
var maxSeederAmount = 0.1m;
if (Investment.InvestmentAmount < minSeederAmount)
{
notificationComponent.ShowErrorMessage($"Seeder minimum investment amount of {minSeederAmount} BTC was not reached");
return;
}

if (Investment.InvestmentAmount > maxSeederAmount)
{
notificationComponent.ShowErrorMessage($"Maximum investment amount of {maxSeederAmount} BTC exceeded");
return;
}
}
else
{
Expand Down Expand Up @@ -883,4 +898,41 @@ else
public DateTime StageDateTime { get; set; }
public int DaysFromStartDate { get; set; }
}

private async Task PrepareInvestmentTransactionJson()
{
var transactionDetails = new
{
ProjectIdentifier = project.ProjectInfo.ProjectIdentifier,
FounderKey = project.ProjectInfo.FounderKey.Substring(0, 10) + "...",
TargetAmount = $"{project.ProjectInfo.TargetAmount} {network.CoinTicker}",
StartDate = project.ProjectInfo.StartDate.ToString("dd/MM/yyyy"),
ExpiryDate = project.ProjectInfo.ExpiryDate.ToString("dd/MM/yyyy"),
PenaltyDays = project.ProjectInfo.PenaltyDays,
MinerFee = Money.Satoshis(signedTransaction?.TransactionFee ?? 0).ToUnit(MoneyUnit.BTC),
AngorFee = signedTransaction?.Transaction.Outputs.First().Value.ToUnit(MoneyUnit.BTC) ?? 0,
FeeRate = $"{feeData.SelectedFeeEstimation.FeeRate} sats",
Confirmations = feeData.SelectedFeeEstimation.Confirmations,
Stages = project.ProjectInfo.Stages.Select((stage, index) => new
{
StageAmount = $"{StagesBreakdown[index].Amount} BTC - {stage.AmountToRelease}%",
StageDate = stage.ReleaseDate.ToString("dd/MM/yyyy"),
DaysAfterStart = (stage.ReleaseDate - project.ProjectInfo.StartDate).Days
}).ToList()
};

transactionJson = JsonSerializer.Serialize(transactionDetails, new JsonSerializerOptions { WriteIndented = true });
}


private async Task ShowTransactionJsonModal()
{
await PrepareInvestmentTransactionJson();
showTransactionJsonModal = true;
}

private void HandleTransactionJsonModalVisibility(bool isVisible)
{
showTransactionJsonModal = isVisible;
}
}
41 changes: 40 additions & 1 deletion src/Angor/Client/Pages/Spend.razor
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
@using Blockcore.NBitcoin.DataEncoders
@using Angor.Shared.Utilities
@using ITransactionSignature = NBitcoin.ITransactionSignature
@using System.Text.Json


@inject IClientStorage storage;
@inject ICacheStorage _cacheStorage;
Expand All @@ -25,6 +27,7 @@

<NotificationComponent @ref="notificationComponent" />
<PasswordComponent @ref="passwordComponent" />
<RawTransactionModal RawTransactionJson="@rawTransactionJson" IsVisible="@showRawTransactionModal" IsVisibleChanged="HandleRawTransactionModalVisibility"/>


@if (!hasWallet)
Expand Down Expand Up @@ -193,7 +196,7 @@

</div>
<div class="modal-footer">
<button type="button" class="btn btn-border" @onclick="Send" disabled="@spendSpinner">
<button type="button" class="btn btn-border" @onclick="Send" disabled="@spendSpinner">
@if (spendSpinner)
{
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Expand All @@ -204,6 +207,9 @@
<span>Confirm</span>
}
</button>
<button class="btn btn-primary" @onclick="ShowTransactionJsonModal">
Show Transaction Details
</button>
</div>
</div>
</div>
Expand Down Expand Up @@ -244,6 +250,9 @@

private int? expandedStageId;
private bool showCreateModal;

private bool showRawTransactionModal = false;
private string rawTransactionJson;

private bool refreshSpinner = false;
private bool firstTimeRefreshSpinner = false;
Expand Down Expand Up @@ -713,4 +722,34 @@
}
}

private async Task ShowTransactionJsonModal()
{
rawTransactionJson = PrepareTransactionDetails();
showRawTransactionModal = true;
}

private string PrepareTransactionDetails()
{
var transactionDetails = new
{
ProjectIdentifier = project.ProjectIdentifier,
TotalSpent = signedTransaction.Transaction.Outputs.Sum(s => s.Value.ToUnit(MoneyUnit.BTC)),
MinerFee = Money.Satoshis(signedTransaction.TransactionFee).ToUnit(MoneyUnit.BTC),
FeeRate = feeData.SelectedFeeEstimation.FeeRate,
Confirmations = feeData.SelectedFeeEstimation.Confirmations,
Utxos = selectedUtxos.Select(utxo => new
{
Stage = GetStageIndexForUtxo(utxo.Key),
TransactionId = utxo.Key.Trxid,
OutputIndex = utxo.Key.Outputindex
}).ToList()
};

return JsonSerializer.Serialize(transactionDetails, new JsonSerializerOptions { WriteIndented = true });
}

private void HandleRawTransactionModalVisibility(bool isVisible)
{
showRawTransactionModal = isVisible;
}
}
84 changes: 50 additions & 34 deletions src/Angor/Client/Pages/Wallet.razor
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ else
@if (sendConfirmModal)
{
<!-- Send Confirmation Modal -->

<div class="modal-wrapper">
<div class="modal fade show d-block">
<div class="modal-dialog">
Expand All @@ -510,13 +511,8 @@ else
</span>
</div>
<div class="modal-body modal-body-scroll">
Are you sure you want to send <strong>@_sendInfo.SendAmount @network.CoinTicker</strong> to <strong> @_sendInfo.SendToAddress?</strong>

<br/>

The fee for this transaction will be <strong>@_sendInfo.SendFee</strong>

<hr>
<p>Are you sure you want to send @_sendInfo.SendAmount to @_sendInfo.SendToAddress?</p>
<p>Fees: @_sendInfo.SendFee</p>

<div class="mb-3">
<label for="feeRange" class="form-label">Feerate for @_sendInfo.FeeBlockCount blocks is @_sendInfo.FeeRate sats</label>
Expand Down Expand Up @@ -550,6 +546,9 @@ else
<span>Confirm</span>
}
</button>
<button class="btn btn-outline-primary" @onclick="ShowTransactionJson">
View Transaction Details
</button>
</div>
</div>
</div>
Expand Down Expand Up @@ -678,6 +677,9 @@ else
</div>
</div>
</div>
<RawTransactionModal RawTransactionJson="@rawTransactionJson" IsVisible="@showRawTransactionModal" IsVisibleChanged="HandleModalVisibility" />
<RawTransactionModal RawTransactionJson="@transactionJson" IsVisible="@showTransactionJsonModal" IsVisibleChanged="HandleTransactionJsonModalVisibility" />

</div>
}

Expand Down Expand Up @@ -725,6 +727,8 @@ else

private bool showRawTransactionModal;
private string rawTransactionJson = string.Empty;
private string transactionJson;
private bool showTransactionJsonModal = false;

private readonly AccountBalanceInfo accountBalanceInfo = new();

Expand Down Expand Up @@ -1300,12 +1304,14 @@ else
showRawTransactionModal = true;
}

private void HandleModalVisibility(bool isVisible)
{
showRawTransactionModal = isVisible;
}

private string GetRawTransactionJson(AddressInfo addressInfo)
{
var options = new JsonSerializerOptions
{
WriteIndented = true
};
var options = new JsonSerializerOptions { WriteIndented = true };
return JsonSerializer.Serialize(addressInfo, options);
}

Expand All @@ -1315,31 +1321,41 @@ else
notificationComponent.ShowNotificationMessage("Copied to clipboard!", 3);
StateHasChanged();
}

private async Task PrepareTransactionJson()
{
var transactionDetails = new
{
Amount = _sendInfo.SendAmount,
ToAddress = _sendInfo.SendToAddress,
Fee = _sendInfo.SendFee,
FeeRate = $"{_sendInfo.FeeRate} sats per byte for {_sendInfo.FeeBlockCount} block confirmations",
ChangeAddress = _sendInfo.ChangeAddress,
Inputs = _sendInfo.SendUtxos.Select(u => new
{
Address = u.Value.UtxoData.address,
Amount = Money.Satoshis(u.Value.UtxoData.value).ToUnit(MoneyUnit.BTC),
Outpoint = u.Key,
CoinTicker = network.CoinTicker
})
};

transactionJson = JsonSerializer.Serialize(transactionDetails, new JsonSerializerOptions { WriteIndented = true });
}


private async Task ShowTransactionJson()
{
await PrepareTransactionJson();
showTransactionJsonModal = true;
}

private void HandleTransactionJsonModalVisibility(bool isVisible)
{
showTransactionJsonModal = isVisible;
}


}


@if (showRawTransactionModal)
{
<div class="modal-wrapper">
<div class="modal fade show d-block">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Raw Transaction JSON</h5>
<span type="button" @onclick="() => showRawTransactionModal = false" aria-label="Close">
<Icon IconName="close-circle"/>
<i @onclick="@(async () => await CopyStringToClipboard(rawTransactionJson))" class="ms-auto cursor-pointer user-select-none">
<Icon IconName="copy"></Icon>
</i>
</span>
</div>
<div class="modal-body">
<pre>@rawTransactionJson</pre>
</div>
</div>
</div>
</div>
</div>
}
Loading