import { AliasHash } from '@polyaztec/barretenberg/account_id';
import { EthAddress, GrumpkinAddress } from '@polyaztec/barretenberg/address';
import { ProofId } from '@polyaztec/barretenberg/client_proofs';
import { pickDefiInputNotes, pickInputNotes } from './pick_input_notes.js';
import { getSpendingKeyAccount } from './spending_key_account.js';
export class ProofRequestDataFactory {
    constructor(worldState, db, blake2s) {
        this.worldState = worldState;
        this.db = db;
        this.blake2s = blake2s;
    }
    /**
     * accountState can be undefined when one of the following is true:
     *  - proofId === ProofId.DEPOSIT
     *  - inputNotes will be picked by AztecWalletProvider when creating proof inputs.
     */
    async createPaymentProofRequestData(proofId, accountPublicKey, spendingPublicKey, assetValue, fee, publicOwner, recipient, recipientSpendingKeyRequired, accountState, options = {}) {
        // TODO - validate input args
        // If spendingPublicKey equals GrumpkinAddress.ZERO, it means that spendingPublicKey is unknown at the moment, and
        // proofInputs will be sent to the spending key owner later on to create signatures.
        const spendingKeyRequired = !spendingPublicKey.equals(accountPublicKey) || spendingPublicKey.equals(GrumpkinAddress.ZERO);
        const inputNotes = accountState
            ? await pickInputNotes(assetValue, fee, { ...options, spendingKeyRequired }, accountState, this.worldState)
            : [];
        const spendingKeyAccount = await getSpendingKeyAccount(spendingPublicKey, accountPublicKey, this.worldState, this.db);
        const dataRoot = this.worldState.getRoot();
        // The output note from a deposit proof can't be chained from by default because it will be a privacy leak when the
        // chained tx is defi or withdraw. People will be able to associate an L1 address or a defi interaction with the
        // depositor.
        const allowChain = options.allowChain ?? proofId !== ProofId.DEPOSIT;
        const hideNoteCreator = options.hideNoteCreator ?? false;
        return {
            accountPublicKey,
            proofId,
            assetValue,
            fee,
            publicOwner,
            recipient,
            recipientSpendingKeyRequired,
            inputNotes,
            spendingKeyAccount,
            dataRoot,
            allowChain,
            hideNoteCreator,
        };
    }
    async createAccountProofRequestData(accountPublicKey, spendingPublicKey, alias, newAccountPublicKey, newSpendingPublicKey1, newSpendingPublicKey2, deposit, fee, depositor, accountState, options = {}) {
        // TODO - validate input args
        if (deposit.value && fee.value && deposit.assetId !== fee.assetId) {
            throw new Error('Inconsistent asset ids.');
        }
        const aliasHash = alias
            ? AliasHash.fromAlias(alias, this.blake2s)
            : (await this.db.getAlias(accountPublicKey))?.aliasHash;
        if (!aliasHash) {
            throw new Error('Provide an alias or wait for the account to be fully synced.');
        }
        const publicInput = !depositor.equals(EthAddress.ZERO) ? deposit.value + fee.value : BigInt(0);
        const privateInput = !publicInput ? fee.value : BigInt(0);
        const inputNotes = privateInput && accountState
            ? await pickInputNotes({ value: privateInput, assetId: fee.assetId }, fee, { ...options, spendingKeyRequired: true }, accountState, this.worldState)
            : [];
        const spendingKeyAccount = await getSpendingKeyAccount(spendingPublicKey, accountPublicKey, this.worldState, this.db);
        const dataRoot = this.worldState.getRoot();
        const allowChain = options.allowChain ?? !!privateInput;
        return {
            accountPublicKey,
            alias,
            aliasHash,
            newAccountPublicKey,
            newSpendingPublicKey1,
            newSpendingPublicKey2,
            deposit,
            fee,
            depositor,
            inputNotes,
            spendingKeyAccount,
            dataRoot,
            allowChain,
        };
    }
    // accountState can be undefined if inputNotes will be picked by AztecWalletProvider when creating proof inputs.
    async createDefiProofRequestData(accountPublicKey, spendingPublicKey, bridgeCallData, assetValue, fee, accountState, options = {}) {
        // TODO - validate input args
        const spendingKeyRequired = !spendingPublicKey.equals(accountPublicKey) || spendingPublicKey.equals(GrumpkinAddress.ZERO);
        const inputNotes = accountState
            ? await pickDefiInputNotes(bridgeCallData, assetValue, fee, { ...options, spendingKeyRequired }, accountState, this.worldState)
            : [];
        const spendingKeyAccount = await getSpendingKeyAccount(spendingPublicKey, accountPublicKey, this.worldState, this.db);
        const dataRoot = this.worldState.getRoot();
        const allowChain = options.allowChain ?? true;
        return {
            accountPublicKey,
            bridgeCallData,
            assetValue,
            fee,
            inputNotes,
            spendingKeyAccount,
            dataRoot,
            allowChain,
        };
    }
}
//# sourceMappingURL=data:application/json;base64, 