Swapping
Integrations
Javascript SDK
Swap Assets
Request deposit address
Request Deposit Address V1

Request Deposit Address

The ability to create a unique deposit address that is reserved for a user during a fixed period of time (24hs) provides a lot of flexibility and is a unique feature of the Chainflip protocol.

Once the deposit address is available, the user can send the funds from any wallet(s) to trigger the swap process. No need to connect a wallet.

Sending funds to a deposit address is cheaper than a smart contract call, as no token approvals are required.

Learn more on Deposit Channels & Brokers section.

requestDepositAddress

Requests a deposit address based on the provided DepositAddressRequest.

requestDepositAddress(
  depositAddressRequest: DepositAddressRequest
): Promise<DepositAddressResponse>

The depositAddressRequest object describes the swap for which a deposit address is requested.

ParamDescriptionData type
srcChain(required)Source chain for the swapChain
destChain(required)Destination chain for the swapChain
srcAsset(required)Symbol of the token to be swapped from the source chainAsset
destAsset(required)Symbol of the token to be received on the destination chainAsset
destAddress(required)Address where the swapped tokens will be sent to on the destination chainstring
amount(required)Amount of the source token to be swapped, represented in the base unit of the source tokenstring
brokerCommissionBps(optional)Commission charged by the broker creating the channel, in basis points. If given, this value will be used instead of the brokerCommissionBps value used when initializing the SDK. This option is only available when the SDK is initialized with a brokerUrlnumber
affiliateBrokers(optional)An array of objects defining affiliate broker accounts that take a commission in addition to brokerCommissionBps. This option is only available when the SDK is initialized with a brokerUrlArray
ccmParams(optional)Optional metadata for triggering a [smart contract call](../advanced/cross-chain-messaging.mdx) on the destination chain.Object
maxBoostFeeBps(optional)The accepted boost fee limit (in bps).
Defaults to 0 - non-boostable deposit channel.
If set to a value higher than 0, the deposits coming through this channel will have a chance to get boosted by paying a fee that doesn't exceed the boost fee limit set - boostable deposit channel.
It is recommended to understand under which conditions deposits get boosted.
number
fillOrKillParams(optional)Optional metadata for setting a minimum accepted price for swaps through the deposit channel. This allows to protect against price changes between a quote and the execution of a swap (also known as slippage protection).Object
dcaParams(optional)Optional metadata for executing a swap through a deposit channel as a DCA swap. Setting these params will split the swap into smaller chunks and execute them consecutively with a delay.Object

Example

Regular Deposit Address

import { Chains, Assets } from "@chainflip/sdk/swap";
 
const swapDepositAddressRequest = {
  srcChain: Chains.Ethereum,
  destChain: Chains.Bitcoin,
  srcAsset: Assets.ETH,
  destAsset: Assets.BTC,
  destAddress: "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
  amount: (1.5e18).toString(), // 1.5 ETH
  brokerCommissionBps: 100, // 100 basis point = 1%
  affiliateBrokers: [
    { account: "cFM8kRvLBXagj6ZXvrt7wCM4jGmHvb5842jTtXXg3mRHjrvKy", commissionBps: 50 }
  ], // total commission 150 bps = 1.5%
};
console.log(await swapSDK.requestDepositAddress(swapDepositAddressRequest));

Boostable Deposit Address

import { Chains, Assets } from "@chainflip/sdk/swap";
 
const swapDepositAddressRequest = {
  srcChain: Chains.Ethereum,
  destChain: Chains.Bitcoin,
  srcAsset: Assets.ETH,
  destAsset: Assets.BTC,
  destAddress: "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
  amount: (1.5e18).toString(), // 1.5 ETH
  maxBoostFeeBps: 10 // Willing to pay up to 10 bps fee for a boosted deposit
};
console.log(await swapSDK.requestDepositAddress(swapDepositAddressRequest));

The amount will always be in the base unit of the source asset, i.e. for ETH it will be Wei.

Sample Response

{
  "srcChain": "Ethereum",
  "destChain": "Bitcoin",
  "srcAsset": "ETH",
  "destAsset": "BTC",
  "destAddress": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
  "amount": "1500000000000000000", // 1.5 ETH
  "depositChannelId": "1234567890", // Identifies the deposit channel for this swap
  "depositAddress": "0x1234567890abcdef1234567890abcdef12345678", // Address where funds need to be deposited to start the swap
  "depositChannelBrokerCommissionBps": 100,
  "depositChannelAffiliateBrokers": [
    { "account": "cFM8kRvLBXagj6ZXvrt7wCM4jGmHvb5842jTtXXg3mRHjrvKy", "commissionBps": 50 }
  ],
  "estimatedDepositChannelExpiryTime": 1630000000, // Estimated expiry time of the deposit channel
  "maxBoostFeeBps": 10 // Boost fee bps limit set upon channel creation. 0 by default
}

fillOrKillParams: Slippage Protection

The optional fillOrKillParams object sets a minimum accepted price for swaps triggered through the deposit channel. This allows to protect against price changes between a quote and the execution of a swap (also known as slippage protection). If the minimum price cannot be met with the available liquidity during the specified number of blocks, deposited assets will be refunded to the specified refund address.

A minimum accepted price is specified as the ratio between the human readable destination amount and the human readable source amount e.g. 3500 for a swap from ETH to USDC if you want to receive at least 3500 USDC per ETH. Prices are checked on the AMM level and do not include deposit or broadcast fees. To calculate a minPrice based on a quote, the estimatedPrice value is multiplied with the desired slippage tolerance. For example, quote.estimatedPrice * 99 / 100 specifies a 1% slippage tolerance relative to the quote.

Refunds are subject to a broadcast fee on the source chain to pay for the transactions sent by the Chainflip protocol. Any boost or deposit fee paid will not be refunded.

ParamDescriptionData type
minPrice(required)Minimum accepted price for swaps triggered through the deposit channel.string
refundAddress(required)Address on the source chain to which the refund will be sent, if the minimum price cannot be met.string
retryDurationBlocks(required)Number of State Chain blocks after which a deposit is refunded, if the minimum price cannot be met. One State Chain block corresponds to 6 seconds.number

Example

import { Chains, Assets } from "@chainflip/sdk/swap";
 
const quote = await swapSDK.getQuote({
  srcChain: Chains.Ethereum,
  destChain: Chains.Bitcoin,
  srcAsset: Assets.ETH,
  destAsset: Assets.BTC,
  amount: (1.5e18).toString(), // 1.5 ETH
});
 
const swapDepositAddressRequest = {
  srcChain: Chains.Ethereum,
  destChain: Chains.Bitcoin,
  srcAsset: Assets.ETH,
  destAsset: Assets.BTC,
  destAddress: "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
  amount: (1.5e18).toString(), // 1.5 ETH
  brokerCommissionBps: 100, // 100 basis point = 1%
  fillOrKillParams: {
    minPrice: (quote.estimatedPrice * 99 / 100).toString(), // minimum accepted price for swaps through the channel
    refundAddress: '0xa56A6be23b6Cf39D9448FF6e897C29c41c8fbDFF', // address to which assets are refunded
    retryDurationBlocks: 100, // 100 blocks * 6 seconds = 10 minutes before deposits are refunded
  },
};
console.log(await swapSDK.requestDepositAddress(swapDepositAddressRequest));

dcaParams

See DCA

The optional dcaParams object sets two parameters numberOfChunks and chunkIntervalBlocks that would split up a swap into smaller chunks and execute them consecutively with a delay. Doing so allows market makers to offer better pricing especially for larger swaps

numberOfChunks is the number of chunks to split the swap into and chunkIntervalBlocks is the number of state-chain blocks to wait before executing the next chunk. We recommend that integrators that wish to adopt DCA swaps set these values according to the response from the quoteV2.

dcaParams must also be set in conjunction with fillOrKillParams. This causes the minPrice to apply to each individual chunk in the overall swap. If a chunk fails to meet the minPrice, it will retry according to retryDurationBlocks until it does. If it does not meet it, the entire swap is retired. The swapped amount is egressed and anything that was not swapped is refunded back to the refundAddress

ParamDescriptionData type
numberOfChunks(required)The number of chunks to split the swap into.number
chunkInterval(required)Interval in state-chain blocks between each chunk. (minimum value: 2 blocks)number
import { Chains, Assets } from "@chainflip/sdk/swap";
 
const [quote, dcaQuote] = await swapSDK.getQuoteV2({
  srcChain: Chains.Ethereum,
  destChain: Chains.Bitcoin,
  srcAsset: Assets.ETH,
  destAsset: Assets.BTC,
  amount: (1.5e18).toString(), // 1.5 ETH
});
 
const swapDepositAddressRequest = {
  srcChain: Chains.Ethereum,
  destChain: Chains.Bitcoin,
  srcAsset: Assets.ETH,
  destAsset: Assets.BTC,
  destAddress: "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
  amount: (1.5e18).toString(), // 1.5 ETH
  brokerCommissionBps: 100, // 100 basis point = 1%
  // ❗ `fillOrKillParams` are required when requesting a DCA deposit channel ❗
  fillOrKillParams: {
    minPrice: (quote.estimatedPrice * 99 / 100).toString(), // minimum accepted price for swaps through the channel
    refundAddress: '0xa56A6be23b6Cf39D9448FF6e897C29c41c8fbDFF', // address to which assets are refunded
    retryDurationBlocks: 100, // 100 blocks * 6 seconds = 10 minutes before deposits are refunded
  },
  dcaParams: {
    numberOfChunks: dcaQuote.numberOfChunks,
    chunkIntervalBlocks: dcaQuote.chunkInterval,
  },
};
console.log(await swapSDK.requestDepositAddress(swapDepositAddressRequest));

ccmParams: Cross-Chain Messaging (CCM)

The optional ccmParams object enables executing a smart contract call on the destination chain and has the following properties:

ParamDescriptionData type
message(required)Message that is passed to the destination address on the destination chain. The message should be shorter than 10k bytes.string
gasBudget(required)Gas budget for the call on the destination chain. This amount is based on the source asset and will be subtracted from the input amount and swapped to pay for gas.number

Example

import { Chains, Assets } from "@chainflip/sdk/swap";
 
const callDepositAddressRequest = {
  srcChain: Chains.Bitcoin,
  destChain: Chains.Ethereum,
  srcAsset: Assets.BTC,
  destAsset: Assets.ETH,
  destAddress: "0x2f41dd5dEe1BcF767139b6bB6e27673aE90061b5",
  amount: (1e8).toString(), // 1 BTC
  ccmParams: {
    message: "0xdeadc0de",
    gasBudget: (0.001e8).toString(), // 0.001 BTC will be swapped for ETH to pay for gas
  },
};
console.log(await swapSDK.requestDepositAddress(callDepositAddressRequest));

The amount and gasBudget will always be in the base unit of the source asset, i.e. for ETH it will be Wei.

Sample Response

{
  "srcChain": "Bitcoin",
  "destChain": "Ethereum",
  "srcAsset": "BTC",
  "destAsset": "ETH",
  "destAddress": "0x2f41dd5dEe1BcF767139b6bB6e27673aE90061b5",
  "amount": "100000000", // 1 BTC
  "ccmParams": {
    "message": "0xdeadc0de",
    "gasBudget": "100000", // 0.001 BTC will be swapped for ETH to pay for gas
  },
  "depositChannelId": "1234567890", // Identifies the deposit channel for this swap
  "depositAddress": "tb1pylj9uhsmuz7h62spprv2z2vcnx2lw9epzt4amm3j45y75r6rrd8sdx0sjf", // Address where funds need to be deposited to start the swap
  "brokerCommissionBps": 0, // Commission charged by the broker for this swap
  "estimatedDepositChannelExpiryTime": 1630000000, // Estimated expiry time of the deposit channel
}

The resulting depositChannelId can be used in Get Status.

Use Your Own Broker

The previous two examples can also be performed with your own broker, instead of the broker that is provided by the Chainflip SDK:

import { SwapSDK } from '@chainflip/sdk/swap';
 
const sdk = new SDK({
  network: 'perseverance',
  broker: {
    url: 'https://my.broker.io',
    commissionBps: 15,
  },
});
 
const channel = await sdk.requestDepositAddress({
  srcAsset: 'ETH',
  srcChain: 'Ethereum',
  destAsset: 'FLIP',
  destChain: 'Ethereum',
  amount: '1000000000000000000', // 1 ETH
  destAddress: '0x1234567890abcdef1234567890abcdef12345678',
});
 
console.log(channel);
/*
  {
    srcAsset: 'ETH',
    srcChain: 'Ethereum',
    destAsset: 'FLIP',
    destChain: 'Ethereum',
    amount: '1000000000000000000',
    destAddress: '0x717e15853fd5f2ac6123e844c3a7c75976eaec9b',
    depositChannelId: '710643-Ethereum-615',
    depositAddress: '0x2d564a0754168cf49af604c82e84bd3a30599bf5',
    brokerCommissionBps: 15,
    estimatedDepositChannelExpiryTime: 1630000000,
  }
*/