Skip to content

Συμβατότητα με S3

Χρησιμοποίησε το AWS SDK για να ανεβάσεις, να κατεβάσεις και να διαχειριστείς αρχεία στο IPFS Ninja με τον ίδιο κώδικα που χρησιμοποιείς για το Amazon S3.

Endpoint

https://s3.ipfs.ninja

Διαπιστευτήρια

Το S3 API χρησιμοποιεί το κλειδί API του IPFS Ninja για πιστοποίηση. Το κλειδί API σου λειτουργεί ταυτόχρονα ως access key και ως secret key.

Πώς να αποκτήσεις τα διαπιστευτήριά σου

  1. Πήγαινε στο Dashboard > API Keys
  2. Κάνε κλικ στο Create API key και δώσε του ένα όνομα (π.χ. «S3 access»)
  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: QmXnnyufdzAWL5CqZ2RnSNgPbvCc1ALT73s6epPrRnZ1Xy

Buckets = Φάκελοι

Τα S3 buckets αντιστοιχούν στους φακέλους σου στο 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 είναι επίπεδοι από προεπιλογή. Για να δημιουργήσεις ένθετες δομές, χρησιμοποίησε τα endpoints φακέλων του REST API με parentFolderId. Από το S3 API, χρησιμοποίησε προθέματα κλειδιών (π.χ. images/photo.png) για οργάνωση εντός ενός φακέλου.

Υποστηριζόμενες Λειτουργίες

PutObject

Ανέβασε ένα αρχείο στο IPFS. Το αρχείο γίνεται pin, ελέγχεται για ασφάλεια, και ο CID επιστρέφεται στα headers ETag και x-amz-meta-cid.

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

Αφαίρεσε το pin ενός αρχείου από το 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 GB) χρησιμοποιώντας 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!")
}

Διαφορές από το Amazon S3

ΧαρακτηριστικόAmazon S3IPFS Ninja S3
Μοντέλο αποθήκευσηςΜεταβλητά αντικείμεναΔιευθυνσιοδότηση περιεχομένου (αμετάβλητα CIDs)
Συμπεριφορά αντικατάστασηςΑντικαθιστά το αντικείμενο επιτόπουΔημιουργεί νέο CID, ο παλιός CID παραμένει προσβάσιμος
ΕκδόσειςΥποστηρίζεταιΔεν υποστηρίζεται (χρησιμοποίησε CIDs για εκδόσεις)
Κρυπτογράφηση στον serverΥποστηρίζεταιΔεν υποστηρίζεται (το περιεχόμενο είναι στο IPFS)
Πολιτικές κύκλου ζωήςΥποστηρίζονταιΔεν υποστηρίζονται
Πολιτικές bucket / ACLsΥποστηρίζονταιΧρησιμοποίησε λειτουργίες πρόσβασης gateway
Προϋπογεγραμμένα URLsΥποστηρίζονταιΧρησιμοποίησε υπογεγραμμένα tokens μεταφόρτωσης
Μέγιστο μέγεθος αντικειμένου5 TB5 GB (multipart), 100 MB (μεμονωμένο PUT)
ΠεριοχέςΠολλαπλές περιοχέςΜόνο us-east-1
Τιμή ETagMD5 hashIPFS CID
Επιπλέον headersStandard S3x-amz-meta-cid (IPFS CID)

Μετάβαση από το Amazon S3

Αντικατέστησε τη διαμόρφωση του S3 client:

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

Αντικατέστησε το endpoint 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
 });