diff --git a/.changeset/olive-monkeys-unite.md b/.changeset/olive-monkeys-unite.md new file mode 100644 index 0000000000..96426d9f09 --- /dev/null +++ b/.changeset/olive-monkeys-unite.md @@ -0,0 +1,5 @@ +--- +"@coinbase/onchainkit": patch +--- + +- **patch**: Add connect wallet functionality to Swap component for disconnected user. By @abcrane123 #1173 diff --git a/playground/nextjs-app-router/components/demo/Swap.tsx b/playground/nextjs-app-router/components/demo/Swap.tsx index 37025d2d28..ec89093c26 100644 --- a/playground/nextjs-app-router/components/demo/Swap.tsx +++ b/playground/nextjs-app-router/components/demo/Swap.tsx @@ -9,11 +9,10 @@ import { } from '@coinbase/onchainkit/swap'; import type { Token } from '@coinbase/onchainkit/token'; import { useCallback, useContext } from 'react'; -import { useAccount } from 'wagmi'; +import { base } from 'viem/chains'; import { AppContext } from '../AppProvider'; function SwapComponent() { - const { address } = useAccount(); const { chainId } = useContext(AppContext); const degenToken: Token = { @@ -23,7 +22,7 @@ function SwapComponent() { decimals: 18, image: 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/3b/bf/3bbf118b5e6dc2f9e7fc607a6e7526647b4ba8f0bea87125f971446d57b296d2-MDNmNjY0MmEtNGFiZi00N2I0LWIwMTItMDUyMzg2ZDZhMWNm', - chainId: 8453, + chainId: base.id, }; const ethToken: Token = { @@ -33,7 +32,7 @@ function SwapComponent() { decimals: 18, image: 'https://wallet-api-production.s3.amazonaws.com/uploads/tokens/eth_288.png', - chainId: 8453, + chainId: base.id, }; const usdcToken: Token = { @@ -43,7 +42,7 @@ function SwapComponent() { decimals: 6, image: 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/44/2b/442b80bd16af0c0d9b22e03a16753823fe826e5bfd457292b55fa0ba8c1ba213-ZWUzYjJmZGUtMDYxNy00NDcyLTg0NjQtMWI4OGEwYjBiODE2', - chainId: 8453, + chainId: base.id, }; const wethToken: Token = { @@ -53,7 +52,7 @@ function SwapComponent() { decimals: 6, image: 'https://d3r81g40ycuhqg.cloudfront.net/wallet/wais/47/bc/47bc3593c2dec7c846b66b7ba5f6fa6bd69ec34f8ebb931f2a43072e5aaac7a8-YmUwNmRjZDUtMjczYy00NDFiLWJhZDUtMzgwNjFmYWM0Njkx', - chainId: 8453, + chainId: base.id, }; const swappableTokens = [degenToken, ethToken, usdcToken, wethToken]; @@ -63,53 +62,48 @@ function SwapComponent() { }, []); return ( -
- {address ? ( - chainId !== 8453 ? ( -
-
- Swap Demo is only available on Base. -
- Please change your chain in settings. -
-
- ) : ( - <> - ) - ) : ( +
+ {chainId !== base.id ? (
- Swap Demo requires wallet. + Swap Demo is only available on Base.
- Please connect in settings. + You're connected to a different network. Switch to Base to continue + using the app.
- )} - {address ? ( - - - - - - - ) : ( <> )} + + {ENVIRONMENT_VARIABLES[ENVIRONMENT.ENVIRONMENT] === 'production' && + chainId === base.id ? ( +
+ Note: Swap is disabled on production. To test, run the app locally. +
+ ) : null} + + + + + + + +
); } diff --git a/src/swap/components/SwapAmountInput.test.tsx b/src/swap/components/SwapAmountInput.test.tsx index 7aa04e46a8..affbe040d4 100644 --- a/src/swap/components/SwapAmountInput.test.tsx +++ b/src/swap/components/SwapAmountInput.test.tsx @@ -34,6 +34,7 @@ vi.mock('./SwapProvider', () => ({ const useSwapContextMock = useSwapContext as Mock; const mockContextValue = { + address: '0x123', from: { amount: '10', balance: '0.0002851826238227', @@ -87,6 +88,14 @@ describe('SwapAmountInput', () => { ).not.toBeInTheDocument(); }); + it('should not render max button if wallet not connected', () => { + useSwapContextMock.mockReturnValue({ ...mockContextValue, address: '' }); + render(); + expect( + screen.queryByTestId('ockSwapAmountInput_MaxButton'), + ).not.toBeInTheDocument(); + }); + it('should update input value with balance amount on max button click', () => { useSwapContextMock.mockReturnValue(mockContextValue); render(); diff --git a/src/swap/components/SwapAmountInput.tsx b/src/swap/components/SwapAmountInput.tsx index 63fc10fb6d..99f9609ba3 100644 --- a/src/swap/components/SwapAmountInput.tsx +++ b/src/swap/components/SwapAmountInput.tsx @@ -17,7 +17,7 @@ export function SwapAmountInput({ type, swappableTokens, }: SwapAmountInputReact) { - const { to, from, handleAmountChange } = useSwapContext(); + const { address, to, from, handleAmountChange } = useSwapContext(); const source = useValue(type === 'from' ? from : to); const destination = useValue(type === 'from' ? to : from); @@ -82,7 +82,7 @@ export function SwapAmountInput({ className={cn( 'w-full border-[none] bg-transparent font-display text-[2.5rem]', 'leading-none outline-none', - hasInsufficientBalance ? color.error : color.foreground, + hasInsufficientBalance && address ? color.error : color.foreground, )} placeholder="0.0" delayMs={delayMs} @@ -112,7 +112,7 @@ export function SwapAmountInput({ className={cn(text.label2, color.foregroundMuted)} >{`Balance: ${getRoundedAmount(source.balance, 8)}`} )} - {type === 'from' && ( + {type === 'from' && address && (