import { Observable } from "rxjs";
import { Demand, DemandBodyPrototype, DemandSpecification } from "./demand";
import { MarketProposalEvent, OfferCounterProposal, OfferProposal } from "./proposal";
import { Agreement, AgreementEvent, AgreementState } from "./agreement";
import { AgreementOptions } from "./agreement/agreement";
import { ScanSpecification, ScannedOffer } from "./scan";
export type MarketEvents = {
    demandSubscriptionStarted: (event: {
        demand: Demand;
    }) => void;
    demandSubscriptionRefreshed: (event: {
        demand: Demand;
    }) => void;
    demandSubscriptionStopped: (event: {
        demand: Demand;
    }) => void;
    /** Emitted when offer proposal from the Provider is received */
    offerProposalReceived: (event: {
        offerProposal: OfferProposal;
    }) => void;
    offerCounterProposalSent: (event: {
        offerProposal: OfferProposal;
        counterProposal: OfferCounterProposal;
    }) => void;
    errorSendingCounterProposal: (event: {
        offerProposal: OfferProposal;
        error: Error;
    }) => void;
    /** Emitted when the Provider rejects the counter-proposal that the Requestor sent */
    offerCounterProposalRejected: (event: {
        counterProposal: OfferCounterProposal;
        reason: string;
    }) => void;
    /** Not implemented */
    offerPropertyQueryReceived: () => void;
    offerProposalRejectedByProposalFilter: (event: {
        offerProposal: OfferProposal;
        reason?: string;
    }) => void;
    /** Emitted when proposal price does not meet user criteria */
    offerProposalRejectedByPriceFilter: (event: {
        offerProposal: OfferProposal;
        reason?: string;
    }) => void;
    agreementApproved: (event: {
        agreement: Agreement;
    }) => void;
    agreementRejected: (event: {
        agreement: Agreement;
        reason: string;
    }) => void;
    agreementTerminated: (event: {
        agreement: Agreement;
        reason: string;
        terminatedBy: "Provider" | "Requestor";
    }) => void;
    agreementCancelled: (event: {
        agreement: Agreement;
    }) => void;
};
export interface IMarketApi {
    /**
     * Creates a new demand based on the given specification and publishes
     * it to the market.
     * Keep in mind that the demand lasts for a limited time and needs to be
     * refreshed periodically (see `refreshDemand` method).
     * Use `unpublishDemand` to remove the demand from the market.
     */
    publishDemandSpecification(specification: DemandSpecification): Promise<Demand>;
    /**
     * Remove the given demand from the market.
     */
    unpublishDemand(demand: Demand): Promise<void>;
    /**
     * "Publishes" the demand on the network and stats to listen (event polling) for the events representing the feedback
     *
     * The feedback can fall into four categories:
     *
     * - (Initial) We will receive initial offer proposals that were matched by the yagna node which we're using
     * - (Negotiations) We will receive responses from providers with draft offer proposals if we decided to counter the initial proposal
     * - (Negotiations) We will receive an event representing rejection of our counter-proposal by the provider
     * - (Negotiations) We will receive a question from the provider about a certain property as part of the negotiation process (_protocol piece not by yagna 0.15_)
     *
     * @param demand
     *
     * @returns A complex object that allows subscribing to these categories of feedback mentioned above
     */
    collectMarketProposalEvents(demand: Demand): Observable<MarketProposalEvent>;
    /**
     * Start looking at the Agreement related events
     */
    collectAgreementEvents(): Observable<AgreementEvent>;
    /**
     * Sends a counter-proposal to the given proposal. Returns the newly created counter-proposal.
     */
    counterProposal(receivedProposal: OfferProposal, specification: DemandSpecification): Promise<OfferCounterProposal>;
    /**
     * Sends a "reject" response for the proposal that was received from the Provider as part of the negotiation process
     *
     * On the protocol level this means that no further counter-proposals will be generated by the Requestor
     *
     * @param receivedProposal The proposal from the provider
     * @param reason User readable reason that should be presented to the Provider
     */
    rejectProposal(receivedProposal: OfferProposal, reason: string): Promise<void>;
    /**
     * Fetches payment related decorations, based on the given allocation ID.
     *
     * @param allocationId The ID of the allocation that will be used to pay for computations related to the demand
     *
     */
    getPaymentRelatedDemandDecorations(allocationId: string): Promise<DemandBodyPrototype>;
    /**
     * Retrieves an agreement based on the provided ID.
     */
    getAgreement(id: string, signalOrTimeout?: AbortSignal | number): Promise<Agreement>;
    /**
     * Request creating an agreement from the provided proposal
     *
     * Use this method if you want to decide what should happen with the agreement after it is created
     *
     * @return An agreement that's in a "Proposal" state (not yet usable for activity creation)
     */
    createAgreement(proposal: OfferProposal, options?: AgreementOptions): Promise<Agreement>;
    /**
     * Request creating an agreement from the provided proposal, send it to the Provider and wait for approval
     *
     * Use this method when you want to quickly finalize the deal with the Provider, but be ready for a rejection
     *
     * @return An agreement that's already in an "Approved" state and can be used to create activities on the Provider
     */
    proposeAgreement(proposal: OfferProposal, options?: AgreementOptions, signalOrTimeout?: AbortSignal | number): Promise<Agreement>;
    /**
     * Confirms the agreement with the provider
     */
    confirmAgreement(agreement: Agreement, options?: AgreementOptions, signalOrTimeout?: AbortSignal | number): Promise<Agreement>;
    /**
     * Terminates an agreement.
     */
    terminateAgreement(agreement: Agreement, reason?: string, signalOrTimeout?: AbortSignal | number): Promise<Agreement>;
    /**
     * Retrieves the state of an agreement based on the provided agreement ID.
     */
    getAgreementState(id: string, signalOrTimeout?: AbortSignal | number): Promise<AgreementState>;
    /**
     * Scan the market for offers that match the given specification.
     */
    scan(scanSpecification: ScanSpecification): Observable<ScannedOffer>;
}
