keyring-bifold — Keyring’s core packages (a Bifold fork)

Repo: github.com/berkmancenter/keyring-bifold — npm scope @bifold/*. Consumed by keyring-wallet as the bifold/ git submodule.

Keyring is two repositories because its ancestor was. The OpenWallet Foundation’s Bifold is a framework for building verifiable-credential wallets on React Native and Credo-TS, and a wallet built on it is a thin app over Bifold’s core. The Berkman Klein Center kept that split: keyring-wallet/app/ holds the Keyring experience, and this fork holds everything reusable — the screens, the agent, and the three things Keyring added that Bifold never had: peer-to-peer relationship credentials, a witness, and hardware attestation. In the OpenVTC turn of September 2026 it gained a fourth: a complete Trust Task client that lets a phone act as a Personal Network Manager over a cloud VTA, join a community and run the vetting ceremony from either seat. Nearly every user-visible feature on the wallet page lives here; the wallet repo mostly carries the pointer.

The history runs back to Indicio’s aries-mobile-agent-react-native sample (first commit 2020-11-06) through Bifold 3.0.x; the public Keyring import is 2026-04-15, tracking upstream Bifold through credo-ts 0.6.3 and then hopping to the 0.7.1-pr-2704 snapshot that carries DIDComm v2. Of the fork’s 3,319 commits, 643 are from September and the first week of October 2026. Commits must be signed and DCO signed-off (09-04).

Packages

PackageVersionWhat it is
@bifold/core3.0.16The wallet: screens, navigation, onboarding, the Credo agent configuration (AnonCreds, Indy VDR, OpenID4VC, mediation). Keyring’s additions are modules/vrc/ (the relationship exchange and witnessed exchange, RCE v3 over DIDComm v1, document loaders and credential-kind detection), modules/trust-tasks/ (below) and hardware-signing/ — the attestation stack with the VRC orchestration taken off, so “sign this payload with a device key and get verifiable evidence back” works without Credo or DIDComm.
@bifold/trust-tasks0.1.0-alpha.1Platform-neutral Trust Task plumbing shared by the phone and the witness: eddsa-jcs-2022 document proofs, digestMultibase and the framework’s taskDigestMultibase, the DIDComm binding-0.2 carriage and the v2 envelope, the Ajv 2020-12 payload validator, a tsp namespace (ports SigningKey / KeyAgreement / VidResolver, HPKE, CESR frames, Rev 2 and Rev 3 codecs, pack/unpack), vetting/ (ticket URI, match code, statement shape, role card, requirement evaluation) and enrolment/ (the keyring://vta/enrol offer and its domain-separated code). Nothing in it may import Node-only or React-Native-only modules. It vendors @openvtc/vti-tsp-js 0.3.0 as a tarball for the wire tables and reference pack/unpack.
@bifold/credo-tsp-adapter0.1.0-alpha.1The Askar-backed implementations of the three TSP ports — the “credo-tsp-adapter” of the integration plan’s Phase D. The static private key never leaves Askar; only the Diffie-Hellman shared secret exits to feed HPKE’s KDF. Registered through Credo’s public module API, so no credo-ts fork.
@bifold/witness-server1.0.0Node.js witness for the witnessed-vrc-exchange: sessions, challenge verification, VWC issuance over DIDComm (v1, and v2 beside it with WITNESS_DIDCOMM_VERSIONS=v1,v2), Trust Task documents on either carriage or inside a TSP envelope, a web UI and REST API, no message history retained by default, and a pluggable LocalityProvider whose BLE implementation (BleLocalityProvider, a noble central) verifies the phones’ signed transcripts and puts the proof in the credential.
@bifold/mediator-server1.0.0A DIDComm mediator for a developer’s own machine, so a wallet boots without anyone else’s infrastructure: v1 always, --didcomm-v2 adds Coordinate Mediation 2.0 and Pickup, tunnel or local endpoints, writes MEDIATOR_URL into the app’s .env.
@bifold/react-native-attestation3.0.16Native module: iOS App Attest with Secure Enclave keys, Android Key Attestation with StrongBox/TEE, full X.509 chain verification done natively on the verifying phone.
@bifold/react-native-locality-peripheral0.1.0The phone’s BLE peripheral role in the co-presence ceremony: advertise the rendezvous EID as a service UUID, serve two GATT characteristics, sign the transcript with the attestation key. Android verified live on devices (08-21); iOS type-checked only.
@bifold/vrc-reference0.1.0-alpha.1Standalone Node implementation of VRC and witnessed VRC exchange over DIDComm v2 with conformance tests — the reference the wallet is checked against.
@bifold/vrc-contexts, @bifold/vrc-shared0.1.0-alpha.1JSON-LD contexts and a pure-TS JCS (RFC 8785) implementation; server-side helpers (wallet paths, Askar utilities, document loaders) explicitly not for the phone.
@bifold/oca, @bifold/verifier, @bifold/remote-logs, @bifold/react-hooks3.0.16Inherited Bifold packages: Overlay Capture Architecture for credential display, verification utilities, Loki remote logging, Credo React hooks.

The Trust Task client (core/src/modules/trust-tasks/)

About 21,000 lines in module/ alone, grown from nothing on 2026-09-15. Two legs with the same shape: vtaAgent / VtaClient is the phone’s one session with its own agent (link state machine, key swap and rotation, devices and presence, consent requests pushed to the phone as approver, step-up, approval rules, owner acts behind biometrics), and vtiAgent is the phone’s session with a community as a persona (manifest, join, invitation offers, status lists, notices, inbox, wallet cards). Carriages are pluggable — DidCommV1Carriage, DidCommV2Carriage, TspCarriage — and VtiMediatorTransport logs into the Affinidi mediator and resolves DIDs with retry. vtiVetting (2,400 lines) is both seats of the ceremony “as the reference client does it”, citing openvtc-core/src/vetting/{applicant,vetter,tickets}.rs by name: applicant Sent → Accepted → Session → Attested, vetter request+ticket → Accepted → Session → CardReceived → Attested, every peer document opened and verified before it is acted on. dtgV1Writing chooses the statement shape per community. The screens/ directory is the OpenVTC face of the app: VtaAgentHome, VtaLink, VtaCreateAgent, VtaDevices, VtaRequests, VtaAskMe, AgentChips, VtiJoin, VtiInvited, VtiCommunity, VtiVetting.

How the wallet consumes it

The wallet pins this repo as a git submodule at a SHA (37f34dc7 on 10-07) and declares the packages as ordinary dependencies at their versions; in development the app’s Metro config and jest mappers read src/ directly, so a core change needs no build, while release bundles use each package’s build/. Every feature that needs new core therefore lands twice: a PR here, then a chore/pin-bifold-* PR in the wallet moving the pointer — there were more than thirty such bumps between 09-22 and 10-07, which is why the wallet’s log reads like a mirror of this one. CI here includes vti-conformance, which clones the wallet, builds its Rust card-verify (and a second copy at VTI vta-service-v0.47.0) with cargo build --locked, and has upstream’s vta-sdk judge every Vetting Card and statement Keyring signs.

Recent Development

  • 10-01 → 10-07 (#244–#348). The automatic agent connection from a host’s QR (#247); the join screen’s “ways in” from manifest 0.3 (#251, #252); Requests screen, member notices, rejoin (#260–#262); the TSP re-greet after no answer (#312); approval rules “Ask me before…” (#285) and approvers following a key swap (#287); the community store per identity (#289); named devices (#307, #308); scan adds another agent, agent chips, membership of another agent (#303, #320, 10-05/06); join shows the identity the community sees (#305, #319); approve asks the owner (#317); a distinct vetter header and granted toast (#314, #315); persona keys held only on use (#336); one address path and cards of unlinked agents hidden (#339, #348).
  • 09-28 → 09-30 (#176–#243). Devices, presence, sibling notices and the removed-phone erase (#174–#179, #182); persona keys in memory with migration (#180, #181); two phones finishing a link (#194); push set-wake (#196); the statement delivered as a signed document openvtc opens (#184, 09-28); the step-up answered from the phone (#200), consent requests showing the match code (#199), every VTA reply’s proof checked (#204), each document signed for the purpose upstream signs it for (#203, #210); DTG Credentials v1: the v1 context bundled, vetted/1 and witnessed/1 and role VACs read, vetted/1 written behind a flag then per community, the legacy shape cut off by date (#231–#242); conformance held against VTI 0.47’s SDK (#241).
  • 09-22 → 09-26 (#56–#175). prague-2, Farm membership, any VTA with any community, join as a profile, cross-mediator DIDComm, names not DIDs (#56–#69); the desk’s grant standing (#71); My Agent redesign (#75); the envelope proof fix for VTI-42 (#76); DID classification for one scanner (#78–#84); the vetter grant revocation catch-up (#94); unlink, leave, real join state, a ticket for another community (#98–#105); the card digest and keyboard fixes (#114, #116); the VTI conformance vectors and upstream-signed fixtures (#117, #118); persist-before-ack and inbound proofs (#120, #128); eligibility VP as upstream verifies it (#125, #126); the own-agent module and screens (#136, #137); console invitations redeemed (#139); community journey and agent segments (#142–#147).
  • 09-15 → 09-21 (direct to main). Address a VTA or VTC by DID through the mediator; the phone as manager of its own VTA (“architecture B”); join by invitation as a VTA-held persona; the vetting ticket link and match code; both sides of the vetting guide; vetter profiles; grant revocation; the phone↔VTA leg on TSP Rev 3.
  • 09-08 → 09-18 (#39–#54). Trust Tasks integration and the VRC/witnessed exchange as Trust Tasks with TSP carriage (#39, #43); the wallet answering credential-exchange/query (#44); BLE locality on Android (#40) and iOS (#47), the witness as a noble central (#49); R-Card profile picture (#45); reference-app demos (#46); one authentication prompt per exchange (#51); credo-ts 0.7 with DIDComm v2 (#54, 09-18).
  • 08-05 → 09-03. VC 2.0 with Data Integrity proofs (#31); mediator pickup strategy (#41). Before that: tracking upstream Bifold releases (3.0.x, credo 0.6.3, OpenID refresh) through April.

See also: keyring-wallet, peer-identity-vetting, witnessed-vrc-exchange, trust-spanning-protocol, didcomm, verifiable-trust-agent, vta-topology, statement-credential, openvtc