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