favorites.ts 3.3 KB

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