Skip to content

Commit

Permalink
[PLA-2019] Adds token struct to TokenType (#259)
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardocustodio authored Oct 4, 2024
1 parent 769f0c7 commit bca3c22
Show file tree
Hide file tree
Showing 21 changed files with 248 additions and 89 deletions.
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',
'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

0 comments on commit bca3c22

Please sign in to comment.