withdrawTwo.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import * as anchor from '@coral-xyz/anchor';
  2. import { PROGRAM_ID as BUBBLEGUM_PROGRAM_ID } from '@metaplex-foundation/mpl-bubblegum';
  3. import { SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, SPL_NOOP_PROGRAM_ID } from '@solana/spl-account-compression';
  4. import type { AccountMeta } from '@solana/web3.js';
  5. import { getAsset, getAssetProof } from '../readAPI';
  6. import { decode, mapProof } from '../utils';
  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([Buffer.from('cNFT-vault', 'utf8')], programID);
  18. const [treeAuthority1, _bump2] = anchor.web3.PublicKey.findProgramAddressSync([tree1.toBuffer()], BUBBLEGUM_PROGRAM_ID);
  19. const [treeAuthority2, _bump3] = anchor.web3.PublicKey.findProgramAddressSync([tree2.toBuffer()], BUBBLEGUM_PROGRAM_ID);
  20. const asset1 = await getAsset(assetId1);
  21. const asset2 = await getAsset(assetId2);
  22. const proof1 = await getAssetProof(assetId1);
  23. const proofPathAsAccounts1 = mapProof(proof1);
  24. const proof2 = await getAssetProof(assetId2);
  25. const proofPathAsAccounts2 = mapProof(proof2);
  26. const ixData1 = getInstructionData(asset1, proof1);
  27. const ixData2 = getInstructionData(asset2, proof2);
  28. const remainingAccounts: AccountMeta[] = [...proofPathAsAccounts1, ...proofPathAsAccounts2];
  29. const tx = await program.methods
  30. .withdrawTwoCnfts(...ixData1, ...ixData2)
  31. .accounts({
  32. leafOwner: vaultPDA,
  33. merkleTree1: tree1,
  34. newLeafOwner1: receiver1,
  35. treeAuthority1: treeAuthority1,
  36. merkleTree2: tree2,
  37. newLeafOwner2: receiver2,
  38. treeAuthority2: treeAuthority2,
  39. bubblegumProgram: BUBBLEGUM_PROGRAM_ID,
  40. compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID,
  41. logWrapper: SPL_NOOP_PROGRAM_ID,
  42. systemProgram: anchor.web3.SystemProgram.programId,
  43. })
  44. .remainingAccounts(remainingAccounts)
  45. .rpc();
  46. console.log(tx);
  47. }
  48. function getInstructionData(asset: any, proof: any): [number[], number[], number[], anchor.BN, number, number] {
  49. const root = decode(proof.root);
  50. const dataHash = decode(asset.compression.data_hash);
  51. const creatorHash = decode(asset.compression.creator_hash);
  52. const nonce = new anchor.BN(asset.compression.leaf_id);
  53. const index = asset.compression.leaf_id;
  54. const proofLength = proof.proof.length;
  55. return [root, dataHash, creatorHash, nonce, index, proofLength];
  56. }
  57. main();