Skip to content

refactor: api endpoints & connection handling #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions src/API/AbstractAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,29 @@

namespace ArkEcosystem\Client\API;

use ArkEcosystem\Client\ArkClient;
use ArkEcosystem\Client\Connection;
use ArkEcosystem\Client\Contracts\API;
use ArkEcosystem\Client\Http\Request;
use GuzzleHttp\Client;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

abstract class AbstractAPI
{
/**
* The client .
* The connection.
*
* @var ArkClient
* @var Connection
*/
public $client;
public $connection;

private string $api = 'api';

/**
* Create a new API class instance.
*
* @param Connection $client
* @param Connection $connection
*/
public function __construct(ArkClient $client)
public function __construct(Connection $connection)
{
$this->client = $client;
$this->connection = $connection;
}

/**
Expand All @@ -43,7 +39,7 @@ public function __construct(ArkClient $client)
*/
protected function requestGet(string $path, array $query = [])
{
$response = $this->client->getHttpClient()->get($this->buildUrl($path), [
$response = $this->connection->getHttpClient()->get($this->buildUrl($path), [
'query' => Arr::dot($query),
]);

Expand All @@ -60,7 +56,7 @@ protected function requestGet(string $path, array $query = [])
*/
protected function requestPost(string $path, array $parameters = [])
{
$response = $this->client->getHttpClient()->post(
$response = $this->connection->getHttpClient()->post(
$this->buildUrl($path),
['json' => $parameters]
);
Expand All @@ -77,7 +73,7 @@ protected function withApi(string $api): self

private function buildUrl(string $path): string
{
$baseUri = $this->client->getHosts()[$this->api];
$baseUri = $this->connection->getHosts()[$this->api];

// Reset the API to the default value.
$this->api = 'api';
Expand Down
196 changes: 66 additions & 130 deletions src/ArkClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,162 +4,98 @@

namespace ArkEcosystem\Client;

use BadMethodCallException;
use GuzzleHttp\Client;
use ArkEcosystem\Client\API\ApiNodes;
use ArkEcosystem\Client\API\Blockchain;
use ArkEcosystem\Client\API\Blocks;
use ArkEcosystem\Client\API\Commits;
use ArkEcosystem\Client\API\Contracts;
use ArkEcosystem\Client\API\EVM;
use ArkEcosystem\Client\API\Node;
use ArkEcosystem\Client\API\Peers;
use ArkEcosystem\Client\API\Receipts;
use ArkEcosystem\Client\API\Rounds;
use ArkEcosystem\Client\API\Transactions;
use ArkEcosystem\Client\API\Validators;
use ArkEcosystem\Client\API\Votes;
use ArkEcosystem\Client\API\Wallets;
use GuzzleHttp\HandlerStack;
use Illuminate\Support\Arr;
use RuntimeException;

/**
* This is the connection class.
*/
class ArkClient
{
/**
* The Guzzle Client instance.
*
* @var Client
*/
public $httpClient;

/**
* The hosts to connect to.
*
* @var array{
* api: string,
* transactions: string|null,
* evm: string|null
* }
*/
private array $hosts;

/**
* Make a new connection instance.
*
* @param string|array{
* api: string,
* transactions: string|null,
* evm: string|null
* } $hostOrHosts
* @param array $clientConfig
* @param HandlerStack $handler
*
* @throws InvalidArgumentException if $hostOrHosts is an array and does not have the required format
*/
public function __construct(array|string $hostOrHosts, array $clientConfig = [], ?HandlerStack $handler = null)
public Connection $connection;

public function __construct(string|array $hostOrHosts, array $clientConfig = [], ?HandlerStack $handler = null)
{
$this->validateHosts($hostOrHosts);

if (is_array($hostOrHosts)) {
$this->hosts = $hostOrHosts;
} else {
$this->hosts = ['api' => $hostOrHosts];
}

$options = [
...$clientConfig,
'headers' => [
...Arr::get($clientConfig, 'headers', []),
'Content-Type' => 'application/json',
],
];

if ($handler instanceof HandlerStack) {
$options['handler'] = $handler;
}

$this->httpClient = new Client($options);
$this->connection = new Connection($hostOrHosts, $clientConfig, $handler);
}

/**
* Handle dynamic method calls into the connection.
*
* @param string $name
* @param mixed $args
*
* @throws BadMethodCallException
*
* @return ApiInterface
*/
public function __call($name, $args)
public function apiNodes(): ApiNodes
{
try {
return $this->api($name);
} catch (RuntimeException $e) {
throw new BadMethodCallException(sprintf('Undefined method called: "%s"', $name));
}
return new ApiNodes($this->connection);
}

/**
* Set the host for the given type.
*
* @param string $host
* @param string $type
*
* @throws InvalidArgumentException if the type is not 'api', 'transactions', or 'evm'
*/
public function setHost(string $host, string $type): void
public function blockchain(): Blockchain
{
if (! in_array($type, ['api', 'transactions', 'evm'], true)) {
throw new \InvalidArgumentException('Invalid host type.');
}
return new Blockchain($this->connection);
}

$this->hosts[$type] = $host;
public function blocks(): Blocks
{
return new Blocks($this->connection);
}

/**
* @return array{
* api: string,
* transactions: string|null,
* evm: string|null
* }
*/
public function getHosts(): array
public function commits(): Commits
{
return $this->hosts;
return new Commits($this->connection);
}

/**
* Make a new resource instance.
*
* @param string $name
*
* @return API\AbstractAPI
*/
public function api(string $name): API\AbstractAPI
public function contracts(): Contracts
{
$name = $name === 'evm' ? 'EVM' : ucfirst($name);
return new Contracts($this->connection);
}

$class = "ArkEcosystem\\Client\\API\\{$name}";
public function evm(): EVM
{
return new EVM($this->connection);
}

if (! class_exists($class)) {
throw new RuntimeException("Class [$class] does not exist.");
}
public function node(): Node
{
return new Node($this->connection);
}

public function peers(): Peers
{
return new Peers($this->connection);
}

return new $class($this);
public function receipts(): Receipts
{
return new Receipts($this->connection);
}

public function rounds(): Rounds
{
return new Rounds($this->connection);
}

public function transactions(): Transactions
{
return new Transactions($this->connection);
}

public function validators(): Validators
{
return new Validators($this->connection);
}

/**
* Get the Guzzle client instance.
*
* @return Client
*/
public function getHttpClient(): Client
public function votes(): Votes
{
return $this->httpClient;
return new Votes($this->connection);
}

/**
* Validate the hosts array format.
*
* @param string|array $hostOrHosts
*
* @throws InvalidArgumentException if the hosts array does not have the required format
*/
private function validateHosts(array|string $hostOrHosts): void
public function wallets(): Wallets
{
if (is_array($hostOrHosts) && ! array_key_exists('api', $hostOrHosts)) {
throw new \InvalidArgumentException(sprintf('The hosts array must contain the key "api".'));
}
return new Wallets($this->connection);
}
}
10 changes: 5 additions & 5 deletions src/ClientManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ class ClientManager
* @param string $host
* @param string $name
*
* @return ArkClient
* @return Connection
*/
public function connect(string $host, string $name = 'main'): ArkClient
public function connect(string $host, string $name = 'main'): Connection
{
if (isset($this->clients[$name])) {
throw new InvalidArgumentException("Client [$name] is already configured.");
}

$this->clients[$name] = new ArkClient($host);
$this->clients[$name] = new Connection($host);

return $this->clients[$name];
}
Expand All @@ -61,9 +61,9 @@ public function disconnect(?string $name = null): void
*
* @param string|null $name
*
* @return ArkClient
* @return Connection
*/
public function client(?string $name = null): ArkClient
public function client(?string $name = null): Connection
{
$name = $name ?? $this->getDefaultClient();

Expand Down
Loading