diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 0f3d4b6b..bc84c8ef 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -196,6 +196,13 @@ class database_api_impl : public std::enable_shared_from_this nft_object nft_token_by_index(const nft_metadata_id_type nft_metadata_id, const uint64_t token_idx) const; nft_object nft_token_of_owner_by_index(const nft_metadata_id_type nft_metadata_id, const account_id_type owner, const uint64_t token_idx) const; + // Marketplace + vector list_offers(uint32_t limit) const; + vector list_sell_offers(uint32_t limit) const; + vector list_buy_offers(uint32_t limit) const; + vector get_offers_by_issuer(const account_id_type issuer_account_id, uint32_t limit) const; + vector get_offers_by_item(nft_id_type item, uint32_t limit)const; + //private: const account_object* get_account_from_string( const std::string& name_or_id, bool throw_if_not_found = true ) const; @@ -2481,6 +2488,128 @@ nft_object database_api_impl::nft_token_of_owner_by_index(const nft_metadata_id_ return {}; } +// Marketplace +vector database_api::list_offers(uint32_t limit) const +{ + return my->list_offers(limit); +} + +vector database_api_impl::list_offers(uint32_t limit) const +{ + FC_ASSERT( limit <= 100 ); + const auto& offers_idx = _db.get_index_type().indices().get(); + vector result; + result.reserve(limit); + + auto itr = offers_idx.begin(); + + while(limit-- && itr != offers_idx.end()) + result.emplace_back(*itr++); + + return result; +} + +vector database_api::list_sell_offers(uint32_t limit) const +{ + return my->list_sell_offers(limit); +} + +vector database_api_impl::list_sell_offers(uint32_t limit) const +{ + FC_ASSERT( limit <= 100 ); + const auto& offers_idx = _db.get_index_type().indices().get(); + vector result; + result.reserve(limit); + + auto itr = offers_idx.begin(); + + while(limit && itr != offers_idx.end()) + { + if(itr->buying_item == false) + { + result.emplace_back(*itr); + limit--; + } + itr++; + } + return result; +} + +vector database_api::list_buy_offers(uint32_t limit) const +{ + return my->list_buy_offers(limit); +} + +vector database_api_impl::list_buy_offers(uint32_t limit) const +{ + FC_ASSERT( limit <= 100 ); + const auto& offers_idx = _db.get_index_type().indices().get(); + vector result; + result.reserve(limit); + + auto itr = offers_idx.begin(); + + while(limit && itr != offers_idx.end()) + { + if(itr->buying_item == true) + { + result.emplace_back(*itr); + limit--; + } + itr++; + } + + return result; +} +vector database_api::get_offers_by_issuer(const account_id_type issuer_account_id, uint32_t limit) const +{ + return my->get_offers_by_issuer(issuer_account_id, limit); +} + +vector database_api_impl::get_offers_by_issuer(const account_id_type issuer_account_id, uint32_t limit) const +{ + FC_ASSERT( limit <= 100 ); + const auto& offers_idx = _db.get_index_type().indices().get(); + vector result; + result.reserve(limit); + auto itr = offers_idx.begin(); + while(limit && itr != offers_idx.end()) + { + if(itr->issuer == issuer_account_id) + { + result.emplace_back(*itr); + limit--; + } + itr++; + } + return result; +} + +vector database_api::get_offers_by_item(nft_id_type item, uint32_t limit) const +{ + return my->get_offers_by_item(item, limit); +} + +vector database_api_impl::get_offers_by_item(nft_id_type item, uint32_t limit) const +{ + FC_ASSERT( limit <= 100 ); + const auto& offers_idx = _db.get_index_type().indices().get(); + vector result; + result.reserve(limit); + + auto itr = offers_idx.begin(); + while(limit && itr != offers_idx.end()) + { + if(itr->item_ids.find(item) != itr->item_ids.end()) + { + result.emplace_back(*itr); + limit--; + } + itr++; + } + return result; +} + ////////////////////////////////////////////////////////////////////// // // // Private methods // diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 0082f3bf..19a0ed5e 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -49,6 +49,7 @@ #include #include +#include #include @@ -788,6 +789,15 @@ class database_api */ nft_object nft_token_of_owner_by_index(const nft_metadata_id_type nft_metadata_id, const account_id_type owner, const uint64_t token_idx) const; + ////////////////// + // MARKET PLACE // + ////////////////// + vector list_offers(uint32_t limit) const; + vector list_sell_offers(uint32_t limit) const; + vector list_buy_offers(uint32_t limit) const; + vector get_offers_by_issuer(const account_id_type issuer_account_id, uint32_t limit) const; + vector get_offers_by_item(nft_id_type item, uint32_t limit) const; + private: std::shared_ptr< database_api_impl > my; }; @@ -938,4 +948,10 @@ FC_API(graphene::app::database_api, (nft_token_by_index) (nft_token_of_owner_by_index) + // Marketplace + (list_offers) + (list_sell_offers) + (list_buy_offers) + (get_offers_by_issuer) + (get_offers_by_item) ) diff --git a/libraries/chain/include/graphene/chain/protocol/nft_ops.hpp b/libraries/chain/include/graphene/chain/protocol/nft_ops.hpp index f1893c29..5f495553 100644 --- a/libraries/chain/include/graphene/chain/protocol/nft_ops.hpp +++ b/libraries/chain/include/graphene/chain/protocol/nft_ops.hpp @@ -42,7 +42,7 @@ namespace graphene { namespace chain { account_id_type payer; - optional nft_metadata_id; + nft_metadata_id_type nft_metadata_id; account_id_type owner; account_id_type approved; vector approved_operators; @@ -103,7 +103,7 @@ FC_REFLECT( graphene::chain::nft_set_approval_for_all_operation::fee_parameters_ FC_REFLECT( graphene::chain::nft_metadata_create_operation, (fee) (owner) (name) (symbol) (base_uri) (revenue_partner) (revenue_split) ) FC_REFLECT( graphene::chain::nft_metadata_update_operation, (fee) (owner) (nft_metadata_id) (name) (symbol) (base_uri) (revenue_partner) (revenue_split) ) -FC_REFLECT( graphene::chain::nft_mint_operation, (fee) (nft_metadata_id) (owner) (approved) (approved_operators) (token_uri) ) +FC_REFLECT( graphene::chain::nft_mint_operation, (fee) (payer) (nft_metadata_id) (owner) (approved) (approved_operators) (token_uri) ) FC_REFLECT( graphene::chain::nft_safe_transfer_from_operation, (fee) (operator_) (from) (to) (token_id) (data) ) FC_REFLECT( graphene::chain::nft_approve_operation, (fee) (operator_) (approved) (token_id) ) FC_REFLECT( graphene::chain::nft_set_approval_for_all_operation, (fee) (owner) (operator_) (approved) ) diff --git a/libraries/chain/nft_evaluator.cpp b/libraries/chain/nft_evaluator.cpp index d0bdf000..bef9fa28 100644 --- a/libraries/chain/nft_evaluator.cpp +++ b/libraries/chain/nft_evaluator.cpp @@ -66,7 +66,7 @@ void_result nft_metadata_update_evaluator::do_apply( const nft_metadata_update_o void_result nft_mint_evaluator::do_evaluate( const nft_mint_operation& op ) { try { const auto& idx_nft_md = db().get_index_type().indices().get(); - auto itr_nft_md = idx_nft_md.find(*op.nft_metadata_id); + auto itr_nft_md = idx_nft_md.find(op.nft_metadata_id); FC_ASSERT( itr_nft_md != idx_nft_md.end(), "NFT metadata not found" ); FC_ASSERT( itr_nft_md->owner == op.payer, "Only metadata owner can mint NFT" ); @@ -76,7 +76,7 @@ void_result nft_mint_evaluator::do_evaluate( const nft_mint_operation& op ) object_id_type nft_mint_evaluator::do_apply( const nft_mint_operation& op ) { try { const auto& new_nft_object = db().create( [&]( nft_object& obj ){ - obj.nft_metadata_id = *op.nft_metadata_id; + obj.nft_metadata_id = op.nft_metadata_id; obj.owner = op.owner; obj.approved = op.approved; obj.approved_operators = op.approved_operators; diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 9183ddb0..ae1b3ff5 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -2040,6 +2040,25 @@ class wallet_api */ bool nft_is_approved_for_all(string owner_account_id_or_name, string operator_account_id_or_name) const; + signed_transaction create_offer(set item_ids, + string issuer_accound_id_or_name, + asset minimum_price, + asset maximum_price, + bool buying_item, + time_point_sec offer_expiration_date, + optional memo, + bool broadcast); + signed_transaction create_bid(string bidder_account_id_or_name, + asset bid_price, + offer_id_type offer_id, + bool broadcast); + vector list_offers(uint32_t limit) const; + vector list_sell_offers(uint32_t limit) const; + vector list_buy_offers(uint32_t limit) const; + vector get_offers_by_issuer(string issuer_account_id_or_name, + uint32_t limit) const; + vector get_offers_by_item(nft_id_type item, uint32_t limit) const; + void dbg_make_uia(string creator, string symbol); void dbg_make_mia(string creator, string symbol); void dbg_push_blocks( std::string src_filename, uint32_t count ); @@ -2290,6 +2309,9 @@ FC_API( graphene::wallet::wallet_api, (tournament_leave) (rps_throw) (create_vesting_balance) + (nft_metadata_create) + (nft_metadata_update) + (nft_create) (nft_get_balance) (nft_owner_of) (nft_safe_transfer_from) @@ -2298,6 +2320,13 @@ FC_API( graphene::wallet::wallet_api, (nft_set_approval_for_all) (nft_get_approved) (nft_is_approved_for_all) + (create_offer) + (create_bid) + (list_offers) + (list_sell_offers) + (list_buy_offers) + (get_offers_by_issuer) + (get_offers_by_item) (get_upcoming_tournaments) (get_tournaments) (get_tournaments_by_state) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 5fe247ad..da5f6696 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -6353,6 +6353,81 @@ bool wallet_api::nft_is_approved_for_all(string owner_account_id_or_name, string return my->_remote_db->nft_is_approved_for_all(owner_account.id, operator_account.id); } +signed_transaction wallet_api::create_offer(set item_ids, + string issuer_accound_id_or_name, + asset minimum_price, + asset maximum_price, + bool buying_item, + time_point_sec offer_expiration_date, + optional memo, + bool broadcast) +{ + account_object issuer_account = my->get_account(issuer_accound_id_or_name); + + offer_operation op; + op.item_ids = item_ids; + op.issuer = issuer_account.id; + op.minimum_price = minimum_price; + op.maximum_price = maximum_price; + op.buying_item = buying_item; + op.offer_expiration_date = offer_expiration_date; + op.memo = memo; + + signed_transaction trx; + trx.operations.push_back(op); + my->set_operation_fees( trx, my->_remote_db->get_global_properties().parameters.current_fees ); + trx.validate(); + + return my->sign_transaction( trx, broadcast ); +} + +signed_transaction wallet_api::create_bid(string bidder_account_id_or_name, + asset bid_price, + offer_id_type offer_id, + bool broadcast) +{ + account_object bidder_account = my->get_account(bidder_account_id_or_name); + + bid_operation op; + op.bidder = bidder_account.id; + op.offer_id = offer_id; + op.bid_price = bid_price; + + signed_transaction trx; + trx.operations.push_back(op); + my->set_operation_fees( trx, my->_remote_db->get_global_properties().parameters.current_fees ); + trx.validate(); + + return my->sign_transaction( trx, broadcast ); +} + +vector wallet_api::list_offers(uint32_t limit) const +{ + return my->_remote_db->list_offers(limit); +} + +vector wallet_api::list_sell_offers(uint32_t limit) const +{ + return my->_remote_db->list_sell_offers(limit); +} + +vector wallet_api::list_buy_offers(uint32_t limit) const +{ + return my->_remote_db->list_buy_offers(limit); +} + +vector wallet_api::get_offers_by_issuer(string issuer_account_id_or_name, + uint32_t limit) const +{ + account_object issuer_account = my->get_account(issuer_account_id_or_name); + return my->_remote_db->get_offers_by_issuer(issuer_account.id, limit); +} + +vector wallet_api::get_offers_by_item(nft_id_type item, uint32_t limit) const +{ + return my->_remote_db->get_offers_by_item(item, limit); +} + // default ctor necessary for FC_REFLECT signed_block_with_info::signed_block_with_info() {