added testing tool

This commit is contained in:
viraladmin 2026-07-27 16:24:47 -06:00
parent 6cdb3da101
commit e0caa14fc5
2 changed files with 144 additions and 0 deletions

View File

@ -106,6 +106,51 @@ const result = await response.json();
The wallet can generate the handshake proof when it is unlocked and reuse it The wallet can generate the handshake proof when it is unlocked and reuse it
for later API calls. It does not send its private key or wallet decryption key. for later API calls. It does not send its private key or wallet decryption key.
### Test Tool
The CLI-only test tool sends an existing wallet handshake proof through the
same headers a browser wallet will use. Set the credentials in the current
shell:
```bash
export CONTRACTLESS_TEST_ADDRESS="$(jq -r '.short_address' /path/to/wallet)"
export CONTRACTLESS_TEST_PUBLIC_KEY="$(jq -r '.public_key' /path/to/wallet)"
```
Generate the handshake signature with the Contractless `sign_message` tool:
```bash
./sign_message "aced"
```
Enter the same wallet path and decryption key. Copy only the hexadecimal value
printed after `signature:`:
```bash
export CONTRACTLESS_TEST_SIGNATURE='1332-character-signature-from-sign-message'
```
`sign_message` and the node handshake both sign the Skein-256 hash of the exact
text `aced`, so this produces the proof expected by the API.
Then test the default `/api/v1/height` route:
```bash
php tools/test_api.php https://api.contractless.dev
```
An alternative GET route may be provided:
```bash
php tools/test_api.php \
https://api.contractless.dev \
/api/v1/network
```
The tool never accepts or loads a private key. It tests the exact public proof
that applications will submit to the API and returns a nonzero exit status
when the HTTP request fails.
## Initial Endpoints ## Initial Endpoints
All responses use JSON. Successful responses contain `success: true` and a All responses use JSON. Successful responses contain `success: true` and a

99
tools/test_api.php Normal file
View File

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') {
http_response_code(404);
exit;
}
$baseUrl = rtrim((string) ($argv[1] ?? ''), '/');
$address = strtolower(trim(
(string) (getenv('CONTRACTLESS_TEST_ADDRESS') ?: ''),
));
$publicKey = strtolower(trim(
(string) (getenv('CONTRACTLESS_TEST_PUBLIC_KEY') ?: ''),
));
$signature = strtolower(trim(
(string) (getenv('CONTRACTLESS_TEST_SIGNATURE') ?: ''),
));
$route = (string) ($argv[2] ?? '/api/v1/height');
if (
$baseUrl === ''
|| filter_var($baseUrl, FILTER_VALIDATE_URL) === false
|| !str_starts_with($baseUrl, 'https://')
) {
fwrite(
STDERR,
"Usage: php tools/test_api.php https://api.example.com [/api/v1/route]\n",
);
exit(1);
}
if (!str_starts_with($route, '/api/v1')) {
fwrite(STDERR, "The test route must begin with /api/v1.\n");
exit(1);
}
if (preg_match('/^[a-f0-9]{40}\.(clc|cltc)$/', $address) !== 1) {
fwrite(STDERR, "Set CONTRACTLESS_TEST_ADDRESS to a canonical wallet address.\n");
exit(1);
}
if (
preg_match('/^(?:[a-f0-9]{1794}|[a-f0-9]{1796})$/', $publicKey) !== 1
) {
fwrite(
STDERR,
"Set CONTRACTLESS_TEST_PUBLIC_KEY to the wallet's Falcon public-key hex.\n",
);
exit(1);
}
if (preg_match('/^[a-f0-9]{1332}$/', $signature) !== 1) {
fwrite(
STDERR,
"Set CONTRACTLESS_TEST_SIGNATURE to the Falcon handshake signature hex.\n",
);
exit(1);
}
try {
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => implode("\r\n", [
'Accept: application/json',
'X-Contractless-Address: ' . $address,
'X-Contractless-Public-Key: ' . $publicKey,
'X-Contractless-Signature: ' . $signature,
]),
'ignore_errors' => true,
'timeout' => 20,
],
]);
$body = file_get_contents($baseUrl . $route, false, $context);
if ($body === false) {
throw new RuntimeException('The API request could not be completed.');
}
$responseHeaders = $http_response_header ?? [];
$statusLine = (string) ($responseHeaders[0] ?? '');
if (preg_match('/\s(\d{3})\s/', $statusLine, $match) !== 1) {
throw new RuntimeException('The API returned an invalid HTTP response.');
}
$status = (int) $match[1];
echo "HTTP $status\n";
try {
$decoded = json_decode($body, true, flags: JSON_THROW_ON_ERROR);
echo json_encode(
$decoded,
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR,
) . PHP_EOL;
} catch (JsonException) {
echo $body . PHP_EOL;
}
exit($status >= 200 && $status < 300 ? 0 : 1);
} catch (Throwable $error) {
fwrite(STDERR, 'API test failed: ' . $error->getMessage() . PHP_EOL);
exit(1);
}