Português (PT)
Português (PT)
Appearance
Português (PT)
Português (PT)
Appearance
Utiliza o AWS SDK para carregar, transferir e gerir ficheiros no IPFS Ninja com o mesmo código que utilizas para o Amazon S3.
https://s3.ipfs.ninjaA API S3 utiliza a tua chave de API do IPFS Ninja para autenticação. A tua chave de API serve tanto como access key como secret key.
A tua chave tem este formato:
bws_628bba35e9e0079d9ff9c392b1b55a7b
├──────────┘└──────────────────────────┘
prefix (12 chars) rest of key| Parâmetro AWS | Valor | Exemplo |
|---|---|---|
accessKeyId | Os primeiros 12 caracteres da tua 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ó é apresentada uma vez, quando a crias. Se a perderes, elimina a chave e cria 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: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdiOs buckets S3 correspondem às tuas pastas no IPFS Ninja. Quando carregas um ficheiro para um bucket, este é guardado na pasta correspondente. Quando listas objetos num bucket, vês os ficheiros dessa pasta.
| Operação S3 | Equivalente no IPFS Ninja |
|---|---|
CreateBucket | Criar uma nova pasta |
ListBuckets | Listar as tuas pastas |
DeleteBucket | Eliminar uma pasta e todos os ficheiros nela |
PutObject no bucket | Carregar ficheiro para a pasta |
ListObjectsV2 no bucket | Listar ficheiros 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 através da API S3 são as mesmas pastas visíveis no teu Dashboard. Podes organizar ficheiros tanto pela API S3, como pela API REST, ou pela interface web — todas partilham o mesmo sistema de pastas.
INFO
Ao contrário do Amazon S3, as pastas do IPFS Ninja são planas por predefinição. Para criar estruturas aninhadas, utiliza os endpoints de pastas da API REST com parentFolderId. A partir da API S3, utiliza prefixos nas chaves (ex.: images/photo.png) para organizar dentro de uma pasta.
Os nomes de bucket vivem num espaço de nomes global partilhado por todos os clientes, tal como acontece no Amazon S3. Isto significa que:
CreateBucket posteriores com o mesmo nome, de qualquer conta, devolvem BucketAlreadyExists (409).BucketAlreadyOwnedByYou (409).Se o nome que queres já estiver ocupado, escolhe um nome com um âmbito diferente (myapp-photos-2026, acme-nft-metadata) — a mesma convenção que usarias no Amazon S3.
Carrega um ficheiro para o IPFS. O ficheiro é fixado, verificado quanto à segurança, e o CID é devolvido nos cabeçalhos ETag e x-amz-meta-cid.
Para importar um ficheiro CAR em vez de um ficheiro normal, adiciona o cabeçalho de metadados x-amz-meta-import: car. Consulta Importação 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"Transfere um ficheiro pela sua chave (nome do ficheiro) 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 ficheiro sem transferir 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);Desfixa um ficheiro do IPFS e elimina-o da tua conta.
import { DeleteObjectCommand } from "@aws-sdk/client-s3";
await s3.send(new DeleteObjectCommand({
Bucket: "my-project",
Key: "photo.png"
}));Lista ficheiros num 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
}Carrega ficheiros grandes (até 5 GB) utilizando o carregamento multiparte. O AWS SDK trata disto 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 controla 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 estás a chamar a API S3 diretamente a partir de JavaScript no browser (SPA, aplicação de carteira, ferramenta do painel), tens de configurar CORS no bucket primeiro. Caso contrário, os browsers bloqueiam o preflight e os teus carregamentos falham com No 'Access-Control-Allow-Origin' header is present.
Mesma estrutura que no 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 browser, não uma fronteira de segurança. Todos os pedidos à API S3 continuam a exigir uma assinatura SigV4 válida calculada a partir da tua chave de API — uma configuração de CORS permissiva não permite que alguém utilize o teu bucket sem essa credencial. O que o CORS efetivamente evita: que uma origem não pretendida (ex.: uma cópia desatualizada da tua aplicação em dev.myapp.com) envie pedidos assinados a partir de um contexto de browser.
A página Ficheiros tem uma opção S3 CORS no menu de ações de cada pasta. Mesmo armazenamento subjacente; se não quiseres escrever código para PutBucketCors, configura-o por ali.
| Funcionalidade | Amazon S3 | IPFS Ninja S3 |
|---|---|---|
| Modelo de armazenamento | Objetos mutáveis | Endereçamento por conteúdo (CIDs imutáveis) |
| Comportamento de sobrescrita | Substitui o objeto no local | Cria novo CID, o CID antigo continua acessível |
| Versionamento | Suportado | Não suportado (utiliza CIDs para versionamento) |
| Encriptação 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 | Utiliza os modos de acesso do gateway |
| URLs pré-assinados | Suportados | Utiliza os tokens de carregamento assinados |
| Tamanho máximo do objeto | 5 TB | 5 GB (multiparte), 100 MB (PUT único) |
| Regiões | Multi-região | Apenas us-east-1 |
Valor do ETag | Hash MD5 | CID IPFS |
| Cabeçalhos extra | S3 padrão | x-amz-meta-cid (CID IPFS) |
| Formato do CID | N/A | CIDv1 moderno (bafy…) para novos carregamentos; o Qm… legado continua válido como entrada |
| Espaço de nomes do bucket | Global (em toda a AWS) | Global (em todas as contas IPFS Ninja) — mesma semântica |
| CORS | PutBucketCors suportado | PutBucketCors suportado (limite de 5 regras) |
Substitui a configuração do teu 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
});As tuas chamadas existentes de PutObject, GetObject, ListObjectsV2 e DeleteObject funcionam sem alterações.
Substitui o 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
});