@accesly/react 1.2.0 → 1.3.1
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 +488 -164
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -6
- package/dist/index.d.ts +61 -6
- package/dist/index.js +473 -149
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,154 +1,346 @@
|
|
|
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/useWalletHistory.ts
|
|
90
|
+
var useWalletHistory_exports = {};
|
|
91
|
+
__export(useWalletHistory_exports, {
|
|
92
|
+
historyClearOptimistic: () => historyClearOptimistic,
|
|
93
|
+
historyOptimisticPush: () => historyOptimisticPush,
|
|
94
|
+
useWalletHistory: () => useWalletHistory
|
|
95
|
+
});
|
|
96
|
+
function useStableRef(value) {
|
|
97
|
+
const ref = useRef(value);
|
|
98
|
+
ref.current = value;
|
|
99
|
+
return ref;
|
|
100
|
+
}
|
|
101
|
+
function loadCache(walletAddress) {
|
|
102
|
+
if (typeof localStorage === "undefined") return null;
|
|
103
|
+
try {
|
|
104
|
+
const raw = localStorage.getItem(CACHE_KEY_PREFIX + walletAddress);
|
|
105
|
+
if (!raw) return null;
|
|
106
|
+
const parsed = JSON.parse(raw);
|
|
107
|
+
if (Date.now() - parsed.storedAt > CACHE_TTL_MS) return null;
|
|
108
|
+
return parsed;
|
|
109
|
+
} catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function saveCache(walletAddress, entry) {
|
|
114
|
+
if (typeof localStorage === "undefined") return;
|
|
115
|
+
try {
|
|
116
|
+
localStorage.setItem(CACHE_KEY_PREFIX + walletAddress, JSON.stringify(entry));
|
|
117
|
+
} catch {
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function historyOptimisticPush(walletAddress, item) {
|
|
121
|
+
const current = optimisticItems.get(walletAddress) ?? [];
|
|
122
|
+
optimisticItems.set(walletAddress, [item, ...current]);
|
|
123
|
+
const listeners = optimisticListeners.get(walletAddress);
|
|
124
|
+
if (listeners) {
|
|
125
|
+
for (const fn of listeners) fn(optimisticItems.get(walletAddress) ?? []);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function historyClearOptimistic(walletAddress) {
|
|
129
|
+
optimisticItems.delete(walletAddress);
|
|
130
|
+
const listeners = optimisticListeners.get(walletAddress);
|
|
131
|
+
if (listeners) {
|
|
132
|
+
for (const fn of listeners) fn([]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function subscribeOptimistic(walletAddress, listener) {
|
|
136
|
+
let set = optimisticListeners.get(walletAddress);
|
|
137
|
+
if (!set) {
|
|
138
|
+
set = /* @__PURE__ */ new Set();
|
|
139
|
+
optimisticListeners.set(walletAddress, set);
|
|
140
|
+
}
|
|
141
|
+
set.add(listener);
|
|
142
|
+
return () => {
|
|
143
|
+
set?.delete(listener);
|
|
144
|
+
if (set && set.size === 0) optimisticListeners.delete(walletAddress);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function useWalletHistory(walletAddress, opts = {}) {
|
|
148
|
+
const { wallet, _internal } = useAccesly();
|
|
149
|
+
const username = _internal.username;
|
|
150
|
+
const [resolvedAddress, setResolvedAddress] = useState(walletAddress ?? null);
|
|
151
|
+
const [events, setEvents] = useState([]);
|
|
152
|
+
const [optimistic, setOptimistic] = useState([]);
|
|
153
|
+
const [cursors, setCursors] = useState({ smartAccount: null, transfers: null });
|
|
154
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
155
|
+
const [error, setError] = useState(null);
|
|
156
|
+
const [hasMore, setHasMore] = useState(true);
|
|
157
|
+
const walletRef = useStableRef(wallet);
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (walletAddress) {
|
|
160
|
+
setResolvedAddress(walletAddress);
|
|
161
|
+
return;
|
|
26
162
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
walletStreamUrl: "",
|
|
31
|
-
cognito: {
|
|
32
|
-
region: "us-east-1",
|
|
33
|
-
userPoolId: "TBD-staging",
|
|
34
|
-
userPoolClientId: "TBD-staging"
|
|
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
|
-
deployerAddress: "GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E",
|
|
41
|
-
ed25519VerifierAddress: "CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5"
|
|
163
|
+
if (!username) {
|
|
164
|
+
setResolvedAddress(null);
|
|
165
|
+
return;
|
|
42
166
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
167
|
+
let cancelled = false;
|
|
168
|
+
void (async () => {
|
|
169
|
+
try {
|
|
170
|
+
const stored = await walletRef.current.getStoredCredential(username);
|
|
171
|
+
if (cancelled) return;
|
|
172
|
+
setResolvedAddress(stored?.walletAddress ?? null);
|
|
173
|
+
} catch {
|
|
174
|
+
if (!cancelled) setResolvedAddress(null);
|
|
175
|
+
}
|
|
176
|
+
})();
|
|
177
|
+
return () => {
|
|
178
|
+
cancelled = true;
|
|
179
|
+
};
|
|
180
|
+
}, [walletAddress, username, walletRef]);
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
if (!resolvedAddress) return void 0;
|
|
183
|
+
setOptimistic(optimisticItems.get(resolvedAddress) ?? []);
|
|
184
|
+
return subscribeOptimistic(resolvedAddress, setOptimistic);
|
|
185
|
+
}, [resolvedAddress]);
|
|
186
|
+
const endpointsRef = useStableRef(_internal.endpoints);
|
|
187
|
+
const transferScanLimit = opts.transferScanLimit ?? 50;
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
if (!resolvedAddress) {
|
|
190
|
+
setIsLoading(false);
|
|
191
|
+
return void 0;
|
|
58
192
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const cognitoConfig = props.cognitoConfig ?? defaults.cognito;
|
|
65
|
-
const telemetry = props.telemetry;
|
|
66
|
-
const instances = useMemo(() => {
|
|
67
|
-
const authClient = props.overrides?.authClient ?? new CognitoAuthClient(cognitoConfig);
|
|
68
|
-
const sessionStorage = props.overrides?.sessionStorage ?? defaultSessionStorage();
|
|
69
|
-
const deviceStore = props.overrides?.deviceStore ?? new InMemoryDeviceStore();
|
|
70
|
-
const tokenManager = new TokenManager({ authClient, storage: sessionStorage });
|
|
71
|
-
const apiClient = new AccesslyApiClient({
|
|
72
|
-
baseUrl: apiUrl,
|
|
73
|
-
getIdToken: () => tokenManager.getValidIdToken(),
|
|
74
|
-
...telemetry ? { telemetry } : {}
|
|
75
|
-
});
|
|
76
|
-
const endpoints = new AccesslyEndpoints(apiClient);
|
|
77
|
-
return { authClient, sessionStorage, deviceStore, tokenManager, endpoints };
|
|
78
|
-
}, [
|
|
79
|
-
apiUrl,
|
|
80
|
-
cognitoConfig.region,
|
|
81
|
-
cognitoConfig.userPoolId,
|
|
82
|
-
cognitoConfig.userPoolClientId,
|
|
83
|
-
props.overrides?.authClient,
|
|
84
|
-
props.overrides?.sessionStorage,
|
|
85
|
-
props.overrides?.deviceStore
|
|
86
|
-
]);
|
|
87
|
-
const [status, setStatus] = useState(() => initialStatus(instances.sessionStorage));
|
|
88
|
-
const [username, setUsername] = useState(
|
|
89
|
-
() => initialUsername(instances.sessionStorage)
|
|
90
|
-
);
|
|
91
|
-
const mountedRef = useRef(true);
|
|
92
|
-
const refreshStatus = useCallback(async () => {
|
|
93
|
-
const next = await instances.tokenManager.getStatus();
|
|
94
|
-
const tokens = await Promise.resolve(instances.sessionStorage.load());
|
|
95
|
-
if (mountedRef.current) {
|
|
96
|
-
setStatus(next);
|
|
97
|
-
setUsername(tokens?.username ?? null);
|
|
193
|
+
const cached = loadCache(resolvedAddress);
|
|
194
|
+
if (cached) {
|
|
195
|
+
setEvents(cached.items);
|
|
196
|
+
setCursors(cached.cursors);
|
|
197
|
+
setIsLoading(false);
|
|
98
198
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
199
|
+
let cancelled = false;
|
|
200
|
+
const channel = typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(BROADCAST_CHANNEL_PREFIX + resolvedAddress) : null;
|
|
201
|
+
if (channel) {
|
|
202
|
+
channel.onmessage = (ev) => {
|
|
203
|
+
const data = ev.data;
|
|
204
|
+
if (data && !cancelled) {
|
|
205
|
+
setEvents(data.items);
|
|
206
|
+
setCursors(data.cursors);
|
|
207
|
+
setIsLoading(false);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
void (async () => {
|
|
212
|
+
try {
|
|
213
|
+
const result = await endpointsRef.current.walletHistory(resolvedAddress, {
|
|
214
|
+
transferScanLimit
|
|
215
|
+
});
|
|
216
|
+
if (cancelled) return;
|
|
217
|
+
const deduped = dedupItems(result.events);
|
|
218
|
+
setEvents(deduped);
|
|
219
|
+
setCursors(result.cursors);
|
|
220
|
+
setIsLoading(false);
|
|
221
|
+
setError(null);
|
|
222
|
+
setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);
|
|
223
|
+
const entry = {
|
|
224
|
+
items: deduped,
|
|
225
|
+
cursors: result.cursors,
|
|
226
|
+
storedAt: Date.now()
|
|
227
|
+
};
|
|
228
|
+
saveCache(resolvedAddress, entry);
|
|
229
|
+
channel?.postMessage(entry);
|
|
230
|
+
} catch (err) {
|
|
231
|
+
if (!cancelled) {
|
|
232
|
+
setError(err);
|
|
233
|
+
setIsLoading(false);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
})();
|
|
103
237
|
return () => {
|
|
104
|
-
|
|
238
|
+
cancelled = true;
|
|
239
|
+
channel?.close();
|
|
105
240
|
};
|
|
106
|
-
}, [
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
241
|
+
}, [resolvedAddress, transferScanLimit, endpointsRef]);
|
|
242
|
+
const interval = opts.pollIntervalMs ?? POLL_INTERVAL_MS;
|
|
243
|
+
useEffect(() => {
|
|
244
|
+
if (!resolvedAddress || interval === 0) return void 0;
|
|
245
|
+
const tick = async () => {
|
|
246
|
+
if (typeof document !== "undefined" && document.hidden) return;
|
|
247
|
+
try {
|
|
248
|
+
const result = await endpointsRef.current.walletHistory(resolvedAddress, {
|
|
249
|
+
transferScanLimit
|
|
250
|
+
});
|
|
251
|
+
setEvents((prev) => mergeAndDedup(prev, result.events));
|
|
252
|
+
const realTxHashes = new Set(result.events.map((it) => it.txHash));
|
|
253
|
+
const current = optimisticItems.get(resolvedAddress) ?? [];
|
|
254
|
+
const remaining = current.filter((it) => !realTxHashes.has(it.txHash));
|
|
255
|
+
if (remaining.length !== current.length) {
|
|
256
|
+
optimisticItems.set(resolvedAddress, remaining);
|
|
257
|
+
const listeners = optimisticListeners.get(resolvedAddress);
|
|
258
|
+
if (listeners) for (const fn of listeners) fn(remaining);
|
|
259
|
+
}
|
|
260
|
+
} catch {
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const id = setInterval(tick, interval);
|
|
264
|
+
return () => clearInterval(id);
|
|
265
|
+
}, [resolvedAddress, interval, transferScanLimit, endpointsRef]);
|
|
266
|
+
const loadMoreImpl = useCallback(async () => {
|
|
267
|
+
if (!resolvedAddress) return;
|
|
268
|
+
if (!cursors.smartAccount && !cursors.transfers) {
|
|
269
|
+
setHasMore(false);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
try {
|
|
273
|
+
const result = await endpointsRef.current.walletHistory(resolvedAddress, {
|
|
274
|
+
...cursors.smartAccount ? { smartAccountCursor: cursors.smartAccount } : {},
|
|
275
|
+
...cursors.transfers ? { transfersCursor: cursors.transfers } : {},
|
|
276
|
+
transferScanLimit
|
|
277
|
+
});
|
|
278
|
+
setEvents((prev) => mergeAndDedup(prev, result.events));
|
|
279
|
+
setCursors(result.cursors);
|
|
280
|
+
setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);
|
|
281
|
+
} catch (err) {
|
|
282
|
+
setError(err);
|
|
283
|
+
}
|
|
284
|
+
}, [resolvedAddress, cursors, transferScanLimit, endpointsRef]);
|
|
285
|
+
const refreshImpl = useCallback(async () => {
|
|
286
|
+
if (!resolvedAddress) return;
|
|
287
|
+
setIsLoading(true);
|
|
288
|
+
try {
|
|
289
|
+
const result = await endpointsRef.current.walletHistory(resolvedAddress, {
|
|
290
|
+
transferScanLimit
|
|
291
|
+
});
|
|
292
|
+
const deduped = dedupItems(result.events);
|
|
293
|
+
setEvents(deduped);
|
|
294
|
+
setCursors(result.cursors);
|
|
295
|
+
setError(null);
|
|
296
|
+
saveCache(resolvedAddress, {
|
|
297
|
+
items: deduped,
|
|
298
|
+
cursors: result.cursors,
|
|
299
|
+
storedAt: Date.now()
|
|
300
|
+
});
|
|
301
|
+
} catch (err) {
|
|
302
|
+
setError(err);
|
|
303
|
+
} finally {
|
|
304
|
+
setIsLoading(false);
|
|
305
|
+
}
|
|
306
|
+
}, [resolvedAddress, transferScanLimit, endpointsRef]);
|
|
307
|
+
const combined = [...optimistic, ...events];
|
|
308
|
+
return {
|
|
309
|
+
events: combined,
|
|
310
|
+
isLoading,
|
|
311
|
+
error,
|
|
312
|
+
hasMore,
|
|
313
|
+
loadMore: loadMoreImpl,
|
|
314
|
+
refresh: refreshImpl
|
|
315
|
+
};
|
|
131
316
|
}
|
|
132
|
-
function
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
317
|
+
function dedupItems(items) {
|
|
318
|
+
const seen = /* @__PURE__ */ new Set();
|
|
319
|
+
const out = [];
|
|
320
|
+
for (const item of items) {
|
|
321
|
+
const key = `${item.type}:${item.txHash}:${item.ledger}`;
|
|
322
|
+
if (seen.has(key)) continue;
|
|
323
|
+
seen.add(key);
|
|
324
|
+
out.push(item);
|
|
325
|
+
}
|
|
326
|
+
out.sort((a, b) => b.ledger - a.ledger);
|
|
327
|
+
return out;
|
|
136
328
|
}
|
|
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");
|
|
329
|
+
function mergeAndDedup(prev, fresh) {
|
|
330
|
+
return dedupItems([...fresh, ...prev]);
|
|
141
331
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
332
|
+
var POLL_INTERVAL_MS, CACHE_TTL_MS, CACHE_KEY_PREFIX, BROADCAST_CHANNEL_PREFIX, optimisticItems, optimisticListeners;
|
|
333
|
+
var init_useWalletHistory = __esm({
|
|
334
|
+
"src/hooks/useWalletHistory.ts"() {
|
|
335
|
+
init_useAccesly();
|
|
336
|
+
POLL_INTERVAL_MS = 3e4;
|
|
337
|
+
CACHE_TTL_MS = 12 * 60 * 60 * 1e3;
|
|
338
|
+
CACHE_KEY_PREFIX = "accesly:history:";
|
|
339
|
+
BROADCAST_CHANNEL_PREFIX = "accesly:history:";
|
|
340
|
+
optimisticItems = /* @__PURE__ */ new Map();
|
|
341
|
+
optimisticListeners = /* @__PURE__ */ new Map();
|
|
150
342
|
}
|
|
151
|
-
};
|
|
343
|
+
});
|
|
152
344
|
function useAccesly() {
|
|
153
345
|
const ctx = useContext(AcceslyContext);
|
|
154
346
|
if (!ctx) {
|
|
@@ -632,6 +824,24 @@ function useAccesly() {
|
|
|
632
824
|
unsignedXdr: sim.unsignedXdr,
|
|
633
825
|
signedAuthEntryXdr
|
|
634
826
|
});
|
|
827
|
+
try {
|
|
828
|
+
const username = ctx.username;
|
|
829
|
+
if (username) {
|
|
830
|
+
const stored = await ctx.deviceStore.loadCredential(username);
|
|
831
|
+
if (stored?.walletAddress) {
|
|
832
|
+
const { historyOptimisticPush: historyOptimisticPush2 } = await Promise.resolve().then(() => (init_useWalletHistory(), useWalletHistory_exports));
|
|
833
|
+
historyOptimisticPush2(stored.walletAddress, {
|
|
834
|
+
type: "transfer-out",
|
|
835
|
+
txHash: submit.txHash,
|
|
836
|
+
ledger: Math.floor(Date.now() / 1e3),
|
|
837
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
838
|
+
to: input.destinationAddress,
|
|
839
|
+
amountStroops: input.amountStroops
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
} catch {
|
|
844
|
+
}
|
|
635
845
|
return {
|
|
636
846
|
txHash: submit.txHash,
|
|
637
847
|
status: submit.status,
|
|
@@ -929,6 +1139,111 @@ function base64ToBytes(s) {
|
|
|
929
1139
|
for (let i = 0; i < bin.length; i += 1) arr[i] = bin.charCodeAt(i);
|
|
930
1140
|
return arr;
|
|
931
1141
|
}
|
|
1142
|
+
var NotImplementedYetError;
|
|
1143
|
+
var init_useAccesly = __esm({
|
|
1144
|
+
"src/hooks/useAccesly.ts"() {
|
|
1145
|
+
init_context();
|
|
1146
|
+
init_config();
|
|
1147
|
+
init_sorobanDeployStatus();
|
|
1148
|
+
NotImplementedYetError = class extends Error {
|
|
1149
|
+
constructor(namespace, method) {
|
|
1150
|
+
super(
|
|
1151
|
+
`${namespace}.${method}() is not implemented yet. This namespace ships in a later release; see docs/Handoff_Fase7.md for the roadmap.`
|
|
1152
|
+
);
|
|
1153
|
+
this.name = "NotImplementedYetError";
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
// src/provider.tsx
|
|
1160
|
+
init_context();
|
|
1161
|
+
init_config();
|
|
1162
|
+
function AcceslyProvider(props) {
|
|
1163
|
+
const defaults = ENVIRONMENT_DEFAULTS[props.env];
|
|
1164
|
+
const apiUrl = props.apiUrl ?? defaults.apiUrl;
|
|
1165
|
+
const cognitoConfig = props.cognitoConfig ?? defaults.cognito;
|
|
1166
|
+
const telemetry = props.telemetry;
|
|
1167
|
+
const instances = useMemo(() => {
|
|
1168
|
+
const authClient = props.overrides?.authClient ?? new CognitoAuthClient(cognitoConfig);
|
|
1169
|
+
const sessionStorage = props.overrides?.sessionStorage ?? defaultSessionStorage();
|
|
1170
|
+
const deviceStore = props.overrides?.deviceStore ?? new InMemoryDeviceStore();
|
|
1171
|
+
const tokenManager = new TokenManager({ authClient, storage: sessionStorage });
|
|
1172
|
+
const apiClient = new AccesslyApiClient({
|
|
1173
|
+
baseUrl: apiUrl,
|
|
1174
|
+
getIdToken: () => tokenManager.getValidIdToken(),
|
|
1175
|
+
...telemetry ? { telemetry } : {}
|
|
1176
|
+
});
|
|
1177
|
+
const endpoints = new AccesslyEndpoints(apiClient);
|
|
1178
|
+
return { authClient, sessionStorage, deviceStore, tokenManager, endpoints };
|
|
1179
|
+
}, [
|
|
1180
|
+
apiUrl,
|
|
1181
|
+
cognitoConfig.region,
|
|
1182
|
+
cognitoConfig.userPoolId,
|
|
1183
|
+
cognitoConfig.userPoolClientId,
|
|
1184
|
+
props.overrides?.authClient,
|
|
1185
|
+
props.overrides?.sessionStorage,
|
|
1186
|
+
props.overrides?.deviceStore
|
|
1187
|
+
]);
|
|
1188
|
+
const [status, setStatus] = useState(() => initialStatus(instances.sessionStorage));
|
|
1189
|
+
const [username, setUsername] = useState(
|
|
1190
|
+
() => initialUsername(instances.sessionStorage)
|
|
1191
|
+
);
|
|
1192
|
+
const mountedRef = useRef(true);
|
|
1193
|
+
const refreshStatus = useCallback(async () => {
|
|
1194
|
+
const next = await instances.tokenManager.getStatus();
|
|
1195
|
+
const tokens = await Promise.resolve(instances.sessionStorage.load());
|
|
1196
|
+
if (mountedRef.current) {
|
|
1197
|
+
setStatus(next);
|
|
1198
|
+
setUsername(tokens?.username ?? null);
|
|
1199
|
+
}
|
|
1200
|
+
}, [instances]);
|
|
1201
|
+
useEffect(() => {
|
|
1202
|
+
mountedRef.current = true;
|
|
1203
|
+
void refreshStatus();
|
|
1204
|
+
return () => {
|
|
1205
|
+
mountedRef.current = false;
|
|
1206
|
+
};
|
|
1207
|
+
}, [instances]);
|
|
1208
|
+
const value = useMemo(
|
|
1209
|
+
() => ({
|
|
1210
|
+
appId: props.appId,
|
|
1211
|
+
env: props.env,
|
|
1212
|
+
apiUrl,
|
|
1213
|
+
cognitoConfig,
|
|
1214
|
+
authClient: instances.authClient,
|
|
1215
|
+
sessionStorage: instances.sessionStorage,
|
|
1216
|
+
tokenManager: instances.tokenManager,
|
|
1217
|
+
endpoints: instances.endpoints,
|
|
1218
|
+
deviceStore: instances.deviceStore,
|
|
1219
|
+
status,
|
|
1220
|
+
username,
|
|
1221
|
+
refreshStatus
|
|
1222
|
+
}),
|
|
1223
|
+
[props.appId, props.env, apiUrl, cognitoConfig, instances, status, username, refreshStatus]
|
|
1224
|
+
);
|
|
1225
|
+
return /* @__PURE__ */ jsx(AcceslyContext.Provider, { value, children: props.children });
|
|
1226
|
+
}
|
|
1227
|
+
function initialStatus(storage) {
|
|
1228
|
+
const tokens = storage.load();
|
|
1229
|
+
if (tokens instanceof Promise) return "bootstrapping";
|
|
1230
|
+
if (!tokens) return "anonymous";
|
|
1231
|
+
return Date.now() + 5 * 60 * 1e3 >= tokens.expiresAt ? "expired" : "authenticated";
|
|
1232
|
+
}
|
|
1233
|
+
function initialUsername(storage) {
|
|
1234
|
+
const tokens = storage.load();
|
|
1235
|
+
if (tokens instanceof Promise) return null;
|
|
1236
|
+
return tokens?.username ?? null;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// src/index.ts
|
|
1240
|
+
init_context();
|
|
1241
|
+
init_config();
|
|
1242
|
+
init_useAccesly();
|
|
1243
|
+
|
|
1244
|
+
// src/hooks/useWalletStatus.ts
|
|
1245
|
+
init_useAccesly();
|
|
1246
|
+
init_config();
|
|
932
1247
|
|
|
933
1248
|
// src/hooks/walletSubscription.ts
|
|
934
1249
|
var ACTIVITY_BUFFER_MAX = 50;
|
|
@@ -1046,7 +1361,7 @@ function closeAllWalletSubscriptions() {
|
|
|
1046
1361
|
// src/hooks/useWalletStatus.ts
|
|
1047
1362
|
var POLL_BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 3e4];
|
|
1048
1363
|
var STALE_THRESHOLD_MS = 6e4;
|
|
1049
|
-
function
|
|
1364
|
+
function useStableRef2(value) {
|
|
1050
1365
|
const ref = useRef(value);
|
|
1051
1366
|
ref.current = value;
|
|
1052
1367
|
return ref;
|
|
@@ -1066,7 +1381,7 @@ function useWalletStatus() {
|
|
|
1066
1381
|
const [isStale, setIsStale] = useState(false);
|
|
1067
1382
|
const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];
|
|
1068
1383
|
const streamUrl = envDefaults.walletStreamUrl;
|
|
1069
|
-
const walletRef =
|
|
1384
|
+
const walletRef = useStableRef2(wallet);
|
|
1070
1385
|
const doFetch = useCallback(async () => {
|
|
1071
1386
|
if (!username) return null;
|
|
1072
1387
|
try {
|
|
@@ -1090,7 +1405,7 @@ function useWalletStatus() {
|
|
|
1090
1405
|
return null;
|
|
1091
1406
|
}
|
|
1092
1407
|
}, [username, walletRef]);
|
|
1093
|
-
const doFetchRef =
|
|
1408
|
+
const doFetchRef = useStableRef2(doFetch);
|
|
1094
1409
|
useEffect(() => {
|
|
1095
1410
|
if (!username) {
|
|
1096
1411
|
setStatus("unknown");
|
|
@@ -1158,8 +1473,12 @@ function useWalletStatus() {
|
|
|
1158
1473
|
}, [doFetchRef]);
|
|
1159
1474
|
return { status, walletAddress, onChain, isStale, refresh };
|
|
1160
1475
|
}
|
|
1476
|
+
|
|
1477
|
+
// src/hooks/useBalance.ts
|
|
1478
|
+
init_useAccesly();
|
|
1479
|
+
init_config();
|
|
1161
1480
|
var POLL_FALLBACK_MS = 1e4;
|
|
1162
|
-
function
|
|
1481
|
+
function useStableRef3(value) {
|
|
1163
1482
|
const ref = useRef(value);
|
|
1164
1483
|
ref.current = value;
|
|
1165
1484
|
return ref;
|
|
@@ -1174,7 +1493,7 @@ function useBalance(walletAddress) {
|
|
|
1174
1493
|
const [xlm, setXlm] = useState(null);
|
|
1175
1494
|
const [isLoading, setIsLoading] = useState(true);
|
|
1176
1495
|
const [error, setError] = useState(null);
|
|
1177
|
-
const walletRef =
|
|
1496
|
+
const walletRef = useStableRef3(wallet);
|
|
1178
1497
|
useEffect(() => {
|
|
1179
1498
|
if (walletAddress) {
|
|
1180
1499
|
setResolvedAddress(walletAddress);
|
|
@@ -1200,7 +1519,7 @@ function useBalance(walletAddress) {
|
|
|
1200
1519
|
}, [walletAddress, username, walletRef]);
|
|
1201
1520
|
const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];
|
|
1202
1521
|
const streamUrl = envDefaults.walletStreamUrl;
|
|
1203
|
-
const endpointsRef =
|
|
1522
|
+
const endpointsRef = useStableRef3(_internal.endpoints);
|
|
1204
1523
|
const doFetchOnce = useCallback(async () => {
|
|
1205
1524
|
if (!resolvedAddress) return;
|
|
1206
1525
|
try {
|
|
@@ -1214,7 +1533,7 @@ function useBalance(walletAddress) {
|
|
|
1214
1533
|
setIsLoading(false);
|
|
1215
1534
|
}
|
|
1216
1535
|
}, [resolvedAddress, endpointsRef]);
|
|
1217
|
-
const doFetchRef =
|
|
1536
|
+
const doFetchRef = useStableRef3(doFetchOnce);
|
|
1218
1537
|
useEffect(() => {
|
|
1219
1538
|
if (!resolvedAddress) {
|
|
1220
1539
|
setIsLoading(false);
|
|
@@ -1259,9 +1578,13 @@ function useBalance(walletAddress) {
|
|
|
1259
1578
|
}, [doFetchRef]);
|
|
1260
1579
|
return { stroops, xlm, isLoading, error, refresh };
|
|
1261
1580
|
}
|
|
1581
|
+
|
|
1582
|
+
// src/hooks/useWalletActivity.ts
|
|
1583
|
+
init_useAccesly();
|
|
1584
|
+
init_config();
|
|
1262
1585
|
var POLL_FALLBACK_MS2 = 25e3;
|
|
1263
1586
|
var DEFAULT_LIMIT = 20;
|
|
1264
|
-
function
|
|
1587
|
+
function useStableRef4(value) {
|
|
1265
1588
|
const ref = useRef(value);
|
|
1266
1589
|
ref.current = value;
|
|
1267
1590
|
return ref;
|
|
@@ -1276,7 +1599,7 @@ function useWalletActivity(walletAddress, opts = {}) {
|
|
|
1276
1599
|
const [events, setEvents] = useState([]);
|
|
1277
1600
|
const [isLoading, setIsLoading] = useState(true);
|
|
1278
1601
|
const [error, setError] = useState(null);
|
|
1279
|
-
const walletRef =
|
|
1602
|
+
const walletRef = useStableRef4(wallet);
|
|
1280
1603
|
useEffect(() => {
|
|
1281
1604
|
if (walletAddress) {
|
|
1282
1605
|
setResolvedAddress(walletAddress);
|
|
@@ -1302,7 +1625,7 @@ function useWalletActivity(walletAddress, opts = {}) {
|
|
|
1302
1625
|
}, [walletAddress, username, walletRef]);
|
|
1303
1626
|
const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];
|
|
1304
1627
|
const streamUrl = envDefaults.walletStreamUrl;
|
|
1305
|
-
const endpointsRef =
|
|
1628
|
+
const endpointsRef = useStableRef4(_internal.endpoints);
|
|
1306
1629
|
const doFetchOnce = useCallback(async () => {
|
|
1307
1630
|
if (!resolvedAddress) return;
|
|
1308
1631
|
try {
|
|
@@ -1320,7 +1643,7 @@ function useWalletActivity(walletAddress, opts = {}) {
|
|
|
1320
1643
|
setIsLoading(false);
|
|
1321
1644
|
}
|
|
1322
1645
|
}, [resolvedAddress, limit, endpointsRef]);
|
|
1323
|
-
const doFetchRef =
|
|
1646
|
+
const doFetchRef = useStableRef4(doFetchOnce);
|
|
1324
1647
|
useEffect(() => {
|
|
1325
1648
|
if (!resolvedAddress) {
|
|
1326
1649
|
setIsLoading(false);
|
|
@@ -1368,8 +1691,9 @@ function adaptRestEvent(ev) {
|
|
|
1368
1691
|
}
|
|
1369
1692
|
|
|
1370
1693
|
// src/index.ts
|
|
1694
|
+
init_useWalletHistory();
|
|
1371
1695
|
var REACT_ADAPTER_VERSION = "0.0.0";
|
|
1372
1696
|
|
|
1373
|
-
export { AcceslyContext, AcceslyProvider, ENVIRONMENT_DEFAULTS, NotImplementedYetError, REACT_ADAPTER_VERSION, closeAllWalletSubscriptions, subscribeToWalletEvent, useAccesly, useBalance, useWalletActivity, useWalletStatus };
|
|
1697
|
+
export { AcceslyContext, AcceslyProvider, ENVIRONMENT_DEFAULTS, NotImplementedYetError, REACT_ADAPTER_VERSION, closeAllWalletSubscriptions, historyClearOptimistic, historyOptimisticPush, subscribeToWalletEvent, useAccesly, useBalance, useWalletActivity, useWalletHistory, useWalletStatus };
|
|
1374
1698
|
//# sourceMappingURL=index.js.map
|
|
1375
1699
|
//# sourceMappingURL=index.js.map
|