# Directory Structure
```
├── .env.example
├── .gitignore
├── deno.json
├── deno.lock
├── Dockerfile
├── main_test.ts
├── main.ts
├── README.md
└── tool
├── toolHandler.ts
└── toolInfo.ts
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
.env
```
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
```
ACCESS_KEY=xxx
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
# DeBanK MCP Server
A stateless Model Context Protocol (MCP) server for interacting with the DeBanK API to retrieve blockchain and DeFi data.
## Overview
This project implements a Model Context Protocol (MCP) server that provides various tools for querying blockchain data, including chains, protocols, tokens, pools, and user assets. Built with the [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/mcp), it leverages the HTTP Streamable transport to provide a modern, efficient API interface.
The server is designed to be completely stateless, with each request being handled independently, making it highly scalable and robust for production environments.
## Features
- **Stateless Architecture**: Each request creates a new server instance and transport
- **Comprehensive DeFi Data Tools**: Access to chains, protocols, tokens, pools, and user data
- **Pagination Support**: All list-returning endpoints support pagination
- **Error Handling**: Robust error handling and reporting
## Tools Available
| Tool Name | Description |
|-----------|-------------|
| `get_chain_info` | Get information about blockchains |
| `get_protocol_info` | Get information about DeFi protocols |
| `get_token_info` | Get information about tokens |
| `get_pool_info` | Get detailed information about a specific liquidity pool |
| `get_user_assets` | Get information about a user's assets across different blockchains |
| `get_user_activities` | Get information about a user's protocol positions, transaction history, and balance charts |
| `get_user_authorizations` | Get information about a user's token and NFT authorizations |
| `get_collection_nft_list` | Get a list of NFTs in a specific collection |
| `wallet_tools` | Access wallet-related functionality |
## Prerequisites
- [Deno](https://deno.land/) 1.35 or later
- DeBanK API Access Key - [Get one here](https://pro.debank.com/)
## Installation
1. Clone the repository
```bash
git clone https://github.com/yourusername/debank-mcp-server.git
cd debank-mcp-server
```
2. Set up your environment variables
```bash
export ACCESS_KEY=your_debank_api_key
```
## Running the Server
Start the server with the following command:
```bash
deno run --allow-net --allow-env main.ts
```
The server will start and listen on port 8080 by default. You can now send MCP requests to `http://localhost:8080/mcp`.
## MCP HTTP Streamable Implementation
This project uses the StreamableHTTPServerTransport from the Model Context Protocol SDK to handle MCP requests. Every request creates a new server instance and transport, making the service completely stateless:
```typescript
// Create new server instance and transport for each request
const server = createServer();
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
});
// Connect to server
await server.connect(transport);
// Handle request
await transport.handleRequest(req, res, req.body);
```
This approach simplifies deployment and scaling, as there's no need to manage session state across multiple instances.
## Project Structure
```
├── main.ts # Main server file with MCP endpoint handling
├── deno.json # Deno configuration
├── deno.lock # Dependency lock file
├── tool/
│ ├── toolInfo.ts # Tool definitions
│ └── toolHandler.ts # Tool handler implementations
└── README.md # This file
```
## Configuration
The following environment variables can be configured:
- `ACCESS_KEY` - Your DeBanK API access key
- `PORT` - (Optional) Port to run the server on (default: 8080)
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## Acknowledgments
- [Model Context Protocol](https://github.com/modelcontextprotocol/mcp)
- [DeBanK API](https://pro.debank.com/)
```
--------------------------------------------------------------------------------
/main_test.ts:
--------------------------------------------------------------------------------
```typescript
import { assertEquals } from "@std/assert";
import { add } from "./main.ts";
Deno.test(function addTest() {
assertEquals(add(2, 3), 5);
});
```
--------------------------------------------------------------------------------
/deno.json:
--------------------------------------------------------------------------------
```json
{
"tasks": {
"dev": "deno run --watch main.ts",
"start": "deno run main.ts"
},
"imports": {
"@modelcontextprotocol/sdk": "npm:@modelcontextprotocol/sdk@^1.10.2",
"@std/assert": "jsr:@std/assert@1"
}
}
```
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM denoland/deno:1.41.3
# Set working directory
WORKDIR /app
# Copy dependency configuration files
COPY deno.json deno.lock ./
# Copy source code
COPY . .
# Cache dependencies
RUN deno cache main.ts
# Expose port (port 8080 is used in main.ts)
EXPOSE 8080
# Configure health check
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
CMD deno eval "try { await fetch('http://localhost:8080/mcp'); Deno.exit(0); } catch { Deno.exit(1); }"
# Run application
CMD ["deno", "run", "--allow-net", "--allow-env", "--allow-read", "main.ts"]
```
--------------------------------------------------------------------------------
/main.ts:
--------------------------------------------------------------------------------
```typescript
// debank.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import express, { Request, Response, NextFunction } from "npm:express";
import { randomUUID } from "node:crypto";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk";
import toolsList from "./tool/toolInfo.ts";
import { toolToHandler } from "./tool/toolHandler.ts";
// Server configuration
const APP_NAME = "debank";
const APP_VERSION = "1.0.0";
const PORT = 8080;
// Create MCP server
function createServer() {
const server = new Server(
{
name: APP_NAME,
version: APP_VERSION,
},
{
capabilities: {
tools: {},
},
}
);
server.setRequestHandler(ListToolsRequestSchema, () => {
console.log("Handling listTools request");
return {
tools: toolsList,
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
console.log(`Handling callTool request for tool: ${request.params.name}`);
try {
const requestToolName = request.params.name;
const isMcptool = toolsList.some(
(tool) => tool.name === requestToolName,
);
if (isMcptool) {
const tool = toolsList.find((tool) => tool.name === requestToolName);
if (!tool) {
console.log(`Tool ${requestToolName} not found`);
return { error: `Tool ${requestToolName} not found` };
}
const handler = toolToHandler[requestToolName];
if (!handler) {
console.log(`Handler for ${requestToolName} not found`);
return { error: `Handler for ${requestToolName} not found` };
}
console.log(`Calling handler for ${requestToolName}`);
const result = await handler(request.params.arguments as any);
return {
content: [
{
type: "text",
text: JSON.stringify(result),
},
],
};
}
console.log(`Tool ${requestToolName} not found in toolsList`);
return {
content: [
{
type: "text",
text: "Tool not found",
},
],
};
} catch (error) {
console.error(`Error calling tool: ${error}`);
return {
content: [
{
type: "text",
text: `Tool ${request.params.name} failed: ${error}`,
},
],
};
}
});
return server;
}
// Start server
const startServer = async () => {
const app = express();
app.use(express.json());
// Logging middleware
app.use((req: Request, res: Response, next: NextFunction) => {
console.log(`${req.method} ${req.url}`);
console.log('Headers:', JSON.stringify(req.headers));
if (req.body) {
console.log('Body:', JSON.stringify(req.body));
}
next();
});
// Single endpoint to handle all MCP requests - stateless mode
app.all('/mcp', async (req: Request, res: Response) => {
console.log(`Received ${req.method} request to /mcp`);
try {
// Create new server instance and transport for each request
const server = createServer();
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
});
// Connect to server
await server.connect(transport);
// Handle request
await transport.handleRequest(req, res, req.body);
} catch (error) {
console.error('Error handling MCP request:', error);
if (!res.headersSent) {
res.status(500).json({
jsonrpc: '2.0',
error: {
code: -32603,
message: 'Internal server error',
},
id: null,
});
}
}
});
const server = app.listen(PORT, () => {
console.log(`DeBanK MCP Server listening on port ${PORT}`);
});
// Handle server shutdown
process.on('SIGINT', () => {
console.log('Shutting down server...');
server.close(() => {
console.log('Server shutdown complete');
process.exit(0);
});
});
};
// Start server
startServer();
```
--------------------------------------------------------------------------------
/tool/toolInfo.ts:
--------------------------------------------------------------------------------
```typescript
export const getChainInfo = {
name: "get_chain_info",
description: "Get information about blockchains via GET requests to /v1/chain or /v1/chain/list. " +
"Can retrieve details about a specific chain or list all supported chains.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "Optional chain identifier (e.g. eth, bsc, xdai)" },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: []
}
}
export const getProtocolInfo = {
name: "get_protocol_info",
description: "Get information about DeFi protocols via GET requests to various protocol endpoints. " +
"Can retrieve details about a specific protocol, list protocols on a chain, or fetch top holders.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "Protocol identifier (e.g. curve, uniswap)" },
chain_id: { type: "string", description: "Chain identifier (e.g. eth, bsc)" },
get_top_holders: { type: "boolean", description: "Set to True to fetch the top holders of a protocol", default: false },
start: { type: "number", description: "Integer offset for pagination" },
limit: { type: "number", description: "Number of results to return", default: 10 },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: []
}
}
export const getTokenInfo = {
name: "get_token_info",
description: "Get information about tokens via GET requests to various token endpoints. " +
"Can retrieve token details, top holders, or historical prices.",
inputSchema: {
type: "object",
properties: {
chain_id: { type: "string", description: "Chain identifier (e.g. eth, bsc, xdai)" },
id: { type: "string", description: "Token identifier - either a contract address or a native token id" },
action: { type: "string", description: "Type of information to retrieve", default: "details" },
date_at: { type: "string", description: "UTC timezone date in YYYY-MM-DD format" },
start: { type: "number", description: "Integer offset for pagination", default: 0 },
limit: { type: "number", description: "Number of holders to return", default: 100 },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: ["chain_id", "id"]
}
}
export const getPoolInfo = {
name: "get_pool_info",
description: "Get detailed information about a specific liquidity pool via a GET request to /v1/pool. " +
"Returns detailed statistics about the pool including its deposits, user counts, and associated protocol.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "Pool identifier" },
chain_id: { type: "string", description: "Chain identifier (e.g. eth, bsc, xdai)" }
},
required: ["id", "chain_id"]
}
}
export const getUserAssets = {
name: "get_user_assets",
description: "Get information about a user's assets across different blockchains. " +
"Can retrieve basic balance, token lists, NFTs, and more with optional chain filtering.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "User wallet address" },
asset_type: { type: "string", description: "Type of asset information to retrieve", default: "balance" },
chain_id: { type: "string", description: "Chain identifier for single-chain queries" },
token_id: { type: "string", description: "Token identifier for specific token balance query" },
chain_ids: { type: "string", description: "Optional comma-separated list of chain IDs" },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: ["id"]
}
}
export const getUserActivities = {
name: "get_user_activities",
description: "Get information about a user's protocol positions, transaction history, and balance charts. " +
"Supports filtering by chain and protocol.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "User wallet address" },
activity_type: { type: "string", description: "Type of activity information to retrieve" },
chain_id: { type: "string", description: "Chain identifier for single-chain queries" },
protocol_id: { type: "string", description: "Protocol identifier for specific protocol query" },
chain_ids: { type: "string", description: "Optional comma-separated list of chain IDs" },
page_count: { type: "number", description: "Optional number of pages to return for history queries" },
start_time: { type: "number", description: "Optional Unix timestamp to start from for history queries" },
is_simple: { type: "boolean", description: "Whether to use simple or complex protocol list", default: true },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: ["id", "activity_type"]
}
}
export const getUserAuthorizations = {
name: "get_user_authorizations",
description: "Get information about a user's token and NFT authorizations on a specific blockchain.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "User wallet address" },
chain_id: { type: "string", description: "Chain identifier (e.g. eth, bsc, xdai)" },
auth_type: { type: "string", description: "Type of authorization to retrieve", default: "token" },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: ["id", "chain_id"]
}
}
export const getCollectionNftList = {
name: "get_collection_nft_list",
description: "Get a list of NFTs in a specific collection using a GET request to /v1/collection/nft_list. " +
"Returns an array of NFT objects with details like name, description, content, and attributes.",
inputSchema: {
type: "object",
properties: {
id: { type: "string", description: "NFT contract address" },
chain_id: { type: "string", description: "Chain identifier (e.g. eth, bsc, xdai)" },
start: { type: "number", description: "Integer offset for pagination", default: 0 },
limit: { type: "number", description: "Number of NFTs to return", default: 20 },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: ["id", "chain_id"]
}
}
export const walletTools = {
name: "wallet_tools",
description: "Access wallet-related functionality: get gas prices, analyze transactions, or simulate transactions.",
inputSchema: {
type: "object",
properties: {
action: { type: "string", description: "Type of wallet action to perform" },
chain_id: { type: "string", description: "Chain identifier (e.g. eth, bsc, xdai)" },
tx: { type: "object", description: "Transaction object" },
pending_tx_list: { type: "array", description: "Optional list of transactions to execute before the main transaction" },
page: { type: "number", description: "Page number, starting from 1", default: 1 },
page_size: { type: "number", description: "Number of records per page", default: 5 }
},
required: ["action"]
}
}
export default [
getChainInfo,
getProtocolInfo,
getTokenInfo,
getPoolInfo,
getUserAssets,
getUserActivities,
getUserAuthorizations,
getCollectionNftList,
walletTools
]
```
--------------------------------------------------------------------------------
/tool/toolHandler.ts:
--------------------------------------------------------------------------------
```typescript
import { getChainInfo, getCollectionNftList, getPoolInfo, getProtocolInfo, getTokenInfo, getUserActivities, getUserAssets, getUserAuthorizations, walletTools } from "./toolInfo.ts";
// DeBanK API configuration
const ACCESS_KEY = Deno.env.get("ACCESS_KEY");
const BASE_URL = "https://pro-openapi.debank.com";
// Pagination function types
interface PaginationInfo {
page: number;
page_size: number;
total_items: number;
total_pages: number;
}
interface PaginatedResult<T> {
data: T[];
pagination: PaginationInfo;
}
// Pagination function
function paginateResults<T>(results: T[] | null | undefined, page = 1, page_size = 5): PaginatedResult<T> | null | undefined {
if (results === null || results === undefined || !Array.isArray(results)) {
return results as any;
}
const start_idx = (page - 1) * page_size;
const end_idx = start_idx + page_size;
const total_items = results.length;
const total_pages = Math.ceil(total_items / page_size);
const paginated_results = results.slice(start_idx, end_idx);
const pagination_info: PaginationInfo = {
page,
page_size,
total_items,
total_pages
};
return {
data: paginated_results,
pagination: pagination_info
};
}
// Network request function
async function makeNwsRequest(url: string): Promise<any> {
const headers = {
"Accept": "application/json",
"AccessKey": ACCESS_KEY || ""
};
try {
const response = await fetch(url, {
method: "GET",
headers
});
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Request error:", error);
return null;
}
}
// POST request function
async function makePostRequest(url: string, data: any): Promise<any> {
const headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"AccessKey": ACCESS_KEY || ""
};
try {
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("POST request error:", error);
return null;
}
}
export const getChainInfoHandler = async ({ id, page = 1, page_size = 5 }: { id?: string, page?: number, page_size?: number }) => {
if (id) {
return await makeNwsRequest(`${BASE_URL}/v1/chain?id=${id}`);
} else {
const results = await makeNwsRequest(`${BASE_URL}/v1/chain/list`);
return paginateResults(results, page, page_size);
}
}
export const getProtocolInfoHandler = async ({ id, chain_id, get_top_holders = false, start, limit = 10, page = 1, page_size = 5 }: { id?: string, chain_id?: string, get_top_holders?: boolean, start?: number, limit?: number, page?: number, page_size?: number }) => {
if (id && get_top_holders) {
// Get top holders of a protocol
let url = `${BASE_URL}/v1/protocol/top_holders?id=${id}`;
if (start !== undefined) {
url += `&start=${start}`;
}
if (limit !== undefined) {
url += `&limit=${limit}`;
}
const results = await makeNwsRequest(url);
return paginateResults(results, page, page_size);
} else if (id) {
// Get specific protocol info
return await makeNwsRequest(`${BASE_URL}/v1/protocol?id=${id}`);
} else if (chain_id) {
// Get protocols on a chain
const protocols = await makeNwsRequest(`${BASE_URL}/v1/protocol/list?chain_id=${chain_id}`);
if (protocols) {
// Sort protocols by TVL in descending order
const sorted_protocols = [...protocols].sort((a, b) =>
(b.tvl || 0) - (a.tvl || 0)
);
return paginateResults(sorted_protocols, page, page_size);
}
return null;
} else {
return { error: "Either id or chain_id must be provided" };
}
}
export const getTokenInfoHandler = async ({ chain_id, id, action = "details", date_at, start = 0, limit = 100, page = 1, page_size = 5 }: { chain_id: string, id: string, action?: string, date_at?: string, start?: number, limit?: number, page?: number, page_size?: number }) => {
if (action === "details") {
return await makeNwsRequest(`${BASE_URL}/v1/token?chain_id=${chain_id}&id=${id}`);
} else if (action === "holders") {
const url = `${BASE_URL}/v1/token/top_holders?chain_id=${chain_id}&id=${id}&start=${start}&limit=${limit}`;
const results = await makeNwsRequest(url);
return paginateResults(results, page, page_size);
} else if (action === "history") {
if (!date_at) {
return { error: "date_at parameter is required for historical price" };
}
return await makeNwsRequest(`${BASE_URL}/v1/token/history_price?chain_id=${chain_id}&id=${id}&date_at=${date_at}`);
} else {
return { error: "Invalid action parameter. Use 'details', 'holders', or 'history'." };
}
}
export const getPoolInfoHandler = async ({ id, chain_id }: { id: string, chain_id: string }) => {
return await makeNwsRequest(`${BASE_URL}/v1/pool?id=${id}&chain_id=${chain_id}`);
}
export const getUserAssetsHandler = async ({ id, asset_type = "balance", chain_id, token_id, chain_ids, page = 1, page_size = 5 }: { id: string, asset_type?: string, chain_id?: string, token_id?: string, chain_ids?: string, page?: number, page_size?: number }) => {
if (asset_type === "balance") {
if (chain_id) {
return await makeNwsRequest(`${BASE_URL}/v1/user/chain_balance?id=${id}&chain_id=${chain_id}`);
} else {
let url = `${BASE_URL}/v1/user/total_balance?id=${id}`;
if (chain_ids) {
url += `&chain_ids=${chain_ids}`;
}
return await makeNwsRequest(url);
}
} else if (asset_type === "chains") {
const results = await makeNwsRequest(`${BASE_URL}/v1/user/used_chain_list?id=${id}`);
return paginateResults(results, page, page_size);
} else if (asset_type === "tokens") {
let results;
if (chain_id) {
results = await makeNwsRequest(`${BASE_URL}/v1/user/token_list?id=${id}&chain_id=${chain_id}`);
} else {
let url = `${BASE_URL}/v1/user/all_token_list?id=${id}`;
if (chain_ids) {
url += `&chain_ids=${chain_ids}`;
}
results = await makeNwsRequest(url);
}
return paginateResults(results, page, page_size);
} else if (asset_type === "token") {
if (!chain_id || !token_id) {
return { error: "chain_id and token_id are required for token balance query" };
}
return await makeNwsRequest(`${BASE_URL}/v1/user/token_balance?id=${id}&chain_id=${chain_id}&token_id=${token_id}`);
} else if (asset_type === "nfts") {
let results;
if (chain_id) {
results = await makeNwsRequest(`${BASE_URL}/v1/user/nft_list?id=${id}&chain_id=${chain_id}`);
} else {
let url = `${BASE_URL}/v1/user/all_nft_list?id=${id}`;
if (chain_ids) {
url += `&chain_ids=${chain_ids}`;
}
results = await makeNwsRequest(url);
}
return paginateResults(results, page, page_size);
} else {
return { error: "Invalid asset_type parameter" };
}
}
export const getUserActivitiesHandler = async ({ id, activity_type, chain_id, protocol_id, chain_ids, page_count, start_time, is_simple = true, page = 1, page_size = 5 }: { id: string, activity_type: string, chain_id?: string, protocol_id?: string, chain_ids?: string, page_count?: number, start_time?: number, is_simple?: boolean, page?: number, page_size?: number }) => {
if (activity_type === "protocols") {
if (protocol_id) {
// Get specific protocol info
return await makeNwsRequest(`${BASE_URL}/v1/user/protocol?id=${id}&protocol_id=${protocol_id}`);
} else if (chain_id) {
// Get protocol list for a specific chain
let results;
if (is_simple) {
results = await makeNwsRequest(`${BASE_URL}/v1/user/simple_protocol_list?id=${id}&chain_id=${chain_id}`);
} else {
results = await makeNwsRequest(`${BASE_URL}/v1/user/complex_protocol_list?id=${id}&chain_id=${chain_id}`);
}
return paginateResults(results, page, page_size);
} else {
// Get protocol list for all chains
const url_base = `${BASE_URL}/v1/user/all_${is_simple ? "simple" : "complex"}_protocol_list`;
let url = `${url_base}?id=${id}`;
if (chain_ids) {
url += `&chain_ids=${chain_ids}`;
}
const results = await makeNwsRequest(url);
return paginateResults(results, page, page_size);
}
} else if (activity_type === "history") {
let url;
if (chain_id) {
// Get history for a specific chain
url = `${BASE_URL}/v1/user/history_list?id=${id}&chain_id=${chain_id}`;
} else {
// Get history for all chains
url = `${BASE_URL}/v1/user/history?id=${id}`;
if (chain_ids) {
url += `&chain_ids=${chain_ids}`;
}
}
if (page_count !== undefined) {
url += `&page_count=${page_count}`;
}
if (start_time !== undefined) {
url += `&start_time=${start_time}`;
}
const results = await makeNwsRequest(url);
return paginateResults(results, page, page_size);
} else if (activity_type === "chart") {
let results;
if (chain_id) {
// Get chart for a specific chain
results = await makeNwsRequest(`${BASE_URL}/v1/user/chain_net_curve?id=${id}&chain_id=${chain_id}`);
} else {
// Get chart for all chains
let url = `${BASE_URL}/v1/user/total_net_curve?id=${id}`;
if (chain_ids) {
url += `&chain_ids=${chain_ids}`;
}
results = await makeNwsRequest(url);
}
return paginateResults(results, page, page_size);
} else {
return { error: "Invalid activity_type parameter" };
}
}
export const getUserAuthorizationsHandler = async ({ id, chain_id, auth_type = "token", page = 1, page_size = 5 }: { id: string, chain_id: string, auth_type?: string, page?: number, page_size?: number }) => {
if (auth_type === "token") {
const results = await makeNwsRequest(`${BASE_URL}/v1/user/token_auth_list?id=${id}&chain_id=${chain_id}`);
return paginateResults(results, page, page_size);
} else if (auth_type === "nft") {
const results = await makeNwsRequest(`${BASE_URL}/v1/user/nft_auth_list?id=${id}&chain_id=${chain_id}`);
return paginateResults(results, page, page_size);
} else {
return { error: "Invalid auth_type parameter. Use 'token' or 'nft'." };
}
}
export const getCollectionNftListHandler = async ({ id, chain_id, start = 0, limit = 20, page = 1, page_size = 5 }: { id: string, chain_id: string, start?: number, limit?: number, page?: number, page_size?: number }) => {
const url = `${BASE_URL}/v1/collection/nft_list?id=${id}&chain_id=${chain_id}&start=${start}&limit=${limit}`;
const results = await makeNwsRequest(url);
return paginateResults(results, page, page_size);
}
export const walletToolsHandler = async ({ action, chain_id, tx, pending_tx_list, page = 1, page_size = 5 }: { action: string, chain_id?: string, tx?: any, pending_tx_list?: any[], page?: number, page_size?: number }) => {
if (action === "gas") {
if (!chain_id) {
return { error: "chain_id parameter is required for gas price query" };
}
const results = await makeNwsRequest(`${BASE_URL}/v1/wallet/gas_market?chain_id=${chain_id}`);
return paginateResults(results, page, page_size);
} else if (action === "explain_tx") {
if (!tx) {
return { error: "tx parameter is required for transaction explanation" };
}
const data = { tx };
return await makePostRequest(`${BASE_URL}/v1/wallet/explain_tx`, data);
} else if (action === "simulate_tx") {
if (!tx) {
return { error: "tx parameter is required for transaction simulation" };
}
const data: any = { tx };
if (pending_tx_list) {
data.pending_tx_list = pending_tx_list;
}
return await makePostRequest(`${BASE_URL}/v1/wallet/pre_exec_tx`, data);
} else {
return { error: "Invalid action parameter. Use 'gas', 'explain_tx', or 'simulate_tx'." };
}
}
export const toolToHandler = {
[getChainInfo.name]: getChainInfoHandler,
[getProtocolInfo.name]: getProtocolInfoHandler,
[getTokenInfo.name]: getTokenInfoHandler,
[getPoolInfo.name]: getPoolInfoHandler,
[getUserAssets.name]: getUserAssetsHandler,
[getUserActivities.name]: getUserActivitiesHandler,
[getUserAuthorizations.name]: getUserAuthorizationsHandler,
[getCollectionNftList.name]: getCollectionNftListHandler,
[walletTools.name]: walletToolsHandler
}
```