> ## 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 지갑의 자금 출처 확인 방법

> 첫 번째 SOL 이체를 추적하여 Solana 지갑의 원래 자금 출처를 발견하세요. 거래소 자금 조달, 귀속 및 지갑 관계를 식별합니다.

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

## 개요

Wallet Funding Source 엔드포인트는 처음으로 들어온 SOL 전송을 분석하여 Solana 지갑을 초기 자금 후원자를 식별합니다. 이는 귀속, 규정 준수, 지갑 관계 이해 및 거래소 자금 조달 지갑 식별에 유용합니다.

자금 제공자의 이름과 범주는 [Identity](/docs/ko/wallet-api/identity) 엔드포인트에서 사용하는 동일한 식별 시스템에서 가져오므로, 자금 제공자가 알려진 엔티티일 경우 응답에 인간이 읽을 수 있는 레이블과 범주가 직접 제공됩니다.

이 엔드포인트는 유료 플랜이 필요합니다. 무료 플랜 API 키로 요청한 경우 `403 Forbidden`이 반환됩니다. 전체 커버리지 표는 [플랜 요구 사항](/docs/ko/wallet-api/overview#플랜-요구-사항)을 참조하세요.

## 사용 시기

Wallet Funding Source API를 사용하세요:

* **지갑 귀속**: 새로운 지갑이 어디에서 자금을 받는지 추적합니다.
* **거래소 감지**: 중앙화 거래소에서 직접 자금을 받은 지갑 식별.
* **규정 준수 및 AML**: 규정 준수 검사를 위해 알려진 엔티티에서 자금을 받은 지갑을 플래그.
* **봇 감지**: 동일한 출처에서 자금을 받은 봇 팜 식별.
* **에어드롭 분석**: 프로젝트에서 초기 자금을 받은 지갑 추적.
* **Sybil 감지**: 동일한 주소에서 자금을 받은 지갑 클러스터 찾기.

## 빠른 시작

### 기본 자금 조회

지갑을 누가 자금을 댔는지 알아보세요:

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

      const response = await fetch(url);

      if (response.status === 404) {
        console.log('No funding transaction found for this wallet');
        return null;
      }

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const funding = await response.json();

      console.log(`Funding Source: ${funding.funderName || funding.funder}`);
      console.log(`Funder Type: ${funding.funderType || 'Unknown'}`);
      console.log(`Initial Amount: ${funding.amount} SOL`);
      console.log(`Date: ${new Date(funding.timestamp * 1000).toLocaleString()}`);
      console.log(`Transaction: ${funding.explorerUrl}`);

      return funding;
    };

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

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

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

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

        if response.status_code == 404:
            print('No funding transaction found for this wallet')
            return None

        response.raise_for_status()
        funding = response.json()

        print(f"Funding Source: {funding.get('funderName') or funding['funder']}")
        print(f"Funder Type: {funding.get('funderType', 'Unknown')}")
        print(f"Initial Amount: {funding['amount']} SOL")
        print(f"Date: {datetime.fromtimestamp(funding['timestamp']).strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"Transaction: {funding['explorerUrl']}")

        return funding

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

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

## 응답 형식

성공적인 응답은 지갑의 첫 번째 SOL 전송을 설명합니다:

```json theme={"system"}
{
  "funder": "26MAyPNpK4At8LgRECMMbgiKQuJyg3oACtw1Q9FRyuba",
  "funderName": null,
  "funderType": null,
  "mint": "So11111111111111111111111111111111111111111",
  "symbol": "SOL",
  "amount": 0.09811972,
  "amountRaw": "98119720",
  "decimals": 9,
  "date": "2022-01-19T20:46:34.000Z",
  "signature": "5WX9C5kCQNULGGrSHJBR1WDFyetVyekbUpe1KQ45p3zEBe6jVgSsJuMqLWijjTDcnaAK2518ZriktRMCNycnsNAG",
  "timestamp": 1642625194,
  "slot": 116984883,
  "explorerUrl": "https://orbmarkets.io/tx/5WX9C5kCQNULGGrSHJBR1WDFyetVyekbUpe1KQ45p3zEBe6jVgSsJuMqLWijjTDcnaAK2518ZriktRMCNycnsNAG?tab=summary"
}
```

지갑이 SOL을 받은 적이 없는 경우 API는 404를 반환합니다:

```json theme={"system"}
{
  "error": "No funding transaction found",
  "code": 404
}
```

### 필드 노트

* **`funder`**: 이 지갑에 첫 SOL 전송을 보낸 주소.
* **`funderName`**: 자금 제공자가 알려진 엔티티인 경우 인간이 읽을 수 있는 이름 (예: 거래소, 프로토콜); 그렇지 않으면 `null`.
* **`funderType`**: 자금 제공자의 범주 (예: `exchange`, `defi-protocol`); 식별 데이터베이스에 없는 경우 `null`.
* **`mint`**: 토큰 민트 주소 (SOL의 경우 `So11111111111111111111111111111111111111111`).
* **`symbol`**: 토큰 심볼 (자금 거래에서는 항상 `SOL`).
* **`amount`**: 받은 초기 SOL 금액 (사람이 읽을 수 있는 형식, 예: `0.05` SOL).
* **`amountRaw`**: 라포트 단위의 원시 금액 (예: 0.05 SOL인 경우 `"50000000"`).
* **`decimals`**: 토큰의 소수 자릿수 (SOL의 경우 9).
* **`date`**: ISO 8601 형식의 날짜 문자열 (예: `"2024-01-01T00:00:00.000Z"`).
* **`signature`**: 자금 전송의 거래 서명.
* **`timestamp`**: 지갑이 자금을 받은 시점의 유닉스 타임스탬프 (초 단위).
* **`slot`**: 자금 거래가 확인된 Solana 슬롯 번호.
* **`explorerUrl`**: Orb에서 거래를 볼 수 있는 직접 링크.

## 사용 사례

### 거래소 자금 조달 지갑 감지

중앙화 거래소에서 직접 자금을 받은 지갑 식별:

```javascript theme={"system"}
const isExchangeFunded = async (address) => {
  try {
    const funding = await getWalletFundingSource(address);

    if (!funding) {
      console.log('Wallet has no funding transaction');
      return false;
    }

    if (funding.funderType === 'exchange') {
      console.log(`Wallet was funded by ${funding.funderName}`);
      console.log(`This is likely a retail user withdrawing from an exchange`);
      return true;
    }

    console.log(`Wallet was not funded by an exchange`);
    return false;

  } catch (error) {
    console.error('Error checking funding source:', error);
    return false;
  }
};

isExchangeFunded("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
```

### 지갑 클러스터 찾기 (Sybil 감지)

동일한 출처에서 자금을 받은 지갑 그룹 식별:

```javascript theme={"system"}
const findWalletClusters = async (walletAddresses) => {
  const fundingData = await Promise.all(
    walletAddresses.map(async address => {
      try {
        const funding = await getWalletFundingSource(address);
        return { address, funder: funding?.funder };
      } catch {
        return { address, funder: null };
      }
    })
  );

  // Group by funder
  const clusters = {};

  fundingData.forEach(({ address, funder }) => {
    if (funder) {
      if (!clusters[funder]) {
        clusters[funder] = [];
      }
      clusters[funder].push(address);
    }
  });

  // Report clusters
  Object.entries(clusters).forEach(([funder, wallets]) => {
    if (wallets.length > 1) {
      console.log(`\nFound cluster: ${wallets.length} wallets funded by ${funder.slice(0, 8)}...`);
      wallets.forEach(wallet => console.log(`  - ${wallet}`));
    }
  });

  return clusters;
};

// Example: Check list of wallets for clusters
const suspiciousWallets = [
  "Wallet1...",
  "Wallet2...",
  "Wallet3..."
];

findWalletClusters(suspiciousWallets);
```

### 에어드롭 수신자 추적

에어드롭 수신자가 어디에서 왔는지 분석:

```javascript theme={"system"}
const analyzeAirdropRecipients = async (airdropWallets) => {
  const fundingSources = await Promise.all(
    airdropWallets.map(async address => {
      try {
        return await getWalletFundingSource(address);
      } catch {
        return null;
      }
    })
  );

  const stats = {
    total: airdropWallets.length,
    exchangeFunded: 0,
    unknown: 0,
    byExchange: {}
  };

  fundingSources.forEach(funding => {
    if (!funding) {
      stats.unknown++;
      return;
    }

    if (funding.funderType === 'exchange') {
      stats.exchangeFunded++;
      const exchange = funding.funderName || 'Unknown Exchange';
      stats.byExchange[exchange] = (stats.byExchange[exchange] || 0) + 1;
    }
  });

  console.log('Airdrop Recipient Analysis:');
  console.log(`Total Recipients: ${stats.total}`);
  console.log(`Exchange-Funded: ${stats.exchangeFunded} (${(stats.exchangeFunded / stats.total * 100).toFixed(1)}%)`);
  console.log(`Unknown Source: ${stats.unknown}`);
  console.log('\nBy Exchange:');
  Object.entries(stats.byExchange).forEach(([exchange, count]) => {
    console.log(`  ${exchange}: ${count}`);
  });

  return stats;
};
```

### 지갑 타임라인 구축

지갑 생성을 시작으로 타임라인 생성:

```javascript theme={"system"}
const buildWalletTimeline = async (address) => {
  const funding = await getWalletFundingSource(address);

  if (!funding) {
    console.log('No funding data available');
    return null;
  }

  const creationDate = new Date(funding.timestamp * 1000);
  const ageInDays = Math.floor((Date.now() - creationDate.getTime()) / (1000 * 60 * 60 * 24));

  console.log('Wallet Timeline:');
  console.log(`Created: ${creationDate.toLocaleString()} (${ageInDays} days ago)`);
  console.log(`Initial Funding: ${funding.amount} SOL`);
  console.log(`Funded By: ${funding.funderName || funding.funder.slice(0, 8) + '...'}`);

  if (funding.funderType === 'exchange') {
    console.log(`This wallet was likely created by withdrawing from ${funding.funderName}`);
  }

  return {
    creationDate,
    ageInDays,
    initialFunding: funding.amount,
    fundedBy: funding.funderName || funding.funder
  };
};
```

### 규정 준수 위험 점수 매기기

자금 출처를 기반으로 위험 점수 할당:

```javascript theme={"system"}
const assessWalletRisk = async (address) => {
  const funding = await getWalletFundingSource(address);

  if (!funding) {
    return { riskLevel: 'UNKNOWN', score: 50, reasons: ['No funding data available'] };
  }

  let score = 0;
  let reasons = [];

  // Low risk: Funded by known exchange
  if (funding.funderType === 'exchange') {
    score = 20;
    reasons.push(`Funded by known exchange (${funding.funderName})`);
  }
  // Medium risk: Unknown funder
  else if (!funding.funderName) {
    score = 50;
    reasons.push('Funded by unknown wallet');
  }
  // High risk: Funded by flagged address
  else if (funding.funderType === 'flagged') {
    score = 90;
    reasons.push('Funded by flagged address');
  }

  // Age factor: New wallets are higher risk
  const ageInDays = (Date.now() / 1000 - funding.timestamp) / (60 * 60 * 24);
  if (ageInDays < 7) {
    score += 20;
    reasons.push('Wallet is less than 7 days old');
  }

  // Amount factor: Very small initial funding is suspicious
  if (funding.amount < 0.01) {
    score += 10;
    reasons.push('Very small initial funding amount');
  }

  const riskLevel = score < 30 ? 'LOW' : score < 60 ? 'MEDIUM' : 'HIGH';

  console.log(`Risk Assessment for ${address}:`);
  console.log(`Risk Level: ${riskLevel} (Score: ${score}/100)`);
  reasons.forEach(reason => console.log(`  - ${reason}`));

  return { riskLevel, score, reasons };
};
```

### 귀속 추적

가장 많은 새로운 지갑을 생성하는 소스 추적:

```javascript theme={"system"}
const trackNewWalletSources = async (recentWallets) => {
  const fundingSources = await Promise.all(
    recentWallets.map(async address => {
      try {
        const funding = await getWalletFundingSource(address);
        return {
          address,
          funder: funding?.funder,
          funderName: funding?.funderName,
          funderType: funding?.funderType
        };
      } catch {
        return { address, funder: null };
      }
    })
  );

  // Count by source
  const sourceStats = {};

  fundingSources.forEach(({ funderName, funderType }) => {
    const sourceName = funderName || funderType || 'Unknown';
    sourceStats[sourceName] = (sourceStats[sourceName] || 0) + 1;
  });

  // Sort by count
  const sorted = Object.entries(sourceStats)
    .sort(([, a], [, b]) => b - a)
    .slice(0, 10);

  console.log('Top Wallet Funding Sources:');
  sorted.forEach(([source, count]) => {
    console.log(`${source}: ${count} wallets`);
  });

  return sourceStats;
};
```

## 자금 제공자 유형

`funderType` 필드는 주소에 자금을 댄 지갑의 범주를 나타냅니다. [Identity Categories](/docs/ko/wallet-api/identity#신원-카테고리)의 모든 값이 지원됩니다.

<Accordion title="지원되는 자금 제공자 유형">
  일반적 자금 제공자 유형:

  | 유형        | 설명             | 예시                    |
  | --------- | -------------- | --------------------- |
  | 중앙화 거래소   | CEX 핫월렛        | 바이낸스, 코인베이스, 크라켄, OKX |
  | DeFi      | DeFi 프로토콜 주소   | 주피터, 레이디움, 마리네이드      |
  | 시장 조성자    | 시장 조성 회사       | 점프 트레이딩, 윈터뮤트         |
  | 트레이딩 회사   | 독립 트레이딩 회사     | 기관 트레이더               |
  | 크로스체인 브리지 | 브릿지 프로토콜 주소    | 웜홀, 올브리지, 포탈          |
  | 검증자       | 검증자 주소         | 코인베이스 검증자, Jito       |
  | 핵심 의견 리더  | 주목할만한 개인       | 영향력 있는 인물, 창립자        |
  | 재무부       | 프로젝트 재무부       | 프로토콜 재무부              |
  | 스테이크 풀    | 유동성 스테이킹 풀     | 마리네이드, Jito           |
  | null      | 알려지지 않은 자금 제공자 | 일반 지갑, 식별 데이터베이스에 없음  |

  전체 목록에는 에어드롭, 권한, 크로스체인 브리지, 카지노 및 도박, DAO, DeFi, DePIN, 중앙화 거래소, 악용자/해커/사기, 수수료, 모금, 게임, 제네시스 블록 배포, 거버넌스, 해커, Jito, 핵심 의견 리더, 시장 조성자, 밈코인, 멀티시그, NFT, 비유통 공급, 오라클, 기타, 결제, 독점 AMM, 재스테이킹, 러거, 사기꾼, 스팸, 스테이크 풀, 시스템, 도구, 트레이딩 앱/봇, 트레이딩 회사, 거래 전송, 재무부, 검증자, 금고, 그리고 X402가 포함됩니다.

  전체 목록 및 설명은 [Identity Categories](/docs/ko/wallet-api/identity#신원-카테고리) 섹션을 참조하세요.
</Accordion>

## 모범 사례

* **404 응답 처리**. SOL을 받은 적이 없는 지갑은 404를 반환합니다. 이는 새로 생성되었지만 자금을 받지 않은 지갑의 경우 예상됩니다.
* **Identity API와 결합**. 응답에는 `funderName`와 `funderType`가 포함되지만, 더 자세한 내용을 위해 [Identity](/docs/ko/wallet-api/identity) 엔드포인트를 `funder` 주소에서 호출할 수 있습니다.
* **자금 데이터 캐싱**. 지갑의 자금 출처는 변경되지 않습니다. 이 데이터를 영구적으로 캐시하여 반복적인 API 호출을 피하세요.
* **컨텍스트를 위한 연령 확인**. `timestamp`는 지갑이 처음 자금을 받았을 때을 알려줍니다. 자금 출처와 연령을 결합하여 더 나은 컨텍스트를 제공하세요.

## 일반적인 오류

| 오류 코드 | 설명                  | 해결 방법                                                                                  |
| ----- | ------------------- | -------------------------------------------------------------------------------------- |
| 400   | 잘못된 지갑 주소 형식        | 주소가 유효한 base58 Solana 주소인지 확인                                                          |
| 401   | 누락되거나 유효하지 않은 API 키 | 요청에 API 키가 포함되어 있는지 확인                                                                 |
| 403   | 엔드포인트에 유료 플랜이 필요    | 자금 출처 조회는 무료 플랜에서 사용할 수 없습니다. [플랜 업그레이드](https://dashboard.helius.dev)하여 유료 구간으로 업그레이드 |
| 404   | 자금 전송이 발견되지 않음      | 이 지갑은 SOL을 받은 적이 없습니다                                                                  |
| 429   | 비율 제한 초과            | 요청 빈도를 줄이거나 플랜을 업그레이드                                                                  |

## 제한 사항

* 이 엔드포인트는 지갑의 **첫 SOL 전송**만 추적합니다.
* 에어드롭이나 프로그래밍 초기화를 통해 SOL 전송 없이 생성된 지갑은 자금 데이터를 갖지 않습니다.
* 자금 출처는 **즉시** 자금을 제공한 자를 나타내며, 반드시 자금의 최종 출처를 나타내지는 않습니다.
* 이 기능이 배포된 후 생성된 지갑에 대한 데이터만 사용할 수 있습니다.

## 다음 단계

<CardGroup cols={3}>
  <Card title="지갑 ID" icon="address-card" href="/docs/ko/wallet-api/identity">
    자금 제공자 주소를 전체 레이블, 범주 및 태그로 해결하세요.
  </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/funded-by">
    자금 출처 조회를 위한 요청 및 응답 스키마.
  </Card>
</CardGroup>
