Status: Accepted
Date: 2026-04-10
Commit: 8fe1404
The CAS beacon announces off-chain Announcement objects keyed by their SHA-256 content hash. Resolvers must retrieve those announcements to process the beacon signal. Two sensible transport choices exist:
https://ipfs.io, https://dweb.link). An HTTP request to a public IPFS gateway that returns the content. Strong: trivial implementation, works in any browser, zero boot time, minimal bundle. Weak: trust-a-gateway, single-point-of-failure, gateways can censor.Wallet webapps and interactive resolvers need fast, lightweight retrieval. Long-running CLIs and service operators might prefer a full Helia node. Both use cases must be supportable without forcing either.
CasExecutor interface: two default implementations (Helia, HTTP gateway): consumer picks.Option 3. Introduce CasExecutor interface in @did-btcr2/api/src/cas.ts:
interface CasExecutor {
retrieve(hash: string): Promise<Uint8Array | null>;
publish(data: Uint8Array): Promise<string>;
}
Two default implementations ship:
IpfsCasExecutor: backed by a caller-provided Helia instance. Deterministic CID derivation from base64url-nopad SHA-256.HttpGatewayCasExecutor (implied by default): reads via the public IPFS gateway at https://ipfs.io unless the caller overrides with DEFAULT_CAS_GATEWAY.Consumer chooses by constructing the appropriate executor and passing it into Api.cas. The resolver doesn’t know or care which implementation is in use.
Default fallback when no CAS is configured: HTTP gateway (the lightweight default fits the wallet / browser scenario and degrades gracefully if the gateway is down: the error is visible).
Positive
CasExecutor interface is a natural place for additional backends (S3-compatible, local blockstore, cache layer, bucket-of-mirrors).Negative
fetch-mock style.Explicitly accepted trade-offs
packages/api/src/cas.ts: CasExecutor, IpfsCasExecutor, DEFAULT_CAS_GATEWAY.packages/method/src/core/beacon/cas-beacon.ts: consumer of the CAS retrieval path via NeedCASAnnouncement.