rippled
Loading...
Searching...
No Matches
NFTOffersHelpers.h
1#pragma once
2
3#include <xrpld/rpc/Context.h>
4#include <xrpld/rpc/detail/RPCHelpers.h>
5#include <xrpld/rpc/detail/RPCLedgerHelpers.h>
6#include <xrpld/rpc/detail/Tuning.h>
7
8#include <xrpl/json/json_value.h>
9#include <xrpl/ledger/ReadView.h>
10#include <xrpl/ledger/View.h>
11#include <xrpl/ledger/helpers/DirectoryHelpers.h>
12#include <xrpl/protocol/ErrorCodes.h>
13#include <xrpl/protocol/RPCErr.h>
14#include <xrpl/protocol/jss.h>
15#include <xrpl/resource/Fees.h>
16
17namespace xrpl {
18
19inline void
21 Application const& app,
22 std::shared_ptr<SLE const> const& offer,
23 Json::Value& offers)
24{
25 Json::Value& obj(offers.append(Json::objectValue));
26
27 obj[jss::nft_offer_index] = to_string(offer->key());
28 obj[jss::flags] = (*offer)[sfFlags];
29 obj[jss::owner] = toBase58(offer->getAccountID(sfOwner));
30
31 if (offer->isFieldPresent(sfDestination))
32 obj[jss::destination] = toBase58(offer->getAccountID(sfDestination));
33
34 if (offer->isFieldPresent(sfExpiration))
35 obj[jss::expiration] = offer->getFieldU32(sfExpiration);
36
37 offer->getFieldAmount(sfAmount).setJson(obj[jss::amount]);
38}
39
40// {
41// nft_id: <token hash>
42// ledger_hash : <ledger>
43// ledger_index : <ledger_index>
44// limit: integer // optional
45// marker: opaque // optional, resume previous query
46// }
47inline Json::Value
48enumerateNFTOffers(RPC::JsonContext& context, uint256 const& nftId, Keylet const& directory)
49{
50 unsigned int limit = 0;
51 if (auto err = readLimitField(limit, RPC::Tuning::nftOffers, context))
52 return *err;
53
55
56 if (auto result = RPC::lookupLedger(ledger, context); !ledger)
57 return result;
58
59 if (!ledger->exists(directory))
61
62 Json::Value result;
63 result[jss::nft_id] = to_string(nftId);
64
65 Json::Value& jsonOffers(result[jss::offers] = Json::arrayValue);
66
68 unsigned int reserve(limit);
69 uint256 startAfter;
70 std::uint64_t startHint = 0;
71
72 if (context.params.isMember(jss::marker))
73 {
74 // We have a start point. Use limit - 1 from the result and use the
75 // very last one for the resume.
76 Json::Value const& marker(context.params[jss::marker]);
77
78 if (!marker.isString())
79 return RPC::expected_field_error(jss::marker, "string");
80
81 if (!startAfter.parseHex(marker.asString()))
83
84 auto const sle = ledger->read(keylet::nftoffer(startAfter));
85
86 if (!sle || nftId != sle->getFieldH256(sfNFTokenID))
88
89 startHint = sle->getFieldU64(sfNFTokenOfferNode);
90 appendNftOfferJson(context.app, sle, jsonOffers);
91 offers.reserve(reserve);
92 }
93 else
94 {
95 // We have no start point, limit should be one higher than requested.
96 offers.reserve(++reserve);
97 }
98
100 *ledger,
101 directory,
102 startAfter,
103 startHint,
104 reserve,
105 [&offers](std::shared_ptr<SLE const> const& offer) {
106 if (offer->getType() == ltNFTOKEN_OFFER)
107 {
108 offers.emplace_back(offer);
109 return true;
110 }
111
112 return false;
113 }))
114 {
116 }
117
118 if (offers.size() == reserve)
119 {
120 result[jss::limit] = limit;
121 result[jss::marker] = to_string(offers.back()->key());
122 offers.pop_back();
123 }
124
125 for (auto const& offer : offers)
126 appendNftOfferJson(context.app, offer, jsonOffers);
127
129 return result;
130}
131
132} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
bool isString() const
std::string asString() const
Returns the unquoted string value.
bool isMember(char const *key) const
Return true if the object has a member named key.
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:476
@ arrayValue
array value (ordered list)
Definition json_value.h:25
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
static LimitRange constexpr nftOffers
Limits for the nft_buy_offers & nft_sell_offers commands.
Json::Value expected_field_error(std::string const &name, std::string const &type)
Definition ErrorCodes.h:297
Status lookupLedger(std::shared_ptr< ReadView const > &ledger, JsonContext const &context, Json::Value &result)
Looks up a ledger from a request and fills a Json::Value with ledger data.
Charge const feeMediumBurdenRPC
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition Indexes.cpp:386
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:602
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:92
Json::Value enumerateNFTOffers(RPC::JsonContext &context, uint256 const &nftId, Keylet const &directory)
Json::Value rpcError(error_code_i iError)
Definition RPCErr.cpp:12
bool forEachItemAfter(ReadView const &view, Keylet const &root, uint256 const &after, std::uint64_t const hint, unsigned int limit, std::function< bool(std::shared_ptr< SLE const > const &)> const &f)
Iterate all items after an item in the given directory.
void appendNftOfferJson(Application const &app, std::shared_ptr< SLE const > const &offer, Json::Value &offers)
@ rpcOBJECT_NOT_FOUND
Definition ErrorCodes.h:123
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:64
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:19
uint256 key
Definition Keylet.h:20
Application & app
Definition Context.h:21
Resource::Charge & loadType
Definition Context.h:22
Json::Value params
Definition Context.h:43