Skip to content

Commit 5a6f297

Browse files
authored
feat(app): add step to collect points receiver (#5283)
- **feat(app): add call to edge fn** - **fix(app): rename from bbn1 to bbn** - **feat(app): add step 3** - **feat(app): adjust steps and page to use step 3**
2 parents 748d967 + 003e95a commit 5a6f297

File tree

5 files changed

+580
-40
lines changed

5 files changed

+580
-40
lines changed

app2/src/lib/dashboard/queries/public.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,42 @@ export const getBTCFIPoints = (address: string) =>
382382
return Effect.succeed(Option.none())
383383
}),
384384
)
385+
386+
export const verifyBTCFIWallet = (params: {
387+
bbnAddress: string
388+
message: string
389+
signature: string
390+
evmAddress: string
391+
}) =>
392+
pipe(
393+
SupabaseClient,
394+
Effect.flatMap((client) =>
395+
Effect.tryPromise({
396+
try: () =>
397+
client.functions.invoke("btcfi-verify-wallet", {
398+
body: params,
399+
}),
400+
catch: (error) =>
401+
new BTCFIError({
402+
operation: "verifyBTCFIWallet",
403+
cause: extractErrorDetails(error as Error),
404+
}),
405+
})
406+
),
407+
Effect.flatMap((response) =>
408+
response.error
409+
? Effect.fail(
410+
new BTCFIError({
411+
operation: "verifyBTCFIWallet",
412+
cause: response.error,
413+
}),
414+
)
415+
: Effect.succeed(response.data as { verified: boolean; owner: string; receiver: string })
416+
),
417+
Effect.map((data) => data.verified),
418+
Effect.catchAll((error) => {
419+
const btcfiError = new BTCFIError({ cause: error, operation: "verifyBTCFIWallet" })
420+
errorStore.showError(btcfiError)
421+
return Effect.succeed(false)
422+
}),
423+
)

app2/src/routes/btcfi/+page.svelte

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<script lang="ts">
22
import Sections from "$lib/components/ui/Sections.svelte"
33
import StepperCard from "$lib/components/ui/StepperCard.svelte"
4+
import { Option } from "effect"
45
import Step1 from "./step/Step1.svelte"
56
import Step2 from "./step/Step2.svelte"
7+
import Step3 from "./step/Step3.svelte"
68
let currentSlide = $state(0)
79
let walletAddress = $state("")
8-
let btcfiPoints = $state<number | null>(null)
10+
let btcfiPoints = $state<Option.Option<number>>(Option.none())
911
let stepperCardRef: StepperCard
1012
1113
function goToNextSlide() {
@@ -14,14 +16,29 @@ function goToNextSlide() {
1416
1517
const handleStep1Next = (address: string, points: number) => {
1618
walletAddress = address
17-
btcfiPoints = points
19+
btcfiPoints = Option.some(points)
1820
goToNextSlide()
1921
}
2022
2123
const handleStep2Back = () => {
2224
currentSlide = 0
2325
walletAddress = ""
24-
btcfiPoints = null
26+
btcfiPoints = Option.none()
27+
}
28+
29+
const handleStep2ReceiveEthereum = () => {
30+
goToNextSlide()
31+
}
32+
33+
const handleStep3Back = () => {
34+
currentSlide = 1
35+
}
36+
37+
const handleStep3Success = () => {
38+
// Reset to beginning after successful verification
39+
currentSlide = 0
40+
walletAddress = ""
41+
btcfiPoints = Option.none()
2542
}
2643
</script>
2744

@@ -30,18 +47,26 @@ const handleStep2Back = () => {
3047
<StepperCard
3148
bind:this={stepperCardRef}
3249
bind:currentSlide
33-
totalSlides={2}
50+
totalSlides={3}
3451
class="max-w-5xl md:h-auto"
3552
>
3653
{#snippet children(slideIndex)}
3754
<div class="flex flex-col gap-4 h-full w-full">
3855
{#if slideIndex === 0}
3956
<Step1 onNext={handleStep1Next} />
40-
{:else if slideIndex === 1 && btcfiPoints !== null}
57+
{:else if slideIndex === 1 && Option.isSome(btcfiPoints)}
4158
<Step2
4259
{walletAddress}
4360
{btcfiPoints}
4461
onBack={handleStep2Back}
62+
onReceiveEthereum={handleStep2ReceiveEthereum}
63+
/>
64+
{:else if slideIndex === 2 && Option.isSome(btcfiPoints)}
65+
<Step3
66+
{walletAddress}
67+
{btcfiPoints}
68+
onBack={handleStep3Back}
69+
onSuccess={handleStep3Success}
4570
/>
4671
{/if}
4772
</div>

app2/src/routes/btcfi/step/Step1.svelte

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ let hasAutoFilled = $state(false)
2424
let isConnected = $derived(cosmosStore.connectionStatus === "connected")
2525
2626
// Convert Cosmos address to bbn1 format
27-
let cosmosAddressBbn1 = $derived(
27+
let cosmosAddressBbn = $derived(
2828
pipe(
2929
wallets.cosmosAddress,
3030
Option.map(cosmosDisplay =>
@@ -40,8 +40,8 @@ let cosmosAddressBbn1 = $derived(
4040
4141
// Auto-populate input only once when wallet connects
4242
$effect(() => {
43-
if (isConnected && Option.isSome(cosmosAddressBbn1) && !hasAutoFilled) {
44-
walletAddress = Option.getOrThrow(cosmosAddressBbn1)
43+
if (isConnected && Option.isSome(cosmosAddressBbn) && !hasAutoFilled) {
44+
walletAddress = Option.getOrThrow(cosmosAddressBbn)
4545
hasAutoFilled = true
4646
}
4747
// Reset auto-fill flag if wallet disconnects
@@ -149,19 +149,19 @@ const handleCheck = () => {
149149
<div class="flex-1">
150150
<div class="text-sm font-medium text-accent">Wallet Connected</div>
151151
<div class="text-xs text-zinc-400 font-mono">
152-
{#if Option.isSome(cosmosAddressBbn1)}
153-
{Option.getOrThrow(cosmosAddressBbn1)?.slice(0, 12)}...{
154-
Option.getOrThrow(cosmosAddressBbn1)?.slice(-6)
152+
{#if Option.isSome(cosmosAddressBbn)}
153+
{Option.getOrThrow(cosmosAddressBbn)?.slice(0, 12)}...{
154+
Option.getOrThrow(cosmosAddressBbn)?.slice(-6)
155155
}
156156
{/if}
157157
</div>
158158
</div>
159-
{#if walletAddress !== Option.getOrUndefined(cosmosAddressBbn1)}
159+
{#if walletAddress !== Option.getOrUndefined(cosmosAddressBbn)}
160160
<button
161161
type="button"
162162
onclick={() => {
163-
if (Option.isSome(cosmosAddressBbn1)) {
164-
walletAddress = Option.getOrThrow(cosmosAddressBbn1)
163+
if (Option.isSome(cosmosAddressBbn)) {
164+
walletAddress = Option.getOrThrow(cosmosAddressBbn)
165165
}
166166
}}
167167
class="p-1.5 hover:bg-accent/20 rounded transition-colors"

app2/src/routes/btcfi/step/Step2.svelte

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
<script lang="ts">
22
import Button from "$lib/components/ui/Button.svelte"
3+
import { Option } from "effect"
34
import StepLayout from "./StepLayout.svelte"
45
56
interface Props {
67
walletAddress: string
7-
btcfiPoints: number | null
8+
btcfiPoints: Option.Option<number>
89
onBack: () => void
10+
onReceiveEthereum?: () => void
911
}
1012
11-
let { walletAddress, btcfiPoints, onBack }: Props = $props()
13+
let { walletAddress, btcfiPoints, onBack, onReceiveEthereum }: Props = $props()
1214
13-
let isEligible = $derived(btcfiPoints && btcfiPoints > 0)
15+
let points = $derived(Option.getOrElse(btcfiPoints, () => 0))
16+
let isEligible = $derived(points > 0)
1417
1518
// Tier based on points
16-
const tierEmoji = btcfiPoints === null || btcfiPoints === 0
17-
? ""
18-
: btcfiPoints >= 100000
19-
? "🐋"
20-
: btcfiPoints >= 15000
21-
? "🐬"
22-
: btcfiPoints >= 5000
23-
? "🐟"
24-
: "🦐"
19+
const tierEmoji = $derived(
20+
points === 0
21+
? ""
22+
: points >= 100000
23+
? "🐋"
24+
: points >= 15000
25+
? "🐬"
26+
: points >= 5000
27+
? "🐟"
28+
: "🦐",
29+
)
2530
</script>
2631

2732
<StepLayout>
@@ -56,26 +61,32 @@ const tierEmoji = btcfiPoints === null || btcfiPoints === 0
5661

5762
<div class="flex flex-col gap-3">
5863
<div class="flex-1 flex items-center justify-center">
59-
{#if isEligible}
60-
<div class="bg-accent/10 border border-accent/20 rounded-lg p-6 w-full">
61-
<div class="text-5xl font-bold text-accent text-center">
62-
{btcfiPoints?.toLocaleString()}
63-
</div>
64-
<div class="text-sm text-zinc-400 mt-3 text-center">Points</div>
64+
<div class="bg-accent/10 border border-accent/20 rounded-lg p-6 w-full text-center">
65+
<div class="text-5xl font-bold text-accent text-center">
66+
{points.toLocaleString()}
6567
</div>
66-
{:else}
67-
<div class="bg-accent/10 border border-accent/20 rounded-lg p-6 w-full text-center">
68-
<div class="text-5xl font-bold text-accent text-center">
69-
{btcfiPoints?.toLocaleString()}
68+
<div class="text-sm text-zinc-400 mt-3 text-center">Points</div>
69+
70+
{#if isEligible}
71+
<div class="mt-6 -mx-6 pt-6 px-6 border-t border-zinc-700/30">
72+
<div class="text-xs text-zinc-400 mb-3">
73+
Rewards will be distributed on Babylon by default.
74+
</div>
75+
<Button
76+
variant="primary"
77+
onclick={onReceiveEthereum}
78+
class="w-full"
79+
>
80+
Receive on Ethereum Instead
81+
</Button>
7082
</div>
71-
<div class="text-sm text-zinc-400 mt-3 text-center">Points</div>
72-
</div>
73-
{/if}
83+
{/if}
84+
</div>
7485
</div>
7586

7687
<div class="space-y-3">
7788
<Button
78-
variant="primary"
89+
variant="secondary"
7990
onclick={onBack}
8091
class="w-full"
8192
>

0 commit comments

Comments
 (0)