# UI

在 SDK 的基础上，我们也提供了 UI 界面。如果选择通过UI接入，若DApp运营在 Telegram内，则用户可以选择唤起移动端App钱包或者停留在Telegram并唤起欧易 Telegram Mini 钱包。

## 通过npm安装

```
npm install @okxconnect/ui
```

## 初始化
连接钱包之前，需要先创建一个对象，用于后续连接钱包、发送交易等操作。

```
OKXUniversalConnectUI.init(dappMetaData, actionsConfiguration, uiPreferences, language, restoreConnection)
```

**请求参数**

- dappMetaData - object
    - name - string: 应用名称，不会作为唯一表示
    - icon - string: 应用图标的 URL。必须是 PNG、ICO 等格式，不支持 SVG 图标。最好传递指向 180x180px PNG 图标的 url。
    - manifestUrl?: string; (okxconnect/ui 1.6.8版本新增字段,可选)tonconnect-manifest.json文件的路径，传递信息到钱包，如果使用OKX钱包插件连接，为必传字段,否则不展示插件链接方式；
- actionsConfiguration - object
    - modals - ('before' | 'success' | 'error')[] | 'all'  交易过程中的提醒界面展示模式，默认为'before'
    - returnStrategy -string 'none' | `${string}://${string}`; 针对app 钱包，指定当用户签署/拒绝请求时深层链接的返回策略，如果是在tg中，可以配置tg://resolve；
    - tmaReturnUrl -string 'back' | 'none' | `${string}://${string}`; Telegram Mini Wallet 钱包中，用户签署/拒绝请求时深层链接的返回策略，一般配置back,表示签名后关闭钱包，会自动展示出DApp；none 表示签名后不做处理；默认为back；
- uiPreferences -object
    - theme -  Theme 可以是：THEME.DARK, THEME.LIGHT, "SYSTEM"
- language - "en_US" | "ru_RU" | "zh_CN" | "ar_AE" | "cs_CZ" | "de_DE" | "es_ES" | "es_LAT" | "fr_FR" | "id_ID" | "it_IT" | "nl_NL" | "pl_PL" | "pt_BR" | "pt_PT" | "ro_RO" | "tr_TR" | "uk_UA" | "vi_VN";
  , 默认为en_US
- restoreConnection?: boolean - 是否自动回复之前的连接；

**返回值**

- OKXUniversalConnectUI

**示例**

```typescript
import { OKXUniversalConnectUI } from "@okxconnect/ui";
import { OKXTonProvider,TONWallet,OKXConnectError } from "@okxconnect/universal-provider";

const universalUi = await OKXUniversalConnectUI.init({
    dappMetaData: {
      icon: "https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png",
      name: "OKX Connect Demo", 
      manifestUrl:"https://app.ston.fi/tonconnect-manifest.json"
  },
  actionsConfiguration: {
    returnStrategy: 'tg://resolve',
    modals:'all',
    tmaReturnUrl:'back'
  },
  language: "en_US",
  uiPreferences: {
    theme: THEME.LIGHT
  },
});

const okxTonProvider = new OKXTonProvider(universalUi)

var unsubscribe = okxTonProvider.onStatusChange((walletInfo: TONWallet | null) => {
        console.log('Connection status:', walletInfo);
    }, (err: OKXConnectError) => {
        console.log('Connection status:', err);
    }
)

// 切换插件连接钱包会触发该事件；
universalUi.on("accountChanged", (session) => {
    if (session){
        console.log(`accountChanged `, JSON.stringify(session));
    }
});

```

## 连接钱包
连接钱包去获取钱包地址，作为标识符和用于签名交易的必要参数，

`await universalUi.openModal(connectParams: ConnectParams);`

**请求参数**

- connectParams - ConnectParams
    - namespaces - [namespace: string]: ConnectNamespace； 请求连接的可选信息，TON的key为"ton"，如果请求的链中，有任何一个链钱包不支持的话，钱包会拒绝连接；
        - chains: string[]; 链id信息,
        - defaultChain?: string; 默认链
        - params?:ConnectRequestParams TON的连接信息，连接TON时，ton_addr是必须的，ton_proof是可选的；
            - ton_addr:TonAddressItem;
                - name: "ton_addr";
            - ton_proof?:TonProofItem;(可选) 连接时的签名信息
                - name: "ton_proof";
                - payload: string; 签名信息；
        - optionalNamespaces - [namespace: string]: ConnectNamespace; 请求连接的可选信息，TON的key为"ton"，如果对应的链信息钱包不支持，依然可以连接；
            - chains: string[]; 链id信息，
                - rpcMap?: [chainId: string]: string; rpc 信息；
                - defaultChain?: string; 默认链
    - sessionConfig: object
        - redirect: string 连接成功后的跳转参数，如果是Telegram中的Mini App，这里可以设置为Telegram的deeplink: "tg://resolve"

**返回值**

- Promise`<SessionTypes.Struct | undefined>`
    - topic: string; 会话标识；
    - namespaces: `Record<string, Namespace>`; 成功连接的namespace 信息；
        - chains: string[]; 连接的链信息；
        - accounts: string[]; 连接的账户信息；
        - methods: string[]; 当前namespace下，钱包支持的方法；
        - rpcMap?: [chainId: string]: string; rpc 信息；
        - defaultChain?: string; 当前会话的默认链
        - payload?:ConnectUniversalDataReply, "ton_addr"与"ton_proof" 的信息
            - ton_addr?:TonAddressItemReply
                - name: 'ton_addr';
                - address: string; TON address raw (`0:<hex>`)
                - network: "-239"
                - walletStateInit: string; Base64 (not url safe) encoded stateinit cell for the wallet contract
                - publicKey: string; HEX string without 0x
            - ton_proof?:TonProofItemReply; 签名信息
                - name: 'ton_proof';
                - proof: ProofInfo
                    - timestamp: number; 签名操作的 64 位 unix epoch 时间（秒）
                    - domain: ProofDomain
                        - lengthBytes: number; 域名长度
                        - value: string; 域名名称
                    - payload: string; Base64-encoded signature
                    - signature: string; payload from the request
    - sessionConfig?: SessionConfig
        - dappInfo: object DApp 信息；
            - name:string
            - icon:string
        - redirect?:string, 连接成功后的跳转参数；
**示例**

```typescript
var session = await universalUi.openModal({
    namespaces: {
        ton: {
            chains: [
                "ton:-239"
            ],
            defaultChain: "ton:-239",
            params: {
                "ton_addr": {
                    "name": "ton_addr"
                },
                "ton_proof": {
                    "name": "ton_proof",
                    "payload": "Hello ton"
                }
            }
        },
        sessionConfig: {
            redirect: "tg://resolve"
        }
    }
})
```

## 获取账户信息

获取当前连接的 account()

**示例**

```typescript
var account: Account = okxTonProvider.account()
```

## 获取钱包信息

获取当前连接的 wallet()

**示例**

```typescript
var walletInfo: TONWallet = okxTonProvider.wallet()
```

## 判断当前是否连接

获取当前是否有连接钱包 connected()

**示例**

```typescript
var connected: boolean = okxTonProvider.connected()
```

## 监听钱包状态变化

钱包状态有：连接成功、恢复连接成功、断开连接等，都可以用此方法获取状态。

```typescript
onStatusChange(callback：(walletInfo: (TONWallet | null)) => void, errorsHandler?: (err: OKXConnectError) => void): () => void 
```

**请求参数**

- callback - (walletInfo) => void : 钱包状态发生变化时候，该callback 会被调用；
    - walletInfo - object
        - device - object
            - appName - string : 钱包名称
            - platform - string : 钱包的平台，（android,ios）
            - appVersion - string : 钱包版本号
            - maxProtocolVersion - number :
            - features - string[] : 支持的方法，当前版本是 sendTransaction
        - account - Account
            - address - string : TON address raw (`0:<hex>`)
            - chain - "-239"
            - walletStateInit - string : Base64 (not url safe) encoded stateinit cell for the wallet contract
            - publicKey - string : HEX string without 0x
        - connectItems - object
            - name - string : "ton_proof"
            - proof - object
                - timestamp - number : 时间戳
                - domain - object
                    - lengthBytes - number : AppDomain Length
                    - value - string : app domain name (as url part, without encoding)
                - payload - string: Base64-encoded signature
                - signature - string: payload from the request
    - errorsHandler - (err: OKXConnectError) => void : 钱包状态发生变化出现异常的时候，该errorsHandler 会被调用；
        - err - TonConnectError
            - code - number
            - message - string

**返回值**

- () => void : 当不再需要监听更新时，执行该方法以节省资源。

**示例**

```typescript
import { TONWallet,OKXConnectError } from "@okxconnect/universal-provider";

const unsubscribe = okxTonConnect.onStatusChange((walletInfo: TONWallet | null) => {
        console.log('Connection status:', walletInfo);
    }, (err: OKXConnectError) => {
        console.log('Connection status:', err);
    }
)
```

当不再需要监听更新时，调用unsubscribe节省资源。

```typescript
unsubscribe()
```


## 发送交易

向钱包发送消息的方法：

`sendTransaction(transaction): Promise<SendTransactionResponse>`

**请求参数**

- TONSendTransactionRequest - object
    - validUntil - number :unix 时间戳。该时刻之后交易将无效
    - from - string (可选): DApp发送交易的发送者地址，默认为当前连接的钱包地址；
    - messages - object[] : （信息数组）： 1-4 条从钱包合约到其他账户的输出消息。所有消息按顺序发送出去，但
      钱包无法保证消息会按相同顺序被传递和执行。
        - address - string : 消息目的地
        - amount - string : 要发送的数量。
        - stateInit - string (可选) : 以 Base64 编码的原始cell BoC。
        - payload - string (可选): 以 Base64 编码的原始cell BoC。

**返回值**

- Promise - `{boc: string}`: 签名结果

**示例**

```typescript

let transactionRequest = {
    "validUntil": Date.now() / 1000 + 360,
    "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f",
    "messages": [
        {
            "address": "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F",
            "amount": "20000000",
            "stateInit": "base64bocblahblahblah==" //deploy contract
        }, {
            "address": "0:E69F10CC84877ABF539F83F879291E5CA169451BA7BCE91A37A5CED3AB8080D3",
            "amount": "60000000",
            "payload": "base64bocblahblahblah==" //transfer nft to new deployed account 0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F
        }
    ]
}

try {
    const result = await okxTonProvider.sendTransaction(transactionRequest);
} catch (error) {
    if (error instanceof OKXConnectError) {
        switch (error.code) {
            case OKX_CONNECT_ERROR_CODES.USER_REJECTS_ERROR:
                alert('You rejected the transaction.');
                break;
            case OKX_CONNECT_ERROR_CODES.NOT_CONNECTED_ERROR:
                alert('Not connected');
                break;
            default:
                alert('Unknown error happened');
                break;
        }
    } else {
        alert('Unknown error happened');
    }
}
```


## 关闭连接弹窗

**示例**
```typescript
universalUi.closeModal();
```

## 获取当前连接的会话信息

获取当前是否有连接钱包，以及已连接的钱包的相关信息；

**示例**

```typescript
universalUi.session;
```

## 设置ui配置项
支持修改主题，文字语言设置，也可以在初始化的时候添加这些配置；

**示例**

```typescript
universalUi.uiOptions = {
  language: 'zh_CN',
  uiPreferences: {
    theme: THEME.DARK
  }
};
```



## 断开钱包连接

**示例**
```typescript
universalUi.disconnect();
```

## Event事件

[详情同EVM兼容链](https://www.okx.com/zh-hans/web3/build/docs/sdks/app-connect-evm-ui#event%E4%BA%8B%E4%BB%B6)

## 错误码

[详情同EVM兼容链](https://www.okx.com/zh-hans/web3/build/docs/sdks/app-connect-evm-sdk#%E9%94%99%E8%AF%AF%E7%A0%81)