07.3 · API
Storage SDK
Indexer upload and download. There is no second, invented REST API.
Builders talk to storage through the indexer SDK. The indexer selects nodes and the flow contract. You choose the indexer URL, which also chooses turbo or standard. A root hash from turbo will not resolve on standard.
Package: @0gfoundation/0g-storage-ts-sdk, with ethers v6. The upload spends Galileo gas, so the signer needs testnet 0G.
01
indexer.upload
SDKStore a payload and return its root hash.
Request
import { Indexer, MemData } from "@0gfoundation/0g-storage-ts-sdk";
import { ethers } from "ethers";
const rpc = "https://evmrpc-testnet.0g.ai";
const indexer = new Indexer("https://indexer-storage-testnet-turbo.0g.ai");
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, new ethers.JsonRpcProvider(rpc));
const file = new MemData(new TextEncoder().encode("hello 0G"));
const [rootHash, error] = await indexer.upload(file, rpc, signer);
if (error) throw error;Response
rootHash: 0x… // content hash, search it on Storage Scan
error: null- Galileo turbo indexer: indexer-storage-testnet-turbo.0g.ai
- Galileo standard indexer: indexer-storage-testnet-standard.0g.ai (maintenance has been the published status)
- Mainnet turbo: indexer-storage-turbo.0g.ai
- Mainnet standard: indexer-storage.0g.ai
- Use ZgFile instead of MemData when the bytes are a path on disk.
02
indexer.download
SDKFetch bytes by root hash and verify the Merkle proof.
Request
const error = await indexer.download(rootHash, "./hello.txt", true);
if (error) throw error;Response
hello.txt contains the original bytes when the third argument is true and the proof checks out.- Search the hash on storagescan-galileo.0g.ai for testnet and storagescan.0g.ai for mainnet.
- Flow, mine, and reward contract addresses are for node operators, not for this upload call. The indexer discovers the flow contract. Confirm operator addresses on the Galileo overview before you mine.