litesvm.test.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import * as anchor from '@coral-xyz/anchor';
  2. import { getCustomErrorMessage } from '@solana-developers/helpers';
  3. import { Keypair } from '@solana/web3.js';
  4. import { LiteSVMProvider, fromWorkspace } from 'anchor-litesvm';
  5. import { assert } from 'chai';
  6. import { Favorites } from '../target/types/favorites';
  7. import { systemProgramErrors } from './system-errors';
  8. const web3 = anchor.web3;
  9. const IDL = require('../target/idl/favorites.json');
  10. describe('anchor', () => {
  11. let client: any;
  12. let provider: LiteSVMProvider;
  13. let program: anchor.Program<Favorites>;
  14. let user: Keypair;
  15. let someRandomGuy: Keypair;
  16. let favoriteNumber: anchor.BN;
  17. let favoriteColor: string;
  18. let favoriteHobbies: string[];
  19. before(async () => {
  20. client = fromWorkspace('');
  21. provider = new LiteSVMProvider(client);
  22. program = new anchor.Program<Favorites>(IDL, provider);
  23. anchor.setProvider(provider);
  24. user = (provider.wallet as anchor.Wallet).payer;
  25. someRandomGuy = anchor.web3.Keypair.generate();
  26. // Here's what we want to write to the blockchain
  27. favoriteNumber = new anchor.BN(23);
  28. favoriteColor = 'purple';
  29. favoriteHobbies = ['skiing', 'skydiving', 'biking'];
  30. // We don't need to airdrop if we're using the local cluster
  31. // because the local cluster gives us 1,000,000 SOL
  32. const balance = await provider.client.getBalance(user.publicKey);
  33. const balanceInSOL = balance / BigInt(web3.LAMPORTS_PER_SOL);
  34. const formattedBalance = new Intl.NumberFormat().format(balanceInSOL);
  35. console.log(`Balance: ${formattedBalance} SOL`);
  36. });
  37. it('Writes our favorites to the blockchain', async () => {
  38. await program.methods
  39. // set_favourites in Rust becomes setFavorites in TypeScript
  40. .setFavorites(favoriteNumber, favoriteColor, favoriteHobbies)
  41. // Sign the transaction
  42. .signers([user])
  43. // Send the transaction to the cluster or RPC
  44. .rpc();
  45. // Find the PDA for the user's favorites
  46. const favoritesPdaAndBump = web3.PublicKey.findProgramAddressSync([Buffer.from('favorites'), user.publicKey.toBuffer()], program.programId);
  47. const favoritesPda = favoritesPdaAndBump[0];
  48. const dataFromPda = await program.account.favorites.fetch(favoritesPda);
  49. // And make sure it matches!
  50. assert.equal(dataFromPda.color, favoriteColor);
  51. // A little extra work to make sure the BNs are equal
  52. assert.equal(dataFromPda.number.toString(), favoriteNumber.toString());
  53. // And check the hobbies too
  54. assert.deepEqual(dataFromPda.hobbies, favoriteHobbies);
  55. });
  56. it('Updates the favorites', async () => {
  57. const newFavoriteHobbies = ['skiing', 'skydiving', 'biking', 'swimming'];
  58. try {
  59. await program.methods.setFavorites(favoriteNumber, favoriteColor, newFavoriteHobbies).signers([user]).rpc();
  60. } catch (error) {
  61. console.error((error as Error).message);
  62. const customErrorMessage = getCustomErrorMessage(systemProgramErrors, error);
  63. throw new Error(customErrorMessage);
  64. }
  65. });
  66. it('Rejects transactions from unauthorized signers', async () => {
  67. try {
  68. await program.methods
  69. // set_favourites in Rust becomes setFavorites in TypeScript
  70. .setFavorites(favoriteNumber, favoriteColor, favoriteHobbies)
  71. // Sign the transaction
  72. .signers([someRandomGuy])
  73. // Send the transaction to the cluster or RPC
  74. .rpc();
  75. } catch (error) {
  76. const errorMessage = (error as Error).message;
  77. assert.isTrue(errorMessage.includes('unknown signer'));
  78. }
  79. });
  80. });