/// <reference types="node" />
import * as splToken from '@solana/spl-token';
import { Connection, Keypair, PublicKey, TransactionInstruction, Transaction } from '@solana/web3.js';
import * as solanaWeb3 from '@solana/web3.js';
import BN from 'bn.js';
import { Logger, Nullable } from '../../utils';
import type { IdentityService } from '../identity';
import type { Web3Manager } from '../web3Manager';
import { SubmitAttestationsConfig as SubmitAttestationsBaseConfig, CreateSenderParams as CreateSenderBaseParams } from './rewards';
import { TransactionHandler } from './transactionHandler';
declare type EvaluateChallengeAttestationsConfig = {
    challengeId: string;
    specifier: string;
    recipientEthAddress: string;
    oracleEthAddress: string;
    tokenAmount: BN;
    logger: Logger;
};
declare type SubmitAttestationsConfig = Omit<SubmitAttestationsBaseConfig, 'rewardManagerProgramId' | 'rewardManagerAccount' | 'rewardManagerTokenSource' | 'userBankProgramAccount' | 'feePayer' | 'transactionHandler'> & {
    feePayerOverride: Nullable<string>;
};
declare type CreateSenderParams = Omit<CreateSenderBaseParams, 'rewardManagerProgramId' | 'rewardManagerAccount' | 'feePayer' | 'transactionHandler' | 'identityService'> & {
    feePayerOverride: Nullable<string>;
};
export declare type MintName = 'usdc' | 'audio';
export declare const DEFAULT_MINT: MintName;
export declare type PurchaseContentType = 'track' | 'album';
export declare type PurchaseAccess = 'stream' | 'download';
export declare type SolanaWeb3Config = {
    solanaClusterEndpoint: string;
    mintAddress: string;
    usdcMintAddress: string;
    solanaTokenAddress: string;
    feePayerAddress: PublicKey;
    claimableTokenProgramAddress: string;
    rewardsManagerProgramId: string;
    rewardsManagerProgramPDA: string;
    rewardsManagerTokenPDA: string;
    paymentRouterProgramId: string;
    useRelay: boolean;
    feePayerKeypairs?: Keypair[];
    confirmationTimeout: number;
};
/**
 * SolanaWeb3Manager acts as the interface to solana contracts from a client.
 * It wraps methods to create and lookup user banks, transfer balances, and
 * interact with the @solana/web3 library.
 *
 * Note: Callers of this class should specify all $AUDIO amounts in units of wei.
 * The internals of this class should handle the conversion from wei AUDIO to wormhole
 * $AUDIO amounts.
 */
export declare class SolanaWeb3Manager {
    solanaWeb3Config: SolanaWeb3Config;
    identityService: Nullable<IdentityService>;
    web3Manager: Nullable<Web3Manager>;
    solanaWeb3: typeof solanaWeb3;
    splToken: typeof splToken;
    solanaClusterEndpoint: string;
    transactionHandler: TransactionHandler;
    connections: Connection[];
    mints: Record<MintName, PublicKey>;
    claimableTokenPDAs: Record<MintName, PublicKey>;
    solanaTokenAddress: string;
    solanaTokenKey: PublicKey;
    feePayerAddress: PublicKey;
    feePayerKey: PublicKey;
    claimableTokenProgramKey: PublicKey;
    rewardManagerProgramId: PublicKey;
    rewardManagerProgramPDA: PublicKey;
    rewardManagerTokenPDA: PublicKey;
    paymentRouterProgramId: PublicKey;
    constructor(solanaWeb3Config: SolanaWeb3Config, identityService: Nullable<IdentityService>, web3Manager: Nullable<Web3Manager>);
    getConnection(): Connection;
    init(): Promise<void>;
    doesUserbankExist({ ethAddress, mint }?: {
        ethAddress?: string;
        mint?: MintName;
    }): Promise<boolean>;
    /**
     * Creates a solana bank account, either for optional `ethAddress` or from the web3 provider's eth address
     */
    createUserBank({ feePayerOverride, ethAddress, mint }: {
        feePayerOverride: string;
        ethAddress?: string;
        mint: MintName;
    }): Promise<{
        res: string | null;
        errorCode: string | number | null;
        error: string | null;
    }>;
    /**
     * Creates a userbank if needed.
     * Returns the userbank address as `userbank` if it was created or already existed, or `error` if it failed to create.
     */
    createUserBankIfNeeded({ feePayerOverride, ethAddress, mint }: {
        feePayerOverride: string;
        ethAddress?: string;
        mint?: MintName;
    }): Promise<{
        error: string;
        errorCode: string | number | null;
    } | {
        didExist: boolean;
        userbank: PublicKey;
    }>;
    /**
     * Creates a token account for the provided solana address (a wallet)
     * See https://spl.solana.com/associated-token-account
     */
    createAssociatedTokenAccount(solanaAddress: string, mint?: MintName): Promise<void>;
    /**
     * Finds the user bank token account for a provided solana address (a wallet) for the given mint
     * See https://spl.solana.com/associated-token-account
     */
    findAssociatedTokenAddress(solanaAddress: string, mint?: MintName): Promise<PublicKey>;
    /**
     * Gets a solana bank account from `ethAddress` or the current web3 provider's eth address.
     */
    deriveUserBank({ ethAddress, mint }?: {
        ethAddress?: string;
        mint?: MintName;
    }): Promise<PublicKey>;
    /**
     * Gets the info for a user bank/wAudio token account given a spl-token address.
     * If the address is not a valid token account, returns `null`
     */
    getTokenAccountInfo(solanaAddress: string): Promise<splToken.Account | null>;
    /**
     * Gets the SPL waudio balance for a solana address in wei with 18 decimals
     */
    getWAudioBalance(solanaAddress: string): Promise<bigint | null>;
    /**
     * Transfers audio from the web3 provider's eth address
     * @param {string} recipientSolanaAddress
     *  Recipient solana address which is either a user bank, wAudio token account,
     *  or a solana account. In the last case, an associated token account is created
     *  if one does not already exist for the solana account
     * @param {BN} amount the amount of $AUDIO to send in wei units of $AUDIO.
     * **IMPORTANT NOTE**
     * wAudio (Solana) does not support 10^-18 (wei) units of $AUDIO. The smallest
     * demarcation on that side is 10^-8, so the $AUDIO amount must be >= 10^8 and have no
     * remainder after a division with 10^8 or this method will throw.
     *
     * Generally speaking, callers into the solanaWeb3Manager should use BN.js representation
     * of wei $AUDIO for all method calls
     */
    transferWAudio(recipientSolanaAddress: string, amount: BN): Promise<{
        res: string | null;
        errorCode: string | number | null;
        error: string | null;
    }>;
    /**
     * Purchases USDC gated content
     * @param params.id the id of the content, eg. the track ID
     * @param params.type the type of the content, eg. "track"
     * @param params.blocknumber the blocknumber the content was last updated
     * @param params.splits map of address to USDC amount, used to split the price amoung several stakeholders
     * @param params.extraAmount Extra amount in USDC wei to be distributed to the stakeholders
     * @param params.purchaserUserId Id of the user that is purchasing the track
     * @returns the transaction signature and/or an error
     */
    purchaseContent({ id, type, blocknumber, extraAmount, splits, purchaserUserId, purchaseAccess }: {
        id: number;
        type: PurchaseContentType;
        splits: Record<string, number | BN>;
        extraAmount?: number | BN;
        blocknumber: number;
        purchaserUserId: number;
        purchaseAccess: PurchaseAccess;
    }): Promise<{
        res: string | null;
        errorCode: string | number | null;
        error: string | null;
    }>;
    /**
     * Purchases USDC gated content
     * @param params.id the id of the content, eg. the track ID
     * @param params.type the type of the content, eg. "track"
     * @param params.blocknumber the blocknumber the content was last updated
     * @param params.splits map of address to USDC amount, used to split the price amoung several stakeholders
     * @param params.extraAmount Extra amount in USDC wei to be distributed to the stakeholders
     * @param params.purchaserUserId Id of the user that is purchasing the track
     * @param params.senderAccount Should either be root solana account or user bank.
     * @returns the transaction signature and/or an error
     */
    getPurchaseContentWithPaymentRouterInstructions({ id, type, blocknumber, extraAmount, splits, purchaserUserId, senderAccount, purchaseAccess }: {
        id: number;
        type: PurchaseContentType;
        splits: Record<string, number | BN>;
        extraAmount?: number | BN;
        blocknumber: number;
        purchaserUserId: number;
        senderAccount: PublicKey;
        purchaseAccess: PurchaseAccess;
    }): Promise<TransactionInstruction[]>;
    purchaseContentWithPaymentRouter({ id, type, blocknumber, extraAmount, splits, purchaserUserId, senderKeypair, skipSendAndReturnTransaction, purchaseAccess }: {
        id: number;
        type: 'track';
        splits: Record<string, number | BN>;
        extraAmount?: number | BN;
        blocknumber: number;
        purchaserUserId: number;
        senderKeypair: Keypair;
        skipSendAndReturnTransaction?: boolean;
        purchaseAccess: PurchaseAccess;
    }): Promise<Transaction | {
        res: string | null;
        errorCode: string | number | null;
        error: string | null;
    }>;
    /**
     * Submits attestations for challenge completion to the RewardsManager program on Solana.
     */
    submitChallengeAttestations({ attestations, oracleAttestation, challengeId, specifier, recipientEthAddress, tokenAmount, instructionsPerTransaction, logger, feePayerOverride }: SubmitAttestationsConfig): Promise<{
        res: string | null;
        errorCode: string | number | null;
        error: string | null;
    } | undefined>;
    /**
     * Evaluates existing submitted attestations, disbursing if successful.
     */
    evaluateChallengeAttestations({ challengeId, specifier, recipientEthAddress, oracleEthAddress, tokenAmount, logger, feePayerOverride }: EvaluateChallengeAttestationsConfig & {
        feePayerOverride: Nullable<string>;
    }): Promise<{
        res: string | null;
        errorCode: string | number | null;
        error: string | null;
    }>;
    /**
     * Creates a new rewards signer (one that can attest)
     */
    createSender({ senderEthAddress, operatorEthAddress, attestations, feePayerOverride }: CreateSenderParams): Promise<{
        res: string | null;
        errorCode: string | number | null;
        error: string | null;
    }>;
    /**
     * Gets the balance of a PublicKey, in SOL
     */
    getBalance({ publicKey }: {
        publicKey: PublicKey;
    }): Promise<number>;
    /**
     * Gets whether a PublicKey has a usable balance
     */
    hasBalance({ publicKey, epsilon }: {
        publicKey: PublicKey;
        epsilon?: number;
    }): Promise<boolean>;
    getSolBalance(address: string): Promise<BN>;
    getSlot(): Promise<number>;
    getRandomFeePayer(): Promise<unknown>;
    /**
     * Gets whether a given node registered on eth with `senderEthAddress` is registered on Solana
     */
    getIsDiscoveryNodeRegistered(senderEthAddress: string): Promise<boolean>;
    findProgramAddress(programId: PublicKey, pubkey: PublicKey): Promise<[PublicKey, number]>;
    /**
     * Finds a 'derived' address by finding a programAddress with
     * seeds array  as first 32 bytes of base + seeds
     * @returns the program address
     */
    findDerivedAddress(programId: PublicKey, base: PublicKey, seed: Buffer | Uint8Array): Promise<[PublicKey, number]>;
    /**
     * Finds the target PDA with the base audius admin as the initial seed
     * In conjunction with the secondary seed as the users id in bytes
     */
    findDerivedPair(programId: PublicKey, adminAccount: PublicKey, seed: Buffer | Uint8Array): Promise<{
        baseAuthorityAccount: PublicKey;
        derivedAddress: PublicKey;
        bumpSeed: number;
    }>;
    /**
     * Given the eth address buffer from the account, convert to hex
     * @returns hex string of input bytes
     */
    deriveEthWalletFromAddress(accountEthAddress: Buffer): Promise<string>;
    /**
     * Creates transfer instructions from the current user's user bank to the provided solana address.
     * Supports both $AUDIO or USDC user banks.
     */
    createTransferInstructionsFromCurrentUser({ amount, feePayerKey, senderSolanaAddress, recipientSolanaAddress, mint, instructionIndex }: {
        amount: BN;
        senderSolanaAddress: PublicKey;
        recipientSolanaAddress: string;
        mint: MintName;
        feePayerKey: PublicKey;
        instructionIndex?: number;
    }): Promise<TransactionInstruction[]>;
}
export {};
