import { Ecc, Script, Signatory, UnsignedTxInput } from 'ecash-lib';
/**
 * "Human viable" parameters for partial Agora offers, can serve as a basis to
 * approximate the actual Script parameters via AgoraPartial.approximateParams.
 **/
export interface AgoraPartialParams {
    /**
     * Offered tokens in base tokens. After param approximation, this may differ
     * from `AgoraPartial`.offeredAtoms(), so make sure to use that when
     * preparing the offer!
     *
     * For SLP, the maximum allowed value here is 0xffffffffffffffff, for ALP it
     * is 0xffffffffffff.
     **/
    offeredAtoms: bigint;
    /**
     * Price in nano sats per atom (aka base token).
     * Using nsats allows users to specify a very large range of prices, from
     * tokens where billions of them cost a single sat, to offers where single
     * tokens can cost millions of XEC.
     **/
    priceNanoSatsPerAtom: bigint;
    /**
     * Public key of the offering party.
     * This is the public key of the wallet, and it serves both as the pubkey to
     * cancel the offer, as well as the pubkey of the P2PKH script to send the
     * sats to.
     **/
    makerPk: Uint8Array;
    /**
     * Minimum number of atoms that can be accepted.
     * Can be used to avoid spam and prevent exploits with really small
     * accept amounts.
     * Also, small amounts can have very bad precision, and raising the minimum
     * amount can mitigate this.
     * It can also just be used to increase the minimum for which tokens are
     * available.
     * It is recommended to set this to 0.1% of the offered amount.
     **/
    minAcceptedAtoms: bigint;
    /** Token ID of the offered token, in big-endian hex. */
    tokenId: string;
    /** Token type of the offered token. */
    tokenType: number;
    /** Token protocol of the offered token. */
    tokenProtocol: 'SLP' | 'ALP';
    /**
     * Locktime enforced by the Script. Used to make identical offers unique.
     *
     * Use Agora.selectParams to automatically select a good value for this,
     * only set this manually if you know what you're doing.
     *
     * If there's two offers with identical terms, it would be possible to burn
     * one of them by accepting both in one transaction.
     * To prevent this for identical offers, set to unique (past) locktimes.
     **/
    enforcedLockTime: number;
    /** Dust amount to be used by the script. */
    dustSats?: bigint;
    /**
     * Minimum atomsScaleFactor when approximating numAtomsTruncBytes.
     * It is recommended to leave this at the default (1000), but it is exposed
     * to either increase price precision and granularity of token amounts (by
     * raising the limit), or to lower price precision but allow more fine-
     * grained token amounts (by lowering the limit).
     **/
    minAtomsScaleFactor?: bigint;
    /**
     * Minimum integer when representing the price
     * (scaledTruncAtomsPerTruncSat), the approximation will truncate
     * additional sats bytes in order to make scaledTruncAtomsPerTruncSat
     * bigger.
     * It is recommended to leave this at the default (1000), but it is exposed
     * for cases where a small number of tokens are offered for a big price,
     * this can be used to improve precision.
     **/
    minPriceInteger?: bigint;
    /**
     * Minimum ratio atomsScaleFactor / scaledTruncAtomsPerTruncSat, this can
     * be used to limit the additional truncation introduced by minPriceInteger.
     * It is recommended to leave this at the default (1000), but it is exposed
     * for cases where the askedSats for small accept amounts are very
     * inaccurate.
     **/
    minScaleRatio?: bigint;
}
/**
 * An Agora offer that can partially be accepted.
 * In contrast to oneshot offers, these can be partially accepted, with the
 * remainder sent back to a new UTXO with the same terms but reduced token
 * amount.
 * This is useful for fungible tokens, where the maker doesn't know upfront how
 * many tokens the takers would like to acquire.
 *
 * The Script enforces that the taker re-creates an offer with the same terms
 * with tokens he didn't buy.
 * It calculates the required sats to accept the offer based on the price per
 * token, and the number of tokens requested by the taker, and enforces the
 * correct amount of satoshis are sent to the P2PKH of the maker of this offer.
 *
 * Offers can also be cancelled by the maker of the offer.
 *
 * One complication is the price calculation, due to eCash's limited precision
 * and range (31-bits plus 1 sign bit) of its Script integers.
 * We employ two strategies to increase precision and range:
 * - "Scaling": We scale up values to the maximum representable, such that we
 *   make full use of the 31 bits available. Values that have been scaled up
 *   have the prefix "scaled", and the scale factor is "atomsScaleFactor". We
 *   only scale token amounts.
 * - "Truncation": We cut off bytes at the "end" of numbers, essentially
 *   dividing them by 256 for each truncation, until they fit in 31 bits, so we
 *   can use arithmetic opcodes. Later we "un-truncate" values again by adding
 *   the bytes back. We use OP_CAT to un-truncate values, which doesn't care
 *   about the 31-bit limit. Values that have been truncated have the "trunc"
 *   prefix. We truncate both token amounts (by numAtomsTruncBytes bytes) and
 *   sats amounts (by numSatsTruncBytes).
 *
 * Scaling and truncation can be combined, such that the token price is in
 * "scaledTruncAtomsPerTruncSat".
 * Together, they give us a very large range of representable values, while
 * keeping a decent precision.
 *
 * Ideally, eCash can eventually raise the maximum integer size to e.g. 64-bits,
 * which would greatly increase the precision. The strategies employed are
 * useful there too, we simply get a much more accurate price calculation.
 **/
export declare class AgoraPartial {
    static COVENANT_VARIANT: string;
    /**
     * Truncated amount that's offered.
     * The last numAtomsTruncBytes bytes are truncated to allow representing it
     * in Script or to increase precision.
     * This means that tokens can only be accepted at a granularity of
     * 2^(8*numAtomsTruncBytes).
     * offeredAtoms = truncAtoms * 2^(8*numAtomsTruncBytes).
     **/
    truncAtoms: bigint;
    /**
     * How many bytes are truncated from the real token amount, so it fits into
     * 31-bit ints, or to increase precision.
     **/
    numAtomsTruncBytes: number;
    /**
     * Factor token amounts will be multiplied with in the Script to improve
     * precision.
     **/
    atomsScaleFactor: bigint;
    /**
     * Price in scaled trunc tokens per truncated sat.
     * This unit may seem a bit bizzare, but it is exactly what is needed in the
     * Script calculation: The "acceptedAtoms" coming from the taker is both
     * scaled by atomsScaleFactor and also truncated by numAtomsTruncBytes
     * bytes, so we only have to divide the acceptedAtoms by this number to get
     * the required (truncated) sats. So we only have to un-truncate that and we
     * have the asked sats.
     **/
    scaledTruncAtomsPerTruncSat: bigint;
    /**
     * How many bytes are truncated from the real sats amount, so it fits into
     * 31-bit ints or to improve precision.
     **/
    numSatsTruncBytes: number;
    /**
     * Where the sats for the tokens should go, and who can cancel the trade.
     **/
    makerPk: Uint8Array;
    /**
     * How many tokens (scaled and truncated) at minimum have to be accepted.
     **/
    minAcceptedScaledTruncAtoms: bigint;
    /** Token of the contract, in big-endian hex. */
    tokenId: string;
    /** Token type offered */
    tokenType: number;
    /** Token protocol of the offered token */
    tokenProtocol: 'SLP' | 'ALP';
    /** Byte length of the Script, after OP_CODESEPARATOR. */
    scriptLen: number;
    /**
     * Locktime enforced by the Script. Used to make identical offers unique.
     *
     * Use Agora.selectParams to automatically select a good value for this,
     * only set this manually if you know what you're doing.
     *
     * If there's two offers with identical terms, it would be possible to burn
     * one of them by accepting both in one transaction.
     * To prevent this for identical offers, set to unique (past) locktimes.
     **/
    enforcedLockTime: number;
    /**
     * Dust amount of the network, the Script will enforce token outputs to have
     * this amount.
     **/
    dustSats: bigint;
    constructor(params: {
        truncAtoms: bigint;
        numAtomsTruncBytes: number;
        atomsScaleFactor: bigint;
        scaledTruncAtomsPerTruncSat: bigint;
        numSatsTruncBytes: number;
        makerPk: Uint8Array;
        minAcceptedScaledTruncAtoms: bigint;
        tokenId: string;
        tokenType: number;
        tokenProtocol: 'SLP' | 'ALP';
        scriptLen: number;
        enforcedLockTime: number;
        dustSats: bigint;
    });
    /**
     * Approximate good script parameters for the given offer params.
     * Note: This is not guaranteed to be optimal and is done on a best-effort
     * basis.
     * @param params Offer params to approximate, see AgoraPartialParams for
     *        details.
     * @param scriptIntegerBits How many bits Script integers have on the
     *        network. On XEC, this must be 32, but if it is raised in the
     *        future to e.g. 64-bit integers, this can be set to 64 to greatly
     *        increase accuracy.
     **/
    static approximateParams(params: AgoraPartialParams, scriptIntegerBits?: bigint): AgoraPartial;
    updateScriptLen(): void;
    /**
     * How many tokens are accually offered by the Script.
     * This may differ from the offeredAtoms in the AgoraPartialParams used to
     * approximate this AgoraPartial.
     **/
    offeredAtoms(): bigint;
    /**
     * Actual minimum acceptable tokens of this Script.
     * This may differ from the minAcceptedAtoms in the AgoraPartialParams used
     * to approximate this AgoraPartial.
     **/
    minAcceptedAtoms(): bigint;
    /**
     * Calculate the actually asked satoshi amount for the given accepted number of tokens.
     * This is the exact amount that has to be sent to makerPk's P2PKH address
     * to accept the offer.
     * `acceptedAtoms` must have the lowest numAtomsTruncBytes bytes set to 0,
     * use prepareAcceptedAtoms to do so.
     **/
    askedSats(acceptedAtoms: bigint): bigint;
    /**
     * Throw an error if accept amount is invalid
     * Note we do not prepare amounts in this function
     * @param acceptedAtoms
     */
    preventUnacceptableRemainder(acceptedAtoms: bigint): void;
    /**
     * Prepare the given acceptedAtoms amount for the Script; `acceptedAtoms`
     * must have the lowest numAtomsTruncBytes bytes set to 0 and this function
     * does this for us.
     **/
    prepareAcceptedAtoms(acceptedAtoms: bigint): bigint;
    /**
     * Calculate the actual priceNanoSatsPerAtom of this offer, factoring in
     * all approximation inacurracies.
     * Due to the rounding, the price can change based on the accepted token
     * amount. By default it calculates the price per token for accepting the
     * entire offer.
     **/
    priceNanoSatsPerAtom(acceptedAtoms?: bigint): bigint;
    adPushdata(): Uint8Array;
    covenantConsts(): [Uint8Array, number];
    script(): Script;
    private _scriptBuildOpReturn;
    private _scriptBuildSlpOpReturn;
    private _scriptBuildAlpOpReturn;
    private _scriptSerTruncAtoms;
    private _scriptOutro;
    /**
     * redeemScript of the Script advertizing this offer.
     * It requires a setup tx followed by the actual offer, which reveals
     * the covenantConsts.
     * The reason we have an OP_CHECKSIGVERIFY (as opposed to just leaving it
     * as "anyone can spend with this pushdata") is so that others on the
     * network can't spend this UTXO (and potentially take the tokens in it),
     * and only the maker can spend it.
     **/
    adScript(): Script;
}
export declare const AgoraPartialSignatory: (params: AgoraPartial, acceptedTruncAtoms: bigint, covenantSk: Uint8Array, covenantPk: Uint8Array) => Signatory;
export declare const AgoraPartialCancelSignatory: (makerSk: Uint8Array, tokenProtocol: 'SLP' | 'ALP') => Signatory;
export declare const AgoraPartialAdSignatory: (makerSk: Uint8Array) => (ecc: Ecc, input: UnsignedTxInput) => Script;
//# sourceMappingURL=partial.d.ts.map