decane-connect-kit 2.7.5 → 2.7.6

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/social/errors.ts","../src/core/emitter.ts","../src/core/registry.ts","../src/errors.ts","../src/constants.ts","../src/core/session.ts","../src/core/chainStore.ts","../src/evm/adapter.ts","../src/solana/adapter.ts","../src/tron/adapter.ts","../src/bitcoin/adapter.ts","../src/core/router.ts","../src/provider.ts","../src/evm/bitcoinSnap.ts","../src/evm/discovery.ts","../src/solana/discovery.ts","../src/tron/discovery.ts","../src/bitcoin/discovery.ts","../src/factory.ts","../src/social/client.ts","../src/social/events.ts","../src/social/api.ts","../src/social/storage.ts","../src/social/session.ts","../src/social/teeClient.ts","../src/social/attestation.ts","../../../infra/tee-measurement.json","../src/social/crypto/shares.ts","../src/social/crypto/wrap.ts","../src/social/crypto/pin.ts","../src/social/crypto/passkey.ts","../src/social/webauthnRegistration.ts","../src/social/auth/email.ts","../src/social/auth/kingschat.ts","../src/social/signers/evm.ts","../src/social/balance.ts","../src/social/eip1193.ts","../src/social/signers/solana.ts","../src/social/recovery/wrappedShareBackup.ts","../src/social/recovery/recoveryShareFile.ts","../src/social/recovery/recoveryFlow.ts","../src/social/recovery/portableBackup.ts","../src/social/index.ts","../src/ui/WalletSelector.tsx","../src/ui/styles.ts","../src/ui/icons.tsx","../src/ui/SocialWalletModal.tsx","../src/ui/context.tsx","../src/ui/StatusOverlay.tsx","../src/ui/hooks.ts"],"sourcesContent":["export class DecaneConnectError extends Error {\n code: string;\n retryable: boolean;\n constructor(code: string, message: string, retryable = false) {\n super(message);\n this.name = 'DecaneConnectError';\n this.code = code;\n this.retryable = retryable;\n }\n}\n\nexport class InvalidApiKeyError extends DecaneConnectError {\n constructor() { super('INVALID_API_KEY', 'API key is invalid or revoked'); }\n}\nexport class OriginNotAllowedError extends DecaneConnectError {\n constructor(origin: string) { super('ORIGIN_NOT_ALLOWED', `Origin ${origin} not in API key allowlist`); }\n}\nexport class SessionExpiredError extends DecaneConnectError {\n constructor() { super('SESSION_EXPIRED', 'Session has expired — call unlock()', true); }\n}\nexport class UnlockRequiredError extends DecaneConnectError {\n constructor() { super('UNLOCK_REQUIRED', 'Wallet must be unlocked before signing', true); }\n}\n/**\n * unlock() was called after a page reload (or any other loss of the in-memory\n * auth state). We still know *who* the user is — their identity and addresses\n * are persisted — but unlock() needs a live JWT to open a TEE session, and\n * JWTs are deliberately never persisted. So there is no unlock() that can\n * succeed here; the user has to re-authenticate.\n *\n * This is its own error type rather than a generic CallSequenceError because\n * it is a *routing* signal, not a programming mistake: the correct response is\n * to show the sign-in UI, which callers can only do reliably if they can tell\n * this case apart from \"you never called connect()\". Prefer checking\n * needsReconnect() up front so this never has to be caught at all.\n */\nexport class ReconnectRequiredError extends DecaneConnectError {\n constructor() {\n super(\n 'RECONNECT_REQUIRED',\n 'Your session ended — sign in again to unlock this wallet',\n true\n );\n }\n}\nexport class UserCancelledError extends DecaneConnectError {\n constructor() { super('USER_CANCELLED', 'User cancelled the operation', true); }\n}\nexport class WebAuthnNotSupportedError extends DecaneConnectError {\n constructor() { super('WEBAUTHN_UNSUPPORTED', 'This browser does not support WebAuthn'); }\n}\nexport class InvalidPinError extends DecaneConnectError {\n constructor() { super('INVALID_PIN', 'Incorrect PIN', true); }\n}\nexport class CallSequenceError extends DecaneConnectError {\n constructor(msg: string) { super('CALL_SEQUENCE', msg); }\n}\nexport class NetworkError extends DecaneConnectError {\n constructor() { super('NETWORK', 'Network request failed', true); }\n}\nexport class ShareCorruptedError extends DecaneConnectError {\n constructor() { super('SHARE_CORRUPTED', 'Stored device share is corrupted'); }\n}\n/**\n * Wallet creation exceeded its time budget.\n *\n * Provisioning is bounded so a stalled network or an unresponsive enclave\n * surfaces as an error the app can act on, rather than a signup that appears to\n * hang forever. The budget covers only the SDK's own work — key generation,\n * share storage, opening the signer session — never time spent waiting on the\n * user (a passkey prompt, choosing a PIN, the recovery-file dialog).\n *\n * Retryable: nothing is left half-created that a later sign-in cannot complete.\n */\nexport class ProvisioningTimeoutError extends DecaneConnectError {\n constructor(step: string) {\n super('PROVISIONING_TIMEOUT', `Wallet setup timed out while ${step}. Check your connection and try again.`, true);\n }\n}\nexport class NewDeviceError extends DecaneConnectError {\n constructor() { super('NEW_DEVICE', 'No device share found. Re-authenticate to set up this device.'); }\n}\n/**\n * The device share this device just used no longer reconstructs the account's\n * real key — almost always because another device recovered via passkey sync\n * since and rotated the whole share set (see rotateOnNewDeviceRecovery in\n * DecaneConnectConfig), silently invalidating every other device's cached\n * copy. Thrown instead of signing: two mismatched shares from different\n * share-set versions still combine to *something*, just not the user's real\n * key, so continuing would risk operating on a wrong (though not\n * attacker-chosen) address. The stale local share is cleared by the caller\n * before this propagates, so the next connect() naturally falls through to\n * recovery instead of repeating the same failure.\n */\nexport class StaleDeviceShareError extends DecaneConnectError {\n constructor() {\n super(\n 'STALE_DEVICE_SHARE',\n 'This device’s wallet share is from a superseded share set (likely rotated from another device) and no longer matches this account. Reconnect to recover a fresh share.',\n true\n );\n }\n}\nexport class PromptPinNotConfiguredError extends DecaneConnectError {\n constructor() { super('PROMPT_PIN_NOT_CONFIGURED', 'Passkey unavailable and no promptPin callback was provided in config'); }\n}\nexport class AttestationError extends DecaneConnectError {\n constructor(msg: string) { super('ATTESTATION_FAILED', msg); }\n}\nexport class RecoveryFailedError extends DecaneConnectError {\n constructor(reason: string) { super('RECOVERY_FAILED', `Recovery failed: ${reason}`, true); }\n}\nexport class InvalidRecoveryFileError extends DecaneConnectError {\n constructor() { super('INVALID_RECOVERY_FILE', 'This does not look like a valid recovery file', false); }\n}\nexport class WrongPasswordError extends DecaneConnectError {\n constructor() { super('WRONG_PASSWORD', 'Incorrect password for this recovery file', true); }\n}\nexport class RecoveryWalletMismatchError extends DecaneConnectError {\n constructor() {\n super(\n 'RECOVERY_WALLET_MISMATCH',\n 'This recovery file is for a different wallet than the account you are signed into',\n false\n );\n }\n}\nexport class ExportNotAuthorizedError extends DecaneConnectError {\n constructor() { super('EXPORT_NOT_AUTHORIZED', 'Export requires a fresh security check', true); }\n}\n","type Handler = (...args: unknown[]) => void;\n\nexport interface Emitter {\n on(event: string, handler: Handler): void;\n off(event: string, handler: Handler): void;\n emit(event: string, ...args: unknown[]): void;\n}\n\nexport function createEmitter(): Emitter {\n const listeners = new Map<string, Set<Handler>>();\n\n return {\n on(event, handler) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n },\n\n off(event, handler) {\n listeners.get(event)?.delete(handler);\n },\n\n emit(event, ...args) {\n listeners.get(event)?.forEach((h) => h(...args));\n },\n };\n}\n","import type {\n RawWalletEntry,\n UnifiedWalletAccount,\n ChainSupport,\n EIP1193Provider,\n StandardWallet,\n TronProvider,\n BitcoinProvider,\n} from \"../types\";\nimport type { Emitter } from \"./emitter\";\n\nexport interface Registry {\n registerOrMerge(incoming: RawWalletEntry): void;\n unregister(provider: StandardWallet): void;\n get: {\n all(): UnifiedWalletAccount[];\n evm(): UnifiedWalletAccount[];\n solana(): UnifiedWalletAccount[];\n tron(): UnifiedWalletAccount[];\n bitcoin(): UnifiedWalletAccount[];\n multiChain(): UnifiedWalletAccount[];\n byId(id: string): UnifiedWalletAccount | undefined;\n };\n}\n\nexport function createRegistry(emitter: Emitter): Registry {\n const wallets: UnifiedWalletAccount[] = [];\n\n function normaliseName(name: string): string {\n return name\n .toLowerCase()\n .replace(/\\s+/g, \"\")\n .replace(/wallet$/, \"\");\n }\n\n function toUnified(incoming: RawWalletEntry): UnifiedWalletAccount {\n const id =\n incoming.rdns ??\n incoming.uuid ??\n normaliseName(incoming.name);\n\n const account: UnifiedWalletAccount = {\n id,\n name: incoming.name,\n icon: incoming.icon,\n rdns: incoming.rdns,\n chainSupport: [incoming.chain] as unknown as ChainSupport,\n };\n\n if (incoming.chain === \"evm\") {\n account.evmProvider = incoming.provider as EIP1193Provider;\n } else if (incoming.chain === \"solana\") {\n account.solanaProvider = incoming.provider as StandardWallet;\n } else if (incoming.chain === \"tron\") {\n account.tronProvider = incoming.provider as TronProvider;\n } else if (incoming.chain === \"bitcoin\") {\n account.bitcoinProvider = incoming.provider as BitcoinProvider;\n }\n\n return account;\n }\n\n function mergeInto(\n existing: UnifiedWalletAccount,\n incoming: RawWalletEntry,\n ): void {\n if (!existing.chainSupport.includes(incoming.chain)) {\n existing.chainSupport = [\n ...existing.chainSupport,\n incoming.chain,\n ].sort() as ChainSupport;\n }\n if (incoming.chain === \"evm\") existing.evmProvider = incoming.provider as EIP1193Provider;\n if (incoming.chain === \"solana\") existing.solanaProvider = incoming.provider as StandardWallet;\n if (incoming.chain === \"tron\") existing.tronProvider = incoming.provider as TronProvider;\n if (incoming.chain === \"bitcoin\") existing.bitcoinProvider = incoming.provider as BitcoinProvider;\n if (!existing.icon && incoming.icon) existing.icon = incoming.icon;\n }\n\n function registerOrMerge(incoming: RawWalletEntry): void {\n // 1. Match by rdns (primary merge key — both sides have rdns and it matches)\n if (incoming.rdns) {\n const existing = wallets.find((w) => w.rdns === incoming.rdns);\n if (existing) {\n mergeInto(existing, incoming);\n emitter.emit(\"walletUpdated\", existing);\n return;\n }\n }\n\n // 2. Match by normalised name — fallback for when rdns didn't match or\n // the incoming entry (typically a Solana Wallet Standard wallet) has no\n // rdns. Solana wallets rarely expose rdns, so this is the normal merge\n // path for multi-chain wallets like Backpack, Phantom, MetaMask.\n if (!incoming.rdns) {\n const norm = normaliseName(incoming.name);\n const existing = wallets.find(\n (w) => normaliseName(w.name) === norm,\n );\n if (existing) {\n mergeInto(existing, incoming);\n emitter.emit(\"walletUpdated\", existing);\n return;\n }\n }\n\n // 3. New wallet\n const account = toUnified(incoming);\n wallets.push(account);\n emitter.emit(\"walletRegistered\", account);\n }\n\n function unregister(provider: StandardWallet): void {\n const idx = wallets.findIndex((w) => w.solanaProvider === provider);\n if (idx === -1) return;\n const entry = wallets[idx];\n if (entry.chainSupport.length === 1) {\n wallets.splice(idx, 1);\n emitter.emit(\"walletUnregistered\", entry);\n } else {\n entry.chainSupport = [\"evm\"];\n entry.solanaProvider = undefined;\n emitter.emit(\"walletUpdated\", entry);\n }\n }\n\n return {\n registerOrMerge,\n unregister,\n get: {\n all: () => [...wallets],\n evm: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"evm\")),\n solana: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"solana\")),\n tron: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"tron\")),\n bitcoin: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"bitcoin\")),\n multiChain: () => wallets.filter((w) => w.chainSupport.length >= 2),\n byId: (id) => wallets.find((w) => w.id === id),\n },\n };\n}\n","export class DecaneError extends Error {\n constructor(\n public code: DecaneErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"DecaneError\";\n }\n}\n\nexport enum DecaneErrorCode {\n // CAIP-25 standard codes\n USER_REJECTED = 4001,\n UNAUTHORIZED = 4100,\n\n // Session\n NO_ACTIVE_SESSION = 5001,\n SCOPE_MISMATCH = 5002,\n SESSION_EXPIRED = 5003,\n\n // Chain\n UNSUPPORTED_CHAIN = 5010,\n CHAIN_NOT_IN_SCOPE = 5011,\n INVALID_CHAIN_CONFIG = 5012,\n\n // Wallet\n NO_WALLET_CONNECTED = 5020,\n WALLET_DISCONNECTED = 5021,\n PROVIDER_ERROR = 5022,\n\n // Method\n METHOD_NOT_SUPPORTED = 5030,\n EVM_ONLY_METHOD = 5031,\n}\n","import type { ChainDescriptor, ChainType } from \"./types\";\n\n// ── Built-in chains ───────────────────────────────────────────────────────────\n\nconst ETH = { name: \"Ether\", symbol: \"ETH\", decimals: 18 };\nconst SOL = { name: \"SOL\", symbol: \"SOL\", decimals: 9 };\n\nexport const BUILT_IN_CHAINS: ChainDescriptor[] = [\n // ── Tier-1 EVM ──────────────────────────────────────────────────────────────\n {\n id: \"eip155:1\",\n type: \"evm\",\n name: \"Ethereum\",\n chainId: 1,\n nativeCurrency: ETH,\n rpcUrl: \"https://cloudflare-eth.com\",\n blockExplorerUrl: \"https://etherscan.io\",\n },\n {\n id: \"eip155:8453\",\n type: \"evm\",\n name: \"Base\",\n chainId: 8453,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.base.org\",\n blockExplorerUrl: \"https://basescan.org\",\n },\n {\n id: \"eip155:42161\",\n type: \"evm\",\n name: \"Arbitrum One\",\n chainId: 42161,\n nativeCurrency: ETH,\n rpcUrl: \"https://arb1.arbitrum.io/rpc\",\n blockExplorerUrl: \"https://arbiscan.io\",\n },\n {\n id: \"eip155:10\",\n type: \"evm\",\n name: \"Optimism\",\n chainId: 10,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.optimism.io\",\n blockExplorerUrl: \"https://optimistic.etherscan.io\",\n },\n {\n id: \"eip155:56\",\n type: \"evm\",\n name: \"BNB Chain\",\n chainId: 56,\n nativeCurrency: { name: \"BNB\", symbol: \"BNB\", decimals: 18 },\n rpcUrl: \"https://bsc-dataseed.binance.org\",\n blockExplorerUrl: \"https://bscscan.com\",\n },\n {\n id: \"eip155:137\",\n type: \"evm\",\n name: \"Polygon\",\n chainId: 137,\n nativeCurrency: { name: \"MATIC\", symbol: \"MATIC\", decimals: 18 },\n rpcUrl: \"https://polygon-rpc.com\",\n blockExplorerUrl: \"https://polygonscan.com\",\n },\n\n // ── Extended EVM ecosystem ───────────────────────────────────────────────────\n {\n id: \"eip155:2741\",\n type: \"evm\",\n name: \"Abstract\",\n chainId: 2741,\n nativeCurrency: ETH,\n rpcUrl: \"https://api.mainnet.abs.xyz\",\n blockExplorerUrl: \"https://abscan.org\",\n },\n {\n id: \"eip155:888888888\",\n type: \"evm\",\n name: \"Ancient8\",\n chainId: 888888888,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.ancient8.gg\",\n blockExplorerUrl: \"https://scan.ancient8.gg\",\n },\n {\n id: \"eip155:69000\",\n type: \"evm\",\n name: \"Animechain\",\n chainId: 69000,\n nativeCurrency: { name: \"Anime\", symbol: \"ANIME\", decimals: 18 },\n rpcUrl: \"https://rpc.animechain.ai\",\n blockExplorerUrl: \"https://explorer.animechain.ai\",\n },\n {\n id: \"eip155:33139\",\n type: \"evm\",\n name: \"ApeChain\",\n chainId: 33139,\n nativeCurrency: { name: \"ApeCoin\", symbol: \"APE\", decimals: 18 },\n rpcUrl: \"https://rpc.apechain.com/http\",\n blockExplorerUrl: \"https://apescan.io\",\n },\n {\n id: \"eip155:42170\",\n type: \"evm\",\n name: \"Arbitrum Nova\",\n chainId: 42170,\n nativeCurrency: ETH,\n rpcUrl: \"https://nova.arbitrum.io/rpc\",\n blockExplorerUrl: \"https://nova.arbiscan.io\",\n },\n {\n id: \"eip155:43114\",\n type: \"evm\",\n name: \"Avalanche\",\n chainId: 43114,\n nativeCurrency: { name: \"Avalanche\", symbol: \"AVAX\", decimals: 18 },\n rpcUrl: \"https://api.avax.network/ext/bc/C/rpc\",\n blockExplorerUrl: \"https://snowtrace.io\",\n },\n {\n id: \"eip155:8333\",\n type: \"evm\",\n name: \"B3\",\n chainId: 8333,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet-rpc.b3.fun/http\",\n blockExplorerUrl: \"https://explorer.b3.fun\",\n },\n {\n id: \"eip155:80094\",\n type: \"evm\",\n name: \"Berachain\",\n chainId: 80094,\n nativeCurrency: { name: \"BERA\", symbol: \"BERA\", decimals: 18 },\n rpcUrl: \"https://rpc.berachain.com\",\n blockExplorerUrl: \"https://berascan.com\",\n },\n {\n id: \"eip155:81457\",\n type: \"evm\",\n name: \"Blast\",\n chainId: 81457,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.blast.io\",\n blockExplorerUrl: \"https://blastscan.io\",\n },\n {\n id: \"eip155:60808\",\n type: \"evm\",\n name: \"BOB\",\n chainId: 60808,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.gobob.xyz\",\n blockExplorerUrl: \"https://explorer.gobob.xyz\",\n },\n {\n id: \"eip155:288\",\n type: \"evm\",\n name: \"Boba Network\",\n chainId: 288,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.boba.network\",\n blockExplorerUrl: \"https://bobascan.com\",\n },\n {\n id: \"eip155:42220\",\n type: \"evm\",\n name: \"Celo\",\n chainId: 42220,\n nativeCurrency: { name: \"CELO\", symbol: \"CELO\", decimals: 18 },\n rpcUrl: \"https://forno.celo.org\",\n blockExplorerUrl: \"https://celoscan.io\",\n },\n {\n id: \"eip155:21000000\",\n type: \"evm\",\n name: \"Corn\",\n chainId: 21000000,\n nativeCurrency: { name: \"Bitcorn\", symbol: \"BTCN\", decimals: 18 },\n rpcUrl: \"https://mainnet.corn-rpc.com\",\n blockExplorerUrl: \"https://cornscan.io\",\n },\n {\n id: \"eip155:25\",\n type: \"evm\",\n name: \"Cronos\",\n chainId: 25,\n nativeCurrency: { name: \"Cronos\", symbol: \"CRO\", decimals: 18 },\n rpcUrl: \"https://evm.cronos.org\",\n blockExplorerUrl: \"https://cronoscan.com\",\n },\n {\n id: \"eip155:7560\",\n type: \"evm\",\n name: \"Cyber\",\n chainId: 7560,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.cyber.co\",\n blockExplorerUrl: \"https://cyberscan.co\",\n },\n {\n id: \"eip155:666666666\",\n type: \"evm\",\n name: \"Degen\",\n chainId: 666666666,\n nativeCurrency: { name: \"Degen\", symbol: \"DEGEN\", decimals: 18 },\n rpcUrl: \"https://rpc.degen.tips\",\n blockExplorerUrl: \"https://explorer.degen.tips\",\n },\n {\n id: \"eip155:747\",\n type: \"evm\",\n name: \"Flow EVM\",\n chainId: 747,\n nativeCurrency: { name: \"Flow\", symbol: \"FLOW\", decimals: 18 },\n rpcUrl: \"https://mainnet.evm.nodes.onflow.org\",\n blockExplorerUrl: \"https://flowdiver.io\",\n },\n {\n id: \"eip155:100\",\n type: \"evm\",\n name: \"Gnosis\",\n chainId: 100,\n nativeCurrency: { name: \"xDai\", symbol: \"xDAI\", decimals: 18 },\n rpcUrl: \"https://rpc.gnosischain.com\",\n blockExplorerUrl: \"https://gnosisscan.io\",\n },\n {\n id: \"eip155:49321\",\n type: \"evm\",\n name: \"Gunz\",\n chainId: 49321,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.gunz.dev/ext/bc/evm\",\n blockExplorerUrl: \"https://explorer.gunz.dev\",\n },\n {\n id: \"eip155:43111\",\n type: \"evm\",\n name: \"Hemi\",\n chainId: 43111,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.hemi.network/rpc\",\n blockExplorerUrl: \"https://explorer.hemi.xyz\",\n },\n {\n id: \"eip155:999\",\n type: \"evm\",\n name: \"HyperEVM\",\n chainId: 999,\n nativeCurrency: { name: \"HYPE\", symbol: \"HYPE\", decimals: 18 },\n rpcUrl: \"https://rpc.hyperliquid.xyz/evm\",\n blockExplorerUrl: \"https://hyperevm-explorer.hyperliquid.xyz\",\n },\n {\n id: \"eip155:57073\",\n type: \"evm\",\n name: \"Ink\",\n chainId: 57073,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc-gel.inkonchain.com\",\n blockExplorerUrl: \"https://explorer.inkonchain.com\",\n },\n {\n id: \"eip155:59144\",\n type: \"evm\",\n name: \"Linea\",\n chainId: 59144,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.linea.build\",\n blockExplorerUrl: \"https://lineascan.build\",\n },\n {\n id: \"eip155:1135\",\n type: \"evm\",\n name: \"Lisk\",\n chainId: 1135,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.api.lisk.com\",\n blockExplorerUrl: \"https://blockscout.lisk.com\",\n },\n {\n id: \"eip155:169\",\n type: \"evm\",\n name: \"Manta Pacific\",\n chainId: 169,\n nativeCurrency: ETH,\n rpcUrl: \"https://pacific-rpc.manta.network/http\",\n blockExplorerUrl: \"https://pacific-explorer.manta.network\",\n },\n {\n id: \"eip155:5000\",\n type: \"evm\",\n name: \"Mantle\",\n chainId: 5000,\n nativeCurrency: { name: \"MNT\", symbol: \"MNT\", decimals: 18 },\n rpcUrl: \"https://rpc.mantle.xyz\",\n blockExplorerUrl: \"https://explorer.mantle.xyz\",\n },\n {\n id: \"eip155:6342\",\n type: \"evm\",\n name: \"MegaETH\",\n chainId: 6342,\n nativeCurrency: ETH,\n rpcUrl: \"https://carrot.megaeth.com\",\n blockExplorerUrl: \"https://megaexplorer.xyz\",\n },\n {\n id: \"eip155:1088\",\n type: \"evm\",\n name: \"Metis\",\n chainId: 1088,\n nativeCurrency: { name: \"Metis\", symbol: \"METIS\", decimals: 18 },\n rpcUrl: \"https://andromeda.metis.io/?owner=1088\",\n blockExplorerUrl: \"https://andromeda-explorer.metis.io\",\n },\n {\n id: \"eip155:34443\",\n type: \"evm\",\n name: \"Mode\",\n chainId: 34443,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.mode.network\",\n blockExplorerUrl: \"https://modescan.io\",\n },\n {\n id: \"eip155:10143\",\n type: \"evm\",\n name: \"Monad\",\n chainId: 10143,\n nativeCurrency: { name: \"MON\", symbol: \"MON\", decimals: 18 },\n rpcUrl: \"https://testnet-rpc.monad.xyz\",\n blockExplorerUrl: \"https://testnet.monadexplorer.com\",\n },\n {\n id: \"eip155:2818\",\n type: \"evm\",\n name: \"Morph\",\n chainId: 2818,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc-quicknode.morphl2.io\",\n blockExplorerUrl: \"https://explorer.morphl2.io\",\n },\n {\n id: \"eip155:98866\",\n type: \"evm\",\n name: \"Plume\",\n chainId: 98866,\n nativeCurrency: { name: \"Plume\", symbol: \"PLUME\", decimals: 18 },\n rpcUrl: \"https://rpc.plume.org\",\n blockExplorerUrl: \"https://explorer.plume.org\",\n },\n {\n id: \"eip155:1380012617\",\n type: \"evm\",\n name: \"RARI\",\n chainId: 1380012617,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.rpc.rarichain.org/ext/bc/C/rpc\",\n blockExplorerUrl: \"https://mainnet.explorer.rarichain.org\",\n },\n {\n id: \"eip155:690\",\n type: \"evm\",\n name: \"Redstone\",\n chainId: 690,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.redstonechain.com\",\n blockExplorerUrl: \"https://explorer.redstone.xyz\",\n },\n {\n id: \"eip155:2020\",\n type: \"evm\",\n name: \"Ronin\",\n chainId: 2020,\n nativeCurrency: { name: \"RON\", symbol: \"RON\", decimals: 18 },\n rpcUrl: \"https://api.roninchain.com/rpc\",\n blockExplorerUrl: \"https://app.roninchain.com\",\n },\n {\n id: \"eip155:534352\",\n type: \"evm\",\n name: \"Scroll\",\n chainId: 534352,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.scroll.io\",\n blockExplorerUrl: \"https://scrollscan.com\",\n },\n {\n id: \"eip155:1329\",\n type: \"evm\",\n name: \"Sei\",\n chainId: 1329,\n nativeCurrency: { name: \"Sei\", symbol: \"SEI\", decimals: 18 },\n rpcUrl: \"https://evm-rpc.sei-apis.com\",\n blockExplorerUrl: \"https://seistream.app\",\n },\n {\n id: \"eip155:360\",\n type: \"evm\",\n name: \"Shape\",\n chainId: 360,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.shape.network\",\n blockExplorerUrl: \"https://shapescan.xyz\",\n },\n {\n id: \"eip155:50312\",\n type: \"evm\",\n name: \"Somnia\",\n chainId: 50312,\n nativeCurrency: { name: \"STT\", symbol: \"STT\", decimals: 18 },\n rpcUrl: \"https://dream-rpc.somnia.network\",\n blockExplorerUrl: \"https://shannon-explorer.somnia.network\",\n },\n {\n id: \"eip155:1868\",\n type: \"evm\",\n name: \"Soneium\",\n chainId: 1868,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.soneium.org\",\n blockExplorerUrl: \"https://soneium.blockscout.com\",\n },\n {\n id: \"eip155:146\",\n type: \"evm\",\n name: \"Sonic\",\n chainId: 146,\n nativeCurrency: { name: \"Sonic\", symbol: \"S\", decimals: 18 },\n rpcUrl: \"https://rpc.soniclabs.com\",\n blockExplorerUrl: \"https://sonicscan.org\",\n },\n {\n id: \"eip155:1514\",\n type: \"evm\",\n name: \"Story\",\n chainId: 1514,\n nativeCurrency: { name: \"IP\", symbol: \"IP\", decimals: 18 },\n rpcUrl: \"https://mainnet.storyrpc.io\",\n blockExplorerUrl: \"https://storyscan.xyz\",\n },\n {\n id: \"eip155:55244\",\n type: \"evm\",\n name: \"Superposition\",\n chainId: 55244,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.superposition.so\",\n blockExplorerUrl: \"https://explorer.superposition.so\",\n },\n {\n id: \"eip155:5330\",\n type: \"evm\",\n name: \"Superseed\",\n chainId: 5330,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.superseed.xyz\",\n blockExplorerUrl: \"https://explorer.superseed.xyz\",\n },\n {\n id: \"eip155:1923\",\n type: \"evm\",\n name: \"SwellChain\",\n chainId: 1923,\n nativeCurrency: ETH,\n rpcUrl: \"https://swell-mainnet.alt.technology\",\n blockExplorerUrl: \"https://explorer.swellnetwork.io\",\n },\n {\n id: \"eip155:167000\",\n type: \"evm\",\n name: \"Taiko\",\n chainId: 167000,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.mainnet.taiko.xyz\",\n blockExplorerUrl: \"https://taikoscan.io\",\n },\n {\n id: \"eip155:130\",\n type: \"evm\",\n name: \"Unichain\",\n chainId: 130,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.unichain.org\",\n blockExplorerUrl: \"https://uniscan.xyz\",\n },\n {\n id: \"eip155:480\",\n type: \"evm\",\n name: \"World Chain\",\n chainId: 480,\n nativeCurrency: ETH,\n rpcUrl: \"https://worldchain-mainnet.g.alchemy.com/public\",\n blockExplorerUrl: \"https://worldchain-mainnet.explorer.alchemy.com\",\n },\n {\n id: \"eip155:543210\",\n type: \"evm\",\n name: \"ZERO\",\n chainId: 543210,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.zerion.io/v1/zero\",\n blockExplorerUrl: \"https://explorer.zero.network\",\n },\n {\n id: \"eip155:48900\",\n type: \"evm\",\n name: \"Zircuit\",\n chainId: 48900,\n nativeCurrency: ETH,\n rpcUrl: \"https://zircuit1-mainnet.p2pify.com\",\n blockExplorerUrl: \"https://explorer.zircuit.com\",\n },\n {\n id: \"eip155:324\",\n type: \"evm\",\n name: \"zkSync Era\",\n chainId: 324,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.era.zksync.io\",\n blockExplorerUrl: \"https://explorer.zksync.io\",\n },\n {\n id: \"eip155:7777777\",\n type: \"evm\",\n name: \"Zora\",\n chainId: 7777777,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.zora.energy\",\n blockExplorerUrl: \"https://explorer.zora.energy\",\n },\n\n // ── Dev / local ──────────────────────────────────────────────────────────────\n {\n id: \"eip155:31337\",\n type: \"evm\",\n name: \"Localhost\",\n chainId: 31337,\n nativeCurrency: ETH,\n rpcUrl: \"http://localhost:8545\",\n isCustom: true,\n },\n\n // ── Solana ───────────────────────────────────────────────────────────────────\n {\n id: \"solana:mainnet\",\n type: \"solana\",\n name: \"Solana\",\n nativeCurrency: SOL,\n blockExplorerUrl: \"https://solscan.io\",\n },\n {\n id: \"solana:devnet\",\n type: \"solana\",\n name: \"Solana Devnet\",\n nativeCurrency: SOL,\n blockExplorerUrl: \"https://solscan.io/?cluster=devnet\",\n },\n\n // ── Tron ─────────────────────────────────────────────────────────────────────\n {\n id: \"tron:mainnet\",\n type: \"tron\",\n name: \"Tron\",\n nativeCurrency: { name: \"Tronix\", symbol: \"TRX\", decimals: 6 },\n blockExplorerUrl: \"https://tronscan.org\",\n },\n {\n id: \"tron:shasta\",\n type: \"tron\",\n name: \"Tron Shasta Testnet\",\n nativeCurrency: { name: \"Tronix\", symbol: \"TRX\", decimals: 6 },\n blockExplorerUrl: \"https://shasta.tronscan.org\",\n isCustom: true,\n },\n\n // ── Bitcoin ───────────────────────────────────────────────────────────────────\n {\n id: \"bip122:mainnet\",\n type: \"bitcoin\",\n name: \"Bitcoin\",\n nativeCurrency: { name: \"Bitcoin\", symbol: \"BTC\", decimals: 8 },\n blockExplorerUrl: \"https://blockstream.info\",\n },\n];\n\n// ── CAIP-2 helpers ────────────────────────────────────────────────────────────\n\nexport function toCAIP2(type: \"evm\", chainId: number): string;\nexport function toCAIP2(type: \"solana\", network: \"mainnet\" | \"devnet\"): string;\nexport function toCAIP2(type: string, id: string | number): string {\n if (type === \"evm\") return `eip155:${id}`;\n if (type === \"solana\") return `solana:${id}`;\n throw new Error(`Unknown chain type: ${type}`);\n}\n\nexport function getChainType(caip2Id: string): ChainType {\n if (caip2Id.startsWith(\"eip155:\")) return \"evm\";\n if (caip2Id.startsWith(\"solana:\")) return \"solana\";\n if (caip2Id.startsWith(\"tron:\")) return \"tron\";\n if (caip2Id.startsWith(\"bip122:\")) return \"bitcoin\";\n throw new Error(`Cannot determine chain type from: ${caip2Id}`);\n}\n\n// ── CAIP-10 helpers ───────────────────────────────────────────────────────────\n\nexport function toCAIP10(chainId: string, address: string): string {\n return `${chainId}:${address}`;\n}\n\nexport function fromCAIP10(account: string): { chainId: string; address: string } {\n const i = account.lastIndexOf(\":\");\n return { chainId: account.slice(0, i), address: account.slice(i + 1) };\n}\n\n// ── Method sets ───────────────────────────────────────────────────────────────\n\nexport const EVM_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n \"wallet_signTypedData\",\n]);\n\nexport const SOLANA_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n // wallet_signTypedData is EVM-only — never included here\n]);\n\nexport const TRON_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n]);\n\nexport const BITCOIN_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n]);\n\n// ── Named chain ID constants ──────────────────────────────────────────────────\n\nexport const CHAINS = {\n // Tier-1\n ETHEREUM: \"eip155:1\",\n BASE: \"eip155:8453\",\n ARBITRUM: \"eip155:42161\",\n OPTIMISM: \"eip155:10\",\n BNB: \"eip155:56\",\n POLYGON: \"eip155:137\",\n // Extended EVM\n ABSTRACT: \"eip155:2741\",\n ANCIENT8: \"eip155:888888888\",\n ANIMECHAIN: \"eip155:69000\",\n APE_CHAIN: \"eip155:33139\",\n ARBITRUM_NOVA: \"eip155:42170\",\n AVALANCHE: \"eip155:43114\",\n B3: \"eip155:8333\",\n BERACHAIN: \"eip155:80094\",\n BLAST: \"eip155:81457\",\n BOB: \"eip155:60808\",\n BOBA: \"eip155:288\",\n CELO: \"eip155:42220\",\n CORN: \"eip155:21000000\",\n CRONOS: \"eip155:25\",\n CYBER: \"eip155:7560\",\n DEGEN: \"eip155:666666666\",\n FLOW_EVM: \"eip155:747\",\n GNOSIS: \"eip155:100\",\n GUNZ: \"eip155:49321\",\n HEMI: \"eip155:43111\",\n HYPER_EVM: \"eip155:999\",\n INK: \"eip155:57073\",\n LINEA: \"eip155:59144\",\n LISK: \"eip155:1135\",\n MANTA_PACIFIC: \"eip155:169\",\n MANTLE: \"eip155:5000\",\n MEGA_ETH: \"eip155:6342\",\n METIS: \"eip155:1088\",\n MODE: \"eip155:34443\",\n MONAD: \"eip155:10143\",\n MORPH: \"eip155:2818\",\n PLUME: \"eip155:98866\",\n RARI: \"eip155:1380012617\",\n REDSTONE: \"eip155:690\",\n RONIN: \"eip155:2020\",\n SCROLL: \"eip155:534352\",\n SEI: \"eip155:1329\",\n SHAPE: \"eip155:360\",\n SOMNIA: \"eip155:50312\",\n SONEIUM: \"eip155:1868\",\n SONIC: \"eip155:146\",\n STORY: \"eip155:1514\",\n SUPERPOSITION: \"eip155:55244\",\n SUPERSEED: \"eip155:5330\",\n SWELL_CHAIN: \"eip155:1923\",\n TAIKO: \"eip155:167000\",\n UNICHAIN: \"eip155:130\",\n WORLD_CHAIN: \"eip155:480\",\n ZERO: \"eip155:543210\",\n ZIRCUIT: \"eip155:48900\",\n ZKSYNC_ERA: \"eip155:324\",\n ZORA: \"eip155:7777777\",\n // Dev\n LOCALHOST: \"eip155:31337\",\n // Solana\n SOLANA: \"solana:mainnet\",\n SOLANA_DEVNET: \"solana:devnet\",\n // Tron\n TRON: \"tron:mainnet\",\n // Bitcoin\n BITCOIN: \"bip122:mainnet\",\n} as const;\n\nexport type ChainId = typeof CHAINS[keyof typeof CHAINS];\n\n// ── Custom chain validation ───────────────────────────────────────────────────\n\nexport function validateCustomChain(chain: unknown): chain is ChainDescriptor {\n if (!chain || typeof chain !== \"object\") return false;\n const c = chain as Record<string, unknown>;\n if (typeof c.id !== \"string\" || !c.id) return false;\n if (c.type !== \"evm\" && c.type !== \"solana\" && c.type !== \"tron\" && c.type !== \"bitcoin\") return false;\n if (typeof c.name !== \"string\" || !c.name) return false;\n if (!c.nativeCurrency || typeof c.nativeCurrency !== \"object\") return false;\n if (c.type === \"evm\" && (typeof c.chainId !== \"number\" || !c.id.startsWith(\"eip155:\")))\n return false;\n if (c.type === \"solana\" && !c.id.startsWith(\"solana:\")) return false;\n return true;\n}\n","import type { ActiveSession } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\nimport { toCAIP10 } from \"../constants\";\n\nconst STORAGE_KEY = \"decane:session\";\n\nfunction loadFromStorage(): ActiveSession | null {\n if (typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n return raw ? (JSON.parse(raw) as ActiveSession) : null;\n } catch {\n return null;\n }\n}\n\nfunction saveToStorage(session: ActiveSession | null): void {\n if (typeof localStorage === \"undefined\") return;\n try {\n if (session) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(session));\n } else {\n localStorage.removeItem(STORAGE_KEY);\n }\n } catch {\n // Storage quota exceeded or private browsing — silently skip\n }\n}\n\nexport interface SessionManager {\n get(): ActiveSession | null;\n set(s: ActiveSession | null): void;\n clear(): void;\n isChainGranted(chainId: string): boolean;\n isAccountGranted(chainId: string, address: string): boolean;\n assertChainInScope(chainId: string): void;\n assertAccountInScope(chainId: string, address: string): void;\n}\n\nexport function createSessionManager(): SessionManager {\n // Restore persisted session on SDK init\n let _session: ActiveSession | null = loadFromStorage();\n\n return {\n get: () => _session,\n\n set(s) {\n _session = s;\n saveToStorage(s);\n },\n\n clear() {\n _session = null;\n saveToStorage(null);\n },\n\n isChainGranted(chainId) {\n return !!_session?.grantedScopes[chainId];\n },\n\n isAccountGranted(chainId, address) {\n const scope = _session?.grantedScopes[chainId];\n if (!scope) return false;\n return scope.accounts.includes(toCAIP10(chainId, address));\n },\n\n assertChainInScope(chainId) {\n if (!this.isChainGranted(chainId)) {\n throw new DecaneError(\n DecaneErrorCode.CHAIN_NOT_IN_SCOPE,\n `Chain ${chainId} is not in the current session scope. Call wallet_requestPermissions first.`,\n );\n }\n },\n\n assertAccountInScope(chainId, address) {\n if (!this.isAccountGranted(chainId, address)) {\n throw new DecaneError(\n DecaneErrorCode.SCOPE_MISMATCH,\n `Account ${address} on chain ${chainId} is not in the current session scope.`,\n );\n }\n },\n };\n}\n","import type { ChainDescriptor } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\nexport interface ChainStore {\n get(id: string): ChainDescriptor | undefined;\n getAll(): ChainDescriptor[];\n add(chain: ChainDescriptor): void;\n remove(id: string): void;\n}\n\nexport function createChainStore(initial: ChainDescriptor[]): ChainStore {\n const chains = new Map<string, ChainDescriptor>(\n initial.map((c) => [c.id, c]),\n );\n\n return {\n get(id) {\n return chains.get(id);\n },\n\n getAll() {\n return [...chains.values()];\n },\n\n add(chain) {\n if (chains.has(chain.id)) {\n throw new DecaneError(\n DecaneErrorCode.INVALID_CHAIN_CONFIG,\n `Chain ${chain.id} is already registered`,\n );\n }\n chains.set(chain.id, chain);\n },\n\n remove(id) {\n const chain = chains.get(id);\n if (!chain) return;\n if (!chain.isCustom) {\n throw new DecaneError(\n DecaneErrorCode.INVALID_CHAIN_CONFIG,\n `Cannot remove built-in chain ${id}`,\n );\n }\n chains.delete(id);\n },\n };\n}\n","import type { EIP1193Provider, CAIP25Method, ChainDescriptor } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\nexport async function eip1193Request(\n provider: EIP1193Provider,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_sendTransaction\":\n return provider.request({\n method: \"eth_sendTransaction\",\n params: [{ ...(payload as object), from: account }],\n }) as Promise<string>;\n\n case \"wallet_signMessage\":\n // personal_sign prepends EIP-191 prefix: \"\\x19Ethereum Signed Message:\\n\"\n return provider.request({\n method: \"personal_sign\",\n params: [payload, account],\n }) as Promise<string>;\n\n case \"wallet_signTypedData\":\n // EIP-712 typed data\n return provider.request({\n method: \"eth_signTypedData_v4\",\n params: [account, JSON.stringify(payload)],\n }) as Promise<string>;\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `EVM adapter: unsupported method ${method}`,\n );\n }\n}\n\nexport async function getEvmAddress(\n provider: EIP1193Provider,\n): Promise<string> {\n const accounts = (await provider.request({\n method: \"eth_requestAccounts\",\n })) as string[];\n if (!accounts?.[0]) {\n throw new DecaneError(\n DecaneErrorCode.USER_REJECTED,\n \"No EVM accounts returned\",\n );\n }\n return accounts[0];\n}\n\n// EIP-3085 — supported by MetaMask and most EVM wallets\nexport async function addEthereumChain(\n provider: EIP1193Provider,\n chain: ChainDescriptor,\n): Promise<void> {\n await provider.request({\n method: \"wallet_addEthereumChain\",\n params: [\n {\n chainId: `0x${chain.chainId!.toString(16)}`,\n chainName: chain.name,\n nativeCurrency: chain.nativeCurrency,\n rpcUrls: chain.rpcUrl ? [chain.rpcUrl] : [],\n blockExplorerUrls: chain.blockExplorerUrl\n ? [chain.blockExplorerUrl]\n : [],\n },\n ],\n });\n}\n","import { base58 } from \"@scure/base\";\nimport type { StandardWallet, CAIP25Method, StandardWalletAccount } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\ninterface SolanaSignAndSendTx {\n signAndSendTransaction(args: {\n transaction: unknown;\n account: StandardWalletAccount;\n }): Promise<Array<{ signature: string }>>;\n}\n\ninterface SolanaSignMessage {\n signMessage(args: {\n message: Uint8Array;\n account: StandardWalletAccount;\n }): Promise<Array<{ signature: Uint8Array }>>;\n}\n\ninterface StandardConnect {\n connect(opts?: { silent?: boolean }): Promise<{\n accounts: Array<{ publicKey: Uint8Array; chains?: string[] }>;\n }>;\n}\n\nfunction deserializeSolanaTransaction(data: unknown): unknown {\n // Passthrough — wallet handles actual deserialization\n return data;\n}\n\nexport async function walletStandardRequest(\n wallet: StandardWallet,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_sendTransaction\": {\n const feature = wallet.features[\n \"solana:signAndSendTransaction\"\n ] as SolanaSignAndSendTx | undefined;\n if (!feature) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Wallet does not support solana:signAndSendTransaction\",\n );\n }\n const walletAccount = wallet.accounts.find(\n (a) => base58.encode(a.publicKey) === account,\n );\n if (!walletAccount) {\n throw new DecaneError(\n DecaneErrorCode.SCOPE_MISMATCH,\n `Account ${account} not found`,\n );\n }\n const tx = deserializeSolanaTransaction(payload);\n const [result] = await feature.signAndSendTransaction({\n transaction: tx,\n account: walletAccount,\n });\n return result.signature;\n }\n\n case \"wallet_signMessage\": {\n const feature = wallet.features[\n \"solana:signMessage\"\n ] as SolanaSignMessage | undefined;\n if (!feature) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Wallet does not support solana:signMessage\",\n );\n }\n const walletAccount = wallet.accounts.find(\n (a) => base58.encode(a.publicKey) === account,\n );\n if (!walletAccount) {\n throw new DecaneError(\n DecaneErrorCode.SCOPE_MISMATCH,\n `Account ${account} not found`,\n );\n }\n const messageBytes =\n typeof payload === \"string\"\n ? new TextEncoder().encode(payload)\n : (payload as Uint8Array);\n const [result] = await feature.signMessage({\n message: messageBytes,\n account: walletAccount,\n });\n return base58.encode(result.signature);\n }\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Solana adapter: unsupported method ${method}`,\n );\n }\n}\n\nfunction isSolanaAccount(a: { chains?: string[] }): boolean {\n return !a.chains?.length || a.chains.some((c) => c.startsWith(\"solana:\"));\n}\n\nexport async function getSolanaAddress(\n wallet: StandardWallet,\n): Promise<string> {\n // Use pre-connected accounts first — avoids triggering multi-chain connect\n // flows that fail for unsupported chains (e.g. tron:728126428 on Backpack)\n const pre = (wallet.accounts as StandardWalletAccount[]).find(isSolanaAccount);\n if (pre) return base58.encode(pre.publicKey);\n\n const connectFeature = wallet.features[\n \"standard:connect\"\n ] as StandardConnect | undefined;\n if (!connectFeature) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Wallet does not support standard:connect\",\n );\n }\n const { accounts } = await connectFeature.connect();\n const solanaAccount = accounts.find(isSolanaAccount);\n if (!solanaAccount) {\n throw new DecaneError(\n DecaneErrorCode.USER_REJECTED,\n \"No Solana accounts returned\",\n );\n }\n return base58.encode(solanaAccount.publicKey);\n}\n","import type { TronProvider, CAIP25Method } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\ninterface TronWeb {\n transactionBuilder?: {\n sendTrx(to: string, amount: number, from: string): Promise<object>;\n triggerSmartContract(\n contractAddress: string,\n functionSelector: string,\n options: object,\n parameters: unknown[],\n issuerAddress: string,\n ): Promise<{ transaction: object }>;\n };\n trx?: {\n sign(transaction: object): Promise<object>;\n sendRawTransaction(signedTx: object): Promise<{ txid?: string; result?: boolean }>;\n };\n defaultAddress?: { base58?: string };\n fullNode?: { host?: string };\n}\n\ntype TronWin = Window & { tronWeb?: TronWeb; tronLink?: { tronWeb?: TronWeb } };\n\nfunction getTronWeb(): TronWeb | undefined {\n if (typeof window === \"undefined\") return undefined;\n const win = window as TronWin;\n return win.tronLink?.tronWeb ?? win.tronWeb;\n}\n\nexport async function getTronAddress(provider: TronProvider): Promise<string> {\n // tronLink.tronWeb is the fully-initialized instance; window.tronWeb may be a stub\n const addr = getTronWeb()?.defaultAddress?.base58;\n if (addr) return addr;\n\n try {\n const result = await provider.request({ method: \"tron_requestAccounts\" });\n const accounts = result as string[];\n if (accounts?.[0]) return accounts[0];\n } catch {\n // fallback below\n }\n const result2 = await provider.request({ method: \"tron_accounts\" }).catch(() => null);\n const accounts2 = result2 as string[] | null;\n if (accounts2?.[0]) return accounts2[0];\n throw new DecaneError(DecaneErrorCode.USER_REJECTED, \"No Tron accounts returned\");\n}\n\nexport async function tronRequest(\n provider: TronProvider,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_signMessage\":\n return provider.request({\n method: \"tron_signMessage\",\n params: { message: payload as string },\n }) as Promise<string>;\n\n case \"wallet_sendTransaction\": {\n const tronWeb = getTronWeb();\n const p = payload as { to: string; value?: number | string; data?: string };\n const toAddress = p.to;\n const sunAmount =\n typeof p.value === \"string\" ? parseInt(p.value, 10) : (p.value ?? 0);\n\n // ── Step 1: build unsigned transaction ───────────────────────────────\n let unsignedTx: object;\n\n if (tronWeb?.transactionBuilder?.sendTrx) {\n // transactionBuilder available — use it directly\n if (p.data && p.data !== \"0x\") {\n const res = await tronWeb.transactionBuilder.triggerSmartContract!(\n toAddress,\n \"transfer(address,uint256)\",\n { callValue: 0, feeLimit: 100_000_000 },\n [],\n account,\n );\n unsignedTx = res.transaction;\n } else {\n unsignedTx = await tronWeb.transactionBuilder.sendTrx(toAddress, sunAmount, account);\n }\n } else {\n // transactionBuilder not available — build via Tron HTTP API\n const host = tronWeb?.fullNode?.host ?? \"https://api.trongrid.io\";\n const endpoint = p.data && p.data !== \"0x\"\n ? `${host}/wallet/triggersmartcontract`\n : `${host}/wallet/createtransaction`;\n const body = p.data && p.data !== \"0x\"\n ? {\n owner_address: account,\n contract_address: toAddress,\n function_selector: \"transfer(address,uint256)\",\n fee_limit: 100_000_000,\n call_value: 0,\n visible: true,\n }\n : {\n owner_address: account,\n to_address: toAddress,\n amount: sunAmount,\n visible: true,\n };\n\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n throw new DecaneError(\n DecaneErrorCode.PROVIDER_ERROR,\n `Failed to build Tron transaction: ${res.statusText}`,\n );\n }\n const json = await res.json() as { transaction?: object } & object;\n // triggersmartcontract wraps result in { transaction: {...} }\n unsignedTx = (json as { transaction?: object }).transaction ?? json;\n }\n\n // ── Step 2: sign ─────────────────────────────────────────────────────\n // TronLink expects the transaction object directly as params (not wrapped)\n let signedTx: object;\n if (tronWeb?.trx?.sign) {\n signedTx = await tronWeb.trx.sign(unsignedTx);\n } else {\n signedTx = await provider.request({\n method: \"tron_signTransaction\",\n params: unsignedTx as Record<string, unknown>,\n }) as object;\n }\n\n // ── Step 3: broadcast ─────────────────────────────────────────────────\n // Same — signed transaction is passed directly as params\n let txid: string | undefined;\n if (tronWeb?.trx?.sendRawTransaction) {\n const result = await tronWeb.trx.sendRawTransaction(signedTx);\n txid = result?.txid;\n } else {\n const result = await provider.request({\n method: \"tron_sendRawTransaction\",\n params: signedTx as Record<string, unknown>,\n }) as { txid?: string };\n txid = result?.txid;\n }\n\n if (!txid) {\n throw new DecaneError(DecaneErrorCode.PROVIDER_ERROR, \"Tron transaction broadcast failed\");\n }\n return txid;\n }\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Tron adapter: unsupported method ${method}`,\n );\n }\n}\n","import type { BitcoinProvider, CAIP25Method } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\nexport async function getBitcoinAddress(provider: BitcoinProvider): Promise<string> {\n const result = await provider.requestAccounts();\n if (!result || result.length === 0) {\n throw new DecaneError(DecaneErrorCode.USER_REJECTED, \"No Bitcoin accounts returned\");\n }\n const first = result[0];\n // Unisat returns string[]; OKX returns {address: string}[]\n return typeof first === \"string\" ? first : (first as { address: string }).address;\n}\n\nexport async function bitcoinRequest(\n provider: BitcoinProvider,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_signMessage\":\n return provider.signMessage(payload as string);\n\n case \"wallet_sendTransaction\": {\n const { to, value } = payload as { to: string; value: number };\n if (provider.sendBitcoin) {\n return provider.sendBitcoin(to, value);\n }\n // Fallback for wallets that use a generic send method\n if (provider.send) {\n return provider.send({ to, value, from: account }) as Promise<string>;\n }\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Bitcoin wallet does not support sendBitcoin\",\n );\n }\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Bitcoin adapter: unsupported method ${method}`,\n );\n }\n}\n","import type {\n CAIP25Method,\n CAIP25SessionRequest,\n CAIP25SessionResult,\n ChainScope,\n ActiveSession,\n} from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\nimport {\n getChainType,\n toCAIP10,\n EVM_METHODS,\n SOLANA_METHODS,\n TRON_METHODS,\n BITCOIN_METHODS,\n} from \"../constants\";\nimport { getEvmAddress, addEthereumChain, eip1193Request } from \"../evm/adapter\";\nimport { getSolanaAddress, walletStandardRequest } from \"../solana/adapter\";\nimport { getTronAddress, tronRequest } from \"../tron/adapter\";\nimport { getBitcoinAddress, bitcoinRequest } from \"../bitcoin/adapter\";\nimport type { Registry } from \"./registry\";\nimport type { SessionManager } from \"./session\";\nimport type { ChainStore } from \"./chainStore\";\n\nexport interface Router {\n request(args: { method: string; params?: unknown[] }): Promise<unknown>;\n}\n\nexport function createRouter(opts: {\n registry: Registry;\n session: SessionManager;\n chainStore: ChainStore;\n}): Router {\n const { registry, session, chainStore } = opts;\n\n async function request(args: {\n method: string;\n params?: unknown[];\n }): Promise<unknown> {\n switch (args.method) {\n case \"wallet_requestPermissions\":\n return handleRequestPermissions(\n args.params as [CAIP25SessionRequest],\n );\n\n case \"wallet_revokePermissions\":\n return handleRevokePermissions();\n\n case \"wallet_getPermissions\":\n return handleGetPermissions();\n\n case \"wallet_sendTransaction\":\n case \"wallet_signMessage\":\n case \"wallet_signTypedData\":\n return handleSigning(args.method, args.params);\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Unknown CAIP-25 method: ${args.method}`,\n );\n }\n }\n\n async function handleRequestPermissions([\n req,\n walletIdHint,\n ]: [CAIP25SessionRequest, string?]): Promise<CAIP25SessionResult> {\n const connectedWallet =\n (walletIdHint ? registry.get.byId(walletIdHint) : undefined) ??\n registry.get.all().find((w) => w.id === session.get()?.walletId) ??\n registry.get.all()[0];\n\n if (!connectedWallet) {\n throw new DecaneError(\n DecaneErrorCode.NO_WALLET_CONNECTED,\n \"No wallet connected\",\n );\n }\n\n const allScopes = { ...req.requiredScopes, ...req.optionalScopes };\n const grantedScopes: Record<string, ChainScope> = {};\n\n for (const [chainId, scope] of Object.entries(allScopes)) {\n const chain = chainStore.get(chainId);\n if (!chain) {\n throw new DecaneError(\n DecaneErrorCode.UNSUPPORTED_CHAIN,\n `Unknown chain: ${chainId}`,\n );\n }\n\n const chainType = getChainType(chainId);\n\n if (chainType === \"evm\" && !connectedWallet.evmProvider) continue;\n if (chainType === \"solana\" && !connectedWallet.solanaProvider) continue;\n if (chainType === \"tron\" && !connectedWallet.tronProvider) continue;\n if (chainType === \"bitcoin\" && !connectedWallet.bitcoinProvider) continue;\n\n let address: string;\n if (chainType === \"evm\") {\n address = await getEvmAddress(connectedWallet.evmProvider!);\n if (chain.isCustom) {\n await addEthereumChain(connectedWallet.evmProvider!, chain).catch(() => {});\n }\n } else if (chainType === \"solana\") {\n address = await getSolanaAddress(connectedWallet.solanaProvider!);\n } else if (chainType === \"tron\") {\n address = await getTronAddress(connectedWallet.tronProvider!);\n } else {\n address = await getBitcoinAddress(connectedWallet.bitcoinProvider!);\n }\n\n const methodSet =\n chainType === \"evm\" ? EVM_METHODS :\n chainType === \"solana\" ? SOLANA_METHODS :\n chainType === \"tron\" ? TRON_METHODS :\n BITCOIN_METHODS;\n const grantedMethods = (scope?.methods ?? []).filter((m) =>\n methodSet.has(m),\n ) as CAIP25Method[];\n\n grantedScopes[chainId] = {\n methods: grantedMethods,\n accounts: [toCAIP10(chainId, address)],\n events: scope?.events ?? [],\n };\n }\n\n // Verify all required scopes were granted\n for (const chainId of Object.keys(req.requiredScopes)) {\n if (!grantedScopes[chainId]) {\n throw new DecaneError(\n DecaneErrorCode.UNSUPPORTED_CHAIN,\n `Required chain ${chainId} could not be granted`,\n );\n }\n }\n\n const newSession: ActiveSession = {\n sessionId: crypto.randomUUID(),\n grantedScopes,\n walletId: connectedWallet.id,\n walletType:\n connectedWallet.chainSupport.length === 2\n ? \"multi\"\n : connectedWallet.chainSupport[0],\n createdAt: Date.now(),\n };\n session.set(newSession);\n\n return { sessionId: newSession.sessionId, grantedScopes };\n }\n\n async function handleRevokePermissions(): Promise<null> {\n session.clear();\n return null;\n }\n\n async function handleGetPermissions(): Promise<CAIP25SessionResult | null> {\n const s = session.get();\n if (!s) return null;\n return { sessionId: s.sessionId, grantedScopes: s.grantedScopes };\n }\n\n function extractSigningContext(\n method: string,\n params: unknown[] | undefined,\n ): { chainId: string; account: string; payload: unknown } {\n if (!params || params.length < 3) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `${method} requires [chainId, account, payload] params`,\n );\n }\n return {\n chainId: params[0] as string,\n account: params[1] as string,\n payload: params[2],\n };\n }\n\n async function handleSigning(\n method: string,\n params: unknown[] | undefined,\n ): Promise<string> {\n const s = session.get();\n if (!s) {\n throw new DecaneError(\n DecaneErrorCode.NO_ACTIVE_SESSION,\n \"No active session. Call wallet_requestPermissions first.\",\n );\n }\n\n const { chainId, account, payload } = extractSigningContext(\n method,\n params,\n );\n const chainType = getChainType(chainId);\n\n session.assertChainInScope(chainId);\n session.assertAccountInScope(chainId, account);\n\n if (method === \"wallet_signTypedData\" && chainType !== \"evm\") {\n throw new DecaneError(\n DecaneErrorCode.EVM_ONLY_METHOD,\n \"wallet_signTypedData is only supported on EVM chains\",\n );\n }\n\n const wallet = registry.get.byId(s.walletId);\n if (!wallet) {\n throw new DecaneError(\n DecaneErrorCode.NO_WALLET_CONNECTED,\n \"Connected wallet not found\",\n );\n }\n\n if (chainType === \"evm\") {\n return eip1193Request(wallet.evmProvider!, method as CAIP25Method, payload, account);\n } else if (chainType === \"solana\") {\n return walletStandardRequest(wallet.solanaProvider!, method as CAIP25Method, payload, account);\n } else if (chainType === \"tron\") {\n return tronRequest(wallet.tronProvider!, method as CAIP25Method, payload, account);\n } else {\n return bitcoinRequest(wallet.bitcoinProvider!, method as CAIP25Method, payload, account);\n }\n }\n\n return { request };\n}\n","import type {\n DecaneProvider,\n DecaneConfig,\n UnifiedWalletAccount,\n ChainDescriptor,\n ChainType,\n ActiveSession,\n} from \"./types\";\nimport { DecaneError, DecaneErrorCode } from \"./errors\";\nimport { validateCustomChain } from \"./constants\";\nimport { addEthereumChain } from \"./evm/adapter\";\nimport type { Registry } from \"./core/registry\";\nimport type { SessionManager } from \"./core/session\";\nimport type { ChainStore } from \"./core/chainStore\";\nimport type { Emitter } from \"./core/emitter\";\nimport type { Router } from \"./core/router\";\n\nexport function createProvider(opts: {\n config: DecaneConfig;\n registry: Registry;\n session: SessionManager;\n chainStore: ChainStore;\n router: Router;\n emitter: Emitter;\n}): DecaneProvider {\n const { config, registry, session, chainStore, router, emitter } = opts;\n\n let _connectedWallet: UnifiedWalletAccount | null = null;\n let _activeChain: string | null = config.defaultChain ?? null;\n\n // Restore connected wallet from a persisted session after discovery\n function tryRestoreWallet(w: UnifiedWalletAccount): void {\n const s = session.get();\n if (!s || _connectedWallet) return;\n if (w.id !== s.walletId) return;\n _connectedWallet = w;\n const granted = Object.keys(s.grantedScopes);\n if (!_activeChain || !granted.includes(_activeChain)) {\n _activeChain = granted[0] ?? null;\n }\n emitter.emit(\"connect\", w);\n }\n\n emitter.on(\"walletRegistered\", (w) => tryRestoreWallet(w as UnifiedWalletAccount));\n // Also handle the case where the Solana provider merges in after EVM is already registered\n emitter.on(\"walletUpdated\", (w) => {\n const wallet = w as UnifiedWalletAccount;\n if (_connectedWallet?.id === wallet.id) {\n _connectedWallet = wallet; // keep reference fresh after merge\n } else {\n tryRestoreWallet(wallet);\n }\n });\n\n const provider: DecaneProvider = {\n // ── CAIP-25 request gateway ─────────────────────────────────────────────\n\n request(args) {\n return router.request(args);\n },\n\n on(event, handler) {\n emitter.on(event, handler);\n },\n\n off(event, handler) {\n emitter.off(event, handler);\n },\n\n // ── Registry views ──────────────────────────────────────────────────────\n\n get wallets() {\n return registry.get.all();\n },\n\n get evmWallets() {\n return registry.get.evm();\n },\n\n get solanaWallets() {\n return registry.get.solana();\n },\n\n get multiChainWallets() {\n return registry.get.multiChain();\n },\n\n get tronWallets() {\n return registry.get.tron();\n },\n\n get bitcoinWallets() {\n return registry.get.bitcoin();\n },\n\n // ── Connection ──────────────────────────────────────────────────────────\n\n async connect(wallet: UnifiedWalletAccount, preferredChain?: ChainType): Promise<void> {\n if (session.get()) {\n session.clear();\n emitter.emit(\"disconnect\");\n }\n\n _connectedWallet = wallet;\n\n const support = wallet.chainSupport as readonly string[];\n\n const hasEvm = support.includes(\"evm\") && preferredChain !== \"solana\" && preferredChain !== \"tron\" && preferredChain !== \"bitcoin\";\n const hasSol = support.includes(\"solana\") && preferredChain !== \"evm\" && preferredChain !== \"tron\" && preferredChain !== \"bitcoin\";\n const hasTron = support.includes(\"tron\") && preferredChain !== \"evm\" && preferredChain !== \"solana\" && preferredChain !== \"bitcoin\";\n const hasBitcoin = support.includes(\"bitcoin\") && preferredChain !== \"evm\" && preferredChain !== \"solana\" && preferredChain !== \"tron\";\n\n // Set active chain based on preference priority\n if (hasEvm) {\n _activeChain = config.defaultChain?.startsWith(\"eip155:\")\n ? config.defaultChain\n : \"eip155:1\";\n } else if (hasSol) {\n _activeChain = \"solana:mainnet\";\n } else if (hasTron) {\n _activeChain = \"tron:mainnet\";\n } else if (hasBitcoin) {\n _activeChain = \"bip122:mainnet\";\n }\n\n const required: Record<string, { methods: string[]; accounts: string[]; events: string[] }> = {};\n const optional: Record<string, { methods: string[]; accounts: string[]; events: string[] }> = {};\n\n if (hasEvm) {\n required[_activeChain ?? \"eip155:1\"] = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\", \"wallet_signTypedData\"],\n accounts: [],\n events: [\"chainChanged\", \"accountsChanged\"],\n };\n }\n if (hasSol) {\n const solChain = \"solana:mainnet\";\n const scope = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n };\n if (hasEvm) {\n optional[solChain] = scope;\n } else {\n required[solChain] = scope;\n _activeChain = solChain;\n }\n }\n if (hasTron) {\n const tronChain = \"tron:mainnet\";\n const scope = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n };\n if (hasEvm || hasSol) {\n optional[tronChain] = scope;\n } else {\n required[tronChain] = scope;\n _activeChain = tronChain;\n }\n }\n if (hasBitcoin) {\n const btcChain = \"bip122:mainnet\";\n const scope = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n };\n if (hasEvm || hasSol || hasTron) {\n optional[btcChain] = scope;\n } else {\n required[btcChain] = scope;\n _activeChain = btcChain;\n }\n }\n\n await router.request({\n method: \"wallet_requestPermissions\",\n params: [{ requiredScopes: required, optionalScopes: optional }, wallet.id],\n });\n\n const s = session.get();\n if (s) {\n const granted = Object.keys(s.grantedScopes);\n if (_activeChain && !granted.includes(_activeChain)) {\n _activeChain = granted[0] ?? null;\n }\n }\n\n emitter.emit(\"connect\", wallet);\n },\n\n async disconnect(): Promise<void> {\n session.clear();\n _connectedWallet = null;\n _activeChain = null;\n emitter.emit(\"disconnect\");\n },\n\n // ── Custom chain management ─────────────────────────────────────────────\n\n addChain(chain: ChainDescriptor): void {\n if (!validateCustomChain(chain)) {\n throw new DecaneError(\n DecaneErrorCode.INVALID_CHAIN_CONFIG,\n \"Invalid chain descriptor\",\n );\n }\n chainStore.add(chain);\n\n if (_connectedWallet?.evmProvider && chain.type === \"evm\") {\n addEthereumChain(_connectedWallet.evmProvider, chain).catch(() => {});\n }\n\n emitter.emit(\"chainAdded\", chain);\n },\n\n removeChain(chainId: string): void {\n chainStore.remove(chainId);\n\n const s = session.get();\n if (s?.grantedScopes[chainId]) {\n delete (s.grantedScopes as Record<string, unknown>)[chainId];\n session.set(s);\n }\n\n if (_activeChain === chainId) {\n const remaining = Object.keys(session.get()?.grantedScopes ?? {});\n _activeChain = remaining[0] ?? null;\n }\n\n emitter.emit(\"chainRemoved\", chainId);\n },\n\n getChain(chainId: string): ChainDescriptor | undefined {\n return chainStore.get(chainId);\n },\n\n get chains(): ChainDescriptor[] {\n return chainStore.getAll();\n },\n\n // ── State ───────────────────────────────────────────────────────────────\n\n get connectedWallet(): UnifiedWalletAccount | null {\n return _connectedWallet;\n },\n\n get activeSession(): ActiveSession | null {\n return session.get();\n },\n\n get activeChain(): string | null {\n return _activeChain;\n },\n };\n\n return provider;\n}\n","import type { EIP1193Provider, BitcoinProvider } from \"../types\";\nimport type { Registry } from \"../core/registry\";\n\n// Known Bitcoin snap IDs — checked in order, first match wins\nconst BITCOIN_SNAP_IDS = [\n \"npm:@metamask/bitcoin-snap\",\n \"npm:@consensys/btc-snap\",\n] as const;\n\ntype SnapMap = Record<string, { enabled?: boolean; blocked?: boolean } | undefined>;\n\nasync function detectBitcoinSnap(provider: EIP1193Provider): Promise<string | null> {\n try {\n const snaps = (await provider.request({ method: \"wallet_getSnaps\" })) as SnapMap | null;\n if (!snaps) return null;\n for (const id of BITCOIN_SNAP_IDS) {\n const snap = snaps[id];\n if (snap && snap.blocked !== true) return id;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction makeBitcoinSnapProvider(snapId: string, evmProvider: EIP1193Provider): BitcoinProvider {\n function invoke(method: string, params?: unknown): Promise<unknown> {\n return evmProvider.request({\n method: \"wallet_invokeSnap\",\n params: [{ snapId, request: { method, params } }],\n });\n }\n\n return {\n async requestAccounts() {\n // Different snap versions use different method names — try both\n const result = await invoke(\"btc_getAddress\").catch(() => invoke(\"btc_getPublicKey\"));\n if (typeof result === \"string\") return [result];\n if (Array.isArray(result)) return result as string[];\n return [];\n },\n async signMessage(message: string) {\n return invoke(\"btc_signMessage\", [message]) as Promise<string>;\n },\n async sendBitcoin(to: string, value: number) {\n return invoke(\"btc_sendBitcoin\", [{ to, satoshis: value }]) as Promise<string>;\n },\n };\n}\n\nexport async function tryRegisterBitcoinSnap(\n registry: Registry,\n name: string,\n icon: string,\n rdns: string | undefined,\n evmProvider: EIP1193Provider,\n): Promise<void> {\n const snapId = await detectBitcoinSnap(evmProvider);\n if (!snapId) return;\n\n registry.registerOrMerge({\n chain: \"bitcoin\",\n name,\n icon,\n rdns,\n provider: makeBitcoinSnapProvider(snapId, evmProvider),\n });\n}\n","import type { EIP6963AnnounceProviderEvent, EIP1193Provider } from \"../types\";\nimport type { Registry } from \"../core/registry\";\nimport { tryRegisterBitcoinSnap } from \"./bitcoinSnap\";\n\nexport function startEvmDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return; // SSR guard\n\n const seenUuids = new Set<string>();\n\n window.addEventListener(\n \"eip6963:announceProvider\",\n (event: Event) => {\n const e = event as EIP6963AnnounceProviderEvent;\n const { info, provider } = e.detail;\n\n if (seenUuids.has(info.uuid)) return;\n seenUuids.add(info.uuid);\n\n registry.registerOrMerge({\n chain: \"evm\",\n name: info.name,\n icon: info.icon,\n rdns: info.rdns,\n uuid: info.uuid,\n provider,\n });\n\n // Async: check for an installed Bitcoin snap on this wallet (fire-and-forget)\n tryRegisterBitcoinSnap(\n registry,\n info.name,\n info.icon,\n info.rdns,\n provider as EIP1193Provider,\n ).catch(() => {});\n },\n );\n\n window.dispatchEvent(new CustomEvent(\"eip6963:requestProvider\"));\n\n // Re-request after 100ms to catch wallets that load slightly after the SDK\n setTimeout(\n () => window.dispatchEvent(new CustomEvent(\"eip6963:requestProvider\")),\n 100,\n );\n}\n","import { getWallets } from \"@wallet-standard/app\";\nimport type { StandardWallet, WalletWithRdns } from \"../types\";\nimport type { Registry } from \"../core/registry\";\n\nexport function startSolanaDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return; // SSR guard\n\n const { get, on } = getWallets();\n\n function register(wallet: StandardWallet): void {\n const required = [\n \"standard:connect\",\n \"solana:signTransaction\",\n \"solana:signMessage\",\n ];\n if (!required.every((f) => f in wallet.features)) return;\n\n registry.registerOrMerge({\n chain: \"solana\",\n name: wallet.name,\n icon: wallet.icon,\n rdns: (wallet as WalletWithRdns).rdns ?? undefined,\n provider: wallet,\n });\n }\n\n (get() as unknown as StandardWallet[]).forEach(register);\n\n on(\"register\", (...wallets) =>\n (wallets as unknown as StandardWallet[]).forEach(register),\n );\n\n on(\"unregister\", (...wallets) =>\n (wallets as unknown as StandardWallet[]).forEach((w) => registry.unregister(w)),\n );\n}\n","import type { Registry } from \"../core/registry\";\nimport type { TronProvider } from \"../types\";\n\ndeclare global {\n interface Window {\n tronLink?: TronProvider;\n tronWeb?: { defaultAddress?: { base58?: string }; ready?: boolean };\n }\n}\n\nconst TRONLINK_RDNS = \"link.tron.tronlink\";\n\n// Base64 encoded SVG of TronLink icon (red circle with play triangle)\nconst TRONLINK_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNGRjAwMTMiLz48cG9seWdvbiBwb2ludHM9IjEyLDkgMjMsMTYgMTIsMjMiIGZpbGw9IndoaXRlIi8+PC9zdmc+\";\n\nexport function startTronDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return;\n let registered = false;\n\n function tryRegister() {\n if (registered || !window.tronLink) return;\n registered = true;\n registry.registerOrMerge({\n chain: \"tron\",\n name: \"TronLink\",\n icon: TRONLINK_ICON,\n rdns: TRONLINK_RDNS,\n provider: window.tronLink,\n });\n }\n\n tryRegister();\n // TronLink fires this event when the extension finishes injecting\n window.addEventListener(\"tronLink#initialized\", tryRegister, { once: true });\n\n // Short poll to catch TronLink loading slightly after the SDK\n const start = Date.now();\n const poll = setInterval(() => {\n tryRegister();\n if (registered || Date.now() - start > 3000) clearInterval(poll);\n }, 200);\n}\n","import type { Registry } from \"../core/registry\";\nimport type { BitcoinProvider } from \"../types\";\n\ndeclare global {\n interface Window {\n unisat?: BitcoinProvider;\n okxwallet?: { bitcoin?: BitcoinProvider };\n // Some wallets inject as BitcoinProvider\n BitcoinProvider?: BitcoinProvider;\n }\n}\n\n// Base64 SVG: orange circle with ₿\nconst BTC_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNGNzkzMUEiLz48dGV4dCB4PSIxNi41IiB5PSIyMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0id2hpdGUiIGZvbnQtZmFtaWx5PSJBcmlhbCxzeXN0ZW0tdWkiPuKmojwvdGV4dD48L3N2Zz4=\";\n\ninterface CandidateDef {\n name: string;\n rdns: string;\n provider: BitcoinProvider | null | undefined;\n}\n\nexport function startBitcoinDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return;\n // Delay slightly so wallet extensions have time to inject\n setTimeout(() => {\n const candidates: CandidateDef[] = [\n { name: \"Unisat\", rdns: \"io.unisat.wallet\", provider: window.unisat },\n // OKX shares rdns with its EVM provider — merges into the EVM entry automatically\n { name: \"OKX Wallet\", rdns: \"com.okex.okxwallet\", provider: window.okxwallet?.bitcoin },\n ];\n\n for (const { name, rdns, provider } of candidates) {\n if (!provider) continue;\n registry.registerOrMerge({\n chain: \"bitcoin\",\n name,\n icon: BTC_ICON,\n rdns,\n provider,\n });\n }\n }, 150);\n}\n","import { createEmitter } from \"./core/emitter\";\nimport { createRegistry } from \"./core/registry\";\nimport { createSessionManager } from \"./core/session\";\nimport { createChainStore } from \"./core/chainStore\";\nimport { createRouter } from \"./core/router\";\nimport { createProvider } from \"./provider\";\nimport { startEvmDiscovery } from \"./evm/discovery\";\nimport { startSolanaDiscovery } from \"./solana/discovery\";\nimport { startTronDiscovery } from \"./tron/discovery\";\nimport { startBitcoinDiscovery } from \"./bitcoin/discovery\";\nimport { BUILT_IN_CHAINS } from \"./constants\";\nimport type { DecaneConfig, DecaneProvider } from \"./types\";\n\nexport function createDecane(config: DecaneConfig): DecaneProvider {\n if (!config?.appId) {\n throw new Error(\n \"decane-connect-kit: appId is required. Pass your dashboard project ID as config.appId.\",\n );\n }\n const emitter = createEmitter();\n const registry = createRegistry(emitter);\n const session = createSessionManager();\n const builtIn = config.supportedChainIds\n ? BUILT_IN_CHAINS.filter((c) => config.supportedChainIds!.includes(c.id))\n : BUILT_IN_CHAINS;\n\n const chainStore = createChainStore([\n ...builtIn,\n ...(config.chains ?? []),\n ]);\n const router = createRouter({ registry, session, chainStore });\n\n startEvmDiscovery(registry);\n startSolanaDiscovery(registry);\n startTronDiscovery(registry);\n startBitcoinDiscovery(registry);\n\n return createProvider({ config, registry, session, chainStore, router, emitter });\n}\n","import { Wallet, sha256, encodeBase58, type TransactionRequest } from \"ethers\";\nimport { Transaction, VersionedTransaction, Keypair } from \"@solana/web3.js\";\n\nimport type {\n DecaneConnect,\n DecaneConnectConfig,\n ConnectResult,\n SignMessageRequest,\n SendTransactionRequest,\n SignTypedDataRequest,\n AuthResult,\n WrappedShareMeta,\n TransactionRecord,\n RecordTransactionInput,\n} from \"./types\";\nimport {\n NewDeviceError,\n ProvisioningTimeoutError,\n UserCancelledError,\n InvalidPinError,\n ShareCorruptedError,\n CallSequenceError,\n PromptPinNotConfiguredError,\n ReconnectRequiredError,\n StaleDeviceShareError,\n} from \"./errors\";\nimport { EventEmitter } from \"./events\";\nimport { ApiClient } from \"./api\";\nimport { Storage, type StoredShare } from \"./storage\";\nimport { SessionManager } from \"./session\";\nimport { TeeClient, prewarmAttestation } from \"./teeClient\";\nimport {\n generateMaster,\n splitMaster,\n combineShares,\n generateRandomBytes,\n zeroize,\n} from \"./crypto/shares\";\nimport { importAesKey, aesGcmEncrypt, aesGcmDecrypt } from \"./crypto/wrap\";\nimport { deriveKeyFromPin, validatePin } from \"./crypto/pin\";\nimport { isPasskeySupported, getPrfOutput, authenticateWithPasskey } from \"./crypto/passkey\";\nimport { registerWebAuthnCredential } from \"./webauthnRegistration\";\nimport {\n startEmailAuth,\n verifyEmailCode as apiVerifyEmailCode,\n} from \"./auth/email\";\nimport { loginWithKingsChatPopup } from \"./auth/kingschat\";\nimport { signEvmMessage, signEvmTransaction, signEvmTypedData, signEvmAuthorization } from \"./signers/evm\";\nimport { createEthereumProvider } from \"./eip1193\";\nimport { signSolanaMessage, signSolanaTransaction } from \"./signers/solana\";\nimport { recoverDeviceShare } from \"./recovery/recoveryFlow\";\nimport { buildRecoveryShareFile, recoveryShareFileName, type RecoveryShareFile } from \"./recovery/recoveryShareFile\";\nimport { buildPortableBackup, portableBackupFileName, type PortableBackup } from \"./recovery/portableBackup\";\n\nconst DEFAULT_API_BASE = \"https://backend.decane.app\";\n// signer.decane.app is not wired up yet (no custom domain on the CVM) —\n// point directly at the Phala gateway URL until that's set up.\nconst DEFAULT_TEE_URL = \"https://4405742df08d19abc549a05ade2a7154d98bd87f-8443.dstack-pha-prod9.phala.network\";\n\n// 2 hours. Signing in every 30 minutes was poor UX. The session is still\n// clamped to whichever is sooner — this value, the JWT's exp, or the TEE\n// signer's SESSION_TTL_SECONDS — so this only takes full effect once the\n// signer's SESSION_TTL_SECONDS is raised to match (see below).\nconst DEFAULT_SESSION_MINUTES = 120;\n\n// DEFAULT_RPCS now lives in ./balance (single source of truth shared by the\n// client, the useSocialBalance hook, and the modal). Re-exported here so the\n// existing `import { DEFAULT_RPCS } from \"../social/client\"` call sites keep\n// working unchanged.\nexport { fetchBalance, formatBalanceDisplay } from \"./balance\";\nimport { fetchBalance as fetchBalanceImpl, DEFAULT_RPCS, type BalanceResult } from \"./balance\";\nexport { DEFAULT_RPCS };\n\ninterface AuthState {\n jwt: string;\n userId: string;\n addresses: { evm: string; solana: string; tron?: string };\n}\n\n// Persisted across reloads — no JWT (short-lived), just identity + addresses.\ninterface PersistedState {\n userId: string;\n addresses: { evm: string; solana: string; tron?: string };\n}\n\nfunction makePersistKey(apiKey: string) {\n return `decane:social:${apiKey.slice(0, 20)}`;\n}\n\nfunction loadPersisted(key: string): PersistedState | null {\n try {\n const raw = typeof localStorage !== 'undefined' ? localStorage.getItem(key) : null;\n return raw ? (JSON.parse(raw) as PersistedState) : null;\n } catch { return null; }\n}\n\nfunction savePersisted(key: string, state: PersistedState): void {\n try { localStorage.setItem(key, JSON.stringify(state)); } catch {}\n}\n\nfunction clearPersisted(key: string): void {\n try { localStorage.removeItem(key); } catch {}\n}\n\n// ── Resumable live session (sessionStorage) ──────────────────────────────────\n// Unlike the identity above (localStorage, addresses only), this holds the live\n// session — handle + JWT — so a page RELOAD can silently resume signing without\n// another passkey/sign-in. sessionStorage is deliberate: it survives reloads but\n// is cleared when the tab closes, so the session can't outlive the tab or be\n// read by other tabs. On tab close the leftover server session simply expires at\n// its TTL, unreachable (the handle is gone).\ninterface PersistedSession {\n handle: string;\n jwt: string;\n userId: string;\n addresses: { evm: string; solana: string; tron?: string };\n expiresAt: number;\n}\n\nfunction sessionPersistKey(apiKey: string) {\n return `decane:sess:${apiKey.slice(0, 20)}`;\n}\n\nfunction loadSession(key: string): PersistedSession | null {\n try {\n const raw = typeof sessionStorage !== \"undefined\" ? sessionStorage.getItem(key) : null;\n return raw ? (JSON.parse(raw) as PersistedSession) : null;\n } catch { return null; }\n}\n\nfunction saveSession(key: string, s: PersistedSession): void {\n try { sessionStorage.setItem(key, JSON.stringify(s)); } catch {}\n}\n\nfunction clearSessionPersist(key: string): void {\n try { sessionStorage.removeItem(key); } catch {}\n}\n\nexport async function createDecaneConnect(\n config: DecaneConnectConfig,\n): Promise<DecaneConnect> {\n if (!config.appId) throw new Error(\"decane-connect-kit: appId is required\");\n if (!config.apiKey) throw new Error(\"decane-connect-kit: apiKey is required\");\n if (!config.chains?.length)\n throw new Error(\"decane-connect-kit: at least one chain is required\");\n // Checked at construction, not when a device actually joins: rotation kills\n // the user's existing recovery file, and discovering there is nowhere to hand\n // them the replacement only at that point would leave them with a rotated set\n // and a dead file. Same reasoning as the Flow B guard in returningUserUnlock.\n if (config.rotateOnNewDeviceRecovery && !config.onRecoveryRotated) {\n throw new Error(\n \"decane-connect-kit: rotateOnNewDeviceRecovery requires an onRecoveryRotated callback — rotating on device join invalidates the user's existing recovery file, and the replacement must be saved.\",\n );\n }\n\n const baseUrl = config.apiBaseUrl ?? DEFAULT_API_BASE;\n const durationMs =\n (config.sessionDurationMinutes ?? DEFAULT_SESSION_MINUTES) * 60_000;\n const rpId =\n config.rpId ??\n (typeof window !== \"undefined\" ? window.location.hostname : \"localhost\");\n const rpName = config.rpName ?? \"Decane Connect\";\n\n const PERSIST_KEY = makePersistKey(config.apiKey);\n\n const teeUrl = config.teeUrl ?? DEFAULT_TEE_URL;\n\n const events = new EventEmitter();\n const api = new ApiClient(baseUrl, config.apiKey, config.appId);\n const storage = new Storage();\n const session = new SessionManager(\n events,\n durationMs,\n teeUrl,\n config.requireAssertionPerSignature === true\n );\n\n let auth: AuthState | null = null;\n // Addresses persisted across reloads — visible even before re-authentication.\n let persisted: PersistedState | null = loadPersisted(PERSIST_KEY);\n\n // Lazily-built, memoized EIP-1193 provider (wagmi/viem expect a stable ref).\n let ethProvider: ReturnType<typeof createEthereumProvider> | null = null;\n\n // Session persistence (sessionStorage) is on by default so a reload doesn't\n // force another passkey. Opt out with persistSession: false.\n const persistSession = config.persistSession !== false;\n // Always on. A wallet a person cannot re-enter after reinstalling is worse\n // than useless to them, so this is the product's behaviour rather than a\n // choice each integrator re-litigates. The trade it makes — the enclave can\n // reconstruct an enrolled wallet — is documented in the recovery guide.\n const serverAssistedRecovery = true;\n\n // How long to wait on the host app's recovery-share dialog before giving up\n // on it and finishing wallet creation anyway.\n //\n // The SDK awaits `onRecoveryShareOffer`, so a handler that never settles — a\n // modal that failed to mount, a promise the app forgot to resolve, a user who\n // walked away — used to hang signup indefinitely. It is not caught by the\n // try/catch around the call either: an unsettled promise is not an error.\n // Timing out is always the safer side of that trade. By the time this runs\n // the wallet is fully created, enrolled and persisted; the only thing skipped\n // is the offer of a recovery file, which the user can still generate later\n // via rotateShares(). Hanging, by contrast, strands them mid-signup.\n const RECOVERY_OFFER_TIMEOUT_MS = 5 * 60_000;\n\n // Wallets whose enrolment we have already tried to repair this page load.\n // The `enrolled === false` check below normally prevents repeats on its own,\n // but this also covers the case where enrolment keeps failing — one attempt\n // per user per load, well inside the enclave's 5-per-hour auth-share budget.\n const selfHealAttempted = new Set<string>();\n\n /**\n * Re-enrol a wallet that has a device share but no auth share.\n *\n * Enrolment runs once at wallet creation and, before 2.7.2, could be skipped\n * entirely if the user reloaded during the recovery-share prompt. Nothing ever\n * retried it, so those wallets are permanently unable to provision a new\n * device — `/signer/provision` answers 409 not_enrolled forever.\n *\n * `/signer/auth-share` validates the share it is given only by combining it\n * with the server share and checking the result derives the recorded\n * addresses. It does not care WHICH of the three shares it receives, and any\n * 2-of-3 reconstruct the master — so the device share we already hold is\n * sufficient to repair the wallet. The set returns to its intended shape on\n * the next provision or rotate, both of which re-seal a fresh recovery share.\n *\n * Runs in the background: the wallet is already usable by this point, and\n * blocking unlock on a repair would trade one hang for another. Takes\n * ownership of `share` and zeroizes it.\n */\n async function selfHealEnrolment(userId: string, jwt: string, share: Uint8Array): Promise<void> {\n try {\n if (selfHealAttempted.has(userId)) return;\n\n const status = await api.getRecoveryStatus(jwt);\n // Absent on backends older than this field. Unknown must not be treated as\n // \"not enrolled\", or every unlock against an old backend would re-enrol.\n if (status.enrolled !== false) return;\n\n selfHealAttempted.add(userId);\n await new TeeClient(teeUrl).enrolAuthShare(jwt, share);\n } catch (e) {\n events.emit(\"enrolment-failed\");\n console.warn(\n \"decane-connect-kit: this wallet is not enrolled for server-assisted recovery and \" +\n \"the automatic repair failed. It still works on this device, but a new device will \" +\n \"need a passkey backup or a recovery file. The SDK will try again on the next unlock.\",\n e,\n );\n } finally {\n zeroize(share);\n }\n }\n\n /**\n * Enrol a freshly created wallet for server-assisted provisioning.\n *\n * Runs off the critical path (see the call site) with one retry. Failure is\n * not fatal and not permanent — the unlock-time self-heal repairs it. Takes\n * ownership of `share`.\n */\n async function enrolInBackground(jwt: string, share: Uint8Array): Promise<void> {\n try {\n for (let attempt = 1; attempt <= 2; attempt++) {\n try {\n await new TeeClient(teeUrl).enrolAuthShare(jwt, share);\n return;\n } catch (e) {\n if (attempt === 2) {\n events.emit(\"enrolment-failed\");\n console.warn(\n \"decane-connect-kit: could not enrol this wallet for server-assisted recovery. \" +\n \"The wallet is fine and fully usable; it will be re-enrolled automatically on \" +\n \"the next unlock. Until then a brand-new device would need a passkey backup \" +\n \"or a recovery file.\",\n e,\n );\n }\n }\n }\n } finally {\n zeroize(share);\n }\n }\n\n // Hard ceiling on the SDK's own work during wallet creation.\n //\n // Covers key generation, share storage and opening the signer session — the\n // steps the SDK drives itself. Deliberately NOT the passkey/PIN prompt or the\n // recovery-file dialog: those wait on a human, and cutting a user off mid-PIN\n // would be worse than the hang this prevents. Individual requests are already\n // capped (30s in api.ts and teeClient.ts); this bounds the whole sequence, so\n // a run of slow-but-not-timing-out calls still cannot drag on indefinitely.\n const PROVISIONING_BUDGET_MS = 90_000;\n\n /** Rejects with ProvisioningTimeoutError if `promise` outlives `ms`. */\n function withDeadline<T>(promise: Promise<T>, ms: number, step: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout>;\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new ProvisioningTimeoutError(step)), Math.max(0, ms));\n }),\n ]).finally(() => clearTimeout(timer)) as Promise<T>;\n }\n\n /** Resolves to `null` if `promise` has not settled within `ms`. */\n function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T | null> {\n let timer: ReturnType<typeof setTimeout>;\n return Promise.race([\n promise,\n new Promise<null>((resolve) => {\n timer = setTimeout(() => resolve(null), ms);\n }),\n ]).finally(() => clearTimeout(timer)) as Promise<T | null>;\n }\n const SESSION_KEY = sessionPersistKey(config.apiKey);\n\n function persistLiveSession(): void {\n if (!persistSession) return;\n const handle = session.getHandle();\n const expiresAt = session.expiresAtTimestamp();\n if (!handle || !auth || !expiresAt) return;\n saveSession(SESSION_KEY, {\n handle, jwt: auth.jwt, userId: auth.userId, addresses: auth.addresses, expiresAt,\n });\n }\n\n function dropLiveSession(): void {\n clearSessionPersist(SESSION_KEY);\n }\n\n // Resume a still-live session from a previous page load — no prompt, no\n // network round trip. A 5s guard avoids adopting a handle about to expire.\n if (persistSession) {\n const saved = loadSession(SESSION_KEY);\n if (saved?.handle && saved.expiresAt > Date.now() + 5_000) {\n try {\n session.resume(saved.handle, saved.addresses, saved.expiresAt);\n auth = { jwt: saved.jwt, userId: saved.userId, addresses: saved.addresses };\n persisted = { userId: saved.userId, addresses: saved.addresses };\n } catch {\n dropLiveSession();\n }\n } else if (saved) {\n dropLiveSession();\n }\n }\n\n // Keep the persisted session in step with its real lifetime.\n events.on(\"session-expired\", () => dropLiveSession());\n\n // ── PIN setup helper ─────────────────────────────────────────────────────\n\n async function pinSetup(): Promise<{\n wrappingKey: CryptoKey;\n meta: Partial<WrappedShareMeta>;\n }> {\n if (!config.promptPin) throw new PromptPinNotConfiguredError();\n const pin = await config.promptPin();\n validatePin(pin);\n const pinSalt = generateRandomBytes(32);\n const wrappingKey = await deriveKeyFromPin(pin, pinSalt);\n return {\n wrappingKey,\n meta: {\n unlockMethod: \"pin\",\n pinSalt: bufferToB64u(pinSalt),\n pinIterations: 600_000,\n },\n };\n }\n\n // ── Wrapping-key derivation for returningUserUnlock's local-share path ────\n\n /**\n * Re-wrap and store a device share issued by a rotation.\n *\n * Every rotation (rotate, portable-export, recovery) invalidates the whole\n * share set server-side the moment it completes: the old device share can no\n * longer be combined with the new server share. If the replacement is not\n * written to storage, this device is left holding a share from a dead set and\n * the wallet is unusable from here — reconstruction silently yields a\n * different key, so it surfaces later as an unfunded address rather than as\n * an error. Persisting is therefore part of the rotation, not a follow-up to\n * it, and any failure has to propagate rather than be swallowed.\n *\n * The existing unlock method and its metadata are reused, so this re-prompts\n * for the same passkey or PIN already protecting the share rather than\n * establishing anything new.\n */\n async function persistRotatedDeviceShare(\n userId: string,\n deviceShare: Uint8Array,\n ): Promise<void> {\n const stored = await storage.getShare(userId);\n if (!stored) {\n // Nothing to re-wrap against (no passkey/PIN metadata on this device).\n // Rotating without being able to store the result is what strands a\n // wallet, so treat it as fatal rather than continuing.\n throw new CallSequenceError(\n \"Share set was rotated but this device has no stored share to update. Recover the wallet on this device before rotating.\",\n );\n }\n const wrappingKey = await getWrappingKey(stored);\n const iv = generateRandomBytes(12);\n const wrappedDeviceShare = await aesGcmEncrypt(wrappingKey, deviceShare, iv);\n await storage.putShare({ ...stored, wrappedDeviceShare, iv });\n }\n\n async function getWrappingKey(stored: StoredShare): Promise<CryptoKey> {\n if (stored.unlockMethod === \"passkey\") {\n const prfOutput = await getPrfOutput({\n rpId,\n credentialId: stored.credentialId!,\n prfSalt: stored.prfSalt!,\n });\n return importAesKey(prfOutput);\n }\n if (!config.promptPin) throw new PromptPinNotConfiguredError();\n const pin = await config.promptPin();\n return deriveKeyFromPin(pin, stored.pinSalt!);\n }\n\n // ── Post-recovery passkey provisioning ─────────────────────────────────────\n // After a Flow B (recovery-share file) recovery, this device has no\n // passkey yet. Best effort: register one and back it up so the *next* new\n // device recovers via the easy Flow A instead of needing a file again.\n // Never fails the recovery that already succeeded — every error is swallowed.\n\n async function registerPasskeyAndBackup(\n userId: string,\n jwt: string,\n deviceShare: Uint8Array,\n ): Promise<void> {\n if (!isPasskeySupported()) return;\n\n const prfSalt = generateRandomBytes(32);\n let credentialId: Uint8Array;\n let prfOutput: Uint8Array | undefined;\n try {\n const result = await registerWebAuthnCredential({ api, jwt, rpId, rpName, prfSalt });\n credentialId = result.credentialId;\n prfOutput = result.prfOutput;\n } catch (e) {\n console.warn('decane-connect-kit: passkey provisioning after recovery failed; user can set this up later.', e);\n return;\n }\n if (!prfOutput) return; // browser claimed support but returned no PRF — skip\n\n const wrappingKey = await importAesKey(prfOutput);\n const iv = generateRandomBytes(12);\n const wrappedDeviceShare = await aesGcmEncrypt(wrappingKey, deviceShare, iv);\n\n await storage.putShare({\n userId,\n wrappedDeviceShare,\n iv,\n unlockMethod: \"passkey\",\n credentialId,\n prfSalt,\n version: 1,\n });\n\n try {\n await api.putRecoveryBackup(jwt, {\n wrappedDeviceShare,\n iv,\n unlockMethod: \"passkey\",\n credentialId,\n prfSalt,\n });\n } catch (e) {\n console.warn('decane-connect-kit: wrapped share backup upload failed; user can retry from settings.', e);\n }\n }\n\n // ── First-time wallet setup (called when hasShare === false) ─────────────\n\n async function firstTimeSetup(\n userId: string,\n jwt: string,\n ): Promise<{ evm: string; solana: string }> {\n // Verifying the enclave means fetching a quote, pulling collateral from\n // Intel's PCS and running a WASM verifier — the slowest single step in\n // creation, and it depends on nothing we are about to compute. Start it now\n // so it runs while the user is at the passkey/PIN prompt and the key is\n // being generated; by the time the session opens it is usually already done.\n prewarmAttestation(teeUrl);\n\n let unlockMethod: \"passkey\" | \"pin\";\n let wrappingKey: CryptoKey;\n let meta: Partial<WrappedShareMeta> = {};\n\n if (isPasskeySupported()) {\n const prfSalt = generateRandomBytes(32);\n try {\n const { credentialId, prfOutput } = await registerWebAuthnCredential({ api, jwt, rpId, rpName, prfSalt });\n\n if (prfOutput) {\n unlockMethod = \"passkey\";\n wrappingKey = await importAesKey(prfOutput);\n meta = {\n unlockMethod: \"passkey\",\n credentialId: bufferToB64u(credentialId),\n prfSalt: bufferToB64u(prfSalt),\n };\n } else {\n // Browser claimed passkey support but didn't return PRF — fall back to PIN\n ({ wrappingKey, meta } = await pinSetup());\n unlockMethod = \"pin\";\n }\n } catch (e: unknown) {\n if ((e as Error).name === \"UserCancelledError\")\n throw new UserCancelledError();\n ({ wrappingKey, meta } = await pinSetup());\n unlockMethod = \"pin\";\n }\n } else {\n ({ wrappingKey, meta } = await pinSetup());\n unlockMethod = \"pin\";\n }\n\n // The unlock tier is settled (that step waits on the user); everything from\n // here to the open session is the SDK's own work and shares one budget.\n const provisioningStartedAt = Date.now();\n const remainingBudget = () => PROVISIONING_BUDGET_MS - (Date.now() - provisioningStartedAt);\n\n // Generate the master secret and split it into a 2-of-3 Shamir set —\n // device, server, recovery. Any two reconstruct; one alone reveals\n // nothing, which is what makes the recovery-share file safe to store\n // somewhere convenient (see recovery/recoveryShareFile.ts).\n const master = generateMaster();\n let shareSet: { device: Uint8Array; server: Uint8Array; recovery: Uint8Array; version: number };\n\n // Derive addresses from the raw master. This is one of the few permitted\n // browser-side uses of it — zeroized in the finally below, immediately\n // after use. The TEE never sees the master; it only ever reconstructs it\n // internally, momentarily, at signing/recovery/rotation time.\n let evmAddress: string;\n let solanaAddress: string;\n let tronAddress: string;\n try {\n evmAddress = new Wallet(toHex(master)).address;\n solanaAddress = Keypair.fromSeed(master).publicKey.toBase58();\n // Same secp256k1 key as EVM, re-encoded to the Tron \"T…\" address.\n tronAddress = evmToTronAddress(evmAddress);\n shareSet = await splitMaster(master, 1);\n } finally {\n zeroize(master);\n }\n\n // Wrap device share with wrapping key\n const iv = generateRandomBytes(12);\n const wrappedDeviceShare = await aesGcmEncrypt(\n wrappingKey,\n shareSet.device,\n iv,\n );\n\n // Store wrapped device share locally (IndexedDB)\n await storage.putShare({\n userId,\n wrappedDeviceShare,\n iv,\n unlockMethod,\n credentialId: meta.credentialId\n ? b64uToBuffer(meta.credentialId)\n : undefined,\n prfSalt: meta.prfSalt ? b64uToBuffer(meta.prfSalt) : undefined,\n pinSalt: meta.pinSalt ? b64uToBuffer(meta.pinSalt) : undefined,\n pinIterations: meta.pinIterations,\n version: 1,\n });\n\n // Send server share + addresses to backend\n const serverIv = generateRandomBytes(12);\n await withDeadline(api.putShare(jwt, {\n ciphertext: shareSet.server,\n iv: serverIv,\n wrappedShareMeta: {\n unlockMethod,\n // credential IDs, prfSalt, pinSalt stay on-device — never sent to server\n },\n evmAddress,\n solanaAddress,\n tronAddress,\n }), remainingBudget(), 'storing your wallet');\n zeroize(shareSet.server);\n\n const addresses = { evm: evmAddress, solana: solanaAddress, tron: tronAddress };\n\n // Back up the wrapped share for passkey-sync recovery (passkey users\n // only — a PIN doesn't sync across devices, so backing up a PIN-wrapped\n // share would be useless; a PIN-only user's sole recovery path is the\n // recovery-share file). Non-fatal: the user can back up later from settings.\n if (unlockMethod === \"passkey\" && meta.credentialId && meta.prfSalt) {\n try {\n await api.putRecoveryBackup(jwt, {\n wrappedDeviceShare,\n iv,\n unlockMethod: \"passkey\",\n credentialId: b64uToBuffer(meta.credentialId),\n prfSalt: b64uToBuffer(meta.prfSalt),\n });\n } catch (e) {\n console.warn('decane-connect-kit: wrapped share backup failed; user can retry from settings.', e);\n }\n }\n\n // Open the TEE session with the device share — not the reconstructed\n // key. The TEE fetches the server share itself and combines the two\n // internally, only for the duration of each sign call. It also derives\n // and returns the addresses of the key it reconstructed; here they must\n // match what we just derived locally, but we use its answer regardless so\n // there is exactly one authority on this in the codebase.\n const confirmed = await withDeadline(\n session.start(shareSet.device, jwt, addresses),\n remainingBudget(),\n 'opening the signing session',\n );\n zeroize(shareSet.device);\n\n if (confirmed.evm.toLowerCase() !== addresses.evm.toLowerCase()) {\n console.warn(\n `decane-connect-kit: signer derived a different EVM address (${confirmed.evm}) than this device did (${addresses.evm}) during setup. Using the signer's.`\n );\n }\n // Keep every downstream consumer on the confirmed values — including the\n // recovery-share file built below, whose embedded addresses must match the\n // key the file can actually reconstruct.\n addresses.evm = evmAddress = confirmed.evm;\n addresses.solana = solanaAddress = confirmed.solana;\n // Tron derives from the (now confirmed) EVM key — keep it in lockstep.\n addresses.tron = tronAddress = confirmed.tron ?? evmToTronAddress(confirmed.evm);\n\n // Enrol for server-assisted provisioning so this user can get back in on a\n // new device without a recovery file. Best effort — a failure leaves a good\n // wallet that simply needs the passkey/file path later.\n //\n // Deliberately BEFORE the recovery-share offer below: that offer awaits\n // user interaction (a modal where they choose and type a password) for an\n // unbounded time, and the JWT it shares expires in ~30 minutes. Enrolling\n // afterwards meant a user who paused on that dialog silently ended up\n // unenrolled — which only surfaces much later, on a new device, as a 409\n // from /signer/provision and a dead-end NewDeviceError.\n if (serverAssistedRecovery) {\n // NOT awaited. Enrolment is a network round-trip to the enclave (plus, on\n // a cold attestation cache, a DCAP verification), and awaiting it here\n // held the \"creating your wallet\" spinner open for the whole thing — up\n // to a minute when the enclave was slow, since each failed attempt was\n // also retried. The wallet is already complete and usable at this point;\n // the caller should not wait on a background durability step.\n //\n // Safe to defer only because 2.7.3 made enrolment self-healing: if this\n // is abandoned by a redirect, or fails outright, the next unlock detects\n // `enrolled: false` and repairs it. Before that existed, a missed\n // enrolment was permanent, which is why it used to run in the foreground.\n void enrolInBackground(jwt, new Uint8Array(shareSet.recovery));\n }\n\n // Offer to save the recovery share — DEFERRED, deliberately not awaited.\n //\n // By this point the wallet is finished: shares stored, session open,\n // enrolment done. The offer is post-creation UX that asks the user to\n // choose a password, so awaiting it here made connect() hang for as long as\n // the host app's modal took to settle — and forever if it never did. That\n // presented as a wallet that \"never finishes creating\", even though it had\n // been fully usable for some time; reloading and unlocking was instant,\n // because the wallet really was already there.\n //\n // Runs on a COPY of the recovery share: the original is zeroized below on\n // the critical path, and the copy is zeroized once the offer settles or its\n // deadline passes, so the extra exposure is bounded.\n if (config.offerRecoveryAtSignup === true && config.onRecoveryShareOffer) {\n void offerRecoveryShare(\n jwt,\n new Uint8Array(shareSet.recovery),\n { ...addresses },\n shareSet.version,\n evmAddress,\n solanaAddress,\n );\n }\n zeroize(shareSet.recovery);\n\n return addresses;\n }\n\n /**\n * Ask the user whether they want a recovery-share file, and build it if so.\n *\n * Split out of firstTimeSetup so it can run AFTER the wallet is returned to\n * the caller. Never throws: a declined, failed, or unresponsive offer must\n * leave the finished wallet alone. Takes ownership of `recoveryShare`.\n */\n async function offerRecoveryShare(\n jwt: string,\n recoveryShare: Uint8Array,\n addresses: { evm: string; solana: string; tron?: string },\n shareSetVersion: number,\n evmAddress: string,\n solanaAddress: string,\n ): Promise<void> {\n try {\n const choice = await withTimeout(\n config.onRecoveryShareOffer!({ evmAddress, solanaAddress }),\n RECOVERY_OFFER_TIMEOUT_MS,\n );\n if (!choice) {\n console.warn(\n \"decane-connect-kit: onRecoveryShareOffer did not settle within \" +\n `${RECOVERY_OFFER_TIMEOUT_MS / 60_000} minutes, so no recovery file was offered. ` +\n \"The wallet is unaffected — it was already created and enrolled — and the user can \" +\n \"generate a recovery share later via rotateShares(). Check that your handler \" +\n \"always resolves or rejects.\",\n );\n return;\n }\n if (!choice.wants) return;\n\n const file = await buildRecoveryShareFile(\n recoveryShare,\n choice.password,\n addresses,\n shareSetVersion,\n choice.passwordHint,\n );\n await config.onRecoveryFileReady?.(file, recoveryShareFileName(evmAddress));\n await api.markRecoveryShareSaved(jwt);\n } catch (e) {\n console.warn('decane-connect-kit: recovery share offer failed or was skipped.', e);\n } finally {\n zeroize(recoveryShare);\n }\n }\n\n // ── Returning-user unlock ────────────────────────────────────────────────\n\n async function returningUserUnlock(\n userId: string,\n jwt: string,\n ): Promise<{ evm: string; solana: string }> {\n // Treated as a *fallback*, not the truth: the signer derives the real\n // addresses from the key itself at session open and its answer wins (and\n // repairs this record). Missing addresses are therefore no longer fatal\n // here — the signer can supply them.\n const rawAddresses = await api.getAddresses(jwt);\n const recordedAddresses =\n rawAddresses.evm && rawAddresses.solana\n ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress(rawAddresses.evm) }\n : null;\n\n const stored = await storage.getShare(userId);\n\n let deviceShare: Uint8Array;\n // Tracks whether this share came from a passkey-sync recovery, i.e. it is a\n // copy of the backup every other synced device also holds. Under\n // rotateOnNewDeviceRecovery that has to be re-split once the session is\n // open, so this device ends up with a share nobody else has.\n let joinedViaPasskeySync = false;\n if (!stored) {\n // Checked BEFORE recovery starts, not inside the post-rotation callback.\n // Flow B rotates the whole set as part of recovering, which spends the\n // recovery file the user just supplied. Discovering only afterwards that\n // there is nowhere to hand them a replacement leaves them with a rotated\n // set and no way back — so refuse before the irreversible step instead.\n // ── Server-assisted provisioning (Flow S) ────────────────────────────\n // Tried FIRST: it is the only path needing nothing from the user. The\n // enclave holds two shares and issues this device a fresh one against the\n // JWT alone. Falls through when the wallet was never enrolled, so wallets\n // created before this existed keep working unchanged.\n if (serverAssistedRecovery) {\n try {\n const tee = new TeeClient(teeUrl);\n const provisioned = await tee.provisionDeviceShare(jwt);\n if (provisioned) {\n await registerPasskeyAndBackup(userId, jwt, provisioned).catch(() => {});\n let addrs: { evm: string; solana: string; tron?: string };\n try {\n addrs = await session.start(provisioned, jwt, recordedAddresses);\n } finally {\n zeroize(provisioned);\n }\n return addrs;\n }\n // null = HTTP 409 not_enrolled. Distinct from the catch below, and\n // worth saying out loud: this wallet holds no auth share, so the\n // enclave has one share of three and cannot mint a device share. The\n // user now needs a passkey backup or a recovery file, and without\n // either this ends in NewDeviceError.\n console.warn(\n \"decane-connect-kit: this wallet is not enrolled for server-assisted provisioning \" +\n \"(/signer/provision returned 409 not_enrolled), so a device share cannot be issued \" +\n \"from the JWT alone. Falling back to passkey sync, then the recovery file.\",\n );\n } catch (e) {\n // Never fatal: a provisioning outage must not lock out a user who\n // still holds a passkey or a recovery file.\n console.warn(\n \"decane-connect-kit: server-assisted provisioning unavailable; falling back to passkey/recovery-file recovery.\",\n e,\n );\n }\n }\n\n if (!config.onRecoveryRotated) {\n throw new CallSequenceError(\n \"Recovery rotates the share set and issues a new recovery file, but no onRecoveryRotated callback is configured to save it. Configure onRecoveryRotated before allowing recovery.\",\n );\n }\n // No local share — attempt recovery (Flow A passkey-sync, then Flow B\n // recovery-share file). Throws NewDeviceError if every path is exhausted.\n const recovered = await recoverDeviceShare({\n userId,\n jwt,\n rpId,\n teeUrl,\n api,\n storage,\n onProgress: config.onRecoveryProgress,\n promptForRecoveryFile: config.promptForRecoveryFile,\n onNewRecoveryShare: async (recoveryShare, shareSetVersion) => {\n // Every Flow B recovery rotates the whole set — the file the user\n // just used is dead now. This MUST get a new one saved; not\n // optional to skip, per MIGRATE_SSS_RECOVERY.md §10.\n // The absence of onRecoveryRotated is rejected before recovery\n // begins (see above), so it is guaranteed present here.\n if (!config.onRecoveryRotated) return;\n // Safe to use the recorded addresses here: /signer/recover only\n // returns a share set after confirming the reconstructed master\n // matches them, so reaching this callback proves they're correct.\n if (!recordedAddresses) return;\n const { password, passwordHint } = await config.onRecoveryRotated({ evmAddress: recordedAddresses.evm, solanaAddress: recordedAddresses.solana });\n const file = await buildRecoveryShareFile(recoveryShare, password, recordedAddresses, shareSetVersion, passwordHint);\n await config.onRecoveryFileReady?.(file, recoveryShareFileName(recordedAddresses.evm));\n await api.markRecoveryShareSaved(jwt);\n },\n });\n deviceShare = recovered.deviceShare;\n joinedViaPasskeySync = recovered.flow === 'passkey-sync';\n\n // If recovery went through Flow B (recovery-share file), there's still\n // no passkey on this device — provision one and back it up so the\n // *next* new device gets the easy Flow A instead of needing the file again.\n if (!(await storage.getShare(userId)) && isPasskeySupported()) {\n await registerPasskeyAndBackup(userId, jwt, deviceShare);\n }\n } else {\n const wrappingKey = await getWrappingKey(stored);\n try {\n deviceShare = await aesGcmDecrypt(\n wrappingKey,\n stored.wrappedDeviceShare,\n stored.iv,\n );\n } catch {\n throw stored.unlockMethod === \"pin\"\n ? new InvalidPinError()\n : new ShareCorruptedError();\n }\n }\n\n // The private key is never reconstructed here — the TEE fetches the\n // server share itself and combines it with the device share we send, and\n // returns the addresses that key actually controls. Those override the\n // recorded ones, which is what repairs an account whose users.evm_address\n // has drifted away from its key.\n let addresses: { evm: string; solana: string; tron?: string };\n try {\n addresses = await session.start(deviceShare, jwt, recordedAddresses);\n } catch (e) {\n // This device's share belongs to a superseded set — under\n // rotateOnNewDeviceRecovery that is the normal consequence of another\n // device joining, not a fault. Drop the dead share (and its useless\n // wrapping metadata) and recover a current one in its place, so the user\n // sees at most one extra passkey prompt instead of a hard failure.\n if (e instanceof StaleDeviceShareError) {\n zeroize(deviceShare);\n // Flow A caches the recovered share before the session is validated, so\n // a stale one has to be cleared here too — otherwise it is left behind\n // to fail again on the next connect().\n await storage.deleteShare(userId);\n // Only retry when the share came from local storage. If recovery just\n // produced a stale share, the synced backup itself is superseded and\n // retrying would recover the same dead bytes forever — surface it so\n // the user is routed to the recovery file instead.\n if (stored) return returningUserUnlock(userId, jwt);\n } else {\n zeroize(deviceShare);\n }\n throw e;\n }\n // Repair enrolment if this wallet never got an auth share (see\n // selfHealEnrolment). Deliberately not awaited: the wallet is already\n // usable, and the session we just opened is what the caller is waiting on.\n // Takes a COPY, because deviceShare is zeroized on the next line.\n void selfHealEnrolment(userId, jwt, new Uint8Array(deviceShare));\n zeroize(deviceShare);\n\n if (recordedAddresses && recordedAddresses.evm.toLowerCase() !== addresses.evm.toLowerCase()) {\n console.warn(\n `decane-connect-kit: recorded EVM address (${recordedAddresses.evm}) does not match the signing key (${addresses.evm}). Using the signing key's address; the record has been corrected.`\n );\n }\n\n // Per-device shares: this device joined by cloning the passkey-synced\n // backup, so right now it holds the same share as every other synced\n // device. Re-split so it gets one nobody else has — which is what makes a\n // later \"revoke that device\" possible at all. Deliberately AFTER the\n // session is open: rotation needs a live session, and a failure here must\n // leave a working wallet rather than a half-rotated one.\n if (joinedViaPasskeySync && config.rotateOnNewDeviceRecovery) {\n await rotateForNewDevice(userId, jwt);\n }\n\n return addresses;\n }\n\n /**\n * Re-split the share set so THIS device holds a unique share, invalidating\n * the copy every other passkey-synced device cached. Runs on a live session.\n *\n * Every surviving device now fails its next unlock with StaleDeviceShareError\n * and silently re-recovers — that is the intended cost of per-device\n * revocability, not a bug. The user's existing recovery FILE dies here too,\n * so the replacement must be handed back through onRecoveryRotated; that\n * callback's presence is validated at config time (see createDecaneConnect),\n * because discovering it missing at this point would strand the user with a\n * rotated set and a dead file.\n */\n async function rotateForNewDevice(userId: string, jwt: string): Promise<void> {\n const tee = session.requireActive();\n const result = await tee.rotateShares(jwt);\n try {\n // Must land before anything else can throw: the server has already\n // switched sets, so this device is unusable until the new share is stored.\n await persistRotatedDeviceShare(userId, result.deviceShare);\n\n // Refresh the synced backup too, or the next new device would recover the\n // now-dead share and immediately have to rotate again.\n const refreshed = await storage.getShare(userId);\n if (refreshed?.unlockMethod === \"passkey\" && refreshed.credentialId && refreshed.prfSalt) {\n await api\n .putRecoveryBackup(jwt, {\n wrappedDeviceShare: refreshed.wrappedDeviceShare,\n iv: refreshed.iv,\n unlockMethod: \"passkey\",\n credentialId: refreshed.credentialId,\n prfSalt: refreshed.prfSalt,\n })\n .catch((e) => {\n console.warn('decane-connect-kit: backup refresh after device rotation failed; the next new device will need the recovery file.', e);\n });\n }\n\n const addrs = await deriveAddressesFromShares(result.deviceShare, result.recoveryShare);\n const { password, passwordHint } = await config.onRecoveryRotated!({\n evmAddress: addrs.evm,\n solanaAddress: addrs.solana,\n });\n const file = await buildRecoveryShareFile(\n result.recoveryShare,\n password,\n addrs,\n result.shareSetVersion,\n passwordHint,\n );\n await config.onRecoveryFileReady?.(file, recoveryShareFileName(addrs.evm));\n await api.markRecoveryShareSaved(jwt);\n } finally {\n zeroize(result.deviceShare);\n zeroize(result.recoveryShare);\n }\n }\n\n // ── Passkey sign-in (returning user, same device) ────────────────────────\n\n /**\n * True when this device can sign the user straight back in with their\n * passkey, skipping Google/email entirely.\n *\n * Requires all three: a remembered identity, a passkey-wrapped share sitting\n * in IndexedDB, and platform support. A PIN-wrapped share doesn't qualify —\n * a PIN proves nothing to the backend, so those users still need the normal\n * flow to obtain a JWT.\n */\n async function passkeyLoginCandidate(): Promise<StoredShare | null> {\n if (!persisted?.userId || !isPasskeySupported()) return null;\n const stored = await storage.getShare(persisted.userId);\n if (!stored || stored.unlockMethod !== \"passkey\") return null;\n if (!stored.credentialId || !stored.prfSalt) return null;\n return stored;\n }\n\n async function passkeyLogin(stored: StoredShare): Promise<ConnectResult> {\n const userId = stored.userId;\n events.emit(\"wallet-unlocking\");\n\n const options = await api.getWebAuthnLoginOptions(userId, rpId);\n if (!options) {\n // No server-side credential — this wallet predates passkey sign-in, or\n // the registration never completed. Not an error, just not available.\n throw new NewDeviceError();\n }\n\n // One prompt, two outputs: the signed assertion authenticates, the PRF\n // output unwraps. See authenticateWithPasskey.\n const { response, prfOutput } = await authenticateWithPasskey({\n optionsJSON: options,\n prfSalt: stored.prfSalt!,\n });\n if (!prfOutput) throw new ShareCorruptedError();\n\n const result = await api.postWebAuthnLogin(userId, response, window.location.origin);\n\n let deviceShare: Uint8Array;\n try {\n deviceShare = await aesGcmDecrypt(\n await importAesKey(prfOutput),\n stored.wrappedDeviceShare,\n stored.iv,\n );\n } catch {\n throw new ShareCorruptedError();\n }\n\n const rawAddresses = await api.getAddresses(result.jwt);\n const recordedAddresses =\n rawAddresses.evm && rawAddresses.solana\n ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress(rawAddresses.evm) }\n : null;\n\n const addresses = await session.start(deviceShare, result.jwt, recordedAddresses);\n zeroize(deviceShare);\n\n auth = { jwt: result.jwt, userId, addresses };\n persisted = { userId, addresses };\n savePersisted(PERSIST_KEY, persisted);\n events.emit(\"connected\");\n persistLiveSession();\n\n return { addresses, isNewUser: false };\n }\n\n // ── Shared post-auth flow ────────────────────────────────────────────────\n\n async function handleAuthResult(result: AuthResult): Promise<ConnectResult> {\n let addresses: { evm: string; solana: string };\n\n if (!result.hasShare) {\n // Multi-second flow: generate key, split shares, register passkey, open\n // TEE session. Signal it so the UI can show progress rather than freezing.\n events.emit(\"wallet-creating\");\n addresses = await firstTimeSetup(result.userId, result.jwt);\n } else {\n events.emit(\"wallet-unlocking\");\n addresses = await returningUserUnlock(result.userId, result.jwt);\n }\n\n auth = { jwt: result.jwt, userId: result.userId, addresses };\n persisted = { userId: result.userId, addresses };\n savePersisted(PERSIST_KEY, persisted);\n events.emit(\"connected\");\n persistLiveSession();\n\n return {\n addresses,\n isNewUser: result.isNewUser,\n ...(result.profile ? { profile: result.profile } : {}),\n };\n }\n\n // ── Public API ───────────────────────────────────────────────────────────\n\n const client: DecaneConnect = {\n async connect(): Promise<ConnectResult> {\n if (auth && session.isActive()) {\n return { addresses: auth.addresses, isNewUser: false };\n }\n\n // Returning user on a device that still holds their passkey-wrapped\n // share: their passkey is sufficient proof of identity, so don't send\n // them back through Google/email. A cancelled prompt propagates (they\n // chose to stop); anything else falls through to the normal flow so a\n // backend or authenticator problem can't lock them out of their wallet.\n const candidate = await passkeyLoginCandidate();\n if (candidate) {\n try {\n return await passkeyLogin(candidate);\n } catch (e: unknown) {\n if (e instanceof UserCancelledError) throw e;\n console.warn(\"decane-connect-kit: passkey sign-in unavailable, falling back to standard sign-in.\", e);\n }\n }\n\n const method = config.authMethods[0];\n if (!method) throw new CallSequenceError(\"No authMethods configured\");\n if (method === \"google\") return client.connectWithGoogle();\n if (method === \"kingschat\") return client.connectWithKingsChat();\n if (method === \"email\")\n throw new CallSequenceError(\n \"Use connectWithEmail(email) for email auth\",\n );\n throw new CallSequenceError(`Unknown auth method: ${method}`);\n },\n\n async connectWithGoogle(): Promise<ConnectResult> {\n const params = new URLSearchParams(window.location.search);\n const decaneJwt = params.get(\"decane_jwt\");\n const decaneError = params.get(\"decane_error\");\n\n if (decaneError) {\n // Clean params from URL\n window.history.replaceState({}, \"\", window.location.pathname);\n throw new CallSequenceError(`Google sign-in failed: ${decaneError}`);\n }\n\n if (decaneJwt) {\n // Backend already exchanged the code and redirected here with the result\n const name = params.get(\"decane_name\");\n const email = params.get(\"decane_email\");\n const picture = params.get(\"decane_picture\");\n const profile = {\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n ...(picture ? { picture } : {}),\n };\n const result = {\n jwt: decaneJwt,\n userId: params.get(\"decane_user_id\") ?? \"\",\n isNewUser: params.get(\"decane_is_new_user\") === \"true\",\n hasShare: params.get(\"decane_has_share\") === \"true\",\n // Omitted entirely when Google released nothing, so callers can test\n // `result.profile` rather than an object that is always present but\n // sometimes empty.\n ...(Object.keys(profile).length ? { profile } : {}),\n };\n // Clean all decane_* params from the URL\n window.history.replaceState({}, \"\", window.location.pathname);\n return handleAuthResult(result);\n }\n\n // No result yet — ask the backend for the Google consent URL and redirect there\n const { url } = await api.getGoogleInitUrl();\n window.location.href = url;\n // Promise never resolves — browser is navigating away\n return new Promise(() => {});\n },\n\n async connectWithGoogleToken(idToken: string): Promise<ConnectResult> {\n if (!idToken) throw new CallSequenceError(\"connectWithGoogleToken requires an ID token\");\n return handleAuthResult(await api.authGoogleToken(idToken));\n },\n\n async connectWithKingsChat(): Promise<ConnectResult> {\n // The clientId is fetched BEFORE the popup opens rather than inside\n // loginWithKingsChatPopup, so that window.open still runs inside the\n // user's click. Awaiting first and opening after is what popup blockers\n // reject — and the failure is silent, so it must not be possible here.\n const { clientId } = await api.getKingsChatConfig();\n const tokens = await loginWithKingsChatPopup({\n clientId,\n scopes: config.kingsChatScopes,\n });\n return client.connectWithKingsChatToken(tokens.accessToken);\n },\n\n async connectWithKingsChatToken(accessToken: string): Promise<ConnectResult> {\n if (!accessToken) {\n throw new CallSequenceError(\"connectWithKingsChatToken requires an access token\");\n }\n const result = await api.authKingsChat(accessToken);\n return handleAuthResult(result);\n },\n\n async connectWithToken(token: string, opts?: { providerId?: string }): Promise<ConnectResult> {\n if (!token) throw new CallSequenceError(\"connectWithToken requires a token\");\n const result = await api.authExternal(token, opts?.providerId);\n return handleAuthResult(result);\n },\n\n async connectWithEmail(email: string) {\n await startEmailAuth(api, email);\n return { codeRequired: true as const };\n },\n\n async verifyEmailCode(email: string, code: string): Promise<ConnectResult> {\n const result = await apiVerifyEmailCode(api, email, code);\n return handleAuthResult(result);\n },\n\n async canSignInWithPasskey(): Promise<boolean> {\n return (await passkeyLoginCandidate()) !== null;\n },\n\n async signInWithPasskey(): Promise<ConnectResult> {\n const candidate = await passkeyLoginCandidate();\n if (!candidate) throw new NewDeviceError();\n return passkeyLogin(candidate);\n },\n\n async unlock(): Promise<void> {\n // Session gone but the passkey is still here — re-authenticate with it\n // rather than raising ReconnectRequiredError and bouncing the user\n // through a sign-in they don't need.\n if (!auth) {\n const candidate = await passkeyLoginCandidate();\n if (candidate) {\n await passkeyLogin(candidate);\n return;\n }\n }\n if (!auth) {\n // Distinguish \"we know you, but your session is gone\" (the common\n // case after a reload) from \"you genuinely never connected\". Only the\n // former is recoverable, and only by re-authenticating — see\n // ReconnectRequiredError. Callers should check needsReconnect() first.\n throw persisted\n ? new ReconnectRequiredError()\n : new CallSequenceError(\"Not connected — call connect() first\");\n }\n if (session.isActive()) return;\n await returningUserUnlock(auth.userId, auth.jwt);\n },\n\n isUnlocked(): boolean {\n return session.isActive();\n },\n\n /**\n * True when we have a persisted identity but no live auth state, i.e.\n * unlock() cannot succeed and the user must sign in again. Exposed on the\n * client (not just the React context) so non-React consumers can branch on\n * it without having to catch ReconnectRequiredError.\n */\n needsReconnect(): boolean {\n return !auth && !!persisted;\n },\n\n sessionExpiresAt(): number | null {\n return session.expiresAtTimestamp();\n },\n\n async signMessage(req: SignMessageRequest): Promise<string> {\n const tee = session.requireActive();\n if (req.chain.startsWith(\"evm:\")) {\n return signEvmMessage(tee, req.chain, req.message as string, auth?.jwt);\n }\n if (req.chain.startsWith(\"solana:\")) {\n const msg =\n typeof req.message === \"string\"\n ? new TextEncoder().encode(req.message)\n : req.message;\n const sig = await signSolanaMessage(tee, req.chain, msg, auth?.jwt);\n return bufferToB64u(sig);\n }\n if (req.chain.startsWith(\"tron:\")) {\n // Tron message signing (TIP-191 / signMessageV2) is the same routine as\n // EVM personal_sign; the enclave applies the Ethereum prefix and signs.\n const msg =\n typeof req.message === \"string\"\n ? req.message\n : new TextDecoder().decode(req.message);\n return tee.sign({ chain: req.chain, kind: \"message\", payload: msg }, auth?.jwt);\n }\n throw new CallSequenceError(`Unsupported chain: ${req.chain}`);\n },\n\n async sendTransaction(req: SendTransactionRequest): Promise<string> {\n const tee = session.requireActive();\n if (!req.chain.startsWith(\"evm:\")) {\n throw new CallSequenceError(\n \"sendTransaction is EVM-only. Use signSolanaTransaction for Solana.\",\n );\n }\n if (!auth?.addresses.evm) {\n throw new CallSequenceError(\"Not connected\");\n }\n const evmAddr = auth.addresses.evm;\n\n const rpcUrl = config.rpcUrls?.[req.chain] ?? DEFAULT_RPCS[req.chain];\n if (!rpcUrl) {\n throw new CallSequenceError(\n `No RPC URL for ${req.chain}. Pass rpcUrls: { '${req.chain}': 'https://...' } in social config.`,\n );\n }\n\n // Dynamic import keeps JsonRpcProvider out of the SSR bundle\n const { JsonRpcProvider } = await import('ethers');\n const provider = new JsonRpcProvider(rpcUrl);\n const chainId = parseInt(req.chain.slice(4), 10);\n\n // Fetch nonce, gas estimate, and fee data in parallel\n const [nonce, feeData] = await Promise.all([\n provider.getTransactionCount(evmAddr, \"pending\"),\n provider.getFeeData(),\n ]);\n\n const gasLimit =\n req.gasLimit ??\n (await provider.estimateGas({\n from: evmAddr,\n to: req.to,\n value: req.value ?? 0n,\n data: req.data,\n }));\n\n const tx: TransactionRequest = {\n to: req.to,\n value: req.value ?? 0n,\n data: req.data,\n gasLimit,\n chainId,\n nonce,\n // EIP-1559 fees — fall back to legacy gasPrice if unavailable\n ...(feeData.maxFeePerGas != null\n ? {\n maxFeePerGas: feeData.maxFeePerGas,\n maxPriorityFeePerGas: feeData.maxPriorityFeePerGas ?? 0n,\n }\n : { gasPrice: req.gasPrice ?? feeData.gasPrice ?? undefined }),\n };\n\n // Signed by the TEE — the browser never holds the key.\n const signedTx = await signEvmTransaction(tee, req.chain, tx, auth?.jwt);\n const txResponse = await provider.broadcastTransaction(signedTx);\n\n // Record it in the user's history — best-effort, never blocks or fails the\n // send (the transaction is already broadcast; a history write is secondary).\n if (auth?.jwt) {\n void api\n .recordTransaction(auth.jwt, {\n chain: req.chain,\n txHash: txResponse.hash,\n to: req.to,\n value: (req.value ?? 0n).toString(),\n kind: \"send\",\n })\n .catch(() => {});\n }\n\n return txResponse.hash;\n },\n\n async signTypedData(req: SignTypedDataRequest): Promise<string> {\n const tee = session.requireActive();\n if (!req.chain.startsWith(\"evm:\")) {\n throw new CallSequenceError(\"signTypedData is EVM-only (EIP-712).\");\n }\n return signEvmTypedData(\n tee,\n req.chain,\n {\n domain: req.domain,\n types: req.types,\n message: req.message,\n primaryType: req.primaryType,\n },\n auth?.jwt,\n );\n },\n\n async signAuthorization(req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) {\n const tee = session.requireActive();\n const delegate = req.address ?? req.contractAddress;\n if (!delegate) throw new CallSequenceError(\"signAuthorization requires `address` (the delegate contract).\");\n return signEvmAuthorization(tee, req.chainId, delegate, req.nonce, auth?.jwt);\n },\n\n // The current session's access token (the Decane JWT), for authenticating\n // the user to your own backend — e.g. a sponsored-bundler proxy. Verify it\n // server-side against https://backend.decane.app/.well-known/jwks.json.\n // Null when there is no live session.\n getAccessToken(): string | null {\n return auth?.jwt ?? null;\n },\n\n async recordTransaction(tx: RecordTransactionInput): Promise<TransactionRecord> {\n if (!auth?.jwt) throw new CallSequenceError(\"Not connected — call connect() first\");\n return api.recordTransaction(auth.jwt, tx);\n },\n\n async getTransactionHistory(limit = 50): Promise<TransactionRecord[]> {\n if (!auth?.jwt) throw new CallSequenceError(\"Not connected — call connect() first\");\n return api.getTransactions(auth.jwt, limit);\n },\n\n getEthereumProvider(opts?: { chainId?: number }) {\n if (!ethProvider) {\n const firstEvm = config.chains.find((c) => c.startsWith(\"evm:\"));\n const defaultChainId = firstEvm ? parseInt(firstEvm.slice(4), 10) : 1;\n ethProvider = createEthereumProvider(client, {\n chainId: opts?.chainId ?? defaultChainId,\n rpcUrls: config.rpcUrls,\n });\n }\n return ethProvider;\n },\n\n async signSolanaTransaction(serializedTx: Uint8Array): Promise<Uint8Array> {\n const tee = session.requireActive();\n let tx: Transaction | VersionedTransaction;\n try {\n tx = VersionedTransaction.deserialize(serializedTx);\n } catch {\n tx = Transaction.from(serializedTx);\n }\n // The public API doesn't take a chain param here — use the first\n // configured Solana chain (mainnet/devnet), same as before.\n const solChain = config.chains.find((c) => c.startsWith(\"solana:\")) ?? \"solana:mainnet\";\n return signSolanaTransaction(tee, solChain, tx, auth?.jwt);\n },\n\n async signTronTransaction(rawDataHex: string): Promise<string> {\n const tee = session.requireActive();\n // The public API doesn't take a chain param — use the first configured\n // Tron chain, defaulting to mainnet. The enclave computes the txID\n // (sha256(raw_data)) and signs it with the same key as the EVM wallet.\n const tronChain = config.chains.find((c) => c.startsWith(\"tron:\")) ?? \"tron:mainnet\";\n return tee.sign(\n { chain: tronChain, kind: \"transaction\", payload: rawDataHex.replace(/^0x/, \"\") },\n auth?.jwt,\n );\n },\n\n async disconnect(): Promise<void> {\n session.end();\n if (auth?.jwt) {\n await api.revoke(auth.jwt).catch(() => {});\n }\n auth = null;\n persisted = null;\n clearPersisted(PERSIST_KEY);\n dropLiveSession();\n events.emit(\"disconnected\");\n },\n\n getAddresses() {\n return auth?.addresses ?? persisted?.addresses ?? null;\n },\n\n // Native-token balance. Read-only public chain data, so it works whenever an\n // address is known — including while the wallet is locked (no TEE session\n // needed). `chain` defaults to the first configured EVM chain, else the\n // first Solana chain.\n async getBalance(chain?: string): Promise<BalanceResult> {\n const addresses = auth?.addresses ?? persisted?.addresses;\n if (!addresses) throw new CallSequenceError(\"Not connected — no wallet address known\");\n\n const resolvedChain =\n chain ??\n config.chains.find((c) => c.startsWith(\"evm:\")) ??\n config.chains.find((c) => c.startsWith(\"solana:\"));\n if (!resolvedChain) throw new CallSequenceError(\"No chain configured\");\n\n const kind = resolvedChain.startsWith(\"solana:\") ? \"solana\" : \"evm\";\n const address = kind === \"evm\" ? addresses.evm : addresses.solana;\n if (!address) throw new CallSequenceError(`This wallet has no ${kind} address`);\n\n return fetchBalanceImpl({ kind, address, chain: resolvedChain, rpcUrls: config.rpcUrls });\n },\n\n // Balances across every configured chain the wallet has an address for.\n // Per-chain failures resolve to null rather than rejecting the whole call,\n // so one dead RPC doesn't blank the entire list.\n async getBalances(): Promise<Array<{ chain: string; balance: BalanceResult | null }>> {\n const addresses = auth?.addresses ?? persisted?.addresses;\n if (!addresses) throw new CallSequenceError(\"Not connected — no wallet address known\");\n\n const targets = config.chains.filter((c) => {\n const kind = c.startsWith(\"solana:\") ? \"solana\" : \"evm\";\n return kind === \"evm\" ? !!addresses.evm : !!addresses.solana;\n });\n\n return Promise.all(\n targets.map(async (chain) => {\n const kind = chain.startsWith(\"solana:\") ? \"solana\" : \"evm\";\n const address = (kind === \"evm\" ? addresses.evm : addresses.solana) as string;\n try {\n return { chain, balance: await fetchBalanceImpl({ kind, address, chain, rpcUrls: config.rpcUrls }) };\n } catch {\n return { chain, balance: null };\n }\n }),\n );\n },\n\n async rotateShares(opts: { password: string; passwordHint?: string }): Promise<RecoveryShareFile> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const tee = session.requireActive();\n const result = await tee.rotateShares(auth.jwt);\n try {\n // Must happen before anything else can fail: the server has already\n // switched to the new set, so this device is unusable until the\n // replacement share is stored.\n await persistRotatedDeviceShare(auth.userId, result.deviceShare);\n const addresses = await deriveAddressesFromShares(result.deviceShare, result.recoveryShare);\n const file = await buildRecoveryShareFile(\n result.recoveryShare,\n opts.password,\n addresses,\n result.shareSetVersion,\n opts.passwordHint\n );\n await api.markRecoveryShareSaved(auth.jwt);\n return file;\n } finally {\n zeroize(result.deviceShare);\n zeroize(result.recoveryShare);\n }\n },\n\n async exportPortableBackup(opts: { password: string; passwordHint?: string }): Promise<PortableBackup> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const tee = session.requireActive();\n const result = await tee.exportPortableBackup(auth.jwt);\n try {\n // Exporting rotates the share set server-side, so the same rule as\n // rotateShares() applies: store the replacement before doing anything\n // that could throw first.\n await persistRotatedDeviceShare(auth.userId, result.deviceShare);\n const addresses = await deriveAddressesFromShares(result.deviceShare, result.recoveryShare);\n return await buildPortableBackup(\n result.deviceShare,\n result.recoveryShare,\n opts.password,\n addresses,\n result.shareSetVersion,\n opts.passwordHint\n );\n } finally {\n zeroize(result.deviceShare);\n zeroize(result.recoveryShare);\n }\n },\n\n async hasRecoveryShare(): Promise<boolean> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const status = await api.getRecoveryStatus(auth.jwt);\n return status.hasRecoveryShare;\n },\n\n async shouldPromptRecovery(): Promise<boolean> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const status = await api.getRecoveryStatus(auth.jwt);\n if (status.hasRecoveryShare || status.nagged) return false;\n\n // \"Holds a non-zero balance\" — check every chain type this wallet\n // actually has an address for, so the one-time nag only fires once\n // there's something real at stake, not on an empty new wallet.\n try {\n const checks: Promise<boolean>[] = [];\n if (auth.addresses.evm) {\n const { JsonRpcProvider } = await import(\"ethers\");\n for (const chain of config.chains.filter((c) => c.startsWith(\"evm:\"))) {\n const rpcUrl = config.rpcUrls?.[chain] ?? DEFAULT_RPCS[chain];\n if (!rpcUrl) continue;\n checks.push(\n new JsonRpcProvider(rpcUrl)\n .getBalance(auth.addresses.evm)\n .then((b) => b > 0n)\n .catch(() => false)\n );\n }\n }\n if (auth.addresses.solana && config.chains.some((c) => c.startsWith(\"solana:\"))) {\n const { Connection, PublicKey } = await import(\"@solana/web3.js\");\n const solChain = config.chains.find((c) => c.startsWith(\"solana:\")) ?? \"solana:mainnet\";\n const cluster = solChain.slice(\"solana:\".length);\n const endpoint = cluster === \"devnet\" ? \"https://api.devnet.solana.com\" : \"https://api.mainnet-beta.solana.com\";\n checks.push(\n new Connection(endpoint)\n .getBalance(new PublicKey(auth.addresses.solana))\n .then((b) => b > 0)\n .catch(() => false)\n );\n }\n const results = await Promise.all(checks);\n return results.some(Boolean);\n } catch {\n // Fail closed on annoyance, not on safety — if balance-checking\n // itself breaks, don't nag rather than risk nagging incorrectly.\n return false;\n }\n },\n\n async dismissRecoveryPrompt(): Promise<void> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n await api.dismissRecoveryNag(auth.jwt);\n },\n\n async hasBackup(): Promise<boolean> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n return api.hasRecoveryBackup(auth.jwt);\n },\n\n async deleteBackup(): Promise<void> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n await api.deleteRecoveryBackup(auth.jwt);\n },\n\n on: events.on.bind(events),\n off: events.off.bind(events),\n };\n\n return client;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction bufferToB64u(buf: Uint8Array): string {\n return btoa(String.fromCharCode(...buf))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n\nfunction b64uToBuffer(b64u: string): Uint8Array {\n const b64 = b64u.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return \"0x\" + Array.from(bytes).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n// A Tron account is derived from the SAME secp256k1 key as the EVM wallet — the\n// address is just a re-encoding of the EVM address: prepend the 0x41 Tron\n// mainnet prefix, append a double-SHA256 checksum, Base58-encode. No new key.\nfunction evmToTronAddress(evmAddress: string): string {\n const hex41 = \"41\" + evmAddress.toLowerCase().replace(/^0x/, \"\");\n const checksum = sha256(sha256(\"0x\" + hex41)).slice(2, 10);\n return encodeBase58(\"0x\" + hex41 + checksum);\n}\n\n/**\n * Derive the real EVM/Solana addresses from two shares by momentarily\n * reconstructing the master. Used when building a recovery-share file or\n * portable backup: the browser already holds both shares in plaintext at\n * that moment (they're being written to a file), so this adds no new\n * exposure — but it guarantees the file's plaintext `addresses` field is\n * always correct by construction, rather than trusting a separately\n * tracked value (e.g. auth.addresses) that could go stale if some other\n * code path — server-side or client-side — ever desyncs from the real\n * current key. The master is zeroized immediately after use.\n */\nasync function deriveAddressesFromShares(\n a: Uint8Array,\n b: Uint8Array,\n): Promise<{ evm: string; solana: string; tron: string }> {\n const master = await combineShares(a, b);\n try {\n const evm = new Wallet(toHex(master)).address;\n return {\n evm,\n solana: Keypair.fromSeed(master).publicKey.toBase58(),\n tron: evmToTronAddress(evm),\n };\n } finally {\n zeroize(master);\n }\n}\n","import type { SdkEvent } from './types';\n\ntype Handler = (...args: unknown[]) => void;\n\nexport class EventEmitter {\n private _listeners = new Map<string, Set<Handler>>();\n\n emit(event: SdkEvent, ...args: unknown[]): void {\n this._listeners.get(event)?.forEach(h => h(...args));\n }\n\n on(event: SdkEvent, handler: Handler): void {\n if (!this._listeners.has(event)) this._listeners.set(event, new Set());\n this._listeners.get(event)!.add(handler);\n }\n\n off(event: SdkEvent, handler: Handler): void {\n this._listeners.get(event)?.delete(handler);\n }\n}\n","import { NetworkError, InvalidApiKeyError, OriginNotAllowedError, ReconnectRequiredError } from './errors';\nimport type { AuthResult, WrappedShareMeta, TransactionRecord } from './types';\n\nconst ERROR_MAP: Record<string, new (...args: never[]) => Error> = {\n INVALID_API_KEY: InvalidApiKeyError,\n ORIGIN_NOT_ALLOWED: OriginNotAllowedError,\n // The backend's authMiddleware code for an expired/revoked JWT. Surfacing it\n // as ReconnectRequiredError routes callers to the sign-in UI instead of a\n // generic failure message.\n UNAUTHORIZED: ReconnectRequiredError,\n};\n\n// Ceiling on any single backend call. Generous enough that a slow mobile\n// connection still completes, short enough that a dead connection surfaces as a\n// retryable error instead of an indefinite hang inside signup or unlock.\nconst REQUEST_TIMEOUT_MS = 30_000;\n\nexport class ApiClient {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly appId: string,\n ) {}\n\n private async _request<T>(path: string, init?: RequestInit): Promise<T>;\n private async _request<T>(path: string, init: RequestInit & { allow404: true }): Promise<T | null>;\n private async _request<T>(path: string, init?: RequestInit & { allow404?: boolean }): Promise<T | null> {\n let res: Response;\n // fetch() has no default timeout, so without this a stalled connection hangs\n // the caller forever. That is not hypothetical here: these calls sit inside\n // wallet creation and unlock, where a hang strands the user mid-flow with no\n // error and no way forward. An abort surfaces as NetworkError, which callers\n // already handle and which is marked retryable.\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n ...init,\n signal: controller.signal,\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n 'X-App-Id': this.appId,\n ...init?.headers,\n },\n });\n } catch {\n throw new NetworkError();\n } finally {\n clearTimeout(timer);\n }\n\n if (res.status === 404 && init?.allow404) return null;\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({})) as { error?: { code?: string; message?: string } };\n const code = body?.error?.code ?? 'UNKNOWN';\n const msg = body?.error?.message ?? `Request failed: ${res.status}`;\n const Ctor = ERROR_MAP[code];\n if (Ctor) throw new (Ctor as new (msg: string) => Error)(msg);\n throw new Error(msg);\n }\n\n return res.json() as Promise<T>;\n }\n\n async getGoogleInitUrl(): Promise<{ url: string }> {\n return this._request('/auth/google/init', { method: 'GET' });\n }\n\n\n /**\n * Exchange a Google ID token the app already holds for a Decane session.\n * Resolves to the SAME identity as the redirect flow, so one Google account\n * means one wallet across web and mobile.\n */\n async authGoogleToken(idToken: string): Promise<AuthResult> {\n return this._request('/auth/google/token', {\n method: 'POST',\n body: JSON.stringify({ idToken }),\n });\n }\n\n /** The project's KingsChat clientId, so the dApp never has to hardcode it. */\n async getKingsChatConfig(): Promise<{ clientId: string; authorizationUrl: string }> {\n return this._request('/auth/kingschat/config', { method: 'GET' });\n }\n\n /**\n * Exchange a KingsChat access token for a Decane session. The backend spends\n * the token against KingsChat's own API to establish the identity — it is\n * never trusted on its face, and never stored.\n */\n async authKingsChat(accessToken: string): Promise<AuthResult> {\n return this._request('/auth/kingschat', {\n method: 'POST',\n body: JSON.stringify({ accessToken }),\n });\n }\n\n async authEmailStart(email: string): Promise<void> {\n await this._request('/auth/email/start', {\n method: 'POST',\n body: JSON.stringify({ email }),\n });\n }\n\n async authEmailVerify(email: string, code: string): Promise<AuthResult> {\n return this._request('/auth/email/verify', {\n method: 'POST',\n body: JSON.stringify({ email, code }),\n });\n }\n\n // GET /share (the server share itself) was removed as part of the TEE\n // migration — the browser must never reconstruct the private key anymore.\n // Only public addresses are fetched from the backend now.\n async getAddresses(jwt: string): Promise<{ evm: string | null; solana: string | null; tron: string | null }> {\n return this._request('/share/addresses', {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async putShare(jwt: string, share: {\n ciphertext: Uint8Array;\n iv: Uint8Array;\n wrappedShareMeta: WrappedShareMeta;\n evmAddress: string;\n solanaAddress: string;\n tronAddress: string;\n }): Promise<void> {\n await this._request('/share', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify({\n ciphertext: bytesToB64(share.ciphertext),\n iv: bytesToB64(share.iv),\n wrappedShareMeta: btoa(JSON.stringify(share.wrappedShareMeta)),\n evmAddress: share.evmAddress,\n solanaAddress: share.solanaAddress,\n tronAddress: share.tronAddress,\n }),\n });\n }\n\n // ── Transaction history ───────────────────────────────────────────────────\n\n async recordTransaction(jwt: string, tx: {\n chain: string;\n txHash?: string;\n to?: string;\n value?: string;\n kind?: string;\n status?: string;\n metadata?: Record<string, unknown>;\n }): Promise<TransactionRecord> {\n const body = await this._request('/transactions', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify(tx),\n }) as { transaction: TransactionRecord };\n return body.transaction;\n }\n\n async getTransactions(jwt: string, limit = 50): Promise<TransactionRecord[]> {\n const body = await this._request(`/transactions?limit=${encodeURIComponent(String(limit))}`, {\n headers: { Authorization: `Bearer ${jwt}` },\n }) as { transactions: TransactionRecord[] };\n return body.transactions;\n }\n\n // ── WebAuthn registration (additive to the PRF-only passkey flow) ─────────\n\n async getWebAuthnRegisterOptions(jwt: string, rpId: string, rpName: string): Promise<import('@simplewebauthn/browser').PublicKeyCredentialCreationOptionsJSON> {\n return this._request(`/webauthn/register-options?rpId=${encodeURIComponent(rpId)}&rpName=${encodeURIComponent(rpName)}`, {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async postWebAuthnRegister(\n jwt: string,\n response: import('@simplewebauthn/browser').RegistrationResponseJSON,\n origin: string\n ): Promise<void> {\n await this._request('/webauthn/register', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify({ response, origin }),\n });\n }\n\n /**\n * Exchange a token from the developer's own auth system for a Decane\n * session. `providerId` is only needed when the project has more than one\n * provider configured.\n */\n async authExternal(token: string, providerId?: string): Promise<AuthResult> {\n return this._request('/auth/external', {\n method: 'POST',\n body: JSON.stringify(providerId ? { token, providerId } : { token }),\n });\n }\n\n /**\n * Returns null when this user has no server-registered passkey, which is the\n * expected answer for wallets created before passkey sign-in existed or for\n * PIN-only users — the caller falls back to the normal sign-in flow.\n */\n async getWebAuthnLoginOptions(\n userId: string,\n rpId: string\n ): Promise<import('@simplewebauthn/browser').PublicKeyCredentialRequestOptionsJSON | null> {\n return this._request('/webauthn/login-options', {\n method: 'POST',\n body: JSON.stringify({ userId, rpId }),\n allow404: true,\n });\n }\n\n async postWebAuthnLogin(\n userId: string,\n response: import('@simplewebauthn/browser').AuthenticationResponseJSON,\n origin: string\n ): Promise<AuthResult> {\n return this._request('/webauthn/login', {\n method: 'POST',\n body: JSON.stringify({ userId, response, origin }),\n });\n }\n\n async revoke(jwt: string): Promise<void> {\n await this._request('/auth/revoke', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n // ── Recovery (passkey-sync backup + recovery-share-saved flag) ────────────\n\n async hasRecoveryBackup(jwt: string): Promise<boolean> {\n const data = await this._request<{ exists: boolean }>('/recovery/backup/exists', {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n return data.exists;\n }\n\n async getRecoveryBackup(jwt: string): Promise<{\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey';\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n formatVersion: number;\n } | null> {\n const data = await this._request<{\n wrappedDeviceShare: string;\n iv: string;\n unlockMethod: 'passkey';\n credentialId: string;\n prfSalt: string;\n formatVersion: number;\n }>('/recovery/backup', {\n headers: { Authorization: `Bearer ${jwt}` },\n allow404: true,\n });\n if (!data) return null;\n return {\n wrappedDeviceShare: b64ToBytes(data.wrappedDeviceShare),\n iv: b64ToBytes(data.iv),\n unlockMethod: data.unlockMethod,\n credentialId: b64ToBytes(data.credentialId),\n prfSalt: b64ToBytes(data.prfSalt),\n formatVersion: data.formatVersion,\n };\n }\n\n async putRecoveryBackup(jwt: string, backup: {\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey';\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n }): Promise<void> {\n await this._request('/recovery/backup', {\n method: 'PUT',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify({\n wrappedDeviceShare: bytesToB64(backup.wrappedDeviceShare),\n iv: bytesToB64(backup.iv),\n unlockMethod: backup.unlockMethod,\n credentialId: bytesToB64(backup.credentialId),\n prfSalt: bytesToB64(backup.prfSalt),\n }),\n });\n }\n\n async deleteRecoveryBackup(jwt: string): Promise<void> {\n await this._request('/recovery/backup', {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async markRecoveryShareSaved(jwt: string): Promise<void> {\n await this._request('/recovery/share-saved', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async getRecoveryStatus(jwt: string): Promise<{\n hasRecoveryShare: boolean;\n savedAt: string | null;\n nagged: boolean;\n shareSetVersion: number;\n /**\n * Whether this wallet is enrolled for server-assisted provisioning, i.e.\n * whether a new device can be given a device share from login alone.\n * Optional because backends older than this field simply omit it — treat\n * `undefined` as \"unknown\", never as \"not enrolled\".\n */\n enrolled?: boolean;\n }> {\n return this._request('/recovery/status', {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async dismissRecoveryNag(jwt: string): Promise<void> {\n await this._request('/recovery/nag-dismissed', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n}\n\nfunction bytesToB64(bytes: Uint8Array): string {\n return btoa(String.fromCharCode(...bytes));\n}\n\nfunction b64ToBytes(b64: string): Uint8Array {\n return Uint8Array.from(atob(b64), c => c.charCodeAt(0));\n}\n","import { openDB, type IDBPDatabase } from 'idb';\n\nexport interface StoredShare {\n userId: string;\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey' | 'pin';\n credentialId?: Uint8Array;\n prfSalt?: Uint8Array;\n pinSalt?: Uint8Array;\n pinIterations?: number;\n version: number;\n}\n\nconst DB_NAME = 'decane-connect-kit';\nconst STORE = 'shares';\n\nexport class Storage {\n private _db: Promise<IDBPDatabase>;\n\n constructor() {\n this._db = openDB(DB_NAME, 1, {\n upgrade(db) {\n db.createObjectStore(STORE, { keyPath: 'userId' });\n },\n });\n }\n\n async getShare(userId: string): Promise<StoredShare | null> {\n return ((await this._db).get(STORE, userId)) ?? null;\n }\n\n async putShare(share: StoredShare): Promise<void> {\n await (await this._db).put(STORE, share);\n }\n\n async deleteShare(userId: string): Promise<void> {\n await (await this._db).delete(STORE, userId);\n }\n}\n","import { sha256, encodeBase58 } from 'ethers';\nimport { TeeClient } from './teeClient';\nimport { EventEmitter } from './events';\nimport { UnlockRequiredError } from './errors';\n\n// Tron shares the EVM secp256k1 key — its address is the EVM address re-encoded:\n// 0x41 prefix + double-SHA256 checksum, Base58. See client.ts for the full note.\nfunction evmToTronAddress(evmAddress: string): string {\n const hex41 = '41' + evmAddress.toLowerCase().replace(/^0x/, '');\n const checksum = sha256(sha256('0x' + hex41)).slice(2, 10);\n return encodeBase58('0x' + hex41 + checksum);\n}\n\nexport class SessionManager {\n private tee: TeeClient | null = null;\n private evmAddress: string | null = null;\n private solanaAddress: string | null = null;\n private tronAddress: string | null = null;\n private expiresAt: number | null = null;\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private events: EventEmitter,\n private durationMs: number,\n private teeUrl: string,\n private requireAssertionPerSignature = false\n ) {\n // NOTE: we deliberately do NOT close the session on pagehide anymore. Doing\n // so killed the server session on every reload, forcing a fresh sign-in each\n // time — terrible UX on flaky networks. The session now survives a reload so\n // it can be resumed from sessionStorage (see the client's persistence). On a\n // real tab close, sessionStorage is cleared, so the lingering server session\n // is unreachable and simply expires at its TTL — no security loss, since the\n // client holds no key material (the TEE does) and the handle is gone.\n }\n\n private setExpiryTimer(effectiveMs: number): void {\n if (this.timeoutId) clearTimeout(this.timeoutId);\n this.timeoutId = setTimeout(() => {\n this.end();\n this.events.emit('session-expired');\n }, Math.max(0, effectiveMs));\n }\n\n /** The live session handle, for persisting a resumable session across reloads. */\n getHandle(): string | null {\n return this.tee?.getHandle() ?? null;\n }\n\n /**\n * Resume a persisted session without re-authenticating: adopt the handle,\n * addresses, and expiry from storage. No key material or prompt involved — the\n * TEE still holds the shares behind this handle. If the handle turns out to be\n * dead (server restarted, TTL passed), the next sign() fails and the caller\n * reconnects; nothing here can sign on its own.\n */\n resume(handle: string, addresses: { evm: string; solana: string; tron?: string }, expiresAtMs: number): void {\n this.tee = new TeeClient(this.teeUrl);\n this.tee.adoptHandle(handle, this.requireAssertionPerSignature);\n this.evmAddress = addresses.evm;\n this.solanaAddress = addresses.solana;\n this.tronAddress = addresses.tron ?? evmToTronAddress(addresses.evm);\n this.expiresAt = expiresAtMs;\n this.setExpiryTimer(expiresAtMs - Date.now());\n this.events.emit('session-started');\n }\n\n /**\n * Opens the TEE session and resolves which addresses this wallet really has.\n *\n * `fallback` is whatever the backend recorded; the TEE's answer is derived\n * from the signing key itself and therefore outranks it. Returns the\n * resolved addresses so callers can propagate the corrected values rather\n * than continuing to use a stale record.\n */\n async start(\n deviceShare: Uint8Array,\n jwt: string,\n fallback: { evm: string; solana: string; tron?: string } | null\n ): Promise<{ evm: string; solana: string; tron: string }> {\n this.tee = new TeeClient(this.teeUrl);\n const verified = await this.tee.openSession(\n deviceShare,\n jwt,\n this.requireAssertionPerSignature\n );\n\n // Fail rather than silently downgrade. If the caller asked for a prompt on\n // every signature and the signer won't honour it (older build), signing\n // anyway would give them the smooth UX and none of the guarantee, which is\n // the one outcome nobody asked for.\n if (this.requireAssertionPerSignature && !this.tee.requiresAssertionPerSignature()) {\n void this.tee.closeSession();\n this.tee = null;\n throw new Error(\n 'requireAssertionPerSignature was requested but this signer does not support it — ' +\n 'refusing to open a session with weaker authority than configured.'\n );\n }\n\n const resolved = verified ?? fallback;\n if (!resolved) {\n this.tee = null;\n throw new Error(\n 'No addresses available for this wallet — the signer could not derive them and none are recorded'\n );\n }\n\n // Tron shares the EVM key, so derive it from the resolved EVM address when\n // the signer (older build) didn't return one.\n const addresses = { evm: resolved.evm, solana: resolved.solana, tron: resolved.tron ?? evmToTronAddress(resolved.evm) };\n\n this.evmAddress = addresses.evm;\n this.solanaAddress = addresses.solana;\n this.tronAddress = addresses.tron;\n\n // Honour whichever expiry is sooner: our configured duration, or the\n // lifetime the signer actually granted (it clamps to the JWT's exp, so it\n // can be shorter). Counting down past the signer's session would leave the\n // UI showing time the handle no longer has, and signing would fail while\n // the clock still read green.\n const serverTtlMs = this.tee.sessionExpiresIn();\n const effectiveMs =\n serverTtlMs != null ? Math.min(this.durationMs, serverTtlMs * 1000) : this.durationMs;\n this.expiresAt = Date.now() + effectiveMs;\n\n if (this.timeoutId) clearTimeout(this.timeoutId);\n this.timeoutId = setTimeout(() => {\n this.end();\n this.events.emit('session-expired');\n }, effectiveMs);\n\n this.events.emit('session-started');\n return addresses;\n }\n\n end(): void {\n void this.tee?.closeSession();\n this.tee = null;\n this.evmAddress = null;\n this.solanaAddress = null;\n this.tronAddress = null;\n this.expiresAt = null;\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n\n isActive(): boolean {\n return this.tee !== null && Date.now() < (this.expiresAt ?? 0);\n }\n\n expiresAtTimestamp(): number | null {\n return this.expiresAt;\n }\n\n requireActive(): TeeClient {\n if (!this.isActive()) throw new UnlockRequiredError();\n return this.tee!;\n }\n\n addresses(): { evm: string; solana: string; tron: string } | null {\n if (!this.evmAddress || !this.solanaAddress) return null;\n return {\n evm: this.evmAddress,\n solana: this.solanaAddress,\n tron: this.tronAddress ?? evmToTronAddress(this.evmAddress),\n };\n }\n}\n","import { startAuthentication } from '@simplewebauthn/browser';\nimport type { AuthenticationResponseJSON } from '@simplewebauthn/browser';\nimport { verifyTeeAttestation } from './attestation';\nimport { SessionExpiredError, ExportNotAuthorizedError, ReconnectRequiredError } from './errors';\n\nfunction bytesToBase64(b: Uint8Array): string {\n let s = '';\n for (const byte of b) s += String.fromCharCode(byte);\n return btoa(s);\n}\nfunction base64ToBytes(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\n\n// Every enclave call is bounded. fetch() has no default timeout, so without this\n// a stalled connection to the TEE hangs wallet creation or unlock indefinitely —\n// the SDK would sit forever with no error and no way forward. An abort surfaces\n// as a normal request failure, which each caller already handles.\nconst TEE_TIMEOUT_MS = 30_000;\n\nasync function teeFetch(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), TEE_TIMEOUT_MS);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\n// Attestation is cached per enclave URL, not per client instance.\n//\n// A fresh TeeClient is constructed for every session open, enrolment and\n// provisioning call, and ensureAttested() previously ran a full DCAP\n// verification for each one — fetching a quote, pulling collateral from Intel's\n// PCS, and running the WASM verifier. Wallet creation alone did that at least\n// twice, back to back, for the same enclave. It is the slowest thing on the\n// critical path and the answer cannot differ between two calls seconds apart.\n//\n// The promise is cached (not just the result) so concurrent callers share one\n// in-flight verification instead of racing several. A TTL bounds how stale the\n// proof can get: long enough to cover a whole create/unlock flow, short enough\n// that a swapped CVM is re-detected within minutes. A failed verification is\n// evicted immediately so the next call retries rather than caching a rejection.\nconst ATTESTATION_TTL_MS = 10 * 60_000;\nconst attestationCache = new Map<string, { at: number; promise: Promise<void> }>();\n\nfunction attestOnce(teeUrl: string, verify: () => Promise<void>): Promise<void> {\n const hit = attestationCache.get(teeUrl);\n if (hit && Date.now() - hit.at < ATTESTATION_TTL_MS) return hit.promise;\n\n const promise = verify().catch((e: unknown) => {\n attestationCache.delete(teeUrl);\n throw e;\n });\n attestationCache.set(teeUrl, { at: Date.now(), promise });\n return promise;\n}\n\n/**\n * Verify the enclave ahead of time so the cost overlaps with work that does not\n * depend on it (key generation, share storage) instead of sitting on the\n * critical path. Never throws — a real failure resurfaces at the call that\n * actually needs attestation.\n */\nexport function prewarmAttestation(teeUrl: string): void {\n void attestOnce(teeUrl, async () => {\n const nonce = crypto.getRandomValues(new Uint8Array(16));\n const nonceHex = Array.from(nonce)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n await verifyTeeAttestation(teeUrl, nonceHex);\n }).catch(() => {});\n}\n\nexport interface SignRequest {\n chain: string;\n kind: 'transaction' | 'message' | 'typedData' | 'authorization';\n payload: string; // hex (EVM tx) | base64 (Solana) | raw string (message) | JSON (typedData/authorization)\n txHash?: string; // required for EVM transactions\n}\n\nexport interface ResplitResult {\n deviceShare: Uint8Array;\n recoveryShare: Uint8Array;\n shareSetVersion: number;\n}\n\nexport class TeeClient {\n private handle: string | null = null;\n private attested = false;\n /** Mirrors what the signer confirmed for this session, not what we asked for. */\n private assertionPerSignature = false;\n /** The signer's authoritative remaining lifetime (seconds), null until a session opens. */\n private sessionExpiresInSec: number | null = null;\n\n constructor(private teeUrl: string) {}\n\n /** Whether this session actually got per-signature assertions. */\n requiresAssertionPerSignature(): boolean {\n return this.assertionPerSignature;\n }\n\n /**\n * The lifetime the signer granted this session, in seconds — which can be\n * shorter than the client's configured duration when the JWT expires first.\n * Null if the signer didn't report one (older build). Callers clamp their own\n * countdown to this so it never promises time the handle doesn't have.\n */\n sessionExpiresIn(): number | null {\n return this.sessionExpiresInSec;\n }\n\n /** The opaque session handle, so a live session can be persisted and resumed after a reload. */\n getHandle(): string | null {\n return this.handle;\n }\n\n /**\n * Adopt a handle from a persisted session (page reload) instead of opening a\n * new one. The session was already attested when first opened, and the handle\n * is bound to that CVM session — a swapped CVM would simply not recognise it —\n * so re-attestation is skipped. If the handle has expired server-side, the\n * first sign() 401s and clears it, falling back to a normal reconnect.\n */\n adoptHandle(handle: string, assertionPerSignature: boolean): void {\n this.handle = handle;\n this.assertionPerSignature = assertionPerSignature;\n this.attested = true;\n }\n\n private async ensureAttested(): Promise<void> {\n if (this.attested) return;\n await attestOnce(this.teeUrl, async () => {\n const nonce = crypto.getRandomValues(new Uint8Array(16));\n const nonceHex = Array.from(nonce)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n await verifyTeeAttestation(this.teeUrl, nonceHex);\n });\n this.attested = true;\n }\n\n /**\n * Opens a signing session and returns the addresses the TEE derived from the\n * key it actually reconstructed — authoritative, unlike the backend's\n * recorded copy, which nothing else can verify. Returns null if the TEE\n * couldn't derive them (older signer build, or a transient share-fetch\n * failure); callers fall back to the backend's addresses in that case.\n */\n async openSession(\n deviceShare: Uint8Array,\n jwt: string,\n requireAssertionPerSignature = false,\n ): Promise<{ evm: string; solana: string; tron?: string } | null> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/session`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n deviceShare: bytesToBase64(deviceShare),\n requireAssertionPerSignature,\n }),\n });\n // The signer fails CLOSED on a share that reconstructs a key other than the\n // one on record (see assertKeyMatchesRecord in the TEE). That is exactly\n // what a device holding a superseded share looks like after another device\n // rotated the set, so surface it as its own recoverable error rather than a\n // generic failure — the caller drops the dead share and re-recovers.\n if (res.status === 403) {\n const body = await res.json().catch(() => ({}));\n if (body?.error === 'share_mismatch') {\n const { StaleDeviceShareError } = await import('./errors');\n throw new StaleDeviceShareError();\n }\n }\n if (!res.ok) throw new Error('session open failed');\n const body = await res.json();\n this.handle = body.handle;\n // Trust the echo, not the request: an older signer build silently ignores\n // the field, and quietly signing without the prompts the caller asked for\n // would be worse than failing. Surfaced via requiresAssertionPerSignature()\n // so client.ts can refuse rather than downgrade.\n this.assertionPerSignature = body.requireAssertionPerSignature === true;\n this.sessionExpiresInSec = typeof body.expiresIn === 'number' ? body.expiresIn : null;\n return body.addresses ?? null;\n }\n\n /**\n * Flow B: exchange a recovery share (from a recovery-share file) for a\n * fresh device share. The server verifies the reconstructed master\n * actually matches this account's addresses before returning anything —\n * see the security note in the TEE's /signer/recover handler. Rotates the\n * whole share set: the caller MUST persist the returned recoveryShare as a\n * new recovery-share file, since the old one stops working immediately.\n */\n async recoverWithShare(jwt: string, recoveryShare: Uint8Array): Promise<ResplitResult> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/recover`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ recoveryShare: bytesToBase64(recoveryShare) }),\n });\n if (res.status === 403) {\n const { RecoveryWalletMismatchError } = await import('./errors');\n throw new RecoveryWalletMismatchError();\n }\n if (!res.ok) throw new Error('recovery failed');\n const body = await res.json();\n return {\n deviceShare: base64ToBytes(body.deviceShare),\n recoveryShare: base64ToBytes(body.recoveryShare),\n shareSetVersion: body.shareSetVersion,\n };\n }\n\n /**\n * Request a fresh WebAuthn assertion challenge and complete it in the\n * browser via @simplewebauthn/browser's startAuthentication(), which\n * handles all the base64url (de)serialization the raw navigator.credentials\n * API requires. Shared by rotateShares() and exportPortableBackup() — both\n * require proof of fresh authenticator possession, not just an active session.\n */\n private async completeAssertion(jwt: string): Promise<{ challengeId: string; assertion: AuthenticationResponseJSON }> {\n const res = await teeFetch(`${this.teeUrl}/signer/assertion-challenge`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ rpId: window.location.hostname }),\n });\n // The signer 401s here ONLY when the JWT fails verification (all other\n // failures are 400), so this is \"your login expired — sign in again\",\n // not \"the security check was refused\". Conflating the two showed users\n // an export-authorization error for what is really a stale token.\n if (res.status === 401) throw new ReconnectRequiredError();\n if (!res.ok) throw new ExportNotAuthorizedError();\n const { challengeId, options } = await res.json();\n\n let assertion: AuthenticationResponseJSON;\n try {\n assertion = await startAuthentication({ optionsJSON: options });\n } catch {\n const { UserCancelledError } = await import('./errors');\n throw new UserCancelledError();\n }\n return { challengeId, assertion };\n }\n\n\n /**\n * Enrol this wallet for server-assisted provisioning by handing the enclave\n * the recovery share to seal.\n *\n * After this, a new device gets a working share from login alone — no passkey\n * sync, no recovery file. The enclave seals the share under a key only it can\n * derive, so the backend stores ciphertext it cannot read; but the enclave\n * then holds two of three shares and can reconstruct on its own. That is the\n * trade this call makes, which is why it is opt-out rather than implicit.\n */\n async enrolAuthShare(jwt: string, recoveryShare: Uint8Array): Promise<void> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/auth-share`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ share: bytesToBase64(recoveryShare) }),\n });\n // Carry the status through: enrolment failure is swallowed by the caller\n // (a failed enrolment must not undo a good wallet), so this message is the\n // only trace of WHY a wallet later fails to provision. 403 = wallet\n // mismatch (addresses missing or not matching the reconstructed key), 401 =\n // bad/expired JWT or the enclave's own backend call failed, 429 = rate\n // limited.\n if (!res.ok) {\n const detail = await res.text().catch(() => '');\n throw new Error(\n `auth share enrolment failed (HTTP ${res.status})${detail ? `: ${detail.slice(0, 200)}` : ''}`,\n );\n }\n }\n\n /**\n * Ask the enclave for a fresh device share for this authenticated user.\n * Returns null when the wallet was never enrolled — the signal to fall back\n * to passkey sync or the recovery file rather than fail.\n *\n * Every successful call re-splits the set, so any share this device or any\n * other held is now dead. Intentional: a leaked device share stops working the\n * next time the user signs in anywhere.\n */\n async provisionDeviceShare(jwt: string): Promise<Uint8Array | null> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/provision`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n });\n if (res.status === 409) return null; // not enrolled\n if (!res.ok) {\n const detail = await res.text().catch(() => '');\n throw new Error(\n `device share provisioning failed (HTTP ${res.status})${detail ? `: ${detail.slice(0, 200)}` : ''}`,\n );\n }\n const body = await res.json();\n return base64ToBytes(body.deviceShare);\n }\n\n /** Voluntary rotation — e.g. after a suspected device compromise, or to invalidate an old recovery file. */\n async rotateShares(jwt: string): Promise<ResplitResult> {\n if (!this.handle) throw new Error('no session');\n const { challengeId, assertion } = await this.completeAssertion(jwt);\n const res = await teeFetch(`${this.teeUrl}/signer/rotate`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ handle: this.handle, challengeId, assertion, origin: window.location.origin }),\n });\n if (!res.ok) throw new ExportNotAuthorizedError();\n const body = await res.json();\n return {\n deviceShare: base64ToBytes(body.deviceShare),\n recoveryShare: base64ToBytes(body.recoveryShare),\n shareSetVersion: body.shareSetVersion,\n };\n }\n\n /** The two-share bearer portable backup — see recovery/portableBackup.ts. Rotates the set on export. */\n async exportPortableBackup(jwt: string): Promise<ResplitResult> {\n if (!this.handle) throw new Error('no session');\n const { challengeId, assertion } = await this.completeAssertion(jwt);\n const res = await teeFetch(`${this.teeUrl}/signer/export-portable`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ handle: this.handle, challengeId, assertion, origin: window.location.origin }),\n });\n if (!res.ok) throw new ExportNotAuthorizedError();\n const body = await res.json();\n return {\n deviceShare: base64ToBytes(body.deviceShare),\n recoveryShare: base64ToBytes(body.recoveryShare),\n shareSetVersion: body.shareSetVersion,\n };\n }\n\n hasSession(): boolean {\n return this.handle !== null;\n }\n\n /**\n * `jwt` is only needed when this session requires per-signature assertions —\n * it authenticates the challenge request. Passed per call rather than cached\n * on the instance deliberately: JWT lifetime is configured independently of\n * the TEE session TTL (they are aligned at 30min by default, but an operator\n * can shorten JWT_EXPIRY_SECONDS), so a stored copy could go stale mid-session.\n */\n async sign(req: SignRequest, jwt?: string): Promise<string> {\n if (!this.handle) throw new Error('no session');\n\n let gate: { challengeId: string; assertion: AuthenticationResponseJSON } | null = null;\n if (this.assertionPerSignature) {\n if (!jwt) throw new Error('sign requires a jwt when per-signature assertion is enabled');\n // One challenge per signature. completeAssertion throws\n // UserCancelledError if the user dismisses the prompt, which propagates\n // as a refusal — the signature simply does not happen.\n gate = await this.completeAssertion(jwt);\n }\n\n const res = await teeFetch(`${this.teeUrl}/signer/sign`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n handle: this.handle,\n ...req,\n ...(gate ? { ...gate, origin: window.location.origin } : {}),\n }),\n });\n if (res.status === 401) {\n // An assertion rejection is also a 401, but it must not be read as an\n // expired session — the handle is still perfectly good and dropping it\n // would force a needless full reconnect.\n const body = await res.clone().json().catch(() => ({}));\n if (body?.error === 'assertion_required') {\n throw new ExportNotAuthorizedError();\n }\n this.handle = null;\n throw new SessionExpiredError();\n }\n if (!res.ok) throw new Error('sign failed');\n return (await res.json()).signature;\n }\n\n async closeSession(): Promise<void> {\n if (!this.handle) return;\n const handle = this.handle;\n this.handle = null;\n void fetch(`${this.teeUrl}/signer/close`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ handle }),\n }).catch(() => {});\n }\n}\n","import { getCollateralAndVerify, type VerifiedReport } from '@phala/dcap-qvl';\nimport { AttestationError } from './errors';\n// packages/decane-connect-kit/src/social/attestation.ts -> repo root is 4\n// levels up (src/social -> src -> decane-connect-kit -> packages -> root).\nimport measurementConfig from '../../../../infra/tee-measurement.json';\n\nexport { AttestationError };\n\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n const bytes = new Uint8Array(Math.floor(clean.length / 2));\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * CORRECTED (found while typechecking, 2026-07-20) against the real\n * @phala/dcap-qvl 0.5.2 type definitions — the doc this was drafted from\n * assumed `getCollateralAndVerify()` returns `{ valid: boolean, reportData }`.\n * Neither field exists. The real `VerifiedReport` shape is:\n * { status: TcbStatus, advisory_ids: string[], report: Report, ppid: Buffer }\n * with the actual TDX report (containing `reportData`, `mrTd`, `rtMr0..3`)\n * reached via `report.asTd10()` / `report.asTd15()`.\n *\n * Two things below are INFERRED from the type shape, not empirically\n * confirmed against a real quote (blocked on Stage 3 — no CVM or dstack\n * simulator has been exercised yet):\n * - That getCollateralAndVerify THROWS on an invalid signature/cert chain\n * rather than returning some failure sentinel (the non-nullable,\n * no-error-variant return type strongly suggests this, matching the\n * usual Rust Result<T,E> -> JS throw-on-Err binding pattern, but this\n * is inference, not confirmation).\n * - The padding/hashing convention dstack-sdk uses to embed a <64-byte\n * nonce into the 64-byte `reportData` field (assumed here: left-aligned,\n * zero-padded, unhashed). A real quote is needed to confirm this.\n * Both must be verified against a real quote before this is trustworthy.\n */\nexport async function verifyTeeAttestation(teeUrl: string, nonce: string): Promise<void> {\n const res = await fetch(`${teeUrl}/attestation`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ nonce }),\n });\n if (!res.ok) throw new AttestationError('quote fetch failed');\n const { quote, measurement } = await res.json();\n\n // 1. Signature chains to Intel's root CA — proves a real TDX enclave.\n let verified: VerifiedReport;\n try {\n verified = await getCollateralAndVerify(hexToBytes(quote));\n } catch {\n throw new AttestationError('quote signature invalid');\n }\n\n // A verified-but-revoked platform is a real TDX chip with a known,\n // unpatched vulnerability — reject it same as a bad signature.\n if (verified.status === 'Revoked') {\n throw new AttestationError('TEE platform TCB status is Revoked');\n }\n\n // 2. Quote binds to our nonce — proves freshness, blocks replay.\n const td = verified.report.asTd10() ?? verified.report.asTd15()?.base;\n if (!td) throw new AttestationError('quote is not a TDX report');\n const reportDataHex = bytesToHex(td.reportData);\n if (!reportDataHex.toLowerCase().startsWith(nonce.toLowerCase())) {\n throw new AttestationError('quote nonce mismatch');\n }\n\n // 3. Measurement is one we pinned — proves it's our audited code.\n // infra/tee-measurement.json is currently a placeholder with an empty\n // acceptedMrtd, so this intentionally fails closed until Stage 3\n // (Phala provisioning + real measurement capture) has run.\n const accepted = measurementConfig.acceptedMrtd.map((m: string) => m.toLowerCase());\n if (!accepted.includes(String(measurement).toLowerCase())) {\n throw new AttestationError(\n `TEE measurement not accepted. Got ${measurement}, expected one of ${accepted.join(', ') || '(none configured yet)'}`\n );\n }\n}\n","{\n \"signerVersion\": \"0.1.3\",\n \"acceptedMrtd\": [\n \"[\\\"68102e7b524af310f7b7d426ce75481e36c40f5d513a9009c046e9d37e31551f0134d954b496a3357fd61d03f07ffe96\\\",\\\"07e6f51aa763abfe75c3ddfbf4f425fe3f0ceff66d807a75e049303dce9addf68e7218729bd419638af63a370f65878c\\\",\\\"a2a58c9a959a4fa44bd6da0c97a2270c051faf12084cfe91ae900e4fdff6cdd4f69a82005e04ee920f231497894d677f\\\",\\\"a76a81147b7f733cb400914c8791ec149bb3a31f3727b1c1e12ec22e9c1a183b6e617e78636dca37075f5a695afd46c2\\\"]\"\n ],\n \"primaryMrtd\": \"[\\\"68102e7b524af310f7b7d426ce75481e36c40f5d513a9009c046e9d37e31551f0134d954b496a3357fd61d03f07ffe96\\\",\\\"07e6f51aa763abfe75c3ddfbf4f425fe3f0ceff66d807a75e049303dce9addf68e7218729bd419638af63a370f65878c\\\",\\\"a2a58c9a959a4fa44bd6da0c97a2270c051faf12084cfe91ae900e4fdff6cdd4f69a82005e04ee920f231497894d677f\\\",\\\"a76a81147b7f733cb400914c8791ec149bb3a31f3727b1c1e12ec22e9c1a183b6e617e78636dca37075f5a695afd46c2\\\"]\",\n \"capturedAt\": \"2026-07-20T10:08:58.717Z\",\n \"tcbStatus\": \"UpToDate\",\n \"_note\": \"Captured from a live, signature-verified TDX quote (getCollateralAndVerify -> UpToDate) against decane-tee-signer v0.1.3 running on Phala Cloud CVM 786e714d-5042-4bf1-8060-0bc358f6a72f. measurement is the JSON.stringify(replayRtmrs()) output, compared as an opaque string (not parsed per-RTMR), matching the actual comparison logic in social/attestation.ts.\"\n}\n","// @noble/curves is used solely to validate a generated master secret lies in\n// secp256k1's valid scalar range [1, n-1] before use — 32 random bytes fall\n// outside that range with negligible-but-nonzero probability, and this\n// matters because the master is exportable to third-party wallets via the\n// offline recovery tool (see recovery/portableBackup.ts).\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { split, combine } from 'shamir-secret-sharing';\nimport type { ShareSet } from './shareTypes';\n\nexport function generateRandomBytes(n: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(n));\n}\n\n/** Overwrites a byte array with zeroes to wipe sensitive material from memory. */\nexport function zeroize(bytes: Uint8Array): void {\n bytes.fill(0);\n}\n\n/**\n * Generate a master secret valid on both curves.\n * secp256k1 requires a scalar in [1, n-1]; Ed25519 accepts any 32 bytes as a\n * seed, so no equivalent check applies there.\n */\nexport function generateMaster(): Uint8Array {\n let master: Uint8Array;\n do {\n master = generateRandomBytes(32);\n } while (!secp256k1.utils.isValidPrivateKey(master));\n return master;\n}\n\n/**\n * Split a master into a 2-of-3 Shamir share set (device, server, recovery).\n * Any two shares reconstruct the master; one alone reveals nothing.\n * Does not zeroize `master` — the caller owns it and is responsible for\n * zeroizing it once splitting (and any address derivation) is done.\n */\nexport async function splitMaster(master: Uint8Array, version = 1): Promise<ShareSet> {\n if (master.length !== 32) throw new Error('master must be 32 bytes');\n const parts = await split(master, 3, 2);\n if (parts.length !== 3) throw new Error('unexpected share count');\n return { device: parts[0]!, server: parts[1]!, recovery: parts[2]!, version };\n}\n\n/**\n * Reconstruct the master from any two shares. Caller must zeroize the result.\n *\n * IMPORTANT: this function does NOT verify the shares actually belong to the\n * same share set — shamir-secret-sharing's combine() will silently produce\n * some 32-byte output even for two shares from unrelated splits (empirically\n * verified, not just theoretical: it does not throw). Any caller combining\n * shares where one side is caller-supplied (e.g. a recovery share submitted\n * over the network) MUST verify the result against known-good addresses\n * before trusting or returning anything derived from it. See the security\n * notes on the TEE signer's /signer/recover and /signer/export-portable.\n */\nexport async function combineShares(a: Uint8Array, b: Uint8Array): Promise<Uint8Array> {\n const master = await combine([a, b]);\n if (master.length !== 32) throw new Error('reconstruction produced wrong length');\n return master;\n}\n","/** AES-256-GCM wrap / unwrap using window.crypto.subtle. */\n\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nexport async function importAesKey(rawKey: Uint8Array): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'raw', buf(rawKey),\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n );\n}\n\nexport async function aesGcmEncrypt(\n key: CryptoKey,\n plaintext: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(plaintext));\n return new Uint8Array(ct);\n}\n\nexport async function aesGcmDecrypt(\n key: CryptoKey,\n ciphertext: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n const pt = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(ciphertext));\n return new Uint8Array(pt);\n}\n","const PBKDF2_ITERATIONS = 600_000;\n\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nexport async function deriveKeyFromPin(pin: string, salt: Uint8Array): Promise<CryptoKey> {\n const pinBytes = new TextEncoder().encode(pin);\n const base = await crypto.subtle.importKey('raw', buf(pinBytes), 'PBKDF2', false, ['deriveKey']);\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: buf(salt), iterations: PBKDF2_ITERATIONS, hash: 'SHA-256' },\n base,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n );\n}\n\nexport function validatePin(pin: string): void {\n if (!/^\\d{4,8}$/.test(pin)) throw new Error('PIN must be 4–8 digits');\n}\n","import { startRegistration, startAuthentication } from '@simplewebauthn/browser';\nimport type {\n PublicKeyCredentialCreationOptionsJSON,\n PublicKeyCredentialRequestOptionsJSON,\n RegistrationResponseJSON,\n AuthenticationResponseJSON,\n} from '@simplewebauthn/browser';\nimport { WebAuthnNotSupportedError, UserCancelledError } from '../errors';\n\nfunction b64u(u: Uint8Array): string {\n return btoa(String.fromCharCode(...u)).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\nfunction fromB64u(s: string): Uint8Array {\n return Uint8Array.from(atob(s.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0));\n}\n\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nexport function isPasskeySupported(): boolean {\n return (\n typeof window !== 'undefined' &&\n !!window.PublicKeyCredential &&\n 'isUserVerifyingPlatformAuthenticatorAvailable' in window.PublicKeyCredential\n );\n}\n\n/**\n * One WebAuthn registration ceremony serving two purposes at once:\n * 1. The PRF extension output (unchanged from before) becomes the AES key\n * that wraps the device share — purely client-side, Decane never sees it.\n * 2. The raw, real registration response is returned alongside it so the\n * caller can forward it to the backend's /webauthn/register for\n * server-side signature verification — this is what lets\n * /signer/rotate and /signer/export-portable gate on a genuine signed\n * assertion later, independent of the PRF flow.\n *\n * `optionsJSON` must come from the backend's /webauthn/register-options\n * (real, server-tracked challenge) — the caller is responsible for injecting\n * the prf extension into it before calling this, since the PRF salt is a\n * purely client-side concept the generic registration endpoint doesn't know\n * about. See social/webauthnRegistration.ts for the full orchestration.\n */\nexport async function registerPasskey(opts: {\n optionsJSON: PublicKeyCredentialCreationOptionsJSON;\n}): Promise<{ credentialId: Uint8Array; prfOutput?: Uint8Array; response: RegistrationResponseJSON }> {\n let response: RegistrationResponseJSON;\n try {\n response = await startRegistration({ optionsJSON: opts.optionsJSON });\n } catch (e: unknown) {\n if ((e as Error).name === 'NotAllowedError') throw new UserCancelledError();\n throw e;\n }\n\n const extResults = response.clientExtensionResults as Record<string, unknown> | undefined;\n const prfResults = (extResults?.prf as { results?: { first?: ArrayBuffer | string } } | undefined)?.results;\n let prfOutput: Uint8Array | undefined;\n if (prfResults?.first) {\n prfOutput = typeof prfResults.first === 'string'\n ? Uint8Array.from(atob(prfResults.first.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0))\n : new Uint8Array(prfResults.first);\n }\n\n const credentialId = Uint8Array.from(\n atob(response.id.replace(/-/g, '+').replace(/_/g, '/')),\n (c) => c.charCodeAt(0)\n );\n\n return { credentialId, prfOutput, response };\n}\n\n/**\n * One assertion ceremony that both authenticates the user and unwraps their\n * device share.\n *\n * The server-issued challenge is signed (proving possession of the passkey, so\n * the backend can mint a session JWT without a Google/email round trip) while\n * the PRF extension evaluates the stored salt in the same call, yielding the\n * AES key for the wrapped device share. Doing these separately would cost the\n * user two biometric prompts back to back for one sign-in.\n *\n * `prfOutput` is undefined when the authenticator declines PRF; the caller\n * must then fall back rather than assume the share can be unwrapped.\n */\nexport async function authenticateWithPasskey(opts: {\n optionsJSON: PublicKeyCredentialRequestOptionsJSON;\n prfSalt: Uint8Array;\n}): Promise<{ response: AuthenticationResponseJSON; prfOutput?: Uint8Array }> {\n // @simplewebauthn/browser (v13) does NOT process the PRF extension — it passes\n // `extensions` straight through to navigator.credentials.get(). So prf.eval.first\n // must be a real ArrayBuffer here, NOT a base64url string; a string reaches the\n // browser as-is and throws \"not of type (ArrayBuffer or ArrayBufferView)\". The\n // registration side (webauthnRegistration.ts) and getPrfOutput already do this;\n // this path was the one still passing a string.\n const optionsJSON: PublicKeyCredentialRequestOptionsJSON = {\n ...opts.optionsJSON,\n extensions: {\n ...opts.optionsJSON.extensions,\n prf: { eval: { first: buf(opts.prfSalt) } },\n } as unknown as PublicKeyCredentialRequestOptionsJSON['extensions'],\n };\n\n let response: AuthenticationResponseJSON;\n try {\n response = await startAuthentication({ optionsJSON });\n } catch (e: unknown) {\n if ((e as Error).name === 'NotAllowedError') throw new UserCancelledError();\n throw e;\n }\n\n const ext = response.clientExtensionResults as Record<string, unknown> | undefined;\n const prfResults = (ext?.['prf'] as { results?: { first?: ArrayBuffer | string } } | undefined)?.results;\n let prfOutput: Uint8Array | undefined;\n if (prfResults?.first) {\n prfOutput =\n typeof prfResults.first === 'string'\n ? fromB64u(prfResults.first)\n : new Uint8Array(prfResults.first);\n }\n\n return { response, prfOutput };\n}\n\nexport async function getPrfOutput(opts: {\n rpId: string;\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n}): Promise<Uint8Array> {\n const challenge = crypto.getRandomValues(new Uint8Array(32));\n\n let cred: PublicKeyCredential;\n try {\n cred = (await navigator.credentials.get({\n publicKey: {\n challenge: buf(challenge),\n rpId: opts.rpId,\n allowCredentials: [{ id: buf(opts.credentialId), type: 'public-key' }],\n userVerification: 'required',\n extensions: { prf: { eval: { first: buf(opts.prfSalt) } } } as AuthenticationExtensionsClientInputs,\n },\n })) as PublicKeyCredential;\n } catch (e: unknown) {\n if ((e as Error).name === 'NotAllowedError') throw new UserCancelledError();\n throw e;\n }\n\n const ext = cred.getClientExtensionResults() as Record<string, unknown>;\n const prfResults = (ext?.prf as { results?: { first?: ArrayBuffer } } | undefined)?.results;\n if (!prfResults?.first) throw new WebAuthnNotSupportedError();\n return new Uint8Array(prfResults.first);\n}\n","import type { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/browser';\nimport { registerPasskey } from './crypto/passkey';\nimport type { ApiClient } from './api';\n\nfunction bufFromBytes(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\n/**\n * Full registration orchestration: fetch a real, server-tracked challenge\n * from the backend, inject the PRF extension (a purely client-side concern\n * the generic /webauthn/register-options endpoint doesn't know about),\n * complete the ceremony, and report the result back for server-side\n * verification. One passkey prompt does double duty — see\n * crypto/passkey.ts's registerPasskey() doc comment for why.\n *\n * Best-effort on the server-verification half: if /webauthn/register fails\n * (network blip, etc.) this still returns the PRF output so the existing\n * device-share-wrapping flow proceeds normally — a user should never be\n * blocked from finishing signup because the *additional* assertion-gating\n * registration didn't complete. The gap self-heals next time rotateShares()\n * or exportPortableBackup() is attempted and finds no stored credential.\n */\nexport async function registerWebAuthnCredential(opts: {\n api: ApiClient;\n jwt: string;\n rpId: string;\n rpName: string;\n prfSalt: Uint8Array;\n}): Promise<{ credentialId: Uint8Array; prfOutput?: Uint8Array }> {\n const baseOptions = await opts.api.getWebAuthnRegisterOptions(opts.jwt, opts.rpId, opts.rpName);\n\n // IMPORTANT: @simplewebauthn/browser's startRegistration() spreads\n // `extensions` straight into navigator.credentials.create()'s options with\n // NO base64url->ArrayBuffer conversion (only challenge/user.id/\n // excludeCredentials get converted) — verified by reading its source.\n // prf.eval.first must therefore be a raw ArrayBuffer here, not a base64url\n // string, even though the JSON-typed interface below suggests otherwise.\n const optionsJSON: PublicKeyCredentialCreationOptionsJSON = {\n ...baseOptions,\n extensions: {\n ...baseOptions.extensions,\n prf: { eval: { first: bufFromBytes(opts.prfSalt) } },\n } as unknown as PublicKeyCredentialCreationOptionsJSON['extensions'],\n };\n\n const { credentialId, prfOutput, response } = await registerPasskey({ optionsJSON });\n\n try {\n await opts.api.postWebAuthnRegister(opts.jwt, response, window.location.origin);\n } catch (e) {\n console.warn('decane-connect-kit: WebAuthn server-side registration failed; PRF-based unlock still works, but rotateShares()/exportPortableBackup() will not until this is retried.', e);\n }\n\n return { credentialId, prfOutput };\n}\n","import type { ApiClient } from '../api';\nimport type { AuthResult } from '../types';\n\n/**\n * Sends a 6-digit magic-link code to the user's email.\n * Always returns void regardless of whether the email exists (prevents enumeration).\n */\nexport async function startEmailAuth(api: ApiClient, email: string): Promise<void> {\n await api.authEmailStart(email);\n}\n\n/**\n * Verifies the 6-digit code and exchanges it for a JWT.\n */\nexport async function verifyEmailCode(\n api: ApiClient,\n email: string,\n code: string,\n): Promise<AuthResult> {\n return api.authEmailVerify(email, code);\n}\n","// Sign in with KingsChat (browser).\n//\n// KingsChat's own web SDK opens accounts.kingsch.at in a popup and receives the\n// tokens back via postMessage. This reimplements that handshake rather than\n// depending on kingschat-web-sdk, for two reasons: that package bundles a\n// stylesheet and DOM helpers this SDK has no use for, and it offers no way to\n// hand the resulting token straight to a backend, which is the only thing we\n// actually need.\n//\n// The access token is NOT a session. It goes to /auth/kingschat, which spends it\n// against KingsChat's own API to establish who it belongs to and returns a\n// Decane JWT. Nothing here trusts the popup's payload on its own.\n\nimport { UserCancelledError, CallSequenceError } from '../errors';\n\n/** Where the consent screen lives, and therefore the only origin we accept a token from. */\nconst KINGSCHAT_AUTH_ORIGIN = 'https://accounts.kingsch.at';\n\nexport interface KingsChatTokens {\n accessToken: string;\n refreshToken?: string;\n expiresInMillis?: number;\n}\n\n/**\n * Read the token payload out of a postMessage, tolerating either casing.\n *\n * KingsChat's API replies in snake_case (`access_token`) while its web SDK's\n * public interface is camelCase (`accessToken`), and the popup payload is not\n * documented either way — so both are accepted rather than betting on one.\n */\nfunction readTokens(data: unknown): KingsChatTokens | null {\n if (!data || typeof data !== 'object') return null;\n const d = data as Record<string, unknown>;\n\n const accessToken = d.accessToken ?? d.access_token;\n if (typeof accessToken !== 'string' || !accessToken) return null;\n\n const refreshToken = d.refreshToken ?? d.refresh_token;\n const expires = d.expiresInMillis ?? d.expires_in_millis;\n\n return {\n accessToken,\n refreshToken: typeof refreshToken === 'string' ? refreshToken : undefined,\n expiresInMillis: typeof expires === 'number' ? expires : undefined,\n };\n}\n\nfunction buildAuthUrl(clientId: string, scopes: string[]): string {\n const url = new URL(KINGSCHAT_AUTH_ORIGIN);\n url.searchParams.set('client_id', clientId);\n // KingsChat expects a JSON array literal here, not repeated params.\n url.searchParams.set('scopes', JSON.stringify(scopes));\n url.searchParams.set('redirect_uri', window.location.origin);\n url.searchParams.set('post_message', '1');\n return url.toString();\n}\n\n/**\n * Open the KingsChat consent popup and resolve with the tokens it returns.\n *\n * Must be called synchronously from a user gesture (a click handler) — popup\n * blockers reject a window.open that happens after an await, which is why the\n * clientId is fetched by the caller *before* this runs.\n */\nexport function loginWithKingsChatPopup(opts: {\n clientId: string;\n scopes?: string[];\n timeoutMs?: number;\n}): Promise<KingsChatTokens> {\n const scopes = opts.scopes ?? ['profile'];\n const popup = window.open(\n buildAuthUrl(opts.clientId, scopes),\n 'decane-kingschat',\n 'width=480,height=720,menubar=no,toolbar=no',\n );\n\n if (!popup) {\n throw new CallSequenceError(\n 'The KingsChat sign-in popup was blocked. Call connectWithKingsChat() directly from a click handler.',\n );\n }\n\n return new Promise<KingsChatTokens>((resolve, reject) => {\n let settled = false;\n\n const finish = (fn: () => void) => {\n if (settled) return;\n settled = true;\n window.removeEventListener('message', onMessage);\n clearInterval(closedPoll);\n clearTimeout(timeout);\n try {\n popup.close();\n } catch {\n // Already gone, or cross-origin — nothing to do.\n }\n fn();\n };\n\n const onMessage = (event: MessageEvent) => {\n // The origin check is the whole security boundary of this handshake: any\n // page can postMessage to us, so a token from anywhere else is ignored\n // outright rather than forwarded to the backend.\n if (event.origin !== KINGSCHAT_AUTH_ORIGIN) return;\n\n const data = event.data as { error?: unknown } | null;\n if (data && typeof data === 'object' && data.error) {\n finish(() => reject(new CallSequenceError(`KingsChat sign-in failed: ${String(data.error)}`)));\n return;\n }\n\n const tokens = readTokens(event.data);\n if (tokens) finish(() => resolve(tokens));\n // A message from the right origin that carries no token is ignored — the\n // consent screen emits several during its lifecycle.\n };\n\n window.addEventListener('message', onMessage);\n\n // The popup being closed by hand produces no message at all, so it has to\n // be observed. `closed` stays readable cross-origin.\n const closedPoll = setInterval(() => {\n if (popup.closed) finish(() => reject(new UserCancelledError()));\n }, 400);\n\n const timeout = setTimeout(\n () =>\n finish(() =>\n reject(new CallSequenceError('KingsChat sign-in timed out before returning a token.')),\n ),\n opts.timeoutMs ?? 5 * 60_000,\n );\n });\n}\n","import { keccak256, Transaction, resolveProperties, type TransactionRequest } from 'ethers';\nimport type { TeeClient } from '../teeClient';\n\n// `jwt` is forwarded to TeeClient.sign so it can fetch a per-signature\n// assertion challenge when the session requires one. Ignored otherwise.\nexport async function signEvmTransaction(\n tee: TeeClient,\n chain: string,\n tx: TransactionRequest,\n jwt?: string\n): Promise<string> {\n const resolved = await resolveProperties(tx);\n const unsigned = Transaction.from(resolved as any).unsignedSerialized;\n const payload = unsigned.startsWith('0x') ? unsigned.slice(2) : unsigned;\n const txHash = keccak256('0x' + payload);\n return tee.sign({ chain, kind: 'transaction', payload, txHash }, jwt);\n}\n\nexport async function signEvmMessage(\n tee: TeeClient,\n chain: string,\n message: string,\n jwt?: string\n): Promise<string> {\n return tee.sign({ chain, kind: 'message', payload: message }, jwt);\n}\n\nexport interface Eip712TypedData {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n message: Record<string, unknown>;\n primaryType?: string;\n}\n\n// EIP-7702 authorization. The enclave computes the 0x05-prefixed auth hash from\n// (chainId, address, nonce) and signs it — a raw ECDSA over that digest, NOT a\n// personal_sign or typed-data signature. The 0x05 magic prefix domain-separates\n// it from transactions, so this path can't be coerced into signing one. Returns\n// the {yParity, r, s} an authorizationList entry needs.\nexport interface SignedAuthorization {\n chainId: number;\n address: string; // the delegate/implementation contract\n nonce: number;\n yParity: number;\n r: string;\n s: string;\n}\n\nexport async function signEvmAuthorization(\n tee: TeeClient,\n chainId: number,\n address: string,\n nonce: number,\n jwt?: string\n): Promise<SignedAuthorization> {\n const serialized = await tee.sign(\n { chain: `evm:${chainId}`, kind: 'authorization', payload: JSON.stringify({ chainId, address, nonce }) },\n jwt\n );\n const hex = serialized.startsWith('0x') ? serialized.slice(2) : serialized;\n const r = '0x' + hex.slice(0, 64);\n const s = '0x' + hex.slice(64, 128);\n const v = parseInt(hex.slice(128, 130), 16);\n // Full SignedAuthorization tuple, matching viem/permissionless so it drops\n // straight into a userOperation's `authorization` field and a type-4 tx's\n // authorizationList — no adapter needed at the call site.\n return { chainId, address, nonce, yParity: v >= 27 ? v - 27 : v, r, s };\n}\n\n// EIP-712. The structured data is sent whole — the enclave hashes it itself\n// (0x1901 || domainSeparator || hashStruct) and signs the result. It never\n// receives a raw digest, so this path cannot be abused to blind-sign a\n// transaction: the 0x1901 domain prefix separates typed data from tx encoding.\nexport async function signEvmTypedData(\n tee: TeeClient,\n chain: string,\n typedData: Eip712TypedData,\n jwt?: string\n): Promise<string> {\n // uint256 fields are commonly bigint; JSON.stringify throws on those. Serialize\n // bigints as decimal strings — ethers' signTypedData in the enclave accepts a\n // string for a numeric field and coerces it back to the same value.\n const payload = JSON.stringify(typedData, (_k, v) =>\n typeof v === 'bigint' ? v.toString() : v,\n );\n return tee.sign({ chain, kind: 'typedData', payload }, jwt);\n}\n","// Read-only native-balance fetching, shared by the client (getBalance), the\n// useSocialBalance hook, and the SocialWalletModal display so there is one\n// implementation instead of three drifting copies. No wallet interaction and\n// no TEE session needed — balances are public chain data. ethers /\n// @solana/web3.js are dynamically imported so consumers who never read a\n// balance don't pay for them in their initial bundle.\n\n// Browser-friendly (CORS-enabled) public RPCs. Devs override via config.rpcUrls.\nexport const DEFAULT_RPCS: Record<string, string> = {\n \"evm:1\": \"https://ethereum.publicnode.com\",\n \"evm:137\": \"https://polygon.publicnode.com\",\n \"evm:8453\": \"https://base.publicnode.com\",\n \"evm:10\": \"https://optimism.publicnode.com\",\n \"evm:42161\": \"https://arbitrum-one.publicnode.com\",\n \"evm:56\": \"https://bsc.publicnode.com\",\n \"evm:11155111\": \"https://ethereum-sepolia.publicnode.com\",\n \"evm:84532\": \"https://base-sepolia.publicnode.com\",\n \"evm:31337\": \"http://localhost:8545\",\n};\n\n// Native-currency symbol per EVM chain — defaults to ETH for the L2s/testnets.\nconst EVM_SYMBOLS: Record<string, string> = {\n \"evm:137\": \"MATIC\",\n \"evm:56\": \"BNB\",\n};\n\nexport type BalanceKind = \"evm\" | \"solana\";\n\nexport interface BalanceResult {\n /** Smallest unit — wei for EVM, lamports for Solana. */\n raw: bigint;\n /** Human-readable amount in whole native units, e.g. \"1.2345\". */\n formatted: string;\n /** Native currency symbol, e.g. \"ETH\", \"MATIC\", \"SOL\". */\n symbol: string;\n /** Decimals of the native currency (18 for EVM, 9 for Solana). */\n decimals: number;\n}\n\nfunction solanaEndpoint(chain: string, rpcUrls?: Record<string, string>): string {\n if (rpcUrls?.[chain]) return rpcUrls[chain];\n const cluster = chain.slice(\"solana:\".length);\n return cluster === \"devnet\"\n ? \"https://api.devnet.solana.com\"\n : \"https://api.mainnet-beta.solana.com\";\n}\n\n/** Fetch the native-token balance for one address on one chain. */\nexport async function fetchBalance(opts: {\n kind: BalanceKind;\n address: string;\n chain: string;\n rpcUrls?: Record<string, string>;\n}): Promise<BalanceResult> {\n const { kind, address, chain, rpcUrls } = opts;\n\n if (kind === \"evm\") {\n const rpcUrl = rpcUrls?.[chain] ?? DEFAULT_RPCS[chain];\n if (!rpcUrl) {\n throw new Error(\n `No RPC URL for ${chain}. Pass rpcUrls: { '${chain}': 'https://...' } in social config.`,\n );\n }\n const { JsonRpcProvider, formatEther } = await import(\"ethers\");\n const wei = await new JsonRpcProvider(rpcUrl).getBalance(address);\n return { raw: wei, formatted: formatEther(wei), symbol: EVM_SYMBOLS[chain] ?? \"ETH\", decimals: 18 };\n }\n\n const { Connection, PublicKey, LAMPORTS_PER_SOL } = await import(\"@solana/web3.js\");\n const lamports = await new Connection(solanaEndpoint(chain, rpcUrls)).getBalance(\n new PublicKey(address),\n );\n return {\n raw: BigInt(lamports),\n formatted: String(lamports / LAMPORTS_PER_SOL),\n symbol: \"SOL\",\n decimals: 9,\n };\n}\n\n/** Compact display form of a `formatted` amount (4 sig-figs, trims trailing zeros). */\nexport function formatBalanceDisplay(value: string | null): string {\n if (value == null) return \"—\";\n const n = Number(value);\n if (!Number.isFinite(n)) return value;\n return n === 0 ? \"0\" : n < 0.0001 ? \"<0.0001\" : n.toFixed(4).replace(/\\.?0+$/, \"\");\n}\n","// A standard EIP-1193 Ethereum provider backed by the Decane social wallet.\n// Signing methods (personal_sign, eth_signTypedData_v4, eth_sendTransaction,\n// eth_signAuthorization/EIP-7702) go through the TEE — the browser never holds\n// the key. Read methods (eth_call, eth_getBalance, eth_estimateGas, …) are\n// forwarded to the chain's RPC. This is what lets viem / wagmi / ethers drive a\n// Decane wallet exactly as they would MetaMask.\n\nimport type { DecaneConnect, Chain } from \"./types\";\nimport { DEFAULT_RPCS } from \"./balance\";\n\nexport interface Eip1193Provider {\n request(args: { method: string; params?: unknown[] | object }): Promise<unknown>;\n on(event: string, handler: (...args: unknown[]) => void): this;\n removeListener(event: string, handler: (...args: unknown[]) => void): this;\n /** Marks this as the Decane provider (parallel to wallets' isMetaMask etc.). */\n readonly isDecane: true;\n}\n\nexport interface EthereumProviderOptions {\n /** Initial chain id (numeric). Defaults to the first configured EVM chain, else 1. */\n chainId?: number;\n /** Per-chain RPC overrides ('evm:8453' -> url). Falls back to Decane's defaults. */\n rpcUrls?: Record<string, string>;\n}\n\nfunction toHex(n: number | bigint): string {\n return \"0x\" + n.toString(16);\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) bytes[i] = parseInt(clean.substr(i * 2, 2), 16);\n return bytes;\n}\n\nfunction asBigInt(v: unknown): bigint | undefined {\n if (v == null) return undefined;\n if (typeof v === \"bigint\") return v;\n if (typeof v === \"number\") return BigInt(v);\n if (typeof v === \"string\") return BigInt(v); // handles 0x… and decimal\n return undefined;\n}\n\ninterface EvmTxParam {\n to?: string;\n from?: string;\n value?: string | number | bigint;\n data?: string;\n input?: string;\n gas?: string | number | bigint;\n gasLimit?: string | number | bigint;\n}\n\n/**\n * Build an EIP-1193 provider over a connected Decane social client.\n *\n * `signAuthorization` (EIP-7702) is wired only when the client exposes it — that\n * requires the TEE signer to support the authorization signing path.\n */\nexport function createEthereumProvider(\n client: DecaneConnect,\n opts: EthereumProviderOptions = {},\n): Eip1193Provider {\n let chainId = opts.chainId ?? 1;\n const listeners = new Map<string, Set<(...a: unknown[]) => void>>();\n\n function emit(event: string, ...args: unknown[]): void {\n listeners.get(event)?.forEach((h) => {\n try { h(...args); } catch { /* a bad listener must not break the provider */ }\n });\n }\n\n // Bridge Decane session events onto the standard provider events dApps expect.\n client.on(\"connected\", () => {\n const evm = client.getAddresses()?.evm;\n emit(\"connect\", { chainId: toHex(chainId) });\n if (evm) emit(\"accountsChanged\", [evm]);\n });\n client.on(\"disconnected\", () => {\n emit(\"accountsChanged\", []);\n emit(\"disconnect\", { code: 4900, message: \"Wallet disconnected\" });\n });\n\n const chainStr = (): Chain => `evm:${chainId}` as Chain;\n\n async function rpc(method: string, params: unknown[]): Promise<unknown> {\n const url = opts.rpcUrls?.[`evm:${chainId}`] ?? DEFAULT_RPCS[`evm:${chainId}`];\n if (!url) {\n throw Object.assign(new Error(`No RPC for chain ${chainId}. Pass rpcUrls.`), { code: 4900 });\n }\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ jsonrpc: \"2.0\", id: Date.now(), method, params }),\n });\n } catch (e) {\n throw Object.assign(new Error(`RPC request failed: ${(e as Error).message}`), { code: 4900 });\n }\n const json = (await res.json()) as { result?: unknown; error?: { code: number; message: string } };\n if (json.error) throw Object.assign(new Error(json.error.message), { code: json.error.code });\n return json.result;\n }\n\n async function request(args: { method: string; params?: unknown[] | object }): Promise<unknown> {\n const params = (Array.isArray(args.params) ? args.params : args.params ? [args.params] : []) as unknown[];\n const addr = () => client.getAddresses()?.evm ?? null;\n\n switch (args.method) {\n case \"eth_requestAccounts\":\n case \"eth_accounts\": {\n const a = addr();\n return a ? [a] : [];\n }\n case \"eth_chainId\":\n return toHex(chainId);\n case \"net_version\":\n return String(chainId);\n\n case \"personal_sign\": {\n // params: [messageHex, address]\n const message = params[0] as string;\n // personal_sign signs the raw bytes the hex represents.\n const bytes = typeof message === \"string\" && message.startsWith(\"0x\") ? hexToBytes(message) : message;\n return client.signMessage({ chain: chainStr(), message: bytes as string | Uint8Array });\n }\n\n case \"eth_signTypedData_v4\":\n case \"eth_signTypedData\": {\n // params: [address, typedData (json string or object)]\n const raw = params[1];\n const td = (typeof raw === \"string\" ? JSON.parse(raw) : raw) as {\n domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string;\n };\n return client.signTypedData({\n chain: chainStr(),\n domain: td.domain, types: td.types, message: td.message, primaryType: td.primaryType,\n });\n }\n\n case \"eth_sendTransaction\": {\n const tx = params[0] as EvmTxParam;\n return client.sendTransaction({\n chain: chainStr(),\n to: tx.to as string,\n value: asBigInt(tx.value),\n data: (tx.data ?? tx.input) as string | undefined,\n gasLimit: asBigInt(tx.gas ?? tx.gasLimit),\n });\n }\n\n case \"eth_signAuthorization\":\n case \"wallet_sign7702Authorization\": {\n const p = params[0] as { chainId?: number | string; address?: string; contractAddress?: string; nonce?: number | string };\n const cid = p.chainId != null ? Number(asBigInt(p.chainId)) : chainId;\n const address = (p.address ?? p.contractAddress) as string;\n const nonce = p.nonce != null ? Number(asBigInt(p.nonce)) : 0;\n return client.signAuthorization({ chainId: cid, address, nonce });\n }\n\n case \"wallet_switchEthereumChain\": {\n const p = params[0] as { chainId: string };\n chainId = Number(asBigInt(p.chainId));\n emit(\"chainChanged\", toHex(chainId));\n return null;\n }\n case \"wallet_addEthereumChain\":\n // Nothing to persist client-side; accept so dApps proceed.\n return null;\n\n default:\n // Everything else (eth_call, eth_getBalance, eth_estimateGas,\n // eth_blockNumber, eth_getTransactionReceipt, …) is a read — forward it.\n return rpc(args.method, params);\n }\n }\n\n const provider: Eip1193Provider = {\n request,\n on(event, handler) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n return this;\n },\n removeListener(event, handler) {\n listeners.get(event)?.delete(handler);\n return this;\n },\n isDecane: true,\n };\n return provider;\n}\n","import type { Transaction, VersionedTransaction } from '@solana/web3.js';\nimport { VersionedTransaction as VTx } from '@solana/web3.js';\nimport type { TeeClient } from '../teeClient';\n\nfunction b64(bytes: Uint8Array): string {\n let s = '';\n for (const b of bytes) s += String.fromCharCode(b);\n return btoa(s);\n}\nfunction unb64(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\n\n// `jwt` is forwarded to TeeClient.sign so it can fetch a per-signature\n// assertion challenge when the session requires one. Ignored otherwise.\nexport async function signSolanaTransaction(\n tee: TeeClient,\n chain: string,\n tx: Transaction | VersionedTransaction,\n jwt?: string\n): Promise<Uint8Array> {\n const bytes =\n tx instanceof VTx ? tx.serialize() : (tx as Transaction).serialize({ requireAllSignatures: false });\n const signed = await tee.sign({ chain, kind: 'transaction', payload: b64(bytes) }, jwt);\n return unb64(signed);\n}\n\nexport async function signSolanaMessage(\n tee: TeeClient,\n chain: string,\n message: Uint8Array,\n jwt?: string\n): Promise<Uint8Array> {\n const sig = await tee.sign({ chain, kind: 'message', payload: b64(message) }, jwt);\n return unb64(sig);\n}\n","import type { ApiClient } from '../api';\n\nexport interface WrappedShareBackup {\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey';\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n formatVersion: number;\n}\n\nexport async function backupWrappedShare(\n api: ApiClient,\n jwt: string,\n backup: WrappedShareBackup\n): Promise<void> {\n await api.putRecoveryBackup(jwt, backup);\n}\n\nexport async function fetchWrappedShareBackup(\n api: ApiClient,\n jwt: string\n): Promise<WrappedShareBackup | null> {\n return api.getRecoveryBackup(jwt);\n}\n","import { InvalidRecoveryFileError, WrongPasswordError } from '../errors';\n\nconst PBKDF2_ITERATIONS = 600_000;\nconst FILE_VERSION = 2;\n\nexport interface RecoveryShareFile {\n version: number;\n type: 'decane-recovery-share';\n shareSetVersion: number;\n kdf: 'pbkdf2-sha256';\n kdfParams: { iterations: number; salt: string };\n cipher: 'aes-256-gcm';\n iv: string;\n ciphertext: string; // encrypted 33-byte share + 16-byte GCM tag\n addresses: { evm: string; solana: string };\n passwordHint: string | null;\n createdAt: string;\n}\n\nfunction b64(u: Uint8Array): string {\n let s = '';\n for (const b of u) s += String.fromCharCode(b);\n return btoa(s);\n}\nfunction unb64(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nasync function deriveFileKey(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey> {\n const base = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveKey']\n );\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: buf(salt), iterations, hash: 'SHA-256' },\n base,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * Build an encrypted recovery-share file from a single 33-byte Shamir share.\n * Does not mutate or retain `share`; the caller remains responsible for\n * zeroizing it. Unlike the v1 master-key-file format this replaces, there is\n * no local verification possible on decrypt — a lone share cannot derive an\n * address. Decrypting successfully proves the password was right; it does\n * not prove the share is the right one. That check can only happen where the\n * server share also is: /signer/recover.\n */\nexport async function buildRecoveryShareFile(\n share: Uint8Array,\n password: string,\n addresses: { evm: string; solana: string },\n shareSetVersion: number,\n passwordHint?: string\n): Promise<RecoveryShareFile> {\n if (share.length !== 33) throw new Error('share must be 33 bytes');\n if (password.length < 8) throw new Error('password must be at least 8 characters');\n if (passwordHint && passwordHint.trim() === password) {\n throw new Error('password hint must not be the password');\n }\n\n const salt = crypto.getRandomValues(new Uint8Array(16));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const key = await deriveFileKey(password, salt, PBKDF2_ITERATIONS);\n const ct = new Uint8Array(\n await crypto.subtle.encrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(share))\n );\n\n return {\n version: FILE_VERSION,\n type: 'decane-recovery-share',\n shareSetVersion,\n kdf: 'pbkdf2-sha256',\n kdfParams: { iterations: PBKDF2_ITERATIONS, salt: b64(salt) },\n cipher: 'aes-256-gcm',\n iv: b64(iv),\n ciphertext: b64(ct),\n addresses,\n passwordHint: passwordHint?.trim() || null,\n createdAt: new Date().toISOString(),\n };\n}\n\n/**\n * Validate the envelope without attempting decryption. Rejects v1 master-key\n * files (from the design this replaces) with a message explaining the\n * format changed, rather than a generic \"invalid file\" error.\n */\nexport function parseRecoveryShareFile(json: unknown): RecoveryShareFile {\n const raw = json as { type?: unknown } | null | undefined;\n if (raw?.type === 'decane-recovery') {\n throw new InvalidRecoveryFileError();\n }\n const f = json as Partial<RecoveryShareFile>;\n if (\n !f ||\n (f.type as unknown) !== 'decane-recovery-share' ||\n f.version !== FILE_VERSION ||\n f.kdf !== 'pbkdf2-sha256' ||\n f.cipher !== 'aes-256-gcm' ||\n typeof f.iv !== 'string' ||\n typeof f.ciphertext !== 'string' ||\n typeof f.kdfParams?.salt !== 'string' ||\n typeof f.kdfParams?.iterations !== 'number' ||\n typeof f.shareSetVersion !== 'number' ||\n typeof f.addresses?.evm !== 'string' ||\n typeof f.addresses?.solana !== 'string'\n ) {\n throw new InvalidRecoveryFileError();\n }\n if (f.kdfParams.iterations < 100_000 || f.kdfParams.iterations > 5_000_000) {\n throw new InvalidRecoveryFileError();\n }\n return f as RecoveryShareFile;\n}\n\n/**\n * Decrypt a recovery-share file. Returns the 33-byte share.\n * Caller MUST zeroize the result.\n */\nexport async function decryptRecoveryShareFile(\n file: RecoveryShareFile,\n password: string\n): Promise<Uint8Array> {\n const salt = unb64(file.kdfParams.salt);\n const iv = unb64(file.iv);\n const ct = unb64(file.ciphertext);\n const key = await deriveFileKey(password, salt, file.kdfParams.iterations);\n\n let share: Uint8Array;\n try {\n share = new Uint8Array(\n await crypto.subtle.decrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(ct))\n );\n } catch {\n throw new WrongPasswordError(); // GCM tag mismatch\n }\n if (share.length !== 33) {\n share.fill(0);\n throw new InvalidRecoveryFileError();\n }\n return share;\n}\n\n/** Suggested download filename. */\nexport function recoveryShareFileName(evmAddress: string): string {\n return `decane-recovery-${evmAddress.slice(0, 8)}.json`;\n}\n","import { fetchWrappedShareBackup } from './wrappedShareBackup';\nimport { parseRecoveryShareFile, decryptRecoveryShareFile } from './recoveryShareFile';\nimport { getPrfOutput } from '../crypto/passkey';\nimport { importAesKey, aesGcmDecrypt } from '../crypto/wrap';\nimport { zeroize } from '../crypto/shares';\nimport { NewDeviceError } from '../errors';\nimport { TeeClient } from '../teeClient';\nimport type { ApiClient } from '../api';\nimport type { Storage } from '../storage';\n\nexport type RecoveryProgress =\n | { type: 'passkey-attempt' }\n | { type: 'passkey-failed'; reason: string }\n | { type: 'recovery-file-prompt' }\n | { type: 'password-prompt'; passwordHint: string | null }\n | { type: 'recovery-verifying' }\n | { type: 'rotated'; shareSetVersion: number };\n\nexport interface RecoveryFlowInput {\n userId: string;\n jwt: string;\n rpId: string;\n teeUrl: string;\n api: ApiClient;\n storage: Storage;\n onProgress?: (event: RecoveryProgress) => void;\n /** Supplies the parsed JSON contents of a user-uploaded recovery-share file, plus a way to prompt for its password. */\n promptForRecoveryFile?: () => Promise<{ value: unknown; getPassword: () => Promise<string | null> } | null>;\n /**\n * Called after a successful Flow B recovery with the NEW recovery share —\n * the old file is dead the instant this flow completes (the set rotates on\n * every recovery), so the caller MUST get this saved. Not optional to\n * ignore in a real UI: MIGRATE_SSS_RECOVERY.md §10 requires this screen to\n * block progress until the user downloads the new file or explicitly\n * acknowledges the risk.\n */\n onNewRecoveryShare?: (recoveryShare: Uint8Array, shareSetVersion: number) => Promise<void>;\n}\n\nexport interface RecoveredDeviceShare {\n deviceShare: Uint8Array;\n /**\n * Which path produced it. 'passkey-sync' shares are a COPY of the backup\n * every other synced device also holds, so callers implementing per-device\n * shares rotate after this one; 'recovery-file' already rotated the set as\n * part of recovering.\n */\n flow: 'passkey-sync' | 'recovery-file';\n}\n\n/**\n * Attempt to recover the device share on a device that has none.\n * Flow A (passkey sync) first, Flow B (recovery-share file) as fallback.\n * Throws NewDeviceError if every path is exhausted.\n */\nexport async function recoverDeviceShare(input: RecoveryFlowInput): Promise<RecoveredDeviceShare> {\n // ── Flow A: passkey sync — unchanged ──────────────────────\n const backup = await fetchWrappedShareBackup(input.api, input.jwt);\n if (backup) {\n input.onProgress?.({ type: 'passkey-attempt' });\n try {\n const prfOutput = await getPrfOutput({\n rpId: input.rpId,\n credentialId: backup.credentialId,\n prfSalt: backup.prfSalt,\n });\n const wrappingKey = await importAesKey(prfOutput);\n const deviceShare = await aesGcmDecrypt(\n wrappingKey,\n backup.wrappedDeviceShare,\n backup.iv\n );\n // Cache locally so subsequent sessions on this device skip recovery.\n await input.storage.putShare({\n userId: input.userId,\n wrappedDeviceShare: backup.wrappedDeviceShare,\n iv: backup.iv,\n unlockMethod: 'passkey',\n credentialId: backup.credentialId,\n prfSalt: backup.prfSalt,\n version: 1,\n });\n return { deviceShare, flow: 'passkey-sync' };\n } catch (e) {\n input.onProgress?.({\n type: 'passkey-failed',\n reason: e instanceof Error ? e.message : 'unknown',\n });\n // fall through to Flow B\n }\n }\n\n // ── Flow B: recovery-share file ───────────────────────────\n if (!input.promptForRecoveryFile) throw new NewDeviceError();\n input.onProgress?.({ type: 'recovery-file-prompt' });\n\n const supplied = await input.promptForRecoveryFile();\n if (!supplied) throw new NewDeviceError();\n\n const file = parseRecoveryShareFile(supplied.value);\n input.onProgress?.({ type: 'password-prompt', passwordHint: file.passwordHint });\n const password = await supplied.getPassword();\n if (!password) throw new NewDeviceError();\n\n const recoveryShare = await decryptRecoveryShareFile(file, password); // throws WrongPasswordError\n\n input.onProgress?.({ type: 'recovery-verifying' });\n const tee = new TeeClient(input.teeUrl);\n let result: { deviceShare: Uint8Array; recoveryShare: Uint8Array; shareSetVersion: number };\n try {\n // Server-verifies the reconstructed master matches this account before\n // returning anything — throws RecoveryWalletMismatchError otherwise.\n // Rotates the whole share set: the presented recovery share is spent.\n result = await tee.recoverWithShare(input.jwt, recoveryShare);\n } finally {\n zeroize(recoveryShare);\n }\n\n // The old recovery file is dead now — the caller MUST get the new one saved.\n input.onProgress?.({ type: 'rotated', shareSetVersion: result.shareSetVersion });\n await input.onNewRecoveryShare?.(result.recoveryShare, result.shareSetVersion);\n zeroize(result.recoveryShare);\n\n // caller wraps under a new passkey and opens a session\n return { deviceShare: result.deviceShare, flow: 'recovery-file' };\n}\n","import { InvalidRecoveryFileError, WrongPasswordError } from '../errors';\n\nconst PBKDF2_ITERATIONS = 600_000;\nconst FILE_VERSION = 1;\n\nexport interface PortableBackup {\n version: number;\n type: 'decane-portable-backup';\n shareSetVersion: number;\n kdf: 'pbkdf2-sha256';\n kdfParams: { iterations: number; salt: string };\n cipher: 'aes-256-gcm';\n iv: string;\n ciphertext: string; // encrypted { deviceShare, recoveryShare } (base64 each) + GCM tag\n addresses: { evm: string; solana: string };\n passwordHint: string | null;\n createdAt: string;\n}\n\nfunction b64(u: Uint8Array): string {\n let s = '';\n for (const b of u) s += String.fromCharCode(b);\n return btoa(s);\n}\nfunction unb64(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nasync function deriveFileKey(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey> {\n const base = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveKey']\n );\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: buf(salt), iterations, hash: 'SHA-256' },\n base,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * Build the portable backup — a BEARER SECRET containing two shares (device +\n * recovery). File + password alone gives complete control of the wallet.\n * This must only ever be produced behind an explicit, warned, opt-in\n * settings action — never by default, never silently. See the export\n * warning copy requirements in MIGRATE_SSS_RECOVERY.md §10.\n */\nexport async function buildPortableBackup(\n deviceShare: Uint8Array,\n recoveryShare: Uint8Array,\n password: string,\n addresses: { evm: string; solana: string },\n shareSetVersion: number,\n passwordHint?: string\n): Promise<PortableBackup> {\n if (deviceShare.length !== 33 || recoveryShare.length !== 33) {\n throw new Error('shares must be 33 bytes');\n }\n if (password.length < 8) throw new Error('password must be at least 8 characters');\n if (passwordHint && passwordHint.trim() === password) {\n throw new Error('password hint must not be the password');\n }\n\n const plaintext = new TextEncoder().encode(\n JSON.stringify({ deviceShare: b64(deviceShare), recoveryShare: b64(recoveryShare) })\n );\n\n const salt = crypto.getRandomValues(new Uint8Array(16));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const key = await deriveFileKey(password, salt, PBKDF2_ITERATIONS);\n const ct = new Uint8Array(\n await crypto.subtle.encrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(plaintext))\n );\n\n return {\n version: FILE_VERSION,\n type: 'decane-portable-backup',\n shareSetVersion,\n kdf: 'pbkdf2-sha256',\n kdfParams: { iterations: PBKDF2_ITERATIONS, salt: b64(salt) },\n cipher: 'aes-256-gcm',\n iv: b64(iv),\n ciphertext: b64(ct),\n addresses,\n passwordHint: passwordHint?.trim() || null,\n createdAt: new Date().toISOString(),\n };\n}\n\nexport function parsePortableBackup(json: unknown): PortableBackup {\n const f = json as Partial<PortableBackup>;\n if (\n !f ||\n f.type !== 'decane-portable-backup' ||\n f.version !== FILE_VERSION ||\n f.kdf !== 'pbkdf2-sha256' ||\n f.cipher !== 'aes-256-gcm' ||\n typeof f.iv !== 'string' ||\n typeof f.ciphertext !== 'string' ||\n typeof f.kdfParams?.salt !== 'string' ||\n typeof f.kdfParams?.iterations !== 'number' ||\n typeof f.shareSetVersion !== 'number' ||\n typeof f.addresses?.evm !== 'string' ||\n typeof f.addresses?.solana !== 'string'\n ) {\n throw new InvalidRecoveryFileError();\n }\n return f as PortableBackup;\n}\n\n/** Decrypt a portable backup. Returns both shares. Caller MUST zeroize both. */\nexport async function decryptPortableBackup(\n file: PortableBackup,\n password: string\n): Promise<{ deviceShare: Uint8Array; recoveryShare: Uint8Array }> {\n const salt = unb64(file.kdfParams.salt);\n const iv = unb64(file.iv);\n const ct = unb64(file.ciphertext);\n const key = await deriveFileKey(password, salt, file.kdfParams.iterations);\n\n let plaintext: Uint8Array;\n try {\n plaintext = new Uint8Array(\n await crypto.subtle.decrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(ct))\n );\n } catch {\n throw new WrongPasswordError();\n }\n\n try {\n const parsed = JSON.parse(new TextDecoder().decode(plaintext)) as {\n deviceShare: string;\n recoveryShare: string;\n };\n const deviceShare = unb64(parsed.deviceShare);\n const recoveryShare = unb64(parsed.recoveryShare);\n if (deviceShare.length !== 33 || recoveryShare.length !== 33) throw new Error('bad share length');\n return { deviceShare, recoveryShare };\n } catch {\n throw new InvalidRecoveryFileError();\n } finally {\n plaintext.fill(0);\n }\n}\n\n/** Deliberately distinct from the ordinary recovery file's name — visually obvious in a downloads folder. */\nexport function portableBackupFileName(evmAddress: string): string {\n return `decane-PORTABLE-BACKUP-${evmAddress.slice(0, 8)}.json`;\n}\n","export { createDecaneConnect } from './client';\nexport { startEmailAuth, verifyEmailCode } from './auth/email';\n// Exposed so an app can run the KingsChat consent popup itself — e.g. to sign\n// the user into KingsChat before deciding whether to create a wallet — and hand\n// the token to connectWithKingsChatToken() later.\nexport { loginWithKingsChatPopup } from './auth/kingschat';\nexport type { KingsChatTokens } from './auth/kingschat';\nexport { createEthereumProvider } from './eip1193';\nexport type { Eip1193Provider, EthereumProviderOptions } from './eip1193';\n\nexport type {\n DecaneConnect,\n DecaneConnectConfig,\n ConnectResult,\n AuthProfile,\n SignMessageRequest,\n SendTransactionRequest,\n SignTypedDataRequest,\n WrappedShareMeta,\n AuthResult,\n SdkEvent,\n Chain,\n BalanceResult,\n SignedAuthorization,\n TransactionRecord,\n RecordTransactionInput,\n} from './types';\n\nexport type { RecoveryProgress } from './recovery/recoveryFlow';\nexport type { RecoveryShareFile } from './recovery/recoveryShareFile';\nexport type { PortableBackup } from './recovery/portableBackup';\n\nexport {\n DecaneConnectError,\n InvalidApiKeyError,\n OriginNotAllowedError,\n SessionExpiredError,\n UnlockRequiredError,\n UserCancelledError,\n WebAuthnNotSupportedError,\n InvalidPinError,\n CallSequenceError,\n NetworkError,\n ShareCorruptedError,\n NewDeviceError,\n ProvisioningTimeoutError,\n PromptPinNotConfiguredError,\n AttestationError,\n RecoveryFailedError,\n InvalidRecoveryFileError,\n WrongPasswordError,\n RecoveryWalletMismatchError,\n ExportNotAuthorizedError,\n ReconnectRequiredError,\n StaleDeviceShareError,\n} from './errors';\n","import React, { useEffect, useCallback, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { DecaneProvider, UnifiedWalletAccount, ChainType, ConnectMode } from \"../types\";\nimport { CSS_VARS } from \"./styles\";\nimport { WalletIcon, ChainIconStack } from \"./icons\";\n\ninterface WalletSelectorProps {\n provider: DecaneProvider;\n open: boolean;\n onClose: () => void;\n onConnect: (wallet: UnifiedWalletAccount, preference?: ChainType) => void;\n theme?: \"light\" | \"dark\" | \"auto\";\n networks?: \"evm\" | \"solana\" | \"tron\" | \"bitcoin\" | \"all\";\n mode?: ConnectMode;\n socialAuthMethods?: (\"google\" | \"email\" | \"kingschat\")[];\n onGoogleSignIn?: () => Promise<void>;\n onKingsChatSignIn?: () => Promise<void>;\n onEmailStart?: (email: string) => Promise<{ codeRequired: true }>;\n onEmailVerify?: (email: string, code: string) => Promise<void>;\n /** Button text for the developer's own auth system, e.g. \"Continue with Acme Inc\". Omitted entirely when not configured. */\n customAuthLabel?: string;\n onCustomAuthSignIn?: () => Promise<void>;\n /** Returning user on this device — offer the passkey instead of sign-in. */\n canUsePasskey?: boolean;\n /** Address shown alongside the passkey button, so they know who they're resuming as. */\n passkeyAddress?: string | null;\n onPasskeySignIn?: () => Promise<unknown>;\n}\n\ntype FilterType = \"all\" | \"evm\" | \"solana\" | \"tron\" | \"bitcoin\";\n\nconst FONT_URL =\n \"https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap\";\n\nfunction injectTokens(theme: \"light\" | \"dark\" | \"auto\"): void {\n let resolved: \"light\" | \"dark\";\n if (theme === \"auto\") {\n resolved = window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n } else {\n resolved = theme;\n }\n let styleEl = document.getElementById(\"decane-tokens\") as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = \"decane-tokens\";\n document.head.appendChild(styleEl);\n }\n styleEl.textContent = `:root { ${CSS_VARS[resolved]} }`;\n}\n\nfunction injectFont(): void {\n if (document.getElementById(\"decane-font\")) return;\n const link = document.createElement(\"link\");\n link.id = \"decane-font\";\n link.rel = \"stylesheet\";\n link.href = FONT_URL;\n document.head.appendChild(link);\n}\n\n\ninterface WalletRowProps {\n wallet: UnifiedWalletAccount;\n onClick: () => void;\n}\n\nfunction WalletRow({ wallet, onClick }: WalletRowProps) {\n const [hovered, setHovered] = useState(false);\n const [focused, setFocused] = useState(false);\n\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n padding: \"11px 14px\",\n background: hovered ? \"var(--dc-surface-hover)\" : \"transparent\",\n border: focused ? \"1px solid var(--dc-border-accent)\" : \"1px solid transparent\",\n borderRadius: 10,\n cursor: \"pointer\",\n textAlign: \"left\",\n transition: \"background 0.12s, border-color 0.12s\",\n outline: \"none\",\n fontFamily: \"inherit\",\n }}\n >\n <WalletIcon src={wallet.icon || undefined} name={wallet.name} size={38} />\n <span style={{ flex: 1, fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\", letterSpacing: \"-0.01em\" }}>\n {wallet.name}\n </span>\n <ChainIconStack support={wallet.chainSupport} size={16} />\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\"\n style={{ color: hovered ? \"var(--dc-text-secondary)\" : \"var(--dc-text-muted)\", flexShrink: 0, transition: \"color 0.12s\" }}>\n <path d=\"M5 2.5L9.5 7L5 11.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n );\n}\n\ninterface FilterTabProps {\n label: string;\n active: boolean;\n onClick: () => void;\n}\n\nfunction FilterTab({ label, active, onClick }: FilterTabProps) {\n const [hovered, setHovered] = useState(false);\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n flex: 1,\n padding: \"6px 8px\",\n borderRadius: 8,\n border: active ? \"1px solid var(--dc-border-accent)\" : \"1px solid transparent\",\n background: active ? \"rgba(245,200,0,0.1)\" : hovered ? \"var(--dc-surface-hover)\" : \"transparent\",\n color: active ? \"var(--dc-accent)\" : \"var(--dc-text-muted)\",\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n cursor: \"pointer\",\n transition: \"all 0.12s\",\n fontFamily: \"inherit\",\n outline: \"none\",\n }}\n >\n {label}\n </button>\n );\n}\n\ninterface ChainOptionProps {\n label: string;\n description: string;\n badges: React.ReactNode;\n onClick: () => void;\n}\n\nfunction ChainOption({ label, description, badges, onClick }: ChainOptionProps) {\n const [hovered, setHovered] = useState(false);\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n gap: 6,\n width: \"100%\",\n padding: \"14px 16px\",\n background: hovered ? \"var(--dc-surface-hover)\" : \"var(--dc-surface)\",\n border: hovered ? \"1px solid var(--dc-border-accent)\" : \"1px solid var(--dc-border)\",\n borderRadius: 12,\n cursor: \"pointer\",\n textAlign: \"left\",\n transition: \"all 0.12s\",\n fontFamily: \"inherit\",\n outline: \"none\",\n }}\n >\n {badges}\n <span style={{ fontSize: 13, fontWeight: 700, color: \"var(--dc-text)\" }}>{label}</span>\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", lineHeight: 1.4 }}>{description}</span>\n </button>\n );\n}\n\ntype MainView = \"wallets\" | \"social\";\ntype EmailStep = \"input\" | \"code\";\n\nfunction hasSocialMode(mode?: ConnectMode) {\n return (\n mode === \"all\" || mode === \"social\" ||\n mode === \"evm+social\" || mode === \"solana+social\" ||\n mode === \"tron+social\" || mode === \"evm+tron+social\"\n );\n}\n\nexport function WalletSelector({\n provider,\n open,\n onClose,\n onConnect,\n theme = \"auto\",\n networks = \"all\",\n mode = \"wallets\",\n socialAuthMethods = [\"google\", \"email\"],\n onGoogleSignIn,\n onKingsChatSignIn,\n onEmailStart,\n onEmailVerify,\n customAuthLabel,\n onCustomAuthSignIn,\n canUsePasskey = false,\n passkeyAddress = null,\n onPasskeySignIn,\n}: WalletSelectorProps) {\n const showSocial = hasSocialMode(mode);\n const showWallets = mode !== \"social\";\n\n // Social leads when it's available: it's the path for users who don't have a\n // wallet yet, and they're the ones who need the obvious default. Anyone with\n // a wallet installed already knows to go looking for it.\n const [view, setView] = useState<MainView>(showSocial ? \"social\" : \"wallets\");\n const [search, setSearch] = useState(\"\");\n const [filter, setFilter] = useState<FilterType>(\"all\");\n const [pendingWallet, setPendingWallet] = useState<UnifiedWalletAccount | null>(null);\n\n // Social form state\n const [emailStep, setEmailStep] = useState<EmailStep>(\"input\");\n const [emailVal, setEmailVal] = useState(\"\");\n const [codeVal, setCodeVal] = useState(\"\");\n const [socialLoad, setSocialLoad] = useState(false);\n const [socialErr, setSocialErr] = useState(\"\");\n // Returning users see the passkey alone; the sign-in methods stay one click\n // away for anyone who actually wants a different account.\n const [showOtherMethods, setShowOtherMethods] = useState(false);\n const passkeyFirst = canUsePasskey && !!onPasskeySignIn && !showOtherMethods;\n\n useEffect(() => {\n if (!open) return;\n injectFont();\n injectTokens(theme);\n if (theme !== \"auto\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const handler = () => injectTokens(\"auto\");\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [open, theme]);\n\n useEffect(() => {\n if (!open) {\n setSearch(\"\");\n setFilter(\"all\");\n setPendingWallet(null);\n setView(showSocial ? \"social\" : \"wallets\");\n setEmailStep(\"input\");\n setEmailVal(\"\");\n setCodeVal(\"\");\n setSocialErr(\"\");\n setShowOtherMethods(false);\n return;\n }\n return () => {\n document.getElementById(\"decane-tokens\")?.remove();\n };\n }, [open, showWallets]);\n\n async function handlePasskeySignIn() {\n if (!onPasskeySignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n try {\n await onPasskeySignIn();\n // The context closes the modal on success; nothing to do here.\n } catch (e: unknown) {\n // Cancelling the OS prompt is not a failure worth shouting about — but\n // a genuine failure needs to leave the standard methods reachable, or\n // the user is stuck staring at a passkey button that doesn't work.\n const err = e as Error;\n if (err?.name !== \"UserCancelledError\") {\n setSocialErr(err?.message ?? \"Passkey sign-in failed\");\n setShowOtherMethods(true);\n }\n setSocialLoad(false);\n }\n }\n\n async function handlePasskeyClick() {\n void handlePasskeySignIn();\n }\n\n async function handleGoogleClick() {\n if (!onGoogleSignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n try { await onGoogleSignIn(); }\n catch (e: unknown) { setSocialErr((e as Error).message); setSocialLoad(false); }\n }\n\n async function handleKingsChatClick() {\n if (!onKingsChatSignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n // Google navigates away and never returns, so it leaves the loading state\n // set. This one resolves in place when the popup closes, so it has to be\n // cleared on success too or the modal stays stuck mid-flight.\n try { await onKingsChatSignIn(); }\n catch (e: unknown) { setSocialErr((e as Error).message); }\n finally { setSocialLoad(false); }\n }\n\n async function handleCustomAuthClick() {\n if (!onCustomAuthSignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n try { await onCustomAuthSignIn(); }\n catch (e: unknown) { setSocialErr((e as Error).message); setSocialLoad(false); }\n }\n\n async function handleEmailStart(e: React.FormEvent) {\n e.preventDefault();\n if (!onEmailStart) return;\n setSocialLoad(true); setSocialErr(\"\");\n try {\n await onEmailStart(emailVal);\n setEmailStep(\"code\");\n } catch (e: unknown) {\n setSocialErr((e as Error).message);\n } finally {\n setSocialLoad(false);\n }\n }\n\n async function handleEmailVerify(e: React.FormEvent) {\n e.preventDefault();\n if (!onEmailVerify) return;\n setSocialLoad(true); setSocialErr(\"\");\n try {\n await onEmailVerify(emailVal, codeVal);\n // context closes the selector on success\n } catch (e: unknown) {\n setSocialErr((e as Error).message);\n } finally {\n setSocialLoad(false);\n }\n }\n\n const handleKey = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (pendingWallet) {\n setPendingWallet(null);\n } else {\n onClose();\n }\n }\n },\n [onClose, pendingWallet],\n );\n\n useEffect(() => {\n if (!open) return;\n document.addEventListener(\"keydown\", handleKey);\n return () => document.removeEventListener(\"keydown\", handleKey);\n }, [open, handleKey]);\n\n if (!open) return null;\n\n const q = search.toLowerCase();\n\n // Pre-filter by configured networks before anything else\n const networkWallets = provider.wallets.filter((w) => {\n const cs = w.chainSupport as string[];\n if (networks === \"evm\") return cs.includes(\"evm\");\n if (networks === \"solana\") return cs.includes(\"solana\");\n if (networks === \"tron\") return cs.includes(\"tron\");\n if (networks === \"bitcoin\") return cs.includes(\"bitcoin\");\n return true;\n });\n\n const baseWallets =\n filter === \"evm\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"evm\"))\n : filter === \"solana\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"solana\"))\n : filter === \"tron\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"tron\"))\n : filter === \"bitcoin\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"bitcoin\"))\n : networkWallets;\n const filtered = q\n ? baseWallets.filter((w) => w.name.toLowerCase().includes(q))\n : baseWallets;\n\n function handleWalletClick(wallet: UnifiedWalletAccount) {\n const cs = wallet.chainSupport as string[];\n const isMulti = cs.length >= 2;\n if (isMulti && networks === \"all\") {\n // Show chain picker only when the dApp supports all network types\n setPendingWallet(wallet);\n } else {\n const preference: ChainType | undefined =\n networks === \"evm\" ? \"evm\" :\n networks === \"solana\" ? \"solana\" :\n networks === \"tron\" ? \"tron\" :\n networks === \"bitcoin\" ? \"bitcoin\" :\n undefined;\n onConnect(wallet, preference);\n onClose();\n }\n }\n\n function handleChainChoice(preference?: ChainType) {\n if (!pendingWallet) return;\n onConnect(pendingWallet, preference);\n onClose();\n }\n\n const modal = (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Connect wallet\"\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 9999,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n // Same fallback chain as SocialWalletModal — without it, this modal\n // drops to the browser default serif whenever the token block hasn't\n // been injected, while the social modal still lands on system-ui.\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n }}\n >\n {/* Backdrop */}\n <div\n onClick={() => {\n if (pendingWallet) {\n setPendingWallet(null);\n } else {\n onClose();\n }\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n background: \"var(--dc-bg-overlay)\",\n backdropFilter: \"blur(8px)\",\n WebkitBackdropFilter: \"blur(8px)\",\n }}\n />\n\n {/* Modal card */}\n <div\n style={{\n position: \"relative\",\n background: \"var(--dc-bg)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 20,\n width: \"100%\",\n maxWidth: 400,\n maxHeight: \"85vh\",\n display: \"flex\",\n flexDirection: \"column\",\n boxShadow: \"0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n overflow: \"hidden\",\n }}\n >\n {/* Gold top accent */}\n <div\n style={{\n height: 2,\n background: \"linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)\",\n }}\n />\n\n {pendingWallet ? (\n /* ── Chain picker step ───────────────────────────────────────── */\n <>\n {/* Header */}\n <div style={{ padding: \"18px 20px 16px\", display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <button\n onClick={() => setPendingWallet(null)}\n aria-label=\"Back\"\n style={{\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 8,\n width: 28,\n height: 28,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: \"var(--dc-text-muted)\",\n flexShrink: 0,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M7.5 2L3 6l4.5 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n <h2 style={{ margin: 0, fontSize: 16, fontWeight: 800, color: \"var(--dc-text)\", letterSpacing: \"-0.02em\" }}>\n Choose networks\n </h2>\n <button\n onClick={onClose}\n aria-label=\"Close\"\n style={{\n marginLeft: \"auto\",\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 8,\n width: 28,\n height: 28,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: \"var(--dc-text-muted)\",\n flexShrink: 0,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n\n {/* Wallet preview */}\n <div\n style={{\n margin: \"0 20px 16px\",\n padding: \"12px 14px\",\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 12,\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n }}\n >\n <WalletIcon src={pendingWallet.icon || undefined} name={pendingWallet.name} size={36} />\n <div>\n <div style={{ fontSize: 14, fontWeight: 700, color: \"var(--dc-text)\" }}>{pendingWallet.name}</div>\n <div style={{ fontSize: 11, color: \"var(--dc-text-muted)\", marginTop: 2 }}>Multi-chain wallet detected</div>\n </div>\n </div>\n\n {/* Options — dynamic per wallet's chainSupport */}\n <div style={{ padding: \"0 12px 20px\", display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n {(pendingWallet.chainSupport as string[]).includes(\"evm\") && (\n <ChainOption\n label=\"EVM networks\"\n description=\"Connect your Ethereum-compatible address only\"\n badges={<ChainIconStack support={[\"evm\"]} size={18} />}\n onClick={() => handleChainChoice(\"evm\")}\n />\n )}\n {(pendingWallet.chainSupport as string[]).includes(\"solana\") && (\n <ChainOption\n label=\"Solana network\"\n description=\"Connect your Solana address only\"\n badges={<ChainIconStack support={[\"solana\"]} size={18} />}\n onClick={() => handleChainChoice(\"solana\")}\n />\n )}\n {(pendingWallet.chainSupport as string[]).includes(\"tron\") && (\n <ChainOption\n label=\"Tron network\"\n description=\"Connect your Tron address only\"\n badges={<ChainIconStack support={[\"tron\"]} size={18} />}\n onClick={() => handleChainChoice(\"tron\")}\n />\n )}\n {(pendingWallet.chainSupport as string[]).includes(\"bitcoin\") && (\n <ChainOption\n label=\"Bitcoin network\"\n description=\"Connect your Bitcoin address only\"\n badges={<ChainIconStack support={[\"bitcoin\"]} size={18} />}\n onClick={() => handleChainChoice(\"bitcoin\")}\n />\n )}\n <ChainOption\n label=\"All networks\"\n description=\"Connect all supported addresses together\"\n badges={<ChainIconStack support={pendingWallet.chainSupport} size={18} />}\n onClick={() => handleChainChoice(undefined)}\n />\n </div>\n </>\n ) : (\n /* ── Wallet list / Social sign-in ────────────────────────────── */\n <>\n {/* Header */}\n <div style={{ padding: \"18px 20px 0\" }}>\n <div style={{ display: \"flex\", alignItems: \"flex-start\", justifyContent: \"space-between\", marginBottom: 14 }}>\n <div>\n <h2 style={{ margin: 0, fontSize: 17, fontWeight: 800, color: \"var(--dc-text)\", letterSpacing: \"-0.02em\", lineHeight: 1.2 }}>\n {view === \"social\" ? \"Sign in\" : \"Connect wallet\"}\n </h2>\n {view === \"wallets\" && networkWallets.length > 0 && (\n <p style={{ margin: \"3px 0 0\", fontSize: 12, color: \"var(--dc-text-muted)\" }}>\n {networkWallets.length} wallet{networkWallets.length !== 1 ? \"s\" : \"\"} detected\n </p>\n )}\n </div>\n <button\n onClick={onClose}\n aria-label=\"Close\"\n style={{\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n cursor: \"pointer\",\n padding: 0,\n width: 28,\n height: 28,\n borderRadius: 8,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"var(--dc-text-muted)\",\n flexShrink: 0,\n transition: \"background 0.12s, color 0.12s\",\n fontFamily: \"inherit\",\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = \"var(--dc-surface-hover)\";\n (e.currentTarget as HTMLButtonElement).style.color = \"var(--dc-text)\";\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = \"var(--dc-surface)\";\n (e.currentTarget as HTMLButtonElement).style.color = \"var(--dc-text-muted)\";\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n\n {/* Tab bar — only when both wallets and social are available */}\n {showWallets && showSocial && (\n <div style={{ display: \"flex\", gap: 4, marginBottom: 14, background: \"var(--dc-surface)\", borderRadius: 10, padding: 3 }}>\n {([\"social\", \"wallets\"] as MainView[]).map((v) => (\n <button\n key={v}\n onClick={() => setView(v)}\n style={{\n flex: 1,\n padding: \"7px 0\",\n borderRadius: 8,\n border: \"none\",\n background: view === v ? \"var(--dc-bg)\" : \"transparent\",\n color: view === v ? \"var(--dc-text)\" : \"var(--dc-text-muted)\",\n fontSize: 13,\n fontWeight: view === v ? 700 : 500,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n boxShadow: view === v ? \"0 1px 4px rgba(0,0,0,0.2)\" : \"none\",\n transition: \"all 0.15s\",\n }}\n >\n {v === \"wallets\" ? \"Wallet\" : \"Sign in\"}\n </button>\n ))}\n </div>\n )}\n\n {/* Filter tabs — only on wallet view, only when multi-network */}\n {view === \"wallets\" && networks === \"all\" && (\n <div style={{ display: \"flex\", gap: 4, marginBottom: 10 }}>\n <FilterTab label=\"All\" active={filter === \"all\"} onClick={() => setFilter(\"all\")} />\n <FilterTab label=\"EVM\" active={filter === \"evm\"} onClick={() => setFilter(\"evm\")} />\n <FilterTab label=\"Solana\" active={filter === \"solana\"} onClick={() => setFilter(\"solana\")} />\n {provider.tronWallets && provider.tronWallets.length > 0 && (\n <FilterTab label=\"Tron\" active={filter === \"tron\"} onClick={() => setFilter(\"tron\")} />\n )}\n {provider.bitcoinWallets && provider.bitcoinWallets.length > 0 && (\n <FilterTab label=\"Bitcoin\" active={filter === \"bitcoin\"} onClick={() => setFilter(\"bitcoin\")} />\n )}\n </div>\n )}\n\n {/* Search — wallet view only */}\n {view === \"wallets\" && (\n <div style={{ position: \"relative\", marginBottom: 10 }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\"\n style={{ position: \"absolute\", left: 10, top: \"50%\", transform: \"translateY(-50%)\", color: \"var(--dc-text-muted)\", pointerEvents: \"none\" }}>\n <circle cx=\"6\" cy=\"6\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.4\" />\n <path d=\"M9.5 9.5L12 12\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" />\n </svg>\n <input\n type=\"text\"\n placeholder=\"Search wallets…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n style={{\n width: \"100%\",\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 10,\n color: \"var(--dc-text)\",\n fontSize: 13,\n padding: \"8px 12px 8px 32px\",\n outline: \"none\",\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n transition: \"border-color 0.15s\",\n boxSizing: \"border-box\",\n }}\n onFocus={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border-accent)\"; }}\n onBlur={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border)\"; }}\n />\n </div>\n )}\n </div>\n\n {/* ── Social sign-in panel ─────────────────────────────── */}\n {view === \"social\" && (\n <div style={{ padding: \"4px 20px 24px\", display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n {socialErr && (\n <div style={{ background: \"rgba(204,51,0,0.1)\", border: \"1px solid var(--dc-danger)\", borderRadius: 8, padding: \"9px 12px\", fontSize: 12, color: \"var(--dc-danger)\" }}>\n {socialErr}\n </div>\n )}\n\n {/* Returning user: their passkey is proof enough — no Google\n redirect, no email code, just the one prompt. */}\n {passkeyFirst && (\n <>\n <button\n onClick={handlePasskeyClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"13px 16px\",\n background: \"var(--dc-accent)\", border: \"none\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n color: \"var(--dc-accent-text)\", fontSize: 14, fontWeight: 700,\n fontFamily: \"inherit\", opacity: socialLoad ? 0.6 : 1,\n }}\n >\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M6 21v-1a4 4 0 0 1 4-4h1\" />\n <path d=\"M17 15v6M14.5 18h5\" />\n </svg>\n {socialLoad ? \"Verifying…\" : \"Continue with passkey\"}\n </button>\n\n {passkeyAddress && (\n <div style={{ textAlign: \"center\", fontSize: 12, color: \"var(--dc-text-muted)\" }}>\n Resuming {passkeyAddress.slice(0, 6)}…{passkeyAddress.slice(-4)}\n </div>\n )}\n\n <button\n onClick={() => { setShowOtherMethods(true); setSocialErr(\"\"); }}\n disabled={socialLoad}\n style={{\n background: \"none\", border: \"none\", padding: \"6px 0\",\n color: \"var(--dc-text-muted)\", fontSize: 12.5,\n cursor: socialLoad ? \"not-allowed\" : \"pointer\", fontFamily: \"inherit\",\n textDecoration: \"underline\", textUnderlineOffset: 3,\n }}\n >\n Use a different account\n </button>\n </>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"google\") && (\n <button\n onClick={handleGoogleClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"11px 16px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\",\n fontFamily: \"inherit\", transition: \"border-color 0.12s, background 0.12s\",\n opacity: socialLoad ? 0.6 : 1,\n }}\n onMouseEnter={(e) => { if (!socialLoad) (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border-accent)\"; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border)\"; }}\n >\n {/* Google G */}\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.875 2.684-6.615z\" fill=\"#4285F4\"/>\n <path d=\"M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z\" fill=\"#34A853\"/>\n <path d=\"M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z\" fill=\"#FBBC05\"/>\n <path d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z\" fill=\"#EA4335\"/>\n </svg>\n {socialLoad ? \"Redirecting…\" : \"Continue with Google\"}\n </button>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"kingschat\") && onKingsChatSignIn && (\n <button\n onClick={handleKingsChatClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"11px 16px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\",\n fontFamily: \"inherit\", transition: \"border-color 0.12s, background 0.12s\",\n opacity: socialLoad ? 0.6 : 1,\n }}\n onMouseEnter={(e) => { if (!socialLoad) (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border-accent)\"; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border)\"; }}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"9\" cy=\"9\" r=\"9\" fill=\"var(--dc-accent)\" />\n <path d=\"M5.5 4.5h1.9v3.6l3.1-3.6h2.3l-3.3 3.8 3.5 5.2h-2.3l-2.5-3.8-.8.9v2.9H5.5V4.5z\" fill=\"var(--dc-accent-text)\" />\n </svg>\n {socialLoad ? \"Waiting for KingsChat…\" : \"Continue with KingsChat\"}\n </button>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"google\") && socialAuthMethods.includes(\"email\") && (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", whiteSpace: \"nowrap\" }}>or continue with email</span>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n </div>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"email\") && (\n emailStep === \"input\" ? (\n <form onSubmit={handleEmailStart} style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <input\n type=\"email\"\n placeholder=\"your@email.com\"\n value={emailVal}\n onChange={(e) => setEmailVal(e.target.value)}\n required\n style={{\n width: \"100%\", padding: \"10px 12px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text)\", fontSize: 13,\n fontFamily: \"inherit\", outline: \"none\", boxSizing: \"border-box\",\n }}\n onFocus={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border-accent)\"; }}\n onBlur={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border)\"; }}\n />\n <button\n type=\"submit\"\n disabled={socialLoad || !emailVal}\n style={{\n width: \"100%\", padding: \"10px 16px\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10,\n fontSize: 14, fontWeight: 700, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\", opacity: socialLoad || !emailVal ? 0.6 : 1,\n }}\n >\n {socialLoad ? \"Sending…\" : \"Send code\"}\n </button>\n </form>\n ) : (\n <form onSubmit={handleEmailVerify} style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <p style={{ margin: 0, fontSize: 12, color: \"var(--dc-text-muted)\", textAlign: \"center\" }}>\n Code sent to <strong style={{ color: \"var(--dc-text)\" }}>{emailVal}</strong>\n </p>\n <input\n type=\"text\"\n placeholder=\"6-digit code\"\n value={codeVal}\n onChange={(e) => setCodeVal(e.target.value.replace(/\\D/g, \"\").slice(0, 6))}\n autoFocus\n required\n style={{\n width: \"100%\", padding: \"10px 12px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text)\", fontSize: 20,\n fontFamily: \"monospace\", letterSpacing: 8, textAlign: \"center\",\n outline: \"none\", boxSizing: \"border-box\",\n }}\n onFocus={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border-accent)\"; }}\n onBlur={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border)\"; }}\n />\n <div style={{ display: \"flex\", gap: 8 }}>\n <button\n type=\"button\"\n onClick={() => { setEmailStep(\"input\"); setCodeVal(\"\"); setSocialErr(\"\"); }}\n style={{\n flex: 1, padding: \"9px 0\",\n background: \"transparent\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text-muted)\",\n fontSize: 13, cursor: \"pointer\", fontFamily: \"inherit\",\n }}\n >\n Back\n </button>\n <button\n type=\"submit\"\n disabled={socialLoad || codeVal.length < 6}\n style={{\n flex: 2, padding: \"9px 0\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10,\n fontSize: 13, fontWeight: 700,\n cursor: socialLoad || codeVal.length < 6 ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n opacity: socialLoad || codeVal.length < 6 ? 0.6 : 1,\n }}\n >\n {socialLoad ? \"Verifying…\" : \"Verify\"}\n </button>\n </div>\n </form>\n )\n )}\n\n {!passkeyFirst && customAuthLabel && onCustomAuthSignIn && (\n <>\n {(socialAuthMethods.includes(\"google\") || socialAuthMethods.includes(\"email\")) && (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", whiteSpace: \"nowrap\" }}>or</span>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n </div>\n )}\n <button\n onClick={handleCustomAuthClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"11px 16px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\",\n fontFamily: \"inherit\", transition: \"border-color 0.12s, background 0.12s\",\n opacity: socialLoad ? 0.6 : 1,\n }}\n onMouseEnter={(e) => { if (!socialLoad) (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border-accent)\"; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border)\"; }}\n >\n {socialLoad ? \"Connecting…\" : customAuthLabel}\n </button>\n </>\n )}\n </div>\n )}\n\n {/* ── Wallet list ──────────────────────────────────────── */}\n {view === \"wallets\" && (\n <div style={{ overflowY: \"auto\", flex: 1, padding: \"0 12px 20px\" }}>\n {filtered.length > 0 ? (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n {filtered.map((w) => (\n <WalletRow key={w.id} wallet={w} onClick={() => handleWalletClick(w)} />\n ))}\n </div>\n ) : (\n <div style={{ textAlign: \"center\", padding: \"32px 16px\", color: \"var(--dc-text-muted)\", fontSize: 13 }}>\n {q ? `No wallets matching \"${q}\"` : \"No wallets detected\"}\n </div>\n )}\n </div>\n )}\n\n {/* Footer */}\n {view === \"wallets\" && (\n <div style={{ padding: \"10px 20px 14px\", borderTop: \"1px solid var(--dc-border)\", textAlign: \"center\", fontSize: 11, color: \"var(--dc-text-muted)\" }}>\n Don't see your wallet? Make sure it's installed and unlocked\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n\n return createPortal(modal, document.body);\n}\n","export const tokens = {\n // ── Gold palette ──────────────────────────────────────────────────────────\n gold: {\n 50: \"#FFFDF0\",\n 100: \"#FFF8D6\",\n 200: \"#FFEF99\",\n 300: \"#FFE04D\",\n 400: \"#F5C800\", // primary gold — buttons, accents\n 500: \"#D4A800\", // darker gold — hover states\n 600: \"#A37F00\", // deep gold — borders, active\n 700: \"#7A5E00\",\n 800: \"#4D3B00\",\n 900: \"#261D00\",\n },\n\n // ── Black / dark palette ──────────────────────────────────────────────────\n black: {\n 0: \"#FFFFFF\",\n 50: \"#F9F9F7\",\n 100: \"#F0EFEB\",\n 200: \"#DDDCDA\",\n 300: \"#BDBBB8\",\n 400: \"#8A8884\",\n 500: \"#5C5A57\",\n 600: \"#3D3C39\",\n 700: \"#2A2927\",\n 800: \"#1A1917\",\n 900: \"#0D0D0B\",\n 950: \"#070706\",\n },\n\n // ── Semantic tokens — light mode ──────────────────────────────────────────\n light: {\n bg: \"#FFFFFF\",\n bgOverlay: \"rgba(0, 0, 0, 0.55)\",\n surface: \"#F9F9F7\",\n surfaceHover: \"#F0EFEB\",\n border: \"#DDDCDA\",\n borderAccent: \"#F5C800\",\n text: \"#0D0D0B\",\n textSecondary: \"#5C5A57\",\n textMuted: \"#8A8884\",\n accent: \"#F5C800\",\n accentHover: \"#D4A800\",\n accentText: \"#0D0D0B\",\n badgeEvm: \"#1A1917\",\n badgeEvmText: \"#F5C800\",\n badgeSolana: \"#F5C800\",\n badgeSolanaText: \"#0D0D0B\",\n danger: \"#CC3300\",\n },\n\n // ── Semantic tokens — dark mode ───────────────────────────────────────────\n dark: {\n bg: \"#0D0D0B\",\n bgOverlay: \"rgba(0, 0, 0, 0.75)\",\n surface: \"#1A1917\",\n surfaceHover: \"#2A2927\",\n border: \"#3D3C39\",\n borderAccent: \"#F5C800\",\n text: \"#F9F9F7\",\n textSecondary: \"#BDBBB8\",\n textMuted: \"#8A8884\",\n accent: \"#F5C800\",\n accentHover: \"#FFE04D\",\n accentText: \"#0D0D0B\",\n badgeEvm: \"#F5C800\",\n badgeEvmText: \"#0D0D0B\",\n badgeSolana: \"#1A1917\",\n badgeSolanaText: \"#F5C800\",\n danger: \"#FF5533\",\n },\n} as const;\n\n// Font stacks — used by the modal container and all child elements via var()\nexport const FONT_SANS = \"'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\";\nexport const FONT_MONO = \"'JetBrains Mono', 'Fira Code', ui-monospace, monospace\";\n\nexport const CSS_VARS = {\n light: `\n --dc-font-sans: ${FONT_SANS};\n --dc-font-mono: ${FONT_MONO};\n --dc-bg: ${tokens.light.bg};\n --dc-bg-overlay: ${tokens.light.bgOverlay};\n --dc-surface: ${tokens.light.surface};\n --dc-surface-hover: ${tokens.light.surfaceHover};\n --dc-border: ${tokens.light.border};\n --dc-border-accent: ${tokens.light.borderAccent};\n --dc-text: ${tokens.light.text};\n --dc-text-secondary: ${tokens.light.textSecondary};\n --dc-text-muted: ${tokens.light.textMuted};\n --dc-accent: ${tokens.light.accent};\n --dc-accent-hover: ${tokens.light.accentHover};\n --dc-accent-text: ${tokens.light.accentText};\n --dc-badge-evm: ${tokens.light.badgeEvm};\n --dc-badge-evm-text: ${tokens.light.badgeEvmText};\n --dc-badge-sol: ${tokens.light.badgeSolana};\n --dc-badge-sol-text: ${tokens.light.badgeSolanaText};\n --dc-danger: ${tokens.light.danger};\n `,\n dark: `\n --dc-font-sans: ${FONT_SANS};\n --dc-font-mono: ${FONT_MONO};\n --dc-bg: ${tokens.dark.bg};\n --dc-bg-overlay: ${tokens.dark.bgOverlay};\n --dc-surface: ${tokens.dark.surface};\n --dc-surface-hover: ${tokens.dark.surfaceHover};\n --dc-border: ${tokens.dark.border};\n --dc-border-accent: ${tokens.dark.borderAccent};\n --dc-text: ${tokens.dark.text};\n --dc-text-secondary: ${tokens.dark.textSecondary};\n --dc-text-muted: ${tokens.dark.textMuted};\n --dc-accent: ${tokens.dark.accent};\n --dc-accent-hover: ${tokens.dark.accentHover};\n --dc-accent-text: ${tokens.dark.accentText};\n --dc-badge-evm: ${tokens.dark.badgeEvm};\n --dc-badge-evm-text: ${tokens.dark.badgeEvmText};\n --dc-badge-sol: ${tokens.dark.badgeSolana};\n --dc-badge-sol-text: ${tokens.dark.badgeSolanaText};\n --dc-danger: ${tokens.dark.danger};\n `,\n} as const;\n","import React from \"react\";\nimport type { ChainType } from \"../types\";\n\n// ── Decane brand ──────────────────────────────────────────────────────────────\n// Official Decane mark — a gold mascot glyph. The drop-shadow filter id is made\n// unique per instance (React.useId) so rendering the logo more than once on a\n// page — e.g. the modal header and footer — doesn't collide on a shared id.\n\nexport function DecaneMark({ size = 28, muted = false }: { size?: number; muted?: boolean }) {\n const uid = React.useId().replace(/:/g, \"\");\n const fid = `dl_logo_f_${uid}`;\n const w = size;\n const h = Math.round((size * 64) / 68);\n return (\n <svg\n width={w}\n height={h}\n viewBox=\"0 0 68 64\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden\n style={{ display: \"block\", flexShrink: 0, opacity: muted ? 0.55 : 1 }}\n >\n <g filter={`url(#${fid})`}>\n <path d=\"M32.8031 10.2986C33.1971 9.68929 34.0886 9.68929 34.4826 10.2986L35.7297 12.2273C36.1599 12.8926 35.6823 13.7703 34.89 13.7703H32.3957C31.6034 13.7703 31.1257 12.8926 31.556 12.2273L32.8031 10.2986Z\" fill=\"#FFD700\"/>\n <path d=\"M16.6095 20.8798C25.5139 8.28662 47.0755 12.2298 51.4641 20.5617C54.9502 24.0479 55.2167 30.8018 55.2167 30.8018C55.2167 30.8018 58.8421 37.862 57.4428 41.3601C55.7891 56.7522 13.9381 57.0066 11.3304 41.3601C9.93111 37.0351 13.4293 31.3744 13.4293 31.3744C13.4293 31.3744 12.9841 27.2404 16.6095 20.8798Z\" fill=\"#FFD700\"/>\n <ellipse cx=\"48.9999\" cy=\"39.2669\" rx=\"2.38155\" ry=\"1.89957\" transform=\"rotate(-22.395 48.9999 39.2669)\" fill=\"#FFE55F\" fillOpacity=\"0.45\"/>\n <ellipse cx=\"18.9785\" cy=\"39.2671\" rx=\"2.38155\" ry=\"1.89958\" transform=\"rotate(15.8893 18.9785 39.2671)\" fill=\"#FFE55F\" fillOpacity=\"0.26\"/>\n <path d=\"M43.5977 30.7344C43.1619 30.7344 42.6943 30.9653 42.3027 31.4824C41.9107 32.0001 41.6388 32.7597 41.6387 33.6406C41.6387 34.5217 41.9107 35.2821 42.3027 35.7998C42.6943 36.3168 43.1619 36.5479 43.5977 36.5479C44.0332 36.5477 44.5002 36.3166 44.8916 35.7998C45.2837 35.2821 45.5557 34.5217 45.5557 33.6406C45.5556 32.7597 45.2836 32.0001 44.8916 31.4824C44.5002 30.9656 44.0333 30.7345 43.5977 30.7344Z\" fill=\"#1A1A1A\" stroke=\"#F4EBBC\" strokeWidth=\"2\"/>\n <path d=\"M25.1514 30.7344C25.5871 30.7344 26.0547 30.9653 26.4463 31.4824C26.8383 32.0001 27.1103 32.7597 27.1104 33.6406C27.1104 34.5217 26.8384 35.2821 26.4463 35.7998C26.0547 36.3168 25.5871 36.5479 25.1514 36.5479C24.7158 36.5477 24.2489 36.3166 23.8574 35.7998C23.4654 35.2821 23.1934 34.5217 23.1934 33.6406C23.1934 32.7597 23.4654 32.0001 23.8574 31.4824C24.2489 30.9656 24.7157 30.7345 25.1514 30.7344Z\" fill=\"#1A1A1A\" stroke=\"#F4EBBC\" strokeWidth=\"2\"/>\n <path d=\"M26.0107 41.6924C26.0107 41.6924 28.0937 46.399 34.759 46.399C41.008 46.399 43.3109 41.6924 43.3109 41.6924\" stroke=\"#1A1A1A\" strokeLinecap=\"round\"/>\n </g>\n <defs>\n <filter id={fid} x=\"0.589964\" y=\"0.334365\" width=\"66.5809\" height=\"62.9754\" filterUnits=\"userSpaceOnUse\" colorInterpolationFilters=\"sRGB\">\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\"/>\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/>\n <feOffset dx=\"-0.501447\" dy=\"0.401157\"/>\n <feGaussianBlur stdDeviation=\"4.95429\"/>\n <feComposite in2=\"hardAlpha\" operator=\"out\"/>\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 0.996078 0 0 0 0 0.996078 0 0 0 0 0.996078 0 0 0 0.12 0\"/>\n <feBlend mode=\"normal\" in2=\"BackgroundImageFix\" result=\"effect1_dropShadow\"/>\n <feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"effect1_dropShadow\" result=\"shape\"/>\n </filter>\n </defs>\n </svg>\n );\n}\n\nexport function DecaneWordmark({ size = 15, muted = false }: { size?: number; muted?: boolean }) {\n return (\n <span\n style={{\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n fontWeight: 800,\n fontSize: size,\n letterSpacing: \"-0.03em\",\n color: muted ? \"var(--dc-text-muted)\" : \"var(--dc-text)\",\n lineHeight: 1,\n }}\n >\n decane\n </span>\n );\n}\n\nexport function DecaneLogo({ size = 20, muted = false }: { size?: number; muted?: boolean }) {\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: size * 0.34 }}>\n <DecaneMark size={size} muted={muted} />\n <DecaneWordmark size={size * 0.78} muted={muted} />\n </span>\n );\n}\n\ninterface WalletIconProps {\n src?: string;\n name: string;\n size?: number;\n}\n\nexport function WalletIcon({ src, name, size = 36 }: WalletIconProps) {\n if (src) {\n return (\n <img\n src={src}\n alt={name}\n width={size}\n height={size}\n style={{ borderRadius: size * 0.25, objectFit: \"cover\", flexShrink: 0 }}\n />\n );\n }\n\n const initial = name.charAt(0).toUpperCase();\n return (\n <div\n style={{\n width: size,\n height: size,\n borderRadius: size * 0.25,\n background: \"linear-gradient(135deg, var(--dc-surface-hover), var(--dc-surface-active, var(--dc-surface-hover)))\",\n border: \"1px solid var(--dc-border)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size * 0.38,\n fontWeight: 800,\n color: \"var(--dc-accent)\",\n flexShrink: 0,\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n letterSpacing: \"-0.02em\",\n }}\n >\n {initial}\n </div>\n );\n}\n\nfunction EthCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#627EEA\" />\n {/* Ethereum diamond */}\n <polygon points=\"8,2.5 11.5,8 8,9.8 4.5,8\" fill=\"white\" fillOpacity=\"0.9\" />\n <polygon points=\"8,9.8 11.5,8 8,13.5\" fill=\"white\" fillOpacity=\"0.6\" />\n <polygon points=\"8,9.8 4.5,8 8,13.5\" fill=\"white\" fillOpacity=\"0.8\" />\n <polygon points=\"8,2.5 8,9.8 4.5,8\" fill=\"white\" fillOpacity=\"0.6\" />\n </svg>\n );\n}\n\nfunction SolCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#9945FF\" />\n {/* Solana 3 bars */}\n <rect x=\"4\" y=\"4.5\" width=\"7\" height=\"1.5\" rx=\"0.75\" fill=\"white\" fillOpacity=\"0.95\" />\n <rect x=\"4\" y=\"7.25\" width=\"7\" height=\"1.5\" rx=\"0.75\" fill=\"white\" fillOpacity=\"0.95\" />\n <rect x=\"4\" y=\"10\" width=\"5.5\" height=\"1.5\" rx=\"0.75\" fill=\"white\" fillOpacity=\"0.95\" />\n </svg>\n );\n}\n\nfunction TronCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#FF0013\" />\n {/* Play triangle */}\n <polygon points=\"6,4.5 12,8 6,11.5\" fill=\"white\" fillOpacity=\"0.95\" />\n </svg>\n );\n}\n\nfunction BitcoinCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#F7931A\" />\n {/* ₿ symbol */}\n <text\n x=\"8.3\"\n y=\"11.5\"\n textAnchor=\"middle\"\n fontSize=\"8\"\n fontWeight=\"700\"\n fill=\"white\"\n fontFamily=\"Arial, system-ui\"\n >\n ₿\n </text>\n </svg>\n );\n}\n\nfunction ChainCircleIcon({ chain, size }: { chain: ChainType; size: number }) {\n switch (chain) {\n case \"evm\": return <EthCircle size={size} />;\n case \"solana\": return <SolCircle size={size} />;\n case \"tron\": return <TronCircle size={size} />;\n case \"bitcoin\": return <BitcoinCircle size={size} />;\n }\n}\n\nconst CHAIN_ORDER: ChainType[] = [\"evm\", \"solana\", \"tron\", \"bitcoin\"];\n\ninterface ChainIconStackProps {\n support: readonly string[];\n size?: number;\n}\n\nexport function ChainIconStack({ support, size = 16 }: ChainIconStackProps) {\n const ordered = CHAIN_ORDER.filter((c) => support.includes(c));\n if (ordered.length === 0) return null;\n const overlap = Math.round(size * 0.35);\n\n return (\n <div style={{ display: \"flex\", alignItems: \"center\", flexShrink: 0 }}>\n {ordered.map((chain, i) => (\n <div\n key={chain}\n style={{\n marginLeft: i === 0 ? 0 : `-${overlap}px`,\n zIndex: ordered.length - i,\n position: \"relative\",\n borderRadius: \"50%\",\n lineHeight: 0,\n boxShadow: i > 0 ? `0 0 0 1.5px var(--dc-bg, #fff)` : undefined,\n }}\n >\n <ChainCircleIcon chain={chain} size={size} />\n </div>\n ))}\n </div>\n );\n}\n","import React, { useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { CSS_VARS } from \"./styles\";\nimport { DecaneMark, DecaneWordmark } from \"./icons\";\nimport type { SocialAuthState } from \"./context\";\nimport { fetchBalance, formatBalanceDisplay } from \"../social/balance\";\nimport type { RecoveryShareFile } from \"../social/recovery/recoveryShareFile\";\nimport type { PortableBackup } from \"../social/recovery/portableBackup\";\n\ninterface SocialWalletModalProps {\n open: boolean;\n onClose: () => void;\n theme?: \"light\" | \"dark\" | \"auto\";\n socialAuth: SocialAuthState;\n onUnlock: () => Promise<void>;\n onDisconnect: () => Promise<void>;\n onGoogleSignIn: () => Promise<void>;\n onKingsChatSignIn?: () => Promise<void>;\n onEmailStart: (email: string) => Promise<{ codeRequired: true }>;\n onEmailVerify: (email: string, code: string) => Promise<void>;\n authMethods?: Array<\"google\" | \"email\" | \"kingschat\">;\n customAuthLabel?: string;\n onCustomAuthSignIn?: () => Promise<void>;\n // Returning user on this device: offer a one-tap passkey reconnect instead of\n // forcing a full Google/email sign-in after a reload.\n canUsePasskey?: boolean;\n passkeyAddress?: string | null;\n onPasskeySignIn?: () => Promise<unknown>;\n onRotateShares: (opts: { password: string; passwordHint?: string }) => Promise<RecoveryShareFile>;\n onExportPortableBackup: (opts: { password: string; passwordHint?: string }) => Promise<PortableBackup>;\n rpcUrls?: Record<string, string>;\n chains?: string[];\n}\n\nfunction injectTokens(theme: \"light\" | \"dark\" | \"auto\"): void {\n const resolved: \"light\" | \"dark\" =\n theme === \"auto\"\n ? window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\"\n : theme;\n let el = document.getElementById(\"decane-tokens\") as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = \"decane-tokens\";\n document.head.appendChild(el);\n }\n el.textContent = `:root { ${CSS_VARS[resolved]} }`;\n}\n\nfunction countdown(expiresAt: number): string {\n const secs = Math.max(0, Math.round((expiresAt - Date.now()) / 1000));\n return `${Math.floor(secs / 60)}m ${String(secs % 60).padStart(2, \"0\")}s`;\n}\n\nfunction downloadJson(data: unknown, filename: string) {\n const blob = new Blob([JSON.stringify(data, null, 2)], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n}\n\nfunction CopyButton({ value }: { value: string }) {\n const [copied, setCopied] = useState(false);\n async function copy() {\n await navigator.clipboard.writeText(value).catch(() => {});\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }\n return (\n <button\n onClick={copy}\n style={{\n background: \"none\", border: \"none\", cursor: \"pointer\",\n color: copied ? \"var(--dc-accent)\" : \"var(--dc-text-muted)\",\n fontSize: 11, fontFamily: \"inherit\", padding: \"2px 6px\",\n borderRadius: 5, transition: \"color 0.15s\",\n }}\n >\n {copied ? \"✓\" : \"copy\"}\n </button>\n );\n}\n\n// ── Balances ─────────────────────────────────────────────────────────────────\n// Fetched client-side, read-only, no wallet interaction needed. Dynamic\n// imports keep ethers/@solana-web3 out of the initial bundle for consumers\n// who never open this modal.\n\ntype BalanceState = { loading: boolean; value: string | null; symbol: string };\n\n// Thin wrapper over the shared fetchBalance() so the modal display and the\n// public getBalance()/useSocialBalance() can never drift apart.\nfunction useBalance(\n kind: \"evm\" | \"solana\",\n address: string | undefined,\n chain: string | undefined,\n rpcUrls: Record<string, string> | undefined,\n): BalanceState {\n const [state, setState] = useState<BalanceState>({ loading: false, value: null, symbol: kind === \"evm\" ? \"ETH\" : \"SOL\" });\n\n useEffect(() => {\n if (!address || !chain) return;\n let cancelled = false;\n setState((s) => ({ ...s, loading: true }));\n\n fetchBalance({ kind, address, chain, rpcUrls })\n .then((b) => { if (!cancelled) setState({ loading: false, value: b.formatted, symbol: b.symbol }); })\n .catch(() => { if (!cancelled) setState({ loading: false, value: null, symbol: kind === \"evm\" ? \"ETH\" : \"SOL\" }); });\n\n return () => { cancelled = true; };\n }, [kind, address, chain, rpcUrls]);\n\n return state;\n}\n\nfunction AddressRow({\n label, address, kind, chain, rpcUrls,\n}: {\n label: string; address: string; kind: \"evm\" | \"solana\"; chain?: string; rpcUrls?: Record<string, string>;\n}) {\n const balance = useBalance(kind, address, chain, rpcUrls);\n const short = `${address.slice(0, 8)}…${address.slice(-6)}`;\n return (\n <div style={{\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, padding: \"10px 14px\", marginBottom: 8,\n }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", marginBottom: 5 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: \"var(--dc-text-muted)\", letterSpacing: \"0.06em\", textTransform: \"uppercase\" }}>\n {label}\n </span>\n <span style={{ fontSize: 11, fontFamily: \"monospace\", color: \"var(--dc-text)\" }}>\n {balance.loading ? \"…\" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`}\n </span>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 8 }}>\n <span style={{ fontSize: 13, fontFamily: \"monospace\", color: \"var(--dc-text)\", letterSpacing: \"0.02em\" }}>\n {short}\n </span>\n <CopyButton value={address} />\n </div>\n </div>\n );\n}\n\n// ── Sign-in view (not connected, or connected-but-no-live-session) ────────────\n\nfunction SignInView({\n onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, authMethods, resumeHint,\n customAuthLabel, onCustomAuthSignIn,\n canUsePasskey, passkeyAddress, onPasskeySignIn,\n}: {\n onGoogleSignIn: () => Promise<void>;\n onKingsChatSignIn?: () => Promise<void>;\n onEmailStart: (email: string) => Promise<{ codeRequired: true }>;\n onEmailVerify: (email: string, code: string) => Promise<void>;\n authMethods: Array<\"google\" | \"email\" | \"kingschat\">;\n resumeHint?: string;\n customAuthLabel?: string;\n onCustomAuthSignIn?: () => Promise<void>;\n canUsePasskey?: boolean;\n passkeyAddress?: string | null;\n onPasskeySignIn?: () => Promise<unknown>;\n}) {\n const [googleLoading, setGoogleLoading] = useState(false);\n const [kingsChatLoading, setKingsChatLoading] = useState(false);\n const [email, setEmail] = useState(\"\");\n const [code, setCode] = useState(\"\");\n const [emailSent, setEmailSent] = useState(false);\n const [emailLoading, setEmailLoading] = useState(false);\n const [customLoading, setCustomLoading] = useState(false);\n const [passkeyLoading, setPasskeyLoading] = useState(false);\n const [showOtherMethods, setShowOtherMethods] = useState(false);\n const [error, setError] = useState(\"\");\n\n // Returning user on this device: a passkey is proof enough — lead with it and\n // keep the full sign-in one tap away as a fallback. This is what turns a\n // page reload from \"sign in again with Google\" into a single biometric.\n const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;\n\n async function handlePasskey() {\n if (!onPasskeySignIn) return;\n setError(\"\"); setPasskeyLoading(true);\n try {\n await onPasskeySignIn();\n // Success closes the modal via the context; nothing to do here.\n } catch (e) {\n const err = e as Error & { name?: string };\n // A cancelled OS prompt isn't worth an error banner, but a real failure\n // must leave the other methods reachable rather than trapping the user.\n if (err?.name !== \"UserCancelledError\") {\n setError(err?.message ?? \"Passkey sign-in failed\");\n setShowOtherMethods(true);\n }\n setPasskeyLoading(false);\n }\n }\n\n async function handleGoogle() {\n setError(\"\"); setGoogleLoading(true);\n try { await onGoogleSignIn(); }\n catch (e) { setError((e as Error).message); setGoogleLoading(false); }\n }\n async function handleKingsChat() {\n if (!onKingsChatSignIn) return;\n setError(\"\"); setKingsChatLoading(true);\n // Unlike Google (a full-page redirect that never returns), this resolves in\n // place when the popup closes — so the loading state has to be cleared on\n // success as well as failure.\n try { await onKingsChatSignIn(); }\n catch (e) { setError((e as Error).message); }\n finally { setKingsChatLoading(false); }\n }\n async function handleEmailStart(e: React.FormEvent) {\n e.preventDefault();\n setError(\"\"); setEmailLoading(true);\n try { await onEmailStart(email); setEmailSent(true); }\n catch (e2) { setError((e2 as Error).message); }\n finally { setEmailLoading(false); }\n }\n async function handleEmailVerify(e: React.FormEvent) {\n e.preventDefault();\n setError(\"\"); setEmailLoading(true);\n try { await onEmailVerify(email, code); }\n catch (e2) { setError((e2 as Error).message); }\n finally { setEmailLoading(false); }\n }\n async function handleCustomAuth() {\n if (!onCustomAuthSignIn) return;\n setError(\"\"); setCustomLoading(true);\n try { await onCustomAuthSignIn(); }\n catch (e) { setError((e as Error).message); }\n finally { setCustomLoading(false); }\n }\n\n const inputStyle: React.CSSProperties = {\n width: \"100%\", background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, color: \"var(--dc-text)\", padding: \"9px 12px\", fontSize: 13,\n outline: \"none\", fontFamily: \"inherit\", boxSizing: \"border-box\",\n };\n\n return (\n <div style={{ padding: \"0 16px 16px\" }}>\n {resumeHint && !passkeyFirst && (\n <div style={{ fontSize: 12, color: \"var(--dc-text-muted)\", marginBottom: 12, textAlign: \"center\" }}>\n Welcome back — sign in again to resume {resumeHint}\n </div>\n )}\n\n {/* Passkey-first: one biometric tap resumes the session, no full sign-in. */}\n {passkeyFirst && (\n <div>\n <div style={{ fontSize: 12, color: \"var(--dc-text-muted)\", marginBottom: 12, textAlign: \"center\" }}>\n Welcome back — unlock to resume{passkeyAddress ? ` ${passkeyAddress.slice(0, 6)}…${passkeyAddress.slice(-4)}` : \"\"}\n </div>\n <button\n onClick={handlePasskey}\n disabled={passkeyLoading}\n style={{\n width: \"100%\", padding: \"11px 0\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10, fontSize: 13, fontWeight: 700,\n cursor: passkeyLoading ? \"not-allowed\" : \"pointer\", opacity: passkeyLoading ? 0.7 : 1,\n fontFamily: \"inherit\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 7,\n }}\n >\n {passkeyLoading ? \"Verifying…\" : \"🔓 Continue with passkey\"}\n </button>\n <button\n onClick={() => setShowOtherMethods(true)}\n style={{\n width: \"100%\", marginTop: 10, background: \"none\", border: \"none\",\n color: \"var(--dc-text-muted)\", fontSize: 12, cursor: \"pointer\", fontFamily: \"inherit\",\n }}\n >\n Use email or Google instead\n </button>\n {error && <div style={{ marginTop: 10, fontSize: 12, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>}\n </div>\n )}\n\n {!passkeyFirst && authMethods.includes(\"google\") && (\n <button\n onClick={handleGoogle}\n disabled={googleLoading}\n style={{\n width: \"100%\", padding: \"10px 0\", marginBottom: 10,\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10, fontSize: 13, fontWeight: 700,\n cursor: googleLoading ? \"not-allowed\" : \"pointer\", opacity: googleLoading ? 0.7 : 1,\n fontFamily: \"inherit\",\n }}\n >\n {googleLoading ? \"Redirecting…\" : \"Continue with Google\"}\n </button>\n )}\n {!passkeyFirst && authMethods.includes(\"kingschat\") && onKingsChatSignIn && (\n <button\n onClick={handleKingsChat}\n disabled={kingsChatLoading}\n style={{\n width: \"100%\", padding: \"10px 0\", marginBottom: 10,\n background: \"var(--dc-surface)\", color: \"var(--dc-text)\",\n border: \"1px solid var(--dc-border)\", borderRadius: 10, fontSize: 13, fontWeight: 700,\n cursor: kingsChatLoading ? \"not-allowed\" : \"pointer\", opacity: kingsChatLoading ? 0.7 : 1,\n fontFamily: \"inherit\",\n }}\n >\n {kingsChatLoading ? \"Waiting for KingsChat…\" : \"Continue with KingsChat\"}\n </button>\n )}\n {!passkeyFirst && authMethods.includes(\"email\") && (\n <>\n {authMethods.includes(\"google\") && (\n <div style={{ textAlign: \"center\", color: \"var(--dc-text-muted)\", fontSize: 12, margin: \"10px 0\" }}>— or —</div>\n )}\n {!emailSent ? (\n <form onSubmit={handleEmailStart} style={{ display: \"flex\", gap: 8 }}>\n <input\n type=\"email\" required placeholder=\"your@email.com\" value={email}\n onChange={(e) => setEmail(e.target.value)} style={{ ...inputStyle, flex: 1 }}\n />\n <button type=\"submit\" disabled={emailLoading} style={{\n padding: \"0 16px\", background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, color: \"var(--dc-text)\", fontSize: 13, cursor: \"pointer\", fontFamily: \"inherit\",\n }}>\n {emailLoading ? \"…\" : \"Send code\"}\n </button>\n </form>\n ) : (\n <form onSubmit={handleEmailVerify} style={{ display: \"flex\", gap: 8 }}>\n <input\n placeholder=\"6-digit code\" value={code} maxLength={6} autoFocus\n onChange={(e) => setCode(e.target.value.replace(/\\D/g, \"\"))}\n style={{ ...inputStyle, flex: 1, letterSpacing: 4, textAlign: \"center\" }}\n />\n <button type=\"submit\" disabled={emailLoading} style={{\n padding: \"0 16px\", background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 8, fontSize: 13, fontWeight: 700, cursor: \"pointer\", fontFamily: \"inherit\",\n }}>\n {emailLoading ? \"…\" : \"Verify\"}\n </button>\n </form>\n )}\n </>\n )}\n {!passkeyFirst && customAuthLabel && onCustomAuthSignIn && (\n <>\n {(authMethods.includes(\"google\") || authMethods.includes(\"email\")) && (\n <div style={{ textAlign: \"center\", color: \"var(--dc-text-muted)\", fontSize: 12, margin: \"10px 0\" }}>— or —</div>\n )}\n <button\n onClick={handleCustomAuth}\n disabled={customLoading}\n style={{\n width: \"100%\", padding: \"10px 0\",\n background: \"var(--dc-surface)\", color: \"var(--dc-text)\",\n border: \"1px solid var(--dc-border)\", borderRadius: 10, fontSize: 13, fontWeight: 600,\n cursor: customLoading ? \"not-allowed\" : \"pointer\", opacity: customLoading ? 0.7 : 1,\n fontFamily: \"inherit\",\n }}\n >\n {customLoading ? \"Connecting…\" : customAuthLabel}\n </button>\n </>\n )}\n {error && (\n <div style={{ marginTop: 10, fontSize: 12, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>\n )}\n </div>\n );\n}\n\n// ── Recovery section (only shown when unlocked) ────────────────────────────────\n\nfunction RecoverySection({\n addresses, onRotateShares, onExportPortableBackup,\n}: {\n addresses: { evm?: string; solana?: string } | null;\n onRotateShares: (opts: { password: string; passwordHint?: string }) => Promise<RecoveryShareFile>;\n onExportPortableBackup: (opts: { password: string; passwordHint?: string }) => Promise<PortableBackup>;\n}) {\n const [expanded, setExpanded] = useState(false);\n const [mode, setMode] = useState<\"share\" | \"portable\" | null>(null);\n const [password, setPassword] = useState(\"\");\n const [passwordHint, setPasswordHint] = useState(\"\");\n const [confirmed, setConfirmed] = useState(false);\n const [busy, setBusy] = useState(false);\n const [result, setResult] = useState<{ kind: \"share\" | \"portable\"; version: number } | null>(null);\n const [error, setError] = useState(\"\");\n\n function reset() {\n setMode(null); setPassword(\"\"); setPasswordHint(\"\"); setConfirmed(false); setError(\"\");\n }\n\n async function handleGenerate() {\n if (!addresses?.evm || !mode) return;\n if (password.length < 8) { setError(\"Password must be at least 8 characters.\"); return; }\n if (mode === \"portable\" && !confirmed) { setError(\"Confirm you understand the risk first.\"); return; }\n\n setBusy(true); setError(\"\");\n try {\n if (mode === \"share\") {\n const file = await onRotateShares({ password, passwordHint: passwordHint || undefined });\n downloadJson(file, `decane-recovery-${addresses.evm.slice(0, 8)}.json`);\n setResult({ kind: \"share\", version: file.shareSetVersion });\n } else {\n const file = await onExportPortableBackup({ password, passwordHint: passwordHint || undefined });\n downloadJson(file, `decane-full-recovery-${addresses.evm.slice(0, 8)}.json`);\n setResult({ kind: \"portable\", version: file.shareSetVersion });\n }\n reset();\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setBusy(false);\n }\n }\n\n const inputStyle: React.CSSProperties = {\n width: \"100%\", background: \"var(--dc-bg)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, color: \"var(--dc-text)\", padding: \"8px 10px\", fontSize: 12,\n outline: \"none\", fontFamily: \"inherit\", boxSizing: \"border-box\",\n };\n const btnStyle: React.CSSProperties = {\n padding: \"8px 12px\", borderRadius: 8, fontSize: 12, fontWeight: 700,\n cursor: \"pointer\", fontFamily: \"inherit\", border: \"none\",\n };\n\n return (\n <div style={{ margin: \"0 16px 14px\", border: \"1px solid var(--dc-border)\", borderRadius: 10, overflow: \"hidden\" }}>\n <button\n onClick={() => setExpanded((v) => !v)}\n style={{\n width: \"100%\", padding: \"10px 14px\", background: \"var(--dc-surface)\", border: \"none\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", cursor: \"pointer\",\n fontFamily: \"inherit\",\n }}\n >\n <span style={{ fontSize: 12, fontWeight: 700, color: \"var(--dc-text)\" }}>Recovery</span>\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\" }}>{expanded ? \"▲\" : \"▼\"}</span>\n </button>\n\n {expanded && (\n <div style={{ padding: \"12px 14px\", borderTop: \"1px solid var(--dc-border)\" }}>\n <p style={{ fontSize: 11, color: \"var(--dc-text-muted)\", lineHeight: 1.5, margin: \"0 0 10px\" }}>\n Save a recovery file so you can restore this wallet on a new device.\n </p>\n\n {!mode && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <button onClick={() => { reset(); setMode(\"share\"); }} style={{ ...btnStyle, background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\" }}>\n Generate recovery-share file\n </button>\n <button onClick={() => { reset(); setMode(\"portable\"); }} style={{ ...btnStyle, background: \"transparent\", border: \"1px solid var(--dc-border)\", color: \"var(--dc-text)\" }}>\n Generate full recovery file\n </button>\n </div>\n )}\n\n {mode === \"share\" && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <p style={{ fontSize: 11, color: \"var(--dc-text-muted)\", margin: 0 }}>\n One share — useless alone, safe to keep in a password manager or cloud drive.\n Generating a new one invalidates any previous recovery-share file.\n </p>\n <input type=\"password\" placeholder=\"Password (min 8 chars)\" value={password} onChange={(e) => setPassword(e.target.value)} style={inputStyle} />\n <input placeholder=\"Password hint (optional)\" value={passwordHint} onChange={(e) => setPasswordHint(e.target.value)} style={inputStyle} />\n {error && <div style={{ fontSize: 11, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>}\n <div style={{ display: \"flex\", gap: 8 }}>\n <button onClick={handleGenerate} disabled={busy} style={{ ...btnStyle, flex: 1, background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\" }}>\n {busy ? \"Generating…\" : \"Generate & download\"}\n </button>\n <button onClick={reset} style={{ ...btnStyle, background: \"transparent\", border: \"1px solid var(--dc-border)\", color: \"var(--dc-text-muted)\" }}>Cancel</button>\n </div>\n </div>\n )}\n\n {mode === \"portable\" && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div style={{\n background: \"rgba(255,85,51,0.08)\", border: \"1px solid rgba(255,85,51,0.3)\",\n borderRadius: 8, padding: \"8px 10px\", fontSize: 11, color: \"#ff9977\", lineHeight: 1.5,\n }}>\n <strong style={{ display: \"block\", marginBottom: 3, color: \"#ff5533\" }}>This file controls your wallet</strong>\n Contains two shares — file plus password gives complete control. Keep it offline,\n not a cloud drive. This also invalidates your current recovery-share file.\n </div>\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6, fontSize: 11, color: \"var(--dc-text)\" }}>\n <input type=\"checkbox\" checked={confirmed} onChange={(e) => setConfirmed(e.target.checked)} style={{ width: \"auto\" }} />\n I understand this is a bearer secret\n </label>\n <input type=\"password\" placeholder=\"Password (min 8 chars)\" value={password} onChange={(e) => setPassword(e.target.value)} style={inputStyle} />\n <input placeholder=\"Password hint (optional)\" value={passwordHint} onChange={(e) => setPasswordHint(e.target.value)} style={inputStyle} />\n {error && <div style={{ fontSize: 11, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>}\n <div style={{ display: \"flex\", gap: 8 }}>\n <button onClick={handleGenerate} disabled={busy || !confirmed} style={{ ...btnStyle, flex: 1, background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\" }}>\n {busy ? \"Generating…\" : \"Generate & download\"}\n </button>\n <button onClick={reset} style={{ ...btnStyle, background: \"transparent\", border: \"1px solid var(--dc-border)\", color: \"var(--dc-text-muted)\" }}>Cancel</button>\n </div>\n </div>\n )}\n\n {result && (\n <div style={{ marginTop: 10, fontSize: 11, color: \"var(--dc-text-muted)\", lineHeight: 1.5 }}>\n {result.kind === \"share\" ? \"Recovery-share file\" : \"Full recovery file\"} downloaded — share\n set is now version {result.version}. Any previous recovery file no longer works.\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ── Main modal ─────────────────────────────────────────────────────────────────\n\nexport function SocialWalletModal({\n open,\n onClose,\n theme = \"auto\",\n socialAuth,\n onUnlock,\n onDisconnect,\n onGoogleSignIn,\n onKingsChatSignIn,\n onEmailStart,\n onEmailVerify,\n authMethods = [\"google\", \"email\"],\n customAuthLabel,\n onCustomAuthSignIn,\n canUsePasskey,\n passkeyAddress,\n onPasskeySignIn,\n onRotateShares,\n onExportPortableBackup,\n rpcUrls,\n chains,\n}: SocialWalletModalProps) {\n const [timer, setTimer] = useState(\"\");\n const [unlocking, setUnlocking] = useState(false);\n const [disconnecting, setDisconnecting] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n injectTokens(theme);\n if (theme !== \"auto\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const h = () => injectTokens(\"auto\");\n mq.addEventListener(\"change\", h);\n return () => mq.removeEventListener(\"change\", h);\n }, [open, theme]);\n\n useEffect(() => {\n if (!socialAuth.sessionExpiresAt) { setTimer(\"\"); return; }\n setTimer(countdown(socialAuth.sessionExpiresAt));\n const id = setInterval(() => setTimer(countdown(socialAuth.sessionExpiresAt!)), 1000);\n return () => clearInterval(id);\n }, [socialAuth.sessionExpiresAt]);\n\n const handleKey = useCallback((e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n }, [onClose]);\n\n useEffect(() => {\n if (!open) return;\n document.addEventListener(\"keydown\", handleKey);\n return () => document.removeEventListener(\"keydown\", handleKey);\n }, [open, handleKey]);\n\n if (!open) return null;\n\n // unlock() ALWAYS requires a fresh, live JWT (to open a TEE session) — and\n // JWTs are deliberately never persisted, so there is no legitimate \"just\n // unlock\" path once socialAuth.needsReconnect is true. Route that state\n // into a real sign-in instead of a call that can only fail.\n async function handleUnlock() {\n setUnlocking(true);\n try { await onUnlock(); } finally { setUnlocking(false); }\n }\n async function handleDisconnect() {\n setDisconnecting(true);\n try { await onDisconnect(); onClose(); } finally { setDisconnecting(false); }\n }\n\n const evmChain = chains?.find((c) => c.startsWith(\"evm:\")) ?? \"evm:11155111\";\n const solChain = chains?.find((c) => c.startsWith(\"solana:\")) ?? \"solana:mainnet\";\n\n const showSignIn = !socialAuth.addresses || socialAuth.needsReconnect;\n\n const modal = (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Social wallet\"\n style={{\n position: \"fixed\", inset: 0, zIndex: 9999,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n padding: 16, fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n }}\n >\n {/* Backdrop */}\n <div\n onClick={onClose}\n style={{\n position: \"absolute\", inset: 0,\n background: \"var(--dc-bg-overlay)\",\n backdropFilter: \"blur(8px)\", WebkitBackdropFilter: \"blur(8px)\",\n }}\n />\n\n {/* Card */}\n <div style={{\n position: \"relative\",\n background: \"var(--dc-bg)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 20, width: \"100%\", maxWidth: 380,\n maxHeight: \"90vh\", overflowY: \"auto\",\n boxShadow: \"0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n }}>\n {/* Gold accent */}\n <div style={{\n height: 2, position: \"sticky\", top: 0, zIndex: 1,\n background: \"linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)\",\n }} />\n\n {/* Header */}\n <div style={{ padding: \"18px 20px 16px\", display: \"flex\", alignItems: \"center\", gap: 11 }}>\n <DecaneMark size={38} />\n <div style={{ flex: 1 }}>\n <div style={{ display: \"flex\", alignItems: \"baseline\", gap: 6 }}>\n <DecaneWordmark size={15} />\n <span style={{ fontSize: 13, fontWeight: 700, color: \"var(--dc-text-muted)\", letterSpacing: \"-0.01em\" }}>\n wallet\n </span>\n </div>\n <div style={{ fontSize: 11, color: \"var(--dc-text-muted)\", marginTop: 2 }}>\n Non-custodial · key split three ways\n </div>\n </div>\n <button\n onClick={onClose}\n style={{\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, width: 28, height: 28, cursor: \"pointer\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n color: \"var(--dc-text-muted)\", flexShrink: 0, padding: 0,\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n\n {showSignIn ? (\n <SignInView\n onGoogleSignIn={onGoogleSignIn}\n onKingsChatSignIn={onKingsChatSignIn}\n onEmailStart={onEmailStart}\n onEmailVerify={onEmailVerify}\n authMethods={authMethods}\n resumeHint={socialAuth.needsReconnect ? \"your wallet\" : undefined}\n customAuthLabel={customAuthLabel}\n onCustomAuthSignIn={onCustomAuthSignIn}\n canUsePasskey={canUsePasskey}\n passkeyAddress={passkeyAddress}\n onPasskeySignIn={onPasskeySignIn}\n />\n ) : (\n <>\n {/* Status bar */}\n <div style={{\n margin: \"0 16px 14px\",\n padding: \"8px 14px\",\n background: socialAuth.isUnlocked ? \"rgba(18,183,106,0.08)\" : \"rgba(245,200,0,0.08)\",\n border: `1px solid ${socialAuth.isUnlocked ? \"rgba(18,183,106,0.2)\" : \"rgba(245,200,0,0.2)\"}`,\n borderRadius: 10,\n display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\",\n }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span style={{\n width: 7, height: 7, borderRadius: \"50%\", flexShrink: 0,\n background: socialAuth.isUnlocked ? \"#12b76a\" : \"var(--dc-accent)\",\n boxShadow: `0 0 6px ${socialAuth.isUnlocked ? \"#12b76a\" : \"var(--dc-accent)\"}`,\n }} />\n <span style={{\n fontSize: 12, fontWeight: 700,\n color: socialAuth.isUnlocked ? \"#12b76a\" : \"var(--dc-accent)\",\n }}>\n {socialAuth.isUnlocked ? \"Unlocked\" : \"Locked\"}\n </span>\n </div>\n {socialAuth.isUnlocked && timer && (\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", fontFamily: \"monospace\" }}>\n expires {timer}\n </span>\n )}\n </div>\n\n {/* Addresses + balances */}\n <div style={{ padding: \"0 16px 14px\" }}>\n {socialAuth.addresses?.evm && (\n <AddressRow label=\"EVM (Ethereum, Base, …)\" address={socialAuth.addresses.evm} kind=\"evm\" chain={evmChain} rpcUrls={rpcUrls} />\n )}\n {socialAuth.addresses?.solana && (\n <AddressRow label=\"Solana\" address={socialAuth.addresses.solana} kind=\"solana\" chain={solChain} rpcUrls={rpcUrls} />\n )}\n </div>\n\n {/* Recovery — only meaningful once unlocked (needs an active TEE session) */}\n {socialAuth.isUnlocked && (\n <RecoverySection\n addresses={socialAuth.addresses}\n onRotateShares={onRotateShares}\n onExportPortableBackup={onExportPortableBackup}\n />\n )}\n\n {/* Actions */}\n <div style={{\n padding: \"14px 16px\", borderTop: \"1px solid var(--dc-border)\",\n display: \"flex\", gap: 8,\n }}>\n {!socialAuth.isUnlocked && (\n <button\n onClick={handleUnlock}\n disabled={unlocking}\n style={{\n flex: 1, padding: \"10px 0\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10,\n fontSize: 13, fontWeight: 700, cursor: unlocking ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\", opacity: unlocking ? 0.7 : 1,\n }}\n >\n {unlocking ? \"Unlocking…\" : \"🔓 Unlock wallet\"}\n </button>\n )}\n <button\n onClick={handleDisconnect}\n disabled={disconnecting}\n style={{\n flex: socialAuth.isUnlocked ? 1 : 0,\n padding: \"10px 16px\",\n background: \"transparent\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text-muted)\",\n fontSize: 13, cursor: disconnecting ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\", opacity: disconnecting ? 0.7 : 1,\n whiteSpace: \"nowrap\",\n }}\n >\n {disconnecting ? \"Signing out…\" : \"Sign out\"}\n </button>\n </div>\n </>\n )}\n\n {/* Brand footer */}\n <div style={{\n padding: \"11px 16px\", borderTop: \"1px solid var(--dc-border)\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 6,\n }}>\n <span style={{ fontSize: 10.5, color: \"var(--dc-text-muted)\", letterSpacing: \"0.02em\" }}>Secured by</span>\n <DecaneMark size={13} muted />\n <DecaneWordmark size={11} muted />\n </div>\n </div>\n </div>\n );\n\n return createPortal(modal, document.body);\n}\n","import React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { createDecane } from \"../factory\";\nimport { createDecaneConnect } from \"../social/client\";\nimport { WalletSelector } from \"./WalletSelector\";\nimport { SocialWalletModal } from \"./SocialWalletModal\";\nimport { WalletStatusOverlay } from \"./StatusOverlay\";\nimport type {\n DecaneProvider,\n DecaneConfig,\n UnifiedWalletAccount,\n ChainType,\n ConnectMode,\n} from \"../types\";\nimport type { DecaneConnect, ConnectResult, AuthProfile } from \"../social/types\";\n\nexport type Theme = \"light\" | \"dark\" | \"auto\";\n\nexport interface SocialAuthState {\n addresses: { evm?: string; solana?: string; tron?: string } | null;\n isNewUser: boolean;\n /**\n * Who the provider said the user is — `{ name?, email?, picture? }`.\n *\n * `null` until a sign-in returns one, and stays null for email sign-in and\n * for providers the user withheld a profile from. It is not persisted across\n * reloads: the backend stores no profile, so a restored session has an\n * address but no name. Copy it somewhere durable if you need it to survive.\n */\n profile: AuthProfile | null;\n isUnlocked: boolean;\n sessionExpiresAt: number | null;\n /**\n * True when `addresses` came from persisted (localStorage) identity only,\n * with no live session. This is NOT the same as \"locked\" — every unlock()\n * requires a fresh, valid JWT to open a TEE session, and JWTs are\n * deliberately never persisted (short-lived, security-sensitive), so\n * there is no legitimate \"just unlock\" path in this state. A consumer\n * should route this into a full reconnect — but see canUsePasskey: when\n * that is true the reconnect is a single biometric prompt rather than a\n * Google redirect or an email code.\n */\n needsReconnect: boolean;\n /**\n * True when this device holds a passkey-wrapped share for the remembered\n * user, so signing back in costs one passkey prompt and nothing else.\n */\n canUsePasskey: boolean;\n /**\n * Long-running work in progress, so the UI can show a status screen instead\n * of appearing frozen. 'creating' = first-time key generation (several\n * seconds); 'unlocking' = reopening the TEE session for a returning user.\n */\n phase: \"creating\" | \"unlocking\" | null;\n}\n\nconst DEFAULT_SOCIAL: SocialAuthState = {\n addresses: null,\n isNewUser: false,\n profile: null,\n isUnlocked: false,\n sessionExpiresAt: null,\n needsReconnect: false,\n canUsePasskey: false,\n phase: null,\n};\n\ninterface DecaneContextValue {\n provider: DecaneProvider;\n selectorOpen: boolean;\n openSelector: () => void;\n closeSelector: () => void;\n theme: Theme;\n setTheme: (t: Theme) => void;\n mode: ConnectMode;\n // Social auth\n socialAuth: SocialAuthState;\n signInWithPasskey: () => Promise<ConnectResult>;\n connectWithGoogle: () => Promise<void>;\n connectWithKingsChat: () => Promise<void>;\n connectWithEmail: (email: string) => Promise<{ codeRequired: true }>;\n verifyEmailCode: (email: string, code: string) => Promise<void>;\n connectWithToken: (token: string, opts?: { providerId?: string }) => Promise<void>;\n // Set only when config.social.customAuth is configured — the built-in UI\n // (WalletSelector / SocialWalletModal) uses this presence to decide\n // whether to render the custom-auth button at all.\n customAuthLabel?: string;\n connectWithCustomAuth?: () => Promise<void>;\n socialUnlock: () => Promise<void>;\n socialDisconnect: () => Promise<void>;\n // Social signing\n socialSignMessage: (chain: string, message: string | Uint8Array) => Promise<string>;\n socialSendTransaction: (req: { chain: string; to: string; value?: bigint; data?: string; gasLimit?: bigint; gasPrice?: bigint }) => Promise<string>;\n socialSignSolanaTransaction: (tx: Uint8Array) => Promise<Uint8Array>;\n socialSignTronTransaction: (rawDataHex: string) => Promise<string>;\n socialSignTypedData: (req: { chain: string; domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string }) => Promise<string>;\n socialGetBalance: (chain?: string) => Promise<import(\"../social/balance\").BalanceResult>;\n socialGetBalances: () => Promise<Array<{ chain: string; balance: import(\"../social/balance\").BalanceResult | null }>>;\n socialGetEthereumProvider: (opts?: { chainId?: number }) => import(\"../social/eip1193\").Eip1193Provider;\n socialSignAuthorization: (req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) => Promise<import(\"../social/signers/evm\").SignedAuthorization>;\n socialGetAccessToken: () => string | null;\n socialRecordTransaction: (tx: import(\"../social/types\").RecordTransactionInput) => Promise<import(\"../social/types\").TransactionRecord>;\n socialGetTransactionHistory: (limit?: number) => Promise<import(\"../social/types\").TransactionRecord[]>;\n // Social recovery (2-of-3 Shamir share set)\n socialRotateShares: (opts: { password: string; passwordHint?: string }) => Promise<import(\"../social/recovery/recoveryShareFile\").RecoveryShareFile>;\n socialExportPortableBackup: (opts: { password: string; passwordHint?: string }) => Promise<import(\"../social/recovery/portableBackup\").PortableBackup>;\n socialHasRecoveryShare: () => Promise<boolean>;\n socialShouldPromptRecovery: () => Promise<boolean>;\n socialDismissRecoveryPrompt: () => Promise<void>;\n // Social wallet modal\n socialModalOpen: boolean;\n openSocialModal: () => void;\n closeSocialModal: () => void;\n}\n\nconst DecaneContext = createContext<DecaneContextValue | null>(null);\n\ninterface DecaneKitProps {\n config?: DecaneConfig;\n children: ReactNode;\n}\n\nfunction hasSocial(mode: ConnectMode): boolean {\n return (\n mode === \"all\" ||\n mode === \"social\" ||\n mode === \"evm+social\" ||\n mode === \"solana+social\" ||\n mode === \"tron+social\" ||\n mode === \"evm+tron+social\"\n );\n}\n\nfunction deriveNetworks(\n mode: ConnectMode,\n explicit?: DecaneConfig[\"networks\"],\n): DecaneConfig[\"networks\"] {\n if (explicit) return explicit;\n if (mode === \"evm\" || mode === \"evm+social\") return \"evm\";\n if (mode === \"solana\" || mode === \"solana+social\") return \"solana\";\n if (mode === \"tron\" || mode === \"tron+social\") return \"tron\";\n return \"all\";\n}\n\nexport function DecaneKit({ config, children }: DecaneKitProps) {\n const mode: ConnectMode = config?.mode ?? \"wallets\";\n\n // Fail loudly at mount rather than letting a missing identifier surface later\n // as an opaque 401/403 from a request that never had a chance of succeeding.\n if (!config?.appId) {\n throw new Error(\n \"DecaneKit: config.appId is required. Pass your dashboard project ID.\",\n );\n }\n if (hasSocial(mode) && !config.social?.apiKey) {\n throw new Error(\n `DecaneKit: config.social.apiKey is required for social sign-in (mode \"${mode}\"). ` +\n \"Create an API key for this project in the dashboard.\",\n );\n }\n\n const walletRef = useRef<DecaneProvider | null>(null);\n if (!walletRef.current) walletRef.current = createDecane(config);\n\n const socialRef = useRef<DecaneConnect | null>(null);\n const socialInitialized = useRef(false);\n\n const [selectorOpen, setSelectorOpen] = useState(false);\n const [socialModalOpen, setSocialModalOpen] = useState(false);\n const [theme, setTheme] = useState<Theme>(config?.theme ?? \"auto\");\n const [socialAuth, setSocialAuth] = useState<SocialAuthState>(DEFAULT_SOCIAL);\n\n const openSelector = useCallback(() => setSelectorOpen(true), []);\n const closeSelector = useCallback(() => setSelectorOpen(false), []);\n const openSocialModal = useCallback(() => setSocialModalOpen(true), []);\n const closeSocialModal = useCallback(() => setSocialModalOpen(false), []);\n\n // Keep session-expiry state fresh\n useEffect(() => {\n if (!socialAuth.isUnlocked) return;\n const id = setInterval(() => {\n const sdk = socialRef.current;\n if (!sdk) return;\n setSocialAuth((p) => ({\n ...p,\n isUnlocked: sdk.isUnlocked(),\n sessionExpiresAt: sdk.sessionExpiresAt(),\n }));\n }, 10_000);\n return () => clearInterval(id);\n }, [socialAuth.isUnlocked]);\n\n // Init social SDK once; auto-complete Google redirect callback\n useEffect(() => {\n if (!hasSocial(mode) || !config?.social || socialInitialized.current) return;\n socialInitialized.current = true;\n\n const {\n apiKey, authMethods, promptPin, apiBaseUrl, chains, rpcUrls,\n requireAssertionPerSignature,\n } = config.social;\n\n createDecaneConnect({\n appId: config.appId,\n apiKey,\n apiBaseUrl,\n authMethods: authMethods ?? [\"google\", \"email\"],\n chains: (chains ?? [\"evm:1\", \"solana:mainnet\"]) as import(\"../social/types\").Chain[],\n rpcUrls,\n promptPin,\n requireAssertionPerSignature,\n }).then((sdk) => {\n socialRef.current = sdk;\n\n sdk.on(\"session-expired\", () =>\n setSocialAuth((p) => ({ ...p, isUnlocked: false, sessionExpiresAt: null })),\n );\n sdk.on(\"disconnected\", () => setSocialAuth(DEFAULT_SOCIAL));\n // Long-running phases drive the \"creating / unlocking your wallet\" screen.\n sdk.on(\"wallet-creating\", () => setSocialAuth((p) => ({ ...p, phase: \"creating\" })));\n sdk.on(\"wallet-unlocking\", () => setSocialAuth((p) => ({ ...p, phase: \"unlocking\" })));\n sdk.on(\"connected\", () => setSocialAuth((p) => ({ ...p, phase: null })));\n\n // If a live session was resumed from sessionStorage (page reload), reflect\n // it immediately as unlocked — no sign-in, no passkey. Otherwise fall back\n // to showing the remembered identity with needsReconnect, which routes to\n // a one-tap passkey (or full sign-in) when the user acts.\n const saved = sdk.getAddresses();\n if (sdk.isUnlocked()) {\n setSocialAuth((p) => ({\n ...p,\n addresses: saved,\n isUnlocked: true,\n needsReconnect: false,\n sessionExpiresAt: sdk.sessionExpiresAt(),\n }));\n } else if (saved) {\n setSocialAuth((p) => ({ ...p, addresses: saved, isUnlocked: false, needsReconnect: true }));\n }\n\n // Whether this device can skip the sign-in flow entirely and go straight\n // to the passkey. Drives which controls the modal offers.\n sdk.canSignInWithPasskey()\n .then((can) => setSocialAuth((p) => ({ ...p, canUsePasskey: can })))\n .catch(() => {});\n\n // Complete Google OAuth redirect if backend bounced back with decane_jwt.\n // Creation runs here with no modal open, which is exactly why the status\n // overlay is rendered by the provider rather than a modal.\n const params = new URLSearchParams(window.location.search);\n if (params.has(\"decane_jwt\") || params.has(\"decane_error\")) {\n sdk.connectWithGoogle().then(applyResult).catch((e) => {\n setSocialAuth((p) => (p.phase ? { ...p, phase: null } : p));\n console.error(e);\n });\n }\n }).catch(console.error);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n function applyResult(result: ConnectResult) {\n const sdk = socialRef.current;\n setSocialAuth({\n addresses: result.addresses,\n isNewUser: result.isNewUser,\n profile: result.profile ?? null,\n isUnlocked: sdk?.isUnlocked() ?? false,\n sessionExpiresAt: sdk?.sessionExpiresAt() ?? null,\n needsReconnect: false,\n canUsePasskey: false,\n phase: null,\n });\n // Re-query rather than assume: signing in provisions a passkey only when\n // the device supports one. PIN-only wallets must not be told they can come\n // back with a passkey they never created.\n sdk?.canSignInWithPasskey()\n .then((can) => setSocialAuth((p) => ({ ...p, canUsePasskey: can })))\n .catch(() => {});\n }\n\n // A phase event may have already fired ('wallet-creating'/'unlocking') when a\n // connect fails; clear it so the status overlay doesn't get stuck on failure.\n const clearPhase = useCallback(() => setSocialAuth((p) => (p.phase ? { ...p, phase: null } : p)), []);\n\n const signInWithPasskey = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n try {\n const result = await sdk.signInWithPasskey();\n applyResult(result);\n setSelectorOpen(false);\n return result;\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const connectWithGoogle = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n await sdk.connectWithGoogle();\n // navigates away — nothing to do after\n }, []);\n\n const connectWithKingsChat = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n // Unlike Google this returns here rather than navigating away, so the\n // result has to be applied to context state the same way the email flow does.\n const result = await sdk.connectWithKingsChat();\n applyResult(result);\n }, [applyResult]);\n\n const connectWithEmail = useCallback(async (email: string) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n return sdk.connectWithEmail(email);\n }, []);\n\n const verifyEmailCode = useCallback(async (email: string, code: string) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n try {\n const result = await sdk.verifyEmailCode(email, code);\n applyResult(result);\n setSelectorOpen(false);\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const connectWithToken = useCallback(async (token: string, opts?: { providerId?: string }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n try {\n const result = await sdk.connectWithToken(token, opts);\n applyResult(result);\n setSelectorOpen(false);\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const customAuthConfig = config?.social?.customAuth;\n const connectWithCustomAuth = useCallback(async () => {\n if (!customAuthConfig) throw new Error(\"Custom auth not configured\");\n const token = await customAuthConfig.getToken();\n await connectWithToken(token, customAuthConfig.providerId ? { providerId: customAuthConfig.providerId } : undefined);\n }, [customAuthConfig, connectWithToken]);\n\n const socialUnlock = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) return;\n setSocialAuth((p) => ({ ...p, phase: \"unlocking\" }));\n try {\n await sdk.unlock();\n setSocialAuth((p) => ({\n ...p,\n isUnlocked: sdk.isUnlocked(),\n sessionExpiresAt: sdk.sessionExpiresAt(),\n needsReconnect: false,\n phase: null,\n }));\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const socialDisconnect = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) return;\n await sdk.disconnect();\n setSocialAuth(DEFAULT_SOCIAL);\n }, []);\n\n const socialSignMessage = useCallback(async (\n chain: string,\n message: string | Uint8Array,\n ): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signMessage({ chain: chain as import(\"../social/types\").Chain, message });\n }, []);\n\n const socialSendTransaction = useCallback(async (\n req: { chain: string; to: string; value?: bigint; data?: string; gasLimit?: bigint; gasPrice?: bigint },\n ): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.sendTransaction({ ...req, chain: req.chain as import(\"../social/types\").Chain });\n }, []);\n\n const socialSignSolanaTransaction = useCallback(async (tx: Uint8Array): Promise<Uint8Array> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signSolanaTransaction(tx);\n }, []);\n\n const socialSignTronTransaction = useCallback(async (rawDataHex: string): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signTronTransaction(rawDataHex);\n }, []);\n\n const socialRecordTransaction = useCallback(async (\n tx: import(\"../social/types\").RecordTransactionInput,\n ): Promise<import(\"../social/types\").TransactionRecord> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.recordTransaction(tx);\n }, []);\n\n const socialGetTransactionHistory = useCallback(async (\n limit?: number,\n ): Promise<import(\"../social/types\").TransactionRecord[]> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getTransactionHistory(limit);\n }, []);\n\n const socialSignTypedData = useCallback(async (\n req: { chain: string; domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string },\n ): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signTypedData({ ...req, chain: req.chain as import(\"../social/types\").Chain });\n }, []);\n\n const socialGetBalance = useCallback(async (chain?: string) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getBalance(chain);\n }, []);\n\n const socialGetEthereumProvider = useCallback((opts?: { chainId?: number }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getEthereumProvider(opts);\n }, []);\n\n const socialSignAuthorization = useCallback(\n async (req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signAuthorization(req);\n },\n [],\n );\n\n const socialGetAccessToken = useCallback((): string | null => {\n return socialRef.current?.getAccessToken() ?? null;\n }, []);\n\n const socialGetBalances = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getBalances();\n }, []);\n\n const socialRotateShares = useCallback(async (opts: { password: string; passwordHint?: string }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.rotateShares(opts);\n }, []);\n\n const socialExportPortableBackup = useCallback(async (opts: { password: string; passwordHint?: string }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.exportPortableBackup(opts);\n }, []);\n\n const socialHasRecoveryShare = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.hasRecoveryShare();\n }, []);\n\n const socialShouldPromptRecovery = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.shouldPromptRecovery();\n }, []);\n\n const socialDismissRecoveryPrompt = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.dismissRecoveryPrompt();\n }, []);\n\n const handleWalletConnect = useCallback(\n (wallet: UnifiedWalletAccount, preference?: ChainType) => {\n walletRef.current!.connect(wallet, preference).catch(console.error);\n },\n [],\n );\n\n const networks = deriveNetworks(mode, config?.networks);\n\n return (\n <DecaneContext.Provider\n value={{\n provider: walletRef.current,\n selectorOpen, openSelector, closeSelector,\n theme, setTheme,\n mode,\n socialAuth,\n signInWithPasskey,\n connectWithGoogle,\n connectWithKingsChat,\n connectWithEmail,\n verifyEmailCode,\n connectWithToken,\n customAuthLabel: customAuthConfig?.label,\n connectWithCustomAuth: customAuthConfig ? connectWithCustomAuth : undefined,\n socialUnlock,\n socialDisconnect,\n socialSignMessage,\n socialSendTransaction,\n socialGetBalance,\n socialGetBalances,\n socialGetEthereumProvider,\n socialSignAuthorization,\n socialSignTronTransaction,\n socialRecordTransaction,\n socialGetTransactionHistory,\n socialGetAccessToken,\n socialSignSolanaTransaction,\n socialSignTypedData,\n socialRotateShares,\n socialExportPortableBackup,\n socialHasRecoveryShare,\n socialShouldPromptRecovery,\n socialDismissRecoveryPrompt,\n socialModalOpen, openSocialModal, closeSocialModal,\n }}\n >\n {children}\n <WalletSelector\n provider={walletRef.current}\n open={selectorOpen}\n onClose={closeSelector}\n onConnect={handleWalletConnect}\n theme={theme}\n networks={networks}\n mode={mode}\n socialAuthMethods={config?.social?.authMethods ?? [\"google\", \"email\"]}\n onGoogleSignIn={connectWithGoogle}\n onKingsChatSignIn={connectWithKingsChat}\n onEmailStart={connectWithEmail}\n onEmailVerify={verifyEmailCode}\n canUsePasskey={socialAuth.canUsePasskey}\n passkeyAddress={socialAuth.addresses?.evm ?? socialAuth.addresses?.solana ?? null}\n onPasskeySignIn={signInWithPasskey}\n customAuthLabel={customAuthConfig?.label}\n onCustomAuthSignIn={customAuthConfig ? connectWithCustomAuth : undefined}\n />\n <SocialWalletModal\n open={socialModalOpen}\n onClose={closeSocialModal}\n theme={theme}\n socialAuth={socialAuth}\n onUnlock={socialUnlock}\n onDisconnect={socialDisconnect}\n customAuthLabel={customAuthConfig?.label}\n onCustomAuthSignIn={customAuthConfig ? connectWithCustomAuth : undefined}\n onGoogleSignIn={connectWithGoogle}\n onKingsChatSignIn={connectWithKingsChat}\n onEmailStart={connectWithEmail}\n onEmailVerify={verifyEmailCode}\n authMethods={config?.social?.authMethods ?? [\"google\", \"email\"]}\n canUsePasskey={socialAuth.canUsePasskey}\n passkeyAddress={socialAuth.addresses?.evm ?? socialAuth.addresses?.solana ?? null}\n onPasskeySignIn={signInWithPasskey}\n onRotateShares={socialRotateShares}\n onExportPortableBackup={socialExportPortableBackup}\n rpcUrls={config?.social?.rpcUrls}\n chains={config?.social?.chains}\n />\n {/* Rendered by the provider (not a modal) so wallet creation after a\n Google redirect still shows a status screen even with no modal open.\n Opt out with social.showStatusOverlay: false to render your own from\n the `phase` the hooks expose. */}\n {config?.social?.showStatusOverlay !== false && (\n <WalletStatusOverlay phase={socialAuth.phase} theme={theme} />\n )}\n </DecaneContext.Provider>\n );\n}\n\nexport function useDecaneContext(): DecaneContextValue {\n const ctx = useContext(DecaneContext);\n if (!ctx) {\n throw new Error(\n \"Decane hooks must be called inside <DecaneKit>. \" +\n \"Wrap your app: <DecaneKit config={...}><App /></DecaneKit>\",\n );\n }\n return ctx;\n}\n","import React, { useEffect } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { CSS_VARS } from \"./styles\";\nimport { DecaneMark, DecaneWordmark } from \"./icons\";\n\n// A self-contained status screen shown while a long-running wallet operation is\n// in flight, so the user never stares at a frozen page wondering if anything is\n// happening. Rendered by <DecaneKit> itself (not tied to a modal being open),\n// because first-time creation often runs right after a Google redirect when no\n// modal is mounted. Injects its own theme tokens for the same reason.\n\nfunction injectTokens(theme: \"light\" | \"dark\" | \"auto\"): void {\n if (typeof document === \"undefined\") return;\n const resolved: \"light\" | \"dark\" =\n theme === \"auto\"\n ? window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\"\n : theme;\n let el = document.getElementById(\"decane-tokens\") as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = \"decane-tokens\";\n document.head.appendChild(el);\n }\n el.textContent = `:root { ${CSS_VARS[resolved]} }`;\n}\n\nexport function WalletStatusOverlay({\n phase,\n theme = \"auto\",\n}: {\n phase: \"creating\" | \"unlocking\" | null;\n theme?: \"light\" | \"dark\" | \"auto\";\n}) {\n useEffect(() => {\n if (!phase) return;\n injectTokens(theme);\n if (theme !== \"auto\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const h = () => injectTokens(\"auto\");\n mq.addEventListener(\"change\", h);\n return () => mq.removeEventListener(\"change\", h);\n }, [phase, theme]);\n\n if (!phase || typeof document === \"undefined\") return null;\n\n const title = phase === \"creating\" ? \"Creating your wallet\" : \"Unlocking your wallet\";\n const sub =\n phase === \"creating\"\n ? \"Generating your keys and splitting them across three shares so no single party ever holds your wallet. This takes a few seconds — please keep this tab open.\"\n : \"Reopening your secure session…\";\n\n return createPortal(\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n style={{\n position: \"fixed\", inset: 0, zIndex: 10000,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n padding: 16, fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n }}\n >\n <div style={{\n position: \"absolute\", inset: 0,\n background: \"var(--dc-bg-overlay, rgba(0,0,0,0.75))\",\n backdropFilter: \"blur(8px)\", WebkitBackdropFilter: \"blur(8px)\",\n }} />\n <div style={{\n position: \"relative\",\n background: \"var(--dc-bg, #0D0D0B)\", border: \"1px solid var(--dc-border, #3D3C39)\",\n borderRadius: 20, width: \"100%\", maxWidth: 340, padding: \"30px 26px\",\n textAlign: \"center\", boxShadow: \"0 24px 64px rgba(0,0,0,0.6)\",\n }}>\n {/* Spinner ring around the mark */}\n <div style={{ display: \"flex\", justifyContent: \"center\", marginBottom: 18 }}>\n <div style={{ position: \"relative\", width: 60, height: 60, display: \"flex\", alignItems: \"center\", justifyContent: \"center\" }}>\n <span style={{\n position: \"absolute\", inset: 0, borderRadius: \"50%\",\n border: \"2px solid var(--dc-border, #3D3C39)\", borderTopColor: \"var(--dc-accent, #F5C800)\",\n animation: \"dc-status-spin 0.8s linear infinite\",\n }} />\n <DecaneMark size={32} />\n </div>\n </div>\n\n <div style={{ fontSize: 16, fontWeight: 800, color: \"var(--dc-text, #F9F9F7)\", letterSpacing: \"-0.02em\", marginBottom: 7 }}>\n {title}\n </div>\n <div style={{ fontSize: 12, color: \"var(--dc-text-muted, #8A8884)\", lineHeight: 1.55 }}>\n {sub}\n </div>\n\n <div style={{ marginTop: 20, paddingTop: 14, borderTop: \"1px solid var(--dc-border, #3D3C39)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 6 }}>\n <DecaneMark size={13} muted />\n <DecaneWordmark size={11} muted />\n </div>\n </div>\n\n <style>{`@keyframes dc-status-spin { to { transform: rotate(360deg); } }`}</style>\n </div>,\n document.body,\n );\n}\n","import { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { useDecaneContext } from \"./context\";\nimport type { DecaneProvider, UnifiedWalletAccount, ChainType, ChainDescriptor } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\n// ── useSocialAuth ─────────────────────────────────────────────────────────────\n// Hook for custom sign-in UI. Works alongside (or instead of) the WalletSelector.\n// Requires mode to include social and social config to be set in <DecaneKit>.\n\nexport function useSocialAuth() {\n const {\n socialAuth,\n connectWithGoogle,\n connectWithEmail,\n verifyEmailCode,\n connectWithToken,\n customAuthLabel,\n connectWithCustomAuth,\n signInWithPasskey: ctxSignInWithPasskey,\n socialUnlock,\n socialDisconnect,\n } = useDecaneContext();\n\n const [googleLoading, setGoogleLoading] = useState(false);\n const [emailLoading, setEmailLoading] = useState(false);\n const [tokenLoading, setTokenLoading] = useState(false);\n const [customLoading, setCustomLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const signInWithGoogle = useCallback(async () => {\n setGoogleLoading(true); setError(null);\n try { await connectWithGoogle(); }\n catch (e: unknown) { setError((e as Error).message); setGoogleLoading(false); }\n // If redirect happens, loading stays true (page navigates away)\n }, [connectWithGoogle]);\n\n const sendEmailCode = useCallback(async (email: string) => {\n setEmailLoading(true); setError(null);\n try {\n await connectWithEmail(email);\n return { codeRequired: true as const };\n } catch (e: unknown) {\n setError((e as Error).message);\n throw e;\n } finally {\n setEmailLoading(false);\n }\n }, [connectWithEmail]);\n\n const confirmEmailCode = useCallback(async (email: string, code: string) => {\n setEmailLoading(true); setError(null);\n try { await verifyEmailCode(email, code); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n finally { setEmailLoading(false); }\n }, [verifyEmailCode]);\n\n const signInWithToken = useCallback(async (token: string, opts?: { providerId?: string }) => {\n setTokenLoading(true); setError(null);\n try { await connectWithToken(token, opts); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n finally { setTokenLoading(false); }\n }, [connectWithToken]);\n\n // Only meaningful when config.social.customAuth is set in <DecaneKit> —\n // calls the configured getToken() then exchanges it the same way as\n // signInWithToken. Undefined when custom auth isn't configured.\n const signInWithCustomAuth = useCallback(async () => {\n if (!connectWithCustomAuth) throw new Error(\"Custom auth not configured\");\n setCustomLoading(true); setError(null);\n try { await connectWithCustomAuth(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n finally { setCustomLoading(false); }\n }, [connectWithCustomAuth]);\n\n // One-tap reconnect for a returning user on this device. After a reload there\n // is no live session (JWTs are never persisted), so a passkey is the smoothest\n // way back in — a single biometric yields a fresh session, no Google/email.\n // Guard on canUsePasskey (false for PIN wallets / new devices).\n const signInWithPasskey = useCallback(async () => {\n setError(null);\n try { await ctxSignInWithPasskey(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [ctxSignInWithPasskey]);\n\n const unlock = useCallback(async () => {\n setError(null);\n try { await socialUnlock(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialUnlock]);\n\n const disconnect = useCallback(async () => {\n setError(null);\n try { await socialDisconnect(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialDisconnect]);\n\n return {\n isConnected: !!socialAuth.addresses,\n isUnlocked: socialAuth.isUnlocked,\n isNewUser: socialAuth.isNewUser,\n addresses: socialAuth.addresses,\n sessionExpiresAt: socialAuth.sessionExpiresAt,\n // True when this device can skip the full sign-in and resume with a passkey.\n canUsePasskey: socialAuth.canUsePasskey,\n // Long-running work in progress, for driving your own status UI.\n phase: socialAuth.phase,\n isCreatingWallet: socialAuth.phase === \"creating\",\n // True when addresses are known (from a previous visit) but there's no\n // live session — unlock() will always throw in this state (every\n // unlock requires a fresh JWT, and JWTs are never persisted). Route\n // this into a real reconnect (signInWithGoogle / sendEmailCode), not unlock().\n needsReconnect: socialAuth.needsReconnect,\n googleLoading,\n emailLoading,\n tokenLoading,\n customLoading,\n customAuthLabel,\n error,\n clearError: () => setError(null),\n signInWithGoogle,\n sendEmailCode,\n confirmEmailCode,\n signInWithToken,\n signInWithCustomAuth: connectWithCustomAuth ? signInWithCustomAuth : undefined,\n signInWithPasskey,\n unlock,\n disconnect,\n };\n}\n\n// ── useSocialWallet ───────────────────────────────────────────────────────────\n// Full hook for the social wallet — auth state, signing methods, and modal control.\n\nexport function useSocialWallet() {\n const {\n socialAuth,\n socialUnlock,\n socialDisconnect,\n socialSignMessage,\n socialSendTransaction,\n socialSignSolanaTransaction,\n socialSignTronTransaction,\n socialRecordTransaction,\n socialGetTransactionHistory,\n socialSignTypedData,\n socialGetBalance,\n socialGetBalances,\n socialGetEthereumProvider,\n socialSignAuthorization,\n socialGetAccessToken,\n socialRotateShares,\n socialExportPortableBackup,\n socialHasRecoveryShare,\n socialShouldPromptRecovery,\n socialDismissRecoveryPrompt,\n openSocialModal,\n closeSocialModal,\n socialModalOpen,\n } = useDecaneContext();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function run<T>(fn: () => Promise<T>): Promise<T> {\n setLoading(true); setError(null);\n try { return await fn(); }\n catch (e: unknown) { const msg = (e as Error).message; setError(msg); throw e; }\n finally { setLoading(false); }\n }\n\n const signMessage = useCallback(\n (chain: string, message: string | Uint8Array) =>\n run(() => socialSignMessage(chain, message)),\n [socialSignMessage],\n );\n\n const sendTransaction = useCallback(\n (req: { chain: string; to: string; value?: bigint; data?: string; gasLimit?: bigint; gasPrice?: bigint }) =>\n run(() => socialSendTransaction(req)),\n [socialSendTransaction],\n );\n\n const signSolanaTransaction = useCallback(\n (tx: Uint8Array) => run(() => socialSignSolanaTransaction(tx)),\n [socialSignSolanaTransaction],\n );\n\n const signTronTransaction = useCallback(\n (rawDataHex: string) => run(() => socialSignTronTransaction(rawDataHex)),\n [socialSignTronTransaction],\n );\n\n const recordTransaction = useCallback(\n (tx: import(\"../social/types\").RecordTransactionInput) => run(() => socialRecordTransaction(tx)),\n [socialRecordTransaction],\n );\n\n // Read-only fetch — not wrapped in `run` so it doesn't toggle the shared\n // loading/error state a dev is using to drive signing buttons.\n const getTransactionHistory = useCallback(\n (limit?: number) => socialGetTransactionHistory(limit),\n [socialGetTransactionHistory],\n );\n\n const signTypedData = useCallback(\n (req: { chain: string; domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string }) =>\n run(() => socialSignTypedData(req)),\n [socialSignTypedData],\n );\n\n const getBalance = useCallback(\n (chain?: string) => run(() => socialGetBalance(chain)),\n [socialGetBalance],\n );\n\n const signAuthorization = useCallback(\n (req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) =>\n run(() => socialSignAuthorization(req)),\n [socialSignAuthorization],\n );\n\n const getBalances = useCallback(\n () => run(() => socialGetBalances()),\n [socialGetBalances],\n );\n\n const unlock = useCallback(async () => {\n setError(null);\n try { await socialUnlock(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialUnlock]);\n\n const disconnect = useCallback(async () => {\n setError(null);\n try { await socialDisconnect(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialDisconnect]);\n\n const rotateShares = useCallback(\n (opts: { password: string; passwordHint?: string }) => run(() => socialRotateShares(opts)),\n [socialRotateShares],\n );\n\n const exportPortableBackup = useCallback(\n (opts: { password: string; passwordHint?: string }) => run(() => socialExportPortableBackup(opts)),\n [socialExportPortableBackup],\n );\n\n const hasRecoveryShare = useCallback(\n () => run(() => socialHasRecoveryShare()),\n [socialHasRecoveryShare],\n );\n\n const shouldPromptRecovery = useCallback(\n () => run(() => socialShouldPromptRecovery()),\n [socialShouldPromptRecovery],\n );\n\n const dismissRecoveryPrompt = useCallback(\n () => run(() => socialDismissRecoveryPrompt()),\n [socialDismissRecoveryPrompt],\n );\n\n return {\n // State\n isConnected: !!socialAuth.addresses,\n isUnlocked: socialAuth.isUnlocked,\n isNewUser: socialAuth.isNewUser,\n addresses: socialAuth.addresses,\n sessionExpiresAt: socialAuth.sessionExpiresAt,\n // True when addresses are known (from a previous visit) but there's no\n // live session — unlock() will always throw in this state (every\n // unlock requires a fresh JWT, and JWTs are never persisted). Route\n // this into a real reconnect (signInWithGoogle / sendEmailCode), not unlock().\n needsReconnect: socialAuth.needsReconnect,\n // Long-running work in progress ('creating' | 'unlocking' | null), for\n // driving your own status UI in addition to the SDK's built-in overlay.\n phase: socialAuth.phase,\n isCreatingWallet: socialAuth.phase === \"creating\",\n // Modal\n modalOpen: socialModalOpen,\n openModal: openSocialModal,\n closeModal: closeSocialModal,\n // Auth\n unlock,\n disconnect,\n // Signing\n signMessage,\n sendTransaction,\n signSolanaTransaction,\n signTronTransaction,\n recordTransaction,\n getTransactionHistory,\n signTypedData,\n // Balances (native token; read-only, works while locked)\n getBalance,\n getBalances,\n // EVM interop\n signAuthorization,\n // An EIP-1193 provider for viem/wagmi/ethers (memoized).\n getEthereumProvider: socialGetEthereumProvider,\n // The Decane JWT — authenticate the user to your own backend (bundler proxy,\n // etc.); verify server-side against backend.decane.app/.well-known/jwks.json.\n getAccessToken: socialGetAccessToken,\n // Recovery (2-of-3 Shamir share set)\n rotateShares,\n exportPortableBackup,\n hasRecoveryShare,\n shouldPromptRecovery,\n dismissRecoveryPrompt,\n loading,\n error,\n clearError: () => setError(null),\n };\n}\n\n// ── useSocialBalance ──────────────────────────────────────────────────────────\n// Auto-fetching native balance for the social wallet — the \"just show me the\n// balance\" primitive. Re-fetches when the address or chain changes, exposes a\n// manual refetch(), and never throws (errors land in `error`). Pass a chain to\n// pin it; omit to use the SDK's default (first EVM chain, else Solana).\n\nexport function useSocialBalance(chain?: string) {\n const { socialAuth, socialGetBalance } = useDecaneContext();\n const [balance, setBalance] = useState<import(\"../social/balance\").BalanceResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Key the effect on address identity, not the object, so it doesn't refetch\n // on every render when the addresses object is recreated.\n const addrKey = `${socialAuth.addresses?.evm ?? \"\"}|${socialAuth.addresses?.solana ?? \"\"}`;\n\n const refetch = useCallback(async () => {\n if (!socialAuth.addresses) { setBalance(null); return; }\n setLoading(true); setError(null);\n try {\n setBalance(await socialGetBalance(chain));\n } catch (e: unknown) {\n setError((e as Error).message);\n setBalance(null);\n } finally {\n setLoading(false);\n }\n }, [socialGetBalance, chain, socialAuth.addresses]);\n\n useEffect(() => {\n let cancelled = false;\n if (!socialAuth.addresses) { setBalance(null); return; }\n setLoading(true); setError(null);\n socialGetBalance(chain)\n .then((b) => { if (!cancelled) setBalance(b); })\n .catch((e: unknown) => { if (!cancelled) { setError((e as Error).message); setBalance(null); } })\n .finally(() => { if (!cancelled) setLoading(false); });\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [addrKey, chain]);\n\n return { balance, loading, error, refetch };\n}\n\n// ── useEthereumProvider ───────────────────────────────────────────────────────\n// The memoized EIP-1193 provider for the social wallet — pass straight to\n// viem's custom() transport, a wagmi connector, or new ethers.BrowserProvider().\n// Null until the social wallet is connected.\n\nexport function useEthereumProvider(opts?: { chainId?: number }) {\n const { socialAuth, socialGetEthereumProvider } = useDecaneContext();\n const chainId = opts?.chainId;\n return useMemo(() => {\n if (!socialAuth.addresses?.evm) return null;\n try { return socialGetEthereumProvider(chainId ? { chainId } : undefined); }\n catch { return null; }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [socialAuth.addresses?.evm, chainId]);\n}\n\nfunction toDecaneError(err: unknown): DecaneError {\n if (err instanceof DecaneError) return err;\n // Wallet providers (EIP-1193, TronLink, Unisat, etc.) throw plain objects\n // with a `message` field — extract it before falling back to String()\n const msg =\n err instanceof Error\n ? err.message\n : (err as { message?: unknown })?.message != null\n ? String((err as { message: unknown }).message)\n : String(err);\n return new DecaneError(DecaneErrorCode.PROVIDER_ERROR, msg);\n}\n\n// ── useDecane ─────────────────────────────────────────────────────────────────\n\nexport function useDecane() {\n const { provider, theme, setTheme } = useDecaneContext();\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n const refresh = () => forceUpdate((n) => n + 1);\n const events = [\n \"connect\", \"disconnect\",\n \"walletRegistered\", \"walletUpdated\", \"walletUnregistered\",\n \"chainAdded\", \"chainRemoved\",\n ] as const;\n events.forEach((e) => provider.on(e, refresh));\n return () => events.forEach((e) => provider.off(e, refresh));\n }, [provider]);\n\n return {\n provider,\n wallets: provider.wallets,\n evmWallets: provider.evmWallets,\n solanaWallets: provider.solanaWallets,\n multiChainWallets: provider.multiChainWallets,\n chains: provider.chains,\n connectedWallet: provider.connectedWallet,\n activeSession: provider.activeSession,\n activeChain: provider.activeChain,\n isConnected: !!provider.connectedWallet,\n theme,\n setTheme,\n connect: (wallet: UnifiedWalletAccount, preference?: ChainType) =>\n provider.connect(wallet, preference),\n disconnect: () => provider.disconnect(),\n addChain: (chain: ChainDescriptor) => provider.addChain(chain),\n removeChain: (chainId: string) => provider.removeChain(chainId),\n };\n}\n\n// ── useWalletSelector ─────────────────────────────────────────────────────────\n// Modal is owned by <DecaneKit> — this hook just exposes open/close controls.\n\nexport function useWalletSelector() {\n const { selectorOpen, openSelector, closeSelector } = useDecaneContext();\n return { isOpen: selectorOpen, open: openSelector, close: closeSelector };\n}\n\n// ── useChainSwitch ────────────────────────────────────────────────────────────\n\nexport function useChainSwitch() {\n const { provider } = useDecaneContext();\n const [, forceUpdate] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n useEffect(() => {\n const refresh = () => forceUpdate((n) => n + 1);\n provider.on(\"connect\", refresh);\n provider.on(\"disconnect\", refresh);\n return () => {\n provider.off(\"connect\", refresh);\n provider.off(\"disconnect\", refresh);\n };\n }, [provider]);\n\n const switchChain = useCallback(\n async (chainId: string): Promise<void> => {\n setLoading(true);\n setError(null);\n try {\n const existingScope = provider.activeSession?.grantedScopes[chainId];\n await provider.request({\n method: \"wallet_requestPermissions\",\n params: [\n {\n requiredScopes: {\n [chainId]: existingScope ?? {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n },\n },\n optionalScopes: {},\n },\n ],\n });\n forceUpdate((n) => n + 1);\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n return {\n switchChain,\n loading,\n error,\n activeChain: provider.activeChain,\n grantedChains: provider.activeSession\n ? Object.keys(provider.activeSession.grantedScopes)\n : [],\n };\n}\n\n// ── internal: resolve chain + account from active session ─────────────────────\n\nfunction resolveScope(\n provider: DecaneProvider,\n chainId?: string,\n account?: string,\n): { chain: string; account: string } {\n const chain = chainId ?? provider.activeChain;\n if (!chain) {\n throw new DecaneError(\n DecaneErrorCode.NO_ACTIVE_SESSION,\n \"No active chain — connect a wallet first.\",\n );\n }\n const scope = provider.activeSession?.grantedScopes[chain];\n const resolved = account ?? scope?.accounts[0]?.split(\":\").pop() ?? \"\";\n return { chain, account: resolved };\n}\n\n// ── useSignMessage ────────────────────────────────────────────────────────────\n\nexport function useSignMessage() {\n const { provider } = useDecaneContext();\n const [signature, setSignature] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n const signMessage = useCallback(\n async (\n message: string,\n options?: { chainId?: string; account?: string },\n ): Promise<string> => {\n const { chain, account } = resolveScope(\n provider, options?.chainId, options?.account,\n );\n setLoading(true);\n setError(null);\n try {\n const sig = (await provider.request({\n method: \"wallet_signMessage\",\n params: [chain, account, message],\n })) as string;\n setSignature(sig);\n return sig;\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n const reset = useCallback(() => { setSignature(null); setError(null); }, []);\n return { signMessage, signature, loading, error, reset };\n}\n\n// ── useSendTransaction ────────────────────────────────────────────────────────\n\nexport interface TxParams {\n to: string;\n value?: string; // decimal wei (\"1000000\") or hex (\"0x0f4240\")\n data?: string;\n gas?: string;\n gasPrice?: string;\n}\n\nexport function useSendTransaction() {\n const { provider } = useDecaneContext();\n const [txHash, setTxHash] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n const sendTransaction = useCallback(\n async (\n tx: TxParams,\n options?: { chainId?: string; from?: string },\n ): Promise<string> => {\n const { chain, account } = resolveScope(\n provider, options?.chainId, options?.from,\n );\n const value = tx.value\n ? tx.value.startsWith(\"0x\")\n ? tx.value\n : `0x${parseInt(tx.value, 10).toString(16)}`\n : \"0x0\";\n\n setLoading(true);\n setError(null);\n try {\n const hash = (await provider.request({\n method: \"wallet_sendTransaction\",\n params: [chain, account, { ...tx, value }],\n })) as string;\n setTxHash(hash);\n return hash;\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n const reset = useCallback(() => { setTxHash(null); setError(null); }, []);\n return { sendTransaction, txHash, loading, error, reset };\n}\n\n// ── useSignTypedData ──────────────────────────────────────────────────────────\n// EVM only — throws EVM_ONLY_METHOD if called on a Solana chain.\n\nexport function useSignTypedData() {\n const { provider } = useDecaneContext();\n const [signature, setSignature] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n const signTypedData = useCallback(\n async (\n typedData: { domain: unknown; types: unknown; message: unknown },\n options?: { chainId?: string; account?: string },\n ): Promise<string> => {\n const { chain, account } = resolveScope(\n provider, options?.chainId, options?.account,\n );\n setLoading(true);\n setError(null);\n try {\n const sig = (await provider.request({\n method: \"wallet_signTypedData\",\n params: [chain, account, typedData],\n })) as string;\n setSignature(sig);\n return sig;\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n const reset = useCallback(() => { setSignature(null); setError(null); }, []);\n return { signTypedData, signature, loading, error, reset };\n}\n"],"mappings":"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","names":["DecaneErrorCode","sha256","encodeBase58","Transaction","b64","body","StaleDeviceShareError","RecoveryWalletMismatchError","UserCancelledError","buf","startAuthentication","buf","startAuthentication","tokens","hexToBytes","PBKDF2_ITERATIONS","b64","unb64","buf","PBKDF2_ITERATIONS","FILE_VERSION","b64","buf","deriveFileKey","b64","PBKDF2_ITERATIONS","FILE_VERSION","toHex","evmToTronAddress","tokens","Transaction","buf","b64","sha256","encodeBase58","React","React","e","React","useCallback","useEffect","useState","createPortal","injectTokens","useState","React","useEffect","useCallback","createPortal","React","useCallback","useEffect","useState","React","useEffect","createPortal","injectTokens","useEffect","createPortal","React","useState","useCallback","useEffect","verifyEmailCode","React","useState","useEffect","useCallback","verifyEmailCode","useState","useCallback","signSolanaTransaction","useEffect"]}
1
+ {"version":3,"sources":["../src/social/errors.ts","../src/core/emitter.ts","../src/core/registry.ts","../src/errors.ts","../src/constants.ts","../src/core/session.ts","../src/core/chainStore.ts","../src/evm/adapter.ts","../src/solana/adapter.ts","../src/tron/adapter.ts","../src/bitcoin/adapter.ts","../src/core/router.ts","../src/provider.ts","../src/evm/bitcoinSnap.ts","../src/evm/discovery.ts","../src/solana/discovery.ts","../src/tron/discovery.ts","../src/bitcoin/discovery.ts","../src/factory.ts","../src/social/client.ts","../src/social/events.ts","../src/social/api.ts","../src/social/storage.ts","../src/social/session.ts","../src/social/teeClient.ts","../src/social/attestation.ts","../../../infra/tee-measurement.json","../src/social/crypto/shares.ts","../src/social/crypto/wrap.ts","../src/social/crypto/pin.ts","../src/social/crypto/passkey.ts","../src/social/webauthnRegistration.ts","../src/social/auth/email.ts","../src/social/auth/kingschat.ts","../src/social/signers/evm.ts","../src/social/balance.ts","../src/social/eip1193.ts","../src/social/signers/solana.ts","../src/social/recovery/wrappedShareBackup.ts","../src/social/recovery/recoveryShareFile.ts","../src/social/recovery/recoveryFlow.ts","../src/social/recovery/portableBackup.ts","../src/social/index.ts","../src/ui/WalletSelector.tsx","../src/ui/styles.ts","../src/ui/icons.tsx","../src/ui/SocialWalletModal.tsx","../src/ui/context.tsx","../src/ui/StatusOverlay.tsx","../src/ui/hooks.ts"],"sourcesContent":["export class DecaneConnectError extends Error {\n code: string;\n retryable: boolean;\n constructor(code: string, message: string, retryable = false) {\n super(message);\n this.name = 'DecaneConnectError';\n this.code = code;\n this.retryable = retryable;\n }\n}\n\nexport class InvalidApiKeyError extends DecaneConnectError {\n constructor() { super('INVALID_API_KEY', 'API key is invalid or revoked'); }\n}\nexport class OriginNotAllowedError extends DecaneConnectError {\n constructor(origin: string) { super('ORIGIN_NOT_ALLOWED', `Origin ${origin} not in API key allowlist`); }\n}\nexport class SessionExpiredError extends DecaneConnectError {\n constructor() { super('SESSION_EXPIRED', 'Session has expired — call unlock()', true); }\n}\nexport class UnlockRequiredError extends DecaneConnectError {\n constructor() { super('UNLOCK_REQUIRED', 'Wallet must be unlocked before signing', true); }\n}\n/**\n * unlock() was called after a page reload (or any other loss of the in-memory\n * auth state). We still know *who* the user is — their identity and addresses\n * are persisted — but unlock() needs a live JWT to open a TEE session, and\n * JWTs are deliberately never persisted. So there is no unlock() that can\n * succeed here; the user has to re-authenticate.\n *\n * This is its own error type rather than a generic CallSequenceError because\n * it is a *routing* signal, not a programming mistake: the correct response is\n * to show the sign-in UI, which callers can only do reliably if they can tell\n * this case apart from \"you never called connect()\". Prefer checking\n * needsReconnect() up front so this never has to be caught at all.\n */\nexport class ReconnectRequiredError extends DecaneConnectError {\n constructor() {\n super(\n 'RECONNECT_REQUIRED',\n 'Your session ended — sign in again to unlock this wallet',\n true\n );\n }\n}\nexport class UserCancelledError extends DecaneConnectError {\n constructor() { super('USER_CANCELLED', 'User cancelled the operation', true); }\n}\nexport class WebAuthnNotSupportedError extends DecaneConnectError {\n constructor() { super('WEBAUTHN_UNSUPPORTED', 'This browser does not support WebAuthn'); }\n}\nexport class InvalidPinError extends DecaneConnectError {\n constructor() { super('INVALID_PIN', 'Incorrect PIN', true); }\n}\nexport class CallSequenceError extends DecaneConnectError {\n constructor(msg: string) { super('CALL_SEQUENCE', msg); }\n}\nexport class NetworkError extends DecaneConnectError {\n constructor() { super('NETWORK', 'Network request failed', true); }\n}\nexport class ShareCorruptedError extends DecaneConnectError {\n constructor() { super('SHARE_CORRUPTED', 'Stored device share is corrupted'); }\n}\n/**\n * Wallet creation exceeded its time budget.\n *\n * Provisioning is bounded so a stalled network or an unresponsive enclave\n * surfaces as an error the app can act on, rather than a signup that appears to\n * hang forever. The budget covers only the SDK's own work — key generation,\n * share storage, opening the signer session — never time spent waiting on the\n * user (a passkey prompt, choosing a PIN, the recovery-file dialog).\n *\n * Retryable: nothing is left half-created that a later sign-in cannot complete.\n */\nexport class ProvisioningTimeoutError extends DecaneConnectError {\n constructor(step: string) {\n super('PROVISIONING_TIMEOUT', `Wallet setup timed out while ${step}. Check your connection and try again.`, true);\n }\n}\nexport class NewDeviceError extends DecaneConnectError {\n constructor() { super('NEW_DEVICE', 'No device share found. Re-authenticate to set up this device.'); }\n}\n/**\n * The device share this device just used no longer reconstructs the account's\n * real key — almost always because another device recovered via passkey sync\n * since and rotated the whole share set (see rotateOnNewDeviceRecovery in\n * DecaneConnectConfig), silently invalidating every other device's cached\n * copy. Thrown instead of signing: two mismatched shares from different\n * share-set versions still combine to *something*, just not the user's real\n * key, so continuing would risk operating on a wrong (though not\n * attacker-chosen) address. The stale local share is cleared by the caller\n * before this propagates, so the next connect() naturally falls through to\n * recovery instead of repeating the same failure.\n */\nexport class StaleDeviceShareError extends DecaneConnectError {\n constructor() {\n super(\n 'STALE_DEVICE_SHARE',\n 'This device’s wallet share is from a superseded share set (likely rotated from another device) and no longer matches this account. Reconnect to recover a fresh share.',\n true\n );\n }\n}\nexport class PromptPinNotConfiguredError extends DecaneConnectError {\n constructor() { super('PROMPT_PIN_NOT_CONFIGURED', 'Passkey unavailable and no promptPin callback was provided in config'); }\n}\nexport class AttestationError extends DecaneConnectError {\n constructor(msg: string) { super('ATTESTATION_FAILED', msg); }\n}\nexport class RecoveryFailedError extends DecaneConnectError {\n constructor(reason: string) { super('RECOVERY_FAILED', `Recovery failed: ${reason}`, true); }\n}\nexport class InvalidRecoveryFileError extends DecaneConnectError {\n constructor() { super('INVALID_RECOVERY_FILE', 'This does not look like a valid recovery file', false); }\n}\nexport class WrongPasswordError extends DecaneConnectError {\n constructor() { super('WRONG_PASSWORD', 'Incorrect password for this recovery file', true); }\n}\nexport class RecoveryWalletMismatchError extends DecaneConnectError {\n constructor() {\n super(\n 'RECOVERY_WALLET_MISMATCH',\n 'This recovery file is for a different wallet than the account you are signed into',\n false\n );\n }\n}\nexport class ExportNotAuthorizedError extends DecaneConnectError {\n constructor() { super('EXPORT_NOT_AUTHORIZED', 'Export requires a fresh security check', true); }\n}\n","type Handler = (...args: unknown[]) => void;\n\nexport interface Emitter {\n on(event: string, handler: Handler): void;\n off(event: string, handler: Handler): void;\n emit(event: string, ...args: unknown[]): void;\n}\n\nexport function createEmitter(): Emitter {\n const listeners = new Map<string, Set<Handler>>();\n\n return {\n on(event, handler) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n },\n\n off(event, handler) {\n listeners.get(event)?.delete(handler);\n },\n\n emit(event, ...args) {\n listeners.get(event)?.forEach((h) => h(...args));\n },\n };\n}\n","import type {\n RawWalletEntry,\n UnifiedWalletAccount,\n ChainSupport,\n EIP1193Provider,\n StandardWallet,\n TronProvider,\n BitcoinProvider,\n} from \"../types\";\nimport type { Emitter } from \"./emitter\";\n\nexport interface Registry {\n registerOrMerge(incoming: RawWalletEntry): void;\n unregister(provider: StandardWallet): void;\n get: {\n all(): UnifiedWalletAccount[];\n evm(): UnifiedWalletAccount[];\n solana(): UnifiedWalletAccount[];\n tron(): UnifiedWalletAccount[];\n bitcoin(): UnifiedWalletAccount[];\n multiChain(): UnifiedWalletAccount[];\n byId(id: string): UnifiedWalletAccount | undefined;\n };\n}\n\nexport function createRegistry(emitter: Emitter): Registry {\n const wallets: UnifiedWalletAccount[] = [];\n\n function normaliseName(name: string): string {\n return name\n .toLowerCase()\n .replace(/\\s+/g, \"\")\n .replace(/wallet$/, \"\");\n }\n\n function toUnified(incoming: RawWalletEntry): UnifiedWalletAccount {\n const id =\n incoming.rdns ??\n incoming.uuid ??\n normaliseName(incoming.name);\n\n const account: UnifiedWalletAccount = {\n id,\n name: incoming.name,\n icon: incoming.icon,\n rdns: incoming.rdns,\n chainSupport: [incoming.chain] as unknown as ChainSupport,\n };\n\n if (incoming.chain === \"evm\") {\n account.evmProvider = incoming.provider as EIP1193Provider;\n } else if (incoming.chain === \"solana\") {\n account.solanaProvider = incoming.provider as StandardWallet;\n } else if (incoming.chain === \"tron\") {\n account.tronProvider = incoming.provider as TronProvider;\n } else if (incoming.chain === \"bitcoin\") {\n account.bitcoinProvider = incoming.provider as BitcoinProvider;\n }\n\n return account;\n }\n\n function mergeInto(\n existing: UnifiedWalletAccount,\n incoming: RawWalletEntry,\n ): void {\n if (!existing.chainSupport.includes(incoming.chain)) {\n existing.chainSupport = [\n ...existing.chainSupport,\n incoming.chain,\n ].sort() as ChainSupport;\n }\n if (incoming.chain === \"evm\") existing.evmProvider = incoming.provider as EIP1193Provider;\n if (incoming.chain === \"solana\") existing.solanaProvider = incoming.provider as StandardWallet;\n if (incoming.chain === \"tron\") existing.tronProvider = incoming.provider as TronProvider;\n if (incoming.chain === \"bitcoin\") existing.bitcoinProvider = incoming.provider as BitcoinProvider;\n if (!existing.icon && incoming.icon) existing.icon = incoming.icon;\n }\n\n function registerOrMerge(incoming: RawWalletEntry): void {\n // 1. Match by rdns (primary merge key — both sides have rdns and it matches)\n if (incoming.rdns) {\n const existing = wallets.find((w) => w.rdns === incoming.rdns);\n if (existing) {\n mergeInto(existing, incoming);\n emitter.emit(\"walletUpdated\", existing);\n return;\n }\n }\n\n // 2. Match by normalised name — fallback for when rdns didn't match or\n // the incoming entry (typically a Solana Wallet Standard wallet) has no\n // rdns. Solana wallets rarely expose rdns, so this is the normal merge\n // path for multi-chain wallets like Backpack, Phantom, MetaMask.\n if (!incoming.rdns) {\n const norm = normaliseName(incoming.name);\n const existing = wallets.find(\n (w) => normaliseName(w.name) === norm,\n );\n if (existing) {\n mergeInto(existing, incoming);\n emitter.emit(\"walletUpdated\", existing);\n return;\n }\n }\n\n // 3. New wallet\n const account = toUnified(incoming);\n wallets.push(account);\n emitter.emit(\"walletRegistered\", account);\n }\n\n function unregister(provider: StandardWallet): void {\n const idx = wallets.findIndex((w) => w.solanaProvider === provider);\n if (idx === -1) return;\n const entry = wallets[idx];\n if (entry.chainSupport.length === 1) {\n wallets.splice(idx, 1);\n emitter.emit(\"walletUnregistered\", entry);\n } else {\n entry.chainSupport = [\"evm\"];\n entry.solanaProvider = undefined;\n emitter.emit(\"walletUpdated\", entry);\n }\n }\n\n return {\n registerOrMerge,\n unregister,\n get: {\n all: () => [...wallets],\n evm: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"evm\")),\n solana: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"solana\")),\n tron: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"tron\")),\n bitcoin: () => wallets.filter((w) => (w.chainSupport as string[]).includes(\"bitcoin\")),\n multiChain: () => wallets.filter((w) => w.chainSupport.length >= 2),\n byId: (id) => wallets.find((w) => w.id === id),\n },\n };\n}\n","export class DecaneError extends Error {\n constructor(\n public code: DecaneErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"DecaneError\";\n }\n}\n\nexport enum DecaneErrorCode {\n // CAIP-25 standard codes\n USER_REJECTED = 4001,\n UNAUTHORIZED = 4100,\n\n // Session\n NO_ACTIVE_SESSION = 5001,\n SCOPE_MISMATCH = 5002,\n SESSION_EXPIRED = 5003,\n\n // Chain\n UNSUPPORTED_CHAIN = 5010,\n CHAIN_NOT_IN_SCOPE = 5011,\n INVALID_CHAIN_CONFIG = 5012,\n\n // Wallet\n NO_WALLET_CONNECTED = 5020,\n WALLET_DISCONNECTED = 5021,\n PROVIDER_ERROR = 5022,\n\n // Method\n METHOD_NOT_SUPPORTED = 5030,\n EVM_ONLY_METHOD = 5031,\n}\n","import type { ChainDescriptor, ChainType } from \"./types\";\n\n// ── Built-in chains ───────────────────────────────────────────────────────────\n\nconst ETH = { name: \"Ether\", symbol: \"ETH\", decimals: 18 };\nconst SOL = { name: \"SOL\", symbol: \"SOL\", decimals: 9 };\n\nexport const BUILT_IN_CHAINS: ChainDescriptor[] = [\n // ── Tier-1 EVM ──────────────────────────────────────────────────────────────\n {\n id: \"eip155:1\",\n type: \"evm\",\n name: \"Ethereum\",\n chainId: 1,\n nativeCurrency: ETH,\n rpcUrl: \"https://cloudflare-eth.com\",\n blockExplorerUrl: \"https://etherscan.io\",\n },\n {\n id: \"eip155:8453\",\n type: \"evm\",\n name: \"Base\",\n chainId: 8453,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.base.org\",\n blockExplorerUrl: \"https://basescan.org\",\n },\n {\n id: \"eip155:42161\",\n type: \"evm\",\n name: \"Arbitrum One\",\n chainId: 42161,\n nativeCurrency: ETH,\n rpcUrl: \"https://arb1.arbitrum.io/rpc\",\n blockExplorerUrl: \"https://arbiscan.io\",\n },\n {\n id: \"eip155:10\",\n type: \"evm\",\n name: \"Optimism\",\n chainId: 10,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.optimism.io\",\n blockExplorerUrl: \"https://optimistic.etherscan.io\",\n },\n {\n id: \"eip155:56\",\n type: \"evm\",\n name: \"BNB Chain\",\n chainId: 56,\n nativeCurrency: { name: \"BNB\", symbol: \"BNB\", decimals: 18 },\n rpcUrl: \"https://bsc-dataseed.binance.org\",\n blockExplorerUrl: \"https://bscscan.com\",\n },\n {\n id: \"eip155:137\",\n type: \"evm\",\n name: \"Polygon\",\n chainId: 137,\n nativeCurrency: { name: \"MATIC\", symbol: \"MATIC\", decimals: 18 },\n rpcUrl: \"https://polygon-rpc.com\",\n blockExplorerUrl: \"https://polygonscan.com\",\n },\n\n // ── Extended EVM ecosystem ───────────────────────────────────────────────────\n {\n id: \"eip155:2741\",\n type: \"evm\",\n name: \"Abstract\",\n chainId: 2741,\n nativeCurrency: ETH,\n rpcUrl: \"https://api.mainnet.abs.xyz\",\n blockExplorerUrl: \"https://abscan.org\",\n },\n {\n id: \"eip155:888888888\",\n type: \"evm\",\n name: \"Ancient8\",\n chainId: 888888888,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.ancient8.gg\",\n blockExplorerUrl: \"https://scan.ancient8.gg\",\n },\n {\n id: \"eip155:69000\",\n type: \"evm\",\n name: \"Animechain\",\n chainId: 69000,\n nativeCurrency: { name: \"Anime\", symbol: \"ANIME\", decimals: 18 },\n rpcUrl: \"https://rpc.animechain.ai\",\n blockExplorerUrl: \"https://explorer.animechain.ai\",\n },\n {\n id: \"eip155:33139\",\n type: \"evm\",\n name: \"ApeChain\",\n chainId: 33139,\n nativeCurrency: { name: \"ApeCoin\", symbol: \"APE\", decimals: 18 },\n rpcUrl: \"https://rpc.apechain.com/http\",\n blockExplorerUrl: \"https://apescan.io\",\n },\n {\n id: \"eip155:42170\",\n type: \"evm\",\n name: \"Arbitrum Nova\",\n chainId: 42170,\n nativeCurrency: ETH,\n rpcUrl: \"https://nova.arbitrum.io/rpc\",\n blockExplorerUrl: \"https://nova.arbiscan.io\",\n },\n {\n id: \"eip155:43114\",\n type: \"evm\",\n name: \"Avalanche\",\n chainId: 43114,\n nativeCurrency: { name: \"Avalanche\", symbol: \"AVAX\", decimals: 18 },\n rpcUrl: \"https://api.avax.network/ext/bc/C/rpc\",\n blockExplorerUrl: \"https://snowtrace.io\",\n },\n {\n id: \"eip155:8333\",\n type: \"evm\",\n name: \"B3\",\n chainId: 8333,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet-rpc.b3.fun/http\",\n blockExplorerUrl: \"https://explorer.b3.fun\",\n },\n {\n id: \"eip155:80094\",\n type: \"evm\",\n name: \"Berachain\",\n chainId: 80094,\n nativeCurrency: { name: \"BERA\", symbol: \"BERA\", decimals: 18 },\n rpcUrl: \"https://rpc.berachain.com\",\n blockExplorerUrl: \"https://berascan.com\",\n },\n {\n id: \"eip155:81457\",\n type: \"evm\",\n name: \"Blast\",\n chainId: 81457,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.blast.io\",\n blockExplorerUrl: \"https://blastscan.io\",\n },\n {\n id: \"eip155:60808\",\n type: \"evm\",\n name: \"BOB\",\n chainId: 60808,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.gobob.xyz\",\n blockExplorerUrl: \"https://explorer.gobob.xyz\",\n },\n {\n id: \"eip155:288\",\n type: \"evm\",\n name: \"Boba Network\",\n chainId: 288,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.boba.network\",\n blockExplorerUrl: \"https://bobascan.com\",\n },\n {\n id: \"eip155:42220\",\n type: \"evm\",\n name: \"Celo\",\n chainId: 42220,\n nativeCurrency: { name: \"CELO\", symbol: \"CELO\", decimals: 18 },\n rpcUrl: \"https://forno.celo.org\",\n blockExplorerUrl: \"https://celoscan.io\",\n },\n {\n id: \"eip155:21000000\",\n type: \"evm\",\n name: \"Corn\",\n chainId: 21000000,\n nativeCurrency: { name: \"Bitcorn\", symbol: \"BTCN\", decimals: 18 },\n rpcUrl: \"https://mainnet.corn-rpc.com\",\n blockExplorerUrl: \"https://cornscan.io\",\n },\n {\n id: \"eip155:25\",\n type: \"evm\",\n name: \"Cronos\",\n chainId: 25,\n nativeCurrency: { name: \"Cronos\", symbol: \"CRO\", decimals: 18 },\n rpcUrl: \"https://evm.cronos.org\",\n blockExplorerUrl: \"https://cronoscan.com\",\n },\n {\n id: \"eip155:7560\",\n type: \"evm\",\n name: \"Cyber\",\n chainId: 7560,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.cyber.co\",\n blockExplorerUrl: \"https://cyberscan.co\",\n },\n {\n id: \"eip155:666666666\",\n type: \"evm\",\n name: \"Degen\",\n chainId: 666666666,\n nativeCurrency: { name: \"Degen\", symbol: \"DEGEN\", decimals: 18 },\n rpcUrl: \"https://rpc.degen.tips\",\n blockExplorerUrl: \"https://explorer.degen.tips\",\n },\n {\n id: \"eip155:747\",\n type: \"evm\",\n name: \"Flow EVM\",\n chainId: 747,\n nativeCurrency: { name: \"Flow\", symbol: \"FLOW\", decimals: 18 },\n rpcUrl: \"https://mainnet.evm.nodes.onflow.org\",\n blockExplorerUrl: \"https://flowdiver.io\",\n },\n {\n id: \"eip155:100\",\n type: \"evm\",\n name: \"Gnosis\",\n chainId: 100,\n nativeCurrency: { name: \"xDai\", symbol: \"xDAI\", decimals: 18 },\n rpcUrl: \"https://rpc.gnosischain.com\",\n blockExplorerUrl: \"https://gnosisscan.io\",\n },\n {\n id: \"eip155:49321\",\n type: \"evm\",\n name: \"Gunz\",\n chainId: 49321,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.gunz.dev/ext/bc/evm\",\n blockExplorerUrl: \"https://explorer.gunz.dev\",\n },\n {\n id: \"eip155:43111\",\n type: \"evm\",\n name: \"Hemi\",\n chainId: 43111,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.hemi.network/rpc\",\n blockExplorerUrl: \"https://explorer.hemi.xyz\",\n },\n {\n id: \"eip155:999\",\n type: \"evm\",\n name: \"HyperEVM\",\n chainId: 999,\n nativeCurrency: { name: \"HYPE\", symbol: \"HYPE\", decimals: 18 },\n rpcUrl: \"https://rpc.hyperliquid.xyz/evm\",\n blockExplorerUrl: \"https://hyperevm-explorer.hyperliquid.xyz\",\n },\n {\n id: \"eip155:57073\",\n type: \"evm\",\n name: \"Ink\",\n chainId: 57073,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc-gel.inkonchain.com\",\n blockExplorerUrl: \"https://explorer.inkonchain.com\",\n },\n {\n id: \"eip155:59144\",\n type: \"evm\",\n name: \"Linea\",\n chainId: 59144,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.linea.build\",\n blockExplorerUrl: \"https://lineascan.build\",\n },\n {\n id: \"eip155:1135\",\n type: \"evm\",\n name: \"Lisk\",\n chainId: 1135,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.api.lisk.com\",\n blockExplorerUrl: \"https://blockscout.lisk.com\",\n },\n {\n id: \"eip155:169\",\n type: \"evm\",\n name: \"Manta Pacific\",\n chainId: 169,\n nativeCurrency: ETH,\n rpcUrl: \"https://pacific-rpc.manta.network/http\",\n blockExplorerUrl: \"https://pacific-explorer.manta.network\",\n },\n {\n id: \"eip155:5000\",\n type: \"evm\",\n name: \"Mantle\",\n chainId: 5000,\n nativeCurrency: { name: \"MNT\", symbol: \"MNT\", decimals: 18 },\n rpcUrl: \"https://rpc.mantle.xyz\",\n blockExplorerUrl: \"https://explorer.mantle.xyz\",\n },\n {\n id: \"eip155:6342\",\n type: \"evm\",\n name: \"MegaETH\",\n chainId: 6342,\n nativeCurrency: ETH,\n rpcUrl: \"https://carrot.megaeth.com\",\n blockExplorerUrl: \"https://megaexplorer.xyz\",\n },\n {\n id: \"eip155:1088\",\n type: \"evm\",\n name: \"Metis\",\n chainId: 1088,\n nativeCurrency: { name: \"Metis\", symbol: \"METIS\", decimals: 18 },\n rpcUrl: \"https://andromeda.metis.io/?owner=1088\",\n blockExplorerUrl: \"https://andromeda-explorer.metis.io\",\n },\n {\n id: \"eip155:34443\",\n type: \"evm\",\n name: \"Mode\",\n chainId: 34443,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.mode.network\",\n blockExplorerUrl: \"https://modescan.io\",\n },\n {\n id: \"eip155:10143\",\n type: \"evm\",\n name: \"Monad\",\n chainId: 10143,\n nativeCurrency: { name: \"MON\", symbol: \"MON\", decimals: 18 },\n rpcUrl: \"https://testnet-rpc.monad.xyz\",\n blockExplorerUrl: \"https://testnet.monadexplorer.com\",\n },\n {\n id: \"eip155:2818\",\n type: \"evm\",\n name: \"Morph\",\n chainId: 2818,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc-quicknode.morphl2.io\",\n blockExplorerUrl: \"https://explorer.morphl2.io\",\n },\n {\n id: \"eip155:98866\",\n type: \"evm\",\n name: \"Plume\",\n chainId: 98866,\n nativeCurrency: { name: \"Plume\", symbol: \"PLUME\", decimals: 18 },\n rpcUrl: \"https://rpc.plume.org\",\n blockExplorerUrl: \"https://explorer.plume.org\",\n },\n {\n id: \"eip155:1380012617\",\n type: \"evm\",\n name: \"RARI\",\n chainId: 1380012617,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.rpc.rarichain.org/ext/bc/C/rpc\",\n blockExplorerUrl: \"https://mainnet.explorer.rarichain.org\",\n },\n {\n id: \"eip155:690\",\n type: \"evm\",\n name: \"Redstone\",\n chainId: 690,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.redstonechain.com\",\n blockExplorerUrl: \"https://explorer.redstone.xyz\",\n },\n {\n id: \"eip155:2020\",\n type: \"evm\",\n name: \"Ronin\",\n chainId: 2020,\n nativeCurrency: { name: \"RON\", symbol: \"RON\", decimals: 18 },\n rpcUrl: \"https://api.roninchain.com/rpc\",\n blockExplorerUrl: \"https://app.roninchain.com\",\n },\n {\n id: \"eip155:534352\",\n type: \"evm\",\n name: \"Scroll\",\n chainId: 534352,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.scroll.io\",\n blockExplorerUrl: \"https://scrollscan.com\",\n },\n {\n id: \"eip155:1329\",\n type: \"evm\",\n name: \"Sei\",\n chainId: 1329,\n nativeCurrency: { name: \"Sei\", symbol: \"SEI\", decimals: 18 },\n rpcUrl: \"https://evm-rpc.sei-apis.com\",\n blockExplorerUrl: \"https://seistream.app\",\n },\n {\n id: \"eip155:360\",\n type: \"evm\",\n name: \"Shape\",\n chainId: 360,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.shape.network\",\n blockExplorerUrl: \"https://shapescan.xyz\",\n },\n {\n id: \"eip155:50312\",\n type: \"evm\",\n name: \"Somnia\",\n chainId: 50312,\n nativeCurrency: { name: \"STT\", symbol: \"STT\", decimals: 18 },\n rpcUrl: \"https://dream-rpc.somnia.network\",\n blockExplorerUrl: \"https://shannon-explorer.somnia.network\",\n },\n {\n id: \"eip155:1868\",\n type: \"evm\",\n name: \"Soneium\",\n chainId: 1868,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.soneium.org\",\n blockExplorerUrl: \"https://soneium.blockscout.com\",\n },\n {\n id: \"eip155:146\",\n type: \"evm\",\n name: \"Sonic\",\n chainId: 146,\n nativeCurrency: { name: \"Sonic\", symbol: \"S\", decimals: 18 },\n rpcUrl: \"https://rpc.soniclabs.com\",\n blockExplorerUrl: \"https://sonicscan.org\",\n },\n {\n id: \"eip155:1514\",\n type: \"evm\",\n name: \"Story\",\n chainId: 1514,\n nativeCurrency: { name: \"IP\", symbol: \"IP\", decimals: 18 },\n rpcUrl: \"https://mainnet.storyrpc.io\",\n blockExplorerUrl: \"https://storyscan.xyz\",\n },\n {\n id: \"eip155:55244\",\n type: \"evm\",\n name: \"Superposition\",\n chainId: 55244,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.superposition.so\",\n blockExplorerUrl: \"https://explorer.superposition.so\",\n },\n {\n id: \"eip155:5330\",\n type: \"evm\",\n name: \"Superseed\",\n chainId: 5330,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.superseed.xyz\",\n blockExplorerUrl: \"https://explorer.superseed.xyz\",\n },\n {\n id: \"eip155:1923\",\n type: \"evm\",\n name: \"SwellChain\",\n chainId: 1923,\n nativeCurrency: ETH,\n rpcUrl: \"https://swell-mainnet.alt.technology\",\n blockExplorerUrl: \"https://explorer.swellnetwork.io\",\n },\n {\n id: \"eip155:167000\",\n type: \"evm\",\n name: \"Taiko\",\n chainId: 167000,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.mainnet.taiko.xyz\",\n blockExplorerUrl: \"https://taikoscan.io\",\n },\n {\n id: \"eip155:130\",\n type: \"evm\",\n name: \"Unichain\",\n chainId: 130,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.unichain.org\",\n blockExplorerUrl: \"https://uniscan.xyz\",\n },\n {\n id: \"eip155:480\",\n type: \"evm\",\n name: \"World Chain\",\n chainId: 480,\n nativeCurrency: ETH,\n rpcUrl: \"https://worldchain-mainnet.g.alchemy.com/public\",\n blockExplorerUrl: \"https://worldchain-mainnet.explorer.alchemy.com\",\n },\n {\n id: \"eip155:543210\",\n type: \"evm\",\n name: \"ZERO\",\n chainId: 543210,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.zerion.io/v1/zero\",\n blockExplorerUrl: \"https://explorer.zero.network\",\n },\n {\n id: \"eip155:48900\",\n type: \"evm\",\n name: \"Zircuit\",\n chainId: 48900,\n nativeCurrency: ETH,\n rpcUrl: \"https://zircuit1-mainnet.p2pify.com\",\n blockExplorerUrl: \"https://explorer.zircuit.com\",\n },\n {\n id: \"eip155:324\",\n type: \"evm\",\n name: \"zkSync Era\",\n chainId: 324,\n nativeCurrency: ETH,\n rpcUrl: \"https://mainnet.era.zksync.io\",\n blockExplorerUrl: \"https://explorer.zksync.io\",\n },\n {\n id: \"eip155:7777777\",\n type: \"evm\",\n name: \"Zora\",\n chainId: 7777777,\n nativeCurrency: ETH,\n rpcUrl: \"https://rpc.zora.energy\",\n blockExplorerUrl: \"https://explorer.zora.energy\",\n },\n\n // ── Dev / local ──────────────────────────────────────────────────────────────\n {\n id: \"eip155:31337\",\n type: \"evm\",\n name: \"Localhost\",\n chainId: 31337,\n nativeCurrency: ETH,\n rpcUrl: \"http://localhost:8545\",\n isCustom: true,\n },\n\n // ── Solana ───────────────────────────────────────────────────────────────────\n {\n id: \"solana:mainnet\",\n type: \"solana\",\n name: \"Solana\",\n nativeCurrency: SOL,\n blockExplorerUrl: \"https://solscan.io\",\n },\n {\n id: \"solana:devnet\",\n type: \"solana\",\n name: \"Solana Devnet\",\n nativeCurrency: SOL,\n blockExplorerUrl: \"https://solscan.io/?cluster=devnet\",\n },\n\n // ── Tron ─────────────────────────────────────────────────────────────────────\n {\n id: \"tron:mainnet\",\n type: \"tron\",\n name: \"Tron\",\n nativeCurrency: { name: \"Tronix\", symbol: \"TRX\", decimals: 6 },\n blockExplorerUrl: \"https://tronscan.org\",\n },\n {\n id: \"tron:shasta\",\n type: \"tron\",\n name: \"Tron Shasta Testnet\",\n nativeCurrency: { name: \"Tronix\", symbol: \"TRX\", decimals: 6 },\n blockExplorerUrl: \"https://shasta.tronscan.org\",\n isCustom: true,\n },\n\n // ── Bitcoin ───────────────────────────────────────────────────────────────────\n {\n id: \"bip122:mainnet\",\n type: \"bitcoin\",\n name: \"Bitcoin\",\n nativeCurrency: { name: \"Bitcoin\", symbol: \"BTC\", decimals: 8 },\n blockExplorerUrl: \"https://blockstream.info\",\n },\n];\n\n// ── CAIP-2 helpers ────────────────────────────────────────────────────────────\n\nexport function toCAIP2(type: \"evm\", chainId: number): string;\nexport function toCAIP2(type: \"solana\", network: \"mainnet\" | \"devnet\"): string;\nexport function toCAIP2(type: string, id: string | number): string {\n if (type === \"evm\") return `eip155:${id}`;\n if (type === \"solana\") return `solana:${id}`;\n throw new Error(`Unknown chain type: ${type}`);\n}\n\nexport function getChainType(caip2Id: string): ChainType {\n if (caip2Id.startsWith(\"eip155:\")) return \"evm\";\n if (caip2Id.startsWith(\"solana:\")) return \"solana\";\n if (caip2Id.startsWith(\"tron:\")) return \"tron\";\n if (caip2Id.startsWith(\"bip122:\")) return \"bitcoin\";\n throw new Error(`Cannot determine chain type from: ${caip2Id}`);\n}\n\n// ── CAIP-10 helpers ───────────────────────────────────────────────────────────\n\nexport function toCAIP10(chainId: string, address: string): string {\n return `${chainId}:${address}`;\n}\n\nexport function fromCAIP10(account: string): { chainId: string; address: string } {\n const i = account.lastIndexOf(\":\");\n return { chainId: account.slice(0, i), address: account.slice(i + 1) };\n}\n\n// ── Method sets ───────────────────────────────────────────────────────────────\n\nexport const EVM_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n \"wallet_signTypedData\",\n]);\n\nexport const SOLANA_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n // wallet_signTypedData is EVM-only — never included here\n]);\n\nexport const TRON_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n]);\n\nexport const BITCOIN_METHODS = new Set([\n \"wallet_sendTransaction\",\n \"wallet_signMessage\",\n]);\n\n// ── Named chain ID constants ──────────────────────────────────────────────────\n\nexport const CHAINS = {\n // Tier-1\n ETHEREUM: \"eip155:1\",\n BASE: \"eip155:8453\",\n ARBITRUM: \"eip155:42161\",\n OPTIMISM: \"eip155:10\",\n BNB: \"eip155:56\",\n POLYGON: \"eip155:137\",\n // Extended EVM\n ABSTRACT: \"eip155:2741\",\n ANCIENT8: \"eip155:888888888\",\n ANIMECHAIN: \"eip155:69000\",\n APE_CHAIN: \"eip155:33139\",\n ARBITRUM_NOVA: \"eip155:42170\",\n AVALANCHE: \"eip155:43114\",\n B3: \"eip155:8333\",\n BERACHAIN: \"eip155:80094\",\n BLAST: \"eip155:81457\",\n BOB: \"eip155:60808\",\n BOBA: \"eip155:288\",\n CELO: \"eip155:42220\",\n CORN: \"eip155:21000000\",\n CRONOS: \"eip155:25\",\n CYBER: \"eip155:7560\",\n DEGEN: \"eip155:666666666\",\n FLOW_EVM: \"eip155:747\",\n GNOSIS: \"eip155:100\",\n GUNZ: \"eip155:49321\",\n HEMI: \"eip155:43111\",\n HYPER_EVM: \"eip155:999\",\n INK: \"eip155:57073\",\n LINEA: \"eip155:59144\",\n LISK: \"eip155:1135\",\n MANTA_PACIFIC: \"eip155:169\",\n MANTLE: \"eip155:5000\",\n MEGA_ETH: \"eip155:6342\",\n METIS: \"eip155:1088\",\n MODE: \"eip155:34443\",\n MONAD: \"eip155:10143\",\n MORPH: \"eip155:2818\",\n PLUME: \"eip155:98866\",\n RARI: \"eip155:1380012617\",\n REDSTONE: \"eip155:690\",\n RONIN: \"eip155:2020\",\n SCROLL: \"eip155:534352\",\n SEI: \"eip155:1329\",\n SHAPE: \"eip155:360\",\n SOMNIA: \"eip155:50312\",\n SONEIUM: \"eip155:1868\",\n SONIC: \"eip155:146\",\n STORY: \"eip155:1514\",\n SUPERPOSITION: \"eip155:55244\",\n SUPERSEED: \"eip155:5330\",\n SWELL_CHAIN: \"eip155:1923\",\n TAIKO: \"eip155:167000\",\n UNICHAIN: \"eip155:130\",\n WORLD_CHAIN: \"eip155:480\",\n ZERO: \"eip155:543210\",\n ZIRCUIT: \"eip155:48900\",\n ZKSYNC_ERA: \"eip155:324\",\n ZORA: \"eip155:7777777\",\n // Dev\n LOCALHOST: \"eip155:31337\",\n // Solana\n SOLANA: \"solana:mainnet\",\n SOLANA_DEVNET: \"solana:devnet\",\n // Tron\n TRON: \"tron:mainnet\",\n // Bitcoin\n BITCOIN: \"bip122:mainnet\",\n} as const;\n\nexport type ChainId = typeof CHAINS[keyof typeof CHAINS];\n\n// ── Custom chain validation ───────────────────────────────────────────────────\n\nexport function validateCustomChain(chain: unknown): chain is ChainDescriptor {\n if (!chain || typeof chain !== \"object\") return false;\n const c = chain as Record<string, unknown>;\n if (typeof c.id !== \"string\" || !c.id) return false;\n if (c.type !== \"evm\" && c.type !== \"solana\" && c.type !== \"tron\" && c.type !== \"bitcoin\") return false;\n if (typeof c.name !== \"string\" || !c.name) return false;\n if (!c.nativeCurrency || typeof c.nativeCurrency !== \"object\") return false;\n if (c.type === \"evm\" && (typeof c.chainId !== \"number\" || !c.id.startsWith(\"eip155:\")))\n return false;\n if (c.type === \"solana\" && !c.id.startsWith(\"solana:\")) return false;\n return true;\n}\n","import type { ActiveSession } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\nimport { toCAIP10 } from \"../constants\";\n\nconst STORAGE_KEY = \"decane:session\";\n\nfunction loadFromStorage(): ActiveSession | null {\n if (typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n return raw ? (JSON.parse(raw) as ActiveSession) : null;\n } catch {\n return null;\n }\n}\n\nfunction saveToStorage(session: ActiveSession | null): void {\n if (typeof localStorage === \"undefined\") return;\n try {\n if (session) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(session));\n } else {\n localStorage.removeItem(STORAGE_KEY);\n }\n } catch {\n // Storage quota exceeded or private browsing — silently skip\n }\n}\n\nexport interface SessionManager {\n get(): ActiveSession | null;\n set(s: ActiveSession | null): void;\n clear(): void;\n isChainGranted(chainId: string): boolean;\n isAccountGranted(chainId: string, address: string): boolean;\n assertChainInScope(chainId: string): void;\n assertAccountInScope(chainId: string, address: string): void;\n}\n\nexport function createSessionManager(): SessionManager {\n // Restore persisted session on SDK init\n let _session: ActiveSession | null = loadFromStorage();\n\n return {\n get: () => _session,\n\n set(s) {\n _session = s;\n saveToStorage(s);\n },\n\n clear() {\n _session = null;\n saveToStorage(null);\n },\n\n isChainGranted(chainId) {\n return !!_session?.grantedScopes[chainId];\n },\n\n isAccountGranted(chainId, address) {\n const scope = _session?.grantedScopes[chainId];\n if (!scope) return false;\n return scope.accounts.includes(toCAIP10(chainId, address));\n },\n\n assertChainInScope(chainId) {\n if (!this.isChainGranted(chainId)) {\n throw new DecaneError(\n DecaneErrorCode.CHAIN_NOT_IN_SCOPE,\n `Chain ${chainId} is not in the current session scope. Call wallet_requestPermissions first.`,\n );\n }\n },\n\n assertAccountInScope(chainId, address) {\n if (!this.isAccountGranted(chainId, address)) {\n throw new DecaneError(\n DecaneErrorCode.SCOPE_MISMATCH,\n `Account ${address} on chain ${chainId} is not in the current session scope.`,\n );\n }\n },\n };\n}\n","import type { ChainDescriptor } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\nexport interface ChainStore {\n get(id: string): ChainDescriptor | undefined;\n getAll(): ChainDescriptor[];\n add(chain: ChainDescriptor): void;\n remove(id: string): void;\n}\n\nexport function createChainStore(initial: ChainDescriptor[]): ChainStore {\n const chains = new Map<string, ChainDescriptor>(\n initial.map((c) => [c.id, c]),\n );\n\n return {\n get(id) {\n return chains.get(id);\n },\n\n getAll() {\n return [...chains.values()];\n },\n\n add(chain) {\n if (chains.has(chain.id)) {\n throw new DecaneError(\n DecaneErrorCode.INVALID_CHAIN_CONFIG,\n `Chain ${chain.id} is already registered`,\n );\n }\n chains.set(chain.id, chain);\n },\n\n remove(id) {\n const chain = chains.get(id);\n if (!chain) return;\n if (!chain.isCustom) {\n throw new DecaneError(\n DecaneErrorCode.INVALID_CHAIN_CONFIG,\n `Cannot remove built-in chain ${id}`,\n );\n }\n chains.delete(id);\n },\n };\n}\n","import type { EIP1193Provider, CAIP25Method, ChainDescriptor } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\nexport async function eip1193Request(\n provider: EIP1193Provider,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_sendTransaction\":\n return provider.request({\n method: \"eth_sendTransaction\",\n params: [{ ...(payload as object), from: account }],\n }) as Promise<string>;\n\n case \"wallet_signMessage\":\n // personal_sign prepends EIP-191 prefix: \"\\x19Ethereum Signed Message:\\n\"\n return provider.request({\n method: \"personal_sign\",\n params: [payload, account],\n }) as Promise<string>;\n\n case \"wallet_signTypedData\":\n // EIP-712 typed data\n return provider.request({\n method: \"eth_signTypedData_v4\",\n params: [account, JSON.stringify(payload)],\n }) as Promise<string>;\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `EVM adapter: unsupported method ${method}`,\n );\n }\n}\n\nexport async function getEvmAddress(\n provider: EIP1193Provider,\n): Promise<string> {\n const accounts = (await provider.request({\n method: \"eth_requestAccounts\",\n })) as string[];\n if (!accounts?.[0]) {\n throw new DecaneError(\n DecaneErrorCode.USER_REJECTED,\n \"No EVM accounts returned\",\n );\n }\n return accounts[0];\n}\n\n// EIP-3085 — supported by MetaMask and most EVM wallets\nexport async function addEthereumChain(\n provider: EIP1193Provider,\n chain: ChainDescriptor,\n): Promise<void> {\n await provider.request({\n method: \"wallet_addEthereumChain\",\n params: [\n {\n chainId: `0x${chain.chainId!.toString(16)}`,\n chainName: chain.name,\n nativeCurrency: chain.nativeCurrency,\n rpcUrls: chain.rpcUrl ? [chain.rpcUrl] : [],\n blockExplorerUrls: chain.blockExplorerUrl\n ? [chain.blockExplorerUrl]\n : [],\n },\n ],\n });\n}\n","import { base58 } from \"@scure/base\";\nimport type { StandardWallet, CAIP25Method, StandardWalletAccount } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\ninterface SolanaSignAndSendTx {\n signAndSendTransaction(args: {\n transaction: unknown;\n account: StandardWalletAccount;\n }): Promise<Array<{ signature: string }>>;\n}\n\ninterface SolanaSignMessage {\n signMessage(args: {\n message: Uint8Array;\n account: StandardWalletAccount;\n }): Promise<Array<{ signature: Uint8Array }>>;\n}\n\ninterface StandardConnect {\n connect(opts?: { silent?: boolean }): Promise<{\n accounts: Array<{ publicKey: Uint8Array; chains?: string[] }>;\n }>;\n}\n\nfunction deserializeSolanaTransaction(data: unknown): unknown {\n // Passthrough — wallet handles actual deserialization\n return data;\n}\n\nexport async function walletStandardRequest(\n wallet: StandardWallet,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_sendTransaction\": {\n const feature = wallet.features[\n \"solana:signAndSendTransaction\"\n ] as SolanaSignAndSendTx | undefined;\n if (!feature) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Wallet does not support solana:signAndSendTransaction\",\n );\n }\n const walletAccount = wallet.accounts.find(\n (a) => base58.encode(a.publicKey) === account,\n );\n if (!walletAccount) {\n throw new DecaneError(\n DecaneErrorCode.SCOPE_MISMATCH,\n `Account ${account} not found`,\n );\n }\n const tx = deserializeSolanaTransaction(payload);\n const [result] = await feature.signAndSendTransaction({\n transaction: tx,\n account: walletAccount,\n });\n return result.signature;\n }\n\n case \"wallet_signMessage\": {\n const feature = wallet.features[\n \"solana:signMessage\"\n ] as SolanaSignMessage | undefined;\n if (!feature) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Wallet does not support solana:signMessage\",\n );\n }\n const walletAccount = wallet.accounts.find(\n (a) => base58.encode(a.publicKey) === account,\n );\n if (!walletAccount) {\n throw new DecaneError(\n DecaneErrorCode.SCOPE_MISMATCH,\n `Account ${account} not found`,\n );\n }\n const messageBytes =\n typeof payload === \"string\"\n ? new TextEncoder().encode(payload)\n : (payload as Uint8Array);\n const [result] = await feature.signMessage({\n message: messageBytes,\n account: walletAccount,\n });\n return base58.encode(result.signature);\n }\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Solana adapter: unsupported method ${method}`,\n );\n }\n}\n\nfunction isSolanaAccount(a: { chains?: string[] }): boolean {\n return !a.chains?.length || a.chains.some((c) => c.startsWith(\"solana:\"));\n}\n\nexport async function getSolanaAddress(\n wallet: StandardWallet,\n): Promise<string> {\n // Use pre-connected accounts first — avoids triggering multi-chain connect\n // flows that fail for unsupported chains (e.g. tron:728126428 on Backpack)\n const pre = (wallet.accounts as StandardWalletAccount[]).find(isSolanaAccount);\n if (pre) return base58.encode(pre.publicKey);\n\n const connectFeature = wallet.features[\n \"standard:connect\"\n ] as StandardConnect | undefined;\n if (!connectFeature) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Wallet does not support standard:connect\",\n );\n }\n const { accounts } = await connectFeature.connect();\n const solanaAccount = accounts.find(isSolanaAccount);\n if (!solanaAccount) {\n throw new DecaneError(\n DecaneErrorCode.USER_REJECTED,\n \"No Solana accounts returned\",\n );\n }\n return base58.encode(solanaAccount.publicKey);\n}\n","import type { TronProvider, CAIP25Method } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\ninterface TronWeb {\n transactionBuilder?: {\n sendTrx(to: string, amount: number, from: string): Promise<object>;\n triggerSmartContract(\n contractAddress: string,\n functionSelector: string,\n options: object,\n parameters: unknown[],\n issuerAddress: string,\n ): Promise<{ transaction: object }>;\n };\n trx?: {\n sign(transaction: object): Promise<object>;\n sendRawTransaction(signedTx: object): Promise<{ txid?: string; result?: boolean }>;\n };\n defaultAddress?: { base58?: string };\n fullNode?: { host?: string };\n}\n\ntype TronWin = Window & { tronWeb?: TronWeb; tronLink?: { tronWeb?: TronWeb } };\n\nfunction getTronWeb(): TronWeb | undefined {\n if (typeof window === \"undefined\") return undefined;\n const win = window as TronWin;\n return win.tronLink?.tronWeb ?? win.tronWeb;\n}\n\nexport async function getTronAddress(provider: TronProvider): Promise<string> {\n // tronLink.tronWeb is the fully-initialized instance; window.tronWeb may be a stub\n const addr = getTronWeb()?.defaultAddress?.base58;\n if (addr) return addr;\n\n try {\n const result = await provider.request({ method: \"tron_requestAccounts\" });\n const accounts = result as string[];\n if (accounts?.[0]) return accounts[0];\n } catch {\n // fallback below\n }\n const result2 = await provider.request({ method: \"tron_accounts\" }).catch(() => null);\n const accounts2 = result2 as string[] | null;\n if (accounts2?.[0]) return accounts2[0];\n throw new DecaneError(DecaneErrorCode.USER_REJECTED, \"No Tron accounts returned\");\n}\n\nexport async function tronRequest(\n provider: TronProvider,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_signMessage\":\n return provider.request({\n method: \"tron_signMessage\",\n params: { message: payload as string },\n }) as Promise<string>;\n\n case \"wallet_sendTransaction\": {\n const tronWeb = getTronWeb();\n const p = payload as { to: string; value?: number | string; data?: string };\n const toAddress = p.to;\n const sunAmount =\n typeof p.value === \"string\" ? parseInt(p.value, 10) : (p.value ?? 0);\n\n // ── Step 1: build unsigned transaction ───────────────────────────────\n let unsignedTx: object;\n\n if (tronWeb?.transactionBuilder?.sendTrx) {\n // transactionBuilder available — use it directly\n if (p.data && p.data !== \"0x\") {\n const res = await tronWeb.transactionBuilder.triggerSmartContract!(\n toAddress,\n \"transfer(address,uint256)\",\n { callValue: 0, feeLimit: 100_000_000 },\n [],\n account,\n );\n unsignedTx = res.transaction;\n } else {\n unsignedTx = await tronWeb.transactionBuilder.sendTrx(toAddress, sunAmount, account);\n }\n } else {\n // transactionBuilder not available — build via Tron HTTP API\n const host = tronWeb?.fullNode?.host ?? \"https://api.trongrid.io\";\n const endpoint = p.data && p.data !== \"0x\"\n ? `${host}/wallet/triggersmartcontract`\n : `${host}/wallet/createtransaction`;\n const body = p.data && p.data !== \"0x\"\n ? {\n owner_address: account,\n contract_address: toAddress,\n function_selector: \"transfer(address,uint256)\",\n fee_limit: 100_000_000,\n call_value: 0,\n visible: true,\n }\n : {\n owner_address: account,\n to_address: toAddress,\n amount: sunAmount,\n visible: true,\n };\n\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n throw new DecaneError(\n DecaneErrorCode.PROVIDER_ERROR,\n `Failed to build Tron transaction: ${res.statusText}`,\n );\n }\n const json = await res.json() as { transaction?: object } & object;\n // triggersmartcontract wraps result in { transaction: {...} }\n unsignedTx = (json as { transaction?: object }).transaction ?? json;\n }\n\n // ── Step 2: sign ─────────────────────────────────────────────────────\n // TronLink expects the transaction object directly as params (not wrapped)\n let signedTx: object;\n if (tronWeb?.trx?.sign) {\n signedTx = await tronWeb.trx.sign(unsignedTx);\n } else {\n signedTx = await provider.request({\n method: \"tron_signTransaction\",\n params: unsignedTx as Record<string, unknown>,\n }) as object;\n }\n\n // ── Step 3: broadcast ─────────────────────────────────────────────────\n // Same — signed transaction is passed directly as params\n let txid: string | undefined;\n if (tronWeb?.trx?.sendRawTransaction) {\n const result = await tronWeb.trx.sendRawTransaction(signedTx);\n txid = result?.txid;\n } else {\n const result = await provider.request({\n method: \"tron_sendRawTransaction\",\n params: signedTx as Record<string, unknown>,\n }) as { txid?: string };\n txid = result?.txid;\n }\n\n if (!txid) {\n throw new DecaneError(DecaneErrorCode.PROVIDER_ERROR, \"Tron transaction broadcast failed\");\n }\n return txid;\n }\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Tron adapter: unsupported method ${method}`,\n );\n }\n}\n","import type { BitcoinProvider, CAIP25Method } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\nexport async function getBitcoinAddress(provider: BitcoinProvider): Promise<string> {\n const result = await provider.requestAccounts();\n if (!result || result.length === 0) {\n throw new DecaneError(DecaneErrorCode.USER_REJECTED, \"No Bitcoin accounts returned\");\n }\n const first = result[0];\n // Unisat returns string[]; OKX returns {address: string}[]\n return typeof first === \"string\" ? first : (first as { address: string }).address;\n}\n\nexport async function bitcoinRequest(\n provider: BitcoinProvider,\n method: CAIP25Method,\n payload: unknown,\n account: string,\n): Promise<string> {\n switch (method) {\n case \"wallet_signMessage\":\n return provider.signMessage(payload as string);\n\n case \"wallet_sendTransaction\": {\n const { to, value } = payload as { to: string; value: number };\n if (provider.sendBitcoin) {\n return provider.sendBitcoin(to, value);\n }\n // Fallback for wallets that use a generic send method\n if (provider.send) {\n return provider.send({ to, value, from: account }) as Promise<string>;\n }\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n \"Bitcoin wallet does not support sendBitcoin\",\n );\n }\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Bitcoin adapter: unsupported method ${method}`,\n );\n }\n}\n","import type {\n CAIP25Method,\n CAIP25SessionRequest,\n CAIP25SessionResult,\n ChainScope,\n ActiveSession,\n} from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\nimport {\n getChainType,\n toCAIP10,\n EVM_METHODS,\n SOLANA_METHODS,\n TRON_METHODS,\n BITCOIN_METHODS,\n} from \"../constants\";\nimport { getEvmAddress, addEthereumChain, eip1193Request } from \"../evm/adapter\";\nimport { getSolanaAddress, walletStandardRequest } from \"../solana/adapter\";\nimport { getTronAddress, tronRequest } from \"../tron/adapter\";\nimport { getBitcoinAddress, bitcoinRequest } from \"../bitcoin/adapter\";\nimport type { Registry } from \"./registry\";\nimport type { SessionManager } from \"./session\";\nimport type { ChainStore } from \"./chainStore\";\n\nexport interface Router {\n request(args: { method: string; params?: unknown[] }): Promise<unknown>;\n}\n\nexport function createRouter(opts: {\n registry: Registry;\n session: SessionManager;\n chainStore: ChainStore;\n}): Router {\n const { registry, session, chainStore } = opts;\n\n async function request(args: {\n method: string;\n params?: unknown[];\n }): Promise<unknown> {\n switch (args.method) {\n case \"wallet_requestPermissions\":\n return handleRequestPermissions(\n args.params as [CAIP25SessionRequest],\n );\n\n case \"wallet_revokePermissions\":\n return handleRevokePermissions();\n\n case \"wallet_getPermissions\":\n return handleGetPermissions();\n\n case \"wallet_sendTransaction\":\n case \"wallet_signMessage\":\n case \"wallet_signTypedData\":\n return handleSigning(args.method, args.params);\n\n default:\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `Unknown CAIP-25 method: ${args.method}`,\n );\n }\n }\n\n async function handleRequestPermissions([\n req,\n walletIdHint,\n ]: [CAIP25SessionRequest, string?]): Promise<CAIP25SessionResult> {\n const connectedWallet =\n (walletIdHint ? registry.get.byId(walletIdHint) : undefined) ??\n registry.get.all().find((w) => w.id === session.get()?.walletId) ??\n registry.get.all()[0];\n\n if (!connectedWallet) {\n throw new DecaneError(\n DecaneErrorCode.NO_WALLET_CONNECTED,\n \"No wallet connected\",\n );\n }\n\n const allScopes = { ...req.requiredScopes, ...req.optionalScopes };\n const grantedScopes: Record<string, ChainScope> = {};\n\n for (const [chainId, scope] of Object.entries(allScopes)) {\n const chain = chainStore.get(chainId);\n if (!chain) {\n throw new DecaneError(\n DecaneErrorCode.UNSUPPORTED_CHAIN,\n `Unknown chain: ${chainId}`,\n );\n }\n\n const chainType = getChainType(chainId);\n\n if (chainType === \"evm\" && !connectedWallet.evmProvider) continue;\n if (chainType === \"solana\" && !connectedWallet.solanaProvider) continue;\n if (chainType === \"tron\" && !connectedWallet.tronProvider) continue;\n if (chainType === \"bitcoin\" && !connectedWallet.bitcoinProvider) continue;\n\n let address: string;\n if (chainType === \"evm\") {\n address = await getEvmAddress(connectedWallet.evmProvider!);\n if (chain.isCustom) {\n await addEthereumChain(connectedWallet.evmProvider!, chain).catch(() => {});\n }\n } else if (chainType === \"solana\") {\n address = await getSolanaAddress(connectedWallet.solanaProvider!);\n } else if (chainType === \"tron\") {\n address = await getTronAddress(connectedWallet.tronProvider!);\n } else {\n address = await getBitcoinAddress(connectedWallet.bitcoinProvider!);\n }\n\n const methodSet =\n chainType === \"evm\" ? EVM_METHODS :\n chainType === \"solana\" ? SOLANA_METHODS :\n chainType === \"tron\" ? TRON_METHODS :\n BITCOIN_METHODS;\n const grantedMethods = (scope?.methods ?? []).filter((m) =>\n methodSet.has(m),\n ) as CAIP25Method[];\n\n grantedScopes[chainId] = {\n methods: grantedMethods,\n accounts: [toCAIP10(chainId, address)],\n events: scope?.events ?? [],\n };\n }\n\n // Verify all required scopes were granted\n for (const chainId of Object.keys(req.requiredScopes)) {\n if (!grantedScopes[chainId]) {\n throw new DecaneError(\n DecaneErrorCode.UNSUPPORTED_CHAIN,\n `Required chain ${chainId} could not be granted`,\n );\n }\n }\n\n const newSession: ActiveSession = {\n sessionId: crypto.randomUUID(),\n grantedScopes,\n walletId: connectedWallet.id,\n walletType:\n connectedWallet.chainSupport.length === 2\n ? \"multi\"\n : connectedWallet.chainSupport[0],\n createdAt: Date.now(),\n };\n session.set(newSession);\n\n return { sessionId: newSession.sessionId, grantedScopes };\n }\n\n async function handleRevokePermissions(): Promise<null> {\n session.clear();\n return null;\n }\n\n async function handleGetPermissions(): Promise<CAIP25SessionResult | null> {\n const s = session.get();\n if (!s) return null;\n return { sessionId: s.sessionId, grantedScopes: s.grantedScopes };\n }\n\n function extractSigningContext(\n method: string,\n params: unknown[] | undefined,\n ): { chainId: string; account: string; payload: unknown } {\n if (!params || params.length < 3) {\n throw new DecaneError(\n DecaneErrorCode.METHOD_NOT_SUPPORTED,\n `${method} requires [chainId, account, payload] params`,\n );\n }\n return {\n chainId: params[0] as string,\n account: params[1] as string,\n payload: params[2],\n };\n }\n\n async function handleSigning(\n method: string,\n params: unknown[] | undefined,\n ): Promise<string> {\n const s = session.get();\n if (!s) {\n throw new DecaneError(\n DecaneErrorCode.NO_ACTIVE_SESSION,\n \"No active session. Call wallet_requestPermissions first.\",\n );\n }\n\n const { chainId, account, payload } = extractSigningContext(\n method,\n params,\n );\n const chainType = getChainType(chainId);\n\n session.assertChainInScope(chainId);\n session.assertAccountInScope(chainId, account);\n\n if (method === \"wallet_signTypedData\" && chainType !== \"evm\") {\n throw new DecaneError(\n DecaneErrorCode.EVM_ONLY_METHOD,\n \"wallet_signTypedData is only supported on EVM chains\",\n );\n }\n\n const wallet = registry.get.byId(s.walletId);\n if (!wallet) {\n throw new DecaneError(\n DecaneErrorCode.NO_WALLET_CONNECTED,\n \"Connected wallet not found\",\n );\n }\n\n if (chainType === \"evm\") {\n return eip1193Request(wallet.evmProvider!, method as CAIP25Method, payload, account);\n } else if (chainType === \"solana\") {\n return walletStandardRequest(wallet.solanaProvider!, method as CAIP25Method, payload, account);\n } else if (chainType === \"tron\") {\n return tronRequest(wallet.tronProvider!, method as CAIP25Method, payload, account);\n } else {\n return bitcoinRequest(wallet.bitcoinProvider!, method as CAIP25Method, payload, account);\n }\n }\n\n return { request };\n}\n","import type {\n DecaneProvider,\n DecaneConfig,\n UnifiedWalletAccount,\n ChainDescriptor,\n ChainType,\n ActiveSession,\n} from \"./types\";\nimport { DecaneError, DecaneErrorCode } from \"./errors\";\nimport { validateCustomChain } from \"./constants\";\nimport { addEthereumChain } from \"./evm/adapter\";\nimport type { Registry } from \"./core/registry\";\nimport type { SessionManager } from \"./core/session\";\nimport type { ChainStore } from \"./core/chainStore\";\nimport type { Emitter } from \"./core/emitter\";\nimport type { Router } from \"./core/router\";\n\nexport function createProvider(opts: {\n config: DecaneConfig;\n registry: Registry;\n session: SessionManager;\n chainStore: ChainStore;\n router: Router;\n emitter: Emitter;\n}): DecaneProvider {\n const { config, registry, session, chainStore, router, emitter } = opts;\n\n let _connectedWallet: UnifiedWalletAccount | null = null;\n let _activeChain: string | null = config.defaultChain ?? null;\n\n // Restore connected wallet from a persisted session after discovery\n function tryRestoreWallet(w: UnifiedWalletAccount): void {\n const s = session.get();\n if (!s || _connectedWallet) return;\n if (w.id !== s.walletId) return;\n _connectedWallet = w;\n const granted = Object.keys(s.grantedScopes);\n if (!_activeChain || !granted.includes(_activeChain)) {\n _activeChain = granted[0] ?? null;\n }\n emitter.emit(\"connect\", w);\n }\n\n emitter.on(\"walletRegistered\", (w) => tryRestoreWallet(w as UnifiedWalletAccount));\n // Also handle the case where the Solana provider merges in after EVM is already registered\n emitter.on(\"walletUpdated\", (w) => {\n const wallet = w as UnifiedWalletAccount;\n if (_connectedWallet?.id === wallet.id) {\n _connectedWallet = wallet; // keep reference fresh after merge\n } else {\n tryRestoreWallet(wallet);\n }\n });\n\n const provider: DecaneProvider = {\n // ── CAIP-25 request gateway ─────────────────────────────────────────────\n\n request(args) {\n return router.request(args);\n },\n\n on(event, handler) {\n emitter.on(event, handler);\n },\n\n off(event, handler) {\n emitter.off(event, handler);\n },\n\n // ── Registry views ──────────────────────────────────────────────────────\n\n get wallets() {\n return registry.get.all();\n },\n\n get evmWallets() {\n return registry.get.evm();\n },\n\n get solanaWallets() {\n return registry.get.solana();\n },\n\n get multiChainWallets() {\n return registry.get.multiChain();\n },\n\n get tronWallets() {\n return registry.get.tron();\n },\n\n get bitcoinWallets() {\n return registry.get.bitcoin();\n },\n\n // ── Connection ──────────────────────────────────────────────────────────\n\n async connect(wallet: UnifiedWalletAccount, preferredChain?: ChainType): Promise<void> {\n if (session.get()) {\n session.clear();\n emitter.emit(\"disconnect\");\n }\n\n _connectedWallet = wallet;\n\n const support = wallet.chainSupport as readonly string[];\n\n const hasEvm = support.includes(\"evm\") && preferredChain !== \"solana\" && preferredChain !== \"tron\" && preferredChain !== \"bitcoin\";\n const hasSol = support.includes(\"solana\") && preferredChain !== \"evm\" && preferredChain !== \"tron\" && preferredChain !== \"bitcoin\";\n const hasTron = support.includes(\"tron\") && preferredChain !== \"evm\" && preferredChain !== \"solana\" && preferredChain !== \"bitcoin\";\n const hasBitcoin = support.includes(\"bitcoin\") && preferredChain !== \"evm\" && preferredChain !== \"solana\" && preferredChain !== \"tron\";\n\n // Set active chain based on preference priority\n if (hasEvm) {\n _activeChain = config.defaultChain?.startsWith(\"eip155:\")\n ? config.defaultChain\n : \"eip155:1\";\n } else if (hasSol) {\n _activeChain = \"solana:mainnet\";\n } else if (hasTron) {\n _activeChain = \"tron:mainnet\";\n } else if (hasBitcoin) {\n _activeChain = \"bip122:mainnet\";\n }\n\n const required: Record<string, { methods: string[]; accounts: string[]; events: string[] }> = {};\n const optional: Record<string, { methods: string[]; accounts: string[]; events: string[] }> = {};\n\n if (hasEvm) {\n required[_activeChain ?? \"eip155:1\"] = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\", \"wallet_signTypedData\"],\n accounts: [],\n events: [\"chainChanged\", \"accountsChanged\"],\n };\n }\n if (hasSol) {\n const solChain = \"solana:mainnet\";\n const scope = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n };\n if (hasEvm) {\n optional[solChain] = scope;\n } else {\n required[solChain] = scope;\n _activeChain = solChain;\n }\n }\n if (hasTron) {\n const tronChain = \"tron:mainnet\";\n const scope = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n };\n if (hasEvm || hasSol) {\n optional[tronChain] = scope;\n } else {\n required[tronChain] = scope;\n _activeChain = tronChain;\n }\n }\n if (hasBitcoin) {\n const btcChain = \"bip122:mainnet\";\n const scope = {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n };\n if (hasEvm || hasSol || hasTron) {\n optional[btcChain] = scope;\n } else {\n required[btcChain] = scope;\n _activeChain = btcChain;\n }\n }\n\n await router.request({\n method: \"wallet_requestPermissions\",\n params: [{ requiredScopes: required, optionalScopes: optional }, wallet.id],\n });\n\n const s = session.get();\n if (s) {\n const granted = Object.keys(s.grantedScopes);\n if (_activeChain && !granted.includes(_activeChain)) {\n _activeChain = granted[0] ?? null;\n }\n }\n\n emitter.emit(\"connect\", wallet);\n },\n\n async disconnect(): Promise<void> {\n session.clear();\n _connectedWallet = null;\n _activeChain = null;\n emitter.emit(\"disconnect\");\n },\n\n // ── Custom chain management ─────────────────────────────────────────────\n\n addChain(chain: ChainDescriptor): void {\n if (!validateCustomChain(chain)) {\n throw new DecaneError(\n DecaneErrorCode.INVALID_CHAIN_CONFIG,\n \"Invalid chain descriptor\",\n );\n }\n chainStore.add(chain);\n\n if (_connectedWallet?.evmProvider && chain.type === \"evm\") {\n addEthereumChain(_connectedWallet.evmProvider, chain).catch(() => {});\n }\n\n emitter.emit(\"chainAdded\", chain);\n },\n\n removeChain(chainId: string): void {\n chainStore.remove(chainId);\n\n const s = session.get();\n if (s?.grantedScopes[chainId]) {\n delete (s.grantedScopes as Record<string, unknown>)[chainId];\n session.set(s);\n }\n\n if (_activeChain === chainId) {\n const remaining = Object.keys(session.get()?.grantedScopes ?? {});\n _activeChain = remaining[0] ?? null;\n }\n\n emitter.emit(\"chainRemoved\", chainId);\n },\n\n getChain(chainId: string): ChainDescriptor | undefined {\n return chainStore.get(chainId);\n },\n\n get chains(): ChainDescriptor[] {\n return chainStore.getAll();\n },\n\n // ── State ───────────────────────────────────────────────────────────────\n\n get connectedWallet(): UnifiedWalletAccount | null {\n return _connectedWallet;\n },\n\n get activeSession(): ActiveSession | null {\n return session.get();\n },\n\n get activeChain(): string | null {\n return _activeChain;\n },\n };\n\n return provider;\n}\n","import type { EIP1193Provider, BitcoinProvider } from \"../types\";\nimport type { Registry } from \"../core/registry\";\n\n// Known Bitcoin snap IDs — checked in order, first match wins\nconst BITCOIN_SNAP_IDS = [\n \"npm:@metamask/bitcoin-snap\",\n \"npm:@consensys/btc-snap\",\n] as const;\n\ntype SnapMap = Record<string, { enabled?: boolean; blocked?: boolean } | undefined>;\n\nasync function detectBitcoinSnap(provider: EIP1193Provider): Promise<string | null> {\n try {\n const snaps = (await provider.request({ method: \"wallet_getSnaps\" })) as SnapMap | null;\n if (!snaps) return null;\n for (const id of BITCOIN_SNAP_IDS) {\n const snap = snaps[id];\n if (snap && snap.blocked !== true) return id;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction makeBitcoinSnapProvider(snapId: string, evmProvider: EIP1193Provider): BitcoinProvider {\n function invoke(method: string, params?: unknown): Promise<unknown> {\n return evmProvider.request({\n method: \"wallet_invokeSnap\",\n params: [{ snapId, request: { method, params } }],\n });\n }\n\n return {\n async requestAccounts() {\n // Different snap versions use different method names — try both\n const result = await invoke(\"btc_getAddress\").catch(() => invoke(\"btc_getPublicKey\"));\n if (typeof result === \"string\") return [result];\n if (Array.isArray(result)) return result as string[];\n return [];\n },\n async signMessage(message: string) {\n return invoke(\"btc_signMessage\", [message]) as Promise<string>;\n },\n async sendBitcoin(to: string, value: number) {\n return invoke(\"btc_sendBitcoin\", [{ to, satoshis: value }]) as Promise<string>;\n },\n };\n}\n\nexport async function tryRegisterBitcoinSnap(\n registry: Registry,\n name: string,\n icon: string,\n rdns: string | undefined,\n evmProvider: EIP1193Provider,\n): Promise<void> {\n const snapId = await detectBitcoinSnap(evmProvider);\n if (!snapId) return;\n\n registry.registerOrMerge({\n chain: \"bitcoin\",\n name,\n icon,\n rdns,\n provider: makeBitcoinSnapProvider(snapId, evmProvider),\n });\n}\n","import type { EIP6963AnnounceProviderEvent, EIP1193Provider } from \"../types\";\nimport type { Registry } from \"../core/registry\";\nimport { tryRegisterBitcoinSnap } from \"./bitcoinSnap\";\n\nexport function startEvmDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return; // SSR guard\n\n const seenUuids = new Set<string>();\n\n window.addEventListener(\n \"eip6963:announceProvider\",\n (event: Event) => {\n const e = event as EIP6963AnnounceProviderEvent;\n const { info, provider } = e.detail;\n\n if (seenUuids.has(info.uuid)) return;\n seenUuids.add(info.uuid);\n\n registry.registerOrMerge({\n chain: \"evm\",\n name: info.name,\n icon: info.icon,\n rdns: info.rdns,\n uuid: info.uuid,\n provider,\n });\n\n // Async: check for an installed Bitcoin snap on this wallet (fire-and-forget)\n tryRegisterBitcoinSnap(\n registry,\n info.name,\n info.icon,\n info.rdns,\n provider as EIP1193Provider,\n ).catch(() => {});\n },\n );\n\n window.dispatchEvent(new CustomEvent(\"eip6963:requestProvider\"));\n\n // Re-request after 100ms to catch wallets that load slightly after the SDK\n setTimeout(\n () => window.dispatchEvent(new CustomEvent(\"eip6963:requestProvider\")),\n 100,\n );\n}\n","import { getWallets } from \"@wallet-standard/app\";\nimport type { StandardWallet, WalletWithRdns } from \"../types\";\nimport type { Registry } from \"../core/registry\";\n\nexport function startSolanaDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return; // SSR guard\n\n const { get, on } = getWallets();\n\n function register(wallet: StandardWallet): void {\n const required = [\n \"standard:connect\",\n \"solana:signTransaction\",\n \"solana:signMessage\",\n ];\n if (!required.every((f) => f in wallet.features)) return;\n\n registry.registerOrMerge({\n chain: \"solana\",\n name: wallet.name,\n icon: wallet.icon,\n rdns: (wallet as WalletWithRdns).rdns ?? undefined,\n provider: wallet,\n });\n }\n\n (get() as unknown as StandardWallet[]).forEach(register);\n\n on(\"register\", (...wallets) =>\n (wallets as unknown as StandardWallet[]).forEach(register),\n );\n\n on(\"unregister\", (...wallets) =>\n (wallets as unknown as StandardWallet[]).forEach((w) => registry.unregister(w)),\n );\n}\n","import type { Registry } from \"../core/registry\";\nimport type { TronProvider } from \"../types\";\n\ndeclare global {\n interface Window {\n tronLink?: TronProvider;\n tronWeb?: { defaultAddress?: { base58?: string }; ready?: boolean };\n }\n}\n\nconst TRONLINK_RDNS = \"link.tron.tronlink\";\n\n// Base64 encoded SVG of TronLink icon (red circle with play triangle)\nconst TRONLINK_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNGRjAwMTMiLz48cG9seWdvbiBwb2ludHM9IjEyLDkgMjMsMTYgMTIsMjMiIGZpbGw9IndoaXRlIi8+PC9zdmc+\";\n\nexport function startTronDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return;\n let registered = false;\n\n function tryRegister() {\n if (registered || !window.tronLink) return;\n registered = true;\n registry.registerOrMerge({\n chain: \"tron\",\n name: \"TronLink\",\n icon: TRONLINK_ICON,\n rdns: TRONLINK_RDNS,\n provider: window.tronLink,\n });\n }\n\n tryRegister();\n // TronLink fires this event when the extension finishes injecting\n window.addEventListener(\"tronLink#initialized\", tryRegister, { once: true });\n\n // Short poll to catch TronLink loading slightly after the SDK\n const start = Date.now();\n const poll = setInterval(() => {\n tryRegister();\n if (registered || Date.now() - start > 3000) clearInterval(poll);\n }, 200);\n}\n","import type { Registry } from \"../core/registry\";\nimport type { BitcoinProvider } from \"../types\";\n\ndeclare global {\n interface Window {\n unisat?: BitcoinProvider;\n okxwallet?: { bitcoin?: BitcoinProvider };\n // Some wallets inject as BitcoinProvider\n BitcoinProvider?: BitcoinProvider;\n }\n}\n\n// Base64 SVG: orange circle with ₿\nconst BTC_ICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNGNzkzMUEiLz48dGV4dCB4PSIxNi41IiB5PSIyMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0id2hpdGUiIGZvbnQtZmFtaWx5PSJBcmlhbCxzeXN0ZW0tdWkiPuKmojwvdGV4dD48L3N2Zz4=\";\n\ninterface CandidateDef {\n name: string;\n rdns: string;\n provider: BitcoinProvider | null | undefined;\n}\n\nexport function startBitcoinDiscovery(registry: Registry): void {\n if (typeof window === \"undefined\") return;\n // Delay slightly so wallet extensions have time to inject\n setTimeout(() => {\n const candidates: CandidateDef[] = [\n { name: \"Unisat\", rdns: \"io.unisat.wallet\", provider: window.unisat },\n // OKX shares rdns with its EVM provider — merges into the EVM entry automatically\n { name: \"OKX Wallet\", rdns: \"com.okex.okxwallet\", provider: window.okxwallet?.bitcoin },\n ];\n\n for (const { name, rdns, provider } of candidates) {\n if (!provider) continue;\n registry.registerOrMerge({\n chain: \"bitcoin\",\n name,\n icon: BTC_ICON,\n rdns,\n provider,\n });\n }\n }, 150);\n}\n","import { createEmitter } from \"./core/emitter\";\nimport { createRegistry } from \"./core/registry\";\nimport { createSessionManager } from \"./core/session\";\nimport { createChainStore } from \"./core/chainStore\";\nimport { createRouter } from \"./core/router\";\nimport { createProvider } from \"./provider\";\nimport { startEvmDiscovery } from \"./evm/discovery\";\nimport { startSolanaDiscovery } from \"./solana/discovery\";\nimport { startTronDiscovery } from \"./tron/discovery\";\nimport { startBitcoinDiscovery } from \"./bitcoin/discovery\";\nimport { BUILT_IN_CHAINS } from \"./constants\";\nimport type { DecaneConfig, DecaneProvider } from \"./types\";\n\nexport function createDecane(config: DecaneConfig): DecaneProvider {\n if (!config?.appId) {\n throw new Error(\n \"decane-connect-kit: appId is required. Pass your dashboard project ID as config.appId.\",\n );\n }\n const emitter = createEmitter();\n const registry = createRegistry(emitter);\n const session = createSessionManager();\n const builtIn = config.supportedChainIds\n ? BUILT_IN_CHAINS.filter((c) => config.supportedChainIds!.includes(c.id))\n : BUILT_IN_CHAINS;\n\n const chainStore = createChainStore([\n ...builtIn,\n ...(config.chains ?? []),\n ]);\n const router = createRouter({ registry, session, chainStore });\n\n startEvmDiscovery(registry);\n startSolanaDiscovery(registry);\n startTronDiscovery(registry);\n startBitcoinDiscovery(registry);\n\n return createProvider({ config, registry, session, chainStore, router, emitter });\n}\n","import { Wallet, sha256, encodeBase58, type TransactionRequest } from \"ethers\";\nimport { Transaction, VersionedTransaction, Keypair } from \"@solana/web3.js\";\n\nimport type {\n DecaneConnect,\n DecaneConnectConfig,\n ConnectResult,\n SignMessageRequest,\n SendTransactionRequest,\n SignTypedDataRequest,\n AuthResult,\n WrappedShareMeta,\n TransactionRecord,\n RecordTransactionInput,\n} from \"./types\";\nimport {\n NewDeviceError,\n ProvisioningTimeoutError,\n UserCancelledError,\n InvalidPinError,\n ShareCorruptedError,\n CallSequenceError,\n PromptPinNotConfiguredError,\n ReconnectRequiredError,\n StaleDeviceShareError,\n} from \"./errors\";\nimport { EventEmitter } from \"./events\";\nimport { ApiClient } from \"./api\";\nimport { Storage, type StoredShare } from \"./storage\";\nimport { SessionManager } from \"./session\";\nimport { TeeClient, prewarmAttestation } from \"./teeClient\";\nimport {\n generateMaster,\n splitMaster,\n combineShares,\n generateRandomBytes,\n zeroize,\n} from \"./crypto/shares\";\nimport { importAesKey, aesGcmEncrypt, aesGcmDecrypt } from \"./crypto/wrap\";\nimport { deriveKeyFromPin, validatePin } from \"./crypto/pin\";\nimport { isPasskeySupported, getPrfOutput, authenticateWithPasskey } from \"./crypto/passkey\";\nimport { registerWebAuthnCredential } from \"./webauthnRegistration\";\nimport {\n startEmailAuth,\n verifyEmailCode as apiVerifyEmailCode,\n} from \"./auth/email\";\nimport { loginWithKingsChatPopup } from \"./auth/kingschat\";\nimport { signEvmMessage, signEvmTransaction, signEvmTypedData, signEvmAuthorization } from \"./signers/evm\";\nimport { createEthereumProvider } from \"./eip1193\";\nimport { signSolanaMessage, signSolanaTransaction } from \"./signers/solana\";\nimport { recoverDeviceShare } from \"./recovery/recoveryFlow\";\nimport { buildRecoveryShareFile, recoveryShareFileName, type RecoveryShareFile } from \"./recovery/recoveryShareFile\";\nimport { buildPortableBackup, portableBackupFileName, type PortableBackup } from \"./recovery/portableBackup\";\n\nconst DEFAULT_API_BASE = \"https://backend.decane.app\";\n// signer.decane.app is not wired up yet (no custom domain on the CVM) —\n// point directly at the Phala gateway URL until that's set up.\nconst DEFAULT_TEE_URL = \"https://4405742df08d19abc549a05ade2a7154d98bd87f-8443.dstack-pha-prod9.phala.network\";\n\n// 2 hours. Signing in every 30 minutes was poor UX. The session is still\n// clamped to whichever is sooner — this value, the JWT's exp, or the TEE\n// signer's SESSION_TTL_SECONDS — so this only takes full effect once the\n// signer's SESSION_TTL_SECONDS is raised to match (see below).\nconst DEFAULT_SESSION_MINUTES = 120;\n\n// DEFAULT_RPCS now lives in ./balance (single source of truth shared by the\n// client, the useSocialBalance hook, and the modal). Re-exported here so the\n// existing `import { DEFAULT_RPCS } from \"../social/client\"` call sites keep\n// working unchanged.\nexport { fetchBalance, formatBalanceDisplay } from \"./balance\";\nimport { fetchBalance as fetchBalanceImpl, DEFAULT_RPCS, type BalanceResult } from \"./balance\";\nexport { DEFAULT_RPCS };\n\ninterface AuthState {\n jwt: string;\n userId: string;\n addresses: { evm: string; solana: string; tron?: string };\n}\n\n// Persisted across reloads — no JWT (short-lived), just identity + addresses.\ninterface PersistedState {\n userId: string;\n addresses: { evm: string; solana: string; tron?: string };\n}\n\nfunction makePersistKey(apiKey: string) {\n return `decane:social:${apiKey.slice(0, 20)}`;\n}\n\nfunction loadPersisted(key: string): PersistedState | null {\n try {\n const raw = typeof localStorage !== 'undefined' ? localStorage.getItem(key) : null;\n return raw ? (JSON.parse(raw) as PersistedState) : null;\n } catch { return null; }\n}\n\nfunction savePersisted(key: string, state: PersistedState): void {\n try { localStorage.setItem(key, JSON.stringify(state)); } catch {}\n}\n\nfunction clearPersisted(key: string): void {\n try { localStorage.removeItem(key); } catch {}\n}\n\n// ── Resumable live session (sessionStorage) ──────────────────────────────────\n// Unlike the identity above (localStorage, addresses only), this holds the live\n// session — handle + JWT — so a page RELOAD can silently resume signing without\n// another passkey/sign-in. sessionStorage is deliberate: it survives reloads but\n// is cleared when the tab closes, so the session can't outlive the tab or be\n// read by other tabs. On tab close the leftover server session simply expires at\n// its TTL, unreachable (the handle is gone).\ninterface PersistedSession {\n handle: string;\n jwt: string;\n userId: string;\n addresses: { evm: string; solana: string; tron?: string };\n expiresAt: number;\n}\n\nfunction sessionPersistKey(apiKey: string) {\n return `decane:sess:${apiKey.slice(0, 20)}`;\n}\n\nfunction loadSession(key: string): PersistedSession | null {\n try {\n const raw = typeof sessionStorage !== \"undefined\" ? sessionStorage.getItem(key) : null;\n return raw ? (JSON.parse(raw) as PersistedSession) : null;\n } catch { return null; }\n}\n\nfunction saveSession(key: string, s: PersistedSession): void {\n try { sessionStorage.setItem(key, JSON.stringify(s)); } catch {}\n}\n\nfunction clearSessionPersist(key: string): void {\n try { sessionStorage.removeItem(key); } catch {}\n}\n\nexport async function createDecaneConnect(\n config: DecaneConnectConfig,\n): Promise<DecaneConnect> {\n if (!config.appId) throw new Error(\"decane-connect-kit: appId is required\");\n if (!config.apiKey) throw new Error(\"decane-connect-kit: apiKey is required\");\n if (!config.chains?.length)\n throw new Error(\"decane-connect-kit: at least one chain is required\");\n // Checked at construction, not when a device actually joins: rotation kills\n // the user's existing recovery file, and discovering there is nowhere to hand\n // them the replacement only at that point would leave them with a rotated set\n // and a dead file. Same reasoning as the Flow B guard in returningUserUnlock.\n if (config.rotateOnNewDeviceRecovery && !config.onRecoveryRotated) {\n throw new Error(\n \"decane-connect-kit: rotateOnNewDeviceRecovery requires an onRecoveryRotated callback — rotating on device join invalidates the user's existing recovery file, and the replacement must be saved.\",\n );\n }\n\n const baseUrl = config.apiBaseUrl ?? DEFAULT_API_BASE;\n const durationMs =\n (config.sessionDurationMinutes ?? DEFAULT_SESSION_MINUTES) * 60_000;\n const rpId =\n config.rpId ??\n (typeof window !== \"undefined\" ? window.location.hostname : \"localhost\");\n const rpName = config.rpName ?? \"Decane Connect\";\n\n const PERSIST_KEY = makePersistKey(config.apiKey);\n\n const teeUrl = config.teeUrl ?? DEFAULT_TEE_URL;\n\n const events = new EventEmitter();\n const api = new ApiClient(baseUrl, config.apiKey, config.appId);\n const storage = new Storage();\n const session = new SessionManager(\n events,\n durationMs,\n teeUrl,\n config.requireAssertionPerSignature === true\n );\n\n let auth: AuthState | null = null;\n // Addresses persisted across reloads — visible even before re-authentication.\n let persisted: PersistedState | null = loadPersisted(PERSIST_KEY);\n\n // Lazily-built, memoized EIP-1193 provider (wagmi/viem expect a stable ref).\n let ethProvider: ReturnType<typeof createEthereumProvider> | null = null;\n\n // Session persistence (sessionStorage) is on by default so a reload doesn't\n // force another passkey. Opt out with persistSession: false.\n const persistSession = config.persistSession !== false;\n // Always on. A wallet a person cannot re-enter after reinstalling is worse\n // than useless to them, so this is the product's behaviour rather than a\n // choice each integrator re-litigates. The trade it makes — the enclave can\n // reconstruct an enrolled wallet — is documented in the recovery guide.\n const serverAssistedRecovery = true;\n\n // How long to wait on the host app's recovery-share dialog before giving up\n // on it and finishing wallet creation anyway.\n //\n // The SDK awaits `onRecoveryShareOffer`, so a handler that never settles — a\n // modal that failed to mount, a promise the app forgot to resolve, a user who\n // walked away — used to hang signup indefinitely. It is not caught by the\n // try/catch around the call either: an unsettled promise is not an error.\n // Timing out is always the safer side of that trade. By the time this runs\n // the wallet is fully created, enrolled and persisted; the only thing skipped\n // is the offer of a recovery file, which the user can still generate later\n // via rotateShares(). Hanging, by contrast, strands them mid-signup.\n const RECOVERY_OFFER_TIMEOUT_MS = 5 * 60_000;\n\n // Wallets whose enrolment we have already tried to repair this page load.\n // The `enrolled === false` check below normally prevents repeats on its own,\n // but this also covers the case where enrolment keeps failing — one attempt\n // per user per load, well inside the enclave's 5-per-hour auth-share budget.\n const selfHealAttempted = new Set<string>();\n\n /**\n * Re-enrol a wallet that has a device share but no auth share.\n *\n * Enrolment runs once at wallet creation and, before 2.7.2, could be skipped\n * entirely if the user reloaded during the recovery-share prompt. Nothing ever\n * retried it, so those wallets are permanently unable to provision a new\n * device — `/signer/provision` answers 409 not_enrolled forever.\n *\n * `/signer/auth-share` validates the share it is given only by combining it\n * with the server share and checking the result derives the recorded\n * addresses. It does not care WHICH of the three shares it receives, and any\n * 2-of-3 reconstruct the master — so the device share we already hold is\n * sufficient to repair the wallet. The set returns to its intended shape on\n * the next provision or rotate, both of which re-seal a fresh recovery share.\n *\n * Runs in the background: the wallet is already usable by this point, and\n * blocking unlock on a repair would trade one hang for another. Takes\n * ownership of `share` and zeroizes it.\n */\n async function selfHealEnrolment(userId: string, jwt: string, share: Uint8Array): Promise<void> {\n try {\n if (selfHealAttempted.has(userId)) return;\n\n const status = await api.getRecoveryStatus(jwt);\n // Absent on backends older than this field. Unknown must not be treated as\n // \"not enrolled\", or every unlock against an old backend would re-enrol.\n if (status.enrolled !== false) return;\n\n selfHealAttempted.add(userId);\n await new TeeClient(teeUrl).enrolAuthShare(jwt, share);\n } catch (e) {\n events.emit(\"enrolment-failed\");\n console.warn(\n \"decane-connect-kit: this wallet is not enrolled for server-assisted recovery and \" +\n \"the automatic repair failed. It still works on this device, but a new device will \" +\n \"need a passkey backup or a recovery file. The SDK will try again on the next unlock.\",\n e,\n );\n } finally {\n zeroize(share);\n }\n }\n\n /**\n * Enrol a freshly created wallet for server-assisted provisioning.\n *\n * Runs off the critical path (see the call site) with one retry. Failure is\n * not fatal and not permanent — the unlock-time self-heal repairs it. Takes\n * ownership of `share`.\n */\n async function enrolInBackground(jwt: string, share: Uint8Array): Promise<void> {\n try {\n for (let attempt = 1; attempt <= 2; attempt++) {\n try {\n await new TeeClient(teeUrl).enrolAuthShare(jwt, share);\n return;\n } catch (e) {\n if (attempt === 2) {\n events.emit(\"enrolment-failed\");\n console.warn(\n \"decane-connect-kit: could not enrol this wallet for server-assisted recovery. \" +\n \"The wallet is fine and fully usable; it will be re-enrolled automatically on \" +\n \"the next unlock. Until then a brand-new device would need a passkey backup \" +\n \"or a recovery file.\",\n e,\n );\n }\n }\n }\n } finally {\n zeroize(share);\n }\n }\n\n // Hard ceiling on the SDK's own work during wallet creation.\n //\n // Covers key generation, share storage and opening the signer session — the\n // steps the SDK drives itself. Deliberately NOT the passkey/PIN prompt or the\n // recovery-file dialog: those wait on a human, and cutting a user off mid-PIN\n // would be worse than the hang this prevents. Individual requests are already\n // capped (30s in api.ts and teeClient.ts); this bounds the whole sequence, so\n // a run of slow-but-not-timing-out calls still cannot drag on indefinitely.\n const PROVISIONING_BUDGET_MS = 90_000;\n\n /** Rejects with ProvisioningTimeoutError if `promise` outlives `ms`. */\n function withDeadline<T>(promise: Promise<T>, ms: number, step: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout>;\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new ProvisioningTimeoutError(step)), Math.max(0, ms));\n }),\n ]).finally(() => clearTimeout(timer)) as Promise<T>;\n }\n\n /** Resolves to `null` if `promise` has not settled within `ms`. */\n function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T | null> {\n let timer: ReturnType<typeof setTimeout>;\n return Promise.race([\n promise,\n new Promise<null>((resolve) => {\n timer = setTimeout(() => resolve(null), ms);\n }),\n ]).finally(() => clearTimeout(timer)) as Promise<T | null>;\n }\n const SESSION_KEY = sessionPersistKey(config.apiKey);\n\n function persistLiveSession(): void {\n if (!persistSession) return;\n const handle = session.getHandle();\n const expiresAt = session.expiresAtTimestamp();\n if (!handle || !auth || !expiresAt) return;\n saveSession(SESSION_KEY, {\n handle, jwt: auth.jwt, userId: auth.userId, addresses: auth.addresses, expiresAt,\n });\n }\n\n function dropLiveSession(): void {\n clearSessionPersist(SESSION_KEY);\n }\n\n // Resume a still-live session from a previous page load — no prompt, no\n // network round trip. A 5s guard avoids adopting a handle about to expire.\n if (persistSession) {\n const saved = loadSession(SESSION_KEY);\n if (saved?.handle && saved.expiresAt > Date.now() + 5_000) {\n try {\n session.resume(saved.handle, saved.addresses, saved.expiresAt);\n auth = { jwt: saved.jwt, userId: saved.userId, addresses: saved.addresses };\n persisted = { userId: saved.userId, addresses: saved.addresses };\n } catch {\n dropLiveSession();\n }\n } else if (saved) {\n dropLiveSession();\n }\n }\n\n // Keep the persisted session in step with its real lifetime.\n events.on(\"session-expired\", () => dropLiveSession());\n\n // ── PIN setup helper ─────────────────────────────────────────────────────\n\n async function pinSetup(): Promise<{\n wrappingKey: CryptoKey;\n meta: Partial<WrappedShareMeta>;\n }> {\n if (!config.promptPin) throw new PromptPinNotConfiguredError();\n const pin = await config.promptPin();\n validatePin(pin);\n const pinSalt = generateRandomBytes(32);\n const wrappingKey = await deriveKeyFromPin(pin, pinSalt);\n return {\n wrappingKey,\n meta: {\n unlockMethod: \"pin\",\n pinSalt: bufferToB64u(pinSalt),\n pinIterations: 600_000,\n },\n };\n }\n\n // ── Wrapping-key derivation for returningUserUnlock's local-share path ────\n\n /**\n * Re-wrap and store a device share issued by a rotation.\n *\n * Every rotation (rotate, portable-export, recovery) invalidates the whole\n * share set server-side the moment it completes: the old device share can no\n * longer be combined with the new server share. If the replacement is not\n * written to storage, this device is left holding a share from a dead set and\n * the wallet is unusable from here — reconstruction silently yields a\n * different key, so it surfaces later as an unfunded address rather than as\n * an error. Persisting is therefore part of the rotation, not a follow-up to\n * it, and any failure has to propagate rather than be swallowed.\n *\n * The existing unlock method and its metadata are reused, so this re-prompts\n * for the same passkey or PIN already protecting the share rather than\n * establishing anything new.\n */\n async function persistRotatedDeviceShare(\n userId: string,\n deviceShare: Uint8Array,\n ): Promise<void> {\n const stored = await storage.getShare(userId);\n if (!stored) {\n // Nothing to re-wrap against (no passkey/PIN metadata on this device).\n // Rotating without being able to store the result is what strands a\n // wallet, so treat it as fatal rather than continuing.\n throw new CallSequenceError(\n \"Share set was rotated but this device has no stored share to update. Recover the wallet on this device before rotating.\",\n );\n }\n const wrappingKey = await getWrappingKey(stored);\n const iv = generateRandomBytes(12);\n const wrappedDeviceShare = await aesGcmEncrypt(wrappingKey, deviceShare, iv);\n await storage.putShare({ ...stored, wrappedDeviceShare, iv });\n }\n\n async function getWrappingKey(stored: StoredShare): Promise<CryptoKey> {\n if (stored.unlockMethod === \"passkey\") {\n const prfOutput = await getPrfOutput({\n rpId,\n credentialId: stored.credentialId!,\n prfSalt: stored.prfSalt!,\n });\n return importAesKey(prfOutput);\n }\n if (!config.promptPin) throw new PromptPinNotConfiguredError();\n const pin = await config.promptPin();\n return deriveKeyFromPin(pin, stored.pinSalt!);\n }\n\n // ── Post-recovery passkey provisioning ─────────────────────────────────────\n // After a Flow B (recovery-share file) recovery, this device has no\n // passkey yet. Best effort: register one and back it up so the *next* new\n // device recovers via the easy Flow A instead of needing a file again.\n // Never fails the recovery that already succeeded — every error is swallowed.\n\n async function registerPasskeyAndBackup(\n userId: string,\n jwt: string,\n deviceShare: Uint8Array,\n ): Promise<void> {\n if (!isPasskeySupported()) return;\n\n const prfSalt = generateRandomBytes(32);\n let credentialId: Uint8Array;\n let prfOutput: Uint8Array | undefined;\n try {\n const result = await registerWebAuthnCredential({ api, jwt, rpId, rpName, prfSalt });\n credentialId = result.credentialId;\n prfOutput = result.prfOutput;\n } catch (e) {\n console.warn('decane-connect-kit: passkey provisioning after recovery failed; user can set this up later.', e);\n return;\n }\n if (!prfOutput) return; // browser claimed support but returned no PRF — skip\n\n const wrappingKey = await importAesKey(prfOutput);\n const iv = generateRandomBytes(12);\n const wrappedDeviceShare = await aesGcmEncrypt(wrappingKey, deviceShare, iv);\n\n await storage.putShare({\n userId,\n wrappedDeviceShare,\n iv,\n unlockMethod: \"passkey\",\n credentialId,\n prfSalt,\n version: 1,\n });\n\n try {\n await api.putRecoveryBackup(jwt, {\n wrappedDeviceShare,\n iv,\n unlockMethod: \"passkey\",\n credentialId,\n prfSalt,\n });\n } catch (e) {\n console.warn('decane-connect-kit: wrapped share backup upload failed; user can retry from settings.', e);\n }\n }\n\n // ── First-time wallet setup (called when hasShare === false) ─────────────\n\n async function firstTimeSetup(\n userId: string,\n jwt: string,\n ): Promise<{ evm: string; solana: string }> {\n // Verifying the enclave means fetching a quote, pulling collateral from\n // Intel's PCS and running a WASM verifier — the slowest single step in\n // creation, and it depends on nothing we are about to compute. Start it now\n // so it runs while the user is at the passkey/PIN prompt and the key is\n // being generated; by the time the session opens it is usually already done.\n prewarmAttestation(teeUrl);\n\n let unlockMethod: \"passkey\" | \"pin\";\n let wrappingKey: CryptoKey;\n let meta: Partial<WrappedShareMeta> = {};\n\n if (isPasskeySupported()) {\n const prfSalt = generateRandomBytes(32);\n try {\n const { credentialId, prfOutput } = await registerWebAuthnCredential({ api, jwt, rpId, rpName, prfSalt });\n\n if (prfOutput) {\n unlockMethod = \"passkey\";\n wrappingKey = await importAesKey(prfOutput);\n meta = {\n unlockMethod: \"passkey\",\n credentialId: bufferToB64u(credentialId),\n prfSalt: bufferToB64u(prfSalt),\n };\n } else {\n // Browser claimed passkey support but didn't return PRF — fall back to PIN\n ({ wrappingKey, meta } = await pinSetup());\n unlockMethod = \"pin\";\n }\n } catch (e: unknown) {\n if ((e as Error).name === \"UserCancelledError\")\n throw new UserCancelledError();\n ({ wrappingKey, meta } = await pinSetup());\n unlockMethod = \"pin\";\n }\n } else {\n ({ wrappingKey, meta } = await pinSetup());\n unlockMethod = \"pin\";\n }\n\n // The unlock tier is settled (that step waits on the user); everything from\n // here to the open session is the SDK's own work and shares one budget.\n const provisioningStartedAt = Date.now();\n const remainingBudget = () => PROVISIONING_BUDGET_MS - (Date.now() - provisioningStartedAt);\n\n // Generate the master secret and split it into a 2-of-3 Shamir set —\n // device, server, recovery. Any two reconstruct; one alone reveals\n // nothing, which is what makes the recovery-share file safe to store\n // somewhere convenient (see recovery/recoveryShareFile.ts).\n const master = generateMaster();\n let shareSet: { device: Uint8Array; server: Uint8Array; recovery: Uint8Array; version: number };\n\n // Derive addresses from the raw master. This is one of the few permitted\n // browser-side uses of it — zeroized in the finally below, immediately\n // after use. The TEE never sees the master; it only ever reconstructs it\n // internally, momentarily, at signing/recovery/rotation time.\n let evmAddress: string;\n let solanaAddress: string;\n let tronAddress: string;\n try {\n evmAddress = new Wallet(toHex(master)).address;\n solanaAddress = Keypair.fromSeed(master).publicKey.toBase58();\n // Same secp256k1 key as EVM, re-encoded to the Tron \"T…\" address.\n tronAddress = evmToTronAddress(evmAddress);\n shareSet = await splitMaster(master, 1);\n } finally {\n zeroize(master);\n }\n\n // Wrap device share with wrapping key\n const iv = generateRandomBytes(12);\n const wrappedDeviceShare = await aesGcmEncrypt(\n wrappingKey,\n shareSet.device,\n iv,\n );\n\n // Store wrapped device share locally (IndexedDB)\n await storage.putShare({\n userId,\n wrappedDeviceShare,\n iv,\n unlockMethod,\n credentialId: meta.credentialId\n ? b64uToBuffer(meta.credentialId)\n : undefined,\n prfSalt: meta.prfSalt ? b64uToBuffer(meta.prfSalt) : undefined,\n pinSalt: meta.pinSalt ? b64uToBuffer(meta.pinSalt) : undefined,\n pinIterations: meta.pinIterations,\n version: 1,\n });\n\n // Send server share + addresses to backend\n const serverIv = generateRandomBytes(12);\n await withDeadline(api.putShare(jwt, {\n ciphertext: shareSet.server,\n iv: serverIv,\n wrappedShareMeta: {\n unlockMethod,\n // credential IDs, prfSalt, pinSalt stay on-device — never sent to server\n },\n evmAddress,\n solanaAddress,\n tronAddress,\n }), remainingBudget(), 'storing your wallet');\n zeroize(shareSet.server);\n\n const addresses = { evm: evmAddress, solana: solanaAddress, tron: tronAddress };\n\n // Back up the wrapped share for passkey-sync recovery (passkey users\n // only — a PIN doesn't sync across devices, so backing up a PIN-wrapped\n // share would be useless; a PIN-only user's sole recovery path is the\n // recovery-share file). Non-fatal: the user can back up later from settings.\n if (unlockMethod === \"passkey\" && meta.credentialId && meta.prfSalt) {\n try {\n await api.putRecoveryBackup(jwt, {\n wrappedDeviceShare,\n iv,\n unlockMethod: \"passkey\",\n credentialId: b64uToBuffer(meta.credentialId),\n prfSalt: b64uToBuffer(meta.prfSalt),\n });\n } catch (e) {\n console.warn('decane-connect-kit: wrapped share backup failed; user can retry from settings.', e);\n }\n }\n\n // Open the TEE session with the device share — not the reconstructed\n // key. The TEE fetches the server share itself and combines the two\n // internally, only for the duration of each sign call. It also derives\n // and returns the addresses of the key it reconstructed; here they must\n // match what we just derived locally, but we use its answer regardless so\n // there is exactly one authority on this in the codebase.\n const confirmed = await withDeadline(\n session.start(shareSet.device, jwt, addresses),\n remainingBudget(),\n 'opening the signing session',\n );\n zeroize(shareSet.device);\n\n if (confirmed.evm.toLowerCase() !== addresses.evm.toLowerCase()) {\n console.warn(\n `decane-connect-kit: signer derived a different EVM address (${confirmed.evm}) than this device did (${addresses.evm}) during setup. Using the signer's.`\n );\n }\n // Keep every downstream consumer on the confirmed values — including the\n // recovery-share file built below, whose embedded addresses must match the\n // key the file can actually reconstruct.\n addresses.evm = evmAddress = confirmed.evm;\n addresses.solana = solanaAddress = confirmed.solana;\n // Tron derives from the (now confirmed) EVM key — keep it in lockstep.\n addresses.tron = tronAddress = confirmed.tron ?? evmToTronAddress(confirmed.evm);\n\n // Enrol for server-assisted provisioning so this user can get back in on a\n // new device without a recovery file. Best effort — a failure leaves a good\n // wallet that simply needs the passkey/file path later.\n //\n // Deliberately BEFORE the recovery-share offer below: that offer awaits\n // user interaction (a modal where they choose and type a password) for an\n // unbounded time, and the JWT it shares expires in ~30 minutes. Enrolling\n // afterwards meant a user who paused on that dialog silently ended up\n // unenrolled — which only surfaces much later, on a new device, as a 409\n // from /signer/provision and a dead-end NewDeviceError.\n if (serverAssistedRecovery) {\n // NOT awaited. Enrolment is a network round-trip to the enclave (plus, on\n // a cold attestation cache, a DCAP verification), and awaiting it here\n // held the \"creating your wallet\" spinner open for the whole thing — up\n // to a minute when the enclave was slow, since each failed attempt was\n // also retried. The wallet is already complete and usable at this point;\n // the caller should not wait on a background durability step.\n //\n // Safe to defer only because 2.7.3 made enrolment self-healing: if this\n // is abandoned by a redirect, or fails outright, the next unlock detects\n // `enrolled: false` and repairs it. Before that existed, a missed\n // enrolment was permanent, which is why it used to run in the foreground.\n void enrolInBackground(jwt, new Uint8Array(shareSet.recovery));\n }\n\n // Offer to save the recovery share — DEFERRED, deliberately not awaited.\n //\n // By this point the wallet is finished: shares stored, session open,\n // enrolment done. The offer is post-creation UX that asks the user to\n // choose a password, so awaiting it here made connect() hang for as long as\n // the host app's modal took to settle — and forever if it never did. That\n // presented as a wallet that \"never finishes creating\", even though it had\n // been fully usable for some time; reloading and unlocking was instant,\n // because the wallet really was already there.\n //\n // Runs on a COPY of the recovery share: the original is zeroized below on\n // the critical path, and the copy is zeroized once the offer settles or its\n // deadline passes, so the extra exposure is bounded.\n if (config.offerRecoveryAtSignup === true && config.onRecoveryShareOffer) {\n void offerRecoveryShare(\n jwt,\n new Uint8Array(shareSet.recovery),\n { ...addresses },\n shareSet.version,\n evmAddress,\n solanaAddress,\n );\n }\n zeroize(shareSet.recovery);\n\n return addresses;\n }\n\n /**\n * Ask the user whether they want a recovery-share file, and build it if so.\n *\n * Split out of firstTimeSetup so it can run AFTER the wallet is returned to\n * the caller. Never throws: a declined, failed, or unresponsive offer must\n * leave the finished wallet alone. Takes ownership of `recoveryShare`.\n */\n async function offerRecoveryShare(\n jwt: string,\n recoveryShare: Uint8Array,\n addresses: { evm: string; solana: string; tron?: string },\n shareSetVersion: number,\n evmAddress: string,\n solanaAddress: string,\n ): Promise<void> {\n try {\n const choice = await withTimeout(\n config.onRecoveryShareOffer!({ evmAddress, solanaAddress }),\n RECOVERY_OFFER_TIMEOUT_MS,\n );\n if (!choice) {\n console.warn(\n \"decane-connect-kit: onRecoveryShareOffer did not settle within \" +\n `${RECOVERY_OFFER_TIMEOUT_MS / 60_000} minutes, so no recovery file was offered. ` +\n \"The wallet is unaffected — it was already created and enrolled — and the user can \" +\n \"generate a recovery share later via rotateShares(). Check that your handler \" +\n \"always resolves or rejects.\",\n );\n return;\n }\n if (!choice.wants) return;\n\n const file = await buildRecoveryShareFile(\n recoveryShare,\n choice.password,\n addresses,\n shareSetVersion,\n choice.passwordHint,\n );\n await config.onRecoveryFileReady?.(file, recoveryShareFileName(evmAddress));\n await api.markRecoveryShareSaved(jwt);\n } catch (e) {\n console.warn('decane-connect-kit: recovery share offer failed or was skipped.', e);\n } finally {\n zeroize(recoveryShare);\n }\n }\n\n // ── Returning-user unlock ────────────────────────────────────────────────\n\n async function returningUserUnlock(\n userId: string,\n jwt: string,\n ): Promise<{ evm: string; solana: string }> {\n // Treated as a *fallback*, not the truth: the signer derives the real\n // addresses from the key itself at session open and its answer wins (and\n // repairs this record). Missing addresses are therefore no longer fatal\n // here — the signer can supply them.\n const rawAddresses = await api.getAddresses(jwt);\n const recordedAddresses =\n rawAddresses.evm && rawAddresses.solana\n ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress(rawAddresses.evm) }\n : null;\n\n const stored = await storage.getShare(userId);\n\n let deviceShare: Uint8Array;\n // Tracks whether this share came from a passkey-sync recovery, i.e. it is a\n // copy of the backup every other synced device also holds. Under\n // rotateOnNewDeviceRecovery that has to be re-split once the session is\n // open, so this device ends up with a share nobody else has.\n let joinedViaPasskeySync = false;\n if (!stored) {\n // Checked BEFORE recovery starts, not inside the post-rotation callback.\n // Flow B rotates the whole set as part of recovering, which spends the\n // recovery file the user just supplied. Discovering only afterwards that\n // there is nowhere to hand them a replacement leaves them with a rotated\n // set and no way back — so refuse before the irreversible step instead.\n // ── Server-assisted provisioning (Flow S) ────────────────────────────\n // Tried FIRST: it is the only path needing nothing from the user. The\n // enclave holds two shares and issues this device a fresh one against the\n // JWT alone. Falls through when the wallet was never enrolled, so wallets\n // created before this existed keep working unchanged.\n if (serverAssistedRecovery) {\n try {\n const tee = new TeeClient(teeUrl);\n const provisioned = await tee.provisionDeviceShare(jwt);\n if (provisioned) {\n await registerPasskeyAndBackup(userId, jwt, provisioned).catch(() => {});\n let addrs: { evm: string; solana: string; tron?: string };\n try {\n addrs = await session.start(provisioned, jwt, recordedAddresses);\n } finally {\n zeroize(provisioned);\n }\n return addrs;\n }\n // null = HTTP 409 not_enrolled. Distinct from the catch below, and\n // worth saying out loud: this wallet holds no auth share, so the\n // enclave has one share of three and cannot mint a device share. The\n // user now needs a passkey backup or a recovery file, and without\n // either this ends in NewDeviceError.\n console.warn(\n \"decane-connect-kit: this wallet is not enrolled for server-assisted provisioning \" +\n \"(/signer/provision returned 409 not_enrolled), so a device share cannot be issued \" +\n \"from the JWT alone. Falling back to passkey sync, then the recovery file.\",\n );\n } catch (e) {\n // Never fatal: a provisioning outage must not lock out a user who\n // still holds a passkey or a recovery file.\n console.warn(\n \"decane-connect-kit: server-assisted provisioning unavailable; falling back to passkey/recovery-file recovery.\",\n e,\n );\n }\n }\n\n if (!config.onRecoveryRotated) {\n throw new CallSequenceError(\n \"Recovery rotates the share set and issues a new recovery file, but no onRecoveryRotated callback is configured to save it. Configure onRecoveryRotated before allowing recovery.\",\n );\n }\n // No local share — attempt recovery (Flow A passkey-sync, then Flow B\n // recovery-share file). Throws NewDeviceError if every path is exhausted.\n const recovered = await recoverDeviceShare({\n userId,\n jwt,\n rpId,\n teeUrl,\n api,\n storage,\n onProgress: config.onRecoveryProgress,\n promptForRecoveryFile: config.promptForRecoveryFile,\n onNewRecoveryShare: async (recoveryShare, shareSetVersion) => {\n // Every Flow B recovery rotates the whole set — the file the user\n // just used is dead now. This MUST get a new one saved; not\n // optional to skip, per MIGRATE_SSS_RECOVERY.md §10.\n // The absence of onRecoveryRotated is rejected before recovery\n // begins (see above), so it is guaranteed present here.\n if (!config.onRecoveryRotated) return;\n // Safe to use the recorded addresses here: /signer/recover only\n // returns a share set after confirming the reconstructed master\n // matches them, so reaching this callback proves they're correct.\n if (!recordedAddresses) return;\n const { password, passwordHint } = await config.onRecoveryRotated({ evmAddress: recordedAddresses.evm, solanaAddress: recordedAddresses.solana });\n const file = await buildRecoveryShareFile(recoveryShare, password, recordedAddresses, shareSetVersion, passwordHint);\n await config.onRecoveryFileReady?.(file, recoveryShareFileName(recordedAddresses.evm));\n await api.markRecoveryShareSaved(jwt);\n },\n });\n deviceShare = recovered.deviceShare;\n joinedViaPasskeySync = recovered.flow === 'passkey-sync';\n\n // If recovery went through Flow B (recovery-share file), there's still\n // no passkey on this device — provision one and back it up so the\n // *next* new device gets the easy Flow A instead of needing the file again.\n if (!(await storage.getShare(userId)) && isPasskeySupported()) {\n await registerPasskeyAndBackup(userId, jwt, deviceShare);\n }\n } else {\n const wrappingKey = await getWrappingKey(stored);\n try {\n deviceShare = await aesGcmDecrypt(\n wrappingKey,\n stored.wrappedDeviceShare,\n stored.iv,\n );\n } catch {\n throw stored.unlockMethod === \"pin\"\n ? new InvalidPinError()\n : new ShareCorruptedError();\n }\n }\n\n // The private key is never reconstructed here — the TEE fetches the\n // server share itself and combines it with the device share we send, and\n // returns the addresses that key actually controls. Those override the\n // recorded ones, which is what repairs an account whose users.evm_address\n // has drifted away from its key.\n let addresses: { evm: string; solana: string; tron?: string };\n try {\n addresses = await session.start(deviceShare, jwt, recordedAddresses);\n } catch (e) {\n // This device's share belongs to a superseded set — under\n // rotateOnNewDeviceRecovery that is the normal consequence of another\n // device joining, not a fault. Drop the dead share (and its useless\n // wrapping metadata) and recover a current one in its place, so the user\n // sees at most one extra passkey prompt instead of a hard failure.\n if (e instanceof StaleDeviceShareError) {\n zeroize(deviceShare);\n // Flow A caches the recovered share before the session is validated, so\n // a stale one has to be cleared here too — otherwise it is left behind\n // to fail again on the next connect().\n await storage.deleteShare(userId);\n // Only retry when the share came from local storage. If recovery just\n // produced a stale share, the synced backup itself is superseded and\n // retrying would recover the same dead bytes forever — surface it so\n // the user is routed to the recovery file instead.\n if (stored) return returningUserUnlock(userId, jwt);\n } else {\n zeroize(deviceShare);\n }\n throw e;\n }\n // Repair enrolment if this wallet never got an auth share (see\n // selfHealEnrolment). Deliberately not awaited: the wallet is already\n // usable, and the session we just opened is what the caller is waiting on.\n // Takes a COPY, because deviceShare is zeroized on the next line.\n void selfHealEnrolment(userId, jwt, new Uint8Array(deviceShare));\n zeroize(deviceShare);\n\n if (recordedAddresses && recordedAddresses.evm.toLowerCase() !== addresses.evm.toLowerCase()) {\n console.warn(\n `decane-connect-kit: recorded EVM address (${recordedAddresses.evm}) does not match the signing key (${addresses.evm}). Using the signing key's address; the record has been corrected.`\n );\n }\n\n // Per-device shares: this device joined by cloning the passkey-synced\n // backup, so right now it holds the same share as every other synced\n // device. Re-split so it gets one nobody else has — which is what makes a\n // later \"revoke that device\" possible at all. Deliberately AFTER the\n // session is open: rotation needs a live session, and a failure here must\n // leave a working wallet rather than a half-rotated one.\n if (joinedViaPasskeySync && config.rotateOnNewDeviceRecovery) {\n await rotateForNewDevice(userId, jwt);\n }\n\n return addresses;\n }\n\n /**\n * Re-split the share set so THIS device holds a unique share, invalidating\n * the copy every other passkey-synced device cached. Runs on a live session.\n *\n * Every surviving device now fails its next unlock with StaleDeviceShareError\n * and silently re-recovers — that is the intended cost of per-device\n * revocability, not a bug. The user's existing recovery FILE dies here too,\n * so the replacement must be handed back through onRecoveryRotated; that\n * callback's presence is validated at config time (see createDecaneConnect),\n * because discovering it missing at this point would strand the user with a\n * rotated set and a dead file.\n */\n async function rotateForNewDevice(userId: string, jwt: string): Promise<void> {\n const tee = session.requireActive();\n const result = await tee.rotateShares(jwt);\n try {\n // Must land before anything else can throw: the server has already\n // switched sets, so this device is unusable until the new share is stored.\n await persistRotatedDeviceShare(userId, result.deviceShare);\n\n // Refresh the synced backup too, or the next new device would recover the\n // now-dead share and immediately have to rotate again.\n const refreshed = await storage.getShare(userId);\n if (refreshed?.unlockMethod === \"passkey\" && refreshed.credentialId && refreshed.prfSalt) {\n await api\n .putRecoveryBackup(jwt, {\n wrappedDeviceShare: refreshed.wrappedDeviceShare,\n iv: refreshed.iv,\n unlockMethod: \"passkey\",\n credentialId: refreshed.credentialId,\n prfSalt: refreshed.prfSalt,\n })\n .catch((e) => {\n console.warn('decane-connect-kit: backup refresh after device rotation failed; the next new device will need the recovery file.', e);\n });\n }\n\n const addrs = await deriveAddressesFromShares(result.deviceShare, result.recoveryShare);\n const { password, passwordHint } = await config.onRecoveryRotated!({\n evmAddress: addrs.evm,\n solanaAddress: addrs.solana,\n });\n const file = await buildRecoveryShareFile(\n result.recoveryShare,\n password,\n addrs,\n result.shareSetVersion,\n passwordHint,\n );\n await config.onRecoveryFileReady?.(file, recoveryShareFileName(addrs.evm));\n await api.markRecoveryShareSaved(jwt);\n } finally {\n zeroize(result.deviceShare);\n zeroize(result.recoveryShare);\n }\n }\n\n // ── Passkey sign-in (returning user, same device) ────────────────────────\n\n /**\n * True when this device can sign the user straight back in with their\n * passkey, skipping Google/email entirely.\n *\n * Requires all three: a remembered identity, a passkey-wrapped share sitting\n * in IndexedDB, and platform support. A PIN-wrapped share doesn't qualify —\n * a PIN proves nothing to the backend, so those users still need the normal\n * flow to obtain a JWT.\n */\n async function passkeyLoginCandidate(): Promise<StoredShare | null> {\n if (!persisted?.userId || !isPasskeySupported()) return null;\n const stored = await storage.getShare(persisted.userId);\n if (!stored || stored.unlockMethod !== \"passkey\") return null;\n if (!stored.credentialId || !stored.prfSalt) return null;\n return stored;\n }\n\n async function passkeyLogin(stored: StoredShare): Promise<ConnectResult> {\n const userId = stored.userId;\n events.emit(\"wallet-unlocking\");\n\n const options = await api.getWebAuthnLoginOptions(userId, rpId);\n if (!options) {\n // No server-side credential — this wallet predates passkey sign-in, or\n // the registration never completed. Not an error, just not available.\n throw new NewDeviceError();\n }\n\n // One prompt, two outputs: the signed assertion authenticates, the PRF\n // output unwraps. See authenticateWithPasskey.\n const { response, prfOutput } = await authenticateWithPasskey({\n optionsJSON: options,\n prfSalt: stored.prfSalt!,\n });\n if (!prfOutput) throw new ShareCorruptedError();\n\n const result = await api.postWebAuthnLogin(userId, response, window.location.origin);\n\n let deviceShare: Uint8Array;\n try {\n deviceShare = await aesGcmDecrypt(\n await importAesKey(prfOutput),\n stored.wrappedDeviceShare,\n stored.iv,\n );\n } catch {\n throw new ShareCorruptedError();\n }\n\n const rawAddresses = await api.getAddresses(result.jwt);\n const recordedAddresses =\n rawAddresses.evm && rawAddresses.solana\n ? { evm: rawAddresses.evm, solana: rawAddresses.solana, tron: rawAddresses.tron ?? evmToTronAddress(rawAddresses.evm) }\n : null;\n\n const addresses = await session.start(deviceShare, result.jwt, recordedAddresses);\n zeroize(deviceShare);\n\n auth = { jwt: result.jwt, userId, addresses };\n persisted = { userId, addresses };\n savePersisted(PERSIST_KEY, persisted);\n events.emit(\"connected\");\n persistLiveSession();\n\n return { addresses, isNewUser: false };\n }\n\n // ── Shared post-auth flow ────────────────────────────────────────────────\n\n async function handleAuthResult(result: AuthResult): Promise<ConnectResult> {\n let addresses: { evm: string; solana: string };\n\n if (!result.hasShare) {\n // Multi-second flow: generate key, split shares, register passkey, open\n // TEE session. Signal it so the UI can show progress rather than freezing.\n events.emit(\"wallet-creating\");\n addresses = await firstTimeSetup(result.userId, result.jwt);\n } else {\n events.emit(\"wallet-unlocking\");\n addresses = await returningUserUnlock(result.userId, result.jwt);\n }\n\n auth = { jwt: result.jwt, userId: result.userId, addresses };\n persisted = { userId: result.userId, addresses };\n savePersisted(PERSIST_KEY, persisted);\n events.emit(\"connected\");\n persistLiveSession();\n\n return {\n addresses,\n isNewUser: result.isNewUser,\n ...(result.profile ? { profile: result.profile } : {}),\n };\n }\n\n // ── Public API ───────────────────────────────────────────────────────────\n\n const client: DecaneConnect = {\n async connect(): Promise<ConnectResult> {\n if (auth && session.isActive()) {\n return { addresses: auth.addresses, isNewUser: false };\n }\n\n // Returning user on a device that still holds their passkey-wrapped\n // share: their passkey is sufficient proof of identity, so don't send\n // them back through Google/email. A cancelled prompt propagates (they\n // chose to stop); anything else falls through to the normal flow so a\n // backend or authenticator problem can't lock them out of their wallet.\n const candidate = await passkeyLoginCandidate();\n if (candidate) {\n try {\n return await passkeyLogin(candidate);\n } catch (e: unknown) {\n if (e instanceof UserCancelledError) throw e;\n console.warn(\"decane-connect-kit: passkey sign-in unavailable, falling back to standard sign-in.\", e);\n }\n }\n\n const method = config.authMethods[0];\n if (!method) throw new CallSequenceError(\"No authMethods configured\");\n if (method === \"google\") return client.connectWithGoogle();\n if (method === \"kingschat\") return client.connectWithKingsChat();\n if (method === \"email\")\n throw new CallSequenceError(\n \"Use connectWithEmail(email) for email auth\",\n );\n throw new CallSequenceError(`Unknown auth method: ${method}`);\n },\n\n async connectWithGoogle(): Promise<ConnectResult> {\n const params = new URLSearchParams(window.location.search);\n const decaneJwt = params.get(\"decane_jwt\");\n const decaneError = params.get(\"decane_error\");\n\n if (decaneError) {\n // Clean params from URL\n window.history.replaceState({}, \"\", window.location.pathname);\n throw new CallSequenceError(`Google sign-in failed: ${decaneError}`);\n }\n\n if (decaneJwt) {\n // Backend already exchanged the code and redirected here with the result\n const name = params.get(\"decane_name\");\n const email = params.get(\"decane_email\");\n const picture = params.get(\"decane_picture\");\n const profile = {\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n ...(picture ? { picture } : {}),\n };\n const result = {\n jwt: decaneJwt,\n userId: params.get(\"decane_user_id\") ?? \"\",\n isNewUser: params.get(\"decane_is_new_user\") === \"true\",\n hasShare: params.get(\"decane_has_share\") === \"true\",\n // Omitted entirely when Google released nothing, so callers can test\n // `result.profile` rather than an object that is always present but\n // sometimes empty.\n ...(Object.keys(profile).length ? { profile } : {}),\n };\n // Clean all decane_* params from the URL\n window.history.replaceState({}, \"\", window.location.pathname);\n return handleAuthResult(result);\n }\n\n // No result yet — ask the backend for the Google consent URL and redirect there\n const { url } = await api.getGoogleInitUrl();\n window.location.href = url;\n // Promise never resolves — browser is navigating away\n return new Promise(() => {});\n },\n\n async connectWithGoogleToken(idToken: string): Promise<ConnectResult> {\n if (!idToken) throw new CallSequenceError(\"connectWithGoogleToken requires an ID token\");\n return handleAuthResult(await api.authGoogleToken(idToken));\n },\n\n async connectWithKingsChat(): Promise<ConnectResult> {\n // The clientId is fetched BEFORE the popup opens rather than inside\n // loginWithKingsChatPopup, so that window.open still runs inside the\n // user's click. Awaiting first and opening after is what popup blockers\n // reject — and the failure is silent, so it must not be possible here.\n const { clientId } = await api.getKingsChatConfig();\n const tokens = await loginWithKingsChatPopup({\n clientId,\n scopes: config.kingsChatScopes,\n });\n return client.connectWithKingsChatToken(tokens.accessToken);\n },\n\n async connectWithKingsChatToken(accessToken: string): Promise<ConnectResult> {\n if (!accessToken) {\n throw new CallSequenceError(\"connectWithKingsChatToken requires an access token\");\n }\n const result = await api.authKingsChat(accessToken);\n return handleAuthResult(result);\n },\n\n async connectWithToken(token: string, opts?: { providerId?: string }): Promise<ConnectResult> {\n if (!token) throw new CallSequenceError(\"connectWithToken requires a token\");\n const result = await api.authExternal(token, opts?.providerId);\n return handleAuthResult(result);\n },\n\n async connectWithEmail(email: string) {\n await startEmailAuth(api, email);\n return { codeRequired: true as const };\n },\n\n async verifyEmailCode(email: string, code: string): Promise<ConnectResult> {\n const result = await apiVerifyEmailCode(api, email, code);\n return handleAuthResult(result);\n },\n\n async canSignInWithPasskey(): Promise<boolean> {\n return (await passkeyLoginCandidate()) !== null;\n },\n\n async signInWithPasskey(): Promise<ConnectResult> {\n const candidate = await passkeyLoginCandidate();\n if (!candidate) throw new NewDeviceError();\n return passkeyLogin(candidate);\n },\n\n async unlock(): Promise<void> {\n // Session gone but the passkey is still here — re-authenticate with it\n // rather than raising ReconnectRequiredError and bouncing the user\n // through a sign-in they don't need.\n if (!auth) {\n const candidate = await passkeyLoginCandidate();\n if (candidate) {\n await passkeyLogin(candidate);\n return;\n }\n }\n if (!auth) {\n // Distinguish \"we know you, but your session is gone\" (the common\n // case after a reload) from \"you genuinely never connected\". Only the\n // former is recoverable, and only by re-authenticating — see\n // ReconnectRequiredError. Callers should check needsReconnect() first.\n throw persisted\n ? new ReconnectRequiredError()\n : new CallSequenceError(\"Not connected — call connect() first\");\n }\n if (session.isActive()) return;\n await returningUserUnlock(auth.userId, auth.jwt);\n },\n\n isUnlocked(): boolean {\n return session.isActive();\n },\n\n /**\n * True when we have a persisted identity but no live auth state, i.e.\n * unlock() cannot succeed and the user must sign in again. Exposed on the\n * client (not just the React context) so non-React consumers can branch on\n * it without having to catch ReconnectRequiredError.\n */\n needsReconnect(): boolean {\n return !auth && !!persisted;\n },\n\n sessionExpiresAt(): number | null {\n return session.expiresAtTimestamp();\n },\n\n async signMessage(req: SignMessageRequest): Promise<string> {\n const tee = session.requireActive();\n if (req.chain.startsWith(\"evm:\")) {\n return signEvmMessage(tee, req.chain, req.message as string, auth?.jwt);\n }\n if (req.chain.startsWith(\"solana:\")) {\n const msg =\n typeof req.message === \"string\"\n ? new TextEncoder().encode(req.message)\n : req.message;\n const sig = await signSolanaMessage(tee, req.chain, msg, auth?.jwt);\n return bufferToB64u(sig);\n }\n if (req.chain.startsWith(\"tron:\")) {\n // Tron message signing (TIP-191 / signMessageV2) is the same routine as\n // EVM personal_sign; the enclave applies the Ethereum prefix and signs.\n const msg =\n typeof req.message === \"string\"\n ? req.message\n : new TextDecoder().decode(req.message);\n return tee.sign({ chain: req.chain, kind: \"message\", payload: msg }, auth?.jwt);\n }\n throw new CallSequenceError(`Unsupported chain: ${req.chain}`);\n },\n\n async sendTransaction(req: SendTransactionRequest): Promise<string> {\n const tee = session.requireActive();\n if (!req.chain.startsWith(\"evm:\")) {\n throw new CallSequenceError(\n \"sendTransaction is EVM-only. Use signSolanaTransaction for Solana.\",\n );\n }\n if (!auth?.addresses.evm) {\n throw new CallSequenceError(\"Not connected\");\n }\n const evmAddr = auth.addresses.evm;\n\n const rpcUrl = config.rpcUrls?.[req.chain] ?? DEFAULT_RPCS[req.chain];\n if (!rpcUrl) {\n throw new CallSequenceError(\n `No RPC URL for ${req.chain}. Pass rpcUrls: { '${req.chain}': 'https://...' } in social config.`,\n );\n }\n\n // Dynamic import keeps JsonRpcProvider out of the SSR bundle\n const { JsonRpcProvider } = await import('ethers');\n const provider = new JsonRpcProvider(rpcUrl);\n const chainId = parseInt(req.chain.slice(4), 10);\n\n // Fetch nonce, gas estimate, and fee data in parallel\n const [nonce, feeData] = await Promise.all([\n provider.getTransactionCount(evmAddr, \"pending\"),\n provider.getFeeData(),\n ]);\n\n const gasLimit =\n req.gasLimit ??\n (await provider.estimateGas({\n from: evmAddr,\n to: req.to,\n value: req.value ?? 0n,\n data: req.data,\n }));\n\n const tx: TransactionRequest = {\n to: req.to,\n value: req.value ?? 0n,\n data: req.data,\n gasLimit,\n chainId,\n nonce,\n // EIP-1559 fees — fall back to legacy gasPrice if unavailable\n ...(feeData.maxFeePerGas != null\n ? {\n maxFeePerGas: feeData.maxFeePerGas,\n maxPriorityFeePerGas: feeData.maxPriorityFeePerGas ?? 0n,\n }\n : { gasPrice: req.gasPrice ?? feeData.gasPrice ?? undefined }),\n };\n\n // Signed by the TEE — the browser never holds the key.\n const signedTx = await signEvmTransaction(tee, req.chain, tx, auth?.jwt);\n const txResponse = await provider.broadcastTransaction(signedTx);\n\n // Record it in the user's history — best-effort, never blocks or fails the\n // send (the transaction is already broadcast; a history write is secondary).\n if (auth?.jwt) {\n void api\n .recordTransaction(auth.jwt, {\n chain: req.chain,\n txHash: txResponse.hash,\n to: req.to,\n value: (req.value ?? 0n).toString(),\n kind: \"send\",\n })\n .catch(() => {});\n }\n\n return txResponse.hash;\n },\n\n async signTypedData(req: SignTypedDataRequest): Promise<string> {\n const tee = session.requireActive();\n if (!req.chain.startsWith(\"evm:\")) {\n throw new CallSequenceError(\"signTypedData is EVM-only (EIP-712).\");\n }\n return signEvmTypedData(\n tee,\n req.chain,\n {\n domain: req.domain,\n types: req.types,\n message: req.message,\n primaryType: req.primaryType,\n },\n auth?.jwt,\n );\n },\n\n async signAuthorization(req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) {\n const tee = session.requireActive();\n const delegate = req.address ?? req.contractAddress;\n if (!delegate) throw new CallSequenceError(\"signAuthorization requires `address` (the delegate contract).\");\n return signEvmAuthorization(tee, req.chainId, delegate, req.nonce, auth?.jwt);\n },\n\n // The current session's access token (the Decane JWT), for authenticating\n // the user to your own backend — e.g. a sponsored-bundler proxy. Verify it\n // server-side against https://backend.decane.app/.well-known/jwks.json.\n // Null when there is no live session.\n getAccessToken(): string | null {\n return auth?.jwt ?? null;\n },\n\n async recordTransaction(tx: RecordTransactionInput): Promise<TransactionRecord> {\n if (!auth?.jwt) throw new CallSequenceError(\"Not connected — call connect() first\");\n return api.recordTransaction(auth.jwt, tx);\n },\n\n async getTransactionHistory(limit = 50): Promise<TransactionRecord[]> {\n if (!auth?.jwt) throw new CallSequenceError(\"Not connected — call connect() first\");\n return api.getTransactions(auth.jwt, limit);\n },\n\n getEthereumProvider(opts?: { chainId?: number }) {\n if (!ethProvider) {\n const firstEvm = config.chains.find((c) => c.startsWith(\"evm:\"));\n const defaultChainId = firstEvm ? parseInt(firstEvm.slice(4), 10) : 1;\n ethProvider = createEthereumProvider(client, {\n chainId: opts?.chainId ?? defaultChainId,\n rpcUrls: config.rpcUrls,\n });\n }\n return ethProvider;\n },\n\n async signSolanaTransaction(serializedTx: Uint8Array): Promise<Uint8Array> {\n const tee = session.requireActive();\n let tx: Transaction | VersionedTransaction;\n try {\n tx = VersionedTransaction.deserialize(serializedTx);\n } catch {\n tx = Transaction.from(serializedTx);\n }\n // The public API doesn't take a chain param here — use the first\n // configured Solana chain (mainnet/devnet), same as before.\n const solChain = config.chains.find((c) => c.startsWith(\"solana:\")) ?? \"solana:mainnet\";\n return signSolanaTransaction(tee, solChain, tx, auth?.jwt);\n },\n\n async signTronTransaction(rawDataHex: string): Promise<string> {\n const tee = session.requireActive();\n // The public API doesn't take a chain param — use the first configured\n // Tron chain, defaulting to mainnet. The enclave computes the txID\n // (sha256(raw_data)) and signs it with the same key as the EVM wallet.\n const tronChain = config.chains.find((c) => c.startsWith(\"tron:\")) ?? \"tron:mainnet\";\n return tee.sign(\n { chain: tronChain, kind: \"transaction\", payload: rawDataHex.replace(/^0x/, \"\") },\n auth?.jwt,\n );\n },\n\n async disconnect(): Promise<void> {\n session.end();\n if (auth?.jwt) {\n await api.revoke(auth.jwt).catch(() => {});\n }\n auth = null;\n persisted = null;\n clearPersisted(PERSIST_KEY);\n dropLiveSession();\n events.emit(\"disconnected\");\n },\n\n getAddresses() {\n return auth?.addresses ?? persisted?.addresses ?? null;\n },\n\n // Native-token balance. Read-only public chain data, so it works whenever an\n // address is known — including while the wallet is locked (no TEE session\n // needed). `chain` defaults to the first configured EVM chain, else the\n // first Solana chain.\n async getBalance(chain?: string): Promise<BalanceResult> {\n const addresses = auth?.addresses ?? persisted?.addresses;\n if (!addresses) throw new CallSequenceError(\"Not connected — no wallet address known\");\n\n const resolvedChain =\n chain ??\n config.chains.find((c) => c.startsWith(\"evm:\")) ??\n config.chains.find((c) => c.startsWith(\"solana:\"));\n if (!resolvedChain) throw new CallSequenceError(\"No chain configured\");\n\n const kind = resolvedChain.startsWith(\"solana:\") ? \"solana\" : \"evm\";\n const address = kind === \"evm\" ? addresses.evm : addresses.solana;\n if (!address) throw new CallSequenceError(`This wallet has no ${kind} address`);\n\n return fetchBalanceImpl({ kind, address, chain: resolvedChain, rpcUrls: config.rpcUrls });\n },\n\n // Balances across every configured chain the wallet has an address for.\n // Per-chain failures resolve to null rather than rejecting the whole call,\n // so one dead RPC doesn't blank the entire list.\n async getBalances(): Promise<Array<{ chain: string; balance: BalanceResult | null }>> {\n const addresses = auth?.addresses ?? persisted?.addresses;\n if (!addresses) throw new CallSequenceError(\"Not connected — no wallet address known\");\n\n const targets = config.chains.filter((c) => {\n const kind = c.startsWith(\"solana:\") ? \"solana\" : \"evm\";\n return kind === \"evm\" ? !!addresses.evm : !!addresses.solana;\n });\n\n return Promise.all(\n targets.map(async (chain) => {\n const kind = chain.startsWith(\"solana:\") ? \"solana\" : \"evm\";\n const address = (kind === \"evm\" ? addresses.evm : addresses.solana) as string;\n try {\n return { chain, balance: await fetchBalanceImpl({ kind, address, chain, rpcUrls: config.rpcUrls }) };\n } catch {\n return { chain, balance: null };\n }\n }),\n );\n },\n\n async rotateShares(opts: { password: string; passwordHint?: string }): Promise<RecoveryShareFile> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const tee = session.requireActive();\n const result = await tee.rotateShares(auth.jwt);\n try {\n // Must happen before anything else can fail: the server has already\n // switched to the new set, so this device is unusable until the\n // replacement share is stored.\n await persistRotatedDeviceShare(auth.userId, result.deviceShare);\n const addresses = await deriveAddressesFromShares(result.deviceShare, result.recoveryShare);\n const file = await buildRecoveryShareFile(\n result.recoveryShare,\n opts.password,\n addresses,\n result.shareSetVersion,\n opts.passwordHint\n );\n await api.markRecoveryShareSaved(auth.jwt);\n return file;\n } finally {\n zeroize(result.deviceShare);\n zeroize(result.recoveryShare);\n }\n },\n\n async exportPortableBackup(opts: { password: string; passwordHint?: string }): Promise<PortableBackup> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const tee = session.requireActive();\n const result = await tee.exportPortableBackup(auth.jwt);\n try {\n // Exporting rotates the share set server-side, so the same rule as\n // rotateShares() applies: store the replacement before doing anything\n // that could throw first.\n await persistRotatedDeviceShare(auth.userId, result.deviceShare);\n const addresses = await deriveAddressesFromShares(result.deviceShare, result.recoveryShare);\n return await buildPortableBackup(\n result.deviceShare,\n result.recoveryShare,\n opts.password,\n addresses,\n result.shareSetVersion,\n opts.passwordHint\n );\n } finally {\n zeroize(result.deviceShare);\n zeroize(result.recoveryShare);\n }\n },\n\n async hasRecoveryShare(): Promise<boolean> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const status = await api.getRecoveryStatus(auth.jwt);\n return status.hasRecoveryShare;\n },\n\n async shouldPromptRecovery(): Promise<boolean> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n const status = await api.getRecoveryStatus(auth.jwt);\n if (status.hasRecoveryShare || status.nagged) return false;\n\n // \"Holds a non-zero balance\" — check every chain type this wallet\n // actually has an address for, so the one-time nag only fires once\n // there's something real at stake, not on an empty new wallet.\n try {\n const checks: Promise<boolean>[] = [];\n if (auth.addresses.evm) {\n const { JsonRpcProvider } = await import(\"ethers\");\n for (const chain of config.chains.filter((c) => c.startsWith(\"evm:\"))) {\n const rpcUrl = config.rpcUrls?.[chain] ?? DEFAULT_RPCS[chain];\n if (!rpcUrl) continue;\n checks.push(\n new JsonRpcProvider(rpcUrl)\n .getBalance(auth.addresses.evm)\n .then((b) => b > 0n)\n .catch(() => false)\n );\n }\n }\n if (auth.addresses.solana && config.chains.some((c) => c.startsWith(\"solana:\"))) {\n const { Connection, PublicKey } = await import(\"@solana/web3.js\");\n const solChain = config.chains.find((c) => c.startsWith(\"solana:\")) ?? \"solana:mainnet\";\n const cluster = solChain.slice(\"solana:\".length);\n const endpoint = cluster === \"devnet\" ? \"https://api.devnet.solana.com\" : \"https://api.mainnet-beta.solana.com\";\n checks.push(\n new Connection(endpoint)\n .getBalance(new PublicKey(auth.addresses.solana))\n .then((b) => b > 0)\n .catch(() => false)\n );\n }\n const results = await Promise.all(checks);\n return results.some(Boolean);\n } catch {\n // Fail closed on annoyance, not on safety — if balance-checking\n // itself breaks, don't nag rather than risk nagging incorrectly.\n return false;\n }\n },\n\n async dismissRecoveryPrompt(): Promise<void> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n await api.dismissRecoveryNag(auth.jwt);\n },\n\n async hasBackup(): Promise<boolean> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n return api.hasRecoveryBackup(auth.jwt);\n },\n\n async deleteBackup(): Promise<void> {\n if (!auth) throw new CallSequenceError(\"Not connected — call connect() first\");\n await api.deleteRecoveryBackup(auth.jwt);\n },\n\n on: events.on.bind(events),\n off: events.off.bind(events),\n };\n\n return client;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction bufferToB64u(buf: Uint8Array): string {\n return btoa(String.fromCharCode(...buf))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n\nfunction b64uToBuffer(b64u: string): Uint8Array {\n const b64 = b64u.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n}\n\nfunction toHex(bytes: Uint8Array): string {\n return \"0x\" + Array.from(bytes).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n// A Tron account is derived from the SAME secp256k1 key as the EVM wallet — the\n// address is just a re-encoding of the EVM address: prepend the 0x41 Tron\n// mainnet prefix, append a double-SHA256 checksum, Base58-encode. No new key.\nfunction evmToTronAddress(evmAddress: string): string {\n const hex41 = \"41\" + evmAddress.toLowerCase().replace(/^0x/, \"\");\n const checksum = sha256(sha256(\"0x\" + hex41)).slice(2, 10);\n return encodeBase58(\"0x\" + hex41 + checksum);\n}\n\n/**\n * Derive the real EVM/Solana addresses from two shares by momentarily\n * reconstructing the master. Used when building a recovery-share file or\n * portable backup: the browser already holds both shares in plaintext at\n * that moment (they're being written to a file), so this adds no new\n * exposure — but it guarantees the file's plaintext `addresses` field is\n * always correct by construction, rather than trusting a separately\n * tracked value (e.g. auth.addresses) that could go stale if some other\n * code path — server-side or client-side — ever desyncs from the real\n * current key. The master is zeroized immediately after use.\n */\nasync function deriveAddressesFromShares(\n a: Uint8Array,\n b: Uint8Array,\n): Promise<{ evm: string; solana: string; tron: string }> {\n const master = await combineShares(a, b);\n try {\n const evm = new Wallet(toHex(master)).address;\n return {\n evm,\n solana: Keypair.fromSeed(master).publicKey.toBase58(),\n tron: evmToTronAddress(evm),\n };\n } finally {\n zeroize(master);\n }\n}\n","import type { SdkEvent } from './types';\n\ntype Handler = (...args: unknown[]) => void;\n\nexport class EventEmitter {\n private _listeners = new Map<string, Set<Handler>>();\n\n emit(event: SdkEvent, ...args: unknown[]): void {\n this._listeners.get(event)?.forEach(h => h(...args));\n }\n\n on(event: SdkEvent, handler: Handler): void {\n if (!this._listeners.has(event)) this._listeners.set(event, new Set());\n this._listeners.get(event)!.add(handler);\n }\n\n off(event: SdkEvent, handler: Handler): void {\n this._listeners.get(event)?.delete(handler);\n }\n}\n","import { NetworkError, InvalidApiKeyError, OriginNotAllowedError, ReconnectRequiredError } from './errors';\nimport type { AuthResult, WrappedShareMeta, TransactionRecord } from './types';\n\nconst ERROR_MAP: Record<string, new (...args: never[]) => Error> = {\n INVALID_API_KEY: InvalidApiKeyError,\n ORIGIN_NOT_ALLOWED: OriginNotAllowedError,\n // The backend's authMiddleware code for an expired/revoked JWT. Surfacing it\n // as ReconnectRequiredError routes callers to the sign-in UI instead of a\n // generic failure message.\n UNAUTHORIZED: ReconnectRequiredError,\n};\n\n// Ceiling on any single backend call. Generous enough that a slow mobile\n// connection still completes, short enough that a dead connection surfaces as a\n// retryable error instead of an indefinite hang inside signup or unlock.\nconst REQUEST_TIMEOUT_MS = 30_000;\n\nexport class ApiClient {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly appId: string,\n ) {}\n\n private async _request<T>(path: string, init?: RequestInit): Promise<T>;\n private async _request<T>(path: string, init: RequestInit & { allow404: true }): Promise<T | null>;\n private async _request<T>(path: string, init?: RequestInit & { allow404?: boolean }): Promise<T | null> {\n let res: Response;\n // fetch() has no default timeout, so without this a stalled connection hangs\n // the caller forever. That is not hypothetical here: these calls sit inside\n // wallet creation and unlock, where a hang strands the user mid-flow with no\n // error and no way forward. An abort surfaces as NetworkError, which callers\n // already handle and which is marked retryable.\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n ...init,\n signal: controller.signal,\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': this.apiKey,\n 'X-App-Id': this.appId,\n ...init?.headers,\n },\n });\n } catch {\n throw new NetworkError();\n } finally {\n clearTimeout(timer);\n }\n\n if (res.status === 404 && init?.allow404) return null;\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({})) as { error?: { code?: string; message?: string } };\n const code = body?.error?.code ?? 'UNKNOWN';\n const msg = body?.error?.message ?? `Request failed: ${res.status}`;\n const Ctor = ERROR_MAP[code];\n if (Ctor) throw new (Ctor as new (msg: string) => Error)(msg);\n throw new Error(msg);\n }\n\n return res.json() as Promise<T>;\n }\n\n async getGoogleInitUrl(): Promise<{ url: string }> {\n return this._request('/auth/google/init', { method: 'GET' });\n }\n\n\n /**\n * Exchange a Google ID token the app already holds for a Decane session.\n * Resolves to the SAME identity as the redirect flow, so one Google account\n * means one wallet across web and mobile.\n */\n async authGoogleToken(idToken: string): Promise<AuthResult> {\n return this._request('/auth/google/token', {\n method: 'POST',\n body: JSON.stringify({ idToken }),\n });\n }\n\n /** The project's KingsChat clientId, so the dApp never has to hardcode it. */\n async getKingsChatConfig(): Promise<{ clientId: string; authorizationUrl: string }> {\n return this._request('/auth/kingschat/config', { method: 'GET' });\n }\n\n /**\n * Exchange a KingsChat access token for a Decane session. The backend spends\n * the token against KingsChat's own API to establish the identity — it is\n * never trusted on its face, and never stored.\n */\n async authKingsChat(accessToken: string): Promise<AuthResult> {\n return this._request('/auth/kingschat', {\n method: 'POST',\n body: JSON.stringify({ accessToken }),\n });\n }\n\n async authEmailStart(email: string): Promise<void> {\n await this._request('/auth/email/start', {\n method: 'POST',\n body: JSON.stringify({ email }),\n });\n }\n\n async authEmailVerify(email: string, code: string): Promise<AuthResult> {\n return this._request('/auth/email/verify', {\n method: 'POST',\n body: JSON.stringify({ email, code }),\n });\n }\n\n // GET /share (the server share itself) was removed as part of the TEE\n // migration — the browser must never reconstruct the private key anymore.\n // Only public addresses are fetched from the backend now.\n async getAddresses(jwt: string): Promise<{ evm: string | null; solana: string | null; tron: string | null }> {\n return this._request('/share/addresses', {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async putShare(jwt: string, share: {\n ciphertext: Uint8Array;\n iv: Uint8Array;\n wrappedShareMeta: WrappedShareMeta;\n evmAddress: string;\n solanaAddress: string;\n tronAddress: string;\n }): Promise<void> {\n await this._request('/share', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify({\n ciphertext: bytesToB64(share.ciphertext),\n iv: bytesToB64(share.iv),\n wrappedShareMeta: btoa(JSON.stringify(share.wrappedShareMeta)),\n evmAddress: share.evmAddress,\n solanaAddress: share.solanaAddress,\n tronAddress: share.tronAddress,\n }),\n });\n }\n\n // ── Transaction history ───────────────────────────────────────────────────\n\n async recordTransaction(jwt: string, tx: {\n chain: string;\n txHash?: string;\n to?: string;\n value?: string;\n kind?: string;\n status?: string;\n metadata?: Record<string, unknown>;\n }): Promise<TransactionRecord> {\n const body = await this._request('/transactions', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify(tx),\n }) as { transaction: TransactionRecord };\n return body.transaction;\n }\n\n async getTransactions(jwt: string, limit = 50): Promise<TransactionRecord[]> {\n const body = await this._request(`/transactions?limit=${encodeURIComponent(String(limit))}`, {\n headers: { Authorization: `Bearer ${jwt}` },\n }) as { transactions: TransactionRecord[] };\n return body.transactions;\n }\n\n // ── WebAuthn registration (additive to the PRF-only passkey flow) ─────────\n\n async getWebAuthnRegisterOptions(jwt: string, rpId: string, rpName: string): Promise<import('@simplewebauthn/browser').PublicKeyCredentialCreationOptionsJSON> {\n return this._request(`/webauthn/register-options?rpId=${encodeURIComponent(rpId)}&rpName=${encodeURIComponent(rpName)}`, {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async postWebAuthnRegister(\n jwt: string,\n response: import('@simplewebauthn/browser').RegistrationResponseJSON,\n origin: string\n ): Promise<void> {\n await this._request('/webauthn/register', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify({ response, origin }),\n });\n }\n\n /**\n * Exchange a token from the developer's own auth system for a Decane\n * session. `providerId` is only needed when the project has more than one\n * provider configured.\n */\n async authExternal(token: string, providerId?: string): Promise<AuthResult> {\n return this._request('/auth/external', {\n method: 'POST',\n body: JSON.stringify(providerId ? { token, providerId } : { token }),\n });\n }\n\n /**\n * Returns null when this user has no server-registered passkey, which is the\n * expected answer for wallets created before passkey sign-in existed or for\n * PIN-only users — the caller falls back to the normal sign-in flow.\n */\n async getWebAuthnLoginOptions(\n userId: string,\n rpId: string\n ): Promise<import('@simplewebauthn/browser').PublicKeyCredentialRequestOptionsJSON | null> {\n return this._request('/webauthn/login-options', {\n method: 'POST',\n body: JSON.stringify({ userId, rpId }),\n allow404: true,\n });\n }\n\n async postWebAuthnLogin(\n userId: string,\n response: import('@simplewebauthn/browser').AuthenticationResponseJSON,\n origin: string\n ): Promise<AuthResult> {\n return this._request('/webauthn/login', {\n method: 'POST',\n body: JSON.stringify({ userId, response, origin }),\n });\n }\n\n async revoke(jwt: string): Promise<void> {\n await this._request('/auth/revoke', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n // ── Recovery (passkey-sync backup + recovery-share-saved flag) ────────────\n\n async hasRecoveryBackup(jwt: string): Promise<boolean> {\n const data = await this._request<{ exists: boolean }>('/recovery/backup/exists', {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n return data.exists;\n }\n\n async getRecoveryBackup(jwt: string): Promise<{\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey';\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n formatVersion: number;\n } | null> {\n const data = await this._request<{\n wrappedDeviceShare: string;\n iv: string;\n unlockMethod: 'passkey';\n credentialId: string;\n prfSalt: string;\n formatVersion: number;\n }>('/recovery/backup', {\n headers: { Authorization: `Bearer ${jwt}` },\n allow404: true,\n });\n if (!data) return null;\n return {\n wrappedDeviceShare: b64ToBytes(data.wrappedDeviceShare),\n iv: b64ToBytes(data.iv),\n unlockMethod: data.unlockMethod,\n credentialId: b64ToBytes(data.credentialId),\n prfSalt: b64ToBytes(data.prfSalt),\n formatVersion: data.formatVersion,\n };\n }\n\n async putRecoveryBackup(jwt: string, backup: {\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey';\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n }): Promise<void> {\n await this._request('/recovery/backup', {\n method: 'PUT',\n headers: { Authorization: `Bearer ${jwt}` },\n body: JSON.stringify({\n wrappedDeviceShare: bytesToB64(backup.wrappedDeviceShare),\n iv: bytesToB64(backup.iv),\n unlockMethod: backup.unlockMethod,\n credentialId: bytesToB64(backup.credentialId),\n prfSalt: bytesToB64(backup.prfSalt),\n }),\n });\n }\n\n async deleteRecoveryBackup(jwt: string): Promise<void> {\n await this._request('/recovery/backup', {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async markRecoveryShareSaved(jwt: string): Promise<void> {\n await this._request('/recovery/share-saved', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async getRecoveryStatus(jwt: string): Promise<{\n hasRecoveryShare: boolean;\n savedAt: string | null;\n nagged: boolean;\n shareSetVersion: number;\n /**\n * Whether this wallet is enrolled for server-assisted provisioning, i.e.\n * whether a new device can be given a device share from login alone.\n * Optional because backends older than this field simply omit it — treat\n * `undefined` as \"unknown\", never as \"not enrolled\".\n */\n enrolled?: boolean;\n }> {\n return this._request('/recovery/status', {\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n\n async dismissRecoveryNag(jwt: string): Promise<void> {\n await this._request('/recovery/nag-dismissed', {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}` },\n });\n }\n}\n\nfunction bytesToB64(bytes: Uint8Array): string {\n return btoa(String.fromCharCode(...bytes));\n}\n\nfunction b64ToBytes(b64: string): Uint8Array {\n return Uint8Array.from(atob(b64), c => c.charCodeAt(0));\n}\n","import { openDB, type IDBPDatabase } from 'idb';\n\nexport interface StoredShare {\n userId: string;\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey' | 'pin';\n credentialId?: Uint8Array;\n prfSalt?: Uint8Array;\n pinSalt?: Uint8Array;\n pinIterations?: number;\n version: number;\n}\n\nconst DB_NAME = 'decane-connect-kit';\nconst STORE = 'shares';\n\nexport class Storage {\n private _db: Promise<IDBPDatabase>;\n\n constructor() {\n this._db = openDB(DB_NAME, 1, {\n upgrade(db) {\n db.createObjectStore(STORE, { keyPath: 'userId' });\n },\n });\n }\n\n async getShare(userId: string): Promise<StoredShare | null> {\n return ((await this._db).get(STORE, userId)) ?? null;\n }\n\n async putShare(share: StoredShare): Promise<void> {\n await (await this._db).put(STORE, share);\n }\n\n async deleteShare(userId: string): Promise<void> {\n await (await this._db).delete(STORE, userId);\n }\n}\n","import { sha256, encodeBase58 } from 'ethers';\nimport { TeeClient } from './teeClient';\nimport { EventEmitter } from './events';\nimport { UnlockRequiredError } from './errors';\n\n// Tron shares the EVM secp256k1 key — its address is the EVM address re-encoded:\n// 0x41 prefix + double-SHA256 checksum, Base58. See client.ts for the full note.\nfunction evmToTronAddress(evmAddress: string): string {\n const hex41 = '41' + evmAddress.toLowerCase().replace(/^0x/, '');\n const checksum = sha256(sha256('0x' + hex41)).slice(2, 10);\n return encodeBase58('0x' + hex41 + checksum);\n}\n\nexport class SessionManager {\n private tee: TeeClient | null = null;\n private evmAddress: string | null = null;\n private solanaAddress: string | null = null;\n private tronAddress: string | null = null;\n private expiresAt: number | null = null;\n private timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private events: EventEmitter,\n private durationMs: number,\n private teeUrl: string,\n private requireAssertionPerSignature = false\n ) {\n // NOTE: we deliberately do NOT close the session on pagehide anymore. Doing\n // so killed the server session on every reload, forcing a fresh sign-in each\n // time — terrible UX on flaky networks. The session now survives a reload so\n // it can be resumed from sessionStorage (see the client's persistence). On a\n // real tab close, sessionStorage is cleared, so the lingering server session\n // is unreachable and simply expires at its TTL — no security loss, since the\n // client holds no key material (the TEE does) and the handle is gone.\n }\n\n private setExpiryTimer(effectiveMs: number): void {\n if (this.timeoutId) clearTimeout(this.timeoutId);\n this.timeoutId = setTimeout(() => {\n this.end();\n this.events.emit('session-expired');\n }, Math.max(0, effectiveMs));\n }\n\n /** The live session handle, for persisting a resumable session across reloads. */\n getHandle(): string | null {\n return this.tee?.getHandle() ?? null;\n }\n\n /**\n * Resume a persisted session without re-authenticating: adopt the handle,\n * addresses, and expiry from storage. No key material or prompt involved — the\n * TEE still holds the shares behind this handle. If the handle turns out to be\n * dead (server restarted, TTL passed), the next sign() fails and the caller\n * reconnects; nothing here can sign on its own.\n */\n resume(handle: string, addresses: { evm: string; solana: string; tron?: string }, expiresAtMs: number): void {\n this.tee = new TeeClient(this.teeUrl);\n this.tee.adoptHandle(handle, this.requireAssertionPerSignature);\n this.evmAddress = addresses.evm;\n this.solanaAddress = addresses.solana;\n this.tronAddress = addresses.tron ?? evmToTronAddress(addresses.evm);\n this.expiresAt = expiresAtMs;\n this.setExpiryTimer(expiresAtMs - Date.now());\n this.events.emit('session-started');\n }\n\n /**\n * Opens the TEE session and resolves which addresses this wallet really has.\n *\n * `fallback` is whatever the backend recorded; the TEE's answer is derived\n * from the signing key itself and therefore outranks it. Returns the\n * resolved addresses so callers can propagate the corrected values rather\n * than continuing to use a stale record.\n */\n async start(\n deviceShare: Uint8Array,\n jwt: string,\n fallback: { evm: string; solana: string; tron?: string } | null\n ): Promise<{ evm: string; solana: string; tron: string }> {\n this.tee = new TeeClient(this.teeUrl);\n const verified = await this.tee.openSession(\n deviceShare,\n jwt,\n this.requireAssertionPerSignature\n );\n\n // Fail rather than silently downgrade. If the caller asked for a prompt on\n // every signature and the signer won't honour it (older build), signing\n // anyway would give them the smooth UX and none of the guarantee, which is\n // the one outcome nobody asked for.\n if (this.requireAssertionPerSignature && !this.tee.requiresAssertionPerSignature()) {\n void this.tee.closeSession();\n this.tee = null;\n throw new Error(\n 'requireAssertionPerSignature was requested but this signer does not support it — ' +\n 'refusing to open a session with weaker authority than configured.'\n );\n }\n\n const resolved = verified ?? fallback;\n if (!resolved) {\n this.tee = null;\n throw new Error(\n 'No addresses available for this wallet — the signer could not derive them and none are recorded'\n );\n }\n\n // Tron shares the EVM key, so derive it from the resolved EVM address when\n // the signer (older build) didn't return one.\n const addresses = { evm: resolved.evm, solana: resolved.solana, tron: resolved.tron ?? evmToTronAddress(resolved.evm) };\n\n this.evmAddress = addresses.evm;\n this.solanaAddress = addresses.solana;\n this.tronAddress = addresses.tron;\n\n // Honour whichever expiry is sooner: our configured duration, or the\n // lifetime the signer actually granted (it clamps to the JWT's exp, so it\n // can be shorter). Counting down past the signer's session would leave the\n // UI showing time the handle no longer has, and signing would fail while\n // the clock still read green.\n const serverTtlMs = this.tee.sessionExpiresIn();\n const effectiveMs =\n serverTtlMs != null ? Math.min(this.durationMs, serverTtlMs * 1000) : this.durationMs;\n this.expiresAt = Date.now() + effectiveMs;\n\n if (this.timeoutId) clearTimeout(this.timeoutId);\n this.timeoutId = setTimeout(() => {\n this.end();\n this.events.emit('session-expired');\n }, effectiveMs);\n\n this.events.emit('session-started');\n return addresses;\n }\n\n end(): void {\n void this.tee?.closeSession();\n this.tee = null;\n this.evmAddress = null;\n this.solanaAddress = null;\n this.tronAddress = null;\n this.expiresAt = null;\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n\n isActive(): boolean {\n return this.tee !== null && Date.now() < (this.expiresAt ?? 0);\n }\n\n expiresAtTimestamp(): number | null {\n return this.expiresAt;\n }\n\n requireActive(): TeeClient {\n if (!this.isActive()) throw new UnlockRequiredError();\n return this.tee!;\n }\n\n addresses(): { evm: string; solana: string; tron: string } | null {\n if (!this.evmAddress || !this.solanaAddress) return null;\n return {\n evm: this.evmAddress,\n solana: this.solanaAddress,\n tron: this.tronAddress ?? evmToTronAddress(this.evmAddress),\n };\n }\n}\n","import { startAuthentication } from '@simplewebauthn/browser';\nimport type { AuthenticationResponseJSON } from '@simplewebauthn/browser';\nimport { verifyTeeAttestation } from './attestation';\nimport { SessionExpiredError, ExportNotAuthorizedError, ReconnectRequiredError } from './errors';\n\nfunction bytesToBase64(b: Uint8Array): string {\n let s = '';\n for (const byte of b) s += String.fromCharCode(byte);\n return btoa(s);\n}\nfunction base64ToBytes(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\n\n// Every enclave call is bounded. fetch() has no default timeout, so without this\n// a stalled connection to the TEE hangs wallet creation or unlock indefinitely —\n// the SDK would sit forever with no error and no way forward. An abort surfaces\n// as a normal request failure, which each caller already handles.\nconst TEE_TIMEOUT_MS = 30_000;\n\nasync function teeFetch(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), TEE_TIMEOUT_MS);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\n// Attestation is cached per enclave URL, not per client instance.\n//\n// A fresh TeeClient is constructed for every session open, enrolment and\n// provisioning call, and ensureAttested() previously ran a full DCAP\n// verification for each one — fetching a quote, pulling collateral from Intel's\n// PCS, and running the WASM verifier. Wallet creation alone did that at least\n// twice, back to back, for the same enclave. It is the slowest thing on the\n// critical path and the answer cannot differ between two calls seconds apart.\n//\n// The promise is cached (not just the result) so concurrent callers share one\n// in-flight verification instead of racing several. A TTL bounds how stale the\n// proof can get: long enough to cover a whole create/unlock flow, short enough\n// that a swapped CVM is re-detected within minutes. A failed verification is\n// evicted immediately so the next call retries rather than caching a rejection.\nconst ATTESTATION_TTL_MS = 10 * 60_000;\nconst attestationCache = new Map<string, { at: number; promise: Promise<void> }>();\n\nfunction attestOnce(teeUrl: string, verify: () => Promise<void>): Promise<void> {\n const hit = attestationCache.get(teeUrl);\n if (hit && Date.now() - hit.at < ATTESTATION_TTL_MS) return hit.promise;\n\n const promise = verify().catch((e: unknown) => {\n attestationCache.delete(teeUrl);\n throw e;\n });\n attestationCache.set(teeUrl, { at: Date.now(), promise });\n return promise;\n}\n\n/**\n * Verify the enclave ahead of time so the cost overlaps with work that does not\n * depend on it (key generation, share storage) instead of sitting on the\n * critical path. Never throws — a real failure resurfaces at the call that\n * actually needs attestation.\n */\nexport function prewarmAttestation(teeUrl: string): void {\n void attestOnce(teeUrl, async () => {\n const nonce = crypto.getRandomValues(new Uint8Array(16));\n const nonceHex = Array.from(nonce)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n await verifyTeeAttestation(teeUrl, nonceHex);\n }).catch(() => {});\n}\n\nexport interface SignRequest {\n chain: string;\n kind: 'transaction' | 'message' | 'typedData' | 'authorization';\n payload: string; // hex (EVM tx) | base64 (Solana) | raw string (message) | JSON (typedData/authorization)\n txHash?: string; // required for EVM transactions\n}\n\nexport interface ResplitResult {\n deviceShare: Uint8Array;\n recoveryShare: Uint8Array;\n shareSetVersion: number;\n}\n\nexport class TeeClient {\n private handle: string | null = null;\n private attested = false;\n /** Mirrors what the signer confirmed for this session, not what we asked for. */\n private assertionPerSignature = false;\n /** The signer's authoritative remaining lifetime (seconds), null until a session opens. */\n private sessionExpiresInSec: number | null = null;\n\n constructor(private teeUrl: string) {}\n\n /** Whether this session actually got per-signature assertions. */\n requiresAssertionPerSignature(): boolean {\n return this.assertionPerSignature;\n }\n\n /**\n * The lifetime the signer granted this session, in seconds — which can be\n * shorter than the client's configured duration when the JWT expires first.\n * Null if the signer didn't report one (older build). Callers clamp their own\n * countdown to this so it never promises time the handle doesn't have.\n */\n sessionExpiresIn(): number | null {\n return this.sessionExpiresInSec;\n }\n\n /** The opaque session handle, so a live session can be persisted and resumed after a reload. */\n getHandle(): string | null {\n return this.handle;\n }\n\n /**\n * Adopt a handle from a persisted session (page reload) instead of opening a\n * new one. The session was already attested when first opened, and the handle\n * is bound to that CVM session — a swapped CVM would simply not recognise it —\n * so re-attestation is skipped. If the handle has expired server-side, the\n * first sign() 401s and clears it, falling back to a normal reconnect.\n */\n adoptHandle(handle: string, assertionPerSignature: boolean): void {\n this.handle = handle;\n this.assertionPerSignature = assertionPerSignature;\n this.attested = true;\n }\n\n private async ensureAttested(): Promise<void> {\n if (this.attested) return;\n await attestOnce(this.teeUrl, async () => {\n const nonce = crypto.getRandomValues(new Uint8Array(16));\n const nonceHex = Array.from(nonce)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n await verifyTeeAttestation(this.teeUrl, nonceHex);\n });\n this.attested = true;\n }\n\n /**\n * Opens a signing session and returns the addresses the TEE derived from the\n * key it actually reconstructed — authoritative, unlike the backend's\n * recorded copy, which nothing else can verify. Returns null if the TEE\n * couldn't derive them (older signer build, or a transient share-fetch\n * failure); callers fall back to the backend's addresses in that case.\n */\n async openSession(\n deviceShare: Uint8Array,\n jwt: string,\n requireAssertionPerSignature = false,\n ): Promise<{ evm: string; solana: string; tron?: string } | null> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/session`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n deviceShare: bytesToBase64(deviceShare),\n requireAssertionPerSignature,\n }),\n });\n // The signer fails CLOSED on a share that reconstructs a key other than the\n // one on record (see assertKeyMatchesRecord in the TEE). That is exactly\n // what a device holding a superseded share looks like after another device\n // rotated the set, so surface it as its own recoverable error rather than a\n // generic failure — the caller drops the dead share and re-recovers.\n if (res.status === 403) {\n const body = await res.json().catch(() => ({}));\n if (body?.error === 'share_mismatch') {\n const { StaleDeviceShareError } = await import('./errors');\n throw new StaleDeviceShareError();\n }\n }\n if (!res.ok) throw new Error('session open failed');\n const body = await res.json();\n this.handle = body.handle;\n // Trust the echo, not the request: an older signer build silently ignores\n // the field, and quietly signing without the prompts the caller asked for\n // would be worse than failing. Surfaced via requiresAssertionPerSignature()\n // so client.ts can refuse rather than downgrade.\n this.assertionPerSignature = body.requireAssertionPerSignature === true;\n this.sessionExpiresInSec = typeof body.expiresIn === 'number' ? body.expiresIn : null;\n return body.addresses ?? null;\n }\n\n /**\n * Flow B: exchange a recovery share (from a recovery-share file) for a\n * fresh device share. The server verifies the reconstructed master\n * actually matches this account's addresses before returning anything —\n * see the security note in the TEE's /signer/recover handler. Rotates the\n * whole share set: the caller MUST persist the returned recoveryShare as a\n * new recovery-share file, since the old one stops working immediately.\n */\n async recoverWithShare(jwt: string, recoveryShare: Uint8Array): Promise<ResplitResult> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/recover`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ recoveryShare: bytesToBase64(recoveryShare) }),\n });\n if (res.status === 403) {\n const { RecoveryWalletMismatchError } = await import('./errors');\n throw new RecoveryWalletMismatchError();\n }\n if (!res.ok) throw new Error('recovery failed');\n const body = await res.json();\n return {\n deviceShare: base64ToBytes(body.deviceShare),\n recoveryShare: base64ToBytes(body.recoveryShare),\n shareSetVersion: body.shareSetVersion,\n };\n }\n\n /**\n * Request a fresh WebAuthn assertion challenge and complete it in the\n * browser via @simplewebauthn/browser's startAuthentication(), which\n * handles all the base64url (de)serialization the raw navigator.credentials\n * API requires. Shared by rotateShares() and exportPortableBackup() — both\n * require proof of fresh authenticator possession, not just an active session.\n */\n private async completeAssertion(jwt: string): Promise<{ challengeId: string; assertion: AuthenticationResponseJSON }> {\n const res = await teeFetch(`${this.teeUrl}/signer/assertion-challenge`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ rpId: window.location.hostname }),\n });\n // The signer 401s here ONLY when the JWT fails verification (all other\n // failures are 400), so this is \"your login expired — sign in again\",\n // not \"the security check was refused\". Conflating the two showed users\n // an export-authorization error for what is really a stale token.\n if (res.status === 401) throw new ReconnectRequiredError();\n if (!res.ok) throw new ExportNotAuthorizedError();\n const { challengeId, options } = await res.json();\n\n let assertion: AuthenticationResponseJSON;\n try {\n assertion = await startAuthentication({ optionsJSON: options });\n } catch {\n const { UserCancelledError } = await import('./errors');\n throw new UserCancelledError();\n }\n return { challengeId, assertion };\n }\n\n\n /**\n * Enrol this wallet for server-assisted provisioning by handing the enclave\n * the recovery share to seal.\n *\n * After this, a new device gets a working share from login alone — no passkey\n * sync, no recovery file. The enclave seals the share under a key only it can\n * derive, so the backend stores ciphertext it cannot read; but the enclave\n * then holds two of three shares and can reconstruct on its own. That is the\n * trade this call makes, which is why it is opt-out rather than implicit.\n */\n async enrolAuthShare(jwt: string, recoveryShare: Uint8Array): Promise<void> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/auth-share`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ share: bytesToBase64(recoveryShare) }),\n });\n // Carry the status through: enrolment failure is swallowed by the caller\n // (a failed enrolment must not undo a good wallet), so this message is the\n // only trace of WHY a wallet later fails to provision. 403 = wallet\n // mismatch (addresses missing or not matching the reconstructed key), 401 =\n // bad/expired JWT or the enclave's own backend call failed, 429 = rate\n // limited.\n if (!res.ok) {\n const detail = await res.text().catch(() => '');\n throw new Error(\n `auth share enrolment failed (HTTP ${res.status})${detail ? `: ${detail.slice(0, 200)}` : ''}`,\n );\n }\n }\n\n /**\n * Ask the enclave for a fresh device share for this authenticated user.\n * Returns null when the wallet was never enrolled — the signal to fall back\n * to passkey sync or the recovery file rather than fail.\n *\n * Every successful call re-splits the set, so any share this device or any\n * other held is now dead. Intentional: a leaked device share stops working the\n * next time the user signs in anywhere.\n */\n async provisionDeviceShare(jwt: string): Promise<Uint8Array | null> {\n await this.ensureAttested();\n const res = await teeFetch(`${this.teeUrl}/signer/provision`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n });\n if (res.status === 409) return null; // not enrolled\n if (!res.ok) {\n const detail = await res.text().catch(() => '');\n throw new Error(\n `device share provisioning failed (HTTP ${res.status})${detail ? `: ${detail.slice(0, 200)}` : ''}`,\n );\n }\n const body = await res.json();\n return base64ToBytes(body.deviceShare);\n }\n\n /** Voluntary rotation — e.g. after a suspected device compromise, or to invalidate an old recovery file. */\n async rotateShares(jwt: string): Promise<ResplitResult> {\n if (!this.handle) throw new Error('no session');\n const { challengeId, assertion } = await this.completeAssertion(jwt);\n const res = await teeFetch(`${this.teeUrl}/signer/rotate`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ handle: this.handle, challengeId, assertion, origin: window.location.origin }),\n });\n if (!res.ok) throw new ExportNotAuthorizedError();\n const body = await res.json();\n return {\n deviceShare: base64ToBytes(body.deviceShare),\n recoveryShare: base64ToBytes(body.recoveryShare),\n shareSetVersion: body.shareSetVersion,\n };\n }\n\n /** The two-share bearer portable backup — see recovery/portableBackup.ts. Rotates the set on export. */\n async exportPortableBackup(jwt: string): Promise<ResplitResult> {\n if (!this.handle) throw new Error('no session');\n const { challengeId, assertion } = await this.completeAssertion(jwt);\n const res = await teeFetch(`${this.teeUrl}/signer/export-portable`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ handle: this.handle, challengeId, assertion, origin: window.location.origin }),\n });\n if (!res.ok) throw new ExportNotAuthorizedError();\n const body = await res.json();\n return {\n deviceShare: base64ToBytes(body.deviceShare),\n recoveryShare: base64ToBytes(body.recoveryShare),\n shareSetVersion: body.shareSetVersion,\n };\n }\n\n hasSession(): boolean {\n return this.handle !== null;\n }\n\n /**\n * `jwt` is only needed when this session requires per-signature assertions —\n * it authenticates the challenge request. Passed per call rather than cached\n * on the instance deliberately: JWT lifetime is configured independently of\n * the TEE session TTL (they are aligned at 30min by default, but an operator\n * can shorten JWT_EXPIRY_SECONDS), so a stored copy could go stale mid-session.\n */\n async sign(req: SignRequest, jwt?: string): Promise<string> {\n if (!this.handle) throw new Error('no session');\n\n let gate: { challengeId: string; assertion: AuthenticationResponseJSON } | null = null;\n if (this.assertionPerSignature) {\n if (!jwt) throw new Error('sign requires a jwt when per-signature assertion is enabled');\n // One challenge per signature. completeAssertion throws\n // UserCancelledError if the user dismisses the prompt, which propagates\n // as a refusal — the signature simply does not happen.\n gate = await this.completeAssertion(jwt);\n }\n\n const res = await teeFetch(`${this.teeUrl}/signer/sign`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n handle: this.handle,\n ...req,\n ...(gate ? { ...gate, origin: window.location.origin } : {}),\n }),\n });\n if (res.status === 401) {\n // An assertion rejection is also a 401, but it must not be read as an\n // expired session — the handle is still perfectly good and dropping it\n // would force a needless full reconnect.\n const body = await res.clone().json().catch(() => ({}));\n if (body?.error === 'assertion_required') {\n throw new ExportNotAuthorizedError();\n }\n this.handle = null;\n throw new SessionExpiredError();\n }\n if (!res.ok) throw new Error('sign failed');\n return (await res.json()).signature;\n }\n\n async closeSession(): Promise<void> {\n if (!this.handle) return;\n const handle = this.handle;\n this.handle = null;\n void fetch(`${this.teeUrl}/signer/close`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ handle }),\n }).catch(() => {});\n }\n}\n","import { getCollateralAndVerify, type VerifiedReport } from '@phala/dcap-qvl';\nimport { AttestationError } from './errors';\n// packages/decane-connect-kit/src/social/attestation.ts -> repo root is 4\n// levels up (src/social -> src -> decane-connect-kit -> packages -> root).\nimport measurementConfig from '../../../../infra/tee-measurement.json';\n\nexport { AttestationError };\n\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith('0x') ? hex.slice(2) : hex;\n const bytes = new Uint8Array(Math.floor(clean.length / 2));\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes).map((b) => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * CORRECTED (found while typechecking, 2026-07-20) against the real\n * @phala/dcap-qvl 0.5.2 type definitions — the doc this was drafted from\n * assumed `getCollateralAndVerify()` returns `{ valid: boolean, reportData }`.\n * Neither field exists. The real `VerifiedReport` shape is:\n * { status: TcbStatus, advisory_ids: string[], report: Report, ppid: Buffer }\n * with the actual TDX report (containing `reportData`, `mrTd`, `rtMr0..3`)\n * reached via `report.asTd10()` / `report.asTd15()`.\n *\n * Two things below are INFERRED from the type shape, not empirically\n * confirmed against a real quote (blocked on Stage 3 — no CVM or dstack\n * simulator has been exercised yet):\n * - That getCollateralAndVerify THROWS on an invalid signature/cert chain\n * rather than returning some failure sentinel (the non-nullable,\n * no-error-variant return type strongly suggests this, matching the\n * usual Rust Result<T,E> -> JS throw-on-Err binding pattern, but this\n * is inference, not confirmation).\n * - The padding/hashing convention dstack-sdk uses to embed a <64-byte\n * nonce into the 64-byte `reportData` field (assumed here: left-aligned,\n * zero-padded, unhashed). A real quote is needed to confirm this.\n * Both must be verified against a real quote before this is trustworthy.\n */\nexport async function verifyTeeAttestation(teeUrl: string, nonce: string): Promise<void> {\n const res = await fetch(`${teeUrl}/attestation`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ nonce }),\n });\n if (!res.ok) throw new AttestationError('quote fetch failed');\n const { quote, measurement } = await res.json();\n\n // 1. Signature chains to Intel's root CA — proves a real TDX enclave.\n let verified: VerifiedReport;\n try {\n verified = await getCollateralAndVerify(hexToBytes(quote));\n } catch {\n throw new AttestationError('quote signature invalid');\n }\n\n // A verified-but-revoked platform is a real TDX chip with a known,\n // unpatched vulnerability — reject it same as a bad signature.\n if (verified.status === 'Revoked') {\n throw new AttestationError('TEE platform TCB status is Revoked');\n }\n\n // 2. Quote binds to our nonce — proves freshness, blocks replay.\n const td = verified.report.asTd10() ?? verified.report.asTd15()?.base;\n if (!td) throw new AttestationError('quote is not a TDX report');\n const reportDataHex = bytesToHex(td.reportData);\n if (!reportDataHex.toLowerCase().startsWith(nonce.toLowerCase())) {\n throw new AttestationError('quote nonce mismatch');\n }\n\n // 3. Measurement is one we pinned — proves it's our audited code.\n // infra/tee-measurement.json is currently a placeholder with an empty\n // acceptedMrtd, so this intentionally fails closed until Stage 3\n // (Phala provisioning + real measurement capture) has run.\n const accepted = measurementConfig.acceptedMrtd.map((m: string) => m.toLowerCase());\n if (!accepted.includes(String(measurement).toLowerCase())) {\n throw new AttestationError(\n `TEE measurement not accepted. Got ${measurement}, expected one of ${accepted.join(', ') || '(none configured yet)'}`\n );\n }\n}\n","{\n \"signerVersion\": \"0.1.3\",\n \"acceptedMrtd\": [\n \"[\\\"68102e7b524af310f7b7d426ce75481e36c40f5d513a9009c046e9d37e31551f0134d954b496a3357fd61d03f07ffe96\\\",\\\"07e6f51aa763abfe75c3ddfbf4f425fe3f0ceff66d807a75e049303dce9addf68e7218729bd419638af63a370f65878c\\\",\\\"a2a58c9a959a4fa44bd6da0c97a2270c051faf12084cfe91ae900e4fdff6cdd4f69a82005e04ee920f231497894d677f\\\",\\\"a76a81147b7f733cb400914c8791ec149bb3a31f3727b1c1e12ec22e9c1a183b6e617e78636dca37075f5a695afd46c2\\\"]\"\n ],\n \"primaryMrtd\": \"[\\\"68102e7b524af310f7b7d426ce75481e36c40f5d513a9009c046e9d37e31551f0134d954b496a3357fd61d03f07ffe96\\\",\\\"07e6f51aa763abfe75c3ddfbf4f425fe3f0ceff66d807a75e049303dce9addf68e7218729bd419638af63a370f65878c\\\",\\\"a2a58c9a959a4fa44bd6da0c97a2270c051faf12084cfe91ae900e4fdff6cdd4f69a82005e04ee920f231497894d677f\\\",\\\"a76a81147b7f733cb400914c8791ec149bb3a31f3727b1c1e12ec22e9c1a183b6e617e78636dca37075f5a695afd46c2\\\"]\",\n \"capturedAt\": \"2026-07-20T10:08:58.717Z\",\n \"tcbStatus\": \"UpToDate\",\n \"_note\": \"Captured from a live, signature-verified TDX quote (getCollateralAndVerify -> UpToDate) against decane-tee-signer v0.1.3 running on Phala Cloud CVM 786e714d-5042-4bf1-8060-0bc358f6a72f. measurement is the JSON.stringify(replayRtmrs()) output, compared as an opaque string (not parsed per-RTMR), matching the actual comparison logic in social/attestation.ts.\"\n}\n","// @noble/curves is used solely to validate a generated master secret lies in\n// secp256k1's valid scalar range [1, n-1] before use — 32 random bytes fall\n// outside that range with negligible-but-nonzero probability, and this\n// matters because the master is exportable to third-party wallets via the\n// offline recovery tool (see recovery/portableBackup.ts).\nimport { secp256k1 } from '@noble/curves/secp256k1';\nimport { split, combine } from 'shamir-secret-sharing';\nimport type { ShareSet } from './shareTypes';\n\nexport function generateRandomBytes(n: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(n));\n}\n\n/** Overwrites a byte array with zeroes to wipe sensitive material from memory. */\nexport function zeroize(bytes: Uint8Array): void {\n bytes.fill(0);\n}\n\n/**\n * Generate a master secret valid on both curves.\n * secp256k1 requires a scalar in [1, n-1]; Ed25519 accepts any 32 bytes as a\n * seed, so no equivalent check applies there.\n */\nexport function generateMaster(): Uint8Array {\n let master: Uint8Array;\n do {\n master = generateRandomBytes(32);\n } while (!secp256k1.utils.isValidPrivateKey(master));\n return master;\n}\n\n/**\n * Split a master into a 2-of-3 Shamir share set (device, server, recovery).\n * Any two shares reconstruct the master; one alone reveals nothing.\n * Does not zeroize `master` — the caller owns it and is responsible for\n * zeroizing it once splitting (and any address derivation) is done.\n */\nexport async function splitMaster(master: Uint8Array, version = 1): Promise<ShareSet> {\n if (master.length !== 32) throw new Error('master must be 32 bytes');\n const parts = await split(master, 3, 2);\n if (parts.length !== 3) throw new Error('unexpected share count');\n return { device: parts[0]!, server: parts[1]!, recovery: parts[2]!, version };\n}\n\n/**\n * Reconstruct the master from any two shares. Caller must zeroize the result.\n *\n * IMPORTANT: this function does NOT verify the shares actually belong to the\n * same share set — shamir-secret-sharing's combine() will silently produce\n * some 32-byte output even for two shares from unrelated splits (empirically\n * verified, not just theoretical: it does not throw). Any caller combining\n * shares where one side is caller-supplied (e.g. a recovery share submitted\n * over the network) MUST verify the result against known-good addresses\n * before trusting or returning anything derived from it. See the security\n * notes on the TEE signer's /signer/recover and /signer/export-portable.\n */\nexport async function combineShares(a: Uint8Array, b: Uint8Array): Promise<Uint8Array> {\n const master = await combine([a, b]);\n if (master.length !== 32) throw new Error('reconstruction produced wrong length');\n return master;\n}\n","/** AES-256-GCM wrap / unwrap using window.crypto.subtle. */\n\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nexport async function importAesKey(rawKey: Uint8Array): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'raw', buf(rawKey),\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n );\n}\n\nexport async function aesGcmEncrypt(\n key: CryptoKey,\n plaintext: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(plaintext));\n return new Uint8Array(ct);\n}\n\nexport async function aesGcmDecrypt(\n key: CryptoKey,\n ciphertext: Uint8Array,\n iv: Uint8Array,\n): Promise<Uint8Array> {\n const pt = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(ciphertext));\n return new Uint8Array(pt);\n}\n","const PBKDF2_ITERATIONS = 600_000;\n\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nexport async function deriveKeyFromPin(pin: string, salt: Uint8Array): Promise<CryptoKey> {\n const pinBytes = new TextEncoder().encode(pin);\n const base = await crypto.subtle.importKey('raw', buf(pinBytes), 'PBKDF2', false, ['deriveKey']);\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: buf(salt), iterations: PBKDF2_ITERATIONS, hash: 'SHA-256' },\n base,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt'],\n );\n}\n\nexport function validatePin(pin: string): void {\n if (!/^\\d{4,8}$/.test(pin)) throw new Error('PIN must be 4–8 digits');\n}\n","import { startRegistration, startAuthentication } from '@simplewebauthn/browser';\nimport type {\n PublicKeyCredentialCreationOptionsJSON,\n PublicKeyCredentialRequestOptionsJSON,\n RegistrationResponseJSON,\n AuthenticationResponseJSON,\n} from '@simplewebauthn/browser';\nimport { WebAuthnNotSupportedError, UserCancelledError } from '../errors';\n\nfunction b64u(u: Uint8Array): string {\n return btoa(String.fromCharCode(...u)).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\nfunction fromB64u(s: string): Uint8Array {\n return Uint8Array.from(atob(s.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0));\n}\n\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nexport function isPasskeySupported(): boolean {\n return (\n typeof window !== 'undefined' &&\n !!window.PublicKeyCredential &&\n 'isUserVerifyingPlatformAuthenticatorAvailable' in window.PublicKeyCredential\n );\n}\n\n/**\n * One WebAuthn registration ceremony serving two purposes at once:\n * 1. The PRF extension output (unchanged from before) becomes the AES key\n * that wraps the device share — purely client-side, Decane never sees it.\n * 2. The raw, real registration response is returned alongside it so the\n * caller can forward it to the backend's /webauthn/register for\n * server-side signature verification — this is what lets\n * /signer/rotate and /signer/export-portable gate on a genuine signed\n * assertion later, independent of the PRF flow.\n *\n * `optionsJSON` must come from the backend's /webauthn/register-options\n * (real, server-tracked challenge) — the caller is responsible for injecting\n * the prf extension into it before calling this, since the PRF salt is a\n * purely client-side concept the generic registration endpoint doesn't know\n * about. See social/webauthnRegistration.ts for the full orchestration.\n */\nexport async function registerPasskey(opts: {\n optionsJSON: PublicKeyCredentialCreationOptionsJSON;\n}): Promise<{ credentialId: Uint8Array; prfOutput?: Uint8Array; response: RegistrationResponseJSON }> {\n let response: RegistrationResponseJSON;\n try {\n response = await startRegistration({ optionsJSON: opts.optionsJSON });\n } catch (e: unknown) {\n if ((e as Error).name === 'NotAllowedError') throw new UserCancelledError();\n throw e;\n }\n\n const extResults = response.clientExtensionResults as Record<string, unknown> | undefined;\n const prfResults = (extResults?.prf as { results?: { first?: ArrayBuffer | string } } | undefined)?.results;\n let prfOutput: Uint8Array | undefined;\n if (prfResults?.first) {\n prfOutput = typeof prfResults.first === 'string'\n ? Uint8Array.from(atob(prfResults.first.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0))\n : new Uint8Array(prfResults.first);\n }\n\n const credentialId = Uint8Array.from(\n atob(response.id.replace(/-/g, '+').replace(/_/g, '/')),\n (c) => c.charCodeAt(0)\n );\n\n return { credentialId, prfOutput, response };\n}\n\n/**\n * One assertion ceremony that both authenticates the user and unwraps their\n * device share.\n *\n * The server-issued challenge is signed (proving possession of the passkey, so\n * the backend can mint a session JWT without a Google/email round trip) while\n * the PRF extension evaluates the stored salt in the same call, yielding the\n * AES key for the wrapped device share. Doing these separately would cost the\n * user two biometric prompts back to back for one sign-in.\n *\n * `prfOutput` is undefined when the authenticator declines PRF; the caller\n * must then fall back rather than assume the share can be unwrapped.\n */\nexport async function authenticateWithPasskey(opts: {\n optionsJSON: PublicKeyCredentialRequestOptionsJSON;\n prfSalt: Uint8Array;\n}): Promise<{ response: AuthenticationResponseJSON; prfOutput?: Uint8Array }> {\n // @simplewebauthn/browser (v13) does NOT process the PRF extension — it passes\n // `extensions` straight through to navigator.credentials.get(). So prf.eval.first\n // must be a real ArrayBuffer here, NOT a base64url string; a string reaches the\n // browser as-is and throws \"not of type (ArrayBuffer or ArrayBufferView)\". The\n // registration side (webauthnRegistration.ts) and getPrfOutput already do this;\n // this path was the one still passing a string.\n const optionsJSON: PublicKeyCredentialRequestOptionsJSON = {\n ...opts.optionsJSON,\n extensions: {\n ...opts.optionsJSON.extensions,\n prf: { eval: { first: buf(opts.prfSalt) } },\n } as unknown as PublicKeyCredentialRequestOptionsJSON['extensions'],\n };\n\n let response: AuthenticationResponseJSON;\n try {\n response = await startAuthentication({ optionsJSON });\n } catch (e: unknown) {\n if ((e as Error).name === 'NotAllowedError') throw new UserCancelledError();\n throw e;\n }\n\n const ext = response.clientExtensionResults as Record<string, unknown> | undefined;\n const prfResults = (ext?.['prf'] as { results?: { first?: ArrayBuffer | string } } | undefined)?.results;\n let prfOutput: Uint8Array | undefined;\n if (prfResults?.first) {\n prfOutput =\n typeof prfResults.first === 'string'\n ? fromB64u(prfResults.first)\n : new Uint8Array(prfResults.first);\n }\n\n return { response, prfOutput };\n}\n\nexport async function getPrfOutput(opts: {\n rpId: string;\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n}): Promise<Uint8Array> {\n const challenge = crypto.getRandomValues(new Uint8Array(32));\n\n let cred: PublicKeyCredential;\n try {\n cred = (await navigator.credentials.get({\n publicKey: {\n challenge: buf(challenge),\n rpId: opts.rpId,\n allowCredentials: [{ id: buf(opts.credentialId), type: 'public-key' }],\n userVerification: 'required',\n extensions: { prf: { eval: { first: buf(opts.prfSalt) } } } as AuthenticationExtensionsClientInputs,\n },\n })) as PublicKeyCredential;\n } catch (e: unknown) {\n if ((e as Error).name === 'NotAllowedError') throw new UserCancelledError();\n throw e;\n }\n\n const ext = cred.getClientExtensionResults() as Record<string, unknown>;\n const prfResults = (ext?.prf as { results?: { first?: ArrayBuffer } } | undefined)?.results;\n if (!prfResults?.first) throw new WebAuthnNotSupportedError();\n return new Uint8Array(prfResults.first);\n}\n","import type { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/browser';\nimport { registerPasskey } from './crypto/passkey';\nimport type { ApiClient } from './api';\n\nfunction bufFromBytes(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\n/**\n * Full registration orchestration: fetch a real, server-tracked challenge\n * from the backend, inject the PRF extension (a purely client-side concern\n * the generic /webauthn/register-options endpoint doesn't know about),\n * complete the ceremony, and report the result back for server-side\n * verification. One passkey prompt does double duty — see\n * crypto/passkey.ts's registerPasskey() doc comment for why.\n *\n * Best-effort on the server-verification half: if /webauthn/register fails\n * (network blip, etc.) this still returns the PRF output so the existing\n * device-share-wrapping flow proceeds normally — a user should never be\n * blocked from finishing signup because the *additional* assertion-gating\n * registration didn't complete. The gap self-heals next time rotateShares()\n * or exportPortableBackup() is attempted and finds no stored credential.\n */\nexport async function registerWebAuthnCredential(opts: {\n api: ApiClient;\n jwt: string;\n rpId: string;\n rpName: string;\n prfSalt: Uint8Array;\n}): Promise<{ credentialId: Uint8Array; prfOutput?: Uint8Array }> {\n const baseOptions = await opts.api.getWebAuthnRegisterOptions(opts.jwt, opts.rpId, opts.rpName);\n\n // IMPORTANT: @simplewebauthn/browser's startRegistration() spreads\n // `extensions` straight into navigator.credentials.create()'s options with\n // NO base64url->ArrayBuffer conversion (only challenge/user.id/\n // excludeCredentials get converted) — verified by reading its source.\n // prf.eval.first must therefore be a raw ArrayBuffer here, not a base64url\n // string, even though the JSON-typed interface below suggests otherwise.\n const optionsJSON: PublicKeyCredentialCreationOptionsJSON = {\n ...baseOptions,\n extensions: {\n ...baseOptions.extensions,\n prf: { eval: { first: bufFromBytes(opts.prfSalt) } },\n } as unknown as PublicKeyCredentialCreationOptionsJSON['extensions'],\n };\n\n const { credentialId, prfOutput, response } = await registerPasskey({ optionsJSON });\n\n try {\n await opts.api.postWebAuthnRegister(opts.jwt, response, window.location.origin);\n } catch (e) {\n console.warn('decane-connect-kit: WebAuthn server-side registration failed; PRF-based unlock still works, but rotateShares()/exportPortableBackup() will not until this is retried.', e);\n }\n\n return { credentialId, prfOutput };\n}\n","import type { ApiClient } from '../api';\nimport type { AuthResult } from '../types';\n\n/**\n * Sends a 6-digit magic-link code to the user's email.\n * Always returns void regardless of whether the email exists (prevents enumeration).\n */\nexport async function startEmailAuth(api: ApiClient, email: string): Promise<void> {\n await api.authEmailStart(email);\n}\n\n/**\n * Verifies the 6-digit code and exchanges it for a JWT.\n */\nexport async function verifyEmailCode(\n api: ApiClient,\n email: string,\n code: string,\n): Promise<AuthResult> {\n return api.authEmailVerify(email, code);\n}\n","// Sign in with KingsChat (browser).\n//\n// KingsChat's own web SDK opens accounts.kingsch.at in a popup and receives the\n// tokens back via postMessage. This reimplements that handshake rather than\n// depending on kingschat-web-sdk, for two reasons: that package bundles a\n// stylesheet and DOM helpers this SDK has no use for, and it offers no way to\n// hand the resulting token straight to a backend, which is the only thing we\n// actually need.\n//\n// The access token is NOT a session. It goes to /auth/kingschat, which spends it\n// against KingsChat's own API to establish who it belongs to and returns a\n// Decane JWT. Nothing here trusts the popup's payload on its own.\n\nimport { UserCancelledError, CallSequenceError } from '../errors';\n\n/** Where the consent screen lives, and therefore the only origin we accept a token from. */\nconst KINGSCHAT_AUTH_ORIGIN = 'https://accounts.kingsch.at';\n\nexport interface KingsChatTokens {\n accessToken: string;\n refreshToken?: string;\n expiresInMillis?: number;\n}\n\n/**\n * Read the token payload out of a postMessage, tolerating either casing.\n *\n * KingsChat's API replies in snake_case (`access_token`) while its web SDK's\n * public interface is camelCase (`accessToken`), and the popup payload is not\n * documented either way — so both are accepted rather than betting on one.\n */\nfunction readTokens(data: unknown): KingsChatTokens | null {\n if (!data || typeof data !== 'object') return null;\n const d = data as Record<string, unknown>;\n\n const accessToken = d.accessToken ?? d.access_token;\n if (typeof accessToken !== 'string' || !accessToken) return null;\n\n const refreshToken = d.refreshToken ?? d.refresh_token;\n const expires = d.expiresInMillis ?? d.expires_in_millis;\n\n return {\n accessToken,\n refreshToken: typeof refreshToken === 'string' ? refreshToken : undefined,\n expiresInMillis: typeof expires === 'number' ? expires : undefined,\n };\n}\n\nfunction buildAuthUrl(clientId: string, scopes: string[]): string {\n const url = new URL(KINGSCHAT_AUTH_ORIGIN);\n url.searchParams.set('client_id', clientId);\n // KingsChat expects a JSON array literal here, not repeated params.\n url.searchParams.set('scopes', JSON.stringify(scopes));\n url.searchParams.set('redirect_uri', window.location.origin);\n url.searchParams.set('post_message', '1');\n return url.toString();\n}\n\n/**\n * Open the KingsChat consent popup and resolve with the tokens it returns.\n *\n * Must be called synchronously from a user gesture (a click handler) — popup\n * blockers reject a window.open that happens after an await, which is why the\n * clientId is fetched by the caller *before* this runs.\n */\nexport function loginWithKingsChatPopup(opts: {\n clientId: string;\n scopes?: string[];\n timeoutMs?: number;\n}): Promise<KingsChatTokens> {\n const scopes = opts.scopes ?? ['profile'];\n const popup = window.open(\n buildAuthUrl(opts.clientId, scopes),\n 'decane-kingschat',\n 'width=480,height=720,menubar=no,toolbar=no',\n );\n\n if (!popup) {\n throw new CallSequenceError(\n 'The KingsChat sign-in popup was blocked. Call connectWithKingsChat() directly from a click handler.',\n );\n }\n\n return new Promise<KingsChatTokens>((resolve, reject) => {\n let settled = false;\n\n const finish = (fn: () => void) => {\n if (settled) return;\n settled = true;\n window.removeEventListener('message', onMessage);\n clearInterval(closedPoll);\n clearTimeout(timeout);\n try {\n popup.close();\n } catch {\n // Already gone, or cross-origin — nothing to do.\n }\n fn();\n };\n\n const onMessage = (event: MessageEvent) => {\n // The origin check is the whole security boundary of this handshake: any\n // page can postMessage to us, so a token from anywhere else is ignored\n // outright rather than forwarded to the backend.\n if (event.origin !== KINGSCHAT_AUTH_ORIGIN) return;\n\n const data = event.data as { error?: unknown } | null;\n if (data && typeof data === 'object' && data.error) {\n finish(() => reject(new CallSequenceError(`KingsChat sign-in failed: ${String(data.error)}`)));\n return;\n }\n\n const tokens = readTokens(event.data);\n if (tokens) finish(() => resolve(tokens));\n // A message from the right origin that carries no token is ignored — the\n // consent screen emits several during its lifecycle.\n };\n\n window.addEventListener('message', onMessage);\n\n // The popup being closed by hand produces no message at all, so it has to\n // be observed. `closed` stays readable cross-origin.\n const closedPoll = setInterval(() => {\n if (popup.closed) finish(() => reject(new UserCancelledError()));\n }, 400);\n\n const timeout = setTimeout(\n () =>\n finish(() =>\n reject(new CallSequenceError('KingsChat sign-in timed out before returning a token.')),\n ),\n opts.timeoutMs ?? 5 * 60_000,\n );\n });\n}\n","import { keccak256, Transaction, resolveProperties, type TransactionRequest } from 'ethers';\nimport type { TeeClient } from '../teeClient';\n\n// `jwt` is forwarded to TeeClient.sign so it can fetch a per-signature\n// assertion challenge when the session requires one. Ignored otherwise.\nexport async function signEvmTransaction(\n tee: TeeClient,\n chain: string,\n tx: TransactionRequest,\n jwt?: string\n): Promise<string> {\n const resolved = await resolveProperties(tx);\n const unsigned = Transaction.from(resolved as any).unsignedSerialized;\n const payload = unsigned.startsWith('0x') ? unsigned.slice(2) : unsigned;\n const txHash = keccak256('0x' + payload);\n return tee.sign({ chain, kind: 'transaction', payload, txHash }, jwt);\n}\n\nexport async function signEvmMessage(\n tee: TeeClient,\n chain: string,\n message: string,\n jwt?: string\n): Promise<string> {\n return tee.sign({ chain, kind: 'message', payload: message }, jwt);\n}\n\nexport interface Eip712TypedData {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n message: Record<string, unknown>;\n primaryType?: string;\n}\n\n// EIP-7702 authorization. The enclave computes the 0x05-prefixed auth hash from\n// (chainId, address, nonce) and signs it — a raw ECDSA over that digest, NOT a\n// personal_sign or typed-data signature. The 0x05 magic prefix domain-separates\n// it from transactions, so this path can't be coerced into signing one. Returns\n// the {yParity, r, s} an authorizationList entry needs.\nexport interface SignedAuthorization {\n chainId: number;\n address: string; // the delegate/implementation contract\n nonce: number;\n yParity: number;\n r: string;\n s: string;\n}\n\nexport async function signEvmAuthorization(\n tee: TeeClient,\n chainId: number,\n address: string,\n nonce: number,\n jwt?: string\n): Promise<SignedAuthorization> {\n const serialized = await tee.sign(\n { chain: `evm:${chainId}`, kind: 'authorization', payload: JSON.stringify({ chainId, address, nonce }) },\n jwt\n );\n const hex = serialized.startsWith('0x') ? serialized.slice(2) : serialized;\n const r = '0x' + hex.slice(0, 64);\n const s = '0x' + hex.slice(64, 128);\n const v = parseInt(hex.slice(128, 130), 16);\n // Full SignedAuthorization tuple, matching viem/permissionless so it drops\n // straight into a userOperation's `authorization` field and a type-4 tx's\n // authorizationList — no adapter needed at the call site.\n return { chainId, address, nonce, yParity: v >= 27 ? v - 27 : v, r, s };\n}\n\n// EIP-712. The structured data is sent whole — the enclave hashes it itself\n// (0x1901 || domainSeparator || hashStruct) and signs the result. It never\n// receives a raw digest, so this path cannot be abused to blind-sign a\n// transaction: the 0x1901 domain prefix separates typed data from tx encoding.\nexport async function signEvmTypedData(\n tee: TeeClient,\n chain: string,\n typedData: Eip712TypedData,\n jwt?: string\n): Promise<string> {\n // uint256 fields are commonly bigint; JSON.stringify throws on those. Serialize\n // bigints as decimal strings — ethers' signTypedData in the enclave accepts a\n // string for a numeric field and coerces it back to the same value.\n const payload = JSON.stringify(typedData, (_k, v) =>\n typeof v === 'bigint' ? v.toString() : v,\n );\n return tee.sign({ chain, kind: 'typedData', payload }, jwt);\n}\n","// Read-only native-balance fetching, shared by the client (getBalance), the\n// useSocialBalance hook, and the SocialWalletModal display so there is one\n// implementation instead of three drifting copies. No wallet interaction and\n// no TEE session needed — balances are public chain data. ethers /\n// @solana/web3.js are dynamically imported so consumers who never read a\n// balance don't pay for them in their initial bundle.\n\n// Browser-friendly (CORS-enabled) public RPCs. Devs override via config.rpcUrls.\nexport const DEFAULT_RPCS: Record<string, string> = {\n \"evm:1\": \"https://ethereum.publicnode.com\",\n \"evm:137\": \"https://polygon.publicnode.com\",\n \"evm:8453\": \"https://base.publicnode.com\",\n \"evm:10\": \"https://optimism.publicnode.com\",\n \"evm:42161\": \"https://arbitrum-one.publicnode.com\",\n \"evm:56\": \"https://bsc.publicnode.com\",\n \"evm:11155111\": \"https://ethereum-sepolia.publicnode.com\",\n \"evm:84532\": \"https://base-sepolia.publicnode.com\",\n \"evm:31337\": \"http://localhost:8545\",\n};\n\n// Native-currency symbol per EVM chain — defaults to ETH for the L2s/testnets.\nconst EVM_SYMBOLS: Record<string, string> = {\n \"evm:137\": \"MATIC\",\n \"evm:56\": \"BNB\",\n};\n\nexport type BalanceKind = \"evm\" | \"solana\";\n\nexport interface BalanceResult {\n /** Smallest unit — wei for EVM, lamports for Solana. */\n raw: bigint;\n /** Human-readable amount in whole native units, e.g. \"1.2345\". */\n formatted: string;\n /** Native currency symbol, e.g. \"ETH\", \"MATIC\", \"SOL\". */\n symbol: string;\n /** Decimals of the native currency (18 for EVM, 9 for Solana). */\n decimals: number;\n}\n\nfunction solanaEndpoint(chain: string, rpcUrls?: Record<string, string>): string {\n if (rpcUrls?.[chain]) return rpcUrls[chain];\n const cluster = chain.slice(\"solana:\".length);\n return cluster === \"devnet\"\n ? \"https://api.devnet.solana.com\"\n : \"https://api.mainnet-beta.solana.com\";\n}\n\n/** Fetch the native-token balance for one address on one chain. */\nexport async function fetchBalance(opts: {\n kind: BalanceKind;\n address: string;\n chain: string;\n rpcUrls?: Record<string, string>;\n}): Promise<BalanceResult> {\n const { kind, address, chain, rpcUrls } = opts;\n\n if (kind === \"evm\") {\n const rpcUrl = rpcUrls?.[chain] ?? DEFAULT_RPCS[chain];\n if (!rpcUrl) {\n throw new Error(\n `No RPC URL for ${chain}. Pass rpcUrls: { '${chain}': 'https://...' } in social config.`,\n );\n }\n const { JsonRpcProvider, formatEther } = await import(\"ethers\");\n const wei = await new JsonRpcProvider(rpcUrl).getBalance(address);\n return { raw: wei, formatted: formatEther(wei), symbol: EVM_SYMBOLS[chain] ?? \"ETH\", decimals: 18 };\n }\n\n const { Connection, PublicKey, LAMPORTS_PER_SOL } = await import(\"@solana/web3.js\");\n const lamports = await new Connection(solanaEndpoint(chain, rpcUrls)).getBalance(\n new PublicKey(address),\n );\n return {\n raw: BigInt(lamports),\n formatted: String(lamports / LAMPORTS_PER_SOL),\n symbol: \"SOL\",\n decimals: 9,\n };\n}\n\n/** Compact display form of a `formatted` amount (4 sig-figs, trims trailing zeros). */\nexport function formatBalanceDisplay(value: string | null): string {\n if (value == null) return \"—\";\n const n = Number(value);\n if (!Number.isFinite(n)) return value;\n return n === 0 ? \"0\" : n < 0.0001 ? \"<0.0001\" : n.toFixed(4).replace(/\\.?0+$/, \"\");\n}\n","// A standard EIP-1193 Ethereum provider backed by the Decane social wallet.\n// Signing methods (personal_sign, eth_signTypedData_v4, eth_sendTransaction,\n// eth_signAuthorization/EIP-7702) go through the TEE — the browser never holds\n// the key. Read methods (eth_call, eth_getBalance, eth_estimateGas, …) are\n// forwarded to the chain's RPC. This is what lets viem / wagmi / ethers drive a\n// Decane wallet exactly as they would MetaMask.\n\nimport type { DecaneConnect, Chain } from \"./types\";\nimport { DEFAULT_RPCS } from \"./balance\";\n\nexport interface Eip1193Provider {\n request(args: { method: string; params?: unknown[] | object }): Promise<unknown>;\n on(event: string, handler: (...args: unknown[]) => void): this;\n removeListener(event: string, handler: (...args: unknown[]) => void): this;\n /** Marks this as the Decane provider (parallel to wallets' isMetaMask etc.). */\n readonly isDecane: true;\n}\n\nexport interface EthereumProviderOptions {\n /** Initial chain id (numeric). Defaults to the first configured EVM chain, else 1. */\n chainId?: number;\n /** Per-chain RPC overrides ('evm:8453' -> url). Falls back to Decane's defaults. */\n rpcUrls?: Record<string, string>;\n}\n\nfunction toHex(n: number | bigint): string {\n return \"0x\" + n.toString(16);\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\n const bytes = new Uint8Array(clean.length / 2);\n for (let i = 0; i < bytes.length; i++) bytes[i] = parseInt(clean.substr(i * 2, 2), 16);\n return bytes;\n}\n\nfunction asBigInt(v: unknown): bigint | undefined {\n if (v == null) return undefined;\n if (typeof v === \"bigint\") return v;\n if (typeof v === \"number\") return BigInt(v);\n if (typeof v === \"string\") return BigInt(v); // handles 0x… and decimal\n return undefined;\n}\n\ninterface EvmTxParam {\n to?: string;\n from?: string;\n value?: string | number | bigint;\n data?: string;\n input?: string;\n gas?: string | number | bigint;\n gasLimit?: string | number | bigint;\n}\n\n/**\n * Build an EIP-1193 provider over a connected Decane social client.\n *\n * `signAuthorization` (EIP-7702) is wired only when the client exposes it — that\n * requires the TEE signer to support the authorization signing path.\n */\nexport function createEthereumProvider(\n client: DecaneConnect,\n opts: EthereumProviderOptions = {},\n): Eip1193Provider {\n let chainId = opts.chainId ?? 1;\n const listeners = new Map<string, Set<(...a: unknown[]) => void>>();\n\n function emit(event: string, ...args: unknown[]): void {\n listeners.get(event)?.forEach((h) => {\n try { h(...args); } catch { /* a bad listener must not break the provider */ }\n });\n }\n\n // Bridge Decane session events onto the standard provider events dApps expect.\n client.on(\"connected\", () => {\n const evm = client.getAddresses()?.evm;\n emit(\"connect\", { chainId: toHex(chainId) });\n if (evm) emit(\"accountsChanged\", [evm]);\n });\n client.on(\"disconnected\", () => {\n emit(\"accountsChanged\", []);\n emit(\"disconnect\", { code: 4900, message: \"Wallet disconnected\" });\n });\n\n const chainStr = (): Chain => `evm:${chainId}` as Chain;\n\n async function rpc(method: string, params: unknown[]): Promise<unknown> {\n const url = opts.rpcUrls?.[`evm:${chainId}`] ?? DEFAULT_RPCS[`evm:${chainId}`];\n if (!url) {\n throw Object.assign(new Error(`No RPC for chain ${chainId}. Pass rpcUrls.`), { code: 4900 });\n }\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ jsonrpc: \"2.0\", id: Date.now(), method, params }),\n });\n } catch (e) {\n throw Object.assign(new Error(`RPC request failed: ${(e as Error).message}`), { code: 4900 });\n }\n const json = (await res.json()) as { result?: unknown; error?: { code: number; message: string } };\n if (json.error) throw Object.assign(new Error(json.error.message), { code: json.error.code });\n return json.result;\n }\n\n async function request(args: { method: string; params?: unknown[] | object }): Promise<unknown> {\n const params = (Array.isArray(args.params) ? args.params : args.params ? [args.params] : []) as unknown[];\n const addr = () => client.getAddresses()?.evm ?? null;\n\n switch (args.method) {\n case \"eth_requestAccounts\":\n case \"eth_accounts\": {\n const a = addr();\n return a ? [a] : [];\n }\n case \"eth_chainId\":\n return toHex(chainId);\n case \"net_version\":\n return String(chainId);\n\n case \"personal_sign\": {\n // params: [messageHex, address]\n const message = params[0] as string;\n // personal_sign signs the raw bytes the hex represents.\n const bytes = typeof message === \"string\" && message.startsWith(\"0x\") ? hexToBytes(message) : message;\n return client.signMessage({ chain: chainStr(), message: bytes as string | Uint8Array });\n }\n\n case \"eth_signTypedData_v4\":\n case \"eth_signTypedData\": {\n // params: [address, typedData (json string or object)]\n const raw = params[1];\n const td = (typeof raw === \"string\" ? JSON.parse(raw) : raw) as {\n domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string;\n };\n return client.signTypedData({\n chain: chainStr(),\n domain: td.domain, types: td.types, message: td.message, primaryType: td.primaryType,\n });\n }\n\n case \"eth_sendTransaction\": {\n const tx = params[0] as EvmTxParam;\n return client.sendTransaction({\n chain: chainStr(),\n to: tx.to as string,\n value: asBigInt(tx.value),\n data: (tx.data ?? tx.input) as string | undefined,\n gasLimit: asBigInt(tx.gas ?? tx.gasLimit),\n });\n }\n\n case \"eth_signAuthorization\":\n case \"wallet_sign7702Authorization\": {\n const p = params[0] as { chainId?: number | string; address?: string; contractAddress?: string; nonce?: number | string };\n const cid = p.chainId != null ? Number(asBigInt(p.chainId)) : chainId;\n const address = (p.address ?? p.contractAddress) as string;\n const nonce = p.nonce != null ? Number(asBigInt(p.nonce)) : 0;\n return client.signAuthorization({ chainId: cid, address, nonce });\n }\n\n case \"wallet_switchEthereumChain\": {\n const p = params[0] as { chainId: string };\n chainId = Number(asBigInt(p.chainId));\n emit(\"chainChanged\", toHex(chainId));\n return null;\n }\n case \"wallet_addEthereumChain\":\n // Nothing to persist client-side; accept so dApps proceed.\n return null;\n\n default:\n // Everything else (eth_call, eth_getBalance, eth_estimateGas,\n // eth_blockNumber, eth_getTransactionReceipt, …) is a read — forward it.\n return rpc(args.method, params);\n }\n }\n\n const provider: Eip1193Provider = {\n request,\n on(event, handler) {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n return this;\n },\n removeListener(event, handler) {\n listeners.get(event)?.delete(handler);\n return this;\n },\n isDecane: true,\n };\n return provider;\n}\n","import type { Transaction, VersionedTransaction } from '@solana/web3.js';\nimport { VersionedTransaction as VTx } from '@solana/web3.js';\nimport type { TeeClient } from '../teeClient';\n\nfunction b64(bytes: Uint8Array): string {\n let s = '';\n for (const b of bytes) s += String.fromCharCode(b);\n return btoa(s);\n}\nfunction unb64(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\n\n// `jwt` is forwarded to TeeClient.sign so it can fetch a per-signature\n// assertion challenge when the session requires one. Ignored otherwise.\nexport async function signSolanaTransaction(\n tee: TeeClient,\n chain: string,\n tx: Transaction | VersionedTransaction,\n jwt?: string\n): Promise<Uint8Array> {\n const bytes =\n tx instanceof VTx ? tx.serialize() : (tx as Transaction).serialize({ requireAllSignatures: false });\n const signed = await tee.sign({ chain, kind: 'transaction', payload: b64(bytes) }, jwt);\n return unb64(signed);\n}\n\nexport async function signSolanaMessage(\n tee: TeeClient,\n chain: string,\n message: Uint8Array,\n jwt?: string\n): Promise<Uint8Array> {\n const sig = await tee.sign({ chain, kind: 'message', payload: b64(message) }, jwt);\n return unb64(sig);\n}\n","import type { ApiClient } from '../api';\n\nexport interface WrappedShareBackup {\n wrappedDeviceShare: Uint8Array;\n iv: Uint8Array;\n unlockMethod: 'passkey';\n credentialId: Uint8Array;\n prfSalt: Uint8Array;\n formatVersion: number;\n}\n\nexport async function backupWrappedShare(\n api: ApiClient,\n jwt: string,\n backup: WrappedShareBackup\n): Promise<void> {\n await api.putRecoveryBackup(jwt, backup);\n}\n\nexport async function fetchWrappedShareBackup(\n api: ApiClient,\n jwt: string\n): Promise<WrappedShareBackup | null> {\n return api.getRecoveryBackup(jwt);\n}\n","import { InvalidRecoveryFileError, WrongPasswordError } from '../errors';\n\nconst PBKDF2_ITERATIONS = 600_000;\nconst FILE_VERSION = 2;\n\nexport interface RecoveryShareFile {\n version: number;\n type: 'decane-recovery-share';\n shareSetVersion: number;\n kdf: 'pbkdf2-sha256';\n kdfParams: { iterations: number; salt: string };\n cipher: 'aes-256-gcm';\n iv: string;\n ciphertext: string; // encrypted 33-byte share + 16-byte GCM tag\n addresses: { evm: string; solana: string };\n passwordHint: string | null;\n createdAt: string;\n}\n\nfunction b64(u: Uint8Array): string {\n let s = '';\n for (const b of u) s += String.fromCharCode(b);\n return btoa(s);\n}\nfunction unb64(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nasync function deriveFileKey(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey> {\n const base = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveKey']\n );\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: buf(salt), iterations, hash: 'SHA-256' },\n base,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * Build an encrypted recovery-share file from a single 33-byte Shamir share.\n * Does not mutate or retain `share`; the caller remains responsible for\n * zeroizing it. Unlike the v1 master-key-file format this replaces, there is\n * no local verification possible on decrypt — a lone share cannot derive an\n * address. Decrypting successfully proves the password was right; it does\n * not prove the share is the right one. That check can only happen where the\n * server share also is: /signer/recover.\n */\nexport async function buildRecoveryShareFile(\n share: Uint8Array,\n password: string,\n addresses: { evm: string; solana: string },\n shareSetVersion: number,\n passwordHint?: string\n): Promise<RecoveryShareFile> {\n if (share.length !== 33) throw new Error('share must be 33 bytes');\n if (password.length < 8) throw new Error('password must be at least 8 characters');\n if (passwordHint && passwordHint.trim() === password) {\n throw new Error('password hint must not be the password');\n }\n\n const salt = crypto.getRandomValues(new Uint8Array(16));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const key = await deriveFileKey(password, salt, PBKDF2_ITERATIONS);\n const ct = new Uint8Array(\n await crypto.subtle.encrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(share))\n );\n\n return {\n version: FILE_VERSION,\n type: 'decane-recovery-share',\n shareSetVersion,\n kdf: 'pbkdf2-sha256',\n kdfParams: { iterations: PBKDF2_ITERATIONS, salt: b64(salt) },\n cipher: 'aes-256-gcm',\n iv: b64(iv),\n ciphertext: b64(ct),\n addresses,\n passwordHint: passwordHint?.trim() || null,\n createdAt: new Date().toISOString(),\n };\n}\n\n/**\n * Validate the envelope without attempting decryption. Rejects v1 master-key\n * files (from the design this replaces) with a message explaining the\n * format changed, rather than a generic \"invalid file\" error.\n */\nexport function parseRecoveryShareFile(json: unknown): RecoveryShareFile {\n const raw = json as { type?: unknown } | null | undefined;\n if (raw?.type === 'decane-recovery') {\n throw new InvalidRecoveryFileError();\n }\n const f = json as Partial<RecoveryShareFile>;\n if (\n !f ||\n (f.type as unknown) !== 'decane-recovery-share' ||\n f.version !== FILE_VERSION ||\n f.kdf !== 'pbkdf2-sha256' ||\n f.cipher !== 'aes-256-gcm' ||\n typeof f.iv !== 'string' ||\n typeof f.ciphertext !== 'string' ||\n typeof f.kdfParams?.salt !== 'string' ||\n typeof f.kdfParams?.iterations !== 'number' ||\n typeof f.shareSetVersion !== 'number' ||\n typeof f.addresses?.evm !== 'string' ||\n typeof f.addresses?.solana !== 'string'\n ) {\n throw new InvalidRecoveryFileError();\n }\n if (f.kdfParams.iterations < 100_000 || f.kdfParams.iterations > 5_000_000) {\n throw new InvalidRecoveryFileError();\n }\n return f as RecoveryShareFile;\n}\n\n/**\n * Decrypt a recovery-share file. Returns the 33-byte share.\n * Caller MUST zeroize the result.\n */\nexport async function decryptRecoveryShareFile(\n file: RecoveryShareFile,\n password: string\n): Promise<Uint8Array> {\n const salt = unb64(file.kdfParams.salt);\n const iv = unb64(file.iv);\n const ct = unb64(file.ciphertext);\n const key = await deriveFileKey(password, salt, file.kdfParams.iterations);\n\n let share: Uint8Array;\n try {\n share = new Uint8Array(\n await crypto.subtle.decrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(ct))\n );\n } catch {\n throw new WrongPasswordError(); // GCM tag mismatch\n }\n if (share.length !== 33) {\n share.fill(0);\n throw new InvalidRecoveryFileError();\n }\n return share;\n}\n\n/** Suggested download filename. */\nexport function recoveryShareFileName(evmAddress: string): string {\n return `decane-recovery-${evmAddress.slice(0, 8)}.json`;\n}\n","import { fetchWrappedShareBackup } from './wrappedShareBackup';\nimport { parseRecoveryShareFile, decryptRecoveryShareFile } from './recoveryShareFile';\nimport { getPrfOutput } from '../crypto/passkey';\nimport { importAesKey, aesGcmDecrypt } from '../crypto/wrap';\nimport { zeroize } from '../crypto/shares';\nimport { NewDeviceError } from '../errors';\nimport { TeeClient } from '../teeClient';\nimport type { ApiClient } from '../api';\nimport type { Storage } from '../storage';\n\nexport type RecoveryProgress =\n | { type: 'passkey-attempt' }\n | { type: 'passkey-failed'; reason: string }\n | { type: 'recovery-file-prompt' }\n | { type: 'password-prompt'; passwordHint: string | null }\n | { type: 'recovery-verifying' }\n | { type: 'rotated'; shareSetVersion: number };\n\nexport interface RecoveryFlowInput {\n userId: string;\n jwt: string;\n rpId: string;\n teeUrl: string;\n api: ApiClient;\n storage: Storage;\n onProgress?: (event: RecoveryProgress) => void;\n /** Supplies the parsed JSON contents of a user-uploaded recovery-share file, plus a way to prompt for its password. */\n promptForRecoveryFile?: () => Promise<{ value: unknown; getPassword: () => Promise<string | null> } | null>;\n /**\n * Called after a successful Flow B recovery with the NEW recovery share —\n * the old file is dead the instant this flow completes (the set rotates on\n * every recovery), so the caller MUST get this saved. Not optional to\n * ignore in a real UI: MIGRATE_SSS_RECOVERY.md §10 requires this screen to\n * block progress until the user downloads the new file or explicitly\n * acknowledges the risk.\n */\n onNewRecoveryShare?: (recoveryShare: Uint8Array, shareSetVersion: number) => Promise<void>;\n}\n\nexport interface RecoveredDeviceShare {\n deviceShare: Uint8Array;\n /**\n * Which path produced it. 'passkey-sync' shares are a COPY of the backup\n * every other synced device also holds, so callers implementing per-device\n * shares rotate after this one; 'recovery-file' already rotated the set as\n * part of recovering.\n */\n flow: 'passkey-sync' | 'recovery-file';\n}\n\n/**\n * Attempt to recover the device share on a device that has none.\n * Flow A (passkey sync) first, Flow B (recovery-share file) as fallback.\n * Throws NewDeviceError if every path is exhausted.\n */\nexport async function recoverDeviceShare(input: RecoveryFlowInput): Promise<RecoveredDeviceShare> {\n // ── Flow A: passkey sync — unchanged ──────────────────────\n const backup = await fetchWrappedShareBackup(input.api, input.jwt);\n if (backup) {\n input.onProgress?.({ type: 'passkey-attempt' });\n try {\n const prfOutput = await getPrfOutput({\n rpId: input.rpId,\n credentialId: backup.credentialId,\n prfSalt: backup.prfSalt,\n });\n const wrappingKey = await importAesKey(prfOutput);\n const deviceShare = await aesGcmDecrypt(\n wrappingKey,\n backup.wrappedDeviceShare,\n backup.iv\n );\n // Cache locally so subsequent sessions on this device skip recovery.\n await input.storage.putShare({\n userId: input.userId,\n wrappedDeviceShare: backup.wrappedDeviceShare,\n iv: backup.iv,\n unlockMethod: 'passkey',\n credentialId: backup.credentialId,\n prfSalt: backup.prfSalt,\n version: 1,\n });\n return { deviceShare, flow: 'passkey-sync' };\n } catch (e) {\n input.onProgress?.({\n type: 'passkey-failed',\n reason: e instanceof Error ? e.message : 'unknown',\n });\n // fall through to Flow B\n }\n }\n\n // ── Flow B: recovery-share file ───────────────────────────\n if (!input.promptForRecoveryFile) throw new NewDeviceError();\n input.onProgress?.({ type: 'recovery-file-prompt' });\n\n const supplied = await input.promptForRecoveryFile();\n if (!supplied) throw new NewDeviceError();\n\n const file = parseRecoveryShareFile(supplied.value);\n input.onProgress?.({ type: 'password-prompt', passwordHint: file.passwordHint });\n const password = await supplied.getPassword();\n if (!password) throw new NewDeviceError();\n\n const recoveryShare = await decryptRecoveryShareFile(file, password); // throws WrongPasswordError\n\n input.onProgress?.({ type: 'recovery-verifying' });\n const tee = new TeeClient(input.teeUrl);\n let result: { deviceShare: Uint8Array; recoveryShare: Uint8Array; shareSetVersion: number };\n try {\n // Server-verifies the reconstructed master matches this account before\n // returning anything — throws RecoveryWalletMismatchError otherwise.\n // Rotates the whole share set: the presented recovery share is spent.\n result = await tee.recoverWithShare(input.jwt, recoveryShare);\n } finally {\n zeroize(recoveryShare);\n }\n\n // The old recovery file is dead now — the caller MUST get the new one saved.\n input.onProgress?.({ type: 'rotated', shareSetVersion: result.shareSetVersion });\n await input.onNewRecoveryShare?.(result.recoveryShare, result.shareSetVersion);\n zeroize(result.recoveryShare);\n\n // caller wraps under a new passkey and opens a session\n return { deviceShare: result.deviceShare, flow: 'recovery-file' };\n}\n","import { InvalidRecoveryFileError, WrongPasswordError } from '../errors';\n\nconst PBKDF2_ITERATIONS = 600_000;\nconst FILE_VERSION = 1;\n\nexport interface PortableBackup {\n version: number;\n type: 'decane-portable-backup';\n shareSetVersion: number;\n kdf: 'pbkdf2-sha256';\n kdfParams: { iterations: number; salt: string };\n cipher: 'aes-256-gcm';\n iv: string;\n ciphertext: string; // encrypted { deviceShare, recoveryShare } (base64 each) + GCM tag\n addresses: { evm: string; solana: string };\n passwordHint: string | null;\n createdAt: string;\n}\n\nfunction b64(u: Uint8Array): string {\n let s = '';\n for (const b of u) s += String.fromCharCode(b);\n return btoa(s);\n}\nfunction unb64(s: string): Uint8Array {\n return Uint8Array.from(atob(s), (c) => c.charCodeAt(0));\n}\nfunction buf(u: Uint8Array): ArrayBuffer {\n return u.buffer.slice(u.byteOffset, u.byteOffset + u.byteLength) as ArrayBuffer;\n}\n\nasync function deriveFileKey(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey> {\n const base = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(password),\n 'PBKDF2',\n false,\n ['deriveKey']\n );\n return crypto.subtle.deriveKey(\n { name: 'PBKDF2', salt: buf(salt), iterations, hash: 'SHA-256' },\n base,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * Build the portable backup — a BEARER SECRET containing two shares (device +\n * recovery). File + password alone gives complete control of the wallet.\n * This must only ever be produced behind an explicit, warned, opt-in\n * settings action — never by default, never silently. See the export\n * warning copy requirements in MIGRATE_SSS_RECOVERY.md §10.\n */\nexport async function buildPortableBackup(\n deviceShare: Uint8Array,\n recoveryShare: Uint8Array,\n password: string,\n addresses: { evm: string; solana: string },\n shareSetVersion: number,\n passwordHint?: string\n): Promise<PortableBackup> {\n if (deviceShare.length !== 33 || recoveryShare.length !== 33) {\n throw new Error('shares must be 33 bytes');\n }\n if (password.length < 8) throw new Error('password must be at least 8 characters');\n if (passwordHint && passwordHint.trim() === password) {\n throw new Error('password hint must not be the password');\n }\n\n const plaintext = new TextEncoder().encode(\n JSON.stringify({ deviceShare: b64(deviceShare), recoveryShare: b64(recoveryShare) })\n );\n\n const salt = crypto.getRandomValues(new Uint8Array(16));\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const key = await deriveFileKey(password, salt, PBKDF2_ITERATIONS);\n const ct = new Uint8Array(\n await crypto.subtle.encrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(plaintext))\n );\n\n return {\n version: FILE_VERSION,\n type: 'decane-portable-backup',\n shareSetVersion,\n kdf: 'pbkdf2-sha256',\n kdfParams: { iterations: PBKDF2_ITERATIONS, salt: b64(salt) },\n cipher: 'aes-256-gcm',\n iv: b64(iv),\n ciphertext: b64(ct),\n addresses,\n passwordHint: passwordHint?.trim() || null,\n createdAt: new Date().toISOString(),\n };\n}\n\nexport function parsePortableBackup(json: unknown): PortableBackup {\n const f = json as Partial<PortableBackup>;\n if (\n !f ||\n f.type !== 'decane-portable-backup' ||\n f.version !== FILE_VERSION ||\n f.kdf !== 'pbkdf2-sha256' ||\n f.cipher !== 'aes-256-gcm' ||\n typeof f.iv !== 'string' ||\n typeof f.ciphertext !== 'string' ||\n typeof f.kdfParams?.salt !== 'string' ||\n typeof f.kdfParams?.iterations !== 'number' ||\n typeof f.shareSetVersion !== 'number' ||\n typeof f.addresses?.evm !== 'string' ||\n typeof f.addresses?.solana !== 'string'\n ) {\n throw new InvalidRecoveryFileError();\n }\n return f as PortableBackup;\n}\n\n/** Decrypt a portable backup. Returns both shares. Caller MUST zeroize both. */\nexport async function decryptPortableBackup(\n file: PortableBackup,\n password: string\n): Promise<{ deviceShare: Uint8Array; recoveryShare: Uint8Array }> {\n const salt = unb64(file.kdfParams.salt);\n const iv = unb64(file.iv);\n const ct = unb64(file.ciphertext);\n const key = await deriveFileKey(password, salt, file.kdfParams.iterations);\n\n let plaintext: Uint8Array;\n try {\n plaintext = new Uint8Array(\n await crypto.subtle.decrypt({ name: 'AES-GCM', iv: buf(iv) }, key, buf(ct))\n );\n } catch {\n throw new WrongPasswordError();\n }\n\n try {\n const parsed = JSON.parse(new TextDecoder().decode(plaintext)) as {\n deviceShare: string;\n recoveryShare: string;\n };\n const deviceShare = unb64(parsed.deviceShare);\n const recoveryShare = unb64(parsed.recoveryShare);\n if (deviceShare.length !== 33 || recoveryShare.length !== 33) throw new Error('bad share length');\n return { deviceShare, recoveryShare };\n } catch {\n throw new InvalidRecoveryFileError();\n } finally {\n plaintext.fill(0);\n }\n}\n\n/** Deliberately distinct from the ordinary recovery file's name — visually obvious in a downloads folder. */\nexport function portableBackupFileName(evmAddress: string): string {\n return `decane-PORTABLE-BACKUP-${evmAddress.slice(0, 8)}.json`;\n}\n","export { createDecaneConnect } from './client';\nexport { startEmailAuth, verifyEmailCode } from './auth/email';\n// Exposed so an app can run the KingsChat consent popup itself — e.g. to sign\n// the user into KingsChat before deciding whether to create a wallet — and hand\n// the token to connectWithKingsChatToken() later.\nexport { loginWithKingsChatPopup } from './auth/kingschat';\nexport type { KingsChatTokens } from './auth/kingschat';\nexport { createEthereumProvider } from './eip1193';\nexport type { Eip1193Provider, EthereumProviderOptions } from './eip1193';\n\nexport type {\n DecaneConnect,\n DecaneConnectConfig,\n ConnectResult,\n AuthProfile,\n SignMessageRequest,\n SendTransactionRequest,\n SignTypedDataRequest,\n WrappedShareMeta,\n AuthResult,\n SdkEvent,\n Chain,\n BalanceResult,\n SignedAuthorization,\n TransactionRecord,\n RecordTransactionInput,\n} from './types';\n\nexport type { RecoveryProgress } from './recovery/recoveryFlow';\nexport type { RecoveryShareFile } from './recovery/recoveryShareFile';\nexport type { PortableBackup } from './recovery/portableBackup';\n\nexport {\n DecaneConnectError,\n InvalidApiKeyError,\n OriginNotAllowedError,\n SessionExpiredError,\n UnlockRequiredError,\n UserCancelledError,\n WebAuthnNotSupportedError,\n InvalidPinError,\n CallSequenceError,\n NetworkError,\n ShareCorruptedError,\n NewDeviceError,\n ProvisioningTimeoutError,\n PromptPinNotConfiguredError,\n AttestationError,\n RecoveryFailedError,\n InvalidRecoveryFileError,\n WrongPasswordError,\n RecoveryWalletMismatchError,\n ExportNotAuthorizedError,\n ReconnectRequiredError,\n StaleDeviceShareError,\n} from './errors';\n","import React, { useEffect, useCallback, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { DecaneProvider, UnifiedWalletAccount, ChainType, ConnectMode } from \"../types\";\nimport { CSS_VARS } from \"./styles\";\nimport { WalletIcon, ChainIconStack } from \"./icons\";\n\ninterface WalletSelectorProps {\n provider: DecaneProvider;\n open: boolean;\n onClose: () => void;\n onConnect: (wallet: UnifiedWalletAccount, preference?: ChainType) => void;\n theme?: \"light\" | \"dark\" | \"auto\";\n networks?: \"evm\" | \"solana\" | \"tron\" | \"bitcoin\" | \"all\";\n mode?: ConnectMode;\n socialAuthMethods?: (\"google\" | \"email\" | \"kingschat\")[];\n onGoogleSignIn?: () => Promise<void>;\n onKingsChatSignIn?: () => Promise<void>;\n onEmailStart?: (email: string) => Promise<{ codeRequired: true }>;\n onEmailVerify?: (email: string, code: string) => Promise<void>;\n /** Button text for the developer's own auth system, e.g. \"Continue with Acme Inc\". Omitted entirely when not configured. */\n customAuthLabel?: string;\n onCustomAuthSignIn?: () => Promise<void>;\n /** Returning user on this device — offer the passkey instead of sign-in. */\n canUsePasskey?: boolean;\n /** Address shown alongside the passkey button, so they know who they're resuming as. */\n passkeyAddress?: string | null;\n onPasskeySignIn?: () => Promise<unknown>;\n}\n\ntype FilterType = \"all\" | \"evm\" | \"solana\" | \"tron\" | \"bitcoin\";\n\nconst FONT_URL =\n \"https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap\";\n\nfunction injectTokens(theme: \"light\" | \"dark\" | \"auto\"): void {\n let resolved: \"light\" | \"dark\";\n if (theme === \"auto\") {\n resolved = window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n } else {\n resolved = theme;\n }\n let styleEl = document.getElementById(\"decane-tokens\") as HTMLStyleElement | null;\n if (!styleEl) {\n styleEl = document.createElement(\"style\");\n styleEl.id = \"decane-tokens\";\n document.head.appendChild(styleEl);\n }\n styleEl.textContent = `:root { ${CSS_VARS[resolved]} }`;\n}\n\nfunction injectFont(): void {\n if (document.getElementById(\"decane-font\")) return;\n const link = document.createElement(\"link\");\n link.id = \"decane-font\";\n link.rel = \"stylesheet\";\n link.href = FONT_URL;\n document.head.appendChild(link);\n}\n\n\ninterface WalletRowProps {\n wallet: UnifiedWalletAccount;\n onClick: () => void;\n}\n\nfunction WalletRow({ wallet, onClick }: WalletRowProps) {\n const [hovered, setHovered] = useState(false);\n const [focused, setFocused] = useState(false);\n\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n width: \"100%\",\n padding: \"11px 14px\",\n background: hovered ? \"var(--dc-surface-hover)\" : \"transparent\",\n border: focused ? \"1px solid var(--dc-border-accent)\" : \"1px solid transparent\",\n borderRadius: 10,\n cursor: \"pointer\",\n textAlign: \"left\",\n transition: \"background 0.12s, border-color 0.12s\",\n outline: \"none\",\n fontFamily: \"inherit\",\n }}\n >\n <WalletIcon src={wallet.icon || undefined} name={wallet.name} size={38} />\n <span style={{ flex: 1, fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\", letterSpacing: \"-0.01em\" }}>\n {wallet.name}\n </span>\n <ChainIconStack support={wallet.chainSupport} size={16} />\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\"\n style={{ color: hovered ? \"var(--dc-text-secondary)\" : \"var(--dc-text-muted)\", flexShrink: 0, transition: \"color 0.12s\" }}>\n <path d=\"M5 2.5L9.5 7L5 11.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n );\n}\n\ninterface FilterTabProps {\n label: string;\n active: boolean;\n onClick: () => void;\n}\n\nfunction FilterTab({ label, active, onClick }: FilterTabProps) {\n const [hovered, setHovered] = useState(false);\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n flex: 1,\n padding: \"6px 8px\",\n borderRadius: 8,\n border: active ? \"1px solid var(--dc-border-accent)\" : \"1px solid transparent\",\n background: active ? \"rgba(245,200,0,0.1)\" : hovered ? \"var(--dc-surface-hover)\" : \"transparent\",\n color: active ? \"var(--dc-accent)\" : \"var(--dc-text-muted)\",\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n cursor: \"pointer\",\n transition: \"all 0.12s\",\n fontFamily: \"inherit\",\n outline: \"none\",\n }}\n >\n {label}\n </button>\n );\n}\n\ninterface ChainOptionProps {\n label: string;\n description: string;\n badges: React.ReactNode;\n onClick: () => void;\n}\n\nfunction ChainOption({ label, description, badges, onClick }: ChainOptionProps) {\n const [hovered, setHovered] = useState(false);\n return (\n <button\n onClick={onClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-start\",\n gap: 6,\n width: \"100%\",\n padding: \"14px 16px\",\n background: hovered ? \"var(--dc-surface-hover)\" : \"var(--dc-surface)\",\n border: hovered ? \"1px solid var(--dc-border-accent)\" : \"1px solid var(--dc-border)\",\n borderRadius: 12,\n cursor: \"pointer\",\n textAlign: \"left\",\n transition: \"all 0.12s\",\n fontFamily: \"inherit\",\n outline: \"none\",\n }}\n >\n {badges}\n <span style={{ fontSize: 13, fontWeight: 700, color: \"var(--dc-text)\" }}>{label}</span>\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", lineHeight: 1.4 }}>{description}</span>\n </button>\n );\n}\n\ntype MainView = \"wallets\" | \"social\";\ntype EmailStep = \"input\" | \"code\";\n\nfunction hasSocialMode(mode?: ConnectMode) {\n return (\n mode === \"all\" || mode === \"social\" ||\n mode === \"evm+social\" || mode === \"solana+social\" ||\n mode === \"tron+social\" || mode === \"evm+tron+social\"\n );\n}\n\nexport function WalletSelector({\n provider,\n open,\n onClose,\n onConnect,\n theme = \"auto\",\n networks = \"all\",\n mode = \"wallets\",\n socialAuthMethods = [\"google\", \"email\"],\n onGoogleSignIn,\n onKingsChatSignIn,\n onEmailStart,\n onEmailVerify,\n customAuthLabel,\n onCustomAuthSignIn,\n canUsePasskey = false,\n passkeyAddress = null,\n onPasskeySignIn,\n}: WalletSelectorProps) {\n const showSocial = hasSocialMode(mode);\n const showWallets = mode !== \"social\";\n\n // Social leads when it's available: it's the path for users who don't have a\n // wallet yet, and they're the ones who need the obvious default. Anyone with\n // a wallet installed already knows to go looking for it.\n const [view, setView] = useState<MainView>(showSocial ? \"social\" : \"wallets\");\n const [search, setSearch] = useState(\"\");\n const [filter, setFilter] = useState<FilterType>(\"all\");\n const [pendingWallet, setPendingWallet] = useState<UnifiedWalletAccount | null>(null);\n\n // Social form state\n const [emailStep, setEmailStep] = useState<EmailStep>(\"input\");\n const [emailVal, setEmailVal] = useState(\"\");\n const [codeVal, setCodeVal] = useState(\"\");\n const [socialLoad, setSocialLoad] = useState(false);\n const [socialErr, setSocialErr] = useState(\"\");\n // Returning users see the passkey alone; the sign-in methods stay one click\n // away for anyone who actually wants a different account.\n const [showOtherMethods, setShowOtherMethods] = useState(false);\n const passkeyFirst = canUsePasskey && !!onPasskeySignIn && !showOtherMethods;\n\n useEffect(() => {\n if (!open) return;\n injectFont();\n injectTokens(theme);\n if (theme !== \"auto\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const handler = () => injectTokens(\"auto\");\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [open, theme]);\n\n useEffect(() => {\n if (!open) {\n setSearch(\"\");\n setFilter(\"all\");\n setPendingWallet(null);\n setView(showSocial ? \"social\" : \"wallets\");\n setEmailStep(\"input\");\n setEmailVal(\"\");\n setCodeVal(\"\");\n setSocialErr(\"\");\n setShowOtherMethods(false);\n return;\n }\n return () => {\n document.getElementById(\"decane-tokens\")?.remove();\n };\n }, [open, showWallets]);\n\n async function handlePasskeySignIn() {\n if (!onPasskeySignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n try {\n await onPasskeySignIn();\n // The context closes the modal on success; nothing to do here.\n } catch (e: unknown) {\n // Cancelling the OS prompt is not a failure worth shouting about — but\n // a genuine failure needs to leave the standard methods reachable, or\n // the user is stuck staring at a passkey button that doesn't work.\n const err = e as Error;\n if (err?.name !== \"UserCancelledError\") {\n setSocialErr(err?.message ?? \"Passkey sign-in failed\");\n setShowOtherMethods(true);\n }\n setSocialLoad(false);\n }\n }\n\n async function handlePasskeyClick() {\n void handlePasskeySignIn();\n }\n\n async function handleGoogleClick() {\n if (!onGoogleSignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n try { await onGoogleSignIn(); }\n catch (e: unknown) { setSocialErr((e as Error).message); setSocialLoad(false); }\n }\n\n async function handleKingsChatClick() {\n if (!onKingsChatSignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n // Google navigates away and never returns, so it leaves the loading state\n // set. This one resolves in place when the popup closes, so it has to be\n // cleared on success too or the modal stays stuck mid-flight.\n try { await onKingsChatSignIn(); }\n catch (e: unknown) { setSocialErr((e as Error).message); }\n finally { setSocialLoad(false); }\n }\n\n async function handleCustomAuthClick() {\n if (!onCustomAuthSignIn) return;\n setSocialLoad(true); setSocialErr(\"\");\n try { await onCustomAuthSignIn(); }\n catch (e: unknown) { setSocialErr((e as Error).message); setSocialLoad(false); }\n }\n\n async function handleEmailStart(e: React.FormEvent) {\n e.preventDefault();\n if (!onEmailStart) return;\n setSocialLoad(true); setSocialErr(\"\");\n try {\n await onEmailStart(emailVal);\n setEmailStep(\"code\");\n } catch (e: unknown) {\n setSocialErr((e as Error).message);\n } finally {\n setSocialLoad(false);\n }\n }\n\n async function handleEmailVerify(e: React.FormEvent) {\n e.preventDefault();\n if (!onEmailVerify) return;\n setSocialLoad(true); setSocialErr(\"\");\n try {\n await onEmailVerify(emailVal, codeVal);\n // context closes the selector on success\n } catch (e: unknown) {\n setSocialErr((e as Error).message);\n } finally {\n setSocialLoad(false);\n }\n }\n\n const handleKey = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n if (pendingWallet) {\n setPendingWallet(null);\n } else {\n onClose();\n }\n }\n },\n [onClose, pendingWallet],\n );\n\n useEffect(() => {\n if (!open) return;\n document.addEventListener(\"keydown\", handleKey);\n return () => document.removeEventListener(\"keydown\", handleKey);\n }, [open, handleKey]);\n\n if (!open) return null;\n\n const q = search.toLowerCase();\n\n // Pre-filter by configured networks before anything else\n const networkWallets = provider.wallets.filter((w) => {\n const cs = w.chainSupport as string[];\n if (networks === \"evm\") return cs.includes(\"evm\");\n if (networks === \"solana\") return cs.includes(\"solana\");\n if (networks === \"tron\") return cs.includes(\"tron\");\n if (networks === \"bitcoin\") return cs.includes(\"bitcoin\");\n return true;\n });\n\n const baseWallets =\n filter === \"evm\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"evm\"))\n : filter === \"solana\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"solana\"))\n : filter === \"tron\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"tron\"))\n : filter === \"bitcoin\"\n ? networkWallets.filter((w) => (w.chainSupport as string[]).includes(\"bitcoin\"))\n : networkWallets;\n const filtered = q\n ? baseWallets.filter((w) => w.name.toLowerCase().includes(q))\n : baseWallets;\n\n function handleWalletClick(wallet: UnifiedWalletAccount) {\n const cs = wallet.chainSupport as string[];\n const isMulti = cs.length >= 2;\n if (isMulti && networks === \"all\") {\n // Show chain picker only when the dApp supports all network types\n setPendingWallet(wallet);\n } else {\n const preference: ChainType | undefined =\n networks === \"evm\" ? \"evm\" :\n networks === \"solana\" ? \"solana\" :\n networks === \"tron\" ? \"tron\" :\n networks === \"bitcoin\" ? \"bitcoin\" :\n undefined;\n onConnect(wallet, preference);\n onClose();\n }\n }\n\n function handleChainChoice(preference?: ChainType) {\n if (!pendingWallet) return;\n onConnect(pendingWallet, preference);\n onClose();\n }\n\n const modal = (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Connect wallet\"\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 9999,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"16px\",\n // Same fallback chain as SocialWalletModal — without it, this modal\n // drops to the browser default serif whenever the token block hasn't\n // been injected, while the social modal still lands on system-ui.\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n }}\n >\n {/* Backdrop */}\n <div\n onClick={() => {\n if (pendingWallet) {\n setPendingWallet(null);\n } else {\n onClose();\n }\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n background: \"var(--dc-bg-overlay)\",\n backdropFilter: \"blur(8px)\",\n WebkitBackdropFilter: \"blur(8px)\",\n }}\n />\n\n {/* Modal card */}\n <div\n style={{\n position: \"relative\",\n background: \"var(--dc-bg)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 20,\n width: \"100%\",\n maxWidth: 400,\n maxHeight: \"85vh\",\n display: \"flex\",\n flexDirection: \"column\",\n boxShadow: \"0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n overflow: \"hidden\",\n }}\n >\n {/* Gold top accent */}\n <div\n style={{\n height: 2,\n background: \"linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)\",\n }}\n />\n\n {pendingWallet ? (\n /* ── Chain picker step ───────────────────────────────────────── */\n <>\n {/* Header */}\n <div style={{ padding: \"18px 20px 16px\", display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <button\n onClick={() => setPendingWallet(null)}\n aria-label=\"Back\"\n style={{\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 8,\n width: 28,\n height: 28,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: \"var(--dc-text-muted)\",\n flexShrink: 0,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M7.5 2L3 6l4.5 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n <h2 style={{ margin: 0, fontSize: 16, fontWeight: 800, color: \"var(--dc-text)\", letterSpacing: \"-0.02em\" }}>\n Choose networks\n </h2>\n <button\n onClick={onClose}\n aria-label=\"Close\"\n style={{\n marginLeft: \"auto\",\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 8,\n width: 28,\n height: 28,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n color: \"var(--dc-text-muted)\",\n flexShrink: 0,\n fontFamily: \"inherit\",\n padding: 0,\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n\n {/* Wallet preview */}\n <div\n style={{\n margin: \"0 20px 16px\",\n padding: \"12px 14px\",\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 12,\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n }}\n >\n <WalletIcon src={pendingWallet.icon || undefined} name={pendingWallet.name} size={36} />\n <div>\n <div style={{ fontSize: 14, fontWeight: 700, color: \"var(--dc-text)\" }}>{pendingWallet.name}</div>\n <div style={{ fontSize: 11, color: \"var(--dc-text-muted)\", marginTop: 2 }}>Multi-chain wallet detected</div>\n </div>\n </div>\n\n {/* Options — dynamic per wallet's chainSupport */}\n <div style={{ padding: \"0 12px 20px\", display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n {(pendingWallet.chainSupport as string[]).includes(\"evm\") && (\n <ChainOption\n label=\"EVM networks\"\n description=\"Connect your Ethereum-compatible address only\"\n badges={<ChainIconStack support={[\"evm\"]} size={18} />}\n onClick={() => handleChainChoice(\"evm\")}\n />\n )}\n {(pendingWallet.chainSupport as string[]).includes(\"solana\") && (\n <ChainOption\n label=\"Solana network\"\n description=\"Connect your Solana address only\"\n badges={<ChainIconStack support={[\"solana\"]} size={18} />}\n onClick={() => handleChainChoice(\"solana\")}\n />\n )}\n {(pendingWallet.chainSupport as string[]).includes(\"tron\") && (\n <ChainOption\n label=\"Tron network\"\n description=\"Connect your Tron address only\"\n badges={<ChainIconStack support={[\"tron\"]} size={18} />}\n onClick={() => handleChainChoice(\"tron\")}\n />\n )}\n {(pendingWallet.chainSupport as string[]).includes(\"bitcoin\") && (\n <ChainOption\n label=\"Bitcoin network\"\n description=\"Connect your Bitcoin address only\"\n badges={<ChainIconStack support={[\"bitcoin\"]} size={18} />}\n onClick={() => handleChainChoice(\"bitcoin\")}\n />\n )}\n <ChainOption\n label=\"All networks\"\n description=\"Connect all supported addresses together\"\n badges={<ChainIconStack support={pendingWallet.chainSupport} size={18} />}\n onClick={() => handleChainChoice(undefined)}\n />\n </div>\n </>\n ) : (\n /* ── Wallet list / Social sign-in ────────────────────────────── */\n <>\n {/* Header */}\n <div style={{ padding: \"18px 20px 0\" }}>\n <div style={{ display: \"flex\", alignItems: \"flex-start\", justifyContent: \"space-between\", marginBottom: 14 }}>\n <div>\n <h2 style={{ margin: 0, fontSize: 17, fontWeight: 800, color: \"var(--dc-text)\", letterSpacing: \"-0.02em\", lineHeight: 1.2 }}>\n {view === \"social\" ? \"Sign in\" : \"Connect wallet\"}\n </h2>\n {view === \"wallets\" && networkWallets.length > 0 && (\n <p style={{ margin: \"3px 0 0\", fontSize: 12, color: \"var(--dc-text-muted)\" }}>\n {networkWallets.length} wallet{networkWallets.length !== 1 ? \"s\" : \"\"} detected\n </p>\n )}\n </div>\n <button\n onClick={onClose}\n aria-label=\"Close\"\n style={{\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n cursor: \"pointer\",\n padding: 0,\n width: 28,\n height: 28,\n borderRadius: 8,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"var(--dc-text-muted)\",\n flexShrink: 0,\n transition: \"background 0.12s, color 0.12s\",\n fontFamily: \"inherit\",\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = \"var(--dc-surface-hover)\";\n (e.currentTarget as HTMLButtonElement).style.color = \"var(--dc-text)\";\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.background = \"var(--dc-surface)\";\n (e.currentTarget as HTMLButtonElement).style.color = \"var(--dc-text-muted)\";\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n\n {/* Tab bar — only when both wallets and social are available */}\n {showWallets && showSocial && (\n <div style={{ display: \"flex\", gap: 4, marginBottom: 14, background: \"var(--dc-surface)\", borderRadius: 10, padding: 3 }}>\n {([\"social\", \"wallets\"] as MainView[]).map((v) => (\n <button\n key={v}\n onClick={() => setView(v)}\n style={{\n flex: 1,\n padding: \"7px 0\",\n borderRadius: 8,\n border: \"none\",\n background: view === v ? \"var(--dc-bg)\" : \"transparent\",\n color: view === v ? \"var(--dc-text)\" : \"var(--dc-text-muted)\",\n fontSize: 13,\n fontWeight: view === v ? 700 : 500,\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n boxShadow: view === v ? \"0 1px 4px rgba(0,0,0,0.2)\" : \"none\",\n transition: \"all 0.15s\",\n }}\n >\n {v === \"wallets\" ? \"Wallet\" : \"Sign in\"}\n </button>\n ))}\n </div>\n )}\n\n {/* Filter tabs — only on wallet view, only when multi-network */}\n {view === \"wallets\" && networks === \"all\" && (\n <div style={{ display: \"flex\", gap: 4, marginBottom: 10 }}>\n <FilterTab label=\"All\" active={filter === \"all\"} onClick={() => setFilter(\"all\")} />\n <FilterTab label=\"EVM\" active={filter === \"evm\"} onClick={() => setFilter(\"evm\")} />\n <FilterTab label=\"Solana\" active={filter === \"solana\"} onClick={() => setFilter(\"solana\")} />\n {provider.tronWallets && provider.tronWallets.length > 0 && (\n <FilterTab label=\"Tron\" active={filter === \"tron\"} onClick={() => setFilter(\"tron\")} />\n )}\n {provider.bitcoinWallets && provider.bitcoinWallets.length > 0 && (\n <FilterTab label=\"Bitcoin\" active={filter === \"bitcoin\"} onClick={() => setFilter(\"bitcoin\")} />\n )}\n </div>\n )}\n\n {/* Search — wallet view only */}\n {view === \"wallets\" && (\n <div style={{ position: \"relative\", marginBottom: 10 }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\"\n style={{ position: \"absolute\", left: 10, top: \"50%\", transform: \"translateY(-50%)\", color: \"var(--dc-text-muted)\", pointerEvents: \"none\" }}>\n <circle cx=\"6\" cy=\"6\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.4\" />\n <path d=\"M9.5 9.5L12 12\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" />\n </svg>\n <input\n type=\"text\"\n placeholder=\"Search wallets…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n style={{\n width: \"100%\",\n background: \"var(--dc-surface)\",\n border: \"1px solid var(--dc-border)\",\n borderRadius: 10,\n color: \"var(--dc-text)\",\n fontSize: 13,\n padding: \"8px 12px 8px 32px\",\n outline: \"none\",\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n transition: \"border-color 0.15s\",\n boxSizing: \"border-box\",\n }}\n onFocus={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border-accent)\"; }}\n onBlur={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border)\"; }}\n />\n </div>\n )}\n </div>\n\n {/* ── Social sign-in panel ─────────────────────────────── */}\n {view === \"social\" && (\n <div style={{ padding: \"4px 20px 24px\", display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n {socialErr && (\n <div style={{ background: \"rgba(204,51,0,0.1)\", border: \"1px solid var(--dc-danger)\", borderRadius: 8, padding: \"9px 12px\", fontSize: 12, color: \"var(--dc-danger)\" }}>\n {socialErr}\n </div>\n )}\n\n {/* Returning user: their passkey is proof enough — no Google\n redirect, no email code, just the one prompt. */}\n {passkeyFirst && (\n <>\n <button\n onClick={handlePasskeyClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"13px 16px\",\n background: \"var(--dc-accent)\", border: \"none\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n color: \"var(--dc-accent-text)\", fontSize: 14, fontWeight: 700,\n fontFamily: \"inherit\", opacity: socialLoad ? 0.6 : 1,\n }}\n >\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M6 21v-1a4 4 0 0 1 4-4h1\" />\n <path d=\"M17 15v6M14.5 18h5\" />\n </svg>\n {socialLoad ? \"Verifying…\" : \"Continue with passkey\"}\n </button>\n\n {passkeyAddress && (\n <div style={{ textAlign: \"center\", fontSize: 12, color: \"var(--dc-text-muted)\" }}>\n Resuming {passkeyAddress.slice(0, 6)}…{passkeyAddress.slice(-4)}\n </div>\n )}\n\n <button\n onClick={() => { setShowOtherMethods(true); setSocialErr(\"\"); }}\n disabled={socialLoad}\n style={{\n background: \"none\", border: \"none\", padding: \"6px 0\",\n color: \"var(--dc-text-muted)\", fontSize: 12.5,\n cursor: socialLoad ? \"not-allowed\" : \"pointer\", fontFamily: \"inherit\",\n textDecoration: \"underline\", textUnderlineOffset: 3,\n }}\n >\n Use a different account\n </button>\n </>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"google\") && (\n <button\n onClick={handleGoogleClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"11px 16px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\",\n fontFamily: \"inherit\", transition: \"border-color 0.12s, background 0.12s\",\n opacity: socialLoad ? 0.6 : 1,\n }}\n onMouseEnter={(e) => { if (!socialLoad) (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border-accent)\"; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border)\"; }}\n >\n {/* Google G */}\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.875 2.684-6.615z\" fill=\"#4285F4\"/>\n <path d=\"M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z\" fill=\"#34A853\"/>\n <path d=\"M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z\" fill=\"#FBBC05\"/>\n <path d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z\" fill=\"#EA4335\"/>\n </svg>\n {socialLoad ? \"Redirecting…\" : \"Continue with Google\"}\n </button>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"kingschat\") && onKingsChatSignIn && (\n <button\n onClick={handleKingsChatClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"11px 16px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\",\n fontFamily: \"inherit\", transition: \"border-color 0.12s, background 0.12s\",\n opacity: socialLoad ? 0.6 : 1,\n }}\n onMouseEnter={(e) => { if (!socialLoad) (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border-accent)\"; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border)\"; }}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"9\" cy=\"9\" r=\"9\" fill=\"var(--dc-accent)\" />\n <path d=\"M5.5 4.5h1.9v3.6l3.1-3.6h2.3l-3.3 3.8 3.5 5.2h-2.3l-2.5-3.8-.8.9v2.9H5.5V4.5z\" fill=\"var(--dc-accent-text)\" />\n </svg>\n {socialLoad ? \"Waiting for KingsChat…\" : \"Continue with KingsChat\"}\n </button>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"google\") && socialAuthMethods.includes(\"email\") && (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", whiteSpace: \"nowrap\" }}>or continue with email</span>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n </div>\n )}\n\n {!passkeyFirst && socialAuthMethods.includes(\"email\") && (\n emailStep === \"input\" ? (\n <form onSubmit={handleEmailStart} style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <input\n type=\"email\"\n placeholder=\"your@email.com\"\n value={emailVal}\n onChange={(e) => setEmailVal(e.target.value)}\n required\n style={{\n width: \"100%\", padding: \"10px 12px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text)\", fontSize: 13,\n fontFamily: \"inherit\", outline: \"none\", boxSizing: \"border-box\",\n }}\n onFocus={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border-accent)\"; }}\n onBlur={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border)\"; }}\n />\n <button\n type=\"submit\"\n disabled={socialLoad || !emailVal}\n style={{\n width: \"100%\", padding: \"10px 16px\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10,\n fontSize: 14, fontWeight: 700, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\", opacity: socialLoad || !emailVal ? 0.6 : 1,\n }}\n >\n {socialLoad ? \"Sending…\" : \"Send code\"}\n </button>\n </form>\n ) : (\n <form onSubmit={handleEmailVerify} style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <p style={{ margin: 0, fontSize: 12, color: \"var(--dc-text-muted)\", textAlign: \"center\" }}>\n Code sent to <strong style={{ color: \"var(--dc-text)\" }}>{emailVal}</strong>\n </p>\n <input\n type=\"text\"\n placeholder=\"6-digit code\"\n value={codeVal}\n onChange={(e) => setCodeVal(e.target.value.replace(/\\D/g, \"\").slice(0, 6))}\n autoFocus\n required\n style={{\n width: \"100%\", padding: \"10px 12px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text)\", fontSize: 20,\n fontFamily: \"monospace\", letterSpacing: 8, textAlign: \"center\",\n outline: \"none\", boxSizing: \"border-box\",\n }}\n onFocus={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border-accent)\"; }}\n onBlur={(e) => { e.currentTarget.style.borderColor = \"var(--dc-border)\"; }}\n />\n <div style={{ display: \"flex\", gap: 8 }}>\n <button\n type=\"button\"\n onClick={() => { setEmailStep(\"input\"); setCodeVal(\"\"); setSocialErr(\"\"); }}\n style={{\n flex: 1, padding: \"9px 0\",\n background: \"transparent\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text-muted)\",\n fontSize: 13, cursor: \"pointer\", fontFamily: \"inherit\",\n }}\n >\n Back\n </button>\n <button\n type=\"submit\"\n disabled={socialLoad || codeVal.length < 6}\n style={{\n flex: 2, padding: \"9px 0\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10,\n fontSize: 13, fontWeight: 700,\n cursor: socialLoad || codeVal.length < 6 ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\",\n opacity: socialLoad || codeVal.length < 6 ? 0.6 : 1,\n }}\n >\n {socialLoad ? \"Verifying…\" : \"Verify\"}\n </button>\n </div>\n </form>\n )\n )}\n\n {!passkeyFirst && customAuthLabel && onCustomAuthSignIn && (\n <>\n {(socialAuthMethods.includes(\"google\") || socialAuthMethods.includes(\"email\")) && (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", whiteSpace: \"nowrap\" }}>or</span>\n <div style={{ flex: 1, height: 1, background: \"var(--dc-border)\" }} />\n </div>\n )}\n <button\n onClick={handleCustomAuthClick}\n disabled={socialLoad}\n style={{\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 10,\n width: \"100%\", padding: \"11px 16px\",\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, cursor: socialLoad ? \"not-allowed\" : \"pointer\",\n fontSize: 14, fontWeight: 600, color: \"var(--dc-text)\",\n fontFamily: \"inherit\", transition: \"border-color 0.12s, background 0.12s\",\n opacity: socialLoad ? 0.6 : 1,\n }}\n onMouseEnter={(e) => { if (!socialLoad) (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border-accent)\"; }}\n onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.borderColor = \"var(--dc-border)\"; }}\n >\n {socialLoad ? \"Connecting…\" : customAuthLabel}\n </button>\n </>\n )}\n </div>\n )}\n\n {/* ── Wallet list ──────────────────────────────────────── */}\n {view === \"wallets\" && (\n <div style={{ overflowY: \"auto\", flex: 1, padding: \"0 12px 20px\" }}>\n {filtered.length > 0 ? (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n {filtered.map((w) => (\n <WalletRow key={w.id} wallet={w} onClick={() => handleWalletClick(w)} />\n ))}\n </div>\n ) : (\n <div style={{ textAlign: \"center\", padding: \"32px 16px\", color: \"var(--dc-text-muted)\", fontSize: 13 }}>\n {q ? `No wallets matching \"${q}\"` : \"No wallets detected\"}\n </div>\n )}\n </div>\n )}\n\n {/* Footer */}\n {view === \"wallets\" && (\n <div style={{ padding: \"10px 20px 14px\", borderTop: \"1px solid var(--dc-border)\", textAlign: \"center\", fontSize: 11, color: \"var(--dc-text-muted)\" }}>\n Don't see your wallet? Make sure it's installed and unlocked\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n\n return createPortal(modal, document.body);\n}\n","export const tokens = {\n // ── Gold palette ──────────────────────────────────────────────────────────\n gold: {\n 50: \"#FFFDF0\",\n 100: \"#FFF8D6\",\n 200: \"#FFEF99\",\n 300: \"#FFE04D\",\n 400: \"#F5C800\", // primary gold — buttons, accents\n 500: \"#D4A800\", // darker gold — hover states\n 600: \"#A37F00\", // deep gold — borders, active\n 700: \"#7A5E00\",\n 800: \"#4D3B00\",\n 900: \"#261D00\",\n },\n\n // ── Black / dark palette ──────────────────────────────────────────────────\n black: {\n 0: \"#FFFFFF\",\n 50: \"#F9F9F7\",\n 100: \"#F0EFEB\",\n 200: \"#DDDCDA\",\n 300: \"#BDBBB8\",\n 400: \"#8A8884\",\n 500: \"#5C5A57\",\n 600: \"#3D3C39\",\n 700: \"#2A2927\",\n 800: \"#1A1917\",\n 900: \"#0D0D0B\",\n 950: \"#070706\",\n },\n\n // ── Semantic tokens — light mode ──────────────────────────────────────────\n light: {\n bg: \"#FFFFFF\",\n bgOverlay: \"rgba(0, 0, 0, 0.55)\",\n surface: \"#F9F9F7\",\n surfaceHover: \"#F0EFEB\",\n border: \"#DDDCDA\",\n borderAccent: \"#F5C800\",\n text: \"#0D0D0B\",\n textSecondary: \"#5C5A57\",\n textMuted: \"#8A8884\",\n accent: \"#F5C800\",\n accentHover: \"#D4A800\",\n accentText: \"#0D0D0B\",\n badgeEvm: \"#1A1917\",\n badgeEvmText: \"#F5C800\",\n badgeSolana: \"#F5C800\",\n badgeSolanaText: \"#0D0D0B\",\n danger: \"#CC3300\",\n },\n\n // ── Semantic tokens — dark mode ───────────────────────────────────────────\n dark: {\n bg: \"#0D0D0B\",\n bgOverlay: \"rgba(0, 0, 0, 0.75)\",\n surface: \"#1A1917\",\n surfaceHover: \"#2A2927\",\n border: \"#3D3C39\",\n borderAccent: \"#F5C800\",\n text: \"#F9F9F7\",\n textSecondary: \"#BDBBB8\",\n textMuted: \"#8A8884\",\n accent: \"#F5C800\",\n accentHover: \"#FFE04D\",\n accentText: \"#0D0D0B\",\n badgeEvm: \"#F5C800\",\n badgeEvmText: \"#0D0D0B\",\n badgeSolana: \"#1A1917\",\n badgeSolanaText: \"#F5C800\",\n danger: \"#FF5533\",\n },\n} as const;\n\n// Font stacks — used by the modal container and all child elements via var()\nexport const FONT_SANS = \"'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\";\nexport const FONT_MONO = \"'JetBrains Mono', 'Fira Code', ui-monospace, monospace\";\n\nexport const CSS_VARS = {\n light: `\n --dc-font-sans: ${FONT_SANS};\n --dc-font-mono: ${FONT_MONO};\n --dc-bg: ${tokens.light.bg};\n --dc-bg-overlay: ${tokens.light.bgOverlay};\n --dc-surface: ${tokens.light.surface};\n --dc-surface-hover: ${tokens.light.surfaceHover};\n --dc-border: ${tokens.light.border};\n --dc-border-accent: ${tokens.light.borderAccent};\n --dc-text: ${tokens.light.text};\n --dc-text-secondary: ${tokens.light.textSecondary};\n --dc-text-muted: ${tokens.light.textMuted};\n --dc-accent: ${tokens.light.accent};\n --dc-accent-hover: ${tokens.light.accentHover};\n --dc-accent-text: ${tokens.light.accentText};\n --dc-badge-evm: ${tokens.light.badgeEvm};\n --dc-badge-evm-text: ${tokens.light.badgeEvmText};\n --dc-badge-sol: ${tokens.light.badgeSolana};\n --dc-badge-sol-text: ${tokens.light.badgeSolanaText};\n --dc-danger: ${tokens.light.danger};\n `,\n dark: `\n --dc-font-sans: ${FONT_SANS};\n --dc-font-mono: ${FONT_MONO};\n --dc-bg: ${tokens.dark.bg};\n --dc-bg-overlay: ${tokens.dark.bgOverlay};\n --dc-surface: ${tokens.dark.surface};\n --dc-surface-hover: ${tokens.dark.surfaceHover};\n --dc-border: ${tokens.dark.border};\n --dc-border-accent: ${tokens.dark.borderAccent};\n --dc-text: ${tokens.dark.text};\n --dc-text-secondary: ${tokens.dark.textSecondary};\n --dc-text-muted: ${tokens.dark.textMuted};\n --dc-accent: ${tokens.dark.accent};\n --dc-accent-hover: ${tokens.dark.accentHover};\n --dc-accent-text: ${tokens.dark.accentText};\n --dc-badge-evm: ${tokens.dark.badgeEvm};\n --dc-badge-evm-text: ${tokens.dark.badgeEvmText};\n --dc-badge-sol: ${tokens.dark.badgeSolana};\n --dc-badge-sol-text: ${tokens.dark.badgeSolanaText};\n --dc-danger: ${tokens.dark.danger};\n `,\n} as const;\n","import React from \"react\";\nimport type { ChainType } from \"../types\";\n\n// ── Decane brand ──────────────────────────────────────────────────────────────\n// Official Decane mark — a gold mascot glyph. The drop-shadow filter id is made\n// unique per instance (React.useId) so rendering the logo more than once on a\n// page — e.g. the modal header and footer — doesn't collide on a shared id.\n\nexport function DecaneMark({ size = 28, muted = false }: { size?: number; muted?: boolean }) {\n const uid = React.useId().replace(/:/g, \"\");\n const fid = `dl_logo_f_${uid}`;\n const w = size;\n const h = Math.round((size * 64) / 68);\n return (\n <svg\n width={w}\n height={h}\n viewBox=\"0 0 68 64\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden\n style={{ display: \"block\", flexShrink: 0, opacity: muted ? 0.55 : 1 }}\n >\n <g filter={`url(#${fid})`}>\n <path d=\"M32.8031 10.2986C33.1971 9.68929 34.0886 9.68929 34.4826 10.2986L35.7297 12.2273C36.1599 12.8926 35.6823 13.7703 34.89 13.7703H32.3957C31.6034 13.7703 31.1257 12.8926 31.556 12.2273L32.8031 10.2986Z\" fill=\"#FFD700\"/>\n <path d=\"M16.6095 20.8798C25.5139 8.28662 47.0755 12.2298 51.4641 20.5617C54.9502 24.0479 55.2167 30.8018 55.2167 30.8018C55.2167 30.8018 58.8421 37.862 57.4428 41.3601C55.7891 56.7522 13.9381 57.0066 11.3304 41.3601C9.93111 37.0351 13.4293 31.3744 13.4293 31.3744C13.4293 31.3744 12.9841 27.2404 16.6095 20.8798Z\" fill=\"#FFD700\"/>\n <ellipse cx=\"48.9999\" cy=\"39.2669\" rx=\"2.38155\" ry=\"1.89957\" transform=\"rotate(-22.395 48.9999 39.2669)\" fill=\"#FFE55F\" fillOpacity=\"0.45\"/>\n <ellipse cx=\"18.9785\" cy=\"39.2671\" rx=\"2.38155\" ry=\"1.89958\" transform=\"rotate(15.8893 18.9785 39.2671)\" fill=\"#FFE55F\" fillOpacity=\"0.26\"/>\n <path d=\"M43.5977 30.7344C43.1619 30.7344 42.6943 30.9653 42.3027 31.4824C41.9107 32.0001 41.6388 32.7597 41.6387 33.6406C41.6387 34.5217 41.9107 35.2821 42.3027 35.7998C42.6943 36.3168 43.1619 36.5479 43.5977 36.5479C44.0332 36.5477 44.5002 36.3166 44.8916 35.7998C45.2837 35.2821 45.5557 34.5217 45.5557 33.6406C45.5556 32.7597 45.2836 32.0001 44.8916 31.4824C44.5002 30.9656 44.0333 30.7345 43.5977 30.7344Z\" fill=\"#1A1A1A\" stroke=\"#F4EBBC\" strokeWidth=\"2\"/>\n <path d=\"M25.1514 30.7344C25.5871 30.7344 26.0547 30.9653 26.4463 31.4824C26.8383 32.0001 27.1103 32.7597 27.1104 33.6406C27.1104 34.5217 26.8384 35.2821 26.4463 35.7998C26.0547 36.3168 25.5871 36.5479 25.1514 36.5479C24.7158 36.5477 24.2489 36.3166 23.8574 35.7998C23.4654 35.2821 23.1934 34.5217 23.1934 33.6406C23.1934 32.7597 23.4654 32.0001 23.8574 31.4824C24.2489 30.9656 24.7157 30.7345 25.1514 30.7344Z\" fill=\"#1A1A1A\" stroke=\"#F4EBBC\" strokeWidth=\"2\"/>\n <path d=\"M26.0107 41.6924C26.0107 41.6924 28.0937 46.399 34.759 46.399C41.008 46.399 43.3109 41.6924 43.3109 41.6924\" stroke=\"#1A1A1A\" strokeLinecap=\"round\"/>\n </g>\n <defs>\n <filter id={fid} x=\"0.589964\" y=\"0.334365\" width=\"66.5809\" height=\"62.9754\" filterUnits=\"userSpaceOnUse\" colorInterpolationFilters=\"sRGB\">\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\"/>\n <feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/>\n <feOffset dx=\"-0.501447\" dy=\"0.401157\"/>\n <feGaussianBlur stdDeviation=\"4.95429\"/>\n <feComposite in2=\"hardAlpha\" operator=\"out\"/>\n <feColorMatrix type=\"matrix\" values=\"0 0 0 0 0.996078 0 0 0 0 0.996078 0 0 0 0 0.996078 0 0 0 0.12 0\"/>\n <feBlend mode=\"normal\" in2=\"BackgroundImageFix\" result=\"effect1_dropShadow\"/>\n <feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"effect1_dropShadow\" result=\"shape\"/>\n </filter>\n </defs>\n </svg>\n );\n}\n\nexport function DecaneWordmark({ size = 15, muted = false }: { size?: number; muted?: boolean }) {\n return (\n <span\n style={{\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n fontWeight: 800,\n fontSize: size,\n letterSpacing: \"-0.03em\",\n color: muted ? \"var(--dc-text-muted)\" : \"var(--dc-text)\",\n lineHeight: 1,\n }}\n >\n decane\n </span>\n );\n}\n\nexport function DecaneLogo({ size = 20, muted = false }: { size?: number; muted?: boolean }) {\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: size * 0.34 }}>\n <DecaneMark size={size} muted={muted} />\n <DecaneWordmark size={size * 0.78} muted={muted} />\n </span>\n );\n}\n\ninterface WalletIconProps {\n src?: string;\n name: string;\n size?: number;\n}\n\nexport function WalletIcon({ src, name, size = 36 }: WalletIconProps) {\n if (src) {\n return (\n <img\n src={src}\n alt={name}\n width={size}\n height={size}\n style={{ borderRadius: size * 0.25, objectFit: \"cover\", flexShrink: 0 }}\n />\n );\n }\n\n const initial = name.charAt(0).toUpperCase();\n return (\n <div\n style={{\n width: size,\n height: size,\n borderRadius: size * 0.25,\n background: \"linear-gradient(135deg, var(--dc-surface-hover), var(--dc-surface-active, var(--dc-surface-hover)))\",\n border: \"1px solid var(--dc-border)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: size * 0.38,\n fontWeight: 800,\n color: \"var(--dc-accent)\",\n flexShrink: 0,\n fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n letterSpacing: \"-0.02em\",\n }}\n >\n {initial}\n </div>\n );\n}\n\nfunction EthCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#627EEA\" />\n {/* Ethereum diamond */}\n <polygon points=\"8,2.5 11.5,8 8,9.8 4.5,8\" fill=\"white\" fillOpacity=\"0.9\" />\n <polygon points=\"8,9.8 11.5,8 8,13.5\" fill=\"white\" fillOpacity=\"0.6\" />\n <polygon points=\"8,9.8 4.5,8 8,13.5\" fill=\"white\" fillOpacity=\"0.8\" />\n <polygon points=\"8,2.5 8,9.8 4.5,8\" fill=\"white\" fillOpacity=\"0.6\" />\n </svg>\n );\n}\n\nfunction SolCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#9945FF\" />\n {/* Solana 3 bars */}\n <rect x=\"4\" y=\"4.5\" width=\"7\" height=\"1.5\" rx=\"0.75\" fill=\"white\" fillOpacity=\"0.95\" />\n <rect x=\"4\" y=\"7.25\" width=\"7\" height=\"1.5\" rx=\"0.75\" fill=\"white\" fillOpacity=\"0.95\" />\n <rect x=\"4\" y=\"10\" width=\"5.5\" height=\"1.5\" rx=\"0.75\" fill=\"white\" fillOpacity=\"0.95\" />\n </svg>\n );\n}\n\nfunction TronCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#FF0013\" />\n {/* Play triangle */}\n <polygon points=\"6,4.5 12,8 6,11.5\" fill=\"white\" fillOpacity=\"0.95\" />\n </svg>\n );\n}\n\nfunction BitcoinCircle({ size }: { size: number }) {\n const s = size;\n return (\n <svg width={s} height={s} viewBox=\"0 0 16 16\" fill=\"none\">\n <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#F7931A\" />\n {/* ₿ symbol */}\n <text\n x=\"8.3\"\n y=\"11.5\"\n textAnchor=\"middle\"\n fontSize=\"8\"\n fontWeight=\"700\"\n fill=\"white\"\n fontFamily=\"Arial, system-ui\"\n >\n ₿\n </text>\n </svg>\n );\n}\n\nfunction ChainCircleIcon({ chain, size }: { chain: ChainType; size: number }) {\n switch (chain) {\n case \"evm\": return <EthCircle size={size} />;\n case \"solana\": return <SolCircle size={size} />;\n case \"tron\": return <TronCircle size={size} />;\n case \"bitcoin\": return <BitcoinCircle size={size} />;\n }\n}\n\nconst CHAIN_ORDER: ChainType[] = [\"evm\", \"solana\", \"tron\", \"bitcoin\"];\n\ninterface ChainIconStackProps {\n support: readonly string[];\n size?: number;\n}\n\nexport function ChainIconStack({ support, size = 16 }: ChainIconStackProps) {\n const ordered = CHAIN_ORDER.filter((c) => support.includes(c));\n if (ordered.length === 0) return null;\n const overlap = Math.round(size * 0.35);\n\n return (\n <div style={{ display: \"flex\", alignItems: \"center\", flexShrink: 0 }}>\n {ordered.map((chain, i) => (\n <div\n key={chain}\n style={{\n marginLeft: i === 0 ? 0 : `-${overlap}px`,\n zIndex: ordered.length - i,\n position: \"relative\",\n borderRadius: \"50%\",\n lineHeight: 0,\n boxShadow: i > 0 ? `0 0 0 1.5px var(--dc-bg, #fff)` : undefined,\n }}\n >\n <ChainCircleIcon chain={chain} size={size} />\n </div>\n ))}\n </div>\n );\n}\n","import React, { useCallback, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { CSS_VARS } from \"./styles\";\nimport { DecaneMark, DecaneWordmark } from \"./icons\";\nimport type { SocialAuthState } from \"./context\";\nimport { fetchBalance, formatBalanceDisplay } from \"../social/balance\";\nimport type { RecoveryShareFile } from \"../social/recovery/recoveryShareFile\";\nimport type { PortableBackup } from \"../social/recovery/portableBackup\";\n\ninterface SocialWalletModalProps {\n open: boolean;\n onClose: () => void;\n theme?: \"light\" | \"dark\" | \"auto\";\n socialAuth: SocialAuthState;\n onUnlock: () => Promise<void>;\n onDisconnect: () => Promise<void>;\n onGoogleSignIn: () => Promise<void>;\n onKingsChatSignIn?: () => Promise<void>;\n onEmailStart: (email: string) => Promise<{ codeRequired: true }>;\n onEmailVerify: (email: string, code: string) => Promise<void>;\n authMethods?: Array<\"google\" | \"email\" | \"kingschat\">;\n customAuthLabel?: string;\n onCustomAuthSignIn?: () => Promise<void>;\n // Returning user on this device: offer a one-tap passkey reconnect instead of\n // forcing a full Google/email sign-in after a reload.\n canUsePasskey?: boolean;\n passkeyAddress?: string | null;\n onPasskeySignIn?: () => Promise<unknown>;\n onRotateShares: (opts: { password: string; passwordHint?: string }) => Promise<RecoveryShareFile>;\n onExportPortableBackup: (opts: { password: string; passwordHint?: string }) => Promise<PortableBackup>;\n rpcUrls?: Record<string, string>;\n chains?: string[];\n}\n\nfunction injectTokens(theme: \"light\" | \"dark\" | \"auto\"): void {\n const resolved: \"light\" | \"dark\" =\n theme === \"auto\"\n ? window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\"\n : theme;\n let el = document.getElementById(\"decane-tokens\") as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = \"decane-tokens\";\n document.head.appendChild(el);\n }\n el.textContent = `:root { ${CSS_VARS[resolved]} }`;\n}\n\nfunction countdown(expiresAt: number): string {\n const secs = Math.max(0, Math.round((expiresAt - Date.now()) / 1000));\n return `${Math.floor(secs / 60)}m ${String(secs % 60).padStart(2, \"0\")}s`;\n}\n\nfunction downloadJson(data: unknown, filename: string) {\n const blob = new Blob([JSON.stringify(data, null, 2)], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n}\n\nfunction CopyButton({ value }: { value: string }) {\n const [copied, setCopied] = useState(false);\n async function copy() {\n await navigator.clipboard.writeText(value).catch(() => {});\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n }\n return (\n <button\n onClick={copy}\n style={{\n background: \"none\", border: \"none\", cursor: \"pointer\",\n color: copied ? \"var(--dc-accent)\" : \"var(--dc-text-muted)\",\n fontSize: 11, fontFamily: \"inherit\", padding: \"2px 6px\",\n borderRadius: 5, transition: \"color 0.15s\",\n }}\n >\n {copied ? \"✓\" : \"copy\"}\n </button>\n );\n}\n\n// ── Balances ─────────────────────────────────────────────────────────────────\n// Fetched client-side, read-only, no wallet interaction needed. Dynamic\n// imports keep ethers/@solana-web3 out of the initial bundle for consumers\n// who never open this modal.\n\ntype BalanceState = { loading: boolean; value: string | null; symbol: string };\n\n// Thin wrapper over the shared fetchBalance() so the modal display and the\n// public getBalance()/useSocialBalance() can never drift apart.\nfunction useBalance(\n kind: \"evm\" | \"solana\",\n address: string | undefined,\n chain: string | undefined,\n rpcUrls: Record<string, string> | undefined,\n): BalanceState {\n const [state, setState] = useState<BalanceState>({ loading: false, value: null, symbol: kind === \"evm\" ? \"ETH\" : \"SOL\" });\n\n useEffect(() => {\n if (!address || !chain) return;\n let cancelled = false;\n setState((s) => ({ ...s, loading: true }));\n\n fetchBalance({ kind, address, chain, rpcUrls })\n .then((b) => { if (!cancelled) setState({ loading: false, value: b.formatted, symbol: b.symbol }); })\n .catch(() => { if (!cancelled) setState({ loading: false, value: null, symbol: kind === \"evm\" ? \"ETH\" : \"SOL\" }); });\n\n return () => { cancelled = true; };\n }, [kind, address, chain, rpcUrls]);\n\n return state;\n}\n\nfunction AddressRow({\n label, address, kind, chain, rpcUrls,\n}: {\n label: string; address: string; kind: \"evm\" | \"solana\"; chain?: string; rpcUrls?: Record<string, string>;\n}) {\n const balance = useBalance(kind, address, chain, rpcUrls);\n const short = `${address.slice(0, 8)}…${address.slice(-6)}`;\n return (\n <div style={{\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, padding: \"10px 14px\", marginBottom: 8,\n }}>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", marginBottom: 5 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: \"var(--dc-text-muted)\", letterSpacing: \"0.06em\", textTransform: \"uppercase\" }}>\n {label}\n </span>\n <span style={{ fontSize: 11, fontFamily: \"monospace\", color: \"var(--dc-text)\" }}>\n {balance.loading ? \"…\" : `${formatBalanceDisplay(balance.value)} ${balance.symbol}`}\n </span>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", gap: 8 }}>\n <span style={{ fontSize: 13, fontFamily: \"monospace\", color: \"var(--dc-text)\", letterSpacing: \"0.02em\" }}>\n {short}\n </span>\n <CopyButton value={address} />\n </div>\n </div>\n );\n}\n\n// ── Sign-in view (not connected, or connected-but-no-live-session) ────────────\n\nfunction SignInView({\n onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, authMethods, resumeHint,\n customAuthLabel, onCustomAuthSignIn,\n canUsePasskey, passkeyAddress, onPasskeySignIn,\n}: {\n onGoogleSignIn: () => Promise<void>;\n onKingsChatSignIn?: () => Promise<void>;\n onEmailStart: (email: string) => Promise<{ codeRequired: true }>;\n onEmailVerify: (email: string, code: string) => Promise<void>;\n authMethods: Array<\"google\" | \"email\" | \"kingschat\">;\n resumeHint?: string;\n customAuthLabel?: string;\n onCustomAuthSignIn?: () => Promise<void>;\n canUsePasskey?: boolean;\n passkeyAddress?: string | null;\n onPasskeySignIn?: () => Promise<unknown>;\n}) {\n const [googleLoading, setGoogleLoading] = useState(false);\n const [kingsChatLoading, setKingsChatLoading] = useState(false);\n const [email, setEmail] = useState(\"\");\n const [code, setCode] = useState(\"\");\n const [emailSent, setEmailSent] = useState(false);\n const [emailLoading, setEmailLoading] = useState(false);\n const [customLoading, setCustomLoading] = useState(false);\n const [passkeyLoading, setPasskeyLoading] = useState(false);\n const [showOtherMethods, setShowOtherMethods] = useState(false);\n const [error, setError] = useState(\"\");\n\n // Returning user on this device: a passkey is proof enough — lead with it and\n // keep the full sign-in one tap away as a fallback. This is what turns a\n // page reload from \"sign in again with Google\" into a single biometric.\n const passkeyFirst = !!canUsePasskey && !!onPasskeySignIn && !showOtherMethods;\n\n async function handlePasskey() {\n if (!onPasskeySignIn) return;\n setError(\"\"); setPasskeyLoading(true);\n try {\n await onPasskeySignIn();\n // Success closes the modal via the context; nothing to do here.\n } catch (e) {\n const err = e as Error & { name?: string };\n // A cancelled OS prompt isn't worth an error banner, but a real failure\n // must leave the other methods reachable rather than trapping the user.\n if (err?.name !== \"UserCancelledError\") {\n setError(err?.message ?? \"Passkey sign-in failed\");\n setShowOtherMethods(true);\n }\n setPasskeyLoading(false);\n }\n }\n\n async function handleGoogle() {\n setError(\"\"); setGoogleLoading(true);\n try { await onGoogleSignIn(); }\n catch (e) { setError((e as Error).message); setGoogleLoading(false); }\n }\n async function handleKingsChat() {\n if (!onKingsChatSignIn) return;\n setError(\"\"); setKingsChatLoading(true);\n // Unlike Google (a full-page redirect that never returns), this resolves in\n // place when the popup closes — so the loading state has to be cleared on\n // success as well as failure.\n try { await onKingsChatSignIn(); }\n catch (e) { setError((e as Error).message); }\n finally { setKingsChatLoading(false); }\n }\n async function handleEmailStart(e: React.FormEvent) {\n e.preventDefault();\n setError(\"\"); setEmailLoading(true);\n try { await onEmailStart(email); setEmailSent(true); }\n catch (e2) { setError((e2 as Error).message); }\n finally { setEmailLoading(false); }\n }\n async function handleEmailVerify(e: React.FormEvent) {\n e.preventDefault();\n setError(\"\"); setEmailLoading(true);\n try { await onEmailVerify(email, code); }\n catch (e2) { setError((e2 as Error).message); }\n finally { setEmailLoading(false); }\n }\n async function handleCustomAuth() {\n if (!onCustomAuthSignIn) return;\n setError(\"\"); setCustomLoading(true);\n try { await onCustomAuthSignIn(); }\n catch (e) { setError((e as Error).message); }\n finally { setCustomLoading(false); }\n }\n\n const inputStyle: React.CSSProperties = {\n width: \"100%\", background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, color: \"var(--dc-text)\", padding: \"9px 12px\", fontSize: 13,\n outline: \"none\", fontFamily: \"inherit\", boxSizing: \"border-box\",\n };\n\n return (\n <div style={{ padding: \"0 16px 16px\" }}>\n {resumeHint && !passkeyFirst && (\n <div style={{ fontSize: 12, color: \"var(--dc-text-muted)\", marginBottom: 12, textAlign: \"center\" }}>\n Welcome back — sign in again to resume {resumeHint}\n </div>\n )}\n\n {/* Passkey-first: one biometric tap resumes the session, no full sign-in. */}\n {passkeyFirst && (\n <div>\n <div style={{ fontSize: 12, color: \"var(--dc-text-muted)\", marginBottom: 12, textAlign: \"center\" }}>\n Welcome back — unlock to resume{passkeyAddress ? ` ${passkeyAddress.slice(0, 6)}…${passkeyAddress.slice(-4)}` : \"\"}\n </div>\n <button\n onClick={handlePasskey}\n disabled={passkeyLoading}\n style={{\n width: \"100%\", padding: \"11px 0\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10, fontSize: 13, fontWeight: 700,\n cursor: passkeyLoading ? \"not-allowed\" : \"pointer\", opacity: passkeyLoading ? 0.7 : 1,\n fontFamily: \"inherit\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 7,\n }}\n >\n {passkeyLoading ? \"Verifying…\" : \"🔓 Continue with passkey\"}\n </button>\n <button\n onClick={() => setShowOtherMethods(true)}\n style={{\n width: \"100%\", marginTop: 10, background: \"none\", border: \"none\",\n color: \"var(--dc-text-muted)\", fontSize: 12, cursor: \"pointer\", fontFamily: \"inherit\",\n }}\n >\n Use email or Google instead\n </button>\n {error && <div style={{ marginTop: 10, fontSize: 12, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>}\n </div>\n )}\n\n {!passkeyFirst && authMethods.includes(\"google\") && (\n <button\n onClick={handleGoogle}\n disabled={googleLoading}\n style={{\n width: \"100%\", padding: \"10px 0\", marginBottom: 10,\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10, fontSize: 13, fontWeight: 700,\n cursor: googleLoading ? \"not-allowed\" : \"pointer\", opacity: googleLoading ? 0.7 : 1,\n fontFamily: \"inherit\",\n }}\n >\n {googleLoading ? \"Redirecting…\" : \"Continue with Google\"}\n </button>\n )}\n {!passkeyFirst && authMethods.includes(\"kingschat\") && onKingsChatSignIn && (\n <button\n onClick={handleKingsChat}\n disabled={kingsChatLoading}\n style={{\n width: \"100%\", padding: \"10px 0\", marginBottom: 10,\n background: \"var(--dc-surface)\", color: \"var(--dc-text)\",\n border: \"1px solid var(--dc-border)\", borderRadius: 10, fontSize: 13, fontWeight: 700,\n cursor: kingsChatLoading ? \"not-allowed\" : \"pointer\", opacity: kingsChatLoading ? 0.7 : 1,\n fontFamily: \"inherit\",\n }}\n >\n {kingsChatLoading ? \"Waiting for KingsChat…\" : \"Continue with KingsChat\"}\n </button>\n )}\n {!passkeyFirst && authMethods.includes(\"email\") && (\n <>\n {authMethods.includes(\"google\") && (\n <div style={{ textAlign: \"center\", color: \"var(--dc-text-muted)\", fontSize: 12, margin: \"10px 0\" }}>— or —</div>\n )}\n {!emailSent ? (\n <form onSubmit={handleEmailStart} style={{ display: \"flex\", gap: 8 }}>\n <input\n type=\"email\" required placeholder=\"your@email.com\" value={email}\n onChange={(e) => setEmail(e.target.value)} style={{ ...inputStyle, flex: 1 }}\n />\n <button type=\"submit\" disabled={emailLoading} style={{\n padding: \"0 16px\", background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, color: \"var(--dc-text)\", fontSize: 13, cursor: \"pointer\", fontFamily: \"inherit\",\n }}>\n {emailLoading ? \"…\" : \"Send code\"}\n </button>\n </form>\n ) : (\n <form onSubmit={handleEmailVerify} style={{ display: \"flex\", gap: 8 }}>\n <input\n placeholder=\"6-digit code\" value={code} maxLength={6} autoFocus\n onChange={(e) => setCode(e.target.value.replace(/\\D/g, \"\"))}\n style={{ ...inputStyle, flex: 1, letterSpacing: 4, textAlign: \"center\" }}\n />\n <button type=\"submit\" disabled={emailLoading} style={{\n padding: \"0 16px\", background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 8, fontSize: 13, fontWeight: 700, cursor: \"pointer\", fontFamily: \"inherit\",\n }}>\n {emailLoading ? \"…\" : \"Verify\"}\n </button>\n </form>\n )}\n </>\n )}\n {!passkeyFirst && customAuthLabel && onCustomAuthSignIn && (\n <>\n {(authMethods.includes(\"google\") || authMethods.includes(\"email\")) && (\n <div style={{ textAlign: \"center\", color: \"var(--dc-text-muted)\", fontSize: 12, margin: \"10px 0\" }}>— or —</div>\n )}\n <button\n onClick={handleCustomAuth}\n disabled={customLoading}\n style={{\n width: \"100%\", padding: \"10px 0\",\n background: \"var(--dc-surface)\", color: \"var(--dc-text)\",\n border: \"1px solid var(--dc-border)\", borderRadius: 10, fontSize: 13, fontWeight: 600,\n cursor: customLoading ? \"not-allowed\" : \"pointer\", opacity: customLoading ? 0.7 : 1,\n fontFamily: \"inherit\",\n }}\n >\n {customLoading ? \"Connecting…\" : customAuthLabel}\n </button>\n </>\n )}\n {error && (\n <div style={{ marginTop: 10, fontSize: 12, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>\n )}\n </div>\n );\n}\n\n// ── Recovery section (only shown when unlocked) ────────────────────────────────\n\nfunction RecoverySection({\n addresses, onRotateShares, onExportPortableBackup,\n}: {\n addresses: { evm?: string; solana?: string } | null;\n onRotateShares: (opts: { password: string; passwordHint?: string }) => Promise<RecoveryShareFile>;\n onExportPortableBackup: (opts: { password: string; passwordHint?: string }) => Promise<PortableBackup>;\n}) {\n const [expanded, setExpanded] = useState(false);\n const [mode, setMode] = useState<\"share\" | \"portable\" | null>(null);\n const [password, setPassword] = useState(\"\");\n const [passwordHint, setPasswordHint] = useState(\"\");\n const [confirmed, setConfirmed] = useState(false);\n const [busy, setBusy] = useState(false);\n const [result, setResult] = useState<{ kind: \"share\" | \"portable\"; version: number } | null>(null);\n const [error, setError] = useState(\"\");\n\n function reset() {\n setMode(null); setPassword(\"\"); setPasswordHint(\"\"); setConfirmed(false); setError(\"\");\n }\n\n async function handleGenerate() {\n if (!addresses?.evm || !mode) return;\n if (password.length < 8) { setError(\"Password must be at least 8 characters.\"); return; }\n if (mode === \"portable\" && !confirmed) { setError(\"Confirm you understand the risk first.\"); return; }\n\n setBusy(true); setError(\"\");\n try {\n if (mode === \"share\") {\n const file = await onRotateShares({ password, passwordHint: passwordHint || undefined });\n downloadJson(file, `decane-recovery-${addresses.evm.slice(0, 8)}.json`);\n setResult({ kind: \"share\", version: file.shareSetVersion });\n } else {\n const file = await onExportPortableBackup({ password, passwordHint: passwordHint || undefined });\n downloadJson(file, `decane-full-recovery-${addresses.evm.slice(0, 8)}.json`);\n setResult({ kind: \"portable\", version: file.shareSetVersion });\n }\n reset();\n } catch (e) {\n setError((e as Error).message);\n } finally {\n setBusy(false);\n }\n }\n\n const inputStyle: React.CSSProperties = {\n width: \"100%\", background: \"var(--dc-bg)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, color: \"var(--dc-text)\", padding: \"8px 10px\", fontSize: 12,\n outline: \"none\", fontFamily: \"inherit\", boxSizing: \"border-box\",\n };\n const btnStyle: React.CSSProperties = {\n padding: \"8px 12px\", borderRadius: 8, fontSize: 12, fontWeight: 700,\n cursor: \"pointer\", fontFamily: \"inherit\", border: \"none\",\n };\n\n return (\n <div style={{ margin: \"0 16px 14px\", border: \"1px solid var(--dc-border)\", borderRadius: 10, overflow: \"hidden\" }}>\n <button\n onClick={() => setExpanded((v) => !v)}\n style={{\n width: \"100%\", padding: \"10px 14px\", background: \"var(--dc-surface)\", border: \"none\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", cursor: \"pointer\",\n fontFamily: \"inherit\",\n }}\n >\n <span style={{ fontSize: 12, fontWeight: 700, color: \"var(--dc-text)\" }}>Recovery</span>\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\" }}>{expanded ? \"▲\" : \"▼\"}</span>\n </button>\n\n {expanded && (\n <div style={{ padding: \"12px 14px\", borderTop: \"1px solid var(--dc-border)\" }}>\n <p style={{ fontSize: 11, color: \"var(--dc-text-muted)\", lineHeight: 1.5, margin: \"0 0 10px\" }}>\n Save a recovery file so you can restore this wallet on a new device.\n </p>\n\n {!mode && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <button onClick={() => { reset(); setMode(\"share\"); }} style={{ ...btnStyle, background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\" }}>\n Generate recovery-share file\n </button>\n <button onClick={() => { reset(); setMode(\"portable\"); }} style={{ ...btnStyle, background: \"transparent\", border: \"1px solid var(--dc-border)\", color: \"var(--dc-text)\" }}>\n Generate full recovery file\n </button>\n </div>\n )}\n\n {mode === \"share\" && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <p style={{ fontSize: 11, color: \"var(--dc-text-muted)\", margin: 0 }}>\n One share — useless alone, safe to keep in a password manager or cloud drive.\n Generating a new one invalidates any previous recovery-share file.\n </p>\n <input type=\"password\" placeholder=\"Password (min 8 chars)\" value={password} onChange={(e) => setPassword(e.target.value)} style={inputStyle} />\n <input placeholder=\"Password hint (optional)\" value={passwordHint} onChange={(e) => setPasswordHint(e.target.value)} style={inputStyle} />\n {error && <div style={{ fontSize: 11, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>}\n <div style={{ display: \"flex\", gap: 8 }}>\n <button onClick={handleGenerate} disabled={busy} style={{ ...btnStyle, flex: 1, background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\" }}>\n {busy ? \"Generating…\" : \"Generate & download\"}\n </button>\n <button onClick={reset} style={{ ...btnStyle, background: \"transparent\", border: \"1px solid var(--dc-border)\", color: \"var(--dc-text-muted)\" }}>Cancel</button>\n </div>\n </div>\n )}\n\n {mode === \"portable\" && (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div style={{\n background: \"rgba(255,85,51,0.08)\", border: \"1px solid rgba(255,85,51,0.3)\",\n borderRadius: 8, padding: \"8px 10px\", fontSize: 11, color: \"#ff9977\", lineHeight: 1.5,\n }}>\n <strong style={{ display: \"block\", marginBottom: 3, color: \"#ff5533\" }}>This file controls your wallet</strong>\n Contains two shares — file plus password gives complete control. Keep it offline,\n not a cloud drive. This also invalidates your current recovery-share file.\n </div>\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6, fontSize: 11, color: \"var(--dc-text)\" }}>\n <input type=\"checkbox\" checked={confirmed} onChange={(e) => setConfirmed(e.target.checked)} style={{ width: \"auto\" }} />\n I understand this is a bearer secret\n </label>\n <input type=\"password\" placeholder=\"Password (min 8 chars)\" value={password} onChange={(e) => setPassword(e.target.value)} style={inputStyle} />\n <input placeholder=\"Password hint (optional)\" value={passwordHint} onChange={(e) => setPasswordHint(e.target.value)} style={inputStyle} />\n {error && <div style={{ fontSize: 11, color: \"var(--dc-danger, #ff5533)\" }}>{error}</div>}\n <div style={{ display: \"flex\", gap: 8 }}>\n <button onClick={handleGenerate} disabled={busy || !confirmed} style={{ ...btnStyle, flex: 1, background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\" }}>\n {busy ? \"Generating…\" : \"Generate & download\"}\n </button>\n <button onClick={reset} style={{ ...btnStyle, background: \"transparent\", border: \"1px solid var(--dc-border)\", color: \"var(--dc-text-muted)\" }}>Cancel</button>\n </div>\n </div>\n )}\n\n {result && (\n <div style={{ marginTop: 10, fontSize: 11, color: \"var(--dc-text-muted)\", lineHeight: 1.5 }}>\n {result.kind === \"share\" ? \"Recovery-share file\" : \"Full recovery file\"} downloaded — share\n set is now version {result.version}. Any previous recovery file no longer works.\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ── Main modal ─────────────────────────────────────────────────────────────────\n\nexport function SocialWalletModal({\n open,\n onClose,\n theme = \"auto\",\n socialAuth,\n onUnlock,\n onDisconnect,\n onGoogleSignIn,\n onKingsChatSignIn,\n onEmailStart,\n onEmailVerify,\n authMethods = [\"google\", \"email\"],\n customAuthLabel,\n onCustomAuthSignIn,\n canUsePasskey,\n passkeyAddress,\n onPasskeySignIn,\n onRotateShares,\n onExportPortableBackup,\n rpcUrls,\n chains,\n}: SocialWalletModalProps) {\n const [timer, setTimer] = useState(\"\");\n const [unlocking, setUnlocking] = useState(false);\n const [disconnecting, setDisconnecting] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n injectTokens(theme);\n if (theme !== \"auto\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const h = () => injectTokens(\"auto\");\n mq.addEventListener(\"change\", h);\n return () => mq.removeEventListener(\"change\", h);\n }, [open, theme]);\n\n useEffect(() => {\n if (!socialAuth.sessionExpiresAt) { setTimer(\"\"); return; }\n setTimer(countdown(socialAuth.sessionExpiresAt));\n const id = setInterval(() => setTimer(countdown(socialAuth.sessionExpiresAt!)), 1000);\n return () => clearInterval(id);\n }, [socialAuth.sessionExpiresAt]);\n\n const handleKey = useCallback((e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n }, [onClose]);\n\n useEffect(() => {\n if (!open) return;\n document.addEventListener(\"keydown\", handleKey);\n return () => document.removeEventListener(\"keydown\", handleKey);\n }, [open, handleKey]);\n\n if (!open) return null;\n\n // unlock() ALWAYS requires a fresh, live JWT (to open a TEE session) — and\n // JWTs are deliberately never persisted, so there is no legitimate \"just\n // unlock\" path once socialAuth.needsReconnect is true. Route that state\n // into a real sign-in instead of a call that can only fail.\n async function handleUnlock() {\n setUnlocking(true);\n try { await onUnlock(); } finally { setUnlocking(false); }\n }\n async function handleDisconnect() {\n setDisconnecting(true);\n try { await onDisconnect(); onClose(); } finally { setDisconnecting(false); }\n }\n\n const evmChain = chains?.find((c) => c.startsWith(\"evm:\")) ?? \"evm:11155111\";\n const solChain = chains?.find((c) => c.startsWith(\"solana:\")) ?? \"solana:mainnet\";\n\n const showSignIn = !socialAuth.addresses || socialAuth.needsReconnect;\n\n const modal = (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Social wallet\"\n style={{\n position: \"fixed\", inset: 0, zIndex: 9999,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n padding: 16, fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n }}\n >\n {/* Backdrop */}\n <div\n onClick={onClose}\n style={{\n position: \"absolute\", inset: 0,\n background: \"var(--dc-bg-overlay)\",\n backdropFilter: \"blur(8px)\", WebkitBackdropFilter: \"blur(8px)\",\n }}\n />\n\n {/* Card */}\n <div style={{\n position: \"relative\",\n background: \"var(--dc-bg)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 20, width: \"100%\", maxWidth: 380,\n maxHeight: \"90vh\", overflowY: \"auto\",\n boxShadow: \"0 24px 64px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)\",\n }}>\n {/* Gold accent */}\n <div style={{\n height: 2, position: \"sticky\", top: 0, zIndex: 1,\n background: \"linear-gradient(90deg, transparent, var(--dc-accent) 30%, var(--dc-accent) 70%, transparent)\",\n }} />\n\n {/* Header */}\n <div style={{ padding: \"18px 20px 16px\", display: \"flex\", alignItems: \"center\", gap: 11 }}>\n <DecaneMark size={38} />\n <div style={{ flex: 1 }}>\n <div style={{ display: \"flex\", alignItems: \"baseline\", gap: 6 }}>\n <DecaneWordmark size={15} />\n <span style={{ fontSize: 13, fontWeight: 700, color: \"var(--dc-text-muted)\", letterSpacing: \"-0.01em\" }}>\n wallet\n </span>\n </div>\n <div style={{ fontSize: 11, color: \"var(--dc-text-muted)\", marginTop: 2 }}>\n Non-custodial · key split three ways\n </div>\n </div>\n <button\n onClick={onClose}\n style={{\n background: \"var(--dc-surface)\", border: \"1px solid var(--dc-border)\",\n borderRadius: 8, width: 28, height: 28, cursor: \"pointer\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n color: \"var(--dc-text-muted)\", flexShrink: 0, padding: 0,\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M1.5 1.5L10.5 10.5M10.5 1.5L1.5 10.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n\n {showSignIn ? (\n <SignInView\n onGoogleSignIn={onGoogleSignIn}\n onKingsChatSignIn={onKingsChatSignIn}\n onEmailStart={onEmailStart}\n onEmailVerify={onEmailVerify}\n authMethods={authMethods}\n resumeHint={socialAuth.needsReconnect ? \"your wallet\" : undefined}\n customAuthLabel={customAuthLabel}\n onCustomAuthSignIn={onCustomAuthSignIn}\n canUsePasskey={canUsePasskey}\n passkeyAddress={passkeyAddress}\n onPasskeySignIn={onPasskeySignIn}\n />\n ) : (\n <>\n {/* Status bar */}\n <div style={{\n margin: \"0 16px 14px\",\n padding: \"8px 14px\",\n background: socialAuth.isUnlocked ? \"rgba(18,183,106,0.08)\" : \"rgba(245,200,0,0.08)\",\n border: `1px solid ${socialAuth.isUnlocked ? \"rgba(18,183,106,0.2)\" : \"rgba(245,200,0,0.2)\"}`,\n borderRadius: 10,\n display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\",\n }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span style={{\n width: 7, height: 7, borderRadius: \"50%\", flexShrink: 0,\n background: socialAuth.isUnlocked ? \"#12b76a\" : \"var(--dc-accent)\",\n boxShadow: `0 0 6px ${socialAuth.isUnlocked ? \"#12b76a\" : \"var(--dc-accent)\"}`,\n }} />\n <span style={{\n fontSize: 12, fontWeight: 700,\n color: socialAuth.isUnlocked ? \"#12b76a\" : \"var(--dc-accent)\",\n }}>\n {socialAuth.isUnlocked ? \"Unlocked\" : \"Locked\"}\n </span>\n </div>\n {socialAuth.isUnlocked && timer && (\n <span style={{ fontSize: 11, color: \"var(--dc-text-muted)\", fontFamily: \"monospace\" }}>\n expires {timer}\n </span>\n )}\n </div>\n\n {/* Addresses + balances */}\n <div style={{ padding: \"0 16px 14px\" }}>\n {socialAuth.addresses?.evm && (\n <AddressRow label=\"EVM (Ethereum, Base, …)\" address={socialAuth.addresses.evm} kind=\"evm\" chain={evmChain} rpcUrls={rpcUrls} />\n )}\n {socialAuth.addresses?.solana && (\n <AddressRow label=\"Solana\" address={socialAuth.addresses.solana} kind=\"solana\" chain={solChain} rpcUrls={rpcUrls} />\n )}\n </div>\n\n {/* Recovery — only meaningful once unlocked (needs an active TEE session) */}\n {socialAuth.isUnlocked && (\n <RecoverySection\n addresses={socialAuth.addresses}\n onRotateShares={onRotateShares}\n onExportPortableBackup={onExportPortableBackup}\n />\n )}\n\n {/* Actions */}\n <div style={{\n padding: \"14px 16px\", borderTop: \"1px solid var(--dc-border)\",\n display: \"flex\", gap: 8,\n }}>\n {!socialAuth.isUnlocked && (\n <button\n onClick={handleUnlock}\n disabled={unlocking}\n style={{\n flex: 1, padding: \"10px 0\",\n background: \"var(--dc-accent)\", color: \"var(--dc-accent-text)\",\n border: \"none\", borderRadius: 10,\n fontSize: 13, fontWeight: 700, cursor: unlocking ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\", opacity: unlocking ? 0.7 : 1,\n }}\n >\n {unlocking ? \"Unlocking…\" : \"🔓 Unlock wallet\"}\n </button>\n )}\n <button\n onClick={handleDisconnect}\n disabled={disconnecting}\n style={{\n flex: socialAuth.isUnlocked ? 1 : 0,\n padding: \"10px 16px\",\n background: \"transparent\", border: \"1px solid var(--dc-border)\",\n borderRadius: 10, color: \"var(--dc-text-muted)\",\n fontSize: 13, cursor: disconnecting ? \"not-allowed\" : \"pointer\",\n fontFamily: \"inherit\", opacity: disconnecting ? 0.7 : 1,\n whiteSpace: \"nowrap\",\n }}\n >\n {disconnecting ? \"Signing out…\" : \"Sign out\"}\n </button>\n </div>\n </>\n )}\n\n {/* Brand footer */}\n <div style={{\n padding: \"11px 16px\", borderTop: \"1px solid var(--dc-border)\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 6,\n }}>\n <span style={{ fontSize: 10.5, color: \"var(--dc-text-muted)\", letterSpacing: \"0.02em\" }}>Secured by</span>\n <DecaneMark size={13} muted />\n <DecaneWordmark size={11} muted />\n </div>\n </div>\n </div>\n );\n\n return createPortal(modal, document.body);\n}\n","import React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { createDecane } from \"../factory\";\nimport { createDecaneConnect } from \"../social/client\";\nimport { WalletSelector } from \"./WalletSelector\";\nimport { SocialWalletModal } from \"./SocialWalletModal\";\nimport { WalletStatusOverlay } from \"./StatusOverlay\";\nimport type {\n DecaneProvider,\n DecaneConfig,\n UnifiedWalletAccount,\n ChainType,\n ConnectMode,\n} from \"../types\";\nimport type { DecaneConnect, ConnectResult, AuthProfile } from \"../social/types\";\n\nexport type Theme = \"light\" | \"dark\" | \"auto\";\n\nexport interface SocialAuthState {\n addresses: { evm?: string; solana?: string; tron?: string } | null;\n isNewUser: boolean;\n /**\n * Who the provider said the user is — `{ name?, email?, picture? }`.\n *\n * `null` until a sign-in returns one, and stays null for email sign-in and\n * for providers the user withheld a profile from. It is not persisted across\n * reloads: the backend stores no profile, so a restored session has an\n * address but no name. Copy it somewhere durable if you need it to survive.\n */\n profile: AuthProfile | null;\n isUnlocked: boolean;\n sessionExpiresAt: number | null;\n /**\n * True when `addresses` came from persisted (localStorage) identity only,\n * with no live session. This is NOT the same as \"locked\" — every unlock()\n * requires a fresh, valid JWT to open a TEE session, and JWTs are\n * deliberately never persisted (short-lived, security-sensitive), so\n * there is no legitimate \"just unlock\" path in this state. A consumer\n * should route this into a full reconnect — but see canUsePasskey: when\n * that is true the reconnect is a single biometric prompt rather than a\n * Google redirect or an email code.\n */\n needsReconnect: boolean;\n /**\n * True when this device holds a passkey-wrapped share for the remembered\n * user, so signing back in costs one passkey prompt and nothing else.\n */\n canUsePasskey: boolean;\n /**\n * Long-running work in progress, so the UI can show a status screen instead\n * of appearing frozen. 'creating' = first-time key generation (several\n * seconds); 'unlocking' = reopening the TEE session for a returning user.\n */\n phase: \"creating\" | \"unlocking\" | null;\n}\n\nconst DEFAULT_SOCIAL: SocialAuthState = {\n addresses: null,\n isNewUser: false,\n profile: null,\n isUnlocked: false,\n sessionExpiresAt: null,\n needsReconnect: false,\n canUsePasskey: false,\n phase: null,\n};\n\ninterface DecaneContextValue {\n provider: DecaneProvider;\n selectorOpen: boolean;\n openSelector: () => void;\n closeSelector: () => void;\n theme: Theme;\n setTheme: (t: Theme) => void;\n mode: ConnectMode;\n // Social auth\n socialAuth: SocialAuthState;\n signInWithPasskey: () => Promise<ConnectResult>;\n connectWithGoogle: () => Promise<void>;\n connectWithKingsChat: () => Promise<void>;\n connectWithEmail: (email: string) => Promise<{ codeRequired: true }>;\n verifyEmailCode: (email: string, code: string) => Promise<void>;\n connectWithToken: (token: string, opts?: { providerId?: string }) => Promise<void>;\n // Set only when config.social.customAuth is configured — the built-in UI\n // (WalletSelector / SocialWalletModal) uses this presence to decide\n // whether to render the custom-auth button at all.\n customAuthLabel?: string;\n connectWithCustomAuth?: () => Promise<void>;\n socialUnlock: () => Promise<void>;\n socialDisconnect: () => Promise<void>;\n // Social signing\n socialSignMessage: (chain: string, message: string | Uint8Array) => Promise<string>;\n socialSendTransaction: (req: { chain: string; to: string; value?: bigint; data?: string; gasLimit?: bigint; gasPrice?: bigint }) => Promise<string>;\n socialSignSolanaTransaction: (tx: Uint8Array) => Promise<Uint8Array>;\n socialSignTronTransaction: (rawDataHex: string) => Promise<string>;\n socialSignTypedData: (req: { chain: string; domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string }) => Promise<string>;\n socialGetBalance: (chain?: string) => Promise<import(\"../social/balance\").BalanceResult>;\n socialGetBalances: () => Promise<Array<{ chain: string; balance: import(\"../social/balance\").BalanceResult | null }>>;\n socialGetEthereumProvider: (opts?: { chainId?: number }) => import(\"../social/eip1193\").Eip1193Provider;\n socialSignAuthorization: (req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) => Promise<import(\"../social/signers/evm\").SignedAuthorization>;\n socialGetAccessToken: () => string | null;\n socialRecordTransaction: (tx: import(\"../social/types\").RecordTransactionInput) => Promise<import(\"../social/types\").TransactionRecord>;\n socialGetTransactionHistory: (limit?: number) => Promise<import(\"../social/types\").TransactionRecord[]>;\n // Social recovery (2-of-3 Shamir share set)\n socialRotateShares: (opts: { password: string; passwordHint?: string }) => Promise<import(\"../social/recovery/recoveryShareFile\").RecoveryShareFile>;\n socialExportPortableBackup: (opts: { password: string; passwordHint?: string }) => Promise<import(\"../social/recovery/portableBackup\").PortableBackup>;\n socialHasRecoveryShare: () => Promise<boolean>;\n socialShouldPromptRecovery: () => Promise<boolean>;\n socialDismissRecoveryPrompt: () => Promise<void>;\n // Social wallet modal\n socialModalOpen: boolean;\n openSocialModal: () => void;\n closeSocialModal: () => void;\n}\n\nconst DecaneContext = createContext<DecaneContextValue | null>(null);\n\ninterface DecaneKitProps {\n config?: DecaneConfig;\n children: ReactNode;\n}\n\nfunction hasSocial(mode: ConnectMode): boolean {\n return (\n mode === \"all\" ||\n mode === \"social\" ||\n mode === \"evm+social\" ||\n mode === \"solana+social\" ||\n mode === \"tron+social\" ||\n mode === \"evm+tron+social\"\n );\n}\n\nfunction deriveNetworks(\n mode: ConnectMode,\n explicit?: DecaneConfig[\"networks\"],\n): DecaneConfig[\"networks\"] {\n if (explicit) return explicit;\n if (mode === \"evm\" || mode === \"evm+social\") return \"evm\";\n if (mode === \"solana\" || mode === \"solana+social\") return \"solana\";\n if (mode === \"tron\" || mode === \"tron+social\") return \"tron\";\n return \"all\";\n}\n\nexport function DecaneKit({ config, children }: DecaneKitProps) {\n const mode: ConnectMode = config?.mode ?? \"wallets\";\n\n // Fail loudly at mount rather than letting a missing identifier surface later\n // as an opaque 401/403 from a request that never had a chance of succeeding.\n if (!config?.appId) {\n throw new Error(\n \"DecaneKit: config.appId is required. Pass your dashboard project ID.\",\n );\n }\n if (hasSocial(mode) && !config.social?.apiKey) {\n throw new Error(\n `DecaneKit: config.social.apiKey is required for social sign-in (mode \"${mode}\"). ` +\n \"Create an API key for this project in the dashboard.\",\n );\n }\n\n const walletRef = useRef<DecaneProvider | null>(null);\n if (!walletRef.current) walletRef.current = createDecane(config);\n\n const socialRef = useRef<DecaneConnect | null>(null);\n const socialInitialized = useRef(false);\n\n const [selectorOpen, setSelectorOpen] = useState(false);\n const [socialModalOpen, setSocialModalOpen] = useState(false);\n const [theme, setTheme] = useState<Theme>(config?.theme ?? \"auto\");\n const [socialAuth, setSocialAuth] = useState<SocialAuthState>(DEFAULT_SOCIAL);\n\n const openSelector = useCallback(() => setSelectorOpen(true), []);\n const closeSelector = useCallback(() => setSelectorOpen(false), []);\n const openSocialModal = useCallback(() => setSocialModalOpen(true), []);\n const closeSocialModal = useCallback(() => setSocialModalOpen(false), []);\n\n // Keep session-expiry state fresh\n useEffect(() => {\n if (!socialAuth.isUnlocked) return;\n const id = setInterval(() => {\n const sdk = socialRef.current;\n if (!sdk) return;\n setSocialAuth((p) => ({\n ...p,\n isUnlocked: sdk.isUnlocked(),\n sessionExpiresAt: sdk.sessionExpiresAt(),\n }));\n }, 10_000);\n return () => clearInterval(id);\n }, [socialAuth.isUnlocked]);\n\n // Init social SDK once; auto-complete Google redirect callback\n useEffect(() => {\n if (!hasSocial(mode) || !config?.social || socialInitialized.current) return;\n socialInitialized.current = true;\n\n const {\n apiKey, authMethods, promptPin, apiBaseUrl, chains, rpcUrls,\n requireAssertionPerSignature,\n // Recovery callbacks. Forwarding these is what makes recovery\n // configurable at all from <DecaneKit>; before, they were silently\n // dropped and the headless client was constructed without them.\n offerRecoveryAtSignup, onRecoveryShareOffer, onRecoveryFileReady,\n promptForRecoveryFile, onRecoveryRotated, onRecoveryProgress,\n } = config.social;\n\n createDecaneConnect({\n appId: config.appId,\n apiKey,\n apiBaseUrl,\n authMethods: authMethods ?? [\"google\", \"email\"],\n chains: (chains ?? [\"evm:1\", \"solana:mainnet\"]) as import(\"../social/types\").Chain[],\n rpcUrls,\n promptPin,\n requireAssertionPerSignature,\n offerRecoveryAtSignup,\n onRecoveryShareOffer,\n onRecoveryFileReady,\n promptForRecoveryFile,\n onRecoveryRotated,\n onRecoveryProgress,\n }).then((sdk) => {\n socialRef.current = sdk;\n\n sdk.on(\"session-expired\", () =>\n setSocialAuth((p) => ({ ...p, isUnlocked: false, sessionExpiresAt: null })),\n );\n sdk.on(\"disconnected\", () => setSocialAuth(DEFAULT_SOCIAL));\n // Long-running phases drive the \"creating / unlocking your wallet\" screen.\n sdk.on(\"wallet-creating\", () => setSocialAuth((p) => ({ ...p, phase: \"creating\" })));\n sdk.on(\"wallet-unlocking\", () => setSocialAuth((p) => ({ ...p, phase: \"unlocking\" })));\n sdk.on(\"connected\", () => setSocialAuth((p) => ({ ...p, phase: null })));\n\n // If a live session was resumed from sessionStorage (page reload), reflect\n // it immediately as unlocked — no sign-in, no passkey. Otherwise fall back\n // to showing the remembered identity with needsReconnect, which routes to\n // a one-tap passkey (or full sign-in) when the user acts.\n const saved = sdk.getAddresses();\n if (sdk.isUnlocked()) {\n setSocialAuth((p) => ({\n ...p,\n addresses: saved,\n isUnlocked: true,\n needsReconnect: false,\n sessionExpiresAt: sdk.sessionExpiresAt(),\n }));\n } else if (saved) {\n setSocialAuth((p) => ({ ...p, addresses: saved, isUnlocked: false, needsReconnect: true }));\n }\n\n // Whether this device can skip the sign-in flow entirely and go straight\n // to the passkey. Drives which controls the modal offers.\n sdk.canSignInWithPasskey()\n .then((can) => setSocialAuth((p) => ({ ...p, canUsePasskey: can })))\n .catch(() => {});\n\n // Complete Google OAuth redirect if backend bounced back with decane_jwt.\n // Creation runs here with no modal open, which is exactly why the status\n // overlay is rendered by the provider rather than a modal.\n const params = new URLSearchParams(window.location.search);\n if (params.has(\"decane_jwt\") || params.has(\"decane_error\")) {\n sdk.connectWithGoogle().then(applyResult).catch((e) => {\n setSocialAuth((p) => (p.phase ? { ...p, phase: null } : p));\n console.error(e);\n });\n }\n }).catch(console.error);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n function applyResult(result: ConnectResult) {\n const sdk = socialRef.current;\n setSocialAuth({\n addresses: result.addresses,\n isNewUser: result.isNewUser,\n profile: result.profile ?? null,\n isUnlocked: sdk?.isUnlocked() ?? false,\n sessionExpiresAt: sdk?.sessionExpiresAt() ?? null,\n needsReconnect: false,\n canUsePasskey: false,\n phase: null,\n });\n // Re-query rather than assume: signing in provisions a passkey only when\n // the device supports one. PIN-only wallets must not be told they can come\n // back with a passkey they never created.\n sdk?.canSignInWithPasskey()\n .then((can) => setSocialAuth((p) => ({ ...p, canUsePasskey: can })))\n .catch(() => {});\n }\n\n // A phase event may have already fired ('wallet-creating'/'unlocking') when a\n // connect fails; clear it so the status overlay doesn't get stuck on failure.\n const clearPhase = useCallback(() => setSocialAuth((p) => (p.phase ? { ...p, phase: null } : p)), []);\n\n const signInWithPasskey = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n try {\n const result = await sdk.signInWithPasskey();\n applyResult(result);\n setSelectorOpen(false);\n return result;\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const connectWithGoogle = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n await sdk.connectWithGoogle();\n // navigates away — nothing to do after\n }, []);\n\n const connectWithKingsChat = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n // Unlike Google this returns here rather than navigating away, so the\n // result has to be applied to context state the same way the email flow does.\n const result = await sdk.connectWithKingsChat();\n applyResult(result);\n }, [applyResult]);\n\n const connectWithEmail = useCallback(async (email: string) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n return sdk.connectWithEmail(email);\n }, []);\n\n const verifyEmailCode = useCallback(async (email: string, code: string) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n try {\n const result = await sdk.verifyEmailCode(email, code);\n applyResult(result);\n setSelectorOpen(false);\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const connectWithToken = useCallback(async (token: string, opts?: { providerId?: string }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social sign-in not configured\");\n try {\n const result = await sdk.connectWithToken(token, opts);\n applyResult(result);\n setSelectorOpen(false);\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const customAuthConfig = config?.social?.customAuth;\n const connectWithCustomAuth = useCallback(async () => {\n if (!customAuthConfig) throw new Error(\"Custom auth not configured\");\n const token = await customAuthConfig.getToken();\n await connectWithToken(token, customAuthConfig.providerId ? { providerId: customAuthConfig.providerId } : undefined);\n }, [customAuthConfig, connectWithToken]);\n\n const socialUnlock = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) return;\n setSocialAuth((p) => ({ ...p, phase: \"unlocking\" }));\n try {\n await sdk.unlock();\n setSocialAuth((p) => ({\n ...p,\n isUnlocked: sdk.isUnlocked(),\n sessionExpiresAt: sdk.sessionExpiresAt(),\n needsReconnect: false,\n phase: null,\n }));\n } catch (e) { clearPhase(); throw e; }\n }, [clearPhase]);\n\n const socialDisconnect = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) return;\n await sdk.disconnect();\n setSocialAuth(DEFAULT_SOCIAL);\n }, []);\n\n const socialSignMessage = useCallback(async (\n chain: string,\n message: string | Uint8Array,\n ): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signMessage({ chain: chain as import(\"../social/types\").Chain, message });\n }, []);\n\n const socialSendTransaction = useCallback(async (\n req: { chain: string; to: string; value?: bigint; data?: string; gasLimit?: bigint; gasPrice?: bigint },\n ): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.sendTransaction({ ...req, chain: req.chain as import(\"../social/types\").Chain });\n }, []);\n\n const socialSignSolanaTransaction = useCallback(async (tx: Uint8Array): Promise<Uint8Array> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signSolanaTransaction(tx);\n }, []);\n\n const socialSignTronTransaction = useCallback(async (rawDataHex: string): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signTronTransaction(rawDataHex);\n }, []);\n\n const socialRecordTransaction = useCallback(async (\n tx: import(\"../social/types\").RecordTransactionInput,\n ): Promise<import(\"../social/types\").TransactionRecord> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.recordTransaction(tx);\n }, []);\n\n const socialGetTransactionHistory = useCallback(async (\n limit?: number,\n ): Promise<import(\"../social/types\").TransactionRecord[]> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getTransactionHistory(limit);\n }, []);\n\n const socialSignTypedData = useCallback(async (\n req: { chain: string; domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string },\n ): Promise<string> => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signTypedData({ ...req, chain: req.chain as import(\"../social/types\").Chain });\n }, []);\n\n const socialGetBalance = useCallback(async (chain?: string) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getBalance(chain);\n }, []);\n\n const socialGetEthereumProvider = useCallback((opts?: { chainId?: number }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getEthereumProvider(opts);\n }, []);\n\n const socialSignAuthorization = useCallback(\n async (req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.signAuthorization(req);\n },\n [],\n );\n\n const socialGetAccessToken = useCallback((): string | null => {\n return socialRef.current?.getAccessToken() ?? null;\n }, []);\n\n const socialGetBalances = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.getBalances();\n }, []);\n\n const socialRotateShares = useCallback(async (opts: { password: string; passwordHint?: string }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.rotateShares(opts);\n }, []);\n\n const socialExportPortableBackup = useCallback(async (opts: { password: string; passwordHint?: string }) => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.exportPortableBackup(opts);\n }, []);\n\n const socialHasRecoveryShare = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.hasRecoveryShare();\n }, []);\n\n const socialShouldPromptRecovery = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.shouldPromptRecovery();\n }, []);\n\n const socialDismissRecoveryPrompt = useCallback(async () => {\n const sdk = socialRef.current;\n if (!sdk) throw new Error(\"Social wallet not connected\");\n return sdk.dismissRecoveryPrompt();\n }, []);\n\n const handleWalletConnect = useCallback(\n (wallet: UnifiedWalletAccount, preference?: ChainType) => {\n walletRef.current!.connect(wallet, preference).catch(console.error);\n },\n [],\n );\n\n const networks = deriveNetworks(mode, config?.networks);\n\n return (\n <DecaneContext.Provider\n value={{\n provider: walletRef.current,\n selectorOpen, openSelector, closeSelector,\n theme, setTheme,\n mode,\n socialAuth,\n signInWithPasskey,\n connectWithGoogle,\n connectWithKingsChat,\n connectWithEmail,\n verifyEmailCode,\n connectWithToken,\n customAuthLabel: customAuthConfig?.label,\n connectWithCustomAuth: customAuthConfig ? connectWithCustomAuth : undefined,\n socialUnlock,\n socialDisconnect,\n socialSignMessage,\n socialSendTransaction,\n socialGetBalance,\n socialGetBalances,\n socialGetEthereumProvider,\n socialSignAuthorization,\n socialSignTronTransaction,\n socialRecordTransaction,\n socialGetTransactionHistory,\n socialGetAccessToken,\n socialSignSolanaTransaction,\n socialSignTypedData,\n socialRotateShares,\n socialExportPortableBackup,\n socialHasRecoveryShare,\n socialShouldPromptRecovery,\n socialDismissRecoveryPrompt,\n socialModalOpen, openSocialModal, closeSocialModal,\n }}\n >\n {children}\n <WalletSelector\n provider={walletRef.current}\n open={selectorOpen}\n onClose={closeSelector}\n onConnect={handleWalletConnect}\n theme={theme}\n networks={networks}\n mode={mode}\n socialAuthMethods={config?.social?.authMethods ?? [\"google\", \"email\"]}\n onGoogleSignIn={connectWithGoogle}\n onKingsChatSignIn={connectWithKingsChat}\n onEmailStart={connectWithEmail}\n onEmailVerify={verifyEmailCode}\n canUsePasskey={socialAuth.canUsePasskey}\n passkeyAddress={socialAuth.addresses?.evm ?? socialAuth.addresses?.solana ?? null}\n onPasskeySignIn={signInWithPasskey}\n customAuthLabel={customAuthConfig?.label}\n onCustomAuthSignIn={customAuthConfig ? connectWithCustomAuth : undefined}\n />\n <SocialWalletModal\n open={socialModalOpen}\n onClose={closeSocialModal}\n theme={theme}\n socialAuth={socialAuth}\n onUnlock={socialUnlock}\n onDisconnect={socialDisconnect}\n customAuthLabel={customAuthConfig?.label}\n onCustomAuthSignIn={customAuthConfig ? connectWithCustomAuth : undefined}\n onGoogleSignIn={connectWithGoogle}\n onKingsChatSignIn={connectWithKingsChat}\n onEmailStart={connectWithEmail}\n onEmailVerify={verifyEmailCode}\n authMethods={config?.social?.authMethods ?? [\"google\", \"email\"]}\n canUsePasskey={socialAuth.canUsePasskey}\n passkeyAddress={socialAuth.addresses?.evm ?? socialAuth.addresses?.solana ?? null}\n onPasskeySignIn={signInWithPasskey}\n onRotateShares={socialRotateShares}\n onExportPortableBackup={socialExportPortableBackup}\n rpcUrls={config?.social?.rpcUrls}\n chains={config?.social?.chains}\n />\n {/* Rendered by the provider (not a modal) so wallet creation after a\n Google redirect still shows a status screen even with no modal open.\n Opt out with social.showStatusOverlay: false to render your own from\n the `phase` the hooks expose. */}\n {config?.social?.showStatusOverlay !== false && (\n <WalletStatusOverlay phase={socialAuth.phase} theme={theme} />\n )}\n </DecaneContext.Provider>\n );\n}\n\nexport function useDecaneContext(): DecaneContextValue {\n const ctx = useContext(DecaneContext);\n if (!ctx) {\n throw new Error(\n \"Decane hooks must be called inside <DecaneKit>. \" +\n \"Wrap your app: <DecaneKit config={...}><App /></DecaneKit>\",\n );\n }\n return ctx;\n}\n","import React, { useEffect } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { CSS_VARS } from \"./styles\";\nimport { DecaneMark, DecaneWordmark } from \"./icons\";\n\n// A self-contained status screen shown while a long-running wallet operation is\n// in flight, so the user never stares at a frozen page wondering if anything is\n// happening. Rendered by <DecaneKit> itself (not tied to a modal being open),\n// because first-time creation often runs right after a Google redirect when no\n// modal is mounted. Injects its own theme tokens for the same reason.\n\nfunction injectTokens(theme: \"light\" | \"dark\" | \"auto\"): void {\n if (typeof document === \"undefined\") return;\n const resolved: \"light\" | \"dark\" =\n theme === \"auto\"\n ? window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\"\n : theme;\n let el = document.getElementById(\"decane-tokens\") as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = \"decane-tokens\";\n document.head.appendChild(el);\n }\n el.textContent = `:root { ${CSS_VARS[resolved]} }`;\n}\n\nexport function WalletStatusOverlay({\n phase,\n theme = \"auto\",\n}: {\n phase: \"creating\" | \"unlocking\" | null;\n theme?: \"light\" | \"dark\" | \"auto\";\n}) {\n useEffect(() => {\n if (!phase) return;\n injectTokens(theme);\n if (theme !== \"auto\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const h = () => injectTokens(\"auto\");\n mq.addEventListener(\"change\", h);\n return () => mq.removeEventListener(\"change\", h);\n }, [phase, theme]);\n\n if (!phase || typeof document === \"undefined\") return null;\n\n const title = phase === \"creating\" ? \"Creating your wallet\" : \"Unlocking your wallet\";\n const sub =\n phase === \"creating\"\n ? \"Generating your keys and splitting them across three shares so no single party ever holds your wallet. This takes a few seconds — please keep this tab open.\"\n : \"Reopening your secure session…\";\n\n return createPortal(\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n style={{\n position: \"fixed\", inset: 0, zIndex: 10000,\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n padding: 16, fontFamily: \"var(--dc-font-sans, system-ui, sans-serif)\",\n }}\n >\n <div style={{\n position: \"absolute\", inset: 0,\n background: \"var(--dc-bg-overlay, rgba(0,0,0,0.75))\",\n backdropFilter: \"blur(8px)\", WebkitBackdropFilter: \"blur(8px)\",\n }} />\n <div style={{\n position: \"relative\",\n background: \"var(--dc-bg, #0D0D0B)\", border: \"1px solid var(--dc-border, #3D3C39)\",\n borderRadius: 20, width: \"100%\", maxWidth: 340, padding: \"30px 26px\",\n textAlign: \"center\", boxShadow: \"0 24px 64px rgba(0,0,0,0.6)\",\n }}>\n {/* Spinner ring around the mark */}\n <div style={{ display: \"flex\", justifyContent: \"center\", marginBottom: 18 }}>\n <div style={{ position: \"relative\", width: 60, height: 60, display: \"flex\", alignItems: \"center\", justifyContent: \"center\" }}>\n <span style={{\n position: \"absolute\", inset: 0, borderRadius: \"50%\",\n border: \"2px solid var(--dc-border, #3D3C39)\", borderTopColor: \"var(--dc-accent, #F5C800)\",\n animation: \"dc-status-spin 0.8s linear infinite\",\n }} />\n <DecaneMark size={32} />\n </div>\n </div>\n\n <div style={{ fontSize: 16, fontWeight: 800, color: \"var(--dc-text, #F9F9F7)\", letterSpacing: \"-0.02em\", marginBottom: 7 }}>\n {title}\n </div>\n <div style={{ fontSize: 12, color: \"var(--dc-text-muted, #8A8884)\", lineHeight: 1.55 }}>\n {sub}\n </div>\n\n <div style={{ marginTop: 20, paddingTop: 14, borderTop: \"1px solid var(--dc-border, #3D3C39)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: 6 }}>\n <DecaneMark size={13} muted />\n <DecaneWordmark size={11} muted />\n </div>\n </div>\n\n <style>{`@keyframes dc-status-spin { to { transform: rotate(360deg); } }`}</style>\n </div>,\n document.body,\n );\n}\n","import { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { useDecaneContext } from \"./context\";\nimport type { DecaneProvider, UnifiedWalletAccount, ChainType, ChainDescriptor } from \"../types\";\nimport { DecaneError, DecaneErrorCode } from \"../errors\";\n\n// ── useSocialAuth ─────────────────────────────────────────────────────────────\n// Hook for custom sign-in UI. Works alongside (or instead of) the WalletSelector.\n// Requires mode to include social and social config to be set in <DecaneKit>.\n\nexport function useSocialAuth() {\n const {\n socialAuth,\n connectWithGoogle,\n connectWithEmail,\n verifyEmailCode,\n connectWithToken,\n customAuthLabel,\n connectWithCustomAuth,\n signInWithPasskey: ctxSignInWithPasskey,\n socialUnlock,\n socialDisconnect,\n } = useDecaneContext();\n\n const [googleLoading, setGoogleLoading] = useState(false);\n const [emailLoading, setEmailLoading] = useState(false);\n const [tokenLoading, setTokenLoading] = useState(false);\n const [customLoading, setCustomLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const signInWithGoogle = useCallback(async () => {\n setGoogleLoading(true); setError(null);\n try { await connectWithGoogle(); }\n catch (e: unknown) { setError((e as Error).message); setGoogleLoading(false); }\n // If redirect happens, loading stays true (page navigates away)\n }, [connectWithGoogle]);\n\n const sendEmailCode = useCallback(async (email: string) => {\n setEmailLoading(true); setError(null);\n try {\n await connectWithEmail(email);\n return { codeRequired: true as const };\n } catch (e: unknown) {\n setError((e as Error).message);\n throw e;\n } finally {\n setEmailLoading(false);\n }\n }, [connectWithEmail]);\n\n const confirmEmailCode = useCallback(async (email: string, code: string) => {\n setEmailLoading(true); setError(null);\n try { await verifyEmailCode(email, code); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n finally { setEmailLoading(false); }\n }, [verifyEmailCode]);\n\n const signInWithToken = useCallback(async (token: string, opts?: { providerId?: string }) => {\n setTokenLoading(true); setError(null);\n try { await connectWithToken(token, opts); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n finally { setTokenLoading(false); }\n }, [connectWithToken]);\n\n // Only meaningful when config.social.customAuth is set in <DecaneKit> —\n // calls the configured getToken() then exchanges it the same way as\n // signInWithToken. Undefined when custom auth isn't configured.\n const signInWithCustomAuth = useCallback(async () => {\n if (!connectWithCustomAuth) throw new Error(\"Custom auth not configured\");\n setCustomLoading(true); setError(null);\n try { await connectWithCustomAuth(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n finally { setCustomLoading(false); }\n }, [connectWithCustomAuth]);\n\n // One-tap reconnect for a returning user on this device. After a reload there\n // is no live session (JWTs are never persisted), so a passkey is the smoothest\n // way back in — a single biometric yields a fresh session, no Google/email.\n // Guard on canUsePasskey (false for PIN wallets / new devices).\n const signInWithPasskey = useCallback(async () => {\n setError(null);\n try { await ctxSignInWithPasskey(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [ctxSignInWithPasskey]);\n\n const unlock = useCallback(async () => {\n setError(null);\n try { await socialUnlock(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialUnlock]);\n\n const disconnect = useCallback(async () => {\n setError(null);\n try { await socialDisconnect(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialDisconnect]);\n\n return {\n isConnected: !!socialAuth.addresses,\n isUnlocked: socialAuth.isUnlocked,\n isNewUser: socialAuth.isNewUser,\n addresses: socialAuth.addresses,\n sessionExpiresAt: socialAuth.sessionExpiresAt,\n // True when this device can skip the full sign-in and resume with a passkey.\n canUsePasskey: socialAuth.canUsePasskey,\n // Long-running work in progress, for driving your own status UI.\n phase: socialAuth.phase,\n isCreatingWallet: socialAuth.phase === \"creating\",\n // True when addresses are known (from a previous visit) but there's no\n // live session — unlock() will always throw in this state (every\n // unlock requires a fresh JWT, and JWTs are never persisted). Route\n // this into a real reconnect (signInWithGoogle / sendEmailCode), not unlock().\n needsReconnect: socialAuth.needsReconnect,\n googleLoading,\n emailLoading,\n tokenLoading,\n customLoading,\n customAuthLabel,\n error,\n clearError: () => setError(null),\n signInWithGoogle,\n sendEmailCode,\n confirmEmailCode,\n signInWithToken,\n signInWithCustomAuth: connectWithCustomAuth ? signInWithCustomAuth : undefined,\n signInWithPasskey,\n unlock,\n disconnect,\n };\n}\n\n// ── useSocialWallet ───────────────────────────────────────────────────────────\n// Full hook for the social wallet — auth state, signing methods, and modal control.\n\nexport function useSocialWallet() {\n const {\n socialAuth,\n socialUnlock,\n socialDisconnect,\n socialSignMessage,\n socialSendTransaction,\n socialSignSolanaTransaction,\n socialSignTronTransaction,\n socialRecordTransaction,\n socialGetTransactionHistory,\n socialSignTypedData,\n socialGetBalance,\n socialGetBalances,\n socialGetEthereumProvider,\n socialSignAuthorization,\n socialGetAccessToken,\n socialRotateShares,\n socialExportPortableBackup,\n socialHasRecoveryShare,\n socialShouldPromptRecovery,\n socialDismissRecoveryPrompt,\n openSocialModal,\n closeSocialModal,\n socialModalOpen,\n } = useDecaneContext();\n\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function run<T>(fn: () => Promise<T>): Promise<T> {\n setLoading(true); setError(null);\n try { return await fn(); }\n catch (e: unknown) { const msg = (e as Error).message; setError(msg); throw e; }\n finally { setLoading(false); }\n }\n\n const signMessage = useCallback(\n (chain: string, message: string | Uint8Array) =>\n run(() => socialSignMessage(chain, message)),\n [socialSignMessage],\n );\n\n const sendTransaction = useCallback(\n (req: { chain: string; to: string; value?: bigint; data?: string; gasLimit?: bigint; gasPrice?: bigint }) =>\n run(() => socialSendTransaction(req)),\n [socialSendTransaction],\n );\n\n const signSolanaTransaction = useCallback(\n (tx: Uint8Array) => run(() => socialSignSolanaTransaction(tx)),\n [socialSignSolanaTransaction],\n );\n\n const signTronTransaction = useCallback(\n (rawDataHex: string) => run(() => socialSignTronTransaction(rawDataHex)),\n [socialSignTronTransaction],\n );\n\n const recordTransaction = useCallback(\n (tx: import(\"../social/types\").RecordTransactionInput) => run(() => socialRecordTransaction(tx)),\n [socialRecordTransaction],\n );\n\n // Read-only fetch — not wrapped in `run` so it doesn't toggle the shared\n // loading/error state a dev is using to drive signing buttons.\n const getTransactionHistory = useCallback(\n (limit?: number) => socialGetTransactionHistory(limit),\n [socialGetTransactionHistory],\n );\n\n const signTypedData = useCallback(\n (req: { chain: string; domain: Record<string, unknown>; types: Record<string, unknown>; message: Record<string, unknown>; primaryType?: string }) =>\n run(() => socialSignTypedData(req)),\n [socialSignTypedData],\n );\n\n const getBalance = useCallback(\n (chain?: string) => run(() => socialGetBalance(chain)),\n [socialGetBalance],\n );\n\n const signAuthorization = useCallback(\n (req: { chainId: number; address?: string; contractAddress?: string; nonce: number }) =>\n run(() => socialSignAuthorization(req)),\n [socialSignAuthorization],\n );\n\n const getBalances = useCallback(\n () => run(() => socialGetBalances()),\n [socialGetBalances],\n );\n\n const unlock = useCallback(async () => {\n setError(null);\n try { await socialUnlock(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialUnlock]);\n\n const disconnect = useCallback(async () => {\n setError(null);\n try { await socialDisconnect(); }\n catch (e: unknown) { setError((e as Error).message); throw e; }\n }, [socialDisconnect]);\n\n const rotateShares = useCallback(\n (opts: { password: string; passwordHint?: string }) => run(() => socialRotateShares(opts)),\n [socialRotateShares],\n );\n\n const exportPortableBackup = useCallback(\n (opts: { password: string; passwordHint?: string }) => run(() => socialExportPortableBackup(opts)),\n [socialExportPortableBackup],\n );\n\n const hasRecoveryShare = useCallback(\n () => run(() => socialHasRecoveryShare()),\n [socialHasRecoveryShare],\n );\n\n const shouldPromptRecovery = useCallback(\n () => run(() => socialShouldPromptRecovery()),\n [socialShouldPromptRecovery],\n );\n\n const dismissRecoveryPrompt = useCallback(\n () => run(() => socialDismissRecoveryPrompt()),\n [socialDismissRecoveryPrompt],\n );\n\n return {\n // State\n isConnected: !!socialAuth.addresses,\n isUnlocked: socialAuth.isUnlocked,\n isNewUser: socialAuth.isNewUser,\n addresses: socialAuth.addresses,\n sessionExpiresAt: socialAuth.sessionExpiresAt,\n // True when addresses are known (from a previous visit) but there's no\n // live session — unlock() will always throw in this state (every\n // unlock requires a fresh JWT, and JWTs are never persisted). Route\n // this into a real reconnect (signInWithGoogle / sendEmailCode), not unlock().\n needsReconnect: socialAuth.needsReconnect,\n // Long-running work in progress ('creating' | 'unlocking' | null), for\n // driving your own status UI in addition to the SDK's built-in overlay.\n phase: socialAuth.phase,\n isCreatingWallet: socialAuth.phase === \"creating\",\n // Modal\n modalOpen: socialModalOpen,\n openModal: openSocialModal,\n closeModal: closeSocialModal,\n // Auth\n unlock,\n disconnect,\n // Signing\n signMessage,\n sendTransaction,\n signSolanaTransaction,\n signTronTransaction,\n recordTransaction,\n getTransactionHistory,\n signTypedData,\n // Balances (native token; read-only, works while locked)\n getBalance,\n getBalances,\n // EVM interop\n signAuthorization,\n // An EIP-1193 provider for viem/wagmi/ethers (memoized).\n getEthereumProvider: socialGetEthereumProvider,\n // The Decane JWT — authenticate the user to your own backend (bundler proxy,\n // etc.); verify server-side against backend.decane.app/.well-known/jwks.json.\n getAccessToken: socialGetAccessToken,\n // Recovery (2-of-3 Shamir share set)\n rotateShares,\n exportPortableBackup,\n hasRecoveryShare,\n shouldPromptRecovery,\n dismissRecoveryPrompt,\n loading,\n error,\n clearError: () => setError(null),\n };\n}\n\n// ── useSocialBalance ──────────────────────────────────────────────────────────\n// Auto-fetching native balance for the social wallet — the \"just show me the\n// balance\" primitive. Re-fetches when the address or chain changes, exposes a\n// manual refetch(), and never throws (errors land in `error`). Pass a chain to\n// pin it; omit to use the SDK's default (first EVM chain, else Solana).\n\nexport function useSocialBalance(chain?: string) {\n const { socialAuth, socialGetBalance } = useDecaneContext();\n const [balance, setBalance] = useState<import(\"../social/balance\").BalanceResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Key the effect on address identity, not the object, so it doesn't refetch\n // on every render when the addresses object is recreated.\n const addrKey = `${socialAuth.addresses?.evm ?? \"\"}|${socialAuth.addresses?.solana ?? \"\"}`;\n\n const refetch = useCallback(async () => {\n if (!socialAuth.addresses) { setBalance(null); return; }\n setLoading(true); setError(null);\n try {\n setBalance(await socialGetBalance(chain));\n } catch (e: unknown) {\n setError((e as Error).message);\n setBalance(null);\n } finally {\n setLoading(false);\n }\n }, [socialGetBalance, chain, socialAuth.addresses]);\n\n useEffect(() => {\n let cancelled = false;\n if (!socialAuth.addresses) { setBalance(null); return; }\n setLoading(true); setError(null);\n socialGetBalance(chain)\n .then((b) => { if (!cancelled) setBalance(b); })\n .catch((e: unknown) => { if (!cancelled) { setError((e as Error).message); setBalance(null); } })\n .finally(() => { if (!cancelled) setLoading(false); });\n return () => { cancelled = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [addrKey, chain]);\n\n return { balance, loading, error, refetch };\n}\n\n// ── useEthereumProvider ───────────────────────────────────────────────────────\n// The memoized EIP-1193 provider for the social wallet — pass straight to\n// viem's custom() transport, a wagmi connector, or new ethers.BrowserProvider().\n// Null until the social wallet is connected.\n\nexport function useEthereumProvider(opts?: { chainId?: number }) {\n const { socialAuth, socialGetEthereumProvider } = useDecaneContext();\n const chainId = opts?.chainId;\n return useMemo(() => {\n if (!socialAuth.addresses?.evm) return null;\n try { return socialGetEthereumProvider(chainId ? { chainId } : undefined); }\n catch { return null; }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [socialAuth.addresses?.evm, chainId]);\n}\n\nfunction toDecaneError(err: unknown): DecaneError {\n if (err instanceof DecaneError) return err;\n // Wallet providers (EIP-1193, TronLink, Unisat, etc.) throw plain objects\n // with a `message` field — extract it before falling back to String()\n const msg =\n err instanceof Error\n ? err.message\n : (err as { message?: unknown })?.message != null\n ? String((err as { message: unknown }).message)\n : String(err);\n return new DecaneError(DecaneErrorCode.PROVIDER_ERROR, msg);\n}\n\n// ── useDecane ─────────────────────────────────────────────────────────────────\n\nexport function useDecane() {\n const { provider, theme, setTheme } = useDecaneContext();\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n const refresh = () => forceUpdate((n) => n + 1);\n const events = [\n \"connect\", \"disconnect\",\n \"walletRegistered\", \"walletUpdated\", \"walletUnregistered\",\n \"chainAdded\", \"chainRemoved\",\n ] as const;\n events.forEach((e) => provider.on(e, refresh));\n return () => events.forEach((e) => provider.off(e, refresh));\n }, [provider]);\n\n return {\n provider,\n wallets: provider.wallets,\n evmWallets: provider.evmWallets,\n solanaWallets: provider.solanaWallets,\n multiChainWallets: provider.multiChainWallets,\n chains: provider.chains,\n connectedWallet: provider.connectedWallet,\n activeSession: provider.activeSession,\n activeChain: provider.activeChain,\n isConnected: !!provider.connectedWallet,\n theme,\n setTheme,\n connect: (wallet: UnifiedWalletAccount, preference?: ChainType) =>\n provider.connect(wallet, preference),\n disconnect: () => provider.disconnect(),\n addChain: (chain: ChainDescriptor) => provider.addChain(chain),\n removeChain: (chainId: string) => provider.removeChain(chainId),\n };\n}\n\n// ── useWalletSelector ─────────────────────────────────────────────────────────\n// Modal is owned by <DecaneKit> — this hook just exposes open/close controls.\n\nexport function useWalletSelector() {\n const { selectorOpen, openSelector, closeSelector } = useDecaneContext();\n return { isOpen: selectorOpen, open: openSelector, close: closeSelector };\n}\n\n// ── useChainSwitch ────────────────────────────────────────────────────────────\n\nexport function useChainSwitch() {\n const { provider } = useDecaneContext();\n const [, forceUpdate] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n useEffect(() => {\n const refresh = () => forceUpdate((n) => n + 1);\n provider.on(\"connect\", refresh);\n provider.on(\"disconnect\", refresh);\n return () => {\n provider.off(\"connect\", refresh);\n provider.off(\"disconnect\", refresh);\n };\n }, [provider]);\n\n const switchChain = useCallback(\n async (chainId: string): Promise<void> => {\n setLoading(true);\n setError(null);\n try {\n const existingScope = provider.activeSession?.grantedScopes[chainId];\n await provider.request({\n method: \"wallet_requestPermissions\",\n params: [\n {\n requiredScopes: {\n [chainId]: existingScope ?? {\n methods: [\"wallet_sendTransaction\", \"wallet_signMessage\"],\n accounts: [],\n events: [],\n },\n },\n optionalScopes: {},\n },\n ],\n });\n forceUpdate((n) => n + 1);\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n return {\n switchChain,\n loading,\n error,\n activeChain: provider.activeChain,\n grantedChains: provider.activeSession\n ? Object.keys(provider.activeSession.grantedScopes)\n : [],\n };\n}\n\n// ── internal: resolve chain + account from active session ─────────────────────\n\nfunction resolveScope(\n provider: DecaneProvider,\n chainId?: string,\n account?: string,\n): { chain: string; account: string } {\n const chain = chainId ?? provider.activeChain;\n if (!chain) {\n throw new DecaneError(\n DecaneErrorCode.NO_ACTIVE_SESSION,\n \"No active chain — connect a wallet first.\",\n );\n }\n const scope = provider.activeSession?.grantedScopes[chain];\n const resolved = account ?? scope?.accounts[0]?.split(\":\").pop() ?? \"\";\n return { chain, account: resolved };\n}\n\n// ── useSignMessage ────────────────────────────────────────────────────────────\n\nexport function useSignMessage() {\n const { provider } = useDecaneContext();\n const [signature, setSignature] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n const signMessage = useCallback(\n async (\n message: string,\n options?: { chainId?: string; account?: string },\n ): Promise<string> => {\n const { chain, account } = resolveScope(\n provider, options?.chainId, options?.account,\n );\n setLoading(true);\n setError(null);\n try {\n const sig = (await provider.request({\n method: \"wallet_signMessage\",\n params: [chain, account, message],\n })) as string;\n setSignature(sig);\n return sig;\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n const reset = useCallback(() => { setSignature(null); setError(null); }, []);\n return { signMessage, signature, loading, error, reset };\n}\n\n// ── useSendTransaction ────────────────────────────────────────────────────────\n\nexport interface TxParams {\n to: string;\n value?: string; // decimal wei (\"1000000\") or hex (\"0x0f4240\")\n data?: string;\n gas?: string;\n gasPrice?: string;\n}\n\nexport function useSendTransaction() {\n const { provider } = useDecaneContext();\n const [txHash, setTxHash] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n const sendTransaction = useCallback(\n async (\n tx: TxParams,\n options?: { chainId?: string; from?: string },\n ): Promise<string> => {\n const { chain, account } = resolveScope(\n provider, options?.chainId, options?.from,\n );\n const value = tx.value\n ? tx.value.startsWith(\"0x\")\n ? tx.value\n : `0x${parseInt(tx.value, 10).toString(16)}`\n : \"0x0\";\n\n setLoading(true);\n setError(null);\n try {\n const hash = (await provider.request({\n method: \"wallet_sendTransaction\",\n params: [chain, account, { ...tx, value }],\n })) as string;\n setTxHash(hash);\n return hash;\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n const reset = useCallback(() => { setTxHash(null); setError(null); }, []);\n return { sendTransaction, txHash, loading, error, reset };\n}\n\n// ── useSignTypedData ──────────────────────────────────────────────────────────\n// EVM only — throws EVM_ONLY_METHOD if called on a Solana chain.\n\nexport function useSignTypedData() {\n const { provider } = useDecaneContext();\n const [signature, setSignature] = useState<string | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<DecaneError | null>(null);\n\n const signTypedData = useCallback(\n async (\n typedData: { domain: unknown; types: unknown; message: unknown },\n options?: { chainId?: string; account?: string },\n ): Promise<string> => {\n const { chain, account } = resolveScope(\n provider, options?.chainId, options?.account,\n );\n setLoading(true);\n setError(null);\n try {\n const sig = (await provider.request({\n method: \"wallet_signTypedData\",\n params: [chain, account, typedData],\n })) as string;\n setSignature(sig);\n return sig;\n } catch (err) {\n const e = toDecaneError(err);\n setError(e);\n throw err;\n } finally {\n setLoading(false);\n }\n },\n [provider],\n );\n\n const reset = useCallback(() => { setSignature(null); setError(null); }, []);\n return { signTypedData, signature, loading, error, reset };\n}\n"],"mappings":"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","names":["DecaneErrorCode","sha256","encodeBase58","Transaction","b64","body","StaleDeviceShareError","RecoveryWalletMismatchError","UserCancelledError","buf","startAuthentication","buf","startAuthentication","tokens","hexToBytes","PBKDF2_ITERATIONS","b64","unb64","buf","PBKDF2_ITERATIONS","FILE_VERSION","b64","buf","deriveFileKey","b64","PBKDF2_ITERATIONS","FILE_VERSION","toHex","evmToTronAddress","tokens","Transaction","buf","b64","sha256","encodeBase58","React","React","e","React","useCallback","useEffect","useState","createPortal","injectTokens","useState","React","useEffect","useCallback","createPortal","React","useCallback","useEffect","useState","React","useEffect","createPortal","injectTokens","useEffect","createPortal","React","useState","useCallback","useEffect","verifyEmailCode","React","useState","useEffect","useCallback","verifyEmailCode","useState","useCallback","signSolanaTransaction","useEffect"]}