Skip to content

Kompatibilitas S3

Gunakan AWS SDK untuk mengunggah, mengunduh, dan mengelola file di IPFS Ninja dengan kode yang sama seperti yang Anda gunakan untuk Amazon S3.

Endpoint

https://s3.ipfs.ninja

Kredensial

API S3 menggunakan kunci API IPFS Ninja Anda untuk autentikasi. Kunci API Anda berfungsi sebagai access key sekaligus secret key.

Cara mendapatkan kredensial Anda

  1. Buka Dashboard > API Keys
  2. Klik Create API key dan beri nama (misal "S3 access")
  3. Salin kunci lengkap segera — kunci hanya ditampilkan sekali dan tidak dapat diambil kembali

Kunci Anda terlihat seperti ini:

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

Pemetaan ke kredensial AWS

Parameter AWSNilaiContoh
accessKeyId12 karakter pertama dari kunci API Andabws_628bba35
secretAccessKeyKunci API lengkap (semua 36 karakter)bws_628bba35e9e0079d9ff9c392b1b55a7b
regionSelalu us-east-1us-east-1

WARNING

Kunci API lengkap hanya ditampilkan sekali saat Anda membuatnya. Jika Anda kehilangan kunci, hapus kunci tersebut dan buat yang baru dari halaman API Keys.

Mulai Cepat

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 = Folder

Bucket S3 dipetakan ke folder IPFS Ninja Anda. Saat Anda mengunggah file ke bucket, file tersebut disimpan di folder yang sesuai. Saat Anda melihat daftar objek di bucket, Anda melihat file-file di folder tersebut.

Operasi S3Padanan IPFS Ninja
CreateBucketMembuat folder baru
ListBucketsMelihat daftar folder Anda
DeleteBucketMenghapus folder beserta semua file di dalamnya
PutObject ke bucketMengunggah file ke dalam folder
ListObjectsV2 pada bucketMelihat daftar file di folder
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

Folder yang dibuat melalui API S3 adalah folder yang sama yang terlihat di Dashboard Anda. Anda dapat mengatur file dari API S3, REST API, atau antarmuka web — semuanya berbagi sistem folder yang sama.

INFO

Berbeda dengan Amazon S3, folder IPFS Ninja bersifat datar secara default. Untuk membuat struktur bersarang, gunakan endpoint folder di REST API dengan parentFolderId. Dari API S3, gunakan prefix key (misal images/photo.png) untuk mengatur file di dalam folder.

Nama bucket unik secara global

Nama bucket berada dalam namespace global di seluruh pelanggan, sesuai dengan semantik AWS S3. Ini berarti:

  • Pengguna pertama yang membuat bucket dengan nama tertentu mengklaim nama tersebut secara global.
  • Panggilan CreateBucket berikutnya dengan nama yang sama dari akun mana pun mengembalikan BucketAlreadyExists (409).
  • Jika Anda mencoba membuat ulang bucket Anda sendiri, Anda mendapatkan BucketAlreadyOwnedByYou (409).
  • Nama folder Anda di dashboard bersifat per-akun dan tetap bisa apa saja — hanya nama bucket yang terlihat di S3 yang melalui namespace global.

Jika nama yang Anda inginkan sudah dipakai, pilih nama dengan cakupan yang berbeda (myapp-photos-2026, acme-nft-metadata) — konvensi yang sama seperti yang Anda gunakan di Amazon S3.

Operasi yang Didukung

PutObject

Mengunggah file ke IPFS. File akan di-pin, dipindai keamanan, dan CID dikembalikan di header ETag dan x-amz-meta-cid.

Untuk mengimpor file CAR alih-alih file biasa, tambahkan header metadata x-amz-meta-import: car. Lihat Impor CAR untuk detail.

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

Mengunduh file berdasarkan key (nama file) atau 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

Mendapatkan metadata file tanpa mengunduh kontennya.

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

Melepas pin file dari IPFS dan menghapusnya dari akun Anda.

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

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

ListObjectsV2

Melihat daftar file di bucket dengan filter prefix opsional dan paginasi.

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

Mengunggah file besar (hingga 5 GB) menggunakan multipart upload. AWS SDK menangani ini secara otomatis:

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

Atau kontrol bagian secara manual:

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

Contoh 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())

Contoh 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!")
}

Konfigurasi CORS (akses SDK browser)

Jika Anda memanggil API S3 langsung dari JavaScript browser (SPA, aplikasi wallet, alat dashboard), Anda perlu mengonfigurasi CORS pada bucket terlebih dahulu. Jika tidak, browser akan memblokir preflight dan unggahan Anda akan gagal dengan No 'Access-Control-Allow-Origin' header is present.

Bentuk yang sama seperti 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" }));

Batas dan default

  • Hingga 5 aturan per bucket (spesifikasi mengizinkan 100; kami membatasi hingga 5 untuk menjaga respons preflight browser tetap ringkas).
  • Total konfigurasi dibatasi hingga 64 KB setelah diserialisasi.
  • Jika tidak ada konfigurasi CORS yang diatur, preflight browser akan ditolak — sesuai dengan sikap default AWS S3. Konfigurasikan aturan eksplisit untuk origin yang benar-benar Anda gunakan.

Catatan keamanan dunia nyata

CORS adalah lapisan kenyamanan sisi browser, bukan batas keamanan. Setiap panggilan API S3 tetap memerlukan signature SigV4 yang valid yang dihitung dari API key Anda — konfigurasi CORS yang permisif tidak memungkinkan siapa pun menggunakan bucket Anda tanpa kredensial tersebut. Yang dicegah CORS: origin yang tidak diinginkan (misal salinan basi dari aplikasi Anda di dev.myapp.com) mengirim permintaan bertanda tangan dari konteks browser.

Alternatif dashboard

Halaman File memiliki entri S3 CORS di menu aksi setiap folder. Penyimpanan yang mendasarinya sama; jika Anda tidak ingin menulis kode PutBucketCors, konfigurasikan di sana.

Perbedaan dengan Amazon S3

FiturAmazon S3IPFS Ninja S3
Model penyimpananObjek yang bisa diubahContent-addressed (CID yang tidak dapat diubah)
Perilaku overwriteMengganti objek di tempatMembuat CID baru, CID lama tetap dapat diakses
VersioningDidukungTidak didukung (gunakan CID untuk versioning)
Enkripsi sisi serverDidukungTidak didukung (konten ada di IPFS)
Lifecycle policiesDidukungTidak didukung
Bucket policies / ACLDidukungGunakan mode akses gateway
Presigned URLDidukungGunakan signed upload token
Ukuran objek maksimum5 TB5 GB (multipart), 100 MB (single PUT)
RegionMulti-regionHanya us-east-1
Nilai ETagHash MD5IPFS CID
Header tambahanS3 standarx-amz-meta-cid (IPFS CID)
Format CIDT/ACIDv1 modern (bafy…) untuk unggahan baru; Qm… lama tetap valid sebagai input
Namespace bucketGlobal (di seluruh AWS)Global (di seluruh akun IPFS Ninja) — semantik yang sama
CORSPutBucketCors didukungPutBucketCors didukung (batas 5 aturan)

Migrasi dari Amazon S3

Ganti konfigurasi klien S3 Anda:

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

Panggilan PutObject, GetObject, ListObjectsV2, dan DeleteObject yang sudah ada tetap berfungsi tanpa perubahan.

Migrasi dari Filebase

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