Add NanoStack adapter (volume + fees)#6231
Conversation
Cross-chain execution fabric tracking daily volume and fees across Base, Ethereum, Arbitrum, Optimism, and Solana. Fetches data from the NanoStack public API.
📝 WalkthroughWalkthroughAdded a new NanoStack adapter module that fetches volume, fees, and revenue statistics from the Nano Labs API for five blockchain chains (Base, Ethereum, Arbitrum, Optimism, Solana), configured with SimpleAdapter version 2 schema and shared metadata. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can scan for known vulnerabilities in your dependencies using OSV Scanner.OSV Scanner will automatically detect and report security vulnerabilities in your project's dependencies. No additional configuration is required. |
|
The nanostack adapter exports: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
dexs/nanostack/index.ts (1)
20-26: Add defensive checks for API response fields.The code directly accesses
data.dailyVolume,data.dailyFees, etc. without validating the response structure. If the API returns an error or unexpected format, this will silently returnundefinedvalues or throw.♻️ Proposed fix with validation
const fetch = async (options: FetchOptions) => { const data = await fetchURL( volumeEndpoint(options.startOfDay, options.startOfDay + 86400) ); + if (!data || typeof data !== 'object') { + throw new Error("Invalid response from NanoStack API"); + } + return { dailyVolume: data.dailyVolume, dailyFees: data.dailyFees, dailyUserFees: data.dailyUserFees, dailyRevenue: data.dailyRevenue, dailyProtocolRevenue: data.dailyProtocolRevenue, }; };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@dexs/nanostack/index.ts` around lines 20 - 26, The returned object directly uses data.dailyVolume, data.dailyFees, data.dailyUserFees, data.dailyRevenue, and data.dailyProtocolRevenue without validating the API response; update the code in index.ts to first assert that data exists and that each field (data.dailyVolume, data.dailyFees, data.dailyUserFees, data.dailyRevenue, data.dailyProtocolRevenue) is present and of the expected type (e.g., number or string), and if any field is missing or invalid either provide a safe default (0 or '0') or throw a descriptive error so callers don’t receive undefined values; ensure the validation occurs before constructing and returning the object.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@dexs/nanostack/index.ts`:
- Around line 15-27: The fetch function currently calls volumeEndpoint (via
fetchURL) which targets a non-existent /v1/stats/volume path; update the adapter
to stop using that endpoint: confirm whether NanoStack exposes historical
volume/fee data at another documented path (check /v1/quote, /v1/execute,
/v1/cross-chain or telemetry), and if not, replace volumeEndpoint usage in fetch
with a proper data source (either on-chain event parsing or a different API) and
adjust FetchOptions accordingly; also add robust response validation in fetch
(detect non-JSON/html responses and throw a clear error) and ensure the returned
shape (dailyVolume, dailyFees, dailyUserFees, dailyRevenue,
dailyProtocolRevenue) is populated only from a verified JSON response or from
your new data pipeline.
---
Nitpick comments:
In `@dexs/nanostack/index.ts`:
- Around line 20-26: The returned object directly uses data.dailyVolume,
data.dailyFees, data.dailyUserFees, data.dailyRevenue, and
data.dailyProtocolRevenue without validating the API response; update the code
in index.ts to first assert that data exists and that each field
(data.dailyVolume, data.dailyFees, data.dailyUserFees, data.dailyRevenue,
data.dailyProtocolRevenue) is present and of the expected type (e.g., number or
string), and if any field is missing or invalid either provide a safe default (0
or '0') or throw a descriptive error so callers don’t receive undefined values;
ensure the validation occurs before constructing and returning the object.
| const fetch = async (options: FetchOptions) => { | ||
| const data = await fetchURL( | ||
| volumeEndpoint(options.startOfDay, options.startOfDay + 86400) | ||
| ); | ||
|
|
||
| return { | ||
| dailyVolume: data.dailyVolume, | ||
| dailyFees: data.dailyFees, | ||
| dailyUserFees: data.dailyUserFees, | ||
| dailyRevenue: data.dailyRevenue, | ||
| dailyProtocolRevenue: data.dailyProtocolRevenue, | ||
| }; | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the API supports chain-specific queries or returns per-chain breakdown
# Using a sample date range
echo "=== Testing aggregate endpoint ==="
curl -s "https://api.nano-labs.io/v1/stats/volume?start=1735689600&end=1735776000" | head -c 2000
echo ""
echo "=== Checking if chain parameter is supported ==="
curl -s "https://api.nano-labs.io/v1/stats/volume?start=1735689600&end=1735776000&chain=base" | head -c 1000Repository: DefiLlama/dimension-adapters
Length of output: 3157
🏁 Script executed:
# Read the full nanostack index.ts file
cat -n dexs/nanostack/index.tsRepository: DefiLlama/dimension-adapters
Length of output: 1865
🏁 Script executed:
# Search for NanoStack-related files or documentation
find . -type f \( -name "*nanostack*" -o -name "*nano*" \) 2>/dev/null | head -20Repository: DefiLlama/dimension-adapters
Length of output: 54
🏁 Script executed:
# Look for similar DEX adapters to understand the pattern
find dexs -name "index.ts" -type f | head -5 | xargs wc -lRepository: DefiLlama/dimension-adapters
Length of output: 213
🏁 Script executed:
# Look at a few other DEX adapters to see how they handle multi-chain scenarios
head -50 dexs/10kswap/index.tsRepository: DefiLlama/dimension-adapters
Length of output: 982
🏁 Script executed:
# Search for other adapters with multiple chains in their configuration
rg "CHAIN\.(BASE|ETHEREUM|ARBITRUM)" dexs/ -A 2 -B 2 | head -80Repository: DefiLlama/dimension-adapters
Length of output: 4126
🏁 Script executed:
# Check if NanoStack is mentioned elsewhere in the repo
rg -i "nanostack\|nano-labs" . --type ts --type jsRepository: DefiLlama/dimension-adapters
Length of output: 54
🏁 Script executed:
# Look for adapters with aggregate/multi-chain patterns
rg "aggregate|all chains|shared" dexs/ --type ts -B 3 -A 3 | head -60Repository: DefiLlama/dimension-adapters
Length of output: 4228
🏁 Script executed:
# Check if there's any adapter documentation or pattern for multi-chain shared fetch
find . -name "*.md" -o -name "README*" | xargs grep -l "adapter\|multi-chain" 2>/dev/null | head -5Repository: DefiLlama/dimension-adapters
Length of output: 110
🏁 Script executed:
# Verify if NanoStack API endpoint pattern is documented anywhere
rg "api\.nano|nano-labs|v1/stats" . 2>/dev/nullRepository: DefiLlama/dimension-adapters
Length of output: 1698
🏁 Script executed:
# Look at swaps-io as it has "AGGREGATE" pattern - see how it handles multiple chains
cat -n dexs/swaps-io/index.ts | head -80Repository: DefiLlama/dimension-adapters
Length of output: 2976
🏁 Script executed:
# Check if there are adapters that use the same fetch function across multiple chains
rg "adapter:\s*{" dexs/ -A 20 | grep -A 15 "CHAIN\." | head -100Repository: DefiLlama/dimension-adapters
Length of output: 159
🏁 Script executed:
# Search for any comments or patterns about single endpoints serving multiple chains
rg "multi.*chain|cross.*chain|all.*chain" dexs/ -B 2 -A 2 | head -60Repository: DefiLlama/dimension-adapters
Length of output: 3875
🏁 Script executed:
# Look at how other adapters structure multiple chains with different endpoints
rg "endpoints.*Record.*CHAIN" dexs/ -A 15 | head -80Repository: DefiLlama/dimension-adapters
Length of output: 54
🏁 Script executed:
# Check if there's a PR or any test data for NanoStack
git log --oneline --all -- "dexs/nanostack" 2>/dev/null | head -10Repository: DefiLlama/dimension-adapters
Length of output: 113
🏁 Script executed:
# Verify the API endpoint one more time with a direct request
curl -s "https://api.nano-labs.io/v1/stats/volume?start=1735689600&end=1735776000" -I | head -20Repository: DefiLlama/dimension-adapters
Length of output: 946
🏁 Script executed:
# Try fetching the API with actual JSON data to see what the response structure is
curl -s "https://api.nano-labs.io/v1/stats/volume?start=1735689600&end=1735776000" | head -100Repository: DefiLlama/dimension-adapters
Length of output: 3499
🏁 Script executed:
# Check the OpenAPI documentation endpoint
curl -s "https://api.nano-labs.io/.well-known/openapi.json" 2>/dev/null | jq . 2>/dev/null | head -100Repository: DefiLlama/dimension-adapters
Length of output: 2554
🏁 Script executed:
# Try with a nanostack.json descriptor
curl -s "https://api.nano-labs.io/.well-known/nanostack.json" 2>/dev/null | jq . 2>/dev/null | head -100Repository: DefiLlama/dimension-adapters
Length of output: 1533
🏁 Script executed:
# Search the full OpenAPI spec for any stats or volume endpoints
curl -s "https://api.nano-labs.io/.well-known/openapi.json" 2>/dev/null | jq '.paths | keys' 2>/dev/nullRepository: DefiLlama/dimension-adapters
Length of output: 410
🏁 Script executed:
# Check the chains.json to see if there's chain-specific data structure
curl -s "https://api.nano-labs.io/.well-known/chains.json" 2>/dev/null | jq . 2>/dev/nullRepository: DefiLlama/dimension-adapters
Length of output: 330
🏁 Script executed:
# Check if there's a /metrics endpoint that might have stats
curl -s "https://api.nano-labs.io/metrics" 2>/dev/null | head -50Repository: DefiLlama/dimension-adapters
Length of output: 3505
🏁 Script executed:
# Check the full OpenAPI spec for any stats-related endpoints
curl -s "https://api.nano-labs.io/.well-known/openapi.json" 2>/dev/null | jq '.paths | to_entries[] | select(.key | contains("stat") or contains("volume") or contains("fee"))' 2>/dev/nullRepository: DefiLlama/dimension-adapters
Length of output: 54
Critical: API endpoint /v1/stats/volume does not exist in the NanoStack API.
The code attempts to fetch from https://api.nano-labs.io/v1/stats/volume?start={start}&end={end}, but this endpoint is not defined in the NanoStack API. The OpenAPI specification shows only these available paths: /health, /metrics, /v1/quote, /v1/execute, /v1/cross-chain, /v1/signal, /v1/bots/*, and /v1/telemetry/*. There is no /v1/stats/volume or any stats endpoint that returns volume/fee data.
The adapter will fail at runtime when trying to parse the response (the API returns an HTML dashboard page, not JSON).
Verify:
- If NanoStack exposes a public API for historical volume and fee data at a different endpoint
- If this adapter should use on-chain event parsing or a different data source instead
- Whether NanoStack is the correct protocol for volume tracking (it's primarily an execution fabric for cross-chain trades)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@dexs/nanostack/index.ts` around lines 15 - 27, The fetch function currently
calls volumeEndpoint (via fetchURL) which targets a non-existent
/v1/stats/volume path; update the adapter to stop using that endpoint: confirm
whether NanoStack exposes historical volume/fee data at another documented path
(check /v1/quote, /v1/execute, /v1/cross-chain or telemetry), and if not,
replace volumeEndpoint usage in fetch with a proper data source (either on-chain
event parsing or a different API) and adjust FetchOptions accordingly; also add
robust response validation in fetch (detect non-JSON/html responses and throw a
clear error) and ensure the returned shape (dailyVolume, dailyFees,
dailyUserFees, dailyRevenue, dailyProtocolRevenue) is populated only from a
verified JSON response or from your new data pipeline.
Hi! Submitting a volume/fees adapter for NanoStack — a cross-chain execution fabric operating across 86 chains. Happy to adjust the adapter based on your feedback.
What is NanoStack?
NanoStack is a cross-chain execution substrate that routes trades directly through on-chain liquidity pools. No external routing contracts — all execution is handled natively with 8-15 bps fees.
Adapter details
https://api.nano-labs.io/v1/stats/volumeLinks
Summary by CodeRabbit
New Features