import * as anchor from "@project-serum/anchor"; import { getAssociatedTokenAddress, getAccount, createAssociatedTokenAccountInstruction, } from "@solana/spl-token"; import { TOKEN_METADATA_PROGRAM_ID, STRIKR_COLLECTION_MINT, } from "../constants"; import { getStrikr, getStrikrAuthority } from "../utils"; import { getOption } from "./get-option"; import { requestComputeUnits } from "../actions/request-compute-units"; /** * Close the put option seller position. * @param provider Anchor provider * @param assetNftMint Asset NFT which underlies the option * @param sellerPositionNftMint Position NFT representing option seller position * @param assetNftTokenAccount Token account containing the asset NFT * @returns Promise resolving to the transaction signature */ export const closePutOptionSeller = async ( provider: anchor.AnchorProvider, assetNftMint: anchor.web3.PublicKey, sellerPositionNftMint: anchor.web3.PublicKey, assetNftTokenAccount?: anchor.web3.PublicKey ) => { const strikr = getStrikr(provider); const transaction = new anchor.web3.Transaction(); // Request additional compute units and attach the instruction const computeUnitsIx = requestComputeUnits(provider, 400_000, 0); transaction.add(computeUnitsIx); const sellerPositionNftTokenAccount = await getAssociatedTokenAddress( sellerPositionNftMint, provider.wallet.publicKey, true ); // Use wallet's ATA as the NFT token account if not passed as argument if (!assetNftTokenAccount) { assetNftTokenAccount = await getAssociatedTokenAddress( assetNftMint, provider.wallet.publicKey ); // Check if ATA exists, otherwise initialize it try { await getAccount(provider.connection, assetNftTokenAccount); } catch { transaction.add( createAssociatedTokenAccountInstruction( provider.wallet.publicKey, assetNftTokenAccount, provider.wallet.publicKey, assetNftMint ) ); } } const strikrAuthority = await getStrikrAuthority(); const strikrAssetNftTokenAccount = await getAssociatedTokenAddress( assetNftMint, strikrAuthority, true ); transaction.add( await strikr.methods .closePutOptionSeller() .accounts({ signer: provider.wallet.publicKey, assetNftMint, strikrCollectionMint: STRIKR_COLLECTION_MINT, sellerPositionNftMint, sellerPositionNftTokenAccount, signerAssetNftTokenAccount: assetNftTokenAccount, strikrAssetNftTokenAccount, tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID, }) .instruction() ); const optionState = await getOption(provider.connection, assetNftMint); if (optionState.isBuyerClosed) { transaction.add( await strikr.methods .closeOptionState() .accounts({ signer: provider.wallet.publicKey, assetNftMint, strikrAssetNftTokenAccount, }) .instruction() ); } return await provider.sendAndConfirm(transaction); };