diff --git a/README.md b/README.md index a73a4aec..b408c76a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # @multiversx/template-dapp -The **MultiversX dApp Template**, built using [React.js](https://reactjs.org/) and [Typescript](https://www.typescriptlang.org/). +The **MultiversX Lite Wallet dApp**, built using [React.js](https://reactjs.org/) and [Typescript](https://www.typescriptlang.org/). It's a basic implementation of [@multiversx/sdk-dapp](https://www.npmjs.com/package/@multiversx/sdk-dapp), providing the basics for MultiversX authentication and TX signing. -See [Dapp template](https://template-dapp.multiversx.com/) for live demo. +See [Lite Wallet dApp](https://lite-wallet-dapp.multiversx.com/) for live demo. ## Requirements diff --git a/index.html b/index.html index 9f264e3f..826f9594 100644 --- a/index.html +++ b/index.html @@ -42,7 +42,7 @@ - + - + - Template dApp + Lite Wallet dApp diff --git a/package.json b/package.json index efa7624b..508fe829 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,28 @@ { - "name": "@multiversx/mx-template-dapp", - "description": "MultiversX Dapp Template", + "name": "@multiversx/mx-lite-wallet-dapp", + "description": "MultiversX Lite Wallet DApp", "version": "1.0.0", "author": "MultiversX", "license": "GPL-3.0-or-later", - "repository": "@multiversx/mx-template-dapp", + "repository": "@multiversx/mx-lite-wallet-dapp", "dependencies": { "@fortawesome/fontawesome-svg-core": "6.5.1", "@fortawesome/free-solid-svg-icons": "6.5.1", "@fortawesome/react-fontawesome": "0.2.0", "@multiversx/sdk-core": "13.0.1", - "@multiversx/sdk-dapp": "2.32.0", + "@multiversx/sdk-dapp": "2.33.2", + "@multiversx/sdk-dapp-form": "^0.10.10", "@multiversx/sdk-network-providers": "2.2.1", + "@reduxjs/toolkit": "1.9.1", "axios": "1.6.5", "classnames": "2.3.2", "moment": "2.29.4", "react": "18.2.0", "react-dom": "18.2.0", - "react-router-dom": "6.16.0" + "react-qr-code": "^2.0.14", + "react-redux": "8.0.5", + "react-router-dom": "6.16.0", + "redux-persist": "6.0.0" }, "scripts": { "lint": "eslint --ext js,ts,tsx src", @@ -51,8 +56,15 @@ "@types/react": "18.2.23", "@types/react-dom": "18.2.8", "@types/react-router-dom": "5.3.3", + "@typescript-eslint/eslint-plugin": "^7.13.0", + "@typescript-eslint/parser": "^7.13.0", "@vitejs/plugin-basic-ssl": "^1.0.1", "@vitejs/plugin-react": "4.1.0", + "@wdio/cli": "^8.33.1", + "@wdio/concise-reporter": "8.32.4", + "@wdio/local-runner": "^8.32.4", + "@wdio/mocha-framework": "^8.32.4", + "@wdio/spec-reporter": "^8.32.4", "autoprefixer": "10.4.16", "eslint": "8.50.0", "eslint-config-prettier": "9.0.0", @@ -75,17 +87,12 @@ "prettier": "3.0.3", "tailwindcss": "3.3.3", "ts-jest": "29.1.1", + "ts-node": "10.9.2", "typescript": "5.2.2", "vite": "4.4.9", "vite-plugin-node-polyfills": "0.14.1", "vite-plugin-svgr": "4.0.0", - "vite-tsconfig-paths": "4.2.1", - "@wdio/local-runner": "^8.32.4", - "@wdio/mocha-framework": "^8.32.4", - "@wdio/spec-reporter": "^8.32.4", - "@wdio/cli": "^8.33.1", - "ts-node": "10.9.2", - "@wdio/concise-reporter": "8.32.4" + "vite-tsconfig-paths": "4.2.1" }, "resolutions": { "**/*/nth-check": "2.0.1" diff --git a/public/manifest.json b/public/manifest.json index 9f481b69..4952b5a3 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,5 +1,5 @@ { - "name": "MultiversX dApp Template", + "name": "MultiversX Lite Wallet dApp", "short_name": "MultiversX dApp", "description": "Easily add or update assets for a Token or NFT Collection on the MultiversX Blockchain", "icons": [ diff --git a/public/site.webmanifest b/public/site.webmanifest index 767cb32a..4e909a79 100644 --- a/public/site.webmanifest +++ b/public/site.webmanifest @@ -1,5 +1,5 @@ { - "name": "MultiversX dApp Template", + "name": "MultiversX Lite Wallet dApp", "short_name": "MultiversX dApp", "icons": [ { diff --git a/src/App.tsx b/src/App.tsx index 3b9cc9fb..32a53127 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; +import { PersistGate } from 'redux-persist/integration/react'; import { AxiosInterceptorContext, // using this is optional @@ -21,6 +22,8 @@ import { RouteNamesEnum } from 'localConstants'; import { PageNotFound, Unlock } from 'pages'; import { routes } from 'routes'; import { BatchTransactionsContextProvider } from 'wrappers'; +import { Provider } from 'react-redux'; +import { persistor, store } from './redux/store'; const AppContent = () => { return ( @@ -72,18 +75,30 @@ const AppContent = () => { ); }; -export const App = () => { +export const MainApp = () => { return ( - - - - - + + + ); }; + +export const ProviderApp = () => ( + + + + + +); + +export const App = () => ( + + + +); diff --git a/src/components/ContractAddress/ContractAddress.tsx b/src/components/ContractAddress/ContractAddress.tsx deleted file mode 100644 index 7007e82c..00000000 --- a/src/components/ContractAddress/ContractAddress.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Label } from 'components/Label'; -import { ACCOUNTS_ENDPOINT, ExplorerLink } from 'components/sdkDappComponents'; -import { contractAddress } from 'config'; - -export const ContractAddress = () => { - return ( -

- - - {contractAddress} - -

- ); -}; diff --git a/src/components/ContractAddress/index.ts b/src/components/ContractAddress/index.ts deleted file mode 100644 index d01c3095..00000000 --- a/src/components/ContractAddress/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ContractAddress'; diff --git a/src/components/Copy/Copy.tsx b/src/components/Copy/Copy.tsx new file mode 100644 index 00000000..d5d4f2bc --- /dev/null +++ b/src/components/Copy/Copy.tsx @@ -0,0 +1,30 @@ +import { useState } from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons'; + +export const Copy = ({ + value, + className = '' +}: { + value: string; + className?: string; +}) => { + const [confirm, setConfirm] = useState(false); + + const copy = () => { + navigator.clipboard.writeText(value); + setConfirm(true); + setTimeout(() => setConfirm(false), 2000); + }; + + return ( + + + + ); +}; diff --git a/src/components/Copy/index.tsx b/src/components/Copy/index.tsx new file mode 100644 index 00000000..bc6c9081 --- /dev/null +++ b/src/components/Copy/index.tsx @@ -0,0 +1 @@ +export * from './Copy'; diff --git a/src/components/Layout/Footer/index.ts b/src/components/Layout/Footer/index.tsx similarity index 100% rename from src/components/Layout/Footer/index.ts rename to src/components/Layout/Footer/index.tsx diff --git a/src/components/Layout/Header/index.ts b/src/components/Layout/Header/index.tsx similarity index 100% rename from src/components/Layout/Header/index.ts rename to src/components/Layout/Header/index.tsx diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 1ead9b83..684b1d8f 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -1,6 +1,6 @@ import type { PropsWithChildren } from 'react'; import { useLocation } from 'react-router-dom'; -import { AuthenticatedRoutesWrapper } from 'components/sdkDappComponents'; +import { AuthenticatedRoutesWrapper } from 'components'; import { RouteNamesEnum } from 'localConstants/routes'; import { routes } from 'routes/routes'; import { Footer } from './Footer'; diff --git a/src/components/OutputContainer/OutputContainer.tsx b/src/components/OutputContainer/OutputContainer.tsx index e5d576f9..60e53f05 100644 --- a/src/components/OutputContainer/OutputContainer.tsx +++ b/src/components/OutputContainer/OutputContainer.tsx @@ -1,6 +1,6 @@ import type { PropsWithChildren } from 'react'; import classNames from 'classnames'; -import { Loader } from 'components/sdkDappComponents'; +import { Loader } from 'components'; import { WithClassnameType } from 'types'; interface OutputContainerPropsType diff --git a/src/components/OutputContainer/components/PingPongOutput.tsx b/src/components/OutputContainer/components/PingPongOutput.tsx deleted file mode 100644 index 9a70e6f1..00000000 --- a/src/components/OutputContainer/components/PingPongOutput.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { ContractAddress } from 'components/ContractAddress'; -import { Label } from 'components/Label'; -import { SignedTransactionType } from 'types'; -import { TransactionsOutput } from './TransactionsOutput'; - -type PingPongOutputType = { - timeRemaining: string; - pongAllowed: boolean; - transactions?: SignedTransactionType[] | null; -}; - -export const PingPongOutput = ({ - timeRemaining, - pongAllowed, - transactions -}: PingPongOutputType) => { - if (!transactions) { - return null; - } - - return ( - <> - - - {!pongAllowed && ( -

- - {timeRemaining} until able to - pong -

- )} - - ); -}; diff --git a/src/components/OutputContainer/components/TransactionOutput.tsx b/src/components/OutputContainer/components/TransactionOutput.tsx deleted file mode 100644 index 7d29558e..00000000 --- a/src/components/OutputContainer/components/TransactionOutput.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { - TRANSACTIONS_ENDPOINT, - ACCOUNTS_ENDPOINT -} from '@multiversx/sdk-dapp/apiCalls/endpoints'; -import { useGetNetworkConfig } from '@multiversx/sdk-dapp/hooks/useGetNetworkConfig'; -import { ExplorerLink } from '@multiversx/sdk-dapp/UI/ExplorerLink'; -import { Label } from 'components/Label'; -import { FormatAmount } from 'components/sdkDappComponents'; -import { SignedTransactionType } from 'types'; - -export const TransactionOutput = ({ - transaction -}: { - transaction: SignedTransactionType; -}) => { - const { network } = useGetNetworkConfig(); - const decodedData = transaction.data - ? Buffer.from(transaction.data, 'base64').toString('ascii') - : 'N/A'; - return ( -
-

- - - {transaction.hash} - -

-

- - - {transaction.receiver} - -

- -

- - -

-

- - {transaction.gasPrice} -

-

- - {transaction.gasLimit} -

-

- {decodedData} -

-
- ); -}; diff --git a/src/components/OutputContainer/components/TransactionsOutput.tsx b/src/components/OutputContainer/components/TransactionsOutput.tsx deleted file mode 100644 index 32c74bd2..00000000 --- a/src/components/OutputContainer/components/TransactionsOutput.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { SignedTransactionType } from 'types'; -import { TransactionOutput } from './TransactionOutput'; - -export const TransactionsOutput = ({ - transactions -}: { - transactions: SignedTransactionType[]; -}) => { - return ( -
- {transactions?.map((transaction) => { - return ( - - ); - })} -
- ); -}; diff --git a/src/components/OutputContainer/components/index.ts b/src/components/OutputContainer/components/index.ts deleted file mode 100644 index 7483ff71..00000000 --- a/src/components/OutputContainer/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './PingPongOutput'; -export * from './TransactionsOutput'; diff --git a/src/components/OutputContainer/index.ts b/src/components/OutputContainer/index.ts index 802078a8..58eff8bf 100644 --- a/src/components/OutputContainer/index.ts +++ b/src/components/OutputContainer/index.ts @@ -1,2 +1 @@ export * from './OutputContainer'; -export * from './components'; diff --git a/src/components/TransactionsTracker/TransactionsTracker.ts b/src/components/TransactionsTracker/TransactionsTracker.ts index ac63ab62..f9b21971 100644 --- a/src/components/TransactionsTracker/TransactionsTracker.ts +++ b/src/components/TransactionsTracker/TransactionsTracker.ts @@ -1,5 +1,5 @@ import { useTransactionsTracker } from '@multiversx/sdk-dapp/hooks/transactions/useTransactionsTracker'; -import { useBatchTransactionsTracker } from 'hooks/sdkDappHooks'; +import { useBatchTransactionsTracker } from 'hooks'; export const TransactionsTracker = () => { useTransactionsTracker({ diff --git a/src/components/index.ts b/src/components/index.ts index 86efea26..a46ecf52 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,10 +1,10 @@ -export * from './Layout'; -export * from './sdkDappComponents'; +export * from './Button'; export * from './Card'; +export * from './Copy'; +export * from './Label'; +export * from './Layout'; +export * from './MissingNativeAuthError'; export * from './MxLink'; -export * from './Button'; export * from './OutputContainer'; export * from './TransactionsTracker'; -export * from './ContractAddress'; -export * from './MissingNativeAuthError'; -export * from './Label'; +export * from './sdkDapp.components'; diff --git a/src/components/sdkDappComponents.ts b/src/components/sdkDapp.components.ts similarity index 90% rename from src/components/sdkDappComponents.ts rename to src/components/sdkDapp.components.ts index 7b2939ff..720d658c 100644 --- a/src/components/sdkDappComponents.ts +++ b/src/components/sdkDapp.components.ts @@ -23,3 +23,6 @@ export { DappProvider } from '@multiversx/sdk-dapp/wrappers/DappProvider/DappPro export { TransactionRow } from '@multiversx/sdk-dapp/UI/TransactionsTable/components/TransactionRow'; export { ACCOUNTS_ENDPOINT } from '@multiversx/sdk-dapp/apiCalls/endpoints'; export { ExplorerLink } from '@multiversx/sdk-dapp/UI/ExplorerLink'; +export { AddressTable } from '@multiversx/sdk-dapp/UI/ledger/LedgerLoginContainer/AddressTable'; +export { Trim } from '@multiversx/sdk-dapp/UI/Trim/Trim'; +export { ModalContainer } from '@multiversx/sdk-dapp/UI/ModalContainer/ModalContainer'; diff --git a/src/contracts/ping-pong.abi.json b/src/contracts/ping-pong.abi.json deleted file mode 100644 index 804a17c4..00000000 --- a/src/contracts/ping-pong.abi.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "buildInfo": { - "rustc": { - "version": "1.61.0-nightly", - "commitHash": "1d9c262eea411ec5230f8a4c9ba50b3647064da4", - "commitDate": "2022-03-26", - "channel": "Nightly", - "short": "rustc 1.61.0-nightly (1d9c262ee 2022-03-26)" - }, - "contractCrate": { - "name": "ping-pong", - "version": "0.0.2", - "git_version": "23ff9bd" - }, - "framework": { - "name": "elrond-wasm", - "version": "0.34.1" - } - }, - "docs": [ - "A contract that allows anyone to send a fixed sum, locks it for a while and then allows users to take it back.", - "Sending funds to the contract is called \"ping\".", - "Taking the same funds back is called \"pong\".", - "", - "Restrictions:", - "- Only the set amount can be `ping`-ed, no more, no less.", - "- `pong` can only be called after a certain period after `ping`." - ], - "name": "PingPong", - "constructor": { - "docs": [ - "Necessary configuration when deploying:", - "`ping_amount` - the exact amount that needs to be sent when `ping`-ing. ", - "`duration_in_seconds` - how much time (in seconds) until `pong` can be called after the initial `ping` call ", - "`token_id` - Optional. The Token Identifier of the token that is going to be used. Default is \"EGLD\"." - ], - "inputs": [ - { - "name": "ping_amount", - "type": "BigUint" - }, - { - "name": "duration_in_seconds", - "type": "u64" - }, - { - "name": "opt_token_id", - "type": "optional", - "multi_arg": true - } - ], - "outputs": [] - }, - "endpoints": [ - { - "docs": [ - "User sends some tokens to be locked in the contract for a period of time." - ], - "name": "ping", - "mutability": "mutable", - "payableInTokens": ["*"], - "inputs": [], - "outputs": [] - }, - { - "docs": [ - "User can take back funds from the contract.", - "Can only be called after expiration." - ], - "name": "pong", - "mutability": "mutable", - "inputs": [], - "outputs": [] - }, - { - "name": "didUserPing", - "mutability": "readonly", - "inputs": [ - { - "name": "address", - "type": "Address" - } - ], - "outputs": [ - { - "type": "bool" - } - ] - }, - { - "name": "getPongEnableTimestamp", - "mutability": "readonly", - "inputs": [ - { - "name": "address", - "type": "Address" - } - ], - "outputs": [ - { - "type": "u64" - } - ] - }, - { - "name": "getTimeToPong", - "mutability": "readonly", - "inputs": [ - { - "name": "address", - "type": "Address" - } - ], - "outputs": [ - { - "type": "optional", - "multi_result": true - } - ] - }, - { - "name": "getAcceptedPaymentToken", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "EgldOrEsdtTokenIdentifier" - } - ] - }, - { - "name": "getPingAmount", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "BigUint" - } - ] - }, - { - "name": "getDurationTimestamp", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "u64" - } - ] - }, - { - "name": "getUserPingTimestamp", - "mutability": "readonly", - "inputs": [ - { - "name": "address", - "type": "Address" - } - ], - "outputs": [ - { - "type": "u64" - } - ] - } - ], - "events": [ - { - "identifier": "pongEvent", - "inputs": [ - { - "name": "user", - "type": "Address", - "indexed": true - } - ] - } - ], - "hasCallback": false, - "types": [] -} diff --git a/src/helpers/api/getBaseURL.ts b/src/helpers/api/getBaseURL.ts new file mode 100644 index 00000000..56143d94 --- /dev/null +++ b/src/helpers/api/getBaseURL.ts @@ -0,0 +1,8 @@ +import { apiAddressSelector } from '@multiversx/sdk-dapp/reduxStore/selectors/networkConfigSelectors'; +import { store } from '@multiversx/sdk-dapp/reduxStore/store'; + +export const getBaseURL = () => { + const state = store.getState(); + + return apiAddressSelector(state); +}; diff --git a/src/helpers/api/index.ts b/src/helpers/api/index.ts new file mode 100644 index 00000000..75e28dbd --- /dev/null +++ b/src/helpers/api/index.ts @@ -0,0 +1 @@ +export * from './getBaseURL'; diff --git a/src/helpers/index.ts b/src/helpers/index.ts index e2e4ec74..db2ddcb4 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,3 +1,2 @@ -export * from './sdkDappHelpers'; -export * from './pingPong'; -export * from './signAndSendTransactions'; +export * from './api'; +export * from './sdkDapp'; diff --git a/src/helpers/pingPong/getCountdownSeconds.ts b/src/helpers/pingPong/getCountdownSeconds.ts deleted file mode 100644 index 04737a22..00000000 --- a/src/helpers/pingPong/getCountdownSeconds.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { SetStateAction } from 'react'; - -type GetCountdownSecondsType = { - secondsLeft: number; - setSecondsLeft: (value: SetStateAction) => void; -}; -export const getCountdownSeconds = ({ - secondsLeft, - setSecondsLeft -}: GetCountdownSecondsType) => { - if (secondsLeft) { - const interval = setInterval(() => { - setSecondsLeft((existing) => { - if (existing) { - return existing - 1; - } else { - clearInterval(interval); - return 0; - } - }); - }, 1000); - return () => { - clearInterval(interval); - }; - } -}; diff --git a/src/helpers/pingPong/index.ts b/src/helpers/pingPong/index.ts deleted file mode 100644 index 47fdb086..00000000 --- a/src/helpers/pingPong/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './getCountdownSeconds'; -export * from './setTimeRemaining'; diff --git a/src/helpers/pingPong/setTimeRemaining.ts b/src/helpers/pingPong/setTimeRemaining.ts deleted file mode 100644 index 00ead7f0..00000000 --- a/src/helpers/pingPong/setTimeRemaining.ts +++ /dev/null @@ -1,25 +0,0 @@ -// null and undefined comes when timeToPong response does not contain returnData -// it cannot be set as 0 because it will display the countdown and will disable canPing -// if it is null/undefined then action of ping can be made -export const setTimeRemaining = ( - secondsRemaining?: null | number -): { canPing: boolean; timeRemaining?: number } => { - switch (secondsRemaining) { - case undefined: - case null: - return { - canPing: true - }; - case 0: - return { - timeRemaining: 0, - canPing: false - }; - default: { - return { - timeRemaining: secondsRemaining, - canPing: false - }; - } - } -}; diff --git a/src/helpers/sdkDapp/index.ts b/src/helpers/sdkDapp/index.ts new file mode 100644 index 00000000..11f0fabb --- /dev/null +++ b/src/helpers/sdkDapp/index.ts @@ -0,0 +1 @@ +export * from './sdkDapp.helpers'; diff --git a/src/helpers/sdkDapp/sdkDapp.helpers.ts b/src/helpers/sdkDapp/sdkDapp.helpers.ts new file mode 100644 index 00000000..c9389965 --- /dev/null +++ b/src/helpers/sdkDapp/sdkDapp.helpers.ts @@ -0,0 +1,17 @@ +export { getTransactions } from '@multiversx/sdk-dapp/apiCalls/transactions/getTransactions'; +export { sendTransactions } from '@multiversx/sdk-dapp/services/transactions/sendTransactions'; +export { refreshAccount } from '@multiversx/sdk-dapp/utils/account/refreshAccount'; +export { logout } from '@multiversx/sdk-dapp/utils/logout'; +export { signTransactions } from '@multiversx/sdk-dapp/services/transactions/signTransactions'; +export { trimUsernameDomain } from '@multiversx/sdk-dapp/hooks/account/helpers'; +export { getAccount } from '@multiversx/sdk-dapp/utils/account/getAccount'; +export { getAddress } from '@multiversx/sdk-dapp/utils/account/getAddress'; +export { newTransaction } from '@multiversx/sdk-dapp/models'; +export { useLoginService } from '@multiversx/sdk-dapp/hooks/login/useLoginService'; +export { decodeNativeAuthToken } from '@multiversx/sdk-dapp/services/nativeAuth/helpers/decodeNativeAuthToken'; +export { getIsNativeAuthSingingForbidden } from '@multiversx/sdk-dapp/services/nativeAuth/helpers/getIsNativeAuthSingingForbidden'; +export { decodeLoginToken } from '@multiversx/sdk-dapp/services/nativeAuth/helpers/decodeLoginToken'; +import { nativeAuth } from '@multiversx/sdk-dapp/services/nativeAuth/nativeAuth'; +const { getToken } = nativeAuth(); +export { getToken }; +export { loginWithExternalProvider } from '@multiversx/sdk-dapp/utils/account/loginWithExternalProvider'; diff --git a/src/helpers/sdkDappHelpers.ts b/src/helpers/sdkDappHelpers.ts deleted file mode 100644 index 9c56294c..00000000 --- a/src/helpers/sdkDappHelpers.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { getTransactions } from '@multiversx/sdk-dapp/apiCalls/transactions/getTransactions'; -export { sendTransactions } from '@multiversx/sdk-dapp/services/transactions/sendTransactions'; -export { refreshAccount } from '@multiversx/sdk-dapp/utils/account/refreshAccount'; -export { logout } from '@multiversx/sdk-dapp/utils/logout'; -export { signTransactions } from '@multiversx/sdk-dapp/services/transactions/signTransactions'; -export { trimUsernameDomain } from '@multiversx/sdk-dapp/hooks/account/helpers'; -export { newTransaction } from '@multiversx/sdk-dapp/models'; diff --git a/src/helpers/signAndSendTransactions.ts b/src/helpers/signAndSendTransactions.ts deleted file mode 100644 index d98f165b..00000000 --- a/src/helpers/signAndSendTransactions.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Transaction, TransactionsDisplayInfoType } from 'types'; - -import { refreshAccount, sendTransactions } from './sdkDappHelpers'; -import { isSafari } from 'localConstants'; - -type SignAndSendTransactionsProps = { - transactions: Transaction[]; - callbackRoute: string; - transactionsDisplayInfo: TransactionsDisplayInfoType; -}; - -export const signAndSendTransactions = async ({ - transactions, - callbackRoute, - transactionsDisplayInfo -}: SignAndSendTransactionsProps) => { - await refreshAccount(); - - const { sessionId } = await sendTransactions({ - transactions, - transactionsDisplayInfo, - redirectAfterSign: false, - callbackRoute, - // NOTE: performing async calls (eg: `await refreshAccount()`) before opening a new tab - // can cause the new tab to be blocked by Safari's popup blocker. - // To support this feature, we can set `hasConsentPopup` to `true` - hasConsentPopup: isSafari - }); - - return sessionId; -}; diff --git a/src/hooks/index.ts b/src/hooks/index.ts index f5eff249..664c3951 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1,5 +1,4 @@ -export * from './sdkDappHooks'; +export * from './sdkDapp.hooks'; export * from './withPageTitle'; -export * from './transactions'; export * from './useScrollToElement'; export * from './useIsWebProvider'; diff --git a/src/hooks/sdkDappHooks.ts b/src/hooks/sdkDapp.hooks.ts similarity index 95% rename from src/hooks/sdkDappHooks.ts rename to src/hooks/sdkDapp.hooks.ts index 4ed22c75..4efeab7a 100644 --- a/src/hooks/sdkDappHooks.ts +++ b/src/hooks/sdkDapp.hooks.ts @@ -16,3 +16,4 @@ export { useSignTransactions } from '@multiversx/sdk-dapp/hooks/transactions/use export { useBatchTransactionsTracker } from '@multiversx/sdk-dapp/hooks/transactions/batch/tracker/useBatchTransactionsTracker'; export { useGetSignedTransactions } from '@multiversx/sdk-dapp/hooks/transactions/useGetSignedTransactions'; export { useGetAccountProvider } from '@multiversx/sdk-dapp/hooks/account/useGetAccountProvider'; +export { useAddressScreens } from '@multiversx/sdk-dapp/hooks/login/useAddressScreens'; diff --git a/src/hooks/transactions/index.ts b/src/hooks/transactions/index.ts deleted file mode 100644 index 8ca4e787..00000000 --- a/src/hooks/transactions/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useSendPingPongTransaction'; diff --git a/src/hooks/transactions/useSendPingPongTransaction.ts b/src/hooks/transactions/useSendPingPongTransaction.ts deleted file mode 100644 index e3615d23..00000000 --- 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/useIsWebProvider.ts b/src/hooks/useIsWebProvider.ts index 0828fa05..841d6bbc 100644 --- a/src/hooks/useIsWebProvider.ts +++ b/src/hooks/useIsWebProvider.ts @@ -1,5 +1,5 @@ -import { LoginMethodsEnum } from 'types/sdkDappTypes'; -import { useGetAccountProvider } from './sdkDappHooks'; +import { LoginMethodsEnum } from 'types'; +import { useGetAccountProvider } from './sdkDapp.hooks'; export const useIsWebProvider = () => { const { providerType } = useGetAccountProvider(); diff --git a/src/localConstants/api/api.constants.ts b/src/localConstants/api/api.constants.ts new file mode 100644 index 00000000..1e5e9858 --- /dev/null +++ b/src/localConstants/api/api.constants.ts @@ -0,0 +1,3 @@ +// Maximum API response of transactions, tokens, etc. +export const MAX_API_SIZE = 5000; +export const API_CACHE_DURATION_SECONDS = 0; diff --git a/src/localConstants/api/index.ts b/src/localConstants/api/index.ts new file mode 100644 index 00000000..ab7f4403 --- /dev/null +++ b/src/localConstants/api/index.ts @@ -0,0 +1 @@ +export * from './api.constants'; diff --git a/src/localConstants/index.ts b/src/localConstants/index.ts index bc6eaf52..14529523 100644 --- a/src/localConstants/index.ts +++ b/src/localConstants/index.ts @@ -1,4 +1,4 @@ +export * from './api'; +export * from './nfts'; export * from './routes'; export * from './sdkDapConstants'; -export * from './signMessage'; -export * from './session'; diff --git a/src/localConstants/nfts/collectionTypeByNft.enum.ts b/src/localConstants/nfts/collectionTypeByNft.enum.ts new file mode 100644 index 00000000..c2f79106 --- /dev/null +++ b/src/localConstants/nfts/collectionTypeByNft.enum.ts @@ -0,0 +1,7 @@ +import { NftEnumType } from '@multiversx/sdk-dapp/types/tokens.types'; + +export const CollectionTypeByNftEnum = { + [NftEnumType.SemiFungibleESDT]: 'sft', + [NftEnumType.NonFungibleESDT]: 'nft', + [NftEnumType.MetaESDT]: 'meta' +}; diff --git a/src/localConstants/nfts/index.ts b/src/localConstants/nfts/index.ts new file mode 100644 index 00000000..a7337378 --- /dev/null +++ b/src/localConstants/nfts/index.ts @@ -0,0 +1 @@ +export * from './collectionTypeByNft.enum'; diff --git a/src/localConstants/routes/routeNames.enums.ts b/src/localConstants/routes/routeNames.enums.ts index f728b432..dd7d62ed 100644 --- a/src/localConstants/routes/routeNames.enums.ts +++ b/src/localConstants/routes/routeNames.enums.ts @@ -2,5 +2,6 @@ export enum RouteNamesEnum { home = '/', dashboard = '/dashboard', unlock = '/unlock', - disclaimer = '/disclaimer' + disclaimer = '/disclaimer', + send = '/send' } diff --git a/src/localConstants/session/index.ts b/src/localConstants/session/index.ts deleted file mode 100644 index 82def9ba..00000000 --- a/src/localConstants/session/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './session.enums'; - -export const isSafari = /^((?!chrome|android).)*safari/i.test( - navigator.userAgent -); diff --git a/src/localConstants/session/session.enums.ts b/src/localConstants/session/session.enums.ts deleted file mode 100644 index 38228a12..00000000 --- a/src/localConstants/session/session.enums.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum SessionEnum { - batchSessionId = 'batchSessionId', - signedSessionId = 'signedSessionId', - rawPingPongSessionId = 'rawPingPongSessionId', - abiPingPongSessionId = 'abiPingPongSessionId', - abiPingPongServiceSessionId = 'abiPingPongServiceSessionId', - batchId = 'batchId' -} diff --git a/src/localConstants/signMessage/index.ts b/src/localConstants/signMessage/index.ts deleted file mode 100644 index 890a5530..00000000 --- a/src/localConstants/signMessage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './signMessage.enums'; diff --git a/src/localConstants/signMessage/signMessage.enums.ts b/src/localConstants/signMessage/signMessage.enums.ts deleted file mode 100644 index 849a83d3..00000000 --- a/src/localConstants/signMessage/signMessage.enums.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum SignMessageEnum { - messageToSign = 'messageToSign' -} diff --git a/src/pages/Dashboard/Dashboard.tsx b/src/pages/Dashboard/Dashboard.tsx index 8a3f90a7..acf1ba81 100644 --- a/src/pages/Dashboard/Dashboard.tsx +++ b/src/pages/Dashboard/Dashboard.tsx @@ -1,89 +1,30 @@ -import { contractAddress } from 'config'; import { AuthRedirectWrapper } from 'wrappers'; -import { - Account, - PingPongAbi, - SignMessage, - NativeAuth, - BatchTransactions, - PingPongRaw, - PingPongService, - Transactions -} from './widgets'; +import { Account, NFTs, Tokens, Transactions } from './widgets'; import { useScrollToElement } from 'hooks'; import { Widget } from './components'; import { WidgetType } from 'types/widget.types'; const WIDGETS: WidgetType[] = [ { - title: 'Account', - widget: Account, - description: 'Connected account details', - 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, - description: - 'Smart Contract interactions using the ABI generated transactions', + title: 'Tokens', + widget: Tokens, + description: 'Tokens for the connected account', 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' + 'https://api.multiversx.com/#/accounts/AccountController_getAccountTokens' }, { - 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, - description: 'List transactions for the connected account', + title: 'NFTs', + widget: NFTs, + description: 'NFTs for the connected account', reference: - 'https://api.elrond.com/#/accounts/AccountController_getAccountTransactions' + 'https://api.multiversx.com/#/accounts/AccountController_getAccountNfts' }, { - title: 'Transactions (Ping & Pong)', + title: 'Transactions', widget: Transactions, - props: { receiver: contractAddress }, - description: 'List transactions filtered for a given Smart Contract', + description: 'Transactions list for the connected account', reference: - 'https://api.elrond.com/#/accounts/AccountController_getAccountTransactions' + 'https://api.multiversx.com/#/accounts/AccountController_getAccountTransactions' } ]; @@ -93,6 +34,7 @@ export const Dashboard = () => { return (
+ {WIDGETS.map((element) => ( ))} diff --git a/src/pages/Dashboard/widgets/Account/Account.tsx b/src/pages/Dashboard/widgets/Account/Account.tsx index f12352af..41d3f0ee 100644 --- a/src/pages/Dashboard/widgets/Account/Account.tsx +++ b/src/pages/Dashboard/widgets/Account/Account.tsx @@ -1,35 +1,77 @@ -import { Label } from 'components/Label'; -import { OutputContainer } from 'components/OutputContainer'; -import { FormatAmount } from 'components/sdkDappComponents'; +import QRCode from 'react-qr-code'; +import { FormatAmount } from 'components/sdkDapp.components'; import { useGetAccountInfo, useGetNetworkConfig } from 'hooks'; -import { Username } from './components'; +import { explorerAddressSelector } from '@multiversx/sdk-dapp/reduxStore/selectors/networkConfigSelectors'; +import { useSelector } from '@multiversx/sdk-dapp/reduxStore/DappProviderContext'; +import { Copy, MxLink } from 'components'; +import { RouteNamesEnum } from '../../../../localConstants'; export const Account = () => { const { network } = useGetNetworkConfig(); const { address, account } = useGetAccountInfo(); + const explorerAddress = useSelector(explorerAddressSelector); return ( - -
-

- - {address} -

- - -

- {account.shard} -

- -

- - +

+
+
+ Account +
+
+
Your address:
+
+ {address} + +
+
+
+ +
+
+
Your balance:
+
+
+ + + +
+
+
+
+ + Open in Explorer + + + Send + +
+
+
+ -

+
- +
); }; diff --git a/src/pages/Dashboard/widgets/Account/components/Username.tsx b/src/pages/Dashboard/widgets/Account/components/Username.tsx index 562a6b18..2e3cb210 100644 --- a/src/pages/Dashboard/widgets/Account/components/Username.tsx +++ b/src/pages/Dashboard/widgets/Account/components/Username.tsx @@ -1,6 +1,6 @@ import type { AccountType } from '@multiversx/sdk-dapp/types'; import { Label } from 'components/Label'; -import { trimUsernameDomain } from 'helpers/sdkDappHelpers'; +import { trimUsernameDomain } from 'helpers'; import { ProfileType } from 'types'; export const Username = (props: { diff --git a/src/pages/Dashboard/widgets/BatchTransactions/BatchTransactions.tsx b/src/pages/Dashboard/widgets/BatchTransactions/BatchTransactions.tsx deleted file mode 100644 index d1b9dfdd..00000000 --- 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 1bab02f4..00000000 --- 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 de77ec55..00000000 --- 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 815798d1..00000000 --- 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 52e67900..00000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/sendBatchTransactions.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { getBatchTransactions } from '../helpers'; -import { sendTransactions } from 'helpers/sdkDappHelpers'; -import { SessionEnum, isSafari } 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, - hasConsentPopup: isSafari - }); - - 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 416fcdb6..00000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/signAndAutoSendBatchTransactions.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { SessionEnum, isSafari } 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, - hasConsentPopup: isSafari - }); - 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 045e6b0d..00000000 --- a/src/pages/Dashboard/widgets/BatchTransactions/helpers/swapAndLockTokens.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { SessionEnum, isSafari } 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, - hasConsentPopup: isSafari - }); - - 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 e60e6be1..00000000 --- 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 03d4b14a..00000000 --- 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 38a28fc7..00000000 --- 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 0d3c5070..00000000 --- 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/NFTs/NFTs.tsx b/src/pages/Dashboard/widgets/NFTs/NFTs.tsx new file mode 100644 index 00000000..30ceed55 --- /dev/null +++ b/src/pages/Dashboard/widgets/NFTs/NFTs.tsx @@ -0,0 +1,36 @@ +import { OutputContainer } from 'components'; +import { useLazyGetNftsQuery } from 'redux/endpoints'; +import { useGetAccountInfo } from 'hooks'; +import { useEffect } from 'react'; +import { NFTRow } from './components'; +import { PartialNftType } from '@multiversx/sdk-dapp-form'; + +export const NFTs = () => { + const { websocketEvent, address } = useGetAccountInfo(); + const [fetchNFTs, { data: nfts, isLoading }] = useLazyGetNftsQuery(); + + useEffect(() => { + fetchNFTs({ address }); + }, [address, websocketEvent]); + + if (!isLoading && nfts?.length === 0) { + return ( + +

No NFTs found

+
+ ); + } + + return ( +
+ + {nfts?.map((nft: PartialNftType) => ( + + ))} + +
+ ); +}; diff --git a/src/pages/Dashboard/widgets/NFTs/components/NFTRow.tsx b/src/pages/Dashboard/widgets/NFTs/components/NFTRow.tsx new file mode 100644 index 00000000..85e92a09 --- /dev/null +++ b/src/pages/Dashboard/widgets/NFTs/components/NFTRow.tsx @@ -0,0 +1,29 @@ +import { NftEnumType } from '@multiversx/sdk-dapp/types/tokens.types'; +import { PartialNftType } from '@multiversx/sdk-dapp-form/types'; +import { CollectionTypeByNftEnum } from 'localConstants'; + +export const NFTRow = ({ nft }: { nft: PartialNftType }) => { + const nftType = + CollectionTypeByNftEnum[nft.type as NftEnumType].toUpperCase(); + + return ( +
+ {`${nft.identifier} +
+
+
+ {nft.balance ?? ''} {nft.name} +
+
{nftType}
+
+
+
{nft.collection}
+
+
+
+ ); +}; diff --git a/src/pages/Dashboard/widgets/NFTs/components/index.tsx b/src/pages/Dashboard/widgets/NFTs/components/index.tsx new file mode 100644 index 00000000..9d65f944 --- /dev/null +++ b/src/pages/Dashboard/widgets/NFTs/components/index.tsx @@ -0,0 +1 @@ +export * from './NFTRow'; diff --git a/src/pages/Dashboard/widgets/NFTs/index.tsx b/src/pages/Dashboard/widgets/NFTs/index.tsx new file mode 100644 index 00000000..c838a60d --- /dev/null +++ b/src/pages/Dashboard/widgets/NFTs/index.tsx @@ -0,0 +1 @@ +export * from './NFTs'; diff --git a/src/pages/Dashboard/widgets/NativeAuth/NativeAuth.tsx b/src/pages/Dashboard/widgets/NativeAuth/NativeAuth.tsx deleted file mode 100644 index 1ac50c13..00000000 --- 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 4c632360..00000000 --- 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 ce982c69..00000000 --- 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 91072c77..00000000 --- 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 3ff86c2b..00000000 --- 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/hooks/index.ts b/src/pages/Dashboard/widgets/PingPongAbi/hooks/index.ts deleted file mode 100644 index 6363b33d..00000000 --- a/src/pages/Dashboard/widgets/PingPongAbi/hooks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './useGetPingAmount'; -export * from './useGetTimeToPong'; diff --git a/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetPingAmount.ts b/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetPingAmount.ts deleted file mode 100644 index 0c8ea188..00000000 --- a/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetPingAmount.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { useEffect, useState } from 'react'; - -import { useGetNetworkConfig } from 'hooks'; -import { ContractFunction, ResultsParser, ProxyNetworkProvider } from 'utils'; -import { smartContract } from 'utils/smartContract'; - -const resultsParser = new ResultsParser(); - -export const useGetPingAmount = () => { - const { network } = useGetNetworkConfig(); - const [pingAmount, setPingAmount] = useState('0'); - - const proxy = new ProxyNetworkProvider(network.apiAddress); - - const getPingAmount = async () => { - try { - const query = smartContract.createQuery({ - func: new ContractFunction('getPingAmount') - }); - const queryResponse = await proxy.queryContract(query); - - const endpointDefinition = smartContract.getEndpoint('getPingAmount'); - - const { firstValue: amount } = resultsParser.parseQueryResponse( - queryResponse, - endpointDefinition - ); - - setPingAmount(amount?.valueOf()?.toString(10)); - } catch (err) { - console.error('Unable to call getPingAmount', err); - } - }; - - useEffect(() => { - getPingAmount(); - }, []); - - return pingAmount; -}; diff --git a/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetTimeToPong.ts b/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetTimeToPong.ts deleted file mode 100644 index 6bb2b183..00000000 --- a/src/pages/Dashboard/widgets/PingPongAbi/hooks/useGetTimeToPong.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ProxyNetworkProvider } from '@multiversx/sdk-network-providers'; -import { useGetAccount, useGetNetworkConfig } from 'hooks'; -import { Address, AddressValue, ContractFunction, ResultsParser } from 'utils'; -import { smartContract } from 'utils/smartContract'; - -const resultsParser = new ResultsParser(); - -export const useGetTimeToPong = () => { - const { network } = useGetNetworkConfig(); - const { address } = useGetAccount(); - - const getTimeToPong = async () => { - try { - const query = smartContract.createQuery({ - func: new ContractFunction('getTimeToPong'), - args: [new AddressValue(new Address(address))] - }); - const provider = new ProxyNetworkProvider(network.apiAddress); - const queryResponse = await provider.queryContract(query); - const endpointDefinition = smartContract.getEndpoint('getTimeToPong'); - const { firstValue } = resultsParser.parseQueryResponse( - queryResponse, - endpointDefinition - ); - const secondsRemaining: number = firstValue?.valueOf()?.toNumber(); - - return secondsRemaining; - } catch (err) { - console.error('Unable to call getTimeToPong', err); - } - }; - - return getTimeToPong; -}; diff --git a/src/pages/Dashboard/widgets/PingPongAbi/index.ts b/src/pages/Dashboard/widgets/PingPongAbi/index.ts deleted file mode 100644 index 0357fd74..00000000 --- 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 903716c4..00000000 --- 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 d2fbb30e..00000000 --- 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 85ca219e..00000000 --- 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 b8060d37..00000000 --- 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 3036394a..00000000 --- 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 715de75a..00000000 --- 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 f1a9438b..00000000 --- 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 bbb156ec..00000000 --- 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 b244cdd3..00000000 --- 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 f5899e48..00000000 --- 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 45268497..00000000 --- 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 8d3273da..00000000 --- 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 63e34053..00000000 --- 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 0216666d..00000000 --- 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 ac28c8d9..00000000 --- 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 e6d46ab1..00000000 --- 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 2227ec59..00000000 --- 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 f1a9438b..00000000 --- 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 5afb89cc..00000000 --- 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 ec87fa3f..00000000 --- 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 && ( -