From f4b5693bcbc1fb92e2b0355fac71770307d7d6c1 Mon Sep 17 00:00:00 2001 From: Yana Date: Fri, 10 Nov 2023 17:27:49 +0000 Subject: [PATCH] Add CosmWasmSigningClient WIP wip --- .../Delegations/components/DelegateModal.tsx | 109 +++++++++++------- explorer/src/components/TableToolbar.tsx | 62 +++++++++- 2 files changed, 127 insertions(+), 44 deletions(-) diff --git a/explorer/src/components/Delegations/components/DelegateModal.tsx b/explorer/src/components/Delegations/components/DelegateModal.tsx index 8a9e844017..d4069687b1 100644 --- a/explorer/src/components/Delegations/components/DelegateModal.tsx +++ b/explorer/src/components/Delegations/components/DelegateModal.tsx @@ -2,34 +2,28 @@ import React, { useCallback, useContext, useState, useEffect, ChangeEvent } from import { Box, Typography, SxProps, TextField } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; -import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation } from '@nymproject/types'; -import { Console } from '../utils/console'; -import { useGetFee } from '../hooks/useGetFee'; -import { debounce } from 'lodash'; +import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation, Coin } from '@nymproject/types'; + import { SimpleModal } from './SimpleModal'; import { ModalListItem } from './ModalListItem'; -import { TPoolOption, checkTokenBalance, validateAmount, validateKey } from '../utils'; +import { TPoolOption, validateAmount } from '../utils'; import { useChain } from '@cosmos-kit/react'; +import { StdFee } from '@cosmjs/amino'; +import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'; + import { uNYMtoNYM } from '../utils'; import { ErrorModal } from './ErrorModal'; -import { ConfirmTx } from './ConfirmTX'; -import { BalanceWarning } from './FeeWarning'; -import { getMixnodeStakeSaturation, simulateDelegateToMixnode, tryConvertIdentityToMixId } from '../requests'; const MIN_AMOUNT_TO_DELEGATE = 10; +const MIXNET_CONTRACT_ADDRESS = 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; +const sandboxContractAddress = 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav'; export const DelegateModal: FCWithChildren<{ open: boolean; onClose: () => void; - onOk?: ( - mixId: number, - identityKey: string, - amount: DecCoin, - tokenPool: TPoolOption, - fee?: FeeDetails, - ) => Promise; + onOk?: () => void; identityKey?: string; onIdentityKeyChanged?: (identityKey: string) => void; onAmountChanged?: (amount: string) => void; @@ -54,27 +48,21 @@ export const DelegateModal: FCWithChildren<{ header, buttonText, identityKey: initialIdentityKey, - rewardInterval, // accountBalance, - estimatedReward, denom, - profitMarginPercentage, - nodeUptimePercentage, - initialAmount, - hasVestingContract, sx, backdropProps, }) => { const [mixId, setMixId] = useState(); const [identityKey, setIdentityKey] = useState(initialIdentityKey); - const [amount, setAmount] = useState(initialAmount); + const [amount, setAmount] = useState(); const [isValidated, setValidated] = useState(false); const [errorAmount, setErrorAmount] = useState(); - // const [tokenPool, setTokenPool] = useState('balance'); const [errorIdentityKey, setErrorIdentityKey] = useState(); const [mixIdError, setMixIdError] = useState(); + const [cosmWasmSignerClient, setCosmWasmSignerClient] = useState(); - const { fee, getFee, resetFeeState, feeError } = useGetFee(); + // const { fee, getFee, resetFeeState, feeError } = useGetFee(); const { username, @@ -86,6 +74,7 @@ export const DelegateModal: FCWithChildren<{ getCosmWasmClient, isWalletConnected, getSigningCosmWasmClient, + estimateFee, } = useChain('nyx'); const [balance, setBalance] = useState<{ @@ -93,6 +82,19 @@ export const DelegateModal: FCWithChildren<{ data?: string; }>({ status: 'loading', data: undefined }); + useEffect(() => { + const getClient = async () => { + await getSigningCosmWasmClient() + .then((res) => { + setCosmWasmSignerClient(res); + console.log('res :>> ', res); + }) + .catch((e) => console.log('e :>> ', e)); + }; + + isWalletConnected && getClient(); + }, [isWalletConnected]); + useEffect(() => { const getBalance = async (walletAddress: string) => { const account = await getCosmWasmClient(); @@ -117,7 +119,7 @@ export const DelegateModal: FCWithChildren<{ errorIdentityKeyMessage = 'Please enter a valid identity key'; } - if (amount && !(await validateAmount(amount, '0'))) { + if (amount && !(await validateAmount(amount.amount, '0'))) { newValidatedValue = false; errorAmountMessage = 'Please enter a valid amount'; } @@ -127,7 +129,7 @@ export const DelegateModal: FCWithChildren<{ newValidatedValue = false; } - if (!amount?.length) { + if (!amount?.amount.length) { newValidatedValue = false; } @@ -148,22 +150,47 @@ export const DelegateModal: FCWithChildren<{ setValidated(newValidatedValue); }; - const handleOk = async () => { - if (onOk && amount && identityKey && mixId) { - onOk(mixId, identityKey, { amount, denom }, 'balance', fee); - } + const delegateToMixnode = async ( + { + mixId, + }: { + mixId: number; + }, + fee: number | StdFee | 'auto' = 'auto', + memo?: string, + funds?: DecCoin[], + ): Promise => { + console.log('cosmWasmSignerClient :>> ', cosmWasmSignerClient); + const amount = (Number(funds![0].amount) * 1000000).toString(); + const uNymFunds = [{ amount: amount, denom: 'unym' }]; + return await cosmWasmSignerClient.execute( + address, + MIXNET_CONTRACT_ADDRESS, + { + delegate_to_mixnode: { + mix_id: mixId, + }, + }, + fee, + memo, + uNymFunds, + ); }; - // const handleConfirm = async ({ mixId: id, value }: { mixId: number; value: DecCoin }) => { - // const SCWClient = await getSigningCosmWasmClient(); - - // console.log('SCWClient :>> ', SCWClient); - // }; - const handleConfirm = async () => { - const SCWClient = await getSigningCosmWasmClient(); + const memo: string = 'test delegation'; + const fee = { gas: '1000000', amount: [{ amount: '25000', denom: 'unym' }] }; - console.log('SCWClient :>> ', SCWClient); + if (mixId && amount && onOk && cosmWasmSignerClient) { + console.log('trying to delegate :>> '); + console.log('balance.data :>> ', balance.data); + onOk(); + console.log('amount :>> ', amount); + console.log('fee :>> ', fee); + await delegateToMixnode({ mixId }, fee, memo, [amount]) + .then((res) => console.log('res :>> ', res)) + .catch((err) => console.log('err :>> ', err)); + } }; const handleIdentityKeyChanged = (newIdentityKey: string) => { @@ -180,7 +207,7 @@ export const DelegateModal: FCWithChildren<{ }; const handleAmountChanged = (newAmount: DecCoin) => { - setAmount(newAmount.amount); + setAmount(newAmount); if (onAmountChanged) { onAmountChanged(newAmount.amount); @@ -236,7 +263,7 @@ export const DelegateModal: FCWithChildren<{ onOk={async () => handleConfirm()} header={header || 'Delegate'} okLabel={buttonText || 'Delegate stake'} - okDisabled={isValidated} + okDisabled={!isValidated} sx={sx} backdropProps={backdropProps} > @@ -278,7 +305,7 @@ export const DelegateModal: FCWithChildren<{ required fullWidth label="Amount" - initialValue={amount} + // initialValue={amount} autoFocus={Boolean(initialIdentityKey)} onChanged={handleAmountChanged} denom={denom} diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index f5aae9f38b..bdd179ac7c 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -7,6 +7,7 @@ import { DelegateModal } from './Delegations/components/DelegateModal'; import { ChainProvider } from '@cosmos-kit/react'; import { assets, chains } from 'chain-registry'; import { wallets as keplr } from '@cosmos-kit/keplr'; +import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation, Coin } from '@nymproject/types'; const fieldsHeight = '42.25px'; @@ -19,6 +20,17 @@ type TableToolBarProps = { childrenBefore?: React.ReactNode; childrenAfter?: React.ReactNode; }; +type ActionType = 'delegate' | 'undelegate' | 'redeem' | 'redeem-all' | 'compound'; + +type DelegationModalProps = { + status: 'loading' | 'success' | 'error'; + action: ActionType; + message?: string; + transactions?: { + url: string; + hash: string; + }[]; +}; export const TableToolbar: FCWithChildren = ({ searchTerm, @@ -30,11 +42,12 @@ export const TableToolbar: FCWithChildren = ({ withFilters, }) => { const [showNewDelegationModal, setShowNewDelegationModal] = useState(false); + const [confirmationModalProps, setConfirmationModalProps] = useState(); const assetsFixedUp = useMemo(() => { - const nyx = assets.find((a) => a.chain_name === 'nyx'); + const nyx = assets.find((a) => a.chain_name === 'sandbox'); if (nyx) { - const nyxCoin = nyx.assets.find((a) => a.name === 'nyx'); + const nyxCoin = nyx.assets.find((a) => a.name === 'sandbox'); if (nyxCoin) { nyxCoin.coingecko_id = 'nyx'; } @@ -53,11 +66,50 @@ export const TableToolbar: FCWithChildren = ({ blocks: 10000, }, }; + if (nyx.apis) nyx.apis.rpc = [{ address: 'https://rpc.nymtech.net', provider: 'nym' }]; } } return chains; }, [chains]); + const handleNewDelegation = () => { + // setConfirmationModalProps({ + // status: 'loading', + // action: 'delegate', + // }); + setShowNewDelegationModal(false); + // setCurrentDelegationListActionItem(undefined); + // try { + // const tx = await addDelegation( + // { + // mix_id, + // amount, + // }, + // tokenPool, + // fee, + // ); + + // const balances = await getAllBalances(); + + // setConfirmationModalProps({ + // status: 'success', + // action: 'delegate', + // message: 'This operation can take up to one hour to process', + // ...balances, + // transactions: [ + // { url: `${urls(network).blockExplorer}/transaction/${tx.transaction_hash}`, hash: tx.transaction_hash }, + // ], + // }); + // } catch (e) { + // Console.error('Failed to addDelegation', e); + // setConfirmationModalProps({ + // status: 'error', + // action: 'delegate', + // message: (e as Error).message, + // }); + // } + }; + const isMobile = useIsMobile(); return ( = ({ }} > @@ -147,6 +200,9 @@ export const TableToolbar: FCWithChildren = ({ header="Delegate" buttonText="Delegate stake" denom={'nym'} // clientDetails?.display_mix_denom || 'nym'} + onOk={handleNewDelegation} + // accountBalance={balance?.printable_balance} + {...confirmationModalProps} /> )}