Skip to content

Commit 8b31b33

Browse files
feat(packages): pegin flow
1 parent 0eaef30 commit 8b31b33

File tree

15 files changed

+791
-1
lines changed

15 files changed

+791
-1
lines changed

packages/babylon-core-ui/src/components/ActivityList/ActivityList.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,49 @@ import type { PropsWithChildren } from "react";
1717
export interface ActivityListProps {
1818
onNewItem?: () => void;
1919
className?: string;
20+
isEmpty?: boolean;
21+
isConnected?: boolean;
2022
}
2123

2224
export function ActivityList({
2325
onNewItem,
2426
className,
2527
children,
28+
isEmpty = false,
29+
isConnected = false,
2630
}: PropsWithChildren<ActivityListProps>) {
31+
// Show empty state when connected but no activities
32+
if (isEmpty && isConnected) {
33+
return (
34+
<Card className={className}>
35+
<div className="flex flex-col items-center justify-center gap-6 py-12 px-4">
36+
<img
37+
src="/mascot-smile-expression-full-body.png"
38+
alt="Babylon mascot"
39+
className="size-[200px]"
40+
/>
41+
<div className="text-center">
42+
<h3 className="text-xl font-semibold text-accent-primary mb-2">
43+
Supply Collateral BTC Trustlessly
44+
</h3>
45+
<p className="text-sm text-accent-secondary max-w-md">
46+
Enter the amount of BTC you want to deposit and select a provider to secure it.
47+
Your deposit will appear here once confirmed.
48+
</p>
49+
</div>
50+
<IconButton
51+
variant="outlined"
52+
size="large"
53+
onClick={onNewItem}
54+
aria-label="Create new item"
55+
>
56+
<PlusIcon />
57+
</IconButton>
58+
</div>
59+
</Card>
60+
);
61+
}
62+
2763
return (
2864
<Card className={className}>
2965
<div className="flex flex-col gap-4">
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Vault Provider API
3+
*
4+
* This module handles fetching vault provider data.
5+
* Currently returns mock data, but structured to support GraphQL integration.
6+
*/
7+
8+
export interface VaultProvider {
9+
id: string;
10+
name: string;
11+
icon: string;
12+
apy?: number;
13+
tvl?: string;
14+
description?: string;
15+
}
16+
17+
export interface VaultProvidersResponse {
18+
providers: VaultProvider[];
19+
}
20+
21+
/**
22+
* Fetch vault providers from backend
23+
* TODO: Implement GraphQL query when backend is ready
24+
*
25+
* @returns Promise<VaultProvidersResponse>
26+
*/
27+
export async function getVaultProviders(): Promise<VaultProvidersResponse> {
28+
// TODO: Replace with actual GraphQL endpoint
29+
// Example GraphQL query:
30+
// query GetVaultProviders {
31+
// vaultProviders {
32+
// id
33+
// name
34+
// icon
35+
// apy
36+
// tvl
37+
// description
38+
// }
39+
// }
40+
41+
// Mock data - will be replaced by GraphQL query
42+
const mockProviders: VaultProvider[] = [
43+
{
44+
id: "ironclad",
45+
name: "Ironclad BTC",
46+
icon: "/icons/ironclad.svg",
47+
apy: 8.5,
48+
tvl: "1.2M",
49+
description: "Secure Bitcoin custody with institutional-grade security"
50+
},
51+
{
52+
id: "atlas",
53+
name: "Atlas Custody",
54+
icon: "/icons/atlas.svg",
55+
apy: 7.8,
56+
tvl: "2.5M",
57+
description: "Regulated custody solution for digital assets"
58+
},
59+
{
60+
id: "stonewall",
61+
name: "Stonewall Capital",
62+
icon: "/icons/stonewall.svg",
63+
apy: 9.2,
64+
tvl: "850K",
65+
description: "High-yield Bitcoin vault provider"
66+
},
67+
{
68+
id: "redwood",
69+
name: "Redwood BTC",
70+
icon: "/icons/redwood.svg",
71+
apy: 8.0,
72+
tvl: "1.8M",
73+
description: "Enterprise-grade Bitcoin vault infrastructure"
74+
},
75+
];
76+
77+
return {
78+
providers: mockProviders,
79+
};
80+
}

routes/vault/src/api/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* API Module
3+
*
4+
* Centralized exports for all API functions
5+
*/
6+
7+
export * from './getVaultProviders';

routes/vault/src/assets/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
// Asset exports for vault application
22

3+
// Bitcoin icon as data URI - Orange bitcoin logo
4+
export const bitcoinIcon = "data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='%23FF7C2A' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M23.638 14.904c-1.602 6.43-8.113 10.34-14.542 8.736C2.67 22.05-1.244 15.525.362 9.105 1.962 2.67 8.475-1.243 14.9.358c6.43 1.605 10.342 8.115 8.738 14.548v-.002zm-6.35-4.613c.24-1.59-.974-2.45-2.64-3.03l.54-2.153-1.315-.33-.525 2.107c-.345-.087-.705-.167-1.064-.25l.526-2.127-1.32-.33-.54 2.165c-.285-.067-.565-.132-.84-.2l-1.815-.45-.35 1.407s.975.225.955.236c.535.136.63.486.615.766l-1.477 5.92c-.075.166-.24.406-.614.314.015.02-.96-.24-.96-.24l-.66 1.51 1.71.426.93.242-.54 2.19 1.32.327.54-2.17c.36.1.705.19 1.05.273l-.51 2.154 1.32.33.545-2.19c2.24.427 3.93.257 4.64-1.774.57-1.637-.03-2.58-1.217-3.196.854-.193 1.5-.76 1.68-1.93h.01zm-3.01 4.22c-.404 1.64-3.157.75-4.05.53l.72-2.9c.896.23 3.757.67 3.33 2.37zm.41-4.24c-.37 1.49-2.662.735-3.405.55l.654-2.64c.744.18 3.137.524 2.75 2.084v.006z'/%3E%3C/svg%3E";
5+
36
// USDC icon as data URI - Simple circle design with USDC branding
47
export const usdcIcon = 'data:image/svg+xml,%3Csvg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"%3E%3Ccircle cx="20" cy="20" r="20" fill="%232775CA"/%3E%3Cpath d="M24.0001 17.3999C24.0001 15.6399 22.8001 14.7999 20.4001 14.5999V12.3999H18.8001V14.5599C18.3601 14.5599 17.9201 14.5599 17.4801 14.5999V12.3999H15.8801V14.5999C15.5601 14.5999 15.2401 14.6399 14.9201 14.6399H13.2001V16.3599H14.4401C14.8801 16.3599 15.0801 16.5999 15.0801 16.9599V23.0399C15.0801 23.3999 14.8801 23.6399 14.4401 23.6399H13.2001V25.7599L14.8401 25.7999C15.1601 25.7999 15.4801 25.7999 15.8001 25.8399V28.0399H17.4001V25.8799C17.8401 25.8799 18.2801 25.9199 18.7201 25.9199V28.0799H20.3201V25.8799C23.2001 25.7199 24.8001 24.5199 24.8001 22.3599C24.8001 20.7999 24.0001 19.8799 22.5601 19.4799C23.5201 19.0799 24.0001 18.3599 24.0001 17.3999ZM18.7201 21.1999V23.5199C17.7201 23.4399 17.2001 23.3999 16.6801 23.3599V21.1999C17.2001 21.1599 17.7201 21.1199 18.7201 21.1999ZM20.3201 16.7199C21.2401 16.7999 21.7601 16.8399 22.3201 16.9199V19.0399C21.7601 18.9599 21.2401 18.9199 20.3201 18.8399V16.7199ZM20.3201 23.5599V21.1599C21.3201 21.2399 21.8401 21.2799 22.4001 21.3599C22.6001 22.3599 21.8401 23.1999 20.3201 23.5599Z" fill="white"/%3E%3C/svg%3E';
58

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { usePeginFlowState } from './usePeginFlowState';
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { useState, useCallback, useMemo } from "react";
2+
import { useChainConnector } from "@babylonlabs-io/wallet-connector";
3+
import type { Hex } from "viem";
4+
5+
export function usePeginFlowState() {
6+
const ethConnector = useChainConnector('ETH');
7+
const btcConnector = useChainConnector('BTC');
8+
9+
// Get BTC address from connector
10+
const btcAddress = useMemo(() => {
11+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12+
return (btcConnector as any)?.connectedWallet?.account?.address as string | undefined;
13+
}, [btcConnector]);
14+
15+
// Get ETH address from connector
16+
const connectedAddress = useMemo(() => {
17+
const address = (
18+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
19+
(ethConnector as any)?.connectedWallet?.account?.address ||
20+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
21+
(ethConnector as any)?.connectedWallet?.accounts?.[0]?.address
22+
) as Hex | undefined;
23+
return address;
24+
}, [ethConnector]);
25+
26+
// Hardcoded BTC balance (in satoshis) - TODO: Replace with real wallet balance
27+
const btcBalanceSat = 500000000; // 5 BTC
28+
29+
// Modal states
30+
const [peginModalOpen, setPeginModalOpen] = useState(false);
31+
const [peginSignModalOpen, setPeginSignModalOpen] = useState(false);
32+
const [peginSuccessModalOpen, setPeginSuccessModalOpen] = useState(false);
33+
34+
// Peg-in flow data
35+
const [peginAmount, setPeginAmount] = useState(0);
36+
const [selectedProviders, setSelectedProviders] = useState<string[]>([]);
37+
38+
// Start the peg-in flow
39+
const handleNewBorrow = useCallback(() => {
40+
setPeginModalOpen(true);
41+
}, []);
42+
43+
// Handle peg-in click from PeginModal
44+
const handlePeginClick = useCallback((amount: number, providers: string[]) => {
45+
console.log("Peg-in clicked:", { amount, providers });
46+
setPeginAmount(amount);
47+
setSelectedProviders(providers);
48+
setPeginModalOpen(false);
49+
setPeginSignModalOpen(true);
50+
}, []);
51+
52+
// Handle signing success
53+
const handlePeginSignSuccess = useCallback(() => {
54+
setPeginSignModalOpen(false);
55+
setPeginSuccessModalOpen(true);
56+
}, []);
57+
58+
// Handle success modal close
59+
const handlePeginSuccessClose = useCallback(() => {
60+
setPeginSuccessModalOpen(false);
61+
setPeginAmount(0);
62+
setSelectedProviders([]);
63+
}, []);
64+
65+
return {
66+
// Wallet data
67+
connectedAddress,
68+
btcAddress,
69+
btcBalanceSat,
70+
// Modal states
71+
peginModalOpen,
72+
peginSignModalOpen,
73+
peginSuccessModalOpen,
74+
// Peg-in data
75+
peginAmount,
76+
selectedProviders,
77+
// Actions
78+
handleNewBorrow,
79+
handlePeginClick,
80+
handlePeginSignSuccess,
81+
handlePeginSuccessClose,
82+
setPeginModalOpen,
83+
setPeginSignModalOpen,
84+
};
85+
}

0 commit comments

Comments
 (0)