/** * Bob — receiver. Boots a Shade runtime and mounts the transfer route on * port 9992. Incoming uploads are decrypted, integrity-checked, and saved * to ./received/. */ import { mkdirSync } from 'node:fs'; import { join } from 'node:path'; import { createShade } from '@shade/sdk'; const PREKEY_URL = 'http://localhost:9991'; const PORT = 9992; const OUT_DIR = join(import.meta.dir, 'received'); mkdirSync(OUT_DIR, { recursive: true }); const bob = await createShade({ prekeyServer: PREKEY_URL, address: 'bob' }); bob.configureTransfers({ resolveBaseUrl: async () => { throw new Error('bob is receive-only'); }, }); bob.onIncomingTransfer(async (incoming) => { const name = incoming.metadata.name ?? incoming.streamId; const path = join(OUT_DIR, name.replace(/[^a-zA-Z0-9._-]/g, '_')); console.log(`[bob] incoming "${name}" from ${incoming.from} → ${path}`); const handle = await incoming.accept({ output: { kind: 'file', path } }); void handle.done().then((result) => { console.log(`[bob] done "${name}" — ${result.bytesSent} B, sha256=${result.sha256}`); }); }); const app = await bob.transferRoute(); Bun.serve({ port: PORT, fetch: app.fetch }); console.log(`Bob's transfer endpoint listening on http://localhost:${PORT}`); console.log(`Saving incoming files to ${OUT_DIR}`);