diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..df1f181 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2023 Mutiny Wallet Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json index 7c827cf..36ca910 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "mws", - "version": "0.1.1", + "version": "0.2.0", + "license": "MIT", "scripts": { "dev": "solid-start dev", "build": "solid-start build", @@ -9,9 +10,9 @@ }, "type": "module", "devDependencies": { - "@types/node": "^18.16.5", - "@typescript-eslint/eslint-plugin": "^5.59.2", - "@typescript-eslint/parser": "^5.59.2", + "@types/node": "^18.16.6", + "@typescript-eslint/eslint-plugin": "^5.59.5", + "@typescript-eslint/parser": "^5.59.5", "autoprefixer": "^10.4.14", "esbuild": "^0.14.54", "eslint": "^8.40.0", @@ -32,7 +33,7 @@ "@kobalte/core": "^0.8.2", "@kobalte/tailwindcss": "^0.5.0", "@modular-forms/solid": "^0.13.2", - "@mutinywallet/mutiny-wasm": "^0.2.8", + "@mutinywallet/mutiny-wasm": "^0.3.0", "@mutinywallet/waila-wasm": "^0.1.5", "@solid-primitives/upload": "^0.0.111", "@solidjs/meta": "^0.28.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 846675e..de2dd85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,8 +11,8 @@ dependencies: specifier: ^0.13.2 version: 0.13.2(solid-js@1.7.5) '@mutinywallet/mutiny-wasm': - specifier: ^0.2.8 - version: 0.2.8 + specifier: ^0.3.0 + version: 0.3.0 '@mutinywallet/waila-wasm': specifier: ^0.1.5 version: 0.1.5 @@ -52,14 +52,14 @@ dependencies: devDependencies: '@types/node': - specifier: ^18.16.5 - version: 18.16.5 + specifier: ^18.16.6 + version: 18.16.6 '@typescript-eslint/eslint-plugin': - specifier: ^5.59.2 - version: 5.59.2(@typescript-eslint/parser@5.59.2)(eslint@8.40.0)(typescript@4.9.5) + specifier: ^5.59.5 + version: 5.59.5(@typescript-eslint/parser@5.59.5)(eslint@8.40.0)(typescript@4.9.5) '@typescript-eslint/parser': - specifier: ^5.59.2 - version: 5.59.2(eslint@8.40.0)(typescript@4.9.5) + specifier: ^5.59.5 + version: 5.59.5(eslint@8.40.0)(typescript@4.9.5) autoprefixer: specifier: ^10.4.14 version: 10.4.14(postcss@8.4.23) @@ -74,7 +74,7 @@ devDependencies: version: 2.7.1(eslint-plugin-import@2.27.5)(eslint@8.40.0) eslint-plugin-import: specifier: 2.27.5 - version: 2.27.5(@typescript-eslint/parser@5.59.2)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0) + version: 2.27.5(@typescript-eslint/parser@5.59.5)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0) eslint-plugin-prettier: specifier: 4.2.1 version: 4.2.1(eslint@8.40.0)(prettier@2.8.8) @@ -95,7 +95,7 @@ devDependencies: version: 4.9.5 vite: specifier: ^4.3.5 - version: 4.3.5(@types/node@18.16.5) + version: 4.3.5(@types/node@18.16.6) vite-plugin-pwa: specifier: ^0.14.7 version: 0.14.7(vite@4.3.5)(workbox-build@6.5.4)(workbox-window@6.5.4) @@ -1590,8 +1590,8 @@ packages: solid-js: 1.7.5 dev: false - /@mutinywallet/mutiny-wasm@0.2.8: - resolution: {integrity: sha512-SaLdJTsK4XTW0xmD3Du8AnHw/hvbomxCbyANyA2IbV4aybtPPgRDcGwRsyCegPioYQHP0skqzwsi1E6k44GIBw==} + /@mutinywallet/mutiny-wasm@0.3.0: + resolution: {integrity: sha512-K+u2u/XMX1269U8af3T/ZvS+SzzrQcVYrdMi420dWCa14gke0vPWbGp+01zN7SCqBL4jp929emHTUZ4YBEpkzQ==} dev: false /@mutinywallet/waila-wasm@0.1.5: @@ -1955,8 +1955,8 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/node@18.16.5: - resolution: {integrity: sha512-seOA34WMo9KB+UA78qaJoCO20RJzZGVXQ5Sh6FWu0g/hfT44nKXnej3/tCQl7FL97idFpBhisLYCTB50S0EirA==} + /@types/node@18.16.6: + resolution: {integrity: sha512-N7KINmeB8IN3vRR8dhgHEp+YpWvGFcpDoh5XZ8jB5a00AdFKCKEyyGTOPTddUf4JqU1ZKTVxkOxakDvchNVI2Q==} /@types/offscreencanvas@2019.7.0: resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==} @@ -1965,22 +1965,22 @@ packages: /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 18.16.5 + '@types/node': 18.16.6 dev: true /@types/resolve@1.20.2: resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - /@types/semver@7.3.13: - resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} + /@types/semver@7.5.0: + resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} dev: true /@types/trusted-types@2.0.3: resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==} dev: true - /@typescript-eslint/eslint-plugin@5.59.2(@typescript-eslint/parser@5.59.2)(eslint@8.40.0)(typescript@4.9.5): - resolution: {integrity: sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==} + /@typescript-eslint/eslint-plugin@5.59.5(@typescript-eslint/parser@5.59.5)(eslint@8.40.0)(typescript@4.9.5): + resolution: {integrity: sha512-feA9xbVRWJZor+AnLNAr7A8JRWeZqHUf4T9tlP+TN04b05pFVhO5eN7/O93Y/1OUlLMHKbnJisgDURs/qvtqdg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -1991,10 +1991,10 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.59.2(eslint@8.40.0)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 5.59.2 - '@typescript-eslint/type-utils': 5.59.2(eslint@8.40.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.2(eslint@8.40.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.59.5(eslint@8.40.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.59.5 + '@typescript-eslint/type-utils': 5.59.5(eslint@8.40.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.5(eslint@8.40.0)(typescript@4.9.5) debug: 4.3.4 eslint: 8.40.0 grapheme-splitter: 1.0.4 @@ -2007,8 +2007,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@5.59.2(eslint@8.40.0)(typescript@4.9.5): - resolution: {integrity: sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==} + /@typescript-eslint/parser@5.59.5(eslint@8.40.0)(typescript@4.9.5): + resolution: {integrity: sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2017,9 +2017,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.59.2 - '@typescript-eslint/types': 5.59.2 - '@typescript-eslint/typescript-estree': 5.59.2(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.59.5 + '@typescript-eslint/types': 5.59.5 + '@typescript-eslint/typescript-estree': 5.59.5(typescript@4.9.5) debug: 4.3.4 eslint: 8.40.0 typescript: 4.9.5 @@ -2027,16 +2027,16 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@5.59.2: - resolution: {integrity: sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==} + /@typescript-eslint/scope-manager@5.59.5: + resolution: {integrity: sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.59.2 - '@typescript-eslint/visitor-keys': 5.59.2 + '@typescript-eslint/types': 5.59.5 + '@typescript-eslint/visitor-keys': 5.59.5 dev: true - /@typescript-eslint/type-utils@5.59.2(eslint@8.40.0)(typescript@4.9.5): - resolution: {integrity: sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==} + /@typescript-eslint/type-utils@5.59.5(eslint@8.40.0)(typescript@4.9.5): + resolution: {integrity: sha512-4eyhS7oGym67/pSxA2mmNq7X164oqDYNnZCUayBwJZIRVvKpBCMBzFnFxjeoDeShjtO6RQBHBuwybuX3POnDqg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -2045,8 +2045,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.59.2(typescript@4.9.5) - '@typescript-eslint/utils': 5.59.2(eslint@8.40.0)(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 5.59.5(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.5(eslint@8.40.0)(typescript@4.9.5) debug: 4.3.4 eslint: 8.40.0 tsutils: 3.21.0(typescript@4.9.5) @@ -2055,13 +2055,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types@5.59.2: - resolution: {integrity: sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==} + /@typescript-eslint/types@5.59.5: + resolution: {integrity: sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree@5.59.2(typescript@4.9.5): - resolution: {integrity: sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==} + /@typescript-eslint/typescript-estree@5.59.5(typescript@4.9.5): + resolution: {integrity: sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -2069,8 +2069,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.59.2 - '@typescript-eslint/visitor-keys': 5.59.2 + '@typescript-eslint/types': 5.59.5 + '@typescript-eslint/visitor-keys': 5.59.5 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -2081,18 +2081,18 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@5.59.2(eslint@8.40.0)(typescript@4.9.5): - resolution: {integrity: sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==} + /@typescript-eslint/utils@5.59.5(eslint@8.40.0)(typescript@4.9.5): + resolution: {integrity: sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.40.0) '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.59.2 - '@typescript-eslint/types': 5.59.2 - '@typescript-eslint/typescript-estree': 5.59.2(typescript@4.9.5) + '@types/semver': 7.5.0 + '@typescript-eslint/scope-manager': 5.59.5 + '@typescript-eslint/types': 5.59.5 + '@typescript-eslint/typescript-estree': 5.59.5(typescript@4.9.5) eslint: 8.40.0 eslint-scope: 5.1.1 semver: 7.5.0 @@ -2101,11 +2101,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@5.59.2: - resolution: {integrity: sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==} + /@typescript-eslint/visitor-keys@5.59.5: + resolution: {integrity: sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.59.2 + '@typescript-eslint/types': 5.59.5 eslint-visitor-keys: 3.4.1 dev: true @@ -2343,7 +2343,7 @@ packages: hasBin: true dependencies: caniuse-lite: 1.0.30001486 - electron-to-chromium: 1.4.385 + electron-to-chromium: 1.4.387 node-releases: 2.0.10 update-browserslist-db: 1.0.11(browserslist@4.21.5) @@ -2626,8 +2626,8 @@ packages: jake: 10.8.5 dev: true - /electron-to-chromium@1.4.385: - resolution: {integrity: sha512-L9zlje9bIw0h+CwPQumiuVlfMcV4boxRjFIWDcLfFqTZNbkwOExBzfmswytHawObQX4OUhtNv8gIiB21kOurIg==} + /electron-to-chromium@1.4.387: + resolution: {integrity: sha512-tutLf+alr1/0YqJwKPdstVvDLmxmLb5xNyDLNS0RZmenHcEYk9qKfpKDCVZEKJ00JVbnayJm1MZAbYhYDFpcOw==} /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2990,7 +2990,7 @@ packages: dependencies: debug: 4.3.4 eslint: 8.40.0 - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.2)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.5)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0) glob: 7.2.3 is-glob: 4.0.3 resolve: 1.22.2 @@ -2999,7 +2999,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.2)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.5)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -3020,7 +3020,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.59.2(eslint@8.40.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.59.5(eslint@8.40.0)(typescript@4.9.5) debug: 3.2.7 eslint: 8.40.0 eslint-import-resolver-node: 0.3.7 @@ -3029,7 +3029,7 @@ packages: - supports-color dev: true - /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.2)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0): + /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.5)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0): resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} peerDependencies: @@ -3039,7 +3039,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.59.2(eslint@8.40.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.59.5(eslint@8.40.0)(typescript@4.9.5) array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -3047,7 +3047,7 @@ packages: doctrine: 2.1.0 eslint: 8.40.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.2)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.5)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@2.7.1)(eslint@8.40.0) has: 1.0.3 is-core-module: 2.12.0 is-glob: 4.0.3 @@ -3084,7 +3084,7 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.59.2(eslint@8.40.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.5(eslint@8.40.0)(typescript@4.9.5) eslint: 8.40.0 is-html: 2.0.0 jsx-ast-utils: 3.3.3 @@ -3767,7 +3767,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.16.5 + '@types/node': 18.16.6 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -4577,7 +4577,7 @@ packages: solid-start: 0.2.26(@solidjs/meta@0.28.4)(@solidjs/router@0.8.2)(solid-js@1.7.5)(solid-start-node@0.2.26)(vite@4.3.5) terser: 5.17.2 undici: 5.22.0 - vite: 4.3.5(@types/node@18.16.5) + vite: 4.3.5(@types/node@18.16.6) transitivePeerDependencies: - supports-color @@ -4647,8 +4647,8 @@ packages: solid-start-node: 0.2.26(solid-start@0.2.26)(undici@5.22.0)(vite@4.3.5) terser: 5.17.2 undici: 5.22.0 - vite: 4.3.5(@types/node@18.16.5) - vite-plugin-inspect: 0.7.25(rollup@3.21.5)(vite@4.3.5) + vite: 4.3.5(@types/node@18.16.6) + vite-plugin-inspect: 0.7.26(rollup@3.21.5)(vite@4.3.5) vite-plugin-solid: 2.7.0(solid-js@1.7.5)(vite@4.3.5) wait-on: 6.0.1(debug@4.3.4) transitivePeerDependencies: @@ -5044,8 +5044,8 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - /vite-plugin-inspect@0.7.25(rollup@3.21.5)(vite@4.3.5): - resolution: {integrity: sha512-11j3hG3stRfFkoI+adIDX+KvZueWNgd9lFGdh7lgm0IjGqpP6luCQAMSSnHHV7AZXaTE06X+bUG3M68diz8ZyA==} + /vite-plugin-inspect@0.7.26(rollup@3.21.5)(vite@4.3.5): + resolution: {integrity: sha512-gRjBay+OxLr/Dr+HXlfJVXZH0cqhE5hkkBvo2du2cA1LGUBnV8Aym89AdPrURkSpTk3Rvw9dNWM2VLIuw6RKJg==} engines: {node: '>=14'} peerDependencies: vite: ^3.1.0 || ^4.0.0 @@ -5056,7 +5056,7 @@ packages: fs-extra: 11.1.1 picocolors: 1.0.0 sirv: 2.0.3 - vite: 4.3.5(@types/node@18.16.5) + vite: 4.3.5(@types/node@18.16.6) transitivePeerDependencies: - rollup - supports-color @@ -5073,7 +5073,7 @@ packages: fast-glob: 3.2.12 pretty-bytes: 6.1.0 rollup: 3.21.5 - vite: 4.3.5(@types/node@18.16.5) + vite: 4.3.5(@types/node@18.16.6) workbox-build: 6.5.4 workbox-window: 6.5.4 transitivePeerDependencies: @@ -5093,7 +5093,7 @@ packages: merge-anything: 5.1.6 solid-js: 1.7.5 solid-refresh: 0.5.2(solid-js@1.7.5) - vite: 4.3.5(@types/node@18.16.5) + vite: 4.3.5(@types/node@18.16.6) vitefu: 0.2.4(vite@4.3.5) transitivePeerDependencies: - supports-color @@ -5103,10 +5103,10 @@ packages: peerDependencies: vite: ^2 || ^3 || ^4 dependencies: - vite: 4.3.5(@types/node@18.16.5) + vite: 4.3.5(@types/node@18.16.6) dev: true - /vite@4.3.5(@types/node@18.16.5): + /vite@4.3.5(@types/node@18.16.6): resolution: {integrity: sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -5131,7 +5131,7 @@ packages: terser: optional: true dependencies: - '@types/node': 18.16.5 + '@types/node': 18.16.6 esbuild: 0.17.18 postcss: 8.4.23 rollup: 3.21.5 @@ -5146,7 +5146,7 @@ packages: vite: optional: true dependencies: - vite: 4.3.5(@types/node@18.16.5) + vite: 4.3.5(@types/node@18.16.6) /wait-on@6.0.1(debug@4.3.4): resolution: {integrity: sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==} diff --git a/src/assets/check-spinner.gif b/src/assets/check-spinner.gif deleted file mode 100644 index 97e3f3a..0000000 Binary files a/src/assets/check-spinner.gif and /dev/null differ diff --git a/src/assets/hands/handshake.png b/src/assets/hands/handshake.png deleted file mode 100644 index 6fccb36..0000000 Binary files a/src/assets/hands/handshake.png and /dev/null differ diff --git a/src/assets/hands/handsup.png b/src/assets/hands/handsup.png deleted file mode 100644 index 8e1cfa9..0000000 Binary files a/src/assets/hands/handsup.png and /dev/null differ diff --git a/src/assets/hands/nostr.png b/src/assets/hands/nostr.png deleted file mode 100644 index 792e552..0000000 Binary files a/src/assets/hands/nostr.png and /dev/null differ diff --git a/src/assets/hands/thumbsdown.png b/src/assets/hands/thumbsdown.png deleted file mode 100644 index 7510060..0000000 Binary files a/src/assets/hands/thumbsdown.png and /dev/null differ diff --git a/src/assets/icons/coin.svg b/src/assets/icons/coin.svg new file mode 100644 index 0000000..70d2f97 --- /dev/null +++ b/src/assets/icons/coin.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/icons/rs.svg b/src/assets/icons/rs.svg new file mode 100644 index 0000000..893976e --- /dev/null +++ b/src/assets/icons/rs.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/party.gif b/src/assets/party.gif deleted file mode 100644 index 056c956..0000000 Binary files a/src/assets/party.gif and /dev/null differ diff --git a/src/assets/wave.gif b/src/assets/wave.gif new file mode 100644 index 0000000..3e91093 Binary files /dev/null and b/src/assets/wave.gif differ diff --git a/src/components/Activity.tsx b/src/components/Activity.tsx index b843f56..50d6702 100644 --- a/src/components/Activity.tsx +++ b/src/components/Activity.tsx @@ -1,17 +1,21 @@ import send from '~/assets/icons/send.svg'; import receive from '~/assets/icons/receive.svg'; -import { Card, LoadingSpinner, NiceP, SmallAmount, SmallHeader, VStack } from './layout'; -import { For, Match, ParentComponent, Suspense, Switch, createMemo, createResource, createSignal } from 'solid-js'; +import { ButtonLink, Card, LoadingSpinner, NiceP, SmallAmount, SmallHeader, VStack } from './layout'; +import { For, Match, ParentComponent, Show, Suspense, Switch, createMemo, createResource, createSignal } from 'solid-js'; import { useMegaStore } from '~/state/megaStore'; import { MutinyInvoice } from '@mutinywallet/mutiny-wasm'; import { prettyPrintTime } from '~/utils/prettyPrintTime'; import { JsonModal } from '~/components/JsonModal'; import mempoolTxUrl from '~/utils/mempoolTxUrl'; +import wave from "~/assets/wave.gif" +import utxoIcon from '~/assets/icons/coin.svg'; +import { getRedshifted } from '~/utils/fakeLabels'; export const THREE_COLUMNS = 'grid grid-cols-[auto,1fr,auto] gap-4 py-2 px-2 border-b border-neutral-800 last:border-b-0' export const CENTER_COLUMN = 'min-w-0 overflow-hidden max-w-full' export const MISSING_LABEL = 'py-1 px-2 bg-white/10 rounded inline-block text-sm' -export const RIGHT_COLUMN = 'flex flex-col items-right text-right max-w-[9rem]' +export const REDSHIFT_LABEL = 'py-1 px-2 bg-white text-m-red rounded inline-block text-sm' +export const RIGHT_COLUMN = 'flex flex-col items-right text-right max-w-[8rem]' export type OnChainTx = { txid: string @@ -26,14 +30,15 @@ export type OnChainTx = { } } -type Utxo = { +export type UtxoItem = { outpoint: string txout: { value: number script_pubkey: string } keychain: string - is_spent: boolean + is_spent: boolean, + redshifted?: boolean } const SubtleText: ParentComponent = (props) => { @@ -58,8 +63,7 @@ function OnChainItem(props: { item: OnChainTx }) {

Unknown

- {isReceive() ? : } - {/*

Txid: {props.item.txid}

*/} + {isReceive() ? : }
@@ -99,23 +103,31 @@ function InvoiceItem(props: { item: MutinyInvoice }) { ) } -function Utxo(props: { item: Utxo }) { +function Utxo(props: { item: UtxoItem }) { const spent = createMemo(() => props.item.is_spent); const [open, setOpen] = createSignal(false) + const redshifted = createMemo(() => getRedshifted(props.item.outpoint)); + return ( <>
setOpen(!open())}> - receive arrow +
+ coin +
-

Unknown

+
+ Unknown}> +

Redshift

+
+
- {spent() ? "SPENT" : "UNSPENT"} + {/* {spent() ? "SPENT" : "UNSPENT"} */}
@@ -128,19 +140,19 @@ export function Activity() { const getTransactions = async () => { console.log("Getting onchain txs"); - const txs = await state.node_manager?.list_onchain() as OnChainTx[]; + const txs = await state.mutiny_wallet?.list_onchain() as OnChainTx[]; return txs.reverse(); } const getInvoices = async () => { console.log("Getting invoices"); - const invoices = await state.node_manager?.list_invoices() as MutinyInvoice[]; + const invoices = await state.mutiny_wallet?.list_invoices() as MutinyInvoice[]; return invoices.filter((inv) => inv.paid).reverse(); } const getUtXos = async () => { console.log("Getting utxos"); - const utxos = await state.node_manager?.list_utxos() as Utxo[]; + const utxos = await state.mutiny_wallet?.list_utxos() as UtxoItem[]; return utxos; } @@ -201,6 +213,7 @@ export function Activity() { + Redshift redshift @@ -220,8 +233,8 @@ export function CombinedActivity(props: { limit?: number }) { const getAllActivity = async () => { console.log("Getting all activity"); - const txs = await state.node_manager?.list_onchain() as OnChainTx[]; - const invoices = await state.node_manager?.list_invoices() as MutinyInvoice[]; + const txs = await state.mutiny_wallet?.list_onchain() as OnChainTx[]; + const invoices = await state.mutiny_wallet?.list_invoices() as MutinyInvoice[]; const activity: ActivityItem[] = []; diff --git a/src/components/App.tsx b/src/components/App.tsx index 176b615..927960c 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1,5 +1,5 @@ import logo from '~/assets/icons/mutiny-logo.svg'; -import { Card, DefaultMain, NodeManagerGuard, SafeArea, VStack } from "~/components/layout"; +import { DefaultMain, MutinyWalletGuard, SafeArea, VStack, Card } from "~/components/layout"; import BalanceBox from "~/components/BalanceBox"; import NavBar from "~/components/NavBar"; import ReloadPrompt from "~/components/Reload"; @@ -10,7 +10,7 @@ import userClock from '~/assets/icons/user-clock.svg'; export default function App() { return ( - +
@@ -30,6 +30,6 @@ export default function App() { - + ); } diff --git a/src/components/DeleteEverything.tsx b/src/components/DeleteEverything.tsx index 7262823..71a052d 100644 --- a/src/components/DeleteEverything.tsx +++ b/src/components/DeleteEverything.tsx @@ -2,6 +2,8 @@ import { createSignal } from "solid-js"; import { ConfirmDialog } from "~/components/Dialog"; import { Button } from "~/components/layout"; import { showToast } from "~/components/Toaster"; +import { useMegaStore } from "~/state/megaStore"; +import eify from "~/utils/eify"; export function deleteDb(name: string) { const req = indexedDB.deleteDatabase(name); @@ -20,18 +22,7 @@ export function deleteDb(name: string) { } export function DeleteEverything() { - async function resetNode() { - setConfirmLoading(true); - deleteDb("gossip") - deleteDb("wallet") - localStorage.clear(); - showToast({ title: "Deleted", description: `Deleted all data` }) - setConfirmOpen(false); - setConfirmLoading(false); - setTimeout(() => { - window.location.href = "/"; - }, 3000); - } + const [_state, actions] = useMegaStore(); async function confirmReset() { setConfirmOpen(true); @@ -40,6 +31,25 @@ export function DeleteEverything() { const [confirmOpen, setConfirmOpen] = createSignal(false); const [confirmLoading, setConfirmLoading] = createSignal(false); + + async function resetNode() { + try { + setConfirmLoading(true); + await actions.deleteMutinyWallet(); + showToast({ title: "Deleted", description: `Deleted all data` }) + + setTimeout(() => { + window.location.href = "/"; + }, 1000); + } catch (e) { + console.error(e) + showToast(eify(e)) + } finally { + setConfirmOpen(false); + setConfirmLoading(false); + } + } + return ( <> @@ -48,4 +58,4 @@ export function DeleteEverything() { ) -} \ No newline at end of file +} diff --git a/src/components/ErrorDisplay.tsx b/src/components/ErrorDisplay.tsx index bbd7878..8ad130d 100644 --- a/src/components/ErrorDisplay.tsx +++ b/src/components/ErrorDisplay.tsx @@ -1,5 +1,5 @@ import { Title } from "solid-start"; -import { ButtonLink, DefaultMain, LargeHeader, SafeArea, SmallHeader } from "~/components/layout"; +import { Button, ButtonLink, DefaultMain, LargeHeader, SafeArea, SmallHeader } from "~/components/layout"; export default function ErrorDisplay(props: { error: Error }) { return ( @@ -13,7 +13,7 @@ export default function ErrorDisplay(props: { error: Error }) { {props.error.name}: {props.error.message}

- Dangit + ); diff --git a/src/components/ImportExport.tsx b/src/components/ImportExport.tsx index 5b4d375..e22a48a 100644 --- a/src/components/ImportExport.tsx +++ b/src/components/ImportExport.tsx @@ -6,13 +6,13 @@ import { showToast } from "./Toaster"; import { downloadTextFile } from "~/utils/download"; import { createFileUploader } from "@solid-primitives/upload" import { ConfirmDialog } from "./Dialog"; -import { NodeManager } from "@mutinywallet/mutiny-wasm"; +import { MutinyWallet } from "@mutinywallet/mutiny-wasm"; export function ImportExport() { const [state, _] = useMegaStore() async function handleSave() { - const json = await state.node_manager?.export_json() + const json = await state.mutiny_wallet?.export_json() downloadTextFile(json || "", "mutiny-state.json") } @@ -32,7 +32,7 @@ export function ImportExport() { // This should throw if there's a parse error, so we won't end up clearing JSON.parse(text); - NodeManager.import_json(text); + MutinyWallet.import_json(text); window.location.href = "/" diff --git a/src/components/KitchenSink.tsx b/src/components/KitchenSink.tsx index 518e05a..a37c0b7 100644 --- a/src/components/KitchenSink.tsx +++ b/src/components/KitchenSink.tsx @@ -17,13 +17,13 @@ function PeerItem(props: { peer: MutinyPeer }) { const [state, _] = useMegaStore() const handleDisconnectPeer = async () => { - const nodes = await state.node_manager?.list_nodes(); + const nodes = await state.mutiny_wallet?.list_nodes(); const firstNode = nodes[0] as string || "" if (props.peer.is_connected) { - await state.node_manager?.disconnect_peer(firstNode, props.peer.pubkey); + await state.mutiny_wallet?.disconnect_peer(firstNode, props.peer.pubkey); } else { - await state.node_manager?.delete_peer(firstNode, props.peer.pubkey); + await state.mutiny_wallet?.delete_peer(firstNode, props.peer.pubkey); } }; @@ -50,7 +50,7 @@ function PeersList() { const [state, _] = useMegaStore() const getPeers = async () => { - return await state.node_manager?.list_peers() as Promise + return await state.mutiny_wallet?.list_peers() as Promise }; const [peers, { refetch }] = createResource(getPeers); @@ -95,10 +95,10 @@ function ConnectPeer(props: { refetchPeers: RefetchPeersType }) { e.preventDefault(); const peerConnectString = value().trim(); - const nodes = await state.node_manager?.list_nodes(); + const nodes = await state.mutiny_wallet?.list_nodes(); const firstNode = nodes[0] as string || "" - await state.node_manager?.connect_to_peer(firstNode, peerConnectString) + await state.mutiny_wallet?.connect_to_peer(firstNode, peerConnectString) await props.refetchPeers() @@ -140,7 +140,7 @@ function ChannelItem(props: { channel: MutinyChannel, network?: string }) { async function confirmCloseChannel() { setConfirmLoading(true); try { - await state.node_manager?.close_channel(props.channel.outpoint as string) + await state.mutiny_wallet?.close_channel(props.channel.outpoint as string) } catch (e) { console.error(e); showToast(eify(e)); @@ -179,7 +179,7 @@ function ChannelsList() { const [state, _] = useMegaStore() const getChannels = async () => { - return await state.node_manager?.list_channels() as Promise + return await state.mutiny_wallet?.list_channels() as Promise }; const [channels, { refetch }] = createResource(getChannels); @@ -194,7 +194,7 @@ function ChannelsList() { }); }) - const network = state.node_manager?.get_network(); + const network = state.mutiny_wallet?.get_network(); return ( <> @@ -236,10 +236,10 @@ function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) { const pubkey = peerPubkey().trim(); const bigAmount = BigInt(amount()); - const nodes = await state.node_manager?.list_nodes(); + const nodes = await state.mutiny_wallet?.list_nodes(); const firstNode = nodes[0] as string || "" - const new_channel = await state.node_manager?.open_channel(firstNode, pubkey, bigAmount) + const new_channel = await state.mutiny_wallet?.open_channel(firstNode, pubkey, bigAmount) setNewChannel(new_channel) @@ -303,7 +303,7 @@ function LnUrlAuth() { e.preventDefault(); const lnurl = value().trim(); - await state.node_manager?.lnurl_auth(0, lnurl) + await state.mutiny_wallet?.lnurl_auth(0, lnurl) setValue(""); }; diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index f70dbb0..e1775d4 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -2,11 +2,12 @@ import mutiny_m from '~/assets/icons/m.svg'; import airplane from '~/assets/icons/airplane.svg'; import settings from '~/assets/icons/settings.svg'; import receive from '~/assets/icons/big-receive.svg'; +import redshift from '~/assets/icons/rs.svg'; import userClock from '~/assets/icons/user-clock.svg'; import { A } from "solid-start"; -type ActiveTab = 'home' | 'scan' | 'send' | 'receive' | 'settings' | 'activity' | 'none'; +type ActiveTab = 'home' | 'scan' | 'send' | 'receive' | 'settings' | 'redshift' | 'activity' | 'none'; export default function NavBar(props: { activeTab: ActiveTab }) { const activeStyle = 'border-t-0 border-b-0 p-2 bg-black rounded-lg' @@ -34,6 +35,11 @@ export default function NavBar(props: { activeTab: ActiveTab }) { activity +
  • + + redshift + +
  • settings diff --git a/src/components/PeerConnectModal.tsx b/src/components/PeerConnectModal.tsx index 29b9dbb..05d0472 100644 --- a/src/components/PeerConnectModal.tsx +++ b/src/components/PeerConnectModal.tsx @@ -3,7 +3,7 @@ import { As, Dialog } from "@kobalte/core"; import { Button, Card } from "~/components/layout"; import { useMegaStore } from "~/state/megaStore"; import { Show, createResource } from "solid-js"; -import { getExistingSettings } from "~/logic/nodeManagerSetup"; +import { getExistingSettings } from "~/logic/mutinyWalletSetup"; import getHostname from "~/utils/getHostname"; const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm" @@ -15,9 +15,9 @@ export default function PeerConnectModal() { const [state, _] = useMegaStore() const getPeerConnectString = async () => { - if (state.node_manager) { + if (state.mutiny_wallet) { const { proxy } = getExistingSettings(); - const nodes = await state.node_manager.list_nodes(); + const nodes = await state.mutiny_wallet.list_nodes(); const firstNode = nodes[0] as string || "" const hostName = getHostname(proxy || "") const connectString = `mutiny:${firstNode}@${hostName}` diff --git a/src/components/SettingsStringsEditor.tsx b/src/components/SettingsStringsEditor.tsx index 63b1622..ed31dcb 100644 --- a/src/components/SettingsStringsEditor.tsx +++ b/src/components/SettingsStringsEditor.tsx @@ -1,36 +1,22 @@ import { createForm, url } from '@modular-forms/solid'; import { TextField } from '~/components/layout/TextField'; -import { NodeManagerSettingStrings, getExistingSettings } from '~/logic/nodeManagerSetup'; -import { Button } from '~/components/layout'; -import { createSignal } from 'solid-js'; -import { deleteDb } from '~/components/DeleteEverything'; +import { MutinyWalletSettingStrings, getExistingSettings } from '~/logic/mutinyWalletSetup'; +import { Button, SmallHeader } from '~/components/layout'; import { showToast } from './Toaster'; import eify from '~/utils/eify'; -import { ConfirmDialog } from "~/components/Dialog"; import { useMegaStore } from '~/state/megaStore'; export function SettingsStringsEditor() { const existingSettings = getExistingSettings(); - const [_settingsForm, { Form, Field }] = createForm({ initialValues: existingSettings }); - const [confirmOpen, setConfirmOpen] = createSignal(false); - - const [settingsTemp, setSettingsTemp] = createSignal(); - + const [_settingsForm, { Form, Field }] = createForm({ initialValues: existingSettings }); const [_store, actions] = useMegaStore(); - async function handleSubmit(values: NodeManagerSettingStrings) { + async function handleSubmit(values: MutinyWalletSettingStrings) { try { const existing = getExistingSettings(); const newSettings = { ...existing, ...values } - if (existing.network !== values.network) { - // If the network changes we need to confirm the wipe - // Save the settings so we can get them later - setSettingsTemp(newSettings); - setConfirmOpen(true); - } else { - await actions.setupNodeManager(newSettings); - window.location.reload(); - } + await actions.setupMutinyWallet(newSettings); + window.location.reload(); } catch (e) { console.error(e) showToast(eify(e)) @@ -38,42 +24,15 @@ export function SettingsStringsEditor() { console.log(values) } - async function confirmStateReset() { - try { - deleteDb("gossip") - localStorage.clear(); - showToast({ title: "Deleted", description: `Deleted all data` }) - const loadedValues = settingsTemp(); - - await actions.setupNodeManager(loadedValues); - window.location.reload(); - } catch (e) { - console.error(e) - showToast(eify(e)) - } - - setConfirmOpen(false); - } - return
    - setConfirmOpen(false)}> - Are you sure? Changing networks will delete your node's state. This can't be undone! -

    Don't trust us! Use your own servers to back Mutiny.

    - - {(field, props) => ( - // TODO: make a cool select component -
    - - -
    - )} -
    +
    + Network +
    +                {existingSettings.network}
    +            
    +
    + {(field, props) => ( diff --git a/src/components/layout/index.tsx b/src/components/layout/index.tsx index 5d8bb18..fd0f71e 100644 --- a/src/components/layout/index.tsx +++ b/src/components/layout/index.tsx @@ -71,11 +71,11 @@ export const FullscreenLoader = () => { ); } -export const NodeManagerGuard: ParentComponent = (props) => { +export const MutinyWalletGuard: ParentComponent = (props) => { const [state, _] = useMegaStore(); return ( }> - + {props.children} @@ -133,4 +133,4 @@ export const Indicator: ParentComponent = (props) => { return (
    {props.children}
    ) -} \ No newline at end of file +} diff --git a/src/logic/nodeManagerSetup.ts b/src/logic/mutinyWalletSetup.ts similarity index 80% rename from src/logic/nodeManagerSetup.ts rename to src/logic/mutinyWalletSetup.ts index 68a0abb..5dd44a6 100644 --- a/src/logic/nodeManagerSetup.ts +++ b/src/logic/mutinyWalletSetup.ts @@ -1,17 +1,17 @@ -import initNodeManager, { NodeManager } from '@mutinywallet/mutiny-wasm'; +import initMutinyWallet, { MutinyWallet } from '@mutinywallet/mutiny-wasm'; import initWaila from '@mutinywallet/waila-wasm' -// export type NodeManagerSettingStrings = { +// export type MutinyWalletSettingStrings = { // network?: string, proxy?: string, esplora?: string, rgs?: string, lsp?: string, // } type Network = "bitcoin" | "testnet" | "regtest" | "signet"; -export type NodeManagerSettingStrings = { +export type MutinyWalletSettingStrings = { network?: Network, proxy?: string, esplora?: string, rgs?: string, lsp?: string, } -export function getExistingSettings(): NodeManagerSettingStrings { +export function getExistingSettings(): MutinyWalletSettingStrings { const network = localStorage.getItem('MUTINY_SETTINGS_network') || import.meta.env.VITE_NETWORK; const proxy = localStorage.getItem('MUTINY_SETTINGS_proxy') || import.meta.env.VITE_PROXY; const esplora = localStorage.getItem('MUTINY_SETTINGS_esplora') || import.meta.env.VITE_ESPLORA; @@ -21,7 +21,7 @@ export function getExistingSettings(): NodeManagerSettingStrings { return { network, proxy, esplora, rgs, lsp } } -export async function setAndGetMutinySettings(settings?: NodeManagerSettingStrings): Promise { +export async function setAndGetMutinySettings(settings?: MutinyWalletSettingStrings): Promise { let { network, proxy, esplora, rgs, lsp } = settings || {}; const existingSettings = getExistingSettings(); @@ -70,29 +70,29 @@ export async function checkForWasm() { } } -export async function setupNodeManager(settings?: NodeManagerSettingStrings): Promise { - await initNodeManager(); +export async function setupMutinyWallet(settings?: MutinyWalletSettingStrings): Promise { + await initMutinyWallet(); // Might as well init waila while we're at it await initWaila(); console.time("Setup"); console.log("Starting setup...") const { network, proxy, esplora, rgs, lsp } = await setAndGetMutinySettings(settings) - console.log("Initializing Node Manager") + console.log("Initializing Mutiny Manager") console.log("Using network", network); console.log("Using proxy", proxy); console.log("Using esplora address", esplora); console.log("Using rgs address", rgs); console.log("Using lsp address", lsp); - const nodeManager = await new NodeManager("", undefined, proxy, network, esplora, rgs, lsp) + const mutinyWallet = await new MutinyWallet("", undefined, proxy, network, esplora, rgs, lsp) - const nodes = await nodeManager.list_nodes(); + const nodes = await mutinyWallet.list_nodes(); // If we don't have any nodes yet, create one if (!nodes.length) { - await nodeManager?.new_node() + await mutinyWallet?.new_node() } - return nodeManager + return mutinyWallet } \ No newline at end of file diff --git a/src/routes/Activity.tsx b/src/routes/Activity.tsx index 3123b41..6234989 100644 --- a/src/routes/Activity.tsx +++ b/src/routes/Activity.tsx @@ -1,6 +1,6 @@ import { For, Show, createResource } from "solid-js"; import NavBar from "~/components/NavBar"; -import { Button, Card, DefaultMain, LargeHeader, NiceP, NodeManagerGuard, SafeArea, VStack } from "~/components/layout"; +import { Button, Card, DefaultMain, LargeHeader, NiceP, MutinyWalletGuard, SafeArea, VStack } from "~/components/layout"; import { BackLink } from "~/components/layout/BackLink"; import { CombinedActivity } from "~/components/Activity"; import { A } from "solid-start"; @@ -43,7 +43,7 @@ const TAB = "flex-1 inline-block px-8 py-4 text-lg font-semibold rounded-lg ui-s export default function Activity() { return ( - + @@ -73,6 +73,6 @@ export default function Activity() { - + ) } \ No newline at end of file diff --git a/src/routes/Admin.tsx b/src/routes/Admin.tsx index 19d32a2..738bf7a 100644 --- a/src/routes/Admin.tsx +++ b/src/routes/Admin.tsx @@ -1,12 +1,12 @@ import { DeleteEverything } from "~/components/DeleteEverything"; import KitchenSink from "~/components/KitchenSink"; import NavBar from "~/components/NavBar"; -import { Card, DefaultMain, LargeHeader, NodeManagerGuard, SafeArea, SmallHeader, VStack } from "~/components/layout"; +import { Card, DefaultMain, LargeHeader, MutinyWalletGuard, SafeArea, SmallHeader, VStack } from "~/components/layout"; import { BackLink } from "~/components/layout/BackLink"; export default function Admin() { return ( - + @@ -22,6 +22,6 @@ export default function Admin() { - + ) } \ No newline at end of file diff --git a/src/routes/Backup.tsx b/src/routes/Backup.tsx index 7d6b60b..30b9015 100644 --- a/src/routes/Backup.tsx +++ b/src/routes/Backup.tsx @@ -1,4 +1,4 @@ -import { Button, DefaultMain, LargeHeader, NiceP, NodeManagerGuard, SafeArea, VStack } from "~/components/layout"; +import { Button, DefaultMain, LargeHeader, NiceP, MutinyWalletGuard, SafeArea, VStack } from "~/components/layout"; import NavBar from "~/components/NavBar"; import { useNavigate } from 'solid-start'; import { SeedWords } from '~/components/SeedWords'; @@ -18,7 +18,7 @@ export default function App() { } return ( - + @@ -30,7 +30,7 @@ export default function App() { If you clear your browser history, or lose your device, these 12 words are the only way you can restore your wallet. Mutiny is self-custodial. It's all up to you... - + You are responsible for your funds! @@ -39,6 +39,6 @@ export default function App() { - + ); } diff --git a/src/routes/Receive.tsx b/src/routes/Receive.tsx index 0e819d6..00031f5 100644 --- a/src/routes/Receive.tsx +++ b/src/routes/Receive.tsx @@ -1,7 +1,7 @@ import { MutinyBip21RawMaterials, MutinyInvoice } from "@mutinywallet/mutiny-wasm"; import { createEffect, createMemo, createResource, createSignal, Match, onCleanup, onMount, Show, Switch } from "solid-js"; import { QRCodeSVG } from "solid-qr-code"; -import { Button, Card, Indicator, LargeHeader, NodeManagerGuard, SafeArea } from "~/components/layout"; +import { Button, Card, Indicator, LargeHeader, MutinyWalletGuard, SafeArea } from "~/components/layout"; import NavBar from "~/components/NavBar"; import { useMegaStore } from "~/state/megaStore"; import { objectToSearchParams } from "~/utils/objectToSearchParams"; @@ -104,13 +104,13 @@ export default function Receive() { async function getUnifiedQr(amount: string) { const bigAmount = BigInt(amount); try { - const raw = await state.node_manager?.create_bip21(bigAmount); + // FIXME: actual labels + const raw = await state.mutiny_wallet?.create_bip21(bigAmount, []); // Save the raw info so we can watch the address and invoice setBip21Raw(raw); const params = objectToSearchParams({ amount: raw?.btc_amount, - label: raw?.description, lightning: raw?.invoice }) @@ -138,7 +138,7 @@ export default function Receive() { const lightning = bip21.invoice const address = bip21.address - const invoice = await state.node_manager?.get_invoice(lightning) + const invoice = await state.mutiny_wallet?.get_invoice(lightning) if (invoice && invoice.paid) { setReceiveState("paid") @@ -146,7 +146,7 @@ export default function Receive() { return "lightning_paid" } - const tx = await state.node_manager?.check_address(address) as OnChainTx | undefined; + const tx = await state.mutiny_wallet?.check_address(address) as OnChainTx | undefined; if (tx) { setReceiveState("paid") @@ -168,7 +168,7 @@ export default function Receive() { }); return ( - +
    }> @@ -229,6 +229,6 @@ export default function Receive() {
    -
    + ) } \ No newline at end of file diff --git a/src/routes/Redshift.tsx b/src/routes/Redshift.tsx new file mode 100644 index 0000000..98cee3e --- /dev/null +++ b/src/routes/Redshift.tsx @@ -0,0 +1,409 @@ +import { Component, createEffect, createMemo, createResource, createSignal, For, Match, onCleanup, onMount, ParentComponent, Show, Suspense, Switch } from "solid-js"; +import { CENTER_COLUMN, MISSING_LABEL, REDSHIFT_LABEL, RIGHT_COLUMN, THREE_COLUMNS, UtxoItem } from "~/components/Activity"; +import { Card, DefaultMain, LargeHeader, LoadingSpinner, NiceP, MutinyWalletGuard, SafeArea, SmallAmount, SmallHeader, VStack } from "~/components/layout"; +import { BackLink } from "~/components/layout/BackLink"; +import { StyledRadioGroup } from "~/components/layout/Radio"; +import NavBar from "~/components/NavBar"; +import { useMegaStore } from "~/state/megaStore"; +import wave from "~/assets/wave.gif" +import utxoIcon from '~/assets/icons/coin.svg'; +import { Button } from "~/components/layout/Button"; +import { ProgressBar } from "~/components/layout/ProgressBar"; +import { MutinyChannel } from "@mutinywallet/mutiny-wasm"; +import mempoolTxUrl from "~/utils/mempoolTxUrl"; +import { Amount } from "~/components/Amount"; +import { getRedshifted, setRedshifted } from "~/utils/fakeLabels"; + +type ShiftOption = "utxo" | "lightning" + +type ShiftStage = "choose" | "observe" | "success" | "failure" + +type OutPoint = string; // Replace with the actual TypeScript type for OutPoint +type RedshiftStatus = string; // Replace with the actual TypeScript type for RedshiftStatus +type RedshiftRecipient = any; // Replace with the actual TypeScript type for RedshiftRecipient +type PublicKey = any; // Replace with the actual TypeScript type for PublicKey + +interface RedshiftResult { + id: string; + input_utxo: OutPoint; + status: RedshiftStatus; + recipient: RedshiftRecipient; + output_utxo?: OutPoint; + introduction_channel?: OutPoint; + output_channel?: OutPoint; + introduction_node: PublicKey; + amount_sats: bigint; + change_amt?: bigint; + fees_paid: bigint; +} + +const dummyRedshift: RedshiftResult = { + id: "44036599c37d590899e8d5d920860286", + input_utxo: "44036599c37d590899e8d5d92086028695d2c2966fdc354ce1da9a9eac610a53:1", + status: "Completed", // Replace with a dummy value for RedshiftStatus + recipient: {}, // Replace with a dummy value for RedshiftRecipient + output_utxo: "44036599c37d590899e8d5d92086028695d2c2966fdc354ce1da9a9eac610a53:1", + introduction_channel: "a7773e57f8595848a635e9af105927cac9ecaf292d71a76456ae0455bd3c9c64:0", + output_channel: "a7773e57f8595848a635e9af105927cac9ecaf292d71a76456ae0455bd3c9c64:0", + introduction_node: {}, // Replace with a dummy value for PublicKey + amount_sats: BigInt(1000000), + change_amt: BigInt(12345), + fees_paid: BigInt(2500), +}; + +function RedshiftReport(props: { redshift: RedshiftResult, utxo: UtxoItem }) { + const [state, _actions] = useMegaStore(); + + const getUtXos = async () => { + console.log("Getting utxos"); + return await state.mutiny_wallet?.list_utxos() as UtxoItem[]; + } + + function findUtxoByOutpoint(outpoint?: string, utxos: UtxoItem[] = []): UtxoItem | undefined { + if (!outpoint) return undefined; + return utxos.find((utxo) => utxo.outpoint === outpoint); + } + + + const [utxos, { refetch: _refetchUtxos }] = createResource(getUtXos); + + const inputUtxo = createMemo(() => { + console.log(utxos()) + const foundUtxo = findUtxoByOutpoint(props.redshift.input_utxo, utxos()) + console.log("Found utxo:", foundUtxo) + return foundUtxo + }) + + + async function checkRedshift(id: string) { + // const rs = redshiftItems[0] as RedshiftResult; + console.log("Checking redshift", id) + const redshift = await state.mutiny_wallet?.get_redshift(id); + console.log(redshift) + return redshift; + } + + const [redshiftResource, { refetch }] = createResource(props.redshift.id, checkRedshift); + onMount(() => { + const interval = setInterval(() => { + if (redshiftResource()) refetch(); + // if (sentAmount() === 200000) { + // clearInterval(interval) + // props.setShiftStage("success"); + // // setSentAmount((0)) + + // } else { + // setSentAmount((sentAmount() + 50000)) + // } + }, 1000) + }) + + const outputUtxo = createMemo(() => { + return findUtxoByOutpoint(redshiftResource()?.output_utxo, utxos()) + }) + + createEffect(() => { + setRedshifted(true, redshiftResource()?.output_utxo) + }) + + + return ( + + + {/* + We did it. Here's your new UTXO: + + + + + + */} + + What happened? + + + + + {/* + + + + */} + + + + + + + + + + + +
    {redshiftResource().introduction_channel}
    +
    + View on mempool + + + + + + +
    {redshiftResource().output_channel}
    + + View on mempool + + +
    +
    +
    + + + + + + + ) +} + +const SHIFT_OPTIONS = [{ value: "utxo", label: "UTXO", caption: "Trade your UTXO for a fresh UTXO" }, { value: "lightning", label: "Lightning", caption: "Convert your UTXO into Lightning" }] + +export function Utxo(props: { item: UtxoItem, onClick?: () => void }) { + const redshifted = createMemo(() => getRedshifted(props.item.outpoint)); + return ( + <> +
    +
    + coin +
    +
    +
    + Unknown}> +

    Redshift

    +
    +
    + +
    +
    + + {/* {props.item?.is_spent ? "SPENT" : "UNSPENT"} */} + +
    +
    + + ) +} + +const FAKE_STATES = ["Creating a new node", "Opening a channel", "Sending funds through", "Closing the channel", "Redshift complete"] + +function ShiftObserver(props: { setShiftStage: (stage: ShiftStage) => void, redshiftId: String }) { + const [state, _actions] = useMegaStore(); + + const [fakeStage, setFakeStage] = createSignal(2); + + const [sentAmount, setSentAmount] = createSignal(0); + + onMount(() => { + const interval = setInterval(() => { + if (sentAmount() === 200000) { + clearInterval(interval) + props.setShiftStage("success"); + // setSentAmount((0)) + + } else { + setSentAmount((sentAmount() + 50000)) + } + }, 1000) + }) + + async function checkRedshift(id: string) { + console.log("Checking redshift", id) + const redshift = await state.mutiny_wallet?.get_redshift(id); + console.log(redshift) + return redshift + } + + const [redshiftResource, { refetch }] = createResource(props.redshiftId, checkRedshift); + + // onMount(() => { + // const interval = setInterval(() => { + // if (redshiftResource()) refetch(); + // // if (sentAmount() === 200000) { + // // clearInterval(interval) + // // props.setShiftStage("success"); + // // // setSentAmount((0)) + + // // } else { + // // setSentAmount((sentAmount() + 50000)) + // // } + // }, 1000) + // }) + + // createEffect(() => { + // const interval = setInterval(() => { + // if (chosenUtxo()) refetch(); + // }, 1000); // Poll every second + // onCleanup(() => { + // clearInterval(interval); + // }); + // }); + + return ( + <> + Watch it go! + + +
    {FAKE_STATES[fakeStage()]}
    + + sine wave +
    +
    + + ) +} + +const KV: ParentComponent<{ key: string }> = (props) => { + return ( +
    +

    {props.key}

    + {props.children} +
    + ) +} + +export default function Redshift() { + const [state, _actions] = useMegaStore(); + + const [shiftStage, setShiftStage] = createSignal("choose"); + const [shiftType, setShiftType] = createSignal("utxo"); + + const [chosenUtxo, setChosenUtxo] = createSignal(); + + const getUtXos = async () => { + console.log("Getting utxos"); + return await state.mutiny_wallet?.list_utxos() as UtxoItem[]; + } + + const getChannels = async () => { + console.log("Getting channels"); + await state.mutiny_wallet?.sync() + const channels = await state.mutiny_wallet?.list_channels() as Promise; + console.log(channels) + return channels + + } + + const [utxos, { refetch: _refetchUtxos }] = createResource(getUtXos); + const [channels, { refetch: _refetchChannels }] = createResource(getChannels); + + + + const redshiftedUtxos = createMemo(() => { + return utxos()?.filter((utxo) => getRedshifted(utxo.outpoint)) + }) + + const unredshiftedUtxos = createMemo(() => { + return utxos()?.filter((utxo) => !getRedshifted(utxo.outpoint)) + }) + + function resetState() { + setShiftStage("choose"); + setShiftType("utxo"); + setChosenUtxo(undefined); + } + + async function redshiftUtxo(utxo: UtxoItem) { + console.log("Redshifting utxo", utxo.outpoint) + const redshift = await state.mutiny_wallet?.init_redshift(utxo.outpoint); + console.log("Redshift initialized:") + console.log(redshift) + return redshift + } + + const [initializedRedshift, { refetch: _refetchRedshift }] = createResource(chosenUtxo, redshiftUtxo); + + createEffect(() => { + if (chosenUtxo() && initializedRedshift()) { + // window.location.href = "/" + setShiftStage("observe"); + } + }) + + return ( + + + + + Redshift + + {/*
    {JSON.stringify(redshiftResource(), null, 2)}
    */} + + + + Where is this going? + setShiftType(newValue as ShiftOption)} choices={SHIFT_OPTIONS} /> + + + Choose your sine wave UTXO to begin + + + + + + + + No utxos (empty state) + + = 0}> + + {(utxo) => + setChosenUtxo(utxo)} /> + } + + + + + + + Redshifted UTXOs}> + + + + + + No utxos (empty state) + + = 0}> + + {(utxo) => + + } + + + + + + + + + + + + + + + + + + Oh dear + Here's what happened: + + + +
    +
    + +
    +
    + ) +} \ No newline at end of file diff --git a/src/routes/Scanner.tsx b/src/routes/Scanner.tsx index c8efdcd..87f499d 100644 --- a/src/routes/Scanner.tsx +++ b/src/routes/Scanner.tsx @@ -83,7 +83,7 @@ export default function Scanner() { // When we have a nice result we can head over to the send screen createEffect(() => { if (scanResult()) { - const network = state.node_manager?.get_network() || "signet"; + const network = state.mutiny_wallet?.get_network() || "signet"; const result = toParsedParams(scanResult() || "", network); if (!result.ok) { showToast(result.error); diff --git a/src/routes/Send.tsx b/src/routes/Send.tsx index cf161b9..8ef1911 100644 --- a/src/routes/Send.tsx +++ b/src/routes/Send.tsx @@ -1,7 +1,7 @@ import { Match, Show, Switch, createEffect, createMemo, createSignal, onMount } from "solid-js"; import { Amount } from "~/components/Amount"; import NavBar from "~/components/NavBar"; -import { Button, ButtonLink, Card, DefaultMain, HStack, LargeHeader, NodeManagerGuard, SafeArea, SmallHeader, VStack } from "~/components/layout"; +import { Button, ButtonLink, Card, DefaultMain, HStack, LargeHeader, MutinyWalletGuard, SafeArea, SmallHeader, VStack } from "~/components/layout"; import { Paste } from "~/assets/svg/Paste"; import { Scan } from "~/assets/svg/Scan"; import { useMegaStore } from "~/state/megaStore"; @@ -14,8 +14,8 @@ import { FullscreenModal } from "~/components/layout/FullscreenModal"; import megacheck from "~/assets/icons/megacheck.png" import megaex from "~/assets/icons/megaex.png"; import mempoolTxUrl from "~/utils/mempoolTxUrl"; -import { useNavigate } from "solid-start"; import { BackLink } from "~/components/layout/BackLink"; +import { useNavigate } from "solid-start"; import { TagEditor } from "~/components/TagEditor"; import { TagItem, createUniqueId, listTags } from "~/state/contacts"; import { StringShower } from "~/components/ShareCard"; @@ -170,7 +170,7 @@ export default function Send() { if (source.memo) setDescription(source.memo); if (source.invoice) { - state.node_manager?.decode_invoice(source.invoice).then(invoice => { + state.mutiny_wallet?.decode_invoice(source.invoice).then(invoice => { if (invoice?.amount_sats) setAmountSats(invoice.amount_sats); setInvoice(invoice) setSource("lightning") @@ -193,7 +193,7 @@ export default function Send() { function parsePaste(text: string) { if (text) { - const network = state.node_manager?.get_network() || "signet"; + const network = state.mutiny_wallet?.get_network() || "signet"; const result = toParsedParams(text || "", network); if (!result.ok) { showToast(result.error); @@ -230,21 +230,21 @@ export default function Send() { const bolt11 = invoice()?.bolt11; const sentDetails: Partial = {}; if (source() === "lightning" && invoice() && bolt11) { - const nodes = await state.node_manager?.list_nodes(); + const nodes = await state.mutiny_wallet?.list_nodes(); const firstNode = nodes[0] as string || "" sentDetails.destination = bolt11; // If the invoice has sats use that, otherwise we pass the user-defined amount if (invoice()?.amount_sats) { - await state.node_manager?.pay_invoice(firstNode, bolt11); + await state.mutiny_wallet?.pay_invoice(firstNode, bolt11); sentDetails.amount = invoice()?.amount_sats; } else { - await state.node_manager?.pay_invoice(firstNode, bolt11, amountSats()); + await state.mutiny_wallet?.pay_invoice(firstNode, bolt11, amountSats()); sentDetails.amount = amountSats(); } } else if (source() === "lightning" && nodePubkey()) { - const nodes = await state.node_manager?.list_nodes(); + const nodes = await state.mutiny_wallet?.list_nodes(); const firstNode = nodes[0] as string || "" - const payment = await state.node_manager?.keysend(firstNode, nodePubkey()!, amountSats()); + const payment = await state.mutiny_wallet?.keysend(firstNode, nodePubkey()!, amountSats()); console.log(payment?.value) // TODO: handle timeouts @@ -254,8 +254,9 @@ export default function Send() { sentDetails.amount = amountSats(); } } else if (source() === "onchain" && address()) { + // FIXME: actual labels // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const txid = await state.node_manager?.send_to_address(address()!, amountSats()); + const txid = await state.mutiny_wallet?.send_to_address(address()!, amountSats(), []); sentDetails.amount = amountSats(); sentDetails.destination = address(); // TODO: figure out if this is necessary, it takes forever @@ -280,7 +281,7 @@ export default function Send() { }) return ( - + @@ -302,7 +303,7 @@ export default function Send() { success - + Mempool Link @@ -335,6 +336,6 @@ export default function Send() { - + ) } \ No newline at end of file diff --git a/src/routes/Settings.tsx b/src/routes/Settings.tsx index ca73c00..1ab8639 100644 --- a/src/routes/Settings.tsx +++ b/src/routes/Settings.tsx @@ -1,4 +1,4 @@ -import { ButtonLink, DefaultMain, LargeHeader, NodeManagerGuard, SafeArea, VStack } from "~/components/layout"; +import { ButtonLink, DefaultMain, LargeHeader, MutinyWalletGuard, SafeArea, VStack } from "~/components/layout"; import { BackLink } from "~/components/layout/BackLink"; import NavBar from "~/components/NavBar"; import { SeedWords } from "~/components/SeedWords"; @@ -9,7 +9,7 @@ export default function Settings() { const [store, _actions] = useMegaStore(); return ( - + @@ -17,7 +17,7 @@ export default function Settings() {

    Write down these words or you'll die!

    - +
    "I know what I'm doing" @@ -25,6 +25,6 @@ export default function Settings() {
    -
    + ) } \ No newline at end of file diff --git a/src/state/megaStore.tsx b/src/state/megaStore.tsx index 7b2c43c..cd3c14f 100644 --- a/src/state/megaStore.tsx +++ b/src/state/megaStore.tsx @@ -3,8 +3,8 @@ // Inspired by https://github.com/solidjs/solid-realworld/blob/main/src/store/index.js import { ParentComponent, createContext, createEffect, onCleanup, onMount, useContext } from "solid-js"; import { createStore } from "solid-js/store"; -import { NodeManagerSettingStrings, setupNodeManager } from "~/logic/nodeManagerSetup"; -import { MutinyBalance, NodeManager } from "@mutinywallet/mutiny-wasm"; +import { MutinyWalletSettingStrings, setupMutinyWallet } from "~/logic/mutinyWalletSetup"; +import { MutinyBalance, MutinyWallet } from "@mutinywallet/mutiny-wasm"; import { ParsedParams } from "~/routes/Scanner"; const MegaStoreContext = createContext(); @@ -13,7 +13,8 @@ type UserStatus = undefined | "new_here" | "waitlisted" | "approved" | "paid" export type MegaStore = [{ waitlist_id?: string; - node_manager?: NodeManager; + mutiny_wallet?: MutinyWallet; + deleting: boolean; user_status: UserStatus; scan_result?: ParsedParams; balance?: MutinyBalance; @@ -24,7 +25,8 @@ export type MegaStore = [{ dismissed_restore_prompt: boolean }, { fetchUserStatus(): Promise; - setupNodeManager(settings?: NodeManagerSettingStrings): Promise; + setupMutinyWallet(settings?: MutinyWalletSettingStrings): Promise; + deleteMutinyWallet(): Promise; setWaitlistId(waitlist_id: string): void; setScanResult(scan_result: ParsedParams | undefined): void; sync(): Promise; @@ -35,7 +37,8 @@ export type MegaStore = [{ export const Provider: ParentComponent = (props) => { const [state, setState] = createStore({ waitlist_id: localStorage.getItem("waitlist_id"), - node_manager: undefined as NodeManager | undefined, + mutiny_wallet: undefined as MutinyWallet | undefined, + deleting: false, user_status: undefined as UserStatus, scan_result: undefined as ParsedParams | undefined, // TODO: wire this up to real price once we have caching @@ -66,24 +69,34 @@ export const Provider: ParentComponent = (props) => { return "new_here" } }, - async setupNodeManager(settings?: NodeManagerSettingStrings): Promise { + async setupMutinyWallet(settings?: MutinyWalletSettingStrings): Promise { try { - const nodeManager = await setupNodeManager(settings) - setState({ node_manager: nodeManager }) + const mutinyWallet = await setupMutinyWallet(settings) + setState({ mutiny_wallet: mutinyWallet }) } catch (e) { console.error(e) } }, + async deleteMutinyWallet(): Promise { + await state.mutiny_wallet?.stop(); + setState((prevState) => ({ + ...prevState, + mutiny_wallet: undefined, + deleting: true, + })); + MutinyWallet.import_json("{}"); + localStorage.clear(); + }, setWaitlistId(waitlist_id: string) { setState({ waitlist_id }) }, async sync(): Promise { console.time("BDK Sync Time") try { - if (state.node_manager && !state.is_syncing) { + if (state.mutiny_wallet && !state.is_syncing) { setState({ is_syncing: true }) - await state.node_manager?.sync() - const balance = await state.node_manager?.get_balance(); + await state.mutiny_wallet?.sync() + const balance = await state.mutiny_wallet?.get_balance(); setState({ balance, last_sync: Date.now() }) } } catch (e) { @@ -115,9 +128,9 @@ export const Provider: ParentComponent = (props) => { // Only load node manager when status is approved createEffect(() => { - if (state.user_status === "approved" && !state.node_manager) { + if (state.user_status === "approved" && !state.mutiny_wallet && !state.deleting) { console.log("running setup node manager...") - actions.setupNodeManager().then(() => console.log("node manager setup done")) + actions.setupMutinyWallet().then(() => console.log("node manager setup done")) } }) @@ -152,4 +165,4 @@ export function useMegaStore() { throw new Error("useMegaStore: cannot find a MegaStoreContext") } return context; -} \ No newline at end of file +} diff --git a/src/utils/conversions.ts b/src/utils/conversions.ts index 2bab67a..37db8ea 100644 --- a/src/utils/conversions.ts +++ b/src/utils/conversions.ts @@ -1,11 +1,11 @@ -import { NodeManager } from "@mutinywallet/mutiny-wasm"; +import { MutinyWallet } from "@mutinywallet/mutiny-wasm"; export function satsToUsd(amount: number | undefined, price: number, formatted: boolean): string { if (typeof amount !== "number" || isNaN(amount)) { return "" } try { - const btc = NodeManager.convert_sats_to_btc(BigInt(Math.floor(amount))); + const btc = MutinyWallet.convert_sats_to_btc(BigInt(Math.floor(amount))); const usd = btc * price; if (formatted) { @@ -26,7 +26,7 @@ export function usdToSats(amount: number | undefined, price: number, formatted: } try { const btc = price / amount; - const sats = NodeManager.convert_btc_to_sats(btc); + const sats = MutinyWallet.convert_btc_to_sats(btc); if (formatted) { return parseInt(sats.toString()).toLocaleString(); } else { diff --git a/src/utils/fakeLabels.ts b/src/utils/fakeLabels.ts new file mode 100644 index 0000000..e528ef2 --- /dev/null +++ b/src/utils/fakeLabels.ts @@ -0,0 +1,19 @@ +// Simple storage for fake labels +// For each outpoint string, we can store a boolean whether it's redshifted or not + +function setRedshifted(redshifted: boolean, outpoint?: string,) { + if (outpoint === undefined) return; + localStorage.setItem(outpoint, redshifted.toString()) +} + +function getRedshifted(outpoint: string): boolean { + const redshifted = localStorage.getItem(outpoint) + if (redshifted === null) { + return false + } + return redshifted === 'true' +} + +const TEST_UTXO = "47651763fbd74488a478aad80e4205c3e34bbadcfc42b5cd9557ef12a15ab00c:1" + +export { setRedshifted, getRedshifted, TEST_UTXO } \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index ee8d5c2..565d4aa 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -52,7 +52,7 @@ export default defineConfig({ }, optimizeDeps: { // Don't want vite to bundle these late during dev causing reload - include: ["qr-scanner", "nostr-tools", "class-variance-authority"], + include: ["qr-scanner", "nostr-tools", "class-variance-authority", "@kobalte/core", "@solid-primitives/upload"], // This is necessary because otherwise `vite dev` can't find the wasm exclude: ["@mutinywallet/mutiny-wasm", "@mutinywallet/waila-wasm"], },