_setup.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import {
  2. Address,
  3. Commitment,
  4. CompilableTransactionMessage,
  5. Rpc,
  6. RpcSubscriptions,
  7. SolanaRpcApi,
  8. SolanaRpcSubscriptionsApi,
  9. TransactionMessageWithBlockhashLifetime,
  10. TransactionSigner,
  11. airdropFactory,
  12. appendTransactionMessageInstruction,
  13. createSolanaRpc,
  14. createSolanaRpcSubscriptions,
  15. createTransactionMessage,
  16. generateKeyPairSigner,
  17. getSignatureFromTransaction,
  18. lamports,
  19. pipe,
  20. sendAndConfirmTransactionFactory,
  21. setTransactionMessageFeePayerSigner,
  22. setTransactionMessageLifetimeUsingBlockhash,
  23. signTransactionMessageWithSigners,
  24. } from '@solana/web3.js';
  25. import {
  26. SYSTEM_PROGRAM_ADDRESS,
  27. getCreateAccountInstruction,
  28. getInitializeNonceAccountInstruction,
  29. getNonceSize,
  30. } from '../src/index.js';
  31. type Client = {
  32. rpc: Rpc<SolanaRpcApi>;
  33. rpcSubscriptions: RpcSubscriptions<SolanaRpcSubscriptionsApi>;
  34. };
  35. export const createDefaultSolanaClient = (): Client => {
  36. const rpc = createSolanaRpc('http://127.0.0.1:8899');
  37. const rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');
  38. return { rpc, rpcSubscriptions };
  39. };
  40. export const generateKeyPairSignerWithSol = async (
  41. client: Client,
  42. putativeLamports: bigint = 1_000_000_000n
  43. ) => {
  44. const signer = await generateKeyPairSigner();
  45. await airdropFactory(client)({
  46. recipientAddress: signer.address,
  47. lamports: lamports(putativeLamports),
  48. commitment: 'confirmed',
  49. });
  50. return signer;
  51. };
  52. export const createDefaultTransaction = async (
  53. client: Client,
  54. feePayer: TransactionSigner
  55. ) => {
  56. const { value: latestBlockhash } = await client.rpc
  57. .getLatestBlockhash()
  58. .send();
  59. return pipe(
  60. createTransactionMessage({ version: 0 }),
  61. (tx) => setTransactionMessageFeePayerSigner(feePayer, tx),
  62. (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx)
  63. );
  64. };
  65. export const signAndSendTransaction = async (
  66. client: Client,
  67. transactionMessage: CompilableTransactionMessage &
  68. TransactionMessageWithBlockhashLifetime,
  69. commitment: Commitment = 'confirmed'
  70. ) => {
  71. const signedTransaction =
  72. await signTransactionMessageWithSigners(transactionMessage);
  73. const signature = getSignatureFromTransaction(signedTransaction);
  74. await sendAndConfirmTransactionFactory(client)(signedTransaction, {
  75. commitment,
  76. });
  77. return signature;
  78. };
  79. export const getBalance = async (client: Client, address: Address) =>
  80. (await client.rpc.getBalance(address, { commitment: 'confirmed' }).send())
  81. .value;
  82. export const createNonceAccount = async (
  83. client: Client,
  84. payer: TransactionSigner,
  85. nonce: TransactionSigner,
  86. nonceAuthority: TransactionSigner
  87. ) => {
  88. const space = BigInt(getNonceSize());
  89. const rent = await client.rpc.getMinimumBalanceForRentExemption(space).send();
  90. const createAccount = getCreateAccountInstruction({
  91. payer,
  92. newAccount: nonce,
  93. lamports: rent,
  94. space,
  95. programAddress: SYSTEM_PROGRAM_ADDRESS,
  96. });
  97. const initializeNonceAccount = getInitializeNonceAccountInstruction({
  98. nonceAccount: nonce.address,
  99. nonceAuthority: nonceAuthority.address,
  100. });
  101. await pipe(
  102. await createDefaultTransaction(client, payer),
  103. (tx) => appendTransactionMessageInstruction(createAccount, tx),
  104. (tx) => appendTransactionMessageInstruction(initializeNonceAccount, tx),
  105. (tx) => signAndSendTransaction(client, tx)
  106. );
  107. };