Splits
Begin by importing SplitsClient
into your app.
import { SplitsClient } from '@0xsplits/splits-sdk'
const splitsClient = new SplitsClient({
chainId,
provider, // ethers provider (optional, required if using any of the SplitMain functions)
signer, // ethers signer (optional, required if using the SplitMain write functions)
includeEnsNames, // boolean, defaults to false. If true, will return ens names for split recipients (only for mainnet)
// If you want to return ens names on chains other than mainnet, you can pass in a mainnet provider
// 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)
ensProvider, // ethers provider (optional)
})
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, SplitMain Writes, and SplitMain Reads.
Subgraph Reads
These functions make it easier to query the subgraph.
getSplitMetadata
Returns all metadata for a given splitId
.
Usage
const args = {
splitId: '0xF8843981e7846945960f53243cA2Fd42a579f719',
}
const response = await splitsClient.getSplitMetadata(args)
Arguments
{
splitId: string
}
Response
{
type: 'Split'
id: string
controller: string | null
newPotentialController: string | null
distributorFeePercent: number
recipients: {
address: string
percentAllocation: number
ensName?: string
}[]
createdBlock: number
}
getRelatedSplits
Returns all Splits related to a given address
.
Usage
const args = {
address: '0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342',
}
const response = await splitsClient.getRelatedSplits(args)
Arguments
{
address: string
}
Response
{
receivingFrom: { # Splits in which the address is a Recipient
id: string
controller: string | null
newPotentialController: string | null
distributorFeePercent: number
recipients: {
address: string;
percentAllocation: number
ensName?: string
}[]
createdBlock: number
}[]
controlling: { # Splits of which the address is the Controller
id: string
controller: string | null
newPotentialController: string | null
distributorFeePercent: number
recipients: {
address: string;
percentAllocation: number
ensName?: string
}[]
createdBlock: number
}[]
pendingControl: { # Splits of which the address has been given but not yet accepted Control
id: string
controller: string | null
newPotentialController: string | null
distributorFeePercent: number
recipients: {
address: string;
percentAllocation: number
ensName?: string
}[]
createdBlock: number
}[]
}
getSplitEarnings
Returns token balances for a given splitId
.
NOTE: Fetching active balances optionally takes an erc20TokenList
argument. If
the provider is not Alchemy or Infura, that token list is required. If the token
list is passed in, balances will only be fetched for tokens in that list (as
well as the native token and any previously distributed tokens). Otherwise, all
erc20 transfers to the split address will be reviewed with a getLogs
request,
but only Alchemy and Infura support a large enough getLogs
request. You can
disable fetching active balances by passing in includeActiveBalances: false
.
Usage
const args = {
splitId: '0xF8843981e7846945960f53243cA2Fd42a579f719',
}
const response = await splitsClient.getSplitEarnings(args)
Arguments
{
splitId: string
includeActiveBalances?: boolean # defaults to true
erc20TokenList?: string[]
}
Response
{
activeBalances?: { # tokens that are waiting to be distributed
[token: string]: BigNumber
}
distributed: { # tokens that have already been distributed
[token: string]: BigNumber
}
}
getFormattedSplitEarnings
Returns the same data as getSplitEarnings
, but includes token data as well as a
formatted amount.
Usage
const args = {
splitId: '0xF8843981e7846945960f53243cA2Fd42a579f719',
}
const response = await splitsClient.getFormattedSplitEarnings(args)
Arguments
{
splitId: string
includeActiveBalances?: boolean # defaults to true
erc20TokenList?: string[]
}
Response
{
activeBalances?: { # tokens that are waiting to be distributed
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
distributed: { # tokens that have already been distributed
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
}
getUserEarnings
Returns token balances for a given userId
.
Usage
const args = {
userId: '0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342',
}
const response = await splitsClient.getUserEarnings(args)
Arguments
{
userId: string
}
Response
{
withdrawn: { # tokens the user has already withdrawn from the protocol
[token: string]: BigNumber
}
activeBalances: { # tokens that have been distributed but not yet withdrawn
[token: string]: BigNumber
}
}
getFormattedUserEarnings
Returns the same data as getUserEarnings
, but includes token data as well as a
formatted amount.
Usage
const args = {
userId: '0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342',
}
const response = await splitsClient.getFormattedUserEarnings(args)
Arguments
{
userId: string
}
Response
{
withdrawn: { # tokens the user has already withdrawn from the protocol
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
activeBalances: { # tokens that have been distributed but not yet withdrawn
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
}
getUserEarningsByContract
Returns token balances for a given userId
, separated out by each 0xSplits contract the user has received from.
Can optionally pass in a list of contractIds
to filter results to just a set of contracts.
Usage
const args = {
userId: '0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342',
}
const response = await splitsClient.getUserEarningsByContract(args)
Arguments
{
userId: string
contractIds?: string[]
}
Response
{
withdrawn: { # tokens the user has already withdrawn from the protocol
[token: string]: BigNumber
}
activeBalances: { # tokens that have been distributed but not yet withdrawn
[token: string]: BigNumber
}
earningsByContract: { # Earnings broken out by each 0xSplits contract the user has received from
[contractAddress: string]: {
withdrawn: {
[token: string]: BigNumber
}
activeBalances: {
[token: string]: BigNumber
}
}
}
}
getFormattedUserEarningsByContract
Returns the same data as getUserEarningsByContract
, but includes token data as well as a
formatted amount.
Usage
const args = {
userId: '0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342',
}
const response = await splitsClient.getFormattedUserEarningsByContract(args)
Arguments
{
userId: string
contractIds?: string[]
}
Response
{
withdrawn: { # tokens the user has already withdrawn from the protocol
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
activeBalances: { # tokens that have been distributed but not yet withdrawn
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
earningsByContract: { # Earnings broken out by each 0xSplits contract the user has received from
[contractAddress: string]: {
withdrawn: {
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
activeBalances: {
[token: string]: {
symbol: string
decimals: number
rawAmount: BigNumber
formattedAmount: string
}
}
}
}
}
SplitMain Writes
createSplit
Creates a new Split contract.
Usage
const args = {
recipients: [
{
address: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f";
percentAllocation: 50.0000
},
{
address: "0xc3313847E2c4A506893999f9d53d07cDa961a675";
percentAllocation: 50.0000
}
]
distributorFeePercent: 1.0000
controller: "0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342"
}
const response = await splitsClient.createSplit(args)
Arguments
{
recipients: {
address: string;
percentAllocation: number # >0 and <100 and up to 4 decimals
}[]
distributorFeePercent: number # <10 and up to 4 decimals
controller?: string # defaults to AddressZero for an immutable split
}
Response
{
splitId: string
event: Event # CreateSplit emitted on SplitMain
}
updateSplit
Updates an existing mutable Split contract. Only callable by the controller of
splitId
.
Usage
const args = {
splitId: "0x047ED5b8E8a7eDBd92FAF61f3117cAFE8c529ABb"
recipients: {
{
address: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f";
percentAllocation: 50.0000
},
{
address: "0xc3313847E2c4A506893999f9d53d07cDa961a675";
percentAllocation: 50.0000
},
}
distributorFeePercent: 1.0000
}
const response = await splitsClient.updateSplit(args)
Arguments
{
splitId: string
recipients: {
address: string;
percentAllocation: number
}[]
distributorFeePercent: number
}
Response
{
event: Event # UpdateSplit emitted on SplitMain
}
distributeToken
Distributes the balance of token
for splitId
, and sends the distributor fee
to distributorAddress
.
Usage
const args = {
splitId: "0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9"
token: "0x64d91f12ece7362f91a6f8e7940cd55f05060b92"
distributorAddress: "0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72"
}
const response = await splitsClient.distributeToken(args)
Arguments
{
splitId: string
token: string
distributorAddress?: string # defaults to signer
}
Response
{
event: Event # DistributeETH or DistributeERC20 emitted on SplitMain
}
updateSplitAndDistributeToken
This combines updateSplit and
distributeToken into one transaction. Only callable by the
controller of splitId
.
Usage
const args = {
splitId: "0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9"
token: "0x64d91f12ece7362f91a6f8e7940cd55f05060b92"
recipients: {
{
address: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f";
percentAllocation: 50.0000
},
{
address: "0xc3313847E2c4A506893999f9d53d07cDa961a675";
percentAllocation: 50.0000
},
}
distributorFeePercent: 1.0000
distributorAddress: "0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72"
}
const response = await splitsClient.updateSplitAndDistributeToken(args)
Arguments
{
splitId: string
token: string
recipients: {
address: string;
percentAllocation: number
}[]
distributorFeePercent: number
distributorAddress?: string # defaults to signer
}
Response
{
event: Event # UpdateSplit and DistributeETH or DistributeERC20 emitted on SplitMain
}
withdrawFunds
Withdraws tokens
for a given address
.
Usage
const args = {
address: "0x357138F2690B82f29dF32bf2a3d0e6d4CC4D63C1"
tokens: [
"0x64d91f12ece7362f91a6f8e7940cd55f05060b92",
"0x0000000000000000000000000000000000000000"
]
}
const response = await splitsClient.withdrawFunds(args)
Arguments
{
address: string
tokens: string[]
}
Response
{
event: Event # Withdrawal emitted on SplitMain
}
initiateControlTransfer
Transfers control of splitId
to newController
. Only callable by the
controller of splitId
.
Usage
const args = {
splitId: "0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9"
newController: "0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72"
}
const response = await splitsClient.initiateControlTransfer(args)
Arguments
{
splitId: string
newController: string
}
Response
{
event: Event # InitiateControlTransfer emitted on SplitMain
}
acceptControlTransfer
Accepts control of splitId
. Only callable by the new controller of splitId
.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
}
const response = await splitsClient.acceptControlTransfer(args)
Arguments
{
splitId: string
}
Response
{
event: Event # ControlTransfer emitted on SplitMain
}
cancelControlTransfer
Cancels the transfer of splitId
. Only callable by the controller of splitId
.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
}
const response = await splitsClient.cancelControlTransfer(args)
Arguments
{
splitId: string
}
Response
{
event: Event # CancelControlTransfer emitted on SplitMain
}
makeSplitImmutable
Makes splitId
immutable. Only callable by the controller of splitId
.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
}
const response = await splitsClient.makeSplitImmutable(args)
Arguments
{
splitId: string
}
Response
{
event: Event # ControlTransfer emitted on SplitMain
}
batchDistributeAndWithdraw
Performs a multicall transaction, will distribute multiple tokens on a split and withdraw for any given addresses.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
tokens: [
'0x0000000000000000000000000000000000000000',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
],
recipientAddresses: [
'0x39883c6e81e273f381bffe5a8c26c3a866ff57ca',
'0xeb78334dfde3afbc2b904f06153f59cc80ee07fa',
'0x6b48ad78a26604b9e158a07ec4abb2981842e168',
'0xc3313847E2c4A506893999f9d53d07cDa961a675',
],
distributorAddress: '0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72',
}
const response = await splitsClient.batchDistributeAndWithdraw(args)
Arguments
{
splitId: string
tokens: string[]
recipientAddresses: string[]
distributorAddress?: string # defaults to signer
}
Response
{
events: Event[]
}
batchDistributeAndWithdrawForAll
Performs a multicall transaction, will distribute multiple tokens on a split and withdraw for all recipients.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
tokens: [
'0x0000000000000000000000000000000000000000',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
],
distributorAddress: '0x2fa128274cfcf47afd4dc03cd3f2a59af09b6a72',
}
const response = await splitsClient.batchDistributeAndWithdrawForAll(args)
Arguments
{
splitId: string
tokens: string[]
distributorAddress?: string # defaults to signer
}
Response
{
events: Event[]
}
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 split function would look like:
const args = {
recipients: [
{
address: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f";
percentAllocation: 50.0000
},
{
address: "0xc3313847E2c4A506893999f9d53d07cDa961a675";
percentAllocation: 50.0000
}
]
distributorFeePercent: 1.0000
controller: "0xEc8Bfc8637247cEe680444BA1E25fA5e151Ba342"
}
const gasEstimate = await splitsClient.estimateGas.createSplit(args)
SplitMain Reads
getSplitBalance
Returns the balance for a given splitId
and token
. If no token
is
provided, returns the ETH balance.
Usage
const args = {
splitId: '0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE',
token: '0x64d91f12ece7362f91a6f8e7940cd55f05060b92',
}
const response = await splitsClient.getSplitBalance(args)
Arguments
{
splitId: string
token?: string # defaults to AddressZero
}
Response
{
balance: BigNumber
}
predictImmutableSplitAddress
Returns the determinisic address (using
CREATE2 (opens in a new tab)) at which an immutable Split
will be deployed for given recipients
and distributorFeePercent
.
Usage
const args = {
recipients: {
{
address: "0x442C01498ED8205bFD9aaB6B8cc5C810Ed070C8f";
percentAllocation: 50.0000
},
{
address: "0xc3313847E2c4A506893999f9d53d07cDa961a675";
percentAllocation: 50.0000
},
}
distributorFeePercent: 1.0000
}
const response = await splitsClient.predictImmutableSplitAddress(args)
Arguments
{
recipients: {
address: string;
percentAllocation: number
}[]
distributorFeePercent: number
}
Response
{
splitId: string
}
getController
Returns the controller for a given splitId
.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
}
const response = await splitsClient.getController(args)
Arguments
{
splitId: string
}
Response
{
controller: string
}
getNewPotentialController
Returns the new potential controller (i.e., the account that needs to accept
control) for a given splitId
.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
}
const response = await splitsClient.getNewPotentialController(args)
Arguments
{
splitId: string
}
Response
{
newPotentialController: string
}
getHash
Returns the current hash for a given splitId
.
Usage
const args = {
splitId: '0xd9137B84f56D61Bb961082DD9Eb21bE3D7B14cB9',
}
const response = await splitsClient.getHash(args)
Arguments
{
splitId: string
}
Response
{
hash: string
}