# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
This site has an agentic ask interface you may use to query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.klipwallet.com/index.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

---

# Introduction

이 페이지는 Klip과 Klip 개발자 가이드를 소개합니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

## Klip

Klip은 사용자의 디지털 자산을 쉽고 편리하게 관리해 주는 개인 디지털 지갑 서비스입니다. 지금까지 다양한 블록체인 지갑이 있었지만, 어려운 사용자 경험으로 인해 제한적으로 활용되었습니다. Klip은 카카오 계정과 연동되어 메신저만큼 쉬운 사용자 경험을 제공합니다. 또한, [Kaia](https://www.kaia.io/) 기반의 다양한 블록체인 서비스들을 소개하는 창구 기능을 하며 블록체인 서비스 확산에 기여합니다.

## BApp과 카드

BApp(Blockchain Application)은 DApp(Decentralized Application)과 유사하지만, DApp과 달리 탈중앙화를 넘어 블록체인의 다른 많은 장점까지 흡수한 더 포괄적인 개념으로 사용된 용어입니다. DApp 개발에 관한 자세한 내용은 [Kaia Docs](https://docs.kaia.io/ko/build/)를 확인하시기 바랍니다.

카드란 Klip에서 사용되는 디지털 자산으로, 일반적으로 NFT를 가리킵니다. Klip 파트너사는 자산(게임 아이템, 할인 쿠폰 등)을 카드 형태로 발행하고 Klip 사용자 또는 BApp 사용자에게 보낼 수 있습니다. 사용자는 카드를 받고 Klip 지갑에서 원하는 카드를 사용하거나 또 다른 사람에게 보낼 수 있습니다. 이 과정에서 Klip 파트너사는 자신의 BApp을 잠재 고객에게 알리고 이들을 구매 고객으로 전환할 수 있습니다.

모든 카드는 기본적으로 [**대체 불가능한 토큰**](https://ko.docs.klaytn.com/smart-contract/token-standard#non-fungible-token-standard-kip-17)(Non-Fungible Token)입니다. 대체 불가능한 토큰은 간단하게 말하면 "화폐"(비트코인, 이더리움 등)가 아닌 "**고유한 자산**"입니다. 5만원권 지폐 1장은 다른 5만원권 지폐 1장으로 완벽히 **대체 가능**합니다. 하지만, 내 예술 작품은 다른 이의 예술 작품으로 **대체 불가능**합니다. 다른 이의 명작이 주는 가치와 내 명작이 주는 가치가 서로 같지 않고 비교하기도 어렵기 때문입니다. 이렇게 수집품, 예술 작품, 개인용 물품 등 고유한 자산을 디지털화하여 블록체인상에 토큰 형태로 표현한 것이 바로 대체 불가 토큰입니다. 카드는 BApp에서 사용하는 대체 불가 토큰이며 Klip 사용자는 Klip에서 카드를 쓰고 교환합니다.

## Klip API

Klip API는 외부 서비스에서 API를 통해 Klip에 있는 코인 및 대체 가능한 토큰(FT)을 전송하거나 Klip에서 카드(NFT)를 발행, 조회, 전송 또는 삭제하는 기능을 제공합니다. Klip API는 Klip Partners API와 App2App API로 구성됩니다. Klip은 Kaia 외에 Ethereum, Polygon 자산에 대해서도 동일한 기능을 제공합니다.

### Klip Partners API <a href="#intro-card-minting-api" id="intro-card-minting-api"></a>

Klip Partners API는 서비스에 가입한 파트너사에서 직접 카드를 발행, 조회, 전송, 삭제하기 위한 API입니다. 복잡한 스마트 컨트랙트 배포나 관리 및 운영없이 간단한 API를 사용하여 카드를 활용하는 BApp을 개발할 수 있습니다. Klip Partners API를 사용하기 위한 절차는 아래와 같습니다.

{% hint style="info" %}
Klip Partners 웹사이트는 허가된 사용자만 접근 가능하나, Klip Partners 서비스가 2024년 7월 31일자로 종료되어 현재는 신규 가입 신청을 받지 않고 있습니다. 아울러 기존 사용자 역시 2024년 8월 1일부터 Klip Partners API를 호출할 수 없습니다.
{% endhint %}

1. Klip Partners에 가입 신청을 합니다.
2. Klip 운영진과 별도 협의를 거쳐 가입 승인을 얻은 후 [Sign In](/rest-api/rest-api-card-minting#sign-in)으로 사이트에 로그인합니다.
3. 로그인 후, [Upload Image](/rest-api/rest-api-card-minting#upload-image)로 카드 이미지로 쓸 이미지 파일을 업로드합니다.
4. [Mint Card To User](/rest-api/rest-api-card-minting#mint-card-to-user) 또는 [Mint Card To Klip Member](/rest-api/rest-api-card-minting#mint-card-to-klip-member)로 업로드한 이미지를 사용해 카드를 직접 발행합니다.
5. [Get Card Information By BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp), [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)으로 발행한 카드 정보를 조회합니다.
6. [Send Card To User](/rest-api/rest-api-card-minting#send-card-to-user) 또는 [Send Card To Klip Member](/rest-api/rest-api-card-minting#send-card-to-klip-member)로 발행한 카드를 다른 사람에게 전송합니다.

또한 API를 통해서 계정 및 카드를 쉽게 관리할 수 있습니다.

* [Sign In](/rest-api/rest-api-card-minting#sign-in)으로 로그인한 후
  * [Change Password](/rest-api/rest-api-card-minting#change-password)로 계정 비밀번호를 변경합니다.
  * [Change Pin](/rest-api/rest-api-card-minting#change-pin)으로 핀 번호를 변경합니다.
  * [Delete Card](/rest-api/rest-api-card-minting#delete-card)로 카드 정보를 조회하고 카드를 삭제합니다.

![Klip Partners](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-dd4a9008e52a9ddeb4a69ebce9e3fec37de8e4d3%2Fcard-minting-api.png?alt=media)

### App2App API <a href="#intro-app2app-api" id="intro-app2app-api"></a>

App2App API는 BApp 개발자가 별도 가입 절차없이 Klip 사용자를 인증하고 해당 사용자의 토큰 및 카드를 전송하기 위한 API입니다. 또한 직접 개발한 스마트 컨트랙트 실행을 Klip 사용자에게 요청할 수 있습니다. 기본적으로 Klip 앱이 설치된 모바일 환경에서 BApp이 Deep Link를 통해 Klip에 서명을 요청하는 방식으로 동작합니다.

App2App API는 아래와 같은 상황에서 활용할 수 있습니다.

* BApp 사용자의 Klip 지갑 주소 인증
* Klip을 통한 KAIA, 토큰 전송
* Klip을 통한 카드 조회 및 전송
* Klip을 통한 Smart Contract 실행

{% hint style="info" %}
현재 토큰/NFT 전송 및 Smart Contract 실행과 같은 트랜잭션 서명 기능은 카이아, 이더리움, 폴리곤 네트워크에 대해서만 실행이 가능하며, 추후 지원이 확대될 예정입니다. 다른 네트워크에 대한 Klip 연동이 필요하다면 당장은 WalletConnect 사용을 부탁드립니다.
{% endhint %}

App2App API를 사용하기 위한 절차는 아래와 같습니다.

* [다운로드](/a2a-sdk/a2a-sdk-download) 탭에서 BApp 개발환경에 맞는 SDK를 다운로드 받아 설치합니다. 또는 REST API를 이용할 수도 있습니다.
* Prepare, Request 및 Result API를 이용하여 Klip 사용자 인증 또는 서명 기능을 BApp에 구현합니다. Prepare 스텝에서 App2App API 요청을 위한 key를 발급받고, Request 스텝에서 Klip을 실행합니다. 마지막 Result 스텝에서 요청에 대한 결과를 확인할 수 있습니다.
* 참고로 PC 또는 물리적으로 떨어진 모바일 환경에서는 QR code를 이용하여 Request 스텝을 처리할 수 있습니다. 자세한 내용은 [App2App REST API](/rest-api/rest-api-a2a#request) 탭을 참조하십시오.

![App2App API](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-3494f68b743eb24e7bfe711b7eeeb88f0b2ca191%2Fa2a-api-v.2.png?alt=media)

## 이 문서에 관하여

Klip 개발자 가이드는 BApp 개발자 또는 파트너사가 Klip에서 제공하는 다양한 API를 활용하여 토큰(FT)을 조회하고 전송하거나 카드(NFT)를 발행, 조회, 전송 또는 삭제하도록 안내하는 문서입니다.

| 페이지                      | 설명                                                          |
| ------------------------ | ----------------------------------------------------------- |
| [Introduction](/)        | Klip과 Klip API를 소개합니다.                                      |
| [Basics](/basics)        | 인증, 페이지네이션, 에러코드, 용어를 소개합니다.                                |
| [REST API](/rest-api)    | Klip Partners API와 App2App API를 소개합니다.                      |
| [App2App SDK](/a2a-sdk)  | App2App API를 Javascript, Android, iOS 환경에서 제공하는 SDK를 소개합니다. |
| [Tutorial](/tutorial)    | Klip Partners API와 App2App API 튜토리얼을 소개합니다.                 |
| [Change Log](/changelog) | API 변경 이력을 소개합니다.                                           |

{% hint style="warning" %}
이 문서는 API 또는 개발에 관한 기본적인 정보를 포함하고 있습니다. 이 정보는 변경될 수 있으며 이 문서를 따라 구현한 소프트웨어는 반드시 최종적으로 운영 체제 소프트웨어와 함께 테스트되어야 합니다.
{% endhint %}

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Basics

이 페이지에서는 Klip Partners API와 App2App API의 사용자 인증, 페이지네이션, 리턴 코드, 약어 등을 설명합니다.

## Klip Partners API <a href="#basic-card-minting" id="basic-card-minting"></a>

{% hint style="info" %}
Klip Partners 웹사이트는 허가된 사용자만 접근 가능하나, Klip Partners 서비스가 2024년 7월 31일자로 종료되어 현재는 신규 가입 신청을 받지 않고 있습니다. 아울러 기존 사용자 역시 2024년 8월 1일부터 Klip Partners API를 호출할 수 없습니다.
{% endhint %}

### Authentication

Klip Partners API를 사용하기 위해서는 JWT 기반 액세스 토큰 발급이 필요합니다. Klip Partners 회원 가입 시 등록한 로그인 ID와 비밀번호를 통해서 토큰을 발급 받을 수 있습니다. 발급된 토큰은 24시간 동안 유효하며 보통 만료 전에 재발급이 필요합니다. 발급된 토큰은 API 요청 헤더의 Authorization 필드에 토큰을 포함하는 방식으로 사용합니다.

### Pagination

보유 카드 내역을 조회할 때 카드의 양의 많은 경우 한 번에 받으면 양이 많기 때문에 여러번 요청해야할 수 있습니다. 이를 위해서 조회 API에서는 결과값에 next\_cursor를 함께 제공합니다. 일반적으로 카드 개수가 100개를 초과한다면 1번 호출 시 100개의 결과와 next\_cursor 값을 받습니다. 나머지 카드를 조회하려면 next\_cursor 값을 query 파라미터 cursor에 전달하여 API를 다시 호출해야합니다.

예들 들어 보유하고 있는 카드를 조회하면,

```bash
//Get Card Information By BApp
curl "https://api.klipwallet.com/v2/wallet/bapp" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

아래와 같은 형태의 응답을 받습니다.

```json
{
  "bapps": [...],
  "next_cursor": "N2r8KY...XOadEG"
}
```

남은 카드 목록을 조회하려면 next\_cursor을 이용하여 아래와 같이 다시 호출합니다. next\_cursor가 비어있을 때까지 계속 호출하여 보유한 전체 카드 목록을 얻을 수 있습니다.

```bash
//Get Card Information By BApp
curl "https://api.klipwallet.com/v2/wallet/bapp?cursor=N2r8KY...XOadEG" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

### Success Codes/Error Codes

요청이 성공하면 HTTP code 200을 받습니다. 만약 요청이 정상 처리되지 않으면 400, 401, 500의 HTTP code가 전달됩니다. 400은 요청이 잘못된 경우, 401은 유효하지 않은 액세스 토큰을 사용했을 때 리턴됩니다. 500은 서버에 알 수 없는 장애가 발생했을 때 리턴됩니다. 400 또는 401 에러는 구체적인 에러 코드와 메시지가 함께 전달됩니다.

에러 메시지는 JSON 포맷으로 전달되며 필드는 아래와 같습니다.

```json
{
  "code": number,
  "err": string
}
```

에러 메시지 종류는 아래와 같습니다.

| Status Code | Error Code | Error Message                                            |
| ----------- | ---------- | -------------------------------------------------------- |
| 400         | 400        | bad request                                              |
| 400         | 410        | invalid birth for account creation                       |
| 400         | 411        | teenagers under the age of 19 are not allowed to sign up |
| 400         | 412        | already existing account (wallet)                        |
| 400         | 413        | already existing email                                   |
| 400         | 414        | already existing account without wallet                  |
| 400         | 4111       | receiver is already an user of klip                      |
| 400         | 4112       | sender daily limit exceeded                              |
| 400         | 4113       | sender already sent invite message to receiver           |
| 400         | 4114       | receiver daily limit exceeded                            |
| 400         | 4115       | receiver monthly limit exceeded                          |
| 400         | 4070       | send token count daily limit exceeded                    |
| 400         | 4071       | send token amount onetime limit exceeded                 |
| 400         | 4072       | send token amount decimal places exceeded                |
| 400         | 4080       | mint count monthly limit exceeded                        |
| 401         | 420        | inactive accounts require new pin code settings          |
| 401         | 421        | banned accounts cannot login                             |
| 401         | 422        | suspended accounts cannot login                          |
| 401         | 423        | the account has been unsubscribed                        |
| 401         | 424        | undefined status                                         |
| 401         | 425        | not yet approved                                         |
| 401         | 440        | content is not active                                    |
| 401         | 402        | invalid session                                          |
| 400         | 403        | exceed pin code error count                              |
| 404         | 404        | not Found                                                |
| 401         | 405        | attempted access from non-kakako app                     |
| 401         | 406        | not found user info in db                                |
| 401         | 4001       | invalid access token                                     |
| 401         | 4002       | the expired token                                        |
| 401         | 4003       | fail to get authorization in header                      |
| 401         | 4004       | invalid password                                         |
| 401         | 4005       | account does not have a contract address                 |
| 401         | 4006       | invalid pin code                                         |
| 400         | 4007       | not allow the same code as before                        |
| 400         | 430        | duplicated ci for account creation                       |
| 400         | 431        | inconsistency with previous ci                           |
| 400         | 432        | fail to check Kakao ci                                   |
| 400         | 433        | fail to check Kakao legal name                           |
| 400         | 434        | fail to check Kakao phone number                         |
| 400         | 435        | kakao ci is empty                                        |
| 500         | 500        | internal server error                                    |
| 500         | 501        | fail to send kakao message                               |
| 500         | 5002       | fail to call kakao unlink                                |
| 401         | 4044       | access token does not exist                              |
| 500         | 5003       | kakao server error                                       |

### Glossary

| 용어       | 설명                                                                                                                                          |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Kaia    | [Kaia 블록체인 플랫폼](https://www.kaia.io/) - 기존에는 Klaytn 명칭으로 운영됨                                                                                |
| 스마트 컨트랙트 | 블록체인의 특정 주소(Contract Address)에 있는 코드(functions)와 데이터(state)의 모음                                                                             |
| KAIA     | Kaia 내부에서 통용되는 기본 가상 자산으로 Kaia에 트랜잭션을 전송할 때 필요한 트랜잭션 수수료를 지불하는데 사용. 기존에는 KLAY 명칭으로 사용됨                                                      |
| FT       | 대체 가능 표준 토큰(Fungible Token) 또는 토큰, [KIP-7](https://kips.klaytn.foundation/KIPs/kip-7) 참조                                                    |
| NFT      | 대체 불가 표준 토큰(Non-fungible Token) 또는 카드, [KIP-17](https://kips.klaytn.foundation/KIPs/kip-17) 참조                                              |
| 카드       | Klip에서 사용되는 디지털 자산으로 NFT를 의미                                                                                                                |
| 계정       | 블록체인에서 가상 자산을 보유하는 주체인 동시에 다양한 종류의 트랜잭션을 블록체인 네트워크에 전송하는 주체 (Account)                                                                       |
| 트랜잭션 전송  | 블록체인의 상태를 "변화"시키는 행위이며 주로 블록체인에 데이터를 업로드, 수정, 삭제하거나 블록체인에 스마트 컨트랙트를 배포, 실행하는 행위를 의미                                                         |
| EOA      | 외부 소유 계정(Externally Owned Account)의 의미로, Kaia 상에서 KAIA, NFT, FT를 소유하고 트랜잭션을 전송하는 주체. Kaia의 [계정](https://docs.kaia.io/ko/learn/accounts/) 참조 |
| 서명       | Kaia에서 실행되는 트랜잭션이 전송자 본인에 의해 생성되었다는 것을 증명하기 위한 정보를 생성하는 행위                                                                                  |
| 계정 키     | 서명에 사용하는 계정의 키(AccountKey). 계정 키로 트랜잭션에 서명해야 서명이 정상적으로 완료됨.                                                                                 |

## App2App API <a href="#basics-app2app" id="basics-app2app"></a>

### Authentication

App2App API는 기본적으로 인증을 필요로 하지 않습니다. 하지만 BApp 별로 요청을 구분하기 위해서 request key를 발급하여 API 요청 시 사용합니다. 해당 key를 통해서 Klip 서버에서 요청 내용을 구분하여 컨텍스트를 유지하여 처리합니다. 일반적으로 request key를 발급받고 사용하는 절차는 아래와 같습니다.

* prepare API를 통해 인증 또는 서명할 내용을 전달하고 응답으로 request key를 전달 받습니다.
* 전달받은 request key를 이용하여 Deep Link(지정된 앱을 자동으로 실행하고 홈페이지가 아닌 특정 페이지로 가기 위한 URI)를 호출합니다. Klip 앱이 설치된 경우에는 Klip이 실행되고, 설치 되지 않은 경우에는 사용자가 앱을 다운로드받을 수 있습니다.
* 처리 결과는 result API를 통해서 polling하고 이 때 Query 파라미터 request\_key에 어떤 요청에 대한 처리 결과를 얻고자 하는지를 전달합니다.

### Pagination

보유 카드 내역을 조회할 때 카드의 양의 많은 경우 한 번에 받으면 양이 많기 때문에 여러번 요청해야할 수 있습니다. 이를 위해서 조회 API에서는 결과값에 next\_cursor를 함께 제공합니다. 일반적으로 카드 개수가 100개를 초과한다면 1번 호출 시 100개의 결과와 next\_cursor 값을 받습니다. 나머지 카드를 조회하려면 next\_cursor 값을 query 파라미터 cursor에 전달하여 API를 다시 호출해야합니다.

예들 들어 보유하고 있는 카드를 조회하면,

```bash
//Get card list
curl "https://api.klipwallet.com/v2/a2a/cards?chain=klaytn&sca=SCA&eoa=EOA" \
-H "Content-Type: application/json"
```

아래와 같은 형태의 응답을 받습니다.

```json
{
  "name": "KLIP",
  "symbol_img": "image url",
  "cards": [...],
  "next_cursor": "N2r8KY...XOadEG"
}
```

남은 카드 목록을 조회하려면 next\_cursor을 이용하여 아래와 같이 다시 호출합니다. next\_cursor가 비어있을 때까지 계속 호출하여 보유한 전체 카드 목록을 얻을 수 있습니다.

```bash
//Get card list
curl "https://api.klipwallet.com/v2/a2a/cards?chain=klaytn&sca=SCA&eoa=EOA&cursor=N2r8KY...XOadEG" \
-H "Content-Type: application/json"
```

### SDK

App2App API 기본적으로 REST API를 제공하지만, 각 BApp 개발환경에 맞게 사용할 수 있는 SDK를 제공합니다. 현재 지원하는 SDK 종류는 Android, iOS, 모바일 웹용 JavaScript입니다. 구체적인 내용은 [SDK 페이지](/a2a-sdk)를 참조하십시오.

### Success Codes/Error Codes <a href="#basics-a2a-return-code" id="basics-a2a-return-code"></a>

요청이 성공하면 HTTP code 200을 받습니다. 만약 요청이 정상 처리되지 않으면 400, 500의 HTTP code가 전달됩니다. 400은 요청 데이터가 잘못됐거나 유효하지 않은 request\_key를 사용했을 때 리턴됩니다. 500은 서버에 알 수 없는 장애가 발생했을 때 리턴됩니다. 400 에러는 구체적인 에러 코드와 메시지가 함께 전달됩니다. 자세한 내용은 각 API를 참조하십시오.

에러 메시지는 JSON 포맷으로 전달되며 필드는 아래와 같습니다.

```json
{
  "request_key": "random key",
  "expiration_time": unix timestamp,
  "status": "error",
  "error": {
    "code": int,
    "err": "error message"
  }
}
```

이와 별개로 카드 조회 API (/v2/a2a/cards)는 request key와 관련이 없기 때문에 아래와 같은 형태로 에러가 전달됩니다.

```json
{
  "code": number,
  "err": string
}
```

에러 메시지 종류는 아래와 같습니다.

| Status Code | Error Code | Error Message                                            |
| ----------- | ---------- | -------------------------------------------------------- |
| 400         | 400        | bad request                                              |
| 400         | 6000       | request key does not exist                               |
| 400         | 6001       | request key is expired                                   |
| 400         | 6010       | invalid request type                                     |
| 400         | 6011       | invalid request status                                   |
| 400         | 6200       | execute contract count daily limit exceeded              |
| 400         | 6401       | bapp name is required                                    |
| 400         | 6402       | invalid transaction                                      |
| 400         | 6403       | invalid to address                                       |
| 400         | 6404       | invalid amount                                           |
| 400         | 6405       | invalid contract                                         |
| 400         | 6406       | invalid card id                                          |
| 400         | 6407       | invalid abi                                              |
| 400         | 6408       | invalid params `or` { ivalid params detail info }        |
| 400         | 6409       | invalid value                                            |
| 400         | 6410       | unknown request type                                     |
| 400         | 6411       | invalid from address                                     |
| 400         | 6412       | insufficient funds                                       |
| 400         | 6414       | { tx revert reason }                                     |
| 400         | 6416       | kas\_authorization\_key cannot be used with this request |
| 400         | 6417       | the request is not supported with this chain             |
| 400         | 6418       | invalid kas\_authorization\_key                          |
| 400         | 6500       | address is on the blacklist                              |
| 400         | 6501       | invalid user status                                      |
| 500         | 500        | internal server error                                    |

### Glossary

| Term        | Description                                                                     |
| ----------- | ------------------------------------------------------------------------------- |
| Deep link   | 웹이나 앱에서 홈페이지가 아닌 특정 페이지로 가기위한 URI (Query 파라미터를 통해 요청할 작업을 구분하기 위한 용도로 사용)       |
| Request key | App2App API 요청을 구분하기 위한 랜덤하게 생성된 `a0fee72d-3b1b-43a3-ae0d-e277a1001bef` 형태의 문자열 |

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# REST API

이 페이지는 Klip REST API를 소개합니다.

Klip REST API는 Klip Partners API와 App2App API로 구성됩니다.

## Klip Partners API

Klip Partners API는 카드(NFT)를 발행, 전송, 삭제, 관리하는 기능 구현을 위한 REST API입니다. Klip Partners API는 카드 발행을 위한 Klip Partners 계정 로그인, 계정 관리 기능부터 카드를 발행, 전송, 관리하기 위한 API를 제공합니다.

## App2App API

App2App API는 여러분의 BApp을 Klip과 연동하는 기능 구현을 위한 API입니다. App2App API는 BApp에서 Klip 사용자 계정에 접근하여 KAIA, 카드, 토큰을 전송하거나 스마트 컨트랙트를 실행하는 요청을 수행하는 REST API를 제공합니다. App2App API는 SDK(iOS, Android, JavaScript)로도 제공됩니다.

| 항목                                                   | 설명                                                 |
| ---------------------------------------------------- | -------------------------------------------------- |
| [Klip Partners API](/rest-api/rest-api-card-minting) | 카드를 발행, 전송, 관리하는 기능 제공                             |
| [App2App API](/rest-api/rest-api-a2a)                | BApp과 Klip을 연동해 카드, 토큰, KAIA 전송 및 컨트랙트 실행 요청 기능 제공 |

{% hint style="info" %}
현재 토큰/NFT 전송 및 Smart Contract 실행과 같은 트랜잭션 서명 기능은 카이아, 이더리움, 폴리곤 네트워크에 대해서만 실행이 가능하며, 추후 지원이 확대될 예정입니다. 다른 네트워크에 대한 Klip 연동이 필요하다면 당장은 WalletConnect 사용을 부탁드립니다.
{% endhint %}

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Klip Partners

이 페이지는 Klip Partners에 로그인하고 카드를 발행, 조회, 전송, 삭제하기 위한 API를 소개합니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

## Klip Partners API Reference

### 계정 관리 <a href="#account-management" id="account-management"></a>

계정 관리 API에는 로그인(Sign In), 비밀번호 변경(Change Password), 핀 번호 변경(Change Pin)이 있습니다.

#### Sign In <a href="#sign-in" id="sign-in"></a>

## Sign In

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/partner/auth`

가입을 승인받은 후, 가입 시 입력한 이메일 주소와 비밀번호로 Klip Partners에 로그인합니다.

#### Headers

| Name                                           | Type   | Description      |
| ---------------------------------------------- | ------ | ---------------- |
| Content-Type<mark style="color:red;">\*</mark> | string | application/json |

#### Request Body

| Name                                       | Type   | Description                                                  |
| ------------------------------------------ | ------ | ------------------------------------------------------------ |
| email<mark style="color:red;">\*</mark>    | string | 가입자 이메일 주소이며 로그인 계정으로 사용됩니다.                                 |
| password<mark style="color:red;">\*</mark> | string | 가입자 로그인 비밀번호입니다. 웹사이트에 가입 시 사용한 비밀번호에 SHA256 해시를 적용하여 전송합니다. |

{% tabs %}
{% tab title="200 " %}

```
{
  "email": "ray.kim@groundx.xyz",
  "klaytn_address":0xdc6AE5861a73d852bd3cdD84a4BA7f598A5160F3,
  "contract_address": "0xc94770007dda54cF92009BFF0dE90c06F603a09f",
  "name": "Ray Kim",
  "phone": "01077777777",
  "service_name": "판타지월드레볼루션"
  "access_token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJI...",
  "status" : 1
  "mint_limit": 1000
  "mint_count": 1
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="406" %}

```
"not found user info in db": 계정 정보가 존재하지 않습니다.
```

{% endtab %}

{% tab title="421" %}

```
"banned accounts cannot login": 제재 계정은 로그인할 수 없습니다.
```

{% endtab %}

{% tab title="422" %}

```
"suspended accounts cannot login": 정지 계정은 로그인할 수 없습니다.
```

{% endtab %}

{% tab title="426" %}

```
"not yet approved": 아직 가입이 승인되지 않았습니다.
```

{% endtab %}

{% tab title="4004" %}

```
"invalid password": 비밀번호가 일치하지 않습니다.
```

{% endtab %}

{% tab title="기타" %}

```
로그인할 수 없습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
[Klip Partners](https://partners.klipwallet.com) 웹사이트는 허가된 사용자만 접근 가능하나, Klip Partners 서비스가 2024년 7월 31일자로 종료되어 현재는 신규 가입 신청을 받지 않고 있습니다. 아울러 기존 사용자 역시 2024년 8월 1일부터 Klip Partners API를 호출할 수 없습니다.
{% endhint %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/partner/auth" \
-d '{"email":"ray.kim@groundx.xyz", "password":"C01069C9ABB6EA7DA49AE418A24BBEF3AD67170DDCD20AC7C76084A5A85E4057"}' \
-H "Content-Type: application/json"
```

**Response Details**

| 이름                | 타입     | 설명                                                                                            |
| ----------------- | ------ | --------------------------------------------------------------------------------------------- |
| email             | string | 가입자 이메일 주소이며 로그인 계정으로 사용됩니다.                                                                  |
| klaytn\_address   | string | 가입자 Kaia [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다. 호환성 유지를 위해 `klaytn` 명칭이 사용됩니다. |
| contract\_address | string | 카드를 발행하는 [SCA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다.                                |
| name              | string | 가입자 이름이며 사업자 또는 법인 이름을 사용합니다.                                                                 |
| phone             | string | 가입자 전화번호입니다.                                                                                  |
| service\_name     | string | 가입자가 제공하는 BApp 서비스 이름입니다.                                                                     |
| access\_token     | string | JWT 형식으로 API 호출을 허용하기 위해 발급된 인증 토큰입니다.                                                        |
| status            | number | 계정 상태코드입니다.                                                                                   |
| mint\_limit       | number | 계정이 이번 달에 발행할 수 있는 최대 카드 개수입니다.                                                               |
| mint\_count       | number | 계정이 이번 달에 발행한 카드 개수입니다.                                                                       |

{% hint style="info" %}
`status`는 가입 승인 전에는 20, 가입 승인 후에는 1의 값을 가집니다.\
`access_token`은 발급받은 지 24시간이 지나면 만료되므로 재발급받아야 합니다.\
`mint_count`와 `mint_limit`은 매달 1일 초기화됩니다.
{% endhint %}

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#sign-in)을 확인하십시오.

#### Change Password <a href="#change-password" id="change-password"></a>

## Change Password

<mark style="color:orange;">`PUT`</mark> `https://api.klipwallet.com/v2/partner/?opt=password`

가입 시 입력한 비밀번호를 변경합니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                            | Type   | Description       |
| ----------------------------------------------- | ------ | ----------------- |
| old\_password<mark style="color:red;">\*</mark> | string | 기존에 사용하던 비밀번호입니다. |
| new\_password<mark style="color:red;">\*</mark> | string | 새롭게 사용할 비밀번호입니다.  |

{% tabs %}
{% tab title="200 " %}

```
{}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4004" %}

```
"invalid password": 비밀번호가 일치하지 않습니다.
```

{% endtab %}

{% tab title="기타" %}

```
비밀번호 변경에 실패했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X PUT "https://api.klipwallet.com/v2/partner/?opt=password" \
-d '{"old_password":"HASHED_OLD_PASSWORD", "new_password":"HASHED_NEW_PASSWORD"}' \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#change-password-and-pin)을 확인하십시오.

#### Change PIN <a href="#change-pin" id="change-pin"></a>

## Change PIN

<mark style="color:orange;">`PUT`</mark> `https://api.klipwallet.com/v2/partner/pin`

가입 시 입력한 핀 번호를 변경합니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                       | Type   | Description                                      |
| ------------------------------------------ | ------ | ------------------------------------------------ |
| old\_pin<mark style="color:red;">\*</mark> | string | 기존에 사용하던 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다. |
| new\_pin<mark style="color:red;">\*</mark> | string | 새롭게 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다.  |

{% tabs %}
{% tab title="200 " %}

```
{}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="403" %}

```
"exceed pin code error count": 핀 번호 입력 오류 횟수가 지정된 한도를 초과하였습니다.
```

{% endtab %}

{% tab title="4006" %}

```
"invalid pin code": 기존 핀 번호가 일치하지 않습니다.
```

{% endtab %}

{% tab title="기타" %}

```
핀 번호를 변경하지 못했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X PUT "https://api.klipwallet.com/v2/partner/pin" \
-d '{"old_pin":"HASHED_OLD_PIN_NUMBER", "new_pin":"HASHED_NEW_PIN_NUMBER"}' \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#change-password-and-pin)을 확인하십시오.

### 카드 관리 <a href="#card-management" id="card-management"></a>

카드 관리 API에는 카드 이미지 업로드(Upload Image), 모든 사용자에게 카드 발행(Mint Card To User), Klip 회원에게 카드 발행(Mint Card To Klip Member), 모든 사용자에게 카드 전송(Send Card To User), Klip 회원에게 카드 전송(Send Card To Klip Member), 카드 정보 불러오기(Get Card Information By Bapp, Get Card Information), 카드 삭제(Delete Card)가 있습니다.

#### Upload Image <a href="#upload-image" id="upload-image"></a>

## Upload Image

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/wallet/image`

카드에 사용할 이미지를 업로드합니다.

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다.    |
| Content-Type<mark style="color:red;">\*</mark>  | string | multipart/form-data |

#### Request Body

| Name                                     | Type   | Description                       |
| ---------------------------------------- | ------ | --------------------------------- |
| upload<mark style="color:red;">\*</mark> | string | 업로드할 이미지 파일명입니다. 파일 경로를 포함해야 합니다. |

{% tabs %}
{% tab title="200 " %}

```
{"image": "https://url_path_to_img_file/image.png"}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
이미지를 업로드하지 못했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/wallet/image" \
-F upload=@./imagefile.png \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: multipart/form-data"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#upload-image)을 확인하십시오.

#### Upload NFT Resource <a href="#upload-nftresource" id="upload-nftresource"></a>

## Upload NFT resource

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/wallet/nftResource`

카드에 사용할 리소스를 업로드합니다. `animation_url` 필드에 설정할 동영상 파일의 경우 크기가 10MiB로 제한됩니다.

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다.    |
| Content-Type<mark style="color:red;">\*</mark>  | string | multipart/form-data |

#### Request Body

| Name                                     | Type   | Description                   |
| ---------------------------------------- | ------ | ----------------------------- |
| upload<mark style="color:red;">\*</mark> | string | 업로드할 파일명입니다. 파일 경로를 포함해야 합니다. |

{% tabs %}
{% tab title="200 " %}

```
{"url": "https://url_path_to_file/file.mp4"}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4100" %}

```
"upload animation file limit exceeded": 동영상 파일의 경우 제한된 크기 10MiB를 넘었습니다. 파일 크기를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4101" %}

```
"upload animation file extension is not support": 지원하지 않는 동영상 포맷입니다.
```

{% endtab %}

{% tab title="기타" %}

```
파일을 업로드하지 못했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/wallet/nftResource" \
-F upload=@./file.mp4 \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: multipart/form-data"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#upload-nftresource)을 확인하십시오.

#### Upload Secure NFT Resource <a href="#upload-secure-nftresource" id="upload-secure-nftresource"></a>

## Upload secure NFT resource

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/wallet/nftResource/secure`

카드에 사용할 소유자 전용 리소스를 업로드합니다. `upload` 필드에 설정할 수 있는 파일 용량은 최대 10MiB입니다. 가로x세로 각각 23000px 이하 카드 이미지를 사용해야 Klip에 정상적으로 노출됩니다.

#### Headers

| Name                                            | Type   | Description         |
| ----------------------------------------------- | ------ | ------------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다.    |
| Content-Type<mark style="color:red;">\*</mark>  | string | multipart/form-data |

#### Request Body

| Name                                     | Type   | Description                   |
| ---------------------------------------- | ------ | ----------------------------- |
| upload<mark style="color:red;">\*</mark> | string | 업로드할 파일명입니다. 파일 경로를 포함해야 합니다. |

{% tabs %}
{% tab title="200 " %}

```
{"filename": "{uuid}.{extension}"}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4100" %}

```
"upload animation file limit exceeded": 동영상 파일의 경우 제한된 크기 10MiB를 넘었습니다. 파일 크기를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4101" %}

```
"upload animation file extension is not support": 지원하지 않는 동영상 포맷입니다.
```

{% endtab %}

{% tab title="기타" %}

```
파일을 업로드하지 못했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/wallet/nftResource/secure" \
-F upload=@./file.mp4 \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: multipart/form-data"
```

#### Mint Card to User <a href="#mint-card-to-user" id="mint-card-to-user"></a>

## Mint Card To User

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/wallet/mint`

Klip Partners에 사용자 정보를 보내고 카드를 발행합니다. 사용자 EOA로 발행됩니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                                | Type    | Description                                                                                                                                                             |
| --------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| pin<mark style="color:red;">\*</mark>               | string  | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다.                                                                                                                         |
| to\_address<mark style="color:red;">\*</mark>       | array   | 카드를 발행받을 EOA 주소들이 담긴 `string` 배열입니다.                                                                                                                                    |
| contract\_address<mark style="color:red;">\*</mark> | string  | 카드를 발행하는 SCA 주소입니다.                                                                                                                                                     |
| name<mark style="color:red;">\*</mark>              | string  | 카드 이름입니다.                                                                                                                                                               |
| description<mark style="color:red;">\*</mark>       | string  | 카드에 관한 설명입니다.                                                                                                                                                           |
| image<mark style="color:red;">\*</mark>             | string  | 카드에 사용할 이미지 URL 주소입니다.                                                                                                                                                  |
| animation\_url                                      | string  | 카드에 사용할 동영상 URL 주소입니다. 지원하는 파일 확장자는 `.mp4`입니다. H.264 코덱이 아니거나 해상도가 `3840x2160`을 넘는 경우 재생되지 않을 수 있습니다.                                                                   |
| background\_color                                   | string  | 카드 배경에 사용할 RGB 색상 코드입니다.                                                                                                                                                |
| sendable                                            | boolean | TRUE이면 발행한 카드를 Klip에서 타인에게 전송 가능합니다.                                                                                                                                    |
| send\_friend\_only                                  | boolean | TRUE이면 발행한 카드를 Klip에서 카카오톡 친구에게만 전송 가능합니다. 현재 Klip 내에서 일시적으로 친구 전송이 제공되지 않고 있으므로 FALSE로 설정합니다.                                                                          |
| group\_name                                         | string  | 카드를 그룹핑할 때 사용하는 카드 그룹 이름입니다.                                                                                                                                            |
| group\_icon                                         | string  | 카드 그룹 아이콘으로 사용할 이미지 URL 주소입니다.                                                                                                                                          |
| hashtags                                            | array   | 해시태그들이 담긴 `string` 배열입니다. 카드에 해시태그를 달면 특정 주제, 내용을 쉽게 찾을 수 있습니다.                                                                                                         |
| layout                                              | string  | 카드를 보여주는 방식입니다. 예를 들어, 정사각형 이미지는 `general`, 가로가 더 긴 이미지는 `horizontal` 세로가 긴 이미지는 `vertical`로 설정할 수 있습니다. 기본값은 `general`입니다.                                             |
| external\_link                                      | string  | Klip 외부로 연결되는 URL 주소입니다. (최대 길이:255)                                                                                                                                    |
| custom\_links                                       | array   | Klip 외부로 연결되는 URL 주소들이 담긴 `object` 배열 입니다. `display_name`에 노출할 속성명, `value`에 속성값을 쌍을 이뤄 지정합니다. Klip의 NFT 상세 화면에서 외부로 연결되는 링크가 제공됩니다. (배열의 최대 크기: 10개, 각 링크의 최대 길이: 255) |
| qr\_code                                            | string  | QR Code가 그려진 이미지 URL입니다 (최대 길이:255)                                                                                                                                     |
| bar\_code                                           | string  | Bar Code가 그려진 이미지 URL입니다. (최대 길이:255)                                                                                                                                   |
| attributes                                          | array   | 발행할 카드 속성값들이 담긴 `object` 배열입니다.                                                                                                                                         |
| secure                                              | object  | 카드 소유자에게만 보여줄 정보를 담은 `object`입니다. `bar_code`, `qr_code`, `images`, `animations`, 및 `attributes` 필드를 선택적으로 설정할 수 있습니다.                                                   |
| status\_url                                         | string  | 카드 상태 정보를 담고 있는 외부 URL입니다. 해당 URL에서는 JSON 값을 반환해야하고, 필수적으로 bool type의 `valid` 필드와 선택적으로 array type의 `attributes` 필드를 설정할 수 있습니다.                                        |

{% tabs %}
{% tab title="200 " %}

```
{
  "hash": "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97"
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
정상적인 카드 발행에 실패했습니다.
일부 카드는 발행되었을 수 있으니 ‘보유 카드 목록’ 에서 보유 목록을 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

```
//attributes 예시
"attributes":[
    {
      "trait_type": "Sword", 
      "value": "Iron Short Sword"
    }, 
    {
      "trait_type": "Magic Type", 
      "value": "Fire"
    }, 
    {
      "trait_type": "Sword Level", 
      "value": "5"
    }, 
    {
      "trait_type": "Magic Level", 
      "value": "2"
    }
]
```

```
//secure 예시 ()
"secure": {
    // 일반적으로 bar_code 또는 qr_code 둘 중 하나만 설정
    "bar_code": "1234 ABCD 5678 EFGH 90IJ",
    "qr_code": "https://your-domain.com?key=1234",

    // 사전에 업로드한 secure 이미지의 UUID를 사용
    // 배열 형식이지만 현재 클립에서 소유자 전용 이미지는 한 개만 추가 노출되므로 하나만 인자로 입력
    "images": [
      {"low_resolution" : "{uploaded-filename-1}.png"}
    ],
    
    // 사전에 업로드한 secure 동영상의 UUID를 사용
    // 배열 형식이지만 현재 클립에서 소유자 전용 동영상은 한 개만 추가 노출되므로 하나만 인자로 입력
    // animations를 등록하는 경우, 반드시 images도 "썸네일" 역할로써 등록 필요
    "animations": [
      {"low_resolution" : "{uploaded-filename-2}.mp4"}
    ],

    "attributes":[
        {
            "trait_type": "Sword",
            "value": "Iron Short Sword"
        },
        {
            "trait_type": "Magic Type",
            "value": "Fire"
        },
        {
            "trait_type": "Sword Level",
            "value": "5"
        },
        {
            "trait_type": "Magic Level",
            "value": "2"
        }
    ]
}
```

```
//status_url 예시
status_url: "https://your-domain.com?key=1234"

//status_url 호출 시 응답값 예시
{
    "valid": true,
    "attributes":[
        {
            "trait_type": "Sword",
            "value": "Iron Short Sword"
        },
        {
            "trait_type": "Magic Type",
            "value": "Fire"
        },
        {
            "trait_type": "Sword Level",
            "value": "5"
        },
        {
            "trait_type": "Magic Level",
            "value": "2"
        }
    ]
}
```

```
custom_links: [
    {
        "display_name": "고객센터",
        "value": "https://customersupport.com"
    },
    {
        "display_name": "홈페이지",
        "value": "https://homepage.com"
    }
]
```

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/wallet/mint" \
-d @./mint_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

**Request Details for** `secure`

| 이름         | 타입     | 설명                                                                                                                                                                                     |
| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| bar\_code  | string | bar code로 표시할 문자열 값입니다. 기본적으로 CODE 128 형식을 사용합니다. optional 필드입니다. (최대 길이:20, ' '(공백) 또는 '-' 문자 제외)                                                                                     |
| qr\_code   | string | qr code로 표시할 문자열 값입니다. optional 필드입니다. (최대 길이:255)                                                                                                                                     |
| attributes | array  | 카드 속성값들이 담긴 `object` 배열입니다. optional 필드입니다.                                                                                                                                            |
| images     | array  | secure 이미지 객체들의 배열입니다. 이미지 객체는 `low_resolution`과 (또는) `high_resolution` 값을 가지며 각각 저해상도 이미지, 고해상도 이미지 파일명을 기록합니다. secure 이미지 업로드 방법은 Upload Secure NFT Resource를 참조하세요. optional 필드입니다. |
| animations | array  | secure 동영상 객체들의 배열입니다. 동영상 객체는 `low_resolution`과 (또는) `high_resolution` 값을 가지며 각각 저해상도 동영상, 고해상도 동영상 파일명을 기록합니다. secure 동영상 업로드 방법은 Upload Secure NFT Resource를 참조하세요. optional 필드입니다. |

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#mint-card-to-user)을 확인하십시오.

#### Mint Card to Klip Member <a href="#mint-card-to-klip-member" id="mint-card-to-klip-member"></a>

## Mint Card To Klip Member

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/wallet/mint/person`

Klip Partners에 Klip 회원 정보를 보내고 카드를 발행합니다. `to_person`에 입력한 실명과 전화번호를 가진 Klip 회원 EOA로 발행됩니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                                | Type    | Description                                                                                                                                                             |
| --------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| pin<mark style="color:red;">\*</mark>               | string  | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다.                                                                                                                         |
| to\_person<mark style="color:red;">\*</mark>        | array   | 카드를 발행받을 실명과 전화번호 쌍이 담긴 2차원 배열입니다.                                                                                                                                      |
| contract\_address<mark style="color:red;">\*</mark> | string  | 카드를 발행하는 SCA 주소입니다.                                                                                                                                                     |
| name<mark style="color:red;">\*</mark>              | string  | 카드 이름입니다.                                                                                                                                                               |
| description<mark style="color:red;">\*</mark>       | string  | 카드에 관한 설명입니다.                                                                                                                                                           |
| image<mark style="color:red;">\*</mark>             | string  | 카드에 사용할 이미지 URL 주소입니다.                                                                                                                                                  |
| animation\_url                                      | string  | 카드에 사용할 동영상 URL 주소입니다. 지원하는 파일 확장자는 `.mp4`입니다. H.264 코덱이 아니거나 해상도가 `3840x2160`을 넘는 경우 재생되지 않을 수 있습니다.                                                                   |
| background\_color                                   | string  | 카드 배경에 사용할 RGB 색상 코드입니다.                                                                                                                                                |
| sendable                                            | boolean | TRUE이면 발행한 카드를 Klip에서 타인에게 전송 가능합니다.                                                                                                                                    |
| send\_friend\_only                                  | boolean | TRUE이면 발행한 카드를 Klip에서 카카오톡 친구에게만 전송 가능합니다. 현재 Klip 내에서 일시적으로 친구 전송이 제공되지 않고 있으므로 FALSE로 설정합니다.                                                                          |
| group\_name                                         | string  | 카드를 그룹핑할 때 사용하는 카드 그룹 이름입니다.                                                                                                                                            |
| group\_icon                                         | string  | 카드 그룹 아이콘으로 사용할 이미지 URL 주소입니다.                                                                                                                                          |
| hashtags                                            | array   | 해시태그들이 담긴 `string` 배열입니다. 카드에 해시태그를 달면 특정 주제, 내용을 쉽게 찾을 수 있습니다.                                                                                                         |
| layout                                              | string  | 카드를 보여주는 방식입니다. 예를 들어, 정사각형 이미지는 `general`, 가로가 더 긴 이미지는 `horizontal` 세로가 긴 이미지는 `vertical`로 설정할 수 있습니다. 기본값은 `general`입니다.                                             |
| external\_link                                      | string  | Klip 외부로 연결되는 URL 주소입니다. (최대 길이:255)                                                                                                                                    |
| custom\_links                                       | array   | Klip 외부로 연결되는 URL 주소들이 담긴 `object` 배열 입니다. `display_name`에 노출할 속성명, `value`에 속성값을 쌍을 이뤄 지정합니다. Klip의 NFT 상세 화면에서 외부로 연결되는 링크가 제공됩니다. (배열의 최대 크기: 10개, 각 링크의 최대 길이: 255) |
| qr\_code                                            | string  | QR Code가 그려진 이미지 URL 주소입니다. (최대 길이:255)                                                                                                                                 |
| bar\_code                                           | string  | Bar Code가 그려진 이미지 URL 주소입니다. (최대 길이:255)                                                                                                                                |
| attributes                                          | array   | 발행할 카드 속성값들이 담긴 `object` 배열입니다.                                                                                                                                         |
| secure                                              | object  | 카드 소유자에게만 보여줄 정보를 담은 `object`입니다. `bar_code`, `qr_code`, `images`, `animations`, 및 `attributes` 필드를 선택적으로 설정할 수 있습니다.                                                   |
| status\_url                                         | string  | 카드 상태 정보를 담고 있는 외부 URL입니다. 해당 URL에서는 JSON 값을 반환해야하고, 필수적으로 bool type의 `valid` 필드와 선택적으로 array type의 `attributes` 필드를 설정할 수 있습니다.                                        |

{% tabs %}
{% tab title="200 " %}

```
{
  "hash": "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97",
  "result": [["홍길동", "010-1111-2222", "success", ""], ["김춘향", "010-3333-4444", "fail", "phone number does not exist"], ...]
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
정상적인 카드 발행에 실패했습니다.
일부 카드는 발행되었을 수 있으니 ‘보유 카드 목록’ 에서 보유 목록을 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

```
//attributes 예시
attributes:[
    {
      "trait_type": "Sword", 
      "value": "Iron Short Sword"
    }, 
    {
      "trait_type": "Magic Type", 
      "value": "Fire"
    }, 
    {
      "trait_type": "Sword Level", 
      "value": "5"
    }, 
    {
      "trait_type": "Magic Level", 
      "value": "2"
    }
]
```

```
//secure 예시
"secure": {
    // 일반적으로 bar_code 또는 qr_code 둘 중 하나만 설정
    "bar_code": "1234 ABCD 5678 EFGH 90IJ",
    "qr_code": "https://your-domain.com?key=1234",

    // 사전에 업로드한 secure 이미지의 UUID를 사용
    // 배열 형식이지만 현재 클립에서 소유자 전용 이미지는 한 개만 추가 노출되므로 하나만 인자로 입력
    "images": [
      {"low_resolution" : "{uploaded-filename-1}.png"}
    ],
    
    // 사전에 업로드한 secure 동영상의 UUID를 사용
    // 배열 형식이지만 현재 클립에서 소유자 전용 동영상은 한 개만 추가 노출되므로 하나만 인자로 입력
    // animations를 등록하는 경우, 반드시 images도 "썸네일" 역할로써 등록 필요
    "animations": [
      {"low_resolution" : "{uploaded-filename-2}.mp4"}
    ],

    "attributes":[
        {
            "trait_type": "Sword",
            "value": "Iron Short Sword"
        },
        {
            "trait_type": "Magic Type",
            "value": "Fire"
        },
        {
            "trait_type": "Sword Level",
            "value": "5"
        },
        {
            "trait_type": "Magic Level",
            "value": "2"
        }
    ]
}
```

```
//status_url 예시
status_url: "https://your-domain.com?key=1234"

//status_url 호출 시 응답값 예시
{
    "valid": true,
    "attributes":[
        {
            "trait_type": "Sword",
            "value": "Iron Short Sword"
        },
        {
            "trait_type": "Magic Type",
            "value": "Fire"
        },
        {
            "trait_type": "Sword Level",
            "value": "5"
        },
        {
            "trait_type": "Magic Level",
            "value": "2"
        }
    ]
}
```

```
custom_links: [
    {
        "display_name": "고객센터",
        "value": "https://customersupport.com"
    },
    {
        "display_name": "홈페이지",
        "value": "https://homepage.com"
    }
]
```

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/wallet/mint/person" \
-d @./mint_person_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

**Request Details for** `secure`

| 이름         | 타입     | 설명                                                                                                                                                                                     |
| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| bar\_code  | string | bar code로 표시할 문자열 값입니다. 기본적으로 CODE 128 형식을 사용합니다. optional 필드입니다. (최대 길이:20, ' '(공백) 또는 '-' 문자 제외)                                                                                     |
| qr\_code   | string | qr code로 표시할 문자열 값입니다. optional 필드입니다. (최대 길이:255)                                                                                                                                     |
| attributes | array  | 카드 속성값들이 담긴 `object` 배열입니다. optional 필드입니다.                                                                                                                                            |
| images     | array  | secure 이미지 객체들의 배열입니다. 이미지 객체는 `low_resolution`과 (또는) `high_resolution` 값을 가지며 각각 저해상도 이미지, 고해상도 이미지 파일명을 기록합니다. secure 이미지 업로드 방법은 Upload Secure NFT Resource를 참조하세요. optional 필드입니다. |
| animations | array  | secure 동영상 객체들의 배열입니다. 동영상 객체는 `low_resolution`과 (또는) `high_resolution` 값을 가지며 각각 저해상도 동영상, 고해상도 동영상 파일명을 기록합니다. secure 동영상 업로드 방법은 Upload Secure NFT Resource를 참조하세요. optional 필드입니다. |

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#mint-card-to-klip-member)을 확인하십시오.

#### Get Mint Count <a href="#mint-count" id="mint-count"></a>

## Get Mint Count

<mark style="color:blue;">`GET`</mark> `https://api.klipwallet.com/v2/wallet/mint/count`

이번 달에 파트너 계정으로 발행한 총 카드 개수를 조회할 수 있습니다. 이 값은 매월 1일에 0으로 초기화됩니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

{% tabs %}
{% tab title="200 " %}

```
{
  "mint_count": 10
}
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X GET "https://api.klipwallet.com/v2/wallet/mint/count" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

**Response Details**

| 이름          | 타입     | 설명                      |
| ----------- | ------ | ----------------------- |
| mint\_count | number | 이번 달 현재까지 발행한 카드 개수입니다. |

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#mint-count)을 확인하십시오.

#### Send Card to User <a href="#send-card-to-user" id="send-card-to-user"></a>

## Send Card To User

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/wallet/nft/:nft_id/:card_id/send`

카드를 다른 사용자에게 보냅니다. 전송 시 사용자 EOA를 사용합니다.

#### Path Parameters

| Name                                       | Type   | Description                      |
| ------------------------------------------ | ------ | -------------------------------- |
| nft\_id<mark style="color:red;">\*</mark>  | string | BApp에 있는 카드를 생성한 스마트 컨트랙트 ID입니다. |
| card\_id<mark style="color:red;">\*</mark> | string | BApp에 있는 카드 ID입니다.               |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                          | Type   | Description                                     |
| --------------------------------------------- | ------ | ----------------------------------------------- |
| pin<mark style="color:red;">\*</mark>         | string | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다. |
| to\_address<mark style="color:red;">\*</mark> | string | 카드를 받는 상대방 EOA 주소입니다.                           |
| card\_name<mark style="color:red;">\*</mark>  | string | 보낼 카드 이름입니다.                                    |

{% tabs %}
{% tab title="200 " %}

```
//전송 성공 예시
{ to_address: "0xb1764B96da889..." , fail_count: 0, tx_hash: "0x7cf09602cebb..."}
//잘못된 핀 번호를 1회 입력 시
{fail_count: 1}
//잘못된 핀 번호를 2회 입력 시
{fail_count: 2}
//잘못된 핀 번호 입력 횟수 한도는 5회입니다. 잘못된 핀 번호를 5회 입력하고
//정확한 핀 번호를 6회째에 입력해도 다음 결과를 받음에 유의하십시오.
{fail_count: 6}
//fail_count의 max값은 현재 6입니다.
//잘못된 핀 번호를 7회 입력 시
{fail_count: 6}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Klip 사용자에게 카드를 전송 시`card_name`을 입력해야 받는 사람에게 카드 이름이 표시됩니다.
{% endhint %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/wallet/nft/60/1/send" \
-d @./send_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#send-card-to-user)을 확인하십시오.

#### Send Card to Klip Member <a href="#send-card-to-klip-member" id="send-card-to-klip-member"></a>

## Send Card To Klip Member

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/wallet/nft/:nft_id/:card_id/send/person`

카드를 Klip 회원에게 보냅니다. `to_person`에 입력한 실명과 전화번호를 가진 Klip 회원 EOA로 보냅니다.

#### Path Parameters

| Name                                       | Type   | Description                      |
| ------------------------------------------ | ------ | -------------------------------- |
| nft\_id<mark style="color:red;">\*</mark>  | string | BApp에 있는 카드를 생성한 스마트 컨트랙트 ID입니다. |
| card\_id<mark style="color:red;">\*</mark> | string | BApp에 있는 카드 ID입니다.               |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                         | Type   | Description                                     |
| -------------------------------------------- | ------ | ----------------------------------------------- |
| pin<mark style="color:red;">\*</mark>        | string | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다. |
| to\_person<mark style="color:red;">\*</mark> | array  | 카드를 받는 상대방의 실명과 전화번호가 있는 `string` 배열입니다.        |
| card\_name<mark style="color:red;">\*</mark> | string | 보낼 카드 이름입니다.                                    |

{% tabs %}
{% tab title="200 " %}

```
//전송 성공 예시
{ fail_count: 0, tx_hash: "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97" }
//잘못된 핀 번호를 1회 입력 시
{fail_count: 1, tx_hash: ""}
//잘못된 핀 번호를 2회 입력 시
{fail_count: 2, tx_hash: ""}
//잘못된 핀 번호 입력 횟수 한도는 5회입니다. 잘못된 핀 번호를 5회 입력하고
//정확한 핀 번호를 6회째에 입력해도 다음 결과를 받음에 유의하십시오.
{fail_count: 6, tx_hash: ""}
//fail_count의 max값은 현재 6입니다.
//잘못된 핀 번호를 7회 입력 시
{fail_count: 6, tx_hash: ""}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Klip 사용자에게 카드를 전송 시`card_name`을 입력해야 받는 사람에게 카드 이름이 표시됩니다.
{% endhint %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/wallet/nft/60/1/send/person" \
-d @./send_person_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#send-card-to-klip-member)을 확인하십시오.

#### (deprecated) Get Card Information by Bapp <a href="#get-card-information-by-bapp" id="get-card-information-by-bapp"></a>

{% hint style="warning" %}
본 API의 경우, 클립의 자산 리스팅 정책 변경에 따라 일부 새로운 카드는 조회가 불가능할 수도 있습니다. 대신 [App2App의 Get Card Information](/rest-api/rest-api-a2a#get-card-information) API 사용을 권장합니다.
{% endhint %}

## Get Card Information By BApp

<mark style="color:blue;">`GET`</mark> `https://api.klipwallet.com/v2/wallet/bapp?cursor=`

내가 소유한 카드 목록을 얻습니다. 보유한 카드들은 BApp별로 묶여 출력됩니다.

#### Query Parameters

| Name   | Type   | Description                            |
| ------ | ------ | -------------------------------------- |
| cursor | string | BApp이 100개 이상이면 다음 100개 정보를 받는 커서값입니다. |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

{% tabs %}
{% tab title="200 " %}

```
{
    "bapps": [
        {
            "id": 2,
            "name": "bapp2",
            "bapp_img": "/img/bapp-icon2.svg",
            "category_id": 2,
            "nft_order_no": 1,
            "summary": "summary",
            "card_count": 10,
            "nft_id": 52,
            "cards": [
                    {
                        "created_at": 1580300503,
                        "updated_at": 1580300503,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 18,
                        "card_uri": "https://.../card_meta.json",
                        "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },
                    ...
                ],
            "cards_next_cursor": ""
        },
        ...
    ],
    "next_cursor": ""
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
BApp별로 보유한 카드 목록을 불러오지 못했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl "https://api.klipwallet.com/v2/wallet/bapp?cursor=mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

**Response Details for** `bapps[i]`

| 이름                  | 타입     | 설명                                            |
| ------------------- | ------ | --------------------------------------------- |
| id                  | number | 이 BApp ID입니다.                                 |
| name                | string | 이 BApp 이름입니다.                                 |
| bapp\_img           | string | 이 BApp 대표 이미지 파일 주소입니다.                       |
| category\_id        | number | 이 BApp 카테고리 분류 코드입니다.                         |
| nft\_order\_no      | number | Klip 카드 목록에서 카드 그룹이 노출되는 순서입니다.               |
| summary             | string | 이 BApp에 관한 한 줄 설명입니다.                         |
| card\_count         | number | 보유한 모든 카드중 이 BApp에서 쓰이는 카드 개수입니다.             |
| nft\_id             | number | NFT ID입니다. NFT는 이 카드를 블록체인에 구현하는 스마트 컨트랙트입니다. |
| cards               | array  | 각 카드 정보를 담은 `object` 배열입니다.                   |
| cards\_next\_cursor | string | 카드가 100개 이상이면 다음 100개 정보를 불러올 커서값입니다.         |
| next\_cursor        | string | BApp이 100개 이상이면 다음 100개 정보를 불러올 커서값입니다.       |

**Response Details for** `bapps[i].cards[i]`

| 이름                | 타입     | 설명                                                                      |
| ----------------- | ------ | ----------------------------------------------------------------------- |
| created\_at       | number | 카드가 발행된 시간입니다.                                                          |
| updated\_at       | number | 카드가 업데이트된 시간입니다.                                                        |
| owner             | string | 이 계정 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다.              |
| sender            | string | 이 계정으로 카드를 보낸 사람의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다. |
| card\_id          | number | 카드 ID입니다.                                                               |
| card\_uri         | string | 카드 메타데이터가 담긴 JSON 파일 URL입니다.                                            |
| transaction\_hash | string | 카드를 발행한 스마트 컨트랙트 트랜잭션 해시입니다.                                            |

자세한 내용은 [튜토리얼1](/tutorial/tutorial-card-minting#get-card-information-by-bapp), [튜토리얼2](/tutorial/tutorial-card-minting#get-extra-card-information)를 확인하십시오.

#### Get Card Information <a href="#get-card-information" id="get-card-information"></a>

## Get Card Information

<mark style="color:blue;">`GET`</mark> `https://api.klipwallet.com/v2/wallet/nft/:nft_id?cursor=`

소유한 카드의 상세 정보를 얻습니다.

#### Path Parameters

| Name                                      | Type   | Description                                   |
| ----------------------------------------- | ------ | --------------------------------------------- |
| nft\_id<mark style="color:red;">\*</mark> | string | NFT ID입니다. NFT는 이 카드를 블록체인에 구현하는 스마트 컨트랙트입니다. |

#### Query Parameters

| Name   | Type   | Description                                                       |
| ------ | ------ | ----------------------------------------------------------------- |
| isAll  | bool   | TRUE이면 내가 소유한 모든 카드 정보를 한 번에 받습니다. `cursor` 파라미터와는 함께 사용할 수 없습니다. |
| cursor | string | 카드 정보를 100개씩 나누어 받기 위한 커서값입니다. `isAll` 파라미터와는 함께 사용할 수 없습니다.      |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

{% tabs %}
{% tab title="200 " %}

```
{
    "name": "conan",
    "symbol_img": "",
    "cards": [
      {
          "created_at": 1580300503,
          "updated_at": 1580300503,
          "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
          "sender": "0x0000000000000000000000000000000000000000",
          "card_id": 18,
          "card_uri": "https://.../card_meta.json",
          "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
      },
    ],
    "next_cursor": "mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL",
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 정보를 불러오지 못했습니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl "https://api.klipwallet.com/v2/wallet/nft/52?cursor=mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

**Response Details**

| 이름           | 타입     | 설명                                    |
| ------------ | ------ | ------------------------------------- |
| name         | string | 카드 이름입니다.                             |
| symbol\_img  | string | 카드에 사용하는 이미지 URL 주소입니다.               |
| cards        | array  | 각 카드 정보를 담은 `object` 배열입니다.           |
| next\_cursor | string | 카드가 100개 이상이면 다음 100개 정보를 불러올 커서값입니다. |

**Response Details for** `cards[i]`

| 이름                | 타입     | 설명                                                                      |
| ----------------- | ------ | ----------------------------------------------------------------------- |
| created\_at       | number | 카드가 발행된 시간입니다.                                                          |
| updated\_at       | number | 카드가 업데이트된 시간입니다.                                                        |
| owner             | string | 이 계정 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다.              |
| sender            | string | 이 계정으로 카드를 보낸 사람의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다. |
| card\_id          | number | 카드 ID입니다.                                                               |
| card\_uri         | string | 카드 메타데이터가 담긴 JSON 파일 URL입니다.                                            |
| transaction\_hash | string | 카드를 발행한 스마트 컨트랙트 트랜잭션 해시입니다.                                            |

자세한 내용은 [튜토리얼1](/tutorial/tutorial-card-minting#get-card-information), [튜토리얼2](/tutorial/tutorial-card-minting#get-extra-card-information)를 확인하십시오.

#### Delete Card <a href="#delete-card" id="delete-card"></a>

## Delete Card

<mark style="color:red;">`DELETE`</mark> `https://api.klipwallet.com/v2/wallet/nft`

발행한 카드를 삭제합니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                                | Type   | Description                                     |
| --------------------------------------------------- | ------ | ----------------------------------------------- |
| pin<mark style="color:red;">\*</mark>               | string | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다. |
| card\_id<mark style="color:red;">\*</mark>          | number | 카드 ID입니다.                                       |
| contract\_address<mark style="color:red;">\*</mark> | string | 카드를 발행한 SCA 주소입니다.                              |

{% tabs %}
{% tab title="200 " %}

```
{
    "hash": "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97"
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 삭제에 실패하였습니다. 정확한 정보를 확인하기 위해 현재 소유한 카드 목록을 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
발행한 카드만 삭제할 수 있으며, 다른 사람에게 보낸 카드는 삭제할 수 없습니다.\
카드를 삭제해도 카드 이미지는 삭제되지 않습니다.
{% endhint %}

**Request Example**

```
curl -X DELETE "https://api.klipwallet.com/v2/wallet/nft" \
-d @./delete_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#delete-card)을 확인하십시오.

#### Approve Escrow <a href="#approve-escrow" id="approve-escrow"></a>

## Approve Escrow

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/escrow/approve`

카드 전송 에스크로 사용을 허용합니다. 카드 전송 에스크로 기능을 사용하기 위해서는 최초에 1회, 필수적으로 호출해야하는 API입니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                                | Type   | Description                                     |
| --------------------------------------------------- | ------ | ----------------------------------------------- |
| pin<mark style="color:red;">\*</mark>               | string | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다. |
| contract\_address<mark style="color:red;">\*</mark> | string | 카드를 발행한 SCA 주소입니다.                              |

{% tabs %}
{% tab title="200 " %}

```
{
  "fail_count": 0,
  "tx_hash": "string"
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
{
  "code": number,
  "err": "string"
}
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/escrow/approve" \
-d @./approve_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#approve-escrow)을 확인하십시오.

#### Get Escrow Approval Status <a href="#get-approve-escrow-information" id="get-approve-escrow-information"></a>

## Get Escrow Approval Status

<mark style="color:blue;">`GET`</mark> `https://api.klipwallet.com/v2/escrow/approve`

카드 전송 에스크로 사용 동의 여부를 조회합니다.

#### Query Parameters

| Name                                                | Type   | Description         |
| --------------------------------------------------- | ------ | ------------------- |
| contract\_address<mark style="color:red;">\*</mark> | string | 카드를 발행하는 SCA 주소입니다. |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

{% tabs %}
{% tab title="200 " %}

```
{
  "approve": true
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
{
  "code": number,
  "err": "string"
}
```

{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X GET "https://api.klipwallet.com/v2/escrow/approve?contract_address=0xc94770007dda54cF92009BFF0dE90c06F603a09f" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#get-approve-escrow)을 확인하십시오.

#### Create Escrow <a href="#create-escrow" id="create-escrow"></a>

## Create Escrow

<mark style="color:green;">`POST`</mark> `https://api.klipwallet.com/v2/escrow`

카드 전송 에스크로를 실행하고, Klip 사용자가 카드를 지급받을 수 있는 링크가 생성됩니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                                | Type   | Description                                        |
| --------------------------------------------------- | ------ | -------------------------------------------------- |
| pin<mark style="color:red;">\*</mark>               | string | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다.    |
| card\_ids<mark style="color:red;">\*</mark>         | array  | 카드 ID들이 담긴 `number` 배열입니다. 최대 100개의 원소를 담을 수 있습니다. |
| contract\_address<mark style="color:red;">\*</mark> | string | 카드를 발행한 SCA 주소입니다.                                 |

{% tabs %}
{% tab title="200 " %}

```
{
  "claim_links": [
    "https://klipwallet.com/?target=/claimCard/2/123?claimKey=1234567890123456789012345678901212345678901234567890123456789012"
  ],
  "fail_count": 0,
  "tx_hash": "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97"
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
{
  "code": number,
  "err": "string"
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
보유중인 카드만 에스크로 전송을 실행 할 수 있으며, 다른 사람에게 보낸 카드는 전송할 수 없습니다.\
에스크로를 수행한 카드는 에스크로 카드 조회를 통해 확인할 수 있습니다.
{% endhint %}

**Request Example**

```
curl -X POST "https://api.klipwallet.com/v2/escrow" \
-d @./escrow_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#create-escrow)을 확인하십시오.

#### Get Cards in Escrow <a href="#escrow-information" id="escrow-information"></a>

## Get Cards in Escrow

<mark style="color:blue;">`GET`</mark> `https://api.klipwallet.com/v2/escrow`

에스크로 카드 목록 조회.

#### Query Parameters

| Name                                                | Type   | Description                                                                                                                                                                         |
| --------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| contract\_address<mark style="color:red;">\*</mark> | string | 카드를 발행하는 SCA 주소입니다.                                                                                                                                                                 |
| cursor                                              | string | 카드 개수가 100개 이상이면 다음 100개 정보를 받는 커서값입니다. 일반적으로 카드 개수가 100개를 초과한다면 1번 호출 시 100개의 결과와 `next_cursor` 값을 받습니다. 나머지 카드를 조회하려면 `next_cursor` 값을 query 파라미터 `cursor`에 전달하여 API를 다시 호출해야합니다. |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

{% tabs %}
{% tab title="200 " %}

```
{
    "cards": [
        {
            "name": "conan",
            "symbol_img": "",
            "cards": [
              {
                  "created_at": 1580300503,
                  "updated_at": 1580300503,
                  "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                  "sender": "0x0000000000000000000000000000000000000000",
                  "card_id": 18,
                  "card_uri": "https://.../card_meta.json",
                  "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
              },
            ],
            "next_cursor": "mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL",
        }
    ]
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
cursor에 대한 자세한 내용은 [pagination](/basics#basic-card-minting) 항목을 참조하십시오.
{% endhint %}

**Request Example**

```
curl -X GET "https://api.klipwallet.com/v2/escrow?contract_address=0xc94770007dda54cF92009BFF0dE90c06F603a09f" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

**Response Details**

| 이름           | 타입     | 설명                                    |
| ------------ | ------ | ------------------------------------- |
| name         | string | 카드 이름입니다.                             |
| symbol\_img  | string | 카드에 사용하는 이미지 URL 주소입니다.               |
| cards        | array  | 각 카드 정보를 담은 `object` 배열입니다.           |
| next\_cursor | string | 카드가 100개 이상이면 다음 100개 정보를 불러올 커서값입니다. |

**Response Details for** `cards[i]`

| 이름                | 타입     | 설명                                                                      |
| ----------------- | ------ | ----------------------------------------------------------------------- |
| created\_at       | number | 카드가 발행된 시간입니다.                                                          |
| updated\_at       | number | 카드가 업데이트된 시간입니다.                                                        |
| owner             | string | 이 계정 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다.              |
| sender            | string | 이 계정으로 카드를 보낸 사람의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다. |
| card\_id          | number | 카드 ID입니다.                                                               |
| card\_uri         | string | 카드 메타데이터가 담긴 JSON 파일 URL입니다.                                            |
| transaction\_hash | string | 카드를 발행한 스마트 컨트랙트 트랜잭션 해시입니다.                                            |

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#get-escrow)을 확인하십시오.

#### Cancel Escrow <a href="#cancel-escrow" id="cancel-escrow"></a>

## Cancel Escrow

<mark style="color:red;">`DELETE`</mark> `https://api.klipwallet.com/v2/escrow`

카드 전송 에스크로를 취소합니다.

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

#### Request Body

| Name                                                | Type   | Description                                        |
| --------------------------------------------------- | ------ | -------------------------------------------------- |
| pin<mark style="color:red;">\*</mark>               | string | 서명에 사용할 핀 번호를 해시(SHA256)한 64자리 Hex String 값입니다.    |
| card\_ids<mark style="color:red;">\*</mark>         | array  | 카드 ID들이 담긴 `number` 배열입니다. 최대 100개의 원소를 담을 수 있습니다. |
| contract\_address<mark style="color:red;">\*</mark> | string | 카드를 발행한 SCA 주소입니다.                                 |

{% tabs %}
{% tab title="200 " %}

```
{
  "fail_count": 0,
  "tx_hash": "string"
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 에스크로 취소에 실패하였습니다. 정확한 정보를 확인하기 위해 현재 에스크로된 카드 목록을 확인하십시오.
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="500 " %}

```
{
  "code": number,
  "err": "string"
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
에스크로된 카드만 취소할 수 있으며, 이미 지급된 카드는 삭제할 수 없습니다. 취소된 카드는 보유 목록으로 반환됩니다.
{% endhint %}

**Request Example**

```
curl -X DELETE "https://api.klipwallet.com/v2/escrow" \
-d @./cancel_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#cancel-escrow)을 확인하십시오.

#### Get Transaction Result <a href="#transasction-result" id="transasction-result"></a>

## Get Transaction Result

<mark style="color:blue;">`GET`</mark> `https://api.klipwallet.com/v2/wallet/receipt`

트랜잭션 처리 결과가 블록에 최종 성공으로 기록됐는지 여부를 조회합니다.

#### Query Parameters

| Name                                       | Type   | Description       |
| ------------------------------------------ | ------ | ----------------- |
| tx\_hash<mark style="color:red;">\*</mark> | string | 조회할 트랜잭션 해시 값입니다. |

#### Headers

| Name                                            | Type   | Description      |
| ----------------------------------------------- | ------ | ---------------- |
| Authorization<mark style="color:red;">\*</mark> | string | JWT 형식 인증 토큰입니다. |
| Content-Type<mark style="color:red;">\*</mark>  | string | application/json |

{% tabs %}
{% tab title="200 " %}

```
{
  "success": true
}
```

{% endtab %}

{% tab title="400 " %}
{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4700" %}

```
"no transaction receipt": 트랜잭션 해시가 존재하지 않습니다. 아직 트랜잭션이 처리되지 않았거나 잘못된 트랜잭션 해시 값입니다.
```

{% endtab %}
{% endtabs %}
{% endtab %}
{% endtabs %}

**Request Example**

```
curl -X GET "https://api.klipwallet.com/v2/wallet/receipt?tx_hash=0x880a45d3c482c7d794c2e7b7dbdc9e933a68f4a1f3d978d582ba9f9ebd1f9e72" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

**Response Details**

| 이름      | 타입   | 설명             |
| ------- | ---- | -------------- |
| success | bool | 트랜잭션 성공 여부입니다. |

자세한 내용은 [튜토리얼](/tutorial/tutorial-card-minting#get-receipt)을 확인하십시오.

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# App2App

이 페이지에서는 BApp에서 Klip을 활용하기 위한 App2App REST API를 설명합니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

{% hint style="info" %}
현재 토큰/NFT 전송 및 Smart Contract 실행과 같은 트랜잭션 서명 기능은 카이아, 이더리움, 폴리곤 네트워크에 대해서만 실행이 가능하며, 추후 지원이 확대될 예정입니다. 다른 네트워크에 대한 Klip 연동이 필요하다면 당장은 WalletConnect 사용을 부탁드립니다.
{% endhint %}

## ※ 개요 <a href="#api-intro" id="api-intro"></a>

App2App API를 사용하는 단계는 **Prepare, Request, Result** 3단계로 구분됩니다.

{% hint style="warning" %}

* Klip API를 사용함에 있어 사용자는 (주)안랩블록체인컴퍼니를 사칭해서는 안됩니다.
* Klip API 사용에 따라 발생하는 모든 책임은 전적으로 사용자에게 있으며, (주)안랩블록체인컴퍼니는 사용자 또는 제3자에 대해 어떠한 책임도 지지 않습니다.
* Klip API 사용자가 과도한 네트워크 트래픽을 발생시키는 시도하는 등 불법 혹은 비정상적인 방식으로 API를 사용하려고 시도하는 경우, 사전 고지없이 API 사용이 차단될 수 있습니다.
  {% endhint %}

### Prepare

BApp에서 어떤 작업을 실행하고 싶은지 정의하는 단계입니다. "인증"을 제외한 나머지는 체인에 트랜잭션을 전송하는 작업입니다. 트랜잭션 전송을 위해 Prepare 단계에서는 트랜잭션 객체를 생성합니다. 실행 가능한 작업은 다음과 같습니다.

* **인증**
* **토큰 전송**
* **카드 전송**
* **스마트 컨트랙트 실행**
* **메시지 서명**

#### 인증 <a href="#auth" id="auth"></a>

BApp 회원의 Klip 지갑에 접근하기 위한 인증 작업입니다. BApp에서 Klip 사용자의 [EOA](https://docs.kaia.io/ko/learn/accounts/)를 얻어야할 때 사용합니다. 이 기능을 위한 Klip 로그인 버튼을 제공하는 경우, 버튼 스타일과 버튼명은 아래 가이드를 준수해야 합니다.

**Klip 로그인 버튼 가이드**

* Klip App2App 버튼 제작 가이드 ([pdf](https://media.klipwallet.com/guide/klip_A2A_button_guide_ko_v2.0.0.pdf), [figma](https://www.figma.com/file/FZuqElOlwYGbQOsjDx8g1c/Klip_A2A-%EB%B2%84%ED%8A%BC-%EC%A0%9C%EC%9E%91-%EA%B0%80%EC%9D%B4%EB%93%9C-v.2.0.0?type=design\&node-id=0-1))
* Klip App2App 버튼 템플릿 [다운로드](https://media.klipwallet.com/guide/klip_A2A_button_template_ko_v2.0.0.psd)

{% hint style="warning" %}
이 기능을 사용하는 경우, Klip 계정을 연결 해지하는 기능도 반드시 제공해야 하며 해지 시 수집한 사용자 EOA 정보를 즉시 삭제해야 합니다.

위와 같은 조건이 지켜지지 않을 경우, 사전 고지없이 API 사용이 차단될 수 있습니다.
{% endhint %}

#### 토큰 전송 <a href="#token-transfer" id="token-transfer"></a>

BApp 회원의 Klip 지갑에서 다른 계정 주소(EOA)로 토큰(Fungible Token)을 전송하는 작업입니다. 토큰 전송을 위한 트랜잭션 객체를 생성합니다. 컨트랙트 주소에 `0x0000000000000000000000000000000000000000` 값을 입력하면 네이티브 코인 (KAIA, ETH, MATIC 등) 전송이 가능합니다.

#### 카드 전송 <a href="#nft-transfer" id="nft-transfer"></a>

BApp 회원의 Klip 지갑에서 다른 계정 주소(EOA)로 카드(Non-Fungible Token)을 전송하는 작업입니다. 카드 전송을 위한 트랜잭션 객체를 생성합니다.

#### 스마트 컨트랙트 실행 <a href="#contract-execution" id="contract-execution"></a>

Klip 계정으로 스마트 컨트랙트를 실행하는 작업입니다. 컨트랙트 실행을 위한 트랜잭션 객체를 생성합니다.

#### 메시지 서명 <a href="#sign-message" id="sign-message"></a>

Klip 계정으로 메시지를 서명하여 반환합니다.

{% hint style="info" %}
Prepare API 호출에 성공하면 응답값으로 “인증키"(Request Key)를 받습니다.\
인증키는 Prepare 단계에서 정의한 작업을 실제로 실행하도록 요청하는 "Request"와 결과를 확인하는 "Result" 단계에서 사용합니다.
{% endhint %}

### Request <a href="#request" id="request"></a>

위 단계에서 정의한 작업을 실제로 실행하도록 요청합니다.

"인증"은 BApp 회원의 Klip 지갑 주소(EOA)를 BApp으로 받아오는 작업이며 그 외에 나머지 작업은 위 트랜잭션에 서명(sign)을 받는 작업입니다. 이들 4가지 작업은 사실 체인에 트랜잭션 전송을 요청하는 작업이며 토큰 전송, KAIA 전송, 카드 전송, 스마트 컨트랙트 실행 트랜잭션을 체인에 전송합니다. 이 단계에서는 이들 트랜잭션에 계정 키로 서명한 다음 체인에 전송합니다.

{% hint style="info" %}
인증 또는 서명은 Deep Link를 통해 Klip에 요청합니다.
{% endhint %}

예를 들어, BApp 회원 “A”가 다른 BApp 회원 “B”에게 토큰 또는 아이템을 전송하는 버튼을 클릭하면 여러분의 BApp은 App2App API를 사용해 “A”의 Klip 지갑 주소를 인증(이미 확보하고 있다면 생략 가능)하고 “A”의 Klip 지갑에 접근합니다. 그리고 전송하려는 토큰 또는 카드를 “B”의 계정 주소에 전송하는 트랜잭션을 보냅니다.

### Result <a href="#result" id="result"></a>

마지막으로 Result 단계는 Request 단계에서 요청한 작업을 실행했을 때 결과 또는 응답값을 얻는 단계입니다.

API는 형태에 따라서 두 가지로 구분할 수 있습니다. 먼저 Prepare와 Result 스텝은 Klip Backend 서버로 요청을 날리는 REST API 형태이고, Request 스텝은 Klip을 띄워서 처리하기 위한 Deep Link 형태입니다. 앞선 두 가지와 별개로 필요 시 사용자의 카드 소유 정보를 얻기위한 REST API 형태의 요청이 있습니다.

## ※ API Flow Diagram <a href="#api-flow-diagram" id="api-flow-diagram"></a>

App2App 처리를 위한 대략적인 흐름은 아래 그림과 같습니다.

![App2App Flow](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-563b04b8f37e1a4cc1da1d25a137064dcde312f9%2Fa2a-basic-flow-v.3.png?alt=media)

API 요청과 별개로 카드 정보 조회는 일반적인 REST API 호출 흐름과 동일합니다. Klip 거치지 않고 Backend에 요청하여 정보를 받아옵니다. 흐름은 아래와 같습니다.

![App2App Information API Flow](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-d9472113194d63c8fcd74196a6c5b6ad3dc5d802%2Fa2a-info-api-flow-v.2.png?alt=media)

Deep Link는 아래와 같은 형태의 링크이고, BApp 유저가 클릭했을 때 클립 앱을 실행하거나 설치할 수 있도록 유도됩니다. `request_key` 필드에는 Prepare 과정에서 응답으로 전달받은 값을 사용합니다.

```
https://klipwallet.com?target=/a2a?request_key=9892...4aeb
```

## ※ API Specification <a href="#api-detail" id="api-detail"></a>

App2App API 세부 스펙은 아래와 같습니다.

## Prepare

<mark style="color:green;">`POST`</mark> `https://a2a-api.klipwallet.com/v2/a2a/prepare`

App2App API 요청 처리를 준비하고 request key를 발급합니다.

#### Headers

| Name                                           | Type   | Description      |
| ---------------------------------------------- | ------ | ---------------- |
| Content-Type<mark style="color:red;">\*</mark> | string | application/json |

#### Request Body

| Name                                   | Type   | Description                                                                                                                                                                                                                                       |
| -------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| chain                                  | string | App2App API 요청을 수행할 체인 정보입니다. `klaytn`, `ethereum`, `polygon` 등 세 종류의 체인을 지원하며 기본값은 `klaytn`입니다. 아래 예시를 참고하십시오. 실제로는 Kaia 체인과 상호작용하지만 호환성 유지를 위해 `klaytn` 명칭이 사용됩니다. 다른 체인의 지갑 주소를 얻기 위해 `type`=`auth`로 요청하는 경우에도 위 세 값을 사용하면 모든 지갑 주소가 일괄 반환됩니다. |
| bapp<mark style="color:red;">\*</mark> | object | App2App API 요청을 수행할 BApp 정보입니다. 이름과 callback URL로 Deep Link를 함께 전달할 수 있습니다. `callback` 필드는 옵셔널입니다. 아래 예시를 참고하십시오.                                                                                                                                 |
| type<mark style="color:red;">\*</mark> | string | App2App API 요청 type입니다. 인증은 `auth`, 코인 및 토큰 전송은 `send_token`, 카드 전송은 `send_card`, 메시지 서명은 `sign_message`, `sign_message_eip191`, `sign_typedData_v4`, 마지막으로 컨트랙트 실행은 `execute_contract`입니다.                                                       |
| transaction                            | object | 서명할 데이터입니다. `to`, `amount`, `contract` 등의 정보가 들어가며 전송 요청 type별로 필요한 필드를 세팅해야합니다. `auth`, `sign_message`를 제외한 요청 타입은 이 필드를 필수적으로 기입해야합니다. 아래 예시를 참고하십시오.                                                                                           |
| message                                | object | 서명할 데이터입니다. `from`과 `value` 값을 포함하며 `from`은 생략 가능합니다. `sign_message` 타입인 경우 이 필드를 필수적으로 기입해야 합니다. 그 외의 타입에서는 설정하지 않습니다. 아래 예시를 참고하십시오.                                                                                                            |

{% tabs %}
{% tab title="200 " %}

```json
{
  "request_key": "random key",
  "status": "prepared",
  "expiration_time": 12345 //unix timestamp
}
```

{% endtab %}

{% tab title="200 " %}

{% endtab %}

{% tab title="200 " %}

{% endtab %}
{% endtabs %}

### `bapp` object 예시 <a href="#prepare-bapp" id="prepare-bapp"></a>

```json
{
  "bapp": {
    "name": "My BApp",
    "callback": { // all optional
      "success": "myApp://...", // Android 플랫폼의 경우, "intent://..." 로 작성
      "fail": "myApp://..." // Android 플랫폼의 경우, "intent://..." 로 작성
    },
   "kas_authorization_key": "Basic abcdefghijklmnopqrstuvwxyz0123456789="
  }
}
```

`name`은 인증 또는 서명 시 Klip 사용자 화면에 표시될 BApp의 이름입니다. `callback`의 `success` 필드는 Klip에서 사용자 확인이 성공적으로 처리됐을 때 BApp으로 돌아가기 위한 Deep Link입니다. `fail`은 반대로 실패한 경우 BApp으로 돌아가기 위한 Deep Link입니다. Android 플랫폼의 경우, Intent Scheme 형식(`intent://..`)의 Deep Link로 작성이 필요합니다. `callback` 객체는 optional입니다. `kas_authorization_key` 는 optional이며, BApp에서 트랜잭션 수수료를 대납하고자 할 경우 사용하는 KAS (Klaytn API Service) 인증 정보입니다. KAS 대납 서비스 구독 및 authorization key 발급 방법은 [이 문서](https://support.klaytnapi.com/hc/ko/articles/6180493705743)를 참고하시기 바라며, 문의사항은 [KAS 헬프센터](https://support.klaytnapi.com/hc/ko)를 이용하여 주시기 바랍니다.

### `transaction` object 예시 <a href="#prepare-tx" id="prepare-tx"></a>

#### 1. type: `send_token` <a href="#prepare-tx-send-token" id="prepare-tx-send-token"></a>

```json
{
  "transaction": {
    "contract": "SCA",
    "from": "0x8756...4321", // optional
    "to": "0x1234...5678",
    "amount": "100",
  }
}
```

`contract`는 토큰의 스마트 컨트랙트 주소입니다 (네이티브 코인의 경우 `0x0000000000000000000000000000000000000000` 입력). `to`는 토큰을 전송받는 사람의 계정 주소입니다. `amount`를 받을 토큰 양입니다. 참고로, `amount`는 컨트랙트 내 decimal을 반영하여 자동으로 환산되는 수치입니다. 예를 들면, 18 decimal의 FT 컨트랙트에서 `amount` 1은 10^18 개의 최소 단위 토큰을 의미하게 됩니다. `from`은 Klip 사용자의 주소입니다. `from`은 optional 필드이고 Klip 사용자의 실제 주소와 비교하여 의도하지 않은 요청을 검사하는 용도로 사용됩니다.

#### 2. type: `send_card` <a href="#prepare-tx-send-card" id="prepare-tx-send-card"></a>

```json
{
  "transaction": {
    "contract": "0xA987...4321",
    "from": "0x8756...4321", // optional
    "to": "0x1234...5678",
    "card_id": "100",
  }
}
```

`contract`는 NFT의 스마트 컨트랙트 주소입니다. `to`는 카드를 전송받는 사람의 주소입니다. `card_id`는 전송할 카드의 고유번호입니다. `from`은 Klip 사용자의 주소입니다. `from`은 optional 필드이고 Klip 사용자의 실제 주소와 비교하여 의도하지 않은 요청을 검사하는 용도로 사용됩니다.

#### 3. type: `execute_contract` <a href="#prepare-tx-execute-contract" id="prepare-tx-execute-contract"></a>

```json
{
  "transaction": {
    "from": "0x8756...4321", // optional
    "to": "0xA987...4321", // contract address
    "value": "1000000000000000000", // 단위는 실제 트랜잭션의 value 단위와 동일
    "abi": "...",
    "params": "...",
    "encoded_function_call": "0x123...23fe23"
  }
}
```

`to`는 실행할 스마트 컨트랙트 주소입니다. `value`는 해당 컨트랙트에 전송할 코인의 수량입니다. `value`의 단위는 실제 해당 체인의 트랜잭션 생성 인자와 동일합니다. Kaia 기준으로 단위는 kei이며, 1 KAIA는 1000000000000000000 (10^18) kei입니다. `abi`는 실행할 컨트랙트 함수 정보입니다. `params`는 해당 함수에 넘겨줄 인자값입니다. 최신 버전 부터는 tuple 타입도 지원합니다. `abi` 와 `param` 대신에 `encoded_function_call`을 사용할 수 있습니다. `encoded_function_call` 에 tx의 data에 들어갈 정보를 입력해주면 해당 값을 사용하여 tx를 실행합니다. `abi, param` 혹은 `encoded_function_call` 중 하나만을 사용하여 tx를 실행하기 때문에 사용하지 않는 값은 비워져 있어야 합니다. `from`은 Klip 사용자의 주소입니다. `from`은 optional 필드이고 Klip 사용자의 실제 주소와 비교하여 의도하지 않은 요청을 검사하는 용도로 사용됩니다. `abi` 및 `params` 의 구체적인 예시는 튜토리얼을 참조하십시오.

{% hint style="info" %}
`from`은 optional 필드이지만 트랜잭션 처리 시 원래 의도했던 Klip 사용자가 맞는지 검증하는 용도로 사용되므로 가능하면 설정하는 것을 권장합니다.
{% endhint %}

### `message` object 예시 <a href="#prepare-msg" id="prepare-msg"></a>

#### 1. type: `sign_message` <a href="#prepare-msg-sign-message" id="prepare-msg-sign-message"></a>

```json
{
 "message": {
  "from": "0x8756...4321", // optional
  "value": "message original", // 서명할 원문
  "is_hex_encoded": true or false // optional. default는 false.
 }
}
```

`from`은 Klip 사용자의 주소입니다. Klip 사용자의 실제 주소와 비교하여 의도하지 않은 요청을 검사하는 용도로 사용됩니다. 선택 항목이므로 생략할 수 있습니다. `is_hex_encoded`는 메시지 원문의 데이터 타입입니다. true 일 경우 서명 값을 데이터의 hex encoding 된 byte 배열로 판단하여 서명합니다. 생략하거나 false 일 경우는 문자열로 판단합니다. `value`는 서명할 메시지의 원문입니다. `is_hex_encoded` 가 true 일 경우 `0x` 로 시작하는 hex encoding된 byte 배열이여야 합니다.

#### 2. type: `sign_message_eip191` <a href="#prepare-msg-sign-message" id="prepare-msg-sign-message"></a>

```json
{
 "message": {
  "from": "0x8756...4321", // optional
  "value": "message original", // 서명할 원문
  "is_hex_encoded": true or false // optional. default는 false.
 }
}
```

`sign_message_eip191`은 기본적으로 `sign_message`와 동일하게 Klip 사용자의 계정 키로 메시지를 서명하는 역할을 수행하나, `sign_message`는 Klaytn의 표준에 따라 `"\x19Klaytn Signed Message:\n" + len(message)`의 접두사를 붙이고, `sign_message_eip191`은 Kaia의 표준에 따라 `"\x19Ethereum Signed Message:\n" + len(message)`의 접두사를 붙인다는 차이점이 있습니다. Kaia에서 변경된 메시지 서명 표준의 변화에 대해서는 [여기](https://github.com/kaiachain/kaia/pull/33)를 참고하시기 바랍니다.\
\
`from`은 Klip 사용자의 주소입니다. Klip 사용자의 실제 주소와 비교하여 의도하지 않은 요청을 검사하는 용도로 사용됩니다. 선택 항목이므로 생략할 수 있습니다. `is_hex_encoded`는 메시지 원문의 데이터 타입입니다. true 일 경우 서명 값을 데이터의 hex encoding 된 byte 배열로 판단하여 서명합니다. 생략하거나 false 일 경우는 문자열로 판단합니다. `value`는 서명할 메시지의 원문입니다. `is_hex_encoded` 가 true 일 경우 `0x` 로 시작하는 hex encoding된 byte 배열이여야 합니다.

#### 3. type: `sign_typedData_v4` <a href="#prepare-msg-sign-typeddata-v4" id="prepare-msg-sign-typeddata-v4"></a>

```json
{
 "message": {
  "value": "message original", // 서명할 원문
 }
}
```

여기에서 vaule 값은 EIP-712에서 정의된 json 형태의 구조화된 메시지로써, 정확한 스펙은 [여기](https://eips.ethereum.org/EIPS/eip-712)를 참고하시기 바랍니다.

**Request Example**

```bash
curl -X POST "https://a2a-api.klipwallet.com/v2/a2a/prepare" \
-d '{"bapp": { "name" : "My BApp" }, "chain": "klaytn", "type": "execute_contract" }' \
-H "Content-Type: application/json"
```

**Response Details**

| 명칭               | 형식     | 설명                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ---------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| request\_key     | string | 요청을 유니크하게 구분한 키값입니다. Request, Result API 호출 시 사용합니다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| status           | string | API 요청의 현재 상태입니다. 기본적으로 `prepared` 상태가 됩니다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| expiration\_time | number | request key 만료 시간을 unix timestamp로 표현한 값입니다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| estimated\_gas   | number | 트랜잭션을 발생시키는 요청이면서 from 값이 존재할 경우 실제 트랜잭션 생성에 사용될 gasLimit 값입니다.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Error            | object | <p>트랜잭션이 실패(revert)할 가능성이 있거나 execute\_contract 요청에서 params 값이 적절하지 않은 경우 에러를 반환합니다.<br><br>1. revert<br>from 주소와 함께 요청 시 트랜잭션을 검증하여 revert 메시지를 반환합니다. 되돌아갈 가능성이 있기 때문에 트랜잭션을 생성하지 않습니다. 해당 오브젝트는 code와 message를 반환하며 revert 상황일 때 값은 다음과 같습니다. message는 트랜잭션이 되돌아가는 원인을 string으로 포함합니다.<br><code>"error":{"code":6414,"message":(revert 원인)}</code><br><br>2. params error<br>params는 abi의 타입에 맞는 데이터를 입력해야 합니다. address type에 숫자(222)를 넣을 경우 다음처럼 에러를 반환 합니다. 필드명을 함께 반환하기 때문에 어떤 param이 잘못 입력되었는지 찾는데 도움을 줍니다. <code>"error":{"code":6408,"message":"dummy\_arg\_name: \[(json.Number)222] is not (address)"}</code></p> |

{% hint style="info" %}
`status`는 `prepared`, `requested`, `completed`, `canceled`, `error` 상태중 하나를 가집니다. `canceled` 상태는 사용자가 명시적으로 App2App 진행을 취소했을 때 설정됩니다.
{% endhint %}

자세한 내용은 [튜토리얼](/tutorial/tutorial-a2a-rest-api)을 확인하십시오.

### 거래소 연동 <a href="#prepare-exchange" id="prepare-exchange"></a>

클립 연동 시 명의에 대한 검증(ci 기준)을 하고 싶은 경우, 클립에서 발행해 준 service key를 함께 전달하면 해싱된 ci를 받아 이를 내부적으로 보관하고 있는 ci와 비교하여 본인임을 검증할 수 있습니다. ci를 해싱하기 위한 알고리즘 및 salt 등을 별도로 협의할 수 있으며, service key 발급을 위해서는 <support@ahnlab.io>로 문의해주시기 바랍니다.

호출하기 위한 방법은 기본적으로 `type`=`auth`(지갑 연동 요청)로 prepare/request/result를 호출하는 절차와 동일하며, prepare 시 아래와 같이 `service_key`를 함께 전달합니다. 참고로 `chain`의 경우 auth에 있어서는 호환성을 위해 유지되는 값으로, 어떤 네트워크 값을 전달하더라도 동일한 결과를 받습니다.

```json
{
  "chain":"klaytn",
  "type":"auth",
  "bapp": {
    "name": "거래소 법인명",
    "callback": { // all optional
      "success": "myApp://...", // Android 플랫폼의 경우, "intent://..." 로 작성
      "fail": "myApp://..." // Android 플랫폼의 경우, "intent://..." 로 작성
    },
   "service_key": "당사에서 발행한 서비스 키"
  }
}
```

이 경우 후술할 result 조회 시 아래와 같이 `ci_hash` 값을 함께 전달받습니다.

```json
{
    "request_key": "random key",
    "expiration_time": unix timestamp,
    "status": "completed",
    "result": {
      "klaytn_address": string, //호환성을 위해 필드명에 klaytn 유지
      "evm_address": string,
      "bitcoin_address": string,
      "solana_address": string,
      "tron_address": string,
      "xrpl_address": string
    },
   "ci_hash": "서비스키별로 정의된 방식으로 해싱된 CI 값"
}
```

여기에서 `evm_address`는 모든 EVM 기반 네트워크에 공유되는 값으로, 클립이 현재 지원하는 EVM 네트워크는 카이아, 이더리움, 비앤비, 아비트럼, 아발란체, 스크롤, 폴리곤, 실리콘, 보라, 체인바운티입니다. 그 외에 비트코인, 솔라나, 트론, XRPL (리플) 지갑 주소가 함께 반환됩니다.

## Request

`DEEP LINK` `https://klipwallet.com?target=/a2a?request_key=`

Klip에 인증 또는 서명을 요청하기 위한 예제는 아래 Request Example 항목을 참조하십시오.

#### Query Parameters

| Name                                           | Type   | Description                                                             |
| ---------------------------------------------- | ------ | ----------------------------------------------------------------------- |
| request\_key<mark style="color:red;">\*</mark> | string | Prepare 단계에서 얻은 request key를 전달하십시오. `request_key`를 통해서 요청을 구분할 수 있습니다. |

{% tabs %}
{% tab title="200 " %}

{% endtab %}
{% endtabs %}

**Request Example**

아래 예제에서 `request_key` 필드는 Prepare 스텝에서 얻은 값으로 설정합니다.

#### iOS 또는 Android 환경 <a href="#request-deeplink" id="request-deeplink"></a>

```
https://klipwallet.com/?target=/a2a?request_key=9892...4aeb
```

{% hint style="info" %}
위 Deep Link를 통해 클립 앱을 실행하거나 설치할 수 있도록 유도됩니다.
{% endhint %}

#### PC 또는 이기종 디바이스 환경 (QR code) <a href="#request-qr-code" id="request-qr-code"></a>

아래와 같은 URL 형식으로 QR code를 생성합니다. 사용자는 클립 앱 또는 네이티브 카메라앱를 통해 QR code를 인식하여 App2App 요청을 처리할 수 있습니다.

```
https://klipwallet.com/?target=/a2a?request_key=9892...4aeb
```

![QR code 샘플](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-778f25e4c5bdc998c142cecb4575a0ad262ac7d0%2Fqr-code-sample.png?alt=media)

{% hint style="info" %}
QR code 생성을 위해서 개발 환경별로 아래 오픈소스 프로젝트를 참고하실 수 있습니다.

* JavaScript : <https://www.npmjs.com/package/qrcode>
* Android : <https://github.com/zxing/zxing>
* iOS : <https://github.com/EFPrefix/EFQRCode>
  {% endhint %}

## Result

<mark style="color:blue;">`GET`</mark> `https://a2a-api.klipwallet.com/v2/a2a/result?request_key=`

App2App API 요청에 대한 결과를 확인합니다.

#### Query Parameters

| Name                                           | Type   | Description                                                             |
| ---------------------------------------------- | ------ | ----------------------------------------------------------------------- |
| request\_key<mark style="color:red;">\*</mark> | string | Prepare 단계에서 얻은 request key를 전달하십시오. `request_key`를 통해서 요청을 구분할 수 있습니다. |

{% tabs %}
{% tab title="200 " %}

```json
{
  "request_key": "random key",
  "expiration_time": unix timestamp,
  "status": "requested" or "completed",
  "result": {
    type에 맞는 결과 object
  }
}
```

{% endtab %}

{% tab title="200 " %}

{% endtab %}

{% tab title="200 " %}

{% endtab %}
{% endtabs %}

**Request Example**

```bash
curl -X GET "https://a2a-api.klipwallet.com/v2/a2a/result?request_key=9892...4aeb" \
-H "Content-Type: application/json"
```

**Response Details**

#### 1. type: `auth` <a href="#result-auth" id="result-auth"></a>

```json
{
    "request_key": "random key",
    "expiration_time": unix timestamp,
    "status": "completed",
    "result": {
      "klaytn_address": string, //호환성을 위해 필드명에 klaytn 유지
      "evm_address": string,
      "bitcoin_address": string,
      "solana_address": string,
      "tron_address": string,
      "xrpl_address": string
    }
}
```

| 명칭               | 형식     | 설명                                                                                                                                                                              |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| request\_key     | string | 요청 키값입니다.                                                                                                                                                                       |
| expiration\_time | number | request key 만료 시간을 unix timestamp로 표현한 값입니다.                                                                                                                                    |
| status           | string | API 요청의 현재 상태입니다. 처리가 완료되었다면 `completed` 상태가 리턴됩니다.                                                                                                                             |
| result           | object | 지갑 연동의 결과입니다. 지갑 주소가 체인별로 반환됩니다. 클립은 EVM 호환 체인들 간에 동일한 주소를 가지며, `evm_address`로 반환됩니다. 이 값은 `klaytn_address`와 동일합니다. 아직 사용자가 앱을 업데이트하지 않아 신규 체인의 지갑을 생성하지 않은 경우에는 일부 누락될 수 있습니다. |

{% hint style="info" %}
`status`는 `prepared`, `requested`, `completed`, `canceled`, `error` 상태중 하나를 가집니다. `canceled` 상태는 사용자가 명시적으로 App2App 진행을 취소했을 때 설정됩니다.
{% endhint %}

#### 2. type: `send_klay`, `send_token`, `send_card`, `execute_contract` <a href="#result-tx" id="result-tx"></a>

```json
{
  "request_key": "random key",
  "expiration_time": unix timestamp,
  "status": "completed",
  "result": {
    "tx_hash": string,
    "status": "success"
  }
}
```

| 명칭               | 형식     | 설명                                                            |
| ---------------- | ------ | ------------------------------------------------------------- |
| request\_key     | string | 요청 키값입니다.                                                     |
| expiration\_time | number | request key 만료 시간을 unix timestamp로 표현한 값입니다.                  |
| status           | string | API 요청의 현재 상태입니다. 처리가 완료되었다면 `completed` 상태가 리턴됩니다.           |
| result           | object | 서명 요청의 결과입니다. transaction hash와 해당 transaction의 처리 상태가 리턴됩니다. |

{% hint style="info" %}
`result` object의 `status` 필드는 `pending` 상태의 경우, 사용자가 Klip에서 확인했자만, 체인에서 아직 트랜잭션을 처리하는 중임을 의미합니다. 일반적으로 몇 초후에 다시 확인하면 요청를 확인할 수 있습니다. 그리고 `success`는 요청이 성공적으로 처리됐을 때, `fail`은 요청이 실패했을 때의 상태를 나타냅니다.
{% endhint %}

#### 3. type: `sign_message`, `sign_message_eip191` <a href="#result-sign-message" id="result-sign-message"></a>

```json
{
 "request_key": "random key",
 "expiration_time": unix timestamp,
 "status": "completed",
 "result": {
    "signature": string // 원문에 대한 사용자 서명
    "hash": string
 } 
}
```

| 명칭               | 형식     | 설명                                                                                                                                                                                                                                                                                                    |
| ---------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| request\_key     | string | 요청 키 값입니다.                                                                                                                                                                                                                                                                                            |
| expiration\_time | number | request key 만료 시간을 unix timestamp로 표현한 값입니다.                                                                                                                                                                                                                                                          |
| status           | string | API 요청 상태입니다. 처리가 완료되었다면 `completed`를 반환합니다.                                                                                                                                                                                                                                                          |
| signature        | string | <p>서명 요청의 결과입니다. 원문에 대한 서명이 전달 됩니다. 서명의 v 값은 27 혹은 28입니다.<br><br>요청 type이 <code>sign\_message</code>인 경우에는 <code>"\x19Klaytn Signed Message:\n" + len(message)</code>의 접두사를 붙이고, <code>sign\_message\_eip191</code>은 <code>"\x19Ethereum Signed Message:\n" + len(message)</code>의 접두사를 붙여 서명합니다.</p> |
| hash             | string | 원문에 대해 각 체인에서 미리 정해진 데이터를 붙여 해싱한 값입니다. 실제로 서명에 사용되는 데이터입니다.                                                                                                                                                                                                                                           |

{% hint style="info" %}
`result` 오브젝트의 `signature` 필드는 요청된 원문에 서명한 결과입니다. status는 prepared, requested, completed, canceled, error 상태 중 하나를 결과값으로 표시합니다. canceled는 사용자가 명시적으로 App2App 진행을 취소했을 때 반환됩니다.
{% endhint %}

#### 4. type: `sign_typedData_v4` <a href="#result-sign-typeddata-v4" id="result-sign-typeddata-v4"></a>

```json
{
 "request_key": "random key",
 "expiration_time": unix timestamp,
 "status": "completed",
 "result": {
    "signature": string // 원문에 대한 사용자 서명
    "hash": string
 } 
}
```

| 명칭               | 형식     | 설명                                                                                                            |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------- |
| request\_key     | string | 요청 키 값입니다.                                                                                                    |
| expiration\_time | number | request key 만료 시간을 unix timestamp로 표현한 값입니다.                                                                  |
| status           | string | API 요청 상태입니다. 처리가 완료되었다면 `completed`를 반환합니다.                                                                  |
| signature        | string | 서명 요청의 결과입니다. 원문에 `"\x19Ethereum Signed Message:\n" + len(message)`의 접두사를 붙여 서명이 전달됩니다. 서명의 v 값은 27 혹은 28입니다. |
| hash             | string | 원문에 대해 EIP191 표준에 정의된 prefix를 붙여 해싱한 값입니다. 실제로 서명에 사용되는 데이터입니다.                                               |

{% hint style="info" %}
`result` 오브젝트의 `signature` 필드는 요청된 원문에 서명한 결과입니다. status는 prepared, requested, completed, canceled, error 상태 중 하나를 결과값으로 표시합니다. canceled는 사용자가 명시적으로 App2App 진행을 취소했을 때 반환됩니다.
{% endhint %}

자세한 내용은 [튜토리얼](/tutorial/tutorial-a2a-rest-api)을 확인하십시오.

## Get Card Information

<mark style="color:blue;">`GET`</mark> `https://a2a-api.klipwallet.com/v2/a2a/cards?cursor=`

사용자 EOA와 NFT 컨트랙트 주소를 입력하고, 이 사용자가 소유한 카드 중에서 이 NFT 컨트랙트에서 발행한 카드 목록을 반환합니다.

#### Query Parameters

| Name                                  | Type   | Description                                                                      |
| ------------------------------------- | ------ | -------------------------------------------------------------------------------- |
| chain                                 | string | 소유 정보를 조회할 체인명입니다. (`klaytn`, `ethereum`, `polygon`)                             |
| sca<mark style="color:red;">\*</mark> | string | 소유 정보를 조회할 smart contract address입니다.                                            |
| eoa<mark style="color:red;">\*</mark> | string | 어떤 사용자 EOA의 카드 소유 정보를 얻어올지 특정합니다. 일반적으로 App2App `auth` 요청을 통해 얻은 EOA를 인자로 사용합니다. |
| cursor                                | string | 카드 보유량이 100개 이상이면 다음 100개 정보를 받는 커서값입니다.                                         |

{% tabs %}
{% tab title="200 " %}

```json
{
    "name": "Klip",
    "symbol_img": "image url",
    "cards": [
    {
      "created_at": 1580176787,
      "created_at_format": "format",
      "updated_at": 1580176787,
      "updated_at_format": "format",
      "owner": "0x2412b300750f505fb2e68ddf0cd45e9d95f5378d",
      "sender": "0x0000000000000000000000000000000000000000",
      "sender_kakao_id": "kakao_id"
      "card_id": 19,
      "card_uri": "metadata uri",
      "transaction_hash": "0x293a2e53ecf238109908e65a2b7ff4aad0919ce3ce54af08d6fc4323f28e935d"
    },
    ],
    "next_cursor": string
}
```

{% endtab %}

{% tab title="200 " %}

{% endtab %}

{% tab title="200 " %}

{% endtab %}
{% endtabs %}

**Request Example**

```bash
curl -X GET "https://a2a-api.klipwallet.com/v2/a2a/cards?chain=klaytn&sca=0x1234...&eoa=0x9876...&cursor=mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL" \
-H "Content-Type: application/json"
```

**Response Details**

| 명칭           | 형식     | 설명                                        |
| ------------ | ------ | ----------------------------------------- |
| name         | string | 이 Contract 이름입니다.                         |
| symbol\_img  | string | 이 Contract symbol image URL입니다.           |
| cards        | array  | 각 카드 정보를 담은 `object` 배열입니다.               |
| next\_cursor | string | 카드 결과값이 100개 이상이면 다음 100개 정보를 불러올 커서값입니다. |

**Response Details for** `cards[i]`

| 명칭                | 형식     | 설명                                                                      |
| ----------------- | ------ | ----------------------------------------------------------------------- |
| created\_at       | number | 카드가 발행된 시간입니다.                                                          |
| updated\_at       | number | 카드가 업데이트된 시간입니다.                                                        |
| owner             | string | 이 계정 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다.              |
| sender            | string | 이 계정으로 카드를 보낸 사람의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소입니다. |
| card\_id          | number | 카드 ID입니다.                                                               |
| card\_uri         | string | 카드 메타데이터가 담긴 JSON 파일 URL입니다.                                            |
| transaction\_hash | string | 카드를 발행한 스마트 컨트랙트 트랜잭션 해시입니다.                                            |

자세한 내용은 [튜토리얼](/tutorial/tutorial-a2a-rest-api)을 확인하십시오.

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# App2App SDK

이 페이지는 Klip의 SDK를 소개합니다.

App2App SDK는 여러분이 개발하는 애플리케이션에서 Klip을 더 쉽게 활용할 수 있도록 도와주는 SDK입니다.

{% hint style="warning" %}
현재 Klip은 Kaia 외에도 다양한 체인 기반 자산의 보관/전송 기능을 제공하고 있으나, 본 문서를 통해 제공되는 SDK는 Kaia 기반의 자산만 조회/전송이 가능한 점 참고 부탁드립니다. Kaia 외의 다른 체인을 지원하는 기능은 추후 제공될 예정입니다.
{% endhint %}

| 항목                                      | 설명                         | 비고           |
| --------------------------------------- | -------------------------- | ------------ |
| [Javascript SDK](/a2a-sdk/a2a-sdk-js)   | Web 환경에서 사용가능한 API를 소개     | Javascript   |
| [Android SDK](/a2a-sdk/a2a-sdk-android) | Android 환경에서 사용가능한 API를 소개 | Java         |
| [iOS SDK](/a2a-sdk/a2a-sdk-ios)         | iOS 환경에서 사용가능한 API를 소개     | Swift        |
| [Download](/a2a-sdk/a2a-sdk-download)   | 플랫폼별 SDK 다운로드              | Sample & SDK |

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# JavaScript SDK

이 페이지에서는 BApp에서 Klip을 활용하기 위한 App2App JavaScript SDK를 설명합니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

## 요구 사항

* (npm 이용하여 설치하는 경우) node 10 이상 권장

## 환경 설정

Klip JavaScript SDK는 별도의 가입 절차가 필요하지 않습니다. HTTP 통신이 가능한 어느 환경에서도 동작합니다. 다만, 기본적으로 Klip 앱이 설치된 환경에서 호출해야 합니다. Klip 앱을 실행하여 Klip 사용자의 승인을 받아야 하기 때문입니다.

### npm을 이용하는 경우

`npm install klip-sdk` 혹은 `yarn add klip-sdk` 커맨드를 통해 설치 후\
다음과 같이 ES module import 방식으로 사용합니다.

```javascript
import { prepare, request, getResult, getCardList } from 'klip-sdk'
```

### 직접 파일을 다운 받아 사용하는 경우

[다운로드](/a2a-sdk/a2a-sdk-download)탭에서 Klip JavaScript SDK를 다운받습니다.\
다운 받은 파일을 레포지토리에 위치시킨 후 HTML파일에 다음과 같이 스트립트 태그를 삽입합니다.

```html
<script src="./lib/klipSDK-2.3.2.min.js"></script>
```

이후 글로벌 네임스페이스에 선언된 klipSDK 변수를 활용하여 각 메소드에 접근합니다.

```javascript
klipSDK.prepare(...)
klipSDK.request(...)
klipSDK.getResult(...)
klipSDK.getCardList(...)
```

## API

### 개요

App2App API 요청은 크게 `prepare`, `request`, `getResult`의 순서로 진행이 됩니다.

* `prepare`는 어떠한 요청을 할지 요청을 정의하는 단계로 총 5가지 종류의 요청이 존재
* `request`는 함수 호출을 통해 Klip으로 화면이 전환되어 실제 서명 프로세스를 진행
* `getResult`는 함수 호출을 통해 결과값을 받고 확인

추가적으로 `getCardList`는 BApp 개발의 편의를 위해 Klip 사용자의 NFT 목록을 받아올 수 있도록 제공되는 함수입니다.

### prepare

App2App API 요청을 준비하고 request key를 받습니다.

**사용 가능한 요청 유형**

* Klip 연결 타입(=인증)의 경우 `auth`
* KAIA(=KLAY) 전송 타입의 경우 `sendKLAY`
* Token 전송 타입의 경우 `sendToken`
* Card 전송 타입의 경우 `sendCard`
* Contract 실행 타입의 경우 `executeContract`
* Sign Message 요청 타입의 경우 `signMessage` - 이 경우 Klaytn 표준에 따라 `"\x19Klaytn Signed Message:\n" + len(message)`의 접두사를 붙여 서명합니다.

### prepare.auth

사용자의 정보를 획득하는 요청입니다.

**Parameters**

| Name        | Type   | Description                                             |
| ----------- | ------ | ------------------------------------------------------- |
| bappName    | string | 사용자에게 표시될 BApp의 이름                                      |
| successLink | string | 사용자 동의과정 완료 후 돌아올 BApp에 대한 Deep Link (optional)         |
| failLink    | string | 사용자 동의과정에서 문제가 발생할 경우 돌아올 BApp에 대한 Deep Link (optional) |

**Example**

```javascript
const bappName = 'my app'
const successLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const failLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const res = await prepare.auth({ bappName, successLink, failLink })
if (res.err) {
  // 에러 처리
} else if (res.request_key) {
  // request_key 보관
}
```

### prepare.sendKLAY

사용자의 KAIA(=KLAY)를 특정 주소로 전송하는 요청입니다.

**Parameters**

| Name        | Type   | Description                                             |
| ----------- | ------ | ------------------------------------------------------- |
| bappName    | string | 사용자에게 표시될 BApp의 이름                                      |
| to          | string | 받는 사람의 주소                                               |
| amount      | string | 보낼 KAIA(=KLAY) 수량 (단위: KAIA, 소수점 최대 6자리 허용)             |
| from        | string | 사용자의 Klip 계정 주소가 from 주소와 일치하는 경우만 진행 (optional)        |
| successLink | string | 사용자 동의과정 완료 후 돌아올 BApp에 대한 Deep Link (optional)         |
| failLink    | string | 사용자 동의과정에서 문제가 발생할 경우 돌아올 BApp에 대한 Deep Link (optional) |

**Example**

```javascript
const bappName = 'my app'
const from = '0xB21F0285d27beb2373EC...'
const to = '0xD8b1dC332...'
const amount = '13.2'
const successLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const failLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const res = await prepare.sendKLAY({ bappName, from, to, amount, successLink, failLink })
if (res.err) {
  // 에러 처리
} else if (res.request_key) {
  // request_key 보관
}
```

### prepare.sendToken

사용자가 보유한 토큰을 특정 주소로 전송하는 요청입니다.

**Parameters**

| Name        | Type   | Description                                             |
| ----------- | ------ | ------------------------------------------------------- |
| bappName    | string | 사용자에게 표시될 BApp의 이름                                      |
| to          | string | 받는 사람의 주소                                               |
| amount      | string | 보낼 토큰 수량 (단위: 토큰의 default 단위, 소수점 최대 6자리 허용)            |
| contract    | string | 토큰 컨트랙트 주소                                              |
| from        | string | 사용자의 Klip 계정 주소가 from 주소와 일치하는 경우만 진행 (optional)        |
| successLink | string | 사용자 동의과정 완료 후 돌아올 BApp에 대한 Deep Link (optional)         |
| failLink    | string | 사용자 동의과정에서 문제가 발생할 경우 돌아올 BApp에 대한 Deep Link (optional) |

**Example**

```javascript
const bappName = 'my app'
const from = '0xB21F0285d27beb2373EC...'
const to = '0xD8b1dC332...'
const amount = '10.123'
const contract = '0x813FB7677BbBAA...'
const successLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const failLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const res = await prepare.sendToken({ bappName, from, to, amount, contract, successLink, failLink })
if (res.err) {
  // 에러 처리
} else if (res.request_key) {
  // request_key 보관
}
```

### prepare.sendCard

사용자가 보유한 카드(NFT)를 특정 주소로 전송하는 요청입니다.

**Parameters**

| Name        | Type   | Description                                             |
| ----------- | ------ | ------------------------------------------------------- |
| bappName    | string | 사용자에게 표시될 BApp의 이름                                      |
| to          | string | 받는 사람의 주소                                               |
| id          | string | NFT id                                                  |
| contract    | string | NFT 컨트랙트 주소                                             |
| from        | string | 사용자의 Klip 계정 주소가 from 주소와 일치하는 경우만 진행 (optional)        |
| successLink | string | 사용자 동의과정 완료 후 돌아올 BApp에 대한 Deep Link (optional)         |
| failLink    | string | 사용자 동의과정에서 문제가 발생할 경우 돌아올 BApp에 대한 Deep Link (optional) |

**Example**

```javascript
const res = await prepare.sendCard({ bappName, from, to, id, contract, successLink, failLink })
if (res.err) {
  setErrorMsg(res.err)
} else {
  setRequestKey(res.request_key)
}
```

### prepare.executeContract

사용자가 특정 컨트랙트의 함수를 실행하도록 하는 요청입니다.

**Parameters**

| Name        | Type   | Description                                             |
| ----------- | ------ | ------------------------------------------------------- |
| bappName    | string | 사용자에게 표시될 BApp의 이름                                      |
| to          | string | 컨트랙트의 주소                                                |
| value       | string | 컨트랙트 실행하면서 같이 보낼 KAIA(=KLAY) 수량 (단위: kei(=peb))         |
| abi         | string | 실행할 함수의 abi                                             |
| params      | string | 실행할 함수의 인자 목록                                           |
| from        | string | 사용자의 Klip 계정 주소가 from 주소와 일치하는 경우만 진행 (optional)        |
| successLink | string | 사용자 동의과정 완료 후 돌아올 BApp에 대한 Deep Link (optional)         |
| failLink    | string | 사용자 동의과정에서 문제가 발생할 경우 돌아올 BApp에 대한 Deep Link (optional) |

**Example**

```javascript
const bappName = 'my app'
const from = '0xB21F0285d27beb2373EC...'
const to = '0xD8b1dC332...'
const value = '800000000'
const abi = "{\"constant\":false,\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"buyCard\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"}"
const params =  "[\"2829\"]"
const successLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const failLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const res = await prepare.executeContract({ bappName, from, to, value, abi, params, successLink, failLink })
if (res.err) {
  // 에러 처리
} else if (res.request_key) {
  // request_key 보관
}
```

### prepare.signMessage

사용자가 Klip 계정으로 메시지를 서명하는 요청입니다. 기존 Klaytn 표준에 따라 `"\x19Klaytn Signed Message:\n" + len(message)`의 접두사를 붙여 서명합니다.

**Parameters**

| Name        | Type   | Description                                             |
| ----------- | ------ | ------------------------------------------------------- |
| bappName    | string | 사용자에게 표시될 BApp의 이름                                      |
| value       | string | 서명할 메시지 원문                                              |
| from        | string | 사용자의 Klip 계정 주소가 from 주소와 일치하는 경우만 진행 (optional)        |
| successLink | string | 사용자 동의과정 완료 후 돌아올 BApp에 대한 Deep Link (optional)         |
| failLink    | string | 사용자 동의과정에서 문제가 발생할 경우 돌아올 BApp에 대한 Deep Link (optional) |

**Example**

```javascript
const bappName = 'my app'
const value = 'original message ...'
const from = '0xB21F0285d27beb2373EC...'
const successLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const failLink = 'myApp://...' // Android 플랫폼의 경우, 'intent://...' 로 작성
const res = await prepare.signMessage({ bappName, value, from, successLink, failLink })
if (res.err) {
  // 에러 처리
} else if (res.request_key) {
  // request_key 보관
}
```

### request

Deep Link를 이용하여 Klip에 인증 또는 서명을 요청합니다. 실행 중인 스마트폰 기기에 Klip 앱이 설치되지 않았거나 자동 실행할 수 없는 경우 'Klip 소개 페이지(<https://klipwallet.com>)' 로 이동하여 사용자는 Klip 앱을 다운로드받을 수 있습니다. requestKey에는 prepare 단계에서 Klip 서버로부터 받은 요청 번호를 사용합니다.

PC 환경에서 QR code를 이용한 request 스텝 처리는 [QR code 예제](/rest-api/rest-api-a2a#request-qr-code) 항목을 참조하십시오.

**Parameters**

| Name                     | Type     | Description                         |
| ------------------------ | -------- | ----------------------------------- |
| requestKey               | String   | 요청 번호                               |
| onUnsupportedEnvironment | Function | 모바일 환경이 아닌 경우 실행 할 콜백 함수 (optional) |

**Example**

```javascript
request(
  'b37f873d-32ce-4d5d-b72e-08d528e7fb8e', 
  () => alert('모바일 환경에서 실행해주세요')
);
```

### getResult

App2App API 요청에 대한 결과를 확인합니다. requestKey에는 prepare 및 request 단계에서 사용한 요청 번호를 사용합니다.

**Parameters**

| Name       | Type   | Description |
| ---------- | ------ | ----------- |
| requestKey | String | 요청 번호       |

**Example**

```javascript
getResult('b37f873d-32ce-4d5d-b72e-08d528e7fb8e')
```

### getCardList

사용자의 카드 (NFT) 보유 목록을 가져옵니다. 조회하고자 하는 NFT 컨트랙트 주소를 알고 있어야 하며, Klip에서 지원하는 컨트랙트만 가능합니다.

**Parameters**

| Name     | Type   | Description                                                               |
| -------- | ------ | ------------------------------------------------------------------------- |
| contract | String | 조회할 카드의 컨트랙트 주소                                                           |
| eoa      | String | 조회할 사용자 주소                                                                |
| cursor   | String | 조회할 커서값입니다. 만약, 조회할 카드의 보유목록이 100개 이상이면, 다음 100개 정보를 받을 수 있습니다.(optional) |

**Example**

```javascript
const contract = '0xB21F0285d27beb2373EC...'
const eoa = '0xD8b1dC332...'
const cursor = ''
getCardList({ contract, eoa, cursor })
```

## Error Code

| Http Status | Error Code | Description                       |
| ----------- | ---------- | --------------------------------- |
| -           | -          | [Klip REST API 에러코드](/basics)와 동일 |

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Android SDK

이 페이지에서는 BApp에서 Klip을 활용하기 위한 App2App Android SDK를 소개합니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

## 요구 사항

* API 16: Android 4.1(Jelly Bean) 이상
* Java 11 이상
* Android Studio 3.0.0 이상
* Android Permission : Internet Permission

## 환경 설정

Klip Android SDK는 별도의 가입 절차가 필요하지 않습니다. HTTP 통신이 가능한 어느 환경에서도 동작합니다. 다만, 기본적으로 Klip 앱이 설치된 환경에서 호출해야 합니다. Klip 앱을 실행하여 Klip 사용자의 승인을 받아야 하기 때문입니다.

Klip Android SDK Sample 앱의 실행 가이드는 프로젝트에 포함되어 있는 `README.md`에 소개되어 있습니다.

### 1. Klip SDK 다운로드

[다운로드](/a2a-sdk/a2a-sdk-download) 페이지에서 Klip Android SDK를 다운받습니다.

### 2. Klip SDK 라이브러리 추가

#### 방법 1. Klip SDK 빌드 후 개발 프로젝트에 추가

1. 다운받은 Klip SDK 프로젝트의 위치에서 **Terminal**을 실행
2. `./gradlew :sdk:build` 명령을 실행하여 Klip SDK 프로젝트를 빌드 (빌드가 완료되면 \<Klip SDK 프로젝트>/sdk/build/outputs/aar/위치에 결과물인 AAR 파일이 생성됨)
3. 개발 프로젝트에 **libs** 디렉토리를 생성
4. 빌드된 AAR 파일을 개발 프로젝트의 **libs** 디렉토리로 복사
5. 개발 프로젝트의 `build.gradle`에 디렉토리 참조 및 디펜던시 설정을 추가

```gradle
repositories {
  flatDir {
    dirs 'libs'
  }
}
dependencies {
  // Klip SDK  
  implementation 'com.klipwallet.app2app:klip-a2a-sdk-android_release_v2.3.0:2.3.0@aar'
}
```

#### 방법 2. Klip SDK 소스코드를 Import하여 개발 프로젝트에 추가

1. 개발 중인 프로젝트를 **Android Studio**로 실행
2. **Android Studio > File > New > Import Module**을 클릭
3. **Source Directory**에 다운받은 Klip SDK 프로젝트의 **sdk** 디렉토리를 선택, 클릭한 후 **Next**를 클릭
4. Klip SDK 프로젝트의 `gradle.properties` 내용들을 개발 프로젝트로 복사
5. 개발 프로젝트의 `build.gradle`에 디펜던시 설정을 추가

```gradle
dependencies {
  // Klip SDK  
  implementation project(path: ':sdk')
}
```

Klip SDK 소스가 개발 프로젝트에 복사되고 라이브러리 코드를 직접 수정할 수 있습니다. 만약, 단일 버전의 라이브러리 코드를 유지하려는 경우에는 이 방법이 적절하지 않을 수 있습니다. 이 경우, **방법 1**에서 안내한 내용에 따라 컴파일된 AAR 파일을 추가합니다.

### 3. 설정하기

#### 인터넷 사용 권한 설정하기

Klip SDK를 통해 HTTP 통신 사용을 허용하기 위해, 앱에 인터넷 사용 권한을 설정해야 합니다. **AndroidManifest.xml** 파일에 다음과 같이 `android.permission.INTERNET` 권한을 추가합니다.

```xml
<manifest ...>
  <uses-permission android:name="android.permission.INTERNET" />
  ...
</manifest> 
```

#### 패키지 쿼리 추가하기

App2App SDK Android v2.0.1 이하 버전을 사용하면서 Android 11을 타겟팅하는 앱(API 수준 30)을 개발하는 경우 Klip과 연동을 위해 패키지 쿼리를 추가해 상호작용을 설정해야 합니다. **AndroidManifest.xml** 파일에 다음과 같이 `queries` 요소를 추가하세요. (App2App SDK v2.1.0 이상을 사용하는 경우는 설정하지 않아도 됩니다.)\
자세한 내용은 [Android 11의 패키지 공개 상태](https://developer.android.com/about/versions/11/privacy/package-visibility?hl=ko)를 참고합니다.

```xml
<manifest ...>
    <queries>
        <package android:name="com.klipwallet.app" />
    </queries>
    ...
</manifest>
```

## API

### 개요

App2App API 요청은 크게 `prepare`, `request`, `getResult`의 순서로 진행이 됩니다.

* `prepare`는 어떠한 요청을 할지 요청을 정의하는 단계로 총 5가지 종류의 요청이 존재
* `request`는 함수 호출을 통해 Klip으로 화면이 전환되어 실제 서명 프로세스를 진행
* `getResult`는 함수 호출을 통해 결과값을 받고 확인

추가적으로 getCardList는 BApp 개발의 편의를 위해 Klip 사용자의 NFT 목록을 받아올 수 있도록 제공되는 함수입니다.

### Klip.getInstance

Klip SDK를 사용하기 위한 인스턴스를 생성합니다.

**Parameters**

| Name    | Type      | Description |
| ------- | --------- | ----------- |
| context | `Context` | 애플리케이션 컨텍스트 |

**Return Value**

| Type   | Description |
| ------ | ----------- |
| `Klip` | Klip 인스턴스   |

**Example**

```java
public class SampleActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Klip klip = Klip.getInstance(this);
  }
}
```

### Klip.prepare

App2App API 요청 처리를 준비하고 request key를 발급합니다.

{% hint style="info" %}
App2App REST API의 Prepare 요청과 같이, Android SDK에서도 BAppInfo의 `setCallback` 메소드를 통해서 BApp으로 돌아가기 위한 Deep Link를 설정할 수 있습니다.\
Link 형식은 Intent Scheme 형식(`intent://...`)의 Deep Link로 작성을 권장합니다.
{% endhint %}

**Request 값에 사용할 객체**

* Klip 연결 타입(=인증)의 경우 `AuthRequest`
* KAIA(=KLAY) 전송 타입의 경우 `KlayTxRequest`
* Token 전송 타입의 경우 `TokenTxRequest`
* Card 전송 타입의 경우 `CardTxRequest`
* Contract 실행 타입의 경우 `ContractTxRequest`
* Sign Message 요청 타입의 경우 `SignMessageRequest` - 이 경우 Klaytn 표준에 따라 `"\x19Klaytn Signed Message:\n" + len(message)`의 접두사를 붙여 서명합니다.

**Parameters**

| Name     | Type                         | Description                                                                                             |
| -------- | ---------------------------- | ------------------------------------------------------------------------------------------------------- |
| request  | `KlipRequest`                | 요청 타입에 따른 요청정보                                                                                          |
| bappInfo | `BAppInfo`                   | 요청 앱 정보                                                                                                 |
| callback | `KlipCallback<KlipResponse>` | 요청 응답 결과를 받을 콜백함수입니다. 처리가 완료되면, 완료결과인 `KlipResponse`를 전송받고, 처리가 실패되면, 실패결과인`KlipErrorResponse`를 전송받습니다. |

**Throws**

| Type                   | Description                      |
| ---------------------- | -------------------------------- |
| `KlipRequestException` | 요청 예외 (ex, 필수 Parameter 미입력시 발생) |

Klip 사용자에게 동의 요청시, request와 bappInfo에 입력된 정보가 출력됩니다.\
응답 결과에 포함된 request key는 사용자에게 트랜잭션을 요청하기 위한 컨텍스트 키의 역할을 수행하며, 사용자 동의 요청 및 결과확인 API와 함께 사용됩니다.

**Example 1. 사용자 정보 획득하기**

```java
// 사용자 정보 획득 요청문
AuthRequest req = new AuthRequest();

// BApp 정보
BAppInfo bappInfo = new BAppInfo("BApp Name");

// 응답 결과 Callback
KlipCallback callback = new KlipCallback<KlipResponse>() {
  @Override public void onSuccess(final KlipResponse res) {}
  @Override public void onFail(final KlipErrorResponse res) {}
}

klip.prepare(req, bappInfo, callback);
```

**Example 2. KAIA(=KLAY) 전송하기**

```java
// KAIA 전송 트랜잭션 요청문
KlayTxRequest req = new KlayTxRequest.Builder()
  .to("0x..receiver address..")
  .amount("10")
  .build();
  
klip.prepare(req, bappInfo, callback); // bappInfo, callback (example 1 참고)
```

**Example 3. Token 전송하기**

```java
// Token 전송 트랜잭션 요청문
TokenTxRequest req = new TokenTxRequest.Builder()
  .contract("0x..token contract address..")
  .to("0x..receiver address..")
  .amount("10")
  .build();
  
klip.prepare(req, bappInfo, callback); // bappInfo, callback (example 1 참고)
```

**Example 4. Card 전송하기**

```java
// Card 전송 트랜잭션 요청문
CardTxRequest req = new CardTxRequest.Builder()
  .contract("0x..card contract address..")
  .to("0x..receiver address..")
  .cardId("9")
  .build();
  
klip.prepare(req, bappInfo, callback); // bappInfo, callback (example 1 참고)
```

**Example 5. Contract 실행하기**

```java
// Contract 전송 트랜잭션 요청문
ContractTxRequest req = new ContractTxRequest.Builder()
  .to("0x..contract address..")
  .value("10")
  .abi("{..contract abi..}")
  .params(new ArrayList<Object>(){
    // contract parameters
  })
  .build();
  
klip.prepare(req, bappInfo, callback); // bappInfo, callback (example 1 참고)
```

**Example 6. Sign Message 실행하기**

```java
// Sign Message 요청문
SignMessageRequest req = new SignMessageRequest.Builder()
    .from("0x..contract address..")
    .value("message")
    .build();

klip.prepare(req, bappInfo, callback); // bappInfo, callback (example 1 참고)
```

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.

### Klip.request

Deep Link를 이용하여 Klip에 인증 또는 서명을 요청합니다. 실행 중인 스마트폰 기기에 Klip 앱이 설치되지 않았거나 자동 실행할 수 없는 경우 'Klip 소개 페이지(<https://klipwallet.com>)' 로 이동하여 사용자는 Klip 앱을 다운로드받을 수 있습니다. requestKey에는 prepare 단계에서 Klip 서버로부터 받은 요청 번호를 사용합니다.

PC 환경에서 QR code를 이용한 request 스텝 처리는 [QR code 예제](/rest-api/rest-api-a2a#request-qr-code) 항목을 참조하십시오.

**Parameters**

| Name       | Type   | Description |
| ---------- | ------ | ----------- |
| requestKey | String | 요청 번호       |

**Throws**

| Type                   | Description                      |
| ---------------------- | -------------------------------- |
| `KlipRequestException` | 요청 예외 (ex, 필수 Parameter 미입력시 발생) |

**Example**

```java
klip.request(requestKey); // Klip 앱 호출
```

### Klip.getResult

App2App API 요청에 대한 결과를 확인합니다. requestKey에는 prepare 및 request 단계에서 사용한 요청 번호를 사용합니다.

**Parameters**

| Name       | Type                         | Description                                                                                             |
| ---------- | ---------------------------- | ------------------------------------------------------------------------------------------------------- |
| requestKey | String                       | 요청 번호                                                                                                   |
| callback   | `KlipCallback<KlipResponse>` | 요청 응답 결과를 받을 콜백함수입니다. 처리가 완료되면, 완료결과인 `KlipResponse`를 전송받고, 처리가 실패되면, 실패결과인`KlipErrorResponse`를 전송받습니다. |

**Throws**

| Type                   | Description                      |
| ---------------------- | -------------------------------- |
| `KlipRequestException` | 요청 예외 (ex, 필수 Parameter 미입력시 발생) |

**Example**

```java
KlipCallback callback = new KlipCallback<KlipResponse>() {
  @Override public void onSuccess(final KlipResponse res) {}
  @Override public void onFail(final KlipErrorResponse res) {}
}

Klip klip = Klip.getInstance();
klip.getResult(requestKey, callback)
```

### Klip.getCardList

사용자의 모든 카드 중 특정 카드의 목록을 가져옵니다.

**Parameters**

| Name        | Type                             | Description                                                                                                  |
| ----------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| cardAddress | String                           | 조회할 카드 주소                                                                                                    |
| userAddress | String                           | 조회할 사용자 주소                                                                                                   |
| cursor      | String                           | (optional) 조회할 커서값입니다. 만약, 조회할 카드의 보유목록이 100개 이상이면, 다음 100개 정보를 받을 수 있습니다.                                   |
| callback    | `KlipCallback<CardListResponse>` | 요청 응답 결과를 받을 콜백함수입니다. 처리가 완료되면, 카드목록인 `CardListResponse`를 전송받고, 처리가 실패되면, 실패 결과인`KlipErrorResponse`를 전송받습니다. |

**Throws**

| Type                   | Description                      |
| ---------------------- | -------------------------------- |
| `KlipRequestException` | 요청 예외 (ex, 필수 Parameter 미입력시 발생) |

**Example**

```java
KlipCallback callback = new KlipCallback<KlipCardListResponse>() {
  @Override public void onSuccess(final KlipCardListResponse res) {}
  @Override public void onFail(final KlipErrorResponse res) {}
}

Klip klip = Klip.getInstance();
klip.getCardList("0x..card address..",
  "0x..user address..",
  null,
  callback);
```

## Error Code

에러코드는 `KlipCallback`의 실패의 응답결과인 `KlipErrorResponse`의 `getErrorCode()`함수를 통해 확인할 수 있습니다.

| Http Status | Error Code | Description                               |
| ----------- | ---------- | ----------------------------------------- |
| -           | -          | [Klip REST API 에러코드](/basics)와 동일         |
| 500         | 10         | Klip SDK에서 에러 발생 (ex, Http 연결 실패)         |
| 500         | 21         | Klip SDK에서 에러 발생 (Klip REST API 미지원 에러코드) |
| 500         | 22         | Klip SDK에서 에러 발생 (Klip Protocol 에러)       |

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# iOS SDK

이 페이지에서는 BApp에서 Klip을 활용하기 위한 App2App iOS SDK를 소개합니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

## 요구 사항

* iOS 12.0 이상
* Swift 5.0 이상
* Xcode 13.4 이상

## 환경 설정

Klip iOS SDK는 별도의 가입 절차가 필요하지 않습니다. HTTP 통신이 가능한 어느 환경에서도 동작합니다. 다만, 기본적으로 Klip 앱이 설치된 환경에서 호출해야 합니다. Klip 앱을 실행하여 Klip 사용자의 승인을 받아야 하기 때문입니다.

### 1. Klip SDK 적용

#### Option 1. SPM 사용

2.3.0 이상 버전만 사용 가능합니다.

```
https://github.com/ground-x/klip-a2a-ios-sdk.git
```

#### option 2. SDK 다운로드하여 적용

**1. Klip SDK 다운로드**

[다운로드](/a2a-sdk/a2a-sdk-download) 페이지에서 Klip iOS SDK를 다운받습니다.

**2. Klip SDK Framework 추가**

**Klip SDK Framework를 Import하여 개발 프로젝트에 추가**

1. 개발 중인 프로젝트를 **Xcode**로 실행
2. **Xcode > 개발 프로젝트의 TARGETS 선택 > General Tab > Framworks, Libraries, and Embedded Content Tab > 왼쪽 하단의 + 버튼**을 클릭
3. **Source Directory**에 다운받은 Klip SDK 프로젝트의 **sdk** 디렉토리를 선택, 클릭한 후 **Next**를 클릭
4. 왼쪽의 Project navigator의 Frameworks에 해당 SDK가 Import 되었는지 확인 후 build 수행

{% hint style="info" %}
Apple App Store 등록용 앱 빌드 시에는 `KlipLib.xcframework`만 포함되어야 합니다. `KlipLib-simulator.xcframework`는 개발 환경에만 사용해주세요.
{% endhint %}

Klip SDK 소스가 개발 프로젝트에 복사되고 라이브러리 코드를 직접 수정할 수 있습니다.

### 2. Info.plist 설정

#### 앱 실행 허용 목록(Allowlist) 등록하기

iOS 9.0 이상에서 iOS SDK로 Klip 등 애플리케이션 실행 기능을 이용하려면 Info.plist 파일에 설정을 추가하여 커스텀 스킴 정보를 등록해야 합니다.

\[Info] > \[Custom iOS Target Properties]에 Array 타입 키(Key)인 LSApplicationQueriesSchemes를 추가하고, 해당 키의 'Item'으로 커스텀 스킴에 사용할 값인 'klip'을 추가합니다.

```xml
 	<key>LSApplicationQueriesSchemes</key>
 	<array>
 		<string>klip</string>
 	</array>
```

### 4. Source Import 설정

#### v2.1.0 이상

```swift
import KlipLib
```

#### v2.1.0 미만

```swift
import KlipSDK
```

## API

### 개요

App2App API 요청은 크게 `prepare`, `request`, `getResult`의 순서로 진행이 됩니다.

* `prepare`는 어떠한 요청을 할지 요청을 정의하는 단계로 총 5가지 종류의 요청이 존재
* `request`는 함수 호출을 통해 Klip으로 화면이 전환되어 실제 서명 프로세스를 진행
* `getResult`는 함수 호출을 통해 결과값을 받고 확인

추가적으로 getCardList는 BApp 개발의 편의를 위해 Klip 사용자의 NFT 목록을 받아올 수 있도록 제공되는 함수입니다.

### KlipSDK.shared

Klip SDK를 사용하기 위한 인스턴스를 생성합니다.

**Return Value**

| Type   | Description |
| ------ | ----------- |
| `Klip` | Klip 인스턴스   |

**Example**

```swift
let klip = KlipSDK.shared
```

### KlipSDK.shared.prepare

`KlipSDK.shared.prepare(request: KlipRequest, bappInfo: BAppInfo, completion: @escaping(KlipCallback<KlipTxResponse>) -> Void)`\
\
App2App API 요청 처리를 준비하고 request key를 발급합니다.

**Request 값에 사용할 객체**

* Klip 연결 타입(=인증)의 경우 `AuthRequest`
* KAIA(=KLAY) 전송 타입의 경우 `KlayTxRequest`
* Token 전송 타입의 경우 `TokenTxRequest`
* Card 전송 타입의 경우 `CardTxRequest`
* Contract 실행 타입의 경우 `ContractTxRequest`
* Sign Message 요청 타입의 경우 `SignMessageRequest` - 이 경우 Klaytn 표준에 따라 `"\x19Klaytn Signed Message:\n" + len(message)`의 접두사를 붙여 서명합니다.

**Parameters**

| Name     | Type                           | Description                                                                                               |
| -------- | ------------------------------ | --------------------------------------------------------------------------------------------------------- |
| request  | `KlipRequest`                  | 요청 타입에 따른 요청정보                                                                                            |
| bappInfo | `BAppInfo`                     | 요청 앱 정보                                                                                                   |
| callback | `KlipCallback<KlipTxResponse>` | 요청 응답 결과를 받을 콜백함수입니다. 처리가 완료되면, 완료결과인 `KlipTxResponse`를 전송받고, 처리가 실패되면, 실패결과인`KlipErrorResponse`를 전송받습니다. |

Klip 사용자에게 동의 요청시, request와 bappInfo에 입력된 정보가 출력됩니다.\
응답 결과에 포함된 request key는 사용자에게 트랜잭션을 요청하기 위한 컨텍스트 키의 역할을 수행하며, 사용자 동의 요청 및 결과확인 API와 함께 사용 됩니다.

**Example 1. 사용자 정보 획득하기**

```swift
// 사용자 정보 획득 요청문
let req: AuthRequest = AuthRequest();

// BApp 정보
let bappInfo: BAppInfo = BAppInfo(name : "BApp Name");

// 응답 결과 Callback
KlipSDK.shared.prepare(request: req, bappInfo: bappInfo) { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

**Example 2. KAIA(=KLAY) 전송하기**

```swift
// KAIA 전송 트랜잭션 요청문
let req: KlayTxRequest = KlayTxRequest(to: "0x..receiver address..", amount: "10")
  
KlipSDK.shared.prepare(request: req, bappInfo: bappInfo) { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

**Example 3. Token 전송하기**

```swift
// Token 전송 트랜잭션 요청문
let req: TokenTxRequest = TokenTxRequest(to: "0x..receiver address..", amount: "10", contract: "0x..token contract address..")
  
KlipSDK.shared.prepare(request: req, bappInfo: bappInfo) { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

**Example 4. Card 전송하기**

```swift
// Card 전송 트랜잭션 요청문
let req: CardTxRequest = CardTxRequest(to: "0x..receiver address..", contract: "0x..card contract address..", cardId: "9")
  
KlipSDK.shared.prepare(request: req, bappInfo: bappInfo) { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

**Example 5. Contract 실행하기**

```swift
// Contract 실행 트랜잭션 요청문
let req: ContractTxRequest = ContractTxRequest(to: "0x..contract address..", value: "10", abi: "{...}", params: "[{...}]")
  
KlipSDK.shared.prepare(request: req, bappInfo: bappInfo) { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

**Example 6. Sign Message 요청하기**

```swift
// Sign Message 요청문
let req = SignMessageRequest(value: "message", from: "0x..contract address..")
  
KlipSDK.shared.prepare(request: req, bappInfo: bappInfo) { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

### KlipSDK.shared.request

`KlipSDK.shared.request(requestKey: String) -> Void`\
\
Deep Link를 이용하여 Klip에 인증 또는 서명을 요청합니다. 실행 중인 스마트폰 기기에 Klip 앱이 설치되지 않았거나 자동 실행할 수 없는 경우 'Klip 소개 페이지(<https://klipwallet.com>)' 로 이동하여 사용자는 Klip 앱을 다운로드받을 수 있습니다. requestKey에는 prepare 단계에서 Klip 서버로부터 받은 요청 번호를 사용합니다.

PC 환경에서 QR code를 이용한 request 스텝 처리는 [QR code 예제](/rest-api/rest-api-a2a#request-qr-code) 항목을 참조하십시오.

**Parameters**

| Name       | Type   | Description |
| ---------- | ------ | ----------- |
| requestKey | String | 요청 번호       |

**Example**

```swift
KlipSDK.shared.request(requestKey: "request key...")
```

### KlipSDK.shared.getResult

`KlipSDK.shared.getResult(requestKey: String, completion: @escaping(KlipCallback<KlipTxResponse>) -> Void)`\
\
App2App API 요청에 대한 결과를 확인합니다. requestKey에는 prepare 및 request 단계에서 사용한 요청 번호를 사용합니다.

**Parameters**

| Name       | Type                           | Description                                                                                               |
| ---------- | ------------------------------ | --------------------------------------------------------------------------------------------------------- |
| requestKey | String                         | 요청 번호                                                                                                     |
| callback   | `KlipCallback<KlipTxResponse>` | 요청 응답 결과를 받을 콜백함수입니다. 처리가 완료되면, 완료결과인 `KlipTxResponse`를 전송받고, 처리가 실패되면, 실패결과인`KlipErrorResponse`를 전송받습니다. |

**Example**

```swift
KlipSDK.shared.getResult(requestKey: "request key...") { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

### KlipSDK.shared.getCardList

`KlipSDK.shared.getCardList(cardAddress: String, userAddress: String, cursor: String?, completion: @escaping(KlipCallback<CardListResponse>) -> Void)`\
\
사용자의 모든 카드 중 특정 카드의 목록을 가져옵니다.

**Parameters**

| Name        | Type                             | Description                                                                                                  |
| ----------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| cardAddress | String                           | 조회할 카드 주소                                                                                                    |
| userAddress | String                           | 조회할 사용자 주소                                                                                                   |
| cursor      | String                           | (optional) 조회할 커서값입니다. 만약, 조회할 카드의 보유목록이 100개 이상이면, 다음 100개 정보를 받을 수 있습니다.                                   |
| callback    | `KlipCallback<CardListResponse>` | 요청 응답 결과를 받을 콜백함수입니다. 처리가 완료되면, 카드목록인 `CardListResponse`를 전송받고, 처리가 실패되면, 실패 결과인`KlipErrorResponse`를 전송받습니다. |

**Example**

```swift
KlipSDK.shared.getCardList(cardAddress: "0x..card address..", userAddress: "0x..user address..", cursor: nil) { result in
    switch result {
    case .success(let response):
    case .failure(let error):
    }
}
```

## Error Code

| Http Status | Error Code | Description                               |
| ----------- | ---------- | ----------------------------------------- |
| -           | -          | [Klip REST API 에러코드](/basics)와 동일         |
| 500         | 10         | Klip SDK에서 에러 발생 (ex, Http 연결 실패)         |
| 500         | 21         | Klip SDK에서 에러 발생 (Klip REST API 미지원 에러코드) |
| 500         | 22         | Klip SDK에서 에러 발생 (Klip Protocol 에러)       |

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Download

이 페이지에서는 App2App SDK 다운로드 링크를 제공합니다.   JavaScript는 npm을 통해서 설치할 수 있으며, Android 및 iOS는 zip 압축 파일을 제공합니다.

## JavaScript

| 프로그램                                                                       | 버전     | 배포일        |
| -------------------------------------------------------------------------- | ------ | ---------- |
| [npm package](https://www.npmjs.com/package/klip-sdk)                      | v2.3.3 | 2025.02.11 |
| [klipSDK-2.3.3.min.js](https://dl.klipwallet.com/sdk/klipSDK-2.3.3.min.js) | v2.3.3 | 2025.02.11 |
| [Sample App](https://dl.klipwallet.com/sdk/js/example_vanilla.zip)         | v2.3.3 | 2025.02.11 |

## Android

| 프로그램                                                                                               | 버전     | 배포일        | 참고                                                                                |
| -------------------------------------------------------------------------------------------------- | ------ | ---------- | --------------------------------------------------------------------------------- |
| [Android SDK Full Source & Samples](https://dl.klipwallet.com/sdk/klip-a2a-sdk-android-v2.3.0.zip) | v2.3.0 | 2024.11.18 | [레퍼런스](https://dl.klipwallet.com/sdk/docs/klip-a2a-sdk-android-v2.3.0/index.html) |

## iOS

| 프로그램                                                                                       | 버전     | 배포일        | 참고                                                                            |
| ------------------------------------------------------------------------------------------ | ------ | ---------- | ----------------------------------------------------------------------------- |
| [iOS SDK Full Source & Samples](https://dl.klipwallet.com/sdk/klip-a2a-sdk-ios-v2.3.0.zip) | v2.3.0 | 2024.11.18 | [레퍼런스](https://dl.klipwallet.com/sdk/docs/klip-a2a-sdk-ios-v2.3.0/index.html) |

{% hint style="warning" %}

* Klip SDK를 사용함에 있어 사용자는 (주)그라운드엑스를 사칭해서는 안됩니다.
* Klip SDK 사용에 따라 발생하는 모든 책임은 전적으로 사용자에게 있으며, (주)그라운드엑스는 사용자 또는 제3자에 대해 어떠한 책임도 지지 않습니다.
* 사용자는 Klip SDK를 상업적 용도로 판매할 수 없습니다.
* Klip SDK 사용자가 과도한 네트워크 트래픽을 발생시키는 시도하는 등 불법 혹은 비정상적인 방식으로 SDK를 사용하려고 시도하는 경우, 사전 고지없이 Klip SDK 및 Klip API 사용이 차단될 수 있습니다.
  {% endhint %}

## 오픈소스 사용 고지

* Android SDK: [오픈소스 라이브러리 사용에 대한 고지문](https://dl.klipwallet.com/sdk/docs/klip-a2a-sdk-android-v2.3.0/NOTICE.html)
* iOS SDK: [오픈소스 라이브러리 사용에 대한 고지문](https://dl.klipwallet.com/sdk/docs/klip-a2a-sdk-ios-v2.3.0/NOTICE.html)

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# WalletConnect

이 페이지에서는 WalletConnect를 이용해 클립을 연동하는 방법에 대해 설명합니다.

월렛커넥트(WalletConnect)는 지갑과 DApp(탈중앙화 블록체인 애플리케이션)을 연동하기 위한 프로토콜입니다. 월렛커넥트를 이용하면 개별적으로 지갑과 DApp의 연동을 개발할 필요 없이, 하나의 프로토콜로 지갑의 연결과 서명이 가능해집니다.

클립 역시 현재 월렛커넥트 v1 및 v2를 통한 디앱 연동을 지원하고 있습니다. 다만 월렛커넥트를 통한 지갑 연동은 카카오톡 내 클립이 아닌 [클립앱](https://klipwallet.com)만 지원하는 점 참고 부탁드립니다.

월렛커넥트에 대한 보다 자세한 소개와 개발 문서는 아래를 참고 하시기 바랍니다.

* 월렛커넥트 홈페이지: <https://walletconnect.com/>
* 월렛커넥트 개발문서: <https://docs.walletconnect.com/2.0>

{% hint style="info" %}
현재 클립은 솔라나 및 트론 네트워크에 대한 월렛커넥트 연동은 지원하지 않고 있으며, 추후 지원할 예정입니다.
{% endhint %}


# Tutorial

이 페이지는 Klip API 튜토리얼을 소개합니다.

Klip API 튜토리얼은 Klip Partners REST API 튜토리얼과 App2App REST API 튜토리얼로 구성됩니다.

## Klip Partners API

Klip Partners API는 카드(NFT)를 발행, 전송, 삭제, 관리하는 기능 구현을 위한 REST API입니다. Klip Partners API 튜토리얼은 Klip Partners 가입과 로그인, 카드 발행, 카드 정보 조회, 카드 전송, 카드와 계정 정보를 관리하는 방법을 상세하게 안내합니다.

## App2App API

App2App API는 여러분의 "BApp"을 "Klip"과 연동하는 기능 구현을 위한 API입니다. App2App API 튜토리얼은 BApp이 Klip에 접근하기 위한 환경 설정부터 BApp에서 Klip에 요청을 보냄으로써 사용자 인증(`auth`), KAIA(=KLAY) 전송(`send_klay`), 토큰 전송(`send_token`), 카드 전송(`send_card`), 컨트랙트 실행(`execute_contract`) 작업을 수행하는 과정을 상세하게 안내합니다. App2App API 튜토리얼은 REST API를 기준으로 안내합니다.

| 항목                                                   | 설명                                                        |
| ---------------------------------------------------- | --------------------------------------------------------- |
| [Klip Partners API](/tutorial/tutorial-card-minting) | 카드를 발행, 전송, 관리하는 방법                                       |
| [App2App API](/tutorial/tutorial-a2a-rest-api)       | BApp과 Klip을 연동해 카드, 토큰, KAIA(=KLAY) 전송 및 컨트랙트 실행을 요청하는 방법 |

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Klip Partners

이 튜토리얼은 Klip 파트너 여러분이 API를 사용해 카드를 손쉽게 발행, 관리하도록 돕기 위해 작성된 개발자 가이드입니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

## Klip Partners API Tutorial

### 1. Klip Partners <a href="#klip-partners" id="klip-partners"></a>

#### 1-1. 가입 신청과 승인 <a href="#registration" id="registration"></a>

카드를 발행하려면 먼저 Klip Partners 사이트에 가입해야 합니다. 가입을 신청하면 Klip 운영진과 별도로 협의한 후 가입이 승인됩니다. 가입이 승인되면 가입 승인 확인 메일을 받으며 Klip Partners에 로그인할 수 있습니다. 서비스 이용을 희망하는 파트너사는 원활한 사업 논의를 위해서 (1)회사 소개, (2)카드 활용 목적, (3)카드 활용 방안 등을 서면으로 정리해 <klip-partners@groundx.xyz>로 보내주시길 바랍니다.

{% hint style="info" %}
Klip Partners 웹사이트는 허가된 사용자만 접근 가능하나, Klip Partners 서비스가 2024년 7월 31일자로 종료되어 현재는 신규 가입 신청을 받지 않고 있습니다. 아울러 기존 사용자 역시 2024년 8월 1일부터 Klip Partners API를 호출할 수 없습니다.
{% endhint %}

#### 1-2. 로그인 <a href="#sign-in" id="sign-in"></a>

[Sign In](/rest-api/rest-api-card-minting#sign-in)으로 로그인 ID와 비밀번호( `email`과 `password`)를 Klip Partners에 보내고 로그인을 요청합니다.

* `password`는 비밀번호를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * 비밀번호는 8\~16자의 영문 대소문자, 숫자, 특수문자를 조합한 string 값입니다.

```bash
//Klip Partners 로그인
curl -X POST "https://api.klipwallet.com/v2/partner/auth" \
-d '{"email":"ray.kim@groundx.xyz", "password":"C01069C9ABB6EA7DA49AE418A24BBEF3AD67170DDCD20AC7C76084A5A85E4057"}' \
-H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```bash
{
  "email": "ray.kim@groundx.xyz",
  "klaytn_address":0xdc6AE5861a73d852bd3cdD84a4BA7f598A5160F3,
  "contract_address": "0xc94770007dda54cF92009BFF0dE90c06F603a09f",
  "name": "Ray Kim",
  "phone": "01077777777",
  "service_name": "판타지월드레볼루션",
  "access_token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJI...",
  "status" : 10,
  "mint_limit": 1000,
  "mint_count": 1,
}
```

Klip Partners에 가입하면 [Kaia](https://www.kaia.io/) 블록체인상에 여러분의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소와 카드를 발행할 스마트 컨트랙트가 생성됩니다. `klaytn_address`는 [Kaia](https://www.kaia.io/) 블록체인에 생성된 여러분의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소이며 `contract_address`는 카드를 발행할 스마트 컨트랙트 주소([SCA](https://docs.kaia.io/ko/learn/accounts/))입니다.

{% hint style="info" %}
로그인 시점으로부터 24시간 유효한 JWT 인증 토큰(`access_token`)을 받습니다. 이 토큰은 로그인 후 24시간이 지나면 만료되며 이 경우 재발급받아야 합니다.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="406" %}

```
"not found user info in db": 계정 정보가 존재하지 않습니다.
```

{% endtab %}

{% tab title="426" %}

```
"not yet approved": 아직 가입이 승인되지 않았습니다.
```

{% endtab %}

{% tab title="4004" %}

```
"invalid password": 비밀번호가 일치하지 않습니다.
```

{% endtab %}

{% tab title="기타" %}

```
로그인할 수 없습니다.
```

{% endtab %}
{% endtabs %}

### 2. 카드 발행하기 <a href="#mint-card" id="mint-card"></a>

#### 2-1. 카드 이미지 업로드하기 <a href="#upload-image" id="upload-image"></a>

카드 이미지는 카드가 Klip 사용자에게 보일 모양입니다. 카드를 발행하려면 이 카드 이미지를 먼저 업로드해야 합니다. [Upload Image](/rest-api/rest-api-card-minting#upload-image)로 카드 이미지 파일, 로그인 시 받은 `access_token`을 Klip Partners에 보내고 이미지 업로드를 요청합니다.

[Mint Card To User](/rest-api/rest-api-card-minting#mint-card-to-user)로 카드를 발행하려면 Upload Image API로 먼저 카드 이미지를 업로드해야 합니다.

```
//Klip Partners에 카드 이미지 업로드
curl -X POST "https://api.klipwallet.com/v2/wallet/image" \
-F upload=@./imagefile.png \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: multipart/form-data"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{"image": "https://path_to_image/image.png"}
```

이미지 파일이 업로드되면 업로드된 이미지 파일 URL 주소를 위와 같이 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
이미지를 업로드하지 못했습니다.
```

{% endtab %}
{% endtabs %}

#### 2-2. 특정 EOA에게 카드 발행하기 <a href="#mint-card-to-user" id="mint-card-to-user"></a>

[Mint Card To User](/rest-api/rest-api-card-minting#mint-card-to-user)로 `mint_info.json` 파일, 로그인 시 받은 `access_token`을 Klip Partners에 보내고 카드 발행을 요청합니다. 업로드한 카드 이미지를 사용합니다. EOA를 가진 사용자라면 누구나 카드를 발행받을 수 있습니다.

```
//카드 발행하기
curl -X POST "https://api.klipwallet.com/v2/wallet/mint" \
-d @./mint_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`mint_info.json` 예시는 아래와 같습니다. 이 파일에는 카드 이미지 URL 주소와 카드 발행에 필요한 정보가 담겨 있습니다.

```
//mint_info.json 파일 내용 예시
{
  "pin": "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
  "to_address": ["0x01ea07D1258c106FFD3197721a838F02408ea809",
    "0xE2d12bE9E570AE58277d6872B001fE9dF94D1531",
    "0xb1764B96da889Cc2F043025aa368517C80e86795"],
  "contract_address": "0xbad6444e1f84af055c22281d4ac7d75bde2ddec8",
  "name": "Magic Sword",
  "description" : "게임 내에서 마법 속성을 띈 마검을 소환할 수 있습니다.",
  "image": "https://path_to_image/image.png",
  "animation_url": "https://path_to_video/video.mp4",
  "background_color" : "#ae312e",
  "sendable": true,
  "send_friend_only": true,
  "group_name": "Ground X Magic Game",
  "group_icon": "https://path_to_image/image.png",
  "hashtags": ["Game","groundX","Magic"],
  "layout": "vertical",
  "external_link": "https://path_to_ext_link",
  "qr_code": "https://path_to_image/qr_image.png",
  "bar_code": "https://path_to_image/bar_image.png",
  "attributes" : [
    {
      "trait_type": "Sword", 
      "value": "Iron Short Sword"
    }, 
    {
      "trait_type": "Magic Type", 
      "value": "Fire"
    }, 
    {
      "trait_type": "Sword Level", 
      "value": "5"
    }, 
    {
      "trait_type": "Magic Level", 
      "value": "2"
    }
  ],
  "secure" : {
    "bar_code" : "1234 ABCD 5678 EFGH 90IJ",
    "qr_code" : "https://your-domain.com?key=1234",
    "attributes" : [
      {
        "trait_type": "Sword",
        "value": "Iron Short Sword"
      },
      {
        "trait_type": "Magic Type",
        "value": "Fire"
      },
      {
        "trait_type": "Sword Level",
        "value": "5"
      },
      {
        "trait_type": "Magic Level",
        "value": "2"
      }
    ]
  },
  "status_url" : "https://your-domain.com?key=1234"
}
```

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.
* `to_address`는 카드를 발행받을 사용자 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소들이 담긴 배열입니다.
  * `to_address`에 원소 1개짜리 배열을 전달하면 1명에게만 발행합니다.
  * `to_address`에 넣을 수 있는 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소 개수는 API 호출 1회당 최대 200개입니다.
* `sendable`이 TRUE이면 카드를 발행받은 사람은 발행받은 카드를 Klip에서 다른 사람에게 전송 가능합니다.
* `send_friend_only`가 TRUE이면 카드를 발행받은 사람은 발행받은 카드를 Klip에서 카카오톡 친구에게만 전송 가능합니다.
* `hashtags` 배열의 원소 개수는 최대 10개입니다. 각 원소는 최대 100글자입니다.
* `external_link`를 지정하면 Klip 외부 브라우저로 연결되는 URL 주소를 넣을 수 있습니다. 최대 255자까지 가능합니다.
* `qr_code`로 사용할 이미지는 가로 400px 이상이고 상하좌우 여백이 없는 것을 권장합니다.
* `bar_code`로 사용할 이미지는 가로 400px 이상이고 상하좌우 여백이 없는 것을 권장합니다.
* `attributes`는 카드의 고유한 속성을 `trait_type/value` 형태로 가지는 `object`들의 배열입니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{
  "hash": "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97"
}
```

카드가 정상 발행되었다면 카드를 발행한 스마트 컨트랙트 트랜잭션 해시값을 위와 같이 받습니다. 전달받은 트랜잭션 해시값을 [Kaiascope](https://kaiascope.com/)에서 조회할 수 있습니다. 이 해시값을 조회하면 카드 발행 트랜잭션이 정상 실행되었는지 확인할 수 있습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
정상적인 카드 발행에 실패했습니다.
일부 카드는 발행되었을 수 있으니 ‘보유 카드 목록’ 에서 보유 목록을 확인하십시오.
```

{% endtab %}
{% endtabs %}

#### 2-3. 특정 Klip 회원에게 카드 발행하기 <a href="#mint-card-to-klip-member" id="mint-card-to-klip-member"></a>

[Mint Card To Klip Member](/rest-api/rest-api-card-minting#mint-card-to-klip-member)로 `mint_info.json` 파일, 로그인 시 받은 `access_token`을 Klip Partners에 보내고 카드 발행을 요청합니다. Klip 회원의 실명과 전화번호를 사용하여 Klip 회원에게만 카드를 발행합니다.

```
//카드 발행하기
curl -X POST "https://api.klipwallet.com/v2/wallet/mint/person" \
-d @./mint_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`mint_info.json` 예시는 아래와 같습니다. 이 파일에는 카드 이미지 URL 주소와 카드 발행에 필요한 정보가 담겨 있습니다.

```
//mint_info.json 파일 내용 예시
{
  "pin": "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
  "to_person": [["홍길동", "010-1111-2222"], ["김춘향", "010-3333-4444"]]
  "contract_address": "0xbad6444e1f84af055c22281d4ac7d75bde2ddec8",
  "name": "Magic Sword",
  "description" : "Summons a magic sword that has magical properties and effects in the game.",
  "image": "https://path_to_image/image.png",
  "animation_url": "https://path_to_video/video.mp4",
  "background_color" : "#ae312e",
  "sendable": true,
  "send_friend_only": true,
  "group_name": "Ground X Magic Game",
  "group_icon": "https://path_to_image/image.png",
  "hashtags": ["Game","groundX","Magic"],
  "layout": "vertical",
  "external_link": "https://path_to_ext_link",
  "qr_code": "https://path_to_image/image.png",
  "bar_code": "https://path_to_image/bar_image.png",
  "attributes" : [
    {
      "trait_type": "Sword", 
      "value": "Iron Short Sword"
    }, 
    {
      "trait_type": "Magic Type", 
      "value": "Fire"
    }, 
    {
      "trait_type": "Sword Level", 
      "value": "5"
    }, 
    {
      "trait_type": "Magic Level", 
      "value": "2"
    }
  ],
  "secure" : {
    "bar_code" : "1234 ABCD 5678 EFGH 90IJ",
    "qr_code" : "https://your-domain.com?key=1234",
    "attributes" : [
      {
        "trait_type": "Sword",
        "value": "Iron Short Sword"
      },
      {
        "trait_type": "Magic Type",
        "value": "Fire"
      },
      {
        "trait_type": "Sword Level",
        "value": "5"
      },
      {
        "trait_type": "Magic Level",
        "value": "2"
      }
    ]
  },
  "status_url" : "https://your-domain.com?key=1234"
}
```

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.
* `to_person`은 카드를 발행받을 사용자 \[실명, 전화번호] 배열들이 담긴 2차원 배열입니다.
  * `to_person`에 원소 1개짜리 배열을 전달하면 1명에게만 발행합니다.
  * `to_person`에 넣을 수 있는 \[실명, 전화번호] 개수는 API 호출 1회당 최대 200개입니다.
  * `to_person` 파라미터에 전달한 실명과 전화번호로 가입한 Klip 회원이 없다면 발행에 실패합니다.
* `sendable`이 TRUE이면 카드를 발행받은 사람은 발행받은 카드를 Klip에서 다른 사람에게 전송 가능합니다.
* `send_friend_only`가 TRUE이면 카드를 발행받은 사람은 발행받은 카드를 Klip에서 카카오톡 친구에게만 전송 가능합니다.
* `hashtags` 배열의 원소 개수는 최대 10개입니다. 각 원소는 최대 100글자입니다.
* `external_link`를 지정하면 Klip 외부 브라우저로 연결되는 URL 주소를 넣을 수 있습니다. 최대 255자까지 가능합니다.
* `qr_code`로 사용할 이미지는 가로 400px 이상이고 상하좌우 여백이 없는 것을 권장합니다.
* `bar_code`로 사용할 이미지는 가로 400px 이상이고 상하좌우 여백이 없는 것을 권장합니다.
* `attributes`는 카드의 고유한 속성을 `trait_type/value` 형태로 가지는 `object`들의 배열입니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{
  "hash": "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97",
  "result": [["홍길동", "010-1111-2222", "success", ""], ["김춘향", "010-3333-4444", "fail", "phone number does not exist"], ...]
}
```

카드가 정상 발행되었다면 카드를 발행한 스마트 컨트랙트 트랜잭션 전송 결과 및 트랜잭션 해시를 받습니다.`to_person`에 입력한 회원 중 1명이라도 카드를 정상적으로 발행받았다면 요청이 정상 처리된 것으로 나타납니다.

{% hint style="info" %}
위 결과에서 "홍길동" 회원은 해당 실명과 전화번호로 Klip에 가입한 정보가 존재하므로 카드를 발행받습니다.\
위 결과에서 "김춘향" 회원은 해당 전화번호로 Klip에 가입한 정보가 존재하지 않으므로 카드를 발행받지 못합니다.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
정상적인 카드 발행에 실패했습니다.
일부 카드는 발행되었을 수 있으니 ‘보유 카드 목록’ 에서 보유 목록을 확인하십시오.
```

{% endtab %}
{% endtabs %}

#### 2-4. 카드 동영상 파일 업로드하기 <a href="#upload-nftresource" id="upload-nftresource"></a>

카드를 발행할 때 `animation_url` 필드를 설정하기 위해서는 카드 동영상을 먼저 업로드해야 합니다. [Upload NFT Resource](/rest-api/rest-api-card-minting#upload-nftresource)로 카드 동영상 파일, 로그인 시 받은 `access_token`을 Klip Partners에 보내고 동영상 업로드를 요청합니다.

```
//Klip Partners에 카드 동영상 업로드
curl -X POST "https://api.klipwallet.com/v2/wallet/nftResource" \
-F upload=@./video.mp4 \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: multipart/form-data"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{"url": "https://path_to_video/video.mp4"}
```

파일이 업로드되면 업로드된 파일 URL을 위와 같이 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
파일을 업로드하지 못했습니다.
```

{% endtab %}
{% endtabs %}

#### 2-5. Secure 리소스 포함 이미지 또는 동영상 업로드하기 <a href="#upload-secure-nftresource" id="upload-secure-nftresource"></a>

Secure 정보를 포함한 NFT를 업로드합니다. Secure 정보는 NFT 소유자만 확인할 수 있는 정보를 오브젝트 형태로 저장합니다. attributes, qr\_code, bar\_code 필드를 선택적으로 설정할 수 있습니다.

```
//Klip Partners에서 secure 미디어를 직접 업로드
curl -X POST "https://api.klipwallet.com/v2/wallet/nftResource/secure" \
-F upload=@./file.mp4 \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: multipart/form-data"
```

요청이 정상 처리되면 아래 값을 받습니다.

```json
{"filename": "{uuid}.{extension}"}
```

파일이 업로드되면 업로드된 파일 URL을 위와 같이 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4100" %}

```
"upload animation file limit exceeded": 동영상 파일의 경우 제한된 크기 10MiB를 넘었습니다. 파일 크기를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4101" %}

```
"upload animation file extension is not support": 지원하지 않는 동영상 포맷입니다.
```

{% endtab %}

{% tab title="기타" %}

```
파일을 업로드하지 못했습니다.
```

{% endtab %}
{% endtabs %}

### 3. 카드 조회하기 <a href="#query-card" id="query-card"></a>

#### 3-1. BApp과 카드 정보 함께 조회하기 <a href="#get-card-information-by-bapp" id="get-card-information-by-bapp"></a>

카드를 발행했다면 발행한 카드를 포함해 소유한 카드 정보를 BApp 정보와 함께 조회할 수 있습니다. [Get Card Information by BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp)으로 로그인 시 받은 `access_token`을 보내고 BApp별 카드 정보 조회를 요청합니다.

```
//Get Card Information By BApp
curl "https://api.klipwallet.com/v2/wallet/bapp" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

{% hint style="warning" %}
본 API의 경우, 클립의 자산 리스팅 정책 변경에 따라 일부 새로운 카드는 조회가 불가능할 수도 있습니다. 대신 [App2App의 Get Card Information](/rest-api/rest-api-a2a#get-card-information) API 사용을 권장합니다.
{% endhint %}

요청이 정상 처리되면 아래 값을 받습니다.

```
//BApp 목록과 BApp별 카드 정보 예시
{
    "bapps": [
        {
            "id": 2,
            "name": "bapp2",
            "bapp_img": "/img/bapp-icon2.svg",
            "category_id": 2,
            "nft_order_no": 1,
            "summary": "summary",
            "card_count": 10,
            "nft_id": 52,
            "cards": [
                    {
                        "created_at": 1580300503,
                        "updated_at": 1580300503,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 18,
                        "card_uri": "https://...",
                        "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },
                    {
                        "created_at": 1580300504,
                        "updated_at": 1580300504,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 19,
                        "card_uri": "https://...",
                        "transaction_hash": "0x8814f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },
                    {
                        "created_at": 1580300505,
                        "updated_at": 1580300505,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 20,
                        "card_uri": "https://...",
                        "transaction_hash": "0x9254f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },
                ],
            "cards_next_cursor": ""
        },
        {
            "id": 3,
            "name": "bapp3",
            "bapp_img": "/img/bapp-icon3.svg",
            "category_id": 2,
            "nft_order_no": 2,
            "summary": "summary",
            "card_count": 10,
            "nft_id": 55,
            "cards": [
                    {
                        "created_at": 1580300511,
                        "updated_at": 1580300511,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 5,
                        "card_uri": "https://...",
                        "transaction_hash": "0x1a54f10f73468ea85c84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },

                ],
            "cards_next_cursor": ""
        },
    ],
    "next_cursor": ""
}
```

카드 정보가 정상 조회되었다면 계정이 쓰는 모든 BApp 목록과 BApp별 카드 정보를 받습니다.

* `bapps`에서 **bapp**은 Klip 파트너사가 서비스하는 BApp입니다.
* `cards`에서 **card**는 이 BApp에서 쓰이는 Klip 카드입니다. BApp에는 카드 1종류가 들어있습니다.
* `nft_id`란 이 **card**를 블록체인 상에 만드는 스마트 컨트랙트의 ID입니다.
* **nft**와 **bapp**은 항상 1:1로 맵핑됩니다.
* `card_uri`는 카드 메타데이터가 담긴 JSON 파일이 있는 URL입니다.
  * 카드 메타데이터는 `name`, `description`, `image`, `background_color`, `attributes` 등 카드를 발행할 때 정의한 카드 기본 정보입니다.

1회 요청에 BApp 정보를 최대 100개까지 받습니다. 불러올 BApp 개수가 100개 이상이면 다음 BApp 정보를 불러올 수 있는 페이지네이션 커서값인 `bapps.next_cursor`로 나머지 카드 정보를 받습니다.\
나머지 BApp 정보를 받으려면 Query 파라미터 `cursor`에 이전 호출에서 받은 `bapps.next_cursor`를 넣고 API를 다시 호출합니다.

또 1회 요청에 BApp별로 BApp에서 쓰이는 카드 정보를 최대 100개까지 받습니다. BApp별로 카드가 100개를 초과할 경우 나머지 카드 정보를 받으려면, [Get Card Information](/rest-api/rest-api-card-minting#get-card-information) API로 각 카드 정보를 확인해야 합니다.

위 API 응답값을 보면 발행자는 BApp 2개를 사용하며, 첫 번째 BApp에는 카드에 3개가, 두 번째 BApp에는 카드 1개가 있습니다.\
`bapps[0].cards` 배열을 보면 카드 생성/업데이트 시간, 카드 소유자 주소, 카드를 보내준 사람 주소, 카드 발행 트랜잭션 해시 등 각 카드에 관한 상세 정보를 확인할 수 있습니다.

한 번에 조회할 BApp 개수가 100개를 초과한다면 1회 호출 시 BApp 100개 정보만 받고 `bapps.next_cursor`값을 받습니다.\
나머지 BApp 정보를 조회하려면 `bapps.next_cursor`값을 Query 파라미터 `cursor`에 전달하고 API를 다시 호출해야 합니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
BApp별로 보유한 카드 목록을 조회하지 못했습니다.
```

{% endtab %}
{% endtabs %}

#### 3-2. 카드 정보만 조회하기 <a href="#get-card-information" id="get-card-information"></a>

각 BApp은 카드를 생성하는 스마트 컨트랙트 ID인 `nft_id`가 있습니다. [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)으로 Path 파라미터 `nft_id`, 로그인 시 받은 `access_token`을 Klip Partners에 보내고 BApp별로 카드 정보를 조회합니다.

```
//Get Card Information - '52' is the `nft_id` of our interest.
curl "https://api.klipwallet.com/v2/wallet/nft/52" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
//카드 정보를 받은 예시.
{
    "name": "conan",
    "symbol_img": "",
    "cards": [
            {
                "created_at": 1580300501,
                "updated_at": 1580300501,
                "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                "sender": "0x0000000000000000000000000000000000000000",
                "card_id": 1,
                "card_uri": "https://...",
                "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
            },
            ...
            {
                "created_at": 1580300502,
                "updated_at": 1580300502,
                "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                "sender": "0x0000000000000000000000000000000000000000",
                "card_id": 100,
                "card_uri": "https://...",
                "transaction_hash": "0x9254f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
            },

        ],
    "next_cursor": "mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL",
}
```

카드 정보가 정상 조회되었다면 계정이 이 BApp에서 소유한 카드 목록과 정보를 받습니다.

* `cards`에서 **card**는 이 bapp에서 쓰이는 Klip 카드입니다. bapp에는 카드 1종류가 들어있습니다.
* Query 파라미터로 `cursor` 또는 `isAll` 둘 중 하나만 사용해야 합니다(`isAll`이 `false`이면 `cursor`를 사용할 수 있습니다).
* `cursor`를 사용하면 Pagination을 사용합니다.
  * 1회 요청에 최대 카드 100개의 정보를 받습니다.
  * 정보를 불러울 카드가 100개를 초과 시 다음 카드 정보를 불러올 수 있는 커서값인 `next_cursor`로 나머지 카드 정보를 받습니다.
  * 나머지 카드 정보를 받으려면 `cursor`에 이전 호출에서 받은 `next_cursor`를 넣고 API를 다시 호출합니다.
* `nft_id`는 [Get Card Information by BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp) API로 받은 BApp 정보에서 확인합니다.

위 예시에서 `cards.next_cursor`값이 존재하므로 이 계정은 **conan** 카드를 100개 이상 가지고 있습니다.\
한 번에 조회할 카드 개수가 100개를 초과한다면 1회 호출 시 카드 100개 정보만 받고 `cards.next_cursor`값을 받습니다.\
나머지 카드 정보를 조회하려면 `cards.next_cursor`값을 Query 파라미터 `cursor`에 전달하고 API를 다시 호출해야 합니다.

예를 들어, 정보를 불러올 카드 개수가 150개라면, 먼저 API를 호출하여 카드 100개의 정보와 `cards.next_cursor`값을 받습니다.\
그리고 동일한 API를 다시 호출할 때 `cards.next_cursor`값을 Query 파라미터 `cursor`로 사용하면 나머지 50개의 정보를 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 정보를 조회하지 못했습니다.
```

{% endtab %}
{% endtabs %}

[Get Card Information](/rest-api/rest-api-card-minting#get-card-information)으로 `cards.next_cursor`값과 로그인 시 받은 `access_token`을 Klip Partners에 보내고 나머지 카드 정보 조회를 요청합니다.

```
//Get Card Information, cards.next_cursor 값을 cursor로 사용
curl "https://api.klipwallet.com/v2/wallet/nft/52?cursor=mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
//cursor를 사용해 나머지 50개 카드 정보를 받은 예시.
{
    "name": "conan",
    "symbol_img": "",
    "cards": [
          {
              "created_at": 1580300503,
              "updated_at": 1580300503,
              "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
              "sender": "0x0000000000000000000000000000000000000000",
              "card_id": 101,
              "card_uri": "https://...",
              "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
          },
          ...
          {
              "created_at": 1580300515,
              "updated_at": 1580300515,
              "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
              "sender": "0x0000000000000000000000000000000000000000",
              "card_id": 150,
              "card_uri": "https://...",
              "transaction_hash": "0x9254f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
          },

      ],
    "next_cursor": "",
}
```

{% hint style="info" %}
`cards` 배열의 상세 정보는 [Get Card Information by BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp)으로 받는`bapps[i].cards`배열 정보와 동일합니다.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 정보를 조회하지 못했습니다.
```

{% endtab %}
{% endtabs %}

#### 3-3. 카드가 100개를 초과할 때 나머지 카드 정보 조회하기 <a href="#get-extra-card-information" id="get-extra-card-information"></a>

[Get Card Information By BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp)은 1회 요청에 각 BApp당 카드 정보를 최대 100개까지만 반환합니다. BApp별 카드가 100개를 초과할 때 나머지 카드 정보까지 받으려면, [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)을 따로 호출해야 합니다. 101번째 카드부터 조회하려면 `bapps[i].cards_next_cursor`를 Query 파라미터 `cursor`로 사용해 [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)을 호출합니다.

예를 들어, BApp을 2개 가지고 있고 BApp1에 카드 150개, BApp2에 카드 200개가 있을 때 [Get Card Information By BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp)을 호출하면 BApp1 카드 100개, BApp2 카드 100개의 정보만을 받습니다. [Get Card Information By BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp)으로 로그인 시 받은 `access_token`을 보내고 BApp별 카드 정보 조회를 요청해야 합니다.

```
//Get Card Information By BApp
curl "https://api.klipwallet.com/v2/wallet/bapp" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

{% hint style="warning" %}
본 API의 경우, 클립의 자산 리스팅 정책 변경에 따라 일부 새로운 카드는 조회가 불가능할 수도 있습니다. 대신 [App2App의 Get Card Information](/rest-api/rest-api-a2a#get-card-information) API 사용을 권장합니다.
{% endhint %}

요청이 정상 처리되면 아래 값을 받습니다.

```
//BApp1은 카드 150개, BApp2는 카드 200개 보유 시 Get Card Information By BApp 결과 예시
{
    "bapps": [
        {
            "id": 1,
            "name": "bapp1",
            "bapp_img": "/img/bapp-icon1.svg",
            "category_id": 2,
            "nft_order_no": 1,
            "summary": "summary",
            "card_count": 150,
            "nft_id": 60,
            "cards": [
                    {
                        "created_at": 1580300503,
                        "updated_at": 1580300503,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 1,
                        "card_uri": "https://...",
                        "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },

                    ...

                    {
                        "created_at": 1580300505,
                        "updated_at": 1580300505,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 100,
                        "card_uri": "https://...",
                        "transaction_hash": "0x9254f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },
                ],
            "cards_next_cursor": "gKvkL1lPYv1P93dpEWgaBzrq7XZ4LwjpgNe39AH9Dt3C1iWkubJtGotkrsQs4qSwdIJMHr3HKrhlCqJupwToWCd0T55IKhLzARM60N5xAGJQbKomeDkVl2O8WxMB0GQ9"
        },
        {
            "id": 2,
            "name": "bapp2",
            "bapp_img": "/img/bapp-icon2.svg",
            "category_id": 2,
            "nft_order_no": 2,
            "summary": "summary",
            "card_count": 200,
            "nft_id": 61,
            "cards": [
                    {
                        "created_at": 1580300511,
                        "updated_at": 1580300511,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 1,
                        "card_uri": "https://...",
                        "transaction_hash": "0x1a54f10f73468ea85c84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },

                    ...

                    {
                        "created_at": 1580300515,
                        "updated_at": 1580300515,
                        "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                        "sender": "0x0000000000000000000000000000000000000000",
                        "card_id": 100,
                        "card_uri": "https://...",
                        "transaction_hash": "0x3t54f10f73468ea85c84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
                    },

                ],
            "cards_next_cursor": "Xrzed2Ot9LeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL"
        },
    ],
    "next_cursor": ""
}
```

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
BApp별로 보유한 카드 목록을 조회하지 못했습니다.
```

{% endtab %}
{% endtabs %}

BApp1 나머지 50개 카드 정보를 받으려면 Query 파라미터 `cursor`에 `bapps[0].cards_next_cursor`값인 `gKvkL1lPYv1P93dpE...`를 전달해 [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)을 호출해야 합니다.

[Get Card Information](/rest-api/rest-api-card-minting#get-card-information)으로 `gKvkL1lPYv1P93dpE...`과 로그인 시 받은 `access_token`을 Klip Partners에 보내고 BApp1 나머지 카드 50개 정보 수신을 요청합니다.

```
//BApp 1 나머지 카드 정보 수신 예시
//Get Card Information, bapps[0].cards_next_cursor값을 cursor로 사용
curl "https://api.klipwallet.com/v2/wallet/nft/60?cursor=gKvkL1lPYv1P93dpEWgaBzrq7XZ4LwjpgNe39AH9Dt3C1iWkubJtGotkrsQs4qSwdIJMHr3HKrhlCqJupwToWCd0T55IKhLzARM60N5xAGJQbKomeDkVl2O8WxMB0GQ9" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
//cursor를 사용해 나머지 50개 카드 정보를 받은 예시.
{
    "name": "ray1",
    "symbol_img": "",
    "cards": [
            {
                "created_at": 1580300503,
                "updated_at": 1580300503,
                "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                "sender": "0x0000000000000000000000000000000000000000",
                "card_id": 101,
                "card_uri": "https://...",
                "transaction_hash": "0x9e54f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
            },
            ...
            {
                "created_at": 1580300515,
                "updated_at": 1580300515,
                "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                "sender": "0x0000000000000000000000000000000000000000",
                "card_id": 150,
                "card_uri": "https://...",
                "transaction_hash": "0x92d4f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
            },

        ],
    "next_cursor": "",
}
```

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 정보를 조회하지 못했습니다.
```

{% endtab %}
{% endtabs %}

BApp2 나머지 카드 100개 정보를 받으려면 Query 파라미터 `cursor`에 `bapps[1].cards_next_cursor`값인 `Xrzed2Ot9LeEor...`을 전달해 [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)을 호출해야 합니다. [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)으로 `Xrzed2Ot9LeEor...`과 로그인 시 받은 `access_token`을 Klip Partners에 보내고 BApp2 나머지 카드 100개 정보 수신을 요청합니다.

```
//BApp 2 나머지 카드 정보 수신 예시
//Get Card Information, bapps[1].cards_next_cursor값을 cursor로 사용
curl "https://api.klipwallet.com/v2/wallet/nft/61?cursor=Xrzed2Ot9LeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
//cursor를 사용해 나머지 100개 카드 정보를 받은 예시.
{
    "name": "ray2",
    "symbol_img": "",
    "cards": [
            {
                "created_at": 1580300505,
                "updated_at": 1580300505,
                "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                "sender": "0x0000000000000000000000000000000000000000",
                "card_id": 101,
                "card_uri": "https://...",
                "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
            },
            ...
            {
                "created_at": 1580300520,
                "updated_at": 1580300520,
                "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
                "sender": "0x0000000000000000000000000000000000000000",
                "card_id": 200,
                "card_uri": "https://...",
                "transaction_hash": "0x9254f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
            },

        ],
    "next_cursor": "",
}
```

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 정보를 조회하지 못했습니다.
```

{% endtab %}
{% endtabs %}

#### 3-4. 카드 개수에 관계없이 한 번에 조회하기 <a href="#get-all-card-information" id="get-all-card-information"></a>

페이지네이션으로 카드 정보를 100개씩 확인하지 않고 한 번에 모든 카드 정보를 받으려면 [Get Card Information](/rest-api/rest-api-card-minting#get-card-information)으로 Query 파라미터 `isAll`, Path 파라미터 `nft_id`, 로그인 시 받은 `access_token`을 Klip Partners에 보내고 모든 카드 정보를 요청합니다.

```
//Get All Card Information - '52' is the `nft_id` of our interest.
curl "https://api.klipwallet.com/v2/wallet/nft/52?isAll=true" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
//카드 정보를 받은 예시.
{
    "name": "conan",
    "symbol_img": "",
    "cards": [
        {
            "created_at": 1580300501,
            "updated_at": 1580300501,
            "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
            "sender": "0x0000000000000000000000000000000000000000",
            "card_id": 1,
            "card_uri": "https://...",
            "transaction_hash": "0x8754f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
        },
        ...
        {
            "created_at": 1580300502,
            "updated_at": 1580300502,
            "owner": "0xa3b7aa3a3c8a08bd22f77932368e2043e7ffe263",
            "sender": "0x0000000000000000000000000000000000000000",
            "card_id": 100,
            "card_uri": "https://...",
            "transaction_hash": "0x9254f10f73468ea85e84d9e29c2a864fc574c1e57675bfc70b5459d82477a91f"
        },

    ],
    "next_cursor": "",
}
```

카드 정보가 정상 조회되었다면 계정이 이 BApp에서 쓰는 모든 카드 목록과 정보를 받습니다.

* Query 파라미터로 `cursor` 또는 `isAll` 둘 중 하나만 사용해야 합니다(`isAll`이 `false`이면 `cursor`를 사용할 수 있습니다).

{% hint style="info" %}
`cards` 배열의 상세 정보는 [Get Card Information by BApp](/rest-api/rest-api-card-minting#get-card-information-by-bapp)으로 받는`bapps[i].cards`배열 정보와 동일합니다.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 정보를 조회하지 못했습니다.
```

{% endtab %}
{% endtabs %}

#### 3-5. Secure 리소스 포함 이미지 또는 동영상 정보 조회하기 <a href="#get-secure-card-information" id="get-secure-card-information"></a>

파트너사에서 업로드한 secure 미디어 파일 목록을 조회할 수 있습니다. 반환되는 파일 목록 형태는 `<uploaded_secure_url>/<uploaded_files[0]>?<uploaded_secure_query>`이며, 사용하려면 Klip 팀으로 먼저 문의하시기 바랍니다.

```
//
curl "https://klipmedia/../uploaded/{uuid-1}.mp4?Base64PolicyQuery.." \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```json
//업로드된 파일이 있는 경우
{
  "uploaded_files" : ["{uuid-1}.mp4", "{uuid-2}.mp4"]
  "uploaded_secure_url" : "https://klipmedia/../uploaded"
  "uploaded_secure_query" : "Base64PolicyQuery"
}

// 업로드된 파일이 없는 경우
{
  "uploaded_files" : []
  "uploaded_secure_url" : ""
  "uploaded_secure_query" : ""
}
```

### 4. 카드 전송하기 <a href="#send-card" id="send-card"></a>

#### 4-1. 특정 EOA에게 전송하기 <a href="#send-card-to-user" id="send-card-to-user"></a>

[Send Card To User](/rest-api/rest-api-card-minting#send-card-to-user)로 Klip Partners에 로그인 시 받은 `access_token`, `send_info.json` 파일, 전송할 BApp 카드의 `nft_id`와 `card_id`(Path 파라미터)를 보내고 현재 계정 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소에 있는 카드를 다른 사람의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소로 전송하도록 요청합니다.

EOA를 가진 사용자라면 누구나 카드를 전송받을 수 있습니다.

```
curl -X POST "https://api.klipwallet.com/v2/wallet/nft/50/1/send" \
-d @./send_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`send_info.json` 파일 예시는 아래와 같습니다.

```
//게임 아이템 카드인 마법 검 카드를 보내기 위한 send_info.json 파일 내용 예시
{
    "pin": "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
    "to_address": "0xb1764B96da889Cc2F043025aa368517C80e86795",
    "card_name": "Magic Sword"
}
```

이 파일에는 카드 이름, `pin`, 카드를 받는 사람의 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소가 담겨 있습니다.

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{ to_address: "0xb1764B96da889Cc2F043025aa368517C80e86795",
  fail_count: 0,
  tx_hash: "0x7cf09602cebb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97" }
```

전송에 성공하면 카드 수신자 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소, 전송 실패 횟수, 카드를 전송한 트랜잭션 해시값을 받습니다. 전송에 성공하면 `fail_count` 0을 받습니다.

{% hint style="info" %}
카드를 보내면 Klip 회원인 카드 수신자는 알림톡을 받습니다. 전송자는 알림톡을 받지 않습니다. Klip 사용자에게 카드를 전송 시 `card_name`을 입력해야 받는 사람에게 카드 이름이 정상 표시됩니다.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}

#### 4-2. 특정 Klip 회원에게 전송하기 <a href="#send-card-to-klip-member" id="send-card-to-klip-member"></a>

[Send Card To Klip Member](/rest-api/rest-api-card-minting#send-card-to-klip-member)로 Klip Partners에 로그인 시 받은 `access_token`, `send_info.json` 파일, 전송할 BApp 카드의 `nft_id`와 `card_id`(Path 파라미터)를 보내고 현재 계정 [EOA](https://docs.kaia.io/ko/learn/accounts/) 주소에 있는 카드를 다른 사람에게 전송하도록 요청합니다.

Klip 회원의 실명과 전화번호를 사용하여 Klip 회원에게만 카드를 전송합니다.

```
curl -X POST "https://api.klipwallet.com/v2/wallet/nft/50/1/send/person" \
-d @./send_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`send_info.json` 파일 예시는 아래와 같습니다.

```
//게임 아이템 카드인 마법 검 카드를 보내기 위한 send_info.json 파일 내용 예시
{
    "pin": "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
    "to_person": ["홍길동", "010-1111-2222"]
    "card_name": "Magic Sword"
}
```

이 파일에는 카드 이름, `pin`, 카드를 받는 사람이 Klip 회원에 가입 시 사용한 실명과 전화번호가 담겨 있습니다.

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.
* `to_person` 파라미터에 전달한 실명과 전화번호로 가입한 Klip 회원이 없다면 전송에 실패합니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{fail_count: 0, tx_hash: "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97"}
```

전송에 성공하면 `fail_count` 0을 받습니다.

{% hint style="info" %}
카드를 보내면 Klip 회원인 카드 수신자는 알림톡을 받습니다. 전송자는 알림톡을 받지 않습니다. Klip 사용자에게 카드를 전송 시 `card_name`을 입력해야 받는 사람에게 카드 이름이 정상 표시됩니다.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}

### 5. 에스크로 <a href="#escrow" id="escrow"></a>

#### 5-1. 에스크로 사용 동의 <a href="#approve-escrow" id="approve-escrow"></a>

에스크로 기능을 사용하기 위해서는 카드 발급을 위한 컨트랙트에서 에스크로 컨트랙트를 승인하는 과정이 필요합니다. 사용 동의는 한 번만 수행하면 되며 이후에는 다시 수행할 필요가 없습니다.

```
curl -X POST "https://api.klipwallet.com/v2/escrow/approve" \
-d @./approve_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`approve.json` 파일 예시는 아래와 같습니다.

```
{
    "pin": "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
    "contract_address": "0x6E3571F451fc960Ea69b532006A2c8683fF8922F"
}
```

이 파일에는 `pin`, `contract_address`는 카드를 발행한 스마트 컨트랙트 주소([SCA](https://docs.kaia.io/ko/learn/accounts/))가 들어갑니다.

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{
    "tx_hash":"0x831e207b0b951127646b8f7d7eded55903cecb29fe794e17a2d93f457b7158a4",
    "fail_count":0,
}
```

에스크로 생성에 성공하면 트랜잭션 해시값을 받습니다. 만약 `pin` 확인에 실패한 경우 `fail_count`에 0보다 큰 값을 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}

#### 5-2. 에스크로 사용 동의 여부 조회 <a href="#get-approve-escrow" id="get-approve-escrow"></a>

에스크로 사용 동의 여부를 조회할 수 있습니다.

```
curl -X GET "https://api.klipwallet.com/v2/escrow/approve?contract_address=0x6E3571F451fc960Ea69b532006A2c8683fF8922F" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{
    "approve":true
}
```

에스크로 생성에 성공하면 `approve` 필드에 `true` 값을 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}

#### 5-3. 에스크로 전송 링크 생성 <a href="#create-escrow" id="create-escrow"></a>

에스크로 전송은 Klip 회원에게 카드를 바로 전송하지 않고 카드 지급 링크를 통해서 전송하는 기능입니다. 에스크로 전송 기능을 활용하기 위해서는 먼저 카드 지급 링크 생성 API를 호출해야합니다. 기본적으로 보유한 카드에 한하여 에스크로 생성을 요청할 수 있습니다. 에스크로 생성 후 해당 카드는 더 이상 카드 보유 목록에서 조회되지 않습니다.

```
curl -X POST "https://api.klipwallet.com/v2/escrow" \
-d @./escrow_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`escrow_info.json` 파일 예시는 아래와 같습니다.

```
{
    "pin": "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
    "contract_address": "0x6E3571F451fc960Ea69b532006A2c8683fF8922F"
    "card_ids": [15277, 15279],
}
```

이 파일에는 `pin`, `contract_address`는 카드를 발행한 스마트 컨트랙트 주소([SCA](https://docs.kaia.io/ko/learn/accounts/)), 에스크로 전송할 `card_id`의 배열인 `card_ids`가 들어갑니다.

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{
    "tx_hash":"0x5082643fc9799badeea30d243e3c5aba46dfd0eedf623f6698c8f30c36618c6c",
    "fail_count":0,
    "claim_links": ["https://klipwallet.com/?target=/claimCard/64/15277?claimKey=234b78b5d03a395f440b3b9acf784959a4f5f0a7f6c558ef6a2d22f8fee25a79", "https://klipwallet.com/?target=/claimCard/64/15279?claimKey=8fdaae3e92208aeb19753edff72abddacfd4d4f36fe871c77eb79f061537e415"]
}
```

에스크로 생성에 성공하면 트랜잭션 해시값과 카드 지급 링크 그리고 `fail_count` 0을 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}

#### 5-4. 에스크로 내역 조회 <a href="#get-escrow" id="get-escrow"></a>

에스크로 생성에 성공했다면 현재 에스크로 중인 카드 정보를 조회할 수 있습니다.

```
curl -X GET "https://api.klipwallet.com/v2/escrow?contract_address=0x6E3571F451fc960Ea69b532006A2c8683fF8922F&cursor=" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{
    "name":"파트너스 발행 카드",
    "symbol_img":"https://...",
    "cards":[{"created_at":1605921829,"updated_at":1606057801,"owner":"0x7998d102b2938532bc068300517d4db783f326c2","sender":"0xc95e3a887cb2108d4a19e2a9bcbe0827367372fe","card_id":15279,"card_uri":"https://klip-media.klaytn.com/card_asset/20295/7de0f5cc-6624-487f-adb9-4bfa86d38992.json","transaction_hash":"0x5082643fc9799badeea30d243e3c5aba46dfd0eedf623f6698c8f30c36618c6c"},{"created_at":1605921668,"updated_at":1606057801,"owner":"0x7998d102b2938532bc068300517d4db783f326c2","sender":"0xc95e3a887cb2108d4a19e2a9bcbe0827367372fe","card_id":15277,"card_uri":"https://klip-media.klaytn.com/card_asset/20295/e18133b8-aedc-4daf-aa2a-87654beabadf.json","transaction_hash":"0x5082643fc9799badeea30d243e3c5aba46dfd0eedf623f6698c8f30c36618c6c"}],
    "next_cursor":""
}
```

{% hint style="info" %}
`cards` 배열의 상세 정보는 [Escrow Information](/rest-api/rest-api-card-minting#escrow-information)의 Response Detail 항목을 참조하십시오.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}

#### 5-5. 에스크로 삭제 <a href="#cancel-escrow" id="cancel-escrow"></a>

현재 에스크로 중인 카드를 취소할 수 있습니다. 취소된 카드는 카드 보유 목록에서 다시 확인할 수 있습니다.

```
curl -X DELETE "https://api.klipwallet.com/v2/escrow" \
-d @./cancel_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`cancel_info.json` 파일 예시는 아래와 같습니다.

```
{
    "pin": "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
    "contract_address": "0x6E3571F451fc960Ea69b532006A2c8683fF8922F"
    "card_ids": [15277, 15279],
}
```

이 파일에는 `pin`, `contract_address`는 카드를 발행한 스마트 컨트랙트 주소([SCA](https://docs.kaia.io/ko/learn/accounts/)), 취소할 `card_id`의 배열인 `card_ids`가 들어갑니다.

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{
    "tx_hash":"0x831e207b0b951127646b8f7d7eded55903cecb29fe794e17a2d93f457b7158a4",
    "fail_count":0,
}
```

에스크로 생성에 성공하면 트랜잭션 해시값과 `fail_count` 0을 받습니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 전송에 실패했습니다.
```

{% endtab %}
{% endtabs %}

### 6. 트랜잭션 <a href="#transaction" id="transaction"></a>

#### 6-1. 처리 결과 조회 <a href="#get-receipt" id="get-receipt"></a>

트랜잭션 처리 결과가 블록에 최종 성공으로 기록됐는지 여부를 조회할 수 있습니다. 트랜잭션 요청 후 곧바로 결과를 조회하는 경우 `4700: no transaction receipt` 에러가 발생할 수 있습니다. 대략 2초 이상의 딜레이를 두고 에러가 뜨지 않을 때까지 수회 반복 호출하는 것을 권장합니다.

```
curl -X GET "https://api.klipwallet.com/v2/wallet/receipt?tx_hash=0x880a45d3c482c7d794c2e7b7dbdc9e933a68f4a1f3d978d582ba9f9ebd1f9e72" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{
  "success": true
}
```

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4700" %}

```
"no transaction receipt": 트랜잭션 해시가 존재하지 않습니다. 아직 트랜잭션이 처리되지 않았거나 잘못된 트랜잭션 해시 값입니다.
```

{% endtab %}
{% endtabs %}

### 7. 계정과 카드 관리하기 <a href="#account-management" id="account-management"></a>

#### 7-1. 계정 비밀번호와 핀 번호 변경하기 <a href="#change-password-and-pin" id="change-password-and-pin"></a>

[Change Password](/rest-api/rest-api-card-minting#change-password)로 Klip Partners에 `old_password`, `new_password`, 로그인 시 받은 `access_token`을 보내고 이전 비밀번호에서 새로운 비밀번호로 교체를 요청합니다.

* `old_password`, `new_password`는 기존 비밀번호/새롭게 사용할 비밀번호를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * 기존 비밀번호/새롭게 사용할 비밀번호는 8\~16자의 영문 대소문자, 숫자, 특수문자를 조합한 string 값입니다.

```
curl -X PUT "https://api.klipwallet.com/v2/partner/?opt=password" \
-d '{"old_password":"HASHED_OLD_PASSWORD", "new_password":"HASHED_NEW_PASSWORD"}' \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{}
```

에러가 발생하지 않았다면 이전 비밀번호가 새 비밀번호로 교체된 것입니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="4004" %}

```
"invalid password": 비밀번호가 일치하지 않습니다.
```

{% endtab %}

{% tab title="기타" %}

```
비밀번호 변경에 실패했습니다.
```

{% endtab %}
{% endtabs %}

[Change PIN](/rest-api/rest-api-card-minting#change-pin)으로 Klip Partners에 이전 핀 번호, 새로운 핀 번호, 로그인 시 받은 `access_token`을 보내고 새로운 핀 번호로 핀 번호 교체를 요청합니다.

* `old_pin`과 `new_pin`은 기존 핀 번호/새롭게 사용할 핀 번호를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `old_pin`과 `new_pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.
  * 기존 핀 번호/새롭게 사용할 핀 번호는 6자리 숫자입니다.

```
curl -X PUT "https://api.klipwallet.com/v2/partner/pin" \
-d '{"old_pin":"HASHED_OLD_PIN_NUMBER", "new_pin":"HASHED_NEW_PIN_NUMBER"}' \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{}
```

에러가 발생하지 않았다면 이전 핀 번호가 새 핀 번호로 교체된 것입니다.

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="403" %}

```
"exceed pin code error count": 핀 번호 입력 오류 횟수가 지정된 한도를 초과하였습니다.
```

{% endtab %}

{% tab title="4006" %}

```
"invalid pin code": 기존 핀 번호가 일치하지 않습니다.
```

{% endtab %}

{% tab title="기타" %}

```
핀 번호를 변경하지 못했습니다.
```

{% endtab %}
{% endtabs %}

#### 7-2. 이번 달 발행한 카드 개수 <a href="#mint-count" id="mint-count"></a>

이번 달에 파트너 계정으로 발행한 총 카드 개수를 조회할 수 있습니다. 이 값은 매월 1일에 0으로 초기화됩니다.

```
curl -X GET "https://api.klipwallet.com/v2/wallet/mint/count" \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```
{
  "mint_count": 10
}
```

`mint_count` 필드에 현재까지 발행한 카드 개수 값을 받습니다.

#### 7-3. 카드 삭제하기 <a href="#delete-card" id="delete-card"></a>

[Delete Card](/rest-api/rest-api-card-minting#delete-card)로 Klip Partners에 `delete_info.json` 파일, 로그인 시 받은 `access_token`을 보내고 발행한 카드 삭제를 요청합니다.

```
curl -X DELETE "https://api.klipwallet.com/v2/wallet/nft" \
-d @./delete_info.json \
-H "Authorization: ACCESS_TOKEN" -H "Content-Type: application/json"
```

`delete_info.json` 파일 예시는 아래와 같습니다.

```
//delete_info.json 파일 내용 예시
{
    pin: "91B4D142823F7D20C5F08DF69122DE43F35F057A988D9619F6D3138485C9A203",
    card_id: 12,
    contract_address: "0xbad6444e1f84af055c22281d4ac7d75bde2ddec8"
}
```

이 파일에는 삭제할 카드 ID, 카드를 발행한 [SCA](https://docs.kaia.io/ko/learn/accounts/) 주소, 핀 번호가 담겨 있습니다.

* `pin`은 핀 번호(Klip Partners 회원 가입 시 설정한 6자리 숫자)를 해시([SHA256](https://ko.wikipedia.org/wiki/SHA))한 64자리 Hex String 값입니다.
  * `pin`은 트랜잭션 서명에 개인 키 대신 사용됩니다.

요청이 정상 처리되면 아래 값을 받습니다.

```
{
    "hash": "0x2d26f602cfbb4c662931592bf2c4ee18d29f09683be5b9e8d589ff935fca0b97"
}
```

에러가 발생하지 않았다면 카드가 정상 삭제된 것입니다. 카드가 정상 삭제되었다면 카드 삭제 트랜잭션 해시값을 받습니다.

{% hint style="warning" %}
발행한 카드만 삭제할 수 있으며, 다른 사람에게 보낸 카드는 삭제할 수 없습니다.\
카드를 삭제해도 카드 이미지는 삭제되지 않습니다.
{% endhint %}

요청이 정상 처리되지 않으면 아래 값을 받습니다.

{% tabs %}
{% tab title="400" %}

```
"bad request": 잘못된 요청입니다. Request 파라미터를 다시 확인하십시오.
```

{% endtab %}

{% tab title="기타" %}

```
카드 삭제에 실패하였습니다. 삭제와 관련해 정확한 정보를 확인하려면 보유 카드를 조회하십시오.
```

{% endtab %}
{% endtabs %}

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# App2App API

이 튜토리얼은 App2App REST API를 손쉽게 사용할 수 있도록 작성된 개발자 가이드입니다. SDK도 기본적으로 REST API 기반이므로 아래 내용을 참고하실 수 있습니다.

{% hint style="info" %}
Kaia는 기존의 Klaytn과 Finschia 블록체인 네트워크가 통합되어 운영되는 블록체인의 새 이름입니다. 이에 따라 본 문서는 대부분 Klaytn을 Kaia로 / KLAY를 KAIA로 지칭하지만, 하위 호환성을 위해 기존 호출과 응답에서 사용되던 klaytn, KLAY 등의 키워드는 동일하게 유지되는 점 참고 부탁드립니다.
{% endhint %}

## App2App REST API Tutorial

### 환경 설정

App2App API는 별도의 가입 절차가 필요없고 기본적으로 HTTP 통신이 가능한 어느 환경에서도 동작 가능합니다. 다만, 클립 앱을 실행하여 사용자의 승인을 받아야하기 때문에 기본적으로 클립 앱이 설치된 환경에서 호출 해야합니다.

{% hint style="info" %}
현재 샌드박스 환경은 따로 제공되지 않으며 실제 카카오 계정으로만 구현 및 테스트가 가능합니다.
{% endhint %}

아래 예제는 REST API는 `curl` 명령을 수행하고, Deep Link는 각 모바일 환경의 SDK에서 제공하는 API를 호출하거나, 모바일웹 환경의 경우 `Web2App` 라이브러리를 이용하여 수행할 수 있습니다. `Web2App` 라이브러리는 아래 GitHub 저장소를 통해서 얻을 수 있습니다. 자세한 사용 방법은 해당 사이트를 참조하십시오.

* [curl download](https://curl.haxx.se/download.html)
* [Web2App GitHub repository](https://github.com/kakao/web2app)

### Step 1 : Prepare

App2App 처리 시 가정 먼저 수행해야할 Prepare 과정은 Klip에서 처리할 요청 데이터를 전달하고 Request Key를 발급받는 과정입니다. Reqeust Key는 Deep Link 호출 및 결과 확인 과정에서 필요합니다.

요청의 종류는 `auth`와 `transaction`이 있으며, `transaction`은 다시 코인/토큰 전송 트랜잭션, 카드 전송 트랜잭션, 그리고 컨트랙트 실행 트랜잭션으로 나뉩니다. 필요에 따라서 적절한 필드를 아래와 같이 설정하여 API를 호출합니다.

{% hint style="info" %}
트랜잭션 요청에서 공통으로 사용하는 `from` 필드에는 트랜잭션에 서명하는 Klip 사용자의 계정 주소를 설정합니다. 이 필드는 Optional이지만 BApp에서 의도한 사용자와 실제 Klip 사용자가 서로 일치하는지 검사하기 위한 필드이므로 설정하는 것을 권장합니다.
{% endhint %}

트랜잭션 수수료를 BApp에서 대신 지불하고자 할 경우 수수료 대납 가능한 KAS (Klaytn API Service) 서비스를 구독하여야 하며, 요청 데이터의 BApp 필드 내부에 인증 정보를 함께 전달해야 합니다.

```json
{"bapp": {"name" :  "My BApp", "kas_authorization_key": "Basic abcdefghijklmnopqrstuvwxyz0123456789="}}
```

KAS 대납 서비스 구독 및 authorization key 발급 방법은 [문서](https://support.klaytnapi.com/hc/ko/articles/6180493705743)를 참고하시기 바라며, 문의사항은 [KAS 헬프센터](https://support.klaytnapi.com/hc/ko)를 이용하여 주시기 바랍니다.

#### Case 1) Auth 요청

Auth 요청은 Klip 사용자의 EOA를 얻야할 때 사용합니다. 요청 예제는 아래와 같습니다.

```bash
curl -X POST "https://a2a-api.klipwallet.com/v2/a2a/prepare" \
-d '{"bapp": { "name" : "My BApp" }, "callback": { "success": "mybapp:\/\/klipwallet\/success", "fail": "mybapp:\/\/klipwallet\/fail" }, "type": "auth" }' \
-H "Content-Type: application/json"
```

{% hint style="info" %}
API 요청 헤더에 `Authorization`, `Cookie` 등의 필드를 넣으면 CORS 설정 때문에 에러가 발생할 수 있습니다. 문서에 설명된 필드 이외에 추가로 넣지 않도록 유의해야합니다.
{% endhint %}

요청이 정상 처리되면 아래 값을 받습니다.

```json
{
  "request_key": "0b0ee0ad-62b3-4146-980b-531b3201265d", // random string
  "status": "prepared", // 정상적으로 처리된 경우. 만약 문제가 있다면 "error" 상태가 넘어옴.
  "expiration_time": 1600011054, //unix timestamp
  "estimated_gas": 210000 // 트랜잭션을 발생시키는 요청이면서 from 값이 존재할 경우 실제 트랜잭션 생성에 사용될 gasLimit 값을 반환. 이외의 경우 생략.
}
```

`callback` 객체의 `success` 필드에는 Request 처리 성공 시 다시 BApp으로 되돌아올 Deep Link를 설정합니다. `fail`의 경우는 처리에 실패했을 때 되돌아올 Deep Link를 설정합니다. 예를 들면, 사용자가 승인했으나 이미 완료된 경우, 만료된 request key를 사용한 경우, 잔고 부족 등에 해당합니다. Android 플랫폼의 경우, Intent Scheme 형식(`intent://...`)의 Deep Link로 작성이 필요합니다.

BApp에서 Deep Link를 지원하지 않는 경우 세팅하지 않아도 됩니다. 이때는 Klip에서 BApp으로 다시 명시적으로 되돌아가야 처리가 완료됨을 안내합니다.

{% hint style="info" %}
취소 혹은 X 버튼의 경우 callback이 동작하지 않습니다. 사용자가 명시적으로 앱 동작을 취소하거나 클립 앱 종료를 선택했기 때문입니다. 이에 따라 자동 화면 전환이 되지 않습니다.
{% endhint %}

#### Case 2) Send Token 요청

Send Token 요청은 Klip 사용자의 토큰을 지정된 주소로 보낼 때 사용합니다. 요청 예제는 아래와 같습니다.

```bash
curl -X POST "https://a2a-api.klipwallet.com/v2/a2a/prepare" \
-d '{"bapp": { "name" : "My BApp" }, "chain": "klaytn", "type": "send_token", "transaction": { "contract": "0xdc8c8d2CD5829dE8e8a31Fc595D69c4B403e9dD8", "from": "0xcD1722f2947Def4CF144679da39c4C32bDc35681", "to": "0x85c17299e9462e035c149847776e4edb7f4b2aa9", "amount": "100" } }' \
-H "Content-Type: application/json"
```

{% hint style="info" %}
Klaytn 체인은 현재 Kaia 체인으로 운영되고 있지만 하위 호한성을 위해 kaia 대신에 `klaytn` 이름을 사용합니다.
{% endhint %}

`transaction` 객체의 `contract` 필드에는 토큰의 컨트랙트 주소(SCA)를 설정해야 합니다(네이티브 코인의 경우 `0x0000000000000000000000000000000000000000` 입력). `amount` 필드에는 보낼 토큰의 양을 설정합니다. 소수점 6자리까지만 지원합니다.

요청이 정상 처리되면 Auth 요청 예시와 동일한 형태의 값을 받습니다.

#### Case 3) Send Card 요청

Send Card 요청은 Klip 사용자의 카드를 지정된 주소로 보낼 때 사용합니다. 요청 예제는 아래와 같습니다.

```bash
curl -X POST "https://a2a-api.klipwallet.com/v2/a2a/prepare" \
-d '{"bapp": { "name" : "My BApp" }, "type": "send_card", "transaction": { "contract": "0xB21F0285d27beb2373ECB5c17E119ccEAd7Ee10A", "from": "0xcD1722f2947Def4CF144679da39c4C32bDc35681", "to": "0x85c17299e9462e035c149847776e4edb7f4b2aa9", "card_id": "1234" } }' \
-H "Content-Type: application/json"
```

`transaction` 객체의 `contract` 필드에는 Klip에서 제공하는 카드의 컨트랙트 주소(SCA)를 설정해야 합니다. `card_id` 필드에는 보낼 토큰의 고유번호를 설정합니다.

요청이 정상 처리되면 Auth 요청 예시와 동일한 형태의 값을 받습니다.

#### Case 4) Execute Contract 요청

Execute Contract 요청은 Klip 사용자의 서명으로 스마트 컨트랙트 함수를 수행할 때 사용합니다. 요청 예제는 아래와 같습니다.

```bash
curl -X POST "https://a2a-api.klipwallet.com/v2/a2a/prepare" \
-d '{"bapp": { "name" : "My BApp" }, "chain": "klaytn", "type": "execute_contract", "transaction": { "to": "0xd4fFbe967c31C29199478Be2b5A53dC69eF9B825", "value": "0", "abi": "{ \"constant\": false, \"inputs\": [ { \"name\": \"a\", \"type\": \"string\" } ], \"name\": \"testString\", \"outputs\": [], \"payable\": false, \"stateMutability\": \"nonpayable\", \"type\": \"function\" }", "params": "[\"test_string\"]" } }' \
-H "Content-Type: application/json"
```

tuple 타입의 경우는 다음의 예제처럼 사용합니다.

```bash
curl -X POST 'https://a2a-api.klipwallet.com/v2/a2a/prepare' \
-d '{
    "bapp": {
        "name": "name",
        "callback": {}
    },
    "chain": "klaytn",
    "type": "execute_contract",
    "transaction": {
        "to": "0xF857Dcd31A2a69764bfEbb30dc51EA24519b8aEc",
        "value": "0",
        "abi": "{\"inputs\": [{\"components\": [{\"internalType\": \"string\",\"name\": \"text\",\"type\": \"string\"},{\"internalType\": \"bool\",\"name\": \"completed\",\"type\": \"bool\"}],\"internalType\": \"struct Test.Todo\",\"name\": \"a\",\"type\": \"tuple\"}],\"name\": \"testStruct\",\"outputs\": [],\"stateMutability\": \"nonpayable\",\"type\": \"function\"}",
        "params": "[[\"2001\",false]]"
    }
}' \
-H 'Content-Type: application/json' 
```

{% hint style="info" %} Klaytn 체인은 현재 Kaia 체인으로 운영되고 있지만 하위 호한성을 위해 kaia 대신에 `klaytn` 이름을 사용합니다. {% endhint %}

\`

transaction`객체의`to`필드에는 실행할 컨트랙트의 주소(SCA)를 설정합니다.`value`필드에는 전송할 KAIA(KLAY)를 kei(peb) 단위로 설정합니다. payable 함수인 경우에만 설정할 수 있습니다.`abi`에는 실행할 함수의 ABI를 입력합니다.` params`에는 해당 함수를 실행한 인자를 배열 형태의 문자열을 설정합니다.` abi`및`params\` 필드는 String 타입임을 유의하여 전송합니다.

요청이 정상 처리되면 Auth 요청 예시와 동일한 형태의 값을 받습니다.

#### Case 5) Sign Message 요청

Sign Message 요청은 Klip 사용자의 계정으로 메시지를 서명할 때 사용합니다. 요청 예제는 아래와 같습니다.

```bash
curl -X POST "https://a2a-api.klipwallet.com/v2/a2a/prepare" \
-d '{"bapp": { "name" : "My BApp" }, "chain": "klaytn", "type": "sign_message", "message": { "value": "original message", "from": "0x220AD25E31BBF7c19D95Be0e47d4cdc0Ad8f8FEa" } }' \
-H "Content-Type: application/json"
```

원문이 hex encoding 된 데이터를 사용할 경우 다음처럼 사용 할 수 있습니다.

```bash
curl -X POST "https://a2a-api.klipwallet.com/v2/a2a/prepare" \
-d '{"bapp": { "name" : "My BApp" }, "chain": "klaytn", "type": "sign_message", "message": { "is_hex_encoded": true, "value": "0x1290fe99a322", "from": "0x220AD25E31BBF7c19D95Be0e47d4cdc0Ad8f8FEa" } }' \
-H "Content-Type: application/json"
```

{% hint style="info" %}
Klaytn 체인은 현재 Kaia 체인으로 운영되고 있지만 하위 호한성을 위해 kaia 대신에 `klaytn` 이름을 사용합니다.
{% endhint %}

`message` 오브젝트의 `value` 필드에 서명할 원문을 포함합니다. `from` 필드는 서명하는 계정 주소입니다. 선택 항목이라 생략할 수 있으나, 만약 입력한다면 해당 값으로 서명 계정의 주소가 올바른지 검증합니다.

요청이 정상 처리되면 Auth 요청 예시와 동일한 형태의 값을 받습니다.

{% hint style="warning" %}
원문에 아스키코드 이외의 문자가 포함된 경우에는, caver-js의 caver.utils.hashMessage 메소드를 통해서 해싱한 결과물을 Klip에서 응답한 signature 값으로 recover하면 결과가 실제 서명한 계정과 다른 주소로 응답될 수 있는 부분 참고하시기 바랍니다.

원문이 ‘0x’로 시작 할 경우 caver-js의 caver.utils.hashMessage 메소드를 통해서 해싱한 결과물은 자동으로 hex encoding 된 데이터로 판단하여 생성합니다. 동일 데이터에 대해 Klip에서 “is\_hex\_encoded": true 사용하여 signature 를 만들지 않으면 recover 한 결과가 실제 서명한 계정과 다른 주소로 응답될 수 있는 부분 참고하시기 바랍니다.
{% endhint %}

### Step 2 : Request

Request는 BApp에서 클립 앱에 App2App 처리를 요청하기 위한 Deep Link를 실행하는 과정입니다. Deep Link를 통해 클립 앱이 실행된 경우, 사용자에게 확인 창이 뜨게됩니다. 인증의 경우는 BApp에 EOA를 제공에 동의를 구하는 창이 뜨게되며, 트랜잭션 처리의 경우 요청한 트랜잭션 데이터를 화면에 보여주고, pin code 입력받아서 실제 트랜잭션을 처리하게됩니다.

만약 Prepare 과정에서 callback Deep Link를 설정한 경우, BApp으로 자동으로 넘어갑니다. 설정하기 않은 경우 사용자에게 BApp으로 되돌아가기 위한 안내 메시지를 제공합니다.

Klip에서 제공하는 URL은 아래와 같습니다. 공통적으로 `request_key`를 쿼리 스트링으로 받습니다. Prepare 과정에서 얻은 값을 설정합니다.

```
https://klipwallet.com?target=/a2a?request_key=0b0ee0ad-62b3-4146-980b-531b3201265d
```

{% hint style="info" %}
위 Deep Link를 통해 클립 앱을 실행하거나 설치할 수 있도록 유도됩니다.
{% endhint %}

### Step 3 : Result

App2App API 요청의 최종 상태는 아래와 같이 Result API를 polling하여 얻을 수 있습니다. Prepare 과정에서 얻은 `request_key`값을 쿼리 스트링으로 설정합니다.

```bash
curl -X GET "https://a2a-api.klipwallet.com/v2/a2a/result?request_key=0b0ee0ad-62b3-4146-980b-531b3201265d" \
-H "Content-Type: application/json"
```

요청이 정상 처리되면 요청 `type`별로 아래 값을 받습니다.

#### Case 1) Auth 요청

```json
{
    "request_key": "0b0ee0ad-62b3-4146-980b-531b3201265d",
    "expiration_time": 1752488581,
    "status": "completed",
    "result": {
        "klaytn_address": "0x7529d7814a19d9a9F9d8405D4eF9BDA56B02f457", //호환성을 위해 필드명에 klaytn 유지
        "evm_address": "0x7529d7814a19d9a9F9d8405D4eF9BDA56B02f457",
        "bitcoin_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
        "solana_address": "M1TRvDk3XZMnafQZhcD2NrBkAcXbDRjmyJDxb5YJUcF",
        "tron_address": "TPF9k4bHPSpZinYMuWcGCeMuCLtAH8Ku43",
        "xrpl_address": "rmBdbQFdwTHAC1a98X6SA5BaXzfUcPwe7"
    }
}
```

#### Case 2) Sign Message 요청

```json
{
  "request_key":  "0b0ee0ad-62b3-4146-980b-531b3201265d",
  "expiration_time": 1600011054,
  "status": "completed",
  "result": {
    "signature": "0x1dc98165c3fc523bcdbdf18eadba12b004cd30b232e5e65fdd6424412cbf0dab2d131dda838cd249a7d00414ae53abe5ba6fa7bf8446f28c328bc60443c1545d07f5",
    "hash": "0x0b9ac081057767a46500710d1007d4f0de7f23b109b50ffdc60d03b175a9eb6f"
  }
}
```

`result` 객체의 `signature` 필드로 부터 원문에 대한 서명값을 받을 수 있습니다. recover는 `caver.utils.recover` 메소드 또는 아래 예제 코드를 통해서 수행할 수 있습니다.

```javascript
const Bytes = require('eth-lib/lib/Bytes');
const elliptic = require("elliptic");
const secp256k1 = new elliptic.ec("secp256k1");
const { keccak256, keccak256s } = require("eth-lib/lib/hash");
const utils = require("caver-js/packages/caver-utils");

function recover(message) {
  const hex = message.signature
  const hash = message.message
  const vals = [Bytes.slice(64, Bytes.length(hex), hex), Bytes.slice(0, 32, hex), Bytes.slice(32, 64, hex)];

  const vrs = { v: Bytes.toNumber(vals[0]), r: vals[1].slice(2), s: vals[2].slice(2) };

  const ecPublicKey = secp256k1.recoverPubKey(new Buffer(hash.slice(2), "hex"), vrs, vrs.v < 2 ? vrs.v : 1 - vrs.v % 2); // because odd vals mean v=0... sadly that means v=0 means v=1... I hate that
  const publicKey = "0x" + ecPublicKey.encode("hex", false).slice(2);
  const publicHash = keccak256(publicKey);

  const recoveredAddress = "0x" + publicHash.slice(-40);

  if (recoveredAddress.toLowerCase() === message.address.toLowerCase()) {
    console.log("ok", recoveredAddress, message.address)
    return true
  } else {
    console.log("not match", recoveredAddress, message.address)
  }
  return false
}

const EthereumPrefix = "Ethereum Signed Message"
const PolygonPrefix = "Ethereum Signed Message"
const KlaytnPrefix = "Klaytn Signed Message"

function hashMessage(chainPrefix, data) {
  const message = utils.isHexStrict(data) ? utils.hexToBytes(data) : data
  const messageBuffer = Buffer.from(message)
  const preamble = `\x19` + chainPrefix + `:\n${message.length}`
  const preambleBuffer = Buffer.from(preamble)
  const saltedMessage = Buffer.concat([preambleBuffer, messageBuffer])
  return keccak256(saltedMessage)
}

const message = {
  message: hashMessage(PolygonPrefix, 'original message'),
  address: "0xa99694791182d3f6d0e0ccf5a2b0703845a50a50",
  signature: "0x25b46420d40415d1a3cab6d1b2849e93e100fb310eebc9db8580a6eb465fc3535dd7f61c6a95efe281acfe0a9de6f089eec57ea78c578738e1dc16ded1c7999d1c"
}

recover(message)
```

{% hint style="info" %}
위의 예시는 type을 `sign_message`로 설정한 경우로, `sign_message_eip191`을 사용하는 경우에는 Kaia의 표준에 따라 `"\x19Ethereum Signed Message:\n" + len(message)`의 접두사를 붙여 메시지에 서명합니다. Kaia에서 변경된 메시지 서명 표준의 변화에 대해서는 [여기](https://github.com/kaiachain/kaia/pull/33)를 참고하시기 바랍니다.
{% endhint %}

{% hint style="warning" %}
원문에 아스키코드 이외의 문자가 포함된 경우에는, caver-js의 caver.utils.hashMessage 메소드를 통해서 해싱한 결과물을 Klip에서 응답한 signature 값으로 recover하면 결과가 실제 서명한 계정과 다른 주소로 응답될 수 있는 부분 참고하시기 바랍니다.

원문이 ‘0x’로 시작 할 경우 caver-js의 caver.utils.hashMessage 메소드를 통해서 해싱한 결과물은 자동으로 hex encoding 된 데이터로 판단하여 생성합니다. 동일 데이터에 대해 Klip에서“is\_hex\_encoded": true 사용하여 signature 를 만들지 않으면 recover 한 결과가 실제 서명한 계정과 다른 주소로 응답될 수 있는 부분 참고하시기 바랍니다.
{% endhint %}

#### Case 3) Auth, Sign Message 이외의 요청

```json
{
  "request_key": "0b0ee0ad-62b3-4146-980b-531b3201265d",
  "expiration_time": 1600011054,
  "status": "completed",
  "result": {
    "tx_hash": "0x82d018556e88b8f8f43dc2c725a683afc204bfd3c17230c41252354980f77fb3",
    "status": "success"
  }
}
```

`Auth`가 아닌 다른 요청 타입일 경우 `result` 객체가 추가로 넘어옵니다. `result` 객체의 `tx_hash` 필드를 복사해 [kaiaScan](https://kaiascan.io/), [Etherscan](https://etherscan.io/), [Polygon](https://polygonscan.com/) 등에서 사용하면 트랜잭션의 처리 상태에 관한 자세한 정보를 확인할 수 있습니다. `result` 객체의 `status` 필드는 `pending` 상태의 경우, 사용자가 Klip에서 확인했자만, 체인에서 아직 트랜잭션을 처리하는 중임을 의미합니다. 일반적으로 몇 초 후에 다시 확인하면 요청을 확인할 수 있습니다. `success`는 요청이 성공적으로 처리될 때, `fail`은 요청 처리에 실패할 때의 상태입니다.

### Get Additional Information

일반적으로 BApp에서 카드를 전송하기 위해서는 사용자가 보유하고 있는 카드 목록을 조회하여 고유번호를 얻어야하는 경우가 많습니다. Auth 과정을 통해서 얻은 EOA와 조회하려는 컨트랙트의 주소를 인자로 삼아서 해당 EOA가 컨트랙트에 소유하고 있는 카드 목록을 조회할 수 있습니다.

요청 예제는 아래와 같습니다.

```bash
curl -X GET "https://a2a-api.klipwallet.com/v2/a2a/cards?chain=klaytn&sca=0xB21F0285d27beb2373ECB5c17E119ccEAd7Ee10A&eoa=0x85c17299e9462e035c149847776e4edb7f4b2aa9&cursor=" -H "Content-Type: application/json"
```

요청이 정상 처리되면 아래 값을 받습니다.

```json
{
    "name": "conan",
    "symbol_img": "https://media.klipwallet.com/token_icon/klay_klip.svg",
    "cards": [
    {
      "created_at": 1580176787,
      "created_at_format": "format",
      "updated_at": 1580176787,
      "updated_at_format": "format",
      "owner": "0x85c17299e9462e035c149847776e4edb7f4b2aa9",
      "sender": "0x2412b300750f505fb2e68ddf0cd45e9d95f5378d",
      "sender_kakao_id": "1234"
      "card_id": 19,
      "card_uri": "https://media.klipwallet.com/card-asset/1234/19.json",
      "transaction_hash": "0x293a2e53ecf238109908e65a2b7ff4aad0919ce3ce54af08d6fc4323f28e935d"
    },
    ],
    "next_cursor": "mrzedXOE9OeEorkAvwQXB7JdVg4LP1Rzze2kLQFxLU4C8iMOhOVulzIr5iesZoie9uv9h87UNXsWCKdhqYszXFWLsYYI7h125Rx8p56qlMKaZ20YbNW3zDGmNBJKM1wL"
}
```

카드 정보가 정상 조회되었다면 계정이 이 BApp에서 소유한 카드 목록과 정보를 받습니다.

* `cards`에서 **card**는 이 BApp에서 쓰이는 카드입니다. BApp에는 카드 1종류가 들어있습니다.
* Query 파라미터로 `cursor` 또는 `isAll` 둘 중 하나만 사용해야 합니다(`isAll`이 `false`이면 `cursor`를 사용할 수 있습니다).
* `cursor`를 사용하면 Pagination을 사용합니다.
  * 1회 요청에 최대 카드 100개의 정보를 받습니다.
  * 정보를 불러울 카드가 100개를 초과 시 다음 카드 정보를 불러올 수 있는 커서값인 `next_cursor`로 나머지 카드 정보를 받습니다.
  * 나머지 카드 정보를 받으려면 `cursor`에 이전 호출에서 받은 `next_cursor`를 넣고 API를 다시 호출합니다.

위 예시에서 `cards.next_cursor`값이 존재하므로 이 계정은 **conan** 카드를 100개 이상 가지고 있습니다.\
한 번에 조회할 카드 개수가 100개를 초과한다면 1회 호출 시 카드 100개 정보만 받고 `cards.next_cursor`값을 받습니다.\
나머지 카드 정보를 조회하려면 `cards.next_cursor`값을 Query 파라미터 `cursor`에 전달하고 API를 다시 호출해야 합니다.

예를 들어, 정보를 불러올 카드 개수가 150개라면, 먼저 API를 호출하여 카드 100개의 정보와 `cards.next_cursor`값을 받습니다.\
그리고 동일한 API를 다시 호출할 때 `cards.next_cursor`값을 Query 파라미터 `cursor`로 사용하면 나머지 50개의 정보를 받습니다.

요청이 정상적으로 처리되지 않은 경우 HTTP 400 또는 500이 리턴되며 자세한 내용은 [Basics](/basics#basics-app2app)를 참조하십시오.

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Klip Guide

이 페이지는 Klip의 각종 가이드를 소개합니다.

본 문서는 Klip을 활용함에 있어 참고할 수 있는 각종 디자인/개발 가이드를 안내하고 있습니다.

| 항목                                                 | 설명                             | 비고      |
| -------------------------------------------------- | ------------------------------ | ------- |
| [Design Guidelines](/klip-guide/design-guidelines) | 클립 및 클립 드롭스에 게시를 위한 각종 디자인 가이드 | 디자인 가이드 |
| [NFT Metadata Standards](/klip-guide/metadata-std) | Klip에서 사용하는 NFT 메타데이터 속성 표준    | 개발 가이드  |

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Design Guidelines

이 페이지에서는 클립과 클립 드롭스 디자인 에셋 제작 시 필요한 디자인 가이드 문서 및 템플릿의 다운로드 링크를 제공합니다.

## 브랜드 디자인 가이드 <a href="#brand-design-guide" id="brand-design-guide"></a>

그라운드엑스 제품의 브랜드 정체성을 유지하기 위한 사용 가이드입니다.

### 1. 그라운드엑스 <a href="#brandguide-gx" id="brandguide-gx"></a>

* [그라운드엑스 브랜드 가이드 문서 & 로고/심볼 파일 다운로드 (.zip)](https://media.klipwallet.com/guide/GroundX_Logo_Asset.zip)

### 2. 클립 <a href="#brandguide-klip" id="brandguide-klip"></a>

* [클립 브랜드 가이드 문서 & 로고/심볼 파일 다운로드 (.zip)](https://media.klipwallet.com/guide/Klip_Logo_Asset.zip)

### 3. 클립 드롭스 <a href="#brandguide-klipdrops" id="brandguide-klipdrops"></a>

* [클립 드롭스 로고 파일 다운로드 (.ai)](https://media.klipwallet.com/guide/KlipDrops_Logo_Vector.ai)

### 4. 그리드 <a href="#brandguide-grid" id="brandguide-grid"></a>

* [그리드 로고 및 가이드 다운로드 (.ai)](https://media.klipwallet.com/guide/GRID_Logo_Guide.ai)

## 클립 <a href="#klipguide" id="klipguide"></a>

### 1. 배너 디자인 가이드 <a href="#klipguide-banner" id="klipguide-banner"></a>

클립에 표시되는 배너 제작 가이드입니다.

* 1-1. (카카오톡 내 클립) 홈 하단 리스트형 배너 가이드
  * 카카오톡 내 클립 홈 화면 하단에 노출되는 배너 제작 가이드입니다.
  * [제작 가이드 문서 & 템플릿 파일 다운로드 (.zip)](https://media.klipwallet.com/guide/klip_main_bottom_list_guide_KOR.zip)

![카카오톡 클립 - 홈 하단 리스트형 배너 예시](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-0eaaac521d23fe44f14abc697acafe2eeb08df4f%2Fbottom_list_banner.jpg?alt=media)

* 1-2. 홈 하단 랜덤형 배너 가이드
  * 클립 홈 화면 최하단에 노출되는 배너 제작 가이드입니다.
  * [제작 가이드 문서 & 템플릿 파일 다운로드 (.zip)](https://media.klipwallet.com/guide/klip_main_bottom_random_guide_KOR.zip)

![홈 하단 랜덤형 배너 예시](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-cdb9fa50c36af7c478c88c35da491e849679d5ab%2Fbottom_random_banner.jpg?alt=media)

* 1-3. 홈 프로모션 팝업 배너 가이드
  * 클립 홈 화면 접근 시 팝업 형태로 노출되는 배너 제작 가이드입니다.
  * [제작 가이드 문서 & 템플릿 파일 다운로드 (.zip)](https://media.klipwallet.com/guide/klip_main_popup_template.zip)

![홈 프로모션 팝업 배너 예시](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-613bb02db4ce1bffa7df572f2597eb526de92406%2Fpopup_banner.jpg?alt=media)

* 1-4. 홈 상단 클립 드롭스 작품 배너 가이드
  * 클립 홈 화면에 노출되는 클립 드롭스 배너 제작 가이드입니다.
  * [홈 배너 템플릿 파일 Type2 다운로드 (.psd)](https://media.klipwallet.com/guide/main_drops_rolling_guide_type2.psd)

![홈 상단 클립 드롭스 작품 배너 예시](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-0ab588dd9fe0a516495d712314796f74b502d92f%2Fdrops_banner.jpg?alt=media)

### 2. 이미지 제작 가이드 <a href="#klipguide-image" id="klipguide-image"></a>

클립에 서비스, 토큰, NFT 등록 시 필요한 이미지 제작 가이드입니다.

* 2-1. 서비스 정보 & 이미지 에셋 가이드
  * 클립 서비스 등록 시 필요한 앱 아이콘 및 스크린샷 가이드입니다.
  * [제작 가이드 문서 & 템플릿 파일 다운로드 (.zip)](https://media.klipwallet.com/guide/klip_service_info_asset_guide.zip)
* 2-2. 토큰 & NFT 가이드
  * 클립에 노출되는 토큰 및 NFT 등록 시 필요한 정보를 참고할 수 있는 가이드입니다.
  * [토큰 제작 가이드 문서 다운로드 (.pdf)](https://media.klipwallet.com/guide/Klip_Token_Guide.pdf)
  * [NFT 제작 가이드 문서 다운로드 (.pdf)](https://media.klipwallet.com/guide/Klip_NFT_Guide.pdf)
* 2-3. NFT 컬렉션 등록 가이드
  * 클립에 노출되는 NFT 컬렉션 등록 시 필요한 정보를 참고할 수 있는 가이드입니다.
  * [제작 가이드 문서 다운로드 (.pdf)](https://media.klipwallet.com/guide/How_to_expose_NFT_collections_on_Klip.pdf)

### 3. 클립 로그인 버튼 가이드 <a href="#klipguide-loginbutton" id="klipguide-loginbutton"></a>

app2app을 통해 클립을 연동하는 경우 참고할 수 있는 디자인 가이드입니다.

* 클립 로그인 버튼 가이드
  * 클립 로그인 기능을 구현할 때 필요한 버튼 가이드입니다.
  * [제작 가이드 문서 링크 (Figma)](https://www.figma.com/file/FZuqElOlwYGbQOsjDx8g1c/Klip_A2A-%EB%B2%84%ED%8A%BC-%EC%A0%9C%EC%9E%91-%EA%B0%80%EC%9D%B4%EB%93%9C-v.2.0.0?type=design\&node-id=0-1)
  * [제작 가이드 문서 & 템플릿 파일 다운로드 (.zip)](https://media.klipwallet.com/guide/klip_login_button_guide_KOR.zip)

## 클립 드롭스 <a href="#klipdropsguide" id="klipdropsguide"></a>

### 1. 작품 제작 가이드 <a href="#klipdropsguide-creation" id="klipdropsguide-creation"></a>

클립 드롭스 작품 및 크리에이터 이미지의 기술사양과 작품 정보를 참고할 수 있는 가이드입니다.

* [제작 가이드 문서 다운로드 (.pdf)](https://media.klipwallet.com/guide/drops_creation_guide.pdf)

### 2. 배너 및 콘텐츠 디자인 가이드 <a href="#klipdropsguide-banner" id="klipdropsguide-banner"></a>

클립 드롭스 내 홍보를 위한 배너 및 콘텐츠 제작 가이드입니다.

* 2-1. 통합 홈 배너 가이드
  * Klip Drops 홈페이지 상단에 노출되는 배너 제작 템플릿 파일입니다.
  * [템플릿 파일 다운로드 (.psd)](https://media.klipwallet.com/guide/drops_main_promotion_name.psd)

![클립 드롭스 통합 홈 배너 예시](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-5a2f1656fad11f90100e58254791b5bebeb5a884%2Fdrops_home_banner.jpg?alt=media)

* 2-2. 작가 소개 콘텐츠 가이드
  * Klip Drops 홈페이지 상단 배너 클릭 시 새 탭으로 노출되는 작가 소개 콘텐츠 제작 가이드입니다.
  * [제작 가이드 문서 다운로드 (.jpg)](https://media.klipwallet.com/guide/drops_creator_intro_contents_guide.jpg)

### 3. 드롭스 파트너스 툴 가이드 <a href="#klipdropsguide-dpt" id="klipdropsguide-dpt"></a>

드롭스 파트너스 툴 (DPT) 이용 방법과 신규 파트너의 필수 설정을 위한 가이드입니다.

* [DPT 빠른 가이드 다운로드 (.pdf)](https://media.klipwallet.com/guide/dpt_quick_guide.pdf)
* [DPT 이용 가이드 다운로드 (.pdf)](https://media.klipwallet.com/guide/dpt_guide.pdf)

이 문서 혹은 클립에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# NFT Metadata Standards

이 페이지에서는 Klip에서 사용하는 NFT 메타데이터 속성의 표준을 설명합니다. 이 표준에 정의되지 않은 속성과 형식의 경우 Klip 내에서 정상적으로 노출되지 않을 수 있으니 참고 바랍니다.

## 메타데이터 속성 <a href="#metadata-properties" id="metadata-properties"></a>

Klip에서 지원하는 속성값의 이름과 설명은 다음과 같습니다. OpenSea에서 사용하는 속성값과 일부 명칭 차이가 있으니 유의 바랍니다.

| 이름                | 타입      | 설명                                                                                                                                                                                       |
| ----------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name\*            | string  | NFT 이름입니다.                                                                                                                                                                               |
| description\*     | string  | NFT에 관한 설명입니다.                                                                                                                                                                           |
| image\*           | string  | NFT에 사용할 이미지 URL 주소입니다. 이미지 파일 형식이 아니거나 경로에 확장자가 포함되지 않는 경우 정상적으로 표시되지 않을 수 있습니다.                                                                                                        |
| animation\_url    | string  | NFT에 사용할 동영상 URL 주소입니다. 지원하는 파일 확장자는 .mp4입니다. H.264 코덱이 아니거나 해상도가 3840x2160을 넘는 경우 재생되지 않을 수 있습니다.                                                                                       |
| background\_color | string  | NFT 이미지 배경에 사용할 RGB 색상 코드입니다. # 다음에 16진수 6자리 문자열로 표시합니다.                                                                                                                                 |
| sendable          | boolean | TRUE이면 해당 NFT를 Klip에서 다른 사람에게 전송할 수 있습니다. 지정되지 않은 경우 기본값은 TRUE입니다.                                                                                                                       |
| group\_name       | string  | NFT를 그룹핑할 때 사용하는 그룹 이름입니다.                                                                                                                                                               |
| group\_icon       | string  | NFT를 그룹핑할 때 그룹 아이콘으로 사용할 이미지 URL 주소입니다.                                                                                                                                                  |
| hashtags          | array   | 해시태그들이 담긴 `string` 배열입니다. 해시태그를 달면 Klip 내에서 NFT를 검색하는데 활용됩니다.                                                                                                                            |
| layout            | string  | NFT 이미지를 보여주는 방식입니다. 정사각형 이미지는 `general`, 가로가 더 긴 이미지는 `horizontal`, 세로가 긴 이미지는 `vertical`로 설정할 수 있습니다. 지정되지 않은 경우 기본값은 `general`입니다.                                                    |
| external\_link    | string  | Klip 외부로 연결되는 URL 주소입니다. 지정하면 NFT 상세 화면에서 외부로 연결되는 링크가 제공됩니다. (최대 길이: 255)                                                                                                               |
| external\_url     | string  | Klip 외부로 연결되는 URL 주소입니다. 지정하면 NFT 상세 화면에서 외부로 연결되는 링크가 제공됩니다. (최대 길이: 255)                                                                                                               |
| custom\_links     | array   | Klip 외부로 연결되는 URL 주소들이 담긴 `object` 배열 입니다. `display_name`에 노출할 버튼 레이블, `value`에 연결할 URL 주소를 쌍을 이뤄 지정합니다. Klip의 NFT 상세 화면에서 외부로 연결되는 링크가 버튼 형태로 제공됩니다. (배열의 최대 크기: 10개, 각 링크의 최대 길이: 255) |
| qr\_code          | string  | QR Code가 그려진 이미지 URL 주소입니다. (최대 길이: 255)                                                                                                                                                 |
| bar\_code         | string  | Bar Code가 그려진 이미지 URL 주소입니다. (최대 길이: 255)                                                                                                                                                |
| attributes        | array   | NFT의 속성값들이 담긴 `object` 배열입니다. `trait_type`으로 노출할 속성명, `value`로 속성값을 쌍을 이뤄 지정합니다. 또한 옵셔널로 `max_value`를 함께 지정하여 속성값의 최대값을 표현할 수 있습니다. 이 경우 `value`의 값은 `max_value`의 값을 초과해서는 안 됩니다.        |
| status\_url       | string  | NFT의 상태 정보를 담고 있는 외부 URL 주소입니다. 해당 URL에서는 JSON 값을 반환해야하고, 필수적으로 bool type의 `valid` 필드와 선택적으로 array type의 `attributes` 필드를 설정할 수 있습니다.                                                    |

{% hint style="warning" %}
token uri에 data:application/json 으로 시작하는 data uri를 지정하는 경우, 일부 화면에서 정상적으로 처리되지 않을 가능성이 있고 1024자 이상은 지원되지 않습니다. 가능하면 http 또는 https URL을 사용하는 것을 권해드립니다.
{% endhint %}

## 권장 이미지 및 영상 규격 <a href="#recommended-media-spec" id="recommended-media-spec"></a>

Klip에 노출되는 NFT 이미지와 영상은 각각 권장 규격과 파일 형식이 존재합니다. 아래 기준을 따르지 않는 경우 NFT 이미지 또는 영상이 정상적으로 표시/재생되지 않을 수 있습니다.

* 이미지 규격
  * 최소 크기: 1024px x 1024px 이상
  * 최대 크기: 23170px x 23170px 이하
  * 용량: 5MB 이하
  * 확장자: JPG, JPEG, GIF, PNG 등 이미지 파일 확장자 (동영상 형식 미지원)
  * 해상도: 72dpi 이상
* 영상 규격
  * 최대 크기: 가로 3840px, 세로 2160px 이하
  * 용량: 50MB 이하
  * 확장자: MP4
  * 동영상 코덱: H.264
  * 오디오 코덱: AAC
  * 레터박스는 영상에 포함하지 않는 것을 권장

## 구조와 예시 <a href="#example" id="example"></a>

Klip에서 지원하는 속성에 맞춰 작성된 메타데이터의 예시는 아래와 같습니다.

```json
{
    "name": "Magic Sword",
    "description": "You can summon a demonic sword with a magic attribute.",
    "image": "https://media.klipwallet.com/card_asset/163632/c6525c6e-060c-426f-9275-0dabadb0ba97.png",
    "background_color" : "#ffffff",
    "sendable": true,
    "group_name": "Weapon",
    "group_icon": "https://media.klipwallet.com/temp_eventcard/bomb_klip.jpg",
    "hashtags": ["Game","GroundX","Magic"],
    "layout": "general",
    "external_link": "https://gxmagicgame.com",
    "custom_links": [
        {
            "display_name": "Klip Homepage",
            "value": "https://klipwallet.com/"           
        },
        {
            "display_name": "GroundX Homepage",
            "value": "https://www.groundx.xyz/"
        }
    ],
    "attributes" : [
        {
            "trait_type": "Sword",
            "value" : "Iron Short Sword"
        }, 
        {
            "trait_type": "Magic Type",
            "value": "Fire"
        },
        {
            "trait_type": "Sword Level",
            "value": "5",
            "max_value": "10"
        },
        {
            "trait_type": "Magic Level",
            "value": 2,
            "max_value": 15
        }
    ],
    "status_url" : "https://fakeapi.gx.com/itemstatus?item_id=923874829"
}
```

여기에서 status\_url에 지정된 URL 주소를 통한 응답값 예시는 아래와 같습니다.

```json
{
    "valid": true,
    "attributes": [
        {
            "trait_type": "VIP Membership",
            "value": "Applicable"
        },
        {
            "trait_type": "Expiration Date",
            "value": "2023-12-31"
        }
    ]
}
```

위의 예시 메타데이터로 발행한 NFT가 Klip에서 어떻게 보이는지 살펴보겠습니다.

![NFT예시이미지1](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-df6afd695997ed28f65dad070b38490038fa5482%2FNFTSample1.png?alt=media)

먼저 메타데이터에 포함된 `image` 파일이 NFT 대표 이미지로 나타나고, 그 아래로 `name`과 `description`이 표시됩니다. `animation_url`을 추가하여 동영상이 있는 경우에도 `image`는 필수 값으로, 여기에 지정된 이미지가 대표 이미지로 표시되고 동영상은 대표 이미지를 클릭해 확인할 수 있습니다. `name` 아래에 `group_icon`과 `group_name` 정보가 표시됩니다. 그룹이 지정되면 콜렉션 내의 NFT 목록에서 상단에 필터 메뉴가 표시되어 빠른 분류 및 검색이 가능합니다. `description` 아래에 `hashtags`를 통해 지정한 해시태그 값들이 #가 자동으로 붙어 표시됩니다.

![NFT예시이미지2](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-f147084ef7f22559ff341ac89a4a7fc835d2ba4f%2FNFTSample2.png?alt=media)

`status_url`로 동적 정보가 지정된 경우, 그 하단에 상태값과 속성을 실시간으로 가져와 NFT 정보에 보여줍니다.

![NFT예시이미지3](https://3172838291-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnNTSgYr0w3EdZpxFJdYr%2Fuploads%2Fgit-blob-54d5563ba3a7f3513d37f1f4fd084601025df50b%2FNFTSample3.png?alt=media)

그 하단으로 `attributes`를 통해 지정한 세부 속성값이 `trait_type` - `value` 쌍으로(`max_value`가 함께 지정된 경우 최대값이 함께 표시), `external_link`를 통해 지정한 URL이 클릭 가능한 관련 링크로, `custom_links`를 통해 지정한 레이블명(`display_name`)과 URL(`value`)값이 각각 버튼 링크로 표시됩니다. 외부 링크는 클릭 시, 외부 브라우저를 통해 앱 전환되어 열리게 됩니다. 아울러 본 NFT는 `sendable`이 true로 지정되어있기 때문에 "보내기" 버튼이 화면 오른쪽 상단의 메뉴 아이콘 버튼을 통해 제공됩니다. 그 이하로 표시되는 내용들은 NFT의 수신 내역과 콜렉션에 대한 정보들로, 메타데이터와 직접적으로 관련 있는 내용은 아닙니다.

이렇게 외부에서 Klip의 표준에 맞춰 구성된 메타데이터가 Klip UI 상 어떻게 표시되는지 알아보았습니다. 본 스크린샷은 환경에 따라, 또는 추후 Klip UI 개선/변경에 따라 다소 차이가 발생할 수 있습니다.

이 문서 혹은 Klip에 관한 문의는 [개발자 포럼](https://klipforum.zendesk.com)을 방문해 도움을 받으십시오.


# Change Log

이 페이지는 Klip Docs 업데이트 기록을 제공합니다.

## 2025/09/15

* 클립의 XRPL (리플) 네트워크 지원에 따라 지갑 연동의 주소 응답값에 XRPL 주소 포함

## 2025/08/18

* 클립 지원 네트워크 확장에 따른 지갑 연동의 주소 응답값 변경
* 서명 요청에 eth\_signTypedData\_v4 지원

## 2025/02/11

* iOS SPM을 사용하여 SDK를 적용하는 방법 추가
* OS별 request 함수 호출 이슈 수정을 위한 JavaScript SDK 2.3.3 배포

## 2024/11/18

* 클립 호출 방식 변경에 따른 App2App REST API Request 내용 수정
* 클립 호출 방식 변경에 따른 JavaScript/Android/iOS SDK 새 버전 배포 및 내용 수정

## 2024/10/31

* Klaytn -> Kaia 변경에 따른 내용 수정 (문서만 변경된 것으로, 기능 스펙은 호환성이 보장됨)
* Kaia의 새로운 서명 표준에 따라, App2App 요청 타입에 `sign_message_eip191` 추가

## 2024/08/01

* Klip Partners 서비스 종료에 따른 내용 수정

## 2024/03/18

* [클립 NFT 메타데이터 표준](/klip-guide/metadata-std)에 max\_value를 사용하는 attributes에 대한 설명 및 예시 추가

## 2023/09/05

* [클립 관련 디자인 가이드](/klip-guide/design-guidelines)를 확인하고 다운로드할 수 있는 페이지 추가
* 기존의 [클립 NFT 메타데이터 표준](/klip-guide/metadata-std) 문서 위치를 Tutorial에서 [Klip Guide](/klip-guide) 밑으로 이동

## 2023/08/03

* 월렛커넥트 (WalletConnect) 지원

## 2023/06/05

* Klip 로그인 버튼 가이드에 Klip 2.0 로고 반영

## 2023/05/30

* App2App Polygon 체인 지원

## 2023/04/11

* Card Minting API 섹션 이름을 좀 더 직관적이게 Klip Partners API로 변경

## 2023/04/05

* App2App JavaScript SDK 2.2.1 배포
* App2App Deeplink 요청 scheme을 인톡클립 우선 호출하도록 변경

## 2023/03/10

* App2App Prepare 요청 시 가스추정량을 계산할 수 있는 경우 함께 반환

## 2023/01/27

* App2App Ethereum 체인 지원
* App2App 트랜잭션 수수료 대납 가이드 추가
* Contract execute 업데이트
  * param type 오류에 대한 상세 정보 반환
* Metadata 표준 개선
  * 필드명을 정의할 수 있는 외부 링크 제공 (custom\_links)
  * 외부 링크 표준 추가 제공 (external\_url)

## 2022/12/19

* Klip 자산 지원 정책 변경과 관련된 주의 사항 / 안내 추가

## 2022/11/15

* Klip에서 지원하는 메타데이터 속성 표준 안내 페이지 추가

## 2022/11/02

* Contract execute 업데이트
  * tuple 지원
  * encoded\_function\_call 지원
* Sign message 업데이트
  * v값에 chain id 제거
  * is\_hex\_encoded 추가

## 2022/09/15

* Klip 앱 지원을 위한 SDK 업데이트 (v2.2.0)
* App2App `sign message` 예제 코드 추가

## 2022/08/18

* Klip 앱 지원을 위한 SDK 업데이트 (v2.1.0)

## 2022/08/17

* App2App `sign message` 기능 설명 추가

## 2022/03/08

* 개발자 포럼 URL 변경

## 2021/09/30

* App2App API의 Response status에 `canceled` 추가

## 2021/07/28

* animation\_url 필드 제약 사항 업데이트

## 2021/07/13

* App2App 인증 API 사용 시 주의사항 문구 추가

## 2021/07/07

* App2App SDK 오픈소스 고지문에서 사명 변경

  | 변경 전     | 변경 후    |
  | -------- | ------- |
  | Ground1  | GroundX |
  | Ground X | GroundX |

## 2021/06/28

* App2App 인증 요청 버튼 문구 관련 가이드 추가

## 2021/05/10

* 신규 API 추가
  * 임의의 NFT resource 파일을 업로드할 수 있는 API를 추가했습니다.
* Card Minting API Request에 필드 추가
  * `animation_url` 필드에 동영상 주소를 설정할 수 있습니다.

## 2021/03/08

* 사명 변경 및 이메일 주소 업데이트

  | 변경 전                       | 변경 후                        |
  | -------------------------- | --------------------------- |
  | (주)그라운드원                   | (주)그라운드엑스                   |
  | <klip-partners@ground1.io> | <klip-partners@groundx.xyz> |

## 2021/02/03

* 특정 Klip 회원에게 발행 및 전송하기 API 응답 필드에 트랜잭션 해시가 추가됐습니다.
* Card Minting API의 Request에 필드 추가
  * `secure` 필드에 카드 소유자만 볼 수 있는 속성을 설정할 수 있습니다.
  * `status_url` 필드에 카드의 상태를 불러올 수 있는 외부 URL을 설정할 수 있습니다.
  * `external_link` 필드에 Klip 외부로 연결되는 URL을 설정할 수 있습니다.
* 튜토리얼 오타 수정

## 2021/01/12

* 신규 API 추가
  * 트랜잭션 해시로 처리 결과를 확인할 수 있는 API가 추가됐습니다.
  * 이번 달 현재까지 발행한 카드 개수를 조회할 수 있는 API가 추가됐습니다.
* Introduction 내 링크 오류 수정

## 2020/11/30

* QR Code 기반 App2App 처리 기능 신규 추가
  * PC 또는 물리적으로 떨어진 환경에서 App2App 기능을 실행할 수 있습니다.
  * 모바일 카메라 앱 또는 Klip에서 QR Code를 인식하면 App2App 요청을 처리하는 방식으로 동작합니다.
* 에스크로 카드 전송 API 신규 추가
  * Klip 파트너스 계정에 보유 중인 카드를 에스크로 전송하면 카드 지급 링크가 생성됩니다.
  * 생성된 링크를 클릭하면 카드를 지급받을 수 있습니다.

## 2020/10/26

* App2App API 추가
  * 외부 서비스에서 Klip 사용자 주소를 가져오는 기능을 제공합니다.
  * 외부 서비스에서 Klip을 이용해 KLAY 및 대체 가능한 토큰(FT), 카드(NFT)를 전송하거나 스마트 컨트랙트를 실행하는 기능을 제공합니다.

## 2020/08/26

* Mint Card To User, Mint Card To Klip Member API로 카드 발행 시 카드 메타데이터에 입력하는 Optional 필드 추가
  * `group_name`
  * `group_icon`
  * `hashtags`
  * `layout`
  * `qr_code`
  * `bar_code`
* Get Card Information By BApp API와 Get Card Information API의 Response 값 변경

  | 변경 전                         | 변경 후                         |
  | ---------------------------- | ---------------------------- |
  | `bapps[i].cards.cards[i]`    | `bapps[i].cards[i]`          |
  | `bapps[i].cards.next_cursor` | `bapps[i].cards_next_cursor` |
* Get Card Information API의 Response 값 변경

  | 변경 전                | 변경 후          |
  | ------------------- | ------------- |
  | `cards.cards[i]`    | `cards[i]`    |
  | `cards.next_cursor` | `next_cursor` |
* Get Card Information API의 Request Parameter에 Query Parameter `isAll` 추가

## 2020/07/31

* Mint Card API를 Mint Card To User API로 이름 변경
  * EOA를 가진 사용자(Klip 회원 또는 비회원)에게 카드를 발행합니다.
  * 발행 시 사용자 EOA를 사용합니다.
* Mint Card To Klip Member API 신규 추가
  * Klip 회원에게 카드를 발행합니다.
  * 발행 시 Klip 회원의 실명과 전화번호를 사용합니다.
* Send Card API를 Send Card To User API로 이름 변경
  * EOA를 가진 사용자(Klip 회원 또는 비회원)에게 카드를 전송합니다.
  * 전송 시 사용자 EOA를 사용합니다.
* Send Card To Klip Member API 신규 추가
  * Klip 회원에게 카드를 전송합니다.
  * 전송 시 Klip 회원의 실명과 전화번호를 사용합니다.
* Send Card To User, Send Card To Klip Member API의 Response에서 `failCount` 변수명을 `fail_count`로 변경

## 2020/07/16

* Get Card Information By BApp API Response에서 `order_no` 변수명을 `nft_order_no`로 변경

## 2020/06/16

* Send Card API의 Request Body Parameter에서 `to_klip_id` 사용 중지

## 2020/05/28

* [Klip 파트너스 회원사](https://partners.klipwallet.com/)가 Klip에 로그인하고 카드(NFT)를 발행/전송/조회할 수 있도록 Klip API 개발


