From f37c30bfa1b1197b73a95f103b1060eafb9d549a Mon Sep 17 00:00:00 2001 From: Yurii Didyk Date: Fri, 3 Jun 2022 14:04:44 +0300 Subject: [PATCH] Move logic to pipeline --- .../Services/SolanaTransactionBuilder.cs | 6 -- .../SolanaTransactionInstructionsPipeline.cs | 67 ++++++++++++++++ .../Services/SolanaTransactionService.cs | 76 ++----------------- 3 files changed, 75 insertions(+), 74 deletions(-) delete mode 100644 NftFaucet/Services/SolanaTransactionBuilder.cs create mode 100644 NftFaucet/Services/SolanaTransactionInstructionsPipeline.cs diff --git a/NftFaucet/Services/SolanaTransactionBuilder.cs b/NftFaucet/Services/SolanaTransactionBuilder.cs deleted file mode 100644 index f5e4347..0000000 --- a/NftFaucet/Services/SolanaTransactionBuilder.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace NftFaucet.Services -{ - public class SolanaTransactionBuilder - { - } -} diff --git a/NftFaucet/Services/SolanaTransactionInstructionsPipeline.cs b/NftFaucet/Services/SolanaTransactionInstructionsPipeline.cs new file mode 100644 index 0000000..2f54d49 --- /dev/null +++ b/NftFaucet/Services/SolanaTransactionInstructionsPipeline.cs @@ -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 _instructions = new List(); + + 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)); + } +} + diff --git a/NftFaucet/Services/SolanaTransactionService.cs b/NftFaucet/Services/SolanaTransactionService.cs index f1e6d6e..a31d000 100644 --- a/NftFaucet/Services/SolanaTransactionService.cs +++ b/NftFaucet/Services/SolanaTransactionService.cs @@ -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(); - - // 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 { wallet.Account, mint }); var simulationResult = await client.SimulateTransactionAsync(tx); - var isSimulationSuccessful = simulationResult.WasSuccessful; + var isSimulationSuccessful = simulationResult.ErrorData == null; if (!isSimulationSuccessful) {