import type { EVMTransaction, SolTransaction, TransactionResult, User, AuthProvider, SetOptions } from '@pooflabs/core'; import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js'; export interface SolanaMobileWalletConfig { /** App identity shown to the wallet during authorization */ appIdentity?: { name?: string; uri?: string; icon?: string; }; /** Solana cluster: 'mainnet-beta' | 'devnet' | 'testnet' */ cluster?: string; /** Theme for any UI elements: 'light' or 'dark' */ theme?: 'light' | 'dark'; } /** * Detects whether the current environment is a mobile browser capable of * Mobile Wallet Adapter (MWA) communication. * * Returns true on Android browsers (Chrome, etc.) where MWA intents work, * or inside a Seeker/Saga in-app browser context. */ export declare function isMobileWalletAvailable(): boolean; /** * Registers Mobile Wallet Adapter as a wallet-standard wallet so it appears * in wallet selection UIs and can be discovered by other wallet-standard consumers. * * Call this once at app startup (in a browser-only / non-SSR context). * * @param config - App identity and optional remote host authority for desktop QR code support */ export declare function registerMobileWalletAdapter(config?: { appIdentity?: { name?: string; uri?: string; icon?: string; }; chains?: string[]; remoteHostAuthority?: string; /** * Optional custom wallet-not-found handler. If omitted, the SDK installs * a no-op (NOT the library default) — see comment below. */ onWalletNotFound?: (mobileWalletAdapter: any) => Promise; }): Promise; /** * SolanaMobileWalletProvider implements the AuthProvider interface using * Solana Mobile's wallet-standard wrapper (`LocalSolanaMobileWalletAdapterWallet`). * * Why wallet-standard and not the raw MWA protocol: as of * `@solana-mobile/wallet-standard-mobile@0.5.0+`, the wallet's internal * `#transact` calls `checkLocalNetworkAccessPermission()` before opening the * localhost WebSocket. That helper renders a three-stage UX flow Solana * Mobile designed specifically to defuse Chrome's Local Network Access * permission dialog (which renders with disabled buttons on Android Chrome, * the source of the long-running Seeker MWA bug): * * 1. "Allow connections to your wallet" informational modal. * 2. Chrome's permission prompt (interactive because it's spawned as a * fresh user gesture from step 1). * 3. "Ready to connect!" success modal. * * `checkLocalNetworkAccessPermission` is internal to the library — it's not * exported. The only way to invoke it is to go through the wallet's * `standard:connect` / `solana:sign*` features, which is what this provider * does. * * Notes on UX: login uses two wallet popups in succession — `standard:connect` * (authorize) and `solana:signMessage` (sign the Tarobase nonce). The * previous implementation combined both inside a single `transact` callback; * splitting them is the cost of going through wallet-standard, and is * acceptable given the alternative was broken on Seeker. */ export declare class SolanaMobileWalletProvider implements AuthProvider { private static instance; private networkUrl; private config; private appIdentity; /** Raw cluster name (e.g. 'mainnet-beta'); mapped via mapChainToWalletStandard. */ private cluster; /** LocalSolanaMobileWalletAdapterWallet, lazy-constructed in ensureWallet(). */ private wallet; constructor(networkUrl?: string | null, config?: SolanaMobileWalletConfig); static getInstance(networkUrl: string | null, config: SolanaMobileWalletConfig): SolanaMobileWalletProvider; /** Lazy-construct LocalSolanaMobileWalletAdapterWallet on first need. */ private ensureWallet; /** * Ensure the wallet has an active authorization. After a Tarobase session * is restored from storage on cold-start, `wallet.accounts` is empty until * we silently reconnect from the AuthorizationCache. If the cache is also * empty, fall back to interactive `login()` (which surfaces the three-stage * Solana Mobile LNA flow + wallet popups). * * Returns the wallet-standard `WalletAccount` to use for sign operations. */ private ensureAuthorized; /** Returns the active wallet-standard chain identifier (e.g. 'solana:mainnet'). */ private getChain; /** * Cached MWA auth_token returned by `wallet.authorize()`. Reused by * subsequent native transact() calls (signMessage / signTransaction) * so the user doesn't get the wallet-pick popup on every operation. * Persisted to platform storage and hydrated by the constructor on * native; cleared by logout() and on `ERROR_REAUTHORIZE`. */ private nativeAuthToken; /** Cached public key string for the connected MWA wallet (native). */ private nativeAddress; /** * Dynamically import and unwrap `transact` from the MWA web3js * package. The package is externalized in rollup.config.js so this * resolves to `lib/cjs/index.native.js` (TurboModule-backed) on * Metro and `lib/esm/index.browser.js` (WebSocket) on webpack/vite * per their respective platform conditions. Handles Metro's CJS-to- * ESM interop variance (`mod.transact` vs `mod.default?.transact`). */ private loadTransact; /** * Cache and persist a fresh MWA auth_token + address. Called from * `_loginNative` after a successful authorize. Storage failures are * non-fatal (next cold-start re-auths). */ private persistNativeAuth; /** Clear cached + persisted native auth state. */ private clearNativeAuth; /** * Classify an MWA-native error as a user cancellation. User-cancel * shouldn't surface as a red console.error; callers can swallow or * show a softer message. MWA spec codes plus the same substring * checks the web path uses to catch wallet-specific phrasing. */ private isNativeUserCancel; /** * Native MWA login via @solana-mobile/mobile-wallet-adapter-protocol-web3js. * Used in true React Native (Expo) environments where wallet-standard-mobile's * web universal-link path doesn't apply. Does authorize + signMessage in a * single transact() roundtrip — intent-based MWA doesn't need the two-popup * dance the web path uses (no Chrome activation-loss concern). Persists the * resulting auth_token so cold-start can reauthorize without a fresh popup. */ private _loginNative; login(): Promise; restoreSession(): Promise; logout(): Promise; signMessage(message: string): Promise; signTransaction(transaction: Transaction | VersionedTransaction): Promise; signAndSubmitTransaction(transaction: Transaction | VersionedTransaction, feePayer?: PublicKey): Promise; runTransaction(_evmTransactionData?: EVMTransaction, solTransactionData?: SolTransaction, options?: SetOptions): Promise; getNativeMethods(): Promise; private getRpcUrl; } declare global { interface Window { CUSTOM_TAROBASE_APP_ID_HEADER?: string; } }