GoodDollar / GoodWeb3-Mono

mono repo with GoodDollar's web3 UI components and SDK
https://gooddollar-storybook.vercel.app
3 stars 4 forks source link

[GoodID-flow] Segmentation flow #140

Open patpedrosa opened 9 months ago

patpedrosa commented 9 months ago

Business Description

The segmentation flow is where we try to get some additional information on the user. After completing the face verification flow OR if the user was not required to re-verify, we want to run AI on a user's image to estimate their gender and age range. Additionally, we will ask for permission to use their location. (they gave permission on the initial onboard screen) we need to ask their permission to process all this data for checking eligibility We show them a completed good-id card with all the data we were able to verify. This concludes the good-id upgrade flow. After this confirmation screen a user is either deemed 'eligible' and will be shown the redtent offer. or deemed 'uneligible', and a user will be going to the claim-screen.

Detailed Description of Functionality

A user first arrives on the Segmentation screen. A modal should show that we are processing their data during which we make two api-calls to get a certificate for identity/location

Once the checks are completed, we will display to the user the result on the Segmentation screen, and ask them to confirm whether it's correct.

HappyPath

If correct and the user taps on "Yes, I am" and all values are verified (If not all values are verified the user continues on the unhappy completion screen flow below):

Unhappy path

If incorrect and the user taps on 'No, I am not',

If user does not accept location permission:

The unhappy flow for the completion screen: (True for: Dispute flow, not all values could be verified, did not accept processing agreement)

Technical Implementation

Segmentation wizard:

Segmentation controller:

Wallet Implementation

Gooddapp implementation

Design reference

Full Design: https://www.figma.com/file/ihw1PxBvLxacTHnN2aj4lC/3.-Product?type=design&node-id=13532-24841&mode=design&t=lf0VKtL8uIIHb2Yq-4

Design preview: image

Acceptance Criteria

How we know if the feature is working as expected / how we test it.

L03TJ3 commented 9 months ago

@patpedrosa when is this check triggered? just upon claiming like always happens for new users but now for everyone?

sirpy commented 8 months ago

@patpedrosa @L03TJ3 For location from device there's a permission flow required. Like we ask for camera permissions. It needs the design+text for the location permission dialog. What if user doesnt give permissions?

@johnsmith-gooddollar please provide the endpoints and how to call them from UI

johnsmith-gooddollar commented 8 months ago

@sirpy currently we have a single one:

POST /goodid/certificate/location
Accepts: application/json
Content-Type: application/json
{
  "user": { // optional
     "mobile": "+380639549357"
   },
  "geoposition": { // a GeolocationPosition returned from navigator.geolocation.getCurrentPosition()
    "timestamp": 1707313563,
    "coords": {
      "longitude": 30.394171,
      "latitude": 50.328899,
      "accuracy": null,
      "altitude": null,
      "altitudeAccuracy": null,
      "heading": null,
      "speed": null,
    }
  }
}

HTTP/1.1 200 OK
Content-Type: application/json
{
  "success": true,
  "certificate": {
    "credential": {
      "credentialSubject": {
        "id": 'did:ethr:<g$ wallet address>',
        "countryCode": "<2-chars upercased>"
      },
      "issuer": {
        "id": 'did:key:<GoodServer's DID>',
      },
      "type": ['VerifiableLocationCredential'],
      "@context": ["https://www.w3.org/2018/credentials/v1"],
      "issuanceDate": "2022-10-28T11:54:22.000Z",
      "proof": {
        "type": "JwtProof2020",
        "jwt": 'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7InlvdSI6IlJvY2sifX0sInN1YiI6ImRpZDp3ZWI6ZXhhbXBsZS5jb20iLCJuYmYiOjE2NjY5NTgwNjIsImlzcyI6ImRpZDpldGhyOmdvZXJsaToweDAzNTBlZWVlYTE0MTBjNWIxNTJmMWE4OGUwZmZlOGJiOGEwYmMzZGY4NjhiNzQwZWIyMzUyYjFkYmY5M2I1OWMxNiJ9.EPeuQBpkK13V9wu66SLg7u8ebY2OS8b2Biah2Vw-RI-Atui2rtujQkVc2t9m1Eqm4XQFECfysgQBdWwnSDvIjw',
      },
    },
  }  
}
johnsmith-gooddollar commented 8 months ago

also we will add endpoint for issue gender + age + identity certificate according to https://github.com/GoodDollar/GoodServer/issues/453 (it will have subject data from the ticket and type: ['VerifiableIdentityCredetial', 'VerifiableGenderCredetial', 'VerifiableAgeCredetial'])

and endpoint to verify certificate.

checking certificates against some input data (e.g. is user from Nigeria) could be done client-side. if certificate passes the check it should be verified via GoodServer

sirpy commented 8 months ago

@johnsmith-gooddollar type should always be verifiablecredential

L03TJ3 commented 8 months ago

@sirpy Can I ask why? How else can I know or filter on the client-side on what credential has been issued? (without needing to alter anything) Its what the type field is supposed to be for. Defining type of credential is actually also explained on w3c: https://www.w3.org/TR/vc-data-model-2.0/#example-a-template-for-creating-prototype-verifiable-credentials

so looking again, it maybe should be ['VerifiableCredential, 'Verifiable(type)Credential')

sirpy commented 8 months ago

@L03TJ3 @johnsmith-gooddollar its fine to have multiple types when the first one is VerifiableCredential The actual type and description of the credential should be defined in a schema linked to by the field schemaUrl you can visit the ipfs file to see the schema structure for example

"schemaHash": "1149366adf462264c0c0450644e765d8",
    "schemaType": "urn:uuid:6585bbfe-e479-4d8a-afd9-4c7088c72b34",
    "schemaTypeDescription": "POAP01",
    "schemaUrl": "ipfs://QmTSwnuCB9grYMB2z5EKXDagfChurK5MiMCS6efrRbsyVX",
johnsmith-gooddollar commented 8 months ago

@johnsmith-gooddollar type should always be verifiablecredential

we discussed it with @L03TJ3 and decided to define different types:


export const Credential = Object.freeze({
  Location: 'VerifiableLocationCredential',
  Identity: 'VerifiableIdentityCredential',
  Gender: 'VerifiableGenderCredential',
  Age: 'VerifiableAgeCredential'
})
johnsmith-gooddollar commented 8 months ago

@L03TJ3 @johnsmith-gooddollar its fine to have multiple types when the first one is VerifiableCredential

@sirpy done in a separate PR

johnsmith-gooddollar commented 8 months ago

@sirpy @L03TJ3 I've added verify endpoint:


    POST /goodid/certificate/verify
    Content-Type: application/json
    {
      "certificate": {
        "credential": {
          "credentialSubject": {
            "id": 'did:ethr:<g$ wallet address>',
            "countryCode": "<2-chars upercased>"
          },
          "issuer": {
            "id": 'did:key:<GoodServer's DID>',
          },
          "type": ["VerifiableCredential ", <set of VerifiableLocationCredential | VerifiableIdentityCredential | VerifiableGenderCredential | VerifiableAgeCredential items>],
          "@context": ["https://www.w3.org/2018/credentials/v1"],
          "issuanceDate": "2022-10-28T11:54:22.000Z",
          "proof": {
            "type": "JwtProof2020",
            "jwt": 'eyJhbGciOiJFUzI1NksiLCJ0eXAiOiJKV1QifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7InlvdSI6IlJvY2sifX0sInN1YiI6ImRpZDp3ZWI6ZXhhbXBsZS5jb20iLCJuYmYiOjE2NjY5NTgwNjIsImlzcyI6ImRpZDpldGhyOmdvZXJsaToweDAzNTBlZWVlYTE0MTBjNWIxNTJmMWE4OGUwZmZlOGJiOGEwYmMzZGY4NjhiNzQwZWIyMzUyYjFkYmY5M2I1OWMxNiJ9.EPeuQBpkK13V9wu66SLg7u8ebY2OS8b2Biah2Vw-RI-Atui2rtujQkVc2t9m1Eqm4XQFECfysgQBdWwnSDvIjw',
          },
        },
      }
    }

    HTTP/1.1 200 OK
    Content-Type: application/json
    {
      "success": true
    }

PR is here: https://github.com/GoodDollar/GoodServer/pull/459