@dappql/react 1.0.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.
- package/dist/react/src/Context.d.ts +35 -0
- package/dist/react/src/Context.d.ts.map +1 -0
- package/dist/react/src/Context.js +42 -0
- package/dist/react/src/ContextQuery.d.ts +66 -0
- package/dist/react/src/ContextQuery.d.ts.map +1 -0
- package/dist/react/src/ContextQuery.js +94 -0
- package/dist/react/src/ContextQueryManager.d.ts +71 -0
- package/dist/react/src/ContextQueryManager.d.ts.map +1 -0
- package/dist/react/src/ContextQueryManager.js +135 -0
- package/dist/react/src/Mutation.d.ts +79 -0
- package/dist/react/src/Mutation.d.ts.map +1 -0
- package/dist/react/src/Mutation.js +147 -0
- package/dist/react/src/Provider.d.ts +34 -0
- package/dist/react/src/Provider.d.ts.map +1 -0
- package/dist/react/src/Provider.js +39 -0
- package/dist/react/src/Query.d.ts +52 -0
- package/dist/react/src/Query.d.ts.map +1 -0
- package/dist/react/src/Query.js +92 -0
- package/dist/react/src/blocksHandler.d.ts +10 -0
- package/dist/react/src/blocksHandler.d.ts.map +1 -0
- package/dist/react/src/blocksHandler.js +32 -0
- package/dist/react/src/buildIteratorQuery.d.ts +5 -0
- package/dist/react/src/buildIteratorQuery.d.ts.map +1 -0
- package/dist/react/src/buildIteratorQuery.js +9 -0
- package/dist/react/src/index.d.ts +7 -0
- package/dist/react/src/index.d.ts.map +1 -0
- package/dist/react/src/index.js +7 -0
- package/dist/react/src/queryHooks.d.ts +31 -0
- package/dist/react/src/queryHooks.d.ts.map +1 -0
- package/dist/react/src/queryHooks.js +49 -0
- package/dist/react/src/useTransactionUpdates.d.ts +3 -0
- package/dist/react/src/useTransactionUpdates.d.ts.map +1 -0
- package/dist/react/src/useTransactionUpdates.js +112 -0
- package/dist/shared/types.d.ts +105 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +2 -0
- package/package.json +74 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import { useAccount, usePublicClient, useWaitForTransactionReceipt, useWriteContract } from 'wagmi';
|
|
3
|
+
import { useDappQL } from './Context.js';
|
|
4
|
+
function useSimulate(config, address, account, chain, client) {
|
|
5
|
+
return useCallback(async (...args) => {
|
|
6
|
+
if (!client)
|
|
7
|
+
throw new Error('No client');
|
|
8
|
+
return await client?.simulateContract({
|
|
9
|
+
abi: config.getAbi(),
|
|
10
|
+
functionName: config.functionName,
|
|
11
|
+
address,
|
|
12
|
+
args,
|
|
13
|
+
account,
|
|
14
|
+
});
|
|
15
|
+
}, [address, config, account, chain?.id, client]);
|
|
16
|
+
}
|
|
17
|
+
function useEstimate(config, address, account, chain, client) {
|
|
18
|
+
return useCallback(async (...args) => {
|
|
19
|
+
if (!client)
|
|
20
|
+
throw new Error('No client');
|
|
21
|
+
return await client?.estimateContractGas({
|
|
22
|
+
abi: config.getAbi(),
|
|
23
|
+
functionName: config.functionName,
|
|
24
|
+
address,
|
|
25
|
+
args,
|
|
26
|
+
account,
|
|
27
|
+
});
|
|
28
|
+
}, [address, config, account, chain?.id, client]);
|
|
29
|
+
}
|
|
30
|
+
function useMutationConfirmation(hash) {
|
|
31
|
+
return useWaitForTransactionReceipt({ hash });
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Hook for executing contract write operations (mutations)
|
|
35
|
+
* @param config Configuration object containing contract details and ABI
|
|
36
|
+
* @param optionsOrTransactionName Optional configuration or transaction name
|
|
37
|
+
* @returns Object containing mutation state and send function
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const mutation = useMutation({
|
|
41
|
+
* contractName: 'MyContract',
|
|
42
|
+
* functionName: 'setValue',
|
|
43
|
+
* getAbi: () => CONTRACT_ABI,
|
|
44
|
+
* deployAddress: '0x...'
|
|
45
|
+
* }, 'Set Value')
|
|
46
|
+
*
|
|
47
|
+
* // Execute the mutation
|
|
48
|
+
* mutation.send(newValue)
|
|
49
|
+
*/
|
|
50
|
+
export function useMutation(config, optionsOrTransactionName) {
|
|
51
|
+
const { addressResolver, onMutationUpdate, simulateMutations } = useDappQL();
|
|
52
|
+
const { chain, address: account } = useAccount();
|
|
53
|
+
const tx = useWriteContract();
|
|
54
|
+
const client = usePublicClient();
|
|
55
|
+
const address = useMemo(() => optionsOrTransactionName && typeof optionsOrTransactionName !== 'string' && optionsOrTransactionName.address
|
|
56
|
+
? optionsOrTransactionName.address
|
|
57
|
+
: addressResolver?.(config.contractName.toString()) || config.deployAddress, [config.contractName, addressResolver, JSON.stringify(optionsOrTransactionName)]);
|
|
58
|
+
const options = useMemo(() => typeof optionsOrTransactionName === 'string'
|
|
59
|
+
? { transactionName: optionsOrTransactionName }
|
|
60
|
+
: optionsOrTransactionName, [optionsOrTransactionName]);
|
|
61
|
+
const mutationInfo = {
|
|
62
|
+
account,
|
|
63
|
+
address,
|
|
64
|
+
contractName: config.contractName,
|
|
65
|
+
functionName: config.functionName,
|
|
66
|
+
transactionName: options?.transactionName || '',
|
|
67
|
+
};
|
|
68
|
+
const simulate = useSimulate(config, address, account, chain, client);
|
|
69
|
+
const estimate = useEstimate(config, address, account, chain, client);
|
|
70
|
+
const send = useCallback((...args) => {
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
const id = mutationInfo.address + mutationInfo.functionName + now.toString();
|
|
73
|
+
if (!account || !chain?.id) {
|
|
74
|
+
const error = !account ? 'No account connected' : 'Invalid chain';
|
|
75
|
+
onMutationUpdate?.({
|
|
76
|
+
...mutationInfo,
|
|
77
|
+
error: new Error(error),
|
|
78
|
+
args,
|
|
79
|
+
id,
|
|
80
|
+
status: 'error',
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const sendTx = () => {
|
|
85
|
+
tx.writeContract({
|
|
86
|
+
abi: config.getAbi(),
|
|
87
|
+
functionName: config.functionName,
|
|
88
|
+
address,
|
|
89
|
+
chainId: chain?.id,
|
|
90
|
+
args,
|
|
91
|
+
}, {
|
|
92
|
+
onSettled(data, error) {
|
|
93
|
+
const status = error ? 'error' : 'signed';
|
|
94
|
+
onMutationUpdate?.({
|
|
95
|
+
...mutationInfo,
|
|
96
|
+
id,
|
|
97
|
+
args,
|
|
98
|
+
error: error ? new Error(error.message) : undefined,
|
|
99
|
+
status,
|
|
100
|
+
txHash: data,
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
onMutationUpdate?.({
|
|
105
|
+
...mutationInfo,
|
|
106
|
+
id,
|
|
107
|
+
args,
|
|
108
|
+
status: 'submitted',
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
if ((options?.simulate ?? simulateMutations) && client) {
|
|
112
|
+
simulate(...args)
|
|
113
|
+
.then(sendTx)
|
|
114
|
+
.catch((error) => {
|
|
115
|
+
onMutationUpdate?.({
|
|
116
|
+
...mutationInfo,
|
|
117
|
+
id,
|
|
118
|
+
args,
|
|
119
|
+
error: new Error(error.message),
|
|
120
|
+
status: 'error',
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
sendTx();
|
|
126
|
+
}
|
|
127
|
+
}, [address, tx, config, account, chain?.id, options?.simulate, simulateMutations, client, simulate]);
|
|
128
|
+
const confirmation = useMutationConfirmation(tx.data);
|
|
129
|
+
return useMemo(() => ({
|
|
130
|
+
status: tx.status,
|
|
131
|
+
data: tx.data,
|
|
132
|
+
error: tx.error,
|
|
133
|
+
isPending: tx.isPending,
|
|
134
|
+
isSuccess: tx.isSuccess,
|
|
135
|
+
isError: tx.isError,
|
|
136
|
+
isLoading: tx.isPending || confirmation.isLoading,
|
|
137
|
+
failureCount: tx.failureCount,
|
|
138
|
+
failureReason: tx.failureReason,
|
|
139
|
+
isIdle: tx.isIdle,
|
|
140
|
+
submittedAt: tx.submittedAt,
|
|
141
|
+
confirmation,
|
|
142
|
+
reset: tx.reset,
|
|
143
|
+
send,
|
|
144
|
+
simulate,
|
|
145
|
+
estimate,
|
|
146
|
+
}), [tx, send, confirmation, simulate, estimate]);
|
|
147
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ComponentType } from 'react';
|
|
2
|
+
import { MutationCallbacks, AddressResolverFunction, AddressResolverProps, QueryContextProps } from '../../shared/types.js';
|
|
3
|
+
export declare const ADDRESS_RESOLVER_ERROR = "Cannot provide both AddressResolverComponent and addressResolver. Please use only one of these props.";
|
|
4
|
+
/**
|
|
5
|
+
* Props for the Provider component
|
|
6
|
+
*/
|
|
7
|
+
type BaseProviderProps = QueryContextProps & {
|
|
8
|
+
children: any;
|
|
9
|
+
/** Whether to simulate mutations before sending them */
|
|
10
|
+
simulateMutations?: boolean;
|
|
11
|
+
} & MutationCallbacks;
|
|
12
|
+
export type ProviderProps = BaseProviderProps & ({
|
|
13
|
+
/** Function to resolve contract addresses */
|
|
14
|
+
addressResolver: AddressResolverFunction;
|
|
15
|
+
/** Component to handle address resolution - cannot be used with addressResolver */
|
|
16
|
+
AddressResolverComponent?: never;
|
|
17
|
+
} | {
|
|
18
|
+
/** Function to resolve contract addresses - cannot be used with AddressResolverComponent */
|
|
19
|
+
addressResolver?: never;
|
|
20
|
+
/** Component to handle address resolution */
|
|
21
|
+
AddressResolverComponent: ComponentType<AddressResolverProps>;
|
|
22
|
+
} | {
|
|
23
|
+
/** Function to resolve contract addresses - optional if no resolution needed */
|
|
24
|
+
addressResolver?: never;
|
|
25
|
+
/** Component to handle address resolution - optional if no resolution needed */
|
|
26
|
+
AddressResolverComponent?: never;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Core provider component for DappQL
|
|
30
|
+
* Manages contract address resolution and mutation callbacks
|
|
31
|
+
*/
|
|
32
|
+
export declare function DappQLProvider({ children, AddressResolverComponent, blocksRefetchInterval, defaultBatchSize, watchBlocks, simulateMutations, addressResolver, onMutationUpdate, }: ProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=Provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Provider.d.ts","sourceRoot":"","sources":["../../../src/Provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,OAAO,CAAA;AAI7D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,uBAAuB,CAAA;AAI9B,eAAO,MAAM,sBAAsB,0GACsE,CAAA;AAEzG;;GAEG;AACH,KAAK,iBAAiB,GAAG,iBAAiB,GAAG;IAC3C,QAAQ,EAAE,GAAG,CAAA;IACb,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,GAAG,iBAAiB,CAAA;AAErB,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAC3C,CACI;IACE,6CAA6C;IAC7C,eAAe,EAAE,uBAAuB,CAAA;IACxC,mFAAmF;IACnF,wBAAwB,CAAC,EAAE,KAAK,CAAA;CACjC,GACD;IACE,4FAA4F;IAC5F,eAAe,CAAC,EAAE,KAAK,CAAA;IACvB,6CAA6C;IAC7C,wBAAwB,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;CAC9D,GACD;IACE,gFAAgF;IAChF,eAAe,CAAC,EAAE,KAAK,CAAA;IACvB,gFAAgF;IAChF,wBAAwB,CAAC,EAAE,KAAK,CAAA;CACjC,CACJ,CAAA;AAEH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,wBAAwB,EACxB,qBAAyB,EACzB,gBAAuB,EACvB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,gBAAgB,GACjB,EAAE,aAAa,2CA8Cf"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
|
+
import { useBlockNumberSubscriber } from './blocksHandler.js';
|
|
4
|
+
import useTransactionUpdates from './useTransactionUpdates.js';
|
|
5
|
+
import { DappQLContext } from './Context.js';
|
|
6
|
+
import { ContextQueryProvider } from './ContextQueryManager.js';
|
|
7
|
+
export const ADDRESS_RESOLVER_ERROR = 'Cannot provide both AddressResolverComponent and addressResolver. Please use only one of these props.';
|
|
8
|
+
/**
|
|
9
|
+
* Core provider component for DappQL
|
|
10
|
+
* Manages contract address resolution and mutation callbacks
|
|
11
|
+
*/
|
|
12
|
+
export function DappQLProvider({ children, AddressResolverComponent, blocksRefetchInterval = 1, defaultBatchSize = 1024, watchBlocks, simulateMutations, addressResolver, onMutationUpdate, }) {
|
|
13
|
+
if (AddressResolverComponent && addressResolver) {
|
|
14
|
+
throw new Error(ADDRESS_RESOLVER_ERROR);
|
|
15
|
+
}
|
|
16
|
+
const [addressResolverState, setAddressResolver] = useState({ resolver: addressResolver });
|
|
17
|
+
const onBlockChange = useBlockNumberSubscriber();
|
|
18
|
+
const handleMutationUpdate = useTransactionUpdates(onMutationUpdate);
|
|
19
|
+
const value = useMemo(() => ({
|
|
20
|
+
onBlockChange,
|
|
21
|
+
onMutationUpdate: handleMutationUpdate,
|
|
22
|
+
addressResolver: addressResolverState.resolver,
|
|
23
|
+
blocksRefetchInterval,
|
|
24
|
+
defaultBatchSize,
|
|
25
|
+
watchBlocks,
|
|
26
|
+
simulateMutations,
|
|
27
|
+
}), [
|
|
28
|
+
onBlockChange,
|
|
29
|
+
handleMutationUpdate,
|
|
30
|
+
addressResolverState.resolver,
|
|
31
|
+
blocksRefetchInterval,
|
|
32
|
+
defaultBatchSize,
|
|
33
|
+
watchBlocks,
|
|
34
|
+
simulateMutations,
|
|
35
|
+
]);
|
|
36
|
+
return (_jsxs(DappQLContext.Provider, { value: value, children: [AddressResolverComponent ? (_jsx(AddressResolverComponent, { onResolved: (resolver) => {
|
|
37
|
+
setAddressResolver({ resolver });
|
|
38
|
+
} })) : null, !AddressResolverComponent || addressResolverState.resolver ? (_jsx(ContextQueryProvider, { ...value, children: children })) : null] }));
|
|
39
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useReadContracts } from 'wagmi';
|
|
2
|
+
import { GetItemCallFunction, QueryOptions, type Request, type RequestCollection } from '../../shared/types.js';
|
|
3
|
+
import { IteratorQueryResult } from './queryHooks.js';
|
|
4
|
+
/**
|
|
5
|
+
* React hook that executes multiple contract read calls in a single multicall
|
|
6
|
+
* @param requests Collection of contract requests to execute
|
|
7
|
+
* @param options Query configuration options
|
|
8
|
+
* @returns Object containing query results and status
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const { data, isLoading } = useQuery({
|
|
12
|
+
* value1: contracts.myContract.getValue(1, 2, 3),
|
|
13
|
+
* value2: contracts.myOtherContract.getOtherValue(4, 5, 6),
|
|
14
|
+
* })
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function useQuery<T extends RequestCollection>(requests: T, options?: QueryOptions): Omit<ReturnType<typeof useReadContracts>, 'data'> & {
|
|
18
|
+
data: {
|
|
19
|
+
[K in keyof T]: NonNullable<T[K]['defaultValue']>;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* React hook that executes a single contract read call
|
|
24
|
+
* This is a convenience wrapper around useQuery for when you only need to query one contract method
|
|
25
|
+
* @param request The contract request to execute
|
|
26
|
+
* @param options Query configuration options
|
|
27
|
+
* @returns Object containing the query result and status, with data directly accessible (not nested in an object)
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const { data, isLoading } = useSingleQuery(
|
|
31
|
+
* contracts.myContract.getValue(1, 2, 3)
|
|
32
|
+
* )
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function useSingleQuery<T extends Request>(request: T, options?: QueryOptions): Omit<ReturnType<typeof useQuery>, 'data'> & {
|
|
36
|
+
data: NonNullable<T['defaultValue']>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* React hook for querying iterable data structures (like arrays) from smart contracts
|
|
40
|
+
* @param total Total number of items to query
|
|
41
|
+
* @param getItem Function that generates the query for a specific index
|
|
42
|
+
* @param options Query configuration options including optional starting index
|
|
43
|
+
* @returns Object containing array of query results and status
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* const { data, isLoading } = useIteratorQuery(10, (i) => contracts.myContract.getValue(i))
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function useIteratorQuery<T>(total: bigint, getItem: GetItemCallFunction<T>, options?: QueryOptions & {
|
|
50
|
+
firstIndex?: bigint;
|
|
51
|
+
}): IteratorQueryResult<T>;
|
|
52
|
+
//# sourceMappingURL=Query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Query.d.ts","sourceRoot":"","sources":["../../../src/Query.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AAExC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE/G,OAAO,EAAE,mBAAmB,EAAuD,MAAM,iBAAiB,CAAA;AAK1G;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,iBAAiB,EAClD,QAAQ,EAAE,CAAC,EACX,OAAO,GAAE,YAAiB,GACzB,IAAI,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG;IACrD,IAAI,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;KAAE,CAAA;CAC5D,CA0CA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,OAAO,EAC9C,OAAO,EAAE,CAAC,EACV,OAAO,GAAE,YAAiB,GACzB,IAAI,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAA;CAAE,CAMtF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC/B,OAAO,GAAE,YAAY,GAAG;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;CACf,GACL,mBAAmB,CAAC,CAAC,CAAC,CAKxB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useReadContracts } from 'wagmi';
|
|
3
|
+
import { useDappQL, useRefetchOnBlockChange } from './Context.js';
|
|
4
|
+
import { useDefaultData, useIteratorQueryData, useResultData } from './queryHooks.js';
|
|
5
|
+
import { useCallKeys } from './queryHooks.js';
|
|
6
|
+
import { useRequestString } from './queryHooks.js';
|
|
7
|
+
import { buildIteratorQuery } from './buildIteratorQuery.js';
|
|
8
|
+
/**
|
|
9
|
+
* React hook that executes multiple contract read calls in a single multicall
|
|
10
|
+
* @param requests Collection of contract requests to execute
|
|
11
|
+
* @param options Query configuration options
|
|
12
|
+
* @returns Object containing query results and status
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const { data, isLoading } = useQuery({
|
|
16
|
+
* value1: contracts.myContract.getValue(1, 2, 3),
|
|
17
|
+
* value2: contracts.myOtherContract.getOtherValue(4, 5, 6),
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function useQuery(requests, options = {}) {
|
|
22
|
+
const { addressResolver, blocksRefetchInterval, defaultBatchSize, watchBlocks } = useDappQL();
|
|
23
|
+
const requestString = useRequestString(requests);
|
|
24
|
+
const callKeys = useCallKeys(requests, requestString);
|
|
25
|
+
const calls = useMemo(() => {
|
|
26
|
+
return Object.values(requests).map((req) => {
|
|
27
|
+
return {
|
|
28
|
+
abi: req.getAbi(),
|
|
29
|
+
functionName: req.method,
|
|
30
|
+
args: req.args,
|
|
31
|
+
address: req.address || addressResolver?.(req.contractName) || req.deployAddress,
|
|
32
|
+
chainId: req.chainId,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
}, [requestString]);
|
|
36
|
+
const defaultData = useDefaultData(requests, callKeys);
|
|
37
|
+
const result = useReadContracts({
|
|
38
|
+
blockNumber: options.blockNumber,
|
|
39
|
+
query: {
|
|
40
|
+
enabled: !options.paused,
|
|
41
|
+
refetchInterval: options.refetchInterval,
|
|
42
|
+
notifyOnChangeProps: ['data', 'error'],
|
|
43
|
+
},
|
|
44
|
+
contracts: calls,
|
|
45
|
+
batchSize: options.batchSize ?? defaultBatchSize,
|
|
46
|
+
});
|
|
47
|
+
const data = useResultData(requests, callKeys, result, defaultData);
|
|
48
|
+
useRefetchOnBlockChange(result.refetch, (options.watchBlocks ?? watchBlocks) &&
|
|
49
|
+
!options.paused &&
|
|
50
|
+
!options.isStatic &&
|
|
51
|
+
!options.blockNumber &&
|
|
52
|
+
!options.refetchInterval, options.blocksRefetchInterval ?? blocksRefetchInterval);
|
|
53
|
+
return useMemo(() => {
|
|
54
|
+
return { ...result, data };
|
|
55
|
+
}, [result.error, result.isLoading, data]);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* React hook that executes a single contract read call
|
|
59
|
+
* This is a convenience wrapper around useQuery for when you only need to query one contract method
|
|
60
|
+
* @param request The contract request to execute
|
|
61
|
+
* @param options Query configuration options
|
|
62
|
+
* @returns Object containing the query result and status, with data directly accessible (not nested in an object)
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const { data, isLoading } = useSingleQuery(
|
|
66
|
+
* contracts.myContract.getValue(1, 2, 3)
|
|
67
|
+
* )
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export function useSingleQuery(request, options = {}) {
|
|
71
|
+
const result = useQuery({ value: request }, options);
|
|
72
|
+
return useMemo(() => {
|
|
73
|
+
return { ...result, data: result.data.value };
|
|
74
|
+
}, [result]);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* React hook for querying iterable data structures (like arrays) from smart contracts
|
|
78
|
+
* @param total Total number of items to query
|
|
79
|
+
* @param getItem Function that generates the query for a specific index
|
|
80
|
+
* @param options Query configuration options including optional starting index
|
|
81
|
+
* @returns Object containing array of query results and status
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const { data, isLoading } = useIteratorQuery(10, (i) => contracts.myContract.getValue(i))
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export function useIteratorQuery(total, getItem, options = {}) {
|
|
88
|
+
const { firstIndex = 0n, ...queryParams } = options;
|
|
89
|
+
const query = useMemo(() => buildIteratorQuery(total, firstIndex, getItem), [total, firstIndex, getItem]);
|
|
90
|
+
const result = useQuery(query, queryParams);
|
|
91
|
+
return useIteratorQueryData(total, result);
|
|
92
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type Subscriber = (blockNumber: bigint) => void;
|
|
2
|
+
export declare class BlockSubscriptionManager {
|
|
3
|
+
private subscribers;
|
|
4
|
+
private currentBlock;
|
|
5
|
+
subscribe(callback: Subscriber): () => boolean;
|
|
6
|
+
onBlockUptated(newBlock: bigint): void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useBlockNumberSubscriber(): (callback: Subscriber) => () => boolean;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=blocksHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocksHandler.d.ts","sourceRoot":"","sources":["../../../src/blocksHandler.ts"],"names":[],"mappings":"AAGA,KAAK,UAAU,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;AAE/C,qBAAa,wBAAwB;IACnC,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,YAAY,CAAa;IAEjC,SAAS,CAAC,QAAQ,EAAE,UAAU;IAO9B,cAAc,CAAC,QAAQ,EAAE,MAAM;CAIhC;AAED,wBAAgB,wBAAwB,eAazB,UAAU,mBAKxB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useEffect, useMemo, useCallback } from 'react';
|
|
2
|
+
import { usePublicClient } from 'wagmi';
|
|
3
|
+
export class BlockSubscriptionManager {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.subscribers = new Set();
|
|
6
|
+
this.currentBlock = 0n;
|
|
7
|
+
}
|
|
8
|
+
subscribe(callback) {
|
|
9
|
+
this.subscribers.add(callback);
|
|
10
|
+
// Immediately call with current value
|
|
11
|
+
callback(this.currentBlock);
|
|
12
|
+
return () => this.subscribers.delete(callback);
|
|
13
|
+
}
|
|
14
|
+
onBlockUptated(newBlock) {
|
|
15
|
+
this.currentBlock = newBlock;
|
|
16
|
+
this.subscribers.forEach((sub) => sub(newBlock));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function useBlockNumberSubscriber() {
|
|
20
|
+
const client = usePublicClient();
|
|
21
|
+
const manager = useMemo(() => new BlockSubscriptionManager(), []);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
return client?.watchBlockNumber({
|
|
24
|
+
onBlockNumber: (blockNumber) => {
|
|
25
|
+
manager.onBlockUptated(blockNumber);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}, [client, manager]);
|
|
29
|
+
return useCallback((callback) => {
|
|
30
|
+
return manager.subscribe(callback);
|
|
31
|
+
}, [manager]);
|
|
32
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { GetItemCallFunction } from '../../shared/types.js';
|
|
2
|
+
export declare function buildIteratorQuery<T>(total: bigint, firstIndex: bigint, getItem: GetItemCallFunction<T>): Record<string, import("../../shared/types.js").Request & {
|
|
3
|
+
defaultValue: T;
|
|
4
|
+
}>;
|
|
5
|
+
//# sourceMappingURL=buildIteratorQuery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildIteratorQuery.d.ts","sourceRoot":"","sources":["../../../src/buildIteratorQuery.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAE3D,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;;GAQvG"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
export function buildIteratorQuery(total, firstIndex, getItem) {
|
|
3
|
+
const iterator = Array.from(new Array(Number(total)).keys());
|
|
4
|
+
return iterator.reduce((acc, index) => {
|
|
5
|
+
const realIndex = BigInt(index) + firstIndex;
|
|
6
|
+
acc[`item${realIndex}`] = getItem(realIndex);
|
|
7
|
+
return acc;
|
|
8
|
+
}, {});
|
|
9
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './Provider.js';
|
|
2
|
+
export * from './Query.js';
|
|
3
|
+
export * from './Mutation.js';
|
|
4
|
+
export * from './ContextQuery.js';
|
|
5
|
+
export { ContextQueryProvider } from './ContextQueryManager.js';
|
|
6
|
+
export { type Request, type RequestCollection, type MutationConfig, type MutationCollection, type QueryOptions, type MutationInfo, type MutationCallbacks, type AddressResolverFunction, type AddressResolverProps, type ReadContractsResult, type GetItemCallFunction, } from '../../shared/types.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ReadContractsResult, RequestCollection } from '../../shared/types.js';
|
|
2
|
+
export declare function useRequestString<T extends RequestCollection>(requests: T): string;
|
|
3
|
+
export declare function useCallKeys<T extends RequestCollection>(requests: T, requestString: string): (keyof T)[];
|
|
4
|
+
export declare function useDefaultData<T extends RequestCollection>(requests: T, callKeys: (keyof T)[]): { [K in keyof T]: NonNullable<T[K]["defaultValue"]>; };
|
|
5
|
+
export declare function useResultData<T extends RequestCollection>(requests: T, callKeys: (keyof T)[], result: ReadContractsResult, defaultData: {
|
|
6
|
+
[K in keyof T]: NonNullable<T[K]['defaultValue']>;
|
|
7
|
+
}): { [K in keyof T]: NonNullable<T[K]["defaultValue"]>; };
|
|
8
|
+
export type IteratorQueryResultData<T> = {
|
|
9
|
+
value: NonNullable<T>;
|
|
10
|
+
queryIndex: bigint;
|
|
11
|
+
}[];
|
|
12
|
+
export type IteratorQueryResult<T> = {
|
|
13
|
+
data: IteratorQueryResultData<T>;
|
|
14
|
+
isLoading?: boolean;
|
|
15
|
+
error?: Error | null;
|
|
16
|
+
};
|
|
17
|
+
export declare function useIteratorQueryData<T>(total: bigint, result: {
|
|
18
|
+
isLoading?: boolean;
|
|
19
|
+
isError?: boolean;
|
|
20
|
+
error?: Error | null;
|
|
21
|
+
data: Record<string, T>;
|
|
22
|
+
}): {
|
|
23
|
+
data: IteratorQueryResultData<T>;
|
|
24
|
+
isLoading: boolean;
|
|
25
|
+
error?: undefined;
|
|
26
|
+
} | {
|
|
27
|
+
data: IteratorQueryResultData<T>;
|
|
28
|
+
isLoading: boolean | undefined;
|
|
29
|
+
error: Error | null | undefined;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=queryHooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryHooks.d.ts","sourceRoot":"","sources":["../../../src/queryHooks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9E,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,iBAAiB,EAAE,QAAQ,EAAE,CAAC,UAExE;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,iBAAiB,EAAE,QAAQ,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,eAE1F;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,iBAAiB,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MACvE,CAAC,mDASvB;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,iBAAiB,EACvD,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EACrB,MAAM,EAAE,mBAAmB,EAC3B,WAAW,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;CAAE,MAE7C,CAAC,mDAuBvB;AAED,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAAE,CAAA;AACxF,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IAAE,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAA;CAAE,CAAA;AACpH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IACN,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAA;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;CACxB;UAGwC,uBAAuB,CAAC,CAAC,CAAC;;;;;;;EAcpE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useMemo, useRef } from 'react';
|
|
2
|
+
import { stringify } from 'viem';
|
|
3
|
+
export function useRequestString(requests) {
|
|
4
|
+
return useMemo(() => stringify(requests), [stringify(requests)]);
|
|
5
|
+
}
|
|
6
|
+
export function useCallKeys(requests, requestString) {
|
|
7
|
+
return useMemo(() => Object.keys(requests), [requestString]);
|
|
8
|
+
}
|
|
9
|
+
export function useDefaultData(requests, callKeys) {
|
|
10
|
+
return useMemo(() => callKeys.reduce((acc, k) => {
|
|
11
|
+
acc[k] = requests[k].defaultValue;
|
|
12
|
+
return acc;
|
|
13
|
+
}, {}), [callKeys]);
|
|
14
|
+
}
|
|
15
|
+
export function useResultData(requests, callKeys, result, defaultData) {
|
|
16
|
+
const previousData = useRef(defaultData);
|
|
17
|
+
return useMemo(() => {
|
|
18
|
+
if (!result.error) {
|
|
19
|
+
const newData = callKeys.reduce((acc, k, index) => {
|
|
20
|
+
acc[k] = result.data?.[index]?.result ?? previousData.current[k] ?? requests?.[k]?.defaultValue;
|
|
21
|
+
return acc;
|
|
22
|
+
}, {});
|
|
23
|
+
previousData.current = newData;
|
|
24
|
+
return newData;
|
|
25
|
+
}
|
|
26
|
+
// During error, merge previous data with new default values
|
|
27
|
+
return callKeys.reduce((acc, k) => {
|
|
28
|
+
acc[k] = previousData.current[k] ?? requests[k].defaultValue;
|
|
29
|
+
return acc;
|
|
30
|
+
}, {});
|
|
31
|
+
}, [stringify(result.data), result.error, defaultData]);
|
|
32
|
+
}
|
|
33
|
+
export function useIteratorQueryData(total, result) {
|
|
34
|
+
return useMemo(() => {
|
|
35
|
+
if (total === 0n)
|
|
36
|
+
return { data: [], isLoading: false };
|
|
37
|
+
const items = Object.keys(result.data)
|
|
38
|
+
.map((k) => ({
|
|
39
|
+
value: result.data[k],
|
|
40
|
+
queryIndex: BigInt(k.replace('item', '')),
|
|
41
|
+
}))
|
|
42
|
+
.filter((i) => !!i.value);
|
|
43
|
+
return {
|
|
44
|
+
data: items,
|
|
45
|
+
isLoading: result.isLoading,
|
|
46
|
+
error: result.error,
|
|
47
|
+
};
|
|
48
|
+
}, [result.data, result.isLoading, result.error, total]);
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTransactionUpdates.d.ts","sourceRoot":"","sources":["../../../src/useTransactionUpdates.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAiHpD,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,GAAG,cAcrE,YAAY,UAM1B"}
|