diff --git a/src/config/config.devnet.ts b/src/config/config.devnet.ts index 16843fb..f5444bc 100644 --- a/src/config/config.devnet.ts +++ b/src/config/config.devnet.ts @@ -3,7 +3,7 @@ import { EnvironmentsEnum } from 'types'; export * from './sharedConfig'; export const contractAddress = - 'erd1qqqqqqqqqqqqqpgqm6ad6xrsjvxlcdcffqe8w58trpec09ug9l5qde96pq'; + 'erd1qqqqqqqqqqqqqpgqx3p5prqkyx0cek8zapn84ejkn46j9szlk3sqpx66pm'; export const API_URL = 'https://devnet-template-api.multiversx.com'; export const sampleAuthenticatedDomains = [API_URL]; export const environment = EnvironmentsEnum.devnet; diff --git a/src/contracts/escrow.abi.json b/src/contracts/escrow.abi.json new file mode 100644 index 0000000..ae6034d --- /dev/null +++ b/src/contracts/escrow.abi.json @@ -0,0 +1,59 @@ +{ + "buildInfo": { + "rustc": { + "version": "1.80.0-nightly", + "commitHash": "debd22da66cfa97c74040ebf68e420672ac8560e", + "commitDate": "2024-05-29", + "channel": "Nightly", + "short": "rustc 1.80.0-nightly (debd22da6 2024-05-29)" + }, + "contractCrate": { + "name": "escrow", + "version": "0.0.0" + }, + "framework": { + "name": "multiversx-sc", + "version": "0.47.4" + } + }, + "name": "Escrow", + "constructor": { + "inputs": [], + "outputs": [] + }, + "endpoints": [ + { + "name": "deposit", + "mutability": "mutable", + "payableInTokens": [ + "EGLD" + ], + "inputs": [], + "outputs": [] + }, + { + "name": "withdraw", + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, + { + "name": "getUserBalance", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "BigUint" + } + ] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": {} +} \ No newline at end of file diff --git a/src/hooks/transactions/index.ts b/src/hooks/transactions/index.ts index 8ca4e78..37d1b56 100644 --- a/src/hooks/transactions/index.ts +++ b/src/hooks/transactions/index.ts @@ -1 +1,3 @@ -export * from './useSendPingPongTransaction'; +export * from './useGetBalance'; +export * from './useSendDeposit'; +export * from './useSendWithdraw'; diff --git a/src/hooks/transactions/useGetBalance.ts b/src/hooks/transactions/useGetBalance.ts new file mode 100644 index 0000000..2a1c353 --- /dev/null +++ b/src/hooks/transactions/useGetBalance.ts @@ -0,0 +1,5 @@ +export const useGetBalance = () => { + return async () => { + console.log('useGetBalance'); + }; +}; diff --git a/src/hooks/transactions/useSendDeposit.ts b/src/hooks/transactions/useSendDeposit.ts new file mode 100644 index 0000000..f219867 --- /dev/null +++ b/src/hooks/transactions/useSendDeposit.ts @@ -0,0 +1,33 @@ +import { Address } from '@multiversx/sdk-core'; +import { smartContract } from 'utils/smartContract'; +import { getChainId } from 'utils/getChainId'; +import { refreshAccount, sendTransactions } from 'helpers/sdkDappHelpers'; +import { RouteNamesEnum } from 'localConstants'; +import { useGetAccount } from 'hooks/sdkDappHooks'; + +export const useSendDeposit = () => { + const { address } = useGetAccount(); + + return async (amount: string) => { + const depositTransaction = smartContract.methodsExplicit + .deposit() + .withValue(amount) + .withGasLimit(60000000) + .withSender(new Address(address)) + .withChainID(getChainId()) + .buildTransaction(); + + await refreshAccount(); + + await sendTransactions({ + transactions: [depositTransaction], + transactionsDisplayInfo: { + processingMessage: 'Processing Deposit transaction', + errorMessage: 'An error has occured during Ping', + successMessage: 'Deposit successful' + }, + redirectAfterSign: false, + callbackRoute: RouteNamesEnum.dashboard + }); + }; +}; diff --git a/src/hooks/transactions/useSendPingPongTransaction.ts b/src/hooks/transactions/useSendPingPongTransaction.ts deleted file mode 100644 index e3615d2..0000000 --- a/src/hooks/transactions/useSendPingPongTransaction.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { useState, useCallback } from 'react'; -import { - deleteTransactionToast, - removeAllSignedTransactions, - removeAllTransactionsToSign -} from '@multiversx/sdk-dapp/services/transactions/clearTransactions'; -import { contractAddress } from 'config'; -import { signAndSendTransactions } from 'helpers/signAndSendTransactions'; -import { - useGetAccountInfo, - useGetNetworkConfig, - useTrackTransactionStatus -} from 'hooks/sdkDappHooks'; -import { GAS_PRICE, SessionEnum, VERSION } from 'localConstants'; -import { getChainId } from 'utils/getChainId'; -import { smartContract } from 'utils/smartContract'; -import { - PingRawProps, - PingPongServiceProps, - PongRawProps -} from 'types/pingPong.types'; -import { newTransaction } from 'helpers/sdkDappHelpers'; -import { Address } from 'utils/sdkDappCore'; - -type PingPongTransactionProps = { - type: SessionEnum; -}; - -const PING_TRANSACTION_INFO = { - processingMessage: 'Processing Ping transaction', - errorMessage: 'An error has occured during Ping', - successMessage: 'Ping transaction successful' -}; - -const PONG_TRANSACTION_INFO = { - processingMessage: 'Processing Pong transaction', - errorMessage: 'An error has occured during Pong', - successMessage: 'Pong transaction successful' -}; - -export const useSendPingPongTransaction = ({ - type -}: PingPongTransactionProps) => { - // Needed in order to differentiate widgets between each other - // By default sdk-dapp takes the last sessionId available which will display on every widget the same transaction - // this usually appears on page refreshes - const [pingPongSessionId, setPingPongSessionId] = useState( - sessionStorage.getItem(type) - ); - - const network = useGetNetworkConfig(); - const { address, account } = useGetAccountInfo(); - - const transactionStatus = useTrackTransactionStatus({ - transactionId: pingPongSessionId ?? '0' - }); - - const clearAllTransactions = () => { - removeAllSignedTransactions(); - removeAllTransactionsToSign(); - deleteTransactionToast(pingPongSessionId ?? ''); - }; - - const sendPingTransaction = useCallback( - async ({ amount, callbackRoute }: PingRawProps) => { - clearAllTransactions(); - - const pingTransaction = newTransaction({ - value: amount, - data: 'ping', - receiver: contractAddress, - gasLimit: 60000000, - gasPrice: GAS_PRICE, - chainID: network.chainID, - nonce: account.nonce, - sender: address, - version: VERSION - }); - - const sessionId = await signAndSendTransactions({ - transactions: [pingTransaction], - callbackRoute, - transactionsDisplayInfo: PING_TRANSACTION_INFO - }); - - sessionStorage.setItem(type, sessionId); - setPingPongSessionId(sessionId); - }, - [] - ); - - const sendPingTransactionFromAbi = useCallback( - async ({ amount, callbackRoute }: PingRawProps) => { - clearAllTransactions(); - - const pingTransaction = smartContract.methodsExplicit - .ping() - .withSender(new Address(address)) - .withValue(amount ?? '0') - .withGasLimit(60000000) - .withChainID(getChainId()) - .buildTransaction(); - - const sessionId = await signAndSendTransactions({ - transactions: [pingTransaction], - callbackRoute, - transactionsDisplayInfo: PING_TRANSACTION_INFO - }); - - sessionStorage.setItem(type, sessionId); - setPingPongSessionId(sessionId); - }, - [] - ); - - const sendPingTransactionFromService = useCallback( - async ({ transactions, callbackRoute }: PingPongServiceProps) => { - clearAllTransactions(); - - const sessionId = await signAndSendTransactions({ - transactions, - callbackRoute, - transactionsDisplayInfo: PING_TRANSACTION_INFO - }); - - sessionStorage.setItem(type, sessionId); - setPingPongSessionId(sessionId); - }, - [] - ); - - const sendPongTransaction = useCallback( - async ({ callbackRoute }: PongRawProps) => { - clearAllTransactions(); - - const pongTransaction = newTransaction({ - value: '0', - data: 'pong', - receiver: contractAddress, - gasLimit: 60000000, - gasPrice: GAS_PRICE, - chainID: network.chainID, - nonce: account.nonce, - sender: address, - version: VERSION - }); - - const sessionId = await signAndSendTransactions({ - transactions: [pongTransaction], - callbackRoute, - transactionsDisplayInfo: PONG_TRANSACTION_INFO - }); - - sessionStorage.setItem(type, sessionId); - setPingPongSessionId(sessionId); - }, - [] - ); - - const sendPongTransactionFromAbi = useCallback( - async ({ callbackRoute }: PongRawProps) => { - clearAllTransactions(); - - const pongTransaction = smartContract.methodsExplicit - .pong() - .withSender(new Address(address)) - .withValue('0') - .withGasLimit(60000000) - .withChainID(getChainId()) - .buildTransaction(); - - const sessionId = await signAndSendTransactions({ - transactions: [pongTransaction], - callbackRoute, - transactionsDisplayInfo: PONG_TRANSACTION_INFO - }); - - sessionStorage.setItem(type, sessionId); - setPingPongSessionId(sessionId); - }, - [] - ); - - const sendPongTransactionFromService = useCallback( - async ({ transactions, callbackRoute }: PingPongServiceProps) => { - clearAllTransactions(); - - const sessionId = await signAndSendTransactions({ - transactions, - callbackRoute, - transactionsDisplayInfo: PONG_TRANSACTION_INFO - }); - - sessionStorage.setItem(type, sessionId); - setPingPongSessionId(sessionId); - }, - [] - ); - - return { - sendPingTransaction, - sendPingTransactionFromAbi, - sendPongTransaction, - sendPongTransactionFromAbi, - sendPingTransactionFromService, - sendPongTransactionFromService, - transactionStatus - }; -}; diff --git a/src/hooks/transactions/useSendWithdraw.ts b/src/hooks/transactions/useSendWithdraw.ts new file mode 100644 index 0000000..2cfa3cb --- /dev/null +++ b/src/hooks/transactions/useSendWithdraw.ts @@ -0,0 +1,5 @@ +export const useSendWithdraw = () => { + return async () => { + console.log('useSendWithdraw'); + }; +}; diff --git a/src/pages/Dashboard/Dashboard.tsx b/src/pages/Dashboard/Dashboard.tsx index 8a3f90a..0b235fe 100644 --- a/src/pages/Dashboard/Dashboard.tsx +++ b/src/pages/Dashboard/Dashboard.tsx @@ -1,15 +1,6 @@ import { contractAddress } from 'config'; import { AuthRedirectWrapper } from 'wrappers'; -import { - Account, - PingPongAbi, - SignMessage, - NativeAuth, - BatchTransactions, - PingPongRaw, - PingPongService, - Transactions -} from './widgets'; +import { Account, EscrowAbi, Transactions } from './widgets'; import { useScrollToElement } from 'hooks'; import { Widget } from './components'; import { WidgetType } from 'types/widget.types'; @@ -22,54 +13,14 @@ const WIDGETS: WidgetType[] = [ reference: 'https://docs.multiversx.com/sdk-and-tools/sdk-dapp/#account' }, { - title: 'Ping & Pong (Manual)', - widget: PingPongRaw, - description: - 'Smart Contract interactions using manually formulated transactions', - reference: - 'https://docs.multiversx.com/sdk-and-tools/indices/es-index-transactions/', - anchor: 'ping-pong-manual' - }, - { - title: 'Ping & Pong (ABI)', - widget: PingPongAbi, + title: 'Escrow (ABI)', + widget: EscrowAbi, description: 'Smart Contract interactions using the ABI generated transactions', reference: 'https://docs.multiversx.com/sdk-and-tools/sdk-js/sdk-js-cookbook/#using-interaction-when-the-abi-is-available', anchor: 'ping-pong-abi' }, - { - title: 'Ping & Pong (Backend)', - widget: PingPongService, - description: - 'Smart Contract interactions using the backend generated transactions', - reference: 'https://github.com/multiversx/mx-ping-pong-service', - anchor: 'ping-pong-backend' - }, - { - title: 'Sign message', - widget: SignMessage, - description: 'Message signing using the connected account', - reference: 'https://docs.multiversx.com/sdk-and-tools/sdk-dapp/#account-1', - anchor: 'sign-message' - }, - { - title: 'Native auth', - widget: NativeAuth, - description: - 'A secure authentication token can be used to interact with the backend', - reference: 'https://github.com/multiversx/mx-sdk-js-native-auth-server' - }, - { - title: 'Batch Transactions', - widget: BatchTransactions, - description: - 'For complex scenarios transactions can be sent in the desired group/sequence', - reference: - 'https://github.com/multiversx/mx-sdk-dapp#sending-transactions-synchronously-in-batches', - anchor: 'batch-transactions' - }, { title: 'Transactions (All)', widget: Transactions, diff --git a/src/pages/Dashboard/widgets/BatchTransactions/BatchTransactions.tsx b/src/pages/Dashboard/widgets/BatchTransactions/BatchTransactions.tsx deleted file mode 100644 index d1b9dfd..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/BatchTransactions.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import { useEffect, useState } from 'react'; -import { - faPaperPlane, - faArrowsRotate -} from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { useGetBatches } from '@multiversx/sdk-dapp/hooks/transactions/batch/useGetBatches'; -import { Button } from 'components/Button'; -import { - OutputContainer, - TransactionsOutput -} from 'components/OutputContainer'; -import { - useGetAccountInfo, - useGetNetworkConfig, - useGetPendingTransactions -} from 'hooks'; -import { SessionEnum } from 'localConstants/session'; -import { SignedTransactionType, WidgetProps } from 'types'; -import { useBatchTransactionContext } from 'wrappers'; -import { useSendSignedTransactions } from './hooks'; -import { - sendBatchTransactions, - signAndAutoSendBatchTransactions, - swapAndLockTokens -} from './helpers'; - -export const BatchTransactions = ({ callbackRoute }: WidgetProps) => { - const { setSendBatchTransactionsOnDemand } = useBatchTransactionContext(); - const { address, account } = useGetAccountInfo(); - const network = useGetNetworkConfig(); - const { batches } = useGetBatches(); - const { hasPendingTransactions } = useGetPendingTransactions(); - const [trackBatchId, setTrackBatchId] = useState( - sessionStorage.getItem(SessionEnum.batchId) - ); - - const [stateTransactions, setStateTransactions] = useState< - SignedTransactionType[] | null - >(null); - const [currentSessionId, setCurrentSessionId] = useState( - sessionStorage.getItem(SessionEnum.signedSessionId) - ); - - const { batchId, setBatchSessionId } = useSendSignedTransactions({ - signedSessionId: currentSessionId - }); - - // If manual batch transactions are executed, track the batchId - useEffect(() => { - if (batchId) { - setTrackBatchId(batchId); - } - }, [batchId]); - - useEffect(() => { - if (trackBatchId && batches[trackBatchId]) { - setStateTransactions(batches[trackBatchId].transactions.flat()); - } - }, [trackBatchId, batches]); - - const executeSignAndAutoSendBatchTransactions = async () => { - setSendBatchTransactionsOnDemand(false); - - const { batchId } = await signAndAutoSendBatchTransactions({ - address, - nonce: account.nonce, - chainID: network.chainID, - callbackRoute - }); - - if (!batchId) { - return; - } - - setTrackBatchId(batchId); - }; - - const executeBatchTransactions = async () => { - setSendBatchTransactionsOnDemand(true); - const { newBatchSessionId, sessionId } = await sendBatchTransactions({ - address, - nonce: account.nonce, - chainID: network.chainID, - callbackRoute - }); - - if (!newBatchSessionId || !sessionId) { - return; - } - - setBatchSessionId(newBatchSessionId); - setCurrentSessionId(sessionId); - }; - - const executeSwapAndLockTokens = async () => { - setSendBatchTransactionsOnDemand(true); - const { batchId: currentBatchId } = await swapAndLockTokens({ - address, - nonce: account.nonce, - chainID: network.chainID, - callbackRoute - }); - - if (!currentBatchId) { - return; - } - - setTrackBatchId(currentBatchId); - }; - - return ( -
-
- - - - -
- - - {stateTransactions && ( - - )} - -
- ); -}; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/helpers/getBatchTransactions.ts b/src/pages/Dashboard/widgets/BatchTransactions/helpers/getBatchTransactions.ts deleted file mode 100644 index 1bab02f..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/getBatchTransactions.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { newTransaction } from 'helpers/sdkDappHelpers'; -import { - DECIMALS, - EXTRA_GAS_LIMIT_GUARDED_TX, - GAS_LIMIT, - GAS_PRICE, - VERSION -} from 'localConstants/sdkDapConstants'; -import { TransactionProps } from 'types/transaction.types'; -import { Transaction } from 'types/sdkCoreTypes'; -import { TokenTransfer } from 'utils/sdkDappCore'; - -const NUMBER_OF_TRANSACTIONS = 5; - -export const getBatchTransactions = ({ - address, - nonce, - chainID -}: TransactionProps): Transaction[] => { - const transactions = Array.from(Array(NUMBER_OF_TRANSACTIONS).keys()); - - return transactions.map((id) => { - const amount = TokenTransfer.fungibleFromAmount( - '', - id + 1, - DECIMALS - ).toString(); - - return newTransaction({ - sender: address, - receiver: address, - data: `batch-tx-${id + 1}`, - value: amount, - chainID, - gasLimit: GAS_LIMIT + EXTRA_GAS_LIMIT_GUARDED_TX, - gasPrice: GAS_PRICE, - nonce, - version: VERSION - }); - }); -}; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/helpers/getSwapAndLockTransactions.ts b/src/pages/Dashboard/widgets/BatchTransactions/helpers/getSwapAndLockTransactions.ts deleted file mode 100644 index de77ec5..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/getSwapAndLockTransactions.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { GAS_PRICE, VERSION } from 'localConstants/sdkDapConstants'; -import { newTransaction } from 'helpers/sdkDappHelpers'; -import { TransactionProps } from 'types/transaction.types'; -import { Transaction } from 'types/sdkCoreTypes'; -import { BATCH_TRANSACTIONS_SC } from 'config'; - -export const getSwapAndLockTransactions = ({ - address, - chainID, - nonce -}: TransactionProps): Transaction[] => { - return [ - newTransaction({ - chainID, - gasLimit: 4200000, - gasPrice: GAS_PRICE, - nonce, - receiver: BATCH_TRANSACTIONS_SC.egld_wEGLD.contract, - sender: address, - value: '1000000000000000000', - version: VERSION, - data: BATCH_TRANSACTIONS_SC.egld_wEGLD.data - }), - newTransaction({ - chainID, - gasLimit: 25500000, - gasPrice: GAS_PRICE, - nonce, - receiver: BATCH_TRANSACTIONS_SC.wEGLD_USDC.contract, - sender: address, - value: '0', - version: VERSION, - data: BATCH_TRANSACTIONS_SC.wEGLD_USDC.data - }), - newTransaction({ - chainID, - gasLimit: 25500000, - gasPrice: GAS_PRICE, - nonce, - receiver: BATCH_TRANSACTIONS_SC.wEGLD_MEX.contract, - sender: address, - value: '0', - version: VERSION, - data: BATCH_TRANSACTIONS_SC.wEGLD_MEX.data - }), - newTransaction({ - chainID, - gasLimit: 10000000, - gasPrice: GAS_PRICE, - nonce, - receiver: BATCH_TRANSACTIONS_SC.lock_MEX.contract, - sender: address, - value: '0', - version: VERSION, - data: BATCH_TRANSACTIONS_SC.lock_MEX.data - }) - ]; -}; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/helpers/index.ts b/src/pages/Dashboard/widgets/BatchTransactions/helpers/index.ts deleted file mode 100644 index 815798d..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './getBatchTransactions'; -export * from './getSwapAndLockTransactions'; -export * from './sendBatchTransactions'; -export * from './signAndAutoSendBatchTransactions'; -export * from './swapAndLockTokens'; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/helpers/sendBatchTransactions.ts b/src/pages/Dashboard/widgets/BatchTransactions/helpers/sendBatchTransactions.ts deleted file mode 100644 index 491b319..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/sendBatchTransactions.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { getBatchTransactions } from '../helpers'; -import { sendTransactions } from 'helpers/sdkDappHelpers'; -import { SessionEnum } from 'localConstants/session'; -import { SendTransactionProps } from '../types'; - -export const sendBatchTransactions = async ({ - address, - chainID, - nonce, - callbackRoute -}: SendTransactionProps) => { - const transactions = getBatchTransactions({ - address, - chainID, - nonce - }); - - const { sessionId, error } = await sendTransactions({ - transactions, - signWithoutSending: true, - customTransactionInformation: { redirectAfterSign: true }, - callbackRoute - }); - - if (error) { - console.error('Could not execute transactions', error); - return {}; - } - - const newBatchSessionId = Date.now().toString(); - // sdk-dapp by default takes the last session id from sdk-dapp’s redux store on page refresh - // in order to differentiate the transactions between widgets, a persistence of sessionId is needed - sessionStorage.setItem(SessionEnum.batchSessionId, newBatchSessionId); - sessionStorage.setItem(SessionEnum.signedSessionId, sessionId); - - return { newBatchSessionId, sessionId }; -}; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/helpers/signAndAutoSendBatchTransactions.ts b/src/pages/Dashboard/widgets/BatchTransactions/helpers/signAndAutoSendBatchTransactions.ts deleted file mode 100644 index 423eb9e..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/signAndAutoSendBatchTransactions.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { SessionEnum } from 'localConstants/session'; -import { getBatchTransactions } from '../helpers'; -import { refreshAccount } from 'utils/sdkDappUtils'; -import { sendBatchTransactions } from 'services/sdkDappServices'; -import { SendTransactionProps } from '../types'; - -// this process will not go through useSendSignedTransactions -// it will automatically sign and send transactions -export const signAndAutoSendBatchTransactions = async ({ - address, - nonce, - chainID, - callbackRoute -}: SendTransactionProps) => { - const transactions = getBatchTransactions({ - address, - nonce, - chainID - }); - - const groupedTransactions = [ - [transactions[0]], - [transactions[1], transactions[2]], - [transactions[3], transactions[4]] - ]; - - await refreshAccount(); - - const { batchId, error } = await sendBatchTransactions({ - transactions: groupedTransactions, - customTransactionInformation: { redirectAfterSign: true }, - transactionsDisplayInfo: { - processingMessage: 'Processing transactions', - errorMessage: 'An error has occurred during transaction execution', - successMessage: 'Batch transactions successful' - }, - callbackRoute - }); - if (error) { - console.error('Could not execute transactions', error); - return {}; - } - - sessionStorage.setItem(SessionEnum.batchId, batchId); - - return { batchId }; -}; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/helpers/swapAndLockTokens.ts b/src/pages/Dashboard/widgets/BatchTransactions/helpers/swapAndLockTokens.ts deleted file mode 100644 index 98e7ebe..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/swapAndLockTokens.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { SessionEnum } from 'localConstants/session'; -import { getSwapAndLockTransactions } from '../helpers'; -import { sendBatchTransactions } from 'services/sdkDappServices'; -import { refreshAccount } from 'utils/sdkDappUtils'; -import { SendTransactionProps } from '../types'; - -export const swapAndLockTokens = async ({ - address, - nonce, - chainID, - callbackRoute -}: SendTransactionProps) => { - const transactions = getSwapAndLockTransactions({ - address, - chainID, - nonce - }); - - const groupedTransactions = [ - [transactions[0]], - [transactions[1], transactions[2]], - [transactions[3]] - ]; - - await refreshAccount(); - - const { batchId, error } = await sendBatchTransactions({ - transactions: groupedTransactions, - customTransactionInformation: { redirectAfterSign: true }, - transactionsDisplayInfo: { - processingMessage: 'Processing transactions', - errorMessage: 'An error has occurred during transaction execution', - successMessage: 'Batch transactions successful' - }, - callbackRoute - }); - - if (error) { - console.error('Could not execute transactions', error); - return {}; - } - - sessionStorage.setItem(SessionEnum.batchId, batchId); - - return { batchId }; -}; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/hooks/index.ts b/src/pages/Dashboard/widgets/BatchTransactions/hooks/index.ts deleted file mode 100644 index e60e6be..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/hooks/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useSendSignedTransactions'; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/hooks/useSendSignedTransactions.ts b/src/pages/Dashboard/widgets/BatchTransactions/hooks/useSendSignedTransactions.ts deleted file mode 100644 index 03d4b14..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/hooks/useSendSignedTransactions.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { useEffect, useState } from 'react'; - -import { TransactionBatchStatusesEnum } from '@multiversx/sdk-dapp/types/enums.types'; -import { - useSendBatchTransactions, - useGetSignedTransactions -} from 'hooks/sdkDappHooks'; -import { SessionEnum } from 'localConstants'; -import { - deleteTransactionToast, - removeAllSignedTransactions, - removeAllTransactionsToSign, - setTransactionsDisplayInfoState, - setTransactionsToSignedState -} from 'services/sdkDappServices'; -import { useBatchTransactionContext } from 'wrappers'; - -export const useSendSignedTransactions = ({ - signedSessionId = null -}: { - signedSessionId: string | null; -}) => { - const [batchSessionId, setBatchSessionId] = useState( - sessionStorage.getItem(SessionEnum.batchSessionId) - ); - const { signedTransactions } = useGetSignedTransactions(); - const { send: sendBatchToBlockchain, batchId } = useSendBatchTransactions(); - const { sendBatchTransactionsOnDemand } = useBatchTransactionContext(); - - const clearTransactionsInformation = () => { - removeAllSignedTransactions(); - removeAllTransactionsToSign(); - deleteTransactionToast(batchSessionId ?? ''); - sessionStorage.removeItem(SessionEnum.batchSessionId); - setBatchSessionId(null); - }; - - const sendTransactions = async () => { - if (!batchSessionId || !signedSessionId) { - return; - } - - const signedSession = signedTransactions?.[signedSessionId]; - const signedSessionTransactions = signedSession?.transactions; - - if (!signedSession || signedSessionTransactions?.length === 0) { - return; - } - - // Cancel flow - if (signedSession?.status !== TransactionBatchStatusesEnum.signed) { - clearTransactionsInformation(); - return; - } - - setTransactionsToSignedState({ - sessionId: batchSessionId, - status: TransactionBatchStatusesEnum.signed, - transactions: signedSessionTransactions - }); - - // In order to reuse the current flow for batch transactions in sdk-dapp we need to use this function - // in order to set the toast display info because the last signed sessionId is not used anymore - // but the new sessionId from the batchId is used - setTransactionsDisplayInfoState({ - sessionId: batchSessionId, - transactionsDisplayInfo: { - processingMessage: 'Processing transactions', - errorMessage: 'An error has occurred during transaction execution', - successMessage: 'Batch transactions successful' - } - }); - - const { error } = await sendBatchToBlockchain({ - transactions: [signedSessionTransactions], - sessionId: batchSessionId - }); - - setBatchSessionId(null); - sessionStorage.removeItem(SessionEnum.batchSessionId); - - if (error) { - clearTransactionsInformation(); - console.log('Failed to send batch', batchSessionId); - } - }; - - useEffect(() => { - if (!sendBatchTransactionsOnDemand) { - return; - } - - if (!batchSessionId) { - return; - } - - if ( - signedTransactions[signedSessionId]?.status === - TransactionBatchStatusesEnum.signed - ) { - sendTransactions(); - } - }, [batchSessionId, signedTransactions[signedSessionId]?.status]); - - return { - batchId, - setBatchSessionId - }; -}; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/index.ts b/src/pages/Dashboard/widgets/BatchTransactions/index.ts deleted file mode 100644 index 38a28fc..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './BatchTransactions'; diff --git a/src/pages/Dashboard/widgets/BatchTransactions/types.ts b/src/pages/Dashboard/widgets/BatchTransactions/types.ts deleted file mode 100644 index 0d3c507..0000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { TransactionProps } from 'types/transaction.types'; - -export type SendTransactionProps = TransactionProps & { - callbackRoute: string; -}; diff --git a/src/pages/Dashboard/widgets/EscrowAbi/EscrowAbi.tsx b/src/pages/Dashboard/widgets/EscrowAbi/EscrowAbi.tsx new file mode 100644 index 0000000..121eb0c --- /dev/null +++ b/src/pages/Dashboard/widgets/EscrowAbi/EscrowAbi.tsx @@ -0,0 +1,54 @@ +import { faArrowDown, faArrowUp } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { TokenTransfer } from '@multiversx/sdk-core/out'; +import { Button } from 'components/Button'; +import { ContractAddress } from 'components/ContractAddress'; +import { OutputContainer } from 'components/OutputContainer'; +import { useSendDeposit, useSendWithdraw, useGetNetworkConfig } from 'hooks'; + +export const EscrowAbi = () => { + const { network } = useGetNetworkConfig(); + const sendDeposit = useSendDeposit(); + const sendWithdraw = useSendWithdraw(); + + const onDeposit = async () => { + if ( + window.confirm(`Are you sure you want to deposit 1 ${network.egldLabel}?`) + ) { + await sendDeposit(TokenTransfer.egldFromAmount('1').toString()); + } + }; + + const onWithdraw = async () => { + if (window.confirm('Are you sure you want to withdraw everything?')) + await sendWithdraw(); + }; + + return ( +
+
+
+ + + +
+
+ + + + +
+ ); +}; diff --git a/src/pages/Dashboard/widgets/PingPongAbi/hooks/index.ts b/src/pages/Dashboard/widgets/EscrowAbi/hooks/index.ts similarity index 100% rename from src/pages/Dashboard/widgets/PingPongAbi/hooks/index.ts rename to src/pages/Dashboard/widgets/EscrowAbi/hooks/index.ts diff --git a/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetPingAmount.ts b/src/pages/Dashboard/widgets/EscrowAbi/hooks/useGetPingAmount.ts similarity index 100% rename from src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetPingAmount.ts rename to src/pages/Dashboard/widgets/EscrowAbi/hooks/useGetPingAmount.ts diff --git a/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetTimeToPong.ts b/src/pages/Dashboard/widgets/EscrowAbi/hooks/useGetTimeToPong.ts similarity index 100% rename from src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetTimeToPong.ts rename to src/pages/Dashboard/widgets/EscrowAbi/hooks/useGetTimeToPong.ts diff --git a/src/pages/Dashboard/widgets/EscrowAbi/index.ts b/src/pages/Dashboard/widgets/EscrowAbi/index.ts new file mode 100644 index 0000000..b94fc1e --- /dev/null +++ b/src/pages/Dashboard/widgets/EscrowAbi/index.ts @@ -0,0 +1 @@ +export * from './EscrowAbi'; diff --git a/src/pages/Dashboard/widgets/NativeAuth/NativeAuth.tsx b/src/pages/Dashboard/widgets/NativeAuth/NativeAuth.tsx deleted file mode 100644 index 1ac50c1..0000000 --- a/src/pages/Dashboard/widgets/NativeAuth/NativeAuth.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { useEffect } from 'react'; -import { Label } from 'components/Label'; -import { MissingNativeAuthError } from 'components/MissingNativeAuthError'; -import { OutputContainer } from 'components/OutputContainer'; -import { FormatAmount } from 'components/sdkDappComponents'; -import { useGetLoginInfo, useGetNetworkConfig } from 'hooks'; -import { useGetProfile } from './hooks'; -import { Username } from '../Account/components'; - -export const NativeAuth = () => { - const { tokenLogin, isLoggedIn } = useGetLoginInfo(); - const { isLoading, profile, getProfile } = useGetProfile(); - const { network } = useGetNetworkConfig(); - - useEffect(() => { - // On page refresh, tokenInfo is null which implies that we do not have access to loginInfo data - if (isLoggedIn && tokenLogin?.nativeAuthToken) { - getProfile(); - } - }, [isLoggedIn]); - - if (!tokenLogin?.nativeAuthToken && !isLoading) { - return ; - } - - if (!profile && !isLoading) { - return ( - -
-

Unable to load profile

-
-
- ); - } - - return ( - -

- {profile?.address ?? 'N/A'} -

- - -

- {profile?.shard ?? 'N/A'} -

- -
- - -
-
- ); -}; diff --git a/src/pages/Dashboard/widgets/NativeAuth/hooks/index.ts b/src/pages/Dashboard/widgets/NativeAuth/hooks/index.ts deleted file mode 100644 index 4c63236..0000000 --- a/src/pages/Dashboard/widgets/NativeAuth/hooks/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useGetProfile'; diff --git a/src/pages/Dashboard/widgets/NativeAuth/hooks/useGetProfile.ts b/src/pages/Dashboard/widgets/NativeAuth/hooks/useGetProfile.ts deleted file mode 100644 index ce982c6..0000000 --- a/src/pages/Dashboard/widgets/NativeAuth/hooks/useGetProfile.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { useState } from 'react'; -import axios from 'axios'; -import { API_URL } from 'config'; -import { ProfileType } from 'types'; - -export const useGetProfile = () => { - const [profile, setProfile] = useState(null); - const [isLoading, setIsLoading] = useState(false); - - const getProfile = async () => { - try { - setIsLoading(true); - const { data } = await axios.get('/account', { - baseURL: API_URL - }); - - if (data) { - setProfile(data); - } - } catch (err) { - console.error('Unable to fetch profile'); - } finally { - setIsLoading(false); - } - }; - - return { profile, getProfile, isLoading }; -}; diff --git a/src/pages/Dashboard/widgets/NativeAuth/index.ts b/src/pages/Dashboard/widgets/NativeAuth/index.ts deleted file mode 100644 index 91072c7..0000000 --- a/src/pages/Dashboard/widgets/NativeAuth/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './NativeAuth'; diff --git a/src/pages/Dashboard/widgets/PingPongAbi/PingPongAbi.tsx b/src/pages/Dashboard/widgets/PingPongAbi/PingPongAbi.tsx deleted file mode 100644 index 3ff86c2..0000000 --- a/src/pages/Dashboard/widgets/PingPongAbi/PingPongAbi.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { useEffect, useState } from 'react'; -import { faArrowUp, faArrowDown } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; - -import moment from 'moment'; -import { Button } from 'components/Button'; -import { ContractAddress } from 'components/ContractAddress'; -import { Label } from 'components/Label'; -import { OutputContainer, PingPongOutput } from 'components/OutputContainer'; -import { getCountdownSeconds, setTimeRemaining } from 'helpers'; -import { useGetPendingTransactions, useSendPingPongTransaction } from 'hooks'; -import { SessionEnum } from 'localConstants'; -import { SignedTransactionType, WidgetProps } from 'types'; -import { useGetTimeToPong, useGetPingAmount } from './hooks'; - -export const PingPongAbi = ({ callbackRoute }: WidgetProps) => { - const { hasPendingTransactions } = useGetPendingTransactions(); - const getTimeToPong = useGetTimeToPong(); - const { - sendPingTransactionFromAbi, - sendPongTransactionFromAbi, - transactionStatus - } = useSendPingPongTransaction({ - type: SessionEnum.abiPingPongSessionId - }); - const pingAmount = useGetPingAmount(); - - const [stateTransactions, setStateTransactions] = useState< - SignedTransactionType[] | null - >(null); - const [hasPing, setHasPing] = useState(true); - const [secondsLeft, setSecondsLeft] = useState(0); - - const setSecondsRemaining = async () => { - const secondsRemaining = await getTimeToPong(); - const { canPing, timeRemaining } = setTimeRemaining(secondsRemaining); - - setHasPing(canPing); - if (timeRemaining && timeRemaining >= 0) { - setSecondsLeft(timeRemaining); - } - }; - - const onSendPingTransaction = async () => { - await sendPingTransactionFromAbi({ amount: pingAmount, callbackRoute }); - }; - - const onSendPongTransaction = async () => { - await sendPongTransactionFromAbi({ callbackRoute }); - }; - - const timeRemaining = moment() - .startOf('day') - .seconds(secondsLeft ?? 0) - .format('mm:ss'); - - const pongAllowed = secondsLeft === 0; - - useEffect(() => { - getCountdownSeconds({ secondsLeft, setSecondsLeft }); - }, [hasPing]); - - useEffect(() => { - if (transactionStatus.transactions) { - setStateTransactions(transactionStatus.transactions); - } - }, [transactionStatus]); - - useEffect(() => { - setSecondsRemaining(); - }, [hasPendingTransactions]); - - return ( -
-
-
- - - -
-
- - - {!stateTransactions && ( - <> - - {!pongAllowed && ( -

- - {timeRemaining} until able - to pong -

- )} - - )} - - -
-
- ); -}; diff --git a/src/pages/Dashboard/widgets/PingPongAbi/index.ts b/src/pages/Dashboard/widgets/PingPongAbi/index.ts deleted file mode 100644 index 0357fd7..0000000 --- a/src/pages/Dashboard/widgets/PingPongAbi/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './PingPongAbi'; diff --git a/src/pages/Dashboard/widgets/PingPongRaw/PingPongRaw.tsx b/src/pages/Dashboard/widgets/PingPongRaw/PingPongRaw.tsx deleted file mode 100644 index 903716c..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/PingPongRaw.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { useEffect, useState } from 'react'; -import { faArrowUp, faArrowDown } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import moment from 'moment'; -import { Button } from 'components/Button'; -import { ContractAddress } from 'components/ContractAddress'; -import { Label } from 'components/Label'; -import { OutputContainer, PingPongOutput } from 'components/OutputContainer'; -import { getCountdownSeconds, setTimeRemaining } from 'helpers'; -import { useGetPendingTransactions, useSendPingPongTransaction } from 'hooks'; -import { SessionEnum } from 'localConstants'; -import { SignedTransactionType, WidgetProps } from 'types'; -import { useGetTimeToPong, useGetPingAmount } from './hooks'; - -// Raw transaction are being done by directly requesting to API instead of calling the smartcontract -export const PingPongRaw = ({ callbackRoute }: WidgetProps) => { - const getTimeToPong = useGetTimeToPong(); - const { hasPendingTransactions } = useGetPendingTransactions(); - const { sendPingTransaction, sendPongTransaction, transactionStatus } = - useSendPingPongTransaction({ - type: SessionEnum.rawPingPongSessionId - }); - const pingAmount = useGetPingAmount(); - - const [stateTransactions, setStateTransactions] = useState< - SignedTransactionType[] | null - >(null); - const [hasPing, setHasPing] = useState(true); - const [secondsLeft, setSecondsLeft] = useState(0); - - const setSecondsRemaining = async () => { - const secondsRemaining = await getTimeToPong(); - const { canPing, timeRemaining } = setTimeRemaining(secondsRemaining); - - setHasPing(canPing); - if (timeRemaining && timeRemaining >= 0) { - setSecondsLeft(timeRemaining); - } - }; - - const onSendPingTransaction = async () => { - await sendPingTransaction({ amount: pingAmount, callbackRoute }); - }; - - const onSendPongTransaction = async () => { - await sendPongTransaction({ callbackRoute }); - }; - - const timeRemaining = moment() - .startOf('day') - .seconds(secondsLeft ?? 0) - .format('mm:ss'); - - const pongAllowed = secondsLeft === 0; - - useEffect(() => { - getCountdownSeconds({ secondsLeft, setSecondsLeft }); - }, [hasPing]); - - useEffect(() => { - if (transactionStatus.transactions) { - setStateTransactions(transactionStatus.transactions); - } - }, [transactionStatus]); - - useEffect(() => { - setSecondsRemaining(); - }, [hasPendingTransactions]); - - return ( -
-
-
- - - -
-
- - - {!stateTransactions && ( - <> - - {!pongAllowed && ( -

- - {timeRemaining} until able - to pong -

- )} - - )} - -
-
- ); -}; diff --git a/src/pages/Dashboard/widgets/PingPongRaw/hooks/index.ts b/src/pages/Dashboard/widgets/PingPongRaw/hooks/index.ts deleted file mode 100644 index d2fbb30..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/hooks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './useGetTimeToPong'; -export * from './useGetPingAmount'; diff --git a/src/pages/Dashboard/widgets/PingPongRaw/hooks/tests/useGetTimeToPong.test.ts b/src/pages/Dashboard/widgets/PingPongRaw/hooks/tests/useGetTimeToPong.test.ts deleted file mode 100644 index 85ca219..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/hooks/tests/useGetTimeToPong.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { renderHook } from '@testing-library/react'; -import axios from 'axios'; -import { useGetTimeToPong } from '../useGetTimeToPong'; - -beforeEach(() => { - jest.mock('@multiversx/sdk-dapp/hooks/useGetNetworkConfig', () => ({ - useGetNetworkConfig: jest.fn().mockReturnValue({ - network: { apiAddress: 'https://devnet-api.multiversx.com' } - }) - })); -}); - -describe('useGetTimeToPong', () => { - it('should return 180 seconds', async () => { - jest.spyOn(axios, 'post').mockResolvedValueOnce({ - data: { - data: { - data: { - returnData: ['tA=='] // 180 converted from b64 to hexa and from hexa to decimal - } - } - } - }); - - const { result } = renderHook(() => useGetTimeToPong()); - const timeToPong = await result.current(); - // Assert the result is correct based on your mock data - expect(timeToPong).toBe(180); - }); - - it('should return 0', async () => { - jest.spyOn(axios, 'post').mockResolvedValueOnce({ - data: { - data: { - data: { - returnData: [''] - } - } - } - }); - - const { result } = renderHook(() => useGetTimeToPong()); - const timeToPong = await result.current(); - // Assert the result is correct based on your mock data - expect(timeToPong).toBe(0); - }); - - it('should return null', async () => { - jest.spyOn(axios, 'post').mockResolvedValueOnce({ - data: { - data: { - data: { - returnData: [] - } - } - } - }); - - const { result } = renderHook(() => useGetTimeToPong()); - const timeToPong = await result.current(); - // Assert the result is correct based on your mock data - expect(timeToPong).toBe(null); - }); -}); diff --git a/src/pages/Dashboard/widgets/PingPongRaw/hooks/useGetPingAmount.ts b/src/pages/Dashboard/widgets/PingPongRaw/hooks/useGetPingAmount.ts deleted file mode 100644 index b8060d3..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/hooks/useGetPingAmount.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { useState, useEffect } from 'react'; -import axios from 'axios'; -import BigNumber from 'bignumber.js'; -import { contractAddress } from 'config'; -import { useGetNetworkConfig } from 'hooks'; -import { PingPongResponseType } from '../types'; - -const decodeAmount = (data: PingPongResponseType) => { - const returnValue = data.data.data.returnData[0]; - const decodedString = Buffer.from(returnValue, 'base64').toString('hex'); - - return new BigNumber(decodedString, 16).toString(10); -}; - -export const useGetPingAmount = () => { - const [pingAmount, setPingAmount] = useState('0'); - const { network } = useGetNetworkConfig(); - - const getPingAmount = async () => { - try { - const { data } = await axios.post( - `${network.apiAddress}/vm-values/query`, - { - scAddress: contractAddress, - funcName: 'getPingAmount', - args: [] - } - ); - - const amount = decodeAmount(data); - setPingAmount(amount); - } catch (err) { - console.error('Unable to call getPingAmount - RAW', err); - } - }; - - useEffect(() => { - getPingAmount(); - }, []); - - return pingAmount; -}; diff --git a/src/pages/Dashboard/widgets/PingPongRaw/hooks/useGetTimeToPong.ts b/src/pages/Dashboard/widgets/PingPongRaw/hooks/useGetTimeToPong.ts deleted file mode 100644 index 3036394..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/hooks/useGetTimeToPong.ts +++ /dev/null @@ -1,45 +0,0 @@ -import axios from 'axios'; -import BigNumber from 'bignumber.js'; -import { contractAddress } from 'config'; -import { useGetNetworkConfig, useGetAccount } from 'hooks'; -import { Address, AddressValue } from 'utils'; -import { PingPongResponseType } from '../types'; - -const decodeTime = (data: PingPongResponseType) => { - const returnValue = data.data.data.returnData[0]; - if (returnValue === '') { - return 0; - } - - if (!returnValue) { - return null; - } - - const decodedString = Buffer.from(returnValue, 'base64').toString('hex'); - return new BigNumber(decodedString, 16).toNumber(); -}; - -export const useGetTimeToPong = () => { - const { network } = useGetNetworkConfig(); - const { address } = useGetAccount(); - - const getTimeToPong = async () => { - try { - const args = new AddressValue(new Address(address)).valueOf().hex(); - const { data } = await axios.post( - `${network.apiAddress}/vm-values/query`, - { - scAddress: contractAddress, - funcName: 'getTimeToPong', - args: [args] - } - ); - - return decodeTime(data); - } catch (err) { - return null; - } - }; - - return getTimeToPong; -}; diff --git a/src/pages/Dashboard/widgets/PingPongRaw/index.ts b/src/pages/Dashboard/widgets/PingPongRaw/index.ts deleted file mode 100644 index 715de75..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './PingPongRaw'; diff --git a/src/pages/Dashboard/widgets/PingPongRaw/types/index.ts b/src/pages/Dashboard/widgets/PingPongRaw/types/index.ts deleted file mode 100644 index f1a9438..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './pingPong.types'; diff --git a/src/pages/Dashboard/widgets/PingPongRaw/types/pingPong.types.ts b/src/pages/Dashboard/widgets/PingPongRaw/types/pingPong.types.ts deleted file mode 100644 index bbb156e..0000000 --- a/src/pages/Dashboard/widgets/PingPongRaw/types/pingPong.types.ts +++ /dev/null @@ -1,29 +0,0 @@ -export type PingPongResponseType = { - code: string; - data: { - data: { - returnData: string[]; - returnCode: string; - returnMessage: string; - gasRemaining: number; - gasRefund: number; - outputAccounts: { - [key: string]: { - address: string; - nonce: number; - balance: null | number; - balanceDelta: number; - storageUpdates: { [key: string]: any }; - code: null | number; - codeMetaData: null | number; - outputTransfers: []; - callType: number; - }; - }; - deletedAccounts: []; - touchedAccounts: []; - logs: []; - }; - }; - error: string; -}; diff --git a/src/pages/Dashboard/widgets/PingPongService/PingPongService.tsx b/src/pages/Dashboard/widgets/PingPongService/PingPongService.tsx deleted file mode 100644 index b244cdd..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/PingPongService.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { useEffect, useState } from 'react'; -import { faArrowUp, faArrowDown } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import moment from 'moment'; -import { Button } from 'components/Button'; -import { ContractAddress } from 'components/ContractAddress'; -import { Label } from 'components/Label'; -import { MissingNativeAuthError } from 'components/MissingNativeAuthError'; -import { OutputContainer, PingPongOutput } from 'components/OutputContainer'; -import { getCountdownSeconds, setTimeRemaining } from 'helpers'; -import { useGetPendingTransactions, useSendPingPongTransaction } from 'hooks'; -import { useGetLoginInfo } from 'hooks/sdkDappHooks'; -import { SessionEnum } from 'localConstants'; -import { SignedTransactionType, WidgetProps } from 'types'; -import { - useGetTimeToPong, - useGetPingTransaction, - useGetPongTransaction -} from './hooks'; - -// The transactions are being done by directly requesting to template-dapp service -export const PingPongService = ({ callbackRoute }: WidgetProps) => { - const [stateTransactions, setStateTransactions] = useState< - SignedTransactionType[] | null - >(null); - const [hasPing, setHasPing] = useState(true); - const [secondsLeft, setSecondsLeft] = useState(0); - - const { - sendPingTransactionFromService, - sendPongTransactionFromService, - transactionStatus - } = useSendPingPongTransaction({ - type: SessionEnum.abiPingPongServiceSessionId - }); - const getTimeToPong = useGetTimeToPong(); - const getPingTransaction = useGetPingTransaction(); - const getPongTransaction = useGetPongTransaction(); - const { hasPendingTransactions } = useGetPendingTransactions(); - const { tokenLogin } = useGetLoginInfo(); - - const setSecondsRemaining = async () => { - if (!tokenLogin?.nativeAuthToken) { - return; - } - - const secondsRemaining = await getTimeToPong(); - const { canPing, timeRemaining } = setTimeRemaining(secondsRemaining); - - setHasPing(canPing); - if (timeRemaining && timeRemaining >= 0) { - setSecondsLeft(timeRemaining); - } - }; - - const onSendPingTransaction = async () => { - const pingTransaction = await getPingTransaction(); - - if (!pingTransaction) { - return; - } - - await sendPingTransactionFromService({ - transactions: [pingTransaction], - callbackRoute - }); - }; - - const onSendPongTransaction = async () => { - const pongTransaction = await getPongTransaction(); - - if (!pongTransaction) { - return; - } - - await sendPongTransactionFromService({ - transactions: [pongTransaction], - callbackRoute - }); - }; - - const timeRemaining = moment() - .startOf('day') - .seconds(secondsLeft ?? 0) - .format('mm:ss'); - - const pongAllowed = secondsLeft === 0; - - useEffect(() => { - getCountdownSeconds({ secondsLeft, setSecondsLeft }); - }, [hasPing]); - - useEffect(() => { - if (transactionStatus.transactions) { - setStateTransactions(transactionStatus.transactions); - } - }, [transactionStatus]); - - useEffect(() => { - setSecondsRemaining(); - }, [hasPendingTransactions]); - - if (!tokenLogin?.nativeAuthToken) { - return ; - } - - return ( -
-
-
- - - -
-
- - - {!stateTransactions && ( - <> - - {!pongAllowed && ( -

- - {timeRemaining} until able - to pong -

- )} - - )} - -
-
- ); -}; diff --git a/src/pages/Dashboard/widgets/PingPongService/hooks/index.ts b/src/pages/Dashboard/widgets/PingPongService/hooks/index.ts deleted file mode 100644 index f5899e4..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/hooks/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './useGetTimeToPong'; -export * from './useGetPingTransaction'; -export * from './useGetPongTransaction'; diff --git a/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetPingTransaction.test.ts b/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetPingTransaction.test.ts deleted file mode 100644 index 4526849..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetPingTransaction.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { renderHook } from '@testing-library/react'; -import axios from 'axios'; -import { useGetPingTransaction } from '../useGetPingTransaction'; - -const pingTransaction = { - nonce: 10705, - value: '1000000000000000000', - receiver: 'erd1qqqqqqqqqqqqqpgq72l6vl07fkn3alyfq753mcy4nakm0l72396qkcud5x', - sender: 'erd1wh9c0sjr2xn8hzf02lwwcr4jk2s84tat9ud2kaq6zr7xzpvl9l5q8awmex', - gasPrice: 1000000000, - gasLimit: 6000000, - data: 'cGluZw==', - chainID: 'D', - version: 1 -}; - -describe('useGetPingTransaction', () => { - it('should return Ping transaction', async () => { - jest.spyOn(axios, 'post').mockResolvedValueOnce({ - data: pingTransaction - }); - - const { result } = renderHook(() => useGetPingTransaction()); - const transactionReceived = await result.current(); - - expect(transactionReceived).toBe(pingTransaction); - }); - - it('should return null', async () => { - jest.spyOn(axios, 'post').mockRejectedValueOnce(new Error('error')); - - const { result } = renderHook(() => useGetPingTransaction()); - const transactionReceived = await result.current(); - - expect(transactionReceived).toBeNull(); - }); -}); diff --git a/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetPongTransaction.test.ts b/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetPongTransaction.test.ts deleted file mode 100644 index 8d3273d..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetPongTransaction.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { renderHook } from '@testing-library/react'; -import axios from 'axios'; -import { useGetPongTransaction } from '../useGetPongTransaction'; - -const pongTransaction = { - nonce: 10702, - value: '0', - receiver: 'erd1qqqqqqqqqqqqqpgq72l6vl07fkn3alyfq753mcy4nakm0l72396qkcud5x', - sender: 'erd1wh9c0sjr2xn8hzf02lwwcr4jk2s84tat9ud2kaq6zr7xzpvl9l5q8awmex', - gasPrice: 1000000000, - gasLimit: 6000000, - data: 'cG9uZw==', - chainID: 'D', - version: 1 -}; - -describe('useGetPongTransaction', () => { - it('should return Pong transaction', async () => { - jest.spyOn(axios, 'post').mockResolvedValueOnce({ - data: pongTransaction - }); - - const { result } = renderHook(() => useGetPongTransaction()); - const transactionReceived = await result.current(); - - expect(transactionReceived).toBe(pongTransaction); - }); - - it('should return null', async () => { - jest.spyOn(axios, 'post').mockRejectedValueOnce(new Error('error')); - - const { result } = renderHook(() => useGetPongTransaction()); - const transactionReceived = await result.current(); - - expect(transactionReceived).toBeNull(); - }); -}); diff --git a/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetTimeToPong.test.ts b/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetTimeToPong.test.ts deleted file mode 100644 index 63e3405..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/hooks/tests/useGetTimeToPong.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { renderHook } from '@testing-library/react'; -import axios from 'axios'; -import { useGetTimeToPong } from '../useGetTimeToPong'; - -describe('useGetTimeToPong', () => { - it('should return 180 seconds', async () => { - jest.spyOn(axios, 'get').mockResolvedValueOnce({ - data: { - status: 'awaiting_pong', - timeToPong: 180 - } - }); - - const { result } = renderHook(() => useGetTimeToPong()); - const timeToPong = await result.current(); - - expect(timeToPong).toBe(180); - }); - - it('should return undefined', async () => { - jest.spyOn(axios, 'get').mockResolvedValueOnce({ - data: { - status: 'not_yet_pinged' - } - }); - - const { result } = renderHook(() => useGetTimeToPong()); - const timeToPong = await result.current(); - - expect(timeToPong).toBeUndefined(); - }); - - it('should return null', async () => { - jest.spyOn(axios, 'get').mockRejectedValueOnce(new Error('error')); - - const { result } = renderHook(() => useGetTimeToPong()); - - const timeToPong = await result.current(); - expect(timeToPong).toBeNull(); - }); -}); diff --git a/src/pages/Dashboard/widgets/PingPongService/hooks/useGetPingTransaction.ts b/src/pages/Dashboard/widgets/PingPongService/hooks/useGetPingTransaction.ts deleted file mode 100644 index 0216666..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/hooks/useGetPingTransaction.ts +++ /dev/null @@ -1,22 +0,0 @@ -import axios from 'axios'; -import { API_URL } from 'config'; -import { Transaction } from 'types/sdkCoreTypes'; - -export const useGetPingTransaction = () => { - return async () => { - try { - const { data } = await axios.post( - '/ping-pong/abi/ping', - {}, - { - baseURL: API_URL - } - ); - - return data; - } catch (err) { - console.error('Unable to get Ping Transaction', err); - return null; - } - }; -}; diff --git a/src/pages/Dashboard/widgets/PingPongService/hooks/useGetPongTransaction.ts b/src/pages/Dashboard/widgets/PingPongService/hooks/useGetPongTransaction.ts deleted file mode 100644 index ac28c8d..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/hooks/useGetPongTransaction.ts +++ /dev/null @@ -1,22 +0,0 @@ -import axios from 'axios'; -import { API_URL } from 'config'; -import { Transaction } from 'types/sdkCoreTypes'; - -export const useGetPongTransaction = () => { - return async () => { - try { - const { data } = await axios.post( - '/ping-pong/abi/pong', - {}, - { - baseURL: API_URL - } - ); - - return data; - } catch (err) { - console.error('Unable to get Pong Transaction', err); - return null; - } - }; -}; diff --git a/src/pages/Dashboard/widgets/PingPongService/hooks/useGetTimeToPong.ts b/src/pages/Dashboard/widgets/PingPongService/hooks/useGetTimeToPong.ts deleted file mode 100644 index e6d46ab..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/hooks/useGetTimeToPong.ts +++ /dev/null @@ -1,23 +0,0 @@ -import axios from 'axios'; -import { API_URL } from 'config'; -import { TimeToPongResponseType } from '../types'; - -export const useGetTimeToPong = () => { - const getTimeToPong = async () => { - try { - const { data } = await axios.get( - '/ping-pong/abi/time-to-pong', - { - baseURL: API_URL - } - ); - - return data.timeToPong; - } catch (err) { - console.error(err); - return null; - } - }; - - return getTimeToPong; -}; diff --git a/src/pages/Dashboard/widgets/PingPongService/index.ts b/src/pages/Dashboard/widgets/PingPongService/index.ts deleted file mode 100644 index 2227ec5..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './PingPongService'; diff --git a/src/pages/Dashboard/widgets/PingPongService/types/index.ts b/src/pages/Dashboard/widgets/PingPongService/types/index.ts deleted file mode 100644 index f1a9438..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './pingPong.types'; diff --git a/src/pages/Dashboard/widgets/PingPongService/types/pingPong.types.ts b/src/pages/Dashboard/widgets/PingPongService/types/pingPong.types.ts deleted file mode 100644 index 5afb89c..0000000 --- a/src/pages/Dashboard/widgets/PingPongService/types/pingPong.types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type TimeToPongResponseType = { - status: 'not_yet_pinged' | 'awaiting_pong'; - timeToPong?: number; -}; diff --git a/src/pages/Dashboard/widgets/SignMessage/SignMessage.tsx b/src/pages/Dashboard/widgets/SignMessage/SignMessage.tsx deleted file mode 100644 index ec87fa3..0000000 --- a/src/pages/Dashboard/widgets/SignMessage/SignMessage.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { useState } from 'react'; -import type { MouseEvent } from 'react'; -import { - faFileSignature, - faBroom, - faArrowsRotate -} from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { useGetSignMessageSession } from '@multiversx/sdk-dapp/hooks/signMessage/useGetSignMessageSession'; -import { Button } from 'components/Button'; -import { OutputContainer } from 'components/OutputContainer'; -import { useSignMessage } from 'hooks'; -import { SignedMessageStatusesEnum, WidgetProps } from 'types'; -import { SignFailure, SignSuccess } from './components'; - -export const SignMessage = ({ callbackRoute }: WidgetProps) => { - const { sessionId, signMessage, onAbort } = useSignMessage(); - const messageSession = useGetSignMessageSession(sessionId); - - const [message, setMessage] = useState(''); - - const handleSubmit = (e: MouseEvent) => { - e.preventDefault(); - - if (messageSession) { - onAbort(); - } - - if (!message.trim()) { - return; - } - - signMessage({ - message, - callbackRoute - }); - - setMessage(''); - }; - - const handleClear = (e: MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - onAbort(); - }; - - const isError = messageSession - ? [ - (SignedMessageStatusesEnum.cancelled, SignedMessageStatusesEnum.failed) - ].includes(messageSession.status) && messageSession?.message - : false; - - const isSuccess = - messageSession?.message && - messageSession?.status === SignedMessageStatusesEnum.signed; - - return ( -
-
- - - {(isSuccess || isError) && ( - - )} -
- - {!isSuccess && !isError && ( -