@accesly/react 1.1.2 → 1.1.3
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 +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +778 -0
- package/dist/index.d.ts +778 -0
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
import { Environment, CognitoConfig, AuthClient, SessionStorage, DeviceStore, TelemetrySink, TokenManager, AccesslyEndpoints, AuthStatus, CredentialRecord, EncryptedEnvelope, WalletActivityEvent } from '@accesly/core';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `AcceslyProvider` — top-level React provider that creates the SDK instances
|
|
7
|
+
* once and exposes them through context. All hooks consume this.
|
|
8
|
+
*
|
|
9
|
+
* Apps wrap their tree:
|
|
10
|
+
* <AcceslyProvider appId="myapp" env="dev">
|
|
11
|
+
* <App />
|
|
12
|
+
* </AcceslyProvider>
|
|
13
|
+
*
|
|
14
|
+
* For advanced cases (custom IdP, custom storage), pass `overrides` to inject
|
|
15
|
+
* your own `AuthClient`, `SessionStorage`, or `DeviceStore`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
interface AcceslyProviderProps {
|
|
19
|
+
readonly appId: string;
|
|
20
|
+
readonly env: Environment;
|
|
21
|
+
readonly children: ReactNode;
|
|
22
|
+
/** Override the resolved API URL. */
|
|
23
|
+
readonly apiUrl?: string;
|
|
24
|
+
/** Override the resolved Cognito config. */
|
|
25
|
+
readonly cognitoConfig?: CognitoConfig;
|
|
26
|
+
/** Override SDK pieces — for tests or custom backends. */
|
|
27
|
+
readonly overrides?: {
|
|
28
|
+
readonly authClient?: AuthClient;
|
|
29
|
+
readonly sessionStorage?: SessionStorage;
|
|
30
|
+
readonly deviceStore?: DeviceStore;
|
|
31
|
+
};
|
|
32
|
+
/** Optional telemetry sink — surfaces every API request/response/retry. */
|
|
33
|
+
readonly telemetry?: TelemetrySink;
|
|
34
|
+
}
|
|
35
|
+
declare function AcceslyProvider(props: AcceslyProviderProps): JSX.Element;
|
|
36
|
+
|
|
37
|
+
interface AcceslyContextValue {
|
|
38
|
+
readonly appId: string;
|
|
39
|
+
readonly env: Environment;
|
|
40
|
+
readonly apiUrl: string;
|
|
41
|
+
readonly cognitoConfig: CognitoConfig;
|
|
42
|
+
readonly authClient: AuthClient;
|
|
43
|
+
readonly sessionStorage: SessionStorage;
|
|
44
|
+
readonly tokenManager: TokenManager;
|
|
45
|
+
readonly endpoints: AccesslyEndpoints;
|
|
46
|
+
readonly deviceStore: DeviceStore;
|
|
47
|
+
/** Current auth status — re-rendered whenever it changes. */
|
|
48
|
+
readonly status: AuthStatus;
|
|
49
|
+
readonly username: string | null;
|
|
50
|
+
/** Force a re-read of `tokenManager.getStatus()`. */
|
|
51
|
+
readonly refreshStatus: () => Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
declare const AcceslyContext: react.Context<AcceslyContextValue | null>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Per-environment defaults — currently the only public stage is `dev`. The
|
|
57
|
+
* others are placeholders so the SDK API doesn't change when `staging`/`prod`
|
|
58
|
+
* come online (Fase 7+ / Fase 10).
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
interface EnvironmentDefaults {
|
|
62
|
+
readonly apiUrl: string;
|
|
63
|
+
readonly cognito: CognitoConfig;
|
|
64
|
+
readonly stellar: {
|
|
65
|
+
readonly networkPassphrase: string;
|
|
66
|
+
readonly horizonUrl: string;
|
|
67
|
+
readonly sorobanRpcUrl: string;
|
|
68
|
+
/**
|
|
69
|
+
* Stellar G-address of the account that invokes `CreateContract` for new
|
|
70
|
+
* Smart Accounts. Same account the backend Lambda uses, so the wallet
|
|
71
|
+
* address computed client-side via `wallet.computeAddress` matches
|
|
72
|
+
* exactly what the backend will (or did) deploy.
|
|
73
|
+
*/
|
|
74
|
+
readonly deployerAddress: string;
|
|
75
|
+
/**
|
|
76
|
+
* Address del contrato `ed25519-verifier` desplegado en la red. Necesario
|
|
77
|
+
* cuando el SDK construye la entrada `Signer::External(verifier, pubkey)`
|
|
78
|
+
* dentro del `AuthPayload` que firma — el Smart Account compara con la
|
|
79
|
+
* misma address que tiene almacenada en su context rule.
|
|
80
|
+
*/
|
|
81
|
+
readonly ed25519VerifierAddress: string;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
declare const ENVIRONMENT_DEFAULTS: Record<Environment, EnvironmentDefaults>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* `useAccesly()` — single hook with namespaces:
|
|
88
|
+
* - auth — signUp / confirmSignUp / signIn / signOut / status
|
|
89
|
+
* - wallet — createWallet, getStoredWallet
|
|
90
|
+
* - tx — sendPayment, signRawXdr
|
|
91
|
+
* - kyc — start, status
|
|
92
|
+
*
|
|
93
|
+
* The hook returns stable references when the underlying SDK instances don't
|
|
94
|
+
* change. Each namespace is built lazily (memoised) so apps that only use
|
|
95
|
+
* `auth` don't bring `wallet` into their render.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
interface AuthNamespace {
|
|
99
|
+
readonly status: AuthStatus;
|
|
100
|
+
readonly username: string | null;
|
|
101
|
+
signUp(email: string, password: string): Promise<{
|
|
102
|
+
userSub: string;
|
|
103
|
+
userConfirmed: boolean;
|
|
104
|
+
}>;
|
|
105
|
+
confirmSignUp(email: string, code: string): Promise<void>;
|
|
106
|
+
resendConfirmation(email: string): Promise<void>;
|
|
107
|
+
signIn(email: string, password: string): Promise<void>;
|
|
108
|
+
signOut(): Promise<void>;
|
|
109
|
+
}
|
|
110
|
+
interface CreateWalletInput {
|
|
111
|
+
readonly email: string;
|
|
112
|
+
readonly emailSalt: Uint8Array;
|
|
113
|
+
readonly encryptionKeys: readonly [Uint8Array, Uint8Array, Uint8Array];
|
|
114
|
+
readonly secp256r1Pubkey: Uint8Array;
|
|
115
|
+
/**
|
|
116
|
+
* Optional. When provided together with `prfSalt`, the SDK persists a
|
|
117
|
+
* `CredentialRecord` to the configured `DeviceStore` BEFORE calling
|
|
118
|
+
* `POST /wallets`. That way, if the network request fails (timeout, tab
|
|
119
|
+
* close, etc.) the encrypted F1 shard + passkey metadata survive locally
|
|
120
|
+
* and the wallet can be recovered via `wallet.ensureWallet` on the next
|
|
121
|
+
* session (the backend dedupes by Cognito user → returns the same
|
|
122
|
+
* walletAddress).
|
|
123
|
+
*
|
|
124
|
+
* Pass it. Omitting it means an orphaned wallet on POST failure is
|
|
125
|
+
* unrecoverable without a server-side query.
|
|
126
|
+
*/
|
|
127
|
+
readonly credentialId?: Uint8Array;
|
|
128
|
+
/** Optional. See `credentialId`. */
|
|
129
|
+
readonly prfSalt?: Uint8Array;
|
|
130
|
+
/**
|
|
131
|
+
* Password de Cognito en plano (`Uint8Array` codificado UTF-8).
|
|
132
|
+
*
|
|
133
|
+
* Recovery v2 (Fase 1, 2026-06-15): si se provee, el SDK deriva
|
|
134
|
+
* `recoveryKey = PBKDF2(password, recoverySalt, 600k)` y la usa para
|
|
135
|
+
* cifrar F3 antes de enviarlo al backend, en vez de usar
|
|
136
|
+
* `encryptionKeys[2]`. El backend almacena F3 cifrado con esa key —
|
|
137
|
+
* SOLO descifrable client-side con el mismo password.
|
|
138
|
+
*
|
|
139
|
+
* Sin esta prop el wallet se crea pero NO podrá recuperarse vía OTP
|
|
140
|
+
* (F3 quedará cifrado con `encryptionKeys[2]`, igual que en 0.x).
|
|
141
|
+
*
|
|
142
|
+
* El caller es responsable de zeroizar este buffer tras `createWallet`
|
|
143
|
+
* (el SDK no lo retiene en memoria).
|
|
144
|
+
*/
|
|
145
|
+
readonly cognitoPassword?: Uint8Array;
|
|
146
|
+
/**
|
|
147
|
+
* 32-byte salt para HKDF — si se persiste en el `CredentialRecord`,
|
|
148
|
+
* `wallet.unlockForSigning` lo recupera y re-deriva las mismas keys sin
|
|
149
|
+
* intervención del caller. Si se omite, el SDK genera uno random y lo
|
|
150
|
+
* persiste igualmente. Si la wallet ya existe en el `DeviceStore` con un
|
|
151
|
+
* `encryptionSalt`, este input se ignora a favor del salt persistido (para
|
|
152
|
+
* preservar la decriptabilidad de F1).
|
|
153
|
+
*/
|
|
154
|
+
readonly encryptionSalt?: Uint8Array;
|
|
155
|
+
}
|
|
156
|
+
interface CreatedWalletInfo {
|
|
157
|
+
readonly walletAddress: string;
|
|
158
|
+
readonly publicKey: Uint8Array;
|
|
159
|
+
/**
|
|
160
|
+
* `'on-chain'` if the backend confirmed deploy; `'pending-deploy'` if the
|
|
161
|
+
* backend submitted to Soroban but the contract did not land (typically
|
|
162
|
+
* because the Smart Account constructor exceeds Soroban v26 resource caps
|
|
163
|
+
* — Phase 1 territory). When pending, the `walletAddress` is the
|
|
164
|
+
* client-side-predicted address: same address that will be live once the
|
|
165
|
+
* deploy succeeds (idempotent on the backend).
|
|
166
|
+
*/
|
|
167
|
+
readonly status: WalletStatus;
|
|
168
|
+
/** When `status === 'pending-deploy'`, the backend's reason if available. */
|
|
169
|
+
readonly pendingReason?: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
type WalletStatus =
|
|
173
|
+
/** Backend confirmed the contract is live on Soroban. Ready to use. */
|
|
174
|
+
'on-chain'
|
|
175
|
+
/**
|
|
176
|
+
* Wallet record exists (locally and/or on backend) but the contract has NOT
|
|
177
|
+
* been observed on Soroban yet. Either deploy is still in flight, or
|
|
178
|
+
* landed in a ghost state. Re-run `wallet.ensureWallet` later (or call
|
|
179
|
+
* `wallet.retryDeploy(username)`).
|
|
180
|
+
*/
|
|
181
|
+
| 'pending-deploy'
|
|
182
|
+
/**
|
|
183
|
+
* Backend has the record but its Soroban RPC check did not respond — the
|
|
184
|
+
* SDK treats the address as usable but flags the uncertainty.
|
|
185
|
+
*/
|
|
186
|
+
| 'unknown';
|
|
187
|
+
interface EnsureWalletResult {
|
|
188
|
+
readonly walletAddress: string;
|
|
189
|
+
readonly status: WalletStatus;
|
|
190
|
+
/** True if this call generated a new keypair (first-time deploy path). */
|
|
191
|
+
readonly createdNow: boolean;
|
|
192
|
+
/** Present only when `createdNow === true`. */
|
|
193
|
+
readonly publicKey?: Uint8Array;
|
|
194
|
+
}
|
|
195
|
+
interface RemoteWalletInfo {
|
|
196
|
+
readonly walletAddress: string;
|
|
197
|
+
readonly appId: string;
|
|
198
|
+
readonly createdAt: string;
|
|
199
|
+
readonly onChain: boolean | null;
|
|
200
|
+
}
|
|
201
|
+
interface RetryDeployResult {
|
|
202
|
+
readonly walletAddress: string;
|
|
203
|
+
readonly status: WalletStatus;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Input para `wallet.bootstrap(...)` — el high-level "todo en uno" que cualquier
|
|
207
|
+
* integrador típico va a llamar como entry point. Hace **TODO**:
|
|
208
|
+
*
|
|
209
|
+
* 1. `sha256(email)` → userId opaco para el RP.
|
|
210
|
+
* 2. Genera `prfSalt` aleatorio (32 bytes).
|
|
211
|
+
* 3. `registerPasskey(...)` con extensión PRF — pide huella/face/Hello.
|
|
212
|
+
* 4. Genera `encryptionSalt` aleatorio (32 bytes).
|
|
213
|
+
* 5. HKDF(prfOutput, encryptionSalt, "accesly-{f1,f2,f3}-encryption") → 3 keys AES.
|
|
214
|
+
* 6. Genera `emailSalt` aleatorio (32 bytes).
|
|
215
|
+
* 7. `wallet.ensureWallet(...)` — el flujo idempotente get-or-create.
|
|
216
|
+
* 8. Persiste `encryptionSalt` en `CredentialRecord` para que `unlockForSigning`
|
|
217
|
+
* pueda re-derivar las mismas keys.
|
|
218
|
+
* 9. Zeroiza `prfOutput`, `f1Key`, `f2Key`, `f3Key`, `cognitoPasswordBytes`.
|
|
219
|
+
*
|
|
220
|
+
* Después de `bootstrap`, llamá `tx.send(...)` directamente con
|
|
221
|
+
* `wallet.unlockForSigning(email)` — no hace falta más wiring.
|
|
222
|
+
*/
|
|
223
|
+
interface BootstrapWalletInput {
|
|
224
|
+
readonly email: string;
|
|
225
|
+
/**
|
|
226
|
+
* Password de Cognito en plano. Usado para:
|
|
227
|
+
* - Re-cifrar F3 (y F2_recovery) con `recoveryKey = PBKDF2(password,
|
|
228
|
+
* recoverySalt, 600k)` para el flujo de Recovery v2.
|
|
229
|
+
*
|
|
230
|
+
* El SDK lo zeroiza tras el ensureWallet.
|
|
231
|
+
*/
|
|
232
|
+
readonly password: string;
|
|
233
|
+
/**
|
|
234
|
+
* Overrides opcionales para el `registerPasskey` interno. Caso típico:
|
|
235
|
+
* cambiar `rpName: 'MiApp'` para que el browser muestre tu marca en el
|
|
236
|
+
* prompt biométrico. `rpId` por default = `window.location.hostname`.
|
|
237
|
+
*/
|
|
238
|
+
readonly passkey?: {
|
|
239
|
+
readonly rpId?: string;
|
|
240
|
+
readonly rpName?: string;
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Material reconstruido por `wallet.unlockForSigning(...)` y listo para pasar
|
|
245
|
+
* a `tx.send(...)`. Las llaves se zeroizan tras la firma; el caller no debería
|
|
246
|
+
* retenerlas más allá del round-trip.
|
|
247
|
+
*/
|
|
248
|
+
interface UnlockedSigningMaterial {
|
|
249
|
+
/** F1 share desencriptado (Shamir-encoded blob). Lo zero-iza `tx.send`. */
|
|
250
|
+
readonly fragmentF1Plain: Uint8Array;
|
|
251
|
+
/** AES key con la que el SDK desencripta el envelope F2 del backend. */
|
|
252
|
+
readonly fragmentF2Key: Uint8Array;
|
|
253
|
+
/** Pubkey ed25519 del owner del Smart Account (32 bytes). */
|
|
254
|
+
readonly ownerPubkey: Uint8Array;
|
|
255
|
+
/** Address C… del Smart Account (display only). */
|
|
256
|
+
readonly walletAddress: string;
|
|
257
|
+
}
|
|
258
|
+
interface WalletNamespace {
|
|
259
|
+
/**
|
|
260
|
+
* **Entry-point recomendado.** Registra passkey + deriva keys + crea-o-recupera
|
|
261
|
+
* wallet en una sola llamada. Sustituye al patrón histórico de
|
|
262
|
+
* `ensureWalletWithPasskey` que tenía que copiar-pegar cada integrador.
|
|
263
|
+
*
|
|
264
|
+
* Idempotente: si ya hay wallet en el backend para este Cognito user, devuelve
|
|
265
|
+
* `{createdNow: false}` sin re-registrar passkey. Si no, hace el flow completo.
|
|
266
|
+
*/
|
|
267
|
+
bootstrap(input: BootstrapWalletInput): Promise<EnsureWalletResult>;
|
|
268
|
+
/**
|
|
269
|
+
* **Helper para `tx.send`.** Lee la credencial del DeviceStore, abre el
|
|
270
|
+
* passkey via WebAuthn (PIN/biométrico), re-deriva las AES keys con HKDF, y
|
|
271
|
+
* descifra F1 local. Devuelve los 3 materiales que `tx.send` necesita.
|
|
272
|
+
*
|
|
273
|
+
* Lanza con mensaje claro si:
|
|
274
|
+
* - no hay credential local (el user tiene que correr `recovery.finalize`
|
|
275
|
+
* en este device);
|
|
276
|
+
* - el passkey no devolvió PRF (browser sin soporte);
|
|
277
|
+
* - el envelope F1 falla al descifrar (corrupto / passkey distinto).
|
|
278
|
+
*/
|
|
279
|
+
unlockForSigning(username: string): Promise<UnlockedSigningMaterial>;
|
|
280
|
+
/**
|
|
281
|
+
* End-to-end wallet creation:
|
|
282
|
+
* 1. Generate keypair + Shamir split + encrypt fragments (client-side).
|
|
283
|
+
* 2. Compute the Smart Account address client-side from the ed25519
|
|
284
|
+
* pubkey + the env-configured deployer (deterministic — matches what
|
|
285
|
+
* the backend will deploy).
|
|
286
|
+
* 3. If `credentialId` + `prfSalt` were provided, persist a full
|
|
287
|
+
* `CredentialRecord` (with all 3 encrypted fragments + computed
|
|
288
|
+
* walletAddress + `onChain: null`) to the `DeviceStore` BEFORE the
|
|
289
|
+
* network call — crash-safety + retry capability in one step.
|
|
290
|
+
* 4. POST /wallets with hex pubkeys + base64 fragments.
|
|
291
|
+
* 5. On success, mark the record `onChain: true` (cleared by the next
|
|
292
|
+
* `ensureWallet` call which queries Soroban via the backend).
|
|
293
|
+
*
|
|
294
|
+
* The caller is responsible for the encryption-key derivation (typically
|
|
295
|
+
* via WebAuthn PRF).
|
|
296
|
+
*/
|
|
297
|
+
createWallet(input: CreateWalletInput): Promise<CreatedWalletInfo>;
|
|
298
|
+
/**
|
|
299
|
+
* Idempotent wallet bootstrap. The recommended entry-point at the top of
|
|
300
|
+
* every authenticated session:
|
|
301
|
+
*
|
|
302
|
+
* - `GET /wallets` → if `onChain === true`, returns `{ status: 'on-chain' }`
|
|
303
|
+
* and skips keypair generation entirely.
|
|
304
|
+
* - `GET /wallets` → if `onChain === false`, calls `retryDeploy` to
|
|
305
|
+
* re-submit the existing record (idempotent on the backend) and
|
|
306
|
+
* returns `{ status: 'pending-deploy' }` if the retry didn't surface
|
|
307
|
+
* success yet.
|
|
308
|
+
* - `GET /wallets` → if `onChain === null` (Soroban RPC unreachable),
|
|
309
|
+
* returns `{ status: 'unknown' }` — the address is usable but the
|
|
310
|
+
* SDK couldn't confirm on-chain presence.
|
|
311
|
+
* - `GET /wallets` → 404 → runs the full `createWallet` flow and returns
|
|
312
|
+
* `{ status: 'pending-deploy', createdNow: true }`. Subsequent calls
|
|
313
|
+
* will upgrade to `'on-chain'` once the backend's Soroban check passes.
|
|
314
|
+
*/
|
|
315
|
+
ensureWallet(input: CreateWalletInput): Promise<EnsureWalletResult>;
|
|
316
|
+
/**
|
|
317
|
+
* Re-submits `POST /wallets` for an existing local `CredentialRecord`. Used
|
|
318
|
+
* to recover from ghost wallets (record exists but deploy did not land).
|
|
319
|
+
* Requires the record to have been persisted with `fragmentF2Encrypted`,
|
|
320
|
+
* `fragmentF3Encrypted`, `publicKey`, and `emailCommitment` (which
|
|
321
|
+
* `createWallet` does automatically when `credentialId` + `prfSalt` are
|
|
322
|
+
* provided).
|
|
323
|
+
*
|
|
324
|
+
* Backend dedupes by ownerPubkey — the returned address is guaranteed to
|
|
325
|
+
* equal the one originally stored.
|
|
326
|
+
*/
|
|
327
|
+
retryDeploy(username: string): Promise<RetryDeployResult>;
|
|
328
|
+
/**
|
|
329
|
+
* Reads the user's wallet metadata from the backend. Returns null if the
|
|
330
|
+
* user has not yet created a wallet.
|
|
331
|
+
*/
|
|
332
|
+
fetchRemote(): Promise<RemoteWalletInfo | null>;
|
|
333
|
+
/**
|
|
334
|
+
* Computes the deterministic Smart Account address that the backend will
|
|
335
|
+
* (or did) deploy for the given ed25519 owner pubkey. Same algorithm
|
|
336
|
+
* Stellar Core uses — pure client-side, no network call. Useful to show
|
|
337
|
+
* the address to the user instantly before any POST.
|
|
338
|
+
*/
|
|
339
|
+
computeAddress(ownerPubkey: Uint8Array): Promise<string>;
|
|
340
|
+
/** Returns the locally-stored credential record, if any. */
|
|
341
|
+
getStoredCredential(username: string): Promise<CredentialRecord | null>;
|
|
342
|
+
/**
|
|
343
|
+
* Lists `CredentialRecord`s whose `walletAddress` is still `null` OR whose
|
|
344
|
+
* `onChain` flag is `false`. Diagnostic + recovery aid.
|
|
345
|
+
*/
|
|
346
|
+
getPendingWallets(): Promise<readonly CredentialRecord[]>;
|
|
347
|
+
/** Removes a stored credential. Useful after a failed pending wallet is reconciled. */
|
|
348
|
+
clearStoredCredential(username: string): Promise<void>;
|
|
349
|
+
/**
|
|
350
|
+
* Testnet only — fondea el Smart Account con XLM via Stellar friendbot.
|
|
351
|
+
*
|
|
352
|
+
* Friendbot acepta directamente direcciones de contrato Soroban (`C…`):
|
|
353
|
+
* internamente arma una tx `invokeContract(XLM_SAC.transfer, ...)` desde
|
|
354
|
+
* la cuenta de la SDF y la submitea. Resultado: ~10,000 XLM testnet al
|
|
355
|
+
* Smart Account, sin necesidad de un G-account intermediario.
|
|
356
|
+
*
|
|
357
|
+
* Idempotente: el primer call exitoso marca `testnetFunded: true` en el
|
|
358
|
+
* `CredentialRecord` local; subsiguientes calls devuelven `alreadyFunded:
|
|
359
|
+
* true` sin hacer otro round-trip a friendbot.
|
|
360
|
+
*
|
|
361
|
+
* En `env: 'mainnet'` la función es un no-op (no existe friendbot en
|
|
362
|
+
* mainnet) y devuelve `{ funded: false, alreadyFunded: false, reason:
|
|
363
|
+
* 'mainnet-not-supported' }`. La UI tiene que mostrar opciones de onramp
|
|
364
|
+
* real (Etherfuse, MoonPay, transferencia externa).
|
|
365
|
+
*
|
|
366
|
+
* `ensureWallet` lo llama automáticamente fire-and-forget cuando el
|
|
367
|
+
* status final es `'on-chain'` — el caller solo necesita llamarlo
|
|
368
|
+
* explícitamente si quiere mostrar feedback en la UI durante el funding.
|
|
369
|
+
*/
|
|
370
|
+
fundTestnet(walletAddress: string): Promise<FundTestnetResult>;
|
|
371
|
+
}
|
|
372
|
+
interface FundTestnetResult {
|
|
373
|
+
/** `true` si esta llamada disparó friendbot y fondeó la wallet ahora. */
|
|
374
|
+
readonly funded: boolean;
|
|
375
|
+
/**
|
|
376
|
+
* `true` si la wallet ya había sido fondeada antes (flag local o response
|
|
377
|
+
* de friendbot indicando que la cuenta ya existe). Igualmente válido —
|
|
378
|
+
* la UI puede mostrar "ya tienes XLM" sin pedir acción del user.
|
|
379
|
+
*/
|
|
380
|
+
readonly alreadyFunded: boolean;
|
|
381
|
+
/** Texto explicativo para no-op cases (mainnet, missing record, etc.). */
|
|
382
|
+
readonly reason?: 'mainnet-not-supported' | 'friendbot-error' | 'already-funded' | 'funded-now';
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Input para `tx.send(...)` — manda XLM desde el Smart Account del usuario a
|
|
386
|
+
* cualquier address Stellar (G… clásico o C… contrato).
|
|
387
|
+
*
|
|
388
|
+
* El SDK orquesta todo el flujo: simulate → ECDH F2 → reconstruct seed →
|
|
389
|
+
* sign auth entry → submit. El caller solo entrega los inputs sensibles que
|
|
390
|
+
* vienen de su flow de unlock (WebAuthn PRF + derivación de F2 key).
|
|
391
|
+
*/
|
|
392
|
+
interface SendXlmInput {
|
|
393
|
+
/** Destinatario. G… (clásico) o C… (contrato). */
|
|
394
|
+
readonly destinationAddress: string;
|
|
395
|
+
/** Monto en STROOPS (1 XLM = 10_000_000 stroops). Base-10 string para evitar precisión. */
|
|
396
|
+
readonly amountStroops: string;
|
|
397
|
+
/**
|
|
398
|
+
* F1 (Shamir share encoded incluyendo el byte de índice) ya en plano —
|
|
399
|
+
* típicamente desencriptado client-side via WebAuthn PRF antes de llamar.
|
|
400
|
+
* El SDK lo zero-iza tras combinar con F2.
|
|
401
|
+
*/
|
|
402
|
+
readonly fragmentF1Plain: Uint8Array;
|
|
403
|
+
/**
|
|
404
|
+
* Llave AES-256 con la que el SDK desencripta el F2 envelope que vino
|
|
405
|
+
* del backend. La derivación de esta llave es responsabilidad del caller
|
|
406
|
+
* (usualmente PBKDF2 sobre material derivado de credenciales del user).
|
|
407
|
+
* Se zero-iza al terminar.
|
|
408
|
+
*/
|
|
409
|
+
readonly fragmentF2Key: Uint8Array;
|
|
410
|
+
/**
|
|
411
|
+
* Pubkey ed25519 (32 bytes) del owner del Smart Account. Se usa para:
|
|
412
|
+
* 1) Sanity-check de que la seed reconstruida deriva esta pubkey.
|
|
413
|
+
* 2) Empaquetarla dentro del `Signer::External(verifier, pubkey)` del
|
|
414
|
+
* AuthPayload.
|
|
415
|
+
*/
|
|
416
|
+
readonly ownerPubkey: Uint8Array;
|
|
417
|
+
}
|
|
418
|
+
interface SendXlmResult {
|
|
419
|
+
readonly txHash: string;
|
|
420
|
+
readonly status: string;
|
|
421
|
+
readonly explorerUrl: string;
|
|
422
|
+
}
|
|
423
|
+
interface TxNamespace {
|
|
424
|
+
/**
|
|
425
|
+
* End-to-end XLM transfer desde el Smart Account del user.
|
|
426
|
+
*
|
|
427
|
+
* Flujo interno (no-custodial):
|
|
428
|
+
* 1) `POST /tx/simulate` con `{ amountStroops, destinationAddress }`.
|
|
429
|
+
* 2) Genera X25519 keypair efímero + `POST /fragments/2` con la pubkey.
|
|
430
|
+
* Backend devuelve F2 wrapped en una capa session-key. El SDK la
|
|
431
|
+
* descifra con ECDH + HKDF — la session key NO persiste en disco.
|
|
432
|
+
* 3) Desencripta el F2 envelope interno con `fragmentF2Key` → F2 plain.
|
|
433
|
+
* 4) Combina F1 + F2 vía Shamir → ed25519 seed (32 bytes).
|
|
434
|
+
* 5) Computa `auth_digest = sha256(signature_payload || rule_ids_xdr)`
|
|
435
|
+
* y lo firma con la seed → 64-byte ed25519 sig.
|
|
436
|
+
* 6) Empaqueta el `AuthPayload {signers, context_rule_ids}` ScVal,
|
|
437
|
+
* reemplaza `credentials.address.signature` en la placeholder entry.
|
|
438
|
+
* 7) `POST /tx/submit` con `{ unsignedXdr, signedAuthEntryXdr }`.
|
|
439
|
+
* 8) Devuelve `{ txHash, status, explorerUrl }`.
|
|
440
|
+
*
|
|
441
|
+
* Toda llave plana sale de scope tras la firma. Lanza si:
|
|
442
|
+
* - El backend rechaza simulate/submit.
|
|
443
|
+
* - La reconstrucción Shamir falla (fragmentos no compatibles).
|
|
444
|
+
* - La pubkey derivada de la seed no matchea `ownerPubkey`.
|
|
445
|
+
*/
|
|
446
|
+
send(input: SendXlmInput): Promise<SendXlmResult>;
|
|
447
|
+
/**
|
|
448
|
+
* Bajo nivel: firma un envelope Stellar ya construido con una seed ed25519
|
|
449
|
+
* dada. Útil para flows custom que arman la tx fuera del SDK.
|
|
450
|
+
*/
|
|
451
|
+
signRawXdr(input: {
|
|
452
|
+
transactionXdr: string;
|
|
453
|
+
ed25519Seed: Uint8Array;
|
|
454
|
+
expectedPublicKey?: Uint8Array;
|
|
455
|
+
}): Promise<{
|
|
456
|
+
signedXdr: string;
|
|
457
|
+
publicKey: Uint8Array;
|
|
458
|
+
}>;
|
|
459
|
+
}
|
|
460
|
+
interface KycNamespace {
|
|
461
|
+
start(): Promise<{
|
|
462
|
+
customerId: string;
|
|
463
|
+
status: string;
|
|
464
|
+
hostedUrl: string | null;
|
|
465
|
+
}>;
|
|
466
|
+
status(): Promise<{
|
|
467
|
+
customerId: string;
|
|
468
|
+
status: string;
|
|
469
|
+
hostedUrl: string | null;
|
|
470
|
+
}>;
|
|
471
|
+
}
|
|
472
|
+
interface SessionNamespace {
|
|
473
|
+
/** Create a temporary session key for unattended low-value tx (Soroban policy). */
|
|
474
|
+
create(_opts: {
|
|
475
|
+
readonly ttlSeconds: number;
|
|
476
|
+
readonly maxAmountStroops: string;
|
|
477
|
+
}): Promise<never>;
|
|
478
|
+
/** Revoke a previously-created session key. */
|
|
479
|
+
revoke(_sessionKeyId: string): Promise<never>;
|
|
480
|
+
}
|
|
481
|
+
interface SettingsNamespace {
|
|
482
|
+
/** Add a new device's passkey to an existing wallet (multi-device). */
|
|
483
|
+
addDevice(_secp256r1Pubkey: Uint8Array): Promise<never>;
|
|
484
|
+
/** Remove a device's passkey from the wallet. */
|
|
485
|
+
removeDevice(_secp256r1Pubkey: Uint8Array): Promise<never>;
|
|
486
|
+
/** List all device passkeys registered for the wallet. */
|
|
487
|
+
listDevices(): Promise<never>;
|
|
488
|
+
/** Change the spending limit policy. */
|
|
489
|
+
updateSpendingLimit(_opts: {
|
|
490
|
+
readonly limitStroops: string;
|
|
491
|
+
readonly perDayStroops?: string;
|
|
492
|
+
}): Promise<never>;
|
|
493
|
+
}
|
|
494
|
+
interface YieldNamespace {
|
|
495
|
+
/** Invest USDC into CETES via Etherfuse (50/50 yield share with Accesly). */
|
|
496
|
+
invest(_amountUsdc: string): Promise<never>;
|
|
497
|
+
/** Redeem CETES tokens back into USDC. */
|
|
498
|
+
redeem(_amountTokens: string): Promise<never>;
|
|
499
|
+
/** Read the user's current yield position. */
|
|
500
|
+
position(): Promise<never>;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Stub thrown by every method in the `session`, `settings`, `yield`
|
|
504
|
+
* namespaces. These features are designed but not implemented in v0.1.0 —
|
|
505
|
+
* they unblock with the dashboard work in Fase 7 (`session`/`settings`) and
|
|
506
|
+
* with Etherfuse activation (`yield`).
|
|
507
|
+
*/
|
|
508
|
+
declare class NotImplementedYetError extends Error {
|
|
509
|
+
constructor(namespace: string, method: string);
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Recovery v2 — OTP por email + password de Cognito (Fase 1, 2026-06-15).
|
|
513
|
+
*
|
|
514
|
+
* Flujo desde la UI:
|
|
515
|
+
* 1. `recovery.requestOtp({ email })` → manda el OTP por SES.
|
|
516
|
+
* 2. `recovery.verifyOtp({ email, code })` → devuelve `recoveryJwt`.
|
|
517
|
+
* 3. `recovery.finalize({ email, password, recoveryJwt })` orquesta todo:
|
|
518
|
+
* - GET /fragments/3 con el JWT
|
|
519
|
+
* - Deriva recoveryKey con el password + recoverySalt del backend
|
|
520
|
+
* - Decifra F3
|
|
521
|
+
* - Decifra F2 (vía session key ECDH)
|
|
522
|
+
* - Combina F2+F3 → seed ed25519 reconstruida
|
|
523
|
+
* - Genera new passkey + new Shamir split (F1', F2', F3')
|
|
524
|
+
* - Re-cifra F3' con la misma recoveryKey + nuevo salt
|
|
525
|
+
* - Firma la tx `rotate_signer` localmente
|
|
526
|
+
* - POST /recovery/finalize con todo
|
|
527
|
+
* - Persiste new CredentialRecord local
|
|
528
|
+
* - Zero-iza la seed
|
|
529
|
+
*/
|
|
530
|
+
interface ReconstructedSeed {
|
|
531
|
+
/** 32-byte ed25519 seed reconstruida vía Shamir(F2_recovery + F3). CALLER ZEROIZE. */
|
|
532
|
+
readonly privateSeed: Uint8Array;
|
|
533
|
+
/** 32-byte ed25519 public key derivada. */
|
|
534
|
+
readonly publicKey: Uint8Array;
|
|
535
|
+
/** 32-byte recoveryKey derivada del password — útil para re-cifrar F2'/F3' nuevos. */
|
|
536
|
+
readonly recoveryKey: Uint8Array;
|
|
537
|
+
/** Base64 32-byte salt que vino del backend. */
|
|
538
|
+
readonly recoverySalt: string;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Input para `recovery.finalize(...)` — **orquestador end-to-end**. El integrador
|
|
542
|
+
* solo provee email + password + recoveryJwt; el SDK hace TODO el resto:
|
|
543
|
+
*
|
|
544
|
+
* 1. `reconstructSeed(...)` con el password → seed VIEJA + recoveryKey.
|
|
545
|
+
* 2. `registerPasskey(...)` con PRF → nuevo credentialId + secp256r1Pubkey + prfOutput.
|
|
546
|
+
* 3. HKDF(prfOutput, encryptionSalt, "accesly-{f1,f2}-encryption") → newF1Key + newF2Key.
|
|
547
|
+
* 4. Genera new ed25519 seed + Shamir 2-of-3 + cifra F1'/F2' con PRF keys, F3' con recoveryKey.
|
|
548
|
+
* 5. `POST /recovery/simulate-rotate-signer` → backend arma + simula.
|
|
549
|
+
* 6. Firma `SorobanAuthorizationEntry` con la SEED VIEJA contra `admin-cfg`.
|
|
550
|
+
* 7. `POST /recovery/finalize` con auth entry firmada + new fragments.
|
|
551
|
+
* 8. Persiste new `CredentialRecord` (con `encryptionSalt`) en `DeviceStore`.
|
|
552
|
+
* 9. Zeroiza TODAS las llaves intermedias (privateSeed vieja, recoveryKey, PRF output, password).
|
|
553
|
+
*/
|
|
554
|
+
interface FinalizeRecoveryInput {
|
|
555
|
+
/** Email del usuario (case-insensitive, se normaliza). */
|
|
556
|
+
readonly email: string;
|
|
557
|
+
/**
|
|
558
|
+
* Password de Cognito (string). El SDK lo encoda a UTF-8 internamente y lo
|
|
559
|
+
* zeroiza tras la operación. No retengas referencias.
|
|
560
|
+
*/
|
|
561
|
+
readonly password: string;
|
|
562
|
+
/** Token KMS-HMAC que devolvió `verifyOtp()` — TTL 5min. */
|
|
563
|
+
readonly recoveryJwt: string;
|
|
564
|
+
/**
|
|
565
|
+
* Overrides opcionales para el `registerPasskey` interno (mismo shape que
|
|
566
|
+
* `wallet.bootstrap`). Caso típico: `rpName: 'MiApp'`.
|
|
567
|
+
*/
|
|
568
|
+
readonly passkey?: {
|
|
569
|
+
readonly rpId?: string;
|
|
570
|
+
readonly rpName?: string;
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
interface FinalizeRecoveryResult {
|
|
574
|
+
readonly walletAddress: string;
|
|
575
|
+
readonly txHash: string;
|
|
576
|
+
readonly status: string;
|
|
577
|
+
/** Pubkey ed25519 NUEVA (32 bytes). Útil para UI confirmación. */
|
|
578
|
+
readonly newPublicKey: Uint8Array;
|
|
579
|
+
/** Link al explorer. */
|
|
580
|
+
readonly explorerUrl: string;
|
|
581
|
+
}
|
|
582
|
+
interface RecoveryNamespace {
|
|
583
|
+
/** Pide OTP. Backend rate-limita; el caller debe respetar `cooldownSeconds`. */
|
|
584
|
+
requestOtp(input: {
|
|
585
|
+
email: string;
|
|
586
|
+
}): Promise<{
|
|
587
|
+
cooldownSeconds: number;
|
|
588
|
+
expiresInSeconds: number;
|
|
589
|
+
}>;
|
|
590
|
+
/** Verifica OTP. Devuelve `recoveryJwt` con TTL 5min. */
|
|
591
|
+
verifyOtp(input: {
|
|
592
|
+
email: string;
|
|
593
|
+
code: string;
|
|
594
|
+
}): Promise<{
|
|
595
|
+
recoveryJwt: string;
|
|
596
|
+
expiresAt: number;
|
|
597
|
+
}>;
|
|
598
|
+
/**
|
|
599
|
+
* Descarga `/fragments/3`, descifra F2_recovery + F3 con la `recoveryKey`
|
|
600
|
+
* derivada del password y reconstruye la seed via Shamir.
|
|
601
|
+
*
|
|
602
|
+
* El caller DEBE zero-izar `result.privateSeed` y `result.recoveryKey`
|
|
603
|
+
* tras firmar la rotación + cifrar las nuevas F1'/F2'/F3'.
|
|
604
|
+
*
|
|
605
|
+
* El caller también es responsable de zeroizar `cognitoPassword` después.
|
|
606
|
+
*/
|
|
607
|
+
reconstructSeed(input: {
|
|
608
|
+
cognitoPassword: Uint8Array;
|
|
609
|
+
recoveryJwt: string;
|
|
610
|
+
}): Promise<ReconstructedSeed>;
|
|
611
|
+
/**
|
|
612
|
+
* Orquestador completo de la rotación de signers para Recovery v2.
|
|
613
|
+
* Ver `FinalizeRecoveryInput` para los pre-requisitos.
|
|
614
|
+
*/
|
|
615
|
+
finalize(input: FinalizeRecoveryInput): Promise<FinalizeRecoveryResult>;
|
|
616
|
+
/**
|
|
617
|
+
* Bajo nivel: submitea la rotación al backend tras que el caller haya
|
|
618
|
+
* armado el body manualmente. `finalize(...)` es el wrapper recomendado.
|
|
619
|
+
*/
|
|
620
|
+
submitFinalize(input: {
|
|
621
|
+
recoveryJwt: string;
|
|
622
|
+
unsignedXdr: string;
|
|
623
|
+
signedAuthEntryXdr: string;
|
|
624
|
+
newOwnerEd25519Pubkey: string;
|
|
625
|
+
newSecp256r1Pubkey: string;
|
|
626
|
+
newFragmentF1Encrypted: EncryptedEnvelope;
|
|
627
|
+
newFragmentF2Encrypted: EncryptedEnvelope;
|
|
628
|
+
newFragmentF2Recovery: EncryptedEnvelope;
|
|
629
|
+
newFragmentF3Encrypted: EncryptedEnvelope;
|
|
630
|
+
newRecoverySalt: string;
|
|
631
|
+
newEmailCommitment: string;
|
|
632
|
+
}): Promise<{
|
|
633
|
+
walletAddress: string;
|
|
634
|
+
txHash: string;
|
|
635
|
+
status: string;
|
|
636
|
+
}>;
|
|
637
|
+
}
|
|
638
|
+
interface AcceslyHook {
|
|
639
|
+
readonly auth: AuthNamespace;
|
|
640
|
+
readonly wallet: WalletNamespace;
|
|
641
|
+
readonly tx: TxNamespace;
|
|
642
|
+
readonly kyc: KycNamespace;
|
|
643
|
+
readonly recovery: RecoveryNamespace;
|
|
644
|
+
readonly session: SessionNamespace;
|
|
645
|
+
readonly settings: SettingsNamespace;
|
|
646
|
+
readonly yieldOps: YieldNamespace;
|
|
647
|
+
/** Raw context, for advanced use cases (custom telemetry, manual refresh). */
|
|
648
|
+
readonly _internal: AcceslyContextValue;
|
|
649
|
+
}
|
|
650
|
+
declare function useAccesly(): AcceslyHook;
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* `useWalletStatus()` — hook event-driven que sustituye al
|
|
654
|
+
* `setInterval(fetchRemote, 30_000)` que cada integrador escribía en su
|
|
655
|
+
* `Wallet.tsx` / `CreateWallet.tsx`.
|
|
656
|
+
*
|
|
657
|
+
* Comportamiento:
|
|
658
|
+
*
|
|
659
|
+
* 1. **SSE-first.** Si la infra del backend expone `GET /wallets/stream`
|
|
660
|
+
* (Lambda function URL con response streaming), el hook se suscribe vía
|
|
661
|
+
* `EventSource` y reacciona instantáneamente a cambios on-chain. Cero
|
|
662
|
+
* polling, cero latencia.
|
|
663
|
+
*
|
|
664
|
+
* 2. **Polling con backoff inteligente como fallback.** Si SSE no está
|
|
665
|
+
* disponible (backend viejo, sandbox sin streaming, browser sin
|
|
666
|
+
* `EventSource`), cae a polling con backoff exponencial:
|
|
667
|
+
* - mientras la wallet NO está `'on-chain'`: 2s → 5s → 10s → 20s →
|
|
668
|
+
* 30s (cap).
|
|
669
|
+
* - si llega `'on-chain'` o el tab queda oculto: polling pausado.
|
|
670
|
+
* - llamadas de `refresh()` resetean el backoff a 2s.
|
|
671
|
+
* Mucho mejor UX que el `30s` constante del legacy.
|
|
672
|
+
*
|
|
673
|
+
* 3. **`document.visibilityState` aware.** Pausa cuando el tab está oculto;
|
|
674
|
+
* retoma + refresca inmediatamente cuando vuelve a visible.
|
|
675
|
+
*
|
|
676
|
+
* 4. **Cross-tab via `BroadcastChannel`.** Si el user tiene la app abierta
|
|
677
|
+
* en 2 tabs, el primero que reciba un update lo emite por el canal
|
|
678
|
+
* `accesly:wallet:<username>` y los otros tabs lo aplican sin hacer su
|
|
679
|
+
* propio fetch — un solo round-trip por update.
|
|
680
|
+
*
|
|
681
|
+
* Devuelve `{ status, walletAddress, onChain, isStale, refresh }`. `refresh()`
|
|
682
|
+
* fuerza un fetch inmediato + resetea backoff. `isStale` = `true` si no se ha
|
|
683
|
+
* podido confirmar status en > 60s (red/Soroban RPC caído).
|
|
684
|
+
*/
|
|
685
|
+
type WalletStatusValue = 'on-chain' | 'pending-deploy' | 'unknown' | 'no-wallet';
|
|
686
|
+
interface UseWalletStatusResult {
|
|
687
|
+
/** Status actual. `'no-wallet'` si el backend nunca recibió un POST /wallets. */
|
|
688
|
+
readonly status: WalletStatusValue;
|
|
689
|
+
/** Address C…, o null si no hay wallet. */
|
|
690
|
+
readonly walletAddress: string | null;
|
|
691
|
+
/** Mirror del campo `onChain` del backend (true / false / null). */
|
|
692
|
+
readonly onChain: boolean | null;
|
|
693
|
+
/** True si el último fetch exitoso fue hace más de 60s — UI puede mostrar warning. */
|
|
694
|
+
readonly isStale: boolean;
|
|
695
|
+
/** Fuerza fetch inmediato + resetea backoff. Llamalo tras submit/recovery. */
|
|
696
|
+
refresh(): Promise<void>;
|
|
697
|
+
}
|
|
698
|
+
declare function useWalletStatus(): UseWalletStatusResult;
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* `useBalance(walletAddress?)` — hook que devuelve el balance XLM del Smart
|
|
702
|
+
* Account con auto-refresh.
|
|
703
|
+
*
|
|
704
|
+
* Si no se le pasa `walletAddress`, intenta auto-resolverlo via
|
|
705
|
+
* `wallet.getStoredCredential(username)` del DeviceStore — el flujo más
|
|
706
|
+
* común (un solo wallet por user en este device).
|
|
707
|
+
*
|
|
708
|
+
* Polling: 8s mientras tab visible, pausa cuando hidden, retoma al volver.
|
|
709
|
+
* También se refresca inmediatamente cuando `useWalletStatus` reporta
|
|
710
|
+
* `'on-chain'` (via cross-tab `BroadcastChannel`) para mostrar el balance
|
|
711
|
+
* tras un deploy fresco.
|
|
712
|
+
*/
|
|
713
|
+
interface UseBalanceResult {
|
|
714
|
+
/** Stroops como string base-10. `null` mientras se carga o no hay address. */
|
|
715
|
+
readonly stroops: string | null;
|
|
716
|
+
/** Mismo balance como string decimal en XLM. `null` mientras se carga. */
|
|
717
|
+
readonly xlm: string | null;
|
|
718
|
+
/** True durante el primer fetch (subsiguientes ediciones son silent). */
|
|
719
|
+
readonly isLoading: boolean;
|
|
720
|
+
/** Error del último fetch, si lo hubo. */
|
|
721
|
+
readonly error: Error | null;
|
|
722
|
+
/** Fuerza fetch inmediato. */
|
|
723
|
+
refresh(): Promise<void>;
|
|
724
|
+
}
|
|
725
|
+
declare function useBalance(walletAddress?: string | null): UseBalanceResult;
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* `useWalletActivity(walletAddress?, opts?)` — hook que devuelve los últimos
|
|
729
|
+
* eventos on-chain del Smart Account, auto-refrescados cada 20s mientras la
|
|
730
|
+
* tab está visible.
|
|
731
|
+
*
|
|
732
|
+
* Pasos:
|
|
733
|
+
* 1. Resuelve `walletAddress` desde el DeviceStore si no se pasa explícito.
|
|
734
|
+
* 2. Fetch inicial inmediato → guarda en estado.
|
|
735
|
+
* 3. Polling cada 20s (pausado si tab oculta).
|
|
736
|
+
* 4. `refresh()` para fetch on-demand tras una operación del user.
|
|
737
|
+
*
|
|
738
|
+
* Mejor UX que el "ver explorer link" porque la app puede renderizar la
|
|
739
|
+
* lista de tx en su propio look — sin abrir otro tab a Stellar Expert.
|
|
740
|
+
*/
|
|
741
|
+
|
|
742
|
+
interface UseWalletActivityOptions {
|
|
743
|
+
/** Cantidad de eventos a pedir. Default 20, max 50. */
|
|
744
|
+
readonly limit?: number;
|
|
745
|
+
}
|
|
746
|
+
interface UseWalletActivityResult {
|
|
747
|
+
readonly events: readonly WalletActivityEvent[];
|
|
748
|
+
readonly isLoading: boolean;
|
|
749
|
+
readonly error: Error | null;
|
|
750
|
+
refresh(): Promise<void>;
|
|
751
|
+
}
|
|
752
|
+
declare function useWalletActivity(walletAddress?: string | null, opts?: UseWalletActivityOptions): UseWalletActivityResult;
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* @accesly/react — React Provider + `useAccesly` hook.
|
|
756
|
+
*
|
|
757
|
+
* Wraps `@accesly/core` for React 18+. Apps integrate with:
|
|
758
|
+
*
|
|
759
|
+
* import { AcceslyProvider, useAccesly } from '@accesly/react';
|
|
760
|
+
*
|
|
761
|
+
* function App() {
|
|
762
|
+
* return (
|
|
763
|
+
* <AcceslyProvider appId="my-app" env="dev">
|
|
764
|
+
* <YourApp />
|
|
765
|
+
* </AcceslyProvider>
|
|
766
|
+
* );
|
|
767
|
+
* }
|
|
768
|
+
*
|
|
769
|
+
* function Login() {
|
|
770
|
+
* const { auth } = useAccesly();
|
|
771
|
+
* return (
|
|
772
|
+
* <button onClick={() => auth.signIn(email, password)}>Sign in</button>
|
|
773
|
+
* );
|
|
774
|
+
* }
|
|
775
|
+
*/
|
|
776
|
+
declare const REACT_ADAPTER_VERSION = "0.0.0";
|
|
777
|
+
|
|
778
|
+
export { AcceslyContext, type AcceslyContextValue, type AcceslyHook, AcceslyProvider, type AcceslyProviderProps, type AuthNamespace, type BootstrapWalletInput, type CreateWalletInput, type CreatedWalletInfo, ENVIRONMENT_DEFAULTS, type EnsureWalletResult, type EnvironmentDefaults, type FinalizeRecoveryInput, type FinalizeRecoveryResult, type KycNamespace, NotImplementedYetError, REACT_ADAPTER_VERSION, type ReconstructedSeed, type RecoveryNamespace, type RemoteWalletInfo, type RetryDeployResult, type SendXlmInput, type SendXlmResult, type SessionNamespace, type SettingsNamespace, type TxNamespace, type UnlockedSigningMaterial, type UseBalanceResult, type UseWalletActivityOptions, type UseWalletActivityResult, type UseWalletStatusResult, type WalletNamespace, type WalletStatus, type WalletStatusValue, type YieldNamespace, useAccesly, useBalance, useWalletActivity, useWalletStatus };
|