Skip to content

Components

This page describes the components of the Synapse SDK and how they work together. You’ll learn how each component can be used independently, how they are organized within the SDK architecture, and how they interact with the underlying smart contracts and storage providers.

The SDK is built from these core components:

  • Synapse - Main SDK entry point with simple, high-level API
  • PaymentsService - SDK client for managing deposits, approvals, and payment rails (interacts with Filecoin Pay contract)
  • StorageManager, StorageContext - Storage operation classes
  • WarmStorageService - SDK client for storage coordination and pricing (interacts with WarmStorage contract)
  • PDPVerifier - Client for PDPVerifier contract - get data set and piece status, create data sets and add pieces
  • PDPServer - HTTP client for Curio providers - create data sets and add pieces
  • PDPAuthHelper - Signature generation utility - Generate EIP-712 signatures for authenticated operations (create data sets and add pieces)

The following diagram illustrates how these components relate to each other and the external systems they interact with:

graph LR
    subgraph "Public API"
        Synapse
    end

    subgraph "Payment Services"
        PS[PaymentsService]
    end

    subgraph "Storage Services"
        SM[StorageManager]
    end

    subgraph "Lower-Level"
        WSS[WarmStorageService]
        SC[StorageContext]
        PDPS[PDPServer]
        PDPA[PDPAuthHelper]
        PDPV[PDPVerifier]
    end
    Synapse --> SM
    Synapse --> PS
    SM --> SC
    SM --> WSS
    SC --> PDPS
    SC --> PDPA
    SC --> PDPV
    PS --> SC

The SDK architecture is guided by several key principles that ensure maintainability, flexibility, and ease of use:

Design Principles:

  • Separation of Concerns: Protocol, business logic, and application layers are distinct
  • Composability: Each component can be used independently or together
  • Abstraction: SDK hides blockchain complexity from applications
  • Verification: All storage backed by cryptographic proofs

The SDK is organized into three layers, each serving a specific purpose:

  • High-Level API: The Synapse class provides a simple interface for common operations.
  • Service Layer: PaymentsService and StorageManager handle domain-specific logic.
  • Lower-Level Clients: Direct access to contracts and providers for advanced use cases.

Purpose: Main SDK entry point with simple, high-level API

API Reference: Synapse API Reference

Synapse Interface:

interface
interface SynapseAPI
SynapseAPI
{
// Create a new Synapse instance
SynapseAPI.create(options: SynapseOptions): Promise<Synapse>
create
(
options: SynapseOptions
options
:
(alias) interface SynapseOptions
import SynapseOptions
SynapseOptions
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
class Synapse
Synapse
>;
// Properties
SynapseAPI.payments: PaymentsService
payments
:
class PaymentsService
PaymentsService
;
SynapseAPI.storage: StorageManager
storage
:
class StorageManager
StorageManager
;
// Storage Information (pricing, providers, service parameters, allowances)
SynapseAPI.getStorageInfo(): Promise<StorageInfo>
getStorageInfo
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface StorageInfo
import StorageInfo
StorageInfo
>;
SynapseAPI.getProviderInfo(providerAddress: string): Promise<ProviderInfo>
getProviderInfo
(
providerAddress: string
providerAddress
: string):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface ProviderInfo
import ProviderInfo
ProviderInfo
>;
// Network Information
SynapseAPI.getNetwork(): FilecoinNetworkType
getNetwork
():
type FilecoinNetworkType = "mainnet" | "calibration"
FilecoinNetworkType
;
SynapseAPI.getChainId(): number
getChainId
(): number;
// Contract Addresses
SynapseAPI.getWarmStorageAddress(): string
getWarmStorageAddress
(): string;
SynapseAPI.getPaymentsAddress(): string
getPaymentsAddress
(): string;
SynapseAPI.getPDPVerifierAddress(): string
getPDPVerifierAddress
(): string;
// Ethers Helpers
SynapseAPI.getProvider(): ethers.Provider
getProvider
():
import ethers
ethers
.
export Provider

A Provider is the primary method to interact with the read-only content on Ethereum.

It allows access to details about accounts, blocks and transactions and the ability to query event logs and simulate contract execution.

Account data includes the balance, transaction count, code and state trie storage.

Simulating execution can be used to call, estimate gas and get transaction results.

The [[broadcastTransaction]] is the only method which allows updating the blockchain, but it is usually accessed by a [[Signer]], since a private key must be used to sign the transaction before it can be broadcast.

Provider
;
SynapseAPI.getSigner(): ethers.Signer
getSigner
():
import ethers
ethers
.
export Signer

A Signer represents an account on the Ethereum Blockchain, and is most often backed by a private key represented by a mnemonic or residing on a Hardware Wallet.

The API remains abstract though, so that it can deal with more advanced exotic Signing entities, such as Smart Contract Wallets or Virtual Wallets (where the private key may not be known).

Signer
;
}

The PaymentsService provides direct access to the Filecoin Pay contract, enabling you to:

  • Manage token deposits and withdrawals
  • Approve operators for automated payments
  • Query and settle payment rails
  • Monitor account health and balance

This is your primary interface for all payment-related operations in the SDK.

API Reference: PaymentsService API Reference

Check out the Payment Operations guide for more details.

Payments Service Interface:

interface
interface PaymentsServiceAPI
PaymentsServiceAPI
{
// Balances
PaymentsServiceAPI.walletBalance(token: TokenIdentifier): Promise<bigint>
walletBalance
(
token: string
token
:
type TokenIdentifier = string
TokenIdentifier
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<bigint>;
PaymentsServiceAPI.balance(): Promise<bigint>
balance
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<bigint>;
PaymentsServiceAPI.accountInfo(token: TokenIdentifier): Promise<AccountInfo>
accountInfo
(
token: string
token
:
type TokenIdentifier = string
TokenIdentifier
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
interface AccountInfo
AccountInfo
>;
// Token Operations
PaymentsServiceAPI.decimals(token: TokenIdentifier): number
decimals
(
token: string
token
:
type TokenIdentifier = string
TokenIdentifier
): number;
PaymentsServiceAPI.allowance(spender: string, token: TokenIdentifier): Promise<bigint>
allowance
(
spender: string
spender
: string,
token: string
token
:
type TokenIdentifier = string
TokenIdentifier
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<bigint>;
PaymentsServiceAPI.approve(spender: string, amount: TokenAmount): Transaction
approve
(
spender: string
spender
: string,
amount: TokenAmount
amount
:
type TokenAmount = number | bigint
TokenAmount
):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
// Deposits
PaymentsServiceAPI.deposit(amount: TokenAmount): Transaction
deposit
(
amount: TokenAmount
amount
:
type TokenAmount = number | bigint
TokenAmount
):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
PaymentsServiceAPI.depositWithPermit(amount: TokenAmount): Transaction
depositWithPermit
(
amount: TokenAmount
amount
:
type TokenAmount = number | bigint
TokenAmount
):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
PaymentsServiceAPI.depositWithPermitAndApproveOperator(amount: TokenAmount, operator: string, rateAllowance: TokenAmount, lockupAllowance: TokenAmount, maxLockupPeriod: TokenAmount): Transaction
depositWithPermitAndApproveOperator
(
amount: TokenAmount
amount
:
type TokenAmount = number | bigint
TokenAmount
,
operator: string
operator
: string,
rateAllowance: TokenAmount
rateAllowance
:
type TokenAmount = number | bigint
TokenAmount
,
lockupAllowance: TokenAmount
lockupAllowance
:
type TokenAmount = number | bigint
TokenAmount
,
maxLockupPeriod: TokenAmount
maxLockupPeriod
:
type TokenAmount = number | bigint
TokenAmount
):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
// Operator management
PaymentsServiceAPI.approveService(service: string, rateAllowance: TokenAmount, lockupAllowance: TokenAmount, maxLockupPeriod: TokenAmount, token: TokenIdentifier): Transaction
approveService
(
service: string
service
: string,
rateAllowance: TokenAmount
rateAllowance
:
type TokenAmount = number | bigint
TokenAmount
,
lockupAllowance: TokenAmount
lockupAllowance
:
type TokenAmount = number | bigint
TokenAmount
,
maxLockupPeriod: TokenAmount
maxLockupPeriod
:
type TokenAmount = number | bigint
TokenAmount
,
token: string
token
:
type TokenIdentifier = string
TokenIdentifier
):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
PaymentsServiceAPI.revokeService(service: string, token: TokenIdentifier): Transaction
revokeService
(
service: string
service
: string,
token: string
token
:
type TokenIdentifier = string
TokenIdentifier
):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
PaymentsServiceAPI.serviceApproval(service: string): Promise<ServiceApproval>
serviceApproval
(
service: string
service
: string):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
interface ServiceApproval
ServiceApproval
>;
// Rails
PaymentsServiceAPI.getRailsAsPayer(): Promise<RailInfo[]>
getRailsAsPayer
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface RailInfo
import RailInfo
RailInfo
[]>;
PaymentsServiceAPI.getRailsAsPayee(): Promise<RailInfo[]>
getRailsAsPayee
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface RailInfo
import RailInfo
RailInfo
[]>;
PaymentsServiceAPI.getRail(railId: bigint): Promise<Rail>
getRail
(
railId: bigint
railId
: bigint):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
type Rail = {
token: string;
from: string;
to: string;
operator: string;
validator: string;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: string;
}
Rail
>;
PaymentsServiceAPI.getSettlementAmounts(railId: bigint, targetEpoch?: bigint): Promise<SettlementResult>
getSettlementAmounts
(
railId: bigint
railId
: bigint,
targetEpoch: bigint | undefined
targetEpoch
?: bigint
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface SettlementResult
import SettlementResult
SettlementResult
>;
PaymentsServiceAPI.settle(railId: bigint, targetEpoch?: bigint): Transaction
settle
(
railId: bigint
railId
: bigint,
targetEpoch: bigint | undefined
targetEpoch
?: bigint):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
PaymentsServiceAPI.settleTerminatedRail(railId: bigint): Transaction
settleTerminatedRail
(
railId: bigint
railId
: bigint):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
PaymentsServiceAPI.settleAuto(railId: bigint, targetEpoch?: bigint): Transaction
settleAuto
(
railId: bigint
railId
: bigint,
targetEpoch: bigint | undefined
targetEpoch
?: bigint):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
}

Purpose: High-level, auto-managed storage operations - upload and download data to and from the Filecoin Onchain Cloud.

API Reference: StorageManager API Reference

Check out the Storage Operations guide for more details.

Storage Manager Interface:

interface
interface StorageManagerAPI
StorageManagerAPI
{
// Upload & Download
StorageManagerAPI.upload(data: Uint8Array | ArrayBuffer, options?: StorageManagerUploadOptions): Promise<UploadResult>
upload
(
data: ArrayBuffer | Uint8Array<ArrayBufferLike>
data
:
interface Uint8Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>

A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.

Uint8Array
|
interface ArrayBuffer

Represents a raw buffer of binary data, which is used to store data for the different typed arrays. ArrayBuffers cannot be read from or written to directly, but can be passed to a typed array or DataView Object to interpret the raw buffer as needed.

ArrayBuffer
,
options: StorageManagerUploadOptions | undefined
options
?:
interface StorageManagerUploadOptions
StorageManagerUploadOptions
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface UploadResult
import UploadResult
UploadResult
>;
StorageManagerAPI.download(pieceCid: string | PieceCID): Promise<Uint8Array>
download
(
pieceCid: string | PieceLink
pieceCid
: string |
type PieceCID = Link<MerkleTreeNode, RAW_CODE, MulticodecCode<4113, "fr32-sha2-256-trunc254-padded-binary-tree">, 1>
PieceCID
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
interface Uint8Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>

A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.

Uint8Array
>;
// Context Management
StorageManagerAPI.createContext(options?: StorageServiceOptions): Promise<StorageContext>
createContext
(
options: StorageServiceOptions | undefined
options
?:
(alias) interface StorageServiceOptions
import StorageServiceOptions
StorageServiceOptions
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
class StorageContext
StorageContext
>;
StorageManagerAPI.getDefaultContext(): Promise<StorageContext>
getDefaultContext
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
class StorageContext
StorageContext
>;
// Data Set Management
StorageManagerAPI.findDataSets(clientAddress?: string): Promise<EnhancedDataSetInfo[]>
findDataSets
(
clientAddress: string | undefined
clientAddress
?: string):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface EnhancedDataSetInfo
import EnhancedDataSetInfo
EnhancedDataSetInfo
[]>;
StorageManagerAPI.terminateDataSet(dataSetId: number): Transaction
terminateDataSet
(
dataSetId: number
dataSetId
: number):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
// Preflight & Info
StorageManagerAPI.preflightUpload(size: number, options?: {
withCDN?: boolean;
metadata?: Record<string, string>;
}): Promise<PreflightInfo>
preflightUpload
(
size: number
size
: number,
options: {
withCDN?: boolean;
metadata?: Record<string, string>;
} | undefined
options
?: {
withCDN?: boolean
withCDN
?: boolean;
metadata?: Record<string, string>
metadata
?:
type Record<K extends keyof any, T> = { [P in K]: T; }

Construct a type with a set of properties K of type T

Record
<string, string> }
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface PreflightInfo
import PreflightInfo
PreflightInfo
>;
StorageManagerAPI.getStorageInfo(): Promise<StorageInfo>
getStorageInfo
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface StorageInfo
import StorageInfo
StorageInfo
>;
}

Purpose: Provider-specific storage operations - upload and download data to and from the Filecoin Onchain Cloud.

API Reference: StorageContext API Reference

Check out the Storage Context guide for more details.

Purpose: SDK client for storage coordination and pricing - storage pricing and cost calculations, data set management and queries, metadata operations (data sets and pieces), service provider approval management, contract address discovery, data set creation verification.

API Reference: WarmStorageService API Reference

WarmStorageService Interface:

interface
interface WarmStorageServiceAPI
WarmStorageServiceAPI
{
// Factory Method
WarmStorageServiceAPI.create(provider: ethers.Provider, warmStorageAddress: string): Promise<WarmStorageService>
create
(
provider: ethers.Provider
provider
:
import ethers
ethers
.
export Provider

A Provider is the primary method to interact with the read-only content on Ethereum.

It allows access to details about accounts, blocks and transactions and the ability to query event logs and simulate contract execution.

Account data includes the balance, transaction count, code and state trie storage.

Simulating execution can be used to call, estimate gas and get transaction results.

The [[broadcastTransaction]] is the only method which allows updating the blockchain, but it is usually accessed by a [[Signer]], since a private key must be used to sign the transaction before it can be broadcast.

Provider
,
warmStorageAddress: string
warmStorageAddress
: string
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
class WarmStorageService
WarmStorageService
>;
// Data Set Queries
WarmStorageServiceAPI.getDataSet(dataSetId: number): Promise<DataSetInfo>
getDataSet
(
dataSetId: number
dataSetId
: number):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface DataSetInfo
import DataSetInfo
DataSetInfo
>;
WarmStorageServiceAPI.getClientDataSets(clientAddress: string): Promise<DataSetInfo[]>
getClientDataSets
(
clientAddress: string
clientAddress
: string):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface DataSetInfo
import DataSetInfo
DataSetInfo
[]>;
WarmStorageServiceAPI.getClientDataSetsWithDetails(client: string, onlyManaged?: boolean): Promise<EnhancedDataSetInfo[]>
getClientDataSetsWithDetails
(
client: string
client
: string,
onlyManaged: boolean | undefined
onlyManaged
?: boolean
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
(alias) interface EnhancedDataSetInfo
import EnhancedDataSetInfo
EnhancedDataSetInfo
[]>;
// Metadata Operations
WarmStorageServiceAPI.getDataSetMetadata(dataSetId: number): Promise<Record<string, string>>
getDataSetMetadata
(
dataSetId: number
dataSetId
: number):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
type Record<K extends keyof any, T> = { [P in K]: T; }

Construct a type with a set of properties K of type T

Record
<string, string>>;
WarmStorageServiceAPI.getDataSetMetadataByKey(dataSetId: number, key: string): Promise<string | null>
getDataSetMetadataByKey
(
dataSetId: number
dataSetId
: number,
key: string
key
: string
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<string | null>;
WarmStorageServiceAPI.getPieceMetadata(dataSetId: number, pieceId: number): Promise<Record<string, string>>
getPieceMetadata
(
dataSetId: number
dataSetId
: number,
pieceId: number
pieceId
: number
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
type Record<K extends keyof any, T> = { [P in K]: T; }

Construct a type with a set of properties K of type T

Record
<string, string>>;
WarmStorageServiceAPI.getPieceMetadataByKey(dataSetId: number, pieceId: number, key: string): Promise<string | null>
getPieceMetadataByKey
(
dataSetId: number
dataSetId
: number,
pieceId: number
pieceId
: number,
key: string
key
: string
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<string | null>;
// Pricing & Cost Calculations
WarmStorageServiceAPI.getServicePrice(): Promise<ServicePriceInfo>
getServicePrice
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
type ServicePriceInfo = {
pricePerTiBPerMonthNoCDN: bigint;
pricePerTiBCdnEgress: bigint;
pricePerTiBCacheMissEgress: bigint;
tokenAddress: string;
epochsPerMonth: bigint;
minimumPricePerMonth: bigint;
}
ServicePriceInfo
>;
WarmStorageServiceAPI.calculateStorageCost(sizeInBytes: number): Promise<CalculateStorageCostResult>
calculateStorageCost
(
sizeInBytes: number
sizeInBytes
: number
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
type CalculateStorageCostResult = {
perEpoch: bigint;
perDay: bigint;
perMonth: bigint;
withCDN: {
perEpoch: bigint;
perDay: bigint;
perMonth: bigint;
};
}
CalculateStorageCostResult
>;
WarmStorageServiceAPI.checkAllowanceForStorage(sizeInBytes: number, withCDN: boolean, paymentsService: PaymentsService, lockupDays?: number): Promise<CheckAllowanceForStorageResult>
checkAllowanceForStorage
(
sizeInBytes: number
sizeInBytes
: number,
withCDN: boolean
withCDN
: boolean,
paymentsService: PaymentsService
paymentsService
:
class PaymentsService
PaymentsService
,
lockupDays: number | undefined
lockupDays
?: number
):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<
type CheckAllowanceForStorageResult = {
rateAllowanceNeeded: bigint;
lockupAllowanceNeeded: bigint;
currentRateAllowance: bigint;
currentLockupAllowance: bigint;
currentRateUsed: bigint;
currentLockupUsed: bigint;
sufficient: boolean;
message?: string;
costs: {
perEpoch: bigint;
perDay: bigint;
perMonth: bigint;
};
depositAmountNeeded: bigint;
}
CheckAllowanceForStorageResult
>;
// Data Set Management
WarmStorageServiceAPI.terminateDataSet(signer: ethers.Signer, dataSetId: number): Transaction
terminateDataSet
(
signer: ethers.Signer
signer
:
import ethers
ethers
.
export Signer

A Signer represents an account on the Ethereum Blockchain, and is most often backed by a private key represented by a mnemonic or residing on a Hardware Wallet.

The API remains abstract though, so that it can deal with more advanced exotic Signing entities, such as Smart Contract Wallets or Virtual Wallets (where the private key may not be known).

Signer
,
dataSetId: number
dataSetId
: number):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
WarmStorageServiceAPI.topUpCDNPaymentRails(signer: ethers.Signer, dataSetId: number, cdnAmountToAdd: bigint, cacheMissAmountToAdd: bigint): Transaction
topUpCDNPaymentRails
(
signer: ethers.Signer
signer
:
import ethers
ethers
.
export Signer

A Signer represents an account on the Ethereum Blockchain, and is most often backed by a private key represented by a mnemonic or residing on a Hardware Wallet.

The API remains abstract though, so that it can deal with more advanced exotic Signing entities, such as Smart Contract Wallets or Virtual Wallets (where the private key may not be known).

Signer
,
dataSetId: number
dataSetId
: number,
cdnAmountToAdd: bigint
cdnAmountToAdd
: bigint,
cacheMissAmountToAdd: bigint
cacheMissAmountToAdd
: bigint
):
type Transaction = Promise<ethers.TransactionResponse>
Transaction
;
WarmStorageServiceAPI.getApprovedProviderIds(): Promise<number[]>
getApprovedProviderIds
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<number[]>;
WarmStorageServiceAPI.isProviderIdApproved(providerId: number): Promise<boolean>
isProviderIdApproved
(
providerId: number
providerId
: number):
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<boolean>;
// Proving Period
WarmStorageServiceAPI.getMaxProvingPeriod(): Promise<number>
getMaxProvingPeriod
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<number>;
WarmStorageServiceAPI.getChallengeWindow(): Promise<number>
getChallengeWindow
():
interface Promise<T>

Represents the completion of an asynchronous operation

Promise
<number>;
}

Purpose: Client for PDPVerifier contract - get dataset and piece status, create data sets and add pieces.

API Reference: PDPVerifier API Reference

PDPVerifier Example:

const
const pdpVerifier: PDPVerifier
pdpVerifier
= new
new PDPVerifier(provider: ethers.Provider, contractAddress: string): PDPVerifier
PDPVerifier
(
const provider: ethers.Provider
provider
,
const pdpVerifierAddress: string
pdpVerifierAddress
);
// Check if data set is live
const
const isLive: boolean
isLive
= await
const pdpVerifier: PDPVerifier
pdpVerifier
.
PDPVerifier.dataSetLive(dataSetId: number): Promise<boolean>
dataSetLive
(
const dataSetId: number
dataSetId
);
// Query data set information
const
const nextPieceId: number
nextPieceId
= await
const pdpVerifier: PDPVerifier
pdpVerifier
.
PDPVerifier.getNextPieceId(dataSetId: number): Promise<number>
getNextPieceId
(
const dataSetId: number
dataSetId
);
const
const listener: string
listener
= await
const pdpVerifier: PDPVerifier
pdpVerifier
.
PDPVerifier.getDataSetListener(dataSetId: number): Promise<string>
getDataSetListener
(
const dataSetId: number
dataSetId
);
const
const storageProvider: {
storageProvider: string;
proposedStorageProvider: string;
}
storageProvider
= await
const pdpVerifier: PDPVerifier
pdpVerifier
.
PDPVerifier.getDataSetStorageProvider(dataSetId: number): Promise<{
storageProvider: string;
proposedStorageProvider: string;
}>
getDataSetStorageProvider
(
const dataSetId: number
dataSetId
);
const
const leafCount: number
leafCount
= await
const pdpVerifier: PDPVerifier
pdpVerifier
.
PDPVerifier.getDataSetLeafCount(dataSetId: number): Promise<number>
getDataSetLeafCount
(
const dataSetId: number
dataSetId
);
const
const activePieces: {
pieces: Array<{
pieceCid: PieceCID;
pieceId: number;
}>;
hasMore: boolean;
}
activePieces
= await
const pdpVerifier: PDPVerifier
pdpVerifier
.
PDPVerifier.getActivePieces(dataSetId: number, options?: {
offset?: number;
limit?: number;
signal?: AbortSignal;
}): Promise<{
pieces: Array<{
pieceCid: PieceCID;
pieceId: number;
}>;
hasMore: boolean;
}>
getActivePieces
(
const dataSetId: number
dataSetId
);
// Extract data set ID from transaction receipt
const
const extractedId: number | null
extractedId
= await
const pdpVerifier: PDPVerifier
pdpVerifier
.
PDPVerifier.extractDataSetIdFromReceipt(receipt: ethers.TransactionReceipt): number | null
extractDataSetIdFromReceipt
(
const transactionReceipt: ethers.TransactionReceipt
transactionReceipt
);

Purpose: Generate EIP-712 signatures for authenticated operations - create data set, add pieces, schedule piece removals, delete data set. Used by PDPServer to sign operations and pass to Curio providers.

API Reference: PDPAuthHelper API Reference

PDPAuthHelper Example:

const
const authHelper: PDPAuthHelper
authHelper
= new
new PDPAuthHelper(serviceContractAddress: string, signer: ethers.Signer, chainId: bigint): PDPAuthHelper
PDPAuthHelper
(
const warmStorageAddress: string
warmStorageAddress
,
const signer: ethers.Signer
signer
,
const chainId: bigint
chainId
);
// Sign data set creation
const
const createDataSetSig: AuthSignature
createDataSetSig
= await
const authHelper: PDPAuthHelper
authHelper
.
PDPAuthHelper.signCreateDataSet(clientDataSetId: bigint, payee: string, metadata?: MetadataEntry[]): Promise<AuthSignature>
signCreateDataSet
(
const clientDataSetId: bigint
clientDataSetId
,
const payeeAddress: string
payeeAddress
,
const datasetMetadata: MetadataEntry[] | undefined
datasetMetadata
);
// Sign piece additions (nonce prevents replay attacks)
const
const addPiecesSig: AuthSignature
addPiecesSig
= await
const authHelper: PDPAuthHelper
authHelper
.
PDPAuthHelper.signAddPieces(clientDataSetId: bigint, nonce: bigint, pieceDataArray: PieceCID[] | string[], metadata?: MetadataEntry[][]): Promise<AuthSignature>
signAddPieces
(
const clientDataSetId: bigint
clientDataSetId
,
const nonce: bigint
nonce
,
const pieceDataArray: PieceLink[] | string[]
pieceDataArray
,
const metadata: MetadataEntry[][] | undefined
metadata
);
// Sign piece removal scheduling
const
const schedulePieceRemovalsSig: AuthSignature
schedulePieceRemovalsSig
= await
const authHelper: PDPAuthHelper
authHelper
.
PDPAuthHelper.signSchedulePieceRemovals(clientDataSetId: bigint, pieceIds: Array<bigint>): Promise<AuthSignature>
signSchedulePieceRemovals
(
const clientDataSetId: bigint
clientDataSetId
,
const pieceIds: bigint[]
pieceIds
);
// Sign data set deletion
const
const deleteDataSetSig: AuthSignature
deleteDataSetSig
= await
const authHelper: PDPAuthHelper
authHelper
.
PDPAuthHelper.signDeleteDataSet(clientDataSetId: bigint): Promise<AuthSignature>
signDeleteDataSet
(
const clientDataSetId: bigint
clientDataSetId
);
// All signatures return { signature, v, r, s, signedData }

Purpose: HTTP client for Curio provider APIs - data set creation and management, piece uploads and downloads, piece discovery and status tracking, transaction status polling, EIP-712 signature generation for operations.

API Reference: PDPServer API Reference

PDPServer Example:

const
const authHelper: PDPAuthHelper
authHelper
= new
new PDPAuthHelper(serviceContractAddress: string, signer: ethers.Signer, chainId: bigint): PDPAuthHelper
PDPAuthHelper
(
const warmStorageAddress: string
warmStorageAddress
,
const signer: ethers.Signer
signer
,
const chainId: bigint
chainId
);
const
const pdpServer: PDPServer
pdpServer
= new
new PDPServer(authHelper: PDPAuthHelper | null, serviceURL: string): PDPServer
PDPServer
(
const authHelper: PDPAuthHelper
authHelper
, "https://pdp.provider.com");
// Verify provider is active
try {
await
const pdpServer: PDPServer
pdpServer
.
PDPServer.ping(): Promise<void>
ping
();
} catch (
var error: unknown
error
) {
throw new
var Error: ErrorConstructor
new (message?: string) => Error
Error
(`Provider is not active: ${
var error: unknown
error
}`);
}
// Create a data set
const
const createResult: CreateDataSetResponse
createResult
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.createDataSet(clientDataSetId: bigint, payee: string, payer: string, metadata: MetadataEntry[], recordKeeper: string): Promise<CreateDataSetResponse>
createDataSet
(
const clientDataSetId: bigint
clientDataSetId
,
const payee: string
payee
,
const payer: string
payer
,
const datasetMetadata: MetadataEntry[]
datasetMetadata
,
const warmStorageAddress: string
warmStorageAddress
);
// Monitor creation status
const
const creationStatus: DataSetCreationStatusResponse
creationStatus
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.getDataSetCreationStatus(txHash: string): Promise<DataSetCreationStatusResponse>
getDataSetCreationStatus
(
const createResult: CreateDataSetResponse
createResult
.
CreateDataSetResponse.txHash: string
txHash
);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(`Status: ${
const creationStatus: DataSetCreationStatusResponse
creationStatus
.
DataSetCreationStatusResponse.txStatus: string
txStatus
}, ID: ${
const creationStatus: DataSetCreationStatusResponse
creationStatus
.
DataSetCreationStatusResponse.dataSetId?: number | undefined
dataSetId
}`);
// Create and add pieces in one operation
const
const batchResult: CreateDataSetResponse
batchResult
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.createAndAddPieces(clientDataSetId: bigint, payee: string, payer: string, recordKeeper: string, pieceDataArray: PieceCID[] | string[], metadata: {
dataset?: MetadataEntry[];
pieces?: MetadataEntry[][];
}): Promise<CreateDataSetResponse>
createAndAddPieces
(
const clientDataSetId: bigint
clientDataSetId
,
const payee: string
payee
,
const payer: string
payer
,
const warmStorageAddress: string
warmStorageAddress
,
const pieceDataArray: PieceLink[] | string[]
pieceDataArray
,
{
dataset?: MetadataEntry[]
dataset
:
const datasetMetadata: MetadataEntry[]
datasetMetadata
,
pieces?: MetadataEntry[][]
pieces
:
const piecesMetadata: MetadataEntry[][]
piecesMetadata
}
);
// Add pieces to existing data set
const
const addResult: AddPiecesResponse
addResult
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.addPieces(dataSetId: number, clientDataSetId: bigint, pieceDataArray: PieceCID[] | string[], metadata?: MetadataEntry[][]): Promise<AddPiecesResponse>
addPieces
(
const dataSetId: number
dataSetId
,
const clientDataSetId: bigint
clientDataSetId
,
const pieceDataArray: PieceLink[] | string[]
pieceDataArray
);
// Track piece addition status
if (
const addResult: AddPiecesResponse
addResult
.
AddPiecesResponse.txHash: string
txHash
) {
const
const addStatus: PieceAdditionStatusResponse
addStatus
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.getPieceAdditionStatus(dataSetId: number, txHash: string): Promise<PieceAdditionStatusResponse>
getPieceAdditionStatus
(
const dataSetId: number
dataSetId
,
const addResult: AddPiecesResponse
addResult
.
AddPiecesResponse.txHash: string
txHash
);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(`Status: ${
const addStatus: PieceAdditionStatusResponse
addStatus
.
PieceAdditionStatusResponse.txStatus: string
txStatus
}, IDs: ${
const addStatus: PieceAdditionStatusResponse
addStatus
.
PieceAdditionStatusResponse.confirmedPieceIds?: number[] | undefined
confirmedPieceIds
}`);
}
// Upload and manage pieces
const {
const pieceCid: PieceLink
pieceCid
} = await
const pdpServer: PDPServer
pdpServer
.
PDPServer.uploadPiece(data: Uint8Array | ArrayBuffer): Promise<UploadResponse>
uploadPiece
(
const data: ArrayBuffer | Uint8Array<ArrayBufferLike>
data
);
const
const piece: FindPieceResponse
piece
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.findPiece(pieceCid: string | PieceCID): Promise<FindPieceResponse>
findPiece
(
const pieceCid: PieceLink
pieceCid
);
const
const pieceData: Uint8Array<ArrayBufferLike>
pieceData
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.downloadPiece(pieceCid: string | PieceCID): Promise<Uint8Array>
downloadPiece
(
const pieceCid: PieceLink
pieceCid
);
// Query data set details
const
const dataSet: DataSetData
dataSet
= await
const pdpServer: PDPServer
pdpServer
.
PDPServer.getDataSet(dataSetId: number): Promise<DataSetData>
getDataSet
(
const dataSetId: number
dataSetId
);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(`Dataset ${
const dataSet: DataSetData
dataSet
.
DataSetData.id: number
id
}: ${
const dataSet: DataSetData
dataSet
.
DataSetData.pieces: DataSetPieceData[]
pieces
.
Array<DataSetPieceData>.length: number

Gets or sets the length of the array. This is a number one higher than the highest index in the array.

length
} pieces`);

Purpose: Calculate PieceCIDs, convert between formats, and get the size of a specific piece.

API Reference: PieceCID Utilities API Reference

PieceCID Utilities Example:

import {
calculate,
asPieceCID,
asLegacyPieceCID,
createPieceCIDStream,
getSizeFromPieceCID,
} from "@filoz/synapse-sdk/piece";
// Calculate PieceCID from data
const data = new Uint8Array([1, 2, 3, 4]);
const pieceCid = calculate(data);
console.log(pieceCid.toString()); // bafkzcib...
// Validate and convert PieceCID string
const converted = asPieceCID(
"bafkzcibcd4bdomn3tgwgrh3g532zopskstnbrd2n3sxfqbze7rxt7vqn7veigmy"
);
if (converted !== null) {
console.log("Valid PieceCID:", converted.toString());
}
// Extract size from PieceCID
const size = getSizeFromPieceCID(pieceCid);
console.log(`Piece size: ${size} bytes`);
// Stream-based PieceCID calculation (Web Streams API compatible)
const { stream, getPieceCID } = createPieceCIDStream();
// Pipe data through stream, then call getPieceCID() for result
// Convert to LegacyPieceCID for compatibility with external Filecoin services
const legacyPieceCid = asLegacyPieceCID(convertedPieceCid);
if (legacyPieceCid !== null) {
console.log("Valid LegacyPieceCID:", legacyPieceCid.toString());
// Valid LegacyPieceCID: baga6ea4seaqdomn3tgwgrh3g532zopskstnbrd2n3sxfqbze7rxt7vqn7veigmy
}

This sequence diagram shows the complete lifecycle of a file upload operation, from initialization through verification. Each step represents an actual blockchain transaction or API call.

sequenceDiagram
    participant Client
    participant SDK
    participant WarmStorage
    participant Curio
    participant PDPVerifier
    participant Payments

    Note over Client,Payments: Step 1: Preparation
    Client->>SDK: Initialize Synapse SDK
    SDK->>WarmStorage: Discover contract addresses

    Note over Client,Payments: Step 2: Payment Setup
    Client->>SDK: Check allowances
    SDK->>WarmStorage: getServicePrice()
    SDK->>Payments: accountInfo(client)
    alt Needs setup
        Client->>Payments: depositWithPermitAndApproveOperator()
    end

    Note over Client,Payments: Step 3: Storage Context
    Client->>SDK: synapse.storage.upload(data)
    SDK->>SDK: Auto-select provider or use default
    alt No data set exists
        SDK->>SDK: Sign CreateDataSet (EIP-712)
        SDK->>Curio: POST /pdp/data-sets (+ signature)
        Curio->>PDPVerifier: createDataSet(warmStorage, signature)
        PDPVerifier->>WarmStorage: dataSetCreated()
        WarmStorage->>Payments: createRail()
        Payments-->>WarmStorage: railId
    end

    Note over Client,Payments: Step 4: Upload & Register
    SDK->>SDK: Calculate PieceCID
    SDK->>Curio: POST /pdp/piece (upload data)
    Curio-->>SDK: uploadUUID
    SDK->>SDK: Sign AddPieces (EIP-712)
    SDK->>Curio: POST /pdp/data-sets/{id}/pieces
    Curio->>PDPVerifier: addPieces(dataSetId, pieces, signature)
    PDPVerifier->>WarmStorage: piecesAdded()
    WarmStorage->>WarmStorage: Store metadata
    WarmStorage-->>PDPVerifier: Success

    Note over Client,Payments: Step 5: Verification Begins
    PDPVerifier->>PDPVerifier: Schedule first challenge
    PDPVerifier-->>Client: Upload complete!

Choose your learning path based on your immediate needs:

Jump straight to code with the Getting Started Guide →