Storage Costs
Understanding storage costs helps you budget effectively and avoid service interruptions. This guide covers the SDK APIs for calculating costs, funding your account, and querying account state.
Storage operates on a pay-per-epoch model where you deposit USDFC tokens and set allowances that control how much the storage service can spend.
Pricing Components
Section titled “Pricing Components”Pricing has two recurring rates and a set of small one-time fees.
Recurring rates
Section titled “Recurring rates”| Component | Cost | Notes |
|---|---|---|
| Storage | $2.50/TiB/month per copy | Charged only while pieces exist. Empty data sets have no recurring cost. |
| Proving Service | $0.12/data set/month | Flat per-data-set fee, added on top of the storage rate. |
| CDN egress | up to $14/TiB (≈ $0.014/GiB) downloaded | Optional, via Filecoin Beam. About half this when served from cache. |
The monthly rate for an active data set is (FWSS-priced bytes / TiB) × $2.50 + $0.12. There is no minimum floor: a data set with no pieces has no recurring cost, and the rate activates when the first piece is added. PDP counts the data-bearing Merkle-tree leaves of each piece, then FWSS converts the aggregate leaf count using the Filecoin 127 / 128 ratio. This priced size can exceed the exact raw payload size by up to 31 bytes per piece.
One-time fees
Section titled “One-time fees”Each on-chain operation pays a small fee to the storage provider, covering the gas that provider spends on your behalf:
| Operation | Fee |
|---|---|
| Create data set | $0.025 |
| Add pieces | $0.008 + $0.003 per piece |
| Schedule piece removals | $0.007 per call |
| Terminate service | $0.006 for client-authorized, provider-relayed termination; no fee for direct payer or provider termination |
These are small one-time charges paid from a refundable lifecycle reserve (~$0.50) held while the data set is active, not added separately to the required deposit on every call. See How the fees and lockup work below.
Real-World Cost Examples
Section titled “Real-World Cost Examples”These examples use plain arithmetic for clarity. For programmatic cost calculation, use getUploadCosts() — see Querying Upload Costs below.
Example 1: NFT Collection (10,000 × 5 KiB ≈ 48.82 MiB)
Section titled “Example 1: NFT Collection (10,000 × 5 KiB ≈ 48.82 MiB)”// 48.82 MiB is tiny, so the storage rate is negligible.
// The recurring cost is dominated by the flat proving fee.
const const STORAGE_PRICE_PER_TIB_PER_MONTH: 2.5STORAGE_PRICE_PER_TIB_PER_MONTH = 2.5;
const const PROVING_FEE_PER_MONTH: 0.12PROVING_FEE_PER_MONTH = 0.12;
const const storageTiB: numberstorageTiB = 48.82 / 1024 / 1024; // ≈ 0.0000466 TiB
const const storageCostPerMonth: numberstorageCostPerMonth = const storageTiB: numberstorageTiB * const STORAGE_PRICE_PER_TIB_PER_MONTH: 2.5STORAGE_PRICE_PER_TIB_PER_MONTH; // ≈ $0.00012
// Per copy, per month
const const costPerMonth: numbercostPerMonth = const storageCostPerMonth: numberstorageCostPerMonth + const PROVING_FEE_PER_MONTH: 0.12PROVING_FEE_PER_MONTH; // ≈ 0.1201 USDFC
const const costFor24Months: numbercostFor24Months = const costPerMonth: numbercostPerMonth * 24; // ≈ 2.883 USDFC| Duration | Per copy |
|---|---|
| 1 month | ≈ 0.120 USDFC |
| 24 months | ≈ 2.88 USDFC |
The default 2-copy configuration roughly doubles the recurring cost. Each copy uses its own data set, so one-time fees apply per copy: every new data set incurs the $0.025 creation fee, and each copy’s addPieces operations incur their own base and per-piece fees.
Example 2: User Content Platform with CDN
Section titled “Example 2: User Content Platform with CDN”- Storage: 1,000 users × 100 MiB ≈ 100,000 MiB
- Traffic: 1,000 users × 100 MiB/month ≈ 100,000 MiB/month egress
const const STORAGE_PRICE_PER_TIB_PER_MONTH: 2.5STORAGE_PRICE_PER_TIB_PER_MONTH = 2.5; // $2.50/TiB/month
const const PROVING_FEE_PER_MONTH: 0.12PROVING_FEE_PER_MONTH = 0.12; // flat per-data-set
const const CDN_EGRESS_PRICE_PER_TIB: 14CDN_EGRESS_PRICE_PER_TIB = 14; // up to $14/TiB on a cache miss
const const storageMiB: 100000storageMiB = 100_000;
const const egressMiB: 100000egressMiB = 100_000;
// Storage: 100,000 MiB ≈ 0.0953 TiB
const const storageTiB: numberstorageTiB = const storageMiB: 100000storageMiB / 1024 / 1024;
// Egress: 100,000 MiB ≈ 0.0953 TiB
const const egressTiB: numberegressTiB = const egressMiB: 100000egressMiB / 1024 / 1024;
// Storage cost per month: 0.0953 TiB × $2.50 ≈ $0.238/month
const const storageCostPerMonth: numberstorageCostPerMonth = const storageTiB: numberstorageTiB * const STORAGE_PRICE_PER_TIB_PER_MONTH: 2.5STORAGE_PRICE_PER_TIB_PER_MONTH;
// Egress cost per month (worst case, all cache misses): 0.0953 TiB × $14 ≈ $1.334/month
const const egressCostPerMonth: numberegressCostPerMonth = const egressTiB: numberegressTiB * const CDN_EGRESS_PRICE_PER_TIB: 14CDN_EGRESS_PRICE_PER_TIB;
// Total cost per month: $0.238 + $0.12 proving + $1.335 egress ≈ $1.694/month
const const totalCostPerMonth: numbertotalCostPerMonth = const storageCostPerMonth: numberstorageCostPerMonth + const PROVING_FEE_PER_MONTH: 0.12PROVING_FEE_PER_MONTH + const egressCostPerMonth: numberegressCostPerMonth;
// Total cost for 24 months: $1.694/month × 24 ≈ $40.65
const const totalCostFor24Months: numbertotalCostFor24Months = const totalCostPerMonth: numbertotalCostPerMonth * 24;| Cost Component | Per Month | 24 Months |
|---|---|---|
| Storage | ≈ 0.238 USDFC | ≈ 5.72 USDFC |
| Proving Service | ≈ 0.120 USDFC | ≈ 2.88 USDFC |
| CDN Egress | ≈ 1.335 USDFC | ≈ 32.04 USDFC |
| Total | ≈ 1.694 USDFC | ≈ 40.65 USDFC |
Egress here is the worst case where every byte is a cache miss. When content is served from the Filecoin Beam cache, egress is roughly half this.
How the fees and lockup work
Section titled “How the fees and lockup work”Most developers can stop at the tables above. This section explains the mechanics behind the per-operation fees and the lockup reserve for anyone who needs the detail.
The proving fee is additive, not a floor. The rate is (FWSS-priced bytes / TiB) × $2.50 + $0.12, so storage scales with size and the proving fee is a flat addition per data set. A data set with no pieces has no recurring charge until the first piece is added.
Add-pieces pricing scales with batch size. Each addPieces call costs $0.008 + $0.003 × N, where N is the number of pieces in the batch. The base fee is shared across the batch, so adding many pieces in one call is cheaper per piece than adding them one at a time. A single-piece call costs $0.011. Each commit must fit the encoded Filecoin message-size budget. Legacy data sets also have an 80-piece safety cap. Piece metadata affects how many pieces fit within the byte budget. Because batch boundaries also depend on upload timing, cost previews conservatively price each supplied piece as a separate operation, so actual batched fees can be lower.
Fees are paid from a lifecycle reserve, not added twice to deposits. When a data set is created, ~$0.50 of USDFC is locked as a lifecycle reserve on the data set’s payment rail. Before pending one-time fees are paid, FWSS checks whether the reserve is below pending fees + $0.025. If so, it raises the fixed lockup enough that paying those fees leaves the reserve at its $0.50 target. The remaining reserve is refundable when the rail is finalized.
Why the reserve exists: wind-down after termination
Filecoin Pay does not allow raising a rail’s fixed lockup once the rail has been terminated. The lifecycle reserve gives you headroom to run wind-down operations (such as scheduling piece removals) after termination, when the reserve can no longer be refilled.
If you expect to need more wind-down operations than the reserve covers, account for them before terminating. A client-authorized termination relayed by the provider charges the $0.006 termination fee, pays pending fees, and releases the remaining reserve rather than replenishing it. Direct payer and provider termination paths do not charge this termination fee.
For the full lockup model (streaming versus fixed lockup, rail settlement, finalization), see the Payments & Storage cookbook and the Filecoin Pay spec.
Querying Upload Costs
Section titled “Querying Upload Costs”Use getUploadCosts() to preview costs without executing any transaction. This is useful for displaying pricing in a UI or letting users confirm before proceeding. The result reads the on-chain price list, so it reflects the rates, one-time fees, and lockups described above.
Getting the costs for uploading to an existing data set:
// Read the existing data set so reserve replenishment is estimated correctly.
const const dataSet: getDataSet.OutputTypedataSet = await function getDataSet(client: Client<Transport, Chain>, options: getDataSet.OptionsType): Promise<getDataSet.OutputType>getDataSet(const synapse: Synapsesynapse.Synapse.readClient: ReadClient<RpcSchema, PublicActions<Transport, FilecoinChain>>readClient, { dataSetId: bigintdataSetId: 42n })
if (const dataSet: getDataSet.OutputTypedataSet == null) throw new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error('Data set not found')
const const dataSetLeafCount: bigintdataSetLeafCount = await function getDataSetLeafCount(client: Client<Transport, Chain>, options: getDataSetLeafCount.OptionsType): Promise<getDataSetLeafCount.OutputType>getDataSetLeafCount(const synapse: Synapsesynapse.Synapse.readClient: ReadClient<RpcSchema, PublicActions<Transport, FilecoinChain>>readClient, { dataSetId: bigintdataSetId: 42n })
const { const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates, const fees: calculateUploadFees.OutputTypefees, const depositNeeded: bigintdepositNeeded } = await const synapse: Synapsesynapse.Synapse.storage: StorageManagerstorage.StorageManager.getUploadCosts(options: Omit<GetUploadCostsOptions, "clientAddress">): Promise<UploadCosts>getUploadCosts({
isNewDataSet?: boolean | undefinedisNewDataSet: false,
dataSetLeafCount?: bigint | undefineddataSetLeafCount,
currentLifecycleReserveBalance?: bigint | undefinedcurrentLifecycleReserveBalance: const dataSet: DataSetInfodataSet.lifecycleReserveBalance: bigintlifecycleReserveBalance,
pendingOneTimePayments?: bigint | undefinedpendingOneTimePayments: const dataSet: DataSetInfodataSet.pendingOneTimePayments: bigintpendingOneTimePayments,
pdpEndEpoch?: bigint | undefinedpdpEndEpoch: const dataSet: DataSetInfodataSet.pdpEndEpoch: bigintpdpEndEpoch,
pieceSizes: readonly bigint[]pieceSizes: [100n * const SIZE_CONSTANTS: {
readonly KiB: 1024n;
readonly MiB: bigint;
readonly GiB: bigint;
readonly TiB: bigint;
readonly PiB: bigint;
readonly MAX_UPLOAD_SIZE: 68182605824;
readonly MIN_UPLOAD_SIZE: 127;
readonly DEFAULT_UPLOAD_BATCH_SIZE: 32;
readonly MAX_LEGACY_ADD_PIECES_BATCH_SIZE: 80;
readonly MAX_ADD_PIECES_MESSAGE_SIZE: number;
readonly BYTES_PER_LEAF: 32n;
}
SIZE_CONSTANTS.type MiB: bigintMiB],
})
// fees.addPiecesFee is the one-time fee for this upload
// Pass every known raw piece size when committing a multi-piece batch.Getting the costs for uploading to a new data set:
const { const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates, const fees: calculateUploadFees.OutputTypefees, const lockups: {
rateDeltaPerEpoch: bigint;
lifecycleLockup: bigint;
reserveReplenishment: bigint;
streamingLockup: bigint;
cdnLockup: bigint;
cacheMissLockup: bigint;
total: bigint;
}
lockups, const depositNeeded: bigintdepositNeeded, const needsFwssMaxApproval: booleanneedsFwssMaxApproval, const ready: booleanready } = await const synapse: Synapsesynapse.Synapse.storage: StorageManagerstorage.StorageManager.getUploadCosts(options: Omit<GetUploadCostsOptions, "clientAddress">): Promise<UploadCosts>getUploadCosts({
pieceSizes: readonly bigint[]pieceSizes: [100n * const SIZE_CONSTANTS: {
readonly KiB: 1024n;
readonly MiB: bigint;
readonly GiB: bigint;
readonly TiB: bigint;
readonly PiB: bigint;
readonly MAX_UPLOAD_SIZE: 68182605824;
readonly MIN_UPLOAD_SIZE: 127;
readonly DEFAULT_UPLOAD_BATCH_SIZE: 32;
readonly MAX_LEGACY_ADD_PIECES_BATCH_SIZE: 80;
readonly MAX_ADD_PIECES_MESSAGE_SIZE: number;
readonly BYTES_PER_LEAF: 32n;
}
SIZE_CONSTANTS.type MiB: bigintMiB],
isNewDataSet?: boolean | undefinedisNewDataSet: true,
withCDN?: boolean | undefinedwithCDN: true,
})
// Storage rate per epoch (30 seconds)
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Rate per epoch:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates.perEpoch: bigintperEpoch), "USDFC")
// Storage rate per month
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Rate per month:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates.perMonth: bigintperMonth), "USDFC")
// One-time fees (create data set + add pieces)
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("One-time fees:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const fees: calculateUploadFees.OutputTypefees.total: biginttotal), "USDFC")
// Locked while the data set is active (lifecycle reserve, streaming, CDN)
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Total lockup:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const lockups: {
rateDeltaPerEpoch: bigint;
lifecycleLockup: bigint;
reserveReplenishment: bigint;
streamingLockup: bigint;
cdnLockup: bigint;
cacheMissLockup: bigint;
total: bigint;
}
lockups.total: biginttotal), "USDFC")
// USDFC to deposit
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Deposit needed:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const depositNeeded: bigintdepositNeeded), "USDFC")
// Whether FWSS needs to be approved
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Needs approval:", const needsFwssMaxApproval: booleanneedsFwssMaxApproval)
// Whether the account is ready to upload
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Ready to upload:", const ready: booleanready)Upload Preparation
Section titled “Upload Preparation”Before uploading, the WarmStorage operator must be approved and your account must be funded. FWSS uses a 30-day lockup (prepayment) period. If your account becomes underfunded, the provider may terminate the storage agreement, after which you have 30 days before data removal.
prepare() computes costs and returns a ready-to-execute transaction. This is the recommended approach — it handles deposit calculation, operator approval, and contract call routing in one step.
const { const costs: calculateUploadCosts.OutputTypecosts, const transaction: {
depositAmount: bigint;
includesApproval: boolean;
execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>;
} | null
transaction } = await const synapse: Synapsesynapse.Synapse.storage: StorageManagerstorage.StorageManager.prepare(options: PrepareOptions): Promise<PrepareResult>prepare({
PrepareOptions.pieceSizes: readonly bigint[]pieceSizes: [const SIZE_CONSTANTS: {
readonly KiB: 1024n;
readonly MiB: bigint;
readonly GiB: bigint;
readonly TiB: bigint;
readonly PiB: bigint;
readonly MAX_UPLOAD_SIZE: 68182605824;
readonly MIN_UPLOAD_SIZE: 127;
readonly DEFAULT_UPLOAD_BATCH_SIZE: 32;
readonly MAX_LEGACY_ADD_PIECES_BATCH_SIZE: 80;
readonly MAX_ADD_PIECES_MESSAGE_SIZE: number;
readonly BYTES_PER_LEAF: 32n;
}
SIZE_CONSTANTS.type GiB: bigintGiB],
})
// Inspect costs
const { const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates, const depositNeeded: bigintdepositNeeded } = const costs: calculateUploadCosts.OutputTypecosts // Upload costs breakdown
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Rate per month:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates.perMonth: bigintperMonth))
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Deposit needed:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const depositNeeded: bigintdepositNeeded))
// Execute if the account isn't ready
if (const transaction: {
depositAmount: bigint;
includesApproval: boolean;
execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>;
} | null
transaction) {
const { const depositAmount: bigintdepositAmount, const includesApproval: booleanincludesApproval } = const transaction: {
depositAmount: bigint;
includesApproval: boolean;
execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>;
}
transaction
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Deposit amount:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const depositAmount: bigintdepositAmount))
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Includes approval:", const includesApproval: booleanincludesApproval)
const { const hash: `0x${string}`hash } = await const transaction: {
depositAmount: bigint;
includesApproval: boolean;
execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>;
}
transaction.execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>
execute()
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Transaction confirmed:", const hash: `0x${string}`hash)
}
// Now safe to uploadWhen storing data across multiple providers, pass an array of contexts. The SDK aggregates per-context lockup while computing account-level values (debt, runway, buffer) once.
import { class SynapseSynapse, function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits, const SIZE_CONSTANTS: {
readonly KiB: 1024n;
readonly MiB: bigint;
readonly GiB: bigint;
readonly TiB: bigint;
readonly PiB: bigint;
readonly MAX_UPLOAD_SIZE: 68182605824;
readonly MIN_UPLOAD_SIZE: 127;
readonly DEFAULT_UPLOAD_BATCH_SIZE: 32;
readonly MAX_LEGACY_ADD_PIECES_BATCH_SIZE: 80;
readonly MAX_ADD_PIECES_MESSAGE_SIZE: number;
readonly BYTES_PER_LEAF: 32n;
}
SIZE_CONSTANTS, const TIME_CONSTANTS: {
readonly EPOCH_DURATION: 30;
readonly EPOCHS_PER_HOUR: 120n;
readonly EPOCHS_PER_DAY: 2880n;
readonly EPOCHS_PER_MONTH: 86400n;
readonly DAYS_PER_MONTH: 30n;
readonly DEFAULT_LOCKUP_DAYS: 30n;
readonly PERMIT_DEADLINE_DURATION: 3600;
}
TIME_CONSTANTS } from "@filoz/synapse-sdk"
import { function privateKeyToAccount(privateKey: Hex, options?: PrivateKeyToAccountOptions): PrivateKeyAccountprivateKeyToAccount } from 'viem/accounts'
const const synapse: Synapsesynapse = class SynapseSynapse.Synapse.create(options: SynapseOptions): Synapsecreate({ SynapseOptions.account: `0x${string}` | Accountaccount: function privateKeyToAccount(privateKey: Hex, options?: PrivateKeyToAccountOptions): PrivateKeyAccountprivateKeyToAccount('0x...'), SynapseOptions.source: string | nullsource: 'my-app' })
const const contexts: StorageContext[]contexts = await const synapse: Synapsesynapse.Synapse.storage: StorageManagerstorage.StorageManager.createContexts(options?: CreateContextsOptions): Promise<StorageContext[]>createContexts({ CreateContextsOptions.copies?: number | undefinedcopies: 3 })
// 1-year runway
const const oneYear: bigintoneYear = const TIME_CONSTANTS: {
readonly EPOCH_DURATION: 30;
readonly EPOCHS_PER_HOUR: 120n;
readonly EPOCHS_PER_DAY: 2880n;
readonly EPOCHS_PER_MONTH: 86400n;
readonly DAYS_PER_MONTH: 30n;
readonly DEFAULT_LOCKUP_DAYS: 30n;
readonly PERMIT_DEADLINE_DURATION: 3600;
}
TIME_CONSTANTS.type EPOCHS_PER_MONTH: 86400nEPOCHS_PER_MONTH * 12n
// Prepare a single deposit covering all 3 copies for 1 year
const { const costs: calculateUploadCosts.OutputTypecosts, const transaction: {
depositAmount: bigint;
includesApproval: boolean;
execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>;
} | null
transaction } = await const synapse: Synapsesynapse.Synapse.storage: StorageManagerstorage.StorageManager.prepare(options: PrepareOptions): Promise<PrepareResult>prepare({
PrepareOptions.context?: StorageContext | StorageContext[] | undefinedcontext: const contexts: StorageContext[]contexts,
PrepareOptions.pieceSizes: readonly bigint[]pieceSizes: [50n * const SIZE_CONSTANTS: {
readonly KiB: 1024n;
readonly MiB: bigint;
readonly GiB: bigint;
readonly TiB: bigint;
readonly PiB: bigint;
readonly MAX_UPLOAD_SIZE: 68182605824;
readonly MIN_UPLOAD_SIZE: 127;
readonly DEFAULT_UPLOAD_BATCH_SIZE: 32;
readonly MAX_LEGACY_ADD_PIECES_BATCH_SIZE: 80;
readonly MAX_ADD_PIECES_MESSAGE_SIZE: number;
readonly BYTES_PER_LEAF: 32n;
}
SIZE_CONSTANTS.type GiB: bigintGiB],
PrepareOptions.extraRunwayEpochs?: bigint | undefinedextraRunwayEpochs: const oneYear: bigintoneYear,
})
const { const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates, const depositNeeded: bigintdepositNeeded, const ready: booleanready } = const costs: calculateUploadCosts.OutputTypecosts
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Total monthly rate:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const rates: {
perEpoch: bigint;
perMonth: bigint;
}
rates.perMonth: bigintperMonth), "USDFC")
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Total deposit needed:", function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const depositNeeded: bigintdepositNeeded), "USDFC")
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Account ready:", const ready: booleanready)
if (const transaction: {
depositAmount: bigint;
includesApproval: boolean;
execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>;
} | null
transaction) {
const { const hash: `0x${string}`hash } = await const transaction: {
depositAmount: bigint;
includesApproval: boolean;
execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>;
}
transaction.execute: (options?: {
onHash?: (hash: Hash) => void;
}) => Promise<{
hash: Hash;
receipt: import("viem").TransactionReceipt | null;
}>
execute()
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log("Funded:", const hash: `0x${string}`hash)
}prepare() returns:
costs: The fullUploadCostsbreakdowntransaction: A transaction object withexecute(), ornullif the account is already ready
The transaction automatically picks the right contract call:
- Needs deposit + approval: calls
depositWithPermitAndApproveOperator - Needs approval only: calls
approveService - Needs deposit only: calls
depositWithPermit - Already ready: returns
transaction: null
Account Queries
Section titled “Account Queries”Read-only APIs for account-level cost visibility.
// Aggregate rate across all active rails
const { const ratePerEpoch: anyratePerEpoch, const ratePerMonth: anyratePerMonth } = await synapse.payments.totalAccountRate()
// Sum of lockupFixed across all rails (including terminated but not finalized)
const { const totalFixedLockup: anytotalFixedLockup } = await synapse.payments.totalAccountLockup()
// Total storage size across all live datasets
import { function getAccountTotalStorageSize(client: Client<Transport, Chain>, options: getAccountTotalStorageSize.OptionsType): Promise<getAccountTotalStorageSize.OutputType>getAccountTotalStorageSize } from '@filoz/synapse-core/warm-storage'
const { const totalSizeBytes: biginttotalSizeBytes, const datasetCount: numberdatasetCount } = await function getAccountTotalStorageSize(client: Client<Transport, Chain>, options: getAccountTotalStorageSize.OptionsType): Promise<getAccountTotalStorageSize.OutputType>getAccountTotalStorageSize(client, {
address: `0x${string}`address: '0x...',
})All rate values come in both per-epoch (contract-native) and per-month (ratePerEpoch * EPOCHS_PER_MONTH) units. Note that ratePerMonth from totalAccountRate() is computed as ratePerEpoch * EPOCHS_PER_MONTH — this is slightly less than the full-precision rates.perMonth returned by getUploadCosts() due to integer truncation. See Rate Precision for details.
Next Steps
Section titled “Next Steps”- Payments & Storage — Deep dive into the payment model mechanics
- StorageManager API Reference — Full SDK storage API
- PaymentsService API Reference — Full SDK payments API
- Upload Pipeline — Upload workflows from simple to advanced
- Storage Operations — Contexts, data sets, and retrieval