Chainalysis KYT 기능을 이용한 위험 평가 API

Chainalysis KYT를 이용한 위험 평가

POST http://<enclave-endpoint>/v1/risk-assessment/chainalysis-kyt

Chainalysis KYT(Know Your Transaction) API는 Chainalysis 서비스와 연계하여 가상 자산 지갑 주소나 트랜잭션의 위험도를 평가하는 데 사용하는 API입니다.

Chainalysis KYT API를 호출하기 위해서는 반드시 먼저 사용자 검증(POST /verifications)을 완료해야 합니다.

Chainalysis KYT API는 트랜잭션 리포트 수행 전/후에 따라 동작 방식과 수행 결과가 달라집니다:

  1. 트랜잭션 리포트를 하기 전:

    • Originating VASP (송신 VASP): Beneficiary의 지갑 주소에 대한 위험도를 평가합니다. 이를 통해 출금 시 수취인의 지갑 주소가 얼마나 위험한지를 신속하게 평가할 수 있습니다.

    • Beneficiary VASP (수신 VASP): KYT API를 호출할 수 없으며, 호출 시 UNSUPPORTED-RISK-ASSESSMENT 에러가 반환됩니다. 따라서 트랜잭션 리포트 전일 경우 Beneficiary VASP는 이 API를 사용할 수 없습니다.

  2. 트랜잭션 리포트를 한 후:

    • Originating VASP (송신 VASP): 출금 트랜잭션에 대한 위험도를 평가합니다. 이를 통해 출금 트랜잭션의 위험 정도를 확인할 수 있습니다.

    • Beneficiary VASP (수신 VASP): 입금 트랜잭션에 대한 위험도를 평가합니다. 이를 통해 입금 트랜잭션의 위험 정도를 확인할 수 있습니다.

위의 방식으로 Chainalysis KYT API를 활용함으로써, 가상 자산 거래의 안전성을 높일 수 있습니다. 송신하는 VASP는 수취인의 지갑 주소의 위험도를 사전에 파악하고, 수신하는 VASP는 트랜잭션의 위험도를 평가하여 필요한 조치를 취할 수 있습니다.

Chainalysis KYT API 란

Chainalysis KYT API는 유료 기반의 API로 다음 2가지 유형의 기능을 제공합니다.

  1. Withdrawal attempt 타입

    • 출금하기 전에 상대방 입금 주소가 얼마나 위험한 주소인지에 대한 위험 평가를 할 수 있습니다.

  2. Transfer 타입

    • 실제 자산 전송 트랜잭션에 대해 해당 블록체인 트랜잭션이 얼마나 위험한 거래인지에 대한 위험 평가를 할 수 있습니다.

Chainalysis KYT API는 Chainalysis Sanction API 보다 더 정확한 위험 평가 기능을 제공합니다.

Chainalysis KYT API를 사용하기 위해서는 Chainalysis 웹사이트에 회원가입하고 라이센스를 구매해야 합니다. 아래의 링크에서 KYT API 라이센스를 구매하기 위해 Chainalysis에 문의하시거나 혹은 VerifyVASP팀에 별도로 문의주시면 Chainalysis 팀과의 미팅 진행을 도와드리겠습니다.

Chainalysis KYT API 라이센스를 구입한 후에는 KYT 콘솔 사이트에 로그인하여 KYT API 키를 발급받을 수 있습니다. 아래의 링크에서 로그인 후 "Help" 아이콘을 클릭하고 "Developers" 클릭 후 "API Keys" 메뉴를 참고하십시오(로그인 후 Help > Developers > API Keys).

Chainalysis KYT API는 비동기적으로 동작합니다. 즉, 위험 평가를 원하는 대상(출금 시도 또는 전송)을 먼저 Chainalysis에 등록하고, 등록된 요청에 대한 결과는 조회 API를 통해 수신합니다. Chainalysis KYT API에 대한 자세한 내용은 아래의 링크에서 확인하실 수 있습니다.

사전 준비 사항

이 기능을 사용하기 위해서는 아래의 2가지 사항을 미리 준비해야 합니다.

  1. Enclave 환경 변수 설정

  2. Enclave 데이터베이스 테이블 생성

    • Chainalysis KYT API 호출 이력과 그로 인해 발생한 KYT alert들이 enclave 데이터베이스에 저장됩니다. 따라서 이를 위한 데이터베이스 테이블을 따로 생성해야 합니다.

    • 테이블 정의는 Chainalysis KYT Results 테이블Chainalysis KYT Alerts 테이블을 참고하시기 바랍니다.

Request Body

Request Body Examples
{
  "verificationUuid": "d63398e3-c806-4300-bd99-170b54642080",
  "network": "Ethereum"
}
Field NameData TypeRequiredDescription

verificationUuid

string

true

위험 평가를 수행할 사전에 수행했던 트래블룰 검증 (verification)의 verificationUuid

network

string

false

사전에 수행한 트래블룰 검증(verification)에 대해 좀 더 정확한 네트워크(가상 자산 전송이 발생한)를 지정하기 위해 입력

  • USDT 와 같은 가상 자산은 이더리움, 트론, 이오스와 같이 여러 블록체인에 존재할 수 있기 때문에 어떤 네트워크로 전송했는지 지정하지 않으면 위험 평가를 하기 어려울 수 있습니다.

  • 따라서 USDT 와 같이 네트워크가 애매한 경우에는 network property를 이용하여 가상 자산 전송이 발생한 정확한 네트워크를 지정할 수 있습니다.

  • 지정 가능한 네트워크에 대해서는 Supported networks and assets를 참고하시기 바랍니다.

Response Body

성공 케이스

Response Body Examples
  • 200 OK

{
  "requestId": "f7231c6f-f1e7-4ae7-b143-2c87cd38abe9"
}
Field NameData TypeRequiredDescription

requestId

string

true

위험 평가 요청을 구분하기 위한 식별자. verificationUuid 와는 다르며, 위험 평가를 요청할 때마다 새로 부여된다.

Chainalysis KYT 기능은 비동기적으로 동작합니다. 따라서 이 API를 호출하는 즉시 결과가 반환되지 않습니다. Chainalysis KYT 기능을 이용한 위험 평가 결과는 Callback VASP API를 통해 전달됩니다. Callback VASP API로 전달되는 위험 평가 결과는 다음과 같은 형식으로 전달됩니다.

Request Body Example for CHAINALYSIS_KYT_RESULT callbackType
{
  "callbackType": "CHAINALYSIS_KYT_RESULT",
  "data": {
    "verificationUuid": "69a310e6-810f-4a31-83d1-bcdafccf5304",
    "riskAssessment": {
      "chainalysisKYT": {
        "requestId": "f7231c6f-f1e7-4ae7-b143-2c87cd38abe9",
        "counterpartyVaspId": "15952089931162059995",
        "apiType": "ATTEMPT",
        "userId": "15952089931162059995",
        "direction": "OUTGOING",
        "network": "ETHEREUM",
        "asset": "ETH",
        "amount": "1",
        "usdPrice": "1820.17",
        "outputAddress": "bb3fd383d1c5540e52ef0a7bcb9433375793aeaf",
        "timestamp": "2023-05-18T12:39:44.000Z",
        "externalId": "79382ac9-c7be-3fab-ad56-8c61c654e2fc",
        "status": "PROCESSED",
        "alertCount": 1,
        "createdAt": "2023-05-18T12:39:46.000Z",
        "assessedAt": "2023-05-18T12:39:45.263Z"
      },
      "chainalysisKYTAlerts": [
        {
          "counterpartyVaspId": "15952089931162059995",
          "externalId": "79382ac9-c7be-3fab-ad56-8c61c654e2fc",
          "direction": "OUTGOING",
          "alertId": "118b8cc8-f579-11ed-b86d-a3210c6ca9b8",
          "alertLevel": "MEDIUM",
          "entityCategory": "high risk exchange",
          "serviceName": "HIGH RISK EXCHANGE: SimpleSwap.io bb3fd383d1c5540e52ef0a7bcb9433375793aeaf",
          "exposureType": "DIRECT",
          "alertAmount": "1820.17",
          "createdAt": "2023-05-18T12:39:52.461Z"
        }
      ]
    }
  }
}

위험 평가 결과가 전달될 때 riskAssessment property가 전달되며 그중에 KYT 기능을 이용한 위험 평가 결과는 riskAssessment 하위의 chainalysisKYT property를 통해 전달됩니다.

chainalysisKYT 구조체는 다음과 같은 속성들을 가집니다.

Field NameData TypeRequiredDescription

requestId

string

true

각각의 위험 평가 요청을 구분하기 위한 식별자

counterpartyVaspId

string

true

거래 상대방 VASP의 ID

apiType

string

true

Chainalysis KYT API를 호출할 때 어떤 API를 호출했는지를 구분하는 값, 출금 전에 상대방 주소의 위험 평가하는 것은 "ATTEMPT", 자산 전송 트랜잭션의 위험 평가를 하는 것은 "TRANSFER"

userId

string

true

Chainalysis KYT API 호출 시 입력한 userId 값, 상대방 VASP ID가 입력된다.

direction

string

true

출금일 경우 "OUTGOING", 입금일 경우에는 "INCOMING"

network

string

true

자산 전송이 이루어질 블록체인 네트워크 이름

asset

string

true

전송하려고 하는, 혹은 전송한 가상 자산의 종류, ticker

amount

string

true

전송하려고 하는, 혹은 전송한 가상 자산의 수량

usdPrice

string

false

전송하려고 하는, 혹은 전송한 가상 자산의 USD 환산 금액

transferRef

string

false

apiType이 "TRANSFER" 인 경우, 위험 평가의 대상이 되는 자산 전송 트랜잭션의 식별자, 블록체인마다 형태가 다르지만 일반적으로 "<tx_hash>:<output_address>"의 형태를 띤다.

outputAddress

string

true

위험 평가의 대상이 되는 수신자의 지갑 주소

timestamp

string

true

위험 평가 대상이 되는 트랜잭션이 발생한 시간, apiType이 "ATTEMPT" 인 경우에는 KYT API가 호출된 시간

externalId

string

false

각각의 위험 평가 요청을 구분하기 위해 Chainalysis에서 발급한 ID, KYT API 호출이 실패한 경우에는 발급되지 않는다.

status

string

true

위험 평가 요청의 상태, 아직 결과가 나오지 않았으면 "REGISTERED", 위험 평가 결과가 나왔으면 "PROCESSED"

alertCount

number

false

위험 평가 결과, 생성된 KYT alert의 개수, status가 "PROCESSED" 가 아니면 null, 만약 alert 개수가 1 이상이면 KYT alert이 별도의 배열로 전달된다.

createdAt

string

true

위험 평가 이력이 만들어진 시간

assessedAt

string

false

Chainalysis로부터 위험 평가 결과가 도출된 시간

만약 Chainalysis KYT 기능을 이용한 위험 평가 결과, alertCount가 1 이상이 경우에는 위와 같이 KYT alert들이 riskAssessment 하위의 chainalysisKYTAlerts property를 통해 전달됩니다.

chainalysisKYTAlerts property는 배열이며 alertCount 개수만큼 원소를 가집니다. 각 원소는 다음과 같은 속성들을 가집니다.

Field NameData TypeRequiredDescription

counterpartyVaspId

string

true

거래 상대방 VASP의 ID

externalId

string

true

각각의 위험 평가 요청을 구분하기 위해 Chainalysis에서 발급한 ID, 해당 alert이 어떤 KYT 요청으로 생성된 것인지 구별하기 위해 사용

direction

string

true

출금일 경우 "OUTGOING", 입금일 경우에는 "INCOMING"

alertId

string

true

KYT alert 하나하나를 구별하기 위해 Chainalysis에서 부여한 ID

alertLevel

string

true

KYT alert의 위험도 수준, 위험도가 낮은 순서대로 "LOW", "MEDIUM", "HIGH", "SEVERE" 값을 가질 수 있다.

entityCategory

string

false

Alert 규칙이 추적 중인 엔터티 카테고리, 하단의 설명을 참고

serviceName

string

false

Chainalysis에서 정의한 거래 상대방의 서비스 이름, 아직 서비스 이름을 식별하지 못했거나 INDIRECT exposure인 경우에는 null

exposureType

string

true

노출 방향을 정의, "DIRECT" or "INDIRECT"

alertAmount

string

true

KYT alert의 대상이 되는 자금의 규모, USD 단위

createdAt

string

true

KYT alert이 생성된 시간

entityCategory는 Chainalysis에서 정의한 카테고리 항목입니다. 다음 URL에서 카테고리 목록을 확인하실 수 있습니다. 단, Chainalysis KYT dashboard에 로그인해야 볼 수 있습니다.

List of Entity Category

실패 케이스

필수 파라미터를 입력하지 않은 경우

Response Body Examples
  • 400 Bad Request

{
  "code": "MISSING-VERIFICATION-UUID",
  "message": "`verificationUuid` is required."
}

API Key가 올바르지 않을 경우

Response Body Examples
  • 403 Forbidden

{
  "code": "UNKNOWN-ERROR-CODE",
  "message": "AccessDenied"
}

존재하지 않는 verificationUuid인 경우

Response Body Examples
  • 400 Bad Request

{
  "code": "NOT-FOUND-VERIFICATION",
  "message": "Verification(8d729bf4-38db-471d-b052-896f8660916a) is not found"
}

Beneficiary VASP에서 트랜잭션 리포트가 되기 전에 호출한 경우

Response Body Examples
  • 400 Bad Request

{
  "code": "UNSUPPORTED-RISK-ASSESSMENT",
  "message": "Chainalysis KYT API for received transfer should be called after txHash is reported"
}

기타 잘못된 요청인 경우

Response Body Examples
  • 400 Bad Request

{
  "code": "BAD-REQUEST",
  "message": "......"
}

Last updated