@animo-id/expo-mdoc-data-transfer 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.author = package['author']
12
12
  s.homepage = package['homepage']
13
- s.platforms = { :ios => '14.0'}
13
+ s.platforms = { :ios => '15.0'}
14
14
  s.swift_version = '5.4'
15
15
  s.source = { :git => "https://github.com/animo/mdoc-data-transfer.git", :tag => "#{s.version}" }
16
16
 
@@ -24,13 +24,19 @@ Pod::Spec.new do |s|
24
24
  install_modules_dependencies(s)
25
25
 
26
26
  if defined?(:spm_dependency)
27
- spm_dependency(s,
27
+ spm_dependency(s,
28
28
  # Currently we use this fork because it adds a manual `sendDeviceResponse` method
29
29
  # Which we use as we generate this outside of the library
30
- url: 'https://github.com/berendsliedrecht/eudi-lib-ios-iso18013-data-transfer.git',
31
- requirement: {kind: 'upToNextMinorVersion', minimumVersion: '0.3.12'},
32
- products: ['MdocDataTransfer18013']
33
- )
30
+ url: 'https://github.com/animo/eudi-lib-ios-iso18013-data-transfer.git',
31
+ requirement: {kind: 'upToNextMinorVersion', minimumVersion: '0.6.3'},
32
+ products: ['MdocDataTransfer18013']
33
+ )
34
+
35
+ spm_dependency(s,
36
+ url: 'https://github.com/eu-digital-identity-wallet/eudi-lib-ios-wallet-storage.git',
37
+ requirement: {kind: 'upToNextMinorVersion', minimumVersion: '0.4.8'},
38
+ products: ['WalletStorage']
39
+ )
34
40
  else
35
41
  raise "Please upgrade React Native to >=0.75.0 to use SPM dependencies."
36
42
  end
@@ -42,16 +42,27 @@ android {
42
42
  }
43
43
  }
44
44
 
45
-
46
45
  dependencies {
47
- implementation("eu.europa.ec.eudi:eudi-lib-android-iso18013-data-transfer:0.3.0-SNAPSHOT") {
46
+ implementation("eu.europa.ec.eudi:eudi-lib-android-wallet-document-manager:0.9.0") {
47
+ exclude group: 'org.bouncycastle'
48
+ exclude module: 'bcprov-jdk18on'
49
+ }
50
+
51
+ implementation("com.android.identity:identity-android:202408.1") {
48
52
  exclude group: 'org.bouncycastle'
49
53
  exclude module: 'bcprov-jdk18on'
50
54
  }
55
+
56
+ implementation("eu.europa.ec.eudi:eudi-lib-android-iso18013-data-transfer:0.6.0") {
57
+ exclude group: 'org.bouncycastle'
58
+ exclude module: 'bcprov-jdk18on'
59
+ }
60
+
51
61
  implementation("org.bouncycastle:bcprov-jdk18on") {
52
62
  version {
53
63
  strictly '1.72'
54
64
  }
55
65
  }
66
+
56
67
  implementation "androidx.biometric:biometric-ktx:1.2.0-alpha05"
57
68
  }
@@ -6,7 +6,8 @@ import android.util.Log
6
6
  import androidx.activity.ComponentActivity
7
7
  import eu.europa.ec.eudi.iso18013.transfer.TransferEvent
8
8
  import eu.europa.ec.eudi.iso18013.transfer.engagement.NfcEngagementService
9
- import eu.europa.ec.eudi.iso18013.transfer.response.DeviceRequest
9
+ import eu.europa.ec.eudi.iso18013.transfer.response.device.DeviceRequest
10
+ import eu.europa.ec.eudi.iso18013.transfer.response.device.DeviceResponse
10
11
 
11
12
  class MdocDataTransfer(
12
13
  context: Context,
@@ -49,24 +50,19 @@ class MdocDataTransfer(
49
50
 
50
51
  is TransferEvent.RequestReceived -> {
51
52
  Log.d(TAG, ":::mdoc-data-transfer::: TransferEvent.RequestReceived")
52
- when (val request = event.request) {
53
- is DeviceRequest -> {
54
- sendEvent(
55
- MdocDataTransferEvent.ON_REQUEST_RECEIVED,
56
- mapOf(
57
- ("deviceRequest" to request.deviceRequestBytes.asList()),
58
- ("sessionTranscript" to request.sessionTranscriptBytes.asList())
59
- )
60
- )
61
- }
62
- }
53
+ val request = event.request as DeviceRequest
54
+ sendEvent(
55
+ MdocDataTransferEvent.ON_REQUEST_RECEIVED, mapOf(
56
+ "deviceRequest" to request.deviceRequestBytes.asList(),
57
+ "sessionTranscript" to request.sessionTranscriptBytes.asList()
58
+ )
59
+ )
63
60
  }
64
61
 
65
62
  is TransferEvent.ResponseSent -> {
66
63
  Log.d(TAG, ":::mdoc-data-transfer::: TransferEvent.ResponseSent")
67
64
  sendEvent(
68
- MdocDataTransferEvent.ON_RESPONSE_SENT,
69
- null
65
+ MdocDataTransferEvent.ON_RESPONSE_SENT, null
70
66
  )
71
67
  }
72
68
  }
@@ -82,7 +78,7 @@ class MdocDataTransfer(
82
78
  }
83
79
 
84
80
  fun respond(deviceResponse: ByteArray) {
85
- MdocDataTransferManager.transferManager.value.sendResponse(deviceResponse)
81
+ MdocDataTransferManager.transferManager.value.sendResponse(DeviceResponse(deviceResponse))
86
82
  }
87
83
 
88
84
  fun enableNfc() {
@@ -2,10 +2,11 @@ package id.animo.mdocdatatransfer
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.content.Context
5
- import eu.europa.ec.eudi.iso18013.transfer.DocumentsResolver
5
+ import com.android.identity.securearea.software.SoftwareSecureArea
6
+ import com.android.identity.storage.EphemeralStorageEngine
6
7
  import eu.europa.ec.eudi.iso18013.transfer.TransferManager
7
- import eu.europa.ec.eudi.iso18013.transfer.response.ResponseGenerator
8
- import eu.europa.ec.eudi.iso18013.transfer.retrieval.BleRetrievalMethod
8
+ import eu.europa.ec.eudi.iso18013.transfer.engagement.BleRetrievalMethod
9
+ import eu.europa.ec.eudi.wallet.document.DocumentManager
9
10
 
10
11
  @SuppressLint("StaticFieldLeak")
11
12
  object MdocDataTransferManager {
@@ -16,20 +17,28 @@ object MdocDataTransferManager {
16
17
  this.context = context
17
18
  }
18
19
 
20
+ private val storageEngine = EphemeralStorageEngine()
21
+ private val secureArea = SoftwareSecureArea(storageEngine)
22
+
23
+ private val documentManager = DocumentManager
24
+ .Builder()
25
+ .setIdentifier("eudi_wallet_document_manager")
26
+ .setStorageEngine(storageEngine)
27
+ .addSecureArea(secureArea)
28
+ .build()
29
+
19
30
  val transferManager = lazy {
20
- TransferManager.Builder(context).apply {
21
- retrievalMethods = listOf(
31
+ TransferManager.getDefault(
32
+ context,
33
+ documentManager,
34
+ null,
35
+ listOf(
22
36
  BleRetrievalMethod(
23
37
  peripheralServerMode = true,
24
38
  centralClientMode = true,
25
39
  clearBleCache = true
26
40
  )
27
41
  )
28
- responseGenerator = ResponseGenerator.Builder(context)
29
- .apply {
30
- documentsResolver = DocumentsResolver { listOf() }
31
- }.build()
32
-
33
- }.build()
42
+ )
34
43
  }
35
44
  }
@@ -18,7 +18,7 @@ class MdocDataTransferModule : Module() {
18
18
  MdocDataTransferEvent.ON_RESPONSE_SENT
19
19
  )
20
20
 
21
- Function("initialize") {
21
+ Function("initialize") { serviceName: String ->
22
22
  // We have to re-set the Bouncy Castle provider, otherwise the EUDI library cannot find it correctly
23
23
  Security.removeProvider("BC")
24
24
  Security.addProvider(BouncyCastleProvider())
@@ -32,8 +32,6 @@ class MdocDataTransferModule : Module() {
32
32
  body ?: mapOf()
33
33
  )
34
34
  }
35
-
36
- return@Function null
37
35
  }
38
36
 
39
37
 
@@ -1,11 +1,11 @@
1
1
  import { type OnRequestReceivedEventPayload } from './MdocDataTransferEvent';
2
2
  export declare let instance: MdocDataTransfer | undefined;
3
3
  export declare const mdocDataTransfer: {
4
- instance: () => MdocDataTransfer;
4
+ instance: (serviceName: string) => MdocDataTransfer;
5
5
  };
6
6
  declare class MdocDataTransfer {
7
7
  isNfcEnabled: boolean;
8
- static initialize(): MdocDataTransfer;
8
+ static initialize(serviceName: string): MdocDataTransfer;
9
9
  startQrEngagement(): Promise<string>;
10
10
  waitForDeviceRequest(): Promise<OnRequestReceivedEventPayload<Uint8Array>>;
11
11
  sendDeviceResponse(deviceResponse: Uint8Array): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"MdocDataTransfer.d.ts","sourceRoot":"","sources":["../src/MdocDataTransfer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,6BAA6B,EAEnC,MAAM,yBAAyB,CAAA;AAGhC,eAAO,IAAI,QAAQ,EAAE,gBAAgB,GAAG,SAAqB,CAAA;AAC7D,eAAO,MAAM,gBAAgB;;CAK5B,CAAA;AAED,cAAM,gBAAgB;IACb,YAAY,UAAQ;WAEb,UAAU;IAWX,iBAAiB;IAIjB,oBAAoB;IAcpB,kBAAkB,CAAC,cAAc,EAAE,UAAU;IAUnD,QAAQ;IAWR,SAAS;CAKjB"}
1
+ {"version":3,"file":"MdocDataTransfer.d.ts","sourceRoot":"","sources":["../src/MdocDataTransfer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,6BAA6B,EAEnC,MAAM,yBAAyB,CAAA;AAGhC,eAAO,IAAI,QAAQ,EAAE,gBAAgB,GAAG,SAAqB,CAAA;AAC7D,eAAO,MAAM,gBAAgB;4BACH,MAAM;CAI/B,CAAA;AAED,cAAM,gBAAgB;IACb,YAAY,UAAQ;WAEb,UAAU,CAAC,WAAW,EAAE,MAAM;IAW/B,iBAAiB;IAIjB,oBAAoB;IAcpB,kBAAkB,CAAC,cAAc,EAAE,UAAU;IAUnD,QAAQ;IAWR,SAAS;CAKjB"}
@@ -2,16 +2,16 @@ import { MdocDataTransferEvent, } from './MdocDataTransferEvent';
2
2
  import { mDocNativeModule, mDocNativeModuleEventEmitter } from './MdocDataTransferModule';
3
3
  export let instance = undefined;
4
4
  export const mdocDataTransfer = {
5
- instance: () => {
5
+ instance: (serviceName) => {
6
6
  if (instance)
7
7
  return instance;
8
- return MdocDataTransfer.initialize();
8
+ return MdocDataTransfer.initialize(serviceName);
9
9
  },
10
10
  };
11
11
  class MdocDataTransfer {
12
12
  isNfcEnabled = false;
13
- static initialize() {
14
- const error = mDocNativeModule.initialize();
13
+ static initialize(serviceName) {
14
+ const error = mDocNativeModule.initialize(serviceName);
15
15
  if (typeof error === 'string' && error.length > 0) {
16
16
  throw new Error(error);
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MdocDataTransfer.js","sourceRoot":"","sources":["../src/MdocDataTransfer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAGtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAA;AAEzF,MAAM,CAAC,IAAI,QAAQ,GAAiC,SAAS,CAAA;AAC7D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,EAAE,GAAG,EAAE;QACb,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAA;QAC7B,OAAO,gBAAgB,CAAC,UAAU,EAAE,CAAA;IACtC,CAAC;CACF,CAAA;AAED,MAAM,gBAAgB;IACb,YAAY,GAAG,KAAK,CAAA;IAEpB,MAAM,CAAC,UAAU;QACtB,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,EAAE,CAAA;QAE3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;QACxB,CAAC;QAED,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAA;QACjC,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEM,KAAK,CAAC,iBAAiB;QAC5B,OAAO,MAAM,gBAAgB,CAAC,iBAAiB,EAAE,CAAA;IACnD,CAAC;IAEM,KAAK,CAAC,oBAAoB;QAC/B,OAAO,MAAM,IAAI,OAAO,CAA4C,CAAC,OAAO,EAAE,EAAE,CAC9E,4BAA4B,CAAC,WAAW,CACtC,qBAAqB,CAAC,iBAAiB,EACvC,CAAC,OAAsC,EAAE,EAAE;YACzC,OAAO,CAAC;gBACN,aAAa,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC;gBACpD,iBAAiB,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC,iBAAiB,CAAC;aAC7D,CAAC,CAAA;QACJ,CAAC,CACF,CACF,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,cAA0B;QACxD,MAAM,CAAC,GAAG,IAAI,OAAO,CAAwB,CAAC,OAAO,EAAE,EAAE,CACvD,4BAA4B,CAAC,WAAW,CAAC,qBAAqB,CAAC,cAAc,EAAE,OAAO,CAAC,CACxF,CAAA;QAED,gBAAgB,CAAC,kBAAkB,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAE7D,MAAM,CAAC,CAAA;IACT,CAAC;IAEM,QAAQ;QACb,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;QACzB,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QAEzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;QACxB,CAAC;QAED,QAAQ,GAAG,SAAS,CAAA;IACtB,CAAC;IAEM,SAAS;QACd,IAAI,IAAI,CAAC,YAAY;YAAE,OAAM;QAC7B,gBAAgB,CAAC,SAAS,EAAE,CAAA;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;IAC1B,CAAC;CACF","sourcesContent":["import {\n MdocDataTransferEvent,\n type OnRequestReceivedEventPayload,\n type OnResponseSendPayload,\n} from './MdocDataTransferEvent'\nimport { mDocNativeModule, mDocNativeModuleEventEmitter } from './MdocDataTransferModule'\n\nexport let instance: MdocDataTransfer | undefined = undefined\nexport const mdocDataTransfer = {\n instance: () => {\n if (instance) return instance\n return MdocDataTransfer.initialize()\n },\n}\n\nclass MdocDataTransfer {\n public isNfcEnabled = false\n\n public static initialize() {\n const error = mDocNativeModule.initialize()\n\n if (typeof error === 'string' && error.length > 0) {\n throw new Error(error)\n }\n\n instance = new MdocDataTransfer()\n return instance\n }\n\n public async startQrEngagement() {\n return await mDocNativeModule.startQrEngagement()\n }\n\n public async waitForDeviceRequest() {\n return await new Promise<OnRequestReceivedEventPayload<Uint8Array>>((resolve) =>\n mDocNativeModuleEventEmitter.addListener(\n MdocDataTransferEvent.OnRequestReceived,\n (payload: OnRequestReceivedEventPayload) => {\n resolve({\n deviceRequest: new Uint8Array(payload.deviceRequest),\n sessionTranscript: new Uint8Array(payload.sessionTranscript),\n })\n }\n )\n )\n }\n\n public async sendDeviceResponse(deviceResponse: Uint8Array) {\n const p = new Promise<OnResponseSendPayload>((resolve) =>\n mDocNativeModuleEventEmitter.addListener(MdocDataTransferEvent.OnResponseSent, resolve)\n )\n\n mDocNativeModule.sendDeviceResponse(deviceResponse.join(':'))\n\n await p\n }\n\n public shutdown() {\n this.isNfcEnabled = false\n const error = mDocNativeModule.shutdown()\n\n if (typeof error === 'string' && error.length > 0) {\n throw new Error(error)\n }\n\n instance = undefined\n }\n\n public enableNfc() {\n if (this.isNfcEnabled) return\n mDocNativeModule.enableNfc()\n this.isNfcEnabled = true\n }\n}\n"]}
1
+ {"version":3,"file":"MdocDataTransfer.js","sourceRoot":"","sources":["../src/MdocDataTransfer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAGtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAA;AAEzF,MAAM,CAAC,IAAI,QAAQ,GAAiC,SAAS,CAAA;AAC7D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,EAAE,CAAC,WAAmB,EAAE,EAAE;QAChC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAA;QAC7B,OAAO,gBAAgB,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IACjD,CAAC;CACF,CAAA;AAED,MAAM,gBAAgB;IACb,YAAY,GAAG,KAAK,CAAA;IAEpB,MAAM,CAAC,UAAU,CAAC,WAAmB;QAC1C,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QAEtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;QACxB,CAAC;QAED,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAA;QACjC,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEM,KAAK,CAAC,iBAAiB;QAC5B,OAAO,MAAM,gBAAgB,CAAC,iBAAiB,EAAE,CAAA;IACnD,CAAC;IAEM,KAAK,CAAC,oBAAoB;QAC/B,OAAO,MAAM,IAAI,OAAO,CAA4C,CAAC,OAAO,EAAE,EAAE,CAC9E,4BAA4B,CAAC,WAAW,CACtC,qBAAqB,CAAC,iBAAiB,EACvC,CAAC,OAAsC,EAAE,EAAE;YACzC,OAAO,CAAC;gBACN,aAAa,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC;gBACpD,iBAAiB,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC,iBAAiB,CAAC;aAC7D,CAAC,CAAA;QACJ,CAAC,CACF,CACF,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,cAA0B;QACxD,MAAM,CAAC,GAAG,IAAI,OAAO,CAAwB,CAAC,OAAO,EAAE,EAAE,CACvD,4BAA4B,CAAC,WAAW,CAAC,qBAAqB,CAAC,cAAc,EAAE,OAAO,CAAC,CACxF,CAAA;QAED,gBAAgB,CAAC,kBAAkB,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAE7D,MAAM,CAAC,CAAA;IACT,CAAC;IAEM,QAAQ;QACb,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;QACzB,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAA;QAEzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;QACxB,CAAC;QAED,QAAQ,GAAG,SAAS,CAAA;IACtB,CAAC;IAEM,SAAS;QACd,IAAI,IAAI,CAAC,YAAY;YAAE,OAAM;QAC7B,gBAAgB,CAAC,SAAS,EAAE,CAAA;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;IAC1B,CAAC;CACF","sourcesContent":["import {\n MdocDataTransferEvent,\n type OnRequestReceivedEventPayload,\n type OnResponseSendPayload,\n} from './MdocDataTransferEvent'\nimport { mDocNativeModule, mDocNativeModuleEventEmitter } from './MdocDataTransferModule'\n\nexport let instance: MdocDataTransfer | undefined = undefined\nexport const mdocDataTransfer = {\n instance: (serviceName: string) => {\n if (instance) return instance\n return MdocDataTransfer.initialize(serviceName)\n },\n}\n\nclass MdocDataTransfer {\n public isNfcEnabled = false\n\n public static initialize(serviceName: string) {\n const error = mDocNativeModule.initialize(serviceName)\n\n if (typeof error === 'string' && error.length > 0) {\n throw new Error(error)\n }\n\n instance = new MdocDataTransfer()\n return instance\n }\n\n public async startQrEngagement() {\n return await mDocNativeModule.startQrEngagement()\n }\n\n public async waitForDeviceRequest() {\n return await new Promise<OnRequestReceivedEventPayload<Uint8Array>>((resolve) =>\n mDocNativeModuleEventEmitter.addListener(\n MdocDataTransferEvent.OnRequestReceived,\n (payload: OnRequestReceivedEventPayload) => {\n resolve({\n deviceRequest: new Uint8Array(payload.deviceRequest),\n sessionTranscript: new Uint8Array(payload.sessionTranscript),\n })\n }\n )\n )\n }\n\n public async sendDeviceResponse(deviceResponse: Uint8Array) {\n const p = new Promise<OnResponseSendPayload>((resolve) =>\n mDocNativeModuleEventEmitter.addListener(MdocDataTransferEvent.OnResponseSent, resolve)\n )\n\n mDocNativeModule.sendDeviceResponse(deviceResponse.join(':'))\n\n await p\n }\n\n public shutdown() {\n this.isNfcEnabled = false\n const error = mDocNativeModule.shutdown()\n\n if (typeof error === 'string' && error.length > 0) {\n throw new Error(error)\n }\n\n instance = undefined\n }\n\n public enableNfc() {\n if (this.isNfcEnabled) return\n mDocNativeModule.enableNfc()\n this.isNfcEnabled = true\n }\n}\n"]}
@@ -1,10 +1,8 @@
1
- import { type TurboModule } from 'react-native';
2
- export interface Spec extends TurboModule {
1
+ export interface Spec {
3
2
  enableNfc: () => void;
4
- initialize: () => undefined | string;
3
+ initialize: (serviceName: string) => undefined | string;
5
4
  startQrEngagement: () => Promise<string>;
6
- sendDeviceResponse: (devceResponse: string) => void;
5
+ sendDeviceResponse: (devceResponse: string) => Promise<void>;
7
6
  shutdown: () => undefined | string;
8
7
  }
9
- export declare const turboModuleMdocDataTransfer: () => Spec;
10
8
  //# sourceMappingURL=NativeMdocDataTransfer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeMdocDataTransfer.d.ts","sourceRoot":"","sources":["../../src/specs/NativeMdocDataTransfer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAuB,MAAM,cAAc,CAAA;AAEpE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,SAAS,EAAE,MAAM,IAAI,CAAA;IAGrB,UAAU,EAAE,MAAM,SAAS,GAAG,MAAM,CAAA;IAEpC,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAExC,kBAAkB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAA;IAGnD,QAAQ,EAAE,MAAM,SAAS,GAAG,MAAM,CAAA;CACnC;AAED,eAAO,MAAM,2BAA2B,YAAmE,CAAA"}
1
+ {"version":3,"file":"NativeMdocDataTransfer.d.ts","sourceRoot":"","sources":["../../src/specs/NativeMdocDataTransfer.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,IAAI;IACnB,SAAS,EAAE,MAAM,IAAI,CAAA;IAGrB,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,SAAS,GAAG,MAAM,CAAA;IAEvD,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAExC,kBAAkB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAG5D,QAAQ,EAAE,MAAM,SAAS,GAAG,MAAM,CAAA;CACnC"}
@@ -1,3 +1,2 @@
1
- import { TurboModuleRegistry } from 'react-native';
2
- export const turboModuleMdocDataTransfer = () => TurboModuleRegistry.getEnforcing('MdocDataTransfer');
1
+ export {};
3
2
  //# sourceMappingURL=NativeMdocDataTransfer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeMdocDataTransfer.js","sourceRoot":"","sources":["../../src/specs/NativeMdocDataTransfer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAgBpE,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,EAAE,CAAC,mBAAmB,CAAC,YAAY,CAAO,kBAAkB,CAAC,CAAA","sourcesContent":["import { type TurboModule, TurboModuleRegistry } from 'react-native'\n\nexport interface Spec extends TurboModule {\n enableNfc: () => void\n\n // String indicates an error on iOS legacy architecture\n initialize: () => undefined | string\n\n startQrEngagement: () => Promise<string>\n\n sendDeviceResponse: (devceResponse: string) => void\n\n // String indicates an error on iOS legacy architecture\n shutdown: () => undefined | string\n}\n\nexport const turboModuleMdocDataTransfer = () => TurboModuleRegistry.getEnforcing<Spec>('MdocDataTransfer')\n"]}
1
+ {"version":3,"file":"NativeMdocDataTransfer.js","sourceRoot":"","sources":["../../src/specs/NativeMdocDataTransfer.ts"],"names":[],"mappings":"","sourcesContent":["export interface Spec {\n enableNfc: () => void\n\n // String indicates an error on iOS legacy architecture\n initialize: (serviceName: string) => undefined | string\n\n startQrEngagement: () => Promise<string>\n\n sendDeviceResponse: (devceResponse: string) => Promise<void>\n\n // String indicates an error on iOS legacy architecture\n shutdown: () => undefined | string\n}\n"]}
@@ -9,13 +9,14 @@
9
9
 
10
10
  RCT_EXTERN_METHOD(enableNfc)
11
11
 
12
- RCT_EXTERN_METHOD(initialize)
12
+ RCT_EXTERN_METHOD(initialize:(NSString *)serviceName)
13
13
 
14
- RCT_EXTERN_METHOD(startQrEngagement
15
- : (RCTPromiseResolveBlock)resolve _
16
- : (RCTPromiseRejectBlock)reject)
14
+ RCT_EXTERN_METHOD(startQrEngagement:(RCTPromiseResolveBlock)resolve
15
+ reject:(RCTPromiseRejectBlock)reject)
17
16
 
18
- RCT_EXTERN_METHOD(sendDeviceResponse : (NSString)deviceResponse)
17
+ RCT_EXTERN_METHOD(sendDeviceResponse:(NSString)deviceResponse
18
+ resolve:(RCTPromiseResolveBlock)resolve
19
+ reject:(RCTPromiseRejectBlock)reject)
19
20
 
20
21
  RCT_EXTERN_METHOD(shutdown)
21
22
 
@@ -3,193 +3,219 @@ import MdocDataTransfer18013
3
3
  import MdocSecurity18013
4
4
  import React
5
5
  import SwiftCBOR
6
+ import WalletStorage
6
7
 
7
8
  @objc(MdocDataTransfer)
8
9
  class MdocDataTransfer: RCTEventEmitter {
9
- let ON_RESPONSE_SENT_EVENT: String = "onResponseSent"
10
- let ON_REQUEST_RECEIVED_EVENT: String = "onRequestReceived"
10
+ let crv: CoseEcCurve = CoseEcCurve.P256
11
11
 
12
- var bleServerTransfer: MdocGattServer?
13
- var resolver: RCTPromiseResolveBlock?
14
- var rejector: RCTPromiseRejectBlock?
12
+ let ON_RESPONSE_SENT_EVENT: String = "onResponseSent"
13
+ let ON_REQUEST_RECEIVED_EVENT: String = "onRequestReceived"
15
14
 
16
- override func supportedEvents() -> [String]! {
17
- return ["onResponseSent", "onRequestReceived"]
18
- }
15
+ var secureArea: SecureArea?
16
+ var bleServerTransfer: MdocGattServer?
17
+ var resolver: RCTPromiseResolveBlock?
18
+ var rejector: RCTPromiseRejectBlock?
19
19
 
20
- // NFC is not enabled on iOS
21
- @objc
22
- func enableNfc() {
23
- return
24
- }
20
+ override func supportedEvents() -> [String]! {
21
+ return ["onResponseSent", "onRequestReceived"]
22
+ }
25
23
 
26
- @objc
27
- func initialize() -> String? {
28
- guard bleServerTransfer == nil else {
29
- return MdocDataTransferError.BleGattServerAlreadyInitialized.localizedDescription
30
- }
24
+ // NFC is not enabled on iOS
25
+ @objc func enableNfc() {
26
+ return
27
+ }
31
28
 
32
- do {
33
- bleServerTransfer = try MdocGattServer(parameters: [
34
- InitializeKeys.document_json_data.rawValue: [],
35
- InitializeKeys.trusted_certificates.rawValue: [],
36
- InitializeKeys.send_response_manually.rawValue: true,
37
- ])
38
- bleServerTransfer?.delegate = self
39
- } catch {
40
- return error.localizedDescription
41
- }
29
+ @objc func initialize(_ serviceName: String) -> String? {
30
+ guard bleServerTransfer == nil else {
31
+ return MdocDataTransferError.BleGattServerAlreadyInitialized.localizedDescription
32
+ }
42
33
 
43
- return nil
34
+ secureArea = SoftwareSecureArea.create(
35
+ storage: KeyChainSecureKeyStorage(serviceName: serviceName, accessGroup: nil))
36
+
37
+ do {
38
+ bleServerTransfer = try MdocGattServer(
39
+ parameters: InitializeTransferData(
40
+ dataFormats: [:],
41
+ documentData: [:],
42
+ docDisplayNames: [:],
43
+ privateKeyData: [:],
44
+ trustedCertificates: [],
45
+ deviceAuthMethod: DeviceAuthMethod.deviceSignature.rawValue,
46
+ idsToDocTypes: [:],
47
+ hashingAlgs: [:],
48
+ sendDeviceResponseManually: true)
49
+ )
50
+ bleServerTransfer?.delegate = self
51
+ } catch {
52
+ return error.localizedDescription
44
53
  }
45
54
 
46
- @objc(startQrEngagement:_:)
47
- func startQrEngagement(
48
- resolve: @escaping RCTPromiseResolveBlock,
49
- reject: @escaping RCTPromiseRejectBlock
50
- ) {
51
- resolver = resolve
52
- rejector = reject
53
-
54
- guard let bleServerTransfer = bleServerTransfer else {
55
- self.reject(
56
- MdocDataTransferError.BleGattServerNotInitialized
57
- .localizedDescription)
58
- return
59
- }
55
+ return nil
56
+ }
57
+
58
+ @objc func startQrEngagement(
59
+ _ resolve: @escaping RCTPromiseResolveBlock,
60
+ reject: @escaping RCTPromiseRejectBlock
61
+ ) {
62
+ Task {
63
+ resolver = resolve
64
+ rejector = reject
65
+
66
+ guard let bleServerTransfer = bleServerTransfer, let secureArea = secureArea else {
67
+ self.reject(
68
+ MdocDataTransferError.BleGattServerNotInitialized
69
+ .localizedDescription)
70
+ return
71
+ }
60
72
 
61
- bleServerTransfer.performDeviceEngagement()
73
+ do {
74
+ try await bleServerTransfer.performDeviceEngagement(secureArea: secureArea, crv: crv)
75
+ } catch {
76
+ self.reject(error.localizedDescription)
77
+ }
62
78
  }
79
+ }
80
+
81
+ @objc func sendDeviceResponse(
82
+ _ deviceResponse: String,
83
+ resolve: @escaping RCTPromiseResolveBlock,
84
+ reject: @escaping RCTPromiseRejectBlock
85
+ ) {
86
+ Task {
87
+ resolver = resolve
88
+ rejector = reject
89
+
90
+ guard let bleServerTransfer = bleServerTransfer,
91
+ var sessionEncryption = bleServerTransfer.sessionEncryption
92
+ else {
93
+ self.reject(
94
+ MdocDataTransferError.BleGattServerNotInitialized
95
+ .localizedDescription)
96
+ return
97
+ }
63
98
 
64
- @objc(sendDeviceResponse:)
65
- func sendDeviceResponse(deviceResponse: String) -> String? {
66
- guard let bleServerTransfer = bleServerTransfer,
67
- var sessionEncryption = bleServerTransfer.sessionEncryption
68
- else {
69
- return MdocDataTransferError.BleGattServerNotInitialized
70
- .localizedDescription
99
+ do {
100
+ let byteArray = deviceResponse.split(separator: ":").compactMap {
101
+ UInt8($0)
71
102
  }
72
-
103
+ let cipherData = try await sessionEncryption.encrypt(byteArray)
104
+ let sd = SessionData(cipher_data: cipherData, status: 20)
105
+ try bleServerTransfer.sendDeviceResponse(
106
+ Data(sd.encode(options: CBOROptions())))
107
+ } catch {
108
+ let sd = SessionData(cipher_data: nil, status: 11)
73
109
  do {
74
- let byteArray = deviceResponse.split(separator: ":").compactMap {
75
- UInt8($0)
76
- }
77
- let cipherData = try sessionEncryption.encrypt(byteArray)
78
- let sd = SessionData(cipher_data: cipherData, status: 20)
79
- try bleServerTransfer.sendResponse(
80
- Data(sd.encode(options: CBOROptions())))
110
+ try bleServerTransfer.sendDeviceResponse(
111
+ Data(sd.encode(options: CBOROptions())))
81
112
  } catch {
82
- let sd = SessionData(cipher_data: nil, status: 11)
83
- do {
84
- try bleServerTransfer.sendResponse(
85
- Data(sd.encode(options: CBOROptions())))
86
- } catch {
87
- return error.localizedDescription
88
- }
89
- return error.localizedDescription
113
+ self.reject(error.localizedDescription)
114
+ return
90
115
  }
91
-
92
- return nil
116
+ self.reject(error.localizedDescription)
117
+ return
118
+ }
119
+ resolve(nil)
93
120
  }
121
+ }
94
122
 
95
- @objc
96
- func shutdown() -> String? {
97
- guard let bleServerTransfer = bleServerTransfer else {
98
- return MdocDataTransferError.BleGattServerNotInitialized
99
- .localizedDescription
100
-
101
- }
123
+ @objc func shutdown() -> String? {
124
+ guard let bleServerTransfer = bleServerTransfer else {
125
+ return MdocDataTransferError.BleGattServerNotInitialized
126
+ .localizedDescription
102
127
 
103
- bleServerTransfer.stop()
128
+ }
104
129
 
105
- self.bleServerTransfer = nil
106
- rejector = nil
107
- resolver = nil
130
+ bleServerTransfer.stop()
108
131
 
109
- return nil
110
- }
132
+ self.bleServerTransfer = nil
133
+ rejector = nil
134
+ resolver = nil
111
135
 
112
- private func reject(_ message: String) {
113
- guard let rejector = rejector else {
114
- fatalError(
115
- MdocDataTransferError.RejectorNotInitialized
116
- .localizedDescription)
117
- }
118
- rejector("ERROR", message, nil)
136
+ return nil
137
+ }
119
138
 
120
- resolver = nil
121
- self.rejector = nil
139
+ private func reject(_ message: String) {
140
+ guard let rejector = rejector else {
141
+ fatalError(
142
+ MdocDataTransferError.RejectorNotInitialized
143
+ .localizedDescription)
122
144
  }
145
+ rejector("ERROR", message, nil)
123
146
 
124
- private func resolve(_ result: Any) {
125
- guard let resolver = resolver else {
126
- fatalError(
127
- MdocDataTransferError.ResolverNotInitialized
128
- .localizedDescription)
129
- }
130
- resolver(result)
147
+ resolver = nil
148
+ self.rejector = nil
149
+ }
131
150
 
132
- self.resolver = nil
133
- rejector = nil
151
+ private func resolve(_ result: Any?) {
152
+ guard let resolver = resolver else {
153
+ fatalError(
154
+ MdocDataTransferError.ResolverNotInitialized
155
+ .localizedDescription)
134
156
  }
157
+ resolver(result)
158
+
159
+ self.resolver = nil
160
+ rejector = nil
161
+ }
135
162
  }
136
163
 
137
164
  extension MdocDataTransfer: MdocOfflineDelegate {
138
- public func didChangeStatus(
139
- _ newStatus: MdocDataTransfer18013.TransferStatus
140
- ) {
141
- guard let bleServerTransfer = bleServerTransfer else {
142
- reject(
143
- MdocDataTransferError.BleGattServerNotInitialized
144
- .localizedDescription)
145
- return
146
- }
147
-
148
- switch newStatus {
149
- case .qrEngagementReady:
150
- guard let qrCode = bleServerTransfer.qrCodePayload else {
151
- reject(MdocDataTransferError.QrCodeNotSet.localizedDescription)
152
- return
153
- }
154
- resolve(qrCode)
155
- case .error:
156
- guard let error = bleServerTransfer.error else {
157
- reject(MdocDataTransferError.ErrorNotSet.localizedDescription)
158
- return
159
- }
160
- reject(error.localizedDescription)
161
- return
162
- case .responseSent:
163
- sendEvent(withName: ON_RESPONSE_SENT_EVENT, body: nil)
164
- default:
165
- os_log("data transfer status change: %@", newStatus.rawValue)
166
- }
167
-
165
+ public func didChangeStatus(
166
+ _ newStatus: MdocDataTransfer18013.TransferStatus
167
+ ) {
168
+ guard let bleServerTransfer = bleServerTransfer else {
169
+ reject(
170
+ MdocDataTransferError.BleGattServerNotInitialized
171
+ .localizedDescription)
172
+ return
168
173
  }
169
174
 
170
- public func didFinishedWithError(_ error: any Error) {
171
- reject(error.localizedDescription)
175
+ switch newStatus {
176
+ case .qrEngagementReady:
177
+ guard let qrCode = bleServerTransfer.qrCodePayload else {
178
+ reject(MdocDataTransferError.QrCodeNotSet.localizedDescription)
179
+ return
180
+ }
181
+ resolve(qrCode)
182
+ case .error:
183
+ guard let error = bleServerTransfer.error else {
184
+ reject(MdocDataTransferError.ErrorNotSet.localizedDescription)
185
+ return
186
+ }
187
+ reject(error.localizedDescription)
188
+ return
189
+ case .responseSent:
190
+ sendEvent(withName: ON_RESPONSE_SENT_EVENT, body: nil)
191
+ default:
192
+ os_log("data transfer status change: %@", newStatus.rawValue)
172
193
  }
173
194
 
174
- public func didReceiveRequest(
175
- _ request: MdocDataTransfer18013.UserRequestInfo?,
176
- handleSelected: @escaping (Bool, MdocDataTransfer18013.RequestItems?) ->
177
- Void
178
- ) {
179
- guard
180
- let sessionTranscriptBytes = bleServerTransfer?.sessionEncryption?
181
- .sessionTranscriptBytes,
182
- let deviceRequestBytes = bleServerTransfer?.deviceRequest?.encode(
183
- options: CBOROptions())
184
- else {
185
- return
186
- }
187
-
188
- sendEvent(
189
- withName: ON_REQUEST_RECEIVED_EVENT,
190
- body: [
191
- "sessionTranscript": sessionTranscriptBytes,
192
- "deviceRequest": deviceRequestBytes,
193
- ])
195
+ }
196
+
197
+ public func didFinishedWithError(_ error: any Error) {
198
+ reject(error.localizedDescription)
199
+ }
200
+
201
+ public func didReceiveRequest(
202
+ _ request: MdocDataTransfer18013.UserRequestInfo?,
203
+ handleSelected: @escaping (Bool, MdocDataTransfer18013.RequestItems?) async -> Void
204
+ ) {
205
+ guard
206
+ let sessionTranscriptBytes = bleServerTransfer?.sessionEncryption?
207
+ .sessionTranscriptBytes,
208
+ let deviceRequestBytes = bleServerTransfer?.deviceRequest?.encode(
209
+ options: CBOROptions())
210
+ else {
211
+ return
194
212
  }
213
+
214
+ sendEvent(
215
+ withName: ON_REQUEST_RECEIVED_EVENT,
216
+ body: [
217
+ "sessionTranscript": sessionTranscriptBytes,
218
+ "deviceRequest": deviceRequestBytes,
219
+ ])
220
+ }
195
221
  }
@@ -1,42 +1,42 @@
1
1
  public enum MdocDataTransferError: Error {
2
- case BleGattServerNotInitialized
3
- case BleGattServerAlreadyInitialized
4
- case DocumentsNotProvided
5
- case RejectorNotInitialized
6
- case ResolverNotInitialized
7
- case QrCodeNotSet
8
- case ErrorNotSet
2
+ case BleGattServerNotInitialized
3
+ case BleGattServerAlreadyInitialized
4
+ case DocumentsNotProvided
5
+ case RejectorNotInitialized
6
+ case ResolverNotInitialized
7
+ case QrCodeNotSet
8
+ case ErrorNotSet
9
9
  }
10
10
 
11
11
  extension MdocDataTransferError: LocalizedError {
12
- public var errorDescription: String? {
13
- switch self {
14
- case .BleGattServerNotInitialized:
15
- return NSLocalizedString(
16
- "Ble Gatt Server is not initialized. Please call `initialize()` before.",
17
- comment: "")
18
- case .BleGattServerAlreadyInitialized:
19
- return NSLocalizedString(
20
- "Ble Gatt Server is already initialized. Please call `shutdown()` before initializing again.",
21
- comment: "")
22
- case .DocumentsNotProvided:
23
- return NSLocalizedString("Documents are not provided.", comment: "")
24
- case .RejectorNotInitialized:
25
- return NSLocalizedString(
26
- "Rejector is not initialized. Invalid state. Bug occurred.",
27
- comment: "")
28
- case .ResolverNotInitialized:
29
- return NSLocalizedString(
30
- "Resolver is not initialized. Invalid state. Bug occurred.",
31
- comment: "")
32
- case .QrCodeNotSet:
33
- return NSLocalizedString(
34
- "QRCode not set on the object. Invalid state. Issue in EUDI mdoc library.",
35
- comment: "")
36
- case .ErrorNotSet:
37
- return NSLocalizedString(
38
- "Error not set on the object. Invalid state. Issue in EUDI mdoc library.",
39
- comment: "")
40
- }
12
+ public var errorDescription: String? {
13
+ switch self {
14
+ case .BleGattServerNotInitialized:
15
+ return NSLocalizedString(
16
+ "Ble Gatt Server is not initialized. Please call `initialize()` before.",
17
+ comment: "")
18
+ case .BleGattServerAlreadyInitialized:
19
+ return NSLocalizedString(
20
+ "Ble Gatt Server is already initialized. Please call `shutdown()` before initializing again.",
21
+ comment: "")
22
+ case .DocumentsNotProvided:
23
+ return NSLocalizedString("Documents are not provided.", comment: "")
24
+ case .RejectorNotInitialized:
25
+ return NSLocalizedString(
26
+ "Rejector is not initialized. Invalid state. Bug occurred.",
27
+ comment: "")
28
+ case .ResolverNotInitialized:
29
+ return NSLocalizedString(
30
+ "Resolver is not initialized. Invalid state. Bug occurred.",
31
+ comment: "")
32
+ case .QrCodeNotSet:
33
+ return NSLocalizedString(
34
+ "QRCode not set on the object. Invalid state. Issue in EUDI mdoc library.",
35
+ comment: "")
36
+ case .ErrorNotSet:
37
+ return NSLocalizedString(
38
+ "Error not set on the object. Invalid state. Issue in EUDI mdoc library.",
39
+ comment: "")
41
40
  }
41
+ }
42
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animo-id/expo-mdoc-data-transfer",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Expo mdoc data transfer module",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1,17 +1,13 @@
1
- import { type TurboModule, TurboModuleRegistry } from 'react-native'
2
-
3
- export interface Spec extends TurboModule {
1
+ export interface Spec {
4
2
  enableNfc: () => void
5
3
 
6
4
  // String indicates an error on iOS legacy architecture
7
- initialize: () => undefined | string
5
+ initialize: (serviceName: string) => undefined | string
8
6
 
9
7
  startQrEngagement: () => Promise<string>
10
8
 
11
- sendDeviceResponse: (devceResponse: string) => void
9
+ sendDeviceResponse: (devceResponse: string) => Promise<void>
12
10
 
13
11
  // String indicates an error on iOS legacy architecture
14
12
  shutdown: () => undefined | string
15
13
  }
16
-
17
- export const turboModuleMdocDataTransfer = () => TurboModuleRegistry.getEnforcing<Spec>('MdocDataTransfer')