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

# 토큰 민트 필터링

> LaserStream gRPC에서 matchMints를 사용해 특정 토큰 민트와 관련된 모든 트랜잭션을 구독하세요. 민트가 계정 키에 없어 accountInclude가 놓치는 SPL 전송도 포착합니다.

LaserStream의 `matchMints` 플래그를 사용하면 gRPC 트랜잭션 구독이 계정 키뿐 아니라 **트랜잭션의 사전/사후 토큰 잔액에 있는 토큰 민트**도 매칭할 수 있습니다.

`accountInclude`에 민트를 넣고 `matchMints: true`를 설정하면 전송, 스왑, 민트 발행, 소각, 계정 폐쇄 등 해당 토큰과 관련된 모든 트랜잭션을 수신합니다.

<Note>
  `matchMints`는 LaserStream gRPC에서만 사용할 수 있습니다. 아직 LaserStream WebSocket에서는 사용할 수 없습니다.
</Note>

## 문제: 일반 계정 필터는 대부분의 토큰 전송을 놓칩니다

`accountInclude: [mint]`를 사용해 토큰을 모니터링하면 민트 공개 키가 트랜잭션의 계정 키에 나타나는 트랜잭션만 매칭됩니다.

일반적인 SPL `Transfer` 명령은 민트를 참조하지 않습니다. 소스 토큰 계정, 대상 토큰 계정, 소유자만 지정하므로 일반 계정 필터는 모든 토큰에서 가장 흔한 작업을 놓칩니다.

`MintTo`, `Burn`, `TransferChecked` 및 프로그램 계정에 민트가 포함된 스왑처럼 민트를 직접 전달하는 명령만 매칭됩니다. 유일한 해결 방법은 모든 트랜잭션을 스트리밍하고 각 트랜잭션의 토큰 잔액을 직접 검사하는 것이었습니다.

## `matchMints`의 작동 방식

트랜잭션 필터에 `matchMints: true`를 설정하면 LaserStream이 트랜잭션의 `preTokenBalances` 및 `postTokenBalances`에서 민트 집합을 구성합니다.

그런 다음 `accountInclude`, `accountExclude`, `accountRequired` 목록을 계정 키와 해당 민트 집합 **모두**에 대해 매칭합니다. 잔액 변경 여부와 관계없이 특정 민트의 토큰 계정이 두 잔액 목록 중 하나에 나타나면 해당 민트가 조건을 충족합니다.

이 플래그는 선택적으로 활성화하며, 이를 생략한 필터는 이전과 정확히 동일하게 작동합니다. 따라서 기존 구독이 이미 수신하는 항목을 변경하지 않고 이 플래그를 추가할 수 있습니다. 두 프로그램 모두 사전/사후 토큰 잔액을 채우므로 SPL 및 Token-2022 민트가 지원됩니다.

## 동작 규칙

| 조건자               | `matchMints` 미사용             | `matchMints: true` 사용                                          |
| ----------------- | ---------------------------- | -------------------------------------------------------------- |
| `accountInclude`  | 나열된 키 중 하나라도 계정 키에 있으면 매칭됩니다 | 나열된 키 중 하나라도 계정 키 **또는** 민트 집합에 있으면 매칭됩니다                      |
| `accountExclude`  | 나열된 키 중 하나라도 계정 키에 있으면 제외합니다 | 나열된 키 중 하나라도 계정 키 **또는** 민트 집합에 있으면 제외합니다                      |
| `accountRequired` | 나열된 모든 키가 계정 키에 있어야 합니다      | 나열된 모든 키가 계정 키 **또는** 민트 집합에 있어야 합니다(각 키는 어느 쪽에 있어도 조건을 충족합니다) |

나머지 필터 로직은 변경되지 않습니다.

* 하나의 명명된 필터 안에 있는 조건자는 계속 AND로 결합됩니다(`vote`, `failed`, `signature` 및 계정 목록).
* 여러 명명된 필터는 계속 OR로 결합됩니다.
* 목록 안의 값은 OR로 처리됩니다(`accountRequired`는 예외이며 모두 매칭되어야 합니다).
* 토큰 잔액이 없는 트랜잭션은 키만 사용하는 매칭으로 대체됩니다. `matchMints`는 토큰 활동이 없는 트랜잭션을 추가하지 않습니다.
* `matchMints`만으로는 스트림을 제한하지 않습니다. 필터가 허용되려면 계정 목록에 키나 민트가 하나 이상 있어야 하며, 또는 다른 제한 조건자가 있어야 합니다.

<Note>
  LaserStream은 정확한 공개 키를 기준으로 민트를 매칭합니다. `tokenAccounts: "balanceChanged"`와 달리 민트에는 "잔액이 변경된 경우만" 매칭하는 모드가 없습니다.
</Note>

## LaserStream gRPC에서 사용하기

`SubscribeRequest`의 트랜잭션 필터에 `matchMints: true`를 추가하고 `accountInclude`에 민트를 넣으세요. 다음 예시는 메인넷의 모든 USDC 트랜잭션을 스트리밍합니다.

<Tabs>
  <Tab title="TypeScript">
    `helius-laserstream` 0.8.5 이상이 필요합니다. 필드는 `match_mints`로도 사용할 수 있습니다.

    ```typescript theme={"system"}
    import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';
    import bs58 from 'bs58';

    const USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';

    const subscriptionRequest: SubscribeRequest = {
      transactions: {
        'usdc-txs': {
          accountInclude: [USDC],
          accountExclude: [],
          accountRequired: [],
          vote: false,
          failed: false,
          matchMints: true, // match USDC via pre/post token-balance mints
        },
      },
      commitment: CommitmentLevel.CONFIRMED,
      accounts: {}, slots: {}, transactionsStatus: {},
      blocks: {}, blocksMeta: {}, entry: {}, accountsDataSlice: [],
    };

    const config: LaserstreamConfig = {
      apiKey: 'YOUR_API_KEY',
      endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com',
    };

    await subscribe(config, subscriptionRequest, async (data) => {
      const tx = data.transaction?.transaction;
      if (!tx) return;
      // USDC balances touched by this transaction
      const usdcBalances = (tx.meta?.postTokenBalances || []).filter((b: any) => b.mint === USDC);
      console.log(bs58.encode(tx.signature), usdcBalances);
    }, async (error) => {
      console.error('Stream error:', error);
    });
    ```
  </Tab>

  <Tab title="Rust">
    `helius-laserstream` 0.6.4 이상이 필요합니다(`laserstream-core-proto` 11.3.0을 가져옵니다). 필드는 proto 크레이트에서 직접 제공됩니다.

    ```rust theme={"system"}
    use std::collections::HashMap;
    use helius_laserstream::grpc::{SubscribeRequest, SubscribeRequestFilterTransactions};

    let request = SubscribeRequest {
        transactions: HashMap::from([(
            "usdc-txs".to_string(),
            SubscribeRequestFilterTransactions {
                account_include: vec!["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v".to_string()],
                vote: Some(false),
                failed: Some(false),
                match_mints: true,
                ..Default::default()
            },
        )]),
        ..Default::default()
    };
    ```
  </Tab>

  <Tab title="Go">
    `go/v0.3.0` 태그 이상의 Go 모듈이 필요합니다.

    ```go theme={"system"}
    vote := false
    failed := false
    req := &laserstream.SubscribeRequest{
        Transactions: map[string]*laserstream.SubscribeRequestFilterTransactions{
            "usdc-txs": {
                AccountInclude: []string{"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"},
                Vote:           &vote,
                Failed:         &failed,
                MatchMints:     true,
            },
        },
        Commitment: &commitmentLevel,
    }
    ```
  </Tab>
</Tabs>

SDK 대신 원시 gRPC 또는 Yellowstone 클라이언트를 사용한다면 Helius proto에서 다시 생성하세요(`laserstream-core-proto` 11.3.0 이상 또는 SDK 저장소에 포함된 `.proto`).

`match_mints`는 `SubscribeRequestFilterTransactions`의 32번 필드입니다. 업스트림 Triton proto에서 생성된 클라이언트는 알 수 없는 필드를 아무 알림 없이 삭제하므로 다시 생성하기 전까지 이 플래그는 적용되지 않습니다.

모든 트랜잭션 필터 필드는 [구독 요청 레퍼런스](/docs/ko/laserstream/grpc#구독-요청)를 참조하세요.

## `tokenAccounts`와 결합하여 특정 지갑의 특정 토큰 모니터링하기

`matchMints`는 [`tokenAccounts` 확장](/docs/ko/laserstream/token-account-filtering)과 함께 사용할 수 있으므로 하나의 필터에서 지갑 소유자와 민트를 동시에 매칭할 수 있습니다.

다음 예시는 특정 지갑의 USDC 잔액에 발생하는 모든 변경 사항을 스트리밍합니다.

```typescript theme={"system"}
transactions: {
  'wallet-usdc': {
    accountInclude: [WALLET],
    accountRequired: [USDC],
    accountExclude: [],
    tokenAccounts: 'balanceChanged', // wallet matched via its token accounts
    matchMints: true,                // USDC matched via balance mints
    vote: false,
    failed: false,
  },
},
```

`accountInclude`와 `tokenAccounts`를 함께 사용하면 지갑의 토큰 잔액이 변동된 트랜잭션을 찾습니다. `accountRequired`와 `matchMints`를 함께 사용하면 그중 USDC와 관련된 트랜잭션으로 범위를 좁힙니다.

## 매칭된 항목 확인하기

트랜잭션이 민트를 통해 매칭되면 `meta.preTokenBalances[].mint` 및 `meta.postTokenBalances[].mint`에서 민트를 찾으세요. 일반 전송에서는 보통 민트가 계정 키에 없으므로 그곳에서 찾지 마세요.

동일한 `accountIndex`에서 `preTokenBalances`와 `postTokenBalances`의 차이를 비교하면 토큰이 얼마나 이동했으며 어느 소유자 사이에서 이동했는지 확인할 수 있습니다.

[트랜잭션 모니터링 가이드](/docs/ko/laserstream/guides/transaction-monitoring#트랜잭션-데이터-구조)에서 트랜잭션 구조를 자세히 설명합니다.

## 제한 사항 및 참고 사항

* 민트는 계정 키와 동일한 `accountInclude`, `accountExclude`, `accountRequired` 목록에 들어가므로 목록별 요금제 제한에 함께 포함됩니다. 별도의 민트 제한은 없습니다.
* 매칭 비용은 나열한 민트 수에 따라 증가하지 않습니다. 민트 100개와 100,000개의 성능은 동일하며, 플래그를 설정하지 않은 구독자에게는 추가 비용이 발생하지 않습니다.
* [과거 데이터 재생](/docs/ko/laserstream/historical-replay)은 `matchMints`를 적용하므로 재생 구독은 라이브 스트림에서 반환했을 트랜잭션과 동일한 트랜잭션을 반환합니다.
* 트랜잭션 구독에 [압축(cuckoo) 필터](/docs/ko/laserstream/cuckoo-filters)를 연결하면 `matchMints`가 계정 키뿐 아니라 민트 집합도 해당 필터에 대조합니다.
* `matchMints`는 메인넷과 개발넷을 포함한 모든 LaserStream gRPC 리전에서 사용할 수 있습니다. 현재 LaserStream WebSocket에서는 사용할 수 없습니다.
* 최소 SDK 버전: JavaScript/TypeScript `helius-laserstream` 0.8.5, Rust `helius-laserstream` 0.6.4, Go `go/v0.3.0`.

## 관련 문서

<CardGroup cols={2}>
  <Card title="Token Account (ATA) Filtering" icon="coins" href="/docs/ko/laserstream/token-account-filtering">
    지갑이 소유한 토큰 계정과 관련된 트랜잭션을 매칭합니다
  </Card>

  <Card title="Transaction Monitoring" icon="receipt" href="/docs/ko/laserstream/guides/transaction-monitoring">
    gRPC를 사용하는 전체 필터링 전략과 실행 가능한 예시를 확인합니다
  </Card>

  <Card title="Subscribe Request Reference" icon="filter" href="/docs/ko/laserstream/grpc">
    `matchMints`를 포함한 모든 트랜잭션 필터 필드를 확인합니다
  </Card>

  <Card title="Historical Replay" icon="clock-rotate-left" href="/docs/ko/laserstream/historical-replay">
    동일한 필터로 최대 24시간의 토큰 활동을 백필합니다
  </Card>
</CardGroup>
