Skip to content

Reference source · 0.1.0-dev.11

host-peer.ts

src/host-peer.ts · Download original file

import type { Identity, Credential } from './identity.ts';
import { TrustStore } from './identity.ts';
import { seal, open } from './envelope.ts';
import type { Transport } from './sdk.ts';
import type { MigrationProof } from './migration-proof.ts';
import { parseObject, unb64, requireThat, ProtocolError } from './core.ts';

// Explicit Host-to-Host transport; it carries no source application tokens or private keys.
export class HostPeer {
  identity: Identity; credential: Credential; recipient: Credential; trust: TrustStore; transport: Transport; clock: () => number;
  constructor(identity: Identity, credential: Credential, recipient: Credential, trust: TrustStore, transport: Transport, clock: () => number) {
    this.identity = identity; this.credential = credential; this.recipient = recipient; this.trust = trust; this.transport = transport; this.clock = clock;
  }
  async exchange(body: Record<string, any>): Promise<Record<string, any>> {
    const destination = this.trust.validate(this.recipient, this.clock(), undefined, 'host');
    const outgoing = seal(body, this.identity, this.credential, destination, this.clock());
    const header = parseObject(unb64(outgoing.protected));
    const response = open(await this.transport(outgoing), this.identity, this.trust, this.clock(), destination.subject, header.messageId);
    requireThat(response.sender.kind === 'host' && response.sender.signingKid === destination.signingKid && response.sender.encryptionKid === destination.encryptionKid, 'wrong_transfer_host');
    if (response.body.status === 'error') throw new ProtocolError(response.body.error); return response.body;
  }
  async activate(transferId: string, release: MigrationProof): Promise<MigrationProof> {
    return (await this.exchange({ operation: 'migration_activate', transfer_id: transferId, release })).activation as MigrationProof;
  }
}