diff --git a/ui/components/api-key-input.tsx b/ui/components/api-key-input.tsx
new file mode 100644
index 00000000..85e62f05
--- /dev/null
+++ b/ui/components/api-key-input.tsx
@@ -0,0 +1,39 @@
+'use client';
+
+import { useState, useEffect } from 'react';
+import * as React from 'react';
+import { Input } from '@/components/ui/input';
+
+interface ApiKeyInputProps extends React.ComponentProps<'input'> {
+ onApiKeyChange: (apiKey: string) => void;
+}
+
+export function ApiKeyInput({
+ value,
+ onApiKeyChange,
+ ...props
+}: ApiKeyInputProps) {
+ const [internalValue, setInternalValue] = useState(value || '');
+
+ useEffect(() => {
+ setInternalValue(value || '');
+ }, [value]);
+
+ useEffect(() => {
+ const handler = setTimeout(() => {
+ onApiKeyChange(internalValue as string);
+ }, 300);
+
+ return () => clearTimeout(handler);
+ }, [internalValue, onApiKeyChange]);
+
+ return (
+ setInternalValue(e.target.value)}
+ placeholder='sk-...'
+ className='font-mono text-sm'
+ {...props}
+ />
+ );
+}
diff --git a/ui/components/child-key-creator.tsx b/ui/components/child-key-creator.tsx
index 460108b9..d82added 100644
--- a/ui/components/child-key-creator.tsx
+++ b/ui/components/child-key-creator.tsx
@@ -2,6 +2,7 @@
import { useState } from 'react';
import { WalletService } from '@/lib/api/services/wallet';
+import { ApiKeyInput } from './api-key-input';
import { Button } from '@/components/ui/button';
import {
Card,
@@ -250,12 +251,22 @@ export function ChildKeyCreator({
- handleApiKeyChange(e.target.value)}
- placeholder='sk-...'
- className='font-mono text-sm'
- />
+
+
+
+
)}
diff --git a/ui/components/landing/cashu-payment-workflow.tsx b/ui/components/landing/cashu-payment-workflow.tsx
index 7af3e231..5608833f 100644
--- a/ui/components/landing/cashu-payment-workflow.tsx
+++ b/ui/components/landing/cashu-payment-workflow.tsx
@@ -11,6 +11,7 @@ import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import { KeyOptions } from '@/components/key-options';
import { WalletBalanceStats } from './wallet-balance-stats';
+import { ApiKeyInput } from '../api-key-input';
import type { ChildKeyInfo, WalletSnapshot } from './key-info-details';
export type RefundReceipt = {
@@ -271,7 +272,7 @@ export function CashuPaymentWorkflow({
onWalletInfoUpdated?.(null);
}
},
- [apiKey]
+ [apiKey, onWalletInfoUpdated]
);
const showManageDetails = hasInteractedManage || Boolean(walletInfo);
@@ -342,11 +343,9 @@ export function CashuPaymentWorkflow({
)}
-
handleApiKeyChange(event.target.value)}
- placeholder='sk-...'
- className='font-mono text-sm'
+ onApiKeyChange={handleApiKeyChange}
onFocus={() => setHasInteractedManage(true)}
/>
diff --git a/ui/components/landing/key-info-details.tsx b/ui/components/landing/key-info-details.tsx
index 053a51fa..dbadeb1c 100644
--- a/ui/components/landing/key-info-details.tsx
+++ b/ui/components/landing/key-info-details.tsx
@@ -4,6 +4,7 @@ import { type JSX, useState, useCallback, useEffect } from 'react';
import { Copy, RefreshCcw, RotateCcw, Trash2 } from 'lucide-react';
import type { RefundReceipt } from './cashu-payment-workflow';
import { toast } from 'sonner';
+import { ApiKeyInput } from '../api-key-input';
import {
Card,
CardContent,
@@ -13,7 +14,6 @@ import {
} from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
-import { Input } from '@/components/ui/input';
import { WalletService } from '@/lib/api/services/wallet';
export type ChildKeyInfo = {
@@ -188,12 +188,7 @@ export function KeyInfoDetails({
-
handleKeyChange(e.target.value)}
- placeholder='sk-...'
- className='font-mono text-sm'
- />
+