Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PLA-2033] Changes for v2.0.0 on marketplace #66

Merged
merged 9 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [8.2]
php: [8.3]

name: PHP ${{ matrix.php }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [8.2]
php: [8.3]

name: PHP ${{ matrix.php }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security_checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
php-version: 8.3
tools: composer:v2
coverage: none

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
}
],
"require": {
"php": "^8.2|^8.3",
"php": "^8.3",
"ext-bcmath": "*",
"ext-json": "*",
"ext-openssl": "*",
Expand Down
6 changes: 4 additions & 2 deletions database/factories/MarketplaceListingFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ public function definition()
'deposit' => fake()->numberBetween(1, 100),
'salt' => fake()->text(),
'type' => $state = ListingType::caseNamesAsCollection()->random(),
'start_block' => $state == ListingType::AUCTION->name ? fake()->numberBetween(1, 100) : null,
'end_block' => $state == ListingType::AUCTION->name ? fake()->numberBetween(100, 200) : null,
'auction_start_block' => $state == ListingType::AUCTION->name ? fake()->numberBetween(1, 100) : null,
'auction_end_block' => $state == ListingType::AUCTION->name ? fake()->numberBetween(100, 200) : null,
'offer_expiration' => $state == ListingType::OFFER->name ? fake()->numberBetween(100, 200) : null,
'counter_offer_count' => $state == ListingType::OFFER->name ? fake()->numberBetween(0, 10) : null,
'amount_filled' => $state == ListingType::FIXED_PRICE->name ? fake()->numberBetween(1000, 2000) : null,
];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class () extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('marketplace_listings', function (Blueprint $table) {
$table->renameColumn('start_block', 'auction_start_block');
$table->renameColumn('end_block', 'auction_end_block');
$table->unsignedInteger('offer_expiration')->nullable()->after('auction_end_block');
$table->unsignedInteger('counter_offer_count')->nullable()->after('offer_expiration');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('marketplace_listings', function (Blueprint $table) {
$table->renameColumn('auction_start_block', 'start_block');
$table->renameColumn('auction_end_block', 'end_block');
$table->dropColumn(['offer_expiration', 'counter_offer_count']);
});
}
};
1 change: 1 addition & 0 deletions lang/en/mutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'create_listing.args.account' => 'The seller account.',
'create_listing.args.makeAssetId' => 'Ids for the asset being sold.',
'create_listing.args.takeAssetId' => 'Ids for the asset requested.',
'create_listing.args.listingData' => 'The listing data parameters.',
'cancel_listing.description' => 'Cancels the listing.',
'fill_listing.description' => 'Fills a fixed price listing.',
'finalize_auction.description' => 'This will end the auction and transfer funds. It fails if the auction is not over.',
Expand Down
8 changes: 8 additions & 0 deletions lang/en/type.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@
'marketplace_sale.description' => 'The listing sale.',
'marketplace_state.description' => 'The state of the marketplace listing.',
'marketplace_state.field.height' => 'The block height.',
'listing_data.description' => 'The data for a listing.',
'listing_data.field.type' => 'The type of listing.',
'listing_data.field.auctionParams' => 'The parameters for an auction listing.',
'listing_data.field.offerParams' => 'The parameters for an offer.',
'offer_data.description' => 'The parameters for an offer.',
'offer_data.field.expiration' => 'The expiration time for the offer.',
'offer_state.description' => 'The state of an offer.',
'offer_state.field.counterOfferCount' => 'The number of counter offers.',
];
2 changes: 2 additions & 0 deletions src/Enums/ListingType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ enum ListingType: string

case FIXED_PRICE = 'FixedPrice';
case AUCTION = 'Auction';

case OFFER = 'Offer';
}
107 changes: 60 additions & 47 deletions src/GraphQL/Mutations/CreateListingMutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
use Enjin\Platform\GraphQL\Types\Input\Substrate\Traits\HasSigningAccountField;
use Enjin\Platform\GraphQL\Types\Input\Substrate\Traits\HasSimulateField;
use Enjin\Platform\Interfaces\PlatformBlockchainTransaction;
use Enjin\Platform\Marketplace\Enums\ListingType;
use Enjin\Platform\Marketplace\Models\Substrate\AuctionDataParams;
use Enjin\Platform\Marketplace\Models\Substrate\ListingDataParams;
use Enjin\Platform\Marketplace\Models\Substrate\MultiTokensTokenAssetIdParams;
use Enjin\Platform\Marketplace\Models\Substrate\OfferDataParams;
use Enjin\Platform\Marketplace\Rules\EnoughTokenSupply;
use Enjin\Platform\Marketplace\Rules\FutureBlock;
use Enjin\Platform\Marketplace\Rules\TokenExistsInCollection;
Expand Down Expand Up @@ -85,14 +88,9 @@ public function args(): array
'type' => GraphQL::type('String'),
'description' => __('enjin-platform-marketplace::type.marketplace_listing.field.salt'),
],
// TODO: We should remove `auctionData` and replace it with `listingData`
// listingData = FixedPrice, Auction, Offer
// FixedPrice => null,
// Auction => { startBlock, endBlock },
// Offer => { expiration }
'auctionData' => [
'type' => GraphQL::type('AuctionDataInputType'),
'description' => __('enjin-platform-marketplace::input_type.auction_data.description'),
'listingData' => [
'type' => GraphQL::type('ListingDataInput'),
'description' => __('enjin-platform-marketplace::mutation.create_listing.args.listingData'),
],
...$this->getSigningAccountField(),
...$this->getIdempotencyField(),
Expand All @@ -111,8 +109,7 @@ public function resolve(
ResolveInfo $resolveInfo,
Closure $getSelectFields,
) {
$method = isRunningLatest() ? $this->getMutationName() . 'V1010' : $this->getMutationName();
$encodedData = TransactionSerializer::encode($method, static::getEncodableParams(
$encodedData = TransactionSerializer::encode($this->getMutationName(), static::getEncodableParams(
makeAssetId: new MultiTokensTokenAssetIdParams(
Arr::get($args, 'makeAssetId.collectionId'),
$this->encodeTokenId(Arr::get($args, 'makeAssetId'))
Expand All @@ -124,9 +121,7 @@ public function resolve(
amount: Arr::get($args, 'amount'),
price: Arr::get($args, 'price'),
salt: Arr::get($args, 'salt', Str::random(10)),
auctionData: ($data = Arr::get($args, 'auctionData'))
? new AuctionDataParams(Arr::get($data, 'startBlock'), Arr::get($data, 'endBlock'))
: null
listingData: Arr::get($args, 'listingData'),
));

return Transaction::lazyLoadSelectFields(
Expand All @@ -142,25 +137,26 @@ public static function getEncodableParams(...$params): array
$amount = Arr::get($params, 'amount', 0);
$price = Arr::get($params, 'price', 0);
$salt = Arr::get($params, 'salt', Str::random(10));
$auctionData = Arr::get($params, 'auctionData');

$extra = isRunningLatest() ? [
'listingData' => $auctionData ? [
'Auction' => $auctionData->toEncodable(),
] : [
'FixedPrice' => null,
],
] : [
'auctionData' => $auctionData?->toEncodable(),
];
$listingType = ListingType::getEnumCase(Arr::get($params, 'listingData.type'));
$listingData = match ($listingType) {
ListingType::AUCTION => new ListingDataParams(
ListingType::AUCTION,
auctionParams: new AuctionDataParams(...Arr::get($params, 'listingData.auctionParams')),
),
ListingType::OFFER => new ListingDataParams(
ListingType::OFFER,
offerParams: new OfferDataParams(...Arr::get($params, 'listingData.offerParams'))
),
default => new ListingDataParams(ListingType::FIXED_PRICE),
};

return [
'makeAssetId' => $makeAsset->toEncodable(),
'takeAssetId' => $takeAsset->toEncodable(),
'amount' => gmp_init($amount),
'price' => gmp_init($price),
'salt' => HexConverter::stringToHexPrefixed($salt),
...$extra,
'listingData' => $listingData->toEncodable(),
'depositor' => null,
];
}
Expand Down Expand Up @@ -210,13 +206,7 @@ protected function rulesCommon(array $args): array
new MaxBigInt(),
],
'salt' => ['bail', 'filled', 'max:255'],
'auctionData.endBlock' => [
'bail',
'required_with:auctionData.startBlock',
new MinBigInt(),
new MaxBigInt(Hex::MAX_UINT32),
'gt:auctionData.startBlock',
],
'listingData.type' => ['required'],
];
}

Expand All @@ -227,6 +217,24 @@ protected function rulesWithValidation(array $args): array
{
$makeRule = $this->makeOrTakeRuleExist($makeCollection = Arr::get($args, 'makeAssetId.collectionId'));
$takeRule = $this->makeOrTakeRuleExist($takeCollection = Arr::get($args, 'takeAssetId.collectionId'), false);
$listingDataType = ListingType::getEnumCase(Arr::get($args, 'listingData.type'));
$extras = match ($listingDataType) {
ListingType::AUCTION => [
'listingData.auctionParams' => ['required'],
'listingData.offerParams' => ['prohibited'],
'listingData.auctionParams.startBlock' => ['bail', 'required', new MinBigInt(), new MaxBigInt(Hex::MAX_UINT32), new FutureBlock()],
'listingData.auctionParams.endBlock' => ['bail', 'required', new MinBigInt(), new MaxBigInt(Hex::MAX_UINT32), 'gt:listingData.auctionParams.startBlock', new FutureBlock()],
],
ListingType::OFFER => [
'listingData.offerParams' => ['required'],
'listingData.auctionParams' => ['prohibited'],
'listingData.offerParams.expiration' => ['bail', 'nullable', new MinBigInt(), new MaxBigInt(Hex::MAX_UINT32), new FutureBlock()],
],
default => [
'listingData.auctionParams' => ['prohibited'],
'listingData.offerParams' => ['prohibited'],
],
};

return [
'makeAssetId' => new TokenExistsInCollection($makeCollection),
Expand All @@ -241,14 +249,7 @@ protected function rulesWithValidation(array $args): array
new MaxBigInt(),
new EnoughTokenSupply(),
],
'auctionData.startBlock' => [
'bail',
'required_with:auctionData.endBlock',
new MinBigInt(),
new MaxBigInt(Hex::MAX_UINT32),
new FutureBlock(),
'lte:auctionData.endBlock',
],
...$extras,
];
}

Expand All @@ -259,6 +260,24 @@ protected function rulesWithoutValidation(array $args): array
{
$makeRule = $this->makeOrTakeRule(Arr::get($args, 'makeAssetId.collectionId'));
$takeRule = $this->makeOrTakeRule(Arr::get($args, 'takeAssetId.collectionId'), false);
$listingDataType = ListingType::getEnumCase(Arr::get($args, 'listingData.type'));
$extras = match ($listingDataType) {
ListingType::AUCTION => [
'listingData.auctionParams' => ['required'],
'listingData.offerParams' => ['prohibited'],
'listingData.auctionParams.startBlock' => ['bail', 'required', new MinBigInt(), new MaxBigInt(Hex::MAX_UINT32)],
'listingData.auctionParams.endBlock' => ['bail', 'required', new MinBigInt(), new MaxBigInt(Hex::MAX_UINT32), 'gt:listingData.auctionParams.startBlock'],
],
ListingType::OFFER => [
'listingData.offerParams' => ['required'],
'listingData.auctionParams' => ['prohibited'],
'listingData.offerParams.expiration' => ['bail', 'nullable', new MinBigInt(), new MaxBigInt(Hex::MAX_UINT32)],
],
default => [
'listingData.auctionParams' => ['prohibited'],
'listingData.offerParams' => ['prohibited'],
],
};

return [
...$makeRule,
Expand All @@ -270,13 +289,7 @@ protected function rulesWithoutValidation(array $args): array
new MinBigInt(1),
new MaxBigInt(),
],
'auctionData.startBlock' => [
'bail',
'required_with:auctionData.endBlock',
new MinBigInt(),
new MaxBigInt(Hex::MAX_UINT32),
'lte:auctionData.endBlock',
],
...$extras,
];
}
}
4 changes: 2 additions & 2 deletions src/GraphQL/Types/AuctionDataType.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ public function fields(): array
'startBlock' => [
'type' => GraphQL::type('Int!'),
'description' => __('enjin-platform-marketplace::type.auction_data.field.startBlock'),
'alias' => 'start_block',
'alias' => 'auction_start_block',
],
'endBlock' => [
'type' => GraphQL::type('Int!'),
'description' => __('enjin-platform-marketplace::type.auction_data.field.endBlock'),
'alias' => 'end_block',
'alias' => 'auction_end_block',
],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@

namespace Enjin\Platform\Marketplace\GraphQL\Types\Input;

use Enjin\Platform\Marketplace\GraphQL\Types\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;

class AuctionDataInputType extends InputType
class AuctionParamsInputType extends InputType
{
/**
* Get the input type's attributes.
* Get the type's attributes.
*/
public function attributes(): array
{
return [
'name' => 'AuctionDataInputType',
'description' => __('enjin-platform-marketplace::input_type.auction_data.description'),
'name' => 'AuctionParamsInput',
'description' => __('enjin-platform-marketplace::type.auction_data.description'),
];
}

/**
* Get the input type's fields.
* Get the type's fields.
*/
public function fields(): array
{
Expand Down
41 changes: 41 additions & 0 deletions src/GraphQL/Types/Input/ListingDataInputType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Enjin\Platform\Marketplace\GraphQL\Types\Input;

use Enjin\Platform\Marketplace\GraphQL\Types\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;

class ListingDataInputType extends InputType
{
/**
* Get the type's attributes.
*/
public function attributes(): array
{
return [
'name' => 'ListingDataInput',
'description' => __('enjin-platform-marketplace::type.listing_data.description'),
];
}

/**
* Get the type's fields.
*/
public function fields(): array
{
return [
'type' => [
'type' => GraphQL::type('ListingType!'),
'description' => __('enjin-platform-marketplace::type.listing_data.field.type'),
],
'auctionParams' => [
'type' => GraphQL::type('AuctionParamsInput'),
'description' => __('enjin-platform-marketplace::type.listing_data.field.auctionParams'),
],
'offerParams' => [
'type' => GraphQL::type('OfferParamsInput'),
'description' => __('enjin-platform-marketplace::type.listing_data.field.offerParams'),
],
];
}
}
Loading
Loading