'use strict';

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

var programs = require('../programs.cjs');
var CandyMachine = require('../models/CandyMachine.cjs');
var Account = require('../../../types/Account.cjs');
var CandyGuard = require('../models/CandyGuard.cjs');
var web3_js = require('@solarti/web3.js');

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

const Key = 'FindCandyMachineByAddressOperation';

/**
 * Find an existing Candy Machine by its address.
 *
 * ```ts
 * const candyMachine = await metaplex
 *   .candyMachines()
 *   .findbyAddress({ address };
 * ```
 *
 * @group Operations
 * @category Constructors
 */
const findCandyMachineByAddressOperation = _findCandyMachineByAddressOperation;
// eslint-disable-next-line @typescript-eslint/naming-convention
function _findCandyMachineByAddressOperation(input) {
  return {
    key: Key,
    input
  };
}
_findCandyMachineByAddressOperation.key = Key;

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

/**
 * @group Operations
 * @category Handlers
 */
const findCandyMachineByAddressOperationHandler = {
  async handle(operation, metaplex, scope) {
    const {
      address
    } = operation.input;
    const {
      commitment,
      programs: programs$1
    } = scope;
    const potentialCandyGuardAddress = metaplex.candyMachines().pdas().candyGuard({
      base: address,
      programs: programs$1
    });
    const [candyMachineAccount, potentialCandyGuardAccount] = await metaplex.rpc().getMultipleAccounts([address, potentialCandyGuardAddress], commitment);
    scope.throwIfCanceled();
    Account.assertAccountExists(candyMachineAccount, 'CandyMachine');
    const candyMachine = CandyMachine.toCandyMachine(candyMachineAccount);
    const mintAuthority = candyMachine.mintAuthorityAddress;

    // Optimisation that tries to load both the Candy Machine
    // And the Candy Guard in one RPC call assuming the Candy
    // Machine's address is the base address of the Candy Guard.
    if (potentialCandyGuardAccount.exists && potentialCandyGuardAccount.publicKey.equals(mintAuthority)) {
      return {
        ...candyMachine,
        candyGuard: CandyGuard.toCandyGuard(potentialCandyGuardAccount, metaplex)
      };
    }

    // If the Candy Machine's mint authority is not a PDA,
    // it cannot have an associated Candy Guard.
    if (web3_js.PublicKey.isOnCurve(mintAuthority)) {
      return candyMachine;
    }

    // Fetch the content of the mint authority PDA.
    const mintAuthorityAccount = await metaplex.rpc().getAccount(mintAuthority, commitment);
    scope.throwIfCanceled();
    try {
      // Identity the program owner as a Candy Guard program
      // and parse the Candy Guard accordingly.
      Account.assertAccountExists(mintAuthorityAccount);
      const program = metaplex.programs().get(mintAuthorityAccount.owner);
      programs.assertCandyGuardProgram(program);
      return {
        ...candyMachine,
        candyGuard: CandyGuard.toCandyGuard(mintAuthorityAccount, metaplex)
      };
    } catch (error) {
      // If anything goes wrong, assume there is no Candy Guard
      // attached to this Candy Machine.
      return candyMachine;
    }
  }
};

exports.findCandyMachineByAddressOperation = findCandyMachineByAddressOperation;
exports.findCandyMachineByAddressOperationHandler = findCandyMachineByAddressOperationHandler;
//# sourceMappingURL=findCandyMachineByAddress.cjs.map
