| 
<?phpdeclare(strict_types=1);
 
 use ParagonIE\Chronicle\Chronicle;
 use ParagonIE\EasyDB\{
 EasyDB,
 Factory
 };
 use ParagonIE\Sapient\CryptographyKeys\SigningPublicKey;
 use ParagonIE\ConstantTime\Base64UrlSafe;
 
 $root = \dirname(__DIR__);
 /** @psalm-suppress UnresolvableInclude */
 require_once $root . '/cli-autoload.php';
 
 /** @var int $argc */
 /** @var array<int, string> $v */
 $v = $argv; // Seriously, Psalm?
 
 if ($argc < 2) {
 echo 'Usage: ', PHP_EOL , "\t",
 'php write_file.php /path/to/input_file [/path/to/keyfile]', PHP_EOL;
 exit(1);
 }
 
 $filePath = $v[1];
 $keyFilePath = ($argc > 2
 ? $v[2]
 : $root . '/local/client.key'
 );
 
 if (!\is_readable($root . '/local/settings.json')) {
 echo 'Settings are not loaded.', PHP_EOL;
 exit(1);
 }
 
 /** @var array<string, string> $settings */
 $settings = \json_decode(
 (string) \file_get_contents($root . '/local/settings.json'),
 true
 );
 
 $db = Factory::create(
 $settings['database']['dsn'],
 $settings['database']['username'] ?? '',
 $settings['database']['password'] ?? '',
 $settings['database']['options'] ?? []
 );
 Chronicle::setDatabase($db);
 
 if (!\is_readable($filePath)) {
 echo 'File not readable (or doesn\'t exist): ', $filePath, PHP_EOL;
 exit(1);
 }
 if (!\is_readable($keyFilePath)) {
 echo 'Key file not readable (or doesn\'t exist): ', $keyFilePath, PHP_EOL;
 exit(1);
 }
 
 /** @var string $fileContents */
 $fileContents = \file_get_contents($filePath);
 
 /** @var array $keyFile */
 $keyFile = \json_decode(
 (string) \file_get_contents($keyFilePath),
 true
 );
 
 $signature = \sodium_crypto_sign_detached(
 $fileContents,
 Base64UrlSafe::decode($keyFile['secret-key'])
 );
 
 Chronicle::extendBlakechain(
 $fileContents,
 Base64UrlSafe::encode($signature),
 new SigningPublicKey(Base64UrlSafe::decode($keyFile['public-key']))
 );
 
 |