# STARKNET

## 安装及初始化

请确保更新OKX App到 6.98.0或以后版本，即可开始接入：将 OKX Connect 集成到您的 DApp 中，可以使用 npm:

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

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

```
OKXUniversalProvider.init({dappMetaData: {name, icon}})
```

**请求参数**

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

**返回值**

- OKXUniversalProvider

**示例**

```typescript
import { OKXUniversalProvider } from "@okxconnect/universal-provider";

const okxUniversalProvider = await OKXUniversalProvider.init({
    dappMetaData: {
        name: "application name",
        icon: "application icon url"
    },
})
```

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

```
okxUniversalProvider.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 okxUniversalProvider.connect({
    namespaces: {
        starknet: {
            chains: [
                "starknet:mainnet", 
            ],
        }
    },
    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()
```