@octanejs/wagmi 0.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/LICENSE +21 -0
- package/README.md +84 -0
- package/package.json +58 -0
- package/src/chains.ts +1 -0
- package/src/connectors.ts +2 -0
- package/src/context.tsrx +42 -0
- package/src/context.tsrx.d.ts +11 -0
- package/src/hooks.ts +762 -0
- package/src/index.ts +54 -0
- package/src/internal.ts +21 -0
- package/src/security.ts +186 -0
- package/status.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dominic Gannaway
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @octanejs/wagmi
|
|
2
|
+
|
|
3
|
+
Wagmi v3 bindings for Octane. The package reuses `@wagmi/core`, Viem, and the
|
|
4
|
+
official connectors, while replacing the React provider and hooks with Octane
|
|
5
|
+
bindings backed by `@octanejs/tanstack-query`.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @octanejs/wagmi @octanejs/tanstack-query viem
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```tsrx
|
|
12
|
+
import { QueryClient, QueryClientProvider } from '@octanejs/tanstack-query';
|
|
13
|
+
import { WagmiProvider, createConfig, http, useConnect, useConnection } from '@octanejs/wagmi';
|
|
14
|
+
import { injected } from '@octanejs/wagmi/connectors';
|
|
15
|
+
import { mainnet } from '@octanejs/wagmi/chains';
|
|
16
|
+
|
|
17
|
+
const config = createConfig({
|
|
18
|
+
chains: [mainnet],
|
|
19
|
+
connectors: [injected()],
|
|
20
|
+
transports: { [mainnet.id]: http() },
|
|
21
|
+
});
|
|
22
|
+
const queryClient = new QueryClient();
|
|
23
|
+
|
|
24
|
+
function Wallet() @{
|
|
25
|
+
const connection = useConnection();
|
|
26
|
+
const connect = useConnect();
|
|
27
|
+
<button onClick={() => connect.connect({ connector: connect.connectors[0] })}>
|
|
28
|
+
{connection.address ?? 'Connect wallet'}
|
|
29
|
+
</button>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function App() @{
|
|
33
|
+
<WagmiProvider config={config}>
|
|
34
|
+
<QueryClientProvider client={queryClient}>
|
|
35
|
+
<Wallet />
|
|
36
|
+
</QueryClientProvider>
|
|
37
|
+
</WagmiProvider>
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Supported surface
|
|
42
|
+
|
|
43
|
+
The first compatibility slice includes config/provider access; connection,
|
|
44
|
+
connect, disconnect, switch-connection, and switch-chain; connector, connection,
|
|
45
|
+
and chain lists; balance; contract read, simulate, and write; transaction send
|
|
46
|
+
and receipt waiting; and message signing.
|
|
47
|
+
|
|
48
|
+
Wagmi v3 names are authoritative. Deprecated v2 aliases and all remaining hooks
|
|
49
|
+
are intentionally absent until they have behavioral evidence.
|
|
50
|
+
|
|
51
|
+
## Wallet-action safety
|
|
52
|
+
|
|
53
|
+
Signing, writing, sending, and wallet-switch prompts set `retry: false` even if a
|
|
54
|
+
shared QueryClient has a mutation retry default. They require a live connected
|
|
55
|
+
connector at dispatch. The binding snapshots the displayed address, chain, and
|
|
56
|
+
connector: replacement before dispatch yields `ActionContextChangedError` and
|
|
57
|
+
does not prompt; replacement after dispatch quarantines the late result in the
|
|
58
|
+
same typed error instead of publishing normal success.
|
|
59
|
+
|
|
60
|
+
Hydrated state is only an initial UI/cache hint. Use `parseHydratedState` for
|
|
61
|
+
untrusted cookie/SSR input: it is versioned, capped at 16 KiB, schema checked,
|
|
62
|
+
and rejects connector/provider/signature/token material. Privileged actions
|
|
63
|
+
always consult current live connector state.
|
|
64
|
+
|
|
65
|
+
EIP-1193 event validation, duplicate coalescing, and stale connector-generation
|
|
66
|
+
discarding remain `@wagmi/core` responsibilities. The Octane binding subscribes
|
|
67
|
+
to the core's normalized store; it does not intercept raw provider events or
|
|
68
|
+
claim a second normalization implementation.
|
|
69
|
+
|
|
70
|
+
## SSR
|
|
71
|
+
|
|
72
|
+
Set `ssr: true` on the Wagmi config and pass the validated state as
|
|
73
|
+
`initialState`. `WagmiProvider` follows Wagmi's split hydration contract:
|
|
74
|
+
non-SSR configs mount immediately, while SSR configs reconnect after hydration.
|
|
75
|
+
|
|
76
|
+
## RainbowKit compatibility gate
|
|
77
|
+
|
|
78
|
+
RainbowKit 2.2.x declares Wagmi v2 peers, but its defining
|
|
79
|
+
`RainbowKitProvider`, `ConnectButton.Custom`, and `useConnectModal` state can be
|
|
80
|
+
derived honestly from this v3 surface. The test suite proves the critical
|
|
81
|
+
disconnected → connecting → connected sequence with a deterministic connector.
|
|
82
|
+
The actual UI/modal implementation belongs to the stacked RainbowKit package.
|
|
83
|
+
|
|
84
|
+
No test needs a wallet secret, production RPC, or funded account.
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@octanejs/wagmi",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22"
|
|
8
|
+
},
|
|
9
|
+
"octane": {
|
|
10
|
+
"hookSlots": {
|
|
11
|
+
"manual": [
|
|
12
|
+
"src"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"description": "Wagmi v3 bindings for Octane over @wagmi/core and @octanejs/tanstack-query.",
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/octanejs/octane.git",
|
|
23
|
+
"directory": "packages/wagmi"
|
|
24
|
+
},
|
|
25
|
+
"main": "src/index.ts",
|
|
26
|
+
"module": "src/index.ts",
|
|
27
|
+
"types": "src/index.ts",
|
|
28
|
+
"files": [
|
|
29
|
+
"src",
|
|
30
|
+
"README.md",
|
|
31
|
+
"status.json"
|
|
32
|
+
],
|
|
33
|
+
"exports": {
|
|
34
|
+
".": "./src/index.ts",
|
|
35
|
+
"./connectors": "./src/connectors.ts",
|
|
36
|
+
"./chains": "./src/chains.ts"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@wagmi/connectors": "8.0.25",
|
|
40
|
+
"@wagmi/core": "3.6.4",
|
|
41
|
+
"viem": "2.55.10",
|
|
42
|
+
"@octanejs/tanstack-query": "0.1.20"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"octane": "0.1.21"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@tsrx/react": "^0.2.56",
|
|
49
|
+
"react": "^19.2.7",
|
|
50
|
+
"react-dom": "^19.2.7",
|
|
51
|
+
"vitest": "^4.1.10",
|
|
52
|
+
"wagmi": "3.7.4",
|
|
53
|
+
"octane": "0.1.21"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"test": "vitest run --root ../.. --project wagmi"
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/chains.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'viem/chains';
|
package/src/context.tsrx
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'octane';
|
|
2
|
+
import { hydrate, type ResolvedRegister, type State } from '@wagmi/core';
|
|
3
|
+
import type { OctaneNode } from 'octane';
|
|
4
|
+
import { WagmiContext } from './internal';
|
|
5
|
+
|
|
6
|
+
export type WagmiProviderProps = {
|
|
7
|
+
config: ResolvedRegister['config'];
|
|
8
|
+
initialState?: State;
|
|
9
|
+
reconnectOnMount?: boolean;
|
|
10
|
+
children?: OctaneNode;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type HydrationLifecycle = {
|
|
14
|
+
config: ResolvedRegister['config'];
|
|
15
|
+
onMount: () => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function WagmiProvider(props: WagmiProviderProps) @{
|
|
19
|
+
const reconnectOnMount = props.reconnectOnMount ?? true;
|
|
20
|
+
const lifecycleRef = useRef<HydrationLifecycle | null>(null);
|
|
21
|
+
let lifecycle = lifecycleRef.current;
|
|
22
|
+
|
|
23
|
+
if (!lifecycle || lifecycle.config !== props.config) {
|
|
24
|
+
const { onMount } = hydrate(props.config, {
|
|
25
|
+
initialState: props.initialState,
|
|
26
|
+
reconnectOnMount,
|
|
27
|
+
});
|
|
28
|
+
lifecycle = {
|
|
29
|
+
config: props.config,
|
|
30
|
+
onMount,
|
|
31
|
+
};
|
|
32
|
+
lifecycleRef.current = lifecycle;
|
|
33
|
+
if (!props.config._internal.ssr) onMount();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!lifecycle.config._internal.ssr) return;
|
|
38
|
+
lifecycle.onMount();
|
|
39
|
+
}, [lifecycle]);
|
|
40
|
+
|
|
41
|
+
<WagmiContext.Provider value={props.config}>{props.children}</WagmiContext.Provider>
|
|
42
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ResolvedRegister, State } from '@wagmi/core';
|
|
2
|
+
import type { OctaneNode } from 'octane';
|
|
3
|
+
|
|
4
|
+
export type WagmiProviderProps = {
|
|
5
|
+
config: ResolvedRegister['config'];
|
|
6
|
+
initialState?: State;
|
|
7
|
+
reconnectOnMount?: boolean;
|
|
8
|
+
children?: OctaneNode;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export declare function WagmiProvider(props: WagmiProviderProps): OctaneNode;
|
package/src/hooks.ts
ADDED
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
import { useCallback, useContext, useEffect, useRef, useSyncExternalStore } from 'octane';
|
|
2
|
+
import {
|
|
3
|
+
getChainId,
|
|
4
|
+
getChains,
|
|
5
|
+
getConnection,
|
|
6
|
+
getConnections,
|
|
7
|
+
getConnectors,
|
|
8
|
+
watchChainId,
|
|
9
|
+
watchConnection,
|
|
10
|
+
watchConnections,
|
|
11
|
+
watchConnectors,
|
|
12
|
+
type Config,
|
|
13
|
+
type ConnectErrorType,
|
|
14
|
+
type DisconnectErrorType,
|
|
15
|
+
type GetBalanceErrorType,
|
|
16
|
+
type ReadContractErrorType,
|
|
17
|
+
type SendTransactionErrorType,
|
|
18
|
+
type ResolvedRegister,
|
|
19
|
+
type SignMessageErrorType,
|
|
20
|
+
type SimulateContractErrorType,
|
|
21
|
+
type SwitchChainErrorType,
|
|
22
|
+
type SwitchConnectionErrorType,
|
|
23
|
+
type WaitForTransactionReceiptErrorType,
|
|
24
|
+
type WriteContractErrorType,
|
|
25
|
+
} from '@wagmi/core';
|
|
26
|
+
import { deepEqual, watchChains } from '@wagmi/core/internal';
|
|
27
|
+
import {
|
|
28
|
+
connectMutationOptions,
|
|
29
|
+
disconnectMutationOptions,
|
|
30
|
+
getBalanceQueryOptions,
|
|
31
|
+
readContractQueryOptions,
|
|
32
|
+
sendTransactionMutationOptions,
|
|
33
|
+
signMessageMutationOptions,
|
|
34
|
+
simulateContractQueryOptions,
|
|
35
|
+
switchChainMutationOptions,
|
|
36
|
+
switchConnectionMutationOptions,
|
|
37
|
+
waitForTransactionReceiptQueryOptions,
|
|
38
|
+
writeContractMutationOptions,
|
|
39
|
+
type ConnectData,
|
|
40
|
+
type ConnectMutate,
|
|
41
|
+
type ConnectMutateAsync,
|
|
42
|
+
type ConnectOptions,
|
|
43
|
+
type ConnectVariables,
|
|
44
|
+
type DisconnectData,
|
|
45
|
+
type DisconnectMutate,
|
|
46
|
+
type DisconnectMutateAsync,
|
|
47
|
+
type DisconnectOptions,
|
|
48
|
+
type DisconnectVariables,
|
|
49
|
+
type GetBalanceData,
|
|
50
|
+
type GetBalanceOptions,
|
|
51
|
+
type ReadContractData,
|
|
52
|
+
type ReadContractOptions,
|
|
53
|
+
type SendTransactionData,
|
|
54
|
+
type SendTransactionMutate,
|
|
55
|
+
type SendTransactionMutateAsync,
|
|
56
|
+
type SendTransactionOptions,
|
|
57
|
+
type SendTransactionVariables,
|
|
58
|
+
type SignMessageData,
|
|
59
|
+
type SignMessageMutate,
|
|
60
|
+
type SignMessageMutateAsync,
|
|
61
|
+
type SignMessageOptions,
|
|
62
|
+
type SignMessageVariables,
|
|
63
|
+
type SimulateContractData,
|
|
64
|
+
type SimulateContractOptions,
|
|
65
|
+
type SwitchChainData,
|
|
66
|
+
type SwitchChainMutate,
|
|
67
|
+
type SwitchChainMutateAsync,
|
|
68
|
+
type SwitchChainOptions,
|
|
69
|
+
type SwitchChainVariables,
|
|
70
|
+
type SwitchConnectionData,
|
|
71
|
+
type SwitchConnectionMutate,
|
|
72
|
+
type SwitchConnectionMutateAsync,
|
|
73
|
+
type SwitchConnectionOptions,
|
|
74
|
+
type SwitchConnectionVariables,
|
|
75
|
+
type WaitForTransactionReceiptData,
|
|
76
|
+
type WaitForTransactionReceiptOptions,
|
|
77
|
+
type WriteContractData,
|
|
78
|
+
type WriteContractMutate,
|
|
79
|
+
type WriteContractMutateAsync,
|
|
80
|
+
type WriteContractOptions,
|
|
81
|
+
type WriteContractVariables,
|
|
82
|
+
} from '@wagmi/core/query';
|
|
83
|
+
import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem';
|
|
84
|
+
import {
|
|
85
|
+
useMutation,
|
|
86
|
+
useQuery,
|
|
87
|
+
type UseMutationOptions,
|
|
88
|
+
type UseMutationResult,
|
|
89
|
+
type UseQueryOptions,
|
|
90
|
+
type UseQueryResult,
|
|
91
|
+
} from '@octanejs/tanstack-query';
|
|
92
|
+
import { WagmiContext, subSlot } from './internal';
|
|
93
|
+
import { secureMutationOptions } from './security';
|
|
94
|
+
|
|
95
|
+
type ParametersWithConfig<config extends Config = Config> = {
|
|
96
|
+
config?: config;
|
|
97
|
+
[key: string]: unknown;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const useMutationWithSlot = useMutation as unknown as <data, error, variables, context>(
|
|
101
|
+
options: UseMutationOptions<data, error, variables, context>,
|
|
102
|
+
queryClient: undefined,
|
|
103
|
+
slot: symbol | undefined,
|
|
104
|
+
) => UseMutationResult<data, error, variables, context>;
|
|
105
|
+
|
|
106
|
+
const useQueryWithSlot = useQuery as unknown as <queryData, error, data>(
|
|
107
|
+
options: UseQueryOptions<queryData, error, data>,
|
|
108
|
+
queryClient: undefined,
|
|
109
|
+
slot: symbol | undefined,
|
|
110
|
+
) => UseQueryResult<data, error>;
|
|
111
|
+
|
|
112
|
+
function useOctaneMutation<data, error, variables, context>(
|
|
113
|
+
options: UseMutationOptions<data, error, variables, context>,
|
|
114
|
+
slot: symbol | undefined,
|
|
115
|
+
): UseMutationResult<data, error, variables, context> {
|
|
116
|
+
return useMutationWithSlot(options, undefined, slot);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function useOctaneQuery<queryData, error, data>(
|
|
120
|
+
options: UseQueryOptions<queryData, error, data>,
|
|
121
|
+
slot: symbol | undefined,
|
|
122
|
+
): UseQueryResult<data, error> {
|
|
123
|
+
return useQueryWithSlot(options, undefined, slot);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function argumentsAndSlot(
|
|
127
|
+
parameters: ParametersWithConfig | symbol | undefined,
|
|
128
|
+
rest: unknown[],
|
|
129
|
+
): [ParametersWithConfig, symbol | undefined] {
|
|
130
|
+
if (typeof parameters === 'symbol') return [{}, parameters];
|
|
131
|
+
const tail = rest.at(-1);
|
|
132
|
+
return [parameters ?? {}, typeof tail === 'symbol' ? tail : undefined];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export class WagmiProviderNotFoundError extends Error {
|
|
136
|
+
override name = 'WagmiProviderNotFoundError';
|
|
137
|
+
constructor() {
|
|
138
|
+
super('`useConfig` must be used within `WagmiProvider` or receive a `config` option.');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function useConfig<config extends Config = ResolvedRegister['config']>(
|
|
143
|
+
parameters: { config?: config } | symbol = {},
|
|
144
|
+
): config {
|
|
145
|
+
const direct = typeof parameters === 'symbol' ? undefined : parameters.config;
|
|
146
|
+
const context = useContext(WagmiContext);
|
|
147
|
+
const config = direct ?? context;
|
|
148
|
+
if (!config) throw new WagmiProviderNotFoundError();
|
|
149
|
+
return config as config;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function useSnapshot<T>(
|
|
153
|
+
subscribe: (onChange: () => void) => () => void,
|
|
154
|
+
getSnapshot: () => T,
|
|
155
|
+
slot: symbol | undefined,
|
|
156
|
+
): T {
|
|
157
|
+
const cached = useRef<T | undefined>(undefined, subSlot(slot, 'cache'));
|
|
158
|
+
const stableSnapshot = () => {
|
|
159
|
+
const next = getSnapshot();
|
|
160
|
+
if (cached.current !== undefined && deepEqual(cached.current, next)) return cached.current;
|
|
161
|
+
cached.current = next;
|
|
162
|
+
return next;
|
|
163
|
+
};
|
|
164
|
+
return useSyncExternalStore(
|
|
165
|
+
subscribe,
|
|
166
|
+
stableSnapshot,
|
|
167
|
+
stableSnapshot,
|
|
168
|
+
subSlot(slot, 'external-store'),
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function useConnection<config extends Config = ResolvedRegister['config']>(
|
|
173
|
+
parameters: ParametersWithConfig<config> | symbol = {},
|
|
174
|
+
...rest: unknown[]
|
|
175
|
+
) {
|
|
176
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
177
|
+
const config = useConfig(options);
|
|
178
|
+
const subscribe = useCallback(
|
|
179
|
+
(onChange: () => void) => watchConnection(config, { onChange }),
|
|
180
|
+
[config],
|
|
181
|
+
subSlot(slot, 'subscribe'),
|
|
182
|
+
);
|
|
183
|
+
return useSnapshot(subscribe, () => getConnection(config), slot);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function useChainId<config extends Config = ResolvedRegister['config']>(
|
|
187
|
+
parameters: ParametersWithConfig<config> | symbol = {},
|
|
188
|
+
...rest: unknown[]
|
|
189
|
+
) {
|
|
190
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
191
|
+
const config = useConfig(options);
|
|
192
|
+
const subscribe = useCallback(
|
|
193
|
+
(onChange: () => void) => watchChainId(config, { onChange }),
|
|
194
|
+
[config],
|
|
195
|
+
subSlot(slot, 'subscribe'),
|
|
196
|
+
);
|
|
197
|
+
return useSnapshot(subscribe, () => getChainId(config), slot);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function useChains<config extends Config = ResolvedRegister['config']>(
|
|
201
|
+
parameters: ParametersWithConfig<config> | symbol = {},
|
|
202
|
+
...rest: unknown[]
|
|
203
|
+
) {
|
|
204
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
205
|
+
const config = useConfig(options);
|
|
206
|
+
const subscribe = useCallback(
|
|
207
|
+
(onChange: () => void) => watchChains(config, { onChange }),
|
|
208
|
+
[config],
|
|
209
|
+
subSlot(slot, 'subscribe'),
|
|
210
|
+
);
|
|
211
|
+
return useSnapshot(subscribe, () => getChains(config), slot);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function useConnectors<config extends Config = ResolvedRegister['config']>(
|
|
215
|
+
parameters: ParametersWithConfig<config> | symbol = {},
|
|
216
|
+
...rest: unknown[]
|
|
217
|
+
) {
|
|
218
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
219
|
+
const config = useConfig(options);
|
|
220
|
+
const subscribe = useCallback(
|
|
221
|
+
(onChange: () => void) => watchConnectors(config, { onChange }),
|
|
222
|
+
[config],
|
|
223
|
+
subSlot(slot, 'subscribe'),
|
|
224
|
+
);
|
|
225
|
+
return useSnapshot(subscribe, () => getConnectors(config), slot);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function useConnections(parameters: ParametersWithConfig | symbol = {}, ...rest: unknown[]) {
|
|
229
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
230
|
+
const config = useConfig(options);
|
|
231
|
+
const subscribe = useCallback(
|
|
232
|
+
(onChange: () => void) => watchConnections(config, { onChange }),
|
|
233
|
+
[config],
|
|
234
|
+
subSlot(slot, 'subscribe'),
|
|
235
|
+
);
|
|
236
|
+
return useSnapshot(subscribe, () => getConnections(config), slot);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function useFactoryMutation<data, error, variables, context>(
|
|
240
|
+
factory: (
|
|
241
|
+
config: Config,
|
|
242
|
+
parameters: ParametersWithConfig,
|
|
243
|
+
) => UseMutationOptions<data, error, variables, context>,
|
|
244
|
+
parameters: ParametersWithConfig | symbol | undefined,
|
|
245
|
+
rest: unknown[],
|
|
246
|
+
privileged = false,
|
|
247
|
+
securityAction: 'privileged' | 'switchChain' | 'switchConnection' = 'privileged',
|
|
248
|
+
): UseMutationResult<data, error, variables, context> {
|
|
249
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
250
|
+
const config = useConfig(options);
|
|
251
|
+
const mutationOptions = factory(config, options);
|
|
252
|
+
return useOctaneMutation(
|
|
253
|
+
privileged
|
|
254
|
+
? secureMutationOptions(config, mutationOptions, undefined, securityAction)
|
|
255
|
+
: mutationOptions,
|
|
256
|
+
subSlot(slot, 'mutation'),
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export type UseConnectParameters<
|
|
261
|
+
config extends Config = Config,
|
|
262
|
+
context = unknown,
|
|
263
|
+
> = ConnectOptions<config, context> & { config?: config };
|
|
264
|
+
|
|
265
|
+
export type UseConnectReturnType<config extends Config = Config, context = unknown> = Omit<
|
|
266
|
+
UseMutationResult<
|
|
267
|
+
ConnectData<config, config['connectors'][number], boolean>,
|
|
268
|
+
ConnectErrorType,
|
|
269
|
+
ConnectVariables<config, config['connectors'][number], boolean>,
|
|
270
|
+
context
|
|
271
|
+
>,
|
|
272
|
+
'mutate' | 'mutateAsync'
|
|
273
|
+
> & {
|
|
274
|
+
mutate: ConnectMutate<config, context>;
|
|
275
|
+
mutateAsync: ConnectMutateAsync<config, context>;
|
|
276
|
+
connect: ConnectMutate<config, context>;
|
|
277
|
+
connectAsync: ConnectMutateAsync<config, context>;
|
|
278
|
+
connectors: config['connectors'];
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export function useConnect<config extends Config = ResolvedRegister['config'], context = unknown>(
|
|
282
|
+
parameters?: UseConnectParameters<config, context> | symbol,
|
|
283
|
+
...rest: unknown[]
|
|
284
|
+
): UseConnectReturnType<config, context>;
|
|
285
|
+
export function useConnect(parameters: ParametersWithConfig | symbol = {}, ...rest: unknown[]) {
|
|
286
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
287
|
+
const config = useConfig(options);
|
|
288
|
+
const mutationOptions = connectMutationOptions(
|
|
289
|
+
config,
|
|
290
|
+
options as UseConnectParameters<typeof config>,
|
|
291
|
+
);
|
|
292
|
+
const mutation = useOctaneMutation(
|
|
293
|
+
{ ...mutationOptions, retry: false },
|
|
294
|
+
subSlot(slot, 'mutation'),
|
|
295
|
+
);
|
|
296
|
+
useEffect(
|
|
297
|
+
() =>
|
|
298
|
+
config.subscribe(
|
|
299
|
+
({ status }) => status,
|
|
300
|
+
(status, previous) => {
|
|
301
|
+
if (previous === 'connected' && status === 'disconnected') mutation.reset();
|
|
302
|
+
},
|
|
303
|
+
),
|
|
304
|
+
[config, mutation.reset],
|
|
305
|
+
subSlot(slot, 'reset'),
|
|
306
|
+
);
|
|
307
|
+
return {
|
|
308
|
+
...mutation,
|
|
309
|
+
connect: mutation.mutate,
|
|
310
|
+
connectAsync: mutation.mutateAsync,
|
|
311
|
+
connectors: useConnectors({ config }, subSlot(slot, 'connectors')),
|
|
312
|
+
} as UseConnectReturnType<typeof config>;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
type AliasedMutationResult<data, error, variables, context, mutate, mutateAsync> = Omit<
|
|
316
|
+
UseMutationResult<data, error, variables, context>,
|
|
317
|
+
'mutate' | 'mutateAsync'
|
|
318
|
+
> & {
|
|
319
|
+
mutate: mutate;
|
|
320
|
+
mutateAsync: mutateAsync;
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
export type UseDisconnectParameters<context = unknown> = DisconnectOptions<context> & {
|
|
324
|
+
config?: Config;
|
|
325
|
+
};
|
|
326
|
+
export type UseDisconnectReturnType<context = unknown> = AliasedMutationResult<
|
|
327
|
+
DisconnectData,
|
|
328
|
+
DisconnectErrorType,
|
|
329
|
+
DisconnectVariables,
|
|
330
|
+
context,
|
|
331
|
+
DisconnectMutate<context>,
|
|
332
|
+
DisconnectMutateAsync<context>
|
|
333
|
+
> & {
|
|
334
|
+
disconnect: DisconnectMutate<context>;
|
|
335
|
+
disconnectAsync: DisconnectMutateAsync<context>;
|
|
336
|
+
connectors: ReturnType<typeof useConnections>[number]['connector'][];
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
export function useDisconnect<context = unknown>(
|
|
340
|
+
parameters?: UseDisconnectParameters<context> | symbol,
|
|
341
|
+
...rest: unknown[]
|
|
342
|
+
): UseDisconnectReturnType<context>;
|
|
343
|
+
export function useDisconnect(parameters: ParametersWithConfig | symbol = {}, ...rest: unknown[]) {
|
|
344
|
+
const mutation = useFactoryMutation<
|
|
345
|
+
DisconnectData,
|
|
346
|
+
DisconnectErrorType,
|
|
347
|
+
DisconnectVariables,
|
|
348
|
+
unknown
|
|
349
|
+
>(
|
|
350
|
+
(config, options) => disconnectMutationOptions(config, options as DisconnectOptions<unknown>),
|
|
351
|
+
parameters,
|
|
352
|
+
rest,
|
|
353
|
+
);
|
|
354
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
355
|
+
const config = useConfig(options);
|
|
356
|
+
return {
|
|
357
|
+
...mutation,
|
|
358
|
+
disconnect: mutation.mutate,
|
|
359
|
+
disconnectAsync: mutation.mutateAsync,
|
|
360
|
+
connectors: useConnections({ config }, subSlot(slot, 'connections')).map(
|
|
361
|
+
(connection) => connection.connector,
|
|
362
|
+
),
|
|
363
|
+
} as UseDisconnectReturnType;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export type UseSwitchConnectionParameters<
|
|
367
|
+
config extends Config = Config,
|
|
368
|
+
context = unknown,
|
|
369
|
+
> = SwitchConnectionOptions<config, context> & { config?: config };
|
|
370
|
+
export type UseSwitchConnectionReturnType<
|
|
371
|
+
config extends Config = Config,
|
|
372
|
+
context = unknown,
|
|
373
|
+
> = AliasedMutationResult<
|
|
374
|
+
SwitchConnectionData<config>,
|
|
375
|
+
SwitchConnectionErrorType,
|
|
376
|
+
SwitchConnectionVariables,
|
|
377
|
+
context,
|
|
378
|
+
SwitchConnectionMutate<config, context>,
|
|
379
|
+
SwitchConnectionMutateAsync<config, context>
|
|
380
|
+
> & {
|
|
381
|
+
switchConnection: SwitchConnectionMutate<config, context>;
|
|
382
|
+
switchConnectionAsync: SwitchConnectionMutateAsync<config, context>;
|
|
383
|
+
connectors: ReturnType<typeof useConnections>[number]['connector'][];
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
export function useSwitchConnection<
|
|
387
|
+
config extends Config = ResolvedRegister['config'],
|
|
388
|
+
context = unknown,
|
|
389
|
+
>(
|
|
390
|
+
parameters?: UseSwitchConnectionParameters<config, context> | symbol,
|
|
391
|
+
...rest: unknown[]
|
|
392
|
+
): UseSwitchConnectionReturnType<config, context>;
|
|
393
|
+
export function useSwitchConnection(
|
|
394
|
+
parameters: ParametersWithConfig | symbol = {},
|
|
395
|
+
...rest: unknown[]
|
|
396
|
+
) {
|
|
397
|
+
const mutation = useFactoryMutation<
|
|
398
|
+
SwitchConnectionData<Config>,
|
|
399
|
+
SwitchConnectionErrorType,
|
|
400
|
+
SwitchConnectionVariables,
|
|
401
|
+
unknown
|
|
402
|
+
>(
|
|
403
|
+
(config, options) =>
|
|
404
|
+
switchConnectionMutationOptions(config, options as SwitchConnectionOptions<Config, unknown>),
|
|
405
|
+
parameters,
|
|
406
|
+
rest,
|
|
407
|
+
true,
|
|
408
|
+
'switchConnection',
|
|
409
|
+
);
|
|
410
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
411
|
+
const config = useConfig(options);
|
|
412
|
+
return {
|
|
413
|
+
...mutation,
|
|
414
|
+
switchConnection: mutation.mutate,
|
|
415
|
+
switchConnectionAsync: mutation.mutateAsync,
|
|
416
|
+
connectors: useConnections({ config }, subSlot(slot, 'connections')).map(
|
|
417
|
+
(connection) => connection.connector,
|
|
418
|
+
),
|
|
419
|
+
} as UseSwitchConnectionReturnType;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
export type UseSwitchChainParameters<
|
|
423
|
+
config extends Config = Config,
|
|
424
|
+
context = unknown,
|
|
425
|
+
> = SwitchChainOptions<config, context> & { config?: config };
|
|
426
|
+
export type UseSwitchChainReturnType<
|
|
427
|
+
config extends Config = Config,
|
|
428
|
+
context = unknown,
|
|
429
|
+
> = AliasedMutationResult<
|
|
430
|
+
SwitchChainData<config, config['chains'][number]['id']>,
|
|
431
|
+
SwitchChainErrorType,
|
|
432
|
+
SwitchChainVariables<config, config['chains'][number]['id']>,
|
|
433
|
+
context,
|
|
434
|
+
SwitchChainMutate<config, context>,
|
|
435
|
+
SwitchChainMutateAsync<config, context>
|
|
436
|
+
> & {
|
|
437
|
+
switchChain: SwitchChainMutate<config, context>;
|
|
438
|
+
switchChainAsync: SwitchChainMutateAsync<config, context>;
|
|
439
|
+
chains: config['chains'];
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
export function useSwitchChain<
|
|
443
|
+
config extends Config = ResolvedRegister['config'],
|
|
444
|
+
context = unknown,
|
|
445
|
+
>(
|
|
446
|
+
parameters?: UseSwitchChainParameters<config, context> | symbol,
|
|
447
|
+
...rest: unknown[]
|
|
448
|
+
): UseSwitchChainReturnType<config, context>;
|
|
449
|
+
export function useSwitchChain(parameters: ParametersWithConfig | symbol = {}, ...rest: unknown[]) {
|
|
450
|
+
const mutation = useFactoryMutation<
|
|
451
|
+
SwitchChainData<Config, Config['chains'][number]['id']>,
|
|
452
|
+
SwitchChainErrorType,
|
|
453
|
+
SwitchChainVariables<Config, Config['chains'][number]['id']>,
|
|
454
|
+
unknown
|
|
455
|
+
>(
|
|
456
|
+
(config, options) =>
|
|
457
|
+
switchChainMutationOptions(config, options as SwitchChainOptions<Config, unknown>),
|
|
458
|
+
parameters,
|
|
459
|
+
rest,
|
|
460
|
+
true,
|
|
461
|
+
'switchChain',
|
|
462
|
+
);
|
|
463
|
+
const [options, slot] = argumentsAndSlot(parameters, rest);
|
|
464
|
+
const config = useConfig(options);
|
|
465
|
+
return {
|
|
466
|
+
...mutation,
|
|
467
|
+
switchChain: mutation.mutate,
|
|
468
|
+
switchChainAsync: mutation.mutateAsync,
|
|
469
|
+
chains: useChains({ config }, subSlot(slot, 'chains')),
|
|
470
|
+
} as UseSwitchChainReturnType;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function useCoreQuery(
|
|
474
|
+
factory: unknown,
|
|
475
|
+
parameters: ParametersWithConfig | symbol | undefined,
|
|
476
|
+
rest: unknown[],
|
|
477
|
+
options: { account?: boolean; chain?: boolean } = {},
|
|
478
|
+
) {
|
|
479
|
+
const [input, slot] = argumentsAndSlot(parameters, rest);
|
|
480
|
+
const config = useConfig(input);
|
|
481
|
+
const chainId = useChainId({ config }, subSlot(slot, 'chain'));
|
|
482
|
+
const connection = options.account
|
|
483
|
+
? useConnection({ config }, subSlot(slot, 'connection'))
|
|
484
|
+
: undefined;
|
|
485
|
+
const queryOptions = (
|
|
486
|
+
factory as (
|
|
487
|
+
config: Config,
|
|
488
|
+
parameters: ParametersWithConfig,
|
|
489
|
+
) => UseQueryOptions<unknown, unknown, unknown>
|
|
490
|
+
)(config, {
|
|
491
|
+
...input,
|
|
492
|
+
...(options.account
|
|
493
|
+
? {
|
|
494
|
+
account: input.account ?? connection?.address,
|
|
495
|
+
connector: input.connector ?? connection?.connector,
|
|
496
|
+
}
|
|
497
|
+
: {}),
|
|
498
|
+
...(options.chain ? { chainId: input.chainId ?? chainId } : {}),
|
|
499
|
+
});
|
|
500
|
+
return useOctaneQuery(queryOptions, subSlot(slot, 'query'));
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
export type UseBalanceParameters<
|
|
504
|
+
config extends Config = Config,
|
|
505
|
+
selectData = GetBalanceData,
|
|
506
|
+
> = GetBalanceOptions<config, selectData> & { config?: config };
|
|
507
|
+
export type UseBalanceReturnType<selectData = GetBalanceData> = UseQueryResult<
|
|
508
|
+
selectData,
|
|
509
|
+
GetBalanceErrorType
|
|
510
|
+
>;
|
|
511
|
+
|
|
512
|
+
export function useBalance<
|
|
513
|
+
config extends Config = ResolvedRegister['config'],
|
|
514
|
+
selectData = GetBalanceData,
|
|
515
|
+
>(
|
|
516
|
+
parameters?: UseBalanceParameters<config, selectData> | symbol,
|
|
517
|
+
...rest: unknown[]
|
|
518
|
+
): UseBalanceReturnType<selectData>;
|
|
519
|
+
export function useBalance(parameters: ParametersWithConfig | symbol = {}, ...rest: unknown[]) {
|
|
520
|
+
return useCoreQuery(getBalanceQueryOptions, parameters, rest, { chain: true });
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export type UseReadContractParameters<
|
|
524
|
+
abi extends Abi | readonly unknown[] = Abi,
|
|
525
|
+
functionName extends ContractFunctionName<abi, 'pure' | 'view'> = ContractFunctionName<
|
|
526
|
+
abi,
|
|
527
|
+
'pure' | 'view'
|
|
528
|
+
>,
|
|
529
|
+
args extends ContractFunctionArgs<abi, 'pure' | 'view', functionName> = ContractFunctionArgs<
|
|
530
|
+
abi,
|
|
531
|
+
'pure' | 'view',
|
|
532
|
+
functionName
|
|
533
|
+
>,
|
|
534
|
+
config extends Config = Config,
|
|
535
|
+
selectData = ReadContractData<abi, functionName, args>,
|
|
536
|
+
> = ReadContractOptions<abi, functionName, args, config, selectData> & { config?: config };
|
|
537
|
+
export type UseReadContractReturnType<
|
|
538
|
+
abi extends Abi | readonly unknown[],
|
|
539
|
+
functionName extends ContractFunctionName<abi, 'pure' | 'view'>,
|
|
540
|
+
args extends ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
|
|
541
|
+
selectData = ReadContractData<abi, functionName, args>,
|
|
542
|
+
> = UseQueryResult<selectData, ReadContractErrorType>;
|
|
543
|
+
|
|
544
|
+
export function useReadContract<
|
|
545
|
+
const abi extends Abi | readonly unknown[],
|
|
546
|
+
functionName extends ContractFunctionName<abi, 'pure' | 'view'>,
|
|
547
|
+
const args extends ContractFunctionArgs<abi, 'pure' | 'view', functionName>,
|
|
548
|
+
config extends Config = ResolvedRegister['config'],
|
|
549
|
+
selectData = ReadContractData<abi, functionName, args>,
|
|
550
|
+
>(
|
|
551
|
+
parameters?: UseReadContractParameters<abi, functionName, args, config, selectData> | symbol,
|
|
552
|
+
...rest: unknown[]
|
|
553
|
+
): UseReadContractReturnType<abi, functionName, args, selectData>;
|
|
554
|
+
export function useReadContract(
|
|
555
|
+
parameters: ParametersWithConfig | symbol = {},
|
|
556
|
+
...rest: unknown[]
|
|
557
|
+
) {
|
|
558
|
+
return useCoreQuery(readContractQueryOptions, parameters, rest, { chain: true });
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export type UseSimulateContractParameters<
|
|
562
|
+
abi extends Abi | readonly unknown[] = Abi,
|
|
563
|
+
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'> = ContractFunctionName<
|
|
564
|
+
abi,
|
|
565
|
+
'nonpayable' | 'payable'
|
|
566
|
+
>,
|
|
567
|
+
args extends ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName> =
|
|
568
|
+
ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
|
|
569
|
+
config extends Config = Config,
|
|
570
|
+
chainId extends config['chains'][number]['id'] | undefined = config['chains'][number]['id'],
|
|
571
|
+
selectData = SimulateContractData<abi, functionName, args, config, chainId>,
|
|
572
|
+
> = SimulateContractOptions<abi, functionName, args, config, chainId, selectData> & {
|
|
573
|
+
config?: config;
|
|
574
|
+
};
|
|
575
|
+
export type UseSimulateContractReturnType<
|
|
576
|
+
abi extends Abi | readonly unknown[],
|
|
577
|
+
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
|
|
578
|
+
args extends ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
|
|
579
|
+
config extends Config,
|
|
580
|
+
chainId extends config['chains'][number]['id'] | undefined,
|
|
581
|
+
selectData = SimulateContractData<abi, functionName, args, config, chainId>,
|
|
582
|
+
> = UseQueryResult<selectData, SimulateContractErrorType>;
|
|
583
|
+
|
|
584
|
+
export function useSimulateContract<
|
|
585
|
+
const abi extends Abi | readonly unknown[],
|
|
586
|
+
functionName extends ContractFunctionName<abi, 'nonpayable' | 'payable'>,
|
|
587
|
+
const args extends ContractFunctionArgs<abi, 'nonpayable' | 'payable', functionName>,
|
|
588
|
+
config extends Config = ResolvedRegister['config'],
|
|
589
|
+
chainId extends config['chains'][number]['id'] | undefined = config['chains'][number]['id'],
|
|
590
|
+
selectData = SimulateContractData<abi, functionName, args, config, chainId>,
|
|
591
|
+
>(
|
|
592
|
+
parameters?:
|
|
593
|
+
UseSimulateContractParameters<abi, functionName, args, config, chainId, selectData> | symbol,
|
|
594
|
+
...rest: unknown[]
|
|
595
|
+
): UseSimulateContractReturnType<abi, functionName, args, config, chainId, selectData>;
|
|
596
|
+
export function useSimulateContract(
|
|
597
|
+
parameters: ParametersWithConfig | symbol = {},
|
|
598
|
+
...rest: unknown[]
|
|
599
|
+
) {
|
|
600
|
+
return useCoreQuery(simulateContractQueryOptions, parameters, rest, {
|
|
601
|
+
account: true,
|
|
602
|
+
chain: true,
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
export type UseWaitForTransactionReceiptParameters<
|
|
607
|
+
config extends Config = Config,
|
|
608
|
+
chainId extends config['chains'][number]['id'] = config['chains'][number]['id'],
|
|
609
|
+
selectData = WaitForTransactionReceiptData<config, chainId>,
|
|
610
|
+
> = WaitForTransactionReceiptOptions<config, chainId, selectData> & { config?: config };
|
|
611
|
+
export type UseWaitForTransactionReceiptReturnType<selectData> = UseQueryResult<
|
|
612
|
+
selectData,
|
|
613
|
+
WaitForTransactionReceiptErrorType
|
|
614
|
+
>;
|
|
615
|
+
|
|
616
|
+
export function useWaitForTransactionReceipt<
|
|
617
|
+
config extends Config = ResolvedRegister['config'],
|
|
618
|
+
chainId extends config['chains'][number]['id'] = config['chains'][number]['id'],
|
|
619
|
+
selectData = WaitForTransactionReceiptData<config, chainId>,
|
|
620
|
+
>(
|
|
621
|
+
parameters?: UseWaitForTransactionReceiptParameters<config, chainId, selectData> | symbol,
|
|
622
|
+
...rest: unknown[]
|
|
623
|
+
): UseWaitForTransactionReceiptReturnType<selectData>;
|
|
624
|
+
export function useWaitForTransactionReceipt(
|
|
625
|
+
parameters: ParametersWithConfig | symbol = {},
|
|
626
|
+
...rest: unknown[]
|
|
627
|
+
) {
|
|
628
|
+
return useCoreQuery(waitForTransactionReceiptQueryOptions, parameters, rest, { chain: true });
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export type UseWriteContractParameters<
|
|
632
|
+
config extends Config = Config,
|
|
633
|
+
context = unknown,
|
|
634
|
+
> = WriteContractOptions<config, context> & { config?: config };
|
|
635
|
+
export type UseWriteContractReturnType<
|
|
636
|
+
config extends Config = Config,
|
|
637
|
+
context = unknown,
|
|
638
|
+
> = AliasedMutationResult<
|
|
639
|
+
WriteContractData,
|
|
640
|
+
WriteContractErrorType,
|
|
641
|
+
WriteContractVariables<Abi, string, readonly unknown[], config, config['chains'][number]['id']>,
|
|
642
|
+
context,
|
|
643
|
+
WriteContractMutate<config, context>,
|
|
644
|
+
WriteContractMutateAsync<config, context>
|
|
645
|
+
> & {
|
|
646
|
+
writeContract: WriteContractMutate<config, context>;
|
|
647
|
+
writeContractAsync: WriteContractMutateAsync<config, context>;
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
export function useWriteContract<
|
|
651
|
+
config extends Config = ResolvedRegister['config'],
|
|
652
|
+
context = unknown,
|
|
653
|
+
>(
|
|
654
|
+
parameters?: UseWriteContractParameters<config, context> | symbol,
|
|
655
|
+
...rest: unknown[]
|
|
656
|
+
): UseWriteContractReturnType<config, context>;
|
|
657
|
+
export function useWriteContract(
|
|
658
|
+
parameters: ParametersWithConfig | symbol = {},
|
|
659
|
+
...rest: unknown[]
|
|
660
|
+
) {
|
|
661
|
+
const mutation = useFactoryMutation<
|
|
662
|
+
WriteContractData,
|
|
663
|
+
WriteContractErrorType,
|
|
664
|
+
WriteContractVariables<Abi, string, readonly unknown[], Config, Config['chains'][number]['id']>,
|
|
665
|
+
unknown
|
|
666
|
+
>(
|
|
667
|
+
(config, options) =>
|
|
668
|
+
writeContractMutationOptions(config, options as WriteContractOptions<Config, unknown>),
|
|
669
|
+
parameters,
|
|
670
|
+
rest,
|
|
671
|
+
true,
|
|
672
|
+
);
|
|
673
|
+
return {
|
|
674
|
+
...mutation,
|
|
675
|
+
writeContract: mutation.mutate,
|
|
676
|
+
writeContractAsync: mutation.mutateAsync,
|
|
677
|
+
} as UseWriteContractReturnType;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
export type UseSendTransactionParameters<
|
|
681
|
+
config extends Config = Config,
|
|
682
|
+
context = unknown,
|
|
683
|
+
> = SendTransactionOptions<config, context> & { config?: config };
|
|
684
|
+
export type UseSendTransactionReturnType<
|
|
685
|
+
config extends Config = Config,
|
|
686
|
+
context = unknown,
|
|
687
|
+
> = AliasedMutationResult<
|
|
688
|
+
SendTransactionData,
|
|
689
|
+
SendTransactionErrorType,
|
|
690
|
+
SendTransactionVariables<config, config['chains'][number]['id']>,
|
|
691
|
+
context,
|
|
692
|
+
SendTransactionMutate<config, context>,
|
|
693
|
+
SendTransactionMutateAsync<config, context>
|
|
694
|
+
> & {
|
|
695
|
+
sendTransaction: SendTransactionMutate<config, context>;
|
|
696
|
+
sendTransactionAsync: SendTransactionMutateAsync<config, context>;
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
export function useSendTransaction<
|
|
700
|
+
config extends Config = ResolvedRegister['config'],
|
|
701
|
+
context = unknown,
|
|
702
|
+
>(
|
|
703
|
+
parameters?: UseSendTransactionParameters<config, context> | symbol,
|
|
704
|
+
...rest: unknown[]
|
|
705
|
+
): UseSendTransactionReturnType<config, context>;
|
|
706
|
+
export function useSendTransaction(
|
|
707
|
+
parameters: ParametersWithConfig | symbol = {},
|
|
708
|
+
...rest: unknown[]
|
|
709
|
+
) {
|
|
710
|
+
const mutation = useFactoryMutation<
|
|
711
|
+
SendTransactionData,
|
|
712
|
+
SendTransactionErrorType,
|
|
713
|
+
SendTransactionVariables<Config, Config['chains'][number]['id']>,
|
|
714
|
+
unknown
|
|
715
|
+
>(
|
|
716
|
+
(config, options) =>
|
|
717
|
+
sendTransactionMutationOptions(config, options as SendTransactionOptions<Config, unknown>),
|
|
718
|
+
parameters,
|
|
719
|
+
rest,
|
|
720
|
+
true,
|
|
721
|
+
);
|
|
722
|
+
return {
|
|
723
|
+
...mutation,
|
|
724
|
+
sendTransaction: mutation.mutate,
|
|
725
|
+
sendTransactionAsync: mutation.mutateAsync,
|
|
726
|
+
} as UseSendTransactionReturnType;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
export type UseSignMessageParameters<context = unknown> = SignMessageOptions<context> & {
|
|
730
|
+
config?: Config;
|
|
731
|
+
};
|
|
732
|
+
export type UseSignMessageReturnType<context = unknown> = Omit<
|
|
733
|
+
UseMutationResult<SignMessageData, SignMessageErrorType, SignMessageVariables, context>,
|
|
734
|
+
'mutate' | 'mutateAsync'
|
|
735
|
+
> & {
|
|
736
|
+
mutate: SignMessageMutate<context>;
|
|
737
|
+
mutateAsync: SignMessageMutateAsync<context>;
|
|
738
|
+
signMessage: SignMessageMutate<context>;
|
|
739
|
+
signMessageAsync: SignMessageMutateAsync<context>;
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
export function useSignMessage<context = unknown>(
|
|
743
|
+
parameters: UseSignMessageParameters<context> | symbol = {},
|
|
744
|
+
...rest: unknown[]
|
|
745
|
+
): UseSignMessageReturnType<context> {
|
|
746
|
+
const mutation = useFactoryMutation<
|
|
747
|
+
SignMessageData,
|
|
748
|
+
SignMessageErrorType,
|
|
749
|
+
SignMessageVariables,
|
|
750
|
+
unknown
|
|
751
|
+
>(
|
|
752
|
+
(config, options) => signMessageMutationOptions(config, options as SignMessageOptions<context>),
|
|
753
|
+
parameters as ParametersWithConfig | symbol,
|
|
754
|
+
rest,
|
|
755
|
+
true,
|
|
756
|
+
);
|
|
757
|
+
return {
|
|
758
|
+
...mutation,
|
|
759
|
+
signMessage: mutation.mutate,
|
|
760
|
+
signMessageAsync: mutation.mutateAsync,
|
|
761
|
+
} as UseSignMessageReturnType<context>;
|
|
762
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export * from '@wagmi/core';
|
|
2
|
+
export { WagmiContext } from './internal';
|
|
3
|
+
export { WagmiProvider, type WagmiProviderProps } from './context.tsrx';
|
|
4
|
+
export {
|
|
5
|
+
WagmiProviderNotFoundError,
|
|
6
|
+
type UseBalanceParameters,
|
|
7
|
+
type UseBalanceReturnType,
|
|
8
|
+
type UseConnectParameters,
|
|
9
|
+
type UseConnectReturnType,
|
|
10
|
+
type UseDisconnectParameters,
|
|
11
|
+
type UseDisconnectReturnType,
|
|
12
|
+
type UseReadContractParameters,
|
|
13
|
+
type UseReadContractReturnType,
|
|
14
|
+
type UseSendTransactionParameters,
|
|
15
|
+
type UseSendTransactionReturnType,
|
|
16
|
+
type UseSignMessageParameters,
|
|
17
|
+
type UseSignMessageReturnType,
|
|
18
|
+
type UseSimulateContractParameters,
|
|
19
|
+
type UseSimulateContractReturnType,
|
|
20
|
+
type UseSwitchChainParameters,
|
|
21
|
+
type UseSwitchChainReturnType,
|
|
22
|
+
type UseSwitchConnectionParameters,
|
|
23
|
+
type UseSwitchConnectionReturnType,
|
|
24
|
+
type UseWaitForTransactionReceiptParameters,
|
|
25
|
+
type UseWaitForTransactionReceiptReturnType,
|
|
26
|
+
type UseWriteContractParameters,
|
|
27
|
+
type UseWriteContractReturnType,
|
|
28
|
+
useBalance,
|
|
29
|
+
useChainId,
|
|
30
|
+
useChains,
|
|
31
|
+
useConfig,
|
|
32
|
+
useConnect,
|
|
33
|
+
useConnection,
|
|
34
|
+
useConnections,
|
|
35
|
+
useConnectors,
|
|
36
|
+
useDisconnect,
|
|
37
|
+
useReadContract,
|
|
38
|
+
useSendTransaction,
|
|
39
|
+
useSignMessage,
|
|
40
|
+
useSimulateContract,
|
|
41
|
+
useSwitchChain,
|
|
42
|
+
useSwitchConnection,
|
|
43
|
+
useWaitForTransactionReceipt,
|
|
44
|
+
useWriteContract,
|
|
45
|
+
} from './hooks';
|
|
46
|
+
export {
|
|
47
|
+
HYDRATION_VERSION,
|
|
48
|
+
MAX_HYDRATION_BYTES,
|
|
49
|
+
parseHydratedState,
|
|
50
|
+
secureMutationOptions,
|
|
51
|
+
serializeHydratedState,
|
|
52
|
+
ActionContextChangedError,
|
|
53
|
+
LiveConnectionRequiredError,
|
|
54
|
+
} from './security';
|
package/src/internal.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createContext } from 'octane';
|
|
2
|
+
import type { ResolvedRegister } from '@wagmi/core';
|
|
3
|
+
|
|
4
|
+
export const WagmiContext = createContext<ResolvedRegister['config'] | undefined>(undefined);
|
|
5
|
+
|
|
6
|
+
const slots = new Map<symbol, Map<string, symbol>>();
|
|
7
|
+
|
|
8
|
+
export function subSlot(slot: symbol | undefined, tag: string): symbol | undefined {
|
|
9
|
+
if (!slot) return undefined;
|
|
10
|
+
let children = slots.get(slot);
|
|
11
|
+
if (!children) {
|
|
12
|
+
children = new Map();
|
|
13
|
+
slots.set(slot, children);
|
|
14
|
+
}
|
|
15
|
+
let child = children.get(tag);
|
|
16
|
+
if (!child) {
|
|
17
|
+
child = Symbol.for(`${slot.description ?? ''}:${tag}`);
|
|
18
|
+
children.set(tag, child);
|
|
19
|
+
}
|
|
20
|
+
return child;
|
|
21
|
+
}
|
package/src/security.ts
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import type { State } from '@wagmi/core';
|
|
2
|
+
import { getChainId, getConnection, type Config } from '@wagmi/core';
|
|
3
|
+
|
|
4
|
+
export const HYDRATION_VERSION = 1;
|
|
5
|
+
export const MAX_HYDRATION_BYTES = 16_384;
|
|
6
|
+
|
|
7
|
+
export class LiveConnectionRequiredError extends Error {
|
|
8
|
+
override name = 'LiveConnectionRequiredError';
|
|
9
|
+
constructor() {
|
|
10
|
+
super('A current live connector is required for this privileged action.');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class ActionContextChangedError extends Error {
|
|
15
|
+
override name = 'ActionContextChangedError';
|
|
16
|
+
readonly phase: 'before-dispatch' | 'after-dispatch';
|
|
17
|
+
constructor(phase: 'before-dispatch' | 'after-dispatch') {
|
|
18
|
+
super(
|
|
19
|
+
phase === 'before-dispatch'
|
|
20
|
+
? 'Wallet context changed before dispatch; the action was cancelled.'
|
|
21
|
+
: 'Wallet context changed after dispatch; the result is indeterminate and quarantined.',
|
|
22
|
+
);
|
|
23
|
+
this.phase = phase;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type SecureMutationAction = 'privileged' | 'switchChain' | 'switchConnection';
|
|
28
|
+
|
|
29
|
+
function actionContext(config: Config) {
|
|
30
|
+
const connection = getConnection(config);
|
|
31
|
+
return {
|
|
32
|
+
address: connection.address,
|
|
33
|
+
chainId: connection.status === 'connected' ? connection.chainId : getChainId(config),
|
|
34
|
+
connector: connection.connector?.uid,
|
|
35
|
+
status: connection.status,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function sameContext(a: ReturnType<typeof actionContext>, b: ReturnType<typeof actionContext>) {
|
|
40
|
+
return (
|
|
41
|
+
a.address === b.address &&
|
|
42
|
+
a.chainId === b.chainId &&
|
|
43
|
+
a.connector === b.connector &&
|
|
44
|
+
a.status === b.status
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function sameIdentity(a: ReturnType<typeof actionContext>, b: ReturnType<typeof actionContext>) {
|
|
49
|
+
return a.address === b.address && a.connector === b.connector && a.status === b.status;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function variableRecord(value: unknown): Record<string, any> {
|
|
53
|
+
return isRecord(value) ? value : {};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function connectorUid(value: unknown): string | undefined {
|
|
57
|
+
return isRecord(value) && typeof value.uid === 'string' ? value.uid : undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function accountAddress(value: unknown): string | undefined {
|
|
61
|
+
if (typeof value === 'string') return value;
|
|
62
|
+
return isRecord(value) && typeof value.address === 'string' ? value.address : undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function sameAddress(a: string | undefined, b: string | undefined) {
|
|
66
|
+
return a?.toLowerCase() === b?.toLowerCase();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function variablesMatchLiveContext(
|
|
70
|
+
variables: unknown,
|
|
71
|
+
context: ReturnType<typeof actionContext>,
|
|
72
|
+
action: SecureMutationAction,
|
|
73
|
+
) {
|
|
74
|
+
const input = variableRecord(variables);
|
|
75
|
+
if (action !== 'switchConnection' && 'connector' in input) {
|
|
76
|
+
if (connectorUid(input.connector) !== context.connector) return false;
|
|
77
|
+
}
|
|
78
|
+
if ('account' in input && !sameAddress(accountAddress(input.account), context.address))
|
|
79
|
+
return false;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function validPostDispatchContext(
|
|
84
|
+
action: SecureMutationAction,
|
|
85
|
+
before: ReturnType<typeof actionContext>,
|
|
86
|
+
after: ReturnType<typeof actionContext>,
|
|
87
|
+
variables: unknown,
|
|
88
|
+
result: unknown,
|
|
89
|
+
) {
|
|
90
|
+
if (action === 'privileged') return sameContext(before, after);
|
|
91
|
+
if (action === 'switchChain') {
|
|
92
|
+
const chainId = variableRecord(variables).chainId;
|
|
93
|
+
return sameIdentity(before, after) && after.chainId === chainId;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const targetUid = connectorUid(variableRecord(variables).connector);
|
|
97
|
+
const returned = variableRecord(result);
|
|
98
|
+
const returnedAddress = Array.isArray(returned.accounts) ? returned.accounts[0] : undefined;
|
|
99
|
+
return (
|
|
100
|
+
after.status === 'connected' &&
|
|
101
|
+
after.connector === targetUid &&
|
|
102
|
+
(typeof returned.chainId !== 'number' || after.chainId === returned.chainId) &&
|
|
103
|
+
(typeof returnedAddress !== 'string' || sameAddress(after.address, returnedAddress))
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Hardens a Wagmi mutation option object without retrying wallet prompts.
|
|
109
|
+
* Late success is deliberately converted to a typed quarantined error.
|
|
110
|
+
*/
|
|
111
|
+
export function secureMutationOptions(
|
|
112
|
+
config: Config,
|
|
113
|
+
options: Record<string, any>,
|
|
114
|
+
displayed = actionContext(config),
|
|
115
|
+
action: SecureMutationAction = 'privileged',
|
|
116
|
+
) {
|
|
117
|
+
const mutationFn = options.mutationFn;
|
|
118
|
+
if (typeof mutationFn !== 'function') return { ...options, retry: false };
|
|
119
|
+
return {
|
|
120
|
+
...options,
|
|
121
|
+
retry: false,
|
|
122
|
+
async mutationFn(variables: unknown) {
|
|
123
|
+
const before = actionContext(config);
|
|
124
|
+
const disconnectedLocalSwitch =
|
|
125
|
+
action === 'switchChain' &&
|
|
126
|
+
before.status === 'disconnected' &&
|
|
127
|
+
!before.connector &&
|
|
128
|
+
!('connector' in variableRecord(variables));
|
|
129
|
+
if (!disconnectedLocalSwitch && (before.status !== 'connected' || !before.connector))
|
|
130
|
+
throw new LiveConnectionRequiredError();
|
|
131
|
+
if (!sameContext(displayed, before)) throw new ActionContextChangedError('before-dispatch');
|
|
132
|
+
if (!variablesMatchLiveContext(variables, before, action))
|
|
133
|
+
throw new ActionContextChangedError('before-dispatch');
|
|
134
|
+
const result = await mutationFn(variables);
|
|
135
|
+
if (!validPostDispatchContext(action, before, actionContext(config), variables, result))
|
|
136
|
+
throw new ActionContextChangedError('after-dispatch');
|
|
137
|
+
return result;
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
143
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function isSafeState(value: unknown): value is State {
|
|
147
|
+
if (!isRecord(value)) return false;
|
|
148
|
+
if (!['connected', 'connecting', 'disconnected', 'reconnecting'].includes(String(value.status)))
|
|
149
|
+
return false;
|
|
150
|
+
if (!Array.isArray(value.connections) && !(value.connections instanceof Map)) return false;
|
|
151
|
+
if (typeof value.chainId !== 'number' || !Number.isSafeInteger(value.chainId)) return false;
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Parse an untrusted SSR/cookie hint. Connector and provider objects are never accepted. */
|
|
156
|
+
export function parseHydratedState(input: string): State | undefined {
|
|
157
|
+
if (new TextEncoder().encode(input).byteLength > MAX_HYDRATION_BYTES) return undefined;
|
|
158
|
+
try {
|
|
159
|
+
const envelope: unknown = JSON.parse(input);
|
|
160
|
+
if (!isRecord(envelope) || envelope.version !== HYDRATION_VERSION) return undefined;
|
|
161
|
+
if (!isSafeState(envelope.state)) return undefined;
|
|
162
|
+
const state = envelope.state as unknown as Record<string, unknown>;
|
|
163
|
+
if ('connector' in state || 'provider' in state || 'signature' in state || 'token' in state)
|
|
164
|
+
return undefined;
|
|
165
|
+
return {
|
|
166
|
+
...(envelope.state as State),
|
|
167
|
+
// Untrusted JSON cannot carry live connector instances. Connections are
|
|
168
|
+
// deliberately rebuilt by Wagmi reconnect rather than trusted here.
|
|
169
|
+
connections: new Map(),
|
|
170
|
+
current: null,
|
|
171
|
+
status: 'disconnected',
|
|
172
|
+
};
|
|
173
|
+
} catch {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function serializeHydratedState(state: State): string | undefined {
|
|
179
|
+
const connections = state.connections instanceof Map ? [] : state.connections;
|
|
180
|
+
const safe = {
|
|
181
|
+
version: HYDRATION_VERSION,
|
|
182
|
+
state: { chainId: state.chainId, connections, current: state.current, status: state.status },
|
|
183
|
+
};
|
|
184
|
+
const value = JSON.stringify(safe);
|
|
185
|
+
return new TextEncoder().encode(value).byteLength <= MAX_HYDRATION_BYTES ? value : undefined;
|
|
186
|
+
}
|
package/status.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"upstream": {
|
|
3
|
+
"package": "wagmi",
|
|
4
|
+
"version": "3.7.4"
|
|
5
|
+
},
|
|
6
|
+
"surface": "WagmiProvider and createConfig over @wagmi/core 3.6.4, with config, connection, connect, disconnect, switch-connection, switch-chain, connectors, connections, chains, balance, contract read/simulate/write, transaction send/wait, and message-signing hooks.",
|
|
7
|
+
"divergences": [
|
|
8
|
+
"The binding targets Wagmi v3 names. Deprecated v2 useAccount/useSwitchAccount aliases and hooks outside the documented representative inventory are not exported.",
|
|
9
|
+
"Privileged mutation hooks force retry:false, require a current live connector, cancel before dispatch when the displayed wallet context changed, and quarantine a late success as ActionContextChangedError when account, chain, or connector changed after dispatch.",
|
|
10
|
+
"RainbowKit 2.2.x declares Wagmi v2 peers. Its defining provider/custom-button/modal contracts can be implemented over this v3 surface, proven by the deterministic disconnected-to-connecting-to-connected gate, but the downstream binding must document that peer-range divergence.",
|
|
11
|
+
"The connectors subpath exposes the dependency-free injected and deterministic mock connectors. Vendor connectors and their optional SDKs remain direct application dependencies.",
|
|
12
|
+
"EIP-1193 event validation, duplicate coalescing, and connector-generation invalidation are delegated unchanged to @wagmi/core 3.6.4. This binding does not add a second provider-event layer or claim independent normalization behavior."
|
|
13
|
+
],
|
|
14
|
+
"ssr": "WagmiProvider supports ssr:true and initialState through @wagmi/core hydrate. parseHydratedState accepts only a versioned, 16 KiB-bounded public-state hint and rejects malformed or privileged material; a hydrated connection is never authority for signing or submission.",
|
|
15
|
+
"verified": "2026-07-29",
|
|
16
|
+
"provenance": {
|
|
17
|
+
"source": "https://github.com/wevm/wagmi",
|
|
18
|
+
"license": "MIT"
|
|
19
|
+
},
|
|
20
|
+
"supportedExports": [
|
|
21
|
+
"createConfig",
|
|
22
|
+
"WagmiProvider",
|
|
23
|
+
"useConfig",
|
|
24
|
+
"useConnection",
|
|
25
|
+
"useConnect",
|
|
26
|
+
"useDisconnect",
|
|
27
|
+
"useSwitchConnection",
|
|
28
|
+
"useSwitchChain",
|
|
29
|
+
"useConnectors",
|
|
30
|
+
"useConnections",
|
|
31
|
+
"useChains",
|
|
32
|
+
"useBalance",
|
|
33
|
+
"useReadContract",
|
|
34
|
+
"useSimulateContract",
|
|
35
|
+
"useWriteContract",
|
|
36
|
+
"useSendTransaction",
|
|
37
|
+
"useWaitForTransactionReceipt",
|
|
38
|
+
"useSignMessage"
|
|
39
|
+
],
|
|
40
|
+
"unsupported": [
|
|
41
|
+
"deprecated Wagmi v2 aliases",
|
|
42
|
+
"connector-specific React UI",
|
|
43
|
+
"all Wagmi hooks not named in supportedExports",
|
|
44
|
+
"automatic signing or submission retry"
|
|
45
|
+
]
|
|
46
|
+
}
|