VueJS对接WalletConnect含源码
Posted 新缸中之脑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VueJS对接WalletConnect含源码相关的知识,希望对你有一定的参考价值。
在本文中,我们将使用 WalletConnect 将钱包应用链接到我们使用Vue.js开发的去中心化应用。
去中心化应用程序 (DApps) 的主要功能之一是能够连接钱包,这反过来又允许用户与 DApp 上的交易进行交互。它抽象了诸如交换网络、提供签名者和其他为用户提供身份验证形式的功能等功能。连接钱包还充当网关,允许用户通过 DApp 使用他们的钱包地址作为授权身份在区块链上进行和读取操作。
WalletConnect是一个免费的开源协议,可以将我们的 DApp 连接到多个钱包,包括MetaMask、Trust Wallet、Rainbow 等。该协议通过在 DApp 和钱包之间建立连接来抽象这个过程,使它们在整个会话期间保持同步。
用熟悉的语言学习 Web3.0开发 :Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart
1、Vue.js 应用程序开发
首先,让我们使用 Vue CLI 启动项目。如果你的系统上已经安装了 Vue CLI,可以继续直接创建 Vue 项目。
可以使用以下命令全局安装它:
npm install -g @vue / cli
我们现在可以使用 Vue CLI 来创建我们的项目。使用以下命令创建一个新项目:
vue create vue-wallet-connect
你将需要选择一个预设。选择,然后选择如下所示的选项:Manually select features
。
创建项目后,导航到新的项目文件夹:
cd vue-wallet-connect
我们将在Vue 应用程序中使用Ethers.js在连接钱包时直接与区块链交互:
npm i ethers
在这里,我们将 WalletConnect 库安装到项目中:
npm install --save web3 @walletconnect/web3-provider
接下来,要直接在 Vue 3 中使用 WalletConnect 库,我们需要安装node-polyfill-webpack-plugin:
npm i node-polyfill-webpack-plugin
我们安装这个插件是因为项目使用 webpack v5,其中删除了 polyfill Node
核心模块。因此,需要安装它以访问项目中的这些模块。
现在,打开vue.config.js
文件并将其替换为以下代码块:
const defineConfig = require("@vue/cli-service");
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
module.exports = defineConfig(
transpileDependencies: true,
configureWebpack:
plugins: [new NodePolyfillPlugin()],
optimization:
splitChunks:
chunks: "all",
,
,
,
);
完成后,现在可以启动服务器:
npm run serve
2、构建用户界面
让我们进入 components
文件夹并创建一个名为StatusContainer.vue
的文件, 该组件包含我们的主页。
这个文件包含了欢迎信息、帮助我们连接的Connect Wallet
按钮以及用于断开我们与钱包的连接的Disconnect
按钮。最后,当我们成功连接到钱包时,会显示Connected
按钮:
<template>
<div class="hello">
<h1>Welcome to Your Vue.js Dapp</h1>
<div >
<button class="button">Connected</button>
<button class="disconnect__button">Disconnect</button>
</div>
<button class="button"> Connect Wallet</button>
</div>
</template>
<script>
export default
name: 'StatusContainer'
</script>
完成后,打开App.vue
文件并导入StatusContainer
组件,如下所示:
<template>
<status-container/>
</template>
<script>
import StatusContainer from './components/StatusContainer.vue'
export default
name: 'App',
components:
StatusContainer
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Sora:wght@100&display=swap');
#app
font-family: 'Sora', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
.button
background-color: #1c82ff;
border: none;
color: #ffffff;
font-family: "Sora";
border-radius: 3rem;
padding: 2rem 3rem;
font-weight: 600;
font-size: 2rem;
margin: 1rem 1rem 1rem auto;
width: 40%;
.disconnect__button
background-color: red;
border: none;
color: #ffffff;
font-family: "Sora";
border-radius: 3rem;
padding: 1rem 1.3rem;
font-weight: 600;
font-size: 1rem;
margin: 8rem 1rem 1rem auto;
width: 20%;
</style>
在样式标签中,现在为之前创建的按钮添加样式:.button
和.disconnect
。 此外,我们从 Google Fonts 导入 Sora Custom Font 并在.__buttonfont-family
样式中使用该字体。
3、实例化 WalletConnect
我们将需要一个 RPC 提供程序来实例化 WalletConnect 库。对于此示例,我们将使用Infura。
打开 Infura,创建一个新项目,然后获取项目 ID。
现在,在 src/walletConnect
文件夹下创建一个新文件夹walletConnect
, 在这个文件夹中,让我们创建一个文件provider.js
。在这里,我们导入 WalletConnect
库,并使用我们的 Infura ID 对其进行实例化,然后将其导出以用于其他文件。
src/walletConnect/provider.js
看起来像这样:
import WalletConnectProvider from "@walletconnect/web3-provider";
export const provider = new WalletConnectProvider(
infuraId: process.env.VUE_APP_INFURA_ID,
);
Infura ID 应当设置为环境变量。因此,将以下内容添加到你的.env
文件中:
VUE_APP_INFURA_ID=INFURA__ID
4、创建Composables
在创建接口并成功实例化我们的库之后,下一步是实现功能。为此,我们将使用 Vue composables,因为它允许我们在应用程序的任何组件中使用我们的状态和操作,类似于Pinia和 Vuex。
在src文件夹内,添加src/composables/connect
,在connect
文件夹中,让我们创建一个index.js
文件。
在这里,我们导入reactive
和 watch
,我们将在这个文件中使用它。让我们创建状态对象defaultState
:
import reactive, watch from "vue";
const defaultState =
address: "",
chainId: "",
status: false,
;
const state = defaultState
为了保持状态一致,我们将状态与本地存储中的项目同步。让我们命名这个条目为userState
并将其分配给一个名为STATE_NAME
的变量。这样做是为了避免userState
在多个地方重复时出错:
const STATE_NAME = "userState";
我们使用watch
来监听状态的任何变化,以便及时更新本地存储:
watch(
() => state,
() =>
localStorage.setItem(STATE_NAME, JSON.stringify(state));
,
deep: true
);
接下来,我们创建一个getDefaultState
函数来检查本地存储中的STATE_NAME
项是否存在,并将本地存储项赋给状态。如果本地存储项不存在,它会将defaultState
赋给state
。
现在,我们可以删除const state = defaultState
并使用reactive
来赋值:
const getDefaultState = () =>
if (localStorage.getItem(STATE_NAME) !== null)
return JSON.parse(localStorage.getItem(STATE_NAME));
return defaultState;
;
const state = reactive(getDefaultState());
最后,我们导出状态。我们还添加了一条if语句来检查本地存储项是否不存在。如果没有,它会创建项目并分配state
给本地存储:
export default () =>
if (localStorage.getItem(STATE_NAME) === null)
localStorage.setItem(STATE_NAME, JSON.stringify(state));
return
state,
;
;
现在,我们的状态总是与本地存储同步,确保一致性。
让我们看看src/composables/connect/index.js
:
import reactive, watch from "vue";
const defaultState =
address: "",
chainId: "",
status: false,
;
const STATE_NAME = "userState";
const getDefaultState = () =>
if (localStorage.getItem(STATE_NAME) !== null)
return JSON.parse(localStorage.getItem(STATE_NAME));
return defaultState;
;
const state = reactive(getDefaultState());
watch(
() => state,
() =>
localStorage.setItem(STATE_NAME, JSON.stringify(state));
,
deep: true
);
export default () =>
if (localStorage.getItem(STATE_NAME) === null)
localStorage.setItem(STATE_NAME, JSON.stringify(state));
return
state,
;
;
5、创建Actions
Actions由将在程序中使用的功能组成。我们将创建三个函数:
connectWalletConnect
,这会触发 WalletConnect 与钱包连接autoConnect
,它在 DApp 连接后处理我们 WalletConnect 会话中的一致性,因此当 DApp 连接并且刷新页面后,用户的会话仍然处于活动状态disconnectWallet
,这会断开 DApp 与钱包的连接并结束用户的会话
让我们直接进入代码!
仍在我们的src/composables/connect
文件夹中,创建connectWalletConnect
文件。首先,我们导入index文件等:
import providers from "ethers";
import connect from "./index";
import provider from "../../walletConnect/provider";
const connectWalletConnect = async () =>
try
const state = connect();
// Enable session (triggers QR Code modal)
await provider.enable();
const web3Provider = new providers.Web3Provider(provider);
const signer = await web3Provider.getSigner();
const address = await signer.getAddress();
state.status = true;
state.address = address;
state.chainId = await provider.request( method: "eth_chainId" );
provider.on("disconnect", (code, reason) =>
console.log(code, reason);
console.log("disconnected");
state.status = false;
state.address = "";
localStorage.removeItem("userState");
);
provider.on("accountsChanged", (accounts) =>
if (accounts.length > 0)
state.address = accounts[0];
);
provider.on("chainChanged", (chainId) =>
state.chainId = chainId
);
catch (error)
console.log(error);
;
export default connectWalletConnect;
然后我们用provider
监听三个事件: disconnect、accountsChanged和chainChainged。
- disconnect:一旦用户直接从他们的钱包断开连接就会触发
- accountsChanged:如果用户在其钱包中切换帐户,则会触发。如果account数组的长度大于零,我们将
state.address
设置为数组第一个地址,也就是当前地址 - chainChainged:如果用户切换其链/网络,则会触发。例如,如果从以太坊主网切换到 rinkeby 测试网,我们的应用程序会将
state.chainId
从1更改为4。
然后,我们的catch语句只是将任何错误记录到控制台。
返回到connect
文件夹中的index.js
文件并导入connectWalletConnect
动作。在这里,我们创建一个actions
对象并使用state
导出:
import reactive, watch from "vue";
import connectWalletConnect from "./connectWalletConnect";
const STATE_NAME = "userState";
const defaultState =
address: "",
chainId: "",
status: false,
;
const getDefaultState = () =>
if (localStorage.getItem(STATE_NAME) !== null)
return JSON.parse(localStorage.getItem(STATE_NAME));
return defaultState;
;
const state = reactive(getDefaultState());
const actions =
connectWalletConnect,
;
watch(
() => state,
() =>
localStorage.setItem(STATE_NAME, JSON.stringify(state));
,
deep: true
);
export default () =>
if (localStorage.getItem(STATE_NAME) === null)
localStorage.setItem(STATE_NAME, JSON.stringify(state));
return
state,
...actions,
;
;
6、实现组件逻辑
让我们打开StatusContainer
组件并将composables中的逻辑连接到接口。像往常一样,导入文件并对其进行解构以获取动作和状态:
<script>
import connect from '../composables/connect/index';
export default
name: 'StatusContainer',
setup: () =>
const connectWalletConnect, disconnectWallet, state = connect();
const connectUserWallet = async () =>
await connectWalletConnect();
;
const disconnectUser = async() =>
await disconnectWallet()
return
connectUserWallet,
disconnectUser,
state
</script>
然后返回函数 ( disconnectUser, connectUserWallet) 和state以便在模板中使用:
<template>
<div class="hello">
<h1>Welcome to Your Vue.js Dapp</h1>
<div v-if="state.status">
<button @click="connectUserWallet" class="button">Connected</button>
<h3>Address: state.address</h3>
<h3>ChainId: state.chainId</h3>
<button @click="disconnectUser" class="disconnect__button">Disconnect</button>
</div>
<button v-else @click="connectUserWallet" class="button"> Connect Wallet</button>
</div>
</template>
首先,我们用v-if
来有条件地显示事物,使用state.status
。 如果已连接并且state.status
为真,我们将显示Connected
按钮、用户address
和chainId
。此外,我们将显示一个触发disconnectUser
功能的断开连接按钮。
如果用户没有连接并且state.status
是false
,我们只显示触发connectUserWallet
功能的连接钱包按钮。
7、结束语
在本文中,我们介绍了在 Vue DApp 中集成 WalletConnect 的详细步骤。内容涵盖项目配置、界面构建、逻辑编写、状态同步等环节,以确保我们的应用程序始终与钱包同步。
原文链接:Vue.js对接WalletConnect教程 — 汇智网
以上是关于VueJS对接WalletConnect含源码的主要内容,如果未能解决你的问题,请参考以下文章
在 ReactJS 中集成时出现 WalletConnect 错误 - Uncaught (in promise) TypeError: this.send is not a function
通信基于matlab语音信号仿真含Matlab源码 957期
如何在 Vuejs+Webpack 中包含外部 sass 目录?