Skip to content

Commit b6eb4c5

Browse files
authored
fix(typink): persisted neworks (#285)
* fix persisted networks with reset default networks * tests * fix ci * clean up
1 parent 8747b22 commit b6eb4c5

File tree

8 files changed

+294
-102
lines changed

8 files changed

+294
-102
lines changed

packages/typink/src/atoms/clientAtoms.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ export const networkConnectionsAtom = atomWithStorage<NetworkConnection[]>(
1111
{ getOnInit: true },
1212
);
1313

14+
// Persistent atom for storing the intended default network IDs as JSON string to detect changes
15+
export const persistedDefaultNetworkIdsAtom = atomWithStorage<string>(
16+
'TYPINK::DEFAULT_NETWORK_IDS',
17+
'',
18+
undefined,
19+
{ getOnInit: true },
20+
);
21+
1422
// Atom for supported networks (set during provider initialization)
1523
export const supportedNetworksAtom = atom<NetworkInfo[]>([]);
1624

packages/typink/src/hooks/__tests__/useCheckMappedAccount.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ describe('useCheckMappedAccount', () => {
3939
};
4040

4141
beforeEach(() => {
42+
// Mock console methods to suppress expected error messages
43+
vi.spyOn(console, 'error').mockImplementation(() => {});
44+
vi.spyOn(console, 'warn').mockImplementation(() => {});
45+
4246
vi.mocked(useTypink).mockReturnValue(defaultMockTypink as any);
4347
vi.mocked(usePolkadotClient).mockReturnValue({
4448
client: mockClient,

packages/typink/src/hooks/__tests__/useLazyStorage.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ const createMockContract = (lazyStorageData: any): Contract<MockContractApi> =>
7373

7474
describe('useLazyStorage', () => {
7575
beforeEach(() => {
76+
// Mock console methods to suppress expected error messages
77+
vi.spyOn(console, 'error').mockImplementation(() => {});
78+
vi.spyOn(console, 'warn').mockImplementation(() => {});
79+
7680
vi.clearAllMocks();
7781
});
7882

@@ -247,7 +251,7 @@ describe('useLazyStorage', () => {
247251
expect(callCount).toBe(1);
248252

249253
// Trigger refresh
250-
result.current.refresh();
254+
await result.current.refresh();
251255

252256
await waitFor(() => {
253257
expect(result.current.isRefreshing).toBe(false);

packages/typink/src/hooks/__tests__/useRootStorage.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ describe('useRootStorage', () => {
1414
let mockContract: any;
1515

1616
beforeEach(() => {
17+
// Mock console methods to suppress expected error messages
18+
vi.spyOn(console, 'error').mockImplementation(() => {});
19+
vi.spyOn(console, 'warn').mockImplementation(() => {});
20+
1721
mockClient = {
1822
query: {
1923
system: {

packages/typink/src/providers/ClientProvider.tsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
currentNetworkAtom,
1616
currentNetworksAtom,
1717
networkConnectionsAtom,
18+
persistedDefaultNetworkIdsAtom,
1819
setNetworkAtom,
1920
setNetworksAtom,
2021
supportedNetworksAtom,
@@ -156,26 +157,49 @@ export function ClientProvider({
156157
// Get network connections from localStorage (via atomWithStorage)
157158
const [networkConnections, setNetworkConnections] = useAtom(networkConnectionsAtom);
158159

160+
// Get persisted default network IDs from localStorage (as JSON string)
161+
const [persistedDefaultNetworkIdsJson, setPersistedDefaultNetworkIdsJson] = useAtom(persistedDefaultNetworkIdsAtom);
162+
159163
// Initialize network connections and default network ID properly
160164
useMemo(() => {
161165
if (supportedNetworks.length === 0) return;
162166

167+
// Extract current default network IDs from initialConnections
168+
const currentDefaultNetworkIdsJson = JSON.stringify(initialConnections);
169+
163170
// Check if we have stored connections from localStorage
164171
if (networkConnections.length === 0 && initialConnections.length > 0) {
165172
setNetworkConnections(initialConnections);
173+
setPersistedDefaultNetworkIdsJson(currentDefaultNetworkIdsJson);
166174
} else if (networkConnections.length > 0) {
167-
// Check if all existing connections are in the supported networks or default networks list
175+
// Check if default network IDs have changed (simple string comparison)
176+
const defaultNetworkIdsChanged =
177+
!!persistedDefaultNetworkIdsJson && persistedDefaultNetworkIdsJson !== currentDefaultNetworkIdsJson;
178+
179+
// Check if default network IDs have changed (developer changed defaultNetworkIds/defaultNetworkId)
180+
if (defaultNetworkIdsChanged) {
181+
console.log(`Default network configuration changed. Resetting to new default networks.`);
182+
setNetworkConnections(initialConnections);
183+
setPersistedDefaultNetworkIdsJson(currentDefaultNetworkIdsJson);
184+
return; // Skip further validation since we're resetting
185+
}
186+
187+
// If we don't have persisted default network IDs yet (first run), store them
188+
if (!persistedDefaultNetworkIdsJson) {
189+
setPersistedDefaultNetworkIdsJson(currentDefaultNetworkIdsJson);
190+
}
191+
192+
// Check if all existing connections are in the supported networks
168193
const hasInvalidNetwork = networkConnections.some(
169-
(conn) =>
170-
!supportedNetworks.find((n) => n.id === conn.networkId) ||
171-
!initialConnections.find((n) => n.networkId === conn.networkId),
194+
(conn) => !supportedNetworks.find((n) => n.id === conn.networkId),
172195
);
173196

174197
if (hasInvalidNetwork) {
175198
console.warn(
176199
'Some persisted network connections are not in the supported networks list. Resetting to default networks.',
177200
);
178201
setNetworkConnections(initialConnections);
202+
setPersistedDefaultNetworkIdsJson(currentDefaultNetworkIdsJson);
179203
}
180204
}
181205
}, []); // Empty deps - only runs once on mount

packages/typink/src/providers/__tests__/ClientProvider.integration.test.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { beforeEach, describe, expect, it } from 'vitest';
1+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
22
import { renderHook } from '@testing-library/react';
33
import { ClientProvider, useClient } from '../ClientProvider.js';
44
import { NetworkInfo } from '../../types.js';
@@ -30,12 +30,21 @@ describe('ClientProvider Integration Tests', () => {
3030
beforeEach(() => {
3131
// Create fresh store for each test
3232
store = createStore();
33+
34+
// Mock console methods to suppress expected error messages
35+
vi.spyOn(console, 'error').mockImplementation(() => {});
36+
vi.spyOn(console, 'warn').mockImplementation(() => {});
37+
3338
// Clear localStorage to ensure clean state
3439
if (typeof window !== 'undefined' && window.localStorage) {
3540
window.localStorage.clear();
3641
}
3742
});
3843

44+
afterEach(() => {
45+
vi.restoreAllMocks();
46+
});
47+
3948
describe('Single Client Mode (Backward Compatibility)', () => {
4049
it('should provide client context with single network', () => {
4150
const wrapper = ({ children }: { children: React.ReactNode }) => (

0 commit comments

Comments
 (0)