@near-kit/react 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,385 @@
1
+ # @near-kit/react
2
+
3
+ React bindings for [near-kit](https://github.com/r-near/near-kit) — a simple, intuitive TypeScript library for interacting with NEAR Protocol.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @near-kit/react near-kit
9
+ # or
10
+ bun add @near-kit/react near-kit
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```tsx
16
+ import { NearProvider, useNear, useView, useCall } from "@near-kit/react"
17
+
18
+ function App() {
19
+ return (
20
+ <NearProvider config={{ network: "testnet" }}>
21
+ <Counter />
22
+ </NearProvider>
23
+ )
24
+ }
25
+
26
+ function Counter() {
27
+ const { data: count, isLoading } = useView<{}, number>({
28
+ contractId: "counter.testnet",
29
+ method: "get_count",
30
+ })
31
+
32
+ const { mutate: increment, isPending } = useCall({
33
+ contractId: "counter.testnet",
34
+ method: "increment",
35
+ })
36
+
37
+ if (isLoading) return <div>Loading...</div>
38
+
39
+ return (
40
+ <button onClick={() => increment({})} disabled={isPending}>
41
+ Count: {count}
42
+ </button>
43
+ )
44
+ }
45
+ ```
46
+
47
+ ## Philosophy
48
+
49
+ This package provides **thin, ergonomic wrappers** around `near-kit`. The hooks handle basic React state (loading, error, data) without reimplementing caching, deduplication, or advanced features.
50
+
51
+ **For simple apps:** Use the built-in hooks directly.
52
+
53
+ **For advanced use cases:** Use `useNear()` with [React Query](#react-query-integration) or [SWR](#swr-integration) for caching, polling, optimistic updates, and more.
54
+
55
+ ## API Reference
56
+
57
+ ### Provider & Context
58
+
59
+ #### `<NearProvider>`
60
+
61
+ Provides a `Near` client to all child components.
62
+
63
+ ```tsx
64
+ // Option 1: Pass configuration (creates Near instance internally)
65
+ <NearProvider config={{ network: "testnet" }}>
66
+ <App />
67
+ </NearProvider>
68
+
69
+ // Option 2: Pass an existing Near instance
70
+ const near = new Near({ network: "testnet", privateKey: "..." })
71
+ <NearProvider near={near}>
72
+ <App />
73
+ </NearProvider>
74
+ ```
75
+
76
+ #### `useNear()`
77
+
78
+ Returns the `Near` client from context. Use this for direct access or integration with React Query/SWR.
79
+
80
+ ```tsx
81
+ function MyComponent() {
82
+ const near = useNear()
83
+ // near.view(), near.call(), near.send(), near.transaction(), etc.
84
+ }
85
+ ```
86
+
87
+ ### View Hooks
88
+
89
+ #### `useView<TArgs, TResult>(params)`
90
+
91
+ Calls a view method on a contract.
92
+
93
+ ```tsx
94
+ const { data, isLoading, error, refetch } = useView<{ account_id: string }, string>({
95
+ contractId: "token.testnet",
96
+ method: "ft_balance_of",
97
+ args: { account_id: "alice.testnet" },
98
+ enabled: true, // optional, default: true
99
+ })
100
+ ```
101
+
102
+ #### `useBalance(params)`
103
+
104
+ Fetches an account's NEAR balance.
105
+
106
+ ```tsx
107
+ const { data: balance, isLoading } = useBalance({
108
+ accountId: "alice.testnet",
109
+ })
110
+ ```
111
+
112
+ #### `useAccountExists(params)`
113
+
114
+ Checks if an account exists.
115
+
116
+ ```tsx
117
+ const { data: exists } = useAccountExists({
118
+ accountId: "alice.testnet",
119
+ })
120
+ ```
121
+
122
+ ### Mutation Hooks
123
+
124
+ #### `useCall<TArgs, TResult>(params)`
125
+
126
+ Calls a change method on a contract.
127
+
128
+ ```tsx
129
+ const { mutate, data, isPending, isSuccess, isError, error, reset } = useCall<
130
+ { amount: number },
131
+ void
132
+ >({
133
+ contractId: "counter.testnet",
134
+ method: "increment",
135
+ options: { gas: "30 Tgas" }, // optional defaults
136
+ })
137
+
138
+ // Execute the call
139
+ await mutate({ amount: 1 })
140
+
141
+ // Override options per-call
142
+ await mutate({ amount: 1 }, { attachedDeposit: "0.1 NEAR" })
143
+ ```
144
+
145
+ #### `useSend()`
146
+
147
+ Sends NEAR tokens.
148
+
149
+ ```tsx
150
+ const { mutate: send, isPending, isSuccess, isError, error, reset } = useSend()
151
+
152
+ await send("bob.testnet", "1 NEAR")
153
+ ```
154
+
155
+ ### Account Hook
156
+
157
+ #### `useAccount()`
158
+
159
+ Returns the current connected account state.
160
+
161
+ ```tsx
162
+ const { accountId, isConnected, isLoading, refetch } = useAccount()
163
+ ```
164
+
165
+ ### Typed Contract Hook
166
+
167
+ #### `useContract<T>(contractId)`
168
+
169
+ Returns a typed contract instance for full TypeScript inference.
170
+
171
+ ```tsx
172
+ import type { Contract } from "near-kit"
173
+
174
+ type MyContract = Contract<{
175
+ view: {
176
+ get_balance: (args: { account_id: string }) => Promise<string>
177
+ }
178
+ call: {
179
+ transfer: (args: { to: string; amount: string }) => Promise<void>
180
+ }
181
+ }>
182
+
183
+ function TokenBalance() {
184
+ const contract = useContract<MyContract>("token.testnet")
185
+
186
+ // Fully typed!
187
+ const balance = await contract.view.get_balance({ account_id: "..." })
188
+ }
189
+ ```
190
+
191
+ ## React Query Integration
192
+
193
+ For caching, polling, background refetching, and devtools, use React Query with `useNear()`:
194
+
195
+ ```tsx
196
+ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"
197
+ import { useNear } from "@near-kit/react"
198
+
199
+ function useContractView<TArgs extends object, TResult>(
200
+ contractId: string,
201
+ method: string,
202
+ args: TArgs
203
+ ) {
204
+ const near = useNear()
205
+
206
+ return useQuery({
207
+ queryKey: ["near", "view", contractId, method, args],
208
+ queryFn: () => near.view<TResult>(contractId, method, args),
209
+ })
210
+ }
211
+
212
+ function useContractCall<TArgs extends object, TResult>(
213
+ contractId: string,
214
+ method: string
215
+ ) {
216
+ const near = useNear()
217
+ const queryClient = useQueryClient()
218
+
219
+ return useMutation({
220
+ mutationFn: (args: TArgs) => near.call<TResult>(contractId, method, args),
221
+ onSuccess: () => {
222
+ // Invalidate relevant queries after mutation
223
+ queryClient.invalidateQueries({ queryKey: ["near", "view", contractId] })
224
+ },
225
+ })
226
+ }
227
+
228
+ // Usage
229
+ function Counter() {
230
+ const { data: count, isLoading } = useContractView<{}, number>(
231
+ "counter.testnet",
232
+ "get_count",
233
+ {}
234
+ )
235
+
236
+ const { mutate: increment } = useContractCall<{}, void>(
237
+ "counter.testnet",
238
+ "increment"
239
+ )
240
+
241
+ return (
242
+ <button onClick={() => increment({})}>
243
+ Count: {isLoading ? "..." : count}
244
+ </button>
245
+ )
246
+ }
247
+ ```
248
+
249
+ ### With Polling
250
+
251
+ ```tsx
252
+ const { data: balance } = useQuery({
253
+ queryKey: ["near", "balance", accountId],
254
+ queryFn: () => near.getBalance(accountId),
255
+ refetchInterval: 5000, // Poll every 5 seconds
256
+ })
257
+ ```
258
+
259
+ ## SWR Integration
260
+
261
+ For a lighter alternative, use SWR with `useNear()`:
262
+
263
+ ```tsx
264
+ import useSWR from "swr"
265
+ import useSWRMutation from "swr/mutation"
266
+ import { useNear } from "@near-kit/react"
267
+
268
+ function useContractView<TArgs extends object, TResult>(
269
+ contractId: string,
270
+ method: string,
271
+ args: TArgs
272
+ ) {
273
+ const near = useNear()
274
+ const key = ["near", "view", contractId, method, JSON.stringify(args)]
275
+
276
+ return useSWR(key, () => near.view<TResult>(contractId, method, args))
277
+ }
278
+
279
+ function useContractCall<TArgs extends object, TResult>(
280
+ contractId: string,
281
+ method: string
282
+ ) {
283
+ const near = useNear()
284
+ const key = ["near", "call", contractId, method]
285
+
286
+ return useSWRMutation(key, (_key, { arg }: { arg: TArgs }) =>
287
+ near.call<TResult>(contractId, method, arg)
288
+ )
289
+ }
290
+
291
+ // Usage
292
+ function Counter() {
293
+ const { data: count, isLoading } = useContractView<{}, number>(
294
+ "counter.testnet",
295
+ "get_count",
296
+ {}
297
+ )
298
+
299
+ const { trigger: increment, isMutating } = useContractCall<{}, void>(
300
+ "counter.testnet",
301
+ "increment"
302
+ )
303
+
304
+ return (
305
+ <button onClick={() => increment({})} disabled={isMutating}>
306
+ Count: {isLoading ? "..." : count}
307
+ </button>
308
+ )
309
+ }
310
+ ```
311
+
312
+ ### With Polling
313
+
314
+ ```tsx
315
+ const { data: balance } = useSWR(
316
+ ["near", "balance", accountId],
317
+ () => near.getBalance(accountId),
318
+ { refreshInterval: 5000 }
319
+ )
320
+ ```
321
+
322
+ ## Wallet Integration
323
+
324
+ ### With Wallet Selector
325
+
326
+ ```tsx
327
+ import { setupWalletSelector } from "@near-wallet-selector/core"
328
+ import { fromWalletSelector } from "near-kit"
329
+
330
+ const selector = await setupWalletSelector({
331
+ network: "testnet",
332
+ modules: [/* your wallet modules */],
333
+ })
334
+ const wallet = await selector.wallet()
335
+
336
+ <NearProvider
337
+ config={{
338
+ network: "testnet",
339
+ wallet: fromWalletSelector(wallet),
340
+ }}
341
+ >
342
+ <App />
343
+ </NearProvider>
344
+ ```
345
+
346
+ ### With HOT Connect
347
+
348
+ ```tsx
349
+ import { setupNearConnect } from "@hot-labs/near-connect"
350
+ import { fromHotConnect } from "near-kit"
351
+
352
+ const connect = await setupNearConnect({ network: "testnet" })
353
+
354
+ <NearProvider
355
+ config={{
356
+ network: "testnet",
357
+ wallet: fromHotConnect(connect),
358
+ }}
359
+ >
360
+ <App />
361
+ </NearProvider>
362
+ ```
363
+
364
+ ## SSR / Next.js
365
+
366
+ This package is marked with `"use client"` and is designed for client-side use only. In Next.js App Router, wrap the provider in a client component:
367
+
368
+ ```tsx
369
+ // app/providers.tsx
370
+ "use client"
371
+
372
+ import { NearProvider } from "@near-kit/react"
373
+
374
+ export function Providers({ children }: { children: React.ReactNode }) {
375
+ return (
376
+ <NearProvider config={{ network: "testnet" }}>
377
+ {children}
378
+ </NearProvider>
379
+ )
380
+ }
381
+ ```
382
+
383
+ ## License
384
+
385
+ MIT
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Account state returned by useAccount
3
+ */
4
+ export interface AccountState {
5
+ /** The connected account ID, if any */
6
+ accountId: string | undefined;
7
+ /** Whether any account is connected */
8
+ isConnected: boolean;
9
+ /** Whether the account state is still being fetched */
10
+ isLoading: boolean;
11
+ /** Function to refresh the account state */
12
+ refetch: () => Promise<void>;
13
+ }
14
+ /**
15
+ * Hook to get the current account state.
16
+ *
17
+ * Derives state from whichever signer/wallet was passed to the Near client
18
+ * (via wallet, privateKey, keyStore, etc.).
19
+ *
20
+ * Note: This hook accesses internal Near client state which may change between versions.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * function Header() {
25
+ * const { accountId, isConnected, isLoading } = useAccount()
26
+ *
27
+ * if (isLoading) return <>Loading...</>
28
+ * if (!isConnected) return <>Not connected</>
29
+ * return <>Connected as {accountId}</>
30
+ * }
31
+ * ```
32
+ */
33
+ export declare function useAccount(): AccountState;
34
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../src/account.tsx"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,uCAAuC;IACvC,WAAW,EAAE,OAAO,CAAA;IACpB,uDAAuD;IACvD,SAAS,EAAE,OAAO,CAAA;IAClB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAuDzC"}
@@ -0,0 +1,69 @@
1
+ "use client";
2
+ import { useCallback, useEffect, useState } from "react";
3
+ import { useNear } from "./provider.js";
4
+ /**
5
+ * Hook to get the current account state.
6
+ *
7
+ * Derives state from whichever signer/wallet was passed to the Near client
8
+ * (via wallet, privateKey, keyStore, etc.).
9
+ *
10
+ * Note: This hook accesses internal Near client state which may change between versions.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * function Header() {
15
+ * const { accountId, isConnected, isLoading } = useAccount()
16
+ *
17
+ * if (isLoading) return <>Loading...</>
18
+ * if (!isConnected) return <>Not connected</>
19
+ * return <>Connected as {accountId}</>
20
+ * }
21
+ * ```
22
+ */
23
+ export function useAccount() {
24
+ const near = useNear();
25
+ const [accountId, setAccountId] = useState(undefined);
26
+ const [isLoading, setIsLoading] = useState(true);
27
+ const fetchAccount = useCallback(async () => {
28
+ setIsLoading(true);
29
+ try {
30
+ // Access internal wallet/signer state via type assertion
31
+ // This is intentionally coupling to Near internals
32
+ const nearInternal = near;
33
+ // First, check if there's a wallet connection
34
+ if (nearInternal.wallet) {
35
+ const accounts = await nearInternal.wallet.getAccounts();
36
+ const firstAccount = accounts[0];
37
+ if (firstAccount) {
38
+ setAccountId(firstAccount.accountId);
39
+ setIsLoading(false);
40
+ return;
41
+ }
42
+ }
43
+ // Fall back to default signer ID if set
44
+ if (nearInternal.defaultSignerId) {
45
+ setAccountId(nearInternal.defaultSignerId);
46
+ setIsLoading(false);
47
+ return;
48
+ }
49
+ // No account found
50
+ setAccountId(undefined);
51
+ }
52
+ catch {
53
+ setAccountId(undefined);
54
+ }
55
+ finally {
56
+ setIsLoading(false);
57
+ }
58
+ }, [near]);
59
+ useEffect(() => {
60
+ void fetchAccount();
61
+ }, [fetchAccount]);
62
+ return {
63
+ accountId,
64
+ isConnected: accountId !== undefined,
65
+ isLoading,
66
+ refetch: fetchAccount,
67
+ };
68
+ }
69
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAgBvC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IAEtB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAqB,SAAS,CAAC,CAAA;IACzE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAEhD,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1C,YAAY,CAAC,IAAI,CAAC,CAAA;QAClB,IAAI,CAAC;YACH,yDAAyD;YACzD,mDAAmD;YACnD,MAAM,YAAY,GAAG,IAKpB,CAAA;YAED,8CAA8C;YAC9C,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,WAAW,EAAE,CAAA;gBACxD,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;gBAChC,IAAI,YAAY,EAAE,CAAC;oBACjB,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;oBACpC,YAAY,CAAC,KAAK,CAAC,CAAA;oBACnB,OAAM;gBACR,CAAC;YACH,CAAC;YAED,wCAAwC;YACxC,IAAI,YAAY,CAAC,eAAe,EAAE,CAAC;gBACjC,YAAY,CAAC,YAAY,CAAC,eAAe,CAAC,CAAA;gBAC1C,YAAY,CAAC,KAAK,CAAC,CAAA;gBACnB,OAAM;YACR,CAAC;YAED,mBAAmB;YACnB,YAAY,CAAC,SAAS,CAAC,CAAA;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,SAAS,CAAC,CAAA;QACzB,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,YAAY,EAAE,CAAA;IACrB,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAA;IAElB,OAAO;QACL,SAAS;QACT,WAAW,EAAE,SAAS,KAAK,SAAS;QACpC,SAAS;QACT,OAAO,EAAE,YAAY;KACtB,CAAA;AACH,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { ContractMethods } from "near-kit";
2
+ /**
3
+ * Hook to get a typed contract instance.
4
+ *
5
+ * This provides full TypeScript inference for contract methods.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import type { Contract } from "near-kit"
10
+ *
11
+ * type MyContract = Contract<{
12
+ * view: {
13
+ * get_balance: (args: { account_id: string }) => Promise<string>
14
+ * }
15
+ * call: {
16
+ * transfer: (args: { to: string; amount: string }) => Promise<void>
17
+ * }
18
+ * }>
19
+ *
20
+ * function WalletBalance() {
21
+ * const contract = useContract<MyContract>("token.testnet")
22
+ *
23
+ * // Fully typed!
24
+ * const balance = await contract.view.get_balance({ account_id: "..." })
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function useContract<T extends ContractMethods>(contractId: string): T;
29
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,CAG5E"}
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { useNear } from "./provider.js";
3
+ /**
4
+ * Hook to get a typed contract instance.
5
+ *
6
+ * This provides full TypeScript inference for contract methods.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import type { Contract } from "near-kit"
11
+ *
12
+ * type MyContract = Contract<{
13
+ * view: {
14
+ * get_balance: (args: { account_id: string }) => Promise<string>
15
+ * }
16
+ * call: {
17
+ * transfer: (args: { to: string; amount: string }) => Promise<void>
18
+ * }
19
+ * }>
20
+ *
21
+ * function WalletBalance() {
22
+ * const contract = useContract<MyContract>("token.testnet")
23
+ *
24
+ * // Fully typed!
25
+ * const balance = await contract.view.get_balance({ account_id: "..." })
26
+ * }
27
+ * ```
28
+ */
29
+ export function useContract(contractId) {
30
+ const near = useNear();
31
+ return near.contract(contractId);
32
+ }
33
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAGZ,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,WAAW,CAA4B,UAAkB;IACvE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,OAAO,IAAI,CAAC,QAAQ,CAAI,UAAU,CAAC,CAAA;AACrC,CAAC"}
@@ -0,0 +1,96 @@
1
+ import type { NearError } from "near-kit";
2
+ /**
3
+ * Result shape for view hooks
4
+ */
5
+ export interface ViewResult<T> {
6
+ /** The data returned from the view call */
7
+ data: T | undefined;
8
+ /** Any error that occurred */
9
+ error: NearError | Error | undefined;
10
+ /** Whether the view call is in progress */
11
+ isLoading: boolean;
12
+ /** Manually trigger a refetch */
13
+ refetch: () => Promise<void>;
14
+ }
15
+ /**
16
+ * Parameters for useView hook
17
+ */
18
+ export interface UseViewParams<TArgs extends object = object> {
19
+ /** Contract account ID */
20
+ contractId: string;
21
+ /** View method name */
22
+ method: string;
23
+ /** Arguments to pass to the method */
24
+ args?: TArgs;
25
+ /** Whether the query is enabled (default: true) */
26
+ enabled?: boolean;
27
+ }
28
+ /**
29
+ * Hook for calling view functions on NEAR contracts.
30
+ *
31
+ * This is a thin wrapper around `near.view()` that provides React state management.
32
+ * For advanced features like caching, polling, or deduplication, use React Query or SWR
33
+ * with the `useNear()` hook directly.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * function Counter() {
38
+ * const { data: count, isLoading, error, refetch } = useView<{}, number>({
39
+ * contractId: "counter.testnet",
40
+ * method: "get_count",
41
+ * })
42
+ *
43
+ * if (isLoading) return <div>Loading...</div>
44
+ * if (error) return <div>Error: {error.message}</div>
45
+ * return <div>Count: {count}</div>
46
+ * }
47
+ * ```
48
+ */
49
+ export declare function useView<TArgs extends object = object, TResult = unknown>(params: UseViewParams<TArgs>): ViewResult<TResult>;
50
+ /**
51
+ * Parameters for useBalance hook
52
+ */
53
+ export interface UseBalanceParams {
54
+ /** Account ID to check balance for */
55
+ accountId: string;
56
+ /** Whether the query is enabled (default: true) */
57
+ enabled?: boolean;
58
+ }
59
+ /**
60
+ * Hook for fetching an account's NEAR balance.
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * function Balance({ accountId }: { accountId: string }) {
65
+ * const { data: balance, isLoading } = useBalance({ accountId })
66
+ *
67
+ * if (isLoading) return <div>Loading...</div>
68
+ * return <div>Balance: {balance}</div>
69
+ * }
70
+ * ```
71
+ */
72
+ export declare function useBalance(params: UseBalanceParams): ViewResult<string>;
73
+ /**
74
+ * Parameters for useAccountExists hook
75
+ */
76
+ export interface UseAccountExistsParams {
77
+ /** Account ID to check */
78
+ accountId: string;
79
+ /** Whether the query is enabled (default: true) */
80
+ enabled?: boolean;
81
+ }
82
+ /**
83
+ * Hook for checking if a NEAR account exists.
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * function AccountCheck({ accountId }: { accountId: string }) {
88
+ * const { data: exists, isLoading } = useAccountExists({ accountId })
89
+ *
90
+ * if (isLoading) return <div>Checking...</div>
91
+ * return <div>{exists ? "Account exists" : "Account not found"}</div>
92
+ * }
93
+ * ```
94
+ */
95
+ export declare function useAccountExists(params: UseAccountExistsParams): ViewResult<boolean>;
96
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAIzC;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,2CAA2C;IAC3C,IAAI,EAAE,CAAC,GAAG,SAAS,CAAA;IACnB,8BAA8B;IAC9B,KAAK,EAAE,SAAS,GAAG,KAAK,GAAG,SAAS,CAAA;IACpC,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAA;IAClB,iCAAiC;IACjC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IAC1D,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,sCAAsC;IACtC,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,OAAO,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,GAAG,OAAO,EACtE,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,GAC3B,UAAU,CAAC,OAAO,CAAC,CAsDrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,CAuCvE;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,sBAAsB,GAC7B,UAAU,CAAC,OAAO,CAAC,CAuCrB"}
package/dist/hooks.js ADDED
@@ -0,0 +1,171 @@
1
+ "use client";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { useNear } from "./provider.js";
4
+ /**
5
+ * Hook for calling view functions on NEAR contracts.
6
+ *
7
+ * This is a thin wrapper around `near.view()` that provides React state management.
8
+ * For advanced features like caching, polling, or deduplication, use React Query or SWR
9
+ * with the `useNear()` hook directly.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * function Counter() {
14
+ * const { data: count, isLoading, error, refetch } = useView<{}, number>({
15
+ * contractId: "counter.testnet",
16
+ * method: "get_count",
17
+ * })
18
+ *
19
+ * if (isLoading) return <div>Loading...</div>
20
+ * if (error) return <div>Error: {error.message}</div>
21
+ * return <div>Count: {count}</div>
22
+ * }
23
+ * ```
24
+ */
25
+ export function useView(params) {
26
+ const { contractId, method, args, enabled = true } = params;
27
+ const near = useNear();
28
+ const [data, setData] = useState(undefined);
29
+ const [error, setError] = useState(undefined);
30
+ const [isLoading, setIsLoading] = useState(enabled);
31
+ // Serialize args for dependency comparison
32
+ const argsKey = JSON.stringify(args ?? {});
33
+ // Track current request to ignore stale responses
34
+ const requestIdRef = useRef(0);
35
+ // Store args in a ref to avoid dependency issues
36
+ const argsRef = useRef(args);
37
+ argsRef.current = args;
38
+ // biome-ignore lint/correctness/useExhaustiveDependencies: argsKey intentionally triggers refetch when args change
39
+ const fetchData = useCallback(async () => {
40
+ if (!enabled) {
41
+ setIsLoading(false);
42
+ return;
43
+ }
44
+ const currentRequestId = ++requestIdRef.current;
45
+ setIsLoading(true);
46
+ setError(undefined);
47
+ try {
48
+ const result = await near.view(contractId, method, argsRef.current ?? {});
49
+ // Ignore if a newer request has started
50
+ if (currentRequestId !== requestIdRef.current)
51
+ return;
52
+ setData(result);
53
+ }
54
+ catch (err) {
55
+ // Ignore if a newer request has started
56
+ if (currentRequestId !== requestIdRef.current)
57
+ return;
58
+ setError(err instanceof Error ? err : new Error(String(err)));
59
+ }
60
+ finally {
61
+ if (currentRequestId === requestIdRef.current) {
62
+ setIsLoading(false);
63
+ }
64
+ }
65
+ }, [near, contractId, method, argsKey, enabled]);
66
+ useEffect(() => {
67
+ void fetchData();
68
+ }, [fetchData]);
69
+ return { data, error, isLoading, refetch: fetchData };
70
+ }
71
+ /**
72
+ * Hook for fetching an account's NEAR balance.
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * function Balance({ accountId }: { accountId: string }) {
77
+ * const { data: balance, isLoading } = useBalance({ accountId })
78
+ *
79
+ * if (isLoading) return <div>Loading...</div>
80
+ * return <div>Balance: {balance}</div>
81
+ * }
82
+ * ```
83
+ */
84
+ export function useBalance(params) {
85
+ const { accountId, enabled = true } = params;
86
+ const near = useNear();
87
+ const [data, setData] = useState(undefined);
88
+ const [error, setError] = useState(undefined);
89
+ const [isLoading, setIsLoading] = useState(enabled);
90
+ const requestIdRef = useRef(0);
91
+ const fetchData = useCallback(async () => {
92
+ if (!enabled || !accountId) {
93
+ setIsLoading(false);
94
+ return;
95
+ }
96
+ const currentRequestId = ++requestIdRef.current;
97
+ setIsLoading(true);
98
+ setError(undefined);
99
+ try {
100
+ const result = await near.getBalance(accountId);
101
+ if (currentRequestId !== requestIdRef.current)
102
+ return;
103
+ setData(result);
104
+ }
105
+ catch (err) {
106
+ if (currentRequestId !== requestIdRef.current)
107
+ return;
108
+ setError(err instanceof Error ? err : new Error(String(err)));
109
+ }
110
+ finally {
111
+ if (currentRequestId === requestIdRef.current) {
112
+ setIsLoading(false);
113
+ }
114
+ }
115
+ }, [near, accountId, enabled]);
116
+ useEffect(() => {
117
+ void fetchData();
118
+ }, [fetchData]);
119
+ return { data, error, isLoading, refetch: fetchData };
120
+ }
121
+ /**
122
+ * Hook for checking if a NEAR account exists.
123
+ *
124
+ * @example
125
+ * ```tsx
126
+ * function AccountCheck({ accountId }: { accountId: string }) {
127
+ * const { data: exists, isLoading } = useAccountExists({ accountId })
128
+ *
129
+ * if (isLoading) return <div>Checking...</div>
130
+ * return <div>{exists ? "Account exists" : "Account not found"}</div>
131
+ * }
132
+ * ```
133
+ */
134
+ export function useAccountExists(params) {
135
+ const { accountId, enabled = true } = params;
136
+ const near = useNear();
137
+ const [data, setData] = useState(undefined);
138
+ const [error, setError] = useState(undefined);
139
+ const [isLoading, setIsLoading] = useState(enabled);
140
+ const requestIdRef = useRef(0);
141
+ const fetchData = useCallback(async () => {
142
+ if (!enabled || !accountId) {
143
+ setIsLoading(false);
144
+ return;
145
+ }
146
+ const currentRequestId = ++requestIdRef.current;
147
+ setIsLoading(true);
148
+ setError(undefined);
149
+ try {
150
+ const result = await near.accountExists(accountId);
151
+ if (currentRequestId !== requestIdRef.current)
152
+ return;
153
+ setData(result);
154
+ }
155
+ catch (err) {
156
+ if (currentRequestId !== requestIdRef.current)
157
+ return;
158
+ setError(err instanceof Error ? err : new Error(String(err)));
159
+ }
160
+ finally {
161
+ if (currentRequestId === requestIdRef.current) {
162
+ setIsLoading(false);
163
+ }
164
+ }
165
+ }, [near, accountId, enabled]);
166
+ useEffect(() => {
167
+ void fetchData();
168
+ }, [fetchData]);
169
+ return { data, error, isLoading, refetch: fetchData };
170
+ }
171
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @near-kit/react - React bindings for near-kit
3
+ *
4
+ * A thin React layer on top of near-kit providing:
5
+ * - NearProvider and useNear for context management
6
+ * - Simple hooks for view calls and mutations
7
+ * - Full TypeScript support
8
+ *
9
+ * For advanced features like caching, polling, or optimistic updates,
10
+ * use React Query or SWR with the useNear() hook directly.
11
+ */
12
+ export { type AccountState, useAccount } from "./account.js";
13
+ export { useContract } from "./contract.js";
14
+ export { type UseAccountExistsParams, type UseBalanceParams, type UseViewParams, useAccountExists, useBalance, useView, type ViewResult, } from "./hooks.js";
15
+ export { type AmountInput, type UseCallParams, type UseCallResult, type UseSendResult, useCall, useSend, } from "./mutations.js";
16
+ export { NearProvider, type NearProviderProps, useNear } from "./provider.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,KAAK,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,KAAK,UAAU,GAChB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,OAAO,EACP,OAAO,GACR,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ /**
3
+ * @near-kit/react - React bindings for near-kit
4
+ *
5
+ * A thin React layer on top of near-kit providing:
6
+ * - NearProvider and useNear for context management
7
+ * - Simple hooks for view calls and mutations
8
+ * - Full TypeScript support
9
+ *
10
+ * For advanced features like caching, polling, or optimistic updates,
11
+ * use React Query or SWR with the useNear() hook directly.
12
+ */
13
+ // Account hook
14
+ export { useAccount } from "./account.js";
15
+ // Typed contract hook
16
+ export { useContract } from "./contract.js";
17
+ // View/query hooks
18
+ export { useAccountExists, useBalance, useView, } from "./hooks.js";
19
+ // Mutation hooks
20
+ export { useCall, useSend, } from "./mutations.js";
21
+ // Provider and context
22
+ export { NearProvider, useNear } from "./provider.js";
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ;;;;;;;;;;GAUG;AAEH,eAAe;AACf,OAAO,EAAqB,UAAU,EAAE,MAAM,cAAc,CAAA;AAC5D,sBAAsB;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,mBAAmB;AACnB,OAAO,EAIL,gBAAgB,EAChB,UAAU,EACV,OAAO,GAER,MAAM,YAAY,CAAA;AACnB,iBAAiB;AACjB,OAAO,EAKL,OAAO,EACP,OAAO,GACR,MAAM,gBAAgB,CAAA;AACvB,uBAAuB;AACvB,OAAO,EAAE,YAAY,EAA0B,OAAO,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,99 @@
1
+ import type { CallOptions, NearError } from "near-kit";
2
+ /**
3
+ * Amount input for NEAR transfers.
4
+ * Accepts "10 NEAR", "1000 yocto", or raw bigint.
5
+ */
6
+ export type AmountInput = `${number} NEAR` | `${bigint} yocto` | bigint;
7
+ /**
8
+ * Parameters for useCall hook
9
+ */
10
+ export interface UseCallParams {
11
+ /** Contract account ID */
12
+ contractId: string;
13
+ /** Change method name */
14
+ method: string;
15
+ /** Default options (gas, attachedDeposit, etc.) */
16
+ options?: CallOptions;
17
+ }
18
+ /**
19
+ * Result type for useCall hook
20
+ */
21
+ export interface UseCallResult<TArgs extends object, TResult> {
22
+ /** Execute the contract call */
23
+ mutate: (args: TArgs, options?: CallOptions) => Promise<TResult>;
24
+ /** The result data from the last successful call */
25
+ data: TResult | undefined;
26
+ /** Any error from the last call */
27
+ error: NearError | Error | undefined;
28
+ /** Whether a call is currently in progress */
29
+ isPending: boolean;
30
+ /** Whether the last call was successful */
31
+ isSuccess: boolean;
32
+ /** Whether the last call failed */
33
+ isError: boolean;
34
+ /** Reset the mutation state */
35
+ reset: () => void;
36
+ }
37
+ /**
38
+ * Hook for calling change methods on NEAR contracts.
39
+ *
40
+ * This is a thin wrapper around `near.call()` that provides React state management.
41
+ * For advanced features like optimistic updates or mutation queuing, use React Query
42
+ * or SWR with the `useNear()` hook directly.
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * function IncrementButton() {
47
+ * const { mutate, isPending, isError, error } = useCall<{}, void>({
48
+ * contractId: "counter.testnet",
49
+ * method: "increment",
50
+ * })
51
+ *
52
+ * return (
53
+ * <button onClick={() => mutate({})} disabled={isPending}>
54
+ * {isPending ? "Sending..." : "Increment"}
55
+ * </button>
56
+ * )
57
+ * }
58
+ * ```
59
+ */
60
+ export declare function useCall<TArgs extends object = object, TResult = unknown>(params: UseCallParams): UseCallResult<TArgs, TResult>;
61
+ /**
62
+ * Result type for useSend hook
63
+ */
64
+ export interface UseSendResult {
65
+ /** Execute the NEAR transfer */
66
+ mutate: (to: string, amount: AmountInput) => Promise<void>;
67
+ /** Any error from the last transfer */
68
+ error: NearError | Error | undefined;
69
+ /** Whether a transfer is currently in progress */
70
+ isPending: boolean;
71
+ /** Whether the last transfer was successful */
72
+ isSuccess: boolean;
73
+ /** Whether the last transfer failed */
74
+ isError: boolean;
75
+ /** Reset the mutation state */
76
+ reset: () => void;
77
+ }
78
+ /**
79
+ * Hook for sending NEAR tokens.
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * function SendButton() {
84
+ * const { mutate: send, isPending } = useSend()
85
+ *
86
+ * const handleSend = () => {
87
+ * send("bob.testnet", "1 NEAR")
88
+ * }
89
+ *
90
+ * return (
91
+ * <button onClick={handleSend} disabled={isPending}>
92
+ * {isPending ? "Sending..." : "Send 1 NEAR"}
93
+ * </button>
94
+ * )
95
+ * }
96
+ * ```
97
+ */
98
+ export declare function useSend(): UseSendResult;
99
+ //# sourceMappingURL=mutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../src/mutations.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAItD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,GAAG,MAAM,OAAO,GAAG,GAAG,MAAM,QAAQ,GAAG,MAAM,CAAA;AAEvE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,mDAAmD;IACnD,OAAO,CAAC,EAAE,WAAW,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO;IAC1D,gCAAgC;IAChC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAChE,oDAAoD;IACpD,IAAI,EAAE,OAAO,GAAG,SAAS,CAAA;IACzB,mCAAmC;IACnC,KAAK,EAAE,SAAS,GAAG,KAAK,GAAG,SAAS,CAAA;IACpC,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAA;IAClB,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAA;IAClB,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,OAAO,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,GAAG,OAAO,EACtE,MAAM,EAAE,aAAa,GACpB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAqE/B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,uCAAuC;IACvC,KAAK,EAAE,SAAS,GAAG,KAAK,GAAG,SAAS,CAAA;IACpC,kDAAkD;IAClD,SAAS,EAAE,OAAO,CAAA;IAClB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAA;IAClB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,OAAO,IAAI,aAAa,CAkDvC"}
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { useCallback, useRef, useState } from "react";
3
+ import { useNear } from "./provider.js";
4
+ /**
5
+ * Hook for calling change methods on NEAR contracts.
6
+ *
7
+ * This is a thin wrapper around `near.call()` that provides React state management.
8
+ * For advanced features like optimistic updates or mutation queuing, use React Query
9
+ * or SWR with the `useNear()` hook directly.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * function IncrementButton() {
14
+ * const { mutate, isPending, isError, error } = useCall<{}, void>({
15
+ * contractId: "counter.testnet",
16
+ * method: "increment",
17
+ * })
18
+ *
19
+ * return (
20
+ * <button onClick={() => mutate({})} disabled={isPending}>
21
+ * {isPending ? "Sending..." : "Increment"}
22
+ * </button>
23
+ * )
24
+ * }
25
+ * ```
26
+ */
27
+ export function useCall(params) {
28
+ const { contractId, method, options: defaultOptions } = params;
29
+ const near = useNear();
30
+ const [data, setData] = useState(undefined);
31
+ const [error, setError] = useState(undefined);
32
+ const [isPending, setIsPending] = useState(false);
33
+ const [isSuccess, setIsSuccess] = useState(false);
34
+ const [isError, setIsError] = useState(false);
35
+ // Track the latest mutation to handle parallel calls (last write wins)
36
+ const mutationIdRef = useRef(0);
37
+ const mutate = useCallback(async (args, options) => {
38
+ const currentMutationId = ++mutationIdRef.current;
39
+ setIsPending(true);
40
+ setIsSuccess(false);
41
+ setIsError(false);
42
+ setError(undefined);
43
+ try {
44
+ const mergedOptions = {
45
+ ...defaultOptions,
46
+ ...options,
47
+ };
48
+ const result = await near.call(contractId, method, args, mergedOptions);
49
+ // Only update state if this is still the latest mutation
50
+ if (currentMutationId === mutationIdRef.current) {
51
+ setData(result);
52
+ setIsSuccess(true);
53
+ setIsPending(false);
54
+ }
55
+ return result;
56
+ }
57
+ catch (err) {
58
+ const normalizedError = err instanceof Error ? err : new Error(String(err));
59
+ // Only update state if this is still the latest mutation
60
+ if (currentMutationId === mutationIdRef.current) {
61
+ setError(normalizedError);
62
+ setIsError(true);
63
+ setIsPending(false);
64
+ }
65
+ throw normalizedError;
66
+ }
67
+ }, [near, contractId, method, defaultOptions]);
68
+ const reset = useCallback(() => {
69
+ setData(undefined);
70
+ setError(undefined);
71
+ setIsPending(false);
72
+ setIsSuccess(false);
73
+ setIsError(false);
74
+ mutationIdRef.current++;
75
+ }, []);
76
+ return { mutate, data, error, isPending, isSuccess, isError, reset };
77
+ }
78
+ /**
79
+ * Hook for sending NEAR tokens.
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * function SendButton() {
84
+ * const { mutate: send, isPending } = useSend()
85
+ *
86
+ * const handleSend = () => {
87
+ * send("bob.testnet", "1 NEAR")
88
+ * }
89
+ *
90
+ * return (
91
+ * <button onClick={handleSend} disabled={isPending}>
92
+ * {isPending ? "Sending..." : "Send 1 NEAR"}
93
+ * </button>
94
+ * )
95
+ * }
96
+ * ```
97
+ */
98
+ export function useSend() {
99
+ const near = useNear();
100
+ const [error, setError] = useState(undefined);
101
+ const [isPending, setIsPending] = useState(false);
102
+ const [isSuccess, setIsSuccess] = useState(false);
103
+ const [isError, setIsError] = useState(false);
104
+ const mutationIdRef = useRef(0);
105
+ const mutate = useCallback(async (to, amount) => {
106
+ const currentMutationId = ++mutationIdRef.current;
107
+ setIsPending(true);
108
+ setIsSuccess(false);
109
+ setIsError(false);
110
+ setError(undefined);
111
+ try {
112
+ await near.send(to, amount);
113
+ if (currentMutationId === mutationIdRef.current) {
114
+ setIsSuccess(true);
115
+ setIsPending(false);
116
+ }
117
+ }
118
+ catch (err) {
119
+ const normalizedError = err instanceof Error ? err : new Error(String(err));
120
+ if (currentMutationId === mutationIdRef.current) {
121
+ setError(normalizedError);
122
+ setIsError(true);
123
+ setIsPending(false);
124
+ }
125
+ throw normalizedError;
126
+ }
127
+ }, [near]);
128
+ const reset = useCallback(() => {
129
+ setError(undefined);
130
+ setIsPending(false);
131
+ setIsSuccess(false);
132
+ setIsError(false);
133
+ mutationIdRef.current++;
134
+ }, []);
135
+ return { mutate, error, isPending, isSuccess, isError, reset };
136
+ }
137
+ //# sourceMappingURL=mutations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.js","sourceRoot":"","sources":["../src/mutations.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { Near, type NearConfig } from "near-kit";
2
+ import { type ReactNode } from "react";
3
+ /**
4
+ * Props for NearProvider - either pass config or an existing Near instance
5
+ */
6
+ export type NearProviderProps = {
7
+ config: NearConfig;
8
+ near?: never;
9
+ children: ReactNode;
10
+ } | {
11
+ near: Near;
12
+ config?: never;
13
+ children: ReactNode;
14
+ };
15
+ /**
16
+ * Provider that creates or wraps a Near client instance and makes it
17
+ * available to all child components via React context.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * // Using configuration (creates Near instance internally)
22
+ * <NearProvider config={{ network: "testnet" }}>
23
+ * <App />
24
+ * </NearProvider>
25
+ *
26
+ * // Using an existing Near instance
27
+ * const near = new Near({ network: "testnet" })
28
+ * <NearProvider near={near}>
29
+ * <App />
30
+ * </NearProvider>
31
+ * ```
32
+ */
33
+ export declare function NearProvider(props: NearProviderProps): ReactNode;
34
+ /**
35
+ * Hook to access the Near client instance from context.
36
+ *
37
+ * @throws Error if called outside of a NearProvider
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * function MyComponent() {
42
+ * const near = useNear()
43
+ * // Use near.view(), near.call(), near.transaction(), etc.
44
+ * }
45
+ * ```
46
+ */
47
+ export declare function useNear(): Near;
48
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAiB,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAA;AAY1E;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,CAAA;AAEvD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,SAAS,CAqChE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,IAAI,IAAI,CAS9B"}
@@ -0,0 +1,78 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Near } from "near-kit";
4
+ import { createContext, useContext, useMemo } from "react";
5
+ /**
6
+ * Context for the Near client instance
7
+ */
8
+ const NearContext = createContext(null);
9
+ /**
10
+ * Internal context to detect nested providers
11
+ */
12
+ const NearProviderDetectionContext = createContext(false);
13
+ /**
14
+ * Provider that creates or wraps a Near client instance and makes it
15
+ * available to all child components via React context.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * // Using configuration (creates Near instance internally)
20
+ * <NearProvider config={{ network: "testnet" }}>
21
+ * <App />
22
+ * </NearProvider>
23
+ *
24
+ * // Using an existing Near instance
25
+ * const near = new Near({ network: "testnet" })
26
+ * <NearProvider near={near}>
27
+ * <App />
28
+ * </NearProvider>
29
+ * ```
30
+ */
31
+ export function NearProvider(props) {
32
+ const { children } = props;
33
+ // Detect nested providers
34
+ const isNested = useContext(NearProviderDetectionContext);
35
+ if (isNested) {
36
+ throw new Error("Nested <NearProvider> detected. Only one NearProvider is allowed per React tree. " +
37
+ "If you need multiple networks, create separate Near instances and pass them explicitly.");
38
+ }
39
+ // Extract the Near instance or config for stable dependency tracking
40
+ const nearProp = "near" in props ? props.near : undefined;
41
+ const configProp = "config" in props ? props.config : undefined;
42
+ // Serialize config for dependency comparison (only used when config is provided)
43
+ const configKey = configProp ? JSON.stringify(configProp) : undefined;
44
+ // Create or use the provided Near instance
45
+ // biome-ignore lint/correctness/useExhaustiveDependencies: configKey is derived from configProp for stable comparison
46
+ const nearInstance = useMemo(() => {
47
+ if (nearProp) {
48
+ return nearProp;
49
+ }
50
+ if (configProp) {
51
+ return new Near(configProp);
52
+ }
53
+ throw new Error("NearProvider requires either 'near' or 'config' prop");
54
+ }, [nearProp, configKey]);
55
+ return (_jsx(NearProviderDetectionContext.Provider, { value: true, children: _jsx(NearContext.Provider, { value: nearInstance, children: children }) }));
56
+ }
57
+ /**
58
+ * Hook to access the Near client instance from context.
59
+ *
60
+ * @throws Error if called outside of a NearProvider
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * function MyComponent() {
65
+ * const near = useNear()
66
+ * // Use near.view(), near.call(), near.transaction(), etc.
67
+ * }
68
+ * ```
69
+ */
70
+ export function useNear() {
71
+ const near = useContext(NearContext);
72
+ if (!near) {
73
+ throw new Error("useNear must be used within a <NearProvider>. " +
74
+ "Wrap your component tree with <NearProvider config={{ network: 'testnet' }}>.");
75
+ }
76
+ return near;
77
+ }
78
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,IAAI,EAAmB,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,aAAa,EAAkB,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE1E;;GAEG;AACH,MAAM,WAAW,GAAG,aAAa,CAAc,IAAI,CAAC,CAAA;AAEpD;;GAEG;AACH,MAAM,4BAA4B,GAAG,aAAa,CAAU,KAAK,CAAC,CAAA;AASlE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAE1B,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,UAAU,CAAC,4BAA4B,CAAC,CAAA;IACzD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,mFAAmF;YACjF,yFAAyF,CAC5F,CAAA;IACH,CAAC;IAED,qEAAqE;IACrE,MAAM,QAAQ,GAAG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;IACzD,MAAM,UAAU,GAAG,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IAC/D,iFAAiF;IACjF,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAErE,2CAA2C;IAC3C,sHAAsH;IACtH,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE;QAChC,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAA;QACjB,CAAC;QACD,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,CAAA;QAC7B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAA;IACzE,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAA;IAEzB,OAAO,CACL,KAAC,4BAA4B,CAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,YAChD,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YACtC,QAAQ,GACY,GACe,CACzC,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,gDAAgD;YAC9C,+EAA+E,CAClF,CAAA;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@near-kit/react",
3
+ "version": "0.8.3",
4
+ "description": "React bindings for near-kit - hooks and providers for NEAR Protocol",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "test": "vitest run",
23
+ "lint": "biome check . --write",
24
+ "typecheck": "tsc --noEmit",
25
+ "prepublishOnly": "bun run build"
26
+ },
27
+ "keywords": [
28
+ "near",
29
+ "near-protocol",
30
+ "blockchain",
31
+ "react",
32
+ "hooks",
33
+ "web3"
34
+ ],
35
+ "license": "MIT",
36
+ "peerDependencies": {
37
+ "near-kit": ">=0.8.3",
38
+ "react": ">=18.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@biomejs/biome": "2.0.6",
42
+ "@testing-library/react": "^16.2.0",
43
+ "@types/react": "^19.0.0",
44
+ "jsdom": "^26.0.0",
45
+ "near-kit": "0.8.3",
46
+ "react": "^19.0.0",
47
+ "react-dom": "^19.0.0",
48
+ "typescript": "^5.9.3",
49
+ "vitest": "^4.0.10"
50
+ }
51
+ }