vue(3.2.16) + vite(2.6.4)

dapp连接wallet,这个实例是实现dapp的功能。

依赖包安装:
“@walletconnect/client”: “^2.0.0-beta.23”,
“@walletconnect/legacy-modal”: “^2.0.0-beta.23”,
“@walletconnect/types”: “^2.0.0-beta.23”,
“@walletconnect/utils”: “^2.0.0-beta.23”,

“vue”: “^3.2.16”,

“vite”: “^2.6.4”,

浏览器版本: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36’

简单程序:
import Client from ‘@walletconnect/client’;
const client = await Client.init({
logger: DEFAULT_LOGGER,
relayUrl: ‘xxxxx’
});
console.log('client = ', client);

浏览器错误:

vue-router.js?v=815b4e48:2217 ReferenceError: global is not defined
at @walletconnect_client.js?v=815b4e48:862:7
at node_modules/localStorage/lib/localStorage.js (@walletconnect_client.js?v=815b4e48:867:7)
at __require2 (chunk-SULJOONQ.js?v=815b4e48:48:44)
at node_modules/keyvaluestorage/dist/cjs/browser/index.js (@walletconnect_client.js?v=815b4e48:1002:42)
at __require2 (chunk-SULJOONQ.js?v=815b4e48:48:44)
at @walletconnect_client.js?v=815b4e48:3449:42

浏览器错误,显示空白。

已解决:

刚刚开始仅安装:
“@walletconnect/client”: “^2.0.0-beta.23”,
“@walletconnect/legacy-modal”: “^2.0.0-beta.23”,
“@walletconnect/types”: “^2.0.0-beta.23”,
“@walletconnect/utils”: “^2.0.0-beta.23”,

执行npm run dev错误,中断执行。
然后把几个安装包全安装了:

“@walletconnect/client”: “^2.0.0-beta.23”,
“@walletconnect/legacy-modal”: “^2.0.0-beta.23”,
“@walletconnect/types”: “^2.0.0-beta.23”,
“@walletconnect/utils”: “^2.0.0-beta.23”,
“@walletconnect/web3-provider”: “^1.7.1”,
“ethers”: “^5.6.1”,
“keyvaluestorage”: “^0.7.1”,
“web3”: “^1.7.1”,

然后npm run dev成功了也不知道是安装什么包影响的,页面能打开了,但是抛出global is not defined或Buffer is not defined错误
然后安装@esbuild-plugins/node-globals-polyfill,rollup-plugin-node-polyfills两个依赖包。
配置vite.config.ts还是没有解决问题。检查了原因是两个包在vite.config.ts中配置的位置不对。

在vite.config.ts中正确配置,global is not defined和Buffer is not defined同时解决:

import NodeGlobalsPolyfillPlugin from '@esbuild-plugins/node-globals-polyfill';
import nodePolyfills from 'rollup-plugin-node-polyfills';

    optimizeDeps: {
      esbuildOptions: {
        // Fix global is not defined error
        define: {
          global: 'globalThis'
        },
        plugins: [
          // Without this, npm run dev will output Buffer or process is not defined error
          NodeGlobalsPolyfillPlugin({
            buffer: true
          })
        ]
      }
    },
    build: {
      rollupOptions: {
        plugins: [nodePolyfills()]
      },
      commonjsOptions: {
        transformMixedEsModules: true
      }
    },
    server: {
     	host:略,
     	proxy:略
    },
    plugins: [
     	略
    ],
    resolve: {
      	略
    }

主体功能代码:
index.html

<meta name="description" content="demo for WalletConnect" />

test.vue
relayUrl:wss://relay.walletconnect.com 官网提供测试中继地址,如果调用官网的中继地址,要传入可用的projectID参数,否则无效,projectID官网注册新的
dapp和wallet要绑定同一个中继服务器地址

初始化客户端数据:

import Client, { CLIENT_EVENTS } from '@walletconnect/client';
const DEFAULT_LOGGER = 'debug';
const client = await Client.init({
    logger: DEFAULT_LOGGER,
    // relayUrl: "wss://relay.walletinit.com",
    relayUrl: '自己配置的中继服务器地址,不需要引入proejctID'
  });
  state.client = client;  // state是声明的存储对象,用于存储各种参数
  subscribeToEvents();
const subscribeToEvents = () => {
  if (typeof state.client === 'undefined') {
    return;
  }

  state.client.on(CLIENT_EVENTS.pairing.proposal, async (proposal: any) => {
    // uri 应通过 QR 码扫描或移动深度链接与钱包共享
    const { uri } = proposal.signal.params;
    state.uri = uri; //生成的URI数据就可以复制到wallet中识别配对
    // QRCodeModal.open(uri, () => {
    //   console.log("EVENT", "QR Code Modal closed");
    // });
  });

  state.client.on(CLIENT_EVENTS.pairing.created, async (proposal: any) => {
    console.log('CLIENT_EVENTS.pairing.created', proposal);
    if (typeof state.client === 'undefined') return;
    state.pairings = state.client.pairing.topics;
  });

  state.client.on(CLIENT_EVENTS.session.deleted, (session: any) => {
    console.log('CLIENT_EVENTS.session.deleted');
    if (state.session && session.topic !== state.session.topic) return;
    console.log('EVENT', 'session_deleted');
    // resetApp();
  });
};

点击按钮调用connect方法,执行连接钱包

const connect = async (pairing?: { topic: string }) => {
  try {

    const chains = ['eip155:4']; //设置链ID,可以设置多个
    const methods = [
      'eth_sendTransaction',
      'personal_sign',
      'eth_signTypedData',
      'eth_signTransaction'
    ];
    //methods: web3区块链支持的签名交易函数
    let permissions = {
      blockchain: {
        chains
      },
      jsonrpc: {
        methods
      }
    };
    //metadata可以设置自动获取浏览器参数设置,这里我就写死
    let params = {
      metadata:  {
        "description": "demo for WalletConnect",
        "url": "http://localhost:8080",
        "icons": [
            "http://localhost:8080/favicon.ico"
        ],
        "name": "……管理平台"
    },
      pairing,
      permissions: {
        blockchain: {
          chains
        },
        jsonrpc: {
          methods
        }
      }
    };
 
    const session = await state.client.connect(params);
 	//和钱包配对成功的话,session会返回钱包账户数据,配对失败也返回失败问题
   
  } catch (e) {
  }
};

发现大问题,本地执行功能没有错,打包没有报错,部署上线,页面显示空白。把vite.config.ts中的相关配置NodeGlobalsPolyfillPlugin,nodePolyfills去掉又好了。
浏览器报错:Uncaught ReferenceError: exports is not defined
at vendor.5a73dff7.js:16:17847

补充:
把vite.config.ts中的NodeGlobalsPolyfillPlugin,nodePolyfills的配置删除:

import NodeGlobalsPolyfillPlugin from '@esbuild-plugins/node-globals-polyfill';   删除
import nodePolyfills from 'rollup-plugin-node-polyfills';   删除

optimizeDeps:  删除
build:  删除

在项目下创建polyfills.ts文件

// global is not defined
if (typeof (window as any).global === 'undefined') {
  (window as any).global = window;
}

// buffer is not defined
import { Buffer } from 'buffer';
if (typeof window !== 'undefined') {
  (window as any).Buffer = Buffer;
}

// process is not defined
import process from 'process';
if (typeof window !== 'undefined') {
  (window as any).process = process;
}

main.ts引入

import './polyfills'; 

好了,终于成功了,本地运行可行,打包部署到环境上也可以了.

调用web3实现签名功能:
异常:
在这里插入图片描述

解决:
在这里插入图片描述

import Web3 from 'web3';

const rpc = 'https://mainnet-eth.compound.finance';

  let provider;
  if (rpc.indexOf('http') !== -1) {
    provider = new Web3.providers.HttpProvider(rpc,);
  } else {
    provider = new Web3.providers.WebsocketProvider(rpc);
  }
  const web3 = new Web3(provider);

或者局部调用:

import Web3 from 'web3';
import createAgent from 'agent-base';

const rpc = 'https://mainnet-eth.compound.finance';

  let provider;
  if (rpc.indexOf('http') !== -1) {
    const options: HttpProviderOptions = {
      agent: {
        http: createAgent,
        https: createAgent
      }
    };
    provider = new Web3.providers.HttpProvider(rpc, options);
  } else {
    provider = new Web3.providers.WebsocketProvider(rpc);
  }
  const web3 = new Web3(provider);

总结:不建议用vue3 + vite, 要不然后面还有很多bug待解决,都是坑。最好直接用Vue3 + webpack,问题也少。

Logo

前往低代码交流专区

更多推荐