Skip to content

Instantly share code, notes, and snippets.

@hoakbuilds
Created August 23, 2021 14:30
Show Gist options
  • Save hoakbuilds/319bd6e941f418d188f8f66fbbe10012 to your computer and use it in GitHub Desktop.
Save hoakbuilds/319bd6e941f418d188f8f66fbbe10012 to your computer and use it in GitHub Desktop.
using Solnet.KeyStore;
using Solnet.Programs;
using Solnet.Rpc;
using Solnet.Rpc.Builders;
using Solnet.Rpc.Core.Http;
using Solnet.Rpc.Messages;
using Solnet.Rpc.Models;
using Solnet.Wallet;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Solnet.Examples
{
public class ReplicationAttempts : IExample
{
private static readonly IRpcClient RpcClient = ClientFactory.GetClient(Cluster.DevNet);
private readonly Wallet.Wallet _wallet;
private static readonly PublicKey ProgramIdKey = new("HmaajdGsXrRPdCqkA5Cv4Nm5eKrUrUK5MFwu14WuD3Gq");
private static readonly PublicKey PlayerAccountKey = new("5Z9oJEs2hUBd5vNTDWZq4A7NANAkPeBRRjQw7eEvbPwB");
private static readonly PublicKey ServerAccountKey = new("FbSwjbBBKPzUiPzK9SewRnVTAK1USEXf9xvv248c2zAm");
private const long GameAccountSpace = 307;
public ReplicationAttempts()
{
// init stuff
SolanaKeyStoreService keyStore = new ();
// get the wallet
_wallet = keyStore.RestoreKeystoreFromFile("/path/to/wallet/");
}
public async void Run()
{
var hash = await RequestAirdropAsync(_wallet.Account.PublicKey);
Console.WriteLine($"Airdrop transaction signature: {hash}");
var balanceForRentExemption = await GetBalanceForRentExemptionAsync(GameAccountSpace);
var blockhash = await GetRecentBlockHashAsync();
var gameAccount = new Account();
var tx = new TransactionBuilder()
.SetFeePayer(_wallet.Account)
.SetRecentBlockHash(blockhash.Value.Blockhash)
.AddInstruction(SystemProgram.CreateAccount(
_wallet.Account,
gameAccount,
balanceForRentExemption,
GameAccountSpace, ProgramIdKey))
.AddInstruction(DoritoAccountDataInstruction(gameAccount))
.Build( new List<Account>{ _wallet.Account, gameAccount });
SimulateTxSendAndLog(tx);
Console.ReadKey();
}
private TransactionInstruction DoritoAccountDataInstruction(PublicKey gameAccount)
{
List<AccountMeta> keys = new()
{
AccountMeta.Writable(gameAccount, false),
AccountMeta.ReadOnly(PlayerAccountKey, false),
AccountMeta.ReadOnly(ServerAccountKey, false)
};
return new TransactionInstruction
{
ProgramId = ProgramIdKey,
Data = new byte[]{0, 0, 0, 0, 0, 0, 0, 0},
Keys = keys
};
}
/// <summary>
/// Submits a transaction and logs the output from SimulateTransaction.
/// </summary>
/// <param name="tx">The transaction data ready to simulate or submit to the network.</param>
public static string SimulateTxSendAndLog(byte[] tx)
{
Console.WriteLine($"Tx Data: {Convert.ToBase64String(tx)}");
RequestResult<ResponseValue<SimulationLogs>> txSim = RpcClient.SimulateTransaction(tx);
string logs = Examples.PrettyPrintTransactionSimulationLogs(txSim.Result.Value.Logs);
Console.WriteLine($"Transaction Simulation:\n\tError: {txSim.Result.Value.Error}\n\tLogs: \n" + logs);
RequestResult<string> txReq = RpcClient.SendTransaction(tx);
Console.WriteLine($"Tx Signature: {txReq.Result}");
return txReq.Result;
}
private async Task<ulong> GetBalanceForRentExemptionAsync(long space)
=> (await RpcClient.GetMinimumBalanceForRentExemptionAsync(space)).Result;
private async Task<ResponseValue<BlockHash>> GetRecentBlockHashAsync()
=> (await RpcClient.GetRecentBlockHashAsync()).Result;
private async Task<string> RequestAirdropAsync(string address)
=> (await RpcClient.RequestAirdropAsync(address, 1_000_000_000)).Result;
private async Task<List<AccountKeyPair>> GetProgramAccountsAsync(string programAddress)
=> (await RpcClient.GetProgramAccountsAsync(programAddress)).Result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment