diff options
| -rwxr-xr-x | bun.lockb | bin | 59851 -> 60922 bytes | |||
| -rw-r--r-- | package.json | 3 | ||||
| -rw-r--r-- | src/lib/Mnemonic.svelte | 16 | ||||
| -rw-r--r-- | src/lib/index.ts | 8 | ||||
| -rw-r--r-- | src/routes/+layout.svelte | 12 | ||||
| -rw-r--r-- | src/routes/+layout.ts | 1 | ||||
| -rw-r--r-- | src/routes/+page.svelte | 16 | ||||
| -rw-r--r-- | src/routes/create/+page.svelte | 44 | ||||
| -rw-r--r-- | src/routes/created/+page.svelte | 0 | ||||
| -rw-r--r-- | static/random.svg | 6 | ||||
| -rw-r--r-- | static/type.svg | 19 |
11 files changed, 121 insertions, 4 deletions
| Binary files differ diff --git a/package.json b/package.json index 0ad98ab..0179457 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,8 @@ "tailwindcss": "^4.0.0", "typescript": "^5.0.0", "vite": "^7.0.4" + }, + "dependencies": { + "@scure/bip39": "^1.6.0" } } diff --git a/src/lib/Mnemonic.svelte b/src/lib/Mnemonic.svelte new file mode 100644 index 0000000..117c98f --- /dev/null +++ b/src/lib/Mnemonic.svelte @@ -0,0 +1,16 @@ +<script> + let { mnemonic } = $props(); +</script> + +<div class="card"> + <div + class="card-body text-secondary grid grid-flow-col grid-rows-6 sm:grid-rows-none grid-cols-2 sm:grid-cols-3 sm:grid-flow-row gap-x-8 gap-y-2 justify-center whitespace-nowrap m-auto" + > + {#each mnemonic.split(" ") as w, i} + <div> + <span class="select-none text-neutral">{i + 1}.</span> + <span>{@html w === "-" ? "—" : w}</span> + </div> + {/each} + </div> +</div> diff --git a/src/lib/index.ts b/src/lib/index.ts index 856f2b6..02f71ba 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1 +1,7 @@ -// place files you want to import through the `$lib` alias in this folder. +import { writable } from 'svelte/store'; +import { browser } from "$app/environment"; + +export const focus = (el: HTMLElement) => + browser && screen.width > 1280 && setTimeout(() => el.focus(), 1); + +export const mnemonic = writable(); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index b93e9ba..1729999 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -4,4 +4,14 @@ let { children } = $props(); </script> -{@render children()} +<div class="container mx-auto mt-10 space-y-5 rounded-2xl bg-gray-100 p-8 text-xl shadow-lg"> + <div class="flex"> + <a href="/" class="mx-auto text-2xl">Bitcoin Wallet</a> + </div> + + {@render children()} +</div> + +<div class="my-4 flex"> + <a href="https://github.com/asoltys/paper" class="mx-auto">Source code</a> +</div> diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts new file mode 100644 index 0000000..a3d1578 --- /dev/null +++ b/src/routes/+layout.ts @@ -0,0 +1 @@ +export const ssr = false; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index cc88df0..44bcb6a 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,2 +1,14 @@ -<h1>Welcome to SvelteKit</h1> -<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p> +<div class="flex flex-wrap justify-center gap-2"> + <a + href="/create" + class="flex w-full justify-center gap-2 rounded-2xl border bg-white p-4 md:w-60" + > + <img src="/random.svg" class="w-8" /> + <div class="my-auto">Generate</div> + </a> + + <a href="/type" class="flex w-full justify-center gap-2 rounded-2xl border bg-white p-4 md:w-60"> + <img src="/type.svg" class="w-8" /> + <div class="my-auto">Import</div> + </a> +</div> diff --git a/src/routes/create/+page.svelte b/src/routes/create/+page.svelte new file mode 100644 index 0000000..1d09990 --- /dev/null +++ b/src/routes/create/+page.svelte @@ -0,0 +1,44 @@ +<script> + import { goto } from '$app/navigation'; + import { onMount, tick } from 'svelte'; + import { mnemonic, focus } from '$lib'; + import { generateMnemonic } from '@scure/bip39'; + import { wordlist } from '@scure/bip39/wordlists/english'; + import Mnemonic from '$lib/Mnemonic.svelte'; + + let password; + + let submitted; + let bm; + onMount(async () => { + $mnemonic = await generateMnemonic(wordlist); + }); + + let submit = async () => { + submitted = true; + await tick(); + + goto('/created'); + }; +</script> + +<Mnemonic mnemonic={$mnemonic} /> + +<form class="space-y-5 text-center" on:submit|preventDefault={submit}> + <div> + <input + use:focus + name="password" + class="rounded-2xl bg-white p-4 text-2xl" + placeholder="Passphrase" + bind:value={password} + /> + </div> + + <button + type="submit" + class="mx-auto flex w-full justify-center gap-2 rounded-2xl border bg-white p-4 md:w-60" + > + <div class="my-auto">Submit</div> + </button> +</form> diff --git a/src/routes/created/+page.svelte b/src/routes/created/+page.svelte new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/routes/created/+page.svelte diff --git a/static/random.svg b/static/random.svg new file mode 100644 index 0000000..f3e5923 --- /dev/null +++ b/static/random.svg @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> +<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg"> +<title>perspective-dice-random</title> +<path d="M15.676 17.312h0.048c-0.114-0.273-0.263-0.539-0.436-0.78l-11.114-6.346c-0.37 0.13-0.607 0.519-0.607 1.109v9.84c0 1.034 0.726 2.291 1.621 2.808l9.168 5.294c0.544 0.314 1.026 0.282 1.32-0.023v-11.902h-0zM10.049 24.234l-1.83-1.057v-1.918l1.83 1.057v1.918zM11.605 19.993c-0.132 0.2-0.357 0.369-0.674 0.505l-0.324 0.12c-0.23 0.090-0.38 0.183-0.451 0.278-0.071 0.092-0.106 0.219-0.106 0.38v0.242l-1.83-1.056v-0.264c0-0.294 0.056-0.523 0.167-0.685 0.111-0.165 0.346-0.321 0.705-0.466l0.324-0.125c0.193-0.076 0.333-0.171 0.421-0.285 0.091-0.113 0.137-0.251 0.137-0.417 0-0.251-0.081-0.494-0.243-0.728-0.162-0.237-0.389-0.44-0.679-0.608-0.274-0.158-0.569-0.268-0.887-0.329-0.318-0.065-0.649-0.078-0.994-0.040v-1.691c0.409 0.085 0.782 0.19 1.12 0.313s0.664 0.276 0.978 0.457c0.825 0.476 1.453 1.019 1.886 1.627 0.433 0.605 0.649 1.251 0.649 1.937 0 0.352-0.066 0.63-0.198 0.834zM27.111 8.247l-9.531-5.514c-0.895-0.518-2.346-0.518-3.241 0l-9.531 5.514c-0.763 0.442-0.875 1.117-0.336 1.628l10.578 6.040c0.583 0.146 1.25 0.145 1.832-0.003l10.589-6.060c0.512-0.508 0.392-1.17-0.36-1.605zM16.305 10.417l-0.23-0.129c-0.257-0.144-0.421-0.307-0.492-0.488-0.074-0.183-0.062-0.474 0.037-0.874l0.095-0.359c0.055-0.214 0.061-0.389 0.016-0.525-0.041-0.139-0.133-0.248-0.277-0.329-0.219-0.123-0.482-0.167-0.788-0.133-0.309 0.033-0.628 0.141-0.958 0.326-0.31 0.174-0.592 0.391-0.846 0.653-0.257 0.26-0.477 0.557-0.661 0.892l-1.476-0.827c0.332-0.333 0.658-0.625 0.978-0.875s0.659-0.474 1.015-0.674c0.934-0.524 1.803-0.835 2.607-0.934 0.8-0.101 1.5 0.016 2.098 0.352 0.307 0.172 0.508 0.368 0.603 0.589 0.092 0.219 0.097 0.507 0.016 0.865l-0.1 0.356c-0.066 0.255-0.080 0.438-0.041 0.55 0.035 0.11 0.124 0.205 0.265 0.284l0.212 0.118-2.074 1.162zM18.674 11.744l-1.673-0.937 2.074-1.162 1.673 0.937-2.074 1.162zM27.747 10.174l-11.060 6.329c-0.183 0.25-0.34 0.527-0.459 0.813v11.84c0.287 0.358 0.793 0.414 1.37 0.081l9.168-5.294c0.895-0.517 1.621-1.774 1.621-2.808v-9.84c0-0.608-0.251-1.003-0.641-1.121zM23.147 23.68l-1.83 1.056v-1.918l1.83-1.057v1.918zM24.703 17.643c-0.132 0.353-0.357 0.78-0.674 1.284l-0.324 0.494c-0.23 0.355-0.38 0.622-0.451 0.799-0.071 0.174-0.106 0.342-0.106 0.503v0.242l-1.83 1.056v-0.264c0-0.294 0.056-0.587 0.167-0.878 0.111-0.294 0.346-0.721 0.705-1.279l0.324-0.5c0.193-0.298 0.333-0.555 0.421-0.771 0.091-0.218 0.137-0.409 0.137-0.575 0-0.251-0.081-0.4-0.243-0.447-0.162-0.050-0.389 0.009-0.679 0.177-0.274 0.158-0.569 0.39-0.887 0.695-0.318 0.302-0.649 0.671-0.994 1.107v-1.692c0.409-0.387 0.782-0.714 1.12-0.981s0.664-0.491 0.978-0.673c0.825-0.476 1.453-0.659 1.886-0.55 0.433 0.106 0.649 0.502 0.649 1.188 0 0.352-0.066 0.706-0.198 1.062z"></path> +</svg>
\ No newline at end of file diff --git a/static/type.svg b/static/type.svg new file mode 100644 index 0000000..6568c5b --- /dev/null +++ b/static/type.svg @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> +<svg version="1.1" id="Uploaded to svgrepo.com" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" + width="800px" height="800px" viewBox="0 0 32 32" xml:space="preserve"> +<style type="text/css"> + .puchipuchi_een{fill:#111918;} +</style> +<path class="puchipuchi_een" d="M30,7H2C0.9,7,0,7.9,0,9v15c0,1.1,0.9,2,2,2h28c1.1,0,2-0.9,2-2V9C32,7.9,31.1,7,30,7z M18.5,10 + c0.828,0,1.5,0.672,1.5,1.5S19.328,13,18.5,13S17,12.328,17,11.5S17.672,10,18.5,10z M18.5,15c0.828,0,1.5,0.672,1.5,1.5 + S19.328,18,18.5,18S17,17.328,17,16.5S17.672,15,18.5,15z M13.5,10c0.828,0,1.5,0.672,1.5,1.5S14.328,13,13.5,13S12,12.328,12,11.5 + S12.672,10,13.5,10z M13.5,15c0.828,0,1.5,0.672,1.5,1.5S14.328,18,13.5,18S12,17.328,12,16.5S12.672,15,13.5,15z M8.5,10 + c0.828,0,1.5,0.672,1.5,1.5S9.328,13,8.5,13S7,12.328,7,11.5S7.672,10,8.5,10z M8.5,15c0.828,0,1.5,0.672,1.5,1.5S9.328,18,8.5,18 + S7,17.328,7,16.5S7.672,15,8.5,15z M3.5,23C2.672,23,2,22.328,2,21.5S2.672,20,3.5,20S5,20.672,5,21.5S4.328,23,3.5,23z M3.5,18 + C2.672,18,2,17.328,2,16.5S2.672,15,3.5,15S5,15.672,5,16.5S4.328,18,3.5,18z M3.5,13C2.672,13,2,12.328,2,11.5S2.672,10,3.5,10 + S5,10.672,5,11.5S4.328,13,3.5,13z M23.5,23h-15C7.671,23,7,22.329,7,21.5S7.671,20,8.5,20h15c0.829,0,1.5,0.671,1.5,1.5 + S24.329,23,23.5,23z M23.5,18c-0.828,0-1.5-0.672-1.5-1.5s0.672-1.5,1.5-1.5s1.5,0.672,1.5,1.5S24.328,18,23.5,18z M23.5,13 + c-0.828,0-1.5-0.672-1.5-1.5s0.672-1.5,1.5-1.5s1.5,0.672,1.5,1.5S24.328,13,23.5,13z M28.5,23c-0.828,0-1.5-0.672-1.5-1.5 + s0.672-1.5,1.5-1.5s1.5,0.672,1.5,1.5S29.328,23,28.5,23z M28.5,18c-0.828,0-1.5-0.672-1.5-1.5s0.672-1.5,1.5-1.5s1.5,0.672,1.5,1.5 + S29.328,18,28.5,18z M28.5,13c-0.828,0-1.5-0.672-1.5-1.5s0.672-1.5,1.5-1.5s1.5,0.672,1.5,1.5S29.328,13,28.5,13z"/> +</svg>
\ No newline at end of file |
