feat: bnb

This commit is contained in:
hashbro
2026-09-26 12:27:12 +08:00
parent 534b36a2d2
commit ad09fdff88
23 changed files with 475 additions and 82 deletions
+19 -21
View File
@@ -76,18 +76,14 @@ class EthDriver implements ChainDriver
// fall through to token
}
foreach (['coruna.eth.usdt_contract', 'coruna.eth.bnb_contract'] as $key) {
$contract = trim((string) config($key, ''));
if ($contract === '') {
continue;
}
$contract = trim((string) config($this->configPrefix().'.usdt_contract', ''));
if ($contract !== '') {
try {
if (bccomp($this->getTokenBalance($address, $contract), '0', 18) > 0) {
return true;
}
} catch (\Throwable) {
// try the next token
return false;
}
}
@@ -129,14 +125,14 @@ class EthDriver implements ChainDriver
private function sendLegacy(string $privateKey, string $from, string $to, string $valueWei, string $data): string
{
$chainId = (int) config('coruna.eth.chain_id', 1);
$chainId = (int) config($this->configPrefix().'.chain_id', 1);
$nonceHex = $this->rpc('eth_getTransactionCount', [EthAddress::normalize($from), 'pending']);
$gasPriceHex = $this->rpc('eth_gasPrice', []);
if (! is_string($nonceHex) || ! is_string($gasPriceHex)) {
throw new RuntimeException('Failed to fetch nonce/gasPrice');
}
$gasLimit = trim((string) config('coruna.eth.gas_limit', ''));
$gasLimit = trim((string) config($this->configPrefix().'.gas_limit', ''));
if ($gasLimit === '' || ! preg_match('/^\d+$/', $gasLimit)) {
$gasLimit = ($data === '0x' || $data === '') ? '21000' : '100000';
}
@@ -190,19 +186,21 @@ class EthDriver implements ChainDriver
return $human === '' ? '0' : $human;
}
protected function configPrefix(): string
{
return 'coruna.eth';
}
private function tokenDecimals(string $contract): int
{
$normalized = EthAddress::normalize($contract);
$known = [
EthAddress::normalize((string) config('coruna.eth.usdt_contract', '')) => (int) config('coruna.eth.usdt_decimals', 6),
EthAddress::normalize((string) config('coruna.eth.bnb_contract', '')) => (int) config('coruna.eth.bnb_decimals', 18),
];
unset($known['']);
if ($normalized !== '' && isset($known[$normalized]) && $known[$normalized] > 0) {
return $known[$normalized];
$usdt = EthAddress::normalize((string) config($this->configPrefix().'.usdt_contract', ''));
$decimals = (int) config($this->configPrefix().'.usdt_decimals', 6);
if ($normalized !== '' && $usdt !== '' && $normalized === $usdt && $decimals > 0) {
return $decimals;
}
return max(1, (int) config('coruna.eth.usdt_decimals', 6));
return max(1, $decimals > 0 ? $decimals : 6);
}
private function toTokenUnits(string $amount, int $decimals): string
@@ -248,7 +246,7 @@ class EthDriver implements ChainDriver
private function rpc(string $method, array $params): mixed
{
$url = rtrim((string) config('coruna.eth.rpc_url', 'https://ethereum.publicnode.com'), '/');
$url = rtrim((string) config($this->configPrefix().'.rpc_url', 'https://ethereum.publicnode.com'), '/');
$resp = $this->http()->post($url, [
'jsonrpc' => '2.0',
'id' => 1,
@@ -256,15 +254,15 @@ class EthDriver implements ChainDriver
'params' => $params,
]);
if (! $resp->successful()) {
throw new RuntimeException('ETH RPC HTTP '.$resp->status());
throw new RuntimeException(strtoupper($this->chainId()).' RPC HTTP '.$resp->status());
}
$json = $resp->json();
if (! is_array($json)) {
throw new RuntimeException('Invalid ETH RPC response');
throw new RuntimeException('Invalid '.strtoupper($this->chainId()).' RPC response');
}
if (isset($json['error'])) {
$msg = $json['error']['message'] ?? json_encode($json['error']);
throw new RuntimeException('ETH RPC: '.(is_string($msg) ? $msg : 'error'));
throw new RuntimeException(strtoupper($this->chainId()).' RPC: '.(is_string($msg) ? $msg : 'error'));
}
return $json['result'] ?? null;