Skip to content

Commit

Permalink
feat(ceremony): rejoin queue (#3067)
Browse files Browse the repository at this point in the history
  • Loading branch information
Swepool authored Oct 8, 2024
2 parents 6fda8d5 + ccee98e commit aa4a5f4
Show file tree
Hide file tree
Showing 16 changed files with 281 additions and 59 deletions.
2 changes: 1 addition & 1 deletion ceremony/src/lib/components/Terminal/Install/Linux.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let { change }: Props = $props()
let showButtons = $state(true)
let command =
"mkdir -p ceremony && docker pull ghcr.io/unionlabs/union/mpc-client:latest && docker run -v $(pwd)/ceremony:/ceremony -w /ceremony -p 4919:4919 --rm -it ghcr.io/unionlabs/union/mpc-client:latest"
"mkdir -p ceremony && docker pull ghcr.io/unionlabs/union/mpc-client:multi && docker run -v $(pwd)/ceremony:/ceremony -w /ceremony -p 4919:4919 --rm -it ghcr.io/unionlabs/union/mpc-client:multi"
onMount(() => {
terminal.setStep(3)
Expand Down
2 changes: 1 addition & 1 deletion ceremony/src/lib/components/Terminal/Install/MacOS.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let { change }: Props = $props()
let showButtons = $state(true)
let command =
"mkdir -p ceremony && docker pull ghcr.io/unionlabs/union/mpc-client:latest && docker run -v $(pwd)/ceremony:/ceremony -w /ceremony -p 4919:4919 --rm -it ghcr.io/unionlabs/union/mpc-client:latest"
"mkdir -p ceremony && docker pull ghcr.io/unionlabs/union/mpc-client:v1.0 && docker run -v $(pwd)/ceremony:/ceremony -w /ceremony -p 4919:4919 --rm -it ghcr.io/unionlabs/union/mpc-client:v1.0"
onMount(() => {
terminal.setStep(3)
Expand Down
94 changes: 89 additions & 5 deletions ceremony/src/lib/components/Terminal/Missed.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,100 @@ import { onDestroy, onMount } from "svelte"
import { getState } from "$lib/state/index.svelte.ts"
import { axiom } from "$lib/utils/axiom.ts"
import { user } from "$lib/state/session.svelte.ts"
import { sleep } from "$lib/utils/utils.ts"
import { queryContributionWindow } from "$lib/supabase/queries.ts"
import Buttons from "$lib/components/Terminal/Install/Buttons.svelte"
import { rejoin } from "$lib/supabase"
const { terminal } = getState()
const { terminal, contributor } = getState()
let showButtons = $state(false)
onMount(() => {
onMount(async () => {
terminal.setStep(0)
terminal.updateHistory({ text: "Too bad, you missed your slot.", replace: true })
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "missed" }])
contributor.stopPolling()
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "mount_missed" }])
const userId = user.session?.user.id
if (userId) {
const window = await queryContributionWindow(userId)
if (window?.data?.started && window?.data?.expire) {
const formatDate = (date: string | number | Date): string => {
const d = new Date(date)
const pad = (num: number): string => num.toString().padStart(2, "0")
return `${d.getFullYear()}/${pad(d.getMonth() + 1)}/${pad(d.getDate())} - ${pad(d.getHours())}:${pad(d.getMinutes())}`
}
const startFormatted = formatDate(window.data.started)
const expireFormatted = formatDate(window.data.expire)
terminal.updateHistory({ text: "Looking for active slot..", replace: true })
await sleep(1000)
terminal.updateHistory({ text: "Expired slot found...", replace: true })
await sleep(1000)
terminal.updateHistory({
text: `Your slot started at ${startFormatted} and expired at ${expireFormatted}.`,
replace: true
})
await sleep(1000)
showButtons = true
} else {
terminal.updateHistory({ text: "No active slot found.", replace: true })
showButtons = true
}
}
})
onDestroy(() => {
terminal.clearHistory()
})
</script>
async function trigger(value: "retry" | "help") {
if (value === "retry") {
terminal.updateHistory({ text: "Retrying..." })
await sleep(1000)
terminal.updateHistory({ text: "Clearing old user data..." })
localStorage.removeItem(`${contributor.userId}:downloaded-secret`)
const secretCleared = !localStorage.getItem(`${contributor.userId}:downloaded-secret`)
if (secretCleared) {
await sleep(1000)
terminal.updateHistory({ text: "Successfully cleared user data." })
await sleep(1000)
terminal.updateHistory({ text: "Attempting to add user to queue..." })
const rejoined = await rejoin()
await sleep(1000)
if (rejoined) {
terminal.updateHistory({ text: "Successfully added user to queue." })
await sleep(1000)
localStorage.removeItem("ceremony:show-boot-sequence")
terminal.updateHistory({ text: "Reinitializing..." })
await sleep(4000)
window.location.href = "/"
} else {
terminal.updateHistory({ text: "Failed to add user to queue." })
await sleep(1000)
terminal.updateHistory({ text: "Please contact support." })
window.location.href = "/"
}
} else {
terminal.updateHistory({ text: "Failed to clear user data." })
await sleep(1000)
terminal.updateHistory({ text: "Please contact support." })
}
} else if (value === "help") {
terminal.updateHistory({ text: "Redirecting to discord..." })
await sleep(4000)
window.open("https://discord.union.build/", "_blank")
}
}
</script>

{#if showButtons}
<Buttons data={[{text: "Generate new slot and continue", action: "retry"}, {text: "Exit and create a support ticket", action: "help"}]} trigger={(action) => trigger(action)}/>
{/if}
14 changes: 9 additions & 5 deletions ceremony/src/lib/components/Terminal/Queue.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ onMount(async () => {
terminal.updateHistory({ text: "You are in queue" })
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "mount_queue" }])
averages = await getAverageTimes()
console.log(averages)
await contributor.checkUserWallet(contributor.userId)
})
onDestroy(() => {
Expand All @@ -32,14 +32,18 @@ $effect(() => {
})
</script>

<!--TODO add new time-->
<Print>Your position: {contributor.queueState.position ?? 1}</Print>
<Print>Queue length: {contributor.queueState.count ?? 2}</Print>
<Print>Your position: {contributor.queueState.position}</Print>
<Print>Queue length: {contributor.queueState.count}</Print>
<Print>Estimated waiting time: {formatWaitTime(waitingTime)}</Print>
<Print><br></Print>
<LoadingBar max={contributor.queueState.count} current={contributor.queueState.position}/>
<Print><br></Print>
<Print>Your MPC Client is connected.</Print>
<Print><span class="text-green-400">✓</span> MPC Client connected.</Print>
{#if contributor.userWallet && contributor.userWallet !== "SKIPPED"}
<Print><span class="text-green-400">✓</span> Wallet registered and valid.</Print>
{/if}
<Print><span class="text-green-400">✓</span> Ready to contribute and awaiting slot.</Print>
<Print><br></Print>
<Print class="!text-[#FD6363]">Do not close this tab or your Terminal. Ensure you have a reliable internet connection
and that your computer does not go to sleep.
</Print>
Expand Down
28 changes: 17 additions & 11 deletions ceremony/src/lib/components/Terminal/Secret.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,39 @@ const { contributor, terminal, user } = getState()
let generated = $state(false)
let generating = $state(false)
let buttons = $state<Array<HTMLButtonElement>>([])
let focusedIndex = $state(0)
onMount(() => {
terminal.setStep(4)
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "mount_secret" }])
axiom.ingest("monitor", [{ user: contributor.userId, type: "mount_secret" }])
})
function handleDownload() {
const newUrl = "http://localhost:4919/secret_key"
window.open(newUrl, "_blank")
const newUrl = `http://localhost:4919/secret_key/${user.session?.user.email}`
const link = document.createElement("a")
link.href = newUrl
link.setAttribute("download", "")
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
function stored() {
localStorage.setItem("downloaded-secret", "true")
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "stored_secret" }])
contributor.downloadedSecret = true
localStorage.setItem(`${contributor.userId}:downloaded-secret`, "true")
axiom.ingest("monitor", [{ user: contributor.userId, type: "stored_secret" }])
contributor.storedSecret = true
}
async function generate() {
if (contributor.state !== "noClient") {
generating = true
terminal.updateHistory({ text: "Generating secret..." })
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "generated_secret" }])
terminal.updateHistory({ text: "Generating secret...", duplicate: true })
axiom.ingest("monitor", [{ user: contributor.userId, type: "generated_secret" }])
await sleep(3000)
generateSecret(user.session?.user.email)
terminal.updateHistory({ text: "Initialize saving..." })
terminal.updateHistory({ text: "Initialize saving...", duplicate: true })
await sleep(1000)
handleDownload()
generating = false
Expand Down
53 changes: 50 additions & 3 deletions ceremony/src/lib/components/Terminal/Thanks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,29 @@ import { onDestroy, onMount } from "svelte"
import Buttons from "$lib/components/Terminal/Install/Buttons.svelte"
import { axiom } from "$lib/utils/axiom.ts"
import { user } from "$lib/state/session.svelte.ts"
import Print from "$lib/components/Terminal/Print.svelte"
import { AddressForm, type ValidState } from "$lib/components/address"
const { terminal } = getState()
type Actions = "tweet" | "view" | "wallet" | "back"
const { terminal, contributor } = getState()
let showButtons = $state(true)
let showInput = $state(false)
let validation = (val: ValidState) => {
if (val === "INVALID") {
showInput = false
showButtons = true
} else if (val === "PENDING") {
showInput = false
} else if (val === "SAVED") {
showInput = false
showButtons = true
} else if (val === "SKIPPED") {
showInput = false
}
}
onMount(() => {
terminal.setStep(10)
Expand All @@ -34,11 +55,17 @@ async function shareOnTwitter() {
window.open(twitterIntentUrl.toString(), "_blank")
}
function trigger(value: "tweet" | "view") {
function trigger(value: Actions) {
if (value === "tweet") {
shareOnTwitter()
} else if (value === "view") {
terminal.setTab(3)
} else if (value === "wallet") {
showButtons = false
showInput = true
} else if (value === "back") {
showInput = false
showButtons = true
}
}
Expand All @@ -47,4 +74,24 @@ onDestroy(() => {
})
</script>

<Buttons data={[{text: "Tweet your attestation", action: "tweet"},{text: "View contributions", action: "view"}]} trigger={(value: 'tweet' | 'view') => trigger(value)}/>
{#if showButtons}
<Buttons
data={[{text: "Tweet your attestation", action: "tweet"}, {text: "View contributions", action: "view"}, {text: "Update wallet", action: "wallet"}]}
trigger={(value: Actions) => trigger(value)}/>
{/if}

{#if showInput}
<Print>Enter your union or any cosmos address, or type "skip".</Print>
{#if !contributor.userWallet || contributor.userWallet === "SKIPPED"}
<Print>No wallet registered</Print>
{:else }
<Print>Registered: <span class="text-union-accent-500">{contributor.userWallet}</span></Print>
{/if}
<Print><br></Print>
<div class="flex w-full gap-1">
<div class="whitespace-nowrap">
<Print>Enter address:</Print>
</div>
<AddressForm {validation}/>
</div>
{/if}
4 changes: 2 additions & 2 deletions ceremony/src/lib/components/Terminal/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Button from "$lib/components/Terminal/Button.svelte"
import TaskBar from "$lib/components/Terminal/TaskBar.svelte"
import Printer from "$lib/components/Terminal/Printer.svelte"
const { terminal } = getState()
const { terminal, contributor } = getState()
let { children } = $props()
Expand Down Expand Up @@ -75,7 +75,7 @@ function autoScroll(node: HTMLElement) {
{/if}
</div>
{#if user.session?.user}
<Button class="text-white" onclick={() => logout(terminal)}>Log out</Button>
<Button class="text-white" onclick={() => logout(terminal, contributor)}>Log out</Button>
{/if}
</div>

Expand Down
22 changes: 14 additions & 8 deletions ceremony/src/lib/components/address/AddressForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { user } from "$lib/state/session.svelte.ts"
import { getState } from "$lib/state/index.svelte.ts"
import { sleep } from "$lib/utils/utils.ts"
import { axiom } from "$lib/utils/axiom.ts"
import { onDestroy } from "svelte"
interface Props extends HTMLInputAttributes {
class?: string
Expand All @@ -32,7 +33,7 @@ const onAddressSubmit = async (event: Event) => {
}
validation("PENDING")
terminal.updateHistory({ text: "Checking address" })
terminal.updateHistory({ text: "Checking address...", duplicate: true })
await sleep(1000)
const addressValidation = isValidBech32Address(inputText)
validState = addressValidation ? "VALID" : "INVALID"
Expand All @@ -48,26 +49,30 @@ const onAddressSubmit = async (event: Event) => {
wallet: inputText
})
if (result) {
terminal.updateHistory({ text: "Saving address..." })
terminal.updateHistory({ text: "Saving address...", duplicate: true })
await sleep(2000)
terminal.updateHistory({ text: "Wallet address saved successfully" })
terminal.updateHistory({ text: "Wallet address saved successfully", duplicate: true })
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "added_address" }])
await sleep(2000)
contributor.checkUserWallet(user.session?.user.id)
validation("SAVED")
} else {
terminal.updateHistory({ text: "Failed to save wallet address" })
terminal.updateHistory({ text: "Failed to save wallet address", duplicate: true })
}
} catch (error) {
console.error("Error saving wallet address:", error)
terminal.updateHistory({ text: "An error occurred while saving the wallet address" })
terminal.updateHistory({
text: "An error occurred while saving the wallet address",
duplicate: true
})
}
} else if (validState === "INVALID") {
terminal.updateHistory({ text: "Wallet address not valid, try again..", duplicate: true })
terminal.updateHistory({ text: "Wallet address not valid, try again.", duplicate: true })
}
}
const skip = async () => {
terminal.updateHistory({ text: "Skipping reward step" })
terminal.updateHistory({ text: "Skipping reward step", duplicate: true })
validation("SKIPPED")
try {
if (!contributor.userId) return
Expand All @@ -76,10 +81,11 @@ const skip = async () => {
wallet: "SKIPPED"
})
if (result) {
terminal.updateHistory({ text: "Saving to db..." })
terminal.updateHistory({ text: "Saving to db...", duplicate: true })
axiom.ingest("monitor", [{ user: user.session?.user.id, type: "skipped_address" }])
await sleep(2000)
contributor.userWallet = "SKIPPED"
validation("SKIPPED")
} else {
terminal.updateHistory({ text: "Failed to save wallet address", duplicate: true })
}
Expand Down
2 changes: 1 addition & 1 deletion ceremony/src/lib/components/address/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import AddressForm from "./AddressForm.svelte"

export type ValidState = "PENDING" | "VALID" | "INVALID" | "SKIPPED" | undefined
export type ValidState = "PENDING" | "VALID" | "INVALID" | "SKIPPED" | "SAVED" | undefined

export { AddressForm }
Loading

0 comments on commit aa4a5f4

Please sign in to comment.