Skip to content

Synapse Core

Synapse Core (@filoz/synapse-core) is the low-level foundation that both the Synapse SDK and Synapse React build on. Use Synapse Core when you need:

  • Direct control over individual contract calls without the Synapse class abstraction
  • Custom integrations that combine only the modules you need

Install dependencies:

npm install @filoz/synapse-core viem

Synapse Core requires viem 2.x as a peer dependency.

Client setup:

All Synapse Core functions accept a viem Client as their first argument. Create one using viem’s standard client factories:

import { function createPublicClient<transport extends Transport, chain extends Chain | undefined = undefined, accountOrAddress extends Account | Address | undefined = undefined, rpcSchema extends RpcSchema | undefined = undefined, const tokens extends Tokens | undefined = undefined>(parameters: PublicClientConfig<transport, chain, accountOrAddress, rpcSchema, tokens>): PublicClient<transport, chain, ParseAccount<accountOrAddress>, rpcSchema, tokens>
Creates a Public Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/clients/chains). - Docs: https://viem.sh/docs/clients/public A Public Client is an interface to "public" [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) methods such as retrieving block numbers, transactions, reading from smart contracts, etc through [Public Actions](/docs/actions/public/introduction).
@paramconfig - {@link PublicClientConfig}@returnsA Public Client. {@link PublicClient}@exampleimport { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' const client = createPublicClient({ chain: mainnet, transport: http(), })
createPublicClient
, function createWalletClient<transport extends Transport, chain extends Chain | undefined = undefined, accountOrAddress extends Account | Address | undefined = undefined, rpcSchema extends RpcSchema | undefined = undefined, const tokens extends Tokens | undefined = undefined>(parameters: WalletClientConfig<transport, chain, accountOrAddress, rpcSchema, tokens>): WalletClient<transport, chain, ParseAccount<accountOrAddress>, rpcSchema, tokens>
Creates a Wallet Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/clients/chains). - Docs: https://viem.sh/docs/clients/wallet A Wallet Client is an interface to interact with [Ethereum Account(s)](https://ethereum.org/en/glossary/#account) and provides the ability to retrieve accounts, execute transactions, sign messages, etc. through [Wallet Actions](https://viem.sh/docs/actions/wallet/introduction). The Wallet Client supports signing over: - [JSON-RPC Accounts](https://viem.sh/docs/clients/wallet#json-rpc-accounts) (e.g. Browser Extension Wallets, WalletConnect, etc). - [Local Accounts](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc) (e.g. private key/mnemonic wallets).
@paramconfig - {@link WalletClientConfig}@returnsA Wallet Client. {@link WalletClient}@example// JSON-RPC Account import { createWalletClient, custom } from 'viem' import { mainnet } from 'viem/chains' const client = createWalletClient({ chain: mainnet, transport: custom(window.ethereum), })@example// Local Account import { createWalletClient, custom } from 'viem' import { privateKeyToAccount } from 'viem/accounts' import { mainnet } from 'viem/chains' const client = createWalletClient({ account: privateKeyToAccount('0x…') chain: mainnet, transport: http(), })
createWalletClient
} from "viem"
import { function privateKeyToAccount(privateKey: Hex, options?: PrivateKeyToAccountOptions): PrivateKeyAccount
@descriptionCreates an Account from a private key.@returnsA Private Key Account.
privateKeyToAccount
} from "viem/accounts"
import { const calibration: FilecoinChaincalibration } from "@filoz/synapse-core/chains" import { function getTransport(chain: Chain): TransportgetTransport } from "@filoz/synapse-core/client" // Read-only client for queries const
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
=
createPublicClient<Transport, FilecoinChain, undefined, undefined, undefined>(parameters: {
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined | undefined;
    cacheTime?: number | undefined | undefined;
    ccipRead?: {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | false | undefined | undefined;
    ... 7 more ...;
    transport: Transport;
}): {
    ...;
}
Creates a Public Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/clients/chains). - Docs: https://viem.sh/docs/clients/public A Public Client is an interface to "public" [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) methods such as retrieving block numbers, transactions, reading from smart contracts, etc through [Public Actions](/docs/actions/public/introduction).
@paramconfig - {@link PublicClientConfig}@returnsA Public Client. {@link PublicClient}@exampleimport { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' const client = createPublicClient({ chain: mainnet, transport: http(), })
createPublicClient
({
chain?: Chain | FilecoinChain | undefined
Chain for the client.
chain
: const calibration: FilecoinChaincalibration, // or mainnet
transport: Transport
The RPC transport
transport
: function getTransport(chain: Chain): TransportgetTransport(const calibration: FilecoinChaincalibration),
}) // Wallet client for transactions const
const account: {
    address: Address;
    nonceManager?: NonceManager | undefined;
    sign: (parameters: {
        hash: Hash;
    }) => Promise<Hex>;
    signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
    signMessage: ({ message }: {
        message: SignableMessage;
    }) => Promise<Hex>;
    signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
        serializer?: serializer | undefined;
    } | undefined) => Promise<Hex>;
    signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
    publicKey: Hex;
    source: "privateKey";
    type: "local";
}
account
= function privateKeyToAccount(privateKey: Hex, options?: PrivateKeyToAccountOptions): PrivateKeyAccount
@descriptionCreates an Account from a private key.@returnsA Private Key Account.
privateKeyToAccount
("0x...")
const
const walletClient: {
    account: {
        address: Address;
        nonceManager?: NonceManager | undefined;
        sign: (parameters: {
            hash: Hash;
        }) => Promise<Hex>;
        signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
        signMessage: ({ message }: {
            message: SignableMessage;
        }) => Promise<Hex>;
        signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
            serializer?: serializer | undefined;
        } | undefined) => Promise<Hex>;
        signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
        publicKey: Hex;
        source: "privateKey";
        type: "local";
    };
    ... 43 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
walletClient
=
createWalletClient<Transport, FilecoinChain, {
    address: Address;
    nonceManager?: NonceManager | undefined;
    sign: (parameters: {
        hash: Hash;
    }) => Promise<Hex>;
    signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
    signMessage: ({ message }: {
        message: SignableMessage;
    }) => Promise<Hex>;
    ... 4 more ...;
    type: "local";
}, undefined, undefined>(parameters: {
    ...;
}): {
    ...;
}
Creates a Wallet Client with a given [Transport](https://viem.sh/docs/clients/intro) configured for a [Chain](https://viem.sh/docs/clients/chains). - Docs: https://viem.sh/docs/clients/wallet A Wallet Client is an interface to interact with [Ethereum Account(s)](https://ethereum.org/en/glossary/#account) and provides the ability to retrieve accounts, execute transactions, sign messages, etc. through [Wallet Actions](https://viem.sh/docs/actions/wallet/introduction). The Wallet Client supports signing over: - [JSON-RPC Accounts](https://viem.sh/docs/clients/wallet#json-rpc-accounts) (e.g. Browser Extension Wallets, WalletConnect, etc). - [Local Accounts](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc) (e.g. private key/mnemonic wallets).
@paramconfig - {@link WalletClientConfig}@returnsA Wallet Client. {@link WalletClient}@example// JSON-RPC Account import { createWalletClient, custom } from 'viem' import { mainnet } from 'viem/chains' const client = createWalletClient({ chain: mainnet, transport: custom(window.ethereum), })@example// Local Account import { createWalletClient, custom } from 'viem' import { privateKeyToAccount } from 'viem/accounts' import { mainnet } from 'viem/chains' const client = createWalletClient({ account: privateKeyToAccount('0x…') chain: mainnet, transport: http(), })
createWalletClient
({
account?: `0x${string}` | {
    address: Address;
    nonceManager?: NonceManager | undefined;
    sign: (parameters: {
        hash: Hash;
    }) => Promise<Hex>;
    signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
    signMessage: ({ message }: {
        message: SignableMessage;
    }) => Promise<Hex>;
    signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
        serializer?: serializer | undefined;
    } | undefined) => Promise<Hex>;
    signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
    publicKey: Hex;
    source: "privateKey";
    type: "local";
} | Account | undefined
The Account to use for the Client. This will be used for Actions that require an account as an argument.
account
,
chain?: Chain | FilecoinChain | undefined
Chain for the client.
chain
: const calibration: FilecoinChaincalibration, // or mainnet
transport: Transport
The RPC transport
transport
: function getTransport(chain: Chain): TransportgetTransport(const calibration: FilecoinChaincalibration),
})

The @filoz/synapse-core/chains subpath exports chain definitions with all contract addresses pre-configured for Filecoin Mainnet (mainnet) and Filecoin testnet (calibration) networks. Import the FOC chain type as FilecoinChain when you need it in TypeScript.

The @filoz/synapse-core/client subpath exports getTransport (ranked Filecoin RPC fallbacks), asClient, and toReadClient. Prefer getTransport(chain) over a bare http() endpoint when talking to mainnet or Calibration.

Collection actions in Synapse Core return one bounded page at a time. They share the same options and result shapes:

type PaginationOptions = {
  cursor?: bigint
  limit?: bigint
}

type Page<T> = {
  items: T[]
  nextCursor?: bigint
}

Some actions also return a total alongside the page. A cursor is an opaque continuation value: pass the returned nextCursor back as cursor without calculating or incrementing it yourself. An omitted limit uses the action’s bounded default, while an explicit limit must be greater than 0n.

To read one page, call the action directly:

import { function getClientDataSets(client: Client<Transport, Chain>, options: getClientDataSets.OptionsType): Promise<getClientDataSets.OutputType>getClientDataSets } from "@filoz/synapse-core/warm-storage"

const const page: getClientDataSets.OutputTypepage = await function getClientDataSets(client: Client<Transport, Chain>, options: getClientDataSets.OptionsType): Promise<getClientDataSets.OutputType>getClientDataSets(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, {
address: `0x${string}`address, limit?: bigint | undefinedlimit: 25n, }) var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const page: getClientDataSets.OutputTypepage.items: DataSetInfo[]items)
if (const page: getClientDataSets.OutputTypepage.nextCursor?: bigint | undefinednextCursor !== var undefinedundefined) { const const nextPage: getClientDataSets.OutputTypenextPage = await function getClientDataSets(client: Client<Transport, Chain>, options: getClientDataSets.OptionsType): Promise<getClientDataSets.OutputType>getClientDataSets(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, {
address: `0x${string}`address, cursor?: bigint | undefinedcursor: const page: getClientDataSets.OutputTypepage.nextCursor?: bigintnextCursor, limit?: bigint | undefinedlimit: 25n, }) var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const nextPage: getClientDataSets.OutputTypenextPage.items: DataSetInfo[]items)
}

Use paginate() when you want to traverse every page. It follows nextCursor, yields individual items, and rejects a repeated or non-advancing cursor. A normal break exits the for await loop, closes the generator, and prevents any further page requests.

import { function paginate<T>(getPage: paginate.GetPage<T>, options?: paginate.OptionsType): paginate.OutputType<T>paginate } from "@filoz/synapse-core"
import { function getClientDataSetIds(client: Client<Transport, Chain>, options: getClientDataSetIds.OptionsType): Promise<getClientDataSetIds.OutputType>getClientDataSetIds } from "@filoz/synapse-core/warm-storage"

for await (const const dataSetId: bigintdataSetId of paginate<bigint>(getPage: paginate.GetPage<bigint>, options?: paginate.OptionsType): paginate.OutputType<bigint>paginate(({ cursor: bigintcursor }) =>
  function getClientDataSetIds(client: Client<Transport, Chain>, options: getClientDataSetIds.OptionsType): Promise<getClientDataSetIds.OutputType>getClientDataSetIds(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, { address: `0x${string}`address, cursor?: bigint | undefinedcursor })
)) { var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const dataSetId: bigintdataSetId)
} const const allDataSetIds: bigint[]allDataSetIds = await var Array: ArrayConstructorArray.ArrayConstructor.fromAsync<bigint>(iterableOrArrayLike: AsyncIterable<bigint> | Iterable<bigint | PromiseLike<bigint>> | ArrayLike<bigint | PromiseLike<bigint>>): Promise<bigint[]> (+1 overload)
Creates an array from an async iterator or iterable object.
@paramiterableOrArrayLike An async iterator or array-like object to convert to an array.
fromAsync
(
paginate<bigint>(getPage: paginate.GetPage<bigint>, options?: paginate.OptionsType): paginate.OutputType<bigint>paginate(({ cursor: bigintcursor }) => function getClientDataSetIds(client: Client<Transport, Chain>, options: getClientDataSetIds.OptionsType): Promise<getClientDataSetIds.OutputType>getClientDataSetIds(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, { address: `0x${string}`address, cursor?: bigint | undefinedcursor })
) )

The exported *Call helpers remain literal ABI adapters for multicalls. They use contract-facing fields such as offset or startPieceId and require an explicit limit; cursor translation and default limits are handled by the corresponding action.

Query account balances, deposit funds, manage operator approvals, and settle payment rails on the Filecoin Pay contract.

import * as import paypay from "@filoz/synapse-core/pay"
import { function parseUnits(value: string, decimals: number): bigint
Multiplies a string representation of a number by a given exponent of base 10 (10exponent). - Docs: https://viem.sh/docs/utilities/parseUnits
@exampleimport { parseUnits } from 'viem' parseUnits('420', 9) // 420000000000n
parseUnits
} from "viem"
// Query Filecoin Pay account info for the USDFC token const const info: pay.accounts.OutputTypeinfo = await import paypay.function accounts(client: Client<Transport, Chain>, options: pay.accounts.OptionsType): Promise<pay.accounts.OutputType>accounts(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, {
// If not provided, the USDFC token address will be used. token?: `0x${string}` | undefinedtoken: const calibration: FilecoinChaincalibration.
FilecoinChain.contracts: {
    multicall3: ChainContract;
    usdfc: {
        address: Address;
        abi: typeof erc20WithPermit;
    };
    filecoinPay: {
        address: Address;
        abi: typeof filecoinPayV1Abi;
    };
    fwss: {
        address: Address;
        abi: typeof fwss;
    };
    fwssView: {
        address: Address;
        abi: typeof fwssView;
    };
    serviceProviderRegistry: {
        address: Address;
        abi: typeof serviceProviderRegistry;
    };
    sessionKeyRegistry: {
        address: Address;
        abi: typeof sessionKeyRegistryAbi;
    };
    pdp: {
        address: Address;
        abi: typeof pdpVerifierAbi;
    };
    endorsements: {
        address: Address;
        abi: typeof providerIdSetAbi;
    };
}
Collection of contracts
contracts
.
usdfc: {
    address: Address;
    abi: typeof erc20WithPermit;
}
usdfc
.address: `0x${string}`address,
address: `0x${string}`address:
const account: {
    address: Address;
    nonceManager?: NonceManager | undefined;
    sign: (parameters: {
        hash: Hash;
    }) => Promise<Hex>;
    signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
    signMessage: ({ message }: {
        message: SignableMessage;
    }) => Promise<Hex>;
    signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
        serializer?: serializer | undefined;
    } | undefined) => Promise<Hex>;
    signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
    publicKey: Hex;
    source: "privateKey";
    type: "local";
}
account
.address: `0x${string}`address,
}) var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const info: pay.accounts.OutputTypeinfo.availableFunds: bigintavailableFunds) // bigint — funds available in Filecoin Pay
// Deposit USDFC in Filecoin Pay const const depositTxHash: `0x${string}`depositTxHash = await import paypay.function depositAndApprove(client: Client<Transport, Chain, Account>, options: pay.DepositAndApproveOptions): Promise<`0x${string}`>depositAndApprove(
const walletClient: {
    account: {
        address: Address;
        nonceManager?: NonceManager | undefined;
        sign: (parameters: {
            hash: Hash;
        }) => Promise<Hex>;
        signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
        signMessage: ({ message }: {
            message: SignableMessage;
        }) => Promise<Hex>;
        signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
            serializer?: serializer | undefined;
        } | undefined) => Promise<Hex>;
        signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
        publicKey: Hex;
        source: "privateKey";
        type: "local";
    };
    ... 43 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
walletClient
, {
// If not provided, the USDFC token address will be used. token?: `0x${string}` | undefinedtoken: const calibration: FilecoinChaincalibration.
FilecoinChain.contracts: {
    multicall3: ChainContract;
    usdfc: {
        address: Address;
        abi: typeof erc20WithPermit;
    };
    filecoinPay: {
        address: Address;
        abi: typeof filecoinPayV1Abi;
    };
    fwss: {
        address: Address;
        abi: typeof fwss;
    };
    fwssView: {
        address: Address;
        abi: typeof fwssView;
    };
    serviceProviderRegistry: {
        address: Address;
        abi: typeof serviceProviderRegistry;
    };
    sessionKeyRegistry: {
        address: Address;
        abi: typeof sessionKeyRegistryAbi;
    };
    pdp: {
        address: Address;
        abi: typeof pdpVerifierAbi;
    };
    endorsements: {
        address: Address;
        abi: typeof providerIdSetAbi;
    };
}
Collection of contracts
contracts
.
usdfc: {
    address: Address;
    abi: typeof erc20WithPermit;
}
usdfc
.address: `0x${string}`address,
amount: bigintamount: function parseUnits(value: string, decimals: number): bigint
Multiplies a string representation of a number by a given exponent of base 10 (10exponent). - Docs: https://viem.sh/docs/utilities/parseUnits
@exampleimport { parseUnits } from 'viem' parseUnits('420', 9) // 420000000000n
parseUnits
("1", 18), // 1 USDFC
}) await
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
.waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<FilecoinChain>) => Promise<TransactionReceipt>
Waits for the [Transaction](https://viem.sh/docs/glossary/terms#transaction) to be included on a [Block](https://viem.sh/docs/glossary/terms#block) (one confirmation), and then returns the [Transaction Receipt](https://viem.sh/docs/glossary/terms#transaction-receipt). If the Transaction reverts, then the action will throw an error. - Docs: https://viem.sh/docs/actions/public/waitForTransactionReceipt - Example: https://stackblitz.com/github/wevm/viem/tree/main/examples/transactions_sending-transactions - JSON-RPC Methods: - Polls [`eth_getTransactionReceipt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionReceipt) on each block until it has been processed. - If a Transaction has been replaced: - Calls [`eth_getBlockByNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber) and extracts the transactions - Checks if one of the Transactions is a replacement - If so, calls [`eth_getTransactionReceipt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionReceipt).
@remarksThe `waitForTransactionReceipt` action additionally supports Replacement detection (e.g. sped up Transactions). Transactions can be replaced when a user modifies their transaction in their wallet (to speed up or cancel). Transactions are replaced when they are sent from the same nonce. There are 3 types of Transaction Replacement reasons: - `repriced`: The gas price has been modified (e.g. different `maxFeePerGas`) - `cancelled`: The Transaction has been cancelled (e.g. `value === 0n`) - `replaced`: The Transaction has been replaced (e.g. different `value` or `data`)@paramargs - {@link WaitForTransactionReceiptParameters}@returnsThe transaction receipt. {@link WaitForTransactionReceiptReturnType}@exampleimport { 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
: const depositTxHash: `0x${string}`depositTxHash
}) // Withdraw USDFC from Filecoin Pay const const withdrawTxHash: `0x${string}`withdrawTxHash = await import paypay.function withdraw(client: Client<Transport, Chain, Account>, options: pay.withdraw.OptionsType): Promise<Hash>withdraw(
const walletClient: {
    account: {
        address: Address;
        nonceManager?: NonceManager | undefined;
        sign: (parameters: {
            hash: Hash;
        }) => Promise<Hex>;
        signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
        signMessage: ({ message }: {
            message: SignableMessage;
        }) => Promise<Hex>;
        signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
            serializer?: serializer | undefined;
        } | undefined) => Promise<Hex>;
        signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
        publicKey: Hex;
        source: "privateKey";
        type: "local";
    };
    ... 43 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
walletClient
, {
// If not provided, the USDFC token address will be used. token?: `0x${string}` | undefinedtoken: const calibration: FilecoinChaincalibration.
FilecoinChain.contracts: {
    multicall3: ChainContract;
    usdfc: {
        address: Address;
        abi: typeof erc20WithPermit;
    };
    filecoinPay: {
        address: Address;
        abi: typeof filecoinPayV1Abi;
    };
    fwss: {
        address: Address;
        abi: typeof fwss;
    };
    fwssView: {
        address: Address;
        abi: typeof fwssView;
    };
    serviceProviderRegistry: {
        address: Address;
        abi: typeof serviceProviderRegistry;
    };
    sessionKeyRegistry: {
        address: Address;
        abi: typeof sessionKeyRegistryAbi;
    };
    pdp: {
        address: Address;
        abi: typeof pdpVerifierAbi;
    };
    endorsements: {
        address: Address;
        abi: typeof providerIdSetAbi;
    };
}
Collection of contracts
contracts
.
usdfc: {
    address: Address;
    abi: typeof erc20WithPermit;
}
usdfc
.address: `0x${string}`address,
amount: bigintamount: function parseUnits(value: string, decimals: number): bigint
Multiplies a string representation of a number by a given exponent of base 10 (10exponent). - Docs: https://viem.sh/docs/utilities/parseUnits
@exampleimport { parseUnits } from 'viem' parseUnits('420', 9) // 420000000000n
parseUnits
("1", 18), // 1 USDFC
}) await
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
.waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<FilecoinChain>) => Promise<TransactionReceipt>
Waits for the [Transaction](https://viem.sh/docs/glossary/terms#transaction) to be included on a [Block](https://viem.sh/docs/glossary/terms#block) (one confirmation), and then returns the [Transaction Receipt](https://viem.sh/docs/glossary/terms#transaction-receipt). If the Transaction reverts, then the action will throw an error. - Docs: https://viem.sh/docs/actions/public/waitForTransactionReceipt - Example: https://stackblitz.com/github/wevm/viem/tree/main/examples/transactions_sending-transactions - JSON-RPC Methods: - Polls [`eth_getTransactionReceipt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionReceipt) on each block until it has been processed. - If a Transaction has been replaced: - Calls [`eth_getBlockByNumber`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber) and extracts the transactions - Checks if one of the Transactions is a replacement - If so, calls [`eth_getTransactionReceipt`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getTransactionReceipt).
@remarksThe `waitForTransactionReceipt` action additionally supports Replacement detection (e.g. sped up Transactions). Transactions can be replaced when a user modifies their transaction in their wallet (to speed up or cancel). Transactions are replaced when they are sent from the same nonce. There are 3 types of Transaction Replacement reasons: - `repriced`: The gas price has been modified (e.g. different `maxFeePerGas`) - `cancelled`: The Transaction has been cancelled (e.g. `value === 0n`) - `replaced`: The Transaction has been replaced (e.g. different `value` or `data`)@paramargs - {@link WaitForTransactionReceiptParameters}@returnsThe transaction receipt. {@link WaitForTransactionReceiptReturnType}@exampleimport { 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
: const withdrawTxHash: `0x${string}`withdrawTxHash
})

List approved storage providers.

import * as import warmStoragewarmStorage from "@filoz/synapse-core/warm-storage"

// Read one bounded page of approved provider IDs
const const page: warmStorage.getApprovedProviderIds.OutputTypepage = await import warmStoragewarmStorage.function getApprovedProviderIds(client: Client<Transport, Chain>, options?: warmStorage.getApprovedProviderIds.OptionsType): Promise<warmStorage.getApprovedProviderIds.OutputType>getApprovedProviderIds(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
)
var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const page: warmStorage.getApprovedProviderIds.OutputTypepage.items: bigint[]items, const page: warmStorage.getApprovedProviderIds.OutputTypepage.nextCursor?: bigint | undefinednextCursor)

Create a data set and upload a file.

import * as import piecepiece from "@filoz/synapse-core/piece"
import * as import spsp from "@filoz/synapse-core/sp"
import { function getPDPProvider(client: Client<Transport, Chain>, options: getPDPProvider.OptionsType): Promise<getPDPProvider.OutputType>getPDPProvider } from "@filoz/synapse-core/sp-registry"

// 1. Select a provider
const const provider: getPDPProvider.OutputTypeprovider = await function getPDPProvider(client: Client<Transport, Chain>, options: getPDPProvider.OptionsType): Promise<getPDPProvider.OutputType>getPDPProvider(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, { providerId: bigintproviderId: 1n })
if (!const provider: getPDPProvider.OutputTypeprovider) { throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error
('Provider not found.');
} // 2. Calculate PieceCID and upload data const const pieceCid: piece.PieceCIDpieceCid = await import piecepiece.
function calculate(input: piece.CalculateInput): Promise<piece.PieceCID>
export calculate
calculate
(const data: Uint8Array<ArrayBuffer>data)
var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const pieceCid: piece.PieceCIDpieceCid.PieceCID.size: numbersize) // size of the piece in bytes
// Upload the piece to the provider await import spsp.function uploadPiece(options: sp.uploadPiece.OptionsType): Promise<void>uploadPiece({ data: Uint8Array<ArrayBufferLike>data, pieceCid: piece.PieceCIDpieceCid, serviceURL: stringserviceURL: const provider: PDPProviderprovider.PDPProvider.pdp: PDPOfferingpdp.PDPOffering.serviceURL: stringserviceURL, }) // Poll the provider to confirm the piece is stored await import spsp.function findPiece(options: sp.findPiece.OptionsType): Promise<sp.findPiece.OutputType>findPiece({ pieceCid: piece.PieceCIDpieceCid, serviceURL: stringserviceURL: const provider: PDPProviderprovider.PDPProvider.pdp: PDPOfferingpdp.PDPOffering.serviceURL: stringserviceURL, poll?: boolean | undefinedpoll: true, }) var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(`Piece ${const pieceCid: piece.PieceCIDpieceCid.CID<unknown, 85, 4113, 1>.toString(base?: MultibaseEncoder<string>): string
Returns a string representation of an object.
toString
()} uploaded to provider ${const provider: PDPProviderprovider.PDPProvider.pdp: PDPOfferingpdp.PDPOffering.serviceURL: stringserviceURL}`)
// 3. Create a data set and add the piece on-chain const const result: sp.createDataSetAndAddPieces.ReturnTyperesult = await import spsp.function createDataSetAndAddPieces(client: Client<Transport, Chain, Account>, options: sp.CreateDataSetAndAddPiecesOptions): Promise<sp.createDataSetAndAddPieces.ReturnType>createDataSetAndAddPieces(
const walletClient: {
    account: {
        address: Address;
        nonceManager?: NonceManager | undefined;
        sign: (parameters: {
            hash: Hash;
        }) => Promise<Hex>;
        signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
        signMessage: ({ message }: {
            message: SignableMessage;
        }) => Promise<Hex>;
        signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
            serializer?: serializer | undefined;
        } | undefined) => Promise<Hex>;
        signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
        publicKey: Hex;
        source: "privateKey";
        type: "local";
    };
    ... 43 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
walletClient
, {
serviceURL: stringserviceURL: const provider: PDPProviderprovider.PDPProvider.pdp: PDPOfferingpdp.PDPOffering.serviceURL: stringserviceURL, payee: `0x${string}`payee: const provider: PDPProviderprovider.payee: `0x${string}`payee, cdn?: boolean | undefinedcdn: false,
pieces: {
    pieceCid: piece.PieceCID;
    metadata?: MetadataObject;
}[]
pieces
: [{ pieceCid: piece.PieceCIDpieceCid }],
}) // 4. Wait for the transaction on chain (follows the provider's fee replacements) const const confirmed: sp.waitForCreateDataSetAddPieces.OutputTypeconfirmed = await import spsp.function waitForCreateDataSetAddPieces(options: sp.waitForCreateDataSetAddPieces.OptionsType): Promise<sp.waitForCreateDataSetAddPieces.OutputType>waitForCreateDataSetAddPieces({ client: Client<Transport, Chain, Account | undefined>client:
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, ...const result: sp.createDataSetAndAddPieces.ReturnTyperesult })
const { const dataSetId: bigintdataSetId, const pieceIds: bigint[]pieceIds, const txHash: `0x${string}`txHash } = const confirmed: sp.waitForCreateDataSetAddPieces.OutputTypeconfirmed var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(`Data set ${const dataSetId: bigintdataSetId} created and piece ${const pieceCid: piece.PieceCIDpieceCid.CID<unknown, 85, 4113, 1>.toString(base?: MultibaseEncoder<string>): string
Returns a string representation of an object.
toString
()} added to data set`)
For large files, use uploadPieceStreaming instead of uploadPiece:
// Stream upload — PieceCID is calculated during transfer
const const stream: ReadableStream<Uint8Array<ArrayBufferLike>>stream = new var ReadableStream: new <Uint8Array<ArrayBufferLike>>(underlyingSource: UnderlyingDefaultSource<Uint8Array<ArrayBufferLike>>, strategy?: QueuingStrategy<Uint8Array<ArrayBufferLike>> | undefined) => ReadableStream<Uint8Array<ArrayBufferLike>> (+2 overloads)ReadableStream<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
>({ /* ... */ })
const const uploaded: sp.uploadPieceStreaming.OutputTypeuploaded = await import spsp.function uploadPieceStreaming(options: sp.uploadPieceStreaming.OptionsType): Promise<sp.uploadPieceStreaming.OutputType>uploadPieceStreaming({ data: anydata: const stream: ReadableStream<Uint8Array<ArrayBufferLike>>stream, serviceURL: stringserviceURL, onProgress?: ((bytesUploaded: number) => void) | undefinedonProgress(bytes: numberbytes) { var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(`${bytes: numberbytes} bytes uploaded`)
}, }) var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const uploaded: sp.uploadPieceStreaming.OutputTypeuploaded.pieceCid: PieceCIDpieceCid) // PieceCID — calculated from streamed data
var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const uploaded: sp.uploadPieceStreaming.OutputTypeuploaded.size: numbersize) // number — total bytes uploaded

Download a piece from a storage provider.

import { function downloadAndValidate(options: downloadAndValidate.OptionsType): Promise<Uint8Array>downloadAndValidate } from "@filoz/synapse-core/piece"

// Download a piece
const const data: Uint8Array<ArrayBufferLike>data = await function downloadAndValidate(options: downloadAndValidate.OptionsType): Promise<Uint8Array>downloadAndValidate({
  url: stringurl: `${const provider: PDPProviderprovider.PDPProvider.pdp: PDPOfferingpdp.PDPOffering.serviceURL: stringserviceURL}/piece`,
  expectedPieceCid: string | PieceCIDexpectedPieceCid: "bafkzcib...",
})
var console: Consoleconsole.Console.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
log
(const data: Uint8Array<ArrayBufferLike>data) // Uint8Array — downloaded piece data

For custom upload pipelines, you can use the provider selection functions directly to find matching data sets and providers:

import { function fetchProviderSelectionInput(client: Client<Transport, Chain>, options: fetchProviderSelectionInput.OptionsType): Promise<ProviderSelectionInput>fetchProviderSelectionInput, function selectProviders(options: ProviderSelectionOptions): ResolvedLocation[]selectProviders } from "@filoz/synapse-core/warm-storage"

// Fetch all chain data needed for selection
const const input: ProviderSelectionInputinput = await function fetchProviderSelectionInput(client: Client<Transport, Chain>, options: fetchProviderSelectionInput.OptionsType): Promise<ProviderSelectionInput>fetchProviderSelectionInput(
const publicClient: {
    account: undefined;
    batch?: {
        multicall?: boolean | Prettify<MulticallBatchOptions> | undefined;
    } | undefined;
    cacheTime: number;
    ccipRead?: false | {
        request?: (parameters: CcipRequestParameters) => Promise<CcipRequestReturnType>;
    } | undefined;
    chain: FilecoinChain;
    dataSuffix?: DataSuffix | undefined;
    experimental_blockTag?: BlockTag | undefined;
    ... 70 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
publicClient
, {
address: `0x${string}`address:
const account: {
    address: Address;
    nonceManager?: NonceManager | undefined;
    sign: (parameters: {
        hash: Hash;
    }) => Promise<Hex>;
    signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
    signMessage: ({ message }: {
        message: SignableMessage;
    }) => Promise<Hex>;
    signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
        serializer?: serializer | undefined;
    } | undefined) => Promise<Hex>;
    signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
    publicKey: Hex;
    source: "privateKey";
    type: "local";
}
account
.address: `0x${string}`address,
}) // Primary: pass endorsedIds to restrict pool to endorsed providers only const [const primary: ResolvedLocationprimary] = function selectProviders(options: ProviderSelectionOptions): ResolvedLocation[]selectProviders({ ...const input: ProviderSelectionInputinput, ProviderSelectionOptions.count?: number | undefinedcount: 1, ProviderSelectionOptions.metadata?: MetadataObject | undefinedmetadata: { source: stringsource: "my-app" }, }) // Secondary: pass empty set to allow any approved provider const [const secondary: ResolvedLocationsecondary] = function selectProviders(options: ProviderSelectionOptions): ResolvedLocation[]selectProviders({ ...const input: ProviderSelectionInputinput, ProviderSelectionInput.endorsedIds: bigint[]endorsedIds: [], ProviderSelectionOptions.count?: number | undefinedcount: 1, ProviderSelectionOptions.excludeProviderIds?: bigint[] | undefinedexcludeProviderIds: [const primary: ResolvedLocationprimary.ResolvedLocation.provider: PDPProviderprovider.PDPProvider.id: bigintid], ProviderSelectionOptions.metadata?: MetadataObject | undefinedmetadata: { source: stringsource: "my-app" }, })

fetchProviderSelectionInput() makes a single multicall to gather providers, endorsements, and existing data sets. selectProviders() is a pure function (no network calls) that applies a 2-tier preference within the eligible pool:

  1. Existing data set with matching metadata
  2. New data set (no matching data set found)

The endorsedIds parameter controls which providers are eligible. When non-empty, only endorsed providers can be selected (no fallback to non-endorsed). When empty, all approved providers are eligible. See Storage Provider Tiers for what approval and endorsement mean and how providers qualify.

Transfer pieces between providers without using client bandwidth:

import * as import SPSP from "@filoz/synapse-core/sp"

const const response: SP.pullPieces.ReturnTyperesponse = await import SPSP.function waitForPullPieces(client: Client<Transport, Chain, Account>, options: SP.waitForPullPieces.OptionsType): Promise<SP.waitForPullPieces.ReturnType>waitForPullPieces(
const walletClient: {
    account: {
        address: Address;
        nonceManager?: NonceManager | undefined;
        sign: (parameters: {
            hash: Hash;
        }) => Promise<Hex>;
        signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
        signMessage: ({ message }: {
            message: SignableMessage;
        }) => Promise<Hex>;
        signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
            serializer?: serializer | undefined;
        } | undefined) => Promise<Hex>;
        signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
        publicKey: Hex;
        source: "privateKey";
        type: "local";
    };
    ... 43 more ...;
    extend: <const client extends {
        ...;
    } & ExactPartial<...>>(fn: (client: Client<...>) => client) => Client<...>;
}
walletClient
, {
serviceURL: stringserviceURL: const secondaryProvider: PDPProvidersecondaryProvider.PDPProvider.pdp: PDPOfferingpdp.PDPOffering.serviceURL: stringserviceURL, pieces: SP.PullPieceInput[]pieces: [{ pieceCid: PieceCIDpieceCid, sourceUrl: stringsourceUrl: `${const primaryProvider: PDPProviderprimaryProvider.PDPProvider.pdp: PDPOfferingpdp.PDPOffering.serviceURL: stringserviceURL}/pdp/piece/${const pieceCid: anypieceCid}`, }], payee: `0x${string}`payee: const secondaryProvider: PDPProvidersecondaryProvider.payee: `0x${string}`payee, payer?: `0x${string}` | undefinedpayer:
const account: {
    address: Address;
    nonceManager?: NonceManager | undefined;
    sign: (parameters: {
        hash: Hash;
    }) => Promise<Hex>;
    signAuthorization: (parameters: AuthorizationRequest) => Promise<SignAuthorizationReturnType>;
    signMessage: ({ message }: {
        message: SignableMessage;
    }) => Promise<Hex>;
    signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
        serializer?: serializer | undefined;
    } | undefined) => Promise<Hex>;
    signTypedData: <const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: TypedDataDefinition<typedData, primaryType>) => Promise<Hex>;
    publicKey: Hex;
    source: "privateKey";
    type: "local";
}
account
.address: `0x${string}`address,
cdn?: boolean | undefinedcdn: false, metadata?: MetadataObject | undefinedmetadata: {}, })

This path requires manual EIP-712 signing. The signAddPieces and signCreateDataSetAndAddPieces functions from @filoz/synapse-core/typed-data handle the signature creation.

Check out the Synapse Core Reference for all available modules and functions.