← back to Ken
kalshi-dash/src/setup/steps/ConnectKalshi.jsx
96 lines
import React, { useState } from 'react';
import { post } from '../../api';
export default function ConnectKalshi({ data, update, next, back }) {
const [apiKey, setApiKey] = useState(data.keys?.api_key || '');
const [privateKey, setPrivateKey] = useState(data.keys?.private_key || '');
const [env, setEnv] = useState(data.keys?.env || 'demo');
const [saving, setSaving] = useState(false);
const [error, setError] = useState(null);
async function save() {
setSaving(true); setError(null);
try {
const r = await post('/kalshi', {
action: 'save_keys',
api_key: apiKey,
private_key: privateKey,
env,
});
if (r.success) {
update({ keys: { api_key: apiKey, private_key: '***', env } });
next();
} else setError(r.error || 'Failed to save');
} catch { setError('Connection error'); }
setSaving(false);
}
function skip() {
update({ keys: null, skippedConnect: true });
next();
}
return (
<div className="space-y-6">
<div className="text-center">
<h2 className="text-2xl font-bold mb-2">Give Me the Keys</h2>
<p className="text-gray-400 text-sm">Your API credentials, darling. I don't have all day.</p>
</div>
<div className="card space-y-4">
{/* Environment Toggle */}
<div>
<label className="block text-xs text-gray-400 mb-1.5 font-medium">Which playground are we using?</label>
<div className="flex gap-2">
<button onClick={() => setEnv('demo')} className={`flex-1 py-2 rounded-lg text-sm font-medium transition ${env === 'demo' ? 'bg-yellow-500/15 text-yellow-400 border border-yellow-500/30' : 'bg-gray-800/50 text-gray-500 border border-gray-700'}`}>
Demo (Smart)
</button>
<button onClick={() => setEnv('prod')} className={`flex-1 py-2 rounded-lg text-sm font-medium transition ${env === 'prod' ? 'bg-green-500/15 text-green-400 border border-green-500/30' : 'bg-gray-800/50 text-gray-500 border border-gray-700'}`}>
Production (Brave)
</button>
</div>
</div>
<div>
<label className="block text-xs text-gray-400 mb-1.5 font-medium">API Key ID (the one they gave you)</label>
<input type="text" value={apiKey} onChange={e => setApiKey(e.target.value)}
placeholder="Paste it here, bubeleh"
className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-sm focus:border-amber-500 focus:outline-none font-mono" />
</div>
<div>
<label className="block text-xs text-gray-400 mb-1.5 font-medium">Private Key (the whole megillah, PEM format)</label>
<textarea value={privateKey} onChange={e => setPrivateKey(e.target.value)}
placeholder="-----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY-----"
rows={6}
className="w-full px-3 py-2 bg-gray-800/50 border border-gray-700 rounded-lg text-sm focus:border-amber-500 focus:outline-none font-mono text-xs leading-relaxed" />
<p className="text-[10px] text-gray-600 mt-1">Don't worry, I keep it locked up tighter than your grandmother's jewelry box</p>
</div>
{error && <p className="text-red-400 text-xs">{error}</p>}
</div>
<div className="card bg-gray-800/30">
<h3 className="text-sm font-medium mb-2">What, you don't have keys yet? Oy vey.</h3>
<ol className="text-xs text-gray-400 space-y-1.5 list-decimal list-inside">
<li>Go log into <span className="text-amber-400 font-mono">ken.com</span> like a mensch</li>
<li>Find Settings → API Keys (it's not that hard, look around)</li>
<li>Click "Create API Key" and <strong>download that private key file immediately</strong></li>
<li>Copy the Key ID and paste the PEM contents up there. Simple.</li>
</ol>
<p className="text-[10px] text-red-400 mt-2">Listen to me — that private key file? You can only download it ONCE. Lose it and you start over. Don't say I didn't warn you.</p>
</div>
<div className="flex items-center justify-between">
<button onClick={back} className="text-sm text-gray-500 hover:text-gray-300">Back</button>
<div className="flex items-center gap-3">
<button onClick={skip} className="text-sm text-gray-500 hover:text-gray-300">Skip (play pretend)</button>
<button onClick={save} disabled={saving || !apiKey || !privateKey} className="btn btn-p">
{saving ? 'Saving, patience...' : 'Save & Continue'}
</button>
</div>
</div>
</div>
);
}