mirror of
https://github.com/status-im/nft-faucet.git
synced 2025-02-22 11:38:26 +00:00
Add Mint dialog
This commit is contained in:
parent
4a0cbb6c66
commit
6795de500f
7
NftFaucetRadzen/Models/Balance.cs
Normal file
7
NftFaucetRadzen/Models/Balance.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace NftFaucetRadzen.Models;
|
||||
|
||||
public class Balance
|
||||
{
|
||||
public decimal Amount { get; set; }
|
||||
public string Currency { get; set; }
|
||||
}
|
10
NftFaucetRadzen/Models/MintingState.cs
Normal file
10
NftFaucetRadzen/Models/MintingState.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace NftFaucetRadzen.Models;
|
||||
|
||||
public enum MintingState
|
||||
{
|
||||
CheckingNetwork,
|
||||
CheckingAddress,
|
||||
CheckingBalance,
|
||||
SendingTransaction,
|
||||
Done,
|
||||
}
|
@ -8,17 +8,17 @@
|
||||
<h4>Image</h4>
|
||||
<RadzenFileInput @bind-Value=@Model.FileData @bind-FileName=@Model.FileName @bind-FileSize=@Model.FileSize TValue="string" Class="w-100"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<h4>Name</h4>
|
||||
<RadzenTextBox Placeholder="YING #668" MaxLength="50" @bind-Value="@Model.Name" Class="w-100"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<h4>Description</h4>
|
||||
<RadzenTextArea Placeholder="YING, ecotype enterprises IP of Inkeverse and the avatar spokesperson for Inkeverse." MaxLength="250" @bind-Value="@Model.Description" Class="w-100"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="display: flex; justify-content: end;">
|
||||
<RadzenButton Click="@((args) => OnSavePressed())" Disabled="!ModelIsValid" Text="Save" Style="width: 120px"/>
|
||||
</div>
|
||||
|
93
NftFaucetRadzen/Pages/MintDialog.razor
Normal file
93
NftFaucetRadzen/Pages/MintDialog.razor
Normal file
@ -0,0 +1,93 @@
|
||||
@page "/mint/in-progress"
|
||||
@using NftFaucetRadzen.Models
|
||||
@inherits BasicComponent
|
||||
|
||||
<PageTitle>Minting...</PageTitle>
|
||||
|
||||
@if (!string.IsNullOrEmpty(ProgressBarText))
|
||||
{
|
||||
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">@ProgressBarText</RadzenText>
|
||||
<RadzenProgressBar Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" />
|
||||
}
|
||||
else if (State == MintingState.CheckingNetwork)
|
||||
{
|
||||
<RadzenContent Container="main">
|
||||
<h4>Network mismatch!</h4>
|
||||
<p>
|
||||
<text style="font-weight: bold;">Selected network: </text>
|
||||
<text style="color: green;">@(AppState?.SelectedNetwork?.Name ?? "<unknown>")</text>
|
||||
</p>
|
||||
<p>
|
||||
<text style="font-weight: bold;">Provider network: </text>
|
||||
<text style="color: red;">@(ProviderNetwork?.Name ?? "<unknown>")</text>
|
||||
</p>
|
||||
<div style="display: flex; justify-content: end;">
|
||||
<RadzenButton Click="@(async (args) => await CheckNetwork())" Text="Try again" Disabled="@(!string.IsNullOrEmpty(ProgressBarText))" />
|
||||
</div>
|
||||
</RadzenContent>
|
||||
} else if (State == MintingState.CheckingAddress)
|
||||
{
|
||||
<RadzenContent Container="main">
|
||||
<h3>Address is not available!</h3>
|
||||
<p>
|
||||
<text style="font-weight: bold;">Provider address: </text>
|
||||
@if (!string.IsNullOrEmpty(SourceAddress))
|
||||
{
|
||||
@:<text style="color: green;">@SourceAddress</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
@:<text style="color: red;"><null></text>
|
||||
}
|
||||
</p>
|
||||
<div style="display: flex; justify-content: end;">
|
||||
<RadzenButton Click="@(async (args) => await CheckNetwork())" Text="Try again" Disabled="@(!string.IsNullOrEmpty(ProgressBarText))" />
|
||||
</div>
|
||||
</RadzenContent>
|
||||
} else if (State == MintingState.CheckingBalance)
|
||||
{
|
||||
<RadzenContent Container="main">
|
||||
<h3>Not enough balance!</h3>
|
||||
<p>
|
||||
<text style="font-weight: bold;">Balance: </text>
|
||||
@if (Balance != null)
|
||||
{
|
||||
@:<text style="color: red;">@(Balance.Amount + " " + Balance.Currency)</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
@:<text style="color: red;"><unknown></text>
|
||||
}
|
||||
</p>
|
||||
<div style="display: flex; justify-content: end;">
|
||||
<RadzenButton Click="@(async (args) => await CheckNetwork())" Text="Try again" Disabled="@(!string.IsNullOrEmpty(ProgressBarText))" />
|
||||
</div>
|
||||
</RadzenContent>
|
||||
} else if (State == MintingState.SendingTransaction)
|
||||
{
|
||||
<RadzenContent Container="main">
|
||||
<h3>Failed to send transaction!</h3>
|
||||
<p>
|
||||
<text>Error message:</text>
|
||||
<br/>
|
||||
<text style="font-weight: bold; color: red;">@SendTransactionError</text>
|
||||
</p>
|
||||
<div style="display: flex; justify-content: end;">
|
||||
<RadzenButton Click="@(async (args) => await CheckNetwork())" Text="Try again" Disabled="@(!string.IsNullOrEmpty(ProgressBarText))" />
|
||||
</div>
|
||||
</RadzenContent>
|
||||
} else if (State == MintingState.Done)
|
||||
{
|
||||
<RadzenContent Container="main">
|
||||
<h3>Success</h3>
|
||||
<p>
|
||||
<text style="font-weight: bold;">Token minted!</text>
|
||||
<br/>
|
||||
<text style="font-weight: bold;">Transaction hash: </text>
|
||||
<text style="color: green;">@TransactionHash</text>
|
||||
</p>
|
||||
<div style="display: flex; justify-content: end;">
|
||||
<RadzenButton Click="@(async (args) => await Close())" Text="Close" Disabled="@(!string.IsNullOrEmpty(ProgressBarText))" />
|
||||
</div>
|
||||
</RadzenContent>
|
||||
}
|
146
NftFaucetRadzen/Pages/MintDialog.razor.cs
Normal file
146
NftFaucetRadzen/Pages/MintDialog.razor.cs
Normal file
@ -0,0 +1,146 @@
|
||||
using NftFaucetRadzen.Components;
|
||||
using NftFaucetRadzen.Models;
|
||||
using NftFaucetRadzen.Plugins.NetworkPlugins;
|
||||
using NftFaucetRadzen.Utils;
|
||||
|
||||
namespace NftFaucetRadzen.Pages;
|
||||
|
||||
public partial class MintDialog : BasicComponent
|
||||
{
|
||||
private const int MinDelayInMilliseconds = 300;
|
||||
|
||||
private string ProgressBarText { get; set; } = "Checking network...";
|
||||
private MintingState State { get; set; } = MintingState.CheckingNetwork;
|
||||
private INetwork ProviderNetwork { get; set; }
|
||||
private string SourceAddress { get; set; }
|
||||
private Balance Balance { get; set; }
|
||||
private string TransactionHash { get; set; }
|
||||
private string SendTransactionError { get; set; }
|
||||
|
||||
protected override Task OnInitializedAsync()
|
||||
{
|
||||
CheckNetwork();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task CheckNetwork()
|
||||
{
|
||||
State = MintingState.CheckingNetwork;
|
||||
ProgressBarText = "Checking network...";
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
|
||||
var providerNetworkResult = await ResultWrapper.Wrap(async () =>
|
||||
{
|
||||
var task1 = AppState.SelectedProvider.GetNetwork(AppState.PluginStorage.Networks.ToArray(), AppState.SelectedNetwork);
|
||||
var task2 = Task.Delay(TimeSpan.FromMilliseconds(MinDelayInMilliseconds));
|
||||
await Task.WhenAll(task1, task2);
|
||||
return task1.Result;
|
||||
});
|
||||
ProviderNetwork = providerNetworkResult.IsSuccess ? providerNetworkResult.Value : null;
|
||||
|
||||
if (ProviderNetwork?.Id == AppState.SelectedNetwork.Id)
|
||||
{
|
||||
CheckAddress();
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressBarText = null;
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CheckAddress()
|
||||
{
|
||||
State = MintingState.CheckingAddress;
|
||||
ProgressBarText = "Checking address...";
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
|
||||
var sourceAddressResult = await ResultWrapper.Wrap(async () =>
|
||||
{
|
||||
var task1 = AppState.SelectedProvider.GetAddress();
|
||||
var task2 = Task.Delay(TimeSpan.FromMilliseconds(MinDelayInMilliseconds));
|
||||
await Task.WhenAll(task1, task2);
|
||||
return task1.Result;
|
||||
});
|
||||
SourceAddress = sourceAddressResult.IsSuccess ? sourceAddressResult.Value : null;
|
||||
|
||||
if (!string.IsNullOrEmpty(SourceAddress))
|
||||
{
|
||||
CheckBalance();
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressBarText = null;
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CheckBalance()
|
||||
{
|
||||
State = MintingState.CheckingBalance;
|
||||
ProgressBarText = "Checking balance...";
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
|
||||
var balanceResult = await ResultWrapper.Wrap(async () =>
|
||||
{
|
||||
var task1 = AppState.SelectedProvider.GetBalance(AppState.SelectedNetwork);
|
||||
var task2 = Task.Delay(TimeSpan.FromMilliseconds(MinDelayInMilliseconds));
|
||||
await Task.WhenAll(task1, task2);
|
||||
return task1.Result;
|
||||
});
|
||||
Balance = balanceResult.IsSuccess ? balanceResult.Value : null;
|
||||
var amount = Math.Max(Balance?.Amount ?? 0, 0);
|
||||
|
||||
if (amount != 0)
|
||||
{
|
||||
SendTransaction();
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressBarText = null;
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SendTransaction()
|
||||
{
|
||||
State = MintingState.SendingTransaction;
|
||||
ProgressBarText = "Sending transaction...";
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
|
||||
var sendTransactionResult = await ResultWrapper.Wrap(async () =>
|
||||
{
|
||||
var mintRequest = new MintRequest(AppState.SelectedNetwork, AppState.SelectedProvider,
|
||||
AppState.SelectedContract, AppState.SelectedToken, AppState.SelectedUploadLocation,
|
||||
AppState.UserStorage.DestinationAddress, AppState.UserStorage.TokenAmount);
|
||||
var task1 = AppState.SelectedProvider.Mint(mintRequest);
|
||||
var task2 = Task.Delay(TimeSpan.FromMilliseconds(MinDelayInMilliseconds));
|
||||
await Task.WhenAll(task1, task2);
|
||||
return task1.Result;
|
||||
});
|
||||
if (sendTransactionResult.IsSuccess)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sendTransactionResult.Value))
|
||||
{
|
||||
TransactionHash = sendTransactionResult.Value;
|
||||
State = MintingState.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendTransactionError = "Tx hash is null or empty";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SendTransactionError = sendTransactionResult.Error;
|
||||
}
|
||||
|
||||
ProgressBarText = null;
|
||||
RefreshMediator.NotifyStateHasChangedSafe();
|
||||
}
|
||||
|
||||
private async Task Close()
|
||||
{
|
||||
DialogService.Close(TransactionHash);
|
||||
}
|
||||
}
|
@ -26,34 +26,6 @@
|
||||
{
|
||||
@:<text style="color: red;">NOT CONFIGURED</text>
|
||||
}
|
||||
else if (!NetworkMatches)
|
||||
{
|
||||
@:<text style="color: red;">NETWORK MISMATCH</text>
|
||||
} else
|
||||
{
|
||||
@:<text style="color: green;">OK</text>
|
||||
}
|
||||
</p>
|
||||
<p>
|
||||
@if (string.IsNullOrEmpty(SourceAddress))
|
||||
{
|
||||
@:<text style="font-weight: bold;">Balance: </text>
|
||||
}
|
||||
else
|
||||
{
|
||||
@:<text style="font-weight: bold;">Balance</text>
|
||||
@:<text> (@SourceAddress)</text>
|
||||
@:<text style="font-weight: bold;">: </text>
|
||||
}
|
||||
|
||||
@if (AppState?.SelectedProvider == null || !AppState.SelectedProvider.IsConfigured || string.IsNullOrEmpty(SourceAddress))
|
||||
{
|
||||
@:<text style="color: red;">UNKNOWN</text>
|
||||
}
|
||||
else if (BalanceIsZero)
|
||||
{
|
||||
@:<text style="color: red;">ZERO</text>
|
||||
}
|
||||
else
|
||||
{
|
||||
@:<text style="color: green;">OK</text>
|
||||
|
@ -1,6 +1,5 @@
|
||||
using CSharpFunctionalExtensions;
|
||||
using NftFaucetRadzen.Components;
|
||||
using NftFaucetRadzen.Models;
|
||||
using NftFaucetRadzen.Utils;
|
||||
using Radzen;
|
||||
|
||||
@ -9,8 +8,6 @@ namespace NftFaucetRadzen.Pages;
|
||||
public partial class MintPage : BasicComponent
|
||||
{
|
||||
private string SourceAddress { get; set; }
|
||||
private bool NetworkMatches { get; set; }
|
||||
private bool BalanceIsZero { get; set; } = true;
|
||||
private bool IsReadyToMint => AppState != null &&
|
||||
AppState.SelectedNetwork != null &&
|
||||
AppState.SelectedProvider != null &&
|
||||
@ -18,9 +15,7 @@ public partial class MintPage : BasicComponent
|
||||
AppState.SelectedContract != null &&
|
||||
AppState.SelectedToken != null &&
|
||||
AppState.SelectedUploadLocation != null &&
|
||||
!string.IsNullOrEmpty(SourceAddress) &&
|
||||
NetworkMatches &&
|
||||
!BalanceIsZero;
|
||||
AppState.UserStorage.DestinationAddress != null;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
@ -28,35 +23,13 @@ public partial class MintPage : BasicComponent
|
||||
{
|
||||
SourceAddress = await ResultWrapper.Wrap(() => AppState.SelectedProvider.GetAddress()).Match(x => x, _ => null);
|
||||
AppState.UserStorage.DestinationAddress = SourceAddress;
|
||||
if (string.IsNullOrEmpty(SourceAddress) || AppState.SelectedNetwork == null)
|
||||
{
|
||||
BalanceIsZero = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var balance = await ResultWrapper.Wrap(() => AppState.SelectedProvider.GetBalance(AppState.SelectedNetwork)).Match(x => x, _ => 0);
|
||||
BalanceIsZero = balance == 0;
|
||||
}
|
||||
if (AppState.SelectedNetwork != null)
|
||||
{
|
||||
NetworkMatches = await ResultWrapper.Wrap(() => AppState.SelectedProvider.EnsureNetworkMatches(AppState.SelectedNetwork)).Match(x => x, _ => false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Mint()
|
||||
{
|
||||
var mintRequest = new MintRequest(AppState.SelectedNetwork, AppState.SelectedProvider,
|
||||
AppState.SelectedContract, AppState.SelectedToken, AppState.SelectedUploadLocation,
|
||||
AppState.UserStorage.DestinationAddress, AppState.UserStorage.TokenAmount);
|
||||
var result = await AppState.SelectedProvider.Mint(mintRequest);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
NotificationService.Notify(NotificationSeverity.Success, "Minting finished", result.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
NotificationService.Notify(NotificationSeverity.Error, "Failed to mint", result.Error);
|
||||
}
|
||||
await DialogService.OpenAsync<MintDialog>("Minting...",
|
||||
new Dictionary<string, object>(),
|
||||
new DialogOptions() { Width = "700px", Height = "570px", Resizable = true, Draggable = true });
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
using CSharpFunctionalExtensions;
|
||||
using NftFaucetRadzen.Components.CardList;
|
||||
using NftFaucetRadzen.Models;
|
||||
using NftFaucetRadzen.Plugins.NetworkPlugins;
|
||||
@ -19,9 +18,9 @@ public interface IProvider
|
||||
public CardListItemConfiguration GetConfiguration();
|
||||
public bool IsNetworkSupported(INetwork network);
|
||||
public Task<string> GetAddress();
|
||||
public Task<long?> GetBalance(INetwork network);
|
||||
public Task<bool> EnsureNetworkMatches(INetwork network);
|
||||
public Task<Result<string>> Mint(MintRequest mintRequest);
|
||||
public Task<Balance> GetBalance(INetwork network);
|
||||
public Task<INetwork> GetNetwork(IReadOnlyCollection<INetwork> allKnownNetworks, INetwork selectedNetwork);
|
||||
public Task<string> Mint(MintRequest mintRequest);
|
||||
public Task<string> GetState();
|
||||
public Task SetState(string state);
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public class EthereumKeygenProvider : IProvider
|
||||
public Task<string> GetAddress()
|
||||
=> Task.FromResult(Key?.Address);
|
||||
|
||||
public async Task<long?> GetBalance(INetwork network)
|
||||
public async Task<Balance> GetBalance(INetwork network)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Key?.Address))
|
||||
return null;
|
||||
@ -93,13 +93,24 @@ public class EthereumKeygenProvider : IProvider
|
||||
var web3 = new Web3(network.PublicRpcUrl.OriginalString);
|
||||
var hexBalance = await web3.Eth.GetBalance.SendRequestAsync(Key.Address);
|
||||
var balance = (long) hexBalance.Value;
|
||||
return balance;
|
||||
return new Balance
|
||||
{
|
||||
Amount = balance,
|
||||
Currency = "wei",
|
||||
};
|
||||
}
|
||||
|
||||
public Task<bool> EnsureNetworkMatches(INetwork network)
|
||||
=> Task.FromResult(network.Type == NetworkType.Ethereum);
|
||||
public Task<INetwork> GetNetwork(IReadOnlyCollection<INetwork> allKnownNetworks, INetwork selectedNetwork)
|
||||
{
|
||||
if (selectedNetwork != null && selectedNetwork.Type == NetworkType.Ethereum)
|
||||
return Task.FromResult(selectedNetwork);
|
||||
|
||||
public async Task<Result<string>> Mint(MintRequest mintRequest)
|
||||
var matchingNetwork = allKnownNetworks.FirstOrDefault(x => x.Type == NetworkType.Ethereum && x.IsSupported) ??
|
||||
allKnownNetworks.FirstOrDefault(x => x.Type == NetworkType.Ethereum);
|
||||
return Task.FromResult(matchingNetwork);
|
||||
}
|
||||
|
||||
public async Task<string> Mint(MintRequest mintRequest)
|
||||
{
|
||||
if (mintRequest.Network.Type != NetworkType.Ethereum)
|
||||
{
|
||||
@ -123,34 +134,31 @@ public class EthereumKeygenProvider : IProvider
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return await ResultWrapper.Wrap(async () =>
|
||||
var data = transfer.Encode();
|
||||
var client = new RpcClient(mintRequest.Network.PublicRpcUrl);
|
||||
var account = new Account(Key.PrivateKey);
|
||||
var transactionManager = new AccountSignerTransactionManager(client, account);
|
||||
var txInput = new TransactionInput
|
||||
{
|
||||
var data = transfer.Encode();
|
||||
var client = new RpcClient(mintRequest.Network.PublicRpcUrl);
|
||||
var account = new Account(Key.PrivateKey);
|
||||
var transactionManager = new AccountSignerTransactionManager(client, account);
|
||||
var txInput = new TransactionInput
|
||||
{
|
||||
From = Key.Address,
|
||||
To = mintRequest.Contract.Address,
|
||||
Data = data,
|
||||
ChainId = new HexBigInteger(new BigInteger(mintRequest.Network.ChainId!.Value)),
|
||||
Type = new HexBigInteger(TransactionType.EIP1559.AsByte()),
|
||||
};
|
||||
txInput.Nonce = await transactionManager.GetNonceAsync(txInput);
|
||||
var fee1559 = await transactionManager.CalculateFee1559Async();
|
||||
txInput.MaxFeePerGas = new HexBigInteger(fee1559.MaxFeePerGas!.Value);
|
||||
txInput.MaxPriorityFeePerGas = new HexBigInteger(fee1559.MaxPriorityFeePerGas!.Value);
|
||||
txInput.Gas = await transactionManager.EstimateGasAsync(txInput);
|
||||
txInput.Gas = new HexBigInteger(new BigInteger((long)txInput.Gas.Value * 1.3));
|
||||
var transactionHash = await transactionManager.SendTransactionAsync(txInput);
|
||||
if (string.IsNullOrEmpty(transactionHash))
|
||||
{
|
||||
throw new Exception("Operation was cancelled or RPC node failure");
|
||||
}
|
||||
From = Key.Address,
|
||||
To = mintRequest.Contract.Address,
|
||||
Data = data,
|
||||
ChainId = new HexBigInteger(new BigInteger(mintRequest.Network.ChainId!.Value)),
|
||||
Type = new HexBigInteger(TransactionType.EIP1559.AsByte()),
|
||||
};
|
||||
txInput.Nonce = await transactionManager.GetNonceAsync(txInput);
|
||||
var fee1559 = await transactionManager.CalculateFee1559Async();
|
||||
txInput.MaxFeePerGas = new HexBigInteger(fee1559.MaxFeePerGas!.Value);
|
||||
txInput.MaxPriorityFeePerGas = new HexBigInteger(fee1559.MaxPriorityFeePerGas!.Value);
|
||||
txInput.Gas = await transactionManager.EstimateGasAsync(txInput);
|
||||
txInput.Gas = new HexBigInteger(new BigInteger((long)txInput.Gas.Value * 1.3));
|
||||
var transactionHash = await transactionManager.SendTransactionAsync(txInput);
|
||||
if (string.IsNullOrEmpty(transactionHash))
|
||||
{
|
||||
throw new Exception("Operation was cancelled or RPC node failure");
|
||||
}
|
||||
|
||||
return transactionHash;
|
||||
});
|
||||
return transactionHash;
|
||||
}
|
||||
|
||||
public Task<string> GetState()
|
||||
|
@ -101,7 +101,7 @@ public class SolanaKeygenProvider : IProvider
|
||||
public Task<string> GetAddress()
|
||||
=> Task.FromResult(Key?.Address);
|
||||
|
||||
public async Task<long?> GetBalance(INetwork network)
|
||||
public async Task<Balance> GetBalance(INetwork network)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Key?.Address))
|
||||
return null;
|
||||
@ -112,13 +112,24 @@ public class SolanaKeygenProvider : IProvider
|
||||
return null;
|
||||
|
||||
var balance = (long) balanceResult.Result.Value;
|
||||
return balance;
|
||||
return new Balance
|
||||
{
|
||||
Amount = balance,
|
||||
Currency = "lamport",
|
||||
};
|
||||
}
|
||||
|
||||
public Task<bool> EnsureNetworkMatches(INetwork network)
|
||||
=> Task.FromResult(network.Type == NetworkType.Solana);
|
||||
public Task<INetwork> GetNetwork(IReadOnlyCollection<INetwork> allKnownNetworks, INetwork selectedNetwork)
|
||||
{
|
||||
if (selectedNetwork != null && selectedNetwork.Type == NetworkType.Solana)
|
||||
return Task.FromResult(selectedNetwork);
|
||||
|
||||
public async Task<Result<string>> Mint(MintRequest mintRequest)
|
||||
var matchingNetwork = allKnownNetworks.FirstOrDefault(x => x.Type == NetworkType.Solana && x.IsSupported) ??
|
||||
allKnownNetworks.FirstOrDefault(x => x.Type == NetworkType.Solana);
|
||||
return Task.FromResult(matchingNetwork);
|
||||
}
|
||||
|
||||
public async Task<string> Mint(MintRequest mintRequest)
|
||||
{
|
||||
var client = ClientFactory.GetClient(mintRequest.Network.PublicRpcUrl.OriginalString);
|
||||
var rentExemption = await client.GetMinimumBalanceForRentExemptionAsync(TokenProgram.MintAccountDataSize);
|
||||
|
@ -133,83 +133,58 @@ public class MetamaskProvider : IProvider
|
||||
public async Task<string> GetAddress()
|
||||
=> Address ?? await MetaMaskService.GetSelectedAccountAsync();
|
||||
|
||||
public async Task<long?> GetBalance(INetwork network)
|
||||
public async Task<Balance> GetBalance(INetwork network)
|
||||
{
|
||||
if (!IsConfigured)
|
||||
return null;
|
||||
|
||||
var balance = (long) await MetaMaskService.GetBalanceAsync();
|
||||
return balance;
|
||||
}
|
||||
|
||||
public async Task<bool> EnsureNetworkMatches(INetwork network)
|
||||
=> network.Type == NetworkType.Ethereum && network.ChainId != null && network.ChainId == await GetChainId();
|
||||
|
||||
private async Task<ulong?> GetChainId()
|
||||
{
|
||||
var chainHex = await MetaMaskService.GetSelectedChainAsync();
|
||||
if (string.IsNullOrEmpty(chainHex) || chainHex == "0x")
|
||||
return new Balance
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var chainId = (ulong) Convert.ToInt64(chainHex, 16);
|
||||
return chainId;
|
||||
Amount = balance,
|
||||
Currency = "wei",
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Result<string>> Mint(MintRequest mintRequest)
|
||||
public Task<INetwork> GetNetwork(IReadOnlyCollection<INetwork> allKnownNetworks, INetwork selectedNetwork)
|
||||
{
|
||||
var chainId = Convert.ToUInt64(ChainId, 16);
|
||||
var matchingNetwork = allKnownNetworks.FirstOrDefault(x => x.ChainId != null && x.ChainId.Value == chainId);
|
||||
return Task.FromResult(matchingNetwork);
|
||||
}
|
||||
|
||||
public async Task<string> Mint(MintRequest mintRequest)
|
||||
{
|
||||
if (mintRequest.Network.Type != NetworkType.Ethereum)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid network type for this provider");
|
||||
}
|
||||
|
||||
switch (mintRequest.Contract.Type)
|
||||
Function transfer = mintRequest.Contract.Type switch
|
||||
{
|
||||
case ContractType.Erc721:
|
||||
ContractType.Erc721 => new Erc721MintFunction
|
||||
{
|
||||
return await ResultWrapper.Wrap(async () =>
|
||||
{
|
||||
var contractAddress = mintRequest.Contract.Address;
|
||||
var transfer = new Erc721MintFunction
|
||||
{
|
||||
To = mintRequest.DestinationAddress,
|
||||
Uri = mintRequest.UploadLocation.Location,
|
||||
};
|
||||
var data = transfer.Encode();
|
||||
var transactionHash = await MetaMaskService.SendTransactionAsync(contractAddress, 0, data);
|
||||
if (string.IsNullOrEmpty(transactionHash))
|
||||
{
|
||||
throw new Exception("Operation was cancelled or RPC node failure");
|
||||
}
|
||||
|
||||
return transactionHash;
|
||||
});
|
||||
}
|
||||
case ContractType.Erc1155:
|
||||
To = mintRequest.DestinationAddress,
|
||||
Uri = mintRequest.UploadLocation.Location,
|
||||
},
|
||||
ContractType.Erc1155 => new Erc1155MintFunction
|
||||
{
|
||||
return await ResultWrapper.Wrap(async () =>
|
||||
{
|
||||
var contractAddress = mintRequest.Contract.Address;
|
||||
var transfer = new Erc1155MintFunction
|
||||
{
|
||||
To = mintRequest.DestinationAddress,
|
||||
Amount = mintRequest.TokensAmount,
|
||||
Uri = mintRequest.UploadLocation.Location,
|
||||
};
|
||||
var data = transfer.Encode();
|
||||
var transactionHash = await MetaMaskService.SendTransactionAsync(contractAddress, 0, data);
|
||||
if (string.IsNullOrEmpty(transactionHash))
|
||||
{
|
||||
throw new Exception("Operation was cancelled or RPC node failure");
|
||||
}
|
||||
To = mintRequest.DestinationAddress,
|
||||
Amount = mintRequest.TokensAmount,
|
||||
Uri = mintRequest.UploadLocation.Location,
|
||||
},
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
return transactionHash;
|
||||
});
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
var contractAddress = mintRequest.Contract.Address;
|
||||
var data = transfer.Encode();
|
||||
var transactionHash = await MetaMaskService.SendTransactionAsync(contractAddress, 0, data);
|
||||
if (string.IsNullOrEmpty(transactionHash))
|
||||
{
|
||||
throw new Exception("Operation was cancelled or RPC node failure");
|
||||
}
|
||||
|
||||
return transactionHash;
|
||||
}
|
||||
|
||||
public Task<string> GetState()
|
||||
|
@ -49,7 +49,12 @@ public class PhantomProvider : IProvider
|
||||
public Task<string> GetAddress()
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<long?> GetBalance(INetwork network)
|
||||
public Task<Balance> GetBalance(INetwork network)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<INetwork> GetNetwork(IReadOnlyCollection<INetwork> allKnownNetworks, INetwork selectedNetwork)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@ -59,7 +64,7 @@ public class PhantomProvider : IProvider
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<Result<string>> Mint(MintRequest mintRequest)
|
||||
public Task<string> Mint(MintRequest mintRequest)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user