rippled
Loading...
Searching...
No Matches
NFTOffers.cpp
1#include <xrpld/rpc/Context.h>
2#include <xrpld/rpc/detail/RPCHelpers.h>
3#include <xrpld/rpc/detail/Tuning.h>
4
5#include <xrpl/json/json_value.h>
6#include <xrpl/ledger/ReadView.h>
7#include <xrpl/ledger/View.h>
8#include <xrpl/protocol/ErrorCodes.h>
9#include <xrpl/protocol/RPCErr.h>
10#include <xrpl/protocol/jss.h>
11#include <xrpl/resource/Fees.h>
12
13namespace ripple {
14
15static void
17 Application const& app,
18 std::shared_ptr<SLE const> const& offer,
19 Json::Value& offers)
20{
21 Json::Value& obj(offers.append(Json::objectValue));
22
23 obj[jss::nft_offer_index] = to_string(offer->key());
24 obj[jss::flags] = (*offer)[sfFlags];
25 obj[jss::owner] = toBase58(offer->getAccountID(sfOwner));
26
27 if (offer->isFieldPresent(sfDestination))
28 obj[jss::destination] = toBase58(offer->getAccountID(sfDestination));
29
30 if (offer->isFieldPresent(sfExpiration))
31 obj[jss::expiration] = offer->getFieldU32(sfExpiration);
32
33 offer->getFieldAmount(sfAmount).setJson(obj[jss::amount]);
34}
35
36// {
37// nft_id: <token hash>
38// ledger_hash : <ledger>
39// ledger_index : <ledger_index>
40// limit: integer // optional
41// marker: opaque // optional, resume previous query
42// }
43static Json::Value
45 RPC::JsonContext& context,
46 uint256 const& nftId,
47 Keylet const& directory)
48{
49 unsigned int limit;
50 if (auto err = readLimitField(limit, RPC::Tuning::nftOffers, context))
51 return *err;
52
54
55 if (auto result = RPC::lookupLedger(ledger, context); !ledger)
56 return result;
57
58 if (!ledger->exists(directory))
60
61 Json::Value result;
62 result[jss::nft_id] = to_string(nftId);
63
64 Json::Value& jsonOffers(result[jss::offers] = Json::arrayValue);
65
67 unsigned int reserve(limit);
68 uint256 startAfter;
69 std::uint64_t startHint = 0;
70
71 if (context.params.isMember(jss::marker))
72 {
73 // We have a start point. Use limit - 1 from the result and use the
74 // very last one for the resume.
75 Json::Value const& marker(context.params[jss::marker]);
76
77 if (!marker.isString())
78 return RPC::expected_field_error(jss::marker, "string");
79
80 if (!startAfter.parseHex(marker.asString()))
82
83 auto const sle = ledger->read(keylet::nftoffer(startAfter));
84
85 if (!sle || nftId != sle->getFieldH256(sfNFTokenID))
87
88 startHint = sle->getFieldU64(sfNFTokenOfferNode);
89 appendNftOfferJson(context.app, sle, jsonOffers);
90 offers.reserve(reserve);
91 }
92 else
93 {
94 // We have no start point, limit should be one higher than requested.
95 offers.reserve(++reserve);
96 }
97
99 *ledger,
100 directory,
101 startAfter,
102 startHint,
103 reserve,
104 [&offers](std::shared_ptr<SLE const> const& offer) {
105 if (offer->getType() == ltNFTOKEN_OFFER)
106 {
107 offers.emplace_back(offer);
108 return true;
109 }
110
111 return false;
112 }))
113 {
115 }
116
117 if (offers.size() == reserve)
118 {
119 result[jss::limit] = limit;
120 result[jss::marker] = to_string(offers.back()->key());
121 offers.pop_back();
122 }
123
124 for (auto const& offer : offers)
125 appendNftOfferJson(context.app, offer, jsonOffers);
126
128 return result;
129}
130
133{
134 if (!context.params.isMember(jss::nft_id))
135 return RPC::missing_field_error(jss::nft_id);
136
137 uint256 nftId;
138
139 if (!nftId.parseHex(context.params[jss::nft_id].asString()))
140 return RPC::invalid_field_error(jss::nft_id);
141
142 return enumerateNFTOffers(context, nftId, keylet::nft_sells(nftId));
143}
144
147{
148 if (!context.params.isMember(jss::nft_id))
149 return RPC::missing_field_error(jss::nft_id);
150
151 uint256 nftId;
152
153 if (!nftId.parseHex(context.params[jss::nft_id].asString()))
154 return RPC::invalid_field_error(jss::nft_id);
155
156 return enumerateNFTOffers(context, nftId, keylet::nft_buys(nftId));
157}
158
159} // namespace ripple
Represents a JSON value.
Definition json_value.h:131
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:484
@ arrayValue
array value (ordered list)
Definition json_value.h:26
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:27
static LimitRange constexpr nftOffers
Limits for the nft_buy_offers & nft_sell_offers commands.
Json::Value invalid_field_error(std::string const &name)
Definition ErrorCodes.h:306
Json::Value expected_field_error(std::string const &name, std::string const &type)
Definition ErrorCodes.h:330
Status lookupLedger(std::shared_ptr< ReadView const > &ledger, JsonContext &context, Json::Value &result)
Look up a ledger from a request and fill a Json::Result with the data representing a ledger.
Json::Value missing_field_error(std::string const &name)
Definition ErrorCodes.h:264
Charge const feeMediumBurdenRPC
Keylet nft_buys(uint256 const &id) noexcept
The directory of buy offers for the specified NFT.
Definition Indexes.cpp:415
Keylet nft_sells(uint256 const &id) noexcept
The directory of sell offers for the specified NFT.
Definition Indexes.cpp:421
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition Indexes.cpp:408
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
static Json::Value enumerateNFTOffers(RPC::JsonContext &context, uint256 const &nftId, Keylet const &directory)
Definition NFTOffers.cpp:44
Json::Value doNFTBuyOffers(RPC::JsonContext &)
@ rpcOBJECT_NOT_FOUND
Definition ErrorCodes.h:124
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:65
Json::Value rpcError(int iError)
Definition RPCErr.cpp:12
Json::Value doNFTSellOffers(RPC::JsonContext &)
static void appendNftOfferJson(Application const &app, std::shared_ptr< SLE const > const &offer, Json::Value &offers)
Definition NFTOffers.cpp:16
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.
Definition View.cpp:665
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
uint256 key
Definition Keylet.h:21
Resource::Charge & loadType
Definition Context.h:23
Application & app
Definition Context.h:22