wagmi-extended 2.2.2 → 2.2.3
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.
- package/README.md +10 -0
- package/dist/fetch-functions/common/fetchDeploymentBlockX.d.ts +35 -15
- package/dist/index.cjs.js +90 -20
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +90 -20
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/fetch-functions/common/fetchDeploymentBlockX.ts +120 -20
|
@@ -12,6 +12,53 @@ export const deploymentBlockKey = (
|
|
|
12
12
|
floor: bigint
|
|
13
13
|
) => ["deploymentBlock", chainId, address?.toLowerCase(), floor] as const;
|
|
14
14
|
|
|
15
|
+
/** Internal: SSR-safe localStorage guards */
|
|
16
|
+
const canUseBrowserStorage =
|
|
17
|
+
typeof window !== "undefined" && typeof window.localStorage !== "undefined";
|
|
18
|
+
|
|
19
|
+
/** Internal: build a stable localStorage key */
|
|
20
|
+
const lsKeyForDeploymentBlock = (
|
|
21
|
+
chainId: number,
|
|
22
|
+
address: Address,
|
|
23
|
+
floor: bigint
|
|
24
|
+
) =>
|
|
25
|
+
`wagmi-extended:deploymentBlock:${chainId}:${address.toLowerCase()}:${floor.toString()}`;
|
|
26
|
+
|
|
27
|
+
/** Internal: read bigint from localStorage (SSR safe) */
|
|
28
|
+
function readDeploymentBlockFromLS(
|
|
29
|
+
chainId: number,
|
|
30
|
+
address: Address,
|
|
31
|
+
floor: bigint
|
|
32
|
+
): bigint | undefined {
|
|
33
|
+
if (!canUseBrowserStorage) return undefined;
|
|
34
|
+
try {
|
|
35
|
+
const raw = window.localStorage.getItem(
|
|
36
|
+
lsKeyForDeploymentBlock(chainId, address, floor)
|
|
37
|
+
);
|
|
38
|
+
return raw ? BigInt(raw) : undefined;
|
|
39
|
+
} catch {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Internal: write bigint to localStorage (SSR safe) */
|
|
45
|
+
function writeDeploymentBlockToLS(
|
|
46
|
+
chainId: number,
|
|
47
|
+
address: Address,
|
|
48
|
+
floor: bigint,
|
|
49
|
+
value: bigint
|
|
50
|
+
) {
|
|
51
|
+
if (!canUseBrowserStorage) return;
|
|
52
|
+
try {
|
|
53
|
+
window.localStorage.setItem(
|
|
54
|
+
lsKeyForDeploymentBlock(chainId, address, floor),
|
|
55
|
+
value.toString()
|
|
56
|
+
);
|
|
57
|
+
} catch {
|
|
58
|
+
/* ignore quota/security errors */
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
15
62
|
/**
|
|
16
63
|
* Internal helper: checks if there is bytecode at `address` on `blockNumber`.
|
|
17
64
|
*/
|
|
@@ -87,18 +134,26 @@ async function findDeploymentBlockRpcX(
|
|
|
87
134
|
*
|
|
88
135
|
* Use with `queryClient.fetchQuery(...)`.
|
|
89
136
|
*
|
|
90
|
-
* @param address
|
|
91
|
-
* @param floor
|
|
92
|
-
* @param wagmiConfig
|
|
137
|
+
* @param address - Contract address to probe.
|
|
138
|
+
* @param floor - Optional lower bound (inclusive) to speed up search. Defaults to `0n`.
|
|
139
|
+
* @param wagmiConfig - Wagmi `Config` (optional; resolved via `ensureClientAndConfig` if omitted).
|
|
140
|
+
* @param options.disableLocalStorage - If `true`, skip reading/writing localStorage (default `false`).
|
|
93
141
|
*
|
|
94
|
-
*
|
|
142
|
+
* Local Storage behavior (SSR-safe):
|
|
143
|
+
* - If not disabled and a value exists in `localStorage`, the `queryFn` will
|
|
144
|
+
* return it immediately without performing RPC calls.
|
|
145
|
+
* - After an on-chain discovery, the result is written to `localStorage`
|
|
146
|
+
* (unless disabled). This pairs nicely with `staleTime: Infinity` to
|
|
147
|
+
* avoid future refetches.
|
|
95
148
|
*/
|
|
96
149
|
export function getDeploymentBlockQueryOptionsX(
|
|
97
150
|
address: Address,
|
|
98
151
|
floor: bigint = 0n,
|
|
99
|
-
wagmiConfig?: Config
|
|
152
|
+
wagmiConfig?: Config,
|
|
153
|
+
options?: { disableLocalStorage?: boolean }
|
|
100
154
|
) {
|
|
101
155
|
if (!address) throw new Error("Address is required");
|
|
156
|
+
const disableLocalStorage = options?.disableLocalStorage ?? false;
|
|
102
157
|
|
|
103
158
|
// Resolve config (caller may pass undefined; we'll normalize later in fetcher too)
|
|
104
159
|
// We only need chainId for the key; if wagmiConfig is missing here,
|
|
@@ -111,9 +166,31 @@ export function getDeploymentBlockQueryOptionsX(
|
|
|
111
166
|
queryFn: async () => {
|
|
112
167
|
if (!wagmiConfig)
|
|
113
168
|
throw new Error("wagmiConfig is required at execution time");
|
|
114
|
-
|
|
169
|
+
|
|
170
|
+
const c = getPublicClient(wagmiConfig);
|
|
171
|
+
const cid = c?.chain?.id;
|
|
172
|
+
if (!cid) throw new Error("Client chain ID is missing");
|
|
173
|
+
|
|
174
|
+
// Try localStorage first (no refetches if we already know it)
|
|
175
|
+
if (!disableLocalStorage) {
|
|
176
|
+
const fromLS = readDeploymentBlockFromLS(cid, address, floor);
|
|
177
|
+
if (fromLS !== undefined) return fromLS;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Otherwise do the discovery via RPC
|
|
181
|
+
const discovered = await findDeploymentBlockRpcX(
|
|
182
|
+
address,
|
|
183
|
+
wagmiConfig,
|
|
184
|
+
floor
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Persist to localStorage for subsequent sessions
|
|
188
|
+
if (!disableLocalStorage) {
|
|
189
|
+
writeDeploymentBlockToLS(cid, address, floor, discovered);
|
|
190
|
+
}
|
|
191
|
+
return discovered;
|
|
115
192
|
},
|
|
116
|
-
...queryConfig.metaDataQuery,
|
|
193
|
+
...queryConfig.metaDataQuery, // typically sets staleTime: Infinity, gcTime, etc.
|
|
117
194
|
} as const;
|
|
118
195
|
}
|
|
119
196
|
|
|
@@ -126,21 +203,31 @@ export function getDeploymentBlockQueryOptionsX(
|
|
|
126
203
|
*
|
|
127
204
|
* #### Caching
|
|
128
205
|
* - Query key: `["deploymentBlock", chainId, address.toLowerCase(), floor]`
|
|
129
|
-
* -
|
|
206
|
+
* - Long-lived results: `queryConfig.metaDataQuery` (e.g., `staleTime: Infinity`)
|
|
130
207
|
*
|
|
131
|
-
* ####
|
|
132
|
-
* -
|
|
133
|
-
*
|
|
208
|
+
* #### Local Storage (SSR-safe)
|
|
209
|
+
* - Before calling `fetchQuery`, we seed the Query Cache from `localStorage`
|
|
210
|
+
* (unless `disableLocalStorage` is true). When a cached value is present,
|
|
211
|
+
* `fetchQuery` will *not* execute the `queryFn`, fully preventing RPC refetches.
|
|
212
|
+
* - After on-chain discovery, the result is written back to `localStorage`
|
|
213
|
+
* (unless disabled).
|
|
134
214
|
*
|
|
135
215
|
* @example
|
|
136
216
|
* ```ts
|
|
137
|
-
* const block = await fetchDeploymentBlockX(
|
|
217
|
+
* const block = await fetchDeploymentBlockX(
|
|
218
|
+
* "0xContract...",
|
|
219
|
+
* 0n,
|
|
220
|
+
* queryClient,
|
|
221
|
+
* wagmiConfig,
|
|
222
|
+
* { disableLocalStorage: false }
|
|
223
|
+
* );
|
|
138
224
|
* ```
|
|
139
225
|
*
|
|
140
|
-
* @param address
|
|
141
|
-
* @param floor
|
|
142
|
-
* @param queryClient
|
|
143
|
-
* @param wagmiConfig
|
|
226
|
+
* @param address - Contract address to probe.
|
|
227
|
+
* @param floor - Optional lower bound (inclusive). Defaults to `0n`.
|
|
228
|
+
* @param queryClient - Optional TanStack `QueryClient`. If omitted, resolved by `ensureClientAndConfig`.
|
|
229
|
+
* @param wagmiConfig - Optional Wagmi `Config`. If omitted, resolved by `ensureClientAndConfig`.
|
|
230
|
+
* @param options.disableLocalStorage - If `true`, skip reading/writing localStorage (default `false`).
|
|
144
231
|
*
|
|
145
232
|
* @returns The earliest block number (bigint) where bytecode exists.
|
|
146
233
|
*
|
|
@@ -150,7 +237,8 @@ export async function fetchDeploymentBlockX(
|
|
|
150
237
|
address: Address,
|
|
151
238
|
floor: bigint = 0n,
|
|
152
239
|
queryClient?: QueryClient,
|
|
153
|
-
wagmiConfig?: Config
|
|
240
|
+
wagmiConfig?: Config,
|
|
241
|
+
options?: { disableLocalStorage?: boolean }
|
|
154
242
|
): Promise<bigint> {
|
|
155
243
|
if (!address) throw new Error("Address is required");
|
|
156
244
|
|
|
@@ -159,15 +247,27 @@ export async function fetchDeploymentBlockX(
|
|
|
159
247
|
wagmiConfig
|
|
160
248
|
));
|
|
161
249
|
|
|
162
|
-
// Resolve chainId for a stable cache key
|
|
163
250
|
const client = getPublicClient(wagmiConfig);
|
|
164
251
|
const chainId = client?.chain?.id;
|
|
165
252
|
if (!chainId) throw new Error("Client chain ID is missing");
|
|
166
253
|
|
|
254
|
+
const key = deploymentBlockKey(chainId, address, floor);
|
|
255
|
+
const disableLocalStorage = options?.disableLocalStorage ?? false;
|
|
256
|
+
|
|
257
|
+
// Seed cache from localStorage so fetchQuery returns immediately w/o running queryFn
|
|
258
|
+
if (!disableLocalStorage) {
|
|
259
|
+
const fromLS = readDeploymentBlockFromLS(chainId, address, floor);
|
|
260
|
+
if (fromLS !== undefined) {
|
|
261
|
+
queryClient.setQueryData(key, fromLS);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
167
265
|
return queryClient.fetchQuery({
|
|
168
|
-
...getDeploymentBlockQueryOptionsX(address, floor, wagmiConfig
|
|
266
|
+
...getDeploymentBlockQueryOptionsX(address, floor, wagmiConfig, {
|
|
267
|
+
disableLocalStorage,
|
|
268
|
+
}),
|
|
169
269
|
// Ensure the final key includes a concrete chainId
|
|
170
|
-
queryKey:
|
|
270
|
+
queryKey: key,
|
|
171
271
|
// Reinstate metadata (in case your ensure/util merges)
|
|
172
272
|
...queryConfig.metaDataQuery,
|
|
173
273
|
});
|