-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: Geo blocking with 451 #382
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import axios, { isAxiosError } from "axios"; | ||
|
||
import { | ||
API_ERROR_MESSAGE, | ||
GEO_BLOCK_MESSAGE, | ||
HealthCheckResult, | ||
HealthCheckStatus, | ||
} from "../types/healthCheck"; | ||
|
||
interface HealthCheckResponse { | ||
data: string; | ||
} | ||
|
||
export const getHealthCheck = async (): Promise<HealthCheckResult> => { | ||
try { | ||
const response = await axios.get( | ||
`${process.env.NEXT_PUBLIC_API_URL}/healthcheck`, | ||
); | ||
const healthCheckAPIResponse: HealthCheckResponse = response.data; | ||
// If the response has a data field, it's a normal response | ||
if (healthCheckAPIResponse.data) { | ||
return { | ||
status: HealthCheckStatus.Normal, | ||
message: healthCheckAPIResponse.data, | ||
}; | ||
} else { | ||
// Something went wrong | ||
throw new Error(API_ERROR_MESSAGE); | ||
} | ||
} catch (error: Error | any) { | ||
// Geo-blocking is a custom status code | ||
if ( | ||
isAxiosError(error) && | ||
(error.response?.status === 451 || error.request.status === 451) | ||
) { | ||
return { | ||
status: HealthCheckStatus.GeoBlocked, | ||
message: error.request?.response?.message || GEO_BLOCK_MESSAGE, | ||
}; | ||
} else { | ||
return { | ||
status: HealthCheckStatus.Error, | ||
message: | ||
error.request?.response?.message || | ||
error?.message || | ||
API_ERROR_MESSAGE, | ||
}; | ||
} | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,9 +1,17 @@ | ||||||
import { useRef, useState } from "react"; | ||||||
import { AiOutlineInfoCircle } from "react-icons/ai"; | ||||||
import { FaBitcoin } from "react-icons/fa"; | ||||||
import { IoMdClose } from "react-icons/io"; | ||||||
import { PiWalletBold } from "react-icons/pi"; | ||||||
import { Tooltip } from "react-tooltip"; | ||||||
import { useOnClickOutside } from "usehooks-ts"; | ||||||
|
||||||
import { | ||||||
API_ERROR_MESSAGE, | ||||||
GEO_BLOCK_MESSAGE, | ||||||
HealthCheckResult, | ||||||
HealthCheckStatus, | ||||||
} from "@/app/types/healthCheck"; | ||||||
import { getNetworkConfig } from "@/config/network.config"; | ||||||
import { satoshiToBtc } from "@/utils/btcConversions"; | ||||||
import { maxDecimals } from "@/utils/maxDecimals"; | ||||||
|
@@ -17,13 +25,15 @@ interface ConnectSmallProps { | |||||
address: string; | ||||||
btcWalletBalanceSat?: number; | ||||||
onDisconnect: () => void; | ||||||
apiAvailable?: HealthCheckResult; | ||||||
} | ||||||
|
||||||
export const ConnectSmall: React.FC<ConnectSmallProps> = ({ | ||||||
onConnect, | ||||||
address, | ||||||
btcWalletBalanceSat, | ||||||
onDisconnect, | ||||||
apiAvailable, | ||||||
}) => { | ||||||
const [showMenu, setShowMenu] = useState(false); | ||||||
const handleClickOutside = () => { | ||||||
|
@@ -35,6 +45,31 @@ export const ConnectSmall: React.FC<ConnectSmallProps> = ({ | |||||
|
||||||
const { coinName, networkName } = getNetworkConfig(); | ||||||
|
||||||
const renderApiAvailableTooltip = () => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's also have a comment describing what this function's purpose is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
if (!apiAvailable) return null; | ||||||
|
||||||
const message = | ||||||
apiAvailable.status === HealthCheckStatus.GeoBlocked | ||||||
? GEO_BLOCK_MESSAGE | ||||||
: API_ERROR_MESSAGE; | ||||||
|
||||||
return ( | ||||||
<> | ||||||
<span | ||||||
className="cursor-pointer text-xs" | ||||||
data-tooltip-id={`tooltip-connect-${apiAvailable.status}`} | ||||||
data-tooltip-content={message} | ||||||
data-tooltip-place="bottom" | ||||||
> | ||||||
<AiOutlineInfoCircle /> | ||||||
</span> | ||||||
<Tooltip id={`tooltip-connect-${apiAvailable.status}`} /> | ||||||
</> | ||||||
); | ||||||
}; | ||||||
|
||||||
const isApiNormal = apiAvailable?.status === HealthCheckStatus.Normal; | ||||||
|
||||||
return address ? ( | ||||||
<div className="relative mr-[-10px] text-sm hidden md:flex" ref={ref}> | ||||||
<button | ||||||
|
@@ -92,13 +127,16 @@ export const ConnectSmall: React.FC<ConnectSmallProps> = ({ | |||||
)} | ||||||
</div> | ||||||
) : ( | ||||||
<button | ||||||
className="btn-primary btn h-[2.5rem] min-h-[2.5rem] rounded-full px-2 text-white md:rounded-lg" | ||||||
onClick={onConnect} | ||||||
disabled={!!address} | ||||||
> | ||||||
<PiWalletBold size={20} className="flex md:hidden" /> | ||||||
<span className="hidden md:flex">Connect to {networkName} network</span> | ||||||
</button> | ||||||
<div className="flex items-center gap-1"> | ||||||
<button | ||||||
className="btn-primary btn h-[2.5rem] min-h-[2.5rem] rounded-full px-2 text-white md:rounded-lg" | ||||||
onClick={onConnect} | ||||||
disabled={!!address || !isApiNormal} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add a comment denoting that we disable the button if the API is not healthy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||
> | ||||||
<PiWalletBold size={20} className="flex md:hidden" /> | ||||||
<span className="hidden md:flex">Connect to {networkName} network</span> | ||||||
</button> | ||||||
{!isApiNormal && renderApiAvailableTooltip()} | ||||||
</div> | ||||||
); | ||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export type HealthCheckResult = | ||
| { status: HealthCheckStatus.Normal; message: string } | ||
| { status: HealthCheckStatus.GeoBlocked; message: string } | ||
| { status: HealthCheckStatus.Error; message: string }; | ||
|
||
export enum HealthCheckStatus { | ||
Normal = "normal", | ||
GeoBlocked = "geoblocked", | ||
Error = "error", | ||
} | ||
|
||
export const API_ERROR_MESSAGE = | ||
"Error occurred while fetching API. Please try again later"; | ||
export const GEO_BLOCK_MESSAGE = | ||
"The Bitcoin Staking functionality is not available in your region"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this
?
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is undefined before we fetch and get into one of the
normal - geoblocking - error
state