walletStore.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { defineStore } from "pinia";
  2. import Web3 from "web3";
  3. import CryptoJS from "crypto-js";
  4. import { cloneDeep } from "lodash";
  5. import { sysLogin } from "@/common/login.js";
  6. export const useWalletStore = defineStore("useWalletStore", {
  7. state: () => ({
  8. id: "", // name + @ + account
  9. isAuthenticated: false, // 登录状态
  10. account: null, // 钱包地址
  11. privateKey: null, // 私钥
  12. encryptedKey: localStorage.getItem("encryptedKey") || null, // 加密后的密钥
  13. loading: false, // 加载状态
  14. error: null, // 错误信息
  15. chainId: null, // 链ID
  16. balance: "0", // 账户余额(ETH)
  17. rpcUrl: "", // ACC私有链RPC
  18. username: "", // 用户名
  19. accountName: "", //网络昵称
  20. accountIcon: "", // 网络头像
  21. accountPassword: null, // 密码
  22. accountHint: "", // 提示词
  23. words: "", // 助记词
  24. walletList: [], // 钱包列表
  25. }),
  26. persist: true,
  27. getters: {
  28. getWalletList() {
  29. return this.walletList;
  30. },
  31. },
  32. actions: {
  33. async initWeb3() {
  34. try {
  35. window.$web3 = new Web3(this.rpcUrl);
  36. return window.$web3
  37. } catch (err) {
  38. console.log(err);
  39. this.error = "初始化区块链连接失败";
  40. return null;
  41. }
  42. },
  43. async getBalance() {
  44. if (!this.account || !window.$web3) {
  45. await this.initWeb3()
  46. }
  47. try {
  48. const weiBalance = await window.$web3.eth.getBalance(this.account);
  49. this.balance = await window.$web3.utils.fromWei(weiBalance, "ether");
  50. return this.balance;
  51. } catch (err) {
  52. this.error = "获取余额失败";
  53. return "0";
  54. }
  55. },
  56. async loginWithPrivateKey(isMnemonic = false) {
  57. this.loading = true;
  58. this.error = null;
  59. try {
  60. const web3 = window.$web3 || (await this.initWeb3());
  61. if (!web3) throw new Error("区块链连接失败");
  62. // 助记词路径
  63. if (isMnemonic) {
  64. // 验证助记词格式 (12或24个单词)
  65. if (![12, 24].includes(this.words.length)) {
  66. throw new Error("助记词应为12或24个单词");
  67. }
  68. // 从助记词派生私钥 (使用HD钱包)
  69. const hdwallet = web3.eth.accounts.wallet.create(1, this.words);
  70. this.privateKey = hdwallet[0].privateKey;
  71. }
  72. if (!/^0x[0-9a-fA-F]{64}$/.test(this.privateKey)) {
  73. throw new Error("私钥格式不正确");
  74. }
  75. // 创建账户对象
  76. const account = await web3.eth.accounts.privateKeyToAccount(this.privateKey);
  77. // 验证是否为合约地址
  78. const code = await web3.eth.getCode(account.address);
  79. if (code !== "0x") throw new Error("该地址是合约地址,不支持登录");
  80. this.account = account.address;
  81. this.isAuthenticated = true;
  82. this.chainId = `${await web3.eth.getChainId()}n`;
  83. this.id = `${this.account}@${this.accountName}`
  84. this.addWallet()
  85. await sysLogin(this.account)
  86. return {
  87. address: account.address,
  88. chainId: this.chainId,
  89. balance: this.balance,
  90. };
  91. } catch (err) {
  92. console.log("登录失败");
  93. this.error = err.message || "登录失败";
  94. throw err;
  95. }finally {
  96. this.$persist();
  97. this.loading = false;
  98. }
  99. },
  100. // 添加钱包
  101. addWallet() {
  102. const data = cloneDeep(this.$state)
  103. Reflect.deleteProperty(data, "walletList");
  104. if(this.walletList.length = 0) {
  105. this.walletList.push(data)
  106. return
  107. }
  108. const findIndex = this.walletList.findIndex(item => item.id === this.id);
  109. if(findIndex != -1){
  110. this.walletList[walletList] = data
  111. }else{
  112. this.walletList.push(data)
  113. }
  114. },
  115. // 切换钱包
  116. switchWallet(account) {
  117. },
  118. },
  119. });