import { disconnectWallet, getWalletState, initWalletService, waitForWalletSession } from "../services/walletconnect-service.mjs";
import { getCredentialVault } from "../services/credential-vault.mjs";
import "../services/bankr-api.mjs";
import { getOnboardingFlow } from "../services/onboarding-flow.mjs";
import { createChannelSender, extractChannelId } from "../services/channel-sender.mjs";
//#region extensions/crypto/src/commands/connect-command.ts
/**
* /connect commands — connect a mobile wallet via WalletConnect.
*
* Each wallet gets its own slash command so it's tappable in Telegram:
*   /connect           — shows wallet menu
*   /connect_metamask  — connect MetaMask
*   /connect_rainbow   — connect Rainbow
*   /connect_coinbase  — connect Coinbase Wallet
*   /connect_trust     — connect Trust Wallet
*   /connect_zerion    — connect Zerion
*   /connect_uniswap   — connect Uniswap Wallet
*   /connect_rabby     — connect Rabby (desktop, raw URI)
*   /connect_other     — any wallet (raw URI)
*/
const WALLETS = [
	{
		id: "metamask",
		label: "MetaMask",
		deepLink: "https://metamask.app.link/wc?uri="
	},
	{
		id: "rainbow",
		label: "Rainbow",
		deepLink: "https://rnbwapp.com/wc?uri="
	},
	{
		id: "coinbase",
		label: "Coinbase Wallet",
		deepLink: "https://go.cb-w.com/wc?uri="
	},
	{
		id: "trust",
		label: "Trust Wallet",
		deepLink: "https://link.trustwallet.com/wc?uri="
	},
	{
		id: "zerion",
		label: "Zerion",
		deepLink: "https://wallet.zerion.io/wc?uri="
	},
	{
		id: "uniswap",
		label: "Uniswap Wallet",
		deepLink: "https://uniswap.org/app/wc?uri="
	},
	{
		id: "rabby",
		label: "Rabby (desktop)"
	},
	{
		id: "other",
		label: "Other wallet"
	}
];
/** Stored plugin API reference for sending messages after session establishes. */
let _api = null;
/** Guard against duplicate waitForWalletSession callbacks. */
let _pendingSessionWait = false;
function setConnectCommandApi(api) {
	_api = api;
}
async function doConnect(wallet, ctx) {
	const state = getWalletState();
	if (state.connected && state.address) return { text: `Wallet already connected: ${state.address.slice(0, 6)}...${state.address.slice(-4)} (chain ${state.chainId})\n\nUse /disconnect to disconnect first.` };
	const projectId = getCredentialVault().getSecret("walletconnect.projectId", "connect-command") ?? void 0;
	const privateKey = getCredentialVault().getSecret("wallet.privateKey", "connect-command") ?? void 0;
	if (!projectId && !privateKey) return { text: `WalletConnect is not configured.\n\nTo enable it, run \`openclawnch init\` or add WALLETCONNECT_PROJECT_ID to your .env file.\n\nGet a project ID at https://cloud.reown.com` };
	try {
		const result = await initWalletService({
			privateKey,
			walletConnectProjectId: projectId,
			rpcUrl: process.env.CLAWNCHER_RPC_URL,
			network: process.env.CLAWNCHER_NETWORK || "mainnet",
			sessionPath: process.env.WALLETCONNECT_SESSION || `${process.env.HOME ?? ""}/.openclawnch/wc-session.json`
		});
		if (result.mode === "private_key") return { text: `Connected via private key (headless mode).\nAddress: ${result.address}\n\nTransactions will be auto-signed.` };
		if (result.address && !result.pairingUri) return { text: `Wallet already connected: ${result.address.slice(0, 6)}...${result.address.slice(-4)}\n\nSession restored from previous connection.` };
		if (result.pairingUri) {
			const chatId = ctx?.conversationId ?? ctx?.senderId ?? ctx?.from;
			const channel = extractChannelId(ctx) ?? "telegram";
			const connectUserId = ctx?.senderId ?? ctx?.from ?? chatId;
			if (_pendingSessionWait) {} else {
				_pendingSessionWait = true;
				waitForWalletSession(3e5).then((session) => {
					console.log(`[/connect] Session established: ${session.address} (chain ${session.chainId})`);
					if (connectUserId) {
						const onboardingMsg = getOnboardingFlow(String(connectUserId)).onWalletConnected(session.address, `chain ${session.chainId}`);
						if (onboardingMsg && _api) {
							createChannelSender(_api).send(channel, String(chatId), onboardingMsg.text).catch((err) => console.log(`[/connect] Failed to send onboarding msg: ${err}`));
							return;
						}
					}
					if (_api && chatId) createChannelSender(_api).send(channel, String(chatId), `Wallet connected!\n\nAddress: ${session.address.slice(0, 6)}...${session.address.slice(-4)}\nChain: ${session.chainId}\n\nYou're ready to trade. Try: "What's the price of ETH?" or "Show my balance"`).catch((err) => console.log(`[/connect] Failed to send confirmation: ${err}`));
				}).catch((err) => {
					console.log(`[/connect] Session wait failed: ${err instanceof Error ? err.message : String(err)}`);
					if (_api && chatId) createChannelSender(_api).send(channel, String(chatId), "Connection timed out. Run /connect to try again.").catch((sendErr) => console.log(`[/connect] Failed to send timeout msg: ${sendErr}`));
				}).finally(() => {
					_pendingSessionWait = false;
				});
			}
			const encodedUri = encodeURIComponent(result.pairingUri);
			if (!wallet.deepLink) return { text: `Copy this code and paste it in your wallet's WalletConnect input:\n\n\`${result.pairingUri}\`\n\nExpires in 5 minutes.` };
			const url = `${wallet.deepLink}${encodedUri}`;
			return { text: `[Connect ${wallet.label}](${url})\n\nTap the link above to open ${wallet.label} and approve the connection. Expires in 5 minutes.` };
		}
		return { text: "WalletConnect failed to generate a pairing link. The relay server may be down. Try again in a minute." };
	} catch (err) {
		return { text: `Connection failed: ${err instanceof Error ? err.message : String(err)}` };
	}
}
/** /connect — shows wallet menu with tappable options */
const connectCommand = {
	name: "connect",
	description: "Connect your mobile wallet via WalletConnect",
	acceptsArgs: false,
	requireAuth: true,
	handler: async (_ctx) => {
		const state = getWalletState();
		if (state.connected && state.address) return { text: `Wallet already connected: ${state.address.slice(0, 6)}...${state.address.slice(-4)} (chain ${state.chainId})\n\nUse /disconnect to disconnect first.` };
		const lines = ["Which wallet do you use?\n"];
		for (const w of WALLETS) lines.push(`  /connect_${w.id} — ${w.label}`);
		lines.push("  /connect_bankr — Bankr (custodial, multi-chain)");
		lines.push("\nTap one to connect.");
		return { text: lines.join("\n") };
	}
};
/** Generate a /connect_<wallet> command */
function makeWalletCommand(wallet) {
	return {
		name: `connect_${wallet.id}`,
		description: `Connect ${wallet.label} via WalletConnect`,
		acceptsArgs: false,
		requireAuth: true,
		handler: async (ctx) => doConnect(wallet, ctx)
	};
}
/** All individual wallet commands: /connect_metamask, /connect_rainbow, etc. */
const walletConnectCommands = WALLETS.map(makeWalletCommand);
const connectBankrCommand = {
	name: "connect_bankr",
	description: "Connect Bankr custodial wallet (multi-chain)",
	acceptsArgs: false,
	requireAuth: true,
	handler: async (_ctx) => {
		const state = getWalletState();
		if (state.connected && state.mode === "bankr") return { text: [
			"**Already connected via Bankr**",
			"",
			`EVM: ${state.bankrEvmAddress ?? "unknown"}`,
			state.bankrSolAddress ? `Solana: ${state.bankrSolAddress}` : null,
			state.bankrClub ? "Bankr Club: Active" : null,
			"",
			"Use /connect to switch to a different wallet."
		].filter(Boolean).join("\n") };
		if (state.connected) return { text: `Wallet already connected (${state.mode}): ${state.address?.slice(0, 6)}...${state.address?.slice(-4)}\n\nDisconnect first to switch to Bankr.` };
		const apiKey = getCredentialVault().getSecret("bankr.apiKey", "connect-command");
		if (!apiKey) return { text: [
			"**BANKR_API_KEY not set**",
			"",
			"To use Bankr as your wallet:",
			"1. Create an account at https://bankr.bot",
			"2. Get an API key with Agent API enabled: https://bankr.bot/api",
			"3. Set the environment variable:",
			"   Fly.io: `fly secrets set BANKR_API_KEY=\"bk_your_key\" -a <your-app>`",
			"   Docker: add `BANKR_API_KEY=bk_your_key` to your `.env` file"
		].join("\n") };
		try {
			const result = await initWalletService({ bankrApiKey: apiKey });
			if (result.mode !== "bankr") return { text: "Failed to initialize Bankr wallet. Check your BANKR_API_KEY." };
			const newState = getWalletState();
			return { text: [
				"**Connected via Bankr** (custodial wallet)",
				"",
				`EVM: ${newState.bankrEvmAddress ?? result.address ?? "unknown"}`,
				newState.bankrSolAddress ? `Solana: ${newState.bankrSolAddress}` : null,
				newState.bankrClub ? `Bankr Club: Active` : null,
				"",
				"Transactions execute server-side. No phone approval needed.",
				"Bankr's Sentinel security system screens all transactions.",
				"",
				"This is a custodial wallet — Bankr holds the keys.",
				"For self-custody, use /connect_metamask or another wallet."
			].filter(Boolean).join("\n") };
		} catch (err) {
			const msg = err instanceof Error ? err.message : String(err);
			if (msg.includes("Agent API not enabled") || msg.includes("403")) return { text: [
				"**Agent API not enabled on this key**",
				"",
				"Your Bankr API key was recognized but doesn't have Agent API access.",
				"",
				"**Fix it:**",
				"1. Go to https://bankr.bot/api",
				"2. Find your API key",
				"3. Enable the \"Agent API\" toggle"
			].join("\n") };
			return { text: `Bankr connection failed: ${msg}` };
		}
	}
};
const disconnectCommand = {
	name: "disconnect",
	description: "Disconnect the current wallet",
	acceptsArgs: false,
	requireAuth: true,
	handler: async (_ctx) => {
		const state = getWalletState();
		if (!state.connected) return { text: "No wallet connected." };
		const addr = state.address ?? "unknown";
		const short = `${addr.slice(0, 6)}...${addr.slice(-4)}`;
		const mode = state.mode ?? "unknown";
		try {
			await disconnectWallet();
			return { text: `Disconnected wallet ${short} (${mode}).\n\nUse /connect to pair a new wallet.` };
		} catch (err) {
			return { text: `Failed to disconnect: ${err instanceof Error ? err.message : String(err)}` };
		}
	}
};
//#endregion
export { connectBankrCommand, connectCommand, disconnectCommand, setConnectCommandApi, walletConnectCommands };

//# sourceMappingURL=connect-command.mjs.map