Skip to content

S3 компатибилност

Користите AWS SDK за отпремање, преузимање и управљање фајловима на IPFS Ninja са истим кодом који користите за Amazon S3.

Крајња тачка

https://s3.ipfs.ninja

Акредитиви

S3 API користи ваш IPFS Ninja API кључ за аутентификацију. Ваш API кључ служи и као приступни кључ (access key) и као тајни кључ (secret key).

Како добити акредитиве

  1. Идите на Контролна табла > API кључеви
  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 кључева.

Брзи почетак

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-ја су исти фолдери видљиви на вашој контролној табли. Можете организовати фајлове из S3 API-ја, REST API-ја или веб интерфејса — сви деле исти систем фолдера.

INFO

За разлику од Amazon S3, IPFS Ninja фолдери су подразумевано равни. За креирање угнежђених структура користите крајње тачке за фолдере у REST API-ју са parentFolderId. Из S3 API-ја користите префиксе кључева (нпр. images/photo.png) за организацију унутар фолдера.

Имена bucket-а су глобално јединствена

Имена bucket-а живе у глобалном именском простору код свих клијената, у складу са семантиком AWS S3. То значи:

  • Први корисник који креира bucket са одређеним именом преузима то име глобално.
  • Каснији позиви CreateBucket са истим именом са било ког налога враћају BucketAlreadyExists (409).
  • Ако покушате да поново креирате свој сопствени bucket, добијате BucketAlreadyOwnedByYou (409).
  • Име вашег фолдера на контролној табли је по налогу и и даље може бити било шта — само 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 увоз за детаље.

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
}

Вишеделно отпремање

Отпремите велике фајлове (до 5 GB) користећи вишеделно отпремање. 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 (приступ browser SDK-а)

Ако S3 API позивате директно из browser JavaScript-а (SPA, wallet апликација, алат контролне табле), прво морате да конфигуришете CORS на bucket-у. У супротном прегледачи блокирају preflight и ваша отпремања не успевају са грешком No 'Access-Control-Allow-Origin' header is present.

Исти облик као AWS S3 — subresource-и 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 да одговор browser preflight-а остане компактан).
  • Укупна конфигурација ограничена на 64 KB серијализовано.
  • Ако CORS конфигурација није постављена, browser preflight захтеви су одбијени — у складу са подразумеваним ставом AWS S3. Конфигуришите експлицитна правила за порекла са којих заиста сервирате.

Напомена о безбедности у стварном свету

CORS је погодност на страни прегледача, а не безбедносна граница. Сваки S3 API позив и даље захтева важећи SigV4 потпис израчунат из вашег API кључа — попустљива CORS конфигурација не дозвољава било коме да користи ваш bucket без тог акредитива. Оно што CORS спречава: да намерно порекло (нпр. застарела копија ваше апликације на dev.myapp.com) шаље потписане захтеве из browser контекста.

Алтернатива преко контролне табле

Страница Фајлови има ставку S3 CORS у менију радњи сваког фолдера. Иста основна меморија; ако не желите да пишете PutBucketCors код, конфигуришите је тамо.

Разлике од Amazon S3

ФункционалностAmazon S3IPFS Ninja S3
Модел складиштењаПромењиви објектиАдресирани садржајем (непроменљиви CID-ови)
Понашање при преписивањуЗамењује објекат на местуКреира нови CID, стари CID остаје доступан
ВерзионисањеПодржаноНије подржано (користите CID-ове за верзионисање)
Енкрипција на серверуПодржаноНије подржано (садржај је на IPFS-у)
Политике животног циклусаПодржаноНије подржано
Политике bucket-а / ACL-овиПодржаноКористите режиме приступа gateway-у
Претходно потписани URL-овиПодржаноКористите потписане токене за отпремање
Максимална величина објекта5 TB5 GB (вишеделно), 100 MB (појединачни PUT)
РегиониВише регионаСамо us-east-1
Вредност ETagMD5 хешIPFS CID
Додатна заглављаСтандардна S3x-amz-meta-cid (IPFS CID)
Формат CID-аН/ПМодерни CIDv1 (bafy…) за нова отпремања; стари Qm… остаје важећи као улаз
Именски простор bucket-аГлобалан (у оквиру AWS-а)Глобалан (код свих IPFS Ninja налога) — иста семантика
CORSПодржан PutBucketCorsПодржан 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 крајње тачке:

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
 });