Skip to content
Back to skills

Gdex Portfolio

ASecurity

Cross-chain portfolio overview, chain-specific token balances, and paginated trade history

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 3, 2026
ai-agentstypescriptapibackend

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 3, 2026

npx -y skills add GemachDAO/gdex-skill --skill gdex-portfolio --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gdex Portfolio?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gdex Portfolio
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gemachdao-gdex-portfolio/badge)](https://www.skillsdirectory.com/skills/gemachdao-gdex-portfolio)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: gdex-portfolio
description: Cross-chain portfolio overview, chain-specific token balances, and paginated trade history
---

# GDEX: Portfolio & Balances

Query cross-chain portfolio summaries, chain-specific balances, and trade history.

## When to Use

- Getting a user's total portfolio value across all chains
- Checking token balances on a specific chain
- Retrieving trade history with pagination and filters

## Prerequisites

- `@gemachdao/gdex-skill` installed
- Authenticated via `loginWithApiKey()` — see **gdex-authentication**

## Cross-Chain Portfolio

> **WARNING (Live-Tested):** The high-level `getPortfolio()` and `getBalances()` methods send `walletAddress` + `chain` to the backend, but the backend expects `userId` + `chainId` + `data` (encrypted session key). **These methods return empty or incorrect results.** Use the raw client workaround below.

### Correct Way — Raw Client (Live-Tested, Works)

```typescript
import { GdexSkill, GDEX_API_KEY_PRIMARY, buildGdexUserSessionData } from '@gemachdao/gdex-skill';

const skill = new GdexSkill();
skill.loginWithApiKey(GDEX_API_KEY_PRIMARY);

// Build encrypted session data
const data = buildGdexUserSessionData(sessionKey, GDEX_API_KEY_PRIMARY);

// Portfolio — use raw client with correct params
const portfolio = await skill.client.get('/v1/portfolio', {
  params: {
    userId: controlAddress,   // control wallet, NOT managed
    chainId: 622112261,       // numeric Solana chain ID
    data,                     // encrypted session key
  }
});
```

### Incorrect Way — High-Level Methods (SDK Bug)

```typescript
// ❌ These send wrong params to backend — DO NOT USE for managed custody
const portfolio = await skill.getPortfolio({ walletAddress: '0x...', chain: 'solana' });
const balances = await skill.getBalances({ walletAddress: '0x...', chain: 8453 });
```

### Portfolio Response

```typescript
interface Portfolio {
  totalValueUsd: number;
  balances: Balance[];
  perpPositions?: PerpPosition[];
  realizedPnl?: number;
  unrealizedPnl?: number;
  totalPnl?: number;
}

interface Balance {
  tokenAddress: string;
  symbol: string;
  name: string;
  decimals: number;
  rawBalance: string;
  balance: string;        // human-readable
  usdValue: number;
  priceUsd: number;
  change24h?: number;
  chain: string | number;
}
```

## Chain-Specific Balances

> **WARNING (Live-Tested):** Same issue as portfolio — use raw client. On
> backend v1.1.0 balances are embedded in the portfolio response under
> `portfolio.balances[]` (there is no separate `/v1/balances` endpoint).

```typescript
const portfolio = await skill.client.get('/v1/portfolio', {
  params: {
    userId: controlAddress,
    chainId: 622112261,       // numeric chain ID
    data,                     // encrypted session key
  }
});
const balances = portfolio.balances ?? [];
```

### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `walletAddress` | `string` | Yes | Wallet address to query |
| `chain` | `string \| ChainId` | Yes | Chain to query balances on |
| `tokenAddress` | `string` | No | Filter to a specific token |

## Trade History

> **WARNING (Live-Tested):** The backend expects param `user` (NOT `userId`), and managed Solana chainId for trade history is `900` (NOT `622112261`). Use the raw client:

```typescript
const history = await skill.client.get('/v1/user_history', {
  params: {
    user: controlAddress,     // NOTE: "user", not "userId"
    chainId: 900,             // NOTE: 900 for Solana trade history, not 622112261
    data,                     // encrypted session key
    page: 1,
    limit: 20,
  }
});
```

> The high-level `getTradeHistory()` sends wrong param names. Use raw client above.

### Trade Record

```typescript
interface TradeRecord {
  id: string;
  type: string;        // 'buy' | 'sell'
  inputToken: string;
  outputToken: string;
  amountIn: string;
  amountOut: string;
  usdValue?: number;
  chain: string | number;
  dex?: string;
  txHash: string;
  timestamp: number;
  status: string;
}
```

## Example: Portfolio Dashboard (Autonomous Agent — Live-Tested)

```typescript
import { GdexSkill, GDEX_API_KEY_PRIMARY, buildGdexUserSessionData } from '@gemachdao/gdex-skill';

const skill = new GdexSkill();
skill.loginWithApiKey(GDEX_API_KEY_PRIMARY);

// Build encrypted session data (required for all portfolio/balance/history queries)
const data = buildGdexUserSessionData(sessionKey, GDEX_API_KEY_PRIMARY);
const userId = controlAddress; // control wallet, NOT managed

// 1. Get portfolio (raw client — high-level method has wrong params)
const portfolio = await skill.client.get('/v1/portfolio', {
  params: { userId, chainId: 622112261, data }
});

// 2. Get balances (embedded in portfolio.balances[] on backend v1.1.0)
const balances = portfolio.balances ?? [];

// 3. Get trade history (use "user" param, chainId 900 for Solana)
const history = await skill.client.get('/v1/user_history', {
  params: { user: userId, chainId: 900, data, page: 1, limit: 20 }
});
```

## Autonomous Agent Notes

1. **Always use raw client** for portfolio, balances, and trade history. The high-level SDK methods send incorrect parameter names.
2. **Portfolio/balances chainId**: Use `622112261` for Solana, standard EVM chain IDs for others.
3. **Trade history chainId**: Use `900` for Solana (not `622112261`). This is a backend quirk.
4. **Trade history param**: Use `user` (not `userId`) — backend expects different param name for this endpoint.
5. **Data param**: Always pass the encrypted session key from `buildGdexUserSessionData()`.
6. **userId**: Always use the **control** wallet address, never the managed address.

## Related Skills

- **gdex-authentication** — Auth setup required for portfolio queries
- **gdex-spot-trading** — Execute trades based on portfolio analysis
- **gdex-perp-trading** — View perp positions in portfolio
- **gdex-token-discovery** — Research tokens found in portfolio

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.