![](/style/images/good.png)
![](/style/images/bad.png)
Vue.js对接WalletConnect教程
source link: http://blog.hubwiz.com/2022/08/14/vue-walletconnect-integration/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Vue.js对接WalletConnect教程
2022-08-14
| 区块链
在本文中,我们将使用 WalletConnect 将钱包应用链接到我们使用Vue.js开发的去中心化应用。
去中心化应用程序 (DApps) 的主要功能之一是能够连接钱包,这反过来又允许用户与 DApp 上的交易进行交互。它抽象了诸如交换网络、 提供签名者和其他为用户提供身份验证形式的功能等功能。连接钱包还充当网关,允许用户通过 DApp 使用他们的钱包地址作为授权身份在 区块链上进行和读取操作。
WalletConnect是一个免费的开源协议,可以将我们的 DApp 连接到多个钱包,包括MetaMask、Trust Wallet、Rainbow 等。 该协议通过在 DApp 和钱包之间建立连接来抽象这个过程,使它们在整个会话期间保持同步。
![cover.avif](http://blog.hubwiz.com/2022/08/14/vue-walletconnect-integration/cover.avif)
用熟悉的语言学习 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
。
![Vue WalletConnect整合](http://blog.hubwiz.com/2022/08/14/vue-walletconnect-integration/Vue-setup-config.avif)
创建项目后,导航到新的项目文件夹:
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。
![Vue WalletConnect整合](http://blog.hubwiz.com/2022/08/14/vue-walletconnect-integration/Infura-project-.avif)
现在,在 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
功能的断开连接按钮。
![Vue WalletConnect整合](http://blog.hubwiz.com/2022/08/14/vue-walletconnect-integration/Disconnecting-the-user-from-current-session..gif)
如果用户没有连接并且state.status
是false
,我们只显示触发connectUserWallet
功能的连接钱包按钮。
![Vue WalletConnect整合](http://blog.hubwiz.com/2022/08/14/vue-walletconnect-integration/Connecting-wallet.gif)
7、结束语
在本文中,我们介绍了在 Vue DApp 中集成 WalletConnect 的详细步骤。内容涵盖项目配置、界面构建、逻辑编写、状态同步 等环节,以确保我们的应用程序始终与钱包同步。
原文链接:Integrating WalletConnect into Vue.js DApps
汇智网翻译整理,转载请标明出处
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK