Skip to content

Commit d7d52d7

Browse files
committed
complete merge from main
2 parents 6ad3ae0 + dbf5277 commit d7d52d7

86 files changed

Lines changed: 21891 additions & 14528 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/api-react/src/services/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,7 @@ export const {
155155
useGetTransactionsCountQuery,
156156
useGetCurrentAddressQuery,
157157
useGetNextAddressMutation,
158-
useGetCoinRecordsByNamesQuery,
159-
useLazyGetCoinRecordsByNamesQuery,
158+
useGetCoinRecordsByNamesMutation,
160159
usePushTransactionsMutation,
161160
useSelectCoinsQuery,
162161
useLazySelectCoinsQuery,

packages/api-react/src/services/wallet.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ export const walletApi = apiWithTag.injectEndpoints({
544544
invalidatesTags: (result, _error, { walletId }) => (result ? [{ type: 'Address', id: walletId }] : []),
545545
}),
546546

547-
getCoinRecordsByNames: query(build, WalletService, 'getCoinRecordsByNames'),
547+
getCoinRecordsByNames: mutation(build, WalletService, 'getCoinRecordsByNames'),
548548

549549
pushTransactions: mutation(build, WalletService, 'pushTransactions', {
550550
invalidatesTags: [{ type: 'Transactions', id: 'LIST' }],
@@ -1567,8 +1567,7 @@ export const {
15671567
useGetTransactionsCountQuery,
15681568
useGetCurrentAddressQuery,
15691569
useGetNextAddressMutation,
1570-
useGetCoinRecordsByNamesQuery,
1571-
useLazyGetCoinRecordsByNamesQuery,
1570+
useGetCoinRecordsByNamesMutation,
15721571
usePushTransactionsMutation,
15731572
useSelectCoinsQuery,
15741573
useLazySelectCoinsQuery,

packages/core/src/hooks/useGetLatestVersionFromWebsite.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ export default function useGetLatestVersionFromWebsite(): UseGetLatestVersionFro
4646
return;
4747
}
4848

49+
async function validateBlogUrl(blogUrlPath: string): Promise<boolean> {
50+
try {
51+
const fullBlogUrl = new URL(blogUrlPath, 'https://www.chia.net/').toString();
52+
const blogResponse = await fetch(fullBlogUrl, { method: 'HEAD' });
53+
return blogResponse.ok;
54+
} catch {
55+
return false;
56+
}
57+
}
58+
4959
async function fetchLatestVersion() {
5060
try {
5161
const response = await fetch(latestVersionURL as string, {
@@ -59,11 +69,19 @@ export default function useGetLatestVersionFromWebsite(): UseGetLatestVersionFro
5969
const data = await response.json();
6070
const { version, downloadPageUrl, releaseNotesUrl, blogUrl } = data;
6171

72+
let validatedBlogUrl: string | null = blogUrl ?? null;
73+
if (blogUrl) {
74+
const blogExists = await validateBlogUrl(blogUrl);
75+
if (!blogExists) {
76+
validatedBlogUrl = null;
77+
}
78+
}
79+
6280
setTimeout(() => {
6381
setLatestVersion(version);
6482
setDownloadPath(downloadPageUrl);
6583
setReleaseNotesPath(releaseNotesUrl);
66-
setBlogPath(blogUrl);
84+
setBlogPath(validatedBlogUrl);
6785
setIsLoading(false);
6886
}, 1000); /* we need the delay, otherwise dialog will close too fast */
6987
} catch (e) {

packages/gui/src/hooks/useWalletConnect.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,18 @@ export default function useWalletConnect(config: UseWalletConnectConfig) {
4040
const processRef = useRef(process);
4141
processRef.current = process;
4242

43+
const pairsRef = useRef(pairs);
44+
pairsRef.current = pairs;
45+
4346
const isLoadingData = isLoading || isLoadingWalletConnectCommand;
4447

4548
useEffect(() => {
4649
if (!client) {
4750
return undefined;
4851
}
4952

50-
return bindEvents(client, pairs, () => processRef.current);
51-
}, [client, pairs]);
53+
return bindEvents(client, pairsRef.current, () => processRef.current);
54+
}, [client]);
5255

5356
const handlePair = useCallback(
5457
async (uri: string, fingerprints: number[], mainnet = false) => {
@@ -61,7 +64,7 @@ export default function useWalletConnect(config: UseWalletConnectConfig) {
6164
throw new Error('Pairing failed');
6265
}
6366

64-
pairs.addPair({
67+
pairsRef.current.addPair({
6568
topic,
6669
fingerprints,
6770
mainnet,
@@ -70,7 +73,7 @@ export default function useWalletConnect(config: UseWalletConnectConfig) {
7073

7174
return topic;
7275
},
73-
[client, pairs],
76+
[client],
7477
);
7578

7679
const handleDisconnect = useCallback(
@@ -79,9 +82,9 @@ export default function useWalletConnect(config: UseWalletConnectConfig) {
7982
throw new Error('Client is not defined');
8083
}
8184

82-
return disconnectPair(client, pairs, topic);
85+
return disconnectPair(client, pairsRef.current, topic);
8386
},
84-
[client, pairs],
87+
[client],
8588
);
8689

8790
return {

packages/gui/src/hooks/useWalletConnectClient.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ import { useState, useEffect, useCallback, useMemo } from 'react';
33

44
import useWalletConnectPreferences from './useWalletConnectPreferences';
55

6+
function clearWalletConnectStorage(): void {
7+
if (typeof indexedDB === 'undefined') return;
8+
try {
9+
indexedDB.deleteDatabase('WALLET_CONNECT_V2_INDEXED_DB');
10+
} catch {
11+
/* best-effort */
12+
}
13+
}
14+
615
const defaultMetadata = {
716
name: 'Chia Blockchain',
817
description: 'GUI for Chia Blockchain',
@@ -93,7 +102,10 @@ export default function useWalletConnectClient(config: UseWalletConnectConfig) {
93102
return createdClient;
94103
})
95104
.catch((initError) => {
105+
console.error('[WC] Client.init() failed, clearing storage', initError);
106+
clearWalletConnectStorage();
96107
singleton.initPromise = undefined;
108+
singleton.configKey = undefined;
97109
throw initError;
98110
});
99111
}

packages/gui/src/hooks/useWalletConnectPairs.ts

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,50 @@ export default function useWalletConnectPairs(): Pairs {
3434
pairsRef.current = localStorageData;
3535

3636
const updatePair = useCallback((topic: string, data: Partial<Omit<Pair, 'topic'>> | ((pair: Pair) => Pair)) => {
37-
const [, setPairs] = pairsRef.current;
37+
const [latestPairs, setPairs] = pairsRef.current;
38+
39+
const index = latestPairs.findIndex((item) => item.topic === topic);
40+
if (index !== -1) {
41+
const oldPair = latestPairs[index];
42+
const newPairing = typeof data === 'function' ? data(oldPair) : { ...oldPair, ...data };
43+
const newPairings = [...latestPairs];
44+
newPairings[index] = newPairing;
45+
pairsRef.current = [newPairings, setPairs];
46+
}
47+
3848
setPairs((pairs: Pair[]) => {
39-
const index = pairs.findIndex((item) => item.topic === topic);
40-
if (index === -1) {
49+
const idx = pairs.findIndex((item) => item.topic === topic);
50+
if (idx === -1) {
4151
return pairs;
4252
}
4353

44-
const oldPair = pairs[index];
54+
const oldPair = pairs[idx];
4555
const newPairing = typeof data === 'function' ? data(oldPair) : { ...oldPair, ...data };
4656
const newPairings = [...pairs];
47-
newPairings[index] = newPairing;
57+
newPairings[idx] = newPairing;
4858

4959
return newPairings;
5060
});
5161
}, []);
5262

5363
const removePair = useCallback((topic: string) => {
54-
const [, setPairs] = pairsRef.current;
64+
const [latestPairs, setPairs] = pairsRef.current;
65+
if (!latestPairs.some((item) => item.topic === topic)) {
66+
return;
67+
}
68+
69+
pairsRef.current = [latestPairs.filter((item) => item.topic !== topic), setPairs];
70+
5571
setPairs((pairs: Pair[]) => pairs.filter((item) => item.topic !== topic));
5672
}, []);
5773

5874
const removePairBySession = useCallback((sessionTopic: string) => {
59-
const [, setPairs] = pairsRef.current;
75+
const [latestPairs, setPairs] = pairsRef.current;
76+
pairsRef.current = [
77+
latestPairs.filter((item) => !item.sessions.find((session) => session.topic === sessionTopic)),
78+
setPairs,
79+
];
80+
6081
setPairs((pairs: Pair[]) =>
6182
pairs.filter((item) => !item.sessions.find((session) => session.topic === sessionTopic)),
6283
);
@@ -78,19 +99,31 @@ export default function useWalletConnectPairs(): Pairs {
7899
}, []);
79100

80101
const addPair = useCallback((pair: Pair) => {
81-
const [, setPairs] = pairsRef.current;
102+
const [latestPairs, setPairs] = pairsRef.current;
103+
if (latestPairs.findIndex((item) => item.topic === pair.topic) !== -1) {
104+
throw new Error('Pair already exists');
105+
}
106+
107+
pairsRef.current = [[...latestPairs, pair], setPairs];
108+
82109
setPairs((pairs: Pair[]) => {
83-
const index = pairs.findIndex((item) => item.topic === pair.topic);
84-
if (index !== -1) {
85-
throw new Error('Pair already exists');
110+
if (pairs.some((item) => item.topic === pair.topic)) {
111+
return pairs;
86112
}
87-
88113
return [...pairs, pair];
89114
});
90115
}, []);
91116

92117
const removeSessionFromPair = useCallback((sessionTopic: string) => {
93-
const [, setPairs] = pairsRef.current;
118+
const [latestPairs, setPairs] = pairsRef.current;
119+
pairsRef.current = [
120+
latestPairs.map((pair) => ({
121+
...pair,
122+
sessions: pair.sessions.filter((item) => item.topic !== sessionTopic),
123+
})),
124+
setPairs,
125+
];
126+
94127
setPairs((pairs: Pair[]) =>
95128
pairs.map((pair) => ({
96129
...pair,

packages/gui/src/index.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,31 @@ import { createRoot } from 'react-dom/client';
66
import App from './components/app/App';
77
import initPrefs from './init-prefs';
88

9+
// The WalletConnect SDK can reject internal promises with "No matching key"
10+
// during benign stale-pairing races (e.g. reconnecting after storage cleanup)
11+
// from async paths outside our try/catch sites, producing noisy errors in
12+
// DevTools. Suppress those specific rejections but leave a visible breadcrumb
13+
// so they are not completely silent, and scope the suppression to
14+
// WalletConnect-originated errors so unrelated code paths are not swallowed.
15+
window.addEventListener('unhandledrejection', (event) => {
16+
const { reason } = event;
17+
const message = reason?.message ?? String(reason);
18+
const stack: string = reason?.stack ?? '';
19+
20+
if (!message.includes('No matching key')) {
21+
return;
22+
}
23+
24+
const isWalletConnectOrigin = /walletconnect/i.test(stack);
25+
if (!isWalletConnectOrigin) {
26+
console.warn('[chia-gui] "No matching key" rejection from non-WalletConnect origin; not suppressing:', reason);
27+
return;
28+
}
29+
30+
console.info('[chia-gui] Suppressing WalletConnect stale-key rejection:', message);
31+
event.preventDefault();
32+
});
33+
934
// we need to use additional root for hot reloading
1035
function Root() {
1136
return <App />;

0 commit comments

Comments
 (0)