> ## 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.

# 모든 Solana 지갑 전송 가져오는 방법

> 모든 Solana 지갑에 대한 들어오고 나가는 토큰 전송을 추적하세요. 발신자/수신자 정보, 금액 및 타임스탬프를 통해 완전한 전송 기록을 확인할 수 있습니다.

<Note>
  지갑 API는 베타 버전입니다. 엔드포인트 및 응답 형식은 변경될 수 있습니다.
</Note>

## 개요

Token Transfers 엔드포인트는 Solana 지갑의 모든 토큰 전송 활동을 검색하며, 발신자 및 수신자에 대한 자세한 정보를 포함합니다. 전체 [거래 내역](/docs/ko/wallet-api/history)과 달리, 이 엔드포인트는 전송에 중점을 두어 결제 추적 및 전송 모니터링에 이상적입니다.

이 엔드포인트는 요청당 최대 100개의 전송을 반환하며 (기본값 50), 다음 페이지를 가져오기 위해 `cursor` 매개변수를 `pagination.nextCursor`와 함께 사용하고, 더 많은 결과를 확인하려면 `pagination.hasMore`를 읽으세요.

## 사용 시기

Token Transfers API는 다음과 같은 경우에 사용하세요:

* **결제 추적**: 결제 프로세서를 위한 들어오는 결제를 모니터링합니다.
* **전송 피드 생성**: 간단한 "보냄/받음" 활동 피드를 표시합니다.
* **특정 토큰 모니터링**: 특정 토큰의 전송을 추적합니다 (예: USDC 결제).
* **거래 상대 식별**: 누가 토큰을 보냈는지 또는 받았는지 확인하세요.
* **영수증 생성**: 발신자/수신자 세부 정보를 포함한 결제 영수증을 만듭니다.
* **의심 활동 감지**: 비정상적인 전송 패턴을 모니터링합니다.

## 빠른 시작

### 기본 전송 쿼리

최근 들어오고 나가는 전송을 얻습니다:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    const getWalletTransfers = async (address) => {
      const url = `https://api.helius.xyz/v1/wallet/${address}/transfers?api-key=YOUR_API_KEY`;

      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json();

      console.log(`Found ${data.data.length} transfers`);

      // Display recent transfers
      data.data.forEach(transfer => {
        const date = new Date(transfer.timestamp * 1000).toLocaleString();
        const direction = transfer.direction === 'in' ? 'Received' : 'Sent';
        const counterparty = transfer.counterparty.slice(0, 8) + '...';

        console.log(`\n${direction} - ${date}`);
        console.log(`Amount: ${transfer.amount} ${transfer.symbol || transfer.mint.slice(0, 8) + '...'}`);
        console.log(`${transfer.direction === 'in' ? 'From' : 'To'}: ${counterparty}`);
        console.log(`Signature: ${transfer.signature.slice(0, 20)}...`);
      });

      return data;
    };

    getWalletTransfers("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    import requests
    from datetime import datetime

    def get_wallet_transfers(address: str):
        url = f"https://api.helius.xyz/v1/wallet/{address}/transfers"
        headers = {"X-Api-Key": "YOUR_API_KEY"}

        response = requests.get(url, headers=headers)
        response.raise_for_status()

        data = response.json()

        print(f"Found {len(data['data'])} transfers")

        # Display recent transfers
        for transfer in data['data']:
            date = datetime.fromtimestamp(transfer['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
            direction = 'Received' if transfer['direction'] == 'in' else 'Sent'
            counterparty = transfer['counterparty'][:8] + '...'
            symbol = transfer.get('symbol') or transfer['mint'][:8] + '...'

            print(f"\n{direction} - {date}")
            print(f"Amount: {transfer['amount']} {symbol}")
            print(f"{'From' if transfer['direction'] == 'in' else 'To'}: {counterparty}")
            print(f"Signature: {transfer['signature'][:20]}...")

        return data

    get_wallet_transfers("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY")
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"system"}
    curl "https://api.helius.xyz/v1/wallet/86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY/transfers?api-key=YOUR_API_KEY"
    ```
  </Tab>
</Tabs>

### 방향별 필터링

클라이언트 측에서 결과를 필터링하여 들어오는 전송 또는 나가는 전송만 얻습니다:

<Tabs>
  <Tab title="Incoming Only">
    ```javascript theme={"system"}
    const getIncomingTransfers = async (address) => {
      const data = await getWalletTransfers(address);

      const incoming = data.data.filter(t => t.direction === 'in');

      console.log(`Received ${incoming.length} incoming transfers`);

      incoming.forEach(transfer => {
        console.log(`Received ${transfer.amount} ${transfer.symbol} from ${transfer.counterparty.slice(0, 8)}...`);
      });

      return incoming;
    };
    ```
  </Tab>

  <Tab title="Outgoing Only">
    ```javascript theme={"system"}
    const getOutgoingTransfers = async (address) => {
      const data = await getWalletTransfers(address);

      const outgoing = data.data.filter(t => t.direction === 'out');

      console.log(`Made ${outgoing.length} outgoing transfers`);

      outgoing.forEach(transfer => {
        console.log(`Sent ${transfer.amount} ${transfer.symbol} to ${transfer.counterparty.slice(0, 8)}...`);
      });

      return outgoing;
    };
    ```
  </Tab>
</Tabs>

## 쿼리 매개변수

| 매개변수     | 유형      | 기본값 | 설명                  |
| -------- | ------- | --- | ------------------- |
| `limit`  | integer | 50  | 반환할 최대 전송 수 (1-100) |
| `cursor` | string  | -   | 이전 응답에서의 페이지네이션 커서  |

## 응답 형식

```json theme={"system"}
{
  "data": [
    {
      "signature": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE",
      "timestamp": 1704067200,
      "direction": "in",
      "counterparty": "HXsKP7wrBWaQ8T2Vtjry3Nj3oUgwYcqq9vrHDM12G664",
      "mint": "So11111111111111111111111111111111111111111",
      "symbol": "SOL",
      "amount": 1.5,
      "amountRaw": "1500000000",
      "decimals": 9
    },
    {
      "signature": "4aHu2qwD8Jtj4xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE",
      "timestamp": 1704067100,
      "direction": "out",
      "counterparty": "2ojv9BAiHUrvsm9gxDe7fJSzbNZSJcxZvf8dqmWGHG8S",
      "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "symbol": "USDC",
      "amount": 100.0,
      "amountRaw": "100000000",
      "decimals": 6
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE"
  }
}
```

### 필드 노트

* **`direction`**: 쿼리하는 지갑에 상대적입니다. `in`는 토큰이 **받아진** 경우 (들어오는 결제)에 해당하며, `out`는 토큰이 **보내진** 경우 (나가는 결제)에 해당합니다.
* **`counterparty`**: `in` 전송의 경우 발신자; `out` 전송의 경우 수신자.
* **`amount`**: 사람이 읽을 수 있는 전송 금액으로 이미 `decimals`로 나뉩니다. 표시용으로 사용하세요 (예: `1.5` SOL, `100.0` USDC).
* **`amountRaw`**: 소수 점 조정 전에 정수 문자열로 표현된 동일한 금액입니다 (예: `"1500000000"`는 1.5 SOL의 경우). 부동 소수점의 정확도 손실을 피하기 위해 문자열로 직렬화됩니다. 온체인 명령이나 정밀한 산수를 위해 사용하세요: `amount = parseInt(amountRaw) / 10**decimals`.
* **`mint`**: 토큰 민트 주소 (네이티브 SOL의 경우 `So11111111111111111111111111111111111111111`).
* **`symbol`**: 토큰 심볼. 모든 토큰에 심볼이 있는 것은 아닙니다; `symbol`가 `null`일 때 민트 주소를 사용하세요.

## 사용 사례

### 상인의 결제 이력 추적

들어오는 USDC 결제를 모니터링합니다:

```javascript theme={"system"}
const trackMerchantPayments = async (merchantWallet) => {
  const data = await getWalletTransfers(merchantWallet);

  // Filter for incoming USDC transfers
  const usdcPayments = data.data.filter(t =>
    t.direction === 'in' &&
    t.mint === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
  );

  console.log(`Received ${usdcPayments.length} USDC payments`);

  const totalReceived = usdcPayments.reduce((sum, t) => sum + t.amount, 0);
  console.log(`Total USDC Received: $${totalReceived.toFixed(2)}`);

  // Display each payment
  usdcPayments.forEach(payment => {
    const date = new Date(payment.timestamp * 1000).toLocaleString();
    console.log(`${date}: $${payment.amount} from ${payment.counterparty}`);
  });

  return {
    count: usdcPayments.length,
    total: totalReceived,
    payments: usdcPayments
  };
};
```

### 결제 영수증 생성

특정 전송에 대한 상세 영수증을 만듭니다:

```javascript theme={"system"}
const generatePaymentReceipt = async (address, signature) => {
  const data = await getWalletTransfers(address);

  const transfer = data.data.find(t => t.signature === signature);

  if (!transfer) {
    console.log('Transfer not found');
    return null;
  }

  const receipt = {
    receiptId: transfer.signature.slice(0, 16),
    date: new Date(transfer.timestamp * 1000).toISOString(),
    type: transfer.direction === 'in' ? 'Payment Received' : 'Payment Sent',
    amount: `${transfer.amount} ${transfer.symbol || 'tokens'}`,
    from: transfer.direction === 'in' ? transfer.counterparty : address,
    to: transfer.direction === 'out' ? transfer.counterparty : address,
    transactionUrl: `https://orbmarkets.io/tx/${transfer.signature}`
  };

  console.log('--- PAYMENT RECEIPT ---');
  Object.entries(receipt).forEach(([key, value]) => {
    console.log(`${key}: ${value}`);
  });

  return receipt;
};
```

### 의심스러운 전송 패턴 모니터링

비정상적인 전송 활동을 감지합니다:

```javascript theme={"system"}
const detectSuspiciousActivity = async (address) => {
  const data = await getWalletTransfers(address);

  const recentTransfers = data.data.filter(t => {
    const hourAgo = Date.now() / 1000 - 3600;
    return t.timestamp > hourAgo;
  });

  // Check for high frequency
  if (recentTransfers.length > 100) {
    console.log(`Warning: ${recentTransfers.length} transfers in the last hour`);
  }

  // Check for large amounts
  const largeTransfers = recentTransfers.filter(t => {
    // Assuming USDC/stablecoins
    return t.amount > 10000 && t.decimals === 6;
  });

  if (largeTransfers.length > 0) {
    console.log(`Warning: ${largeTransfers.length} large transfers (>$10k) in the last hour`);
  }

  // Check for transfers to same address
  const counterparties = recentTransfers.map(t => t.counterparty);
  const duplicates = counterparties.filter((item, index) => counterparties.indexOf(item) !== index);

  if (duplicates.length > 5) {
    console.log(`Warning: Multiple transfers to the same address`);
  }

  return {
    recentCount: recentTransfers.length,
    largeTransfers: largeTransfers.length,
    suspiciousPatterns: duplicates.length > 5
  };
};
```

### 전송 활동 피드 구축

사용자 친화적인 활동 피드를 만듭니다:

```javascript theme={"system"}
const buildTransferFeed = async (address) => {
  const data = await getWalletTransfers(address);

  const feed = data.data.map(transfer => {
    const date = new Date(transfer.timestamp * 1000);
    const timeAgo = getTimeAgo(date);

    return {
      id: transfer.signature,
      direction: transfer.direction,
      title: transfer.direction === 'in' ? 'Received' : 'Sent',
      subtitle: `${transfer.amount} ${transfer.symbol || 'tokens'}`,
      description: transfer.direction === 'in'
        ? `from ${transfer.counterparty.slice(0, 8)}...`
        : `to ${transfer.counterparty.slice(0, 8)}...`,
      timeAgo,
      explorerUrl: `https://orbmarkets.io/tx/${transfer.signature}`
    };
  });

  return feed;
};

function getTimeAgo(date) {
  const seconds = Math.floor((new Date() - date) / 1000);

  if (seconds < 60) return 'Just now';
  if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
  if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
  return `${Math.floor(seconds / 86400)}d ago`;
}
```

### 결제 조정

예상 결제와 전송을 일치시킵니다:

```javascript theme={"system"}
const reconcilePayments = async (address, expectedPayments) => {
  const data = await getWalletTransfers(address);

  const recentTransfers = data.data.filter(t =>
    t.direction === 'in' &&
    t.mint === 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' // USDC
  );

  const reconciliation = expectedPayments.map(expected => {
    const match = recentTransfers.find(t =>
      Math.abs(t.amount - expected.amount) < 0.01 &&
      t.counterparty === expected.from
    );

    return {
      orderId: expected.orderId,
      expectedAmount: expected.amount,
      status: match ? 'Received' : 'Pending',
      receivedAmount: match?.amount,
      signature: match?.signature,
      timestamp: match?.timestamp
    };
  });

  console.log('Payment Reconciliation:');
  reconciliation.forEach(r => {
    console.log(`Order ${r.orderId}: ${r.status}`);
  });

  return reconciliation;
};

// Example usage
const expected = [
  { orderId: 'ORDER-001', amount: 100.00, from: 'ABC...' },
  { orderId: 'ORDER-002', amount: 250.50, from: 'XYZ...' }
];

reconcilePayments("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY", expected);
```

## 페이지네이션

많은 전송이 있는 지갑의 경우 `cursor` 매개변수 및 `pagination.hasMore`를 사용하여 결과를 페이지로 나눕니다:

```javascript theme={"system"}
const getAllTransfers = async (address) => {
  let allTransfers = [];
  let cursor = null;

  do {
    const url = cursor
      ? `https://api.helius.xyz/v1/wallet/${address}/transfers?api-key=YOUR_API_KEY&cursor=${cursor}`
      : `https://api.helius.xyz/v1/wallet/${address}/transfers?api-key=YOUR_API_KEY`;

    const response = await fetch(url);
    const data = await response.json();

    allTransfers = allTransfers.concat(data.data);
    cursor = data.pagination.hasMore ? data.pagination.nextCursor : null;

    console.log(`Fetched ${allTransfers.length} transfers so far...`);

  } while (cursor);

  console.log(`\nTotal transfers: ${allTransfers.length}`);
  return allTransfers;
};
```

## 모범 사례

* **특정 토큰을 위해 클라이언트 측에서 필터링.** API는 모든 토큰 전송을 반환합니다. 특정 토큰 (예: USDC 또는 SOL)을 추적하려면 `mint` 주소로 필터링하십시오.
* **Identity API와 결합.** [Identity](/docs/ko/wallet-api/identity) 엔드포인트를 사용하여 알려진 상대방 (거래소, 프로토콜 등)의 이름을 사람이 읽을 수 있게 표시하세요.
* **최근 전송 캐시.** 전송 데이터는 변경되지 않습니다. 결과를 캐시하고 마지막 쿼리 이후 새 전송만 가져옵니다.
* **전체 기록을 위해 페이지네이션.** 수천 개의 전송이 있는 지갑을 효율적으로 처리하려면 페이지네이션을 구현하세요.
* **심볼 누락 처리.** 모든 토큰에 `symbol` 필드가 있는 것은 아닙니다. `symbol`가 `null`일 때 민트 주소를 사용하세요.

## 전송 대 거래 내역

| 기능        | 전송         | 거래 내역           |
| --------- | ---------- | --------------- |
| **중점**    | 오직 토큰 전송   | 모든 거래 유형        |
| **데이터**   | 발신자/수신자 정보 | 모든 토큰에 대한 잔액 변경 |
| **사용 사례** | 결제 추적      | 완전한 활동 로그       |
| **성능**    | 빠르고 간단함    | 보다 포괄적임         |

결제에만 관심이 있다면 [Transfers](/docs/ko/wallet-api/transfers)를 사용하세요. 전체 잔액 변경 데이터가 필요할 경우 [Transaction History](/docs/ko/wallet-api/history)를 사용하세요.

## 일반적인 오류

| 오류 코드 | 설명              | 해결 방법                            |
| ----- | --------------- | -------------------------------- |
| 400   | 잘못된 지갑 주소 형식    | 주소가 올바른 base58 Solana 주소인지 확인하세요 |
| 401   | 누락되거나 잘못된 API 키 | 요청에 API 키가 포함되어 있는지 확인하세요        |
| 429   | 요청 한도 초과        | 요청 빈도를 줄이거나 플랜을 업그레이드하세요         |

## 다음 단계

<CardGroup cols={3}>
  <Card title="지갑 내역" icon="clock-rotate-left" href="/docs/ko/wallet-api/history">
    거래별 잔액 변경과 함께 완전한 거래 내역을 제공합니다.
  </Card>

  <Card title="지갑 API 개요" icon="wallet" href="/docs/ko/wallet-api/overview">
    모든 지갑 API 엔드포인트와 공유 규칙.
  </Card>

  <Card title="API 참조" icon="code" href="/docs/ko/api-reference/wallet-api/transfers">
    토큰 전송에 대한 요청 및 응답 스키마.
  </Card>
</CardGroup>
