@dappql/react 1.0.7 → 1.0.10
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 +143 -0
- package/dist/Mutation.d.ts.map +1 -1
- package/dist/Mutation.js +14 -2
- package/dist/blocksHandler.d.ts +1 -1
- package/dist/blocksHandler.js +2 -2
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# @dappql/react
|
|
2
|
+
|
|
3
|
+
> React hooks for [DappQL](https://github.com/dappql/core). Typed, batched smart-contract reads and writes on top of [wagmi](https://wagmi.sh) + [viem](https://viem.sh), with automatic multicall fusion across your entire component tree, per-block reactivity, iterator queries, and mutation tracking.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @dappql/react wagmi viem @tanstack/react-query
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Pair with the [`dappql`](https://www.npmjs.com/package/dappql) CLI to generate your typed contract modules.
|
|
12
|
+
|
|
13
|
+
## Provider
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { WagmiProvider } from 'wagmi'
|
|
17
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
18
|
+
import { DappQLProvider } from '@dappql/react'
|
|
19
|
+
|
|
20
|
+
const queryClient = new QueryClient()
|
|
21
|
+
|
|
22
|
+
export function Root({ children }) {
|
|
23
|
+
return (
|
|
24
|
+
<WagmiProvider config={wagmiConfig}>
|
|
25
|
+
<QueryClientProvider client={queryClient}>
|
|
26
|
+
<DappQLProvider watchBlocks>{children}</DappQLProvider>
|
|
27
|
+
</QueryClientProvider>
|
|
28
|
+
</WagmiProvider>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Provider options:
|
|
34
|
+
|
|
35
|
+
| Option | Purpose |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `watchBlocks` | Refetch on every new block, makes reads reactive to chain state. |
|
|
38
|
+
| `simulateMutations` | Preflight every tx via `eth_call`. Aborts on revert. |
|
|
39
|
+
| `onMutationUpdate` | Single callback for every transaction lifecycle event, one place to drive toasts, analytics, receipts. |
|
|
40
|
+
| `addressResolver` | Function that resolves contract names to addresses, for registries, proxies, multi-deploy. |
|
|
41
|
+
| `AddressResolverComponent` | Async alternative to `addressResolver` when the resolver needs hooks. |
|
|
42
|
+
|
|
43
|
+
## Reads
|
|
44
|
+
|
|
45
|
+
### `useContextQuery`: the default
|
|
46
|
+
|
|
47
|
+
Batches calls across your **entire** component tree into one multicall.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { Token, ToDo } from './contracts'
|
|
51
|
+
import { useContextQuery } from '@dappql/react'
|
|
52
|
+
|
|
53
|
+
function Dashboard({ account }) {
|
|
54
|
+
const { data, isLoading } = useContextQuery({
|
|
55
|
+
balance: Token.call.balanceOf(account),
|
|
56
|
+
symbol: Token.call.symbol(),
|
|
57
|
+
totalTasks: ToDo.call.totalTasks(),
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
if (isLoading) return <Spinner />
|
|
61
|
+
return <p>{data.balance.toString()} {data.symbol}</p>
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If `<Dashboard>` and `<Sidebar>` both use `useContextQuery`, their calls fuse into one RPC, not two.
|
|
66
|
+
|
|
67
|
+
### `useQuery`: component-scoped batching
|
|
68
|
+
|
|
69
|
+
Same shape as `useContextQuery`, but scoped to this hook call. Use when you need `blockNumber`, `paused`, custom `refetchInterval`, or `batchSize` overrides.
|
|
70
|
+
|
|
71
|
+
### `useSingleQuery` / `useSingleContextQuery`
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
const { data } = useSingleContextQuery(Token.call.balanceOf(account))
|
|
75
|
+
// data: bigint (inferred from the ABI)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `useIteratorQuery`: on-chain arrays
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { useIteratorQuery } from '@dappql/react'
|
|
82
|
+
|
|
83
|
+
const { data } = useIteratorQuery(totalTasks, (i) => ToDo.call.taskAt(account, i))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Writes
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { useMutation } from '@dappql/react'
|
|
90
|
+
import { ToDo } from './contracts'
|
|
91
|
+
|
|
92
|
+
function NewTask() {
|
|
93
|
+
const mutation = useMutation(ToDo.mutation.addItem, 'Add task')
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<button
|
|
97
|
+
disabled={mutation.isLoading}
|
|
98
|
+
onClick={() => mutation.send('Buy milk', 0n)}
|
|
99
|
+
>
|
|
100
|
+
{mutation.confirmation.isSuccess ? 'Added' : 'Add task'}
|
|
101
|
+
</button>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Surface:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
mutation.send(...args) // broadcast; spread args, not array
|
|
110
|
+
mutation.simulate(...args) // manual preflight
|
|
111
|
+
mutation.estimate(...args) // gas estimate
|
|
112
|
+
mutation.isPending // awaiting signature
|
|
113
|
+
mutation.isLoading // awaiting signature OR mining
|
|
114
|
+
mutation.confirmation.isSuccess // receipt confirmed
|
|
115
|
+
mutation.reset()
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Fluent request API
|
|
119
|
+
|
|
120
|
+
Every generated call exposes a small fluent API for overrides:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
Token.call.balanceOf(account)
|
|
124
|
+
.at('0x...') // override deploy address
|
|
125
|
+
.defaultTo(0n) // default value until the call resolves
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Related packages
|
|
129
|
+
|
|
130
|
+
| Package | Purpose |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| [`dappql`](https://www.npmjs.com/package/dappql) | Codegen CLI, generates the typed contract modules you import above |
|
|
133
|
+
| [`@dappql/async`](https://www.npmjs.com/package/@dappql/async) | Non-React runtime, same typed calls, no React required |
|
|
134
|
+
| [`@dappql/codegen`](https://www.npmjs.com/package/@dappql/codegen) | Framework-agnostic codegen engine |
|
|
135
|
+
| [`@dappql/mcp`](https://www.npmjs.com/package/@dappql/mcp) | MCP server, live contract context for AI coding agents |
|
|
136
|
+
|
|
137
|
+
## Full documentation
|
|
138
|
+
|
|
139
|
+
[github.com/dappql/core](https://github.com/dappql/core)
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|
package/dist/Mutation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mutation.d.ts","sourceRoot":"","sources":["../src/Mutation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,KAAK,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAGxD,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAEtD,iBAAS,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,SAAS,GAAG,EAAE,EAChE,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,MAAM,EAAE,YAAY,GAAG,SAAS,aAGd,IAAI,8KAYvB;AAED,iBAAS,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,SAAS,GAAG,EAAE,EAChE,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,MAAM,EAAE,YAAY,GAAG,SAAS,aAGd,IAAI,qBAYvB;AAED,iBAAS,uBAAuB,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,GAAG,SAAS;;;;;;;;;;;;;;;;;;;GAE/D;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB;IACE,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,GACD,MAAM,CAAA;AAEV;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,SAAS,GAAG,EAAE,EACvE,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAC/B,wBAAwB,CAAC,EAAE,eAAe,GACzC;IACD,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;IAChD,IAAI,EAAE,OAAO,GAAG,SAAS,CAAA;IACzB,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAA;IACpC,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAA;IAC5C,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAA;IACxD,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IAC7B,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;IACjD,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;CAClD,
|
|
1
|
+
{"version":3,"file":"Mutation.d.ts","sourceRoot":"","sources":["../src/Mutation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,KAAK,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAGxD,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAEtD,iBAAS,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,SAAS,GAAG,EAAE,EAChE,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,MAAM,EAAE,YAAY,GAAG,SAAS,aAGd,IAAI,8KAYvB;AAED,iBAAS,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,SAAS,GAAG,EAAE,EAChE,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,MAAM,EAAE,YAAY,GAAG,SAAS,aAGd,IAAI,qBAYvB;AAED,iBAAS,uBAAuB,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,GAAG,SAAS;;;;;;;;;;;;;;;;;;;GAE/D;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB;IACE,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,GACD,MAAM,CAAA;AAEV;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,SAAS,GAAG,EAAE,EACvE,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAC/B,wBAAwB,CAAC,EAAE,eAAe,GACzC;IACD,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;IAChD,IAAI,EAAE,OAAO,GAAG,SAAS,CAAA;IACzB,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAA;IACpC,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,sBAAsB,GAAG,IAAI,CAAA;IAC5C,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAA;IACxD,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IAC7B,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;IACjD,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;CAClD,CA2IA;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,SAAS,SAAS,GAAG,EAAE,IAAI,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA"}
|
package/dist/Mutation.js
CHANGED
|
@@ -49,7 +49,7 @@ function useMutationConfirmation(hash) {
|
|
|
49
49
|
*/
|
|
50
50
|
export function useMutation(config, optionsOrTransactionName) {
|
|
51
51
|
const { addressResolver, onMutationUpdate, simulateMutations } = useDappQL();
|
|
52
|
-
const { chain, address: account } = useAccount();
|
|
52
|
+
const { chain, address: account, connector } = useAccount();
|
|
53
53
|
const tx = useWriteContract();
|
|
54
54
|
const client = usePublicClient();
|
|
55
55
|
const address = useMemo(() => optionsOrTransactionName && typeof optionsOrTransactionName !== 'string' && optionsOrTransactionName.address
|
|
@@ -70,6 +70,16 @@ export function useMutation(config, optionsOrTransactionName) {
|
|
|
70
70
|
const send = useCallback((...args) => {
|
|
71
71
|
const now = Date.now();
|
|
72
72
|
const id = mutationInfo.address + mutationInfo.functionName + now.toString();
|
|
73
|
+
// Captured when the caller asks to send, and used for the write below.
|
|
74
|
+
//
|
|
75
|
+
// `writeContract` resolves the active connection inside its own mutation
|
|
76
|
+
// function, which runs after a yield — and after `simulate` below, which
|
|
77
|
+
// is awaited. A wallet event landing in either gap would otherwise sign
|
|
78
|
+
// with whoever is connected then, against arguments built and simulated
|
|
79
|
+
// for whoever was connected when the caller decided to send. Binding both
|
|
80
|
+
// makes wagmi fail that write instead of retargeting it.
|
|
81
|
+
const boundAccount = account;
|
|
82
|
+
const boundConnector = connector;
|
|
73
83
|
if (!account || !chain?.id) {
|
|
74
84
|
const error = !account ? 'No account connected' : 'Invalid chain';
|
|
75
85
|
onMutationUpdate?.({
|
|
@@ -88,6 +98,8 @@ export function useMutation(config, optionsOrTransactionName) {
|
|
|
88
98
|
address,
|
|
89
99
|
chainId: chain?.id,
|
|
90
100
|
args,
|
|
101
|
+
account: boundAccount,
|
|
102
|
+
connector: boundConnector,
|
|
91
103
|
}, {
|
|
92
104
|
onSettled(data, error) {
|
|
93
105
|
const status = error ? 'error' : 'signed';
|
|
@@ -124,7 +136,7 @@ export function useMutation(config, optionsOrTransactionName) {
|
|
|
124
136
|
else {
|
|
125
137
|
sendTx();
|
|
126
138
|
}
|
|
127
|
-
}, [address, tx, config, account, chain?.id, options?.simulate, simulateMutations, client, simulate]);
|
|
139
|
+
}, [address, tx, config, account, connector, chain?.id, options?.simulate, simulateMutations, client, simulate]);
|
|
128
140
|
const confirmation = useMutationConfirmation(tx.data);
|
|
129
141
|
return useMemo(() => ({
|
|
130
142
|
status: tx.status,
|
package/dist/blocksHandler.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export declare class BlockSubscriptionManager {
|
|
|
3
3
|
private subscribers;
|
|
4
4
|
private currentBlock;
|
|
5
5
|
subscribe(callback: Subscriber): () => boolean;
|
|
6
|
-
|
|
6
|
+
onBlockUpdated(newBlock: bigint): void;
|
|
7
7
|
}
|
|
8
8
|
export declare function useBlockNumberSubscriber(): (callback: Subscriber) => () => boolean;
|
|
9
9
|
export {};
|
package/dist/blocksHandler.js
CHANGED
|
@@ -13,7 +13,7 @@ export class BlockSubscriptionManager {
|
|
|
13
13
|
}
|
|
14
14
|
return () => this.subscribers.delete(callback);
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
onBlockUpdated(newBlock) {
|
|
17
17
|
this.currentBlock = newBlock;
|
|
18
18
|
this.subscribers.forEach((sub) => sub(newBlock));
|
|
19
19
|
}
|
|
@@ -24,7 +24,7 @@ export function useBlockNumberSubscriber() {
|
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
return client?.watchBlockNumber({
|
|
26
26
|
onBlockNumber: (blockNumber) => {
|
|
27
|
-
manager.
|
|
27
|
+
manager.onBlockUpdated(blockNumber);
|
|
28
28
|
},
|
|
29
29
|
});
|
|
30
30
|
}, [client, manager]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dappql/react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Streamlined smart contract data fetching library for React dApps with TypeScript support",
|
|
5
5
|
"author": "DappQL Team",
|
|
6
6
|
"type": "module",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
|
-
"url": "git+https://github.com/dappql/
|
|
31
|
+
"url": "git+https://github.com/dappql/core.git"
|
|
32
32
|
},
|
|
33
33
|
"bugs": {
|
|
34
|
-
"url": "https://github.com/dappql/
|
|
34
|
+
"url": "https://github.com/dappql/core/issues"
|
|
35
35
|
},
|
|
36
|
-
"homepage": "https://github.com/dappql/
|
|
36
|
+
"homepage": "https://github.com/dappql/core#readme",
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@tanstack/react-query": ">=5.0.0",
|