# UI

## 安装及初始化

请确保更新OKX App到 6.98.0版本或以后版本，即可开始接入：

将 OKX Connect 集成到您的 DApp 中，可以使用 npm:

```
npm install @okxconnect/ui
npm install @okxconnect/universal-provider
```

连接钱包之前，需要先创建一个可以提供UI界面的对象，用于后续连接钱包、发送交易等操作。

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

**请求参数**

- dappMetaData - object
    - name - string: 应用名称，不会作为唯一表示
    - icon - string: 应用图标的 URL。必须是 PNG、ICO 等格式，不支持 SVG 图标。最好传递指向 180x180px PNG 图标的 url。
- 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

**返回值**

- OKXUniversalConnectUI

**示例**

```typescript
import { OKXUniversalConnectUI } from "@okxconnect/ui";

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

## 连接钱包

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

```
okxUniversalConnectUI.connect(connectParams: ConnectParams)
```

**请求参数**

- connectParams - ConnectParams
    - namespaces - [namespace: string]: ConnectNamespace ; 请求连接的可选信息， starknet系的key为"starknet"，目前只支持starknet:mainnet，如果请求的链中，有任何一个链钱包不支持的话，钱包会拒绝连接；
        - chains: string[]; 链id信息,
        - defaultChain?: string; 默认链
    - optionalNamespaces - [namespace: string]: ConnectNamespace; 请求连接的可选信息，starknet系的key为"starknet"，目前只支持starknet:mainnet，如果请求的链当前钱包不支持，依然可以连接；
        - chains: string[]; 链id信息,
            - 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下，钱包支持的方法；
        - defaultChain?: string; 当前会话的默认链
    - sessionConfig?: SessionConfig
        - dappInfo: object DApp 信息；
            - name:string
            - icon:string
        - redirect?:string, 连接成功后的跳转参数；
    - connectMethodsReply?:ConnectMethodResponseItem[]; 成功连接后执行方法的结果
        - method: string;  请求的方法名称
        - chainId: string;  执行方法所在的链的ID
        - result?: unknown[]  | Record<string, unknown> | object | string | undefined, 请求方法执行完成的结果
        - error?: RequestError; 请求方法执行失败;
            - code: OKX_CONNECT_ERROR_CODES;
            - message: string;
              **示例**

```typescript
var session = await okxUniversalConnectUI.connect({
    namespaces: {
        starknet: {
            chains: [
                "starknet:mainnet"
            ],
        }
    },
    connectMethods:[
        {
            "chainId": "starknet:mainnet",
            "method": "starknet_signMessage",
            "params":  {
                domain: {
                    chainId: "0x534e5f4d41494e",
                    name: "STRKFarm",
                    version: 1
                },
                message: {
                    document: "app.strkfarm.xyz/tnc/v1",
                    message: "Read and Agree T&C"
                },
                primaryType: "Tnc",
                types: {
                    StarkNetDomain: [
                        {
                            name: "name",
                            type: "felt"
                        },
                        {
                            name: "version",
                            type: "felt"
                        },
                        {
                            name: "chainId",
                            type: "felt"
                        }
                    ],
                    Tnc: [
                        {
                            name: "message",
                            type: "felt"
                        },
                        {
                            name: "document",
                            type: "felt"
                        }
                    ]
                }
            }
        }
    ],
    sessionConfig: {
        redirect: "tg://resolve"
    }
})
```



## 准备交易

首先创建一个OKXStarknetProvider对象，构造函数传入OKXUniversalProvider
```typescript
import { OKXStarknetProvider } from "@okxconnect/universal-provider";
let okxStarknetProvider = new OKXStarknetProvider(okxUniversalProvider)
```

## 获取账户信息

```
okxStarknetProvider.getAccount(chainId)
```

***请求参数***
- chainId: 请求的链，如starknet:mainnet

***返回值***
- Object
    - address: string 钱包地址,
    - pubKey: string 公钥


***示例***
```typescript
let result = okxStarknetProvider.getAccount("starknet:mainnet")
//返回结构
{
    address:"0x0667ae9b1c3d3ab1dacffd8b23269e9fedf2f8de5c57a35fe0a55f209db59179",
    pubKey:"07c26f0fd90a6847d3de5ce7002dcd9454b45a78d5592ee369c4d7561fa5e5ee"
}
```


## 签署消息

```
okxStarknetProvider.signMessage(signerAddress, typedData， chain)
```

***请求参数***

- signerAddress - string, 钱包地址
- typedData - object 需要签名的消息，按照固定格式签名。
- chain? - string, 请求执行方法的链

***返回值***

- Promise - [string, string] 签名结果r,v


***示例***
```ts
let chain = "starknet:mainnet"
let address = okxStarknetProvider.getAccount("starknet:mainnet").address
const signData = {
    "domain": {
        "chainId": "0x534e5f4d41494e",
        "name": "STRKFarm",
        "version": "1"
    },
    "message": {
        "document": "app.strkfarm.xyz/tnc/v1",
        "message": "Read and Agree T&C"
    },
    "primaryType": "Tnc",
    "types": {
        "StarkNetDomain": [
            {
                "name": "name",
                "type": "felt"
            },
            {
                "name": "version",
                "type": "felt"
            },
            {
                "name": "chainId",
                "type": "felt"
            }
        ],
        "Tnc": [
            {
                "name": "message",
                "type": "felt"
            },
            {
                "name": "document",
                "type": "felt"
            }
        ]
    }
}

let result = okxStarknetProvider.signMessage(address, signData,chain)
//返回:0x07fcd65fded07c7daaa79a818a39c5236562914a5d48fa7fad268fac609faa9a,0x0324c3bafc4d0e7e04a3a0b805bf8438f5111e308c4d596daa46fc213b37ebf1
```

## 签署交易并广播上链 sendTransaction

```
okxStarknetProvider.sendTransaction(signerAddress, transaction, chainId?)
```

***请求参数***

- signerAddress - string,钱包地址
- transaction - object，交易信息 按照固定格式签名
- chainId? - string, 请求签名执行的链

***返回值***

- Promise - string 交易hash

***示例***
```ts
 let val = uint256.bnToUint256(120000000000000000)
const transferCalldata = CallData.compile({
    to: "0x00b909cefa36ab6bc26f5887a867e46ef162238f0a171b1c2974b665afd4237f",
    value: val
})

const DAITokenAddress = "0x00da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3"

const invokeParams = {
    calls: [
        {
            contract_address: DAITokenAddress,
            entry_point: "transfer",
            calldata: transferCalldata
        }
    ],
}

let okxStarknetProvider = new OKXStarknetProvider(window.provider)
let address = okxStarknetProvider.getAccount("starknet:mainnet").address
let res = await provider.sendTransaction( this.address, invokeParams, "starknet:mainnet")
//返回值：0x515d9de049c43477cee7eaea987ab04995d8dc2a7b3d7a184dca4bcd7224ec2
```

## 断开钱包连接

断开已连接钱包,并删除当前会话,如果要切换连接钱包,请先断开当前钱包。

```typescript
okxUniversalProvider.disconnect()
```