withdrawTwo.ts 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import * as anchor from "@project-serum/anchor";
  2. import { decode, mapProof } from "../utils";
  3. import { PROGRAM_ID as BUBBLEGUM_PROGRAM_ID } from "@metaplex-foundation/mpl-bubblegum";
  4. import { SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, SPL_NOOP_PROGRAM_ID } from "@solana/spl-account-compression";
  5. import { getAsset, getAssetProof } from "../readAPI";
  6. import { AccountMeta } from "@solana/web3.js";
  7. import { program, programID } from "./constants";
  8. async function main() {
  9. // TODO change all of these to your values
  10. const assetId1 = "DGWU3mHenDerCvjkeDsKYEbsvXbWvqdo1bVoXy3dkeTd";
  11. const assetId2 = "14JojSTdBZvP7f77rCxB3oQK78skTVD6DiXrXUL4objg";//"D2CoMLCRfsfv1EAiNbaBHfoU1Sqf1964KXLGxEfyUwWo";
  12. const tree1 = new anchor.web3.PublicKey("trezdkTFPKyj4gE9LAJYPpxn8AYVCvM7Mc4JkTb9X5B")
  13. const tree2 = new anchor.web3.PublicKey("Feywkti8LLBLfxhSGmYgzUBqpq89qehfB1SMTYV1zCu")
  14. const receiver1 = new anchor.web3.PublicKey("Andys9wuoMdUeRiZLgRS5aJwYNFv4Ut6qQi8PNDTAPEM")
  15. const receiver2 = new anchor.web3.PublicKey("Andys9wuoMdUeRiZLgRS5aJwYNFv4Ut6qQi8PNDTAPEM")
  16. // ---
  17. const [vaultPDA, _bump] = anchor.web3.PublicKey.findProgramAddressSync(
  18. [Buffer.from("cNFT-vault", "utf8")],
  19. programID,
  20. );
  21. const [treeAuthority1, _bump2] = anchor.web3.PublicKey.findProgramAddressSync(
  22. [tree1.toBuffer()],
  23. BUBBLEGUM_PROGRAM_ID,
  24. );
  25. const [treeAuthority2, _bump3] = anchor.web3.PublicKey.findProgramAddressSync(
  26. [tree2.toBuffer()],
  27. BUBBLEGUM_PROGRAM_ID,
  28. );
  29. const asset1 = await getAsset(assetId1);
  30. const asset2 = await getAsset(assetId2);
  31. const proof1 = await getAssetProof(assetId1);
  32. const proofPathAsAccounts1 = mapProof(proof1);
  33. const proof2 = await getAssetProof(assetId2);
  34. const proofPathAsAccounts2 = mapProof(proof2);
  35. const ixData1 = getInstructionData(asset1, proof1);
  36. const ixData2 = getInstructionData(asset2, proof2);
  37. const remainingAccounts: AccountMeta[] = [...proofPathAsAccounts1, ...proofPathAsAccounts2];
  38. const tx = await program.methods.withdrawTwoCnfts(...ixData1, ...ixData2)
  39. .accounts({
  40. leafOwner: vaultPDA,
  41. merkleTree1: tree1,
  42. newLeafOwner1: receiver1,
  43. treeAuthority1: treeAuthority1,
  44. merkleTree2: tree2,
  45. newLeafOwner2: receiver2,
  46. treeAuthority2: treeAuthority2,
  47. bubblegumProgram: BUBBLEGUM_PROGRAM_ID,
  48. compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID,
  49. logWrapper: SPL_NOOP_PROGRAM_ID,
  50. systemProgram: anchor.web3.SystemProgram.programId
  51. })
  52. .remainingAccounts(remainingAccounts)
  53. .rpc();
  54. console.log(tx);
  55. };
  56. function getInstructionData(asset: any, proof: any):
  57. [number[], number[], number[], anchor.BN, number, number] {
  58. const root = decode(proof.root);
  59. const dataHash = decode(asset.compression.data_hash);
  60. const creatorHash = decode(asset.compression.creator_hash);
  61. const nonce = new anchor.BN(asset.compression.leaf_id);
  62. const index = asset.compression.leaf_id;
  63. const proofLength = proof.proof.length;
  64. return [root, dataHash, creatorHash, nonce, index, proofLength];
  65. }
  66. main();