内容概览
接下来一起通过 PTB
和 Navi SDK
实现一个一键存入借出的简单 DApp
。
本节分为两部分:
- 创建一个 DApp 前端项目以及
Sui dApp Kit
的使用; - 了解
Navi SDK
,主要包含的功能以及如何实现存入和借出功能;
最终完成我们的项目。
前端项目部分
创建项目
项目使用 Next.js
框架,创建新项目:npx create-next-app@latest
按提示输入项目名及配置(配置按习惯选择),然后等待安装完成。
添加 Sui dApp Kit 依赖
Sui dApp Kit
是一组 React
组件,可以帮助我们快速构建 dApp
。
首先需要安装它,进入到项目目录,执行命令:
npm i --save @mysten/dapp-kit @mysten/sui @tanstack/react-query
你也可以使用官方提供的 @mysten/dapp cli
命令创建项目。
运行项目:npm run dev
,如何可以打开页面说明已经成功创建工程。
配置项目,编写相关代码
接下来在 src
中新建文件 providers.tsx
和 utils/sui.ts
。
providers.tsx
用来设置使用 sdk
中提供的组件和钩子函数需要的 provider
,内容如下:
'use client';
import { QueryClientProvider } from "@tanstack/react-query";
import React from "react";
import { networkConfig, queryClient } from "./utils/sui";
import { SuiClientProvider, WalletProvider } from "@mysten/dapp-kit";
export default function SuiProviders({ children }: { children: React.ReactNode }) {
return (
<QueryClientProvider client={queryClient}>
<SuiClientProvider networks={networkConfig} defaultNetwork="mainnet">
<WalletProvider>
{children}
</WalletProvider>
</SuiClientProvider>
</QueryClientProvider>
);
}
utils/sui.ts
提供 providers
中需要的对象,内容如下:
import { createNetworkConfig } from "@mysten/dapp-kit";
import { getFullnodeUrl } from "@mysten/sui/client";
import { QueryClient } from "@tanstack/react-query";
const { networkConfig } = createNetworkConfig({
mainnet: {
url: getFullnodeUrl('mainnet'),
}
});
const queryClient = new QueryClient();
export { networkConfig, queryClient };
layout.tsx
中的修改如下:
import SuiProviders from "./providers";
import '@mysten/dapp-kit/dist/index.css'; // 导入 sui dapp kit sdk 样式
...
// 使用 SuiProviders 包裹 children
<SuiProviders>
{children}
</SuiProviders>
page.tsx
就是展示的默认页面,修改内容如下包含:一个标题,一个链接钱包的按钮,一个可以实现存入/借出的按钮,内容如下:
'use client';
import { ConnectButton, } from "@mysten/dapp-kit";
export default function Home() {
function handleClick() {
// todo: 点击显示一个 alert
alert('click button');
}
return (
<div className="container mx-auto p-4">
<div className="flex justify-between">
<p className="text-2xl font-bold">Hello SUI dApp</p>
<ConnectButton />
</div>
<button
onClick={handleClick}
className="mt-4 border border-blue-500 rounded-md p-2 font-bold text-blue-500">
存入/借出/存入
</button>
</div>
);
}
页面效果
此时页面效果如下:
Navi SDK
navi-sdk
提供了与 navi
协议交互的封装,方便存款/借款等功能。
首先安装:npm i --save navi-sdk
。
接下来补充上面按钮的逻辑
导包
import { ConnectButton, useCurrentAccount, useSignAndExecuteTransaction } from "@mysten/dapp-kit";
import { Transaction } from "@mysten/sui/transactions";
import { borrowCoin, depositCoin, nUSDC, Pool, pool, Sui } from "navi-sdk";
import { useState } from "react";
按钮逻辑
// 当前链接的钱包
const currentAddress = useCurrentAccount();
// 执行交易
const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction();
// 交易hash
const [digest, setDigest] = useState('');
// 发生错误时提示信息
const [noticeInfo, setNoticeInfo] = useState('');
const handleClick = async () => {
if (!currentAddress) {
alert("请先连接钱包");
return;
}
// 存入 1 SUI,借出当前日期对应的 USDC,并将 USDC 存入协议中
// 数量
const suiAmount = 1 * 10 ** Sui.decimal;
console.log("suiAmount = ", suiAmount);
const date = new Date();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const usdcAmount = parseInt((parseFloat(`0.${month.toString().padStart(2, '0')}${day.toString().padStart(2, '0')}${hours.toString().padStart(2, '0')}`) * 10 ** nUSDC.decimal).toString());
console.log("usdcAmount = ", usdcAmount);
// 创建交易对象
const tx = new Transaction();
// 分割 sui
const [suiCoin] = tx.splitCoins(tx.gas, [suiAmount]);
console.log(suiCoin);
if (!suiCoin) {
setNoticeInfo("分割 SUI 失败");
return;
}
// 操作池
const suiPool = pool[Sui.symbol as keyof Pool];
const usdcPool = pool[nUSDC.symbol as keyof Pool];
if (!suiPool || !usdcPool) {
setNoticeInfo("pool 配置失败");
return;
}
// 存 sui
await depositCoin(tx, suiPool, suiCoin, suiAmount);
// 借 usdc
const [borrowedCoin] = await borrowCoin(tx, usdcPool, usdcAmount);
// 存 usdc
await depositCoin(tx, usdcPool, borrowedCoin, usdcAmount);
signAndExecuteTransaction(
{
transaction: tx,
},
{
onSuccess: (result) => {
setDigest(result.digest);
setNoticeInfo("交易已发送");
},
onError: (error) => {
setNoticeInfo(error.message);
}
});
}
页面 UI 添加
{noticeInfo && <p>{noticeInfo}</p>}
{digest && <p>交易 hash {digest}</p>}
如果觉得本节内容对你有所帮助,可以点赞鼓励下,更多信息,,https://t.me/+_QibemQqIIg1OTY1。