Skip to content

Upgrade Phases 3+5: bifold 3.0.16 + credo-ts 0.6.3 + React 19 + DTG/VC 2.0#26

Closed
albertoleon7794 wants to merge 2247 commits into
mainfrom
upgrade/bifold-3.x
Closed

Upgrade Phases 3+5: bifold 3.0.16 + credo-ts 0.6.3 + React 19 + DTG/VC 2.0#26
albertoleon7794 wants to merge 2247 commits into
mainfrom
upgrade/bifold-3.x

Conversation

@albertoleon7794

@albertoleon7794 albertoleon7794 commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Phase 3 of the upgrade plan (berkmancenter/keyring-wallet#10). This branch was cut from upstream openwallet-foundation/bifold-wallet v3.0.16 ("branch swap" strategy), with the fork's main tied in via a merge commit so the histories connect. It carries:

  1. Port Keyring delta onto v3.0.16 (68d9da80) — VRC module, chat/witness screens, vrc-shared, vrc-reference, witness-server, and the rebuilt react-native-attestation (upstream 3.0.16 base + Keyring crypto).
  2. Migrate to credo-ts 0.6.3 (cdb9289c) — DIDComm APIs moved under agent.modules.didcomm, renamed DIDComm types/events, KMS-based key management, @openwallet-foundation/askar-* store config, W3cCredentialRecord.encoded instead of the now-private .credential, jest ESM transforms for credo's .mjs builds, React 19 snapshot updates, and lint fixes for the upstream flat eslint config.
  3. Post-port fixes — Keyring onboarding carousel/Get Started restore (63a0fdc6), attestation Android stubs (69062ae2), two-device E2E fixes for credo 0.6 / New Arch (6cd44a9a), legacy R-Card template proof migration for the Askar 0.2→0.6 store upgrade (3dd6a786), and RNGH jest mock fix for ChatMessage tests (71ec921f).

Because of the branch-swap, the diff against main includes all upstream changes between the old base and v3.0.16 — review focus should be the Keyring commits listed above.

Verification

Notes

Phase 5 (3828b301) — DTG spec alignment + W3C VC 2.0

  1. RCard/VRC separation — VRC issuer is a bare DID for v2 peers; contact info moves to an exchanged, auto-accepted RelationshipCard credential (new JSON-LD context with @type: @json jCard); display resolves newest RCard with legacy-issuer fallback.
  2. JCS witness digestjcsCanonicalize (RFC 8785) in @bifold/vrc-contexts, used by witness-server and vrc-reference.
  3. VC 2.0 verification@credo-ts/core 0.6.3 yarn patch (v2 context accepted as first @context, optional issuanceDate) + bundled VCDM 2.0 context + pinned standard security contexts for offline sign/verify.
  4. VC 2.0 issuance with RCE v2 negotiation — handshake announces vrc:rceVersion:2; v2 peers get VCDM 2.0 VRC/RCard/VWC (Ed25519 suite context included at build time to keep @context stable through signing); v1 peers keep the full legacy exchange (1.1 VRC with embedded issuer object, no RCard offer). Witness mirrors the VRC's data model and widens its freshness window for clock-skew backdating.

Phase 5 verification: core jest 159 suites / 1434 tests; VC 2.0 conformance sign/verify round-trips; two-device E2E (new↔new, VC 2.0) and backward-compat E2E against a Phase-4 baseline build both green.

Attestation hardening (88f80fe8)

  1. Google attestation trust anchors (cherry-pick of fix: align Google attestation trust anchors with published roots #23) — embed Google's three published attestation roots (legacy RSA, re-signed RSA, RKP ECDSA) and validate Android hardware attestation chains against them only, no self-as-anchor. Required for real-device attestation with biometrics.

travkhl and others added 30 commits June 3, 2025 13:39
Signed-off-by: Travis Lee <travislee2k15@gmail.com>
Signed-off-by: Travis Lee <travislee2k15@gmail.com>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: Bryce McMath <bryce.j.mcmath@gmail.com>
Signed-off-by: Bryce McMath <bryce.j.mcmath@gmail.com>
Signed-off-by: Travis Lee <travislee2k15@gmail.com>
Co-authored-by: Al Rosenthal <alfred.k.rosenthal@gmail.com>
Signed-off-by: Bryce McMath <bryce.j.mcmath@gmail.com>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: Mohamed Abd El-Samie Ahmad Mansour <masmas04@gmail.com>
Signed-off-by: al-rosenthal <alfred.k.rosenthal@gmail.com>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…1560)

Signed-off-by: Travis Lee <travislee2k15@gmail.com>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: Travis Lee <travislee2k15@gmail.com>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: ehanoc <ehanoc@protonmail.com>
Signed-off-by: Christian Lippa <christian.lippa@ontario.ca>
Co-authored-by: Mostafa Gamal <46829557+MosCD3@users.noreply.github.com>
Signed-off-by: Matthew Golshani <matthew.golshani@gov.bc.ca>
Co-authored-by: Matthew Golshani <matthew.golshani@gov.bc.ca>
Co-authored-by: Al Rosenthal <alfred.k.rosenthal@gmail.com>
Signed-off-by: Bryce McMath <bryce.j.mcmath@gmail.com>
Signed-off-by: Bryce McMath <32586431+bryce-mcmath@users.noreply.github.com>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: ehanoc <ehanoc@protonmail.com>
Signed-off-by: Travis Lee <travislee2k15@gmail.com>
Signed-off-by: traviskhl <travislee2k15@gmail.com>
Co-authored-by: Al Rosenthal <alfred.k.rosenthal@gmail.com>
Signed-off-by: Bryce McMath <bryce.j.mcmath@gmail.com>
…2337 (#1581)

Signed-off-by: Mac Deluca <Mac.Deluca@quartech.com>
… (#1583)

Signed-off-by: Matthew Golshani <matthew.golshani@gov.bc.ca>
Co-authored-by: Matthew Golshani <matthew.golshani@gov.bc.ca>
Signed-off-by: traviskhl <travislee2k15@gmail.com>
Co-authored-by: Al Rosenthal <alfred.k.rosenthal@gmail.com>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: Mac Deluca <Mac.Deluca@quartech.com>
Signed-off-by: traviskhl <travislee2k15@gmail.com>
Signed-off-by: Bryce McMath <bryce.j.mcmath@gmail.com>
MosCD3 and others added 13 commits June 9, 2026 16:20
… (#1864)

Signed-off-by: Mostafa Gamal <moscd3@gmail.com>
…853)

Signed-off-by: Mostafa Gamal <moscd3@gmail.com>
…(#1860)

Signed-off-by: Christian <christian.lippa@ontario.ca>
…p (#1867)

Signed-off-by: Jason C. Leach <jason.leach@fullboar.ca>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: Mostafa Gamal <moscd3@gmail.com>
Signed-off-by: Christian <christian.lippa@ontario.ca>
Signed-off-by: "github-actions[bot]" <"41898282+github-actions[bot]@users.noreply.github.com">
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…ream v3.0.16

Cherry-picked the full Keyring delta (v2.7.4..keyring HEAD) onto the
upstream bifold-wallet v3.0.16 tree. Conflicts resolved by unioning
Keyring features (VRC module, witness/rCard state, chat redesign,
hardware-signing attestation) with upstream 3.x structure (credo 0.6
API, React 19 refs, ScreenWrapper layouts).

Signed-off-by: Alberto L <aleon@law.harvard.edu>
- Rewire agent construction: connections/credentials/proofs/mediation
  config now lives under DidCommModule; transports register via
  agent.modules.didcomm
- Adopt renamed DIDComm types and events (DidCommConnectionRecord,
  DidCommCredentialExchangeRecord, DidCommProofState, etc.)
- Replace wallet.createKey with kms.importKey / dids.create createKey
  option (JWK types); deterministic witness DID derives Ed25519 public
  key via node:crypto
- Switch askar to @openwallet-foundation/askar-* store config
- W3cCredentialRecord: use .encoded instead of private .credential
- witness-server + vrc-reference: full source and test migration,
  jest ESM transforms for credo 0.6 (.mjs) dependencies
- Fix lint debt surfaced by upstream flat eslint config; update
  React 19 snapshots

All workspaces: build, lint, prettier, and tests green
(155 suites / 1398 tests).

Signed-off-by: Alberto L <aleon@law.harvard.edu>
Ties the fork history to the upstream openwallet-foundation/bifold-wallet
v3.0.16 base so the Phase 3 branch can be reviewed and merged as a PR.
The tree is taken entirely from the Phase 3 branch (upstream 3.0.16 +
Keyring delta + credo-ts 0.6.3 migration).

Signed-off-by: Alberto L <aleon@law.harvard.edu>
The absolute 'components/views/Banner' specifier only resolves with core's
own baseUrl and breaks consumers that compile @bifold/core from source
(e.g. the Keyring app workspace).

Signed-off-by: Alberto L <aleon@law.harvard.edu>
With the New Architecture, codegen derives an abstract base class from the
TS spec on both platforms, so generateKey/sha256/appleKeyAttestation/
getAppStoreReceipt/attestHardwareSigningKey must exist on Android too.
They reject with UNSUPPORTED. Old-arch spec mirrors them so both source
sets stay interchangeable. Also refresh the android gradle lockfile for
RN 0.81 / compileSdk 36 hosts.

Signed-off-by: Alberto L <aleon@law.harvard.edu>
albertoleon7794 and others added 4 commits July 6, 2026 14:24
The merge onto upstream v3.0.16 reverted the customized Onboarding screen
to the plain upstream pager. Restore the card-style carousel with arrow
overlays, the onComplete prop, and the Get Started button, and wire them
back up in OnboardingStack. Also replace the stale react-native-argon2
jest mock with an Argon2 mock on askar-react-native (crypto.ts migrated).

Signed-off-by: Alberto L <aleon@law.harvard.edu>
Co-authored-by: Cursor <cursoragent@cursor.com>
- vrc-manager + InAppMessageNotifier: subscribe with
  DidCommBasicMessageEventTypes.DidCommBasicMessageStateChanged (credo 0.6
  renamed the event; the old 0.5 string silently never fired, stalling VRC
  issuance after connection)
- chat: swap RN TouchableOpacity for react-native-gesture-handler touchables
  in ChatMessage (YES/NO offer actions) and chat-messages details links —
  RN touchables miss taps inside GiftedChat's inverted list on Android with
  the New Architecture
- react-hooks: key useCredentialByState/useProofByState (and NotInState
  variants) memo on state contents instead of array identity — callers pass
  fresh array literals each render, producing new filtered arrays every
  render and an infinite re-render loop under React 19 ("Maximum update
  depth exceeded") that starved the credential exchange
- vrc-manager: backdate issuanceDate/validFrom by 5 min to tolerate clock
  skew between devices (holder rejects VCs issued "in the future")
- Splash: log full agent-init error chain (cause + stack)

Signed-off-by: Alberto L <aleon@law.harvard.edu>
…ormat

R-Card template records stored by credo-0.5 builds have no `proof`, but
credo 0.6 parses stored credentials as W3cJsonLdVerifiableCredential whose
class validation requires one — `record.getTags()` threw and crashed the
OpenID credential provider on first launch after an app upgrade over an
old askar store.

Add migrateRCardTemplateProofs(): a one-time fixup that adds the same
placeholder proof new templates get to any legacy RCardTemplate record
missing one. Verified end-to-end by the askar 0.2->0.6 store-migration
E2E (old release apk populated with a real VRC, `adb install -r` upgrade,
wallet + contact + credential survive).

Signed-off-by: Alberto L <aleon@law.harvard.edu>
…tests)

react-native-gesture-handler's bundled jest mocks render buttons without
children (RawButton discards them), so labels inside gesture-handler
touchables disappear under test and the ChatMessage credential-offer
YES/NO suite could not find its buttons. Map the touchables to their
react-native equivalents in jestSetup so children render normally.

Signed-off-by: Alberto L <aleon@law.harvard.edu>
Align the VRC module with the ToIP DTG credential spec and move issuance
to the W3C VC Data Model 2.0, with negotiated backward compatibility.

RCard/VRC separation (spec hygiene):
- VRC issuer is a bare DID string for v2 peers; contact info moves into a
  separate exchanged RelationshipCard credential (subject = counterparty,
  credentialSubject.card = jCard) issued right after the VRC, auto-accepted
  by the receiver and hidden from chat/notifications/wallet list
- new RCard JSON-LD context with @type: @JSON so the jCard survives RDF
  canonicalization as a JCS JSON literal
- contact display resolves from the newest received RCard, falling back to
  legacy VRC issuer objects (rcardDisplayUtils)

VWC digest:
- witness digest now uses JCS (RFC 8785) canonicalization instead of a
  top-level-only key sort (jcsCanonicalize in @bifold/vrc-contexts)

VC 2.0 verification (credo yarn patch):
- patch @credo-ts/core 0.6.3: accept https://www.w3.org/ns/credentials/v2
  as first @context and make issuanceDate optional (2.0 uses validFrom)
- bundle the VCDM 2.0 context document and pin credo's standard security
  contexts into the shared document loader for offline sign/verify
- upstream issue filed: openwallet-foundation/credo-ts#2864

VC 2.0 issuance flip with RCE v2 negotiation:
- handshake announces vrc:rceVersion:2; peer version stored on
  RelationshipDidRecord (absent = v1)
- v2 peers get VCDM 2.0 VRC/RCard/VWC (v2 context, validFrom/validUntil);
  the Ed25519Signature2018 suite context is included at build time because
  the v2 base context doesn't define the proof terms and jsonld-signatures
  would otherwise mutate @context during signing, failing credo's
  holder-side offer/credential equality check
- v1 peers keep the full legacy exchange: VCDM 1.1 VRC with the embedded
  issuer object (name/email/org) and no RCard offer
- witness-server mirrors the observed VRC's data model for the VWC and
  widens the freshness window to cover the wallets' clock-skew backdating

Gates: core jest 159 suites / 1434 tests green; conformance sign/verify
round-trips for v1.1 and v2; two-device E2E (new/new) and backward-compat
E2E against a Phase-4 baseline build both green.

Signed-off-by: Alberto L <aleon@law.harvard.edu>
@albertoleon7794 albertoleon7794 changed the title Upgrade Phase 3: bifold 3.0.16 + credo-ts 0.6.3 + React 19 Upgrade Phases 3+5: bifold 3.0.16 + credo-ts 0.6.3 + React 19 + DTG/VC 2.0 Jul 8, 2026
Embed all three Google attestation roots, validate chains against them
only (no self-as-anchor), and add Android/TS regression tests.

Signed-off-by: Alberto L <aleon@law.harvard.edu>
Avoid RN Modal presentation failures on iPhone (camera disclosure as view,
dismiss QR sheet before Scan nav). Make Settings Secure Exchanges row
actionable under VoiceOver/Appium. Log slim IssuedCredentialJSON for E2E.
Keep Ed25519Signature2018 intentionally (DI deferred — see keyring docs).

Signed-off-by: Alberto L <aleon@law.harvard.edu>
@albertoleon7794

Copy link
Copy Markdown
Collaborator Author

Superseded by the consolidated upgrade PR #31, which folds the bifold 3.x / credo-ts 0.6 upgrade and the eddsa-rdfc-2022 Data Integrity work into a single review branch. Closing without merge — see the consolidated PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.