lthn.io/app/Mod/Chain/Services/WalletRpc.php
Claude b4e4766e01
feat: HealthCheckable interface on DaemonRpc and WalletRpc
Services implement healthCheck() returning {status, detail, stale?}.
Status page refactored to use healthCheck() instead of ad-hoc checks.
Statuses: healthy, degraded (stale data), unhealthy (unreachable).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 11:43:01 +01:00

117 lines
3 KiB
PHP

<?php
declare(strict_types=1);
namespace Mod\Chain\Services;
use Illuminate\Support\Facades\Http;
/**
* $wallet = app(WalletRpc::class);
* $wallet->registerAlias('myname', $address, 'v=lthn1;type=user');
*/
class WalletRpc implements \Mod\Chain\Contracts\ChainWallet, \Mod\Chain\Contracts\HealthCheckable
{
private string $endpoint;
public function __construct()
{
$this->endpoint = config('chain.wallet_rpc', 'http://127.0.0.1:46944/json_rpc');
}
/**
* $result = $wallet->getAddress();
* // 'iTHNHN11xMe...'
*/
public function getAddress(): string
{
$result = $this->call('getaddress');
return $result['address'] ?? '';
}
/**
* $balance = $wallet->getBalance();
* // ['balance' => 1000000000000, 'unlocked_balance' => 1000000000000]
*/
public function getBalance(): array
{
return $this->call('getbalance');
}
/**
* $result = $wallet->registerAlias('myname', $address, 'v=lthn1;type=user');
* // ['status' => 'OK', 'tx_id' => 'abc123...']
*/
public function registerAlias(string $alias, string $address, string $comment = ''): array
{
return $this->call('register_alias', [
'al' => [
'alias' => strtolower(trim($alias)),
'address' => $address,
'comment' => $comment,
],
]);
}
/**
* $result = $wallet->updateAlias('myname', $address, 'v=lthn1;type=gateway');
*/
public function updateAlias(string $alias, string $address, string $comment = ''): array
{
return $this->call('update_alias', [
'al' => [
'alias' => strtolower(trim($alias)),
'address' => $address,
'comment' => $comment,
],
]);
}
/**
* $result = $wallet->call('get_recent_txs_and_info', [...]);
*/
public function call(string $method, array $params = []): array
{
$payload = [
'jsonrpc' => '2.0',
'id' => '0',
'method' => $method,
];
if ($params) {
$payload['params'] = $params;
}
try {
$response = Http::timeout(15)
->accept('application/json')
->post($this->endpoint, $payload);
} catch (\Throwable $e) {
return ['error' => 'Wallet RPC unreachable'];
}
if ($response->failed()) {
return ['error' => 'Wallet RPC unreachable'];
}
$data = $response->json();
return $data['result'] ?? $data['error'] ?? [];
}
public function healthCheck(): array
{
try {
$balance = $this->getBalance();
if (isset($balance['error'])) {
return ['status' => 'unhealthy', 'detail' => 'Unreachable'];
}
return ['status' => 'healthy', 'detail' => 'Connected'];
} catch (\Throwable $e) {
return ['status' => 'unhealthy', 'detail' => 'Unreachable'];
}
}
}