PHP code example of innis / nostr-blossom

1. Go to this page and download the library: Download innis/nostr-blossom library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

innis / nostr-blossom example snippets


use Innis\Nostr\Blossom\Application\Service\BlobDescriptorFactory;
use Innis\Nostr\Blossom\Application\Service\BlobIngestor;
use Innis\Nostr\Blossom\Application\Service\BlobValidator;
use Innis\Nostr\Blossom\Application\Service\BlossomAuthValidator;
use Innis\Nostr\Blossom\Application\Service\TenantBlossomPolicy;
use Innis\Nostr\Blossom\Application\UseCase\UploadBlobUseCase;
use Innis\Nostr\Blossom\Domain\Failure\BlossomFailure;

// $store, $index, $inspector, $clock implement the host ports; $config and
// $signatureService are built as in the Authorisation example below.
$validator = new BlossomAuthValidator($signatureService, $clock, $config->getIdentity());
$policy = new TenantBlossomPolicy($config->getTenantPubkeys());
$ingestor = new BlobIngestor(
    new BlobValidator($inspector, $config->getUploadConstraints(), $validator),
    new BlobDescriptorFactory($config->getIdentity(), $clock),
    $store,
    $index,
);
$upload = new UploadBlobUseCase($validator, $policy, $ingestor);

$result = $upload->execute($authHeader, $pendingBlobSource, $declaredHash);

if ($result instanceof BlossomFailure) {
    http_response_code($result->category()->httpStatus()); // 401/403/413/415/…
    return;
}

echo json_encode($result); // BlobDescriptor: url, sha256, size, type, uploaded, nip94

use Innis\Nostr\Blossom\Application\Service\BlossomAuthValidator;
use Innis\Nostr\Blossom\Application\Service\TenantBlossomPolicy;
use Innis\Nostr\Blossom\Application\UseCase\GetBlobUseCase;
use Innis\Nostr\Blossom\Domain\Failure\BlossomFailure;
use Innis\Nostr\Blossom\Domain\ValueObject\BlobHash;

$hash = BlobHash::tryFromHex($sha256); // ?BlobHash — null unless 64 hex chars
if (null === $hash) {
    http_response_code(404);
    return;
}

// TenantBlossomPolicy defaults to GetAccessPolicy::Public, so reads are public by
// hash; pass a different GetAccessPolicy to gate them. $validator and $config are
// built as in the Authorisation example below.
$validator = new BlossomAuthValidator($signatureService, $clock, $config->getIdentity());
$policy = new TenantBlossomPolicy($config->getTenantPubkeys());
$blob = new GetBlobUseCase($store, $index, $validator, $policy)->execute($hash, $authHeader);
if ($blob instanceof BlossomFailure) {
    http_response_code($blob->category()->httpStatus()); // 404
    return;
}

// $blob is a RetrievedBlob: $blob->getDescriptor() (metadata) + $blob->getPath() (bytes to stream)

$readPolicy = new TenantOwnedBlossomPolicy(
    new TenantBlossomPolicy($config, GetAccessPolicy::Tenant),
    $index,
);

use Innis\Nostr\Blossom\Application\Service\BlossomAuthValidator;
use Innis\Nostr\Blossom\Application\Service\TenantBlossomPolicy;
use Innis\Nostr\Blossom\Domain\Enum\BlossomVerb;
use Innis\Nostr\Blossom\Domain\Failure\BlossomFailure;
use Innis\Nostr\Blossom\Domain\Collection\AllowedMimeTypes;
use Innis\Nostr\Blossom\Domain\ValueObject\BlobHash;
use Innis\Nostr\Blossom\Domain\ValueObject\HttpUrl;
use Innis\Nostr\Blossom\Domain\ValueObject\MimeType;
use Innis\Nostr\Blossom\Domain\ValueObject\ServerConfig;
use Innis\Nostr\Blossom\Domain\ValueObject\ServerIdentity;
use Innis\Nostr\Blossom\Domain\ValueObject\TenantPubkeys;
use Innis\Nostr\Blossom\Domain\ValueObject\UploadConstraints;
use Innis\Nostr\Core\Domain\Entity\Event;
use Innis\Nostr\Core\Domain\ValueObject\Identity\PublicKey;
use Innis\Nostr\Core\Infrastructure\Crypto\Secp256k1Signer;

$signatureService = Secp256k1Signer::create();
$tenant = PublicKey::tryFromHex($tenantPubkeyHex) ?? throw new InvalidArgumentException('invalid tenant pubkey');
$baseUrl = HttpUrl::tryFromString('https://blossom.example.com') ?? throw new InvalidArgumentException('invalid base url');
$config = new ServerConfig(
    new TenantPubkeys([$tenant]),
    new UploadConstraints(
        104857600,
        new AllowedMimeTypes(array_map(
            static fn (string $type): MimeType => MimeType::tryFromString($type) ?? throw new InvalidArgumentException('invalid allowed mime type'),
            ['image/png', 'image/jpeg'],
        )),
    ),
    new ServerIdentity($baseUrl),
);

// Each collaborator is wired from the slice it needs (see ADR-0020).
$validator = new BlossomAuthValidator($signatureService, $clock, $config->getIdentity());
$policy = new TenantBlossomPolicy($config->getTenantPubkeys());

// A use case sequences these for you; this is the shape it follows.
$event = $validator->parse(BlossomVerb::Upload, $authHeader);
if ($event instanceof BlossomFailure) {
    // $event->category()->httpStatus() gives the BUD-appropriate status code
}

$denied = $policy->allowUpload($event->getPubkey())  // cheap admission first
    ?? $validator->verify($event);                   // then the secp256k1 check
if (null !== $denied) {
    // $denied->category()->httpStatus()
}

// $event is now authenticated and authorised
$blob = BlobHash::tryFromHex($sha256) ?? throw new InvalidArgumentException('invalid hash');
if (null !== $validator->