@btc-vision/walletconnect 1.2.4 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import { Network } from '@btc-vision/bitcoin';
2
2
  import { Address } from '@btc-vision/transaction';
3
3
  import { AbstractRpcProvider } from 'opnet';
4
- import React from 'react';
5
- import { Signers, SupportedWallets, Wallets } from './WalletConnection.js';
4
+ import { ReactNode } from 'react';
5
+ import { Signers, SupportedWallets, Wallets } from './WalletConnection';
6
6
  export interface Account {
7
7
  isConnected: boolean;
8
8
  signer: Signers | null;
@@ -12,14 +12,14 @@ export interface Account {
12
12
  provider: AbstractRpcProvider;
13
13
  }
14
14
  interface WalletContextType {
15
- connect: (walletType: SupportedWallets, signal?: AbortSignal) => Promise<void>;
15
+ connect: (wallet: SupportedWallets, signal?: AbortSignal) => Promise<void>;
16
16
  disconnect: () => void;
17
17
  walletType: SupportedWallets | null;
18
18
  walletWindowInstance: Wallets | null;
19
19
  account: Account | null;
20
20
  }
21
- export declare const WalletProvider: React.FC<{
22
- children: React.ReactNode;
23
- }>;
21
+ export declare const WalletProvider: ({ children }: {
22
+ children: ReactNode;
23
+ }) => import("react/jsx-runtime").JSX.Element;
24
24
  export declare const useWallet: () => WalletContextType;
25
25
  export {};
@@ -1,31 +1,66 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useCallback, useContext, useEffect, useRef, useState, } from 'react';
3
- import WalletConnection, { SupportedWallets } from './WalletConnection.js';
3
+ import WalletConnection, { SupportedWallets } from './WalletConnection';
4
4
  const WalletContext = createContext(undefined);
5
- const maxRetries = 10;
6
- const delayBetweenRetries = 2000;
5
+ const MAX_RETRIES = 10;
6
+ const RETRY_DELAY_MS = 2000;
7
+ function useDocumentComplete(fn) {
8
+ const fired = useRef(false);
9
+ useEffect(() => {
10
+ if (fired.current)
11
+ return;
12
+ const run = () => {
13
+ if (fired.current)
14
+ return;
15
+ fired.current = true;
16
+ fn();
17
+ };
18
+ if (document.readyState === 'complete') {
19
+ run();
20
+ return;
21
+ }
22
+ const handler = () => {
23
+ if (document.readyState === 'complete') {
24
+ document.removeEventListener('readystatechange', handler);
25
+ run();
26
+ }
27
+ };
28
+ document.addEventListener('readystatechange', handler);
29
+ return () => document.removeEventListener('readystatechange', handler);
30
+ }, [fn]);
31
+ }
7
32
  export const WalletProvider = ({ children }) => {
8
33
  const [walletConnection] = useState(() => new WalletConnection());
9
34
  const [walletType, setWalletType] = useState(null);
10
35
  const [walletWindowInstance, setWalletWindowInstance] = useState(null);
11
36
  const [account, setAccount] = useState(null);
12
- const registeredEvents = useRef(false);
37
+ const listeners = useRef({});
13
38
  const disconnect = useCallback(() => {
39
+ const inst = walletWindowInstance;
40
+ if (inst) {
41
+ if (listeners.current.disconnect) {
42
+ inst.removeListener?.('disconnect', listeners.current.disconnect);
43
+ listeners.current.disconnect = undefined;
44
+ }
45
+ if (listeners.current.accountsChanged) {
46
+ inst.removeListener?.('accountsChanged', listeners.current.accountsChanged);
47
+ listeners.current.accountsChanged = undefined;
48
+ }
49
+ }
14
50
  walletConnection.disconnect();
15
51
  setWalletType(null);
16
52
  setWalletWindowInstance(null);
17
53
  localStorage.removeItem('walletType');
18
54
  setAccount(null);
19
- registeredEvents.current = false;
20
- }, [walletConnection]);
55
+ }, [walletConnection, walletWindowInstance]);
21
56
  const connect = useCallback(async (type, signal) => {
22
- let success = false;
23
57
  let attempt = 0;
24
- while (attempt < maxRetries) {
25
- if (signal?.aborted) {
26
- console.debug('Connection aborted.');
27
- return;
28
- }
58
+ const throwIfAborted = () => {
59
+ if (signal?.aborted)
60
+ throw new DOMException('Aborted', 'AbortError');
61
+ };
62
+ while (attempt < MAX_RETRIES) {
63
+ throwIfAborted();
29
64
  try {
30
65
  await walletConnection.connect(type);
31
66
  if ((walletConnection.walletType !== SupportedWallets.OP_WALLET &&
@@ -33,20 +68,22 @@ export const WalletProvider = ({ children }) => {
33
68
  !walletConnection.walletWindowInstance) {
34
69
  throw new Error('Wallet not fully loaded yet');
35
70
  }
36
- success = true;
37
71
  break;
38
72
  }
39
- catch (error) {
40
- console.warn(`Connection attempt ${attempt + 1} failed:`, error.message);
41
- }
42
- attempt++;
43
- if (attempt < maxRetries) {
73
+ catch (err) {
74
+ attempt += 1;
75
+ if (attempt >= MAX_RETRIES) {
76
+ console.warn(`Failed to connect after ${MAX_RETRIES} attempts.`, err);
77
+ disconnect();
78
+ return;
79
+ }
80
+ console.warn(`Connection attempt ${attempt} failed:`, err.message);
44
81
  try {
45
- await new Promise((resolve, reject) => {
46
- const timer = setTimeout(() => resolve(), delayBetweenRetries);
82
+ await new Promise((res, rej) => {
83
+ const t = setTimeout(res, RETRY_DELAY_MS);
47
84
  signal?.addEventListener('abort', () => {
48
- clearTimeout(timer);
49
- reject(new DOMException('Aborted', 'AbortError'));
85
+ clearTimeout(t);
86
+ rej(new DOMException('Aborted', 'AbortError'));
50
87
  });
51
88
  });
52
89
  }
@@ -56,25 +93,18 @@ export const WalletProvider = ({ children }) => {
56
93
  }
57
94
  }
58
95
  }
59
- if (!success) {
60
- console.warn(`Failed to connect after ${maxRetries} attempts.`);
61
- disconnect();
62
- return;
63
- }
64
- if (signal?.aborted) {
65
- console.debug('Connection aborted after a success, cleaning up.');
66
- disconnect();
67
- return;
68
- }
96
+ throwIfAborted();
69
97
  setWalletType(type);
70
98
  setWalletWindowInstance(walletConnection.walletWindowInstance);
71
99
  localStorage.setItem('walletType', type);
72
100
  try {
73
- const signer = walletConnection.signer;
74
- const address = await walletConnection.getAddress();
75
- const addressTyped = await walletConnection.getAddressTyped();
76
- const network = await walletConnection.getNetwork();
77
- const provider = await walletConnection.getProvider();
101
+ const [signer, address, addressTyped, network, provider] = await Promise.all([
102
+ walletConnection.signer,
103
+ walletConnection.getAddress(),
104
+ walletConnection.getAddressTyped(),
105
+ walletConnection.getNetwork(),
106
+ walletConnection.getProvider(),
107
+ ]);
78
108
  setAccount({
79
109
  isConnected: true,
80
110
  signer,
@@ -83,75 +113,66 @@ export const WalletProvider = ({ children }) => {
83
113
  network,
84
114
  provider,
85
115
  });
86
- if ((walletConnection.walletType === SupportedWallets.OP_WALLET ||
87
- walletConnection.walletType === SupportedWallets.UNISAT) &&
88
- walletConnection.walletWindowInstance &&
89
- !registeredEvents.current) {
90
- const instance = walletConnection.walletWindowInstance;
91
- instance.on('disconnect', () => {
92
- disconnect();
93
- });
94
- instance.on('accountsChanged', async () => {
116
+ const instance = walletConnection.walletWindowInstance;
117
+ if (instance) {
118
+ const onDisconnect = () => disconnect();
119
+ const onAccountsChanged = async () => {
95
120
  try {
96
- const updatedAddress = await walletConnection.getAddress();
97
- const updatedAddressTyped = await walletConnection.getAddressTyped();
98
- const updatedNetwork = await walletConnection.getNetwork();
99
- const updatedProvider = await walletConnection.getProvider();
121
+ const [updatedAddr, updatedAddrTyped, updatedNet, updatedProv] = await Promise.all([
122
+ walletConnection.getAddress(),
123
+ walletConnection.getAddressTyped(),
124
+ walletConnection.getNetwork(),
125
+ walletConnection.getProvider(),
126
+ ]);
100
127
  setAccount((prev) => prev
101
128
  ? {
102
129
  ...prev,
103
- address: updatedAddress,
104
- addressTyped: updatedAddressTyped,
105
- network: updatedNetwork,
106
- provider: updatedProvider,
130
+ address: updatedAddr,
131
+ addressTyped: updatedAddrTyped,
132
+ network: updatedNet,
133
+ provider: updatedProv,
107
134
  }
108
135
  : prev);
109
136
  }
110
- catch (err) {
137
+ catch {
111
138
  disconnect();
112
- throw err;
113
139
  }
114
- });
115
- registeredEvents.current = true;
140
+ };
141
+ listeners.current.disconnect = onDisconnect;
142
+ listeners.current.accountsChanged = onAccountsChanged;
143
+ instance.on('disconnect', onDisconnect);
144
+ instance.on('accountsChanged', onAccountsChanged);
116
145
  }
117
146
  }
118
- catch (error) {
119
- console.warn('Unable to finalize wallet connection:', error);
147
+ catch (err) {
148
+ console.warn('Unable to finalize wallet connection:', err);
120
149
  disconnect();
121
150
  }
122
- }, [disconnect, walletConnection]);
123
- useEffect(() => {
124
- const storedWalletType = localStorage.getItem('walletType');
125
- if (!storedWalletType)
151
+ }, [walletConnection, disconnect]);
152
+ useDocumentComplete(() => {
153
+ const stored = localStorage.getItem('walletType');
154
+ if (!stored)
126
155
  return;
127
156
  const controller = new AbortController();
128
- void (async () => {
129
- try {
130
- await connect(storedWalletType, controller.signal);
157
+ connect(stored, controller.signal).catch((err) => {
158
+ if (err.name !== 'AbortError') {
159
+ console.warn('Failed to reconnect to wallet:', err);
131
160
  }
132
- catch (error) {
133
- if (error.name !== 'AbortError') {
134
- console.warn('Failed to reconnect to wallet:', error);
135
- }
136
- }
137
- })();
138
- return () => {
139
- controller.abort();
140
- };
141
- }, [connect]);
142
- const value = {
161
+ });
162
+ return () => controller.abort();
163
+ });
164
+ const ctx = {
143
165
  connect,
144
166
  disconnect,
145
167
  walletType,
146
168
  walletWindowInstance,
147
169
  account,
148
170
  };
149
- return _jsx(WalletContext.Provider, { value: value, children: children });
171
+ return _jsx(WalletContext.Provider, { value: ctx, children: children });
150
172
  };
151
173
  export const useWallet = () => {
152
- const context = useContext(WalletContext);
153
- if (!context) {
174
+ const ctx = useContext(WalletContext);
175
+ if (!ctx)
154
176
  throw new Error('useWallet must be used within a WalletProvider');
155
- }
156
- return context;
177
+ return ctx;
157
178
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@btc-vision/walletconnect",
3
3
  "type": "module",
4
- "version": "1.2.4",
4
+ "version": "1.3.1",
5
5
  "author": "impredmet",
6
6
  "description": "The OP_NET Wallet Connect library helps your dApp connect to any compatible wallet.",
7
7
  "engines": {
@@ -67,10 +67,10 @@
67
67
  "react-dom": "^19"
68
68
  },
69
69
  "devDependencies": {
70
- "@babel/preset-env": "^7.27.1",
70
+ "@babel/preset-env": "^7.27.2",
71
71
  "@babel/preset-react": "^7.27.1",
72
72
  "@babel/preset-typescript": "^7.27.1",
73
- "@types/react": "^19.1.3",
73
+ "@types/react": "^19.1.5",
74
74
  "gulp": "^5.0.0",
75
75
  "gulp-cached": "^1.1.1",
76
76
  "gulp-typescript": "^6.0.0-alpha.1",
@@ -80,17 +80,17 @@
80
80
  "https-browserify": "^1.0.0",
81
81
  "os-browserify": "^0.3.0",
82
82
  "stream-browserify": "^3.0.0",
83
- "typescript-eslint": "^8.32.0",
83
+ "typescript-eslint": "^8.32.1",
84
84
  "webpack-cli": "^6.0.1"
85
85
  },
86
86
  "dependencies": {
87
87
  "@btc-vision/bitcoin": "^6.3.6",
88
88
  "@btc-vision/transaction": "^1.4.0",
89
- "@eslint/js": "^9.26.0",
89
+ "@eslint/js": "^9.27.0",
90
90
  "gulp-clean": "^0.4.0",
91
91
  "gulp-eslint-new": "^2.4.0",
92
92
  "gulp-logger-new": "^1.0.1",
93
- "opnet": "^1.4.7",
94
- "webpack": "^5.99.7"
93
+ "opnet": "^1.5.1",
94
+ "webpack": "^5.99.9"
95
95
  }
96
96
  }
@@ -1,15 +1,16 @@
1
1
  import { Network } from '@btc-vision/bitcoin';
2
2
  import { Address } from '@btc-vision/transaction';
3
3
  import { AbstractRpcProvider } from 'opnet';
4
- import React, {
4
+ import {
5
5
  createContext,
6
+ ReactNode,
6
7
  useCallback,
7
8
  useContext,
8
9
  useEffect,
9
10
  useRef,
10
11
  useState,
11
12
  } from 'react';
12
- import WalletConnection, { Signers, SupportedWallets, Wallets } from './WalletConnection.js';
13
+ import WalletConnection, { Signers, SupportedWallets, Wallets } from './WalletConnection';
13
14
 
14
15
  export interface Account {
15
16
  isConnected: boolean;
@@ -21,7 +22,7 @@ export interface Account {
21
22
  }
22
23
 
23
24
  interface WalletContextType {
24
- connect: (walletType: SupportedWallets, signal?: AbortSignal) => Promise<void>;
25
+ connect: (wallet: SupportedWallets, signal?: AbortSignal) => Promise<void>;
25
26
  disconnect: () => void;
26
27
  walletType: SupportedWallets | null;
27
28
  walletWindowInstance: Wallets | null;
@@ -30,38 +31,79 @@ interface WalletContextType {
30
31
 
31
32
  const WalletContext = createContext<WalletContextType | undefined>(undefined);
32
33
 
33
- const maxRetries = 10;
34
- const delayBetweenRetries = 2000;
34
+ const MAX_RETRIES = 10;
35
+ const RETRY_DELAY_MS = 2_000;
35
36
 
36
- export const WalletProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
37
+ function useDocumentComplete(fn: () => void) {
38
+ const fired = useRef(false);
39
+
40
+ useEffect(() => {
41
+ if (fired.current) return;
42
+ const run = () => {
43
+ if (fired.current) return;
44
+ fired.current = true;
45
+ fn();
46
+ };
47
+
48
+ if (document.readyState === 'complete') {
49
+ run();
50
+ return;
51
+ }
52
+
53
+ const handler = () => {
54
+ if (document.readyState === 'complete') {
55
+ document.removeEventListener('readystatechange', handler);
56
+ run();
57
+ }
58
+ };
59
+ document.addEventListener('readystatechange', handler);
60
+ return () => document.removeEventListener('readystatechange', handler);
61
+ }, [fn]);
62
+ }
63
+
64
+ export const WalletProvider = ({ children }: { children: ReactNode }) => {
37
65
  const [walletConnection] = useState(() => new WalletConnection());
38
66
  const [walletType, setWalletType] = useState<SupportedWallets | null>(null);
39
67
  const [walletWindowInstance, setWalletWindowInstance] = useState<Wallets | null>(null);
40
68
  const [account, setAccount] = useState<Account | null>(null);
41
69
 
42
- const registeredEvents = useRef(false);
70
+ /** keeps the latest listeners so they can be removed in `disconnect` */
71
+ const listeners = useRef<{
72
+ disconnect?: () => void;
73
+ accountsChanged?: () => void;
74
+ }>({});
43
75
 
44
76
  const disconnect = useCallback(() => {
77
+ // detach previously attached listeners, if any
78
+ const inst = walletWindowInstance;
79
+ if (inst) {
80
+ if (listeners.current.disconnect) {
81
+ inst.removeListener?.('disconnect', listeners.current.disconnect);
82
+ listeners.current.disconnect = undefined;
83
+ }
84
+ if (listeners.current.accountsChanged) {
85
+ inst.removeListener?.('accountsChanged', listeners.current.accountsChanged);
86
+ listeners.current.accountsChanged = undefined;
87
+ }
88
+ }
89
+
45
90
  walletConnection.disconnect();
46
91
  setWalletType(null);
47
92
  setWalletWindowInstance(null);
48
93
  localStorage.removeItem('walletType');
49
94
  setAccount(null);
50
- registeredEvents.current = false;
51
- }, [walletConnection]);
95
+ }, [walletConnection, walletWindowInstance]);
52
96
 
53
97
  const connect = useCallback(
54
98
  async (type: SupportedWallets, signal?: AbortSignal) => {
55
- let success = false;
56
99
  let attempt = 0;
57
100
 
58
- while (attempt < maxRetries) {
59
- // If the signal was already aborted, exit early
60
- if (signal?.aborted) {
61
- console.debug('Connection aborted.');
62
- return;
63
- }
101
+ const throwIfAborted = () => {
102
+ if (signal?.aborted) throw new DOMException('Aborted', 'AbortError');
103
+ };
64
104
 
105
+ while (attempt < MAX_RETRIES) {
106
+ throwIfAborted();
65
107
  try {
66
108
  await walletConnection.connect(type);
67
109
 
@@ -72,60 +114,45 @@ export const WalletProvider: React.FC<{ children: React.ReactNode }> = ({ childr
72
114
  ) {
73
115
  throw new Error('Wallet not fully loaded yet');
74
116
  }
117
+ break; // success
118
+ } catch (err) {
119
+ attempt += 1;
120
+ if (attempt >= MAX_RETRIES) {
121
+ console.warn(`Failed to connect after ${MAX_RETRIES} attempts.`, err);
122
+ disconnect();
123
+ return;
124
+ }
125
+ console.warn(`Connection attempt ${attempt} failed:`, (err as Error).message);
75
126
 
76
- success = true;
77
- break;
78
- } catch (error) {
79
- console.warn(
80
- `Connection attempt ${attempt + 1} failed:`,
81
- (error as Error).message,
82
- );
83
- }
84
-
85
- attempt++;
86
- if (attempt < maxRetries) {
87
- // Wait before the next retry, unless aborted
88
127
  try {
89
- await new Promise<void>((resolve, reject) => {
90
- const timer = setTimeout(() => resolve(), delayBetweenRetries);
91
-
92
- // If the signal is aborted during the timeout, reject so we jump out
128
+ await new Promise<void>((res, rej) => {
129
+ const t = setTimeout(res, RETRY_DELAY_MS);
93
130
  signal?.addEventListener('abort', () => {
94
- clearTimeout(timer);
95
- reject(new DOMException('Aborted', 'AbortError'));
131
+ clearTimeout(t);
132
+ rej(new DOMException('Aborted', 'AbortError'));
96
133
  });
97
134
  });
98
135
  } catch {
99
- // The abort event was triggered during the delay
100
136
  console.debug('Connection aborted during retry delay.');
101
137
  return;
102
138
  }
103
139
  }
104
140
  }
105
141
 
106
- if (!success) {
107
- console.warn(`Failed to connect after ${maxRetries} attempts.`);
108
- disconnect();
109
- return;
110
- }
111
-
112
- // If the signal was aborted right after a successful connect, bail
113
- if (signal?.aborted) {
114
- console.debug('Connection aborted after a success, cleaning up.');
115
- disconnect();
116
- return;
117
- }
142
+ throwIfAborted();
118
143
 
119
144
  setWalletType(type);
120
145
  setWalletWindowInstance(walletConnection.walletWindowInstance);
121
146
  localStorage.setItem('walletType', type);
122
147
 
123
148
  try {
124
- const signer = walletConnection.signer;
125
- const address = await walletConnection.getAddress();
126
- const addressTyped = await walletConnection.getAddressTyped();
127
- const network = await walletConnection.getNetwork();
128
- const provider = await walletConnection.getProvider();
149
+ const [signer, address, addressTyped, network, provider] = await Promise.all([
150
+ walletConnection.signer,
151
+ walletConnection.getAddress(),
152
+ walletConnection.getAddressTyped(),
153
+ walletConnection.getNetwork(),
154
+ walletConnection.getProvider(),
155
+ ]);
129
156
 
130
157
  setAccount({
131
158
  isConnected: true,
@@ -136,74 +163,66 @@ export const WalletProvider: React.FC<{ children: React.ReactNode }> = ({ childr
136
163
  provider,
137
164
  });
138
165
 
139
- if (
140
- (walletConnection.walletType === SupportedWallets.OP_WALLET ||
141
- walletConnection.walletType === SupportedWallets.UNISAT) &&
142
- walletConnection.walletWindowInstance &&
143
- !registeredEvents.current
144
- ) {
145
- const instance = walletConnection.walletWindowInstance;
146
- instance.on('disconnect', () => {
147
- disconnect();
148
- });
149
-
150
- instance.on('accountsChanged', async () => {
166
+ /* attach listeners exactly once per successful connect */
167
+ const instance = walletConnection.walletWindowInstance;
168
+ if (instance) {
169
+ const onDisconnect = () => disconnect();
170
+ const onAccountsChanged = async () => {
151
171
  try {
152
- const updatedAddress = await walletConnection.getAddress();
153
- const updatedAddressTyped = await walletConnection.getAddressTyped();
154
- const updatedNetwork = await walletConnection.getNetwork();
155
- const updatedProvider = await walletConnection.getProvider();
172
+ const [updatedAddr, updatedAddrTyped, updatedNet, updatedProv] =
173
+ await Promise.all([
174
+ walletConnection.getAddress(),
175
+ walletConnection.getAddressTyped(),
176
+ walletConnection.getNetwork(),
177
+ walletConnection.getProvider(),
178
+ ]);
156
179
 
157
180
  setAccount((prev) =>
158
181
  prev
159
182
  ? {
160
- ...prev,
161
- address: updatedAddress,
162
- addressTyped: updatedAddressTyped,
163
- network: updatedNetwork,
164
- provider: updatedProvider,
165
- }
183
+ ...prev,
184
+ address: updatedAddr,
185
+ addressTyped: updatedAddrTyped,
186
+ network: updatedNet,
187
+ provider: updatedProv,
188
+ }
166
189
  : prev,
167
190
  );
168
- } catch (err) {
191
+ } catch {
169
192
  disconnect();
170
- throw err;
171
193
  }
172
- });
194
+ };
173
195
 
174
- registeredEvents.current = true;
196
+ /* store for later removal */
197
+ listeners.current.disconnect = onDisconnect;
198
+ listeners.current.accountsChanged = onAccountsChanged;
199
+
200
+ instance.on('disconnect', onDisconnect);
201
+ instance.on('accountsChanged', onAccountsChanged);
175
202
  }
176
- } catch (error) {
177
- console.warn('Unable to finalize wallet connection:', error);
203
+ } catch (err) {
204
+ console.warn('Unable to finalize wallet connection:', err);
178
205
  disconnect();
179
206
  }
180
207
  },
181
- [disconnect, walletConnection],
208
+ [walletConnection, disconnect],
182
209
  );
183
210
 
184
- // Reconnect if localStorage has a storedWalletType
185
- useEffect(() => {
186
- const storedWalletType = localStorage.getItem('walletType') as SupportedWallets | null;
187
- if (!storedWalletType) return;
211
+ useDocumentComplete(() => {
212
+ const stored = localStorage.getItem('walletType') as SupportedWallets | null;
213
+ if (!stored) return;
188
214
 
189
215
  const controller = new AbortController();
190
- void (async () => {
191
- try {
192
- await connect(storedWalletType, controller.signal);
193
- } catch (error) {
194
- // AbortError is normal if the component unmounted or re-rendered quickly
195
- if ((error as DOMException).name !== 'AbortError') {
196
- console.warn('Failed to reconnect to wallet:', error);
197
- }
216
+ connect(stored, controller.signal).catch((err: unknown) => {
217
+ if ((err as DOMException).name !== 'AbortError') {
218
+ console.warn('Failed to reconnect to wallet:', err);
198
219
  }
199
- })();
220
+ });
200
221
 
201
- return () => {
202
- controller.abort();
203
- };
204
- }, [connect]);
222
+ return () => controller.abort();
223
+ });
205
224
 
206
- const value = {
225
+ const ctx: WalletContextType = {
207
226
  connect,
208
227
  disconnect,
209
228
  walletType,
@@ -211,13 +230,11 @@ export const WalletProvider: React.FC<{ children: React.ReactNode }> = ({ childr
211
230
  account,
212
231
  };
213
232
 
214
- return <WalletContext.Provider value={value}>{children}</WalletContext.Provider>;
233
+ return <WalletContext.Provider value={ctx}>{children}</WalletContext.Provider>;
215
234
  };
216
235
 
217
236
  export const useWallet = (): WalletContextType => {
218
- const context = useContext(WalletContext);
219
- if (!context) {
220
- throw new Error('useWallet must be used within a WalletProvider');
221
- }
222
- return context;
237
+ const ctx = useContext(WalletContext);
238
+ if (!ctx) throw new Error('useWallet must be used within a WalletProvider');
239
+ return ctx;
223
240
  };