_setup.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import {
  2. Address,
  3. Commitment,
  4. CompilableTransactionMessage,
  5. Rpc,
  6. RpcSubscriptions,
  7. SolanaRpcApi,
  8. SolanaRpcSubscriptionsApi,
  9. TransactionMessageWithBlockhashLifetime,
  10. TransactionSigner,
  11. airdropFactory,
  12. appendTransactionMessageInstructions,
  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. TOKEN_PROGRAM_ADDRESS,
  27. getInitializeMintInstruction,
  28. getMintSize,
  29. } from '../src/index.js';
  30. import { getCreateAccountInstruction } from '@solana-program/system';
  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 createMint = async (
  83. client: Client,
  84. authority: TransactionSigner
  85. ): Promise<Address> => {
  86. const space = BigInt(getMintSize());
  87. const [transactionMessage, rent, mint] = await Promise.all([
  88. createDefaultTransaction(client, authority),
  89. client.rpc.getMinimumBalanceForRentExemption(space).send(),
  90. generateKeyPairSigner(),
  91. ]);
  92. const instructions = [
  93. getCreateAccountInstruction({
  94. payer: authority,
  95. newAccount: mint,
  96. lamports: rent,
  97. space,
  98. programAddress: TOKEN_PROGRAM_ADDRESS,
  99. }),
  100. getInitializeMintInstruction({
  101. mint: mint.address,
  102. decimals: 2,
  103. mintAuthority: authority.address,
  104. }),
  105. ];
  106. await pipe(
  107. transactionMessage,
  108. (tx) => appendTransactionMessageInstructions(instructions, tx),
  109. (tx) => signAndSendTransaction(client, tx)
  110. );
  111. return mint.address;
  112. };