Walrus Publisherは、データの保存準備、ストレージ料金の支払い、およびWalrusネットワークとのトランザクション管理を担当します。
BLOBの保存
BLOBをWalrusネットワークに追加します。BLOBデータはリクエストボディで送信されます。Publisherがデータの保存準備、ストレージ料金の支払い、Walrusネットワークとのトランザクション管理を行います。ベースURL
https://walrus-mainnet-publisher.nami.cloud/${endpoint_key}/
${endpoint_key}は、あなた専用のエンドポイントキーです。
クエリパラメータ
BLOBを保存するストレージエポック数(デフォルト: 1)
BLOBオブジェクトを送信するSuiアドレス
BLOBを削除可能として保存するかどうか(デフォルト: false)
リクエスト例
# 1エポック分のストレージで文字列を保存
curl -X PUT "https://walrus-mainnet-publisher.nami.cloud/${endpoint_key}/v1/blobs" \
-d "some string"
# 5エポック分のストレージでファイルを保存
curl -X PUT "https://walrus-mainnet-publisher.nami.cloud/${endpoint_key}/v1/blobs?epochs=5" \
--upload-file "some/file"
# ファイルを保存し、BLOBオブジェクトを特定のアドレスに送信
curl -X PUT "https://walrus-mainnet-publisher.nami.cloud/${endpoint_key}/v1/blobs?send_object_to=${ADDRESS}" \
--upload-file "some/file"
# ファイルを削除可能なBLOBとして保存
curl -X PUT "https://walrus-mainnet-publisher.nami.cloud/${endpoint_key}/v1/blobs?deletable=true" \
--upload-file "some/file"
import requests
# エンドポイントキーを設定
endpoint_key = "your_endpoint_key"
publisher_url = f"https://walrus-mainnet-publisher.nami.cloud/{endpoint_key}/v1/blobs"
# 文字列を保存
response = requests.put(publisher_url, data="some string")
print(response.json())
# 5エポック分のファイルを保存
with open("some/file", "rb") as file:
response = requests.put(f"{publisher_url}?epochs=5", data=file)
print(response.json())
// 文字列を保存
fetch(`https://walrus-mainnet-publisher.nami.cloud/${endpoint_key}/v1/blobs`, {
method: 'PUT',
body: 'some string'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// 5エポック分のファイルを保存
const fs = require('fs');
const fileData = fs.readFileSync('some/file');
fetch(`https://walrus-mainnet-publisher.nami.cloud/${endpoint_key}/v1/blobs?epochs=5`, {
method: 'PUT',
body: fileData
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
package main
import (
"fmt"
"log"
"os"
"github.com/namihq/walrus-go"
)
func main() {
// デフォルトエンドポイントで新しいクライアントを作成
client := walrus.NewClient()
// またはカスタムエンドポイントを指定
// client := walrus.NewClient(
// walrus.WithPublisherURLs([]string{"https://walrus-mainnet-publisher.nami.cloud/your-endpoint-key"}),
// )
// 例1: バイト配列を保存
data := []byte("Hello, Walrus!")
resp, err := client.Store(data, &walrus.StoreOptions{
Epochs: 5, // 5エポック保存
})
if err != nil {
log.Fatalf("データ保存エラー: %v", err)
}
// blobIdは後でデータ取得に利用可能
if resp.NewlyCreated != nil {
fmt.Printf("新しいBLOBを保存しました。ID: %s\n", resp.NewlyCreated.BlobObject.BlobId)
fmt.Printf("ストレージコスト: %d\n", resp.NewlyCreated.Cost)
} else if resp.AlreadyCertified != nil {
fmt.Printf("既存のBLOBが存在します。ID: %s\n", resp.AlreadyCertified.BlobId)
fmt.Printf("有効期限エポック: %d\n", resp.AlreadyCertified.EndEpoch)
}
// 例2: ファイルを保存
filePath := "example.txt"
fileResp, err := client.StoreFile(filePath, &walrus.StoreOptions{
Epochs: 10, // 10エポック保存
})
if err != nil {
log.Fatalf("ファイル保存エラー: %v", err)
}
if fileResp.NewlyCreated != nil {
fmt.Printf("ファイルを保存しました。BLOB ID: %s\n", fileResp.NewlyCreated.BlobObject.BlobId)
}
// 例3: URLから保存
urlResp, err := client.StoreFromURL("https://example.com/sample.jpg", &walrus.StoreOptions{
Epochs: 3,
})
if err != nil {
log.Fatalf("URLからの保存エラー: %v", err)
}
if urlResp.NewlyCreated != nil {
fmt.Printf("URLコンテンツを保存しました。BLOB ID: %s\n", urlResp.NewlyCreated.BlobObject.BlobId)
}
// 例4: 暗号化して保存
encryptedResp, err := client.Store([]byte("Secret data"), &walrus.StoreOptions{
Epochs: 5,
Encryption: &walrus.EncryptionOptions{
Key: []byte("a-32-byte-key-for-aes-256-encryption"), // AES-256用32バイト
},
})
if err != nil {
log.Fatalf("暗号化データ保存エラー: %v", err)
}
if encryptedResp.NewlyCreated != nil {
fmt.Printf("暗号化データを保存しました。BLOB ID: %s\n", encryptedResp.NewlyCreated.BlobObject.BlobId)
}
}
レスポンス - 新規作成BLOB
BLOBが初めて保存された場合、newlyCreatedフィールドに新しいBLOBの情報が含まれます:
{
"newlyCreated": {
"blobObject": {
"id": "0xe91eee8c5b6f35b9a250cfc29e30f0d9e5463a21fd8d1ddb0fc22d44db4eac50",
"registeredEpoch": 34,
"blobId": "M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk",
"size": 17,
"encodingType": "RS2",
"certifiedEpoch": 34,
"storage": {
"id": "0x4748cd83217b5ce7aa77e7f1ad6fc5f7f694e26a157381b9391ac65c47815faf",
"startEpoch": 34,
"endEpoch": 35,
"storageSize": 66034000
},
"deletable": false
},
"resourceOperation": {
"registerFromScratch": {
"encodedLength": 66034000,
"epochsAhead": 1
}
},
"cost": 132300
}
}
レスポンス - 既に認証済みのBLOB
Publisherが同じBLOB IDかつ有効期間が十分な認証済みBLOBを見つけた場合、alreadyCertified JSON構造が返されます:
{
"alreadyCertified": {
"blobId": "M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk",
"event": {
"txDigest": "4XQHFa9S324wTzYHF3vsBSwpUZuLpmwTHYMFv9nsttSs",
"eventSeq": "0"
},
"endEpoch": 35
}
}
eventフィールドは、Sui Blobオブジェクトを作成したトランザクションをSui ExplorerやSui SDKで検索するために利用できるSuiイベントIDを返します。