# 소개

### Welcome

위핀(Wepin) 개발자 문서를 방문해 주셔서 감사합니다. 이 문서에서는 Web3 지갑 솔루션 위핀을 애플리케이션에 통합하는 방법에 대해서 설명합니다. 위핀의 인앱 위젯을 통해 쉽고 빠르게 서비스와 통합하는 방법에 대해 알아보세요.

위핀 지갑 SDK를 앱과 연동하기 위해서는 먼저 App ID와 App Key 발급이 필요합니다. 발급은 위핀 워크스페이스(Wepin Workspace)의 개발 도구(Development Tool)에서 앱 정보를 등록하고 받을 수 있습니다. 자세한 방법은 [앱 등록 및 키 발급 페이지](/wepin/workspace/app-registration-and-key-issuance)를 참고하세요.

{% embed url="<https://workspace.wepin.io>" %}

### 구성 요소 <a href="#components" id="components"></a>

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>아키텍처</strong> </td><td>지갑의 키 관리와 구성 요소에 대해서 알아보세요.</td><td></td><td><a href="/pages/m9QEQEypCro2peWfI6uj">/pages/m9QEQEypCro2peWfI6uj</a></td></tr><tr><td> <strong>소셜 로그인</strong></td><td>위핀에서 제공하는 소셜 로그인 인증 제공자에 대해 살펴보세요.</td><td></td><td><a href="/pages/QVlvsaE6CqleGTg5HNjE">/pages/QVlvsaE6CqleGTg5HNjE</a></td></tr><tr><td><strong>지원 블록체인</strong></td><td>위핀에서 지원하는 블록체인 네트워크에 대해 알아보세요.</td><td></td><td><a href="/pages/jNG611rZkq69C8zZKglh">/pages/jNG611rZkq69C8zZKglh</a></td></tr></tbody></table>

### 위젯 연동 <a href="#widget-integration" id="widget-integration"></a>

위젯 연동을 통해 단 10분 만에 앱에 지갑을 내장할 수 있습니다. 현재 지원하는 플랫폼을 선택하여 시작해보세요.

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>WEB</strong></td><td><a href="/files/sxhGRCfaskpV9jEYdrrw">/files/sxhGRCfaskpV9jEYdrrw</a></td><td><a href="/pages/MEW6ehTd2XIqIAPe8YTf">/pages/MEW6ehTd2XIqIAPe8YTf</a></td></tr><tr><td align="center"><strong>Android</strong></td><td><a href="/files/FUsCRJwQ7wowF9kp7Pek">/files/FUsCRJwQ7wowF9kp7Pek</a></td><td><a href="/pages/GvjzIdRoeTi1Z6vHXv5G">/pages/GvjzIdRoeTi1Z6vHXv5G</a></td></tr><tr><td align="center"><strong>iOS</strong></td><td><a href="/files/EZdXi5n1zCz7SFF7UNYp">/files/EZdXi5n1zCz7SFF7UNYp</a></td><td><a href="/pages/Zcb5TPX7EDJpBVjftNc2">/pages/Zcb5TPX7EDJpBVjftNc2</a></td></tr><tr><td align="center"><strong>Flutter</strong></td><td><a href="/files/bLw4b8tfgq7v8s5MEAg3">/files/bLw4b8tfgq7v8s5MEAg3</a></td><td><a href="/pages/Skd7friEk0cjUrCXxgdF">/pages/Skd7friEk0cjUrCXxgdF</a></td></tr><tr><td align="center"><strong>React Native</strong></td><td><a href="/files/MpnJEJ9KovvU2J16UnGx">/files/MpnJEJ9KovvU2J16UnGx</a></td><td><a href="/pages/0JbQYH8TKZl2I2IWyjmu">/pages/0JbQYH8TKZl2I2IWyjmu</a></td></tr><tr><td align="center"><strong>Unity</strong></td><td><a href="/files/QSsVt7Yl9hxT8pkyyPCe">/files/QSsVt7Yl9hxT8pkyyPCe</a></td><td><a href="/pages/3uV92DanPjLz5ajIChEv">/pages/3uV92DanPjLz5ajIChEv</a></td></tr><tr><td align="center"><strong>Compose Multiplatform</strong></td><td><a href="/files/DjmzvilovxljmBCOnak0">/files/DjmzvilovxljmBCOnak0</a></td><td><a href="/pages/6g4keZQNXIAF9RnGGL37">/pages/6g4keZQNXIAF9RnGGL37</a></td></tr></tbody></table>

{% hint style="info" %}
위핀에서는 앱에 최적화된 UX/UI를 구축할 수 있도록 지갑 기능을 RESTful API로 제공합니다. RESTful API를 통한 지갑 통합 방법은 [해당 페이지](/restful-api/restful-api)를 참고하세요.
{% endhint %}


# 퀵스타트

이 예제에서는 JavaScript 기반의 WEB 어플리케이션에 위핀 지갑을 빠르게 통합하는 방법에 대해 설명합니다. 위핀에서는 아래 세 가지를 각각의 패키지로 제공하며, 필요에 따라서 선택하여 설정할 수 있습니다.

* 로그인: 사용자의 위핀 지갑 로그인을 위한 OAuth 인증 토큰 및 이메일을 지원합니다.
* 위젯: 위젯 형태로 연동된 위핀의 지갑 기능을 제공합니다.
* 프로바이더 : 블록체인과 상호 작용하기 위한 프로바이더로, Ethereum Provider와 Wagmi Provider를 지원합니다.

{% hint style="info" %}
Wepin Provider를 Ethers.js 또는 Web3.js와 함께 사용하여 EVM 계열의 블록체인과 상호작용 할 수 있습니다. 자세한 내용은 [프로바이더 페이지](/widget-integration/web-javascript-sdk/provider)를 참고하세요.
{% endhint %}

### SDK 설치

패키지 매니저로 SDK를 설치합니다.&#x20;

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

```sh
npm install @wepin/login-js @wepin/sdk-js @wepin/provider-js
```

{% endtab %}

{% tab title="yarn" %}

```sh
yarn add @wepin/login-js @wepin/sdk-js @wepin/provider-js
```

{% endtab %}
{% endtabs %}

### SDK 초기화하기

SDK를 초기화하기 위해서는 위핀에서 사용할 app Id와 app Key가 필요합니다. [위핀 워크스페이스](https://workspace.wepin.io/)에 가입하여 앱 정보를 등록 후 app Id와 app Key 값을 아래 코드에 붙여 넣습니다. 자세한 안내가 필요할 경우, [앱 등록 및 키 발급 페이지](/wepin/workspace/app-registration-and-key-issuance)를 참고하세요.&#x20;

```javascript
// 패키지 import
import { WepinLogin } from '@wepin/login-js'
import { WepinSDK } from '@wepin/sdk-js'
import { WepinProvider } from '@wepin/provider-js'

// WepinLogin 초기화
const wepinLogin = new WepinLogin({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-api-key',
})

// wepin SDK 초기화
const wepinSdk = new WepinSDK({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-api-key',
})

// WepinProvider 초기화
const WepinProvider = new WepinProvider({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-api-key',
})
```

{% hint style="warning" %}
위 패키지는 클라이언트 사이드 렌더링(CSR: Client Side Rendering) 환경에서만 동작합니다. 서버 사이드 렌더링(SSR: Server Side Rendering) 환경에 대한 안내는 패키지별 설치  페이지를 참고하세요.
{% endhint %}

### 다음 단계

이제 위핀 지갑을 사용할 준비를 마쳤습니다! 위핀에서 제공하는 [위젯의 다양한 기능](/widget-integration/web-javascript-sdk/widget/methods)과 [로그인 프로바이더](broken://pages/vxTFuTdrmfqTTqNlqGfS)를 활용하여 원하는 형태의 지갑을 구성해보세요.

{% hint style="info" %}
위핀 연동에 문제가 있을,경우 [문의하기](https://mail.google.com/mail/u/0/?to=wepin.contact@iotrust.kr\&su=%EB%AC%B8%EC%9D%98%ED%95%98%EA%B8%B0%5BGeneral%5D\&body=%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94.+%EA%B4%80%EB%A0%A8+%EB%AC%B8%EC%9D%98+%EC%82%AC%ED%95%AD%EC%9D%84+%EC%9E%85%EB%A0%A5%ED%95%B4%EC%A3%BC%EC%84%B8%EC%9A%94.\&fs=1\&tf=cm)를 통해 지원을 받아보세요.
{% endhint %}


# 개요

지갑은 사용자가 Web3에 진입하기 위한 첫 번째 관문입니다. Web2에서 로그인에 널리 사용된 이메일이나 소셜 로그인 계정과는 다르게, Web3는 자산을 직접 관리하기 위한 개인키가 필요합니다. 코인과 토큰, NFT 등 사용자의 자산에 대한 소유권을 관리하기 위한 블록체인의 구성은 사용자에게 완전한 소유권을 보장하지만, 익숙하지 않은 환경에서 사용자들이 원하는 Web3 애플리케이션으로 진입하는데 장벽이 되기도 합니다. 뿐만 아니라, 앱을 만드는데 집중 해야할 팀이 사용자들의 온보딩에서 이탈을 막기 위해 지갑을 고민하고, 이 과정에서 발생하는 고객의 요청을 대응하는 등 자원을 분산화 시키는 어려움이 발생할 수 있습니다.

위핀은 지갑을 개발하는데 필요한 고민과 비용을 획기적으로 줄여주는 Web3 지갑입니다. 위핀에서 제공하는 SDK를 이용하여 사용자의 앱에서 지갑으로의 온보딩을 쉽고 간편하게 구축할 수 있도록 빌트인 형식으로 구현할 수 있습니다. 이를 통해 앱을 개발하는 수많은 팀들이 지갑을 고민하는데 필요한 시간과 자원을 낭비하지 않고, 앱의 핵심 가치에 집중할 수 있습니다.

이러한 목적을 달성하기 위해 위핀은 다음과 같은 특징을 가진 지갑으로 개발되었습니다.

### 빌트인(인앱) 위젯

개발자는 위핀에서 제공되는 SDK를 설치하여 단 10분만에 지갑을 웹/앱과 연동할 수 있습니다. 앱에 빌트인된 위젯을 통해, 사용자는 앱을 떠나 지갑의 주소를 복사하거나, 자신의 자산이나 거래내역을 확인하는 번거로운 과정을 거치지 않아도 됩니다. 위핀을 통해 앱 내에서 지원되는 플로팅 버튼을 클릭만 함으로써 사용자는 지갑의 내역을 확인할 수 있습니다. 또한 앱에서 사용자의 주소 정보가 필요할 경우, 앱에서 활성화된 지갑으로 부터 간단하게 주소를 불러오는 것과 같이 앱과 일체화된 경험을 사용자에게 제공할 수 있습니다. 추가적으로, 위핀에서 제공하는 위젯 디자인을 활용하여, 손쉽게 앱과 일체화된 UI를 제공할 수 있습니다.

손쉽게 위젯 디자인을 설정하는 방법을 확인해보세요.

{% content-ref url="/pages/bIUtQ9JiIt0Dx6Wwy7Os" %}
[위젯 디자인](/wepin/workspace/widget-design)
{% endcontent-ref %}

### 소셜 로그인 기반 회원 가입/로그인

사용자의 온보딩  과정에서 마주하는 가장 큰 어려움 중 하나는 니모닉 문구였습니다. 12-24자리의 단어 목록은 완전한 소유권을 보장하지만, 동시에 사용자에게 분실에 대한 염려와 관리의 어려움을 가져다 줍니다. 무엇보다 단어를 기억하고, 올바른 단어를 인지했는지 확인하기 위한 과정에 걸쳐 사용자가 앱으로 진입하기까지의 시간을 지연시킵니다. 이는 사용자에게 어려움, 귀찮음과 같은 부정적인 인식을 심어줄 수 있으므로 앱의 가치에 악영향을 줄 수 있는 심각한 문제입니다.

이러한 문제를 해결하기 위하여 위핀은 사용자에게 익숙한 이메일, 소셜 로그인 방식을 통해 지갑을 생성하고 개인키를 관리할 수 있도록 지원합니다. 이미 경험한 방식으로 회원가입, 로그인 과정을 거쳐 사용자가 어렵지 않게 지갑과 계정을 생성할 수 있도록 유도하고, 앱내 핵심 가치로 전환 될 수 있는 시간을 단축시킬 수 있습니다.

현재 지원되는 로그인 제공자(Login Provider)를 확인해보세요.

{% content-ref url="/pages/nCDAbhdDOBhShLyYrISb" %}
[소셜 로그인 인증 프로바이더](/login/social-login-auth-provider)
{% endcontent-ref %}

### 멀티체인 지원

미래는 멀티체인 시대입니다. 이미 수많은 블록체인 메인넷들이 운영중에 있으며, 사용자는 하나의 체인에 머무르지 않습니다. 즉, 사용자는 다양한 메인넷에 속해있는 자산을 가지고 체인 간 여행을 하고 있습니다. 개발자는 앱을 배포할 메인넷의 환경만 신경쓰면 되지만, 사용자는 여러가지 앱을 탐색하면서 메인넷이 바뀔 때마다 별도의 다른 지갑을 가지고 운영해야 합니다. 이는 사용자에게 혼란스러움을 가중시킵니다.

결과적으로 사용자의 자산을 통합 관리할 수 있는 멀티체인 환경과 이를 지원할 수 있는 지갑이 필요합니다. A 앱에서는 A 지갑, B 앱에서는 B 지갑이 아니라, A, B가 배포된 블록체인 환경을 모두 지원하는 하나의 지갑이 사용자에게는 편리합니다. 위핀에서는 이러한 환경을 지원하기 위해 현재 20개 이상의 블록체인을 지원하기 때문에 사용자가 하나의 지갑에서 대부분의 자산을 관리할 수 있습니다.

위핀에서 지원되는 블록체인을 확인해보세요.

{% content-ref url="/pages/jNG611rZkq69C8zZKglh" %}
[지원 블록체인](/wepin/supported-blockchains)
{% endcontent-ref %}

### Non-custodial 아키텍처

Web3의 가장 큰 핵심 가치 중 하나는 자산의 소유권입니다. 소유하지 않는 자산은 사용자의 것이 아닙니다. 사용자의 소유권을 보장하는 개인키 정보는 오직 사용자만 알고 있어야 하며, 자산의 권한을 타인에게 맡기지 않고 스스로 제어할 수 있어야 합니다.

위핀은 이와 같은 요구사항을 잘 이해하고 있기에, Non-custodial 방식으로 설계되었습니다. 위핀은 사용자의 요청에 대한 명령을 수행할 뿐 사용자의 개인키 정보에 접근할 수 없습니다. 개인키에 접근할 수 있는 이는 오직 생성한 사용자뿐이며, 모든 통신 과정에서 개인키는 암호화되어 전달됩니다.

위핀의 아키텍처는 아래 링크를 통해 상세히 확인할 수 있습니다.

{% content-ref url="/pages/m9QEQEypCro2peWfI6uj" %}
[아키텍처](/wepin/architecture)
{% endcontent-ref %}


# 특징

위핀(Wepin)은 Web3 서비스에서 사용자를 간편하게 온보딩하고, 블록체인 자산을 쉽게 관리할 수 있도록 설계된 지갑 솔루션입니다. 기존 지갑 시스템은 복잡한 생성 과정과 키 관리 문제로 사용자 이탈을 초래했고, 이를 구현하는 데는 많은 비용과 리소스가 필요했습니다. 또한, 개인 키를 안전하게 관리하는 것도 큰 도전 과제였습니다. 위핀은 이러한 문제를 해결하며, 개발자들이 손쉽게 지갑을 통합할 수 있는 다양한 기능을 제공합니다. 아래에서는 위핀의 주요 기능들을 소개합니다.

### 소셜 로그인 기반의 간편한 지갑 <a href="#simple-wallet-based-on-social-login" id="simple-wallet-based-on-social-login"></a>

위핀은 Google, Apple, Naver, Discord와 같은 주요 [**소셜 로그인 제공자**](/login/social-login-auth-provider)를 지원하여 사용자가 손쉽게 지갑을 생성하고 로그인할 수 있도록 합니다. 이를 통해 복잡한 지갑 생성 절차 없이도 사용자는 빠르게 Web3 서비스에 진입할 수 있습니다. 또한, 위핀은[ **로그인 일원화 기능**](/login/simplified-login)을 통해 서비스의 로그인과 지갑 로그인을 하나로 통합하여 매끄러운 온보딩 경험을 사용자에게 제공합니다. 개발자는 필요에 따라 추가적인 [**프로바이더**](/widget-integration/web-javascript-sdk/provider)를 설정해 다양한 블록체인 네트워크와 상호작용할 수 있습니다.

### 강력한 위젯 기능 <a href="#powerful-widget-functionality" id="powerful-widget-functionality"></a>

위핀은 개발자가 서비스에 손쉽게 통합할 수 있는 위젯을 제공합니다. 이를 통해 사용자의 토큰과 NFT를 조회하고, 송수신할 수 있으며, 사용자 지갑 주소를 조회하거나 트랜잭션 서명 요청을 처리할 수 있습니다. 위젯은 다양한 언어(영어, 한국어, 일본어)를 지원하여, 글로벌 사용자에게도 일관된 경험을 제공할 수 있습니다. 또한  위젯 커스터마이징 기능을 통해 서비스의 고유한 정체성을 유지하면서도 일관된 사용자 경험을 선사할 수 있습니다. 위젯은 [Web](/widget-integration/web-javascript-sdk), [Android](/widget-integration/android-java-and-kotlin-sdk), [iOS](/widget-integration/ios-swift-sdk), [Flutter](/widget-integration/flutter-sdk), [React Native](/deprecated/react-native-sdk), [Unity](/deprecated/unity-sdk), [Compose Multiplatform](/widget-integration/compose-multiplatform-sdk) 등 다양한 환경에서 연동 가능합니다.

### 관리자를 위한 대시보드: 워크스페이스 <a href="#workspace" id="workspace"></a>

위핀은 관리자 대시보드인 [**워크스페이스(Workspace)**](/wepin/workspace)를 통해 지갑과 관련된 모든 정보를 효율적으로 관리할 수 있는 환경을 제공합니다. 워크스페이스에서는 사용자가 위젯에서 접근 할 수 있는 [**블록체인 네트워크와 토큰, NFT를 설정**](/wepin/workspace/add-networks-and-assets)할 수 있으며, [**위젯 디자인을 커스터마이징**](/wepin/workspace/widget-design)하여 서비스에 맞는 사용자 경험을 제공하는 등 별도의 코드 수정 없이 설정을 변경해 서비스 상황에 맞게 유연한 대응이 가능합니다.

### 멀티체인 지원 <a href="#multichain-support" id="multichain-support"></a>

위핀에서는 다양한 블록체인 네트워크를 지원합니다. EVM 기반 네트워크뿐만 아니라, non-EVM 블록체인도 지원하여 개발자가 지갑의 네트워크 지원으로 인한 한계에 봉착하지 않고 멀티체인으로 확장할 수 있습니다. 특히, 추가 메인넷 지원이 필요할 경우 추가적인 비용 없이 손쉽게 지원하고 있으므로, 메인넷 지원 여부에 대한 걱정 없이 지갑을 연동할 수 있습니다. [**지원 블록체인 페이지**](/wepin/supported-blockchains)에서 위핀이 지원하는 네트워크 목록을 확인해보세요.

### Non-Custodial 아키텍처 <a href="#non-custodial-architecture" id="non-custodial-architecture"></a>

위핀은 사용자가 지갑의 완전한 소유권을 가질 수 있도록 Non-Custodial 아키텍처로 설계되었습니다. 사용자의 개인 키는 오직 사용자 본인만 접근할 수 있으며, 위핀 관리자나 개발자조차도 이 키에 접근할 수 없습니다. 또한, 사용자는 자신의 지갑 키를 언제든지 추출할 수 있으며, 다른 셀프 커스터디 지갑과도 호환 가능합니다. 위핀의 키 생성과 서명과정에 대한 자세한 정보는 [**아키텍처 페이지**](/wepin/architecture)에서 확인할 수 있습니다.

### 기술 지원 <a href="#technical-support" id="technical-support"></a>

위핀은 누구나 서비스에 최적화된 인앱 지갑을 빠르고 쉽게 설정할 수 있도록 지원합니다. 1시간 만에 연동 가능한 SDK를 제공하며, 이를 통해 개발자는 복잡한 코딩 작업 없이 간단하게 위핀 지갑을 서비스에 연동할 수 있습니다. 또한, 개발자 지원 채널을 통해 빠르고 효율적인 기술 지원을 받을 수 있어, 연동 과정을 원활하게 진행할 수 있습니다.


# 아키텍처

위핀은 다음과 같은 엔티티로 구성됩니다.

<figure><img src="/files/5Erw8n9gwf9KsyKHFB8X" alt=""><figcaption></figcaption></figure>

* Cloud : 위핀은 SaaS(Software as a Service) 형태로 제공되는 클라우드 기반의 지갑 서비스입니다. 사용자가 개인키를 안전하게 암호화할 수 있도록 사용되는 KMS(Key Management System)와 저장된 키 데이터에 대한 자격을 확인하는 수단인 CIAM(Customer Identity Access Manager)을 활용합니다.
* 인증 제공자 : 인증 제공자는 사용자가 회원가입 및 로그인을 기존 시스템에서 가지고 있던 정보를 활용하여 지갑을 생성 및 제어하는데 활용할 수 있도록 지원합니다.
* 위젯 : 위젯은 위핀 지갑 기능을 손쉽게 활용할 수 있도록 앱에 빌트인 되는 애플리케이션입니다. 위핀 SDK를 설치하여 사용자가 앱 내에서 지갑 기능을 쉽게 활용할 수 있으며 , 앱이 필요한 사용자의 주소를 쉽게 불러올 수 있도록 상호작용합니다.
* 위핀 서버 : 위핀 서버는 지갑 및 블록체인과 상호 작용하기 위한 모든 처리를 담당하는 서비스의 핵심 기능을 가진 백엔드 시스템입니다. 블록체인 노드와 연결되어 거래를 전송하고 자산을 불러오며, 사용자의 요청에 의해 키를 생성 및 서명을 담당합니다. 키 생성과 서명과 같이 개인키 정보와 관련된 연산은 신뢰 실행 환경(Trusted Execution Environment) 하에서 실행되기 때문에 위핀 서버는 사용자의 개인키에 접근할 수 없습니다.

위핀에서 개인키를 활용한 작업에 대한 플로우를 아래 링크를 통해 확인하세요.&#x20;

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>키 생성</strong></td><td><a href="/files/0yPDaKMdEIbF24CIVAzM">/files/0yPDaKMdEIbF24CIVAzM</a></td><td><a href="/pages/KpnmN2n54kNMRqNhlmOB">/pages/KpnmN2n54kNMRqNhlmOB</a></td></tr><tr><td align="center"><strong>서명</strong></td><td><a href="/files/dMHFlTbw32IoAQZ2OCh8">/files/dMHFlTbw32IoAQZ2OCh8</a></td><td><a href="/pages/3q63WniJVW3oihROae6q">/pages/3q63WniJVW3oihROae6q</a></td></tr><tr><td align="center"><strong>키 백업</strong></td><td><a href="/files/ux6xLfOfdXY0KHly1yWQ">/files/ux6xLfOfdXY0KHly1yWQ</a></td><td><a href="/pages/9odYk5QooDUB7Ne4OcmU">/pages/9odYk5QooDUB7Ne4OcmU</a></td></tr></tbody></table>


# 키 생성

<figure><img src="/files/KKffZS075H0VxeqjcsJX" alt=""><figcaption></figcaption></figure>

위핀은 인증 프로바이더를 통해서 웹2의 회원가입, 로그인 경험을 바탕으로 지갑을 생성할 수 있습니다. 인증 프로바이더로부터 회원 가입 후, AWS에 접근하여 키 관리를 위한 토큰을 교환한 후 위핀 서버로 키 생성을 요청합니다. 이 때 설정되는 PIN번호는 지갑에서 관리하는 개인키를 암호화 하는데 사용되는 중요한 정보입니다. (PIN 번호는 암호화하여 위핀 서버로 전송되기 때문에 노출되지 않습니다.) 위핀 서버가 지갑 생성 요청을 받으면, AWS KMS에 랜덤 값 생성을 요청하며, 랜던 값을 받아 사용자의 개인키를 생성합니다. 생성된 개인키는 비밀 정보이므로 사용자의 PIN을 기반으로 암호화를 한 후 암호화된 상태로 안전하게 클라우드에 저장됩니다.

키 생성 과정에 실행되는 연산은 신뢰 실행 환경 하에서 실행되기 때문에 위핀 서버에서 접근할 수 없습니다. 랜덤 값으로 키를 생성하고 유도하는 모든 과정은 TEE에서 실행됩니다.


# 서명

<figure><img src="/files/kaHfHJHxlCHFT1l7kTvy" alt=""><figcaption></figcaption></figure>

키 생성 절차와 마찬가지로, 로그인한 사용자는 암호화된 키가 저장된 스토리지에 접근할 수 있는 토큰을 받아 서명이 필요한 트랜잭션과 함께 위핀 서버에 요청합니다. 서버는 사용자의 토큰을 이용하여 암호화된 개인키를 가져 온 후 사용자가 제출한 PIN을 활용하여 개인키를 복호화 합니다. 복호화된 키로 트랜잭션에 서명한 후 개인키는 다시 안전하게 암호화하여 클라우드에 저장됩니다.

서명을 위한 연산도 마찬가지로 신뢰 실행 환경에서만 실행됩니다. 따라서 서명 생성시 메모리에 로드되는 개인키는 위핀 서버에서 접근할 수 없기 때문에, 서버는 개인키 정보를 알 수 없습니다. 서버는 단지 연산을 실행해주는 역할을 할 뿐, 개인키의 정보는 공개되지 않으며, 거래에 서명하는 프로토콜 전 과정에서 암호화된 채로 상호 작용합니다.


# 키 백업

위핀에서 사용하는 키를 백업하여 다른 지갑 시스템에서 활용하고자 하는 경우 개인키를 익스포트 할 수 있습니다. 사용자는 키를 익스포트 하기 위해 본인임을 인증한 후, 책임 소재에 대한 약관에 동의를 해야합니다. 반환되는 키는 니모닉 문구로 제공되며, 반환된 키에 귀속된 사용자의 자산에 대해서 위핀은 책임지지 않음을 알려드립니다.


# 워크스페이스

**위핀 워크스페이스(Wepin Workspace)**&#xB294; 위핀의 관리자 대시보드로 위핀 지갑을 연동하려는 서비스 제공자(앱 개발자)가 위젯 및 지갑을 효율적으로 관리할 수 있도록 다양한 기능을 제공합니다. 워크스페이스의 세부 기능은 아래 각 페이지에서 상세히 확인할 수 있습니다.

* [앱 등록 및 키 발급](/wepin/workspace/app-registration-and-key-issuance): 앱과 연동된 지갑 관리를 위해 앱 정보를 워크스페이스에 등록하기 위한 절차입니다.
* [네트워크 및 자산 추가](/wepin/workspace/add-networks-and-assets): 연동된 위핀 지갑과 연결된 블록체인 정보를 설정하여 사용자에게 보여지는 자산 목록을 관리합니다.
* [위젯 디자인](/wepin/workspace/widget-design): 위젯의 UX/UI를 커스터마이징 할 수 있는 기능입니다.


# 앱 등록 및 키 발급

위핀 지갑을 연동하기 위해서 위핀 워크스페이스에서 앱 정보를 등록하고 App ID 와 App Key를 발급받아야 합니다. 아래 위핀 워크스페이스로 이동하여 회원 가입 후 로그인을 진행해 주세요.

{% embed url="<https://workspace.wepin.io>" %}

로그인 후 워크스페이스에서 앱의 이름을 입력하면, 아래와 같은 워크스페이스 대시보드가 화면에 나타납니다. 앱 이름은 기본 정보 탭에서 변경할 수 있습니다.

<figure><img src="/files/cahmAcVhMmeN0hKooQA9" alt=""><figcaption></figcaption></figure>

워크스페이스 화면의 안내에 따라 네트워크와 자산을 추가한 후(생략 가능), 앱 정보를 등록하고 키를 발급 받습니다. 먼저, 개발 도구 탭에서 App ID를 확인합니다. App ID는 앱 생성 시에 자동으로 생성되는 값입니다. App ID를 확인 후, 앱 개발 환경에 따라 다음과 같이 설정할 수 있습니다.

<figure><img src="/files/IplBN98ztrqJ9PAl60TR" alt=""><figcaption></figcaption></figure>

#### Web

Web의 기본 도메인 (예.<http://localhost:3000>)을 입력하고 저장하면, App Key가 화면에 나타나는 것을 확인할 수 있습니다.

<figure><img src="/files/7U6ZMsIiz0WQ6nCiEDfY" alt=""><figcaption></figcaption></figure>

#### Android

Android 패키지명을 입력하고 저장하면, App Key가 화면에 나타나는 것을 확인할 수 있습니다.

<figure><img src="/files/8L6OOitAM0Fg4NYUseI5" alt=""><figcaption></figcaption></figure>

#### iOS

번들 ID를 입력하고 저장하면, App Key가 화면에 나타나는 것을 확인할 수 있습니다.

<figure><img src="/files/WjEhLtG4xV8D7b7b3oIU" alt=""><figcaption></figcaption></figure>

위핀 설치를 위한 앱 등록과 키 발급이 완료되었습니다.


# 네트워크 및 자산 추가

앱과 연동된 지갑에서 사용할 네트워크를 설정할 수 있습니다. 네트워크 탭에서 네트워크 추가하기를 선택하여 앱에서 사용되는 네트워크 이름을 검색합니다. 지원되는 네트워크 전체를 확인하려면, [지원 블록체인 페이지](/wepin/supported-blockchains)를 참고하세요.

<figure><img src="/files/o3oM1vjAIRmGK7CtjuGZ" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
목록에 필요한 블록체인이 없나요? [위핀 팀에 요청](https://wepinwallet.typeform.com/WEPIN-Wallet)하여 별도의 비용 없이 블록체인을 추가할 수 있습니다.
{% endhint %}

네트워크를 추가한 후에, 연동되는 위핀 위젯에서 사용자에게 보여줄 자산을 등록해야 합니다. 앱의 특성에 따라 위젯 내에서 사용자에게 보여지는 토큰 목록을 설정할 수 있습니다.토큰 목록은 삭제하거나 숨김 처리할 수 있습니다.

<figure><img src="/files/QQFjB7UMu8iSxZAWCYhL" alt=""><figcaption></figcaption></figure>

멀티체인일 경우, 동일한 토큰이라도 네트워크 별로 상이하기 때문에 네트워크마다 토큰을 추가해야 합니다. 예를 들어, 이러디움과 폴리곤의 USDT를 토큰 목록에 추가하려는 경우, 이더리움 네트워크에서 USDT를 추가하더라도 폴리곤 네트워크의 USDT를 추가해야 합니다.&#x20;

<figure><img src="/files/sSIqbjGT0Tl63WnPCeql" alt=""><figcaption></figcaption></figure>


# 위젯 디자인

[위핀 워크스페이스](https://workspace.wepin.io/)를 통해 지갑 위젯을 손쉽게 커스터마이징하여, 여러분의 앱에 맞는 사용자 경험을 제공할 수 있습니다. 이 문서에서는 위핀 워크스페이스를 활용해 위젯의 디자인과 기능을 설정하는 방법을 단계별로 설명합니다.

### 위젯 디자인 미리보기 <a href="#previewing-widget-design" id="previewing-widget-design"></a>

먼저, 위핀 워크스페이스에서 위젯의 현재 적용된 기본 디자인을 확인할 수 있습니다. 디자인 수정에 들어가기 전, 위젯 디자인 메뉴에서 계정 상세, 메인, 로그인의 세 가지 주요 위젯 UI를 미리 확인할 수 있습니다.

* 계정 상세: 사용자가 보유한 특정 블록체인 계정의 잔액과 세부 정보를 확인할 수 있습니다. 이 화면에서 자산을 송금하거나 받을 수 있습니다.
* 메인: 여러 블록체인 네트워크의 자산 현황을 한눈에 볼 수 있는 화면입니다. 지갑과 NFT 목록이 표시됩니다.
* 로그인: 사용자가 다양한 소셜 로그인 옵션(Google, Apple, Naver, Discord 등)을 통해 위핀 지갑에 로그인할 수 있는 화면입니다.

<figure><img src="/files/anCxnfYrwkrjA9mhvrgj" alt=""><figcaption></figcaption></figure>

### 디자인 수정하기 <a href="#editing-the-design" id="editing-the-design"></a>

위젯 디자인 메뉴에서 오른쪽의 ‘수정’ 버튼을 클릭하여 디자인 수정 화면으로 이동할 수 있습니다.

#### 컬러 테마 선택 <a href="#choosing-a-color-theme" id="choosing-a-color-theme"></a>

디자인 수정 페이지로 들어가면, 위젯의 **컬러 테마**를 선택할 수 있습니다. 다양한 컬러 옵션(Light, Dark, Mono, Pastel, Woody, DarkBerry)을 제공하며, 이 중 하나를 선택해 앱의 전반적인 디자인과 일치하도록 커스터마이징할 수 있습니다.

<figure><img src="/files/poWGxzXO0cOMsW3rdJ12" alt=""><figcaption></figcaption></figure>

#### 레이아웃 설정 <a href="#setting-the-layout" id="setting-the-layout"></a>

**홈 레이아웃**에서는 위젯의 콘텐츠 배치를 결정합니다. 예를 들어, 자산 목록과 NFT 위치를 상단 또는 하단에 배치할 수 있으며, 목록 1단, 목록 2단, 블록 1단 등 다양한 레이아웃을 선택할 수 있습니다. 이러한 레이아웃 옵션을 통해 사용자에게 필요한 정보를 가장 효율적으로 제공할 수 있습니다.

<figure><img src="/files/jyxLZeDcl5NMIJkFH228" alt=""><figcaption></figcaption></figure>

#### 로그인 이미지 및 앱 아이콘 설정 <a href="#setting-login-image-and-app-icon" id="setting-login-image-and-app-icon"></a>

**로고 이미지** 탭에서는 위핀 위젯의 로그인 화면에 표시될 이미지를 설정할 수 있습니다. 여기에서 로고를 업로드하여 브랜드 정체성을 강화할 수 있습니다. 사용자가 설정한 로고는 실시간 미리보기를 통해 어떻게 표시될지 확인할 수 있습니다.

{% hint style="info" %}
**파일 규격**: 120x120 픽셀, 5MB 이내의 PNG 또는 SVG 파일을 권장합니다.
{% endhint %}

<figure><img src="/files/nTspNUF2m6HO2IEVHHou" alt=""><figcaption></figcaption></figure>

### 디자인 저장 및 적용 <a href="#saving-and-applying-the-design" id="saving-and-applying-the-design"></a>

모든 커스터마이징 작업을 완료한 후, "저장" 버튼을 클릭하면 변경된 디자인을 저장할 수 있습니다. 저장만으로는 즉시 서비스에 반영되지 않으며, 저장된 디자인과 현재 적용된 디자인을 비교하고, 최종적으로 서비스에 적용하는 과정이 필요합니다.

<figure><img src="/files/vlnnm9H8QAcWN5a1fjEw" alt=""><figcaption></figcaption></figure>

이미지에서 볼 수 있듯이, 저장된 디자인과 현재 서비스에 적용된 디자인을 비교할 수 있는 화면이 나타납니다. 이 화면에서는 두 가지 디자인을 나란히 비교할 수 있으며, 왼쪽에는 현재 서비스에 적용된 디자인이, 오른쪽에는 저장된 새 디자인이 표시됩니다.

예시에서는 다음과 같은 변경 사항이 적용되었습니다:

* **컬러 테마**: Dark 테마로 변경되어, 위젯의 배경이 어두운 색으로 설정되었습니다.
* **NFT 위치**: NFT 목록이 화면의 상단에 위치하도록 변경되었습니다.

이 비교 화면을 통해, 저장한 디자인이 원하는 대로 적용되었는지 시각적으로 확인할 수 있습니다. 디자인이 마음에 들면, "서비스 적용" 버튼을 클릭하여 새 디자인을 실제 서비스에 반영할 수 있습니다. 반영 후, 모든 사용자에게 변경된 디자인이 적용된 위핀 위젯이 표시됩니다.

이와 같이 위핀 워크스페이스를 통해 코드를 작성하지 않고도 위젯을 커스터마이징하는 것이 가능합니다. 추가적으로, 위핀은 위젯에서 사용하는 기능을 RESTful API로도 제공하고 있습니다. 만약 여러분이 보다 더 앱에 최적화된 지갑 환경을 구축하고 싶다면, [RESTful API 페이지](/restful-api/restful-api)를 참고하세요.


# 지원 블록체인

위핀에서 지원하는 블록체인 목록입니다.&#x20;

{% hint style="info" %}
목록에 필요한 블록체인이 없나요? [위핀 팀에 요청](https://wepinwallet.typeform.com/WEPIN-Wallet)하여 별도의 비용 없이 블록체인을 추가할 수 있습니다.
{% endhint %}

### 메인넷 <a href="#mainnets" id="mainnets"></a>

#### EVM 호환 네트워크 <a href="#evm-compatible-networks" id="evm-compatible-networks"></a>

| Network          | 위젯 토큰 | 위젯 NFT | 프로바이더 | RESTful API |
| ---------------- | :---: | :----: | :---: | :---------: |
| Ethereum         |   O   |    O   |   O   |      O      |
| Kaia             |   O   |    O   |   O   |      O      |
| BSC              |   O   |    O   |   O   |      O      |
| Polygon          |   O   |    O   |   O   |      O      |
| xDAI             |   O   |    X   |   X   |      O      |
| Avalanche        |   O   |    O   |   O   |      O      |
| Arbitrum         |   O   |    X   |   X   |      O      |
| Boba             |   O   |    X   |   X   |      O      |
| Celo             |   O   |    X   |   X   |      O      |
| Metadium         |   O   |    X   |   X   |      O      |
| KuCoin           |   O   |    X   |   X   |      O      |
| Songbird         |   O   |    O   |   O   |      O      |
| Flare            |   O   |    X   |   X   |      O      |
| OEC              |   O   |    X   |   X   |      O      |
| Harmony          |   O   |    X   |   X   |      O      |
| Cronos           |   O   |    X   |   X   |      O      |
| Huobi            |   O   |    O   |   X   |      O      |
| Palm             |   O   |    O   |   X   |      O      |
| Oasys            |   O   |    X   |   O   |      O      |
| Kroma            |   O   |    X   |   X   |      O      |
| XPLA             |   O   |    X   |   O   |      O      |
| XPLA Verse       |   O   |    X   |   O   |      O      |
| opBNB            |   O   |    X   |   O   |      O      |
| Japan Open Chain |   O   |    X   |   X   |      O      |

#### Non-EVM 네트워크 <a href="#non-evm-networks" id="non-evm-networks"></a>

| Network       | 위젯 토큰 | 위젯 NFT | 프로바이더 | RESTful API |
| ------------- | :---: | :----: | :---: | :---------: |
| Near Protocol |   O   |    O   |   X   |      O      |
| Solana        |   O   |    O   |   O   |      O      |

### 테스트넷 <a href="#testnets" id="testnets"></a>

#### EVM 호환 네트워크 <a href="#evm-compatible-networks" id="evm-compatible-networks"></a>

<table><thead><tr><th width="223">Network</th><th align="center">위젯 토큰</th><th align="center">위젯 NFT</th><th align="center">프로바이더</th><th align="center">RESTful API</th></tr></thead><tbody><tr><td>Ethereum Goerli</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td>Ethereum Sepolia</td><td align="center">O</td><td align="center">X</td><td align="center">O</td><td align="center">O</td></tr><tr><td>Kaia Kairos</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td>Polygon Amoy</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td>Kroma Sepolia</td><td align="center">O</td><td align="center">X</td><td align="center">X</td><td align="center">O</td></tr><tr><td>TimeNetwork Testnet</td><td align="center">O</td><td align="center">X</td><td align="center">O</td><td align="center">O</td></tr><tr><td>Oasys Testnet</td><td align="center">O</td><td align="center">X</td><td align="center">O</td><td align="center">O</td></tr><tr><td>XPLA Testnet</td><td align="center">O</td><td align="center">X</td><td align="center">O</td><td align="center">O</td></tr><tr><td>XPLA Verse Testnet</td><td align="center">O</td><td align="center">X</td><td align="center">O</td><td align="center">O</td></tr><tr><td>BSC Testnet</td><td align="center">O</td><td align="center">X</td><td align="center">O</td><td align="center">O</td></tr><tr><td>opBNB Testnet</td><td align="center">O</td><td align="center">X</td><td align="center">O</td><td align="center">O</td></tr><tr><td>Open Campus Testnet</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td>Japan Open Chain Testnet</td><td align="center">O</td><td align="center">X</td><td align="center">X</td><td align="center">O</td></tr></tbody></table>

#### Non-EVM 네트워크 <a href="#non-evm-networks" id="non-evm-networks"></a>

<table><thead><tr><th width="223">Network</th><th align="center">위젯 토큰</th><th align="center">위젯 NFT</th><th align="center">프로바이더</th><th align="center">RESTful API</th></tr></thead><tbody><tr><td>Solana Devnet</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr></tbody></table>


# 계정 추상화

계정 추상화(Account Abstraction)는 사용자에게 EOA(Externally Owned Account)가 아닌 스마트 계정(Smart Cccount) 생성을 통해 사용자에게 획기적인 UX를 제공할 수 있는 이더리움 업데이트입니다. 위핀에서는 [계정 추상화 표준인 ERC-4337](https://eips.ethereum.org/EIPS/eip-4337)을 연동하여 지갑 사용자에게 가스 수수료를 후원하고 관리할 수 있는 기능을 제공합니다. 위핀을 연동하여 계정 추상화를 도입하길 원하신다면, [양식을 통해 신청](https://wepinwallet.typeform.com/WEPIN-Wallet)해주세요.&#x20;

### 온보딩의 다음 단계 <a href="#beyond-onboarding" id="beyond-onboarding"></a>

소셜 로그인 기반으로 지갑을 생성하는 위핀 지갑을 통해 사용자는 어플리케이션에 쉽게 온보딩 할 수 있습니다. 이는 과거에 복잡한 니모닉이나 키 관리와 같은 문제로 인해 사용자의 대부분이 이탈하던 환경에서, web3에 익숙하지 않은 사용자도 쉽게 진입할 수 있는 새로운 가능성을 열어줍니다. 하지만 최종 목표는 온보딩이 아니라, 사용자가 진정한 web3 어플리케이션의 가치를 알게 되는 것입니다.

사용자는 web3 여정 가운데 블록체인 거래 (e.g. 토큰 전송)를 마주하게 됩니다. 블록체인 환경에서는 거래를 위해서 네이티브 토큰을 필요로 하지만, web3에 익숙하지 않은 사용자가 거래를 위해 네이티브 토큰을 획득하는 것은 새로운 진입 장벽입니다. 예를 들어, 사용자는 어플리케이션으로부터 획득한 NFT를 단순히 전송하거나 토큰을 교환하길 원할 때, 중앙화된 거래소에서 KYC를 거치고 코인을 구매한 후 이용 중인 앱의 지갑 계정으로 네이티브 토큰을 전송해야 합니다. 이러한 복잡한 과정과 비용, 전송 중의 리스크를 고려한다면 원활한 온보딩 이후에도 거래 환경으로 인해 여전히 사용자 경험이 좋지 못한 것을 알 수 있습니다.

### 계정 추상화를 통한 가스비 후원 <a href="#gas-fee-sponsorship" id="gas-fee-sponsorship"></a>

계정 추상화는 지갑 사용자에게 스마트 컨트랙트로 구성된 스마트 계정을 생성하여 향상된 UX를 제공할 수 있습니다.

[이더리움의 2가지 유형의 계정](https://ethereum.org/en/developers/docs/accounts/#types-of-account) 중, 위핀을 포함한 많은 지갑은 사용자의 서명을 필요로 하는 EOA로 구현되어 있습니다. 반면에 스마트 계정이란, 스마트 컨트랙트로 구성된 지갑 계정을 의미하며, 프로그래밍 가능한 코드로 제어됩니다. 자산을 보유하고 있는 스마트 계정은 서명자로 등록된 사용자만이 제어할 수 있습니다. 위핀 지갑에서 생성된 EOA는 스마트 계정의 서명자로 활용되도록 연결하고, 사용자에게는 새로운 스마트 계정을 생성합니다.

스마트 계정을 생성한 사용자는 직접 가스 수수료를 보유하고 있지 않아도, 번들러라고 불리는 제 3자를 통해 온체인 거래가 가능합니다. 번들러가 사용자의 거래를 블록체인에 전송하면서 수수료를 지불하고, 이후 수수료에 사용된 금액을 페이백 하기 위해 페이마스터를 사용합니다. 어플리케이션 개발자는 페이마스터를 통해 번들러가 수수료를 페이백 할 수 있도록 설정해둘 수 있습니다. 이를 통해 최종 사용자는 가스 피 수수료 없이 어플리케이션으로부터 수수료를 후원 받을 수 있게 됩니다.

### 위핀으로 계정 추상화 도입하기 <a href="#implementing-account-abstraction" id="implementing-account-abstraction"></a>

위핀을 통해 계정 추상화를 도입할 경우 다음과 같은 이점을 얻을 수 있습니다.

* 사용자가 네이티브 토큰 없이도 거래가 가능하여 원활하게 어플리케이션을 이용할 수 있습니다.
* 어플리케이션 개발자는 페이마스터를 통해 수수료 후원을 관리할 수 있습니다.
* 복잡한 통합 과정 없이 위핀 지갑을 통합 후 간단한 설정으로 후원 정책(예. 최초 5회 수수료 지원)을 설정할 수 있습니다.

이외에도 계정 추상화를 도입하게 될 경우 미래에 더 많은 사용자 경험의 혁신을 가져다줄 기능들이 제공될 예정입니다.&#x20;


# 개요

위핀 로그인 시스템은 사용자 인증과 세션 관리를 위해 세 가지 주요 토큰(OAuth Token, Firebase Token, 그리고 Wepin Session Token)을 사용합니다.각 토큰은 순차적으로 발급되며, 사용자는 이러한 과정을 통해 위핀 지갑 서비스에 안전하게 접근할 수 있습니다.

### 위핀에서 사용되는 토큰 유형 <a href="#types-of-tokens" id="types-of-tokens"></a>

#### OAuth Token

OAuth Token은 Google, Apple, Naver, Discord와 같은 외부 소셜 로그인 인증 프로바이더(OAuth Provider)로부터 발급됩니다. 이 토큰은 두 가지 형태로 제공되며, ID Token과 Access Token이 이에 해당합니다. ID Token은 사용자의 신원을 확인하는 데 사용되며, Access Token은 특정 리소스에 대한 접근 권한을 부여합니다.

{% hint style="info" %}
토큰 만료 시간은 OAuth Provider에 따라 다를 수 있으며, 만료 시 새로운 토큰을 발급 받아야 합니다.
{% endhint %}

#### Firebase Token

Firebase Token은 OAuth Token을 통해 FIrebase에서 발급하는 토큰으로 위핀의 사용자 인증 및 세션 관리에 사용됩니다. Firebase Token에는 ID Token과 Refresh Token이 포함되며, 이를 통해 사용자는 위핀 지갑 서비스에 접근할 수 있습니다.

{% hint style="info" %}
Fireabse Token의 ID Token은 발급 1시간 후 만료됩니다. Refresh Token은 만료 기간이 따로 없지만, 사용되지 않을 경우 만료될 수 있습니다.
{% endhint %}

#### Wepin Session Token

Wepin Session Token은 최종적으로 위핀 서버에서 발급되며, 위핀 지갑 서비스와의 세션을 유지하기 위해 사용됩니다. 이 토큰은 Access Token과 Refresh Token으로 구성되며, 사용자의 로그인 세션을 유지하는 데 중요한 역할을 합니다.

{% hint style="info" %}
Access Token은 발급 후 12시간 후 만료됩니다. Refresh Token은 7일 동안 유효하며, 이를 통해 새로운 Access Token을 발급 받을 수 있습니다.
{% endhint %}

### 위핀 로그인 프로세스 <a href="#wepin-login-process" id="wepin-login-process"></a>

앱과 연동된 지갑의 로그인 프로세스를 구현할 때 다음과 같은 흐름으로 구성할 수 있습니다. 아래 순서는 로그인 일원화가 적용된 예시입니다.

1. 사용자가 앱에서 소셜 로그인으로 로그인을 진행합니다.
2. OAuth Provider로부터 ID Token 혹은 Access Token을 발급 받습니다.
3. 발급받은 토큰으로 위핀 Firebase에 접근하여 Firebase Token을 발급 받습니다.
4. Firebase Token을 사용하여 위핀에 로그인합니다.
5. Wepin Session Token을 발급 받아 세션을 유지하고, 각종 요청에 인증을 부여하는데 사용됩니다.

위핀 로그인과 관련된 다양한 정보들을 알아보세요.&#x20;

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>소셜 로그인 인증 제공자</strong></td><td>위핀에서 지원하는 소셜 로그인에 대해 알아보세요.</td><td><a href="/pages/nCDAbhdDOBhShLyYrISb">/pages/nCDAbhdDOBhShLyYrISb</a></td></tr><tr><td><strong>사용자 인터페이스</strong></td><td>위핀 지갑을 연동 시로그인 UI를 구성하는 방식에 대해 알아보세요.</td><td><a href="/pages/80u0l612JKmfbe2ShsZo">/pages/80u0l612JKmfbe2ShsZo</a></td></tr><tr><td><strong>로그인 일원화</strong></td><td>앱과 지갑에서 동시에 로그인하여 사용자 경험을 향상시키는 방법을 알아보세요.</td><td><a href="/pages/rIRyCIBdACndmMLzcpSP">/pages/rIRyCIBdACndmMLzcpSP</a></td></tr></tbody></table>


# 소셜 로그인 인증 프로바이더

위핀에서는 소셜 로그인을 기본 로그인 방식으로 지원하고 있습니다. 아래 로그인 프로바이더를 선택하여 소셜 로그인 기반의 지갑을 연동해보세요.&#x20;

<table data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>Email/Password</strong><br></td><td><a href="/files/4BSO8DtF0YrVmf0YAuC5">/files/4BSO8DtF0YrVmf0YAuC5</a></td><td><a href="/pages/xXmUmCUtKWHLSSkAvDgj">/pages/xXmUmCUtKWHLSSkAvDgj</a></td></tr><tr><td align="center"><strong>Google</strong><br></td><td><a href="/files/guw7HCas2BEAY9FcqxIH">/files/guw7HCas2BEAY9FcqxIH</a></td><td><a href="/pages/BUgaVqzLOehsMFfdM6sP">/pages/BUgaVqzLOehsMFfdM6sP</a></td></tr><tr><td align="center"><strong>Apple</strong><br></td><td><a href="/files/qNVraYf2yoXro7lFXIV9">/files/qNVraYf2yoXro7lFXIV9</a></td><td><a href="/pages/yrYgnz4bEEoNjriUUcSE">/pages/yrYgnz4bEEoNjriUUcSE</a></td></tr><tr><td align="center"><strong>Discord</strong><br></td><td><a href="/files/54EgjsRkrPIcw3MGCBg7">/files/54EgjsRkrPIcw3MGCBg7</a></td><td><a href="/pages/l2T5knY5poHDJfznCDHl">/pages/l2T5knY5poHDJfznCDHl</a></td></tr><tr><td align="center"><strong>Naver</strong><br></td><td><a href="/files/ZAW1NNeSXPI6o5PW7bXU">/files/ZAW1NNeSXPI6o5PW7bXU</a></td><td><a href="/pages/ISuzeCVDJq44ediFetTx">/pages/ISuzeCVDJq44ediFetTx</a></td></tr><tr><td align="center"><strong>Facebook</strong></td><td><a href="/files/n4LXdsRkDW0kPJvQkqT0">/files/n4LXdsRkDW0kPJvQkqT0</a></td><td><a href="/pages/P3hq56jHdSoQfDGU69yR">/pages/P3hq56jHdSoQfDGU69yR</a></td></tr><tr><td align="center"><strong>Line</strong></td><td><a href="/files/0CKfg5ZevsjpJJ85DvZC">/files/0CKfg5ZevsjpJJ85DvZC</a></td><td><a href="/pages/hQre4xWq9pkGz7xLHBXU">/pages/hQre4xWq9pkGz7xLHBXU</a></td></tr><tr><td align="center">Kakao</td><td><a href="/files/GkpfvJJMQftfxAtAecsi">/files/GkpfvJJMQftfxAtAecsi</a></td><td><a href="/pages/mVnK7C4oBzPEozwp9QBo">/pages/mVnK7C4oBzPEozwp9QBo</a></td></tr></tbody></table>

### 지원 환경 <a href="#supported-sdk" id="supported-sdk"></a>

위핀에서 지원하는 SDK에 따라 지원 가능한 소셜 로그인 프로바이더의 차이가 있습니다. 아래 테이블에서 연동하려는 소셜 로그인 프로바이더의 개발 환경을 확인할 수 있습니다.&#x20;

<table data-full-width="false"><thead><tr><th>로그인 프로바이더</th><th align="center">WEB</th><th align="center">Android</th><th align="center">iOS</th><th align="center">Flutter</th><th align="center">React Native</th><th align="center">Compose Multipatform</th><th data-hidden align="center">로그인 일원화</th></tr></thead><tbody><tr><td>E<strong>mail</strong></td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td><strong>Google</strong></td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td><strong>Apple</strong></td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td><strong>Discord</strong></td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td><strong>Naver</strong></td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td><td align="center">O</td></tr><tr><td><strong>Facebook</strong></td><td align="center">O</td><td align="center">X</td><td align="center">X</td><td align="center">O</td><td align="center">X</td><td align="center">X</td><td align="center">O</td></tr><tr><td>LI<strong>NE</strong></td><td align="center">O</td><td align="center">X</td><td align="center">X</td><td align="center">O</td><td align="center">X</td><td align="center">X</td><td align="center">O</td></tr><tr><td><strong>Ka</strong>k<strong>ao</strong></td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">O</td></tr></tbody></table>

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}


# Email/Password

### 지원 로그인 패키지 <a href="#supported-login-packages" id="supported-login-packages"></a>

Email/Password 로그인을 위핀 로그인 라이브러리와 연결하여 사용할 수 있습니다. SDK 별 로그인 라이브러리 문서를 참고하세요.

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}

<table><thead><tr><th width="275">플랫폼</th><th>로그인 패키지</th></tr></thead><tbody><tr><td>Web</td><td><a href="/pages/hCKXE80aWsDBpGVZFqcs">@wepin/login-js</a></td></tr><tr><td>Android</td><td><a href="/pages/mdypap56isby8QNWA5PU">wepin-android-sdk-login-v1</a></td></tr><tr><td>iOS</td><td><a href="/pages/6g86Y7WfjpkZMdK0v9J9">WepinLogin</a></td></tr><tr><td>Flutter</td><td><a href="/pages/CUsZtt54jx1fetzWm2uH">wepin_flutter_login_lib</a></td></tr><tr><td>React Native</td><td><a href="/pages/9y2qWtQNg9FAYfF4E9oW">@wepin/login-rn</a></td></tr><tr><td>Compose MultiPlatform</td><td><a href="/pages/f5HPVeWllTHURfLwZsne">wepin-compose-sdk-login-v1</a></td></tr></tbody></table>


# Google

### 지원 로그인 패키지 <a href="#supported-login-packages" id="supported-login-packages"></a>

Google 로그인을 위핀 로그인 라이브러리와 연결하여 사용할 수 있습니다. SDK 별 로그인 라이브러리 문서를 참고하세요.

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}

<table><thead><tr><th width="275">플랫폼</th><th>로그인 패키지</th></tr></thead><tbody><tr><td>Web</td><td><a href="/pages/hCKXE80aWsDBpGVZFqcs">@wepin/login-js</a></td></tr><tr><td>Android</td><td><a href="/pages/mdypap56isby8QNWA5PU">wepin-android-sdk-login-v1</a></td></tr><tr><td>iOS</td><td><a href="/pages/6g86Y7WfjpkZMdK0v9J9">WepinLogin</a></td></tr><tr><td>Flutter</td><td><a href="/pages/CUsZtt54jx1fetzWm2uH">wepin_flutter_login_lib</a></td></tr><tr><td>React Native</td><td><a href="/pages/9y2qWtQNg9FAYfF4E9oW">@wepin/login-rn</a></td></tr><tr><td>Compose MultiPlatform</td><td><a href="/pages/f5HPVeWllTHURfLwZsne">wepin-compose-sdk-login-v1</a></td></tr></tbody></table>

### 로그인 프로바이더 등록하기 <a href="#registering-login-providers" id="registering-login-providers"></a>

{% hint style="info" %}
모바일 앱에서 소셜 로그인을 수행하기 위해서는 워크스페이스에서 로그인 프로바이더를 등록해야 합니다. 웹 환경에서 소셜 로그인을 구축하거나 로그인 일원화를 사용할 경우에는 워크스페이스 등록 없이도 사용이 가능합니다.
{% endhint %}

1. [위핀 워크스페이스](https://workspace.wepin.io/)의 개발 도구 메뉴에서 로그인 탭으로 이동합니다.&#x20;
2. 로그인 탭에서 "로그인 프로바이더 설정" 버튼을 클릭합니다.&#x20;

<figure><img src="/files/4M3WsK6W1TSLlRKwbgLP" alt=""><figcaption></figcaption></figure>

3. [Google Console](https://console.cloud.google.com/apis/dashboard)에서 정보를 확인한 후, Web Client ID와 Client Secret 값을 워크스페이스에 입력합니다.&#x20;

<figure><img src="/files/P46wufcUnxxnR1Od7HpV" alt=""><figcaption></figcaption></figure>

4. 필수 입력 정보를 모두 입력 후 Redirect URL이 생성되면, [Google APIs](https://developers.google.com/identity/protocols/oauth2/web-server#creatingcred)를 참고하여 Redirect URL을 OAuth Provider에 등록합니다.


# Apple

### 지원 로그인 패키지 <a href="#supported-login-packages" id="supported-login-packages"></a>

Apple 로그인을 위핀 로그인 라이브러리와 연결하여 사용할 수 있습니다. SDK 별 로그인 라이브러리 문서를 참고하세요.

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}

<table><thead><tr><th width="275">플랫폼</th><th>로그인 패키지</th></tr></thead><tbody><tr><td>Web</td><td><a href="/pages/hCKXE80aWsDBpGVZFqcs">@wepin/login-js</a></td></tr><tr><td>Android</td><td><a href="/pages/mdypap56isby8QNWA5PU">wepin-android-sdk-login-v1</a></td></tr><tr><td>iOS</td><td><a href="/pages/6g86Y7WfjpkZMdK0v9J9">WepinLogin</a></td></tr><tr><td>Flutter</td><td><a href="/pages/CUsZtt54jx1fetzWm2uH">wepin_flutter_login_lib</a></td></tr><tr><td>React Native</td><td><a href="/pages/9y2qWtQNg9FAYfF4E9oW">@wepin/login-rn</a></td></tr><tr><td>Compose MultiPlatform</td><td><a href="/pages/f5HPVeWllTHURfLwZsne">wepin-compose-sdk-login-v1</a></td></tr></tbody></table>

### 로그인 프로바이더 등록하기 <a href="#registering-login-providers" id="registering-login-providers"></a>

{% hint style="info" %}
모바일 앱에서 소셜 로그인을 수행하기 위해서는 워크스페이스에서 로그인 프로바이더를 등록해야 합니다. 웹 환경에서 소셜 로그인을 구축하거나 로그인 일원화를 사용할 경우에는 워크스페이스 등록 없이도 사용이 가능합니다.
{% endhint %}

1. [위핀 워크스페이스](https://workspace.wepin.io/)의 개발 도구 메뉴에서 로그인 탭으로 이동합니다.
2. 로그인 탭에서 “로그인 프로바이더 설정” 버튼을 클릭합니다.

<figure><img src="/files/4M3WsK6W1TSLlRKwbgLP" alt=""><figcaption></figcaption></figure>

3. [Apple Developer](https://developer.apple.com/account)에서 정보를 확인한 후, Service ID와 Team ID, Key ID 및 Private Key 값을 워크스페이스에 입력합니다.

<figure><img src="/files/oe3C2WXbqfVa51G4COPE" alt=""><figcaption></figcaption></figure>

4. 필수 입력 정보를 모두 입력 후, Redirect URL이 생성되면 [Apple APIs](https://developer.apple.com/help/account/configure-app-capabilities/configure-sign-in-with-apple-for-the-web)를 참고하여 Redirect URL을 OAuth Provider에 등록합니다.


# Discord

### 지원 로그인 패키지 <a href="#supported-login-packages" id="supported-login-packages"></a>

Discord 로그인을 위핀 로그인 라이브러리와 연결하여 사용할 수 있습니다. SDK 별 로그인 라이브러리 문서를 참고하세요.

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}

<table><thead><tr><th width="275">플랫폼</th><th>로그인 패키지</th></tr></thead><tbody><tr><td>Web</td><td><a href="/pages/hCKXE80aWsDBpGVZFqcs">@wepin/login-js</a></td></tr><tr><td>Android</td><td><a href="/pages/mdypap56isby8QNWA5PU">wepin-android-sdk-login-v1</a></td></tr><tr><td>iOS</td><td><a href="/pages/6g86Y7WfjpkZMdK0v9J9">WepinLogin</a></td></tr><tr><td>Flutter</td><td><a href="/pages/CUsZtt54jx1fetzWm2uH">wepin_flutter_login_lib</a></td></tr><tr><td>React Native</td><td><a href="/pages/9y2qWtQNg9FAYfF4E9oW">@wepin/login-rn</a></td></tr><tr><td>Compose MultiPlatform</td><td><a href="/pages/f5HPVeWllTHURfLwZsne">wepin-compose-sdk-login-v1</a></td></tr></tbody></table>

### 로그인 프로바이더 등록하기 <a href="#registering-login-providers" id="registering-login-providers"></a>

{% hint style="info" %}
모바일 앱에서 소셜 로그인을 수행하기 위해서는 워크스페이스에서 로그인 프로바이더를 등록해야 합니다. 웹 환경에서 소셜 로그인을 구축하거나 로그인 일원화를 사용할 경우에는 워크스페이스 등록 없이도 사용이 가능합니다.
{% endhint %}

1. [위핀 워크스페이스](https://workspace.wepin.io/)의 개발 도구 메뉴에서 로그인 탭으로 이동합니다.
2. 로그인 탭에서 “로그인 프로바이더 설정” 버튼을 클릭합니다.

<figure><img src="/files/4M3WsK6W1TSLlRKwbgLP" alt=""><figcaption></figcaption></figure>

3. [Discord Developer](https://discord.com/developers/applications)에서 정보를 확인한 후, Client ID 값을 워크스페이스에 입력합니다.

<figure><img src="/files/g99xz9IPmM6T9I8usiiR" alt=""><figcaption></figcaption></figure>

4. 필수 입력 정보를 모두 입력 후, Redirect URL이 생성되면 [Discord APIs](https://discord.com/developers/docs/activities/building-an-activity#you-must-set-up-a-oauth2-redirect-uri-in-order-for-this-example-to-work)를 참고하여 Redirect URL을 OAuth Provider에 등록합니다.


# Naver

### 지원 로그인 패키지 <a href="#supported-login-packages" id="supported-login-packages"></a>

Naver 로그인을 위핀 로그인 라이브러리와 연결하여 사용할 수 있습니다. SDK 별 로그인 라이브러리 문서를 참고하세요.

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}

<table><thead><tr><th width="275">플랫폼</th><th>로그인 패키지</th></tr></thead><tbody><tr><td>Web</td><td><a href="/pages/hCKXE80aWsDBpGVZFqcs">@wepin/login-js</a></td></tr><tr><td>Android</td><td><a href="/pages/mdypap56isby8QNWA5PU">wepin-android-sdk-login-v1</a></td></tr><tr><td>iOS</td><td><a href="/pages/6g86Y7WfjpkZMdK0v9J9">WepinLogin</a></td></tr><tr><td>Flutter</td><td><a href="/pages/CUsZtt54jx1fetzWm2uH">wepin_flutter_login_lib</a></td></tr><tr><td>React Native</td><td><a href="/pages/9y2qWtQNg9FAYfF4E9oW">@wepin/login-rn</a></td></tr><tr><td>Compose MultiPlatform</td><td><a href="/pages/f5HPVeWllTHURfLwZsne">wepin-compose-sdk-login-v1</a></td></tr></tbody></table>

### 로그인 프로바이더 등록하기 <a href="#registering-login-providers" id="registering-login-providers"></a>

{% hint style="info" %}
모바일 앱에서 소셜 로그인을 수행하기 위해서는 워크스페이스에서 로그인 프로바이더를 등록해야 합니다. 웹 환경에서 소셜 로그인을 구축하거나 로그인 일원화를 사용할 경우에는 워크스페이스 등록 없이도 사용이 가능합니다.
{% endhint %}

1. [위핀 워크스페이스](https://workspace.wepin.io/)의 개발 도구 메뉴에서 로그인 탭으로 이동합니다.
2. 로그인 탭에서 “로그인 프로바이더 설정” 버튼을 클릭합니다.

<figure><img src="/files/4M3WsK6W1TSLlRKwbgLP" alt=""><figcaption></figcaption></figure>

3. [Naver Developers](https://developers.naver.com/apps/#/register)에서 Console URL 정보를 확인한 후, Client ID, Client Secret 값을 워크스페이스에 입력합니다.

<figure><img src="/files/TxuIT1PHKEF7D8x0MWni" alt=""><figcaption></figcaption></figure>

4. 필수 입력 정보를 모두 입력 후, Redirect URL이 생성되면 [Naver APIs](https://developers.naver.com/docs/common/openapiguide/appregister.md)를 참고하여 Redirect URL을 OAuth Provider에 등록합니다.


# Facebook

### 지원 로그인 패키지 <a href="#supported-login-packages" id="supported-login-packages"></a>

Facebook 로그인을 위핀 로그인 라이브러리와 연결하여 사용할 수 있습니다. SDK 별 로그인 라이브러리 문서를 참고하세요.

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}

<table><thead><tr><th width="275">플랫폼</th><th>로그인 패키지</th></tr></thead><tbody><tr><td>Web</td><td><a href="/pages/hCKXE80aWsDBpGVZFqcs">@wepin/login-js</a></td></tr><tr><td>Flutter</td><td><a href="/pages/CUsZtt54jx1fetzWm2uH">wepin_flutter_login_lib</a></td></tr></tbody></table>

### 로그인 프로바이더 등록하기 <a href="#registering-login-providers" id="registering-login-providers"></a>

{% hint style="info" %}
모바일 앱에서 소셜 로그인을 수행하기 위해서는 워크스페이스에서 로그인 프로바이더를 등록해야 합니다. 웹 환경에서 소셜 로그인을 구축하거나 로그인 일원화를 사용할 경우에는 워크스페이스 등록 없이도 사용이 가능합니다.
{% endhint %}

1. [위핀 워크스페이스](https://workspace.wepin.io/)의 개발 도구 메뉴에서 로그인 탭으로 이동합니다.
2. 로그인 탭에서 “로그인 프로바이더 설정” 버튼을 클릭합니다.

<figure><img src="/files/4M3WsK6W1TSLlRKwbgLP" alt=""><figcaption></figcaption></figure>

3. [Meta Developer](https://developers.facebook.com/apps)에서 정보를 확인한 후, App ID와 App Secret Code 값을 워크스페이스에 입력합니다.

<figure><img src="/files/dV7xb17Y7fiCE8NkcCdm" alt=""><figcaption></figcaption></figure>

4. 필수 입력 정보를 모두 입력 후, Redirect URL이 생성되면 [Facebook APIs](https://developers.facebook.com/docs/development/create-an-app/facebook-login-use-case)를 참고하여 Redirect URL을 OAuth Provider에 등록합니다.


# Line

### 지원 로그인 패키지 <a href="#supported-login-packages" id="supported-login-packages"></a>

Facebook 로그인을 위핀 로그인 라이브러리와 연결하여 사용할 수 있습니다. SDK 별 로그인 라이브러리 문서를 참고하세요.

{% hint style="info" %}
위핀과 연동 가능한 모든 소셜 로그인 인증 프로바이더는 로그인 일원화를 지원합니다. 로그인 일원화를 통해 통합하려는 경우 [로그인 일원화 페이지](/login/simplified-login)를 참고하세요.
{% endhint %}

<table><thead><tr><th width="275">플랫폼</th><th>로그인 패키지</th></tr></thead><tbody><tr><td>Web</td><td><a href="/pages/hCKXE80aWsDBpGVZFqcs">@wepin/login-js</a></td></tr><tr><td>Flutter</td><td><a href="/pages/CUsZtt54jx1fetzWm2uH">wepin_flutter_login_lib</a></td></tr></tbody></table>

### 로그인 프로바이더 등록하기 <a href="#registering-login-providers" id="registering-login-providers"></a>

{% hint style="info" %}
모바일 앱에서 소셜 로그인을 수행하기 위해서는 워크스페이스에서 로그인 프로바이더를 등록해야 합니다. 웹 환경에서 소셜 로그인을 구축하거나 로그인 일원화를 사용할 경우에는 워크스페이스 등록 없이도 사용이 가능합니다.
{% endhint %}

1. [위핀 워크스페이스](https://workspace.wepin.io/)의 개발 도구 메뉴에서 로그인 탭으로 이동합니다.
2. 로그인 탭에서 “로그인 프로바이더 설정” 버튼을 클릭합니다.

<figure><img src="/files/4M3WsK6W1TSLlRKwbgLP" alt=""><figcaption></figcaption></figure>

3. [Line Developer](https://developers.line.biz/console)에서 정보를 확인한 후, Channel ID와 Channel secret 값을 워크스페이스에 입력합니다.

<figure><img src="/files/ct2pd7hrKMcQFScw10Yl" alt=""><figcaption></figcaption></figure>

4. 필수 입력 정보를 모두 입력 후, Redirect URL이 생성되면 [Line APIs](https://developers.line.biz/en/docs/line-login/integrate-line-login/#setting-callback-url)를 참고하여 Redirect URL을 OAuth Provider에 등록합니다.


# Kakao

Kakao 로그인은 현재 로그인 일원화 방식을 통해서만 지원됩니다. [로그인 일원화 페이지](/login/simplified-login)에서 KaKao 로그인을 활용한 연동 방법에 대해서 확인할 수 있습니다.


# 사용자 인터페이스

위핀은 다양한 로그인 UI 옵션을 통해 개발자들이 사용자의 필요에 맞게 로그인 경험을 맞춤화할 수 있도록 지원합니다. 로그인 UI 기능은 크게 세 가지 접근 방식으로 나뉘며, 이들 방식에 따라 사용자는 위핀의 기본 제공 UI를 사용하거나, 커스텀 UI를 직접 제작할 수 있습니다.

### 위젯 기본 로그인 UI 사용 <a href="#using-the-default-widget-login-ui" id="using-the-default-widget-login-ui"></a>

위핀 위젯은 기본적인 로그인 UI를 제공하여, OAuth Provider를 통해 쉽게 소셜 로그인을 구현할 수 있도록 지원합니다. 이 UI는 별도의 커스텀 작업 없이 바로 사용할 수 있으며, Google, Apple, Naver, Discord 등의 주요 소셜 로그인을 적용할 수 있습니다.

* 위젯 SDK를 설치하고 초기화한 후, `loginWithUI` 메서드를 호출하여 사용자에게 로그인 UI를 표시합니다.

### 커스텀 로그인 UI 구현 <a href="#implementing-a-custom-login-ui" id="implementing-a-custom-login-ui"></a>

위핀의 기본 제공 UI 대신, 직접 커스텀 UI를 디자인하여 구현할 수 있습니다. 이를 통해 앱의 고유한 디자인을 유지하고, 사용자 맞춤형 경험을 제공할 수 있습니다. 이 방식의 경우, 커스텀 UI와 위핀의 로그인 기능을 통합하여, 앱의 고유한 사용자 흐름과 인터페이스에 맞게 로그인 과정을 구현해야 합니다.

#### 이메일/패스워드 로그인 <a href="#email-password-login" id="email-password-login"></a>

* `loginWithEmailAndPassword` 메서드를 사용하여 이메일로 로그인한 후 Firebase에 인증 정보를 전달하고, 인증을 완료합니다.
* 이후 `loginWepin` 메서드를 사용하여 Firebase Token을 통해 위핀에 로그인합니다.

#### OAuth Provider 로그인 <a href="#oauth-provider-login" id="oauth-provider-login"></a>

* (Web SDK 사용 시) `loginWithOauthProvider` 메서드를 사용하여 OAuth Provider로 로그인한 후 Firebase에 인증 정보를 전달하고, 인증을 완료합니다.
* (Web 외 SDK 사용 시)`loginWithOauthProvider` 메서드를 사용하여 OAuth Provider로 로그인한 후, OAuth Token(Access Token 또는 ID Token)을 발급받습니다.
* 이후 `loginWithIdToken` 또는 `loginWithAccessToken` 메서드를 사용하여 해당 OAuth Token을 Firebase에 전달하고, 인증을 완료합니다.
* 이후 `loginWepin` 메서드를 사용하여 Firebase Token을 통해 위핀에 로그인합니다.

### 로그인 일원화 UI 사용 <a href="#using-simplified-login-ui" id="using-simplified-login-ui"></a>

로그인 일원화 기능을 통해, 앱의 회원가입과 지갑 로그인을 단일 프로세스로 처리할 수 있습니다. 이 방식은 사용자 경험을 단순화하고, 한 번의 로그인으로 앱과 지갑 모두에 접근할 수 있게 합니다.

* 로그인 라이브러이의 `loginWithIdToken`, `loginWithAccessToken` 메서드를 사용하여 OAuth 및 Firebase 토큰을 처리하며, 로그인 일원화를 구현할 수 있습니다.

보다 상세한 내용은 로그인 일원화 페이지를 통해 살펴보세요.

{% content-ref url="/pages/rIRyCIBdACndmMLzcpSP" %}
[로그인 일원화](/login/simplified-login)
{% endcontent-ref %}


# 로그인 일원화

앱 서비스에 위핀을 통합할 때 사용자 경험을 향상시키기 위해 로그인 일원화를 구현할 수 있습니다. 로그인 일원화는 사용자가 한 번의 로그인으로 앱과 위핀 지갑 모두에 로그인할 수 있게 하는 방식입니다. 이 접근 방식은 UX를 개선하며, 두 번의 로그인 과정을 단순화하여 사용자 이탈을 줄여줍니다.

위핀은 ID Token과 Access Token을 통한 두 가지 로그인 방식을 지원합니다. 각각의 방식에 따라 사용할 수 있는 소셜 로그인 프로바이더가 다르며, 소셜 로그인 인증 프로바이더에 따라 사용되는 토큰 방식은 아래와 같습니다.&#x20;

<table><thead><tr><th width="252">토큰 분류</th><th>소셜 로그인 인증 프로바이더</th></tr></thead><tbody><tr><td>ID Token</td><td>Google, Apple, Line, Kakao</td></tr><tr><td>Access Token</td><td>Discord, Naver, Facebook</td></tr></tbody></table>

### ID Token 로그인 기능 설정 <a href="#setting-up-id-token-login" id="setting-up-id-token-login"></a>

ID Token은 사용자에 대한 인증 정보를 포함하는 토큰으로, 주로 OIDC(OpenID Connect) 표준을 따르는 OAuth Provider에서 발급됩니다. 위핀에서는 OIDC 기반의 로그인 프로바이더에서 발급된 ID Token을 사용하여 로그인 일원화를 구현할 수 있습니다.

* `loginWithIdToken` 메서드를 사용하여 OAuth Provider로부터 발급받은 ID Token을 Firebase에 전달하고, 인증을 완료합니다.
* 이후 `loginWepin` 메서드를 사용하여 Firebase Token을 통해 위핀에 로그인합니다.

### Access Token 로그인 기능 설정 <a href="#setting-up-access-token-login" id="setting-up-access-token-login"></a>

Access Token은 사용자의 인증, 접근 및 수정 권한을 제공하는 토큰으로, 대부분의 OAuth Provider에서 사용됩니다. 위핀에서는 OAuth Provider의 Access Token을 이용해 로그인 일원화를 구현할 수 있습니다.

* `loginWithAccessToken` 메서드를 사용하여 OAuth Provider로부터 발급받은 Access Token을 Firebase에 전달하고, 인증을 완료합니다.
* 이후 `loginWepin` 메서드를 사용하여 Firebase Token을 통해 위핀에 로그인합니다.

SDK에 따라 로그인 관련 메서드에 대한 안내는 리소스 페이지에서 확인할 수 있습니다.

{% content-ref url="/pages/IGQkBuEvZH0XviufYrqy" %}
[리소스](/login/resource)
{% endcontent-ref %}


# 리소스

SDK 별로 로그인 관련 메서드를 아래 테이블에서 확인할 수 있습니다.

<table><thead><tr><th width="253">SDK</th><th>메서드</th><th data-hidden>로그인 변수</th></tr></thead><tbody><tr><td>WEB</td><td><p><a href="/pages/P5ATOSOEetbbN9gkwRFN#loginwithoauthprovider">loginWithOauthProvider</a> </p><p><a href="/pages/P5ATOSOEetbbN9gkwRFN#loginwithemailandpassword">loginWithEmailAndPassWord</a></p><p><a href="/pages/P5ATOSOEetbbN9gkwRFN#loginwithidtoken">loginWithIdToken</a> / <a href="/pages/P5ATOSOEetbbN9gkwRFN#loginwithaccesstoken">loginWithAccessToken</a><br><a href="/pages/P5ATOSOEetbbN9gkwRFN#loginwepin">loginWepin</a></p></td><td>login (0.0.6-alpha 버전 이상 지원)</td></tr><tr><td>Android</td><td><p><a href="/pages/Z4cXyrEwplM0AjRpnO3p#loginwithoauthprovider">loginWithOauthProvider</a></p><p><a href="/pages/Z4cXyrEwplM0AjRpnO3p#loginwithemailandpassword">loginWithEmailAndPassWord</a></p><p><a href="/pages/Z4cXyrEwplM0AjRpnO3p#loginwithidtoken">loginWithIdToken</a> / <a href="/pages/Z4cXyrEwplM0AjRpnO3p#loginwithaccesstoken">loginWithAccessToken</a></p><p><a href="/pages/Z4cXyrEwplM0AjRpnO3p#loginwepin">loginWepin</a></p></td><td></td></tr><tr><td>iOS</td><td><p><a href="/pages/TpUZqGGgJgWsxDGaEZ72#loginwithoauthprovider">loginWithOauthProvider</a></p><p><a href="/pages/TpUZqGGgJgWsxDGaEZ72#loginwithemailandpassword">loginWithEmailAndPassWord</a></p><p><a href="/pages/TpUZqGGgJgWsxDGaEZ72#loginwithidtoken">loginWithIdToken</a> / <a href="/pages/TpUZqGGgJgWsxDGaEZ72#loginwithaccesstoken">loginWithAccessToken</a></p><p><a href="/pages/TpUZqGGgJgWsxDGaEZ72#loginwepin">loginWepin</a></p></td><td></td></tr><tr><td>Flutter</td><td><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginwithoauthprovider">loginWithOauthProvider</a></p><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginwithemailandpassword">loginWithEmailAndPassWord</a></p><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginwithidtoken">loginWithIdToken</a> / <a href="/pages/RFcrG1tIFFs50B4hOiis#loginwithaccesstoken">loginWithAccessToken</a></p><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginwepin">loginWepin</a></p><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginfirebasewithoauthprovider">loginFirebaseWithOauthProvider</a></p><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginwepinwithoauthprovider">loginWepinWithOauthProvider</a></p><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginwepinwithidtoken">loginWepinWithIdToken</a></p><p><a href="/pages/RFcrG1tIFFs50B4hOiis#loginwepinwithaccesstoken">loginWepinWithAccessToken</a></p></td><td></td></tr><tr><td>React Native</td><td><a href="/pages/scY37fZR0DFMdgd6XOb2#loginwithexternaltoken-0.0.19-alpha">loginWithExternalToken </a>(0.0.19-alpha 버전 이상 지원)<br><a href="/pages/scY37fZR0DFMdgd6XOb2#loginwithemailandpassword-0.0.9-alpha">loginWithEmailAndPassword</a> (0.0.9-alpha 버전 이상 지원)</td><td>login</td></tr><tr><td>Compose Multiplatform</td><td><p><a href="/pages/1dERB2Lu1lyXSHHCvwGz#loginwithoauthprovider">loginWithOauthProvider</a></p><p><a href="/pages/1dERB2Lu1lyXSHHCvwGz#loginwithemailandpassword">loginWithEmailAndPassWord</a></p><p><a href="/pages/1dERB2Lu1lyXSHHCvwGz#loginwithidtoken">loginWithIdToken</a> / <a href="/pages/1dERB2Lu1lyXSHHCvwGz#loginwithaccesstoken">loginWithAccessToken</a></p><p><a href="/pages/1dERB2Lu1lyXSHHCvwGz#loginwepin">loginWepin</a></p></td><td></td></tr></tbody></table>


# 사전 준비

위핀 SDK를 활용하여 위젯 연동을 시작하기 전에, App ID와 App Key 정보가 필요합니다. 아래 앱 등록 및 키 발급 페이지를 참고하여, 워크스페이스에서 App ID와 App Key를 발급 받은 후 위젯 연동을 시작하세요.

{% content-ref url="/pages/cfg4nwJBI8VfiJpH4EW8" %}
[앱 등록 및 키 발급](/wepin/workspace/app-registration-and-key-issuance)
{% endcontent-ref %}


# Web: JavaScript SDK

JavaScript SDK 브라우저 환경에서 사용할 수 있는 SDK(Software Development Kit)입니다. 이 문서는 위핀 위젯을 Javascript SDK를 이용하여 WEB에 통합하기 위한 절차를 설명합니다.

#### 패키지 리스트 <a href="#package-list" id="package-list"></a>

* [sdk](/widget-integration/web-javascript-sdk/widget): @wepin/sdk-js
  * 위핀 위젯을 사용하기 위한 기능을 제공합니다.
* [login](/widget-integration/web-javascript-sdk/login-library): @wepin/login-js
  * 소셜 로그인과 같은 OAuth 인증 토큰으로 위핀에 로그인하는 기능을 제공합니다.
* [provider](/widget-integration/web-javascript-sdk/provider): @wepin/provider-js, @wepin/wagmi-connector
  * 이더리움 및 EVM, 솔라나 등 위핀에서 지원하는 블록체인과 상호작용하기 위한 프로바이더를 제공합니다.

{% hint style="danger" %}
&#x20;Wepin 패키지는 모두 **클라이언트 사이드 렌더링(CSR: Client Side Rendering)** 환경에서만 동작합니다. 서버 사이드 렌더링(SSR: Server Side Rendering) 환경에서 이 패키지를 사용할 경우, CSR에서만 패키지를 불러올 수 있도록 설정이 필요합니다.

아래 코드를 참고하여 설정하세요:

```javascript
const initWepin = async () => {
    const { WepinSDK } = await import('@wepin/sdk-js');
    const wepinSDK = new WepinSDK({
        appKey: '',
        appId: '',
    });
    await wepinSDK.init();
}
```

{% endhint %}


# 로그인

소셜 로그인과 같은 OAuth 인증 토큰 또는 이메일로 위핀에 로그인 하는 방법에 대한 안내 페이지입니다


# 설치

## 패키지 매니저로 설치하기 <a href="#installing-with-a-package-manager" id="installing-with-a-package-manager"></a>

npm 패키지로 설치 가능합니다.&#x20;

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

```bash
npm install @wepin/login-js
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/login-js
```

{% endtab %}
{% endtabs %}

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와  같이 WepinLogin인스턴스를 초기화합니다. 이렇게 하면 WepinLogin를 사용할 수 있게 됩니다.

<pre class="language-javascript"><code class="lang-javascript"><strong>// 1. 패키지 import
</strong>import { WepinLogin } from '@wepin/login-js'
<strong>
</strong>// 2. 초기화
const wepinLogin = new WepinLogin({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-app-key',
})
</code></pre>

{% hint style="danger" %}
해당 패키지는 **클라이언트 사이드 렌더링(CSR: Client Side Rendering)** 환경에서만 동작합니다. 서버 사이드 렌더링(SSR: Server Side Rendering) 환경에서 이 패키지를 사용할 경우, CSR에서만 패키지를 불러올 수 있도록 설정이 필요합니다.

아래 코드를 참고하여 설정하세요:

```javascript
const initWepinLogin = async () => {
    const { WepinLogin } = await import('@wepin/login-js');
    const wepinLogin = new WepinLogin({
        appKey: '',
        appId: '',
    });
    await wepinLogin.init({
        defaultLanguage: 'ko',
    });
}
```

{% endhint %}


# 초기화하기

Wepin Login Library를 초기화하는 방법입니다.&#x20;

## init

Wepin Login Library 초기화 합니다. 초기화시에  위젯 화면에 보여질 언어를 설정합니다.

```javascript
await wepinLogin.init(language?)
```

### **Parameters**

* `language`: \<string>\
  위젯 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'`, `'ja'`3가지 입니다.

### **Return value**

* `Promise`\<void>

### Example

```javascript
await wepinLogin.init('ko')
```

## isInitialized

Wepin Login Library가 정상적으로 초기화 되었는지 확인할 수 있습니다.&#x20;

```javascript
wepinLogin.isInitialized()
```

### **Parameters**

* \<void>

### **Return Value**

* `<boolean>`\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### **Example**

```javascript
if(wepinLogin.isInitialized()) {
  console.log('wepinSDK is initialized!')
}
```

## changeLanguage

위젯의 언어를 변경할 수 있습니다.

```javascript
wepinLogin.changeLanguage(language)
```

### **Parameters**

* `language` \<string>\
  위젯에 표시될 언어를  지정합니다. 현재 지원하는 언어는 `'ko'`, `'en'`, `'ja'` 3가지 입니다.

### Example

```javascript
wepinLogin.changeLanguage('ko')
```


# 메서드

Wepin Login Library  초기화 이후 사용할 수 있습니다.

## loginWithOauthProvider

```javascript
await wepinLogin.loginWithOauthProvider(params)
```

새 창이 열리고 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다. `required/register_email`오류 메시지를 반환하면 `sendVerifyEmail` 메서드를 호출해야 합니다.

### **Parameters**

* `params` \<object>
  * `provider` <'google'|'naver'|'discord'|'apple'|'line'|'facebook'> - Provider for Firebase login
  * `withLogout` \<boolean> **optional**&#x20;
    * true : 이미 로그인 되어 있는 경우, 로그아웃을 하지 않음
    * false  : 이미 로그인 되어 있는 경우, 로그아웃을 하고 다시 로그인 함

### **Return value**

* `Promise` \<LoginResult | LoginErrorResult>
  * \<LoginResult>
    * `provider` <'google'|'naver'|'discord'|'apple'|'line'|'facebook'>
    * `token` \<object>
      * `idToken` \<string> \
        wepin firebase idToken
      * `refreshToken` \
        wepin firebase refreshToken
  * \<LoginErrorResult>
    * `error` \<string> \
      error message
    * `idToken` \<string> ***optional***\
      id token value
    * `accessToken` \<string> ***optional*** \
      accessToken token value
    * `provider` <'google'|'naver'|'discord'|'apple'|'line'|'facebook'> ***optional*** \
      Provider that issued the access token

### **Exception**

* `Invalid provider`:  파라미터인 프로바이더값이 잘못된 경우
* `User canceled` : 로그인 진행중에 사용자가 창을 닫은 경우
* `Internal error` : 나머지 예외 상황이 발생한 경우

### **Example**

```javascript
const user = await wepinLogin.loginWithOauthProvider(true)
```

* response
  * LoginResult

    ```json
    {
      "provider": "google",
      "token": {
          "idToken": "ab2231df....ad0f3291",
          "refreshToken": "eyJHGciO....adQssw5c",
      }
    }
    ```
  * LoginErrorResult

    ```json
    {
      "error": "required/register_email",
      "provider": "naver",
      "accessToken": "eyJHGciO....adQssw5c",
    }
    ```

## &#x20;signUpWithEmailAndPassWord

```javascript
await wepinLogin.signUpWithEmailAndPassword(email, password, openWepinWallet?)
```

이메일과 비밀번호로 Wepin Firebase에 회원가입을 합니다. 가입되지 않은 사용자의 경우 검증 이메일이 전송되며, `auth/email-verified`오류가 발생합니다. 이미 가입된 사용자의 경우, `auth/existed-email` 오류가 발생하며 [loginWithEmailAndPassword](/widget-integration/web-javascript-sdk/login-library/methods#loginwithemailandpassword)를 호출하여 로그인 프로세스를 진행합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

### **Parameters**

* `email` \<string>\
  사용자 이메일 주소
* `password` \<string>

  사용자 이메일 비밀번호
* `openWepinWallet` \<boolean> **optional** \
  Wepin Wallet의 인증 이메일 전송 페이지가 보이게 할지 여부

### **Return Value**

* `Promise`\<LoginResult>
  * `provider` <'email'>
  * `token` \<object>
    * `idToken` \<string>\
      wepin firebase idToken
    * `refreshToken` \
      wepin firebase refreshToken

### **Exception**

* `auth/email-verified`: 회원가입을 위해 인증 이메일이 발송되었으며, 이메일 인증이 필요합니다.
* `auth/existed-email` : 이미 회원가입이 되어 있는 경우
* `fail/send-email` : 인증 이메일 발송에 실패한 경우
* `fail/email-verified` : 이메일 인증에 실패한 경우

### **Example**

```javascript
const user = await wepinLogin.signUpWithEmailAndPassword('abc@defg.com', 'abcdef123&')
```

* response

<pre class="language-json"><code class="lang-json"><strong>    {
</strong>        "provider": "email",
        "token": {
            "idToken": "ab2231df....ad0f3291",
            "refreshToken": "eyJHGciO....adQssw5c",
        }
    }
</code></pre>

## loginWithEmailAndPassWord

```javascript
await wepinLogin.loginWithEmailAndPassword(email, password)
```

이메일과 비밀번호로 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

### **Parameters**

* `email` \<string>\
  사용자 이메일 주소
* `password` \<string>

  사용자 이메일 비밀번호

### **Return Value**

* `Promise`\<LoginResult>
  * `provider` <'email'>
  * `token` \<object>
    * `idToken` \<string>\
      wepin firebase idToken
    * `refreshToken` \
      wepin firebase refreshToken

### **Example**

```javascript
const user = await wepinLogin.loginWithEmailAndPassword('abc@defg.com', 'abcdef123&')
```

* response

```json
    {
        "provider": "email",
        "token": {
            "idToken": "ab2231df....ad0f3291",
            "refreshToken": "eyJHGciO....adQssw5c",
        }
    }
```

## loginWithIdToken

```javascript
await wepinLogin.loginWithIdToken(params)
```

외부 IdToken으로 Wepin Firebase에 로그인합니다. 성공적으로 로그인하면 Firebase 로그인 정보를 반환합니다. `required/register_email`오류 메세지를 반환하면 `sendVerifyEmail` 메서드를 호출해야 합니다.

### **Parameters**

* `params` \<object>

  * `token` \<string> \
    로그인에 사용될 외부 IdToken 값입니다.
  * `sign` \<string> ***optional***

    첫 번째 매개변수로 제공된 `token`의 서명 값입니다. ([Signature Generation Methods](https://github.com/WepinWallet/wepin-widget-js-sdk/blob/main/doc/SignatureGenerationMethods.md))

  <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><code>@wepin/login-js</code> 버전 <mark style="color:red;"><strong>0.0.29</strong></mark> 부터 <code>sign</code> 값은 옵셔널로 변경되었습니다.<br><br><a href="https://workspace.wepin.io/">Wepin Workspace</a>에서 인증 키를 제거하면, 서명(<strong><code>sign</code></strong>)  값을 사용하지 않을 수 있습니다.</p><p>(<a href="https://workspace.wepin.io/">Wepin Workspace</a> > Development Tools menu > Login tab > Auth Key> Delete)</p><blockquote><p><mark style="background-color:yellow;">인증 키를 이전에 생성한 경우에만 인증 키 메뉴가 표시됩니다.</mark></p></blockquote></div>

### **Return Value**

* `Promise`\<LoginResult | LoginErrorResult>
  * \<LoginResult>
    * `provider` <'external\_token'>
    * `token` \<object>
      * `idToken` \<string> \
        wepin firebase idToken
      * `refreshToken` \
        wepin firebase refreshToken
  * \<LoginErrorResult>
    * `error` \<string>\
      error message
    * `idToken` \<string> ***optional*** \
      id token value

### **Example**

```javascript
const user = await wepinLogin.loginWithIdToken({
    token:'eyJHGciO....adQssw5c', 
    sign:'9753d4dc...c63466b9'
})
```

* response
  * LoginResult

    ```json
    {
      "provider": "external_token",
      "token": {
          "idToken": "ab2231df....ad0f3291",
          "refreshToken": "eyJHGciO....adQssw5c",
      }
    }
    ```
  * LoginErrorResult

    ```json
    {
      "error": "required/register_email",
      "idToken": "eyJHGciO....adQssw5c",
    }
    ```

## loginWithAccessToken

```javascript
await wepinLogin.loginWithAccessToken(params)
```

외부 Access Token으로 Wepin Firebase에 로그인합니다. 성공적으로 로그인하면 Firebase 로그인 정보를 반환합니다. `required/register_email`오류 메세지를 반환하면 `sendVerifyEmail` 메서드를 호출해야 합니다.

### **Parameters**

* `params` \<object>

  * `provider` <'naver'|'discord'|'facebook'>\
    Access Token을 발급 받은 로그인 Provider
  * `token` \<string> \
    로그인에 사용될 외부 Access Token값입니다.
  * `sign` \<string> ***optional***

    두 번째 매개변수로 제공된 `token`의 서명 값입니다. ([Signature Generation Methods](https://github.com/WepinWallet/wepin-widget-js-sdk/blob/main/doc/SignatureGenerationMethods.md))

  <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><code>@wepin/login-js</code> 버전 <mark style="color:red;"><strong>0.0.29</strong></mark> 부터 <code>sign</code> 값은 옵셔널로 변경되었습니다.<br><a href="https://workspace.wepin.io/">Wepin Workspace</a>에서 인증 키를 제거하면, 서명(<strong><code>sign</code></strong>)  값을 사용하지 않을 수 있습니다.</p><p>(<a href="https://workspace.wepin.io/">Wepin Workspace</a> > Development Tools menu > Login tab > Auth Key> Delete)</p><blockquote><p><mark style="background-color:yellow;">인증 키를 이전에 생성한 경우에만 인증 키 메뉴가 표시됩니다.</mark></p></blockquote></div>

### **Return Value**

* `Promise`\<LoginResult | LoginErrorResult>
  * \<LoginResult>
    * `provider` <'external\_token'>
    * `token` \<object>
      * `idToken` \<string>  \
        wepin firebase idToken
      * `refreshToken` \
        &#x20;wepin firebase refreshToken
  * \<LoginErrorResult>
    * `error` \<string> \
      error message
    * `accessToken` \<string> ***optional***\
      accessToken token value
    * `provider` \<string> ***optional*** \
      Provider that issued the access token

### **Example**

```javascript
const user = await wepinLogin.loginWithAccessToken({
    provider: 'naver', 
    token:'eyJHGciO....adQssw5c', 
    sign:'9753d4dc...c63466b9'
})
```

* response
  * LoginResult

    ```json
    {
      "provider": "external_token",
      "token": {
          "idToken": "ab2231df....ad0f3291",
          "refreshToken": "eyJHGciO....adQssw5c",
      }
    }
    ```
  * LoginErrorResult

    ```json
    {
      "error": "required/register_email",
      "provider": "naver",
      "accessToken": "eyJHGciO....adQssw5c",
    }
    ```

## getSignForLogin

```javascript
import {getSignForLogin} from '@wepin/login-js'
const result = getSignForLogin(privKey, message);
```

발행자를 검증하기 위한 서명을 생성합니다. 주로 IdToken 및 Access Token과 같은 로그인 관련 정보의 서명을 생성하는 데 사용됩니다.

### **Parameters**

* `privKey` \<string> \
  서명 생성에 사용되는 인증 키입니다.
* `message` \<string> \
  서명될 메세지 또는 페이로드입니다.

### **Return Value**

* \<string>

  서명값

{% hint style="danger" %}
인증 키(privKey)는 안전하게 보관해야 하며 외부에 노출되어서는 안 됩니다. 민감한 정보의 보안과 보호를 강화하기 위해 getSignForLogin() 메서드는 프론트 엔드가 아닌 백엔드에서 실행하는것을 권장합니다.
{% endhint %}

### **Example**

```javascript
const privKey = '0400112233445566778899001122334455667788990011223344556677889900'
const idToken = 'idtokenabcdef'
const sign = getSignForLogin(privKey, idToken)

const res = await wepinLogin.loginWithIdToken({
    token: idToken, 
    sign
})
```

## getRefreshFirebaseToken

```javascript
import {getRefreshFirebaseToken} from '@wepin/login-js'
const result = getSignForLogin(privKey, message);
```

Wepin에서 현재 Firebase 토큰의 정보를 가져옵니다.

### **Parameters**

* `prevFBToken` \<LoginResult> ***optional***
  * `provider` <'google'|'naver'|'discord'|'apple'|'line'|'facebook'>
  * `token` \<object>
    * `idToken` \<string> \
      wepin firebase idToken
    * `refreshToken` \
      wepin firebase refreshToken

{% hint style="warning" %}
`@wepin/login-js` version <mark style="color:red;">**0.0.33**</mark>부터`prevFBToken` 이 parameter 에 추가되었습니다.
{% endhint %}

### **Return Value**

* `Promise` \<LoginResult>
  * \<LoginResult>
    * `provider` <'google'|'naver'|'discord'|'apple'|'line'|'facebook'>
    * `token` \<object>
      * `idToken` \<string> \
        wepin firebase idToken
      * `refreshToken` \
        wepin firebase refreshToken

### **Example**

```javascript
// Without parameter (legacy way)
const result = await wepinLogin.getRefreshFirebaseToken()

// With prevFBToken parameter (since v0.0.33)
const prevToken = {
    provider: 'google',
    token: {
        idToken: 'previous_id_token',
        refreshToken: 'previous_refresh_token'
    }
}
const result = await wepinLogin.getRefreshFirebaseToken(prevToken)
```

## sendVerifyEmail

<pre class="language-javascript"><code class="lang-javascript"><strong>await wepinLogin.sendVerifyEmail(params)
</strong></code></pre>

sendVerifyEmail 메서드는 이메일 등록 및 이메일 인증 요청을 수행합니다. required/register\_email 오류가 발생한 경우, 이메일을 등록하고 인증을 요청해야 합니다. 인증이 완료되면 `loginWithAccessToken` 또는 `loginWithIdToken` 메서드를 사용하여 처음 로그인 시 사용했던 AccessToken 또는 IdToken으로 다시 로그인합니다.

### **Supported Version**

* 버전 <mark style="color:orange;">**`0.0.18`**</mark> 이상에서 지원

### **Parameters**

* `params` \<ISendVerifyEmailParams>
  * `email` \<string>\
    등록하고 인증할 이메일 주소
  * `provider` \<string> \
    Firebase 로그인 프로바이더. 소문자로 ‘google’, ‘naver’, ‘discord’, ‘apple’, ‘facebook’, ‘line’ 등의 지원되는 프로바이더 중 하나여야 합니다. 지원되는 로그인 프로바이더의전체 목록은 [Wepin Social Login Auth Provider](/login/social-login-auth-provider) 문서를 참조하세요.
  * `idToken` \<string> \
    로그인에 사용될 id token 값
  * `accessToken` \<string> \
    로그인에 사용될 access token 값

### **Return Value**

* Promise\<boolean>

### **Example**

```javascript
const res = await wepinLogin.sendVerifyEmail({
    email:'test@abcde.com'
    provider: 'naver', 
    accessToken:'eyJHGciO....adQssw5c', 
})
```

## loginWepin

<pre class="language-javascript"><code class="lang-javascript"><strong>await wepinLogin.loginWepin({provider, token})
</strong></code></pre>

지정된 Login Provider와 Token을 사용하여 사용자를 위핀에 로그인 합니다.

### **Parameters**

이  메서드의 파라미터는 해당 모듈내의 [loginWithOauthProvider()](#loginwithoauthprovider), [loginWithEmailAndPassword()](#loginwithemailandpassword), [loginWithIdToken()](#loginwithidtoken), 그리고 [loginWithAccessToken()](#loginwithaccesstoken) 메서드들로부터의 반환 값들을 활용해야 합니다.

* `provider` <'google'|'apple'|'naver'|'discord'|'line'|'facebook'|'external\_token'|'email'>\
  Login Provider
* `token` \<object>
  * `idToken` \<string>\
    wepin firebase idToken
  * `refreshToken` \
    wepin firebase refreshToken

### **Return Value**

* `Promise`\<IWepinUser>
  * `status` <'success'|'fail'>\
    로그인 결괏값
  * `userInfo` \<object> **optional**\
    로그인된 사용자의 정보
    * userId \<string>\
      사용자의 Wepin ID
    * email \<string>\
      사용자의 email 주소
    * provider<'google'|'apple'|'naver'|'discord'|'email'|'external\_token'>\
      로그인한 Provider
    * use2FA \<boolean>\
      사용자의 2FA 설정 여부
  * `userStatus` \<object>\
    로그인된 사용자의 상태정보
    * `loginStats`: <'complete' | 'pinRequired' | 'registerRequired'>\
      'complete'가 아닌 경우, 위핀에 회원가입(등록)을 해야됩니다.
    * `pinRequired` \<boolean> **optional**\
      사용자 PIN 번호의 필요 여부
  * `token` \<object>\
    사용자의 wepin token
    * `accessToken` \<string>\
      Wepin Access Token
    * `refreshToken` \
      Wepin Refresh Token

### **Example**

```javascript
const wepinLogin = WepinLogin({ appId: 'appId', appKey: 'appKey' })
const res = await wepinLogin.loginWithOauthProvider({ provider: 'google' })

const userInfo = await wepinLogin.loginWepin(res)
const userStatus = userInfo.userStatus
if(userStatus.loginStatus === 'pinRequired'||userStatus.loginStatus === 'registerRequired') {
    // wepin register
}
```

* response

```json
{
    "status": "success",
    "userInfo": {
      "userId": "120349034824234234",
      "email": "abc@gmail.com",
      "provider": "google",
      "use2FA": true,
    },
    "walletId": "abcdsfsf123",
    "userStatus": {
        "loginRequired": "completed",
        "pinRequired": false,
    },
    "token": {
        "accessToken": "",
        "refreshToken": "",
    }
}
```

## logout

```javascript
await wepinLogin.logout()
```

위핀 사용자를 로그아웃 합니다.&#x20;

### **Parameters**

* \<void>

### **Return Value**

* `Promise` \<boolean>

  성공인 경우 true

### **Exception**

* `Wepin login module Not initialized`: Wepin Login Library가 초기화 되지 않은 경우
* `Already logout` : 사용자가 이미 로그아웃된 상태인 경우우

### **Example**

```javascript
const result = await wepinLogin.logout()
```

## finalize

```javascript
wepinLogin.finalize()
```

Wepin Login Library 사용을 종료합니다.

### **Parameters**

* \<void>

### **Return Value**

* \<void>

### **Example**

```javascript
wepinLogin.finalize()
```


# 핀 패드

RESTful API 사용시, Web 환경의 서비스에서 사용자의 PIN을 입력 받을 수 있는 UI 및 기능을 제공하는 패키지입니다.


# 설치

## 패키지 매니저로 설치하기 <a href="#installing-with-a-package-manager" id="installing-with-a-package-manager"></a>

npm 패키지로 설치 가능합니다.&#x20;

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

```bash
npm install @wepin/pin-js
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/pin-js
```

{% endtab %}
{% endtabs %}

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와  같이 WepinPin 인스턴스를 초기화합니다. 이렇게 하면  위핀의 핀 패드를 사용할 수 있게 됩니다.

<pre class="language-javascript"><code class="lang-javascript"><strong>// 1. 패키지 import
</strong>import { WepinPin } from '@wepin/pin-js'
<strong>
</strong>// 2. 초기화
const wepinPin = new WepinPin({
  appKey: 'your-wepin-app-key',
})
</code></pre>

{% hint style="danger" %}
해당 패키지는 **클라이언트 사이드 렌더링(CSR: Client Side Rendering)** 환경에서만 동작합니다. 서버 사이드 렌더링(SSR: Server Side Rendering) 환경에서 이 패키지를 사용할 경우, CSR에서만 패키지를 불러올 수 있도록 설정이 필요합니다.

아래 코드를 참고하여 설정하세요:

```typescript
const initWepinPin = async () => {
   const { WepinPin } = await import('@wepin/pin-js');
   const wepinPin = new WepinPin({
       appKey: '',
   });
   await wepinPin.init();
}
```

{% endhint %}


# 초기화하기

Wepin PIN Pad Library를 초기화하는 방법입니다.

## init

Wepin PIN Pad Library 인스턴스를 생성하고 초기화 합니다.&#x20;

초기화시에 핀 패드 화면에 보여질 언어를 설정합니다.

```javascript
// 인스턴스 생성
const wepinPin = new WepinPin({
  appKey: 'your-wepin-app-key',
})
// 초기화
await wepinPin.init({
  defaultLanguage: 'ko',
})
```

### **Parameters**

* `defaultLanguage`: \<string>\
  핀 패드화면의 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'` ,`'ja'`입니다.

### **Return value**

* `Promise`\<void>

### Example

```javascript
// 인스턴스 생성
const wepinPin = new WepinPin({
  appKey: 'your-wepin-app-key',
})

or 

// 생성한 WepinLogin 인스턴스를 WepinPin에 전달
const wepinLogin = new WepinLogin()
const wepinPin = new WepinPin({
  appKey: 'your-wepin-api-key',
  wepinLogin,
})

```

```javascript
// 초기화
await wepinPin.init({
  defaultLanguage: 'ko',
})
```

그런 다음 [Wepin Login Library](https://docs.wepin.io/widget-integration/web-javascript-sdk/login-library) 로 위핀에 로그인 하세요.

```javascript
// 로그인 방식에 따라 필요한 로그인 메소드를 실행
const loginRes = await wepinPin.login.loginWithEmailAndPassword(...)
// Wepin에 로그인
await wepinPin.login.loginWepin(loginRes)
```

## isInitialized

Wepin PIN Pad Library가 정상적으로 초기화 되었는지 확인할 수 있습니다.&#x20;

```javascript
wepinPin.isInitialized()
```

### **Parameters**

* `<void>`

### **Return Value**

* `<boolean>`\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### **Example**

```javascript
if(wepinPin.isInitialized()) {
  console.log('wepinPin is initialized!')
}
```

## changeLanguage <a href="#changelanguage" id="changelanguage"></a>

```javascript
wepinPin.changeLanguage(language)
```

핀 패드 화면에 표시되는 언어를 변경합니다. 현재 `'ko'`, `'en'`, `'ja'`만 지원됩니다.

### **Supported Version**

* 버전 <mark style="color:orange;">**`0.0.23`**</mark> 이상에서 지원.

### **Parameters**

* `language` \<string>

### **Return value** <a href="#return-value-1" id="return-value-1"></a>

* `<void>`

### Example <a href="#example-1" id="example-1"></a>

```javascript
wepinPin.changeLanguage("ko")
```


# 메서드

Wepin PIN Pad Library  초기화 이후 사용할 수 있습니다.

## generateRegistrationPINBlock

```javascript
await wepinPin.generateRegistrationPINBlock()
```

사용자의  지갑생성 및 회원가입을 위해 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.

### **Parameters**

* `<void>`

### **Return value**

* `Promise` \<RegistrationPinBlock>
  * `UVD` \<EncUVD>

    * `b64Data` \<string> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<string> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<number> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값

  * `hint` \<EncPinHint>

    * `data` \<string> \
      &#x20;PIN 힌트를 암호화한 값
    * `length` \<string>\
      PIN 힌트의 길이
    * `version` \<number>&#x20;

    &#x20;      PIN 힌트의 버전

### **Example**

```javascript
const pinBlock = await wepinPin.generateRegistrationPINBlock()

fetch({
  url: 'https://sdk.wepin.io/v1/app/register',
  method: 'POST',
  // Omit authentication headers
  body: {
    // Omit other bodies
    UVD: pinBlock.UVD,
    hint: pinBlock.hint,
  }
})
```

## &#x20;generateAuthPINBlock

```javascript
await wepinPin.generateAuthPINBlock(count?)
```

사용자 인증에 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `count` \<number> **optional**&#x20;

  생성하려는 PIN Block의 갯수. 기본값은 `1` 입니다.

### **Return value**

* `Promise` \<AuthPinBlock>
  * `UVDs` \<EncUVD\[]> \
    암호화된 PIN Block의 리스트
    * `UVD` \<EncUVD>
      * `b64Data` \<string> \
        b64SKey의  원본키로 암호화된 데이터
      * `b64SKey` \<string> \
        b64Data 를 생성할때  사용하는 키
      * `seqNum` \<number> **optional** \
        **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값.\
        Multi Tx 요청시, 반드시 받은 PIN Block의 순서대로 사용해야 합니다.(1,2,3...)
  * `otp` \<string> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### **Example**

```javascript
const pinBlock = await wepinPin.generateAuthPINBlock(count)
// Sort seqNum of uvd in ascending order from 1 because I need to write it in order starting from 1
pinBlock.UVDs.sort((a, b) => (a.seqNum ?? 0) - (b.seqNum ?? 0))

const resArray: any[] = []
for (const encUVD of pinBlock.UVDs) {
  await fetch({
    url: 'https://sdk.wepin.io/v1/tx/sign',
    method: 'POST',
    body: {
      userId: await getUserId(),
      walletId: await getWalletId(),
      accountId: (await getEthereumAccount()).accountId,
      type: 'msg_sign',
      txData: {
        data: '0x0',
      },
      pin: encUVD,
      otpCode: {
        code: pinBlock.otp,
      },
    }
  })
}
```

## generateChangePINBlock

```javascript
await wepinPin.generateChangePINBlock()
```

사용자 PIN 변경을 위해 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `<void>`

### **Return Value**

* `Promise` \<ChangePinBlock>
  * `UVD` \<EncUVD>
    * `b64Data` \<string> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<string> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<number> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값
  * `newUVD` \<EncUVD>
    * `b64Data` \<string> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<string> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<number> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값.
  * `hint` \<EncPinHint>
    * `data` \<string> \
      &#x20;PIN 힌트를 암호화한 값
    * `length` \<string>\
      PIN 힌트의 길이
    * `version` \<number> \
      PIN 힌트의 버전
  * `otp` \<string> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### **Example**

```javascript
const pinBlock = await wepinPin.generateChangePINBlock()
const res = await fetch({
  url: 'https://sdk.wepin.io/v1/wallet/pin/change'
  body: {
    userId: await getUserId(),
    walletId: await getWalletId(),
    UVD: pinBlock.UVD,
    newUVD: pinBlock.newUVD,
    hint: pinBlock.hint,
    otpCode: {
      code: pinBlock.otp
    }
  }
})
```

## generateAuthOTP

```javascript
await wepinPin.generateAuthOTP()
```

사용자로부터 OTP 코드를  입력받을 수 있는 화면을 띄우고 처리합니다.

### **Parameters**

* `<void>`

### **Return Value**

* `Promise`\<AuthOTP>
  * `code` \<string>\
    입력받은 OTP 코드

### **Example**

```javascript
let res = await getWepinSignMessage(pinBlocks.UVDs, pinBlock.otp)
if (res.body[0].message === 'OTP_MISMATCH_WRONG_CODE') {
  const otp = await wepinPin.generateAuthOTP()
  res = await getWepinSignMessage(pinBlocks.UVDs, otp.code)
}
```

## finalize

```javascript
wepinPin.finalize()
```

Wepin PIN Pad Library 사용을 종료합니다.

### **Parameters**

* \<void>

### **Return Value**

* \<void>

### **Example**

```javascript
wepinPin.finalize()
```


# 위젯

위핀 위젯을 사용하는 방법에 대한 안내 페이지 입니다.


# 설치

## 패키지 매니저로 설치하기

npm 패키지로 설치 가능합니다.&#x20;

{% hint style="info" %}
해당 패키지는 **웹 환경에서만 사용 가능**합니다. Android, iOS 하이브리드 앱(Webview)에서는 사용할 수 없습니다.&#x20;
{% endhint %}

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

```bash
npm install @wepin/sdk-js
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/sdk-js
```

{% endtab %}
{% endtabs %}

설치가 완료되면 package.json에서 아래와 "dependencies"에 추가된 것을 확인할 수 있습니다.

```json
{
  "dependencies": {
    "@wepin/sdk-js": "^0.0.1"
  }
}
```

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와 같이 wepinSDK 인스턴스를 초기화합니다. 이렇게 하면 WepinSDK를 사용할 수 있게 됩니다.

<pre class="language-javascript"><code class="lang-javascript"><strong>// 1. 패키지 import
</strong>import { WepinSDK } from '@wepin/sdk-js'
<strong>
</strong>// 2. 초기화
const wepinSdk = new WepinSDK({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-app-key',
})
</code></pre>

{% hint style="danger" %}
해당 패키지는 **클라이언트 사이드 렌더링(CSR: Client Side Rendering)** 환경에서만 동작합니다. 서버 사이드 렌더링(SSR: Server Side Rendering) 환경에서 이 패키지를 사용할 경우, CSR에서만 패키지를 불러올 수 있도록 설정이 필요합니다.

아래 코드를 참고하여 설정하세요:

```javascript
const initWepin = async () => {
    const { WepinSDK } = await import('@wepin/sdk-js');
    const wepinSDK = new WepinSDK({
        appKey: '',
        appId: '',
    });
    await wepinSDK.init({
        defaultLanguage: 'ko',
    });
}
```

{% endhint %}


# 초기화하기

Wepin Widget Javascript SDK를 초기화하는 방법입니다.&#x20;

## init

WepinSDK 를 초기화 합니다. 초기화시에  필요한 위젯의 속성들을 정의합니다.

```javascript
await wepinSdk.init(attributes?)
```

### **Parameters**

* `attributes` \<object> **optional** &#x20;
* `type` \<string>\
  처음 로딩 시 앱 위젯 윈도우를 어떻게 보여줄 지를 결정 합니다. 기본 값은 `hide` 입니다. 현재는\
  `hide` 만 지원합니다 \
  `hide` 는 처음 로딩시 위젯 윈도우를 보여주지 않고 숨깁니다. 이후 `openWindow()`을 통해서 위젯 윈도우을 띄워 보여 줍니다.
* `defaultLanguage`: \<string>\
  위젯 기본 언어 설정, 기본 값은 `ko`입니다. 현재 지원하는 언어는 `en`, `ko`, `ja` 3가지 입니다.
* `defaultCurrency`**:** \<string>\
  위젯 기본 통화 설정, 기본 값은 `KRW`입니다. 현재 지원하는 통화는 `USD`, `KRW`, `JPY` 3가지 입니다.
* `loginProviders`: \<string\[]> **optional**

  로그인 프로바이더 리스트 입니다.   현재 지원하는 프로바이더는 `google`, `apple` , `naver`, `discord`, `line`, `facebook` 이렇게 6가지 입니다.  필요한 로그인 프로바이더만 정의해서 사용하세요. &#x20;

  * 이 값을 지정하지 않으면  제공하는 모든 프로바이더를 이용할 수 있습니다.
  * 빈 배열이 제공된 경우, 이메일 로그인 기능만 사용 가능합니다. (v0.0.3 버전 이상부터  지원)

### **Return value**

* `Promise`\<void>

### Example

<pre class="language-javascript"><code class="lang-javascript">await wepinSdk.init({
    type: 'hide',
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
})

// google, apple login
<strong>await wepinSdk.init({
</strong>    type: 'hide',
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
    loginProviders: ['google', 'apple']
})

// only email login
await wepinSdk.init({
    type: 'hide',
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
    loginProviders: []
})
</code></pre>

## isInitialized

WepinSDK 가 정상적으로 초기화 되었는지 확인할 수 있습니다.&#x20;

```javascript
wepinSdk.isInitialized()
```

### **Parameters**

* \<void>

### **Return Value**

* `<boolean>`\
  초기화가 정상적으로 잘 된 경우 true , 실패한 경우 false 를 반환합니다.

### **Example**

```javascript
await wepinSdk.init({
    type: 'hide',
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
})

if(wepinSdk.isInitialized()) {
  console.log('wepinSDK is initialized!')
}
```

## changeLanguage

위젯의 언어와 통화를 변경할 수 있습니다.

```javascript
wepinSdk.changeLanguage({language, currency})
```

### **Parameters**

* `language` \<string>\
  위젯에 표시될 언어를   지정합니다. 현재 지원하는 언어는 `en`, `ko`, `ja` 3가지 입니다.
* `currency` \<string>\
  위젯에 표시될 통화를  지정합니다. 현재 지원하는 통화는 `USD`, `KRW`, `JPY` 3가지 입니다.

### Example

```javascript
wepinSdk.changeLanguage({
   currency: 'KRW',
   language: 'ko'
})
```


# 메서드

Wepin Widget Javascript SDK에서 제공하는 메서드 입니다.

## getStatus

```javascript
await wepinSdk.getStatus()
```

WepinSDK의 Lifecycle 상태 값을 반환합니다.

### **Parameters**

* \<void>

### **Return value**

* `WepinLifeCycle` \<string>
  * `not_initialized`: `WepinSDK`이 초기화되지 않음
  * `initializing`: `WepinSDK`초기화 진행 중
  * `initialized`: `WepinSDK`초기화 완료
  * `before_login`: `WepinSDK`은 초기화되었으나 사용자는 로그인되지 않음
  * `login`: 사용자가 로그인 되었고 위핀에도  가입되어있음
  * `login_before_register` : 사용자가 로그인하였으나 위핀에 가입되지 않음

### **Example**

```javascript
const status = await wepinSdk.getStatus()
```

## openWidget

```javascript
await wepinSdk.openWidget()
```

위젯 윈도우를 보여 줍니다. 만약 사용자가 로그인 되어 있지 않다면, 위젯 윈도우는 열리지 않습니다. 따라서 `openWidget` 전에 반드시 사용자는 위핀에 로그인 되어 있어야 합니다. 위핀에 로그인 하기 위해서는 `loginWithUI` 또는 `@wepin/login-js`의  `oginWepin` 메서드를 사용합니다.&#x20;

### **Parameters**

* \<void>

### **Return Value**

* `<Promise>` \<void>

### **Example**

```javascript
await wepinSdk.openWidget()
```

## closeWidget

```javascript
wepinSdk.closeWidget()
```

위젯 윈도우를 닫습니다. 윈도우를 닫아도 로그아웃 되지 않습니다.&#x20;

### **Parameters**

* \<void>

### **Return Value**

* \<void>

### **Example**

```javascript
wepinSdk.closeWidget()
```

## loginWithUI

```javascript
await wepinSdk.loginWithUI({email}?)
```

로그인한 사용자의 정보를 반환합니다. 로그인한 사용자가 없을 경우, 위핀 위젯은 로그인 페이지를 표시할 것입니다. 위젯 없이 로그인을 수행하려면, `@wepin/login-js`에서 `loginWepin()` 메서드를 사용하세요.

### **Parameters**

* `email` \<string> **optional**

  위핀에 로그인할 사용자의 이메일 주소

### **Return Value**

* Promise \<IWepinUser>
  * `status` \<string> &#x20;

    성공 여부<'success'|'fail'>
  * `userInfo` \<object> **optional**
    * `userId` \<string>

      위핀의 사용자 ID
    * `email` \<string>

      위핀에 로그인된 사용자의 이메일 주소
    * `provider` \<string>

      &#x20;<'google'|'apple'|'naver'|'discord'|'email'|'external\_token'>
    * `use2FA` \<boolean>

      사용자 지갑에 2FA가 활성화 되어 있는지 여부
  * `userStatus`: \<object>&#x20;
    * `loginStatus` \<string>

      <'complete' | 'pinRequired' | 'registerRequired'>&#x20;

      사용자의 loginStatus 값이 'complete'가 아닌  경우, 위핀에 등록을 해야 합니다.
    * `pinRequired` \<boolean> **optional**

      사용자 PIN 번호 필요 여부
  * `walletId` \<string>

    위핀 사용자의 지갑 ID
  * `token` \<object> **optional**
    * `accessToken` \<string> \
      Wepin Access Token
    * `refreshToken` \<string>\
      Wepin Refresh Token

### **Example**

```javascript
//without email
const userInfo = await wepinSdk.loginWithUI()
//with email
const userInfo = await wepinSdk.loginWithUI({email})
```

* respnse

```json
{
    "status": "success",
      "userInfo": {
        "userId": "120349034824234234",
        "email": "abc@gmail.com",
        "provider": "google",
        "use2FA": true,
      },
}
```

## getLoginSession

```javascript
await wepinSdk.getLoginSession(provToken?)
```

Wepin에서 현재 Firebase 토큰의 정보를 가져옵니다. 이전 토큰이 제공된 경우, 저장된 토큰을 업데이트한 후 최신 인증 정보를 반환합니다.

### **Supported Version**

* 버전 <mark style="color:orange;">**`0.0.33`**</mark> 이상에서 지원

### **Parameters**

* `provToken` \<object> **optional** \
  이전에 발급된 토큰
  * `firebaseToken` \<IFirebaseWepin>\
    Firebase 로그인 정보
    * `provider` \<string>\
      Provider for Firebase Login
    * `idToken` \<string>\
      Wepin Firebase idToken
    * `refreshToken` \<string>\
      Wepin Firebase refreshToken
  * `wepinToken` \<IWepinToken>\
    사용자의 Wepin Token
    * `accessToken` \<string>\
      Wepin  Access Token
    * `refreshToken` \<string>\
      Wepin Refresh Token

### **Return Value**

* Promise \<object>
  * `firebaseToken` \<IFirebaseWepin>\
    Firebase 로그인 정보
    * `provider` \<string>\
      Provider for Firebase Login
    * `idToken` \<string>\
      Wepin Firebase idToken
    * `refreshToken` \<string>\
      Wepin Firebase refreshToken
  * `wepinToken` \<IWepinToken>\
    사용자의 Wepin Token
    * `accessToken` \<string>\
      Wepin  Access Token
    * `refreshToken` \<string>\
      Wepin Refresh Token

### **Example**

```javascript
//without parameter. get prevToken
const prevToken = await wepinSdk.getLoginSession()
//with parameter. refresh Firebase Token.
const loginToken = await wepinSdk.getLoginSession(prevToken)
```

* respnse

```json
{
  "firebaseToken": {
    "provider": "google",
    "idToken": "eyJhbGci...",
    "refreshToken": "AMf-vBwvHUYdt5..."
  },
  "wepinToken": {
    "accessToken": "eyJhbGciOiJS...",
    "refreshToken": "eyJhbGciOiJ..."
  }
}
```

## register

```javascript
await wepinSdk.register()
```

사용자를 위핀에 등록합니다. 가입 및 로그인 후,  위핀 위젯의 등록 페이지가 열리고 위핀 서비스에 등록(지갑 생성 및 계정 생성)을 진행합니다. 이 기능은 WepinSDK의 `WepinLifeCycle`이 login\_before\_register일 때만 사용할 수 있습니다. @wepin/login-js에서 loginWepin() 메서드를 호출한 후, userStatus의 loginStatus 값이 'complete'가 아니면 이 메서드를 호출해야 합니다.

### **Parameters**

* `<void>`

### **Return Value**

* Promise \<IWepinUser>
  * `status` \<string> &#x20;

    성공 여부<'success'|'fail'>
  * `userInfo` \<object> **optional**
    * `userId` \<string>

      위핀의 사용자 ID
    * `email` \<string>

      위핀에 로그인된 사용자의 이메일 주소
    * `provider` \<string>

      <'google'|'apple'|'naver'|'discord'|'email'|'external\_token'>
    * `use2FA` \<boolean>

      사용자 지갑에 2FA가 활성화 되어 있는지 여부
  * `userStatus`: \<object>&#x20;
    * `loginStatus` \<string>

      <'complete' | 'pinRequired' | 'registerRequired'>&#x20;

      사용자의 loginStatus 값이 'complete'가 아닌  경우, 위핀에 등록을 해야 합니다.
    * `pinRequired` \<boolean> **optional**

      사용자 PIN 번호 필요 여부
  * `walletId` \<string>

    위핀 사용자의 지갑 ID
  * `token` \<object> **optional**
    * `accessToken` \<string>\
      Wepin Access Token
    * `refreshToken` \<string>\
      Wepin Refresh Token

### **Example**

```javascript
const userInfo = await wepinSdk.register()
```

## registerUserEmail

```javascript
await wepinSdk.registerUserEmail(param)
```

registerUserEmail 함수는 OAuth 프로바이더로부터 이메일이 등록되지 않은 계정에 대해 위핀 이메일을 등록합니다.

### **Supported Version**

* 버전 <mark style="color:orange;">**`0.0.18`**</mark> 이상에서 지원

### **Parameters**

* `provider` \<LoginProviders> \
  Provider for Firebase login. The value must be one of the supported login provider names in lowercase, such as 'google', 'naver', 'discord', 'apple', 'facebook', or 'line'. Please refer to [Wepin Social Login Auth Provider documentation](/login/social-login-auth-provider) to check the supported login providers.
* `idToken` \<string> \
  id token value to be used for login
* `accessToken` \<string> \
  access token value to be used for login

### **Return Value**

* `Promise` \<IWepinUser>
  * `status` \<string> &#x20;

    성공 여부<'success'|'fail'>
  * `userInfo` \<object> **optional**
    * `userId` \<string>

      위핀의 사용자 ID
    * `email` \<string>

      위핀에 로그인된 사용자의 이메일 주소
    * `provider` \<string>

      <'google'|'apple'|'naver'|'discord'|'email'|'external\_token'>
    * `use2FA` \<boolean>

      사용자 지갑에 2FA가 활성화 되어 있는지 여부
  * `userStatus`: \<object>&#x20;
    * `loginStatus` \<string>

      <'complete' | 'pinRequired' | 'registerRequired'>&#x20;

      사용자의 loginStatus 값이 'complete'가 아닌  경우, 위핀에 등록을 해야 합니다.
    * `pinRequired` \<boolean> **optional**

      사용자 PIN 번호 필요 여부
  * `walletId` \<string>

    위핀 사용자의 지갑 ID
  * `token` \<object> **optional**
    * `accessToken` \<string>\
      Wepin Access Token
    * `refreshToken` \<string>\
      Wepin Refresh Token

### **Example**

```javascript
await wepinSdk.registerUserEmail({
    provider: 'google',
    idToken: 'google-idToken',
})
```

## logout

```javascript
await wepinSdk.logout()
```

위핀 사용자를 로그아웃 합니다.&#x20;

### **Parameters**

* \<void>

### **Return Value**

* `Promise` \<void>

### **Example**

```javascript
await wepinSdk.logout()
```

## getAccounts

```javascript
await wepinSdk.getAccounts()
or
await wepinSdk.getAccounts(options?)
```

앱에서 사용 가능한 사용자의  계정정보(네트워크와 주소)를 반환합니다.&#x20;

이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다.&#x20;

`options` 파라미터가 없는 경우에는 사용자의 모든 계정 정보가 반환됩니다.&#x20;

### **Parameters**

* `options` \<object> **optional**
  * `networks` \<string\[]> **optional**

    반환 받고자 하는 계정의네트워크 입니다. \
    `networks` 에 넣을 수 있는 블록체인 네트워크는  아래의 **지원 블록체인 페이지**에서 확인가능합니다.
  * `withEoa` \<boolean> **optional**

    AA 계정이 있는 경우, EOA 계정도 포함해서 반환 받을지 여부

{% content-ref url="/pages/jNG611rZkq69C8zZKglh" %}
[지원 블록체인](/wepin/supported-blockchains)
{% endcontent-ref %}

### **Return Value**

사용자가 로그인 되어 있는 경우,  네트워크의 계정 정보  `Account[]` 가 반환됩니다.&#x20;

* `Promise` \<Account\[]>
  * address \<string>

    사용자 계정의 주소
  * network \<string>

    사용자 계정의 network 종류
  * contract \<string> **optional**&#x20;

    토큰의 계약 주소
  * isAA \<boolean> **optional**&#x20;

    AA 계정인지 여부

### **Example**

```javascript
const result = await wepinSdk.getAccounts({
  networks: ['Ethereum'], 
  withEoa: true
})
```

* response

```javascript
[
  {
    "address": "0x0000001111112222223333334444445555556666",
    "network": "Ethereum",
  },
  {
    "address": "0x0000001111112222223333334444445555556666",
    "network": "Ethereum",
    "contract": "0x777777888888999999000000111111222222333333",
  },
  {
    "address": "0x4444445555556666000000111111222222333333",
    "network": "Ethereum",
    "isAA": true,
  },
]

```

## getBalance

```javascript
await wepinSdk.getBalance(accounts)
or
await wepinSdk.getBalance()
```

계정의 잔액(수량) 정보를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다.&#x20;

`accounts` 파라미터가 없는 경우에는 사용자의 모든 계정의 잔액이 반환 됩니다.

### **Parameters**

* `accounts` \<Account\[]> **optional**
  * `network` \<string>

    잔액을 조회할 사용자 계정의 네트워크 종류
  * `address` \<string>

    잔액을 조회할 사용자 계정의 주소
  * `isAA` \<boolean> **optional**&#x20;

    AA 계정인지 여부

### **Return Value**

* `Promise` \<AccountBalanceInfo\[]>
  * `network` \<string>

    사용자 계정의 네트워크 종류
  * `address` \<string>

    사용자 계정의 주소
  * `symbol` \<string>&#x20;

    네트워크 심볼
  * `balance` \<string>&#x20;

    보유하고 있는 네트워크 코인의 갯수
  * `tokens` \<TokenBalanceInfo\[]>&#x20;
    * `symbol` \<string>&#x20;

      토큰 심볼
    * `balance` \<string>&#x20;

      보유하고 있는 토큰의 갯수
    * `contract` \<string>&#x20;

      토큰 계약주소

### **Example**

```javascript
const result = await wepinSdk.getBalance([{
  address: '0x0000001111112222223333334444445555556666',
  network: 'Ethereum',
}])
```

* response

```
[
    {
        "symbol": "ETH",
            "balance": "1.1",
        "tokens":[
            {
                "contract": "0x123...213",
                "symbol": "TEST",
                "balance": "10"
            },
        ]
    }
]
```

## send

```javascript
await wepinSdk.send({account, txData?})
```

위젯을 이용하여 send기능을 수행하고 send 트랜젝션의 ID정보를 반환합니다. 위핀에 로그인한 후에만 사용할 수 있습니다.

### **Parameters**

* `account` \<Account>&#x20;

  전송할 사용자의  계정 정보

  * `network` \<string>&#x20;

    전송할 네트워크 종류
  * `address` \<string>&#x20;

    전송할 계정의 주소
  * contract \<String> **optional**&#x20;

    토큰의 계약 주소
* `txData` \<object> **optional**
  * `to` \<string>&#x20;

    전송 받을 주소
  * `amount` \<string> &#x20;

    전송할 수량

### **Return Value**

* `Promise` \<object>

  * `txId` \<string>

  &#x20;      send 트랜잭션의 txID

### **Example**

```javascript
const result = await wepinSdk.send({
    account: {
        address: '0x0000001111112222223333334444445555556666',
        network: 'Ethereum',
    },
    txData: {
        to: '0x9999991111112222223333334444445555556666',
        amount: '0.1',
    }
})
```

* response

```json
{
    "txId": "0x76bafd4b700ed959999d08ab76f95d7b6ab2249c0446921c62a6336a70b84f32"
}
```

## finalize

```javascript
wepinSdk.finalize()
```

WepinSDK 사용을 종료합니다. `WepinLifeCycle`이 `not_initialized` 로 변경됩니다.&#x20;

### **Return Value**

* `void`

### **Example**

```javascript
wepinSdk.finalize()
```


# 확인하기

Wepin Widget SDK 초기화를 정상적으로 완료하고 `openWindow` 를 하면 위핀에 로그인 할 수 있습니다. 로그인까지 완료하면 아래와 같이 새로운 위핀 지갑이 생성되고 해당 지갑에 있는 계정 정보를 확인할 수 있습니다.&#x20;

<figure><img src="/files/fkwyApOQszrCVOhazDM2" alt=""><figcaption></figcaption></figure>

## 예제

\[준비중입니다]


# 프로바이더

프로바이더는 애플리케이션과 블록체인 네트워크를 연결하여 상호작용을 가능하게 합니다. 위핀 지갑을 통합한 이후, 스마트 컨트랙트 메서드를 호출하거나, 사용자의 토큰 잔액을 확인하고, 거래를 진행하는데 프로바이더를 활용할 수 있습니다. 위핀 프로바이더를 이용하면, 위핀에서 지원하는 다양한 네트워크와 쉽게 상호 작용 할 수있습니다.&#x20;

위핀에서 지원하는 프로바이더는 다음과 같습니다.

* [Ethereum Provider](https://eips.ethereum.org/EIPS/eip-1193): Ethereum, Polygon, Klaytn 등 **EVM(Ethereum Virtual Machine) 호환 네트워크**와 상호작용할 때 사용합니다. 스마트 컨트랙트 함수를 호출하거나 EVM 기반 토큰의 잔액을 확인하고, 트랜잭션을 전송하는 등의 기능을 구현할 때 사용할 수 있습니다.
* [Solana Provider](https://solana.com/docs/rpc/http): Solana 블록체인과 상호작용할 때 사용할 수 있습니다. Solana 기반의 NFT 거래, SPL 토큰 전송, 혹은 Solana 스마트 컨트랙트와 상호작용하는 기능을 구현할 때 유용합니다.
* [Wagmi Connector](https://wagmi.sh/): React 기반의 앱을 개발하면서 블록체인과 상호작용할 수 있는 다양한 React Hooks를 제공하여 지갑 연결이나 계정 관리를 간단히 수행할 수 있으며, 멀티체인 지원 및 네트워크 관리에 이점을 가지고 있습니다.
* [Kaia Provider](/widget-integration/web-javascript-sdk/provider/kaia-provider): Kaia 블록체인과 상호작용할 수 있도록 지원하는 프로바이더입니다. JSON-RPC 요청을 통해 계정 연결, 트랜잭션 서명 및 전송, 스마트 컨트랙트 실행 등의 기능을 제공하며, EVM 기반 블록체인과 연동이 가능합니다.

아래 문서에서 자세한 사용 방법을 알아보세요.

<table data-view="cards"><thead><tr><th align="center"></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td align="center">Ethereum Provider</td><td></td><td></td><td><a href="/pages/ZDs7I0nRw6Umo7XGE4yY">/pages/ZDs7I0nRw6Umo7XGE4yY</a></td><td><a href="/files/IHeW92M41dlOiVSk7wZB">/files/IHeW92M41dlOiVSk7wZB</a></td></tr><tr><td align="center">Solana Provider</td><td></td><td></td><td><a href="/pages/ralXF5Lnkc9iCeldtb4d">/pages/ralXF5Lnkc9iCeldtb4d</a></td><td><a href="/files/2nQ06Dvn0e1DwBx8QV8l">/files/2nQ06Dvn0e1DwBx8QV8l</a></td></tr><tr><td align="center">Wagmi Connector</td><td></td><td></td><td><a href="/pages/VoUhE1kkS06xyyiX4Z1L">/pages/VoUhE1kkS06xyyiX4Z1L</a></td><td><a href="/files/9XjUS3VNPtCwrMIBuT0B">/files/9XjUS3VNPtCwrMIBuT0B</a></td></tr><tr><td align="center">Kaia Provider</td><td></td><td></td><td></td><td><a href="/files/siEKsLmDlNXIQlVFDmVR">/files/siEKsLmDlNXIQlVFDmVR</a></td></tr></tbody></table>


# Ethereum Provider

Ethers.js 또는 Web3.js를 Wepin Provider와 함께 사용하면 EVM 계열의 블록체인과 상호작용 할 수 있습니다.&#x20;

## 지원 네트워크 <a href="#supported-networks" id="supported-networks"></a>

{% hint style="info" %}
목록에 필요한 블록체인이 없나요? [위핀 팀에 요청](https://wepinwallet.typeform.com/WEPIN-Wallet)하여 별도의 비용 없이 블록체인을 추가할 수 있습니다.
{% endhint %}

<table><thead><tr><th width="172.33333333333331">Chain ID</th><th>Network Name</th><th>Network Variable</th></tr></thead><tbody><tr><td>1</td><td>Ethereum Mainnet</td><td>ethereum</td></tr><tr><td>5</td><td>Ethereum Goerli Testnet</td><td>evmeth-goerli</td></tr><tr><td>8217</td><td>Kaia Mainnet</td><td>klaytn</td></tr><tr><td>1001</td><td>Kaia Kairos Testnet</td><td>klaytn-testnet</td></tr><tr><td>19</td><td>Songbird Canary Network</td><td>evmsongbird</td></tr><tr><td>137</td><td>Polygon Mainnet</td><td>evmpolygon</td></tr><tr><td>248</td><td>Oasys</td><td>evmoasys-games</td></tr><tr><td>37</td><td>XPLA Mainnet</td><td>evmxpla</td></tr><tr><td>7300</td><td>XPLA Verse Mainnet</td><td>evmxpla-verse</td></tr><tr><td>2731</td><td>TimeNetwork Testnet</td><td>evmtime-elizabeth</td></tr><tr><td>11155111</td><td>Ethereum Sepolia Testnet</td><td>evmeth-sepolia</td></tr><tr><td>80002</td><td>Polygon Amoy Testnet</td><td>evmpolygon-amoy</td></tr><tr><td>9372</td><td>Oasys Testnet</td><td>evmoasys-games-testnet</td></tr><tr><td>47</td><td>XPLA Testnet</td><td>evmxpla-testnet</td></tr><tr><td>2225</td><td>XPLA Verse Testnet</td><td>evmxpla-verse-testnet</td></tr><tr><td>204</td><td>opBNB Mainnet</td><td>evmopbnb</td></tr><tr><td>56</td><td>Binance Smart Chain</td><td>evmbsc</td></tr><tr><td>97</td><td>BSC-TESTNET</td><td>evmbsc-testnet</td></tr><tr><td>5611</td><td>opBNB Testnet</td><td>evmopbnb-testnet</td></tr><tr><td>656476</td><td>Open Campus Testnet</td><td>evmopencampus-testnet</td></tr><tr><td>43114</td><td>Avalanche</td><td>evmavax-c-chain</td></tr><tr><td>4613</td><td>VERY Mainnet</td><td>evmvery</td></tr></tbody></table>

## 설치(Install)

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

```bash
npm install @wepin/provider-js
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/provider-js
```

{% endtab %}
{% endtabs %}

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와  같이 WepinProvider 인스턴스를 초기화합니다. 이렇게 하면 WepinProvider 를 사용할 수 있게 됩니다.

<pre class="language-javascript"><code class="lang-javascript"><strong>// 1. 패키지 import
</strong>import { WepinProvider } from '@wepin/provider-js'
<strong>
</strong>// 2. 초기화
const WepinProvider = new WepinProvider({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-app-key',
})
</code></pre>

## 초기화하기 <a href="#initialization" id="initialization"></a>

Wepin Provider를 초기화하는 방법입니다.&#x20;

## init

```javascript
await wepinProvider.init(attributes?)
```

### **Parameters**

* `attributes` \<object> **optional**
  * `defaultLanguage`: 위젯 기본 언어 설정, 기본 값은 `ko`입니다. 현재 지원하는 언어는 `en`, `ko`, `ja` 3가지 입니다.
  * `defaultCurrency`: T위젯 기본 통화 설정, 기본 값은 `KRW`입니다. 현재 지원하는 통화는 `USD`, `KRW`, `JPY` 3가지 입니다.

### **Return value**

* `Promise`\<void>

### **Example**

```javascript
await wepinProvider.init({
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
})
```

## isInitialized

WepinProvider 가 정상적으로 초기화 되었는지 확인할 수 있습니다.&#x20;

```javascript
wepinProvider.isInitialized()
```

### **Parameters**

* `<void>`

### **Return value**

* `<boolean>`\
  init이 정상적으로 잘 된 경우 <mark style="color:orange;">`true`</mark> , 실패한 경우 <mark style="color:orange;">`false`</mark> 를 반환합니다.

### **Example**

```javascript
if(wepinProvider.isInitialized()) {
  console.log('wepinProvider is initialized!')
}
```

## changeLanguage

위젯의 언어와 통화를 변경할 수 있습니다.

```javascript
wepinProvider.changeLanguage(attributes)
```

### **Parameters**

* `attributes` \<object>
  * `language` \<string>\
    위젯에 표시될 언어를   지정합니다. 현재 지원하는 언어는 `en`, `ko`, `ja` 3가지 입니다.
  * `currency` \<string>\
    위젯에 표시될 통화를  지정합니다. 현재 지원하는 통화는 `USD`, `KRW` , `JPY` 3가지 입니다.

### **Return value**

* \<boolean>\
  init이 정상적으로 잘 된 경우 <mark style="color:orange;">`true`</mark> , 실패한 경우 <mark style="color:orange;">`false`</mark> 를 반환합니다.

### **Example**

```javascript
if(wepinProvider.isInitialized()) {
  console.log('wepinProvider is initialized!')
}
```

## 메서드(Method)

Wepin Provider 초기화 후에 메서서드를 사용할 수 있습니다.

## getProvider

Network에 해당하는 Provider를 반환합니다.

```jsx
await wepinProvider.getProvider(network)
```

### **Parameters**

* `network` \<string> \
  위핀이 지원하는 Provider의 Network Variable 값으로, Ethereum Mainnet의 경우 "ethereum" 입니다. Network Variable은 소문자로 입력해야 합니다. 전체 목록은 [Ethereum Provider 지원 네트워크](/widget-integration/web-javascript-sdk/provider/ethereum-provider#undefined)에서 확인하세요.

### **Return value**

* `Promise`\<BaseProvider> - A EIP-1193 provider

### **Example**

```javascript
const provider = await wepinProvider.getProvider('ethereum')
```

### finalize

WepinProvider 사용을 종료합니다.

```javascript
wepinProvider.finalize()
```

### **Parameters**

* `<void>`

### **Return value**

* `<void>`

### **Example**

```javascript
wepinProvider.finalize()
```

이더리움 호환 네트워크 프로바이더의 자세한 내용은 아래 링크를 참고하세요.

{% embed url="<https://eips.ethereum.org/EIPS/eip-1193>" %}


# Kaia Provider

Ethers.js 또는 Web3.js를 Wepin Provider와 함께 사용하면 EVM 계열의 블록체인과 상호작용 할 수 있습니다.&#x20;

## 지원 네트워크 <a href="#supported-networks" id="supported-networks"></a>

{% hint style="info" %}
목록에 필요한 블록체인이 없나요? [위핀 팀에 요청](https://wepinwallet.typeform.com/WEPIN-Wallet)하여 별도의 비용 없이 블록체인을 추가할 수 있습니다.
{% endhint %}

<table><thead><tr><th width="172.33333333333331">Chain ID</th><th>Network Name</th><th>Network Variable</th><th></th></tr></thead><tbody><tr><td>8217</td><td>Kaia Mainnet</td><td>klaytn</td><td></td></tr><tr><td>1001</td><td>Kaia Kairos Testnet</td><td>klaytn-testnet</td><td></td></tr></tbody></table>

## 설치(Install)

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

```bash
npm install @wepin/provider-js
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/provider-js
```

{% endtab %}
{% endtabs %}

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와  같이 WepinProvider 인스턴스를 초기화합니다. 이렇게 하면 WepinProvider 를 사용할 수 있게 됩니다.

<pre class="language-javascript"><code class="lang-javascript"><strong>// 1. 패키지 import
</strong>import { WepinProvider } from '@wepin/provider-js'
<strong>
</strong>// 2. 초기화
const WepinProvider = new WepinProvider({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-app-key',
})
</code></pre>

## 초기화하기 <a href="#initialization" id="initialization"></a>

Wepin Provider를 초기화하는 방법입니다.&#x20;

## init

```javascript
await wepinProvider.init(attributes?)
```

### **Parameters**

* `attributes` \<object> **optional**
  * `defaultLanguage`: 위젯 기본 언어 설정, 기본 값은 `ko`입니다. 현재 지원하는 언어는 `en`, `ko`, `ja` 3가지 입니다.
  * `defaultCurrency`: T위젯 기본 통화 설정, 기본 값은 `KRW`입니다. 현재 지원하는 통화는 `USD`, `KRW`, `JPY` 3가지 입니다.

### **Return value**

* `Promise`\<void>

### **Example**

```javascript
await wepinProvider.init({
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
})
```

## isInitialized

WepinProvider 가 정상적으로 초기화 되었는지 확인할 수 있습니다.&#x20;

```javascript
wepinProvider.isInitialized()
```

### **Parameters**

* `<void>`

### **Return value**

* `<boolean>`\
  init이 정상적으로 잘 된 경우 <mark style="color:orange;">`true`</mark> , 실패한 경우 <mark style="color:orange;">`false`</mark> 를 반환합니다.

### **Example**

```javascript
if(wepinProvider.isInitialized()) {
  console.log('wepinProvider is initialized!')
}
```

## changeLanguage

위젯의 언어와 통화를 변경할 수 있습니다.

```javascript
wepinProvider.changeLanguage(attributes)
```

### **Parameters**

* `attributes` \<object>
  * `language` \<string>\
    위젯에 표시될 언어를   지정합니다. 현재 지원하는 언어는 `en`, `ko`, `ja` 3가지 입니다.
  * `currency` \<string>\
    위젯에 표시될 통화를  지정합니다. 현재 지원하는 통화는 `USD`, `KRW` , `JPY` 3가지 입니다.

### **Return value**

* \<boolean>\
  init이 정상적으로 잘 된 경우 <mark style="color:orange;">`true`</mark> , 실패한 경우 <mark style="color:orange;">`false`</mark> 를 반환합니다.

### **Example**

```javascript
if(wepinProvider.isInitialized()) {
  console.log('wepinProvider is initialized!')
}
```

## 메서드(Method)

Wepin Provider 초기화 후에 메서서드를 사용할 수 있습니다.

### getProvider

Network에 해당하는 Provider를 반환합니다.

```jsx
await wepinProvider.getProvider(network)
```

#### **Parameters**

* `network` \<string> \
  위핀이 지원하는 Provider의 Network Variable 값으로, Kaia Mainnet의 경우 "klaytn" 입니다. Network Variable은 소문자로 입력해야 합니다. 전체 목록은 [Kaia Provider 지원 네트워크](#supported-networks)에서 확인하세요.

#### **Return value**

* `Promise`\<BaseProvider> - A EIP-1193 provider

#### **Example**

```javascript
const provider = await wepinProvider.getProvider('klaytn')
```

## finalize

WepinProvider 사용을 종료합니다.

```javascript
wepinProvider.finalize()
```

#### **Parameters**

* `<void>`

#### **Return value**

* `<void>`

#### **Example**

```javascript
wepinProvider.finalize()
```

***

### request

Kaia 블록체인과 상호작용 할 수 있도록 JSON-RPC 요청을 보낼 수 있습니다.

{% hint style="info" %}

#### kaia prefix method 는 버전0.0.31 이부터 지원합니다.

{% endhint %}

#### eth\_accounts / klay\_accounts / kaia\_accounts

위핀 지갑에 연결하여 사용자의 허가를 받아 계정의 주소를 공유합니다. 연결이 승인되면 애플리케이션은 메세지 서명이나 트랜잭션 요청을 할 수 있습니다.

**Parameters**

* `void`

**Returns**

* `Promise<Array<string>>` - 사용자의 주소 목록을 반환합니다.

**Example**

```typescript
const accounts = await wepinProvider.request({
      method: 'kaia_accounts',
      params: []
})
```

***

#### eth\_signTransaction / klay\_signTransaction / kaia\_signTransaction

주어진 매개변수로 트랜잭션을 구성하고 사용자의 개인키로 트랜잭션에 서명합니다.&#x20;

**Supported Tx Type**

<table><thead><tr><th width="300">TxType</th><th width="247">Support Fee Delegateed</th><th>Version</th></tr></thead><tbody><tr><td>TxTypeLegacy</td><td>false</td><td></td></tr><tr><td>TxTypeValueTransfer</td><td>true</td><td>≥ v.0.0.31</td></tr><tr><td>TxTypeValueTransferMemo</td><td>true</td><td>≥ v.0.0.31</td></tr><tr><td>TxTypeSmartContractExecution</td><td>true</td><td>≥ v.0.0.31</td></tr></tbody></table>

**Parameters**

{% tabs %}
{% tab title="TxTypeLegacy" %}
TxTypeLegacyTransaction 은 기존에 Kaia(Klaytn)에 존재했던 거래 유형을 나타냅니다.

* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소 (컨트랙트 주소 또는 일반 계정 주소)
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice`\<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
* `data` \<string> - 실행할 스마트 컨트랙트의 데이터 또는 빈 값. 일반 전송의 경우 `0x`
  {% endtab %}

{% tab title="TxTypeValueTransfer" %}
TxTypeValueTransfer 는 사용자가 KLAY 를 전송할 때 사용되는 트랜잭션입니다.

* `typeInt` \<number> - 8(TxTypeValueTransfer) or 9(TxTypeFeeDelegatedValueTransfer) or 10(TxTypeFeeDelegatedValueTransferWithRatio)
* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice` \<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
* `feePayer` \<string> - 수수료를 대납할 계정의 주소. typeInt 가 9 또는 10 일 때 필요.
* `feeRatio` \<string> - 수수료 대납자의 수수료 비율. 1\~99 사이의 값을 HexString 형식으로 입력. typeInt가 10 일 때 필요.
  {% endtab %}

{% tab title="TxTypeValueTransferMemo" %}
TxTypeValueTransferMemo 는 사용자가 특정 메세지와 함께KLAY 를 전송할 때 사용되는 트랜잭션 입니다.

* `typeInt` \<number> - 16(TxTypeValueTransfer) or 17(TxTypeFeeDelegatedValueTransfer) or 18(TxTypeFeeDelegatedValueTransferWithRatio)
* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice` \<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
* `input` \<string> - 트랜잭션과 함께 전송되는 메세지. Hex string 형식으로 입력.
* `feePayer` \<string> - 수수료를 대납할 계정의 주소. typeInt 가 17 또는 18 일 때 필요.
* `feeRatio` \<string> - 수수료 대납자의 수수료 비율. 1\~99 사이의 값을 HexString 형식으로 입력. typeInt가 18 일 때 필요.
  {% endtab %}

{% tab title="TxTypeSmartContractExecution" %}
TxTypeSmartContractExecution 은 스마트 컨트랙트 실행을 위한 트랜잭션입니다.

* `typeInt` \<number> - 48(TxTypeValueTransfer) or 49(TxTypeFeeDelegatedValueTransfer) or 50(TxTypeFeeDelegatedValueTransferWithRatio)
* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소 (컨트랙트 주소)
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice` \<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
* `input` \<string> - 트랜잭션과 함께 전송되는 데이터. Hex string 형식으로 입력.
* `feePayer` \<string> - 수수료를 대납할 계정의 주소. typeInt 가 49 또는 50 일 때 필요.
* `feeRatio` \<string> - 수수료 대납자의 수수료 비율. 1\~99 사이의 값을 HexString 형식으로 입력. typeInt가 50 일 때 필요.
  {% endtab %}
  {% endtabs %}

**Returns**

* `Promise<Object>`
  * `raw <string>` - 직렬화된 트랜잭션
  * `tx <Object>` - 서명이 포함된 트랜잭션 오브젝트.

**Example**

<pre class="language-typescript"><code class="lang-typescript"><strong>const params = {
</strong>      typeInt: 49,       //TxTypeFeeDelegatedSmartContractExecution
      from: senderAddress,
      to: '0x4dbccb64e9f7b4df4263d8e3b93c89ae406fd8e5',
      input: '0x45773e4e'
      gas: '0x15f90',
      gasPrice: '0x5d21dba00',
      feePayer: feePayerAddress,
}

const {raw, tx} = await wepinProvider.request({
      method: 'kaia_signTransaction',
      params: [params]
})


const decodedTx = caver.transaction.decode(raw)
const signedTx = await caver.wallet.signAsFeePayer(
      feePayerAddress,
      decodedTx as FeeDelegatedTransaction
)
const txId = await caver.rpc.klay.sendRawTransaction(
      signedTx.getRawTransaction()
)
</code></pre>

***

#### eth\_sendTransaction / klay\_sendTransaction / kaia\_sendTransaction

주어진 매개변수로 트랜잭션을 구성하고 사용자의 개인키로 트랜잭션에 서명하여 네트워크에 전송합니다.&#x20;

sendTransaction 은 FeeDelegated 를 지원하지 않습니다.

**Supported Tx Type**

<table><thead><tr><th width="300">TxType</th><th>Version</th></tr></thead><tbody><tr><td>TxTypeLegacy</td><td></td></tr><tr><td>TxTypeValueTransfer</td><td>≥ v.0.0.31</td></tr><tr><td>TxTypeValueTransferMemo</td><td>≥ v.0.0.31</td></tr><tr><td>TxTypeSmartContractExecution</td><td>≥ v.0.0.31</td></tr></tbody></table>

**Parameters**

{% tabs %}
{% tab title="TxTypeLegacy" %}
TxTypeLegacyTransaction 은 기존에 Kaia(Klaytn)에 존재했던 거래 유형을 나타냅니다.

* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소 (컨트랙트 주소 또는 일반 계정 주소)
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice`\<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
* `data` \<string> - 실행할 스마트 컨트랙트의 데이터 또는 빈 값. 일반 전송의 경우 `0x`
  {% endtab %}

{% tab title="TxTypeValueTransfer" %}
TxTypeValueTransfer 는 사용자가 KLAY 를 전송할 때 사용되는 트랜잭션입니다.

* `typeInt` \<number> - 8
* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice` \<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
  {% endtab %}

{% tab title="TxTypeValueTransferMemo" %}
TxTypeValueTransferMemo 는 사용자가 특정 메세지와 함께KLAY 를 전송할 때 사용되는 트랜잭션 입니다.

* `typeInt` \<number> - 16
* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice` \<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
* `input` \<string> - 트랜잭션과 함께 전송되는 메세지. Hex string 형식으로 입력.
  {% endtab %}

{% tab title="TxTypeSmartContractExecution" %}
TxTypeSmartContractExecution 은 스마트 컨트랙트 실행을 위한 트랜잭션입니다.

* `typeInt` \<number> - 48
* `from` \<string> - 트랜잭션을 보내는 계정의 주소. 실제 서명자의 주소와 다르면 에러 발생.
* `to` \<string> - 트랜잭션의 수신자 주소 (컨트랙트 주소)
* `gas` \<string> - 트랜잭션 실행에 필요한 최대 가스량. Hex string 형식으로 입력.
* `gasPrice` \<string> - 트랜잭션에 지불할 가스 비용. Hex string 형식으로 입력.
* `value` \<string> - 트랜잭션과 함께 전송되는 Klay 값. Hex string 형식으로 입력.
* `input` \<string> - 트랜잭션과 함께 전송되는 데이터. Hes string 형식으로 입력.
  {% endtab %}
  {% endtabs %}

**Returns**

* `Promise<string>` - 트랜잭션 해시

**Example**

```typescript
const params = {
      typeInt: 8,       //TxTypeValueTransfer
      from: senderAddress,
      to: toAddress,
      value: '0x1234'
      gas: '0x15f90',
      gasPrice: '0x5d21dba00'
}

const txId = await wepinProvider.request({
      method: 'kaia_sendTransaction',
      params: [params]
})
```

***

#### eth\_sign / klay\_sign / kaia\_sign

EIP-191 방식으로 message 를 서명합니다.

**Parameters**

* `<array>`
  * `<string>` - sign 하는 계정의 주소(Public Key)
  * `<string>` - sign 하려는 message

**Returns**

* `Promise<string>` - 서명 값(hex string)

**Example**

```typescript
const message = 'Hello World'

const signature = await wepinProvider.request({
      method: 'kaia_sign',
      params: [signerAddress, message]
})
```

***

#### personal\_sign

EIP-191 방식으로 message 를 서명합니다.

**Parameters**

* `<array>`
  * `<string>` - sign 하는 계정의 주소(Public Key)
  * `<string>` - sign 하려는 message

**Returns**

* `Promise<string>` - 서명 값(hex string)

**Example**

```typescript
const message = 'Hello World'

const signature = await wepinProvider.request({
      method: 'personal_sign',
      params: [signerAddress, message]
})
```

***

#### eth\_signTypedData\_v1 / klay\_signTypedData\_v1

EIP-712 v1 형식의 데이터를 서명합니다.

**Parameters**

* `<array>`
  * `<string>` - sign 하는 계정의 주소(Public Key)
  * `<string>` - sign 하려는 message

**Returns**

* `Promise<string>` - 서명 값(hex string)

**Example**

```typescript
const signature = await wepinProvider.request({
      method: 'kaia_signTypedData_v1',
      params: [signerAddress, msgParamsV1 ]
})
```

***

#### eth\_signTypedData\_v3 / klay\_signTypedData\_v3

EIP-712 v3 형식의 데이터를 서명합니다.

**Parameters**

* `<array>`
  * `<string>` - sign 하는 계정의 주소(Public Key)
  * `<string>` - sign 하려는 message

**Returns**

* `Promise<string>` - 서명 값(hex string)

**Example**

```typescript
const signature = await wepinProvider.request({
      method: 'kaia_signTypedData_v3',
      params: [signerAddress, msgParamsV3 ]
})
```

***

#### eth\_signTypedData\_v4 / klay\_signTypedData\_v4

EIP-712 v4 형식의 데이터를 서명합니다.

**Parameters**

* `<array>`
  * `<string>` - sign 하는 계정의 주소(Public Key)
  * `<string>` - sign 하려는 message

**Returns**

* `Promise<string>` - 서명 값(hex string)

**Example**

```typescript
const signature = await wepinProvider.request({
      method: 'kaia_signTypedData_v4',
      params: [signerAddress, msgParamsV4 ]
})
```

그 외 Kaia 네트워크의 자세한 내용은 아래 링크를 참고하세요.

{% embed url="<https://docs.kaia.io/references/json-rpc/references/>" %}


# Solana Provider

@solana/web3.js를 Wepin Provider와 함께 사용하면 Solana 블록체인과 상호작용 할 수 있습니다.&#x20;

## 지원 네트워크 <a href="#supported-networks" id="supported-networks"></a>

<table><thead><tr><th width="172.33333333333331">Chain ID</th><th>Network Name</th><th>Network Variable</th></tr></thead><tbody><tr><td>solana:mainnet</td><td>Solana Mainnet</td><td>solana</td></tr><tr><td>solana:devnet</td><td>Solana Devnet</td><td>solana-devnet</td></tr></tbody></table>

## 설치(Install)

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

```bash
npm install @wepin/provider-js
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/provider-js
```

{% endtab %}
{% endtabs %}

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와 같이 WepinProvider 인스턴스를 초기화합니다. 이렇게 하면 WepinProvider 를 사용할 수 있게 됩니다.

<pre class="language-javascript"><code class="lang-javascript"><strong>// 1. 패키지 import
</strong>import { WepinProvider } from '@wepin/provider-js'
<strong>
</strong>// 2. 초기화
const WepinProvider = new WepinProvider({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-app-key',
})
</code></pre>

***

## 초기화하기 <a href="#initialization" id="initialization"></a>

Wepin Provider를 초기화하는 방법입니다.&#x20;

## init

```javascript
await wepinProvider.init(attributes?)
```

### **Parameters**

* `attributes` \<object> **optional**
  * `defaultLanguage`: 위젯의 기본 설정 언어. 현재 지원하는 언어는 `en`, `ko` , `ja`입니다.
  * `defaultCurrency`: 위젯의 기본 통화 설정. 현재 지원하는 통화는 `USD`, `KRW`, `JPY` 입니다.

### **Return value**

* `Promise`\<void>

### **Example**

```javascript
await wepinProvider.init({
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
})
```

***

## isInitialized

WepinProvider 가 정상적으로 초기화 되었는지 확인할 수 있습니다.&#x20;

```javascript
wepinProvider.isInitialized()
```

### **Parameters**

* `<void>`

### **Return value**

* `<boolean>`\
  init이 정상적으로 잘 된 경우 <mark style="color:orange;">`true`</mark> , 실패한 경우 <mark style="color:orange;">`false`</mark> 를 반환합니다.

### **Example**

```javascript
if(wepinProvider.isInitialized()) {
  console.log('wepinProvider is initialized!')
}
```

***

## changeLanguage

위젯의 언어와 통화를 변경할 수 있습니다.

```javascript
wepinProvider.changeLanguage(attributes)
```

### **Parameters**

* `attributes` \<object>
  * `language` \<string>\
    위젯에 표시될 언어를   지정합니다. 현재 지원하는 언어는 `en`, `ko`, `ja` 3가지 입니다.
  * `currency` \<string>\
    위젯에 표시될 통화를  지정합니다. 현재 지원하는 통화는 `USD`, `KRW`, `JPY` 3가지 입니다.

### **Return value**

* \<boolean>\
  init이 정상적으로 잘 된 경우 <mark style="color:orange;">`true`</mark> , 실패한 경우 <mark style="color:orange;">`false`</mark> 를 반환합니다.

### **Example**

```javascript
if(wepinProvider.isInitialized()) {
  console.log('wepinProvider is initialized!')
}
```

***

## 메서드(Method)

Wepin Provider 초기화 후에 메소드를 사용할 수 있습니다.

## getProvider

Network에 해당하는 프로바이더를 반환합니다.

```jsx
await wepinProvider.getProvider(network)
```

### **Parameters**

* `network` \<string> \
  위핀이 지원하는 Provider의 Network Variable 값으로, Solana Mainnet의 경우 "solana" 입니다. Network Variable은 소문자로 입력해야 합니다. 전체 목록은 [Solana Provider 지원 네트워크](/widget-integration/web-javascript-sdk/provider/solana-provider#undefined)에서 확인하세요.

### **Return value**

* `Promise`\<BaseProvider> - solana provider

### **Example**

```javascript
const provider = await wepinProvider.getProvider('solana')
```

***

## finalize

WepinProvider 사용을 종료합니다.

```javascript
wepinProvider.finalize()
```

### **Parameters**

* `<void>`

### **Return value**

* `<void>`

### **Example**

```javascript
wepinProvider.finalize()
```

***

## request

Solana 블록체인과 상호작용할 수 있도록 JSON-RPC 요청을 보낼 수 있습니다.

### connect

위핀 지갑에 연결하여 사용자의 허가를 받아 계정의 주소(Public Key)를 공유합니다. 연결이 승인되면 애플리케이션은 메시지 서명이나 트랜잭션 요청을 할 수 있습니다.

#### Parameters

* `<void>`

#### Return value

* `Promise`\<object>
  * `publicKey`\<string> - Solana 계정의 Address(Public Key)

#### Example

```typescript
await wepinProvider.request({
    method: 'connect',
    params: [],
})
```

***

### signTransaction

직렬화된 트랜잭션을 서명합니다. 입력으로 hex string으로 변환된 트랜잭션을 받고, 서명된 트랜잭션을 반환합니다.

#### Parameters

* `<object>`
  * `transaction` \<string> - 직렬화된 트랜잭션을 hex string으로 변환한 값

#### Return value

* `Promise` \<Transaction> - 서명이 포함된 Transaction

#### Example

<pre class="language-typescript"><code class="lang-typescript"><strong>import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js'
</strong>
const transaction = new Transaction()
const { value } = await getBlock()
transaction.add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey(selectedAccount),
    toPubkey: new PublicKey(toAddress),
    lamports: parseFloat(toAmount) * 1000000000,
  })
)

transaction.recentBlockhash = value.blockhash
transaction.feePayer = new PublicKey(selectedAccount.value)

await wepinProvider.request({
    method: 'signTransaction',
    params: { transaction: _toHexString(transaction.serializeMessage()) },
})
</code></pre>

***

### signAndSendTransaction

직렬화된 트랜잭션에 서명하고 Solana 네트워크에 제출합니다. 트랜잭션의 서명(Tx ID)을 반환합니다.

#### Parameters

* `<object>`
  * `transaction` \<string> - 직렬화된 트랜잭션을 hex string으로 변환한 값

#### Return value

* `Promise` \<object>
  * `signature` \<TransactionSignature> - 성공적으로 전송된 트랜잭션의 고유 서명(signature) 을 반환합니다.

#### Example

```typescript
import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js'

const transaction = new Transaction()
const { value } = await getBlock()
transaction.add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey(selectedAccount),
    toPubkey: new PublicKey(toAddress),
    lamports: parseFloat(toAmount) * 1000000000,
  })
)

transaction.recentBlockhash = value.blockhash
transaction.feePayer = new PublicKey(selectedAccount.value)

await wepinProvider.request({
    method: 'signAndSendTransaction',
    params: { transaction: _toHexString(transaction.serializeMessage()) },  //transaction.serializeMessage() 의 return 값은 Buffer 로 hex string 으로 변환해야 합니다.
})
```

***

### signAllTransactions

직렬화된 여러개의 트랜잭션을 한번에 서명합니다. 입력으로 hex string으로 변환된 트랜잭션 배열을 받고, 서명된 트랜잭션 배열을 반환합니다.

#### Parameters

* `<object>`
  * `transactions` \<Array\<string>> - 직렬화된 트랜잭션 데이터 배열. 각 트랜잭션은 Solana의 `Transaction` 또는 `VersionedTransaction` 객체를 직렬화 한 후, 해당 데이터를 Hexadecimal(16진수) 문자열로 변환한 값입니다.

#### Return value

* `Promise` \<Array\<Transaction>> - 서명이 포함된 Transaction 배열

#### Example

```typescript
import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js'

const transaction = new Transaction()
const { value } = await getBlock()
transaction.add(
  SystemProgram.transfer({
    fromPubkey: new PublicKey(selectedAccount),
    toPubkey: new PublicKey(toAddress),
    lamports: parseFloat(toAmount) * 1000000000,
  })
)

transaction.recentBlockhash = value.blockhash
transaction.feePayer = new PublicKey(selectedAccount.value)

await wepinProvider.request({
    method: 'signAndSendTransaction',
    params: { transactions: _toHexString(transaction.serializeMessage()) },  //transaction.serializeMessage() 의 return 값은 Buffer 로 hex string 으로 변환해야 합니다.
})
```

***

### signMessage

특정 계정의 주소(Public Key)와 메시지에 서명합니다. 입력으로 계정 주소와 서명할 메시지를 받습니다.

{% hint style="info" %}
signAllTransactions을 이용하기 위해서는 사전에 사용 등록이 필요합니다. Wepin에 [문의](https://mail.google.com/mail/u/0/?to=wepin.contact@iotrust.kr\&su=%EB%AC%B8%EC%9D%98%ED%95%98%EA%B8%B0%5BGeneral%5D\&body=%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94.+%EA%B4%80%EB%A0%A8+%EB%AC%B8%EC%9D%98+%EC%82%AC%ED%95%AD%EC%9D%84+%EC%9E%85%EB%A0%A5%ED%95%B4%EC%A3%BC%EC%84%B8%EC%9A%94.\&fs=1\&tf=cm)해주세요. 한번에 sign 할 수 있는 Transaction 개수는 최대 10개 입니다.
{% endhint %}

#### Parameters

* `<array>`
  * `<string>` - sign 하는 계정의 주소(Public Key)
  * `<string>` - sign 하려는 message

#### Return value

* `Promise` \<string> - 서명 값(hex string)

#### Example

```typescript
await wepinProvider.request({
    method: 'signMessage',
    params: [selectedAccount, data],
})
```

***

### changeNetwork

네트워크를 변경합니다. Solana Mainnet 또는 Devnet으로 전환할 수 있으며, 변경된 네트워크의 주소, 네트워크 이름 및 chain ID를 반환합니다.

#### Parameters

* `<object>`
  * `chainId` \<string> - 변경할 network 의 chainId. solana chain(solana:mainnet, solana:devnet) 만 가능

#### Return value

* `Promise` \<object>
  * `address` \<string> - 변경된 네트워크의 계정 주소 (Public Key)
  * `network` \<string> - 변경된 네트워크의 이름
  * `chainId` \<string> - 변경된 네트워크의 chain ID

#### Example

```typescript
await wepinProvider.request({
    method: 'changeNetwork',
    params: [{ chainId: 'solana:devnet' }],
})
```

***

## 기타 메서드 예제 <a href="#other-method-example" id="other-method-example"></a>

위핀에서 제공하는 메서드 외에 Solana RPC HTTP Methods 도 사용 가능합니다.

### [getAccountInfo](https://solana.com/docs/rpc/http/getaccountinfo)

Parameter 로 들어온 Pubkey 와 연결된 모든 계정의 정보를 반환합니다.

#### Parameters

* `PubKey` \<string> - 조회할 계정의 주소 (base-58로 인코딩 된 PubKey)
* `<object>`
  * `commitment` \<string> ***optional***
    * Default Commitment - **finalize**
    * **processed** - node가 처리한 가장 최신 블록을 조회. 이 블록은 아직 확정되지 않았으며, 변경될 가능성이 있음
    * **confirmed** - 클러스터의 과반이 승인한 최신 블록을 조회
    * **finalized** - 클러스터의 과반이 최종적으로 확정한 최신 블록
  * `encoding` \<string> ***optional***
    * Account data 의 인코딩 형식
    * base58, base64, base64+zstd, jsonParsed
  * `dataSlice` \<object> ***optional -*** base58, base64, base64+zstd 인코딩일 때만 사용 가능
    * `length` \<usize> - 반환할 바이트 수
    * `offset` \<usize> - 읽기를 시작할 바이트 offset
  * `minContextSlot` \<number> ***optional***
    * 요청을 실행할 수 있는 최소 슬롯

#### Return value

* `context` \<object>
  * `apiVersion` \<string> - solana-core version
  * `slot` \<number> - 작업이  실행된 slot
* `value` \<object> ***nullable***
  * `lamports` \<u64> - 계정 잔액
  * `owner` \<string> - 해당 계정을 소유하고 관리하는 프로그램의  주소 (base-58로 인코딩 된 PubKey)
  * `data` <\[string, encoding] | object> - 계정과 관련된 데이터&#x20;
  * `executable` \<boolean> - 계정에 프로그램이 포함되어있는지(읽기전용  여부포함) 나타내는 불리언 값
  * `rentEpoch` \<u64> - 이 계정이 다음  스토리지 비용을 지불해야 하는 epoch
  * `size` \<u64> - 계정 데이터의 크기

#### Example

```typescript
await wepinProvider.request({
    method: 'getAccountInfo',
    params: [
        "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
    ],
})
```

```json
//return data
{
  "context": {
    "apiVersion": "2.0.14",
    "slot": 338510838
  },
  "value": {
    "data": "",
    "executable": false,
    "lamports": 14000000000,
    "owner": "11111111111111111111111111111111",
    "rentEpoch": 18446744073709552000,
    "space": 0
  }
}
```

***

### [getBalance](https://solana.com/docs/rpc/http/getbalance)

계정의 잔액을 반환합니다.

#### Parameters

* `Pubkey` \<string> - 잔액을 조회할 계정의 주소 (base-58로 인코딩 된 PubKey)
* \<object>
  * `commitment` \<string> ***optional***
    * Default Commitment - **finalize**
    * **processed** - node가 처리한 가장 최신 블록을 조회. 이 블록은 아직 확정되지 않았으며, 변경될 가능성이 있음.
    * **confirmed** - 클러스터의 과반이 승인한 최신 블록을 조회.
    * **finalized** - 클러스터의 과반이 최종적으로 확정한 최신 블록.
  * `minContextSlot` \<number> ***optional***
    * 요청을 실행할 수 있는 최소 슬롯

#### Return value

* `context` \<object>
  * `apiVersion` \<string> - solana-core version
  * `slot` \<number> - 작업이  실행된 slot
* `value` \<number> - 계정의 잔액

#### Example

```typescript
await wepinProvider.request({
    method: 'getAccountInfo',
    params: [
        "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
    ],
})
```

```json
//return data
{
  "context": {
    "apiVersion": "2.0.14",
    "slot": 338529622
  },
  "value": 14000000000
}
```

***

### [getLatestBlockhash](https://solana.com/docs/rpc/http/getlatestblockhash)

가장 최신 블록해시를 반환합니다.

#### Parameters

* \<object> ***optional***
  * `commitment` \<string> ***optional***
    * Default Commitment - **finalize**
    * **processed** - node가 처리한 가장 최신 블록을 조회. 이 블록은 아직 확정되지 않았으며, 변경될 가능성이 있음
    * **confirmed** - 클러스터의 과반이 승인한 최신 블록을 조회
    * **finalized** - 클러스터의 과반이 최종적으로 확정한 최신 블록
  * `minContextSlot` \<number> ***optional***
    * 요청을 실행할 수 있는 최소 슬롯

#### Return value

* `context` \<object>
  * `apiVersion` \<string> - solana-core version
  * `slot` \<number> - 작업이  실행된 slot
* `value` \<object>
  * `blockhash` \<string> - base-58로 인코딩 된 해시 값
  * `lastValidBlockHeight` \<number> - 해당 블록 해시가 유효한 마지막 블록 높이

#### Example

```typescript
await wepinProvider.request({
    method: 'getAccountInfo',
    params: [
        "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
    ],
})
```

```json
//return data
{
    "context": {
        "apiVersion": "2.0.14",
        "slot": 338534308
    },
    "value": {
        "blockhash": "8uJtPoFrdEqxFCA4zaBxBQXosZKvWWQYcWb9kZbF2hDW",
        "lastValidBlockHeight": 326729023
    }
}
```

***

### [getTokenAccountsByOwner](https://solana.com/docs/rpc/http/gettokenaccountsbyowner)

계정의 모든 SPL Token 계정 정보를 반환합니다.

#### Parameters

* `PubKey` \<string> - SPL Token Account 의 Owner 주소 (base-58로 인코딩 된 PubKey)
* \<object> - 조회할 SPL 토큰 계정에 대한 필터.  mint 와 programId 중 하나만 있으면 됨
  * `mint` \<string> - base-58로 인코딩 된 특정   토큰의 Mint Address
  * `programId` \<string> -  base-58로 인코딩 된 특정 프로그램의 ID
* \<object>
  * `commitment` \<string> ***optional***
    * Default Commitment - **finalize**
    * **processed** - node가 처리한 가장 최신 블록을 조회. 이 블록은 아직 확정되지 않았으며, 변경될 가능성이 있음
    * **confirmed** - 클러스터의 과반이 승인한 최신 블록을 조회
    * **finalized** - 클러스터의 과반이 최종적으로 확정한 최신 블록
  * `minContextSlot` \<number> ***optional***
    * 요청을 실행할 수 있는 최소 슬롯
  * `encoding` \<string> ***optional***
    * Account data 의 인코딩 형식
    * base58, base64, base64+zstd, jsonParsed
  * `dataSlice` \<object> ***optional -*** base58, base64, base64+zstd 인코딩일 때만 사용 가능
    * `length` \<usize> - 반환할 바이트 수
    * `offset` \<usize> - 읽기를 시작할 바이트 offset

#### Return value

* `context` \<object>
  * `apiVersion` \<string> - solana-core version
  * `slot` \<number> - 작업이  실행된 slot
* `value` \<Array\<object>>
  * `pubkey` \<string> - 조회 된 계정의 주소
  * `account` \<object> - 해당 계정의 정보
    * `lamports` \<u64> - 계정 잔액
    * `data` \<object> - 해당 계정과 연결된 Token state data
      * `parsed` \<object>
        * `info` \<object> - 계정 정보
          * `isNative` \<boolean> - 네이티브 계정 여부 표시. 일반적으로 false
          * `mint` \<string> - 해당 토큰 계정과 연결된 특정 토큰의 주소
          * `owner` \<string> - 해당 토큰 계정을 통제하는 사용자의 Solana 지갑 주소
          * `state` \<string> - 토큰 계정의 상태
          * `tokenAmount` \<object> - 토큰 계정의 잔액 정보
            * `amount` \<string> - 계정 내 보유량을 나타내는 숫자
            * `decimals` \<number> - 해당 토큰의 소수점 자수
            * `uiAmount` \<number> - 소수 형태의 토큰 잔액. **DEPRECATED**
            * `uiAmountString` \<string> - 문자열로 표시된 소수 형태의 토큰 잔액
        * `type` \<string> - info 의 유형. 이 경우 account
      * `program` \<string> - 해당 계정이 속한 프로그램
      * `space` \<number> - 계정 데이터의 크기. 바이트 단위로 표시
    * `executable` \<boolean> - 해당 계정이 실행 가능한지 여부
    * `owner` \<string> - 계정을 소유한 프로그램의 주소
    * `rentEpoch` \<u64> - 계정이 현재 임대 상태인 epoch
    * `size` \<u64> - 계정의 데이터 크기

#### Example

```typescript
await wepinProvider.request({
    method: 'getTokenAccountsByOwner',
    params: [
      "A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd",
      {
        "mint": "BejB75Gmq8btLboHx7yffWcurHVBv5xvKcnY1fBYxnvf"
      },
      {
        "encoding": "jsonParsed"
      }
    ]
})
```

```json
//return data
{
    "context": {
      "apiVersion": "2.0.8",
      "slot": 329669901
    },
    "value": [
      {
        "account": {
          "data": {
            "parsed": {
              "info": {
                "isNative": false,
                "mint": "BejB75Gmq8btLboHx7yffWcurHVBv5xvKcnY1fBYxnvf",
                "owner": "A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd",
                "state": "initialized",
                "tokenAmount": {
                  "amount": "10000000000000",
                  "decimals": 9,
                  "uiAmount": 10000,
                  "uiAmountString": "10000"
                }
              },
              "type": "account"
            },
            "program": "spl-token",
            "space": 165
          },
          "executable": false,
          "lamports": 2039280,
          "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
          "rentEpoch": 18446744073709551615,
          "space": 165
        },
        "pubkey": "5HvuXcy57o41qtGBBJM7dRN9DS6G3jd9KEhHt4eYqJmB"
      }
    ]
}
```

***

### [getTokenAccountBalance](https://solana.com/docs/rpc/http/gettokenaccountbalance)

SPL Token 계정의 잔액을 반환합니다.

#### Parameters

* `PubKey` \<string> -  ATA(Associated Token Account) 주소 ( base-58로 인코딩 된 PubKey)

#### Return value

* `context` \<object>
  * `apiVersion` \<string> - solana-core version
  * `slot` \<number> - 작업이 실행된 slot
* `value` \<object>
  * `amount` \<string> - 해당 토큰 계정의 잔액
  * `decimals` \<number> - 해당 토큰의 소수점 자릿수
  * `uiAmount` \<number> ***nullable*** - 소수 형태의 토큰 잔액. **DEPRECATED**
  * `uiAmountString` \<string> - 문자열로 표시된 소수 형태의 토큰 잔액

#### Example

```typescript
await wepinProvider.request({
    method: 'getTokenAccountBalance',
    params: [
        "7fUAJdStEuGbc3sM84cKRL6yYaaSstyLSU4ve5oovLS7"
    ],
})
```

```json
{
    "context": {
      "slot": 1114
    },
    "value": {
      "amount": "9864",
      "decimals": 2,
      "uiAmount": 98.64,
      "uiAmountString": "98.64"
    }
}
```

그 외 Solana 네트워크 프로바이더의 자세한 내용은 아래 링크를 참고하세요.

{% embed url="<https://solana.com/docs/rpc/http>" %}


# Wagmi Connector

위핀에서는 wagmi를 이용한 지갑 연결을 지원하고 있습니다. <mark style="color:blue;">`@wepin/wagmi-connector`</mark>로 wagmi interface를 통한 위핀 지갑 연동을 손쉽게 할 수 있습니다. 이에 대한 자세한 내용은 아래 wagmi 공식 사이트에서 확인 가능합니다.

{% embed url="<https://wagmi.sh/>" %}

## 지원 네트워크 <a href="#supported-networks" id="supported-networks"></a>

{% hint style="info" %}
목록에 필요한 블록체인이 없나요? [위핀 팀에 요청](https://wepinwallet.typeform.com/WEPIN-Wallet)하여 별도의 비용 없이 블록체인을 추가할 수 있습니다.
{% endhint %}

<table><thead><tr><th width="172.33333333333331">Chain ID</th><th>Network Name</th><th>Network Variable</th></tr></thead><tbody><tr><td>1</td><td>Ethereum Mainnet</td><td>ethereum</td></tr><tr><td>5</td><td>Ethereum Goerli Testnet</td><td>evmeth-goerli</td></tr><tr><td>8217</td><td>Kaia Mainnet</td><td>klaytn</td></tr><tr><td>1001</td><td>Kaia Kairos Testnet</td><td>klaytn-testnet</td></tr><tr><td>19</td><td>Songbird Canary Network</td><td>evmsongbird</td></tr><tr><td>137</td><td>Polygon Mainnet</td><td>evmpolygon</td></tr><tr><td>2731</td><td>TimeNetwork Testnet</td><td>evmtime-elizabeth</td></tr><tr><td>11155111</td><td>Ethereum Sepolia Testnet</td><td>evmeth-sepolia</td></tr><tr><td>80002</td><td>Polygon Amoy Testnet</td><td>evmpolygon-amoy</td></tr></tbody></table>

## 설치(Install)

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

```bash
npm install wagmi viem @wepin/wagmi-connector
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add wagmi viem @wepin/wagmi-connector
```

{% endtab %}
{% endtabs %}

<mark style="color:blue;">`@wepin/wagmi-connector`</mark> 는 <mark style="color:blue;">`wagmi`</mark> <mark style="color:blue;">`viem`</mark> 과 함께 설치해서 사용합니다.&#x20;

{% hint style="warning" %}
`@wepin/wagmi-connector`는 `@wepin/sdk-js 와 함께 사용하지 않습니다.`
{% endhint %}

## 시작하기 <a href="#getting-started" id="getting-started"></a>

### 패키지 import  <a href="#import-packages" id="import-packages"></a>

```javascript
import { WepinConnector } from '@wepin/wagmi-connector'
import type { WepinConnectorOptions } from '@wepin/wagmi-connector' 
```

### 연결 옵션 정의 <a href="#define-connection-options" id="define-connection-options"></a>

<mark style="color:blue;">`WepinConnectorOptions`</mark>는 wagmi와 위핀 지갑의 연동을 위해 필요한 속성 값입니다.&#x20;

#### WepinConnectorOptions \<objec&#x74;*>*

* `appId`: \<strin&#x67;*>*\
  앱 등록 시 할당 받은 ID
* `appKey`: \<strin&#x67;*>*\
  앱 등록 시 할당 받은 키 값
* `defaultChainId`**:<**&#x4E;umbe&#x72;*>* **optional**
  * 지갑을  연결하기 위한 기본 Chain ID.
  * 값을 지정하지 않으면 앱에 등록된 첫 번째 네트워크로 자동 연결됩니다.&#x20;
* **attributes**: *<*&#x49;WepinSDKAttributes> **optional**[\
  @wepin/sdk-js](https://github.com/WepinWallet/wepin-web-sdk-v1/tree/main/packages/sdk) 에 선언된 위핀 연결 속성 값&#x20;
  * type: \<strin&#x67;*>*\
    위젯이 초기화될때의 Display 타입 설정, 현재 지원하는 타입은  `hide`  입니다.
  * defaultLanguage: \<strin&#x67;*>*\
    위젯 기본 언어 설정, 기본 값은 `ko`입니다. 현재 지원하는 언어는 `en`, `ko` 2가지 입니다.
  * defaultCurrenc&#x79;**:** \<strin&#x67;*>*\
    위젯 기본 통화 설정, 기본 값은 `KRW`입니다. 현재 지원하는 통화는 `USD`, `KRW` 2가지 입니다.
  * loginProvider&#x73;**:** \<string\[]*>* **optional**

    로그인 프로바이더 리스트 입니다.   현재 지원하는 프로바이더는 `google`, `apple` , `naver`, `discord` 이렇게 4가지 입니다.  필요한 로그인 프로바이더만 정의해서 사용하세요. &#x20;

    * 이 값을 지정하지 않으면  제공하는 모든 프로바이더를 이용할 수 있습니다.
    * 빈 배열이 제공된 경우, 이메일 로그인 기능만 사용 가능합니다. ([@wepin/sdk-js](https://github.com/WepinWallet/wepin-web-sdk-v1/tree/main/packages/sdk) v0.0.3 버전 이상부터  지원)

```javascript
const connectorOptions: WepinConnectorOptions = {
  appId: 'YOUR_APP_ID',
  appKey: 'YOUR_APP_KEY',
  defaultChainId: 1, // optional
  attributes: {  // optional
    type: 'hide',
    defaultLanguage: 'ko',
    defaultCurrency: 'krw',
    loginProviders: ['google', 'apple'] //optional
  }
}
```

### wagmi config에 WepinConnector 추가 <a href="#add-wepinconnector-to-wagmi-config" id="add-wepinconnector-to-wagmi-config"></a>

```javascript
const config = createConfig({
  connectors: [
    // ... Other connectors,
    new WepinConnector({
      chains,
      options: connectorOptions,
    }),
  ],
  publicClient,
})
```

### \`WagmiConfig\`로 app 래핑 <a href="#wrap-app-with-wagmiconfig" id="wrap-app-with-wagmiconfig"></a>

```javascript
import { WagmiConfig } from 'wagmi'

function App() {
  return (
    <WagmiConfig config={config}>
      <YourRoutes />
    </WagmiConfig>
  )
}
```

## 확인하기 <a href="#verification" id="verification"></a>

이후 `wagmi`와의 자세한 연동 방법은 아래 wagmi 가이드에서 확인하세요.&#x20;

{% embed url="<https://wagmi.sh/react/getting-started>" %}

### 예제 <a href="#examples" id="examples"></a>

<mark style="color:blue;">`wepin-wagmi-connector`</mark>를 사용한 예제는 아래 깃허브에서 확인 가능합니다.

{% embed url="<https://github.com/WepinWallet/wepin-wagmi-connector/tree/main_v1/example>" %}


# 월렛 어댑터


# Solana Wallet Adapter

@wepin/solana-wallet-adapter 는 Solana 블록체인과 상호작용하기 위해 설계된 JavaScript SDK 입니다.

## 지원 네트워크 <a href="#supported-networks" id="supported-networks"></a>

<table><thead><tr><th width="172.33333333333331">Chain ID</th><th>Network Name</th><th>Network Variable</th></tr></thead><tbody><tr><td>solana:mainnet</td><td>Solana Mainnet</td><td>solana</td></tr><tr><td>solana:devnet</td><td>Solana Devnet</td><td>solana-devnet</td></tr></tbody></table>

## 설치(Install)

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

```bash
npm install @wepin/solana-wallet-adapter
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/solana-wallet-adapter
```

{% endtab %}
{% endtabs %}

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와 같이 WepinProvider 인스턴스를 초기화합니다. 이렇게 하면 WepinProvider 를 사용할 수 있게 됩니다.

<pre class="language-javascript"><code class="lang-javascript"><strong>// 1. 패키지 import
</strong>import { WepinSolanaWalletAdapter } from "@wepin/solana-wallet-adapter";

<strong>
</strong>// 2. 초기화
const wepinSolanaWalletAdapter = new WepinSolanaWalletAdapter({
    appId: 'your-wepin-app-id',
    appKey: 'your-wepin-app-key',
    network: 'solana',
    attributes: {
        defaultCurrency: 'KRW', 
        defaultLanguage: 'ko'
    }
})
</code></pre>

```jsx
//@solana/wallet-adapter-react 와 함께 사용하시는 경우
const wallets = useMemo(
    () => [
      new WepinSolanaWalletAdapter({
        appId: 'your-wepin-app-id',
        appKey: 'your-wepin-app-key',
        network: 'solana',
        attributes: {
            defaultCurrency: 'KRW', 
            defaultLanguage: 'ko'
        }
      })
    ],
    []
  );
```

### **Parameters**

* WepinWalletAdapterConfig \<Object>
  * `appId` \<string>\
    앱 등록 후 할당받은 App ID
  * `appKey` \<string>\
    앱 등록 후 할당받은 App Key
  * `network` \<string> **optional**\
    위핀이 지원하는 월렛어댑터의 Network Variable 값으로, Solana Mainnet의 경우 "solana" 입니다. Network Variable은 소문자로 입력해야 합니다. 전체 목록은 [Wepin Solana Wallet Adapter 지원 네트워크](#supported-networks)에서 확인하세요.\
    기본값은 "solana"입니다.
  * `attributes` \<object> **optional**
    * `defaultLanguage`: 위젯의 기본 설정 언어. 현재 지원하는 언어는 `en`, `ko` , `ja`입니다. 기본값은 `en` 입니다.
    * `defaultCurrency`: 위젯의 기본 통화 설정. 현재 지원하는 통화는 `USD`, `KRW`, `JPY` 입니다. 기본값은 `USD` 입니다.

## 메소드(Method)

Wepin Solana Wallet Provider 에서 사용할 수 있는 메소드는 다음과 같습니다.

### connect

Wepin Wallet 과 연결하고 사용자의 Public Key 를 가져옵니다.

#### parameters

* `<void>`

#### Return Value

Promise\<void>

* 연결 성공 시, Wallet Adapter의 connected 값이 true 로 설정되고, `publicKey` 속성에 사용자의 Public Key 가 설정됩니다.

#### Example

```typescript
await walletSolanaWalletAdapter.connect()
const isConnected = walletSolanaWalletAdapter.connected    //연결 여부 확인
const publicKey = walletSolanaWalletAdapter.publicKey        //연결된 계정의 PublicKey
```

***

### signMessage

지정된 메시지를 사용자의 계정으로 서명합니다.

#### parameters

* `message` \<Uint8Array>\
  서명할 메시지

#### Return Value

* `Promise<Uint8Array>`\
  서명된 메시지&#x20;

#### Example

```typescript
const message = new TextEncoder().encode('Hello, Solana!');
const signedMessage = await wepinSolanaWalletAdapter.signMessage(message);
console.log(`Signed message as Uint8Array:`, signedMessage);
```

***

### signTransaction

Solana 트랜잭션 객체를 입력받아 서명합니다.

#### parameters

* `transaction` \<Transaction | VersionedTransaction>\
  서명할 Solana 트랜잭션 객체

#### Return Value

* `Promise<Transaction | VersionedTransaction>`\
  서명이 포함된 트랜잭션 객체

#### Example

```typescript
import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js';

const publicKey = wepinSolanaWalletAdapter.publicKey
// 트랜잭션 생성
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: new PublicKey('recipient-public-key'),
    lamports: 1000000,
  }),
);

// 최근 블록해시와 feePayer 설정
transaction.recentBlockhash = 'recent-blockhash';
transaction.feePayer = publicKey;

// 트랜잭션 서명
const signedTransaction = await wepinSolanaWalletAdapter.signTransaction(transaction);

console.log('Signed Transaction:', signedTransaction);

```

***

### sendTransaction

Solana 트랜잭션 객체를 입력 받아 서명하고 전송합니다.

#### parameters

* `transaction` \<Transaction | VersionedTransaction> - 서명 및 전송할 Solana 트랜잭션 객체
* `connection` Connection - Solana 네트워크와 상호작용하는 연결 객체
* `options` SendTransactinOptions - 트랜잭션 전송 시 필요한 추가 옵션 *optional*
  * `signers` - 추가 서명이 필요한 계정 배열 *optional*

#### Return Value

* `Promise<TransactionSignature>` - 성공적으로 전송된 트랜잭션의 고유 서명(signature) 을 반환합니다.

#### Example

```typescript
import { Connection, Transaction, SystemProgram, PublicKey } from '@solana/web3.js';

const connection = new Connection(umi.rpc.getEndpoint(), 'finalized')
const publicKey = wepinSolanaWalletAdapter.publicKey
// 트랜잭션 생성
const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: new PublicKey('recipient-public-key'),
    lamports: 1000000,
  }),
);

// 최근 블록해시와 feePayer 설정
transaction.recentBlockhash = 'recent-blockhash';
transaction.feePayer = publicKey;

// 트랜잭션 서명
const signature = await wepinSolanaWalletAdapter.sendTransaction(transaction, connection, {});

console.log('Signature:', signature );

```

***

### signAllTransactions

여러개의 Solana 트랜잭션 객체를 입력 받아 서명합니다.

{% hint style="info" %}
signAllTransactions을 이용하기 위해서는 사전에 사용 등록이 필요합니다. Wepin에 [문의](https://mail.google.com/mail/u/0/?to=wepin.contact@iotrust.kr\&su=%EB%AC%B8%EC%9D%98%ED%95%98%EA%B8%B0%5BGeneral%5D\&body=%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94.+%EA%B4%80%EB%A0%A8+%EB%AC%B8%EC%9D%98+%EC%82%AC%ED%95%AD%EC%9D%84+%EC%9E%85%EB%A0%A5%ED%95%B4%EC%A3%BC%EC%84%B8%EC%9A%94.\&fs=1\&tf=cm)해주세요. 한번에 sign 할 수 있는 Transaction 개수는 최대 10개 입니다.
{% endhint %}

#### parameters

* `Array<Transaction | VersionedTransaction>`\
  서명할 Solana 트랜잭션 객체 배열

#### Return Value

* `Promise<Array<Transaction | VersionedTransaction>>`\
  서명이 포함된 트랜잭션 객체 배열

#### Example

```typescript
import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js';

// 트랜잭션 서명
const signedTransactions = await wepinSolanaWalletAdapter.signAllTransactions(transactions);

console.log('Signed Transactions:', signedTransactions);

```

***

### disconnect

Wepin Wallet 연결을 해제합니다.

#### parameters

* `<void>`

#### Return Value

* `Promise<void>`

#### Example

```typescript
await wepinWallet.disconnect();
```


# Android: Java & Kotlin SDK

이 문서는 위핀 위젯을 Android에 통합하기 위한 절차를 설명합니다.


# 로그인

소셜 로그인과 같은 OAuth 인증 토큰 또는 이메일로 위핀에 로그인 하는 방법에 대한 안내 페이지입니다


# 설치

## 요구사항 <a href="#requirements" id="requirements"></a>

Android API 버전 <mark style="color:blue;">24</mark> 이상&#x20;

## 설치하기 <a href="#installation" id="installation"></a>

### WepinLoginLibrary를 .gradle에 추가하기  <a href="#add-wepinloginlibrary-to-.gradle" id="add-wepinloginlibrary-to-.gradle"></a>

프로젝트레벨의 build gradle 파일에 JitPack 레포지토리를 추가합니다.

```kts
 dependencyResolutionManagement {
     repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
     repositories {
         google()
         mavenCentral()
         maven("https://jitpack.io") // <= Add JitPack Repository
     }
 }
```

### WepinLoginLibrary를 dependencies에 추가하기 <a href="#add-wepinloginlibrary-to-dependencies" id="add-wepinloginlibrary-to-dependencies"></a>

앱의 build gradle 파일에 아래와 같이 추가 합니다. 버전은 사용하고자 하는 릴리즈 버전을 넣으면 됩니다.&#x20;

```kts
dependencies {
  // ...
  implementation("com.github.WepinWallet:wepin-android-sdk-login-v1:vX.X.X") 
}
```

### Permission 추가하기  <a href="#add-permission" id="add-permission"></a>

앱의 AndroidManifest에 아래와 같이 추가 합니다.

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

### Deep Link 설하기 <a href="#setting-up-deep-link" id="setting-up-deep-link"></a>

#### Deep Link scheme format : <mark style="color:blue;">`wepin. + Your Wepin App ID`</mark>

사용자 정의 스킴이 사용될 때, WepinLogin 라이브러리는 매니페스트 플레이스홀더를 통해 이 사용자 정의 스킴을 사용하여 모든 리디렉션을 쉽게 캡처하도록 구성할 수 있습니다.

앱의 build gradle 파일에 아래처럼 추가 합니다.&#x20;

```html
// For Deep Link => RedirectScheme Format : wepin. + Wepin App ID
android.defaultConfig.manifestPlaceholders = [
  'appAuthRedirectScheme': 'wepin.{{YOUR_WEPIN_APPID}}'
]
```

앱의 AndroidManifest 파일에 아래처럼 추가 합니다.&#x20;

```xml
<activity
  android:name="com.wepin.android.loginlib.RedirectUriReceiverActivity"
  android:exported="true">
  <intent-filter>
     <action android:name="android.intent.action.VIEW" />

     <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.BROWSABLE" />
     <data
      android:host="oauth2redirect"
      android:scheme="${appAuthRedirectScheme}" />
  </intent-filter>
</activity>
```

## 릴리즈  <a href="#release" id="release"></a>

릴리즈된 패키지 버전은 아래 깃허브에서 확인 가능합니다.

{% embed url="<https://github.com/WepinWallet/wepin-android-sdk-login-v1/releases>" %}


# 초기화하기

Wepin Android Login Library를 초기화하는 방법입니다.&#x20;

<pre class="language-kotlin"><code class="lang-kotlin"><strong>import com.wepin.android.loginlib.WepinLogin
</strong></code></pre>

WepinLogin 인스턴스를 생성하기전에 아래와 같이 앱의 Activity Context , 앱 등록 후 할당받은 App ID와 App Key를 WepinLoginOptions 객체에 전달해 주세요.

```kotlin
val wepinLoginOptions =  WepinLoginOptions(
            context = this,
            appId = "your-wepin-app-id",
            appKey = "your-wepin-app-key"
        )
```

앞서 생성한 WepinLoginOptions 를 전달하면서 WepinLogin 인스턴스를 생성해 주세요.

```kotlin
val wepinLogin = WepinLogin(wepinLoginOptions)
```

WepinLogin 인스턴스생성 후 `init` 메서드를 호출하여 초기화를 합니다.

```kotlin
wepinLogin.init()
```

### Example

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

```java
public class MainActivity extends ComponentActivity {
  private WepinLogin wepinLogin;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_example_main);

      String appId = "your-wepin-app-id";
      String appKey = "your-wepin-app-key";

      WepinLoginOptions wepinLoginOptions = new WepinLoginOptions(this, appId, appKey);
      wepinLogin = new WepinLogin(wepinLoginOptions, null);

      // Call initialize function
      CompletableFuture<Boolean> res = wepinLogin.init();
      res.whenComplete((infResponse, error) -> {
          if (error == null) {
              System.out.println("infResponse: " + infResponse);
          } else {
              // render error UI
          }
      });
  }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
class MainActivity : ComponentActivity() {
    private lateinit var wepinLogin: WepinLogin
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_example_main)

        val wepinLoginOptions =  WepinLoginOptions(
            context = this,
            appId = 'your-wepin-app-id',
            appKey = 'your-wepin-app-key'
        )
        wepinLogin = WepinLogin(wepinLoginOptions)
        // Call initialize function 
        val res: CompletableFuture<Void> = wepinLogin.init()
        res.whenComplete { infResponse, error ->
            if (error == null) {
                println("infResponse: $infResponse")
            } else {
                // render error UI
            }
    }
    // ...
}
```

{% endtab %}
{% endtabs %}

## isInitialized

`isInitialized`메서드를 이용해서 WepinLogin 인스턴스가 정상적으로 초기화 되었는지 확인할 수 있습니다. &#x20;

반환값은 아래와 같습니다.&#x20;

* \<Boolean>\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### Example

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

```java
if(wepinLogin.isInitialized()){
    // Success to initialize WepinLogin
}

```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
if(wepinLogin.isInitialized()){
    // Success to initialize WepinLogin
}
```

{% endtab %}
{% endtabs %}


# 메서드

Wepin Android Login Library에서 제공하는 메서드 입니다.

## loginWithOauthProvider

```java
wepinLogin.loginWithOauthProvider(params)
```

In-app browser가 열리고 OAuth provider에 로그인 합니다. Firebase 로그인 정보를 가져오려면 loginWithIdToken() 또는 loginWithAccessToken() 메서드를 호출해야 합니다.

**Parameters**

* `params` \<LoginOauth2Params>
  * `provider` <'google'|'naver'|'discord'|'apple'> - Provider for login
  * `clientId` \<String>

**Returns**

* CompletableFuture\<LoginOauthResult>
  * `provider` \<String> - login provider
  * `token` \<String> - accessToken (if provider is "naver" or "discord") or idToken (if provider is "google" or "apple")
  * `type` \<OauthTokenType> - type of token

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

```java
LoginOauth2Params loginOption = new LoginOauth2Params(
                    provider = "discord",
                    clientId = getString(R.string.default_discord_client_id),
                  )
CompletableFuture<LoginOauthResult> res = wepinLogin.loginWithOauthProvider(loginOption);
res.whenComplete((loginResponse, error) -> {
    if (error == null) {
        System.out.println("loginResponse: " + loginResponse);
        String privateKey = "private key for wepin id/access Token"
        // token sign 
        String sign = wepinLogin.getSignForLogin(loginResponse.token, privateKey)
        //call loginWithIdToken() or loginWithAccessToken()
    } else {
        // render error UI
        System.out.println("login error" + error.getMessage())
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val loginOption = LoginOauth2Params(
                  provider = "discord",
                  clientId = getString(R.string.default_discord_client_id),
                )
wepinLogin.loginWithOauthProvider(loginOption).whenComplete { loginResponse, error ->
  if (error == null) {
      // render logged in UI
      println(loginResponse)
      val privateKey = "private key for wepin id/access Token"
      // token sign 
      wepinLogin.getSignForLogin(loginResponse.token, privateKey)
      //call loginWithIdToken() or loginWithAccessToken()
  } else {
      println("login error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## signUpWithEmailAndPassword

```java
wepinLogin.signUpWithEmailAndPassword(params)
```

이메일과 비밀번호로 Wepin Firebase에 회원가입을 합니다. 가입되지 않은 사용자의 경우 검증 이메일이 전송되며, `REQUIRED_EMAIL_VERIFIED` 오류가 발생합니다. 이미 가입된 사용자의 경우, `EXISTED_EMAIL` 오류가 발생하며 [loginWithEmailAndPassword](#loginwithemailandpassword)를 호출하여 로그인 프로세스를 진행합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<LoginWithEmailParams>
  * `email` \<String> - User email
  * `password` \<String> - User password
  * `locale` \<String> - **optional** Language for the verification email (default value: "en")

**Returns**

* CompletableFuture\<LoginResult>
  * `provider` \<Providers.EMAIL>
  * `token` \<FBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

```java
LoginWithEmailParams loginOption = new LoginWithEmailParams(
                    "abc@defg.com",
                    "abcdef123&",
                    "ko"
                  )
CompletableFuture<LoginResult> res = wepinLogin.signUpWithEmailAndPassword(loginOption);
res.whenComplete((loginResponse, error) -> {
    if (error == null) {
        System.out.println("loginResponse: " + loginResponse);
    } else {
        // render error UI
        System.out.println("login error" + error.getMessage())
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val loginOption = LoginWithEmailParams(
                  email = "abc@defg.com",
                  password = "abcdef123&",
                  language = "ko"
                )
wepinLogin.signUpWithEmailAndPassword(loginOption).whenComplete { loginResponse, error ->
  if (error == null) {
      // render logged in UI
      println(loginResponse)
      
  } else {
      println("login error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## loginWithEmailAndPassword

```java
wepinLogin.loginWithEmailAndPassword(params)
```

이메일과 비밀번호를 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<LoginWithEmailParams>
  * `email` \<String> - User email
  * `password` \<String> - User password

**Returns**

* CompletableFuture\<LoginResult>
  * `provider` \<Providers.EMAIL>
  * `token` \<FBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

<pre class="language-java"><code class="lang-java"><strong>LoginWithEmailParams loginOption = new LoginWithEmailParams(
</strong>                    "abc@defg.com",
                    "abcdef123&#x26;",
                  )
CompletableFuture&#x3C;LoginResult> res = wepinLogin.loginWithEmailAndPassword(loginOption);
res.whenComplete((loginResponse, error) -> {
    if (error == null) {
        System.out.println("loginResponse: " + loginResponse);
    } else {
        // render error UI
        System.out.println("login error" + error.getMessage())
    }
});
</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val loginOption = LoginWithEmailParams(
                  email = "abc@defg.com",
                  password = "abcdef123&",
                  language = "ko"
                )
wepinLogin.loginWithEmailAndPassword(loginOption).whenComplete { loginResponse, error ->
  if (error == null) {
      // render logged in UI
      println(loginResponse)
      
  } else {
      println("login error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## loginWithIdToken

```java
wepinLogin.loginWithIdToken(params)
```

외부 ID 토큰을 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<LoginOauthIdTokenRequest>
  * `token` \<String> - ID token value to be used for login
  * `sign` \<String> - token 에 대한 서명값입니다. (Returned value of [getSignForLogin()](#getsignforlogin)).&#x20;

{% hint style="warning" %}
Note

WepinLogin 버전 1.0.0부터는 `sign` 값이 선택 사항입니다.

[Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거하는 경우, `sign` 값을 사용하지 않아도 됩니다.

(Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제)

> 인증 키 메뉴는 이전에 인증 키를 발급한 경우에만 표시됩니다.

WepinLogin 버전 1.1.0부터는 `sign` 값이 제거되었습니다.

WepinLogin 버전 1.1.0 을 사용하는 경우 반드시 [Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거해야 합니다.
{% endhint %}

**Returns**

* CompletableFuture\<LoginResult>
  * `provider` \<Providers.EXTERNAL\_TOKEN>
  * `token` \<FBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

<pre class="language-java"><code class="lang-java"><strong>String token = "eyJHGciO....adQssw5c"
</strong>String sign = "9753d4dc...c63466b9"
LoginWithEmailParams loginOption = new LoginOauthIdTokenRequest(token, sign)
CompletableFuture&#x3C;LoginResult> res = wepinLogin.loginWithIdToken(loginOption);
res.whenComplete((loginResponse, error) -> {
    if (error == null) {
        System.out.println("loginResponse: " + loginResponse);
    } else {
        // render error UI
        System.out.println("login error" + error.getMessage())
    }
});

</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val token = "eyJHGciO....adQssw5c"
val sign = "9753d4dc...c63466b9"
val loginOption = new LoginOauthIdTokenRequest(token, sign)
wepinLogin.loginWithIdToken(loginOption).whenComplete { loginResponse, error ->
  if (error == null) {
      // render logged in UI
      println(loginResponse)
      
  } else {
      println("login error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## loginWithAccessToken

```java
wepinLogin.loginWithAccessToken(params)
```

외부 Access Token을 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<LoginOauthAccessTokenRequest>
  * `provider` <"naver"|"discord"> - Provider that issued the access token
  * `accessToken` \<String> - Access token value to be used for login
  * `sign` \<String> -  accessToken에 대한 서명값입니다. (Returned value of [getSignForLogin()](#getsignforlogin)).&#x20;

{% hint style="warning" %}
Note

WepinLogin 버전 1.0.0부터는 `sign` 값이 선택 사항입니다.

[Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거하는 경우, `sign` 값을 사용하지 않아도 됩니다.

(Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제)

> 인증 키 메뉴는 이전에 인증 키를 발급한 경우에만 표시됩니다.

WepinLogin 버전 1.1.0부터는 `sign` 값이 제거되었습니다.

WepinLogin 버전 1.1.0 을 사용하는 경우 반드시 [Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거해야 합니다.
{% endhint %}

**Returns**

* CompletableFuture\<LoginResult>
  * `provider` \<Providers.EXTERNAL\_TOKEN>
  * `token` \<FBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

```java
String accessToken = "eyJHGciO....adQssw5c"
String sign = "9753d4dc...c63466b9"
LoginOauthAccessTokenRequest loginOption = new LoginOauthAccessTokenRequest("discord", accessToken, sign)
CompletableFuture<LoginResult> res = wepinLogin.loginWithAccessToken(loginOption);
res.whenComplete((loginResponse, error) -> {
    if (error == null) {
        System.out.println("loginResponse: " + loginResponse);
    } else {
        // render error UI
        System.out.println("login error" + error.getMessage())
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val accessToken = "eyJHGciO....adQssw5c"
val sign = "9753d4dc...c63466b9"
val loginOption = LoginOauthAccessTokenRequest(
  provider = "discord",
  accessToken = accessToken, sign = sign
)
wepinLogin.loginWithAccessToken(loginOption).whenComplete { loginResponse, error ->
  if (error == null) {
    // render logged in UI
    println(loginResponse) 
  } else {
      println("login error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## getRefreshFirebaseToken

```java
wepinLogin.getRefreshFirebaseToken()
```

현재 Wepin Firebase 토큰의 정보를 가져옵니다.

**Parameters**

* void

**Returns**

* CompletableFuture\<LoginResult>
  * `provider` \<Providers>
  * `token` \<FBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

```java
CompletableFuture<WepinUser> res = wepinLogin.getRefreshFirebaseToken();
res.whenComplete((firebaseResponse, error) -> {
  if (error == null) {
      System.out.println("firebaseResponse: " + firebaseResponse);
      // render logged in UI
        println(firebaseResponse)
  } else {
      // render error UI
      System.out.println("login error: " + error.getMessage());
  }
});
```

{% endtab %}

{% tab title="Kotlin" %}

<pre class="language-kotlin"><code class="lang-kotlin">wepinLogin.getRefreshFirebaseToken().whenComplete { firebaseResponse, error ->
<strong>  if (error == null) {
</strong>    println(firebaseResponse)
    // render logged in UI
  } else {
    println("login error - ${error.message}")
    // render error UI
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

## loginWepin

```java
wepinLogin.loginWepin(param)
```

지정된 프로바이더와 토큰을 사용하여 사용자를 위핀에 로그인합니다.

**Parameters**

매개변수는 이 모듈 내에서 loginWithEmailAndPassword(), loginWithIdToken(), loginWithAccessToken() 메서드의 반환 값을 활용해야 합니다.

* \<LoginResult>
  * provider \<Providers>
  * token \<FBToken>
    * idToken \<String> - Wepin Firebase idToken
    * refreshToken\<String> - Wepin Firebase refreshToken

**Returns**

* CompletableFuture\<WepinUser> - A promise that resolves to an object containing the user's login status and information. The object includes:
  * status <'success'|'fail'> - The login status.
  * userInfo \<UserInfo> **optional** - The user's information, including:
    * userId \<String> - The user's ID.
    * email \<String> - The user's email.
    * provider <'google'|'apple'|'naver'|'discord'|'email'|'external\_token'> - The login provider.
    * use2FA \<Boolean> - Whether the user uses two-factor authentication.
  * walletId \<String> = The user's wallet ID.
  * userStatus: \<UserStatus> - The user's status of wepin login. including:
    * loginStats: <'complete' | 'pinRequired' | 'registerRequired'> - If the user's loginStatus value is not complete, it must be registered in the wepin.
    * pinRequired?:
  * token: \<Token> - The user's token of wepin.
    * accessToken: \<String>
    * refreshToken \<String>

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

```java
String accessToken = "eyJHGciO....adQssw5c"
String sign = "9753d4dc...c63466b9"
LoginOauthAccessTokenRequest loginOption = new LoginOauthAccessTokenRequest("discord", accessToken, sign)
CompletableFuture<LoginResult> res = wepinLogin.loginWithAccessToken(loginOption);
res.whenComplete((loginResponse, error) -> {
  if (error == null) {
      System.out.println("loginResponse: " + loginResponse);
      CompletableFuture<LoginResult> resWepin = wepinLogin.loginWepin(loginResponse);
      resWepin.whenComplete((loginWepinResponse, error) -> {
        if (error == null) {
            System.out.println("loginWepinResponse: " + loginWepinResponse);
            if(loginWepinResponse.loginStatus === WepinLoginStatus.PIN_REQUIRED||loginWepinResponse.loginStatus === WepinLoginStatus.REGISTER_REQUIRED) {
                // wepin registration
            }else {
              // render logged in UI
            }                
        } else {
            // render error UI
            System.out.println("login error" + error.getMessage())
        }
      })
  } else {
      // render error UI
      System.out.println("login error" + error.getMessage())
}
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val accessToken = "eyJHGciO....adQssw5c"
val sign = "9753d4dc...c63466b9"
val loginOption = LoginOauthAccessTokenRequest(
  provider = "discord",
  accessToken = accessToken, sign = sign
)
wepinLogin.loginWithAccessToken(loginOption).whenComplete { loginResponse, error ->
  if (error == null) {
      println(loginResponse)
      wepinLogin.loginWepin(loginResponse).whenComplete { loginWepinResponse, err ->
        if (err == null) {
            println(loginWepinResponse)
            if(loginWepinResponse.loginStatus === WepinLoginStatus.PIN_REQUIRED||loginWepinResponse.loginStatus === WepinLoginStatus.REGISTER_REQUIRED) {
              // wepin registration
          }else {
            // render logged in UI
          }                 
        } else {
            println("login err - ${err.message}")
            // render error UI
        }
    }   
  } else {
      println("login error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## getCurrentWepinUser

```java
wepinLogin.getCurrentWepinUser()
```

이 메서드는 위핀에 현재 로그인한 사용자의 정보를 가져옵니다.

**Parameters**

* void

**Returns**

* CompletableFuture\<WepinUser> - A promise that resolves to an object containing the user's login status and information. The object includes:
  * status <'success'|'fail'> - The login status.
  * userInfo \<UserInfo> **optional** - The user's information, including:
    * userId \<String> - The user's ID.
    * email \<String> - The user's email.
    * provider <'google'|'apple'|'naver'|'discord'|'email'|'external\_token'> - The login provider.
    * use2FA \<Boolean> - Whether the user uses two-factor authentication.
  * walletId \<String> = The user's wallet ID.
  * userStatus: \<UserStatus> - The user's status of wepin login. including:
    * loginStats: <'complete' | 'pinRequired' | 'registerRequired'> - If the user's loginStatus value is not complete, it must be registered in the wepin.
    * pinRequired?:
  * token: \<Token> - The user's token of wepin.
    * accessToken: \<String>
    * refreshToken \<String>

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

<pre class="language-java"><code class="lang-java"><strong>CompletableFuture&#x3C;WepinUser> res = wepinLogin.getCurrentWepinUser();
</strong>res.whenComplete((wepinUserResponse, error) -> {
  if (error == null) {
      System.out.println("wepinUserResponse: " + wepinUserResponse);
      if (wepinUserResponse.loginStatus == WepinLoginStatus.PIN_REQUIRED || wepinUserResponse.loginStatus == WepinLoginStatus.REGISTER_REQUIRED) {
          // wepin registration
      } else {
          // render logged in UI
      }
  } else {
      // render error UI
      System.out.println("login error: " + error.getMessage());
  }
});
</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinLogin.getCurrentWepinUser().whenComplete { wepinUserResponse, error ->
  if (error == null) {
      println(wepinUserResponse)
      if (wepinUserResponse.loginStatus == WepinLoginStatus.PIN_REQUIRED || wepinUserResponse.loginStatus == WepinLoginStatus.REGISTER_REQUIRED) {
          // wepin registration
      } else {
          // render logged in UI
      }
  } else {
      println("login error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## logoutWepin

```java
wepinLogin.logoutWepin()
```

위핀에 로그인한 사용자를 로그아웃합니다.

**Parameters**

* void

**Returns**

* CompletableFuture\<Boolean>

**Exception**

* [Wepin Error](#wepin-error)

**Example**

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

```java
CompletableFuture<Boolean> res = wepinLogin.logoutWepin();
res.whenComplete((logoutResponse, error) -> {
  if (error == null) {
      System.out.println("logoutResponse: " + logoutResponse);
  } else {
      // render error UI
      System.out.println("logout error" + error.getMessage())
  }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinLogin.logoutWepin().whenComplete { logoutResponse, error ->
  if (error == null) {
      println(logoutResponse)
  } else {
      println("logout error - ${error.message}")
      // render error UI
  }
}
```

{% endtab %}
{% endtabs %}

## getSignForLogin(Deprecated)

{% hint style="danger" %}
🔄 `getSignForLogin`은 더 이상 지원되지 않습니다\
• v1.1.0부터 `getSignForLogin()` 함수는 로그인 프로세스에서 `sign` 파라미터가 제거됨에 따라 더 이상 지원되지 않습니다.\
• 서명 없이 로그인하려면, **Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제**에서 인증키를 삭제해 주세요.\
• 인증키 메뉴는 이전에 키를 생성한 경우에만 표시됩니다.
{% endhint %}

발급자를 확인하기 위한 서명을 생성합니다. 주로 ID Token 및 Access Token과 같은 로그인 관련 정보를 위한 서명을 생성하는 데 사용됩니다.

```kotlin
wepinLogin.getSignForLogin(privKey, message);
```

**Parameters**

* `privKey` \<String> - The authentication key used for signature generation.
* `message` \<String> - The message or payload to be signed.

**Returns**

* String - The generated signature.

{% hint style="warning" %}
인증 키(privKey)는 안전하게 저장되어야 하며 외부에 노출되어서는 안 됩니다. 보안과 민감한 정보 보호를 강화하기 위해 getSignForLogin() 메서드는 프론트엔드가 아닌 백엔드에서 실행하는 것이 권장됩니다.
{% endhint %}

**Example**

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

```java
String privKey = '0400112233445566778899001122334455667788990011223344556677889900'
String idToken = 'idtokenabcdef'
String sign = wepinLogin.getSignForLogin(privKey, idToken)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val privKey = '0400112233445566778899001122334455667788990011223344556677889900'
val idToken = 'idtokenabcdef'
val sign = wepinLogin.getSignForLogin(privKey, idToken)
```

{% endtab %}
{% endtabs %}

## finalize

```java
wepinLogin.finalize()
```

Wepin Login Library 를 종료 합니다.

**Parameters**

* void

**Returns**

* void

**Example**

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

```java
wepinLogin.finalize()
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinLogin.finalize()
```

{% endtab %}
{% endtabs %}

## Wepin Error

| Error Code                  | Error Message                     | Error Description                                                                                                                                                                                    |
| --------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_APP_KEY`           | "Invalid app key"                 | The Wepin app key is invalid.                                                                                                                                                                        |
| `INVALID_PARAMETER` \`      | "Invalid parameter"               | One or more parameters provided are invalid or missing.                                                                                                                                              |
| `INVALID_LOGIN_PROVIDER`    | "Invalid login provider"          | The login provider specified is not supported or is invalid.                                                                                                                                         |
| `INVALID_TOKEN`             | "Token does not exist"            | The token does not exist.                                                                                                                                                                            |
| `INVALID_LOGIN_SESSION`     | "Invalid Login Session"           | The login session information does not exist.                                                                                                                                                        |
| `NOT_INITIALIZED_ERROR`     | "Not initialized error"           | The WepinLoginLibrary has not been properly initialized.                                                                                                                                             |
| `ALREADY_INITIALIZED_ERROR` | "Already initialized"             | The WepinLoginLibrary is already initialized, so the logout operation cannot be performed again.                                                                                                     |
| `NOT_ACTIVITY`              | "Context is not activity"         | The Context is not an activity                                                                                                                                                                       |
| `USER_CANCELLED`            | "User cancelled"                  | The user has cancelled the operation.                                                                                                                                                                |
| `UNKNOWN_ERROR`             | "An unknown error occurred"       | An unknown error has occurred, and the cause is not identified.                                                                                                                                      |
| `NOT_CONNECTED_INTERNET`    | "No internet connection"          | The system is unable to detect an active internet connection.                                                                                                                                        |
| `FAILED_LOGIN`              | "Failed to Oauth log in"          | The login attempt has failed due to incorrect credentials or other issues.                                                                                                                           |
| `ALREADY_LOGOUT`            | "Already Logout"                  | The user is already logged out, so the logout operation cannot be performed again.                                                                                                                   |
| `INVALID_EMAIL_DOMAIN`      | "Invalid email domain"            | The provided email address's domain is not allowed or recognized by the system.                                                                                                                      |
| `FAILED_SEND_EMAIL`         | "Failed to send email"            | The system encountered an error while sending an email. This is because the email address is invalid or we sent verification emails too often. Please change your email or try again after 1 minute. |
| `REQUIRED_EMAIL_VERIFIED`   | "Email verification required"     | Email verification is required to proceed with the requested operation.                                                                                                                              |
| `INCORRECT_EMAIL_FORM`      | "Incorrect email format"          | The provided email address does not match the expected format.                                                                                                                                       |
| `INCORRECT_PASSWORD_FORM`   | "Incorrect password format"       | The provided password does not meet the required format or criteria.                                                                                                                                 |
| `NOT_INITIALIZED_NETWORK`   | "Network Manager not initialized" | The network or connection required for the operation has not been properly initialized.                                                                                                              |
| `REQUIRED_SIGNUP_EMAIL`     | "Email sign-up required."         | The user needs to sign up with an email address to proceed.                                                                                                                                          |
| `FAILED_EMAIL_VERIFIED`     | "Failed to verify email."         | The WepinLoginLibrary encountered an issue while attempting to verify the provided email address.                                                                                                    |
| `FAILED_PASSWORD_SETTING`   | "Failed to set password."         | The WepinLoginLibrary failed to set the password.                                                                                                                                                    |
| `EXISTED_EMAIL`             | "Email already exists."           | The provided email address is already registered in Wepin.                                                                                                                                           |


# 핀 패드

RESTful API 사용 시, Android 환경의 서비스에서 사용자의 PIN을 입력 받을 수 있는 UI 및 기능을 제공하는 패키지입니다.


# 설치

## 요구사항 <a href="#requirements" id="requirements"></a>

* Android API 버전 <mark style="color:blue;">24</mark> 이상&#x20;

#### 저장소 마이그레이션 안내 (v1.0.0 기준) <a href="#storage-migration-notice-from-v1.0.0" id="storage-migration-notice-from-v1.0.0"></a>

* v1.0.0부터 저장소 키 변경 정책이 적용되어, 기존 저장된 데이터에 접근할 수 없는 경우가 발생할 수 있습니다.
* &#x20;키가 유효하지 않은 경우에 한해, 기존 저장 데이터는 자동으로 초기화되고 새 키가 생성됩니다.
* 키가 정상적으로 유지되는 경우, 기존 데이터는 그대로 유지됩니다.
* v1.0.0 이후 버전에서 이전 버전으로 다운그레이드할 경우, 기존 데이터에 접근하지 못할 수 있습니다.

{% hint style="info" %}
업데이트 전에 잠재적인 문제를 방지하기 위해 데이터를 백업해두는 것을 추천드립니다.
{% endhint %}

#### &#x20;WepinLogin과의 호환성 <a href="#compatibility-with-wepinlogin" id="compatibility-with-wepinlogin"></a>

* 이 모듈을 WepinLogin과 함께 사용하는 경우, **WepinLogin v1.0.0** 이상을 사용하고 있는지 확인해주세요.
* Wepin 모듈 간에 주요 버전이 다른 경우, 호환성 문제, 예상치 못한 오류, 또는 일관되지 않은 동작이 발생할 수 있습니다.
* 안정적인 통합을 위해서는 모든 Wepin 모듈을 v1.0.0 이상 버전으로 통일하여 사용하는 것을 권장합니다.
* **WepinPin v1.1.0** 부터 WepinPin에 WepinLogin이 포함되었습니다.

## 설치하기 <a href="#installation" id="installation"></a>

프로젝트레벨의 build gradle 파일에  JitPack 레포지토리를 추가합니다.

```kts
 dependencyResolutionManagement {
     repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
     repositories {
         google()
         mavenCentral()
         maven("https://jitpack.io") // <= Add JitPack Repository
     }
 }
```

### Wepin PIN Pad Library를 dependencies에 추가하기 <a href="#add-wepin-pin-pad-library-to-dependencies" id="add-wepin-pin-pad-library-to-dependencies"></a>

앱의 build gradle 파일에 아래와 같이 추가 합니다. 버전은 사용하고자 하는 릴리즈 버전을 넣으면 됩니다.&#x20;

```kts
dependencies {
  // ...
  implementation("com.github.WepinWallet:wepin-android-sdk-pin-v1:vX.X.X") 
}
```

## 릴리즈  <a href="#release" id="release"></a>

릴리즈된 패키지 버전은 아래 깃허브에서 확인 가능합니다.

{% embed url="<https://github.com/WepinWallet/wepin-android-sdk-pin-v1/releases>" %}


# 초기화하기

Wepin Android PIN Pad Library를 초기화하는 방법은 다음과 같습니다.&#x20;

```kotlin
import com.wepin.android.pinlib.WepinPin
```

`WepinPin` 인스턴스를 생성하기전에 아래와 같이 앱의 Activity Context , 앱 등록 후 할당받은 App ID와 App Key를 WepinPinParams 객체에 전달해 주세요.

```kotlin
val wepinPinParams =  WepinPinParams(
            context = this,
            appId = "your-wepin-app-id",
            appKey = "your-wepin-app-key"
        )
```

앞서 생성한 `WepinPinParams` 를 전달하면서 `WepinPin` 인스턴스를 생성해 주세요.

```kotlin
val wepinPin = WepinPin(wepinPinParams)
```

`WepinPin` 인스턴스생성 후 `initialize` 메서드를 호출하여 초기화를 합니다.

```kotlin
val res = wepinPin.initialize(attributes)
```

#### parameters

&#x20;`atrributes` \<WepinPinAttributes>

* `defualtLanguage` \<String>\
  핀 패드 화면의 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'` ,`'ja'`입니다.

#### Return value

`CompletableFuture` \<Boolean>\
정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### Example

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

```java
public class MainActivity extends ComponentActivity {
    //v1.1.0 부터 WepinPin.login 으로 WepinLogin 의 메서드를 사용할 수 있습니다.
    private WepinLogin wepinLogin;    
    private WepinPin wepinPin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_example_main);

        initView();
        // Wepin Login Library 초기화
        // ...

        // Wepin PIN Pad Library 초기화        
        WepinPinParams wepinPinParams = new WepinPinParams(
            this,
            "your-wepin-app-id",
            "your-wepin-app-key"
        );
        wepinPin = new WepinPin(wepinPinParams);
        
        WepinPinAttributes attributes = new WepinPinAttributes("en");
        CompletableFuture<Boolean> res = wepinPin.initialize(attributes);
        if (res != null) {
            res.whenComplete((result, error) -> {
                if (error == null) {
                    System.out.println(result);
                } else {
                    System.out.println(error);
                }
            });
        }
        // ...
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
class MainActivity : ComponentActivity() {
    private lateinit var wepinLogin: WepinLogin
    private lateinit var wepinPin: WepinPin
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_example_main)
    
        initView()
        // Wepin Login Libary 초기화
        // ...
        
        // Wepin PIN Pad Libary 초기화        
        val wepinPinParams =  WepinPinParams(
            context = this,
            appId = 'your-wepin-app-id',
            appKey = 'your-wepin-app-key'
        )
        wepinPin = WepinPin(wepinPinParams)       
        var attributes = WepinPinAttributes("en")
        val res = wepinPin.initialize(attributes)
        res?.whenComplete { infResponse, error ->
          if (error == null) {
            println(infResponse)
          } else {
            println(error) 
          }
      }        
    // ...
}
```

{% endtab %}
{% endtabs %}

## isInitialized

`isInitialized`메서드를 이용해서 `WepinPin` 인스턴스가 정상적으로 초기화 되었는지 확인할 수 있습니다. &#x20;

반환값은 아래와 같습니다.&#x20;

* \<Boolean>\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### Example

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

```java
if(wepinPin.isInitialized()){
    // Success to initialize WepinPin
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
if(wepinPin.isInitialized()){
    // Success to initialize WepinPin
}
```

{% endtab %}
{% endtabs %}

## changeLanguage

```kotlin
wepinPin.changeLanguage("ko")
```

핀 패드 화면에 표시되는 언어를 변경합니다. 현재 `'ko'`, `'en'`, `'ja'`만 지원됩니다.&#x20;

### **Parameters**

* &#x20;`language` \<String>

### **Return value**

* `CompletableFuture` \<Boolean>\
  정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### **Example**

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

```java
wepinPin.changeLanguage("ko").whenComplete((res, err) -> {
    if (err == null) {
        System.out.println(res);
    } else {
        System.out.println(err);
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinPin.changeLanguage("ko").whenComplete{ res, err ->
    if (err == null) {
      println(res)
    } else {
      println(err)
    }
}
```

{% endtab %}
{% endtabs %}


# 메서드

Wepin PIN Pad Library  초기화 이후 사용할 수 있습니다.

## &#x20;generateRegistrationPINBlock

```kotlin
wepinPin.generateRegistrationPINBlock()
```

사용자의  지갑생성 및 회원가입을 위해 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.

### **Parameters**

* `<void>`

### **Return value**

* `CompletableFuture` \<RegistrationPinBlock>
  * `uvd` \<EncUVD>

    * `b64Data` \<String> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<Int> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값

  * `hint` \<EncPinHint>

    * `data` \<string> \
      &#x20;PIN 힌트를 암호화한 값
    * `length` \<string>\
      PIN 힌트의 길이
    * `version` \<number>&#x20;

    &#x20;      PIN 힌트의 버전

### **Example**

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

```java
wepinPin.generateRegistrationPINBlock().whenComplete((res, err) -> {
    if (err == null) {
        RegistrationPinBlock registerPin = new RegistrationPinBlock(res.getUvd(), res.getHint());
        // You need to make a Wepin RESTful API request using the received data.
    } else {
        System.out.println(err);
    }
});

```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinPin.generateRegistrationPINBlock().whenComplete { res, err ->
    if (err == null) {
        registerPin = RegistrationPinBlock(uvd = res!!.uvd, hint = res!!.hint)
        // You need to make a Wepin RESTful API request using the received data.
    } else {
      println(err)
    }
}
```

{% endtab %}
{% endtabs %}

## generateAuthPINBlock

```kotlin
wepinPin.generateAuthPINBlock(3)
```

사용자 인증에필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `count` \<Int> **optional**&#x20;

  생성하려는 PIN Block의 갯수. 기본값은 `1` 입니다.

### **Return value**

* `Promise` \<AuthPinBlock>
  * `uvdList` List\<EncUVD> \
    암호화된 PIN Block의 리스트
    * \<EncUVD>
      * `b64Data` \<String> \
        b64SKey의  원본키로 암호화된 데이터
      * `b64SKey` \<String> \
        b64Data 를 생성할때  사용하는 키
      * `seqNum` \<Int> **optional** \
        **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값.\
        Multi Tx 요청시, 반드시 받은 PIN Block의 순서대로 사용해야 합니다.(1,2,3...)
  * `otp` \<String> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### **Example**

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

```java
wepinPin.generateAuthPINBlock(3).whenComplete((res, err) -> {
    if (err == null) {
        AuthPinBlock authPin = new AuthPinBlock(res.getUvdList(), res.getOtp());
        // You need to make a Wepin RESTful API request using the received data.
    } else {
        System.out.println(err);
    }
});

```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinPin.generateAuthPINBlock(3).whenComplete { res, err ->
    if (err == null) {
        authPin = AuthPinBlock(uvdList = res!!.uvdList, otp = res!!.otp)
        // You need to make a Wepin RESTful API request using the received data.
    } else {
      println(err)
    }
}
```

{% endtab %}
{% endtabs %}

## generateChangePINBlock

```kotlin
wepinPin.generateChangePINBlock()
```

사용자 PIN 변경을 위해 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `<void>`

### **Return Value**

* `CompletableFuture` \<ChangePinBlock>
  * `uvd` \<EncUVD>
    * `b64Data` \<String> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<Int> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값
  * `newUVD` \<EncUVD>
    * `b64Data` \<String> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<Int> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값.
  * `hint` \<EncPinHint>
    * `data` \<String> \
      &#x20;PIN 힌트를 암호화한 값
    * `length` \<String>\
      PIN 힌트의 길이
    * `version` \<Int> \
      PIN 힌트의 버전
  * `otp` \<String> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### **Example**

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

```java
wepinPin.generateChangePINBlock().whenComplete((res, err) -> {
    if (err == null) {
        ChangePinBlock changePin = new ChangePinBlock(res.getUvd(), res.getNewUVD(), res.getHint(), res.getOtp());
        // You need to make a Wepin RESTful API request using the received data.
    } else {
        System.out.println(err);
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinPin.generateChangePINBlock().whenComplete { res, err ->
    if (err == null) {
        changePin = ChangePinBlock(uvd = res!!.uvd, newUVD = res.newUVD, hint = res.hint, otp = res.otp)
        // You need to make a Wepin RESTful API request using the received data.
    } else {
      println(err)
    }
}
```

{% endtab %}
{% endtabs %}

## generateAuthOTP

```kotlin
wepinPin.generateAuthOTPCode()
```

사용자로부터 OTP 코드를 입력받을 수 있는 화면을 띄우고 처리합니다.

### **Parameters**

* `<void>`

### **Return Value**

* `CompletableFuture` \<AuthOTP>
  * `code` \<String>\
    입력받은 OTP 코드

### **Example**

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

```java
wepinPin.generateAuthOTPCode().whenComplete((res, err) -> {
    if (err == null) {
        AuthOTP authOTPCode = new AuthOTP(res.getCode());
        // You need to make a Wepin RESTful API request using the received data.
    } else {
        System.out.println(err);
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinPin.generateAuthOTPCode().whenComplete { res, err ->
    if (err == null) {
        authOTPCode = AuthOTP(res!!.code)
        // You need to make a Wepin RESTful API request using the received data.
    } else {
      println(err)
    }
}
```

{% endtab %}
{% endtabs %}

## finalize

```kotlin
wepinPin.finalize()
```

Wepin PIN Pad Library 사용을 종료합니다.

### **Parameters**

* `<void>`

### **Return Value**

* `<void>`

### **Example**

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

```java
wepinPin.finalize();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinPin.finalize()
```

{% endtab %}
{% endtabs %}

## login

<mark style="color:red;">`v1.1.0`</mark> 부터 `WepinPin` SDK에 `WepinLogin`이 통합되었습니다.`WepinPin` 에 통합된 `WepinLogin` 을 사용하지 않고 별도의 `WepinLogin` 을 사용할 때, 두 SDK 의 버전이 동일하지 않은 경우 에러가 발생할 수 있습니다.

`login` 변수는 다양한 인증 방법을 포함한 위핀 로그인 라이브러리로, 사용자가 여러 방식으로 로그인할 수 있도록 합니다. 이메일 및 비밀번호 로그인, OAuth 프로바이더 로그인, ID Token 또는 Access Token을 사용한 로그인 등을 지원합니다. 각 메서드에 대한 자세한 정보는 공식 라이브러리 문서 [Login Library 가이드](/widget-integration/android-java-and-kotlin-sdk/login-library)에서 확인할 수 있습니다.

### **Available Methods**

* [`loginWithOauthProvider`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithoauthprovider)
* [`signUpWithEmailAndPassword`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#signupwithemailandpassword)
* [`loginWithEmailAndPassword`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithemailandpassword)
* [`loginWithIdToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithidtoken)
* [`loginWithAccessToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithaccesstoken)
* [`getRefreshFirebaseToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#getrefreshfirebasetoken)
* [`loginWepin`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwepin)
* [`getCurrentWepinUser`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#getcurrentwepinuser)
* [`logout`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#logoutwepin)

이 메서드들은 다양한 로그인 시나리오를 지원하며, 필요에 맞는 적절한 방법을 선택할 수 있습니다.

**Exception**

* [WepinError](https://docs.wepin.io/widget-integration/flutter-sdk/widget/methods#wepinerror)

**Example**

<pre class="language-kotlin"><code class="lang-kotlin"><strong>// OAuth Provider를 사용한 로그인
</strong>wepinSDK.login.loginWithOauthProvider("google", "your-client-id")
    .thenCompose { authResult ->
        // ID Token을 사용한 로그인
        wepinSDK.login.loginWithIdToken(authResult.idToken)
    }.thenCompose { idTokenResult ->
        // 위핀에 로그인
        wepinSDK.login.loginWepin(idTokenResult)
    }.thenAccept { user ->
        Log.d("WepinSDK", "로그인 성공! 사용자 정보: $user")
    }.exceptionally { e ->
        Log.e("WepinSDK", "로그인 실패: ${e.message}", e)
        null
    }

// 이메일 및 비밀번호로 회원가입 및 로그인
wepinSDK.login.signUpWithEmailAndPassword(
    email = 'example@example.com', 
    password = 'password123'
).thenAccept { signUpResult ->
    Log.d("WepinSDK", "로그인 성공! 사용자 정보: $user")
}.exceptionally { error ->
    if (error is WepinError) {
    }
}

// 현재 로그인된 사용자 가져오기
var currentUser = wepinSDK.login.getCurrentWepinUser()
    .thenAccept { user ->
        Log.d("WepinSDK", "현재 사용자: $user")
    }.exceptionally { e ->
        Log.e("WepinSDK", "사용자 가져오기 실패", e)
        null
    }

// 로그아웃
wepinSDK.login.logout()
    .thenAccept { result ->
        Log.d("WepinSDK", "로그아웃 결과: $result")
    }.exceptionally { e ->
        Log.e("WepinSDK", "로그아웃 실패", e)
        null
    }    
</code></pre>


# 위젯


# 설치

## 요구사항 <a href="#requirements" id="requirements"></a>

* Android API 버전 <mark style="color:blue;">24</mark> 이상

## 설치하기 <a href="#installation" id="installation"></a>

### Wepin Widget Library를 .gradle에 추가하기  <a href="#add-wepin-widget-library-to-.gradle" id="add-wepin-widget-library-to-.gradle"></a>

프로젝트 레벨의 build gradle 파일에 JitPack 레포지토리를 추가합니다.

```kts
 dependencyResolutionManagement {
     repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
     repositories {
         google()
         mavenCentral()
         maven("https://jitpack.io") // <= Add JitPack Repository
     }
 }
```

### Wepin Widget Library를 dependencies에 추가하기 <a href="#add-wepin-widget-library-to-dependencies" id="add-wepin-widget-library-to-dependencies"></a>

앱의 build gradle 파일에 아래와 같이 추가 합니다. 버전은 사용하고자 하는 릴리즈 버전을 넣으면 됩니다.&#x20;

Wepin Widget Library 는 1.1.0 버전부터 지원합니다.

```kts
dependencies {
  // ...
  implementation("com.github.WepinWallet:wepin-android-sdk-widget-v1:vX.X.X") 
}
```

## 릴리즈  <a href="#release" id="release"></a>

릴리즈된 패키지 버전은 아래 깃허브에서 확인 가능합니다.&#x20;

{% embed url="<https://github.com/WepinWallet/wepin-android-sdk-widget-v1>" %}


# 초기화하기

Wepin Android Widget Library를 초기화하는 방법은 다음과 같습니다.&#x20;

```kotlin
import com.wepin.android.widgetlib.WepinWidget 
```

`WepinWidget`인스턴스를 생성하기전에 아래와 같이 앱의 Activity Context , 앱 등록 후 할당받은 App ID와 App Key를 WepinWidgetParams 객체에 전달해 주세요.

```kotlin
val wepinWidgetParams =  WepinWidgetParams(
            context = this,
            appId = "your-wepin-app-id",
            appKey = "your-wepin-app-key"
        )
```

앞서 생성한 `WepinWidgetParams` 를 전달하면서 `WepinWidget` 인스턴스를 생성해 주세요.

```kotlin
val wepinWidget = WepinWidget(wepinWidgetParams)
```

`WepinWidget` 인스턴스생성 후 `initialize` 메서드를 호출하여 초기화를 합니다.

```kotlin
val res = wepinWidget.initialize(attributes)
```

#### parameters

&#x20;`atrributes` \<WepinWidgetAttribute>

* `defualtLanguage` \<String>\
  위젯 화면의 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'` ,`'ja'`입니다.
* `defaultCurrency`\<String>

  위젯 화면의 기본 통화 설정, 기본 값은 `'USD'` 입니다. 현재 지원하는 통화는 `'KRW'`, `'USD'`, `'JPY'`입니다.

#### Return value

`CompletableFuture` \<Boolean>\
정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### Example

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

```java
public class MainActivity extends ComponentActivity {
    private WepinWidget wepinWidget;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_example_main);

        initView();
        // Wepin Login Library 초기화
        // ...

        // Wepin PIN Pad Library 초기화        
        WepinWidgetParams wepinWidgetParams = new WepinWidgetParams(
            this,
            "your-wepin-app-id",
            "your-wepin-app-key"
        );
        wepinWidget = new WepinWidget(wepinWidgetParams null);
        
        WepinWidgetAttributes attributes = new WepinWidgetAttributes("en", "USD");
        CompletableFuture<Boolean> res = wepinWidget.initialize(attributes);
        if (res != null) {
            res.whenComplete((result, error) -> {
                if (error == null) {
                    System.out.println(result);
                } else {
                    System.out.println(error);
                }
            });
        }
        // ...
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
class MainActivity : ComponentActivity() {
    private lateinit var wepinWidget: WepinWidget
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_example_main)
    
        initView()
        
        // Wepin Widget Pad Libary 초기화        
        val wepinWidgetParams =  WepinWidgetParams(
            context = this,
            appId = 'your-wepin-app-id',
            appKey = 'your-wepin-app-key'
        )
        wepinWidget = WepinWidget(wepinWidgetParams)       
        var attributes = WepinWidgetAttribute("en", "USD")
        val res = wepinWidget.initialize(attributes)
        res?.whenComplete { infResponse, error ->
          if (error == null) {
            println(infResponse)
          } else {
            println(error) 
          }
      }        
    // ...
}
```

{% endtab %}
{% endtabs %}

## isInitialized

`isInitialized`메서드를 이용해서 `WepinWidget` 인스턴스가 정상적으로 초기화 되었는지 확인할 수 있습니다. &#x20;

반환값은 아래와 같습니다.&#x20;

* \<Boolean>\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### Example

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

```java
if(wepinWidget.isInitialized()){
    // Success to initialize WepinPin
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
if(wepinWidget.isInitialized()){
    // Success to initialize WepinPin
}
```

{% endtab %}
{% endtabs %}

## changeLanguage

```kotlin
wepinWidget.changeLanguage("ko")
```

위젯화면에 표시되는 언어를 변경합니다. 현재 `'ko'`, `'en'`, `'ja'`만 지원됩니다.&#x20;

### **Parameters**

* &#x20;`language` \<String>\
  위젯 화면에 표시될 언어
* `currency` \<String>  *optional*\
  위젯 화면에 표시될&#x20;

### **화Return value**

* `CompletableFuture` \<Boolean>\
  정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### **Example**

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

```java
wepinWidget.changeLanguage("ko", null).whenComplete((res, err) -> {
    if (err == null) {
        System.out.println(res);
    } else {
        System.out.println(err);
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinWidget.changeLanguage("ko").whenComplete{ res, err ->
    if (err == null) {
      println(res)
    } else {
      println(err)
    }
}
```

{% endtab %}
{% endtabs %}


# 메서드

## getStatus

WepinSDK의 Lifecycle 상태 값을 반환합니다.

Parameters

* None

Return Value

* CompletableFutuer\<WepinLifeCycle>
  * NOT\_INITIALIZED: `WepinSDK`이 초기화되지 않음
  * INITIALIZING: `WepinSDK`초기화 진행 중
  * INITIALIZED: `WepinSDK`초기화 완료
  * BEFORE\_LOGIN: `WepinSDK`은 초기화되었으나 사용자는 로그인 되지 않음
  * LOGIN: 사용자가 로그인 되었고 위핀에도 가입되어있음
  * LOGIN\_BEFORE\_REGISTER: 사용자가 로그인하였으나 위핀에 가입되지 않음

Example

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

<pre class="language-java"><code class="lang-java"><strong>CompletableFuture&#x3C;WepinLifeCycle> res = wepinWidget.getStatus()
</strong>res.whenComplete((state, error) -> {
    if (error ==  null) {
        Log.d(TAG, "Wepin SDK Lifecycle is $state");
    } else {
        Log.d(TAG, "loginWithUI error: $error");
    }
});
</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

<pre class="language-kotlin"><code class="lang-kotlin"><strong>val res = wepinWidget.getStatus()
</strong>res?.whenComplete { state, error ->
    if (error == null) {
        Log.d(TAG, "Wepin SDK Lifecycle is $state")
    } else {
        Log.d(TAG, "getStatus error: $error")
    }
</code></pre>

{% endtab %}
{% endtabs %}

***

## loginWithUI

`loginWithUI()` 메서드는 위젯을 사용하여 로그인하는 기능을 제공하며, 로그인된 사용자의 정보를 반환합니다. 사용자가 이미 로그인되어 있는 경우, 위젯을 표시하지 않고 로그인된 사용자의 정보를 바로 반환합니다. 위젯 없이 로그인을 수행하려면, `login` 변수의 `loginWepin()` 메서드를 대신 사용해야 합니다.

Parameters

* `context` \<Context> - 애플리케이션 특정 리소스와 클래스에 대한 접근을 제공하고 애플리케이션 환경에 관한 정보를 제공하기 때문에 Android에서 필수적입니다. 이는 새로운 액티비티를 시작하거나, 애플리케이션 자산에 접근하거나, 시스템 서비스를 검색하는 등의 작업에 사용됩니다.\
  `loginWithUI(context)`와 같은 메서드를 호출할 때는 올바른 작동을 보장하기 위해 적절한 Context(예: `Activity` 또는 `Application context`)를 전달해야 합니다. UI 관련 작업(예: 새 화면 열기)의 경우에는 Activity context를 사용하는 것이 권장됩니다.
* `loginProviders` \<List\<LoginProvider>>\
  위젯을 구성할 로그인 프로바이더들의 목록입니다. 빈 목록이 제공되면 이메일 로그인 기능만 사용할 수 있습니다.
  * `provider`\<String>\
    OAuth 로그인 프로바이더(예: 'google', 'naver', 'discord', 'apple')
  * `clientId`\<String>\
    OAuth 로그인 프로바이더의 클라이언트 ID입니다.
* `email`\<String> *optional*\
  `email` 매개변수는 위젯에서 로그인할 때 지정된 이메일 주소로 로그인할 수 있도록 합니다.

Return Value

* CompletableFuture\<WepinUser>
  * `status` \<String>\
    성공여부<'success'|'fail'>
  * `userInfo` \<WepinUserInfo> *optional*\
    사용자 정보
    * `userId` \<String>\
      Wepin 사용자 ID
    * `email` \<String>\
      Wepin 에 로그인된 사용자의 이메일 주소
    * `provider` \<String>\
      로그인 프로바이더 이름 <'google'|'apple'|'naver'|'discord'|'email'|'external\_toekn'>
    * `use2FA` \<Boolean>\
      사용자 지갑에 2FA가 활성화 되어 있는지 여부
  * `userStatus` \<WepinUserStatus>\
    사용자 상태
    * `loginStatus` \<String>\
      로그인 상태<'complete'|'pinRequired'|'registerRequired'>
    * `pinRequired` \<Boolean> *optional*\
      사용자 PIN 번호 필요 여부
  * `walletId` \<String> optional\
    Wepin 사용자의 지갑 ID
  * `token` \<WepinToken>\
    Wepin Token 정보
    * `accessToken` \<String>\
      Wepin Access Token
    * `refreshToken` \<String>\
      Wepin Refresh Token&#x20;

Example

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

```java
Context context = this;
List<LoginProviderInfo> providers = List.of(new LoginProviderInfo("google", "GOOGLE_CLIENT_ID"));
CompletableFuture<WepinUser> res = wepinWidget.loginWithUI(context, providers, null);
res.whenComplete((user, error) -> {
    if (error ==  null) {
        Log.d(TAG, "Wepin User is $user");
    } else {
        Log.d(TAG, "loginWithUI error: $error");
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.loginWithUI(context, providers, email)
res?.whenComplete { wepinUser, error ->
    if (error == null) {
        Log.d(TAG, "Wepin User is $wepinUser")
    } else {
        Log.d(TAG, "loginWithUI error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## openWidget

위젯 창을 열어줍니다. 사용자가 로그인되어 있지 않으면 위젯 창이 열리지 않으므로, `openWidget`을 호출하기 전에 반드시 사용자가 위핀에 로그인되어 있어야 합니다. 로그인하려면 `loginWithUI` 매서드 또는 `login` 변수의 `loginWepin` 메서드를 사용해야 합니다.

Parameters

* context \<Context>\
  애플리케이션 특정 리소스와 클래스에 대한 접근을 제공하고 애플리케이션 환경에 관한 정보를 제공하기 때문에 Android에서 필수적입니다. 이는 새로운 액티비티를 시작하거나, 애플리케이션 자산에 접근하거나, 시스템 서비스를 검색하는 등의 작업에 사용됩니다.\
  `openWidget(context)`와 같은 메서드를 호출할 때는 올바른 작동을 보장하기 위해 적절한 Context(예: `Activity` 또는 `Application context`)를 전달해야 합니다. UI 관련 작업(예: 새 화면 열기)의 경우에는 Activity context를 사용하는 것이 권장됩니다.

Return Value

* CompletableFuture\<Boolean>

Example

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

```java
Context context = this;
CompletableFuture<Boolean> res = wepinWidget.openWidget(context);
res.whenComplete((result, error) -> {
    if (error ==  null) {
        Log.d(TAG, "openWidget Result is $user");
    } else {
        Log.d(TAG, "openWidget error: $error");
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.openWidget(context)
res?.whenComplete { result, error ->
    if (error == null) {
        Log.d(TAG, "openWidget result is $result")
    } else {
        Log.d(TAG, "openWidget error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## closeWidget

위젯 창을 닫습니다. 창을 닫아도 로그아웃되지 않습니다.

Parameters

* None

Return Value

* None

Example

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

<pre class="language-java"><code class="lang-java"><strong>wepinWidget.closeWidget();
</strong></code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinWidget.closeWidget()
```

{% endtab %}
{% endtabs %}

***

## register

사용자를 위에 등록합니다. 가입 및 로그인 후 위핀 위젯의 등록 페이지가 열리며, 위핀 서비스에 등록(지갑 생성 및 계정 생성)을 진행합니다. 이 기능은 `WepinSDK`의 `WepinLifeCycle`이 `loginBeforeRegister` 상태일 때만 사용할 수 있습니다. `loginWithUI` 매서드 또는 `login` 변수의 `loginWepin` 메서드를 호출한 후, `userStatus`의 `loginStatus` 값이 'complete'가 아니면 이 메서드를 호출해야 합니다.

Parameters

* context \<Context>\
  애플리케이션 특정 리소스와 클래스에 대한 접근을 제공하고 애플리케이션 환경에 관한 정보를 제공하기 때문에 Android에서 필수적입니다. 이는 새로운 액티비티를 시작하거나, 애플리케이션 자산에 접근하거나, 시스템 서비스를 검색하는 등의 작업에 사용됩니다.\
  `register(context)`와 같은 메서드를 호출할 때는 올바른 작동을 보장하기 위해 적절한 Context(예: `Activity` 또는 `Application context`)를 전달해야 합니다. UI 관련 작업(예: 새 화면 열기)의 경우에는 Activity context를 사용하는 것이 권장됩니다.

Return Value

* CompletableFuture\<WepinUser>
  * `status` \<String>\
    성공여부<'success'|'fail'>
  * `userInfo` \<WepinUserInfo> *optional*\
    사용자 정보
    * `userId` \<String>\
      Wepin 사용자 ID
    * `email` \<String>\
      Wepin 에 로그인된 사용자의 이메일 주소
    * `provider` \<String>\
      로그인 프로바이더 이름 <'google'|'apple'|'naver'|'discord'|'email'|'external\_toekn'>
    * `use2FA` \<Boolean>\
      사용자 지갑에 2FA가 활성화 되어 있는지 여부
  * `userStatus` \<WepinUserStatus>\
    사용자 상태
    * `loginStatus` \<String>\
      로그인 상태<'complete'|'pinRequired'|'registerRequired'>
    * `pinRequired` \<Boolean> *optional*\
      사용자 PIN 번호 필요 여부
  * `walletId` \<String> optional\
    Wepin 사용자의 지갑 ID
  * `token` \<WepinToken>\
    Wepin Token 정보
    * `accessToken` \<String>\
      Wepin Access Token
    * `refreshToken` \<String>\
      Wepin Refresh Token&#x20;

Example

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

```java
Context context = this;
CompletableFuture<WepinUser> res = wepinWidget.register(context);
res.whenComplete((wepinUser, error) -> {
    if (error ==  null) {
        Log.d(TAG, "Wepin User is $wepinUser");
    } else {
        Log.d(TAG, "register error: $error");
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.register(context)
res?.whenComplete { wepinUser, error ->
    if (error == null) {
        Log.d(TAG, "Wepin User is $wepinUser")
    } else {
        Log.d(TAG, "register error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## getAccounts

앱에서 사용 가능한 사용자의 계정 정보(네트워크와 주소)를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. 파라미터가 없는 경우에는 사용자의 모든 계정 정보가 반환됩니다.

Parameters

* `networks` \<List\<String>> optional\
  반환받고자 하는 계정의 네트워크입니다. 네트워크로 지원하는 블록체인 목록은 아래 지원 블록체인 페이지에서 확인 가능합니다.
* `withEoa` \<Boolean> optional\
  AA 계정이 있는 경우, EOA 계정도 포함하여 반환할지 여부를 지정합니다.

{% content-ref url="/pages/jNG611rZkq69C8zZKglh" %}
[지원 블록체인](/wepin/supported-blockchains)
{% endcontent-ref %}

Return Value

* CompletableFuture\<List\<WepinAccount>>
  * `address` \<String>\
    사용자 계정의 주소
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `contract` \<String> *optional*\
    토큰의 Contract 주소
  * `isAA` \<Boolean> *optional*\
    AA 계정인지 여부

Example

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

<pre class="language-java"><code class="lang-java">List&#x3C;String> networks = List.of("Ethereum", "Kaia");
<strong>CompletableFuture&#x3C;List&#x3C;WepinAccount>> res = wepinWidget.getAccounts(networks, null);
</strong>res.whenComplete((result, error) -> {
    if (error ==  null) {
        Log.d(TAG, "WepinAccount List is $result");
    } else {
        Log.d(TAG, "getAccounts error: $error");
    }
});
</code></pre>

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.getAccounts(networks)
res?.whenComplete { accounts, error ->
    if (error == null) {
        Log.d(TAG, "Account List is $accounts")
    } else {
        Log.d(TAG, "getAccounts error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## getBalance

정의 잔액(수량) 정보를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. `accounts` 파라미터가 없는 경우에는 사용자의 모든 계정의 잔액이 반환됩니다.

Parameters

* `accounts` \<List\<WepinAccount>> *optional*
  * `network` \<String>\
    잔액을 조회할 사용자 계정의 네트워크 종류
  * `address` \<String>\
    잔액을 조회할 사용자 계정의 주소
  * `isAA` \<Boolean> *optional*\
    AA계정인지 여부

Return Value

* CompletableFuture\<List\<WepinAccountBalanceInfo>>
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `address` \<String>\
    사용자 계정의 주소
  * `symbol` \<String>\
    네트워크 심볼
  * `balance` \<String>\
    보유하고 있는 네트워크 코인의 수량
  * `token` \<List\<WepinTokenBalanceInfo>>
    * `symbol` \<String>\
      토큰 심볼
    * `balance` \<String>\
      보유하고 있는 토큰의 수량
    * `contract` \<String>\
      토큰 Contract 주소소

Example

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

```java
CompletableFuture<List<WepinAccountBalanceInfo>> res = wepinWidget.getBalance(accounts);
res.whenComplete((result, error) -> {
    if (error ==  null) {
        Log.d(TAG, "Balances is $result");
    } else {
        Log.d(TAG, "getBalance error: $error");
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.getBalance()
res?.whenComplete { balance, error ->
    if (error == null) {
        Log.d(TAG, "Balance is $balance")
    } else {
        Log.d(TAG, "getBalance error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## getNFTs

사용자의 NFT를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. `networks`파라미터가 없는 경우에는 사용자의 모든 NFT 정보가 반환됩니다.

Parameters

* `refresh` \<Boolean>\
  NFT 데이터를 온체인에서 새로 조회할지 여부
* `networks` \<List\<String>> optional\
  NFT 를 필터링할 네트워크 이름 목록

Return Value

* CompletableFuture\<List\<WepinNFT>>
  * `account` \<WepinAccount>
    * `address` \<String>\
      사용자 계정의 주소
    * `network` \<String>\
      사용자 계정의 네트워크 종류
    * `contract` \<String> *optional*\
      토큰의 Contract 주소
    * `isAA` \<Boolean> *optional*\
      AA 계정인지 여부
  * contract \<WepinNFTContract>
    * `name` \<String>\
      NFT Contract 이름
    * `address` \<String>\
      NFT Contract 주소
    * `scheme` \<String>\
      NFT의 스킴
    * `description` \<String> *optional*\
      NFT Contract의 설명
    * `network` \<String>\
      NFT Contract 와 연결된 네트워크
    * `externalLink` \<String> *optional*\
      NFT Contract와 관련된 외부 링크
    * `imageUrl` \<String> *optional*\
      NFT Contract와 관련된 이미지 URL
  * `name` \<String>\
    NFT 이름
  * `description` \<String>\
    NFT 의 설명
  * `externalLink` \<String>\
    NFT 와 관련된 외부 링크
  * `imageUrl` \<String>\
    NFT 와 관련된 이미지 URL
  * `contentUrl` \<String> *optional*\
    NFT와 연결된 콘텐츠의 URL
  * `quantity` \<Int> *optional*\
    NFT의 수량
  * `contentType` \<String>\
    NFT 의 콘텐츠 유형<'image'|'video'>
  * `state` \<Int>\
    NFT의 상태

Example

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

```java
CompletableFuture<List<WepinNFT>> res = wepinWidget.getNFTs(true, null);
res.whenComplete((result, error) -> {
    if (error ==  null) {
        Log.d(TAG, "NFT List is $result");
    } else {
        Log.d(TAG, "getNFTs error: $error");
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.getNFTs(true)
res?.whenComplete { nfts, error ->
    if (error == null) {
        Log.d(TAG, "Wepin NFT List is $nfts")
    } else {
        Log.d(TAG, "getNFTs error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## send

위젯을 이용하여 send기능을 수행하고 send 트랜젝션의 ID정보를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다.

Parameters

* context \<Context>\
  애플리케이션 특정 리소스와 클래스에 대한 접근을 제공하고 애플리케이션 환경에 관한 정보를 제공하기 때문에 Android에서 필수적입니다. 이는 새로운 액티비티를 시작하거나, 애플리케이션 자산에 접근하거나, 시스템 서비스를 검색하는 등의 작업에 사용됩니다.\
  `send(context)`와 같은 메서드를 호출할 때는 올바른 작동을 보장하기 위해 적절한 Context(예: `Activity` 또는 `Application context`)를 전달해야 합니다. UI 관련 작업(예: 새 화면 열기)의 경우에는 Activity context를 사용하는 것이 권장됩니다.
* `account` \<WepinAccount>
  * `address` \<String>\
    사용자 계정의 주소
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `contract` \<String> *optional*\
    토큰의 Contract 주소
  * `isAA` \<Boolean> *optional*\
    AA 계정인지 여부
* txData \<WepinTxData> *optional*
  * `toAddress` \<String>\
    전송 받을 주소
  * `amount` \<String>\
    전송할 수량

Return Value

* CompletableFuture\<WepinSendResponse>
  * `txId` \<String>\
    send 트랜젝션의 txID

Example

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

```java
Context context = this;
CompletableFuture<WepinSendResponse> res = wepinWidget.send(context, account);
res.whenComplete((sendResult, error) -> {
    if (error ==  null) {
        Log.d(TAG, "Send Result is $sendResult");
    } else {
        Log.d(TAG, "send error: $error");
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.send(context, account, txData)
res?.whenComplete { result, error ->
    if (error == null) {
        Log.d(TAG, "Send Result is $result")
    } else {
        Log.d(TAG, "send error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## receive

`receive` 메서드는 지정된 계정과 연관된 계정 정보 페이지를 엽니다. 이 메서드는 위핀에 로그인한 후에만 사용할 수 있습니다.

Parameters

* context \<Context>\
  애플리케이션 특정 리소스와 클래스에 대한 접근을 제공하고 애플리케이션 환경에 관한 정보를 제공하기 때문에 Android에서 필수적입니다. 이는 새로운 액티비티를 시작하거나, 애플리케이션 자산에 접근하거나, 시스템 서비스를 검색하는 등의 작업에 사용됩니다.\
  `receive(context)`와 같은 메서드를 호출할 때는 올바른 작동을 보장하기 위해 적절한 Context(예: `Activity` 또는 `Application context`)를 전달해야 합니다. UI 관련 작업(예: 새 화면 열기)의 경우에는 Activity context를 사용하는 것이 권장됩니다.
* `account` \<WepinAccount>
  * `address` \<String>\
    사용자 계정의 주소
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `contract` \<String> *optional*\
    토큰의 Contract 주소
  * `isAA` \<Boolean> *optional*\
    AA 계정인지 여부

Return Value

* CompletableFuture\<WepinReceiveResponse>
  * `account` \<WepinAccount>
    * `address` \<String>\
      사용자 계정의 주소
    * `network` \<String>\
      사용자 계정의 네트워크 종류
    * `contract` \<String> *optional*\
      토큰의 Contract 주소
    * `isAA` \<Boolean> *optional*\
      AA 계정인지 여부

Example

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

```java
Context context = this;
CompletableFuture<WepinReceiveResponse> res = wepinWidget.receive(context, account);
res.whenComplete((result, error) -> {
    if (error ==  null) {
        Log.d(TAG, "Receive Result is $result");
    } else {
        Log.d(TAG, "receive error: $error");
    }
});
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val res = wepinWidget.receive(context, account)
res?.whenComplete { result, error ->
    if (error == null) {
        Log.d(TAG, "Receive Result is $result")
    } else {
        Log.d(TAG, "receive error: $error")
    }
```

{% endtab %}
{% endtabs %}

***

## finalize

```kotlin
wepinWidget.finalize()
```

Wepin Widget SDK 사용을 종료합니다.

### **Parameters**

* None

### **Return Value**

* None

### **Example**

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

```java
wepinWidget.finalize();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
wepinWidget.finalize()
```

{% endtab %}
{% endtabs %}

## login

#### `WepinWidget` 에 통합된 `WepinLogin` 을 사용하지 않고 별도의 `WepinLogin`을 사용할 때, 두 SDK 의 버전이 동일하지 않은 경우 에러가 발생할 수 있습니다.

`login` 변수는 다양한 인증 방법을 포함한 위핀 로그인 라이브러리로, 사용자가 여러 방식으로 로그인할 수 있도록 합니다. 이메일 및 비밀번호 로그인, OAuth 프로바이더 로그인, ID Token 또는 Access Token을 사용한 로그인 등을 지원합니다. 각 메서드에 대한 자세한 정보는 공식 라이브러리 문서 [Login Library 가이드](/widget-integration/android-java-and-kotlin-sdk/login-library)에서 확인할 수 있습니다.

### **Available Methods**

* [`loginWithOauthProvider`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithoauthprovider)
* [`signUpWithEmailAndPassword`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#signupwithemailandpassword)
* [`loginWithEmailAndPassword`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithemailandpassword)
* [`loginWithIdToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithidtoken)
* [`loginWithAccessToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithaccesstoken)
* [`getRefreshFirebaseToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#getrefreshfirebasetoken)
* [`loginWepin`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwepin)
* [`getCurrentWepinUser`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#getcurrentwepinuser)
* [`logout`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#logoutwepin)

이 메서드들은 다양한 로그인 시나리오를 지원하며, 필요에 맞는 적절한 방법을 선택할 수 있습니다.

**Exception**

* [WepinError](https://docs.wepin.io/widget-integration/flutter-sdk/widget/methods#wepinerror)

**Example**

Copy

<pre class="language-kotlin"><code class="lang-kotlin"><strong>// OAuth Provider를 사용한 로그인
</strong>wepinSDK.login.loginWithOauthProvider("google", "your-client-id")
    .thenCompose { authResult ->
        // ID Token을 사용한 로그인
        wepinSDK.login.loginWithIdToken(authResult.idToken)
    }.thenCompose { idTokenResult ->
        // 위핀에 로그인
        wepinSDK.login.loginWepin(idTokenResult)
    }.thenAccept { user ->
        Log.d("WepinSDK", "로그인 성공! 사용자 정보: $user")
    }.exceptionally { e ->
        Log.e("WepinSDK", "로그인 실패: ${e.message}", e)
        null
    }

// 이메일 및 비밀번호로 회원가입 및 로그인
wepinSDK.login.signUpWithEmailAndPassword(
    email = 'example@example.com', 
    password = 'password123'
).thenAccept { signUpResult ->
    Log.d("WepinSDK", "로그인 성공! 사용자 정보: $user")
}.exceptionally { error ->
    if (error is WepinError) {
    }
}

// 현재 로그인된 사용자 가져오기
var currentUser = wepinSDK.login.getCurrentWepinUser()
    .thenAccept { user ->
        Log.d("WepinSDK", "현재 사용자: $user")
    }.exceptionally { e ->
        Log.e("WepinSDK", "사용자 가져오기 실패", e)
        null
    }

// 로그아웃
wepinSDK.login.logout()
    .thenAccept { result ->
        Log.d("WepinSDK", "로그아웃 결과: $result")
    }.exceptionally { e ->
        Log.e("WepinSDK", "로그아웃 실패", e)
        null
    }    
</code></pre>


# iOS: Swift SDK

이 문서는 위핀 위젯을 iOS에 통합하기 위한 절차를 설명합니다.


# 로그인

소셜 로그인과 같은 OAuth 인증 토큰 또는 이메일로 위핀에 로그인 하는 방법에 대한 안내 페이지입니다.


# 설치

## 요구사항 <a href="#requirements" id="requirements"></a>

* iOS 13+
* Swift 5.x
* Xcode 16+

{% hint style="info" %}
참고: v1.0.0 이전 버전에서 설치한 경우에만 확인해주세요.\
v1.0.0 업데이트에는 저장소 키 변경 등 앱 동작에 영향을 줄 수 있는 중요한 변경사항이 포함되어 있습니다. v1.0.0 이전 버전을 사용 중이었다면, 다음 변경 사항을 반드시 먼저 확인해주세요.
{% endhint %}

#### 저장소 마이그레이션 안내 (v1.0.0 기준) <a href="#storage-migration-notice-from-v1.0.0" id="storage-migration-notice-from-v1.0.0"></a>

* v1.0.0부터 저장소 키 변경 정책이 적용되어, 기존 저장된 데이터에 접근할 수 없는 경우가 발생할 수 있습니다.
* &#x20;키가 유효하지 않은 경우에 한해, 기존 저장 데이터는 자동으로 초기화되고 새 키가 생성됩니다.
* 키가 정상적으로 유지되는 경우, 기존 데이터는 그대로 유지됩니다.
* v1.0.0 이후 버전에서 이전 버전으로 다운그레이드할 경우, 기존 데이터에 접근하지 못할 수 있습니다.

{% hint style="info" %}
업데이트 전에 잠재적인 문제를 방지하기 위해 데이터를 백업해두는 것을 추천드립니다.
{% endhint %}

## 설치하기 <a href="#installation" id="installation"></a>

WepinLogin은 CocoaPods를 통해 사용할 수 있습니다. 설치하려면 Podfile에 다음 줄을 추가하시면 됩니다.

```
pod 'WepinLogin'
```

> ⚠️ **Notice** - Resolution for Build Errors
>
> WepinLogin 라이브러리를 빌드할 때 다음과 같은 오류가 발생할 수 있습니다:
>
> `SDK does not contain 'libarclite' at the path '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a'; try increasing the minimum deployment target`
>
> 이 오류는 secp256k1 라이브러리의 "최소 배포 대상" 설정을 변경하여 해결할 수 있습니다. secp256k1 라이브러리 프로젝트의 "최소 배포 대상" 설정을 Xcode에서 지원하는 iOS 버전으로 업데이트하십시오. 이렇게 하면 발생하고 있는 빌드 오류가 해결될 것입니다.

## 프로젝트에 WepinLogin 추가하기 <a href="#import-wepinlogin-into-your-project" id="import-wepinlogin-into-your-project"></a>

```sh
import WepinLogin
```

## Info.plist 설정 <a href="#setting-info.plist" id="setting-info.plist"></a>

앱의 URL 스킴을 Info.plist 파일에 추가해야 합니다. 이는 인증 과정이 끝난 후 앱으로 리다이렉션되기 위해 필요합니다.

#### Url scheme format : <mark style="color:blue;">`wepin. + Your Wepin App ID`</mark>

```
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <string>Editor</string>
  			<key>CFBundleURLName</key>
  			<string>unique name</string>
        <array>
            <string>wepin + your Wepin app id</string>
        </array>
    </dict>
</array>
```

## Podfile 설정

Xcode 26.0.1 이상 버전 사용 시 빌드 에러가 발생할 수 있습니다.

> error Unable to find module dependency: 'bcrypt' (in tarrget 'WepinLogin' from project 'Pods')

위와 같은 에러가 발생하는 경우 Podfile 에 아래 코드를 추가해주세요.

```
post_install do |installer| 
  installer.pods_project.targets.each do |target| 
    target.build_configurations.each do |config| 
      config.build_settings['SWIFT_ENABLE_EXPLICIT_MODULES'] = 'NO' 
    end 
  end 
end
```

## Release

릴리즈된 패키지 버전은 아래 깃허브에서 확인 가능합니다.

{% embed url="<https://github.com/WepinWallet/wepin-ios-sdk-login-v1/releases>" %}


# 초기화하기

Wepin iOS 로그인 라이브러리를 초기화하는 방법은 다음과 같습니다.&#x20;

WepinLogin 인스턴스를 생성하기 전에, App ID와 App Key를 WepinLoginParams 객체에 다음과 같이 전달해 주세요.

```swift
let initParam = WepinLoginParams(appId: appId, appKey: appKey)
```

이전에 생성한 WepinLoginParams를 전달하여 WepinLogin 인스턴스를 생성해 주세요.

```swift
var wepin = WepinLogin(initParam);
```

WepinLogin 인스턴스를 생성한 후, 초기화를 진행하기 위해 `initialize` 메서드를 호출하세요.

```swift
await wepin!.initialize()
```

### Example

```swift
let appKey: String = "Wepin-App-Key"
let appId: String = "Wepin-App-ID"
var wepin: WepinLogin? = nil
let initParam = WepinLoginParams(appId: appId, appKey: appKey)
wepin = WepinLogin(initParam)
// Call initialize function
do{
    let res = try await wepin!.initialize()
    self.tvResult.text = String("Successed: " + String(res!))
} catch (let error){
    self.tvResult.text = String("Faild: \(error)")
}
```

## isInitialized

`isInitialized` 메서드를 사용하여 WepinLogin 인스턴스가 올바르게 초기화되었는지 확인할 수 있습니다. 반환값은 다음과 같습니다:

* \<Bool>\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

```swift
let result = wepin!.isInitialized()
```


# 메서드

다음은 Wepin iOS Login Library에서 제공하는 메서드입니다.&#x20;

Wepin Login Library를 초기화한 후에 사용할 수 있습니다.

## loginWithOauthProvider

```swift
await wepin!.loginWithOauthProvider(params)
```

In-app browser가 열리고 OAuth provider에 로그인 합니다. Firebase 로그인 정보를 가져오려면 loginWithIdToken() 또는 loginWithAccessToken() 메서드를 호출해야 합니다.

**Parameters**

* `params` \<WepinLoginOauth2Params>
  * `provider` <'google'|'naver'|'discord'|'apple'> - Provider for login
  * `clientId` \<String>
* `viewController` \<UIViewController>

**Returns**

* \<WepinLoginOauthResult>
  * `provider` \<String> - login provider
  * `token` \<String> - accessToken (if provider is "naver" or "discord") or idToken (if provider is "google" or "apple")
  * `type` \<WepinOauthTokenType> - type of token

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let oauthParams = WepinLoginOauth2Params(provider: "discord", clientId: self.discordClientId)
        let res = try await wepin!.loginWithOauthProvider(params: oauthParams, viewController: self)
        let privateKey = "private key for wepin id/access Token"
        // token sign 
        let sign = wepin!.getSignForLogin(privateKey: privateKey, message: res.token)
        //call loginWithIdToken() or loginWithAccessToken()
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## signUpWithEmailAndPassword

```swift
await wepin!.signUpWithEmailAndPassword(params: params)
```

이메일과 비밀번호로 Wepin Firebase에 회원가입을 합니다. 가입되지 않은 사용자의 경우 검증 이메일이 전송되며, `requiredEmailVerified` 오류가 발생합니다. 이미 가입된 사용자의 경우, `existedEmail` 오류가 발생하며 [loginWithEmailAndPassword](/widget-integration/ios-swift-sdk/login-library/methods#loginwithemailandpassword)를 호출하여 로그인 프로세스를 진행합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<WepinLoginWithEmailParams>
  * `email` \<String> - User email
  * `password` \<String> - User password
  * `locale` \<String> - **optional** Language for the verification email (default value: "en")

**Returns**

* \<WepinLoginResult>
  * `provider` \<WepinLoginProviders>
  * `token` \<WepinFBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` - wepin firebase refreshToken

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let email = "EMAIL-ADDRESS"
        let password = "PASSWORD"
        let params = WepinLoginWithEmailParams(email: email, password: password)
        wepinLoginRes = try await wepin!.signUpWithEmailAndPassword(params: params)
        self.tvResult.text = String("Successed: \(wepinLoginRes)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## loginWithEmailAndPassword

```swift
await wepin!.loginWithEmailAndPassword(params: params)
```

이메일과 비밀번호를 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<WepinLoginWithEmailParams>
  * `email` \<String> - User email
  * `password` \<String> - User password

**Returns**

* \<WepinLoginResult>
  * `provider` \<WepinLoginProviders>
  * `token` \<WepinFBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let email = "EMAIL-ADDRESS"
        let password = "PASSWORD"
        let params = WepinLoginWithEmailParams(email: email, password: password)
        wepinLoginRes = try await wepin!.loginWithEmailAndPassword(params: params)
        self.tvResult.text = String("Successed: \(wepinLoginRes)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## loginWithIdToken

```swift
await wepin!.loginWithIdToken(params: params)
```

외부 ID 토큰을 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<WepinLoginOauthIdTokenRequest>
  * `idToken` \<String> - ID token value to be used for login
  * `sign` \<String> **optional**- Signature value for the token provided as the first parameter.(Returned value of [getSignForLogin()](#getsignforlogin))

{% hint style="warning" %}
&#x20;Note

WepinLogin 버전 1.0.0부터는 `sign` 값이 선택 사항입니다.

[Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거하는 경우, `sign` 값을 사용하지 않아도 됩니다.

(Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제)

> 인증 키 메뉴는 이전에 인증 키를 발급한 경우에만 표시됩니다.

WepinLogin 버전 1.1.0부터는 `sign` 값이 제거되었습니다.

WepinLogin 버전 1.1.0 을 사용하는 경우 반드시 [Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거해야 합니다.
{% endhint %}

**Returns**

* \<WepinLoginResult>
  * `provider` \<WepinLoginProviders>
  * `token` \<WepinFBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let token = "ID-TOKEN"
        let sign = wepin!.getSignForLogin(privateKey: privateKey, message: token)
        let params = WepinLoginOauthIdTokenRequest(idToken: token, sign: sign!)
        wepinLoginRes = try await wepin!.loginWithIdToken(params: params)
        
        self.tvResult.text = String("Successed: \(wepinLoginRes)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## loginWithAccessToken

```swift
await wepin!.loginWithAccessToken(params: params)
```

외부 Access Token을 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

**Parameters**

* `params` \<WepinLoginOauthAccessTokenRequest>
  * `provider` <"naver"|"discord"> - Provider that issued the access token
  * `accessToken` \<String> - Access token value to be used for login
  * `sign` \<String> **optional** - Signature value for the token provided as the first parameter. (Returned value of [getSignForLogin()](#getsignforlogin))

{% hint style="warning" %}
&#x20;Note

WepinLogin 버전 1.0.0부터는 `sign` 값이 선택 사항입니다.

[Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거하는 경우, `sign` 값을 사용하지 않아도 됩니다.

(Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제)

> 인증 키 메뉴는 이전에 인증 키를 발급한 경우에만 표시됩니다.

WepinLogin 버전 1.1.0부터는 `sign` 값이 제거되었습니다.

WepinLogin 버전 1.1.0 을 사용하는 경우 반드시 [Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거해야 합니다.
{% endhint %}

**Returns**

* \<WepinLoginResult>
  * `provider` \<WepinLoginProviders>
  * `token` \<WepinFBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let token = "ACCESS-TOKEN"
        let sign = wepin!.getSignForLogin(privateKey: privateKey, message: token)
        let params = WepinLoginOauthAccessTokenRequest(provider: "discord", accessToken: token, sign: sign!)
        wepinLoginRes = try await wepin!.loginWithAccessToken(params: params)
        self.tvResult.text = String("Successed: \(wepinLoginRes)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## getRefreshFirebaseToken

```swift
await wepin!.getRefreshFirebaseToken()
```

현재  Wepin Firebase 토큰의 정보를 가져옵니다.

**Parameters**

* void

**Returns**

* \<WepinLoginResult>
  * `provider` \<WepinLoginProviders>
  * `token` \<WepinFBToken>
    * `idToken` \<String> - wepin firebase idToken
    * `refreshToken` \` - wepin firebase refreshToken

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let res = try await wepin!.getRefreshFirebaseToken()
        wepinLoginRes = res
        self.tvResult.text = String("Successed: \(res)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## loginWepin

```swift
await wepin!.loginWepin(params: wepinLoginRes)
```

지정한 로그인 프로바이더와 토큰을 사용하여 사용자를 위핀에 로그인합니다.

**Parameters**

매개변수는 이 모듈 내에서 loginWithEmailAndPassword(), loginWithIdToken(), loginWithAccessToken() 메서드의 반환 값을 활용해야 합니다.

* \<WepinLoginResult>
  * `provider` \<WepinLoginProviders>
  * `token` \<WepinFBToken>
    * `idToken` \<String> - Wepin Firebase idToken
    * `refreshToken` \` - Wepin Firebase refreshToken

**Returns**

* \<WepinUser> - An object containing the user's login status and information. The object includes:
  * status <'success'|'fail'> - The login status.
  * userInfo \<WepinUserInfo> **optional** - The user's information, including:
    * userId \<String> - The user's ID.
    * email \<String> - The user's email.
    * provider \<WepinLoginProviders> - 'google'|'apple'|'naver'|'discord'|'email'|'external\_token'
    * use2FA \<Bool> - Whether the user uses two-factor authentication.
  * walletId \<String> **optional** - The user's wallet ID.
  * userStatus: \<WepinUserStatus> **optional** - The user's status of wepin login. including:
    * loginStatus: \<WepinLoginStatus> - 'complete' | 'pinRequired' | 'registerRequired' - If the user's loginStatus value is not complete, it must be registered in the wepin.
    * pinRequired: **optional**
  * token: \<WepinToken> **optional** - The user's token of wepin.
    * refresh: \<String>
    * access \<String>

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let res = try await wepin!.loginWepin(params: wepinLoginRes)
        wepinLoginRes = nil
        self.tvResult.text = String("Successed: \(res)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## getCurrentWepinUser

```swift
await wepin!.getCurrentWepinUser()
```

위핀에 현재 로그인한 사용자의 정보를 가져옵니다.

**Parameters**

* void

**Returns**

* \<WepinUser> - An object containing the user's login status and information. The object includes:
  * status <'success'|'fail'> - The login status.
  * userInfo \<WepinUserInfo> **optional** - The user's information, including:
    * userId \<String> - The user's ID.
    * email \<String> - The user's email.
    * provider \<WepinLoginProviders> - 'google'|'apple'|'naver'|'discord'|'email'|'external\_token'
    * use2FA \<Bool> - Whether the user uses two-factor authentication.
  * walletId \<String> **optional** - The user's wallet ID.
  * userStatus: \<WepinUserStatus> **optional** - The user's status of wepin login. including:
    * loginStatus: \<WepinLoginStatus> - 'complete' | 'pinRequired' | 'registerRequired' - If the user's loginStatus value is not complete, it must be registered in the wepin.
    * pinRequired: **optional**
  * token: \<WepinToken> **optional** - The user's token of wepin.
    * refresh: \<String>
    * access \<String>

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let res = try await wepin!.getCurrentWepinUser()
        self.tvResult.text = String("Successed: \(res)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## logoutWepin

```swift
await wepin!.logoutWepin()
```

위핀에 로그인한 사용자를 로그아웃합니다.

**Parameters**

* void

**Returns**

* \<Bool>

**Exception**

* [Wepin Login Error](#wepinloginerror)

**Example**

```swift
    do {
        let res = try await wepin!.logoutWepin()
        self.tvResult.text = String("Successed: \(res)")
    } catch (let error){
        self.tvResult.text = String("Faild: \(error)")
    }
```

## getSignForLogin(Deprecated)

{% hint style="danger" %}
🔄 `getSignForLogin`은 더 이상 지원되지 않습니다\
• v1.1.0부터 `getSignForLogin()` 함수는 로그인 프로세스에서 `sign` 파라미터가 제거됨에 따라 더 이상 지원되지 않습니다.\
• 서명 없이 로그인하려면, **Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제**에서 인증키를 삭제해 주세요.\
• 인증키 메뉴는 이전에 키를 생성한 경우에만 표시됩니다.
{% endhint %}

발급자를 확인하기 위한 서명을 생성합니다. 주로 ID Token 및 Access Token과 같은 로그인 관련 정보를 위한 서명을 생성하는 데 사용됩니다.

```swift
wepin!.getSignForLogin(privateKey: privateKey, message: "")
```

**Parameters**

* `privKey` \<String> - The authentication key used for signature generation.
* `message` \<String> - The message or payload to be signed.

**Returns**

* String - The generated signature.

{% hint style="warning" %}
인증 키(privKey)는 안전하게 저장되어야 하며 외부에 노출되어서는 안 됩니다. 보안과 민감한 정보 보호를 강화하기 위해 getSignForLogin() 메서드는 프론트엔드가 아닌 백엔드에서 실행하는 것이 권장됩니다.
{% endhint %}

**Example**

```swift
let privKey = '0400112233445566778899001122334455667788990011223344556677889900'
let idToken = 'idtokenabcdef'
let sign = wepin!.getSignForLogin(privateKey: privKey, message: idToken)
```

## finalize

```swift
wepin!.finalize()
```

Wepin Login Library 를 종료합니다.

**Parameters**

* void

**Returns**

* void

**Example**

```swift
wepin!.finalize()
```

## WepinLoginError

| Error                          | Error Description                                                                                                                                                                                    |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalidParameters`            | One or more parameters provided are invalid or missing.                                                                                                                                              |
| `notInitialized`               | The WepinLoginLibrary has not been properly initialized.                                                                                                                                             |
| `invalidAppKey`                | The Wepin app key is invalid.                                                                                                                                                                        |
| `invalidLoginProvider`         | The login provider specified is not supported or is invalid.                                                                                                                                         |
| `invalidToken`                 | The token does not exist.                                                                                                                                                                            |
| `invalidLoginSession`          | The login session information does not exist.                                                                                                                                                        |
| `userCancelled`                | The user has cancelled the operation.                                                                                                                                                                |
| `unkonwError(message: String)` | An unknown error has occurred, and the cause is not identified.                                                                                                                                      |
| `notConnectedInternet`         | The system is unable to detect an active internet connection.                                                                                                                                        |
| `failedLogin`                  | The login attempt has failed due to incorrect credentials or other issues.                                                                                                                           |
| `alreadyLogout`                | The user is already logged out, so the logout operation cannot be performed again.                                                                                                                   |
| `alreadyInitialized`           | The WepinLoginLibrary is already initialized, so the logout operation cannot be performed again.                                                                                                     |
| `invalidEmailDomain`           | The provided email address's domain is not allowed or recognized by the system.                                                                                                                      |
| `failedSendEmail`              | The system encountered an error while sending an email. This is because the email address is invalid or we sent verification emails too often. Please change your email or try again after 1 minute. |
| `requiredEmailVerified`        | Email verification is required to proceed with the requested operation.                                                                                                                              |
| `incorrectEmailForm`           | The provided email address does not match the expected format.                                                                                                                                       |
| `incorrectPasswordForm`        | The provided password does not meet the required format or criteria.                                                                                                                                 |
| `notInitializedNetwork`        | The network or connection required for the operation has not been properly initialized.                                                                                                              |
| `requiredSignupEmail`          | The user needs to sign up with an email address to proceed.                                                                                                                                          |
| `failedEmailVerified`          | The WepinLoginLibrary encountered an issue while attempting to verify the provided email address.                                                                                                    |
| `failedPasswordStateSetting`   | The WepinLoginLibrary failed to set state of the password.                                                                                                                                           |
| `failedPasswordSetting`        | The WepinLoginLibrary failed to set the password.                                                                                                                                                    |
| `existedEmail`                 | The provided email address is already registered in Wepin.                                                                                                                                           |


# 핀 패드

RESTful API 사용 시, iOS 환경의 서비스에서 사용자의 PIN을 입력 받을 수 있는 UI 및 기능을 제공하는 패키지입니다.


# 설치

## 요구사항 <a href="#requirements" id="requirements"></a>

* iOS 13+
* Swift 5.x

{% hint style="info" %}
참고: v1.0.0 이전 버전에서 설치한 경우에만 확인해주세요.\
v1.0.0 업데이트에는 저장소 키 변경 등 앱 동작에 영향을 줄 수 있는 중요한 변경사항이 포함되어 있습니다. v1.0.0 이전 버전을 사용 중이었다면, 다음 변경 사항을 반드시 먼저 확인해주세요.
{% endhint %}

#### 저장소 마이그레이션 안내 (v1.0.0 기준) <a href="#storage-migration-notice-from-v1.0.0" id="storage-migration-notice-from-v1.0.0"></a>

* v1.0.0부터 저장소 키 변경 정책이 적용되어, 기존 저장된 데이터에 접근할 수 없는 경우가 발생할 수 있습니다.
* &#x20;키가 유효하지 않은 경우에 한해, 기존 저장 데이터는 자동으로 초기화되고 새 키가 생성됩니다.
* 키가 정상적으로 유지되는 경우, 기존 데이터는 그대로 유지됩니다.
* v1.0.0 이후 버전에서 이전 버전으로 다운그레이드할 경우, 기존 데이터에 접근하지 못할 수 있습니다.

{% hint style="info" %}
업데이트 전에 잠재적인 문제를 방지하기 위해 데이터를 백업해두는 것을 추천드립니다.
{% endhint %}

#### &#x20;WepinLogin과의 호환성 <a href="#compatibility-with-wepinlogin" id="compatibility-with-wepinlogin"></a>

* 이 모듈을 WepinLogin과 함께 사용하는 경우, **WepinLogin v1.0.0** 이상을 사용하고 있는지 확인해주세요.
* Wepin 모듈 간에 주요 버전이 다른 경우, 호환성 문제, 예상치 못한 오류, 또는 일관되지 않은 동작이 발생할 수 있습니다.
* 안정적인 통합을 위해서는 모든 Wepin 모듈을 v1.0.0 이상 버전으로 통일하여 사용하는 것을 권장합니다.
* **WepinPin v1.1.0** 부터 WepinPin에 WepinLogin이 포함되었습니다.

## 설치하기 <a href="#installation" id="installation"></a>

WepinPin은 CocoaPods를 통해 사용할 수 있습니다. 설치하려면 Podfile에 다음 줄을 추가하시면 됩니다.

```
pod 'WepinPin'
```

## Podfile 설정

Xcode 26.0.1 이상 버전 사용 시 빌드 에러가 발생할 수 있습니다.

> error Unable to find module dependency: 'bcrypt' (in tarrget 'WepinLogin' from project 'Pods')

위와 같은 에러가 발생하는 경우 Podfile 에 아래 코드를 추가해주세요.

```
post_install do |installer| 
  installer.pods_project.targets.each do |target| 
    target.build_configurations.each do |config| 
      config.build_settings['SWIFT_ENABLE_EXPLICIT_MODULES'] = 'NO' 
    end 
  end 
end
```

## 프로젝트에 WepinPin 추가하기 <a href="#import-wepinpin-into-your-project" id="import-wepinpin-into-your-project"></a>

```sh
import WepinPin
```

## Release

릴리즈된 패키지 버전은 아래 깃허브에서 확인 가능합니다.

{% embed url="<https://github.com/WepinWallet/wepin-ios-sdk-pin-v1/releases>" %}


# 초기화하기

Wepin iOS PIN Pad 라이브러리를 초기화하는 방법은 다음과 같습니다.&#x20;

`WepinPin` 인스턴스를 생성하기 전에, App ID와 App Key를 `WepinPinParams` 객체에 다음과 같이 전달해 주세요.

```swift
let initPinParam = WepinPinParams(appId: appId, appKey: appKey)
```

앞서 생성한 `WepinPinParams` 를 전달하면서 `WepinPin` 인스턴스를 생성해 주세요.

```swift
var wepinPin = WepinPin(initPinParam);
```

`WepinPin` 인스턴스생성 후 `initialize` 메서드를 호출하여 초기화를 합니다.

```swift
await wepinPin?.initialize(attributes: attributes)
```

#### parameters

&#x20;`attributes` \<WepinPinAttributes>

* `language` \<String>\
  핀 패드 화면의 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'` ,`'ja'`입니다.

#### Return value

`<Boolean>`\
정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### Example

```swift
let appKey: String = "Wepin-App-Key"
let appId: String = "Wepin-App-ID"
var wepinPin: WepinPin? = nil
let initPinParam = WepinPinParams(appId: appId, appKey: appKey)
wepinPin = WepinPin(initPinParam)
// Call initialize function
let attributes = WepinPinAttributes(language: "en")
if let res = try await wepinPin?.initialize(attributes: attributes) {
    self.tvResult.text = "Successed: \(res)"
} else {
    self.tvResult.text = "Failed: No result returned from initialization"
}
```

## isInitialized

`isInitialized` 메서드를 사용하여 `WepinPin` 인스턴스가 올바르게 초기화되었는지 확인할 수 있습니다. 반환 값은 다음과 같습니다:

* \<Bool>\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

```swift
let result = wepinPin!.isInitialized()
```

## changeLanguage

```swift
wepinPin!.changeLanguage(language: "ko")
```

핀 패드 화면에 표시되는 언어를 변경합니다. 현재 `'ko'`, `'en'`, `'ja'`만 지원됩니다. <br>

**Parameters**

* &#x20;`language` \<String>

### **Return value**

* \<Void>

### Example

```swift
wepinPin!.changeLanguage(language: "ko")
```


# 메서드

Wepin PIN Pad Library 초기화 이후 사용할 수 있습니다.

## &#x20;generateRegistrationPINBlock

```swift
await wepinPin!.generateRegistrationPINBlock()
```

사용자의  지갑생성 및 회원가입을 위해 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.

### **Parameters**

* `viewController` \<UIViewController> *optional*\
  위젯(WebView)을 모달 형태로 표시할 ViewController입니다. 해당 ViewController는 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.

{% hint style="warning" %}
Note&#x20;

**WepinPin v.1.1.0** 부터선택적으로 `UIViewController`를 파라미터로 전달할 수 있습니다.\
전달된 경우, 해당 컨트롤러를 사용해 WebView가 표시됩니다.\
전달하지 않으면, SDK는 메인 스레드에서 최상위 `UIViewController`를 자동으로 찾아 사용합니다.

단, 모달 표시 중이거나 커스텀 컨테이너 사용 시 등 일부 상황에서는 최상위 ViewController를 자동으로 감지하지 못할 수 있습니다. 가능하다면 명시적으로 `UIViewController`를 전달하는 것을 권장합니다.
{% endhint %}

### **Return value**

* `<RegistrationPinBlock>`
  * `uvd` \<EncUVD>

    * `b64Data` \<String> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<Int> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값

  * `hint` \<EncPinHint>

    * `data` \<string> \
      &#x20;PIN 힌트를 암호화한 값
    * `length` \<string>\
      PIN 힌트의 길이
    * `version` \<number>&#x20;

    &#x20;      PIN 힌트의 버전

### Example

```swift
do{
  let registrationPinBlock = try await wepinPin!.generateRegistrationPINBlock()
  if let registerPinBlock = registrationPinBlock {
  // You need to make a Wepin RESTful API request using the received data.  
  }
}catch(let error){
  print(error)
}

```

## generateAuthPINBlock

```swift
await wepinPin!.generateAuthPINBlock(3)
```

사용자 인증에필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `count` \<Int> **optional**&#x20;

  생성하려는 PIN Block의 갯수. 기본값은 `1` 입니다.
* `viewController`\<UIViewController> *optional*\
  위젯(WebView)을 모달 형태로 표시할 ViewController입니다. 해당 ViewController는 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.

{% hint style="warning" %}
Note&#x20;

**WepinPin v.1.1.0** 부터선택적으로 `UIViewController`를 파라미터로 전달할 수 있습니다.\
전달된 경우, 해당 컨트롤러를 사용해 WebView가 표시됩니다.\
전달하지 않으면, SDK는 메인 스레드에서 최상위 `UIViewController`를 자동으로 찾아 사용합니다.

단, 모달 표시 중이거나 커스텀 컨테이너 사용 시 등 일부 상황에서는 최상위 ViewController를 자동으로 감지하지 못할 수 있습니다. 가능하다면 명시적으로 `UIViewController`를 전달하는 것을 권장합니다.
{% endhint %}

### **Return value**

* `<AuthPinBlock>`
  * `uvdList` List\<EncUVD> \
    암호화된 PIN Block의 리스트
    * \<EncUVD>
      * `b64Data` \<String> \
        b64SKey의  원본키로 암호화된 데이터
      * `b64SKey` \<String> \
        b64Data 를 생성할때  사용하는 키
      * `seqNum` \<Int> **optional** \
        **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값.\
        Multi Tx 요청시, 반드시 받은 PIN Block의 순서대로 사용해야 합니다.(1,2,3...)
  * `otp` \<String> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### Example

```swift
do{
  let authPinBlock = try await wepinPin!.generateAuthPINBlock(3)
  if let authPinBlock = authPinBlock {
    // You need to make a Wepin RESTful API request using the received data.  
  }
}catch(let error){
  print(error)
}
```

## generateChangePINBlock

```swift
await wepinPin!.generateChangePINBlock()
```

사용자 PIN 변경을 위해 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `viewController` \<UIViewController> *optional*\
  위젯(WebView)을 모달 형태로 표시할 ViewController입니다. 해당 ViewController는 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.

{% hint style="warning" %}
Note&#x20;

**WepinPin v.1.1.0** 부터선택적으로 `UIViewController`를 파라미터로 전달할 수 있습니다.\
전달된 경우, 해당 컨트롤러를 사용해 WebView가 표시됩니다.\
전달하지 않으면, SDK는 메인 스레드에서 최상위 `UIViewController`를 자동으로 찾아 사용합니다.

단, 모달 표시 중이거나 커스텀 컨테이너 사용 시 등 일부 상황에서는 최상위 ViewController를 자동으로 감지하지 못할 수 있습니다. 가능하다면 명시적으로 `UIViewController`를 전달하는 것을 권장합니다.
{% endhint %}

### **Return Value**

* `<ChangePinBlock>`
  * `uvd` \<EncUVD>
    * `b64Data` \<String> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<Int> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값
  * `newUVD` \<EncUVD>
    * `b64Data` \<String> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<Int> **optional** \
      **P**IN Block 사용시 순서대로 사용되었는지 확인하기 위한 값.
  * `hint` \<EncPinHint>
    * `data` \<String> \
      &#x20;PIN 힌트를 암호화한 값
    * `length` \<String>\
      PIN 힌트의 길이
    * `version` \<Int> \
      PIN 힌트의 버전
  * `otp` \<String> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### Example

```swift
do{
  let changepPinBlock = try await wepinPin!.generateChangePINBlock()
  if let changepPinBlock = changePinBlock {
    // You need to make a Wepin RESTful API request using the received data.  
  }
}catch(let error){
  print(error)
}
```

## generateAuthOTP

```javascript
await wepinPin!.generateAuthOTPCode()
```

사용자로부터 OTP 코드를  입력받을 수 있는 화면을 띄우고 처리합니다.

### **Parameters**

* `viewController` \<UIViewController> *optional*\
  위젯(WebView)을 모달 형태로 표시할 ViewController입니다. 해당 ViewController는 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.

{% hint style="warning" %}
Note&#x20;

**WepinPin v.1.1.0** 부터선택적으로 `UIViewController`를 파라미터로 전달할 수 있습니다.\
전달된 경우, 해당 컨트롤러를 사용해 WebView가 표시됩니다.\
전달하지 않으면, SDK는 메인 스레드에서 최상위 `UIViewController`를 자동으로 찾아 사용합니다.

단, 모달 표시 중이거나 커스텀 컨테이너 사용 시 등 일부 상황에서는 최상위 ViewController를 자동으로 감지하지 못할 수 있습니다. 가능하다면 명시적으로 `UIViewController`를 전달하는 것을 권장합니다.
{% endhint %}

### **Return Value**

* `<AuthOTP>`
  * `code` \<String>\
    입력받은 OTP 코드

### Example

```swift
do{
  let authOTPCode = try await wepinPin!.generateAuthOTPCode()
  if let authOTPCode = authOTPCode {
    // You need to make a Wepin RESTful API request using the received data.  
  }
}catch(let error){
  print(error)
}
```

## finalize

```javascript
wepinPin!.finalize()
```

Wepin PIN Pad Library 사용을 종료합니다.

### **Parameters**

* `<Void>`

### **Return Value**

* `<Void>`

### Example

```swift
wepinPin!.finalize()
```


# 위젯


# 설치

WepinWidget 은 v1.1.0부터 제공됩니다.

## 요구사항 <a href="#requirements" id="requirements"></a>

* iOS 13+
* Swift 5.x
* Xcode 16+

#### &#x20;WepinLogin과의 호환성 <a href="#compatibility-with-wepinlogin" id="compatibility-with-wepinlogin"></a>

* WepinWidget 은 WepinLogin 을 포함하고 있습니다.&#x20;
* 이 모듈에 포함되지 않은 WepinLogin을 사용하는 경우, **WepinLogin v1.1.0** 이상을 사용하고 있는지 확인해주세요.
* Wepin 모듈 간에 주요 버전이 다른 경우, 호환성 문제, 예상치 못한 오류, 또는 일관되지 않은 동작이 발생할 수 있습니다.
* 안정적인 통합을 위해서는 모든 Wepin 모듈을 v1.1.0 이상 버전으로 통일하여 사용하는 것을 권장합니다.

## 설치하기 <a href="#installation" id="installation"></a>

WepinWidget은 CocoaPods를 통해 사용할 수 있습니다. 설치하려면 Podfile에 다음 줄을 추가하시면 됩니다.

```
pod 'WepinWidget'
```

## Podfile 설정

Xcode 26.0.1 이상 버전 사용 시 빌드 에러가 발생할 수 있습니다.

> error Unable to find module dependency: 'bcrypt' (in tarrget 'WepinLogin' from project 'Pods')

위와 같은 에러가 발생하는 경우 Podfile 에 아래 코드를 추가해주세요.

```
post_install do |installer| 
  installer.pods_project.targets.each do |target| 
    target.build_configurations.each do |config| 
      config.build_settings['SWIFT_ENABLE_EXPLICIT_MODULES'] = 'NO' 
    end 
  end 
end
```

## 프로젝트에 WepinWidget 추가하기 <a href="#import-wepinwidget-into-your-project" id="import-wepinwidget-into-your-project"></a>

```sh
import WepinWidget
```

## Release

릴리즈된 패키지 버전은 아래 깃허브에서 확인 가능합니다.

{% embed url="<https://github.com/WepinWallet/wepin-ios-sdk-widget-v1>" %}


# 초기화하기

Wepin iOS Widget Pad 라이브러리를 초기화하는 방법은 다음과 같습니다.&#x20;

`WepinWidget` 인스턴스를 생성하기 전에, App ID와 App Key를 `WepinWidgetParams` 객체에 다음과 같이 전달해 주세요.

```swift
let initWidgetParam = WepinWidgetParams(viewController: UIViewController, appId: appId, appKey: appKey)
```

앞서 생성한 `WepinWidgetParams` 를 전달하면서 `WepinWidget` 인스턴스를 생성해 주세요.

```swift
var wepinWidget = WepinWidget(initWidgetParam);
```

`WepinWidget` 인스턴스생성 후 `initialize` 메서드를 호출하여 초기화를 합니다.

```swift
await wepinWidget?.initialize(attributes: attributes)
```

#### parameters

&#x20;`attributes` \<WepinWidgetAttributes>

* `defaultLanguage` \<String>\
  위젯 화면의 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'` ,`'ja'`입니다.
* `defaultCurrency` \<String>\
  위젯 화면의 기본 통화 설정, 기본 값은 `'USD'` 입니다. 현재 지원하는 통화는 `'KRW'`, `'USD'`, `'JPY'` 입니다.

#### Return value

`<Boolean>`\
정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### Example

```swift
let appKey: String = "Wepin-App-Key"
let appId: String = "Wepin-App-ID"
var wepinWidget: WepinWidget? = nil
let initWidgetParam = WepinWidgetParams(viewController: self, appId: appId, appKey: appKey)
wepinWidget = WepinWidget(initWidgetParam)
// Call initialize function
let attributes = WepinWidgetAttributes(defaultLanguage: "en", defaultCurrency: "USD")
if let res = try await wepinWidget?.initialize(attributes: attributes) {
    self.tvResult.text = "Successed: \(res)"
} else {
    self.tvResult.text = "Failed: No result returned from initialization"
}
```

## isInitialized

`isInitialized` 메서드를 사용하여 `WepinWidget` 인스턴스가 올바르게 초기화되었는지 확인할 수 있습니다. 반환 값은 다음과 같습니다:

* \<Bool>\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

```swift
let result = wepinWidget!.isInitialized()
```

## changeLanguage

```swift
wepinWidget!.changeLanguage("ko", currency: "KRW")
```

위젯 화면에 표시되는 언어를 변경합니다. 현재 `'ko'`, `'en'`, `'ja'`만 지원됩니다. <br>

**Parameters**

* &#x20;`language`\<String>
* `currency` \<String>

### **Return value**

* \<Void>

### Example

<pre class="language-swift"><code class="lang-swift"><strong>wepinWidget!.changeLanguage("ko", currency: "KRW")
</strong></code></pre>


# 메서드

## getStatus

WepinSDK의 Lifecycle 상태 값을 반환합니다.

### Parameters

* None

### Return Value

* \<WepinLifeCycle>
  * notInitialized: `WepinSDK`이 초기화되지 않음
  * initializing: `WepinSDK`초기화 진행 중
  * initialized: `WepinSDK`초기화 완료
  * beforeLogin: `WepinSDK`은 초기화되었으나 사용자는 로그인 되지 않음
  * login: 사용자가 로그인 되었고 위핀에도 가입되어있음
  * loginBeforeRegister: 사용자가 로그인하였으나 위핀에 가입되지 않음

### Example

```swift
do {
    let statusResult = try await widget.getStatus()
    self.lifecycle = statusResult
    return lifecycle
} catch {
    self.lifecycle = .notInitialized
    return lifecycle
}
```

***

## loginWithUI

`loginWithUI()` 메서드는 위젯을 사용하여 로그인하는 기능을 제공하며, 로그인된 사용자의 정보를 반환합니다. 사용자가 이미 로그인되어 있는 경우, 위젯을 표시하지 않고 로그인된 사용자의 정보를 바로 반환합니다. 위젯 없이 로그인을 수행하려면, `login` 변수의 `loginWepin()` 메서드를 대신 사용해야 합니다.

### Parameters

* `viewController` \<UIViewController> - 위젯(WebView)을 모달 방식으로 표시할 기준이 되는 뷰 컨트롤러입니다. 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.
* `loginProviders`<\[LoginProviderInfo]>\
  위젯을 구성할 로그인 프로바이더들의 목록입니다. 빈 목록이 제공되면 이메일 로그인 기능만 사용할 수 있습니다.
  * `provider`\<String>\
    OAuth 로그인 프로바이더(예: 'google', 'naver', 'discord', 'apple')
  * `clientId`\<String>\
    OAuth 로그인 프로바이더의 클라이언트 ID입니다.
* `email`\<String> *optional*\
  `email` 매개변수는 위젯에서 로그인할 때 지정된 이메일 주소로 로그인할 수 있도록 합니다.

### Return Value

* \<WepinUser>
  * `status` \<String>\
    성공여부<'success'|'fail'>
  * `userInfo` \<WepinUserInfo> *optional*\
    사용자 정보
    * `userId` \<String>\
      Wepin 사용자 ID
    * `email` \<String>\
      Wepin 에 로그인된 사용자의 이메일 주소
    * `provider` \<WepinLoginProviders>\
      로그인 프로바이더 이름 <'google'|'apple'|'naver'|'discord'|'email'|'external\_toekn'>
    * `use2FA` \<Bool>\
      사용자 지갑에 2FA가 활성화 되어 있는지 여부
  * `userStatus` \<WepinUserStatus>\
    사용자 상태
    * `loginStatus` \<WepinLoginStatus>\
      로그인 상태<'complete'|'pinRequired'|'registerRequired'>
    * `pinRequired` \<Bool> *optional*\
      사용자 PIN 번호 필요 여부
  * `walletId` \<String> *optional*\
    Wepin 사용자의 지갑 ID
  * `token` \<WepinToken>\
    Wepin Token 정보
    * `access` \<String>\
      Wepin Access Token
    * `refresh` \<String>\
      Wepin Refresh Token&#x20;

### Example

```swift
let providerInfos: [LoginProviderInfo] = [
    LoginProviderInfo(provider: "google", clientId: "GOOGLE_CLIENT_ID"),
    LoginProviderInfo(provider: "apple", clientId: "APPLE_CLIENT_ID"),
    LoginProviderInfo(provider: "discord", clientId: "DISCORD_CLIENT_ID"),
    LoginProviderInfo(provider: "naver", clientId: "NAVER_CLIENT_ID"),
    LoginProviderInfo(provider: "facebook", clientId: "FACEBOOK_CLIENT_ID"),
    LoginProviderInfo(provider: "line", clientId: "LINE_CLIENT_ID")
]
let user = try await widget.loginWithUI(viewController: self, loginProviders: self.providerInfos)
```

***

## openWidget

위젯 창을 열어줍니다. 사용자가 로그인되어 있지 않으면 위젯 창이 열리지 않으므로, `openWidget`을 호출하기 전에 반드시 사용자가 위핀에 로그인되어 있어야 합니다. 로그인하려면 `loginWithUI` 매서드 또는 `login` 변수의 `loginWepin` 메서드를 사용해야 합니다.

### Parameters

* `viewController` \<UIViewController> - 위젯(WebView)을 모달 방식으로 표시할 기준이 되는 뷰 컨트롤러입니다. 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.

### Return Value

* \<Bool>\
  성공적으로 위젯이 열린 경우 true 반환

### Example

```swift
do {
    let result = try await widget.openWidget(viewController: self)
    updateStatus(result ? "Widget Opened" : "Open Widget Failed")
} catch {
    updateStatus("Error: \(error.localizedDescription)")
}
```

***

## closeWidget

위젯 창을 닫습니다. 창을 닫아도 로그아웃되지 않습니다.

### Parameters

* None

### Return Value

* None

### Example

```swift
try wepinWidget?.closeWidget()
```

***

## register

사용자를 위에 등록합니다. 가입 및 로그인 후 위핀 위젯의 등록 페이지가 열리며, 위핀 서비스에 등록(지갑 생성 및 계정 생성)을 진행합니다. 이 기능은 `WepinSDK`의 `WepinLifeCycle`이 `loginBeforeRegister` 상태일 때만 사용할 수 있습니다. `loginWithUI` 매서드 또는 `login` 변수의 `loginWepin` 메서드를 호출한 후, `userStatus`의 `loginStatus` 값이 'complete'가 아니면 이 메서드를 호출해야 합니다.

### Parameters

* `viewController` \<UIViewController> - 위젯(WebView)을 모달 방식으로 표시할 기준이 되는 뷰 컨트롤러입니다. 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.

### Return Value

* \<WepinUser>
  * `status` \<String>\
    성공여부<'success'|'fail'>
  * `userInfo` \<WepinUserInfo> *optional*\
    사용자 정보
    * `userId` \<String>\
      Wepin 사용자 ID
    * `email` \<String>\
      Wepin 에 로그인된 사용자의 이메일 주소
    * `provider` \<WepinLoginProviders>\
      로그인 프로바이더 이름 <'google'|'apple'|'naver'|'discord'|'email'|'external\_toekn'>
    * `use2FA` \<Bool>\
      사용자 지갑에 2FA가 활성화 되어 있는지 여부
  * `userStatus` \<WepinUserStatus>\
    사용자 상태
    * `loginStatus` \<WepinLoginStatus>\
      로그인 상태<'complete'|'pinRequired'|'registerRequired'>
    * `pinRequired` \<Bool> *optional*\
      사용자 PIN 번호 필요 여부
  * `walletId` \<String> *optional*\
    Wepin 사용자의 지갑 ID
  * `token` \<WepinToken>\
    Wepin Token 정보
    * `access` \<String>\
      Wepin Access Token
    * `refresh` \<String>\
      Wepin Refresh Token&#x20;

### Example

```swift
do {
    let result = try await widget.register(viewController: self)
    self.updateStatus("Registered: \(result)")
} catch {
    self.updateStatus("Error: \(error.localizedDescription)")
}
```

***

## getAccounts

앱에서 사용 가능한 사용자의 계정 정보(네트워크와 주소)를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. 파라미터가 없는 경우에는 사용자의 모든 계정 정보가 반환됩니다.

### Parameters

* `networks` <\[String]> *optional*\
  반환받고자 하는 계정의 네트워크입니다. 네트워크로 지원하는 블록체인 목록은 아래 지원 블록체인 페이지에서 확인 가능합니다.
* `withEoa` \<Bool> *optional*\
  AA 계정이 있는 경우, EOA 계정도 포함하여 반환할지 여부를 지정합니다.

{% content-ref url="/pages/jNG611rZkq69C8zZKglh" %}
[지원 블록체인](/wepin/supported-blockchains)
{% endcontent-ref %}

### Return Value

* <\[WepinAccount]>
  * `address` \<String>\
    사용자 계정의 주소
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `contract` \<String> *optional*\
    토큰의 Contract 주소
  * `isAA` \<Bool> *optional*\
    AA 계정인지 여부

### Example

```swift
do {
    let accounts = try await widget.getAccounts()
    self.updateStatus("Accounts: \(accounts)")
} catch {
    self.updateStatus("Error: \(error.localizedDescription)")
}
```

***

## getBalance

정의 잔액(수량) 정보를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. `accounts` 파라미터가 없는 경우에는 사용자의 모든 계정의 잔액이 반환됩니다.

### Parameters

* `accounts` <\[WepinAccount]> *optional*
  * `network` \<String>\
    잔액을 조회할 사용자 계정의 네트워크 종류
  * `address` \<String>\
    잔액을 조회할 사용자 계정의 주소
  * `contract` \<String> optional\
    토큰의 컨트렉트 주소
  * `isAA` \<Boolean> *optional*\
    AA계정인지 여부

### Return Value

* <\[WepinAccountBalanceInfo]>
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `address` \<String>\
    사용자 계정의 주소
  * `symbol` \<String>\
    네트워크 심볼
  * `balance` \<String>\
    보유하고 있는 네트워크 코인의 수량
  * `token` <\[WepinTokenBalanceInfo]>
    * `symbol` \<String>\
      토큰 심볼
    * `balance` \<String>\
      보유하고 있는 토큰의 수량
    * `contract` \<String>\
      토큰 Contract 주소소

### Example

```swift
do {
    let balance = try await widget.getBalance()
    self.updateStatus("Balance: \(balance)")
} catch {
    self.updateStatus("Error: \(error.localizedDescription)")
}
```

***

## getNFTs

사용자의 NFT를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. `networks`파라미터가 없는 경우에는 사용자의 모든 NFT 정보가 반환됩니다.

### Parameters

* `refresh` \<Bool>\
  NFT 데이터를 온체인에서 새로 조회할지 여부
* `networks` <\[String]> *optional*\
  NFT 를 필터링할 네트워크 이름 목록

### Return Value

* <\[WepinNFT]>
  * `account` \<WepinAccount>
    * `address` \<String>\
      사용자 계정의 주소
    * `network` \<String>\
      사용자 계정의 네트워크 종류
    * `contract` \<String> *optional*\
      토큰의 Contract 주소
    * `isAA` \<Bool> *optional*\
      AA 계정인지 여부
  * contract \<WepinNFTContract>
    * `name` \<String>\
      NFT Contract 이름
    * `address` \<String>\
      NFT Contract 주소
    * `scheme` \<String>\
      NFT의 스킴
    * `description` \<String> *optional*\
      NFT Contract의 설명
    * `network` \<String>\
      NFT Contract 와 연결된 네트워크
    * `externalLink` \<String> *optional*\
      NFT Contract와 관련된 외부 링크
    * `imageUrl` \<String> *optional*\
      NFT Contract와 관련된 이미지 URL
  * `name` \<String>\
    NFT 이름
  * `description` \<String>\
    NFT 의 설명
  * `externalLink` \<String>\
    NFT 와 관련된 외부 링크
  * `imageUrl` \<String>\
    NFT 와 관련된 이미지 URL
  * `contentUrl` \<String> *optional*\
    NFT와 연결된 콘텐츠의 URL
  * `quantity` \<Int> *optional*\
    NFT의 수량
  * `contentType` \<String>\
    NFT 의 콘텐츠 유형<'image'|'video'>
  * `state` \<Int>\
    NFT의 상태

### Example

```swift
do {
    let nfts = try await widget.getNFTs(refresh: false)
    self.updateStatus("NFTs: \(nfts)")
} catch {
    self.updateStatus("Error: \(error.localizedDescription)")
}
```

***

## send

위젯을 이용하여 send기능을 수행하고 send 트랜젝션의 ID정보를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다.

### Parameters

* `viewController` \<UIViewController> - 위젯(WebView)을 모달 방식으로 표시할 기준이 되는 뷰 컨트롤러입니다. 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.
* `account` \<WepinAccount>
  * `address` \<String>\
    사용자 계정의 주소
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `contract` \<String> *optional*\
    토큰의 Contract 주소
  * `isAA` \<Boolean> *optional*\
    AA 계정인지 여부
* txData \<WepinTxData> *optional*
  * `toAddress` \<String>\
    전송 받을 주소
  * `amount` \<String>\
    전송할 수량

### Return Value

* \<WepinSendResponse>
  * `txId` \<String>\
    send 트랜젝션의 txID

### Example

```swift
do {
     let result = try await widget.send(viewController: self, account: account)
    updateStatus("Send success: \(result)")
} catch {
    updateStatus("Error: \(error.localizedDescription)")
}
```

***

## receive

`receive` 메서드는 지정된 계정과 연관된 계정 정보 페이지를 엽니다. 이 메서드는 위핀에 로그인한 후에만 사용할 수 있습니다.

### Parameters

* `viewController` \<UIViewController> - 위젯(WebView)을 모달 방식으로 표시할 기준이 되는 뷰 컨트롤러입니다. 위젯이 올바른 화면 위에 표시될 수 있도록 표시 컨텍스트를 제공합니다.
* `account` \<WepinAccount>
  * `address` \<String>\
    사용자 계정의 주소
  * `network` \<String>\
    사용자 계정의 네트워크 종류
  * `contract` \<String> *optional*\
    토큰의 Contract 주소
  * `isAA` \<Boolean> *optional*\
    AA 계정인지 여부

### Return Value

* \<WepinReceiveResponse>
  * `account` \<WepinAccount>
    * `address` \<String>\
      사용자 계정의 주소
    * `network` \<String>\
      사용자 계정의 네트워크 종류
    * `contract` \<String> *optional*\
      토큰의 Contract 주소
    * `isAA` \<Boolean> *optional*\
      AA 계정인지 여부

### Example

```swift
do {
    let result = try await widget.receive(viewController: self, account: account)
    updateStatus("Receive success: \(result)")
} catch {
    updateStatus("Error: \(error.localizedDescription)")
}
```

***

## finalize

```kotlin
wepinWidget.finalize()
```

Wepin Widget SDK 사용을 종료합니다.

### **Parameters**

* None

### **Return Value**

* None

### Example

```swift
try await wepin.finalize()
```

## login

#### `WepinWidget` 에 통합된 `WepinLogin` 을 사용하지 않고 별도의 `WepinLogin`을 사용할 때, 두 SDK 의 버전이 동일하지 않은 경우 에러가 발생할 수 있습니다.

`login` 변수는 다양한 인증 방법을 포함한 위핀 로그인 라이브러리로, 사용자가 여러 방식으로 로그인할 수 있도록 합니다. 이메일 및 비밀번호 로그인, OAuth 프로바이더 로그인, ID Token 또는 Access Token을 사용한 로그인 등을 지원합니다. 각 메서드에 대한 자세한 정보는 공식 라이브러리 문서 [Login Library 가이드](/widget-integration/android-java-and-kotlin-sdk/login-library)에서 확인할 수 있습니다.

### **Available Methods**

* [`loginWithOauthProvider`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithoauthprovider)
* [`signUpWithEmailAndPassword`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#signupwithemailandpassword)
* [`loginWithEmailAndPassword`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithemailandpassword)
* [`loginWithIdToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithidtoken)
* [`loginWithAccessToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwithaccesstoken)
* [`getRefreshFirebaseToken`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#getrefreshfirebasetoken)
* [`loginWepin`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#loginwepin)
* [`getCurrentWepinUser`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#getcurrentwepinuser)
* [`logout`](https://docs.wepin.io/widget-integration/ios-swift-sdk/login-library/methods#logoutwepin)

이 메서드들은 다양한 로그인 시나리오를 지원하며, 필요에 맞는 적절한 방법을 선택할 수 있습니다.

**Exception**

* [WepinError](https://docs.wepin.io/widget-integration/flutter-sdk/widget/methods#wepinerror)

**Example**

Copy

<pre class="language-swift"><code class="lang-swift"><strong>// OAuth Provider를 사용한 로그인
</strong>do {
    let oauthParams = WepinLoginOauth2Params(provider: "discord", clientId: self.discordClientId)
    let res = try await wepin!.login.loginWithOauthProvider(params: oauthParams, viewController: self)
    let privateKey = "private key for wepin id/access Token"
        //call loginWithIdToken() or loginWithAccessToken()
} catch (let error){
    self.tvResult.text = String("Faild: \(error)")
}

//Email을 사용한 회원가입입
do {
    let email = "EMAIL-ADDRESS"
    let password = "PASSWORD"
    let params = WepinLoginWithEmailParams(email: email, password: password)
    wepinLoginRes = try await wepin!.login.signUpWithEmailAndPassword(params: params)
    self.tvResult.text = String("Successed: \(wepinLoginRes)")
} catch (let error){
    self.tvResult.text = String("Faild: \(error)")
}

//IDToken 을 사용한 로그인
do {
    let token = "ID-TOKEN"
    let params = WepinLoginOauthIdTokenRequest(idToken: token)
    wepinLoginRes = try await wepin!.login.loginWithIdToken(params: params)
        
    self.tvResult.text = String("Successed: \(wepinLoginRes)")
} catch (let error){
    self.tvResult.text = String("Faild: \(error)")
}

//위핀 로그인인
do {
    let res = try await wepin!.login.loginWepin(params: wepinLoginRes)
    wepinLoginRes = nil
    self.tvResult.text = String("Successed: \(res)")
} catch (let error){
    self.tvResult.text = String("Faild: \(error)")
}

//현재 로그인 된 사용자 정보 조회
do {
    let res = try await wepin!.login.getCurrentWepinUser()
    self.tvResult.text = String("Successed: \(res)")
} catch (let error){
    self.tvResult.text = String("Faild: \(error)")
}

//로그아웃
do {
    let res = try await wepin!.login.logoutWepin()
    self.tvResult.text = String("Successed: \(res)")
} catch (let error){
    self.tvResult.text = String("Faild: \(error)")
}
</code></pre>


# Flutter SDK

이 문서는 Flutter SDK 을 이용하여 Flutter에서 위핀 위젯을 통합하기 위한 절차를 설명합니다.

## 패키지 리스트

<table><thead><tr><th width="162">종류</th><th width="281">패키지 </th><th>설명</th></tr></thead><tbody><tr><td><a href="/pages/CUsZtt54jx1fetzWm2uH">로그인</a></td><td><code>wepin_flutter_login_lib</code></td><td>소셜 로그인과 같은 OAuth 인증 토큰으로 위핀에 로그인하는 기능을 제공합니다.</td></tr><tr><td><a href="/pages/rd4KAiXAfvboVi8wSuy5">위젯</a></td><td><code>wepin_flutter_widget_sdk</code></td><td>위핀 위젯을 사용하기 위한 기능을 제공합니다.</td></tr></tbody></table>

{% hint style="warning" %}

#### Migration Guide 안내

이전 버전의 위핀 패키지인 <mark style="color:blue;">**`wepin_flutter_sdk`**</mark>를 사용 중이라면, 호환성과 최신 기능을 사용하기 위해 현재 버전의 SDK와 로그인 라이브러리로 Migration하는 것이 중요합니다.

**지원 중단된 패키지**

* <mark style="color:blue;">**`wepin_flutter_sdk`**</mark><br>

**현재 패키지**

* <mark style="color:blue;">**`wepin_flutter_widget_sdk`**</mark>

\
기존 패키지에서 새로운 패키지로 Migration하려면 아래 링크에서 자세한 Migration가이드를 확인하세요:

* [Wepin Flutter Widget SDK Migration Guide](https://github.com/WepinWallet/wepin-flutter-sdk-v1/blob/main/packages/wepin_flutter_widget_sdk/MIGRATIONGUIDE.md)&#x20;
  {% endhint %}


# 로그인

Flutter에서 소셜 로그인과 같은 OAuth 인증 토큰 또는 이메일로 위핀에 로그인하는 방법에 대한 안내 페이지입니다.


# 설치

Wepin Flutter Login Library를 설치하는 방법을 설명합니다.

## 요구사항 <a href="#requirements" id="requirements"></a>

* **Android**: API 버전 <mark style="color:blue;">**21**</mark> 이상
* **iOS**: 버전 <mark style="color:blue;">**13.0**</mark> 이상
  * Flutter 프로젝트의 `ios/Podfile`에서 `platform :ios` 버전을 <mark style="color:blue;">**13.0**</mark> 으로 업데이트하고, 필요에 따라 `ios/Podfile`을 확인하고 수정해야 합니다.

{% hint style="info" %}
해당 패키지는  Android, iOS 환경에서만 사용 가능합니다. Web, MacOS, Window, Linux 환경에서는 사용할 수 없습니다.&#x20;
{% endhint %}

## 설치하기 <a href="#installation" id="installation"></a>

Wepin Flutter Login Library는 [pub.dev](https://pub.dev/packages/wepin_flutter_login_lib)에 배포되어 있으며, 아래 명령어나 앱의 `pubspec.yaml`에 dependency를 추가하여 설치할 수 있습니다.

#### Flutter pub add 명령어로 추가 <a href="#add-using-flutter-pub-add-command" id="add-using-flutter-pub-add-command"></a>

```sh
$ flutter pub add wepin_flutter_login_lib
```

#### pubspec.yaml 의 dependency 에 `wepin_flutter_login_lib`추가 <a href="#add-to-dependencies-in-pubspec.yaml" id="add-to-dependencies-in-pubspec.yaml"></a>

```yaml
dependencies:
    wepin_flutter_login_lib: ^0.0.1
```

## 설정하기 <a href="#configuration" id="configuration"></a>

### Deep Link 설정  <a href="#deep-link-configuration" id="deep-link-configuration"></a>

OAuth 로그인 기능(`loginWithOauthProvider`)을 활성화하려면 Deep Link 스킴을 설정해야 합니다.

* Deep Link scheme format : `wepin. + Wepin 앱 ID`

**Android**

* `build.gradle (app)` 파일에서 `manifestPlaceholders`를 추가하여 Wepin Widget SDK가 이 커스텀 스킴을 통한 모든 리디렉션을 쉽게 캡처할 수 있도록 설정합니다.

{% code title="build.gradle(app)" %}

```gradle
// Deep Link 설정 => 리디렉션 스킴 형식: wepin. + Wepin 앱 ID
android.defaultConfig.manifestPlaceholders = [
  'appAuthRedirectScheme': 'wepin.{{YOUR_WEPIN_APPID}}'
]
```

{% endcode %}

**iOS**

* 인증 프로세스 후 앱으로 다시 리디렉션하기 위해 앱의 URL 스킴을 `Info.plist` 파일에 추가해야 합니다.&#x20;

<pre class="language-xml" data-title="Info.plist"><code class="lang-xml"><strong>&#x3C;key>CFBundleURLTypes&#x3C;/key>
</strong>&#x3C;array>
    &#x3C;dict>
        &#x3C;key>CFBundleURLName&#x3C;/key>
        &#x3C;string>unique name&#x3C;/string>
        &#x3C;key>CFBundleURLSchemes&#x3C;/key>
        &#x3C;array>
            &#x3C;string>wepin.{{YOUR_WEPIN_APPID}}&#x3C;/string>
        &#x3C;/array>
    &#x3C;/dict>
&#x3C;/array>
</code></pre>


# 초기화하기

Wepin Flutter Login Library를 초기화하는 방법입니다.

Wepin Flutter Login Library를 설치한 후 다음 단계는 SDK를 초기화하는 것입니다. SDK 초기화는 `WepinLogin`인스턴스를 생성하고, `init()` 함수를 사용하여 진행할 수 있습니다.

## Import SDK

Wepin Flutter Login Library를 사용하기 위해 SDK를 가져와야 합니다. 다음과 같이 import 문을 추가합니다.

```dart
import 'package:wepin_flutter_login_lib/wepin_flutter_login_lib.dart';
import 'package:wepin_flutter_login_lib/type/wepin_flutter_login_lib_type.dart';
```

## `WepinLogin`Instance 생성 및 초기화 <a href="#creating-and-initializing-the-wepinlogininstance" id="creating-and-initializing-the-wepinlogininstance"></a>

먼저, `WepinLogin` 인스턴스를 생성하기 전에 위핀 워크스페이스에서 Android/iOS 관련 앱 정보를 등록해야 합니다.

{% content-ref url="/pages/cfg4nwJBI8VfiJpH4EW8" %}
[앱 등록 및 키 발급](/wepin/workspace/app-registration-and-key-issuance)
{% endcontent-ref %}

등록한 앱 정보를 바탕으로 `WepinLogin` 인스턴스를 생성합니다. `main.dart` 파일의 `state init` 단계에서 `WepinLogin` 인스턴스를 생성하고 초기화해야 합니다.

<pre class="language-dart" data-title="main.dart"><code class="lang-dart"><strong>WepinLogin wepinLogin = WepinLogin(
</strong>    wepinAppKey: wepinAppKey, 
    wepinAppId: wepinAppId
);
await wepinLogin.init();
</code></pre>

## isInitialized

<mark style="color:blue;">`isInitialized`</mark>메서드를 이용해서 WepinLogin 인스턴스가 정상적으로 초기화 되었는지 확인할 수 있습니다. &#x20;

반환값은 아래와 같습니다.&#x20;

* bool\
  초기화가 정상적으로 잘 된 경우 true , 실패한 경우 false 를 반환합니다.

```dart
if(wepinLogin.isInitialized()) {
    // Success to initialize WepinLogin
}
```


# 메서드

Wepin Flutter Login Library에서 제공하는 메서드 입니다.

## loginWithOauthProvider

```dart
await wepinLogin.loginWithOauthProvider({required String provider, required String clientId})
```

인앱 브라우저가 열리고 OAuth Provider에 로그인합니다. Firebase 로그인 정보를 가져오려면 `loginWithIdToken()` 또는 `loginWithAccessToken()` 메서드를 호출해야 합니다.

#### **Parameters**

* **provider** `<String>`

  OAuth 로그인 프로바이더 (예: 'google', 'naver', 'discord', 'apple')
* **clientId** `<String>`

  OAuth 로그인 프로바이더의 클라이언트 ID

#### **Returns**

* **Future\<LoginOauthResult>**
  * **provider** `<String>`

    사용된 OAuth Provider의 이름
  * **token** `<String>`

    accessToken (프로바이더가 "naver" 또는 "discord"일 경우) 또는 idToken (프로바이더가 "google" 또는 "apple"일 경우)
  * **type** `<WepinOauthTokenType>`

    OAuth 토큰의 유형 (예: idToken, accessToken)

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final user = await wepinLogin.loginWithOauthProvider(
  provider: "google",
  clientId: "your-google-client-id"
);
```

## signUpWithEmailAndPassword

```java
await wepinLogin.signUpWithEmailAndPassword({required String email, required String password, String? locale})
```

이메일과 비밀번호로 Wepin Firebase에 회원가입을 합니다. 가입되지 않은 사용자의 경우 검증 이메일이 전송되며, `requiredEmailVerified` 오류가 발생합니다. 이미 가입된 사용자의 경우, `existedEmail` 오류가 발생하며, [loginWepinWithEmailAndPassword](/widget-integration/flutter-sdk/login-library/methods#loginwepinwithemailandpassword)를 호출하여 로그인 프로세스를 진행합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

{% hint style="info" %}
flutter SDK에서는 [loginWithEmailAndPassword](/widget-integration/flutter-sdk/login-library/methods#loginwithemailandpassword)와 [loginWepin](/widget-integration/flutter-sdk/login-library/methods#loginwepin) 메서드가 통합된 [loginWepinWithEmailAndPassword](/widget-integration/flutter-sdk/login-library/methods#loginwepinwithemailandpassword) 메서드를 호출하여 사용 가능합니다.
{% endhint %}

#### **Parameters**

* **email** `<String>`

  사용자 이메일
* **password** `<String>`

  사용자 비밀번호
* **locale** `<String>` ***optional***

  인증 이메일의 언어 설정 (기본 값: "en")

#### **Returns**

* **Future\<LoginResult>**
  * **provider** `<String>`

    로그인에 사용된 Provider (이 경우, 'email')
  * **token** `<WepinFBToken>`
    * **idToken** `<String>`

      Wepin Firebase ID 토큰
    * **refreshToken** `<String>`

      Wepin Firebase refresh토큰

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final user = await wepinLogin.signUpWithEmailAndPassword(
  email: 'abc@defg.com', 
  password: 'abcdef123&'
);
```

## loginWithEmailAndPassword

```dart
await wepinLogin.loginWithEmailAndPassword({required String email, required String password})
```

이메일과 비밀번호를 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

#### **Parameters**

* **email** `<String>`\
  사용자 이메일
* **password** `<String>`\
  사용자 비밀번호

#### **Returns**

* **Future\<LoginResult>**
  * **provider** `<String>`

    로그인에 사용된 Provider (이 경우, 'email')
  * **token** `<WepinFBToken>`
    * **idToken** `<String>`

      Wepin Firebase ID 토큰
    * **refreshToken** `<String>`

      Wepin Firebase refresh토큰

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final user = await wepinLogin.loginWithEmailAndPassword(
  email: 'abc@defg.com', 
  password: 'abcdef123&'
);
```

## loginWithIdToken

```dart
await wepinLogin.loginWithIdToken({required String idToken, required String sign})
```

외부 ID Token을사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

#### **Parameters**

* **idToken** `<String>`\
  로그인에 사용될 ID 토큰 값
* **sign** `<String>` ***optional***\
  ID Token의 서명 값 ([`getSignForLogin()`](#getsignforlogin)의 반환 값)

{% hint style="warning" %}
`wepin_flutter_login_lib` 버전 <mark style="color:red;">**0.0.5**</mark> 부터 `sign` 값은 optional로 변경되었습니다. [Wepin Workspace](https://workspace.wepin.io/)에서 인증 키를 제거(Development Tools menu > Login tab > Auth Key> Delete)하면, 서명(**`sign`**)  값을 사용하지 않을 수 있습니다. 인증 키를 이전에 생성한 경우에만 인증 키 메뉴가 표시됩니다.
{% endhint %}

#### **Returns**

* **Future\<LoginResult>**
  * **provider** `<String>` \
    로그인에 사용된 프로바이더(이 경우, 'external\_token')
  * **token** `<WepinFBToken>`
    * **idToken** `<String>`

      Wepin Firebase ID 토큰
    * **refreshToken** `<String>`

      Wepin Firebase refresh토큰

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final user = await wepinLogin.loginWithIdToken(
    idToken:'eyJHGciO....adQssw5c', 
    sign:'9753d4dc...c63466b9'
);
```

## loginWithAccessToken

```java
await wepinLogin.loginWithAccessToken({required String provider, required String accessToken, required String sign})
```

외부 Access Token을 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

#### **Parameters**

* **provider** `<"naver"|"discord">`

  Access Token을 발급한 프로바이더
* **accessToken** `<String>`

  로그인에 사용될 Access Token 값
* **sign** `<String>` ***optional***

  Access Token의 서명 값 (returned value of `getSignForLogin()`)

{% hint style="warning" %}
`wepin_flutter_login_lib` 버전 <mark style="color:red;">**0.0.5**</mark> 부터 `sign` 값은 optional로 변경되었습니다.\
[Wepin Workspace](https://workspace.wepin.io/)에서 인증 키를 제거(Development Tools menu > Login tab > Auth Key> Delete)하면, 서명(**`sign`**)  값을 사용하지 않을 수 있습니다. 인증 키를 이전에 생성한 경우에만 인증 키 메뉴가 표시됩니다.
{% endhint %}

#### **Returns**

* **Future\<LoginResult>**
  * **provider** `<String>`

    로그인에 사용된 프로바이더(in this case, 'external\_token')
  * **token** `<WepinFBToken>`
    * **idToken** `<String>`

      Wepin Firebase ID Token
    * **refreshToken** `<String>`

      Wepin Firebase refresh Token

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final user = await wepinLogin.loginWithAccessToken(
    provider: 'naver', 
    accessToken:'eyJHGciO....adQssw5c', 
    sign:'9753d4dc...c63466b9'
);
```

## getRefreshFirebaseToken

```dart
await wepinLogin.getRefreshFirebaseToken({LoginResult? prevToken})
```

현재  Wepin Firebase 토큰의 정보를 가져옵니다.

#### **Parameters** (버전 <mark style="color:orange;">**`0.0.11`**</mark> 이상에서 지원)

* prevToken \<LoginResult> ***optional***&#x20;
  * 이전 로그인 결과에 포함된 토큰 정보를 사용하여 갱신할 때 사용됩니다.

{% hint style="warning" %}
**prevToken** 매개변수는 0.0.11 버전부터 지원됩니다.

* 매개변수를 제공하지 않으면 저장된 토큰을 사용하여 갱신하고 저장소를 업데이트합니다. 이 옵션은 Wepin 로그인 세션이 만료되지 않은 경우에만 사용할 수 있습니다.
* **prevToken** 매개변수를 제공하면, Wepin 로그인 세션 만료 여부와 상관없이 전달된 토큰을 사용하여 갱신합니다.
  {% endhint %}

#### **Returns**

* **Future\<LoginResult>**
  * **provider** `<String>`\
    로그인에 사용된 Provider

    `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`
  * **token** `<WepinFBToken>`
    * **idToken** `<String>`\
      Wepin Firebase ID Token
    * **refreshToken** `<String>`\
      Wepin Firebase refresh Token

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final user = await wepinLogin.getRefreshFirebaseToken({LoginResult? prevToken});
```

## loginFirebaseWithOauthProvider &#x20;

```dart
await wepinLogin.loginFirebaseWithOauthProvider({required String provider, required String clientId})
```

해당 메서드는 `loginWithOauthProvider()`, `loginWithIdToken()`, `loginWithAccessToken()` 기능을 통합한 것입니다. 인앱 브라우저를 열어 지정된 OAuth 로그인 Provider를 통해 Wepin Firebase에 로그인  합니다. 성공적인 로그인 후 Firebase 로그인 정보를 반환합니다

**Supported Version**\
버전 <mark style="color:orange;">**`0.0.5`**</mark> 이상에서 지원

#### **Parameters**

* **provider** `<String>`

  OAuth 로그인 프로바이더(예: 'google', 'naver', 'discord', 'apple')
* **clientId** `<String>`

  OAuth 로그인 Provider의 클라이언트 ID

#### **Return Value**

* **Future\<LoginResult>**
  * **provider** `<String>`\
    로그인에 사용된 프로바이더

    `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`
  * **token** `<WepinFBToken>`
    * **idToken** `<String>`\
      Wepin Firebase ID Token
      * **refreshToken** `<String>`\
        Wepin Firebase Refresh Token

**Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final user = await wepinLogin.loginFirebaseWithOauthProvider(
    provider:'apple', 
    clietId:'apple-client-id'
);
```

## loginWepinWithOauthProvider

```dart
await wepinLogin.loginWepinWithOauthProvider({required String provider, required String clientId})
```

해당 메서드는 `loginFirebaseWithOauthProvider()`와 `loginWepin()` 기능을 통합한 것입니다. 인앱 브라우저를 열어 지정된 OAuth 로그인 프로바이더를 통해 위핀에 로그인  합니다. 성공적인 로그인 후 위핀사용자 정보를 반환합니다.

{% hint style="warning" %}
이 메서드는 [Wepin Workspace](https://workspace.wepin.io/)에서 인증 키를 삭제(Development Tools menu > Login tab > Auth Key> Delete)한 후에만 사용할 수 있습니다. 인증 키를 이전에 생성한 경우에만 인증 키 메뉴가 표시됩니다.
{% endhint %}

**Supported Version**\
버전 <mark style="color:orange;">**`0.0.5`**</mark> 이상에서 지원

#### **Parameters**

* **provider** `<String>`

  OAuth 로그인 Provider (예: 'google', 'naver', 'discord', 'apple')
* **clientId** `<String>`

  OAuth 로그인 Provider의 클라이언트 ID

#### **Return Value**

* **Future\<WepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<WepinUserInfo>`***optional***  - 사용자의 정보
    * **userId** `<String>`

      사용자의 ID
    * **email** `<String>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 Provider
    * **use2FA** `<bool>`

      사용자가 이중 인증을 사용하는지 여부
    * **walletId** `<String>`

      사용자의 지갑 ID
  * **userStatus** `<WepinUserStatus>` -사용자의 위핀  로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<bool>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<Token>`

    사용자의 Wepin Token
  * **accessToken** `<String>`\
    Access Token
  * **refreshToken** `<String>`\
    Refresh Token

**Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final userInfo = await wepinLogin.loginWepinWithOauthProvider(
  provider: 'google',
  clientId; 'google-client-id'
);

final userStatus = userInfo.userStatus;
if (userStatus.loginStatus == 'pinRequired' || userStatus.loginStatus == 'registerRequired') {
    // Wepin register
}
```

## loginWepinWithIdToken

```dart
await wepinLogin.loginWepinWithIdToken({required String idToken, String? sign})
```

해당 메서드는 `loginWithIdToken()`과 `loginWepin()` 기능을 통합한 것입니다. `loginWepinWithIdToken()` 메서드는 외부 ID Token을 사용하여 위핀에 로그인 합니다. 성공적인 로그인 후 위핀 사용자 정보를 반환합니다.

**Supported Version**\
버전 <mark style="color:orange;">**`0.0.5`**</mark> 이상에서 지원

#### **Parameters**

* **idToken** `<String>`\
  로그인에 사용될 ID Token 값
* **sign** `<String>`***optional***  \
  ID Token의 서명 값 ([`getSignForLogin()`](#getsignforlogin)의 반환 값)<br>

  <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><a href="https://workspace.wepin.io/">Wepin Workspace</a>에서 인증 키를 제거(Development Tools menu > Login tab > Auth Key> Delete)하면, 서명(<strong><code>sign</code></strong>)  값을 사용하지 않을 수 있습니다. 인증 키를 이전에 생성한 경우에만 인증 키 메뉴가 표시됩니다.</p></div>

#### **Return Value**

* **Future\<WepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<WepinUserInfo>`***optional***  - 사용자의 정보.
    * **userId** `<String>`

      사용자의 ID
    * **email** `<String>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 프로바이더
    * **use2FA** `<bool>`

      사용자가 이중 인증을 사용하는지 여부
    * **walletId** `<String>`

      사용자의 지갑 ID
  * **userStatus** `<WepinUserStatus>` -사용자의 위핀 로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<bool>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<Token>`

    사용자의 Wepin Token
  * **accessToken** `<String>`\
    Access Token
  * **refreshToken** `<String>`\
    Refresh Token

**Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final userInfo = await wepinLogin.loginWepinWithIdToken(
  idToken:'eyJHGciO....adQssw5c',
);

final userStatus = userInfo.userStatus;
if (userStatus.loginStatus == 'pinRequired' || userStatus.loginStatus == 'registerRequired') {
    // Wepin register
}
```

## loginWepinWithAccessToken

```dart
await wepinLogin.loginWepinWithAccessToken({required String provider, required String accessToken, String? sign})
```

해당 메서드는 `loginWithAccessToken()`과 `loginWepin()` 기능을 통합한 것입니다. `loginWepinWithAccessToken()` 메서드는 외부 액세스 토큰을 사용하여 위핀에 로그인 합니다. 성공적인 로그인 후 위핀 사용자 정보를 반환합니다.

**Supported Version**\
버전 <mark style="color:orange;">**`0.0.5`**</mark> 이상에서 지원

#### **Parameters**

* **provider** `<"naver"|"discord">`

  Access Token을 발급한 프로바이더
* **accessToken** `<String>`

  로그인에 사용될 Access Token 값
* **sign** `<String>` ***optional*** &#x20;

  Access Token의 서명 값 (returned value of `getSignForLogin()`)

#### **Return Value**

* **Future\<WepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<WepinUserInfo>`***optional***  - 사용자의 정보
    * **userId** `<String>`

      사용자의 ID
    * **email** `<String>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 프로바이더
    * **use2FA** `<bool>`

      사용자가 이중 인증을 사용하는지 여부
    * **walletId** `<String>`

      사용자의 지갑 ID
  * **userStatus** `<WepinUserStatus>` -사용자의 위핀 로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<bool>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<Token>`

    사용자의 Wepin Token
  * **accessToken** `<String>`\
    Access Token
  * **refreshToken** `<String>`\
    Refresh Token

**Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final userInfo = await wepinLogin.loginWepinWithAccessToken(
    provider: 'naver',
    accessToken:'eyJHGciO....adQssw5c',
);

final userStatus = userInfo.userStatus;
if (userStatus.loginStatus == 'pinRequired' || userStatus.loginStatus == 'registerRequired') {
    // Wepin register
}
```

## loginWepinWithEmailAndPassword

```dart
await wepinLogin.loginWepinWithEmailAndPassword({required String email, required String password})
```

해당 메서드는 `loginWithEmailAndPassword()`와 `loginWepin()` 기능을 통합한 것입니다. `loginWepinWithEmailAndPassword()` 메서드는 제공된 이메일과 비밀번호를 사용하여 위핀에 로그인 합니다. 성공적인 로그인 후 위핀 사용자 정보를 반환합니다.

**Supported Version**\
버전 <mark style="color:orange;">**`0.0.5`**</mark> 이상에서 지원

#### **Parameters**

* **email** `<String>`\
  사용자 이메일
* **password** `<String>`\
  사용자 비밀번호

  서비스의 로그인과 별개로 사용자의 비밀번호를 입력받는 로직이 추가로 필요할 수 있습니다.

#### **Return Value**

* **Future\<WepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<WepinUserInfo>`***optional***  - 사용자의 정보
    * **userId** `<String>`

      사용자의 ID
    * **email** `<String>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 프로바이더더
    * **use2FA** `<bool>`

      사용자가 이중 인증을 사용하는지 여부
    * **walletId** `<String>`

      사용자의 지갑 ID
  * **userStatus** `<WepinUserStatus>` -사용자의 위핀 로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<bool>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<Token>`

    사용자의 Wepin Token
  * **accessToken** `<String>`\
    Access Tken
  * **refreshToken** `<String>`\
    Refresh Token

**Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final userInfo = await wepinLogin.loginWithEmailAndPassword(
    email: "abc@abc.com",
    password: "user_password"
);

final userStatus = userInfo.userStatus;
if (userStatus.loginStatus == 'pinRequired' || userStatus.loginStatus == 'registerRequired') {
    // Wepin register
}
```

## loginWepin

```dart
await wepinLogin.loginWepin(LoginResult params) 
```

Wepin Firebase 토큰을 사용하여 사용자를 위핀에 로그인합니다.

#### **Parameters**

* **params** `<LoginResult>`\
  Parameters from the return value of methods like `loginWithEmailAndPassword()`, `loginWithIdToken()`, or `loginWithAccessToken()`.

#### **Returns**

* **Future\<WepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<WepinUserInfo>`***optional***  - 사용자의 정보
    * **userId** `<String>`

      사용자의 ID
    * **email** `<String>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 Provider
    * **use2FA** `<bool>`

      사용자가 이중 인증을 사용하는지 여부
    * **walletId** `<String>`

      사용자의 지갑 ID
  * **userStatus** `<WepinUserStatus>` -사용자의 위핀 로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<bool>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<Token>`

    사용자의 Wepin Token
  * **accessToken** `<String>`\
    Access Token
  * **refreshToken** `<String>`\
    Refresh Token

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

<pre class="language-dart"><code class="lang-dart">final wepinLogin = WepinLogin(appId: 'appId', appKey: 'appKey');
await wepinLogin.init();
final res = await wepinLogin.loginWithOauthProvider(
provider: "google",
clientId: "your-google-client-id"
);

final sign = wepinLogin?.getSignForLogin(privateKey: privateKey, message: res!.token);
LoginResult? resLogin;
<strong>if(provider == 'naver' || provider == 'discord') {
</strong>  resLogin = await wepinLogin.loginWithAccessToken(provider: provider, accessToken: res!.token, sign: sign));
} else {
  resLogin = await wepinLogin.loginWithIdToken(idToken: res!.token, sign: sign));
}

final userInfo = await wepinLogin.loginWepin(resLogin);
final userStatus = userInfo.userStatus;
if (userStatus.loginStatus == 'pinRequired' || userStatus.loginStatus == 'registerRequired') {
    // Wepin register
}
</code></pre>

## getCurrentWepinUser

```dart
await wepinLogin.getCurrentWepinUser()
```

위핀에 현재 로그인한 사용자의 정보를 가져옵니다.

#### **Parameters**

* None

#### **Returns**

* **Future\<WepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<WepinUserInfo>`***optional***  - 사용자의 정보
    * **userId** `<String>`

      사용자의 ID
    * **email** `<String>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 Provider
    * **use2FA** `<bool>`

      사용자가 이중 인증을 사용하는지 여부
    * **walletId** `<String>`

      사용자의 지갑 ID
  * **userStatus** `<WepinUserStatus>` -사용자의 위핀 로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<bool>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<Token>`

    사용자의 Wepin Token
  * **accessToken** `<String>`\
    Access Token
  * **refreshToken** `<String>`\
    Refresh Token

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final userInfo = await wepinLogin.getCurrentWepinUser();
final userStatus = userInfo.userStatus;
if (userStatus.loginStatus == 'pinRequired' || userStatus.loginStatus == 'registerRequired') {
    // Wepin register
}
```

## logout

```dart
await wepinLogin.logout()
```

위핀에 로그인한 사용자를 로그아웃합니다.

#### **Parameters**

* None

#### **Returns**

* **Future\<bool>**

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/login-library/methods#wepinerror)

#### **Example**

```dart
final result = await wepinLogin.logout();
if (result) {
  // Successfully logged out
}
```

## getSignForLogin

발급자를 확인하기 위한 서명을 생성합니다. 주로 ID Token 및 Access Token과 같은 로그인 관련 정보를 위한 서명을 생성하는 데 사용됩니다.

```dart
final result = getSignForLogin({required String privateKey, required String message});
```

#### **Parameters**

* **privateKey** `<String>`\
  서명 생성에 사용되는 인증 키
* **message** `<String>`\
  서명될 메시지 또는 페이로드

{% hint style="info" %}
서명에 사용할 키는 [위핀 워크스페이스](https://workspace.wepin.io/login)에서 발급 받을 수 있습니다. 개발 도구 메뉴에서 로그인 탭의 인증키 발급 받기를 클릭하여 인증키를 확인하세요.
{% endhint %}

#### **Returns**

* **\<String>** \
  생성된 서명

{% hint style="warning" %}
인증키(**privateKey**)는 반드시 안전하게 보관되어야 하며, 외부에 노출되지 않도록 주의해야 합니다. 보안과 민감한 정보 보호를 위해 `getSignForLogin()` 메서드는 프론트엔드가 아닌 백엔드에서 실행하는 것이 권장됩니다. 서명 생성 방법에 대해서는 [문서를 참고](https://github.com/WepinWallet/wepin-web-sdk-v1/blob/main/packages/login/SignatureGenerationMethods.md)하세요.
{% endhint %}

#### **Example**

```dart
final sign = getSignForLogin(
  privateKey: '0400112233445566778899001122334455667788990011223344556677889900', 
  message: 'idtokenabcdef'
);

final res = await wepinLogin.loginWithIdToken(
    idToken: 'eyJHGciO....adQssw5c', 
    sign: sign
);
```

## finalize

```dart
await wepinLogin.finalize()
```

Wepin Login Library 를 종료합니다.

#### **Parameters**

* None

#### **Returns**

* **Future\<void>**

#### **Example**

```dart
await wepinLogin.finalize();
```

## WepinError

| Error Code                    | Error Message                 | Error Description                                                                                                                                                                                    |
| ----------------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalidAppKey`               | "InvalidAppKey"               | The Wepin app key is invalid.                                                                                                                                                                        |
| `invalidParameters` \`        | "InvalidParameters"           | One or more parameters provided are invalid or missing.                                                                                                                                              |
| `invalidLoginProvider`        | "InvalidLoginProvider"        | The login provider specified is not supported or is invalid.                                                                                                                                         |
| `invalidToken`                | "InvalidToken"                | The token does not exist.                                                                                                                                                                            |
| `invalidLoginSession`         | "InvalidLoginSession"         | The login session information does not exist.                                                                                                                                                        |
| `notInitialized`              | "NotInitialized"              | The WepinLoginLibrary has not been properly initialized.                                                                                                                                             |
| `alreadyInitialized`          | "AlreadyInitialized"          | The WepinLoginLibrary is already initialized, so the logout operation cannot be performed again.                                                                                                     |
| `userCancelled`               | "UserCancelled"               | The user has cancelled the operation.                                                                                                                                                                |
| `unknownError`                | "UnknownError"                | An unknown error has occurred, and the cause is not identified.                                                                                                                                      |
| `notConnectedInternet`        | "NotConnectedInternet"        | The system is unable to detect an active internet connection.                                                                                                                                        |
| `failedLogin`                 | "FailedLogin"                 | The login attempt has failed due to incorrect credentials or other issues.                                                                                                                           |
| `alreadyLogout`               | "AlreadyLogout"               | The user is already logged out, so the logout operation cannot be performed again.                                                                                                                   |
| `invalidEmailDomain`          | "InvalidEmailDomain"          | The provided email address's domain is not allowed or recognized by the system.                                                                                                                      |
| `failedSendEmail`             | "FailedSendEmail"             | The system encountered an error while sending an email. This is because the email address is invalid or we sent verification emails too often. Please change your email or try again after 1 minute. |
| `requiredEmailVerified`       | "RequiredEmailVerified"       | Email verification is required to proceed with the requested operation.                                                                                                                              |
| `incorrectEmailForm`          | "incorrectEmailForm"          | The provided email address does not match the expected format.                                                                                                                                       |
| `incorrectPasswordForm`       | "IncorrectPasswordForm"       | The provided password does not meet the required format or criteria.                                                                                                                                 |
| `notInitializedNetwork`       | "NotInitializedNetwork"       | The network or connection required for the operation has not been properly initialized.                                                                                                              |
| `requiredSignupEmail`         | "RequiredSignupEmail"         | The user needs to sign up with an email address to proceed.                                                                                                                                          |
| `failedEmailVerified`         | "FailedEmailVerified"         | The WepinLoginLibrary encountered an issue while attempting to verify the provided email address.                                                                                                    |
| `failedPasswordStateSetting`  | "FailedPasswordStateSetting"  | Failed to set the password state. This error may occur during password management operations, potentially due to invalid input or system issues.                                                     |
| `failedPasswordSetting`       | "failedPasswordSetting"       | Failed to set the password. This could be due to issues with the provided password or internal errors during the password setting process.                                                           |
| `existedEmail`                | "ExistedEmail"                | The provided email address is already registered. This error occurs when attempting to sign up with an email that is already in use.                                                                 |
| `apiRequestError`             | "ApiRequestError"             | There was an error while making the API request. This can happen due to network issues, invalid endpoints, or server errors.                                                                         |
| `incorrectLifecycleException` | "IncorrectLifecycleException" | The lifecycle of the Wepin SDK is incorrect for the requested operation. Ensure that the SDK is in the correct state (e.g., `initialized` and `login`) before proceeding.                            |
| `failedRegister`              | "FailedRegister"              | Failed to register the user. This can occur due to issues with the provided registration details or internal errors during the registration process.                                                 |
| `accountNotFound`             | "AccountNotFound"             | The specified account was not found. This error is returned when attempting to access an account that does not exist in the Wepin.                                                                   |
| `nftNotFound`                 | "NftNotFound"                 | The specified NFT was not found. This error occurs when the requested NFT does not exist or is not accessible within the user's account.                                                             |
| `failedSend`                  | "FailedSend"                  | Failed to send the required data or request. This error could be due to network issues, incorrect data, or internal server errors.                                                                   |


# 핀 패드

RESTful API 사용시, Flutter 환경의 서비스에서 사용자의 PIN을 입력 받을 수 있는 UI 및 기능을 제공하는 패키지입니다.


# 설치

## 요구사항 <a href="#requirements" id="requirements"></a>

* **Android**: API 버전 <mark style="color:blue;">**21**</mark> 이상
  * `android/app/build.gradle` 파일에서 `compileSdkVersion`을 <mark style="color:blue;">**34**</mark>로 설정해야 합니다.
* **iOS**: 버전 <mark style="color:blue;">**13.0**</mark> 이상
  * Flutter 프로젝트의 `ios/Podfile`에서 `platform :ios` 버전을 <mark style="color:blue;">**13.0**</mark> 으로 업데이트하고, 필요에 따라 `ios/Podfile`을 확인하고 수정해야 합니다.

{% hint style="info" %}
해당 패키지는 **Android**, **iOS** 환경에서만 사용 가능합니다. **Web**, **MacOS**, **Window**, **Linux** 환경에서는 사용할 수 없습니다.&#x20;
{% endhint %}

## 설치하기 <a href="#installation" id="installation"></a>

Wepin Flutter 핀 패드 라이브러리는 [pub.dev](https://pub.dev/packages/wepin_flutter_pin_pad)에 배포되어 있으며, 아래 명령어나 앱의 pubspec.yaml에 dependency를 추가하여 설치할 수 있습니다.

#### Flutter pub add 명령어로 추가

```sh
$ flutter pub add wepin_flutter_pin_pad
```

#### pubspec.yaml 의 dependency 에 `wepin_flutter_pin_pad`추가

```yaml
dependencies:
  wepin_flutter_pin_pad: ^0.0.1
```

설치가 완료되면 앱 등록 후 할당받은 App ID와 App Key를 사용하여 아래와 같이 WepinPinPad 인스턴스를 초기화합니다. 이렇게 하면 위핀의 핀 패드를 사용할 수 있게 됩니다.

<pre class="language-dart"><code class="lang-dart"><strong>// 1. 패키지 import
</strong>import 'package:wepin_flutter_pin_pad/wepin_flutter_pin_pad.dart';
import 'package:wepin_flutter_pin_pad/wepin_flutter_pin_pad_types.dart';
<strong>
</strong>// 2. 인스턴스 초기화
WepinPinPad wepinPinPad = WepinPinPad(wepinAppKey: wepinAppKey, wepinAppId: wepinAppId);
</code></pre>


# 초기화하기

Wepin PIN Pad Library를 초기화하는 방법입니다.

## init

Wepin PIN Pad Library를 초기화 합니다.&#x20;

초기화 시 핀 패드 화면에 보여질 언어를 설정합니다.

```dart
await wepinPinPad.init(String? language)
```

### **Parameters**

* `language`: \<String> **optional**\
  핀 패드 화면의 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'` ,`'ja'`입니다.

### **Return value**

* `Future`\<void>

### Example

```dart
await wepinPinPad.init('ko')
```

## isInitialized

Wepin PIN Pad Library가 정상적으로 초기화 되었는지 확인할 수 있습니다.&#x20;

```dart
wepinPinPad.isInitialized()
```

### **Parameters**

* `<void>`

### **Return Value**

* `<bool>`\
  초기화가 정상적으로 잘 된 경우 **true** , 실패한 경우 **false** 를 반환합니다.

### **Example**

```dart
if(wepinPinPad.isInitialized()) {
  print('wepinPin is initialized!')
}
```

## changeLanguage

```dart
wepinPinPad.changeLanguage(String language)
```

핀 패드 화면에 표시되는 언어를 변경합니다. 현재 `'ko'`, `'en'`, `'ja'`만 지원됩니다. <br>

**Parameters**

* &#x20;`language` \<String>

### **Return value**

* `<void>`

### Example

```dart
wepinPinPad.changeLanguage('ko')
```


# 메서드

Wepin PIN Pad Library  초기화 이후 사용할 수 있습니다.

## generateRegistrationPINBlock

```dart
await generateRegistrationPINBlock(BuildContext context)
```

사용자의 지갑 생성 및 회원가입을 위해 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.

### **Parameters**

* `context` \<BuildContext>\
  **BuildContext** 매개변수는 Flutter에서 매우 중요한 요소로, 위젯 트리 내에서 특정 위젯의 위치를 나타냅니다. 이 컨텍스트는 Flutter가 해당 위젯의 위치를 파악하고, 네비게이션, 테마 데이터 접근 등 다양한 기능을 제공하기 위해 사용됩니다. 예를 들어, **generateRegistrationPINBlock** 함수를 호출할 때 현재의 컨텍스트를 전달하는 이유는 해당 위젯이 UI 계층 구조의 올바른 위치에 표시되도록 보장하기 위함입니다.

### **Return value**

* `Future` \<RegistrationPinBlock>
  * `uvd` \<EncUVD>

    * `b64Data` \<String> \
      b64SKey의  원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data를 생성할때  사용하는 키
    * `seqNum` \<int> **optional** \
      **P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값

  * `hint` \<EncPinHint>

    * `data` \<String> \
      PIN 힌트를 암호화한 값
    * `length` \<String>\
      PIN 힌트의 길이
    * `version` \<int>&#x20;

    &#x20;      PIN 힌트의 버전

### **Example**

```dart
final res = await wepinPinPad!.generateRegistrationPINBlock(context);
//You need to make a Wepin RESTful API request using the received data.
```

## &#x20;generateAuthPINBlock

```dart
await generateAuthPINBlock(BuildContext context, int? count)
```

사용자 인증에 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `context` \<BuildContext>\
  **BuildContext** 매개변수는 Flutter에서 매우 중요한 요소로, 위젯 트리 내에서 특정 위젯의 위치를 나타냅니다. 이 컨텍스트는 Flutter가 해당 위젯의 위치를 파악하고, 네비게이션, 테마 데이터 접근 등 다양한 기능을 제공하기 위해 사용됩니다. 예를 들어, **generateAuthPINBlock** 함수를 호출할 때 현재의 컨텍스트를 전달하는 이유는 해당 위젯이 UI 계층 구조의 올바른 위치에 표시되도록 보장하기 위함입니다.
* `count` \<int> **optional**&#x20;

  생성하려는 PIN Block의 개수. 기본값은 `1` 입니다.

### **Return value**

* `Future` \<AuthPinBlock>
  * `uvdList` \<List\<EncUVD>> \
    암호화된 PIN Block의 리스트
    * \<EncUVD>
      * `b64Data` \<String> \
        b64SKey의  원본 키로 암호화된 데이터
      * `b64SKey` \<String> \
        b64Data 를 생성할 때  사용하는 키
      * `seqNum` \<int> **optional** \
        **P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값.\
        Multi Tx 요청 시, 반드시 받은 PIN Block의 순서대로 사용해야 합니다.(1,2,3...)
  * `otp` \<String> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### **Example**

```dart
final res = await wepinPinPad!.generateAuthPINBlock(context, 1);
// You need to make a Wepin RESTful API request using the received data.
```

## generateChangePINBlock

```dart
await generateChangePINBlock(BuildContext context)
```

사용자 PIN 변경을 위해 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.&#x20;

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

### **Parameters**

* `context` \<BuildContext>\
  **BuildContext** 매개변수는 Flutter에서 매우 중요한 요소로, 위젯 트리 내에서 특정 위젯의 위치를 나타냅니다. 이 컨텍스트는 Flutter가 해당 위젯의 위치를 파악하고, 네비게이션, 테마 데이터 접근 등 다양한 기능을 제공하기 위해 사용됩니다. 예를 들어, **generateChangePINBlock** 함수를 호출할 때 현재의 컨텍스트를 전달하는 이유는 해당 위젯이 UI 계층 구조의 올바른 위치에 표시되도록 보장하기 위함입니다.

### **Return Value**

* `Future` \<ChangePinBlock>
  * `uvd` \<EncUVD>
    * `b64Data` \<String> \
      b64SKey의 원본키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할때  사용하는 키
    * `seqNum` \<int> **optional** \
      **P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값
  * `newUVD` \<EncUVD>
    * `b64Data` \<String> \
      b64SKey의  원본 키로 암호화된 데이터
    * `b64SKey` \<String> \
      b64Data 를 생성할 때  사용하는 키
    * `seqNum` \<int> **optional** \
      **P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값
  * `hint` \<EncPinHint>
    * `data` \<String> \
      &#x20;PIN 힌트를 암호화한 값
    * `length` \<String>\
      PIN 힌트의 길이
    * `version` \<int> \
      PIN 힌트의 버전
  * `otp` \<String> **optional** \
    사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

### **Example**

```dart
await wepinPinPad.generateChangePINBlock(context);
// You need to make a Wepin RESTful API request using the received data.
```

## generateAuthOTP

```dart
await generateAuthOTP(BuildContext context)
```

사용자로부터 OTP 코드를  입력받을 수 있는 화면을 띄우고 처리합니다.

### **Parameters**

* `context` \<BuildContext>\
  **BuildContext** 매개변수는 Flutter에서 매우 중요한 요소로, 위젯 트리 내에서 특정 위젯의 위치를 나타냅니다. 이 컨텍스트는 Flutter가 해당 위젯의 위치를 파악하고, 네비게이션, 테마 데이터 접근 등 다양한 기능을 제공하기 위해 사용됩니다. 예를 들어, **generateAuthOTP** 함수를 호출할 때 현재의 컨텍스트를 전달하는 이유는 해당 위젯이 UI 계층 구조의 올바른 위치에 표시되도록 보장하기 위함입니다.

### **Return Value**

* `Future`\<AuthOTP>
  * `code` \<String>\
    입력받은 OTP 코드

### **Example**

```dart
await wepinPinPad.generateAuthOTP(context);
// You need to make a Wepin RESTful API request using the received data.
```

## finalize

```dart
await wepinPinPad.finalize()
```

Wepin PIN Pad Library 사용을 종료합니다.

### **Parameters**

* \<void>

### **Return Value**

* `Future`\<void>

### **Example**

```dart
await wepinPinPad.finalize();
```


# 위젯

Flutter에서 Wepin Widget SDK를 사용하는 방법에 대한 안내 페이지입니다.


# 설치

Wepin Flutter Widget SDK를 설치하는 방법을 설명합니다.

## 요구사항 <a href="#requirements" id="requirements"></a>

* **Android**: API 버전 <mark style="color:blue;">**21**</mark> 이상
  * `android/app/build.gradle` 파일에서 `compileSdkVersion`을 <mark style="color:blue;">**34**</mark>로 설정해야 합니다.
* **iOS**: 버전 <mark style="color:blue;">**13.0**</mark> 이상
  * Flutter 프로젝트의 `ios/Podfile`에서 `platform :ios` 버전을 <mark style="color:blue;">**13.0**</mark> 으로 업데이트하고, 필요에 따라 `ios/Podfile`을 확인하고 수정해야 합니다.

{% hint style="info" %}
해당 패키지는  **Android**, **iOS** 환경에서만 사용 가능합니다. **Web**, **MacOS**, **Window**, **Linux** 환경에서는 사용할 수 없습니다.&#x20;
{% endhint %}

## 설치하기 <a href="#installation" id="installation"></a>

Wepin Flutter Widget SDK는 [pub.dev](https://pub.dev/packages/wepin_flutter_widget_sdk)에 배포되어 있으며, 아래 명령어나 앱의 `pubspec.yaml`에 dependency를 추가하여 설치할 수 있습니다.

#### Flutter pub add 명령어로 추가 <a href="#add-using-flutter-pub-add-command" id="add-using-flutter-pub-add-command"></a>

```sh
$ flutter pub add wepin_flutter_widget_sdk
```

#### pubspec.yaml 의 dependency 에 `wepin_flutter_widget_sdk`추가 <a href="#add-to-dependencies-in-pubspec.yaml" id="add-to-dependencies-in-pubspec.yaml"></a>

```yaml
dependencies:
    wepin_flutter_widget_sdk: ^0.0.1
```

## 설정하기 <a href="#configuration" id="configuration"></a>

### Deep Link 설정  <a href="#deep-link-configuration" id="deep-link-configuration"></a>

OAuth 로그인 기능(`login.loginWithOauthProvider`)을 활성화하려면 Deep Link 스킴을 설정해야 합니다.

* **Deep Link scheme format** : `wepin. + Wepin 앱 ID`

**Android**

* `build.gradle (app)` 파일에서 `manifestPlaceholders`를 추가하여 Wepin Widget SDK가 이 커스텀 스킴을 통한 모든 리디렉션을 쉽게 캡처할 수 있도록 설정합니다.

{% code title="build.gradle(app)" %}

```gradle
// Deep Link 설정 => 리디렉션 스킴 형식: wepin. + Wepin 앱 ID
android.defaultConfig.manifestPlaceholders = [
  'appAuthRedirectScheme': 'wepin.{{YOUR_WEPIN_APPID}}'
]
```

{% endcode %}

**iOS**

* 인증 프로세스 후 앱으로 다시 리디렉션하기 위해 앱의 URL 스킴을 `Info.plist` 파일에 추가해야 합니다.&#x20;

<pre class="language-xml" data-title="Info.plist"><code class="lang-xml"><strong>&#x3C;key>CFBundleURLTypes&#x3C;/key>
</strong>&#x3C;array>
    &#x3C;dict>
        &#x3C;key>CFBundleURLName&#x3C;/key>
        &#x3C;string>unique name&#x3C;/string>
        &#x3C;key>CFBundleURLSchemes&#x3C;/key>
        &#x3C;array>
            &#x3C;string>wepin.{{YOUR_WEPIN_APPID}}&#x3C;/string>
        &#x3C;/array>
    &#x3C;/dict>
&#x3C;/array>
</code></pre>

### Permission 설정 <a href="#permission-configuration" id="permission-configuration"></a>

Wepin Flutter Widget SDK를 사용하려면 카메라 접근 권한이 필요합니다. 카메라 기능은 QR 코드 형식의 주소를 인식하는 데 필수적입니다. \[[Reference: permission\_handle](https://pub.dev/packages/permission_handler)]

**Android**

앱의 `AndroidManifest.xml` 파일에 아래 줄을 추가합니다.

{% code title="AndroidManifest.xml" %}

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.INTERNET" />
  <!-- ... -->
</manifest>
```

{% endcode %}

**iOS**

1. **`Podfile` 업데이트**: Podfile 파일에 카메라 권한을 추가합니다.

{% code title="Podfile " %}

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|
       # 자세한 정보는 https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h 를 참조하세요.
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',
        ]
    end
  end
end
```

{% endcode %}

2. **`Info.plist`업데이트**: 필요한 권한 사용 설명을 추가합니다.

{% code title="Info.plist" %}

```xml
다<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <!-- 🚨 Keep only the permissions used in your app 🚨 -->
  <key>NSCameraUsageDescription</key>
  <string>YOUR TEXT</string>
  <!-- … -->
</dict>
</plist>
```

{% endcode %}


# 초기화하기

Wepin flutter widget SDK를 초기화하는 방법입니다.

Wepin Flutter Widget SDK를 설치한 후 다음 단계는 SDK를 초기화하는 것입니다. SDK 초기화는 `WepinWidgetSDK` 인스턴스를 생성하고, `init()` 함수를 사용하여 진행할 수 있습니다.<br>

## **Import SDK**

Wepin Flutter Widget SDK를 사용하기 위해 먼저 SDK를 가져와야 합니다. 다음과 같이 import 문을 추가합니다.

```dart
import 'package:wepin_flutter_widget_sdk/wepin_flutter_widget_sdk.dart';
import 'package:wepin_flutter_widget_sdk/wepin_flutter_widget_sdk_type.dart';
```

## WepinWidgetSDK Instance 생성 <a href="#creating-the-wepinwidgetsdk-instance" id="creating-the-wepinwidgetsdk-instance"></a>

`WepinWidgetSDK` 인스턴스를 생성하기 전에 위핀 워크스페이스에서 Android/iOS 관련 앱 정보를 등록해야 합니다.

{% content-ref url="/pages/cfg4nwJBI8VfiJpH4EW8" %}
[앱 등록 및 키 발급](/wepin/workspace/app-registration-and-key-issuance)
{% endcontent-ref %}

등록한 앱 정보를 바탕으로 `WepinWidgetSDK` 인스턴스를 생성합니다. `main.dart` 파일의 `state init` 단계에서 `WepinWidgetSDK` 인스턴스를 생성하고 초기화해야 합니다.

{% code title="main.dart" %}

```dart
WepinWidgetSDK wepinSDK = WepinWidgetSDK(
    wepinAppKey: wepinAppKey, 
    wepinAppId: wepinAppId
);
```

{% endcode %}

## init

`Wepin Flutter Widget SDK`를 초기화할 때, 필요한 위젯 속성들을 정의할 수 있습니다.

```dart
await wepinSDK.init({WidgetAttributes? attributes});
```

#### **Parameters**

* **attributes** `<WidgetAttributes>` ***optional*****&#x20;-** 초기화 시 정의할 위젯 속성들입니다
  * **defaultLanguage**`<String>`\
    위젯의 기본 언어 설정. 기본 값은 `ko`이며, 현재 지원하는 언어는 `en`, `ko` 두 가지입니다.
  * **defaultCurrency** `<String>`\
    위젯의 기본 통화 설정. 기본 값은 `KRW`이며, 현재 지원하는 통화는 `USD`, `KRW` 두 가지입니다.

#### **Return value**

* `Future`\<void>

#### Example

```dart
await wepinSDK.init(WidgetAttributes(
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
));
```

## isInitialized

`WepinSDK`가 정상적으로 초기화되었는지 확인할 수 있습니다.

```dart
wepinSDK.isInitialized()
```

#### **Parameters**

* None

#### **Return Value**

* **\<bool>**\
  초기화가 정상적으로 잘 된 경우 true , 실패한 경우 false 를 반환합니다.

#### **Example**

```dart
await wepinSDK.init(WidgetAttributes(
    defaultLanguage: 'ko',
    defaultCurrency: 'KRW',
));

if (wepinSDK.isInitialized()) {
  print('WepinSDK is initialized!');
}
```

## changeLanguage

위젯의 언어와 통화를 변경할 수 있습니다.

```dart
wepinSDK.changeLanguage({language, currency});
```

#### **Parameters**

* **language** `<String>`\
  위젯에 표시될 언어를 지정합니다. 현재 지원하는 언어는 `en`, `ko` 두 가지 입니다.
* **currency** `<String>`\
  위젯에 표시될 통화를 지정합니다. 현재 지원하는 통화는 `USD`, `KRW` 두 가지 입니다.

#### Example

```dart
wepinSDK.changeLanguage(
  language: 'ko',
  currency: 'KRW'
);
```


# 메서드

Wepin flutter widget SDK에서 제공하는 메서드입니다.

## getStatus

```dart
await wepinSDK.getStatus()
```

`WepinSDK`의 Lifecycle 상태 값을 반환합니다.

#### **Parameters**

* None

#### **Return value**

* **Future \<WepinLifeCycle>**
  * **notInitialized**: `WepinSDK`이 초기화되지 않음
  * **initializing**: `WepinSDK`초기화 진행 중
  * **initialized**: `WepinSDK`초기화 완료
  * **beforeLogin**: `WepinSDK`은 초기화되었으나 사용자는 로그인 되지 않음
  * **login**: 사용자가 로그인 되었고 위핀에도  가입되어있음
  * **loginBeforeRegister**: 사용자가 로그인하였으나 위핀에 가입되지 않음

#### **Example**

```dart
final status = await wepinSDK.getStatus();
```

## login

`login` 변수는 다양한 인증 방법을 포함한 위핀 로그인 라이브러리로, 사용자가 여러 방식으로 로그인할 수 있도록 합니다. 이메일 및 비밀번호 로그인, OAuth 프로바이더 로그인, ID Token 또는 Access Token을 사용한 로그인 등을 지원합니다. 각 메서드에 대한 자세한 정보는 공식 라이브러리 문서  [Login Library 가이드](/widget-integration/flutter-sdk/login-library/methods)에서 확인할 수 있습니다.

#### **Available Methods**

* [`loginWithOauthProvider`](/widget-integration/ios-swift-sdk/login-library/methods#loginwithoauthprovider)
* [`signUpWithEmailAndPassword`](/widget-integration/ios-swift-sdk/login-library/methods#signupwithemailandpassword)
* [`loginWithEmailAndPassword`](/widget-integration/ios-swift-sdk/login-library/methods#loginwithemailandpassword)
* [`loginWithIdToken`](/widget-integration/ios-swift-sdk/login-library/methods#loginwithidtoken)
* [`loginWithAccessToken`](/widget-integration/ios-swift-sdk/login-library/methods#loginwithaccesstoken)
* [`getRefreshFirebaseToken`](/widget-integration/ios-swift-sdk/login-library/methods#getrefreshfirebasetoken)
* [`loginFirebaseWithOauthProvider`](/widget-integration/flutter-sdk/login-library/methods#loginfirebasewithoauthprovider)
* [`loginWepinWithOauthProvider`](/widget-integration/flutter-sdk/login-library/methods#loginWepinWithOauthProvider)
* [`loginWepinWithIdToken`](/widget-integration/flutter-sdk/login-library/methods#loginWepinWithIdToken)
* [`loginWepinWithAccessToken`](/widget-integration/flutter-sdk/login-library/methods#loginWepinWithAccessToken)
* [`loginWepinWithEmailAndPassword`](/widget-integration/flutter-sdk/login-library/methods#loginWepinWithEmailAndPassword)
* [`loginWepin`](/widget-integration/ios-swift-sdk/login-library/methods#loginwepin)
* [`getCurrentWepinUser`](/widget-integration/ios-swift-sdk/login-library/methods#getcurrentwepinuser)
* [`logout`](/widget-integration/ios-swift-sdk/login-library/methods#logoutwepin)
* [`getSignForLogin`](/widget-integration/ios-swift-sdk/login-library/methods#getsignforlogin)

이 메서드들은 다양한 로그인 시나리오를 지원하며, 필요에 맞는 적절한 방법을 선택할 수 있습니다.

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
// OAuth Provider를 사용한 로그인
final oauthResult = await wepinSDK.login.loginWithOauthProvider(provider: 'google', clientId: 'your-client-id');

// 이메일 및 비밀번호로 회원가입 및 로그인
final signUpResult = await wepinSDK.login.signUpWithEmailAndPassword(email: 'example@example.com', password: 'password123');

// ID Token을 사용한 로그인
final idTokenResult = await wepinSDK.login.loginWithIdToken(idToken: 'your-id-token', sign: 'your-sign');

// 위핀에 로그인
final wepinLoginResult = await wepinSDK.login.loginWepin(idTokenResult);

// 현재 로그인된 사용자 가져오기
final currentUser = await wepinSDK.login.getCurrentWepinUser();

// 로그아웃
await wepinSDK.login.logout();
```

## loginWithUI&#x20;

```dart
await wepinSDK.loginWithUI(BuildContext context, {required List<LoginProvider> loginProviders, String? email})
```

`loginWithUI()` 메서드는 위젯을 사용하여 로그인하는 기능을 제공하며, 로그인된 사용자의 정보를 반환합니다. 사용자가 이미 로그인되어 있는 경우, 위젯을 표시하지 않고 로그인된 사용자의 정보를 바로 반환합니다. 위젯 없이 로그인을 수행하려면, `login` 변수의 `loginWepin()` 메서드를 대신 사용해야 합니다.

**Supported Version**\
버전 <mark style="color:orange;">**`0.0.4`**</mark> 이상에서 지원.

#### **Parameters**

* **context** <`BuildContext`> \
  Flutter에서 위젯 트리 내의 위치를 나타내며, 위젯의 위치를 찾고 네비게이션, 테마 데이터 접근 등의 기능을 제공합니다.   `loginWithUI`을 호출할 때 현재 `context`를 전달하여 위젯이 UI 계층의 올바른 부분에 표시되도록 합니다.
* **loginProviders**<`List<LoginProvider>`> - 위젯을 구성할 로그인 프로바이더들의 목록입니다. 빈 목록이 제공되면 이메일 로그인 기능만 사용할 수 있습니다.
  * **provider** <`String`>\
    OAuth 로그인 프로바이더(예: 'google', 'naver', 'discord', 'apple')
  * **clientId** <`String`> \
    OAuth 로그인 프로바이더의 클라이언트 ID입니다.
* **email**<`String`> ***optional***\
  `email` 매개변수는 위젯에서 로그인할 때 지정된 이메일 주소로 로그인할 수 있도록 합니다.

{% hint style="info" %}
OAuth 로그인 기능(예: loginWithUI)을 사용하려면 OAuth 로그인 프로바이더를 설정해야 합니다. 이를 위해 먼저 [위핀 워크스페이스](https://workspace.wepin.io/login)에 OAuth 로그인 프로바이더 정보를 등록해야 합니다. OAuth 프로바이더 설정에 대한 자세한 내용은 [소셜 로그인 인증 프로바이더 문서](/login/social-login-auth-provider)를 참고하세요.
{% endhint %}

#### **Return Value**

* **Future\<WepinUser>**
  * **status** `<String>`&#x20;

    성공 여부<'success'|'fail'>
  * **userInfo** `<WepinUserInfo>` ***optional*****&#x20;-** 사용자 정보
    * **userId** `<String>`

      Wepin 사용자 ID
    * **email** `<String>`&#x20;

      위핀에 로그인된 사용자의 이메일 주소
    * **provider**`<String>`

      로그인 프로바이더<'google'|'apple'|'naver'|'discord'|'email'|'external\_token'>
    * **use2FA**`<bool>`

      사용자 지갑에 2FA가 활성화되어 있는지 여부
  * **userStatus** `<WepinUserStatus>` - 사용자 상태
    * **loginStatus** `<String>`

      로그인 상태 <'complete' | 'pinRequired' | 'registerRequired'>&#x20;

      사용자의 loginStatus 값이 'complete'가 아닌  경우, 위핀에 register 해야 합니다.
    * **pinRequired** `<bool>` ***optional***

      사용자 PIN 번호 필요 여부
  * **walletId** `<String>`

    위핀사용자의 지갑 ID
  * **token** `<WepinToken>`\
    Wepin Token 정보

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
// google, apple, discord, naver login
final res = await wepinSDK.loginWithUI(context,
  loginProviders: [
    {
      provider: 'google',
      clientId: 'google-client-id'
    },
    {
      provider: 'apple',
      clientId: 'apple-client-id'
    },
    {
      provider: 'discord',
      clientId: 'discord-client-id'
    },
    {
      provider: 'naver',
      clientId: 'naver-client-id'
    },
  ]);

// only email login
final res = await wepinSDK.loginWithUI(context,
  loginProviders: []);

//with specified email address
final res = await wepinSDK.loginWithUI(context,
  loginProviders: [], email: 'abc@abc.com');
  
if(res.userStatus.loginStatus != "complete"){
    final userInfo  = await wepinSDK.register(context);
}
```

## openWidget

```dart
await wepinSDK.openWidget(BuildContext context)
```

위젯 창을 열어줍니다. 사용자가 로그인되어 있지 않으면 위젯 창이 열리지 않으므로, `openWidget`을 호출하기 전에 반드시 사용자가 위핀에 로그인되어 있어야 합니다. 로그인하려면 `loginWithUI` 매서드 또는 `login` 변수의 `loginWepin` 메서드를 사용해야 합니다.

#### **Parameters**

* **context** <`BuildContext`> \
  Flutter에서 위젯 트리 내의 위치를 나타내며, 위젯의 위치를 찾고 네비게이션, 테마 데이터 접근 등의 기능을 제공합니다. `openWidget`을 호출할 때 현재 `context`를 전달하여 위젯이 UI 계층의 올바른 부분에 표시되도록 합니다.

#### **Return Value**

* **Future\<void>**

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
await wepinSDK.openWidget(context);
```

## closeWidget

```dart
wepinSDK.closeWidget()
```

위젯 창을 닫습니다. 창을 닫아도 로그아웃되지 않습니다.

#### **Parameters**

* None

#### **Return Value**

* **void**

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
wepinSDK.closeWidget();
```

## register

```dart
await wepinSDK.register(BuildContext context)
```

사용자를 위에 등록합니다. 가입 및 로그인 후 위핀 위젯의 등록 페이지가 열리며, 위핀 서비스에 등록(지갑 생성 및 계정 생성)을 진행합니다. 이 기능은 `WepinSDK`의 `WepinLifeCycle`이 `loginBeforeRegister` 상태일 때만 사용할 수 있습니다. `loginWithUI` 매서드 또는 `login` 변수의 `loginWepin` 메서드를 호출한 후, `userStatus`의 `loginStatus` 값이 'complete'가 아니면 이 메서드를 호출해야 합니다.

#### **Parameters**

* context <`BuildContext`> \
  위젯 트리 내의 위치를 나타내며, 위젯의 위치를 찾고 네비게이션, 테마 데이터 접근 등의 기능을 제공합니다. `register`를 호출할 때 현재 `context`를 전달하여 위젯이 UI 계층의 올바른 부분에 표시되도록 합니다.

#### **Return Value**

* **Future\<WepinUser>**
  * **status** `<String>`&#x20;

    성공 여부<'success'|'fail'>
  * **userInfo** `<WepinUserInfo>` ***optional*****&#x20;-** 사용자 정보
    * **userId** `<String>`

      위핀사용자 ID
    * **email** `<String>`

      위핀에 로그인된 사용자의 이메일 주소
    * **provider**`<String>`

      로그인 프로바이더<'google'|'apple'|'naver'|'discord'|'email'|'external\_token'>
    * **use2FA**`<bool>`

      사용자 지갑에 2FA가 활성화되어 있는지 여부
  * **userStatus** `<WepinUserStatus>` - 사용자 상태
    * **loginStatus** `<String>`

      로그인 상태 <'complete' | 'pinRequired' | 'registerRequired'>&#x20;

      사용자의 loginStatus 값이 'complete'가 아닌  경우, 위핀에 register 해야 합니다.
    * **pinRequired** `<bool>` ***optional***

      사용자 PIN 번호 필요 여부
  * **walletId** `<String>`

    위핀 사용자의 지갑 ID
  * **token** `<WepinToken>`\
    Wepin Token 정보

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
final userInfo = await wepinSDK.register(context);
```

## getAccounts

```dart
await wepinSDK.getAccounts({List<String>? networks, bool? withEoa})
```

앱에서 사용 가능한 사용자의 계정 정보(네트워크와 주소)를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. 파라미터가 없는 경우에는 사용자의 모든 계정 정보가 반환됩니다.

#### **Parameters**

* **networks** `<List<String>>` ***optional***

  반환받고자 하는 계정의 네트워크입니다. 네트워크로 지원하는 블록체인 목록은 아래 지원 블록체인 페이지에서 확인 가능합니다.
* **withEoa**`<bool>` ***optional***

  AA 계정이 있는 경우, EOA 계정도 포함하여 반환할지 여부를 지정합니다.

{% content-ref url="/pages/jNG611rZkq69C8zZKglh" %}
[지원 블록체인](/wepin/supported-blockchains)
{% endcontent-ref %}

#### **Return Value**

* **Future \<List\<WepinAccount>>**
  * **address** `<String>`

    사용자 계정의 주소
  * **network** `<String>`

    사용자 계정의 네트워크 종류
  * **contract** `<String>` ***optional***

    토큰의 Contract 주소
  * **isAA** `<bool>` ***optional***

    AA 계정인지 여부

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
final result = await wepinSDK.getAccounts(
  networks: ['Ethereum'], 
  withEoa: true
);
```

* response

```dart
[
  WepinAccount(
    address: "0x0000001111112222223333334444445555556666",
    network: "Ethereum",
  ),
  WepinAccount(
    address: "0x0000001111112222223333334444445555556666",
    network: "Ethereum",
    contract: "0x777777888888999999000000111111222222333333",
  ),
  WepinAccount(
    address: "0x4444445555556666000000111111222222333333",
    network: "Ethereum",
    isAA: true,
  ),
]
```

## getBalance

```dart
await wepinSDK.getBalance({List<WepinAccount>? accounts})
```

정의 잔액(수량) 정보를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다.\
`accounts` 파라미터가 없는 경우에는 사용자의 모든 계정의 잔액이 반환됩니다.

#### **Parameters**

* **accounts** `<List<WepinAccount>>` ***optional***
  * **network** `<String>`

    잔액을 조회할 사용자 계정의 네트워크 종류
  * **address** `<String>`

    잔액을 조회할 사용자 계정의 주소
  * **isAA**`<bool>` ***optional***

    AA 계정인지 여부

#### **Return Value**

* **Future \<List\<WepinAccountBalanceInfo>>**
  * **network** `<String>`

    사용자 계정의 네트워크 종류
  * **address** `<String>`

    사용자 계정의 주소
  * **symbol** `<String>`&#x20;

    네트워크 심볼
  * **balance** `<String>`&#x20;

    보유하고 있는 네트워크 코인의 수량
  * **tokens** `<List<WepinTokenBalanceInfo>>`&#x20;
    * **symbol** `<String>`&#x20;

      토큰 심볼
    * **balance** `<String>`&#x20;

      보유하고 있는 토큰의 수량
    * **contract** `<String>`&#x20;

      토큰  Contract 주소

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
final result = await wepinSDK.getBalance([WepinAccount(
  address: '0x0000001111112222223333334444445555556666',
  network: 'Ethereum',
)]);
```

* response

```dart
[
    WepinAccountBalanceInfo(
        network: "Ethereum",
        address: "0x0000001111112222223333334444445555556666",
        symbol: "ETH",
        balance: "1.1",
        tokens:[
            WepinTokenBalanceInfo(
                contract: "0x123...213",
                symbol: "TEST",
                balance: "10"
            ),
        ]
    )
]
```

## getNFTs

```dart
await wepinSDK.getNFTs({required bool refresh, List<String>? networks})
```

사용자의 NFT를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다. \
`networks`파라미터가 없는 경우에는 사용자의 모든 NFT 정보가 반환됩니다.

#### **Parameters**

* **refresh** `<bool>` \
  NFT 데이터를 새로 조회할지 여부
* **networks** `<List<String>>` ***optional***\
  NFT를 필터링할 네트워크 이름 목록

#### **Return Value**

* **Future \<List\<WepinNFT>>**
  * **account** `<WepinAccount>`
    * **address** `<String>`

      사용자 계정의 주소
    * **network** `<String>`

      사사용자 계정의 네트워크 종류
    * **contract** `<String>` ***optional***

      토큰의 Contract 주소
    * **isAA** `<bool>` ***optional***

      AA 계정인지 여부
  * **contract** `<WepinNFTContract>`&#x20;
    * **name** `<String>` \
      NFT Contract 이름
    * **address** `<String>`\
      NFT Contract 주소
    * **scheme** `<String>` \
      NFT의 스킴&#x20;
    * **description** `<String>` ***optional***\
      NFT Contract의 설명&#x20;
    * **network** `<String>` \
      NFT Contract과 연결된 네트워크
    * **externalLink** `<String>` ***optional***\
      NFT Contract와 관련된 외부 링크
    * **imageUrl** `<String>` ***optional***\
      NFT Contract와 관련된 이미지 URL
  * **name** `<String>` \
    NFT의 이름
  * **description** `<String>` \
    NFT의 설명
  * **externalLink** `<String>` \
    NFT와 관련된 외부 링크
  * **imageUrl** `<String>` \
    NFT와 관련된 이미지 URL
  * **contentUrl** `<String>` ***optional***\
    NFT와 연결된 콘텐츠의 URL
  * **quantity** `<int>` \
    NFT의 수량
  * **contentType** `<String>` \
    NFT의 콘텐츠 유형<'image' | 'video'>
  * **state** `<int>` \
    NFT의 상태

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
final result = await wepinSDK.getNFTs(refresh: true, networks: ['Ethereum']);
```

* response

```dart
[
  WepinNFT(
    account: WepinAccount(
      address: "0x0000001111112222223333334444445555556666",
      network: "Ethereum",
      contract: "0x777777888888999999000000111111222222333333",
      isAA: true,
    ),
    contract: WepinNFTContract(
      name: "NFT Collection",
      address: "0x777777888888999999000000111111222222333333",
      scheme: "ERC721",
      description: "An example NFT collection",
      network: "Ethereum",
      externalLink: "https://example.com",
      imageUrl: "https://example.com/image.png",
    ),
    name: "Sample NFT",
    description: "A sample NFT description",
    externalLink: "https://example.com/nft",
    imageUrl: "https://example.com/nft-image.png",
    contentUrl: "https://example.com/nft-content.png",
    quantity: 1,
    contentType: "image/png",
    state: 0,
  ),
]
```

## send

```dart
await wepinSDK.send(BuildContext context, {required WepinAccount account, WepinTxData? txData})
```

위젯을 이용하여 send기능을 수행하고 send 트랜젝션의 ID정보를 반환합니다. 이 기능은 위핀에 로그인한 후에만 사용할 수 있습니다.

#### **Parameters**

* `context` \<BuildContext> -Flutter에서 위젯 트리 내의 위치를 나타내며, 위젯의 위치를 찾고 네비게이션, 테마 데이터 접근 등의 기능을 제공합니다. `send`를 호출할 때 현재 `context`를 전달하여 위젯이 UI 계층의 올바른 부분에 표시되도록 합니다.
* **`account`**`<WepinAccount>`&#x20;

  전송할 사용자의  계정 정보

  * **network**`<String>`&#x20;

    전송할 네트워크 종류
  * **address**`<String>`&#x20;

    전송할 계정의 주소
  * **contract** `<String>` ***optional***

    토큰의 Contract 주소
* **txData** `<WepinTxData>` ***optional***
  * **to** `<String>`\
    전송 받을 주소
  * **amount** `<String>` \
    전송할 수량

#### **Return Value**

* **Future \<WepinSendResponse>**
  * **txId** `<String>`\
    send 트랜잭션의 txID

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

```dart
final result = await wepinSDK.send(context, {
    account: WepinAccount(
        address: '0x0000001111112222223333334444445555556666',
        network: 'Ethereum',
    ),
    txData: WepinTxData(
        to: '0x9999991111112222223333334444445555556666',
        amount: '0.1',
    )
})

// token send
final result = await wepinSDK.send(context, {
    account: WepinAccount(
        address: '0x0000001111112222223333334444445555556666',
        network: 'Ethereum',
        contract: '0x0000001111112222223333334444445555556666'
    ),
    txData: WepinTxData(
        to: '0x9999991111112222223333334444445555556666',
        amount: '0.1',
    )
})
```

* response

```dart
WepinSendResponse(
    txId: "0x76bafd4b700ed959999d08ab76f95d7b6ab2249c0446921c62a6336a70b84f32"
)
```

## receive

```dart
await wepinSDK.receive(BuildContext context, {required WepinAccount account})
```

`receive` 메서드는 지정된 계정과 연관된 계정 정보 페이지를 엽니다. 이 메서드는 위핀에 로그인한 후에만 사용할 수 있습니다.

**Supported Version**\
버전 <mark style="color:orange;">**`0.0.4`**</mark> 이상에서 지원.

#### **Parameters**

* **context** <`BuildContext`> \
  Flutter에서 위젯 트리 내의 위치를 나타내며, 위젯의 위치를 찾고 네비게이션, 테마 데이터 접근 등의 기능을 제공합니다.  `receive` 매서드를 호출할 때 현재 `context`를 전달하여 위젯이 UI 계층의 올바른 부분에 표시되도록 합니다.
* **account**`<WepinAccount>`&#x20;

  오픈할 페이지에 대한 계정을 제공합니다.

  * **network**`<String>`&#x20;

    계정과 연관된 네트워크
  * **address**`<String>`&#x20;

    계정의 주소
  * **contract** `<String>` ***optional***

    토큰의 Contract 주소

#### **Return Value**

* **Future\<WepinReceiveResponse>**
  * **account**`<WepinAccount>`&#x20;

    오픈된 페이지의 계정 정보

    * **network**`<String>`&#x20;

      계정과 연관된 네트워크

      * **address**`<String>`&#x20;

        계정의 주소
      * **contract** `<String>` ***optional***

        토큰의 Contract 주소

#### **Exception**

* [WepinError](/widget-integration/flutter-sdk/widget/methods#wepinerror)

#### **Example**

<pre class="language-dart"><code class="lang-dart"><strong>// Opening an account page
</strong>final result = await wepinSDK.receive(context, {
    account: WepinAccount(
      address: '0x0000001111112222223333334444445555556666',
      network: 'Ethereum',
    ),
})

// Opening a token page
final result = await wepinSDK.receive(context, {
  account: WepinAccount(
    address: '0x0000001111112222223333334444445555556666',
    network: 'Ethereum',
    contract: '0x9999991111112222223333334444445555556666'
  ),
})
</code></pre>

## finalize

```dart
await wepinSDK.finalize()
```

WepinSDK 사용을 종료합니다. `WepinLifeCycle`이 `notInitialized` 로 변경됩니다.&#x20;

#### **Return Value**

* **None**

#### **Example**

```dart
await wepinSDK.finalize();
```

## WepinError

| Error Code                    | Error Message                 | Error Description                                                                                                                                                                                    |
| ----------------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalidAppKey`               | "InvalidAppKey"               | The Wepin app key is invalid.                                                                                                                                                                        |
| `invalidParameters` \`        | "InvalidParameters"           | One or more parameters provided are invalid or missing.                                                                                                                                              |
| `invalidLoginProvider`        | "InvalidLoginProvider"        | The login provider specified is not supported or is invalid.                                                                                                                                         |
| `invalidToken`                | "InvalidToken"                | The token does not exist.                                                                                                                                                                            |
| `invalidLoginSession`         | "InvalidLoginSession"         | The login session information does not exist.                                                                                                                                                        |
| `notInitialized`              | "NotInitialized"              | The WepinLoginLibrary has not been properly initialized.                                                                                                                                             |
| `alreadyInitialized`          | "AlreadyInitialized"          | The WepinLoginLibrary is already initialized, so the logout operation cannot be performed again.                                                                                                     |
| `userCancelled`               | "UserCancelled"               | The user has cancelled the operation.                                                                                                                                                                |
| `unknownError`                | "UnknownError"                | An unknown error has occurred, and the cause is not identified.                                                                                                                                      |
| `notConnectedInternet`        | "NotConnectedInternet"        | The system is unable to detect an active internet connection.                                                                                                                                        |
| `failedLogin`                 | "FailedLogin"                 | The login attempt has failed due to incorrect credentials or other issues.                                                                                                                           |
| `alreadyLogout`               | "AlreadyLogout"               | The user is already logged out, so the logout operation cannot be performed again.                                                                                                                   |
| `invalidEmailDomain`          | "InvalidEmailDomain"          | The provided email address's domain is not allowed or recognized by the system.                                                                                                                      |
| `failedSendEmail`             | "FailedSendEmail"             | The system encountered an error while sending an email. This is because the email address is invalid or we sent verification emails too often. Please change your email or try again after 1 minute. |
| `requiredEmailVerified`       | "RequiredEmailVerified"       | Email verification is required to proceed with the requested operation.                                                                                                                              |
| `incorrectEmailForm`          | "incorrectEmailForm"          | The provided email address does not match the expected format.                                                                                                                                       |
| `incorrectPasswordForm`       | "IncorrectPasswordForm"       | The provided password does not meet the required format or criteria.                                                                                                                                 |
| `notInitializedNetwork`       | "NotInitializedNetwork"       | The network or connection required for the operation has not been properly initialized.                                                                                                              |
| `requiredSignupEmail`         | "RequiredSignupEmail"         | The user needs to sign up with an email address to proceed.                                                                                                                                          |
| `failedEmailVerified`         | "FailedEmailVerified"         | The WepinLoginLibrary encountered an issue while attempting to verify the provided email address.                                                                                                    |
| `failedPasswordStateSetting`  | "FailedPasswordStateSetting"  | Failed to set the password state. This error may occur during password management operations, potentially due to invalid input or system issues.                                                     |
| `failedPasswordSetting`       | "failedPasswordSetting"       | Failed to set the password. This could be due to issues with the provided password or internal errors during the password setting process.                                                           |
| `existedEmail`                | "ExistedEmail"                | The provided email address is already registered. This error occurs when attempting to sign up with an email that is already in use.                                                                 |
| `apiRequestError`             | "ApiRequestError"             | There was an error while making the API request. This can happen due to network issues, invalid endpoints, or server errors.                                                                         |
| `incorrectLifecycleException` | "IncorrectLifecycleException" | The lifecycle of the Wepin SDK is incorrect for the requested operation. Ensure that the SDK is in the correct state (e.g., `initialized` and `login`) before proceeding.                            |
| `failedRegister`              | "FailedRegister"              | Failed to register the user. This can occur due to issues with the provided registration details or internal errors during the registration process.                                                 |
| `accountNotFound`             | "AccountNotFound"             | The specified account was not found. This error is returned when attempting to access an account that does not exist in the Wepin.                                                                   |
| `nftNotFound`                 | "NftNotFound"                 | The specified NFT was not found. This error occurs when the requested NFT does not exist or is not accessible within the user's account.                                                             |
| `failedSend`                  | "FailedSend"                  | Failed to send the required data or request. This error could be due to network issues, incorrect data, or internal server errors.                                                                   |


# 확인하기

Wepin flutter widget SDK 초기화를 정상적으로 완료하면 위핀에 로그인 할 수 있습니다. 로그인까지 완료하면 아래와 같이 새로운 위핀 지갑이 생성되고 해당 지갑에 있는 계정 정보를 확인할 수 있습니다.

<figure><img src="/files/Tm47bItnp70Z0MwTXLob" alt=""><figcaption></figcaption></figure>

## 예제

<mark style="color:blue;">`wepin-flutter-widget_sdk`</mark> 를 사용한 예제 Flutter 앱은 아래 깃허브에서 확인 가능합니다.

{% embed url="<https://github.com/WepinWallet/wepin-flutter-sdk-v1/tree/main/packages/wepin_flutter_widget_sdk/example>" %}


# React Native SDK

이 문서는 React Native SDK 을 이용하여 Flutter에서 위핀 위젯을 통합하기 위한 절차를 설명합니다.

## 패키지 리스트

<table><thead><tr><th width="162">종류</th><th width="281">패키지 </th><th>설명</th></tr></thead><tbody><tr><td><a href="/pages/CUsZtt54jx1fetzWm2uH">로그인</a></td><td><code>@wepin/login-rn</code></td><td>소셜 로그인과 같은 OAuth 인증 토큰으로 위핀에 로그인하는 기능을 제공합니다.</td></tr></tbody></table>


# 로그인

소셜 로그인과 같은 OAuth 인증 토큰 또는 이메일로 Wepin에 로그인 하는 방법에 대한 안내 페이지입니다.


# 설치

## 요구사항 <a href="#requirements" id="requirements"></a>

* React Native version 0.71.8 이상
* **Android:** API 버전 <mark style="color:blue;">**23**</mark> 이상
* **iOS:** API 버전 <mark style="color:blue;">**12.0**</mark> 이상

{% hint style="info" %}
해당 패키지는 Android, iOS 환경에서만 사용 가능합니다. Web, MacOS, Window, Linux 환경에서는 사용할 수 없습니다.&#x20;
{% endhint %}

{% hint style="info" %}
1.0.0 이전 버전에서 설치한 경우에만 확인해주세요.\
v1.0.0 업데이트에는 저장소 키 변경 등 앱 동작에 영향을 줄 수 있는 중요한 변경사항이 포함되어 있습니다. v1.0.0 이전 버전을 사용 중이었다면, 다음 변경 사항을 반드시 먼저 확인해주세요.
{% endhint %}

{% hint style="warning" %}
New Architecture는 아직 지원되지 않습니다
{% endhint %}

#### 저장소 마이그레이션 안내 (v1.0.0 기준) <a href="#storage-migration-notice-from-v1.0.0" id="storage-migration-notice-from-v1.0.0"></a>

* v1.0.0부터 저장소 키 변경 정책이 적용되어, 기존 저장된 데이터에 접근할 수 없는 경우가 발생할 수 있습니다.
* &#x20;키가 유효하지 않은 경우에 한해, 기존 저장 데이터는 자동으로 초기화되고 새 키가 생성됩니다.
* 키가 정상적으로 유지되는 경우, 기존 데이터는 그대로 유지됩니다.
* v1.0.0 이후 버전에서 이전 버전으로 다운그레이드할 경우, 기존 데이터에 접근하지 못할 수 있습니다.

{% hint style="info" %}
업데이트 전에 잠재적인 문제를 방지하기 위해 데이터를 백업해두는 것을 추천드립니다.
{% endhint %}

#### 백업 비활성화 방법 (Android) <a href="#how-to-disable-backup-android" id="how-to-disable-backup-android"></a>

`AndroidManifest.xml` 파일을 다음과 같이 수정하세요:

```xml
<application
    android:allowBackup="false"
    android:fullBackupContent="false">
```

`android:allowBackup`이 `true`로 설정되어 있으면, 마이그레이션 과정이 정상적으로 동작하지 않아 **데이터 손실** 또는 **저장소 문제**가 발생할 수 있습니다.

## 설치하기 <a href="#installation" id="installation"></a>

Wepin React Native SDK 를 설치하는 방법을 설명합니다.

### Wepin 설치하기

Wepin React Native SDK 는 npm 패키지로 설치 가능합니다.

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

```bash
npm install @wepin/login-rn
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add @wepin/login-rn
```

{% endtab %}
{% endtabs %}

### peerDependencies

```bash
npm install react-native-device-info

# for ios
cd ios
pod install
```

or

```bash
yarn add react-native-device-info

# for ios
cd ios 
pod install
```

### react-native.config.js 설정 <a href="#react-native.config.js-setting" id="react-native.config.js-setting"></a>

react-native.config.js 파일에 @wepin/storage-rn 경로를 설정해주어야 합니다.

```javascript
const path = require('path');
module.exports = {
  dependencies: {
    '@wepin/storage-rn': {
      root: path.join(__dirname, './node_modules/@wepin/storage-rn'),
    },
  },
};
```

#### iOS Podfile 설정

Xcode 26.0.1 이상 버전 사용 시 빌드 에러가 발생할 수 있습니다.

> error Unable to find module dependency: 'bcrypt' (in tarrget 'WepinLogin' from project 'Pods')

위와 같은 에러가 발생하는 경우 Podfile 에 아래 코드를 추가해주세요.

```
post_install do |installer| 
  installer.pods_project.targets.each do |target| 
    target.build_configurations.each do |config| 
      config.build_settings['SWIFT_ENABLE_EXPLICIT_MODULES'] = 'NO' 
    end 
  end 
end
```


# 초기화

Wepin React Native  Login Library 를 초기화하는 방법입니다.

## Import SDK

다음과 같이 import 문을 추가합니다.

```typescript
import WepinLogin from '@wepin/login-rn'
```

## WepinLogin Instance 생성 및 초기화 <a href="#creating-and-initializing-the-wepinlogin-instance" id="creating-and-initializing-the-wepinlogin-instance"></a>

먼저, `WepinLogin` 인스턴스를 생성하기 전에 위핀 워크스페이스에서 Android/iOS 관련 앱 정보를 등록해야 합니다.

{% content-ref url="/pages/cfg4nwJBI8VfiJpH4EW8" %}
[앱 등록 및 키 발급](/wepin/workspace/app-registration-and-key-issuance)
{% endcontent-ref %}

등록한 앱 정보를 바탕으로 `WepinLogin` 인스턴스를 생성하고, `init()` 메소드를 호출하여 초기화 해야 합니다.

```typescript
const wepinLogin = new WepinLogin({
  appId: 'wepinAppId',
  appKey: 'wepinAppKey',
});

await wepinLogin.init()
```

## isInitialized

<mark style="color:blue;">`isInitialized`</mark>메서드를 이용해서 WepinLogin 인스턴스가 정상적으로 초기화 되었는지 확인할 수 있습니다. &#x20;

반환값은 아래와 같습니다.&#x20;

* **\<boolean>**\
  초기화가 성공적으로 완료된 경우 `true`, 실패한 경우 `false`를 반환합니다.

```typescript
if(wepinLogin.isInitialized()) {
    // Success to initialize WepinLogin
}
```


# 메서드

Wepin React Native Login Library에서 제공하는 메서드 입니다.

## loginWithOauthProvider

```dart
await wepinLogin.loginWithOauthProvider(params);
```

인앱 브라우저가 열리고 OAuth 프로바이더에로그인합니다. Firebase 로그인 정보를 가져오려면 `loginWithIdToken()` 또는 `loginWithAccessToken()` 메서드를 호출해야 합니다.

#### **Parameters**

* **params** `<object>`
  * **provider** `<'google'|'naver'|'discord'|'apple'>`

    OAuth 로그인 프로바이더
  * **clientId** `<string>`

    OAuth 로그인 프로바이더의 클라이언트 ID

#### **Returns**

* **Promise\<LoginOauthResult>**
  * **provider** `<'google'|'naver'|'discord'|'apple'>`

    사용된 OAuth Provider의 이름
  * **token** `<string>`

    accessToken (Provider가 "naver" 또는 "discord"일 경우) 또는 idToken (Provider가 "google" 또는 "apple"일 경우)
  * **type** `<'id_token'|'access_token'>`

    OAuth 토큰의 유형

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const user = await wepinLogin.loginWithOauthProvider({
  provider: "google",
  clientId: "your-google-client-id"
});
```

***

## signUpWithEmailAndPassword

```typescript
await wepinLogin.signUpWithEmailAndPassword(email, password, locale?)
```

이메일과 비밀번호로 Wepin Firebase에 회원가입을 합니다. 가입되지 않은 사용자의 경우 검증 이메일이 전송되며, `REQUIRED_EMAIL_VERIFIED` 오류가 발생합니다. 이미 가입된 사용자의 경우, `EXISTED_EMAIL` 오류가 발생하며 [loginWithEmailAndPassword](#loginwithemailandpassword)를 호출하여 로그인 프로세스를 진행합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

#### **Parameters**

* **email** `<string>`

  사용자 이메일
* **password** `<string>`

  사용자 비밀번호
* **locale** `<string>` ***optional***

  인증 이메일의 언어 설정 (기본 값: "en")

#### **Returns**

* **Promise\<LoginResult>**
  * **provider** `<string>`

    로그인에 사용된 프로바이더(이 경우, 'email')
  * **token** `<object>`
    * **idToken** `<string>`

      Wepin Firebase ID Token
    * **refreshToken** `<string>`

      Wepin Firebase refresh Token

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const user = await wepinLogin.signUpWithEmailAndPassword(
  'abc@defg.com', 
  'abcdef123&'
);
```

***

## loginWithEmailAndPassword

```typescript
await wepinLogin.loginWithEmailAndPassword(email, password);
```

이메일과 비밀번호를 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

#### **Parameters**

* **email** `<string>`\
  사용자 이메일
* **password** `<string>`\
  사용자 비밀번호

#### **Returns**

* **Promise\<LoginResult>**
  * **provider** `<'email'>`

    로그인에 사용된 Provider
  * **token** `<object>`
    * **idToken** `<string>`

      Wepin Firebase ID Token
    * **refreshToken** `<string>`

      Wepin Firebase refresh Token

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const user = await wepinLogin.loginWithEmailAndPassword(
  'abc@defg.com', 
  'abcdef123&'
);
```

***

## loginWithIdToken

```typescript
await wepinLogin.loginWithIdToken(params);
```

외부 ID 토큰을 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

#### **Parameters**

* **params**`<object>`
  * **idToken** `<string>`\
    로그인에 사용될 ID Token 값
  * **sign** `<string>` **optional**\
    ID 토큰의 서명 값 ([`getSignForLogin()`](#getsignforlogin)의 반환값)

{% hint style="warning" %}
&#x20;Note

WepinLogin 버전 1.0.0부터는 `sign` 값이 선택 사항입니다.

[Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거하는 경우, `sign` 값을 사용하지 않아도 됩니다.

(Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제)

> 인증 키 메뉴는 이전에 인증 키를 발급한 경우에만 표시됩니다.
> {% endhint %}

#### **Returns**

* **Promise\<LoginResult>**
  * **provider** `<'external_token'>` \
    로그인에 사용된 프로바이더
  * **token** `<object>`
    * **idToken** `<string>`

      Wepin Firebase ID Token
    * **refreshToken** `<string>`

      Wepin Firebase refresh Token

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const user = await wepinLogin.loginWithIdToken({
    idToken:'eyJHGciO....adQssw5c', 
    sign:'9753d4dc...c63466b9'
});
```

***

## loginWithAccessToken

```typescript
await wepinLogin.loginWithAccessToken(params);
```

외부 Access Token을 사용하여 Wepin Firebase에 로그인합니다. 로그인에 성공하면 Firebase 로그인 정보를 반환합니다.

#### **Parameters**

* **params**`<object>`
  * **provider** `<"naver"|"discord">`

    Access Token을 발급한 프로바이더
  * **accessToken** `<string>`

    로그인에 사용될 Access Token 값
  * **sign** `<string>` **optional**

    Access Token의 서명 값 (returned value of `getSignForLogin()`)

{% hint style="warning" %}
&#x20;Note

WepinLogin 버전 1.0.0부터는 `sign` 값이 선택 사항입니다.

[Wepin Workspace](https://workspace.wepin.io/) 에서 발급된 인증 키를 제거하는 경우, `sign` 값을 사용하지 않아도 됩니다.

(Wepin Workspace > 개발 도구 메뉴 > 로그인 탭 > 인증 키 > 삭제)

> 인증 키 메뉴는 이전에 인증 키를 발급한 경우에만 표시됩니다.
> {% endhint %}

#### **Returns**

* **Promise\<LoginResult>**
  * **provider** `<string>`

    로그인에 사용된 프로바이더(in this case, 'external\_token')
  * **token** `<object>`
    * **idToken** `<string>`

      Wepin Firebase ID Token
    * **refreshToken** `<string>`

      Wepin Firebase refresh Token

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const user = await wepinLogin.loginWithAccessToken({
  provider: 'naver',
  token: 'eyJHGciO....adQssw5c',
  sign: '9753d4dc...c63466b9',
});
```

***

## getRefreshFirebaseToken

```typescript
await wepinLogin.getRefreshFirebaseToken();
```

현재 Wepin Firebase 토큰의 정보를 가져옵니다.

#### **Parameters**

* None

#### **Returns**

* **Promise\<LoginResult>**
  * **provider** `<string>`\
    로그인에 사용된 프로바이더
    * `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`
  * **token** `<object>`
    * **idToken** `<string>`\
      Wepin Firebase ID Token
    * **refreshToken** `<string>`\
      Wepin Firebase refresh Token

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const user = await wepinLogin.getRefreshFirebaseToken();
```

***

## loginWepin

```typescript
await wepinLogin.loginWepin({ provider, token });
```

Wepin Firebase Token을 사용하여 사용자를 위핀에 로그인합니다.

#### **Parameters**

* **params** `<LoginResult>`\
  [`loginWithEmailAndPassword()`](#loginwithemailandpassword), [`loginWithIdToken()`](#loginwithidtoken), or [`loginWithAccessToken()`](#loginwithaccesstoken)의 반환 값

#### **Returns**

* **Promise\<IWepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<object>`***optional***  - 사용자의 정보
    * **userId** `<string>`

      사용자의 ID
    * **email** `<string>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 Provider
    * **use2FA** `<boolean>`

      사용자가 이중 인증을 사용하는지 여부
  * **walletId** `<string>`

    사용자의 지갑 ID
  * **userStatus** `<object>` -사용자의 위핀 로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<boolean>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<object>`

    사용자의 Wepin Token

    * **accessToken** `<string>`\
      Access Token
    * **refreshToken** `<string>`\
      Refresh Token

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const wepinLogin = WepinLogin({ appId: 'appId', appKey: 'appKey' });
const res = await wepinLogin.loginWithOauthProvider({ 
  provider: 'google', 
  clientId: 'clientId'
});

const userInfo = await wepinLogin.loginWepin(res);
const userStatus = userInfo.userStatus;
if (
  userStatus.loginStatus === 'pinRequired' ||
  userStatus.loginStatus === 'registerRequired'
) {
  // wepin register
}
```

## getCurrentWepinUser

```typescript
await wepinLogin.getCurrentWepinUser();
```

위핀에 현재 로그인한 사용자의 정보를 가져옵니다.

#### **Parameters**

* None

#### **Returns**

* **Promise\<IWepinUser>**&#x20;
  * **status** `<'success'|'fail'>`

    로그인 상태
  * **userInfo** `<object>`***optional***  - 사용자의 정보
    * **userId** `<string>`

      사용자의 ID
    * **email** `<string>`

      사용자의 이메일
    * **provider** `<'google'|'apple'|'naver'|'discord'|'email'|'external_token'>`

      로그인 Provider
    * **use2FA** `<boolean>`

      사용자가 이중 인증을 사용하는지 여부
  * **walletId** `<string>`

    사용자의 지갑 ID
  * **userStatus** `<object>` -사용자의 위핀 로그인 상태
    * **loginStats** `<'complete' | 'pinRequired' | 'registerRequired'>`

      사용자의 `loginStatus` 값이 'complete'가 아닌 경우, 사용자는 위핀에 register해야 합니다.
    * **pinRequired** `<boolean>`***optional***&#x20;

      PIN이 필요한지 여부
  * **token** `<object>`

    사용자의 Wepin Token

    * **accessToken** `<string>`\
      Access Token
    * **refreshToken** `<string>`\
      Refresh Token

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const userInfo = await wepinLogin.getCurrentWepinUser();
const userStatus = userInfo.userStatus;
if (
  userStatus.loginStatus === 'pinRequired' ||
  userStatus.loginStatus === 'registerRequired'
) {
  // wepin register
}
```

## logout

```typescript
await wepinLogin.logout();
```

위핀에 로그인한 사용자를 로그아웃합니다.

#### **Parameters**

* None

#### **Returns**

* **Promise\<boolean>**

#### **Exception**

* [WepinLoginException](#wepinloginexception)

#### **Example**

```typescript
const result = await wepinLogin.logout();
if (result) {
  // Successfully logged out
}
```

## getSignForLogin

발급자를 확인하기 위한 서명을 생성합니다. 주로 ID Token 및 Access Token과 같은 로그인 관련 정보를 위한 서명을 생성하는 데 사용됩니다.

```typescript
import { getSignForLogin } from '@wepin/login-rn';
const result = getSignForLogin(privKey, message);
```

#### **Parameters**

* **privateKey** `<string>`\
  서명 생성에 사용되는 인증 키
* **message** `<string>`\
  서명될 메시지 또는 페이로드

{% hint style="info" %}
서명에 사용할 키는 [위핀 워크스페이스](https://workspace.wepin.io/login)에서 발급 받을 수 있습니다. 개발 도구 메뉴에서 로그인 탭의 인증키 발급 받기를 클릭하여 인증키를 확인하세요.
{% endhint %}

#### **Returns**

* **\<string>** \
  생성된 서명

{% hint style="warning" %}
인증 키(**privateKey**)는 반드시 안전하게 보관되어야 하며, 외부에 노출되지 않도록 주의해야 합니다. 보안과 민감한 정보 보호를 위해 `getSignForLogin()` 메서드는 프론트엔드가 아닌 백엔드에서 실행하는 것이 권장됩니다. 서명 생성 방법에 대해서는 아래 문서를 참고하세요.

* [Signature Generation Methods](https://github.com/WepinWallet/wepin-web-sdk-v1/blob/main/packages/login/SignatureGenerationMethods.md)
  {% endhint %}

#### **Example**

```typescript
const sign = getSignForLogin(
    '0400112233445566778899001122334455667788990011223344556677889900',
    'idtokenabcdef'
);

const res = await wepinLogin.loginWithIdToken(
    'eyJHGciO....adQssw5c', 
    sign
);
```

## finalize

```typescript
await wepinLogin.finalize();
```

Wepin Login Library 를 종료합니다.

#### **Parameters**

* None

#### **Returns**

* **Promise\<void>**

#### **Example**

```typescript
await wepinLogin.finalize();
```

## WepinLoginException

<table><thead><tr><th width="297">Error Code</th><th>Error Message</th><th>Error Description</th></tr></thead><tbody><tr><td><code>INVALID_APP_KEY</code></td><td>"InvalidAppKey"</td><td>The Wepin app key is invalid.</td></tr><tr><td><code>INVALID_PARAMETER</code></td><td>"InvalidParameters"</td><td>One or more parameters provided are invalid or missing.</td></tr><tr><td><code>INVALID_LOGIN_PROVIDER</code></td><td>"InvalidLoginProvider"</td><td>The login provider specified is not supported or is invalid.</td></tr><tr><td><code>INVALID_TOKEN</code></td><td>"InvalidToken"</td><td>The token does not exist.</td></tr><tr><td><code>INVALID_LOGIN_SESSION</code></td><td>"InvalidLoginSession"</td><td>The login session information does not exist.</td></tr><tr><td><code>NOT_INITIALIZED_ERROR</code></td><td>"NotInitialized"</td><td>The WepinLoginLibrary has not been properly initialized.</td></tr><tr><td><code>ALREADY_INITIALIZED_ERROR</code></td><td>"AlreadyInitialized"</td><td>The WepinLoginLibrary is already initialized, so the logout operation cannot be performed again.</td></tr><tr><td><code>USER_CANCLED</code></td><td>"UserCancelled"</td><td>The user has cancelled the operation.</td></tr><tr><td><code>UNKNOWN_ERROR</code></td><td>"UnknownError"</td><td>An unknown error has occurred, and the cause is not identified.</td></tr><tr><td><code>NOT_CONNECTED_INTERNET</code></td><td>"NotConnectedInternet"</td><td>The system is unable to detect an active internet connection.</td></tr><tr><td><code>FAILED_LOGIN</code></td><td>"FailedLogin"</td><td>The login attempt has failed due to incorrect credentials or other issues.</td></tr><tr><td><code>ALREADY_LOGOUT</code></td><td>"AlreadyLogout"</td><td>The user is already logged out, so the logout operation cannot be performed again.</td></tr><tr><td><code>INVALID_EMAIL_DOMAIN</code></td><td>"InvalidEmailDomain"</td><td>The provided email address's domain is not allowed or recognized by the system.</td></tr><tr><td><code>FAILED_SEND_EMAIL</code></td><td>"FailedSendEmail"</td><td>The system encountered an error while sending an email. This is because the email address is invalid or we sent verification emails too often. Please change your email or try again after 1 minute.</td></tr><tr><td><code>REQUIRED_EMAIL_VERIFIED</code></td><td>"RequiredEmailVerified"</td><td>Email verification is required to proceed with the requested operation.</td></tr><tr><td><code>INCORRECT_EMAIL_FORM</code></td><td>"incorrectEmailForm"</td><td>The provided email address does not match the expected format.</td></tr><tr><td><code>INCORRECT_PASSWORD_FORM</code></td><td>"IncorrectPasswordForm"</td><td>The provided password does not meet the required format or criteria.</td></tr><tr><td><code>NOT_INITIALIZED_NETWORK</code></td><td>"NotInitializedNetwork"</td><td>The network or connection required for the operation has not been properly initialized.</td></tr><tr><td><code>REQUIRED_SIGNUP_EMAIL</code></td><td>"RequiredSignupEmail"</td><td>The user needs to sign up with an email address to proceed.</td></tr><tr><td><code>FAILED_EMAIL_VERIFIED</code></td><td>"FailedEmailVerified"</td><td>The WepinLoginLibrary encountered an issue while attempting to verify the provided email address.</td></tr><tr><td><code>FAILED_PASSWORD_SETTING</code></td><td>"failedPasswordSetting"</td><td>Failed to set the password. This could be due to issues with the provided password or internal errors during the password setting process.</td></tr><tr><td><code>EXISTED_EMAIL</code></td><td>"ExistedEmail"</td><td>The provided email address is already registered. This error occurs when attempting to sign up with an email that is already in use.</td></tr></tbody></table>


# 핀 패드

RESTful API 사용시, React Native 환경의 서비스에서 사용자의 PIN을 입력 받을 수 있는 UI 및 기능을 제공하는 패키지입니다.


# 설치

Wepin ReactNative PIN Pad SDK를 설치하는 방법을 설명합니다.

## 요구사항 <a href="#requirements" id="requirements"></a>

* **Android**: API 버전 <mark style="color:blue;">**24**</mark>이상
* **iOS**: 버전 <mark style="color:blue;">**13.0**</mark> 이상

{% hint style="info" %}
해당 패키지는  **Android**, **iOS** 환경에서만 사용 가능합니다. **Web**, **MacOS**, **Window**, **Linux** 환경에서는 사용할 수 없습니다.&#x20;
{% endhint %}

{% hint style="info" %}
1.0.0 이전 버전에서 설치한 경우에만 확인해주세요.\
v1.0.0 업데이트에는 저장소 키 변경 등 앱 동작에 영향을 줄 수 있는 중요한 변경사항이 포함되어 있습니다. v1.0.0 이전 버전을 사용 중이었다면, 다음 변경 사항을 반드시 먼저 확인해주세요.
{% endhint %}

{% hint style="warning" %}
New Architecture는 아직 지원되지 않습니다
{% endhint %}

#### 저장소 마이그레이션 안내 (v1.0.0 기준) <a href="#storage-migration-notice-from-v1.0.0" id="storage-migration-notice-from-v1.0.0"></a>

* v1.0.0부터 저장소 키 변경 정책이 적용되어, 기존 저장된 데이터에 접근할 수 없는 경우가 발생할 수 있습니다.
* &#x20;키가 유효하지 않은 경우에 한해, 기존 저장 데이터는 자동으로 초기화되고 새 키가 생성됩니다.
* 키가 정상적으로 유지되는 경우, 기존 데이터는 그대로 유지됩니다.
* v1.0.0 이후 버전에서 이전 버전으로 다운그레이드할 경우, 기존 데이터에 접근하지 못할 수 있습니다.

{% hint style="info" %}
업데이트 전에 잠재적인 문제를 방지하기 위해 데이터를 백업해두는 것을 추천드립니다.
{% endhint %}

#### 백업 비활성화 방법 (Android) <a href="#how-to-disable-backup-android" id="how-to-disable-backup-android"></a>

`AndroidManifest.xml` 파일을 다음과 같이 수정하세요:

```xml
<application
    android:allowBackup="false"
    android:fullBackupContent="false">
```

`android:allowBackup`이 `true`로 설정되어 있으면, 마이그레이션 과정이 정상적으로 동작하지 않아 **데이터 손실** 또는 **저장소 문제**가 발생할 수 있습니다.

## 설치하기 <a href="#installation" id="installation"></a>

npm 패키지로 설치할 수 있습니다.

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

```bash
npm install @wepin/pin-rn
```

{% endtab %}

{% tab title="yarn" %}

```bash
npm install @wepin/pin-rn
```

{% endtab %}
{% endtabs %}

### peerDependencies

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

```bash
npm install react-native-device-info

# for ios
cd ios
pod install
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add react-native-device-info

# for ios
cd ios
pod install
```

{% endtab %}
{% endtabs %}

### 설정하기 <a href="#setting" id="setting"></a>

OAuth 로그인 기능을 활성화하려면 **딥 링크 스킴(Deep Link Scheme)** 을 구성해야 합니다.\
**딥 링크 스킴 형식(Deep Link scheme format) :** `wepin. + Your Wepin App ID`

#### Android

`build.gradle (app)` 파일에서 `manifestPlaceholders`를 추가하여 Wepin PIN Pad SDK가 이 커스텀 스킴을 통한 모든 리디렉션을 쉽게 캡처할 수 있도록 설정합니다.

```
// For Deep Link => RedirectScheme Format : wepin. + Wepin App ID
android.defaultConfig.manifestPlaceholders = [
  'appAuthRedirectScheme': 'wepin.{{YOUR_WEPIN_APPID}}'
]
```

#### iOS

인증 프로세스 후 앱으로 다시 리디렉션하기 위해 앱의 URL 스킴을 `Info.plist` 파일에 추가해야 합니다.&#x20;

```
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>unique name</string>
        <array>
            <string>wepin + your Wepin app id</string>
        </array>
    </dict>
</array>
```

#### iOS Podfile 설정

Xcode 26.0.1 이상 버전 사용 시 빌드 에러가 발생할 수 있습니다.

> error Unable to find module dependency: 'bcrypt' (in tarrget 'WepinLogin' from project 'Pods')

위와 같은 에러가 발생하는 경우 Podfile 에 아래 코드를 추가해주세요.

```
post_install do |installer| 
  installer.pods_project.targets.each do |target| 
    target.build_configurations.each do |config| 
      config.build_settings['SWIFT_ENABLE_EXPLICIT_MODULES'] = 'NO' 
    end 
  end 
end
```


# 초기화하기

Wepin React Native PIN Pad SDK를 초기화하는 방법입니다.

## **Import SDK**

Wepin React Native PIN Pad SDK를 사용하기 위해 먼저 SDK를 가져와야 합니다.&#x20;

다음과 같이 import 문을 추가합니다.

```javascript
import WepinPin from '@wepin/pin-rn';
```

## **WepinPINPadSDK** Instance 생성 <a href="#creating-the-wepinwidgetsdk-instance" id="creating-the-wepinwidgetsdk-instance"></a>

`WepinPin` 인스턴스를 생성하기 전에 위핀 워크스페이스에서 Android/iOS 관련 앱 정보를 등록해야 합니다.

{% content-ref url="/pages/cfg4nwJBI8VfiJpH4EW8" %}
[앱 등록 및 키 발급](/wepin/workspace/app-registration-and-key-issuance)
{% endcontent-ref %}

등록한 앱 정보를 바탕으로 다음과 같이  `WepinPin` 인스턴스를 생성합니다.&#x20;

```javascript
const wepinPin = new WepinPin({
  appId: 'wepinAppId',
  appKey: 'wepinAppKey',
});
```

## init

`Wepin React Native PIN Pad SDK`를 초기화할 때, 필요한 위젯 속성들을 정의할 수 있습니다.

```javascript
await wepinPin.init(attributes);
```

#### **Parameters**

* **attributes** <`IWepinSDKAttributes`> **optional**
  * defaultLanguage: - 핀 패드 화면의 기본 언어 설정, 기본 값은 `'en'` 입니다. 현재 지원하는 언어는 `'ko'`, `'en'` ,`'ja'`입니다.
  * defaultCurrency: 핀 패드 화면의 기본 통화 설정, 기본 값은 `'USD'` 입니다. 현재 지원하는 통화는 `'KRW'`, `'USD'`, `'JPY'` 입니다.

#### **Return value**

* **Promise**<`boolean`>

#### **Example**

```javascript
await wepinPin.init({
  defaultLanguage: 'ko',
  defaultCurrency: 'KRW',
});
```

## isInitialized

`WepinPINPadSDK`가 정상적으로 초기화되었는지 확인할 수 있습니다.

```javascript
wepinPin.isInitialized();
```

#### **Parameters**

* None

#### **Return Value**

* **\<boolean>**\
  초기화가 정상적으로 잘 된 경우 true , 실패한 경우 false 를 반환합니다.

## changeLanguage

핀 패드 화면의 언어를 변경할 수 있습니다.

```javascript
await wepinPin.changeLanguage({ language: 'ko' });
```

#### **Parameters**

* **\<object>**
  * **language** `<String>`\
    핀 패드 화면에  표시될 언어를 지정합니다. 현재 지원하는 언어는 `en`, `ko` , `ja` 세 가지 입니다.


# 메서드

Wepin PIN Pad SDK  초기화 이후 사용할 수 있습니다.

## login

`login` 변수는 다양한 인증 방법을 포함한 위핀 로그인 라이브러리로, 사용자가 여러 방식으로 로그인할 수 있도록 합니다. 이메일 및 비밀번호 로그인, OAuth 프로바이더 로그인, ID Token 또는 Access Token을 사용한 로그인 등을 지원합니다. 각 메서드에 대한 자세한 정보는 공식 라이브러리 문서  [Login Library 가이드](/widget-integration/react-native-sdk/login-library)에서 확인할 수 있습니다.

#### **Available Methods**

* `loginWithOauthProvider`
* `signUpWithEmailAndPassword`
* `loginWithEmailAndPassword`
* `loginWithIdToken`
* `loginWithAccessToken`
* `getRefreshFirebaseToken`
* `loginWepin`
* `getCurrentWepinUser`
* `logout`
* `getSignForLogin`

이 메서드들은 다양한 로그인 시나리오를 지원하며, 필요에 맞는 적절한 방법을 선택할 수 있습니다.

#### **Example**

```javascript
// Login using an OAuth provider
const oauthResult = await wepinPin.login.loginWithOauthProvider({
  provider: 'google',
  clientId: 'your-client-id',
});

// Sign up and log in using email and password
const signUpResult = await wepinPin.login.signUpWithEmailAndPassword(
  'example@example.com',
  'password123'
);

// Log in to Wepin
const wepinLoginResult = await wepinPin.login.loginWepin(signUpResult);

// Get the currently logged-in user
const currentUser = await wepinPin.login.getCurrentWepinUser();

// Logout
await wepinPin.login.logout();
```

## generateRegistrationPINBlock

```javascript
await wepinPin.generateRegistrationPINBlock();
```

사용자의 지갑 생성 및 회원가입을 위해 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.

#### **Parameters**

* None

#### **Return value**

* Promise\<RegistrationPinBlock>
  * `uvd` \<EncUVD> - 암호화된 PIN
    * `b64Data` \<string> - b64SKey의 원본키로 암호화된 데이터
    * `b64SKey` \<string> - b64Data를 생성할때 사용하는 키
    * `seqNum` \<number> **optional** - **P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값
  * `hint` \<EncPinHint>&#x20;
    * `data` \<string> - PIN 힌트를 암호화한 값
    * `length` \<string> - PIN 힌트의 길이
    * `version` \<number> - PIN 힌트의 버전

#### **Example**

```javascript
const pinBlock = await wepinPin.generateRegistrationPINBlock();

// You need to make a Wepin RESTful API request using the received data.
fetch('https://sdk.wepin.io/v1/app/register', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    // Add authentication headers
  },
  body: JSON.stringify({
    // Add other required fields
    UVD: pinBlock.uvd,
    hint: pinBlock.hint,
  }),
});
```

## generateAuthPINBlock

```javascript
await wepinPin.generateAuthPINBlock(count?);
```

사용자 인증에 필요한 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

#### **Parameters**

* `count` \<number> **optional** - 생성하려는 PIN Block의 개수. 기본값은 `1` 입니다.

#### **Return value**

* Promise\<AuthPinBlock>
  * `uvdList` \<EncUVD\[]> - 암호화된 PIN Block의 리스트
    * `b64Data` \<string> - b64SKey의 원본 키로 암호화된 데이터
    * `b64SKey` \<string> - b64Data 를 생성할 때 사용하는 키
    * `seqNum` \<number> **optional** - **P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값. Multi Tx 요청 시, 반드시 받은 PIN Block의 순서대로 사용해야 합니다.(1,2,3...)
  * `otp` \<string> **optional** - 사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

#### **Example**

```javascript
const pinBlock = await wepinPin.generateAuthPINBlock(3);

// Sort seqNum of uvd in ascending order from 1 because you need to write it in order starting from 1
pinBlock.uvdList.sort((a, b) => (a.seqNum ?? 0) - (b.seqNum ?? 0));

const resArray = [];
for (const encUVD of pinBlock.uvdList) {
  const response = await fetch('https://sdk.wepin.io/v1/tx/sign', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      // Add authentication headers
    },
    body: JSON.stringify({
      userId: await getUserId(),
      walletId: await getWalletId(),
      accountId: (await getEthereumAccount()).accountId,
      type: 'msg_sign',
      txData: {
        data: '0x0',
      },
      pin: encUVD,
      otpCode: {
        code: pinBlock.otp,
      },
    }),
  });
  resArray.push(response);
}
```

## generateChangePINBlock

```javascript
await wepinPin.generateChangePINBlock();
```

사용자 PIN 변경을 위해 PIN을 입력 받을 수 있는 핀 패드 화면을 띄우고 입력받은 PIN을 처리하여 PIN Block을 생성합니다.

사용자가 2FA(OTP)를 활성화한 경우에는, OTP 코드를 입력받을 수 있는 화면도 띄우고 처리합니다.

#### **Parameters**

* None

#### **Return value**

* Promise\<ChangePinBlock>
  * `uvd` \<EncUVD>  - 사용자의 암호화된 기존 PIN
    * `b64Data` \<string> - b64SKey의 원본키로 암호화된 데이터
    * `b64SKey` \<string> - b64Data 를 생성할때 사용하는 키
    * `seqNum` \<number> **optional** -**P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값
  * `newUVD` \<EncUVD> - 사용자의 암호화된 새로운 PIN
    * `b64Data` \<string> - b64SKey의 원본 키로 암호화된 데이터
    * `b64SKey` \<string> - b64Data 를 생성할 때 사용하는 키
    * `seqNum` \<number> **optional** - **P**IN Block 사용 시 순서대로 사용되었는지 확인하기 위한 값are used in order
  * `hint` \<EncPinHint>&#x20;
    * `data` \<string> - PIN 힌트를 암호화한 값
    * `length` \<string> - PIN 힌트의 길이
    * `version` \<number> - PIN 힌트의 버전
  * `otp` \<string> **optional** - 사용자가 2FA(OTP) 를 활성화한 경우, 입력받은 OTP 코드

#### **Example**

```javascript
const pinBlock = await wepinPin.generateChangePINBlock();

const response = await fetch('https://sdk.wepin.io/v1/wallet/pin/change', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    // Add authentication headers
  },
  body: JSON.stringify({
    userId: await getUserId(),
    walletId: await getWalletId(),
    UVD: pinBlock.uvd,
    newUVD: pinBlock.newUVD,
    hint: pinBlock.hint,
    otpCode: {
      code: pinBlock.otp,
    },
  }),
});
```

## generateAuthOTPCode

```javascript
await wepinPin.generateAuthOTPCode();
```

사용자로부터 OTP 코드를 입력받을 수 있는 화면을 띄우고 처리합니다.

#### **arameters**

* None

#### **Return value**

* Promise\<AuthOTP>
  * `code` \<string> - 입력받은 OTP 코드

#### **Example**

```javascript
let res = await getWepinSignMessage(pinBlocks.uvdList, pinBlock.otp);
if (res.body[0].message === 'OTP_MISMATCH_WRONG_CODE') {
  const otp = await wepinPin.generateAuthOTPCode();
  res = await getWepinSignMessage(pinBlocks.uvdList, otp.code);
}
```

## finalize

```javascript
await wepinWidget.getStatus();
```

&#x20;Wepin PIN Pad SDK 사용을 종료합니다.

#### **Parameters**

* None

#### **Return value**

* Promise\<void>

#### **Example**

```javascript
await wepinPin.finalize();
```

## WepinError

이 섹션에서는 Wepin SDK 기능을 사용하는 동안 발생할 수 있는 다양한 오류 코드에 대한 설명을 제공합니다.\
각 오류 코드는 특정 문제에 대응하며, 이를 이해하면 디버깅 및 오류 처리를 보다 효과적으로 수행할 수 있습니다.

| Error Code                   | Description                                                                               |
| ---------------------------- | ----------------------------------------------------------------------------------------- |
| `ApiRequestError`            | There was an error while making the API request.                                          |
| `InvalidParameters`          | One or more parameters provided are invalid or missing.                                   |
| `NotInitialized`             | The Wepin SDK has not been properly initialized.                                          |
| `InvalidAppKey`              | The Wepin app key is invalid.                                                             |
| `InvalidLoginProvider`       | The login provider specified is not supported or is invalid.                              |
| `InvalidToken`               | The token does not exist.                                                                 |
| `InvalidLoginSession`        | The login session information does not exist.                                             |
| `UserCancelled`              | The user has cancelled the operation.                                                     |
| `UnknownError`               | An unknown error has occurred, and the cause is not identified.                           |
| `NotConnectedInternet`       | The system is unable to detect an active internet connection.                             |
| `FailedLogin`                | The login attempt has failed due to incorrect credentials or other issues.                |
| `AlreadyLogout`              | The user is already logged out, so the logout operation cannot be performed again.        |
| `AlreadyInitialized`         | The Wepin SDK is already initialized.                                                     |
| `InvalidEmailDomain`         | The provided email address's domain is not allowed or recognized by the system.           |
| `FailedSendEmail`            | The system encountered an error while sending an email.                                   |
| `RequiredEmailVerified`      | Email verification is required to proceed with the requested operation.                   |
| `IncorrectEmailForm`         | The provided email address does not match the expected format.                            |
| `IncorrectPasswordForm`      | The provided password does not meet the required format or criteria.                      |
| `NotInitializedNetwork`      | The network or connection required for the operation has not been properly initialized.   |
| `RequiredSignupEmail`        | The user needs to sign up with an email address to proceed.                               |
| `FailedEmailVerified`        | The Wepin SDK encountered an issue while attempting to verify the provided email address. |
| `FailedPasswordStateSetting` | Failed to set the password state.                                                         |
| `FailedPasswordSetting`      | The Wepin SDK failed to set the password.                                                 |
| `ExistedEmail`               | The provided email address is already registered in Wepin.                                |
| `NotActivity`                | The Context is not an activity.                                                           |


# 위젯

React Native 에서 Wepin Widget SDK를 사용하는 방법에 대한 안내 페이지입니다.


# 설치

Wepin ReactNative Widget SDK를 설치하는 방법을 설명합니다.

## 요구사항 <a href="#requirements" id="requirements"></a>

* **React Native** 버전 0.71.8이상
* **Android**: API 버전 <mark style="color:blue;">**24**</mark>이상
* **iOS**: 버전 <mark style="color:blue;">**13.0**</mark> 이상

{% hint style="info" %}
해당 패키지는  **Android**, **iOS** 환경에서만 사용 가능합니다. **Web**, **MacOS**, **Window**, **Linux** 환경에서는 사용할 수 없습니다.&#x20;
{% endhint %}

{% hint style="warning" %}
New Architecture는 아직 지원되지 않습니다
{% endhint %}

## 설치하기 <a href="#installation" id="installation"></a>

npm 패키지로 설치할 수 있습니다.

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

```bash
npm install @wepin/sdk-rn
```

{% endtab %}

{% tab title="yarn" %}

```bash
npm install @wepin/sdk-rn
```

{% endtab %}
{% endtabs %}

### peerDependencies

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

```bash
npm install react-native-device-info

# for ios
cd ios
pod install
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add react-native-device-info

# for ios
cd ios
pod install
```

{% endtab %}
{% endtabs %}

### 설정하기

OAuth 로그인 기능을 활성화하려면 **딥 링크 스킴(Deep Link Scheme)** 을 구성해야 합니다.\
**딥 링크 스킴 형식(Deep Link scheme format) :** `wepin. + Your Wepin App ID`

#### Android

`build.gradle (app)` 파일에서 `manifestPlaceholders`를 추가하여 Wepin Widget SDK가 이 커스텀 스킴을 통한 모든 리디렉션을 쉽게 캡처할 수 있도록 설정합니다.

```
// For Deep Link => RedirectScheme Format : wepin. + Wepin App ID
android.defaultConfig.manifestPlaceholders = [
  'appAuthRedirectScheme': 'wepin.{{YOUR_WEPIN_APPID}}'
]
```

#### iOS

인증 프로세스 후 앱으로 다시 리디렉션하기 위해 앱의 URL 스킴을 `Info.plist` 파일에 추가해야 합니다.&#x20;

```
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>unique name</string>
        <array>
            <string>wepin + your Wepin app id</string>
        </array>
    </dict>
</array>
```

#### iOS Podfile 설정

Xcode 26.0.1 이상 버전 사용 시 빌드 에러가 발생할 수 있습니다.

> error Unable to find module dependency: 'bcrypt' (in tarrget 'WepinLogin' from project 'Pods')

위와 같은 에러가 발생하는 경우 Podfile 에 아래 코드를 추가해주세요.

```
post_install do |installer| 
  installer.pods_project.targets.each do |target| 
    target.build_configurations.each do |config| 
      config.build_settings['SWIFT_ENABLE_EXPLICIT_MODULES'] = 'NO' 
    end 
  end 
end
```




---

[Next Page](/llms-full.txt/1)

