Waterfall

Waterfall

Begin by importing WaterfallClient into your app. If you are using the SplitsClient, you can access the waterfall client as well.

import { WaterfallClient } from '@0xsplits/splits-sdk'
 
const waterfallClient = new WaterfallClient({
  chainId,
  publicClient, // viem public client (optional, required if using any of the contract functions)
  walletClient, // viem wallet client (optional, required if using any contract write functions. must have an account already attached)
  includeEnsNames, // boolean, defaults to false. If true, will return ens names for any waterfall recipient (only for mainnet)
  // If you want to return ens names on chains other than mainnet, you can pass in a mainnet public client
  // here. Be aware though that the ens name may not necessarily resolve to the proper address on the
  // other chain for non EOAs (e.g. Gnosis Safe's)
  ensPublicClient, // viem public client (optional)
})

OR

import { SplitsClient } from '@0xsplits/splits-sdk'
 
const splitsClient = new SplitsClient({
  chainId,
  publicClient,
  walletClient,
  includeEnsNames,
  ensPublicClient,
})
 
const waterfallClient = splitsClient.waterfall

Now you're ready to use any of the functions. All Arguments and Responses for these functions are objects. This will make it easier for us to release updates to the SDK without breaking existing implementations.

The SDK comprises 3 different types of functions: Subgraph Reads, Waterfall Writes, and Waterfall Reads.

Subgraph Reads

These functions make it easier to query the subgraph.

getWaterfallMetadata

Returns all metadata for a given waterfallModuleAddress.

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
}
 
const response = await waterfallClient.getWaterfallMetadata(args)

Arguments

{
  waterfallModuleAddress: string
}

Response

{
  type: 'WaterfallModule'
  address: string
  token: {
    address: string
    symbol?: string
    decimals?: number
  }
  nonWaterfallRecipient: {
    address: string
    ensName?: string
  } | null
  tranches: {
    recipient: {
      address: string
      ensName?: string
    }
    startAmount: number
    size?: number
  }[]
}

Waterfall Writes

These functions make it easier to call Waterfall functions.

createWaterfallModule

Creates a new Waterfall contract.

Usage

const args = {
  token: "0x0000000000000000000000000000000000000000"
  tranches: [
    {
      recipient: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f",
      size: 5.2 # Receives the first 5.2 eth
    },
    {
      recipient: "0xc3313847E2c4A506893999f9d53d07cDa961a675",
      size: 3 # Receives the next 3 eth
    },
    {
      recipient: "0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342",
    }
  ]
}
 
const response = await waterfallClient.createWaterfallModule(args)

Arguments

{
  token: string
  tranches: {
    recipient: string
    size?: number # the last tranche should have no size set, as it will receive all residual funds
  }[]
  nonWaterfallRecipient?: string # defaults to AddressZero, meaning any tranche recipient can recover non-waterfall tokens
}

Response

{
  waterfallModuleAddress: string
  event: Log # CreateWaterfallModule emitted on WaterfallModuleFactory
}

waterfallFunds

Distributes the current balance for the given waterfall through it's tranches

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
}
 
const response = await waterfallClient.waterfallFunds(args)

Arguments

{
  waterfallModuleAddress: string
  # If you have attempted to distribute the funds through the tranches, but are
  # hitting an error due to one of the tranche recipients being unable to receive
  # funds, you can call waterfallFunds with usePull set to true. This will set aside
  # the appropriate balance for each tranche recipient within the waterfall module
  # contract. Each recipient can then withdraw their funds using the withdrawPullFunds
  # function below.
  usePull?: boolean # defaults to false
}

Response

{
  event: Log # WaterfallFunds emitted on the Waterfall contract
}

recoverNonWaterfallFunds

Recovers the balance of token for waterfallModuleAddress to the passed in recipient.

Usage

const args = {
  waterfallModuleAddress: "0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC"
  token: "0x64d91f12ece7362f91a6f8e7940cd55f05060b92"
  recipient: "0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72"
}
 
const response = await waterfallClient.recoverNonWaterfallFunds(args)

Arguments

{
  waterfallModuleAddress: string
  token: string
  # The recipient can be any of the tranche recipients on the waterfall. If a `nonWaterfallRecipient`
  # was set when the waterfall was created, then recipient must be that address
  recipient: string
}

Response

{
  event: Log # RecoverNonWaterfallFunds on the Waterfall contract
}

withdrawPullFunds

Withdraws the funds for the passed in recipient that were set aside after a waterfallFunds call with usePull set to true.

Usage

const args = {
  waterfallModuleAddress: "0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC"
  address: "0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72"
}
 
const response = await waterfallClient.withdrawPullFunds(args)

Arguments

{
  waterfallModuleAddress: string
  address: string
}

Response

{
  event: Log # Withdrawal emitted on the Waterfall contract
}

Gas Estimation

The client has a gas estimation feature that can be used with any of the above write functions. Just call the function off of the estimateGas property. Estimating the gas for the create waterfall module function would look like:

const args = {
  token: "0x0000000000000000000000000000000000000000"
  tranches: [
    {
      recipient: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f",
      size: 5.2 # Receives the first 5.2 eth
    },
    {
      recipient: "0xc3313847E2c4A506893999f9d53d07cDa961a675",
      size: 3 # Receives the next 3 eth
    },
    {
      recipient: "0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342",
    }
  ]
}
 
const gasEstimate = await waterfallClient.estimateGas.createWaterfallModule(args)

CallData

The client has a call data feature that can be used with any of the above write functions. Just call the function off of the callData property. Generating call data for the create waterfall module function would look like:

const args = {
  token: "0x0000000000000000000000000000000000000000"
  tranches: [
    {
      recipient: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f",
      size: 5.2 # Receives the first 5.2 eth
    },
    {
      recipient: "0xc3313847E2c4A506893999f9d53d07cDa961a675",
      size: 3 # Receives the next 3 eth
    },
    {
      recipient: "0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342",
    }
  ]
}
 
const callData = await waterfallClient.callData.createWaterfallModule(args)

Waterfall Reads

These functions make it easier to query the Waterfall contracts.

getDistributedFunds

Returns the distributed balance for a given waterfallModuleAddress.

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
}
 
const response = await waterfallClient.getDistributedFunds(args)

Arguments

{
  waterfallModuleAddress: string
}

Response

{
  distributedFunds: bigint
}

getFundsPendingWithdrawal

Returns the pending balance for pull withdrawal for a given waterfallModuleAddress.

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
}
 
const response = await waterfallClient.getFundsPendingWithdrawal(args)

Arguments

{
  waterfallModuleAddress: string
}

Response

{
  fundsPendingWithdrawal: bigint
}

getTranches

Returns the recipient list and threshold list for the tranches of a given waterfallModuleAddress.

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
}
 
const response = await waterfallClient.getTranches(args)

Arguments

{
  waterfallModuleAddress: string
}

Response

{
  recipients: string[]
  thresholds: bigint[]
}

getNonWaterfallRecipient

Returns the non-waterfall recipient for a given waterfallModuleAddress. If none was set, returns the zero address.

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
}
 
const response = await waterfallClient.getNonWaterfallRecipient(args)

Arguments

{
  waterfallModuleAddress: string
}

Response

{
  nonWaterfallRecipient: string
}

getToken

Returns the token for a given waterfallModuleAddress.

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
}
 
const response = await waterfallClient.getToken(args)

Arguments

{
  waterfallModuleAddress: string
}

Response

{
  token: string
}

getPullBalance

Returns the balance set aside for withdrawal for a given waterfallModuleAddress and recipient address.

Usage

const args = {
  waterfallModuleAddress: '0x8904D1fBfc9c88792aaaE8f452ac57E1Ba2130fC',
  address: '0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72',
}
 
const response = await waterfallClient.getPullBalance(args)

Arguments

{
  waterfallModuleAddress: string
  address: string
}

Response

{
  pullBalance: bigint
}