@accesly/react 1.0.0-pre.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.cjs +97 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -2
- package/dist/index.d.ts +81 -2
- package/dist/index.js +97 -1
- 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/provider.tsx","../src/hooks/sorobanDeployStatus.ts","../src/hooks/useAccesly.ts","../src/index.ts"],"names":["createContext","useMemo","CognitoAuthClient","InMemorySessionStorage","InMemoryDeviceStore","TokenManager","AccesslyApiClient","AccesslyEndpoints","useState","useRef","useEffect","AccesslyApiError","useContext","computeSmartAccountAddress","normalizeSecp256r1Pubkey","coreCreateWallet","generateRecoverySalt","decryptAesGcm","deriveRecoveryKey","encryptAesGcm","emailHashBytes","c","generateX25519Keypair","unwrapSessionFragment2","reconstructFromPlainAndEncrypted","signSorobanAuthEntry","coreSignTransaction","reconstructKey"],"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 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 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 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 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 * `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 InMemoryDeviceStore,\n InMemorySessionStorage,\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 { 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 const sessionStorage: SessionStorage =\n props.overrides?.sessionStorage ?? new InMemorySessionStorage();\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 const refreshStatus = 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 };\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\nfunction initialStatus(storage: SessionStorage): AuthStatus {\n const tokens = storage.load();\n if (tokens instanceof Promise) return 'anonymous';\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 * 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 * `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 normalizeSecp256r1Pubkey,\n reconstructFromPlainAndEncrypted,\n reconstructKey,\n signSorobanAuthEntry,\n signTransaction as coreSignTransaction,\n unwrapSessionFragment2,\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\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\nexport interface WalletNamespace {\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\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 * Envía la rotación al backend tras que el caller haya construido la tx\n * `rotate_signer` y firmado el auth entry localmente.\n */\n submitFinalize(input: {\n recoveryJwt: string;\n unsignedXdr: 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 });\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 }, [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 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 submitFinalize(input) {\n return ctx.endpoints.finalizeRecovery(input.recoveryJwt, {\n unsignedXdr: input.unsignedXdr,\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],\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 * @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 CreatedWalletInfo,\n type CreateWalletInput,\n type EnsureWalletResult,\n type KycNamespace,\n type RecoveryNamespace,\n type RemoteWalletInfo,\n type RetryDeployResult,\n type SendXlmInput,\n type SendXlmResult,\n type SessionNamespace,\n type SettingsNamespace,\n type TxNamespace,\n type WalletNamespace,\n type WalletStatus,\n type YieldNamespace,\n} from './hooks/useAccesly.js';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/config.ts","../src/provider.tsx","../src/hooks/sorobanDeployStatus.ts","../src/hooks/useAccesly.ts","../src/index.ts"],"names":["createContext","useMemo","CognitoAuthClient","InMemorySessionStorage","InMemoryDeviceStore","TokenManager","AccesslyApiClient","AccesslyEndpoints","useState","useRef","useEffect","AccesslyApiError","useContext","computeSmartAccountAddress","normalizeSecp256r1Pubkey","coreCreateWallet","generateRecoverySalt","decryptAesGcm","deriveRecoveryKey","encryptAesGcm","emailHashBytes","c","generateX25519Keypair","unwrapSessionFragment2","reconstructFromPlainAndEncrypted","signSorobanAuthEntry","coreSignTransaction","reconstructKey"],"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 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 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 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 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 * `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 InMemoryDeviceStore,\n InMemorySessionStorage,\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 { 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 const sessionStorage: SessionStorage =\n props.overrides?.sessionStorage ?? new InMemorySessionStorage();\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 const refreshStatus = 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 };\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\nfunction initialStatus(storage: SessionStorage): AuthStatus {\n const tokens = storage.load();\n if (tokens instanceof Promise) return 'anonymous';\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 * 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 * `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 normalizeSecp256r1Pubkey,\n reconstructFromPlainAndEncrypted,\n reconstructKey,\n signSorobanAuthEntry,\n signTransaction as coreSignTransaction,\n unwrapSessionFragment2,\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\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\nexport interface WalletNamespace {\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 de la rotación\n * de signers tras una recuperación por OTP.\n *\n * El caller debe pre-cumplir 2 pasos UI:\n * a) `reconstructSeed(...)` — devolvió `privateSeed` (la VIEJA, va a firmar\n * la auth entry) + `publicKey` (la VIEJA, no se rota acá).\n * b) WebAuthn `navigator.credentials.create()` con PRF extension — devolvió\n * `credentialId`, `secp256r1Pubkey`, y un output PRF que el caller\n * derivó en 2 keys `newF1Key` + `newF2Key` (HKDF típicamente).\n *\n * El SDK hace todo lo demás client-side:\n * 1. Genera fresh ed25519 seed (la NUEVA) + Shamir 2-of-3 split.\n * 2. Cifra F1' con `newF1Key`, F2' con `newF2Key`, F3' con `recoveryKey`.\n * 3. Cifra una segunda copia de F2' con `recoveryKey` (F2_recovery) para\n * que la siguiente recovery siga siendo posible.\n * 4. POST /recovery/simulate-rotate-signer → backend simula + devuelve material.\n * 5. Firma la auth entry con la SEED VIEJA contra la regla `admin-cfg`.\n * 6. POST /recovery/finalize con auth entry firmada + new fragments.\n * 7. Persiste el nuevo `CredentialRecord` en `DeviceStore` (sustituye el viejo).\n * 8. Zeroiza todas las llaves intermedias (la seed vieja la entrega el caller,\n * su lifecycle es responsabilidad del caller).\n */\nexport interface FinalizeRecoveryInput {\n /** Email del usuario (case-insensitive, se normaliza). */\n readonly email: string;\n /**\n * Password de Cognito (UTF-8 bytes). El SDK la usa SOLO para derivar el\n * `newRecoveryKey` con `PBKDF2(password, newRecoverySalt, 600k)`. Caller\n * debe zeroizar tras la llamada.\n */\n readonly cognitoPassword: Uint8Array;\n /** Token KMS-HMAC que devolvió `verifyOtp()` — TTL 5min. */\n readonly recoveryJwt: string;\n /**\n * La seed VIEJA reconstruida por `reconstructSeed()`. Se usa SOLO para\n * firmar la `SorobanAuthorizationEntry` de `rotate_signer` (la regla\n * `admin-cfg` valida con el ed25519 pubkey actual del Smart Account, que\n * es el del owner viejo). Tras firmar, el SDK la zeroiza internamente.\n *\n * IMPORTANTE: pasa `seedResult.privateSeed` tal cual te lo dio\n * `reconstructSeed()`. Si ya lo zeroizaste, falla.\n */\n readonly oldReconstructedSeed: Uint8Array;\n /**\n * La pubkey VIEJA (32 bytes) — derivable de `oldReconstructedSeed`, pero\n * la pedimos explícita para sanity-check y para empaquetar dentro del\n * `Signer::External(verifier, pubkey)` del AuthPayload.\n */\n readonly oldOwnerPubkey: Uint8Array;\n /** Credential ID del nuevo passkey (de `navigator.credentials.create`). */\n readonly newCredentialId: Uint8Array;\n /** Pubkey secp256r1 uncompressed (65 bytes) del nuevo passkey. */\n readonly newSecp256r1Pubkey: Uint8Array;\n /** Salt PRF del nuevo passkey (32 bytes random). */\n readonly newPrfSalt: Uint8Array;\n /** AES-256 key derivada del PRF output para cifrar F1'. */\n readonly newF1Key: Uint8Array;\n /** AES-256 key derivada del PRF output para cifrar F2' (PRF-bound, sign path). */\n readonly newF2Key: Uint8Array;\n /** Salt aleatorio (32 bytes) para el nuevo emailCommitment. */\n readonly newEmailSalt: Uint8Array;\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 });\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 }, [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 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 // 0. Sanity check — oldOwnerPubkey debe derivarse de oldReconstructedSeed.\n // Si no matchea, el caller pasó pubkeys cruzadas o la seed está\n // corrupta — abortar antes de tocar la red.\n if (input.oldReconstructedSeed.length !== 32) {\n throw new Error(\n `recovery.finalize: oldReconstructedSeed must be 32 bytes, got ${input.oldReconstructedSeed.length}`,\n );\n }\n if (input.oldOwnerPubkey.length !== 32) {\n throw new Error(\n `recovery.finalize: oldOwnerPubkey must be 32 bytes, got ${input.oldOwnerPubkey.length}`,\n );\n }\n if (input.newSecp256r1Pubkey.length !== 65) {\n throw new Error(\n `recovery.finalize: newSecp256r1Pubkey must be 65 bytes (uncompressed), got ${input.newSecp256r1Pubkey.length}`,\n );\n }\n\n // 1. Generar NUEVA seed + new Shamir split.\n // F1' cifrado con newF1Key (PRF-bound, vive en device).\n // F2' cifrado con newF2Key (PRF-bound, vive en backend para sign normal).\n // F3' cifrado con newRecoveryKey — pero todavía no derivamos esa key\n // (necesita newRecoverySalt). Usamos un placeholder y re-ciframos\n // abajo con la real.\n const newRecoverySalt = generateRecoverySalt();\n const newRecoveryKey = deriveRecoveryKey({\n password: input.cognitoPassword,\n salt: newRecoverySalt,\n });\n const newRecoverySaltBase64 = base64FromBytes(newRecoverySalt);\n\n const created = coreCreateWallet({\n emailBytes: new TextEncoder().encode(input.email),\n emailSalt: input.newEmailSalt,\n encryptionKeys: [input.newF1Key, input.newF2Key, newRecoveryKey] as const,\n });\n\n // 2. Derivar F2' cifrado con newRecoveryKey (cipher-bound a recovery path).\n // Necesitamos descifrar F2' del envelope que produjo `coreCreateWallet`\n // y re-cifrarlo con newRecoveryKey. La seed plaintext NO se toca acá\n // — solo el SHARE plaintext.\n const f2PlainShare = decryptAesGcm(created.encryptedFragments[1], input.newF2Key);\n let newFragmentF2Recovery: EncryptedEnvelope;\n try {\n newFragmentF2Recovery = encryptAesGcm(f2PlainShare, newRecoveryKey);\n } finally {\n for (let i = 0; i < f2PlainShare.length; i += 1) f2PlainShare[i] = 0;\n }\n\n // 3. newEmailCommitment + newSecp256r1Pubkey canonical.\n const newSecp256r1Canonical = normalizeSecp256r1Pubkey(input.newSecp256r1Pubkey);\n const newOwnerHex = hexFromBytes(created.publicKey);\n const newSecpHex = hexFromBytes(newSecp256r1Canonical);\n const newEmailCommitHex = hexFromBytes(created.emailCommitment);\n\n // 4. POST /recovery/simulate-rotate-signer — backend arma + simula la\n // tx `rotate_signer(newOwner, newSecp256r1, newEmailCommit)`.\n const sim = await ctx.endpoints.simulateRotateSigner(input.recoveryJwt, {\n newOwnerEd25519Pubkey: newOwnerHex,\n newSecp256r1Pubkey: newSecpHex,\n newEmailCommitment: newEmailCommitHex,\n });\n\n // 5. Firmar la SorobanAuthorizationEntry con la SEED VIEJA contra la\n // regla `admin-cfg`. `signSorobanAuthEntry` zero-iza la seed\n // internamente tras firmar.\n const { signedAuthEntryXdr } = await signSorobanAuthEntry({\n signaturePayloadHashBase64: sim.signaturePayloadHashBase64,\n contextRuleIds: [...sim.contextRuleIds],\n placeholderAuthEntryXdr: sim.placeholderAuthEntryXdr,\n ed25519Seed: input.oldReconstructedSeed,\n ed25519VerifierAddress: verifierAddress,\n ownerPubkey: input.oldOwnerPubkey,\n });\n\n // 6. POST /recovery/finalize — backend re-simula + fee-bumps + submitea.\n let finalize;\n try {\n finalize = 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 key material aunque finalize falle.\n for (let i = 0; i < newRecoveryKey.length; i += 1) newRecoveryKey[i] = 0;\n }\n\n // 7. Persistir nuevo CredentialRecord local (sustituye el viejo).\n await ctx.deviceStore.saveCredential({\n username: input.email,\n credentialId: input.newCredentialId,\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: input.newPrfSalt,\n fallbackKeyMaterial: new Uint8Array(0),\n walletAddress: finalize.walletAddress,\n onChain: true,\n createdAt: Date.now(),\n });\n\n return {\n walletAddress: finalize.walletAddress,\n txHash: finalize.txHash,\n status: finalize.status,\n newPublicKey: created.publicKey,\n explorerUrl: `${explorerBase}${finalize.txHash}`,\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 * @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 CreatedWalletInfo,\n type CreateWalletInput,\n type EnsureWalletResult,\n type KycNamespace,\n type RecoveryNamespace,\n type RemoteWalletInfo,\n type RetryDeployResult,\n type SendXlmInput,\n type SendXlmResult,\n type SessionNamespace,\n type SettingsNamespace,\n type TxNamespace,\n type WalletNamespace,\n type WalletStatus,\n type YieldNamespace,\n} from './hooks/useAccesly.js';\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -454,6 +454,78 @@ interface ReconstructedSeed {
|
|
|
454
454
|
/** Base64 32-byte salt que vino del backend. */
|
|
455
455
|
readonly recoverySalt: string;
|
|
456
456
|
}
|
|
457
|
+
/**
|
|
458
|
+
* Input para `recovery.finalize(...)` — orquestador end-to-end de la rotación
|
|
459
|
+
* de signers tras una recuperación por OTP.
|
|
460
|
+
*
|
|
461
|
+
* El caller debe pre-cumplir 2 pasos UI:
|
|
462
|
+
* a) `reconstructSeed(...)` — devolvió `privateSeed` (la VIEJA, va a firmar
|
|
463
|
+
* la auth entry) + `publicKey` (la VIEJA, no se rota acá).
|
|
464
|
+
* b) WebAuthn `navigator.credentials.create()` con PRF extension — devolvió
|
|
465
|
+
* `credentialId`, `secp256r1Pubkey`, y un output PRF que el caller
|
|
466
|
+
* derivó en 2 keys `newF1Key` + `newF2Key` (HKDF típicamente).
|
|
467
|
+
*
|
|
468
|
+
* El SDK hace todo lo demás client-side:
|
|
469
|
+
* 1. Genera fresh ed25519 seed (la NUEVA) + Shamir 2-of-3 split.
|
|
470
|
+
* 2. Cifra F1' con `newF1Key`, F2' con `newF2Key`, F3' con `recoveryKey`.
|
|
471
|
+
* 3. Cifra una segunda copia de F2' con `recoveryKey` (F2_recovery) para
|
|
472
|
+
* que la siguiente recovery siga siendo posible.
|
|
473
|
+
* 4. POST /recovery/simulate-rotate-signer → backend simula + devuelve material.
|
|
474
|
+
* 5. Firma la auth entry con la SEED VIEJA contra la regla `admin-cfg`.
|
|
475
|
+
* 6. POST /recovery/finalize con auth entry firmada + new fragments.
|
|
476
|
+
* 7. Persiste el nuevo `CredentialRecord` en `DeviceStore` (sustituye el viejo).
|
|
477
|
+
* 8. Zeroiza todas las llaves intermedias (la seed vieja la entrega el caller,
|
|
478
|
+
* su lifecycle es responsabilidad del caller).
|
|
479
|
+
*/
|
|
480
|
+
interface FinalizeRecoveryInput {
|
|
481
|
+
/** Email del usuario (case-insensitive, se normaliza). */
|
|
482
|
+
readonly email: string;
|
|
483
|
+
/**
|
|
484
|
+
* Password de Cognito (UTF-8 bytes). El SDK la usa SOLO para derivar el
|
|
485
|
+
* `newRecoveryKey` con `PBKDF2(password, newRecoverySalt, 600k)`. Caller
|
|
486
|
+
* debe zeroizar tras la llamada.
|
|
487
|
+
*/
|
|
488
|
+
readonly cognitoPassword: Uint8Array;
|
|
489
|
+
/** Token KMS-HMAC que devolvió `verifyOtp()` — TTL 5min. */
|
|
490
|
+
readonly recoveryJwt: string;
|
|
491
|
+
/**
|
|
492
|
+
* La seed VIEJA reconstruida por `reconstructSeed()`. Se usa SOLO para
|
|
493
|
+
* firmar la `SorobanAuthorizationEntry` de `rotate_signer` (la regla
|
|
494
|
+
* `admin-cfg` valida con el ed25519 pubkey actual del Smart Account, que
|
|
495
|
+
* es el del owner viejo). Tras firmar, el SDK la zeroiza internamente.
|
|
496
|
+
*
|
|
497
|
+
* IMPORTANTE: pasa `seedResult.privateSeed` tal cual te lo dio
|
|
498
|
+
* `reconstructSeed()`. Si ya lo zeroizaste, falla.
|
|
499
|
+
*/
|
|
500
|
+
readonly oldReconstructedSeed: Uint8Array;
|
|
501
|
+
/**
|
|
502
|
+
* La pubkey VIEJA (32 bytes) — derivable de `oldReconstructedSeed`, pero
|
|
503
|
+
* la pedimos explícita para sanity-check y para empaquetar dentro del
|
|
504
|
+
* `Signer::External(verifier, pubkey)` del AuthPayload.
|
|
505
|
+
*/
|
|
506
|
+
readonly oldOwnerPubkey: Uint8Array;
|
|
507
|
+
/** Credential ID del nuevo passkey (de `navigator.credentials.create`). */
|
|
508
|
+
readonly newCredentialId: Uint8Array;
|
|
509
|
+
/** Pubkey secp256r1 uncompressed (65 bytes) del nuevo passkey. */
|
|
510
|
+
readonly newSecp256r1Pubkey: Uint8Array;
|
|
511
|
+
/** Salt PRF del nuevo passkey (32 bytes random). */
|
|
512
|
+
readonly newPrfSalt: Uint8Array;
|
|
513
|
+
/** AES-256 key derivada del PRF output para cifrar F1'. */
|
|
514
|
+
readonly newF1Key: Uint8Array;
|
|
515
|
+
/** AES-256 key derivada del PRF output para cifrar F2' (PRF-bound, sign path). */
|
|
516
|
+
readonly newF2Key: Uint8Array;
|
|
517
|
+
/** Salt aleatorio (32 bytes) para el nuevo emailCommitment. */
|
|
518
|
+
readonly newEmailSalt: Uint8Array;
|
|
519
|
+
}
|
|
520
|
+
interface FinalizeRecoveryResult {
|
|
521
|
+
readonly walletAddress: string;
|
|
522
|
+
readonly txHash: string;
|
|
523
|
+
readonly status: string;
|
|
524
|
+
/** Pubkey ed25519 NUEVA (32 bytes). Útil para UI confirmación. */
|
|
525
|
+
readonly newPublicKey: Uint8Array;
|
|
526
|
+
/** Link al explorer. */
|
|
527
|
+
readonly explorerUrl: string;
|
|
528
|
+
}
|
|
457
529
|
interface RecoveryNamespace {
|
|
458
530
|
/** Pide OTP. Backend rate-limita; el caller debe respetar `cooldownSeconds`. */
|
|
459
531
|
requestOtp(input: {
|
|
@@ -484,12 +556,19 @@ interface RecoveryNamespace {
|
|
|
484
556
|
recoveryJwt: string;
|
|
485
557
|
}): Promise<ReconstructedSeed>;
|
|
486
558
|
/**
|
|
487
|
-
*
|
|
488
|
-
* `
|
|
559
|
+
* Orquestador completo de la rotación de signers para Recovery v2.
|
|
560
|
+
* Ver `FinalizeRecoveryInput` para los pre-requisitos.
|
|
561
|
+
*/
|
|
562
|
+
finalize(input: FinalizeRecoveryInput): Promise<FinalizeRecoveryResult>;
|
|
563
|
+
/**
|
|
564
|
+
* Bajo nivel: submitea la rotación al backend tras que el caller haya
|
|
565
|
+
* armado el body manualmente. `finalize(...)` es el wrapper recomendado.
|
|
489
566
|
*/
|
|
490
567
|
submitFinalize(input: {
|
|
491
568
|
recoveryJwt: string;
|
|
492
569
|
unsignedXdr: string;
|
|
570
|
+
signedAuthEntryXdr: string;
|
|
571
|
+
newOwnerEd25519Pubkey: string;
|
|
493
572
|
newSecp256r1Pubkey: string;
|
|
494
573
|
newFragmentF1Encrypted: EncryptedEnvelope;
|
|
495
574
|
newFragmentF2Encrypted: EncryptedEnvelope;
|