Skip to content

Commit 565e34e

Browse files
committed
feat: event payload support for async EVM transactions
1 parent 2e33010 commit 565e34e

File tree

8 files changed

+26
-20
lines changed

8 files changed

+26
-20
lines changed

src/Clients/ContractClientGeneric.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function estimateGas(string $data, ?string $from = null): int
6868
return (int) max(150000, ceil($n * $pad));
6969
}
7070

71-
public function sendAsync(string $function, array $args = [], array $opts = []): string
71+
public function sendAsync(string $function, array $args = [], array $opts = [], mixed $payload = null): string
7272
{
7373
$data = $this->abi->encodeFunction($this->abiJson, $function, $args);
7474
$queue = (string) ($this->txCfg['queue'] ?? 'evm-send');
@@ -80,7 +80,8 @@ public function sendAsync(string $function, array $args = [], array $opts = []):
8080
data: $data,
8181
opts: array_merge($opts, ['request_id' => $requestId]),
8282
chainId: $this->chainId,
83-
txCfg: $this->txCfg
83+
txCfg: $this->txCfg,
84+
payload: $payload
8485
))->onQueue($queue);
8586

8687
return $requestId;

src/Contracts/ContractClient.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ public function at(string $address, array|string $abi = []): self;
99
/** Synchronous read only call returning raw hex or decoded value depending on ABI usage. */
1010
public function call(string $function, array $args = []): mixed;
1111

12-
/** Enqueue a non blocking write job. Returns job id string. */
13-
public function sendAsync(string $function, array $args = [], array $opts = []): string;
12+
/**
13+
* Enqueue a non blocking write job. Returns job id string.
14+
* Optional $payload allows attaching any serializable context (e.g. an Eloquent model) that will
15+
* be forwarded to all transaction lifecycle events (TxQueued, TxBroadcasted, TxReplaced, TxMined, TxFailed).
16+
*/
17+
public function sendAsync(string $function, array $args = [], array $opts = [], mixed $payload = null): string;
1418

1519
/** Wait for a receipt with timeout returns receipt array or null. */
1620
public function wait(string $txHash, int $timeoutSec = 120, int $pollMs = 800): ?array;

src/Events/TxBroadcasted.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66

77
class TxBroadcasted
88
{
9-
public function __construct(public string $txHash, public array $fields) {}
9+
public function __construct(public string $txHash, public array $fields, public mixed $payload = null) {}
1010
}

src/Events/TxFailed.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66

77
class TxFailed
88
{
9-
public function __construct(public string $to, public string $data, public string $reason) {}
9+
public function __construct(public string $to, public string $data, public string $reason, public mixed $payload = null) {}
1010
}

src/Events/TxMined.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66

77
class TxMined
88
{
9-
public function __construct(public string $txHash, public array $receipt) {}
9+
public function __construct(public string $txHash, public array $receipt, public mixed $payload = null) {}
1010
}

src/Events/TxQueued.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66

77
class TxQueued
88
{
9-
public function __construct(public string $to, public string $data) {}
9+
public function __construct(public string $to, public string $data, public mixed $payload = null) {}
1010
}

src/Events/TxReplaced.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ class TxReplaced
1111
* @param array $newFields Neue Felder inklusive angehobener Fees
1212
* @param int $attempt Laufende Ersatz-Versuchsnummer (1-basiert)
1313
*/
14-
public function __construct(public string $oldTxHash, public array $newFields, public int $attempt) {}
14+
public function __construct(public string $oldTxHash, public array $newFields, public int $attempt, public mixed $payload = null) {}
1515
}

src/Jobs/SendTransaction.php

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ class SendTransaction implements ShouldQueue
2727
{
2828
use InteractsWithQueue, Queueable, SerializesModels;
2929

30-
public function __construct(public string $address, public string $data, public array $opts, public int $chainId, public array $txCfg) {}
30+
public function __construct(public string $address, public string $data, public array $opts, public int $chainId, public array $txCfg, public mixed $payload = null) {}
3131

3232
public function handle(RpcClient $rpc, Signer $signer, NonceManager $nonces, FeePolicy $fees): void
3333
{
34-
event(new TxQueued($this->address, $this->data));
34+
event(new TxQueued($this->address, $this->data, $this->payload));
3535

3636
$from = $signer->getAddress();
3737

@@ -67,7 +67,7 @@ public function handle(RpcClient $rpc, Signer $signer, NonceManager $nonces, Fee
6767

6868
$pk = method_exists($signer, 'privateKey') ? $signer->privateKey() : null;
6969
if (! $pk) {
70-
event(new TxFailed($this->address, $this->data, 'Signer has no privateKey method'));
70+
event(new TxFailed($this->address, $this->data, 'Signer has no privateKey method', $this->payload));
7171

7272
return;
7373
}
@@ -78,10 +78,10 @@ public function handle(RpcClient $rpc, Signer $signer, NonceManager $nonces, Fee
7878
$rawHex = str_starts_with($raw, '0x') ? $raw : '0x'.$raw; // ensure 0x prefix
7979
$txHash = $rpc->call('eth_sendRawTransaction', [$rawHex]);
8080
$nonces->markUsed($from, $nonce);
81-
event(new TxBroadcasted($txHash, $fields));
81+
event(new TxBroadcasted($txHash, $fields, $this->payload));
8282

8383
} catch (\Throwable $e) {
84-
event(new TxFailed($this->address, $this->data, 'rpc_send_error: '.$e->getMessage()));
84+
event(new TxFailed($this->address, $this->data, 'rpc_send_error: '.$e->getMessage(), $this->payload));
8585

8686
return;
8787
}
@@ -94,7 +94,7 @@ public function handle(RpcClient $rpc, Signer $signer, NonceManager $nonces, Fee
9494
while (time() < $deadline) {
9595
$rec = $rpc->call('eth_getTransactionReceipt', [$txHash]);
9696
if (! empty($rec)) {
97-
event(new TxMined($txHash, $rec));
97+
event(new TxMined($txHash, $rec, $this->payload));
9898

9999
return;
100100
}
@@ -109,15 +109,15 @@ public function handle(RpcClient $rpc, Signer $signer, NonceManager $nonces, Fee
109109
$fields['maxFeePerGas'] = $max;
110110

111111
// Emit replacement attempt (before rebroadcast)
112-
event(new TxReplaced($oldTxHash, $fields, $i + 1));
112+
event(new TxReplaced($oldTxHash, $fields, $i + 1, $this->payload));
113113

114114
try {
115115
$raw = new EIP1559Transaction($fields)->sign($pk);
116116
$rawHex = str_starts_with($raw, '0x') ? $raw : '0x'.$raw; // ensure 0x prefix
117117
$txHash = $rpc->call('eth_sendRawTransaction', [$rawHex]);
118-
event(new TxBroadcasted($txHash, $fields));
118+
event(new TxBroadcasted($txHash, $fields, $this->payload));
119119
} catch (\Throwable $e) {
120-
event(new TxFailed($this->address, $this->data, 'rpc_send_error_replacement_'.$i.': '.$e->getMessage()));
120+
event(new TxFailed($this->address, $this->data, 'rpc_send_error_replacement_'.$i.': '.$e->getMessage(), $this->payload));
121121

122122
return;
123123
}
@@ -126,7 +126,7 @@ public function handle(RpcClient $rpc, Signer $signer, NonceManager $nonces, Fee
126126
while (time() < $deadline) {
127127
$rec = $rpc->call('eth_getTransactionReceipt', [$txHash]);
128128
if (! empty($rec)) {
129-
event(new TxMined($txHash, $rec));
129+
event(new TxMined($txHash, $rec, $this->payload));
130130

131131
return;
132132
}
@@ -137,7 +137,8 @@ public function handle(RpcClient $rpc, Signer $signer, NonceManager $nonces, Fee
137137
event(new TxFailed(
138138
$this->address,
139139
$this->data,
140-
sprintf('no_receipt_after_%d_replacements (last maxFee=%d priority=%d)', $maxRep, $fields['maxFeePerGas'], $fields['maxPriorityFeePerGas'])
140+
sprintf('no_receipt_after_%d_replacements (last maxFee=%d priority=%d)', $maxRep, $fields['maxFeePerGas'], $fields['maxPriorityFeePerGas']),
141+
$this->payload
141142
));
142143
}
143144
}

0 commit comments

Comments
 (0)