@accesly/react 1.2.0 → 1.3.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.cjs CHANGED
@@ -1,158 +1,526 @@
1
1
  'use strict';
2
2
 
3
- var core = require('@accesly/core');
4
3
  var react = require('react');
4
+ var core = require('@accesly/core');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
7
- // src/provider.tsx
8
- var AcceslyContext = react.createContext(null);
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropNames = Object.getOwnPropertyNames;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ exports.AcceslyContext = void 0;
17
+ var init_context = __esm({
18
+ "src/context.ts"() {
19
+ exports.AcceslyContext = react.createContext(null);
20
+ }
21
+ });
9
22
 
10
23
  // src/config.ts
11
- var ENVIRONMENT_DEFAULTS = {
12
- dev: {
13
- apiUrl: "https://3fki7eiio5.execute-api.us-east-1.amazonaws.com/dev",
14
- walletStreamUrl: "https://ajlmn37thw7fxen3oyykbfmlrm0eecue.lambda-url.us-east-1.on.aws/",
15
- cognito: {
16
- region: "us-east-1",
17
- userPoolId: "us-east-1_K2Nag1tB1",
18
- userPoolClientId: "6r64diep7pne50sender4557jt"
19
- },
20
- stellar: {
21
- networkPassphrase: "Test SDF Network ; September 2015",
22
- horizonUrl: "https://horizon-testnet.stellar.org",
23
- sorobanRpcUrl: "https://soroban-testnet.stellar.org",
24
- // OZ Relayer channels-fund see CloudServices-accesly/docs/Deployed_Resources_dev.md
25
- deployerAddress: "GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E",
26
- // accesly-contracts Phase 1 deploy on Stellar testnet.
27
- ed25519VerifierAddress: "CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5"
24
+ exports.ENVIRONMENT_DEFAULTS = void 0;
25
+ var init_config = __esm({
26
+ "src/config.ts"() {
27
+ exports.ENVIRONMENT_DEFAULTS = {
28
+ dev: {
29
+ apiUrl: "https://3fki7eiio5.execute-api.us-east-1.amazonaws.com/dev",
30
+ walletStreamUrl: "https://ajlmn37thw7fxen3oyykbfmlrm0eecue.lambda-url.us-east-1.on.aws/",
31
+ cognito: {
32
+ region: "us-east-1",
33
+ userPoolId: "us-east-1_K2Nag1tB1",
34
+ userPoolClientId: "6r64diep7pne50sender4557jt"
35
+ },
36
+ stellar: {
37
+ networkPassphrase: "Test SDF Network ; September 2015",
38
+ horizonUrl: "https://horizon-testnet.stellar.org",
39
+ sorobanRpcUrl: "https://soroban-testnet.stellar.org",
40
+ // OZ Relayer channels-fund — see CloudServices-accesly/docs/Deployed_Resources_dev.md
41
+ deployerAddress: "GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E",
42
+ // accesly-contracts Phase 1 deploy on Stellar testnet.
43
+ ed25519VerifierAddress: "CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5"
44
+ }
45
+ },
46
+ staging: {
47
+ apiUrl: "https://api-staging.accesly.xyz",
48
+ walletStreamUrl: "",
49
+ cognito: {
50
+ region: "us-east-1",
51
+ userPoolId: "TBD-staging",
52
+ userPoolClientId: "TBD-staging"
53
+ },
54
+ stellar: {
55
+ networkPassphrase: "Test SDF Network ; September 2015",
56
+ horizonUrl: "https://horizon-testnet.stellar.org",
57
+ sorobanRpcUrl: "https://soroban-testnet.stellar.org",
58
+ deployerAddress: "GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E",
59
+ ed25519VerifierAddress: "CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5"
60
+ }
61
+ },
62
+ prod: {
63
+ apiUrl: "https://api.accesly.xyz",
64
+ walletStreamUrl: "",
65
+ cognito: {
66
+ region: "us-east-1",
67
+ userPoolId: "TBD-prod",
68
+ userPoolClientId: "TBD-prod"
69
+ },
70
+ stellar: {
71
+ networkPassphrase: "Public Global Stellar Network ; September 2015",
72
+ horizonUrl: "https://horizon.stellar.org",
73
+ sorobanRpcUrl: "https://soroban-rpc.mainnet.stellar.org",
74
+ deployerAddress: "TBD-prod",
75
+ ed25519VerifierAddress: "TBD-prod"
76
+ }
77
+ }
78
+ };
79
+ }
80
+ });
81
+ function isSorobanDeployPendingError(err) {
82
+ if (!(err instanceof core.AccesslyApiError)) return false;
83
+ const haystack = `${err.message ?? ""} ${err.code ?? ""}`.toLowerCase();
84
+ return haystack.includes("txsorobaninvalid") || haystack.includes("soroban sendtransaction") || haystack.includes("soroban submit failed") || haystack.includes("scecexceededlimit") || haystack.includes("exceededlimit");
85
+ }
86
+ var init_sorobanDeployStatus = __esm({
87
+ "src/hooks/sorobanDeployStatus.ts"() {
88
+ }
89
+ });
90
+
91
+ // src/hooks/stellarExpert.ts
92
+ async function fetchContractEvents(contractId, opts) {
93
+ const params = new URLSearchParams();
94
+ params.set("limit", String(opts.limit ?? 50));
95
+ params.set("order", opts.order ?? "desc");
96
+ if (opts.cursor) params.set("cursor", opts.cursor);
97
+ if (opts.topics) params.set("topics", opts.topics);
98
+ const url = `${SE_BASE}/${opts.network}/contract/${contractId}/events?${params.toString()}`;
99
+ const res = await fetch(url, opts.signal ? { signal: opts.signal } : {});
100
+ if (!res.ok) {
101
+ throw new Error(`StellarExpert ${res.status} ${res.statusText}`);
102
+ }
103
+ return await res.json();
104
+ }
105
+ async function fetchContractMeta(contractId, network, signal) {
106
+ const url = `${SE_BASE}/${network}/contract/${contractId}`;
107
+ try {
108
+ const res = await fetch(url, signal ? { signal } : {});
109
+ if (!res.ok) return null;
110
+ return await res.json();
111
+ } catch {
112
+ return null;
113
+ }
114
+ }
115
+ function decodeTransferAmount(bodyXdr) {
116
+ if (!bodyXdr) return "0";
117
+ try {
118
+ const bytes = base64ToBytes(bodyXdr);
119
+ if (bytes.length < 20) return "0";
120
+ let hi = 0n;
121
+ for (let i = 8; i < 16; i += 1) hi = hi << 8n | BigInt(bytes[i] ?? 0);
122
+ let lo = 0n;
123
+ for (let i = 16; i < 24; i += 1) lo = lo << 8n | BigInt(bytes[i] ?? 0);
124
+ const value = hi << 64n | lo;
125
+ return value.toString();
126
+ } catch {
127
+ return "0";
128
+ }
129
+ }
130
+ function base64ToBytes(s) {
131
+ if (typeof Buffer !== "undefined") return new Uint8Array(Buffer.from(s, "base64"));
132
+ const bin = globalThis.atob(s);
133
+ const arr = new Uint8Array(bin.length);
134
+ for (let i = 0; i < bin.length; i += 1) arr[i] = bin.charCodeAt(i);
135
+ return arr;
136
+ }
137
+ function decodeSEEvent(ev, walletAddress, xlmSac, txHashByEventId) {
138
+ const t0 = ev.topics[0];
139
+ if (!t0) return null;
140
+ const timestamp = new Date(ev.ts * 1e3).toISOString();
141
+ const txHash = txHashByEventId.get(ev.id) ?? ev.id.split("-")[0] ?? "";
142
+ if (ev.contract === walletAddress) {
143
+ if (t0 === "signer_rotated") {
144
+ return {
145
+ type: "signer-rotated",
146
+ txHash,
147
+ ledger: ev.ts,
148
+ // SE no expone ledger directamente — usamos timestamp
149
+ timestamp,
150
+ newOwnerEd25519Hex: ""
151
+ };
28
152
  }
29
- },
30
- staging: {
31
- apiUrl: "https://api-staging.accesly.xyz",
32
- walletStreamUrl: "",
33
- cognito: {
34
- region: "us-east-1",
35
- userPoolId: "TBD-staging",
36
- userPoolClientId: "TBD-staging"
37
- },
38
- stellar: {
39
- networkPassphrase: "Test SDF Network ; September 2015",
40
- horizonUrl: "https://horizon-testnet.stellar.org",
41
- sorobanRpcUrl: "https://soroban-testnet.stellar.org",
42
- deployerAddress: "GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E",
43
- ed25519VerifierAddress: "CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5"
153
+ return null;
154
+ }
155
+ if (ev.contract === xlmSac && t0 === "transfer") {
156
+ const from = ev.topics[1];
157
+ const to = ev.topics[2];
158
+ if (!from || !to) return null;
159
+ const amountStroops = decodeTransferAmount(ev.bodyXdr);
160
+ if (from === walletAddress && to !== walletAddress) {
161
+ return {
162
+ type: "transfer-out",
163
+ txHash,
164
+ ledger: ev.ts,
165
+ timestamp,
166
+ to,
167
+ amountStroops
168
+ };
44
169
  }
45
- },
46
- prod: {
47
- apiUrl: "https://api.accesly.xyz",
48
- walletStreamUrl: "",
49
- cognito: {
50
- region: "us-east-1",
51
- userPoolId: "TBD-prod",
52
- userPoolClientId: "TBD-prod"
53
- },
54
- stellar: {
55
- networkPassphrase: "Public Global Stellar Network ; September 2015",
56
- horizonUrl: "https://horizon.stellar.org",
57
- sorobanRpcUrl: "https://soroban-rpc.mainnet.stellar.org",
58
- deployerAddress: "TBD-prod",
59
- ed25519VerifierAddress: "TBD-prod"
170
+ if (to === walletAddress && from !== walletAddress) {
171
+ return {
172
+ type: "transfer-in",
173
+ txHash,
174
+ ledger: ev.ts,
175
+ timestamp,
176
+ from,
177
+ amountStroops
178
+ };
60
179
  }
61
180
  }
62
- };
63
- function AcceslyProvider(props) {
64
- const defaults = ENVIRONMENT_DEFAULTS[props.env];
65
- const apiUrl = props.apiUrl ?? defaults.apiUrl;
66
- const cognitoConfig = props.cognitoConfig ?? defaults.cognito;
67
- const telemetry = props.telemetry;
68
- const instances = react.useMemo(() => {
69
- const authClient = props.overrides?.authClient ?? new core.CognitoAuthClient(cognitoConfig);
70
- const sessionStorage = props.overrides?.sessionStorage ?? core.defaultSessionStorage();
71
- const deviceStore = props.overrides?.deviceStore ?? new core.InMemoryDeviceStore();
72
- const tokenManager = new core.TokenManager({ authClient, storage: sessionStorage });
73
- const apiClient = new core.AccesslyApiClient({
74
- baseUrl: apiUrl,
75
- getIdToken: () => tokenManager.getValidIdToken(),
76
- ...telemetry ? { telemetry } : {}
77
- });
78
- const endpoints = new core.AccesslyEndpoints(apiClient);
79
- return { authClient, sessionStorage, deviceStore, tokenManager, endpoints };
80
- }, [
81
- apiUrl,
82
- cognitoConfig.region,
83
- cognitoConfig.userPoolId,
84
- cognitoConfig.userPoolClientId,
85
- props.overrides?.authClient,
86
- props.overrides?.sessionStorage,
87
- props.overrides?.deviceStore
181
+ return null;
182
+ }
183
+ async function fetchWalletHistory(walletAddress, opts) {
184
+ const xlmSac = opts.network === "mainnet" ? XLM_SAC_MAINNET : XLM_SAC_TESTNET;
185
+ const limit = 50;
186
+ const transferLimit = opts.transferScanLimit ?? 50;
187
+ const [smartAccountResp, transfersResp] = await Promise.all([
188
+ fetchContractEvents(walletAddress, {
189
+ network: opts.network,
190
+ limit,
191
+ order: "desc",
192
+ ...opts.smartAccountCursor ? { cursor: opts.smartAccountCursor } : {},
193
+ ...opts.signal ? { signal: opts.signal } : {}
194
+ }).catch((err) => {
195
+ console.warn("[stellarExpert] smart account events failed", err);
196
+ return { _embedded: { records: [] } };
197
+ }),
198
+ fetchContractEvents(xlmSac, {
199
+ network: opts.network,
200
+ limit: transferLimit,
201
+ order: "desc",
202
+ topics: "transfer",
203
+ ...opts.signal ? { signal: opts.signal } : {}
204
+ }).catch((err) => {
205
+ console.warn("[stellarExpert] xlm sac events failed", err);
206
+ return { _embedded: { records: [] } };
207
+ })
88
208
  ]);
89
- const [status, setStatus] = react.useState(() => initialStatus(instances.sessionStorage));
90
- const [username, setUsername] = react.useState(
91
- () => initialUsername(instances.sessionStorage)
92
- );
93
- const mountedRef = react.useRef(true);
94
- const refreshStatus = react.useCallback(async () => {
95
- const next = await instances.tokenManager.getStatus();
96
- const tokens = await Promise.resolve(instances.sessionStorage.load());
97
- if (mountedRef.current) {
98
- setStatus(next);
99
- setUsername(tokens?.username ?? null);
209
+ const txHashByEventId = /* @__PURE__ */ new Map();
210
+ const items = [];
211
+ const saRecords = smartAccountResp._embedded?.records ?? [];
212
+ const txRecords = transfersResp._embedded?.records ?? [];
213
+ for (const ev of saRecords) {
214
+ const decoded = decodeSEEvent(ev, walletAddress, xlmSac, txHashByEventId);
215
+ if (decoded) items.push(decoded);
216
+ }
217
+ for (const ev of txRecords) {
218
+ const decoded = decodeSEEvent(ev, walletAddress, xlmSac, txHashByEventId);
219
+ if (decoded) items.push(decoded);
220
+ }
221
+ if (!opts.smartAccountCursor) {
222
+ const meta = await fetchContractMeta(walletAddress, opts.network, opts.signal);
223
+ if (meta) {
224
+ items.push({
225
+ type: "wallet-created",
226
+ txHash: "",
227
+ ledger: meta.created,
228
+ timestamp: new Date(meta.created * 1e3).toISOString()
229
+ });
100
230
  }
101
- }, [instances]);
231
+ }
232
+ items.sort((a, b) => (b.ledger ?? 0) - (a.ledger ?? 0));
233
+ return {
234
+ items,
235
+ cursors: {
236
+ smartAccount: extractCursor(smartAccountResp),
237
+ transfers: extractCursor(transfersResp)
238
+ }
239
+ };
240
+ }
241
+ function extractCursor(resp) {
242
+ const records = resp._embedded?.records;
243
+ if (!records || records.length === 0) return null;
244
+ return records[records.length - 1]?.paging_token ?? records[records.length - 1]?.id ?? null;
245
+ }
246
+ var SE_BASE, XLM_SAC_TESTNET, XLM_SAC_MAINNET;
247
+ var init_stellarExpert = __esm({
248
+ "src/hooks/stellarExpert.ts"() {
249
+ SE_BASE = "https://api.stellar.expert/explorer";
250
+ XLM_SAC_TESTNET = "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC";
251
+ XLM_SAC_MAINNET = "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA";
252
+ }
253
+ });
254
+
255
+ // src/hooks/useWalletHistory.ts
256
+ var useWalletHistory_exports = {};
257
+ __export(useWalletHistory_exports, {
258
+ historyClearOptimistic: () => historyClearOptimistic,
259
+ historyOptimisticPush: () => historyOptimisticPush,
260
+ useWalletHistory: () => useWalletHistory
261
+ });
262
+ function useStableRef(value) {
263
+ const ref = react.useRef(value);
264
+ ref.current = value;
265
+ return ref;
266
+ }
267
+ function loadCache(walletAddress) {
268
+ if (typeof localStorage === "undefined") return null;
269
+ try {
270
+ const raw = localStorage.getItem(CACHE_KEY_PREFIX + walletAddress);
271
+ if (!raw) return null;
272
+ const parsed = JSON.parse(raw);
273
+ if (Date.now() - parsed.storedAt > CACHE_TTL_MS) return null;
274
+ return parsed;
275
+ } catch {
276
+ return null;
277
+ }
278
+ }
279
+ function saveCache(walletAddress, entry) {
280
+ if (typeof localStorage === "undefined") return;
281
+ try {
282
+ localStorage.setItem(CACHE_KEY_PREFIX + walletAddress, JSON.stringify(entry));
283
+ } catch {
284
+ }
285
+ }
286
+ function historyOptimisticPush(walletAddress, item) {
287
+ const current = optimisticItems.get(walletAddress) ?? [];
288
+ optimisticItems.set(walletAddress, [item, ...current]);
289
+ const listeners = optimisticListeners.get(walletAddress);
290
+ if (listeners) {
291
+ for (const fn of listeners) fn(optimisticItems.get(walletAddress) ?? []);
292
+ }
293
+ }
294
+ function historyClearOptimistic(walletAddress) {
295
+ optimisticItems.delete(walletAddress);
296
+ const listeners = optimisticListeners.get(walletAddress);
297
+ if (listeners) {
298
+ for (const fn of listeners) fn([]);
299
+ }
300
+ }
301
+ function subscribeOptimistic(walletAddress, listener) {
302
+ let set = optimisticListeners.get(walletAddress);
303
+ if (!set) {
304
+ set = /* @__PURE__ */ new Set();
305
+ optimisticListeners.set(walletAddress, set);
306
+ }
307
+ set.add(listener);
308
+ return () => {
309
+ set?.delete(listener);
310
+ if (set && set.size === 0) optimisticListeners.delete(walletAddress);
311
+ };
312
+ }
313
+ function useWalletHistory(walletAddress, opts = {}) {
314
+ const { wallet, _internal } = useAccesly();
315
+ const username = _internal.username;
316
+ const network = opts.network ?? inferNetwork(_internal.env);
317
+ const [resolvedAddress, setResolvedAddress] = react.useState(walletAddress ?? null);
318
+ const [events, setEvents] = react.useState([]);
319
+ const [optimistic, setOptimistic] = react.useState([]);
320
+ const [cursors, setCursors] = react.useState({
321
+ smartAccount: null,
322
+ transfers: null
323
+ });
324
+ const [isLoading, setIsLoading] = react.useState(true);
325
+ const [error, setError] = react.useState(null);
326
+ const [hasMore, setHasMore] = react.useState(true);
327
+ const walletRef = useStableRef(wallet);
102
328
  react.useEffect(() => {
103
- mountedRef.current = true;
104
- void refreshStatus();
329
+ if (walletAddress) {
330
+ setResolvedAddress(walletAddress);
331
+ return;
332
+ }
333
+ if (!username) {
334
+ setResolvedAddress(null);
335
+ return;
336
+ }
337
+ let cancelled = false;
338
+ void (async () => {
339
+ try {
340
+ const stored = await walletRef.current.getStoredCredential(username);
341
+ if (cancelled) return;
342
+ setResolvedAddress(stored?.walletAddress ?? null);
343
+ } catch {
344
+ if (!cancelled) setResolvedAddress(null);
345
+ }
346
+ })();
105
347
  return () => {
106
- mountedRef.current = false;
348
+ cancelled = true;
107
349
  };
108
- }, [instances]);
109
- const value = react.useMemo(
110
- () => ({
111
- appId: props.appId,
112
- env: props.env,
113
- apiUrl,
114
- cognitoConfig,
115
- authClient: instances.authClient,
116
- sessionStorage: instances.sessionStorage,
117
- tokenManager: instances.tokenManager,
118
- endpoints: instances.endpoints,
119
- deviceStore: instances.deviceStore,
120
- status,
121
- username,
122
- refreshStatus
123
- }),
124
- [props.appId, props.env, apiUrl, cognitoConfig, instances, status, username, refreshStatus]
125
- );
126
- return /* @__PURE__ */ jsxRuntime.jsx(AcceslyContext.Provider, { value, children: props.children });
350
+ }, [walletAddress, username, walletRef]);
351
+ react.useEffect(() => {
352
+ if (!resolvedAddress) return void 0;
353
+ setOptimistic(optimisticItems.get(resolvedAddress) ?? []);
354
+ return subscribeOptimistic(resolvedAddress, setOptimistic);
355
+ }, [resolvedAddress]);
356
+ react.useEffect(() => {
357
+ if (!resolvedAddress) {
358
+ setIsLoading(false);
359
+ return void 0;
360
+ }
361
+ const cached = loadCache(resolvedAddress);
362
+ if (cached) {
363
+ setEvents(cached.items);
364
+ setCursors(cached.cursors);
365
+ setIsLoading(false);
366
+ }
367
+ let cancelled = false;
368
+ const channel = typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(BROADCAST_CHANNEL_PREFIX + resolvedAddress) : null;
369
+ if (channel) {
370
+ channel.onmessage = (ev) => {
371
+ const data = ev.data;
372
+ if (data && !cancelled) {
373
+ setEvents(data.items);
374
+ setCursors(data.cursors);
375
+ setIsLoading(false);
376
+ }
377
+ };
378
+ }
379
+ void (async () => {
380
+ try {
381
+ const result = await fetchWalletHistory(resolvedAddress, {
382
+ network,
383
+ ...opts.transferScanLimit ? { transferScanLimit: opts.transferScanLimit } : {}
384
+ });
385
+ if (cancelled) return;
386
+ const deduped = dedupItems(result.items);
387
+ setEvents(deduped);
388
+ setCursors(result.cursors);
389
+ setIsLoading(false);
390
+ setError(null);
391
+ setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);
392
+ const entry = {
393
+ items: deduped,
394
+ cursors: result.cursors,
395
+ storedAt: Date.now()
396
+ };
397
+ saveCache(resolvedAddress, entry);
398
+ channel?.postMessage(entry);
399
+ } catch (err) {
400
+ if (!cancelled) {
401
+ setError(err);
402
+ setIsLoading(false);
403
+ }
404
+ }
405
+ })();
406
+ return () => {
407
+ cancelled = true;
408
+ channel?.close();
409
+ };
410
+ }, [resolvedAddress, network, opts.transferScanLimit]);
411
+ const interval = opts.pollIntervalMs ?? POLL_INTERVAL_MS;
412
+ react.useEffect(() => {
413
+ if (!resolvedAddress || interval === 0) return void 0;
414
+ const tick = async () => {
415
+ if (typeof document !== "undefined" && document.hidden) return;
416
+ try {
417
+ const result = await fetchWalletHistory(resolvedAddress, {
418
+ network,
419
+ ...opts.transferScanLimit ? { transferScanLimit: opts.transferScanLimit } : {}
420
+ });
421
+ setEvents((prev) => mergeAndDedup(prev, result.items));
422
+ if (resolvedAddress) {
423
+ const realTxHashes = new Set(result.items.map((it) => it.txHash));
424
+ const optimisticsRemaining = (optimisticItems.get(resolvedAddress) ?? []).filter(
425
+ (it) => !realTxHashes.has(it.txHash)
426
+ );
427
+ if (optimisticsRemaining.length !== (optimisticItems.get(resolvedAddress)?.length ?? 0)) {
428
+ optimisticItems.set(resolvedAddress, optimisticsRemaining);
429
+ const listeners = optimisticListeners.get(resolvedAddress);
430
+ if (listeners) for (const fn of listeners) fn(optimisticsRemaining);
431
+ }
432
+ }
433
+ } catch {
434
+ }
435
+ };
436
+ const id = setInterval(tick, interval);
437
+ return () => clearInterval(id);
438
+ }, [resolvedAddress, network, interval]);
439
+ const loadMoreImpl = react.useCallback(async () => {
440
+ if (!resolvedAddress) return;
441
+ if (!cursors.smartAccount && !cursors.transfers) {
442
+ setHasMore(false);
443
+ return;
444
+ }
445
+ try {
446
+ const result = await fetchWalletHistory(resolvedAddress, {
447
+ network,
448
+ ...cursors.smartAccount ? { smartAccountCursor: cursors.smartAccount } : {},
449
+ ...opts.transferScanLimit ? { transferScanLimit: opts.transferScanLimit } : {}
450
+ });
451
+ setEvents((prev) => mergeAndDedup(prev, result.items));
452
+ setCursors(result.cursors);
453
+ setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);
454
+ } catch (err) {
455
+ setError(err);
456
+ }
457
+ }, [resolvedAddress, network, cursors, opts.transferScanLimit]);
458
+ const refreshImpl = react.useCallback(async () => {
459
+ if (!resolvedAddress) return;
460
+ setIsLoading(true);
461
+ try {
462
+ const result = await fetchWalletHistory(resolvedAddress, {
463
+ network,
464
+ ...opts.transferScanLimit ? { transferScanLimit: opts.transferScanLimit } : {}
465
+ });
466
+ const deduped = dedupItems(result.items);
467
+ setEvents(deduped);
468
+ setCursors(result.cursors);
469
+ setError(null);
470
+ saveCache(resolvedAddress, {
471
+ items: deduped,
472
+ cursors: result.cursors,
473
+ storedAt: Date.now()
474
+ });
475
+ } catch (err) {
476
+ setError(err);
477
+ } finally {
478
+ setIsLoading(false);
479
+ }
480
+ }, [resolvedAddress, network, opts.transferScanLimit]);
481
+ const combined = [...optimistic, ...events];
482
+ return {
483
+ events: combined,
484
+ isLoading,
485
+ error,
486
+ hasMore,
487
+ loadMore: loadMoreImpl,
488
+ refresh: refreshImpl
489
+ };
127
490
  }
128
- function initialStatus(storage) {
129
- const tokens = storage.load();
130
- if (tokens instanceof Promise) return "bootstrapping";
131
- if (!tokens) return "anonymous";
132
- return Date.now() + 5 * 60 * 1e3 >= tokens.expiresAt ? "expired" : "authenticated";
491
+ function inferNetwork(env) {
492
+ return env === "prod" ? "mainnet" : "testnet";
133
493
  }
134
- function initialUsername(storage) {
135
- const tokens = storage.load();
136
- if (tokens instanceof Promise) return null;
137
- return tokens?.username ?? null;
494
+ function dedupItems(items) {
495
+ const seen = /* @__PURE__ */ new Set();
496
+ const out = [];
497
+ for (const item of items) {
498
+ const key = `${item.type}:${item.txHash}:${item.ledger}`;
499
+ if (seen.has(key)) continue;
500
+ seen.add(key);
501
+ out.push(item);
502
+ }
503
+ out.sort((a, b) => (b.ledger ?? 0) - (a.ledger ?? 0));
504
+ return out;
138
505
  }
139
- function isSorobanDeployPendingError(err) {
140
- if (!(err instanceof core.AccesslyApiError)) return false;
141
- const haystack = `${err.message ?? ""} ${err.code ?? ""}`.toLowerCase();
142
- return haystack.includes("txsorobaninvalid") || haystack.includes("soroban sendtransaction") || haystack.includes("soroban submit failed") || haystack.includes("scecexceededlimit") || haystack.includes("exceededlimit");
506
+ function mergeAndDedup(prev, fresh) {
507
+ return dedupItems([...fresh, ...prev]);
143
508
  }
144
-
145
- // src/hooks/useAccesly.ts
146
- var NotImplementedYetError = class extends Error {
147
- constructor(namespace, method) {
148
- super(
149
- `${namespace}.${method}() is not implemented yet. This namespace ships in a later release; see docs/Handoff_Fase7.md for the roadmap.`
150
- );
151
- this.name = "NotImplementedYetError";
509
+ var POLL_INTERVAL_MS, CACHE_TTL_MS, CACHE_KEY_PREFIX, BROADCAST_CHANNEL_PREFIX, optimisticItems, optimisticListeners;
510
+ var init_useWalletHistory = __esm({
511
+ "src/hooks/useWalletHistory.ts"() {
512
+ init_useAccesly();
513
+ init_stellarExpert();
514
+ POLL_INTERVAL_MS = 3e4;
515
+ CACHE_TTL_MS = 12 * 60 * 60 * 1e3;
516
+ CACHE_KEY_PREFIX = "accesly:history:";
517
+ BROADCAST_CHANNEL_PREFIX = "accesly:history:";
518
+ optimisticItems = /* @__PURE__ */ new Map();
519
+ optimisticListeners = /* @__PURE__ */ new Map();
152
520
  }
153
- };
521
+ });
154
522
  function useAccesly() {
155
- const ctx = react.useContext(AcceslyContext);
523
+ const ctx = react.useContext(exports.AcceslyContext);
156
524
  if (!ctx) {
157
525
  throw new Error(
158
526
  "useAccesly: missing <AcceslyProvider>. Wrap your app with <AcceslyProvider appId env>."
@@ -184,7 +552,7 @@ function useAccesly() {
184
552
  [ctx]
185
553
  );
186
554
  const { hexToBytes, hexFromBytes } = react.useMemo(() => coderHelpers(), []);
187
- const stellarConfig = ENVIRONMENT_DEFAULTS[ctx.env].stellar;
555
+ const stellarConfig = exports.ENVIRONMENT_DEFAULTS[ctx.env].stellar;
188
556
  const wallet = react.useMemo(() => {
189
557
  const c = ctx;
190
558
  const postWallet = async (params) => {
@@ -615,8 +983,8 @@ function useAccesly() {
615
983
  const sessionPlaintext = core.unwrapSessionFragment2(wrappedF2, ephemeral.privateKey).plaintext;
616
984
  const fragmentF2Wire = JSON.parse(new TextDecoder().decode(sessionPlaintext));
617
985
  const fragmentF2Envelope = {
618
- nonce: base64ToBytes(fragmentF2Wire.nonce),
619
- ciphertext: base64ToBytes(fragmentF2Wire.ciphertext)
986
+ nonce: base64ToBytes2(fragmentF2Wire.nonce),
987
+ ciphertext: base64ToBytes2(fragmentF2Wire.ciphertext)
620
988
  };
621
989
  const reconstructed = core.reconstructFromPlainAndEncrypted({
622
990
  fragmentF1Plain: input.fragmentF1Plain,
@@ -634,6 +1002,24 @@ function useAccesly() {
634
1002
  unsignedXdr: sim.unsignedXdr,
635
1003
  signedAuthEntryXdr
636
1004
  });
1005
+ try {
1006
+ const username = ctx.username;
1007
+ if (username) {
1008
+ const stored = await ctx.deviceStore.loadCredential(username);
1009
+ if (stored?.walletAddress) {
1010
+ const { historyOptimisticPush: historyOptimisticPush2 } = await Promise.resolve().then(() => (init_useWalletHistory(), useWalletHistory_exports));
1011
+ historyOptimisticPush2(stored.walletAddress, {
1012
+ type: "transfer-out",
1013
+ txHash: submit.txHash,
1014
+ ledger: Math.floor(Date.now() / 1e3),
1015
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1016
+ to: input.destinationAddress,
1017
+ amountStroops: input.amountStroops
1018
+ });
1019
+ }
1020
+ }
1021
+ } catch {
1022
+ }
637
1023
  return {
638
1024
  txHash: submit.txHash,
639
1025
  status: submit.status,
@@ -677,18 +1063,18 @@ function useAccesly() {
677
1063
  "recovery.reconstructSeed: la wallet fue creada antes de Fase 1 y no tiene F2 cipher-bound a recoveryKey. No es recuperable v\xEDa OTP."
678
1064
  );
679
1065
  }
680
- const recoverySalt = base64ToBytes(frag.recoverySalt);
1066
+ const recoverySalt = base64ToBytes2(frag.recoverySalt);
681
1067
  const recoveryKey = core.deriveRecoveryKey({
682
1068
  password: input.cognitoPassword,
683
1069
  salt: recoverySalt
684
1070
  });
685
1071
  const f2Envelope = {
686
- ciphertext: base64ToBytes(frag.fragmentF2Recovery.ciphertext),
687
- nonce: base64ToBytes(frag.fragmentF2Recovery.nonce)
1072
+ ciphertext: base64ToBytes2(frag.fragmentF2Recovery.ciphertext),
1073
+ nonce: base64ToBytes2(frag.fragmentF2Recovery.nonce)
688
1074
  };
689
1075
  const f3Envelope = {
690
- ciphertext: base64ToBytes(frag.fragmentF3Encrypted.ciphertext),
691
- nonce: base64ToBytes(frag.fragmentF3Encrypted.nonce)
1076
+ ciphertext: base64ToBytes2(frag.fragmentF3Encrypted.ciphertext),
1077
+ nonce: base64ToBytes2(frag.fragmentF3Encrypted.nonce)
692
1078
  };
693
1079
  const seedResult = core.reconstructKey({
694
1080
  fragments: [
@@ -851,10 +1237,10 @@ function useAccesly() {
851
1237
  const session = react.useMemo(
852
1238
  () => ({
853
1239
  async create() {
854
- throw new NotImplementedYetError("session", "create");
1240
+ throw new exports.NotImplementedYetError("session", "create");
855
1241
  },
856
1242
  async revoke() {
857
- throw new NotImplementedYetError("session", "revoke");
1243
+ throw new exports.NotImplementedYetError("session", "revoke");
858
1244
  }
859
1245
  }),
860
1246
  []
@@ -862,16 +1248,16 @@ function useAccesly() {
862
1248
  const settings = react.useMemo(
863
1249
  () => ({
864
1250
  async addDevice() {
865
- throw new NotImplementedYetError("settings", "addDevice");
1251
+ throw new exports.NotImplementedYetError("settings", "addDevice");
866
1252
  },
867
1253
  async removeDevice() {
868
- throw new NotImplementedYetError("settings", "removeDevice");
1254
+ throw new exports.NotImplementedYetError("settings", "removeDevice");
869
1255
  },
870
1256
  async listDevices() {
871
- throw new NotImplementedYetError("settings", "listDevices");
1257
+ throw new exports.NotImplementedYetError("settings", "listDevices");
872
1258
  },
873
1259
  async updateSpendingLimit() {
874
- throw new NotImplementedYetError("settings", "updateSpendingLimit");
1260
+ throw new exports.NotImplementedYetError("settings", "updateSpendingLimit");
875
1261
  }
876
1262
  }),
877
1263
  []
@@ -879,13 +1265,13 @@ function useAccesly() {
879
1265
  const yieldOps = react.useMemo(
880
1266
  () => ({
881
1267
  async invest() {
882
- throw new NotImplementedYetError("yield", "invest");
1268
+ throw new exports.NotImplementedYetError("yield", "invest");
883
1269
  },
884
1270
  async redeem() {
885
- throw new NotImplementedYetError("yield", "redeem");
1271
+ throw new exports.NotImplementedYetError("yield", "redeem");
886
1272
  },
887
1273
  async position() {
888
- throw new NotImplementedYetError("yield", "position");
1274
+ throw new exports.NotImplementedYetError("yield", "position");
889
1275
  }
890
1276
  }),
891
1277
  []
@@ -924,13 +1310,118 @@ function base64FromBytes(bytes) {
924
1310
  for (let i = 0; i < bytes.length; i += 1) bin += String.fromCharCode(bytes[i] ?? 0);
925
1311
  return globalThis.btoa(bin);
926
1312
  }
927
- function base64ToBytes(s) {
1313
+ function base64ToBytes2(s) {
928
1314
  if (typeof Buffer !== "undefined") return new Uint8Array(Buffer.from(s, "base64"));
929
1315
  const bin = globalThis.atob(s);
930
1316
  const arr = new Uint8Array(bin.length);
931
1317
  for (let i = 0; i < bin.length; i += 1) arr[i] = bin.charCodeAt(i);
932
1318
  return arr;
933
1319
  }
1320
+ exports.NotImplementedYetError = void 0;
1321
+ var init_useAccesly = __esm({
1322
+ "src/hooks/useAccesly.ts"() {
1323
+ init_context();
1324
+ init_config();
1325
+ init_sorobanDeployStatus();
1326
+ exports.NotImplementedYetError = class extends Error {
1327
+ constructor(namespace, method) {
1328
+ super(
1329
+ `${namespace}.${method}() is not implemented yet. This namespace ships in a later release; see docs/Handoff_Fase7.md for the roadmap.`
1330
+ );
1331
+ this.name = "NotImplementedYetError";
1332
+ }
1333
+ };
1334
+ }
1335
+ });
1336
+
1337
+ // src/provider.tsx
1338
+ init_context();
1339
+ init_config();
1340
+ function AcceslyProvider(props) {
1341
+ const defaults = exports.ENVIRONMENT_DEFAULTS[props.env];
1342
+ const apiUrl = props.apiUrl ?? defaults.apiUrl;
1343
+ const cognitoConfig = props.cognitoConfig ?? defaults.cognito;
1344
+ const telemetry = props.telemetry;
1345
+ const instances = react.useMemo(() => {
1346
+ const authClient = props.overrides?.authClient ?? new core.CognitoAuthClient(cognitoConfig);
1347
+ const sessionStorage = props.overrides?.sessionStorage ?? core.defaultSessionStorage();
1348
+ const deviceStore = props.overrides?.deviceStore ?? new core.InMemoryDeviceStore();
1349
+ const tokenManager = new core.TokenManager({ authClient, storage: sessionStorage });
1350
+ const apiClient = new core.AccesslyApiClient({
1351
+ baseUrl: apiUrl,
1352
+ getIdToken: () => tokenManager.getValidIdToken(),
1353
+ ...telemetry ? { telemetry } : {}
1354
+ });
1355
+ const endpoints = new core.AccesslyEndpoints(apiClient);
1356
+ return { authClient, sessionStorage, deviceStore, tokenManager, endpoints };
1357
+ }, [
1358
+ apiUrl,
1359
+ cognitoConfig.region,
1360
+ cognitoConfig.userPoolId,
1361
+ cognitoConfig.userPoolClientId,
1362
+ props.overrides?.authClient,
1363
+ props.overrides?.sessionStorage,
1364
+ props.overrides?.deviceStore
1365
+ ]);
1366
+ const [status, setStatus] = react.useState(() => initialStatus(instances.sessionStorage));
1367
+ const [username, setUsername] = react.useState(
1368
+ () => initialUsername(instances.sessionStorage)
1369
+ );
1370
+ const mountedRef = react.useRef(true);
1371
+ const refreshStatus = react.useCallback(async () => {
1372
+ const next = await instances.tokenManager.getStatus();
1373
+ const tokens = await Promise.resolve(instances.sessionStorage.load());
1374
+ if (mountedRef.current) {
1375
+ setStatus(next);
1376
+ setUsername(tokens?.username ?? null);
1377
+ }
1378
+ }, [instances]);
1379
+ react.useEffect(() => {
1380
+ mountedRef.current = true;
1381
+ void refreshStatus();
1382
+ return () => {
1383
+ mountedRef.current = false;
1384
+ };
1385
+ }, [instances]);
1386
+ const value = react.useMemo(
1387
+ () => ({
1388
+ appId: props.appId,
1389
+ env: props.env,
1390
+ apiUrl,
1391
+ cognitoConfig,
1392
+ authClient: instances.authClient,
1393
+ sessionStorage: instances.sessionStorage,
1394
+ tokenManager: instances.tokenManager,
1395
+ endpoints: instances.endpoints,
1396
+ deviceStore: instances.deviceStore,
1397
+ status,
1398
+ username,
1399
+ refreshStatus
1400
+ }),
1401
+ [props.appId, props.env, apiUrl, cognitoConfig, instances, status, username, refreshStatus]
1402
+ );
1403
+ return /* @__PURE__ */ jsxRuntime.jsx(exports.AcceslyContext.Provider, { value, children: props.children });
1404
+ }
1405
+ function initialStatus(storage) {
1406
+ const tokens = storage.load();
1407
+ if (tokens instanceof Promise) return "bootstrapping";
1408
+ if (!tokens) return "anonymous";
1409
+ return Date.now() + 5 * 60 * 1e3 >= tokens.expiresAt ? "expired" : "authenticated";
1410
+ }
1411
+ function initialUsername(storage) {
1412
+ const tokens = storage.load();
1413
+ if (tokens instanceof Promise) return null;
1414
+ return tokens?.username ?? null;
1415
+ }
1416
+
1417
+ // src/index.ts
1418
+ init_context();
1419
+ init_config();
1420
+ init_useAccesly();
1421
+
1422
+ // src/hooks/useWalletStatus.ts
1423
+ init_useAccesly();
1424
+ init_config();
934
1425
 
935
1426
  // src/hooks/walletSubscription.ts
936
1427
  var ACTIVITY_BUFFER_MAX = 50;
@@ -1048,7 +1539,7 @@ function closeAllWalletSubscriptions() {
1048
1539
  // src/hooks/useWalletStatus.ts
1049
1540
  var POLL_BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 3e4];
1050
1541
  var STALE_THRESHOLD_MS = 6e4;
1051
- function useStableRef(value) {
1542
+ function useStableRef2(value) {
1052
1543
  const ref = react.useRef(value);
1053
1544
  ref.current = value;
1054
1545
  return ref;
@@ -1066,9 +1557,9 @@ function useWalletStatus() {
1066
1557
  const [onChain, setOnChain] = react.useState(null);
1067
1558
  const [lastSuccessAt, setLastSuccessAt] = react.useState(0);
1068
1559
  const [isStale, setIsStale] = react.useState(false);
1069
- const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];
1560
+ const envDefaults = exports.ENVIRONMENT_DEFAULTS[_internal.env];
1070
1561
  const streamUrl = envDefaults.walletStreamUrl;
1071
- const walletRef = useStableRef(wallet);
1562
+ const walletRef = useStableRef2(wallet);
1072
1563
  const doFetch = react.useCallback(async () => {
1073
1564
  if (!username) return null;
1074
1565
  try {
@@ -1092,7 +1583,7 @@ function useWalletStatus() {
1092
1583
  return null;
1093
1584
  }
1094
1585
  }, [username, walletRef]);
1095
- const doFetchRef = useStableRef(doFetch);
1586
+ const doFetchRef = useStableRef2(doFetch);
1096
1587
  react.useEffect(() => {
1097
1588
  if (!username) {
1098
1589
  setStatus("unknown");
@@ -1160,8 +1651,12 @@ function useWalletStatus() {
1160
1651
  }, [doFetchRef]);
1161
1652
  return { status, walletAddress, onChain, isStale, refresh };
1162
1653
  }
1654
+
1655
+ // src/hooks/useBalance.ts
1656
+ init_useAccesly();
1657
+ init_config();
1163
1658
  var POLL_FALLBACK_MS = 1e4;
1164
- function useStableRef2(value) {
1659
+ function useStableRef3(value) {
1165
1660
  const ref = react.useRef(value);
1166
1661
  ref.current = value;
1167
1662
  return ref;
@@ -1176,7 +1671,7 @@ function useBalance(walletAddress) {
1176
1671
  const [xlm, setXlm] = react.useState(null);
1177
1672
  const [isLoading, setIsLoading] = react.useState(true);
1178
1673
  const [error, setError] = react.useState(null);
1179
- const walletRef = useStableRef2(wallet);
1674
+ const walletRef = useStableRef3(wallet);
1180
1675
  react.useEffect(() => {
1181
1676
  if (walletAddress) {
1182
1677
  setResolvedAddress(walletAddress);
@@ -1200,9 +1695,9 @@ function useBalance(walletAddress) {
1200
1695
  cancelled = true;
1201
1696
  };
1202
1697
  }, [walletAddress, username, walletRef]);
1203
- const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];
1698
+ const envDefaults = exports.ENVIRONMENT_DEFAULTS[_internal.env];
1204
1699
  const streamUrl = envDefaults.walletStreamUrl;
1205
- const endpointsRef = useStableRef2(_internal.endpoints);
1700
+ const endpointsRef = useStableRef3(_internal.endpoints);
1206
1701
  const doFetchOnce = react.useCallback(async () => {
1207
1702
  if (!resolvedAddress) return;
1208
1703
  try {
@@ -1216,7 +1711,7 @@ function useBalance(walletAddress) {
1216
1711
  setIsLoading(false);
1217
1712
  }
1218
1713
  }, [resolvedAddress, endpointsRef]);
1219
- const doFetchRef = useStableRef2(doFetchOnce);
1714
+ const doFetchRef = useStableRef3(doFetchOnce);
1220
1715
  react.useEffect(() => {
1221
1716
  if (!resolvedAddress) {
1222
1717
  setIsLoading(false);
@@ -1261,9 +1756,13 @@ function useBalance(walletAddress) {
1261
1756
  }, [doFetchRef]);
1262
1757
  return { stroops, xlm, isLoading, error, refresh };
1263
1758
  }
1759
+
1760
+ // src/hooks/useWalletActivity.ts
1761
+ init_useAccesly();
1762
+ init_config();
1264
1763
  var POLL_FALLBACK_MS2 = 25e3;
1265
1764
  var DEFAULT_LIMIT = 20;
1266
- function useStableRef3(value) {
1765
+ function useStableRef4(value) {
1267
1766
  const ref = react.useRef(value);
1268
1767
  ref.current = value;
1269
1768
  return ref;
@@ -1278,7 +1777,7 @@ function useWalletActivity(walletAddress, opts = {}) {
1278
1777
  const [events, setEvents] = react.useState([]);
1279
1778
  const [isLoading, setIsLoading] = react.useState(true);
1280
1779
  const [error, setError] = react.useState(null);
1281
- const walletRef = useStableRef3(wallet);
1780
+ const walletRef = useStableRef4(wallet);
1282
1781
  react.useEffect(() => {
1283
1782
  if (walletAddress) {
1284
1783
  setResolvedAddress(walletAddress);
@@ -1302,9 +1801,9 @@ function useWalletActivity(walletAddress, opts = {}) {
1302
1801
  cancelled = true;
1303
1802
  };
1304
1803
  }, [walletAddress, username, walletRef]);
1305
- const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];
1804
+ const envDefaults = exports.ENVIRONMENT_DEFAULTS[_internal.env];
1306
1805
  const streamUrl = envDefaults.walletStreamUrl;
1307
- const endpointsRef = useStableRef3(_internal.endpoints);
1806
+ const endpointsRef = useStableRef4(_internal.endpoints);
1308
1807
  const doFetchOnce = react.useCallback(async () => {
1309
1808
  if (!resolvedAddress) return;
1310
1809
  try {
@@ -1322,7 +1821,7 @@ function useWalletActivity(walletAddress, opts = {}) {
1322
1821
  setIsLoading(false);
1323
1822
  }
1324
1823
  }, [resolvedAddress, limit, endpointsRef]);
1325
- const doFetchRef = useStableRef3(doFetchOnce);
1824
+ const doFetchRef = useStableRef4(doFetchOnce);
1326
1825
  react.useEffect(() => {
1327
1826
  if (!resolvedAddress) {
1328
1827
  setIsLoading(false);
@@ -1370,18 +1869,19 @@ function adaptRestEvent(ev) {
1370
1869
  }
1371
1870
 
1372
1871
  // src/index.ts
1872
+ init_useWalletHistory();
1373
1873
  var REACT_ADAPTER_VERSION = "0.0.0";
1374
1874
 
1375
- exports.AcceslyContext = AcceslyContext;
1376
1875
  exports.AcceslyProvider = AcceslyProvider;
1377
- exports.ENVIRONMENT_DEFAULTS = ENVIRONMENT_DEFAULTS;
1378
- exports.NotImplementedYetError = NotImplementedYetError;
1379
1876
  exports.REACT_ADAPTER_VERSION = REACT_ADAPTER_VERSION;
1380
1877
  exports.closeAllWalletSubscriptions = closeAllWalletSubscriptions;
1878
+ exports.historyClearOptimistic = historyClearOptimistic;
1879
+ exports.historyOptimisticPush = historyOptimisticPush;
1381
1880
  exports.subscribeToWalletEvent = subscribeToWalletEvent;
1382
1881
  exports.useAccesly = useAccesly;
1383
1882
  exports.useBalance = useBalance;
1384
1883
  exports.useWalletActivity = useWalletActivity;
1884
+ exports.useWalletHistory = useWalletHistory;
1385
1885
  exports.useWalletStatus = useWalletStatus;
1386
1886
  //# sourceMappingURL=index.cjs.map
1387
1887
  //# sourceMappingURL=index.cjs.map