Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions projects/meteora-dammv2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Meteora DAMM v2 Adapter

This adapter tracks TVL for Meteora's Dynamic Automated Market Maker v2 (DAMM v2) on Solana.

## Files

### index.js (Production)
- **Method**: Uses Meteora's global metrics API endpoint
- **Endpoint**: `https://dammv2-api.meteora.ag/pools/global-metrics`
- **Performance**: Fast, single API call
- **Use Case**: Standard protocol-level TVL tracking

### index-detailed.js (Alternative - Launchpad Filtering)
- **Method**: Fetches all pools via paginated API and sums vault balances
- **Endpoint**: `https://dammv2-api.meteora.ag/pools` (paginated)
- **Performance**: Slower (132k+ pools across 1,322 pages)
- **Use Case**: When filtering by specific launchpads (Believe, Bags, etc.)
- **Features**:
- Can filter pools by creator address
- Provides granular pool-level data
- Skips empty/closed pools automatically

## Usage

### Standard TVL (Current Implementation)
```javascript
// Uses global metrics API - fast and efficient
const tvl = await tvl() // Returns ~$77M USD
```

### Launchpad-Specific TVL (Future Use)
```javascript
// Switch to index-detailed.js and configure FILTER_CREATORS
// Example: Only track Bags launchpad pools
const FILTER_CREATORS = ['1gy7kCxHxX13zLdu4bgwFqsdwdeAWMnLFVLJvwpAXuh']
```

## API Reference
- [DAMM v2 API Docs](https://docs.meteora.ag/api-reference/damm-v2/overview)
- [Protocol Metrics](https://docs.meteora.ag/api-reference/protocol-metrics/get_protocol_metrics)
- Program ID: `cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG`
59 changes: 59 additions & 0 deletions projects/meteora-dammv2/idl.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"version": "1.0.0",
"name": "cp_amm",
"constants": [],
"instructions": [],
"accounts": [
{
"name": "pool",
"type": {
"kind": "struct",
"fields": [
{
"name": "creator",
"docs": ["Pool creator"],
"type": "publicKey"
},
{
"name": "config",
"docs": ["Pool configuration"],
"type": "publicKey"
},
{
"name": "tokenAMint",
"docs": ["Token A mint"],
"type": "publicKey"
},
{
"name": "tokenBMint",
"docs": ["Token B mint"],
"type": "publicKey"
},
{
"name": "tokenAVault",
"docs": ["Token A vault"],
"type": "publicKey"
},
{
"name": "tokenBVault",
"docs": ["Token B vault"],
"type": "publicKey"
},
{
"name": "sqrtPrice",
"docs": ["Square root price"],
"type": "u128"
},
{
"name": "liquidity",
"docs": ["Total liquidity"],
"type": "u128"
}
]
}
}
],
"types": [],
"events": [],
"errors": []
}
60 changes: 60 additions & 0 deletions projects/meteora-dammv2/index-detailed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// ALTERNATIVE IMPLEMENTATION: Detailed pool-by-pool TVL calculation
// This file is NOT used in production. Use index.js for standard TVL tracking.
//
// Use this implementation when you need to:
// - Filter TVL by specific launchpad creators (Believe, Bags, etc.)
// - Get granular pool-level data
// - Calculate TVL for a subset of pools
//
// Note: This approach is slower as it paginates through 132k+ pools.
// The standard implementation (index.js) uses the global metrics API instead.

const { sumTokens2 } = require('../helper/solana')
const { get } = require('../helper/http')
const { getEnv } = require('../helper/env')

const METEORA_API = 'https://dammv2-api.meteora.ag'
const SYSTEM_PROGRAM = '11111111111111111111111111111111'

// https://docs.meteora.ag/api-reference/damm-v2/overview
async function tvl() {
if (!getEnv('IS_RUN_FROM_CUSTOM_JOB')) throw new Error('This job is not meant to be run directly, please use the custom job feature')
const allVaults = []
let page = 1
let hasMore = true
const pageSize = 100 // Max page size to reduce API calls

// Fetch all pools from Meteora API with pagination
while (hasMore) {
const response = await get(`${METEORA_API}/pools?page=${page}&limit=${pageSize}`)

const pools = response.data || []

for (const pool of pools) {
const { token_a_vault, token_b_vault, token_a_amount, token_b_amount } = pool

// Skip pools with no tokens (empty/closed pools)
if (token_a_amount === 0 && token_b_amount === 0) continue

// Skip system program addresses (uninitialized/closed pools)
if (token_a_vault && token_a_vault !== SYSTEM_PROGRAM) {
allVaults.push(token_a_vault)
}
if (token_b_vault && token_b_vault !== SYSTEM_PROGRAM) {
allVaults.push(token_b_vault)
}
}

// Check if there are more pages
hasMore = page < response.pages
page++
}

return sumTokens2({ tokenAccounts: allVaults })
}

module.exports = {
timetravel: false,
isHeavyProtocol: true,
solana: { tvl, },
}
19 changes: 19 additions & 0 deletions projects/meteora-dammv2/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const { get } = require('../helper/http')

const METEORA_API = 'https://dammv2-api.meteora.ag'

// https://docs.meteora.ag/api-reference/damm-v2/overview
async function tvl() {
const { data } = await get(`${METEORA_API}/pools/global-metrics`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use on chain data to export token balances rather than an off chain USD value


// Return TVL as object with USD value
return {
tether: data.tvl24h, // Using tvl24h which represents current TVL
}
}

module.exports = {
timetravel: false,
methodology: 'TVL is calculated using the Meteora DAMM v2 API global metrics endpoint',
solana: { tvl, },
}
Loading