Move logic to pipeline

This commit is contained in:
Yurii Didyk 2022-06-03 14:04:44 +03:00
parent e804361398
commit f37c30bfa1
3 changed files with 75 additions and 74 deletions

View File

@ -1,6 +0,0 @@
namespace NftFaucet.Services
{
public class SolanaTransactionBuilder
{
}
}

View File

@ -0,0 +1,67 @@
using Solana.Metaplex;
using Solnet.Programs;
using Solnet.Rpc.Builders;
using Solnet.Rpc.Models;
using Solnet.Wallet;
namespace NftFaucet.Services;
public class SolanaTransactionInstructionsPipeline
{
private readonly List<TransactionInstruction> _instructions = new List<TransactionInstruction>();
public void InitializeForMint(PublicKey from, PublicKey dest, PublicKey mint, ulong balanceForMint, ulong tokenAmount, ulong tokenPrice)
{
Add(SystemProgram.CreateAccount(from, mint, balanceForMint, TokenProgram.MintAccountDataSize, TokenProgram.ProgramIdKey));
Add(TokenProgram.InitializeMint(mint, 0, from, from));
Add(AssociatedTokenAccountProgram.CreateAssociatedTokenAccount(from, dest, mint));
var tokenBalanceAddress = AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(dest, mint);
Add(TokenProgram.MintTo(mint, tokenBalanceAddress, tokenAmount, from));
Add(SystemProgram.Transfer(from, from, tokenPrice));
}
public void AddMetadata(PublicKey from, PublicKey mint, PublicKey metadataAddress, MetadataParameters data)
{
Add(MetadataProgram.CreateMetadataAccount(
metadataAddress,
mint,
from,
from,
from,
data,
true,
true
));
}
public void AddMasterEdition(PublicKey from, PublicKey mint, PublicKey masterEditionAddress, PublicKey metadataAddress, MetadataParameters data)
{
Add(MetadataProgram.CreateMasterEdition(
1,
masterEditionAddress,
mint,
from,
from,
from,
metadataAddress
));
}
public void AddRange(TransactionInstruction[] instructions)
{
_instructions.AddRange(instructions);
}
public void Add(TransactionInstruction instruction)
{
_instructions.Add(instruction);
}
public void Build(TransactionBuilder builder)
{
_instructions.ForEach(x => builder.AddInstruction(x));
}
}

View File

@ -6,6 +6,7 @@ using Solnet.Rpc;
using Solnet.Rpc.Builders;
using Solnet.Rpc.Core.Http;
using Solnet.Rpc.Models;
using Solnet.Rpc.Types;
using Solnet.Rpc.Utilities;
using Solnet.Wallet;
using Solnet.Wallet.Bip39;
@ -30,7 +31,7 @@ public class SolanaTransactionService : ISolanaTransactionService
ulong tokenPrice = 20000000; // 1 SOL
var airdropSig = await client.RequestAirdropAsync(wallet.Account.PublicKey, 50000000);
await client.GetTransactionAsync(airdropSig.Result);
await client.GetConfirmedTransactionAsync(airdropSig.Result, Commitment.Finalized);
var walletAddress = wallet.Account.PublicKey;
var balanceRes = await client.GetBalanceAsync(walletAddress);
@ -55,71 +56,13 @@ public class SolanaTransactionService : ISolanaTransactionService
sellerFeeBasisPoints = 88,
};
var instructions = new List<TransactionInstruction>();
// Step #1 - System Program: Create Account
instructions.Add(SystemProgram.CreateAccount(
walletAddress,
mintAddress,
rentExemption.Result,
TokenProgram.MintAccountDataSize,
TokenProgram.ProgramIdKey
));
// Step #2 - Token Program: Initialize Mint
instructions.Add(TokenProgram.InitializeMint(
mintAddress,
0,
walletAddress,
walletAddress
));
var destinationPublicKey = new PublicKey(destinationAddress);
// Step #3 - Associated Token Program: Create
instructions.Add(AssociatedTokenAccountProgram.CreateAssociatedTokenAccount(
walletAddress,
destinationPublicKey,
mintAddress
));
// Step #4 - Token Program: Mint To
// Wallet address = dest
var tokenBalanceAddress = AssociatedTokenAccountProgram.DeriveAssociatedTokenAccount(destinationPublicKey, mintAddress);
instructions.Add(TokenProgram.MintTo(
mintAddress,
tokenBalanceAddress,
(ulong)amount,
walletAddress
));
var pipeline = new SolanaTransactionInstructionsPipeline();
// Step #5.1 - System Program: Transfer
instructions.Add(SystemProgram.Transfer(
walletAddress,
walletAddress,
tokenPrice
));
// Step #5.2 (also 5.3, 5.4, 5.5) - Token Metadata Program: Create Metadata Accounts
instructions.Add(MetadataProgram.CreateMetadataAccount(
metadataAddress,
mintAddress,
walletAddress,
walletAddress,
walletAddress,
data,
true,
true
));
// Step #5.6 (also 5.7, 5.8, 5.9, 5.10, 5.11) - Token Metadata Program: Create Master Edition
instructions.Add(MetadataProgram.CreateMasterEdition(
1,
masterEditionAddress,
mintAddress,
walletAddress,
walletAddress,
walletAddress,
metadataAddress
));
pipeline.InitializeForMint(walletAddress, destinationPublicKey, mintAddress, rentExemption.Result, (ulong)amount, tokenPrice);
pipeline.AddMetadata(walletAddress, mintAddress, metadataAddress, data);
pipeline.AddMasterEdition(walletAddress, mintAddress, masterEditionAddress, metadataAddress, data);
var blockHash = (await client.GetRecentBlockHashAsync()).Result.Value.Blockhash;
@ -127,14 +70,11 @@ public class SolanaTransactionService : ISolanaTransactionService
.SetFeePayer(wallet.Account.PublicKey)
.SetRecentBlockHash(blockHash);
foreach (var instruction in instructions)
{
txBuilder.AddInstruction(instruction);
}
pipeline.Build(txBuilder);
var tx = txBuilder.Build(new List<Account> { wallet.Account, mint });
var simulationResult = await client.SimulateTransactionAsync(tx);
var isSimulationSuccessful = simulationResult.WasSuccessful;
var isSimulationSuccessful = simulationResult.ErrorData == null;
if (!isSimulationSuccessful)
{