This library is designed to simplify and standardize the process of fetching and interacting with data from various DeFi protocols, which often have unique interfaces and data structures. Our adapters fetch and transform underlying protocol data into a standardized format that can be easily used by portfolio dashboards.
- Connect users with DeFi protocols
- Benefit the wider ecosystem
- Simplify and standardize adapter building
- Provide the following data in a standardized format:
- DeFi positions by address, including the balance of underlying tokens such as USDC, WETH, etc.
- Total Value Locked (TVL) by pool
- APY/APR by pool
- Daily profit and loss by address
- Price of LP token
- Deposits by address
- Withdrawals by address
Check out the tutorial video below for an intro to our library and how to build an adapter:
This project requires Node 18. Ensure you're using the correct version (e.g. run nvm use
)
To build an adapter follow these steps:
- Install the necessary packages with
npm i
- Build the project with
npm run build:watch
- To build an adapter run:
npm run new-adapter
- To create a typescript-smart-contract class create a json file with your abi and add it to your ${protocolName}/contracts/abis/ folder, then run:
npm run build-types
- To build metadata files run:
npm run build-metadata
- To build snapshot tests run:
npm run build-snapshots
- To run tests run:
npm run test
- To test your adapter further you can use the following commands, update userAddress and other params accordingly:
npm run positions 0x6b8Be925ED8277fE4D27820aE4677e76Ebf4c255 -- --protocols stargate --chains 1,arbitrum
npm run profits 0xB0D502E938ed5f4df2E681fE6E419ff29631d62b
npm run tvl
npm run prices
npm run apr
npm run apy
npm run deposits 0x30cb2c51fc4f031fa5f326d334e1f5da00e19ab5 18262162 18262164 0xC36442b4a4522E871399CD717aBDD847Ab11FE88 pool uniswap-v3 1 573046
npm run withdrawals 0x4Ffc5F22770ab6046c8D66DABAe3A9CD1E7A03e7 17979753 17979755 0xdf0770df86a8034b3efef0a1bb3c889b8332ff56 pool stargate 1
Detailed documentation on the adapter methods can be found here.
The DeFi adapter library is the engine behind MetaMask's retail and institutional portfolio dashboards 🦊.
In this example, the user holds positions in both Stargate and Uniswap.
As a adapter developer,
I want to implement a new DeFi adapter that follows the IProtocolAdapter interface,
So that MMI and MetaMask Portfolio users can view in-depth data related to their positions.
- Multiple Products Consideration: Ensure that protocols with multiple products (e.g., farming, staking, pools) are supported by one adapter each.
- Adapter Implementation: Successfully add a new DeFi adapter implementing the IProtocolAdapter to support the product.
- Add Adapter using CLI:
- Follow instructions in the "Adding a new Adapter (CLI)" section of the readme.
- Ethers Contracts Creation:
- Create ethers contracts to interact with the smart contracts of the protocol.
- Refer to the "Contract Factories" section in the readme for guidance.
- LP Token Metadata Building: Implement the
buildMetadata()
logic in the adapter to retrieve the LP token reference data and runnpm run build-metadata
. (e.g., Check out thebuildMetadata()
method in theStargatePoolAdapter
class. output example).- Testing: Test the adapter(s) using the commands specified in the readme.
The IProtocolAdapter interface has been documented with TSDocs, detailed descriptions of the methods and properties can be found here.
-
What is a DeFi adapter?
A DeFi adapter is code that standardizes DeFi protocol data and positions, allowing for consistent data retrieval and interaction. It acts as a connector (a.k.a translator) between our dashboards and your DeFi products.
-
What do these adapters do?
They power the MetaMask portfolio dashboards, displaying users' DeFi positions.
-
What experience do I need to map an adapter?
Ideally experience in Typescript, Ethers library, and be familiar with the DeFi protocol.
-
Are these adapters deployed onchain?
No this adapter library is installed and deployed in microservices. The adapters are written in TypeScript (not solidity).
-
I'm not familiar with the protocol. Can I still map an adapter?
Yes. To assist you refer to the protocol docs, smart contracts, find example open positions and review deposits and withdrawals to the position.
-
How long does it take to map an adapter?
A few hours for those with knowledge of Typescript, Ethers, and the DeFi protocol.
-
What is the getProfits method?
It returns profit on individual open positions by considering weekly changes and transactions in and out of the position.
-
How do you calculate profits?
- We capture users' positions from 7 days ago using the
get positions
adapter method with ablocknumber override
. - We then obtain the current positions.
- To account for deposits and withdrawals in this period, we examine
mint
andburn
events of LP tokens and convert these back to underlying tokens. - We found this method works for the majority of protocols. However, adapt as necessary for your protocol. For example, if there are better event logs available for your protocol, use them.
- We capture users' positions from 7 days ago using the
-
Some adapter methods don't make sense for my DeFi-protocol?
Throw an error: new Error('Does not apply').
-
Can I use an API for results?
We recommend getting data directly from the blockchain over centralized APIs.
-
My protocol only has a few pools, can I hardcode the buildMetadata() result?
Yes. Feel free to hardcode this result if it doesn't make sense to fetch pool data on chain.
-
My protocol has more than one product, should I create separate adapters?
Yes. We find this reduces complexity.
-
Im getting
>> TypeError: Cannot read properties of undefined (reading 'F_OK')
error when runningnpm run new-adapter
Make sure you are using Node 18. Run nvm use
-
How can I share feedback or proposals?
Please reach out to us directly. We value feedback.
From left to right, get-onchain-data and convert to standardize format.
See CONTRIBUTING.md.
- Node v18
To get specific details on available commands, run npm run adapters-cli
. For arguments and options for specific commands, use npm run positions -- --help
.
This project requires Node 18. Ensure you're using the correct version (e.g. run nvm use
)
Run the following command to add a new adapter npm run new-adapter
This will start an interactive process in the command line to create a new adapter. Running npm run new-adapter -- --help
shows available options for defaults.
Add a JSON file with the ABI of any new contract to the folder src/adapter/<protocol-name>/contracts/abis
. Run npm run build-types
to generate factories and ABIs for those contracts automatically.
In order to maintain integrity, it is possible to create test snapshots.
Tests can be added to src/adapters/<protocol-name>/tests/testCases.ts
by adding them to the exported testCases
array. The test object is fully typed.
A test needs to include:
chainId
: Chain for which the test will runmethod
: One of the available public methods of the libraryinput
: If the testmethod
requires input, such as an user address, it needs to be specified here.blockNumber
: For some tests, it is possible to specify which block number should be used. If it's not provided, the snapshot will be created with the latest block number, which will be stored along with the snapshot.key
: When there are multiple tests for the samechainId
andmethod
, but with different inputs (e.g. testing multiple user addresses), a key is necessary for the system to identify them.
Once the tests are DeFined, running npm run build-snapshots -- -p <protocol-name>
will generate snapshots for them.
Running npm run test
validates snapshots match results.
To version and publish:
- Create a pull request with your changes.
- Apply one of the labels:
major
,minor
,patch
,premajor
,preminor
,prepatch
, orprerelease
to the pull request. This label will determine how the package version is bumped. - Once your pull request is approved, merge it into
main
. - The GitHub Action workflow will automatically bump the package version based on the label, push the new version and associated tag, and then publish the package.
Please note: You no longer need to manually bump the package version or push tags.
To update all averages, run npm run adapters-cli block-average
. To update a specific chain, run npm run adapters-cli block-average -- --chain 1
.
Johann |
Bernardo |
JP |