Português BR
Português BR
Appearance
Português BR
Português BR
Appearance
Use o AWS SDK para enviar, baixar e gerenciar arquivos no IPFS Ninja com o mesmo código que você usa para o Amazon S3.
https://s3.ipfs.ninjaA API S3 usa sua chave de API do IPFS Ninja para autenticação. Sua chave de API funciona tanto como access key quanto como secret key.
Sua chave se parece com isto:
bws_628bba35e9e0079d9ff9c392b1b55a7b
├──────────┘└──────────────────────────┘
prefix (12 chars) rest of key| Parâmetro AWS | Valor | Exemplo |
|---|---|---|
accessKeyId | Os primeiros 12 caracteres da sua chave de API | bws_628bba35 |
secretAccessKey | A chave de API completa (todos os 36 caracteres) | bws_628bba35e9e0079d9ff9c392b1b55a7b |
region | Sempre us-east-1 | us-east-1 |
WARNING
A chave de API completa só é exibida uma vez, no momento em que você a cria. Se você perdê-la, exclua a chave e crie uma nova na página de API Keys.
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: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdiBuckets S3 correspondem às suas pastas no IPFS Ninja. Quando você envia um arquivo para um bucket, ele é armazenado na pasta correspondente. Quando você lista objetos em um bucket, você vê os arquivos daquela pasta.
| Operação S3 | Equivalente no IPFS Ninja |
|---|---|
CreateBucket | Criar uma nova pasta |
ListBuckets | Listar suas pastas |
DeleteBucket | Excluir uma pasta e todos os arquivos nela |
PutObject no bucket | Enviar arquivo para a pasta |
ListObjectsV2 no bucket | Listar arquivos na pasta |
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 são as mesmas pastas visíveis no seu Dashboard. Você pode organizar arquivos tanto pela API S3, quanto pela API REST, ou pela interface web — todas compartilham o mesmo sistema de pastas.
INFO
Diferente do Amazon S3, as pastas do IPFS Ninja são planas por padrão. Para criar estruturas aninhadas, use os endpoints de pastas da API REST com parentFolderId. Pela API S3, use prefixos de chave (ex.: images/photo.png) para organizar dentro de uma pasta.
Nomes de bucket vivem em um namespace global entre todos os clientes, seguindo a mesma semântica do AWS S3. Isso significa que:
CreateBucket com o mesmo nome, vindas de qualquer conta, retornam BucketAlreadyExists (409).BucketAlreadyOwnedByYou (409).Se o nome que você quer já está em uso, escolha um com escopo diferente (myapp-photos-2026, acme-nft-metadata) — a mesma convenção que você usaria no Amazon S3.
Envia um arquivo para o IPFS. O arquivo é fixado, verificado quanto à segurança, e o CID é retornado nos cabeçalhos ETag e x-amz-meta-cid.
Para importar um arquivo CAR em vez de um arquivo normal, adicione o cabeçalho de metadados x-amz-meta-import: car. Veja Importação de CAR para detalhes.
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);# 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"Baixa um arquivo pela sua chave (nome do arquivo) ou CID.
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);Obtém os metadados do arquivo sem baixar o conteúdo.
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);Remove a fixação de um arquivo do IPFS e o exclui da sua conta.
import { DeleteObjectCommand } from "@aws-sdk/client-s3";
await s3.send(new DeleteObjectCommand({
Bucket: "my-project",
Key: "photo.png"
}));Lista arquivos em um bucket com filtragem opcional por prefixo e paginação.
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
}Envie arquivos grandes (até 5 GB) usando upload multipart. O AWS SDK cuida disso automaticamente:
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:
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 }]
}
}));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())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!")
}Se você está chamando a API S3 diretamente do JavaScript do navegador (SPA, app de carteira, ferramenta de painel), primeiro é preciso configurar o CORS no bucket. Caso contrário, os navegadores bloqueiam o preflight e seus uploads falham com No 'Access-Control-Allow-Origin' header is present.
Mesmo formato do AWS S3 — subrecursos PutBucketCors / GetBucketCors / DeleteBucketCors:
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,
}],
},
}));import { GetBucketCorsCommand } from "@aws-sdk/client-s3";
const { CORSRules } = await s3.send(new GetBucketCorsCommand({ Bucket: "my-bucket" }));
console.log(CORSRules);import { DeleteBucketCorsCommand } from "@aws-sdk/client-s3";
await s3.send(new DeleteBucketCorsCommand({ Bucket: "my-bucket" }));CORS é uma camada de conveniência do lado do navegador, não uma barreira de segurança. Toda chamada à API S3 ainda exige uma assinatura SigV4 válida computada a partir da sua chave de API — uma configuração de CORS permissiva não permite que qualquer pessoa use seu bucket sem essa credencial. O que o CORS realmente evita: uma origem não intencional (ex.: uma cópia desatualizada do seu app em dev.myapp.com) enviando requisições assinadas a partir de um contexto de navegador.
A página Arquivos tem uma opção S3 CORS no menu de ações de cada pasta. Mesmo armazenamento por baixo dos panos; se você não quiser escrever código para PutBucketCors, configure por lá.
| Recurso | Amazon S3 | IPFS Ninja S3 |
|---|---|---|
| Modelo de armazenamento | Objetos mutáveis | Endereçado por conteúdo (CIDs imutáveis) |
| Comportamento de sobrescrita | Substitui o objeto no lugar | Cria um novo CID; o CID antigo continua acessível |
| Versionamento | Suportado | Não suportado (use CIDs para versionamento) |
| Criptografia no servidor | Suportada | Não suportada (o conteúdo está no IPFS) |
| Políticas de ciclo de vida | Suportadas | Não suportadas |
| Políticas de bucket / ACLs | Suportadas | Use os modos de acesso do gateway |
| URLs pré-assinadas | Suportadas | Use os tokens de upload assinados |
| Tamanho máximo do objeto | 5 TB | 5 GB (multipart), 100 MB (PUT único) |
| Regiões | Multirregião | Apenas us-east-1 |
Valor do ETag | Hash MD5 | CID do IPFS |
| Cabeçalhos extras | S3 padrão | x-amz-meta-cid (CID do IPFS) |
| Formato do CID | N/A | CIDv1 moderno (bafy…) para novos uploads; Qm… legado continua válido como entrada |
| Namespace de bucket | Global (em toda a AWS) | Global (entre todas as contas do IPFS Ninja) — mesma semântica |
| CORS | PutBucketCors suportado | PutBucketCors suportado (limite de 5 regras) |
Substitua a configuração do seu cliente S3:
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
});Suas chamadas existentes de PutObject, GetObject, ListObjectsV2 e DeleteObject funcionam sem alterações.
Substitua a URL do endpoint:
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
});