Skip to content

Quick Start with Synapse SDK

The Synapse SDK is your gateway to Filecoin Onchain Cloud — a decentralized, programmable cloud platform built on Filecoin. This comprehensive guide will walk you through everything you need to know to start building with the SDK.

The Synapse SDK provides an interface to Filecoin’s decentralized services ecosystem:

  • 🚀 Recommended Usage: Use the high-level Synapse class for a streamlined experience with sensible defaults
  • 🔧 Composable Components: Import and use individual components for fine-grained control over specific functionality

The SDK handles all the complexity of blockchain interactions, provider selection, and data management, so you can focus on building your application.

By the end of this guide, you’ll understand how to:

  • Install and configure the Synapse SDK
  • Connect to Filecoin networks (mainnet and calibration)
  • Manage payments and allowances
  • Upload and download data with Synapse SDK
  • Use advanced features like CDN and custom providers

Before installing the Synapse SDK, make sure you have the following:

Before you start building with Synapse SDK, you’ll need to request test tokens from faucets to pay transaction fees and storage fees. For the calibration testnet:

Get tFIL tokens:

Get test USDFC tokens:

The Synapse SDK requires Node.js 20+ and can be installed via npm, yarn, or pnpm:

Terminal window
npm install @filoz/synapse-sdk viem

Note: viem is a peer dependency and must be installed separately.

The Synapse class provides a complete, easy-to-use interface for interacting with Filecoin storage services.

Get started with storage in just a few lines of code.

import {
class Synapse
Synapse
,
function parseUnits(value: string | number | bigint | Dnum, decimals?: number): bigint
parseUnits
} from "@filoz/synapse-sdk"
import {
function privateKeyToAccount(privateKey: Hex, options?: PrivateKeyToAccountOptions): PrivateKeyAccount

@description Creates an Account from a private key.

@returnsA Private Key Account.

privateKeyToAccount
} from 'viem/accounts'
async function
function main(): Promise<void>
main
() {
// 1) Initialize the Synapse SDK
const
const synapse: Synapse
synapse
=
class Synapse
Synapse
.
Synapse.create(options: SynapseOptions): Synapse
create
({
SynapseOptions.account: `0x${string}` | Account
account
:
function privateKeyToAccount(privateKey: Hex, options?: PrivateKeyToAccountOptions): PrivateKeyAccount

@description Creates an Account from a private key.

@returnsA Private Key Account.

privateKeyToAccount
('0x...')
// Uncomment for high-performance incentive-aligned data retrievability through Filecoin Beam
// withCDN: true
})
// 2) Fund & approve (single tx)
const
const depositAmount: bigint
depositAmount
=
function parseUnits(value: string | number | bigint | Dnum, decimals?: number): bigint
parseUnits
("2.5")
const
const hash: `0x${string}`
hash
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.depositWithPermitAndApproveOperator(amount: TokenAmount, operator?: Address, rateAllowance?: TokenAmount, lockupAllowance?: TokenAmount, maxLockupPeriod?: bigint, deadline?: bigint, token?: TokenIdentifier): Promise<Hash>
depositWithPermitAndApproveOperator
(
const depositAmount: bigint
depositAmount
, // 2.5 USDFC (covers 1TiB of storage for 30 days)
)
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

Waits for the Transaction to be included on a Block (one confirmation), and then returns the Transaction Receipt. If the Transaction reverts, then the action will throw an error.

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains'

const client = createPublicClient({ chain: mainnet, transport: http(), }) const transactionReceipt = await client.waitForTransactionReceipt({ hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', })

waitForTransactionReceipt
({
hash: `0x${string}`

The hash of the transaction.

hash
})
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`✅ USDFC deposit and Warm Storage service approval successful!`);
// 3) Upload
const
const data: Uint8Array<ArrayBuffer>
data
= new
var TextEncoder: new () => TextEncoder

The TextEncoder interface takes a stream of code points as input and emits a stream of UTF-8 bytes.

MDN Reference

TextEncoder
().
TextEncoder.encode(input?: string): Uint8Array<ArrayBuffer>

The TextEncoder.encode() method takes a string as input, and returns a Global_Objects/Uint8Array containing the text given in parameters encoded with the specific method for that TextEncoder object.

MDN Reference

encode
(
`🚀 Welcome to decentralized storage on Filecoin Onchain Cloud!
Your data is safe here.
🌍 You need to make sure to meet the minimum size
requirement of 127 bytes per upload.`
);
const {
const pieceCid: PieceLink
pieceCid
,
const size: number
size
} = await
const synapse: Synapse
synapse
.
Synapse.storage: StorageManager
storage
.
StorageManager.upload(data: Uint8Array | ReadableStream<Uint8Array>, options?: StorageManagerUploadOptions): Promise<UploadResult>
upload
(
const data: Uint8Array<ArrayBuffer>
data
)
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`✅ Upload complete!`);
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`PieceCID: ${
const pieceCid: PieceLink
pieceCid
}`);
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`Size: ${
const size: number
size
} bytes`);
// 4) Download
const
const bytes: Uint8Array<ArrayBufferLike>
bytes
= await
const synapse: Synapse
synapse
.
Synapse.storage: StorageManager
storage
.
StorageManager.download(pieceCid: string | PieceCID, options?: StorageManagerDownloadOptions): Promise<Uint8Array>
download
(
const pieceCid: PieceLink
pieceCid
)
const
const decodedText: string
decodedText
= new
var TextDecoder: new (label?: string, options?: TextDecoderOptions) => TextDecoder

The TextDecoder interface represents a decoder for a specific text encoding, such as UTF-8, ISO-8859-2, KOI8-R, GBK, etc.

MDN Reference

TextDecoder
().
TextDecoder.decode(input?: AllowSharedBufferSource, options?: TextDecodeOptions): string

The TextDecoder.decode() method returns a string containing text decoded from the buffer passed as a parameter.

MDN Reference

decode
(
const bytes: Uint8Array<ArrayBufferLike>
bytes
);
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`✅ Download successful!`);
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`Downloaded data: ${
const decodedText: string
decodedText
}\n`);
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
("🎉 Data storage and retrieval successful!");
}
function main(): Promise<void>
main
().
Promise<void>.then<void, never>(onfulfilled?: ((value: void) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<void>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(() => {
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
("✅ Storage workflow completed successfully!");
}).
Promise<void>.catch<void>(onrejected?: ((reason: any) => void | PromiseLike<void>) | null | undefined): Promise<void>

Attaches a callback for only the rejection of the Promise.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of the callback.

catch
((
error: any
error
) => {
var console: Console
console
.
Console.error(...data: any[]): void

The console.error() static method outputs a message to the console at the 'error' log level.

MDN Reference

error
("❌ Error occurred:");
var console: Console
console
.
Console.error(...data: any[]): void

The console.error() static method outputs a message to the console at the 'error' log level.

MDN Reference

error
(
error: any
error
.
any
message
); // Clear error description
var console: Console
console
.
Console.error(...data: any[]): void

The console.error() static method outputs a message to the console at the 'error' log level.

MDN Reference

error
(
error: any
error
.
any
cause
); // Underlying error if any
});

What you just did:

  • ✅ Initialized synapse SDK for Filecoin Calibration
  • ✅ Deposited USDFC as payment tokens
  • ✅ Authorized the storage service to use the token
  • ✅ Uploaded data to decentralized storage
  • ✅ Retrieved it using only the content address

Now let’s break down each step…

First, set up the Synapse SDK with your credentials. We use wallet private key here as an example, but you can definitely inject signer from any wallet providers, such as MetaMask or wallet connect.

// Initialize SDK with your private key and RPC endpoint
const
const synapse: Synapse
synapse
=
class Synapse
Synapse
.
Synapse.create(options: SynapseOptions): Synapse
create
({
SynapseOptions.account: `0x${string}` | Account
account
:
function privateKeyToAccount(privateKey: Hex, options?: PrivateKeyToAccountOptions): PrivateKeyAccount

@description Creates an Account from a private key.

@returnsA Private Key Account.

privateKeyToAccount
('0x...') })

Before storing data, you need to deposit USDFC tokens in your payments account. The amount you deposit is entirely up to your anticipated storage and retrieval needs.

// Check current USDFC balance
const
const walletBalance: bigint
walletBalance
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.walletBalance(token?: TokenIdentifier): Promise<bigint>
walletBalance
(
const TOKENS: {
readonly USDFC: "USDFC";
readonly FIL: "FIL";
}
TOKENS
.
type USDFC: "USDFC"
USDFC
);
const
const formattedBalance: string
formattedBalance
=
function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits
(
const walletBalance: bigint
walletBalance
);
const
const depositAmount: bigint
depositAmount
=
function parseUnits(value: string | number | bigint | Dnum, decimals?: number): bigint
parseUnits
("2.5") // 2.5 USDFC
// Deposit USDFC for payment and approve Warm Storage service
const
const hash: `0x${string}`
hash
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.depositWithPermitAndApproveOperator(amount: TokenAmount, operator?: Address, rateAllowance?: TokenAmount, lockupAllowance?: TokenAmount, maxLockupPeriod?: bigint, deadline?: bigint, token?: TokenIdentifier): Promise<Hash>
depositWithPermitAndApproveOperator
(
const depositAmount: bigint
depositAmount
, // Deposit amount: 2.5 USDFC (covers 1TiB of storage for 30 days)
);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

Waits for the Transaction to be included on a Block (one confirmation), and then returns the Transaction Receipt. If the Transaction reverts, then the action will throw an error.

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains'

const client = createPublicClient({ chain: mainnet, transport: http(), }) const transactionReceipt = await client.waitForTransactionReceipt({ hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', })

waitForTransactionReceipt
({
hash: `0x${string}`

The hash of the transaction.

hash
});
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`✅ USDFC deposit and Warm Storage service approval successful!`);

Now you can upload data to decentralized storage and retrieve it:

// Upload data - SDK automatically selects provider and creates data set if needed
const
const data: Uint8Array<ArrayBuffer>
data
= new
var TextEncoder: new () => TextEncoder

The TextEncoder interface takes a stream of code points as input and emits a stream of UTF-8 bytes.

MDN Reference

TextEncoder
().
TextEncoder.encode(input?: string): Uint8Array<ArrayBuffer>

The TextEncoder.encode() method takes a string as input, and returns a Global_Objects/Uint8Array containing the text given in parameters encoded with the specific method for that TextEncoder object.

MDN Reference

encode
(
`🚀 Welcome to decentralized storage on Filecoin Onchain Cloud!
Your data is safe here.
🌍 You need to make sure to meet the minimum size
requirement of 127 bytes per upload.`
);
const {
const pieceCid: PieceLink
pieceCid
} = await
const synapse: Synapse
synapse
.
Synapse.storage: StorageManager
storage
.
StorageManager.upload(data: Uint8Array | ReadableStream<Uint8Array>, options?: StorageManagerUploadOptions): Promise<UploadResult>
upload
(
const data: Uint8Array<ArrayBuffer>
data
);
// Download data from any provider that has it
const
const downloadedData: Uint8Array<ArrayBufferLike>
downloadedData
= await
const synapse: Synapse
synapse
.
Synapse.storage: StorageManager
storage
.
StorageManager.download(pieceCid: string | PieceCID, options?: StorageManagerDownloadOptions): Promise<Uint8Array>
download
(
const pieceCid: PieceLink
pieceCid
);
const
const decodedText: string
decodedText
= new
var TextDecoder: new (label?: string, options?: TextDecoderOptions) => TextDecoder

The TextDecoder interface represents a decoder for a specific text encoding, such as UTF-8, ISO-8859-2, KOI8-R, GBK, etc.

MDN Reference

TextDecoder
().
TextDecoder.decode(input?: AllowSharedBufferSource, options?: TextDecodeOptions): string

The TextDecoder.decode() method returns a string containing text decoded from the buffer passed as a parameter.

MDN Reference

decode
(
const downloadedData: Uint8Array<ArrayBufferLike>
downloadedData
);
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
(`Downloaded data: ${
const decodedText: string
decodedText
}`);

Congratulations! You’ve successfully stored and retrieved data using the Synapse SDK. But this is just the beginning - the SDK offers many powerful features for building decentralized applications:

CategoryFeatures
🗄️ Advanced StorageCDN Integration: Enable fast global content delivery
Metadata Management: Tag and organize your data
Batch Operations: Upload multiple files efficiently
💰 Payment ManagementAutomated Settlements: Handle payment rails automatically
Cost Estimation: Preview storage costs before uploading
Allowance Management: Control spending limits
🛠️ Developer ToolsSession Keys: Improve user experience with delegated signing
Progress Callbacks: Track upload/download progress
Error Handling: Comprehensive error management
🌐 Network IntegrationProvider Discovery: Find optimal storage providers
Proof Verification: Verify data integrity with PDP
Subgraph Integration: Query blockchain data efficiently

For more control over provider selection and data set management:

// Create a storage context with specific provider
const
const context: StorageContext
context
= await
const synapse: Synapse
synapse
.
Synapse.storage: StorageManager
storage
.
StorageManager.createContext(options?: StorageServiceOptions): Promise<StorageContext>
createContext
({
StorageServiceOptions.providerId?: bigint
providerId
: 1n, // Use specific provider
StorageServiceOptions.withCDN?: boolean
withCDN
: true, // Enable CDN for faster retrieval
StorageServiceOptions.metadata?: Record<string, string>
metadata
: {
category: string
category
: "documents",
version: string
version
: "1.0",
},
});
// Upload to this specific context
const
const result: UploadResult
result
= await
const context: StorageContext
context
.
StorageContext.upload(data: Uint8Array | ReadableStream<Uint8Array>, options?: UploadOptions): Promise<UploadResult>
upload
(
const data: Uint8Array<ArrayBufferLike>
data
);
// Download from this context
const
const downloaded: Uint8Array<ArrayBufferLike>
downloaded
= await
const context: StorageContext
context
.
StorageContext.download(pieceCid: string | PieceCID, options?: DownloadOptions): Promise<Uint8Array>
download
(
const result: UploadResult
result
.
UploadResult.pieceCid: PieceLink
pieceCid
);
  • providerId: By specifying providerId, you tell Synapse SDK to store (and later retrieve) your data specifically with that provider.

  • withCDN: Setting withCDN: true enables Filecoin Beam, the decentralized retrieval and delivery layer. So global users can download data faster, and pay-by-egress billing.

  • metadata: Attach custom key-value pairs to your data set for easy categorization, tagging, or later querying. This metadata is stored on-chain and can be used by apps or indexing systems.

// Get all approved providers
const
const storageInfo: StorageInfo
storageInfo
= await
const synapse: Synapse
synapse
.
Synapse.storage: StorageManager
storage
.
StorageManager.getStorageInfo(): Promise<StorageInfo>
getStorageInfo
();
const
const providers: PDPProvider[]
providers
=
const storageInfo: StorageInfo
storageInfo
.
StorageInfo.providers: PDPProvider[]
providers
;
var console: Console
console
.
Console.log(...data: any[]): void

The console.log() static method outputs a message to the console.

MDN Reference

log
("Available providers:");
const providers: PDPProvider[]
providers
.
Array<PDPProvider>.forEach(callbackfn: (value: PDPProvider, index: number, array: PDPProvider[]) => void, thisArg?: any): void

Performs the specified action for each element in an array.

@paramcallbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.

@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.

forEach
((
provider: PDPProvider
provider
) => {
var console: Console
console
.
Console.table(tabularData?: any, properties?: string[]): void

The console.table() static method displays tabular data as a table.

MDN Reference

table
({
type ID: bigint
ID
:
provider: PDPProvider
provider
.
PDPProvider.id: bigint
id
,
type Name: string
Name
:
provider: PDPProvider
provider
.
name: string
name
,
type Description: string
Description
:
provider: PDPProvider
provider
.
description: string
description
,
type Active: boolean
Active
:
provider: PDPProvider
provider
.
isActive: boolean
isActive
,
type ProviderAddress: `0x${string}`
ProviderAddress
:
provider: PDPProvider
provider
.
serviceProvider: `0x${string}`
serviceProvider
,
type PDPServiceURL: string
PDPServiceURL
:
provider: PDPProvider
provider
.
PDPProvider.pdp: PDPOffering
pdp
.
PDPOffering.serviceURL: string
serviceURL
,
});
});

Ready to dive deeper? Check out these comprehensive guides:

For complete API documentation, see the API Reference which covers:

  • All SDK classes and methods
  • TypeScript interfaces and types
  • Configuration options
  • Error handling patterns