GithubHelp home page GithubHelp logo

digitalcredentials / learner-credential-wallet Goto Github PK

View Code? Open in Web Editor NEW
50.0 15.0 24.0 5.16 MB

Learner Credential Wallet is a cross-platform iOS and Android mobile application for storing and sharing digital learner credentials.

Home Page: https://lcw.app

License: MIT License

TypeScript 99.49% JavaScript 0.51%

learner-credential-wallet's Introduction

icon

Learner Credential Wallet

Learner Credential Wallet is a cross-platform iOS and Android mobile application for storing and sharing digital learner credentials.

Install Learner Credential Wallet for your mobile!

The wallet is based on the learner credential wallet specification developed by the Digital Credentials Consortium. The learner credential wallet specification is based on the draft W3C Universal Wallet interoperability specification and the draft W3C Verifiable Credentials data model.

The app has been compiled for iOS and Android and allows users to add and share credentials, as well as manage the wallet.

The Learner Credential Wallet startup screen, displaying the choice between quick and custom setup. The “credential preview” screen, displaying information about an issued credential, including credential name, issuer, issuer date, credential description, criteria, and verification status. The “share credential” screen, which allows the user to share their credentials with others through a public link or QR code, and includes the additional options to send the credential link or directly add it to LinkedIn through the app. The “verification status” screen, which shows whether the credential has been verified, and includes an additional breakdown of information including the last date verification status was checked, the validity of the credentials digital signature, expiration, and revocation status.

Goals

This learner credential wallet includes the features and technical requirements ultimately enabling individuals to curate and present their learning and employment records to others—for example, as applicants to educational programs or to apply for jobs with employers—in an interoperable manner.

  • Receive digital credentials from standards compliant issuers via link or QR code
  • Store credentials on their mobile device
  • Keep credential access safe with strong encryption best practices
  • Create and share a presentation that collates any number of credentials in their wallet
  • Backup and restore their wallet

Pilot

The Digital Credentials Consortium is working with a number of colleges and universities to pilot test the wallet.

Development Setup

Dependencies

If you encounter any issues, visit the Troubleshooting Page

Prerequisites:

See Installing on Linux on setting up the project on Linux.

Setup of the LCW App

  1. Clone this repository or git pull
  2. In root of project, run npm i --legacy-peer-deps to install the React Native dependencies.
    • Note: The app will crash if you try to use just npm i or yarn for example
    • (Optionally, if you use the asdf version manager run asdf install to install - more info in asdf section below)
  3. Run npm run prebuild:ios and npm run prebuild:android to set up the ios and android folders. This step uses Expo prebuild.

If using asdf

  • Run asdf install to install the proper versions of the technologies used listed in the .tool-versions file
    • If you need to install anything, run asdf plugin add [plugin-name] to add it to your local machine
    • Here is a link if you need it to the asdf installation documentation (homebrew is the easiest)

Running the LCW App

  1. Run yarn start in one terminal
  2. In another terminal run yarn android
  • When running on android, open Android Studio and make sure the device you want to run on is selected (whether that is an emulator or a real device).
  • Note: You might need to hit the play button in Android Studio for it to fully register which device to set to be used from the command line.
  1. In another terminal yarn yarn ios

Environment

This project uses TypeScript and React Native with Expo. It would be best to use an editor that can hook into the TypeScript language server (VSCode does this with Intellisense, Vim does it with CoC). We also use eslint to catch common mistakes and formatting errors. Most editors should support dynamic linting support while editing. If your editor does not, you can manually lint by running npm run lint in the project root.

This project also uses environment variables, which are stored in config.ts. These values can be overridden, but development values should not be committed to the repository.

Project Structure

├── app
│   ├── assets ← Image assets 
│   ├── components ← React components
│   ├── hooks ← This is where custom hooks are defined (usually wraps lib methods)
│   ├── lib ← Location for utility methods
│   ├── mock ← Location for mock data, usually used for testing
│   ├── model ← Database access objects and connections
│   ├── navigation ← React Navigation structure
│   ├── screens ← Individual screen views
│   ├── store ← Redux and Redux Toolkit definitions
│   │   └── slices ← Redux Toolkit slices (add new Redux state here)
│   ├── styles ← All app style definitions
│   └── types ← General place for defining types (usually DCC types for Credential, Presentation, etc...)
├── android ← Auto-generated android build folder, can still be manually edited if needed
└── ios ← Same as android, except it also uses Cocoapods for dependency management

Configuration

Overridable configuration lives in two places:

  1. app.json - created by Expo, contains app name, icon, splash page color, etc.
  2. app/config/index.ts - contains everything else, including a list of Known DID Registries, deep link schemes, app website URLs, and so on.

Issuing new credential

Instructions for issuing a credential.

Adding new credential display

A custom display can be created for different credentials, to do so:

  • Create a new React component for your credential type in app/components/CredentialCard/ - eg. app/components/CredentialCard/YourNewTypeCard.tsx
  • Define addition styles in app/components/CredentialCard/YourNewTypeCard.styles.tsx
  • Add a function to the credentialTypes list defined in app/components/CredentialCard/CredentialCard.tsx. The function should return {component: YourNewCredentialCard, title: 'the title of the credential that should be used when listing it elsewhere'} or null if the credential isn't the appropriate type for you custom display
  • note: the list will be scanned for the first function that returns a component and title, so it's important that the type check is specific and doesn't match any other types.

Accessibility

We have conducted a Voluntary Product Accessibility Test, please review the Learner Credential Wallet Accessibility Conformance Report, December 2021

For more information on accessibility please visit the MIT Accessibilty page.

Privacy Policy

This Privacy Policy explains how Learner Credential Wallet collects, uses, and processes personal information about our learners.

What Personal Information We Collect

We do not collect any personal information.

Additional Information

We may change this Privacy Policy from time to time. If we make any significant changes in the way we treat your personal information we will make this clear on our website or by contacting you directly.

The controller for your personal information is the Learner Credential Wallet project at MIT. We can be contacted at [email protected].

Terms and Conditions of Use

Learner Credential Wallet Terms and Conditions of Use

Acknowledgements

Initial development was supported by the U.S. Department of Education (Contract Number: 91990020C0105). The opinions expressed herein do not necessarily represent the positions or policies of the U.S. Department of Education, and no official endorsement by the U.S. Department of Education should be inferred.

Initial development was also supported by the Massachusetts Institute of Technology. Continued development is supported by members of the Digital Credentials Consortium.

License

MIT License Copyright (c) 2021 Massachusetts Institute of Technology

All files located in external directories are externally maintained libraries used by this software which have their own licenses; we recommend you read them, as their terms may differ from the terms above.

learner-credential-wallet's People

Contributors

alexfigtree avatar bmuramatsu avatar dirkcuys avatar dittonjs avatar dmitrizagidulin avatar fields37 avatar jchartrand avatar jennacioffi avatar kayaelle avatar kezike avatar kylehovey avatar pascalherrmann avatar sethduffin avatar shruti3004 avatar stuartf avatar vonovak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

learner-credential-wallet's Issues

Issuer auth 'code' overriding auth_type 'bearer'

To reproduce:

Load up a local build from latest main.
Click on deeplink: dccrequest://request?issuer=issuer.example.com&vc_request_url=https://verify.dcconsortium.org/request/credential&challenge=ke12345678-0001&auth_type=bearer

Expected behavior: You should receive the VC from the issuer (since it's using bearer auth).
Actual behavior: Instead, you're shown a 'Log in with Google' prompt, with the wallet acting as if auth_type=code.

I suspect this is due to requestCredential() having auth_type=code by default. And the callback mechanism is somehow not passing in the right auth_type.

Differentiate background color for swipe-left and swipe-right

@dittonjs Could you please ask Brandon Findlay to recommend a color for the background on the share side. Perhaps a different gray?

For the delete, can he recommend a color? I'm thinking the same color red as Apple Mail and Notes. It might be SwiftUI systemRed (see (https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/))

I don't use Android to know what the "typical" delete background color is. I presume Google specifies it somewhere.

Originally posted by @bmuramatsu in #139 (comment)

Android - Wallet setup stalls after wallet reset

To replicate:

Build latest main (tag v1.1.7-build18) for Android. (You can also replicate this behavior with the Google Play test version.)

Go to settings > Reset wallet
get prompted to exit, app closes.
Reopen app.
Click Start Setup
Enter passwords, get to Creating Wallet spinner screen.
Wait for spinner to complete, click on 'Take Me To My Wallet'.

The button seems to do nothing (does not respond, does not take you to home screen).
(I was able to get it to go to home screen eventually, after tapping it a number of times.)

See also #144 (comment)

Support URL based VC import

Similar to the simple VPQR import flow, we would like to load VCs via an endpoint, "handing it over" to the learner.

New Display Template: Image-type Credential

Add support for a primarily image based credential to LCW.

issuer.name: The institution’s name or program’s name issuing the credential
issuer.url: The institution’s website
issuer.image: URL to logo of the institution’s choosing
expirationDate: Date on which the credential expires, if specified
credentialSubject.name: Name of the individual receiving the credential
'image<field name TBD>: Single PNG or JPEG imagetype`: Type label(s) TBD

Can add same credential multiple times from individual credential preview screen's add button

Reproducible for Brandon on iOS TestFlight build 5. When adding from the QR code containing two credentials, when I preview a credential I can add the credential from the preview screen. I can do so multiple times -- aka I can mash the Accept button and get as many credentials as I hit the button. When I return to the two credential preview screen I seed the "Added to Wallet". When I view the Home screen I see multiple copies of the same credential.
I think there are two bugs. The infinite add and adding multiple copies of the same credential.

v1.1.1 (11) no longer handling GT credentials

This issue was not present in v.1.1.0 (10). After clicking a deep link, launching eduwallet, and completing the GT login workflow... we now arrive at the following error screen:
IMG_344795ADC438-1

BUG: Sharing Credentials as VP does not work for certain @context's

Using:

  • Android 11
  • LCW v1.4.1

Issue:
When trying to share a credentials via the "Share" page that contains one of those context uris ("http://home.in.tum.de/~sehlke/elmoLearner.json", "https://w3id.org/vc-revocation-list-2020/v1") the app simple does nothing.

Expectation:
When pressing the "Send" button in the "Share Preview" Page the app should create a presentation with the selected credentials and open Android's share menu as it does for other credentials (that do not contain any of the listed context uris).
Currently only very specific credentials can be shared and be presented to a verifying party and for all others it simple does not work (yet).

Steps to reproduce:

  • load the credential into the wallet via a QR-Code (dccrequest://request?&auth_type=bearer&issuer=example.org&vc_request_url=http://localhost:3000/credential&challenge=123)
  • open the "Share" page in the app
  • select the just added credential
  • press "Share Selected Credential"
  • press "Send"

For following credential

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
    ],
    "id": "http://localhost:8082/credentials/29",
    "type": ["VerifiableCredential"],
    "issuer": "did:key:z6MkqVmUBC49F98kvo5bC2Me6PpT3C1YjMGNRXi1Ci312zms",
    "issuanceDate": "2022-06-15T15:05:01Z",
    "credentialSubject": {
        "id": "did:ethr:0x1844d35477a3eea17dece6d1ac6a9f91d20a5140"
    }
}
  • Android's share menu appears with a presentation containing the selected credential ✔️

And for the following credential

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://w3id.org/vc-revocation-list-2020/v1",
        "https://w3id.org/security/suites/ed25519-2020/v1"
    ],
    "id": "http://localhost:8082/credentials/29",
    "type": ["VerifiableCredential"],
    "issuer": "did:key:z6MkqVmUBC49F98kvo5bC2Me6PpT3C1YjMGNRXi1Ci312zms",
    "issuanceDate": "2022-06-15T15:05:01Z",
    "credentialSubject": {
        "id": "did:ethr:0x1844d35477a3eea17dece6d1ac6a9f91d20a5140"
    }
}
  • simply nothing happens ❌

Deleted credential cannot be readded to wallet

From reset wallet. Finish setup.

Add credential from digitalcredentials/docs#10 multiple credentials with invalid signature:
135905712-2e9baf4d-3489-40eb-966f-6e3da5cc2a3c

Delete second credential. Only 1 credential remains in the wallet.

Try to readd credentials using the same two from QR code.

Both credentials appear as "Aready in Wallet"

But, only 1 credential in the wallet...

iOS build errors with ExpoSplashScreen

Running into an issue building wallet on iOS, on main.
To reproduce:

  1. rm -rf node_modules
  2. npm install --legacy-peer-deps # (needed for npm 7)
  3. cd ios
  4. pod install

gives the following warning:

Found some duplicated unimodule packages. Installed the ones with the highest version number.
Make sure following dependencies of your project are resolving to one specific version:
 expo-splash-screen

But then, when building in XCode (on iPhone 8+ hardware), gives the following build error:

In file included from ~/code/DCC/learner-credential-wallet/ios/eduwallet/AppDelegate.m:11:
~/code/DCC/learner-credential-wallet/ios/Pods/Headers/Public/EXSplashScreen/EXSplashScreenService.h:5:9: fatal error: 'ExpoModulesCore/EXSingletonModule.h' file not found
#import <ExpoModulesCore/EXSingletonModule.h>

(I'm on cocoapods 1.11.0)

Add Achievement.image to Credential Display

An Open Badge may have an achievement.image: https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#achievement

The image is an object minimally containing an id and type like:

"image": {
"id": "https://w3c-ccg.github.io/vc-ed/plugfest-2-2022/images/JFF-VC-EDU-PLUGFEST2-badge-image.png",
"type": "Image"
}
the id can be a URL or an embedded image like in this example: https://w3c-ccg.github.io/vc-ed/plugfest-2-2022/unsigned-badge-example-p2-embedded-image.json

An achievement image is not required by the Open Badges spec, so the display conditional can be: if (achievement.image) > display achievement.image, else display nothing. A suggestion for placement is next to the achievement.name at the top of the screen.

Fix LoadingIndicator.tsx lint issue

Currently getting a CI linting error:

/home/runner/work/learner-credential-wallet/learner-credential-wallet/app/components/LoadingIndicator/LoadingIndicator.tsx
Error:   14:16  error  Component definition is missing display name  react/display-name

Enable/fix scanning of QR codes containing URLs to credentials

LCW should support scanning of a QR code (on the Add Credential screen) that contains a URL to a cloud-hosted Verifiable Presentation. (I vaguely remember us implementing this earlier, but it doesn't seem to be working):

So, for example, when in LCW I scan the following QR code:
qr

it decodes to the following Gist:
https://gist.githubusercontent.com/dmitrizagidulin/c51ba271196d2b55119063db90e86437/raw/e52d34119c961e5d680f8a86ef82541843820182/sample-vc.json

The wallet should fetch the contents of the URL, and if it contains JSON, attempt to parse it, and add it via the same channel as if it was scanned via embedded VPQR-encode QR code.

Support for Expiration Date in Credential Verification Logic

We'll be adding expiration dates to the VCs for the pilots, and want to make sure the wallet supports expiration in the credential verification logic as a first step.

Seth, Dmitri can talk you through how to do this.

(A later step is to display the expirationd date, but I don't feel the need to implement this now.)

Learner Credential Issuer - token/DID exchange handling

Build a module (call it Learner Credential Issuer - LCI for ease of reference ) that simplifies issuing to the LCW, most specifically by managing a token/DID exchange between wallet and server, thereby removing the need to directly tie an issuer's OAuth system into the wallet.

The LCI could also optionally handle all the other bits like constructing the VC, signing, logging, revocation allocation, thereby making it quite a bit simpler for a new issuer to get up and running.

The LCI could be set up as a simple http server (e.g., Node Express) with two endpoints:

/issueCredential (called by issuer)
/collectCredential (called by wallet, passing holder DID)

The fundamental flow (see the diagram below) is that a request for a credential is made from a web page behind the issuer's standard authentication system (e.g., Azure), i.e, after the student has logged into the campus system. When the credential is requested, the issuer retrieves the student's data from the database and then redirects the initial http request to the 'issueCredential' endpoint of the LCI , passing along the data needed to populate the credential. The endpoint receives the data and stores it as the 'value' in a simple in-memory key-value store, with the key a new UUID. The endpoint then redirects to a deeplink that opens the LCW, passing along the UUID. The wallet opens, prompts the user to accept the credential and choose a profile/DID, then submits that DID (as a DIDAuthResponse) back to the /collectCredential endpoint where the LCI receives the DID, adds it to the VC as the subject, signs the VC and returns it.

Note: could split out the piece that handles the DID exchange with the wallet, to make it easier for projects to just use that piece - basically to provide a 'standard' non-OAuth way to collect the holder's DID.

Note that a lot of this is probably already part of sign-and-verify and so this could simply be adding two endpoints to sign-and-verify.

image

Unable to share credential presentation

Right now, attempting to verify or share credentials results in an unhandled promise rejection warning and no UI response:

 WARN     Possible Unhandled Promise Rejection (id: 0): Error: not implemented

After some debugging, I was able to track down the location of the exception. Here's the stack trace:

protocol at node_modules/react-native/Libraries/Blob/URL.js:192
_validateUriId at node_modules/@digitalcredentials/vc/lib/vc.js:588
_checkCredential at node_modules/@digitalcredentials/vc/lib/vc.js:500
createPresentation at node_modules/@digitalcredentials/vc/lib/vc.js:309
createVerifiablePresentation at app/lib/present.ts:23
sharePresentation at app/lib/present.ts:44

It looks like in version 1.1.1 of @digitalcredentials/vc, the new method _validateUriId attempts to access the protocol attribute of a URL instance, but it seems that the attribute isn't "implemented" within React Native. (Not sure if this is the right place to report the issue)

This was introduced in commit 215f61f

'No DID' error when initializing wallet

@dmitrizagidulin As requested, posting the error we talked about on the DCC call earlier this morning.

Error that appears on the emulator screen: "No DID generated. Something went wrong in wallet initialization."

Screen shot:

Simulator Screen Shot - iPhone 13 - 2022-08-18 at 11 24 09

Which might be caused by this underlying error in the didState/addDidRecord action (screen shot):

image

This is on a MacBook Pro (M1 Pro) running Monterey 12.5. Running the emulator from the cloned GitHub project with the package.json 'ios' script (react-native run-ios). Emulating iPhone 13, iOS 15.5.

credentialSubject Undefined When Transporting a VC Wrapped in a VP

When transporting a VC not wrapped in a VP the credential is accepted without error but when wrapped in a VP, the following error occurs:

`2022-03-17 14:29:28.448872-0400 Learner Credential Wallet[78223:3085257] [javascript] TypeError: undefined is not an object (evaluating 'credentialSubject.hasCredential')

This error is located at:
in CellRenderer (at VirtualizedList.js:900)
in RCTScrollContentView (at ScrollView.js:1124)
in RCTScrollView (at ScrollView.js:1260)
in ScrollView (at ScrollView.js:1286)
in ScrollView (at VirtualizedList.js:1329)
in VirtualizedList (at FlatList.js:624)
in FlatList (at ApproveCredentialsScreen.tsx:79)
in ApproveCredentialsScreen (at SceneView.tsx:126)
in StaticContainer
in StaticContainer (at SceneView.tsx:119)
in EnsureSingleNavigator (at SceneView.tsx:118)
in SceneView (at useDescriptors.tsx:210)
in RCTView (at View.js:34)
in View (at CardContainer.tsx:280)
in RCTView (at View.js:34)
in View (at CardContainer.tsx:278)
in RCTView (at View.js:34)
in View (at CardSheet.tsx:33)
in ForwardRef(CardSheet) (at Card.tsx:557)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:536)
in PanGestureHandler (at GestureHandlerNative.tsx:14)
in PanGestureHandler (at Card.tsx:530)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:526)
in RCTView (at View.js:34)
in View (at Card.tsx:520)
in Card (at CardContainer.tsx:218)
in CardContainer (at CardStack.tsx:649)
in RNSScreen (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at src/index.native.tsx:147)
in Screen (at Screens.tsx:37)
in MaybeScreen (at CardStack.tsx:642)
in RNSScreenContainer (at src/index.native.tsx:186)
in ScreenContainer (at Screens.tsx:20)
in MaybeScreenContainer (at CardStack.tsx:561)
in RCTView (at View.js:34)
in View (at Background.tsx:13)
in Background (at CardStack.tsx:559)
in CardStack (at StackView.tsx:437)
in RCTView (at View.js:34)
in View (at SafeAreaProviderCompat.tsx:42)
in SafeAreaProviderCompat (at StackView.tsx:430)
in RCTView (at View.js:34)
in View (at StackView.tsx:429)
in StackView (at createStackNavigator.tsx:118)
in Unknown (at createStackNavigator.tsx:117)
in StackNavigator (at AddCredentialNavigation.tsx:14)
in AddCredentialNavigation (at SceneView.tsx:126)
in StaticContainer
in StaticContainer (at SceneView.tsx:119)
in EnsureSingleNavigator (at SceneView.tsx:118)
in SceneView (at useDescriptors.tsx:210)
in RCTView (at View.js:34)
in View (at Screen.tsx:63)
in RCTView (at View.js:34)
in View (at Background.tsx:13)
in Background (at Screen.tsx:58)
in Screen (at BottomTabView.tsx:129)
in RNSScreen (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at src/index.native.tsx:147)
in Screen (at ScreenFallback.tsx:37)
in MaybeScreen (at BottomTabView.tsx:122)
in RNSScreenContainer (at src/index.native.tsx:186)
in ScreenContainer (at ScreenFallback.tsx:28)
in MaybeScreenContainer (at BottomTabView.tsx:93)
in RCTView (at View.js:34)
in View (at SafeAreaProviderCompat.tsx:42)
in SafeAreaProviderCompat (at BottomTabView.tsx:92)
in BottomTabView (at createBottomTabNavigator.tsx:116)
in Unknown (at createBottomTabNavigator.tsx:115)
in BottomTabNavigator (at HomeNavigation.tsx:29)
in HomeNavigation (at SceneView.tsx:126)
in StaticContainer
in StaticContainer (at SceneView.tsx:119)
in EnsureSingleNavigator (at SceneView.tsx:118)
in SceneView (at useDescriptors.tsx:210)
in RCTView (at View.js:34)
in View (at CardContainer.tsx:280)
in RCTView (at View.js:34)
in View (at CardContainer.tsx:278)
in RCTView (at View.js:34)
in View (at CardSheet.tsx:33)
in ForwardRef(CardSheet) (at Card.tsx:557)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:536)
in PanGestureHandler (at GestureHandlerNative.tsx:14)
in PanGestureHandler (at Card.tsx:530)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:526)
in RCTView (at View.js:34)
in View (at Card.tsx:520)
in Card (at CardContainer.tsx:218)
in CardContainer (at CardStack.tsx:649)
in RNSScreen (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at src/index.native.tsx:147)
in Screen (at Screens.tsx:37)
in MaybeScreen (at CardStack.tsx:642)
in RNSScreenContainer (at src/index.native.tsx:186)
in ScreenContainer (at Screens.tsx:20)
in MaybeScreenContainer (at CardStack.tsx:561)
in RCTView (at View.js:34)
in View (at Background.tsx:13)
in Background (at CardStack.tsx:559)
in CardStack (at StackView.tsx:437)
in RCTView (at View.js:34)
in View (at SafeAreaProviderCompat.tsx:42)
in SafeAreaProviderCompat (at StackView.tsx:430)
in RCTView (at View.js:34)
in View (at StackView.tsx:429)
in StackView (at createStackNavigator.tsx:118)
in Unknown (at createStackNavigator.tsx:117)
in StackNavigator (at RootNavigation.tsx:14)
in RootNavigation (at AppNavigation.tsx:79)
in EnsureSingleNavigator (at BaseNavigationContainer.tsx:430)
in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:132)
in ThemeProvider (at NavigationContainer.tsx:131)
in ForwardRef(NavigationContainerInner) (at AppNavigation.tsx:101)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
in SafeAreaProvider (at AppNavigation.tsx:98)
in AppNavigation (at App.tsx:12)
in Provider (at App.tsx:11)
in App (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)`

Example VP:
{"@context":["https://www.w3.org/2018/credentials/v1"],"type":["VerifiablePresentation"],"verifiableCredential":[{"@context":["https://www.w3.org/2018/credentials/v1","https://w3id.org/security/suites/ed25519-2020/v1","https://w3id.org/dcc/v1"],"id":"https://cred.127.0.0.1.nip.io/api/issuance/12","type":["VerifiableCredential","Assertion"],"issuer":{"id":"did:key:z6MkmLN7XTAQUPFEpEHKtikoanHL24bPvWaVvHQEVLaTxk65","name":"United Federation of Production Software","image":"https://media.badgr.com/uploads/issuers/issuer_logo_2a3aa2a8-fc9d-4b46-a25e-d4ec721a1681.png","url":"https://ufop.badgr.com"},"issuanceDate":"2021-01-01T00:00:00.000Z","credentialSubject":{"id":"did:key:z6MkjUpSWmHTdiYAG3ASMD5tPHAtD9F1fGnQEi94sPNF7vUs","name":"GT Buz","hasCredential":{"id":"https://ufop.badgr.com/public/badges/-Kiv1iwRRraKLt1OWmo-yw","name":"I.C.E.B.E.R.G.: an Intercultural Program","type":["EducationalOccupationalCredential"],"description":"This credential certifies participation in the I.C.E.B.E.R.G. (Inspiring Cross-cultural Experiences By Engaging Ramblers at Georgia Tech) program, offered by the Georgia Tech Office of International Education.","competencyRequired":"(1) Attend three workshops on the topics of culture and self-awareness, perception and values, and the Culture Map. \n(2) Complete a culminating self-assessment on the skills gained throughout the I.C.E.B.E.R.G. program."}},"proof":{"type":"Ed25519Signature2020","created":"2022-03-17T18:29:28Z","verificationMethod":"did:key:z6MkmLN7XTAQUPFEpEHKtikoanHL24bPvWaVvHQEVLaTxk65#z6MkmLN7XTAQUPFEpEHKtikoanHL24bPvWaVvHQEVLaTxk65","proofPurpose":"assertionMethod","proofValue":"z4W7ci6ip4qUvRhW9P4f1wsweU5JdeCcHPWvGcFebTKDsHDEaexcFNnbDajieZ5ofGzd8NGGs2cW8o17FosaohR7A"}}]}

Example VC without VP that is accepted without error:

{"@context":["https://www.w3.org/2018/credentials/v1","https://w3id.org/security/suites/ed25519-2020/v1","https://w3id.org/dcc/v1"],"id":"https://cred.127.0.0.1.nip.io/api/issuance/12","type":["VerifiableCredential","Assertion"],"issuer":{"id":"did:key:z6MkmLN7XTAQUPFEpEHKtikoanHL24bPvWaVvHQEVLaTxk65","name":"United Federation of Production Software","image":"https://media.badgr.com/uploads/issuers/issuer_logo_2a3aa2a8-fc9d-4b46-a25e-d4ec721a1681.png","url":"https://ufop.badgr.com"},"issuanceDate":"2021-01-01T00:00:00.000Z","credentialSubject":{"id":"did:key:z6MkjUpSWmHTdiYAG3ASMD5tPHAtD9F1fGnQEi94sPNF7vUs","name":"GT Buz","hasCredential":{"id":"https://ufop.badgr.com/public/badges/-Kiv1iwRRraKLt1OWmo-yw","name":"I.C.E.B.E.R.G.: an Intercultural Program","type":["EducationalOccupationalCredential"],"description":"This credential certifies participation in the I.C.E.B.E.R.G. (Inspiring Cross-cultural Experiences By Engaging Ramblers at Georgia Tech) program, offered by the Georgia Tech Office of International Education.","competencyRequired":"(1) Attend three workshops on the topics of culture and self-awareness, perception and values, and the Culture Map. \n(2) Complete a culminating self-assessment on the skills gained throughout the I.C.E.B.E.R.G. program."}},"proof":{"type":"Ed25519Signature2020","created":"2022-03-17T18:34:49Z","verificationMethod":"did:key:z6MkmLN7XTAQUPFEpEHKtikoanHL24bPvWaVvHQEVLaTxk65#z6MkmLN7XTAQUPFEpEHKtikoanHL24bPvWaVvHQEVLaTxk65","proofPurpose":"assertionMethod","proofValue":"z3hzckKvrVsHE7Rn3A6emsALdfSzKaqCYYc799QBGRGa9mo1LgMEUHZz6kq2Sqo19rYcSWjKSZkjrg3NhXYiY8jD4"}}

Swipe to Delete language

Instead of "Are you sure you want to remove Brandon Muramatsu from your wallet?"

I suggest changing to "Are you sure you want to remove <hasCredential.name> from your wallet?"

Feature Request: Verifiable Presentation creation with server-provided challenge

Short Description

Right now, LCW is able to generate a Verifiable Presentation (VP) using a random UUID as challenge. To confirm that a given VP was generated intentionally for a given third party, it is necessary to have that challenge supplied by that third party.

Target Process Outline

This could be very similar to the current process for loading credentials into the wallet, hopefully minimizing required changes:

  1. Our web app generates a qr code with the following information
    1. Random server-generated challenge
    2. API endpoint URL to send the VP to
dccrequest://present?              // DCC: mobile app deep link
&vc_present_url=<vc_present_url>   // DCC: verifiable credential present url
&challenge=<challenge>             // DCC: challenge for signing
  1. After scanning the code with the smartphone camera, the LCW can generate the VP using the provided challenge.
    1. The order of sub-actions here is not clear. Either selecting credentials for the VP, or scanning the code could happen first.
  2. The finished VP is sent from the LCW to the API endpoint obtained previously from the qr code.
  3. Our server can validate that the VP is valid and uses the correct challenge.

Update credential verify status text

Credential not verified text:

This could mean that the credential:

  • is in an unrecognized format
  • the digital signature does not validate (aka has been tampered with)
  • has not been issued by a registered institution
  • the issuing institution could not be reached to verify the credential
  • has expired
  • has been revoked by the issuing institution

Display criteria

This is for future consideration, not for initial pilots.

User would like the criteria to display in the wallet. In our credentials, that's contained in the competencyRequired field.

Add Achievement.image to Home Screen Display

An Open Badge may have an achievement.image: https://imsglobal.github.io/openbadges-specification/ob_v3p0.html#achievement

The image is an object minimally containing an id and type like:

"image": {
        "id": "https://w3c-ccg.github.io/vc-ed/plugfest-2-2022/images/JFF-VC-EDU-PLUGFEST2-badge-image.png",
        "type": "Image"
      }

the id can be a URL or an embedded image like in this example: https://w3c-ccg.github.io/vc-ed/plugfest-2-2022/unsigned-badge-example-p2-embedded-image.json

An achievement image is not required by the Open Badges spec, so the display conditional for home can be: if (achievement.image) > display achievement.image, else if (issuer.image) > display issuer.image, else display nothing.

App crashes after viewing credential

I tried adding credentials listed at digitalcredentials/docs#10 and encountered the following:

  1. Add credential using QR code
  2. Upon success, click "Added to Wallet"
  3. Arrive at Credential Preview, Click Home
  4. See credential from step 1. Tap that credential.
  5. App crashes
  6. Upon reopening app, my wallet is empty again.

My wallet remains empty until after I add another credential, at which point I can temporarily see credential from step 1. But once I try to select a credential, the app crashes and my wallet empties again.

Support for deep links as QR Codes

Currently eduWallet supports QR codes that fully contain a credential. This should be extened to allow the app to process a deep link URL encoded in a QR code.

LCW White Screens after update

After updating LCW to any version from at least 16 onward, opening the newly updated app causes a white screen under at least iOS 15.2+. Force closing the app does not resolve the issue. Only resolution seems to be turning off the phone and restarting it.

Version number display on About screen

Is there an automated way of displaying the current build number in iOS and Android at the bottom of the About screen and maybe the Home screen so we can visually determine the version number after building it?

I think we're going to want to display this somewhere.

(Seth, I'm ok with adding this as a new feature and spending time to implement it and including getting Brandon Findlay involved in suggesting a location for it.)

Wallet logic directing GT users to Google signon

I believe this behavior started Friday 1/28 on iOS (maybe a few days earlier).

GT users are being directed to log in via Google, rather than GT's OIDC. This happens both with a QR code and with a normal deep link. Here's the deep link I tested for reference:

dccrequest://request?issuer=https%3A%2F%2Fsso.gatech.edu%2Fcas%2Foidc&vc_request_url=https%3A%2F%2Fcredadmin.blockcerts.gatech.edu%2Fapi%2Fclaim%2F&challenge=544317d2-22d3-4efd-a62a-a55860aa0d69&auth_type=code

After discussing in Slack, Dmitri is investigating... but creating an issue here just to document it.

Enable scanning of QR codes containing raw JSON text

We currently support scanning of VPQR-encoded QR codes, and issue #249 adds support for QR codes containing URLs.

In addition, we need to support a third type of QR codes, which is containing raw JSON text.

For example:

image

When text-decoded, contains (with whitespace removed):

{
  "@context": [
    "https://www.w3.org/2018/credentials/v1"
  ],
  "type": [
    "VerifiablePresentation"
  ],
  "verifiableCredential": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://purl.imsglobal.org/spec/ob/v3p0/context.json",
      "https://w3id.org/security/suites/ed25519-2020/v1"
    ],
    "id": "urn:uuid:a63a60be-f4af-491c-87fc-2c8fd3007a58",
    "type": [
      "VerifiableCredential",
      "OpenBadgeCredential"
    ],
    "name": "JFF x vc-edu PlugFest 2 Interoperability",
    "issuer": {
      "type": [
        "Profile"
      ],
      "id": "did:key:z6MkqanD5cmEVf154z5xExoxNKENAzVr3gdPo4wD2R2aCUzj",
      "name": "Jobs for the Future (JFF)",
      "url": "https://www.jff.org/",
      "image": "https://w3c-ccg.github.io/vc-ed/plugfest-1-2022/images/JFF_LogoLockup.png"
    },
    "credentialSubject": {
      "type": [
        "AchievementSubject"
      ],
      "id": "did:key:123",
      "achievement": {
        "id": "urn:uuid:bd6d9316-f7ae-4073-a1e5-2f7f5bd22922",
        "type": [
          "Achievement"
        ],
        "name": "JFF x vc-edu PlugFest 2 Interoperability",
        "description": "This credential solution supports the use of OBv3 and w3c Verifiable Credentials and is interoperable with at least two other solutions.  This was demonstrated successfully during JFF x vc-edu PlugFest 2.",
        "criteria": {
          "narrative": "Solutions providers earned this badge by demonstrating interoperability between multiple providers based on the OBv3 candidate final standard, with some additional required fields. Credential issuers earning this badge successfully issued a credential into at least two wallets.  Wallet implementers earning this badge successfully displayed credentials issued by at least two different credential issuers."
        },
        "image": {
          "id": "https://w3c-ccg.github.io/vc-ed/plugfest-2-2022/images/JFF-VC-EDU-PLUGFEST2-badge-image.png",
          "type": "Image"
        }
      }
    },
    "issuanceDate": "2022-11-02T15:43:06Z",
    "proof": {
      "type": "Ed25519Signature2020",
      "created": "2022-11-02T15:43:06Z",
      "verificationMethod": "did:key:z6MkqanD5cmEVf154z5xExoxNKENAzVr3gdPo4wD2R2aCUzj#z6MkqanD5cmEVf154z5xExoxNKENAzVr3gdPo4wD2R2aCUzj",
      "proofPurpose": "assertionMethod",
      "proofValue": "z4KaKPTzmrwt73rfBzCoVRocbVRnZDH4PgVpgKWKi2z4nFStQJUeHwy5pWYKkvS1fuo2SgsgyWHxZvMDEeHEVkUTz"
    }
  }
}

This should also be fed to the Add Credential logic.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.