@caatinga/client 2.0.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ import {
2
+ WALLET_SESSION_STORAGE_KEY,
3
+ createWalletSession,
4
+ withWalletTimeout
5
+ } from "./chunk-HKAMQDUV.js";
6
+
1
7
  // src/artifacts/resolve-contract-id.ts
2
8
  import { CaatingaError, CaatingaErrorCode } from "@caatinga/core/browser";
3
9
  function resolveContractId(input) {
@@ -46,6 +52,13 @@ import { CaatingaError as CaatingaError2, CaatingaErrorCode as CaatingaErrorCode
46
52
  function createDefaultBindingAdapter(binding) {
47
53
  return {
48
54
  createClient({ contractId, publicKey, rpcUrl, networkPassphrase }) {
55
+ if (binding.__caatingaPlaceholder) {
56
+ throw new CaatingaError2(
57
+ "Placeholder bindings are still in use; the app cannot reach the contract.",
58
+ CaatingaErrorCode2.PLACEHOLDER_BINDING,
59
+ "Run `caatinga generate <contract> --network <network>`, then restart the dev server."
60
+ );
61
+ }
49
62
  if (!binding.Client) {
50
63
  throw new CaatingaError2(
51
64
  "Generated binding does not export Client.",
@@ -76,10 +89,10 @@ function createDefaultBindingAdapter(binding) {
76
89
  }
77
90
 
78
91
  // src/client/create-caatinga-client.ts
79
- import { CaatingaError as CaatingaError8, CaatingaErrorCode as CaatingaErrorCode8 } from "@caatinga/core/browser";
92
+ import { CaatingaError as CaatingaError7, CaatingaErrorCode as CaatingaErrorCode7 } from "@caatinga/core/browser";
80
93
 
81
94
  // src/client/caatinga-contract-client.ts
82
- import { CaatingaError as CaatingaError7, CaatingaErrorCode as CaatingaErrorCode7 } from "@caatinga/core/browser";
95
+ import { CaatingaError as CaatingaError6, CaatingaErrorCode as CaatingaErrorCode6 } from "@caatinga/core/browser";
83
96
 
84
97
  // src/xdr/build-xdr.ts
85
98
  import { CaatingaError as CaatingaError3, CaatingaErrorCode as CaatingaErrorCode3 } from "@caatinga/core/browser";
@@ -138,43 +151,6 @@ function readXdr(transaction) {
138
151
  return candidate.toXDR();
139
152
  }
140
153
 
141
- // src/wallet/with-wallet-timeout.ts
142
- import { CaatingaError as CaatingaError4, CaatingaErrorCode as CaatingaErrorCode4 } from "@caatinga/core/browser";
143
- function withWalletTimeout(label, timeoutMs, fn) {
144
- if (timeoutMs === void 0 || timeoutMs <= 0) {
145
- return fn();
146
- }
147
- let timedOut = false;
148
- return new Promise((resolve, reject) => {
149
- const timer = setTimeout(() => {
150
- timedOut = true;
151
- reject(
152
- new CaatingaError4(
153
- `Wallet "${label}" timed out after ${timeoutMs}ms.`,
154
- CaatingaErrorCode4.WALLET_TIMEOUT,
155
- "Ensure the wallet adapter rejects on user dismissal, or increase walletTimeout."
156
- )
157
- );
158
- }, timeoutMs);
159
- fn().then(
160
- (value) => {
161
- if (timedOut) {
162
- return;
163
- }
164
- clearTimeout(timer);
165
- resolve(value);
166
- },
167
- (error) => {
168
- if (timedOut) {
169
- return;
170
- }
171
- clearTimeout(timer);
172
- reject(error);
173
- }
174
- );
175
- });
176
- }
177
-
178
154
  // src/client/invoke-args.ts
179
155
  function splitArgsAndOptions(argsOrOptions, maybeOptions) {
180
156
  return {
@@ -214,7 +190,7 @@ function splitReadArgsAndOptions(argsOrOptions, maybeOptions) {
214
190
  }
215
191
 
216
192
  // src/client/transaction-simulate.ts
217
- import { CaatingaError as CaatingaError5, CaatingaErrorCode as CaatingaErrorCode5 } from "@caatinga/core/browser";
193
+ import { CaatingaError as CaatingaError4, CaatingaErrorCode as CaatingaErrorCode4 } from "@caatinga/core/browser";
218
194
  async function prepareReadTransaction(transaction, contractName, method, rpcUrl) {
219
195
  const candidate = transaction;
220
196
  if (typeof candidate.prepare !== "function") {
@@ -223,12 +199,12 @@ async function prepareReadTransaction(transaction, contractName, method, rpcUrl)
223
199
  try {
224
200
  return await candidate.prepare.call(transaction);
225
201
  } catch (error) {
226
- if (error instanceof CaatingaError5) {
202
+ if (error instanceof CaatingaError4) {
227
203
  throw error;
228
204
  }
229
- throw new CaatingaError5(
205
+ throw new CaatingaError4(
230
206
  `Failed to prepare XDR for "${contractName}.${method}".`,
231
- CaatingaErrorCode5.XDR_PREPARE_FAILED,
207
+ CaatingaErrorCode4.XDR_PREPARE_FAILED,
232
208
  `RPC: ${rpcUrl}. Check connectivity, simulation errors, and binding compatibility.`,
233
209
  error
234
210
  );
@@ -241,15 +217,15 @@ function readSimulationResult(raw, contractName, method) {
241
217
  return result;
242
218
  }
243
219
  }
244
- throw new CaatingaError5(
220
+ throw new CaatingaError4(
245
221
  `Simulation for "${contractName}.${method}" did not return a result.`,
246
- CaatingaErrorCode5.READ_RESULT_MISSING,
222
+ CaatingaErrorCode4.READ_RESULT_MISSING,
247
223
  `Expected "${contractName}.${method}" to expose a simulation result. Use debugRaw to inspect the generated binding output.`
248
224
  );
249
225
  }
250
226
 
251
227
  // src/client/transaction-submit.ts
252
- import { CaatingaError as CaatingaError6, CaatingaErrorCode as CaatingaErrorCode6 } from "@caatinga/core/browser";
228
+ import { CaatingaError as CaatingaError5, CaatingaErrorCode as CaatingaErrorCode5 } from "@caatinga/core/browser";
253
229
  async function submitTransaction(transaction, signTransaction, contractName, method, rpcUrl) {
254
230
  const candidate = transaction;
255
231
  if (typeof candidate.signAndSend === "function") {
@@ -258,12 +234,12 @@ async function submitTransaction(transaction, signTransaction, contractName, met
258
234
  assertSubmitResultRecognized(raw, contractName, method);
259
235
  return raw;
260
236
  } catch (error) {
261
- if (error instanceof CaatingaError6) {
237
+ if (error instanceof CaatingaError5) {
262
238
  throw error;
263
239
  }
264
- throw new CaatingaError6(
240
+ throw new CaatingaError5(
265
241
  `Failed to submit XDR for "${contractName}.${method}".`,
266
- CaatingaErrorCode6.XDR_SUBMIT_FAILED,
242
+ CaatingaErrorCode5.XDR_SUBMIT_FAILED,
267
243
  `RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
268
244
  error
269
245
  );
@@ -275,20 +251,20 @@ async function submitTransaction(transaction, signTransaction, contractName, met
275
251
  assertSubmitResultRecognized(raw, contractName, method);
276
252
  return raw;
277
253
  } catch (error) {
278
- if (error instanceof CaatingaError6) {
254
+ if (error instanceof CaatingaError5) {
279
255
  throw error;
280
256
  }
281
- throw new CaatingaError6(
257
+ throw new CaatingaError5(
282
258
  `Failed to submit XDR for "${contractName}.${method}".`,
283
- CaatingaErrorCode6.XDR_SUBMIT_FAILED,
259
+ CaatingaErrorCode5.XDR_SUBMIT_FAILED,
284
260
  `RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
285
261
  error
286
262
  );
287
263
  }
288
264
  }
289
- throw new CaatingaError6(
265
+ throw new CaatingaError5(
290
266
  `Binding transaction for "${contractName}.${method}" cannot be submitted.`,
291
- CaatingaErrorCode6.XDR_SUBMIT_FAILED,
267
+ CaatingaErrorCode5.XDR_SUBMIT_FAILED,
292
268
  "Regenerate bindings or provide a compatible binding adapter."
293
269
  );
294
270
  }
@@ -302,9 +278,9 @@ function assertSubmitResultRecognized(raw, contractName, method) {
302
278
  if (hasTransactionId || hasResult) {
303
279
  return;
304
280
  }
305
- throw new CaatingaError6(
281
+ throw new CaatingaError5(
306
282
  `Submit returned an unrecognized payload for "${contractName}.${method}".`,
307
- CaatingaErrorCode6.XDR_RESULT_FAILED,
283
+ CaatingaErrorCode5.XDR_RESULT_FAILED,
308
284
  "Expected txHash, transactionHash, hash, sendTransactionResponse.hash, or result on the submit response. Use debugRaw to inspect the binding output."
309
285
  );
310
286
  }
@@ -369,20 +345,20 @@ var CaatingaContractClient = class {
369
345
  })
370
346
  );
371
347
  } catch (error) {
372
- if (error instanceof CaatingaError7) {
348
+ if (error instanceof CaatingaError6) {
373
349
  throw error;
374
350
  }
375
- throw new CaatingaError7(
351
+ throw new CaatingaError6(
376
352
  `Failed to sign XDR for "${this.contractName}.${method}".`,
377
- CaatingaErrorCode7.XDR_SIGN_FAILED,
353
+ CaatingaErrorCode6.XDR_SIGN_FAILED,
378
354
  "Connect a wallet and approve the transaction.",
379
355
  error
380
356
  );
381
357
  }
382
358
  if (typeof signedXdr !== "string" || signedXdr.trim().length === 0) {
383
- throw new CaatingaError7(
359
+ throw new CaatingaError6(
384
360
  `Failed to sign XDR for "${this.contractName}.${method}".`,
385
- CaatingaErrorCode7.XDR_SIGN_FAILED,
361
+ CaatingaErrorCode6.XDR_SIGN_FAILED,
386
362
  "Wallet returned an empty or invalid signed XDR. The user may have dismissed the signing prompt.",
387
363
  signedXdr
388
364
  );
@@ -397,9 +373,9 @@ var CaatingaContractClient = class {
397
373
  this.config.network.rpcUrl
398
374
  );
399
375
  if (typeof transaction.signAndSend === "function" && signedXdr === void 0) {
400
- throw new CaatingaError7(
376
+ throw new CaatingaError6(
401
377
  `Failed to sign XDR for "${this.contractName}.${method}".`,
402
- CaatingaErrorCode7.XDR_SIGN_FAILED,
378
+ CaatingaErrorCode6.XDR_SIGN_FAILED,
403
379
  "Wallet returned an empty or invalid signed XDR. The generated transaction did not request a wallet signature."
404
380
  );
405
381
  }
@@ -459,12 +435,12 @@ var CaatingaContractClient = class {
459
435
  () => this.config.wallet.getPublicKey()
460
436
  );
461
437
  } catch (error) {
462
- if (error instanceof CaatingaError7) {
438
+ if (error instanceof CaatingaError6) {
463
439
  throw error;
464
440
  }
465
- throw new CaatingaError7(
441
+ throw new CaatingaError6(
466
442
  `Wallet is not connected or the public key is unavailable for "${this.contractName}".`,
467
- CaatingaErrorCode7.WALLET_NOT_CONNECTED,
443
+ CaatingaErrorCode6.WALLET_NOT_CONNECTED,
468
444
  "Connect the wallet and grant account access, then retry.",
469
445
  error
470
446
  );
@@ -486,9 +462,9 @@ function createCaatingaClient(config) {
486
462
  contract(contractName) {
487
463
  const registration = config.contracts[contractName];
488
464
  if (!registration) {
489
- throw new CaatingaError8(
465
+ throw new CaatingaError7(
490
466
  `Contract "${contractName}" is not registered.`,
491
- CaatingaErrorCode8.CONTRACT_NOT_FOUND,
467
+ CaatingaErrorCode7.CONTRACT_NOT_FOUND,
492
468
  "Add the contract binding to createCaatingaClient()."
493
469
  );
494
470
  }
@@ -498,8 +474,10 @@ function createCaatingaClient(config) {
498
474
  }
499
475
  export {
500
476
  CaatingaContractClient,
477
+ WALLET_SESSION_STORAGE_KEY,
501
478
  buildXdr,
502
479
  createCaatingaClient,
503
480
  createDefaultBindingAdapter,
481
+ createWalletSession,
504
482
  resolveContractId
505
483
  };
package/dist/react.cjs ADDED
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react.ts
21
+ var react_exports = {};
22
+ __export(react_exports, {
23
+ WALLET_SESSION_STORAGE_KEY: () => WALLET_SESSION_STORAGE_KEY,
24
+ WalletProvider: () => WalletProvider,
25
+ createWalletSession: () => createWalletSession,
26
+ useWallet: () => useWallet,
27
+ useWalletSession: () => useWalletSession
28
+ });
29
+ module.exports = __toCommonJS(react_exports);
30
+
31
+ // src/react/wallet-provider.ts
32
+ var import_react = require("react");
33
+
34
+ // src/wallet/with-wallet-timeout.ts
35
+ var import_browser = require("@caatinga/core/browser");
36
+ function withWalletTimeout(label, timeoutMs, fn) {
37
+ if (timeoutMs === void 0 || timeoutMs <= 0) {
38
+ return fn();
39
+ }
40
+ let timedOut = false;
41
+ return new Promise((resolve, reject) => {
42
+ const timer = setTimeout(() => {
43
+ timedOut = true;
44
+ reject(
45
+ new import_browser.CaatingaError(
46
+ `Wallet "${label}" timed out after ${timeoutMs}ms.`,
47
+ import_browser.CaatingaErrorCode.WALLET_TIMEOUT,
48
+ "Ensure the wallet adapter rejects on user dismissal, or increase walletTimeout."
49
+ )
50
+ );
51
+ }, timeoutMs);
52
+ fn().then(
53
+ (value) => {
54
+ if (timedOut) {
55
+ return;
56
+ }
57
+ clearTimeout(timer);
58
+ resolve(value);
59
+ },
60
+ (error) => {
61
+ if (timedOut) {
62
+ return;
63
+ }
64
+ clearTimeout(timer);
65
+ reject(error);
66
+ }
67
+ );
68
+ });
69
+ }
70
+
71
+ // src/wallet/wallet-session.ts
72
+ var WALLET_SESSION_STORAGE_KEY = "caatinga:wallet-session";
73
+ function defaultStorage() {
74
+ if (typeof window === "undefined") {
75
+ return void 0;
76
+ }
77
+ try {
78
+ return window.localStorage;
79
+ } catch {
80
+ return void 0;
81
+ }
82
+ }
83
+ function toError(value) {
84
+ return value instanceof Error ? value : new Error(String(value));
85
+ }
86
+ function createWalletSession(adapter, options = {}) {
87
+ const capabilities = adapter;
88
+ const storage = options.persist ? options.storage ?? defaultStorage() : void 0;
89
+ const storageKey = options.storageKey ?? WALLET_SESSION_STORAGE_KEY;
90
+ const listeners = /* @__PURE__ */ new Set();
91
+ let state = {
92
+ status: "disconnected",
93
+ publicKey: null,
94
+ error: null
95
+ };
96
+ function setState(next) {
97
+ state = next;
98
+ for (const listener of listeners) {
99
+ listener();
100
+ }
101
+ }
102
+ function persistConnection() {
103
+ if (!storage) {
104
+ return;
105
+ }
106
+ const payload = { v: 1 };
107
+ const walletId = capabilities.getWalletId?.();
108
+ if (walletId) {
109
+ payload.walletId = walletId;
110
+ }
111
+ try {
112
+ storage.setItem(storageKey, JSON.stringify(payload));
113
+ } catch {
114
+ }
115
+ }
116
+ function clearPersisted() {
117
+ try {
118
+ storage?.removeItem(storageKey);
119
+ } catch {
120
+ }
121
+ }
122
+ function readPersisted() {
123
+ if (!storage) {
124
+ return null;
125
+ }
126
+ try {
127
+ const raw = storage.getItem(storageKey);
128
+ if (!raw) {
129
+ return null;
130
+ }
131
+ const parsed = JSON.parse(raw);
132
+ return parsed && parsed.v === 1 ? parsed : null;
133
+ } catch {
134
+ return null;
135
+ }
136
+ }
137
+ async function requestPublicKey(label, viaModal) {
138
+ const request = viaModal && capabilities.openModal ? () => capabilities.openModal() : () => adapter.getPublicKey();
139
+ return withWalletTimeout(label, options.timeout, request);
140
+ }
141
+ async function connect() {
142
+ setState({ status: "connecting", publicKey: null, error: null });
143
+ try {
144
+ const publicKey = await requestPublicKey("connect", true);
145
+ setState({ status: "connected", publicKey, error: null });
146
+ persistConnection();
147
+ return publicKey;
148
+ } catch (error) {
149
+ setState({ status: "disconnected", publicKey: null, error: toError(error) });
150
+ throw error;
151
+ }
152
+ }
153
+ async function disconnect() {
154
+ try {
155
+ await capabilities.disconnect?.();
156
+ } finally {
157
+ clearPersisted();
158
+ setState({ status: "disconnected", publicKey: null, error: null });
159
+ }
160
+ }
161
+ async function restore() {
162
+ if (state.status === "connected") {
163
+ return state.publicKey;
164
+ }
165
+ const persisted = readPersisted();
166
+ if (!persisted) {
167
+ return null;
168
+ }
169
+ setState({ status: "connecting", publicKey: null, error: null });
170
+ try {
171
+ if (persisted.walletId) {
172
+ capabilities.setWallet?.(persisted.walletId);
173
+ }
174
+ const publicKey = await requestPublicKey("restore", false);
175
+ setState({ status: "connected", publicKey, error: null });
176
+ return publicKey;
177
+ } catch {
178
+ clearPersisted();
179
+ setState({ status: "disconnected", publicKey: null, error: null });
180
+ return null;
181
+ }
182
+ }
183
+ return {
184
+ adapter,
185
+ getState: () => state,
186
+ subscribe(listener) {
187
+ listeners.add(listener);
188
+ return () => {
189
+ listeners.delete(listener);
190
+ };
191
+ },
192
+ connect,
193
+ disconnect,
194
+ restore
195
+ };
196
+ }
197
+
198
+ // src/react/wallet-provider.ts
199
+ var WalletSessionContext = (0, import_react.createContext)(null);
200
+ function WalletProvider(props) {
201
+ const { adapter, session: providedSession, autoConnect, children } = props;
202
+ const initialOptions = (0, import_react.useRef)(props.options);
203
+ const session = (0, import_react.useMemo)(() => {
204
+ if (providedSession) {
205
+ return providedSession;
206
+ }
207
+ if (!adapter) {
208
+ throw new Error("WalletProvider requires an `adapter` or a `session` prop.");
209
+ }
210
+ return createWalletSession(adapter, initialOptions.current);
211
+ }, [providedSession, adapter]);
212
+ const shouldAutoConnect = autoConnect ?? initialOptions.current?.persist ?? false;
213
+ const restoredFor = (0, import_react.useRef)(null);
214
+ (0, import_react.useEffect)(() => {
215
+ if (!shouldAutoConnect || restoredFor.current === session) {
216
+ return;
217
+ }
218
+ restoredFor.current = session;
219
+ void session.restore();
220
+ }, [session, shouldAutoConnect]);
221
+ return (0, import_react.createElement)(WalletSessionContext.Provider, { value: session }, children);
222
+ }
223
+ function useWalletSession() {
224
+ const session = (0, import_react.useContext)(WalletSessionContext);
225
+ if (!session) {
226
+ throw new Error("useWalletSession must be used within a <WalletProvider>.");
227
+ }
228
+ return session;
229
+ }
230
+ function useWallet() {
231
+ const session = useWalletSession();
232
+ const state = (0, import_react.useSyncExternalStore)(session.subscribe, session.getState, session.getState);
233
+ return (0, import_react.useMemo)(
234
+ () => ({
235
+ ...state,
236
+ connected: state.status === "connected",
237
+ connecting: state.status === "connecting",
238
+ connect: session.connect,
239
+ disconnect: session.disconnect,
240
+ session
241
+ }),
242
+ [session, state]
243
+ );
244
+ }
245
+ // Annotate the CommonJS export names for ESM import in node:
246
+ 0 && (module.exports = {
247
+ WALLET_SESSION_STORAGE_KEY,
248
+ WalletProvider,
249
+ createWalletSession,
250
+ useWallet,
251
+ useWalletSession
252
+ });
@@ -0,0 +1,32 @@
1
+ import { ReactNode, ReactElement } from 'react';
2
+ import { C as CaatingaWalletAdapter } from './types-D4XEyX4J.cjs';
3
+ import { c as WalletSessionState, a as WalletSession, b as WalletSessionOptions } from './wallet-session-ed2Dgs9A.cjs';
4
+ export { C as CaatingaWalletCapabilities, W as WALLET_SESSION_STORAGE_KEY, d as WalletSessionStatus, e as WalletSessionStorage, f as createWalletSession } from './wallet-session-ed2Dgs9A.cjs';
5
+ import '@caatinga/core/browser';
6
+
7
+ interface WalletProviderProps {
8
+ /** Adapter the provider wraps in a session. Ignored when `session` is given. */
9
+ adapter?: CaatingaWalletAdapter;
10
+ /** Pre-built session (e.g. shared with non-React code). Takes precedence over `adapter`. */
11
+ session?: WalletSession;
12
+ /** Session options applied when the provider creates the session from `adapter`. */
13
+ options?: WalletSessionOptions;
14
+ /**
15
+ * Run `session.restore()` on mount for silent reconnect.
16
+ * Defaults to true when persistence is enabled, false otherwise.
17
+ */
18
+ autoConnect?: boolean;
19
+ children?: ReactNode;
20
+ }
21
+ declare function WalletProvider(props: WalletProviderProps): ReactElement;
22
+ declare function useWalletSession(): WalletSession;
23
+ interface UseWalletResult extends WalletSessionState {
24
+ connected: boolean;
25
+ connecting: boolean;
26
+ connect(): Promise<string>;
27
+ disconnect(): Promise<void>;
28
+ session: WalletSession;
29
+ }
30
+ declare function useWallet(): UseWalletResult;
31
+
32
+ export { type UseWalletResult, WalletProvider, type WalletProviderProps, WalletSession, WalletSessionOptions, WalletSessionState, useWallet, useWalletSession };
@@ -0,0 +1,32 @@
1
+ import { ReactNode, ReactElement } from 'react';
2
+ import { C as CaatingaWalletAdapter } from './types-D4XEyX4J.js';
3
+ import { c as WalletSessionState, a as WalletSession, b as WalletSessionOptions } from './wallet-session-DeLp8S1c.js';
4
+ export { C as CaatingaWalletCapabilities, W as WALLET_SESSION_STORAGE_KEY, d as WalletSessionStatus, e as WalletSessionStorage, f as createWalletSession } from './wallet-session-DeLp8S1c.js';
5
+ import '@caatinga/core/browser';
6
+
7
+ interface WalletProviderProps {
8
+ /** Adapter the provider wraps in a session. Ignored when `session` is given. */
9
+ adapter?: CaatingaWalletAdapter;
10
+ /** Pre-built session (e.g. shared with non-React code). Takes precedence over `adapter`. */
11
+ session?: WalletSession;
12
+ /** Session options applied when the provider creates the session from `adapter`. */
13
+ options?: WalletSessionOptions;
14
+ /**
15
+ * Run `session.restore()` on mount for silent reconnect.
16
+ * Defaults to true when persistence is enabled, false otherwise.
17
+ */
18
+ autoConnect?: boolean;
19
+ children?: ReactNode;
20
+ }
21
+ declare function WalletProvider(props: WalletProviderProps): ReactElement;
22
+ declare function useWalletSession(): WalletSession;
23
+ interface UseWalletResult extends WalletSessionState {
24
+ connected: boolean;
25
+ connecting: boolean;
26
+ connect(): Promise<string>;
27
+ disconnect(): Promise<void>;
28
+ session: WalletSession;
29
+ }
30
+ declare function useWallet(): UseWalletResult;
31
+
32
+ export { type UseWalletResult, WalletProvider, type WalletProviderProps, WalletSession, WalletSessionOptions, WalletSessionState, useWallet, useWalletSession };
package/dist/react.js ADDED
@@ -0,0 +1,68 @@
1
+ import {
2
+ WALLET_SESSION_STORAGE_KEY,
3
+ createWalletSession
4
+ } from "./chunk-HKAMQDUV.js";
5
+
6
+ // src/react/wallet-provider.ts
7
+ import {
8
+ createContext,
9
+ createElement,
10
+ useContext,
11
+ useEffect,
12
+ useMemo,
13
+ useRef,
14
+ useSyncExternalStore
15
+ } from "react";
16
+ var WalletSessionContext = createContext(null);
17
+ function WalletProvider(props) {
18
+ const { adapter, session: providedSession, autoConnect, children } = props;
19
+ const initialOptions = useRef(props.options);
20
+ const session = useMemo(() => {
21
+ if (providedSession) {
22
+ return providedSession;
23
+ }
24
+ if (!adapter) {
25
+ throw new Error("WalletProvider requires an `adapter` or a `session` prop.");
26
+ }
27
+ return createWalletSession(adapter, initialOptions.current);
28
+ }, [providedSession, adapter]);
29
+ const shouldAutoConnect = autoConnect ?? initialOptions.current?.persist ?? false;
30
+ const restoredFor = useRef(null);
31
+ useEffect(() => {
32
+ if (!shouldAutoConnect || restoredFor.current === session) {
33
+ return;
34
+ }
35
+ restoredFor.current = session;
36
+ void session.restore();
37
+ }, [session, shouldAutoConnect]);
38
+ return createElement(WalletSessionContext.Provider, { value: session }, children);
39
+ }
40
+ function useWalletSession() {
41
+ const session = useContext(WalletSessionContext);
42
+ if (!session) {
43
+ throw new Error("useWalletSession must be used within a <WalletProvider>.");
44
+ }
45
+ return session;
46
+ }
47
+ function useWallet() {
48
+ const session = useWalletSession();
49
+ const state = useSyncExternalStore(session.subscribe, session.getState, session.getState);
50
+ return useMemo(
51
+ () => ({
52
+ ...state,
53
+ connected: state.status === "connected",
54
+ connecting: state.status === "connecting",
55
+ connect: session.connect,
56
+ disconnect: session.disconnect,
57
+ session
58
+ }),
59
+ [session, state]
60
+ );
61
+ }
62
+ export {
63
+ WALLET_SESSION_STORAGE_KEY,
64
+ WalletProvider,
65
+ createWalletSession,
66
+ useWallet,
67
+ useWalletSession
68
+ };