import { Transaction } from '@solana/web3.js'; import { StandardWalletAdapter } from '@solana/wallet-standard-wallet-adapter-base'; export interface EthereumProvider { request: (args: { method: string; params?: unknown[]; }) => Promise; on?: (event: string, handler: (...args: any[]) => void) => void; removeListener?: (event: string, handler: (...args: any[]) => void) => void; } interface ExtendedStandardWalletAdapter extends StandardWalletAdapter { customFunctions: ('sendSerializedTransaction' | 'signSerializedTransaction' | 'signAllSerializedTransactions' | 'signSolanaTransactionBytes')[]; sendSerializedTransaction: (transaction: ArrayBufferLike, rpcUrl: string) => Promise; signSerializedTransaction: (transaction: ArrayBufferLike) => Promise; signAllSerializedTransactions: (transactions: ArrayBufferLike[]) => Promise; signSolanaTransactionBytes: (transaction: ArrayBufferLike, connectedAddress?: string) => Promise; } export interface WalletStandardInfo { uuid: string; name: string; chains: string[]; features: string[]; adapter: ExtendedStandardWalletAdapter | undefined; } interface Bip122ConnectFeature { connect: (input: unknown) => Promise; } /** * Marshaled so a FRAMED child can revoke the origin's bip122 authorization. * Without it the child's only route was a local-cache clear, which leaves the * grant intact — so a re-connect replays the same account and a pinned-address * connect can never reach a different one. */ interface Bip122DisconnectFeature { disconnect: () => Promise; } /** * A bip122 account reduced to plain, structured-cloneable data. * * `publicKey` travels as a number array rather than a `Uint8Array`: the child * rebuilds it (`BridgeChild.reviveBip122Account`), which keeps the wire shape * free of typed-array assumptions. */ export interface Bip122WireAccount { address: string; publicKey: number[]; purpose?: string; } /** * Reshape a wallet-native bip122 account into plain data before it crosses * Comlink. * * REQUIRED, not cosmetic. Comlink marshals by structured clone, which copies * only OWN ENUMERABLE properties — and MetaMask's account is a class instance * whose `address`/`publicKey` are accessors on the prototype chain * (`Object.getOwnPropertyNames(account)` is `[]`). Passing one through * unchanged therefore delivers `{}` to the child, and the first * `bytesToHex(account.publicKey)` throws "bytes is not iterable" — which made * every framed bip122 connect fail before reaching the wallet. */ export declare function toBip122WireAccount(account: unknown): Bip122WireAccount; interface Bip122SignMessageFeature { signMessage: (input: unknown) => Promise; } interface Bip122SignTransactionFeature { signTransaction: (input: unknown) => Promise; } /** * Wallet Standard `bitcoin:*` wallet, reshaped into plain data (`name`, * `accounts`) plus Comlink-proxied feature methods so it survives the * postMessage bridge — mirrors `WalletStandardBitcoinWallet` * (`@meshconnect/uwc-bitcoin`), duck-typed here rather than imported to avoid * a new cross-package dependency (same approach as the Tron/TON provider * shapes below). */ export interface Bip122WireWallet { name: string; /** Plain data — see {@link toBip122WireAccount} for why this cannot be the * wallet's own account objects. */ accounts: Bip122WireAccount[]; features: { 'bitcoin:connect'?: Bip122ConnectFeature | undefined; 'bitcoin:disconnect'?: Bip122DisconnectFeature | undefined; 'bitcoin:signMessage'?: Bip122SignMessageFeature | undefined; 'bitcoin:signTransaction'?: Bip122SignTransactionFeature | undefined; }; } export interface Bip122WalletInfo { uuid: string; name: string; features: string[]; wallet: Bip122WireWallet; } export interface EIP6963ProviderInfo { uuid: string; name: string; icon: string; rdns: string; } export interface EIP6963ProviderDetail { info: EIP6963ProviderInfo; provider: EthereumProvider; } export interface EIP6963AnnounceProviderEvent extends CustomEvent { type: 'eip6963:announceProvider'; detail: EIP6963ProviderDetail; } export interface DetectedWallet { uuid: string; name: string; icon: string; rdns: string; provider: EthereumProvider; } export interface TronWalletInfo { uuid: string; name: string; injectedId: string; provider: any; } export interface TonWalletInfo { uuid: string; name: string; icon: string; jsBridgeKey: string; provider: any; } export interface ParentAPI { eip6963Wallets: DetectedWallet[]; eip6963WalletsReady: boolean; walletStandardWallets: WalletStandardInfo[]; walletStandardWalletsReady: boolean; bip122Wallets: Bip122WalletInfo[]; bip122WalletsReady: boolean; tronWallets: TronWalletInfo[]; tronWalletsReady: boolean; tonWallets: TonWalletInfo[]; tonWalletsReady: boolean; parentOrigin: string; discoverTronWallets: (injectedIds: string[]) => void; discoverTonWallets: (jsBridgeKeys: string[]) => void; /** * Attach a real listener for `eventName` on the EIP-6963 provider. Awaits the * one-shot EIP-6963 discovery window before looking up the wallet by `uuid` in * `eip6963Wallets`; if that misses and an optional `rdns` was supplied, falls * back to matching by `rdns` (a wallet-defined identifier stable across * injection contexts). Forwards every event firing to `callback` (a * Comlink-proxied callback the child supplies). Resolves to a teardown that * removes the listener. THROWS when neither `uuid` nor the `rdns` fallback * resolves a wallet (surfaced to the child as a bridge error rather than a * silent no-op); resolves to `undefined` only when the wallet IS found but * exposes no `.on` to observe. */ subscribeEip6963ProviderEvent: (uuid: string, eventName: 'accountsChanged' | 'chainChanged' | 'disconnect', callback: (payload?: unknown) => void, rdns?: string) => Promise<(() => void) | undefined>; /** * Same as `subscribeEip6963ProviderEvent`, but for an injected Tron * provider resolved fresh by its window path (`injectedId`) rather than a * cached discovery list, since Tron providers aren't cached the same way. */ subscribeTronProviderEvent: (injectedId: string, eventName: 'accountsChanged' | 'disconnect', callback: (payload?: unknown) => void) => (() => void) | undefined; /** * Relay a connected Solana wallet's account-change events across the * bridge. `walletId` is the SAME id `walletStandardWallets[].uuid` * publishes (see `generateWalletId` — name+chain based, not a real UUID), * which the child mirrors back as * `SolanaWalletService.connectedWalletUuid`. Deliberately re-resolves the * REAL, in-frame adapter (via `getWallets()`) rather than reusing the * serialized `walletStandardWallets[].adapter` object — that object only * exposes the whitelisted sign/transaction methods for Comlink, not * `.on`/`.off`, so it can't be used to attach a live listener. Forwards a * plain `string | null` (never a `PublicKey`) to `callback`, a * Comlink-proxied callback the child supplies. Throws when no wallet * matches `walletId` (reported as a bridge error on the child side, * mirroring `subscribeEip6963ProviderEvent`'s uuid-miss); returns * `undefined` when the resolved adapter can't be observed. */ subscribeSolanaWalletEvent: (walletId: string, callback: (address: string | null) => void) => (() => void) | undefined; /** * Bitcoin peer of `subscribeSolanaWalletEvent`. `walletId` is the SAME id * `bip122Wallets[].uuid` publishes (see `generateBip122WalletId`), which the * child mirrors back as `BitcoinWalletService.connectedWalletUuid`. Bitcoin * has no adapter class re-emitting `connect`/`disconnect` on a switch (the * way `StandardWalletAdapter` does for Solana) — `standard:events` is the * ONLY path, not a preferred one with a fallback. Forwards a plain * `string | null` (never the raw account object) to `callback`, a * Comlink-proxied callback the child supplies. Throws when no wallet * matches `walletId` (reported as a bridge error on the child side, * mirroring `subscribeSolanaWalletEvent`'s walletId-miss); returns * `undefined` when the resolved wallet exposes no `standard:events`. */ subscribeBip122WalletEvent: (walletId: string, callback: (address: string | null) => void) => (() => void) | undefined; } export declare class BridgeParent { private iframe; private parentAPI; private endpoint; private exposeListeners; private destroyed; private eip6963DiscoveryPromise; constructor(iframe: HTMLIFrameElement); private initializeConnection; private discovereip6963Wallets; private getSolanaWallets; private isSolanaWallet; private isBitcoinWallet; /** * Wallet Standard `bitcoin:*` discovery — the Bitcoin peer of * `getSolanaWallets`. Reshapes each matching registry wallet into plain * data (`accounts`) plus individually Comlink-proxied feature methods * (`bitcoin:connect`/`signMessage`/`signTransaction`), each left `undefined` * when the real wallet doesn't declare it — so `WalletStandardBitcoinAdapter`'s * own presence checks (`if (!feature) throw ...`) still work once marshaled * across the bridge. */ private getBitcoinWallets; private generateWalletId; /** * Bitcoin peer of `generateWalletId`, kept separate rather than shared: it * keys on the wallet's first `bitcoin:` chain, not `chains[0]` — MetaMask's * bitcoin:* wallet is multi-chain (eip155 chains registered first), so * `chains[0]` would key this id off an unrelated namespace. Mirrors the * same fix already applied to the local (unframed) discovery path in * wallet-standard-discovery.ts. Used by both `getBitcoinWallets()` and * `resolveBip122WalletForEvent()` so they agree on the same id. */ private generateBip122WalletId; /** * Resolve the REAL registry wallet for `walletId` (the same id * `getBitcoinWallets()` publishes as `Bip122WalletInfo.uuid`) so * `subscribeBip122WalletEvent` can attach a live listener. Unlike Solana, * Bitcoin has no adapter class to construct — `getBitcoinWallets()` already * reshapes the raw registry `Wallet` directly, so this returns that same * raw `Wallet`, which still carries `standard:events` (the reshaped * `Bip122WireWallet` sent across the bridge does not). */ private resolveBip122WalletForEvent; /** * Checks if a value looks like a Tron provider (has request and tronWeb) */ private isTronProvider; /** * Resolve the REAL (non-serialized) Solana adapter for `walletId` — the * same id `getSolanaWallets()` publishes as `WalletStandardInfo.uuid` (see * `generateWalletId`). Mirrors `getSolanaWallets()`'s wallet-standard + * traditional-Base-Wallet resolution, but returns the adapter instance * itself instead of the Comlink-serialized object literal, since only the * real instance has `.on`/`.off` to subscribe to. */ private resolveSolanaAdapterForWalletEvent; /** Resolve a nested window path (e.g. 'tokenpocket.tron' -> window.tokenpocket.tron). */ private resolveTronProviderByPath; /** * TronLink's account/disconnect events fire on its TIP-1193 provider * (`window.tron`), NOT on the `window.tronLink` object the catalog * `injectedId` resolves to (that one carries `request`+`tronWeb` but is not * an event emitter). Returns TronLink's `window.tron` emitter, but ONLY when * the subscription is for TronLink itself. * * `window.tron` belongs exclusively to TronLink. Other Tron wallets whose own * provider happens to lack `.on` (confirmed for OKX's `okxwallet.tronLink`, * which is not an event emitter and broadcasts account switches on the window * `message` channel instead) MUST NOT inherit it — binding OKX's * `accountsChanged` on TronLink's `window.tron` means OKX's switches fire on * the wrong wallet's provider and are silently dropped. Gated on the * subscription's identity so only the TronLink path uses this fallback; every * other wallet falls through to `subscribeTronWindowMessage`. */ private resolveTronEventEmitter; /** * Last-resort account/disconnect subscription for TronLink builds that expose * neither an EIP-1193 nor a TIP-1193 `.on`: the wallet broadcasts changes as * `window` `message` events (`{ message: { action, data } }`). Maps the * TronLink `action` to the requested UWC event and forwards a * Comlink-cloneable payload (never the raw event). Returns a teardown. * * `message` is window-global (not wallet-scoped), so this is only reached * when no `.on` emitter exists anywhere for this session. */ private subscribeTronWindowMessage; private getTronWallets; private isTonConnectBridge; private getTonWallets; destroy(): void; } export {}; //# sourceMappingURL=BridgeParent.d.ts.map