wagmi 0.5.6 → 0.5.7

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.
@@ -17,7 +17,7 @@ export declare const queryKey: ([{ cacheKey, overrides }]: [{
17
17
  readonly cacheKey: string;
18
18
  readonly overrides: import("ethers").CallOverrides | undefined;
19
19
  }];
20
- export declare function useContractInfiniteReads<TPageParam = any>({ cacheKey, cacheTime, contracts, enabled: enabled_, getNextPageParam, keepPreviousData, onError, onSettled, onSuccess, overrides, select, staleTime, suspense, }: UseContractInfiniteReadsConfig<TPageParam>): Pick<import("react-query").InfiniteQueryObserverResult<import("ethers/lib/utils").Result, Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch" | "fetchNextPage" | "hasNextPage" | "isFetchingNextPage"> & {
20
+ export declare function useContractInfiniteReads<TPageParam = any>({ cacheKey, cacheTime, contracts, enabled: enabled_, getNextPageParam, isDataEqual, keepPreviousData, onError, onSettled, onSuccess, overrides, select, staleTime, suspense, }: UseContractInfiniteReadsConfig<TPageParam>): Pick<import("react-query").InfiniteQueryObserverResult<import("ethers/lib/utils").Result, Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch" | "fetchNextPage" | "hasNextPage" | "isFetchingNextPage"> & {
21
21
  isIdle: boolean;
22
22
  status: "error" | "success" | "idle" | "loading";
23
23
  internal: Pick<import("react-query").InfiniteQueryObserverResult<unknown, unknown>, "dataUpdatedAt" | "errorUpdatedAt" | "failureCount" | "isFetchedAfterMount" | "isLoadingError" | "isPaused" | "isPlaceholderData" | "isPreviousData" | "isRefetchError" | "isStale" | "remove">;
@@ -19,7 +19,7 @@ export declare const queryKey: ([{ addressOrName, args, chainId, contractInterfa
19
19
  readonly functionName: string;
20
20
  readonly overrides: import("ethers").CallOverrides | undefined;
21
21
  }];
22
- export declare function useContractRead({ addressOrName, contractInterface, functionName, args, chainId: chainId_, overrides, cacheOnBlock, cacheTime, enabled: enabled_, select, staleTime, suspense, watch, onError, onSettled, onSuccess, }: UseContractReadArgs & UseContractReadConfig): Pick<import("react-query").QueryObserverResult<import("ethers/lib/utils").Result, Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch"> & {
22
+ export declare function useContractRead({ addressOrName, contractInterface, functionName, args, chainId: chainId_, overrides, cacheOnBlock, cacheTime, enabled: enabled_, isDataEqual, select, staleTime, suspense, watch, onError, onSettled, onSuccess, }: UseContractReadArgs & UseContractReadConfig): Pick<import("react-query").QueryObserverResult<import("ethers/lib/utils").Result, Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch"> & {
23
23
  isIdle: boolean;
24
24
  status: "error" | "success" | "idle" | "loading";
25
25
  internal: Pick<import("react-query").QueryObserverResult<unknown, unknown>, "dataUpdatedAt" | "errorUpdatedAt" | "failureCount" | "isFetchedAfterMount" | "isLoadingError" | "isPaused" | "isPlaceholderData" | "isPreviousData" | "isRefetchError" | "isStale" | "remove">;
@@ -17,7 +17,7 @@ export declare const queryKey: ([{ allowFailure, contracts, overrides }, { block
17
17
  readonly contracts: import("@wagmi/core/src/actions/contracts/readContracts").ReadContractsContract[];
18
18
  readonly overrides: import("ethers").CallOverrides | undefined;
19
19
  }];
20
- export declare function useContractReads({ allowFailure, cacheOnBlock, cacheTime, contracts, overrides, enabled: enabled_, keepPreviousData, onError, onSettled, onSuccess, select, staleTime, suspense, watch, }: UseContractReadsConfig): Pick<import("react-query").QueryObserverResult<import("ethers/lib/utils").Result[], Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch"> & {
20
+ export declare function useContractReads({ allowFailure, cacheOnBlock, cacheTime, contracts, overrides, enabled: enabled_, isDataEqual, keepPreviousData, onError, onSettled, onSuccess, select, staleTime, suspense, watch, }: UseContractReadsConfig): Pick<import("react-query").QueryObserverResult<import("ethers/lib/utils").Result[], Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch"> & {
21
21
  isIdle: boolean;
22
22
  status: "error" | "success" | "idle" | "loading";
23
23
  internal: Pick<import("react-query").QueryObserverResult<unknown, unknown>, "dataUpdatedAt" | "errorUpdatedAt" | "failureCount" | "isFetchedAfterMount" | "isLoadingError" | "isPaused" | "isPlaceholderData" | "isPreviousData" | "isRefetchError" | "isStale" | "remove">;
@@ -1,6 +1,8 @@
1
1
  import { FetchBlockNumberArgs, FetchBlockNumberResult } from '@wagmi/core';
2
2
  import { QueryConfig } from '../../types';
3
3
  declare type UseBlockNumberArgs = Partial<FetchBlockNumberArgs> & {
4
+ /** Function fires when a new block is created */
5
+ onBlock?: (blockNumber: number) => void;
4
6
  /** Subscribe to changes */
5
7
  watch?: boolean;
6
8
  };
@@ -11,7 +13,7 @@ export declare const queryKey: ({ chainId }: {
11
13
  readonly entity: "blockNumber";
12
14
  readonly chainId: number | undefined;
13
15
  }];
14
- export declare function useBlockNumber({ cacheTime, chainId: chainId_, enabled, staleTime, suspense, watch, onError, onSettled, onSuccess, }?: UseBlockNumberArgs & UseBlockNumberConfig): Pick<import("react-query").QueryObserverResult<number, Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch"> & {
16
+ export declare function useBlockNumber({ cacheTime, chainId: chainId_, enabled, staleTime, suspense, watch, onBlock, onError, onSettled, onSuccess, }?: UseBlockNumberArgs & UseBlockNumberConfig): Pick<import("react-query").QueryObserverResult<number, Error>, "data" | "error" | "fetchStatus" | "isError" | "isFetched" | "isFetching" | "isLoading" | "isRefetching" | "isSuccess" | "refetch"> & {
15
17
  isIdle: boolean;
16
18
  status: "error" | "success" | "idle" | "loading";
17
19
  internal: Pick<import("react-query").QueryObserverResult<unknown, unknown>, "dataUpdatedAt" | "errorUpdatedAt" | "failureCount" | "isFetchedAfterMount" | "isLoadingError" | "isPaused" | "isPlaceholderData" | "isPreviousData" | "isRefetchError" | "isStale" | "remove">;
@@ -1,5 +1,6 @@
1
1
  export { useBaseQuery, useQuery, useInfiniteQuery } from './query';
2
2
  export { useChainId } from './useChainId';
3
3
  export { useForceUpdate } from './useForceUpdate';
4
+ export { useInvalidateOnBlock } from './useInvalidateOnBlock';
4
5
  export { useSyncExternalStore } from './useSyncExternalStore';
5
6
  export { useSyncExternalStoreWithTracked } from './useSyncExternalStoreWithTracked';
@@ -0,0 +1,5 @@
1
+ import { QueryKey } from 'react-query';
2
+ export declare function useInvalidateOnBlock({ enabled, queryKey, }: {
3
+ enabled?: boolean;
4
+ queryKey: QueryKey;
5
+ }): void;
@@ -4,5 +4,5 @@ WagmiConfig as WagmiProvider, WagmiConfig, createClient, useClient, } from './co
4
4
  export type { CreateClientConfig, WagmiConfigProps } from './context';
5
5
  export { paginatedIndexesConfig, useAccount, useBalance, useBlockNumber, useConnect, useContract, useContractEvent, useContractInfiniteReads, useContractRead, useContractReads, useContractWrite, useDisconnect, useEnsAddress, useEnsAvatar, useEnsName, useEnsResolver, useFeeData, useInfiniteQuery, useNetwork, useProvider, useQuery, useSendTransaction, useSignMessage, useSignTypedData, useSigner, useSwitchNetwork, useToken, useWaitForTransaction, useWebSocketProvider, } from './hooks';
6
6
  export { deserialize, serialize } from './utils';
7
- export { AddChainError, ChainDoesNotSupportMulticallError, ChainMismatchError, ChainNotConfiguredError, Client, Connector, ConnectorAlreadyConnectedError, ConnectorNotFoundError, ContractMethodNoResultError, ProviderChainsNotFound, ProviderRpcError, ResourceUnavailableError, RpcError, SwitchChainError, SwitchChainNotSupportedError, UserRejectedRequestError, alchemyRpcUrls, allChains, chain, chainId, configureChains, createStorage, defaultChains, defaultL2Chains, erc20ABI, erc721ABI, etherscanBlockExplorers, infuraRpcUrls, publicRpcUrls, readContracts, } from '@wagmi/core';
7
+ export { AddChainError, ChainDoesNotSupportMulticallError, ChainMismatchError, ChainNotConfiguredError, Client, Connector, ConnectorAlreadyConnectedError, ConnectorNotFoundError, ContractMethodNoResultError, ProviderChainsNotFound, ProviderRpcError, ResourceUnavailableError, RpcError, SwitchChainError, SwitchChainNotSupportedError, UserRejectedRequestError, alchemyRpcUrls, allChains, chain, chainId, configureChains, createStorage, deepEqual, defaultChains, defaultL2Chains, erc20ABI, erc721ABI, etherscanBlockExplorers, infuraRpcUrls, publicRpcUrls, readContracts, } from '@wagmi/core';
8
8
  export type { Chain, ChainProviderFn, ConnectorData, ConnectorEvents, Storage, Unit, } from '@wagmi/core';
@@ -1,7 +1,7 @@
1
1
  import { QueryFunctionContext, UseInfiniteQueryOptions, UseMutationOptions, UseQueryOptions } from 'react-query';
2
2
  export declare type QueryFunctionArgs<T extends (...args: any) => any> = QueryFunctionContext<ReturnType<T>>;
3
- export declare type QueryConfig<Data, Error> = Pick<UseQueryOptions<Data, Error>, 'cacheTime' | 'enabled' | 'keepPreviousData' | 'staleTime' | 'select' | 'suspense' | 'onError' | 'onSettled' | 'onSuccess'>;
4
- export declare type InfiniteQueryConfig<Data, Error> = Pick<UseInfiniteQueryOptions<Data, Error>, 'cacheTime' | 'enabled' | 'getNextPageParam' | 'keepPreviousData' | 'select' | 'staleTime' | 'suspense' | 'onError' | 'onSettled' | 'onSuccess'>;
3
+ export declare type QueryConfig<Data, Error> = Pick<UseQueryOptions<Data, Error>, 'cacheTime' | 'enabled' | 'isDataEqual' | 'keepPreviousData' | 'staleTime' | 'select' | 'suspense' | 'onError' | 'onSettled' | 'onSuccess'>;
4
+ export declare type InfiniteQueryConfig<Data, Error> = Pick<UseInfiniteQueryOptions<Data, Error>, 'cacheTime' | 'enabled' | 'getNextPageParam' | 'isDataEqual' | 'keepPreviousData' | 'select' | 'staleTime' | 'suspense' | 'onError' | 'onSettled' | 'onSuccess'>;
5
5
  export declare type MutationConfig<Data, Error, Variables = void> = {
6
6
  /** Function fires if mutation encounters error */
7
7
  onError?: UseMutationOptions<Data, Error, Variables>['onError'];
@@ -1,4 +1,3 @@
1
- export { deepEqual } from './deepEqual';
2
1
  export { deserialize } from './deserialize';
3
2
  export { parseContractResult } from './parseContractResult';
4
3
  export { serialize } from './serialize';
@@ -32,44 +32,6 @@ function _interopNamespace(e) {
32
32
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
33
33
  var pkg__namespace = /*#__PURE__*/_interopNamespace(pkg);
34
34
 
35
- /** Forked from https://github.com/epoberezkin/fast-deep-equal */
36
- function deepEqual(a, b) {
37
- if (a === b) return true;
38
-
39
- if (a && b && typeof a === 'object' && typeof b === 'object') {
40
- if (a.constructor !== b.constructor) return false;
41
- let length;
42
- let i;
43
-
44
- if (Array.isArray(a) && Array.isArray(b)) {
45
- length = a.length;
46
- if (length != b.length) return false;
47
-
48
- for (i = length; i-- !== 0;) if (!deepEqual(a[i], b[i])) return false;
49
-
50
- return true;
51
- }
52
-
53
- if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
54
- if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
55
- const keys = Object.keys(a);
56
- length = keys.length;
57
- if (length !== Object.keys(b).length) return false;
58
-
59
- for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
60
-
61
- for (i = length; i-- !== 0;) {
62
- const key = keys[i];
63
- if (key && !deepEqual(a[key], b[key])) return false;
64
- }
65
-
66
- return true;
67
- } // true if both NaN, false otherwise
68
-
69
-
70
- return a !== a && b !== b;
71
- }
72
-
73
35
  const findAndReplace = (cacheRef, _ref) => {
74
36
  let {
75
37
  find,
@@ -564,83 +526,6 @@ function useForceUpdate() {
564
526
  return forceUpdate;
565
527
  }
566
528
 
567
- const isPlainObject = obj => typeof obj === 'object' && !Array.isArray(obj);
568
-
569
- function useSyncExternalStoreWithTracked(subscribe, getSnapshot) {
570
- let getServerSnapshot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getSnapshot;
571
- let isEqual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (a, b) => deepEqual(a, b);
572
- const trackedKeys = React__namespace.useRef([]);
573
- const result = withSelector_js.useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, x => x, (a, b) => {
574
- if (isPlainObject(a) && isPlainObject(b)) {
575
- for (const key of trackedKeys.current) {
576
- const equal = isEqual(a[key], b[key]);
577
- if (!equal) return false;
578
- }
579
-
580
- return true;
581
- }
582
-
583
- return isEqual(a, b);
584
- });
585
-
586
- if (isPlainObject(result)) {
587
- const trackedResult = { ...result
588
- };
589
- Object.defineProperties(trackedResult, Object.entries(trackedResult).reduce((res, _ref) => {
590
- let [key, value] = _ref;
591
- return { ...res,
592
- [key]: {
593
- configurable: false,
594
- enumerable: true,
595
- get: () => {
596
- if (!trackedKeys.current.includes(key)) {
597
- trackedKeys.current.push(key);
598
- }
599
-
600
- return value;
601
- }
602
- }
603
- };
604
- }, {}));
605
- return trackedResult;
606
- }
607
-
608
- return result;
609
- }
610
-
611
- function useAccount() {
612
- let {
613
- onConnect,
614
- onDisconnect
615
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
616
- const account = useSyncExternalStoreWithTracked(core.watchAccount, core.getAccount);
617
- const {
618
- subscribe
619
- } = useClient();
620
- React__namespace.useEffect(() => {
621
- // No need to subscribe if these callbacks aren't defined
622
- if (!onConnect && !onDisconnect) return; // Trigger update when status changes
623
-
624
- const unsubscribe = subscribe(state => state.status, (status, prevStatus) => {
625
- if (!!onConnect && status === 'connected') {
626
- const {
627
- address,
628
- connector
629
- } = core.getAccount();
630
- onConnect({
631
- address,
632
- connector,
633
- isReconnected: prevStatus === 'reconnecting'
634
- });
635
- }
636
-
637
- if (!!onDisconnect && prevStatus !== 'connecting' && status === 'disconnected') onDisconnect();
638
- });
639
- return unsubscribe;
640
- }, [onConnect, onDisconnect, subscribe]);
641
- return account;
642
- }
643
-
644
529
  const queryKey$c = _ref => {
645
530
  let {
646
531
  chainId
@@ -670,6 +555,7 @@ function useBlockNumber() {
670
555
  staleTime,
671
556
  suspense,
672
557
  watch = false,
558
+ onBlock,
673
559
  onError,
674
560
  onSettled,
675
561
  onSuccess
@@ -681,14 +567,15 @@ function useBlockNumber() {
681
567
  const webSocketProvider = useWebSocketProvider();
682
568
  const queryClient = reactQuery.useQueryClient();
683
569
  React__namespace.useEffect(() => {
684
- if (!watch) return;
570
+ if (!watch && !onBlock) return;
685
571
 
686
572
  const listener = blockNumber => {
687
573
  // Just to be safe in case the provider implementation
688
574
  // calls the event callback after .off() has been called
689
- queryClient.setQueryData(queryKey$c({
575
+ if (watch) queryClient.setQueryData(queryKey$c({
690
576
  chainId
691
577
  }), blockNumber);
578
+ if (onBlock) onBlock(blockNumber);
692
579
  };
693
580
 
694
581
  const provider_ = webSocketProvider !== null && webSocketProvider !== void 0 ? webSocketProvider : provider;
@@ -696,7 +583,7 @@ function useBlockNumber() {
696
583
  return () => {
697
584
  provider_.off('block', listener);
698
585
  };
699
- }, [chainId, provider, queryClient, watch, webSocketProvider]);
586
+ }, [chainId, onBlock, provider, queryClient, watch, webSocketProvider]);
700
587
  return useQuery(queryKey$c({
701
588
  chainId
702
589
  }), queryFn$c, {
@@ -777,6 +664,94 @@ function useFeeData() {
777
664
  return feeDataQuery;
778
665
  }
779
666
 
667
+ function useInvalidateOnBlock(_ref) {
668
+ let {
669
+ enabled,
670
+ queryKey
671
+ } = _ref;
672
+ const queryClient = reactQuery.useQueryClient();
673
+ useBlockNumber({
674
+ onBlock: enabled ? () => queryClient.invalidateQueries(queryKey) : undefined
675
+ });
676
+ }
677
+
678
+ const isPlainObject = obj => typeof obj === 'object' && !Array.isArray(obj);
679
+
680
+ function useSyncExternalStoreWithTracked(subscribe, getSnapshot) {
681
+ let getServerSnapshot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getSnapshot;
682
+ let isEqual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (a, b) => core.deepEqual(a, b);
683
+ const trackedKeys = React__namespace.useRef([]);
684
+ const result = withSelector_js.useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, x => x, (a, b) => {
685
+ if (isPlainObject(a) && isPlainObject(b)) {
686
+ for (const key of trackedKeys.current) {
687
+ const equal = isEqual(a[key], b[key]);
688
+ if (!equal) return false;
689
+ }
690
+
691
+ return true;
692
+ }
693
+
694
+ return isEqual(a, b);
695
+ });
696
+
697
+ if (isPlainObject(result)) {
698
+ const trackedResult = { ...result
699
+ };
700
+ Object.defineProperties(trackedResult, Object.entries(trackedResult).reduce((res, _ref) => {
701
+ let [key, value] = _ref;
702
+ return { ...res,
703
+ [key]: {
704
+ configurable: false,
705
+ enumerable: true,
706
+ get: () => {
707
+ if (!trackedKeys.current.includes(key)) {
708
+ trackedKeys.current.push(key);
709
+ }
710
+
711
+ return value;
712
+ }
713
+ }
714
+ };
715
+ }, {}));
716
+ return trackedResult;
717
+ }
718
+
719
+ return result;
720
+ }
721
+
722
+ function useAccount() {
723
+ let {
724
+ onConnect,
725
+ onDisconnect
726
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
727
+ const account = useSyncExternalStoreWithTracked(core.watchAccount, core.getAccount);
728
+ const {
729
+ subscribe
730
+ } = useClient();
731
+ React__namespace.useEffect(() => {
732
+ // No need to subscribe if these callbacks aren't defined
733
+ if (!onConnect && !onDisconnect) return; // Trigger update when status changes
734
+
735
+ const unsubscribe = subscribe(state => state.status, (status, prevStatus) => {
736
+ if (!!onConnect && status === 'connected') {
737
+ const {
738
+ address,
739
+ connector
740
+ } = core.getAccount();
741
+ onConnect({
742
+ address,
743
+ connector,
744
+ isReconnected: prevStatus === 'reconnecting'
745
+ });
746
+ }
747
+
748
+ if (!!onDisconnect && prevStatus !== 'connecting' && status === 'disconnected') onDisconnect();
749
+ });
750
+ return unsubscribe;
751
+ }, [onConnect, onDisconnect, subscribe]);
752
+ return account;
753
+ }
754
+
780
755
  const queryKey$a = _ref => {
781
756
  let {
782
757
  addressOrName,
@@ -1372,6 +1347,7 @@ function useContractInfiniteReads(_ref5) {
1372
1347
  contracts,
1373
1348
  enabled: enabled_ = true,
1374
1349
  getNextPageParam,
1350
+ isDataEqual = core.deepEqual,
1375
1351
  keepPreviousData,
1376
1352
  onError,
1377
1353
  onSettled,
@@ -1394,8 +1370,9 @@ function useContractInfiniteReads(_ref5) {
1394
1370
  }), {
1395
1371
  cacheTime,
1396
1372
  enabled,
1397
- keepPreviousData,
1398
1373
  getNextPageParam,
1374
+ isDataEqual,
1375
+ keepPreviousData,
1399
1376
  select,
1400
1377
  staleTime,
1401
1378
  suspense,
@@ -1470,6 +1447,7 @@ function useContractRead(_ref4) {
1470
1447
  cacheOnBlock = false,
1471
1448
  cacheTime,
1472
1449
  enabled: enabled_ = true,
1450
+ isDataEqual = core.deepEqual,
1473
1451
  select,
1474
1452
  staleTime,
1475
1453
  suspense,
@@ -1502,24 +1480,14 @@ function useContractRead(_ref4) {
1502
1480
  if (cacheOnBlock) enabled = Boolean(enabled && blockNumber);
1503
1481
  return enabled;
1504
1482
  }, [addressOrName, blockNumber, cacheOnBlock, enabled_, functionName]);
1505
- const client = reactQuery.useQueryClient();
1506
- React__namespace.useEffect(() => {
1507
- if (enabled) {
1508
- const unwatch = core.watchReadContract({
1509
- addressOrName,
1510
- args,
1511
- chainId,
1512
- contractInterface,
1513
- functionName,
1514
- overrides,
1515
- listenToBlock: watch && !cacheOnBlock
1516
- }, result => client.setQueryData(queryKey_, result));
1517
- return unwatch;
1518
- }
1519
- }, [addressOrName, args, cacheOnBlock, chainId, client, contractInterface, enabled, functionName, overrides, queryKey_, watch]);
1483
+ useInvalidateOnBlock({
1484
+ enabled: watch && !cacheOnBlock,
1485
+ queryKey: queryKey_
1486
+ });
1520
1487
  return useQuery(queryKey_, queryFn$7, {
1521
1488
  cacheTime,
1522
1489
  enabled,
1490
+ isDataEqual,
1523
1491
  queryKeyHashFn: queryKeyHashFn$1,
1524
1492
  select: data => {
1525
1493
  const result = parseContractResult({
@@ -1600,6 +1568,7 @@ function useContractReads(_ref4) {
1600
1568
  contracts,
1601
1569
  overrides,
1602
1570
  enabled: enabled_ = true,
1571
+ isDataEqual = core.deepEqual,
1603
1572
  keepPreviousData,
1604
1573
  onError,
1605
1574
  onSettled,
@@ -1629,20 +1598,14 @@ function useContractReads(_ref4) {
1629
1598
  if (cacheOnBlock) enabled = Boolean(enabled && blockNumber);
1630
1599
  return enabled;
1631
1600
  }, [blockNumber, cacheOnBlock, contracts, enabled_]);
1632
- const client = reactQuery.useQueryClient();
1633
- React__namespace.useEffect(() => {
1634
- if (enabled) {
1635
- const unwatch = core.watchReadContracts({
1636
- contracts,
1637
- overrides,
1638
- listenToBlock: watch && !cacheOnBlock
1639
- }, result => client.setQueryData(queryKey_, result));
1640
- return unwatch;
1641
- }
1642
- }, [cacheOnBlock, client, contracts, enabled, overrides, queryKey_, watch]);
1601
+ useInvalidateOnBlock({
1602
+ enabled: watch && !cacheOnBlock,
1603
+ queryKey: queryKey_
1604
+ });
1643
1605
  return useQuery(queryKey_, queryFn$6, {
1644
1606
  cacheTime,
1645
1607
  enabled,
1608
+ isDataEqual,
1646
1609
  keepPreviousData,
1647
1610
  queryKeyHashFn,
1648
1611
  staleTime,
@@ -2290,6 +2253,10 @@ Object.defineProperty(exports, 'createStorage', {
2290
2253
  enumerable: true,
2291
2254
  get: function () { return core.createStorage; }
2292
2255
  });
2256
+ Object.defineProperty(exports, 'deepEqual', {
2257
+ enumerable: true,
2258
+ get: function () { return core.deepEqual; }
2259
+ });
2293
2260
  Object.defineProperty(exports, 'defaultChains', {
2294
2261
  enumerable: true,
2295
2262
  get: function () { return core.defaultChains; }
@@ -32,44 +32,6 @@ function _interopNamespace(e) {
32
32
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
33
33
  var pkg__namespace = /*#__PURE__*/_interopNamespace(pkg);
34
34
 
35
- /** Forked from https://github.com/epoberezkin/fast-deep-equal */
36
- function deepEqual(a, b) {
37
- if (a === b) return true;
38
-
39
- if (a && b && typeof a === 'object' && typeof b === 'object') {
40
- if (a.constructor !== b.constructor) return false;
41
- let length;
42
- let i;
43
-
44
- if (Array.isArray(a) && Array.isArray(b)) {
45
- length = a.length;
46
- if (length != b.length) return false;
47
-
48
- for (i = length; i-- !== 0;) if (!deepEqual(a[i], b[i])) return false;
49
-
50
- return true;
51
- }
52
-
53
- if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
54
- if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
55
- const keys = Object.keys(a);
56
- length = keys.length;
57
- if (length !== Object.keys(b).length) return false;
58
-
59
- for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
60
-
61
- for (i = length; i-- !== 0;) {
62
- const key = keys[i];
63
- if (key && !deepEqual(a[key], b[key])) return false;
64
- }
65
-
66
- return true;
67
- } // true if both NaN, false otherwise
68
-
69
-
70
- return a !== a && b !== b;
71
- }
72
-
73
35
  const findAndReplace = (cacheRef, _ref) => {
74
36
  let {
75
37
  find,
@@ -564,83 +526,6 @@ function useForceUpdate() {
564
526
  return forceUpdate;
565
527
  }
566
528
 
567
- const isPlainObject = obj => typeof obj === 'object' && !Array.isArray(obj);
568
-
569
- function useSyncExternalStoreWithTracked(subscribe, getSnapshot) {
570
- let getServerSnapshot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getSnapshot;
571
- let isEqual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (a, b) => deepEqual(a, b);
572
- const trackedKeys = React__namespace.useRef([]);
573
- const result = withSelector_js.useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, x => x, (a, b) => {
574
- if (isPlainObject(a) && isPlainObject(b)) {
575
- for (const key of trackedKeys.current) {
576
- const equal = isEqual(a[key], b[key]);
577
- if (!equal) return false;
578
- }
579
-
580
- return true;
581
- }
582
-
583
- return isEqual(a, b);
584
- });
585
-
586
- if (isPlainObject(result)) {
587
- const trackedResult = { ...result
588
- };
589
- Object.defineProperties(trackedResult, Object.entries(trackedResult).reduce((res, _ref) => {
590
- let [key, value] = _ref;
591
- return { ...res,
592
- [key]: {
593
- configurable: false,
594
- enumerable: true,
595
- get: () => {
596
- if (!trackedKeys.current.includes(key)) {
597
- trackedKeys.current.push(key);
598
- }
599
-
600
- return value;
601
- }
602
- }
603
- };
604
- }, {}));
605
- return trackedResult;
606
- }
607
-
608
- return result;
609
- }
610
-
611
- function useAccount() {
612
- let {
613
- onConnect,
614
- onDisconnect
615
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
616
- const account = useSyncExternalStoreWithTracked(core.watchAccount, core.getAccount);
617
- const {
618
- subscribe
619
- } = useClient();
620
- React__namespace.useEffect(() => {
621
- // No need to subscribe if these callbacks aren't defined
622
- if (!onConnect && !onDisconnect) return; // Trigger update when status changes
623
-
624
- const unsubscribe = subscribe(state => state.status, (status, prevStatus) => {
625
- if (!!onConnect && status === 'connected') {
626
- const {
627
- address,
628
- connector
629
- } = core.getAccount();
630
- onConnect({
631
- address,
632
- connector,
633
- isReconnected: prevStatus === 'reconnecting'
634
- });
635
- }
636
-
637
- if (!!onDisconnect && prevStatus !== 'connecting' && status === 'disconnected') onDisconnect();
638
- });
639
- return unsubscribe;
640
- }, [onConnect, onDisconnect, subscribe]);
641
- return account;
642
- }
643
-
644
529
  const queryKey$c = _ref => {
645
530
  let {
646
531
  chainId
@@ -670,6 +555,7 @@ function useBlockNumber() {
670
555
  staleTime,
671
556
  suspense,
672
557
  watch = false,
558
+ onBlock,
673
559
  onError,
674
560
  onSettled,
675
561
  onSuccess
@@ -681,14 +567,15 @@ function useBlockNumber() {
681
567
  const webSocketProvider = useWebSocketProvider();
682
568
  const queryClient = reactQuery.useQueryClient();
683
569
  React__namespace.useEffect(() => {
684
- if (!watch) return;
570
+ if (!watch && !onBlock) return;
685
571
 
686
572
  const listener = blockNumber => {
687
573
  // Just to be safe in case the provider implementation
688
574
  // calls the event callback after .off() has been called
689
- queryClient.setQueryData(queryKey$c({
575
+ if (watch) queryClient.setQueryData(queryKey$c({
690
576
  chainId
691
577
  }), blockNumber);
578
+ if (onBlock) onBlock(blockNumber);
692
579
  };
693
580
 
694
581
  const provider_ = webSocketProvider !== null && webSocketProvider !== void 0 ? webSocketProvider : provider;
@@ -696,7 +583,7 @@ function useBlockNumber() {
696
583
  return () => {
697
584
  provider_.off('block', listener);
698
585
  };
699
- }, [chainId, provider, queryClient, watch, webSocketProvider]);
586
+ }, [chainId, onBlock, provider, queryClient, watch, webSocketProvider]);
700
587
  return useQuery(queryKey$c({
701
588
  chainId
702
589
  }), queryFn$c, {
@@ -777,6 +664,94 @@ function useFeeData() {
777
664
  return feeDataQuery;
778
665
  }
779
666
 
667
+ function useInvalidateOnBlock(_ref) {
668
+ let {
669
+ enabled,
670
+ queryKey
671
+ } = _ref;
672
+ const queryClient = reactQuery.useQueryClient();
673
+ useBlockNumber({
674
+ onBlock: enabled ? () => queryClient.invalidateQueries(queryKey) : undefined
675
+ });
676
+ }
677
+
678
+ const isPlainObject = obj => typeof obj === 'object' && !Array.isArray(obj);
679
+
680
+ function useSyncExternalStoreWithTracked(subscribe, getSnapshot) {
681
+ let getServerSnapshot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getSnapshot;
682
+ let isEqual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (a, b) => core.deepEqual(a, b);
683
+ const trackedKeys = React__namespace.useRef([]);
684
+ const result = withSelector_js.useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, x => x, (a, b) => {
685
+ if (isPlainObject(a) && isPlainObject(b)) {
686
+ for (const key of trackedKeys.current) {
687
+ const equal = isEqual(a[key], b[key]);
688
+ if (!equal) return false;
689
+ }
690
+
691
+ return true;
692
+ }
693
+
694
+ return isEqual(a, b);
695
+ });
696
+
697
+ if (isPlainObject(result)) {
698
+ const trackedResult = { ...result
699
+ };
700
+ Object.defineProperties(trackedResult, Object.entries(trackedResult).reduce((res, _ref) => {
701
+ let [key, value] = _ref;
702
+ return { ...res,
703
+ [key]: {
704
+ configurable: false,
705
+ enumerable: true,
706
+ get: () => {
707
+ if (!trackedKeys.current.includes(key)) {
708
+ trackedKeys.current.push(key);
709
+ }
710
+
711
+ return value;
712
+ }
713
+ }
714
+ };
715
+ }, {}));
716
+ return trackedResult;
717
+ }
718
+
719
+ return result;
720
+ }
721
+
722
+ function useAccount() {
723
+ let {
724
+ onConnect,
725
+ onDisconnect
726
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
727
+ const account = useSyncExternalStoreWithTracked(core.watchAccount, core.getAccount);
728
+ const {
729
+ subscribe
730
+ } = useClient();
731
+ React__namespace.useEffect(() => {
732
+ // No need to subscribe if these callbacks aren't defined
733
+ if (!onConnect && !onDisconnect) return; // Trigger update when status changes
734
+
735
+ const unsubscribe = subscribe(state => state.status, (status, prevStatus) => {
736
+ if (!!onConnect && status === 'connected') {
737
+ const {
738
+ address,
739
+ connector
740
+ } = core.getAccount();
741
+ onConnect({
742
+ address,
743
+ connector,
744
+ isReconnected: prevStatus === 'reconnecting'
745
+ });
746
+ }
747
+
748
+ if (!!onDisconnect && prevStatus !== 'connecting' && status === 'disconnected') onDisconnect();
749
+ });
750
+ return unsubscribe;
751
+ }, [onConnect, onDisconnect, subscribe]);
752
+ return account;
753
+ }
754
+
780
755
  const queryKey$a = _ref => {
781
756
  let {
782
757
  addressOrName,
@@ -1372,6 +1347,7 @@ function useContractInfiniteReads(_ref5) {
1372
1347
  contracts,
1373
1348
  enabled: enabled_ = true,
1374
1349
  getNextPageParam,
1350
+ isDataEqual = core.deepEqual,
1375
1351
  keepPreviousData,
1376
1352
  onError,
1377
1353
  onSettled,
@@ -1394,8 +1370,9 @@ function useContractInfiniteReads(_ref5) {
1394
1370
  }), {
1395
1371
  cacheTime,
1396
1372
  enabled,
1397
- keepPreviousData,
1398
1373
  getNextPageParam,
1374
+ isDataEqual,
1375
+ keepPreviousData,
1399
1376
  select,
1400
1377
  staleTime,
1401
1378
  suspense,
@@ -1470,6 +1447,7 @@ function useContractRead(_ref4) {
1470
1447
  cacheOnBlock = false,
1471
1448
  cacheTime,
1472
1449
  enabled: enabled_ = true,
1450
+ isDataEqual = core.deepEqual,
1473
1451
  select,
1474
1452
  staleTime,
1475
1453
  suspense,
@@ -1502,24 +1480,14 @@ function useContractRead(_ref4) {
1502
1480
  if (cacheOnBlock) enabled = Boolean(enabled && blockNumber);
1503
1481
  return enabled;
1504
1482
  }, [addressOrName, blockNumber, cacheOnBlock, enabled_, functionName]);
1505
- const client = reactQuery.useQueryClient();
1506
- React__namespace.useEffect(() => {
1507
- if (enabled) {
1508
- const unwatch = core.watchReadContract({
1509
- addressOrName,
1510
- args,
1511
- chainId,
1512
- contractInterface,
1513
- functionName,
1514
- overrides,
1515
- listenToBlock: watch && !cacheOnBlock
1516
- }, result => client.setQueryData(queryKey_, result));
1517
- return unwatch;
1518
- }
1519
- }, [addressOrName, args, cacheOnBlock, chainId, client, contractInterface, enabled, functionName, overrides, queryKey_, watch]);
1483
+ useInvalidateOnBlock({
1484
+ enabled: watch && !cacheOnBlock,
1485
+ queryKey: queryKey_
1486
+ });
1520
1487
  return useQuery(queryKey_, queryFn$7, {
1521
1488
  cacheTime,
1522
1489
  enabled,
1490
+ isDataEqual,
1523
1491
  queryKeyHashFn: queryKeyHashFn$1,
1524
1492
  select: data => {
1525
1493
  const result = parseContractResult({
@@ -1600,6 +1568,7 @@ function useContractReads(_ref4) {
1600
1568
  contracts,
1601
1569
  overrides,
1602
1570
  enabled: enabled_ = true,
1571
+ isDataEqual = core.deepEqual,
1603
1572
  keepPreviousData,
1604
1573
  onError,
1605
1574
  onSettled,
@@ -1629,20 +1598,14 @@ function useContractReads(_ref4) {
1629
1598
  if (cacheOnBlock) enabled = Boolean(enabled && blockNumber);
1630
1599
  return enabled;
1631
1600
  }, [blockNumber, cacheOnBlock, contracts, enabled_]);
1632
- const client = reactQuery.useQueryClient();
1633
- React__namespace.useEffect(() => {
1634
- if (enabled) {
1635
- const unwatch = core.watchReadContracts({
1636
- contracts,
1637
- overrides,
1638
- listenToBlock: watch && !cacheOnBlock
1639
- }, result => client.setQueryData(queryKey_, result));
1640
- return unwatch;
1641
- }
1642
- }, [cacheOnBlock, client, contracts, enabled, overrides, queryKey_, watch]);
1601
+ useInvalidateOnBlock({
1602
+ enabled: watch && !cacheOnBlock,
1603
+ queryKey: queryKey_
1604
+ });
1643
1605
  return useQuery(queryKey_, queryFn$6, {
1644
1606
  cacheTime,
1645
1607
  enabled,
1608
+ isDataEqual,
1646
1609
  keepPreviousData,
1647
1610
  queryKeyHashFn,
1648
1611
  staleTime,
@@ -2290,6 +2253,10 @@ Object.defineProperty(exports, 'createStorage', {
2290
2253
  enumerable: true,
2291
2254
  get: function () { return core.createStorage; }
2292
2255
  });
2256
+ Object.defineProperty(exports, 'deepEqual', {
2257
+ enumerable: true,
2258
+ get: function () { return core.deepEqual; }
2259
+ });
2293
2260
  Object.defineProperty(exports, 'defaultChains', {
2294
2261
  enumerable: true,
2295
2262
  get: function () { return core.defaultChains; }
package/dist/wagmi.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { createClient as createClient$1, getProvider, watchProvider, getWebSocketProvider, watchWebSocketProvider, getAccount, watchAccount, fetchBlockNumber, fetchFeeData, fetchBalance, connect, disconnect, getNetwork, watchNetwork, watchSigner, fetchSigner, signMessage, signTypedData, switchNetwork, getContract, readContracts, watchReadContract, readContract, watchReadContracts, writeContract, fetchToken, fetchEnsAddress, fetchEnsAvatar, fetchEnsName, fetchEnsResolver, sendTransaction, waitForTransaction } from '@wagmi/core';
3
- export { AddChainError, ChainDoesNotSupportMulticallError, ChainMismatchError, ChainNotConfiguredError, Client, Connector, ConnectorAlreadyConnectedError, ConnectorNotFoundError, ContractMethodNoResultError, ProviderChainsNotFound, ProviderRpcError, ResourceUnavailableError, RpcError, SwitchChainError, SwitchChainNotSupportedError, UserRejectedRequestError, alchemyRpcUrls, allChains, chain, chainId, configureChains, createStorage, defaultChains, defaultL2Chains, erc20ABI, erc721ABI, etherscanBlockExplorers, infuraRpcUrls, publicRpcUrls, readContracts } from '@wagmi/core';
2
+ import { createClient as createClient$1, getProvider, watchProvider, getWebSocketProvider, watchWebSocketProvider, fetchBlockNumber, fetchFeeData, deepEqual, getAccount, watchAccount, fetchBalance, connect, disconnect, getNetwork, watchNetwork, watchSigner, fetchSigner, signMessage, signTypedData, switchNetwork, getContract, readContracts, readContract, writeContract, fetchToken, fetchEnsAddress, fetchEnsAvatar, fetchEnsName, fetchEnsResolver, sendTransaction, waitForTransaction } from '@wagmi/core';
3
+ export { AddChainError, ChainDoesNotSupportMulticallError, ChainMismatchError, ChainNotConfiguredError, Client, Connector, ConnectorAlreadyConnectedError, ConnectorNotFoundError, ContractMethodNoResultError, ProviderChainsNotFound, ProviderRpcError, ResourceUnavailableError, RpcError, SwitchChainError, SwitchChainNotSupportedError, UserRejectedRequestError, alchemyRpcUrls, allChains, chain, chainId, configureChains, createStorage, deepEqual, defaultChains, defaultL2Chains, erc20ABI, erc721ABI, etherscanBlockExplorers, infuraRpcUrls, publicRpcUrls, readContracts } from '@wagmi/core';
4
4
  import { QueryClient, QueryClientProvider, useQueryClient, useIsRestoring, useQueryErrorResetBoundary, notifyManager, InfiniteQueryObserver, QueryObserver, useMutation, hashQueryKey } from 'react-query';
5
5
  import { persistQueryClient } from 'react-query/persistQueryClient';
6
6
  import { createWebStoragePersister } from 'react-query/createWebStoragePersister';
@@ -8,44 +8,6 @@ import { BigNumber, Contract } from 'ethers/lib/ethers';
8
8
  import * as pkg from 'use-sync-external-store/shim/index.js';
9
9
  import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js';
10
10
 
11
- /** Forked from https://github.com/epoberezkin/fast-deep-equal */
12
- function deepEqual(a, b) {
13
- if (a === b) return true;
14
-
15
- if (a && b && typeof a === 'object' && typeof b === 'object') {
16
- if (a.constructor !== b.constructor) return false;
17
- let length;
18
- let i;
19
-
20
- if (Array.isArray(a) && Array.isArray(b)) {
21
- length = a.length;
22
- if (length != b.length) return false;
23
-
24
- for (i = length; i-- !== 0;) if (!deepEqual(a[i], b[i])) return false;
25
-
26
- return true;
27
- }
28
-
29
- if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
30
- if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
31
- const keys = Object.keys(a);
32
- length = keys.length;
33
- if (length !== Object.keys(b).length) return false;
34
-
35
- for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
36
-
37
- for (i = length; i-- !== 0;) {
38
- const key = keys[i];
39
- if (key && !deepEqual(a[key], b[key])) return false;
40
- }
41
-
42
- return true;
43
- } // true if both NaN, false otherwise
44
-
45
-
46
- return a !== a && b !== b;
47
- }
48
-
49
11
  const findAndReplace = (cacheRef, _ref) => {
50
12
  let {
51
13
  find,
@@ -540,83 +502,6 @@ function useForceUpdate() {
540
502
  return forceUpdate;
541
503
  }
542
504
 
543
- const isPlainObject = obj => typeof obj === 'object' && !Array.isArray(obj);
544
-
545
- function useSyncExternalStoreWithTracked(subscribe, getSnapshot) {
546
- let getServerSnapshot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getSnapshot;
547
- let isEqual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (a, b) => deepEqual(a, b);
548
- const trackedKeys = React.useRef([]);
549
- const result = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, x => x, (a, b) => {
550
- if (isPlainObject(a) && isPlainObject(b)) {
551
- for (const key of trackedKeys.current) {
552
- const equal = isEqual(a[key], b[key]);
553
- if (!equal) return false;
554
- }
555
-
556
- return true;
557
- }
558
-
559
- return isEqual(a, b);
560
- });
561
-
562
- if (isPlainObject(result)) {
563
- const trackedResult = { ...result
564
- };
565
- Object.defineProperties(trackedResult, Object.entries(trackedResult).reduce((res, _ref) => {
566
- let [key, value] = _ref;
567
- return { ...res,
568
- [key]: {
569
- configurable: false,
570
- enumerable: true,
571
- get: () => {
572
- if (!trackedKeys.current.includes(key)) {
573
- trackedKeys.current.push(key);
574
- }
575
-
576
- return value;
577
- }
578
- }
579
- };
580
- }, {}));
581
- return trackedResult;
582
- }
583
-
584
- return result;
585
- }
586
-
587
- function useAccount() {
588
- let {
589
- onConnect,
590
- onDisconnect
591
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
592
- const account = useSyncExternalStoreWithTracked(watchAccount, getAccount);
593
- const {
594
- subscribe
595
- } = useClient();
596
- React.useEffect(() => {
597
- // No need to subscribe if these callbacks aren't defined
598
- if (!onConnect && !onDisconnect) return; // Trigger update when status changes
599
-
600
- const unsubscribe = subscribe(state => state.status, (status, prevStatus) => {
601
- if (!!onConnect && status === 'connected') {
602
- const {
603
- address,
604
- connector
605
- } = getAccount();
606
- onConnect({
607
- address,
608
- connector,
609
- isReconnected: prevStatus === 'reconnecting'
610
- });
611
- }
612
-
613
- if (!!onDisconnect && prevStatus !== 'connecting' && status === 'disconnected') onDisconnect();
614
- });
615
- return unsubscribe;
616
- }, [onConnect, onDisconnect, subscribe]);
617
- return account;
618
- }
619
-
620
505
  const queryKey$c = _ref => {
621
506
  let {
622
507
  chainId
@@ -646,6 +531,7 @@ function useBlockNumber() {
646
531
  staleTime,
647
532
  suspense,
648
533
  watch = false,
534
+ onBlock,
649
535
  onError,
650
536
  onSettled,
651
537
  onSuccess
@@ -657,14 +543,15 @@ function useBlockNumber() {
657
543
  const webSocketProvider = useWebSocketProvider();
658
544
  const queryClient = useQueryClient();
659
545
  React.useEffect(() => {
660
- if (!watch) return;
546
+ if (!watch && !onBlock) return;
661
547
 
662
548
  const listener = blockNumber => {
663
549
  // Just to be safe in case the provider implementation
664
550
  // calls the event callback after .off() has been called
665
- queryClient.setQueryData(queryKey$c({
551
+ if (watch) queryClient.setQueryData(queryKey$c({
666
552
  chainId
667
553
  }), blockNumber);
554
+ if (onBlock) onBlock(blockNumber);
668
555
  };
669
556
 
670
557
  const provider_ = webSocketProvider !== null && webSocketProvider !== void 0 ? webSocketProvider : provider;
@@ -672,7 +559,7 @@ function useBlockNumber() {
672
559
  return () => {
673
560
  provider_.off('block', listener);
674
561
  };
675
- }, [chainId, provider, queryClient, watch, webSocketProvider]);
562
+ }, [chainId, onBlock, provider, queryClient, watch, webSocketProvider]);
676
563
  return useQuery(queryKey$c({
677
564
  chainId
678
565
  }), queryFn$c, {
@@ -753,6 +640,94 @@ function useFeeData() {
753
640
  return feeDataQuery;
754
641
  }
755
642
 
643
+ function useInvalidateOnBlock(_ref) {
644
+ let {
645
+ enabled,
646
+ queryKey
647
+ } = _ref;
648
+ const queryClient = useQueryClient();
649
+ useBlockNumber({
650
+ onBlock: enabled ? () => queryClient.invalidateQueries(queryKey) : undefined
651
+ });
652
+ }
653
+
654
+ const isPlainObject = obj => typeof obj === 'object' && !Array.isArray(obj);
655
+
656
+ function useSyncExternalStoreWithTracked(subscribe, getSnapshot) {
657
+ let getServerSnapshot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getSnapshot;
658
+ let isEqual = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : (a, b) => deepEqual(a, b);
659
+ const trackedKeys = React.useRef([]);
660
+ const result = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, x => x, (a, b) => {
661
+ if (isPlainObject(a) && isPlainObject(b)) {
662
+ for (const key of trackedKeys.current) {
663
+ const equal = isEqual(a[key], b[key]);
664
+ if (!equal) return false;
665
+ }
666
+
667
+ return true;
668
+ }
669
+
670
+ return isEqual(a, b);
671
+ });
672
+
673
+ if (isPlainObject(result)) {
674
+ const trackedResult = { ...result
675
+ };
676
+ Object.defineProperties(trackedResult, Object.entries(trackedResult).reduce((res, _ref) => {
677
+ let [key, value] = _ref;
678
+ return { ...res,
679
+ [key]: {
680
+ configurable: false,
681
+ enumerable: true,
682
+ get: () => {
683
+ if (!trackedKeys.current.includes(key)) {
684
+ trackedKeys.current.push(key);
685
+ }
686
+
687
+ return value;
688
+ }
689
+ }
690
+ };
691
+ }, {}));
692
+ return trackedResult;
693
+ }
694
+
695
+ return result;
696
+ }
697
+
698
+ function useAccount() {
699
+ let {
700
+ onConnect,
701
+ onDisconnect
702
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
703
+ const account = useSyncExternalStoreWithTracked(watchAccount, getAccount);
704
+ const {
705
+ subscribe
706
+ } = useClient();
707
+ React.useEffect(() => {
708
+ // No need to subscribe if these callbacks aren't defined
709
+ if (!onConnect && !onDisconnect) return; // Trigger update when status changes
710
+
711
+ const unsubscribe = subscribe(state => state.status, (status, prevStatus) => {
712
+ if (!!onConnect && status === 'connected') {
713
+ const {
714
+ address,
715
+ connector
716
+ } = getAccount();
717
+ onConnect({
718
+ address,
719
+ connector,
720
+ isReconnected: prevStatus === 'reconnecting'
721
+ });
722
+ }
723
+
724
+ if (!!onDisconnect && prevStatus !== 'connecting' && status === 'disconnected') onDisconnect();
725
+ });
726
+ return unsubscribe;
727
+ }, [onConnect, onDisconnect, subscribe]);
728
+ return account;
729
+ }
730
+
756
731
  const queryKey$a = _ref => {
757
732
  let {
758
733
  addressOrName,
@@ -1348,6 +1323,7 @@ function useContractInfiniteReads(_ref5) {
1348
1323
  contracts,
1349
1324
  enabled: enabled_ = true,
1350
1325
  getNextPageParam,
1326
+ isDataEqual = deepEqual,
1351
1327
  keepPreviousData,
1352
1328
  onError,
1353
1329
  onSettled,
@@ -1370,8 +1346,9 @@ function useContractInfiniteReads(_ref5) {
1370
1346
  }), {
1371
1347
  cacheTime,
1372
1348
  enabled,
1373
- keepPreviousData,
1374
1349
  getNextPageParam,
1350
+ isDataEqual,
1351
+ keepPreviousData,
1375
1352
  select,
1376
1353
  staleTime,
1377
1354
  suspense,
@@ -1446,6 +1423,7 @@ function useContractRead(_ref4) {
1446
1423
  cacheOnBlock = false,
1447
1424
  cacheTime,
1448
1425
  enabled: enabled_ = true,
1426
+ isDataEqual = deepEqual,
1449
1427
  select,
1450
1428
  staleTime,
1451
1429
  suspense,
@@ -1478,24 +1456,14 @@ function useContractRead(_ref4) {
1478
1456
  if (cacheOnBlock) enabled = Boolean(enabled && blockNumber);
1479
1457
  return enabled;
1480
1458
  }, [addressOrName, blockNumber, cacheOnBlock, enabled_, functionName]);
1481
- const client = useQueryClient();
1482
- React.useEffect(() => {
1483
- if (enabled) {
1484
- const unwatch = watchReadContract({
1485
- addressOrName,
1486
- args,
1487
- chainId,
1488
- contractInterface,
1489
- functionName,
1490
- overrides,
1491
- listenToBlock: watch && !cacheOnBlock
1492
- }, result => client.setQueryData(queryKey_, result));
1493
- return unwatch;
1494
- }
1495
- }, [addressOrName, args, cacheOnBlock, chainId, client, contractInterface, enabled, functionName, overrides, queryKey_, watch]);
1459
+ useInvalidateOnBlock({
1460
+ enabled: watch && !cacheOnBlock,
1461
+ queryKey: queryKey_
1462
+ });
1496
1463
  return useQuery(queryKey_, queryFn$7, {
1497
1464
  cacheTime,
1498
1465
  enabled,
1466
+ isDataEqual,
1499
1467
  queryKeyHashFn: queryKeyHashFn$1,
1500
1468
  select: data => {
1501
1469
  const result = parseContractResult({
@@ -1576,6 +1544,7 @@ function useContractReads(_ref4) {
1576
1544
  contracts,
1577
1545
  overrides,
1578
1546
  enabled: enabled_ = true,
1547
+ isDataEqual = deepEqual,
1579
1548
  keepPreviousData,
1580
1549
  onError,
1581
1550
  onSettled,
@@ -1605,20 +1574,14 @@ function useContractReads(_ref4) {
1605
1574
  if (cacheOnBlock) enabled = Boolean(enabled && blockNumber);
1606
1575
  return enabled;
1607
1576
  }, [blockNumber, cacheOnBlock, contracts, enabled_]);
1608
- const client = useQueryClient();
1609
- React.useEffect(() => {
1610
- if (enabled) {
1611
- const unwatch = watchReadContracts({
1612
- contracts,
1613
- overrides,
1614
- listenToBlock: watch && !cacheOnBlock
1615
- }, result => client.setQueryData(queryKey_, result));
1616
- return unwatch;
1617
- }
1618
- }, [cacheOnBlock, client, contracts, enabled, overrides, queryKey_, watch]);
1577
+ useInvalidateOnBlock({
1578
+ enabled: watch && !cacheOnBlock,
1579
+ queryKey: queryKey_
1580
+ });
1619
1581
  return useQuery(queryKey_, queryFn$6, {
1620
1582
  cacheTime,
1621
1583
  enabled,
1584
+ isDataEqual,
1622
1585
  keepPreviousData,
1623
1586
  queryKeyHashFn,
1624
1587
  staleTime,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "wagmi",
3
3
  "description": "React Hooks for Ethereum",
4
4
  "license": "WAGMIT",
5
- "version": "0.5.6",
5
+ "version": "0.5.7",
6
6
  "repository": "tmm/wagmi",
7
7
  "author": "awkweb.eth",
8
8
  "homepage": "https://wagmi.sh",
@@ -1,2 +0,0 @@
1
- /** Forked from https://github.com/epoberezkin/fast-deep-equal */
2
- export declare function deepEqual(a: any, b: any): boolean;