Skip to content

Compatibilidade S3

Utilize o AWS SDK para carregar, descarregar e gerir ficheiros no IPFS Ninja com o mesmo codigo que utiliza para o Amazon S3.

Endpoint

https://s3.ipfs.ninja

Credenciais

A API S3 utiliza a sua chave de API do IPFS Ninja para autenticacao. A sua chave de API serve tanto como access key como secret key.

Como obter as suas credenciais

  1. Aceda a Dashboard > API Keys
  2. Clique em Create API key e atribua um nome (ex: "S3 access")
  3. Copie a chave completa imediatamente — e apresentada apenas uma vez e nao pode ser recuperada posteriormente

A sua chave tem este formato:

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

Mapeamento para credenciais AWS

Parametro AWSValorExemplo
accessKeyIdPrimeiros 12 caracteres da sua chave de APIbws_628bba35
secretAccessKeyA chave de API completa (todos os 36 caracteres)bws_628bba35e9e0079d9ff9c392b1b55a7b
regionSempre us-east-1us-east-1

WARNING

A chave de API completa e apresentada apenas uma vez quando a cria. Se a perder, elimine a chave e crie uma nova na pagina de API Keys.

Inicio Rapido

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

Os buckets S3 correspondem as suas pastas no IPFS Ninja. Quando carrega um ficheiro para um bucket, este e armazenado na pasta correspondente. Quando lista objetos num bucket, ve os ficheiros nessa pasta.

Operacao S3Equivalente no IPFS Ninja
CreateBucketCriar uma nova pasta
ListBucketsListar as suas pastas
DeleteBucketEliminar uma pasta e todos os ficheiros nela
PutObject no bucketCarregar ficheiro para a pasta
ListObjectsV2 no bucketListar ficheiros na pasta
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

As pastas criadas pela API S3 sao as mesmas pastas visiveis no seu Dashboard. Pode organizar ficheiros tanto pela API S3, como pela API REST, ou pela interface web — todos partilham o mesmo sistema de pastas.

INFO

Ao contrario do Amazon S3, as pastas do IPFS Ninja sao planas por defeito. Para criar estruturas aninhadas, utilize os endpoints de pastas da API REST com parentFolderId. Pela API S3, utilize prefixos nas chaves (ex: images/photo.png) para organizar dentro de uma pasta.

Operacoes Suportadas

PutObject

Carrega um ficheiro para o IPFS. O ficheiro e fixado (pinned), verificado quanto a seguranca, e o CID e devolvido nos headers ETag e 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

Descarrega um ficheiro pela sua chave (nome do ficheiro) ou 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

Obtem os metadados do ficheiro sem descarregar o conteudo.

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

Remove a fixacao (unpin) de um ficheiro do IPFS e elimina-o da sua conta.

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

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

ListObjectsV2

Lista ficheiros num bucket com filtragem opcional por prefixo e paginacao.

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

Carregue ficheiros grandes (ate 5 GB) utilizando multipart upload. O AWS SDK trata disto automaticamente:

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

Ou controle as partes manualmente:

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

Exemplo em 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())

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

Diferencas em relacao ao Amazon S3

FuncionalidadeAmazon S3IPFS Ninja S3
Modelo de armazenamentoObjetos mutaveisEnderecamento por conteudo (CIDs imutaveis)
Comportamento de sobrescritaSubstitui o objeto no localCria novo CID, o CID antigo continua acessivel
VersionamentoSuportadoNao suportado (utilize CIDs para versionamento)
Encriptacao no servidorSuportadaNao suportada (conteudo esta no IPFS)
Politicas de ciclo de vidaSuportadasNao suportadas
Politicas de bucket / ACLsSuportadasUtilize modos de acesso do gateway
URLs pre-assinadosSuportadosUtilize tokens de carregamento assinados
Tamanho maximo do objeto5 TB5 GB (multipart), 100 MB (PUT unico)
RegioesMulti-regiaoApenas us-east-1
Valor do ETagHash MD5IPFS CID
Headers extrasS3 padraox-amz-meta-cid (IPFS CID)

Migrar do Amazon S3

Substitua a configuracao do seu cliente 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
 });

As suas chamadas existentes de PutObject, GetObject, ListObjectsV2 e DeleteObject funcionam sem alteracoes.

Migrar do Filebase

Substitua o URL do 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
 });