diff --git a/.eslintrc.js b/.eslintrc.js index a075f6a13..bd08524b2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,7 @@ module.exports = { 'vuejs-accessibility/mouse-events-have-key-events': 'off', 'import/extensions': 'off', 'global-require': 'off', + 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], }, overrides: [ { diff --git a/jest.config.js b/jest.config.js index 86f530e0a..10a02b966 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,8 @@ module.exports = { + transform: { + '^.+\\.vue$': '@vue/vue3-jest', + '^.+\\.(mts|mjs|jsx|ts|tsx)$': 'ts-jest', + }, preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel', collectCoverage: true, collectCoverageFrom: ['src/(common|pegin)/(providers|services|utils)/*.ts'], @@ -13,4 +17,5 @@ module.exports = { coverageProvider: 'v8', transformIgnorePatterns: ['node_modules/(?!axios)/'], setupFilesAfterEnv: ['/setup-jest.js'], + silent: true, }; diff --git a/package-lock.json b/package-lock.json index e9e122955..8498adcb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "PowPeg", - "version": "2.2.1", + "version": "2.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "PowPeg", - "version": "2.2.1", + "version": "2.3.0", "dependencies": { "@leather.io/rpc": "^2.0.2", "@ledgerhq/devices": "6.27.1", @@ -41,12 +41,15 @@ "crypto-browserify": "^3.12.0", "ethers": "^5.7.2", "https-browserify": "^1.0.0", + "idb": "^8.0.0", "jest-environment-jsdom": "^27.5.1", "lodash": "^4.17.21", "markdown-it": "^14.1.0", "moment": "^2.29.4", "os-browserify": "^0.3.0", "process": "^0.11.10", + "register-service-worker": "^1.7.2", + "sats-connect": "2.3.x", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "text-encoding": "^0.7.0", @@ -58,7 +61,8 @@ "vuetify": "^3.5.17", "vuex": "^4.1.0", "web3": "^4.8.0", - "web3-eth-contract": "^1.10.0" + "web3-eth-contract": "^1.10.0", + "workbox-precaching": "^7.1.0" }, "devDependencies": { "@intlify/vue-i18n-loader": "^4.2.0", @@ -75,6 +79,7 @@ "@typescript-eslint/parser": "^5.62.0", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", + "@vue/cli-plugin-pwa": "^5.0.8", "@vue/cli-plugin-router": "~5.0.0", "@vue/cli-plugin-typescript": "~5.0.0", "@vue/cli-plugin-unit-jest": "~5.0.0", @@ -92,6 +97,7 @@ "eslint-plugin-import": "^2.28.0", "eslint-plugin-vue": "^8.7.1", "eslint-plugin-vuejs-accessibility": "^1.2.0", + "fake-indexeddb": "^6.0.0", "geckodriver": "^4.4.0", "jest": "^27.5.1", "sass": "^1.64.2", @@ -143,39 +149,41 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.25.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.22.9", - "license": "MIT", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", + "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.22.11", - "license": "MIT", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", + "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.11", - "@babel/parser": "^7.22.11", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", @@ -189,15 +197,20 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, "node_modules/@babel/generator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", - "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "dependencies": { - "@babel/types": "^7.23.4", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/types": "^7.25.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" @@ -224,12 +237,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.10", - "license": "MIT", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -330,26 +344,26 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", "dependencies": { - "@babel/types": "^7.24.0" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", - "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-simple-access": "^7.24.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/helper-validator-identifier": "^7.24.5" + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -408,11 +422,12 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", - "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", "dependencies": { - "@babel/types": "^7.24.5" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -440,25 +455,25 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", - "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", "engines": { "node": ">=6.9.0" } @@ -476,34 +491,38 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.11", - "license": "MIT", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.11", - "@babel/types": "^7.22.11" + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", - "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", + "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", + "dependencies": { + "@babel/types": "^7.25.7" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -2140,32 +2159,29 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", - "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", - "dependencies": { - "@babel/code-frame": "^7.23.4", - "@babel/generator": "^7.23.4", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.4", - "@babel/types": "^7.23.4", - "debug": "^4.1.0", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -2173,12 +2189,12 @@ } }, "node_modules/@babel/types": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", - "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", + "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", "dependencies": { - "@babel/helper-string-parser": "^7.24.1", - "@babel/helper-validator-identifier": "^7.24.5", + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -5868,12 +5884,13 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "license": "MIT", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -5887,8 +5904,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "license": "MIT", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { "node": ">=6.0.0" } @@ -5907,8 +5925,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "license": "MIT", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -6818,6 +6837,80 @@ "node": ">=10" } }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, "node_modules/@rsksmart/bridges-core-sdk": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@rsksmart/bridges-core-sdk/-/bridges-core-sdk-0.3.3.tgz", @@ -7102,6 +7195,48 @@ "version": "1.0.1", "license": "ISC" }, + "node_modules/@sats-connect/core": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@sats-connect/core/-/core-0.0.8.tgz", + "integrity": "sha512-vb7drnd8lFfO4ahCzaVAFkX1eHF1J7jheJl2V/JuuJd5f1sy6nHeNzKMp1zmiuql8uNwe0Sx1WrK1I+4tUmDHg==", + "dependencies": { + "axios": "1.6.8", + "bitcoin-address-validation": "2.2.3", + "buffer": "6.0.3", + "jsontokens": "4.0.1", + "lodash.omit": "4.5.0" + } + }, + "node_modules/@sats-connect/core/node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/@sats-connect/core/node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" + }, + "node_modules/@sats-connect/core/node_modules/bitcoin-address-validation": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/bitcoin-address-validation/-/bitcoin-address-validation-2.2.3.tgz", + "integrity": "sha512-1uGCGl26Ye8JG5qcExtFLQfuib6qEZWNDo1ZlLlwp/z7ygUFby3IxolgEfgMGaC+LG9csbVASLcH8fRLv7DIOg==", + "dependencies": { + "base58-js": "^1.0.0", + "bech32": "^2.0.0", + "sha256-uint8array": "^0.10.3" + } + }, + "node_modules/@sats-connect/ui": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@sats-connect/ui/-/ui-0.0.6.tgz", + "integrity": "sha512-H3bFFhr9CcY1oNosNi/QJszmMHSht4U19bUWfM3vzayAKgV4ebY6iUnRK5g3p2rVLLWVzlpaw1J9m+7JWwyBfA==" + }, "node_modules/@scure/base": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", @@ -7521,6 +7656,27 @@ "npm": ">=6.0.0" } }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dev": true, + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, "node_modules/@swan-bitcoin/xpub-lib": { "version": "0.1.5", "license": "MIT", @@ -8107,26 +8263,18 @@ }, "node_modules/@types/eslint": { "version": "8.44.2", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { - "version": "1.0.1", - "devOptional": true, - "license": "MIT" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "devOptional": true }, "node_modules/@types/express": { "version": "4.17.17", @@ -8446,6 +8594,12 @@ "version": "7.0.0", "license": "MIT" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true + }, "node_modules/@types/w3c-web-usb": { "version": "1.0.6", "license": "MIT" @@ -9085,6 +9239,407 @@ "eslint": ">=7.5.0" } }, + "node_modules/@vue/cli-plugin-pwa": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-pwa/-/cli-plugin-pwa-5.0.8.tgz", + "integrity": "sha512-MnD9Y6I3nX7c/NawpsJtbXaGFjI9LT5Az7IQjpshS65+yvuOcxV2j/tCjPTrja+zd1VmB4DZUhrfUU2exSBfGg==", + "dev": true, + "dependencies": { + "@vue/cli-shared-utils": "^5.0.8", + "html-webpack-plugin": "^5.1.0", + "webpack": "^5.54.0", + "workbox-webpack-plugin": "^6.1.0" + }, + "peerDependencies": { + "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dev": true, + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "dev": true, + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==", + "dev": true + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "dev": true, + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "dev": true, + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==", + "dev": true + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, + "node_modules/@vue/cli-plugin-pwa/node_modules/workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "dev": true, + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, "node_modules/@vue/cli-plugin-router": { "version": "5.0.8", "dev": true, @@ -9998,9 +10553,10 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "devOptional": true, - "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -10008,23 +10564,27 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "devOptional": true }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "devOptional": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "devOptional": true, - "license": "MIT" + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "devOptional": true }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "devOptional": true, - "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -10033,62 +10593,69 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "devOptional": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "devOptional": true, - "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "devOptional": true, - "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "devOptional": true, - "license": "MIT" + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "devOptional": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "devOptional": true, - "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "devOptional": true, - "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", @@ -10096,22 +10663,24 @@ } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "devOptional": true, - "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "devOptional": true, - "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", @@ -10120,11 +10689,12 @@ } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "devOptional": true, - "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -10138,13 +10708,15 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "devOptional": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "devOptional": true }, "node_modules/@xtuc/long": { "version": "4.2.2", - "devOptional": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "devOptional": true }, "node_modules/abab": { "version": "2.0.6", @@ -10227,10 +10799,11 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "devOptional": true, - "license": "MIT", "peerDependencies": { "acorn": "^8" } @@ -10768,11 +11341,11 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz", - "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -11153,6 +11726,14 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/base58-js": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/base58-js/-/base58-js-1.0.5.tgz", + "integrity": "sha512-LkkAPP8Zu+c0SVNRTRVDyMfKVORThX+rCViget00xdgLRrKkClCTz1T7cIrpr69ShwV5XJuuoZvMvJ43yURwkA==", + "engines": { + "node": ">= 8" + } + }, "node_modules/base64-js": { "version": "1.5.1", "funding": [ @@ -11425,9 +12006,9 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -11438,7 +12019,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -11463,21 +12044,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/bonjour-service": { "version": "1.1.1", "dev": true, @@ -11625,7 +12191,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.10", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "funding": [ { "type": "opencollective", @@ -11640,12 +12208,11 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -11771,6 +12338,18 @@ "node": ">=8.0.0" } }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/builtin-status-codes": { "version": "3.0.0", "license": "MIT" @@ -11783,8 +12362,9 @@ }, "node_modules/bytes": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } @@ -11978,9 +12558,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001646", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz", - "integrity": "sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==", + "version": "1.0.30001667", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", + "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", "funding": [ { "type": "opencollective", @@ -12461,6 +13041,15 @@ "node": ">= 12" } }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/commondir": { "version": "1.0.1", "license": "MIT" @@ -12666,14 +13255,16 @@ }, "node_modules/content-type": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { "version": "1.9.0", + "dev": true, "license": "MIT" }, "node_modules/cookie": { @@ -12882,7 +13473,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "peer": true, "engines": { "node": ">=8" } @@ -14123,6 +14713,21 @@ "node": ">=10.0.0" } }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron": { "version": "24.8.8", "resolved": "https://registry.npmjs.org/electron/-/electron-24.8.8.tgz", @@ -14142,8 +14747,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.502", - "license": "ISC" + "version": "1.5.33", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", + "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==" }, "node_modules/electron/node_modules/@types/node": { "version": "18.17.11", @@ -14199,6 +14805,7 @@ "node_modules/encodeurl": { "version": "1.0.2", "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8" } @@ -14479,8 +15086,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "license": "MIT", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -16645,37 +17253,37 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -16695,6 +17303,15 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -16702,25 +17319,50 @@ "dev": true }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "dev": true, - "license": "MIT" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "dev": true }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/express/node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.8.0" + } + }, + "node_modules/express/node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" } }, + "node_modules/express/node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", @@ -16797,6 +17439,15 @@ "node": "> 0.1.90" } }, + "node_modules/fake-indexeddb": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-6.0.0.tgz", + "integrity": "sha512-YEboHE5VfopUclOck7LncgIqskAqnv4q0EWbYCaxKKjAvO93c+TJIaBuGy8CBFdbg9nKdpN3AuPRwVBJ4k7NrQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/fake-merkle-patricia-tree": { "version": "1.0.1", "license": "ISC", @@ -16868,6 +17519,12 @@ "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" }, + "node_modules/fast-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", + "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "dev": true + }, "node_modules/fastq": { "version": "1.15.0", "license": "ISC", @@ -17056,6 +17713,36 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -17068,12 +17755,13 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, - "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -17086,16 +17774,27 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, - "node_modules/finalhandler/node_modules/ms": { + "node_modules/finalhandler/node_modules/encodeurl": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, - "license": "MIT" + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/find-cache-dir": { "version": "3.3.2", @@ -17691,6 +18390,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, "node_modules/get-package-type": { "version": "0.1.0", "dev": true, @@ -18473,6 +19178,11 @@ "postcss": "^8.1.0" } }, + "node_modules/idb": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/idb/-/idb-8.0.0.tgz", + "integrity": "sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw==" + }, "node_modules/ieee754": { "version": "1.2.1", "funding": [ @@ -18964,6 +19674,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, "node_modules/is-nan": { "version": "1.3.2", "license": "MIT", @@ -19015,6 +19731,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -19072,6 +19797,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-shared-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", @@ -19357,6 +20091,100 @@ "node": ">=8" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/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==", + "dev": true + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/javascript-stringify": { "version": "2.1.0", "dev": true, @@ -21727,13 +22555,14 @@ "license": "MIT" }, "node_modules/jsesc": { - "version": "2.5.2", - "license": "MIT", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-bigint": { @@ -21940,6 +22769,15 @@ "node >= 0.2.0" ] }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jsonschema": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.2.tgz", @@ -22502,6 +23340,17 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, "node_modules/lodash.truncate": { "version": "4.4.2", "dev": true, @@ -22926,8 +23775,9 @@ }, "node_modules/media-typer": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -22978,9 +23828,13 @@ "license": "MIT" }, "node_modules/merge-descriptors": { - "version": "1.0.1", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true, - "license": "MIT" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-source-map": { "version": "1.1.0", @@ -23082,10 +23936,11 @@ "license": "MIT" }, "node_modules/micromatch": { - "version": "4.0.5", - "license": "MIT", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -23636,8 +24491,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.13", - "license": "MIT" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, "node_modules/nopt": { "version": "6.0.0", @@ -24396,9 +25252,10 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "1.8.0", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, - "license": "MIT", "dependencies": { "isarray": "0.0.1" } @@ -24447,8 +25304,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", - "license": "ISC" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -25166,7 +26024,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "peer": true, "engines": { "node": ">=6" }, @@ -25582,10 +26439,11 @@ } }, "node_modules/qs": { - "version": "6.11.2", - "license": "BSD-3-Clause", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -25919,6 +26777,11 @@ "node": ">=4" } }, + "node_modules/register-service-worker": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/register-service-worker/-/register-service-worker-1.7.2.tgz", + "integrity": "sha512-CiD3ZSanZqcMPRhtfct5K9f7i3OLCcBBWsJjLh1gW9RO/nS94sVzY59iS+fgYBOBqaBpf4EzfqUF3j9IG+xo8A==" + }, "node_modules/regjsparser": { "version": "0.9.1", "license": "BSD-2-Clause", @@ -26303,6 +27166,81 @@ "license": "BSD-3-Clause", "optional": true }, + "node_modules/rollup": { + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/rpc-websockets": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.11.0.tgz", @@ -26511,6 +27449,84 @@ } } }, + "node_modules/sats-connect": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sats-connect/-/sats-connect-2.3.1.tgz", + "integrity": "sha512-3KzqRO5KVBlge7Q4a/L828SfCkFD+M4MVdtgJZS+L+oHiDYoXlLkvnu3almh9Ynhcm0HnsGmVH1pKVL0lonjyQ==", + "dependencies": { + "@sats-connect/core": "0.0.8", + "@sats-connect/make-default-provider-config": "0.0.4", + "@sats-connect/ui": "0.0.6" + } + }, + "node_modules/sats-connect/node_modules/@sats-connect/make-default-provider-config": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@sats-connect/make-default-provider-config/-/make-default-provider-config-0.0.4.tgz", + "integrity": "sha512-PsLzg1hV3FxMXUp9XrOUmDJgbuyR4VDHq/7mh1O1CtC3dDZQnJFa+Ue43duPMmUaRGinuVKtS2hnMhPLyURdGA==", + "dependencies": { + "@sats-connect/core": "0.0.7", + "@sats-connect/ui": "0.0.5-c661c02", + "bowser": "2.11.0" + }, + "peerDependencies": { + "typescript": "5.4.4" + } + }, + "node_modules/sats-connect/node_modules/@sats-connect/make-default-provider-config/node_modules/@sats-connect/core": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@sats-connect/core/-/core-0.0.7.tgz", + "integrity": "sha512-4m5amq+orHDbqLqCRWojvDQigKAys33Ntwc7U5xNtFeib4j+DpYz6lVAL/s3cay1kq03WUZ+Gil3l5rv+5bQWQ==", + "dependencies": { + "axios": "1.6.8", + "bitcoin-address-validation": "2.2.3", + "buffer": "6.0.3", + "jsontokens": "4.0.1", + "lodash.omit": "4.5.0" + } + }, + "node_modules/sats-connect/node_modules/@sats-connect/make-default-provider-config/node_modules/@sats-connect/ui": { + "version": "0.0.5-c661c02", + "resolved": "https://registry.npmjs.org/@sats-connect/ui/-/ui-0.0.5-c661c02.tgz", + "integrity": "sha512-6MUXFDGTapBhZAxb6deAdqKuB64GOe6k927gGww5JYwVnOUCaHGDcfaZ/lwexzYL45u8RJof12I4np7MgS+Bwg==" + }, + "node_modules/sats-connect/node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/sats-connect/node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" + }, + "node_modules/sats-connect/node_modules/bitcoin-address-validation": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/bitcoin-address-validation/-/bitcoin-address-validation-2.2.3.tgz", + "integrity": "sha512-1uGCGl26Ye8JG5qcExtFLQfuib6qEZWNDo1ZlLlwp/z7ygUFby3IxolgEfgMGaC+LG9csbVASLcH8fRLv7DIOg==", + "dependencies": { + "base58-js": "^1.0.0", + "bech32": "^2.0.0", + "sha256-uint8array": "^0.10.3" + } + }, + "node_modules/sats-connect/node_modules/typescript": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", + "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/sax": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", @@ -26632,6 +27648,7 @@ "node_modules/send": { "version": "0.18.0", "license": "MIT", + "peer": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -26654,17 +27671,20 @@ "node_modules/send/node_modules/debug": { "version": "2.6.9", "license": "MIT", + "peer": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/serialize-error": { "version": "7.0.1", @@ -26772,18 +27792,76 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "license": "MIT", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-static/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static/node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/serve-static/node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "license": "ISC" @@ -26844,6 +27922,11 @@ "sha.js": "bin.js" } }, + "node_modules/sha256-uint8array": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/sha256-uint8array/-/sha256-uint8array-0.10.7.tgz", + "integrity": "sha512-1Q6JQU4tX9NqsDGodej6pkrUVQVNapLZnvkwIhddH/JqzBZF1fSaxSWNY6sziXBE8aEa2twtGkXUrwzGeZCMpQ==" + }, "node_modules/shallow-clone": { "version": "3.0.1", "license": "MIT", @@ -26891,12 +27974,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "license": "MIT", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -27132,6 +28220,12 @@ "node": ">=10" } }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, "node_modules/source-map": { "version": "0.6.1", "license": "BSD-3-Clause", @@ -27155,6 +28249,13 @@ "source-map": "^0.6.0" } }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, "node_modules/spdx-correct": { "version": "3.2.0", "dev": true, @@ -27407,6 +28508,32 @@ "version": "8.0.0", "license": "MIT" }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -27453,6 +28580,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "license": "MIT", @@ -27471,6 +28612,15 @@ "node": ">=8" } }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/strip-dirs": { "version": "2.1.0", "dev": true, @@ -27955,7 +29105,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "peer": true, "engines": { "node": ">=8" } @@ -28030,9 +29179,10 @@ } }, "node_modules/terser": { - "version": "5.19.2", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "devOptional": true, - "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -28047,15 +29197,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.9", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "devOptional": true, - "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -28692,8 +29843,9 @@ }, "node_modules/type-is": { "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, - "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -29029,7 +30181,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "peer": true, "dependencies": { "crypto-random-string": "^2.0.0" }, @@ -29081,7 +30232,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -29096,10 +30249,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -29685,9 +30837,10 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "devOptional": true, - "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -31267,33 +32420,33 @@ } }, "node_modules/webpack": { - "version": "5.88.2", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "devOptional": true, - "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -31719,9 +32872,10 @@ "license": "MIT" }, "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.15.0", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "devOptional": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -31749,8 +32903,9 @@ }, "node_modules/webpack/node_modules/tapable": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -31947,6 +33102,37 @@ "integrity": "sha512-U0IUQHKXXn6PFo9nqsHphVCE5m3IntqZNB9Jjn7EB1lrR7YTDY3YWgFvEvwniTzXSvOH/XMzAZaIfJF/LvHYXg==", "peer": true }, + "node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, + "node_modules/workbox-precaching": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.1.0.tgz", + "integrity": "sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==", + "dependencies": { + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" + } + }, + "node_modules/workbox-routing": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.1.0.tgz", + "integrity": "sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-strategies": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.1.0.tgz", + "integrity": "sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==", + "dependencies": { + "workbox-core": "7.1.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "license": "MIT", diff --git a/package.json b/package.json index f251cc9d5..632208d7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "PowPeg", - "version": "2.2.1", + "version": "2.3.0", "private": true, "scripts": { "serve": "vue-cli-service serve", @@ -8,6 +8,7 @@ "build": "vue-cli-service build", "test": "vue-cli-service test:unit --env=./tests/jsdom-env.js --coverageReporters=lcov --collect-coverage", "test:unit": "vue-cli-service test:unit --env=./tests/jsdom-env.js --coverageReporters=lcov --collect-coverage", + "test:unit-logs": "vue-cli-service test:unit --env=./tests/jsdom-env.js --coverageReporters=lcov --silent=false --collect-coverage", "lint": "vue-cli-service lint", "scanner": "npx sonar-scanner" }, @@ -45,12 +46,15 @@ "crypto-browserify": "^3.12.0", "ethers": "^5.7.2", "https-browserify": "^1.0.0", + "idb": "^8.0.0", "jest-environment-jsdom": "^27.5.1", "lodash": "^4.17.21", "markdown-it": "^14.1.0", "moment": "^2.29.4", "os-browserify": "^0.3.0", "process": "^0.11.10", + "register-service-worker": "^1.7.2", + "sats-connect": "2.3.x", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "text-encoding": "^0.7.0", @@ -62,7 +66,8 @@ "vuetify": "^3.5.17", "vuex": "^4.1.0", "web3": "^4.8.0", - "web3-eth-contract": "^1.10.0" + "web3-eth-contract": "^1.10.0", + "workbox-precaching": "^7.1.0" }, "devDependencies": { "@intlify/vue-i18n-loader": "^4.2.0", @@ -79,6 +84,7 @@ "@typescript-eslint/parser": "^5.62.0", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", + "@vue/cli-plugin-pwa": "^5.0.8", "@vue/cli-plugin-router": "~5.0.0", "@vue/cli-plugin-typescript": "~5.0.0", "@vue/cli-plugin-unit-jest": "~5.0.0", @@ -96,6 +102,7 @@ "eslint-plugin-import": "^2.28.0", "eslint-plugin-vue": "^8.7.1", "eslint-plugin-vuejs-accessibility": "^1.2.0", + "fake-indexeddb": "^6.0.0", "geckodriver": "^4.4.0", "jest": "^27.5.1", "sass": "^1.64.2", diff --git a/public/img/icons/android-chrome-192x192.png b/public/img/icons/android-chrome-192x192.png new file mode 100644 index 000000000..b02aa64d9 Binary files /dev/null and b/public/img/icons/android-chrome-192x192.png differ diff --git a/public/img/icons/android-chrome-512x512.png b/public/img/icons/android-chrome-512x512.png new file mode 100644 index 000000000..06088b011 Binary files /dev/null and b/public/img/icons/android-chrome-512x512.png differ diff --git a/public/img/icons/android-chrome-maskable-192x192.png b/public/img/icons/android-chrome-maskable-192x192.png new file mode 100644 index 000000000..791e9c8c2 Binary files /dev/null and b/public/img/icons/android-chrome-maskable-192x192.png differ diff --git a/public/img/icons/android-chrome-maskable-512x512.png b/public/img/icons/android-chrome-maskable-512x512.png new file mode 100644 index 000000000..5f2098ed2 Binary files /dev/null and b/public/img/icons/android-chrome-maskable-512x512.png differ diff --git a/public/img/icons/apple-touch-icon-120x120.png b/public/img/icons/apple-touch-icon-120x120.png new file mode 100644 index 000000000..1427cf627 Binary files /dev/null and b/public/img/icons/apple-touch-icon-120x120.png differ diff --git a/public/img/icons/apple-touch-icon-152x152.png b/public/img/icons/apple-touch-icon-152x152.png new file mode 100644 index 000000000..f24d454a2 Binary files /dev/null and b/public/img/icons/apple-touch-icon-152x152.png differ diff --git a/public/img/icons/apple-touch-icon-180x180.png b/public/img/icons/apple-touch-icon-180x180.png new file mode 100644 index 000000000..404e192a9 Binary files /dev/null and b/public/img/icons/apple-touch-icon-180x180.png differ diff --git a/public/img/icons/apple-touch-icon-60x60.png b/public/img/icons/apple-touch-icon-60x60.png new file mode 100644 index 000000000..cf10a5602 Binary files /dev/null and b/public/img/icons/apple-touch-icon-60x60.png differ diff --git a/public/img/icons/apple-touch-icon-76x76.png b/public/img/icons/apple-touch-icon-76x76.png new file mode 100644 index 000000000..c500769e3 Binary files /dev/null and b/public/img/icons/apple-touch-icon-76x76.png differ diff --git a/public/img/icons/apple-touch-icon.png b/public/img/icons/apple-touch-icon.png new file mode 100644 index 000000000..03c0c5d5e Binary files /dev/null and b/public/img/icons/apple-touch-icon.png differ diff --git a/public/img/icons/favicon-16x16.png b/public/img/icons/favicon-16x16.png new file mode 100644 index 000000000..8976969fb Binary files /dev/null and b/public/img/icons/favicon-16x16.png differ diff --git a/public/img/icons/favicon-32x32.png b/public/img/icons/favicon-32x32.png new file mode 100644 index 000000000..91726088b Binary files /dev/null and b/public/img/icons/favicon-32x32.png differ diff --git a/public/img/icons/maskable_icon.png b/public/img/icons/maskable_icon.png new file mode 100644 index 000000000..90d3a705a Binary files /dev/null and b/public/img/icons/maskable_icon.png differ diff --git a/public/img/icons/maskable_icon_x192.png b/public/img/icons/maskable_icon_x192.png new file mode 100644 index 000000000..363436f48 Binary files /dev/null and b/public/img/icons/maskable_icon_x192.png differ diff --git a/public/img/icons/maskable_icon_x384.png b/public/img/icons/maskable_icon_x384.png new file mode 100644 index 000000000..6f31ac7e2 Binary files /dev/null and b/public/img/icons/maskable_icon_x384.png differ diff --git a/public/img/icons/maskable_icon_x512.png b/public/img/icons/maskable_icon_x512.png new file mode 100644 index 000000000..d143c5d82 Binary files /dev/null and b/public/img/icons/maskable_icon_x512.png differ diff --git a/public/img/icons/msapplication-icon-144x144.png b/public/img/icons/msapplication-icon-144x144.png new file mode 100644 index 000000000..7808237a1 Binary files /dev/null and b/public/img/icons/msapplication-icon-144x144.png differ diff --git a/public/img/icons/mstile-150x150.png b/public/img/icons/mstile-150x150.png new file mode 100644 index 000000000..3b37a43ae Binary files /dev/null and b/public/img/icons/mstile-150x150.png differ diff --git a/public/img/icons/safari-pinned-tab.svg b/public/img/icons/safari-pinned-tab.svg new file mode 100644 index 000000000..e44c0d5b0 --- /dev/null +++ b/public/img/icons/safari-pinned-tab.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/index.html b/public/index.html index f6e727901..11e4e8f57 100644 --- a/public/index.html +++ b/public/index.html @@ -5,7 +5,7 @@ - <%= htmlWebpackPlugin.options.title %> + PowPeg diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 000000000..eb0536286 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/setup-jest.js b/setup-jest.js index 7c97c034f..43f7fb8a6 100644 --- a/setup-jest.js +++ b/setup-jest.js @@ -1,3 +1,4 @@ import { TextEncoder, TextDecoder } from 'util'; +import 'fake-indexeddb/auto'; Object.assign(global, { TextDecoder, TextEncoder }); diff --git a/src/App.vue b/src/App.vue index 2b7baa84e..69ce33273 100644 --- a/src/App.vue +++ b/src/App.vue @@ -13,7 +13,9 @@ diff --git a/src/common/components/status/StatusProgressBar.vue b/src/common/components/status/StatusProgressBar.vue index 623c2b798..92f39193c 100644 --- a/src/common/components/status/StatusProgressBar.vue +++ b/src/common/components/status/StatusProgressBar.vue @@ -6,10 +6,9 @@
+ :id="`indicator-${timeLineData[0][1]}${txFailed?'-error':''}`">
- @@ -37,7 +35,6 @@

{{ timeLineData[0][0] }}

-

{{ timeLineData[4][0] }}

@@ -73,6 +69,7 @@ import { TxStatusType, } from '@/common/types'; import { PegStatus, FlyoverStatus } from '@/common/store/constants'; +import EnvironmentContextProviderService from '@/common/providers/EnvironmentContextProvider'; export default defineComponent({ name: 'StatusProgressBar', @@ -83,6 +80,11 @@ export default defineComponent({ }, setup(props) { const status = useState('status'); + const environmentContext = EnvironmentContextProviderService.getEnvironmentContext(); + const btcTicker = environmentContext.getBtcTicker(); + const rbtcTicker = environmentContext.getRbtcTicker(); + const txFailed = computed(() => props.txWithError + || status.value.flyoverStatus === FlyoverStatus.FAILED); const txDetails = useStateAttribute('status', 'txDetails'); const isPegOut = computed((): boolean => status.value.type === TxStatusType.PEGOUT || status.value.type === TxStatusType.FLYOVER_PEGOUT); @@ -99,8 +101,8 @@ export default defineComponent({ } return require('@/assets/status/rbtc.svg'); }); - const initialImgSize = computed(() => (props.txWithError ? 32 : 12)); - const barColor = computed(() => (props.txWithError ? 'red' : 'green')); + const initialImgSize = computed(() => (txFailed.value ? 32 : 12)); + const barColor = computed(() => (txFailed.value ? 'red' : 'green')); const timeLineData = computed(() => { let labelOne = 'Transaction Broadcasted'; let labelTwo = 'Transaction Confirmed'; @@ -116,7 +118,38 @@ export default defineComponent({ } else if (isPegOut.value) { labelThree = 'Sent to Bitcoin'; if (props.isFlyover) { - zero = txDetails.value.status === FlyoverStatus.COMPLETED ? 100 : 50; + labelOne = `Send ${rbtcTicker} to Liquidity Provider`; + labelTwo = `Liquidity Provider received ${rbtcTicker}`; + labelThree = `Liquidity Provider send ${btcTicker}`; + switch (status.value.flyoverStatus) { + case FlyoverStatus.PENDING: + zero = 100; + first = 100; + second = 70; + break; + case FlyoverStatus.SUCCESS: + zero = 100; + first = 100; + second = 100; + third = 100; + break; + case FlyoverStatus.FAILED: + zero = 100; + labelOne = 'Error occurred'; + labelTwo = ''; + labelThree = ''; + break; + default: + zero = 0; + first = 0; + second = 0; + third = 0; + fourth = 0; + labelOne = ''; + labelTwo = ''; + labelThree = ''; + break; + } } else { switch (txDetails.value.status as PegoutStatus) { case PegoutStatus.PENDING: @@ -166,7 +199,38 @@ export default defineComponent({ } } } else if (props.isFlyover) { - zero = txDetails.value.status === FlyoverStatus.COMPLETED ? 100 : 50; + labelOne = `Send ${btcTicker} to Liquidity Provider`; + labelTwo = `Liquidity Provider received ${btcTicker}`; + labelThree = `Liquidity Provider send ${rbtcTicker}`; + switch (status.value.flyoverStatus) { + case FlyoverStatus.PENDING: + zero = 100; + first = 100; + second = 70; + break; + case FlyoverStatus.SUCCESS: + zero = 100; + first = 100; + second = 100; + third = 100; + break; + case FlyoverStatus.FAILED: + zero = 100; + labelOne = 'Error occurred'; + labelTwo = ''; + labelThree = ''; + break; + default: + zero = 0; + first = 0; + second = 0; + third = 0; + fourth = 0; + labelOne = ''; + labelTwo = ''; + labelThree = ''; + break; + } } else { const txDetailsPegIn = txDetails.value as PeginStatus; const btc = txDetailsPegIn.btc as BtcPeginStatus; @@ -240,7 +304,7 @@ export default defineComponent({ }; }); const imgStep1 = computed(() => { - if (props.txWithError) return require('@/assets/status/ellipse_error.svg'); + if (txFailed.value) return require('@/assets/status/ellipse_error.svg'); if (timeLineData.value[0][1] === 100) return require('@/assets/status/ellipse.svg'); return require('@/assets/status/ellipse_empty.svg'); }); @@ -266,6 +330,7 @@ export default defineComponent({ imgStep3, initialImgSize, barColor, + txFailed, }; }, }); diff --git a/src/common/components/status/TxPegout.vue b/src/common/components/status/TxPegout.vue index 70641a628..0266fc2a9 100644 --- a/src/common/components/status/TxPegout.vue +++ b/src/common/components/status/TxPegout.vue @@ -61,6 +61,7 @@ export default defineComponent({ const status = txDetails.value as PegoutStatusDataModel; const valueRequested = new SatoshiBig(status.valueRequestedInSatoshis, 'satoshi').toBTCTrimmedString(); const amountSent = new WeiBig(valueRequested, 'rbtc').plus(calculatedGasFee.value).toRBTCTrimmedString(); + const btcTxId = status.status === PegoutStatus.RELEASE_BTC ? status.btcTxId : ''; return { amountFromString: amountSent, amountReceivedString: amountToBeReceived.value, @@ -71,6 +72,7 @@ export default defineComponent({ txId: status.rskTxHash ? status.rskTxHash : props.txId, estimatedFee: Number(pegOutEstimatedFee.value.toBTCTrimmedString()), status: status.status, + btcTxId, }; }); diff --git a/src/common/providers/UnreadNotifications.ts b/src/common/providers/UnreadNotifications.ts new file mode 100644 index 000000000..8088891ee --- /dev/null +++ b/src/common/providers/UnreadNotifications.ts @@ -0,0 +1,8 @@ +import { InjectionKey, Ref } from 'vue'; + +export interface UnreadNotification { + counter: Ref + updateCounter: (value: number) => void + } + +export const unreadNotificationsKey = Symbol('UnreadNotificationsKey') as InjectionKey; diff --git a/src/common/services/FlyoverService.ts b/src/common/services/FlyoverService.ts index 8f50b206e..c22f811aa 100644 --- a/src/common/services/FlyoverService.ts +++ b/src/common/services/FlyoverService.ts @@ -3,6 +3,7 @@ import { AcceptedPegoutQuote, Flyover, LiquidityProvider, PegoutQuote, Quote, AcceptedQuote, + FlyoverUtils, } from '@rsksmart/flyover-sdk'; import * as constants from '@/common/store/constants'; import { @@ -443,4 +444,59 @@ export default class FlyoverService { } }); } + + public getAvailableLiquidity(): Promise<{peginLiquidity: WeiBig, pegoutLiquidity: SatoshiBig}> { + return new Promise((resolve, reject) => { + this.flyover?.getAvailableLiquidity() + .then(({ peginLiquidityAmount, pegoutLiquidityAmount }) => { + const peginLiquidity = new WeiBig(peginLiquidityAmount, 'wei'); + const pegoutLiquidity = new SatoshiBig(pegoutLiquidityAmount, 'satoshi'); + resolve({ peginLiquidity, pegoutLiquidity }); + }) + .catch((error) => { + reject(new ServiceError( + 'FlyoverService', + 'getAvailableLiquidity', + 'There was an error getting the available liquidity from the Flyover server', + error.message, + )); + }); + }); + } + + public getPeginStatus(quoteHash: string) { + return new Promise((resolve, reject) => { + this.flyover?.getPeginStatus(quoteHash) + .then((detailedStatus) => { + const status = FlyoverUtils.getSimpleQuoteStatus(detailedStatus.status.state); + resolve(status); + }) + .catch((error) => { + reject(new ServiceError( + 'FlyoverService', + 'getPeginStatus', + 'There was an error getting the status of the peg-in transaction from the Flyover server', + error.message, + )); + }); + }); + } + + public getPegoutStatus(quoteHash: string) { + return new Promise((resolve, reject) => { + this.flyover?.getPegoutStatus(quoteHash) + .then((detailedStatus) => { + const status = FlyoverUtils.getSimpleQuoteStatus(detailedStatus.status.state); + resolve(status); + }) + .catch((error) => { + reject(new ServiceError( + 'FlyoverService', + 'getPegoutStatus', + 'There was an error getting the status of the peg-out transaction from the Flyover server', + error.message, + )); + }); + }); + } } diff --git a/src/common/services/XverseService.ts b/src/common/services/XverseService.ts new file mode 100644 index 000000000..d79c667d1 --- /dev/null +++ b/src/common/services/XverseService.ts @@ -0,0 +1,144 @@ +/* eslint-disable class-methods-use-this */ +import Wallet, { AddressPurpose, BitcoinNetworkType } from 'sats-connect'; +import * as bitcoin from 'bitcoinjs-lib'; +import { WalletService } from '@/common/services/index'; +import * as constants from '@/common/store/constants'; +import { + WalletAddress, Tx, SignedTx, BtcAccount, Step, + XverseTx, +} from '../types'; + +export default class XverseService extends WalletService { + satsBtcNetwork: BitcoinNetworkType; + + constructor() { + super(); + switch (this.network) { + case constants.BTC_NETWORK_MAINNET: + this.satsBtcNetwork = BitcoinNetworkType.Mainnet; + break; + default: + this.satsBtcNetwork = BitcoinNetworkType.Testnet; + break; + } + } + + getAccountAddresses(): Promise { + return new Promise((resolve, reject) => { + const walletAddresses: WalletAddress[] = []; + const payload = { + purposes: ['payment'] as AddressPurpose[], + message: 'Welcome to the Powpeg app, please select your Bitcoin account to start.', + network: { + type: this.satsBtcNetwork, + }, + }; + Wallet.request('getAddresses', payload) + .then((response) => { + if (response.status === 'error') { + reject(new Error(response.error.message)); + } else { + response.result.addresses + .forEach((addr: { address: string; publicKey: string; }) => { + walletAddresses.push({ + address: addr.address, + publicKey: addr.publicKey, + derivationPath: '', + }); + }); + } + resolve(walletAddresses); + }) + .catch(reject); + }); + } + + sign(tx: Tx): Promise { + const xverseTx = tx as XverseTx; + return new Promise((resolve, reject) => { + const signInputs: Record = {}; + xverseTx.inputs.forEach((input: { address: string; idx: number; }, inputIdx: number) => { + if (signInputs[input.address]) { + signInputs[input.address].push(inputIdx); + } else { + signInputs[input.address] = [inputIdx]; + } + }); + const signPsbtOptions = { + psbt: xverseTx.base64UnsignedPsbt, + signInputs, + broadcast: false, + }; + Wallet.request('signPsbt', signPsbtOptions) + .then((response) => { + if (response.status === 'error') { + reject(new Error(response.error.message)); + } else { + const signedPsbt = bitcoin.Psbt.fromBase64(response.result.psbt as string); + if (!signedPsbt.validateSignaturesOfAllInputs()) { + reject(new Error('Invalid signature provided')); + } else { + resolve({ + signedTx: signedPsbt.finalizeAllInputs().extractTransaction().toHex(), + }); + } + } + }) + .catch(() => reject(new Error('Invalid psbt provided'))); + }); + } + + isConnected(): Promise { + return Promise.resolve(true); + } + + reconnect(): Promise { + return new Promise((resolve, reject) => { + this.getAccountAddresses() + .then(() => resolve()) + .catch(reject); + }); + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + getXpub(accountType: BtcAccount, accountNumber: number): Promise { + throw new Error('Method not supported.'); + } + + areEnoughUnusedAddresses(): boolean { + return this.addressesToFetch.segwit.lastIndex >= 1; + } + + availableAccounts(): BtcAccount[] { + return [constants.BITCOIN_SEGWIT_ADDRESS]; + } + + name(): Record<'formal_name' | 'short_name' | 'long_name', string> { + return constants.WALLET_NAMES.XVERSE; + } + + confirmationSteps(): Step[] { + return [ + { + title: 'Transaction information', + subtitle: '', + outputsToshow: { + opReturn: { + value: false, + amount: true, + }, + change: { + address: true, + amount: true, + }, + federation: { + address: true, + amount: true, + }, + }, + fullAmount: false, + fee: true, + }, + ]; + } +} diff --git a/src/common/services/index.ts b/src/common/services/index.ts index 17c102547..be5b73a3a 100644 --- a/src/common/services/index.ts +++ b/src/common/services/index.ts @@ -4,3 +4,4 @@ export { default as TrezorService } from './TrezorService'; export { default as LedgerService } from './LedgerService'; export { default as LeatherService } from './LeatherService'; export { default as FlyoverService } from './FlyoverService'; +export { default as XverseService } from './XverseService'; diff --git a/src/common/store/constants.ts b/src/common/store/constants.ts index a7796c314..c4b4ec06d 100644 --- a/src/common/store/constants.ts +++ b/src/common/store/constants.ts @@ -3,6 +3,7 @@ export const WALLET_NAMES = { TREZOR: { formal_name: 'Trezor', short_name: 'trezor', long_name: 'WALLET_TREZOR' }, METAMASK: { formal_name: 'Metamask', short_name: 'metamask', long_name: 'WALLET_METAMASK' }, LEATHER: { formal_name: 'Leather', short_name: 'leather', long_name: 'WALLET_LEATHER' }, + XVERSE: { formal_name: 'XVerse', short_name: 'xverse', long_name: 'WALLET_XVERSE' }, } as const; export const OPERATION_TYPE = 'OPERATION_TYPE'; @@ -261,6 +262,7 @@ export const STATUS_CLEAR = 'STATUS_CLEAR'; export const PEGOUT_TX_ADD_BITCOIN_PRICE = 'PEGOUT_TX_ADD_BITCOIN_PRICE'; export const STATUS_GET_ESTIMATED_FEE = 'STATUS_GET_ESTIMATED_FEE'; export const STATUS_GET_ESTIMATED_RELEASE_TIME_IN_MINUTES = 'STATUS_GET_ESTIMATED_RELEASE_TIME_IN_MINUTES'; +export const STATUS_GET_FLYOVER_STATUS = 'STATUS_GET_FLYOVER_STATUS'; // Status mutations export const STATUS_SET_TX_DETAILS = 'STATUS_SET_TX_DETAILS'; @@ -268,6 +270,7 @@ export const STATUS_SET_TX_TYPE = 'STATUS_SET_TX_TYPE'; export const STATUS_SET_CLEAR = 'STATUS_SET_CLEAR'; export const STATUS_SET_BTC_ESTIMATED_FEE = 'STATUS_SET_BTC_ESTIMATED_FEE'; export const STATUS_SET_ESTIMATED_RELEASE_TIME_IN_MINUTES = 'STATUS_SET_ESTIMATED_RELEASE_TIME_IN_MINUTES'; +export const STATUS_SET_FLYOVER_STATUS = 'STATUS_SET_FLYOVER_STATUS'; // Status getters export const STATUS_IS_REJECTED = 'STATUS_IS_REJECTED'; @@ -290,7 +293,8 @@ export enum PegStatus { export enum FlyoverStatus { PENDING = 'PENDING', - COMPLETED = 'COMPLETED', + SUCCESS = 'SUCCESS', + FAILED = 'FAILED', } export const LEDGER_STATUS_CODES = { diff --git a/src/common/types/Common.ts b/src/common/types/Common.ts index fa5c5b291..a7a7613f6 100644 --- a/src/common/types/Common.ts +++ b/src/common/types/Common.ts @@ -109,6 +109,7 @@ export interface PsbtExtendedInput { value: number; script: Buffer; }; + redeemScript?: Buffer; } export interface NormalizedSummary { @@ -125,6 +126,7 @@ export interface NormalizedSummary { federationAddress?: string; total?: string; status?: PegStatus | PegoutStatus; + btcTxId?: string; } export type AddressType = 'BITCOIN_LEGACY_ADDRESS' | 'BITCOIN_SEGWIT_ADDRESS' | 'BITCOIN_NATIVE_SEGWIT_ADDRESS' | @@ -140,3 +142,8 @@ export enum AppLocale { LOCALE_EN = 'en', LOCALE_ES = 'es', } + +export interface XverseTx extends Tx { + base64UnsignedPsbt: string; + inputs: Array<{idx: number; address: string}>; +} diff --git a/src/common/types/TxInfo.ts b/src/common/types/TxInfo.ts index 18dc876a5..8ac804235 100644 --- a/src/common/types/TxInfo.ts +++ b/src/common/types/TxInfo.ts @@ -10,4 +10,5 @@ export interface TxInfo { btcEstimatedFee?: number; provider?: string; details?: Record; + quoteHash?: string; } diff --git a/src/common/types/pegInTx.ts b/src/common/types/pegInTx.ts index 601ecc39e..a35980eec 100644 --- a/src/common/types/pegInTx.ts +++ b/src/common/types/pegInTx.ts @@ -7,7 +7,7 @@ export type BtcAccount = 'BITCOIN_LEGACY_ADDRESS' | 'BITCOIN_SEGWIT_ADDRESS' | 'BITCOIN_NATIVE_SEGWIT_ADDRESS'; -export type BtcWallet = 'WALLET_LEDGER' | 'WALLET_TREZOR' | 'WALLET_LEATHER'; +export type BtcWallet = 'WALLET_LEDGER' | 'WALLET_TREZOR' | 'WALLET_LEATHER' | 'WALLET_XVERSE'; export type MiningSpeedFee = 'BITCOIN_SLOW_FEE_LEVEL' | 'BITCOIN_AVERAGE_FEE_LEVEL' | diff --git a/src/common/types/store.ts b/src/common/types/store.ts index b67a43e60..345f1b6c6 100644 --- a/src/common/types/store.ts +++ b/src/common/types/store.ts @@ -3,13 +3,19 @@ import { PegStatus } from '@/common/store/constants'; import SatoshiBig from '@/common/types/SatoshiBig'; import { PegInTxState } from '@/common/types/pegInTx'; import { SessionState } from '@/common/types/session'; -import { PegOutTxState } from './pegOutTx'; +import { PegOutTxState } from '@/common/types/pegOutTx'; +import { FlyoverPeginState } from '@/common/types/FlyoverPegin'; +import { FlyoverPegoutState } from '@/common/types/FlyoverPegout'; +import { StatusState } from '@/common/types/Status'; export interface RootState { pegInTx?: PegInTxState, web3Session?: SessionState, pegOutTx?: PegOutTxState, version: string; + status?: StatusState; + flyoverPegin?: FlyoverPeginState; + flyoverPegout?: FlyoverPegoutState; } export interface BtcPeginStatus { @@ -66,6 +72,7 @@ export interface PegoutStatusDataModel { btcRawTransaction: string; fees: number; estimatedFee: SatoshiBig; + btcTxId: string; } export interface FlyoverStatusModel { @@ -78,6 +85,7 @@ export interface FlyoverStatusModel { status: string; senderAddress: string; recipientAddress: string; + quoteHash: string; } export enum TxStatusType { @@ -95,4 +103,5 @@ export interface TxStatus { type: TxStatusType; pegOutEstimatedFee: SatoshiBig; estimatedReleaseTimeInMinutes: Duration; + flyoverStatus?: string; } diff --git a/src/common/utils/btcAddressUtils.ts b/src/common/utils/btcAddressUtils.ts index 73ea16682..f013f8dce 100644 --- a/src/common/utils/btcAddressUtils.ts +++ b/src/common/utils/btcAddressUtils.ts @@ -52,3 +52,17 @@ export function validateAddress(address: string): {valid: boolean; addressType: } return { valid, addressType }; } + +function compressPublicKey(pubKey: string) { + const { publicKey } = bitcoin.ECPair.fromPublicKey(Buffer.from(pubKey, 'hex')); + return publicKey.toString('hex'); +} + +export function getP2SHRedeemScript(publicKey: string, network: bitcoin.Network) { + const pubkey = compressPublicKey(publicKey); + const pair = bitcoin.ECPair.fromPublicKey(Buffer.from(pubkey, 'hex')); + const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: pair.publicKey, network }); + const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network }); + const redeem = p2sh.redeem?.output; + return redeem; +} diff --git a/src/common/utils/utils.ts b/src/common/utils/utils.ts index cccd51d6c..0de917604 100644 --- a/src/common/utils/utils.ts +++ b/src/common/utils/utils.ts @@ -73,7 +73,7 @@ export function getRskAddressExplorerUrl(address: string) { return `${getRskBaseExplorerUrl()}/address/${address}`; } -export function getEstimatedFee(): Promise { +export function getEstimatedFee(pegoutAlreadyRequested = false): Promise { return new Promise((resolve, reject) => { const bridgeService = new BridgeService(); Promise.all([ @@ -81,6 +81,11 @@ export function getEstimatedFee(): Promise { bridgeService.getQueuedPegoutsCount(), ]) .then(([nextPegoutCost, pegoutQueueCount]) => { + if (pegoutAlreadyRequested && pegoutQueueCount !== 0n) { + const currentEstimatedFee = nextPegoutCost / pegoutQueueCount; + resolve(new SatoshiBig(currentEstimatedFee, 'satoshi')); + return; + } const estimatedFee = nextPegoutCost / (pegoutQueueCount + 1n); resolve(new SatoshiBig(estimatedFee, 'satoshi')); }) @@ -194,7 +199,7 @@ export function setStatusMessage(txType: string, status: string): TxStatusMessag activeMessageStyle = 'statusProgress'; isRejected = false; break; - case constants.FlyoverStatus.COMPLETED: + case constants.FlyoverStatus.SUCCESS: statusMessage = 'Your transaction was successfully processed!'; activeMessageStyle = 'statusSuccess'; isRejected = false; @@ -209,7 +214,7 @@ export function setStatusMessage(txType: string, status: string): TxStatusMessag activeMessageStyle = 'statusProgress'; isRejected = false; break; - case constants.FlyoverStatus.COMPLETED: + case constants.FlyoverStatus.SUCCESS: statusMessage = 'Your transaction was successfully processed!'; activeMessageStyle = 'statusSuccess'; isRejected = false; diff --git a/src/common/views/Home.vue b/src/common/views/Home.vue index 4ce377150..dc5bea984 100644 --- a/src/common/views/Home.vue +++ b/src/common/views/Home.vue @@ -62,10 +62,13 @@
Already made a transaction? - + Transaction Status +
To learn about the various RBTC access methods, visit @@ -98,7 +101,9 @@ diff --git a/src/pegout/components/FlyoverPegout.vue b/src/pegout/components/FlyoverPegout.vue index 501c0d95b..55ae624d4 100644 --- a/src/pegout/components/FlyoverPegout.vue +++ b/src/pegout/components/FlyoverPegout.vue @@ -110,7 +110,7 @@ import { import { mdiArrowLeft, mdiArrowRight } from '@mdi/js'; import { FlyoverPegoutState, ObjectDifference, PegOutTxState, QuotePegOut2WP, - SatoshiBig, TxStatusType, WeiBig, + SatoshiBig, TxInfo, TxStatusType, WeiBig, } from '@/common/types'; import { appendRecaptcha, Machine, ServiceError, validateAddress, @@ -136,8 +136,7 @@ export default defineComponent({ required: true, }, }, - setup(props, context) { - const nextPage = 'Confirmation'; + setup(props) { const showTxErrorDialog = ref(false); const txError = ref(new ServiceError('', '', '', '')); const environmentContext = EnvironmentContextProviderService.getEnvironmentContext(); @@ -264,7 +263,6 @@ export default defineComponent({ : pegOutTxState.value.txHash, }, }); - context.emit('changePage', nextPage); } function getLPName(): string { @@ -280,7 +278,7 @@ export default defineComponent({ .toRBTCTrimmedString(); } - const registerFlyover = computed(() => ({ + const registerFlyover = computed(() => ({ sessionId: '', txHash: flyoverPegoutState.value.txHash as string, type: TxStatusType.PEGOUT.toLowerCase(), @@ -294,6 +292,7 @@ export default defineComponent({ recipientAddress: flyoverPegoutState.value.btcRecipientAddress, blocksToCompleteTransaction: selectedQuote.value.quote.depositConfirmations, }, + quoteHash: selectedQuote.value.quoteHash, })); const registerPegout = computed(() => ({ diff --git a/src/pegout/views/PegOut.vue b/src/pegout/views/PegOut.vue index bcd5ad695..619a87980 100644 --- a/src/pegout/views/PegOut.vue +++ b/src/pegout/views/PegOut.vue @@ -15,13 +15,11 @@ import FlyoverPegout from '@/pegout/components/FlyoverPegout.vue'; import { Machine } from '@/common/utils'; import { useAction, useGetter } from '@/common/store/helper'; import { Feature, FeatureNames } from '@/common/types'; -import Confirmation from '../components/Confirmation.vue'; export default defineComponent({ name: 'PegOut', components: { PegOutForm, - Confirmation, FlyoverPegout, }, setup() { diff --git a/src/registerServiceWorker.ts b/src/registerServiceWorker.ts new file mode 100644 index 000000000..e2aba3d3f --- /dev/null +++ b/src/registerServiceWorker.ts @@ -0,0 +1,45 @@ +/* eslint-disable no-console */ + +import { register } from 'register-service-worker'; + +if (process.env.NODE_ENV === 'production') { + register(`${process.env.BASE_URL}service-worker.js`, { + ready(registration) { + if ('periodicSync' in registration) { + navigator.permissions.query({ name: 'periodic-background-sync' as PermissionName }) + .then((permission) => { + if (permission.state === 'granted') { + // @ts-expect-error not periodicsync ts support + registration.periodicSync.register('update-txs', { minInterval: 1000 * 60 * 60 }); // 1 hour + } + }) + .catch((error) => { + console.error('Periodic Sync registration failed', error); + }); + } + Notification.requestPermission().then((permission) => { + if (permission === 'granted') { + console.log('Notification permission granted.'); + } + }); + }, + registered() { + console.log('Service worker has been registered.'); + }, + cached() { + console.log('Content has been cached for offline use.'); + }, + updatefound() { + console.log('New content is downloading.'); + }, + updated() { + console.log('New content is available; please refresh.'); + }, + offline() { + console.log('No internet connection found. App is running in offline mode.'); + }, + error(error) { + console.error('Error during service worker registration:', error); + }, + }); +} diff --git a/src/service-worker.ts b/src/service-worker.ts new file mode 100644 index 000000000..c271bcec2 --- /dev/null +++ b/src/service-worker.ts @@ -0,0 +1,57 @@ +import { precacheAndRoute } from 'workbox-precaching'; +import { getMany, set } from './db'; + +// workaround to access service worker global scope via self +declare const self: ServiceWorkerGlobalScope; + +// eslint-disable-next-line no-underscore-dangle +precacheAndRoute(self.__WB_MANIFEST); + +async function updateView() { + self.clients.matchAll().then((clients) => { + clients.forEach((client) => { + client.postMessage('update-view'); + }); + }); +} + +async function getUpdatedStatuses() { + // get txs from db + const txs = await getMany(); + // fetch updated statuses + const updatedTxs = await Promise.all(txs.map((tx) => fetch(`${process.env.VUE_APP_API_BASE_URL}/tx-status/${tx.txId}`))); + // create updated txs to store in db + const updatedTxsToStore = await Promise.all(updatedTxs.map(async (tx) => { + const { type, txDetails } = await tx.json(); + if (type === 'PEGIN') { + return { + txId: txDetails.btc.txId, + status: txDetails.status, + }; + } + if (type === 'PEGOUT') { + return { + txId: txDetails.originatingRskTxHash, + status: txDetails.status, + }; + } + return { + txId: '', + status: '', + }; + })); + // store updated txs in db + await Promise.all(updatedTxsToStore.map((tx) => set(tx))); + + if (updatedTxsToStore.length > 0) { + await updateView(); + } +} + +self.addEventListener('periodicsync', (event) => { + // @ts-expect-error not periodicsync ts support + if (event.tag === 'update-txs') { + // @ts-expect-error not periodicsync ts support + event.waitUntil(getUpdatedStatuses()); + } +}); diff --git a/src/status/store/actions.ts b/src/status/store/actions.ts index e40aff762..981f0cfa4 100644 --- a/src/status/store/actions.ts +++ b/src/status/store/actions.ts @@ -2,6 +2,7 @@ import { ActionTree } from 'vuex'; import Web3 from 'web3'; import moment from 'moment'; import { + FlyoverStatusModel, PegoutStatusDataModel, RootState, SatoshiBig, TxStatus, TxStatusType, } from '@/common/types'; @@ -10,29 +11,43 @@ import * as constants from '@/common/store/constants'; import { ApiService } from '@/common/services'; import { BridgeService } from '@/common/services/BridgeService'; import { getEstimatedFee } from '@/common/utils'; +import { set } from '@/db'; export const actions: ActionTree = { [constants.STATUS_CLEAR]: ({ commit }) => { commit(constants.STATUS_SET_CLEAR); }, - [constants.STATUS_GET_TX_STATUS]: ({ commit, dispatch }, txId: string) => { - Promise.all([ - ApiService.getTxStatus(txId), - dispatch(constants.STATUS_GET_ESTIMATED_FEE), - ]) - .then(([status]) => { - commit(constants.STATUS_SET_TX_DETAILS, status.txDetails); - commit(constants.STATUS_SET_TX_TYPE, status.type); - return dispatch(constants.STATUS_GET_ESTIMATED_RELEASE_TIME_IN_MINUTES); - }) - .catch(() => { - commit(constants.STATUS_SET_TX_DETAILS, undefined); - commit(constants.STATUS_SET_TX_TYPE, TxStatusType.UNEXPECTED_ERROR); - }); - }, + [constants.STATUS_GET_TX_STATUS]: + ({ commit, dispatch }, txId: string) => new Promise((resolve, reject) => { + Promise.all([ + ApiService.getTxStatus(txId), + dispatch(constants.STATUS_GET_ESTIMATED_FEE), + ]) + .then(([status]) => { + commit(constants.STATUS_SET_TX_DETAILS, status.txDetails); + commit(constants.STATUS_SET_TX_TYPE, status.type); + set({ txId, status: status.txDetails?.status ?? 'UNKNOWN' }); + const nextActions = []; + if (status.type === TxStatusType.FLYOVER_PEGIN + || status.type === TxStatusType.FLYOVER_PEGOUT) { + nextActions.push(dispatch( + constants.STATUS_GET_FLYOVER_STATUS, + (status.txDetails as FlyoverStatusModel).quoteHash, + )); + } + nextActions.push(dispatch(constants.STATUS_GET_ESTIMATED_RELEASE_TIME_IN_MINUTES)); + return Promise.all(nextActions); + }) + .then(resolve) + .catch(() => { + commit(constants.STATUS_SET_TX_DETAILS, undefined); + commit(constants.STATUS_SET_TX_TYPE, TxStatusType.UNEXPECTED_ERROR); + reject(); + }); + }), [constants.STATUS_GET_ESTIMATED_FEE]: async ({ commit }) => { try { - const estimatedFee = await getEstimatedFee(); + const estimatedFee = await getEstimatedFee(true); commit(constants.STATUS_SET_BTC_ESTIMATED_FEE, new SatoshiBig(estimatedFee, 'satoshi')); } catch (e) { commit(constants.STATUS_SET_BTC_ESTIMATED_FEE, new SatoshiBig(0, 'satoshi')); @@ -64,4 +79,28 @@ export const actions: ActionTree = { } resolve(); }), + [constants.STATUS_GET_FLYOVER_STATUS]: async ({ + state, commit, dispatch, rootState, + }, quoteHash) => { + let status; + try { + if (state.type === TxStatusType.FLYOVER_PEGIN) { + const flyoverService = rootState.flyoverPegin?.flyoverService; + await dispatch(`flyoverPegin/${constants.FLYOVER_PEGIN_INIT}`, null, { root: true }); + flyoverService?.useLiquidityProvider(1); + status = await flyoverService?.getPeginStatus(quoteHash); + } + if (state.type === TxStatusType.FLYOVER_PEGOUT) { + const flyoverService = rootState.flyoverPegout?.flyoverService; + await dispatch(`flyoverPegout/${constants.FLYOVER_PEGOUT_INIT}`, null, { root: true }); + await dispatch(`flyoverPegout/${constants.FLYOVER_PEGOUT_GET_PROVIDERS}`, null, { root: true }); + flyoverService?.useLiquidityProvider(1); + status = await rootState.flyoverPegout?.flyoverService.getPegoutStatus(quoteHash); + } + } catch (e) { + status = 'NOT_FOUND'; + } finally { + commit(constants.STATUS_SET_FLYOVER_STATUS, status); + } + }, }; diff --git a/src/status/store/mutations.ts b/src/status/store/mutations.ts index 433bc1a9d..bf58e2859 100644 --- a/src/status/store/mutations.ts +++ b/src/status/store/mutations.ts @@ -26,4 +26,7 @@ export const mutations: MutationTree = { (state: TxStatus, releaseTime: Duration) => { state.estimatedReleaseTimeInMinutes = releaseTime; }, + [constants.STATUS_SET_FLYOVER_STATUS]: (state, status) => { + state.flyoverStatus = status; + }, }; diff --git a/src/status/views/Status.vue b/src/status/views/Status.vue index 531e7875a..ef3e99878 100644 --- a/src/status/views/Status.vue +++ b/src/status/views/Status.vue @@ -18,7 +18,7 @@ Estimated time: {{ releaseTimeText }} - + + + + Searching... + + + + + Last transactions + + + + Transaction ID + Status + + + + + + + {{ tx.txId }} + + + + + {{ tx.status }} + + + + + @@ -34,7 +70,7 @@ import { computed, ref, watch, defineComponent, onUnmounted, } from 'vue'; import { useRoute, useRouter } from 'vue-router'; -import { mdiMagnify } from '@mdi/js'; +import { mdiMagnify, mdiOpenInNew } from '@mdi/js'; import TxPegout from '@/common/components/status/TxPegout.vue'; import TxPegin from '@/common/components/status/TxPegin.vue'; import { @@ -48,6 +84,8 @@ import { } from '@/common/store/helper'; import StatusProgressBar from '@/common/components/status/StatusProgressBar.vue'; import { PegStatus } from '@/common/store/constants'; +import { getBtcTxExplorerUrl, getRskTxExplorerUrl } from '@/common/utils'; +import { getMany } from '@/db'; export default defineComponent({ name: 'StatusSearch', @@ -149,6 +187,11 @@ export default defineComponent({ loading.value = false; } + const lastTxs = ref(); + async function getLastTxs() { + lastTxs.value = await getMany(); + } + function getPegStatus() { if (!isValidTxId.value) clean(); else if (route.path !== `/status/txId/${txId.value}`) { @@ -160,12 +203,18 @@ export default defineComponent({ clean(); loading.value = true; setTxStatus(txId.value) + .then(getLastTxs) .then(() => { loading.value = false; }); } } + function searchTx(id: string) { + txId.value = id; + getPegStatus(); + } + function onUrlChange() { if (props.txIdProp) { txId.value = props.txIdProp ?? ''; @@ -179,9 +228,26 @@ export default defineComponent({ router.replace({ name: 'Home' }); } + function getExplorerUrl(id: string) { + let url = ''; + if (id.startsWith('0x')) { + url = getRskTxExplorerUrl(id); + } else { + url = getBtcTxExplorerUrl(id); + } + return url; + } + watch(route, onUrlChange, { immediate: true, deep: true }); clearStatus(); + getLastTxs(); + + navigator.serviceWorker.addEventListener('message', async (evt) => { + if (evt.data === 'update-view') { + await getLastTxs(); + } + }); onUnmounted(clean); @@ -204,6 +270,10 @@ export default defineComponent({ rules, txWithErrorType, txWithError, + lastTxs, + mdiOpenInNew, + getExplorerUrl, + searchTx, }; }, }); diff --git a/src/vuex.d.ts b/src/vuex.d.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/webworker.d.ts b/src/webworker.d.ts new file mode 100644 index 000000000..a55366736 --- /dev/null +++ b/src/webworker.d.ts @@ -0,0 +1,6 @@ +interface Navigator { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/clearAppBadge) */ + clearAppBadge(): Promise; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/setAppBadge) */ + setAppBadge(contents?: number): Promise; +} diff --git a/tests/unit/common/services/FlyoverService.spec.ts b/tests/unit/common/services/FlyoverService.spec.ts index d4329493d..d04ad3444 100644 --- a/tests/unit/common/services/FlyoverService.spec.ts +++ b/tests/unit/common/services/FlyoverService.spec.ts @@ -1,9 +1,10 @@ import FlyoverService from '@/common/services/FlyoverService'; import { EnvironmentAccessorService } from '@/common/services/enviroment-accessor.service'; import { SatoshiBig, WeiBig } from '@/common/types'; -import { Flyover } from '@rsksmart/flyover-sdk'; +import { Flyover, FlyoverUtils } from '@rsksmart/flyover-sdk'; import * as constants from '@/common/store/constants'; import sinon from 'sinon'; +import { ServiceError } from '@/common/utils'; describe('FlyoverService', () => { let flyoverService: FlyoverService; @@ -128,8 +129,6 @@ describe('FlyoverService', () => { expect(provider).toHaveProperty('id'); expect(provider).toHaveProperty('name'); }); - - test.todo('should handle errors when fetching providers'); }); describe('getPegoutQuotes', () => { @@ -324,6 +323,7 @@ describe('FlyoverService', () => { const btcRefundAddress = 'n2y5V6LYszsrsxkMdMypL98YQxtBoLCXdc'; const btcRecipientAddress = 'n2y5V6LYszsrsxkMdMypL98YQxtBoLCXdc'; const valueToTransfer = new WeiBig('0.005', 'rbtc'); + const expectedTotalAmount = 5255689215476000n; const quotes = await flyoverService.getPegoutQuotes( rskRefundAddress, @@ -341,7 +341,28 @@ describe('FlyoverService', () => { expect(acceptedQuote).toBe('txHash'); expect(spyAcceptPegoutQuote).toHaveBeenCalled(); expect(spyIsValidAcceptedQuote).toHaveBeenCalled(); - expect(spyDepositPegout).toHaveBeenCalledWith(flyoverService['pegoutQuotes'][0], 'signature', 5255689215476000n); + expect(spyDepositPegout).toHaveBeenCalledWith(flyoverService['pegoutQuotes'][0], 'signature', expectedTotalAmount); + expect(FlyoverUtils.getQuoteTotal(flyoverService['pegoutQuotes'][0])).toEqual(expectedTotalAmount); + }); + }); + + describe('getAvailableLiquidity', () => { + it('should return the available liquidity', async () => { + const stubedInstance = sinon.createStubInstance(Flyover); + flyoverService.flyover = stubedInstance; + stubedInstance.getAvailableLiquidity.resolves({ + peginLiquidityAmount: 1000000000000000000n, + pegoutLiquidityAmount: 1000000000000000000n, + }); + const liquidity = await flyoverService.getAvailableLiquidity(); + expect(liquidity.peginLiquidity).toBeInstanceOf(WeiBig); + expect(liquidity.pegoutLiquidity).toBeInstanceOf(SatoshiBig); + }); + it('should throw an error if the available liquidity is not found', async () => { + const stubedInstance = sinon.createStubInstance(Flyover); + flyoverService.flyover = stubedInstance; + stubedInstance.getAvailableLiquidity.rejects(); + await expect(flyoverService.getAvailableLiquidity()).rejects.toThrowError(ServiceError); }); }); }); diff --git a/tests/unit/common/services/XverseService.spec.ts b/tests/unit/common/services/XverseService.spec.ts new file mode 100644 index 000000000..ac61192e1 --- /dev/null +++ b/tests/unit/common/services/XverseService.spec.ts @@ -0,0 +1,140 @@ +import { EnvironmentAccessorService } from '@/common/services/enviroment-accessor.service'; +import * as constants from '@/common/store/constants'; +import sinon from 'sinon'; +import Wallet, { AddressPurpose, AddressType } from 'sats-connect'; +import { WalletService, XverseService } from '@/common/services'; + +const initEnvironment = () => { + const defaultEnvironmentVariables = { + vueAppCoin: constants.BTC_NETWORK_TESTNET, + vueAppManifestAppUrl: '', + vueAppManifestEmail: '', + vueAppWalletAddressPerCall: 5, + vueAppWalletAddressHardStop: 100, + }; + EnvironmentAccessorService.initializeEnvironmentVariables(defaultEnvironmentVariables); +}; + +describe('Xverse Service:', () => { + // let request: sinon.SinonStub<[XverseRequestArgs], Promise>; + // let mockedXverseProvider: sinon.SinonStubbedInstance; + + beforeEach(initEnvironment); + afterEach(() => sinon.restore()); + + it('should create a XverseService instance', () => { + const xverseService = new XverseService(); + expect(xverseService).toBeInstanceOf(XverseService); + expect(xverseService).toBeInstanceOf(WalletService); + }); + + it('should return a single address since that is the current amount supported by xverse', () => { + sinon.stub(Wallet, 'request').resolves({ + status: 'success', + result: { + addresses: [ + { + address: 'testAddress', + publicKey: 'testPublicKey', + purpose: AddressPurpose.Payment, + addressType: AddressType.p2pkh, + }, + ], + }, + }); + const xverseService = new XverseService(); + xverseService.getAccountAddresses().then((addresses) => { + expect(addresses.length).toBe(1); + expect(addresses[0].address).toBe('testAddress'); + expect(addresses[0].publicKey).toBe('testPublicKey'); + }); + }); + + it('should handle the error case when the wallet are not available', () => { + sinon.stub(Wallet, 'request').resolves({ + status: 'error', + error: { + code: 1, + message: 'Wallet not available', + }, + }); + const xverseService = new XverseService(); + expect(xverseService.getAccountAddresses()) + .rejects + .toThrow('Wallet not available'); + }); + + it('should return an error when the psbt are wrong', () => { + sinon.stub(Wallet, 'request').resolves({ + status: 'success', + result: { + psbt: 'cHNidP8BAHECAAAAAW4TCBaK74DxafvrRdWpF32Gg5eVRs1DJX9YHz2v9jduAQAAAAD9', + }, + }); + const xverseService = new XverseService(); + const xverseTx = { + coin: 'test', + inputs: [ + { + addres: '2Mxv1YkAXpTMcq2at1it9QRfq8bDX82N99J', + idx: 2, + }, + ], + outputs: [ + { + amount: '0', + op_return_data: '52534b5401aFf12FA1c482BEab1D70C68fe0Fc5825447A9818', + }, + { + address: '2N3JQb9erL1SnAr3NTMrZiPQQ8dcjJp4idV', + amount: '500000', + }, + { + address: '2Mxv1YkAXpTMcq2at1it9QRfq8bDX82N99J', + amount: '982474', + }, + ], + base64UnsignedPsbt: 'cHNidP8BAJcCAAAAAboaf2woNcottY/Ax+9lbYi349++WmdwYZPyOp8nXg5tAgAAAAD/////AwAAAAAAAAAAG2oZUlNLVAGv8S+hxIK+qx1wxo/g/FglRHqYGCChBwAAAAAAF6kUbkta6F2G5NsObl2wn4wnYyjNvz+Hyv0OAAAAAAAXqRQ+Lnd+D2z9GnchcMB/v3/pWn8CfYcAAAAAAAEBIL60FgAAAAAAF6kUPi53fg9s/Rp3IXDAf79/6Vp/An2HAQQWABSmO24c7Zf0uweZC7P9rNOrMR7sqwAAAAA=', + }; + expect(xverseService.sign(xverseTx)) + .rejects + .toThrow('Invalid psbt provided'); + }); + + it('should return an error when the psbt has some unsigned input', () => { + sinon.stub(Wallet, 'request').resolves({ + status: 'success', + result: { + psbt: 'cHNidP8BAJcCAAAAAboaf2woNcottY/Ax+9lbYi349++WmdwYZPyOp8nXg5tAgAAAAD/////AwAAAAAAAAAAG2oZUlNLVAGv8S+hxIK+qx1wxo/g/FglRHqYGCChBwAAAAAAF6kUbkta6F2G5NsObl2wn4wnYyjNvz+Hyv0OAAAAAAAXqRQ+Lnd+D2z9GnchcMB/v3/pWn8CfYcAAAAAAAEBIL60FgAAAAAAF6kUPi53fg9s/Rp3IXDAf79/6Vp/An2HAQQWABSmO24c7Zf0uweZC7P9rNOrMR7sqwAAAAA=', + }, + }); + const xverseService = new XverseService(); + const xverseTx = { + coin: 'test', + inputs: [ + { + addres: '2Mxv1YkAXpTMcq2at1it9QRfq8bDX82N99J', + idx: 2, + }, + ], + outputs: [ + { + amount: '0', + op_return_data: '52534b5401aFf12FA1c482BEab1D70C68fe0Fc5825447A9818', + }, + { + address: '2N3JQb9erL1SnAr3NTMrZiPQQ8dcjJp4idV', + amount: '500000', + }, + { + address: '2Mxv1YkAXpTMcq2at1it9QRfq8bDX82N99J', + amount: '982474', + }, + ], + base64UnsignedPsbt: 'cHNidP8BAJcCAAAAAboaf2woNcottY/Ax+9lbYi349++WmdwYZPyOp8nXg5tAgAAAAD/////AwAAAAAAAAAAG2oZUlNLVAGv8S+hxIK+qx1wxo/g/FglRHqYGCChBwAAAAAAF6kUbkta6F2G5NsObl2wn4wnYyjNvz+Hyv0OAAAAAAAXqRQ+Lnd+D2z9GnchcMB/v3/pWn8CfYcAAAAAAAEBIL60FgAAAAAAF6kUPi53fg9s/Rp3IXDAf79/6Vp/An2HAQQWABSmO24c7Zf0uweZC7P9rNOrMR7sqwAAAAA=', + }; + expect(xverseService.sign(xverseTx)) + .rejects + .toThrow('Invalid psbt provided'); + }); +}); diff --git a/tests/unit/pegin/services/components/XverseTxBuilder.spec.ts b/tests/unit/pegin/services/components/XverseTxBuilder.spec.ts new file mode 100644 index 000000000..32552f841 --- /dev/null +++ b/tests/unit/pegin/services/components/XverseTxBuilder.spec.ts @@ -0,0 +1,182 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import { ApiService } from '@/common/services'; +import store from '@/common/store'; +import * as constants from '@/common/store/constants'; +import XverseTxBuilder from '@/pegin/middleware/TxBuilder/XverseTxBuilder'; +import { NormalizedTx, NormalizedInput } from '@/common/types'; +import axios, { AxiosHeaders, AxiosResponse } from 'axios'; +import { EnvironmentAccessorService } from '@/common/services/enviroment-accessor.service'; + +const txHex1 = '01000000022d2d5d12644b7f46bd2c094eb663f074f1042fa0a522b59d338cedde83aa5661000000006b483045022100b247c5947c69ab0e6249c587e2792cc5b723a356f796d092b1c2493ed5a74d3a02203e72fc592318ed72b2537859e6d02d91c61da1f27fcb066a566ce20d87e90178012103cb3b06dff127665fc0173c4910b8c254924627cd27decaaf9771f0566b859fdefdffffff57497ac2292f1dec0baba43abbbb02059164309c5f384b64ac4a931c0ae96177010000006a473044022026fa68c558f028258a4f489ecbbe0c5457825f5f7bedaabbcac82b5a64793dc402202aa1996f62728adfe78e1b7b31481397b8bdb20b004b161c3f121a972660746b01210264f3f31d1a81ab1062fce2187dad0c0efb1cee194f5c1ca520bf0a1295df6ee5fdffffff01f44f05000000000017a914a8e241e997f18c2dc0611cc6cb2d889e17f34f378700000000'; + +function getTxHex(expectedHex: string): Promise { + return new Promise((resolve) => { + resolve( + { + data: { hex: expectedHex }, + status: 200, + statusText: 'OK', + headers: {}, + config: { headers: new AxiosHeaders() }, + }, + ); + }); +} + +function setEnvironment() { + const defaultEnvironmentVariables = { + vueAppCoin: constants.BTC_NETWORK_TESTNET, + vueAppRskNodeHost: '', + vueAppApiBaseUrl: 'https://api.2wp.testnet.rootstock.io', + }; + EnvironmentAccessorService.initializeEnvironmentVariables(defaultEnvironmentVariables); +} + +describe('XverseTxBuilder', () => { + let xverseTxBuilder: XverseTxBuilder; + + beforeEach(() => { + setEnvironment(); + xverseTxBuilder = new XverseTxBuilder(); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('buildTx', () => { + it('should build a transaction successfully', async () => { + const normalizedTx: NormalizedTx = { + inputs: [ + { + address: '2N8eCZA1Su5ysSDKqDGSMNH8KgFi1L5jEYh', + prev_hash: 'c31556bf6a6b6c0a57387a88ad69a8cc7c159362d25d4870bffa3c005293375e', + prev_index: 0, + amount: '348148', + }, + ], + outputs: [ + { + address: '2N15XxmYFrp9e1cjCruQVNgYF3cuYQxvtqX', + amount: '1000', + }, + ], + coin: 'test', + }; + store.commit( + `pegInTx/${constants.PEGIN_TX_SET_ADDRESS_LIST}`, + [ + { + derivationPath: "m/49'/1'/0'/1/2", + address: '2N8eCZA1Su5ysSDKqDGSMNH8KgFi1L5jEYh', + publicKey: '02dc57829f1a5001646eb64edcecd797d5cbd0fcb24fb5a37d3084309a9201537c', + unused: false, + }, + { + derivationPath: "m/49'/1'/0'/0/3", + address: '2MzYn6qw7fbV7BtsoT6yBVV8nrbp37f6Uju', + publicKey: '0321afc4e7457e83aedecb1995ea2331d2aeff18a38f14ea710f35924d16d35a30', + unused: true, + }, + ], + ); + sinon.stub(axios, 'get').resolves(getTxHex(txHex1)); + + const result = await xverseTxBuilder.buildTx(normalizedTx); + + expect(result).to.have.property('coin'); + expect(result).to.have.property('inputs').that.is.an('array').with.lengthOf(1); + expect(result).to.have.property('outputs').that.is.an('array').with.lengthOf(1); + expect(result).to.have.property('base64UnsignedPsbt').that.is.a('string'); + }); + + it('should handle errors when building a transaction', async () => { + const normalizedTx: NormalizedTx = { + inputs: [ + { + address: '2N8eCZA1Su5ysSDKqDGSMNH8KgFi1L5jEYh', + prev_hash: 'c31556bf6a6b6c0a57387a88ad69a8cc7c159362d25d4870bffa3c005293375e', + prev_index: 0, + amount: '348148', + }, + ], + outputs: [ + { + address: '2N15XxmYFrp9e1cjCruQVNgYF3cuYQxvtqX', + amount: '1000', + }, + ], + coin: '', + }; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + sinon.stub(xverseTxBuilder, 'getExtendedInputs').rejects(new Error('Test error')); + + try { + await xverseTxBuilder.buildTx(normalizedTx); + } catch (error) { + expect(error).to.be.an('error').with.property('message', 'Test error'); + } + }); + }); + + describe('getExtendedInputs', () => { + it('should get extended inputs successfully', async () => { + const normalizedInputs: NormalizedInput[] = [ + { + address: '2N8eCZA1Su5ysSDKqDGSMNH8KgFi1L5jEYh', + prev_hash: 'c31556bf6a6b6c0a57387a88ad69a8cc7c159362d25d4870bffa3c005293375e', + prev_index: 0, + amount: '348148', + }, + ]; + store.commit( + `pegInTx/${constants.PEGIN_TX_SET_ADDRESS_LIST}`, + [ + { + derivationPath: "m/49'/1'/0'/1/2", + address: '2N8eCZA1Su5ysSDKqDGSMNH8KgFi1L5jEYh', + publicKey: '02dc57829f1a5001646eb64edcecd797d5cbd0fcb24fb5a37d3084309a9201537c', + unused: false, + }, + { + derivationPath: "m/49'/1'/0'/0/3", + address: '2MzYn6qw7fbV7BtsoT6yBVV8nrbp37f6Uju', + publicKey: '0321afc4e7457e83aedecb1995ea2331d2aeff18a38f14ea710f35924d16d35a30', + unused: true, + }, + ], + ); + sinon.stub(axios, 'get').resolves(getTxHex(txHex1)); + // eslint-disable-next-line dot-notation + const result = await xverseTxBuilder['getExtendedInputs'](normalizedInputs); + + expect(result).to.be.an('array').with.lengthOf(1); + expect(result[0]).to.have.property('hash', 'c31556bf6a6b6c0a57387a88ad69a8cc7c159362d25d4870bffa3c005293375e'); + expect(result[0]).to.have.property('index', 0); + expect(result[0]).to.have.property('witnessUtxo').that.is.an('object'); + expect(result[0]).to.have.property('redeemScript').that.is.an.instanceOf(Buffer); + }); + + it('should handle errors when getting extended inputs', async () => { + const normalizedInputs: NormalizedInput[] = [ + { + address: 'testAddress1', + prev_hash: 'testHash1', + prev_index: 0, + amount: '', + }, + ]; + + sinon.stub(ApiService, 'getTxHex').rejects(new Error('Tx not found')); + + try { + // eslint-disable-next-line dot-notation + await xverseTxBuilder['getExtendedInputs'](normalizedInputs); + } catch (error) { + expect(error).to.be.an('error').with.property('message', 'Tx not found'); + } + }); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 1e364344f..ed2281b44 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,7 +32,8 @@ "es6", "dom", "dom.iterable", - "scripthost" + "scripthost", + "webworker" ] }, "include": [ diff --git a/vue.config.js b/vue.config.js index aa177edd6..401be429c 100644 --- a/vue.config.js +++ b/vue.config.js @@ -5,6 +5,51 @@ const { defineConfig } = require('@vue/cli-service'); const { VuetifyPlugin } = require('webpack-plugin-vuetify'); module.exports = defineConfig({ + pwa: { + name: 'PowPeg', + themeColor: '#FF9800', + iconPaths: { + favicon32: 'img/icons/favicon-32x32.png', + favicon16: 'img/icons/favicon-16x16.png', + }, + manifestOptions: { + id: 'powpeg', + short_name: 'PowPeg', + description: 'Bridging Bitcoin and Rootstock', + start_url: '/', + icons: [ + { + purpose: 'any maskable', + sizes: '1024x1024', + src: 'img/icons/maskable_icon.png', + type: 'image/png', + }, + { + purpose: 'maskable', + sizes: '192x192', + src: 'img/icons/maskable_icon_x192.png', + type: 'image/png', + }, + { + purpose: 'maskable', + sizes: '384x384', + src: 'img/icons/maskable_icon_x384.png', + type: 'image/png', + }, + { + purpose: 'maskable', + sizes: '512x512', + src: 'img/icons/maskable_icon_x512.png', + type: 'image/png', + }, + ], + }, + workboxPluginMode: 'InjectManifest', + workboxOptions: { + swSrc: './src/service-worker.ts', + swDest: 'service-worker.js', + }, + }, transpileDependencies: true, configureWebpack: { resolve: {