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: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getRailsAsPayer(token?: TokenIdentifier): Promise<RailInfo[]>
getRailsAsPayer
();
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

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: RailInfo
rail
of
const payerRails: RailInfo[]
payerRails
) {
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(`Rail ${
const rail: RailInfo
rail
.
railId: bigint
railId
}:`);
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(`Active: ${!
const rail: RailInfo
rail
.
isTerminated: boolean
isTerminated
}`);
if (
const rail: RailInfo
rail
.
isTerminated: boolean
isTerminated
) {
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(`Terminated at epoch: ${
const rail: RailInfo
rail
.
endEpoch: bigint
endEpoch
}`);
}
}

Check rails where you’re receiving payments:

const
const payeeRails: RailInfo[]
payeeRails
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getRailsAsPayee(token?: TokenIdentifier): Promise<RailInfo[]>
getRailsAsPayee
();
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

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: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getRail(railId: bigint): Promise<{
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}>
getRail
(
const railId: bigint
railId
);
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
("Rail details:", {
from: `0x${string}`
from
:
const railInfo: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
.
from: `0x${string}`
from
,
to: `0x${string}`
to
:
const railInfo: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
.
to: `0x${string}`
to
,
rate: bigint
rate
:
const railInfo: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
.
paymentRate: bigint
paymentRate
,
settledUpTo: bigint
settledUpTo
:
const railInfo: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
.
settledUpTo: bigint
settledUpTo
,
isTerminated: boolean
isTerminated
:
const railInfo: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
.
endEpoch: bigint
endEpoch
> 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: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.settleAuto(railId: bigint, untilEpoch?: bigint): Promise<Hash>
settleAuto
(
const railId: 1n
railId
);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

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

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

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

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

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

The hash of the transaction.

hash
:
const hash1: `0x${string}`
hash1
});
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

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: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.settleAuto(railId: bigint, untilEpoch?: bigint): Promise<Hash>
settleAuto
(
const railId: 1n
railId
, 1000n);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

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

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

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

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

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

The hash of the transaction.

hash
:
const hash2: `0x${string}`
hash2
});
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

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: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.settle(railId: bigint, untilEpoch?: bigint): Promise<Hash>
settle
(
const railId: 1n
railId
);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

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

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

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

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

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

The hash of the transaction.

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

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

MDN Reference

log
("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: 1000n
targetEpoch
= 1000n; // Ensure it's not in the future
const
const hash: `0x${string}`
hash
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.settle(railId: bigint, untilEpoch?: bigint): Promise<Hash>
settle
(
const railId: 1n
railId
,
const targetEpoch: 1000n
targetEpoch
);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

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

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

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

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

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

The hash of the transaction.

hash
});

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: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getRail(railId: bigint): Promise<{
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}>
getRail
(
const railId: 1n
railId
);
if (
const railInfo: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
.
endEpoch: bigint
endEpoch
> 0) {
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(`Rail terminated at epoch ${
const railInfo: {
token: Address;
from: Address;
to: Address;
operator: Address;
validator: Address;
paymentRate: bigint;
lockupPeriod: bigint;
lockupFixed: bigint;
settledUpTo: bigint;
endEpoch: bigint;
commissionRateBps: bigint;
serviceFeeRecipient: Address;
}
railInfo
.
endEpoch: bigint
endEpoch
}`);
// Settle the terminated rail
const
const hash: `0x${string}`
hash
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.settleTerminatedRail(railId: bigint): Promise<Hash>
settleTerminatedRail
(
const railId: 1n
railId
);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

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

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

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

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

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

The hash of the transaction.

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

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

MDN Reference

log
("Terminated rail settled and closed");
}
// Preview settlement to current epoch
const
const amounts: SettlementResult
amounts
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getSettlementAmounts(railId: bigint, untilEpoch?: bigint): Promise<SettlementResult>
getSettlementAmounts
(
const railId: 1n
railId
);
const
const totalSettledAmount: string
totalSettledAmount
=
function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits
(
const amounts: SettlementResult
amounts
.
SettlementResult.totalSettledAmount: bigint
totalSettledAmount
);
const
const totalNetPayeeAmount: string
totalNetPayeeAmount
=
function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits
(
const amounts: SettlementResult
amounts
.
SettlementResult.totalNetPayeeAmount: bigint
totalNetPayeeAmount
);
const
const totalOperatorCommission: string
totalOperatorCommission
=
function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits
(
const amounts: SettlementResult
amounts
.
SettlementResult.totalOperatorCommission: bigint
totalOperatorCommission
);
const
const finalSettledEpoch: bigint
finalSettledEpoch
=
const amounts: SettlementResult
amounts
.
SettlementResult.finalSettledEpoch: bigint
finalSettledEpoch
;
const
const note: string
note
=
const amounts: SettlementResult
amounts
.
SettlementResult.note: string
note
;
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
("Settlement preview:");
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(` Total amount: ${
const totalSettledAmount: string
totalSettledAmount
} USDFC`);
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(` Payee receives: ${
const totalNetPayeeAmount: string
totalNetPayeeAmount
} USDFC`);
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(` Operator commission: ${
const totalOperatorCommission: string
totalOperatorCommission
} USDFC`);
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(` Settled up to epoch: ${
const finalSettledEpoch: bigint
finalSettledEpoch
}`);
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(` Note: ${
const note: string
note
}`);
// Preview partial settlement to a specific past epoch
const
const targetEpoch: 1000n
targetEpoch
= 1000n; // Must be less than or equal to current epoch
const
const partialAmounts: SettlementResult
partialAmounts
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getSettlementAmounts(railId: bigint, untilEpoch?: bigint): Promise<SettlementResult>
getSettlementAmounts
(
const railId: 1n
railId
,
const targetEpoch: 1000n
targetEpoch
);
const
const partialTotalSettledAmount: string
partialTotalSettledAmount
=
function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits
(
const partialAmounts: SettlementResult
partialAmounts
.
SettlementResult.totalSettledAmount: bigint
totalSettledAmount
);
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(
`Partial settlement to epoch ${
const targetEpoch: 1000n
targetEpoch
} -`,
`would settle: ${
const partialTotalSettledAmount: string
partialTotalSettledAmount
} 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: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getRailsAsPayee(token?: TokenIdentifier): Promise<RailInfo[]>
getRailsAsPayee
();
for (const
const rail: RailInfo
rail
of
const rails: RailInfo[]
rails
) {
try {
// Check if settlement is worthwhile
const
const amounts: SettlementResult
amounts
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getSettlementAmounts(railId: bigint, untilEpoch?: bigint): Promise<SettlementResult>
getSettlementAmounts
(
const rail: RailInfo
rail
.
railId: bigint
railId
);
// Only settle if amount exceeds threshold (e.g., $10)
const
const threshold: bigint
threshold
=
function parseUnits(value: string | number | bigint | Dnum, decimals?: number): bigint
parseUnits
("10"); // 10 USDFC
if (
const amounts: SettlementResult
amounts
.
SettlementResult.totalNetPayeeAmount: bigint
totalNetPayeeAmount
>
const threshold: bigint
threshold
) {
// settleAuto handles both active and terminated rails
const
const hash: `0x${string}`
hash
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.settleAuto(railId: bigint, untilEpoch?: bigint): Promise<Hash>
settleAuto
(
const rail: RailInfo
rail
.
railId: bigint
railId
);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

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

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

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

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

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

The hash of the transaction.

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

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

MDN Reference

log
(
`Settled rail ${
const rail: RailInfo
rail
.
railId: bigint
railId
} for ${
function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits
(
const amounts: SettlementResult
amounts
.
SettlementResult.totalNetPayeeAmount: bigint
totalNetPayeeAmount
)} USDFC`
);
}
} catch (
function (local var) error: unknown
error
) {
var console: Console
console
.
Console.error(...data: any[]): void

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

MDN Reference

error
(`Failed to settle rail ${
const rail: RailInfo
rail
.
railId: bigint
railId
}:`,
function (local var) error: unknown
error
);
}
}
}

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: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.getRailsAsPayer(token?: TokenIdentifier): Promise<RailInfo[]>
getRailsAsPayer
();
// Settle all rails to update balance (settleAuto handles both active and terminated)
for (const
const rail: RailInfo
rail
of
const rails: RailInfo[]
rails
) {
const
const hash: `0x${string}`
hash
= await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.settleAuto(railId: bigint, untilEpoch?: bigint): Promise<Hash>
settleAuto
(
const rail: RailInfo
rail
.
railId: bigint
railId
);
await
const synapse: Synapse
synapse
.
Synapse.client: Client<Transport, Chain, Account, PublicRpcSchema, PublicActions<Transport, Chain>>
client
.
waitForTransactionReceipt: (args: WaitForTransactionReceiptParameters<Chain>) => Promise<TransactionReceipt>

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

@paramargs - WaitForTransactionReceiptParameters

@returnsThe transaction receipt. WaitForTransactionReceiptReturnType

@example

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

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

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

The hash of the transaction.

hash
});
}
// Now withdrawal will reflect accurate balance
const
const availableBalance: bigint
availableBalance
= (await
const synapse: Synapse
synapse
.
Synapse.payments: PaymentsService
payments
.
PaymentsService.accountInfo(token?: TokenIdentifier): Promise<{
funds: bigint;
lockupCurrent: bigint;
lockupRate: bigint;
lockupLastSettledAt: bigint;
availableFunds: bigint;
}>
accountInfo
())
.
availableFunds: bigint
availableFunds
;
var console: Console
console
.
Console.log(...data: any[]): void

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

MDN Reference

log
(
`Available for withdrawal: ${
function formatUnits(value: bigint, options?: FormatUnitsOptions): string
formatUnits
(
const availableBalance: bigint
availableBalance
)} USDFC`
);
}

Common settlement errors and solutions:

try {
await synapse.payments.settle(railId);
} catch (error) {
if (error.message.includes("InsufficientNativeTokenForBurn")) {
console.error("Insufficient FIL for settlement fee (0.0013 FIL required)");
} else if (error.message.includes("NoProgressInSettlement")) {
console.error("Rail already settled to current epoch");
} else if (error.message.includes("RailNotActive")) {
console.error("Rail is not active or already terminated");
} else {
console.error("Settlement failed:", error);
}
}