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

# Read DEX Activity

`swig.dex` reads what Swig's index recorded about a Swig your API key's
organization owns: its DEX transaction history and the latest state of its
liquidity positions. The lists are API-key `POST`s that carry their filters in
the body, and `get` is an API-key `GET`. All of them only read and follow the
client's retry policy, so they are safe to repeat. Each call counts as one API
query against your organization's monthly allowance, and so does each retried
attempt. The network may also come from the client.

TypeScript `0.12.0` and Python `0.11.0` add these reads.

## List DEX transactions

```typescript TypeScript theme={null}
const page = await swig.dex.transactions.list({
  swigConfigAddress,
  network: 'mainnet',
  pageSize: 25,
  startSlot: 357_000_000,
  endSlot: 358_000_000,
  protocol: 'raydium-clmm',
  actionType: 'swap',
  swigVaultAddress,
});

for (const transaction of page.transactions) {
  for (const { action, protocol } of transaction.actions) {
    if (action.type === 'swap') {
      console.log(protocol, action.input.amountRaw, action.output.amountRaw);
    }
  }
}
```

```python Python theme={null}
page = await swig.dex.transactions.list(
    swig_config_address=swig_config_address,
    network="mainnet",
    page_size=25,
    start_slot=357_000_000,
    end_slot=358_000_000,
    protocol="raydium-clmm",
    action_type="swap",
    swig_vault_address=swig_vault_address,
)

for transaction in page.transactions:
    for executed in transaction.actions:
        if executed.action.type == "swap":
            print(
                executed.protocol,
                executed.action.input.amount_raw,
                executed.action.output.amount_raw,
            )
```

Transactions come newest first. Every filter is optional:

| TypeScript | Python | Selects |
| :- | :- | :- |
| `startSlot`, `endSlot` | `start_slot`, `end_slot` | transactions in an inclusive slot range |
| `protocol` | `protocol` | transactions with an action on that protocol |
| `actionType` | `action_type` | transactions with an action of that type |
| `swigVaultAddress` | `swig_vault_address` | transactions with an action from that vault or sub-account |

Filters combine with AND. The action filters must all match the same action. A
matching transaction still carries every DEX action the Swig executed in it.
The backend answers `400` when `startSlot` / `start_slot` is after `endSlot` /
`end_slot`.

Protocols are `pump-swap`, `meteora-dlmm`, `raydium-amm-v4`, `raydium-cpmm`,
`raydium-clmm`, and `orca-whirlpool`. Action types are `swap`,
`position-open`, `liquidity-add`, `liquidity-remove`, `position-rebalance`,
`fee-claim`, `reward-claim`, and `position-close`. An unknown value is refused
before any request is sent.

## Page through results

Pass `nextCursor` / `next_cursor` back as `cursor` with the same network and
filters. The cursor is the page's last row: `{ slot, transactionSignature }`
for transactions and `{ protocol, dexPositionAddress }` for positions
(`DexTransactionCursor` and `DexPositionCursor` in both SDKs). It is absent
(`undefined` / `None`) on the last page. The backend does not tie a cursor to
the filters it came from, so keep them the same yourself. `pageSize` /
`page_size` defaults to 25, and the backend caps it at 100. Each page is one
API query, so a larger page reads a long history in fewer requests.

```typescript TypeScript theme={null}
import type { DexTransactionCursor } from '@swig-wallet/developer-sdk';

let cursor: DexTransactionCursor | undefined;
do {
  const page = await swig.dex.transactions.list({
    swigConfigAddress,
    network: 'mainnet',
    actionType: 'swap',
    cursor,
  });
  // handle page.transactions
  cursor = page.nextCursor;
} while (cursor);
```

```python Python theme={null}
from swig_developer_sdk import DexTransactionCursor

cursor: DexTransactionCursor | None = None
while True:
    page = await swig.dex.transactions.list(
        swig_config_address=swig_config_address,
        network="mainnet",
        action_type="swap",
        cursor=cursor,
    )
    # handle page.transactions
    cursor = page.next_cursor
    if cursor is None:
        break
```

## Read one transaction

```typescript TypeScript theme={null}
const transaction = await swig.dex.transactions.get({
  swigConfigAddress,
  network: 'mainnet',
  transactionSignature,
});
```

```python Python theme={null}
transaction = await swig.dex.transactions.get(
    swig_config_address=swig_config_address,
    network="mainnet",
    transaction_signature=transaction_signature,
)
```

The result has the same shape as a list item.

## What a transaction carries

| Field | Meaning |
| :- | :- |
| `transactionSignature` / `transaction_signature` | the Solana transaction |
| `slot` | its slot |
| `blockTime` / `block_time` | RFC 3339 block time, when known |
| `actions` | every DEX action the Swig executed, in execution order |
| `actionIndex` / `action_index` | the action's place in that order |
| `swigVaultAddress` / `swig_vault_address` | the vault or sub-account that signed for it |
| `actingRoleId` / `acting_role_id` | the Swig role that authorized it |
| `protocol`, `dexProgramAddress` / `dex_program_address` | where it executed |
| `action` | the typed action, discriminated by `type` |

Each action carries `protocolInstruction` / `protocol_instruction` and
`protocolActorAddress` / `protocol_actor_address`. Swaps add the pool and an
`input` and `output` amount. Position actions add the pool and position, plus
`deposits`, `withdrawals`, or `claimed` amounts. A position close carries the
pool only when the instruction names one.

### Read the amounts as the venue saw them

* `amountRaw` / `amount_raw` is a signed decimal string for the action's
  `protocolActorAddress`: a negative amount left its accounts. Keep it a string,
  or parse it into an arbitrary-precision integer.
* That actor is the Swig vault on a direct call. When an aggregator such as
  Jupiter routed the trade, it is the router's account, and the swap appears as
  one action per venue hop. For the wallet's own inflows and outflows, use
  [token activity](https://build.onswig.com/developer-sdk/wallet-reads.md#token-activity).
* Only transactions the index interpreted are listed. One it could not
  interpret, or has not processed yet, is omitted, and `get` answers `404`
  for it.

## List latest positions

```typescript TypeScript theme={null}
const { positions } = await swig.dex.positions.list({
  swigConfigAddress,
  network: 'mainnet',
  positionStatus: 'open',
});

for (const position of positions) {
  if (position.status === 'open') {
    console.log(
      position.dexPositionAddress,
      position.dexPoolAddress,
      position.state.liquidityRaw,
    );
  }
}
```

```python Python theme={null}
from swig_developer_sdk import DexOpenPosition

result = await swig.dex.positions.list(
    swig_config_address=swig_config_address,
    network="mainnet",
    position_status="open",
)

for position in result.positions:
    if isinstance(position, DexOpenPosition):
        print(
            position.dex_position_address,
            position.dex_pool_address,
            position.state.liquidity_raw,
        )
```

A position is the latest known on-chain state of a position held by the Swig's
vault or any of its sub-accounts, enabled or not. An open position carries its
pool and decoded account state; a closed position means the account no longer
exists.
`updatedSlot` / `updated_slot` is the slot of the read the state came from.
Latest state is currently recorded for Raydium CLMM positions only.

Positions take `positionStatus` / `position_status` (`open` or `closed`),
`protocol`, and `swigVaultAddress` / `swig_vault_address` filters, each applied
to the position, and page the same way as transactions.

## Underlying routes

| Read | Route |
| :- | :- |
| Transaction history | `POST /wallet/api/swig/{swig_config_address}/dex/transactions` |
| One transaction | `GET /wallet/api/swig/{swig_config_address}/dex/transactions/{transaction_signature}` |
| Latest positions | `POST /wallet/api/swig/{swig_config_address}/dex/positions` |

See the [DEX API](https://build.onswig.com/developer-api/dex.md) for the exact parameters and response
shapes. These are API-key routes and must be called from a trusted server. If
your product shows the data elsewhere, return an authorized view through your
own application API.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.