From 001085ac2c2061cae2d6e5695b5b8b1c6bb65929 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Thu, 2 Jun 2022 11:28:37 +0200 Subject: [PATCH 01/11] add gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e1100e0..ea0405f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /.pytest_cache /.mypy_cache __pycache__ +.idea From 6ba9422809c826af2fc849590be1ee6200a31589 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Thu, 2 Jun 2022 11:29:14 +0200 Subject: [PATCH 02/11] init auction impl --- dipdup.ithacanet.yml | 25 +++++++++ .../handlers/rarible_cancel_auction.py | 11 ++++ .../handlers/rarible_finish_auction.py | 11 ++++ .../handlers/rarible_put_auction_bid.py | 11 ++++ .../handlers/rarible_start_auction.py | 11 ++++ .../types/rarible_auctions/__init__.py | 0 .../rarible_auctions/parameter/__init__.py | 0 .../parameter/cancel_auction.py | 15 ++++++ .../parameter/finish_auction.py | 16 ++++++ .../rarible_auctions/parameter/put_bid.py | 48 +++++++++++++++++ .../parameter/start_auction.py | 54 +++++++++++++++++++ .../types/rarible_auctions/storage.py | 26 +++++++++ 12 files changed, 228 insertions(+) create mode 100644 rarible_marketplace_indexer/handlers/rarible_cancel_auction.py create mode 100644 rarible_marketplace_indexer/handlers/rarible_finish_auction.py create mode 100644 rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py create mode 100644 rarible_marketplace_indexer/handlers/rarible_start_auction.py create mode 100644 rarible_marketplace_indexer/types/rarible_auctions/__init__.py create mode 100644 rarible_marketplace_indexer/types/rarible_auctions/parameter/__init__.py create mode 100644 rarible_marketplace_indexer/types/rarible_auctions/parameter/cancel_auction.py create mode 100644 rarible_marketplace_indexer/types/rarible_auctions/parameter/finish_auction.py create mode 100644 rarible_marketplace_indexer/types/rarible_auctions/parameter/put_bid.py create mode 100644 rarible_marketplace_indexer/types/rarible_auctions/parameter/start_auction.py create mode 100644 rarible_marketplace_indexer/types/rarible_auctions/storage.py diff --git a/dipdup.ithacanet.yml b/dipdup.ithacanet.yml index 8d2ea55..3964fec 100644 --- a/dipdup.ithacanet.yml +++ b/dipdup.ithacanet.yml @@ -10,6 +10,9 @@ contracts: rarible_bids_ithacanet: address: KT1UcBbv2D84mZ9tZx4MVLbCNyC5ihJERED2 typename: rarible_bids + rarible_auctions_ithacanet: + address: KT1CB5JBSC7kTxRV3ir2xsooMA1FLieiD4Mt + typename: rarible_auctions indexes: rarible_exchange_actions: @@ -62,4 +65,26 @@ indexes: pattern: - destination: rarible_bids_ithacanet entrypoint: cancel_floor_bid + rarible_auctions_actions: + kind: operation + datasource: tzkt_ithacanet + contracts: + - rarible_auctions_ithacanet + handlers: + - callback: rarible_start_auction + pattern: + - destination: rarible_auctions_ithacanet + entrypoint: start_auction + - callback: rarible_put_auction_bid + pattern: + - destination: rarible_auctions_ithacanet + entrypoint: put_bid + - callback: rarible_finish_auction + pattern: + - destination: rarible_auctions_ithacanet + entrypoint: finish_auction + - callback: rarible_cancel_auction + pattern: + - destination: rarible_auctions_ithacanet + entrypoint: cancel_auction diff --git a/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py b/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py new file mode 100644 index 0000000..cbcdc27 --- /dev/null +++ b/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py @@ -0,0 +1,11 @@ + +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage +from rarible_marketplace_indexer.types.rarible_auctions.parameter.cancel_auction import CancelAuctionParameter +from dipdup.context import HandlerContext +from dipdup.models import Transaction + +async def rarible_cancel_auction( + ctx: HandlerContext, + cancel_auction: Transaction[CancelAuctionParameter, RaribleAuctionsStorage], +) -> None: + ... \ No newline at end of file diff --git a/rarible_marketplace_indexer/handlers/rarible_finish_auction.py b/rarible_marketplace_indexer/handlers/rarible_finish_auction.py new file mode 100644 index 0000000..1c3409d --- /dev/null +++ b/rarible_marketplace_indexer/handlers/rarible_finish_auction.py @@ -0,0 +1,11 @@ + +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage +from dipdup.context import HandlerContext +from rarible_marketplace_indexer.types.rarible_auctions.parameter.finish_auction import FinishAuctionParameter +from dipdup.models import Transaction + +async def rarible_finish_auction( + ctx: HandlerContext, + finish_auction: Transaction[FinishAuctionParameter, RaribleAuctionsStorage], +) -> None: + ... \ No newline at end of file diff --git a/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py b/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py new file mode 100644 index 0000000..257035b --- /dev/null +++ b/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py @@ -0,0 +1,11 @@ + +from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter +from dipdup.context import HandlerContext +from dipdup.models import Transaction +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage + +async def rarible_put_auction_bid( + ctx: HandlerContext, + put_bid: Transaction[PutBidParameter, RaribleAuctionsStorage], +) -> None: + ... \ No newline at end of file diff --git a/rarible_marketplace_indexer/handlers/rarible_start_auction.py b/rarible_marketplace_indexer/handlers/rarible_start_auction.py new file mode 100644 index 0000000..745e1ca --- /dev/null +++ b/rarible_marketplace_indexer/handlers/rarible_start_auction.py @@ -0,0 +1,11 @@ + +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage +from dipdup.context import HandlerContext +from dipdup.models import Transaction +from rarible_marketplace_indexer.types.rarible_auctions.parameter.start_auction import StartAuctionParameter + +async def rarible_start_auction( + ctx: HandlerContext, + start_auction: Transaction[StartAuctionParameter, RaribleAuctionsStorage], +) -> None: + ... \ No newline at end of file diff --git a/rarible_marketplace_indexer/types/rarible_auctions/__init__.py b/rarible_marketplace_indexer/types/rarible_auctions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rarible_marketplace_indexer/types/rarible_auctions/parameter/__init__.py b/rarible_marketplace_indexer/types/rarible_auctions/parameter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rarible_marketplace_indexer/types/rarible_auctions/parameter/cancel_auction.py b/rarible_marketplace_indexer/types/rarible_auctions/parameter/cancel_auction.py new file mode 100644 index 0000000..074ba4d --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_auctions/parameter/cancel_auction.py @@ -0,0 +1,15 @@ +# generated by datamodel-codegen: +# filename: cancel_auction.json + +from __future__ import annotations + +from pydantic import BaseModel +from pydantic import Extra + + +class CancelAuctionParameter(BaseModel): + class Config: + extra = Extra.forbid + + ca_asset_contract: str + ca_asset_id: str diff --git a/rarible_marketplace_indexer/types/rarible_auctions/parameter/finish_auction.py b/rarible_marketplace_indexer/types/rarible_auctions/parameter/finish_auction.py new file mode 100644 index 0000000..3b9b3ff --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_auctions/parameter/finish_auction.py @@ -0,0 +1,16 @@ +# generated by datamodel-codegen: +# filename: finish_auction.json + +from __future__ import annotations + +from pydantic import BaseModel +from pydantic import Extra + + +class FinishAuctionParameter(BaseModel): + class Config: + extra = Extra.forbid + + fa_asset_contract: str + fa_asset_id: str + fa_asset_seller: str diff --git a/rarible_marketplace_indexer/types/rarible_auctions/parameter/put_bid.py b/rarible_marketplace_indexer/types/rarible_auctions/parameter/put_bid.py new file mode 100644 index 0000000..82930a4 --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_auctions/parameter/put_bid.py @@ -0,0 +1,48 @@ +# generated by datamodel-codegen: +# filename: put_bid.json + +from __future__ import annotations + +from typing import List +from typing import Optional + +from pydantic import BaseModel +from pydantic import Extra + + +class BidOriginFee(BaseModel): + class Config: + extra = Extra.forbid + + part_account: str + part_value: str + + +class BidPayout(BaseModel): + class Config: + extra = Extra.forbid + + part_account: str + part_value: str + + +class PbBid(BaseModel): + class Config: + extra = Extra.forbid + + bid_origin_fees: List[BidOriginFee] + bid_payouts: List[BidPayout] + bid_amount: str + bid_bidder: str + bid_data_type: Optional[str] + bid_data: Optional[str] + + +class PutBidParameter(BaseModel): + class Config: + extra = Extra.forbid + + pb_asset_contract: str + pb_asset_id: str + pb_asset_seller: str + pb_bid: PbBid diff --git a/rarible_marketplace_indexer/types/rarible_auctions/parameter/start_auction.py b/rarible_marketplace_indexer/types/rarible_auctions/parameter/start_auction.py new file mode 100644 index 0000000..27269fd --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_auctions/parameter/start_auction.py @@ -0,0 +1,54 @@ +# generated by datamodel-codegen: +# filename: start_auction.json + +from __future__ import annotations + +from typing import List +from typing import Optional + +from pydantic import BaseModel +from pydantic import Extra + + +class AuctionArgsOriginFee(BaseModel): + class Config: + extra = Extra.forbid + + part_account: str + part_value: str + + +class AuctionArgsPayout(BaseModel): + class Config: + extra = Extra.forbid + + part_account: str + part_value: str + + +class SaAuction(BaseModel): + class Config: + extra = Extra.forbid + + auction_args_sell_asset_amount: str + auction_args_buy_asset_type: str + auction_args_buy_asset: str + auction_args_start_time: Optional[str] + auction_args_duration: str + auction_args_minimal_price: str + auction_args_buy_out_price: str + auction_args_minimal_step: str + auction_args_max_seller_fees: str + auction_args_origin_fees: List[AuctionArgsOriginFee] + auction_args_payouts: List[AuctionArgsPayout] + auction_args_data_type: Optional[str] + auction_args_data: Optional[str] + + +class StartAuctionParameter(BaseModel): + class Config: + extra = Extra.forbid + + sa_asset_contract: str + sa_asset_token_id: str + sa_auction: SaAuction diff --git a/rarible_marketplace_indexer/types/rarible_auctions/storage.py b/rarible_marketplace_indexer/types/rarible_auctions/storage.py new file mode 100644 index 0000000..d190015 --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_auctions/storage.py @@ -0,0 +1,26 @@ +# generated by datamodel-codegen: +# filename: storage.json + +from __future__ import annotations + +from typing import Dict +from typing import Optional + +from pydantic import BaseModel +from pydantic import Extra + + +class RaribleAuctionsStorage(BaseModel): + class Config: + extra = Extra.forbid + + owner: str + protocol_fee: str + transfer_manager: str + auction_storage: str + owner_candidate: Optional[str] + max_bundle_items: str + max_fees_limit: str + extension_duration: str + max_duration: str + metadata: Dict[str, str] From f23a70b7f0afc953e41fba505d4aabb774015948 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Thu, 2 Jun 2022 22:31:16 +0200 Subject: [PATCH 03/11] add indexing of start auction --- .../event/abstract_action.py | 93 +++++++++++++- rarible_marketplace_indexer/event/dto.py | 22 ++++ .../event/rarible_action.py | 60 +++++++++- .../handlers/rarible_cancel_auction.py | 9 +- .../handlers/rarible_finish_auction.py | 9 +- .../handlers/rarible_put_auction_bid.py | 7 +- .../handlers/rarible_start_auction.py | 8 +- rarible_marketplace_indexer/models.py | 113 ++++++++++++++++++ .../types/rarible_api_objects/asset/asset.py | 4 +- .../rarible_api_objects/asset/asset_type.py | 3 +- 10 files changed, 308 insertions(+), 20 deletions(-) diff --git a/rarible_marketplace_indexer/event/abstract_action.py b/rarible_marketplace_indexer/event/abstract_action.py index 73a1553..acc0ff6 100644 --- a/rarible_marketplace_indexer/event/abstract_action.py +++ b/rarible_marketplace_indexer/event/abstract_action.py @@ -1,17 +1,19 @@ from abc import ABC from abc import abstractmethod +from datetime import timedelta from typing import final from dipdup.datasources.tzkt.datasource import TzktDatasource from dipdup.models import Transaction -from rarible_marketplace_indexer.event.dto import CancelDto +from rarible_marketplace_indexer.event.dto import CancelDto, StartAuctionDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MatchDto -from rarible_marketplace_indexer.models import ActivityModel +from rarible_marketplace_indexer.models import ActivityModel, AuctionModel, AuctionStatusEnum, AuctionActivityModel from rarible_marketplace_indexer.models import ActivityTypeEnum from rarible_marketplace_indexer.models import OrderModel from rarible_marketplace_indexer.models import OrderStatusEnum +from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum from rarible_marketplace_indexer.types.tezos_objects.asset_value.asset_value import AssetValue @@ -556,3 +558,90 @@ async def handle( order.last_updated_at = transaction.data.timestamp await order.save() + +class AbstractStartAuctionEvent(EventInterface): + @staticmethod + @abstractmethod + def _get_start_auction_dto( + transaction: Transaction, + datasource: TzktDatasource, + ) -> StartAuctionDto: + raise NotImplementedError + + @classmethod + @final + async def handle( + cls, + transaction: Transaction, + datasource: TzktDatasource, + ): + dto = cls._get_start_auction_dto(transaction, datasource) + order_status = AuctionStatusEnum.INACTIVE + ongoing = False + if dto.start_at == transaction.data.timestamp: + order_status = AuctionStatusEnum.ACTIVE + ongoing = True + + auction = await AuctionModel.create( + network=datasource.network, + platform=cls.platform, + auction_id=dto.auction_id, + status=order_status, + start_at=dto.start_at, + ended_at=None, + created_at=transaction.data.timestamp, + end_time=dto.start_at+timedelta(seconds=dto.duration), + last_updated_at=transaction.data.timestamp, + ongoing=ongoing, + seller=transaction.data.sender_address, + sell_asset_class=AssetClassEnum.MULTI_TOKEN, + sell_contract=dto.sell_contract, + sell_token_id=dto.sell_token_id, + sell_value=dto.sell_value, + buy_asset_class=AssetClassEnum.FUNGIBLE_TOKEN, + buy_contract=dto.buy_asset.contract, + buy_token_id=dto.buy_asset.token_id, + minimal_step=dto.min_step, + minimal_price=dto.min_price, + duration=dto.duration, + buy_price=dto.buy_price, + max_seller_fees=dto.max_seller_fees, + last_bid_amount=None, + last_bid_bidder=None, + last_bid_date=None + ) + + await AuctionActivityModel.create( + auction_id=auction.id, + type=ActivityTypeEnum.AUCTION_CREATED, + network=datasource.network, + platform=cls.platform, + internal_auction_id=dto.auction_id, + bid_value=None, + bid_bidder=None, + date=transaction.data.timestamp, + last_updated_at=transaction.data.timestamp, + operation_level=transaction.data.level, + operation_timestamp=transaction.data.timestamp, + operation_hash=transaction.data.hash, + operation_counter=transaction.data.counter, + operation_nonce=transaction.data.nonce, + ) + + if ongoing: + await AuctionActivityModel.create( + auction_id=auction.id, + type=ActivityTypeEnum.AUCTION_STARTED, + network=datasource.network, + platform=cls.platform, + internal_auction_id=dto.auction_id, + bid_value=None, + bid_bidder=None, + date=transaction.data.timestamp, + last_updated_at=transaction.data.timestamp, + operation_level=transaction.data.level, + operation_timestamp=transaction.data.timestamp, + operation_hash=transaction.data.hash, + operation_counter=transaction.data.counter, + operation_nonce=transaction.data.nonce, + ) \ No newline at end of file diff --git a/rarible_marketplace_indexer/event/dto.py b/rarible_marketplace_indexer/event/dto.py index 7783a33..beae481 100644 --- a/rarible_marketplace_indexer/event/dto.py +++ b/rarible_marketplace_indexer/event/dto.py @@ -10,6 +10,11 @@ from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OriginatedAccountAddress +@dataclass +class AssetDto: + contract: Optional[OriginatedAccountAddress] + token_id: Optional[int] + @dataclass class MakeDto: asset_class: AssetClassEnum @@ -49,3 +54,20 @@ class MatchDto: token_id: Optional[int] match_amount: Optional[AssetValue] match_timestamp: datetime + + +@dataclass +class StartAuctionDto: + auction_id: str + sell_contract: OriginatedAccountAddress + sell_token_id: int + sell_value: int + buy_asset_type: int + buy_asset: AssetDto + start_at: datetime + duration: int + min_price: int + buy_price: int + min_step: int + max_seller_fees: int + diff --git a/rarible_marketplace_indexer/event/rarible_action.py b/rarible_marketplace_indexer/event/rarible_action.py index 28ddc21..e4638a1 100644 --- a/rarible_marketplace_indexer/event/rarible_action.py +++ b/rarible_marketplace_indexer/event/rarible_action.py @@ -7,7 +7,7 @@ from dipdup.datasources.tzkt.datasource import TzktDatasource from dipdup.models import Transaction -from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent +from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent, AbstractStartAuctionEvent from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptFloorBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractBidCancelEvent from rarible_marketplace_indexer.event.abstract_action import AbstractFloorBidCancelEvent @@ -15,7 +15,7 @@ from rarible_marketplace_indexer.event.abstract_action import AbstractOrderListEvent from rarible_marketplace_indexer.event.abstract_action import AbstractOrderMatchEvent from rarible_marketplace_indexer.event.abstract_action import AbstractPutBidEvent -from rarible_marketplace_indexer.event.dto import CancelDto +from rarible_marketplace_indexer.event.dto import CancelDto, StartAuctionDto, AssetDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MakeDto from rarible_marketplace_indexer.event.dto import MatchDto @@ -23,6 +23,8 @@ from rarible_marketplace_indexer.models import PlatformEnum from rarible_marketplace_indexer.models import TransactionTypeEnum from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.rarible_auctions.parameter.start_auction import StartAuctionParameter +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_bid import CancelBidParameter from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_floor_bid import CancelFloorBidParameter from rarible_marketplace_indexer.types.rarible_bids.parameter.put_bid import AcceptBidParameter @@ -147,6 +149,14 @@ def get_floor_bid_hash( ) -> str: return uuid5(namespace=uuid.NAMESPACE_OID, name=f'{TransactionTypeEnum.FLOOR_BID}-{contract}@{bidder}/{asset_class}-{asset}').hex + @staticmethod + def get_auction_hash( + contract: OriginatedAccountAddress, token_id: int, seller: ImplicitAccountAddress + ) -> str: + return uuid5( + namespace=uuid.NAMESPACE_OID, name=f'{TransactionTypeEnum.AUCTION}-{contract}:{token_id}@{seller}' + ).hex + @classmethod def get_take_dto(cls, sale_type: int, value: int, asset_bytes: Optional[bytes] = None) -> TakeDto: method_name = cls.unpack_map_take.get(sale_type) @@ -161,6 +171,18 @@ def get_make_dto(cls, sale_type: int, value: int, asset_bytes: Optional[bytes] = return make_method(value, asset_bytes) + @classmethod + def get_asset(cls, sale_type: int, asset_bytes: Optional[bytes]) -> AssetDto: + match sale_type: + case "0": + return AssetDto(contract=None, token_id=None); + case "1": + return AssetDto(contract=cls._get_contract(asset_bytes, 7), token_id=None); + case "2": + return AssetDto(contract=cls._get_contract(asset_bytes, 9), token_id=cls._get_token_id(asset_bytes)); + case _: + raise Exception(f"Could not parse asset {asset_bytes} for type {sale_type}"); + class RaribleOrderListEvent(AbstractOrderListEvent): platform = PlatformEnum.RARIBLE @@ -396,3 +418,37 @@ def _get_cancel_floor_bid_dto(transaction: RaribleCancelFloorBidTransaction, dat ) return CancelDto(internal_order_id=internal_order_id) + +class RaribleStartAuctionEvent(AbstractStartAuctionEvent): + platform = PlatformEnum.RARIBLE + RaribleCreateAuctionTransaction = Transaction[StartAuctionParameter, RaribleAuctionsStorage] + + @staticmethod + def _get_start_auction_dto( + transaction: RaribleCreateAuctionTransaction, + datasource: TzktDatasource, + ) -> StartAuctionDto: + auction_id = RaribleAware.get_auction_hash( + contract=OriginatedAccountAddress(transaction.parameter.sa_asset_contract), + token_id=int(transaction.parameter.sa_asset_token_id), + seller=ImplicitAccountAddress(transaction.data.sender_address) + ) + + start = transaction.data.timestamp + if transaction.parameter.sa_auction.auction_args_start_time is not None: + start = transaction.parameter.sa_auction.auction_args_start_time + + return StartAuctionDto( + auction_id=auction_id, + sell_contract=OriginatedAccountAddress(transaction.parameter.sa_asset_contract), + sell_token_id=int(transaction.parameter.sa_asset_token_id), + sell_value=int(transaction.parameter.sa_auction.auction_args_sell_asset_amount), + buy_asset_type=transaction.parameter.sa_auction.auction_args_buy_asset_type, + buy_asset=RaribleAware.get_asset(transaction.parameter.sa_auction.auction_args_buy_asset_type, bytes.fromhex(transaction.parameter.sa_auction.auction_args_buy_asset)), + start_at=start, + duration=transaction.parameter.sa_auction.auction_args_duration, + min_price=transaction.parameter.sa_auction.auction_args_minimal_price, + min_step=transaction.parameter.sa_auction.auction_args_minimal_step, + buy_price=transaction.parameter.sa_auction.auction_args_buy_out_price, + max_seller_fees=transaction.parameter.sa_auction.auction_args_max_seller_fees + ) \ No newline at end of file diff --git a/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py b/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py index cbcdc27..ce5a56c 100644 --- a/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py +++ b/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py @@ -1,11 +1,12 @@ - -from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage -from rarible_marketplace_indexer.types.rarible_auctions.parameter.cancel_auction import CancelAuctionParameter from dipdup.context import HandlerContext from dipdup.models import Transaction +from rarible_marketplace_indexer.types.rarible_auctions.parameter.cancel_auction import CancelAuctionParameter +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage + + async def rarible_cancel_auction( ctx: HandlerContext, cancel_auction: Transaction[CancelAuctionParameter, RaribleAuctionsStorage], ) -> None: - ... \ No newline at end of file + ... diff --git a/rarible_marketplace_indexer/handlers/rarible_finish_auction.py b/rarible_marketplace_indexer/handlers/rarible_finish_auction.py index 1c3409d..8f10964 100644 --- a/rarible_marketplace_indexer/handlers/rarible_finish_auction.py +++ b/rarible_marketplace_indexer/handlers/rarible_finish_auction.py @@ -1,11 +1,12 @@ - -from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage from dipdup.context import HandlerContext -from rarible_marketplace_indexer.types.rarible_auctions.parameter.finish_auction import FinishAuctionParameter from dipdup.models import Transaction +from rarible_marketplace_indexer.types.rarible_auctions.parameter.finish_auction import FinishAuctionParameter +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage + + async def rarible_finish_auction( ctx: HandlerContext, finish_auction: Transaction[FinishAuctionParameter, RaribleAuctionsStorage], ) -> None: - ... \ No newline at end of file + ... diff --git a/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py b/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py index 257035b..107925d 100644 --- a/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py +++ b/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py @@ -1,11 +1,12 @@ - -from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter from dipdup.context import HandlerContext from dipdup.models import Transaction + +from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage + async def rarible_put_auction_bid( ctx: HandlerContext, put_bid: Transaction[PutBidParameter, RaribleAuctionsStorage], ) -> None: - ... \ No newline at end of file + ... diff --git a/rarible_marketplace_indexer/handlers/rarible_start_auction.py b/rarible_marketplace_indexer/handlers/rarible_start_auction.py index 745e1ca..af95b7a 100644 --- a/rarible_marketplace_indexer/handlers/rarible_start_auction.py +++ b/rarible_marketplace_indexer/handlers/rarible_start_auction.py @@ -1,11 +1,13 @@ - -from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage from dipdup.context import HandlerContext from dipdup.models import Transaction + +from rarible_marketplace_indexer.event.rarible_action import RaribleStartAuctionEvent from rarible_marketplace_indexer.types.rarible_auctions.parameter.start_auction import StartAuctionParameter +from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage + async def rarible_start_auction( ctx: HandlerContext, start_auction: Transaction[StartAuctionParameter, RaribleAuctionsStorage], ) -> None: - ... \ No newline at end of file + await RaribleStartAuctionEvent.handle(start_auction, ctx.datasource) diff --git a/rarible_marketplace_indexer/models.py b/rarible_marketplace_indexer/models.py index 1c2f71d..26cd663 100644 --- a/rarible_marketplace_indexer/models.py +++ b/rarible_marketplace_indexer/models.py @@ -26,6 +26,7 @@ class TransactionTypeEnum(str, Enum): SALE: _StrEnumValue = 'SALE' BID: _StrEnumValue = 'BID' FLOOR_BID: _StrEnumValue = 'FLOOR_BID' + AUCTION: _StrEnumValue = 'AUCTION' class OrderStatusEnum(str, Enum): @@ -35,6 +36,11 @@ class OrderStatusEnum(str, Enum): INACTIVE: _StrEnumValue = 'INACTIVE' CANCELLED: _StrEnumValue = 'CANCELLED' +class AuctionStatusEnum(str, Enum): + ACTIVE: _StrEnumValue = 'ACTIVE' + FINISHED: _StrEnumValue = 'FINISHED' + INACTIVE: _StrEnumValue = 'INACTIVE' + CANCELLED: _StrEnumValue = 'CANCELLED' class ActivityTypeEnum(str, Enum): GET_BID: _StrEnumValue = 'GET_BID' @@ -49,6 +55,12 @@ class ActivityTypeEnum(str, Enum): TOKEN_MINT: _StrEnumValue = 'MINT' TOKEN_TRANSFER: _StrEnumValue = 'TRANSFER' TOKEN_BURN: _StrEnumValue = 'BURN' + AUCTION_CREATED: _StrEnumValue = 'AUCTION_CREATED' + AUCTION_STARTED: _StrEnumValue = 'AUCTION_STARTED' + AUCTION_BID: _StrEnumValue = 'AUCTION_BID' + AUCTION_CANCEL: _StrEnumValue = 'AUCTION_CANCEL' + AUCTION_FINISHED: _StrEnumValue = 'AUCTION_FINISHED' + AUCTION_ENDED: _StrEnumValue = 'AUCTION_ENDED' class PlatformEnum(str, Enum): @@ -166,6 +178,107 @@ def get_id(network, platform, internal_order_id, maker, created_at, *args, **kwa return uuid5(namespace=uuid.NAMESPACE_OID, name=oid) +class AuctionModel(Model): + class Meta: + table = 'marketplace_auction' + + _custom_generated_pk = True + + id = fields.UUIDField(pk=True, generated=False, required=True) + network = fields.CharField(max_length=16, index=True) + platform = fields.CharEnumField(PlatformEnum, index=True) + auction_id = fields.CharField(max_length=32, index=True) + status = fields.CharEnumField(AuctionStatusEnum, index=True) + start_at = fields.DatetimeField() + ended_at = fields.DatetimeField(null=True) + created_at = fields.DatetimeField(index=True) + end_time = fields.DatetimeField(index=True, null=True) + last_updated_at = fields.DatetimeField(index=True) + ongoing = fields.BooleanField(default=False) + seller = AccountAddressField() + sell_asset_class = fields.CharEnumField(AssetClassEnum) + sell_contract = AccountAddressField(null=True) + sell_token_id = fields.TextField(null=True) + sell_value = AssetValueField() + buy_asset_class = fields.CharEnumField(AssetClassEnum, null=True) + buy_contract = AccountAddressField(null=True) + buy_token_id = fields.TextField(null=True) + minimal_step = fields.IntField() + minimal_price = fields.IntField() + duration = fields.IntField() + buy_price = fields.IntField() + max_seller_fees = fields.IntField() + last_bid_amount = fields.IntField(null=True) + last_bid_bidder = AccountAddressField(null=True) + last_bid_date = fields.DatetimeField(null=True) + + def __init__(self, **kwargs: Any) -> None: + try: + kwargs['id'] = self.get_id(**kwargs) + except TypeError: + pass + super().__init__(**kwargs) + + @staticmethod + def get_id(network, platform, auction_id, seller, created_at, *args, **kwargs): + assert network + assert platform + assert auction_id + assert seller + assert created_at + + oid = '.'.join(map(str, filter(bool, [network, platform, auction_id, seller, created_at]))) + return uuid5(namespace=uuid.NAMESPACE_OID, name=oid) + +class AuctionActivityModel(Model): + class Meta: + table = 'marketplace_auction_activity' + + _custom_generated_pk = True + + id = fields.UUIDField(pk=True, generated=False, required=True, default=None) + auction_id = fields.UUIDField(required=True, index=True) + type = fields.CharEnumField(ActivityTypeEnum) + network = fields.CharField(max_length=16) + platform = fields.CharEnumField(PlatformEnum) + internal_auction_id = fields.CharField(max_length=32, index=True) + bid_value = fields.IntField(null=True) + bid_bidder = AccountAddressField(null=True) + date = fields.DatetimeField() + last_updated_at = fields.DatetimeField(index=True) + operation_level = fields.IntField() + operation_timestamp = fields.DatetimeField() + operation_hash = OperationHashField() + operation_counter = fields.IntField() + operation_nonce = fields.IntField(null=True) + + def __init__(self, **kwargs: Any) -> None: + try: + kwargs['id'] = self.get_id(**kwargs) + except TypeError: + pass + super().__init__(**kwargs) + + @staticmethod + def get_id(type, operation_hash, operation_counter, operation_nonce, *args, **kwargs): + assert operation_hash + assert operation_counter + + oid = '.'.join(map(str, filter(bool, [type, operation_hash, operation_counter, operation_nonce]))) + return uuid5(namespace=uuid.NAMESPACE_OID, name=oid) + + def apply(self, transaction: Transaction): + new_id = self.get_id(transaction.data.hash, transaction.data.counter, transaction.data.nonce) + activity = self.clone(pk=new_id) + + activity.operation_level = transaction.data.level + activity.operation_timestamp = transaction.data.timestamp + activity.operation_hash = transaction.data.hash + activity.operation_counter = transaction.data.counter + activity.operation_nonce = transaction.data.nonce + + return activity + @post_save(OrderModel) async def signal_order_post_save( sender: OrderModel, diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py index 30f422f..8613ac2 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py @@ -24,7 +24,9 @@ class Config: class TokenAsset(AbstractAsset): - _asset_class: Literal[AssetClassEnum.FUNGIBLE_TOKEN, AssetClassEnum.NON_FUNGIBLE_TOKEN, AssetClassEnum.MULTI_TOKEN, AssetClassEnum.COLLECTION] = None + _asset_class: Literal[ + AssetClassEnum.FUNGIBLE_TOKEN, AssetClassEnum.NON_FUNGIBLE_TOKEN, AssetClassEnum.MULTI_TOKEN, AssetClassEnum.COLLECTION + ] = None asset_type: TokenAssetType asset_value: AssetValue diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py index 77ba97d..87a560e 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py @@ -1,5 +1,6 @@ from abc import ABC -from typing import Literal, Optional +from typing import Literal +from typing import Optional from typing import Union from humps.main import camelize From 1899a2229e305f5fce97eaaaaef4ba0ebcffca41 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Thu, 2 Jun 2022 23:12:18 +0200 Subject: [PATCH 04/11] add indexing of put bid --- .../event/abstract_action.py | 71 +++++++++++++++++-- rarible_marketplace_indexer/event/dto.py | 7 ++ .../event/rarible_action.py | 59 ++++++++++----- .../handlers/rarible_put_auction_bid.py | 5 +- rarible_marketplace_indexer/models.py | 4 ++ 5 files changed, 123 insertions(+), 23 deletions(-) diff --git a/rarible_marketplace_indexer/event/abstract_action.py b/rarible_marketplace_indexer/event/abstract_action.py index acc0ff6..6e7b635 100644 --- a/rarible_marketplace_indexer/event/abstract_action.py +++ b/rarible_marketplace_indexer/event/abstract_action.py @@ -6,11 +6,16 @@ from dipdup.datasources.tzkt.datasource import TzktDatasource from dipdup.models import Transaction -from rarible_marketplace_indexer.event.dto import CancelDto, StartAuctionDto +from rarible_marketplace_indexer.event.dto import CancelDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MatchDto -from rarible_marketplace_indexer.models import ActivityModel, AuctionModel, AuctionStatusEnum, AuctionActivityModel +from rarible_marketplace_indexer.event.dto import PutAuctionBidDto +from rarible_marketplace_indexer.event.dto import StartAuctionDto +from rarible_marketplace_indexer.models import ActivityModel from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.models import AuctionModel +from rarible_marketplace_indexer.models import AuctionStatusEnum from rarible_marketplace_indexer.models import OrderModel from rarible_marketplace_indexer.models import OrderStatusEnum from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum @@ -559,6 +564,7 @@ async def handle( await order.save() + class AbstractStartAuctionEvent(EventInterface): @staticmethod @abstractmethod @@ -590,7 +596,7 @@ async def handle( start_at=dto.start_at, ended_at=None, created_at=transaction.data.timestamp, - end_time=dto.start_at+timedelta(seconds=dto.duration), + end_time=dto.start_at + timedelta(seconds=dto.duration), last_updated_at=transaction.data.timestamp, ongoing=ongoing, seller=transaction.data.sender_address, @@ -608,7 +614,7 @@ async def handle( max_seller_fees=dto.max_seller_fees, last_bid_amount=None, last_bid_bidder=None, - last_bid_date=None + last_bid_date=None, ) await AuctionActivityModel.create( @@ -644,4 +650,59 @@ async def handle( operation_hash=transaction.data.hash, operation_counter=transaction.data.counter, operation_nonce=transaction.data.nonce, - ) \ No newline at end of file + ) + + +class AbstractPutAuctionBidEvent(EventInterface): + @staticmethod + @abstractmethod + def _get_put_auction_bid_dto( + transaction: Transaction, + datasource: TzktDatasource, + ) -> PutAuctionBidDto: + raise NotImplementedError + + @classmethod + @final + async def handle( + cls, + transaction: Transaction, + datasource: TzktDatasource, + ): + dto = cls._get_put_auction_bid_dto(transaction, datasource) + + auction = ( + await AuctionModel.filter( + network=datasource.network, + platform=cls.platform, + auction_id=dto.auction_id, + ) + .order_by('-id') + .first() + ) + + auction.last_updated_at = transaction.data.timestamp + auction.last_bid_date = transaction.data.timestamp + auction.last_bid_amount = dto.bid_value + auction.last_bid_bidder = dto.bidder + auction.status = AuctionStatusEnum.ACTIVE + auction.save() + + # TODO: handle buyouts + + await AuctionActivityModel.create( + auction_id=auction.id, + type=ActivityTypeEnum.AUCTION_BID, + network=datasource.network, + platform=cls.platform, + internal_auction_id=dto.auction_id, + bid_value=dto.bid_value, + bid_bidder=dto.bidder, + date=transaction.data.timestamp, + last_updated_at=transaction.data.timestamp, + operation_level=transaction.data.level, + operation_timestamp=transaction.data.timestamp, + operation_hash=transaction.data.hash, + operation_counter=transaction.data.counter, + operation_nonce=transaction.data.nonce, + ) diff --git a/rarible_marketplace_indexer/event/dto.py b/rarible_marketplace_indexer/event/dto.py index beae481..3cf7db1 100644 --- a/rarible_marketplace_indexer/event/dto.py +++ b/rarible_marketplace_indexer/event/dto.py @@ -15,6 +15,7 @@ class AssetDto: contract: Optional[OriginatedAccountAddress] token_id: Optional[int] + @dataclass class MakeDto: asset_class: AssetClassEnum @@ -71,3 +72,9 @@ class StartAuctionDto: min_step: int max_seller_fees: int + +@dataclass +class PutAuctionBidDto: + auction_id: str + bidder: ImplicitAccountAddress + bid_value: Optional[AssetValue] diff --git a/rarible_marketplace_indexer/event/rarible_action.py b/rarible_marketplace_indexer/event/rarible_action.py index e4638a1..12ee121 100644 --- a/rarible_marketplace_indexer/event/rarible_action.py +++ b/rarible_marketplace_indexer/event/rarible_action.py @@ -7,22 +7,29 @@ from dipdup.datasources.tzkt.datasource import TzktDatasource from dipdup.models import Transaction -from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent, AbstractStartAuctionEvent +import rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid +from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptFloorBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractBidCancelEvent from rarible_marketplace_indexer.event.abstract_action import AbstractFloorBidCancelEvent from rarible_marketplace_indexer.event.abstract_action import AbstractOrderCancelEvent from rarible_marketplace_indexer.event.abstract_action import AbstractOrderListEvent from rarible_marketplace_indexer.event.abstract_action import AbstractOrderMatchEvent +from rarible_marketplace_indexer.event.abstract_action import AbstractPutAuctionBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractPutBidEvent -from rarible_marketplace_indexer.event.dto import CancelDto, StartAuctionDto, AssetDto +from rarible_marketplace_indexer.event.abstract_action import AbstractStartAuctionEvent +from rarible_marketplace_indexer.event.dto import AssetDto +from rarible_marketplace_indexer.event.dto import CancelDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MakeDto from rarible_marketplace_indexer.event.dto import MatchDto +from rarible_marketplace_indexer.event.dto import PutAuctionBidDto +from rarible_marketplace_indexer.event.dto import StartAuctionDto from rarible_marketplace_indexer.event.dto import TakeDto from rarible_marketplace_indexer.models import PlatformEnum from rarible_marketplace_indexer.models import TransactionTypeEnum from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter from rarible_marketplace_indexer.types.rarible_auctions.parameter.start_auction import StartAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_bid import CancelBidParameter @@ -150,12 +157,8 @@ def get_floor_bid_hash( return uuid5(namespace=uuid.NAMESPACE_OID, name=f'{TransactionTypeEnum.FLOOR_BID}-{contract}@{bidder}/{asset_class}-{asset}').hex @staticmethod - def get_auction_hash( - contract: OriginatedAccountAddress, token_id: int, seller: ImplicitAccountAddress - ) -> str: - return uuid5( - namespace=uuid.NAMESPACE_OID, name=f'{TransactionTypeEnum.AUCTION}-{contract}:{token_id}@{seller}' - ).hex + def get_auction_hash(contract: OriginatedAccountAddress, token_id: int, seller: ImplicitAccountAddress) -> str: + return uuid5(namespace=uuid.NAMESPACE_OID, name=f'{TransactionTypeEnum.AUCTION}-{contract}:{token_id}@{seller}').hex @classmethod def get_take_dto(cls, sale_type: int, value: int, asset_bytes: Optional[bytes] = None) -> TakeDto: @@ -175,13 +178,13 @@ def get_make_dto(cls, sale_type: int, value: int, asset_bytes: Optional[bytes] = def get_asset(cls, sale_type: int, asset_bytes: Optional[bytes]) -> AssetDto: match sale_type: case "0": - return AssetDto(contract=None, token_id=None); + return AssetDto(contract=None, token_id=None) case "1": - return AssetDto(contract=cls._get_contract(asset_bytes, 7), token_id=None); + return AssetDto(contract=cls._get_contract(asset_bytes, 7), token_id=None) case "2": - return AssetDto(contract=cls._get_contract(asset_bytes, 9), token_id=cls._get_token_id(asset_bytes)); + return AssetDto(contract=cls._get_contract(asset_bytes, 9), token_id=cls._get_token_id(asset_bytes)) case _: - raise Exception(f"Could not parse asset {asset_bytes} for type {sale_type}"); + raise Exception(f"Could not parse asset {asset_bytes} for type {sale_type}") class RaribleOrderListEvent(AbstractOrderListEvent): @@ -419,6 +422,7 @@ def _get_cancel_floor_bid_dto(transaction: RaribleCancelFloorBidTransaction, dat return CancelDto(internal_order_id=internal_order_id) + class RaribleStartAuctionEvent(AbstractStartAuctionEvent): platform = PlatformEnum.RARIBLE RaribleCreateAuctionTransaction = Transaction[StartAuctionParameter, RaribleAuctionsStorage] @@ -431,7 +435,7 @@ def _get_start_auction_dto( auction_id = RaribleAware.get_auction_hash( contract=OriginatedAccountAddress(transaction.parameter.sa_asset_contract), token_id=int(transaction.parameter.sa_asset_token_id), - seller=ImplicitAccountAddress(transaction.data.sender_address) + seller=ImplicitAccountAddress(transaction.data.sender_address), ) start = transaction.data.timestamp @@ -444,11 +448,34 @@ def _get_start_auction_dto( sell_token_id=int(transaction.parameter.sa_asset_token_id), sell_value=int(transaction.parameter.sa_auction.auction_args_sell_asset_amount), buy_asset_type=transaction.parameter.sa_auction.auction_args_buy_asset_type, - buy_asset=RaribleAware.get_asset(transaction.parameter.sa_auction.auction_args_buy_asset_type, bytes.fromhex(transaction.parameter.sa_auction.auction_args_buy_asset)), + buy_asset=RaribleAware.get_asset( + transaction.parameter.sa_auction.auction_args_buy_asset_type, + bytes.fromhex(transaction.parameter.sa_auction.auction_args_buy_asset), + ), start_at=start, duration=transaction.parameter.sa_auction.auction_args_duration, min_price=transaction.parameter.sa_auction.auction_args_minimal_price, min_step=transaction.parameter.sa_auction.auction_args_minimal_step, buy_price=transaction.parameter.sa_auction.auction_args_buy_out_price, - max_seller_fees=transaction.parameter.sa_auction.auction_args_max_seller_fees - ) \ No newline at end of file + max_seller_fees=transaction.parameter.sa_auction.auction_args_max_seller_fees, + ) + + +class RariblePutAuctionBidEvent(AbstractPutAuctionBidEvent): + platform = PlatformEnum.RARIBLE + RariblePutAuctionBidTransaction = Transaction[rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid.PutBidParameter, RaribleAuctionsStorage] + + @staticmethod + def _get_put_auction_bid_dto( + transaction: RariblePutAuctionBidTransaction, + datasource: TzktDatasource, + ) -> PutAuctionBidDto: + auction_id = RaribleAware.get_auction_hash( + contract=OriginatedAccountAddress(transaction.parameter.pb_asset_contract), + token_id=int(transaction.parameter.pb_asset_id), + seller=ImplicitAccountAddress(transaction.parameter.pb_asset_seller), + ) + + return PutAuctionBidDto( + auction_id=auction_id, bidder=transaction.data.sender_address, bid_value=transaction.parameter.pb_bid.bid_amount + ) diff --git a/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py b/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py index 107925d..688a3b9 100644 --- a/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py +++ b/rarible_marketplace_indexer/handlers/rarible_put_auction_bid.py @@ -1,12 +1,13 @@ from dipdup.context import HandlerContext from dipdup.models import Transaction +from rarible_marketplace_indexer.event.rarible_action import RariblePutAuctionBidEvent from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage async def rarible_put_auction_bid( ctx: HandlerContext, - put_bid: Transaction[PutBidParameter, RaribleAuctionsStorage], + put_auction_bid: Transaction[PutBidParameter, RaribleAuctionsStorage], ) -> None: - ... + await RariblePutAuctionBidEvent.handle(put_auction_bid, ctx.datasource) diff --git a/rarible_marketplace_indexer/models.py b/rarible_marketplace_indexer/models.py index 26cd663..83fe1b6 100644 --- a/rarible_marketplace_indexer/models.py +++ b/rarible_marketplace_indexer/models.py @@ -36,12 +36,14 @@ class OrderStatusEnum(str, Enum): INACTIVE: _StrEnumValue = 'INACTIVE' CANCELLED: _StrEnumValue = 'CANCELLED' + class AuctionStatusEnum(str, Enum): ACTIVE: _StrEnumValue = 'ACTIVE' FINISHED: _StrEnumValue = 'FINISHED' INACTIVE: _StrEnumValue = 'INACTIVE' CANCELLED: _StrEnumValue = 'CANCELLED' + class ActivityTypeEnum(str, Enum): GET_BID: _StrEnumValue = 'GET_BID' GET_FLOOR_BID: _StrEnumValue = 'GET_FLOOR_BID' @@ -230,6 +232,7 @@ def get_id(network, platform, auction_id, seller, created_at, *args, **kwargs): oid = '.'.join(map(str, filter(bool, [network, platform, auction_id, seller, created_at]))) return uuid5(namespace=uuid.NAMESPACE_OID, name=oid) + class AuctionActivityModel(Model): class Meta: table = 'marketplace_auction_activity' @@ -279,6 +282,7 @@ def apply(self, transaction: Transaction): return activity + @post_save(OrderModel) async def signal_order_post_save( sender: OrderModel, From 7cea22b7a582e1d03628ae687f179e2ceedff105 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Fri, 3 Jun 2022 09:34:15 +0200 Subject: [PATCH 05/11] add indexing of cancel and finish auction --- .../event/abstract_action.py | 105 +++++++++++++++++- rarible_marketplace_indexer/event/dto.py | 4 + .../event/rarible_action.py | 45 +++++++- .../handlers/rarible_cancel_auction.py | 3 +- .../handlers/rarible_finish_auction.py | 3 +- 5 files changed, 155 insertions(+), 5 deletions(-) diff --git a/rarible_marketplace_indexer/event/abstract_action.py b/rarible_marketplace_indexer/event/abstract_action.py index 6e7b635..353d7e2 100644 --- a/rarible_marketplace_indexer/event/abstract_action.py +++ b/rarible_marketplace_indexer/event/abstract_action.py @@ -6,7 +6,7 @@ from dipdup.datasources.tzkt.datasource import TzktDatasource from dipdup.models import Transaction -from rarible_marketplace_indexer.event.dto import CancelDto +from rarible_marketplace_indexer.event.dto import CancelDto, FinishAuctionDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MatchDto from rarible_marketplace_indexer.event.dto import PutAuctionBidDto @@ -686,6 +686,7 @@ async def handle( auction.last_bid_amount = dto.bid_value auction.last_bid_bidder = dto.bidder auction.status = AuctionStatusEnum.ACTIVE + auction.ongoing = True auction.save() # TODO: handle buyouts @@ -706,3 +707,105 @@ async def handle( operation_counter=transaction.data.counter, operation_nonce=transaction.data.nonce, ) + +class AbstractFinishAuctionEvent(EventInterface): + @staticmethod + @abstractmethod + def _get_finish_auction_dto( + transaction: Transaction, + datasource: TzktDatasource, + ) -> FinishAuctionDto: + raise NotImplementedError + + @classmethod + @final + async def handle( + cls, + transaction: Transaction, + datasource: TzktDatasource, + ): + dto = cls._get_finish_auction_dto(transaction, datasource) + + auction = ( + await AuctionModel.filter( + network=datasource.network, + platform=cls.platform, + auction_id=dto.auction_id, + ) + .order_by('-id') + .first() + ) + + auction.last_updated_at = transaction.data.timestamp + auction.ended_at = transaction.data.timestamp + auction.ongoing = False + auction.status = AuctionStatusEnum.FINISHED + auction.save() + + await AuctionActivityModel.create( + auction_id=auction.id, + type=ActivityTypeEnum.AUCTION_FINISHED, + network=datasource.network, + platform=cls.platform, + internal_auction_id=dto.auction_id, + bid_value=auction.last_bid_amount, + bid_bidder=auction.last_bid_bidder, + date=transaction.data.timestamp, + last_updated_at=transaction.data.timestamp, + operation_level=transaction.data.level, + operation_timestamp=transaction.data.timestamp, + operation_hash=transaction.data.hash, + operation_counter=transaction.data.counter, + operation_nonce=transaction.data.nonce, + ) + +class AbstractCancelAuctionEvent(EventInterface): + @staticmethod + @abstractmethod + def _get_cancel_auction_dto( + transaction: Transaction, + datasource: TzktDatasource, + ) -> FinishAuctionDto: + raise NotImplementedError + + @classmethod + @final + async def handle( + cls, + transaction: Transaction, + datasource: TzktDatasource, + ): + dto = cls._get_cancel_auction_dto(transaction, datasource) + + auction = ( + await AuctionModel.filter( + network=datasource.network, + platform=cls.platform, + auction_id=dto.auction_id, + ) + .order_by('-id') + .first() + ) + + auction.last_updated_at = transaction.data.timestamp + auction.ended_at = transaction.data.timestamp + auction.ongoing = False + auction.status = AuctionStatusEnum.CANCELLED + auction.save() + + await AuctionActivityModel.create( + auction_id=auction.id, + type=ActivityTypeEnum.AUCTION_CANCEL, + network=datasource.network, + platform=cls.platform, + internal_auction_id=dto.auction_id, + bid_value=auction.last_bid_amount, + bid_bidder=auction.last_bid_bidder, + date=transaction.data.timestamp, + last_updated_at=transaction.data.timestamp, + operation_level=transaction.data.level, + operation_timestamp=transaction.data.timestamp, + operation_hash=transaction.data.hash, + operation_counter=transaction.data.counter, + operation_nonce=transaction.data.nonce, + ) diff --git a/rarible_marketplace_indexer/event/dto.py b/rarible_marketplace_indexer/event/dto.py index 3cf7db1..cb678c1 100644 --- a/rarible_marketplace_indexer/event/dto.py +++ b/rarible_marketplace_indexer/event/dto.py @@ -78,3 +78,7 @@ class PutAuctionBidDto: auction_id: str bidder: ImplicitAccountAddress bid_value: Optional[AssetValue] + +@dataclass +class FinishAuctionDto: + auction_id: str \ No newline at end of file diff --git a/rarible_marketplace_indexer/event/rarible_action.py b/rarible_marketplace_indexer/event/rarible_action.py index 12ee121..838f58d 100644 --- a/rarible_marketplace_indexer/event/rarible_action.py +++ b/rarible_marketplace_indexer/event/rarible_action.py @@ -8,7 +8,8 @@ from dipdup.models import Transaction import rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid -from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent +from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent, AbstractFinishAuctionEvent, \ + AbstractCancelAuctionEvent from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptFloorBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractBidCancelEvent from rarible_marketplace_indexer.event.abstract_action import AbstractFloorBidCancelEvent @@ -18,7 +19,7 @@ from rarible_marketplace_indexer.event.abstract_action import AbstractPutAuctionBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractPutBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractStartAuctionEvent -from rarible_marketplace_indexer.event.dto import AssetDto +from rarible_marketplace_indexer.event.dto import AssetDto, FinishAuctionDto from rarible_marketplace_indexer.event.dto import CancelDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MakeDto @@ -29,6 +30,8 @@ from rarible_marketplace_indexer.models import PlatformEnum from rarible_marketplace_indexer.models import TransactionTypeEnum from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.rarible_auctions.parameter.cancel_auction import CancelAuctionParameter +from rarible_marketplace_indexer.types.rarible_auctions.parameter.finish_auction import FinishAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter from rarible_marketplace_indexer.types.rarible_auctions.parameter.start_auction import StartAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage @@ -479,3 +482,41 @@ def _get_put_auction_bid_dto( return PutAuctionBidDto( auction_id=auction_id, bidder=transaction.data.sender_address, bid_value=transaction.parameter.pb_bid.bid_amount ) + +class RaribleFinishAuctionEvent(AbstractFinishAuctionEvent): + platform = PlatformEnum.RARIBLE + RaribleFinishAuctionTransaction = Transaction[FinishAuctionParameter, RaribleAuctionsStorage] + + @staticmethod + def _get_finish_auction_dto( + transaction: RaribleFinishAuctionTransaction, + datasource: TzktDatasource, + ) -> FinishAuctionDto: + auction_id = RaribleAware.get_auction_hash( + contract=OriginatedAccountAddress(transaction.parameter.fa_asset_contract), + token_id=int(transaction.parameter.fa_asset_id), + seller=ImplicitAccountAddress(transaction.parameter.fa_asset_seller), + ) + + return FinishAuctionDto( + auction_id=auction_id + ) + +class RaribleCancelAuctionEvent(AbstractCancelAuctionEvent): + platform = PlatformEnum.RARIBLE + RaribleCancelAuctionTransaction = Transaction[CancelAuctionParameter, RaribleAuctionsStorage] + + @staticmethod + def _get_cancel_auction_dto( + transaction: RaribleCancelAuctionTransaction, + datasource: TzktDatasource, + ) -> FinishAuctionDto: + auction_id = RaribleAware.get_auction_hash( + contract=OriginatedAccountAddress(transaction.parameter.ca_asset_contract), + token_id=int(transaction.parameter.ca_asset_id), + seller=ImplicitAccountAddress(transaction.data.sender_address), + ) + + return FinishAuctionDto( + auction_id=auction_id + ) diff --git a/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py b/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py index ce5a56c..a2dd84c 100644 --- a/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py +++ b/rarible_marketplace_indexer/handlers/rarible_cancel_auction.py @@ -1,6 +1,7 @@ from dipdup.context import HandlerContext from dipdup.models import Transaction +from rarible_marketplace_indexer.event.rarible_action import RaribleCancelAuctionEvent from rarible_marketplace_indexer.types.rarible_auctions.parameter.cancel_auction import CancelAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage @@ -9,4 +10,4 @@ async def rarible_cancel_auction( ctx: HandlerContext, cancel_auction: Transaction[CancelAuctionParameter, RaribleAuctionsStorage], ) -> None: - ... + await RaribleCancelAuctionEvent.handle(cancel_auction, ctx.datasource) diff --git a/rarible_marketplace_indexer/handlers/rarible_finish_auction.py b/rarible_marketplace_indexer/handlers/rarible_finish_auction.py index 8f10964..b1c8905 100644 --- a/rarible_marketplace_indexer/handlers/rarible_finish_auction.py +++ b/rarible_marketplace_indexer/handlers/rarible_finish_auction.py @@ -1,6 +1,7 @@ from dipdup.context import HandlerContext from dipdup.models import Transaction +from rarible_marketplace_indexer.event.rarible_action import RaribleFinishAuctionEvent from rarible_marketplace_indexer.types.rarible_auctions.parameter.finish_auction import FinishAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage @@ -9,4 +10,4 @@ async def rarible_finish_auction( ctx: HandlerContext, finish_auction: Transaction[FinishAuctionParameter, RaribleAuctionsStorage], ) -> None: - ... + await RaribleFinishAuctionEvent.handle(finish_auction, ctx.datasource) From 88d5980a3a7f40ded9949e4a60069a4bccdc001a Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Fri, 3 Jun 2022 11:48:10 +0200 Subject: [PATCH 06/11] add event support for auctions --- .../event/abstract_action.py | 5 +- rarible_marketplace_indexer/event/dto.py | 3 +- .../event/rarible_action.py | 22 +++--- rarible_marketplace_indexer/models.py | 26 ++++++ rarible_marketplace_indexer/producer/const.py | 2 + .../activity/auction/__init__.py | 0 .../activity/auction/activity.py | 44 +++++++++++ .../activity/auction/factory.py | 79 +++++++++++++++++++ .../types/rarible_api_objects/asset/asset.py | 16 ++++ .../asset/asset_description.py | 17 ++++ .../rarible_api_objects/asset/asset_type.py | 2 +- .../rarible_api_objects/auction/__init__.py | 0 .../rarible_api_objects/auction/auction.py | 40 ++++++++++ .../auction/auction_bid.py | 17 ++++ .../rarible_api_objects/auction/factory.py | 38 +++++++++ 15 files changed, 297 insertions(+), 14 deletions(-) create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/__init__.py create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_description.py create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/auction/__init__.py create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/auction/auction.py create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/auction/auction_bid.py create mode 100644 rarible_marketplace_indexer/types/rarible_api_objects/auction/factory.py diff --git a/rarible_marketplace_indexer/event/abstract_action.py b/rarible_marketplace_indexer/event/abstract_action.py index 353d7e2..5323904 100644 --- a/rarible_marketplace_indexer/event/abstract_action.py +++ b/rarible_marketplace_indexer/event/abstract_action.py @@ -6,7 +6,8 @@ from dipdup.datasources.tzkt.datasource import TzktDatasource from dipdup.models import Transaction -from rarible_marketplace_indexer.event.dto import CancelDto, FinishAuctionDto +from rarible_marketplace_indexer.event.dto import CancelDto +from rarible_marketplace_indexer.event.dto import FinishAuctionDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MatchDto from rarible_marketplace_indexer.event.dto import PutAuctionBidDto @@ -708,6 +709,7 @@ async def handle( operation_nonce=transaction.data.nonce, ) + class AbstractFinishAuctionEvent(EventInterface): @staticmethod @abstractmethod @@ -759,6 +761,7 @@ async def handle( operation_nonce=transaction.data.nonce, ) + class AbstractCancelAuctionEvent(EventInterface): @staticmethod @abstractmethod diff --git a/rarible_marketplace_indexer/event/dto.py b/rarible_marketplace_indexer/event/dto.py index cb678c1..8a85650 100644 --- a/rarible_marketplace_indexer/event/dto.py +++ b/rarible_marketplace_indexer/event/dto.py @@ -79,6 +79,7 @@ class PutAuctionBidDto: bidder: ImplicitAccountAddress bid_value: Optional[AssetValue] + @dataclass class FinishAuctionDto: - auction_id: str \ No newline at end of file + auction_id: str diff --git a/rarible_marketplace_indexer/event/rarible_action.py b/rarible_marketplace_indexer/event/rarible_action.py index 838f58d..c6a3b34 100644 --- a/rarible_marketplace_indexer/event/rarible_action.py +++ b/rarible_marketplace_indexer/event/rarible_action.py @@ -8,10 +8,11 @@ from dipdup.models import Transaction import rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid -from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent, AbstractFinishAuctionEvent, \ - AbstractCancelAuctionEvent +from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptFloorBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractBidCancelEvent +from rarible_marketplace_indexer.event.abstract_action import AbstractCancelAuctionEvent +from rarible_marketplace_indexer.event.abstract_action import AbstractFinishAuctionEvent from rarible_marketplace_indexer.event.abstract_action import AbstractFloorBidCancelEvent from rarible_marketplace_indexer.event.abstract_action import AbstractOrderCancelEvent from rarible_marketplace_indexer.event.abstract_action import AbstractOrderListEvent @@ -19,8 +20,9 @@ from rarible_marketplace_indexer.event.abstract_action import AbstractPutAuctionBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractPutBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractStartAuctionEvent -from rarible_marketplace_indexer.event.dto import AssetDto, FinishAuctionDto +from rarible_marketplace_indexer.event.dto import AssetDto from rarible_marketplace_indexer.event.dto import CancelDto +from rarible_marketplace_indexer.event.dto import FinishAuctionDto from rarible_marketplace_indexer.event.dto import ListDto from rarible_marketplace_indexer.event.dto import MakeDto from rarible_marketplace_indexer.event.dto import MatchDto @@ -32,7 +34,7 @@ from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum from rarible_marketplace_indexer.types.rarible_auctions.parameter.cancel_auction import CancelAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.parameter.finish_auction import FinishAuctionParameter -from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter +from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter as PutAuctionBidParameter from rarible_marketplace_indexer.types.rarible_auctions.parameter.start_auction import StartAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_bid import CancelBidParameter @@ -466,7 +468,7 @@ def _get_start_auction_dto( class RariblePutAuctionBidEvent(AbstractPutAuctionBidEvent): platform = PlatformEnum.RARIBLE - RariblePutAuctionBidTransaction = Transaction[rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid.PutBidParameter, RaribleAuctionsStorage] + RariblePutAuctionBidTransaction = Transaction[PutAuctionBidParameter, RaribleAuctionsStorage] @staticmethod def _get_put_auction_bid_dto( @@ -483,6 +485,7 @@ def _get_put_auction_bid_dto( auction_id=auction_id, bidder=transaction.data.sender_address, bid_value=transaction.parameter.pb_bid.bid_amount ) + class RaribleFinishAuctionEvent(AbstractFinishAuctionEvent): platform = PlatformEnum.RARIBLE RaribleFinishAuctionTransaction = Transaction[FinishAuctionParameter, RaribleAuctionsStorage] @@ -498,9 +501,8 @@ def _get_finish_auction_dto( seller=ImplicitAccountAddress(transaction.parameter.fa_asset_seller), ) - return FinishAuctionDto( - auction_id=auction_id - ) + return FinishAuctionDto(auction_id=auction_id) + class RaribleCancelAuctionEvent(AbstractCancelAuctionEvent): platform = PlatformEnum.RARIBLE @@ -517,6 +519,4 @@ def _get_cancel_auction_dto( seller=ImplicitAccountAddress(transaction.data.sender_address), ) - return FinishAuctionDto( - auction_id=auction_id - ) + return FinishAuctionDto(auction_id=auction_id) diff --git a/rarible_marketplace_indexer/models.py b/rarible_marketplace_indexer/models.py index 83fe1b6..113f096 100644 --- a/rarible_marketplace_indexer/models.py +++ b/rarible_marketplace_indexer/models.py @@ -307,3 +307,29 @@ async def signal_activity_post_save( from rarible_marketplace_indexer.types.rarible_api_objects.activity.order.factory import RaribleApiOrderActivityFactory await producer_send(RaribleApiOrderActivityFactory.build(instance)) + + +@post_save(AuctionModel) +async def signal_auction_post_save( + sender: AuctionModel, + instance: AuctionModel, + created: bool, + using_db: "Optional[BaseDBAsyncClient]", + update_fields: List[str], +) -> None: + from rarible_marketplace_indexer.types.rarible_api_objects.auction.factory import RaribleApiAuctionFactory + + await producer_send(RaribleApiAuctionFactory.build(instance)) + + +@post_save(AuctionActivityModel) +async def signal_auction_activity_post_save( + sender: AuctionActivityModel, + instance: AuctionActivityModel, + created: bool, + using_db: "Optional[BaseDBAsyncClient]", + update_fields: List[str], +) -> None: + from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.factory import RaribleApiAuctionActivityFactory + + await producer_send(RaribleApiAuctionActivityFactory.build(instance)) diff --git a/rarible_marketplace_indexer/producer/const.py b/rarible_marketplace_indexer/producer/const.py index ce3e143..bb92b9d 100644 --- a/rarible_marketplace_indexer/producer/const.py +++ b/rarible_marketplace_indexer/producer/const.py @@ -1,3 +1,5 @@ class KafkaTopic: ORDER_TOPIC: str = 'order_topic' ACTIVITY_TOPIC: str = 'activity_topic' + AUCTION_TOPIC: str = 'auction_topic' + AUCTION_ACTIVITY_TOPIC: str = 'auction_activity_topic' diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/__init__.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py new file mode 100644 index 0000000..30c0496 --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py @@ -0,0 +1,44 @@ +import uuid +from datetime import datetime +from typing import Literal +from typing import Union + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.producer.const import KafkaTopic +from rarible_marketplace_indexer.types.rarible_api_objects import AbstractRaribleApiObject +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction_bid import AuctionBid +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + + +class AbstractRaribleApiAuctionActivity(AbstractRaribleApiObject): + _kafka_topic = KafkaTopic.ACTIVITY_TOPIC + type: str + auction_id: uuid.UUID + source: PlatformEnum + hash: OperationHash + date: datetime + last_updated_at: datetime + reverted: bool = False + + +class RaribleApiAuctionStartActivity(AbstractRaribleApiAuctionActivity): + type: Literal[ActivityTypeEnum.AUCTION_STARTED] = ActivityTypeEnum.AUCTION_STARTED + + +class RaribleApiAuctionPutBidActivity(AbstractRaribleApiAuctionActivity): + type: Literal[ActivityTypeEnum.AUCTION_BID] = ActivityTypeEnum.AUCTION_BID + bid: AuctionBid + + +class RaribleApiAuctionCancelActivity(AbstractRaribleApiAuctionActivity): + type: Literal[ActivityTypeEnum.AUCTION_CANCEL] = ActivityTypeEnum.AUCTION_CANCEL + + +class RaribleApiAuctionFinishActivity(AbstractRaribleApiAuctionActivity): + type: Literal[ActivityTypeEnum.AUCTION_FINISHED] = ActivityTypeEnum.AUCTION_FINISHED + + +RaribleApiAuctionActivity = Union[ + RaribleApiAuctionStartActivity, RaribleApiAuctionPutBidActivity, RaribleApiAuctionCancelActivity, RaribleApiAuctionFinishActivity +] diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py new file mode 100644 index 0000000..0c42f1d --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py @@ -0,0 +1,79 @@ +from typing import Callable +from typing import Dict + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionActivity +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionCancelActivity +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionFinishActivity +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionPutBidActivity +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionStartActivity +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction_bid import AuctionBid + + +class RaribleApiAuctionActivityFactory: + @classmethod + def _build_start_auction_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionStartActivity: + return RaribleApiAuctionStartActivity( + id=activity.id, + auction_id=activity.auction_id, + network=activity.network, + source=activity.platform, + hash=activity.operation_hash, + date=activity.operation_timestamp, + last_updated_at=activity.last_updated_at, + ) + + @classmethod + def _build_auction_put_bid_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionPutBidActivity: + return RaribleApiAuctionPutBidActivity( + id=activity.id, + auction_id=activity.auction_id, + network=activity.network, + source=activity.platform, + hash=activity.operation_hash, + date=activity.operation_timestamp, + last_updated_at=activity.last_updated_at, + bid=AuctionBid(buyer=activity.bid_bidder, amount=activity.bid_value, date=activity.date), + ) + + @classmethod + def _build_auction_cancel_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionCancelActivity: + return RaribleApiAuctionCancelActivity( + id=activity.id, + auction_id=activity.auction_id, + network=activity.network, + source=activity.platform, + hash=activity.operation_hash, + date=activity.operation_timestamp, + last_updated_at=activity.last_updated_at, + ) + + @classmethod + def _build_auction_finish_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionFinishActivity: + return RaribleApiAuctionFinishActivity( + id=activity.id, + auction_id=activity.auction_id, + network=activity.network, + source=activity.platform, + hash=activity.operation_hash, + date=activity.operation_timestamp, + last_updated_at=activity.last_updated_at, + ) + + @classmethod + def _get_factory_method(cls, activity: AuctionActivityModel) -> callable: + method_map: Dict[ActivityTypeEnum, Callable[[AuctionActivityModel], callable]] = { + ActivityTypeEnum.AUCTION_STARTED: cls._build_start_auction_activity, + ActivityTypeEnum.AUCTION_BID: cls._build_auction_put_bid_activity, + ActivityTypeEnum.AUCTION_CANCEL: cls._build_auction_cancel_activity, + ActivityTypeEnum.AUCTION_FINISHED: cls._build_auction_finish_activity, + } + + return method_map.get(activity.type, cls._build_start_auction_activity) + + @classmethod + def build(cls, activity: AuctionActivityModel) -> RaribleApiAuctionActivity: + factory_method = cls._get_factory_method(activity) + + return factory_method(activity) diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py index 8613ac2..f7ebfb7 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py @@ -9,6 +9,7 @@ from typing_extensions import Annotated from rarible_marketplace_indexer.models import ActivityModel +from rarible_marketplace_indexer.models import AuctionModel from rarible_marketplace_indexer.models import OrderModel from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_type import TokenAssetType from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_type import XtzAssetType @@ -72,3 +73,18 @@ def take_from_model(cls, model: Union[OrderModel, ActivityModel]) -> Optional[Ab }, ) return asset.__root__ + + @classmethod + def sell_from_auction_model(cls, model: AuctionModel) -> Optional[AbstractAsset]: + asset = parse_obj_as( + cls, + { + 'asset_type': { + 'asset_class': model.sell_asset_class, + 'contract': model.sell_contract, + 'token_id': model.sell_asset_class, + }, + 'asset_value': model.sell_value, + }, + ) + return asset.__root__ diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_description.py b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_description.py new file mode 100644 index 0000000..869164e --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_description.py @@ -0,0 +1,17 @@ +from typing import Optional + +from humps.main import camelize +from pydantic import BaseModel + +from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OriginatedAccountAddress + + +class AssetDescription(BaseModel): + class Config: + alias_generator = camelize + allow_population_by_field_name = True + + type: AssetClassEnum + contract: Optional[OriginatedAccountAddress] + token_id: Optional[str] diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py index 87a560e..e621590 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset_type.py @@ -25,7 +25,7 @@ class XtzAssetType(AbstractAssetType): class AbstractTokenAssetType(AbstractAssetType, ABC): - contract: OriginatedAccountAddress + contract: Optional[OriginatedAccountAddress] token_id: Optional[str] diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/auction/__init__.py b/rarible_marketplace_indexer/types/rarible_api_objects/auction/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/auction/auction.py b/rarible_marketplace_indexer/types/rarible_api_objects/auction/auction.py new file mode 100644 index 0000000..5bb28e8 --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_api_objects/auction/auction.py @@ -0,0 +1,40 @@ +from datetime import datetime +from typing import Optional + +from humps.main import camelize + +from rarible_marketplace_indexer.models import AuctionStatusEnum +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.producer.const import KafkaTopic +from rarible_marketplace_indexer.types.rarible_api_objects import AbstractRaribleApiObject +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset import AbstractAsset +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_description import AssetDescription +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction_bid import AuctionBid +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OriginatedAccountAddress + + +class RaribleApiAuction(AbstractRaribleApiObject): + class Config: + alias_generator = camelize + allow_population_by_field_name = True + use_enum_values = True + + _kafka_topic = KafkaTopic.AUCTION_TOPIC + platform: PlatformEnum + contract: OriginatedAccountAddress + seller: ImplicitAccountAddress + sell: AbstractAsset + buy: AssetDescription + end_time: Optional[datetime] + minimal_step: int + minimal_price: int + created_at: datetime + last_updated_at: datetime + buy_price: int + status: AuctionStatusEnum + ongoing: bool + hash: str + start_at: datetime + auction_id: str + last_bid: Optional[AuctionBid] diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/auction/auction_bid.py b/rarible_marketplace_indexer/types/rarible_api_objects/auction/auction_bid.py new file mode 100644 index 0000000..4562912 --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_api_objects/auction/auction_bid.py @@ -0,0 +1,17 @@ +from datetime import datetime + +from humps.main import camelize +from pydantic import BaseModel + +from rarible_marketplace_indexer.types.tezos_objects.asset_value.asset_value import AssetValue +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress + + +class AuctionBid(BaseModel): + class Config: + alias_generator = camelize + allow_population_by_field_name = True + + buyer: ImplicitAccountAddress + amount: AssetValue + date: datetime diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/auction/factory.py b/rarible_marketplace_indexer/types/rarible_api_objects/auction/factory.py new file mode 100644 index 0000000..ef78768 --- /dev/null +++ b/rarible_marketplace_indexer/types/rarible_api_objects/auction/factory.py @@ -0,0 +1,38 @@ +from rarible_marketplace_indexer.models import AuctionModel +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset import Asset +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_description import AssetDescription +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction import RaribleApiAuction +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction_bid import AuctionBid + + +class RaribleApiAuctionFactory: + @staticmethod + def build(auction: AuctionModel) -> RaribleApiAuction: + last_bid = None + if auction.last_bid_bidder is not None: + last_bid = AuctionBid(buyer=auction.last_bid_bidder, amount=auction.last_bid_amount, date=auction.last_bid_date) + return RaribleApiAuction( + id=auction.id, + platform=auction.platform, + network=auction.network, + contract=auction.sell_contract, + seller=auction.seller, + sell=Asset.sell_from_auction_model(auction), + buy=AssetDescription( + type=auction.buy_asset_class, + contract=auction.buy_contract, + token_id=auction.buy_token_id, + ), + end_time=auction.end_time, + minimal_step=auction.minimal_step, + minimal_price=auction.minimal_price, + created_at=auction.created_at, + last_updated_at=auction.last_updated_at, + buy_price=auction.buy_price, + status=auction.status, + ongoing=auction.ongoing, + hash=auction.auction_id, + start_at=auction.start_at, + auction_id=auction.auction_id, + last_bid=last_bid, + ) From 5d5ff4566457808a384e9197af0f6c600e21895e Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Fri, 3 Jun 2022 11:57:18 +0200 Subject: [PATCH 07/11] add support for buy out bids --- .../event/abstract_action.py | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/rarible_marketplace_indexer/event/abstract_action.py b/rarible_marketplace_indexer/event/abstract_action.py index 5323904..dccae94 100644 --- a/rarible_marketplace_indexer/event/abstract_action.py +++ b/rarible_marketplace_indexer/event/abstract_action.py @@ -686,28 +686,52 @@ async def handle( auction.last_bid_date = transaction.data.timestamp auction.last_bid_amount = dto.bid_value auction.last_bid_bidder = dto.bidder - auction.status = AuctionStatusEnum.ACTIVE - auction.ongoing = True - auction.save() + if dto.bid_value >= auction.buy_price: + auction.status = AuctionStatusEnum.FINISHED + auction.ongoing = False + auction.ended_at = transaction.data.timestamp + auction.save() + + await AuctionActivityModel.create( + auction_id=auction.id, + type=ActivityTypeEnum.AUCTION_FINISHED, + network=datasource.network, + platform=cls.platform, + internal_auction_id=dto.auction_id, + bid_value=dto.bid_value, + bid_bidder=dto.bidder, + date=transaction.data.timestamp, + last_updated_at=transaction.data.timestamp, + operation_level=transaction.data.level, + operation_timestamp=transaction.data.timestamp, + operation_hash=transaction.data.hash, + operation_counter=transaction.data.counter, + operation_nonce=transaction.data.nonce, + ) + else: + auction.status = AuctionStatusEnum.ACTIVE + auction.ongoing = True + auction.save() + + await AuctionActivityModel.create( + auction_id=auction.id, + type=ActivityTypeEnum.AUCTION_BID, + network=datasource.network, + platform=cls.platform, + internal_auction_id=dto.auction_id, + bid_value=dto.bid_value, + bid_bidder=dto.bidder, + date=transaction.data.timestamp, + last_updated_at=transaction.data.timestamp, + operation_level=transaction.data.level, + operation_timestamp=transaction.data.timestamp, + operation_hash=transaction.data.hash, + operation_counter=transaction.data.counter, + operation_nonce=transaction.data.nonce, + ) + - # TODO: handle buyouts - await AuctionActivityModel.create( - auction_id=auction.id, - type=ActivityTypeEnum.AUCTION_BID, - network=datasource.network, - platform=cls.platform, - internal_auction_id=dto.auction_id, - bid_value=dto.bid_value, - bid_bidder=dto.bidder, - date=transaction.data.timestamp, - last_updated_at=transaction.data.timestamp, - operation_level=transaction.data.level, - operation_timestamp=transaction.data.timestamp, - operation_hash=transaction.data.hash, - operation_counter=transaction.data.counter, - operation_nonce=transaction.data.nonce, - ) class AbstractFinishAuctionEvent(EventInterface): From a1d466e131db954c0f0f89246ffcfef8f24f8950 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Fri, 3 Jun 2022 12:03:32 +0200 Subject: [PATCH 08/11] change topic for auction activity --- .../types/rarible_api_objects/activity/auction/activity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py index 30c0496..d3d17ca 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py @@ -12,7 +12,7 @@ class AbstractRaribleApiAuctionActivity(AbstractRaribleApiObject): - _kafka_topic = KafkaTopic.ACTIVITY_TOPIC + _kafka_topic = KafkaTopic.AUCTION_ACTIVITY_TOPIC type: str auction_id: uuid.UUID source: PlatformEnum From 5784e111d292f093af42d1ba12307ae2c9d7d1a7 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Fri, 10 Jun 2022 15:43:11 +0200 Subject: [PATCH 09/11] fix events and add missing envts + tests --- .../event/abstract_action.py | 3 -- rarible_marketplace_indexer/event/dto.py | 1 + .../event/rarible_action.py | 11 +++--- .../activity/auction/activity.py | 15 +++++++- .../activity/auction/factory.py | 34 +++++++++++++++++-- .../activity/order/activity.py | 4 ++- .../activity/order/factory.py | 2 +- tests/models/conftest.py | 25 ++++++++++++++ .../api_object/bid_auction.py | 26 ++++++++++++++ .../api_object/cancel_auction.py | 18 ++++++++++ .../api_object/create_auction.py | 18 ++++++++++ .../api_object/end_auction.py | 18 ++++++++++ .../api_object/finish_auction.py | 18 ++++++++++ .../api_object/start_auction.py | 18 ++++++++++ .../auction_activity/message/bid_auction.json | 16 +++++++++ .../message/cancel_auction.json | 11 ++++++ .../message/create_auction.json | 11 ++++++ .../auction_activity/message/end_auction.json | 11 ++++++ .../message/finish_auction.json | 11 ++++++ .../message/start_auction.json | 11 ++++++ .../auction_activity/model/bid_auction.py | 28 +++++++++++++++ .../auction_activity/model/cancel_auction.py | 26 ++++++++++++++ .../auction_activity/model/create_auction.py | 26 ++++++++++++++ .../auction_activity/model/end_auction.py | 26 ++++++++++++++ .../auction_activity/model/finish_auction.py | 26 ++++++++++++++ .../auction_activity/model/start_auction.py | 26 ++++++++++++++ tests/models/test_auction.py | 19 +++++++++++ tests/models/test_auction_activity.py | 19 +++++++++++ 28 files changed, 463 insertions(+), 15 deletions(-) create mode 100644 tests/models/fixture_data/auction_activity/api_object/bid_auction.py create mode 100644 tests/models/fixture_data/auction_activity/api_object/cancel_auction.py create mode 100644 tests/models/fixture_data/auction_activity/api_object/create_auction.py create mode 100644 tests/models/fixture_data/auction_activity/api_object/end_auction.py create mode 100644 tests/models/fixture_data/auction_activity/api_object/finish_auction.py create mode 100644 tests/models/fixture_data/auction_activity/api_object/start_auction.py create mode 100644 tests/models/fixture_data/auction_activity/message/bid_auction.json create mode 100644 tests/models/fixture_data/auction_activity/message/cancel_auction.json create mode 100644 tests/models/fixture_data/auction_activity/message/create_auction.json create mode 100644 tests/models/fixture_data/auction_activity/message/end_auction.json create mode 100644 tests/models/fixture_data/auction_activity/message/finish_auction.json create mode 100644 tests/models/fixture_data/auction_activity/message/start_auction.json create mode 100644 tests/models/fixture_data/auction_activity/model/bid_auction.py create mode 100644 tests/models/fixture_data/auction_activity/model/cancel_auction.py create mode 100644 tests/models/fixture_data/auction_activity/model/create_auction.py create mode 100644 tests/models/fixture_data/auction_activity/model/end_auction.py create mode 100644 tests/models/fixture_data/auction_activity/model/finish_auction.py create mode 100644 tests/models/fixture_data/auction_activity/model/start_auction.py create mode 100644 tests/models/test_auction.py create mode 100644 tests/models/test_auction_activity.py diff --git a/rarible_marketplace_indexer/event/abstract_action.py b/rarible_marketplace_indexer/event/abstract_action.py index 1f8570f..07997cf 100644 --- a/rarible_marketplace_indexer/event/abstract_action.py +++ b/rarible_marketplace_indexer/event/abstract_action.py @@ -737,9 +737,6 @@ async def handle( ) - - - class AbstractFinishAuctionEvent(EventInterface): @staticmethod @abstractmethod diff --git a/rarible_marketplace_indexer/event/dto.py b/rarible_marketplace_indexer/event/dto.py index 11e94e7..a64f7bf 100644 --- a/rarible_marketplace_indexer/event/dto.py +++ b/rarible_marketplace_indexer/event/dto.py @@ -42,6 +42,7 @@ class ListDto: start_at: Optional[datetime] = None # for marketplaces with the possibility of a delayed start of sales end_at: Optional[datetime] = None # for marketplaces with the possibility of sales expiration + @dataclass class CancelDto: internal_order_id: str diff --git a/rarible_marketplace_indexer/event/rarible_action.py b/rarible_marketplace_indexer/event/rarible_action.py index 14cccb8..ca50858 100644 --- a/rarible_marketplace_indexer/event/rarible_action.py +++ b/rarible_marketplace_indexer/event/rarible_action.py @@ -7,7 +7,6 @@ from dipdup.datasources.tzkt.datasource import TzktDatasource from dipdup.models import Transaction -import rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractAcceptFloorBidEvent from rarible_marketplace_indexer.event.abstract_action import AbstractBidCancelEvent @@ -37,10 +36,10 @@ from rarible_marketplace_indexer.types.rarible_auctions.parameter.put_bid import PutBidParameter as PutAuctionBidParameter from rarible_marketplace_indexer.types.rarible_auctions.parameter.start_auction import StartAuctionParameter from rarible_marketplace_indexer.types.rarible_auctions.storage import RaribleAuctionsStorage -from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_bid import CancelBidParameter -from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_floor_bid import CancelFloorBidParameter from rarible_marketplace_indexer.types.rarible_bids.parameter.accept_bid import AcceptBidParameter from rarible_marketplace_indexer.types.rarible_bids.parameter.accept_floor_bid import AcceptFloorBidParameter +from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_bid import CancelBidParameter +from rarible_marketplace_indexer.types.rarible_bids.parameter.cancel_floor_bid import CancelFloorBidParameter from rarible_marketplace_indexer.types.rarible_bids.parameter.put_bid import PutBidParameter from rarible_marketplace_indexer.types.rarible_bids.parameter.put_floor_bid import PutFloorBidParameter from rarible_marketplace_indexer.types.rarible_bids.storage import RaribleBidsStorage @@ -229,7 +228,7 @@ def _get_list_dto( ), take=take, start_at=transaction.parameter.s_sale.sale_start, - end_at=transaction.parameter.s_sale.sale_end + end_at=transaction.parameter.s_sale.sale_end, ) @@ -311,7 +310,7 @@ def _get_bid_dto( make=make, take=take, start_at=transaction.data.timestamp, - end_at=transaction.parameter.pb_bid.bid_expiry_date + end_at=transaction.parameter.pb_bid.bid_expiry_date, ) @@ -352,7 +351,7 @@ def _get_bid_dto( make=make, take=take, start_at=transaction.data.timestamp, - end_at=transaction.parameter.pfb_bid.bid_expiry_date + end_at=transaction.parameter.pfb_bid.bid_expiry_date, ) diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py index d3d17ca..791d870 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/activity.py @@ -26,6 +26,10 @@ class RaribleApiAuctionStartActivity(AbstractRaribleApiAuctionActivity): type: Literal[ActivityTypeEnum.AUCTION_STARTED] = ActivityTypeEnum.AUCTION_STARTED +class RaribleApiAuctionCreateActivity(AbstractRaribleApiAuctionActivity): + type: Literal[ActivityTypeEnum.AUCTION_CREATED] = ActivityTypeEnum.AUCTION_CREATED + + class RaribleApiAuctionPutBidActivity(AbstractRaribleApiAuctionActivity): type: Literal[ActivityTypeEnum.AUCTION_BID] = ActivityTypeEnum.AUCTION_BID bid: AuctionBid @@ -39,6 +43,15 @@ class RaribleApiAuctionFinishActivity(AbstractRaribleApiAuctionActivity): type: Literal[ActivityTypeEnum.AUCTION_FINISHED] = ActivityTypeEnum.AUCTION_FINISHED +class RaribleApiAuctionEndActivity(AbstractRaribleApiAuctionActivity): + type: Literal[ActivityTypeEnum.AUCTION_ENDED] = ActivityTypeEnum.AUCTION_ENDED + + RaribleApiAuctionActivity = Union[ - RaribleApiAuctionStartActivity, RaribleApiAuctionPutBidActivity, RaribleApiAuctionCancelActivity, RaribleApiAuctionFinishActivity + RaribleApiAuctionStartActivity, + RaribleApiAuctionPutBidActivity, + RaribleApiAuctionCancelActivity, + RaribleApiAuctionFinishActivity, + RaribleApiAuctionCreateActivity, + RaribleApiAuctionEndActivity, ] diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py index 0c42f1d..fffa101 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/activity/auction/factory.py @@ -5,6 +5,8 @@ from rarible_marketplace_indexer.models import AuctionActivityModel from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionActivity from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionCancelActivity +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionCreateActivity +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionEndActivity from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionFinishActivity from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionPutBidActivity from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionStartActivity @@ -13,7 +15,7 @@ class RaribleApiAuctionActivityFactory: @classmethod - def _build_start_auction_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionStartActivity: + def _build_auction_start_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionStartActivity: return RaribleApiAuctionStartActivity( id=activity.id, auction_id=activity.auction_id, @@ -24,6 +26,18 @@ def _build_start_auction_activity(cls, activity: AuctionActivityModel) -> Raribl last_updated_at=activity.last_updated_at, ) + @classmethod + def _build_auction_create_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionCreateActivity: + return RaribleApiAuctionCreateActivity( + id=activity.id, + auction_id=activity.auction_id, + network=activity.network, + source=activity.platform, + hash=activity.operation_hash, + date=activity.operation_timestamp, + last_updated_at=activity.last_updated_at, + ) + @classmethod def _build_auction_put_bid_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionPutBidActivity: return RaribleApiAuctionPutBidActivity( @@ -61,16 +75,30 @@ def _build_auction_finish_activity(cls, activity: AuctionActivityModel) -> Rarib last_updated_at=activity.last_updated_at, ) + @classmethod + def _build_auction_end_activity(cls, activity: AuctionActivityModel) -> RaribleApiAuctionEndActivity: + return RaribleApiAuctionEndActivity( + id=activity.id, + auction_id=activity.auction_id, + network=activity.network, + source=activity.platform, + hash=activity.operation_hash, + date=activity.operation_timestamp, + last_updated_at=activity.last_updated_at, + ) + @classmethod def _get_factory_method(cls, activity: AuctionActivityModel) -> callable: method_map: Dict[ActivityTypeEnum, Callable[[AuctionActivityModel], callable]] = { - ActivityTypeEnum.AUCTION_STARTED: cls._build_start_auction_activity, + ActivityTypeEnum.AUCTION_CREATED: cls._build_auction_create_activity, + ActivityTypeEnum.AUCTION_STARTED: cls._build_auction_start_activity, ActivityTypeEnum.AUCTION_BID: cls._build_auction_put_bid_activity, ActivityTypeEnum.AUCTION_CANCEL: cls._build_auction_cancel_activity, ActivityTypeEnum.AUCTION_FINISHED: cls._build_auction_finish_activity, + ActivityTypeEnum.AUCTION_ENDED: cls._build_auction_end_activity, } - return method_map.get(activity.type, cls._build_start_auction_activity) + return method_map.get(activity.type, cls._build_auction_start_activity) @classmethod def build(cls, activity: AuctionActivityModel) -> RaribleApiAuctionActivity: diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/activity.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/activity.py index 6e94e6a..2f5d841 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/activity.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/activity.py @@ -42,7 +42,9 @@ class RaribleApiOrderMatchActivity(AbstractRaribleApiOrderActivity): class RaribleApiOrderCancelActivity(AbstractRaribleApiOrderActivity): - type: Literal[ActivityTypeEnum.ORDER_CANCEL, ActivityTypeEnum.CANCEL_BID, ActivityTypeEnum.CANCEL_FLOOR_BID] = ActivityTypeEnum.ORDER_CANCEL + type: Literal[ + ActivityTypeEnum.ORDER_CANCEL, ActivityTypeEnum.CANCEL_BID, ActivityTypeEnum.CANCEL_FLOOR_BID + ] = ActivityTypeEnum.ORDER_CANCEL maker: ImplicitAccountAddress make: AbstractAsset take: Optional[AbstractAsset] diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/factory.py b/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/factory.py index d4e1524..d1e1c41 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/factory.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/activity/order/factory.py @@ -72,7 +72,7 @@ def _get_factory_method(cls, activity: ActivityModel) -> callable: ActivityTypeEnum.GET_BID: cls._build_match_activity, ActivityTypeEnum.GET_FLOOR_BID: cls._build_match_activity, ActivityTypeEnum.CANCEL_BID: cls._build_cancel_activity, - ActivityTypeEnum.CANCEL_FLOOR_BID: cls._build_cancel_activity + ActivityTypeEnum.CANCEL_FLOOR_BID: cls._build_cancel_activity, } return method_map.get(activity.type, cls._build_list_activity) diff --git a/tests/models/conftest.py b/tests/models/conftest.py index ad2f287..dd3ea2a 100644 --- a/tests/models/conftest.py +++ b/tests/models/conftest.py @@ -16,7 +16,9 @@ from tortoise.models import Model from rarible_marketplace_indexer.models import ActivityModel +from rarible_marketplace_indexer.models import AuctionActivityModel from rarible_marketplace_indexer.models import OrderModel +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionActivity from rarible_marketplace_indexer.types.rarible_api_objects.activity.order.activity import RaribleApiOrderActivity from rarible_marketplace_indexer.types.rarible_api_objects.order.order import RaribleApiOrder @@ -24,6 +26,8 @@ class TestingSubject: order: str = 'order' activity: str = 'activity' + auction: str = 'auction' + auction_activity: str = 'auction_activity' @dataclass @@ -43,6 +47,16 @@ class TestActivityData(TestModelData): test_api_object: RaribleApiOrderActivity +# class TestAuctionData(TestModelData): +# test_model: Optional[AuctionModel] +# test_api_object: RaribleApiAuction + + +class TestAuctionActivityData(TestModelData): + test_model: Optional[AuctionActivityModel] + test_api_object: RaribleApiAuctionActivity + + def import_object(object_name: str, object_type: str, testcase_name: str): try: test_module = import_module(f'tests.models.fixture_data.{object_name}.{object_type}.{testcase_name}') @@ -58,6 +72,7 @@ def data_loader(object_type: str): fixtures: Dict[str, Type[TestModelData]] = { TestingSubject.order: TestOrderData, TestingSubject.activity: TestActivityData, + TestingSubject.auction_activity: TestAuctionActivityData, } object_dataclass = fixtures[object_type] @@ -96,6 +111,16 @@ def activity_serializer_data_provider(request: SubRequest): return request.param +# @pytest.fixture(params=data_loader(TestingSubject.auction)) +# def auction_data_provider(request: SubRequest): +# return request.param + + +@pytest.fixture(params=data_loader(TestingSubject.auction_activity)) +def auction_activity_data_provider(request: SubRequest): + return request.param + + def compare_kafka_messages(actual: bytes, expected: bytes): assert type(actual) == type(expected) == bytes diff --git a/tests/models/fixture_data/auction_activity/api_object/bid_auction.py b/tests/models/fixture_data/auction_activity/api_object/bid_auction.py new file mode 100644 index 0000000..dd40ee6 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/api_object/bid_auction.py @@ -0,0 +1,26 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionPutBidActivity +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction_bid import AuctionBid +from rarible_marketplace_indexer.types.tezos_objects.asset_value.asset_value import AssetValue +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_api_object = RaribleApiAuctionPutBidActivity( + id=UUID('03fa1145-08fc-58ae-8939-3b4e3b10d465'), + auction_id=UUID('1d1df503-0239-5a74-aae4-b86f375b6695'), + network='ithacanet', + source=PlatformEnum.RARIBLE, + hash=OperationHash('ooQohS1pjNehxAJZFoatr8qCXqNkYWC5ND8f17439PLQv72G4y9'), + date=datetime(2022, 5, 3, 8, 10, 5, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 10, 5, tzinfo=UTC), + bid=AuctionBid( + buyer=ImplicitAccountAddress('tz1U6HmK5feYQ7VzrLdho7u5aRbBssNeMsU9'), + amount=AssetValue(10), + date=datetime(2022, 5, 3, 8, 10, 5, tzinfo=UTC), + ), +) diff --git a/tests/models/fixture_data/auction_activity/api_object/cancel_auction.py b/tests/models/fixture_data/auction_activity/api_object/cancel_auction.py new file mode 100644 index 0000000..8e84d26 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/api_object/cancel_auction.py @@ -0,0 +1,18 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionCancelActivity +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_api_object = RaribleApiAuctionCancelActivity( + id=UUID('417b7587-a82a-5d61-93da-bc37dc717bce'), + auction_id=UUID('36d7c813-9bc6-5352-9ea4-e60c4c5947aa'), + network='ithacanet', + source=PlatformEnum.RARIBLE, + hash=OperationHash('ooSw6k8gJfdowJqHUPBJzS3W8jnkxj8f8sjh8ba4A219soahsjp'), + date=datetime(2022, 5, 3, 9, 10, 0, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 9, 10, 0, tzinfo=UTC), +) diff --git a/tests/models/fixture_data/auction_activity/api_object/create_auction.py b/tests/models/fixture_data/auction_activity/api_object/create_auction.py new file mode 100644 index 0000000..4ffd49a --- /dev/null +++ b/tests/models/fixture_data/auction_activity/api_object/create_auction.py @@ -0,0 +1,18 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionCreateActivity +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_api_object = RaribleApiAuctionCreateActivity( + id=UUID('9bbb97ee-877c-5b64-aa76-33dd730bafeb'), + auction_id=UUID('1d1df503-0239-5a74-aae4-b86f375b6695'), + network='ithacanet', + source=PlatformEnum.RARIBLE, + hash=OperationHash('opFJNJhaEzvzAv3AUHMjUwYAFjNUCGA1rsTHBsh6fcmiZfCXevF'), + date=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), +) diff --git a/tests/models/fixture_data/auction_activity/api_object/end_auction.py b/tests/models/fixture_data/auction_activity/api_object/end_auction.py new file mode 100644 index 0000000..89d1003 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/api_object/end_auction.py @@ -0,0 +1,18 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionEndActivity +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_api_object = RaribleApiAuctionEndActivity( + id=UUID('56381187-6022-5490-893b-8b86501a99b7'), + auction_id=UUID('f5f26042-cf6d-5b1b-9e64-30896b516356'), + network='ithacanet', + source=PlatformEnum.RARIBLE, + hash=OperationHash('opV3Rj694sqZPJboq9PvhJRDdyo8d5MQ3o8k7umeiunehu2tezx'), + date=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), +) diff --git a/tests/models/fixture_data/auction_activity/api_object/finish_auction.py b/tests/models/fixture_data/auction_activity/api_object/finish_auction.py new file mode 100644 index 0000000..b92d506 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/api_object/finish_auction.py @@ -0,0 +1,18 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionFinishActivity +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_api_object = RaribleApiAuctionFinishActivity( + id=UUID('bfd61bb9-5348-5a1c-91a9-9f4d35c2cdf1'), + auction_id=UUID('f5f26042-cf6d-5b1b-9e64-30896b516356'), + network='ithacanet', + source=PlatformEnum.RARIBLE, + hash=OperationHash('opV3Rj694sqZPJboq9PvhJRDdyo8d5MQ3o8k7umeiunehu2tezx'), + date=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), +) diff --git a/tests/models/fixture_data/auction_activity/api_object/start_auction.py b/tests/models/fixture_data/auction_activity/api_object/start_auction.py new file mode 100644 index 0000000..012b1e1 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/api_object/start_auction.py @@ -0,0 +1,18 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionStartActivity +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_api_object = RaribleApiAuctionStartActivity( + id=UUID('e6873f56-efd1-5be4-88de-de9cb2db6434'), + auction_id=UUID('1d1df503-0239-5a74-aae4-b86f375b6695'), + network='ithacanet', + source=PlatformEnum.RARIBLE, + hash=OperationHash('opFJNJhaEzvzAv3AUHMjUwYAFjNUCGA1rsTHBsh6fcmiZfCXevF'), + date=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), +) diff --git a/tests/models/fixture_data/auction_activity/message/bid_auction.json b/tests/models/fixture_data/auction_activity/message/bid_auction.json new file mode 100644 index 0000000..a5966ae --- /dev/null +++ b/tests/models/fixture_data/auction_activity/message/bid_auction.json @@ -0,0 +1,16 @@ +{ + "id": "03fa1145-08fc-58ae-8939-3b4e3b10d465", + "network": "ithacanet", + "type": "AUCTION_BID", + "auctionId": "1d1df503-0239-5a74-aae4-b86f375b6695", + "source": "Rarible", + "hash": "ooQohS1pjNehxAJZFoatr8qCXqNkYWC5ND8f17439PLQv72G4y9", + "date": "2022-05-03T08:10:05+00:00", + "lastUpdatedAt": "2022-05-03T08:10:05+00:00", + "reverted": false, + "bid": { + "buyer": "tz1U6HmK5feYQ7VzrLdho7u5aRbBssNeMsU9", + "amount": "10", + "date": "2022-05-03T08:10:05+00:00" + } +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction_activity/message/cancel_auction.json b/tests/models/fixture_data/auction_activity/message/cancel_auction.json new file mode 100644 index 0000000..8ff7c71 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/message/cancel_auction.json @@ -0,0 +1,11 @@ +{ + "id": "417b7587-a82a-5d61-93da-bc37dc717bce", + "network": "ithacanet", + "type": "AUCTION_CANCEL", + "auctionId": "36d7c813-9bc6-5352-9ea4-e60c4c5947aa", + "source": "Rarible", + "hash": "ooSw6k8gJfdowJqHUPBJzS3W8jnkxj8f8sjh8ba4A219soahsjp", + "date": "2022-05-03T09:10:00+00:00", + "lastUpdatedAt": "2022-05-03T09:10:00+00:00", + "reverted": false +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction_activity/message/create_auction.json b/tests/models/fixture_data/auction_activity/message/create_auction.json new file mode 100644 index 0000000..3a5abc2 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/message/create_auction.json @@ -0,0 +1,11 @@ +{ + "id": "9bbb97ee-877c-5b64-aa76-33dd730bafeb", + "network": "ithacanet", + "type": "AUCTION_CREATED", + "auctionId": "1d1df503-0239-5a74-aae4-b86f375b6695", + "source": "Rarible", + "hash": "opFJNJhaEzvzAv3AUHMjUwYAFjNUCGA1rsTHBsh6fcmiZfCXevF", + "date": "2022-05-03T08:09:00+00:00", + "lastUpdatedAt": "2022-05-03T08:09:00+00:00", + "reverted": false +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction_activity/message/end_auction.json b/tests/models/fixture_data/auction_activity/message/end_auction.json new file mode 100644 index 0000000..64fc383 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/message/end_auction.json @@ -0,0 +1,11 @@ +{ + "id": "56381187-6022-5490-893b-8b86501a99b7", + "network": "ithacanet", + "type": "AUCTION_ENDED", + "auctionId": "f5f26042-cf6d-5b1b-9e64-30896b516356", + "source": "Rarible", + "hash": "opV3Rj694sqZPJboq9PvhJRDdyo8d5MQ3o8k7umeiunehu2tezx", + "date": "2022-05-03T08:32:10+00:00", + "lastUpdatedAt": "2022-05-03T08:32:10+00:00", + "reverted": false +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction_activity/message/finish_auction.json b/tests/models/fixture_data/auction_activity/message/finish_auction.json new file mode 100644 index 0000000..e7dc28b --- /dev/null +++ b/tests/models/fixture_data/auction_activity/message/finish_auction.json @@ -0,0 +1,11 @@ +{ + "id": "bfd61bb9-5348-5a1c-91a9-9f4d35c2cdf1", + "network": "ithacanet", + "type": "AUCTION_FINISHED", + "auctionId": "f5f26042-cf6d-5b1b-9e64-30896b516356", + "source": "Rarible", + "hash": "opV3Rj694sqZPJboq9PvhJRDdyo8d5MQ3o8k7umeiunehu2tezx", + "date": "2022-05-03T08:32:10+00:00", + "lastUpdatedAt": "2022-05-03T08:32:10+00:00", + "reverted": false +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction_activity/message/start_auction.json b/tests/models/fixture_data/auction_activity/message/start_auction.json new file mode 100644 index 0000000..7cd160d --- /dev/null +++ b/tests/models/fixture_data/auction_activity/message/start_auction.json @@ -0,0 +1,11 @@ +{ + "id": "e6873f56-efd1-5be4-88de-de9cb2db6434", + "network": "ithacanet", + "type": "AUCTION_STARTED", + "auctionId": "1d1df503-0239-5a74-aae4-b86f375b6695", + "source": "Rarible", + "hash": "opFJNJhaEzvzAv3AUHMjUwYAFjNUCGA1rsTHBsh6fcmiZfCXevF", + "date": "2022-05-03T08:09:00+00:00", + "lastUpdatedAt": "2022-05-03T08:09:00+00:00", + "reverted": false +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction_activity/model/bid_auction.py b/tests/models/fixture_data/auction_activity/model/bid_auction.py new file mode 100644 index 0000000..4566fe7 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/model/bid_auction.py @@ -0,0 +1,28 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.tezos_objects.asset_value.asset_value import AssetValue +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_model = AuctionActivityModel( + auction_id=UUID('1d1df503-0239-5a74-aae4-b86f375b6695'), + type=ActivityTypeEnum.AUCTION_BID, + network='ithacanet', + platform=PlatformEnum.RARIBLE, + internal_auction_id=123456, + bid_value=AssetValue(10), + bid_bidder=ImplicitAccountAddress('tz1U6HmK5feYQ7VzrLdho7u5aRbBssNeMsU9'), + date=datetime(2022, 5, 3, 8, 10, 5, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 10, 5, tzinfo=UTC), + operation_level=127001, + operation_timestamp=datetime(2022, 5, 3, 8, 10, 5, tzinfo=UTC), + operation_hash=OperationHash('ooQohS1pjNehxAJZFoatr8qCXqNkYWC5ND8f17439PLQv72G4y9'), + operation_counter=30182030, + operation_nonce=1, +) diff --git a/tests/models/fixture_data/auction_activity/model/cancel_auction.py b/tests/models/fixture_data/auction_activity/model/cancel_auction.py new file mode 100644 index 0000000..9817478 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/model/cancel_auction.py @@ -0,0 +1,26 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_model = AuctionActivityModel( + auction_id=UUID('36d7c813-9bc6-5352-9ea4-e60c4c5947aa'), + type=ActivityTypeEnum.AUCTION_CANCEL, + network='ithacanet', + platform=PlatformEnum.RARIBLE, + internal_auction_id=123456, + bid_value=None, + bid_bidder=None, + date=datetime(2022, 5, 3, 9, 10, 0, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 9, 10, 0, tzinfo=UTC), + operation_level=127001, + operation_timestamp=datetime(2022, 5, 3, 9, 10, 0, tzinfo=UTC), + operation_hash=OperationHash('ooSw6k8gJfdowJqHUPBJzS3W8jnkxj8f8sjh8ba4A219soahsjp'), + operation_counter=30182030, + operation_nonce=1, +) diff --git a/tests/models/fixture_data/auction_activity/model/create_auction.py b/tests/models/fixture_data/auction_activity/model/create_auction.py new file mode 100644 index 0000000..8415670 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/model/create_auction.py @@ -0,0 +1,26 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_model = AuctionActivityModel( + auction_id=UUID('1d1df503-0239-5a74-aae4-b86f375b6695'), + type=ActivityTypeEnum.AUCTION_CREATED, + network='ithacanet', + platform=PlatformEnum.RARIBLE, + internal_auction_id=123456, + bid_value=None, + bid_bidder=None, + date=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + operation_level=127001, + operation_timestamp=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + operation_hash=OperationHash('opFJNJhaEzvzAv3AUHMjUwYAFjNUCGA1rsTHBsh6fcmiZfCXevF'), + operation_counter=30182030, + operation_nonce=1, +) diff --git a/tests/models/fixture_data/auction_activity/model/end_auction.py b/tests/models/fixture_data/auction_activity/model/end_auction.py new file mode 100644 index 0000000..466c6db --- /dev/null +++ b/tests/models/fixture_data/auction_activity/model/end_auction.py @@ -0,0 +1,26 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_model = AuctionActivityModel( + auction_id=UUID('f5f26042-cf6d-5b1b-9e64-30896b516356'), + type=ActivityTypeEnum.AUCTION_ENDED, + network='ithacanet', + platform=PlatformEnum.RARIBLE, + internal_auction_id=123456, + bid_value=None, + bid_bidder=None, + date=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + operation_level=127001, + operation_timestamp=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + operation_hash=OperationHash('opV3Rj694sqZPJboq9PvhJRDdyo8d5MQ3o8k7umeiunehu2tezx'), + operation_counter=30182030, + operation_nonce=1, +) diff --git a/tests/models/fixture_data/auction_activity/model/finish_auction.py b/tests/models/fixture_data/auction_activity/model/finish_auction.py new file mode 100644 index 0000000..0cb6e76 --- /dev/null +++ b/tests/models/fixture_data/auction_activity/model/finish_auction.py @@ -0,0 +1,26 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_model = AuctionActivityModel( + auction_id=UUID('f5f26042-cf6d-5b1b-9e64-30896b516356'), + type=ActivityTypeEnum.AUCTION_FINISHED, + network='ithacanet', + platform=PlatformEnum.RARIBLE, + internal_auction_id=123456, + bid_value=None, + bid_bidder=None, + date=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + operation_level=127001, + operation_timestamp=datetime(2022, 5, 3, 8, 32, 10, tzinfo=UTC), + operation_hash=OperationHash('opV3Rj694sqZPJboq9PvhJRDdyo8d5MQ3o8k7umeiunehu2tezx'), + operation_counter=30182030, + operation_nonce=1, +) diff --git a/tests/models/fixture_data/auction_activity/model/start_auction.py b/tests/models/fixture_data/auction_activity/model/start_auction.py new file mode 100644 index 0000000..b8dbc3b --- /dev/null +++ b/tests/models/fixture_data/auction_activity/model/start_auction.py @@ -0,0 +1,26 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import ActivityTypeEnum +from rarible_marketplace_indexer.models import AuctionActivityModel +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OperationHash + +auction_activity_model = AuctionActivityModel( + auction_id=UUID('1d1df503-0239-5a74-aae4-b86f375b6695'), + type=ActivityTypeEnum.AUCTION_STARTED, + network='ithacanet', + platform=PlatformEnum.RARIBLE, + internal_auction_id=123456, + bid_value=None, + bid_bidder=None, + date=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + operation_level=127001, + operation_timestamp=datetime(2022, 5, 3, 8, 9, 0, tzinfo=UTC), + operation_hash=OperationHash('opFJNJhaEzvzAv3AUHMjUwYAFjNUCGA1rsTHBsh6fcmiZfCXevF'), + operation_counter=30182030, + operation_nonce=1, +) diff --git a/tests/models/test_auction.py b/tests/models/test_auction.py new file mode 100644 index 0000000..36a1fae --- /dev/null +++ b/tests/models/test_auction.py @@ -0,0 +1,19 @@ +from rarible_marketplace_indexer.producer.serializer import kafka_value_serializer +from rarible_marketplace_indexer.types.rarible_api_objects.order.factory import RaribleApiOrderFactory +from tests.models.conftest import compare_kafka_messages + + +class TestRaribleApiOrder: + def test_kafka_topic(self, order_data_provider): + order_api_object = RaribleApiOrderFactory.build(order_data_provider.test_model) + assert order_api_object.kafka_topic == 'order_topic_mainnet' + + def test_factory(self, order_data_provider): + order_api_object = RaribleApiOrderFactory.build(order_data_provider.test_model) + expected_object = order_data_provider.test_api_object + assert order_api_object == expected_object + + def test_serializer(self, order_data_provider): + order_message = kafka_value_serializer(order_data_provider.test_api_object, sort_keys=True) + expected_message = order_data_provider.test_message + compare_kafka_messages(order_message, expected_message) diff --git a/tests/models/test_auction_activity.py b/tests/models/test_auction_activity.py new file mode 100644 index 0000000..ab0d6b4 --- /dev/null +++ b/tests/models/test_auction_activity.py @@ -0,0 +1,19 @@ +from rarible_marketplace_indexer.producer.serializer import kafka_value_serializer +from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.factory import RaribleApiAuctionActivityFactory +from tests.models.conftest import compare_kafka_messages + + +class TestRaribleApiAuctionActivity: + def test_kafka_topic(self, auction_activity_data_provider): + auction_activity_api_object = RaribleApiAuctionActivityFactory.build(auction_activity_data_provider.test_model) + assert auction_activity_api_object.kafka_topic == 'auction_activity_topic_ithacanet' + + def test_factory(self, auction_activity_data_provider): + auction_activity_api_object = RaribleApiAuctionActivityFactory.build(auction_activity_data_provider.test_model) + expected_object = auction_activity_data_provider.test_api_object + assert auction_activity_api_object == expected_object + + def test_serializer(self, auction_activity_data_provider): + auction_message = kafka_value_serializer(auction_activity_data_provider.test_api_object, sort_keys=True) + expected_message = auction_activity_data_provider.test_message + compare_kafka_messages(auction_message, expected_message) From 2e5c29558b1034f76f263d3690323c49e5d5a9d3 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Fri, 10 Jun 2022 17:18:50 +0200 Subject: [PATCH 10/11] add tests for auctions --- .../types/rarible_api_objects/asset/asset.py | 2 +- tests/models/conftest.py | 16 +++--- .../auction/api_object/auction.py | 49 +++++++++++++++++++ .../fixture_data/auction/message/auction.json | 32 ++++++++++++ .../fixture_data/auction/model/auction.py | 38 ++++++++++++++ tests/models/test_auction.py | 23 ++++----- 6 files changed, 141 insertions(+), 19 deletions(-) create mode 100644 tests/models/fixture_data/auction/api_object/auction.py create mode 100644 tests/models/fixture_data/auction/message/auction.json create mode 100644 tests/models/fixture_data/auction/model/auction.py diff --git a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py index f7ebfb7..64c4e83 100644 --- a/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py +++ b/rarible_marketplace_indexer/types/rarible_api_objects/asset/asset.py @@ -82,7 +82,7 @@ def sell_from_auction_model(cls, model: AuctionModel) -> Optional[AbstractAsset] 'asset_type': { 'asset_class': model.sell_asset_class, 'contract': model.sell_contract, - 'token_id': model.sell_asset_class, + 'token_id': model.sell_token_id, }, 'asset_value': model.sell_value, }, diff --git a/tests/models/conftest.py b/tests/models/conftest.py index dd3ea2a..d1117c3 100644 --- a/tests/models/conftest.py +++ b/tests/models/conftest.py @@ -15,11 +15,12 @@ from pydantic import BaseModel from tortoise.models import Model -from rarible_marketplace_indexer.models import ActivityModel +from rarible_marketplace_indexer.models import ActivityModel, AuctionModel from rarible_marketplace_indexer.models import AuctionActivityModel from rarible_marketplace_indexer.models import OrderModel from rarible_marketplace_indexer.types.rarible_api_objects.activity.auction.activity import RaribleApiAuctionActivity from rarible_marketplace_indexer.types.rarible_api_objects.activity.order.activity import RaribleApiOrderActivity +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction import RaribleApiAuction from rarible_marketplace_indexer.types.rarible_api_objects.order.order import RaribleApiOrder @@ -47,9 +48,9 @@ class TestActivityData(TestModelData): test_api_object: RaribleApiOrderActivity -# class TestAuctionData(TestModelData): -# test_model: Optional[AuctionModel] -# test_api_object: RaribleApiAuction +class TestAuctionData(TestModelData): + test_model: Optional[AuctionModel] + test_api_object: RaribleApiAuction class TestAuctionActivityData(TestModelData): @@ -72,6 +73,7 @@ def data_loader(object_type: str): fixtures: Dict[str, Type[TestModelData]] = { TestingSubject.order: TestOrderData, TestingSubject.activity: TestActivityData, + TestingSubject.auction: TestAuctionData, TestingSubject.auction_activity: TestAuctionActivityData, } @@ -111,9 +113,9 @@ def activity_serializer_data_provider(request: SubRequest): return request.param -# @pytest.fixture(params=data_loader(TestingSubject.auction)) -# def auction_data_provider(request: SubRequest): -# return request.param +@pytest.fixture(params=data_loader(TestingSubject.auction)) +def auction_data_provider(request: SubRequest): + return request.param @pytest.fixture(params=data_loader(TestingSubject.auction_activity)) diff --git a/tests/models/fixture_data/auction/api_object/auction.py b/tests/models/fixture_data/auction/api_object/auction.py new file mode 100644 index 0000000..bcf0f23 --- /dev/null +++ b/tests/models/fixture_data/auction/api_object/auction.py @@ -0,0 +1,49 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import AuctionStatusEnum +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset import TokenAsset +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_description import AssetDescription +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_type import MultiTokenAssetType +from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction import RaribleApiAuction +from rarible_marketplace_indexer.types.tezos_objects.asset_value.asset_value import AssetValue +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OriginatedAccountAddress + +auction_api_object = RaribleApiAuction( + id=UUID("427d1b55-fff3-5af7-ad49-6d817b0f7d14"), + platform=PlatformEnum.RARIBLE, + network="ithacanet", + contract=OriginatedAccountAddress("KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43"), + seller=ImplicitAccountAddress('tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC'), + sell=TokenAsset( + _asset_class=AssetClassEnum.MULTI_TOKEN, + asset_type=MultiTokenAssetType( + asset_class=AssetClassEnum.MULTI_TOKEN, + contract=OriginatedAccountAddress("KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43"), + token_id="1" + ), + asset_value=AssetValue(1) + ), + buy=AssetDescription( + type=AssetClassEnum.FUNGIBLE_TOKEN, + contract=None, + token_id=None + ), + end_time=datetime(2022, 5, 2, 18, 20, 15, tzinfo=UTC), + minimal_step=1, + minimal_price=10, + created_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + buy_price=100000, + status=AuctionStatusEnum.ACTIVE, + ongoing=True, + hash="1ed421e034a451d89ecb57f487595b28", + start_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + auction_id="1ed421e034a451d89ecb57f487595b28", + last_bid=None, + ) diff --git a/tests/models/fixture_data/auction/message/auction.json b/tests/models/fixture_data/auction/message/auction.json new file mode 100644 index 0000000..d90641a --- /dev/null +++ b/tests/models/fixture_data/auction/message/auction.json @@ -0,0 +1,32 @@ +{ + "id": "427d1b55-fff3-5af7-ad49-6d817b0f7d14", + "network": "ithacanet", + "platform": "Rarible", + "contract": "KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43", + "seller": "tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC", + "sell": { + "assetType": { + "assetClass": "TEZOS_MT", + "contract": "KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43", + "tokenId": "1" + }, + "assetValue": "1" + }, + "buy": { + "type": "TEZOS_FT", + "contract": null, + "tokenId": null + }, + "endTime": "2022-05-02T18:20:15+00:00", + "minimalStep": "1", + "minimalPrice": "10", + "createdAt": "2022-05-02T15:33:35+00:00", + "lastUpdatedAt": "2022-05-02T15:33:35+00:00", + "buyPrice": "100000", + "status": "ACTIVE", + "ongoing": true, + "hash": "1ed421e034a451d89ecb57f487595b28", + "startAt": "2022-05-02T15:33:35+00:00", + "auctionId": "1ed421e034a451d89ecb57f487595b28", + "lastBid": null +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction/model/auction.py b/tests/models/fixture_data/auction/model/auction.py new file mode 100644 index 0000000..07e3caf --- /dev/null +++ b/tests/models/fixture_data/auction/model/auction.py @@ -0,0 +1,38 @@ +from datetime import datetime + +from pytz import UTC + +from rarible_marketplace_indexer.models import AuctionModel, AuctionStatusEnum +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OriginatedAccountAddress + +auction_model = AuctionModel( + network="ithacanet", + platform=PlatformEnum.RARIBLE, + auction_id="1ed421e034a451d89ecb57f487595b28", + status=AuctionStatusEnum.ACTIVE, + start_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + ended_at=None, + created_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + end_time=datetime(2022, 5, 2, 18, 20, 15, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + ongoing=True, + seller=ImplicitAccountAddress('tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC'), + sell_asset_class=AssetClassEnum.MULTI_TOKEN, + sell_contract=OriginatedAccountAddress("KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43"), + sell_token_id="1", + sell_value=1, + buy_asset_class=AssetClassEnum.FUNGIBLE_TOKEN, + buy_contract=None, + buy_token_id=None, + minimal_step=1, + minimal_price=10, + duration=1000, + buy_price=100000, + max_seller_fees=10000, + last_bid_amount=None, + last_bid_bidder=None, + last_bid_date=None, + ) diff --git a/tests/models/test_auction.py b/tests/models/test_auction.py index 36a1fae..97f264f 100644 --- a/tests/models/test_auction.py +++ b/tests/models/test_auction.py @@ -1,19 +1,20 @@ from rarible_marketplace_indexer.producer.serializer import kafka_value_serializer +from rarible_marketplace_indexer.types.rarible_api_objects.auction.factory import RaribleApiAuctionFactory from rarible_marketplace_indexer.types.rarible_api_objects.order.factory import RaribleApiOrderFactory from tests.models.conftest import compare_kafka_messages class TestRaribleApiOrder: - def test_kafka_topic(self, order_data_provider): - order_api_object = RaribleApiOrderFactory.build(order_data_provider.test_model) - assert order_api_object.kafka_topic == 'order_topic_mainnet' + def test_kafka_topic(self, auction_data_provider): + auction_api_object = RaribleApiAuctionFactory.build(auction_data_provider.test_model) + assert auction_api_object.kafka_topic == 'auction_topic_ithacanet' - def test_factory(self, order_data_provider): - order_api_object = RaribleApiOrderFactory.build(order_data_provider.test_model) - expected_object = order_data_provider.test_api_object - assert order_api_object == expected_object + def test_factory(self, auction_data_provider): + auction_api_object = RaribleApiAuctionFactory.build(auction_data_provider.test_model) + expected_object = auction_data_provider.test_api_object + assert auction_api_object == expected_object - def test_serializer(self, order_data_provider): - order_message = kafka_value_serializer(order_data_provider.test_api_object, sort_keys=True) - expected_message = order_data_provider.test_message - compare_kafka_messages(order_message, expected_message) + def test_serializer(self, auction_data_provider): + auction_message = kafka_value_serializer(auction_data_provider.test_api_object, sort_keys=True) + expected_message = auction_data_provider.test_message + compare_kafka_messages(auction_message, expected_message) From 74ac5449e8b55aeb4860a02a94e86d9b7252d5a4 Mon Sep 17 00:00:00 2001 From: Florian PAUTOT Date: Fri, 10 Jun 2022 17:52:24 +0200 Subject: [PATCH 11/11] add tests for auctions with bids --- .../auction/api_object/auction_with_bids.py | 54 +++++++++++++++++++ .../auction/message/auction_with_bids.json | 36 +++++++++++++ .../auction/model/auction_with_bids.py | 39 ++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 tests/models/fixture_data/auction/api_object/auction_with_bids.py create mode 100644 tests/models/fixture_data/auction/message/auction_with_bids.json create mode 100644 tests/models/fixture_data/auction/model/auction_with_bids.py diff --git a/tests/models/fixture_data/auction/api_object/auction_with_bids.py b/tests/models/fixture_data/auction/api_object/auction_with_bids.py new file mode 100644 index 0000000..e1a7cd5 --- /dev/null +++ b/tests/models/fixture_data/auction/api_object/auction_with_bids.py @@ -0,0 +1,54 @@ +from datetime import datetime +from uuid import UUID + +from pytz import UTC + +from rarible_marketplace_indexer.models import AuctionStatusEnum +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset import TokenAsset +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_description import AssetDescription +from rarible_marketplace_indexer.types.rarible_api_objects.asset.asset_type import MultiTokenAssetType +from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction import RaribleApiAuction +from rarible_marketplace_indexer.types.rarible_api_objects.auction.auction_bid import AuctionBid +from rarible_marketplace_indexer.types.tezos_objects.asset_value.asset_value import AssetValue +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OriginatedAccountAddress + +auction_api_object = RaribleApiAuction( + id=UUID("427d1b55-fff3-5af7-ad49-6d817b0f7d14"), + platform=PlatformEnum.RARIBLE, + network="ithacanet", + contract=OriginatedAccountAddress("KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43"), + seller=ImplicitAccountAddress('tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC'), + sell=TokenAsset( + _asset_class=AssetClassEnum.MULTI_TOKEN, + asset_type=MultiTokenAssetType( + asset_class=AssetClassEnum.MULTI_TOKEN, + contract=OriginatedAccountAddress("KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43"), + token_id="1" + ), + asset_value=AssetValue(1) + ), + buy=AssetDescription( + type=AssetClassEnum.FUNGIBLE_TOKEN, + contract=None, + token_id=None + ), + end_time=datetime(2022, 5, 2, 18, 20, 15, tzinfo=UTC), + minimal_step=1, + minimal_price=10, + created_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + buy_price=100000, + status=AuctionStatusEnum.ACTIVE, + ongoing=True, + hash="1ed421e034a451d89ecb57f487595b28", + start_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + auction_id="1ed421e034a451d89ecb57f487595b28", + last_bid=AuctionBid( + buyer=ImplicitAccountAddress('tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC'), + amount=AssetValue(1), + date=datetime(2022, 5, 2, 16, 33, 35, tzinfo=UTC) + ), + ) diff --git a/tests/models/fixture_data/auction/message/auction_with_bids.json b/tests/models/fixture_data/auction/message/auction_with_bids.json new file mode 100644 index 0000000..40b8637 --- /dev/null +++ b/tests/models/fixture_data/auction/message/auction_with_bids.json @@ -0,0 +1,36 @@ +{ + "id": "427d1b55-fff3-5af7-ad49-6d817b0f7d14", + "network": "ithacanet", + "platform": "Rarible", + "contract": "KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43", + "seller": "tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC", + "sell": { + "assetType": { + "assetClass": "TEZOS_MT", + "contract": "KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43", + "tokenId": "1" + }, + "assetValue": "1" + }, + "buy": { + "type": "TEZOS_FT", + "contract": null, + "tokenId": null + }, + "endTime": "2022-05-02T18:20:15+00:00", + "minimalStep": "1", + "minimalPrice": "10", + "createdAt": "2022-05-02T15:33:35+00:00", + "lastUpdatedAt": "2022-05-02T15:33:35+00:00", + "buyPrice": "100000", + "status": "ACTIVE", + "ongoing": true, + "hash": "1ed421e034a451d89ecb57f487595b28", + "startAt": "2022-05-02T15:33:35+00:00", + "auctionId": "1ed421e034a451d89ecb57f487595b28", + "lastBid": { + "buyer": "tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC", + "amount": "1", + "date": "2022-05-02T16:33:35+00:00" + } +} \ No newline at end of file diff --git a/tests/models/fixture_data/auction/model/auction_with_bids.py b/tests/models/fixture_data/auction/model/auction_with_bids.py new file mode 100644 index 0000000..1fddbf1 --- /dev/null +++ b/tests/models/fixture_data/auction/model/auction_with_bids.py @@ -0,0 +1,39 @@ +from datetime import datetime + +from pytz import UTC + +from rarible_marketplace_indexer.models import AuctionModel, AuctionStatusEnum +from rarible_marketplace_indexer.models import PlatformEnum +from rarible_marketplace_indexer.types.rarible_api_objects.asset.enum import AssetClassEnum +from rarible_marketplace_indexer.types.tezos_objects.asset_value.asset_value import AssetValue +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import ImplicitAccountAddress +from rarible_marketplace_indexer.types.tezos_objects.tezos_object_hash import OriginatedAccountAddress + +auction_model = AuctionModel( + network="ithacanet", + platform=PlatformEnum.RARIBLE, + auction_id="1ed421e034a451d89ecb57f487595b28", + status=AuctionStatusEnum.ACTIVE, + start_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + ended_at=None, + created_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + end_time=datetime(2022, 5, 2, 18, 20, 15, tzinfo=UTC), + last_updated_at=datetime(2022, 5, 2, 15, 33, 35, tzinfo=UTC), + ongoing=True, + seller=ImplicitAccountAddress('tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC'), + sell_asset_class=AssetClassEnum.MULTI_TOKEN, + sell_contract=OriginatedAccountAddress("KT1EreNsT2gXRvuTUrpx6Ju4WMug5xcEpr43"), + sell_token_id="1", + sell_value=1, + buy_asset_class=AssetClassEnum.FUNGIBLE_TOKEN, + buy_contract=None, + buy_token_id=None, + minimal_step=1, + minimal_price=10, + duration=1000, + buy_price=100000, + max_seller_fees=10000, + last_bid_amount=AssetValue(1), + last_bid_bidder=ImplicitAccountAddress('tz1Mxsc66En4HsVHr6rppYZW82ZpLhpupToC'), + last_bid_date=datetime(2022, 5, 2, 16, 33, 35, tzinfo=UTC), + )