import type { Transaction, VersionedTransaction } from '@solana/web3.js'; /** * Minimal shape of an injected Solana wallet provider (Wallet-Standard * compatible). Phantom's `window.phantom.solana` / `window.solana` and most * other Solana browser wallets implement this. We only require the methods the * login + signing surface needs. */ export interface InjectedSolanaProvider { isPhantom?: boolean; publicKey?: { toString(): string; } | null; isConnected?: boolean; /** * True when reaching this wallet LEAVES THE PAGE (Solana Mobile dispatches * an Android intent for every operation). Such a wallet needs a fresh user * gesture per call, so the SDK applies `confirmWalletAction` to it and skips * it for wallets that sign in-page. Set by the SDK's own adapter; a custom * provider that also navigates away should set it too. */ leavesPage?: boolean; /** * Whether the wallet can sign AND send in one call, asked at CALL TIME. * A Wallet Standard wallet can rewrite its feature set during connect (the * mobile adapter learns the wallet's real capabilities from the * authorization), so a snapshot taken when the provider was built can be * wrong by the time it is used. When present this is authoritative; * otherwise the presence of `signAndSendTransaction` is the answer. */ canSignAndSend?(): boolean; /** * Whether this wallet can sign a transaction and hand it back RIGHT NOW, * asked the same way and for the same reason as canSignAndSend: a Wallet * Standard wallet rewrites its feature set during connect, so the method * being present proves nothing. Signing is what lets a caller verify the * signature before submitting, so this is the capability that decides * whether that is possible at all. */ canSignTransaction?(): boolean; /** * Finish any async work this provider would otherwise do INSIDE the call for * `action` (lazy chunks, codecs). Callers await it before collecting the * user gesture that a leaving-the-page wallet needs, so nothing async * remains between the tap and the wallet invocation - a chunk fetched after * the tap can outlast the transient activation on a cold mobile connection. * Takes the action so a provider prepares only what that one needs (SIWS * login must not pull a transaction codec). Optional: a provider with * nothing to prepare simply omits it. */ prepare?(action: WalletAction): Promise; connect(options?: { onlyIfTrusted?: boolean; }): Promise<{ publicKey: { toString(): string; }; }>; disconnect(): Promise; /** Wallet-Standard: signMessage(Uint8Array) -> { signature, publicKey } */ signMessage(message: Uint8Array, display?: 'utf8' | 'hex'): Promise<{ signature: Uint8Array; publicKey: { toString(): string; }; }>; signTransaction(tx: T): Promise; signAllTransactions?(txs: T[]): Promise; signAndSendTransaction?(tx: Transaction | VersionedTransaction, options?: any): Promise<{ signature: string; }>; } /** The wallet operations that may need a fresh user gesture (see * `InjectedWalletConfig.confirmWalletAction`). */ export type WalletAction = 'connect' | 'login' | 'signMessage' | 'signTransaction' | 'signAndSubmitTransaction'; export interface InjectedWalletConfig { /** * Resolve/pick the injected provider. Defaults to Phantom * (`window.phantom.solana`) then a generic `window.solana`. Pass this to * point at a specific wallet, or to bridge a custom/mock provider (e.g. an * app that already discovered a Wallet-Standard wallet). */ getProvider?: () => InjectedSolanaProvider | null | undefined; /** * Awaited immediately before EVERY wallet operation, after all async * preparation (nonce, lazy imports, blockhash) is done - your chance to * collect a fresh user gesture. * * Only needed by wallets that leave the page, i.e. Solana Mobile * (Saga/Seeker): each operation dispatches a `solana-wallet:` Android intent * through `window.location.assign`, and by then the tap that started the * flow is spent. With no transient activation left Chrome blocks the * navigation, the wallet never blurs the page, and the protocol's 3s * detection rejects with ERROR_WALLET_NOT_FOUND. Resolve this from a real * click and the intent rides that activation. * * Return a promise that settles when the user taps; REJECT it to abort the * operation (nothing is signed). The Bounded login widget supplies it for * the login signature automatically; supply it here to cover the signing * and transaction surfaces your own UI drives. Injected wallets sign * in-page, so leave it unset unless you support Solana Mobile. */ confirmWalletAction?: (action: WalletAction) => Promise; /** Solana network for transaction RPC: solana_devnet | solana_mainnet. */ network?: string | null; /** Explicit RPC URL override (wins over `network`). */ rpcUrl?: string | null; } /** * Default provider discovery: Phantom-first, then any Wallet-Standard * `window.solana`. Kept tiny + synchronous (no heavy imports) so it works inside * a user gesture and can be eagerly exported from the SDK entry. */ export declare function defaultInjectedProvider(): InjectedSolanaProvider | null;