TON 链上社保 (TON401K)- 主网部署和Telegram小程序上线

TON401k 教学系列终于来到尾声,这次要做的很简单,我们只需要把已经开发好的智能合约部署到TON 链上,然后再接驳到之前开发好的前端,最后就是开通小程序。这一次的内容会比较繁杂,但都不难,各位也可以到 @ton401k_bot 上感受一下这个链上社保(尽量不要点lockup 锁仓,不然你要提前取回的话就得找我。)

这是TON401K 系列的第六篇文章,以下为其他相关内容

加入继承功能

在开始之前,我们先补回一个之前忘了加入的功能,继承人功能。设计是这样的,用户可以设定一个闲置阈值,一但储蓄钱包超过多少天没有活动是就可以启动继承功能,继承人可以取出钱包内的款项。代码如下:

設定继承人地址和閑置阈值(不可少於一年)

    receive(msg: AssignSuccessor){
        let ctx: Context = context(); // Check sender
        require(sender() == self.owner, "owner wallet owner can withdraw from the account"); 
        require(msg.succeedIfAwayFrom >= 365*24*60*60, "min to wait 1 year"); 
        
        self.successor = msg.successor;
        self.succeedIfAwayFrom = msg.succeedIfAwayFrom;
    }

启动继承程序

    receive("succeed"){
        // this allows successor to withdraw the fund from saving wallet
        let ctx: Context = context(); // Check sender
        require(sender() == self.successor, "owner wallet owner can withdraw from the account"); 
        require((now() - self.lastSavingDate) >= self.succeedIfAwayFrom, "the wallet is still active"); 

        let amount: Int = myBalance();
        self.checkPlanWhenWithdraw();
        self.terminated = true;

        send(SendParameters{
                to: self.successor,
                body: "withdrawal from saving account".asComment(),
                value: amount,
                mode: SendIgnoreErrors | SendRemainingBalance
            }
        );
        
    }

测试部分(移除了一年的限制,把闲置阈值设定为5秒)

 PASS  tests/Ton401kMain.spec.ts (9.476 s)
  Ton401kMain
    ✓ should deploy (350 ms)
    ✓ should create a new TON saving plan with lockup (177 ms)
    ✓ withdraw money from a finished saving plan (195 ms)
    ✓ withdraw money from an unfinished locked saving plan (278 ms)
    ✓ withdraw money from an unfinished flexible saving plan (184 ms)
    ✓ force withdraw initiated by admin and fund back to wallet owner (248 ms)
    ✓ assign successor (211 ms)
    ✓ succeed should be failed (178 ms)
    ✓ succeed should be successful (6214 ms)

部署到主网

测试成功后,我们便可以把合约部署到主网了,直接使用blueprint sdk 中的指令:

npx blueprint build
npx blueprint run

部署合约之后,你便可以看到对应的交易(https://tonscan.org/address/EQCFebsxgeyq2UmRXWVLEErl1dfmLiBWIooPfgXSAtFxZp-p)和地址:EQCFebsxgeyq2UmRXWVLEErl1dfmLiBWIooPfgXSAtFxZp-p 我们之后会用到这个地址和 blueprint build 自动生成的 wrapper 来接驳前端的(build -> Ton401kMain -> tact_Ton401kMain.ts)。

接驳前端

我们的前端是用react 和 typescript 写的,因为这篇文章主要是讨论TON 开发相关的事情,react 的我们就不在这里过于深入去探讨。总的来说,我们的任务是参考前端模版中的 hook : useTonConnect.ts ,用上面提到的wrapper class 去写 useTon401kContract.ts,然后在前端调用hook 来获取链上数据。这个部分你也可以用自己熟悉的方法去做,只是blueprint sdk build 之后有自带的 typescript wrapper,如果能直接使用会更方便。下面是 useTon401kContract.ts 的代码供各位参考:

export function useTon401kContract() {
    const { client } = useTonClient()
    const { wallet, sender } = useTonConnect()


    const CONTRACT_ADDRESS = __CONTRACT_ADDRESS__;

    const ton401kContract = useAsyncInitialize(async () => {
        if (!client || !wallet) return;
        //open a contract from the contract address using the wrapper
        const contract = Ton401kMain.fromAddress(Address.parse(CONTRACT_ADDRESS))

        return client.open(contract) as OpenedContract<HelloCoin>
    }, [client, wallet]);


    const mainStatQuery = useQuery(
        ["getMainStat"],
        async () => {
            if (!ton401kContract) return null;
            const mainStat = await ton401kContract.getMainStat();
            return (mainStat);
        },
        { refetchInterval: 5000 }
    );


    return {
        mainStat: mainStatQuery.data,
        createPlan: (purpose, savingAmt, deadline, lockup, callback) => {
            ton401kContract?.send(sender, { value: toNano("0.05") }, { $$type: "StartTonSavingPlan", purpose: purpose, target: toNano(savingAmt), deadline: deadline, lockup: lockup }).then((result) => {
                console.log(result);
                callback();
            }, (err) => {
                console.log("err: " + err)
            })
        },
        saving: (value, callback) => {
            ton401kContract?.send(sender, { value: toNano(value.toString()) }, "saving").then((result) => {
                callback();
            }, (err) => {
                console.log("err: " + err)
            })
        }
    }
}

接驳完成后可以看到首页已经能读取合约的数据。

部署小程序 Telegram Mini App

Mini App 中需要加入SDK

npm i @twa-dev/sdk

之后在程序中引用就可以了,其实不加也可以运行的,但加了之后就可以通过小程序调用一些telegram 帐户的资料,特别是如果小程序有推荐人机制也必须用到twa sdk

import WebApp from '@twa-dev/sdk';
...
const referer = WebApp.initDataUnsafe.start_param; //一般都是这样获取推荐人id 的 

之后,我们参考官方教学中的 TMA 启动教程,在BotFather(在搜索栏中搜索 @BotFather 或跟随链接 https://t.me/BotFather。)上面创建一个新的机器人,之后在 /mybot 的指命中 设置机器人小程序。

部署完成后就可以看到下面的效果,欢迎大家去体验一下(主网或测试网都有部署)


我是TonPanda,以太坊开发者,也是一名热爱去中心化的小韭菜,现时主要开发Telegram和TON生态应用。欢迎关注我们的 X:https://x.com/ton_org 和 飞机群 @tonchina

Leave a Comment