aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-09-24 13:22:31 -0700
committerAdam Soltys <[email protected]>2024-09-24 13:22:31 -0700
commit8aeb0d6d818b823afec1ee7e5749971468842c9c (patch)
treec9e131848e0903a7629372c3642c99cc8697512a /src
parent52871e09d9218f3f2fb2ce4bd6e97f5c1fc15480 (diff)
downloadcoinos-ui-8aeb0d6d818b823afec1ee7e5749971468842c9c.tar.gz
coinos-ui-8aeb0d6d818b823afec1ee7e5749971468842c9c.zip
fix signing
Diffstat (limited to 'src')
-rw-r--r--src/components/Account.svelte3
-rw-r--r--src/components/Mnemonic.svelte14
-rw-r--r--src/components/WalletPass.svelte6
-rw-r--r--src/lib/parse.ts4
-rw-r--r--src/locales/en.json8
-rw-r--r--src/routes/(app)/[username]/(profile)/+page.svelte12
-rw-r--r--src/routes/(app)/account/[id]/+page.svelte19
-rw-r--r--src/routes/(app)/account/pass/+page.svelte29
-rw-r--r--src/routes/(app)/account/seed/+page.svelte26
-rw-r--r--src/routes/(app)/payment/[id]/+page.svelte17
-rw-r--r--src/routes/(app)/send/bitcoin/[address]/+layout.server.ts12
-rw-r--r--src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte20
12 files changed, 113 insertions, 57 deletions
diff --git a/src/components/Account.svelte b/src/components/Account.svelte
index 4bfdc4ac..8f72119e 100644
--- a/src/components/Account.svelte
+++ b/src/components/Account.svelte
@@ -10,7 +10,8 @@
$: refresh(account);
let refresh = (a) => ({ seed, balance, id } = a);
- let setAccount = () => (document.cookie = `aid=${id}; path=/; max-age=86400`);
+ let setAccount = () =>
+ (document.cookie = `aid=${id}; path=/; max-age=86400`);
</script>
<a href={`/payments`} class="block" on:click={setAccount}>
diff --git a/src/components/Mnemonic.svelte b/src/components/Mnemonic.svelte
new file mode 100644
index 00000000..5e834aed
--- /dev/null
+++ b/src/components/Mnemonic.svelte
@@ -0,0 +1,14 @@
+<script>
+ export let mnemonic;
+</script>
+
+<div
+ class="text-lg border p-4 rounded-2xl text-secondary grid grid-cols-3 gap-2 justify-center"
+>
+ {#each mnemonic.split(" ") as w, i}
+ <div>
+ <span class="select-none text-sm text-black">{i + 1}.</span>
+ <span>{@html w === "-" ? "&mdash;" : w}</span>
+ </div>
+ {/each}
+</div>
diff --git a/src/components/WalletPass.svelte b/src/components/WalletPass.svelte
index 7793ecc5..69b95107 100644
--- a/src/components/WalletPass.svelte
+++ b/src/components/WalletPass.svelte
@@ -46,10 +46,10 @@
<Icon icon={revealPassword ? "eye" : "eye-off"} />
</button>
</div>
- <div class="w-full flex">
+ <div class="w-full flex justify-center gap-2">
<button
type="button"
- class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80 mx-auto"
+ class="border-2 bg-primary rounded-2xl font-semibold mx-auto py-5 px-6 hover:opacity-80 mx-auto grow"
on:click={cancel}
on:keydown={cancel}
>
@@ -57,7 +57,7 @@
</button>
<button
type="submit"
- class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80 mx-auto"
+ class="rounded-2xl font-semibold mx-auto py-5 px-6 hover:opacity-80 mx-auto grow bg-black text-white"
>
<div class="my-auto">Submit</div>
</button>
diff --git a/src/lib/parse.ts b/src/lib/parse.ts
index 781c7087..0ab3e809 100644
--- a/src/lib/parse.ts
+++ b/src/lib/parse.ts
@@ -10,7 +10,7 @@ export default async (t, host) => {
if (t.startsWith("http")) redirect(307, t);
if (t.startsWith(host)) redirect(307, `http://${t}`);
- let amount, id, user;
+ let amount, user;
t = t.trim();
t.toLowerCase().startsWith("bitcoin:") &&
@@ -37,7 +37,7 @@ export default async (t, host) => {
if (t.toLowerCase().startsWith("ln")) {
try {
- ({ id } = await get(`/invoice/${t}`));
+ await get(`/invoice/${t}`);
} catch (e) {
redirect(307, `/send/lightning/${t}`);
}
diff --git a/src/locales/en.json b/src/locales/en.json
index 78ef8de1..f65841d3 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -1,5 +1,13 @@
{
"accounts": {
+ "back": "Back",
+ "next": "Next",
+ "seedPhrase": "Seed phrase",
+ "save": "Save",
+ "copy": "Copy",
+ "revealMnemonic": "Reveal seed phrase",
+ "regenerate": "Regenerate",
+ "deleteAccount": "Delete account",
"addAccount": "Add account",
"create": "Create",
"import": "Import",
diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte
index 2c2ff9a8..0d85fc56 100644
--- a/src/routes/(app)/[username]/(profile)/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/+page.svelte
@@ -28,14 +28,6 @@
<div class="space-y-2">
{#if user?.id === subject.id}
- {#if !user.balance}
- <div class="mb-8">
- <p class="text-secondary text-lg">
- {$t("user.welcome")}
- </p>
- </div>
- {/if}
-
{#each accounts as account}
<Account {user} {rate} {account} />
{/each}
@@ -47,7 +39,9 @@
>
<div class="mx-auto flex gap-2">
<Icon icon="plus" style="w-8 mx-auto invert" />
- <div class="my-auto text-xl whitespace-nowrap">{$t("accounts.addAccount")}</div>
+ <div class="my-auto text-xl whitespace-nowrap">
+ {$t("accounts.addAccount")}
+ </div>
</div>
</button>
</a>
diff --git a/src/routes/(app)/account/[id]/+page.svelte b/src/routes/(app)/account/[id]/+page.svelte
index 3dcd99b8..06494dd8 100644
--- a/src/routes/(app)/account/[id]/+page.svelte
+++ b/src/routes/(app)/account/[id]/+page.svelte
@@ -1,4 +1,5 @@
<script>
+ import Mnemonic from "$comp/Mnemonic.svelte";
import WalletPass from "$comp/WalletPass.svelte";
import { goto } from "$app/navigation";
import { copy, fail, focus, post } from "$lib/utils";
@@ -46,28 +47,28 @@
<div class="space-y-2">
<button
type="submit"
- class="rounded-2xl border py-3 font-bold mx-auto bg-black text-white px-4 w-full"
- >Submit</button
+ class="rounded-2xl border py-5 font-bold mx-auto bg-black text-white px-6 w-full"
+ >{$t("accounts.save")}</button
>
{#if mnemonic}
- <div class="p-8">{mnemonic}</div>
+ <Mnemonic {mnemonic} />
<button
on:click={() => copy(mnemonic)}
type="button"
- class="flex gap-2 rounded-2xl border py-3 font-bold mx-auto px-4 w-full justify-center"
+ class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
<Icon icon="copy" style="w-8 my-auto" />
- <div class="my-auto">Copy</div></button
+ <div class="my-auto">{$t("accounts.copy")}</div></button
>
{:else if seed}
<button
on:click={toggle}
type="button"
- class="flex gap-2 rounded-2xl border py-3 font-bold mx-auto px-4 w-full justify-center bg-primary"
+ class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
<Icon icon="eye" style="w-8 my-auto" />
- <div class="my-auto">Reveal mnemonic</div></button
+ <div class="my-auto">{$t("accounts.revealMnemonic")}</div></button
>
{/if}
@@ -75,10 +76,10 @@
<button
on:click={del}
type="button"
- class="flex gap-2 rounded-2xl border py-3 font-bold mx-auto px-4 w-full justify-center bg-primary"
+ class="flex gap-2 rounded-2xl border py-5 mx-auto px-6 w-full justify-center"
>
<Icon icon="trash" style="w-8 my-auto" />
- <div class="my-auto"><span class="text-red-600">Delete</span> account</div></button
+ <div class="my-auto">{$t("accounts.deleteAccount")}</div></button
>
{/if}
</div>
diff --git a/src/routes/(app)/account/pass/+page.svelte b/src/routes/(app)/account/pass/+page.svelte
index 2ce8b168..36992a98 100644
--- a/src/routes/(app)/account/pass/+page.svelte
+++ b/src/routes/(app)/account/pass/+page.svelte
@@ -44,8 +44,6 @@
let child = master.derive("m/84'/0'/0'");
let pubkey = child.publicExtendedKey;
let fingerprint = child.fingerprint.toString(16).padStart(8, "0");
-
- let receiving = child.deriveChild(0);
await post("/api/accounts", { fingerprint, pubkey, name, seed, type });
goto(`/${user.username}`);
} catch (e) {
@@ -59,7 +57,9 @@
<div class="space-y-5">
<div>
- <h1 class="text-center text-3xl font-semibold">{$t("accounts.accountPassword")}</h1>
+ <h1 class="text-center text-3xl font-semibold">
+ {$t("accounts.accountPassword")}
+ </h1>
</div>
<form
@@ -67,7 +67,7 @@
class="container w-full mx-auto text-lg px-4 max-w-xl space-y-5"
>
<p class="text-secondary mb-1">
- {$t("accounts.passwordWarning")}
+ {$t("accounts.passwordWarning")}
</p>
<div class="relative">
@@ -129,10 +129,21 @@
</button>
</div>
- <button
- class="bg-black text-white w-full px-5 py-6 text-xl rounded-2xl font-bold"
- >
- Submit
- </button>
+ <div class="flex gap-2">
+ <a href={`/account/seed`} class="contents">
+ <button
+ type="button"
+ class="bg-primary w-full px-5 py-6 text-xl rounded-2xl font-bold"
+ >
+ {$t("accounts.back")}
+ </button>
+ </a>
+ <button
+ type="submit"
+ class="bg-black text-white w-full px-5 py-6 text-xl rounded-2xl font-bold"
+ >
+ {$t("accounts.next")}
+ </button>
+ </div>
</form>
</div>
diff --git a/src/routes/(app)/account/seed/+page.svelte b/src/routes/(app)/account/seed/+page.svelte
index e922d6be..4e55534b 100644
--- a/src/routes/(app)/account/seed/+page.svelte
+++ b/src/routes/(app)/account/seed/+page.svelte
@@ -1,4 +1,5 @@
<script>
+ import Mnemonic from "$comp/Mnemonic.svelte";
import { browser } from "$app/environment";
import { tick, onMount } from "svelte";
import { copy } from "$lib/utils";
@@ -13,7 +14,7 @@
onMount(async () => {
if (!browser) return;
- await generate();
+ if (!$mnemonic) await generate();
});
let generate = async () => {
@@ -22,20 +23,13 @@
</script>
<div class="space-y-5">
- <h1 class="text-center text-3xl font-semibold">Seed phrase</h1>
+ <h1 class="text-center text-3xl font-semibold">
+ {$t("accounts.seedPhrase")}
+ </h1>
<div class="container w-full mx-auto text-lg px-4 max-w-xl space-y-5">
{#if $mnemonic}
- <div
- class="text-lg border p-4 rounded-2xl text-secondary grid grid-cols-3 gap-2 justify-center"
- >
- {#each $mnemonic.split(" ") as w, i}
- <div>
- <span class="select-none text-sm text-black">{i + 1}.</span>
- <span>{@html w === "-" ? "&mdash;" : w}</span>
- </div>
- {/each}
- </div>
+ <Mnemonic mnemonic={$mnemonic} />
{/if}
<div>
@@ -45,7 +39,7 @@
on:click={generate}
>
<Icon icon="random" style="w-8 my-auto" />
- <div class="my-auto">Regenerate</div>
+ <div class="my-auto">{$t("accounts.regenerate")}</div>
</button>
<button
@@ -64,9 +58,9 @@
<a href={`/account/savings`} class="contents">
<button
type="button"
- class="bg-black text-white w-full px-5 py-6 text-xl rounded-2xl font-bold"
+ class="bg-primary w-full px-5 py-6 text-xl rounded-2xl font-bold"
>
- Back
+ {$t("accounts.back")}
</button>
</a>
<a href={`/account/pass`} class="contents">
@@ -74,7 +68,7 @@
type="button"
class="bg-black text-white w-full px-5 py-6 text-xl rounded-2xl font-bold"
>
- Next
+ {$t("accounts.next")}
</button>
</a>
</div>
diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte
index 9a278049..481d0242 100644
--- a/src/routes/(app)/payment/[id]/+page.svelte
+++ b/src/routes/(app)/payment/[id]/+page.svelte
@@ -34,6 +34,7 @@
rate,
type,
ref,
+ path,
tip,
ourfee,
fee,
@@ -57,6 +58,7 @@
rate,
type,
ref,
+ path,
tip,
ourfee,
fee,
@@ -225,6 +227,21 @@
</div>
{/if}
+ {#if path}
+ <div>
+ <span class="text-lg text-secondary">Path</span>
+ <div class="flex">
+ <div>{path}</div>
+ <button
+ class="flex font-bold hover:opacity-80 mb-auto my-auto"
+ on:click={() => copy(path)}
+ >
+ <Icon icon="copy" style="ml-2 w-12 my-auto" />
+ </button>
+ </div>
+ </div>
+ {/if}
+
<div class="flex gap-2">
{#if user.admin}
<button
diff --git a/src/routes/(app)/send/bitcoin/[address]/+layout.server.ts b/src/routes/(app)/send/bitcoin/[address]/+layout.server.ts
new file mode 100644
index 00000000..6c22f5f1
--- /dev/null
+++ b/src/routes/(app)/send/bitcoin/[address]/+layout.server.ts
@@ -0,0 +1,12 @@
+import { auth, get } from "$lib/utils";
+import { redirect } from "@sveltejs/kit";
+
+export async function load({ cookies, params }) {
+ let aid = cookies.get("aid");
+ let { address } = params;
+ let { balance } = await get(`/account/${aid}`, auth(cookies));
+ let invoice = await get(`/invoice/${address}`);
+ let recipient = await get(`/user/${invoice.uid}`);
+ if (invoice.aid === invoice.uid) redirect(307, `/send/${recipient.username}`);
+ return { balance };
+}
diff --git a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte
index 4da2e04c..ba87436f 100644
--- a/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte
+++ b/src/routes/(app)/send/bitcoin/[address]/[amount]/[...feeRate]/+page.svelte
@@ -5,6 +5,7 @@
import Toggle from "$comp/Toggle.svelte";
import Icon from "$comp/Icon.svelte";
import Spinner from "$comp/Spinner.svelte";
+ import WalletPass from "$comp/WalletPass.svelte";
import { page } from "$app/stores";
import {
fiat as toFiat,
@@ -21,6 +22,7 @@
import { applyAction } from "$app/forms";
import { hex as hexUtil } from "@scure/base";
import * as btc from "@scure/btc-signer";
+ import { hash160 } from "@scure/btc-signer/utils";
import { decrypt } from "nostr-tools/nip49";
import { HDKey } from "@scure/bip32";
import { entropyToMnemonic, mnemonicToSeed } from "@scure/bip39";
@@ -51,22 +53,24 @@
let signTx = async () => {
let entropy = await decrypt(account.seed, password);
let mnemonic = entropyToMnemonic(entropy, wordlist);
- let seed = await mnemonicToSeed(mnemonic);
+ let seed = await mnemonicToSeed(mnemonic, password);
let master = HDKey.fromMasterSeed(seed, network);
let child = master.derive("m/84'/0'/0'");
let tx = btc.Transaction.fromRaw(decode(hex));
for (let [i, input] of tx.inputs.entries()) {
- let { nonWitnessUtxo, path } = inputs[i];
- tx.updateInput(i, { nonWitnessUtxo });
+ let { witnessUtxo, path } = inputs[i];
+ witnessUtxo.amount = BigInt(witnessUtxo.amount);
+ witnessUtxo.script = decode(witnessUtxo.script);
let key = child.derive(path);
- let { privateKey, publicKey } = key;
- let address = btc.getAddress("wpkh", privateKey, network);
- tx.signIdx(privateKey, i);
+ tx.updateInput(i, { witnessUtxo });
+ tx.signIdx(key.privateKey, i);
}
+
tx.finalize();
hex = tx.hex;
+ console.log("HEX", hex);
signed = true;
await tick();
submit.click();
@@ -182,7 +186,7 @@
<input name="pin" value={$pin} type="hidden" />
<input name="hex" value={hex} type="hidden" />
<input name="rate" value={$rate} type="hidden" />
- <input name="account" value={account.id} type="hidden" />
+ <input name="aid" value={account.id} type="hidden" />
<input name="signed" value={signed} type="hidden" />
<div class="flex justify-center gap-2">
@@ -205,7 +209,7 @@
</div>
{#if passwordPrompt}
- <WalletPass bind:password bind:cancel />
+ <WalletPass bind:password bind:cancel submit={signTx} />
{/if}
<style>