'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var mplAuctionHouse = require('@metaplex-foundation/mpl-auction-house');
var web3_js = require('@solarti/web3.js');
var errors = require('../errors.cjs');
var Operation = require('../../../types/Operation.cjs');
var PublicKey = require('../../../types/PublicKey.cjs');
var TransactionBuilder = require('../../../utils/TransactionBuilder.cjs');
var Signer = require('../../../types/Signer.cjs');

// -----------------
// Operation
// -----------------

const Key = 'CancelBidOperation';

/**
 * Cancels the user's bid in the given auction house.
 *
 * ```ts
 * await metaplex
 *   .auctionHouse()
 *   .cancelBid({ auctionHouse, bid };
 * ```
 *
 * @group Operations
 * @category Constructors
 */
const cancelBidOperation = Operation.useOperation(Key);

/**
 * @group Operations
 * @category Types
 */

/**
 * @group Operations
 * @category Handlers
 */
const cancelBidOperationHandler = {
  handle: async (operation, metaplex, scope) => cancelBidBuilder(metaplex, operation.input, scope).sendAndConfirm(metaplex, scope.confirmOptions)
};

// -----------------
// Builder
// -----------------

/**
 * @group Transaction Builders
 * @category Inputs
 */

/**
 * Cancels the user's bid in the given auction house.
 *
 * ```ts
 * const transactionBuilder = metaplex
 *   .auctionHouse()
 *   .builders()
 *   .cancelBid({ auctionHouse, bid });
 * ```
 *
 * @group Transaction Builders
 * @category Constructors
 */
const cancelBidBuilder = (metaplex, params, options = {}) => {
  const {
    programs,
    payer = metaplex.rpc().getDefaultFeePayer()
  } = options;
  const {
    auctionHouse,
    auctioneerAuthority,
    bid
  } = params;

  // Data.
  const {
    asset,
    buyerAddress,
    tradeStateAddress,
    price,
    receiptAddress,
    tokens,
    isPublic
  } = bid;
  const {
    authorityAddress,
    address: auctionHouseAddress,
    feeAccountAddress,
    hasAuctioneer
  } = auctionHouse;
  if (hasAuctioneer && !auctioneerAuthority) {
    throw new errors.AuctioneerAuthorityRequiredError();
  }

  // Accounts.
  const tokenAccount = isPublic ? metaplex.tokens().pdas().associatedTokenAccount({
    mint: asset.mint.address,
    owner: PublicKey.toPublicKey(buyerAddress),
    programs
  }) : asset.token.address;
  const accounts = {
    wallet: buyerAddress,
    tokenAccount,
    tokenMint: asset.address,
    authority: authorityAddress,
    auctionHouse: auctionHouseAddress,
    auctionHouseFeeAccount: feeAccountAddress,
    tradeState: tradeStateAddress
  };

  // Args.
  const args = {
    buyerPrice: price.basisPoints,
    tokenSize: tokens.basisPoints
  };

  // Cancel Bid Instruction.
  let cancelBidInstruction = mplAuctionHouse.createCancelInstruction(accounts, args);
  if (auctioneerAuthority) {
    cancelBidInstruction = mplAuctionHouse.createAuctioneerCancelInstruction({
      ...accounts,
      auctioneerAuthority: auctioneerAuthority.publicKey,
      ahAuctioneerPda: metaplex.auctionHouse().pdas().auctioneer({
        auctionHouse: auctionHouseAddress,
        auctioneerAuthority: auctioneerAuthority.publicKey,
        programs
      })
    }, args);
  }

  // Signers.
  const cancelSigners = [auctioneerAuthority].filter(Signer.isSigner);
  return TransactionBuilder.TransactionBuilder.make().setFeePayer(payer)

  // Cancel Bid.
  .add({
    instruction: cancelBidInstruction,
    signers: cancelSigners,
    key: params.instructionKey ?? 'cancelBid'
  })

  // Cancel Bid Receipt.
  .when(Boolean(receiptAddress), builder => builder.add({
    instruction: mplAuctionHouse.createCancelBidReceiptInstruction({
      receipt: receiptAddress,
      instruction: web3_js.SYSVAR_INSTRUCTIONS_PUBKEY
    }),
    signers: [],
    key: 'cancelBidReceipt'
  }));
};

exports.cancelBidBuilder = cancelBidBuilder;
exports.cancelBidOperation = cancelBidOperation;
exports.cancelBidOperationHandler = cancelBidOperationHandler;
//# sourceMappingURL=cancelBid.cjs.map
