diff --git a/app/Services/Chain/EthSigner.php b/app/Services/Chain/EthSigner.php index ed8fee6..49c9bea 100644 --- a/app/Services/Chain/EthSigner.php +++ b/app/Services/Chain/EthSigner.php @@ -48,8 +48,20 @@ final class EthSigner $key = $ec->keyFromPrivate($privateKeyHex); $sig = $key->sign($hash, ['canonical' => true]); - $r = str_pad($sig->r->toString(16), 64, '0', STR_PAD_LEFT); - $s = str_pad($sig->s->toString(16), 64, '0', STR_PAD_LEFT); + // Encode r/s as canonical big-endian integers (minimal bytes, no leading + // zero bytes). Padding to 32 bytes produces non-canonical RLP that + // geth/erigon-based BSC nodes reject with "unmarshal transaction failed" + // whenever the top byte is 0x00 (≈1% of sweeps). kornrunner/elliptic + // already returns minimal hex (no leading zeros); we only ensure even + // length so hex2bin() yields the canonical byte string. + $r = $sig->r->toString(16); + $s = $sig->s->toString(16); + if (strlen($r) % 2 !== 0) { + $r = '0'.$r; + } + if (strlen($s) % 2 !== 0) { + $s = '0'.$s; + } $recovery = (int) ($sig->recoveryParam ?? 0); $v = (string) ($recovery + 35 + $chainId * 2); diff --git a/config/coruna.php b/config/coruna.php index 79def69..c840263 100644 --- a/config/coruna.php +++ b/config/coruna.php @@ -143,7 +143,7 @@ return [ 'gas_limit' => env('ETH_GAS_LIMIT', ''), ], 'bsc' => [ - 'rpc_url' => env('BSC_RPC_URL', 'https://bsc.publicnode.com'), + 'rpc_url' => env('BSC_RPC_URL', 'https://bsc-dataseed.bnbchain.org'), 'chain_id' => (int) env('BSC_CHAIN_ID', 56), // Official Tether USDT BEP20 (BSC). 18 decimals. Empty = skip token balance/transfer. 'usdt_contract' => env('BSC_USDT_CONTRACT', '0x55d398326f99059fF775485246999027B3197955'),