{"author":{"address":"0x99DD70Cb7d9F8B85EDeE2a454E56478Cd0b0EaEF","user":"https://learnblockchain.cn/people/23775"},"content":{"body":"本文介绍HOH水分子社区Move共学营的task6学习笔记。\r\n\r\n## 1. 使用脚手架快速创建Sui dApp项目\r\n\r\nSui生态为开发者提供了一个名为`@mysten/create-dapp`的脚手架工具，帮助我们快速初始化一个功能完善的dApp项目。以下是使用脚手架的简单步骤：\r\n\r\n### 1.1 安装和创建项目\r\n\r\n运行以下命令启动脚手架工具：\r\n\r\n```bash\r\nnpm create @mysten/dapp\r\n```\r\n\r\n脚手架会通过交互式提示，引导你完成新项目的创建。\r\n\r\n### 1.2 选择模板\r\n\r\n项目创建过程中，你可以选择以下两种模板：\r\n- `react-client-dapp`：一个简单的React模板，包含展示钱包内资产列表的示例功能。\r\n- `react-e2e-counter`：一个更复杂的端到端模板，结合了Move代码和简单的计数器UI。\r\n\r\n### 1.3 脚手架的功能特性\r\n\r\n该脚手架基于Vite TypeScript项目，并预配置了以下功能：\r\n- **React**：构建现代化的用户界面。\r\n- **TypeScript**：为代码提供类型安全。\r\n- **Radix UI**：一组可访问性友好的UI组件。\r\n- **ESLint**：代码风格和质量检查工具。\r\n- **@mysten/dapp-kit**：与Sui网络交互的核心工具包。\r\n\r\n### 1.4 启动开发服务器\r\n\r\n完成项目创建后，进入项目目录并运行以下命令启动本地开发服务器：\r\n\r\n```bash\r\ncd your-dapp-project\r\nnpm install\r\nnpm run dev\r\n```\r\n\r\n随后，通过浏览器访问项目，即可开始你的dApp开发之旅。\r\n\r\n## 2. 集成Sui dApp Kit与Navi SDK\r\n\r\n创建项目后，你可以通过集成`@mysten/dapp-kit`和`navi-sdk`，实现复杂的链上交互功能。以下是具体步骤：\r\n\r\n### 2.1 安装依赖\r\n\r\n在项目根目录运行以下命令安装必要的库：\r\n\r\n```bash\r\nnpm install @mysten/dapp-kit @mysten/sui @tanstack/react-query navi-sdk\r\n```\r\n\r\n### 2.2 配置网络和Providers\r\n\r\n在应用的入口文件（如`App.js`或`App.tsx`）中配置网络连接和Provider组件：\r\n\r\n```move\r\nimport { createNetworkConfig, SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';\r\nimport { getFullnodeUrl } from '@mysten/sui/client';\r\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\r\n\r\nconst { networkConfig } = createNetworkConfig({\r\n    localnet: { url: getFullnodeUrl('localnet') },\r\n    mainnet: { url: getFullnodeUrl('mainnet') },\r\n});\r\nconst queryClient = new QueryClient();\r\n\r\nfunction App() {\r\n    return (\r\n        \u003cQueryClientProvider client={queryClient}\u003e\r\n            \u003cSuiClientProvider networks={networkConfig} defaultNetwork=\"localnet\"\u003e\r\n                \u003cWalletProvider\u003e\r\n                    \u003cYourApp /\u003e\r\n                \u003c/WalletProvider\u003e\r\n            \u003c/SuiClientProvider\u003e\r\n        \u003c/QueryClientProvider\u003e\r\n    );\r\n}\r\n\r\nexport default App;\r\n```\r\n\r\n此配置确保应用能够连接到Sui网络，并提供了钱包和状态管理的支持。\r\n\r\n### 2.3 实现与Navi协议交互的页面\r\n\r\n#### 代码详细解读：NaviPage\r\n\r\n以下逐步解析代码中的每个关键点，详细说明其作用和实现逻辑，并辅以具体代码段。\r\n\r\n1. **导入工具和模块**\r\n\r\n```move\r\nimport { useCurrentAccount, useSignAndExecuteTransaction } from \"@mysten/dapp-kit\";\r\nimport { Transaction } from \"@mysten/sui/transactions\";\r\nimport { depositCoin, borrowCoin } from 'navi-sdk/dist/libs/PTB';\r\nimport { pool, wUSDC } from 'navi-sdk/dist/address';\r\n```\r\n\r\n- `useCurrentAccount`：获取当前连接的钱包账户信息。\r\n- `useSignAndExecuteTransaction`：提供一个签名并执行交易的函数。\r\n- `Transaction`：用于构造复杂的链上交易。\r\n- `depositCoin` 和 `borrowCoin`：Navi SDK 提供的功能，用于存款和借款操作。\r\n- `pool` 和 `wUSDC`：Navi协议中预设的资源池配置和资产信息。\r\n\r\n2. **定义核心组件**\r\n\r\n```move\r\nconst NaviPage = () =\u003e {\r\n    const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction();\r\n    const currentAccount = useCurrentAccount();\r\n```\r\n\r\n- `signAndExecuteTransaction`：通过`useSignAndExecuteTransaction`钩子获取链上交易提交的函数。\r\n- `currentAccount`：使用`useCurrentAccount`获取当前连接的钱包账户。如果未连接钱包，返回`null`。\r\n\r\n3. **检查钱包连接状态**\r\n\r\n```move\r\nif (!currentAccount) {\r\n    alert(\"请先连接钱包\");\r\n    return;\r\n}\r\n```\r\n\r\n确保用户已连接钱包，否则提示用户操作并终止后续逻辑。\r\n\r\n4. **初始化交易对象**\r\n\r\n```move\r\nconst tx = new Transaction();\r\ntx.setSender(currentAccount.address);\r\n```\r\n\r\n- `new Transaction()`：创建一个新的交易对象`tx`。\r\n- `setSender`：指定交易发起方为当前钱包地址`currentAccount.address`。\r\n\r\n5. **分割Gas Coin并存款**\r\n\r\n```move\r\nconst suiPoolConfig = pool['Sui'];\r\nconst splitCoin = tx.splitCoins(tx.gas, [1_000_000_000]);\r\n\r\nawait depositCoin(tx, suiPoolConfig, splitCoin, 1_000_000_000);\r\n```\r\n\r\n- 获取池配置：`pool['Sui']`从Navi协议的资源池中获取针对Sui资产的配置。\r\n- 分割Gas Coin：`splitCoins`将Gas Coin拆分出1 SUI（1,000,000,000 MIST）。\r\n- 存款到池：`depositCoin`将分割出的1 SUI存入指定资源池。\r\n\r\n6. **动态计算借款金额并借出USDC**\r\n\r\n```move\r\nconst currentDate = new Date();\r\nconst borrowAmount = parseFloat(`0.${currentDate.getMonth() + 1}${currentDate.getDate()}${currentDate.getHours()}`);\r\nconst loanPoolConfig = pool[wUSDC.symbol as keyof typeof pool];\r\nconst [borrowedUSDC] = await borrowCoin(tx, loanPoolConfig, borrowAmount * Math.pow(10, wUSDC.decimal));\r\n```\r\n\r\n- 动态计算借款金额：基于当前日期，借款金额为0.MMDDHH。\r\n- 获取USDC池配置：通过`pool[wUSDC.symbol]`获取USDC资产配置。\r\n- 借款操作：调用`borrowCoin`从USDC资源池中借款。\r\n\r\n7. **存回借出的USDC**\r\n\r\n```move\r\nawait depositCoin(tx, loanPoolConfig, borrowedUSDC, borrowAmount * Math.pow(10, wUSDC.decimal));\r\n```\r\n\r\n将步骤6中借出的USDC按相同金额存回资源池。\r\n\r\n8. **提交交易**\r\n\r\n```move\r\nawait signAndExecuteTransaction({ transaction: tx });\r\nalert(\"交易完成！\");\r\n```\r\n\r\n签名并提交交易，完成整个流程。\r\n\r\n9. **组件的UI部分**\r\n\r\n```move\r\nreturn \u003cbutton onClick={handleTransaction}\u003e执行交易\u003c/button\u003e;\r\n```\r\n\r\n定义一个按钮，当用户点击时，执行`handleTransaction`函数。\r\n\r\n#### 完整代码\r\n\r\n```move\r\nimport { useCurrentAccount, useSignAndExecuteTransaction } from \"@mysten/dapp-kit\";\r\nimport { Transaction } from \"@mysten/sui/transactions\";\r\nimport { depositCoin, borrowCoin } from 'navi-sdk/dist/libs/PTB';\r\nimport { pool, wUSDC } from 'navi-sdk/dist/address';\r\n\r\nconst NaviPage = () =\u003e {\r\n    const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction();\r\n    const currentAccount = useCurrentAccount();\r\n\r\n    const handleTransaction = async () =\u003e {\r\n        if (!currentAccount) {\r\n            alert(\"请先连接钱包\");\r\n            return;\r\n        }\r\n\r\n        const tx = new Transaction();\r\n        tx.setSender(currentAccount.address);\r\n\r\n        try {\r\n            // 1. 拆分Gas Coin并存款\r\n            const suiPoolConfig = pool['Sui'];\r\n            const splitCoin = tx.splitCoins(tx.gas, [1_000_000_000]);\r\n            await depositCoin(tx, suiPoolConfig, splitCoin, 1_000_000_000);\r\n\r\n            // 2. 动态计算借款金额并借出USDC\r\n            const currentDate = new Date();\r\n            const borrowAmount = parseFloat(`0.${currentDate.getMonth() + 1}${currentDate.getDate()}${currentDate.getHours()}`);\r\n            const loanPoolConfig = pool[wUSDC.symbol];\r\n            const [borrowedUSDC] = await borrowCoin(tx, loanPoolConfig, borrowAmount * Math.pow(10, wUSDC.decimal));\r\n\r\n            // 3. 存回借款\r\n            await depositCoin(tx, loanPoolConfig, borrowedUSDC, borrowAmount * Math.pow(10, wUSDC.decimal));\r\n\r\n            // 4. 提交交易\r\n            await signAndExecuteTransaction({ transaction: tx });\r\n            alert(\"交易完成！\");\r\n        } catch (error) {\r\n            console.error(\"交易失败:\", error);\r\n            alert(\"交易失败，请检查控制台日志。\");\r\n        }\r\n    };\r\n\r\n    return \u003cbutton onClick={handleTransaction}\u003e执行交易\u003c/button\u003e;\r\n};\r\n\r\nexport default NaviPage;\r\n```\r\n\r\n通过这段代码，你可以实现以下链上操作：\r\n    1.\t分割Gas Coin：分出一部分资金用于操作。\r\n    2.\t存款到资源池：模拟将资产存入某个池子。\r\n    3.\t借款操作：从资源池借出一定金额的 USDC。\r\n    4.\t再存款操作：将借出的 USDC 再存回池子。\r\n    5.\t提交交易：完成整个链上交互流程。\r\n\r\n## 3. 总结\r\n\r\n利用 @mysten/create-dapp 快速创建项目，并结合 @mysten/dapp-kit 和 navi-sdk，你可以轻松打造功能强大的去中心化defi应用。\r\n\r\n为什么推荐这套工具？\r\n\t•\t简单高效：脚手架让你省去繁琐的配置环节。\r\n\t•\t功能丰富：支持钱包连接、网络切换、链上操作等多种功能。\r\n\t•\t高度灵活：适合初学者学习，也适合资深开发者进行复杂场景开发。\r\n\r\n\u003e **请用微信关注《HOH水分子》公众号，我们将持续分享和制作变成语言教程，让大家对编程产生化学反应。**\r\n![HOH_QR.jpg](https://img.learnblockchain.cn/attachments/2024/11/4h04Aovz6738b68758d43.jpg)","title":"（十六）Move语言学习笔记：使用脚手架创建Sui dApp项目与Navi SDK集成"},"history":null,"timestamp":1734008684,"version":1}