walletStore.js 3.8 KB

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