From c57ac32ac37eb58b97f78889962097650274b58b Mon Sep 17 00:00:00 2001 From: Denis Nebytov Date: Wed, 8 Jul 2026 12:41:15 +0300 Subject: [PATCH 01/19] fix: correctness fixes and rename yoroiProvider to cardanoProvider - apiCard: use static HEIGHT_CLASSES map so Tailwind JIT keeps h-10/16/24 (dynamic h-${height} was purged, silently no-op'ing getAllInfoCard) - providers: fix useContext guards (=== undefined -> !context; default is null) - cardanoProvider: rename connect() param requestId -> requestIdentification - rename yoroiProvider -> cardanoProvider, useYoroi -> useCardano across 13 files --- src/App.js | 4 +-- src/components/accessButton.js | 4 +-- src/components/cards/apiCard.js | 10 ++++++- src/components/tabs/subtabs/NFTTab.js | 4 +-- src/components/tabs/subtabs/cip20Tab.js | 4 +-- src/components/tabs/subtabs/cip30Tab.js | 4 +-- src/components/tabs/subtabs/cip95Tab.js | 4 +-- src/components/tabs/subtabs/cip95ToolsTab.js | 4 +-- src/components/tabs/subtabs/stakingTab.js | 4 +-- src/components/tabs/subtabs/testTxsTab.js | 4 +-- src/components/tabs/subtabs/tokenTab.js | 4 +-- src/components/walletsModal.js | 4 +-- src/hooks/bitcoinProvider.js | 2 +- .../{yoroiProvider.js => cardanoProvider.js} | 30 +++++++++---------- src/hooks/ethereumProvider.js | 2 +- src/index.js | 6 ++-- 16 files changed, 51 insertions(+), 43 deletions(-) rename src/hooks/{yoroiProvider.js => cardanoProvider.js} (85%) diff --git a/src/App.js b/src/App.js index d0720c9..368bc1e 100644 --- a/src/App.js +++ b/src/App.js @@ -2,7 +2,7 @@ import React, {useEffect} from 'react' import AccessButton from './components/accessButton' import MainTab from './components/tabs/mainTab' import TabsComponent from './components/tabs/tabsComponent' -import useYoroi from './hooks/yoroiProvider' +import useCardano from './hooks/cardanoProvider' import useNetwork, {NETWORK_CARDANO, NETWORK_ETHEREUM} from './hooks/networkProvider' import BitcoinAccessButton from './components/bitcoinAccessButton' import BitcoinMainTab from './components/tabs/bitcoinMainTab' @@ -24,7 +24,7 @@ import EthTransactionsTab from './components/tabs/subtabs/ethTransactionsTab' import Erc20Tab from './components/tabs/subtabs/erc20Tab' const App = () => { - const {connectionState, selectedWallet, setConnectionState, setConnectionStateFalse} = useYoroi() + const {connectionState, selectedWallet, setConnectionState, setConnectionStateFalse} = useCardano() const {activeNetwork} = useNetwork() const isWalletConnected = connectionState === CONNECTED const isNoProvider = connectionState === NO_PROVIDER diff --git a/src/components/accessButton.js b/src/components/accessButton.js index 27559fa..158cb87 100644 --- a/src/components/accessButton.js +++ b/src/components/accessButton.js @@ -1,10 +1,10 @@ import React from 'react' -import useYoroi from '../hooks/yoroiProvider' +import useCardano from '../hooks/cardanoProvider' import {IN_PROGRESS} from '../utils/connectionStates' import WalletsModal from './walletsModal' const AccessButton = () => { - const {api, connectionState, availableWallets, selectedWallet} = useYoroi() + const {api, connectionState, availableWallets, selectedWallet} = useCardano() console.log(`[dApp][AccessButton] available wallets: ${availableWallets.length}`) const getWalletIcon = () => { diff --git a/src/components/cards/apiCard.js b/src/components/cards/apiCard.js index 7d522ed..73a5d8b 100644 --- a/src/components/cards/apiCard.js +++ b/src/components/cards/apiCard.js @@ -1,5 +1,13 @@ import React from 'react' +// Static map so Tailwind's JIT keeps these classes — `h-${height}` would be +// built at runtime and purged from the production build. +const HEIGHT_CLASSES = { + 10: 'h-10', + 16: 'h-16', + 24: 'h-24', +} + const ApiCard = (props) => { const {apiName, clickFunction, color, height} = props @@ -7,7 +15,7 @@ const ApiCard = (props) => { if (color != null) { localColor = color } - const localHeight = height == null ? 'h-16' : `h-${height}` + const localHeight = HEIGHT_CLASSES[height] || 'h-16' const localClassName = `w-full ${localHeight} ${localColor} disabled:bg-gray-800 rounded-lg text-white text-lg` diff --git a/src/components/tabs/subtabs/NFTTab.js b/src/components/tabs/subtabs/NFTTab.js index 39207bb..202a6a3 100644 --- a/src/components/tabs/subtabs/NFTTab.js +++ b/src/components/tabs/subtabs/NFTTab.js @@ -1,6 +1,6 @@ import {useState} from 'react' import {Buffer} from 'buffer' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import { getAddressFromBytes, getAssetName, @@ -39,7 +39,7 @@ const NFTTab = () => { {label: 'Video_WebM', value: 'video/webm'}, {label: 'Video_WMV', value: 'video/x-ms-wmv'}, ] - const {api, connectionState} = useYoroi() + const {api, connectionState} = useCardano() const [currentNFTName, setCurrentNFTName] = useState('') const [currentImageUrl, setCurrentImageUrl] = useState('') const [currentDescription, setCurrentDescription] = useState('') diff --git a/src/components/tabs/subtabs/cip20Tab.js b/src/components/tabs/subtabs/cip20Tab.js index 650a3b6..f89d41a 100644 --- a/src/components/tabs/subtabs/cip20Tab.js +++ b/src/components/tabs/subtabs/cip20Tab.js @@ -1,6 +1,6 @@ import React, {useState, useEffect, useMemo} from 'react' import Popup from 'reactjs-popup' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import {CONNECTED} from '../../../utils/connectionStates' import {hexToBytes} from '../../../utils/utils' import { @@ -55,7 +55,7 @@ const RawCborPopup = ({label, value}) => ( ) const Cip20Tab = () => { - const {api, connectionState} = useYoroi() + const {api, connectionState} = useCardano() const [hexUtxos, setHexUtxos] = useState([]) const [decodedUtxos, setDecodedUtxos] = useState([]) diff --git a/src/components/tabs/subtabs/cip30Tab.js b/src/components/tabs/subtabs/cip30Tab.js index d4d9bd3..f4d4f67 100644 --- a/src/components/tabs/subtabs/cip30Tab.js +++ b/src/components/tabs/subtabs/cip30Tab.js @@ -1,11 +1,11 @@ import React, {useState} from 'react' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import ResponsesPart from './responsesPart' import OfficialPart from './officialPart' import {CONNECTED} from '../../../utils/connectionStates' const Cip30Tab = () => { - const {api, connectionState, selectedWallet} = useYoroi() + const {api, connectionState, selectedWallet} = useCardano() const [currentText, setCurrentText] = useState('') const [rawCurrentText, setRawCurrentText] = useState('') const [waiterState, setWaiterState] = useState(false) diff --git a/src/components/tabs/subtabs/cip95Tab.js b/src/components/tabs/subtabs/cip95Tab.js index 4947664..6948761 100644 --- a/src/components/tabs/subtabs/cip95Tab.js +++ b/src/components/tabs/subtabs/cip95Tab.js @@ -1,11 +1,11 @@ import React, {useState} from 'react' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import ResponsesPart from './responsesPart' import {CONNECTED} from '../../../utils/connectionStates' import Cip95OfficialPart from './cip95OfficialPart' const Cip95Tab = () => { - const {api, connectionState} = useYoroi() + const {api, connectionState} = useCardano() const [currentText, setCurrentText] = useState('') const [rawCurrentText, setRawCurrentText] = useState('') const [waiterState, setWaiterState] = useState(false) diff --git a/src/components/tabs/subtabs/cip95ToolsTab.js b/src/components/tabs/subtabs/cip95ToolsTab.js index e310af4..16f4920 100644 --- a/src/components/tabs/subtabs/cip95ToolsTab.js +++ b/src/components/tabs/subtabs/cip95ToolsTab.js @@ -1,12 +1,12 @@ import {useState} from 'react' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import {CONNECTED} from '../../../utils/connectionStates' import Cip95AdditionalPart from './cip95AdditionalPart' import GetAllInfoCard from '../../cards/getAllInfoCard' import InfoPanel from './infoPanel' const Cip95TabTools = () => { - const {api, connectionState} = useYoroi() + const {api, connectionState} = useCardano() // Waiter label const [waiterState, setWaiterState] = useState(false) // Error label diff --git a/src/components/tabs/subtabs/stakingTab.js b/src/components/tabs/subtabs/stakingTab.js index 36b203a..6d2a7e9 100644 --- a/src/components/tabs/subtabs/stakingTab.js +++ b/src/components/tabs/subtabs/stakingTab.js @@ -1,11 +1,11 @@ import {useState} from 'react' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import {CONNECTED} from '../../../utils/connectionStates' import ResponsesPart from './responsesPart' import WithdrawCard from '../../cards/staking/withdrawCard' const Staking = () => { - const {api, connectionState} = useYoroi() + const {api, connectionState} = useCardano() const [currentText, setCurrentText] = useState('') const [rawCurrentText, setRawCurrentText] = useState('') const [waiterState, setWaiterState] = useState(false) diff --git a/src/components/tabs/subtabs/testTxsTab.js b/src/components/tabs/subtabs/testTxsTab.js index a3823d6..9d13056 100644 --- a/src/components/tabs/subtabs/testTxsTab.js +++ b/src/components/tabs/subtabs/testTxsTab.js @@ -1,5 +1,5 @@ import React, {useState, useEffect} from 'react' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import ResponsesPart from './responsesPart' import CheckboxWithLabel from '../../checkboxWithLabel' import ExpandablePanel from '../../expandablePanel' @@ -14,7 +14,7 @@ const defaultCredModes = () => Object.fromEntries([...CREDENTIAL_FEATURES].map((f) => [f, 'key'])) const TestTxsTab = () => { - const {api, connectionState} = useYoroi() + const {api, connectionState} = useCardano() const [enabledFeatures, setEnabledFeatures] = useState(new Set()) const [credModes, setCredModes] = useState(defaultCredModes) const [walletRewardAddrHex, setWalletRewardAddrHex] = useState(null) diff --git a/src/components/tabs/subtabs/tokenTab.js b/src/components/tabs/subtabs/tokenTab.js index 785041c..f5d06c7 100644 --- a/src/components/tabs/subtabs/tokenTab.js +++ b/src/components/tabs/subtabs/tokenTab.js @@ -1,5 +1,5 @@ import {useState} from 'react' -import useYoroi from '../../../hooks/yoroiProvider' +import useCardano from '../../../hooks/cardanoProvider' import { getAddressFromBytes, getAssetName, @@ -18,7 +18,7 @@ import {firstOrThrow} from '../../../utils/helpFunctions' import InputWithLabel from '../../inputWithLabel' const TokenTab = () => { - const {api, connectionState} = useYoroi() + const {api, connectionState} = useCardano() const [currentTokenName, setCurrentTokenName] = useState('') const [currentTokenTicker, setCurrentTokenTicker] = useState('') const [currentTokenDescription, setCurrentTokenDescription] = useState('') diff --git a/src/components/walletsModal.js b/src/components/walletsModal.js index 2560c80..69a7dff 100644 --- a/src/components/walletsModal.js +++ b/src/components/walletsModal.js @@ -1,10 +1,10 @@ import React, {useState} from 'react' import Popup from 'reactjs-popup' -import useYoroi from '../hooks/yoroiProvider' +import useCardano from '../hooks/cardanoProvider' import {NO_PROVIDER} from '../utils/connectionStates' const WalletsModal = () => { - const {connect, availableWallets, setSelectedWallet, connectionState} = useYoroi() + const {connect, availableWallets, setSelectedWallet, connectionState} = useCardano() const [selectedUserWallet, setSelectedUserWallet] = useState('') console.log(`[dApp][WalletsModal] is called`) diff --git a/src/hooks/bitcoinProvider.js b/src/hooks/bitcoinProvider.js index 38e8e58..5c9d5d9 100644 --- a/src/hooks/bitcoinProvider.js +++ b/src/hooks/bitcoinProvider.js @@ -50,7 +50,7 @@ export const BitcoinProvider = ({children}) => { const useBitcoin = () => { const context = React.useContext(BitcoinContext) - if (context === undefined) throw new Error('useBitcoin must be used within BitcoinProvider') + if (!context) throw new Error('useBitcoin must be used within BitcoinProvider') return context } diff --git a/src/hooks/yoroiProvider.js b/src/hooks/cardanoProvider.js similarity index 85% rename from src/hooks/yoroiProvider.js rename to src/hooks/cardanoProvider.js index 9a1caeb..a25f67a 100644 --- a/src/hooks/yoroiProvider.js +++ b/src/hooks/cardanoProvider.js @@ -1,7 +1,7 @@ import React, {useState, useEffect} from 'react' import {NOT_CONNECTED, IN_PROGRESS, CONNECTED, NO_PROVIDER} from '../utils/connectionStates' -const YoroiContext = React.createContext(null) +const CardanoContext = React.createContext(null) const reservedKeys = [ 'enable', 'isEnabled', @@ -22,8 +22,8 @@ const reservedKeys = [ '_events', ] -export const YoroiProvider = ({children}) => { - console.debug('[dApp][YoroiProvider] is called') +export const CardanoProvider = ({children}) => { + console.debug('[dApp][CardanoProvider] is called') const [api, setApi] = useState(null) const [connectionState, setConnectionState] = useState(NO_PROVIDER) const [availableWallets, setAvailableWallets] = useState([]) @@ -105,12 +105,12 @@ export const YoroiProvider = ({children}) => { /** * @param {string} walletName - A wallet name as it is presented in the Cardano object - * @param {bool} requestId - Request connection with or without required authentication - * @param {bool} silent - Request connection with or without showing the connection pop-up - * @param {bool} throwError - Throw an error which possibly can be while connecting to the wallet + * @param {boolean} requestIdentification - Request connection with or without required authentication + * @param {boolean} silent - Request connection with or without showing the connection pop-up + * @param {boolean} throwError - Throw an error which possibly can be while connecting to the wallet * @returns {Promise} */ - const connect = async (walletName, requestId, silent, throwError = false) => { + const connect = async (walletName, requestIdentification, silent, throwError = false) => { setConnectionState(IN_PROGRESS) setApi(null) console.debug(`[dApp][connect] is called`) @@ -122,11 +122,11 @@ export const YoroiProvider = ({children}) => { } console.log(`[dApp][connect] connecting the wallet "${walletName}"`) - console.debug(`[dApp][connect] {requestIdentification: ${requestId}, onlySilent: ${silent}}`) + console.debug(`[dApp][connect] {requestIdentification: ${requestIdentification}, onlySilent: ${silent}}`) try { const connectedApi = await window.cardano[walletName].enable({ - requestIdentification: requestId, + requestIdentification, onlySilent: silent, }) console.debug(`[dApp][connect] wallet API object is received`) @@ -190,17 +190,17 @@ export const YoroiProvider = ({children}) => { setSelectedWallet, } - return {children} + return {children} } -const useYoroi = () => { - const context = React.useContext(YoroiContext) +const useCardano = () => { + const context = React.useContext(CardanoContext) - if (context === undefined) { - throw new Error('Install Yoroi') + if (!context) { + throw new Error('useCardano must be used within CardanoProvider') } return context } -export default useYoroi +export default useCardano diff --git a/src/hooks/ethereumProvider.js b/src/hooks/ethereumProvider.js index f959d0b..e346fb9 100644 --- a/src/hooks/ethereumProvider.js +++ b/src/hooks/ethereumProvider.js @@ -98,7 +98,7 @@ export const EthereumProvider = ({children}) => { const useEthereum = () => { const context = React.useContext(EthereumContext) - if (context === undefined) throw new Error('useEthereum must be used within EthereumProvider') + if (!context) throw new Error('useEthereum must be used within EthereumProvider') return context } diff --git a/src/index.js b/src/index.js index 372e1de..458fae6 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import App from './App' -import {YoroiProvider} from './hooks/yoroiProvider' +import {CardanoProvider} from './hooks/cardanoProvider' import {NetworkProvider} from './hooks/networkProvider' import {EthereumProvider} from './hooks/ethereumProvider' import {BitcoinProvider} from './hooks/bitcoinProvider' @@ -12,7 +12,7 @@ const root = ReactDOM.createRoot(document.getElementById('root')) root.render( - + @@ -22,7 +22,7 @@ root.render( - + , ) From cb75f1f74fddb7ba940d5e64ccf9bb948f2190ac Mon Sep 17 00:00:00 2001 From: Denis Nebytov Date: Wed, 8 Jul 2026 12:49:30 +0300 Subject: [PATCH 02/19] refactor: memoize cardanoProvider and tidy index.js - Wrap cardanoProvider callbacks in useCallback and context value in useMemo (match ethereumProvider; avoids re-rendering all consumers each render) - Move connect() above the mount effect and add it to deps (stable identity) - Fix provider nesting indentation in index.js --- src/hooks/cardanoProvider.js | 118 +++++++++++++++++------------------ src/index.js | 10 +-- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/hooks/cardanoProvider.js b/src/hooks/cardanoProvider.js index a25f67a..e569961 100644 --- a/src/hooks/cardanoProvider.js +++ b/src/hooks/cardanoProvider.js @@ -1,4 +1,4 @@ -import React, {useState, useEffect} from 'react' +import React, {useState, useEffect, useCallback, useMemo} from 'react' import {NOT_CONNECTED, IN_PROGRESS, CONNECTED, NO_PROVIDER} from '../utils/connectionStates' const CardanoContext = React.createContext(null) @@ -29,10 +29,10 @@ export const CardanoProvider = ({children}) => { const [availableWallets, setAvailableWallets] = useState([]) const [selectedWallet, setSelectedWallet] = useState('') - const setConnectionStateFalse = () => { + const setConnectionStateFalse = useCallback(() => { setConnectionState(NOT_CONNECTED) setApi(null) - } + }, []) const getAvailableWallets = () => { // We need to filter like this because of the Nami wallet. @@ -46,6 +46,49 @@ export const CardanoProvider = ({children}) => { }) } + /** + * @param {string} walletName - A wallet name as it is presented in the Cardano object + * @param {boolean} requestIdentification - Request connection with or without required authentication + * @param {boolean} silent - Request connection with or without showing the connection pop-up + * @param {boolean} throwError - Throw an error which possibly can be while connecting to the wallet + * @returns {Promise} + */ + const connect = useCallback(async (walletName, requestIdentification, silent, throwError = false) => { + setConnectionState(IN_PROGRESS) + setApi(null) + console.debug(`[dApp][connect] is called`) + + if (!window.cardano) { + console.error('There are no cardano wallets are installed') + setConnectionState(NOT_CONNECTED) + return + } + + console.log(`[dApp][connect] connecting the wallet "${walletName}"`) + console.debug(`[dApp][connect] {requestIdentification: ${requestIdentification}, onlySilent: ${silent}}`) + + try { + const connectedApi = await window.cardano[walletName].enable({ + requestIdentification, + onlySilent: silent, + }) + console.debug(`[dApp][connect] wallet API object is received`) + setApi(connectedApi) + setSelectedWallet(walletName) + setConnectionState(CONNECTED) + return connectedApi + } catch (error) { + console.error(`[dApp][connect] The error received while connecting the wallet`) + setSelectedWallet('') + setConnectionState(NOT_CONNECTED) + if (throwError) { + throw new Error(JSON.stringify(error)) + } else { + console.error(`[dApp][connect] ${JSON.stringify(error)}`) + } + } + }, []) + useEffect(() => { if (!window.cardano) { console.warn('[dApp] There are no cardano wallets are installed') @@ -101,79 +144,36 @@ export const CardanoProvider = ({children}) => { } else { setConnectionState(NOT_CONNECTED); } - }, []) - - /** - * @param {string} walletName - A wallet name as it is presented in the Cardano object - * @param {boolean} requestIdentification - Request connection with or without required authentication - * @param {boolean} silent - Request connection with or without showing the connection pop-up - * @param {boolean} throwError - Throw an error which possibly can be while connecting to the wallet - * @returns {Promise} - */ - const connect = async (walletName, requestIdentification, silent, throwError = false) => { - setConnectionState(IN_PROGRESS) - setApi(null) - console.debug(`[dApp][connect] is called`) - - if (!window.cardano) { - console.error('There are no cardano wallets are installed') - setConnectionState(NOT_CONNECTED) - return - } - - console.log(`[dApp][connect] connecting the wallet "${walletName}"`) - console.debug(`[dApp][connect] {requestIdentification: ${requestIdentification}, onlySilent: ${silent}}`) + }, [connect]) - try { - const connectedApi = await window.cardano[walletName].enable({ - requestIdentification, - onlySilent: silent, - }) - console.debug(`[dApp][connect] wallet API object is received`) - setApi(connectedApi) - setSelectedWallet(walletName) - setConnectionState(CONNECTED) - return connectedApi - } catch (error) { - console.error(`[dApp][connect] The error received while connecting the wallet`) - setSelectedWallet('') - setConnectionState(NOT_CONNECTED) - if (throwError) { - throw new Error(JSON.stringify(error)) - } else { - console.error(`[dApp][connect] ${JSON.stringify(error)}`) - } - } - } - - const disconnect = () => { + const disconnect = useCallback(() => { setApi(null) setSelectedWallet('') setConnectionState(NOT_CONNECTED) - } + }, []) - const getAccounts = async () => { + const getAccounts = useCallback(async () => { if (!api) return [] return await api.getUsedAddresses() - } + }, [api]) - const getBalance = async () => { + const getBalance = useCallback(async () => { if (!api) return '0' return await api.getBalance() - } + }, [api]) - const sendTransaction = async (tx) => { + const sendTransaction = useCallback(async (tx) => { if (!api) throw new Error('Not connected') const signedTx = await api.signTx(tx) return await api.submitTx(signedTx) - } + }, [api]) - const signMessage = async (address, payload) => { + const signMessage = useCallback(async (address, payload) => { if (!api) throw new Error('Not connected') return await api.signData(address, payload) - } + }, [api]) - const values = { + const values = useMemo(() => ({ api, connect, disconnect, @@ -188,7 +188,7 @@ export const CardanoProvider = ({children}) => { setConnectionState, setConnectionStateFalse, setSelectedWallet, - } + }), [api, connect, disconnect, getAccounts, getBalance, sendTransaction, signMessage, connectionState, availableWallets, selectedWallet, setConnectionStateFalse]) return {children} } diff --git a/src/index.js b/src/index.js index 458fae6..135b8ca 100644 --- a/src/index.js +++ b/src/index.js @@ -15,11 +15,11 @@ root.render( - - - } /> - - + + + } /> + + From 5c50a61835d6ed1333ac6de427d0862bbee9a30f Mon Sep 17 00:00:00 2001 From: Denis Nebytov Date: Wed, 8 Jul 2026 13:01:25 +0300 Subject: [PATCH 03/19] refactor: add debug-gated logger, replace console.* calls - Add src/utils/logger.js: debug/log/info gated on NODE_ENV==='development' or REACT_APP_DEBUG==='true'; warn/error always print - Route all 159 console.* calls across 53 files through logger.* --- src/App.js | 7 ++-- src/components/accessButton.js | 3 +- src/components/cards/apiCardWithModal.js | 5 ++- .../cards/cip95BuildSignSubmitCard.js | 9 +++-- src/components/cards/cip95SignDataCard.js | 3 +- .../cards/cip95getPubDRepKeyCard.js | 3 +- .../cip95getRegisteredPubStakeKeysCard.js | 5 ++- .../cip95getUnregisteredPubStakeKeysCard.js | 5 ++- src/components/cards/createRandomKeyCard.js | 3 +- .../cards/ethereum/getAccountsCard.js | 3 +- .../cards/ethereum/getChainIdCard.js | 3 +- .../cards/ethereum/getErc20BalanceCard.js | 3 +- .../cards/ethereum/getEthBalanceCard.js | 3 +- .../cards/ethereum/sendEthTransactionCard.js | 3 +- .../cards/ethereum/signEthMessageCard.js | 3 +- .../cards/ethereum/transferErc20Card.js | 3 +- src/components/cards/getAllInfoCard.js | 37 ++++++++++--------- src/components/cards/getBalanceCard.js | 3 +- src/components/cards/getChangeAddressCard.js | 3 +- .../cards/getCollateralUtxosCard.js | 3 +- src/components/cards/getExtensionsCard.js | 3 +- src/components/cards/getNetworkIdCard.js | 3 +- .../cards/getRewardAddressesCard.js | 3 +- src/components/cards/getUnusedAddressCard.js | 3 +- src/components/cards/getUsedAddressCard.js | 3 +- src/components/cards/getUtxosCard.js | 3 +- .../cards/govActions/authCCPanel.js | 3 +- .../cards/govActions/dRepRegistrationPanel.js | 3 +- .../cards/govActions/dRepRetirementPanel.js | 3 +- .../cards/govActions/dRepUpdatePanel.js | 3 +- .../cards/govActions/regStakeKeyPanel.js | 5 ++- .../cards/govActions/unregStakeKeyPanel.js | 5 ++- .../cards/govActions/voteDelegationPanel.js | 3 +- src/components/cards/govActions/votePanel.js | 3 +- src/components/cards/govToolsPanel.js | 3 +- src/components/cards/isEnabledCard.js | 3 +- src/components/cards/listNFTsCard.js | 3 +- src/components/cards/signDataCard.js | 5 ++- src/components/cards/signTransactionCard.js | 5 ++- src/components/cards/staking/withdrawCard.js | 9 +++-- src/components/cards/submitTransactionCard.js | 3 +- src/components/tabs/subtabs/NFTTab.js | 35 +++++++++--------- .../tabs/subtabs/certificatesInTxPart.js | 3 +- .../tabs/subtabs/cip95AdditionalPart.js | 5 ++- .../tabs/subtabs/govBasicFunctionsTab.js | 3 +- src/components/tabs/subtabs/responsesPart.js | 9 +++-- src/components/tabs/subtabs/testTxsTab.js | 9 +++-- src/components/tabs/subtabs/tokenTab.js | 25 +++++++------ src/components/walletsModal.js | 7 ++-- src/hooks/bitcoinProvider.js | 15 ++++---- src/hooks/cardanoProvider.js | 33 +++++++++-------- src/hooks/ethereumProvider.js | 15 ++++---- src/utils/cslTools.js | 25 +++++++------ src/utils/logger.js | 24 ++++++++++++ 54 files changed, 236 insertions(+), 159 deletions(-) create mode 100644 src/utils/logger.js diff --git a/src/App.js b/src/App.js index 368bc1e..4d1f44a 100644 --- a/src/App.js +++ b/src/App.js @@ -1,3 +1,4 @@ +import logger from './utils/logger' import React, {useEffect} from 'react' import AccessButton from './components/accessButton' import MainTab from './components/tabs/mainTab' @@ -42,7 +43,7 @@ const App = () => { useEffect(() => { const getConnectionState = async () => { - console.debug(`[dApp][App] Checking connection works`) + logger.debug(`[dApp][App] Checking connection works`) try { const walletObject = window.cardano[selectedWallet] const conState = await walletStateWithTimeout(walletObject, 10000) @@ -54,14 +55,14 @@ const App = () => { } } catch (error) { setConnectionStateFalse() - console.error(error) + logger.error(error) } } if (isWalletConnected) { const connectionTimer = setInterval(getConnectionState, 10000) return () => { - console.debug(`[dApp][App] Checking connection is stopped`) + logger.debug(`[dApp][App] Checking connection is stopped`) clearInterval(connectionTimer) } } diff --git a/src/components/accessButton.js b/src/components/accessButton.js index 158cb87..5fe070f 100644 --- a/src/components/accessButton.js +++ b/src/components/accessButton.js @@ -1,3 +1,4 @@ +import logger from '../utils/logger' import React from 'react' import useCardano from '../hooks/cardanoProvider' import {IN_PROGRESS} from '../utils/connectionStates' @@ -5,7 +6,7 @@ import WalletsModal from './walletsModal' const AccessButton = () => { const {api, connectionState, availableWallets, selectedWallet} = useCardano() - console.log(`[dApp][AccessButton] available wallets: ${availableWallets.length}`) + logger.log(`[dApp][AccessButton] available wallets: ${availableWallets.length}`) const getWalletIcon = () => { return window.cardano[selectedWallet].icon diff --git a/src/components/cards/apiCardWithModal.js b/src/components/cards/apiCardWithModal.js index 0c0cf43..881ecdd 100644 --- a/src/components/cards/apiCardWithModal.js +++ b/src/components/cards/apiCardWithModal.js @@ -1,13 +1,14 @@ +import logger from '../../utils/logger' import Popup from 'reactjs-popup' export const ApiCardWithModal = (props) => { const {buttonLabel, clickFunction, halfOpacity, children, btnDisabled} = props const handleActionAndClose = (closeFunc) => { - console.log(`[dApp][ApiCardWithModal][${buttonLabel}] is called`) + logger.log(`[dApp][ApiCardWithModal][${buttonLabel}] is called`) clickFunction() closeFunc() - console.log(`[dApp][ApiCardWithModal][${buttonLabel}] is closed`) + logger.log(`[dApp][ApiCardWithModal][${buttonLabel}] is closed`) } const overlayStyle = {background: 'rgba(0,0,0,0.75)'} diff --git a/src/components/cards/cip95BuildSignSubmitCard.js b/src/components/cards/cip95BuildSignSubmitCard.js index 42a04f7..1ab764d 100644 --- a/src/components/cards/cip95BuildSignSubmitCard.js +++ b/src/components/cards/cip95BuildSignSubmitCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import { getAddressFromBech32, getCslUtxos, @@ -17,7 +18,7 @@ const Cip95BuildSignSubmitCard = (props) => { const errorHappen = (errorMessage) => { onWaiting(false) onError() - console.error(errorMessage) + logger.error(errorMessage) } const buildSignSubmit = async () => { @@ -55,7 +56,7 @@ const Cip95BuildSignSubmitCard = (props) => { const wasmUnsignedTransaction = txBuilder.build_tx() // sign Tx const fixedTx = getFixedTxFromBytes(wasmUnsignedTransaction.to_bytes()) - console.log('[Cip95BuildSignSubmitCard] Unsigned Tx:', fixedTx.to_hex()) + logger.log('[Cip95BuildSignSubmitCard] Unsigned Tx:', fixedTx.to_hex()) const witnessHex = await api?.signTx(fixedTx.to_hex()) const wasmWitnessSet = getTransactionWitnessSetFromBytes(witnessHex) const vkeys = wasmWitnessSet.vkeys() @@ -63,9 +64,9 @@ const Cip95BuildSignSubmitCard = (props) => { fixedTx.add_vkey_witness(vkeys.get(i)) } const signedTxHex = fixedTx.to_hex() - console.log('Signed Tx:', signedTxHex) + logger.log('Signed Tx:', signedTxHex) const txId = await api?.submitTx(signedTxHex) - console.log('The transaction is sent:', txId) + logger.log('The transaction is sent:', txId) } catch (e) { errorHappen(e) } finally { diff --git a/src/components/cards/cip95SignDataCard.js b/src/components/cards/cip95SignDataCard.js index 236a450..a89166e 100644 --- a/src/components/cards/cip95SignDataCard.js +++ b/src/components/cards/cip95SignDataCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {Buffer} from 'buffer' @@ -35,7 +36,7 @@ const Cip95SignDataCard = ({api, onRawResponse, onResponse, onWaiting}) => { } else { onResponse(error) } - console.error(error) + logger.error(error) } finally { onWaiting(false) } diff --git a/src/components/cards/cip95getPubDRepKeyCard.js b/src/components/cards/cip95getPubDRepKeyCard.js index 088d073..ae1b6e1 100644 --- a/src/components/cards/cip95getPubDRepKeyCard.js +++ b/src/components/cards/cip95getPubDRepKeyCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { getPublicKeyFromHex } from '../../utils/cslTools' @@ -22,7 +23,7 @@ const Cip95GetPubDRepKeyCard = ({api, onRawResponse, onResponse, onWaiting}) => onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/cip95getRegisteredPubStakeKeysCard.js b/src/components/cards/cip95getRegisteredPubStakeKeysCard.js index 5de1dc8..96efa55 100644 --- a/src/components/cards/cip95getRegisteredPubStakeKeysCard.js +++ b/src/components/cards/cip95getRegisteredPubStakeKeysCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { getPublicKeyFromHex } from '../../utils/cslTools' @@ -8,7 +9,7 @@ const Cip95GetRegisteredPubStakeKeysCard = ({api, onRawResponse, onResponse, onW api?.cip95 .getRegisteredPubStakeKeys() .then((regPubStakeKeys) => { - console.log('regPubStakeKeys: ', regPubStakeKeys) + logger.log('regPubStakeKeys: ', regPubStakeKeys) onWaiting(false) onRawResponse(regPubStakeKeys) if (regPubStakeKeys.length < 1) { @@ -23,7 +24,7 @@ const Cip95GetRegisteredPubStakeKeysCard = ({api, onRawResponse, onResponse, onW onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js b/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js index 05b67b1..e346c15 100644 --- a/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js +++ b/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { getPublicKeyFromHex } from '../../utils/cslTools' @@ -8,7 +9,7 @@ const Cip95GetUnregisteredPubStakeKeysCard = ({api, onRawResponse, onResponse, o api?.cip95 .getUnregisteredPubStakeKeys() .then((unregPubStakeKeys) => { - console.log('unregPubStakeKeys: ', unregPubStakeKeys) + logger.log('unregPubStakeKeys: ', unregPubStakeKeys) onWaiting(false) onRawResponse(unregPubStakeKeys) if (unregPubStakeKeys.length < 1) { @@ -23,7 +24,7 @@ const Cip95GetUnregisteredPubStakeKeysCard = ({api, onRawResponse, onResponse, o onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/createRandomKeyCard.js b/src/components/cards/createRandomKeyCard.js index d3df1b2..40ec8fa 100644 --- a/src/components/cards/createRandomKeyCard.js +++ b/src/components/cards/createRandomKeyCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { getAddressFromCred, getCredential, getSecretKey } from '../../utils/cslTools' @@ -24,7 +25,7 @@ const CreateRandomKeyPart = ({onRawResponse, onResponse, onWaiting}) => { } catch(e) { onRawResponse(''); onResponse(e); - console.error(e); + logger.error(e); } finally { onWaiting(false); } diff --git a/src/components/cards/ethereum/getAccountsCard.js b/src/components/cards/ethereum/getAccountsCard.js index c886f05..df8416a 100644 --- a/src/components/cards/ethereum/getAccountsCard.js +++ b/src/components/cards/ethereum/getAccountsCard.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React from 'react' import ApiCard from '../apiCard' @@ -15,7 +16,7 @@ const GetAccountsCard = ({onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) }) } diff --git a/src/components/cards/ethereum/getChainIdCard.js b/src/components/cards/ethereum/getChainIdCard.js index 38fb6f0..eb7338d 100644 --- a/src/components/cards/ethereum/getChainIdCard.js +++ b/src/components/cards/ethereum/getChainIdCard.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React from 'react' import ApiCard from '../apiCard' @@ -15,7 +16,7 @@ const GetChainIdCard = ({onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) }) } diff --git a/src/components/cards/ethereum/getErc20BalanceCard.js b/src/components/cards/ethereum/getErc20BalanceCard.js index 6c76f51..e88dfa8 100644 --- a/src/components/cards/ethereum/getErc20BalanceCard.js +++ b/src/components/cards/ethereum/getErc20BalanceCard.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' /* global BigInt */ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' @@ -33,7 +34,7 @@ const GetErc20BalanceCard = ({accounts, onRawResponse, onResponse, onWaiting}) = } catch (e) { onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) } finally { onWaiting(false) } diff --git a/src/components/cards/ethereum/getEthBalanceCard.js b/src/components/cards/ethereum/getEthBalanceCard.js index 7b1561d..14de94f 100644 --- a/src/components/cards/ethereum/getEthBalanceCard.js +++ b/src/components/cards/ethereum/getEthBalanceCard.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React from 'react' import ApiCard from '../apiCard' import {weiHexToEth} from '../../../utils/ethereumUtils' @@ -20,7 +21,7 @@ const GetEthBalanceCard = ({accounts, onRawResponse, onResponse, onWaiting}) => onWaiting(false) onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) }) } diff --git a/src/components/cards/ethereum/sendEthTransactionCard.js b/src/components/cards/ethereum/sendEthTransactionCard.js index 4cb464d..f909460 100644 --- a/src/components/cards/ethereum/sendEthTransactionCard.js +++ b/src/components/cards/ethereum/sendEthTransactionCard.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../../ui-constants' @@ -29,7 +30,7 @@ const SendEthTransactionCard = ({accounts, onRawResponse, onResponse, onWaiting} } catch (e) { onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) } finally { onWaiting(false) } diff --git a/src/components/cards/ethereum/signEthMessageCard.js b/src/components/cards/ethereum/signEthMessageCard.js index 990f77d..4a3ae95 100644 --- a/src/components/cards/ethereum/signEthMessageCard.js +++ b/src/components/cards/ethereum/signEthMessageCard.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../../ui-constants' @@ -21,7 +22,7 @@ const SignEthMessageCard = ({accounts, onRawResponse, onResponse, onWaiting}) => } catch (e) { onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) } finally { onWaiting(false) } diff --git a/src/components/cards/ethereum/transferErc20Card.js b/src/components/cards/ethereum/transferErc20Card.js index d143239..2f2e3ff 100644 --- a/src/components/cards/ethereum/transferErc20Card.js +++ b/src/components/cards/ethereum/transferErc20Card.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' /* global BigInt */ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' @@ -32,7 +33,7 @@ const TransferErc20Card = ({accounts, onRawResponse, onResponse, onWaiting}) => } catch (e) { onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) } finally { onWaiting(false) } diff --git a/src/components/cards/getAllInfoCard.js b/src/components/cards/getAllInfoCard.js index ddb4cc0..995f6f3 100644 --- a/src/components/cards/getAllInfoCard.js +++ b/src/components/cards/getAllInfoCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { @@ -30,102 +31,102 @@ const GetAllInfoCard = ({api, onWaiting, onError, setters}) => { onWaiting(true) getBalance(api) .then((adaValue) => { - console.log('[dApp][GetAllInfoCard][getBalance]: ', adaValue) + logger.log('[dApp][GetAllInfoCard][getBalance]: ', adaValue) setBalance(adaValue) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getUTxOs(api) .then((utxos) => { - console.log('[dApp][GetAllInfoCard][getUTxOs]: ', utxos) + logger.log('[dApp][GetAllInfoCard][getUTxOs]: ', utxos) setAndMapUtxos(utxos) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getChangeAddress(api) .then((bech32Addr) => { - console.log('[dApp][GetAllInfoCard][getChangeAddress]: ', bech32Addr) + logger.log('[dApp][GetAllInfoCard][getChangeAddress]: ', bech32Addr) setChangeAddress(bech32Addr) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getRewardAddress(api) .then((bech32Addr) => { - console.log('[dApp][GetAllInfoCard][getRewardAddress]: ', bech32Addr) + logger.log('[dApp][GetAllInfoCard][getRewardAddress]: ', bech32Addr) setRewardAddress(bech32Addr) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getUsedAddress(api) .then((bech32Addr) => { - console.log('[dApp][GetAllInfoCard][getUsedAddress]: ', bech32Addr) + logger.log('[dApp][GetAllInfoCard][getUsedAddress]: ', bech32Addr) setUsedAddress(bech32Addr) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getUnusedAddress(api) .then((bech32Addr) => { - console.log('[dApp][GetAllInfoCard][getUnusedAddress]: ', bech32Addr) + logger.log('[dApp][GetAllInfoCard][getUnusedAddress]: ', bech32Addr) setUnusedAddress(bech32Addr) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getPubDRepKey(api) .then((drepKey) => { - console.log('[dApp][GetAllInfoCard][getPubDRepKey]: ', drepKey) + logger.log('[dApp][GetAllInfoCard][getPubDRepKey]: ', drepKey) setDRepIdBech32(drepKey.dRepIDBech32) setDRepIdHex(drepKey.dRepIDHex) setDRepIdInputValue(drepKey.dRepIDBech32) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getRegPubStakeKey(api) .then((stakeKeyHash) => { - console.log('[dApp][GetAllInfoCard][getRegPubStakeKey]: ', stakeKeyHash) + logger.log('[dApp][GetAllInfoCard][getRegPubStakeKey]: ', stakeKeyHash) setRegPubStakeKey(stakeKeyHash) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) getUnregPubStakeKey(api) .then((stakeKeyHash) => { - console.log('[dApp][GetAllInfoCard][getUnregPubStakeKey]: ', stakeKeyHash) + logger.log('[dApp][GetAllInfoCard][getUnregPubStakeKey]: ', stakeKeyHash) setUnregPubStakeKey(stakeKeyHash) onWaiting(false) }) .catch((e) => { - console.error(e) + logger.error(e) onWaiting(false) onError() }) diff --git a/src/components/cards/getBalanceCard.js b/src/components/cards/getBalanceCard.js index 9a246dd..3fb79a8 100644 --- a/src/components/cards/getBalanceCard.js +++ b/src/components/cards/getBalanceCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import {wasmMultiassetToJSONs} from '../../utils/utils' import ApiCard from './apiCard' @@ -20,7 +21,7 @@ const GetBalanceCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getChangeAddressCard.js b/src/components/cards/getChangeAddressCard.js index 39bcb3f..ee5adc7 100644 --- a/src/components/cards/getChangeAddressCard.js +++ b/src/components/cards/getChangeAddressCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import {getBech32AddressFromHex} from '../../utils/cslTools' @@ -16,7 +17,7 @@ const GetChangeAddressCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getCollateralUtxosCard.js b/src/components/cards/getCollateralUtxosCard.js index a55d3e2..e881a7c 100644 --- a/src/components/cards/getCollateralUtxosCard.js +++ b/src/components/cards/getCollateralUtxosCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {CommonStyles, ModalWindowContent} from '../ui-constants' @@ -25,7 +26,7 @@ const GetCollateralUtxosCard = ({api, onRawResponse, onResponse, onWaiting}) => onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getExtensionsCard.js b/src/components/cards/getExtensionsCard.js index 27c9d15..68822c5 100644 --- a/src/components/cards/getExtensionsCard.js +++ b/src/components/cards/getExtensionsCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' @@ -14,7 +15,7 @@ const GetExtensionsCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getNetworkIdCard.js b/src/components/cards/getNetworkIdCard.js index c5ba731..0b84a80 100644 --- a/src/components/cards/getNetworkIdCard.js +++ b/src/components/cards/getNetworkIdCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' @@ -15,7 +16,7 @@ const GetNetworkIdCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getRewardAddressesCard.js b/src/components/cards/getRewardAddressesCard.js index bd4b0a8..d370954 100644 --- a/src/components/cards/getRewardAddressesCard.js +++ b/src/components/cards/getRewardAddressesCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import {getBech32AddressFromHex} from '../../utils/cslTools' @@ -20,7 +21,7 @@ const GetRewardAddressesCard = ({api, onRawResponse, onResponse, onWaiting}) => onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getUnusedAddressCard.js b/src/components/cards/getUnusedAddressCard.js index b6e8faf..3461840 100644 --- a/src/components/cards/getUnusedAddressCard.js +++ b/src/components/cards/getUnusedAddressCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import {getBech32AddressFromHex} from '../../utils/cslTools' @@ -20,7 +21,7 @@ const GetUnusedAddressesCard = ({api, onRawResponse, onResponse, onWaiting}) => onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getUsedAddressCard.js b/src/components/cards/getUsedAddressCard.js index dbcddad..37bd7c7 100644 --- a/src/components/cards/getUsedAddressCard.js +++ b/src/components/cards/getUsedAddressCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React, {useState} from 'react' import {getBech32AddressFromHex} from '../../utils/cslTools' import ApiCardWithModal from './apiCardWithModal' @@ -23,7 +24,7 @@ const GetUsedAddresses = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/getUtxosCard.js b/src/components/cards/getUtxosCard.js index b94f636..c744699 100644 --- a/src/components/cards/getUtxosCard.js +++ b/src/components/cards/getUtxosCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../ui-constants' @@ -24,7 +25,7 @@ const GetUtxosCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/govActions/authCCPanel.js b/src/components/cards/govActions/authCCPanel.js index b8ff295..7b8771f 100644 --- a/src/components/cards/govActions/authCCPanel.js +++ b/src/components/cards/govActions/authCCPanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import InputWithLabel from '../../inputWithLabel' import { @@ -41,7 +42,7 @@ const AuthCCPanel = (props) => { handleAddingCertInTx(certBuilder) onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govActions/dRepRegistrationPanel.js b/src/components/cards/govActions/dRepRegistrationPanel.js index 1d51fc6..fb0d402 100644 --- a/src/components/cards/govActions/dRepRegistrationPanel.js +++ b/src/components/cards/govActions/dRepRegistrationPanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import GovToolsPanel from '../govToolsPanel' import InputWithLabel from '../../inputWithLabel' @@ -34,7 +35,7 @@ const DRepRegistrationPanel = (props) => { handleAddingCertInTx(certBuilder) onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govActions/dRepRetirementPanel.js b/src/components/cards/govActions/dRepRetirementPanel.js index 39546ae..bfc3bb9 100644 --- a/src/components/cards/govActions/dRepRetirementPanel.js +++ b/src/components/cards/govActions/dRepRetirementPanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import GovToolsPanel from '../govToolsPanel' import InputWithLabel from '../../inputWithLabel' @@ -20,7 +21,7 @@ const DRepRetirementPanel = (props) => { handleAddingCertInTx(certBuilder) onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govActions/dRepUpdatePanel.js b/src/components/cards/govActions/dRepUpdatePanel.js index 796be13..dbad4e1 100644 --- a/src/components/cards/govActions/dRepUpdatePanel.js +++ b/src/components/cards/govActions/dRepUpdatePanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import GovToolsPanel from '../govToolsPanel' import InputWithLabel from '../../inputWithLabel' @@ -35,7 +36,7 @@ const DRepUpdatePanel = (props) => { handleAddingCertInTx(certBuilder) onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govActions/regStakeKeyPanel.js b/src/components/cards/govActions/regStakeKeyPanel.js index 1cefbda..4bb983b 100644 --- a/src/components/cards/govActions/regStakeKeyPanel.js +++ b/src/components/cards/govActions/regStakeKeyPanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import CheckboxWithLabel from '../../checkboxWithLabel' import InputWithLabel from '../../inputWithLabel' @@ -17,7 +18,7 @@ const RegisterStakeKeyPanel = (props) => { const handleUseConwayCert = () => { setUseConway(!useConway) - console.debug(`[dApp][RegisterStakeKeyPanel] use Conway Stake Registration Certificate is set: ${!useConway}`) + logger.debug(`[dApp][RegisterStakeKeyPanel] use Conway Stake Registration Certificate is set: ${!useConway}`) } const buildRegStakeKey = () => { @@ -36,7 +37,7 @@ const RegisterStakeKeyPanel = (props) => { handleAddingCertInTx(certBuilder) onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govActions/unregStakeKeyPanel.js b/src/components/cards/govActions/unregStakeKeyPanel.js index 0eef56f..94d339b 100644 --- a/src/components/cards/govActions/unregStakeKeyPanel.js +++ b/src/components/cards/govActions/unregStakeKeyPanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' import GovToolsPanel from '../govToolsPanel' import CheckboxWithLabel from '../../checkboxWithLabel' @@ -16,7 +17,7 @@ const UnregisterStakeKeyPanel = (props) => { const handleUseConwayCert = () => { setUseConway(!useConway) - console.debug(`[dApp][UnregisterStakeKeyPanel] use Conway Stake Registration Certificate is set: ${!useConway}`) + logger.debug(`[dApp][UnregisterStakeKeyPanel] use Conway Stake Registration Certificate is set: ${!useConway}`) } const buildUnregStakeKey = () => { @@ -34,7 +35,7 @@ const UnregisterStakeKeyPanel = (props) => { handleAddingCertInTx(certBuilder) onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govActions/voteDelegationPanel.js b/src/components/cards/govActions/voteDelegationPanel.js index 3204dc4..7753e6a 100644 --- a/src/components/cards/govActions/voteDelegationPanel.js +++ b/src/components/cards/govActions/voteDelegationPanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import {useState} from 'react' import InputWithLabel from '../../inputWithLabel' import { @@ -65,7 +66,7 @@ const VoteDelegationPanel = (props) => { } onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govActions/votePanel.js b/src/components/cards/govActions/votePanel.js index e2ca01b..02ec16f 100644 --- a/src/components/cards/govActions/votePanel.js +++ b/src/components/cards/govActions/votePanel.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import {useState} from 'react' import InputWithLabel from '../../inputWithLabel' import GovToolsPanel from '../govToolsPanel' @@ -56,7 +57,7 @@ const VotePanel = (props) => { handleAddingVotesInTx(votingBuilder) onWaiting(false) } catch (error) { - console.error(error) + logger.error(error) onWaiting(false) onError() } diff --git a/src/components/cards/govToolsPanel.js b/src/components/cards/govToolsPanel.js index 8c14742..629c928 100644 --- a/src/components/cards/govToolsPanel.js +++ b/src/components/cards/govToolsPanel.js @@ -1,10 +1,11 @@ +import logger from '../../utils/logger' import React from 'react' import {ModalWindowContent} from '../ui-constants' const GovToolsPanel = (props) => { const {buttonName, certLabel, clickFunction, children} = props const handleAction = () => { - console.log(`[dApp][GovToolsPanel][${certLabel}] Building is called`) + logger.log(`[dApp][GovToolsPanel][${certLabel}] Building is called`) // action here clickFunction() } diff --git a/src/components/cards/isEnabledCard.js b/src/components/cards/isEnabledCard.js index ea9651f..5449e92 100644 --- a/src/components/cards/isEnabledCard.js +++ b/src/components/cards/isEnabledCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import ApiCard from './apiCard' const IsEnabledCard = ({onRawResponse, onResponse, onWaiting, selectedWallet}) => { @@ -14,7 +15,7 @@ const IsEnabledCard = ({onRawResponse, onResponse, onWaiting, selectedWallet}) = onWaiting(false) onRawResponse('') onResponse(e) - console.error(e) + logger.error(e) }) } diff --git a/src/components/cards/listNFTsCard.js b/src/components/cards/listNFTsCard.js index f5eb9a5..a53efa3 100644 --- a/src/components/cards/listNFTsCard.js +++ b/src/components/cards/listNFTsCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' @@ -15,7 +16,7 @@ const ListNFTsCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/cards/signDataCard.js b/src/components/cards/signDataCard.js index 4dc9460..b046317 100644 --- a/src/components/cards/signDataCard.js +++ b/src/components/cards/signDataCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {Buffer} from 'buffer' @@ -57,7 +58,7 @@ const SignDataCard = ({api, onRawResponse, onResponse, onWaiting}) => { const payloadHex = getPayloadHex(message, encodingType) // Log the inputs for debugging - console.log('SignData inputs:', { address, payloadHex, originalMessage: message, encodingType }) + logger.log('SignData inputs:', { address, payloadHex, originalMessage: message, encodingType }) const signDataResponse = await api?.signData(address, payloadHex) @@ -81,7 +82,7 @@ const SignDataCard = ({api, onRawResponse, onResponse, onWaiting}) => { } else { onResponse(error) } - console.error(error) + logger.error(error) } finally { onWaiting(false) } diff --git a/src/components/cards/signTransactionCard.js b/src/components/cards/signTransactionCard.js index f80c65c..299bf52 100644 --- a/src/components/cards/signTransactionCard.js +++ b/src/components/cards/signTransactionCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React, {useState} from 'react' import {bytesToHex, hexToBytes} from '../../utils/utils' import { @@ -46,7 +47,7 @@ const SignTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { if (!txHex) { txHex = await buildTransaction(defaultValue) } - console.log('[SignTransactionCard] Unsingned Tx:', txHex) + logger.log('[SignTransactionCard] Unsingned Tx:', txHex) api ?.signTx(txHex, partialSign) .then((witnessHex) => { @@ -69,7 +70,7 @@ const SignTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } const apiProps = { diff --git a/src/components/cards/staking/withdrawCard.js b/src/components/cards/staking/withdrawCard.js index 0d88627..faf50b8 100644 --- a/src/components/cards/staking/withdrawCard.js +++ b/src/components/cards/staking/withdrawCard.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import { getAddressFromBytes, getCertificateBuilder, @@ -75,7 +76,7 @@ const WithdrawCard = ({api, onRawResponse, onResponse, onWaiting}) => { setShowSuccessInfo(true) } catch (error) { setErrorMessage('Network error occurred while fetching account info') - console.error(error) + logger.error(error) } finally { setWaitingAccountInfo(false) } @@ -108,7 +109,7 @@ const WithdrawCard = ({api, onRawResponse, onResponse, onWaiting}) => { const tx = txBuilderWithWithdrawal.build_tx() const fixedTx = getFixedTxFromBytes(tx.to_bytes()) - console.log('[WithdrawCard] Unsingned Tx:', fixedTx) + logger.log('[WithdrawCard] Unsingned Tx:', fixedTx) const signaturesWitnessesSet = await api.signTx(fixedTx.to_hex()) const witnesses = getTransactionWitnessSetFromBytes(signaturesWitnessesSet) @@ -116,14 +117,14 @@ const WithdrawCard = ({api, onRawResponse, onResponse, onWaiting}) => { for (let i = 0; i < vkeysSignatures.len(); i++) { fixedTx.add_vkey_witness(vkeysSignatures.get(i)) } - console.log('Withdrawal signed Tx: ', fixedTx.to_hex()) + logger.log('Withdrawal signed Tx: ', fixedTx.to_hex()) const txId = await api?.submitTx(fixedTx.to_hex()) onWaiting(false) onRawResponse(txId) onResponse(txId, false) } catch (error) { - console.error(error) + logger.error(error) onRawResponse('') onResponse(error) } finally { diff --git a/src/components/cards/submitTransactionCard.js b/src/components/cards/submitTransactionCard.js index c0d922d..8820332 100644 --- a/src/components/cards/submitTransactionCard.js +++ b/src/components/cards/submitTransactionCard.js @@ -1,3 +1,4 @@ +import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {CommonStyles, ModalWindowContent} from '../ui-constants' @@ -18,7 +19,7 @@ const SubmitTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { onWaiting(false) onRawResponse('') onResponse(e) - console.log(e) + logger.log(e) }) } diff --git a/src/components/tabs/subtabs/NFTTab.js b/src/components/tabs/subtabs/NFTTab.js index 202a6a3..9ca7bec 100644 --- a/src/components/tabs/subtabs/NFTTab.js +++ b/src/components/tabs/subtabs/NFTTab.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import {useState} from 'react' import {Buffer} from 'buffer' import useCardano from '../../../hooks/cardanoProvider' @@ -77,7 +78,7 @@ const NFTTab = () => { const handleNFTsAmount = () => { setIsMoreThenOneNFT(!isMoreThenOneNFT) - console.debug(`[NFTTab] mint MoreThenOneNFT is set: ${!isMoreThenOneNFT}`) + logger.debug(`[NFTTab] mint MoreThenOneNFT is set: ${!isMoreThenOneNFT}`) if (isMoreThenOneNFT === false) { setCurrentNFTsAmount(1) } @@ -85,10 +86,10 @@ const NFTTab = () => { const handleNftVersionOnChange = () => { setIsV2nft(!isV2nft) - console.debug(`[NFTTab] V2 is set: ${!isV2nft}`) + logger.debug(`[NFTTab] V2 is set: ${!isV2nft}`) setCurrentMintingInfo(emptyTokenInfo) setMintingTxInfo([]) - console.debug('[NFTTab] cleared the metadata and the prepared minting batch info') + logger.debug('[NFTTab] cleared the metadata and the prepared minting batch info') } const handleImageTypeChange = (event) => { @@ -96,7 +97,7 @@ const NFTTab = () => { } const sliceBy64Char = (inputString) => { - console.debug(`[NFTTab] inputString: ${JSON.stringify(inputString)}`) + logger.debug(`[NFTTab] inputString: ${JSON.stringify(inputString)}`) if (inputString.length <= 64) { return inputString } @@ -116,7 +117,7 @@ const NFTTab = () => { } const _genMeta = (nftName, nftImageUrl, nftDescription) => { - console.debug( + logger.debug( `[NFTTab][_genMeta]\nnftName: ${nftName}\nnftImageUrl: ${nftImageUrl}\nnftDescription: ${nftDescription}`, ) const name = nftName.replace(/ /g, '_') @@ -129,7 +130,7 @@ const NFTTab = () => { newInfo.metadata.image = imageUrl newInfo.metadata.files[0].src = imageUrl newInfo.metadata.description = description - console.debug(`[NFTTab][_genMeta] newInfo: ${JSON.stringify(newInfo, null, 2)}`) + logger.debug(`[NFTTab][_genMeta] newInfo: ${JSON.stringify(newInfo, null, 2)}`) return newInfo } @@ -145,7 +146,7 @@ const NFTTab = () => { } const generateSeveralMetadata = () => { - console.debug(`[NFTTab][generateSeveralMetadata] ${currentNFTsAmount} NFTs metadata will be generated`) + logger.debug(`[NFTTab][generateSeveralMetadata] ${currentNFTsAmount} NFTs metadata will be generated`) const allMetadataInfo = [] for (let index = 1; index <= currentNFTsAmount; index++) { const newName = currentNFTName + `_${index}` @@ -162,7 +163,7 @@ const NFTTab = () => { const txBuilder = getTxBuilder() const changeAddress = await api?.getChangeAddress() - console.debug(`[NFTTab][mint] changeAddress -> ${changeAddress}`) + logger.debug(`[NFTTab][mint] changeAddress -> ${changeAddress}`) const wasmChangeAddress = getAddressFromBytes(changeAddress) const usedAddresses = await api?.getUsedAddresses() const usedAddress = getAddressFromBytes(firstOrThrow(usedAddresses, 'No used address available from wallet')) @@ -175,7 +176,7 @@ const NFTTab = () => { for (const assetInfo of mintingTxInfo) { metadata[scriptHashHex][assetInfo.NFTName] = assetInfo.metadata metadata['version'] = isV2nft ? '2.0' : '1.0' - console.debug(`[NFTTab][mint] metadata -> ${JSON.stringify(metadata)}`) + logger.debug(`[NFTTab][mint] metadata -> ${JSON.stringify(metadata)}`) txBuilder.add_json_metadatum(strToBigNum('721'), JSON.stringify(metadata)) txBuilder.add_mint_asset_and_output_min_required_coin( wasmNativeScript, @@ -185,21 +186,21 @@ const NFTTab = () => { ) } - console.debug(`[NFTTab][mint] getting UTxOs`) + logger.debug(`[NFTTab][mint] getting UTxOs`) const hexInputUtxos = await api?.getUtxos() - console.debug(`[NFTTab][mint] preparing wasmUTxOs`) + logger.debug(`[NFTTab][mint] preparing wasmUTxOs`) const wasmUtxos = getCslUtxos(hexInputUtxos) - console.debug(`[NFTTab][mint] adding inputs`) + logger.debug(`[NFTTab][mint] adding inputs`) txBuilder.add_inputs_from(wasmUtxos, getLargestFirstMultiAsset()) txBuilder.add_required_signer(pubkeyHash) txBuilder.add_change_if_needed(wasmChangeAddress) const wasmUnsignedTransaction = txBuilder.build_tx() const fixedTx = getFixedTxFromBytes(wasmUnsignedTransaction.to_bytes()) - console.log('[NFTTab][mint] Unsigned Tx:', fixedTx.to_hex()) - console.debug(`[NFTTab][mint] signing the tx`) + logger.log('[NFTTab][mint] Unsigned Tx:', fixedTx.to_hex()) + logger.debug(`[NFTTab][mint] signing the tx`) const witnessHex = await api?.signTx(fixedTx.to_hex()) const wasmWitnessSet = getTransactionWitnessSetFromBytes(witnessHex) const vkeys = wasmWitnessSet.vkeys() @@ -207,12 +208,12 @@ const NFTTab = () => { fixedTx.add_vkey_witness(vkeys.get(i)) } const signedTxHex = fixedTx.to_hex() - console.log('[NFTTab][mint] Signed Tx:', signedTxHex) + logger.log('[NFTTab][mint] Signed Tx:', signedTxHex) const txId = await api?.submitTx(signedTxHex) - console.log(`[NFTTab][mint] Transaction successfully submitted: ${txId}`) + logger.log(`[NFTTab][mint] Transaction successfully submitted: ${txId}`) } catch (error) { handleError() - console.error(error) + logger.error(error) } } diff --git a/src/components/tabs/subtabs/certificatesInTxPart.js b/src/components/tabs/subtabs/certificatesInTxPart.js index 5888a17..7663a4d 100644 --- a/src/components/tabs/subtabs/certificatesInTxPart.js +++ b/src/components/tabs/subtabs/certificatesInTxPart.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React from 'react' import ExpandablePanel from '../../expandablePanel' import {iconCollapsed16, iconExpanded16} from '../../ui-constants' @@ -19,7 +20,7 @@ const CertificatesInTxPart = ({getters}) => { } if (votesInTx) { const voteJsonObjects = JSON.parse(votesInTx) - console.log('voteJsonObjects', voteJsonObjects) + logger.log('voteJsonObjects', voteJsonObjects) for (const voteJsonObject of voteJsonObjects) { resultArray.push(['Votes', voteJsonObject]) } diff --git a/src/components/tabs/subtabs/cip95AdditionalPart.js b/src/components/tabs/subtabs/cip95AdditionalPart.js index 700c9a3..73e328a 100644 --- a/src/components/tabs/subtabs/cip95AdditionalPart.js +++ b/src/components/tabs/subtabs/cip95AdditionalPart.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import {useState} from 'react' import {getCertificateBuilder, getCslVotingBuilder} from '../../../utils/cslTools' import TabsComponent from '../tabsComponent' @@ -20,14 +21,14 @@ const Cip95AdditionalPart = ({api, onWaiting, onError, getters, setters}) => { for (let i = 0; i < certs.len(); i++) { certsInJson.push(certs.get(i).to_json()) } - console.log('CertInTx', certsInJson) + logger.log('CertInTx', certsInJson) setCertsInTx(certsInJson) } const handleAddingVotesInTx = (votingBuilderWithVote) => { setVotingBuilder(votingBuilderWithVote) setVotesInTx(votingBuilderWithVote.build().to_json()) - console.log('Votes in Tx', votesInTx) + logger.log('Votes in Tx', votesInTx) } const getCertBuilder = () => { diff --git a/src/components/tabs/subtabs/govBasicFunctionsTab.js b/src/components/tabs/subtabs/govBasicFunctionsTab.js index 0bd6c12..1c4a8f1 100644 --- a/src/components/tabs/subtabs/govBasicFunctionsTab.js +++ b/src/components/tabs/subtabs/govBasicFunctionsTab.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import TabsComponent from '../tabsComponent' import VoteDelegationPanel from '../../cards/govActions/voteDelegationPanel' import { @@ -92,7 +93,7 @@ const GovBasicFunctionsTab = ({api, onWaiting, onError, getters, setters}) => { */ const handleDrepId = (bechEncodedID) => { if (!isValidDRepID(bechEncodedID) && !isPotentiallyValidHex(bechEncodedID)) { - console.error(`The value "${bechEncodedID}" is not valid dRepID`) + logger.error(`The value "${bechEncodedID}" is not valid dRepID`) onError() return } diff --git a/src/components/tabs/subtabs/responsesPart.js b/src/components/tabs/subtabs/responsesPart.js index 0033371..5a17634 100644 --- a/src/components/tabs/subtabs/responsesPart.js +++ b/src/components/tabs/subtabs/responsesPart.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState} from 'react' const ResponsesPart = ({rawCurrentText, currentText, currentWaiterState}) => { @@ -7,12 +8,12 @@ const ResponsesPart = ({rawCurrentText, currentText, currentWaiterState}) => { const copyToClipboard = () => { navigator.clipboard.writeText(currentText).then( function () { - console.log('Async: Copying the processed response to clipboard was successful!') + logger.log('Async: Copying the processed response to clipboard was successful!') setMessageDisplayed(true) hideMessage() }, function (err) { - console.error('Async: Could not copy text: ', err) + logger.error('Async: Could not copy text: ', err) }, ) } @@ -20,12 +21,12 @@ const ResponsesPart = ({rawCurrentText, currentText, currentWaiterState}) => { const copyRawToClipboard = () => { navigator.clipboard.writeText(rawCurrentText).then( function () { - console.log('Async: Copying raw response to clipboard was successful!') + logger.log('Async: Copying raw response to clipboard was successful!') setMessageDisplayedRaw(true) hideMessageRaw() }, function (err) { - console.error('Async: Could not copy raw response: ', err) + logger.error('Async: Could not copy raw response: ', err) }, ) } diff --git a/src/components/tabs/subtabs/testTxsTab.js b/src/components/tabs/subtabs/testTxsTab.js index 9d13056..8af901a 100644 --- a/src/components/tabs/subtabs/testTxsTab.js +++ b/src/components/tabs/subtabs/testTxsTab.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import React, {useState, useEffect} from 'react' import useCardano from '../../../hooks/cardanoProvider' import ResponsesPart from './responsesPart' @@ -32,15 +33,15 @@ const TestTxsTab = () => { .then((addrs) => { if (addrs && addrs.length > 0) setWalletRewardAddrHex(addrs[0]) }) - .catch(console.error) + .catch(logger.error) api .getChangeAddress() .then((addr) => setWalletChangeAddrHex(addr)) - .catch(console.error) + .catch(logger.error) api .getNetworkId() .then((id) => setNetworkId(id)) - .catch(console.error) + .catch(logger.error) }, [api]) const toggleFeature = (key) => { @@ -105,7 +106,7 @@ const TestTxsTab = () => { } catch (e) { setRawCurrentText('') setCurrentText(`Sign error: ${e.message ?? JSON.stringify(e)}`) - console.error(e) + logger.error(e) } setWaiterState(false) } diff --git a/src/components/tabs/subtabs/tokenTab.js b/src/components/tabs/subtabs/tokenTab.js index f5d06c7..788eac5 100644 --- a/src/components/tabs/subtabs/tokenTab.js +++ b/src/components/tabs/subtabs/tokenTab.js @@ -1,3 +1,4 @@ +import logger from '../../../utils/logger' import {useState} from 'react' import useCardano from '../../../hooks/cardanoProvider' import { @@ -84,13 +85,13 @@ const TokenTab = () => { const clearTokenName = currentTokenName.trim() if (clearTokenName.length === 0) { handleEmptyTokenName() - console.error("The token name shouldn't be empty") + logger.error("The token name shouldn't be empty") return } if (currentQuantity === '0') { handleEmptyTokenQuantity() - console.error("The token quantity isn't suitable") + logger.error("The token quantity isn't suitable") return } let quantityInt = 0 @@ -98,14 +99,14 @@ const TokenTab = () => { quantityInt = toInt(currentQuantity) } catch (error) { handleEmptyTokenQuantity() - console.error(error) + logger.error(error) return } const txBuilder = getTxBuilder() const changeAddress = await api?.getChangeAddress() - console.debug(`[dApp][Tokens_Tab][mint] changeAddress -> ${changeAddress}`) + logger.debug(`[dApp][Tokens_Tab][mint] changeAddress -> ${changeAddress}`) const wasmChangeAddress = getAddressFromBytes(changeAddress) try { @@ -122,21 +123,21 @@ const TokenTab = () => { getTransactionOutputBuilder(wasmChangeAddress), ) - console.debug(`[TokenTab][mint] getting UTxOs`) + logger.debug(`[TokenTab][mint] getting UTxOs`) const hexInputUtxos = await api?.getUtxos() - console.debug(`[TokenTab][mint] preparing wasmUTxOs`) + logger.debug(`[TokenTab][mint] preparing wasmUTxOs`) const wasmUtxos = getCslUtxos(hexInputUtxos) - console.debug(`[TokenTab][mint] adding inputs`) + logger.debug(`[TokenTab][mint] adding inputs`) txBuilder.add_inputs_from(wasmUtxos, getLargestFirstMultiAsset()) txBuilder.add_required_signer(pubkeyHash) txBuilder.add_change_if_needed(wasmChangeAddress) const wasmUnsignedTransaction = txBuilder.build_tx() const fixedTx = getFixedTxFromBytes(wasmUnsignedTransaction.to_bytes()) - console.log('[TokenTab] Unsigned Tx:', fixedTx.to_hex()) - console.debug(`[TokenTab][mint] signing the tx`) + logger.log('[TokenTab] Unsigned Tx:', fixedTx.to_hex()) + logger.debug(`[TokenTab][mint] signing the tx`) const witnessHex = await api?.signTx(fixedTx.to_hex()) const wasmWitnessSet = getTransactionWitnessSetFromBytes(witnessHex) const vkeys = wasmWitnessSet.vkeys() @@ -144,12 +145,12 @@ const TokenTab = () => { fixedTx.add_vkey_witness(vkeys.get(i)) } const signedTxHex = fixedTx.to_hex() - console.log('[TokenTab][mint] Signed Tx:', signedTxHex) + logger.log('[TokenTab][mint] Signed Tx:', signedTxHex) const txId = await api?.submitTx(signedTxHex) - console.log(`[TokenTab][mint] Transaction successfully submitted: ${txId}`) + logger.log(`[TokenTab][mint] Transaction successfully submitted: ${txId}`) } catch (error) { handleError(error) - console.error(error) + logger.error(error) } } diff --git a/src/components/walletsModal.js b/src/components/walletsModal.js index 69a7dff..8d1116b 100644 --- a/src/components/walletsModal.js +++ b/src/components/walletsModal.js @@ -1,3 +1,4 @@ +import logger from '../utils/logger' import React, {useState} from 'react' import Popup from 'reactjs-popup' import useCardano from '../hooks/cardanoProvider' @@ -6,13 +7,13 @@ import {NO_PROVIDER} from '../utils/connectionStates' const WalletsModal = () => { const {connect, availableWallets, setSelectedWallet, connectionState} = useCardano() const [selectedUserWallet, setSelectedUserWallet] = useState('') - console.log(`[dApp][WalletsModal] is called`) + logger.log(`[dApp][WalletsModal] is called`) const handleSelectionAndClose = (closeFunc) => { - console.log(`[dApp][WalletsModal] selected wallet is ${selectedUserWallet}`) + logger.log(`[dApp][WalletsModal] selected wallet is ${selectedUserWallet}`) setSelectedWallet(selectedUserWallet) closeFunc() - console.log(`[dApp][WalletsModal] is closed`) + logger.log(`[dApp][WalletsModal] is closed`) connect(selectedUserWallet, false, false) } diff --git a/src/hooks/bitcoinProvider.js b/src/hooks/bitcoinProvider.js index 5c9d5d9..de38cb1 100644 --- a/src/hooks/bitcoinProvider.js +++ b/src/hooks/bitcoinProvider.js @@ -1,37 +1,38 @@ +import logger from '../utils/logger' import React, {useState} from 'react' import {NO_PROVIDER} from '../utils/connectionStates' const BitcoinContext = React.createContext(null) export const BitcoinProvider = ({children}) => { - console.debug('[dApp][BitcoinProvider] is called') + logger.debug('[dApp][BitcoinProvider] is called') const [connectionState] = useState(NO_PROVIDER) const connect = async () => { - console.warn('[dApp][BitcoinProvider] connect: not implemented') + logger.warn('[dApp][BitcoinProvider] connect: not implemented') } const disconnect = () => { - console.warn('[dApp][BitcoinProvider] disconnect: not implemented') + logger.warn('[dApp][BitcoinProvider] disconnect: not implemented') } const getAccounts = async () => { - console.warn('[dApp][BitcoinProvider] getAccounts: not implemented') + logger.warn('[dApp][BitcoinProvider] getAccounts: not implemented') return [] } const getBalance = async (_address) => { - console.warn('[dApp][BitcoinProvider] getBalance: not implemented') + logger.warn('[dApp][BitcoinProvider] getBalance: not implemented') return '0' } const sendTransaction = async (_tx) => { - console.warn('[dApp][BitcoinProvider] sendTransaction: not implemented') + logger.warn('[dApp][BitcoinProvider] sendTransaction: not implemented') throw new Error('Bitcoin sendTransaction not implemented') } const signMessage = async (_message) => { - console.warn('[dApp][BitcoinProvider] signMessage: not implemented') + logger.warn('[dApp][BitcoinProvider] signMessage: not implemented') throw new Error('Bitcoin signMessage not implemented') } diff --git a/src/hooks/cardanoProvider.js b/src/hooks/cardanoProvider.js index e569961..53ea98c 100644 --- a/src/hooks/cardanoProvider.js +++ b/src/hooks/cardanoProvider.js @@ -1,3 +1,4 @@ +import logger from '../utils/logger' import React, {useState, useEffect, useCallback, useMemo} from 'react' import {NOT_CONNECTED, IN_PROGRESS, CONNECTED, NO_PROVIDER} from '../utils/connectionStates' @@ -23,7 +24,7 @@ const reservedKeys = [ ] export const CardanoProvider = ({children}) => { - console.debug('[dApp][CardanoProvider] is called') + logger.debug('[dApp][CardanoProvider] is called') const [api, setApi] = useState(null) const [connectionState, setConnectionState] = useState(NO_PROVIDER) const [availableWallets, setAvailableWallets] = useState([]) @@ -56,42 +57,42 @@ export const CardanoProvider = ({children}) => { const connect = useCallback(async (walletName, requestIdentification, silent, throwError = false) => { setConnectionState(IN_PROGRESS) setApi(null) - console.debug(`[dApp][connect] is called`) + logger.debug(`[dApp][connect] is called`) if (!window.cardano) { - console.error('There are no cardano wallets are installed') + logger.error('There are no cardano wallets are installed') setConnectionState(NOT_CONNECTED) return } - console.log(`[dApp][connect] connecting the wallet "${walletName}"`) - console.debug(`[dApp][connect] {requestIdentification: ${requestIdentification}, onlySilent: ${silent}}`) + logger.log(`[dApp][connect] connecting the wallet "${walletName}"`) + logger.debug(`[dApp][connect] {requestIdentification: ${requestIdentification}, onlySilent: ${silent}}`) try { const connectedApi = await window.cardano[walletName].enable({ requestIdentification, onlySilent: silent, }) - console.debug(`[dApp][connect] wallet API object is received`) + logger.debug(`[dApp][connect] wallet API object is received`) setApi(connectedApi) setSelectedWallet(walletName) setConnectionState(CONNECTED) return connectedApi } catch (error) { - console.error(`[dApp][connect] The error received while connecting the wallet`) + logger.error(`[dApp][connect] The error received while connecting the wallet`) setSelectedWallet('') setConnectionState(NOT_CONNECTED) if (throwError) { throw new Error(JSON.stringify(error)) } else { - console.error(`[dApp][connect] ${JSON.stringify(error)}`) + logger.error(`[dApp][connect] ${JSON.stringify(error)}`) } } }, []) useEffect(() => { if (!window.cardano) { - console.warn('[dApp] There are no cardano wallets are installed') + logger.warn('[dApp] There are no cardano wallets are installed') setConnectionState(NO_PROVIDER) return } @@ -102,13 +103,13 @@ export const CardanoProvider = ({children}) => { */ const tryConnectSilent = async (walletName) => { let connectResult = null - console.debug(`[dApp][tryConnectSilent] is called`) + logger.debug(`[dApp][tryConnectSilent] is called`) try { - console.debug(`[dApp][tryConnectSilent] trying {false, true}`) + logger.debug(`[dApp][tryConnectSilent] trying {false, true}`) setConnectionState(IN_PROGRESS) connectResult = await connect(walletName, false, true, false) if (connectResult != null) { - console.log('[dApp][tryConnectSilent] RE-CONNECTED!') + logger.log('[dApp][tryConnectSilent] RE-CONNECTED!') setSelectedWallet(walletName) setConnectionState(CONNECTED) return @@ -116,12 +117,12 @@ export const CardanoProvider = ({children}) => { } catch (error) { setSelectedWallet('') setConnectionState(NOT_CONNECTED) - console.error(error) + logger.error(error) } } const availableWallets = getAvailableWallets() - console.log('[dApp] allInfoWallets: ', availableWallets) + logger.log('[dApp] allInfoWallets: ', availableWallets) setAvailableWallets(availableWallets) if (availableWallets.length === 1) { @@ -130,7 +131,7 @@ export const CardanoProvider = ({children}) => { walletObject .isEnabled() .then((response) => { - console.debug(`[dApp] Connection is enabled: ${response}`) + logger.debug(`[dApp] Connection is enabled: ${response}`) if (response) { tryConnectSilent(existingWallet).then() } else { @@ -139,7 +140,7 @@ export const CardanoProvider = ({children}) => { }) .catch((err) => { setConnectionState(NOT_CONNECTED) - console.error(err) + logger.error(err) }) } else { setConnectionState(NOT_CONNECTED); diff --git a/src/hooks/ethereumProvider.js b/src/hooks/ethereumProvider.js index e346fb9..582fc49 100644 --- a/src/hooks/ethereumProvider.js +++ b/src/hooks/ethereumProvider.js @@ -1,24 +1,25 @@ +import logger from '../utils/logger' import React, {useState, useEffect, useCallback, useMemo} from 'react' import {NOT_CONNECTED, IN_PROGRESS, CONNECTED, NO_PROVIDER} from '../utils/connectionStates' const EthereumContext = React.createContext(null) export const EthereumProvider = ({children}) => { - console.debug('[dApp][EthereumProvider] is called') + logger.debug('[dApp][EthereumProvider] is called') const [accounts, setAccounts] = useState([]) const [connectionState, setConnectionState] = useState(NO_PROVIDER) const [chainId, setChainId] = useState(null) useEffect(() => { if (!window.ethereum) { - console.warn('[dApp] No Ethereum wallet found') + logger.warn('[dApp] No Ethereum wallet found') setConnectionState(NO_PROVIDER) return } setConnectionState(NOT_CONNECTED) const handleAccountsChanged = (newAccounts) => { - console.debug('[dApp][EthereumProvider] accountsChanged', newAccounts) + logger.debug('[dApp][EthereumProvider] accountsChanged', newAccounts) if (newAccounts.length === 0) { setConnectionState(NOT_CONNECTED) setAccounts([]) @@ -29,7 +30,7 @@ export const EthereumProvider = ({children}) => { } const handleChainChanged = (newChainId) => { - console.debug('[dApp][EthereumProvider] chainChanged', newChainId) + logger.debug('[dApp][EthereumProvider] chainChanged', newChainId) setChainId(newChainId) } @@ -45,16 +46,16 @@ export const EthereumProvider = ({children}) => { const connect = useCallback(async () => { if (!window.ethereum) return setConnectionState(IN_PROGRESS) - console.debug('[dApp][EthereumProvider] connect is called') + logger.debug('[dApp][EthereumProvider] connect is called') try { const accs = await window.ethereum.request({method: 'eth_requestAccounts'}) const chain = await window.ethereum.request({method: 'eth_chainId'}) setAccounts(accs) setChainId(chain) setConnectionState(CONNECTED) - console.log('[dApp][EthereumProvider] CONNECTED, accounts:', accs) + logger.log('[dApp][EthereumProvider] CONNECTED, accounts:', accs) } catch (err) { - console.error('[dApp][EthereumProvider] connect error', err) + logger.error('[dApp][EthereumProvider] connect error', err) setConnectionState(NOT_CONNECTED) } }, []) diff --git a/src/utils/cslTools.js b/src/utils/cslTools.js index 2e49805..c9cff8e 100644 --- a/src/utils/cslTools.js +++ b/src/utils/cslTools.js @@ -1,3 +1,4 @@ +import logger from './logger' import {protocolParams} from './networkConfig' import {hexToBytes, bytesToHex, wasmMultiassetToJSONs} from './utils' import {Buffer} from 'buffer' @@ -276,38 +277,38 @@ export const keyHashFromHex = (hexValue) => wasm.Ed25519KeyHash.from_hex(hexValu export const keyHashFromBech32 = (bech32Value) => wasm.Ed25519KeyHash.from_bech32(bech32Value) export const getCslCredentialFromHex = (hexValue) => { - console.debug('[cslTools][getCslCredentialFromHex]::hexValue', hexValue) + logger.debug('[cslTools][getCslCredentialFromHex]::hexValue', hexValue) const keyHash = keyHashFromHex(hexValue) - console.debug('[cslTools][getCslCredentialFromHex]::keyHash', keyHash) + logger.debug('[cslTools][getCslCredentialFromHex]::keyHash', keyHash) const cred = getCredential(keyHash) - console.debug('[cslTools][getCslCredentialFromHex]::cred', cred) + logger.debug('[cslTools][getCslCredentialFromHex]::cred', cred) return cred } export const getCslCredentialFromBech32 = (bech32Value) => { - console.debug('[cslTools][getCslCredentialFromBech32]::bech32Value', bech32Value) + logger.debug('[cslTools][getCslCredentialFromBech32]::bech32Value', bech32Value) const keyHash = keyHashFromBech32(bech32Value) - console.debug('[cslTools][getCslCredentialFromBech32]::keyHash', keyHash) + logger.debug('[cslTools][getCslCredentialFromBech32]::keyHash', keyHash) const cred = getCredential(keyHash) - console.debug('[cslTools][getCslCredentialFromBech32]::cred', cred) + logger.debug('[cslTools][getCslCredentialFromBech32]::cred', cred) return cred } export const getCslCredentialFromScriptFromBech32 = (bech32Value) => { - console.debug('[cslTools][getCslCredentialFromScriptFromBech32]::bech32Value', bech32Value) + logger.debug('[cslTools][getCslCredentialFromScriptFromBech32]::bech32Value', bech32Value) const scriptHash = wasm.ScriptHash.from_bech32(bech32Value) - console.debug('[cslTools][getCslCredentialFromScriptFromBech32]::scriptHash', scriptHash) + logger.debug('[cslTools][getCslCredentialFromScriptFromBech32]::scriptHash', scriptHash) const cred = getCredentialFromScriptHash(scriptHash) - console.debug('[cslTools][getCslCredentialFromScriptFromBech32]::cred', cred) + logger.debug('[cslTools][getCslCredentialFromScriptFromBech32]::cred', cred) return cred } export const getCslCredentialFromScriptFromHex = (hexValue) => { - console.debug('[cslTools][getCslCredentialFromScriptFromHex]::hexValue', hexValue) + logger.debug('[cslTools][getCslCredentialFromScriptFromHex]::hexValue', hexValue) const scriptHash = wasm.ScriptHash.from_hex(hexValue) - console.debug('[cslTools][getCslCredentialFromScriptFromHex]::scriptHash', scriptHash) + logger.debug('[cslTools][getCslCredentialFromScriptFromHex]::scriptHash', scriptHash) const cred = getCredentialFromScriptHash(scriptHash) - console.debug('[cslTools][getCslCredentialFromScriptFromHex]::cred', cred) + logger.debug('[cslTools][getCslCredentialFromScriptFromHex]::cred', cred) return cred } diff --git a/src/utils/logger.js b/src/utils/logger.js new file mode 100644 index 0000000..821aae5 --- /dev/null +++ b/src/utils/logger.js @@ -0,0 +1,24 @@ +// Debug-gated logger. +// +// `debug`, `log` and `info` only print when debug output is enabled — during +// local development (NODE_ENV === 'development') or when the app is built with +// REACT_APP_DEBUG=true. `warn` and `error` always print so real problems stay +// visible in production. +const isDebugEnabled = + process.env.NODE_ENV === 'development' || process.env.REACT_APP_DEBUG === 'true' + +const logger = { + debug: (...args) => { + if (isDebugEnabled) console.debug(...args) + }, + log: (...args) => { + if (isDebugEnabled) console.log(...args) + }, + info: (...args) => { + if (isDebugEnabled) console.info(...args) + }, + warn: (...args) => console.warn(...args), + error: (...args) => console.error(...args), +} + +export default logger From 7e16a8a301c8f49861a0b4fe81a6d2b119cd8571 Mon Sep 17 00:00:00 2001 From: Denis Nebytov Date: Wed, 8 Jul 2026 13:07:56 +0300 Subject: [PATCH 04/19] feat: runtime on/off switch for logger via browser console - Persist an enabled override in localStorage (key 'dapp:debug') - Expose window.dappLogs { on, off, toggle, status, reset } so logs can be toggled live from the console without rebuilding - Falls back to build default (dev, or REACT_APP_DEBUG=true) when no override --- src/utils/logger.js | 80 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/src/utils/logger.js b/src/utils/logger.js index 821aae5..5ca79bd 100644 --- a/src/utils/logger.js +++ b/src/utils/logger.js @@ -1,24 +1,86 @@ -// Debug-gated logger. +// Debug-gated logger with a runtime on/off switch. // -// `debug`, `log` and `info` only print when debug output is enabled — during -// local development (NODE_ENV === 'development') or when the app is built with -// REACT_APP_DEBUG=true. `warn` and `error` always print so real problems stay -// visible in production. -const isDebugEnabled = +// `debug`, `log` and `info` only print when debug output is enabled; +// `warn` and `error` always print so real problems stay visible in production. +// +// Enabled state is resolved in this order: +// 1. A runtime override saved in localStorage (set from the browser console). +// 2. The build-time default: on during local development, or when the app is +// built with REACT_APP_DEBUG=true. +// +// Toggle logs live from the browser console without rebuilding: +// dappLogs.on() // enable and remember across reloads +// dappLogs.off() // disable and remember across reloads +// dappLogs.toggle() // flip current state +// dappLogs.status() // -> true | false +// dappLogs.reset() // forget the override, fall back to the build default +const STORAGE_KEY = 'dapp:debug' + +const buildDefault = process.env.NODE_ENV === 'development' || process.env.REACT_APP_DEBUG === 'true' +const readOverride = () => { + try { + const value = window.localStorage.getItem(STORAGE_KEY) + if (value === 'true') return true + if (value === 'false') return false + } catch (e) { + // localStorage may be unavailable (SSR, privacy mode) — ignore. + } + return null +} + +const override = readOverride() +let enabled = override === null ? buildDefault : override + +const persist = (value) => { + try { + window.localStorage.setItem(STORAGE_KEY, String(value)) + } catch (e) { + // ignore write failures + } +} + +const setEnabled = (value) => { + enabled = !!value + persist(enabled) + // Always report the switch itself so the user sees the effect immediately. + console.info(`[dApp][logger] logging ${enabled ? 'ENABLED' : 'DISABLED'}`) + return enabled +} + const logger = { debug: (...args) => { - if (isDebugEnabled) console.debug(...args) + if (enabled) console.debug(...args) }, log: (...args) => { - if (isDebugEnabled) console.log(...args) + if (enabled) console.log(...args) }, info: (...args) => { - if (isDebugEnabled) console.info(...args) + if (enabled) console.info(...args) }, warn: (...args) => console.warn(...args), error: (...args) => console.error(...args), } +// Expose runtime controls on window so logs can be toggled from the console. +if (typeof window !== 'undefined') { + window.dappLogs = { + on: () => setEnabled(true), + off: () => setEnabled(false), + toggle: () => setEnabled(!enabled), + status: () => enabled, + reset: () => { + try { + window.localStorage.removeItem(STORAGE_KEY) + } catch (e) { + // ignore + } + enabled = buildDefault + console.info(`[dApp][logger] override cleared, logging ${enabled ? 'ENABLED' : 'DISABLED'} (build default)`) + return enabled + }, + } +} + export default logger From 28f59e4080df8036a3422235c9ae0f3d1e135395 Mon Sep 17 00:00:00 2001 From: Denis Nebytov Date: Wed, 8 Jul 2026 13:25:33 +0300 Subject: [PATCH 05/19] test: add smoke + util tests and CI workflow - setupTests.js loads @testing-library/jest-dom - ethereumUtils: chainName, wei/eth conversions, shortAddress, ERC-20 encoders - utils: bytesToHex/hexToBytes round-trip - logger: gating, always-on warn/error, persisted override, window.dappLogs toggle - ApiCard: render, click, height class map, color prop - add test:ci script and .github/workflows/test.yml (runs on push/PR) - 24 tests across 4 suites, all passing --- .github/workflows/test.yml | 28 ++++++++++ package.json | 1 + src/components/cards/apiCard.test.js | 28 ++++++++++ src/setupTests.js | 3 ++ src/utils/ethereumUtils.test.js | 80 ++++++++++++++++++++++++++++ src/utils/logger.test.js | 76 ++++++++++++++++++++++++++ src/utils/utils.test.js | 16 ++++++ 7 files changed, 232 insertions(+) create mode 100644 .github/workflows/test.yml create mode 100644 src/components/cards/apiCard.test.js create mode 100644 src/setupTests.js create mode 100644 src/utils/ethereumUtils.test.js create mode 100644 src/utils/logger.test.js create mode 100644 src/utils/utils.test.js diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..ed7716e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Test + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Read .nvmrc + id: nvm + run: echo "version=$(cat .nvmrc)" >> $GITHUB_OUTPUT + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: '${{ steps.nvm.outputs.version }}' + cache: 'npm' + + - name: Install dependencies + run: npm i + + - name: Run tests + run: npm run test:ci diff --git a/package.json b/package.json index c453dda..5daab20 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "start": "craco start", "build": "CI=false && craco build", "test": "craco test", + "test:ci": "CI=true craco test", "eject": "craco eject" }, "eslintConfig": { diff --git a/src/components/cards/apiCard.test.js b/src/components/cards/apiCard.test.js new file mode 100644 index 0000000..4a1aee4 --- /dev/null +++ b/src/components/cards/apiCard.test.js @@ -0,0 +1,28 @@ +import {render, screen, fireEvent} from '@testing-library/react' +import ApiCard from './apiCard' + +describe('ApiCard', () => { + it('renders the apiName as a button and fires clickFunction', () => { + const onClick = jest.fn() + render() + + const button = screen.getByRole('button', {name: 'Do Thing'}) + fireEvent.click(button) + expect(onClick).toHaveBeenCalledTimes(1) + }) + + it('applies a mapped height class', () => { + render( {}} height={24} />) + expect(screen.getByRole('button', {name: 'Tall'}).className).toContain('h-24') + }) + + it('falls back to h-16 for an unmapped height', () => { + render( {}} height={999} />) + expect(screen.getByRole('button', {name: 'Default'}).className).toContain('h-16') + }) + + it('uses the provided color class when given', () => { + render( {}} color="bg-red-700" />) + expect(screen.getByRole('button', {name: 'Red'}).className).toContain('bg-red-700') + }) +}) diff --git a/src/setupTests.js b/src/setupTests.js new file mode 100644 index 0000000..fe64dfa --- /dev/null +++ b/src/setupTests.js @@ -0,0 +1,3 @@ +// Adds custom jest matchers such as toBeInTheDocument(). +// Automatically loaded by Create React App / craco before each test file. +import '@testing-library/jest-dom' diff --git a/src/utils/ethereumUtils.test.js b/src/utils/ethereumUtils.test.js new file mode 100644 index 0000000..461f441 --- /dev/null +++ b/src/utils/ethereumUtils.test.js @@ -0,0 +1,80 @@ +import { + CHAIN_IDS, + chainName, + weiHexToEth, + ethToHexWei, + shortAddress, + balanceOfData, + transferData, +} from './ethereumUtils' + +describe('chainName', () => { + it('maps known chain ids to readable names', () => { + expect(chainName(CHAIN_IDS.MAINNET)).toBe('Mainnet') + expect(chainName(CHAIN_IDS.SEPOLIA)).toBe('Sepolia') + expect(chainName(CHAIN_IDS.HOLESKY)).toBe('Holesky') + }) + + it('returns the raw id for unknown chains', () => { + expect(chainName('0x99')).toBe('0x99') + }) + + it('returns "Unknown" when no chain id is given', () => { + expect(chainName(undefined)).toBe('Unknown') + }) +}) + +describe('weiHexToEth', () => { + it('converts whole ether', () => { + expect(weiHexToEth('0xde0b6b3a7640000')).toBe('1.0') // 1e18 wei + }) + + it('converts fractional ether and trims trailing zeros', () => { + expect(weiHexToEth('0x6f05b59d3b20000')).toBe('0.5') // 5e17 wei + }) + + it('handles zero', () => { + expect(weiHexToEth('0x0')).toBe('0.0') + }) +}) + +describe('ethToHexWei', () => { + it('converts an ether string to hex wei', () => { + expect(ethToHexWei('1')).toBe('0xde0b6b3a7640000') + }) + + it('round-trips with weiHexToEth', () => { + expect(weiHexToEth(ethToHexWei('2.5'))).toBe('2.5') + }) +}) + +describe('shortAddress', () => { + it('shortens a full address', () => { + expect(shortAddress('0x1234567890abcdef1234567890abcdef12345678')).toBe('0x1234...5678') + }) + + it('returns empty string for falsy input', () => { + expect(shortAddress('')).toBe('') + expect(shortAddress(undefined)).toBe('') + }) +}) + +describe('ERC-20 ABI encoders', () => { + const addr = '0x1234567890abcdef1234567890abcdef12345678' + + it('encodes balanceOf(address)', () => { + const data = balanceOfData(addr) + expect(data.startsWith('0x70a08231')).toBe(true) + // selector (8) + 0x (2) + 64 hex chars of padded address + expect(data.length).toBe(2 + 8 + 64) + expect(data.endsWith(addr.slice(2))).toBe(true) + }) + + it('encodes transfer(address,uint256)', () => { + const data = transferData(addr, '1') + expect(data.startsWith('0xa9059cbb')).toBe(true) + // selector (8) + 0x (2) + 64 (address) + 64 (amount) + expect(data.length).toBe(2 + 8 + 64 + 64) + expect(data.endsWith('1'.padStart(64, '0'))).toBe(true) + }) +}) diff --git a/src/utils/logger.test.js b/src/utils/logger.test.js new file mode 100644 index 0000000..e942125 --- /dev/null +++ b/src/utils/logger.test.js @@ -0,0 +1,76 @@ +// NODE_ENV is 'test' here, so the build default is "logging off" — which lets us +// assert the gating and the runtime toggle cleanly. +describe('logger', () => { + beforeEach(() => { + jest.resetModules() // re-evaluate logger.js so it re-reads localStorage + window.localStorage.clear() + jest.restoreAllMocks() + }) + + it('does not print debug/log when disabled (build default in test env)', () => { + const debugSpy = jest.spyOn(console, 'debug').mockImplementation(() => {}) + const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}) + const logger = require('./logger').default + + logger.debug('nope') + logger.log('nope') + + expect(debugSpy).not.toHaveBeenCalled() + expect(logSpy).not.toHaveBeenCalled() + }) + + it('always prints warn and error regardless of state', () => { + const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}) + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const logger = require('./logger').default + + logger.warn('w') + logger.error('e') + + expect(warnSpy).toHaveBeenCalledWith('w') + expect(errorSpy).toHaveBeenCalledWith('e') + }) + + it('reads a persisted override on load', () => { + window.localStorage.setItem('dapp:debug', 'true') + const debugSpy = jest.spyOn(console, 'debug').mockImplementation(() => {}) + const logger = require('./logger').default + + logger.debug('yes') + + expect(debugSpy).toHaveBeenCalledWith('yes') + }) + + it('exposes window.dappLogs controls that toggle output and persist', () => { + jest.spyOn(console, 'info').mockImplementation(() => {}) + const debugSpy = jest.spyOn(console, 'debug').mockImplementation(() => {}) + const logger = require('./logger').default + + expect(window.dappLogs.status()).toBe(false) + + window.dappLogs.on() + expect(window.dappLogs.status()).toBe(true) + expect(window.localStorage.getItem('dapp:debug')).toBe('true') + logger.debug('on') + expect(debugSpy).toHaveBeenCalledWith('on') + + debugSpy.mockClear() + window.dappLogs.off() + expect(window.dappLogs.status()).toBe(false) + logger.debug('off') + expect(debugSpy).not.toHaveBeenCalled() + }) + + it('reset() clears the override and falls back to the build default', () => { + window.localStorage.setItem('dapp:debug', 'true') + jest.spyOn(console, 'info').mockImplementation(() => {}) + const logger = require('./logger').default + + expect(window.dappLogs.status()).toBe(true) + window.dappLogs.reset() + + expect(window.localStorage.getItem('dapp:debug')).toBeNull() + expect(window.dappLogs.status()).toBe(false) // build default in test env + void logger + }) +}) diff --git a/src/utils/utils.test.js b/src/utils/utils.test.js new file mode 100644 index 0000000..f6cc25d --- /dev/null +++ b/src/utils/utils.test.js @@ -0,0 +1,16 @@ +import {bytesToHex, hexToBytes} from './utils' + +describe('bytesToHex / hexToBytes', () => { + it('encodes bytes to a hex string', () => { + expect(bytesToHex([0, 1, 15, 16, 255])).toBe('00010f10ff') + }) + + it('decodes a hex string back to bytes', () => { + expect(Array.from(hexToBytes('00010f10ff'))).toEqual([0, 1, 15, 16, 255]) + }) + + it('round-trips arbitrary data', () => { + const original = [222, 173, 190, 239] + expect(Array.from(hexToBytes(bytesToHex(original)))).toEqual(original) + }) +}) From 1a33f280ce67b1f669c2f057bf762ed449c03f65 Mon Sep 17 00:00:00 2001 From: Denis Nebytov Date: Wed, 8 Jul 2026 13:51:01 +0300 Subject: [PATCH 06/19] refactor: extract runApiCall helper, collapse card handlers - Add src/utils/runApiCall.js: shared waiting/raw/response/error envelope with parse, rawText and stringify options (+ unit tests) - Convert 22 API cards to runApiCall, removing the repeated then/catch boilerplate - Left signTransactionCard (multi-step build) and cip95getRegisteredPubStakeKeys (per-branch stringify) on the explicit form to preserve exact behavior --- .../cards/cip95getPubDRepKeyCard.js | 32 ++++--------- .../cip95getUnregisteredPubStakeKeysCard.js | 33 ++++--------- src/components/cards/createRandomKeyCard.js | 45 ++++++++---------- .../cards/ethereum/getAccountsCard.js | 22 ++------- .../cards/ethereum/getChainIdCard.js | 22 ++------- .../cards/ethereum/getErc20BalanceCard.js | 37 +++++---------- .../cards/ethereum/getEthBalanceCard.js | 21 +++------ .../cards/ethereum/sendEthTransactionCard.js | 34 +++++--------- .../cards/ethereum/signEthMessageCard.js | 24 +++------- .../cards/ethereum/transferErc20Card.js | 35 +++++--------- src/components/cards/getBalanceCard.js | 29 ++++-------- src/components/cards/getChangeAddressCard.js | 23 +++------ .../cards/getCollateralUtxosCard.js | 24 ++-------- src/components/cards/getExtensionsCard.js | 19 ++------ src/components/cards/getNetworkIdCard.js | 20 ++------ .../cards/getRewardAddressesCard.js | 26 ++-------- src/components/cards/getUnusedAddressCard.js | 26 ++-------- src/components/cards/getUsedAddressCard.js | 26 ++-------- src/components/cards/getUtxosCard.js | 29 +++--------- src/components/cards/isEnabledCard.js | 20 ++------ src/components/cards/listNFTsCard.js | 20 ++------ src/components/cards/submitTransactionCard.js | 20 ++------ src/utils/runApiCall.js | 28 +++++++++++ src/utils/runApiCall.test.js | 47 +++++++++++++++++++ 24 files changed, 227 insertions(+), 435 deletions(-) create mode 100644 src/utils/runApiCall.js create mode 100644 src/utils/runApiCall.test.js diff --git a/src/components/cards/cip95getPubDRepKeyCard.js b/src/components/cards/cip95getPubDRepKeyCard.js index ae1b6e1..f2dd78d 100644 --- a/src/components/cards/cip95getPubDRepKeyCard.js +++ b/src/components/cards/cip95getPubDRepKeyCard.js @@ -1,31 +1,19 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { getPublicKeyFromHex } from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const Cip95GetPubDRepKeyCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getPubDRepKeyClick = () => { - onWaiting(true) - api?.cip95 - .getPubDRepKey() - .then((pubDRepKey) => { - onWaiting(false) - onRawResponse(pubDRepKey) + const getPubDRepKeyClick = () => + runApiCall(() => api.cip95.getPubDRepKey(), {onRawResponse, onResponse, onWaiting}, { + parse: (pubDRepKey) => { const dRepID = getPublicKeyFromHex(pubDRepKey).hash() - const dRepIDHex = dRepID.to_hex() - const dRepIDBech32 = dRepID.to_bech32('drep') - onResponse({ - dRepIDHex: dRepIDHex, - dRepIDBech32: dRepIDBech32, - }) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + return { + dRepIDHex: dRepID.to_hex(), + dRepIDBech32: dRepID.to_bech32('drep'), + } + }, + }) const apiProps = { apiName: 'getPubDRepKey', diff --git a/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js b/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js index e346c15..b792a38 100644 --- a/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js +++ b/src/components/cards/cip95getUnregisteredPubStakeKeysCard.js @@ -1,32 +1,17 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { getPublicKeyFromHex } from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const Cip95GetUnregisteredPubStakeKeysCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getUnregisteredPubStakeKeysClick = () => { - onWaiting(true) - api?.cip95 - .getUnregisteredPubStakeKeys() - .then((unregPubStakeKeys) => { - logger.log('unregPubStakeKeys: ', unregPubStakeKeys) - onWaiting(false) - onRawResponse(unregPubStakeKeys) - if (unregPubStakeKeys.length < 1) { - onResponse('No Unregistered Pub Stake Keys', false) - } else { - const unregPubStakeKey = unregPubStakeKeys[0] - const stakeKeyHash = getPublicKeyFromHex(unregPubStakeKey).hash().to_hex() - onResponse(stakeKeyHash, false) - } - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getUnregisteredPubStakeKeysClick = () => + runApiCall(() => api.cip95.getUnregisteredPubStakeKeys(), {onRawResponse, onResponse, onWaiting}, { + parse: (unregPubStakeKeys) => + unregPubStakeKeys.length < 1 + ? 'No Unregistered Pub Stake Keys' + : getPublicKeyFromHex(unregPubStakeKeys[0]).hash().to_hex(), + stringify: false, + }) const apiProps = { apiName: 'getUnregisteredPubStakeKeys', diff --git a/src/components/cards/createRandomKeyCard.js b/src/components/cards/createRandomKeyCard.js index 40ec8fa..d8b8ce7 100644 --- a/src/components/cards/createRandomKeyCard.js +++ b/src/components/cards/createRandomKeyCard.js @@ -1,35 +1,28 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import { getAddressFromCred, getCredential, getSecretKey } from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const CreateRandomKeyPart = ({onRawResponse, onResponse, onWaiting}) => { - const clickFunction = () => { - onWaiting(true) - try { - const wasmSK = getSecretKey() - const wasmPK = wasmSK.to_public(); - const hash = wasmPK.to_raw_key().hash(); - const cred = getCredential(hash); - const mainnetAddress = getAddressFromCred(1, cred) - const testnetAddress = getAddressFromCred(0, cred) - onRawResponse(''); - onResponse({ - privateKeyHex: wasmSK.to_raw_key().to_hex(), - publicKeyHex: wasmPK.to_raw_key().to_hex(), - pubKeyHash: hash.to_hex(), - mainnetAddress, - testnetAddress, - }); - } catch(e) { - onRawResponse(''); - onResponse(e); - logger.error(e); - } finally { - onWaiting(false); - } - } + const clickFunction = () => + runApiCall( + async () => { + const wasmSK = getSecretKey() + const wasmPK = wasmSK.to_public() + const hash = wasmPK.to_raw_key().hash() + const cred = getCredential(hash) + return { + privateKeyHex: wasmSK.to_raw_key().to_hex(), + publicKeyHex: wasmPK.to_raw_key().to_hex(), + pubKeyHash: hash.to_hex(), + mainnetAddress: getAddressFromCred(1, cred), + testnetAddress: getAddressFromCred(0, cred), + } + }, + {onRawResponse, onResponse, onWaiting}, + {rawText: () => ''}, + ) return { - const getAccountsClick = () => { - onWaiting(true) - window.ethereum - .request({method: 'eth_accounts'}) - .then((accounts) => { - onWaiting(false) - onRawResponse(JSON.stringify(accounts)) - onResponse(accounts) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.error(e) - }) - } + const getAccountsClick = () => + runApiCall(() => window.ethereum.request({method: 'eth_accounts'}), {onRawResponse, onResponse, onWaiting}, { + rawText: (accounts) => JSON.stringify(accounts), + }) return } diff --git a/src/components/cards/ethereum/getChainIdCard.js b/src/components/cards/ethereum/getChainIdCard.js index eb7338d..4352476 100644 --- a/src/components/cards/ethereum/getChainIdCard.js +++ b/src/components/cards/ethereum/getChainIdCard.js @@ -1,24 +1,12 @@ -import logger from '../../../utils/logger' import React from 'react' import ApiCard from '../apiCard' +import runApiCall from '../../../utils/runApiCall' const GetChainIdCard = ({onRawResponse, onResponse, onWaiting}) => { - const getChainIdClick = () => { - onWaiting(true) - window.ethereum - .request({method: 'eth_chainId'}) - .then((chainId) => { - onWaiting(false) - onRawResponse(chainId) - onResponse({chainId, decimal: parseInt(chainId, 16)}) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.error(e) - }) - } + const getChainIdClick = () => + runApiCall(() => window.ethereum.request({method: 'eth_chainId'}), {onRawResponse, onResponse, onWaiting}, { + parse: (chainId) => ({chainId, decimal: parseInt(chainId, 16)}), + }) return } diff --git a/src/components/cards/ethereum/getErc20BalanceCard.js b/src/components/cards/ethereum/getErc20BalanceCard.js index e88dfa8..212298a 100644 --- a/src/components/cards/ethereum/getErc20BalanceCard.js +++ b/src/components/cards/ethereum/getErc20BalanceCard.js @@ -1,43 +1,30 @@ -import logger from '../../../utils/logger' /* global BigInt */ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../../ui-constants' import {balanceOfData} from '../../../utils/ethereumUtils' +import runApiCall from '../../../utils/runApiCall' const GetErc20BalanceCard = ({accounts, onRawResponse, onResponse, onWaiting}) => { const [contractAddress, setContractAddress] = useState('') const [holderAddress, setHolderAddress] = useState('') - const getBalanceClick = async () => { + const getBalanceClick = () => { const holder = holderAddress || (accounts && accounts[0]) if (!holder) { onResponse('No address to check') return } - onWaiting(true) - try { - const result = await window.ethereum.request({ - method: 'eth_call', - params: [ - { - to: contractAddress, - data: balanceOfData(holder), - }, - 'latest', - ], - }) - onRawResponse(result) - // result is a 32-byte hex: parse as BigInt - const balance = BigInt(result) - onResponse({contract: contractAddress, holder, rawHex: result, balance: balance.toString()}) - } catch (e) { - onRawResponse('') - onResponse(e) - logger.error(e) - } finally { - onWaiting(false) - } + return runApiCall( + () => + window.ethereum.request({ + method: 'eth_call', + params: [{to: contractAddress, data: balanceOfData(holder)}, 'latest'], + }), + {onRawResponse, onResponse, onWaiting}, + // result is a 32-byte hex; parse as BigInt + {parse: (result) => ({contract: contractAddress, holder, rawHex: result, balance: BigInt(result).toString()})}, + ) } const isValid = contractAddress.startsWith('0x') && contractAddress.length === 42 diff --git a/src/components/cards/ethereum/getEthBalanceCard.js b/src/components/cards/ethereum/getEthBalanceCard.js index 14de94f..2db03cc 100644 --- a/src/components/cards/ethereum/getEthBalanceCard.js +++ b/src/components/cards/ethereum/getEthBalanceCard.js @@ -1,7 +1,7 @@ -import logger from '../../../utils/logger' import React from 'react' import ApiCard from '../apiCard' import {weiHexToEth} from '../../../utils/ethereumUtils' +import runApiCall from '../../../utils/runApiCall' const GetEthBalanceCard = ({accounts, onRawResponse, onResponse, onWaiting}) => { const getBalanceClick = () => { @@ -9,20 +9,11 @@ const GetEthBalanceCard = ({accounts, onRawResponse, onResponse, onWaiting}) => onResponse('No account connected') return } - onWaiting(true) - window.ethereum - .request({method: 'eth_getBalance', params: [accounts[0], 'latest']}) - .then((hexBalance) => { - onWaiting(false) - onRawResponse(hexBalance) - onResponse({account: accounts[0], balanceWei: hexBalance, balanceEth: weiHexToEth(hexBalance)}) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.error(e) - }) + return runApiCall( + () => window.ethereum.request({method: 'eth_getBalance', params: [accounts[0], 'latest']}), + {onRawResponse, onResponse, onWaiting}, + {parse: (hexBalance) => ({account: accounts[0], balanceWei: hexBalance, balanceEth: weiHexToEth(hexBalance)})}, + ) } return diff --git a/src/components/cards/ethereum/sendEthTransactionCard.js b/src/components/cards/ethereum/sendEthTransactionCard.js index f909460..af7f84f 100644 --- a/src/components/cards/ethereum/sendEthTransactionCard.js +++ b/src/components/cards/ethereum/sendEthTransactionCard.js @@ -1,39 +1,27 @@ -import logger from '../../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../../ui-constants' import {ethToHexWei} from '../../../utils/ethereumUtils' +import runApiCall from '../../../utils/runApiCall' const SendEthTransactionCard = ({accounts, onRawResponse, onResponse, onWaiting}) => { const [toAddress, setToAddress] = useState('') const [amount, setAmount] = useState('') - const sendTxClick = async () => { + const sendTxClick = () => { if (!accounts || accounts.length === 0) { onResponse('No account connected') return } - onWaiting(true) - try { - const txHash = await window.ethereum.request({ - method: 'eth_sendTransaction', - params: [ - { - from: accounts[0], - to: toAddress, - value: ethToHexWei(amount), - }, - ], - }) - onRawResponse(txHash) - onResponse({txHash, from: accounts[0], to: toAddress, amountEth: amount}) - } catch (e) { - onRawResponse('') - onResponse(e) - logger.error(e) - } finally { - onWaiting(false) - } + return runApiCall( + () => + window.ethereum.request({ + method: 'eth_sendTransaction', + params: [{from: accounts[0], to: toAddress, value: ethToHexWei(amount)}], + }), + {onRawResponse, onResponse, onWaiting}, + {parse: (txHash) => ({txHash, from: accounts[0], to: toAddress, amountEth: amount})}, + ) } const isValid = toAddress.startsWith('0x') && toAddress.length === 42 && amount && parseFloat(amount) > 0 diff --git a/src/components/cards/ethereum/signEthMessageCard.js b/src/components/cards/ethereum/signEthMessageCard.js index 4a3ae95..94f38aa 100644 --- a/src/components/cards/ethereum/signEthMessageCard.js +++ b/src/components/cards/ethereum/signEthMessageCard.js @@ -1,31 +1,21 @@ -import logger from '../../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../../ui-constants' +import runApiCall from '../../../utils/runApiCall' const SignEthMessageCard = ({accounts, onRawResponse, onResponse, onWaiting}) => { const [message, setMessage] = useState('') - const signMessageClick = async () => { + const signMessageClick = () => { if (!accounts || accounts.length === 0) { onResponse('No account connected') return } - onWaiting(true) - try { - const signature = await window.ethereum.request({ - method: 'personal_sign', - params: [message, accounts[0]], - }) - onRawResponse(signature) - onResponse({account: accounts[0], message, signature}) - } catch (e) { - onRawResponse('') - onResponse(e) - logger.error(e) - } finally { - onWaiting(false) - } + return runApiCall( + () => window.ethereum.request({method: 'personal_sign', params: [message, accounts[0]]}), + {onRawResponse, onResponse, onWaiting}, + {parse: (signature) => ({account: accounts[0], message, signature})}, + ) } return ( diff --git a/src/components/cards/ethereum/transferErc20Card.js b/src/components/cards/ethereum/transferErc20Card.js index 2f2e3ff..7a44d76 100644 --- a/src/components/cards/ethereum/transferErc20Card.js +++ b/src/components/cards/ethereum/transferErc20Card.js @@ -1,42 +1,29 @@ -import logger from '../../../utils/logger' /* global BigInt */ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../../ui-constants' import {transferData} from '../../../utils/ethereumUtils' +import runApiCall from '../../../utils/runApiCall' const TransferErc20Card = ({accounts, onRawResponse, onResponse, onWaiting}) => { const [contractAddress, setContractAddress] = useState('') const [toAddress, setToAddress] = useState('') const [amount, setAmount] = useState('') - const transferClick = async () => { + const transferClick = () => { if (!accounts || accounts.length === 0) { onResponse('No account connected') return } - onWaiting(true) - try { - const amountWei = BigInt(amount).toString() - const txHash = await window.ethereum.request({ - method: 'eth_sendTransaction', - params: [ - { - from: accounts[0], - to: contractAddress, - data: transferData(toAddress, amountWei), - }, - ], - }) - onRawResponse(txHash) - onResponse({txHash, contract: contractAddress, from: accounts[0], to: toAddress, amount}) - } catch (e) { - onRawResponse('') - onResponse(e) - logger.error(e) - } finally { - onWaiting(false) - } + return runApiCall( + () => + window.ethereum.request({ + method: 'eth_sendTransaction', + params: [{from: accounts[0], to: contractAddress, data: transferData(toAddress, BigInt(amount).toString())}], + }), + {onRawResponse, onResponse, onWaiting}, + {parse: (txHash) => ({txHash, contract: contractAddress, from: accounts[0], to: toAddress, amount})}, + ) } const isValid = diff --git a/src/components/cards/getBalanceCard.js b/src/components/cards/getBalanceCard.js index 3fb79a8..756bed7 100644 --- a/src/components/cards/getBalanceCard.js +++ b/src/components/cards/getBalanceCard.js @@ -1,29 +1,20 @@ -import logger from '../../utils/logger' import React from 'react' import {wasmMultiassetToJSONs} from '../../utils/utils' import ApiCard from './apiCard' import {getCslValue} from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const GetBalanceCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getBalanceClick = () => { - onWaiting(true) - api - ?.getBalance() - .then((hexBalance) => { - onWaiting(false) - onRawResponse(hexBalance) + const getBalanceClick = () => + runApiCall(() => api.getBalance(), {onRawResponse, onResponse, onWaiting}, { + parse: (hexBalance) => { const cslValue = getCslValue(hexBalance) - const adaValue = cslValue.coin().to_str() - const assetValue = wasmMultiassetToJSONs(cslValue.multiasset()) - onResponse({lovelaces: adaValue, assets: assetValue}) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + return { + lovelaces: cslValue.coin().to_str(), + assets: wasmMultiassetToJSONs(cslValue.multiasset()), + } + }, + }) const apiProps = { apiName: 'getBalance', diff --git a/src/components/cards/getChangeAddressCard.js b/src/components/cards/getChangeAddressCard.js index ee5adc7..65d42ce 100644 --- a/src/components/cards/getChangeAddressCard.js +++ b/src/components/cards/getChangeAddressCard.js @@ -1,25 +1,14 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import {getBech32AddressFromHex} from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const GetChangeAddressCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getChangeAddressClick = () => { - onWaiting(true) - api - ?.getChangeAddress() - .then((hexAddress) => { - onWaiting(false) - onRawResponse(hexAddress) - onResponse(getBech32AddressFromHex(hexAddress), false) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getChangeAddressClick = () => + runApiCall(() => api.getChangeAddress(), {onRawResponse, onResponse, onWaiting}, { + parse: getBech32AddressFromHex, + stringify: false, + }) const apiProps = { apiName: 'getChangeAddress', diff --git a/src/components/cards/getCollateralUtxosCard.js b/src/components/cards/getCollateralUtxosCard.js index e881a7c..93bb9f4 100644 --- a/src/components/cards/getCollateralUtxosCard.js +++ b/src/components/cards/getCollateralUtxosCard.js @@ -1,33 +1,17 @@ -import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {CommonStyles, ModalWindowContent} from '../ui-constants' import {getAmountInHex, getUtxoFromHex} from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const GetCollateralUtxosCard = ({api, onRawResponse, onResponse, onWaiting}) => { const [getCollateralUtxosInput, setGetCollateralUtxosInput] = useState('2000000') const getCollateralUtxosClick = () => { const amountInHex = getCollateralUtxosInput ? getAmountInHex(getCollateralUtxosInput) : undefined - onWaiting(true) - api - ?.getCollateral(amountInHex) - .then((hexUtxos) => { - onWaiting(false) - onRawResponse(hexUtxos) - let utxos = [] - for (const hexUtxo of hexUtxos) { - const utxo = getUtxoFromHex(hexUtxo) - utxos.push(utxo) - } - onResponse(utxos) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) + return runApiCall(() => api.getCollateral(amountInHex), {onRawResponse, onResponse, onWaiting}, { + parse: (hexUtxos) => hexUtxos.map(getUtxoFromHex), + }) } const apiProps = { diff --git a/src/components/cards/getExtensionsCard.js b/src/components/cards/getExtensionsCard.js index 68822c5..52f6a9c 100644 --- a/src/components/cards/getExtensionsCard.js +++ b/src/components/cards/getExtensionsCard.js @@ -1,23 +1,10 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' +import runApiCall from '../../utils/runApiCall' const GetExtensionsCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getExtensionsClick = () => { - onWaiting(true) - api?.getExtensions() - .then((response) => { - onWaiting(false) - onRawResponse('') - onResponse(response) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getExtensionsClick = () => + runApiCall(() => api.getExtensions(), {onRawResponse, onResponse, onWaiting}, {rawText: () => ''}) const apiProps = { apiName: 'getExtensions', diff --git a/src/components/cards/getNetworkIdCard.js b/src/components/cards/getNetworkIdCard.js index 0b84a80..42a7227 100644 --- a/src/components/cards/getNetworkIdCard.js +++ b/src/components/cards/getNetworkIdCard.js @@ -1,24 +1,10 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' +import runApiCall from '../../utils/runApiCall' const GetNetworkIdCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getNetworkIdClick = () => { - onWaiting(true) - api - ?.getNetworkId() - .then((response) => { - onWaiting(false) - onRawResponse(response) - onResponse(response) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getNetworkIdClick = () => + runApiCall(() => api.getNetworkId(), {onRawResponse, onResponse, onWaiting}) const apiProps = { apiName: 'getNetworkId', diff --git a/src/components/cards/getRewardAddressesCard.js b/src/components/cards/getRewardAddressesCard.js index d370954..cbaaa4c 100644 --- a/src/components/cards/getRewardAddressesCard.js +++ b/src/components/cards/getRewardAddressesCard.js @@ -1,29 +1,13 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import {getBech32AddressFromHex} from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const GetRewardAddressesCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getRewardAddressesClick = () => { - onWaiting(true) - api - ?.getRewardAddresses() - .then((hexAddresses) => { - onWaiting(false) - onRawResponse(hexAddresses) - const addresses = [] - for (const hexAddr of hexAddresses) { - addresses.push(getBech32AddressFromHex(hexAddr)) - } - onResponse(addresses) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getRewardAddressesClick = () => + runApiCall(() => api.getRewardAddresses(), {onRawResponse, onResponse, onWaiting}, { + parse: (hexAddresses) => hexAddresses.map(getBech32AddressFromHex), + }) const apiProps = { apiName: 'getRewardAddresses', diff --git a/src/components/cards/getUnusedAddressCard.js b/src/components/cards/getUnusedAddressCard.js index 3461840..1879c2a 100644 --- a/src/components/cards/getUnusedAddressCard.js +++ b/src/components/cards/getUnusedAddressCard.js @@ -1,29 +1,13 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' import {getBech32AddressFromHex} from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const GetUnusedAddressesCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const getUnusedAddressesClick = () => { - onWaiting(true) - api - ?.getUnusedAddresses() - .then((hexAddresses) => { - onWaiting(false) - onRawResponse(hexAddresses) - const addresses = [] - for (const hexAddr of hexAddresses) { - addresses.push(getBech32AddressFromHex(hexAddr)) - } - onResponse(addresses) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getUnusedAddressesClick = () => + runApiCall(() => api.getUnusedAddresses(), {onRawResponse, onResponse, onWaiting}, { + parse: (hexAddresses) => hexAddresses.map(getBech32AddressFromHex), + }) const apiProps = { apiName: 'getUnusedAddresses', diff --git a/src/components/cards/getUsedAddressCard.js b/src/components/cards/getUsedAddressCard.js index 37bd7c7..210a7f3 100644 --- a/src/components/cards/getUsedAddressCard.js +++ b/src/components/cards/getUsedAddressCard.js @@ -1,32 +1,16 @@ -import logger from '../../utils/logger' import React, {useState} from 'react' import {getBech32AddressFromHex} from '../../utils/cslTools' import ApiCardWithModal from './apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../ui-constants' +import runApiCall from '../../utils/runApiCall' const GetUsedAddresses = ({api, onRawResponse, onResponse, onWaiting}) => { const [usedAddressInput, setUsedAddressInput] = useState({page: 0, limit: 5}) - const getUsedAddressesClick = () => { - onWaiting(true) - api - ?.getUsedAddresses(usedAddressInput) - .then((hexAddresses) => { - onWaiting(false) - onRawResponse(hexAddresses) - const addresses = [] - for (const hexAddr of hexAddresses) { - addresses.push(getBech32AddressFromHex(hexAddr)) - } - onResponse(addresses) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getUsedAddressesClick = () => + runApiCall(() => api.getUsedAddresses(usedAddressInput), {onRawResponse, onResponse, onWaiting}, { + parse: (hexAddresses) => hexAddresses.map(getBech32AddressFromHex), + }) const apiProps = { buttonLabel: 'getUsedAddresses', diff --git a/src/components/cards/getUtxosCard.js b/src/components/cards/getUtxosCard.js index c744699..5b14263 100644 --- a/src/components/cards/getUtxosCard.js +++ b/src/components/cards/getUtxosCard.js @@ -1,33 +1,18 @@ -import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {ModalWindowContent, CommonStyles} from '../ui-constants' import {getUtxoFromHex} from '../../utils/cslTools' +import runApiCall from '../../utils/runApiCall' const GetUtxosCard = ({api, onRawResponse, onResponse, onWaiting}) => { const [getUtxosInput, setGetUtxosInput] = useState({amount: '', page: 0, limit: 10}) - const getUtxosClick = () => { - onWaiting(true) - api - ?.getUtxos(getUtxosInput.amount, {page: getUtxosInput.page, limit: getUtxosInput.limit}) - .then((hexUtxos) => { - onWaiting(false) - onRawResponse(hexUtxos) - let utxos = [] - for (const hexUtxo of hexUtxos) { - const utxo = getUtxoFromHex(hexUtxo) - utxos.push(utxo) - } - onResponse(utxos) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const getUtxosClick = () => + runApiCall( + () => api.getUtxos(getUtxosInput.amount, {page: getUtxosInput.page, limit: getUtxosInput.limit}), + {onRawResponse, onResponse, onWaiting}, + {parse: (hexUtxos) => hexUtxos.map(getUtxoFromHex)}, + ) const apiProps = { buttonLabel: 'getUtxos', diff --git a/src/components/cards/isEnabledCard.js b/src/components/cards/isEnabledCard.js index 5449e92..40e0687 100644 --- a/src/components/cards/isEnabledCard.js +++ b/src/components/cards/isEnabledCard.js @@ -1,23 +1,9 @@ -import logger from '../../utils/logger' import ApiCard from './apiCard' +import runApiCall from '../../utils/runApiCall' const IsEnabledCard = ({onRawResponse, onResponse, onWaiting, selectedWallet}) => { - const isDisabledClick = () => { - onWaiting(true) - window.cardano[selectedWallet] - ?.isEnabled() - .then((enabled) => { - onWaiting(false) - onRawResponse(enabled) - onResponse(enabled) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.error(e) - }) - } + const isDisabledClick = () => + runApiCall(() => window.cardano[selectedWallet].isEnabled(), {onRawResponse, onResponse, onWaiting}) const apiProps = { apiName: 'isEnabled', diff --git a/src/components/cards/listNFTsCard.js b/src/components/cards/listNFTsCard.js index a53efa3..030c4e8 100644 --- a/src/components/cards/listNFTsCard.js +++ b/src/components/cards/listNFTsCard.js @@ -1,24 +1,10 @@ -import logger from '../../utils/logger' import React from 'react' import ApiCard from './apiCard' +import runApiCall from '../../utils/runApiCall' const ListNFTsCard = ({api, onRawResponse, onResponse, onWaiting}) => { - const listNFTsClick = () => { - onWaiting(true) - api?.experimental - .listNFTs() - .then((response) => { - onWaiting(false) - onRawResponse('') - onResponse(response) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const listNFTsClick = () => + runApiCall(() => api.experimental.listNFTs(), {onRawResponse, onResponse, onWaiting}, {rawText: () => ''}) const apiProps = { apiName: 'listNFTs', diff --git a/src/components/cards/submitTransactionCard.js b/src/components/cards/submitTransactionCard.js index 8820332..b4ed413 100644 --- a/src/components/cards/submitTransactionCard.js +++ b/src/components/cards/submitTransactionCard.js @@ -1,27 +1,13 @@ -import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {CommonStyles, ModalWindowContent} from '../ui-constants' +import runApiCall from '../../utils/runApiCall' const SubmitTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { const [submitTransactionInput, setSubmitTransactionInput] = useState('') - const submitTransactionClick = () => { - onWaiting(true) - api - ?.submitTx(submitTransactionInput) - .then((txId) => { - onWaiting(false) - onRawResponse(txId) - onResponse(txId, false) - }) - .catch((e) => { - onWaiting(false) - onRawResponse('') - onResponse(e) - logger.log(e) - }) - } + const submitTransactionClick = () => + runApiCall(() => api.submitTx(submitTransactionInput), {onRawResponse, onResponse, onWaiting}, {stringify: false}) const apiProps = { buttonLabel: 'submitTx', diff --git a/src/utils/runApiCall.js b/src/utils/runApiCall.js new file mode 100644 index 0000000..b6c54f8 --- /dev/null +++ b/src/utils/runApiCall.js @@ -0,0 +1,28 @@ +import logger from './logger' + +// Shared lifecycle for the API cards: flip the waiting flag, run the wallet +// call, then publish the raw response and a parsed result — or publish the error. +// Collapses the identical then/catch envelope that every card used to repeat. +// +// call () => Promise the wallet/API call to run +// handlers { onRawResponse, onResponse, onWaiting } (card props) +// options.parse (raw) => result value passed to onResponse (default: identity) +// options.rawText (raw) => shown value passed to onRawResponse (default: identity) +// options.stringify boolean 2nd arg to onResponse (default: true) +export const runApiCall = async (call, {onRawResponse, onResponse, onWaiting}, options = {}) => { + const {parse = (raw) => raw, rawText = (raw) => raw, stringify = true} = options + onWaiting(true) + try { + const raw = await call() + onRawResponse(rawText(raw)) + onResponse(parse(raw), stringify) + } catch (e) { + onRawResponse('') + onResponse(e) + logger.error(e) + } finally { + onWaiting(false) + } +} + +export default runApiCall diff --git a/src/utils/runApiCall.test.js b/src/utils/runApiCall.test.js new file mode 100644 index 0000000..bcf87f8 --- /dev/null +++ b/src/utils/runApiCall.test.js @@ -0,0 +1,47 @@ +import {runApiCall} from './runApiCall' + +const makeHandlers = () => ({ + onRawResponse: jest.fn(), + onResponse: jest.fn(), + onWaiting: jest.fn(), +}) + +describe('runApiCall', () => { + it('toggles waiting on then off around a successful call', async () => { + const handlers = makeHandlers() + await runApiCall(() => Promise.resolve('ok'), handlers) + + expect(handlers.onWaiting).toHaveBeenNthCalledWith(1, true) + expect(handlers.onWaiting).toHaveBeenLastCalledWith(false) + }) + + it('publishes the raw and parsed response (stringify default true)', async () => { + const handlers = makeHandlers() + await runApiCall(() => Promise.resolve('42'), handlers) + + expect(handlers.onRawResponse).toHaveBeenCalledWith('42') + expect(handlers.onResponse).toHaveBeenCalledWith('42', true) + }) + + it('applies parse, rawText and stringify options', async () => { + const handlers = makeHandlers() + await runApiCall(() => Promise.resolve(2), handlers, { + parse: (n) => n * 10, + rawText: (n) => `raw:${n}`, + stringify: false, + }) + + expect(handlers.onRawResponse).toHaveBeenCalledWith('raw:2') + expect(handlers.onResponse).toHaveBeenCalledWith(20, false) + }) + + it('publishes the error and clears raw on failure', async () => { + const handlers = makeHandlers() + const err = new Error('boom') + await runApiCall(() => Promise.reject(err), handlers) + + expect(handlers.onRawResponse).toHaveBeenCalledWith('') + expect(handlers.onResponse).toHaveBeenCalledWith(err) + expect(handlers.onWaiting).toHaveBeenLastCalledWith(false) + }) +}) From 9de376a77b8200b16b26ad503cf3c3d1129d48fd Mon Sep 17 00:00:00 2001 From: Denis Nebytov Date: Wed, 8 Jul 2026 14:01:21 +0300 Subject: [PATCH 07/19] refactor: route card input fields through InputWithLabel - Extend InputWithLabel with placeholder, min, step, disabled and wrapperClassName props (disabled swaps to the disabled input style) - Replace ~22 hand-rolled label+input blocks across 11 cards with InputWithLabel - Removes duplicated CommonStyles.inputStyles / contentLabelStyle markup --- src/components/cards/buildTransactionCard.js | 45 +++++-------- src/components/cards/cip95SignDataCard.js | 40 ++++-------- .../cards/ethereum/getErc20BalanceCard.js | 43 +++++-------- .../cards/ethereum/sendEthTransactionCard.js | 48 ++++++-------- .../cards/ethereum/signEthMessageCard.js | 17 +++-- .../cards/ethereum/transferErc20Card.js | 63 +++++++------------ .../cards/getCollateralUtxosCard.js | 16 +++-- src/components/cards/getUsedAddressCard.js | 48 ++++++-------- src/components/cards/getUtxosCard.js | 61 +++++++----------- src/components/cards/signDataCard.js | 41 +++++------- src/components/cards/signTransactionCard.js | 18 +++--- src/components/cards/submitTransactionCard.js | 18 +++--- src/components/inputWithLabel.js | 11 +++- 13 files changed, 179 insertions(+), 290 deletions(-) diff --git a/src/components/cards/buildTransactionCard.js b/src/components/cards/buildTransactionCard.js index df27b6c..236ab5b 100644 --- a/src/components/cards/buildTransactionCard.js +++ b/src/components/cards/buildTransactionCard.js @@ -9,7 +9,8 @@ import { getAddressFromBech32, } from '../../utils/cslTools' import ApiCardWithModal from './apiCardWithModal' -import {ModalWindowContent, CommonStyles} from '../ui-constants' +import {ModalWindowContent} from '../ui-constants' +import InputWithLabel from '../inputWithLabel' import CheckboxWithLabel from '../checkboxWithLabel' const BuildTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { @@ -82,21 +83,15 @@ const BuildTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { return (
-
- - setBuildTransactionInput({...buildTransactionInput, amount: event.target.value})} - disabled={isAmountInputDisabled} - /> -
+ setBuildTransactionInput({...buildTransactionInput, amount: event.target.value})} + disabled={isAmountInputDisabled} + wrapperClassName="" + /> { @@ -109,19 +104,11 @@ const BuildTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { name="sendAll" labelText="Send all (no change)" /> -
- - setBuildTransactionInput({...buildTransactionInput, address: event.target.value})} - /> -
+ setBuildTransactionInput({...buildTransactionInput, address: event.target.value})} + />
) diff --git a/src/components/cards/cip95SignDataCard.js b/src/components/cards/cip95SignDataCard.js index a89166e..53e273d 100644 --- a/src/components/cards/cip95SignDataCard.js +++ b/src/components/cards/cip95SignDataCard.js @@ -2,7 +2,8 @@ import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {Buffer} from 'buffer' -import {CommonStyles, ModalWindowContent} from '../ui-constants' +import {ModalWindowContent} from '../ui-constants' +import InputWithLabel from '../inputWithLabel' const Cip95SignDataCard = ({api, onRawResponse, onResponse, onWaiting}) => { const [message, setMessage] = useState('') @@ -50,32 +51,17 @@ const Cip95SignDataCard = ({api, onRawResponse, onResponse, onWaiting}) => { return (
-
- - setAddressOrDRep(event.target.value)} - /> -
-
- - setMessage(event.target.value)} - /> -
+ setAddressOrDRep(event.target.value)} + wrapperClassName="" + /> + setMessage(event.target.value)} + />
) diff --git a/src/components/cards/ethereum/getErc20BalanceCard.js b/src/components/cards/ethereum/getErc20BalanceCard.js index 212298a..8eed972 100644 --- a/src/components/cards/ethereum/getErc20BalanceCard.js +++ b/src/components/cards/ethereum/getErc20BalanceCard.js @@ -1,7 +1,8 @@ /* global BigInt */ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' -import {ModalWindowContent, CommonStyles} from '../../ui-constants' +import {ModalWindowContent} from '../../ui-constants' +import InputWithLabel from '../../inputWithLabel' import {balanceOfData} from '../../../utils/ethereumUtils' import runApiCall from '../../../utils/runApiCall' @@ -32,32 +33,20 @@ const GetErc20BalanceCard = ({accounts, onRawResponse, onResponse, onWaiting}) = return (
-
- - setContractAddress(e.target.value)} - /> -
-
- - setHolderAddress(e.target.value)} - /> -
+ setContractAddress(e.target.value)} + placeholder="0xTokenContractAddress" + wrapperClassName="mb-3" + /> + setHolderAddress(e.target.value)} + placeholder="0xHolderAddress (optional)" + wrapperClassName="" + />
) diff --git a/src/components/cards/ethereum/sendEthTransactionCard.js b/src/components/cards/ethereum/sendEthTransactionCard.js index af7f84f..7b4afc2 100644 --- a/src/components/cards/ethereum/sendEthTransactionCard.js +++ b/src/components/cards/ethereum/sendEthTransactionCard.js @@ -1,6 +1,7 @@ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' -import {ModalWindowContent, CommonStyles} from '../../ui-constants' +import {ModalWindowContent} from '../../ui-constants' +import InputWithLabel from '../../inputWithLabel' import {ethToHexWei} from '../../../utils/ethereumUtils' import runApiCall from '../../../utils/runApiCall' @@ -29,34 +30,23 @@ const SendEthTransactionCard = ({accounts, onRawResponse, onResponse, onWaiting} return (
-
- - setToAddress(e.target.value)} - /> -
-
- - setAmount(e.target.value)} - /> -
+ setToAddress(e.target.value)} + placeholder="0xRecipientAddress" + wrapperClassName="mb-3" + /> + setAmount(e.target.value)} + placeholder="0.001" + wrapperClassName="" + />
) diff --git a/src/components/cards/ethereum/signEthMessageCard.js b/src/components/cards/ethereum/signEthMessageCard.js index 94f38aa..9ab3d2b 100644 --- a/src/components/cards/ethereum/signEthMessageCard.js +++ b/src/components/cards/ethereum/signEthMessageCard.js @@ -1,6 +1,7 @@ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' -import {ModalWindowContent, CommonStyles} from '../../ui-constants' +import {ModalWindowContent} from '../../ui-constants' +import InputWithLabel from '../../inputWithLabel' import runApiCall from '../../../utils/runApiCall' const SignEthMessageCard = ({accounts, onRawResponse, onResponse, onWaiting}) => { @@ -21,16 +22,12 @@ const SignEthMessageCard = ({accounts, onRawResponse, onResponse, onWaiting}) => return (
- - setMessage(e.target.value)} placeholder="Hello, Ethereum!" - value={message} - onChange={(e) => setMessage(e.target.value)} + wrapperClassName="" />
diff --git a/src/components/cards/ethereum/transferErc20Card.js b/src/components/cards/ethereum/transferErc20Card.js index 7a44d76..43895d7 100644 --- a/src/components/cards/ethereum/transferErc20Card.js +++ b/src/components/cards/ethereum/transferErc20Card.js @@ -1,7 +1,8 @@ /* global BigInt */ import React, {useState} from 'react' import ApiCardWithModal from '../apiCardWithModal' -import {ModalWindowContent, CommonStyles} from '../../ui-constants' +import {ModalWindowContent} from '../../ui-constants' +import InputWithLabel from '../../inputWithLabel' import {transferData} from '../../../utils/ethereumUtils' import runApiCall from '../../../utils/runApiCall' @@ -37,45 +38,27 @@ const TransferErc20Card = ({accounts, onRawResponse, onResponse, onWaiting}) => return (
-
- - setContractAddress(e.target.value)} - /> -
-
- - setToAddress(e.target.value)} - /> -
-
- - setAmount(e.target.value)} - /> -
+ setContractAddress(e.target.value)} + placeholder="0xTokenContractAddress" + wrapperClassName="mb-3" + /> + setToAddress(e.target.value)} + placeholder="0xRecipientAddress" + wrapperClassName="mb-3" + /> + setAmount(e.target.value)} + placeholder="1000000000000000000" + wrapperClassName="" + />
) diff --git a/src/components/cards/getCollateralUtxosCard.js b/src/components/cards/getCollateralUtxosCard.js index 93bb9f4..edb9669 100644 --- a/src/components/cards/getCollateralUtxosCard.js +++ b/src/components/cards/getCollateralUtxosCard.js @@ -1,6 +1,7 @@ import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' -import {CommonStyles, ModalWindowContent} from '../ui-constants' +import {ModalWindowContent} from '../ui-constants' +import InputWithLabel from '../inputWithLabel' import {getAmountInHex, getUtxoFromHex} from '../../utils/cslTools' import runApiCall from '../../utils/runApiCall' @@ -22,17 +23,14 @@ const GetCollateralUtxosCard = ({api, onRawResponse, onResponse, onWaiting}) => return (
- - setGetCollateralUtxosInput(event.target.value)} + inputValue={getCollateralUtxosInput} + onChangeFunction={(event) => setGetCollateralUtxosInput(event.target.value)} + wrapperClassName="" />
diff --git a/src/components/cards/getUsedAddressCard.js b/src/components/cards/getUsedAddressCard.js index 210a7f3..98cce0e 100644 --- a/src/components/cards/getUsedAddressCard.js +++ b/src/components/cards/getUsedAddressCard.js @@ -1,7 +1,7 @@ import React, {useState} from 'react' import {getBech32AddressFromHex} from '../../utils/cslTools' import ApiCardWithModal from './apiCardWithModal' -import {ModalWindowContent, CommonStyles} from '../ui-constants' +import InputWithLabel from '../inputWithLabel' import runApiCall from '../../utils/runApiCall' const GetUsedAddresses = ({api, onRawResponse, onResponse, onWaiting}) => { @@ -20,34 +20,24 @@ const GetUsedAddresses = ({api, onRawResponse, onResponse, onWaiting}) => { return (
-
- - setUsedAddressInput({...usedAddressInput, page: Number(event.target.value)})} - /> -
-
- - setUsedAddressInput({...usedAddressInput, limit: Number(event.target.value)})} - /> -
+ setUsedAddressInput({...usedAddressInput, page: Number(event.target.value)})} + wrapperClassName="" + /> + setUsedAddressInput({...usedAddressInput, limit: Number(event.target.value)})} + wrapperClassName="" + />
) diff --git a/src/components/cards/getUtxosCard.js b/src/components/cards/getUtxosCard.js index 5b14263..f162c43 100644 --- a/src/components/cards/getUtxosCard.js +++ b/src/components/cards/getUtxosCard.js @@ -1,6 +1,7 @@ import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' -import {ModalWindowContent, CommonStyles} from '../ui-constants' +import {ModalWindowContent} from '../ui-constants' +import InputWithLabel from '../inputWithLabel' import {getUtxoFromHex} from '../../utils/cslTools' import runApiCall from '../../utils/runApiCall' @@ -22,48 +23,32 @@ const GetUtxosCard = ({api, onRawResponse, onResponse, onWaiting}) => { return (
- - setGetUtxosInput({...getUtxosInput, amount: event.target.value})} + inputValue={getUtxosInput.amount} + onChangeFunction={(event) => setGetUtxosInput({...getUtxosInput, amount: event.target.value})} + wrapperClassName="" />
-
- - setGetUtxosInput({...getUtxosInput, page: Number(event.target.value)})} - /> -
-
- - setGetUtxosInput({...getUtxosInput, limit: Number(event.target.value)})} - /> -
+ setGetUtxosInput({...getUtxosInput, page: Number(event.target.value)})} + wrapperClassName="" + /> + setGetUtxosInput({...getUtxosInput, limit: Number(event.target.value)})} + wrapperClassName="" + />
) diff --git a/src/components/cards/signDataCard.js b/src/components/cards/signDataCard.js index b046317..2b8272a 100644 --- a/src/components/cards/signDataCard.js +++ b/src/components/cards/signDataCard.js @@ -2,9 +2,10 @@ import logger from '../../utils/logger' import React, {useState} from 'react' import ApiCardWithModal from './apiCardWithModal' import {Buffer} from 'buffer' -import {CommonStyles, ModalWindowContent} from '../ui-constants' +import {ModalWindowContent} from '../ui-constants' import {getBech32AddressFromHex} from '../../utils/cslTools' import SelectWithLabel from '../selectWithLabel' +import InputWithLabel from '../inputWithLabel' const SignDataCard = ({api, onRawResponse, onResponse, onWaiting}) => { const [message, setMessage] = useState('') @@ -101,38 +102,24 @@ const SignDataCard = ({api, onRawResponse, onResponse, onWaiting}) => { return (
-
- - setAddress(event.target.value)} - /> -
+ setAddress(event.target.value)} + wrapperClassName="" + /> setEncodingType(event.target.value)} defaultValue={encodingType} /> -
- - setMessage(event.target.value)} - /> -
+ setMessage(event.target.value)} + placeholder={encodingType === 'hex' ? 'e.g., 0x48656c6c6f or 48656c6c6f' : 'e.g., Hello'} + />
) diff --git a/src/components/cards/signTransactionCard.js b/src/components/cards/signTransactionCard.js index 299bf52..0df0c53 100644 --- a/src/components/cards/signTransactionCard.js +++ b/src/components/cards/signTransactionCard.js @@ -12,7 +12,8 @@ import { getAddressFromBech32, } from '../../utils/cslTools' import ApiCardWithModal from './apiCardWithModal' -import {CommonStyles, ModalWindowContent} from '../ui-constants' +import {ModalWindowContent} from '../ui-constants' +import InputWithLabel from '../inputWithLabel' const SignTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { const defaultValue = {amount: '2000000', address: ''} @@ -81,16 +82,11 @@ const SignTransactionCard = ({api, onRawResponse, onResponse, onWaiting}) => { return (
- - setSignTransactionInput(event.target.value)} + setSignTransactionInput(event.target.value)} + wrapperClassName="" />