Skip to content
Open
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: 20 additions & 2 deletions src/Rpc/HttpHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public function processCall(RpcRequest $params): RpcResponse
{
$curl = curl_init($this->url);

if ($curl === false) {
throw new \RuntimeException('Failed to initialize cURL');
}

$headers = [
'Accept: application/json',
'Content-type: application/json'
Expand All @@ -34,8 +38,22 @@ public function processCall(RpcRequest $params): RpcResponse
curl_setopt($curl, CURLOPT_POSTFIELDS, $params->toJson());

$rawResponse = curl_exec($curl);
curl_close($curl);

return RpcResponse::fromArray(json_decode($rawResponse, true));
if ($rawResponse === false) {
$error = curl_error($curl);
throw new \RuntimeException('cURL request failed: ' . $error);
}

if (!is_string($rawResponse)) {
throw new \RuntimeException('Unexpected response type from cURL');
}

$decoded = json_decode($rawResponse, true);

if (!is_array($decoded)) {
throw new \RuntimeException('Invalid JSON response from RPC server: ' . $rawResponse);
}

return RpcResponse::fromArray($decoded);
}
}
45 changes: 27 additions & 18 deletions src/Rpc/ResultTypes/InfoGetStatusResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class InfoGetStatusResult extends AbstractResult

private string $chainSpecName;

private MinimalBlockInfo $lastAddedBlockInfo;
private ?MinimalBlockInfo $lastAddedBlockInfo;

private ?NextUpgrade $nextUpgrade;

Expand Down Expand Up @@ -46,23 +46,27 @@ class InfoGetStatusResult extends AbstractResult

public static function fromJSON(array $json): self
{
$lastAddedBlockInfo = isset($json['last_added_block_info'])
? MinimalBlockInfoSerializer::fromJSON($json['last_added_block_info'])
: null;

return new self(
$json,
$json['protocol_version'],
$json['build_version'],
$json['chainspec_name'],
MinimalBlockInfoSerializer::fromJSON($json['last_added_block_info']),
$json['next_upgrade'] ? NextUpgradeSerializer::fromJSON($json['next_upgrade']) : null,
$json['our_public_signing_key'],
PeerSerializer::fromJsonArray($json['peers']),
$json['round_length'],
$json['starting_state_root_hash'],
$json['uptime'],
$json['reactor_state'],
new \DateTime($json['last_progress']),
$json['latest_switch_block_hash'],
$json['available_block_ranges'],
$json['block_sync']
$json['protocol_version'] ?? $json['api_version'] ?? '',
$json['build_version'] ?? '',
$json['chainspec_name'] ?? '',
$lastAddedBlockInfo,
isset($json['next_upgrade']) ? NextUpgradeSerializer::fromJSON($json['next_upgrade']) : null,
$json['our_public_signing_key'] ?? '',
isset($json['peers']) ? PeerSerializer::fromJsonArray($json['peers']) : [],
$json['round_length'] ?? '',
$json['starting_state_root_hash'] ?? '',
$json['uptime'] ?? '',
$json['reactor_state'] ?? '',
isset($json['last_progress']) ? new \DateTime($json['last_progress']) : new \DateTime(),
$json['latest_switch_block_hash'] ?? '',
$json['available_block_ranges'] ?? $json['available_block_range'] ?? null,
$json['block_sync'] ?? []
);
}

Expand All @@ -71,7 +75,7 @@ public function __construct(
string $protocolVersion,
string $buildVersion,
string $chainSpecName,
MinimalBlockInfo $lastAddedBlockInfo,
?MinimalBlockInfo $lastAddedBlockInfo,
?NextUpgrade $nextUpgrade,
string $outPublicSigningKey,
array $peers,
Expand Down Expand Up @@ -118,7 +122,7 @@ public function getChainSpecName(): string
return $this->chainSpecName;
}

public function getLastAddedBlockInfo(): MinimalBlockInfo
public function getLastAddedBlockInfo(): ?MinimalBlockInfo
{
return $this->lastAddedBlockInfo;
}
Expand All @@ -133,6 +137,11 @@ public function getOutPublicSigningKey(): string
return $this->outPublicSigningKey;
}

public function getOurPublicSigningKey(): string
{
return $this->outPublicSigningKey;
}

public function getPeers(): array
{
return $this->peers;
Expand Down
4 changes: 2 additions & 2 deletions src/Rpc/RpcClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ public function getLatestBlockTransfers(): ChainGetBlockTransfersResult
/**
* @throws RpcError
*/
public function getBlockTransfersByHash(string $blockHash = null): ChainGetBlockTransfersResult
public function getBlockTransfersByHash(?string $blockHash = null): ChainGetBlockTransfersResult
{
$result = $this->processRequest(
self::RPC_METHOD_CHAIN_GET_BLOCK_TRANSFERS,
Expand All @@ -645,7 +645,7 @@ public function getBlockTransfersByHash(string $blockHash = null): ChainGetBlock
/**
* @throws RpcError
*/
public function getBlockTransfersByHeight(int $blockHeight = null): ChainGetBlockTransfersResult
public function getBlockTransfersByHeight(?int $blockHeight = null): ChainGetBlockTransfersResult
{
$result = $this->processRequest(
self::RPC_METHOD_CHAIN_GET_BLOCK_TRANSFERS,
Expand Down
2 changes: 1 addition & 1 deletion src/Rpc/RpcError.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class RpcError extends \Exception
{
public function __construct($message = "", $code = 0, Throwable $previous = null)
public function __construct($message = "", $code = 0, ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
Expand Down
16 changes: 12 additions & 4 deletions src/Rpc/RpcResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@ public static function fromArray(array $data): self
$response->result = $data['result'] ?? null;

if ($response->result === null || isset($data['error'])) {
$response->error = new RpcError(
$data['error']['message'] ?? $data['message'] ?? 'Empty response',
$data['error']['code'] ?? 0
);
$errorMessage = $data['error']['message'] ?? $data['message'] ?? 'Empty response';
$errorCode = $data['error']['code'] ?? 0;

if (isset($data['error']['data'])) {
$errorData = $data['error']['data'];
if (is_array($errorData) || is_object($errorData)) {
$errorData = json_encode($errorData);
}
$errorMessage .= '. Data: ' . $errorData;
}

$response->error = new RpcError($errorMessage, $errorCode);
}

return $response;
Expand Down
4 changes: 2 additions & 2 deletions src/Rpc/SpeculativeClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __construct(Handler $handler)
/**
* @throws RpcError
*/
public function speculativeExecByBlockHash(Deploy $signedDeploy, string $blockHash = null): SpeculativeExecResult
public function speculativeExecByBlockHash(Deploy $signedDeploy, ?string $blockHash = null): SpeculativeExecResult
{
$params = array(
'deploy' => DeploySerializer::toJson($signedDeploy)
Expand All @@ -39,7 +39,7 @@ public function speculativeExecByBlockHash(Deploy $signedDeploy, string $blockHa
/**
* @throws RpcError
*/
public function speculativeExecByBlockHeight(Deploy $signedDeploy, int $blockHeight = null): SpeculativeExecResult
public function speculativeExecByBlockHeight(Deploy $signedDeploy, ?int $blockHeight = null): SpeculativeExecResult
{
$params = array(
'deploy' => DeploySerializer::toJson($signedDeploy)
Expand Down
9 changes: 8 additions & 1 deletion src/Types/CLValue/CLPublicKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ final class CLPublicKey extends CLValue
/**
* @throws \Exception
*/
public function __construct(array $rawPublicKey, CLPublicKeyTag $tag)
public function __construct(array $rawPublicKey, $tag)
{
if (is_int($tag)) {
$tag = new CLPublicKeyTag($tag);
}
if (!$tag instanceof CLPublicKeyTag) {
throw new \InvalidArgumentException('Invalid public key tag type');
}

$this->assertRawPublicKeyLengthIsValid($rawPublicKey, $tag);
$this->data = $rawPublicKey;
$this->tag = $tag;
Expand Down
6 changes: 3 additions & 3 deletions src/Types/DeployExecutable.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static function newStandardPayment($amount): DeployExecutableModuleBytes
return self::newModuleBytes('', [new NamedArg('amount', new CLU512($amount))]);
}

public static function newTransfer($id, $amount, $target, CLURef $sourcePurse = null): DeployExecutableTransfer
public static function newTransfer($id, $amount, $target, ?CLURef $sourcePurse = null): DeployExecutableTransfer
{
if (!in_array(get_class($target), [CLURef::class, CLPublicKey::class])) {
throw new \Exception('Please specify target');
Expand Down Expand Up @@ -63,7 +63,7 @@ public static function newStoredContractPackageByHash(
string $entrypoint,
array $args,
string $hexContractPackageHash,
int $version = null
?int $version = null
): DeployExecutableStoredVersionedContractByHash {
return (new DeployExecutableStoredVersionedContractByHash($hexContractPackageHash, $entrypoint, $version))
->setArgs($args);
Expand All @@ -73,7 +73,7 @@ public static function newStoredContractPackageByName(
string $entrypoint,
array $args,
string $contractPackageAlias,
int $version = null
?int $version = null
): DeployExecutableStoredVersionedContractByName {
return (new DeployExecutableStoredVersionedContractByName($contractPackageAlias, $entrypoint, $version))
->setArgs($args);
Expand Down
2 changes: 1 addition & 1 deletion src/Types/DeployParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function __construct(
int $gasPrice = self::DEFAULT_GAS_PRICE,
int $ttl = self::DEFAULT_TTL,
array $dependencies = [],
int $timestamp = null
?int $timestamp = null
)
{
$this->accountPublicKey = $accountPublicKey;
Expand Down
51 changes: 47 additions & 4 deletions src/Types/Serializer/DelegatorSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@

class DelegatorSerializer extends JsonSerializer
{
private static function normalizePublicKey($value): ?string
{
if (is_string($value)) {
return $value;
}
if (is_array($value)) {
return $value['PublicKey'] ?? $value['public_key'] ?? null;
}

return null;
}

/**
* @param Delegator $delegator
*/
Expand All @@ -23,11 +35,42 @@ public static function toJson($delegator): array

public static function fromJson(array $json): Delegator
{
$publicKeyHex = self::normalizePublicKey($json['public_key'] ?? $json['delegator_public_key'] ?? $json['delegator'] ?? null);
$delegateeHex = self::normalizePublicKey($json['delegatee'] ?? $json['validator_public_key'] ?? $json['validator'] ?? null);
$stakedAmount = $json['staked_amount'] ?? $json['bonding_amount'] ?? '0';
$bondingPurse = $json['bonding_purse'] ?? $json['bonding_purse_uref'] ?? null;

if (is_array($bondingPurse)) {
$bondingPurse = $bondingPurse['URef'] ?? $bondingPurse['uref'] ?? null;
}

if (null === $publicKeyHex || null === $delegateeHex || '' === $bondingPurse) {
throw new \RuntimeException('Invalid delegator data: missing required fields');
}

return new Delegator(
CLPublicKey::fromHex($json['public_key']),
gmp_init($json['staked_amount']),
CLURef::fromString($json['bonding_purse']),
CLPublicKey::fromHex($json['delegatee'])
CLPublicKey::fromHex($publicKeyHex),
gmp_init($stakedAmount),
CLURef::fromString($bondingPurse),
CLPublicKey::fromHex($delegateeHex)
);
}

public static function fromJsonArray(array $array): array
{
$result = [];

foreach ($array as $item) {
if (!is_array($item)) {
continue;
}
try {
$result[] = self::fromJson($item);
} catch (\RuntimeException $e) {
continue;
}
}

return $result;
}
}
4 changes: 2 additions & 2 deletions src/Types/Serializer/InitiatorAddrSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public static function toJson($initiatorAddr): array
public static function fromJson(array $json): InitiatorAddr
{
return new InitiatorAddr(
$json['PublicKey'] ? CLPublicKey::fromHex($json['PublicKey']) : null,
$json['AccountHash'] ? CLAccountHash::fromString($json['AccountHash']) : null
isset($json['PublicKey']) ? CLPublicKey::fromHex($json['PublicKey']) : null,
isset($json['AccountHash']) ? CLAccountHash::fromString($json['AccountHash']) : null
);
}
}
5 changes: 4 additions & 1 deletion src/Types/Serializer/TransformSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ public static function toJson($transform): array

public static function fromJson(array $json): Transform
{
return new Transform($json['key'], $json['kind']);
$key = $json['key'] ?? '';
$kind = $json['kind'] ?? ($json['transform'] ?? ($json['value'] ?? null));

return new Transform($key, $kind);
}
}
2 changes: 1 addition & 1 deletion src/Types/SessionTarget.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class SessionTarget
public function __construct(
DeployExecutableModuleBytes $moduleBytes,
TransactionRuntime $runtime,
bool $isInstallUpgrade = null
?bool $isInstallUpgrade = null
)
{
$this->moduleBytes = $moduleBytes;
Expand Down
2 changes: 1 addition & 1 deletion src/Util/Crypto/Secp256K1Key.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class Secp256K1Key extends AsymmetricKey

private PrivateKeyInterface $privateKeyObject;

public function __construct(PrivateKeyInterface $privateKeyObject = null)
public function __construct(?PrivateKeyInterface $privateKeyObject = null)
{
$this->adapter = EccFactory::getAdapter();
$this->generator = EccFactory::getSecgCurves()
Expand Down
Loading