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

# 追踪 Solana 钱包和代币转账

> 查询钱包的 SOL 和 SPL 转账历史，支持筛选和历史美元价值；再通过 Datastream 按钱包或代币实时订阅新转账。

用一次 REST 调用加载钱包的转账历史，再加入转账房间，实时接收新转账。两者都覆盖原生 SOL、SPL 代币和 Token-2022 代币。

> [card] [查询转账历史](#query-transfer-history)
>
> 按代币、交易对手、时间、数量或美元价值筛选。

> [card] [实时订阅转账](#stream-transfers-live)
>
> 追踪一个钱包、一个代币，或某个钱包的某个代币。

## 查询转账历史

`GET /account/{address}/transfers` 返回钱包的转入和转出记录，按从新到旧排序。SPL 转账通过钱包拥有的代币账户匹配，每一方都同时给出代币账户（`address`）和拥有该账户的钱包（`owner`）。

默认情况下，历史记录不包含有 DEX 活动的交易，例如兑换、添加和移除流动性以及领取池手续费，因此你得到的是钱包的普通转账。设置 `dex=include` 可保留这些交易，设置 `dex=only` 则只返回这些交易。

```bash 收到的 USDC theme={null}
curl --get "https://data.solanatracker.io/account/GachaNgyXTU3zFogQ8Z5jR2BLXs8215X2AtEH18VxJq3/transfers" \
  --header "x-api-key: YOUR_API_KEY" \
  --data-urlencode "mint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" \
  --data-urlencode "direction=in" \
  --data-urlencode "historicPrices=true" \
  --data-urlencode "limit=50"
```

```javascript 分页加载历史 theme={null}
const address = "GachaNgyXTU3zFogQ8Z5jR2BLXs8215X2AtEH18VxJq3";
let cursor;

do {
  const url = new URL(`https://data.solanatracker.io/account/${address}/transfers`);
  url.search = new URLSearchParams({ limit: "100", historicPrices: "true", ...(cursor && { cursor }) });

  const response = await fetch(url, { headers: { "x-api-key": "YOUR_API_KEY" } });
  if (!response.ok) throw new Error((await response.json()).error);
  const page = await response.json();

  for (const t of page.transfers) {
    console.log(t.direction, t.uiAmount, t.token.symbol, t.value.usd, t.from?.owner, "->", t.to?.owner);
  }
  cursor = page.pagination.next;
} while (cursor);
```

每笔转账的格式如下：

```json theme={null}
{
  "signature": "2VxcHt8HKSt2T2EuUZLyWPsEKz4H4BPreWV28aZDEzoaHG4Fsu232oKKeQqpVqsSYaf3vv8KN7UoZ4MPJA8vw9EF",
  "status": "success",
  "type": "spl",
  "direction": "in",
  "from": { "address": "C2RjaMN2NeYAErS6KiBjPQhHCt95J8mCmmLiQqZXPisR", "owner": "BfG7WYmravgBhNdWpGoiFmF8L1duw2vdqdDHiZid2hoJ" },
  "to": { "address": "D9CEogjHA6CpS12F8St9zpSco7pQKJB5uR1RqDsuzQZk", "owner": "GachaNgyXTU3zFogQ8Z5jR2BLXs8215X2AtEH18VxJq3" },
  "token": { "name": "USD Coin", "symbol": "USDC", "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "image": "https://image.solanatracker.io/proxy?url=…", "decimals": 6 },
  "amount": "25000000",
  "uiAmount": "25",
  "decimals": 6,
  "price": { "usd": 1 },
  "value": { "usd": 25 },
  "timestamp": 1792483949,
  "slot": 459159504
}
```

* **`amount`** 是原始整数数量，**`uiAmount`** 是精确十进制数量，两者均为字符串。
* **`timestamp`** 是区块时间，单位为 Unix **秒**。
* **`type`** 为 `sol` 表示原生 SOL，为 `spl` 表示代币转账。SOL 使用 wrapped SOL mint `So11111111111111111111111111111111111111112`。
* **`status`** 是交易结果，为 `success` 或 `failed`。除非指定 `status=failed` 或 `status=any`，否则不包含失败的交易。
* **`price`** 和 **`value`** 仅在 `historicPrices=true` 或使用价值筛选时返回。
* **`identity`**：钱包身份已知时出现在 `from` 或 `to` 上，例如 KOL、交易所、池、开发者或 SNS 名称。

### 筛选历史

| 筛选 | 参数 |
| - | - |
| 代币 | `mint`、`type=sol\|spl` |
| 方向 | `direction=in\|out\|all` |
| 发送方、接收方 | `from`、`to`、`counterparty`（任一方）、`excludeFrom`、`excludeTo`（每个最多 5 个地址，用英文逗号分隔，可为钱包或代币账户） |
| 时间 | `start`、`end`（包含边界值），单位为 Unix 秒 |
| 插槽 | `startSlot`、`endSlot`（包含边界值） |
| 数量 | `minAmount`、`maxAmount`（代币单位），`excludeZero=true` |
| 美元价值 | `minValue`、`maxValue`（会启用 `historicPrices`；`limit` 最多为 100） |
| DEX 活动 | `dex=exclude\|include\|only`（默认 `exclude`） |
| 交易结果 | `status=success\|failed\|any`（默认 `success`） |
| 排序 | `sortOrder=desc\|asc` |

每个参数只有一个名称。端点无法识别的参数名会返回 400，并告诉你正确的名称，例如 `unknown parameter timeStart; use start`，因此拼写错误不会返回未经筛选的页面。

`historicPrices=true` 会添加 `price.usd` 和 `value.usd`，即转账发生时代币的美元价格，取自转账前最多一小时内最近的一根 1 分钟 K 线。没有价格时两者为 `null`。

### 什么算作 DEX 活动

当交易中有转账发往或来自某个池时，该交易即视为有 DEX 活动。池是指 DEX 或发射台程序拥有的账户，例如 pump.fun 联合曲线或 Meteora DLMM 池，或者 Raydium、Meteora 的金库权限账户。这涵盖兑换、添加和移除流动性，以及领取手续费和奖励。钱包发出一种代币并收到另一种代币的交易也算在内。`dex=exclude` 和 `dex=only` 作用于整笔交易：交易中的所有转账会一起被排除或保留。只有匹配 `direction` 和 `mint` 的转账会被检查，因此设置了这两个筛选时，如果某笔交易中与池相关的那段转账被筛掉，该交易就会被视为普通转账。

### 按交易分组

添加 `grouped=true`，同时获取 `transactions`，即本页转账按签名分组的结果。每笔交易包含其 `transfers`、转账数量 `legs`、`totals.in`、`totals.out` 和 `totals.tokens`，以及 `dex`。`dex` 为 true 时 `type` 为 `swap`；当钱包发出一种代币并收到另一种代币时，`swap` 会给出转入和转出的代币。启用 `historicPrices=true` 时，合计还会带有美元金额：`totals.value`、`totals.net`，以及每一侧的 `usd`。

### 分页

将 `pagination.next` 作为 `cursor` 传回，并保持筛选不变，直到 `hasMore` 为 `false`。一页不会拆分交易，因此转账数可能比 `limit` 略多或略少；`grouped=true` 时，`limit` 通常按交易计数。带筛选的请求每次只读取有限数量的转账，因此即使 `hasMore` 仍为 `true`，一页也可能少于 `limit` 条，甚至为空。继续翻页即可。

使用 `minValue` 或 `maxValue` 时，每页会为接下来的 `limit` 笔转账计价，并返回其中匹配的转账。如果无法及时读取价格，请求会返回 503；重新发送即可。

### 使用 TypeScript SDK

安装 **0.6.0 或更高版本**的 `@solana-tracker/data-api`。`getAccountTransfers` 接受与接口相同的筛选参数，地址类筛选可以传数组或逗号分隔的字符串。SDK 会按 API 的规则检查参数，对 API 会拒绝的请求在发送前抛出 `ValidationError`。`iterateAccountTransfers` 会自动跟随 `pagination.next`，遇到带筛选的空页也会继续翻页。

```typescript theme={null}
import { Client } from '@solana-tracker/data-api';

const client = new Client({ apiKey: 'YOUR_API_KEY' });
const wallet = 'GachaNgyXTU3zFogQ8Z5jR2BLXs8215X2AtEH18VxJq3';

// 收到的每一页 USDC 转账，附带当时的美元价值。
for await (const page of client.iterateAccountTransfers(wallet, {
  mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
  direction: 'in',
  historicPrices: true,
  limit: 100,
})) {
  for (const t of page.transfers) {
    console.log(t.signature, t.uiAmount, t.token.symbol, t.value?.usd, t.from?.identity?.name ?? t.from?.owner);
  }
}

// 每笔交易一条，包含兑换。
const grouped = await client.getAccountTransfers(wallet, {
  grouped: true,
  dex: 'include',
  historicPrices: true,
  limit: 50,
});
for (const tx of grouped.transactions) {
  console.log(tx.signature, tx.type, tx.totals.net?.usd, tx.swap?.out.token.symbol, '->', tx.swap?.in.token.symbol);
}
```

传入 `{ grouped: true }` 时，TypeScript 会推断出响应带有 `transactions`。

## 实时订阅转账

使用 Data API 密钥连接 `wss://datastream.solanatracker.io/{apiKey}`。Datastream 适用于 Premium、Business 和 Enterprise 套餐。

### 选择房间

* **[`transfer:wallet:{wallet}`](https://docs.solanatracker.io/cn/datastream/websockets/transferwallet)**：某个钱包在所有代币上的转入和转出。
* **[`transfer:{mint}`](https://docs.solanatracker.io/cn/datastream/websockets/transfertoken)**：某个代币的所有转账。不支持 SOL。
* **[`transfer:{mint}:{wallet}`](https://docs.solanatracker.io/cn/datastream/websockets/transfertokenwallet)**：某个代币转入或转出某个钱包。使用 wrapped SOL mint 时也支持 SOL。

在任意房间后添加 **`:enriched`**，为每笔转账和余额变化添加 `token`（名称、符号、图片、精度）、`price.usd`、`value.usd` 和 `marketCap.usd`，并为每笔转账的 `from` 和 `to` 以及每条余额变化添加 `identity`：钱包的 KOL 资料、机器人、平台、开发者、池子或 SNS 标签，与交易房间相同；钱包没有身份时为 `null`。SOL 的 `marketCap.usd` 为其价格乘以流通供应量；USDC、USDT 和 USD1 没有该值。增强消息可能比普通消息晚最多 250 毫秒到达；如果某项查询耗时更长，消息会带 `enrichmentStatus: "partial"`，缺失的值为 `null`。

```javascript theme={null}
const wallet = "GachaNgyXTU3zFogQ8Z5jR2BLXs8215X2AtEH18VxJq3";
const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY");

ws.addEventListener("open", () => {
  ws.send(JSON.stringify({ type: "join", room: `transfer:wallet:${wallet}:enriched` }));
});

ws.addEventListener("message", (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type === "ping") return ws.send(JSON.stringify({ type: "pong" }));
  if (msg.type !== "message") return;

  for (const t of msg.data.transfers) {
    console.log(t.direction, t.uiAmount, t.token.symbol, t.value.usd, msg.data.signature);
  }
});
```

### 使用 SDK 订阅

SDK 自动处理心跳和重连。`transfers.wallet`、`transfers.token` 和 `transfers.tokenWallet` 分别订阅三个房间；设置 `{ enriched: true }` 订阅 `:enriched` 房间。`transfers.token` 不支持 SOL，会直接抛出错误；SOL 请使用 `transfers.wallet`，或将 wrapped SOL mint 传给 `transfers.tokenWallet`。

```typescript theme={null}
import { Datastream } from '@solana-tracker/data-api';

const stream = new Datastream({
  wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY',
});
stream.on('error', console.error);
await stream.connect();

const sub = stream.subscribe.transfers
  .wallet('GachaNgyXTU3zFogQ8Z5jR2BLXs8215X2AtEH18VxJq3', { enriched: true })
  .on((update) => {
    for (const t of update.transfers) {
      console.log(t.direction, t.uiAmount, t.token.symbol, t.value.usd, t.from.identity?.name ?? t.from.owner);
    }
    // 部分价格或身份查询超时，对应值为 null。
    if (update.enrichmentStatus === 'partial') console.log(update.signature);
  });

// sub.unsubscribe();
// stream.disconnect();
```

### 读取消息

每条消息对应一笔交易：

```json theme={null}
{
  "type": "message",
  "room": "transfer:wallet:5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
  "data": {
    "signature": "3sGWwELDWpxMaTWkadG95XK3mYiY2TZw8X6VVG7eZopJ8hGvWt4s2A6KK7ZZMVN7Qujg4WtJcm8dXmwvfnyhZ4NS",
    "slot": 462944056,
    "timestamp": 1793290384,
    "commitment": "processed",
    "swapTx": false,
    "transfers": [
      {
        "id": "3sGWwELDWpxMaTWkadG95XK3mYiY2TZw8X6VVG7eZopJ8hGvWt4s2A6KK7ZZMVN7Qujg4WtJcm8dXmwvfnyhZ4NS:3:-1",
        "signature": "3sGWwELDWpxMaTWkadG95XK3mYiY2TZw8X6VVG7eZopJ8hGvWt4s2A6KK7ZZMVN7Qujg4WtJcm8dXmwvfnyhZ4NS",
        "slot": 462944056,
        "timestamp": 1793290384,
        "commitment": "processed",
        "instruction": 3,
        "inner": -1,
        "type": "spl",
        "program": "token-2022",
        "mint": "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn",
        "decimals": 6,
        "amount": "18404223000000",
        "uiAmount": "18404223",
        "from": {
          "address": "CEbJzsx15hLQkHD6Tsp5vk58rcnMtvbgLReGLzjiy4uH",
          "owner": "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
          "postBalance": "1151345685569531"
        },
        "to": {
          "address": "F5zXibinJCcNKY8BJhYC6iX5sKCKkaaSFV3MJgbVz25M",
          "owner": "G56HkiSheuhfjnTPGjGC1nNddu7NBtTqedueYKCrEHW2",
          "postBalance": "18404223000000"
        },
        "swapTx": false,
        "direction": "out"
      }
    ],
    "balances": [
      {
        "owner": "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
        "account": "CEbJzsx15hLQkHD6Tsp5vk58rcnMtvbgLReGLzjiy4uH",
        "mint": "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn",
        "program": "token-2022",
        "decimals": 6,
        "pre": "1169749908569531",
        "post": "1151345685569531",
        "change": "-18404223000000",
        "cause": "transfer"
      },
      {
        "owner": "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
        "account": "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
        "mint": "So11111111111111111111111111111111111111112",
        "program": "system",
        "decimals": 9,
        "pre": "1029258892726041",
        "post": "1029258892711041",
        "change": "-15000",
        "cause": "other",
        "fee": "15000"
      }
    ]
  }
}
```

* **`transfers`** 是此房间的转账，按指令顺序排列。`id` 格式为 `signature:instruction:inner`，每笔转账唯一。钱包房间会设置 `direction`。带转账手续费的 Token-2022 转账包含 `fee`，`amount` 为扣除手续费前的数量。
* **`balances`** 是此房间在该交易中的余额变化：钱包的、代币的，或钱包在该代币上的。`cause` 为 `transfer`、`swap`（交易者交易的代币）或 `other`。手续费支付者的 SOL 记录带有 `fee`，已包含在 `change` 中。
* **兑换保留在交易房间中。** 已推送的兑换中的转账不会再次发送。兑换的剩余部分，例如平台手续费、小费或付给其他钱包的款项，会带 `swapTx: true` 推送。
* **不属于转账：** 包装（wrap）、解包（unwrap）以及钱包自有账户之间的转移。失败的交易不会推送。

在 `:enriched` 房间中，同一条消息还会带有 `token`、`price`、`value`、`marketCap` 和 `identity`。在下面的例子中，一位 KOL 将某个代币卖出换成 SOL；付给另一个钱包的 SOL 手续费是兑换的剩余部分，因此带 `swapTx: true` 推送。

> [accordion] 增强消息示例
>
> ```json theme={null}
> {
>   "type": "message",
>   "room": "transfer:wallet:ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph:enriched",
>   "data": {
>     "signature": "3og3m2Rtw2L6P9Zv98J1ZhwGtrKVfmyTzJBSWKf1mCLGDzNddSyceNqHvTvP5oAZ42FpoAkqmEEStT42XMBmXuJp",
>     "slot": 463404942,
>     "timestamp": 1793388931,
>     "commitment": "processed",
>     "swapTx": true,
>     "transfers": [
>       {
>         "id": "3og3m2Rtw2L6P9Zv98J1ZhwGtrKVfmyTzJBSWKf1mCLGDzNddSyceNqHvTvP5oAZ42FpoAkqmEEStT42XMBmXuJp:1:-1",
>         "signature": "3og3m2Rtw2L6P9Zv98J1ZhwGtrKVfmyTzJBSWKf1mCLGDzNddSyceNqHvTvP5oAZ42FpoAkqmEEStT42XMBmXuJp",
>         "slot": 463404942,
>         "timestamp": 1793388931,
>         "commitment": "processed",
>         "instruction": 1,
>         "inner": -1,
>         "type": "sol",
>         "program": "system",
>         "mint": "So11111111111111111111111111111111111111112",
>         "decimals": 9,
>         "amount": "1984300",
>         "uiAmount": "0.0019843",
>         "from": {
>           "address": "ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>           "owner": "ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>           "postBalance": "89633841158",
>           "identity": {
>             "name": "Ducky",
>             "twitter": "@zXDuckyXz",
>             "avatar": "https://kol-avatar.solanatracker.io/ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>             "platforms": [
>               "axiom"
>             ],
>             "type": "kol",
>             "tags": [
>               "kol",
>               "axiom"
>             ]
>           }
>         },
>         "to": {
>           "address": "8GV86MhDQST6rh56oTMU9v5TdHwRtXnFQ3zdGD3WT3mG",
>           "owner": "8GV86MhDQST6rh56oTMU9v5TdHwRtXnFQ3zdGD3WT3mG",
>           "postBalance": "43378482944",
>           "identity": null
>         },
>         "swapTx": true,
>         "token": {
>           "mint": "So11111111111111111111111111111111111111112",
>           "name": "Solana",
>           "symbol": "SOL",
>           "image": "https://image.solanatracker.io/proxy?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsolana-labs%2Ftoken-list%2Fmain%2Fassets%2Fmainnet%2FSo11111111111111111111111111111111111111112%2Flogo.png",
>           "decimals": 9
>         },
>         "price": {
>           "usd": 94.23572271990248
>         },
>         "value": {
>           "usd": 0.19
>         },
>         "marketCap": {
>           "usd": 55602827082.74623
>         },
>         "direction": "out"
>       }
>     ],
>     "balances": [
>       {
>         "owner": "ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>         "account": "CMkGUwGS7a7qxNKVUv2UwMoy92Awj9DbUNXcLy1ZbXxZ",
>         "mint": "6AyZsNDJctD1T1hmqPsZWGGSuWM7feNEUbph5SeLpump",
>         "program": "token-2022",
>         "decimals": 6,
>         "pre": "26109484455083",
>         "post": "0",
>         "change": "-26109484455083",
>         "cause": "swap",
>         "identity": {
>           "name": "Ducky",
>           "twitter": "@zXDuckyXz",
>           "avatar": "https://kol-avatar.solanatracker.io/ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>           "platforms": [
>             "axiom"
>           ],
>           "type": "kol",
>           "tags": [
>             "kol",
>             "axiom"
>           ]
>         },
>         "token": {
>           "mint": "6AyZsNDJctD1T1hmqPsZWGGSuWM7feNEUbph5SeLpump",
>           "name": "The Chill Penguin",
>           "symbol": "Penguin",
>           "image": "https://image.solanatracker.io/proxy?url=https%3A%2F%2Faxiomtrading-v2.axiom-cdn.io%2FCKUym5DFePEDCGA8VTVxZcNEpveHgb71JzhXGRqypump.webp",
>           "decimals": 6
>         },
>         "price": {
>           "usd": 0.000003898241016375787
>         },
>         "value": {
>           "usd": -101.78
>         },
>         "marketCap": {
>           "usd": 3898.241016375787
>         }
>       },
>       {
>         "owner": "ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>         "account": "ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>         "mint": "So11111111111111111111111111111111111111112",
>         "program": "system",
>         "decimals": 9,
>         "pre": "88473075092",
>         "post": "89633841158",
>         "change": "1160766066",
>         "cause": "swap",
>         "fee": "20700",
>         "identity": {
>           "name": "Ducky",
>           "twitter": "@zXDuckyXz",
>           "avatar": "https://kol-avatar.solanatracker.io/ADC1QV9raLnGGDbnWdnsxazeZ4Tsiho4vrWadYswA2ph",
>           "platforms": [
>             "axiom"
>           ],
>           "type": "kol",
>           "tags": [
>             "kol",
>             "axiom"
>           ]
>         },
>         "token": {
>           "mint": "So11111111111111111111111111111111111111112",
>           "name": "Solana",
>           "symbol": "SOL",
>           "image": "https://image.solanatracker.io/proxy?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsolana-labs%2Ftoken-list%2Fmain%2Fassets%2Fmainnet%2FSo11111111111111111111111111111111111111112%2Flogo.png",
>           "decimals": 9
>         },
>         "price": {
>           "usd": 94.23572271990248
>         },
>         "value": {
>           "usd": 109.39
>         },
>         "marketCap": {
>           "usd": 55602827082.74623
>         }
>       }
>     ]
>   }
> }
> ```

实时转账在 processed 确认级别发送。交易可能因分叉而被丢弃，且不会发送回滚消息，因此请用 REST 端点核对。加入重叠房间时，同一笔转账会在每个房间各发送一次。

## 下一步

> [card] [账户转账 API 参考](https://docs.solanatracker.io/cn/data-api/transfers/get-account-transfers.md)
>
> 所有参数和响应字段。

> [card] [Datastream 协议](https://docs.solanatracker.io/cn/guides/datastream-protocol.md)
>
> 连接、加入房间并处理心跳。


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