From d0acb1115ceab4022b0c5f5d540bd932e3d09137 Mon Sep 17 00:00:00 2001 From: rovast Date: Tue, 11 Jul 2023 17:47:39 +0800 Subject: [PATCH 1/3] Add encrypt and decrypt function Signed-off-by: rovast --- package.json | 1 + pnpm-lock.yaml | 25 ++++++++++++++++--------- src/utils/shared.ts | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 63345d8..0db0cc0 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "animate.css": "^4.1.1", "apexcharts": "^3.37.1", "axios": "^1.2.1", + "crypto-js": "^4.1.1", "daisyui": "^2.50.2", "dayjs": "^1.11.6", "ethers": "^6.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08eb777..94b4163 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,9 @@ dependencies: axios: specifier: ^1.2.1 version: 1.2.1 + crypto-js: + specifier: ^4.1.1 + version: 4.1.1 daisyui: specifier: ^2.50.2 version: 2.50.2(autoprefixer@10.4.13)(postcss@8.4.20) @@ -952,8 +955,8 @@ packages: vue-i18n: optional: true dependencies: - '@intlify/message-compiler': 9.3.0-beta.19 - '@intlify/shared': 9.3.0-beta.19 + '@intlify/message-compiler': 9.3.0-beta.24 + '@intlify/shared': 9.3.0-beta.24 jsonc-eslint-parser: 1.4.1 source-map: 0.6.1 vue-i18n: 9.2.2(vue@3.2.45) @@ -982,20 +985,20 @@ packages: '@intlify/shared': 9.2.2 source-map: 0.6.1 - /@intlify/message-compiler@9.3.0-beta.19: - resolution: {integrity: sha512-5RBn5tMOsWh5FqM65IfEJvfpRS8R0lHEUVNDa2rNc9Y7oGEI7swezlbFqU9Kc5FyHy5Kx2jHtdgFIipDwnIYFQ==} + /@intlify/message-compiler@9.3.0-beta.24: + resolution: {integrity: sha512-prhHATkgp0mpPqoVgiAtLmUc1JMvs8fMH6w53AVEBn+VF87dLhzanfmWY5FoZWORG51ag54gBDBOoM/VFv3m3A==} engines: {node: '>= 16'} dependencies: - '@intlify/shared': 9.3.0-beta.19 - source-map: 0.6.1 + '@intlify/shared': 9.3.0-beta.24 + source-map-js: 1.0.2 dev: true /@intlify/shared@9.2.2: resolution: {integrity: sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==} engines: {node: '>= 14'} - /@intlify/shared@9.3.0-beta.19: - resolution: {integrity: sha512-+lhQggrLvlQ/O5OmIYAc9gadcYXMoaDi0Doef+X/f6TLZFr9PTMjOpBWmpwNNHi026e54jckntUn6GzqDtIN4w==} + /@intlify/shared@9.3.0-beta.24: + resolution: {integrity: sha512-AKxJ8s7eKIQWkNaf4wyyoLRwf4puCuQgjSChlDJm5JBEt6T8HGgnYTJLRXu6LD/JACn3Qwu6hM/XRX1c9yvjmQ==} engines: {node: '>= 16'} dev: true @@ -1015,7 +1018,7 @@ packages: optional: true dependencies: '@intlify/bundle-utils': 3.4.0(vue-i18n@9.2.2) - '@intlify/shared': 9.3.0-beta.19 + '@intlify/shared': 9.3.0-beta.24 '@rollup/pluginutils': 4.2.1 '@vue/compiler-sfc': 3.2.45 debug: 4.3.4 @@ -2294,6 +2297,10 @@ packages: which: 2.0.2 dev: true + /crypto-js@4.1.1: + resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} + dev: false + /css-declaration-sorter@6.3.1(postcss@8.4.20): resolution: {integrity: sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==} engines: {node: ^10 || ^12 || >=14} diff --git a/src/utils/shared.ts b/src/utils/shared.ts index 4629812..4227d19 100644 --- a/src/utils/shared.ts +++ b/src/utils/shared.ts @@ -1,10 +1,12 @@ import type { Event } from "nostr-tools"; +import { generatePrivateKey } from "nostr-tools"; import type { Ref } from "vue"; import { useNostrStore } from "@/store/modules/nostr"; import { useModalStore } from "@/store/modules/modal"; import moment from "moment"; import { getConfig } from "@/config"; import type { EthersError } from "ethers"; +import CryptoJS from "crypto-js"; export function formatTime(timeStr, formatStr = "YYYY/MM/DD HH:mm:ss") { if (!timeStr) { @@ -148,3 +150,17 @@ export function handleEtherError(error: EthersError) { window.alert(error.info?.error?.message || msg(error.code)); } + +export function getNewNostrPrivateKey() { + const id64 = generatePrivateKey(); + + return "0x" + id64; +} + +export function encrypt(text: string, key = "STC") { + return CryptoJS.AES.encrypt(text, key).toString(); +} + +export function decrypt(text: string, key = "STC") { + return CryptoJS.AES.decrypt(text, key).toString(CryptoJS.enc.Utf8); +} From 43b8a791a9a46b608b56855907e73eff1f33011e Mon Sep 17 00:00:00 2001 From: rovast Date: Wed, 12 Jul 2023 11:27:32 +0800 Subject: [PATCH 2/3] Register user with Smart Contract Signed-off-by: rovast --- locales/en.yaml | 4 + locales/zh-CN.yaml | 5 + package.json | 2 +- pnpm-lock.yaml | 51 ++--- src/components/Modal/account.bak.vue | 50 +++++ src/components/Modal/account.vue | 54 +++--- src/utils/contract/user-hub.json | 267 +++++++++++++++++++++++++++ src/utils/contract/user-hub.sol | 58 ++++++ src/utils/contract/user-hub.ts | 11 ++ src/utils/shared.ts | 4 +- 10 files changed, 445 insertions(+), 61 deletions(-) create mode 100644 src/components/Modal/account.bak.vue create mode 100644 src/utils/contract/user-hub.json create mode 100644 src/utils/contract/user-hub.sol create mode 100644 src/utils/contract/user-hub.ts diff --git a/locales/en.yaml b/locales/en.yaml index bda6ca6..947582f 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -192,3 +192,7 @@ wasm: Capabilities: Capabilities "New Actor": New Actor + +user: + "modal title": Join CloudX3 + "modal description": Once you click on "Join CloudX3," the platform will generate user information for you, which will be used for subsequent resource creation and management. diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index 00c2fa1..d482e17 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -192,3 +192,8 @@ wasm: Capabilities: 能力声明 "New Actor": 创建Actor + +user: + "modal title": 加入 CloudX3 + "modal description": 点击加入 CloudX3 后,平台会为你生成用户信息,用于后续的资源创建和管理 + "join now": 现在加入 diff --git a/package.json b/package.json index 0db0cc0..22fa946 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "apexcharts": "^3.37.1", "axios": "^1.2.1", "crypto-js": "^4.1.1", - "daisyui": "^2.50.2", + "daisyui": "^3.2.1", "dayjs": "^1.11.6", "ethers": "^6.1.0", "js-base64": "^3.7.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94b4163..dd7d225 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,8 +20,8 @@ dependencies: specifier: ^4.1.1 version: 4.1.1 daisyui: - specifier: ^2.50.2 - version: 2.50.2(autoprefixer@10.4.13)(postcss@8.4.20) + specifier: ^3.2.1 + version: 3.2.1 dayjs: specifier: ^1.11.6 version: 1.11.7 @@ -1937,6 +1937,7 @@ packages: picocolors: 1.0.0 postcss: 8.4.20 postcss-value-parser: 4.2.0 + dev: true /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} @@ -2030,6 +2031,7 @@ packages: electron-to-chromium: 1.4.284 node-releases: 2.0.7 update-browserslist-db: 1.0.10(browserslist@4.21.4) + dev: true /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -2086,6 +2088,7 @@ packages: /caniuse-lite@1.0.30001439: resolution: {integrity: sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==} + dev: true /carbites@1.0.6: resolution: {integrity: sha512-dS9IQvnrb5VIRvSTNz5Ff+mB9d2MFfi5mojtJi7Rlss79VeF190jr0sZdA7eW0CGHotvHkZaWuM6wgfD9PEFRg==} @@ -2183,6 +2186,7 @@ packages: engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 + dev: true /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} @@ -2190,24 +2194,8 @@ packages: /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - /color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - dev: false - - /color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} - dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 - dev: false - /colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - dev: true /colorette@2.0.19: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} @@ -2452,14 +2440,11 @@ packages: /csstype@2.6.21: resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} - /daisyui@2.50.2(autoprefixer@10.4.13)(postcss@8.4.20): - resolution: {integrity: sha512-CzyTsqdkpP2Zwk5Fl+1pFfL7XewRn/COm4TyKx4DbdITpzADMe01j6YZRG/D0kAOyd7t4rXA3zvkqNc7Ak9ukQ==} - peerDependencies: - autoprefixer: ^10.0.2 - postcss: ^8.1.6 + /daisyui@3.2.1: + resolution: {integrity: sha512-gIqE6wiqoJt9G8+n3R/SwLeUnpNCE2eDhT73rP0yZYVaM7o6zVcakBH3aEW5RGpx3UkonPiLuvcgxRcb2lE8TA==} + engines: {node: '>=16.9.0'} dependencies: - autoprefixer: 10.4.13(postcss@8.4.20) - color: 4.2.3 + colord: 2.9.3 css-selector-tokenizer: 0.8.0 postcss: 8.4.20 postcss-js: 4.0.0(postcss@8.4.20) @@ -2636,6 +2621,7 @@ packages: /electron-to-chromium@1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} + dev: true /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2711,6 +2697,7 @@ packages: /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} + dev: true /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} @@ -3072,6 +3059,7 @@ packages: /fraction.js@4.2.0: resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + dev: true /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} @@ -3555,10 +3543,6 @@ packages: /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - /is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - dev: false - /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -4262,6 +4246,7 @@ packages: /node-releases@2.0.7: resolution: {integrity: sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ==} + dev: true /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -4287,6 +4272,7 @@ packages: /normalize-range@0.1.2: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + dev: true /normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} @@ -5292,12 +5278,6 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true - /simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - dependencies: - is-arrayish: 0.3.2 - dev: false - /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -5877,6 +5857,7 @@ packages: browserslist: 4.21.4 escalade: 3.1.1 picocolors: 1.0.0 + dev: true /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} diff --git a/src/components/Modal/account.bak.vue b/src/components/Modal/account.bak.vue new file mode 100644 index 0000000..c20e5fc --- /dev/null +++ b/src/components/Modal/account.bak.vue @@ -0,0 +1,50 @@ + + diff --git a/src/components/Modal/account.vue b/src/components/Modal/account.vue index c20e5fc..65690c3 100644 --- a/src/components/Modal/account.vue +++ b/src/components/Modal/account.vue @@ -1,22 +1,34 @@ @@ -31,19 +43,17 @@ const handleSubmit = () => { >✕ -

{{ t("common.input private key") }}

-

- -

+

{{ t("user.modal title") }}

+

{{ t("user.modal description") }}

diff --git a/src/utils/contract/user-hub.json b/src/utils/contract/user-hub.json new file mode 100644 index 0000000..73dc41c --- /dev/null +++ b/src/utils/contract/user-hub.json @@ -0,0 +1,267 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "publicKey", + "type": "string" + } + ], + "name": "RegisterSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "granter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "expireTime", + "type": "uint256" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "granter", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "getAllPublicKeys", + "outputs": [ + { + "internalType": "string[]", + "name": "", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "getUserInfo", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "components": [ + { + "internalType": "string", + "name": "publicKey", + "type": "string" + }, + { + "internalType": "string", + "name": "privateKey", + "type": "string" + }, + { + "internalType": "uint256", + "name": "userId", + "type": "uint256" + } + ], + "internalType": "struct UserHub.UserIdentity", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "getUserPublicKey", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "grantee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "expireTime", + "type": "uint256" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "granter", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "publicKey", + "type": "string" + }, + { + "internalType": "string", + "name": "privateKey", + "type": "string" + } + ], + "name": "registerUser", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "granter", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/utils/contract/user-hub.sol b/src/utils/contract/user-hub.sol new file mode 100644 index 0000000..da32484 --- /dev/null +++ b/src/utils/contract/user-hub.sol @@ -0,0 +1,58 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "@openzeppelin/contracts/utils/Counters.sol"; + +import "./utils/AccessControl.sol"; + +contract UserHub is AccessControl { + + event RegisterSuccess(address owner, string publicKey); + + using Counters for Counters.Counter; + Counters.Counter private _userCounter; + + // UserIdentity + struct UserIdentity { + string publicKey; + string privateKey; + uint256 userId; + } + + constructor() { + _userCounter.increment(); + } + + mapping(address => UserIdentity) private userMap; + + string[] private userPublicKeys; + + function registerUser(string memory publicKey, string memory privateKey) external returns (bool) { + require(userMap[msg.sender].userId == 0,"user already exists"); + userMap[msg.sender] = UserIdentity(publicKey, privateKey, _userCounter.current()); + userPublicKeys.push(publicKey); + _userCounter.increment(); + emit RegisterSuccess(msg.sender, publicKey); + return true; + } + + function getAllPublicKeys() external view returns(string[] memory) { + return userPublicKeys; + } + + function getUserInfo(address owner) external view returns(bool, UserIdentity memory) { +// if (msg.sender != owner) { +// require(hasRole()); +// }= + if (userMap[msg.sender].userId == 0) { + return (false,userMap[owner]); + } else { + return (true,userMap[owner]); + } + } + + function getUserPublicKey(address owner) external view returns(string memory) { + return userMap[owner].publicKey; + } + +} diff --git a/src/utils/contract/user-hub.ts b/src/utils/contract/user-hub.ts new file mode 100644 index 0000000..64fe437 --- /dev/null +++ b/src/utils/contract/user-hub.ts @@ -0,0 +1,11 @@ +import { getWritebleContractInstance } from "./web3"; + +// @ts-ignore +import ABI from "./user-hub.json?raw"; +const ADDR = "0x76b77D1b625f5ad1Ed462C02C9a01f9622A60D8A"; + +export async function getUserHubContract() { + const contract = await getWritebleContractInstance(ADDR, ABI); + + return contract; +} diff --git a/src/utils/shared.ts b/src/utils/shared.ts index 4227d19..d880516 100644 --- a/src/utils/shared.ts +++ b/src/utils/shared.ts @@ -152,9 +152,7 @@ export function handleEtherError(error: EthersError) { } export function getNewNostrPrivateKey() { - const id64 = generatePrivateKey(); - - return "0x" + id64; + return generatePrivateKey(); } export function encrypt(text: string, key = "STC") { From 19f412981588c6d90607f363d630123445cd0504 Mon Sep 17 00:00:00 2001 From: rovast Date: Wed, 12 Jul 2023 14:42:36 +0800 Subject: [PATCH 3/3] Use private key from blockchain Signed-off-by: rovast --- locales/en.yaml | 1 + src/main.ts | 8 ++--- src/store/modules/account.ts | 25 ++++++++++---- src/utils/contract/user-hub.json | 57 ++++++++++++++++---------------- src/utils/contract/user-hub.ts | 2 +- src/utils/contract/web3.ts | 6 ++++ src/utils/shared.ts | 1 + 7 files changed, 60 insertions(+), 40 deletions(-) diff --git a/locales/en.yaml b/locales/en.yaml index 947582f..11526a6 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -196,3 +196,4 @@ wasm: user: "modal title": Join CloudX3 "modal description": Once you click on "Join CloudX3," the platform will generate user information for you, which will be used for subsequent resource creation and management. + "join now": Join Now diff --git a/src/main.ts b/src/main.ts index 6308649..b969109 100644 --- a/src/main.ts +++ b/src/main.ts @@ -43,13 +43,13 @@ getServerConfig(app).then(async config => { setupStore(app); app.use(useI18n); - app.mount("#app"); - // init store if needed - useAccountStore().init(); + // get user info from smart contract, for nostr private key + await useAccountStore().init(); - // 尝试预获取 instance + app.mount("#app"); try { + // 尝试预获取 instance await useNostrStore().asyncGetNostrInstance(); } catch (e) { // ignore diff --git a/src/store/modules/account.ts b/src/store/modules/account.ts index 9aa0cc2..a392800 100644 --- a/src/store/modules/account.ts +++ b/src/store/modules/account.ts @@ -2,14 +2,17 @@ import { defineStore } from "pinia"; import { store } from "@/store"; import { accountType } from "./types"; import { getPublicKey } from "nostr-tools"; -import { storageLocal } from "@pureadmin/utils"; +// import { storageLocal } from "@pureadmin/utils"; +import { getUserHubContract } from "@/utils/contract/user-hub"; +import { handleEtherError, decrypt } from "@/utils/shared"; +import { getWalletAddres } from "@/utils/contract/web3"; export const useAccountStore = defineStore({ id: "account-settings", state: (): accountType => ({ name: "", publicKey: "", - privateKey: storageLocal().getItem("sk") || "" + privateKey: "" //storageLocal().getItem("sk") || "" }), getters: { getPublicKey() { @@ -29,9 +32,19 @@ export const useAccountStore = defineStore({ SET_PRIVATEKEY(key: string) { this.privateKey = key; }, - init() { - if (this.privateKey) { - this.savePrivateKey(this.privateKey); + async init(): Promise { + try { + const address = await getWalletAddres(); + const contract = await getUserHubContract(); + const data = await contract.getUserInfo(address); + if (!data[0]) return; + + const { privateKey } = data[1]; + const truePrivateKey = decrypt(privateKey); + this.savePrivateKey(truePrivateKey); + console.log("2") + } catch (e) { + handleEtherError(e); } }, savePrivateKey(sk: string): string { @@ -40,7 +53,7 @@ export const useAccountStore = defineStore({ this.SET_PRIVATEKEY(sk); this.SET_PUBLICKEY(pk); this.SET_NAME(pk.substring(0, 2)); - storageLocal().setItem("sk", sk); + // storageLocal().setItem("sk", sk); return ""; } catch (e) { return e.message; diff --git a/src/utils/contract/user-hub.json b/src/utils/contract/user-hub.json index 73dc41c..b69a447 100644 --- a/src/utils/contract/user-hub.json +++ b/src/utils/contract/user-hub.json @@ -26,12 +26,6 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, { "indexed": true, "internalType": "address", @@ -57,12 +51,6 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, { "indexed": true, "internalType": "address", @@ -155,10 +143,23 @@ { "inputs": [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" + "internalType": "address", + "name": "account", + "type": "address" }, + { + "internalType": "uint256", + "name": "expireTime", + "type": "uint256" + } + ], + "name": "grant", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", "name": "grantee", @@ -177,11 +178,6 @@ }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, { "internalType": "address", "name": "granter", @@ -230,11 +226,6 @@ }, { "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, { "internalType": "address", "name": "granter", @@ -249,10 +240,18 @@ { "inputs": [ { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revoke", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", "name": "account", diff --git a/src/utils/contract/user-hub.ts b/src/utils/contract/user-hub.ts index 64fe437..bd5bfed 100644 --- a/src/utils/contract/user-hub.ts +++ b/src/utils/contract/user-hub.ts @@ -2,7 +2,7 @@ import { getWritebleContractInstance } from "./web3"; // @ts-ignore import ABI from "./user-hub.json?raw"; -const ADDR = "0x76b77D1b625f5ad1Ed462C02C9a01f9622A60D8A"; +const ADDR = "0x5D9D1DC34c46707ebCd4e4473c81Cc5BD69A4c98"; export async function getUserHubContract() { const contract = await getWritebleContractInstance(ADDR, ABI); diff --git a/src/utils/contract/web3.ts b/src/utils/contract/web3.ts index 2d673da..06712ed 100644 --- a/src/utils/contract/web3.ts +++ b/src/utils/contract/web3.ts @@ -37,6 +37,12 @@ export async function getProviderSignerInstance(): Promise { return { provider, signer }; } +export async function getWalletAddres() { + const { signer } = await getProviderSignerInstance(); + + return signer.getAddress(); +} + export async function getReadonlyConractInstance( addr: string, abi: InterfaceAbi diff --git a/src/utils/shared.ts b/src/utils/shared.ts index d880516..20c04af 100644 --- a/src/utils/shared.ts +++ b/src/utils/shared.ts @@ -152,6 +152,7 @@ export function handleEtherError(error: EthersError) { } export function getNewNostrPrivateKey() { + // return "9bb6e52ed32384d06545914c4da1e7122645ddb735691773e6ddde82710edfa3"; return generatePrivateKey(); }