> ## Documentation Index
> Fetch the complete documentation index at: https://pond.dflow.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Track Equity Balances

> How to read a user's equity token balances and scaled UI amounts

An equity token account holds the raw `amount`. The app shows the user that amount scaled by the mint's [ScaledUiAmount multiplier](https://pond.dflow.net/equities/orders.md#equity-response-fields).

**1. Set Up**

```typescript theme={null}
import "dotenv/config";

import { getMint, getScaledUiAmountConfig } from "@solana/spl-token";
import { Connection, PublicKey } from "@solana/web3.js";

const DFLOW_TRADE_API_URL = process.env.DFLOW_TRADE_API_URL ?? "https://dev-quote-api.dflow.net";
const DFLOW_API_KEY = process.env.DFLOW_API_KEY; // the key must be enabled for equities
const SOLANA_RPC_URL = process.env.SOLANA_RPC_URL ?? "https://api.mainnet-beta.solana.com";

const headers: HeadersInit = {};
if (DFLOW_API_KEY) headers["x-api-key"] = DFLOW_API_KEY;

const connection = new Connection(SOLANA_RPC_URL, "confirmed");

const userWalletAddress = "USER_WALLET_ADDRESS_HERE";
if (userWalletAddress === "USER_WALLET_ADDRESS_HERE") {
  throw new Error("Replace USER_WALLET_ADDRESS_HERE with a real Solana wallet address.");
}
const userWallet = new PublicKey(userWalletAddress);
```

**2. Fetch the Equity Mints**

```typescript theme={null}
type EquityMapping = { ticker: string; mint: string; provider: string };

const equitiesResponse = await fetch(`${DFLOW_TRADE_API_URL}/equities`, { headers });
if (!equitiesResponse.ok) {
  throw new Error(`GET /equities failed: ${equitiesResponse.status} ${await equitiesResponse.text()}`);
}
const equities: EquityMapping[] = await equitiesResponse.json();

const tickerByMint = new Map(equities.map((equity) => [equity.mint, equity.ticker]));
```

**3. Read Each Mint's Token Program**

```typescript theme={null}
const mintAddresses = equities.map((equity) => new PublicKey(equity.mint));
const tokenProgramByMint = new Map<string, PublicKey>();

for (let i = 0; i < mintAddresses.length; i += 100) { // getMultipleAccounts accepts at most 100 keys
  const batch = mintAddresses.slice(i, i + 100);
  const accounts = await connection.getMultipleAccountsInfo(batch);
  accounts.forEach((account, j) => {
    if (account) tokenProgramByMint.set(batch[j].toBase58(), account.owner);
  });
}

const tokenPrograms = new Map(
  [...tokenProgramByMint.values()].map((programId) => [programId.toBase58(), programId])
);
```

**4. Fetch the User's Equity Token Accounts**

With `jsonParsed` encoding, the RPC returns the raw `amount` and a `uiAmountString` that already applies the mint's current multiplier.

```typescript theme={null}
type EquityBalance = {
  ticker: string;
  mint: string;
  tokenProgram: PublicKey;
  amount: string;
  decimals: number;
  uiAmountString: string;
};

const balances: EquityBalance[] = [];

for (const tokenProgram of tokenPrograms.values()) {
  const { value } = await connection.getParsedTokenAccountsByOwner(userWallet, {
    programId: tokenProgram,
  });

  for (const { account } of value) {
    const info = account.data.parsed.info;
    const ticker = tickerByMint.get(info.mint);
    if (!ticker || info.tokenAmount.amount === "0") continue;

    balances.push({
      ticker,
      mint: info.mint,
      tokenProgram,
      amount: info.tokenAmount.amount,
      decimals: info.tokenAmount.decimals,
      uiAmountString: info.tokenAmount.uiAmountString,
    });
  }
}

console.table(balances.map(({ tokenProgram, ...balance }) => balance));
```

The app displays `uiAmountString` and passes the raw `amount` as the order endpoint's `amount` to sell a full balance.

**5. Compute the Scaled UI Amount from the Mint**

The token program uses `newMultiplier` from `newMultiplierEffectiveTimestamp` onward and `multiplier` before it, and truncates the scaled amount before dividing by `10^decimals`.

```typescript theme={null}
async function currentMultiplier(mint: string, tokenProgram: PublicKey) {
  const mintInfo = await getMint(connection, new PublicKey(mint), "confirmed", tokenProgram);
  const config = getScaledUiAmountConfig(mintInfo);
  if (!config) return { multiplier: 1, decimals: mintInfo.decimals };

  const now = Math.floor(Date.now() / 1000);
  const multiplier =
    now >= Number(config.newMultiplierEffectiveTimestamp)
      ? config.newMultiplier
      : config.multiplier;
  return { multiplier, decimals: mintInfo.decimals };
}

for (const balance of balances) {
  const { multiplier, decimals } = await currentMultiplier(balance.mint, balance.tokenProgram);
  const scaledUiAmount = Math.trunc(Number(balance.amount) * multiplier) / 10 ** decimals;

  console.log({
    ticker: balance.ticker,
    amount: balance.amount,
    multiplier,
    scaledUiAmount,
  });
}
```
