import { toMintAddress } from './helpers';
import { NftBuildersClient } from './NftBuildersClient';
import { NftPdasClient } from './NftPdasClient';
import { approveNftCollectionAuthorityOperation, approveNftUseAuthorityOperation, createNftOperation, createSftOperation, deleteNftOperation, findNftByMetadataOperation, findNftByMintOperation, findNftByTokenOperation, findNftsByCreatorOperation, findNftsByMintListOperation, findNftsByOwnerOperation, findNftsByUpdateAuthorityOperation, freezeDelegatedNftOperation, loadMetadataOperation, migrateToSizedCollectionNftOperation, printNewEditionOperation, revokeNftCollectionAuthorityOperation, revokeNftUseAuthorityOperation, thawDelegatedNftOperation, unverifyNftCollectionOperation, unverifyNftCreatorOperation, updateNftOperation, uploadMetadataOperation, useNftOperation, verifyNftCollectionOperation, verifyNftCreatorOperation, } from './operations';
import { token } from '../../types';
/**
 * This is a client for the NFT module.
 *
 * It enables us to interact with the Token Metadata program in order to
 * manage NFTs and SFTs.
 *
 * You may access this client via the `nfts()` method of your `Metaplex` instance.
 *
 * ```ts
 * const nftClient = metaplex.nfts();
 * ```
 *
 * @example
 * You can upload some custom JSON metadata and use its URI to create
 * a new NFT like so. The owner and update authority of this NFT will,
 * by default, be the current identity of the metaplex instance.
 *
 * ```ts
 * const { uri } = await metaplex
 *   .nfts()
 *   .uploadMetadata({
 *     name: "My off-chain name",
 *     description: "My off-chain description",
 *     image: "https://arweave.net/123",
 *   };
 *
 * const { nft } = await metaplex
 *   .nfts()
 *   .create({
 *     uri,
 *     name: 'My on-chain NFT',
 *     sellerFeeBasisPoints: 250, // 2.5%
 *   };
 * ```
 *
 * @group Modules
 */
export class NftClient {
    constructor(metaplex) {
        this.metaplex = metaplex;
    }
    /**
     * You may use the `builders()` client to access the
     * underlying Transaction Builders of this module.
     *
     * ```ts
     * const buildersClient = metaplex.nfts().builders();
     * ```
     */
    builders() {
        return new NftBuildersClient(this.metaplex);
    }
    /**
     * You may use the `pdas()` client to build PDAs related to this module.
     *
     * ```ts
     * const pdasClient = metaplex.nfts().pdas();
     * ```
     */
    pdas() {
        return new NftPdasClient(this.metaplex);
    }
    // -----------------
    // Queries
    // -----------------
    /** {@inheritDoc findNftByMintOperation} */
    findByMint(input, options) {
        return this.metaplex
            .operations()
            .execute(findNftByMintOperation(input), options);
    }
    /** {@inheritDoc findNftByMetadataOperation} */
    findByMetadata(input, options) {
        return this.metaplex
            .operations()
            .execute(findNftByMetadataOperation(input), options);
    }
    /** {@inheritDoc findNftByTokenOperation} */
    findByToken(input, options) {
        return this.metaplex
            .operations()
            .execute(findNftByTokenOperation(input), options);
    }
    /** {@inheritDoc findNftsByCreatorOperation} */
    findAllByCreator(input, options) {
        return this.metaplex
            .operations()
            .execute(findNftsByCreatorOperation(input), options);
    }
    /** {@inheritDoc findNftsByMintListOperation} */
    findAllByMintList(input, options) {
        return this.metaplex
            .operations()
            .execute(findNftsByMintListOperation(input), options);
    }
    /** {@inheritDoc findNftsByOwnerOperation} */
    findAllByOwner(input, options) {
        return this.metaplex
            .operations()
            .execute(findNftsByOwnerOperation(input), options);
    }
    /** {@inheritDoc findNftsByUpdateAuthorityOperation} */
    findAllByUpdateAuthority(input, options) {
        return this.metaplex
            .operations()
            .execute(findNftsByUpdateAuthorityOperation(input), options);
    }
    /** {@inheritDoc loadMetadataOperation} */
    load(input, options) {
        return this.metaplex
            .operations()
            .execute(loadMetadataOperation(input), options);
    }
    /**
     * Helper method that refetches a given model
     * and returns an instance of the same type.
     *
     * ```ts
     * nft = await metaplex.nfts().refresh(nft);
     * sft = await metaplex.nfts().refresh(sft);
     * nftWithToken = await metaplex.nfts().refresh(nftWithToken);
     * ```
     */
    refresh(model, input, options) {
        return this.findByMint(Object.assign({ mintAddress: toMintAddress(model), tokenAddress: 'token' in model ? model.token.address : undefined }, input), options);
    }
    // -----------------
    // Create, Update and Delete
    // -----------------
    /** {@inheritDoc createNftOperation} */
    create(input, options) {
        return this.metaplex
            .operations()
            .execute(createNftOperation(input), options);
    }
    /** {@inheritDoc createSftOperation} */
    createSft(input, options) {
        return this.metaplex
            .operations()
            .execute(createSftOperation(input), options);
    }
    /** {@inheritDoc printNewEditionOperation} */
    printNewEdition(input, options) {
        return this.metaplex
            .operations()
            .execute(printNewEditionOperation(input), options);
    }
    /** {@inheritDoc uploadMetadataOperation} */
    uploadMetadata(input, options) {
        return this.metaplex
            .operations()
            .execute(uploadMetadataOperation(input), options);
    }
    /** {@inheritDoc updateNftOperation} */
    update(input, options) {
        return this.metaplex
            .operations()
            .execute(updateNftOperation(input), options);
    }
    /** {@inheritDoc deleteNftOperation} */
    delete(input, options) {
        return this.metaplex
            .operations()
            .execute(deleteNftOperation(input), options);
    }
    // -----------------
    // Use
    // -----------------
    /** {@inheritDoc useNftOperation} */
    use(input, options) {
        return this.metaplex.operations().execute(useNftOperation(input), options);
    }
    /** {@inheritDoc approveNftUseAuthorityOperation} */
    approveUseAuthority(input, options) {
        return this.metaplex
            .operations()
            .execute(approveNftUseAuthorityOperation(input), options);
    }
    /** {@inheritDoc revokeNftUseAuthorityOperation} */
    revokeUseAuthority(input, options) {
        return this.metaplex
            .operations()
            .execute(revokeNftUseAuthorityOperation(input), options);
    }
    // -----------------
    // Creators
    // -----------------
    /** {@inheritDoc verifyNftCreatorOperation} */
    verifyCreator(input, options) {
        return this.metaplex
            .operations()
            .execute(verifyNftCreatorOperation(input), options);
    }
    /** {@inheritDoc unverifyNftCreatorOperation} */
    unverifyCreator(input, options) {
        return this.metaplex
            .operations()
            .execute(unverifyNftCreatorOperation(input), options);
    }
    // -----------------
    // Collections
    // -----------------
    /** {@inheritDoc verifyNftCollectionOperation} */
    verifyCollection(input, options) {
        return this.metaplex
            .operations()
            .execute(verifyNftCollectionOperation(input), options);
    }
    /** {@inheritDoc unverifyNftCollectionOperation} */
    unverifyCollection(input, options) {
        return this.metaplex
            .operations()
            .execute(unverifyNftCollectionOperation(input), options);
    }
    /** {@inheritDoc approveNftCollectionAuthorityOperation} */
    approveCollectionAuthority(input, options) {
        return this.metaplex
            .operations()
            .execute(approveNftCollectionAuthorityOperation(input), options);
    }
    /** {@inheritDoc revokeNftCollectionAuthorityOperation} */
    revokeCollectionAuthority(input, options) {
        return this.metaplex
            .operations()
            .execute(revokeNftCollectionAuthorityOperation(input), options);
    }
    /** {@inheritDoc migrateToSizedCollectionNftOperation} */
    migrateToSizedCollection(input, options) {
        return this.metaplex
            .operations()
            .execute(migrateToSizedCollectionNftOperation(input), options);
    }
    // -----------------
    // Tokens
    // -----------------
    /** {@inheritDoc freezeDelegatedNftOperation} */
    freezeDelegatedNft(input, options) {
        return this.metaplex
            .operations()
            .execute(freezeDelegatedNftOperation(input), options);
    }
    /** {@inheritDoc thawDelegatedNftOperation} */
    thawDelegatedNft(input, options) {
        return this.metaplex
            .operations()
            .execute(thawDelegatedNftOperation(input), options);
    }
    /** {@inheritDoc sendTokensOperation} */
    send(input, options) {
        // TODO: update documentation.
        return this.metaplex.tokens().send(Object.assign(Object.assign({}, input), { amount: token(1) }), options);
    }
}
//# sourceMappingURL=NftClient.js.map