import { Actor, Handle, Turn } from './actor.js'; import { Dataspace } from './dataspace.js'; import { Relay, spawnRelay } from './relay.js'; import * as net from 'net'; import { mint, sturdyEncode, SturdyRef, validate, Resolve } from './sturdy.js'; import { KEY_LENGTH } from './cryptography.js'; import { attenuate } from './rewrite.js'; import { Bytes, IdentityMap } from '@preserves/core'; import { Attenuation, isResolve } from './gen/sturdy.js'; const secretKey = new Bytes(KEY_LENGTH); mint('syndicate', secretKey).then(v => { console.log(v.asPreservesText()); console.log(sturdyEncode(v).toHex()); }); Turn.for(new Actor(), t => { const ds = t.ref(new Dataspace()); function spawnConnection(t: Turn, socket: net.Socket) { console.log('connection', socket.remoteAddress, socket.remotePort); spawnRelay(t, { packetWriter: bs => socket.write(bs), setup(t: Turn, r: Relay) { socket.on('error', err => t.freshen(t => ((err as any).code === 'ECONNRESET') ? t.quit() : t.crash(err))); socket.on('close', () => t.freshen(t => t.quit())); socket.on('end', () => t.freshen(t => t.quit())); socket.on('data', data => r.accept(data)); t.actor.atExit(() => socket.destroy()); }, initialRef: t.ref({ handleMap: new IdentityMap(), async assert(t, a, h) { if (!isResolve(a)) return; const r = Resolve._.sturdyref(a); if (!await validate(r, secretKey)) { console.warn(`Invalid SturdyRef: ${r.asPreservesText()}`); return; } const cavs: Attenuation = []; SturdyRef._.caveatChain(r).forEach(cs => cavs.push(... cs)); const attenuated_ds = attenuate(ds, ... cavs); t.freshen(t => this.handleMap.set( h, t.assert(Resolve._.observer(a), attenuated_ds))); }, retract(t, h) { t.retract(this.handleMap.get(h)); this.handleMap.delete(h); } }), // debug: true, }); } t.spawn(t => { const server = net.createServer(socket => t.freshen(t => spawnConnection(t, socket))); server.on('error', err => t.freshen(t => t.crash(err))); server.listen(5999, '0.0.0.0', 512); t.actor.atExit(() => { try { server.close(); } catch (e) { console.error(e); } }); }); });