Skip to content

Commit d11f034

Browse files
committed
merge master into branch
2 parents bf159b2 + 0832bc4 commit d11f034

File tree

31 files changed

+1592
-635
lines changed

31 files changed

+1592
-635
lines changed

app/api/evm-chain-faucet/route.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ async function handleFaucetRequest(request: NextRequest): Promise<NextResponse>
171171
const destinationAddress = searchParams.get('address')!;
172172
const chainId = parseInt(searchParams.get('chainId')!);
173173
const supportedChain = findSupportedChain(chainId);
174-
const dripAmount = (supportedChain?.dripAmount || 3).toString();
174+
const dripAmount = (supportedChain?.faucetThresholds?.dripAmount || 3).toString();
175175

176176
const tx = await transferEVMTokens(
177177
FAUCET_ADDRESS!,
@@ -217,8 +217,9 @@ export async function GET(request: NextRequest): Promise<NextResponse> {
217217
identifier: async (_req: NextRequest) => {
218218
const session = await import('@/lib/auth/authSession').then(mod => mod.getAuthSession());
219219
if (!session) throw new Error('Authentication required');
220-
const userId = session.user.id;
221-
return `${userId}-${chainId}`;
220+
const email = session.user.email;
221+
if (!email) throw new Error('email required for rate limiting');
222+
return `${email}-${chainId}`;
222223
}
223224
});
224225

app/api/pchain-faucet/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { rateLimit } from '@/lib/rateLimit';
66
const SERVER_PRIVATE_KEY = process.env.SERVER_PRIVATE_KEY;
77
const FAUCET_P_CHAIN_ADDRESS = process.env.FAUCET_P_CHAIN_ADDRESS;
88
const NETWORK_API = 'https://api.avax-test.network';
9-
const FIXED_AMOUNT = 1;
9+
const FIXED_AMOUNT = 0.5;
1010

1111
if (!SERVER_PRIVATE_KEY || !FAUCET_P_CHAIN_ADDRESS) {
1212
console.error('necessary environment variables are not set');

app/console/layout.tsx

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,39 @@ import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
77
import { SessionProvider } from "next-auth/react";
88
import { Toaster } from "sonner";
99
import { WalletProvider } from "@/components/toolbox/providers/WalletProvider";
10+
import { useAutomatedFaucet } from "@/hooks/useAutomatedFaucet";
11+
12+
function ConsoleContent({ children }: { children: ReactNode }) {
13+
useAutomatedFaucet();
14+
15+
return (
16+
<WalletProvider>
17+
<SidebarProvider
18+
className="h-screen overflow-hidden"
19+
style={
20+
{
21+
"--sidebar-width": "calc(var(--spacing) * 72)",
22+
"--header-height": "calc(var(--spacing) * 12)",
23+
} as React.CSSProperties
24+
}
25+
>
26+
<ConsoleSidebar variant="inset" />
27+
<SidebarInset className="bg-white dark:bg-gray-800 h-[calc(100vh-1rem)] overflow-hidden m-2">
28+
<SiteHeader />
29+
<div className="flex flex-1 flex-col gap-4 p-8 overflow-y-auto h-[calc(100vh-var(--header-height)-1rem)]">
30+
{children}
31+
</div>
32+
</SidebarInset>
33+
</SidebarProvider>
34+
<Toaster position="bottom-right" richColors expand={true} visibleToasts={5}/>
35+
</WalletProvider>
36+
);
37+
}
1038

1139
export default function Layout({ children }: { children: ReactNode }) {
1240
return (
1341
<SessionProvider>
14-
<WalletProvider>
15-
<SidebarProvider
16-
className="h-screen overflow-hidden"
17-
style={
18-
{
19-
"--sidebar-width": "calc(var(--spacing) * 72)",
20-
"--header-height": "calc(var(--spacing) * 12)",
21-
} as React.CSSProperties
22-
}
23-
>
24-
<ConsoleSidebar variant="inset" />
25-
<SidebarInset className="bg-white dark:bg-gray-800 h-[calc(100vh-1rem)] overflow-hidden m-2">
26-
<SiteHeader />
27-
<div className="flex flex-1 flex-col gap-4 p-8 overflow-y-auto h-[calc(100vh-var(--header-height)-1rem)]">
28-
{children}
29-
</div>
30-
</SidebarInset>
31-
</SidebarProvider>
32-
<Toaster position="bottom-right" richColors expand={true} visibleToasts={5} />
33-
</WalletProvider>
42+
<ConsoleContent>{children}</ConsoleContent>
3443
</SessionProvider>
3544
);
3645
}
Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
"use client";
22
import { useState } from "react";
33
import { useWalletStore } from "@/components/toolbox/stores/walletStore";
4-
import { useBuilderHubFaucet } from "../../hooks/useBuilderHubFaucet";
54
import { useL1List, type L1ListItem } from "../../stores/l1ListStore";
6-
import useConsoleNotifications from "@/hooks/useConsoleNotifications";
5+
import { useTestnetFaucet } from "@/hooks/useTestnetFaucet";
76

87
const LOW_BALANCE_THRESHOLD = 1;
98

@@ -27,11 +26,8 @@ export const EVMFaucetButton = ({
2726
updateL1Balance,
2827
updateCChainBalance,
2928
} = useWalletStore();
30-
const { requestTokens } = useBuilderHubFaucet();
3129
const l1List = useL1List();
32-
const { notify } = useConsoleNotifications();
33-
34-
const [isRequestingTokens, setIsRequestingTokens] = useState(false);
30+
const { claimEVMTokens, isClaimingEVM } = useTestnetFaucet();
3531

3632
const chainConfig = l1List.find(
3733
(chain: L1ListItem) =>
@@ -42,31 +38,23 @@ export const EVMFaucetButton = ({
4238
return null;
4339
}
4440

41+
const isRequestingTokens = isClaimingEVM[chainId] || false;
42+
4543
const handleTokenRequest = async () => {
4644
if (isRequestingTokens || !walletEVMAddress) return;
47-
setIsRequestingTokens(true);
48-
const faucetRequest = requestTokens(chainId);
49-
50-
notify(
51-
{
52-
type: "local",
53-
name: `${chainConfig.coinName} Faucet Claim`,
54-
},
55-
faucetRequest
56-
);
5745

5846
try {
59-
await faucetRequest;
47+
await claimEVMTokens(chainId, false);
6048
} catch (error) {
61-
} finally {
62-
setIsRequestingTokens(false);
49+
// error handled via notifications from useTestnetFaucet
6350
}
6451
};
6552

66-
const defaultClassName = `px-2 py-1 text-xs font-medium text-white rounded transition-colors ${cChainBalance < LOW_BALANCE_THRESHOLD
53+
const defaultClassName = `px-2 py-1 text-xs font-medium text-white rounded transition-colors ${
54+
cChainBalance < LOW_BALANCE_THRESHOLD
6755
? "bg-blue-500 hover:bg-blue-600 shimmer"
6856
: "bg-zinc-600 hover:bg-zinc-700"
69-
} ${isRequestingTokens ? "opacity-50 cursor-not-allowed" : ""}`;
57+
} ${isRequestingTokens ? "opacity-50 cursor-not-allowed" : ""}`;
7058

7159
return (
7260
<button
@@ -76,7 +64,9 @@ export const EVMFaucetButton = ({
7664
className={className || defaultClassName}
7765
title={`Get free ${chainConfig.coinName} tokens`}
7866
>
79-
{isRequestingTokens ? "Requesting..." : children || `${chainConfig.coinName} Faucet`}
67+
{isRequestingTokens
68+
? "Requesting..."
69+
: children || `${chainConfig.coinName} Faucet`}
8070
</button>
8171
);
8272
};
Lines changed: 25 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,54 @@
1-
"use client"
2-
import { useState } from "react"
3-
import { useWalletStore } from "@/components/toolbox/stores/walletStore"
4-
import useConsoleNotifications from "@/hooks/useConsoleNotifications"
1+
"use client";
2+
import { useState } from "react";
3+
import { useWalletStore } from "@/components/toolbox/stores/walletStore";
4+
import { useTestnetFaucet } from "@/hooks/useTestnetFaucet";
55

6-
const LOW_BALANCE_THRESHOLD = 0.5
6+
const LOW_BALANCE_THRESHOLD = 0.5;
77

88
interface PChainFaucetButtonProps {
99
className?: string;
1010
buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>;
1111
children?: React.ReactNode;
1212
}
1313

14-
export const PChainFaucetButton = ({ className, buttonProps, children }: PChainFaucetButtonProps = {}) => {
15-
const { pChainAddress, isTestnet, pChainBalance, updatePChainBalance } = useWalletStore();
16-
const { notify } = useConsoleNotifications();
17-
18-
const [isRequestingPTokens, setIsRequestingPTokens] = useState(false);
14+
export const PChainFaucetButton = ({
15+
className,
16+
buttonProps,
17+
children,
18+
}: PChainFaucetButtonProps = {}) => {
19+
const { pChainAddress, isTestnet, pChainBalance, updatePChainBalance } =
20+
useWalletStore();
21+
const { claimPChainAVAX, isClaimingPChain } = useTestnetFaucet();
1922

2023
const handlePChainTokenRequest = async () => {
21-
if (isRequestingPTokens || !pChainAddress) return;
22-
setIsRequestingPTokens(true);
23-
24-
const faucetRequest = async () => {
25-
const response = await fetch(`/api/pchain-faucet?address=${pChainAddress}`);
26-
const rawText = await response.text();
27-
28-
let data;
29-
30-
try {
31-
data = JSON.parse(rawText);
32-
} catch (parseError) {
33-
throw new Error(`Invalid response: ${rawText.substring(0, 100)}...`);
34-
}
35-
36-
if (!response.ok) {
37-
if (response.status === 401) {
38-
throw new Error("Please login first");
39-
}
40-
if (response.status === 429) {
41-
throw new Error(
42-
data.message || "Rate limit exceeded. Please try again later."
43-
);
44-
}
45-
throw new Error(
46-
data.message || `Error ${response.status}: Failed to get tokens`
47-
);
48-
}
49-
50-
if (!data.success) { throw new Error(data.message || "Failed to get tokens") }
51-
return data;
52-
};
53-
54-
const faucetPromise = faucetRequest();
55-
56-
notify(
57-
{
58-
type: "local",
59-
name: "P-Chain AVAX Faucet Claim",
60-
},
61-
faucetPromise
62-
);
24+
if (isClaimingPChain || !pChainAddress) return;
6325

64-
try {
65-
await faucetPromise;
26+
try {
27+
await claimPChainAVAX(false);
6628
} catch (error) {
67-
} finally {
68-
setIsRequestingPTokens(false);
29+
// error handling done via notifications
6930
}
7031
};
7132

72-
if (!isTestnet) { return null }
33+
if (!isTestnet) {
34+
return null;
35+
}
7336

74-
const defaultClassName = `px-2 py-1 text-xs font-medium text-white rounded transition-colors ${pChainBalance < LOW_BALANCE_THRESHOLD
37+
const defaultClassName = `px-2 py-1 text-xs font-medium text-white rounded transition-colors ${
38+
pChainBalance < LOW_BALANCE_THRESHOLD
7539
? "bg-blue-500 hover:bg-blue-600 shimmer"
7640
: "bg-zinc-600 hover:bg-zinc-700"
77-
} ${isRequestingPTokens ? "opacity-50 cursor-not-allowed" : ""}`;
41+
} ${isClaimingPChain ? "opacity-50 cursor-not-allowed" : ""}`;
7842

7943
return (
8044
<button
8145
{...buttonProps}
8246
onClick={handlePChainTokenRequest}
83-
disabled={isRequestingPTokens}
47+
disabled={isClaimingPChain}
8448
className={className || defaultClassName}
8549
title="Get free P-Chain AVAX"
8650
>
87-
{isRequestingPTokens ? "Requesting..." : children || "Faucet"}
51+
{isClaimingPChain ? "Requesting..." : children || "Faucet"}
8852
</button>
8953
);
9054
};

components/toolbox/components/console-header/evm-network-wallet/hooks/useNetworkActions.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { useWalletStore } from '@/components/toolbox/stores/walletStore'
22
import { networkIDs } from '@avalabs/avalanchejs'
3+
import { useChainTokenTracker } from '@/hooks/useChainTokenTracker'
4+
import { useL1List, type L1ListItem } from '@/components/toolbox/stores/l1ListStore'
35

46
export function useNetworkActions() {
57
const {
@@ -10,7 +12,11 @@ export function useNetworkActions() {
1012
setIsTestnet,
1113
isTestnet,
1214
walletEVMAddress,
15+
balances,
1316
} = useWalletStore()
17+
18+
const l1List = useL1List()
19+
const { markChainAsNeeded } = useChainTokenTracker()
1420

1521
const handleNetworkChange = async (network: any) => {
1622
try {
@@ -30,6 +36,7 @@ export function useNetworkActions() {
3036

3137
// Determine if this is C-Chain for appropriate balance update
3238
const isCChain = network.evmChainId === 43114 || network.evmChainId === 43113
39+
3340
setTimeout(() => {
3441
if (isCChain) {
3542
updateCChainBalance()

0 commit comments

Comments
 (0)