Skip to content

Commit c6616dd

Browse files
committed
2 parents ea4a24c + 9cbed5a commit c6616dd

36 files changed

+268
-134
lines changed

config/evm.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
// Fee policy for EIP 1559.
2222
'fees' => [
2323
'min_priority_gwei' => env('EVM_MIN_PRIORITY_GWEI', 3),
24-
'min_maxfee_gwei' => env('EVM_MIN_MAXFEE_GWEI', 40),
25-
'base_multiplier' => env('EVM_BASE_MULTIPLIER', 3),
26-
'replacement_factor'=> env('EVM_REPLACEMENT_FACTOR', 1.5),
24+
'min_maxfee_gwei' => env('EVM_MIN_MAXFEE_GWEI', 40),
25+
'base_multiplier' => env('EVM_BASE_MULTIPLIER', 3),
26+
'replacement_factor' => env('EVM_REPLACEMENT_FACTOR', 1.5),
2727
],
2828

2929
// Transaction behavior.
3030
'tx' => [
3131
'estimate_padding' => env('EVM_ESTIMATE_PADDING', 1.2),
32-
'confirm_timeout' => env('EVM_CONFIRM_TIMEOUT', 120), // seconds
32+
'confirm_timeout' => env('EVM_CONFIRM_TIMEOUT', 120), // seconds
3333
'max_replacements' => env('EVM_MAX_REPLACEMENTS', 2),
3434
'poll_interval_ms' => env('EVM_POLL_INTERVAL_MS', 800),
3535

src/Clients/ContractClientGeneric.php

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,37 @@
22

33
namespace Farbcode\LaravelEvm\Clients;
44

5+
use Farbcode\LaravelEvm\Contracts\AbiCodec;
6+
use Farbcode\LaravelEvm\Contracts\ContractClient;
7+
use Farbcode\LaravelEvm\Contracts\FeePolicy;
8+
use Farbcode\LaravelEvm\Contracts\NonceManager;
59
use Farbcode\LaravelEvm\Contracts\RpcClient;
610
use Farbcode\LaravelEvm\Contracts\Signer;
7-
use Farbcode\LaravelEvm\Contracts\NonceManager;
8-
use Farbcode\LaravelEvm\Contracts\FeePolicy;
911
use Farbcode\LaravelEvm\Contracts\TxBuilder;
10-
use Farbcode\LaravelEvm\Contracts\AbiCodec;
11-
use Farbcode\LaravelEvm\Contracts\ContractClient;
12-
1312
use Farbcode\LaravelEvm\Jobs\SendTransaction;
1413

1514
class ContractClientGeneric implements ContractClient
1615
{
1716
public function __construct(
18-
private RpcClient $rpc,
19-
private Signer $signer,
17+
private RpcClient $rpc,
18+
private Signer $signer,
2019
private NonceManager $nonces,
21-
private FeePolicy $fees,
22-
private TxBuilder $builder,
23-
private AbiCodec $abi,
24-
private int $chainId,
25-
private array $txCfg
26-
)
27-
{
28-
}
20+
private FeePolicy $fees,
21+
private TxBuilder $builder,
22+
private AbiCodec $abi,
23+
private int $chainId,
24+
private array $txCfg
25+
) {}
2926

3027
private string $address = '';
28+
3129
private array|string $abiJson = [];
3230

3331
public function at(string $address, array|string $abi = []): self
3432
{
3533
$this->address = $address;
3634
$this->abiJson = $abi;
35+
3736
return $this;
3837
}
3938

@@ -45,7 +44,7 @@ public function call(string $function, array $args = []): mixed
4544
return $this->rpc->call('eth_call', [[
4645
'from' => $from,
4746
'to' => $this->address,
48-
'data' => $data
47+
'data' => $data,
4948
], 'latest']);
5049
}
5150

@@ -55,17 +54,18 @@ public function estimateGas(string $data, ?string $from = null): int
5554
$est = $this->rpc->call('eth_estimateGas', [[
5655
'from' => $from,
5756
'to' => $this->address,
58-
'data' => $data
57+
'data' => $data,
5958
]]);
60-
$n = is_string($est) ? hexdec($est) : (int)$est;
61-
$pad = (float)($this->txCfg['estimate_padding'] ?? 1.2);
62-
return (int)max(150000, ceil($n * $pad));
59+
$n = is_string($est) ? hexdec($est) : (int) $est;
60+
$pad = (float) ($this->txCfg['estimate_padding'] ?? 1.2);
61+
62+
return (int) max(150000, ceil($n * $pad));
6363
}
6464

6565
public function sendAsync(string $function, array $args = [], array $opts = []): string
6666
{
6767
$data = $this->abi->encodeFunction($this->abiJson, $function, $args);
68-
$queue = (string)($this->txCfg['queue'] ?? 'evm-send');
68+
$queue = (string) ($this->txCfg['queue'] ?? 'evm-send');
6969

7070
return dispatch(
7171
new SendTransaction(
@@ -83,11 +83,12 @@ public function wait(string $txHash, int $timeoutSec = 120, int $pollMs = 800):
8383
$deadline = time() + $timeoutSec;
8484
while (time() < $deadline) {
8585
$rec = $this->rpc->call('eth_getTransactionReceipt', [$txHash]);
86-
if (!empty($rec)) {
86+
if (! empty($rec)) {
8787
return $rec;
8888
}
8989
usleep($pollMs * 1000);
9090
}
91+
9192
return null;
9293
}
9394
}

src/Clients/RpcHttpClient.php

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
namespace Farbcode\LaravelEvm\Clients;
44

5-
use Illuminate\Support\Str;
6-
use Illuminate\Support\Facades\Http;
7-
use Illuminate\Support\Facades\Log;
85
use Farbcode\LaravelEvm\Contracts\RpcClient;
96
use Farbcode\LaravelEvm\Exceptions\RpcException;
7+
use Illuminate\Support\Facades\Http;
8+
use Illuminate\Support\Facades\Log;
9+
use Illuminate\Support\Str;
1010

1111
class RpcHttpClient implements RpcClient
1212
{
@@ -15,7 +15,9 @@ class RpcHttpClient implements RpcClient
1515
* Uses Laravel HTTP client with retry and timeout
1616
*/
1717
protected array $urls;
18+
1819
protected int $chainId;
20+
1921
protected int $cursor = 0;
2022

2123
public function __construct(array $urls, int $chainId)
@@ -39,9 +41,9 @@ public function callRaw(string $method, array $params = []): array
3941

4042
$payload = [
4143
'jsonrpc' => '2.0',
42-
'id' => $id,
43-
'method' => $method,
44-
'params' => $params,
44+
'id' => $id,
45+
'method' => $method,
46+
'params' => $params,
4547
];
4648

4749
$attempts = count($this->urls);
@@ -70,11 +72,12 @@ public function callRaw(string $method, array $params = []): array
7072
if (is_array($json) && isset($json['error'])) {
7173
$lastError = $json['error']['message'] ?? 'RPC error';
7274
Log::warning('RPC error body', [
73-
'url' => $url,
75+
'url' => $url,
7476
'method' => $method,
75-
'id' => $id,
76-
'error' => $json['error'],
77+
'id' => $id,
78+
'error' => $json['error'],
7779
]);
80+
7881
// try next url
7982
continue;
8083
}
@@ -86,32 +89,33 @@ public function callRaw(string $method, array $params = []): array
8689
// Unexpected body shape
8790
$lastError = 'Invalid JSON body';
8891
Log::warning('RPC invalid json', [
89-
'url' => $url,
92+
'url' => $url,
9093
'method' => $method,
91-
'id' => $id,
92-
'body' => $response->body(),
94+
'id' => $id,
95+
'body' => $response->body(),
9396
]);
97+
9498
continue;
9599
}
96100

97101
// Non success HTTP
98102
$lastError = 'HTTP '.$response->status();
99103
Log::warning('RPC non success', [
100-
'url' => $url,
104+
'url' => $url,
101105
'method' => $method,
102-
'id' => $id,
106+
'id' => $id,
103107
'status' => $response->status(),
104-
'body' => $response->body(),
108+
'body' => $response->body(),
105109
]);
106110
// try next url
107111
} catch (\Throwable $e) {
108112
// Network or timeout
109113
$lastError = $e->getMessage();
110114
Log::error('RPC exception', [
111-
'url' => $url,
115+
'url' => $url,
112116
'method' => $method,
113-
'id' => $id,
114-
'error' => $lastError,
117+
'id' => $id,
118+
'error' => $lastError,
115119
]);
116120
// try next url
117121
}
@@ -146,7 +150,7 @@ public function health(): array
146150

147151
return [
148152
'chainId' => is_string($idHex) ? hexdec($idHex) : (int) $idHex,
149-
'block' => is_string($bnHex) ? hexdec($bnHex) : (int) $bnHex,
153+
'block' => is_string($bnHex) ? hexdec($bnHex) : (int) $bnHex,
150154
];
151155
}
152156
}

src/Codec/AbiCodecWeb3p.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
2+
23
// src/Codec/AbiCodecWeb3p.php
4+
35
namespace Farbcode\LaravelEvm\Codec;
46

57
use Farbcode\LaravelEvm\Contracts\AbiCodec;
@@ -10,12 +12,14 @@ class AbiCodecWeb3p implements AbiCodec
1012
public function encodeFunction(array|string $abi, string $fn, array $args): string
1113
{
1214
$c = new Contract('', is_array($abi) ? json_encode($abi) : $abi);
15+
1316
return $c->getData($fn, ...$args);
1417
}
1518

1619
public function callStatic(array|string $abi, string $fn, array $args, callable $ethCall): mixed
1720
{
1821
$data = $this->encodeFunction($abi, $fn, $args);
22+
1923
return $ethCall($data);
2024
}
2125
}

src/Commands/EvmCallCommand.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
<?php
2+
23
// src/Commands/EvmCallCommand.php
4+
35
namespace Farbcode\LaravelEvm\Commands;
46

57
use Illuminate\Console\Command;
6-
use LaravelEvm; // Facade Alias
8+
9+
// Facade Alias
710

811
class EvmCallCommand extends Command
912
{
1013
protected $signature = 'evm:call {address} {abiPath} {function} {args*}';
14+
1115
protected $description = 'Static eth_call on a contract function';
1216

1317
public function handle(): int
1418
{
1519
$addr = $this->argument('address');
16-
$abi = file_get_contents($this->argument('abiPath'));
17-
$fn = $this->argument('function');
20+
$abi = file_get_contents($this->argument('abiPath'));
21+
$fn = $this->argument('function');
1822
$args = $this->argument('args');
1923

2024
$res = Evm::at($addr, $abi)->call($fn, $args);
2125
$this->line(json_encode($res, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
26+
2227
return self::SUCCESS;
2328
}
2429
}

src/Commands/EvmGenerateAddressCommand.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
2+
23
// src/Commands/EvmGenerateAddressCommand.php
4+
35
namespace Farbcode\LaravelEvm\Commands;
46

57
use Illuminate\Console\Command;
@@ -9,13 +11,15 @@
911
class EvmGenerateAddressCommand extends Command
1012
{
1113
protected $signature = 'evm:address:generate {--count=1 : Number of addresses to generate} {--json : Output JSON array instead of table}';
14+
1215
protected $description = 'Generate one or more fresh Ethereum addresses (private key + public key + checksum address)';
1316

1417
public function handle(): int
1518
{
1619
$count = (int) $this->option('count');
1720
if ($count < 1 || $count > 50) {
1821
$this->error('Count must be between 1 and 50');
22+
1923
return self::FAILURE;
2024
}
2125

@@ -24,9 +28,10 @@ public function handle(): int
2428
// Library auto-generates secure private key if none supplied.
2529
// Wrap in try/catch to handle rare ECC overflow edge cases on certain PHP builds.
2630
try {
27-
$addr = new EthAddress();
31+
$addr = new EthAddress;
2832
} catch (\Throwable $e) {
2933
$this->error('Failed to generate address: '.$e->getMessage());
34+
3035
return self::FAILURE;
3136
}
3237
$privateKey = $addr->getPrivateKey(); // 64 hex (no 0x)
@@ -44,7 +49,7 @@ public function handle(): int
4449
if ($this->option('json')) {
4550
$this->line(json_encode($rows, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
4651
} else {
47-
$this->table(['Address', 'Private Key', 'Public Key'], array_map(fn($r) => [$r['address'], $r['private_key'], substr($r['public_key'],0,20).''], $rows));
52+
$this->table(['Address', 'Private Key', 'Public Key'], array_map(fn ($r) => [$r['address'], $r['private_key'], substr($r['public_key'], 0, 20).''], $rows));
4853
$this->info('IMPORTANT: Store private keys securely. They will NOT be shown again.');
4954
}
5055

@@ -59,6 +64,7 @@ private function toChecksum(string $address): string
5964
for ($i = 0; $i < strlen($hex); $i++) {
6065
$out .= (hexdec($hash[$i]) >= 8) ? strtoupper($hex[$i]) : $hex[$i];
6166
}
67+
6268
return $out;
6369
}
6470
}

src/Commands/EvmHealthCommand.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
<?php
2+
23
// src/Commands/EvmHealthCommand.php
4+
35
namespace Farbcode\LaravelEvm\Commands;
46

5-
use Illuminate\Console\Command;
67
use Farbcode\LaravelEvm\Contracts\RpcClient;
8+
use Illuminate\Console\Command;
79

810
class EvmHealthCommand extends Command
911
{
1012
protected $signature = 'evm:health';
13+
1114
protected $description = 'Show chain id and latest block to verify RPC health';
1215

1316
public function handle(RpcClient $rpc): int
1417
{
1518
$h = $rpc->health();
1619
$this->info('Chain ID '.$h['chainId']);
1720
$this->info('Latest block '.$h['block']);
21+
1822
return self::SUCCESS;
1923
}
2024
}

src/Commands/EvmSendCommand.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
<?php
2+
23
// src/Commands/EvmSendCommand.php
4+
35
namespace Farbcode\LaravelEvm\Commands;
46

57
use Illuminate\Console\Command;
6-
use LaravelEvm; // Facade Alias
8+
9+
// Facade Alias
710

811
class EvmSendCommand extends Command
912
{
1013
protected $signature = 'evm:send {address} {abiPath} {function} {args*} {--timeout=120}';
14+
1115
protected $description = 'Queue a non blocking transaction for a contract function';
1216

1317
public function handle(): int
1418
{
1519
$addr = $this->argument('address');
16-
$abi = file_get_contents($this->argument('abiPath'));
17-
$fn = $this->argument('function');
20+
$abi = file_get_contents($this->argument('abiPath'));
21+
$fn = $this->argument('function');
1822
$args = $this->argument('args');
1923
$timeout = (int) $this->option('timeout');
2024

2125
$jobId = Evm::at($addr, $abi)->sendAsync($fn, $args, ['timeout' => $timeout]);
2226
$this->info('Queued job id '.$jobId);
2327
$this->info('Queue '.config('evm.tx.queue'));
28+
2429
return self::SUCCESS;
2530
}
2631
}

0 commit comments

Comments
 (0)