import type { Network, Namespace, ExtensionInjectedProvider, IntegratedBrowserInjectedProvider, ConnectorResult, SwitchNetworkResult, AvailableAddress } from '@meshconnect/uwc-types'; import { EthereumWalletService } from './ethereum/ethereum-wallet-service'; import { SolanaWalletService } from './solana/solana-wallet-service'; import { TronWalletService } from './tron/tron-wallet-service'; import { TonWalletService } from './ton/ton-wallet-service'; /** * Payload for the `onSecondarySolanaConnectSkipped` triage sink: the ONC-3536 * gate was active for a legacy-`injectedId` wallet's secondary Solana gather — * in a framed embed OR top-level in the wallet's in-app browser (`framed` * distinguishes the two). Metadata key + discovery/runtime facets only — * never an address. */ export interface SecondarySolanaConnectSkippedInfo { /** The `solana.injectedId` metadata key that triggered the skip (e.g. `coinbaseSolana`). */ injectedId: string; /** * What the active gate observed: `connectSuppressed` = a would-be connect * was skipped; `alreadyConnected` = the passive check found the provider * already authorized (no connect was needed or made) — if a hang still * follows, the parking predates the gather and is wallet-side state. */ outcome: 'connectSuppressed' | 'alreadyConnected'; /** * True when the wallet was discovered via the legacy injected fallback * (true "Legacy mode"); false when it registered via the Wallet Standard. */ legacyInjected: boolean; /** * True when the skip happened in a framed embed; false when it happened * top-level in the wallet's in-app browser (the dapp deep-link flow). */ framed: boolean; } /** * Payload for the `onSecondarySolanaConnectGathered` sink: a legacy-`injectedId` * wallet's SECONDARY Solana address WAS gathered after an EVM connect (the * positive counterpart of {@link SecondarySolanaConnectSkippedInfo}). This is * the "the ONC-231 fix works" signal — in prod, filter `framed:true` to confirm * framed clients recover the Base Wallet Solana address that the over-broad gate * used to drop. Metadata key + discovery/runtime facets only — never an address. */ export interface SecondarySolanaConnectGatheredInfo { /** The `solana.injectedId` metadata key of the gathered wallet (e.g. `coinbaseSolana`). */ injectedId: string; /** `existing` = surfaced via the passive/silent check; `connect` = a fresh connect was made. */ source: 'existing' | 'connect'; /** True = wallet discovered via the legacy injected fallback (true "Legacy mode"); false = Wallet Standard. */ legacyInjected: boolean; /** True = gathered while framed (the SDK-client case the ONC-231 fix restores); false = top frame. */ framed: boolean; } /** Optional collaborators for {@link ConnectionManager}. */ export interface ConnectionManagerOptions { /** * Whether this session runs inside a wallet's in-app browser (same flag the * `InjectedConnector` receives) — one of the two triggers of the ONC-3536 * legacy-Solana gather gate, see * {@link skipLegacyInjectedSolanaSecondaryConnect}. */ usingIntegratedBrowser?: boolean | undefined; /** * Triage telemetry sink (ONC-3536 follow-up): invoked when the ONC-3536 * gate is active for a legacy-`injectedId` wallet. Fires once per * injectedId × outcome per instance — so it can fire twice for the same * injectedId (`connectSuppressed` and `alreadyConnected`). */ onSecondarySolanaConnectSkipped?: ((info: SecondarySolanaConnectSkippedInfo) => void) | undefined; /** * Positive telemetry sink (ONC-231): invoked when a legacy-`injectedId` * wallet's secondary Solana address IS gathered. Fires once per * injectedId × source per instance. Verifies the framed gather works. */ onSecondarySolanaConnectGathered?: ((info: SecondarySolanaConnectGatheredInfo) => void) | undefined; /** * Telemetry sink: the wallet-switch guard released live per-namespace state * that belonged to a different wallet (see * {@link ConnectionManager.checkExistingConnections}). Fires once per * connect attempt that released anything, with the released namespaces — * never an address. Observability only; the release happens regardless. */ onWalletConnectionsReleased?: ((info: { namespaces: Namespace[]; }) => void) | undefined; } export declare class ConnectionManager { private ethereumService; private solanaService; private tronService; private tonService; private currentNetworkId; /** `${injectedId}:${outcome}` keys already reported via * `onSecondarySolanaConnectSkipped` — dedupes the emit across repeated * gathers per outcome (mirrors the legacy-discovery failure dedup in * `InjectedConnector`, which keys on injectedId alone). */ private readonly reportedSolanaGatherSkips; /** `${injectedId}:${source}` keys already reported via * `onSecondarySolanaConnectGathered` — dedupes the positive emit per source. */ private readonly reportedSolanaGathers; private readonly usingIntegratedBrowser; private readonly onSecondarySolanaConnectSkipped?; private readonly onSecondarySolanaConnectGathered?; private readonly onWalletConnectionsReleased?; constructor(ethereumService: EthereumWalletService, solanaService: SolanaWalletService, tronService: TronWalletService, tonService: TonWalletService, options?: ConnectionManagerOptions); /** Report a gathered legacy-injectedId Solana address, once per injectedId x source. */ private reportSecondarySolanaConnectGathered; /** Report the ACTIVE gate's observation, once per injectedId x outcome. */ private reportSecondarySolanaConnectSkipped; /** * Release any live per-namespace connection that does NOT belong to the * wallet being connected (identified by `provider`'s detected metadata). * Connecting wallet B while wallet A is still connected must behave like a * fresh connect for B: without this, the in-memory reuse shortcuts below * (and the cross-namespace gathers) hand B's session wallet A's account — * the session shows A's address under B's name, signing keeps routing to * A's provider, and A's other-namespace addresses leak into B's * availableAddresses. Identity is compared per namespace on the live * surface (EVM/Tron provider, Solana adapter, TON jsBridgeKey), so a * same-wallet reconnect releases nothing and keeps its fast path. Local * state only — A's wallet-side permissions are untouched (the disconnect() * contract); TON is the exception, where the stale session is explicitly * ended over the JS Bridge so the old wallet doesn't keep a live session. * * Fail-closed by design: when the target wallet's identity for a namespace * can't be established (no `detectedWallet` uuid, or the uuid no longer * resolves), a live connection is released rather than reused — reusing * state we can't attribute to the requested wallet is exactly the * cross-wallet mixup this guard exists to prevent. This cannot strand a * same-wallet reconnect: every path that reaches the connected state * (`connect*` throws, the silent checks skip) requires the detected uuid, * and detection stamps that uuid on the same metadata object `connect()` * passes back in, so a wallet that was ever connected presents a uuid that * resolves to its own live surface. The one benign spurious release is * Solana adapter-instance churn (a consumer re-running discovery replaces * adapter instances): the follow-up silent check re-binds the fresh adapter * from `wallet.accounts` without a wallet round-trip. */ private releaseOtherWalletConnections; /** * Check and add existing connections from other namespaces */ checkExistingConnections(targetNamespace: 'eip155' | 'solana' | 'tron' | 'tvm', provider: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider): Promise<{ address: string | null; availableAddresses: AvailableAddress[]; }>; /** * Check and add Ethereum addresses if connected */ private checkAndAddEthereumAddresses; /** * Check and add Solana addresses if connected */ private checkAndAddSolanaAddresses; /** * Check and add Tron addresses if connected */ private checkAndAddTronAddresses; /** * Check and add TON addresses if connected, or auto-connect if detected. * This will prompt the wallet approval dialog if TON is not yet connected — * same behavior as Solana/Tron cross-namespace auto-connect. */ private checkAndAddTonAddresses; /** * After connecting one namespace, check and add addresses for all OTHER namespaces. * E.g. after connecting Ethereum, also gather Solana, Tron, and TON addresses. */ private checkAndAddOtherNamespaceAddresses; /** * Collect addresses from all currently-connected namespaces. * Unlike checkAndAdd* helpers, this does NOT attempt new connections — * it only gathers addresses for namespaces already connected in this session. */ private collectConnectedAddresses; /** * Connect to Ethereum wallet */ connectEthereum(network: Network, provider: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider): Promise; /** * Connect to Solana wallet */ connectSolana(network: Network, provider: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider): Promise; /** * Connect to Tron wallet */ connectTron(network: Network, provider: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider): Promise; /** * Connect to TON wallet */ connectTon(network: Network, provider: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider): Promise; /** * Switch network */ switchNetwork(network: Network, provider: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider): Promise; /** * Get current network ID */ getCurrentNetworkId(): string | null; /** * Set current network ID */ setCurrentNetworkId(networkId: string | null): void; /** * Get current account based on current network */ getCurrentAccount(): string | null; /** * Disconnect all */ disconnect(): Promise; } //# sourceMappingURL=connection-manager.d.ts.map