diff --git a/apps/trading-e2e/src/integration/capsule.cy.ts b/apps/trading-e2e/src/integration/capsule.cy.ts
index a9d8735e9..456ff3e1a 100644
--- a/apps/trading-e2e/src/integration/capsule.cy.ts
+++ b/apps/trading-e2e/src/integration/capsule.cy.ts
@@ -72,7 +72,11 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
cy.getByTestId('deposit-button').click();
connectEthereumWallet('Unknown');
cy.get(assetSelectField, txTimeout).select(btcName, { force: true });
- cy.getByTestId('deposit-approve-submit').click();
+ cy.getByTestId('approve-warning').should(
+ 'contain.text',
+ `Deposits of ${btcSymbol} not approved`
+ );
+ cy.getByTestId('deposit-submit').click();
cy.getByTestId('dialog-title').should('contain.text', 'Approve complete');
cy.get('[data-testid="Return to deposit"]').click();
cy.get(amountField).clear().type('10');
@@ -407,7 +411,7 @@ describe('capsule', { tags: '@slow' }, () => {
cy.getByTestId('deposit-button').click();
connectEthereumWallet('Unknown');
cy.get(assetSelectField, txTimeout).select(vegaName, { force: true });
- cy.getByTestId('deposit-approve-submit').click();
+ cy.getByTestId('deposit-submit').click();
cy.getByTestId('dialog-title').should('contain.text', 'Approve complete');
cy.get('[data-testid="Return to deposit"]').click();
cy.get(amountField).clear().type('10000');
diff --git a/apps/trading-e2e/src/integration/deposit.cy.ts b/apps/trading-e2e/src/integration/deposit.cy.ts
index eb20a6630..ec53bfe9f 100644
--- a/apps/trading-e2e/src/integration/deposit.cy.ts
+++ b/apps/trading-e2e/src/integration/deposit.cy.ts
@@ -1,3 +1,5 @@
+import { removeDecimal } from '@vegaprotocol/cypress';
+import { ethers } from 'ethers';
import { connectEthereumWallet } from '../support/ethereum-wallet';
import { selectAsset } from '../support/helpers';
@@ -9,7 +11,7 @@ const formFieldError = 'input-error-text';
const ASSET_EURO = 1;
describe('deposit form validation', { tags: '@smoke' }, () => {
- before(() => {
+ function openDepositForm() {
cy.mockWeb3Provider();
cy.mockSubscription();
cy.mockTradingPage();
@@ -20,10 +22,14 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
cy.getByTestId('deposit-button').click();
cy.wait('@Assets');
connectEthereumWallet('MetaMask');
- cy.getByTestId('deposit-submit').click();
+ }
+
+ before(() => {
+ openDepositForm();
});
it('handles empty fields', () => {
+ cy.getByTestId('deposit-submit').click();
cy.getByTestId(formFieldError).should('contain.text', 'Required');
cy.getByTestId(formFieldError).should('have.length', 2);
});
@@ -44,6 +50,13 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
});
it('invalid amount', () => {
+ mockWeb3DepositCalls({
+ allowance: '1000',
+ depositLifetimeLimit: '1000',
+ balance: '800',
+ deposited: '0',
+ dps: 5,
+ });
// Deposit amount smaller than minimum viable for selected asset
// Select an amount so that we have a known decimal places value to work with
selectAsset(ASSET_EURO);
@@ -56,12 +69,16 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
});
it('insufficient funds', () => {
- // 1001-DEPO-005
- // Deposit amount is valid, but less than approved. This will always be the case because our
- // CI wallet wont have approved any assets
+ mockWeb3DepositCalls({
+ allowance: '1000',
+ depositLifetimeLimit: '1000',
+ balance: '800',
+ deposited: '0',
+ dps: 5,
+ });
cy.get(amountField)
.clear()
- .type('100')
+ .type('850')
.next(`[data-testid="${formFieldError}"]`)
.should('have.text', 'Insufficient amount in Ethereum wallet');
});
@@ -88,3 +105,90 @@ describe('deposit actions', { tags: '@smoke' }, () => {
cy.getByTestId('deposit-submit').should('be.visible');
});
});
+
+function mockWeb3DepositCalls({
+ allowance,
+ depositLifetimeLimit,
+ balance,
+ deposited,
+ dps,
+}: {
+ allowance: string;
+ depositLifetimeLimit: string;
+ balance: string;
+ deposited: string;
+ dps: number;
+}) {
+ const assetContractAddress = '0x0158031158bb4df2ad02eaa31e8963e84ea978a4';
+ const collateralBridgeAddress = '0x7fe27d970bc8afc3b11cc8d9737bfb66b1efd799';
+ const toResult = (value: string, dps: number) => {
+ const rawValue = removeDecimal(value, dps);
+ return ethers.utils.hexZeroPad(
+ ethers.utils.hexlify(parseInt(rawValue)),
+ 32
+ );
+ };
+ cy.intercept('POST', 'http://localhost:8545', (req) => {
+ // Mock chainId call
+ if (req.body.method === 'eth_chainId') {
+ req.alias = 'eth_chainId';
+ req.reply({
+ id: req.body.id,
+ jsonrpc: req.body.jsonrpc,
+ result: '0xaa36a7', // 11155111 for sepolia chain id
+ });
+ }
+
+ // Mock deposited amount
+ if (req.body.method === 'eth_getStorageAt') {
+ req.alias = 'eth_getStorageAt';
+ req.reply({
+ id: req.body.id,
+ jsonrpc: req.body.jsonrpc,
+ result: toResult(deposited, dps),
+ });
+ }
+
+ if (req.body.method === 'eth_call') {
+ // Mock approved amount for asset on collateral bridge
+ if (
+ req.body.params[0].to === assetContractAddress &&
+ req.body.params[0].data ===
+ '0xdd62ed3e000000000000000000000000ee7d375bcb50c26d52e1a4a472d8822a2a22d94f0000000000000000000000007fe27d970bc8afc3b11cc8d9737bfb66b1efd799'
+ ) {
+ req.alias = 'eth_call_allowance';
+ req.reply({
+ id: req.body.id,
+ jsonrpc: req.body.jsonrpc,
+ result: toResult(allowance, dps),
+ });
+ }
+ // Mock balance of asset in Ethereum wallet
+ else if (
+ req.body.params[0].to === assetContractAddress &&
+ req.body.params[0].data ===
+ '0x70a08231000000000000000000000000ee7d375bcb50c26d52e1a4a472d8822a2a22d94f'
+ ) {
+ req.alias = 'eth_call_balanceOf';
+ req.reply({
+ id: req.body.id,
+ jsonrpc: req.body.jsonrpc,
+ result: toResult(balance, dps),
+ });
+ }
+ // Mock deposit lifetime limit
+ else if (
+ req.body.params[0].to === collateralBridgeAddress &&
+ req.body.params[0].data ===
+ '0x354a897a0000000000000000000000000158031158bb4df2ad02eaa31e8963e84ea978a4'
+ ) {
+ req.alias = 'eth_call_get_deposit_maximum'; // deposit lifetime limit
+ req.reply({
+ id: req.body.id,
+ jsonrpc: req.body.jsonrpc,
+ result: toResult(depositLifetimeLimit, dps),
+ });
+ }
+ }
+ });
+}
diff --git a/apps/trading-e2e/src/integration/wallets.cy.ts b/apps/trading-e2e/src/integration/wallets.cy.ts
index 1798a406d..ee02b8873 100644
--- a/apps/trading-e2e/src/integration/wallets.cy.ts
+++ b/apps/trading-e2e/src/integration/wallets.cy.ts
@@ -17,19 +17,50 @@ describe('connect hosted wallet', { tags: '@smoke' }, () => {
});
it('can connect', () => {
+ // Mock authentication
+ cy.intercept('POST', 'https://wallet.testnet.vega.xyz/api/v1/auth/token', {
+ body: {
+ token: 'test-token',
+ },
+ });
+ // Mock getting keys from wallet
+ cy.intercept('GET', 'https://wallet.testnet.vega.xyz/api/v1/keys', {
+ body: {
+ keys: [
+ {
+ algorithm: {
+ name: 'algo',
+ version: 1,
+ },
+ index: 0,
+ meta: [],
+ pub: 'HOSTED_PUBKEY',
+ tainted: false,
+ },
+ ],
+ },
+ });
cy.getByTestId(connectVegaBtn).click();
- mockConnectWallet();
cy.contains('Connect Vega wallet');
cy.contains('Hosted Fairground wallet');
cy.getByTestId('connectors-list')
- .find('[data-testid="connector-jsonRpc"]')
+ .find('[data-testid="connector-hosted"]')
.click();
- cy.wait('@walletReq');
+ cy.getByTestId(form).find('#wallet').click().type('user');
+ cy.getByTestId(form).find('#passphrase').click().type('pass');
+ cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
cy.getByTestId(manageVegaBtn).should('exist');
});
it('doesnt connect with invalid credentials', () => {
+ // Mock incorrect username/password
+ cy.intercept('POST', 'https://wallet.testnet.vega.xyz/api/v1/auth/token', {
+ body: {
+ error: 'No wallet',
+ },
+ statusCode: 403, // 403 forbidden invalid crednetials
+ });
cy.getByTestId(connectVegaBtn).click();
cy.getByTestId('connectors-list')
.find('[data-testid="connector-hosted"]')
@@ -37,10 +68,10 @@ describe('connect hosted wallet', { tags: '@smoke' }, () => {
cy.getByTestId(form).find('#wallet').click().type('invalid name');
cy.getByTestId(form).find('#passphrase').click().type('invalid password');
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
- cy.getByTestId('form-error').should('have.text', 'No wallet detected');
+ cy.getByTestId('form-error').should('have.text', 'Invalid credentials');
});
- it('doesnt connect with invalid fields', () => {
+ it('doesnt connect with empty fields', () => {
cy.getByTestId(connectVegaBtn).click();
cy.getByTestId('connectors-list')
.find('[data-testid="connector-hosted"]')
diff --git a/libs/deal-ticket/src/components/deal-ticket/deal-ticket.tsx b/libs/deal-ticket/src/components/deal-ticket/deal-ticket.tsx
index f8c3c6226..ac7848783 100644
--- a/libs/deal-ticket/src/components/deal-ticket/deal-ticket.tsx
+++ b/libs/deal-ticket/src/components/deal-ticket/deal-ticket.tsx
@@ -318,33 +318,37 @@ const SummaryMessage = memo(
}
if (!pubKey) {
return (
-
- You need a{' '}
-
- Vega wallet
- {' '}
- with {assetSymbol} to start trading in this market.
-
- }
- buttonProps={{
- text: t('Connect wallet'),
- action: openVegaWalletDialog,
- dataTestId: 'order-connect-wallet',
- size: 'md',
- }}
- />
+
+
+ You need a{' '}
+
+ Vega wallet
+ {' '}
+ with {assetSymbol} to start trading in this market.
+
+ }
+ buttonProps={{
+ text: t('Connect wallet'),
+ action: openVegaWalletDialog,
+ dataTestId: 'order-connect-wallet',
+ size: 'md',
+ }}
+ />
+
);
}
if (errorMessage === SummaryValidationType.NoCollateral) {
return (
-
+
+
+
);
}
@@ -363,7 +367,11 @@ const SummaryMessage = memo(
// If there is no blocking error but user doesn't have enough
// balance render the margin warning, but still allow submission
if (balanceError) {
- return ;
+ return (
+
+ ;
+
+ );
}
// Show auction mode warning
@@ -375,13 +383,15 @@ const SummaryMessage = memo(
].includes(marketData.marketTradingMode)
) {
return (
-
+
+
+
);
}
diff --git a/libs/deposits/src/lib/deposit-form.spec.tsx b/libs/deposits/src/lib/deposit-form.spec.tsx
index 40598feae..b0e918377 100644
--- a/libs/deposits/src/lib/deposit-form.spec.tsx
+++ b/libs/deposits/src/lib/deposit-form.spec.tsx
@@ -4,10 +4,12 @@ import type { DepositFormProps } from './deposit-form';
import { DepositForm } from './deposit-form';
import * as Schema from '@vegaprotocol/types';
import { useVegaWallet } from '@vegaprotocol/wallet';
+import { useWeb3ConnectStore } from '@vegaprotocol/web3';
import { useWeb3React } from '@web3-react/core';
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
jest.mock('@vegaprotocol/wallet');
+jest.mock('@vegaprotocol/web3');
jest.mock('@web3-react/core');
const mockConnector = { deactivate: jest.fn() };
@@ -37,6 +39,8 @@ function generateAsset(): AssetFieldsFragment {
let asset: AssetFieldsFragment;
let props: DepositFormProps;
const MOCK_ETH_ADDRESS = '0x72c22822A19D20DE7e426fB84aa047399Ddd8853';
+const MOCK_VEGA_KEY =
+ '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680';
beforeEach(() => {
asset = generateAsset();
@@ -89,14 +93,17 @@ describe('Deposit form', () => {
});
});
- it('fails when submitted with invalid ethereum address', async () => {
- (useWeb3React as jest.Mock).mockReturnValue({ account: '123' });
+ it('fails when Ethereum wallet not connected', async () => {
+ (useWeb3React as jest.Mock).mockReturnValue({
+ isActive: false,
+ account: '',
+ });
render( );
fireEvent.submit(screen.getByTestId('deposit-form'));
expect(
- await screen.findByText('Invalid Ethereum address')
+ await screen.findByText('Connect Ethereum wallet')
).toBeInTheDocument();
});
@@ -138,7 +145,7 @@ describe('Deposit form', () => {
fireEvent.submit(screen.getByTestId('deposit-form'));
expect(
- await screen.findByText('Insufficient amount in Ethereum wallet')
+ await screen.findByText('Amount is above deposit limit')
).toBeInTheDocument();
});
@@ -159,7 +166,7 @@ describe('Deposit form', () => {
fireEvent.submit(screen.getByTestId('deposit-form'));
expect(
- await screen.findByText('Amount is above approved amount')
+ await screen.findByText('Amount is above approved amount.')
).toBeInTheDocument();
});
@@ -193,9 +200,9 @@ describe('Deposit form', () => {
});
});
- it('handles deposit approvals', () => {
+ it('handles deposit approvals', async () => {
const mockUseVegaWallet = useVegaWallet as jest.Mock;
- mockUseVegaWallet.mockReturnValue({ pubKey: null });
+ mockUseVegaWallet.mockReturnValue({ pubKey: MOCK_VEGA_KEY });
const mockUseWeb3React = useWeb3React as jest.Mock;
mockUseWeb3React.mockReturnValue({
@@ -212,13 +219,18 @@ describe('Deposit form', () => {
/>
);
- fireEvent.click(
- screen.getByText(`Approve ${asset.symbol}`, {
- selector: '[type="button"]',
- })
+ expect(screen.queryByLabelText('Amount')).not.toBeInTheDocument();
+ expect(screen.getByTestId('approve-warning')).toHaveTextContent(
+ `Deposits of ${asset.symbol} not approved`
);
- expect(props.submitApprove).toHaveBeenCalled();
+ fireEvent.click(
+ screen.getByRole('button', { name: `Approve ${asset.symbol}` })
+ );
+
+ await waitFor(() => {
+ expect(props.submitApprove).toHaveBeenCalled();
+ });
});
it('handles submitting a deposit', async () => {
@@ -284,4 +296,55 @@ describe('Deposit form', () => {
render( );
expect(await screen.queryAllByTestId('view-asset-details')).toHaveLength(0);
});
+
+ it('renders a connect button if Ethereum wallet is not connected', () => {
+ (useWeb3React as jest.Mock).mockReturnValue({
+ isActive: false,
+ account: '',
+ });
+ render( );
+
+ expect(screen.getByRole('button', { name: 'Connect' })).toBeInTheDocument();
+ expect(
+ screen.queryByLabelText('From (Ethereum address)')
+ ).not.toBeInTheDocument();
+ });
+
+ it('renders a disabled input if Ethereum wallet is connected', () => {
+ (useWeb3React as jest.Mock).mockReturnValue({
+ isActive: true,
+ account: MOCK_ETH_ADDRESS,
+ });
+ render( );
+
+ expect(
+ screen.queryByRole('button', { name: 'Connect' })
+ ).not.toBeInTheDocument();
+ const fromInput = screen.getByLabelText('From (Ethereum address)');
+ expect(fromInput).toHaveValue(MOCK_ETH_ADDRESS);
+ expect(fromInput).toBeDisabled();
+ expect(fromInput).toHaveAttribute('readonly');
+ });
+
+ it('prevents submission if you are on the wrong chain', () => {
+ (useWeb3React as jest.Mock).mockReturnValue({
+ isActive: true,
+ account: MOCK_ETH_ADDRESS,
+ chainId: 1,
+ });
+ (useWeb3ConnectStore as unknown as jest.Mock).mockImplementation(
+ // eslint-disable-next-line
+ (selector: (result: ReturnType) => any) => {
+ return selector({
+ desiredChainId: 11155111,
+ open: jest.fn(),
+ foo: 'asdf',
+ });
+ }
+ );
+ render( );
+ expect(screen.getByTestId('chain-error')).toHaveTextContent(
+ /this app only works on/i
+ );
+ });
});
diff --git a/libs/deposits/src/lib/deposit-form.tsx b/libs/deposits/src/lib/deposit-form.tsx
index 6fc88a51d..2df087e12 100644
--- a/libs/deposits/src/lib/deposit-form.tsx
+++ b/libs/deposits/src/lib/deposit-form.tsx
@@ -1,8 +1,8 @@
import type { Asset } from '@vegaprotocol/assets';
import { AssetOption } from '@vegaprotocol/assets';
import {
- ethereumAddress,
t,
+ ethereumAddress,
required,
vegaPublicKey,
minSafe,
@@ -14,17 +14,19 @@ import {
import {
Button,
FormGroup,
- Icon,
Input,
InputError,
RichSelect,
+ Notification,
+ Intent,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useWeb3React } from '@web3-react/core';
import BigNumber from 'bignumber.js';
-import type { ButtonHTMLAttributes, ReactNode } from 'react';
+import type { ButtonHTMLAttributes } from 'react';
import { useMemo } from 'react';
-import { Controller, useForm, useWatch } from 'react-hook-form';
+import type { FieldError } from 'react-hook-form';
+import { Controller, useForm } from 'react-hook-form';
import { DepositLimits } from './deposit-limits';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import {
@@ -72,7 +74,8 @@ export const DepositForm = ({
isFaucetable,
}: DepositFormProps) => {
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
- const { account } = useWeb3React();
+ const openDialog = useWeb3ConnectStore((store) => store.open);
+ const { isActive, account } = useWeb3React();
const { pubKey } = useVegaWallet();
const {
register,
@@ -83,26 +86,27 @@ export const DepositForm = ({
formState: { errors },
} = useForm({
defaultValues: {
- from: account,
to: pubKey ? pubKey : undefined,
asset: selectedAsset?.id || '',
},
});
- const onDeposit = async (fields: FormFields) => {
+ const onSubmit = async (fields: FormFields) => {
if (!selectedAsset || selectedAsset.source.__typename !== 'ERC20') {
throw new Error('Invalid asset');
}
- submitDeposit({
- assetSource: selectedAsset.source.contractAddress,
- amount: fields.amount,
- vegaPublicKey: fields.to,
- });
+ if (approved) {
+ submitDeposit({
+ assetSource: selectedAsset.source.contractAddress,
+ amount: fields.amount,
+ vegaPublicKey: fields.to,
+ });
+ } else {
+ submitApprove();
+ }
};
- const amount = useWatch({ name: 'amount', control });
-
const maxAmount = useMemo(() => {
const maxApproved = allowance ? allowance : new BigNumber(0);
const maxAvailable = balance ? balance : new BigNumber(0);
@@ -133,9 +137,12 @@ export const DepositForm = ({
return minViableAmount;
}, [selectedAsset]);
+ const approved = allowance && allowance.isGreaterThan(0) ? true : false;
+ const formState = getFormState(selectedAsset, isActive, approved);
+
return (
);
};
+const AmountError = ({
+ error,
+ submitApprove,
+}: {
+ error: FieldError;
+ submitApprove: () => void;
+}) => {
+ if (error.type === 'approved') {
+ return (
+
+ {error.message}.
+
+ {t('Update approve amount')}
+
+
+ );
+ }
+ return (
+
+ {error.message}
+
+ );
+};
+
interface FormButtonProps {
selectedAsset?: Asset;
- amount: BigNumber;
- allowance: BigNumber | undefined;
- onApproveClick: () => void;
+ formState: ReturnType;
}
-const FormButton = ({
- selectedAsset,
- amount,
- allowance,
- onApproveClick,
-}: FormButtonProps) => {
- const { open, desiredChainId } = useWeb3ConnectStore((store) => ({
- open: store.open,
- desiredChainId: store.desiredChainId,
- }));
+const FormButton = ({ selectedAsset, formState }: FormButtonProps) => {
const { isActive, chainId } = useWeb3React();
- const approved =
- allowance && allowance.isGreaterThan(0) && amount.isLessThan(allowance);
- let button = null;
- let message: ReactNode = '';
-
- if (!isActive) {
- button = (
-
- {t('Connect Ethereum wallet')}
-
- );
- } else if (chainId !== desiredChainId) {
- const chainName = getChainName(desiredChainId);
- message = t(`This app only works on ${chainName}.`);
- button = (
-
- {t('Deposit')}
-
- );
- } else if (!selectedAsset) {
- button = (
-
- {t('Deposit')}
-
- );
- } else if (approved) {
- message = (
- <>
-
- {t('Approved')}
- >
- );
- button = (
-
- {t('Deposit')}
-
- );
- } else {
- message = t(`Deposits of ${selectedAsset.symbol} not approved`);
- button = (
-
- {t(`Approve ${selectedAsset.symbol}`)}
-
- );
- }
-
+ const desiredChainId = useWeb3ConnectStore((store) => store.desiredChainId);
+ const submitText =
+ formState === 'approve'
+ ? t(`Approve ${selectedAsset ? selectedAsset.symbol : ''}`)
+ : t('Deposit');
+ const invalidChain = isActive && chainId !== desiredChainId;
return (
-
- {message &&
{message}
}
- {button}
-
+ <>
+ {formState === 'approve' && (
+
+
+
+ )}
+ {invalidChain && (
+
+
+
+ )}
+
+ {submitText}
+
+ >
);
};
@@ -398,21 +428,20 @@ const UseButton = (props: UseButtonProps) => {
);
};
-const EthereumButton = ({ clearAddress }: { clearAddress: () => void }) => {
- const openDialog = useWeb3ConnectStore((state) => state.open);
- const { isActive, connector } = useWeb3React();
+const DisconnectEthereumButton = ({
+ onDisconnect,
+}: {
+ onDisconnect: () => void;
+}) => {
+ const { connector } = useWeb3React();
const [, , removeEagerConnector] = useLocalStorage(ETHEREUM_EAGER_CONNECT);
- if (!isActive) {
- return {t('Connect')} ;
- }
-
return (
{
connector.deactivate();
- clearAddress();
removeEagerConnector();
+ onDisconnect();
}}
data-testid="disconnect-ethereum-wallet"
>
@@ -420,3 +449,14 @@ const EthereumButton = ({ clearAddress }: { clearAddress: () => void }) => {
);
};
+
+const getFormState = (
+ selectedAsset: Asset | undefined,
+ isActive: boolean,
+ approved: boolean
+) => {
+ if (!selectedAsset) return 'deposit';
+ if (!isActive) return 'deposit';
+ if (approved) return 'deposit';
+ return 'approve';
+};
diff --git a/libs/deposits/src/lib/deposit-limits.tsx b/libs/deposits/src/lib/deposit-limits.tsx
index 2977a784c..cb2a3ea62 100644
--- a/libs/deposits/src/lib/deposit-limits.tsx
+++ b/libs/deposits/src/lib/deposit-limits.tsx
@@ -11,6 +11,7 @@ interface DepositLimitsProps {
deposited: BigNumber;
asset: Asset;
balance?: BigNumber;
+ allowance?: BigNumber;
}
export const DepositLimits = ({
@@ -18,6 +19,7 @@ export const DepositLimits = ({
deposited,
asset,
balance,
+ allowance,
}: DepositLimitsProps) => {
const limits = [
{
@@ -44,6 +46,12 @@ export const DepositLimits = ({
rawValue: max.minus(deposited),
value: compactNumber(max.minus(deposited), asset.decimals),
},
+ {
+ key: 'ALLOWANCE',
+ label: t('Approved'),
+ rawValue: allowance,
+ value: allowance ? compactNumber(allowance, asset.decimals) : '-',
+ },
];
return (
diff --git a/libs/governance/src/components/asset-proposal-notification.tsx b/libs/governance/src/components/asset-proposal-notification.tsx
index e1080dc5c..1ed187b21 100644
--- a/libs/governance/src/components/asset-proposal-notification.tsx
+++ b/libs/governance/src/components/asset-proposal-notification.tsx
@@ -27,12 +27,13 @@ export const AssetProposalNotification = ({
>
);
return (
-
+
+
+
);
}
diff --git a/libs/governance/src/components/market-proposal-notification.tsx b/libs/governance/src/components/market-proposal-notification.tsx
index 4a0ff39c0..f1ebb5b43 100644
--- a/libs/governance/src/components/market-proposal-notification.tsx
+++ b/libs/governance/src/components/market-proposal-notification.tsx
@@ -34,7 +34,6 @@ export const MarketProposalNotification = ({
intent={Intent.Warning}
message={message}
testId="market-proposal-notification"
- className="px-2 py-1"
/>
);
diff --git a/libs/ui-toolkit/src/components/notification/notification.tsx b/libs/ui-toolkit/src/components/notification/notification.tsx
index 5a6b0750c..07bf8353b 100644
--- a/libs/ui-toolkit/src/components/notification/notification.tsx
+++ b/libs/ui-toolkit/src/components/notification/notification.tsx
@@ -19,7 +19,6 @@ type NotificationProps = {
size?: ButtonSize;
};
testId?: string;
- className?: string;
};
const getIcon = (intent: Intent): IconName => {
@@ -39,7 +38,6 @@ export const Notification = ({
title,
testId,
buttonProps,
- className,
}: NotificationProps) => {
return (