Skip to content
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
68 changes: 63 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Here’s a basic example of how to use the SDK:

require 'vendor/autoload.php';

use Suicore\Walrus\Responses\StoreBlobOptions;
use Suicore\Walrus\Types\StoreBlobOrQuiltOptions;
use Suicore\Walrus\WalrusClient;


Expand All @@ -37,7 +37,7 @@ $aggregatorUrl = 'https://aggregator.walrus-testnet.walrus.space';
$client = new WalrusClient($publisherUrl, $aggregatorUrl);

// Prepare options for storing a blob
$options = new StoreBlobOptions(epochs: 2);
$options = new StoreBlobOrQuiltOptions(epochs: 2);

// Store a text blob
$storeResponse = $client->storeBlob("Hello, Walrus!", $options);
Expand All @@ -58,15 +58,54 @@ echo "Retrieved content: {$content}\n";
```

### Uploading Files
To upload a file, simply pass the file path to the `storeBlob` method and set the $isFile parameter to `true`:
To upload a blob, simply pass the file path to the `storeBlob` method and set the $isFile parameter to `true`:

```php
// Save a file as a blob
$file = '/path/to/file.txt';
$options = new StoreBlobOptions(epochs: 2);
$options = new StoreBlobOrQuiltOptions(epochs: 2);
$storeResponse = $client->storeBlob(dataOrPath: $file, options: $options, isFile: true);
```

### Uploading a file in a quilt
The SDK supports uploading multiple files as a single quilt using the `storeQuilt` method. Each file can be associated with custom metadata.

```php
use Suicore\Walrus\WalrusClient;
use Suicore\Walrus\Types\StoreBlobOrQuiltOptions;
use Suicore\Walrus\Types\QuiltElementFile;
use Suicore\Walrus\Types\QuiltElementFileMetadata;

$client = new WalrusClient($publisherUrl, $aggregatorUrl);
$options = new StoreBlobOrQuiltOptions(epochs: 2);

$files = [
new QuiltElementFile('wal1.jpg', __DIR__ . '/walrus.jpg'),
new QuiltElementFile('wal2.jpg', fopen(__DIR__ . '/walrus.jpg', 'rb')), // Open resource
];

$metadata = [
new QuiltElementFileMetadata('wal1.jpg', (object)['creator' => 'walrus', 'version' => '1.0']),
new QuiltElementFileMetadata('wal2.jpg', (object)['type' => 'logo', 'format' => 'png']),
];

$storeResponse = $client->storeQuilt($files, $options, $metadata);

$files = $storeResponse->getStoredQuiltBlobs()->getQuiltFiles();
foreach ($files as $file) {
echo "Stored patch ID: " . $file->getQuiltPatchId() . "\n";
}
```

### Retrieving a Quilt Patch or Quilt by name
```php
$patchId = 'quilt-file-patch-id';
$content = $client->getQuilt($patchId);

$blobId = 'quilt-blob-id';
$fileContent = $client->getQuilt($blobId, 'wal1.jpg');
```

### Encryption
The Walrus SDK provides a simple, but secure way to encrypt and decrypt data using the `Aes256Encryptor` class. Here’s an example:
```php
Expand All @@ -89,18 +128,37 @@ A key length of 32 bytes is required for AES-256 encryption. Shorter or longer k

#### storeBlob
Stores a blob using the publisher API.

Parameters:
- `string dataOrPath`: The blob data or file path.
- `StoreBlobOptions $options`: Options such as epochs, sendObjectTo address, and deletability.
- `StoreBlobOrQuiltOptions $options`: Options such as epochs, sendObjectTo address, and deletability.
- `bool $isFile`: Set to true if $dataOrPath is a file path.
- Returns: A StoreBlobResponse object representing the response from the API.

#### getBlob
Retrieves a blob from the aggregator API.

Parameters:
- `string $blobId`: The unique blob identifier.
- Returns: The blob content as a string.

#### storeQuilt
Stores multiple files as a quilt with optional metadata.

Parameters:
- `QuiltFile[] $files`: An array of QuiltFile objects containing identifier and file source.
- `StoreBlobOrQuiltOptions $options`: Storage options.
- `QuiltMetadata[] $metadata`: (Optional) Metadata associated with each file.
- Returns: StoreQuiltResponse

#### getQuilt
Retrieves quilt content from the aggregator.

Parameters:
- `string $blobOrPatchId`: A blob ID (for full quilt) or a patch ID (for specific patch).
- `string|null $filename`: Optional filename to extract a specific file from the quilt.
- Returns: File contents as a string.

### Testing
To run the test suite, use the following commands:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class AlreadyCertifiedEvent
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class AlreadyCertifiedResponse
{
Expand Down
11 changes: 5 additions & 6 deletions src/Responses/BlobObject.php → src/Types/BlobObject.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class BlobObject
{
Expand All @@ -9,7 +9,7 @@ class BlobObject
private string $blobId;
private int $size;
private string $encodingType;
private int $certifiedEpoch;
private int | null $certifiedEpoch;
private Storage $storage;
private bool $deletable;

Expand All @@ -19,7 +19,7 @@ public function __construct(
string $blobId,
int $size,
string $encodingType,
int $certifiedEpoch,
int | null $certifiedEpoch,
Storage $storage,
bool $deletable
) {
Expand All @@ -42,7 +42,6 @@ public static function fromArray(array $data): self
$data['blobId'],
$data['size'],
$data['encodingType'],
$data['certifiedEpoch'],
$data['storage'],
$data['deletable']
)
Expand All @@ -57,7 +56,7 @@ public static function fromArray(array $data): self
$data['blobId'],
(int)$data['size'],
$data['encodingType'],
(int)$data['certifiedEpoch'],
isset($data['certifiedEpoch']) ? (int)$data['certifiedEpoch'] : null,
$storage,
(bool)$data['deletable']
);
Expand All @@ -83,7 +82,7 @@ public function getEncodingType(): string
{
return $this->encodingType;
}
public function getCertifiedEpoch(): int
public function getCertifiedEpoch(): int | null
{
return $this->certifiedEpoch;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class NewlyCreatedResponse
{
Expand Down
33 changes: 33 additions & 0 deletions src/Types/QuiltElement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Suicore\Walrus\Types;

class QuiltElement
{
private string $identifier;
private string $quiltPatchId;

public function __construct(string $identifier, string $quiltPatchId)
{
$this->identifier = $identifier;
$this->quiltPatchId = $quiltPatchId;
}

public static function fromObject(\stdClass $data): self
{
if (!isset($data->identifier, $data->quiltPatchId)) {
throw new \InvalidArgumentException("Invalid data for QuiltElement");
}
return new self($data->identifier, $data->quiltPatchId);
}

public function getIdentifier(): string
{
return $this->identifier;
}

public function getQuiltPatchId(): string
{
return $this->quiltPatchId;
}
}
36 changes: 36 additions & 0 deletions src/Types/QuiltElementFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Suicore\Walrus\Types;

/**
* @property string $identifier
* @property string|resource $source
*/
class QuiltElementFile
{
private string $identifier;

/** @var string|resource */
private $source;

/**
* @param string $identifier
* @param string|resource $source
*/
public function __construct(string $identifier, $source)
{
$this->identifier = $identifier;
$this->source = $source;
}

public function getIdentifier(): string
{
return $this->identifier;
}

/** @return string|resource */
public function getSource()
{
return $this->source;
}
}
37 changes: 37 additions & 0 deletions src/Types/QuiltElementFileMetadata.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Suicore\Walrus\Types;

class QuiltElementFileMetadata
{
private string $identifier;
private array $tags;

public function __construct(string $identifier, array $tags)
{
$this->identifier = $identifier;
$this->tags = $tags;
}

public function getIdentifier(): string
{
return $this->identifier;
}

public function getTags(): array
{
return $this->tags;
}

public function toArray(): array
{
$result = [
'identifier' => $this->identifier
];
if (!empty($this->tags)) {
$result['tags'] = $this->tags;
}

return $result;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class RegisterFromScratch
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class ResourceOperation
{
Expand Down
2 changes: 1 addition & 1 deletion src/Responses/Storage.php → src/Types/Storage.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class Storage
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class StoreBlobOptions
class StoreBlobOrQuiltOptions
{
private int $epochs;
private string $sendObjectTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Suicore\Walrus\Responses;
namespace Suicore\Walrus\Types;

class StoreBlobResponse
{
Expand Down Expand Up @@ -31,6 +31,22 @@ public static function fromJson(string $json): self
return new self($newlyCreated, $alreadyCertified);
}

public static function fromArray(array $data): self
{
if (!isset($data['newlyCreated']) && !isset($data['alreadyCertified'])) {
throw new \InvalidArgumentException("Invalid data for StoreBlobResponse");
}

$newlyCreated = isset($data['newlyCreated'])
? NewlyCreatedResponse::fromArray($data['newlyCreated'])
: null;
$alreadyCertified = isset($data['alreadyCertified'])
? AlreadyCertifiedResponse::fromArray($data['alreadyCertified'])
: null;

return new self($newlyCreated, $alreadyCertified);
}

public function isNewlyCreated(): bool
{
return $this->newlyCreated !== null;
Expand Down
Loading