@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.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
|
-
|
|
8
|
-
var
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
104
|
-
|
|
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
|
-
|
|
348
|
+
cancelled = true;
|
|
107
349
|
};
|
|
108
|
-
}, [
|
|
109
|
-
|
|
110
|
-
()
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
|
129
|
-
|
|
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
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
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
|
|
140
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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:
|
|
619
|
-
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 =
|
|
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:
|
|
687
|
-
nonce:
|
|
1072
|
+
ciphertext: base64ToBytes2(frag.fragmentF2Recovery.ciphertext),
|
|
1073
|
+
nonce: base64ToBytes2(frag.fragmentF2Recovery.nonce)
|
|
688
1074
|
};
|
|
689
1075
|
const f3Envelope = {
|
|
690
|
-
ciphertext:
|
|
691
|
-
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|