Skip to content

Commit

Permalink
Add RawTransactionModal for TRX processes (#168)
Browse files Browse the repository at this point in the history
* add in wallet, and create the component

* add RawTransactioModal for invest

* add max

* add for Spend.razor

* config
  • Loading branch information
itailiors authored Nov 8, 2024
1 parent 48f1881 commit f6d3a0a
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 38 deletions.
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>
}

0 comments on commit f6d3a0a

Please sign in to comment.