Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions app/components/TransferForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useSmartWallets } from "@privy-io/react-auth/smart-wallets";
import { useShouldUseEOA, useWalletMigrationStatus } from "../hooks/useEIP7702Account";
import { useNetwork } from "../context/NetworksContext";
import { useBalance, useTokens } from "../context";
import WalletMigrationModal from "./WalletMigrationModal";
import {
classNames,
formatDecimalPrecision,
Expand Down Expand Up @@ -47,12 +48,16 @@ export const TransferForm: React.FC<{
const { user, getAccessToken } = usePrivy();
const { wallets } = useWallets();
const shouldUseEOA = useShouldUseEOA();
const { isChecking: isMigrationChecking } = useWalletMigrationStatus();
const { isChecking: isMigrationChecking, needsMigration, isRemainingFundsMigration } = useWalletMigrationStatus();
const { refreshBalance } = useBalance();
const { allTokens } = useTokens();
const useInjectedWallet = shouldUseInjectedWallet(searchParams);
const isDark = useActualTheme();

const MIGRATION_DEADLINE = new Date("2026-03-01T00:00:00Z");
const isMigrationMandatory = needsMigration && !isRemainingFundsMigration && new Date() >= MIGRATION_DEADLINE;
const [isMigrationModalOpen, setIsMigrationModalOpen] = useState(false);

// State for network dropdown
const [isNetworkDropdownOpen, setIsNetworkDropdownOpen] = useState(false);
const networkDropdownRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -323,9 +328,18 @@ export const TransferForm: React.FC<{
const networksMatch = selectedNetwork.chain.name === recipientNetwork;
const showNetworkWarning = recipientNetwork && !networksMatch;

const onFormSubmit = (data: any) => {
if (isMigrationMandatory) {
setIsMigrationModalOpen(true);
return;
}
transfer({ ...data, resetForm: reset });
};

return (
<>
<form
onSubmit={handleSubmit((data) => transfer({ ...data, resetForm: reset }))}
onSubmit={handleSubmit(onFormSubmit)}
className="z-50 w-full max-w-full space-y-4 overflow-x-hidden text-neutral-900 transition-all dark:text-white"
noValidate
>
Expand Down Expand Up @@ -622,5 +636,11 @@ export const TransferForm: React.FC<{
{isConfirming ? "Confirming..." : "Continue"}
</button>
</form>

<WalletMigrationModal
isOpen={isMigrationModalOpen}
onClose={() => setIsMigrationModalOpen(false)}
/>
</>
);
};
4 changes: 2 additions & 2 deletions app/components/WalletMigrationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ const WalletMigrationModal: React.FC<WalletMigrationModalProps> = ({
{/* Approve Migration Button */}
<button
onClick={handleApproveMigration}
className="w-full rounded-xl bg-lavender-500 px-6 py-3.5 text-sm font-medium text-white transition-all hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 focus:ring-offset-white active:opacity-80 dark:focus:ring-offset-neutral-900"
className="w-full rounded-xl bg-lavender-500 px-4 py-3.5 text-center text-sm font-medium text-white transition-all hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-lavender-500 focus:ring-offset-2 focus:ring-offset-white active:opacity-80 sm:px-6 dark:focus:ring-offset-neutral-900"
>
Approve Transfer
Approve transfer
</button>
</div>
</motion.div>
Expand Down
8 changes: 5 additions & 3 deletions app/components/WalletTransferApprovalModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ const WalletTransferApprovalModal: React.FC<WalletTransferApprovalModalProps> =
continue;
}

setProgress(`Transferring ${calls.length} token(s) on ${chainName} (gasless)...`);
setProgress(`Transferring ${calls.length} token${calls.length === 1 ? '' : 's'} on ${chainName}.`);

// ✅ Send batched transaction from SCW
const txHash = (await smartWalletClient.sendTransaction({
Expand Down Expand Up @@ -537,9 +537,11 @@ const WalletTransferApprovalModal: React.FC<WalletTransferApprovalModalProps> =
<button
onClick={handleApproveTransfer}
disabled={isProcessing || isLoading || isFetchingBalances}
className="w-full rounded-xl bg-lavender-500 px-6 py-3.5 text-sm font-medium text-white hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-opacity"
className="w-full rounded-xl bg-lavender-500 px-4 py-3.5 text-center text-sm font-medium text-white hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed transition-opacity sm:px-6"
>
{isProcessing ? progress || "Processing migration..." : isFetchingBalances ? "Loading balances..." : tokens.length === 0 ? "Complete migration" : "Approve transfer"}
<span className="block truncate">
{isProcessing ? progress || "Processing..." : isFetchingBalances ? "Loading balances..." : tokens.length === 0 ? "Complete migration" : "Approve transfer"}
</span>
</button>
</div>
</motion.div>
Expand Down
9 changes: 5 additions & 4 deletions app/hooks/useSwapButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface UseSwapButtonProps {
rate?: number | null;
tokenDecimals?: number;
needsMigration?: boolean;
isRemainingFundsMigration?: boolean;
}

export function useSwapButton({
Expand All @@ -25,6 +26,7 @@ export function useSwapButton({
rate,
tokenDecimals = 18,
needsMigration = false,
isRemainingFundsMigration = false,
}: UseSwapButtonProps) {
const { authenticated } = usePrivy();
const { isInjectedWallet } = useInjectedWallet();
Expand All @@ -34,7 +36,7 @@ export function useSwapButton({
const isCurrencySelected = Boolean(currency);

const isMigrationMandatory =
needsMigration && new Date() >= MIGRATION_DEADLINE;
needsMigration && !isRemainingFundsMigration && new Date() >= MIGRATION_DEADLINE;

// Calculate sender fee and include in balance check
const { feeAmount: senderFeeAmount } = calculateSenderFee(
Expand All @@ -47,7 +49,7 @@ export function useSwapButton({
const hasInsufficientBalance = totalRequired > balance;

const isEnabled = (() => {
if (isMigrationMandatory) return false;
if (isMigrationMandatory) return true;
if (!rate) return false;
if (isInjectedWallet && hasInsufficientBalance) {
return false;
Expand Down Expand Up @@ -87,8 +89,6 @@ export function useSwapButton({
})();

const buttonText = (() => {
if (isMigrationMandatory) return "Migrate wallet";

if (isInjectedWallet && hasInsufficientBalance) {
return "Insufficient balance";
}
Expand Down Expand Up @@ -132,5 +132,6 @@ export function useSwapButton({
buttonText,
buttonAction,
hasInsufficientBalance,
isMigrationMandatory,
};
}
17 changes: 15 additions & 2 deletions app/pages/TransactionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
useNetwork,
useTokens,
} from "../context";
import WalletMigrationModal from "../components/WalletMigrationModal";

/**
* TransactionForm component renders a form for submitting a transaction.
Expand Down Expand Up @@ -74,7 +75,7 @@ export const TransactionForm = ({
const { selectedNetwork } = useNetwork();
const { smartWalletBalance, externalWalletBalance, injectedWalletBalance, isLoading } = useBalance();
const shouldUseEOA = useShouldUseEOA();
const { needsMigration } = useWalletMigrationStatus();
const { needsMigration, isRemainingFundsMigration } = useWalletMigrationStatus();
const { isInjectedWallet, injectedAddress } = useInjectedWallet();
const { allTokens } = useTokens();

Expand Down Expand Up @@ -470,7 +471,7 @@ export const TransactionForm = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currencies]);

const { isEnabled, buttonText, buttonAction } = useSwapButton({
const { isEnabled, buttonText, buttonAction, isMigrationMandatory } = useSwapButton({
watch,
balance,
isDirty,
Expand All @@ -479,9 +480,16 @@ export const TransactionForm = ({
rate,
tokenDecimals,
needsMigration,
isRemainingFundsMigration,
});

const [isMigrationModalOpen, setIsMigrationModalOpen] = useState(false);

const handleSwap = () => {
if (isMigrationMandatory) {
setIsMigrationModalOpen(true);
return;
}
setOrderId("");
handleSubmit(onSubmit)();
};
Expand Down Expand Up @@ -948,6 +956,11 @@ export const TransactionForm = ({
<FundWalletForm onClose={() => setIsFundModalOpen(false)} />
</AnimatedModal>
)}

<WalletMigrationModal
isOpen={isMigrationModalOpen}
onClose={() => setIsMigrationModalOpen(false)}
/>
</div>
);
};