@comms-id/website-logo
Typed client for the Comms.ID Website logo API (https://api.comms.id/logo/v1): a company's logo, resolved from its website address.
src/ is generated from the Website logo contract (packages/website-logo-service/openapi/website-logo.v1.json) by @comms-id/forge-transformers. Do not edit it: change the contract and run pnpm --filter @comms-id/forge-transformers generate.
import { createWebsiteLogoClient } from "@comms-id/website-logo/server";
const client = createWebsiteLogoClient({
clientId: process.env.COMMS_ID_CLIENT_ID!,
privateJwk: JSON.parse(process.env.COMMS_ID_PRIVATE_JWK!),
});
const reply = await client.resolve({"hostname": "example.com", "mode": "direct-favicon"});
Operations
resolve: Resolve a website logo using the selected source or named composition. A genuine miss is a 200 reply with status missing; source failures remain distinct.
Every operation is a read, safe to repeat, and is retried after a retryable failure. A reply that is not a match is one of the outcomes of the reply convention: an error with outcomeOf(error) of no-match, source-unavailable or failed; an outage is never a "no match".
Test it first
createWebsiteLogoFixtureClient() from @comms-id/website-logo/fixtures answers from the contract's own examples with no network and says so (fixture: true). To call the TEST service (synthetic replies, your development app's key), pass environment: "test"; going live changes only the environment and the key.
COMMS_ID_PRIVATE_JWK is an ML-DSA-87 private JWK (kty AKP, with priv and pub). The server entry needs Node.js 24.7 or later, or a Cloudflare Worker with the compatibility flag webcrypto_modern_algorithms.
Entries: . (types and errors, safe in a browser), ./server (signs each call), ./browser (your relay route; never signs), ./fixtures (LOCAL FIXTURES, no network), ./descriptor (what @comms-id/relay may forward).
LICENSE is the consumer client licence.
The image
@comms-id/website-logo/controller is the headless controller of a Website logo image: it asks the service about a site and decides what to show, and it refuses any image outside the Comms.ID hosts. It has no framework and no DOM. @comms-id/website-logo-react (a hook and a component) and <comms-id-website-logo> (a web element) run on it, and so can your own UI.
import { createWebsiteLogoController } from "@comms-id/website-logo/controller";
const controller = createWebsiteLogoController({ client, site: "example.com" });
controller.subscribe(() => render(controller.getState())); // state.url is the image to load, or the letter state.monogram
src/local/profile.ts is the only product-specific part: it reads the site, prepares the call and takes the Comms.ID image from the reply. Everything else is generated.