Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mdoc): proximity flow for Android functionality #202

Merged
merged 4 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ yarn-error.log*
.env.development.local
.env.test.local
.env.production.local
.env

# vercel
.vercel
Expand Down
22 changes: 12 additions & 10 deletions apps/easypid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"dependencies": {
"@animo-id/expo-ausweis-sdk": "*",
"@animo-id/expo-mdoc-data-transfer": "0.0.1-alpha.1",
"@animo-id/expo-mdoc-data-transfer": "*",
"@animo-id/expo-secure-environment": "*",
"@credo-ts/core": "*",
"@expo-google-fonts/open-sans": "^0.2.3",
Expand All @@ -24,41 +24,43 @@
"@package/secure-store": "workspace:*",
"@package/ui": "workspace:*",
"@package/utils": "workspace:*",
"@protokoll/mdoc-client": "*",
"@react-native-community/blur": "^4.3.2",
"@react-native-community/netinfo": "11.3.1",
"@react-native-masked-view/masked-view": "0.3.1",
"@react-navigation/native": "^6.1.6",
"babel-plugin-module-resolver": "^4.1.0",
"burnt": "^0.12.2",
"expo": "~51.0.12",
"expo": "~51.0.39",
"expo-barcode-scanner": "~13.0.1",
"expo-blur": "^13.0.2",
"expo-constants": "~16.0.2",
"expo-dev-client": "~4.0.16",
"expo-font": "~12.0.7",
"expo-haptics": "~13.0.1",
"expo-image": "~1.12.11",
"expo-image": "~1.13.0",
"expo-linear-gradient": "~13.0.2",
"expo-linking": "~6.3.1",
"expo-navigation-bar": "~3.0.6",
"expo-router": "~3.5.16",
"expo-router": "~3.5.24",
"expo-secure-store": "~13.0.1",
"expo-splash-screen": "~0.27.5",
"expo-splash-screen": "~0.27.7",
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.6",
"expo-updates": "~0.25.16",
"react": "*",
"react-native": "*",
"react": "18.2.0",
"react-native": "~0.74.5",
"react-native-argon2": "^2.0.1",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "~2.16.2",
"react-native-get-random-values": "~1.11.0",
"react-native-keychain": "^8.2.0",
"react-native-mmkv": "^2.12.2",
"react-native-reanimated": "~3.15.0",
"react-native-safe-area-context": "4.10.1",
"react-native-qrcode-svg": "^6.3.12",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "~3.31.1",
"react-native-svg": "15.2.0"
"react-native-svg": "15.9.0"
},
"devDependencies": {
"@babel/core": "^7.24.4",
Expand Down
1 change: 1 addition & 0 deletions apps/easypid/src/features/proximity/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './mdocProximity'
95 changes: 95 additions & 0 deletions apps/easypid/src/features/proximity/mdocProximity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { mdocDataTransfer } from '@animo-id/expo-mdoc-data-transfer'
import { TypedArrayEncoder } from '@credo-ts/core'
import { getMdocContext } from '@credo-ts/core/build/modules/mdoc/MdocContext'
import type { EasyPIDAppAgent } from '@package/agent'
import {
COSEKey,
DeviceRequest,
DeviceResponse,
MDoc,
type MdocContext,
parseIssuerSigned,
} from '@protokoll/mdoc-client'
import { type Permission, PermissionsAndroid, Platform } from 'react-native'

type ShareDeviceResponseOptions = {
sessionTranscript: Uint8Array
deviceRequest: Uint8Array
agent: EasyPIDAppAgent
}

const PERMISSIONS = [
'android.permission.ACCESS_FINE_LOCATION',
'android.permission.BLUETOOTH_CONNECT',
'android.permission.BLUETOOTH_SCAN',
'android.permission.BLUETOOTH_ADVERTISE',
'android.permission.ACCESS_COARSE_LOCATION',
] as const as Permission[]

export const requestMdocPermissions = async () => {
if (Platform.OS !== 'android') return
await PermissionsAndroid.requestMultiple(PERMISSIONS)
}

export const getMdocQrCode = async () => {
const mdt = mdocDataTransfer.instance()
const qrData = await mdt.startQrEngagement()
return qrData
}

/**
*
* Wait for the device request
*
* Returns the device request and session transcript
*
*/
export const waitForDeviceRequest = async () => {
const mdt = mdocDataTransfer.instance()
return await mdt.waitForDeviceRequest()
}

/**
*
* Naive way to share the device response based on the device request
*
* Optimalisations:
*
* 1. pre-filter the `agent.mdoc.getAll()` based on the `deviceRequest`
* 2. Allow the user to pick which specific mdoc is being used
*
*/
export const shareDeviceResponse = async (options: ShareDeviceResponseOptions) => {
const mdocs = await options.agent.mdoc.getAll()
const issuerSignedDocuments = mdocs.map((mdoc) => {
const docType = mdoc.getTag('DocType') as string
return parseIssuerSigned(TypedArrayEncoder.fromBase64(mdoc.base64Url), docType)
})

const mdoc = new MDoc(issuerSignedDocuments)

const mdocContext = getMdocContext(options.agent.context) as unknown as {
cose: MdocContext['cose']
crypto: MdocContext['crypto']
}

const mdt = mdocDataTransfer.instance()

const mso = mdoc.documents[0].issuerSigned.issuerAuth.decodedPayload
const deviceKeyInfo = mso.deviceKeyInfo
if (!deviceKeyInfo?.deviceKey) {
throw new Error('Device key info is missing')
}

const publicDeviceJwk = COSEKey.import(deviceKeyInfo.deviceKey).toJWK()

const deviceRequest = DeviceRequest.parse(options.deviceRequest)

const deviceResponse = await DeviceResponse.from(mdoc)
.usingSessionTranscriptBytes(new Uint8Array(options.sessionTranscript))
.usingDeviceRequest(deviceRequest)
.authenticateWithSignature(publicDeviceJwk, 'ES256')
.sign(mdocContext)

await mdt.sendDeviceResponse(deviceResponse.encode())
}
1 change: 1 addition & 0 deletions apps/paradym/app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const config = {
},
plugins: [
[
'expo-router',
'expo-font',
{
fonts: [
Expand Down
18 changes: 9 additions & 9 deletions apps/paradym/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,31 @@
"@react-navigation/native": "^6.1.6",
"babel-plugin-module-resolver": "^4.1.0",
"burnt": "^0.12.2",
"expo": "~51.0.12",
"expo": "~51.0.39",
"expo-barcode-scanner": "~13.0.1",
"expo-constants": "~16.0.2",
"expo-dev-client": "~4.0.16",
"expo-font": "~12.0.7",
"expo-haptics": "~13.0.1",
"expo-image": "~1.12.11",
"expo-image": "~1.13.0",
"expo-linear-gradient": "~13.0.2",
"expo-linking": "~6.3.1",
"expo-navigation-bar": "~3.0.6",
"expo-router": "~3.5.16",
"expo-router": "~3.5.24",
"expo-secure-store": "~13.0.1",
"expo-splash-screen": "~0.27.5",
"expo-splash-screen": "~0.27.7",
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.6",
"expo-updates": "~0.25.16",
"react": "*",
"react-native": "*",
"react": "18.2.0",
"react-native": "~0.74.5",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "~2.16.2",
"react-native-get-random-values": "~1.11.0",
"react-native-reanimated": "~3.15.0",
"react-native-safe-area-context": "4.10.1",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "~3.31.1",
"react-native-svg": "15.2.0"
"react-native-svg": "15.9.0"
},
"devDependencies": {
"@babel/core": "^7.24.4",
Expand Down
3 changes: 2 additions & 1 deletion apps/storybook/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"../../node_modules/@expo-google-fonts/open-sans/OpenSans_700Bold.ttf"
]
}
]
],
"expo-router"
]
}
25 changes: 12 additions & 13 deletions apps/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "storybook-app",
"version": "1.0.0",
"main": "App.tsx",
"license": "MIT",
"private": true,
"scripts": {
"start": "expo start -c --dev-client",
"android": "expo run:android",
Expand All @@ -20,34 +20,34 @@
"@react-navigation/native": "^6.1.6",
"@storybook/addons": "^7.6.17",
"burnt": "^0.12.2",
"expo": "~51.0.12",
"expo": "~51.0.39",
"expo-barcode-scanner": "~13.0.1",
"expo-constants": "~16.0.2",
"expo-dev-client": "~4.0.16",
"expo-font": "~12.0.7",
"expo-haptics": "~13.0.1",
"expo-image": "~1.12.11",
"expo-image": "~1.13.0",
"expo-linear-gradient": "~13.0.2",
"expo-linking": "~6.3.1",
"expo-navigation-bar": "~3.0.6",
"expo-router": "~3.5.16",
"expo-router": "~3.5.24",
"expo-secure-store": "~13.0.1",
"expo-splash-screen": "~0.27.5",
"expo-splash-screen": "~0.27.7",
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.6",
"react": "*",
"react": "18.2.0",
"react-device-frameset": "^1.3.4",
"react-native": "*",
"react-native": "~0.74.5",
"react-native-gesture-handler": "~2.16.2",
"react-native-get-random-values": "~1.11.0",
"react-native-reanimated": "~3.15.0",
"react-native-safe-area-context": "4.10.1",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "~3.31.1",
"react-native-svg": "15.2.0"
"react-native-svg": "15.9.0"
},
"devDependencies": {
"@babel/core": "^7.24.4",
"@expo/metro-runtime": "~3.1.3",
"@expo/metro-runtime": "~3.2.3",
"@storybook/addon-actions": "^7.6.18",
"@storybook/addon-controls": "^7.6.18",
"@storybook/addon-essentials": "^7.6.18",
Expand All @@ -69,6 +69,5 @@
"storybook": "^7.6.18",
"tamagui-loader": "1.109.5",
"typescript": "*"
},
"private": true
}
}
18 changes: 11 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
},
"pnpm": {
"overrides": {
"@types/react": "~18.2.79",
"react": "18.2.0",
"react-docgen-typescript": "2.2.2",
"typescript": "~5.3.3",
"@unimodules/react-native-adapter": "./noop",
"@unimodules/core": "./noop",
Expand All @@ -40,18 +37,25 @@
"@credo-ts/question-answer": "https://gitpkg.vercel.app/animo/aries-framework-javascript/packages/question-answer?funke",
"@credo-ts/react-native": "https://gitpkg.vercel.app/animo/aries-framework-javascript/packages/react-native?funke",
"@credo-ts/react-hooks": "0.6.1",
"@animo-id/expo-secure-environment": "0.1.0-alpha.5",
"@animo-id/expo-ausweis-sdk": "0.0.1-alpha.14",
"react-native": "0.74.5",
"@animo-id/expo-secure-environment": "0.1.0-alpha.5",
"@animo-id/expo-mdoc-data-transfer": "0.0.3-alpha.6",
"@types/react": "~18.2.79",
"react": "18.3.1",
"react-docgen-typescript": "2.2.2",
"react-native": "~0.75.0",
"react-native-reanimated": "~3.15.5",
"@sphereon/did-auth-siop": "https://gitpkg.vercel.app/animo/OID4VC/packages/siop-oid4vp?funke",
"@sphereon/oid4vc-common": "https://gitpkg.vercel.app/animo/OID4VC/packages/common?funke",
"@sphereon/oid4vci-common": "https://gitpkg.vercel.app/animo/OID4VC/packages/oid4vci-common?funke",
"@sphereon/oid4vci-issuer": "https://gitpkg.vercel.app/animo/OID4VC/packages/issuer?funke",
"@sphereon/oid4vci-client": "https://gitpkg.vercel.app/animo/OID4VC/packages/client?funke",
"@sphereon/jarm": "https://gitpkg.vercel.app/animo/OID4VC/packages/jarm?funke"
"@sphereon/jarm": "https://gitpkg.vercel.app/animo/OID4VC/packages/jarm?funke",
"@protokoll/mdoc-client": "0.2.36"
},
"patchedDependencies": {
"@hyperledger/[email protected]": "patches/@[email protected]"
"@hyperledger/[email protected]": "patches/@[email protected]",
"@protokoll/mdoc-client": "patches/@protokoll__mdoc-client.patch"
}
}
}
8 changes: 4 additions & 4 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
"expo-linking": "~6.3.1",
"expo-modules-autolinking": "~1.11.0",
"expo-navigation-bar": "~3.0.6",
"expo-router": "~3.5.16",
"expo-router": "~3.5.24",
"fast-text-encoding": "^1.0.6",
"react": "*",
"react-native-safe-area-context": "4.10.1",
"react-native-reanimated": "~3.15.0",
"react": "18.2.0",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"solito": "^3.0.0"
},
"devDependencies": {
Expand Down
11 changes: 1 addition & 10 deletions packages/app/src/provider/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,7 @@ export function Provider({ children, ...rest }: PropsWithChildren<TamaguiProvide
return (
<TamaguiProvider disableInjectCSS defaultTheme="light" {...rest}>
<PortalProvider shouldAddRootHost>
<ToastProvider
swipeDirection="up"
duration={6000}
native={
[
/* uncomment the next line to do native toasts on mobile. NOTE: it'll require you making a dev build and won't work with Expo Go */
// 'mobile'
]
}
>
<ToastProvider swipeDirection="up" duration={6000} native={['mobile']}>
<QueryClientProvider client={queryClient}>
<GestureHandlerRootView style={{ flex: 1 }}>{children}</GestureHandlerRootView>
</QueryClientProvider>
Expand Down
2 changes: 1 addition & 1 deletion packages/scanner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"@react-native-masked-view/masked-view": "0.3.1",
"@types/react": "~18.2.79",
"expo-barcode-scanner": "~13.0.1",
"react-native": "*"
"react-native": "~0.74.5"
},
"peerDependencies": {
"@react-native-masked-view/masked-view": "0.3.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@tamagui/themes": "1.109.5",
"@tamagui/toast": "1.109.5",
"react-native-heroicons": "^4.0.0",
"react-native-reanimated": "~3.15.0",
"react-native-reanimated": "~3.10.1",
"tamagui": "1.109.5"
}
}
Loading