Skip to content

Сумісність з S3

Використовуйте AWS SDK для завантаження, скачування та керування файлами на IPFS Ninja з тим самим кодом, який ви використовуєте для Amazon S3.

Endpoint

https://s3.ipfs.ninja

Облікові дані

S3 API використовує ваш API-ключ IPFS Ninja для автентифікації. Ваш API-ключ слугує одночасно ключем доступу та секретним ключем.

Як отримати облікові дані

  1. Перейдіть до Dashboard > API Keys
  2. Натисніть Create API key та задайте назву (наприклад, "S3 доступ")
  3. Негайно скопіюйте повний ключ — він показується лише один раз і не може бути відновлений пізніше

Ваш ключ виглядає так:

bws_628bba35e9e0079d9ff9c392b1b55a7b
├──────────┘└──────────────────────────┘
 prefix (12 chars)    rest of key

Відповідність параметрам AWS

Параметр AWSЗначенняПриклад
accessKeyIdПерші 12 символів вашого API-ключаbws_628bba35
secretAccessKeyПовний API-ключ (усі 36 символів)bws_628bba35e9e0079d9ff9c392b1b55a7b
regionЗавжди us-east-1us-east-1

WARNING

Повний API-ключ показується лише один раз під час створення. Якщо ви його втратите, видаліть ключ і створіть новий на сторінці API Keys.

Швидкий старт

javascript
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: "https://s3.ipfs.ninja",
  credentials: {
    accessKeyId: "bws_628bba35",
    secretAccessKey: "bws_628bba35e9e0079d9ff9c392b1b55a7b"
  },
  region: "us-east-1",
  forcePathStyle: true
});

// Upload a file
const put = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "hello.json",
  Body: JSON.stringify({ hello: "IPFS" }),
  ContentType: "application/json"
}));

console.log("CID:", put.Metadata?.cid);
// CID: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

Bucket'и = Папки

S3 bucket'и відповідають вашим папкам IPFS Ninja. Коли ви завантажуєте файл у bucket, він зберігається у відповідній папці. Коли ви переглядаєте об'єкти в bucket'і, ви бачите файли в цій папці.

Операція S3Еквівалент IPFS Ninja
CreateBucketСтворити нову папку
ListBucketsПоказати ваші папки
DeleteBucketВидалити папку та всі файли в ній
PutObject у bucketЗавантажити файл у папку
ListObjectsV2 у bucket'іПоказати файли в папці
javascript
import { ListBucketsCommand, CreateBucketCommand, PutObjectCommand } from "@aws-sdk/client-s3";

// Create a bucket (= create a folder)
await s3.send(new CreateBucketCommand({ Bucket: "nft-metadata" }));

// Upload a file into the folder
await s3.send(new PutObjectCommand({
  Bucket: "nft-metadata",      // ← folder name
  Key: "token-42.json",        // ← filename within the folder
  Body: JSON.stringify({ name: "My NFT #42" })
}));

// List buckets (= list your folders)
const { Buckets } = await s3.send(new ListBucketsCommand({}));
console.log(Buckets);
// [{ Name: "nft-metadata", CreationDate: "2026-04-13T..." }]

TIP

Папки, створені через S3 API, є тими самими папками, що відображаються у вашому Dashboard. Ви можете організовувати файли через S3 API, REST API або веб-інтерфейс — усі вони використовують одну й ту саму систему папок.

INFO

На відміну від Amazon S3, папки IPFS Ninja за замовчуванням плоскі. Для створення вкладених структур використовуйте endpoint'и папок REST API з parentFolderId. Через S3 API використовуйте префікси ключів (наприклад, images/photo.png) для організації всередині папки.

Назви bucket'ів глобально унікальні

Назви bucket'ів існують у глобальному просторі імен серед усіх клієнтів, що відповідає семантиці AWS S3. Це означає:

  • Перший користувач, який створює bucket із заданою назвою, закріплює цю назву глобально.
  • Наступні виклики CreateBucket з тією самою назвою від будь-якого облікового запису повертають BucketAlreadyExists (409).
  • Якщо ви спробуєте повторно створити свій власний bucket, ви отримаєте BucketAlreadyOwnedByYou (409).
  • Назва вашої папки в dashboard прив'язана до облікового запису і може бути якою завгодно — лише видима в S3 назва bucket'а проходить через глобальний простір імен.

Якщо потрібна назва вже зайнята, виберіть іншу за масштабом (myapp-photos-2026, acme-nft-metadata) — так само, як ви б зробили на Amazon S3.

Підтримувані операції

PutObject

Завантажте файл в IPFS. Файл закріплюється, проходить перевірку безпеки, а CID повертається у заголовках ETag та x-amz-meta-cid.

Щоб імпортувати CAR-файл замість звичайного файлу, додайте заголовок метаданих x-amz-meta-import: car. Див. CAR Import для деталей.

javascript
import { PutObjectCommand } from "@aws-sdk/client-s3";
import fs from "fs";

const result = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "photo.png",
  Body: fs.readFileSync("photo.png"),
  ContentType: "image/png"
}));

console.log("CID:", result.ETag);
bash
# curl equivalent
curl -X PUT "https://s3.ipfs.ninja/my-project/photo.png" \
  --data-binary @photo.png \
  -H "Content-Type: image/png" \
  --aws-sigv4 "aws:amz:us-east-1:s3" \
  --user "bws_628bba35:bws_628bba35e9e0079d9ff9c392b1b55a7b"

GetObject

Скачайте файл за його ключем (ім'ям файлу) або CID.

javascript
import { GetObjectCommand } from "@aws-sdk/client-s3";

const result = await s3.send(new GetObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

const body = await result.Body.transformToByteArray();
console.log("Size:", body.length);
console.log("CID:", result.Metadata?.cid);

HeadObject

Отримайте метадані файлу без скачування вмісту.

javascript
import { HeadObjectCommand } from "@aws-sdk/client-s3";

const head = await s3.send(new HeadObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

console.log("Size:", head.ContentLength);
console.log("Type:", head.ContentType);
console.log("CID:", head.Metadata?.cid);

DeleteObject

Відкріпіть файл з IPFS та видаліть його з вашого облікового запису.

javascript
import { DeleteObjectCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

ListObjectsV2

Перегляньте файли в bucket'і з необов'язковою фільтрацією за префіксом та пагінацією.

javascript
import { ListObjectsV2Command } from "@aws-sdk/client-s3";

const list = await s3.send(new ListObjectsV2Command({
  Bucket: "my-project",
  Prefix: "images/",
  MaxKeys: 100
}));

for (const obj of list.Contents ?? []) {
  console.log(obj.Key, obj.Size, obj.ETag); // ETag = CID
}

Multipart Upload

Завантажуйте великі файли (до 5 ГБ) за допомогою multipart upload. AWS SDK обробляє це автоматично:

javascript
import { Upload } from "@aws-sdk/lib-storage";
import fs from "fs";

const upload = new Upload({
  client: s3,
  params: {
    Bucket: "my-project",
    Key: "large-dataset.tar.gz",
    Body: fs.createReadStream("large-dataset.tar.gz"),
    ContentType: "application/gzip"
  },
  partSize: 10 * 1024 * 1024, // 10 MB per part
});

upload.on("httpUploadProgress", (progress) => {
  console.log(`Uploaded ${progress.loaded} of ${progress.total} bytes`);
});

const result = await upload.done();
console.log("CID:", result.ETag);

Або керуйте частинами вручну:

javascript
import {
  CreateMultipartUploadCommand,
  UploadPartCommand,
  CompleteMultipartUploadCommand
} from "@aws-sdk/client-s3";

// 1. Start
const { UploadId } = await s3.send(new CreateMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin"
}));

// 2. Upload parts
const part1 = await s3.send(new UploadPartCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  PartNumber: 1,
  Body: chunk1
}));

// 3. Complete
const result = await s3.send(new CompleteMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  MultipartUpload: {
    Parts: [{ PartNumber: 1, ETag: part1.ETag }]
  }
}));

Приклад Python

python
import boto3

s3 = boto3.client(
    "s3",
    endpoint_url="https://s3.ipfs.ninja",
    aws_access_key_id="bws_628bba35",
    aws_secret_access_key="bws_628bba35e9e0079d9ff9c392b1b55a7b",
    region_name="us-east-1"
)

# Upload
s3.put_object(
    Bucket="my-project",
    Key="data.json",
    Body=b'{"hello": "IPFS"}',
    ContentType="application/json"
)

# List files
response = s3.list_objects_v2(Bucket="my-project")
for obj in response.get("Contents", []):
    print(obj["Key"], obj["Size"])

# Download
result = s3.get_object(Bucket="my-project", Key="data.json")
print(result["Body"].read())

Приклад Go

go
package main

import (
    "context"
    "fmt"
    "strings"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    client := s3.New(s3.Options{
        BaseEndpoint: aws.String("https://s3.ipfs.ninja"),
        Region:       "us-east-1",
        Credentials:  credentials.NewStaticCredentialsProvider("bws_628bba35", "bws_628bba35e9e0...", ""),
        UsePathStyle: true,
    })

    _, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
        Bucket:      aws.String("my-project"),
        Key:         aws.String("hello.txt"),
        Body:        strings.NewReader("Hello, IPFS!"),
        ContentType: aws.String("text/plain"),
    })
    if err != nil {
        panic(err)
    }
    fmt.Println("Uploaded!")
}

Налаштування CORS (доступ з браузерного SDK)

Якщо ви викликаєте S3 API безпосередньо з браузерного JavaScript (SPA, wallet-додаток, інструмент dashboard), спочатку потрібно налаштувати CORS на bucket'і. Інакше браузери блокують preflight-запит, і ваші завантаження провалюються з помилкою No 'Access-Control-Allow-Origin' header is present.

Та сама структура, що й в AWS S3 — субресурси PutBucketCors / GetBucketCors / DeleteBucketCors:

PutBucketCors

javascript
import { S3Client, PutBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new PutBucketCorsCommand({
  Bucket: "my-bucket",
  CORSConfiguration: {
    CORSRules: [{
      AllowedOrigins: ["http://localhost:3000", "https://myapp.com"],
      AllowedMethods: ["GET", "HEAD", "PUT", "POST", "DELETE"],
      AllowedHeaders: ["*"],
      ExposeHeaders: ["ETag", "x-amz-meta-cid", "x-amz-request-id"],
      MaxAgeSeconds: 3600,
    }],
  },
}));

GetBucketCors

javascript
import { GetBucketCorsCommand } from "@aws-sdk/client-s3";

const { CORSRules } = await s3.send(new GetBucketCorsCommand({ Bucket: "my-bucket" }));
console.log(CORSRules);

DeleteBucketCors

javascript
import { DeleteBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteBucketCorsCommand({ Bucket: "my-bucket" }));

Ліміти та значення за замовчуванням

  • До 5 правил на bucket (специфікація дозволяє 100; ми обмежуємо до 5, щоб зберегти відповідь preflight компактною).
  • Загальна конфігурація обмежена до 64 КБ у серіалізованому вигляді.
  • Якщо конфігурація CORS не встановлена, браузерні preflight-запити відхиляються — так само, як і за замовчуванням в AWS S3. Налаштуйте явні правила для джерел, з яких ви дійсно обслуговуєте запити.

Примітка щодо безпеки

CORS — це рівень зручності на стороні браузера, а не межа безпеки. Кожен виклик S3 API все одно вимагає дійсного підпису SigV4, обчисленого з вашого API-ключа — дозвільна конфігурація CORS не дає нікому змоги використовувати ваш bucket без цих облікових даних. Що CORS дійсно запобігає: небажане джерело (наприклад, застаріла копія вашого додатку на dev.myapp.com) надсилатиме підписані запити з контексту браузера.

Альтернатива через dashboard

На сторінці Files у меню дій кожної папки є пункт S3 CORS. Те саме сховище під капотом; якщо ви не хочете писати код PutBucketCors, налаштуйте це там.

Відмінності від Amazon S3

ФункціяAmazon S3IPFS Ninja S3
Модель зберіганняЗмінювані об'єктиАдресація за вмістом (незмінні CID)
Поведінка перезаписуЗамінює об'єкт на місціСтворює новий CID, старий CID залишається доступним
ВерсіонуванняПідтримуєтьсяНе підтримується (використовуйте CID для версіонування)
Шифрування на стороні сервераПідтримуєтьсяНе підтримується (вміст знаходиться в IPFS)
Політики життєвого циклуПідтримуютьсяНе підтримуються
Політики bucket'ів / ACLПідтримуютьсяВикористовуйте режими доступу gateway
Попередньо підписані URLПідтримуютьсяВикористовуйте підписані токени завантаження
Максимальний розмір об'єкта5 ТБ5 ГБ (multipart), 100 МБ (одиночний PUT)
РегіониМультирегіональнийЛише us-east-1
Значення ETagMD5 hashIPFS CID
Додаткові заголовкиСтандартні S3x-amz-meta-cid (IPFS CID)
Формат CIDН/ЗСучасні CIDv1 (bafy…) для нових завантажень; застарілі Qm… залишаються дійсними для вхідних даних
Простір імен bucket'івГлобальний (у межах AWS)Глобальний (у межах усіх облікових записів IPFS Ninja) — та сама семантика
CORSPutBucketCors підтримуєтьсяPutBucketCors підтримується (ліміт 5 правил)

Міграція з Amazon S3

Замініть конфігурацію вашого S3-клієнта:

diff
 const s3 = new S3Client({
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "AKIA...",
-    secretAccessKey: "wJalrX..."
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
+  forcePathStyle: true
 });

Ваші існуючі виклики PutObject, GetObject, ListObjectsV2 та DeleteObject працюють без змін.

Міграція з Filebase

Замініть URL endpoint'а:

diff
 const s3 = new S3Client({
-  endpoint: "https://s3.filebase.com",
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "FILEBASE_KEY",
-    secretAccessKey: "FILEBASE_SECRET"
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
   forcePathStyle: true
 });