Reference
SDK
TypeScript. Runs in browsers, Bun, Node and serverless functions. Source: sdk/src.
imports
// Everything
import { prepareFile, uploadFile, getFile } from "@potdrive/sdk";
// Or per module, to keep @polkadot/api out of bundles that only read
import { getFile } from "@potdrive/sdk/fetch";Prepare
prepareFile(data: Uint8Array, opts: PrepareOptions): Promise<PreparedFile>Chunks, hashes and builds the UnixFS DAG locally. No network access.
| opts.name | string | File name. Recorded in the registry, or sealed inside the envelope for private files. |
| opts.mime | string? | Content type. Defaults to application/octet-stream. |
| opts.private | boolean? | Seal with AES-256-GCM first. Sets PreparedFile.key. |
| opts.chunking | Chunking? | { cdc: CdcOptions } (default) or a fixed size in bytes. |
Returns { root, kind, blocks, storedBytes, originalBytes, name, mime, private, key? }
prepareFolder(entries: { path: string; bytes: Uint8Array }[], opts: { name: string }): Promise<PreparedFile>A UnixFS directory. Paths may contain
/. .. is rejected. Links are sorted, so the CID does not depend on input order.Returns PreparedFile with kind 'directory' and files[]
Upload
estimateUpload(api, file, owner: string, opts?: { registry?: Address; keepAlive?: bigint }): Promise<Estimate>One state read for deduplication and two
paymentInfo calls for the fee model. All amounts are in planck (14 decimals).Returns { storeFees, registryFee, registryDeposit, keepAlive, budget, total, alreadyStored, reused, reusedBytes, newBytes }
uploadFile(opts: UploadOptions): Promise<UploadResult>The one-signature flow described in One-signature uploads.
| api | ApiPromise | From connect(). |
| file | PreparedFile | From prepareFile or prepareFolder. |
| owner | Account | { address, signer } from a wallet extension, or a KeyringPair. |
| registry | Address? | Register ownership in the same signature. |
| keepAlive | bigint? | Prepaid renewals in planck, held by the registry. |
| sessions | SessionStore? | Persist the upload key until it is swept. |
| concurrency | number? | Store extrinsics in flight. Default 4. |
| onEvent | (e: UploadEvent) => void | estimate, session, authorized, block, verified, swept, done. |
Returns { root, key?, blocks: BlockState[], authorizeTx?, deduplicated }
recoverSession(api, mnemonic: string, to: string): Promise<void>Sends an abandoned upload key's balance back to its owner.
Read
getBlock(cid: CID | string, url?: string): Promise<Uint8Array>One block via
bitswap_v1_get, verified. Throws NotFoundError or IntegrityError.getFile(cid, opts?: { onLayout?, onChunk?, concurrency? }): Promise<Uint8Array>A whole file, every leaf verified.
onChunk reports each leaf as ok, missing or corrupt, with timing.stat(cid): Promise<Stat>Reads one block and decodes it.
Returns { cid, kind: 'raw' | 'file' | 'directory', size, node?, raw? }
readRange(stat: Stat, start: number, end: number, opts?): Promise<Uint8Array>Bytes
[start, end), fetching only the leaves that overlap the range.resolvePath(root, path: string): Promise<Stat>Walks a UnixFS directory path. Throws
PathError if a segment is missing or a file is used as a directory.Chain state and renewals
listStored(api): Promise<StoredEntry[]>Everything TransactionStorage currently holds, newest first.
Returns { block, index, contentHash, size, expiresAt }[]
placements(api, root): Promise<Placement[]>Every block under a root (directories, file roots, leaves) and the
(block, index) where it is held.renewFile(api, account, root, onRenewed?): Promise<number>Sends
renew for every block and returns the earliest renewal block. Permissionless.proofReport(api, depth = 12): Promise<ProofReport>Recent blocks, whether each carried
checkProof or ProofChecked, and when the next proof is due.Sponsored uploads, sharing, NFTs
uploadSponsored({ api, file, owner: { address, signRaw }, relayUrl, onEvent }): Promise<UploadResult>Gasless upload through the MetaTx relay. See Gasless uploads.
signMetaTx(api, keyPair, call, nonce?): { metaTx, hex, length }Builds and signs a
PalletMetaTxMetaTx for Portaldot's extension pipeline.sealToInbox(fileKey, inboxPublicKey, root) / openFromInbox(sealed, inboxPrivateKey, root)X25519 + HKDF-SHA256 + AES-256-GCM, with the root bound as AAD.
newInbox() makes a key pair.planMint(api, owner, { name, image, url?, mime? }) → mintCalls(api, owner, plan) → ownedNfts(api, owner)Native Nfts pallet minting in one batch, with metadata kept under the 256-byte StringLimit.
readVersions(registry, root): Promise<{ root, size, block }[]>Follows
parent links in Registered logs, newest first.Low level
cidFor(bytes, codec = RAW): CIDCIDv1 with a blake2b-256 multihash, the digest TransactionStorage indexes.
cdcChunks(data, opts = CDC_DEFAULT): Uint8Array[]FastCDC with normalized chunking. Defaults: 256 KiB min, 512 KiB average, 1 MiB max.
buildFileDag(bytes, chunking?): FileDagRaw leaves plus a UnixFS dag-pb root.
blocks is unique by CID.sealFile(data, meta) / openFile(bytes, key)The private-file envelope. See Private files.