From 3c601230240b22a4aa915952b9ef9399376d1662 Mon Sep 17 00:00:00 2001 From: Jonathan Bursztyn Date: Thu, 14 May 2026 21:32:59 +0100 Subject: [PATCH 1/2] feat(vault): new onboarding for wallet --- .../src/components/Chains/index.tsx | 41 +++++++- .../components/TermsOfService/container.tsx | 16 ---- .../TermsOfService/index.stories.tsx | 19 ---- .../src/components/TermsOfService/index.tsx | 96 ------------------- .../WalletProvider/components/Screen.tsx | 6 -- .../components/WalletDialog.tsx | 11 +-- .../src/components/WalletProvider/index.tsx | 8 +- .../src/context/State.context.tsx | 8 +- services/vault/.env.example | 2 - services/vault/README.md | 4 - services/vault/src/config/featureFlags.ts | 11 --- .../wallet/VaultWalletConnectionProvider.tsx | 2 - 12 files changed, 42 insertions(+), 182 deletions(-) delete mode 100644 packages/babylon-wallet-connector/src/components/TermsOfService/container.tsx delete mode 100644 packages/babylon-wallet-connector/src/components/TermsOfService/index.stories.tsx delete mode 100644 packages/babylon-wallet-connector/src/components/TermsOfService/index.tsx diff --git a/packages/babylon-wallet-connector/src/components/Chains/index.tsx b/packages/babylon-wallet-connector/src/components/Chains/index.tsx index b7d1e2f40..ff5efae75 100644 --- a/packages/babylon-wallet-connector/src/components/Chains/index.tsx +++ b/packages/babylon-wallet-connector/src/components/Chains/index.tsx @@ -1,9 +1,10 @@ -import { Button, DialogBody, DialogFooter, DialogHeader, Text } from "@babylonlabs-io/core-ui"; -import { memo } from "react"; +import { Button, Checkbox, DialogBody, DialogFooter, DialogHeader, Text } from "@babylonlabs-io/core-ui"; +import { memo, useState } from "react"; import { twMerge } from "tailwind-merge"; import { ChainButton } from "@/components/ChainButton"; import { ConnectedWallet } from "@/components/ConnectedWallet"; +import { FieldControl } from "@/components/FieldControl"; import type { IChain, IWallet } from "@/core/types"; interface ChainsProps { @@ -28,6 +29,7 @@ export const Chains = memo( onSelectChain, onDisconnectWallet, }: ChainsProps) => { + const [termsAccepted, setTermsAccepted] = useState(false); const chainNames = chains.map((chain) => chain.name).join(" and "); const subtitle = `Connect to both ${chainNames} Wallets`; @@ -62,6 +64,34 @@ export const Chains = memo( ); })} + + + I certify that I have read and accept the updated{" "} + + Terms of Use + {" "} + and{" "} + + Privacy Policy + + . + + } + > + setTermsAccepted(value)} /> + @@ -69,7 +99,12 @@ export const Chains = memo( Cancel - diff --git a/packages/babylon-wallet-connector/src/components/TermsOfService/container.tsx b/packages/babylon-wallet-connector/src/components/TermsOfService/container.tsx deleted file mode 100644 index 56e709dcc..000000000 --- a/packages/babylon-wallet-connector/src/components/TermsOfService/container.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { useWidgetState } from "@/hooks/useWidgetState"; - -import { TermsOfService } from "."; - -export interface TermsOfServiceContainerProps { - className?: string; - onClose?: () => void; - onSubmit?: () => void; - simplifiedTerms?: boolean; -} - -export function TermsOfServiceContainer(props: TermsOfServiceContainerProps) { - const { chains } = useWidgetState(); - - return ; -} diff --git a/packages/babylon-wallet-connector/src/components/TermsOfService/index.stories.tsx b/packages/babylon-wallet-connector/src/components/TermsOfService/index.stories.tsx deleted file mode 100644 index be69bbee1..000000000 --- a/packages/babylon-wallet-connector/src/components/TermsOfService/index.stories.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; - -import { TermsOfService } from "./index"; - -const meta: Meta = { - component: TermsOfService, - tags: ["autodocs"], -}; - -export default meta; - -type Story = StoryObj; - -export const Default: Story = { - args: { - onClose: console.log, - className: "h-[600px]", - }, -}; diff --git a/packages/babylon-wallet-connector/src/components/TermsOfService/index.tsx b/packages/babylon-wallet-connector/src/components/TermsOfService/index.tsx deleted file mode 100644 index 0f36ceb2f..000000000 --- a/packages/babylon-wallet-connector/src/components/TermsOfService/index.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Button, Checkbox, DialogBody, DialogFooter, DialogHeader, Text } from "@babylonlabs-io/core-ui"; -import { useCallback, useMemo, useState } from "react"; -import { twMerge } from "tailwind-merge"; - -import { FieldControl } from "@/components/FieldControl"; -import { BTCConfig } from "@/core/types"; - -export interface Props { - className?: string; - config?: BTCConfig; - onClose?: () => void; - onSubmit?: () => void; - simplifiedTerms?: boolean; -} - -const defaultState = { - termsOfUse: false, - inscriptions: false, - staking: false, -} as const; - -export function TermsOfService({ className, onClose, onSubmit, simplifiedTerms = false }: Props) { - const [state, setState] = useState(defaultState); - const valid = useMemo( - () => (simplifiedTerms ? state.termsOfUse : Object.values(state).every((val) => val)), - [state, simplifiedTerms], - ); - - const handleChange = useCallback( - (key: keyof typeof defaultState) => - (value: boolean = false) => { - setState((state) => ({ ...state, [key]: value })); - }, - [], - ); - - return ( -
- - Please read and accept the following terms - - - - - I certify that I have read and accept the updated{" "} - - Terms of Use - {" "} - and{" "} - - Privacy Policy - - . -
- } - className="mb-4" - > - - - - {!simplifiedTerms && ( - <> - - - - - - - - - )} - - - - - - - ); -} diff --git a/packages/babylon-wallet-connector/src/components/WalletProvider/components/Screen.tsx b/packages/babylon-wallet-connector/src/components/WalletProvider/components/Screen.tsx index 56305f4cf..9240eb2dc 100644 --- a/packages/babylon-wallet-connector/src/components/WalletProvider/components/Screen.tsx +++ b/packages/babylon-wallet-connector/src/components/WalletProvider/components/Screen.tsx @@ -4,7 +4,6 @@ import { ChainsContainer as Chains } from "@/components/Chains/container"; import { ErrorContainer as Error } from "@/components/Error/container"; import { InscriptionsContainer as Inscriptions } from "@/components/Inscriptions/container"; import { LoaderScreen } from "@/components/Loader"; -import { TermsOfServiceContainer as TermsOfService } from "@/components/TermsOfService/container"; import { WalletsContainer as Wallets } from "@/components/Wallets/container"; import type { Screen } from "@/context/State.context"; import type { IChain, IWallet } from "@/core/types"; @@ -16,17 +15,12 @@ interface ScreenProps { widgets?: Record; onSelectWallet?: (chain: IChain, wallet: IWallet) => void; onDisconnectWallet?: (chainId: string) => void; - onAccepTermsOfService?: () => void; onToggleInscriptions?: (value: boolean, showAgain: boolean) => void; onClose?: () => void; onConfirm?: () => void; - simplifiedTerms?: boolean; } const SCREENS = { - TERMS_OF_SERVICE: ({ className, onClose, onAccepTermsOfService, simplifiedTerms }: ScreenProps) => ( - - ), CHAINS: ({ className, onClose, onConfirm, onDisconnectWallet }: ScreenProps) => ( ), diff --git a/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx b/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx index cdf85de81..3deb9802a 100644 --- a/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx +++ b/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx @@ -16,12 +16,11 @@ interface WalletDialogProps { storage: HashMap; config: any; persistent: boolean; - simplifiedTerms?: boolean; } const ANIMATION_DELAY = 1000; -export function WalletDialog({ persistent, storage, config, onError, simplifiedTerms }: WalletDialogProps) { +export function WalletDialog({ persistent, storage, config, onError }: WalletDialogProps) { const { visible, screen, confirmed, close, confirm, displayChains } = useWidgetState(); const { toggleShowAgain, toggleLockInscriptions } = useInscriptionProvider(); const connectors = useChainProviders(); @@ -29,10 +28,6 @@ export function WalletDialog({ persistent, storage, config, onError, simplifiedT const { connect, disconnect } = useWalletConnectors({ persistent, accountStorage: storage, onError }); const { disconnect: disconnectAll } = useWalletConnect(); - const handleAccepTermsOfService = useCallback(() => { - displayChains?.(); - }, [displayChains]); - const handleToggleInscriptions = useCallback( (lockInscriptions: boolean, showAgain: boolean) => { toggleShowAgain?.(showAgain); @@ -63,11 +58,9 @@ export function WalletDialog({ persistent, storage, config, onError, simplifiedT onClose={handleClose} onConfirm={handleConfirm} onSelectWallet={connect} - onAccepTermsOfService={handleAccepTermsOfService} onToggleInscriptions={handleToggleInscriptions} onDisconnectWallet={disconnect} - simplifiedTerms={simplifiedTerms} /> ); -} \ No newline at end of file +} diff --git a/packages/babylon-wallet-connector/src/components/WalletProvider/index.tsx b/packages/babylon-wallet-connector/src/components/WalletProvider/index.tsx index b1c070971..c734fa9b1 100644 --- a/packages/babylon-wallet-connector/src/components/WalletProvider/index.tsx +++ b/packages/babylon-wallet-connector/src/components/WalletProvider/index.tsx @@ -48,11 +48,6 @@ interface WalletProviderProps { * Provide eth and/or btc properties to enable respective chains */ appKitConfig?: AppKitModalConfig; - /** - * When true, only show the T&C checkbox in the terms of service dialog - * instead of all three checkboxes (inscriptions, hardware wallet warnings) - */ - simplifiedTerms?: boolean; disableTomo?: boolean; } @@ -68,7 +63,6 @@ export function WalletProvider({ disabledWallets = [], requiredChains, appKitConfig, - simplifiedTerms = false, disableTomo = false, }: PropsWithChildren) { const networkMap = useMemo(() => deriveNetworkMap(config), [config]); @@ -113,7 +107,7 @@ export function WalletProvider({ )} - + ); diff --git a/packages/babylon-wallet-connector/src/context/State.context.tsx b/packages/babylon-wallet-connector/src/context/State.context.tsx index f2b9820e3..6488a36a5 100644 --- a/packages/babylon-wallet-connector/src/context/State.context.tsx +++ b/packages/babylon-wallet-connector/src/context/State.context.tsx @@ -9,7 +9,6 @@ export type Screen = { export type Screens = | Screen<"LOADER"> - | Screen<"TERMS_OF_SERVICE"> | Screen<"CHAINS"> | Screen<"WALLETS"> | Screen<"INSCRIPTIONS"> @@ -30,7 +29,6 @@ export interface Actions { displayChains?: () => void; displayWallets?: (chain: string) => void; displayInscriptions?: () => void; - displayTermsOfService?: () => void; displayError?: (params: { icon?: JSX.Element; title: string; @@ -49,7 +47,7 @@ export interface Actions { const defaultState: State = { confirmed: false, visible: false, - screen: { type: "TERMS_OF_SERVICE" }, + screen: { type: "CHAINS" }, chains: {}, selectedWallets: {}, }; @@ -105,10 +103,6 @@ export function StateProvider({ children, chains }: PropsWithChildren ({ ...state, screen: { type: "LOADER", params: { message } } })); }, - displayTermsOfService: () => { - setState((state) => ({ ...state, screen: { type: "TERMS_OF_SERVICE" } })); - }, - displayChains: () => { setState((state) => ({ ...state, screen: { type: "CHAINS" } })); }, diff --git a/services/vault/.env.example b/services/vault/.env.example index e2347a531..9f14c5d7b 100644 --- a/services/vault/.env.example +++ b/services/vault/.env.example @@ -38,8 +38,6 @@ NEXT_PUBLIC_TBV_SIDECAR_API_URL=https://sidecar-api.canon-devnet.babylonlabs.io # NEXT_PUBLIC_FF_DISABLE_VAULT_CAP=true # Shows the position notifications debug panel for testing notification scenarios # NEXT_PUBLIC_FF_POSITION_DEBUG_PANEL=true -# Show only the T&C checkbox in the wallet connection dialog instead of all three. -# NEXT_PUBLIC_FF_SIMPLIFIED_TERMS=true # Added by sync-env from devnet diff --git a/services/vault/README.md b/services/vault/README.md index 25ce447b3..7bf813f01 100644 --- a/services/vault/README.md +++ b/services/vault/README.md @@ -83,10 +83,6 @@ Create a `.env` file with the following variables: - Set to `"true"` to disable borrowing functionality - When disabled, users will see "Borrowing Unavailable" and the borrow button will be disabled -- `NEXT_PUBLIC_FF_SIMPLIFIED_TERMS` - Controls whether the wallet connection dialog shows simplified terms - - Default: `false` (all three checkboxes shown unless explicitly set to `"true"`) - - Set to `"true"` to show only the Terms of Use & Privacy Policy checkbox, hiding the inscriptions and hardware wallet warnings - - `NEXT_PUBLIC_FF_FORCE_PARTIAL_LIQUIDATION_SPLIT` - Forces partial liquidation split to always be suggested, even with active vaults - Default: `false` (disabled unless explicitly set to `"true"`) - Set to `"true"` to bypass the active-vaults check — useful for dev/QA testing of the split deposit flow diff --git a/services/vault/src/config/featureFlags.ts b/services/vault/src/config/featureFlags.ts index 137098a97..530118d78 100644 --- a/services/vault/src/config/featureFlags.ts +++ b/services/vault/src/config/featureFlags.ts @@ -33,17 +33,6 @@ export default { return process.env.NEXT_PUBLIC_FF_DISABLE_BORROW === "true"; }, - /** - * SIMPLIFIED_TERMS feature flag - * - * Purpose: Controls whether the wallet connection dialog shows simplified terms - * Why needed: When enabled, only the T&C checkbox is shown instead of all three - * Default: false (all three checkboxes are shown unless explicitly set to "true") - */ - get isSimplifiedTermsEnabled() { - return process.env.NEXT_PUBLIC_FF_SIMPLIFIED_TERMS === "true"; - }, - /** * FORCE_PARTIAL_LIQUIDATION feature flag * diff --git a/services/vault/src/context/wallet/VaultWalletConnectionProvider.tsx b/services/vault/src/context/wallet/VaultWalletConnectionProvider.tsx index 36ce315ba..7f08a1e84 100644 --- a/services/vault/src/context/wallet/VaultWalletConnectionProvider.tsx +++ b/services/vault/src/context/wallet/VaultWalletConnectionProvider.tsx @@ -10,7 +10,6 @@ import { useTheme } from "next-themes"; import { useCallback, useMemo, useRef, type PropsWithChildren } from "react"; import { getNetworkConfigBTC } from "@/config"; -import featureFlags from "@/config/featureFlags"; import { getNetworkConfigETH } from "@/config/network"; import { logger } from "@/infrastructure"; @@ -116,7 +115,6 @@ export const WalletConnectionProvider = ({ children }: PropsWithChildren) => { onError={onError} disabledWallets={DISABLED_WALLETS} requiredChains={["BTC", "ETH"]} - simplifiedTerms={featureFlags.isSimplifiedTermsEnabled} disableTomo > {children} From 730b139eb687fb0e2839bb1fe146b02e4f2bf155 Mon Sep 17 00:00:00 2001 From: Jonathan Bursztyn Date: Sun, 17 May 2026 21:18:53 +0100 Subject: [PATCH 2/2] fix(wallet-connector): defer TOS acceptance to explicit confirm --- .../components/WalletDialog.tsx | 20 ++++++++++++++++--- .../src/hooks/useWalletConnectors.tsx | 7 +------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx b/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx index 3deb9802a..326c061c5 100644 --- a/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx +++ b/packages/babylon-wallet-connector/src/components/WalletProvider/components/WalletDialog.tsx @@ -3,6 +3,7 @@ import { useCallback } from "react"; import { ResponsiveDialog } from "@/components/ResponsiveDialog/ResponsiveDialog"; import { useChainProviders } from "@/context/Chain.context"; import { useInscriptionProvider } from "@/context/Inscriptions.context"; +import { useLifeCycleHooks } from "@/context/LifecycleHooks.context"; import { HashMap } from "@/core/types"; import { useWalletConnect } from "@/hooks/useWalletConnect"; import { useWalletConnectors } from "@/hooks/useWalletConnectors"; @@ -21,8 +22,9 @@ interface WalletDialogProps { const ANIMATION_DELAY = 1000; export function WalletDialog({ persistent, storage, config, onError }: WalletDialogProps) { - const { visible, screen, confirmed, close, confirm, displayChains } = useWidgetState(); + const { visible, screen, confirmed, selectedWallets, close, confirm, displayChains } = useWidgetState(); const { toggleShowAgain, toggleLockInscriptions } = useInscriptionProvider(); + const { acceptTermsOfService } = useLifeCycleHooks(); const connectors = useChainProviders(); const walletWidgets = useWalletWidgets(connectors, config, onError); const { connect, disconnect } = useWalletConnectors({ persistent, accountStorage: storage, onError }); @@ -44,10 +46,22 @@ export function WalletDialog({ persistent, storage, config, onError }: WalletDia } }, [close, disconnectAll, confirmed]); - const handleConfirm = useCallback(() => { + const handleConfirm = useCallback(async () => { + const btcWallet = selectedWallets["BTC"]; + if (btcWallet?.account?.address && btcWallet.account.publicKeyHex) { + try { + await acceptTermsOfService?.({ + address: btcWallet.account.address, + public_key: btcWallet.account.publicKeyHex, + }); + } catch (e) { + onError?.(e as Error); + return; + } + } confirm?.(); close?.(); - }, [confirm]); + }, [confirm, close, selectedWallets, acceptTermsOfService, onError]); return ( diff --git a/packages/babylon-wallet-connector/src/hooks/useWalletConnectors.tsx b/packages/babylon-wallet-connector/src/hooks/useWalletConnectors.tsx index e07227974..dfa1ac742 100644 --- a/packages/babylon-wallet-connector/src/hooks/useWalletConnectors.tsx +++ b/packages/babylon-wallet-connector/src/hooks/useWalletConnectors.tsx @@ -30,7 +30,7 @@ export function useWalletConnectors({ persistent, accountStorage, onError }: Pro chains: chainMap, } = useWidgetState(); const { showAgain } = useInscriptionProvider(); - const { verifyBTCAddress, acceptTermsOfService } = useLifeCycleHooks(); + const { verifyBTCAddress } = useLifeCycleHooks(); // Connecting event useEffect(() => { @@ -66,11 +66,6 @@ export function useWalletConnectors({ persistent, accountStorage, onError }: Pro validateAddress(connector.config.network, connectedWallet.account.address); - await acceptTermsOfService?.({ - address: connectedWallet.account.address, - public_key: connectedWallet.account.publicKeyHex, - }); - const goToNextScreen = () => void (showAgain ? displayInscriptions?.() : displayChains?.()); if (