Skip to content

钱包登录的简易实现

Code
vue
<template>
  <div class="web3-login">
    <button v-if="!account" @click="connectWallet" class="btn">
      连接钱包
    </button>
    <div v-else class="status">
      <p>已连接: {{ shortAddress }}</p>
      <button @click="signMessage" class="btn sign-btn">
        发起签名
      </button>
    </div>
    
    <div v-if="signature" class="result">
      <p>签名结果:</p>
      <p> {{ signature }}</p>
    </div>
    
    <p v-if="error" class="error">{{ error }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

const account = ref('')
const signature = ref('')
const error = ref('')

const shortAddress = computed(() => {
  if (!account.value) return ''
  return `${account.value.slice(0, 6)}...${account.value.slice(-4)}`
})

const connectWallet = async () => {
  error.value = ''
  if (typeof window.ethereum === 'undefined') {
    error.value = '请安装 MetaMask!'
    return
  }

  try {
    const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' })
    account.value = accounts[0]
  } catch (err) {
    error.value = '连接被拒绝或发生错误: ' + err.message
  }
}

const signMessage = async () => {
  if (!account.value) return
  error.value = ''
  signature.value = ''
  
  const originalMessage = `登录验证\n时间戳: ${Date.now()}`
  
  try {
    // 将消息转换为 hex 格式
    const msgParams = originalMessage
    const from = account.value

    // 发起签名请求 (personal_sign)
    const sign = await window.ethereum.request({
      method: 'personal_sign',
      params: [msgParams, from],
    })
    
    signature.value = sign
    console.log('签名成功:', sign)
  } catch (err) {
    error.value = '签名失败: ' + err.message
    console.error(err)
  }
}
</script>