import { ShadeSessionManager } from '../../packages/shade-core/src/index.js'; import { SubtleCryptoProvider, MemoryStorage } from '../../packages/shade-crypto-web/src/index.js'; const crypto = new SubtleCryptoProvider(); async function main() { console.log('=== Shade Basic Conversation ===\n'); // Set up Alice and Bob with separate storage const alice = new ShadeSessionManager(crypto, new MemoryStorage()); const bob = new ShadeSessionManager(crypto, new MemoryStorage()); await alice.initialize(); await bob.initialize(); // Show fingerprints (safety numbers for verification) console.log('Alice fingerprint:', await alice.getIdentityFingerprint()); console.log('Bob fingerprint: ', await bob.getIdentityFingerprint()); console.log(); // Bob generates one-time prekeys (would be uploaded to a prekey server) const bobOTPKs = await bob.generateOneTimePreKeys(5); const bobBundle = await bob.createPreKeyBundle(); bobBundle.oneTimePreKey = { keyId: bobOTPKs[0].keyId, publicKey: bobOTPKs[0].keyPair.publicKey, }; // Alice fetches Bob's bundle (here: directly) and starts a session await alice.initSessionFromBundle('bob', bobBundle); // Alice → Bob console.log('→ Alice encrypts: "Hello Bob!"'); const msg1 = await alice.encrypt('bob', 'Hello Bob!'); const plain1 = await bob.decrypt('alice', msg1); console.log(`← Bob decrypts: "${plain1}"`); // Bob → Alice (triggers DH ratchet step) console.log('\n→ Bob encrypts: "Hi Alice, got your message"'); const msg2 = await bob.encrypt('alice', 'Hi Alice, got your message'); const plain2 = await alice.decrypt('bob', msg2); console.log(`← Alice decrypts: "${plain2}"`); // Several more turns console.log('\n=== Continued conversation (each message has a unique key) ==='); const conversation = [ ['alice', 'How are you?'], ['bob', 'Doing well!'], ['alice', 'Want to grab coffee?'], ['bob', 'Sure, when?'], ] as const; for (const [from, text] of conversation) { const sender = from === 'alice' ? alice : bob; const receiver = from === 'alice' ? bob : alice; const recvAddr = from === 'alice' ? 'alice' : 'bob'; const sendAddr = from === 'alice' ? 'bob' : 'alice'; const env = await sender.encrypt(sendAddr, text); const plain = await receiver.decrypt(recvAddr, env); console.log(`${from === 'alice' ? 'Alice' : 'Bob '}: "${plain}"`); } console.log('\n=== Done. Every message used a unique key. ==='); } main().catch(console.error);