link with sdk client and start pairing process
This commit is contained in:
parent
fd209aeb67
commit
335fbb42c9
232
package-lock.json
generated
232
package-lock.json
generated
@ -9,8 +9,10 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"qrcode": "^1.5.3",
|
||||
"vite": "^5.3.3",
|
||||
"vite-plugin-copy": "^0.1.6",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
@ -1276,7 +1278,6 @@
|
||||
"version": "20.14.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
|
||||
"integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
@ -1290,6 +1291,14 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qrcode": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz",
|
||||
"integrity": "sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
|
||||
@ -1794,7 +1803,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@ -2028,6 +2036,14 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001640",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
|
||||
@ -2116,6 +2132,77 @@
|
||||
"node": ">= 10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/cliui/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/cliui/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/clone-deep": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
||||
@ -2358,6 +2445,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/default-browser": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
||||
@ -2452,6 +2547,11 @@
|
||||
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/dijkstrajs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
|
||||
},
|
||||
"node_modules/dns-packet": {
|
||||
"version": "5.6.1",
|
||||
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
|
||||
@ -2589,6 +2689,11 @@
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/encode-utf8": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz",
|
||||
"integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
@ -3011,7 +3116,6 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
@ -3138,6 +3242,14 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
@ -3680,7 +3792,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@ -4025,7 +4136,6 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
@ -4391,7 +4501,6 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
@ -4406,7 +4515,6 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
@ -4435,7 +4543,6 @@
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@ -4477,7 +4584,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@ -4573,6 +4679,14 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.39",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
|
||||
@ -4647,6 +4761,23 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz",
|
||||
"integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
|
||||
"dependencies": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"encode-utf8": "^1.0.3",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"qrcode": "bin/qrcode"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
@ -4790,6 +4921,14 @@
|
||||
"strip-ansi": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-from-string": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
@ -4799,6 +4938,11 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||
},
|
||||
"node_modules/requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
@ -5166,6 +5310,11 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
@ -5420,7 +5569,6 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
@ -5794,8 +5942,7 @@
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"devOptional": true
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/unicorn-magic": {
|
||||
"version": "0.1.0",
|
||||
@ -6381,6 +6528,11 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/which-module": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
|
||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
|
||||
},
|
||||
"node_modules/wildcard": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
|
||||
@ -6535,10 +6687,66 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/yargs/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
"name": "sdk_client",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build_wasm": "wasm-pack build --out-dir ../../dist/pkg ./crates/sp_client --target bundler --dev",
|
||||
"build_wasm": "wasm-pack build --out-dir ../ihm_client/dist/pkg ../sdk_client --target bundler --dev",
|
||||
"start": "vite --host 0.0.0.0",
|
||||
"build": "webpack",
|
||||
"build": "tsc && vite build",
|
||||
"deploy": "sudo cp -r dist/* /var/www/html/"
|
||||
},
|
||||
"keywords": [],
|
||||
@ -24,8 +24,10 @@
|
||||
"webpack-dev-server": "^5.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"qrcode": "^1.5.3",
|
||||
"vite": "^5.3.3",
|
||||
"vite-plugin-copy": "^0.1.6",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
|
@ -36,9 +36,9 @@ body {
|
||||
|
||||
.modal-content {
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
height: 30%;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
@ -48,21 +48,19 @@ body {
|
||||
|
||||
.modal-title {
|
||||
margin: 0;
|
||||
padding-bottom: 20px;
|
||||
padding-bottom: 8px;
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
font-size: 0.9em;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.confirmation-box {
|
||||
margin-top: 20px;
|
||||
align-content: center;
|
||||
width: 40%;
|
||||
width: 70%;
|
||||
height: 20%;
|
||||
padding: 20px;
|
||||
background-color: var(--secondary-color);
|
||||
border-radius: 8px;
|
||||
font-size: 1.2em;
|
||||
font-size: 1.6em;
|
||||
color: #333333;
|
||||
top: 20%;
|
||||
position: relative;
|
||||
@ -106,6 +104,32 @@ body {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.notification-board {
|
||||
position: absolute;
|
||||
width: 20rem;
|
||||
min-height: 8rem;
|
||||
background-color: white;
|
||||
right: 0.5rem;
|
||||
display: none;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
display: none;
|
||||
|
||||
.notification-element {
|
||||
padding: .8rem 0;
|
||||
width: 100%;
|
||||
&:hover {
|
||||
background-color: rgba(26, 28, 24, .08);
|
||||
}
|
||||
}
|
||||
.notification-element:not(:last-child) {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.brand-logo {
|
||||
@ -235,6 +259,12 @@ body {
|
||||
align-items: center;
|
||||
height: 200px;
|
||||
}
|
||||
.camera-card {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
@ -282,7 +312,13 @@ body {
|
||||
padding: 1rem 0;
|
||||
}
|
||||
.process-element {
|
||||
padding: .3rem 0;
|
||||
padding: .4rem 0;
|
||||
&:hover {
|
||||
background-color: rgba(26, 28, 24, .08);
|
||||
}
|
||||
&.selected {
|
||||
background-color: rgba(26, 28, 24, .08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,14 @@
|
||||
<div class="brand-logo">4NK</div>
|
||||
<div class="nav-right-icons">
|
||||
<div class="notification-container">
|
||||
<div class="bell-icon">
|
||||
<div id="notification-bell" class="bell-icon">
|
||||
<svg class="notification-bell" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"/></svg>
|
||||
</div>
|
||||
<div class="notification-badge">1</div>
|
||||
<div class="notification-badge"></div>
|
||||
<div id="notification-board" class="notification-board">
|
||||
<div class="no-notification">No notifications available</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="burger-menu">
|
||||
@ -52,7 +55,7 @@
|
||||
<div class="card-description">
|
||||
Scan your other device :
|
||||
</div>
|
||||
<div class="card-image qr-code">
|
||||
<div class="card-image camera-card">
|
||||
<img src="assets/camera.jpg" alt="QR Code" width="150" height="150">
|
||||
</div>
|
||||
<div class="card-action">
|
||||
|
@ -1,3 +1,5 @@
|
||||
import Services from "/src/services/service.ts";
|
||||
|
||||
document.querySelectorAll('.tab').forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
||||
@ -7,7 +9,11 @@ document.querySelectorAll('.tab').forEach(tab => {
|
||||
document.getElementById(tab.getAttribute('data-tab')).classList.add('active');
|
||||
});
|
||||
});
|
||||
function toggleMenu() {
|
||||
|
||||
document.getElementById('notification-bell').addEventListener('click', openCloseNotifications);
|
||||
|
||||
|
||||
export function toggleMenu() {
|
||||
var menu = document.getElementById('menu');
|
||||
if (menu.style.display === 'block') {
|
||||
menu.style.display = 'none';
|
||||
@ -16,11 +22,13 @@ document.querySelectorAll('.tab').forEach(tab => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// Modal
|
||||
function openModal() {
|
||||
export function openModal() {
|
||||
document.getElementById('modal').style.display = 'flex';
|
||||
}
|
||||
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('modal').style.display = 'none';
|
||||
}
|
||||
@ -31,4 +39,15 @@ document.querySelectorAll('.tab').forEach(tab => {
|
||||
if (event.target === modal) {
|
||||
closeModal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openCloseNotifications() {
|
||||
const notifications = document.querySelector('.notification-board')
|
||||
notifications.style.display = notifications?.style.display === 'none' ? 'block' : 'none'
|
||||
}
|
||||
|
||||
const service = await Services.getInstance()
|
||||
service.setNotification()
|
||||
|
||||
window.toggleMenu = toggleMenu;
|
||||
window.openModal = openModal;
|
@ -34,7 +34,7 @@
|
||||
<div class="card">
|
||||
<div class="card-description">
|
||||
<div class="input-container">
|
||||
<select multiple data-multi-select-plugin id="autocoplete" placeholder="Filter processes..." class="select-field">
|
||||
<select multiple data-multi-select-plugin id="autocomplete" placeholder="Filter processes..." class="select-field">
|
||||
</select>
|
||||
<label for="autocomplete" class="input-label">Filter processes :</label>
|
||||
<div class="selected-processes"></div>
|
||||
|
@ -7,43 +7,6 @@ function toggleMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
// Input for filtering script
|
||||
// var processeList = [
|
||||
// {
|
||||
// id: 1,
|
||||
// name: "Messaging",
|
||||
// description: "Encrypted messages",
|
||||
// zoneList: [
|
||||
// {
|
||||
// id: 1,
|
||||
// name: "General",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: 2,
|
||||
// name: "Storage",
|
||||
// description: "Distributed storage",
|
||||
// zoneList: [
|
||||
// {
|
||||
// id: 1,
|
||||
// name: "Paris",
|
||||
// },
|
||||
// {
|
||||
// id: 2,
|
||||
// name: "Normandy",
|
||||
// },
|
||||
// {
|
||||
// id: 3,
|
||||
// name: "New York",
|
||||
// },
|
||||
// {
|
||||
// id: 4,
|
||||
// name: "Moscow",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ];
|
||||
|
||||
// Initialize function, create initial tokens with itens that are already selected by the user
|
||||
function init(element) {
|
||||
|
@ -6,7 +6,7 @@
|
||||
<meta name="description" content="4NK Web5 Platform">
|
||||
<meta name="keywords" content="4NK web5 bitcoin blockchain decentralize dapps relay contract">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/style/4nk.css">
|
||||
<link rel="stylesheet" href="./style/4nk.css">
|
||||
<title>4NK Application</title>
|
||||
</head>
|
||||
<body>
|
||||
@ -14,5 +14,6 @@
|
||||
<!-- 4NK Web5 Solution -->
|
||||
</div>
|
||||
<script type="module" src="/src/index.ts"></script>
|
||||
<script type="module" src="https://cdn.rawgit.com/davidshimjs/qrcodejs/gh-pages/qrcode.min.js"></script>
|
||||
</body>
|
||||
</html>
|
17
src/index.ts
17
src/index.ts
@ -1,10 +1,21 @@
|
||||
import Services from './services';
|
||||
import { WebSocketClient } from './websockets';
|
||||
import Services from './services/service';
|
||||
// import { WebSocketClient } from './websockets';
|
||||
|
||||
const wsurl = `wss://${window.location.hostname}/ws/`;
|
||||
const wsurl = `wss://${window.location.hostname}:3001/ws/`;
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
try {
|
||||
|
||||
const services = await Services.getInstance();
|
||||
let user = await services.getWallet()
|
||||
console.log("🚀 ~ document.addEventListener ~ user:", user);
|
||||
|
||||
if(!user) {
|
||||
const sp_adress = await services.createNewDevice();
|
||||
user = await services.getWallet()
|
||||
|
||||
console.log("🚀 ~ document.addEventListener ~ sp_adress:", sp_adress)
|
||||
}
|
||||
await services.getAdresses()
|
||||
await services.addWebsocketConnection(wsurl);
|
||||
await services.recoverInjectHtml()
|
||||
} catch (error) {
|
||||
|
22
src/models/notification.model.ts
Normal file
22
src/models/notification.model.ts
Normal file
@ -0,0 +1,22 @@
|
||||
export interface INotification {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
sendToNotificationPage?: boolean;
|
||||
path?: string;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Quelles sont les données utiles pour le user ???
|
||||
export interface IUser {
|
||||
id: string;
|
||||
information?: any
|
||||
}
|
||||
|
||||
|
||||
// Quelles sont les données utiles pour les messages ???
|
||||
export interface IMessage {
|
||||
id: string;
|
||||
message: any
|
||||
}
|
23
src/models/process.model.ts
Normal file
23
src/models/process.model.ts
Normal file
@ -0,0 +1,23 @@
|
||||
export interface IProcess {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
icon?: string;
|
||||
zoneList: IZone[],
|
||||
}
|
||||
|
||||
export interface IZone {
|
||||
id: number;
|
||||
name: string;
|
||||
path: string;
|
||||
// Est-ce que la zone a besoin d'une icone ?
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export interface INotification {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
sendToNotificationPage?: boolean;
|
||||
path?: string;
|
||||
}
|
183
src/services.ts
183
src/services.ts
@ -1,183 +0,0 @@
|
||||
import { WebSocketClient } from './websockets';
|
||||
import homePage from './html/home.html?raw';
|
||||
import homeScript from './html/home.js?raw';
|
||||
import processPage from './html/process.html?raw';
|
||||
import processScript from './html/process.js?raw';
|
||||
|
||||
export default class Services {
|
||||
private static instance: Services;
|
||||
private current_process: string | null = null;
|
||||
private websocketConnection: WebSocketClient[] = [];
|
||||
private sp_address: string | null = null;
|
||||
private processes = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Messaging",
|
||||
description: "Encrypted messages",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "General",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Storage",
|
||||
description: "Distributed storage",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "Paris",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Normandy",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "New York",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Moscow",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
private subscriptions: {element: Element; event: string; eventHandler: string;}[] = [] ;
|
||||
// Private constructor to prevent direct instantiation from outside
|
||||
private constructor() {}
|
||||
|
||||
// Method to access the singleton instance of Services
|
||||
public static async getInstance(): Promise<Services> {
|
||||
if (!Services.instance) {
|
||||
Services.instance = new Services();
|
||||
// await Services.instance.init();
|
||||
}
|
||||
return Services.instance;
|
||||
}
|
||||
|
||||
|
||||
public async addWebsocketConnection(url: string): Promise<void> {
|
||||
const services = await Services.getInstance();
|
||||
const newClient = new WebSocketClient(url, services);
|
||||
if (!services.websocketConnection.includes(newClient)) {
|
||||
services.websocketConnection.push(newClient);
|
||||
}
|
||||
}
|
||||
public async recoverInjectHtml(): Promise<void> {
|
||||
const container = document.getElementById('containerId');
|
||||
|
||||
if (!container) {
|
||||
console.error("No html container");
|
||||
return;
|
||||
}
|
||||
|
||||
const services = await Services.getInstance();
|
||||
container.innerHTML = homePage;
|
||||
|
||||
const newScript = document.createElement('script')
|
||||
newScript.textContent = homeScript;
|
||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||
|
||||
const btn = container.querySelector('#scan-this-device')
|
||||
if(btn) {
|
||||
this.addSubscription(btn, 'click', 'injectProcessListPage')
|
||||
}
|
||||
}
|
||||
private addSubscription(element: Element, event: string, eventHandler: string): void {
|
||||
this.subscriptions.push({ element, event, eventHandler });
|
||||
element.addEventListener(event, (this as any)[eventHandler].bind(this));
|
||||
}
|
||||
|
||||
private cleanSubsciptions(): void {
|
||||
for (const sub of this.subscriptions) {
|
||||
const el = sub.element;
|
||||
const eventHandler = sub.eventHandler;
|
||||
el.removeEventListener(sub.event, (this as any)[eventHandler].bind(this));
|
||||
}
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
async injectProcessListPage(): Promise<void> {
|
||||
const container = document.getElementById('containerId');
|
||||
if (!container) {
|
||||
console.error("No html container");
|
||||
return;
|
||||
}
|
||||
|
||||
this.cleanSubsciptions()
|
||||
|
||||
const services = await Services.getInstance();
|
||||
|
||||
container.innerHTML = processPage;
|
||||
const newScript = document.createElement('script');
|
||||
newScript.textContent = processScript;
|
||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||
|
||||
if(this.processes) {
|
||||
services.setProcessesInSelectElement(this.processes)
|
||||
}
|
||||
}
|
||||
|
||||
public async setProcessesInSelectElement(processList: any[]) {
|
||||
const select = document.querySelector(".select-field");
|
||||
if(select) {
|
||||
for (const process of processList) {
|
||||
const option = document.createElement("option");
|
||||
option.setAttribute("value", process.name);
|
||||
option.innerText = process.name;
|
||||
select.appendChild(option);
|
||||
}
|
||||
}
|
||||
const optionList = document.querySelector('.autocomplete-list');
|
||||
if(optionList) {
|
||||
const observer = new MutationObserver((mutations, observer) => {
|
||||
console.log(mutations, observer);
|
||||
const options = optionList.querySelectorAll('li')
|
||||
if(options) {
|
||||
for(const option of options) {
|
||||
this.addSubscription(option, 'click', 'showSelectedProcess')
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(document, {
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async listenToOptionListPopulating(event: Event) {
|
||||
const target = event.target as HTMLUListElement;
|
||||
const options = target?.querySelectorAll('li')
|
||||
console.log(options)
|
||||
}
|
||||
|
||||
public async showSelectedProcess(event: MouseEvent) {
|
||||
const elem = event.target;
|
||||
if(elem) {
|
||||
|
||||
const cardContent = document.querySelector(".card-content");
|
||||
const processes = this.processes;
|
||||
const process = processes.find((process: any) => process.name === (elem as any).dataset.value);
|
||||
if (process) {
|
||||
const processDiv = document.createElement("div");
|
||||
processDiv.className = "process";
|
||||
processDiv.id = process.name;
|
||||
const titleDiv = document.createElement("div");
|
||||
titleDiv.className = "process-title";
|
||||
titleDiv.innerHTML = `${process.name} : ${process.description}`;
|
||||
processDiv.appendChild(titleDiv);
|
||||
for (const zone of process.zoneList) {
|
||||
const zoneElement = document.createElement("div");
|
||||
zoneElement.className = "process-element";
|
||||
zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`;
|
||||
processDiv.appendChild(zoneElement);
|
||||
}
|
||||
if(cardContent) cardContent.appendChild(processDiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,11 @@ class Database {
|
||||
options: {'keyPath': 'pre_id'},
|
||||
indices: []
|
||||
},
|
||||
AnkSpAddress: {
|
||||
name: "address",
|
||||
options: {'keyPath': 'sp_address'},
|
||||
indices: []
|
||||
},
|
||||
AnkSession: {
|
||||
name: "session",
|
||||
options: {},
|
0
src/services/routing.service.ts
Normal file
0
src/services/routing.service.ts
Normal file
329
src/services/service.ts
Normal file
329
src/services/service.ts
Normal file
@ -0,0 +1,329 @@
|
||||
// import { WebSocketClient } from '../websockets';
|
||||
import { INotification } from '~/models/notification.model';
|
||||
import homePage from '../html/home.html?raw';
|
||||
import homeScript from '../html/home.js?raw';
|
||||
import processPage from '../html/process.html?raw';
|
||||
import processScript from '../html/process.js?raw';
|
||||
import { IProcess } from '~/models/process.model';
|
||||
import Database from './database';
|
||||
import { WebSocketClient } from '../websockets';
|
||||
import QRCode from 'qrcode'
|
||||
|
||||
export default class Services {
|
||||
private static instance: Services;
|
||||
private current_process: string | null = null;
|
||||
private sdkClient: any;
|
||||
// private websocketConnection: WebSocketClient[] = [];
|
||||
private sp_address: string | null = null;
|
||||
private processes: IProcess[] | null = null;
|
||||
private notifications: INotification[] | null = null;
|
||||
private subscriptions: {element: Element; event: string; eventHandler: string;}[] = [] ;
|
||||
private database: any
|
||||
// Private constructor to prevent direct instantiation from outside
|
||||
private constructor() {}
|
||||
|
||||
// Method to access the singleton instance of Services
|
||||
public static async getInstance(): Promise<Services> {
|
||||
if (!Services.instance) {
|
||||
Services.instance = new Services();
|
||||
await Services.instance.init();
|
||||
}
|
||||
return Services.instance;
|
||||
}
|
||||
|
||||
public async init(): Promise<void> {
|
||||
this.notifications = this.getNotifications();
|
||||
this.sdkClient = await import("../../dist/pkg/sdk_client");
|
||||
this.database = Database.getInstance()
|
||||
}
|
||||
|
||||
|
||||
public async addWebsocketConnection(url: string): Promise<void> {
|
||||
const services = await Services.getInstance();
|
||||
const newClient = new WebSocketClient(url, services);
|
||||
// if (!services.websocketConnection.includes(newClient)) {
|
||||
// services.websocketConnection.push(newClient);
|
||||
// }
|
||||
}
|
||||
public async recoverInjectHtml(): Promise<void> {
|
||||
const container = document.getElementById('containerId');
|
||||
|
||||
if (!container) {
|
||||
console.error("No html container");
|
||||
return;
|
||||
}
|
||||
|
||||
const services = await Services.getInstance();
|
||||
container.innerHTML = homePage;
|
||||
|
||||
const newScript = document.createElement('script')
|
||||
newScript.setAttribute('type', 'module')
|
||||
newScript.textContent = homeScript;
|
||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||
|
||||
const btn = container.querySelector('#scan-this-device')
|
||||
if(btn) {
|
||||
this.addSubscription(btn, 'click', 'injectProcessListPage')
|
||||
}
|
||||
|
||||
this.generateQRCode(this.sp_address || '')
|
||||
}
|
||||
|
||||
private generateQRCode = async (text: string) => {
|
||||
try {
|
||||
const container = document.getElementById('containerId');
|
||||
const url = await QRCode.toDataURL(text);
|
||||
const qrCode = container?.querySelector('.qr-code img');
|
||||
qrCode?.setAttribute('src', url)
|
||||
console.log(url);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
private addSubscription(element: Element, event: string, eventHandler: string): void {
|
||||
this.subscriptions.push({ element, event, eventHandler });
|
||||
element.addEventListener(event, (this as any)[eventHandler].bind(this));
|
||||
}
|
||||
|
||||
async getWallet(): Promise<any> {
|
||||
const database = await Database.getInstance();
|
||||
const indexedDb = await database.getDb();
|
||||
const wallet = await database.getAll(indexedDb, database.getStoreList().AnkSpAddress)
|
||||
console.log("🚀 ~ Services ~ getWallet ~ wallet:", wallet)
|
||||
if(wallet.length) return wallet;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async createNewDevice() {
|
||||
const service = await Services.getInstance();
|
||||
const device = await service.sdkClient.create_new_device(1994, 'regtest')
|
||||
const adresses = await service.sdkClient.get_address()
|
||||
console.log("🚀 ~ Services ~ createNewDevice ~ adresses:", adresses)
|
||||
if(device) {
|
||||
console.log("🚀 ~ Services ~ createNewDevice ~ device:", {sp_adress: device})
|
||||
const database = await Database.getInstance();
|
||||
const indexedDb = await database.getDb();
|
||||
await database.writeObject(indexedDb, database.getStoreList().AnkSpAddress, {sp_address: device}, null);
|
||||
}
|
||||
this.sp_address = device;
|
||||
console.log("🚀 ~ Services ~ createNewDevice ~ device:", device)
|
||||
return device;
|
||||
}
|
||||
|
||||
async getAdresses() {
|
||||
const service = await Services.getInstance();
|
||||
const adresses:string = await service.sdkClient.get_address()
|
||||
console.log("🚀 ~ Services ~ createNewDevice ~ adresses:", adresses)
|
||||
this.sp_address = adresses
|
||||
}
|
||||
|
||||
private cleanSubsciptions(): void {
|
||||
for (const sub of this.subscriptions) {
|
||||
const el = sub.element;
|
||||
const eventHandler = sub.eventHandler;
|
||||
el.removeEventListener(sub.event, (this as any)[eventHandler].bind(this));
|
||||
}
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
async injectProcessListPage(): Promise<void> {
|
||||
const container = document.getElementById('containerId');
|
||||
|
||||
if (!container) {
|
||||
console.error("No html container");
|
||||
return;
|
||||
}
|
||||
|
||||
this.cleanSubsciptions()
|
||||
|
||||
const services = await Services.getInstance();
|
||||
// const user = services.sdkClient.create_user('Test', 'test', 10, 1, 'Messaging')
|
||||
// console.log("🚀 ~ Services ~ injectProcessListPage ~ user:", user)
|
||||
|
||||
// const database = await Database.getInstance();
|
||||
// const indexedDb = await database.getDb();
|
||||
// await database.writeObject(indexedDb, database.getStoreList().AnkUser, user.user, null);
|
||||
container.innerHTML = processPage;
|
||||
const newScript = document.createElement('script');
|
||||
newScript.textContent = processScript;
|
||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||
|
||||
this.processes = await services.getProcesses();
|
||||
if(this.processes) {
|
||||
services.setProcessesInSelectElement(this.processes)
|
||||
}
|
||||
}
|
||||
|
||||
public async setProcessesInSelectElement(processList: any[]) {
|
||||
const select = document.querySelector(".select-field");
|
||||
if(select) {
|
||||
for (const process of processList) {
|
||||
const option = document.createElement("option");
|
||||
option.setAttribute("value", process.name);
|
||||
option.innerText = process.name;
|
||||
select.appendChild(option);
|
||||
}
|
||||
}
|
||||
const optionList = document.querySelector('.autocomplete-list');
|
||||
if(optionList) {
|
||||
const observer = new MutationObserver((mutations, observer) => {
|
||||
const options = optionList.querySelectorAll('li')
|
||||
if(options) {
|
||||
for(const option of options) {
|
||||
this.addSubscription(option, 'click', 'showSelectedProcess')
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(document, {
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async listenToOptionListPopulating(event: Event) {
|
||||
const target = event.target as HTMLUListElement;
|
||||
const options = target?.querySelectorAll('li')
|
||||
}
|
||||
|
||||
public async showSelectedProcess(event: MouseEvent) {
|
||||
const elem = event.target;
|
||||
if(elem) {
|
||||
|
||||
const cardContent = document.querySelector(".card-content");
|
||||
const services = await Services.getInstance();
|
||||
|
||||
const processes = await services.getProcesses();
|
||||
console.log("🚀 ~ Services ~ showSelectedProcess ~ processes:", processes)
|
||||
const process = processes.find((process: any) => process.name === (elem as any).dataset.value);
|
||||
if (process) {
|
||||
const processDiv = document.createElement("div");
|
||||
processDiv.className = "process";
|
||||
processDiv.id = process.name;
|
||||
const titleDiv = document.createElement("div");
|
||||
titleDiv.className = "process-title";
|
||||
titleDiv.innerHTML = `${process.name} : ${process.description}`;
|
||||
processDiv.appendChild(titleDiv);
|
||||
for (const zone of process.zoneList) {
|
||||
const zoneElement = document.createElement("div");
|
||||
zoneElement.className = "process-element";
|
||||
zoneElement.setAttribute('zone-id', zone.id.toString())
|
||||
zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`;
|
||||
this.addSubscription(zoneElement, 'click', 'goToProcessPage')
|
||||
processDiv.appendChild(zoneElement);
|
||||
}
|
||||
if(cardContent) cardContent.appendChild(processDiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goToProcessPage(event: MouseEvent) {
|
||||
const target = event.target as HTMLDivElement;
|
||||
const zoneId = target?.getAttribute('zone-id');
|
||||
const processList = document.querySelectorAll('.process-element');
|
||||
if(processList) {
|
||||
for(const process of processList) {
|
||||
process.classList.remove('selected')
|
||||
}
|
||||
}
|
||||
target.classList.add('selected')
|
||||
|
||||
console.log('=======================> going to process page', zoneId)
|
||||
}
|
||||
|
||||
async getProcesses(): Promise<IProcess[]> {
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
name: "Messaging",
|
||||
description: "Encrypted messages",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "General",
|
||||
path: '/test'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Storage",
|
||||
description: "Distributed storage",
|
||||
zoneList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "Paris",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Normandy",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "New York",
|
||||
path: '/test'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Moscow",
|
||||
path: '/test'
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
getNotifications(): INotification[] {
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Notif 1',
|
||||
description: 'A normal notification',
|
||||
sendToNotificationPage: false,
|
||||
path: '/notif1'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Notif 2',
|
||||
description: 'A normal notification',
|
||||
sendToNotificationPage: false,
|
||||
path: '/notif2'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Notif 3',
|
||||
description: 'A normal notification',
|
||||
sendToNotificationPage: false,
|
||||
path: '/notif3'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
async setNotification(): Promise<void> {
|
||||
const badge = document.querySelector('.notification-badge') as HTMLDivElement
|
||||
const notifications = this.notifications
|
||||
const noNotifications = document.querySelector('.no-notification') as HTMLDivElement
|
||||
if(notifications?.length) {
|
||||
badge.innerText = notifications.length.toString()
|
||||
const notificationBoard = document.querySelector('.notification-board') as HTMLDivElement
|
||||
noNotifications.style.display = 'none'
|
||||
for(const notif of notifications) {
|
||||
const notifElement = document.createElement("div");
|
||||
notifElement.className = "notification-element";
|
||||
notifElement.setAttribute('notif-id', notif.id.toString())
|
||||
notifElement.innerHTML = `
|
||||
<div>${notif.title}</div>
|
||||
<div>${notif.description}</div>
|
||||
`;
|
||||
// this.addSubscription(notifElement, 'click', 'goToProcessPage')
|
||||
notificationBoard.appendChild(notifElement);
|
||||
}
|
||||
} else {
|
||||
noNotifications.style.display = 'block'
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import Services from "./services";
|
||||
import { AnkFlag, AnkNetworkMsg, CachedMessage } from "../dist/pkg/sdk_client";
|
||||
import { AnkFlag, AnkNetworkMsg, CachedMessage } from "dist/pkg/sdk_client";
|
||||
import Services from "./services/service";
|
||||
// import { AnkFlag, AnkNetworkMsg, CachedMessage } from "../dist/pkg/sdk_client";
|
||||
|
||||
class WebSocketClient {
|
||||
private ws: WebSocket;
|
||||
@ -24,51 +25,37 @@ class WebSocketClient {
|
||||
const msgData = event.data;
|
||||
|
||||
(async () => {
|
||||
console.log(msgData);
|
||||
if (typeof(msgData) === 'string') {
|
||||
console.log("Received text message: "+msgData);
|
||||
try {
|
||||
const feeRate = 1;
|
||||
// By parsing the message, we can link it with existing cached message and return the updated version of the message
|
||||
let res: CachedMessage = await services.parseNetworkMessage(msgData, feeRate);
|
||||
console.debug(res);
|
||||
if (res.status === 'FaucetComplete') {
|
||||
// we received a faucet tx, there's nothing else to do
|
||||
window.alert(`New faucet output\n${res.commited_in}`);
|
||||
await services.updateMessages(res);
|
||||
await services.updateOwnedOutputsForUser();
|
||||
} else if (res.status === 'TxWaitingCipher') {
|
||||
// we received a tx but we don't have the cipher
|
||||
console.debug(`received notification in output ${res.commited_in}, waiting for cipher message`);
|
||||
await services.updateMessages(res);
|
||||
await services.updateOwnedOutputsForUser();
|
||||
} else if (res.status === 'CipherWaitingTx') {
|
||||
// we received a cipher but we don't have the key
|
||||
console.debug(`received a cipher`);
|
||||
await services.updateMessages(res);
|
||||
} else if (res.status === 'SentWaitingConfirmation') {
|
||||
// We are sender and we're waiting for the challenge that will confirm recipient got the transaction and the message
|
||||
await services.updateMessages(res);
|
||||
await services.updateOwnedOutputsForUser();
|
||||
} else if (res.status === 'MustSpendConfirmation') {
|
||||
// we received a challenge for a notification we made
|
||||
// that means we can stop rebroadcasting the tx and we must spend the challenge to confirm
|
||||
window.alert(`Spending ${res.confirmed_by} to prove our identity`);
|
||||
console.debug(`sending confirm message to ${res.recipient}`);
|
||||
await services.updateMessages(res);
|
||||
await services.answer_confirmation_message(res);
|
||||
} else if (res.status === 'ReceivedMustConfirm') {
|
||||
// we found a notification and decrypted the cipher
|
||||
window.alert(`Received message from ${res.sender}\n${res.plaintext}`);
|
||||
// we must spend the commited_in output to sender
|
||||
await services.updateMessages(res);
|
||||
await services.confirm_sender_address(res);
|
||||
} else if (res.status === 'Complete') {
|
||||
window.alert(`Received confirmation that ${res.sender} is the author of message ${res.plaintext}`)
|
||||
await services.updateMessages(res);
|
||||
await services.updateOwnedOutputsForUser();
|
||||
} else {
|
||||
console.debug('Received an unimplemented valid message');
|
||||
}
|
||||
// if (res.status === 'FaucetComplete') {
|
||||
// // we received a faucet tx, there's nothing else to do
|
||||
// window.alert(`New faucet output\n${res.commited_in}`);
|
||||
// } else if (res.status === 'TxWaitingCipher') {
|
||||
// // we received a tx but we don't have the cipher
|
||||
// console.debug(`received notification in output ${res.commited_in}, waiting for cipher message`);
|
||||
// } else if (res.status === 'CipherWaitingTx') {
|
||||
// // we received a cipher but we don't have the key
|
||||
// console.debug(`received a cipher`);
|
||||
// } else if (res.status === 'SentWaitingConfirmation') {
|
||||
// // We are sender and we're waiting for the challenge that will confirm recipient got the transaction and the message
|
||||
// } else if (res.status === 'MustSpendConfirmation') {
|
||||
// // we received a challenge for a notification we made
|
||||
// // that means we can stop rebroadcasting the tx and we must spend the challenge to confirm
|
||||
// window.alert(`Spending ${res.confirmed_by} to prove our identity`);
|
||||
// console.debug(`sending confirm message to ${res.recipient}`);
|
||||
// } else if (res.status === 'ReceivedMustConfirm') {
|
||||
// // we found a notification and decrypted the cipher
|
||||
// window.alert(`Received message from ${res.sender}\n${res.plaintext}`);
|
||||
// // we must spend the commited_in output to sender
|
||||
// } else if (res.status === 'Complete') {
|
||||
// window.alert(`Received confirmation that ${res.sender} is the author of message ${res.plaintext}`)
|
||||
// } else {
|
||||
// console.debug('Received an unimplemented valid message');
|
||||
// }
|
||||
} catch (error) {
|
||||
console.error('Received an invalid message:', error);
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import wasm from 'vite-plugin-wasm';
|
||||
import {createHtmlPlugin} from 'vite-plugin-html';
|
||||
|
||||
export default defineConfig({
|
||||
optimizeDeps: {
|
||||
include: ['qrcode']
|
||||
},
|
||||
plugins: [
|
||||
vue(), // or react() if using React
|
||||
wasm(),
|
||||
@ -14,6 +17,7 @@ export default defineConfig({
|
||||
],
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
target: 'esnext',
|
||||
rollupOptions: {
|
||||
input: './src/index.ts',
|
||||
output: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user