@accesly/react 1.3.1 → 1.3.2
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 +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.ts","../src/config.ts","../src/hooks/sorobanDeployStatus.ts","../src/hooks/useWalletHistory.ts","../src/hooks/useAccesly.ts","../src/provider.tsx","../src/index.ts","../src/hooks/useWalletStatus.ts","../src/hooks/walletSubscription.ts","../src/hooks/useBalance.ts","../src/hooks/useWalletActivity.ts"],"names":["AcceslyContext","createContext","ENVIRONMENT_DEFAULTS","AccesslyApiError","useRef","useState","useEffect","useCallback","useContext","useMemo","computeSmartAccountAddress","normalizeSecp256r1Pubkey","coreCreateWallet","generateRecoverySalt","decryptAesGcm","deriveRecoveryKey","encryptAesGcm","emailHashBytes","c","sha256","getRandomBytes","registerPasskey","hkdfSha256","zeroize","unlockPasskey","generateX25519Keypair","unwrapSessionFragment2","reconstructFromPlainAndEncrypted","signSorobanAuthEntry","historyOptimisticPush","coreSignTransaction","reconstructKey","NotImplementedYetError","CognitoAuthClient","defaultSessionStorage","InMemoryDeviceStore","TokenManager","AccesslyApiClient","AccesslyEndpoints","useStableRef","POLL_FALLBACK_MS"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * React context internals — keep separate from the Provider component to\n * make refactors and tests cleaner.\n */\n\nimport { createContext } from 'react';\nimport type {\n AccesslyEndpoints,\n AuthClient,\n AuthStatus,\n CognitoConfig,\n DeviceStore,\n Environment,\n SessionStorage,\n TokenManager,\n} from '@accesly/core';\n\nexport interface AcceslyContextValue {\n readonly appId: string;\n readonly env: Environment;\n readonly apiUrl: string;\n readonly cognitoConfig: CognitoConfig;\n readonly authClient: AuthClient;\n readonly sessionStorage: SessionStorage;\n readonly tokenManager: TokenManager;\n readonly endpoints: AccesslyEndpoints;\n readonly deviceStore: DeviceStore;\n /** Current auth status — re-rendered whenever it changes. */\n readonly status: AuthStatus;\n readonly username: string | null;\n /** Force a re-read of `tokenManager.getStatus()`. */\n readonly refreshStatus: () => Promise<void>;\n}\n\nexport const AcceslyContext = createContext<AcceslyContextValue | null>(null);\n","/**\n * Per-environment defaults — currently the only public stage is `dev`. The\n * others are placeholders so the SDK API doesn't change when `staging`/`prod`\n * come online (Fase 7+ / Fase 10).\n */\n\nimport type { CognitoConfig, Environment } from '@accesly/core';\n\nexport interface EnvironmentDefaults {\n readonly apiUrl: string;\n /**\n * Lambda Function URL del `wallet-stream` Lambda — Server-Sent Events\n * que multiplexa status + balance + activity en una sola conexión.\n * Si está vacío, los hooks `useBalance` / `useWalletActivity` /\n * `useWalletStatus` caen al polling fallback (mucho menos eficiente).\n */\n readonly walletStreamUrl: string;\n readonly cognito: CognitoConfig;\n readonly stellar: {\n readonly networkPassphrase: string;\n readonly horizonUrl: string;\n readonly sorobanRpcUrl: string;\n /**\n * Stellar G-address of the account that invokes `CreateContract` for new\n * Smart Accounts. Same account the backend Lambda uses, so the wallet\n * address computed client-side via `wallet.computeAddress` matches\n * exactly what the backend will (or did) deploy.\n */\n readonly deployerAddress: string;\n /**\n * Address del contrato `ed25519-verifier` desplegado en la red. Necesario\n * cuando el SDK construye la entrada `Signer::External(verifier, pubkey)`\n * dentro del `AuthPayload` que firma — el Smart Account compara con la\n * misma address que tiene almacenada en su context rule.\n */\n readonly ed25519VerifierAddress: string;\n };\n}\n\nexport const ENVIRONMENT_DEFAULTS: Record<Environment, EnvironmentDefaults> = {\n dev: {\n apiUrl: 'https://3fki7eiio5.execute-api.us-east-1.amazonaws.com/dev',\n walletStreamUrl: 'https://ajlmn37thw7fxen3oyykbfmlrm0eecue.lambda-url.us-east-1.on.aws/',\n cognito: {\n region: 'us-east-1',\n userPoolId: 'us-east-1_K2Nag1tB1',\n userPoolClientId: '6r64diep7pne50sender4557jt',\n },\n stellar: {\n networkPassphrase: 'Test SDF Network ; September 2015',\n horizonUrl: 'https://horizon-testnet.stellar.org',\n sorobanRpcUrl: 'https://soroban-testnet.stellar.org',\n // OZ Relayer channels-fund — see CloudServices-accesly/docs/Deployed_Resources_dev.md\n deployerAddress: 'GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E',\n // accesly-contracts Phase 1 deploy on Stellar testnet.\n ed25519VerifierAddress: 'CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5',\n },\n },\n staging: {\n apiUrl: 'https://api-staging.accesly.xyz',\n walletStreamUrl: '',\n cognito: {\n region: 'us-east-1',\n userPoolId: 'TBD-staging',\n userPoolClientId: 'TBD-staging',\n },\n stellar: {\n networkPassphrase: 'Test SDF Network ; September 2015',\n horizonUrl: 'https://horizon-testnet.stellar.org',\n sorobanRpcUrl: 'https://soroban-testnet.stellar.org',\n deployerAddress: 'GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E',\n ed25519VerifierAddress: 'CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5',\n },\n },\n prod: {\n apiUrl: 'https://api.accesly.xyz',\n walletStreamUrl: '',\n cognito: {\n region: 'us-east-1',\n userPoolId: 'TBD-prod',\n userPoolClientId: 'TBD-prod',\n },\n stellar: {\n networkPassphrase: 'Public Global Stellar Network ; September 2015',\n horizonUrl: 'https://horizon.stellar.org',\n sorobanRpcUrl: 'https://soroban-rpc.mainnet.stellar.org',\n deployerAddress: 'TBD-prod',\n ed25519VerifierAddress: 'TBD-prod',\n },\n },\n};\n","/**\n * Recognises backend `POST /wallets` failures that are KNOWN to leave the\n * wallet record on the backend (Soroban submit rejected the deploy — typical\n * after Soroban protocol v26 lowered the resource caps).\n *\n * In these cases the SDK does NOT throw: `wallet.createWallet` returns\n * `status: 'pending-deploy'` with the client-side-predicted address so the\n * app can render normally and call `wallet.retryDeploy` later (or wait for\n * the contracts team to slim the constructor and let the backend's\n * auto-retry land it).\n *\n * Recognised patterns (case-insensitive substring match against the error\n * message and code):\n * - `txSorobanInvalid` — Soroban RPC rejected the envelope shape\n * - `Soroban sendTransaction` — generic submit rejection\n * - `soroban submit failed` — backend wrapper message\n * - `scecExceededLimit` / `exceededLimit` — protocol v26 cap exceeded\n */\n\nimport { AccesslyApiError } from '@accesly/core';\n\nexport function isSorobanDeployPendingError(err: unknown): boolean {\n if (!(err instanceof AccesslyApiError)) return false;\n const haystack = `${err.message ?? ''} ${err.code ?? ''}`.toLowerCase();\n return (\n haystack.includes('txsorobaninvalid') ||\n haystack.includes('soroban sendtransaction') ||\n haystack.includes('soroban submit failed') ||\n haystack.includes('scecexceededlimit') ||\n haystack.includes('exceededlimit')\n );\n}\n","/**\n * `useWalletHistory(walletAddress?, opts?)` — historial completo de la wallet\n * pre-decodificado desde Stellar Expert (indexer free, full retention).\n *\n * El backend de Accesly **proxea** las requests a Stellar Expert porque SE\n * bloquea CORS desde browsers (Cloudflare retorna 403 en cross-origin). El\n * proxy hace el call server-side, decodea topics + amounts, y devuelve items\n * tipados listos para renderizar.\n *\n * Features:\n * - Cache en `localStorage` per-wallet con TTL 12h → render instantáneo en\n * reloads + navegación.\n * - Polling cada 30s para nuevos events. Pausa si tab oculta.\n * - `BroadcastChannel` cross-tab para compartir fetches — solo UN tab hace\n * el request, los demás escuchan el resultado vía canal.\n * - Optimistic updates: el SDK inserta el item al instante cuando `tx.send`\n * confirma, sin esperar el indexing de SE (~30-60s típico).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { WalletHistoryItem } from '@accesly/core';\nimport { useAccesly } from './useAccesly.js';\nimport type { WalletActivityItem } from './walletSubscription.js';\n\nconst POLL_INTERVAL_MS = 30_000;\nconst CACHE_TTL_MS = 12 * 60 * 60 * 1000;\nconst CACHE_KEY_PREFIX = 'accesly:history:';\nconst BROADCAST_CHANNEL_PREFIX = 'accesly:history:';\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\ninterface Cursors {\n readonly smartAccount: string | null;\n readonly transfers: string | null;\n}\n\ninterface CacheEntry {\n readonly items: WalletHistoryItem[];\n readonly cursors: Cursors;\n readonly storedAt: number;\n}\n\nfunction loadCache(walletAddress: string): CacheEntry | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(CACHE_KEY_PREFIX + walletAddress);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as CacheEntry;\n if (Date.now() - parsed.storedAt > CACHE_TTL_MS) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction saveCache(walletAddress: string, entry: CacheEntry): void {\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.setItem(CACHE_KEY_PREFIX + walletAddress, JSON.stringify(entry));\n } catch {\n /* quota / disabled — no-op */\n }\n}\n\n/* ── Optimistic update store ─────────────────────────────────────────────── */\n\nconst optimisticItems = new Map<string, WalletHistoryItem[]>();\nconst optimisticListeners = new Map<string, Set<(items: WalletHistoryItem[]) => void>>();\n\n/**\n * Inyecta un item de history \"optimistically\" — útil cuando acabás de hacer\n * `tx.send` y querés que aparezca al instante sin esperar el indexing de SE.\n * El item queda hasta que el próximo fetch confirma que ya está en el feed.\n */\nexport function historyOptimisticPush(\n walletAddress: string,\n item: WalletHistoryItem | WalletActivityItem,\n): void {\n const current = optimisticItems.get(walletAddress) ?? [];\n optimisticItems.set(walletAddress, [item as WalletHistoryItem, ...current]);\n const listeners = optimisticListeners.get(walletAddress);\n if (listeners) {\n for (const fn of listeners) fn(optimisticItems.get(walletAddress) ?? []);\n }\n}\n\nexport function historyClearOptimistic(walletAddress: string): void {\n optimisticItems.delete(walletAddress);\n const listeners = optimisticListeners.get(walletAddress);\n if (listeners) {\n for (const fn of listeners) fn([]);\n }\n}\n\nfunction subscribeOptimistic(\n walletAddress: string,\n listener: (items: WalletHistoryItem[]) => void,\n): () => void {\n let set = optimisticListeners.get(walletAddress);\n if (!set) {\n set = new Set();\n optimisticListeners.set(walletAddress, set);\n }\n set.add(listener);\n return () => {\n set?.delete(listener);\n if (set && set.size === 0) optimisticListeners.delete(walletAddress);\n };\n}\n\n/* ── Hook ─────────────────────────────────────────────────────────────────── */\n\nexport interface UseWalletHistoryOptions {\n /** Intervalo de poll para nuevos events (ms). Default 30s, 0 desactiva. */\n readonly pollIntervalMs?: number;\n /**\n * Cuántos transfers del XLM_SAC scan-ear por fetch. Default 50, max 500\n * (5 paginated calls). En testnet hay millones de transfers globalmente; si\n * tu wallet tiene pocos transfers, sube este número para encontrarlos.\n */\n readonly transferScanLimit?: number;\n}\n\nexport interface UseWalletHistoryResult {\n readonly events: readonly WalletHistoryItem[];\n readonly isLoading: boolean;\n readonly error: Error | null;\n readonly hasMore: boolean;\n loadMore(): Promise<void>;\n refresh(): Promise<void>;\n}\n\nexport function useWalletHistory(\n walletAddress?: string | null,\n opts: UseWalletHistoryOptions = {},\n): UseWalletHistoryResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n\n const [resolvedAddress, setResolvedAddress] = useState<string | null>(walletAddress ?? null);\n const [events, setEvents] = useState<WalletHistoryItem[]>([]);\n const [optimistic, setOptimistic] = useState<WalletHistoryItem[]>([]);\n const [cursors, setCursors] = useState<Cursors>({ smartAccount: null, transfers: null });\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [hasMore, setHasMore] = useState(true);\n\n // Resolver address.\n const walletRef = useStableRef(wallet);\n useEffect(() => {\n if (walletAddress) {\n setResolvedAddress(walletAddress);\n return;\n }\n if (!username) {\n setResolvedAddress(null);\n return;\n }\n let cancelled = false;\n void (async () => {\n try {\n const stored = await walletRef.current.getStoredCredential(username);\n if (cancelled) return;\n setResolvedAddress(stored?.walletAddress ?? null);\n } catch {\n if (!cancelled) setResolvedAddress(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [walletAddress, username, walletRef]);\n\n // Optimistic items.\n useEffect(() => {\n if (!resolvedAddress) return undefined;\n setOptimistic(optimisticItems.get(resolvedAddress) ?? []);\n return subscribeOptimistic(resolvedAddress, setOptimistic);\n }, [resolvedAddress]);\n\n // Cache + primer fetch.\n const endpointsRef = useStableRef(_internal.endpoints);\n const transferScanLimit = opts.transferScanLimit ?? 50;\n\n useEffect(() => {\n if (!resolvedAddress) {\n setIsLoading(false);\n return undefined;\n }\n\n // Replay cache.\n const cached = loadCache(resolvedAddress);\n if (cached) {\n setEvents(cached.items);\n setCursors(cached.cursors);\n setIsLoading(false);\n }\n\n let cancelled = false;\n const channel =\n typeof BroadcastChannel !== 'undefined'\n ? new BroadcastChannel(BROADCAST_CHANNEL_PREFIX + resolvedAddress)\n : null;\n\n if (channel) {\n channel.onmessage = (ev) => {\n const data = ev.data as CacheEntry | undefined;\n if (data && !cancelled) {\n setEvents(data.items);\n setCursors(data.cursors);\n setIsLoading(false);\n }\n };\n }\n\n void (async () => {\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n transferScanLimit,\n });\n if (cancelled) return;\n const deduped = dedupItems(result.events as WalletHistoryItem[]);\n setEvents(deduped);\n setCursors(result.cursors);\n setIsLoading(false);\n setError(null);\n setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);\n\n const entry: CacheEntry = {\n items: deduped,\n cursors: result.cursors,\n storedAt: Date.now(),\n };\n saveCache(resolvedAddress, entry);\n channel?.postMessage(entry);\n } catch (err) {\n if (!cancelled) {\n setError(err as Error);\n setIsLoading(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n channel?.close();\n };\n }, [resolvedAddress, transferScanLimit, endpointsRef]);\n\n // Polling.\n const interval = opts.pollIntervalMs ?? POLL_INTERVAL_MS;\n useEffect(() => {\n if (!resolvedAddress || interval === 0) return undefined;\n\n const tick = async () => {\n if (typeof document !== 'undefined' && document.hidden) return;\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n transferScanLimit,\n });\n setEvents((prev) => mergeAndDedup(prev, result.events as WalletHistoryItem[]));\n // Limpiar optimistics ya confirmados.\n const realTxHashes = new Set(result.events.map((it) => it.txHash));\n const current = optimisticItems.get(resolvedAddress) ?? [];\n const remaining = current.filter((it) => !realTxHashes.has(it.txHash));\n if (remaining.length !== current.length) {\n optimisticItems.set(resolvedAddress, remaining);\n const listeners = optimisticListeners.get(resolvedAddress);\n if (listeners) for (const fn of listeners) fn(remaining);\n }\n } catch {\n /* silenciar errores del polling */\n }\n };\n\n const id = setInterval(tick, interval);\n return () => clearInterval(id);\n }, [resolvedAddress, interval, transferScanLimit, endpointsRef]);\n\n const loadMoreImpl = useCallback(async () => {\n if (!resolvedAddress) return;\n if (!cursors.smartAccount && !cursors.transfers) {\n setHasMore(false);\n return;\n }\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n ...(cursors.smartAccount ? { smartAccountCursor: cursors.smartAccount } : {}),\n ...(cursors.transfers ? { transfersCursor: cursors.transfers } : {}),\n transferScanLimit,\n });\n setEvents((prev) => mergeAndDedup(prev, result.events as WalletHistoryItem[]));\n setCursors(result.cursors);\n setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);\n } catch (err) {\n setError(err as Error);\n }\n }, [resolvedAddress, cursors, transferScanLimit, endpointsRef]);\n\n const refreshImpl = useCallback(async () => {\n if (!resolvedAddress) return;\n setIsLoading(true);\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n transferScanLimit,\n });\n const deduped = dedupItems(result.events as WalletHistoryItem[]);\n setEvents(deduped);\n setCursors(result.cursors);\n setError(null);\n saveCache(resolvedAddress, {\n items: deduped,\n cursors: result.cursors,\n storedAt: Date.now(),\n });\n } catch (err) {\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [resolvedAddress, transferScanLimit, endpointsRef]);\n\n // Combinar optimistic items con events reales.\n const combined = [...optimistic, ...events];\n\n return {\n events: combined,\n isLoading,\n error,\n hasMore,\n loadMore: loadMoreImpl,\n refresh: refreshImpl,\n };\n}\n\n/* ── Helpers ──────────────────────────────────────────────────────────────── */\n\nfunction dedupItems(items: WalletHistoryItem[]): WalletHistoryItem[] {\n const seen = new Set<string>();\n const out: WalletHistoryItem[] = [];\n for (const item of items) {\n const key = `${item.type}:${item.txHash}:${item.ledger}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(item);\n }\n out.sort((a, b) => b.ledger - a.ledger);\n return out;\n}\n\nfunction mergeAndDedup(\n prev: readonly WalletHistoryItem[],\n fresh: readonly WalletHistoryItem[],\n): WalletHistoryItem[] {\n return dedupItems([...fresh, ...prev]);\n}\n","/**\n * `useAccesly()` — single hook with namespaces:\n * - auth — signUp / confirmSignUp / signIn / signOut / status\n * - wallet — createWallet, getStoredWallet\n * - tx — sendPayment, signRawXdr\n * - kyc — start, status\n *\n * The hook returns stable references when the underlying SDK instances don't\n * change. Each namespace is built lazily (memoised) so apps that only use\n * `auth` don't bring `wallet` into their render.\n */\n\nimport { useContext, useMemo } from 'react';\nimport {\n computeSmartAccountAddress,\n createWallet as coreCreateWallet,\n decryptAesGcm,\n deriveRecoveryKey,\n emailHashBytes,\n encryptAesGcm,\n generateRecoverySalt,\n generateX25519Keypair,\n getRandomBytes,\n hkdfSha256,\n normalizeSecp256r1Pubkey,\n reconstructFromPlainAndEncrypted,\n reconstructKey,\n registerPasskey,\n sha256,\n signSorobanAuthEntry,\n signTransaction as coreSignTransaction,\n unlockPasskey,\n unwrapSessionFragment2,\n zeroize,\n type AuthStatus,\n type CredentialRecord,\n type EncryptedEnvelope,\n} from '@accesly/core';\nimport { AcceslyContext, type AcceslyContextValue } from '../context.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\n\n// Recovery (ZK email) se removió en 1.0.0-pre.0 (2026-06-15). El nuevo modelo\n// OTP-email + password de Cognito se introduce en 1.0.0 como un namespace\n// `recovery` en este mismo hook. Ver docs/Plan_Final_v1.md §5.\n\nexport interface AuthNamespace {\n readonly status: AuthStatus;\n readonly username: string | null;\n signUp(email: string, password: string): Promise<{ userSub: string; userConfirmed: boolean }>;\n confirmSignUp(email: string, code: string): Promise<void>;\n resendConfirmation(email: string): Promise<void>;\n signIn(email: string, password: string): Promise<void>;\n signOut(): Promise<void>;\n}\n\nexport interface CreateWalletInput {\n readonly email: string;\n readonly emailSalt: Uint8Array;\n readonly encryptionKeys: readonly [Uint8Array, Uint8Array, Uint8Array];\n readonly secp256r1Pubkey: Uint8Array;\n /**\n * Optional. When provided together with `prfSalt`, the SDK persists a\n * `CredentialRecord` to the configured `DeviceStore` BEFORE calling\n * `POST /wallets`. That way, if the network request fails (timeout, tab\n * close, etc.) the encrypted F1 shard + passkey metadata survive locally\n * and the wallet can be recovered via `wallet.ensureWallet` on the next\n * session (the backend dedupes by Cognito user → returns the same\n * walletAddress).\n *\n * Pass it. Omitting it means an orphaned wallet on POST failure is\n * unrecoverable without a server-side query.\n */\n readonly credentialId?: Uint8Array;\n /** Optional. See `credentialId`. */\n readonly prfSalt?: Uint8Array;\n /**\n * Password de Cognito en plano (`Uint8Array` codificado UTF-8).\n *\n * Recovery v2 (Fase 1, 2026-06-15): si se provee, el SDK deriva\n * `recoveryKey = PBKDF2(password, recoverySalt, 600k)` y la usa para\n * cifrar F3 antes de enviarlo al backend, en vez de usar\n * `encryptionKeys[2]`. El backend almacena F3 cifrado con esa key —\n * SOLO descifrable client-side con el mismo password.\n *\n * Sin esta prop el wallet se crea pero NO podrá recuperarse vía OTP\n * (F3 quedará cifrado con `encryptionKeys[2]`, igual que en 0.x).\n *\n * El caller es responsable de zeroizar este buffer tras `createWallet`\n * (el SDK no lo retiene en memoria).\n */\n readonly cognitoPassword?: Uint8Array;\n /**\n * 32-byte salt para HKDF — si se persiste en el `CredentialRecord`,\n * `wallet.unlockForSigning` lo recupera y re-deriva las mismas keys sin\n * intervención del caller. Si se omite, el SDK genera uno random y lo\n * persiste igualmente. Si la wallet ya existe en el `DeviceStore` con un\n * `encryptionSalt`, este input se ignora a favor del salt persistido (para\n * preservar la decriptabilidad de F1).\n */\n readonly encryptionSalt?: Uint8Array;\n}\n\nexport interface CreatedWalletInfo {\n readonly walletAddress: string;\n readonly publicKey: Uint8Array;\n /**\n * `'on-chain'` if the backend confirmed deploy; `'pending-deploy'` if the\n * backend submitted to Soroban but the contract did not land (typically\n * because the Smart Account constructor exceeds Soroban v26 resource caps\n * — Phase 1 territory). When pending, the `walletAddress` is the\n * client-side-predicted address: same address that will be live once the\n * deploy succeeds (idempotent on the backend).\n */\n readonly status: WalletStatus;\n /** When `status === 'pending-deploy'`, the backend's reason if available. */\n readonly pendingReason?: string;\n}\n\nimport { isSorobanDeployPendingError } from './sorobanDeployStatus.js';\nexport { isSorobanDeployPendingError } from './sorobanDeployStatus.js';\n\nexport type WalletStatus =\n /** Backend confirmed the contract is live on Soroban. Ready to use. */\n | 'on-chain'\n /**\n * Wallet record exists (locally and/or on backend) but the contract has NOT\n * been observed on Soroban yet. Either deploy is still in flight, or\n * landed in a ghost state. Re-run `wallet.ensureWallet` later (or call\n * `wallet.retryDeploy(username)`).\n */\n | 'pending-deploy'\n /**\n * Backend has the record but its Soroban RPC check did not respond — the\n * SDK treats the address as usable but flags the uncertainty.\n */\n | 'unknown';\n\nexport interface EnsureWalletResult {\n readonly walletAddress: string;\n readonly status: WalletStatus;\n /** True if this call generated a new keypair (first-time deploy path). */\n readonly createdNow: boolean;\n /** Present only when `createdNow === true`. */\n readonly publicKey?: Uint8Array;\n}\n\nexport interface RemoteWalletInfo {\n readonly walletAddress: string;\n readonly appId: string;\n readonly createdAt: string;\n readonly onChain: boolean | null;\n}\n\nexport interface RetryDeployResult {\n readonly walletAddress: string;\n readonly status: WalletStatus;\n}\n\n/**\n * Input para `wallet.bootstrap(...)` — el high-level \"todo en uno\" que cualquier\n * integrador típico va a llamar como entry point. Hace **TODO**:\n *\n * 1. `sha256(email)` → userId opaco para el RP.\n * 2. Genera `prfSalt` aleatorio (32 bytes).\n * 3. `registerPasskey(...)` con extensión PRF — pide huella/face/Hello.\n * 4. Genera `encryptionSalt` aleatorio (32 bytes).\n * 5. HKDF(prfOutput, encryptionSalt, \"accesly-{f1,f2,f3}-encryption\") → 3 keys AES.\n * 6. Genera `emailSalt` aleatorio (32 bytes).\n * 7. `wallet.ensureWallet(...)` — el flujo idempotente get-or-create.\n * 8. Persiste `encryptionSalt` en `CredentialRecord` para que `unlockForSigning`\n * pueda re-derivar las mismas keys.\n * 9. Zeroiza `prfOutput`, `f1Key`, `f2Key`, `f3Key`, `cognitoPasswordBytes`.\n *\n * Después de `bootstrap`, llamá `tx.send(...)` directamente con\n * `wallet.unlockForSigning(email)` — no hace falta más wiring.\n */\nexport interface BootstrapWalletInput {\n readonly email: string;\n /**\n * Password de Cognito en plano. Usado para:\n * - Re-cifrar F3 (y F2_recovery) con `recoveryKey = PBKDF2(password,\n * recoverySalt, 600k)` para el flujo de Recovery v2.\n *\n * El SDK lo zeroiza tras el ensureWallet.\n */\n readonly password: string;\n /**\n * Overrides opcionales para el `registerPasskey` interno. Caso típico:\n * cambiar `rpName: 'MiApp'` para que el browser muestre tu marca en el\n * prompt biométrico. `rpId` por default = `window.location.hostname`.\n */\n readonly passkey?: {\n readonly rpId?: string;\n readonly rpName?: string;\n };\n}\n\n/**\n * Material reconstruido por `wallet.unlockForSigning(...)` y listo para pasar\n * a `tx.send(...)`. Las llaves se zeroizan tras la firma; el caller no debería\n * retenerlas más allá del round-trip.\n */\nexport interface UnlockedSigningMaterial {\n /** F1 share desencriptado (Shamir-encoded blob). Lo zero-iza `tx.send`. */\n readonly fragmentF1Plain: Uint8Array;\n /** AES key con la que el SDK desencripta el envelope F2 del backend. */\n readonly fragmentF2Key: Uint8Array;\n /** Pubkey ed25519 del owner del Smart Account (32 bytes). */\n readonly ownerPubkey: Uint8Array;\n /** Address C… del Smart Account (display only). */\n readonly walletAddress: string;\n}\n\nexport interface WalletNamespace {\n /**\n * **Entry-point recomendado.** Registra passkey + deriva keys + crea-o-recupera\n * wallet en una sola llamada. Sustituye al patrón histórico de\n * `ensureWalletWithPasskey` que tenía que copiar-pegar cada integrador.\n *\n * Idempotente: si ya hay wallet en el backend para este Cognito user, devuelve\n * `{createdNow: false}` sin re-registrar passkey. Si no, hace el flow completo.\n */\n bootstrap(input: BootstrapWalletInput): Promise<EnsureWalletResult>;\n /**\n * **Helper para `tx.send`.** Lee la credencial del DeviceStore, abre el\n * passkey via WebAuthn (PIN/biométrico), re-deriva las AES keys con HKDF, y\n * descifra F1 local. Devuelve los 3 materiales que `tx.send` necesita.\n *\n * Lanza con mensaje claro si:\n * - no hay credential local (el user tiene que correr `recovery.finalize`\n * en este device);\n * - el passkey no devolvió PRF (browser sin soporte);\n * - el envelope F1 falla al descifrar (corrupto / passkey distinto).\n */\n unlockForSigning(username: string): Promise<UnlockedSigningMaterial>;\n /**\n * End-to-end wallet creation:\n * 1. Generate keypair + Shamir split + encrypt fragments (client-side).\n * 2. Compute the Smart Account address client-side from the ed25519\n * pubkey + the env-configured deployer (deterministic — matches what\n * the backend will deploy).\n * 3. If `credentialId` + `prfSalt` were provided, persist a full\n * `CredentialRecord` (with all 3 encrypted fragments + computed\n * walletAddress + `onChain: null`) to the `DeviceStore` BEFORE the\n * network call — crash-safety + retry capability in one step.\n * 4. POST /wallets with hex pubkeys + base64 fragments.\n * 5. On success, mark the record `onChain: true` (cleared by the next\n * `ensureWallet` call which queries Soroban via the backend).\n *\n * The caller is responsible for the encryption-key derivation (typically\n * via WebAuthn PRF).\n */\n createWallet(input: CreateWalletInput): Promise<CreatedWalletInfo>;\n /**\n * Idempotent wallet bootstrap. The recommended entry-point at the top of\n * every authenticated session:\n *\n * - `GET /wallets` → if `onChain === true`, returns `{ status: 'on-chain' }`\n * and skips keypair generation entirely.\n * - `GET /wallets` → if `onChain === false`, calls `retryDeploy` to\n * re-submit the existing record (idempotent on the backend) and\n * returns `{ status: 'pending-deploy' }` if the retry didn't surface\n * success yet.\n * - `GET /wallets` → if `onChain === null` (Soroban RPC unreachable),\n * returns `{ status: 'unknown' }` — the address is usable but the\n * SDK couldn't confirm on-chain presence.\n * - `GET /wallets` → 404 → runs the full `createWallet` flow and returns\n * `{ status: 'pending-deploy', createdNow: true }`. Subsequent calls\n * will upgrade to `'on-chain'` once the backend's Soroban check passes.\n */\n ensureWallet(input: CreateWalletInput): Promise<EnsureWalletResult>;\n /**\n * Re-submits `POST /wallets` for an existing local `CredentialRecord`. Used\n * to recover from ghost wallets (record exists but deploy did not land).\n * Requires the record to have been persisted with `fragmentF2Encrypted`,\n * `fragmentF3Encrypted`, `publicKey`, and `emailCommitment` (which\n * `createWallet` does automatically when `credentialId` + `prfSalt` are\n * provided).\n *\n * Backend dedupes by ownerPubkey — the returned address is guaranteed to\n * equal the one originally stored.\n */\n retryDeploy(username: string): Promise<RetryDeployResult>;\n /**\n * Reads the user's wallet metadata from the backend. Returns null if the\n * user has not yet created a wallet.\n */\n fetchRemote(): Promise<RemoteWalletInfo | null>;\n /**\n * Computes the deterministic Smart Account address that the backend will\n * (or did) deploy for the given ed25519 owner pubkey. Same algorithm\n * Stellar Core uses — pure client-side, no network call. Useful to show\n * the address to the user instantly before any POST.\n */\n computeAddress(ownerPubkey: Uint8Array): Promise<string>;\n /** Returns the locally-stored credential record, if any. */\n getStoredCredential(username: string): Promise<CredentialRecord | null>;\n /**\n * Lists `CredentialRecord`s whose `walletAddress` is still `null` OR whose\n * `onChain` flag is `false`. Diagnostic + recovery aid.\n */\n getPendingWallets(): Promise<readonly CredentialRecord[]>;\n /** Removes a stored credential. Useful after a failed pending wallet is reconciled. */\n clearStoredCredential(username: string): Promise<void>;\n /**\n * Testnet only — fondea el Smart Account con XLM via Stellar friendbot.\n *\n * Friendbot acepta directamente direcciones de contrato Soroban (`C…`):\n * internamente arma una tx `invokeContract(XLM_SAC.transfer, ...)` desde\n * la cuenta de la SDF y la submitea. Resultado: ~10,000 XLM testnet al\n * Smart Account, sin necesidad de un G-account intermediario.\n *\n * Idempotente: el primer call exitoso marca `testnetFunded: true` en el\n * `CredentialRecord` local; subsiguientes calls devuelven `alreadyFunded:\n * true` sin hacer otro round-trip a friendbot.\n *\n * En `env: 'mainnet'` la función es un no-op (no existe friendbot en\n * mainnet) y devuelve `{ funded: false, alreadyFunded: false, reason:\n * 'mainnet-not-supported' }`. La UI tiene que mostrar opciones de onramp\n * real (Etherfuse, MoonPay, transferencia externa).\n *\n * `ensureWallet` lo llama automáticamente fire-and-forget cuando el\n * status final es `'on-chain'` — el caller solo necesita llamarlo\n * explícitamente si quiere mostrar feedback en la UI durante el funding.\n */\n fundTestnet(walletAddress: string): Promise<FundTestnetResult>;\n}\n\nexport interface FundTestnetResult {\n /** `true` si esta llamada disparó friendbot y fondeó la wallet ahora. */\n readonly funded: boolean;\n /**\n * `true` si la wallet ya había sido fondeada antes (flag local o response\n * de friendbot indicando que la cuenta ya existe). Igualmente válido —\n * la UI puede mostrar \"ya tienes XLM\" sin pedir acción del user.\n */\n readonly alreadyFunded: boolean;\n /** Texto explicativo para no-op cases (mainnet, missing record, etc.). */\n readonly reason?: 'mainnet-not-supported' | 'friendbot-error' | 'already-funded' | 'funded-now';\n}\n\n/**\n * Input para `tx.send(...)` — manda XLM desde el Smart Account del usuario a\n * cualquier address Stellar (G… clásico o C… contrato).\n *\n * El SDK orquesta todo el flujo: simulate → ECDH F2 → reconstruct seed →\n * sign auth entry → submit. El caller solo entrega los inputs sensibles que\n * vienen de su flow de unlock (WebAuthn PRF + derivación de F2 key).\n */\nexport interface SendXlmInput {\n /** Destinatario. G… (clásico) o C… (contrato). */\n readonly destinationAddress: string;\n /** Monto en STROOPS (1 XLM = 10_000_000 stroops). Base-10 string para evitar precisión. */\n readonly amountStroops: string;\n /**\n * F1 (Shamir share encoded incluyendo el byte de índice) ya en plano —\n * típicamente desencriptado client-side via WebAuthn PRF antes de llamar.\n * El SDK lo zero-iza tras combinar con F2.\n */\n readonly fragmentF1Plain: Uint8Array;\n /**\n * Llave AES-256 con la que el SDK desencripta el F2 envelope que vino\n * del backend. La derivación de esta llave es responsabilidad del caller\n * (usualmente PBKDF2 sobre material derivado de credenciales del user).\n * Se zero-iza al terminar.\n */\n readonly fragmentF2Key: Uint8Array;\n /**\n * Pubkey ed25519 (32 bytes) del owner del Smart Account. Se usa para:\n * 1) Sanity-check de que la seed reconstruida deriva esta pubkey.\n * 2) Empaquetarla dentro del `Signer::External(verifier, pubkey)` del\n * AuthPayload.\n */\n readonly ownerPubkey: Uint8Array;\n}\n\nexport interface SendXlmResult {\n readonly txHash: string;\n readonly status: string;\n readonly explorerUrl: string;\n}\n\nexport interface TxNamespace {\n /**\n * End-to-end XLM transfer desde el Smart Account del user.\n *\n * Flujo interno (no-custodial):\n * 1) `POST /tx/simulate` con `{ amountStroops, destinationAddress }`.\n * 2) Genera X25519 keypair efímero + `POST /fragments/2` con la pubkey.\n * Backend devuelve F2 wrapped en una capa session-key. El SDK la\n * descifra con ECDH + HKDF — la session key NO persiste en disco.\n * 3) Desencripta el F2 envelope interno con `fragmentF2Key` → F2 plain.\n * 4) Combina F1 + F2 vía Shamir → ed25519 seed (32 bytes).\n * 5) Computa `auth_digest = sha256(signature_payload || rule_ids_xdr)`\n * y lo firma con la seed → 64-byte ed25519 sig.\n * 6) Empaqueta el `AuthPayload {signers, context_rule_ids}` ScVal,\n * reemplaza `credentials.address.signature` en la placeholder entry.\n * 7) `POST /tx/submit` con `{ unsignedXdr, signedAuthEntryXdr }`.\n * 8) Devuelve `{ txHash, status, explorerUrl }`.\n *\n * Toda llave plana sale de scope tras la firma. Lanza si:\n * - El backend rechaza simulate/submit.\n * - La reconstrucción Shamir falla (fragmentos no compatibles).\n * - La pubkey derivada de la seed no matchea `ownerPubkey`.\n */\n send(input: SendXlmInput): Promise<SendXlmResult>;\n\n /**\n * Bajo nivel: firma un envelope Stellar ya construido con una seed ed25519\n * dada. Útil para flows custom que arman la tx fuera del SDK.\n */\n signRawXdr(input: {\n transactionXdr: string;\n ed25519Seed: Uint8Array;\n expectedPublicKey?: Uint8Array;\n }): Promise<{ signedXdr: string; publicKey: Uint8Array }>;\n}\n\nexport interface KycNamespace {\n start(): Promise<{ customerId: string; status: string; hostedUrl: string | null }>;\n status(): Promise<{ customerId: string; status: string; hostedUrl: string | null }>;\n}\n\nexport interface SessionNamespace {\n /** Create a temporary session key for unattended low-value tx (Soroban policy). */\n create(_opts: { readonly ttlSeconds: number; readonly maxAmountStroops: string }): Promise<never>;\n /** Revoke a previously-created session key. */\n revoke(_sessionKeyId: string): Promise<never>;\n}\n\nexport interface SettingsNamespace {\n /** Add a new device's passkey to an existing wallet (multi-device). */\n addDevice(_secp256r1Pubkey: Uint8Array): Promise<never>;\n /** Remove a device's passkey from the wallet. */\n removeDevice(_secp256r1Pubkey: Uint8Array): Promise<never>;\n /** List all device passkeys registered for the wallet. */\n listDevices(): Promise<never>;\n /** Change the spending limit policy. */\n updateSpendingLimit(_opts: {\n readonly limitStroops: string;\n readonly perDayStroops?: string;\n }): Promise<never>;\n}\n\nexport interface YieldNamespace {\n /** Invest USDC into CETES via Etherfuse (50/50 yield share with Accesly). */\n invest(_amountUsdc: string): Promise<never>;\n /** Redeem CETES tokens back into USDC. */\n redeem(_amountTokens: string): Promise<never>;\n /** Read the user's current yield position. */\n position(): Promise<never>;\n}\n\n/**\n * Stub thrown by every method in the `session`, `settings`, `yield`\n * namespaces. These features are designed but not implemented in v0.1.0 —\n * they unblock with the dashboard work in Fase 7 (`session`/`settings`) and\n * with Etherfuse activation (`yield`).\n */\nexport class NotImplementedYetError extends Error {\n constructor(namespace: string, method: string) {\n super(\n `${namespace}.${method}() is not implemented yet. This namespace ships in a later release; ` +\n 'see docs/Handoff_Fase7.md for the roadmap.',\n );\n this.name = 'NotImplementedYetError';\n }\n}\n\n/**\n * Recovery v2 — OTP por email + password de Cognito (Fase 1, 2026-06-15).\n *\n * Flujo desde la UI:\n * 1. `recovery.requestOtp({ email })` → manda el OTP por SES.\n * 2. `recovery.verifyOtp({ email, code })` → devuelve `recoveryJwt`.\n * 3. `recovery.finalize({ email, password, recoveryJwt })` orquesta todo:\n * - GET /fragments/3 con el JWT\n * - Deriva recoveryKey con el password + recoverySalt del backend\n * - Decifra F3\n * - Decifra F2 (vía session key ECDH)\n * - Combina F2+F3 → seed ed25519 reconstruida\n * - Genera new passkey + new Shamir split (F1', F2', F3')\n * - Re-cifra F3' con la misma recoveryKey + nuevo salt\n * - Firma la tx `rotate_signer` localmente\n * - POST /recovery/finalize con todo\n * - Persiste new CredentialRecord local\n * - Zero-iza la seed\n */\nexport interface ReconstructedSeed {\n /** 32-byte ed25519 seed reconstruida vía Shamir(F2_recovery + F3). CALLER ZEROIZE. */\n readonly privateSeed: Uint8Array;\n /** 32-byte ed25519 public key derivada. */\n readonly publicKey: Uint8Array;\n /** 32-byte recoveryKey derivada del password — útil para re-cifrar F2'/F3' nuevos. */\n readonly recoveryKey: Uint8Array;\n /** Base64 32-byte salt que vino del backend. */\n readonly recoverySalt: string;\n}\n\n/**\n * Input para `recovery.finalize(...)` — **orquestador end-to-end**. El integrador\n * solo provee email + password + recoveryJwt; el SDK hace TODO el resto:\n *\n * 1. `reconstructSeed(...)` con el password → seed VIEJA + recoveryKey.\n * 2. `registerPasskey(...)` con PRF → nuevo credentialId + secp256r1Pubkey + prfOutput.\n * 3. HKDF(prfOutput, encryptionSalt, \"accesly-{f1,f2}-encryption\") → newF1Key + newF2Key.\n * 4. Genera new ed25519 seed + Shamir 2-of-3 + cifra F1'/F2' con PRF keys, F3' con recoveryKey.\n * 5. `POST /recovery/simulate-rotate-signer` → backend arma + simula.\n * 6. Firma `SorobanAuthorizationEntry` con la SEED VIEJA contra `admin-cfg`.\n * 7. `POST /recovery/finalize` con auth entry firmada + new fragments.\n * 8. Persiste new `CredentialRecord` (con `encryptionSalt`) en `DeviceStore`.\n * 9. Zeroiza TODAS las llaves intermedias (privateSeed vieja, recoveryKey, PRF output, password).\n */\nexport interface FinalizeRecoveryInput {\n /** Email del usuario (case-insensitive, se normaliza). */\n readonly email: string;\n /**\n * Password de Cognito (string). El SDK lo encoda a UTF-8 internamente y lo\n * zeroiza tras la operación. No retengas referencias.\n */\n readonly password: string;\n /** Token KMS-HMAC que devolvió `verifyOtp()` — TTL 5min. */\n readonly recoveryJwt: string;\n /**\n * Overrides opcionales para el `registerPasskey` interno (mismo shape que\n * `wallet.bootstrap`). Caso típico: `rpName: 'MiApp'`.\n */\n readonly passkey?: {\n readonly rpId?: string;\n readonly rpName?: string;\n };\n}\n\nexport interface FinalizeRecoveryResult {\n readonly walletAddress: string;\n readonly txHash: string;\n readonly status: string;\n /** Pubkey ed25519 NUEVA (32 bytes). Útil para UI confirmación. */\n readonly newPublicKey: Uint8Array;\n /** Link al explorer. */\n readonly explorerUrl: string;\n}\n\nexport interface RecoveryNamespace {\n /** Pide OTP. Backend rate-limita; el caller debe respetar `cooldownSeconds`. */\n requestOtp(input: { email: string }): Promise<{\n cooldownSeconds: number;\n expiresInSeconds: number;\n }>;\n /** Verifica OTP. Devuelve `recoveryJwt` con TTL 5min. */\n verifyOtp(input: { email: string; code: string }): Promise<{\n recoveryJwt: string;\n expiresAt: number;\n }>;\n /**\n * Descarga `/fragments/3`, descifra F2_recovery + F3 con la `recoveryKey`\n * derivada del password y reconstruye la seed via Shamir.\n *\n * El caller DEBE zero-izar `result.privateSeed` y `result.recoveryKey`\n * tras firmar la rotación + cifrar las nuevas F1'/F2'/F3'.\n *\n * El caller también es responsable de zeroizar `cognitoPassword` después.\n */\n reconstructSeed(input: {\n cognitoPassword: Uint8Array;\n recoveryJwt: string;\n }): Promise<ReconstructedSeed>;\n /**\n * Orquestador completo de la rotación de signers para Recovery v2.\n * Ver `FinalizeRecoveryInput` para los pre-requisitos.\n */\n finalize(input: FinalizeRecoveryInput): Promise<FinalizeRecoveryResult>;\n /**\n * Bajo nivel: submitea la rotación al backend tras que el caller haya\n * armado el body manualmente. `finalize(...)` es el wrapper recomendado.\n */\n submitFinalize(input: {\n recoveryJwt: string;\n unsignedXdr: string;\n signedAuthEntryXdr: string;\n newOwnerEd25519Pubkey: string;\n newSecp256r1Pubkey: string;\n newFragmentF1Encrypted: EncryptedEnvelope;\n newFragmentF2Encrypted: EncryptedEnvelope;\n newFragmentF2Recovery: EncryptedEnvelope;\n newFragmentF3Encrypted: EncryptedEnvelope;\n newRecoverySalt: string;\n newEmailCommitment: string;\n }): Promise<{ walletAddress: string; txHash: string; status: string }>;\n}\n\nexport interface AcceslyHook {\n readonly auth: AuthNamespace;\n readonly wallet: WalletNamespace;\n readonly tx: TxNamespace;\n readonly kyc: KycNamespace;\n readonly recovery: RecoveryNamespace;\n readonly session: SessionNamespace;\n readonly settings: SettingsNamespace;\n readonly yieldOps: YieldNamespace;\n /** Raw context, for advanced use cases (custom telemetry, manual refresh). */\n readonly _internal: AcceslyContextValue;\n}\n\nexport function useAccesly(): AcceslyHook {\n const ctx = useContext(AcceslyContext);\n if (!ctx) {\n throw new Error(\n 'useAccesly: missing <AcceslyProvider>. Wrap your app with <AcceslyProvider appId env>.',\n );\n }\n\n const auth = useMemo<AuthNamespace>(\n () => ({\n status: ctx.status,\n username: ctx.username,\n async signUp(email, password) {\n return ctx.authClient.signUp(email, password);\n },\n confirmSignUp(email, code) {\n return ctx.authClient.confirmSignUp(email, code);\n },\n resendConfirmation(email) {\n return ctx.authClient.resendConfirmationCode(email);\n },\n async signIn(email, password) {\n const tokens = await ctx.authClient.signIn(email, password);\n await ctx.tokenManager.setTokens(tokens);\n await ctx.refreshStatus();\n },\n async signOut() {\n await ctx.tokenManager.signOut();\n await ctx.refreshStatus();\n },\n }),\n [ctx],\n );\n\n const { hexToBytes, hexFromBytes } = useMemo(() => coderHelpers(), []);\n\n const stellarConfig = ENVIRONMENT_DEFAULTS[ctx.env].stellar;\n\n const wallet = useMemo<WalletNamespace>(() => {\n // Capture the narrowed non-null context once, so the inner closures\n // don't trip TS's narrowing-through-function-declaration limitation.\n const c = ctx;\n\n /**\n * Sends the POST /wallets request given a fully-assembled record. Used\n * by both the first-time create flow and `retryDeploy`. Returns the\n * backend-confirmed walletAddress.\n */\n const postWallet = async (params: {\n pubkeyEd25519: Uint8Array;\n emailCommitment: Uint8Array;\n secp256r1Pubkey: Uint8Array;\n fragmentF2: EncryptedEnvelope;\n fragmentF3: EncryptedEnvelope;\n /** Recovery v2 — F2 cipher-bound a recoveryKey. */\n fragmentF2Recovery?: EncryptedEnvelope;\n /** Recovery v2 — `sha256(email)` en hex. Optional para compat. */\n emailHash?: string;\n /** Recovery v2 — base64 salt. Optional para compat. */\n recoverySalt?: string;\n }): Promise<string> => {\n const res = await c.endpoints.createWallet({\n appId: c.appId,\n pubkeyEd25519: hexFromBytes(params.pubkeyEd25519),\n emailCommitment: hexFromBytes(params.emailCommitment),\n secp256r1Pubkey: hexFromBytes(params.secp256r1Pubkey),\n fragmentF2: encodeFragmentToWire(params.fragmentF2),\n fragmentF3: encodeFragmentToWire(params.fragmentF3),\n ...(params.fragmentF2Recovery\n ? { fragmentF2Recovery: encodeFragmentToWire(params.fragmentF2Recovery) }\n : {}),\n ...(params.emailHash ? { emailHash: params.emailHash } : {}),\n ...(params.recoverySalt ? { recoverySalt: params.recoverySalt } : {}),\n });\n return res.walletAddress;\n };\n\n const statusFromOnChain = (onChain: boolean | null): WalletStatus => {\n if (onChain === true) return 'on-chain';\n if (onChain === false) return 'pending-deploy';\n return 'unknown';\n };\n\n /**\n * Testnet auto-funding implementation. Hits Stellar friendbot with the\n * Smart Account contract address — la SDF lo soporta directamente post\n * Soroban (internamente arma una invokeContract XLM_SAC.transfer desde\n * la cuenta de friendbot al contrato). Resultado: ~10,000 XLM testnet\n * acreditados al Smart Account.\n *\n * No-op si `env !== 'testnet'`. Idempotente via flag local — solo hace\n * el round-trip a friendbot la primera vez.\n */\n // Detect testnet via the network passphrase rather than `env` — `env` is\n // a deploy stage (`dev` | `staging` | `prod`), not a chain selector.\n // Pre-mainnet, both `dev` and `staging` point to Stellar testnet; only\n // `prod` flips to the public mainnet passphrase.\n const TESTNET_PASSPHRASE = 'Test SDF Network ; September 2015';\n const isTestnet = stellarConfig.networkPassphrase === TESTNET_PASSPHRASE;\n\n const fundTestnetIfNeeded = async (\n walletAddress: string,\n username: string | null,\n opts?: { readonly retries?: number; readonly retryDelayMs?: number },\n ): Promise<FundTestnetResult> => {\n if (!isTestnet) {\n return { funded: false, alreadyFunded: false, reason: 'mainnet-not-supported' };\n }\n\n // Check local idempotency flag\n const existing = username ? await c.deviceStore.loadCredential(username) : null;\n if (existing?.testnetFunded) {\n return { funded: false, alreadyFunded: true, reason: 'already-funded' };\n }\n\n // Retries: caller path (auto-fund post-create) pasa varios porque hay\n // una race entre POST /wallets OK y el contrato apareciendo on-chain\n // — friendbot necesita el C-address vivo para invocar XLM_SAC.transfer.\n // Manual button: 0 retries (mismo comportamiento de antes).\n const retries = opts?.retries ?? 0;\n const retryDelayMs = opts?.retryDelayMs ?? 5000;\n\n const url = `https://friendbot.stellar.org?addr=${encodeURIComponent(walletAddress)}`;\n let funded = false;\n let alreadyFunded = false;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url);\n if (res.ok) {\n funded = true;\n break;\n }\n if (res.status === 400) {\n // Friendbot 400 puede ser \"ya fondeada\" (éxito idempotente) o\n // \"contrato no existe aún\" (retry). El body trae el detalle.\n const body = await res.text().catch(() => '');\n const alreadyExists =\n /already|exist|funded/i.test(body) && !/destination|account.*not/i.test(body);\n if (alreadyExists) {\n alreadyFunded = true;\n break;\n }\n // Contract probably not yet on-chain — retry if possible.\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, retryDelayMs));\n continue;\n }\n return { funded: false, alreadyFunded: false, reason: 'friendbot-error' };\n }\n // Other status — retry if possible.\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, retryDelayMs));\n continue;\n }\n return { funded: false, alreadyFunded: false, reason: 'friendbot-error' };\n } catch {\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, retryDelayMs));\n continue;\n }\n return { funded: false, alreadyFunded: false, reason: 'friendbot-error' };\n }\n }\n\n // Persist the flag so we don't hit friendbot again on subsequent\n // ensureWallet calls. If there's no existing credential record\n // (different device, fresh browser), nothing to update — the next\n // session might try again, which is OK (friendbot will 400 with\n // \"already funded\" and we treat that as success).\n if (existing) {\n await c.deviceStore.saveCredential({ ...existing, testnetFunded: true });\n }\n\n return {\n funded,\n alreadyFunded,\n reason: funded ? 'funded-now' : 'already-funded',\n };\n };\n\n return {\n async computeAddress(ownerPubkey) {\n return computeSmartAccountAddress({\n ownerPubkey,\n deployerAddress: stellarConfig.deployerAddress,\n networkPassphrase: stellarConfig.networkPassphrase,\n });\n },\n\n async createWallet(input) {\n // Defense in depth: coerce the passkey pubkey to the canonical\n // 65-byte 0x04-prefixed form. The backend validator rejects anything\n // else with \"secp256r1Pubkey must be hex 65 bytes (uncompressed)\".\n const secp256r1Canonical = normalizeSecp256r1Pubkey(input.secp256r1Pubkey);\n const created = coreCreateWallet({\n emailBytes: new TextEncoder().encode(input.email),\n emailSalt: input.emailSalt,\n encryptionKeys: input.encryptionKeys,\n });\n\n // Recovery v2: si el caller pasó `cognitoPassword`, generamos un\n // recoverySalt y re-ciframos F2 + F3 con `recoveryKey =\n // PBKDF2(password, recoverySalt, 600k)`. Necesitamos AMBOS porque\n // Shamir 2-de-3 exige DOS shares para reconstruir el seed durante\n // recovery (F1 está perdido cuando el device se pierde).\n //\n // Esa key vive SOLO en cliente — el backend recibe `{F2_recovery,\n // F3, recoverySalt}` y nunca puede descifrar sin el password.\n let fragmentF3ToSend = created.encryptedFragments[2];\n let fragmentF2Recovery: EncryptedEnvelope | undefined;\n let recoverySaltBase64: string | undefined;\n if (input.cognitoPassword) {\n const recoverySalt = generateRecoverySalt();\n const f2Plain = decryptAesGcm(created.encryptedFragments[1], input.encryptionKeys[1]);\n const f3Plain = decryptAesGcm(created.encryptedFragments[2], input.encryptionKeys[2]);\n const recoveryKey = deriveRecoveryKey({\n password: input.cognitoPassword,\n salt: recoverySalt,\n });\n try {\n fragmentF2Recovery = encryptAesGcm(f2Plain, recoveryKey);\n fragmentF3ToSend = encryptAesGcm(f3Plain, recoveryKey);\n } finally {\n // No leak: zeroize la key + plaintexts.\n for (let i = 0; i < recoveryKey.length; i += 1) recoveryKey[i] = 0;\n for (let i = 0; i < f2Plain.length; i += 1) f2Plain[i] = 0;\n for (let i = 0; i < f3Plain.length; i += 1) f3Plain[i] = 0;\n }\n recoverySaltBase64 = base64FromBytes(recoverySalt);\n }\n\n // emailHash = sha256(email.toLowerCase().trim()) en hex. El backend\n // lo indexa en el GSI by-email-hash para resolver Recovery v2.\n const emailHashHex = hexFromBytes(emailHashBytes(input.email));\n\n // Pre-compute the deterministic walletAddress.\n const predictedAddress = await computeSmartAccountAddress({\n ownerPubkey: created.publicKey,\n deployerAddress: stellarConfig.deployerAddress,\n networkPassphrase: stellarConfig.networkPassphrase,\n });\n\n // Crash-safety: persist el record con F3 cifrado en su forma\n // recoverable (la que se envía al backend). Si el caller no provee\n // password, mantenemos el F3 viejo (compat).\n const canPersist = Boolean(input.credentialId && input.prfSalt);\n if (canPersist) {\n await ctx.deviceStore.saveCredential({\n username: input.email,\n credentialId: input.credentialId!,\n secp256r1Pubkey: secp256r1Canonical,\n fragmentF1Encrypted: created.encryptedFragments[0],\n fragmentF2Encrypted: created.encryptedFragments[1],\n fragmentF3Encrypted: fragmentF3ToSend,\n publicKey: created.publicKey,\n emailCommitment: created.emailCommitment,\n prfSalt: input.prfSalt!,\n fallbackKeyMaterial: new Uint8Array(0),\n walletAddress: predictedAddress,\n onChain: null,\n createdAt: Date.now(),\n ...(input.encryptionSalt ? { encryptionSalt: input.encryptionSalt } : {}),\n });\n }\n\n let confirmedAddress: string;\n let deployStatus: WalletStatus = 'unknown';\n let pendingReason: string | undefined;\n\n try {\n confirmedAddress = await postWallet({\n pubkeyEd25519: created.publicKey,\n emailCommitment: created.emailCommitment,\n secp256r1Pubkey: secp256r1Canonical,\n fragmentF2: created.encryptedFragments[1],\n fragmentF3: fragmentF3ToSend,\n emailHash: emailHashHex,\n ...(fragmentF2Recovery ? { fragmentF2Recovery } : {}),\n ...(recoverySaltBase64 ? { recoverySalt: recoverySaltBase64 } : {}),\n });\n // POST succeeded — leave status as 'unknown'; the next\n // ensureWallet GET will upgrade it to 'on-chain' once Soroban\n // confirms the deploy.\n } catch (err) {\n if (!isSorobanDeployPendingError(err)) throw err;\n // Soroban rejected the deploy (constructor too big, footprint\n // exceeded, etc). Treat as deferrable — the local record is\n // already persisted with the predicted address; the backend also\n // has the record by design. `wallet.retryDeploy` will land it\n // later once the contracts team slims the constructor.\n confirmedAddress = predictedAddress;\n deployStatus = 'pending-deploy';\n pendingReason = err instanceof Error ? err.message : String(err);\n console.warn(\n '[accesly] wallet deploy is pending — predicted address persisted, retry once Phase 1 destrabes the constructor',\n pendingReason,\n );\n }\n\n // Sanity check — predicted vs confirmed should always match. If not,\n // either the deployer address in env is wrong or the algorithm\n // drifted; either way the app should know about it.\n if (confirmedAddress !== predictedAddress) {\n console.warn('[accesly] computed walletAddress does not match backend response', {\n predicted: predictedAddress,\n confirmed: confirmedAddress,\n });\n }\n\n if (canPersist) {\n const existing = await ctx.deviceStore.loadCredential(input.email);\n if (existing) {\n await ctx.deviceStore.saveCredential({\n ...existing,\n walletAddress: confirmedAddress,\n onChain: deployStatus === 'pending-deploy' ? false : (existing.onChain ?? null),\n });\n }\n }\n\n return {\n walletAddress: confirmedAddress,\n publicKey: created.publicKey,\n status: deployStatus,\n ...(pendingReason !== undefined ? { pendingReason } : {}),\n };\n },\n\n async ensureWallet(input) {\n // Fire-and-forget auto-fund. Disparamos también con status='unknown'\n // (que es lo que regresa createWallet tras un POST exitoso, antes de\n // que el GET de confirmación marque on-chain). Friendbot necesita el\n // contrato vivo en Soroban para invocar XLM_SAC.transfer, así que\n // pasamos `retries` para esperar la race POST→on-chain (~5–10s).\n const maybeAutoFund = (result: EnsureWalletResult): EnsureWalletResult => {\n if (isTestnet && (result.status === 'on-chain' || result.status === 'unknown')) {\n fundTestnetIfNeeded(result.walletAddress, input.email, {\n retries: 6,\n retryDelayMs: 5000,\n }).catch(() => {\n /* friendbot a veces falla, no es crítico para el flow */\n });\n }\n return result;\n };\n\n // 1. Cheap idempotent metadata read.\n const remote = await ctx.endpoints.getWallet();\n\n if (remote) {\n // Update the local record's onChain mirror if we have one.\n const local = await ctx.deviceStore.loadCredential(input.email);\n if (local) {\n await ctx.deviceStore.saveCredential({\n ...local,\n walletAddress: remote.walletAddress,\n onChain: remote.onChain,\n });\n }\n\n if (\n remote.onChain === false &&\n local &&\n local.fragmentF2Encrypted &&\n local.fragmentF3Encrypted\n ) {\n // Ghost wallet — backend has the record but Soroban shows no\n // contract. Try a retry; if it still doesn't surface as on-chain\n // (constructor too big, RPC slow), surface pending-deploy.\n try {\n const retried = await this.retryDeploy(input.email);\n return maybeAutoFund({\n walletAddress: retried.walletAddress,\n status: retried.status,\n createdNow: false,\n });\n } catch {\n return maybeAutoFund({\n walletAddress: remote.walletAddress,\n status: 'pending-deploy',\n createdNow: false,\n });\n }\n }\n\n return maybeAutoFund({\n walletAddress: remote.walletAddress,\n status: statusFromOnChain(remote.onChain),\n createdNow: false,\n });\n }\n\n // 2. No wallet at the backend — first-time flow.\n const created = await this.createWallet(input);\n return maybeAutoFund({\n walletAddress: created.walletAddress,\n publicKey: created.publicKey,\n // Use whatever status createWallet inferred. POST OK ⇒ 'unknown'\n // (the next GET will upgrade to 'on-chain'); Soroban rejected the\n // deploy ⇒ 'pending-deploy' with the predicted address.\n status: created.status,\n createdNow: true,\n });\n },\n\n async retryDeploy(username) {\n const record = await ctx.deviceStore.loadCredential(username);\n if (!record) {\n throw new Error(\n `wallet.retryDeploy: no local CredentialRecord for \"${username}\". ` +\n 'Call wallet.createWallet first (with credentialId + prfSalt).',\n );\n }\n if (\n !record.publicKey ||\n !record.emailCommitment ||\n !record.fragmentF2Encrypted ||\n !record.fragmentF3Encrypted\n ) {\n throw new Error(\n `wallet.retryDeploy: stored CredentialRecord for \"${username}\" is missing ` +\n 'publicKey / emailCommitment / encrypted F2 / F3. ' +\n 'Re-create the wallet from scratch.',\n );\n }\n const confirmed = await postWallet({\n pubkeyEd25519: record.publicKey,\n emailCommitment: record.emailCommitment,\n secp256r1Pubkey: record.secp256r1Pubkey,\n fragmentF2: record.fragmentF2Encrypted,\n fragmentF3: record.fragmentF3Encrypted,\n });\n // Re-query the backend to learn the up-to-date onChain status.\n const remote = await ctx.endpoints.getWallet();\n const onChain = remote?.onChain ?? null;\n await ctx.deviceStore.saveCredential({\n ...record,\n walletAddress: confirmed,\n onChain,\n });\n return { walletAddress: confirmed, status: statusFromOnChain(onChain) };\n },\n\n async fetchRemote() {\n const remote = await ctx.endpoints.getWallet();\n return remote;\n },\n getStoredCredential(username) {\n return ctx.deviceStore.loadCredential(username);\n },\n async getPendingWallets() {\n const all = await ctx.deviceStore.listCredentials();\n return all.filter((c) => c.walletAddress === null || c.onChain === false);\n },\n clearStoredCredential(username) {\n return ctx.deviceStore.deleteCredential(username);\n },\n fundTestnet(walletAddress) {\n // Username viene del context — coincide con el primary key del DeviceStore.\n return fundTestnetIfNeeded(walletAddress, c.username);\n },\n\n /**\n * Implementación del high-level entry point. Combina registración de\n * passkey + derivación HKDF + ensureWallet en una sola llamada.\n */\n async bootstrap(input) {\n const enc = new TextEncoder();\n const userIdHash = sha256(enc.encode(input.email));\n const prfSalt = getRandomBytes(32);\n\n const rpId =\n input.passkey?.rpId ??\n (typeof window !== 'undefined' ? window.location.hostname : 'localhost');\n const rpName = input.passkey?.rpName ?? 'Accesly';\n\n const passkey = await registerPasskey({\n rpId,\n rpName,\n userId: userIdHash,\n userName: input.email,\n prfSalt,\n });\n\n if (!passkey.prfSupported || !passkey.prfOutput) {\n throw new Error(\n 'wallet.bootstrap: this authenticator does not support the WebAuthn PRF ' +\n 'extension. Use Chrome 116+, Edge 116+, or Safari 18+ with a native ' +\n 'OS passkey (Touch ID, Face ID, Windows Hello).',\n );\n }\n\n const encryptionSalt = getRandomBytes(32);\n const f1Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f1-encryption'),\n 32,\n );\n const f2Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f2-encryption'),\n 32,\n );\n const f3Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f3-encryption'),\n 32,\n );\n\n // prfOutput drained — zeroize lo antes posible.\n zeroize(passkey.prfOutput);\n\n const emailSalt = getRandomBytes(32);\n const cognitoPasswordBytes = enc.encode(input.password);\n\n try {\n const result = await this.ensureWallet({\n email: input.email,\n emailSalt,\n encryptionKeys: [f1Key, f2Key, f3Key] as const,\n secp256r1Pubkey: passkey.secp256r1Pubkey,\n credentialId: passkey.credentialId,\n prfSalt,\n cognitoPassword: cognitoPasswordBytes,\n encryptionSalt,\n });\n return result;\n } finally {\n zeroize(f1Key);\n zeroize(f2Key);\n zeroize(f3Key);\n zeroize(cognitoPasswordBytes);\n }\n },\n\n /**\n * Implementación del helper de unlock. Reemplaza al\n * `lib/unlockForSigning.ts` que cada integrador tenía que copiar.\n */\n async unlockForSigning(username) {\n const record = await ctx.deviceStore.loadCredential(username);\n if (!record) {\n throw new Error(\n `wallet.unlockForSigning: no local CredentialRecord for \"${username}\". ` +\n 'Run recovery.finalize on this device or create a new wallet.',\n );\n }\n if (!record.publicKey) {\n throw new Error(\n 'wallet.unlockForSigning: stored CredentialRecord has no publicKey. ' +\n 'Legacy wallet — recreate it with wallet.bootstrap.',\n );\n }\n if (!record.fragmentF1Encrypted) {\n throw new Error(\n 'wallet.unlockForSigning: stored CredentialRecord has no fragmentF1Encrypted.',\n );\n }\n\n const challenge = getRandomBytes(32);\n const rpId =\n typeof window !== 'undefined' ? window.location.hostname : 'localhost';\n const unlock = await unlockPasskey({\n rpId,\n credentialId: record.credentialId,\n challenge,\n prfSalt: record.prfSalt,\n });\n if (!unlock.prfOutput) {\n throw new Error(\n 'wallet.unlockForSigning: authenticator did not return PRF output. ' +\n 'Did you use the same browser/device where the wallet was created?',\n );\n }\n\n // Backwards compat: legacy CredentialRecords (pre-1.1.0) no tienen\n // `encryptionSalt`. Fallback al `prfSalt` — el flujo legacy del example\n // usaba un encryptionSalt separado pero que vive en otro store fuera\n // del SDK. Para nuevas wallets `wallet.bootstrap` siempre persiste el\n // encryptionSalt, así que este path solo aplica a wallets viejas.\n const salt = record.encryptionSalt ?? record.prfSalt;\n const enc = new TextEncoder();\n const f1Key = hkdfSha256(\n unlock.prfOutput,\n salt,\n enc.encode('accesly-f1-encryption'),\n 32,\n );\n const fragmentF2Key = hkdfSha256(\n unlock.prfOutput,\n salt,\n enc.encode('accesly-f2-encryption'),\n 32,\n );\n\n zeroize(unlock.prfOutput);\n\n let fragmentF1Plain: Uint8Array;\n try {\n fragmentF1Plain = decryptAesGcm(record.fragmentF1Encrypted, f1Key);\n } finally {\n zeroize(f1Key);\n }\n\n return {\n fragmentF1Plain,\n fragmentF2Key,\n ownerPubkey: record.publicKey,\n walletAddress: record.walletAddress ?? '',\n };\n },\n };\n }, [ctx, hexFromBytes, stellarConfig]);\n\n const tx = useMemo<TxNamespace>(\n () => ({\n async send(input) {\n const networkPassphrase = stellarConfig.networkPassphrase;\n const verifierAddress = stellarConfig.ed25519VerifierAddress;\n const explorerBase =\n networkPassphrase === 'Public Global Stellar Network ; September 2015'\n ? 'https://stellar.expert/explorer/public/tx/'\n : 'https://stellar.expert/explorer/testnet/tx/';\n\n // 1. Backend simulate → returns the placeholder envelope + payload to sign.\n const sim = await ctx.endpoints.simulateTx({\n amountStroops: input.amountStroops,\n destinationAddress: input.destinationAddress,\n });\n\n // 2. ECDH key exchange → backend re-wraps F2 with a per-request key.\n const ephemeral = generateX25519Keypair();\n const ephemeralPubBase64 = base64FromBytes(ephemeral.publicKey);\n\n const wrappedF2 = await ctx.endpoints.getFragment2({\n clientEphemeralPubkey: ephemeralPubBase64,\n });\n\n // 3. Undo the session layer → recovers the original EncryptedFragment JSON.\n const sessionPlaintext = unwrapSessionFragment2(wrappedF2, ephemeral.privateKey).plaintext;\n const fragmentF2Wire = JSON.parse(new TextDecoder().decode(sessionPlaintext)) as {\n ciphertext: string;\n nonce: string;\n algo: string;\n };\n\n const fragmentF2Envelope: EncryptedEnvelope = {\n nonce: base64ToBytes(fragmentF2Wire.nonce),\n ciphertext: base64ToBytes(fragmentF2Wire.ciphertext),\n };\n\n // 4. Reconstruct ed25519 seed by combining F1 (plain) + F2 (decrypted with F2 key).\n const reconstructed = reconstructFromPlainAndEncrypted({\n fragmentF1Plain: input.fragmentF1Plain,\n fragmentF2: { envelope: fragmentF2Envelope, key: input.fragmentF2Key },\n });\n\n // 5. Sign the Soroban auth entry with the reconstructed seed. The helper\n // zero-izes the seed even on throw.\n const { signedAuthEntryXdr } = await signSorobanAuthEntry({\n signaturePayloadHashBase64: sim.signaturePayloadHashBase64,\n contextRuleIds: [...sim.contextRuleIds],\n placeholderAuthEntryXdr: sim.placeholderAuthEntryXdr,\n ed25519Seed: reconstructed.privateSeed,\n ed25519VerifierAddress: verifierAddress,\n ownerPubkey: input.ownerPubkey,\n });\n\n // 6. Backend submit → wraps in fee-bump with channels-fund and submits.\n const submit = await ctx.endpoints.submitTx({\n unsignedXdr: sim.unsignedXdr,\n signedAuthEntryXdr,\n });\n\n // 7. Optimistic update — push el item al `useWalletHistory` cache para\n // que aparezca al instante sin esperar el indexing de Stellar\n // Expert (~30-60s típico). El próximo poll del hook lo va a\n // descartar cuando confirme que ya está en el feed real.\n try {\n // walletAddress = computeSmartAccountAddress requeriría el deployer.\n // En vez de re-computar, los hooks que consumen optimistic resuelven\n // el wallet via DeviceStore; acá insertamos por ownerPubkey hex.\n const username = ctx.username;\n if (username) {\n const stored = await ctx.deviceStore.loadCredential(username);\n if (stored?.walletAddress) {\n const { historyOptimisticPush } = await import('./useWalletHistory.js');\n historyOptimisticPush(stored.walletAddress, {\n type: 'transfer-out',\n txHash: submit.txHash,\n ledger: Math.floor(Date.now() / 1000),\n timestamp: new Date().toISOString(),\n to: input.destinationAddress,\n amountStroops: input.amountStroops,\n });\n }\n }\n } catch {\n // Fire-and-forget — no rompemos el send si falla el optimistic push.\n }\n\n return {\n txHash: submit.txHash,\n status: submit.status,\n explorerUrl: `${explorerBase}${submit.txHash}`,\n };\n },\n async signRawXdr(input) {\n return coreSignTransaction({\n transactionXdr: input.transactionXdr,\n ed25519Seed: input.ed25519Seed,\n networkPassphrase: stellarConfig.networkPassphrase,\n ...(input.expectedPublicKey ? { expectedPublicKey: input.expectedPublicKey } : {}),\n });\n },\n }),\n [ctx, stellarConfig],\n );\n\n const kyc = useMemo<KycNamespace>(\n () => ({\n async start() {\n return ctx.endpoints.kycStart();\n },\n async status() {\n return ctx.endpoints.kycStatus();\n },\n }),\n [ctx],\n );\n\n // ── Recovery v2 (Fase 1, 2026-06-15) ──────────────────────────────────────\n // Esta primera versión expone los wrappers thin de los 3 endpoints públicos\n // (`requestOtp`, `verifyOtp`, `finalize`). El `finalize` aquí solo manda el\n // body al backend tal cual lo arme el caller — el orchestration completo\n // (descifrar F3 con recoveryKey, reconstruir seed, registrar new passkey,\n // firmar rotate_signer, etc.) se hace en el componente de UI con los\n // helpers de @accesly/core (deriveRecoveryKey, decryptAesGcm, etc.).\n //\n // Razón: el flujo requiere navegar 2-3 pantallas (pedir password, registrar\n // new passkey vía navigator.credentials.create, esperar response del user)\n // y meterlo todo dentro de un solo `finalize()` programáticamente hace el\n // UX worse. El example app va a tener el orchestrator end-to-end.\n const recovery = useMemo<RecoveryNamespace>(\n () => ({\n async requestOtp(input) {\n return ctx.endpoints.requestRecoveryOtp(input);\n },\n async verifyOtp(input) {\n return ctx.endpoints.verifyRecoveryOtp(input);\n },\n async reconstructSeed(input) {\n // 1. Trae F2_recovery + F3 + recoverySalt del backend.\n const frag = await ctx.endpoints.getFragment3(input.recoveryJwt);\n if (!frag.fragmentF2Recovery) {\n throw new Error(\n 'recovery.reconstructSeed: la wallet fue creada antes de Fase 1 y no tiene F2 cipher-bound a recoveryKey. No es recuperable vía OTP.',\n );\n }\n\n // 2. Decode salt + deriva recoveryKey con el password.\n const recoverySalt = base64ToBytes(frag.recoverySalt);\n const recoveryKey = deriveRecoveryKey({\n password: input.cognitoPassword,\n salt: recoverySalt,\n });\n\n // 3. Reconstruye seed via Shamir(F2, F3) ambos descifrados con\n // recoveryKey. `reconstructKey` zeroiza las plaintexts internas.\n const f2Envelope: EncryptedEnvelope = {\n ciphertext: base64ToBytes(frag.fragmentF2Recovery.ciphertext),\n nonce: base64ToBytes(frag.fragmentF2Recovery.nonce),\n };\n const f3Envelope: EncryptedEnvelope = {\n ciphertext: base64ToBytes(frag.fragmentF3Encrypted.ciphertext),\n nonce: base64ToBytes(frag.fragmentF3Encrypted.nonce),\n };\n const seedResult = reconstructKey({\n fragments: [\n { envelope: f2Envelope, key: recoveryKey },\n { envelope: f3Envelope, key: recoveryKey },\n ],\n });\n\n return {\n privateSeed: seedResult.privateSeed,\n publicKey: seedResult.publicKey,\n recoveryKey,\n recoverySalt: frag.recoverySalt,\n };\n },\n async finalize(input) {\n const networkPassphrase = stellarConfig.networkPassphrase;\n const verifierAddress = stellarConfig.ed25519VerifierAddress;\n const explorerBase =\n networkPassphrase === 'Public Global Stellar Network ; September 2015'\n ? 'https://stellar.expert/explorer/public/tx/'\n : 'https://stellar.expert/explorer/testnet/tx/';\n\n const enc = new TextEncoder();\n const cognitoPasswordBytes = enc.encode(input.password);\n\n // 1. Reconstruct la seed VIEJA via Shamir(F2_recovery + F3). El SDK ya\n // expone esto como `this.reconstructSeed` — reusamos.\n const seedResult = await this.reconstructSeed({\n cognitoPassword: cognitoPasswordBytes,\n recoveryJwt: input.recoveryJwt,\n });\n const oldReconstructedSeed = seedResult.privateSeed;\n const oldOwnerPubkey = seedResult.publicKey;\n const oldRecoveryKey = seedResult.recoveryKey;\n\n try {\n // 2. Registrar el NUEVO passkey con PRF.\n const userIdHash = sha256(enc.encode(input.email));\n const newPrfSalt = getRandomBytes(32);\n const rpId =\n input.passkey?.rpId ??\n (typeof window !== 'undefined' ? window.location.hostname : 'localhost');\n const rpName = input.passkey?.rpName ?? 'Accesly';\n const passkey = await registerPasskey({\n rpId,\n rpName,\n userId: userIdHash,\n userName: input.email,\n prfSalt: newPrfSalt,\n });\n if (!passkey.prfSupported || !passkey.prfOutput) {\n throw new Error(\n 'recovery.finalize: the new authenticator did not return PRF output. ' +\n 'Required by Accesly. Use Chrome 116+, Edge 116+, Safari 18+ with a native OS passkey.',\n );\n }\n\n // 3. Derivar las dos AES keys nuevas (F1' PRF-bound, F2' PRF-bound)\n // + el encryptionSalt persistible.\n const encryptionSalt = getRandomBytes(32);\n const newF1Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f1-encryption'),\n 32,\n );\n const newF2Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f2-encryption'),\n 32,\n );\n zeroize(passkey.prfOutput);\n\n // 4. Genera NUEVA seed + new Shamir split. F3' se cifra con\n // newRecoveryKey (PBKDF2(password, newRecoverySalt, 600k)).\n const newRecoverySalt = generateRecoverySalt();\n const newRecoveryKey = deriveRecoveryKey({\n password: cognitoPasswordBytes,\n salt: newRecoverySalt,\n });\n const newRecoverySaltBase64 = base64FromBytes(newRecoverySalt);\n const newEmailSalt = getRandomBytes(32);\n\n const created = coreCreateWallet({\n emailBytes: enc.encode(input.email),\n emailSalt: newEmailSalt,\n encryptionKeys: [newF1Key, newF2Key, newRecoveryKey] as const,\n });\n\n // 5. F2_recovery — derivar el envelope cifrado con newRecoveryKey.\n // Descifra F2' (PRF-bound) → re-cifra con recoveryKey. La seed\n // plaintext nunca se toca acá; solo el SHARE plaintext.\n const f2PlainShare = decryptAesGcm(created.encryptedFragments[1], newF2Key);\n let newFragmentF2Recovery: EncryptedEnvelope;\n try {\n newFragmentF2Recovery = encryptAesGcm(f2PlainShare, newRecoveryKey);\n } finally {\n zeroize(f2PlainShare);\n }\n\n const newSecp256r1Canonical = normalizeSecp256r1Pubkey(passkey.secp256r1Pubkey);\n const newOwnerHex = hexFromBytes(created.publicKey);\n const newSecpHex = hexFromBytes(newSecp256r1Canonical);\n const newEmailCommitHex = hexFromBytes(created.emailCommitment);\n\n // 6. POST /recovery/simulate-rotate-signer.\n const sim = await ctx.endpoints.simulateRotateSigner(input.recoveryJwt, {\n newOwnerEd25519Pubkey: newOwnerHex,\n newSecp256r1Pubkey: newSecpHex,\n newEmailCommitment: newEmailCommitHex,\n });\n\n // 7. Firmar la auth entry con la SEED VIEJA. signSorobanAuthEntry\n // zero-iza la seed internamente.\n const { signedAuthEntryXdr } = await signSorobanAuthEntry({\n signaturePayloadHashBase64: sim.signaturePayloadHashBase64,\n contextRuleIds: [...sim.contextRuleIds],\n placeholderAuthEntryXdr: sim.placeholderAuthEntryXdr,\n ed25519Seed: oldReconstructedSeed,\n ed25519VerifierAddress: verifierAddress,\n ownerPubkey: oldOwnerPubkey,\n });\n\n // 8. POST /recovery/finalize.\n let finalizeResp;\n try {\n finalizeResp = await ctx.endpoints.finalizeRecovery(input.recoveryJwt, {\n unsignedXdr: sim.unsignedXdr,\n signedAuthEntryXdr,\n newOwnerEd25519Pubkey: newOwnerHex,\n newSecp256r1Pubkey: newSecpHex,\n newFragmentF1Encrypted: encodeFragmentToWire(created.encryptedFragments[0]),\n newFragmentF2Encrypted: encodeFragmentToWire(created.encryptedFragments[1]),\n newFragmentF2Recovery: encodeFragmentToWire(newFragmentF2Recovery),\n newFragmentF3Encrypted: encodeFragmentToWire(created.encryptedFragments[2]),\n newRecoverySalt: newRecoverySaltBase64,\n newEmailCommitment: newEmailCommitHex,\n });\n } finally {\n zeroize(newRecoveryKey);\n }\n\n // 9. Persistir el nuevo CredentialRecord (con encryptionSalt para que\n // unlockForSigning pueda re-derivar las mismas keys).\n await ctx.deviceStore.saveCredential({\n username: input.email,\n credentialId: passkey.credentialId,\n secp256r1Pubkey: newSecp256r1Canonical,\n fragmentF1Encrypted: created.encryptedFragments[0],\n fragmentF2Encrypted: created.encryptedFragments[1],\n fragmentF3Encrypted: created.encryptedFragments[2],\n publicKey: created.publicKey,\n emailCommitment: created.emailCommitment,\n prfSalt: newPrfSalt,\n encryptionSalt,\n fallbackKeyMaterial: new Uint8Array(0),\n walletAddress: finalizeResp.walletAddress,\n onChain: true,\n createdAt: Date.now(),\n });\n\n // Zeroize key material que aún tenemos en mano.\n zeroize(newF1Key);\n zeroize(newF2Key);\n\n return {\n walletAddress: finalizeResp.walletAddress,\n txHash: finalizeResp.txHash,\n status: finalizeResp.status,\n newPublicKey: created.publicKey,\n explorerUrl: `${explorerBase}${finalizeResp.txHash}`,\n };\n } finally {\n // Zeroize TODO el material sensitive aunque algo truene a mitad.\n zeroize(cognitoPasswordBytes);\n zeroize(oldReconstructedSeed);\n zeroize(oldRecoveryKey);\n }\n },\n async submitFinalize(input) {\n return ctx.endpoints.finalizeRecovery(input.recoveryJwt, {\n unsignedXdr: input.unsignedXdr,\n signedAuthEntryXdr: input.signedAuthEntryXdr,\n newOwnerEd25519Pubkey: input.newOwnerEd25519Pubkey,\n newSecp256r1Pubkey: input.newSecp256r1Pubkey,\n newFragmentF1Encrypted: encodeFragmentToWire(input.newFragmentF1Encrypted),\n newFragmentF2Encrypted: encodeFragmentToWire(input.newFragmentF2Encrypted),\n newFragmentF2Recovery: encodeFragmentToWire(input.newFragmentF2Recovery),\n newFragmentF3Encrypted: encodeFragmentToWire(input.newFragmentF3Encrypted),\n newRecoverySalt: input.newRecoverySalt,\n newEmailCommitment: input.newEmailCommitment,\n });\n },\n }),\n [ctx, stellarConfig, hexFromBytes],\n );\n\n const session = useMemo<SessionNamespace>(\n () => ({\n async create() {\n throw new NotImplementedYetError('session', 'create');\n },\n async revoke() {\n throw new NotImplementedYetError('session', 'revoke');\n },\n }),\n [],\n );\n\n const settings = useMemo<SettingsNamespace>(\n () => ({\n async addDevice() {\n throw new NotImplementedYetError('settings', 'addDevice');\n },\n async removeDevice() {\n throw new NotImplementedYetError('settings', 'removeDevice');\n },\n async listDevices() {\n throw new NotImplementedYetError('settings', 'listDevices');\n },\n async updateSpendingLimit() {\n throw new NotImplementedYetError('settings', 'updateSpendingLimit');\n },\n }),\n [],\n );\n\n const yieldOps = useMemo<YieldNamespace>(\n () => ({\n async invest() {\n throw new NotImplementedYetError('yield', 'invest');\n },\n async redeem() {\n throw new NotImplementedYetError('yield', 'redeem');\n },\n async position() {\n throw new NotImplementedYetError('yield', 'position');\n },\n }),\n [],\n );\n\n // hexToBytes is reserved for future helpers.\n void hexToBytes;\n return { auth, wallet, tx, kyc, recovery, session, settings, yieldOps, _internal: ctx };\n}\n\n/* --------------------------------- helpers --------------------------------- */\n\nfunction coderHelpers(): {\n hexToBytes: (hex: string) => Uint8Array;\n hexFromBytes: (bytes: Uint8Array) => string;\n} {\n function hexFromBytes(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 1) {\n out += (bytes[i] ?? 0).toString(16).padStart(2, '0');\n }\n return out;\n }\n function hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n if (clean.length % 2 !== 0) throw new Error(`hexToBytes: odd length ${clean.length}`);\n const out = new Uint8Array(clean.length / 2);\n for (let i = 0; i < out.length; i += 1) {\n out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n }\n return { hexToBytes, hexFromBytes };\n}\n\nfunction encodeFragmentToWire(env: EncryptedEnvelope): {\n ciphertext: string;\n nonce: string;\n algo: 'aes-256-gcm';\n} {\n return {\n ciphertext: base64FromBytes(env.ciphertext),\n nonce: base64FromBytes(env.nonce),\n algo: 'aes-256-gcm',\n };\n}\n\nfunction base64FromBytes(bytes: Uint8Array): string {\n if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64');\n // Browser fallback\n let bin = '';\n for (let i = 0; i < bytes.length; i += 1) bin += String.fromCharCode(bytes[i] ?? 0);\n return globalThis.btoa(bin);\n}\n\nfunction base64ToBytes(s: string): Uint8Array {\n if (typeof Buffer !== 'undefined') return new Uint8Array(Buffer.from(s, 'base64'));\n const bin = globalThis.atob(s);\n const arr = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i += 1) arr[i] = bin.charCodeAt(i);\n return arr;\n}\n","/**\n * `AcceslyProvider` — top-level React provider that creates the SDK instances\n * once and exposes them through context. All hooks consume this.\n *\n * Apps wrap their tree:\n * <AcceslyProvider appId=\"myapp\" env=\"dev\">\n * <App />\n * </AcceslyProvider>\n *\n * For advanced cases (custom IdP, custom storage), pass `overrides` to inject\n * your own `AuthClient`, `SessionStorage`, or `DeviceStore`.\n */\n\nimport {\n AccesslyApiClient,\n AccesslyEndpoints,\n CognitoAuthClient,\n defaultSessionStorage,\n InMemoryDeviceStore,\n TokenManager,\n type AuthClient,\n type AuthStatus,\n type CognitoConfig,\n type DeviceStore,\n type Environment,\n type SessionStorage,\n type TelemetrySink,\n} from '@accesly/core';\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { AcceslyContext, type AcceslyContextValue } from './context.js';\nimport { ENVIRONMENT_DEFAULTS } from './config.js';\n\nexport interface AcceslyProviderProps {\n readonly appId: string;\n readonly env: Environment;\n readonly children: ReactNode;\n /** Override the resolved API URL. */\n readonly apiUrl?: string;\n /** Override the resolved Cognito config. */\n readonly cognitoConfig?: CognitoConfig;\n /** Override SDK pieces — for tests or custom backends. */\n readonly overrides?: {\n readonly authClient?: AuthClient;\n readonly sessionStorage?: SessionStorage;\n readonly deviceStore?: DeviceStore;\n };\n /** Optional telemetry sink — surfaces every API request/response/retry. */\n readonly telemetry?: TelemetrySink;\n}\n\nexport function AcceslyProvider(props: AcceslyProviderProps): JSX.Element {\n const defaults = ENVIRONMENT_DEFAULTS[props.env];\n const apiUrl = props.apiUrl ?? defaults.apiUrl;\n const cognitoConfig = props.cognitoConfig ?? defaults.cognito;\n const telemetry = props.telemetry;\n\n // Build the SDK pieces once. The dependency array is intentionally only the\n // identity inputs — we don't want to rebuild on every render.\n const instances = useMemo(() => {\n const authClient: AuthClient =\n props.overrides?.authClient ?? new CognitoAuthClient(cognitoConfig);\n // Default: LocalStorageSessionStorage en browsers (sobrevive reload),\n // InMemorySessionStorage en Node/SSR. Override solo si tu app necesita\n // un backend distinto (httpOnly cookie, Electron safeStorage, etc.).\n const sessionStorage: SessionStorage =\n props.overrides?.sessionStorage ?? defaultSessionStorage();\n const deviceStore: DeviceStore = props.overrides?.deviceStore ?? new InMemoryDeviceStore();\n const tokenManager = new TokenManager({ authClient, storage: sessionStorage });\n const apiClient = new AccesslyApiClient({\n baseUrl: apiUrl,\n getIdToken: () => tokenManager.getValidIdToken(),\n ...(telemetry ? { telemetry } : {}),\n });\n const endpoints = new AccesslyEndpoints(apiClient);\n return { authClient, sessionStorage, deviceStore, tokenManager, endpoints };\n }, [\n apiUrl,\n cognitoConfig.region,\n cognitoConfig.userPoolId,\n cognitoConfig.userPoolClientId,\n props.overrides?.authClient,\n props.overrides?.sessionStorage,\n props.overrides?.deviceStore,\n ]);\n\n // Compute the initial status synchronously from storage when possible. If\n // storage.load returns a Promise (custom async storage), fall back to\n // 'anonymous' and let the mount effect upgrade it.\n const [status, setStatus] = useState<AuthStatus>(() => initialStatus(instances.sessionStorage));\n const [username, setUsername] = useState<string | null>(() =>\n initialUsername(instances.sessionStorage),\n );\n const mountedRef = useRef(true);\n\n // refreshStatus tiene que ser estable entre renders, si no el ctx value\n // cambia siempre y los hooks consumers (useBalance, useWalletActivity,\n // useWalletStatus) se re-disparan en loop infinito porque sus effects\n // dependen de `_internal.endpoints` que viene del ctx.\n const refreshStatus = useCallback(async (): Promise<void> => {\n const next = await instances.tokenManager.getStatus();\n const tokens = await Promise.resolve(instances.sessionStorage.load());\n if (mountedRef.current) {\n setStatus(next);\n setUsername(tokens?.username ?? null);\n }\n }, [instances]);\n\n useEffect(() => {\n mountedRef.current = true;\n void refreshStatus();\n return () => {\n mountedRef.current = false;\n };\n }, [instances]);\n\n const value: AcceslyContextValue = useMemo(\n () => ({\n appId: props.appId,\n env: props.env,\n apiUrl,\n cognitoConfig,\n authClient: instances.authClient,\n sessionStorage: instances.sessionStorage,\n tokenManager: instances.tokenManager,\n endpoints: instances.endpoints,\n deviceStore: instances.deviceStore,\n status,\n username,\n refreshStatus,\n }),\n [props.appId, props.env, apiUrl, cognitoConfig, instances, status, username, refreshStatus],\n );\n\n return <AcceslyContext.Provider value={value}>{props.children}</AcceslyContext.Provider>;\n}\n\n/**\n * Estado inicial — antes de que el effect del provider corra `refreshStatus()`.\n *\n * - Si el `SessionStorage` devuelve sync con tokens válidos → arrancamos directo\n * en `'authenticated'` / `'expired'`. Aplica al `LocalStorageSessionStorage`\n * default; el primer paint del browser ya conoce el status real → cero race\n * para `AuthGuard`.\n * - Si el `SessionStorage` devuelve sync con `null` → directo a `'anonymous'`.\n * - Si el `SessionStorage` es async (devuelve Promise) → `'bootstrapping'`,\n * para que `<AuthGuard>` muestre un loader en vez de redirigir a `/signin`\n * prematuramente. El effect lo flippa al estado real apenas resuelve.\n */\nfunction initialStatus(storage: SessionStorage): AuthStatus {\n const tokens = storage.load();\n if (tokens instanceof Promise) return 'bootstrapping';\n if (!tokens) return 'anonymous';\n return Date.now() + 5 * 60 * 1000 >= tokens.expiresAt ? 'expired' : 'authenticated';\n}\n\nfunction initialUsername(storage: SessionStorage): string | null {\n const tokens = storage.load();\n if (tokens instanceof Promise) return null;\n return tokens?.username ?? null;\n}\n","/**\n * @accesly/react — React Provider + `useAccesly` hook.\n *\n * Wraps `@accesly/core` for React 18+. Apps integrate with:\n *\n * import { AcceslyProvider, useAccesly } from '@accesly/react';\n *\n * function App() {\n * return (\n * <AcceslyProvider appId=\"my-app\" env=\"dev\">\n * <YourApp />\n * </AcceslyProvider>\n * );\n * }\n *\n * function Login() {\n * const { auth } = useAccesly();\n * return (\n * <button onClick={() => auth.signIn(email, password)}>Sign in</button>\n * );\n * }\n */\n\nexport const REACT_ADAPTER_VERSION = '0.0.0';\n\nexport { AcceslyProvider, type AcceslyProviderProps } from './provider.js';\nexport { AcceslyContext, type AcceslyContextValue } from './context.js';\nexport { ENVIRONMENT_DEFAULTS, type EnvironmentDefaults } from './config.js';\nexport {\n NotImplementedYetError,\n useAccesly,\n type AcceslyHook,\n type AuthNamespace,\n type BootstrapWalletInput,\n type CreatedWalletInfo,\n type CreateWalletInput,\n type EnsureWalletResult,\n type FinalizeRecoveryInput,\n type FinalizeRecoveryResult,\n type KycNamespace,\n type RecoveryNamespace,\n type ReconstructedSeed,\n type RemoteWalletInfo,\n type RetryDeployResult,\n type SendXlmInput,\n type SendXlmResult,\n type SessionNamespace,\n type SettingsNamespace,\n type TxNamespace,\n type UnlockedSigningMaterial,\n type WalletNamespace,\n type WalletStatus,\n type YieldNamespace,\n} from './hooks/useAccesly.js';\n\nexport { useWalletStatus, type UseWalletStatusResult, type WalletStatusValue } from './hooks/useWalletStatus.js';\nexport { useBalance, type UseBalanceResult } from './hooks/useBalance.js';\nexport {\n useWalletActivity,\n type UseWalletActivityOptions,\n type UseWalletActivityResult,\n} from './hooks/useWalletActivity.js';\nexport {\n useWalletHistory,\n historyOptimisticPush,\n historyClearOptimistic,\n type UseWalletHistoryOptions,\n type UseWalletHistoryResult,\n} from './hooks/useWalletHistory.js';\nexport {\n closeAllWalletSubscriptions,\n subscribeToWalletEvent,\n type WalletActivityItem,\n type WalletStreamActivityPayload,\n type WalletStreamBalancePayload,\n type WalletStreamEventType,\n type WalletStreamStatusPayload,\n} from './hooks/walletSubscription.js';\n","/**\n * `useWalletStatus()` — status on-chain del Smart Account del user actual con\n * push real-time vía SSE.\n *\n * Reemplaza el polling cada 30s del legacy. Comportamiento:\n *\n * 1. SSE-first: si `walletStreamUrl` está configurado y `EventSource` existe,\n * se suscribe al canal `status` del `wallet-stream` Lambda. Cero polling.\n * 2. Fallback a polling backoff (1s → 30s) si SSE no está disponible.\n * 3. Pausa cuando `document.hidden`, retoma al volver.\n * 4. `refresh()` fuerza fetch HTTP inmediato.\n *\n * El status del Smart Account vive en DDB (lo que el backend reporta de su\n * verificación contra Soroban). El backend push-ea cambios cuando los detecta\n * (cada 5s en el loop del wallet-stream).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAccesly } from './useAccesly.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\nimport { subscribeToWalletEvent } from './walletSubscription.js';\n\nexport type WalletStatusValue = 'on-chain' | 'pending-deploy' | 'unknown' | 'no-wallet';\n\nconst POLL_BACKOFF_MS = [2000, 5000, 10_000, 20_000, 30_000];\nconst STALE_THRESHOLD_MS = 60_000;\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport interface UseWalletStatusResult {\n readonly status: WalletStatusValue;\n readonly walletAddress: string | null;\n readonly onChain: boolean | null;\n readonly isStale: boolean;\n refresh(): Promise<void>;\n}\n\nfunction deriveStatus(onChain: boolean | null): WalletStatusValue {\n if (onChain === true) return 'on-chain';\n if (onChain === false) return 'pending-deploy';\n return 'unknown';\n}\n\nexport function useWalletStatus(): UseWalletStatusResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n\n const [status, setStatus] = useState<WalletStatusValue>('unknown');\n const [walletAddress, setWalletAddress] = useState<string | null>(null);\n const [onChain, setOnChain] = useState<boolean | null>(null);\n const [lastSuccessAt, setLastSuccessAt] = useState<number>(0);\n const [isStale, setIsStale] = useState(false);\n\n const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];\n const streamUrl = envDefaults.walletStreamUrl;\n const walletRef = useStableRef(wallet);\n\n const doFetch = useCallback(async (): Promise<WalletStatusValue | null> => {\n if (!username) return null;\n try {\n const remote = await walletRef.current.fetchRemote();\n if (!remote) {\n setStatus('no-wallet');\n setWalletAddress(null);\n setOnChain(null);\n setLastSuccessAt(Date.now());\n setIsStale(false);\n return 'no-wallet';\n }\n const next = deriveStatus(remote.onChain);\n setStatus(next);\n setWalletAddress(remote.walletAddress);\n setOnChain(remote.onChain);\n setLastSuccessAt(Date.now());\n setIsStale(false);\n return next;\n } catch {\n return null;\n }\n }, [username, walletRef]);\n\n const doFetchRef = useStableRef(doFetch);\n\n useEffect(() => {\n if (!username) {\n setStatus('unknown');\n return undefined;\n }\n\n // Primer fetch HTTP para resolver walletAddress + status inicial.\n let cancelled = false;\n let unsubscribe: (() => void) | null = null;\n let pollTimer: ReturnType<typeof setTimeout> | null = null;\n let backoffIndex = 0;\n\n const schedulePoll = (delayMs: number) => {\n if (cancelled) return;\n pollTimer = setTimeout(async () => {\n if (cancelled) return;\n if (typeof document !== 'undefined' && document.hidden) return;\n const next = await doFetchRef.current();\n if (next === 'on-chain' || next === 'no-wallet') return;\n backoffIndex = Math.min(backoffIndex + 1, POLL_BACKOFF_MS.length - 1);\n schedulePoll(POLL_BACKOFF_MS[backoffIndex]!);\n }, delayMs);\n };\n\n void (async () => {\n const initial = await doFetchRef.current();\n if (cancelled) return;\n if (initial === 'on-chain' || initial === 'no-wallet') return;\n\n // Intentar SSE.\n if (walletAddress) {\n unsubscribe = subscribeToWalletEvent(streamUrl, walletAddress, 'status', (data) => {\n setWalletAddress(data.walletAddress);\n setOnChain(data.onChain);\n setStatus(deriveStatus(data.onChain));\n setLastSuccessAt(Date.now());\n setIsStale(false);\n });\n }\n if (!unsubscribe) {\n // SSE no disponible → polling con backoff.\n backoffIndex = 0;\n schedulePoll(POLL_BACKOFF_MS[0]!);\n }\n })();\n\n const onVisibilityChange = () => {\n if (typeof document === 'undefined') return;\n if (!document.hidden && !unsubscribe) {\n void doFetchRef.current();\n }\n };\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', onVisibilityChange);\n }\n\n const staleTimer = setInterval(() => {\n if (Date.now() - lastSuccessAt > STALE_THRESHOLD_MS && lastSuccessAt > 0) {\n setIsStale(true);\n }\n }, 30_000);\n\n return () => {\n cancelled = true;\n if (unsubscribe) unsubscribe();\n if (pollTimer) clearTimeout(pollTimer);\n clearInterval(staleTimer);\n if (typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [username, streamUrl, walletAddress]);\n\n const refresh = useCallback(async () => {\n await doFetchRef.current();\n }, [doFetchRef]);\n\n return { status, walletAddress, onChain, isStale, refresh };\n}\n","/**\n * `WalletSubscription` — singleton manager por wallet address que abre UNA\n * sola conexión `EventSource` al `wallet-stream` Lambda y desmultiplexa los\n * eventos a múltiples subscribers (hooks).\n *\n * Beneficios:\n * - 3 hooks (`useBalance`, `useWalletActivity`, `useWalletStatus`) sobre la\n * misma wallet → 1 sola conexión TCP, no 3 polls separados.\n * - Auto-reconnect cuando el server cierra (default de EventSource — `retry:`).\n * - Ref-count: la conexión se abre con el primer subscriber y se cierra\n * cuando no quedan listeners (`useEffect` cleanup en cada hook).\n * - Eventos cacheados: el último valor recibido de cada tipo se replay-ea\n * a nuevos subscribers para que no esperen el próximo push.\n *\n * Sin SSE configurado (`walletStreamUrl` vacío) o cuando `EventSource` no\n * existe (SSR / workers), los hooks individuales detectan el flag\n * `unavailable` y caen al polling fallback que ya existe.\n */\n\nexport type WalletStreamEventType = 'status' | 'balance' | 'activity';\n\nexport interface WalletStreamStatusPayload {\n readonly walletAddress: string | null;\n readonly onChain: boolean | null;\n}\n\nexport interface WalletStreamBalancePayload {\n readonly stroops: string;\n readonly xlm: string;\n}\n\n/**\n * Activity tipada lista para renderizar. Cuatro variants:\n *\n * - `wallet-created` — deploy inicial del Smart Account.\n * - `signer-rotated` — rotación de signer (recovery).\n * - `transfer-in` — recibió XLM.\n * - `transfer-out` — envió XLM.\n *\n * Otros eventos on-chain (signer_added/removed internos, ruido) se descartan.\n */\nexport type WalletActivityItem =\n | {\n readonly type: 'wallet-created';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n }\n | {\n readonly type: 'signer-rotated';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n readonly newOwnerEd25519Hex: string;\n }\n | {\n readonly type: 'transfer-in';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n readonly from: string;\n readonly amountStroops: string;\n }\n | {\n readonly type: 'transfer-out';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n readonly to: string;\n readonly amountStroops: string;\n };\n\nexport interface WalletStreamActivityPayload {\n readonly events: readonly WalletActivityItem[];\n}\n\ntype Listener<T> = (payload: T) => void;\n\ninterface InternalSubscription {\n status: Set<Listener<WalletStreamStatusPayload>>;\n balance: Set<Listener<WalletStreamBalancePayload>>;\n activity: Set<Listener<WalletStreamActivityPayload>>;\n}\n\ninterface WalletSubscriptionState {\n readonly walletAddress: string;\n readonly url: string;\n eventSource: EventSource | null;\n listeners: InternalSubscription;\n lastStatus: WalletStreamStatusPayload | null;\n lastBalance: WalletStreamBalancePayload | null;\n /** Acumulamos los últimos eventos para que nuevos subscribers vean histórico. */\n activityBuffer: WalletActivityItem[];\n refCount: number;\n}\n\nconst ACTIVITY_BUFFER_MAX = 50;\n\nconst subscriptions = new Map<string, WalletSubscriptionState>();\n\nfunction buildSubscriptionUrl(streamUrl: string, walletAddress: string): string {\n // Lambda Function URL ya trae trailing slash en algunos casos — normalizamos.\n const base = streamUrl.replace(/\\/$/, '');\n return `${base}/?walletAddress=${encodeURIComponent(walletAddress)}`;\n}\n\nfunction openConnection(state: WalletSubscriptionState): void {\n if (state.eventSource) return;\n if (typeof EventSource === 'undefined') return;\n\n let es: EventSource;\n try {\n es = new EventSource(state.url, { withCredentials: false });\n } catch (err) {\n console.warn('[walletSubscription] EventSource construction failed', err);\n return;\n }\n state.eventSource = es;\n\n es.addEventListener('status', (ev) => {\n try {\n const data = JSON.parse((ev as MessageEvent).data) as WalletStreamStatusPayload;\n state.lastStatus = data;\n for (const listener of state.listeners.status) listener(data);\n } catch {\n /* ignore malformed */\n }\n });\n\n es.addEventListener('balance', (ev) => {\n try {\n const data = JSON.parse((ev as MessageEvent).data) as WalletStreamBalancePayload;\n state.lastBalance = data;\n for (const listener of state.listeners.balance) listener(data);\n } catch {\n /* ignore malformed */\n }\n });\n\n es.addEventListener('activity', (ev) => {\n try {\n const data = JSON.parse((ev as MessageEvent).data) as WalletStreamActivityPayload;\n // Acumula al buffer (más reciente primero). Trim al max.\n const merged = [...data.events, ...state.activityBuffer];\n // Dedup por txHash + ledger.\n const seen = new Set<string>();\n const deduped: WalletActivityItem[] = [];\n for (const item of merged) {\n const key = `${item.txHash}:${item.ledger}`;\n if (seen.has(key)) continue;\n seen.add(key);\n deduped.push(item);\n if (deduped.length >= ACTIVITY_BUFFER_MAX) break;\n }\n state.activityBuffer = deduped;\n for (const listener of state.listeners.activity) {\n listener({ events: state.activityBuffer });\n }\n } catch {\n /* ignore malformed */\n }\n });\n\n es.addEventListener('close', () => {\n // El server cerró por timeout de budget — EventSource reconectará solo.\n // No hacemos nada acá.\n });\n\n es.onerror = () => {\n // Network blip o end-of-stream. EventSource auto-reconecta por default,\n // pero si la URL no funciona (404, CORS) el browser cierra para siempre.\n // No cerramos nosotros para dejar que el browser lo intente.\n };\n}\n\nfunction closeConnection(state: WalletSubscriptionState): void {\n if (!state.eventSource) return;\n state.eventSource.close();\n state.eventSource = null;\n}\n\nfunction getOrCreateSubscription(\n streamUrl: string,\n walletAddress: string,\n): WalletSubscriptionState {\n const existing = subscriptions.get(walletAddress);\n if (existing) return existing;\n const state: WalletSubscriptionState = {\n walletAddress,\n url: buildSubscriptionUrl(streamUrl, walletAddress),\n eventSource: null,\n listeners: {\n status: new Set(),\n balance: new Set(),\n activity: new Set(),\n },\n lastStatus: null,\n lastBalance: null,\n activityBuffer: [],\n refCount: 0,\n };\n subscriptions.set(walletAddress, state);\n return state;\n}\n\n/**\n * Suscribirse a un tipo de evento de la wallet. Devuelve una función\n * de cleanup que el caller (típicamente `useEffect`) debe llamar para\n * desuscribir y, eventualmente, cerrar la conexión SSE.\n *\n * Si SSE no está disponible (URL vacía, EventSource undefined), devuelve\n * `null` para indicar al caller que use el fallback de polling.\n */\nexport function subscribeToWalletEvent<T extends WalletStreamEventType>(\n streamUrl: string,\n walletAddress: string,\n eventType: T,\n listener: T extends 'status'\n ? Listener<WalletStreamStatusPayload>\n : T extends 'balance'\n ? Listener<WalletStreamBalancePayload>\n : Listener<WalletStreamActivityPayload>,\n): (() => void) | null {\n if (!streamUrl || typeof EventSource === 'undefined') return null;\n\n const state = getOrCreateSubscription(streamUrl, walletAddress);\n state.refCount += 1;\n\n // Registrar listener (cast a través del shape conocido).\n (state.listeners[eventType] as Set<typeof listener>).add(listener);\n\n // Replay del último valor cacheado para que el subscriber tenga data inmediata.\n if (eventType === 'status' && state.lastStatus) {\n (listener as Listener<WalletStreamStatusPayload>)(state.lastStatus);\n } else if (eventType === 'balance' && state.lastBalance) {\n (listener as Listener<WalletStreamBalancePayload>)(state.lastBalance);\n } else if (eventType === 'activity' && state.activityBuffer.length > 0) {\n (listener as Listener<WalletStreamActivityPayload>)({\n events: state.activityBuffer,\n });\n }\n\n // Abrir conexión si es el primer subscriber.\n if (!state.eventSource) openConnection(state);\n\n return () => {\n (state.listeners[eventType] as Set<typeof listener>).delete(listener);\n state.refCount -= 1;\n if (state.refCount <= 0) {\n closeConnection(state);\n subscriptions.delete(walletAddress);\n }\n };\n}\n\n/**\n * Cierra TODAS las conexiones SSE activas. Útil para tests o cuando el user\n * cierra sesión y querés limpiar conexiones colgadas. Llamar en `auth.signOut`\n * lo tienen pendiente como mejora — por ahora el cleanup natural de los\n * unmount basta.\n */\nexport function closeAllWalletSubscriptions(): void {\n for (const state of subscriptions.values()) closeConnection(state);\n subscriptions.clear();\n}\n","/**\n * `useBalance(walletAddress?)` — devuelve el balance XLM del Smart Account\n * con push real-time vía SSE.\n *\n * Si SSE está configurado (env tiene `walletStreamUrl` y `EventSource` existe),\n * el hook se suscribe al canal `balance` del `wallet-stream` Lambda y se\n * actualiza instantáneamente cuando cambia el balance on-chain.\n *\n * Fallback automático a polling cada 10s si SSE no está disponible (entorno\n * que no lo soporta o backend self-hosteado sin el endpoint).\n *\n * El `walletAddress` se auto-resuelve desde el `DeviceStore` si no se pasa\n * (cubrir el caso \"wallet del user actual sin tener que pasarla a mano\").\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAccesly } from './useAccesly.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\nimport { subscribeToWalletEvent } from './walletSubscription.js';\n\nconst POLL_FALLBACK_MS = 10_000;\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport interface UseBalanceResult {\n /** Stroops como string base-10. `null` mientras se carga o no hay address. */\n readonly stroops: string | null;\n /** Mismo balance como string decimal en XLM. `null` mientras se carga. */\n readonly xlm: string | null;\n readonly isLoading: boolean;\n readonly error: Error | null;\n /** Fuerza fetch HTTP inmediato (útil tras una operación del user). */\n refresh(): Promise<void>;\n}\n\nexport function useBalance(walletAddress?: string | null): UseBalanceResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n\n const [resolvedAddress, setResolvedAddress] = useState<string | null>(\n walletAddress ?? null,\n );\n const [stroops, setStroops] = useState<string | null>(null);\n const [xlm, setXlm] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Resolver walletAddress si no fue pasado explícitamente.\n const walletRef = useStableRef(wallet);\n useEffect(() => {\n if (walletAddress) {\n setResolvedAddress(walletAddress);\n return;\n }\n if (!username) {\n setResolvedAddress(null);\n return;\n }\n let cancelled = false;\n void (async () => {\n try {\n const stored = await walletRef.current.getStoredCredential(username);\n if (cancelled) return;\n setResolvedAddress(stored?.walletAddress ?? null);\n } catch {\n if (!cancelled) setResolvedAddress(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [walletAddress, username, walletRef]);\n\n // Suscribirse SSE — o si no está, fallback a polling.\n const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];\n const streamUrl = envDefaults.walletStreamUrl;\n const endpointsRef = useStableRef(_internal.endpoints);\n\n const doFetchOnce = useCallback(async () => {\n if (!resolvedAddress) return;\n try {\n const res = await endpointsRef.current.walletBalance(resolvedAddress);\n setStroops(res.xlm.stroops);\n setXlm(res.xlm.xlm);\n setError(null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [resolvedAddress, endpointsRef]);\n\n const doFetchRef = useStableRef(doFetchOnce);\n useEffect(() => {\n if (!resolvedAddress) {\n setIsLoading(false);\n return undefined;\n }\n\n // Intentar suscripción SSE primero.\n const unsubscribe = subscribeToWalletEvent(\n streamUrl,\n resolvedAddress,\n 'balance',\n (data) => {\n setStroops(data.stroops);\n setXlm(data.xlm);\n setError(null);\n setIsLoading(false);\n },\n );\n\n if (unsubscribe) {\n // SSE conectado — pero hacemos UN fetch HTTP inicial para no esperar\n // hasta el primer push del server (puede tardar 10s).\n void doFetchRef.current();\n return unsubscribe;\n }\n\n // SSE no disponible → polling fallback.\n void doFetchRef.current();\n const interval = setInterval(() => {\n if (typeof document !== 'undefined' && document.hidden) return;\n void doFetchRef.current();\n }, POLL_FALLBACK_MS);\n\n const onVisibilityChange = () => {\n if (typeof document === 'undefined') return;\n if (!document.hidden) void doFetchRef.current();\n };\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', onVisibilityChange);\n }\n\n return () => {\n clearInterval(interval);\n if (typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n };\n }, [resolvedAddress, streamUrl, doFetchRef]);\n\n const refresh = useCallback(async () => {\n await doFetchRef.current();\n }, [doFetchRef]);\n\n return { stroops, xlm, isLoading, error, refresh };\n}\n","/**\n * `useWalletActivity(walletAddress?, opts?)` — actividad on-chain relevante de\n * la wallet (rotate_signer + transfers in/out de XLM) con push real-time vía SSE.\n *\n * El backend YA filtra eventos irrelevantes — el integrador solo recibe\n * `WalletActivityItem` tipados (`signer-rotated` | `transfer-in` | `transfer-out`).\n * Sin parsing manual de XDR ni lógica de filtrado client-side.\n *\n * Fallback: si SSE no está disponible, polling cada 25s al endpoint\n * `/wallets/:address/activity`. Mucho menos eficiente pero garantiza data.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAccesly } from './useAccesly.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\nimport {\n subscribeToWalletEvent,\n type WalletActivityItem,\n} from './walletSubscription.js';\n\nconst POLL_FALLBACK_MS = 25_000;\nconst DEFAULT_LIMIT = 20;\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport interface UseWalletActivityOptions {\n /** Cantidad de eventos a mostrar (cap del buffer del cliente). Default 20. */\n readonly limit?: number;\n}\n\nexport interface UseWalletActivityResult {\n /** Eventos tipados, más recientes primero. */\n readonly events: readonly WalletActivityItem[];\n readonly isLoading: boolean;\n readonly error: Error | null;\n refresh(): Promise<void>;\n}\n\nexport function useWalletActivity(\n walletAddress?: string | null,\n opts: UseWalletActivityOptions = {},\n): UseWalletActivityResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n const limit = Math.min(opts.limit ?? DEFAULT_LIMIT, 50);\n\n const [resolvedAddress, setResolvedAddress] = useState<string | null>(\n walletAddress ?? null,\n );\n const [events, setEvents] = useState<readonly WalletActivityItem[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const walletRef = useStableRef(wallet);\n useEffect(() => {\n if (walletAddress) {\n setResolvedAddress(walletAddress);\n return;\n }\n if (!username) {\n setResolvedAddress(null);\n return;\n }\n let cancelled = false;\n void (async () => {\n try {\n const stored = await walletRef.current.getStoredCredential(username);\n if (cancelled) return;\n setResolvedAddress(stored?.walletAddress ?? null);\n } catch {\n if (!cancelled) setResolvedAddress(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [walletAddress, username, walletRef]);\n\n const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];\n const streamUrl = envDefaults.walletStreamUrl;\n const endpointsRef = useStableRef(_internal.endpoints);\n\n const doFetchOnce = useCallback(async () => {\n if (!resolvedAddress) return;\n try {\n const res = await endpointsRef.current.walletActivity(resolvedAddress, limit);\n // El endpoint REST devuelve eventos sin tipar (parseado raw). Adaptamos\n // al shape tipado del SSE para que el integrador vea la misma forma —\n // y descartamos los que no encajen en los 3 tipos conocidos.\n const adapted: WalletActivityItem[] = [];\n for (const ev of res.events) {\n const conv = adaptRestEvent(ev);\n if (conv) adapted.push(conv);\n }\n setEvents(adapted.slice(0, limit));\n setError(null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [resolvedAddress, limit, endpointsRef]);\n\n const doFetchRef = useStableRef(doFetchOnce);\n useEffect(() => {\n if (!resolvedAddress) {\n setIsLoading(false);\n return undefined;\n }\n\n const unsubscribe = subscribeToWalletEvent(\n streamUrl,\n resolvedAddress,\n 'activity',\n (data) => {\n setEvents(data.events.slice(0, limit));\n setError(null);\n setIsLoading(false);\n },\n );\n\n if (unsubscribe) {\n void doFetchRef.current();\n return unsubscribe;\n }\n\n // Polling fallback.\n void doFetchRef.current();\n const interval = setInterval(() => {\n if (typeof document !== 'undefined' && document.hidden) return;\n void doFetchRef.current();\n }, POLL_FALLBACK_MS);\n\n return () => clearInterval(interval);\n }, [resolvedAddress, streamUrl, limit, doFetchRef]);\n\n const refresh = useCallback(async () => {\n await doFetchRef.current();\n }, [doFetchRef]);\n\n return { events, isLoading, error, refresh };\n}\n\n/**\n * Adapta un `WalletActivityEvent` raw (del REST endpoint) al `WalletActivityItem`\n * tipado del SSE. Best-effort — si no matchea ninguno de los 3 tipos conocidos,\n * devuelve null y el item se descarta.\n *\n * En la práctica el REST endpoint ya viene en formato compatible; este adapter\n * es solo defensa por si el shape divergiera en el futuro.\n */\nfunction adaptRestEvent(ev: {\n type: string;\n txHash: string;\n ledger: number;\n timestamp: string | null;\n topics: readonly unknown[];\n value: unknown;\n}): WalletActivityItem | null {\n const t0 = ev.topics[0];\n if (typeof t0 !== 'string') return null;\n if (t0 === 'SignerRotated') {\n return {\n type: 'signer-rotated',\n txHash: ev.txHash,\n ledger: ev.ledger,\n timestamp: ev.timestamp,\n newOwnerEd25519Hex: typeof ev.value === 'string' ? ev.value : '',\n };\n }\n // Transfers REST no vienen pre-filtrados como in/out; lo dejamos sin\n // adaptar — el integrador igual los ve via SSE en cuanto se conecta.\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/config.ts","../src/hooks/sorobanDeployStatus.ts","../src/hooks/useWalletHistory.ts","../src/hooks/useAccesly.ts","../src/provider.tsx","../src/index.ts","../src/hooks/useWalletStatus.ts","../src/hooks/walletSubscription.ts","../src/hooks/useBalance.ts","../src/hooks/useWalletActivity.ts"],"names":["AcceslyContext","createContext","ENVIRONMENT_DEFAULTS","AccesslyApiError","useRef","useState","useEffect","useCallback","useContext","useMemo","computeSmartAccountAddress","normalizeSecp256r1Pubkey","coreCreateWallet","generateRecoverySalt","decryptAesGcm","deriveRecoveryKey","encryptAesGcm","emailHashBytes","c","sha256","getRandomBytes","registerPasskey","hkdfSha256","zeroize","unlockPasskey","generateX25519Keypair","unwrapSessionFragment2","reconstructFromPlainAndEncrypted","signSorobanAuthEntry","historyOptimisticPush","coreSignTransaction","reconstructKey","NotImplementedYetError","CognitoAuthClient","defaultSessionStorage","InMemoryDeviceStore","TokenManager","AccesslyApiClient","AccesslyEndpoints","useStableRef","POLL_FALLBACK_MS"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * React context internals — keep separate from the Provider component to\n * make refactors and tests cleaner.\n */\n\nimport { createContext } from 'react';\nimport type {\n AccesslyEndpoints,\n AuthClient,\n AuthStatus,\n CognitoConfig,\n DeviceStore,\n Environment,\n SessionStorage,\n TokenManager,\n} from '@accesly/core';\n\nexport interface AcceslyContextValue {\n readonly appId: string;\n readonly env: Environment;\n readonly apiUrl: string;\n readonly cognitoConfig: CognitoConfig;\n readonly authClient: AuthClient;\n readonly sessionStorage: SessionStorage;\n readonly tokenManager: TokenManager;\n readonly endpoints: AccesslyEndpoints;\n readonly deviceStore: DeviceStore;\n /** Current auth status — re-rendered whenever it changes. */\n readonly status: AuthStatus;\n readonly username: string | null;\n /** Force a re-read of `tokenManager.getStatus()`. */\n readonly refreshStatus: () => Promise<void>;\n}\n\nexport const AcceslyContext = createContext<AcceslyContextValue | null>(null);\n","/**\n * Per-environment defaults — currently the only public stage is `dev`. The\n * others are placeholders so the SDK API doesn't change when `staging`/`prod`\n * come online (Fase 7+ / Fase 10).\n */\n\nimport type { CognitoConfig, Environment } from '@accesly/core';\n\nexport interface EnvironmentDefaults {\n readonly apiUrl: string;\n /**\n * Lambda Function URL del `wallet-stream` Lambda — Server-Sent Events\n * que multiplexa status + balance + activity en una sola conexión.\n * Si está vacío, los hooks `useBalance` / `useWalletActivity` /\n * `useWalletStatus` caen al polling fallback (mucho menos eficiente).\n */\n readonly walletStreamUrl: string;\n readonly cognito: CognitoConfig;\n readonly stellar: {\n readonly networkPassphrase: string;\n readonly horizonUrl: string;\n readonly sorobanRpcUrl: string;\n /**\n * Stellar G-address of the account that invokes `CreateContract` for new\n * Smart Accounts. Same account the backend Lambda uses, so the wallet\n * address computed client-side via `wallet.computeAddress` matches\n * exactly what the backend will (or did) deploy.\n */\n readonly deployerAddress: string;\n /**\n * Address del contrato `ed25519-verifier` desplegado en la red. Necesario\n * cuando el SDK construye la entrada `Signer::External(verifier, pubkey)`\n * dentro del `AuthPayload` que firma — el Smart Account compara con la\n * misma address que tiene almacenada en su context rule.\n */\n readonly ed25519VerifierAddress: string;\n };\n}\n\nexport const ENVIRONMENT_DEFAULTS: Record<Environment, EnvironmentDefaults> = {\n dev: {\n apiUrl: 'https://3fki7eiio5.execute-api.us-east-1.amazonaws.com/dev',\n walletStreamUrl: 'https://ajlmn37thw7fxen3oyykbfmlrm0eecue.lambda-url.us-east-1.on.aws/',\n cognito: {\n region: 'us-east-1',\n userPoolId: 'us-east-1_K2Nag1tB1',\n userPoolClientId: '6r64diep7pne50sender4557jt',\n },\n stellar: {\n networkPassphrase: 'Test SDF Network ; September 2015',\n horizonUrl: 'https://horizon-testnet.stellar.org',\n sorobanRpcUrl: 'https://soroban-testnet.stellar.org',\n // OZ Relayer channels-fund — see CloudServices-accesly/docs/Deployed_Resources_dev.md\n deployerAddress: 'GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E',\n // accesly-contracts Phase 1 deploy on Stellar testnet.\n ed25519VerifierAddress: 'CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5',\n },\n },\n staging: {\n apiUrl: 'https://api-staging.accesly.xyz',\n walletStreamUrl: '',\n cognito: {\n region: 'us-east-1',\n userPoolId: 'TBD-staging',\n userPoolClientId: 'TBD-staging',\n },\n stellar: {\n networkPassphrase: 'Test SDF Network ; September 2015',\n horizonUrl: 'https://horizon-testnet.stellar.org',\n sorobanRpcUrl: 'https://soroban-testnet.stellar.org',\n deployerAddress: 'GDRHSVLY3VCEHCHCSR5MZR2ALYLCERDDFT3ULCUIELGFVYHTZFCMNU4E',\n ed25519VerifierAddress: 'CALVIIGIOMODZMWTMKZLSD4PZFFEPWQBSYERHUFM6MH5FLWKCHW4E4G5',\n },\n },\n prod: {\n apiUrl: 'https://api.accesly.xyz',\n walletStreamUrl: '',\n cognito: {\n region: 'us-east-1',\n userPoolId: 'TBD-prod',\n userPoolClientId: 'TBD-prod',\n },\n stellar: {\n networkPassphrase: 'Public Global Stellar Network ; September 2015',\n horizonUrl: 'https://horizon.stellar.org',\n sorobanRpcUrl: 'https://soroban-rpc.mainnet.stellar.org',\n deployerAddress: 'TBD-prod',\n ed25519VerifierAddress: 'TBD-prod',\n },\n },\n};\n","/**\n * Recognises backend `POST /wallets` failures that are KNOWN to leave the\n * wallet record on the backend (Soroban submit rejected the deploy — typical\n * after Soroban protocol v26 lowered the resource caps).\n *\n * In these cases the SDK does NOT throw: `wallet.createWallet` returns\n * `status: 'pending-deploy'` with the client-side-predicted address so the\n * app can render normally and call `wallet.retryDeploy` later (or wait for\n * the contracts team to slim the constructor and let the backend's\n * auto-retry land it).\n *\n * Recognised patterns (case-insensitive substring match against the error\n * message and code):\n * - `txSorobanInvalid` — Soroban RPC rejected the envelope shape\n * - `Soroban sendTransaction` — generic submit rejection\n * - `soroban submit failed` — backend wrapper message\n * - `scecExceededLimit` / `exceededLimit` — protocol v26 cap exceeded\n */\n\nimport { AccesslyApiError } from '@accesly/core';\n\nexport function isSorobanDeployPendingError(err: unknown): boolean {\n if (!(err instanceof AccesslyApiError)) return false;\n const haystack = `${err.message ?? ''} ${err.code ?? ''}`.toLowerCase();\n return (\n haystack.includes('txsorobaninvalid') ||\n haystack.includes('soroban sendtransaction') ||\n haystack.includes('soroban submit failed') ||\n haystack.includes('scecexceededlimit') ||\n haystack.includes('exceededlimit')\n );\n}\n","/**\n * `useWalletHistory(walletAddress?, opts?)` — historial completo de la wallet\n * pre-decodificado desde Stellar Expert (indexer free, full retention).\n *\n * El backend de Accesly **proxea** las requests a Stellar Expert porque SE\n * bloquea CORS desde browsers (Cloudflare retorna 403 en cross-origin). El\n * proxy hace el call server-side, decodea topics + amounts, y devuelve items\n * tipados listos para renderizar.\n *\n * Features:\n * - Cache en `localStorage` per-wallet con TTL 12h → render instantáneo en\n * reloads + navegación.\n * - Polling cada 30s para nuevos events. Pausa si tab oculta.\n * - `BroadcastChannel` cross-tab para compartir fetches — solo UN tab hace\n * el request, los demás escuchan el resultado vía canal.\n * - Optimistic updates: el SDK inserta el item al instante cuando `tx.send`\n * confirma, sin esperar el indexing de SE (~30-60s típico).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { WalletHistoryItem } from '@accesly/core';\nimport { useAccesly } from './useAccesly.js';\nimport type { WalletActivityItem } from './walletSubscription.js';\n\nconst POLL_INTERVAL_MS = 30_000;\nconst CACHE_TTL_MS = 12 * 60 * 60 * 1000;\nconst CACHE_KEY_PREFIX = 'accesly:history:';\nconst BROADCAST_CHANNEL_PREFIX = 'accesly:history:';\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\ninterface Cursors {\n readonly smartAccount: string | null;\n readonly transfers: string | null;\n}\n\ninterface CacheEntry {\n readonly items: WalletHistoryItem[];\n readonly cursors: Cursors;\n readonly storedAt: number;\n}\n\nfunction loadCache(walletAddress: string): CacheEntry | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(CACHE_KEY_PREFIX + walletAddress);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as CacheEntry;\n if (Date.now() - parsed.storedAt > CACHE_TTL_MS) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction saveCache(walletAddress: string, entry: CacheEntry): void {\n if (typeof localStorage === 'undefined') return;\n try {\n localStorage.setItem(CACHE_KEY_PREFIX + walletAddress, JSON.stringify(entry));\n } catch {\n /* quota / disabled — no-op */\n }\n}\n\n/* ── Optimistic update store ─────────────────────────────────────────────── */\n\nconst optimisticItems = new Map<string, WalletHistoryItem[]>();\nconst optimisticListeners = new Map<string, Set<(items: WalletHistoryItem[]) => void>>();\n\n/**\n * Inyecta un item de history \"optimistically\" — útil cuando acabás de hacer\n * `tx.send` y querés que aparezca al instante sin esperar el indexing de SE.\n * El item queda hasta que el próximo fetch confirma que ya está en el feed.\n */\nexport function historyOptimisticPush(\n walletAddress: string,\n item: WalletHistoryItem | WalletActivityItem,\n): void {\n const current = optimisticItems.get(walletAddress) ?? [];\n optimisticItems.set(walletAddress, [item as WalletHistoryItem, ...current]);\n const listeners = optimisticListeners.get(walletAddress);\n if (listeners) {\n for (const fn of listeners) fn(optimisticItems.get(walletAddress) ?? []);\n }\n}\n\nexport function historyClearOptimistic(walletAddress: string): void {\n optimisticItems.delete(walletAddress);\n const listeners = optimisticListeners.get(walletAddress);\n if (listeners) {\n for (const fn of listeners) fn([]);\n }\n}\n\nfunction subscribeOptimistic(\n walletAddress: string,\n listener: (items: WalletHistoryItem[]) => void,\n): () => void {\n let set = optimisticListeners.get(walletAddress);\n if (!set) {\n set = new Set();\n optimisticListeners.set(walletAddress, set);\n }\n set.add(listener);\n return () => {\n set?.delete(listener);\n if (set && set.size === 0) optimisticListeners.delete(walletAddress);\n };\n}\n\n/* ── Hook ─────────────────────────────────────────────────────────────────── */\n\nexport interface UseWalletHistoryOptions {\n /** Intervalo de poll para nuevos events (ms). Default 30s, 0 desactiva. */\n readonly pollIntervalMs?: number;\n /**\n * Cuántos transfers del XLM_SAC scan-ear por fetch. Default 50, max 500\n * (5 paginated calls). En testnet hay millones de transfers globalmente; si\n * tu wallet tiene pocos transfers, sube este número para encontrarlos.\n */\n readonly transferScanLimit?: number;\n}\n\nexport interface UseWalletHistoryResult {\n readonly events: readonly WalletHistoryItem[];\n readonly isLoading: boolean;\n readonly error: Error | null;\n readonly hasMore: boolean;\n loadMore(): Promise<void>;\n refresh(): Promise<void>;\n}\n\nexport function useWalletHistory(\n walletAddress?: string | null,\n opts: UseWalletHistoryOptions = {},\n): UseWalletHistoryResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n\n const [resolvedAddress, setResolvedAddress] = useState<string | null>(walletAddress ?? null);\n const [events, setEvents] = useState<WalletHistoryItem[]>([]);\n const [optimistic, setOptimistic] = useState<WalletHistoryItem[]>([]);\n const [cursors, setCursors] = useState<Cursors>({ smartAccount: null, transfers: null });\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [hasMore, setHasMore] = useState(true);\n\n // Resolver address.\n const walletRef = useStableRef(wallet);\n useEffect(() => {\n if (walletAddress) {\n setResolvedAddress(walletAddress);\n return;\n }\n if (!username) {\n setResolvedAddress(null);\n return;\n }\n let cancelled = false;\n void (async () => {\n try {\n const stored = await walletRef.current.getStoredCredential(username);\n if (cancelled) return;\n setResolvedAddress(stored?.walletAddress ?? null);\n } catch {\n if (!cancelled) setResolvedAddress(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [walletAddress, username, walletRef]);\n\n // Optimistic items.\n useEffect(() => {\n if (!resolvedAddress) return undefined;\n setOptimistic(optimisticItems.get(resolvedAddress) ?? []);\n return subscribeOptimistic(resolvedAddress, setOptimistic);\n }, [resolvedAddress]);\n\n // Cache + primer fetch.\n const endpointsRef = useStableRef(_internal.endpoints);\n // Default 1500 events scan (= 30 pages * 50). El XLM_SAC del testnet tiene\n // mucha actividad global, hay que scan-ear varios cientos para encontrar\n // transfers del wallet específico. Cap por Lambda budget ≈ 30s.\n const transferScanLimit = opts.transferScanLimit ?? 1500;\n\n useEffect(() => {\n if (!resolvedAddress) {\n setIsLoading(false);\n return undefined;\n }\n\n // Replay cache.\n const cached = loadCache(resolvedAddress);\n if (cached) {\n setEvents(cached.items);\n setCursors(cached.cursors);\n setIsLoading(false);\n }\n\n let cancelled = false;\n const channel =\n typeof BroadcastChannel !== 'undefined'\n ? new BroadcastChannel(BROADCAST_CHANNEL_PREFIX + resolvedAddress)\n : null;\n\n if (channel) {\n channel.onmessage = (ev) => {\n const data = ev.data as CacheEntry | undefined;\n if (data && !cancelled) {\n setEvents(data.items);\n setCursors(data.cursors);\n setIsLoading(false);\n }\n };\n }\n\n void (async () => {\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n transferScanLimit,\n });\n if (cancelled) return;\n const deduped = dedupItems(result.events as WalletHistoryItem[]);\n setEvents(deduped);\n setCursors(result.cursors);\n setIsLoading(false);\n setError(null);\n setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);\n\n const entry: CacheEntry = {\n items: deduped,\n cursors: result.cursors,\n storedAt: Date.now(),\n };\n saveCache(resolvedAddress, entry);\n channel?.postMessage(entry);\n } catch (err) {\n if (!cancelled) {\n setError(err as Error);\n setIsLoading(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n channel?.close();\n };\n }, [resolvedAddress, transferScanLimit, endpointsRef]);\n\n // Polling.\n const interval = opts.pollIntervalMs ?? POLL_INTERVAL_MS;\n useEffect(() => {\n if (!resolvedAddress || interval === 0) return undefined;\n\n const tick = async () => {\n if (typeof document !== 'undefined' && document.hidden) return;\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n transferScanLimit,\n });\n setEvents((prev) => mergeAndDedup(prev, result.events as WalletHistoryItem[]));\n // Limpiar optimistics ya confirmados.\n const realTxHashes = new Set(result.events.map((it) => it.eventToid));\n const current = optimisticItems.get(resolvedAddress) ?? [];\n const remaining = current.filter((it) => !realTxHashes.has(it.eventToid));\n if (remaining.length !== current.length) {\n optimisticItems.set(resolvedAddress, remaining);\n const listeners = optimisticListeners.get(resolvedAddress);\n if (listeners) for (const fn of listeners) fn(remaining);\n }\n } catch {\n /* silenciar errores del polling */\n }\n };\n\n const id = setInterval(tick, interval);\n return () => clearInterval(id);\n }, [resolvedAddress, interval, transferScanLimit, endpointsRef]);\n\n const loadMoreImpl = useCallback(async () => {\n if (!resolvedAddress) return;\n if (!cursors.smartAccount && !cursors.transfers) {\n setHasMore(false);\n return;\n }\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n ...(cursors.smartAccount ? { smartAccountCursor: cursors.smartAccount } : {}),\n ...(cursors.transfers ? { transfersCursor: cursors.transfers } : {}),\n transferScanLimit,\n });\n setEvents((prev) => mergeAndDedup(prev, result.events as WalletHistoryItem[]));\n setCursors(result.cursors);\n setHasMore(result.cursors.smartAccount !== null || result.cursors.transfers !== null);\n } catch (err) {\n setError(err as Error);\n }\n }, [resolvedAddress, cursors, transferScanLimit, endpointsRef]);\n\n const refreshImpl = useCallback(async () => {\n if (!resolvedAddress) return;\n setIsLoading(true);\n try {\n const result = await endpointsRef.current.walletHistory(resolvedAddress, {\n transferScanLimit,\n });\n const deduped = dedupItems(result.events as WalletHistoryItem[]);\n setEvents(deduped);\n setCursors(result.cursors);\n setError(null);\n saveCache(resolvedAddress, {\n items: deduped,\n cursors: result.cursors,\n storedAt: Date.now(),\n });\n } catch (err) {\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [resolvedAddress, transferScanLimit, endpointsRef]);\n\n // Combinar optimistic items con events reales.\n const combined = [...optimistic, ...events];\n\n return {\n events: combined,\n isLoading,\n error,\n hasMore,\n loadMore: loadMoreImpl,\n refresh: refreshImpl,\n };\n}\n\n/* ── Helpers ──────────────────────────────────────────────────────────────── */\n\nfunction dedupItems(items: WalletHistoryItem[]): WalletHistoryItem[] {\n const seen = new Set<string>();\n const out: WalletHistoryItem[] = [];\n for (const item of items) {\n const key = `${item.type}:${item.eventToid}:${item.ledger}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(item);\n }\n out.sort((a, b) => b.ledger - a.ledger);\n return out;\n}\n\nfunction mergeAndDedup(\n prev: readonly WalletHistoryItem[],\n fresh: readonly WalletHistoryItem[],\n): WalletHistoryItem[] {\n return dedupItems([...fresh, ...prev]);\n}\n","/**\n * `useAccesly()` — single hook with namespaces:\n * - auth — signUp / confirmSignUp / signIn / signOut / status\n * - wallet — createWallet, getStoredWallet\n * - tx — sendPayment, signRawXdr\n * - kyc — start, status\n *\n * The hook returns stable references when the underlying SDK instances don't\n * change. Each namespace is built lazily (memoised) so apps that only use\n * `auth` don't bring `wallet` into their render.\n */\n\nimport { useContext, useMemo } from 'react';\nimport {\n computeSmartAccountAddress,\n createWallet as coreCreateWallet,\n decryptAesGcm,\n deriveRecoveryKey,\n emailHashBytes,\n encryptAesGcm,\n generateRecoverySalt,\n generateX25519Keypair,\n getRandomBytes,\n hkdfSha256,\n normalizeSecp256r1Pubkey,\n reconstructFromPlainAndEncrypted,\n reconstructKey,\n registerPasskey,\n sha256,\n signSorobanAuthEntry,\n signTransaction as coreSignTransaction,\n unlockPasskey,\n unwrapSessionFragment2,\n zeroize,\n type AuthStatus,\n type CredentialRecord,\n type EncryptedEnvelope,\n} from '@accesly/core';\nimport { AcceslyContext, type AcceslyContextValue } from '../context.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\n\n// Recovery (ZK email) se removió en 1.0.0-pre.0 (2026-06-15). El nuevo modelo\n// OTP-email + password de Cognito se introduce en 1.0.0 como un namespace\n// `recovery` en este mismo hook. Ver docs/Plan_Final_v1.md §5.\n\nexport interface AuthNamespace {\n readonly status: AuthStatus;\n readonly username: string | null;\n signUp(email: string, password: string): Promise<{ userSub: string; userConfirmed: boolean }>;\n confirmSignUp(email: string, code: string): Promise<void>;\n resendConfirmation(email: string): Promise<void>;\n signIn(email: string, password: string): Promise<void>;\n signOut(): Promise<void>;\n}\n\nexport interface CreateWalletInput {\n readonly email: string;\n readonly emailSalt: Uint8Array;\n readonly encryptionKeys: readonly [Uint8Array, Uint8Array, Uint8Array];\n readonly secp256r1Pubkey: Uint8Array;\n /**\n * Optional. When provided together with `prfSalt`, the SDK persists a\n * `CredentialRecord` to the configured `DeviceStore` BEFORE calling\n * `POST /wallets`. That way, if the network request fails (timeout, tab\n * close, etc.) the encrypted F1 shard + passkey metadata survive locally\n * and the wallet can be recovered via `wallet.ensureWallet` on the next\n * session (the backend dedupes by Cognito user → returns the same\n * walletAddress).\n *\n * Pass it. Omitting it means an orphaned wallet on POST failure is\n * unrecoverable without a server-side query.\n */\n readonly credentialId?: Uint8Array;\n /** Optional. See `credentialId`. */\n readonly prfSalt?: Uint8Array;\n /**\n * Password de Cognito en plano (`Uint8Array` codificado UTF-8).\n *\n * Recovery v2 (Fase 1, 2026-06-15): si se provee, el SDK deriva\n * `recoveryKey = PBKDF2(password, recoverySalt, 600k)` y la usa para\n * cifrar F3 antes de enviarlo al backend, en vez de usar\n * `encryptionKeys[2]`. El backend almacena F3 cifrado con esa key —\n * SOLO descifrable client-side con el mismo password.\n *\n * Sin esta prop el wallet se crea pero NO podrá recuperarse vía OTP\n * (F3 quedará cifrado con `encryptionKeys[2]`, igual que en 0.x).\n *\n * El caller es responsable de zeroizar este buffer tras `createWallet`\n * (el SDK no lo retiene en memoria).\n */\n readonly cognitoPassword?: Uint8Array;\n /**\n * 32-byte salt para HKDF — si se persiste en el `CredentialRecord`,\n * `wallet.unlockForSigning` lo recupera y re-deriva las mismas keys sin\n * intervención del caller. Si se omite, el SDK genera uno random y lo\n * persiste igualmente. Si la wallet ya existe en el `DeviceStore` con un\n * `encryptionSalt`, este input se ignora a favor del salt persistido (para\n * preservar la decriptabilidad de F1).\n */\n readonly encryptionSalt?: Uint8Array;\n}\n\nexport interface CreatedWalletInfo {\n readonly walletAddress: string;\n readonly publicKey: Uint8Array;\n /**\n * `'on-chain'` if the backend confirmed deploy; `'pending-deploy'` if the\n * backend submitted to Soroban but the contract did not land (typically\n * because the Smart Account constructor exceeds Soroban v26 resource caps\n * — Phase 1 territory). When pending, the `walletAddress` is the\n * client-side-predicted address: same address that will be live once the\n * deploy succeeds (idempotent on the backend).\n */\n readonly status: WalletStatus;\n /** When `status === 'pending-deploy'`, the backend's reason if available. */\n readonly pendingReason?: string;\n}\n\nimport { isSorobanDeployPendingError } from './sorobanDeployStatus.js';\nexport { isSorobanDeployPendingError } from './sorobanDeployStatus.js';\n\nexport type WalletStatus =\n /** Backend confirmed the contract is live on Soroban. Ready to use. */\n | 'on-chain'\n /**\n * Wallet record exists (locally and/or on backend) but the contract has NOT\n * been observed on Soroban yet. Either deploy is still in flight, or\n * landed in a ghost state. Re-run `wallet.ensureWallet` later (or call\n * `wallet.retryDeploy(username)`).\n */\n | 'pending-deploy'\n /**\n * Backend has the record but its Soroban RPC check did not respond — the\n * SDK treats the address as usable but flags the uncertainty.\n */\n | 'unknown';\n\nexport interface EnsureWalletResult {\n readonly walletAddress: string;\n readonly status: WalletStatus;\n /** True if this call generated a new keypair (first-time deploy path). */\n readonly createdNow: boolean;\n /** Present only when `createdNow === true`. */\n readonly publicKey?: Uint8Array;\n}\n\nexport interface RemoteWalletInfo {\n readonly walletAddress: string;\n readonly appId: string;\n readonly createdAt: string;\n readonly onChain: boolean | null;\n}\n\nexport interface RetryDeployResult {\n readonly walletAddress: string;\n readonly status: WalletStatus;\n}\n\n/**\n * Input para `wallet.bootstrap(...)` — el high-level \"todo en uno\" que cualquier\n * integrador típico va a llamar como entry point. Hace **TODO**:\n *\n * 1. `sha256(email)` → userId opaco para el RP.\n * 2. Genera `prfSalt` aleatorio (32 bytes).\n * 3. `registerPasskey(...)` con extensión PRF — pide huella/face/Hello.\n * 4. Genera `encryptionSalt` aleatorio (32 bytes).\n * 5. HKDF(prfOutput, encryptionSalt, \"accesly-{f1,f2,f3}-encryption\") → 3 keys AES.\n * 6. Genera `emailSalt` aleatorio (32 bytes).\n * 7. `wallet.ensureWallet(...)` — el flujo idempotente get-or-create.\n * 8. Persiste `encryptionSalt` en `CredentialRecord` para que `unlockForSigning`\n * pueda re-derivar las mismas keys.\n * 9. Zeroiza `prfOutput`, `f1Key`, `f2Key`, `f3Key`, `cognitoPasswordBytes`.\n *\n * Después de `bootstrap`, llamá `tx.send(...)` directamente con\n * `wallet.unlockForSigning(email)` — no hace falta más wiring.\n */\nexport interface BootstrapWalletInput {\n readonly email: string;\n /**\n * Password de Cognito en plano. Usado para:\n * - Re-cifrar F3 (y F2_recovery) con `recoveryKey = PBKDF2(password,\n * recoverySalt, 600k)` para el flujo de Recovery v2.\n *\n * El SDK lo zeroiza tras el ensureWallet.\n */\n readonly password: string;\n /**\n * Overrides opcionales para el `registerPasskey` interno. Caso típico:\n * cambiar `rpName: 'MiApp'` para que el browser muestre tu marca en el\n * prompt biométrico. `rpId` por default = `window.location.hostname`.\n */\n readonly passkey?: {\n readonly rpId?: string;\n readonly rpName?: string;\n };\n}\n\n/**\n * Material reconstruido por `wallet.unlockForSigning(...)` y listo para pasar\n * a `tx.send(...)`. Las llaves se zeroizan tras la firma; el caller no debería\n * retenerlas más allá del round-trip.\n */\nexport interface UnlockedSigningMaterial {\n /** F1 share desencriptado (Shamir-encoded blob). Lo zero-iza `tx.send`. */\n readonly fragmentF1Plain: Uint8Array;\n /** AES key con la que el SDK desencripta el envelope F2 del backend. */\n readonly fragmentF2Key: Uint8Array;\n /** Pubkey ed25519 del owner del Smart Account (32 bytes). */\n readonly ownerPubkey: Uint8Array;\n /** Address C… del Smart Account (display only). */\n readonly walletAddress: string;\n}\n\nexport interface WalletNamespace {\n /**\n * **Entry-point recomendado.** Registra passkey + deriva keys + crea-o-recupera\n * wallet en una sola llamada. Sustituye al patrón histórico de\n * `ensureWalletWithPasskey` que tenía que copiar-pegar cada integrador.\n *\n * Idempotente: si ya hay wallet en el backend para este Cognito user, devuelve\n * `{createdNow: false}` sin re-registrar passkey. Si no, hace el flow completo.\n */\n bootstrap(input: BootstrapWalletInput): Promise<EnsureWalletResult>;\n /**\n * **Helper para `tx.send`.** Lee la credencial del DeviceStore, abre el\n * passkey via WebAuthn (PIN/biométrico), re-deriva las AES keys con HKDF, y\n * descifra F1 local. Devuelve los 3 materiales que `tx.send` necesita.\n *\n * Lanza con mensaje claro si:\n * - no hay credential local (el user tiene que correr `recovery.finalize`\n * en este device);\n * - el passkey no devolvió PRF (browser sin soporte);\n * - el envelope F1 falla al descifrar (corrupto / passkey distinto).\n */\n unlockForSigning(username: string): Promise<UnlockedSigningMaterial>;\n /**\n * End-to-end wallet creation:\n * 1. Generate keypair + Shamir split + encrypt fragments (client-side).\n * 2. Compute the Smart Account address client-side from the ed25519\n * pubkey + the env-configured deployer (deterministic — matches what\n * the backend will deploy).\n * 3. If `credentialId` + `prfSalt` were provided, persist a full\n * `CredentialRecord` (with all 3 encrypted fragments + computed\n * walletAddress + `onChain: null`) to the `DeviceStore` BEFORE the\n * network call — crash-safety + retry capability in one step.\n * 4. POST /wallets with hex pubkeys + base64 fragments.\n * 5. On success, mark the record `onChain: true` (cleared by the next\n * `ensureWallet` call which queries Soroban via the backend).\n *\n * The caller is responsible for the encryption-key derivation (typically\n * via WebAuthn PRF).\n */\n createWallet(input: CreateWalletInput): Promise<CreatedWalletInfo>;\n /**\n * Idempotent wallet bootstrap. The recommended entry-point at the top of\n * every authenticated session:\n *\n * - `GET /wallets` → if `onChain === true`, returns `{ status: 'on-chain' }`\n * and skips keypair generation entirely.\n * - `GET /wallets` → if `onChain === false`, calls `retryDeploy` to\n * re-submit the existing record (idempotent on the backend) and\n * returns `{ status: 'pending-deploy' }` if the retry didn't surface\n * success yet.\n * - `GET /wallets` → if `onChain === null` (Soroban RPC unreachable),\n * returns `{ status: 'unknown' }` — the address is usable but the\n * SDK couldn't confirm on-chain presence.\n * - `GET /wallets` → 404 → runs the full `createWallet` flow and returns\n * `{ status: 'pending-deploy', createdNow: true }`. Subsequent calls\n * will upgrade to `'on-chain'` once the backend's Soroban check passes.\n */\n ensureWallet(input: CreateWalletInput): Promise<EnsureWalletResult>;\n /**\n * Re-submits `POST /wallets` for an existing local `CredentialRecord`. Used\n * to recover from ghost wallets (record exists but deploy did not land).\n * Requires the record to have been persisted with `fragmentF2Encrypted`,\n * `fragmentF3Encrypted`, `publicKey`, and `emailCommitment` (which\n * `createWallet` does automatically when `credentialId` + `prfSalt` are\n * provided).\n *\n * Backend dedupes by ownerPubkey — the returned address is guaranteed to\n * equal the one originally stored.\n */\n retryDeploy(username: string): Promise<RetryDeployResult>;\n /**\n * Reads the user's wallet metadata from the backend. Returns null if the\n * user has not yet created a wallet.\n */\n fetchRemote(): Promise<RemoteWalletInfo | null>;\n /**\n * Computes the deterministic Smart Account address that the backend will\n * (or did) deploy for the given ed25519 owner pubkey. Same algorithm\n * Stellar Core uses — pure client-side, no network call. Useful to show\n * the address to the user instantly before any POST.\n */\n computeAddress(ownerPubkey: Uint8Array): Promise<string>;\n /** Returns the locally-stored credential record, if any. */\n getStoredCredential(username: string): Promise<CredentialRecord | null>;\n /**\n * Lists `CredentialRecord`s whose `walletAddress` is still `null` OR whose\n * `onChain` flag is `false`. Diagnostic + recovery aid.\n */\n getPendingWallets(): Promise<readonly CredentialRecord[]>;\n /** Removes a stored credential. Useful after a failed pending wallet is reconciled. */\n clearStoredCredential(username: string): Promise<void>;\n /**\n * Testnet only — fondea el Smart Account con XLM via Stellar friendbot.\n *\n * Friendbot acepta directamente direcciones de contrato Soroban (`C…`):\n * internamente arma una tx `invokeContract(XLM_SAC.transfer, ...)` desde\n * la cuenta de la SDF y la submitea. Resultado: ~10,000 XLM testnet al\n * Smart Account, sin necesidad de un G-account intermediario.\n *\n * Idempotente: el primer call exitoso marca `testnetFunded: true` en el\n * `CredentialRecord` local; subsiguientes calls devuelven `alreadyFunded:\n * true` sin hacer otro round-trip a friendbot.\n *\n * En `env: 'mainnet'` la función es un no-op (no existe friendbot en\n * mainnet) y devuelve `{ funded: false, alreadyFunded: false, reason:\n * 'mainnet-not-supported' }`. La UI tiene que mostrar opciones de onramp\n * real (Etherfuse, MoonPay, transferencia externa).\n *\n * `ensureWallet` lo llama automáticamente fire-and-forget cuando el\n * status final es `'on-chain'` — el caller solo necesita llamarlo\n * explícitamente si quiere mostrar feedback en la UI durante el funding.\n */\n fundTestnet(walletAddress: string): Promise<FundTestnetResult>;\n}\n\nexport interface FundTestnetResult {\n /** `true` si esta llamada disparó friendbot y fondeó la wallet ahora. */\n readonly funded: boolean;\n /**\n * `true` si la wallet ya había sido fondeada antes (flag local o response\n * de friendbot indicando que la cuenta ya existe). Igualmente válido —\n * la UI puede mostrar \"ya tienes XLM\" sin pedir acción del user.\n */\n readonly alreadyFunded: boolean;\n /** Texto explicativo para no-op cases (mainnet, missing record, etc.). */\n readonly reason?: 'mainnet-not-supported' | 'friendbot-error' | 'already-funded' | 'funded-now';\n}\n\n/**\n * Input para `tx.send(...)` — manda XLM desde el Smart Account del usuario a\n * cualquier address Stellar (G… clásico o C… contrato).\n *\n * El SDK orquesta todo el flujo: simulate → ECDH F2 → reconstruct seed →\n * sign auth entry → submit. El caller solo entrega los inputs sensibles que\n * vienen de su flow de unlock (WebAuthn PRF + derivación de F2 key).\n */\nexport interface SendXlmInput {\n /** Destinatario. G… (clásico) o C… (contrato). */\n readonly destinationAddress: string;\n /** Monto en STROOPS (1 XLM = 10_000_000 stroops). Base-10 string para evitar precisión. */\n readonly amountStroops: string;\n /**\n * F1 (Shamir share encoded incluyendo el byte de índice) ya en plano —\n * típicamente desencriptado client-side via WebAuthn PRF antes de llamar.\n * El SDK lo zero-iza tras combinar con F2.\n */\n readonly fragmentF1Plain: Uint8Array;\n /**\n * Llave AES-256 con la que el SDK desencripta el F2 envelope que vino\n * del backend. La derivación de esta llave es responsabilidad del caller\n * (usualmente PBKDF2 sobre material derivado de credenciales del user).\n * Se zero-iza al terminar.\n */\n readonly fragmentF2Key: Uint8Array;\n /**\n * Pubkey ed25519 (32 bytes) del owner del Smart Account. Se usa para:\n * 1) Sanity-check de que la seed reconstruida deriva esta pubkey.\n * 2) Empaquetarla dentro del `Signer::External(verifier, pubkey)` del\n * AuthPayload.\n */\n readonly ownerPubkey: Uint8Array;\n}\n\nexport interface SendXlmResult {\n readonly txHash: string;\n readonly status: string;\n readonly explorerUrl: string;\n}\n\nexport interface TxNamespace {\n /**\n * End-to-end XLM transfer desde el Smart Account del user.\n *\n * Flujo interno (no-custodial):\n * 1) `POST /tx/simulate` con `{ amountStroops, destinationAddress }`.\n * 2) Genera X25519 keypair efímero + `POST /fragments/2` con la pubkey.\n * Backend devuelve F2 wrapped en una capa session-key. El SDK la\n * descifra con ECDH + HKDF — la session key NO persiste en disco.\n * 3) Desencripta el F2 envelope interno con `fragmentF2Key` → F2 plain.\n * 4) Combina F1 + F2 vía Shamir → ed25519 seed (32 bytes).\n * 5) Computa `auth_digest = sha256(signature_payload || rule_ids_xdr)`\n * y lo firma con la seed → 64-byte ed25519 sig.\n * 6) Empaqueta el `AuthPayload {signers, context_rule_ids}` ScVal,\n * reemplaza `credentials.address.signature` en la placeholder entry.\n * 7) `POST /tx/submit` con `{ unsignedXdr, signedAuthEntryXdr }`.\n * 8) Devuelve `{ txHash, status, explorerUrl }`.\n *\n * Toda llave plana sale de scope tras la firma. Lanza si:\n * - El backend rechaza simulate/submit.\n * - La reconstrucción Shamir falla (fragmentos no compatibles).\n * - La pubkey derivada de la seed no matchea `ownerPubkey`.\n */\n send(input: SendXlmInput): Promise<SendXlmResult>;\n\n /**\n * Bajo nivel: firma un envelope Stellar ya construido con una seed ed25519\n * dada. Útil para flows custom que arman la tx fuera del SDK.\n */\n signRawXdr(input: {\n transactionXdr: string;\n ed25519Seed: Uint8Array;\n expectedPublicKey?: Uint8Array;\n }): Promise<{ signedXdr: string; publicKey: Uint8Array }>;\n}\n\nexport interface KycNamespace {\n start(): Promise<{ customerId: string; status: string; hostedUrl: string | null }>;\n status(): Promise<{ customerId: string; status: string; hostedUrl: string | null }>;\n}\n\nexport interface SessionNamespace {\n /** Create a temporary session key for unattended low-value tx (Soroban policy). */\n create(_opts: { readonly ttlSeconds: number; readonly maxAmountStroops: string }): Promise<never>;\n /** Revoke a previously-created session key. */\n revoke(_sessionKeyId: string): Promise<never>;\n}\n\nexport interface SettingsNamespace {\n /** Add a new device's passkey to an existing wallet (multi-device). */\n addDevice(_secp256r1Pubkey: Uint8Array): Promise<never>;\n /** Remove a device's passkey from the wallet. */\n removeDevice(_secp256r1Pubkey: Uint8Array): Promise<never>;\n /** List all device passkeys registered for the wallet. */\n listDevices(): Promise<never>;\n /** Change the spending limit policy. */\n updateSpendingLimit(_opts: {\n readonly limitStroops: string;\n readonly perDayStroops?: string;\n }): Promise<never>;\n}\n\nexport interface YieldNamespace {\n /** Invest USDC into CETES via Etherfuse (50/50 yield share with Accesly). */\n invest(_amountUsdc: string): Promise<never>;\n /** Redeem CETES tokens back into USDC. */\n redeem(_amountTokens: string): Promise<never>;\n /** Read the user's current yield position. */\n position(): Promise<never>;\n}\n\n/**\n * Stub thrown by every method in the `session`, `settings`, `yield`\n * namespaces. These features are designed but not implemented in v0.1.0 —\n * they unblock with the dashboard work in Fase 7 (`session`/`settings`) and\n * with Etherfuse activation (`yield`).\n */\nexport class NotImplementedYetError extends Error {\n constructor(namespace: string, method: string) {\n super(\n `${namespace}.${method}() is not implemented yet. This namespace ships in a later release; ` +\n 'see docs/Handoff_Fase7.md for the roadmap.',\n );\n this.name = 'NotImplementedYetError';\n }\n}\n\n/**\n * Recovery v2 — OTP por email + password de Cognito (Fase 1, 2026-06-15).\n *\n * Flujo desde la UI:\n * 1. `recovery.requestOtp({ email })` → manda el OTP por SES.\n * 2. `recovery.verifyOtp({ email, code })` → devuelve `recoveryJwt`.\n * 3. `recovery.finalize({ email, password, recoveryJwt })` orquesta todo:\n * - GET /fragments/3 con el JWT\n * - Deriva recoveryKey con el password + recoverySalt del backend\n * - Decifra F3\n * - Decifra F2 (vía session key ECDH)\n * - Combina F2+F3 → seed ed25519 reconstruida\n * - Genera new passkey + new Shamir split (F1', F2', F3')\n * - Re-cifra F3' con la misma recoveryKey + nuevo salt\n * - Firma la tx `rotate_signer` localmente\n * - POST /recovery/finalize con todo\n * - Persiste new CredentialRecord local\n * - Zero-iza la seed\n */\nexport interface ReconstructedSeed {\n /** 32-byte ed25519 seed reconstruida vía Shamir(F2_recovery + F3). CALLER ZEROIZE. */\n readonly privateSeed: Uint8Array;\n /** 32-byte ed25519 public key derivada. */\n readonly publicKey: Uint8Array;\n /** 32-byte recoveryKey derivada del password — útil para re-cifrar F2'/F3' nuevos. */\n readonly recoveryKey: Uint8Array;\n /** Base64 32-byte salt que vino del backend. */\n readonly recoverySalt: string;\n}\n\n/**\n * Input para `recovery.finalize(...)` — **orquestador end-to-end**. El integrador\n * solo provee email + password + recoveryJwt; el SDK hace TODO el resto:\n *\n * 1. `reconstructSeed(...)` con el password → seed VIEJA + recoveryKey.\n * 2. `registerPasskey(...)` con PRF → nuevo credentialId + secp256r1Pubkey + prfOutput.\n * 3. HKDF(prfOutput, encryptionSalt, \"accesly-{f1,f2}-encryption\") → newF1Key + newF2Key.\n * 4. Genera new ed25519 seed + Shamir 2-of-3 + cifra F1'/F2' con PRF keys, F3' con recoveryKey.\n * 5. `POST /recovery/simulate-rotate-signer` → backend arma + simula.\n * 6. Firma `SorobanAuthorizationEntry` con la SEED VIEJA contra `admin-cfg`.\n * 7. `POST /recovery/finalize` con auth entry firmada + new fragments.\n * 8. Persiste new `CredentialRecord` (con `encryptionSalt`) en `DeviceStore`.\n * 9. Zeroiza TODAS las llaves intermedias (privateSeed vieja, recoveryKey, PRF output, password).\n */\nexport interface FinalizeRecoveryInput {\n /** Email del usuario (case-insensitive, se normaliza). */\n readonly email: string;\n /**\n * Password de Cognito (string). El SDK lo encoda a UTF-8 internamente y lo\n * zeroiza tras la operación. No retengas referencias.\n */\n readonly password: string;\n /** Token KMS-HMAC que devolvió `verifyOtp()` — TTL 5min. */\n readonly recoveryJwt: string;\n /**\n * Overrides opcionales para el `registerPasskey` interno (mismo shape que\n * `wallet.bootstrap`). Caso típico: `rpName: 'MiApp'`.\n */\n readonly passkey?: {\n readonly rpId?: string;\n readonly rpName?: string;\n };\n}\n\nexport interface FinalizeRecoveryResult {\n readonly walletAddress: string;\n readonly txHash: string;\n readonly status: string;\n /** Pubkey ed25519 NUEVA (32 bytes). Útil para UI confirmación. */\n readonly newPublicKey: Uint8Array;\n /** Link al explorer. */\n readonly explorerUrl: string;\n}\n\nexport interface RecoveryNamespace {\n /** Pide OTP. Backend rate-limita; el caller debe respetar `cooldownSeconds`. */\n requestOtp(input: { email: string }): Promise<{\n cooldownSeconds: number;\n expiresInSeconds: number;\n }>;\n /** Verifica OTP. Devuelve `recoveryJwt` con TTL 5min. */\n verifyOtp(input: { email: string; code: string }): Promise<{\n recoveryJwt: string;\n expiresAt: number;\n }>;\n /**\n * Descarga `/fragments/3`, descifra F2_recovery + F3 con la `recoveryKey`\n * derivada del password y reconstruye la seed via Shamir.\n *\n * El caller DEBE zero-izar `result.privateSeed` y `result.recoveryKey`\n * tras firmar la rotación + cifrar las nuevas F1'/F2'/F3'.\n *\n * El caller también es responsable de zeroizar `cognitoPassword` después.\n */\n reconstructSeed(input: {\n cognitoPassword: Uint8Array;\n recoveryJwt: string;\n }): Promise<ReconstructedSeed>;\n /**\n * Orquestador completo de la rotación de signers para Recovery v2.\n * Ver `FinalizeRecoveryInput` para los pre-requisitos.\n */\n finalize(input: FinalizeRecoveryInput): Promise<FinalizeRecoveryResult>;\n /**\n * Bajo nivel: submitea la rotación al backend tras que el caller haya\n * armado el body manualmente. `finalize(...)` es el wrapper recomendado.\n */\n submitFinalize(input: {\n recoveryJwt: string;\n unsignedXdr: string;\n signedAuthEntryXdr: string;\n newOwnerEd25519Pubkey: string;\n newSecp256r1Pubkey: string;\n newFragmentF1Encrypted: EncryptedEnvelope;\n newFragmentF2Encrypted: EncryptedEnvelope;\n newFragmentF2Recovery: EncryptedEnvelope;\n newFragmentF3Encrypted: EncryptedEnvelope;\n newRecoverySalt: string;\n newEmailCommitment: string;\n }): Promise<{ walletAddress: string; txHash: string; status: string }>;\n}\n\nexport interface AcceslyHook {\n readonly auth: AuthNamespace;\n readonly wallet: WalletNamespace;\n readonly tx: TxNamespace;\n readonly kyc: KycNamespace;\n readonly recovery: RecoveryNamespace;\n readonly session: SessionNamespace;\n readonly settings: SettingsNamespace;\n readonly yieldOps: YieldNamespace;\n /** Raw context, for advanced use cases (custom telemetry, manual refresh). */\n readonly _internal: AcceslyContextValue;\n}\n\nexport function useAccesly(): AcceslyHook {\n const ctx = useContext(AcceslyContext);\n if (!ctx) {\n throw new Error(\n 'useAccesly: missing <AcceslyProvider>. Wrap your app with <AcceslyProvider appId env>.',\n );\n }\n\n const auth = useMemo<AuthNamespace>(\n () => ({\n status: ctx.status,\n username: ctx.username,\n async signUp(email, password) {\n return ctx.authClient.signUp(email, password);\n },\n confirmSignUp(email, code) {\n return ctx.authClient.confirmSignUp(email, code);\n },\n resendConfirmation(email) {\n return ctx.authClient.resendConfirmationCode(email);\n },\n async signIn(email, password) {\n const tokens = await ctx.authClient.signIn(email, password);\n await ctx.tokenManager.setTokens(tokens);\n await ctx.refreshStatus();\n },\n async signOut() {\n await ctx.tokenManager.signOut();\n await ctx.refreshStatus();\n },\n }),\n [ctx],\n );\n\n const { hexToBytes, hexFromBytes } = useMemo(() => coderHelpers(), []);\n\n const stellarConfig = ENVIRONMENT_DEFAULTS[ctx.env].stellar;\n\n const wallet = useMemo<WalletNamespace>(() => {\n // Capture the narrowed non-null context once, so the inner closures\n // don't trip TS's narrowing-through-function-declaration limitation.\n const c = ctx;\n\n /**\n * Sends the POST /wallets request given a fully-assembled record. Used\n * by both the first-time create flow and `retryDeploy`. Returns the\n * backend-confirmed walletAddress.\n */\n const postWallet = async (params: {\n pubkeyEd25519: Uint8Array;\n emailCommitment: Uint8Array;\n secp256r1Pubkey: Uint8Array;\n fragmentF2: EncryptedEnvelope;\n fragmentF3: EncryptedEnvelope;\n /** Recovery v2 — F2 cipher-bound a recoveryKey. */\n fragmentF2Recovery?: EncryptedEnvelope;\n /** Recovery v2 — `sha256(email)` en hex. Optional para compat. */\n emailHash?: string;\n /** Recovery v2 — base64 salt. Optional para compat. */\n recoverySalt?: string;\n }): Promise<string> => {\n const res = await c.endpoints.createWallet({\n appId: c.appId,\n pubkeyEd25519: hexFromBytes(params.pubkeyEd25519),\n emailCommitment: hexFromBytes(params.emailCommitment),\n secp256r1Pubkey: hexFromBytes(params.secp256r1Pubkey),\n fragmentF2: encodeFragmentToWire(params.fragmentF2),\n fragmentF3: encodeFragmentToWire(params.fragmentF3),\n ...(params.fragmentF2Recovery\n ? { fragmentF2Recovery: encodeFragmentToWire(params.fragmentF2Recovery) }\n : {}),\n ...(params.emailHash ? { emailHash: params.emailHash } : {}),\n ...(params.recoverySalt ? { recoverySalt: params.recoverySalt } : {}),\n });\n return res.walletAddress;\n };\n\n const statusFromOnChain = (onChain: boolean | null): WalletStatus => {\n if (onChain === true) return 'on-chain';\n if (onChain === false) return 'pending-deploy';\n return 'unknown';\n };\n\n /**\n * Testnet auto-funding implementation. Hits Stellar friendbot with the\n * Smart Account contract address — la SDF lo soporta directamente post\n * Soroban (internamente arma una invokeContract XLM_SAC.transfer desde\n * la cuenta de friendbot al contrato). Resultado: ~10,000 XLM testnet\n * acreditados al Smart Account.\n *\n * No-op si `env !== 'testnet'`. Idempotente via flag local — solo hace\n * el round-trip a friendbot la primera vez.\n */\n // Detect testnet via the network passphrase rather than `env` — `env` is\n // a deploy stage (`dev` | `staging` | `prod`), not a chain selector.\n // Pre-mainnet, both `dev` and `staging` point to Stellar testnet; only\n // `prod` flips to the public mainnet passphrase.\n const TESTNET_PASSPHRASE = 'Test SDF Network ; September 2015';\n const isTestnet = stellarConfig.networkPassphrase === TESTNET_PASSPHRASE;\n\n const fundTestnetIfNeeded = async (\n walletAddress: string,\n username: string | null,\n opts?: { readonly retries?: number; readonly retryDelayMs?: number },\n ): Promise<FundTestnetResult> => {\n if (!isTestnet) {\n return { funded: false, alreadyFunded: false, reason: 'mainnet-not-supported' };\n }\n\n // Check local idempotency flag\n const existing = username ? await c.deviceStore.loadCredential(username) : null;\n if (existing?.testnetFunded) {\n return { funded: false, alreadyFunded: true, reason: 'already-funded' };\n }\n\n // Retries: caller path (auto-fund post-create) pasa varios porque hay\n // una race entre POST /wallets OK y el contrato apareciendo on-chain\n // — friendbot necesita el C-address vivo para invocar XLM_SAC.transfer.\n // Manual button: 0 retries (mismo comportamiento de antes).\n const retries = opts?.retries ?? 0;\n const retryDelayMs = opts?.retryDelayMs ?? 5000;\n\n const url = `https://friendbot.stellar.org?addr=${encodeURIComponent(walletAddress)}`;\n let funded = false;\n let alreadyFunded = false;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const res = await fetch(url);\n if (res.ok) {\n funded = true;\n break;\n }\n if (res.status === 400) {\n // Friendbot 400 puede ser \"ya fondeada\" (éxito idempotente) o\n // \"contrato no existe aún\" (retry). El body trae el detalle.\n const body = await res.text().catch(() => '');\n const alreadyExists =\n /already|exist|funded/i.test(body) && !/destination|account.*not/i.test(body);\n if (alreadyExists) {\n alreadyFunded = true;\n break;\n }\n // Contract probably not yet on-chain — retry if possible.\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, retryDelayMs));\n continue;\n }\n return { funded: false, alreadyFunded: false, reason: 'friendbot-error' };\n }\n // Other status — retry if possible.\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, retryDelayMs));\n continue;\n }\n return { funded: false, alreadyFunded: false, reason: 'friendbot-error' };\n } catch {\n if (attempt < retries) {\n await new Promise((r) => setTimeout(r, retryDelayMs));\n continue;\n }\n return { funded: false, alreadyFunded: false, reason: 'friendbot-error' };\n }\n }\n\n // Persist the flag so we don't hit friendbot again on subsequent\n // ensureWallet calls. If there's no existing credential record\n // (different device, fresh browser), nothing to update — the next\n // session might try again, which is OK (friendbot will 400 with\n // \"already funded\" and we treat that as success).\n if (existing) {\n await c.deviceStore.saveCredential({ ...existing, testnetFunded: true });\n }\n\n return {\n funded,\n alreadyFunded,\n reason: funded ? 'funded-now' : 'already-funded',\n };\n };\n\n return {\n async computeAddress(ownerPubkey) {\n return computeSmartAccountAddress({\n ownerPubkey,\n deployerAddress: stellarConfig.deployerAddress,\n networkPassphrase: stellarConfig.networkPassphrase,\n });\n },\n\n async createWallet(input) {\n // Defense in depth: coerce the passkey pubkey to the canonical\n // 65-byte 0x04-prefixed form. The backend validator rejects anything\n // else with \"secp256r1Pubkey must be hex 65 bytes (uncompressed)\".\n const secp256r1Canonical = normalizeSecp256r1Pubkey(input.secp256r1Pubkey);\n const created = coreCreateWallet({\n emailBytes: new TextEncoder().encode(input.email),\n emailSalt: input.emailSalt,\n encryptionKeys: input.encryptionKeys,\n });\n\n // Recovery v2: si el caller pasó `cognitoPassword`, generamos un\n // recoverySalt y re-ciframos F2 + F3 con `recoveryKey =\n // PBKDF2(password, recoverySalt, 600k)`. Necesitamos AMBOS porque\n // Shamir 2-de-3 exige DOS shares para reconstruir el seed durante\n // recovery (F1 está perdido cuando el device se pierde).\n //\n // Esa key vive SOLO en cliente — el backend recibe `{F2_recovery,\n // F3, recoverySalt}` y nunca puede descifrar sin el password.\n let fragmentF3ToSend = created.encryptedFragments[2];\n let fragmentF2Recovery: EncryptedEnvelope | undefined;\n let recoverySaltBase64: string | undefined;\n if (input.cognitoPassword) {\n const recoverySalt = generateRecoverySalt();\n const f2Plain = decryptAesGcm(created.encryptedFragments[1], input.encryptionKeys[1]);\n const f3Plain = decryptAesGcm(created.encryptedFragments[2], input.encryptionKeys[2]);\n const recoveryKey = deriveRecoveryKey({\n password: input.cognitoPassword,\n salt: recoverySalt,\n });\n try {\n fragmentF2Recovery = encryptAesGcm(f2Plain, recoveryKey);\n fragmentF3ToSend = encryptAesGcm(f3Plain, recoveryKey);\n } finally {\n // No leak: zeroize la key + plaintexts.\n for (let i = 0; i < recoveryKey.length; i += 1) recoveryKey[i] = 0;\n for (let i = 0; i < f2Plain.length; i += 1) f2Plain[i] = 0;\n for (let i = 0; i < f3Plain.length; i += 1) f3Plain[i] = 0;\n }\n recoverySaltBase64 = base64FromBytes(recoverySalt);\n }\n\n // emailHash = sha256(email.toLowerCase().trim()) en hex. El backend\n // lo indexa en el GSI by-email-hash para resolver Recovery v2.\n const emailHashHex = hexFromBytes(emailHashBytes(input.email));\n\n // Pre-compute the deterministic walletAddress.\n const predictedAddress = await computeSmartAccountAddress({\n ownerPubkey: created.publicKey,\n deployerAddress: stellarConfig.deployerAddress,\n networkPassphrase: stellarConfig.networkPassphrase,\n });\n\n // Crash-safety: persist el record con F3 cifrado en su forma\n // recoverable (la que se envía al backend). Si el caller no provee\n // password, mantenemos el F3 viejo (compat).\n const canPersist = Boolean(input.credentialId && input.prfSalt);\n if (canPersist) {\n await ctx.deviceStore.saveCredential({\n username: input.email,\n credentialId: input.credentialId!,\n secp256r1Pubkey: secp256r1Canonical,\n fragmentF1Encrypted: created.encryptedFragments[0],\n fragmentF2Encrypted: created.encryptedFragments[1],\n fragmentF3Encrypted: fragmentF3ToSend,\n publicKey: created.publicKey,\n emailCommitment: created.emailCommitment,\n prfSalt: input.prfSalt!,\n fallbackKeyMaterial: new Uint8Array(0),\n walletAddress: predictedAddress,\n onChain: null,\n createdAt: Date.now(),\n ...(input.encryptionSalt ? { encryptionSalt: input.encryptionSalt } : {}),\n });\n }\n\n let confirmedAddress: string;\n let deployStatus: WalletStatus = 'unknown';\n let pendingReason: string | undefined;\n\n try {\n confirmedAddress = await postWallet({\n pubkeyEd25519: created.publicKey,\n emailCommitment: created.emailCommitment,\n secp256r1Pubkey: secp256r1Canonical,\n fragmentF2: created.encryptedFragments[1],\n fragmentF3: fragmentF3ToSend,\n emailHash: emailHashHex,\n ...(fragmentF2Recovery ? { fragmentF2Recovery } : {}),\n ...(recoverySaltBase64 ? { recoverySalt: recoverySaltBase64 } : {}),\n });\n // POST succeeded — leave status as 'unknown'; the next\n // ensureWallet GET will upgrade it to 'on-chain' once Soroban\n // confirms the deploy.\n } catch (err) {\n if (!isSorobanDeployPendingError(err)) throw err;\n // Soroban rejected the deploy (constructor too big, footprint\n // exceeded, etc). Treat as deferrable — the local record is\n // already persisted with the predicted address; the backend also\n // has the record by design. `wallet.retryDeploy` will land it\n // later once the contracts team slims the constructor.\n confirmedAddress = predictedAddress;\n deployStatus = 'pending-deploy';\n pendingReason = err instanceof Error ? err.message : String(err);\n console.warn(\n '[accesly] wallet deploy is pending — predicted address persisted, retry once Phase 1 destrabes the constructor',\n pendingReason,\n );\n }\n\n // Sanity check — predicted vs confirmed should always match. If not,\n // either the deployer address in env is wrong or the algorithm\n // drifted; either way the app should know about it.\n if (confirmedAddress !== predictedAddress) {\n console.warn('[accesly] computed walletAddress does not match backend response', {\n predicted: predictedAddress,\n confirmed: confirmedAddress,\n });\n }\n\n if (canPersist) {\n const existing = await ctx.deviceStore.loadCredential(input.email);\n if (existing) {\n await ctx.deviceStore.saveCredential({\n ...existing,\n walletAddress: confirmedAddress,\n onChain: deployStatus === 'pending-deploy' ? false : (existing.onChain ?? null),\n });\n }\n }\n\n return {\n walletAddress: confirmedAddress,\n publicKey: created.publicKey,\n status: deployStatus,\n ...(pendingReason !== undefined ? { pendingReason } : {}),\n };\n },\n\n async ensureWallet(input) {\n // Fire-and-forget auto-fund. Disparamos también con status='unknown'\n // (que es lo que regresa createWallet tras un POST exitoso, antes de\n // que el GET de confirmación marque on-chain). Friendbot necesita el\n // contrato vivo en Soroban para invocar XLM_SAC.transfer, así que\n // pasamos `retries` para esperar la race POST→on-chain (~5–10s).\n const maybeAutoFund = (result: EnsureWalletResult): EnsureWalletResult => {\n if (isTestnet && (result.status === 'on-chain' || result.status === 'unknown')) {\n fundTestnetIfNeeded(result.walletAddress, input.email, {\n retries: 6,\n retryDelayMs: 5000,\n }).catch(() => {\n /* friendbot a veces falla, no es crítico para el flow */\n });\n }\n return result;\n };\n\n // 1. Cheap idempotent metadata read.\n const remote = await ctx.endpoints.getWallet();\n\n if (remote) {\n // Update the local record's onChain mirror if we have one.\n const local = await ctx.deviceStore.loadCredential(input.email);\n if (local) {\n await ctx.deviceStore.saveCredential({\n ...local,\n walletAddress: remote.walletAddress,\n onChain: remote.onChain,\n });\n }\n\n if (\n remote.onChain === false &&\n local &&\n local.fragmentF2Encrypted &&\n local.fragmentF3Encrypted\n ) {\n // Ghost wallet — backend has the record but Soroban shows no\n // contract. Try a retry; if it still doesn't surface as on-chain\n // (constructor too big, RPC slow), surface pending-deploy.\n try {\n const retried = await this.retryDeploy(input.email);\n return maybeAutoFund({\n walletAddress: retried.walletAddress,\n status: retried.status,\n createdNow: false,\n });\n } catch {\n return maybeAutoFund({\n walletAddress: remote.walletAddress,\n status: 'pending-deploy',\n createdNow: false,\n });\n }\n }\n\n return maybeAutoFund({\n walletAddress: remote.walletAddress,\n status: statusFromOnChain(remote.onChain),\n createdNow: false,\n });\n }\n\n // 2. No wallet at the backend — first-time flow.\n const created = await this.createWallet(input);\n return maybeAutoFund({\n walletAddress: created.walletAddress,\n publicKey: created.publicKey,\n // Use whatever status createWallet inferred. POST OK ⇒ 'unknown'\n // (the next GET will upgrade to 'on-chain'); Soroban rejected the\n // deploy ⇒ 'pending-deploy' with the predicted address.\n status: created.status,\n createdNow: true,\n });\n },\n\n async retryDeploy(username) {\n const record = await ctx.deviceStore.loadCredential(username);\n if (!record) {\n throw new Error(\n `wallet.retryDeploy: no local CredentialRecord for \"${username}\". ` +\n 'Call wallet.createWallet first (with credentialId + prfSalt).',\n );\n }\n if (\n !record.publicKey ||\n !record.emailCommitment ||\n !record.fragmentF2Encrypted ||\n !record.fragmentF3Encrypted\n ) {\n throw new Error(\n `wallet.retryDeploy: stored CredentialRecord for \"${username}\" is missing ` +\n 'publicKey / emailCommitment / encrypted F2 / F3. ' +\n 'Re-create the wallet from scratch.',\n );\n }\n const confirmed = await postWallet({\n pubkeyEd25519: record.publicKey,\n emailCommitment: record.emailCommitment,\n secp256r1Pubkey: record.secp256r1Pubkey,\n fragmentF2: record.fragmentF2Encrypted,\n fragmentF3: record.fragmentF3Encrypted,\n });\n // Re-query the backend to learn the up-to-date onChain status.\n const remote = await ctx.endpoints.getWallet();\n const onChain = remote?.onChain ?? null;\n await ctx.deviceStore.saveCredential({\n ...record,\n walletAddress: confirmed,\n onChain,\n });\n return { walletAddress: confirmed, status: statusFromOnChain(onChain) };\n },\n\n async fetchRemote() {\n const remote = await ctx.endpoints.getWallet();\n return remote;\n },\n getStoredCredential(username) {\n return ctx.deviceStore.loadCredential(username);\n },\n async getPendingWallets() {\n const all = await ctx.deviceStore.listCredentials();\n return all.filter((c) => c.walletAddress === null || c.onChain === false);\n },\n clearStoredCredential(username) {\n return ctx.deviceStore.deleteCredential(username);\n },\n fundTestnet(walletAddress) {\n // Username viene del context — coincide con el primary key del DeviceStore.\n return fundTestnetIfNeeded(walletAddress, c.username);\n },\n\n /**\n * Implementación del high-level entry point. Combina registración de\n * passkey + derivación HKDF + ensureWallet en una sola llamada.\n */\n async bootstrap(input) {\n const enc = new TextEncoder();\n const userIdHash = sha256(enc.encode(input.email));\n const prfSalt = getRandomBytes(32);\n\n const rpId =\n input.passkey?.rpId ??\n (typeof window !== 'undefined' ? window.location.hostname : 'localhost');\n const rpName = input.passkey?.rpName ?? 'Accesly';\n\n const passkey = await registerPasskey({\n rpId,\n rpName,\n userId: userIdHash,\n userName: input.email,\n prfSalt,\n });\n\n if (!passkey.prfSupported || !passkey.prfOutput) {\n throw new Error(\n 'wallet.bootstrap: this authenticator does not support the WebAuthn PRF ' +\n 'extension. Use Chrome 116+, Edge 116+, or Safari 18+ with a native ' +\n 'OS passkey (Touch ID, Face ID, Windows Hello).',\n );\n }\n\n const encryptionSalt = getRandomBytes(32);\n const f1Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f1-encryption'),\n 32,\n );\n const f2Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f2-encryption'),\n 32,\n );\n const f3Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f3-encryption'),\n 32,\n );\n\n // prfOutput drained — zeroize lo antes posible.\n zeroize(passkey.prfOutput);\n\n const emailSalt = getRandomBytes(32);\n const cognitoPasswordBytes = enc.encode(input.password);\n\n try {\n const result = await this.ensureWallet({\n email: input.email,\n emailSalt,\n encryptionKeys: [f1Key, f2Key, f3Key] as const,\n secp256r1Pubkey: passkey.secp256r1Pubkey,\n credentialId: passkey.credentialId,\n prfSalt,\n cognitoPassword: cognitoPasswordBytes,\n encryptionSalt,\n });\n return result;\n } finally {\n zeroize(f1Key);\n zeroize(f2Key);\n zeroize(f3Key);\n zeroize(cognitoPasswordBytes);\n }\n },\n\n /**\n * Implementación del helper de unlock. Reemplaza al\n * `lib/unlockForSigning.ts` que cada integrador tenía que copiar.\n */\n async unlockForSigning(username) {\n const record = await ctx.deviceStore.loadCredential(username);\n if (!record) {\n throw new Error(\n `wallet.unlockForSigning: no local CredentialRecord for \"${username}\". ` +\n 'Run recovery.finalize on this device or create a new wallet.',\n );\n }\n if (!record.publicKey) {\n throw new Error(\n 'wallet.unlockForSigning: stored CredentialRecord has no publicKey. ' +\n 'Legacy wallet — recreate it with wallet.bootstrap.',\n );\n }\n if (!record.fragmentF1Encrypted) {\n throw new Error(\n 'wallet.unlockForSigning: stored CredentialRecord has no fragmentF1Encrypted.',\n );\n }\n\n const challenge = getRandomBytes(32);\n const rpId =\n typeof window !== 'undefined' ? window.location.hostname : 'localhost';\n const unlock = await unlockPasskey({\n rpId,\n credentialId: record.credentialId,\n challenge,\n prfSalt: record.prfSalt,\n });\n if (!unlock.prfOutput) {\n throw new Error(\n 'wallet.unlockForSigning: authenticator did not return PRF output. ' +\n 'Did you use the same browser/device where the wallet was created?',\n );\n }\n\n // Backwards compat: legacy CredentialRecords (pre-1.1.0) no tienen\n // `encryptionSalt`. Fallback al `prfSalt` — el flujo legacy del example\n // usaba un encryptionSalt separado pero que vive en otro store fuera\n // del SDK. Para nuevas wallets `wallet.bootstrap` siempre persiste el\n // encryptionSalt, así que este path solo aplica a wallets viejas.\n const salt = record.encryptionSalt ?? record.prfSalt;\n const enc = new TextEncoder();\n const f1Key = hkdfSha256(\n unlock.prfOutput,\n salt,\n enc.encode('accesly-f1-encryption'),\n 32,\n );\n const fragmentF2Key = hkdfSha256(\n unlock.prfOutput,\n salt,\n enc.encode('accesly-f2-encryption'),\n 32,\n );\n\n zeroize(unlock.prfOutput);\n\n let fragmentF1Plain: Uint8Array;\n try {\n fragmentF1Plain = decryptAesGcm(record.fragmentF1Encrypted, f1Key);\n } finally {\n zeroize(f1Key);\n }\n\n return {\n fragmentF1Plain,\n fragmentF2Key,\n ownerPubkey: record.publicKey,\n walletAddress: record.walletAddress ?? '',\n };\n },\n };\n }, [ctx, hexFromBytes, stellarConfig]);\n\n const tx = useMemo<TxNamespace>(\n () => ({\n async send(input) {\n const networkPassphrase = stellarConfig.networkPassphrase;\n const verifierAddress = stellarConfig.ed25519VerifierAddress;\n const explorerBase =\n networkPassphrase === 'Public Global Stellar Network ; September 2015'\n ? 'https://stellar.expert/explorer/public/tx/'\n : 'https://stellar.expert/explorer/testnet/tx/';\n\n // 1. Backend simulate → returns the placeholder envelope + payload to sign.\n const sim = await ctx.endpoints.simulateTx({\n amountStroops: input.amountStroops,\n destinationAddress: input.destinationAddress,\n });\n\n // 2. ECDH key exchange → backend re-wraps F2 with a per-request key.\n const ephemeral = generateX25519Keypair();\n const ephemeralPubBase64 = base64FromBytes(ephemeral.publicKey);\n\n const wrappedF2 = await ctx.endpoints.getFragment2({\n clientEphemeralPubkey: ephemeralPubBase64,\n });\n\n // 3. Undo the session layer → recovers the original EncryptedFragment JSON.\n const sessionPlaintext = unwrapSessionFragment2(wrappedF2, ephemeral.privateKey).plaintext;\n const fragmentF2Wire = JSON.parse(new TextDecoder().decode(sessionPlaintext)) as {\n ciphertext: string;\n nonce: string;\n algo: string;\n };\n\n const fragmentF2Envelope: EncryptedEnvelope = {\n nonce: base64ToBytes(fragmentF2Wire.nonce),\n ciphertext: base64ToBytes(fragmentF2Wire.ciphertext),\n };\n\n // 4. Reconstruct ed25519 seed by combining F1 (plain) + F2 (decrypted with F2 key).\n const reconstructed = reconstructFromPlainAndEncrypted({\n fragmentF1Plain: input.fragmentF1Plain,\n fragmentF2: { envelope: fragmentF2Envelope, key: input.fragmentF2Key },\n });\n\n // 5. Sign the Soroban auth entry with the reconstructed seed. The helper\n // zero-izes the seed even on throw.\n const { signedAuthEntryXdr } = await signSorobanAuthEntry({\n signaturePayloadHashBase64: sim.signaturePayloadHashBase64,\n contextRuleIds: [...sim.contextRuleIds],\n placeholderAuthEntryXdr: sim.placeholderAuthEntryXdr,\n ed25519Seed: reconstructed.privateSeed,\n ed25519VerifierAddress: verifierAddress,\n ownerPubkey: input.ownerPubkey,\n });\n\n // 6. Backend submit → wraps in fee-bump with channels-fund and submits.\n const submit = await ctx.endpoints.submitTx({\n unsignedXdr: sim.unsignedXdr,\n signedAuthEntryXdr,\n });\n\n // 7. Optimistic update — push el item al `useWalletHistory` cache para\n // que aparezca al instante sin esperar el indexing de Stellar\n // Expert (~30-60s típico). El próximo poll del hook lo va a\n // descartar cuando confirme que ya está en el feed real.\n try {\n // walletAddress = computeSmartAccountAddress requeriría el deployer.\n // En vez de re-computar, los hooks que consumen optimistic resuelven\n // el wallet via DeviceStore; acá insertamos por ownerPubkey hex.\n const username = ctx.username;\n if (username) {\n const stored = await ctx.deviceStore.loadCredential(username);\n if (stored?.walletAddress) {\n const { historyOptimisticPush } = await import('./useWalletHistory.js');\n historyOptimisticPush(stored.walletAddress, {\n type: 'transfer-out',\n txHash: submit.txHash,\n ledger: Math.floor(Date.now() / 1000),\n timestamp: new Date().toISOString(),\n to: input.destinationAddress,\n amountStroops: input.amountStroops,\n });\n }\n }\n } catch {\n // Fire-and-forget — no rompemos el send si falla el optimistic push.\n }\n\n return {\n txHash: submit.txHash,\n status: submit.status,\n explorerUrl: `${explorerBase}${submit.txHash}`,\n };\n },\n async signRawXdr(input) {\n return coreSignTransaction({\n transactionXdr: input.transactionXdr,\n ed25519Seed: input.ed25519Seed,\n networkPassphrase: stellarConfig.networkPassphrase,\n ...(input.expectedPublicKey ? { expectedPublicKey: input.expectedPublicKey } : {}),\n });\n },\n }),\n [ctx, stellarConfig],\n );\n\n const kyc = useMemo<KycNamespace>(\n () => ({\n async start() {\n return ctx.endpoints.kycStart();\n },\n async status() {\n return ctx.endpoints.kycStatus();\n },\n }),\n [ctx],\n );\n\n // ── Recovery v2 (Fase 1, 2026-06-15) ──────────────────────────────────────\n // Esta primera versión expone los wrappers thin de los 3 endpoints públicos\n // (`requestOtp`, `verifyOtp`, `finalize`). El `finalize` aquí solo manda el\n // body al backend tal cual lo arme el caller — el orchestration completo\n // (descifrar F3 con recoveryKey, reconstruir seed, registrar new passkey,\n // firmar rotate_signer, etc.) se hace en el componente de UI con los\n // helpers de @accesly/core (deriveRecoveryKey, decryptAesGcm, etc.).\n //\n // Razón: el flujo requiere navegar 2-3 pantallas (pedir password, registrar\n // new passkey vía navigator.credentials.create, esperar response del user)\n // y meterlo todo dentro de un solo `finalize()` programáticamente hace el\n // UX worse. El example app va a tener el orchestrator end-to-end.\n const recovery = useMemo<RecoveryNamespace>(\n () => ({\n async requestOtp(input) {\n return ctx.endpoints.requestRecoveryOtp(input);\n },\n async verifyOtp(input) {\n return ctx.endpoints.verifyRecoveryOtp(input);\n },\n async reconstructSeed(input) {\n // 1. Trae F2_recovery + F3 + recoverySalt del backend.\n const frag = await ctx.endpoints.getFragment3(input.recoveryJwt);\n if (!frag.fragmentF2Recovery) {\n throw new Error(\n 'recovery.reconstructSeed: la wallet fue creada antes de Fase 1 y no tiene F2 cipher-bound a recoveryKey. No es recuperable vía OTP.',\n );\n }\n\n // 2. Decode salt + deriva recoveryKey con el password.\n const recoverySalt = base64ToBytes(frag.recoverySalt);\n const recoveryKey = deriveRecoveryKey({\n password: input.cognitoPassword,\n salt: recoverySalt,\n });\n\n // 3. Reconstruye seed via Shamir(F2, F3) ambos descifrados con\n // recoveryKey. `reconstructKey` zeroiza las plaintexts internas.\n const f2Envelope: EncryptedEnvelope = {\n ciphertext: base64ToBytes(frag.fragmentF2Recovery.ciphertext),\n nonce: base64ToBytes(frag.fragmentF2Recovery.nonce),\n };\n const f3Envelope: EncryptedEnvelope = {\n ciphertext: base64ToBytes(frag.fragmentF3Encrypted.ciphertext),\n nonce: base64ToBytes(frag.fragmentF3Encrypted.nonce),\n };\n const seedResult = reconstructKey({\n fragments: [\n { envelope: f2Envelope, key: recoveryKey },\n { envelope: f3Envelope, key: recoveryKey },\n ],\n });\n\n return {\n privateSeed: seedResult.privateSeed,\n publicKey: seedResult.publicKey,\n recoveryKey,\n recoverySalt: frag.recoverySalt,\n };\n },\n async finalize(input) {\n const networkPassphrase = stellarConfig.networkPassphrase;\n const verifierAddress = stellarConfig.ed25519VerifierAddress;\n const explorerBase =\n networkPassphrase === 'Public Global Stellar Network ; September 2015'\n ? 'https://stellar.expert/explorer/public/tx/'\n : 'https://stellar.expert/explorer/testnet/tx/';\n\n const enc = new TextEncoder();\n const cognitoPasswordBytes = enc.encode(input.password);\n\n // 1. Reconstruct la seed VIEJA via Shamir(F2_recovery + F3). El SDK ya\n // expone esto como `this.reconstructSeed` — reusamos.\n const seedResult = await this.reconstructSeed({\n cognitoPassword: cognitoPasswordBytes,\n recoveryJwt: input.recoveryJwt,\n });\n const oldReconstructedSeed = seedResult.privateSeed;\n const oldOwnerPubkey = seedResult.publicKey;\n const oldRecoveryKey = seedResult.recoveryKey;\n\n try {\n // 2. Registrar el NUEVO passkey con PRF.\n const userIdHash = sha256(enc.encode(input.email));\n const newPrfSalt = getRandomBytes(32);\n const rpId =\n input.passkey?.rpId ??\n (typeof window !== 'undefined' ? window.location.hostname : 'localhost');\n const rpName = input.passkey?.rpName ?? 'Accesly';\n const passkey = await registerPasskey({\n rpId,\n rpName,\n userId: userIdHash,\n userName: input.email,\n prfSalt: newPrfSalt,\n });\n if (!passkey.prfSupported || !passkey.prfOutput) {\n throw new Error(\n 'recovery.finalize: the new authenticator did not return PRF output. ' +\n 'Required by Accesly. Use Chrome 116+, Edge 116+, Safari 18+ with a native OS passkey.',\n );\n }\n\n // 3. Derivar las dos AES keys nuevas (F1' PRF-bound, F2' PRF-bound)\n // + el encryptionSalt persistible.\n const encryptionSalt = getRandomBytes(32);\n const newF1Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f1-encryption'),\n 32,\n );\n const newF2Key = hkdfSha256(\n passkey.prfOutput,\n encryptionSalt,\n enc.encode('accesly-f2-encryption'),\n 32,\n );\n zeroize(passkey.prfOutput);\n\n // 4. Genera NUEVA seed + new Shamir split. F3' se cifra con\n // newRecoveryKey (PBKDF2(password, newRecoverySalt, 600k)).\n const newRecoverySalt = generateRecoverySalt();\n const newRecoveryKey = deriveRecoveryKey({\n password: cognitoPasswordBytes,\n salt: newRecoverySalt,\n });\n const newRecoverySaltBase64 = base64FromBytes(newRecoverySalt);\n const newEmailSalt = getRandomBytes(32);\n\n const created = coreCreateWallet({\n emailBytes: enc.encode(input.email),\n emailSalt: newEmailSalt,\n encryptionKeys: [newF1Key, newF2Key, newRecoveryKey] as const,\n });\n\n // 5. F2_recovery — derivar el envelope cifrado con newRecoveryKey.\n // Descifra F2' (PRF-bound) → re-cifra con recoveryKey. La seed\n // plaintext nunca se toca acá; solo el SHARE plaintext.\n const f2PlainShare = decryptAesGcm(created.encryptedFragments[1], newF2Key);\n let newFragmentF2Recovery: EncryptedEnvelope;\n try {\n newFragmentF2Recovery = encryptAesGcm(f2PlainShare, newRecoveryKey);\n } finally {\n zeroize(f2PlainShare);\n }\n\n const newSecp256r1Canonical = normalizeSecp256r1Pubkey(passkey.secp256r1Pubkey);\n const newOwnerHex = hexFromBytes(created.publicKey);\n const newSecpHex = hexFromBytes(newSecp256r1Canonical);\n const newEmailCommitHex = hexFromBytes(created.emailCommitment);\n\n // 6. POST /recovery/simulate-rotate-signer.\n const sim = await ctx.endpoints.simulateRotateSigner(input.recoveryJwt, {\n newOwnerEd25519Pubkey: newOwnerHex,\n newSecp256r1Pubkey: newSecpHex,\n newEmailCommitment: newEmailCommitHex,\n });\n\n // 7. Firmar la auth entry con la SEED VIEJA. signSorobanAuthEntry\n // zero-iza la seed internamente.\n const { signedAuthEntryXdr } = await signSorobanAuthEntry({\n signaturePayloadHashBase64: sim.signaturePayloadHashBase64,\n contextRuleIds: [...sim.contextRuleIds],\n placeholderAuthEntryXdr: sim.placeholderAuthEntryXdr,\n ed25519Seed: oldReconstructedSeed,\n ed25519VerifierAddress: verifierAddress,\n ownerPubkey: oldOwnerPubkey,\n });\n\n // 8. POST /recovery/finalize.\n let finalizeResp;\n try {\n finalizeResp = await ctx.endpoints.finalizeRecovery(input.recoveryJwt, {\n unsignedXdr: sim.unsignedXdr,\n signedAuthEntryXdr,\n newOwnerEd25519Pubkey: newOwnerHex,\n newSecp256r1Pubkey: newSecpHex,\n newFragmentF1Encrypted: encodeFragmentToWire(created.encryptedFragments[0]),\n newFragmentF2Encrypted: encodeFragmentToWire(created.encryptedFragments[1]),\n newFragmentF2Recovery: encodeFragmentToWire(newFragmentF2Recovery),\n newFragmentF3Encrypted: encodeFragmentToWire(created.encryptedFragments[2]),\n newRecoverySalt: newRecoverySaltBase64,\n newEmailCommitment: newEmailCommitHex,\n });\n } finally {\n zeroize(newRecoveryKey);\n }\n\n // 9. Persistir el nuevo CredentialRecord (con encryptionSalt para que\n // unlockForSigning pueda re-derivar las mismas keys).\n await ctx.deviceStore.saveCredential({\n username: input.email,\n credentialId: passkey.credentialId,\n secp256r1Pubkey: newSecp256r1Canonical,\n fragmentF1Encrypted: created.encryptedFragments[0],\n fragmentF2Encrypted: created.encryptedFragments[1],\n fragmentF3Encrypted: created.encryptedFragments[2],\n publicKey: created.publicKey,\n emailCommitment: created.emailCommitment,\n prfSalt: newPrfSalt,\n encryptionSalt,\n fallbackKeyMaterial: new Uint8Array(0),\n walletAddress: finalizeResp.walletAddress,\n onChain: true,\n createdAt: Date.now(),\n });\n\n // Zeroize key material que aún tenemos en mano.\n zeroize(newF1Key);\n zeroize(newF2Key);\n\n return {\n walletAddress: finalizeResp.walletAddress,\n txHash: finalizeResp.txHash,\n status: finalizeResp.status,\n newPublicKey: created.publicKey,\n explorerUrl: `${explorerBase}${finalizeResp.txHash}`,\n };\n } finally {\n // Zeroize TODO el material sensitive aunque algo truene a mitad.\n zeroize(cognitoPasswordBytes);\n zeroize(oldReconstructedSeed);\n zeroize(oldRecoveryKey);\n }\n },\n async submitFinalize(input) {\n return ctx.endpoints.finalizeRecovery(input.recoveryJwt, {\n unsignedXdr: input.unsignedXdr,\n signedAuthEntryXdr: input.signedAuthEntryXdr,\n newOwnerEd25519Pubkey: input.newOwnerEd25519Pubkey,\n newSecp256r1Pubkey: input.newSecp256r1Pubkey,\n newFragmentF1Encrypted: encodeFragmentToWire(input.newFragmentF1Encrypted),\n newFragmentF2Encrypted: encodeFragmentToWire(input.newFragmentF2Encrypted),\n newFragmentF2Recovery: encodeFragmentToWire(input.newFragmentF2Recovery),\n newFragmentF3Encrypted: encodeFragmentToWire(input.newFragmentF3Encrypted),\n newRecoverySalt: input.newRecoverySalt,\n newEmailCommitment: input.newEmailCommitment,\n });\n },\n }),\n [ctx, stellarConfig, hexFromBytes],\n );\n\n const session = useMemo<SessionNamespace>(\n () => ({\n async create() {\n throw new NotImplementedYetError('session', 'create');\n },\n async revoke() {\n throw new NotImplementedYetError('session', 'revoke');\n },\n }),\n [],\n );\n\n const settings = useMemo<SettingsNamespace>(\n () => ({\n async addDevice() {\n throw new NotImplementedYetError('settings', 'addDevice');\n },\n async removeDevice() {\n throw new NotImplementedYetError('settings', 'removeDevice');\n },\n async listDevices() {\n throw new NotImplementedYetError('settings', 'listDevices');\n },\n async updateSpendingLimit() {\n throw new NotImplementedYetError('settings', 'updateSpendingLimit');\n },\n }),\n [],\n );\n\n const yieldOps = useMemo<YieldNamespace>(\n () => ({\n async invest() {\n throw new NotImplementedYetError('yield', 'invest');\n },\n async redeem() {\n throw new NotImplementedYetError('yield', 'redeem');\n },\n async position() {\n throw new NotImplementedYetError('yield', 'position');\n },\n }),\n [],\n );\n\n // hexToBytes is reserved for future helpers.\n void hexToBytes;\n return { auth, wallet, tx, kyc, recovery, session, settings, yieldOps, _internal: ctx };\n}\n\n/* --------------------------------- helpers --------------------------------- */\n\nfunction coderHelpers(): {\n hexToBytes: (hex: string) => Uint8Array;\n hexFromBytes: (bytes: Uint8Array) => string;\n} {\n function hexFromBytes(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 1) {\n out += (bytes[i] ?? 0).toString(16).padStart(2, '0');\n }\n return out;\n }\n function hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n if (clean.length % 2 !== 0) throw new Error(`hexToBytes: odd length ${clean.length}`);\n const out = new Uint8Array(clean.length / 2);\n for (let i = 0; i < out.length; i += 1) {\n out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n }\n return { hexToBytes, hexFromBytes };\n}\n\nfunction encodeFragmentToWire(env: EncryptedEnvelope): {\n ciphertext: string;\n nonce: string;\n algo: 'aes-256-gcm';\n} {\n return {\n ciphertext: base64FromBytes(env.ciphertext),\n nonce: base64FromBytes(env.nonce),\n algo: 'aes-256-gcm',\n };\n}\n\nfunction base64FromBytes(bytes: Uint8Array): string {\n if (typeof Buffer !== 'undefined') return Buffer.from(bytes).toString('base64');\n // Browser fallback\n let bin = '';\n for (let i = 0; i < bytes.length; i += 1) bin += String.fromCharCode(bytes[i] ?? 0);\n return globalThis.btoa(bin);\n}\n\nfunction base64ToBytes(s: string): Uint8Array {\n if (typeof Buffer !== 'undefined') return new Uint8Array(Buffer.from(s, 'base64'));\n const bin = globalThis.atob(s);\n const arr = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i += 1) arr[i] = bin.charCodeAt(i);\n return arr;\n}\n","/**\n * `AcceslyProvider` — top-level React provider that creates the SDK instances\n * once and exposes them through context. All hooks consume this.\n *\n * Apps wrap their tree:\n * <AcceslyProvider appId=\"myapp\" env=\"dev\">\n * <App />\n * </AcceslyProvider>\n *\n * For advanced cases (custom IdP, custom storage), pass `overrides` to inject\n * your own `AuthClient`, `SessionStorage`, or `DeviceStore`.\n */\n\nimport {\n AccesslyApiClient,\n AccesslyEndpoints,\n CognitoAuthClient,\n defaultSessionStorage,\n InMemoryDeviceStore,\n TokenManager,\n type AuthClient,\n type AuthStatus,\n type CognitoConfig,\n type DeviceStore,\n type Environment,\n type SessionStorage,\n type TelemetrySink,\n} from '@accesly/core';\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { AcceslyContext, type AcceslyContextValue } from './context.js';\nimport { ENVIRONMENT_DEFAULTS } from './config.js';\n\nexport interface AcceslyProviderProps {\n readonly appId: string;\n readonly env: Environment;\n readonly children: ReactNode;\n /** Override the resolved API URL. */\n readonly apiUrl?: string;\n /** Override the resolved Cognito config. */\n readonly cognitoConfig?: CognitoConfig;\n /** Override SDK pieces — for tests or custom backends. */\n readonly overrides?: {\n readonly authClient?: AuthClient;\n readonly sessionStorage?: SessionStorage;\n readonly deviceStore?: DeviceStore;\n };\n /** Optional telemetry sink — surfaces every API request/response/retry. */\n readonly telemetry?: TelemetrySink;\n}\n\nexport function AcceslyProvider(props: AcceslyProviderProps): JSX.Element {\n const defaults = ENVIRONMENT_DEFAULTS[props.env];\n const apiUrl = props.apiUrl ?? defaults.apiUrl;\n const cognitoConfig = props.cognitoConfig ?? defaults.cognito;\n const telemetry = props.telemetry;\n\n // Build the SDK pieces once. The dependency array is intentionally only the\n // identity inputs — we don't want to rebuild on every render.\n const instances = useMemo(() => {\n const authClient: AuthClient =\n props.overrides?.authClient ?? new CognitoAuthClient(cognitoConfig);\n // Default: LocalStorageSessionStorage en browsers (sobrevive reload),\n // InMemorySessionStorage en Node/SSR. Override solo si tu app necesita\n // un backend distinto (httpOnly cookie, Electron safeStorage, etc.).\n const sessionStorage: SessionStorage =\n props.overrides?.sessionStorage ?? defaultSessionStorage();\n const deviceStore: DeviceStore = props.overrides?.deviceStore ?? new InMemoryDeviceStore();\n const tokenManager = new TokenManager({ authClient, storage: sessionStorage });\n const apiClient = new AccesslyApiClient({\n baseUrl: apiUrl,\n getIdToken: () => tokenManager.getValidIdToken(),\n ...(telemetry ? { telemetry } : {}),\n });\n const endpoints = new AccesslyEndpoints(apiClient);\n return { authClient, sessionStorage, deviceStore, tokenManager, endpoints };\n }, [\n apiUrl,\n cognitoConfig.region,\n cognitoConfig.userPoolId,\n cognitoConfig.userPoolClientId,\n props.overrides?.authClient,\n props.overrides?.sessionStorage,\n props.overrides?.deviceStore,\n ]);\n\n // Compute the initial status synchronously from storage when possible. If\n // storage.load returns a Promise (custom async storage), fall back to\n // 'anonymous' and let the mount effect upgrade it.\n const [status, setStatus] = useState<AuthStatus>(() => initialStatus(instances.sessionStorage));\n const [username, setUsername] = useState<string | null>(() =>\n initialUsername(instances.sessionStorage),\n );\n const mountedRef = useRef(true);\n\n // refreshStatus tiene que ser estable entre renders, si no el ctx value\n // cambia siempre y los hooks consumers (useBalance, useWalletActivity,\n // useWalletStatus) se re-disparan en loop infinito porque sus effects\n // dependen de `_internal.endpoints` que viene del ctx.\n const refreshStatus = useCallback(async (): Promise<void> => {\n const next = await instances.tokenManager.getStatus();\n const tokens = await Promise.resolve(instances.sessionStorage.load());\n if (mountedRef.current) {\n setStatus(next);\n setUsername(tokens?.username ?? null);\n }\n }, [instances]);\n\n useEffect(() => {\n mountedRef.current = true;\n void refreshStatus();\n return () => {\n mountedRef.current = false;\n };\n }, [instances]);\n\n const value: AcceslyContextValue = useMemo(\n () => ({\n appId: props.appId,\n env: props.env,\n apiUrl,\n cognitoConfig,\n authClient: instances.authClient,\n sessionStorage: instances.sessionStorage,\n tokenManager: instances.tokenManager,\n endpoints: instances.endpoints,\n deviceStore: instances.deviceStore,\n status,\n username,\n refreshStatus,\n }),\n [props.appId, props.env, apiUrl, cognitoConfig, instances, status, username, refreshStatus],\n );\n\n return <AcceslyContext.Provider value={value}>{props.children}</AcceslyContext.Provider>;\n}\n\n/**\n * Estado inicial — antes de que el effect del provider corra `refreshStatus()`.\n *\n * - Si el `SessionStorage` devuelve sync con tokens válidos → arrancamos directo\n * en `'authenticated'` / `'expired'`. Aplica al `LocalStorageSessionStorage`\n * default; el primer paint del browser ya conoce el status real → cero race\n * para `AuthGuard`.\n * - Si el `SessionStorage` devuelve sync con `null` → directo a `'anonymous'`.\n * - Si el `SessionStorage` es async (devuelve Promise) → `'bootstrapping'`,\n * para que `<AuthGuard>` muestre un loader en vez de redirigir a `/signin`\n * prematuramente. El effect lo flippa al estado real apenas resuelve.\n */\nfunction initialStatus(storage: SessionStorage): AuthStatus {\n const tokens = storage.load();\n if (tokens instanceof Promise) return 'bootstrapping';\n if (!tokens) return 'anonymous';\n return Date.now() + 5 * 60 * 1000 >= tokens.expiresAt ? 'expired' : 'authenticated';\n}\n\nfunction initialUsername(storage: SessionStorage): string | null {\n const tokens = storage.load();\n if (tokens instanceof Promise) return null;\n return tokens?.username ?? null;\n}\n","/**\n * @accesly/react — React Provider + `useAccesly` hook.\n *\n * Wraps `@accesly/core` for React 18+. Apps integrate with:\n *\n * import { AcceslyProvider, useAccesly } from '@accesly/react';\n *\n * function App() {\n * return (\n * <AcceslyProvider appId=\"my-app\" env=\"dev\">\n * <YourApp />\n * </AcceslyProvider>\n * );\n * }\n *\n * function Login() {\n * const { auth } = useAccesly();\n * return (\n * <button onClick={() => auth.signIn(email, password)}>Sign in</button>\n * );\n * }\n */\n\nexport const REACT_ADAPTER_VERSION = '0.0.0';\n\nexport { AcceslyProvider, type AcceslyProviderProps } from './provider.js';\nexport { AcceslyContext, type AcceslyContextValue } from './context.js';\nexport { ENVIRONMENT_DEFAULTS, type EnvironmentDefaults } from './config.js';\nexport {\n NotImplementedYetError,\n useAccesly,\n type AcceslyHook,\n type AuthNamespace,\n type BootstrapWalletInput,\n type CreatedWalletInfo,\n type CreateWalletInput,\n type EnsureWalletResult,\n type FinalizeRecoveryInput,\n type FinalizeRecoveryResult,\n type KycNamespace,\n type RecoveryNamespace,\n type ReconstructedSeed,\n type RemoteWalletInfo,\n type RetryDeployResult,\n type SendXlmInput,\n type SendXlmResult,\n type SessionNamespace,\n type SettingsNamespace,\n type TxNamespace,\n type UnlockedSigningMaterial,\n type WalletNamespace,\n type WalletStatus,\n type YieldNamespace,\n} from './hooks/useAccesly.js';\n\nexport { useWalletStatus, type UseWalletStatusResult, type WalletStatusValue } from './hooks/useWalletStatus.js';\nexport { useBalance, type UseBalanceResult } from './hooks/useBalance.js';\nexport {\n useWalletActivity,\n type UseWalletActivityOptions,\n type UseWalletActivityResult,\n} from './hooks/useWalletActivity.js';\nexport {\n useWalletHistory,\n historyOptimisticPush,\n historyClearOptimistic,\n type UseWalletHistoryOptions,\n type UseWalletHistoryResult,\n} from './hooks/useWalletHistory.js';\nexport {\n closeAllWalletSubscriptions,\n subscribeToWalletEvent,\n type WalletActivityItem,\n type WalletStreamActivityPayload,\n type WalletStreamBalancePayload,\n type WalletStreamEventType,\n type WalletStreamStatusPayload,\n} from './hooks/walletSubscription.js';\n","/**\n * `useWalletStatus()` — status on-chain del Smart Account del user actual con\n * push real-time vía SSE.\n *\n * Reemplaza el polling cada 30s del legacy. Comportamiento:\n *\n * 1. SSE-first: si `walletStreamUrl` está configurado y `EventSource` existe,\n * se suscribe al canal `status` del `wallet-stream` Lambda. Cero polling.\n * 2. Fallback a polling backoff (1s → 30s) si SSE no está disponible.\n * 3. Pausa cuando `document.hidden`, retoma al volver.\n * 4. `refresh()` fuerza fetch HTTP inmediato.\n *\n * El status del Smart Account vive en DDB (lo que el backend reporta de su\n * verificación contra Soroban). El backend push-ea cambios cuando los detecta\n * (cada 5s en el loop del wallet-stream).\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAccesly } from './useAccesly.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\nimport { subscribeToWalletEvent } from './walletSubscription.js';\n\nexport type WalletStatusValue = 'on-chain' | 'pending-deploy' | 'unknown' | 'no-wallet';\n\nconst POLL_BACKOFF_MS = [2000, 5000, 10_000, 20_000, 30_000];\nconst STALE_THRESHOLD_MS = 60_000;\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport interface UseWalletStatusResult {\n readonly status: WalletStatusValue;\n readonly walletAddress: string | null;\n readonly onChain: boolean | null;\n readonly isStale: boolean;\n refresh(): Promise<void>;\n}\n\nfunction deriveStatus(onChain: boolean | null): WalletStatusValue {\n if (onChain === true) return 'on-chain';\n if (onChain === false) return 'pending-deploy';\n return 'unknown';\n}\n\nexport function useWalletStatus(): UseWalletStatusResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n\n const [status, setStatus] = useState<WalletStatusValue>('unknown');\n const [walletAddress, setWalletAddress] = useState<string | null>(null);\n const [onChain, setOnChain] = useState<boolean | null>(null);\n const [lastSuccessAt, setLastSuccessAt] = useState<number>(0);\n const [isStale, setIsStale] = useState(false);\n\n const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];\n const streamUrl = envDefaults.walletStreamUrl;\n const walletRef = useStableRef(wallet);\n\n const doFetch = useCallback(async (): Promise<WalletStatusValue | null> => {\n if (!username) return null;\n try {\n const remote = await walletRef.current.fetchRemote();\n if (!remote) {\n setStatus('no-wallet');\n setWalletAddress(null);\n setOnChain(null);\n setLastSuccessAt(Date.now());\n setIsStale(false);\n return 'no-wallet';\n }\n const next = deriveStatus(remote.onChain);\n setStatus(next);\n setWalletAddress(remote.walletAddress);\n setOnChain(remote.onChain);\n setLastSuccessAt(Date.now());\n setIsStale(false);\n return next;\n } catch {\n return null;\n }\n }, [username, walletRef]);\n\n const doFetchRef = useStableRef(doFetch);\n\n useEffect(() => {\n if (!username) {\n setStatus('unknown');\n return undefined;\n }\n\n // Primer fetch HTTP para resolver walletAddress + status inicial.\n let cancelled = false;\n let unsubscribe: (() => void) | null = null;\n let pollTimer: ReturnType<typeof setTimeout> | null = null;\n let backoffIndex = 0;\n\n const schedulePoll = (delayMs: number) => {\n if (cancelled) return;\n pollTimer = setTimeout(async () => {\n if (cancelled) return;\n if (typeof document !== 'undefined' && document.hidden) return;\n const next = await doFetchRef.current();\n if (next === 'on-chain' || next === 'no-wallet') return;\n backoffIndex = Math.min(backoffIndex + 1, POLL_BACKOFF_MS.length - 1);\n schedulePoll(POLL_BACKOFF_MS[backoffIndex]!);\n }, delayMs);\n };\n\n void (async () => {\n const initial = await doFetchRef.current();\n if (cancelled) return;\n if (initial === 'on-chain' || initial === 'no-wallet') return;\n\n // Intentar SSE.\n if (walletAddress) {\n unsubscribe = subscribeToWalletEvent(streamUrl, walletAddress, 'status', (data) => {\n setWalletAddress(data.walletAddress);\n setOnChain(data.onChain);\n setStatus(deriveStatus(data.onChain));\n setLastSuccessAt(Date.now());\n setIsStale(false);\n });\n }\n if (!unsubscribe) {\n // SSE no disponible → polling con backoff.\n backoffIndex = 0;\n schedulePoll(POLL_BACKOFF_MS[0]!);\n }\n })();\n\n const onVisibilityChange = () => {\n if (typeof document === 'undefined') return;\n if (!document.hidden && !unsubscribe) {\n void doFetchRef.current();\n }\n };\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', onVisibilityChange);\n }\n\n const staleTimer = setInterval(() => {\n if (Date.now() - lastSuccessAt > STALE_THRESHOLD_MS && lastSuccessAt > 0) {\n setIsStale(true);\n }\n }, 30_000);\n\n return () => {\n cancelled = true;\n if (unsubscribe) unsubscribe();\n if (pollTimer) clearTimeout(pollTimer);\n clearInterval(staleTimer);\n if (typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [username, streamUrl, walletAddress]);\n\n const refresh = useCallback(async () => {\n await doFetchRef.current();\n }, [doFetchRef]);\n\n return { status, walletAddress, onChain, isStale, refresh };\n}\n","/**\n * `WalletSubscription` — singleton manager por wallet address que abre UNA\n * sola conexión `EventSource` al `wallet-stream` Lambda y desmultiplexa los\n * eventos a múltiples subscribers (hooks).\n *\n * Beneficios:\n * - 3 hooks (`useBalance`, `useWalletActivity`, `useWalletStatus`) sobre la\n * misma wallet → 1 sola conexión TCP, no 3 polls separados.\n * - Auto-reconnect cuando el server cierra (default de EventSource — `retry:`).\n * - Ref-count: la conexión se abre con el primer subscriber y se cierra\n * cuando no quedan listeners (`useEffect` cleanup en cada hook).\n * - Eventos cacheados: el último valor recibido de cada tipo se replay-ea\n * a nuevos subscribers para que no esperen el próximo push.\n *\n * Sin SSE configurado (`walletStreamUrl` vacío) o cuando `EventSource` no\n * existe (SSR / workers), los hooks individuales detectan el flag\n * `unavailable` y caen al polling fallback que ya existe.\n */\n\nexport type WalletStreamEventType = 'status' | 'balance' | 'activity';\n\nexport interface WalletStreamStatusPayload {\n readonly walletAddress: string | null;\n readonly onChain: boolean | null;\n}\n\nexport interface WalletStreamBalancePayload {\n readonly stroops: string;\n readonly xlm: string;\n}\n\n/**\n * Activity tipada lista para renderizar. Cuatro variants:\n *\n * - `wallet-created` — deploy inicial del Smart Account.\n * - `signer-rotated` — rotación de signer (recovery).\n * - `transfer-in` — recibió XLM.\n * - `transfer-out` — envió XLM.\n *\n * Otros eventos on-chain (signer_added/removed internos, ruido) se descartan.\n */\nexport type WalletActivityItem =\n | {\n readonly type: 'wallet-created';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n }\n | {\n readonly type: 'signer-rotated';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n readonly newOwnerEd25519Hex: string;\n }\n | {\n readonly type: 'transfer-in';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n readonly from: string;\n readonly amountStroops: string;\n }\n | {\n readonly type: 'transfer-out';\n readonly txHash: string;\n readonly ledger: number;\n readonly timestamp: string | null;\n readonly to: string;\n readonly amountStroops: string;\n };\n\nexport interface WalletStreamActivityPayload {\n readonly events: readonly WalletActivityItem[];\n}\n\ntype Listener<T> = (payload: T) => void;\n\ninterface InternalSubscription {\n status: Set<Listener<WalletStreamStatusPayload>>;\n balance: Set<Listener<WalletStreamBalancePayload>>;\n activity: Set<Listener<WalletStreamActivityPayload>>;\n}\n\ninterface WalletSubscriptionState {\n readonly walletAddress: string;\n readonly url: string;\n eventSource: EventSource | null;\n listeners: InternalSubscription;\n lastStatus: WalletStreamStatusPayload | null;\n lastBalance: WalletStreamBalancePayload | null;\n /** Acumulamos los últimos eventos para que nuevos subscribers vean histórico. */\n activityBuffer: WalletActivityItem[];\n refCount: number;\n}\n\nconst ACTIVITY_BUFFER_MAX = 50;\n\nconst subscriptions = new Map<string, WalletSubscriptionState>();\n\nfunction buildSubscriptionUrl(streamUrl: string, walletAddress: string): string {\n // Lambda Function URL ya trae trailing slash en algunos casos — normalizamos.\n const base = streamUrl.replace(/\\/$/, '');\n return `${base}/?walletAddress=${encodeURIComponent(walletAddress)}`;\n}\n\nfunction openConnection(state: WalletSubscriptionState): void {\n if (state.eventSource) return;\n if (typeof EventSource === 'undefined') return;\n\n let es: EventSource;\n try {\n es = new EventSource(state.url, { withCredentials: false });\n } catch (err) {\n console.warn('[walletSubscription] EventSource construction failed', err);\n return;\n }\n state.eventSource = es;\n\n es.addEventListener('status', (ev) => {\n try {\n const data = JSON.parse((ev as MessageEvent).data) as WalletStreamStatusPayload;\n state.lastStatus = data;\n for (const listener of state.listeners.status) listener(data);\n } catch {\n /* ignore malformed */\n }\n });\n\n es.addEventListener('balance', (ev) => {\n try {\n const data = JSON.parse((ev as MessageEvent).data) as WalletStreamBalancePayload;\n state.lastBalance = data;\n for (const listener of state.listeners.balance) listener(data);\n } catch {\n /* ignore malformed */\n }\n });\n\n es.addEventListener('activity', (ev) => {\n try {\n const data = JSON.parse((ev as MessageEvent).data) as WalletStreamActivityPayload;\n // Acumula al buffer (más reciente primero). Trim al max.\n const merged = [...data.events, ...state.activityBuffer];\n // Dedup por txHash + ledger.\n const seen = new Set<string>();\n const deduped: WalletActivityItem[] = [];\n for (const item of merged) {\n const key = `${item.txHash}:${item.ledger}`;\n if (seen.has(key)) continue;\n seen.add(key);\n deduped.push(item);\n if (deduped.length >= ACTIVITY_BUFFER_MAX) break;\n }\n state.activityBuffer = deduped;\n for (const listener of state.listeners.activity) {\n listener({ events: state.activityBuffer });\n }\n } catch {\n /* ignore malformed */\n }\n });\n\n es.addEventListener('close', () => {\n // El server cerró por timeout de budget — EventSource reconectará solo.\n // No hacemos nada acá.\n });\n\n es.onerror = () => {\n // Network blip o end-of-stream. EventSource auto-reconecta por default,\n // pero si la URL no funciona (404, CORS) el browser cierra para siempre.\n // No cerramos nosotros para dejar que el browser lo intente.\n };\n}\n\nfunction closeConnection(state: WalletSubscriptionState): void {\n if (!state.eventSource) return;\n state.eventSource.close();\n state.eventSource = null;\n}\n\nfunction getOrCreateSubscription(\n streamUrl: string,\n walletAddress: string,\n): WalletSubscriptionState {\n const existing = subscriptions.get(walletAddress);\n if (existing) return existing;\n const state: WalletSubscriptionState = {\n walletAddress,\n url: buildSubscriptionUrl(streamUrl, walletAddress),\n eventSource: null,\n listeners: {\n status: new Set(),\n balance: new Set(),\n activity: new Set(),\n },\n lastStatus: null,\n lastBalance: null,\n activityBuffer: [],\n refCount: 0,\n };\n subscriptions.set(walletAddress, state);\n return state;\n}\n\n/**\n * Suscribirse a un tipo de evento de la wallet. Devuelve una función\n * de cleanup que el caller (típicamente `useEffect`) debe llamar para\n * desuscribir y, eventualmente, cerrar la conexión SSE.\n *\n * Si SSE no está disponible (URL vacía, EventSource undefined), devuelve\n * `null` para indicar al caller que use el fallback de polling.\n */\nexport function subscribeToWalletEvent<T extends WalletStreamEventType>(\n streamUrl: string,\n walletAddress: string,\n eventType: T,\n listener: T extends 'status'\n ? Listener<WalletStreamStatusPayload>\n : T extends 'balance'\n ? Listener<WalletStreamBalancePayload>\n : Listener<WalletStreamActivityPayload>,\n): (() => void) | null {\n if (!streamUrl || typeof EventSource === 'undefined') return null;\n\n const state = getOrCreateSubscription(streamUrl, walletAddress);\n state.refCount += 1;\n\n // Registrar listener (cast a través del shape conocido).\n (state.listeners[eventType] as Set<typeof listener>).add(listener);\n\n // Replay del último valor cacheado para que el subscriber tenga data inmediata.\n if (eventType === 'status' && state.lastStatus) {\n (listener as Listener<WalletStreamStatusPayload>)(state.lastStatus);\n } else if (eventType === 'balance' && state.lastBalance) {\n (listener as Listener<WalletStreamBalancePayload>)(state.lastBalance);\n } else if (eventType === 'activity' && state.activityBuffer.length > 0) {\n (listener as Listener<WalletStreamActivityPayload>)({\n events: state.activityBuffer,\n });\n }\n\n // Abrir conexión si es el primer subscriber.\n if (!state.eventSource) openConnection(state);\n\n return () => {\n (state.listeners[eventType] as Set<typeof listener>).delete(listener);\n state.refCount -= 1;\n if (state.refCount <= 0) {\n closeConnection(state);\n subscriptions.delete(walletAddress);\n }\n };\n}\n\n/**\n * Cierra TODAS las conexiones SSE activas. Útil para tests o cuando el user\n * cierra sesión y querés limpiar conexiones colgadas. Llamar en `auth.signOut`\n * lo tienen pendiente como mejora — por ahora el cleanup natural de los\n * unmount basta.\n */\nexport function closeAllWalletSubscriptions(): void {\n for (const state of subscriptions.values()) closeConnection(state);\n subscriptions.clear();\n}\n","/**\n * `useBalance(walletAddress?)` — devuelve el balance XLM del Smart Account\n * con push real-time vía SSE.\n *\n * Si SSE está configurado (env tiene `walletStreamUrl` y `EventSource` existe),\n * el hook se suscribe al canal `balance` del `wallet-stream` Lambda y se\n * actualiza instantáneamente cuando cambia el balance on-chain.\n *\n * Fallback automático a polling cada 10s si SSE no está disponible (entorno\n * que no lo soporta o backend self-hosteado sin el endpoint).\n *\n * El `walletAddress` se auto-resuelve desde el `DeviceStore` si no se pasa\n * (cubrir el caso \"wallet del user actual sin tener que pasarla a mano\").\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAccesly } from './useAccesly.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\nimport { subscribeToWalletEvent } from './walletSubscription.js';\n\nconst POLL_FALLBACK_MS = 10_000;\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport interface UseBalanceResult {\n /** Stroops como string base-10. `null` mientras se carga o no hay address. */\n readonly stroops: string | null;\n /** Mismo balance como string decimal en XLM. `null` mientras se carga. */\n readonly xlm: string | null;\n readonly isLoading: boolean;\n readonly error: Error | null;\n /** Fuerza fetch HTTP inmediato (útil tras una operación del user). */\n refresh(): Promise<void>;\n}\n\nexport function useBalance(walletAddress?: string | null): UseBalanceResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n\n const [resolvedAddress, setResolvedAddress] = useState<string | null>(\n walletAddress ?? null,\n );\n const [stroops, setStroops] = useState<string | null>(null);\n const [xlm, setXlm] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Resolver walletAddress si no fue pasado explícitamente.\n const walletRef = useStableRef(wallet);\n useEffect(() => {\n if (walletAddress) {\n setResolvedAddress(walletAddress);\n return;\n }\n if (!username) {\n setResolvedAddress(null);\n return;\n }\n let cancelled = false;\n void (async () => {\n try {\n const stored = await walletRef.current.getStoredCredential(username);\n if (cancelled) return;\n setResolvedAddress(stored?.walletAddress ?? null);\n } catch {\n if (!cancelled) setResolvedAddress(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [walletAddress, username, walletRef]);\n\n // Suscribirse SSE — o si no está, fallback a polling.\n const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];\n const streamUrl = envDefaults.walletStreamUrl;\n const endpointsRef = useStableRef(_internal.endpoints);\n\n const doFetchOnce = useCallback(async () => {\n if (!resolvedAddress) return;\n try {\n const res = await endpointsRef.current.walletBalance(resolvedAddress);\n setStroops(res.xlm.stroops);\n setXlm(res.xlm.xlm);\n setError(null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [resolvedAddress, endpointsRef]);\n\n const doFetchRef = useStableRef(doFetchOnce);\n useEffect(() => {\n if (!resolvedAddress) {\n setIsLoading(false);\n return undefined;\n }\n\n // Intentar suscripción SSE primero.\n const unsubscribe = subscribeToWalletEvent(\n streamUrl,\n resolvedAddress,\n 'balance',\n (data) => {\n setStroops(data.stroops);\n setXlm(data.xlm);\n setError(null);\n setIsLoading(false);\n },\n );\n\n if (unsubscribe) {\n // SSE conectado — pero hacemos UN fetch HTTP inicial para no esperar\n // hasta el primer push del server (puede tardar 10s).\n void doFetchRef.current();\n return unsubscribe;\n }\n\n // SSE no disponible → polling fallback.\n void doFetchRef.current();\n const interval = setInterval(() => {\n if (typeof document !== 'undefined' && document.hidden) return;\n void doFetchRef.current();\n }, POLL_FALLBACK_MS);\n\n const onVisibilityChange = () => {\n if (typeof document === 'undefined') return;\n if (!document.hidden) void doFetchRef.current();\n };\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', onVisibilityChange);\n }\n\n return () => {\n clearInterval(interval);\n if (typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n };\n }, [resolvedAddress, streamUrl, doFetchRef]);\n\n const refresh = useCallback(async () => {\n await doFetchRef.current();\n }, [doFetchRef]);\n\n return { stroops, xlm, isLoading, error, refresh };\n}\n","/**\n * `useWalletActivity(walletAddress?, opts?)` — actividad on-chain relevante de\n * la wallet (rotate_signer + transfers in/out de XLM) con push real-time vía SSE.\n *\n * El backend YA filtra eventos irrelevantes — el integrador solo recibe\n * `WalletActivityItem` tipados (`signer-rotated` | `transfer-in` | `transfer-out`).\n * Sin parsing manual de XDR ni lógica de filtrado client-side.\n *\n * Fallback: si SSE no está disponible, polling cada 25s al endpoint\n * `/wallets/:address/activity`. Mucho menos eficiente pero garantiza data.\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useAccesly } from './useAccesly.js';\nimport { ENVIRONMENT_DEFAULTS } from '../config.js';\nimport {\n subscribeToWalletEvent,\n type WalletActivityItem,\n} from './walletSubscription.js';\n\nconst POLL_FALLBACK_MS = 25_000;\nconst DEFAULT_LIMIT = 20;\n\nfunction useStableRef<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport interface UseWalletActivityOptions {\n /** Cantidad de eventos a mostrar (cap del buffer del cliente). Default 20. */\n readonly limit?: number;\n}\n\nexport interface UseWalletActivityResult {\n /** Eventos tipados, más recientes primero. */\n readonly events: readonly WalletActivityItem[];\n readonly isLoading: boolean;\n readonly error: Error | null;\n refresh(): Promise<void>;\n}\n\nexport function useWalletActivity(\n walletAddress?: string | null,\n opts: UseWalletActivityOptions = {},\n): UseWalletActivityResult {\n const { wallet, _internal } = useAccesly();\n const username = _internal.username;\n const limit = Math.min(opts.limit ?? DEFAULT_LIMIT, 50);\n\n const [resolvedAddress, setResolvedAddress] = useState<string | null>(\n walletAddress ?? null,\n );\n const [events, setEvents] = useState<readonly WalletActivityItem[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const walletRef = useStableRef(wallet);\n useEffect(() => {\n if (walletAddress) {\n setResolvedAddress(walletAddress);\n return;\n }\n if (!username) {\n setResolvedAddress(null);\n return;\n }\n let cancelled = false;\n void (async () => {\n try {\n const stored = await walletRef.current.getStoredCredential(username);\n if (cancelled) return;\n setResolvedAddress(stored?.walletAddress ?? null);\n } catch {\n if (!cancelled) setResolvedAddress(null);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [walletAddress, username, walletRef]);\n\n const envDefaults = ENVIRONMENT_DEFAULTS[_internal.env];\n const streamUrl = envDefaults.walletStreamUrl;\n const endpointsRef = useStableRef(_internal.endpoints);\n\n const doFetchOnce = useCallback(async () => {\n if (!resolvedAddress) return;\n try {\n const res = await endpointsRef.current.walletActivity(resolvedAddress, limit);\n // El endpoint REST devuelve eventos sin tipar (parseado raw). Adaptamos\n // al shape tipado del SSE para que el integrador vea la misma forma —\n // y descartamos los que no encajen en los 3 tipos conocidos.\n const adapted: WalletActivityItem[] = [];\n for (const ev of res.events) {\n const conv = adaptRestEvent(ev);\n if (conv) adapted.push(conv);\n }\n setEvents(adapted.slice(0, limit));\n setError(null);\n } catch (err) {\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [resolvedAddress, limit, endpointsRef]);\n\n const doFetchRef = useStableRef(doFetchOnce);\n useEffect(() => {\n if (!resolvedAddress) {\n setIsLoading(false);\n return undefined;\n }\n\n const unsubscribe = subscribeToWalletEvent(\n streamUrl,\n resolvedAddress,\n 'activity',\n (data) => {\n setEvents(data.events.slice(0, limit));\n setError(null);\n setIsLoading(false);\n },\n );\n\n if (unsubscribe) {\n void doFetchRef.current();\n return unsubscribe;\n }\n\n // Polling fallback.\n void doFetchRef.current();\n const interval = setInterval(() => {\n if (typeof document !== 'undefined' && document.hidden) return;\n void doFetchRef.current();\n }, POLL_FALLBACK_MS);\n\n return () => clearInterval(interval);\n }, [resolvedAddress, streamUrl, limit, doFetchRef]);\n\n const refresh = useCallback(async () => {\n await doFetchRef.current();\n }, [doFetchRef]);\n\n return { events, isLoading, error, refresh };\n}\n\n/**\n * Adapta un `WalletActivityEvent` raw (del REST endpoint) al `WalletActivityItem`\n * tipado del SSE. Best-effort — si no matchea ninguno de los 3 tipos conocidos,\n * devuelve null y el item se descarta.\n *\n * En la práctica el REST endpoint ya viene en formato compatible; este adapter\n * es solo defensa por si el shape divergiera en el futuro.\n */\nfunction adaptRestEvent(ev: {\n type: string;\n txHash: string;\n ledger: number;\n timestamp: string | null;\n topics: readonly unknown[];\n value: unknown;\n}): WalletActivityItem | null {\n const t0 = ev.topics[0];\n if (typeof t0 !== 'string') return null;\n if (t0 === 'SignerRotated') {\n return {\n type: 'signer-rotated',\n txHash: ev.txHash,\n ledger: ev.ledger,\n timestamp: ev.timestamp,\n newOwnerEd25519Hex: typeof ev.value === 'string' ? ev.value : '',\n };\n }\n // Transfers REST no vienen pre-filtrados como in/out; lo dejamos sin\n // adaptar — el integrador igual los ve via SSE en cuanto se conecta.\n return null;\n}\n"]}
|