From 92628dd7e1bf6150001c2a35cfbdd318b3fb82b7 Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Tue, 23 May 2023 12:16:32 -0500 Subject: [PATCH] redshift coming soon --- src/routes/Redshift.tsx | 861 +++++++++++++++++++++++----------------- 1 file changed, 498 insertions(+), 363 deletions(-) diff --git a/src/routes/Redshift.tsx b/src/routes/Redshift.tsx index 8568d57..9968e7c 100644 --- a/src/routes/Redshift.tsx +++ b/src/routes/Redshift.tsx @@ -1,119 +1,157 @@ -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 { + 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"; -import { Network } from "~/logic/mutinyWalletSetup"; +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" +import { Network } from "~/logic/mutinyWalletSetup" 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 +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; + 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), -}; + 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(); +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[]; - } + 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); - } + 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 [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 + }) - 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)) - 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; - } + // } else { + // setSentAmount((sentAmount() + 50000)) + // } + }, 1000) + }) - 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)) + const outputUtxo = createMemo(() => { + return findUtxoByOutpoint(redshiftResource()?.output_utxo, utxos()) + }) - // } else { - // setSentAmount((sentAmount() + 50000)) - // } - }, 1000) - }) + createEffect(() => { + setRedshifted(true, redshiftResource()?.output_utxo) + }) - const outputUtxo = createMemo(() => { - return findUtxoByOutpoint(redshiftResource()?.output_utxo, utxos()) - }) + const network = state.mutiny_wallet?.get_network() as Network - createEffect(() => { - setRedshifted(true, redshiftResource()?.output_utxo) - }) - - const network = state.mutiny_wallet?.get_network() as Network; - - - return ( - - - {/* + return ( + + {/* We did it. Here's your new UTXO: @@ -121,292 +159,389 @@ function RedshiftReport(props: { redshift: RedshiftResult, utxo: UtxoItem }) { */} - - What happened? - - - - - {/* + + 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 +
+                    {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} -
- ) + return ( +
+

{props.key}

+ {props.children} +
+ ) } export default function Redshift() { - const [state, _actions] = useMegaStore(); + const [state, _actions] = useMegaStore() - const [shiftStage, setShiftStage] = createSignal("choose"); - const [shiftType, setShiftType] = createSignal("utxo"); + const [shiftStage, setShiftStage] = createSignal("choose") + const [shiftType, setShiftType] = createSignal("utxo") - const [chosenUtxo, setChosenUtxo] = createSignal(); + const [chosenUtxo, setChosenUtxo] = createSignal() - const getUtXos = async () => { - console.log("Getting utxos"); - return await state.mutiny_wallet?.list_utxos() as UtxoItem[]; + 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< + MutinyChannel[] + > + 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") } + }) - 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)}
*/} + return ( + + + + + Redshift (coming soon) +
+ + {/*
{JSON.stringify(redshiftResource(), null, 2)}
*/} + + + + Where is this going? + + setShiftType(newValue as ShiftOption) + } + choices={SHIFT_OPTIONS} + /> + + + + Choose your{" "} + + sine wave + {" "} + UTXO to begin + + + - - - 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 utxos (empty state) + + = 0 + } + > + + {(utxo) => ( + setChosenUtxo(utxo)} + /> + )} + + - - - - - - ) -} \ No newline at end of file + + + + + Redshifted UTXOs + + } + > + + + + + + No utxos (empty state) + + = 0 + } + > + + {(utxo) => } + + + + + +
+ + + + + + + + + + + + Oh dear + Here's what happened: + + + + +
+
+ +
+
+ ) +}