Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 404e31f

Browse files
committed
fix: allow failed address checker users to perform unbond
1 parent 9728e9d commit 404e31f

4 files changed

Lines changed: 115 additions & 7 deletions

File tree

src/ui/common/context/wallet/BTCWalletProvider.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,19 @@ import {
3535
toNetwork,
3636
} from "@/ui/common/utils/wallet";
3737

38+
import { useAddressScreeningService } from "../../hooks/services/useAddressScreeningService";
39+
3840
const btcConfig = getNetworkConfigBTC();
41+
const supportedNetworkMessage =
42+
"Only Native SegWit and Taproot addresses are supported. Please switch the address type in your wallet and try again.";
3943

4044
interface BTCWalletContextProps {
4145
loading: boolean;
4246
network?: networks.Network;
4347
publicKeyNoCoord: string;
4448
address: string;
4549
connected: boolean;
50+
failedBtcAddressRiskAssessment: boolean;
4651
disconnect: () => void;
4752
open: () => void;
4853
getAddress: () => Promise<string>;
@@ -70,6 +75,7 @@ const BTCWalletContext = createContext<BTCWalletContextProps>({
7075
connected: false,
7176
publicKeyNoCoord: "",
7277
address: "",
78+
failedBtcAddressRiskAssessment: false,
7379
disconnect: () => {},
7480
open: () => {},
7581
getAddress: async () => "",
@@ -87,6 +93,8 @@ const BTCWalletContext = createContext<BTCWalletContextProps>({
8793

8894
export const BTCWalletProvider = ({ children }: PropsWithChildren) => {
8995
const [loading, setLoading] = useState(true);
96+
const [failedBtcAddressRiskAssessment, setFailedBtcAddressRiskAssessment] =
97+
useState(false);
9098
const [btcWalletProvider, setBTCWalletProvider] = useState<IBTCProvider>();
9199
const [network, setNetwork] = useState<networks.Network>();
92100
const [publicKeyNoCoord, setPublicKeyNoCoord] = useState("");
@@ -97,24 +105,25 @@ export const BTCWalletProvider = ({ children }: PropsWithChildren) => {
97105
const { open = () => {}, connected } = useWalletConnect();
98106
const logger = useLogger();
99107
const { updateUser } = useSentryUser();
108+
const { screenAddress, clearAddressScreeningResult } =
109+
useAddressScreeningService();
100110

101111
const btcDisconnect = useCallback(() => {
102112
setBTCWalletProvider(undefined);
103113
setNetwork(undefined);
104114
setPublicKeyNoCoord("");
105115
setAddress("");
116+
setFailedBtcAddressRiskAssessment(false);
106117

107118
updateUser({ btcAddress: null });
108-
}, [updateUser]);
119+
clearAddressScreeningResult();
120+
}, [updateUser, clearAddressScreeningResult]);
109121

110122
const connectBTC = useCallback(
111123
async (walletProvider: IBTCProvider | null) => {
112124
if (!walletProvider) return;
113125
setLoading(true);
114126

115-
const supportedNetworkMessage =
116-
"Only Native SegWit and Taproot addresses are supported. Please switch the address type in your wallet and try again.";
117-
118127
try {
119128
const network = await walletProvider.getNetwork();
120129
if (network !== btcConfig.network) {
@@ -164,6 +173,9 @@ export const BTCWalletProvider = ({ children }: PropsWithChildren) => {
164173
throw emptyProcessedPubKeyError;
165174
}
166175

176+
const failedRiskAssessment = await screenAddress(address);
177+
setFailedBtcAddressRiskAssessment(failedRiskAssessment);
178+
167179
setBTCWalletProvider(walletProvider);
168180
setNetwork(toNetwork(network));
169181
setAddress(address);
@@ -192,7 +204,7 @@ export const BTCWalletProvider = ({ children }: PropsWithChildren) => {
192204
});
193205
}
194206
},
195-
[handleError, publicKeyNoCoord, address, logger, updateUser],
207+
[handleError, publicKeyNoCoord, address, logger, updateUser, screenAddress],
196208
);
197209

198210
useEffect(() => {
@@ -288,13 +300,15 @@ export const BTCWalletProvider = ({ children }: PropsWithChildren) => {
288300
network,
289301
publicKeyNoCoord,
290302
address,
303+
failedBtcAddressRiskAssessment,
291304
connected,
292305
open,
293306
disconnect: btcDisconnect,
294307
...btcWalletMethods,
295308
}),
296309
[
297310
loading,
311+
failedBtcAddressRiskAssessment,
298312
connected,
299313
network,
300314
publicKeyNoCoord,

src/ui/common/context/wallet/WalletConnectionProvider.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { useTheme } from "next-themes";
77
import { useCallback, type PropsWithChildren } from "react";
88

99
import { logTermsAcceptance } from "@/ui/common/api/logTermAcceptance";
10-
import { verifyBTCAddress } from "@/ui/common/api/verifyBTCAddress";
1110
import { getNetworkConfigBBN } from "@/ui/common/config/network/bbn";
1211
import { getNetworkConfigBTC } from "@/ui/common/config/network/btc";
1312
import { ClientError, ERROR_CODES } from "@/ui/common/errors";
@@ -20,7 +19,6 @@ const context = typeof window !== "undefined" ? window : {};
2019

2120
const lifecycleHooks = {
2221
acceptTermsOfService: logTermsAcceptance,
23-
verifyBTCAddress: verifyBTCAddress,
2422
};
2523

2624
const config: ChainConfigArr = [
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { useCallback } from "react";
2+
3+
import { verifyBTCAddress } from "../../api/verifyBTCAddress";
4+
import {
5+
clearBtcAddressScreeningResult,
6+
getBtcAddressScreeningResult,
7+
setBtcAddressScreeningResult,
8+
} from "../../utils/local_storage/addressScreeningStorage";
9+
import { useLogger } from "../useLogger";
10+
11+
export function useAddressScreeningService() {
12+
const logger = useLogger();
13+
14+
const screenAddress = useCallback(
15+
async (btcAddress: string) => {
16+
try {
17+
// Check cache first
18+
const cachedResult = getBtcAddressScreeningResult();
19+
if (cachedResult && cachedResult.btcAddress === btcAddress) {
20+
return cachedResult.failedRiskAssessment;
21+
}
22+
23+
// Perform screening
24+
const riskAssessment = await verifyBTCAddress(btcAddress);
25+
const failedRiskAssessment = !riskAssessment;
26+
27+
// Cache result
28+
setBtcAddressScreeningResult(btcAddress, failedRiskAssessment);
29+
30+
logger.info("Address screening completed", {
31+
btcAddress,
32+
failedRiskAssessment,
33+
});
34+
35+
return failedRiskAssessment;
36+
} catch (error: any) {
37+
logger.error(error, { data: { btcAddress } });
38+
return false; // Default to safe
39+
}
40+
},
41+
[logger],
42+
);
43+
44+
const clearAddressScreeningResult = useCallback(() => {
45+
clearBtcAddressScreeningResult();
46+
}, []);
47+
48+
return {
49+
screenAddress,
50+
clearAddressScreeningResult,
51+
};
52+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { network } from "@/ui/common/config/network/bbn";
2+
3+
export const BTC_ADDRESS_SCREENING_KEY = `btc-address-screening-${network}`;
4+
5+
export interface BtcAddressScreening {
6+
btcAddress: string;
7+
failedRiskAssessment: boolean;
8+
}
9+
10+
export function getBtcAddressScreeningResult():
11+
| BtcAddressScreening
12+
| undefined {
13+
try {
14+
const value = localStorage.getItem(BTC_ADDRESS_SCREENING_KEY);
15+
if (!value) return undefined;
16+
const parsed = JSON.parse(value);
17+
return parsed;
18+
} catch {
19+
return undefined;
20+
}
21+
}
22+
23+
export function setBtcAddressScreeningResult(
24+
address: string,
25+
failedRiskAssessment: boolean = false,
26+
): void {
27+
try {
28+
if (!address) return;
29+
localStorage.setItem(
30+
BTC_ADDRESS_SCREENING_KEY,
31+
JSON.stringify({ btcAddress: address, failedRiskAssessment }),
32+
);
33+
} catch {
34+
/* noop */
35+
}
36+
}
37+
38+
export function clearBtcAddressScreeningResult(): void {
39+
try {
40+
localStorage.removeItem(BTC_ADDRESS_SCREENING_KEY);
41+
} catch {
42+
/* noop */
43+
}
44+
}

0 commit comments

Comments
 (0)