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-2019] Adds token struct to TokenType #259

Merged
merged 5 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
17 changes: 12 additions & 5 deletions database/migrations/2024_09_17_164605_upgrade_tokens_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,28 @@
public function up(): void
{
Schema::table('tokens', function (Blueprint $table) {
// New fields
$table->boolean('requires_deposit')->default(true)->after('is_frozen');
// Creation deposit
$table->string('creation_depositor')->nullable()->after('requires_deposit');
$table->foreignId('creation_depositor')
->nullable()
->index()
->after('requires_deposit')
->constrained('wallets')
->cascadeOnUpdate()
->cascadeOnDelete();
$table->string('creation_deposit_amount')->default('0')->after('creation_depositor');
// Others
$table->string('owner_deposit')->default('0')->after('creation_deposit_amount');
$table->string('total_token_account_deposit')->default('0')->after('owner_deposit');
$table->integer('attribute_count')->default(0)->after('total_token_account_deposit')->change();
$table->integer('account_count')->default(0)->after('attribute_count');
$table->string('infusion')->default('0')->after('account_count');
$table->boolean('anyone_can_infuse')->default(false)->after('infusion');
// Metadata
$table->integer('decimal_count')->default(0)->after('anyone_can_infuse');
$table->string('name')->nullable()->after('decimal_count');
$table->string('symbol')->nullable()->after('name');

// Changes
$table->integer('attribute_count')->default(0)->after('total_token_account_deposit')->change();

// Not used anymore
$table->dropColumn('unit_price');
$table->dropColumn('minimum_balance');
Expand Down
10 changes: 10 additions & 0 deletions lang/en/type.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@
'token.field.supply' => 'The current supply of this token.',
'token.field.tokenId' => 'The token chain ID which is a 128bit unsigned integer number.',
'token.field.unitPrice' => '(DEPRECATED) The price of each token in ENJ.',
'token.field.requiresDeposit' => 'Specifies if this token requires a deposit to be minted.',
'token.field.creationDeposit' => 'The creation deposit of this token.',
'token.field.ownerDeposit' => 'The amount of deposit the owner has paid for this token.',
'token.field.totalTokenAccountDeposit' => 'The total deposit of all token accounts.',
'token.field.infusion' => 'The amount of ENJ infused into each token.',
'token.field.anyoneCanInfuse' => 'Specifies if anyone can infuse ENJ into this token.',
'token.field.tokenMetadata' => 'The metadata for this token.',
'token_account.description' => "A token account stores a wallet's balance of a specific token in a collection.",
'token_account.field.balance' => 'The balance of the token this account holds.',
'token_account.field.collection' => 'The collection this token account belongs to.',
Expand All @@ -115,6 +122,9 @@
'token_account_named_reserve.args.amount' => 'The amount in the wallet that has been reserved.',
'token_account_named_reserve.args.pallet' => 'The pallet that has created this reserve.',
'token_account_named_reserve.description' => 'The pallet that has reserved some tokens and the amount.',
'token_metadata.field.name' => 'The token name.',
'token_metadata.field.symbol' => 'The token symbol.',
'token_metadata.field.decimalCount' => 'The decimal count of the token.',
'transaction.description' => 'An blockchain transaction.',
'transaction.eth.description' => 'An Ethereum transaction.',
'transaction.eth.field.transactionId' => 'The transaction hash.',
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/Sync.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ protected function displayOverview(array $storages): void
$storage[2]
));
}
$this->info(__('enjin-platform::commands.sync.total_time', ['sec' => now()->diffInMilliseconds($this->start) / 1000]));
$this->info(__('enjin-platform::commands.sync.total_time', ['sec' => $this->start->diffInMilliseconds(now()) / 1000]));
$this->info('=======================================================');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function resolve($root, $args, $context, ResolveInfo $resolveInfo, Closur
}

/**
* Get the validatio rules.
* Get the validation rules.
*/
protected function rules(array $args = []): array
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function fields(): array
'defaultValue' => false,
],
'metadata' => [
'type' => GraphQL::type('MetadataInput'),
'type' => GraphQL::type('TokenMetadataInput'),
'description' => __('enjin-platform::input_type.create_token_params.field.metadata'),
'defaultValue' => null,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\InputType;

class MetadataInputType extends InputType implements PlatformGraphQlType
class TokenMetadataInputType extends InputType implements PlatformGraphQlType
{
use InSubstrateSchema;

Expand All @@ -18,7 +18,7 @@ class MetadataInputType extends InputType implements PlatformGraphQlType
public function attributes(): array
{
return [
'name' => 'MetadataInput',
'name' => 'TokenMetadataInput',
'description' => __('enjin-platform::type.metadata_input.description'),
];
}
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQL/Types/Substrate/CreationDepositType.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function fields(): array
return [
// Properties
'depositor' => [
'type' => GraphQL::type('Wallet!'),
'type' => GraphQL::type('Wallet'),
'description' => __('enjin-platform::type.creation_deposit.description'),
],
'amount' => [
Expand Down
46 changes: 46 additions & 0 deletions src/GraphQL/Types/Substrate/TokenMetadataType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Enjin\Platform\GraphQL\Types\Substrate;

use Enjin\Platform\GraphQL\Types\Traits\InSubstrateSchema;
use Enjin\Platform\Interfaces\PlatformGraphQlType;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Type;

class TokenMetadataType extends Type implements PlatformGraphQlType
{
use InSubstrateSchema;

/**
* Get the type's attributes.
*/
public function attributes(): array
{
return [
'name' => 'TokenMetadata',
leonardocustodio marked this conversation as resolved.
Show resolved Hide resolved
'description' => __('enjin-platform::type.token_metadata.description'),
];
}

/**
* Get the type's fields definition.
*/
public function fields(): array
{
return [
// Properties
'name' => [
'type' => GraphQL::type('String'),
'description' => __('enjin-platform::type.token_metadata.field.name'),
],
'symbol' => [
'type' => GraphQL::type('String'),
'description' => __('enjin-platform::type.token_metadata.field.symbol'),
],
'decimalCount' => [
'type' => GraphQL::type('Int!'),
'description' => __('enjin-platform::type.token_metadata.field.decimal_count'),
],
];
}
}
46 changes: 46 additions & 0 deletions src/GraphQL/Types/Substrate/TokenType.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,52 @@ public function fields(): array
'description' => __('enjin-platform::type.token.field.attributeCount'),
'alias' => 'attribute_count',
],
'requiresDeposit' => [
'type' => GraphQL::type('Boolean!'),
'description' => __('enjin-platform::type.token.field.requiresDeposit'),
'alias' => 'requires_deposit',
],
'creationDeposit' => [
'type' => GraphQL::type('CreationDeposit!'),
'description' => __('enjin-platform::type.collection_type.field.creationDeposit'),
'resolve' => fn ($token) => [
'depositor' => $token->creationDepositor,
'amount' => $token->creation_deposit_amount,
],
'is_relation' => false,
'selectable' => false,
],
'ownerDeposit' => [
'type' => GraphQL::type('BigInt!'),
'description' => __('enjin-platform::type.token.field.ownerDeposit'),
'alias' => 'owner_deposit',
],
'totalTokenAccountDeposit' => [
'type' => GraphQL::type('BigInt!'),
'description' => __('enjin-platform::type.token.field.totalTokenAccountDeposit'),
'alias' => 'total_token_account_deposit',
],
'infusion' => [
'type' => GraphQL::type('BigInt!'),
'description' => __('enjin-platform::type.token.field.infusion'),
'alias' => 'infusion',
],
'anyoneCanInfuse' => [
'type' => GraphQL::type('Boolean!'),
'description' => __('enjin-platform::type.token.field.anyoneCanInfuse'),
'alias' => 'anyone_can_infuse',
],
'tokenMetadata' => [
'type' => GraphQL::type('TokenMetadata!'),
'description' => __('enjin-platform::type.token.field.tokenMetadata'),
'resolve' => fn ($token) => [
'name' => $token->name,
'symbol' => $token->symbol,
'decimalCount' => $token->decimal_count,
],
'is_relation' => false,
'selectable' => false,
],

// Related
'collection' => [
Expand Down
6 changes: 6 additions & 0 deletions src/Models/Laravel/Traits/EagerLoadSelectFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,18 @@ public static function loadToken(
): array {
$fields = Arr::get($selections, $attribute, $selections);
$hasBeneficiary = (bool) Arr::get($fields, 'royalty.fields.beneficiary');
$hasDepositor = (bool) Arr::get($fields, 'creationDeposit.fields.depositor');
$select = array_filter([
'id',
'collection_id',
...(isset($fields['nonFungible']) ? ['is_currency', 'supply', 'cap', 'cap_supply'] : []),
$hasBeneficiary ? 'royalty_wallet_id' : null,
$hasDepositor ? 'creation_depositor' : null,
Arr::get($fields, 'royalty.fields.percentage') ? 'royalty_percentage' : null,
Arr::get($fields, 'creationDeposit.fields.amount') ? 'creation_deposit_amount' : null,
Arr::get($fields, 'tokenMetadata.fields.name') ? 'name' : null,
Arr::get($fields, 'tokenMetadata.fields.symbol') ? 'symbol' : null,
Arr::get($fields, 'tokenMetadata.fields.decimalCount') ? 'decimal_count' : null,
...TokenType::getSelectFields($fieldKeys = array_keys($fields)),
]);

Expand Down
8 changes: 8 additions & 0 deletions src/Models/Laravel/Traits/Token.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public function collection(): BelongsTo
return $this->belongsTo(Collection::class);
}

/**
* The creation depositor relationship.
*/
public function creationDepositor(): BelongsTo
{
return $this->belongsTo(Wallet::class, 'creation_depositor');
}

/**
* The royalty benificiary relationship.
*/
Expand Down
25 changes: 12 additions & 13 deletions src/Services/Processor/Substrate/Codec/Decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,12 @@ public function tokenStorageKey(string $data): array

public function tokenStorageData(string $data): array
{
$decoded = $this->codec->process('TokenStorageDataV1010', new ScaleBytes($data));
$decoded = $this->codec->process('TokenStorageData', new ScaleBytes($data));

$cap = TokenMintCapType::tryFrom(collect(Arr::get($decoded, 'cap'))->keys()->first());
$capSupply = Arr::get($decoded, 'cap.Supply') ?? Arr::get($decoded, 'cap.CollapsingSupply');
$isCurrency = Arr::exists(Arr::get($decoded, 'marketBehavior') ?: [], 'IsCurrency');
$isFrozen = in_array(Arr::get($decoded, 'freezeState'), ['Permanent', 'Temporary']);
$unitPrice = Arr::get($decoded, 'sufficiency.Insufficient');

return [
'supply' => gmp_strval(Arr::get($decoded, 'supply')),
Expand All @@ -243,18 +242,18 @@ public function tokenStorageData(string $data): array
'royaltyPercentage' => ($percentage = Arr::get($decoded, 'marketBehavior.HasRoyalty.percentage')) !== null ? $percentage / 10 ** 7 : null,
'isCurrency' => $isCurrency,
'listingForbidden' => Arr::get($decoded, 'listingForbidden'),
'minimumBalance' => gmp_strval(Arr::get($decoded, 'minimumBalance')),
// TODO: unitPrice and mintDeposit don't exists anymore on v1010
'unitPrice' => gmp_strval($unitPrice),
'mintDeposit' => gmp_strval(Arr::get($decoded, 'mintDeposit')),
'attributeCount' => gmp_strval(Arr::get($decoded, 'attributeCount')),
// TODO: Implement new v1010 fields
// 'requiresDeposit' => Arr::get($decoded, 'requiresDeposit'),
// 'creationDepositDepositor' => Arr::get($decoded, 'creationDeposit.depositor'),
// 'creationDepositAmount' => gmp_strval(Arr::get($decoded, 'creationDeposit.amount')),
// 'ownerDeposit' => gmp_strval(Arr::get($decoded, 'ownerDeposit')),
// 'infusion' => gmp_strval(Arr::get($decoded, 'infusion')),
// 'anyoneCanInfuse' => Arr::get($decoded, 'anyoneCanInfuse'),
'accountCount' => gmp_strval(Arr::get($decoded, 'accountCount')),
'requiresDeposit' => Arr::get($decoded, 'requiresDeposit'),
'creationDepositor' => ($depositor = Arr::get($decoded, 'creationDeposit.depositor')) !== null ? HexConverter::prefix($depositor) : null,
'creationDepositAmount' => gmp_strval(Arr::get($decoded, 'creationDeposit.amount')),
'ownerDeposit' => gmp_strval(Arr::get($decoded, 'ownerDeposit')),
'totalTokenAccountDeposit' => gmp_strval(Arr::get($decoded, 'totalTokenAccountDeposit')),
'infusion' => gmp_strval(Arr::get($decoded, 'infusion')),
'anyoneCanInfuse' => Arr::get($decoded, 'anyoneCanInfuse'),
'decimalCount' => gmp_strval(Arr::get($decoded, 'metadata.decimalCount')),
'name' => Arr::get($decoded, 'metadata.name'),
'symbol' => Arr::get($decoded, 'metadata.symbol'),
];

}
Expand Down
48 changes: 9 additions & 39 deletions src/Services/Processor/Substrate/Codec/Types/TokenStorage.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,85 +7,55 @@
"hashTokenId": "u128",
"tokenId": "u128"
},
"TokenStorageData": {
"supply": "Compact<u128>",
"cap": "Option<TokenCap>",
"freezeState": "Option<FreezeState>",
"minimumBalance": "Compact",
"sufficiency": "Sufficiency",
"mintDeposit": "Compact",
"attributeCount": "Compact",
"marketBehavior": "Option<TokenMarketBehavior>",
"listingForbidden": "bool",
"metadata": "TokenMetadata"
},
"Sufficiency": {
"_enum": {
"Sufficient": "Null",
"Insufficient": "Compact<u128>"
}
},
"TokenMarketBehavior": {
"_enum": {
"HasRoyalty": "RoyaltyPolicyDescriptor",
"IsCurrency": "Null"
}
},
"FreezeState": {
"_enum": [
"Permanent",
"Temporary",
"Never"
]
},
"TokenMetadata": {
"_enum": {
"Native": "Null",
"Foreign": "ForeignTokenMetadata"
}
},
"ForeignTokenMetadata": {
"decimalCount": "Compact<u32>",
"name": "Bytes",
"symbol": "Bytes",
"location": "Option<XcmV1MultiLocation>"
},
"TokenStorageDataV1010": {
"TokenStorageData": {
"supply": "Compact<u128>",
"cap": "Option<TokenCapV1010>",
"cap": "Option<TokenCap>",
"freezeState": "Option<FreezeState>",
"requiresDeposit": "bool",
"creationDeposit": "TokenCreationDeposit",
"ownerDeposit": "Compact<u128>",
"totalTokenAccountDeposit": "Compact<u128>",
"attributeCount": "Compact<u32>",
"accountCount": "Compact<u32>",
"marketBehavior": "Option<TokenMarketBehaviorV1010>",
"marketBehavior": "Option<TokenMarketBehavior>",
"listingForbidden": "bool",
"metadata": "TokenMetadataV1010",
"metadata": "TokenMetadata",
"infusion": "u128",
"anyoneCanInfuse": "bool",
"groups": "Vec<u128>"
},
"TokenMetadataV1010": {
"TokenMetadata": {
"decimalCount": "u8",
"name": "Bytes",
"symbol": "Bytes",
"foreign": "Option<XcmV1MultiLocation>"
},
"TokenCapV1010": {
"TokenCap": {
"_enum": {
"Supply": "Compact<u128>",
"CollapsingSupply": "Compact<u128>"
}
},
"TokenMarketBehaviorV1010": {
"TokenMarketBehavior": {
"_enum": {
"HasRoyalty": "RoyaltyPolicyDescriptorV1010",
"HasRoyalty": "RoyaltyPolicyDescriptor",
"IsCurrency": "Null"
}
},
"RoyaltyPolicyDescriptorV1010": {
"RoyaltyPolicyDescriptor": {
"beneficiary": "AccountId",
"percentage": "Compact<Perbill>"
},
Expand Down
Loading
Loading