Tronlink集成

介绍

TronLink,类似于 MetaMask,允许 TRON DApp 在浏览器中运行而不必部署TRON Full Node 。 如果用户已经在 Chrome 扩展程序中安装了TronLink,则 TronLink 会将TronWeb 对象注入每个浏览器页面。 这将允许 web DApp 与 TRON 网络交互。
我们通过一个简单的示例来了解它:

📘

注:

本文demo需要依托开发软件或者http server来通过访问方可以运行。以开发软件WebStorm为例,点击浏览器访问demo页面:

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    </head>
    <body>
    <button onclick="gettronweb()">Can you get tronweb from tronlink?</button>
    <script>
        function gettronweb(){
            if(window.tronWeb && window.tronWeb.defaultAddress.base58){
                document.write("Yes, catch it:",window.tronWeb.defaultAddress.base58)
            }
        }
    </script>
    </body>
</html>

当然,TronWeb还有很多函数等待着你去使用。

签名

在完成交易过程当中,TronWeb需要让TronLink来进行签名,这里TronLink重写了签名,签名过程在TronLink中完成,然后把签名后的transaction返还给TronWeb进行广播。我们通过一个示例来了解它:

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    </head>
    <body>
    <script>
        var obj = setInterval(async ()=>{
            if (window.tronWeb && window.tronWeb.defaultAddress.base58) {
                clearInterval(obj)
                var tronweb = window.tronWeb
                var tx = await tronweb.transactionBuilder.sendTrx('TN9RRaXkCFtTXRso2GdTZxSxxwufzxLQPP', 10, 'TTSFjEG3Lu9WkHdp4JrWYhbGP6K1REqnGQ')
                var signedTx = await tronweb.trx.sign(tx)
                var broastTx = await tronweb.trx.sendRawTransaction(signedTx)
                console.log(broastTx)
            }
        }, 10)
    </script>
    </body>
</html>

当执行代码到 tronweb.trx.sign(tx) 时,TronLink会弹出窗口,来确认签名。

至此,相信您已经能够结合TronLink完成TronWeb的函数调用了。

TronLink事件

TronLink目前支持侧链和主链,开发者可以通过在DAPP中监听TronLink发出的message事件来感知到TronLink当前选择的侧链还是主链, 以及当前选择的是哪个账户。我们通过一个示例来了解它:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    window.addEventListener('message', function (e) {
        if (e.data.message && e.data.message.action == "tabReply") {
            console.log("tabReply event", e.data.message)
            if (e.data.message.data.data.node.chain == '_'){
                console.log("tronLink currently selects the main chain")
            }else{
                console.log("tronLink currently selects the side chain")
            }
        }

        if (e.data.message && e.data.message.action == "setAccount") {
            console.log("setAccount event", e.data.message)
            console.log("current address:", e.data.message.data.address)

        }
        if (e.data.message && e.data.message.action == "setNode") {
            console.log("setNode event", e.data.message)
            if (e.data.message.data.node.chain == '_'){
                console.log("tronLink currently selects the main chain")
            }else{
                console.log("tronLink currently selects the side chain")
            }

        }
    })
    var obj = setInterval(async ()=>{
        if (window.tronWeb && window.tronWeb.defaultAddress.base58) {
            clearInterval(obj)
            let tronweb = window.tronWeb

        }
    }, 10)

</script>

</body>
</html>

上面代码涉及3个事件分别是tabReply、setAccount 、setNode,下面是这些事件的触发场景如下:

TronLink初始化完成(页面加载后)

tabReply

TronLink中主链和侧链切换:

setAccount、setNode

TronLink中设置节点

setAccount、setNode

  • DAPP页面加载之前,可以通过判断tabReply事件的data.message.data.data.node.chain字段来判断页面加载时,TronLink选择的是侧链还是主链,如果是'_' 表示的是主链,否则就是侧链,同时chain表示的侧链的编号,每一条侧链的编号是唯一的。

  • DAPP页面加载之后,可以通过判断setNode事件的data.message.data.data.node.chain字段来判断用户在TronLink中手动选择的是侧链还是主链,如果是'_' 表示的是主链,否则就是侧链,同时chain表示的侧链的编号,每一条侧链的编号是唯一的。

当选择 MainChain(主链)的时候,返回的消息事件中的node即是所选择的网络。

当选择 DAppChain 的时候,返回的消息事件中的node即是所选择的网络。

📘

实际上在调用过程中,对于主链和侧链而言,按照方法调用即可,因为SunWeb继承Tronweb

当选择 Shasta 测试网的时候,返回的消息事件中的node即是所选择的网络。

添加资产到TronLink

TronLink的TronWeb的对象提供了API给开发者向TronLink添加Token,使其展示在TronLink资产列表中。

开发者可以在项目中提供按钮给用户, 直接将指定的Token添加到用户TronLink Chrome插件的资产展示列表中。

📘

目前只支持主网和Nile测试网,不支持shasta测试网

我们通过几个示例来了解它:

添加TRC-20资产:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
        var obj = setInterval(async ()=>{
            if (window.tronWeb && window.tronWeb.defaultAddress.base58) {
                clearInterval(obj)
                var tronweb = window.tronWeb
                var tx = await tronweb.request({method: 'wallet_watchAsset',
                                                params:{type: 'trc20',
                                                        options: {address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'},
                                                        },
                                                }
                                               )

            }
        }, 10)
    </script>
</body>
</html>

代码执行时,TronLink会弹出如下窗口,用户来确定添加或者取消添加。

点击”添加”后,此资产显示到了资产列表中,如下图

添加TRC-10资产:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
        var obj = setInterval(async ()=>{
            if (window.tronWeb && window.tronWeb.defaultAddress.base58) {
                clearInterval(obj)
                var tronweb = window.tronWeb
                var tx = await tronweb.request({method: 'wallet_watchAsset',
                                                params:{type: 'trc10',
                                                        options: {address: '1002000'},
                                                        },
                                                }
                                               )

            }
        }, 10)
    </script>
</body>
</html>

代码执行时,TronLink会弹出如下窗口,用户点击确定添加TRC10资产,或者取消添加。

点击”添加”按钮,资产被添加到资产列表,如下图所示。

添加TRC-721资产:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
        var obj = setInterval(async ()=>{
            if (window.tronWeb && window.tronWeb.defaultAddress.base58) {
                clearInterval(obj)
                var tronweb = window.tronWeb
                var tx = await tronweb.request({method: 'wallet_watchAsset',
                                                params:{type: 'trc721',
                                                        options: {address: 'TCzUYnFSwtH2bJkynGB46tWxWjdTQqL1SG'},
                                                        },
                                                }
                                               )

            }
        }, 10)
    </script>
</body>
</html>

执行上述代码后,用户需要确认添加或取消添加。

添加完成后,该资产显示到收藏品列表中

request函数及参数说明:

await tronWeb.request({
    method: 'wallet_watchAsset',
    params: <WatchAssetParams>,
})

TronWeb请求调用TronLink插件的某个方法。

参数说明
request 接收一个参数,该参数是一个object,包含method和params
method: 调用的TronLink插件的方法,目前支持wallet_watchAsset
params: 上面method方法的参数。如下为wallet_watchAsset的参数说明

interface WatchAssetParams {
  type: 'TRC20'; // 支持的token类型(`trc10`, `trc20`, `trc721`) 
  options: {  address: string;   // token的合约地址 或者 token id, 必传
              symbol?: string;   // 占位(目前未使用),可选 
              decimals?: number; // 占位(目前未使用),可选 
              image?: string;    // 占位(目前未使用),可选
           }; 
}