#pragma once #include #include namespace xrpl { class PaymentSandbox; class Sandbox; /** Transactor specialized for creating offers in the ledger. */ class OfferCreate : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Custom}; /** Construct a Transactor subclass that creates an offer in the ledger. */ explicit OfferCreate(ApplyContext& ctx) : Transactor(ctx) { } static TxConsequences makeTxConsequences(PreflightContext const& ctx); static bool checkExtraFeatures(PreflightContext const& ctx); static std::uint32_t getFlagsMask(PreflightContext const& ctx); /** Enforce constraints beyond those of the Transactor base class. */ static NotTEC preflight(PreflightContext const& ctx); /** Enforce constraints beyond those of the Transactor base class. */ static TER preclaim(PreclaimContext const& ctx); /** Precondition: fee collection is likely. Attempt to create the offer. */ TER doApply() override; void visitInvariantEntry( bool isDelete, std::shared_ptr const& before, std::shared_ptr const& after) override; [[nodiscard]] bool finalizeInvariants( STTx const& tx, TER result, XRPAmount fee, ReadView const& view, beast::Journal const& j) override; private: std::pair applyGuts(Sandbox& view, Sandbox& view_cancel); // Determine if we are authorized to hold the asset we want to get. static TER checkAcceptAsset( ReadView const& view, ApplyFlags const flags, AccountID const id, beast::Journal const j, Asset const& asset); // Use the payment flow code to perform offer crossing. std::pair flowCross( PaymentSandbox& psb, PaymentSandbox& psbCancel, Amounts const& takerAmount, std::optional const& domainID); static std::string format_amount(STAmount const& amount); TER applyHybrid( Sandbox& sb, std::shared_ptr sleOffer, Keylet const& offer_index, STAmount const& saTakerPays, STAmount const& saTakerGets, std::function)> const& setDir); }; } // namespace xrpl