Skip to content

Commit

Permalink
Fix max token count validation
Browse files Browse the repository at this point in the history
  • Loading branch information
enjinabner committed Aug 19, 2024
1 parent e6d5684 commit fc64333
Showing 1 changed file with 43 additions and 26 deletions.
69 changes: 43 additions & 26 deletions src/Rules/MaxTokenCount.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
use Enjin\Platform\Beam\Models\BeamClaim;
use Enjin\Platform\Beam\Rules\Traits\IntegerRange;
use Enjin\Platform\Models\Collection;
use Enjin\Platform\Models\Token;
use Enjin\Platform\Rules\Traits\HasDataAwareRule;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Arr;

class MaxTokenCount implements DataAwareRule, ValidationRule
{
Expand All @@ -33,35 +33,52 @@ public function __construct(protected ?string $collectionId) {}
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if ($this->collectionId && ($collection = Collection::withCount('tokens')->firstWhere(['collection_chain_id' => $this->collectionId]))) {
if (! is_null($this->limit = $collection->max_token_count)) {
$passes = $collection->max_token_count >= $collection->tokens_count
+ collect($this->data['tokens'])
->filter(fn ($token) => BeamType::getEnumCase($token['type']) == BeamType::MINT_ON_DEMAND)
->reduce(function ($carry, $token) {
return collect(Arr::get($token, 'tokenIds'))->reduce(function ($val, $tokenId) use ($token) {
$range = $this->integerRange($tokenId);
/**
* The sum of existing tokens, tokens in beams and tokens to be created
* must not exceed the collection's max token count.
*/
if ($this->collectionId
&& ($collection = Collection::withCount('tokens')->firstWhere(['collection_chain_id' => $this->collectionId]))
&& ! is_null($this->limit = $collection->max_token_count)
) {
$existingCount = BeamClaim::where('type', BeamType::MINT_ON_DEMAND->name)
->whereHas(
'beam',
fn ($query) => $query->where('collection_chain_id', $this->collectionId)->where('end', '>', now())
)->whereNotExists(function ($query) {
$query->selectRaw('1')
->from('tokens')
->whereColumn('tokens.token_chain_id', 'beam_claims.token_chain_id');
})
->groupBy('token_chain_id')
->count();

return $val + (
$range === false
? $token['claimQuantity']
: (($range[1] - $range[0]) + 1) * $token['claimQuantity']
);
}, $carry);
}, 0)
+ BeamClaim::whereHas(
'beam',
fn ($query) => $query->where('collection_chain_id', $this->collectionId)->where('end', '>', now())
)->where('type', BeamType::MINT_ON_DEMAND->name)
->count();
[$integers, $ranges] = collect($this->data['tokens'])
->pluck('tokenIds')
->flatten()
->partition(fn ($val) => $this->integerRange($val) === false);

$createTokenTotal = 0;
if (count($integers)) {
$createTokenTotal = Token::where('collection_id', $collection->id)
->whereNotIn('token_chain_id', $integers->pluck('tokenIds'))
->count();
}

if (! $passes) {
$fail('enjin-platform-beam::validation.max_token_count')
->translate([
'limit' => $this->limit,
]);
if (count($ranges)) {
foreach ($ranges as $range) {
[$from, $to] = $this->integerRange($range);
$count = Token::where('collection_id', $collection->id)
->whereBetween('token_chain_id', [(int) $from, (int) $to])
->count();
$createTokenTotal += (($to - $from) + 1) - $count;
}
}

$passes = $collection->max_token_count >= $collection->tokens_count + $existingCount + $createTokenTotal;
if (! $passes) {
$fail('enjin-platform-beam::validation.max_token_count')->translate(['limit' => $this->limit]);
}
}
}
}

0 comments on commit fc64333

Please sign in to comment.