+
diff --git a/apps/trading/pages/dialogs-container.tsx b/apps/trading/pages/dialogs-container.tsx
index c03576ac4..6f0bbeb77 100644
--- a/apps/trading/pages/dialogs-container.tsx
+++ b/apps/trading/pages/dialogs-container.tsx
@@ -8,6 +8,7 @@ import { CreateWithdrawalDialog } from '@vegaprotocol/withdraws';
import { DepositDialog } from '@vegaprotocol/deposits';
import { Web3ConnectUncontrolledDialog } from '@vegaprotocol/web3';
import { WelcomeDialog } from '../components/welcome-dialog';
+import { TransferDialog } from '@vegaprotocol/accounts';
const DialogsContainer = () => {
const { isOpen, id, trigger, setOpen } = useAssetDetailsDialogStore();
@@ -25,6 +26,7 @@ const DialogsContainer = () => {
+
>
);
};
diff --git a/libs/accounts/src/lib/index.ts b/libs/accounts/src/lib/index.ts
index d3b35a103..ce1402607 100644
--- a/libs/accounts/src/lib/index.ts
+++ b/libs/accounts/src/lib/index.ts
@@ -7,3 +7,4 @@ export * from './breakdown-table';
export * from './use-account-balance';
export * from './get-settlement-account';
export * from './use-market-account-balance';
+export * from './transfer-dialog';
diff --git a/libs/accounts/src/lib/transfer-container.tsx b/libs/accounts/src/lib/transfer-container.tsx
new file mode 100644
index 000000000..29c6535c0
--- /dev/null
+++ b/libs/accounts/src/lib/transfer-container.tsx
@@ -0,0 +1,45 @@
+import * as Schema from '@vegaprotocol/types';
+import {
+ addDecimal,
+ NetworkParams,
+ useDataProvider,
+ useNetworkParam,
+} from '@vegaprotocol/react-helpers';
+import { useVegaWallet } from '@vegaprotocol/wallet';
+import { useMemo } from 'react';
+import { accountsDataProvider } from './accounts-data-provider';
+import { TransferForm } from './transfer-form';
+
+export const TransferContainer = () => {
+ const { pubKey, pubKeys } = useVegaWallet();
+ const { param } = useNetworkParam(NetworkParams.transfer_fee_factor);
+ const { data } = useDataProvider({
+ dataProvider: accountsDataProvider,
+ variables: { partyId: pubKey },
+ skip: !pubKey,
+ });
+
+ const assets = useMemo(() => {
+ if (!data) return [];
+ return data
+ .filter(
+ (account) => account.type === Schema.AccountType.ACCOUNT_TYPE_GENERAL
+ )
+ .map((account) => ({
+ id: account.asset.id,
+ symbol: account.asset.symbol,
+ name: account.asset.name,
+ decimals: account.asset.decimals,
+ balance: addDecimal(account.balance, account.asset.decimals),
+ }));
+ }, [data]);
+
+ return (
+
pk.publicKey) : null}
+ assets={assets}
+ feeFactor={param}
+ />
+ );
+};
diff --git a/libs/accounts/src/lib/transfer-dialog.tsx b/libs/accounts/src/lib/transfer-dialog.tsx
new file mode 100644
index 000000000..998eaf253
--- /dev/null
+++ b/libs/accounts/src/lib/transfer-dialog.tsx
@@ -0,0 +1,28 @@
+import { t } from '@vegaprotocol/react-helpers';
+import { Dialog } from '@vegaprotocol/ui-toolkit';
+import { create } from 'zustand';
+import { TransferContainer } from './transfer-container';
+
+interface State {
+ isOpen: boolean;
+}
+
+interface Actions {
+ open: (open?: boolean) => void;
+}
+
+export const useTransferDialog = create((set) => ({
+ isOpen: false,
+ open: (open = true) => {
+ set(() => ({ isOpen: open }));
+ },
+}));
+
+export const TransferDialog = () => {
+ const { isOpen, open } = useTransferDialog();
+ return (
+
+ );
+};
diff --git a/libs/accounts/src/lib/transfer-form.tsx b/libs/accounts/src/lib/transfer-form.tsx
new file mode 100644
index 000000000..d8ac7492c
--- /dev/null
+++ b/libs/accounts/src/lib/transfer-form.tsx
@@ -0,0 +1,226 @@
+import {
+ t,
+ minSafe,
+ maxSafe,
+ required,
+ vegaPublicKey,
+ addDecimal,
+ formatNumber,
+} from '@vegaprotocol/react-helpers';
+import * as Schema from '@vegaprotocol/types';
+import {
+ Button,
+ FormGroup,
+ Input,
+ InputError,
+ Option,
+ RichSelect,
+ Select,
+} from '@vegaprotocol/ui-toolkit';
+import BigNumber from 'bignumber.js';
+import { useMemo, useState } from 'react';
+import { Controller, useForm } from 'react-hook-form';
+
+interface FormFields {
+ toAddress: string;
+ asset: string;
+ amount: string;
+}
+
+interface TransferFormProps {
+ pubKey: string | null;
+ pubKeys: string[] | null;
+ assets: Array<{
+ id: string;
+ symbol: string;
+ name: string;
+ decimals: number;
+ balance: string;
+ }>;
+ feeFactor: string | null;
+}
+
+export const TransferForm = ({
+ pubKey,
+ pubKeys,
+ assets,
+ feeFactor,
+}: TransferFormProps) => {
+ const [manualAddressEntry, setManualAddressEntry] = useState(false);
+ const {
+ control,
+ register,
+ watch,
+ handleSubmit,
+ setValue,
+ formState: { errors },
+ } = useForm();
+
+ const onSubmit = (fields: FormFields) => {
+ console.log(fields);
+ };
+
+ const amount = watch('amount');
+ const assetId = watch('asset');
+
+ const asset = useMemo(() => {
+ return assets.find((a) => a.id === assetId);
+ }, [assets, assetId]);
+
+ const min = useMemo(() => {
+ // Min viable amount given asset decimals EG for WEI 0.000000000000000001
+ const minViableAmount = asset
+ ? new BigNumber(addDecimal('1', asset.decimals))
+ : new BigNumber(0);
+
+ return minViableAmount;
+ }, [asset]);
+
+ const max = useMemo(() => {
+ const maxAmount = asset ? new BigNumber(asset.balance) : new BigNumber(0);
+
+ return maxAmount;
+ }, [asset]);
+
+ console.log(asset, max.toString());
+
+ return (
+
+ );
+};
+
+const TransferFee = ({
+ amount,
+ feeFactor,
+}: {
+ amount: string;
+ feeFactor: string | null;
+}) => {
+ if (!feeFactor || !amount) return null;
+ const value = new BigNumber(amount).times(feeFactor).toString();
+
+ return Transfer fee: {value.toString()}
;
+};
diff --git a/libs/react-helpers/src/hooks/use-network-params.ts b/libs/react-helpers/src/hooks/use-network-params.ts
index 8f8081ae0..aae942a29 100644
--- a/libs/react-helpers/src/hooks/use-network-params.ts
+++ b/libs/react-helpers/src/hooks/use-network-params.ts
@@ -104,6 +104,7 @@ export const NetworkParams = {
market_liquidity_stakeToCcyVolume: 'market_liquidity_stakeToCcyVolume',
market_liquidity_targetstake_triggering_ratio:
'market_liquidity_targetstake_triggering_ratio',
+ transfer_fee_factor: 'transfer.fee.factor',
} as const;
type Params = typeof NetworkParams;