Skip to content

Rails & Settlement

Payment rails are the core mechanism for streaming payments between parties in the Synapse ecosystem. They enable continuous, per-epoch payments for services like storage and are created automatically when you upload your first file to a storage provider.

Rails ensure reliable payments through a simple lockup mechanism:

When you create a data set (storage), the system calculates how much balance you need to maintain:

  • Formula: lockup = paymentRate × lockupPeriod (e.g., 30 days worth of payments)
  • Example: Storing 1 GiB costs ~0.0000565 USDFC/epoch, requiring ~1.63 USDFC minimum balance
  • Purpose: This protects the service provider by ensuring you always have enough for the next payment period
  • You deposit funds into the payments contract (e.g., 100 USDFC)
  • The lockup requirement reserves part of this balance (e.g., 1.63 USDFC for 1 GiB storage)
  • You can withdraw anything above the lockup requirement
  • When you settle, your total balance decreases by the payment amount (lockup requirement stays the same)
  • Normal Operation: You keep settling regularly, lockup stays reserved but unused
  • If you stop settling: Service continues but unpaid amounts accumulate
  • If balance gets too low: Rail terminates when you can’t cover future payments
  • After termination: The lockup now becomes available to pay the service provider for the period already provided

Think of your account as having these components:

  • Total Funds: All tokens you’ve deposited into the payments contract
  • Lockup Requirement: The minimum balance reserved to guarantee future payments
  • Available Balance: totalFunds - lockupRequirement (this is what you can withdraw)

The lockup finally gets “used” when things go wrong:

  • Rail terminates (due to insufficient funds or manual termination)
  • After termination, the service provider can settle and claim payment from the lockup
  • This ensures the provider gets paid for services already delivered, even if the client disappears
  • Example: If you had 10 days of lockup and the rail terminates, the provider can claim up to 10 days of service payments from that locked amount

For more details on the payment mechanics, see the Filecoin Pay documentation

Each rail consists of:

  • Payer: The account paying for services
  • Payee: The recipient of payments (service provider)
  • Operator: The contract managing the rail (e.g., WarmStorage contract)
  • Payment Rate: Amount paid per epoch
  • Lockup Period: How many epochs of payments to lock up in advance
  • Commission: Percentage taken by the operator (in basis points)

Check active payment rails to monitor ongoing commitments and verify proper service authorization.

Check rails where you’re the payer:

const const payerRails: RailInfo[]payerRails = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getRailsAsPayer(options?: {
    token?: TokenIdentifier;
}): Promise<RailInfo[]>
getRailsAsPayer
();
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
(`You have ${const payerRails: RailInfo[]payerRails.Array<RailInfo>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.
length
} outgoing payment rails`);
for (const const rail: RailInforail of const payerRails: RailInfo[]payerRails) { 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
(`Rail ${const rail: RailInforail.railId: bigintrailId}:`);
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
(`Active: ${!const rail: RailInforail.isTerminated: booleanisTerminated}`);
if (const rail: RailInforail.isTerminated: booleanisTerminated) { 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
(`Terminated at epoch: ${const rail: RailInforail.endEpoch: bigintendEpoch}`);
} }

Check rails where you’re receiving payments:

const const payeeRails: RailInfo[]payeeRails = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getRailsAsPayee(options?: {
    token?: TokenIdentifier;
}): Promise<RailInfo[]>
getRailsAsPayee
();
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
(`You have ${const payeeRails: RailInfo[]payeeRails.Array<RailInfo>.length: number
Gets or sets the length of the array. This is a number one higher than the highest index in the array.
length
} incoming payment rails`);

For detailed information about a specific rail:

const const railInfo: getRail.OutputTyperailInfo = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getRail(options: {
    railId: bigint;
}): Promise<getRail.OutputType>
getRail
({ railId: bigintrailId });
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
("Rail details:", {
from: `0x${string}`from: const railInfo: getRail.OutputTyperailInfo.from: `0x${string}`from, to: `0x${string}`to: const railInfo: getRail.OutputTyperailInfo.to: `0x${string}`to, rate: bigintrate: const railInfo: getRail.OutputTyperailInfo.paymentRate: bigintpaymentRate, settledUpTo: bigintsettledUpTo: const railInfo: getRail.OutputTyperailInfo.settledUpTo: bigintsettledUpTo, isTerminated: booleanisTerminated: const railInfo: getRail.OutputTyperailInfo.endEpoch: bigintendEpoch > 0, });

Settlement is the process of executing the accumulated payments in a rail. Until settled, payments accumulate but aren’t transferred.

  • Gas Efficiency: Batches many epochs of payments into one transaction
  • Flexibility: Allows validators to adjust payments if needed
  • Finality: Makes funds available for withdrawal

The simplest way to settle a rail is using settleAuto(), which automatically detects whether the rail is active or terminated and calls the appropriate method:

// Automatically handles both active and terminated rails
const const hash1: `0x${string}`hash1 = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settleAuto(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<Hash>
settleAuto
({ railId: bigintrailId });
await const synapse: Synapsesynapse.Synapse.client: AccountClient<PublicRpcSchema, PublicActions<Transport, FilecoinChain>>client.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 hash1: `0x${string}`hash1 });
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
("Rail settled successfully");
// For active rails, you can specify the epoch to settle up to const const hash2: `0x${string}`hash2 = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settleAuto(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<Hash>
settleAuto
({ railId: bigintrailId, untilEpoch?: bigint | undefineduntilEpoch: 1000n });
await const synapse: Synapsesynapse.Synapse.client: AccountClient<PublicRpcSchema, PublicActions<Transport, FilecoinChain>>client.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 hash2: `0x${string}`hash2 });
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
("Rail settled successfully up to epoch 1000");

For more control, you can use the specific settlement methods:

Settle up to the current epoch:

// Settle a specific rail (requires settlement fee)
const const hash: `0x${string}`hash = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settle(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<Hash>
settle
({ railId: bigintrailId });
await const synapse: Synapsesynapse.Synapse.client: AccountClient<PublicRpcSchema, PublicActions<Transport, FilecoinChain>>client.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
});
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
("Rail settled successfully");

Settle up to a specific past epoch (partial settlement):

Useful for:

  • Partial settlements to manage cash flow
  • Testing settlement calculations
  • Settling up to a specific accounting period
const const targetEpoch: 1000ntargetEpoch = 1000n; // Ensure it's not in the future
const const hash: `0x${string}`hash = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settle(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<Hash>
settle
({ railId: bigintrailId, untilEpoch?: bigint | undefineduntilEpoch: const targetEpoch: 1000ntargetEpoch });
await const synapse: Synapsesynapse.Synapse.client: AccountClient<PublicRpcSchema, PublicActions<Transport, FilecoinChain>>client.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
});

Important: The untilEpoch parameter:

  • Must be less than or equal to current epoch - Cannot settle future epochs that haven’t occurred yet
  • Can be in the past - Allows partial settlement up to a historical epoch
  • Defaults to current epoch - If omitted, settles all accumulated payments up to now
  • The contract will revert with CannotSettleFutureEpochs error if you try to settle beyond the current epoch

When a rail is terminated, use the specific method for terminated rails:

// Check if rail is terminated
const const railInfo: getRail.OutputTyperailInfo = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getRail(options: {
    railId: bigint;
}): Promise<getRail.OutputType>
getRail
({ railId: bigintrailId });
if (const railInfo: getRail.OutputTyperailInfo.endEpoch: bigintendEpoch > 0) { 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
(`Rail terminated at epoch ${const railInfo: getRail.OutputTyperailInfo.endEpoch: bigintendEpoch}`);
// Settle the terminated rail const const hash: `0x${string}`hash = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settleTerminatedRail(options: {
    railId: bigint;
}): Promise<Hash>
settleTerminatedRail
({ railId: bigintrailId });
await const synapse: Synapsesynapse.Synapse.client: AccountClient<PublicRpcSchema, PublicActions<Transport, FilecoinChain>>client.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
});
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
("Terminated rail settled and closed");
}
// Preview settlement to current epoch
const const amounts: SettlementResultamounts = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getSettlementAmounts(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<SettlementResult>
getSettlementAmounts
({ railId: bigintrailId });
const const totalSettledAmount: stringtotalSettledAmount = function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const amounts: SettlementResultamounts.SettlementResult.totalSettledAmount: biginttotalSettledAmount); const const totalNetPayeeAmount: stringtotalNetPayeeAmount = function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const amounts: SettlementResultamounts.SettlementResult.totalNetPayeeAmount: biginttotalNetPayeeAmount); const const totalOperatorCommission: stringtotalOperatorCommission = function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const amounts: SettlementResultamounts.SettlementResult.totalOperatorCommission: biginttotalOperatorCommission); const const finalSettledEpoch: bigintfinalSettledEpoch = const amounts: SettlementResultamounts.SettlementResult.finalSettledEpoch: bigintfinalSettledEpoch; const const note: stringnote = const amounts: SettlementResultamounts.SettlementResult.note: stringnote; 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
("Settlement preview:");
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
(` Total amount: ${const totalSettledAmount: stringtotalSettledAmount} USDFC`);
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
(` Payee receives: ${const totalNetPayeeAmount: stringtotalNetPayeeAmount} USDFC`);
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
(` Operator commission: ${const totalOperatorCommission: stringtotalOperatorCommission} USDFC`);
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
(` Settled up to epoch: ${const finalSettledEpoch: bigintfinalSettledEpoch}`);
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
(` Note: ${const note: stringnote}`);
// Preview partial settlement to a specific past epoch const const untilEpoch: 1000nuntilEpoch = 1000n; // Must be less than or equal to current epoch const const partialAmounts: SettlementResultpartialAmounts = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getSettlementAmounts(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<SettlementResult>
getSettlementAmounts
({ railId: bigintrailId, untilEpoch?: bigint | undefineduntilEpoch });
const const partialTotalSettledAmount: stringpartialTotalSettledAmount = function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const partialAmounts: SettlementResultpartialAmounts.SettlementResult.totalSettledAmount: biginttotalSettledAmount); 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
(
`Partial settlement to epoch ${const untilEpoch: 1000nuntilEpoch} -`, `would settle: ${const partialTotalSettledAmount: stringpartialTotalSettledAmount} USDFC` );

Service providers (payees) should settle regularly to receive accumulated earnings.

// Example: Settle all incoming rails using settleAuto
async function function settleAllIncomingRails(): Promise<void>settleAllIncomingRails() {
  const const rails: RailInfo[]rails = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getRailsAsPayee(options?: {
    token?: TokenIdentifier;
}): Promise<RailInfo[]>
getRailsAsPayee
();
for (const const rail: RailInforail of const rails: RailInfo[]rails) { try { // Check if settlement is worthwhile const const amounts: SettlementResultamounts = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getSettlementAmounts(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<SettlementResult>
getSettlementAmounts
({ railId: bigintrailId: const rail: RailInforail.railId: bigintrailId });
// Only settle if amount exceeds threshold (e.g., $10) const const threshold: bigintthreshold = function parseUnits(value: string | number | bigint | Dnum, decimals?: number): bigintparseUnits("10"); // 10 USDFC if (const amounts: SettlementResultamounts.SettlementResult.totalNetPayeeAmount: biginttotalNetPayeeAmount > const threshold: bigintthreshold) { // settleAuto handles both active and terminated rails const const hash: `0x${string}`hash = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settleAuto(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<Hash>
settleAuto
({ railId: bigintrailId: const rail: RailInforail.railId: bigintrailId });
await const synapse: Synapsesynapse.Synapse.client: AccountClient<PublicRpcSchema, PublicActions<Transport, FilecoinChain>>client.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
});
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
(
`Settled rail ${const rail: RailInforail.railId: bigintrailId} for ${function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const amounts: SettlementResultamounts.SettlementResult.totalNetPayeeAmount: biginttotalNetPayeeAmount)} USDFC` ); } } catch (function (local var) error: unknownerror) { var console: Consoleconsole.Console.error(...data: any[]): void
The **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)
error
(`Failed to settle rail ${const rail: RailInforail.railId: bigintrailId}:`, function (local var) error: unknownerror);
} } }

Clients (payers) typically don’t need to settle unless:

  • They want to update their available balance before withdrawal
  • A rail is terminated and needs finalization
// Example: Settle before withdrawal
async function function prepareForWithdrawal(): Promise<void>prepareForWithdrawal() {
  const const rails: RailInfo[]rails = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.getRailsAsPayer(options?: {
    token?: TokenIdentifier;
}): Promise<RailInfo[]>
getRailsAsPayer
();
// Settle all rails to update balance (settleAuto handles both active and terminated) for (const const rail: RailInforail of const rails: RailInfo[]rails) { const const hash: `0x${string}`hash = await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settleAuto(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<Hash>
settleAuto
({ railId: bigintrailId: const rail: RailInforail.railId: bigintrailId });
await const synapse: Synapsesynapse.Synapse.client: AccountClient<PublicRpcSchema, PublicActions<Transport, FilecoinChain>>client.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
});
} // Now withdrawal will reflect accurate balance const const availableBalance: bigintavailableBalance = (await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.accountInfo(options?: {
    token?: TokenIdentifier;
}): Promise<accounts.OutputType>
accountInfo
())
.availableFunds: bigintavailableFunds; 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
(
`Available for withdrawal: ${function formatUnits(value: bigint, options?: FormatUnitsOptions): stringformatUnits(const availableBalance: bigintavailableBalance)} USDFC` ); }

Common settlement errors and solutions:

try {
  await const synapse: Synapsesynapse.Synapse.payments: PaymentsServicepayments.
PaymentsService.settle(options: {
    railId: bigint;
    untilEpoch?: bigint;
}): Promise<Hash>
settle
({railId: bigintrailId});
} catch (var error: unknownerror) { if (var error: unknownerror instanceof var Error: ErrorConstructorError && var error: Errorerror.Error.message: stringmessage.String.includes(searchString: string, position?: number): boolean
Returns true if searchString appears as a substring of the result of converting this object to a String, at one or more positions that are greater than or equal to position; otherwise, returns false.
@paramsearchString search string@paramposition If position is undefined, 0 is assumed, so as to search all of the String.
includes
("InsufficientNativeTokenForBurn")) {
var console: Consoleconsole.Console.error(...data: any[]): void
The **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)
error
("Insufficient FIL for settlement fee (0.0013 FIL required)");
} else if (var error: unknownerror instanceof var Error: ErrorConstructorError && var error: Errorerror.Error.message: stringmessage.String.includes(searchString: string, position?: number): boolean
Returns true if searchString appears as a substring of the result of converting this object to a String, at one or more positions that are greater than or equal to position; otherwise, returns false.
@paramsearchString search string@paramposition If position is undefined, 0 is assumed, so as to search all of the String.
includes
("NoProgressInSettlement")) {
var console: Consoleconsole.Console.error(...data: any[]): void
The **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)
error
("Rail already settled to current epoch");
} else if (var error: unknownerror instanceof var Error: ErrorConstructorError && var error: Errorerror.Error.message: stringmessage.String.includes(searchString: string, position?: number): boolean
Returns true if searchString appears as a substring of the result of converting this object to a String, at one or more positions that are greater than or equal to position; otherwise, returns false.
@paramsearchString search string@paramposition If position is undefined, 0 is assumed, so as to search all of the String.
includes
("RailNotActive")) {
var console: Consoleconsole.Console.error(...data: any[]): void
The **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)
error
("Rail is not active or already terminated");
} else { var console: Consoleconsole.Console.error(...data: any[]): void
The **`console.error()`** static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error_static)
error
("Settlement failed:", var error: unknownerror);
} }