Integration guide
In this integration guide, we are going to integrate the e2e flow for your users to select which vaults they want to deposit on, do a deposit transaction to start earning rewards and withdraw (part of) their positions.
1. Setup
First, let's make sure you have all the resources you need to start integrating the product.
Deployments
We have public deployments already made for testing purposes that you can use.
Network | Lending Protocol | Asset | Address |
---|---|---|---|
Arbitrum One | Compound v3 | USDbC | 0xC268C59fa29220208EfbeC31380e9f4DBE143621 |
Arbitrum One | Compound v3 | USDC | 0xCA8F5dbC4c90678763B291217e6ddDfcA00341d0 |
Arbitrum One | AAVE v3 | USDT | 0x0f11f7fbdb33347688441400186b210f1f4eebb9 |
Arbitrum One | AAVE v3 | USDC | 0xFf131917E1D6751e4d1B17612751Db521b1403c5 |
BNB | Venus | USDC | 0x6E90B52A5eAb4e4a08135dcf8c93ABdf6caE9C91 |
Polygon | AAVE v3 | USDC | 0x899b8cd1d209e4368c41dc9fd2de04a866b5d19a |
Polygon | Compound v3 | USDC.e | 0xd4c6dDA2158EFd3a41597d89349F06E17dFfbBFd |
Sepolia | AAVE v3 | USDC | 0xf3a9A790f84B2E0301069BE589fc976Cf3eB5661 |
Sepolia | Compound v3 | USDC | 0xf3a9A790f84B2E0301069BE589fc976Cf3eB5661 |
The protocol you want to test is not in this list?
Fill out this form to request custom deployments
These vaults SHOULD NOT be used in production
They are either testnet or staging deployments made for testing purposes only.
💡 Some L2 do not have a stable testnet for defi applications so staging deployments are done on mainnet but should never end up on your production setup.
Setup your API credentials
Connect to your kiln dashboard organization on testnet and get your api token.
Refer to this section of the documentation to get more infos on how to generate and manage your keys in your backend.
2. Backend
In this section, we are going to query the data required for "view" displays that we will use on the frontend later.
Vault registry
You should define a vault registry list on your side, which is a list of vault addresses you want to expose your users to per network. For security reasons you cannot fetch your vault addresses from Kiln api without knowing them in advance so you have to define this list on your application.
We recommend having a mapping
chainId <> vaultAddress[]
so you can always query the vaults per chain.
Get vault(s) information
API - GET /v1/defi/network-stats?vaults=
- Query using
?vaults
parameter to specify the vaults you want to query data of
- 💡 use the mapping you have to query the vault list on the network you want
Example:
{
"data": [
{
"asset": "0x94a9d9ac8a22534e3faca9f4e7f2e2cf85d5e4c8",
"asset_icon": "https://public.kiln.fi/icons/assets/usdc.svg",
"asset_symbol": "skUSDC",
"share_symbol": "skcUSDC",
"tvl": "1980000",
"protocol": "aave_v3",
"protocol_icon": "https://public.kiln.fi/icons/defi-protocols/aave.svg",
"protocol_tvl": "1980000",
"protocol_supply_limit": "1980000",
"grr": 0.028795338310400043,
"nrr": 0.028507384927296042,
"vault": "0x9aB5F9101a3C1B868e2c422E294cc2ee685551D5",
"chain": "eth",
"chain_id": 1,
"asset_decimals": 6,
"updated_at_block": 220379047
}
]
}
In this response you can see useful vault information:
- underlying protocol information: name, icon, tvl, supply limit (ie asset amount left to supply, if 0 nothing can be supplied)
- GRR (gross rewards rate) and NRR (net rewards rate) users can earn by depositing through this vault
- asset information: name, icon, symbol
- share symbol: what the user will receive in exchange for depositing assets
- when the data was last refreshed: updated_at_block
Get user positions
API - GET /v1/defi/stakes?wallets=&vaults=
- Query using
?vaults
parameter to specify the vaults you want to query stakes on
- 💡use the mapping you have to query the vault list on the network you want
- Query using
?wallets
parameter to get the user(s) stakes in the scope of the vault list you specify
Example:
{
"data": [
{
"owner": "0x356c33675674691ad6b8ac92ecfb91960c5d2c30",
"current_balance": "1880000",
"total_rewards": "0",
"total_deposited_amount": "1980000",
"total_withdrawn_amount": "100000",
"vault": "0x9aB5F9101a3C1B868e2c422E294cc2ee685551D5",
"chain": "eth",
"updated_at_block": 220379047
}
]
}
Here we can see:
- the current "staked" balance in assets
- user total rewards earned, in assets
- user total rewards deposited and withdrawn amounts, in assets
- the vault the stake in made on
- when the data was last refreshed
(Optional) Get user history
API - GET /v1/defi/operations?wallets=&vaults=
- Query using
?vaults
parameter to specify the vaults you want to query stakes on- 💡use the mapping you have to query the vault list on the network you want
- Query using
?wallets
parameter to get the user(s) stakes in the scope of the vault list you specify
Example:
{
"data": [
{
"type": "withdrawal",
"owner": "0x356c33675674691ad6b8ac92ecfb91960c5d2c30",
"assets": "100000",
"shares": "100000",
"sender": "0x356c33675674691ad6b8ac92ecfb91960c5d2c30",
"timestamp": "1710434028",
"tx_hash": "0xca1e9f9a9ed7b632dbb71e9d22730d1541df010e915d65af91d1ca102600c965",
"vault": "0x9aB5F9101a3C1B868e2c422E294cc2ee685551D5",
"chain": "eth"
}
]
}
Here we can see:
- the type of the operation: withdrawal or deposit
- the amount of assets and shares involved in the operation
- the vault it is made on
- the owner of the stake, the transaction sender
- the vault the operation is made on
3. Frontend
Now that we have setup the backend data query, we can start the integration within the UI. There are 4 main flows to integrate:
- [VIEW] As a User, I can see the vaults and their information available on the chain I am connected on, so I can assess which DeFi protocol I want to be exposed to
- [TX] As a User, I can deposit on the vault, so I can start earning
- [VIEW] As a User, I see my positions and rewards, so that I can assess my performance
- [TX] As a User, I can withdraw from vaults, so I can get back my assets
1 - [VIEW] As a User, I can see the vaults and their information available on the chain I am connected on, so I can assess which DeFi protocol I want to be exposed to
Use the queried data in the "Get vault(s) information" section.
Some recommendations:
- Use the protocol and asset icons to give a more visual experience
- Sort by descending NRR, or have a "sort by APY" button
- Display if the user already deposited in a vault (using the "Get user positions")
- Do no display vaults where
protocol_supply_limit
is < 5000 assets to avoid the user being not able to deposit.
2 - [TX] As a User, I can deposit on the vault, so I can start earning
Show a preview of the tx to the user
You can compute the amount of shares the user will receive and using the "Get vault(s) information" data show the name of the shares. As they are not pegged 1:1 with the deposited assets, it can be useful to help the user understand what he is doing.
You can preview this amount by doing a view call on the vault and calling
previewDeposit(uint256 assets)
where assets is the amount of ERC20 to deposit in assets expressed in the lowest unit of the token (ie asset_amount * 10**decimal).If this call reverts, it can mean that the underlying protocol is not accepting supply funds at the moment, you can then display a "Deposits on this protocol are unavailable at the moment, retry later".
Before depositing X assets, you must make sure the user approved the vault to spend X on its behalf on the asset contract.
To check the allowance, call the allowance(address owner, address spender)(uint256)
function on the ERC20 asset contract, if there is not enough allowance, you must make the user perform an approve:
TX - function: approve(address spender, uint256 amount)
- to: asset contract address
- from: user wallet address
- value: 0
- parameters:
- spender: vault address
- amount: amount the user inputed in asset wei (ie amount * decimals)
ONLY MAKE THE USER APPROVE THE AMOUNT IT WANTS TO DEPOSIT TO THE VAULT
Now that there is enough allowance, we can make the user deposit to the vault.
TX - function: deposit(uint256 assets, address receiver)
- to: vault address
- from: user wallet address
- value: 0
- parameters:
- assets: amount the user inputed in asset expressed in the lowest unit of the token (ie asset_amount * 10**decimal).
- receiver: user wallet address (or another if you want to let the user input a receiver wallet)
Now the user successfully deposited, received vault shares and can now receive supply rewards as frequently as the protocol distributes them!
3 - [VIEW] As a User, I see my positions and rewards, so that I can assess my performance
Use the data collected in the "Get user positions" section of this guide.
Recommendations:
- display amounts in assets and in fiat value
4 - [TX] As a User, I can withdraw my position from vaults, so I can get back my assets
Case 1: exit part of a position
Show a preview of the tx to the user
You can compute the amount of assets the user will receive after withdrawing.
You can preview this amount by doing a view call on the vault calling
previewWithdraw(uint256 assets)
where assets is the amount of ERC20 to deposit in assets expressed in the lowest unit of the token (ie asset_amount * 10**decimal).If this call reverts, it can mean that the underlying protocol is not accepting withdraw of supply funds at the moment, you can then display a "Withdrawals on this protocol are unavailable at the moment, retry later".
TX - function: withdraw(uint256 assets, address receiver, address owner)
- to: vault address
- from: user wallet address
- value: 0
- parameters:
- assets: amount the user inputed in asset expressed in the lowest unit of the token (ie asset_amount * 10**decimal).
- receiver: user wallet address (or another if you want to let the user input a receiver wallet)
- owner: user wallet address
Case 2: exit 100% of the positions
This case is made to avoid leaving dust on the contract, as there is time between the user input and the actual moment the transaction is executed, shares rate might have changed.
Show a preview of the tx to the user
You can compute the amount of assets the user will receive after withdrawing.
You can preview this amount by doing a view call on the vault calling
previewRedeem(uint256 assets)
where assets is the amount of ERC20 to deposit in assets expressed in the lowest unit of the token (ie asset_amount * 10**decimal).If this call reverts, it can mean that the underlying protocol is not accepting withdraw of supply funds at the moment, you can then display a "Withdrawals on this protocol are unavailable at the moment, retry later".
TX - function: redeem(uint256 shares, address receiver, address owner)
- to: vault address
- from: user wallet address
- value: 0
- parameters:
- shares: amount in shares, you MUST get this value by calling
balanceOf(address owner)
on the vault before-end whereowner
is the user wallet address.- receiver: user wallet address (or another if you want to let the user input a receiver wallet)
- owner: user wallet address
🚀 We now completed the full E2E flow of Kiln DeFi on your application 🚀
4. Testing
Now let's validate that the implementation works properly. We recommend creating a test suite from this list and running it frequently, and especially during each release.
- As a User, I should be able to see all available vaults on the chain I am connected on
- As a User, I should see an info message / be redirected if there are no deployments on the chain I'm connected on
- As a User, I should be able to see each vault NRR, its asset, and the protocol it relies on
- As a User, I should be able to select a vault to deposit on based on the asset on my wallet
- As a User, I should be able to see the amount of shares and the name I will receive when inputing a number of asset to deposit
- As a User with no allowance on the asset to the vault, I should sign an approve transaction with the amount to deposit as amount
- on explorer, transaction must be valid with the specs above (from, to, value, param values etc)
- As a User with enough allowance on the asset to the vault, I should not be asked to sign an approval transaction
- As a User, I should be able to
deposit
my assets on the vault.- on explorer, transaction must be valid with the specs above (from, to, value, param values etc)
- As a User, I should be able to see my positions in all of your vaults with the amount in assets and fiat value and my rewards amount
- As a User, I should be able to select a vault to withdraw on based on my positions
- As a User, I should be able to preview the withdrawal of my positions, by seeing the asset I will receive on my wallet, when inputing the value to withdraw
- As a User who wants to withdraw part of its positions, I should be able to sign a
withdraw
transaction- on explorer, transaction must be valid with the specs above (from, to, value, param values etc)
- As a User who wants to withdraw 100% of its positions, I should be able to sign a
redeem
transaction- on explorer, transaction must be valid with the specs above (from, to, value, param values etc)
Updated 5 months ago