utils.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import {
  2. MINT_SIZE,
  3. TOKEN_PROGRAM_ID,
  4. createAssociatedTokenAccountInstruction,
  5. createInitializeMint2Instruction,
  6. createMintToInstruction,
  7. getAssociatedTokenAddressSync,
  8. } from '@solana/spl-token';
  9. import { Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction } from '@solana/web3.js';
  10. import * as borsh from 'borsh';
  11. import { ProgramTestContext } from 'solana-bankrun';
  12. export const instructionDiscriminators = {
  13. MakeOffer: Buffer.from([0]),
  14. TakeOffer: Buffer.from([1]),
  15. };
  16. export const getMakeOfferInstructionData = (id: bigint, token_a_offered_amount: bigint, token_b_wanted_amount: bigint) => {
  17. return Buffer.concat([
  18. instructionDiscriminators.MakeOffer,
  19. encodeBigint(id),
  20. encodeBigint(token_a_offered_amount),
  21. encodeBigint(token_b_wanted_amount),
  22. ]);
  23. };
  24. export const getTakeOfferInstructionData = () => {
  25. return Buffer.concat([instructionDiscriminators.TakeOffer]);
  26. };
  27. export const createAMint = async (context: ProgramTestContext, payer: Keypair, mint: Keypair) => {
  28. const tx = new Transaction();
  29. tx.add(
  30. SystemProgram.createAccount({
  31. fromPubkey: payer.publicKey,
  32. newAccountPubkey: mint.publicKey,
  33. // the `space` required for a token mint is accessible in the `@solana/spl-token` sdk
  34. space: MINT_SIZE,
  35. // store enough lamports needed for our `space` to be rent exempt
  36. lamports: Number((await context.banksClient.getRent()).minimumBalance(BigInt(MINT_SIZE))),
  37. // tokens are owned by the "token program"
  38. programId: TOKEN_PROGRAM_ID,
  39. }),
  40. createInitializeMint2Instruction(mint.publicKey, 9, payer.publicKey, payer.publicKey),
  41. );
  42. tx.recentBlockhash = context.lastBlockhash;
  43. tx.sign(payer, mint);
  44. // process the transaction
  45. await context.banksClient.processTransaction(tx);
  46. };
  47. export const mintTo = async (context: ProgramTestContext, payer: Keypair, owner: PublicKey, mint: PublicKey) => {
  48. const tokenAccount = getAssociatedTokenAddressSync(mint, owner, false);
  49. const tx = new Transaction();
  50. tx.add(
  51. createAssociatedTokenAccountInstruction(payer.publicKey, tokenAccount, owner, mint),
  52. createMintToInstruction(mint, tokenAccount, payer.publicKey, 1_000 * LAMPORTS_PER_SOL),
  53. );
  54. tx.recentBlockhash = context.lastBlockhash;
  55. tx.sign(payer);
  56. // process the transaction
  57. await context.banksClient.processTransaction(tx);
  58. return tokenAccount;
  59. };
  60. export const encodeBigint = (value: bigint) => {
  61. const buffer = Buffer.alloc(8);
  62. buffer.writeBigUInt64LE(value);
  63. return Uint8Array.from(buffer);
  64. };
  65. export type OfferAccount = {
  66. id: number;
  67. maker: PublicKey;
  68. token_mint_a: PublicKey;
  69. token_mint_b: PublicKey;
  70. token_b_wanted_amount: number;
  71. bump: number;
  72. };
  73. // Define DataAccountRaw type for deserialization
  74. export type OfferAccountRaw = {
  75. id: number;
  76. maker: Uint8Array;
  77. token_mint_a: Uint8Array;
  78. token_mint_b: Uint8Array;
  79. token_b_wanted_amount: number;
  80. bump: number;
  81. };
  82. // Define the schema for the account data
  83. export const offerAccountSchema: borsh.Schema = {
  84. struct: {
  85. discriminator: 'u64',
  86. id: 'u64',
  87. maker: { array: { type: 'u8', len: 32 } },
  88. token_mint_a: { array: { type: 'u8', len: 32 } },
  89. token_mint_b: { array: { type: 'u8', len: 32 } },
  90. token_b_wanted_amount: 'u64',
  91. bump: 'u8',
  92. },
  93. };
  94. export const deserializeOfferAccount = (data: Uint8Array): OfferAccount => {
  95. const account = borsh.deserialize(offerAccountSchema, data) as OfferAccountRaw;
  96. return {
  97. id: account.id,
  98. maker: new PublicKey(account.maker),
  99. token_mint_a: new PublicKey(account.token_mint_a),
  100. token_mint_b: new PublicKey(account.token_mint_b),
  101. token_b_wanted_amount: account.token_b_wanted_amount,
  102. bump: account.bump,
  103. };
  104. };