Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions components/Layout/Header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import CurrencyTable from './CurrencyTable'
import NetworkTable from './NetworkTable'
import MobileMenu from './MobileMenu'
import { FaAngleDown } from 'react-icons/fa'
import { FaWallet } from 'react-icons/fa'
import { IoIosRocket } from 'react-icons/io'

import LogoSmall from '../LogoSmall'
Expand Down Expand Up @@ -522,6 +523,9 @@ export default function Header({
)}

<hr className="hr" />
<Link href="/auth/connect-wallet" className="link">
<FaWallet /> Connect Wallet
</Link>
<Link href="/admin">
<IoIosRocket style={{ fontSize: '1.2em', marginBottom: '-2px' }} /> Bithomp Pro
</Link>
Expand Down
2 changes: 2 additions & 0 deletions components/SignForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ export default function SignForm({
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [uuid])

if (!signRequest) return null
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!signRequest) return null is executed before afterSigning, onSignIn, afterSubmitExe, etc. are initialized, but the useEffect([uuid]) callback above references those bindings. In cases where the app renders SignForm with a UUID but no signRequest (see pages/_app.js condition (signRequest || isValidUUID(uuid))), this will cause a runtime error when the effect runs. Either avoid returning early in this way, or only return early when both signRequest and uuid are absent, and ensure any functions used by effects are defined before the return.

Suggested change
if (!signRequest) return null
if (!signRequest && !uuid) return null

Copilot uses AI. Check for mistakes.

const txSend = (options) => {
//when the request is wallet specific it's a priority, logout if not matched
//when request is not wallet specific, use the account wallet if loggedin
Expand Down
127 changes: 127 additions & 0 deletions pages/auth/connect-wallet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { useState } from 'react'

import { useTranslation } from 'next-i18next'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import Image from 'next/image'

import SignForm from '../../components/SignForm'

export async function getServerSideProps(context) {
const { locale } = context
return {
props: {
...(await serverSideTranslations(locale, ['common']))
}
}
}

export default function ConnectWallet() {
const { t } = useTranslation('common')

const [account, setAccount] = useState(null)
const [signRequest, setSignRequest] = useState(null)
const [refreshPage, setRefreshPage] = useState('')
const [wcSession, setWcSession] = useState(null)

const handleWalletClick = (wallet) => {
setSignRequest({
wallet: wallet,
redirectName: 'connect-wallet'
})
}

return (
<main className="content-center">
<h1>{t('connect-wallet.title', 'Connect your crypto wallet')}</h1>
<p>
{t(
'connect-wallet.description',
'Connect your crypto wallet to the blockchain explorer to start exploring XRP Ledger.'
)}
</p>
<section className="mx-auto max-w-sm">
<ul className="list-none flex flex-col gap-2">
<li className="flex justify-center items-center gap-2 border-2 border-black p-2 hover:shadow-[4px_4px_0px_0px] transition-shadow duration-300">
<span onClick={() => handleWalletClick('xaman')}>
<Image src="/images/wallets/xaman.png" alt="Xaman" width={24} height={24} />
<span>Xaman</span>
</span>
Comment on lines +43 to +48
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wallet options are implemented as clickable <span>/<li> elements without keyboard support or semantics, which makes the list inaccessible (no tab focus, no Enter/Space activation, no role). Please use <button type="button"> (or a <Link> where appropriate) for each wallet option and attach the click handler to the button so the whole row is operable via keyboard and screen readers.

Copilot uses AI. Check for mistakes.
</li>
<li
onClick={() => handleWalletClick('crossmark')}
className="flex justify-center items-center gap-2 border-2 border-black p-2 hover:shadow-[4px_4px_0px_0px] transition-shadow duration-300"
>
<span>
<Image
src="/images/wallets/crossmark.png"
className="wallet-logo"
alt="Crossmark Wallet"
height={24}
width={24}
/>
Crossmark
</span>
</li>
<li className="flex justify-center items-center gap-2 border-2 border-black p-2 hover:shadow-[4px_4px_0px_0px] transition-shadow duration-300">
<span onClick={() => handleWalletClick('gemwallet')}>
<Image
src="/images/wallets/gemwallet.svg"
className="wallet-logo"
alt="GemWallet"
height={24}
width={24}
/>
GemWallet
</span>
</li>
<li className="flex justify-center items-center gap-2 border-2 border-black p-2 hover:shadow-[4px_4px_0px_0px] transition-shadow duration-300">
<span onClick={() => handleWalletClick('metamask')}>
<Image
src="/images/wallets/metamask.svg"
className="wallet-logo"
alt="Metamask Wallet"
height={24}
width={24}
/>
Metamask
</span>
</li>
<li className="flex justify-center items-center gap-2 border-2 border-black p-2 hover:shadow-[4px_4px_0px_0px] transition-shadow duration-300">
<span onClick={() => handleWalletClick('ledgerwallet')}>
<Image
src="/images/wallets/ledgerwallet.svg"
className="wallet-logo"
alt="Ledger Wallet"
height={24}
width={24}
/>
Ledger
</span>
</li>
<li className="flex justify-center items-center gap-2 border-2 border-black p-2 hover:shadow-[4px_4px_0px_0px] transition-shadow duration-300">
<span onClick={() => handleWalletClick('trezor')}>
<Image
src="/images/wallets/trezor.svg"
className="wallet-logo"
alt="Trezor Wallet"
height={24}
width={24}
/>
Trezor
</span>
</li>
</ul>
</section>
<SignForm
signRequest={signRequest}
setSignRequest={setSignRequest}
refreshPage={refreshPage}
setRefreshPage={setRefreshPage}
account={account}
setAccount={setAccount}
wcSession={wcSession}
setWcSession={setWcSession}
/>
Comment on lines +115 to +124
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page renders SignForm directly but does not pass saveAddressData. SignForm calls await saveAddressData({ address, wallet }) during onSignIn without a guard, which will throw when a sign-in completes. Recommend relying on the existing global SignForm in pages/_app.js (set the global signRequest via props) rather than embedding SignForm here, or otherwise ensure saveAddressData is provided.

Copilot uses AI. Check for mistakes.
</main>
)
}
2 changes: 1 addition & 1 deletion styles/components/signForm.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.sign-in-form {
background: rgba(black, 0.6);
position: absolute;
position: fixed;
top: 0;
right: 0;
bottom: 0;
Expand Down
2 changes: 1 addition & 1 deletion styles/ui.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ body.dark {
.content-text,
.content-center,
.content-profile {
z-index: 1;
// z-index: 1;
position: relative;
}
Comment on lines 99 to 104
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting out z-index: 1 on .content-* makes those positioned elements fall back to z-index: auto. Since .background is also positioned (position: absolute) and is rendered after .content in the DOM (see components/Layout/BackgroundImage.js), the background layer can paint over the page content. Please restore a positive z-index for the content layer, or explicitly push .background behind (e.g., negative z-index / separate stacking context).

Copilot uses AI. Check for mistakes.

Expand Down
Loading