Skip to content

Upgrade Phases 3+4+5: bifold 3.0.16, credo-ts 0.6.3, React 19, RN 0.81, bc-wallet-mobile ports, VC 2.0#14

Closed
albertoleon7794 wants to merge 12 commits into
upgrade/phase2-rn77from
upgrade/phase3-bifold3
Closed

Upgrade Phases 3+4+5: bifold 3.0.16, credo-ts 0.6.3, React 19, RN 0.81, bc-wallet-mobile ports, VC 2.0#14
albertoleon7794 wants to merge 12 commits into
upgrade/phase2-rn77from
upgrade/phase3-bifold3

Conversation

@albertoleon7794

@albertoleon7794 albertoleon7794 commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacked on #13 (Phase 2). Closes the app-layer portion of #10.

Phase 3 — platform upgrade

  • Deps: React Native 0.81.5 / React 19.1.0, @bifold/* 3.0.16 portals (incl. new @bifold/react-hooks), @credo-ts/* 0.6.3 with @credo-ts/didcomm, askar → @openwallet-foundation/askar-react-native 0.6.0, expo modules; Storybook removed
  • Credo 0.6 migration: bc-agent-modules rewritten (DidCommModule config, KMS with askar + expo secure-environment), wallet id/key move into the Askar store config, DIDComm type/event renames across hooks/utils, DRPC-based BC attestation flow removed (Keyring doesn't use BC's attestation service)
  • Android: compileSdk 36, Kotlin 2.1.20, Gradle 8.14.3, New Architecture enabled, expo autolinking, lockfiles regenerated
  • iOS: Podfile expo autolinking, pods on RN 0.81.5
  • Metro/Jest/Babel: metro 0.83 package-exports config, singleton react resolution for bifold sources, RN 0.81 jest mocks; react-native-document-picker patched for RN 0.81; unused react-native-date-picker removed
  • Store migration: Askar 0.2→0.6 store opens in place; legacy R-Card template records backfilled with a placeholder proof (credo 0.6 validation)

Phase 4 lite — bc-wallet-mobile ports (dc944fd)

  • Errors framework (app/src/errors/): AppError + trimmed ErrorRegistry, handler utilities, ErrorInfoCard/AppErrorModal/ErrorBoundary, ErrorAlertProvider wired into App.tsx. Snowplow analytics dropped — "Report this problem" sends to Loki with a user-facing reference code
  • PressableOpacity and small hooks (usePreventGestureBack, useDeclineCredentialOffer, useDeclineProofRequest, useAutoRequestPermission)
  • Mediator pickup simplified: unconditional PickUpV2LiveMode (WebSocket push); batch pickup, 5s trust-ping polling, and the MEDIATOR_USE_V2_BATCH_PICKUP env flag removed (supersedes feat: enable Pickup V2 batch pickup via env flag #7)
  • Companion bifold PR: Upgrade Phases 3+5: bifold 3.0.16 + credo-ts 0.6.3 + React 19 + DTG/VC 2.0 keyring-bifold#26

Verification

  • yarn typecheck and yarn lint clean; app jest 16 suites / 70 tests pass
  • assembleDebug (New Arch) and xcodebuild Debug both green; release JS bundles build for both platforms
  • Two-device E2E VRC exchange green (Android emulator ↔ iOS simulator), incl. bidirectional VRC issuance on live-mode-only pickup
  • Askar 0.2→0.6 store-migration E2E green with real credentials (baseline 0.5.17 APK → in-place upgrade)

Phase 5 — DTG spec alignment + VC 2.0 (b346f0a + bifold Phase 5 commit)

  • RCard separated from the VRC: issuer becomes a bare DID string for v2 peers; contact info travels in an exchanged, auto-accepted RelationshipCard credential (hidden from chat/notifications/wallet list); contact display resolves from the newest received RCard with legacy-issuer fallback
  • VWC digest now uses JCS (RFC 8785) canonicalization on the witness side
  • VC 2.0 verification: @credo-ts/core yarn patch in BOTH trees (accept https://www.w3.org/ns/credentials/v2 as first @context, optional issuanceDate) + bundled v2 context document
  • VC 2.0 issuance with RCE v2 negotiation: handshake announces vrc:rceVersion:2; v2 peers get VCDM 2.0 credentials (validFrom/validUntil, Ed25519 suite context included at build time), v1 peers keep the full legacy exchange (1.1 VRC with embedded issuer object, no RCard)

Phase 5 verification

  • bifold core jest 159 suites / 1434 tests; VC 2.0 sign/verify conformance round-trips (v1.1 + v2)
  • Two-device E2E (new↔new): RCE v2 negotiated, VC 2.0 VRCs verified, RCards auto-accepted, contacts visible both sides
  • Backward-compat E2E: Phase-4 baseline release APK ↔ new build exchanges cleanly (legacy 1.1 path), then upgrades in place with store, contact and VRC intact

Attestation hardening (a9ca437)

  • Bumps the bifold submodule to 88f80fe8: Google attestation trust anchors from keyring-bifold#23 cherry-picked onto the upgrade branch (embedded published Google roots, no self-as-anchor). Verified on the upgraded stack: 7/7 attestation JUnit tests, 29/29 BiometricSignatureVerifier TS tests, app assembleDebug green

Do not merge without approval — merge order is coordinated by the repo owner (bifold #26 first, as a merge commit so the pinned submodule commit stays reachable).

… 0.6.3

Wire the app workspace to the upgraded bifold 3.x submodule:

- deps: react-native 0.81.5 / react 19.1.0, @bifold/* 3.0.16 portals (incl.
  new @bifold/react-hooks), @credo-ts/* 0.6.3 with @credo-ts/didcomm,
  askar -> @openwallet-foundation/askar-react-native 0.6.0, expo modules,
  reanimated + keyboard-controller; adopt upstream patch set, drop 0.5.17
  patches; remove Storybook entirely
- bc-agent-modules: credo 0.6 module graph (DidCommModule config, KMS with
  askar + expo secure-environment, explicit JSON-LD/AnonCreds DIDComm format
  services, VRC document loader)
- useBCAgentSetup: wallet id/key move into AskarModule store config (no
  agent.wallet.open()), didcomm transport registration, guarded indy-vdr
  pool warm-up
- attestation: remove DRPC-based BC attestation flow (@credo-ts/drpc has no
  stable 0.6.x and Keyring does not use BC's attestation service); delete
  utils/drpc.ts; keep bifold AttestationMonitor interface
- credo 0.6 API renames across hooks/utils (DidComm* types, proofExchangeRecordId,
  metadata keys from @credo-ts/anoncreds root)
- jest/babel: sync transformIgnorePatterns with bifold core, map @bifold/* to
  sources, RN 0.81 Keyboard/BackHandler/reanimated mocks, drop module-resolver
  root '.' (rewrote node_modules '.' imports to app index.js), add
  export-namespace-from + reanimated babel plugins
- snapshots updated for RN 0.81 style flattening; theme gains new bifold 3.x
  IBrandColors fields

App gate (JS): typecheck 0 errors, eslint clean, jest 14 suites / 27 tests pass.
Native Android/iOS project upgrade is the next step.
Android: compileSdk/targetSdk 36, kotlin 2.1.20, gradle 8.14.3, AGP from RN
gradle plugin, newArchEnabled=true, expo modules autolinking (settings.gradle
useExpoModules + ReactNativeHostWrapper/loadReactNative in MainApplication),
react.internal.disableJavaVersionAlignment + subprojects Java 17 alignment
(mirrors bifold samples/app), gradle lockfiles regenerated. assembleDebug green.

iOS: Podfile gains expo autolinking (use_expo_modules! +
expo_patch_react_imports!), pods reinstalled on RN 0.81.5. xcodebuild Debug
(simulator) green. AppDelegate stays on RCTAppDelegate for now.

Bundling (metro 0.83): exclusionList import moved to metro-config/private,
package exports enabled with react-native/browser/require conditions,
bifold/node_modules added to watchFolders/nodeModulesPaths,
react-native-svg-transformer 0.14 -> 1.5.1. Release bundles green for both
platforms.

Deps: add zustand (bifold core lists it only as devDep) and
@expo/app-integrity (used by bifold attestation hooks). Patch
react-native-document-picker 9.3.1 to drop GuardedResultAsyncTask
(removed in RN 0.81).

Gates re-run after changes: typecheck 0 errors, eslint clean, jest 14/27 pass.
- metro: re-resolve react/react-native/react-dom/@credo-ts singletons from the
  app root when imported from outside app/ (bifold sources were pulling a second
  react copy from bifold/node_modules in dev bundles, crashing the hooks
  dispatcher); add @bifold/react-hooks to the dev source-resolution list
- remove react-native-date-picker: unused, and 5.0.13 fails RN 0.81's
  RCTModuleProvider conformance check on iOS

Verified: Android emulator reaches onboarding, iOS simulator reaches PIN
unlock (existing askar store opens). Both native builds and release bundles
re-verified after the changes; typecheck clean.
- attestation service: credo 0.6 renamed credential event payload
  credentialRecord -> credentialExchangeRecord (handler threw "Cannot read
  property 'id' of undefined" on every credential event)
- index.js: LogBox.ignoreAllLogs() in dev — notification banners overlay
  bottom buttons (Done) and eat taps during E2E; everything still logs to
  metro/logcat/syslog
- e2e: iOS caps get enforceAppInstall (stale simulator builds caused RN
  version-mismatch redbox), document ad-hoc signing requirement for keychain
  entitlements; acceptCredentialOfferFromChat retries the YES tap until the
  offer screen opens
- resolutions: pin @hyperledger/indy-vdr-shared 0.2.4 (duplicate instance
  broke pool init)
- bifold submodule: E2E fixes (event names, gesture-handler chat touchables,
  react-hooks memo loop fix, issuanceDate clock-skew backdate)
- UPGRADE_PROGRESS.md: Phase 3 E2E gate green, fixes documented
… present

The RN Modal hosting the camera-use disclosure occasionally fails to present
when it mounts mid push-animation on iOS, leaving a blank Scan screen with no
Continue or PasteUrlButton. Back out and re-enter the screen to re-present it.

Also gitignore app/android/app/.cxx/ (CMake build cache).
run-store-migration.js installs the baseline apk (credo 0.5.17/askar
0.2.3, release build so its own JS is bundled), populates the old-format
store with a real VRC exchange against the new iOS build, upgrades in
place with `adb install -r`, and verifies the wallet unlocks and the
contact + VRC survive.

- deliver the invitation to the old android build via deep link (its QR
  bottom-sheet ignores appium synthetic taps; deep link is the real-user
  path anyway)
- grant runtime permissions via `adb shell pm grant` (manual installs
  skip appium's autoGrantPermissions)
- iOS: `simctl privacy grant camera` kills the app; terminate + wait +
  activate avoids a black-screen race on relaunch
- app: run migrateRCardTemplateProofs() after agent.initialize() so
  legacy R-Card template records get a proof before any provider reads
  W3C credential records (bifold 3dd6a786)

Signed-off-by: Alberto L <aleon@law.harvard.edu>
Signed-off-by: Alberto L <aleon@law.harvard.edu>
The baseline is one worktree of the root repo (submodule init for bifold),
not two separate worktrees. Worktrees under /tmp were removed; the
upgrade-baseline-p0 tags are the source of truth.

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

Port the generic app-layer improvements from upstream bc-wallet-mobile
(BCSC-specific work intentionally skipped):

- errors framework (src/errors/): AppError + trimmed ErrorRegistry +
  handler utils, ErrorInfoCard/AppErrorModal/ErrorBoundary components,
  ErrorAlertProvider/useErrorAlert context. Snowplow analytics coupling
  dropped; "Report this problem" ships the report to Loki via
  reportProblem() and surfaces a copyable reference code. App.tsx now
  uses our ErrorBoundaryWrapper and mounts ErrorAlertProvider.
- PressableOpacity component (New-Architecture-reliable Pressable
  wrapper mimicking TouchableOpacity).
- hooks: usePreventGestureBack, useDeclineCredentialOffer,
  useDeclineProofRequest, useAutoRequestPermission.
- mediator pickup simplified to unconditional PickUpV2LiveMode
  (WebSocket push); legacy batch-pickup + 5s trust-ping polling loop
  removed and MEDIATOR_USE_V2_BATCH_PICKUP flag retired. Verified
  against the hosted mediator via the two-device VRC E2E.
- i18n: en/fr/pt-br strings for the error modal reference-code UI.

Gate: app jest 16 suites/70 tests, bifold core 155 suites/1398 tests,
typecheck, and Android<->iOS VRC exchange E2E all 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, RN 0.81 (New Architecture) Upgrade Phases 3+4: bifold 3.0.16, credo-ts 0.6.3, React 19, RN 0.81 + bc-wallet-mobile ports Jul 8, 2026
albertoleon7794 added a commit that referenced this pull request Jul 8, 2026
…edo patch, merge plan)

Bump the bifold submodule to the Phase 5 commit (RCard/VRC separation, JCS
witness digest, VCDM 2.0 verification + negotiated issuance with RCE v2).
Apply the @credo-ts/core 0.6.3 yarn patch in the app tree as well (accept
the VC 2.0 context as first @context entry, make issuanceDate optional) so
the wallet's own dependency graph resolves the same patched credo.

Gates green 2026-07-08: app + bifold jest/typecheck/lint, two-device E2E
VRC exchange on the VC 2.0 flow, and a backward-compat E2E where a Phase-4
baseline build exchanges with the new app (legacy 1.1 VRC with issuer
object, no RCard) and then upgrades in place with its store intact.

Adds MERGE_PLAN.md documenting the PR merge order (bifold #26 first as a
merge commit, then wallet #13 and #14) and the submodule-pointer rules.
Upstream credo issue: openwallet-foundation/credo-ts#2864.
@albertoleon7794 albertoleon7794 changed the title Upgrade Phases 3+4: bifold 3.0.16, credo-ts 0.6.3, React 19, RN 0.81 + bc-wallet-mobile ports Upgrade Phases 3+4+5: bifold 3.0.16, credo-ts 0.6.3, React 19, RN 0.81, bc-wallet-mobile ports, VC 2.0 Jul 8, 2026
…edo patch)

Bump the bifold submodule to the Phase 5 commit (RCard/VRC separation, JCS
witness digest, VCDM 2.0 verification + negotiated issuance with RCE v2).
Apply the @credo-ts/core 0.6.3 yarn patch in the app tree as well (accept
the VC 2.0 context as first @context entry, make issuanceDate optional) so
the wallet's own dependency graph resolves the same patched credo.

Gates green 2026-07-08: app + bifold jest/typecheck/lint, two-device E2E
VRC exchange on the VC 2.0 flow, and a backward-compat E2E where a Phase-4
baseline build exchanges with the new app (legacy 1.1 VRC with issuer
object, no RCard) and then upgrades in place with its store intact.
…y-pick)

Pull in bifold 88f80fe8: embed Google's three published attestation roots
(legacy RSA, re-signed RSA, RKP ECDSA) and validate Android hardware
attestation chains against them only, instead of accepting the chain's own
root as its anchor. Needed for real-device attestation with biometrics.

Verified on the upgraded stack: 7/7 attestation JUnit tests, 29/29
BiometricSignatureVerifier TS tests, app assembleDebug green.
@albertoleon7794
albertoleon7794 force-pushed the upgrade/phase3-bifold3 branch from 331d1db to a9ca437 Compare July 9, 2026 17:49
Rewrite HARDWARE_ATTESTATION_FLOW for native verifyHardwareEvidence and
preference-gated Secure Exchange. Add CRYPTO_SUITE_FOLLOWUP so
Ed25519Signature2018 stays documented as intentional until a clean stack
can take DataIntegrityProof (eddsa-rdfc-2022) as a separate project.
Ship dual real-device VRC harness, RN Hermes SIGBUS yarn patch, and
bifold bump for modal/a11y/credential-dump fixes.

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

Copy link
Copy Markdown
Collaborator Author

Docs / debt note (2026-07-13)

Pushed c880d31 on this branch:

  • Rewrote docs/HARDWARE_ATTESTATION_FLOW.md (native verify + preference gate; real-device E2E covered).
  • Added docs/CRYPTO_SUITE_FOLLOWUP.mdEd25519Signature2018 stays; Data Integrity (eddsa-rdfc-2022) deliberately deferred until after a clean upgrade state. Address separately.
  • Real-device harness: yarn e2e:vrc:devices + RN Hermes SIGBUS yarn patch.

Phase 5 on this PR = VCDM 2.0 payload; not DI suite migration.

@albertoleon7794

Copy link
Copy Markdown
Collaborator Author

Superseded by the consolidated upgrade PR #17, which folds phases 1–5 plus RCE v3 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.

1 participant