diff options
| author | Adam Soltys <[email protected]> | 2022-09-29 15:05:13 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2022-09-29 15:05:13 -0700 |
| commit | 64911388f80d52d6dd53d707457a37fe386c194e (patch) | |
| tree | b96d7c1b85857459d6a91673e5ac6598eed7bd98 | |
| parent | 9e07792fcdd0ba0b7c07a20fe83db54597388e26 (diff) | |
| download | coinos-ui-64911388f80d52d6dd53d707457a37fe386c194e.tar.gz coinos-ui-64911388f80d52d6dd53d707457a37fe386c194e.zip | |
address parsing
| -rw-r--r-- | package.json | 13 | ||||
| -rw-r--r-- | pnpm-lock.yaml | 311 | ||||
| -rw-r--r-- | src/components/Numpad.svelte | 153 | ||||
| -rw-r--r-- | src/components/RegisterOrLogin.svelte | 6 | ||||
| -rw-r--r-- | src/components/index.js | 1 | ||||
| -rw-r--r-- | src/lib/parse.js | 296 | ||||
| -rw-r--r-- | src/lib/utils.js | 4 | ||||
| -rw-r--r-- | src/routes/logout/+page.server.js | 25 | ||||
| -rw-r--r-- | src/routes/scan/+page.svelte | 7 | ||||
| -rw-r--r-- | src/routes/send/+page.svelte | 69 | ||||
| -rw-r--r-- | src/routes/send/bitcoin/[address]/+page.server.js | 8 | ||||
| -rw-r--r-- | src/routes/send/bitcoin/[address]/+page.svelte | 39 | ||||
| -rw-r--r-- | src/routes/send/lightning/+page.svelte | 0 | ||||
| -rw-r--r-- | src/routes/send/lnurl/+page.svelte | 0 |
14 files changed, 593 insertions, 339 deletions
diff --git a/package.json b/package.json index 9c8dadf9..07deb599 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,21 @@ "format": "prettier --write --plugin-search-dir=. ." }, "devDependencies": { + "@lottiefiles/svelte-lottie-player": "^0.2.0", "@sveltejs/adapter-node": "next", - "@sveltejs/kit": "1.0.0-next.470", + "@sveltejs/kit": "1.0.0-next.505", "@zerodevx/svelte-toast": "^0.7.2", "autoprefixer": "^10.4.11", + "bitcoin-address-validation": "^2.2.1", + "bip21": "^2.0.3", + "bolt11": "^1.4.0", "cookie": "^0.5.0", "leaflet": "^1.8.0", "postcss": "^8.4.16", "prettier": "^2.7.1", "prettier-plugin-svelte": "^2.7.0", "qr-code-styling": "1.6.0-rc.1", + "qr-scanner": "^1.4.1", "svelte": "^3.50.1", "svelte-outclick": "^3.1.0", "svelte-pincode": "^2.1.1", @@ -28,9 +33,5 @@ "tailwindcss": "^3.1.8", "vite": "^3.1.1" }, - "type": "module", - "dependencies": { - "@lottiefiles/svelte-lottie-player": "^0.2.0", - "qr-scanner": "^1.4.1" - } + "type": "module" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 249d6f05..d4a3c75f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,9 +3,12 @@ lockfileVersion: 5.4 specifiers: '@lottiefiles/svelte-lottie-player': ^0.2.0 '@sveltejs/adapter-node': next - '@sveltejs/kit': 1.0.0-next.470 + '@sveltejs/kit': 1.0.0-next.505 '@zerodevx/svelte-toast': ^0.7.2 autoprefixer: ^10.4.11 + bip21: ^2.0.3 + bitcoin-address-validation: ^2.2.1 + bolt11: ^1.4.0 cookie: ^0.5.0 leaflet: ^1.8.0 postcss: ^8.4.16 @@ -21,21 +24,22 @@ specifiers: tailwindcss: ^3.1.8 vite: ^3.1.1 -dependencies: - '@lottiefiles/svelte-lottie-player': 0.2.0 - qr-scanner: 1.4.1 - devDependencies: + '@lottiefiles/svelte-lottie-player': 0.2.0 '@sveltejs/adapter-node': 1.0.0-next.96 - '@sveltejs/kit': [email protected][email protected] + '@sveltejs/kit': [email protected][email protected] '@zerodevx/svelte-toast': 0.7.2 autoprefixer: [email protected] + bip21: 2.0.3 + bitcoin-address-validation: 2.2.1 + bolt11: 1.4.0 cookie: 0.5.0 leaflet: 1.8.0 postcss: 8.4.16 prettier: 2.7.1 prettier-plugin-svelte: 2.7.0_nk6d2fkgcllkkdynqbuearcure qr-code-styling: 1.6.0-rc.1 + qr-scanner: 1.4.1 svelte: 3.50.1 svelte-outclick: 3.1.0 svelte-pincode: 2.1.1 @@ -59,7 +63,7 @@ packages: resolution: {integrity: sha512-sV8YkO8hCDGq67LCCqjT+JW6cAbVCIw9wtgrOWz+Ao6Q8cD7ZvdsCiipSIMIH55Ja6MWwEXP4N4nKD+jL3XQLg==} dependencies: lottie-web: 5.9.6 - dev: false + dev: true /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -155,8 +159,8 @@ packages: rollup: 2.78.1 dev: true - /@sveltejs/kit/[email protected][email protected]: - resolution: {integrity: sha512-gXe+x4pQSxjI1oNo74WOcMXc6sIFJuUAhwAaZ2jcDw+9vpjKJnH/hZFzER97YQA5Oz+iRdv6Mzw1+pprSJoT9Q==} + /@sveltejs/kit/[email protected][email protected]: + resolution: {integrity: sha512-vg2WvWiUB7useJZOKbdM8WOXv10WD7SVDER74IXd1t/TWb/uXHzwMQ/ZAsXZFdxQsz1cDGFub3iC76PW+j58Pg==} engines: {node: '>=16.14'} hasBin: true requiresBuild: true @@ -165,6 +169,7 @@ packages: vite: ^3.1.0 dependencies: '@sveltejs/vite-plugin-svelte': [email protected][email protected] + '@types/cookie': 0.5.1 cookie: 0.5.0 devalue: 3.1.3 kleur: 4.1.5 @@ -220,6 +225,16 @@ packages: resolution: {integrity: sha512-HheveklTjp3hxpYQhoHfyA6B4bQaUeSV5MQf2usIv/58UF2jY/YqhCAWj9bDBjufbuZc5pSz4BXvdX3WVT+viA==} dev: true + /@types/bn.js/4.11.6: + resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} + dependencies: + '@types/node': 18.7.18 + dev: true + + /@types/cookie/0.5.1: + resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} + dev: true + /@types/estree/0.0.39: resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} dev: true @@ -234,7 +249,7 @@ packages: /@types/offscreencanvas/2019.7.0: resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==} - dev: false + dev: true /@types/pug/2.0.6: resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} @@ -307,11 +322,80 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /base-x/3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /base58-js/1.0.4: + resolution: {integrity: sha512-DQtWOeY+JwAUyFaL1KBqL0L81LWUj5S92N39LCiQwBouHz1GNZBqyhJz9ZtIDEtwaBYyoF63x27oqFL0Lu7DUg==} + engines: {node: '>= 8'} + dev: true + + /bech32/1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + dev: true + + /bech32/2.0.0: + resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==} + dev: true + /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true + /bip174/2.1.0: + resolution: {integrity: sha512-lkc0XyiX9E9KiVAS1ZiOqK1xfiwvf4FXDDdkDq5crcDzOq+xGytY+14qCsqz7kCiy8rpN1CRNfacRhf9G3JNSA==} + engines: {node: '>=8.0.0'} + dev: true + + /bip21/2.0.3: + resolution: {integrity: sha512-L4ODmASLjsHYAU+TG7xffkYNMvHzAe4mkVX7mcvOUyKAr/MDBPrsRgqUhE8EmKdeEKHk5SYpX1Aexzvm/6WdbQ==} + dependencies: + qs: 6.11.0 + dev: true + + /bitcoin-address-validation/2.2.1: + resolution: {integrity: sha512-f6LXNpvRKlTbHWb37N9tHoAbYGbshzM8FPWvCtloh++hxZ0/dmkokvKNVLz6HkG82zVwo8w6Sq4JmfO2timzyg==} + dependencies: + base58-js: 1.0.4 + bech32: 2.0.0 + sha256-uint8array: 0.10.3 + dev: true + + /bitcoinjs-lib/6.0.2: + resolution: {integrity: sha512-I994pGt9cL5s5OA6mkv1e8IuYcsKN2ORXnWbkqAXLNGvEnOHBhKBSvCjFl7YC2uVoJnfr/iwq7JMrq575SYO5w==} + engines: {node: '>=8.0.0'} + dependencies: + bech32: 2.0.0 + bip174: 2.1.0 + bs58check: 2.1.2 + create-hash: 1.2.0 + ripemd160: 2.0.2 + typeforce: 1.18.0 + varuint-bitcoin: 1.1.2 + wif: 2.0.6 + dev: true + + /bn.js/4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + dev: true + + /bolt11/1.4.0: + resolution: {integrity: sha512-TeGIOpFNrvNA1XGvwBr+lYmzKfoJeyMRt7nsGmIci+5gbmSz7s46jwKLNYXH3IoxV7fjmYUEUu2NM19n9w0msg==} + dependencies: + '@types/bn.js': 4.11.6 + bech32: 1.1.4 + bitcoinjs-lib: 6.0.2 + bn.js: 4.12.0 + create-hash: 1.2.0 + lodash: 4.17.21 + safe-buffer: 5.2.1 + secp256k1: 4.0.3 + dev: true + /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -326,6 +410,10 @@ packages: fill-range: 7.0.1 dev: true + /brorand/1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + dev: true + /browserslist/4.21.4: resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -337,6 +425,20 @@ packages: update-browserslist-db: [email protected] dev: true + /bs58/4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + dependencies: + base-x: 3.0.9 + dev: true + + /bs58check/2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + dev: true + /buffer-crc32/0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} dev: true @@ -346,6 +448,13 @@ packages: engines: {node: '>=6'} dev: true + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.3 + dev: true + /camelcase-css/2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -370,6 +479,13 @@ packages: fsevents: 2.3.2 dev: true + /cipher-base/1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true @@ -387,6 +503,16 @@ packages: engines: {node: '>= 0.6'} dev: true + /create-hash/1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + dev: true + /cssesc/3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -450,6 +576,18 @@ packages: resolution: {integrity: sha512-Sh/7YsHqQYkA6ZHuHMy24e6TE4eX6KZVsZb9E/DvU1nQRIrH4BflO/4k+83tfdYvDl+MObvlqHPRICzEdC9c6Q==} dev: true + /elliptic/6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: true + /es6-promise/3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} dev: true @@ -735,6 +873,14 @@ packages: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true + /get-intrinsic/1.1.3: + resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + /glob-parent/5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -772,6 +918,11 @@ packages: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} dev: true + /has-symbols/1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + /has/1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -779,6 +930,30 @@ packages: function-bind: 1.1.1 dev: true + /hash-base/3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.0 + safe-buffer: 5.2.1 + dev: true + + /hash.js/1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: true + + /hmac-drbg/1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: true + /inflight/1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -851,9 +1026,13 @@ packages: engines: {node: '>=10'} dev: true + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + /lottie-web/5.9.6: resolution: {integrity: sha512-JFs7KsHwflugH5qIXBpB4905yC1Sub2MZWtl/elvO/QC6qj1ApqbUZJyjzJseJUtVpgiDaXQLjBlIJGS7UUUXA==} - dev: false + dev: true /magic-string/0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} @@ -868,6 +1047,14 @@ packages: sourcemap-codec: 1.4.8 dev: true + /md5.js/1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + /merge2/1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -892,6 +1079,14 @@ packages: engines: {node: '>=4'} dev: true + /minimalistic-assert/1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + dev: true + + /minimalistic-crypto-utils/1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + dev: true + /minimatch/3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -929,6 +1124,10 @@ packages: hasBin: true dev: true + /node-addon-api/2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + dev: true + /node-domexception/1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -943,6 +1142,11 @@ packages: formdata-polyfill: 4.0.10 dev: true + /node-gyp-build/4.5.0: + resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} + hasBin: true + dev: true + /node-releases/2.0.6: resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} dev: true @@ -962,6 +1166,10 @@ packages: engines: {node: '>= 6'} dev: true + /object-inspect/1.12.2: + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + /once/1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -1087,12 +1295,19 @@ packages: resolution: {integrity: sha512-xiR90NONHTfTwaFgW/ihlqjGMIZg6ExHDOvGQRba1TvV+WVw7GoDArIOt21e+RO+9WiO4AJJq+mwc5f4BnGH3w==} dependencies: '@types/offscreencanvas': 2019.7.0 - dev: false + dev: true /qrcode-generator/1.4.4: resolution: {integrity: sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==} dev: true + /qs/6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -1108,6 +1323,15 @@ packages: pify: 2.3.0 dev: true + /readable-stream/3.6.0: + resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + /readdirp/3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -1136,6 +1360,13 @@ packages: glob: 7.2.3 dev: true + /ripemd160/2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + dev: true + /rollup/2.78.1: resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==} engines: {node: '>=10.0.0'} @@ -1157,6 +1388,10 @@ packages: mri: 1.2.0 dev: true + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + /sander/0.5.1: resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} dependencies: @@ -1166,10 +1401,40 @@ packages: rimraf: 2.7.1 dev: true + /secp256k1/4.0.3: + resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} + engines: {node: '>=10.0.0'} + requiresBuild: true + dependencies: + elliptic: 6.5.4 + node-addon-api: 2.0.2 + node-gyp-build: 4.5.0 + dev: true + /set-cookie-parser/2.5.1: resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==} dev: true + /sha.js/2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /sha256-uint8array/0.10.3: + resolution: {integrity: sha512-SFTs87RfXVulKrhhP6B5/qcFruOKQZaKf6jY9V4PJ7NOG0qIlQP6XL4pQq5xagsuP/Wd55S7tUBJpRajEsDUEQ==} + dev: true + + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + object-inspect: 1.12.2 + dev: true + /sirv/2.0.2: resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==} engines: {node: '>= 10'} @@ -1198,6 +1463,12 @@ packages: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} dev: true + /string_decoder/1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /strip-indent/3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -1345,6 +1616,10 @@ packages: engines: {node: '>=6'} dev: true + /typeforce/1.18.0: + resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} + dev: true + /undici/5.10.0: resolution: {integrity: sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==} engines: {node: '>=12.18'} @@ -1365,6 +1640,12 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true + /varuint-bitcoin/1.1.2: + resolution: {integrity: sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /vite/3.1.1: resolution: {integrity: sha512-hgxQWev/AL7nWYrqByYo8nfcH9n97v6oFsta9+JX8h6cEkni7nHKP2kJleNYV2kcGhE8jsbaY1aStwPZXzPbgA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -1397,6 +1678,12 @@ packages: engines: {node: '>= 8'} dev: true + /wif/2.0.6: + resolution: {integrity: sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==} + dependencies: + bs58check: 2.1.2 + dev: true + /wrappy/1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true diff --git a/src/components/Numpad.svelte b/src/components/Numpad.svelte new file mode 100644 index 00000000..f00f33c1 --- /dev/null +++ b/src/components/Numpad.svelte @@ -0,0 +1,153 @@ +<script> + import { Icon } from "$comp"; + import { selectedRate, user } from '$lib/store'; + import { f, s, post, warning, sats } from '$lib/utils'; + import { t } from '$lib/translations'; + + export let amount, currency; + + let useFiat = true; + let amountFiat = 0; + let amountSats = 0; + let loading = false; + + let symbol = + { + USD: '$', + CAD: '$', + AUD: '$', + NZD: '$', + MXN: '$', + BRL: '$', + HKD: '$', + TWD: '$', + JPY: '¥', + CNY: '¥', + GBP: '£', + EUR: '€', + KRW: '₩' + }[currency] || ''; + + $: amount = parseInt(useFiat ? Math.round(amountFiat / ($selectedRate / sats)) : amountSats); + + $: amountSatsFormatted = s(amountSats); + + $: amountFiatConverted = f(amountSats * ($selectedRate / sats), $user.currency); + + $: amountSatsConverted = s(amountFiat / ($selectedRate / sats)); + + const numPad = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0', '<']; + + const handleInput = (value) => { + if (useFiat) { + if (amountFiat === 0 && value !== '.' && value !== '<' && value !== '0') { + amountFiat = value; + } else if ((amountFiat === 0 || amountFiat === '0') && value === '0') { + return; + } else if (amountFiat === 0 && value === '.') { + amountFiat = '0.'; + } else if (amountFiat !== 0 && amountFiat.includes('.') && value === '.') { + return; + } else if (value === '<') { + if (amountFiat !== 0) { + amountFiat = amountFiat.slice(0, amountFiat.length - 1); + if (amountFiat.length === 0) { + amountFiat = 0; + amountSats = 0; + } + } + } else if (value !== '.' && value !== '<' && parseInt(amountFiat + value) > $selectedRate) { + warning($t('user.receive.lessThan1BTCWarning')); + } else if (amountFiat !== 0 && amountFiat.match(/\.../)) { + return; + } else { + amountFiat = amountFiat + value; + } + } else { + if (value === '.') { + return; + } else if (!amountSats && value !== '<' && value !== '0') { + amountSats = parseInt(value); + } else if (value === '<') { + if (amountSats !== 0) { + amountSats = Math.floor(amountSats / 10); + if (amountSats.length === 0) { + amountSats = 0; + amountFiat = 0; + } + } + } else if (value !== '<' && parseInt(amountSats + value) > sats) { + warning($t('user.receive.lessThan1BTCWarning')); + } else { + amountSats = parseInt(amountSats + value); + } + } + }; +</script> + +<div class="flex justify-center items-center mb-3 px-3"> + {#if $selectedRate} + <div class="space-y-5"> + <!-- amounts --> + <div class="text-center"> + <div class="text-5xl md:text-6xl font-semibold tracking-widest mb-1"> + {useFiat ? `${symbol}${amountFiat}` : amountSatsFormatted}<span + class="tracking-normal text-base font-normal">{useFiat ? $user.currency : 'SAT'}</span + > + </div> + <span class="text-secondary mr-1" + >{useFiat ? `${amountSatsConverted} SAT` : amountFiatConverted}</span + > + <button + on:click={() => { + if (useFiat) { + amountSats = parseInt((amountFiat / ($selectedRate / sats)).toFixed(0)); + } else { + amountFiat = + (amountSats * ($selectedRate / sats)).toFixed(2) > 0.0 + ? (amountSats * ($selectedRate / sats)).toFixed(2) + : 0; + } + useFiat = !useFiat; + }}><Icon icon="swap" style="inline hover:opacity-80" /></button + > + </div> + + <!-- numpad --> + <div class="grid grid-cols-3 gap-2 w-full md:w-[300px] mx-auto"> + {#each numPad as value} + {#if value === '<'} + <button + class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white flex justify-center items-center hover:opacity-80" + on:click={() => handleInput(value)} + > + <svg + class="w-5" + width="24" + height="24" + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M15 19L8 12L15 5" + stroke="currentColor" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + /> + </svg> + </button> + {:else} + <button + class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white hover:opacity-80" + on:click={() => handleInput(value)}>{value}</button + > + {/if} + {/each} + </div> + </div> + {:else} + <div class="w-full md:w-[300px] h-[475px] md:h-[485px] animate-pulse bg-gray-400 rounded-xl" /> + {/if} +</div> diff --git a/src/components/RegisterOrLogin.svelte b/src/components/RegisterOrLogin.svelte index fa805a1d..8f10fadd 100644 --- a/src/components/RegisterOrLogin.svelte +++ b/src/components/RegisterOrLogin.svelte @@ -3,7 +3,7 @@ import { page } from '$app/stores'; import { tick } from 'svelte'; import { Icon } from '$comp'; - import { post, failure } from '$lib/utils'; + import { focus, post, failure } from '$lib/utils'; import { redirect, user, token } from '$lib/store'; import { auth } from '$lib/socket'; import { goto } from '$app/navigation'; @@ -25,10 +25,6 @@ // TODO: move to server side $: if (browser && $user) goto(`/${$user.username}/receive`); - - let focus = (el) => setTimeout(() => el.focus()); - - console.log('REDIRECT STORE', $redirect); </script> <div class="pt-10"> diff --git a/src/components/index.js b/src/components/index.js index ba0f6516..48d5ecd0 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -1,3 +1,4 @@ +export { default as Numpad } from './Numpad.svelte'; export { default as Spinner } from './Spinner.svelte'; export { default as Check } from './Check.svelte'; export { default as Heart } from './Heart.svelte'; diff --git a/src/lib/parse.js b/src/lib/parse.js index 2a827956..2abc2cba 100644 --- a/src/lib/parse.js +++ b/src/lib/parse.js @@ -1,271 +1,39 @@ -export default (text) => { +// import bolt11 from 'bolt11'; +import validate from 'bitcoin-address-validation'; +import bip21 from 'bip21'; +import { get } from '$lib/utils'; +import { goto } from "$app/navigation"; + +let debounce; +export default async (text) => { if (!text) return; + console.log("parsing") - if (text.includes('@') && text.includes('.')) { - let [name, domain] = text.split('@'); - try { - clearTimeout(debounce); - await new Promise((r) => (debounce = setTimeout(r, 1500))); - ({ data: text } = await Vue.axios.get( - `/encode?domain=${domain}&name=${name}` - )); - } catch (e) {} + // lightning + if (text.startsWith('ln')) { + try { + console.log('lightning'); + } catch (e) {} } - try { - if (text.toLowerCase().slice(0, 10) === 'lightning:') - text = text.slice(10); - let payreq = text.toLowerCase(); - payment.payreq = payreq; - payment.payobj = bolt11.decode(payment.payreq); - let { - network: { bech32 }, - } = payment.payobj; - - if (!networks.includes('lightning')) - return commit('error', 'Lightning not supported in this account'); - - if (bech32 !== process.env.VUE_APP_NETWORK_BECH32) { - dispatch('clearPayment'); - commit( - 'error', - `Wrong network prefix '${bech32}' instead of '${process.env.VUE_APP_NETWORK_BECH32}'` - ); - throw new Error('Wrong network'); - } - - if (user.account.ticker !== 'BTC') - await dispatch( - 'shiftAccount', - user.accounts.find((a) => a.asset === BTC).id - ); - - let { tags, satoshis, millisatoshis } = payment.payobj; - let description = tags.find((t) => t.tagName === 'description'); - if (description) payment.memo = description.data; - payment.amount = millisatoshis - ? Math.round(millisatoshis / 1000) - : satoshis; - payment.fiatAmount = ((payment.amount * getters.rate) / SATS).toFixed( - 2 - ); - payment.network = 'lightning'; + // bitcoin + if (validate(text)) { + console.log('bitcoin'); + goto(`/send/bitcoin/${text}`); + } - await Vue.axios.post('/lightning/query', { payreq }); - if (!getters.payment.recipient) - go({ name: 'send', params: { keep: true } }); + // ln address + if (text.includes('@') && text.includes('.')) { + console.log("ln address") + let [name, domain] = text.split('@'); + try { + clearTimeout(debounce); + await new Promise((r) => (debounce = setTimeout(r, 1500))); + let lnurl = await get(`/encode?domain=${domain}&name=${name}`); + console.log('lnurl', lnurl); + } catch (e) {} + } - return; - } catch (e) { - if (e.response) commit('error', e.response.data); - } - // - // let url; - // try { - // if (nodes.includes('bitcoin')) { - // url = bip21.decode(text); - // if (!networks.includes('bitcoin')) - // return commit('error', 'Bitcoin not supported in this account'); - // payment.network = 'bitcoin'; - // url.options.asset = BTC; - // } - // } catch (e) { - // if (nodes.includes('liquid')) { - // try { - // url = bip21.decode(text, 'liquidnetwork'); - // if (!networks.includes('liquid')) - // return commit('error', 'Liquid not supported in this account'); - // payment.network = 'liquid'; - // } catch (e) { - // /**/ - // } - // } - // } - // - // if (url) { - // let { amount, asset, assetid, message } = url.options; - // if (assetid) asset = assetid; - // if (!asset) asset = BTC; - // let account = user.accounts.find((a) => a.asset === asset); - // if (account) { - // if (account.asset !== user.account.asset) - // await dispatch('shiftAccount', account.id); - // } else return commit('error', 'Unrecognized asset'); - // - // payment.address = url.address; - // - // if (message) payment.memo = message; - // - // if (amount) { - // payment.amount = parseInt((amount * SATS).toFixed(0)); - // payment.fiatAmount = ((payment.amount * getters.rate) / SATS).toFixed( - // 2 - // ); - // } - // - // await dispatch('isInternal'); - // await dispatch('estimateFee'); - // go({ name: 'send', params: { keep: true } }); - // return; - // } - // - // if (nodes.includes('bitcoin') && validate(text)) { - // if (!networks.includes('bitcoin')) - // return commit('error', 'Bitcoin not supported in this account'); - // payment.address = text; - // payment.network = 'bitcoin'; - // await dispatch('isInternal'); - // go({ name: 'send', params: { keep: true } }); - // return; - // } - // - // // Liquid - // if (nodes.includes('liquid') && isLiquid(text)) { - // if (!networks.includes('liquid')) - // return commit('error', 'Liquid not supported in this account'); - // payment.address = text; - // payment.network = 'liquid'; - // await dispatch('isInternal'); - // go({ name: 'send', params: { keep: true } }); - // return; - // } - // - // if (text.startsWith('6P')) { - // commit('text', text); - // return go('/decrypt'); - // } - // - // try { - // let ecpair = ECPair.fromWIF(text, { - // ...this._vm.$network, - // confidentialPrefix: 1, - // assetHash: '', - // }); - // commit('ecpair', ecpair); - // go('/sweep'); - // } catch (e) { - // /* */ - // } - // - // if (text.toLowerCase().startsWith('lnurl:')) { - // try { - // const { data: lnurl } = await Vue.axios.get(`/url?code=${text}`); - // await dispatch('handleScan', lnurl); - // return; - // } catch (e) { - // commit('error', e.response ? e.response.data : e.message); - // } - // } - // - // if (text.toLowerCase().includes('lnurl')) { - // commit('loading', true); - // let txt = text.toLowerCase().match(/lnurl[a-z0-9]+/); - // - // try { - // const { data: params } = await Vue.axios.get(`/decode?text=${txt}`); - // if (params.status === 'ERROR') { - // let { reason } = params; - // try { - // ({ reason } = JSON.parse(reason.replace(/.*{/, '{'))); - // } catch { - // /**/ - // } - // - // commit('loading', false); - // return commit('error', reason); - // } - // - // let { seed } = getters; - // - // switch (params.tag) { - // case 'channelRequest': - // await dispatch('openChannel', params); - // break; - // case 'login': - // if (!seed) ({ seed } = await dispatch('passwordPrompt')); - // try { - // const key = linkingKey(params.domain, seed); - // const signedMessage = secp256k1.ecdsaSign( - // hexToUint8Array(params.k1), - // key.privateKey - // ); - // const signedMessageDER = secp256k1.signatureExport( - // signedMessage.signature - // ); - // const linkingKeyPub = secp256k1.publicKeyCreate( - // key.privateKey, - // true - // ); - // const sig = bytesToHexString(signedMessageDER); - // - // const response = await Vue.axios.post('/login', { - // params, - // sig, - // key: bytesToHexString(linkingKeyPub), - // }); - // - // if (response.data.status === 'OK') { - // commit('snack', 'Login success'); - // } else { - // commit('error', response.status); - // } - // - // go('/home'); - // } catch (e) { - // commit('error', e.response ? e.response.data : e.message); - // } - // break; - // - // case 'withdrawRequest': - // commit('lnurl', params); - // go('/withdraw'); - // break; - // case 'payRequest': - // commit('lnurl', params); - // go('/pay'); - // break; - // } - // } catch (e) { - // commit('error', e.response ? e.response.data : e.message); - // } - // - // commit('loading', false); - // } - // - // if (isUuid(text)) { - // try { - // const { data: payment } = await Vue.axios.post('/checkRedeemCode', { - // redeemcode: text, - // }); - // - // if (payment) { - // window.location.href = `${window.location.protocol}//${window.location.host}/redeem/${text}`; - // return; - // } - // } catch (e) { - // commit('error', e.response ? e.response.data : e.message); - // } - // - // try { - // const { data: invoice } = await Vue.axios.get( - // `/invoice?uuid=${text}` - // ); - // await dispatch('handleScan', invoice.text); - // return; - // } catch (e) { - // commit('error', e.response ? e.response.data : e.message); - // } - // } - // - // if ( - // text.startsWith( - // `${window.location.protocol}//${window.location.host}/redeem` - // ) - // ) { - // window.location.href = text; - // } - // - // commit('stopScanning', true); - // - // return 'no'; + // user + console.log("username") }; diff --git a/src/lib/utils.js b/src/lib/utils.js index 61e2ddac..514e3adb 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -146,6 +146,8 @@ export const toggleFullscreen = (el) => export const sats = 100000000; -export const goBack = () => { +export const back = () => { browser && history.go(-1); }; + +export const focus = (el) => setTimeout(() => el.focus()); diff --git a/src/routes/logout/+page.server.js b/src/routes/logout/+page.server.js index 3eae005f..726094fd 100644 --- a/src/routes/logout/+page.server.js +++ b/src/routes/logout/+page.server.js @@ -7,19 +7,18 @@ const opts = { path: '/' }; -export async function load({ setHeaders }) { - setHeaders({ - 'set-cookie': [ - cookie.serialize('token', '', { - ...opts, - expires: new Date(0) - }), - cookie.serialize('refresh_token', '', { - ...opts, - expires: new Date(0) - }) - ] - }); +export async function load({ cookies }) { + console.log('COOKIES', cookies); + cookies.set('set-cookie', [ + cookies.serialize('token', '', { + ...opts, + expires: new Date(0) + }), + cookies.serialize('refresh_token', '', { + ...opts, + expires: new Date(0) + }) + ]); throw redirect(302, '/logout/done'); } diff --git a/src/routes/scan/+page.svelte b/src/routes/scan/+page.svelte index 5c8c09f6..9b1072e0 100644 --- a/src/routes/scan/+page.svelte +++ b/src/routes/scan/+page.svelte @@ -2,11 +2,12 @@ import { Icon } from "$comp"; import QrScanner from 'qr-scanner'; import { onMount } from 'svelte'; - import { goBack } from "$lib/utils"; + import { back } from "$lib/utils"; + import { goto } from "$app/navigation"; let scanner, vid; onMount(() => { - scanner = new QrScanner(vid, console.log); + scanner = new QrScanner(vid, (text) => goto(`/send/${text}`)); scanner.start(); }); @@ -14,7 +15,7 @@ <button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" - on:click={goBack} + on:click={back} > <Icon icon="arrow-left" style="w-10" /> </button> diff --git a/src/routes/send/+page.svelte b/src/routes/send/+page.svelte index 777f9766..2162d76d 100644 --- a/src/routes/send/+page.svelte +++ b/src/routes/send/+page.svelte @@ -1,40 +1,32 @@ <script> + import { browser } from '$app/environment'; import { t } from '$lib/translations'; import { AppHeader, Icon, Spinner } from '$comp'; + import { back, focus } from '$lib/utils'; + import parse from '$lib/parse'; - let payreq = '', - loading, - payreqField; + let text, loading; - let withdraw = async () => { - loading = true; - try { - await post('/withdraw', { payreq }); - loading = false; - } catch (e) { - failure(e.message); - loading = false; - } + let paste = async () => { + text = await navigator.clipboard.readText(); }; </script> -<AppHeader avatarPosition="left-[calc(50vw-64px)] lg:left-[calc(15vw-64px)]" /> +<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}> + <Icon icon="arrow-left" style="w-10" /> +</button> <div class="container px-4 mt-20 max-w-xl mx-auto"> <div> - <!-- found missing translation --> - <label for="invoice" class="font-bold mb-1 block" - >Destination <small class="text-secondary">Address, Invoice, User, Email or Phone</small - ></label - > + <label for="invoice" class="font-bold mb-1 block">Destination</label> - <div class="relative"> + <div class="relative mb-8"> <input - bind:this={payreqField} + placeholder="Address, Invoice, Username" type="text" - name="payreq" + name="text" required - bind:value={payreq} + bind:value={text} class="block rounded-2xl p-3 w-full bg-primary" /> @@ -43,20 +35,27 @@ <Icon icon="scan" style="mr-2 w-6 my-auto" /> </div> </a> + + {#if browser && navigator.clipboard} + <div class="flex absolute h-[48px] right-10 top-0 px-2 mt-[1px]" on:click={paste}> + <Icon icon="paste" style="mr-2 w-6 my-auto" /> + </div> + {/if} </div> </div> - <button - disabled={!payreq} - class="{!payreq - ? 'opacity-50' - : 'opacity-100 hover:opacity-80'} rounded-2xl border py-3 font-bold w-full mt-2 bg-black text-white" - on:click={withdraw} - > - {#if loading} - <Spinner /> - {:else} - {$t('user.dashboard.go')} - {/if} - </button> + <div class="flex w-full"> + <button + class="{!text + ? 'opacity-50' + : 'opacity-100 hover:opacity-80'} rounded-2xl border py-3 font-bold mx-auto mt-2 bg-black text-white px-4 w-24" + on:click={() => parse(text)} + > + {#if loading} + <Spinner /> + {:else} + {$t('user.dashboard.go')} + {/if} + </button> + </div> </div> diff --git a/src/routes/send/bitcoin/[address]/+page.server.js b/src/routes/send/bitcoin/[address]/+page.server.js new file mode 100644 index 00000000..8cdf7276 --- /dev/null +++ b/src/routes/send/bitcoin/[address]/+page.server.js @@ -0,0 +1,8 @@ +import { redirect } from "@sveltejs/kit"; +export const actions = { + default: async ({ request }) => { + let form = Object.fromEntries(await request.formData()); + console.log('send bitcoin', form); + throw redirect(307, '/'); + } +}; diff --git a/src/routes/send/bitcoin/[address]/+page.svelte b/src/routes/send/bitcoin/[address]/+page.svelte new file mode 100644 index 00000000..fd635fd5 --- /dev/null +++ b/src/routes/send/bitcoin/[address]/+page.svelte @@ -0,0 +1,39 @@ +<script> + import { AppHeader, Icon, Numpad } from '$comp'; + import { page } from '$app/stores'; + import { back } from '$lib/utils'; + export let data; + + let { address } = $page.params; + let { currency } = data.user; + let amount, loading; +</script> + +<button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}> + <Icon icon="arrow-left" style="w-10" /> +</button> + +<div class="container px-4 mt-20 max-w-xl mx-auto"> + <div class="text-center mb-8"> + <h1 class="text-3xl md:text-4xl font-semibold mb-2">Send to</h1> + <p class="text-lg text-secondary">{address}</p> + </div> + <Numpad bind:amount {currency} /> + + <form method="POST"> + <input name="address" value={address} type="hidden" /> + <input name="amount" value={amount} type="hidden" /> + <div class="flex w-full"> + <button + type="submit" + class="opacity-100 hover:opacity-80'} rounded-2xl border py-3 font-bold mx-auto mt-2 bg-black text-white px-4 w-24" + > + {#if loading} + <Spinner /> + {:else} + Send + {/if} + </button> + </div> + </form> +</div> diff --git a/src/routes/send/lightning/+page.svelte b/src/routes/send/lightning/+page.svelte new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/routes/send/lightning/+page.svelte diff --git a/src/routes/send/lnurl/+page.svelte b/src/routes/send/lnurl/+page.svelte new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/routes/send/lnurl/+page.svelte |
