This repo offers a self service approach to Ethena Points Campaign integrations.
For your protocol to be included and your users to receive points, you should submit a PR to this repo. Here some guidelines to follow:
- Make a copy of
.env.example
and name it.env
. - Run
pip install -r requirements.txt
to install the required packages.- If using TypeScript scripts (recommended for L2 delegated integrations), also run
pnpm install
ornpm install
in the root directory.
- If using TypeScript scripts (recommended for L2 delegated integrations), also run
- Add your integration metadata to
integrations/integration_ids.py
. - Create a new summary column in
constants/summary_columns.py
. - Choose your integration type:
- For EVM compatible chains: Copy CachedBalancesTemplate
- For non-EVM chains (e.g. Solana): Copy L2DelegationTemplate
- We strongly recommend using a TypeScript script or similar to fetch balances for better reliability and maintainability
- See KaminoL2DelegationExampleIntegration for the recommended TypeScript approach
- Create your TypeScript script in the
ts/
directory - Use the Kamino example as a reference for calling your script from Python
- Create your TypeScript script in the
- API integration is also supported but less preferred (see RatexL2DelegationExampleIntegration)
- Name your file
[protocol name]_integration.py
and place it in theintegrations
directory. - Your integration must inherit from either:
CachedBalancesIntegration
and implement theget_block_balances
methodL2DelegationIntegration
and implement theget_l2_block_balances
andget_participants_data
methods
- The integration should return user balances:
- For CachedBalances: Return a dict of {block_number: {checksum_address: balance}}
- For L2Delegation: Return a dict of {block_number: {address: balance}}
- Write some basic tests at the bottom of the file to ensure your integration is working correctly.
- Submit a PR to this repo with your integration and ping the Ethena team in Telegram.
- Integrations must follow this architecture and be written in python.
- The
get_block_balances
method should be as efficient as possible. So the use of the cached data from previous blocks if possible is highly encouraged. - We prefer that on chain RPC calls are used to get information as much as possible due to reliability and trustlessness. Off chain calls to apis or subgraphs are acceptable if necessary. If usage is not reasonable or the external service is not reliable, users may not receive their points.
For non-EVM chain integrations (like Solana) or users that don't control the same addresses in the L2 and Ethereum, your users must complete an additional delegation step to receive points. This process links their L2 wallet to their Ethereum address:
- Visit the Ethena UI and connect your Ethereum wallet
- Navigate to Ethena Delegation Section
- Click "Select Chain" and select.
- Click "Signing With" and select your wallet type.
- Connect your wallet and sign a message to prove ownership
- Once delegated, your L2 balances will be attributed to your Ethereum address for points calculation
Important Notes:
- Users can delegate at any moment and they won't miss any past points.
- ClaimedEnaIntegration: This integration demonstrates how to track ENA token claims using cached balance snapshots for improved performance. It reads from previous balance snapshots to efficiently track user claim history.
- BeefyCachedBalanceExampleIntegration: This integration is an example of a cached balance integration that is based on API calls.
-
KaminoL2DelegationExampleIntegration
- Example of L2 delegation for Solana chain
- Uses TypeScript script to query Kamino balances
- Demonstrates cross-chain integration pattern
-
RatexL2DelegationExampleIntegration
- Example of L2 delegation using API calls
- Shows how to integrate external API data sources
- Demonstrates proper API response handling
- PendleLPTIntegration: (Legacy Example) A basic integration showing Pendle LPT staking tracking. Note: This is a non-cached implementation included only for reference - new integrations should use the cached approach for better efficiency.
- PendleYTIntegration: (Legacy Example) A basic integration showing Pendle YT staking tracking. Note: This is a non-cached implementation included only for reference - new integrations should use the cached approach for better efficiency.