连接浏览器插件钱包

Provider API#

什么是 Injected provider API?#

欧易 Injected providers API 是一个 JavaScript API,欧易将其注入用户访问的网站。您的 DApp 可以使用此 API 请求用户帐户,从用户连接的区块链读取数据,帮助用户签署消息和交易。

特别说明#

OKX Wallet 的 TON API 完全符合 Ton Connect 协议 的规范。

Dapp 可以使用 TON Connect SDK 来更方便地接入 OKX Wallet 。

获取注入的对象#

OKX Wallet 按照 TON Connect 协议的规范向 Dapp 中注入如下属性:

window.okxTonWallet.tonconnect

其指向的对象的数据结构如下:

interface TonConnectBridge {
    deviceInfo: DeviceInfo;
    walletInfo?: WalletInfo;
    protocolVersion: number;
    connect(protocolVersion: number, message: ConnectRequest): Promise<ConnectEvent>;
    restoreConnection(): Promise<ConnectEvent>;
    send(message: AppRequest): Promise<WalletResponse>;
    listen(callback: (event: WalletEvent) => void): () => void;
}

deviceInfo#

用于获取设备信息,数据结构如下:

{
    platform: 'browser',
    appName: 'OKX Wallet',
    appVersion: '3.3.19',
    maxProtocolVersion: 2,
    features: [
      'SendTransaction',
      {
        name: 'SendTransaction',
        maxMessages: 4,
      },
    ],
}
  • platform:设备平台
  • appName:钱包名称
  • appVersion:钱包版本
  • maxProtocolVersion:支持的最大协议版本
  • features:钱包支持的特性

walletInfo#

用于获取钱包信息,数据结构如下:

{
    name: 'OKX Wallet',
    app_name: 'okxTonWallet',
    image: 'https://static.okx.com/cdn/assets/imgs/247/58E63FEA47A2B7D7.png',
    about_url: 'https://www.okx.com/web3',
    platforms: ['chrome', 'firefox', 'safari'],
}
  • name:钱包名称
  • app_name:钱包应用唯一标识
  • image:钱包图标
  • about_url:钱包介绍页面
  • platforms:钱包支持的平台

protocolVersion#

OKX Wallet 支持的 Ton Connect 的版本,目前为 2 。

connect#

连接钱包的方法,连接钱包时,也可以对钱包进行签名验证。

connect(protocolVersion: number, message: ConnectRequest): Promise<ConnectEvent>;

入参#

  • protocolVersion:Dapp 期望钱包支持的 Ton Connect 的版本,如果钱包暂未支持该版本,会直接返回错误
  • message: 连接钱包的请求信息

message 入参

type ConnectRequest = {
  manifestUrl: string;
  items: ConnectItem[], // 与应用共享的数据项
}

type ConnectItem = TonAddressItem | TonProofItem

type TonAddressItem = {
  name: "ton_addr";
}

type TonProofItem = {
  name: "ton_proof";
  payload: string; // 任意载荷,例如 nonce + 过期时间戳。
}
  • manifestUrl:Dapp 的 manifest.json 文件的 URL,该文件中包含 Dapp 的元信息,数据结构如下:
    {
          "url": "<app-url>",                        // 必填
          "name": "<app-name>",                      // 必填
          "iconUrl": "<app-icon-url>",               // 必填
          "termsOfUseUrl": "<terms-of-use-url>",     // 可选
          "privacyPolicyUrl": "<privacy-policy-url>" // 可选
        }
    
  • items:请求钱包的指令列表,目前支持两个指令:
    • ton_addr:获取用户的地址、公钥等信息
    • ton_proof:对钱包进行签名验证

返回值#

返回一个 Promise 对象,Promise 对象的结果为 ConnectEvent,数据结构如下:

type ConnectEvent = ConnectEventSuccess | ConnectEventError;

type ConnectEventSuccess = {
  event: "connect";
  id: number; // 递增的事件计数器
  payload: {
      items: ConnectItemReply[];
      device: DeviceInfo;
  }
}

type ConnectEventError = {
  event: "connect_error",
  id: number; // 递增的事件计数器
  payload: {
      code: number;
      message: string;
  }
}

// 与 window.okxTonWallet.tonconnect 对象上的 deviceInfo 完全相同
type DeviceInfo = {
  platform: "iphone" | "ipad" | "android" | "windows" | "mac" | "linux";
  appName: string;
  appVersion: string;
  maxProtocolVersion: number;
  features: Feature[];
}

type Feature = { name: 'SendTransaction', maxMessages: number } // `maxMessages` 是钱包支持的一次 `SendTransaction` 中的最大消息数

type ConnectItemReply = TonAddressItemReply | TonProofItemReply;

// 由钱包返回的不受信任的数据。
// 如果您需要保证用户拥有此地址和公钥,您需要额外请求 ton_proof。
type TonAddressItemReply = {
  name: "ton_addr";
  address: string; // TON 地址原始 (`0:<hex>`)
  network: NETWORK; // 网络 global_id
  publicKey: string; // HEX 字符串,不带 0x
  walletStateInit: string; // Base64(不安全 URL)编码的钱包合约的 stateinit cell
}

type TonProofItemReply = {
  name: "ton_proof";
  proof: {
    timestamp: string; // 签名操作的 64 位 unix epoch 时间(秒)
    domain: {
      lengthBytes: number; // AppDomain 长度
      value: string;  // 应用域名(作为 url 部分,无编码)
    };
    signature: string; // base64 编码的签名
    payload: string; // 请求中的载荷
  }
}

// 目前仅支持主网
enum NETWORK {
  MAINNET = '-239',
  TESTNET = '-3'
}

示例#

只是获取用户的地址、公钥等信息:

const result = await window.okxTonWallet.tonconnect.connect(2, {
    manifestUrl: 'https://example.com/manifest.json',
    items: [{ name: 'ton_addr' }]
})

if (result.event === 'connect') {
    console.log(result.payload.items[0].address)
} else {
    console.log(result.payload.message)
}

获取用户地址、公钥等信息,同时对钱包进行签名验证:

const result = await window.okxTonWallet.tonconnect.connect(2, {
    manifestUrl: 'https://example.com/manifest.json',
    items: [
        { name: 'ton_addr' },
        { name: 'ton_proof', payload: '123' }
    ]
})

if(result.event === 'connect') {
    console.log(result.payload.items[0].address)
    console.log(result.payload.items[1].proof)
} else {
    console.log(result.payload.message)
}

restoreConnection#

恢复连接的方法,只会返回 ton_addr 指令的结果,如果无法连接钱包,则返回错误。

restoreConnection(): Promise<ConnectEvent>;

示例#

const result = await window.okxTonWallet.tonconnect.restoreConnection()

if(result.event === 'connect') {
    console.log(result.payload.items[0].address)
} else {
    console.log(result.payload.message)
}

send#

向钱包发送消息的方法:

send(message: AppRequest): Promise<WalletResponse>;

入参#

  • message:发送给钱包的消息体

message 入参

interface AppRequest {
    method: string;
    params: string[];
    id: string;
}
  • method:消息的名称,目前支持 sendTransactiondisconnect
  • params:消息的参数
  • id:递增的标识符,允许匹配请求和响应

sendTransaction 消息#

用于签署并广播交易。

入参:

interface SendTransactionRequest {
    method: 'sendTransaction';
    params: [<transaction-payload>];
    id: string;
}

其中 <transaction-payload> 是具有以下属性的 JSON:

  • valid_until(整数,可选):unix 时间戳。该时刻之后交易将无效。
  • network(NETWORK,可选):目前仅支持主网
  • from(以 wc:hex 格式的字符串,可选)- DApp打算从中发送交易的发送者地址。
  • messages(信息数组):1-4 条从钱包合约到其他账户的输出消息。所有消息按顺序发送出去,但钱包无法保证消息会按相同顺序被传递和执行。

消息结构:

  • address(字符串):消息目的地
  • amount(小数字符串):要发送的纳币数量。
  • payload(base64 编码的字符串,可选):以 Base64 编码的原始cell BoC。
  • stateInit(base64 编码的字符串,可选):以 Base64 编码的原始cell BoC。

示例:

{
  "valid_until": 1658253458,
  "network": "-239",
  "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f",
  "messages": [
    {
      "address": "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F",
      "amount": "20000000",
      "stateInit": "base64bocblahblahblah==" // 部署合约
    },{
      "address": "0:E69F10CC84877ABF539F83F879291E5CA169451BA7BCE91A37A5CED3AB8080D3",
      "amount": "60000000",
      "payload": "base64bocblahblahblah==" // 将 nft 转移至新部署的账户 0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F
    }
  ]
}

返回值:

type SendTransactionResponse = SendTransactionResponseSuccess | SendTransactionResponseError;

interface SendTransactionResponseSuccess {
    result: <boc>;
    id: string;

}

interface SendTransactionResponseError {
   error: { code: number; message: string };
   id: string;
}

其中 result 是签名后的签名串。

disconnect 消息#

用于断开钱包连接。

入参:

interface DisconnectRequest {
    method: 'disconnect';
    params: [];
    id: string;
}

返回值:

type DisconnectResponse = DisconnectResponseSuccess | DisconnectResponseError;

interface DisconnectResponseSuccess {
    result: {};
    id: string;

}

interface DisconnectResponseError {
   error: { code: number; message: string };
   id: string;
}

listen#

监听钱包事件的方法。

listen(callback: (event: WalletEvent) => void): () => void;

入参#

  • callback:事件监听的回调函数
interface WalletEvent {
    event: WalletEventName;
    id: number; // 递增的事件计数器
    payload: <event-payload>; // 每个事件特定的载荷
}

type WalletEventName = 'connect' | 'connect_error' | 'disconnect';

返回值#

返回一个函数,用于取消监听。

on / off#

这是专属于 OKX Wallet 的非标准 API,设计该 API 主要是为了支持 accountChanged 事件,可以让 Dapp 响应插件内的钱包切换

添加/移除事件监听,目前支持的事件有:

  • connect: 钱包已连接的事件
  • disconnect:当用户断开连接时会触发该事件
  • accountChanged:当用户切换账户时会触发该事件
const accountChanged = () => {}
window.okxTonWallet.tonconnect.on('accountChanged', accountChanged)
window.okxTonWallet.tonconnect.off('accountChanged', accountChanged)