import { createShade } from '@shade/sdk'; import { loadConfig } from '../config.js'; export async function peerAddCommand(address: string): Promise { const config = loadConfig(); const shade = await createShade({ prekeyServer: config.prekeyServer, storage: config.storage, address: config.address, autoReplenish: false, }); try { // Fetching and establishing happens on first send; we fake-send by // calling the manager directly. const transport = shade.getTransport(); const bundle = await transport.fetchBundle(address); await shade.getManager().initSessionFromBundle(address, bundle); const fp = await shade.getFingerprintFor(address); console.log(`\x1b[32m✓\x1b[0m Session established with ${address}`); console.log(` Fingerprint: ${fp}`); console.log(); console.log('Verify this fingerprint with the peer out-of-band before exchanging sensitive messages.'); } finally { await shade.shutdown(); } } export async function peerListCommand(): Promise { // Loading the config validates the environment; we don't need its values // until session enumeration is implemented (TODO). loadConfig(); // For list, we need to enumerate sessions from storage. The StorageProvider // doesn't currently expose a "list all sessions" method. For v1, we show // a message and suggest the dashboard. console.log('\x1b[33mNote:\x1b[0m CLI session enumeration not yet implemented.'); console.log('Run `shade dashboard` for a live session list.'); } export async function peerVerifyCommand(address: string, fingerprint: string): Promise { const config = loadConfig(); const shade = await createShade({ prekeyServer: config.prekeyServer, storage: config.storage, address: config.address, autoReplenish: false, }); try { const match = await shade.verify(address, fingerprint); if (match) { console.log(`\x1b[32m✓\x1b[0m Fingerprint matches session with ${address}`); } else { const actual = await shade.getFingerprintFor(address); console.log(`\x1b[31m✗\x1b[0m Fingerprint does NOT match`); console.log(` Expected: ${fingerprint}`); console.log(` Actual: ${actual}`); process.exitCode = 1; } } finally { await shade.shutdown(); } } export async function peerRemoveCommand(address: string): Promise { const config = loadConfig(); const shade = await createShade({ prekeyServer: config.prekeyServer, storage: config.storage, address: config.address, autoReplenish: false, }); try { await shade.getManager().resetSession(address); console.log(`\x1b[32m✓\x1b[0m Session with ${address} removed`); } finally { await shade.shutdown(); } }