diff --git a/packages/yoroi-extension/app/assets/images/revamp/icons/chevron-down.inline.svg b/packages/yoroi-extension/app/assets/images/revamp/icons/chevron-down.inline.svg
new file mode 100644
index 0000000000..8f20fcc172
--- /dev/null
+++ b/packages/yoroi-extension/app/assets/images/revamp/icons/chevron-down.inline.svg
@@ -0,0 +1,3 @@
+
diff --git a/packages/yoroi-extension/app/assets/images/revamp/icons/edit.inline.svg b/packages/yoroi-extension/app/assets/images/revamp/icons/edit.inline.svg
new file mode 100644
index 0000000000..330f53347b
--- /dev/null
+++ b/packages/yoroi-extension/app/assets/images/revamp/icons/edit.inline.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/yoroi-extension/app/assets/images/revamp/icons/info.inline.svg b/packages/yoroi-extension/app/assets/images/revamp/icons/info.inline.svg
index dc2f19dbf1..9df6509f1d 100644
--- a/packages/yoroi-extension/app/assets/images/revamp/icons/info.inline.svg
+++ b/packages/yoroi-extension/app/assets/images/revamp/icons/info.inline.svg
@@ -1,5 +1,5 @@
diff --git a/packages/yoroi-extension/app/assets/images/revamp/icons/refresh.inline.svg b/packages/yoroi-extension/app/assets/images/revamp/icons/refresh.inline.svg
new file mode 100644
index 0000000000..708130d3f4
--- /dev/null
+++ b/packages/yoroi-extension/app/assets/images/revamp/icons/refresh.inline.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/yoroi-extension/app/assets/images/revamp/icons/switch.inline.svg b/packages/yoroi-extension/app/assets/images/revamp/icons/switch.inline.svg
new file mode 100644
index 0000000000..107db0b327
--- /dev/null
+++ b/packages/yoroi-extension/app/assets/images/revamp/icons/switch.inline.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/yoroi-extension/app/assets/images/revamp/token-default.inline.svg b/packages/yoroi-extension/app/assets/images/revamp/token-default.inline.svg
new file mode 100644
index 0000000000..a914ec366e
--- /dev/null
+++ b/packages/yoroi-extension/app/assets/images/revamp/token-default.inline.svg
@@ -0,0 +1,9 @@
+
diff --git a/packages/yoroi-extension/app/components/swap/PriceInput.js b/packages/yoroi-extension/app/components/swap/PriceInput.js
new file mode 100644
index 0000000000..1ff346c554
--- /dev/null
+++ b/packages/yoroi-extension/app/components/swap/PriceInput.js
@@ -0,0 +1,75 @@
+// @flow
+import type { Node } from 'react';
+import { Box, Typography } from '@mui/material';
+import type { AssetAmount } from './types'
+import { BigNumber } from 'bignumber.js';
+
+type Props = {|
+ label: string,
+ baseCurrency: AssetAmount,
+ quoteCurrency: AssetAmount,
+ readonly?: boolean,
+|};
+
+export default function PriceInput({
+ label,
+ baseCurrency,
+ quoteCurrency,
+ readonly = false,
+}: Props): Node {
+ return (
+
+
+ {label}
+
+
+
+
+
+ {baseCurrency.ticker || '-'}
+ /
+ {quoteCurrency.ticker || '-'}
+
+
+
+ );
+}
diff --git a/packages/yoroi-extension/app/components/swap/SwapInput.js b/packages/yoroi-extension/app/components/swap/SwapInput.js
new file mode 100644
index 0000000000..f97f144a84
--- /dev/null
+++ b/packages/yoroi-extension/app/components/swap/SwapInput.js
@@ -0,0 +1,150 @@
+// @flow
+import type { Node } from 'react';
+import { useState } from 'react';
+import { Box, Typography } from '@mui/material';
+import { ReactComponent as ChevronDownIcon } from '../../assets/images/revamp/icons/chevron-down.inline.svg';
+import { ReactComponent as DefaultTokenImage } from '../../assets/images/revamp/token-default.inline.svg';
+import type { AssetAmount } from './types';
+
+type Props = {|
+ label: string,
+ asset: AssetAmount,
+ onAssetSelect: function,
+ handleAmountChange: function,
+ showMax?: boolean,
+ image?: Node | null,
+ isFrom?: boolean,
+|};
+
+export default function SwapInput({
+ label,
+ asset,
+ isFrom = false,
+ showMax = false,
+ image = null,
+ onAssetSelect,
+ handleAmountChange,
+}: Props): Node {
+ const { amount, walletAmount, ticker } = asset;
+ const [error, setError] = useState('');
+ const [inputValue, setInputValue] = useState(amount);
+ const [isFocused, setIsFocused] = useState(false);
+
+ const handleChange = e => {
+ if (e.target.value === '') {
+ setError('');
+ setInputValue('');
+ return;
+ }
+
+ const val = Number(e.target.value);
+ const checkAmount = isFrom ? walletAmount : Infinity;
+
+ if (val !== 0 && val > checkAmount) {
+ setError('Not enough balance');
+ } else if (Number.isNaN(val)) {
+ setError('Invalid amount');
+ } else {
+ handleAmountChange(val);
+ }
+
+ setInputValue(e.target.value);
+ };
+
+ const isFocusedColor = isFocused ? 'black' : 'gray.400';
+
+ return (
+
+
+
+ {label}
+
+
+ setIsFocused(true)}
+ onBlur={() => setIsFocused(false)}
+ />
+
+
+ svg': { width: '100%', height: '100%' } }}>
+ {ticker ? image || : }
+
+ {ticker || 'Select asset'}
+
+
+
+
+
+ {!error && showMax ? (
+
+ {
+ setInputValue(walletAmount);
+ handleAmountChange(walletAmount);
+ }}
+ >
+ MAX
+
+
+ ) : (
+
+ )}
+
+
+ Current balance: {walletAmount || 0} {ticker}
+
+
+
+ {error && (
+
+ {error}
+
+ )}
+
+ );
+}
diff --git a/packages/yoroi-extension/app/components/swap/types.js b/packages/yoroi-extension/app/components/swap/types.js
new file mode 100644
index 0000000000..f59a54c91d
--- /dev/null
+++ b/packages/yoroi-extension/app/components/swap/types.js
@@ -0,0 +1,7 @@
+//@flow
+
+export type AssetAmount = {|
+ ticker: string,
+ amount: string,
+ walletAmount: number,
+|};
\ No newline at end of file
diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/SwapForm.js b/packages/yoroi-extension/app/containers/swap/asset-swap/SwapForm.js
new file mode 100644
index 0000000000..f6d067382c
--- /dev/null
+++ b/packages/yoroi-extension/app/containers/swap/asset-swap/SwapForm.js
@@ -0,0 +1,116 @@
+// @flow
+import type { Node } from 'react';
+import { useState } from 'react';
+import { Box, Button, Typography } from '@mui/material';
+import { ReactComponent as SwitchIcon } from '../../../assets/images/revamp/icons/switch.inline.svg';
+import { ReactComponent as RefreshIcon } from '../../../assets/images/revamp/icons/refresh.inline.svg';
+import { ReactComponent as AdaTokenImage } from './img.inline.svg';
+import { ReactComponent as UsdaTokenImage } from './usda.inline.svg';
+import SwapInput from '../../../components/swap/SwapInput';
+import PriceInput from '../../../components/swap/PriceInput';
+
+const defaultFromAsset = {
+ amount: '',
+ ticker: 'TADA',
+ walletAmount: 212,
+};
+const defaultToAsset = {
+ amount: '',
+ ticker: '',
+ walletAmount: 0,
+};
+
+export default function SwapForm(): Node {
+ const [isMarketOrder, setIsMarketOrder] = useState(true);
+ const [fromAsset, setFromAsset] = useState(defaultFromAsset);
+ const [toAsset, setToAsset] = useState(defaultToAsset);
+
+ const handleSwitchSelectedAssets = () => {
+ setFromAsset(toAsset);
+ setToAsset(fromAsset);
+ };
+
+ const handleAmountChange = (amount, type) => {
+ const func = type === 'from' ? setFromAsset : setToAsset;
+ func(p => ({ ...p, amount }));
+ };
+
+ const handleResetForm = () => {
+ setFromAsset(defaultFromAsset);
+ setToAsset(defaultToAsset);
+ };
+
+ return (
+
+
+
+ setIsMarketOrder(true)}
+ p="8px"
+ borderRadius="8px"
+ bgcolor={isMarketOrder ? 'grayscale.200' : ''}
+ >
+
+ Market
+
+
+ setIsMarketOrder(false)}
+ p="8px"
+ borderRadius="8px"
+ bgcolor={!isMarketOrder ? 'grayscale.200' : ''}
+ >
+
+ Limit
+
+
+
+
+
+
+
+
+ {/* From Field */}
+ : }
+ asset={fromAsset}
+ onAssetSelect={() => null}
+ handleAmountChange={amount => handleAmountChange(amount, 'from')}
+ showMax
+ isFrom
+ />
+
+ {/* Clear and switch */}
+
+
+
+
+
+
+
+
+
+ {/* To Field */}
+ : }
+ asset={toAsset}
+ onAssetSelect={() => null}
+ handleAmountChange={amount => handleAmountChange(amount, 'to')}
+ />
+
+ {/* Price between assets */}
+
+
+
+
+ );
+}
diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js b/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js
index 29ee9a8a03..5858eb8b87 100644
--- a/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js
+++ b/packages/yoroi-extension/app/containers/swap/asset-swap/SwapPage.js
@@ -1,6 +1,49 @@
// @flow
import type { Node } from 'react';
+import { useState } from 'react';
+import { Box, Button } from '@mui/material';
+import SwapForm from './SwapForm';
export default function SwapPage(): Node {
- return <>Swap form here>;
+ const [step, setStep] = useState(0);
+
+ //
+ // eslint-disable-next-line no-unused-vars
+ const [isSuccessful, setIsSuccessful] = useState(false);
+
+ const handleNextStep = () => setStep(s => s + 1);
+ const handlePrevStep = () => setStep(s => s - 1);
+
+ return (
+
+ {step === 0 && }
+ {step < 2 && (
+
+ {step === 1 && (
+
+ )}
+
+
+ )}
+
+ );
}
diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/img.inline.svg b/packages/yoroi-extension/app/containers/swap/asset-swap/img.inline.svg
new file mode 100644
index 0000000000..ca6bd935b4
--- /dev/null
+++ b/packages/yoroi-extension/app/containers/swap/asset-swap/img.inline.svg
@@ -0,0 +1,9 @@
+
diff --git a/packages/yoroi-extension/app/containers/swap/asset-swap/usda.inline.svg b/packages/yoroi-extension/app/containers/swap/asset-swap/usda.inline.svg
new file mode 100644
index 0000000000..d49f12d12e
--- /dev/null
+++ b/packages/yoroi-extension/app/containers/swap/asset-swap/usda.inline.svg
@@ -0,0 +1,9 @@
+