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

feat: add token transfer token name #1170

Draft
wants to merge 30 commits into
base: mainsail-develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8dd1364
fetch transaction token name
alfonsobries Jan 27, 2025
8554370
move api call to service
alexbarnsley Jan 28, 2025
bdabd58
update cache keys
alexbarnsley Jan 28, 2025
0941423
update view model method to get token name
alexbarnsley Jan 28, 2025
1df8457
add evm functions enum
alexbarnsley Jan 28, 2025
15cd028
output token name for token transfer
alexbarnsley Jan 28, 2025
1da8c79
style: resolve style guide violations
alexbarnsley Jan 28, 2025
b975006
tidy
alexbarnsley Jan 28, 2025
cce63f7
test command
alexbarnsley Jan 28, 2025
f0e5d66
Merge branch 'feat/add-token-transfer-token-name' of github.com:Arden…
alexbarnsley Jan 28, 2025
7f1427b
style: resolve style guide violations
alexbarnsley Jan 28, 2025
622c829
allow nullable token name from cache
alexbarnsley Jan 28, 2025
85b6a58
test
alexbarnsley Jan 28, 2025
4c44910
chore: stanley
alexbarnsley Jan 28, 2025
0c0c983
handle failed http request
alexbarnsley Jan 28, 2025
d1fcb33
adjust token transfer factory method
alexbarnsley Jan 28, 2025
4f4a47f
test
alexbarnsley Jan 28, 2025
b43d63e
Merge branch 'feat/add-token-transfer-token-name' of github.com:Arden…
alexbarnsley Jan 28, 2025
03e3d5c
update crypto dependency
alexbarnsley Jan 28, 2025
e135e3e
style: resolve style guide violations
alexbarnsley Jan 28, 2025
c66619e
single line for payload amount
alexbarnsley Jan 28, 2025
d42d8fe
test
alexbarnsley Jan 28, 2025
26fe7c8
test
alexbarnsley Jan 28, 2025
4f8fdd9
Merge branch 'feat/add-token-transfer-token-name' of github.com:Arden…
alexbarnsley Jan 28, 2025
505bdf8
style: resolve style guide violations
alexbarnsley Jan 28, 2025
94c04df
Merge branch 'mainsail-develop' into feat/add-token-transfer-token-name
alexbarnsley Jan 29, 2025
f3e0411
remove token transfer contract method as its incorrect
alexbarnsley Jan 31, 2025
951b2e0
style: resolve style guide violations
alexbarnsley Jan 31, 2025
3b86f48
Merge branch 'mainsail-develop' into feat/add-token-transfer-token-name
alexbarnsley Feb 3, 2025
4e72f04
Merge branch 'mainsail-develop' into feat/add-token-transfer-token-name
alexbarnsley Feb 4, 2025
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
57 changes: 57 additions & 0 deletions app/Console/Commands/CacheTransactionsTokenName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\Scopes\ContractDeploymentScope;
use App\Models\Transaction;
use App\Services\Cache\TokenTransferCache;
use App\Services\MainsailApi;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Collection;

final class CacheTransactionsTokenName extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'explorer:cache-transactions-token-name';

/**
* The console command description.
*
* @var string|null
*/
protected $description = 'Cache the token name for token transfers.';

public function handle(TokenTransferCache $cache): void
{
/** @var Collection<int, Transaction> $transactions */
$transactions = Transaction::withScope(ContractDeploymentScope::class)->get();

foreach ($transactions as $transaction) {
if ($transaction->receipt === null) {
continue;
}

if ($transaction->receipt->deployed_contract_address === null) {
continue;
}

$contractAddress = $transaction->receipt->deployed_contract_address;
if ($cache->hasTokenName($contractAddress)) {
continue;
}

$tokenName = MainsailApi::deployedTokenName($contractAddress);
if ($tokenName === null) {
continue;
}

$cache->setTokenName($contractAddress, $tokenName);
}
}
}
10 changes: 10 additions & 0 deletions app/Enums/EvmFunctions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace App\Enums;

enum EvmFunctions: string
{
case NAME = '0x06fdde03';
}
5 changes: 5 additions & 0 deletions app/Services/Cache/Concerns/ManagesCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ private function forget(string $key)
return $this->getCache()->forget(md5($key));
}

private function has(string $key): bool
{
return $this->getCache()->has(md5($key));
}

private function blockTimeTTL(): int
{
return (int) ceil(Network::blockTime() / 2);
Expand Down
35 changes: 35 additions & 0 deletions app/Services/Cache/TokenTransferCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace App\Services\Cache;

use App\Contracts\Cache as Contract;
use App\Services\Cache\Concerns\ManagesCache;
use Illuminate\Cache\TaggedCache;
use Illuminate\Support\Facades\Cache;

final class TokenTransferCache implements Contract
{
use ManagesCache;

public function getTokenName(string $transactionId): ?string
{
return $this->get('name/'.$transactionId);
}

public function setTokenName(string $transactionId, string $tokenName): void
{
$this->put('name/'.$transactionId, $tokenName);
}

public function hasTokenName(string $transactionId): bool
{
return $this->has('name/'.$transactionId);
}

public function getCache(): TaggedCache
{
return Cache::tags('tokenTransfer');
}
}
30 changes: 30 additions & 0 deletions app/Services/MainsailApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

namespace App\Services;

use App\Enums\EvmFunctions;
use App\Facades\Network;
use App\Services\Cache\MainsailCache;
use ArkEcosystem\Crypto\Utils\AbiDecoder;
use ArkEcosystem\Crypto\Utils\UnitConverter;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -45,6 +47,34 @@ public static function fees(): array
return $fees;
}

public static function deployedTokenName(string $contractAddress): ?string
{
try {
$response = Http::withHeader('Content-Type', 'application/json')
->post('https://dwallets-evm.ihost.org/evm/api', [
'jsonrpc' => '2.0',
'method' => 'eth_call',
'params' => [[
'from' => '0x12361f0Bd5f95C3Ea8BF34af48F5484b811B5CCe',
'to' => $contractAddress,
'data' => EvmFunctions::NAME->value,
], 'latest'],
'id' => 1,
])->json();
} catch (\Throwable) {
return null;
}

$result = Arr::get($response, 'result');
if ($result === null) {
return null;
}

$method = AbiDecoder::decodeFunctionWithAbi('function name() view returns (string)', $result);

return $method[0];
}

public static function timeToForge(): int
{
return 1 * Network::blockTime();
Expand Down
42 changes: 42 additions & 0 deletions app/ViewModels/Concerns/Transaction/CanHaveTokenName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace App\ViewModels\Concerns\Transaction;

use App\Services\Cache\TokenTransferCache;

trait CanHaveTokenName
{
public function tokenName(): ?string
{
$cache = new TokenTransferCache();
$contractId = $this->contractId();
if ($contractId === null) {
return null;
}

if (! $cache->hasTokenName($contractId)) {
return null;
}

return $cache->getTokenName($contractId);
}

public function contractId(): ?string
{
if ($this->isContractDeployment()) {
if ($this->transaction->receipt === null) {
return null;
}

return $this->transaction->receipt->deployed_contract_address;
}

if ($this->isTokenTransfer()) {
return $this->transaction->recipient_address;
}

return null;
}
}
2 changes: 2 additions & 0 deletions app/ViewModels/TransactionViewModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use App\Services\Transactions\TransactionMethod;
use App\Services\Transactions\TransactionState;
use App\ViewModels\Concerns\Transaction\CanBeValidatorRegistration;
use App\ViewModels\Concerns\Transaction\CanHaveTokenName;
use App\ViewModels\Concerns\Transaction\CanHaveUsername;
use App\ViewModels\Concerns\Transaction\HasDirection;
use App\ViewModels\Concerns\Transaction\HasMethod;
Expand All @@ -28,6 +29,7 @@ final class TransactionViewModel implements ViewModel
{
use CanBeValidatorRegistration;
use CanHaveUsername;
use CanHaveTokenName;
use HasDirection;
use HasPayload;
use HasState;
Expand Down
10 changes: 5 additions & 5 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions database/factories/TransactionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function transfer(): Factory
]);
}

public function tokenTransfer(string $address, int $amount): Factory
public function tokenTransfer(string $address, int $amount, string $recipient): Factory
{
$payload = ContractMethod::transfer();
$payload .= str_pad(preg_replace('/^0x/', '', $address), 64, '0', STR_PAD_LEFT);
Expand All @@ -69,7 +69,7 @@ public function tokenTransfer(string $address, int $amount): Factory
return $this->withPayload($payload)
->state(fn () => [
// TODO: update recipient - https://app.clickup.com/t/86dvdegme
'recipient_address' => Network::knownContract('consensus'),
'recipient_address' => $recipient,
]);
}

Expand Down
6 changes: 6 additions & 0 deletions resources/views/components/payload/amount.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@props([
'argument',
'suffix',
])

{{ ExplorerNumberFormatter::weiToArk((new ArgumentDecoder($argument))->decodeUnsignedInt(), false) }} {{ $suffix }}
3 changes: 0 additions & 3 deletions resources/views/components/payload/number.blade.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
:title="trans('pages.transaction.header.amount')"
:transaction="$transaction"
>
<x-payload.number :argument="$methodArguments[TokenTransferArgument::AMOUNT]" />
<x-payload.amount
:argument="$methodArguments[TokenTransferArgument::AMOUNT]"
:suffix="$transaction->tokenName()"
/>
</x-transaction.page.section-detail.row>
@endif
</x-general.page-section.container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\Transaction;
use App\Models\Wallet;
use App\Services\Cache\TokenTransferCache;
use Carbon\Carbon;

it('should render the page without any errors', function ($type, $args) {
Expand Down Expand Up @@ -51,17 +52,21 @@
$address = Wallet::factory()->create()->address;
$amount = (int) (34 * 1e9);

$transaction = Transaction::factory()->tokenTransfer($address, $amount)->create([
'timestamp' => Carbon::parse('2021-04-14 13:02:04')->getTimestampMs(),
'amount' => 123 * 1e18,
]);
(new TokenTransferCache())->setTokenName('0xC5a19e23E99bdFb7aae4301A009763AdC01c1b5B', 'DARK20');

$transaction = Transaction::factory()
->tokenTransfer($address, $amount, '0xC5a19e23E99bdFb7aae4301A009763AdC01c1b5B')
->create([
'timestamp' => Carbon::parse('2021-04-14 13:02:04')->getTimestampMs(),
'amount' => 123 * 1e18,
]);

$this
->get(route('transaction', $transaction))
->assertOk()
->assertSeeInOrder([
trans('pages.transaction.tokens_transferred'),
$address,
'34 DARK',
'34 DARK20',
]);
});
Loading
Loading