@procivis/react-native-one-core 1.60807.0 → 1.73295.0

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.
@@ -1,5 +1,5 @@
1
1
  import { Claim, CredentialDetail, CredentialListItem } from "./credential";
2
- import { CredentialSchema } from "./credentialSchema";
2
+ import { ClaimSchema, CredentialSchema } from "./credentialSchema";
3
3
  import { ListQuery, SortDirection } from "./list";
4
4
  import { ProofInputClaimSchema, ProofSchemaListItem } from "./proofSchema";
5
5
  import { DidListItem } from "./did";
@@ -36,7 +36,6 @@ export interface ProofDetail {
36
36
  role: ProofRoleEnum;
37
37
  proofSchema?: ProofSchemaListItem;
38
38
  verifier?: IdentifierListItem;
39
- holder?: IdentifierListItem;
40
39
  protocol: string;
41
40
  transport: string;
42
41
  redirectUri?: string;
@@ -136,6 +135,40 @@ export interface PresentationSubmitCredentialRequest {
136
135
  credentialId: CredentialListItem["id"];
137
136
  submitClaims: Array<PresentationDefinitionField["id"]>;
138
137
  }
138
+ export interface PresentationDefinitionV2 {
139
+ credentialQueries: Record<string, PresentationDefinitionV2CredentialQuery>;
140
+ credentialSets: Array<{
141
+ required: boolean;
142
+ options: Array<Array<string>>;
143
+ }>;
144
+ }
145
+ export type PresentationDefinitionV2CredentialQuery = {
146
+ multiple: boolean;
147
+ } & (ApplicableCredentials | FailureHint);
148
+ export interface ApplicableCredentials {
149
+ applicableCredentials: Array<PresentationDefinitionV2CredentialDetail>;
150
+ }
151
+ export interface FailureHint {
152
+ failureHint: {
153
+ credentialSchema?: CredentialSchema;
154
+ reason: "NO_CREDENTIAL" | "VALIDITY" | "CONSTRAINT";
155
+ };
156
+ }
157
+ export interface PresentationDefinitionV2CredentialDetail extends Omit<CredentialDetail, "claims"> {
158
+ claims: Array<PresentationDefinitionV2CredentialClaim>;
159
+ }
160
+ export interface PresentationDefinitionV2CredentialClaim {
161
+ path: string;
162
+ schema: ClaimSchema;
163
+ value: PresentationDefinitionV2ClaimValue;
164
+ userSelection: boolean;
165
+ required: boolean;
166
+ }
167
+ export type PresentationDefinitionV2ClaimValue = string | number | boolean | PresentationDefinitionV2CredentialClaim[];
168
+ export interface PresentationSubmitV2CredentialRequest {
169
+ credentialId: CredentialListItem["id"];
170
+ userSelections: Array<string>;
171
+ }
139
172
  export declare enum SortableProofColumnEnum {
140
173
  SCHEMA_NAME = "SCHEMA_NAME",
141
174
  VERIFIER = "VERIFIER",
@@ -154,7 +187,7 @@ export interface ProofListQuery extends ListQuery {
154
187
  proofRoles?: ProofRoleEnum[];
155
188
  proofSchemaIds?: string[];
156
189
  exact?: ExactProofFilterColumnEnum[];
157
- profile?: string;
190
+ profiles?: string[];
158
191
  /** accepts the RFC3339 format, e.g. use the {@link Date.toISOString} */
159
192
  createdDateAfter?: string;
160
193
  /** accepts the RFC3339 format, e.g. use the {@link Date.toISOString} */
@@ -172,6 +205,12 @@ export interface ProofListQuery extends ListQuery {
172
205
  /** accepts the RFC3339 format, e.g. use the {@link Date.toISOString} */
173
206
  completedDateBefore?: string;
174
207
  }
208
+ export interface ProposeProofRequest {
209
+ protocol: string;
210
+ organisationId: string;
211
+ engagement: string[];
212
+ uiMessage?: string;
213
+ }
175
214
  export interface ProposeProofResponse {
176
215
  proofId: string;
177
216
  interactionId: string;
@@ -1,4 +1,4 @@
1
- import { CredentialSchema, CredentialSchemaLayoutProperties, CredentialSchemaType, LayoutType, WalletStorageType } from "./credentialSchema";
1
+ import { CredentialSchema, CredentialSchemaLayoutProperties, LayoutType, KeyStorageSecurity } from "./credentialSchema";
2
2
  import { ListQuery, SortDirection } from "./list";
3
3
  export interface ProofInputClaimSchema {
4
4
  id: string;
@@ -93,10 +93,9 @@ export interface ImportProofSchemaCredentialSchema {
93
93
  name: string;
94
94
  format: string;
95
95
  revocationMethod: string;
96
- walletStorageType?: WalletStorageType;
96
+ keyStorageSecurity?: KeyStorageSecurity;
97
97
  schemaId: string;
98
98
  importedSourceUrl: string;
99
- schemaType: CredentialSchemaType;
100
99
  layoutType?: LayoutType;
101
100
  layoutProperties?: CredentialSchemaLayoutProperties;
102
101
  }
@@ -107,13 +107,18 @@ export interface CreateTrustEntityRequest {
107
107
  content?: string;
108
108
  organisationId: UpsertOrganisationRequest["id"];
109
109
  }
110
- export interface TrustEntityListQuery {
110
+ export interface TrustEntityListQuery extends Omit<ListQuery, "organisationId"> {
111
111
  sort?: SortableTrustEntityColumnEnum;
112
112
  sortDirection?: SortDirection;
113
+ organisationId?: string;
113
114
  name?: string;
114
115
  exact?: ExactTrustEntityFilterColumnEnum[];
115
- type?: string;
116
- isPublisher?: boolean;
116
+ role?: TrustEntityRoleEnum;
117
+ trustAnchor?: TrustAnchor["id"];
118
+ didId?: DidListItem["id"];
119
+ types?: TrustEntityTypeEnum[];
120
+ entityKey?: string;
121
+ states?: TrustEntityStateEnum[];
117
122
  /** accepts the RFC3339 format, e.g. use the {@link Date.toISOString} */
118
123
  createdDateAfter?: string;
119
124
  /** accepts the RFC3339 format, e.g. use the {@link Date.toISOString} */
@@ -2,40 +2,29 @@ import { KeyListItem } from "./key";
2
2
  export declare enum WalletProviderTypeEnum {
3
3
  PROCIVIS_ONE = "PROCIVIS_ONE"
4
4
  }
5
- export declare enum WalletUnitStatusEnum {
6
- PENDING = "PENDING",
7
- ACTIVE = "ACTIVE",
8
- REVOKED = "REVOKED",
9
- ERROR = "ERROR"
10
- }
11
5
  export interface WalletProvider {
12
6
  url: string;
13
7
  type: WalletProviderTypeEnum;
14
- name: string;
15
- appIntegrityCheckRequired: boolean;
16
8
  }
17
9
  export interface HolderRegisterWalletUnitRequest {
18
10
  organisationId: string;
19
11
  walletProvider: WalletProvider;
20
12
  keyType: KeyListItem["keyType"];
21
13
  }
22
- export interface HolderRegisterWalletUnitResponse {
23
- id: string;
24
- keyId: KeyListItem["id"];
25
- }
26
- export interface HolderRefreshWalletUnitRequest {
27
- organisationId: string;
28
- appIntegrityCheckRequired: boolean;
29
- }
30
- export interface HolderAttestationWalletUnitResponse {
14
+ export interface HolderWalletUnitDetail {
31
15
  id: string;
32
16
  createdDate: string;
33
17
  lastModified: string;
34
- expirationDate: string;
35
- status: WalletUnitStatusEnum;
36
- attestation: string;
37
- walletUnitId: string;
18
+ providerWalletUnitId: string;
38
19
  walletProviderUrl: string;
39
20
  walletProviderType: WalletProviderTypeEnum;
40
21
  walletProviderName: string;
22
+ status: WalletUnitStatus;
23
+ authenticationKey: KeyListItem;
24
+ }
25
+ export declare enum WalletUnitStatus {
26
+ PENDING = "PENDING",
27
+ ACTIVE = "ACTIVE",
28
+ REVOKED = "REVOKED",
29
+ ERROR = "ERROR"
41
30
  }
@@ -2,10 +2,10 @@ export var WalletProviderTypeEnum;
2
2
  (function (WalletProviderTypeEnum) {
3
3
  WalletProviderTypeEnum["PROCIVIS_ONE"] = "PROCIVIS_ONE";
4
4
  })(WalletProviderTypeEnum || (WalletProviderTypeEnum = {}));
5
- export var WalletUnitStatusEnum;
6
- (function (WalletUnitStatusEnum) {
7
- WalletUnitStatusEnum["PENDING"] = "PENDING";
8
- WalletUnitStatusEnum["ACTIVE"] = "ACTIVE";
9
- WalletUnitStatusEnum["REVOKED"] = "REVOKED";
10
- WalletUnitStatusEnum["ERROR"] = "ERROR";
11
- })(WalletUnitStatusEnum || (WalletUnitStatusEnum = {}));
5
+ export var WalletUnitStatus;
6
+ (function (WalletUnitStatus) {
7
+ WalletUnitStatus["PENDING"] = "PENDING";
8
+ WalletUnitStatus["ACTIVE"] = "ACTIVE";
9
+ WalletUnitStatus["REVOKED"] = "REVOKED";
10
+ WalletUnitStatus["ERROR"] = "ERROR";
11
+ })(WalletUnitStatus || (WalletUnitStatus = {}));
@@ -67,11 +67,7 @@ RCT_EXTERN_METHOD(handleInvitation:(NSDictionary *)request
67
67
  resolver:(RCTPromiseResolveBlock)resolve
68
68
  rejecter:(RCTPromiseRejectBlock)reject)
69
69
 
70
- RCT_EXTERN_METHOD(holderAcceptCredential:(NSString *)interactionId
71
- didId:(NSString *)didId
72
- identifierId:(NSString *)identifierId
73
- keyId:(NSString *)keyId
74
- txCode:(NSString *)txCode
70
+ RCT_EXTERN_METHOD(holderAcceptCredential:(NSDictionary *)request
75
71
  resolver:(RCTPromiseResolveBlock)resolve
76
72
  rejecter:(RCTPromiseRejectBlock)reject)
77
73
 
@@ -91,15 +87,21 @@ RCT_EXTERN_METHOD(getPresentationDefinition:(NSString *)proofId
91
87
  resolver:(RCTPromiseResolveBlock)resolve
92
88
  rejecter:(RCTPromiseRejectBlock)reject)
93
89
 
90
+ RCT_EXTERN_METHOD(getPresentationDefinitionV2:(NSString *)proofId
91
+ resolver:(RCTPromiseResolveBlock)resolve
92
+ rejecter:(RCTPromiseRejectBlock)reject)
93
+
94
94
  RCT_EXTERN_METHOD(holderRejectProof:(NSString *)interactionId
95
95
  resolver:(RCTPromiseResolveBlock)resolve
96
96
  rejecter:(RCTPromiseRejectBlock)reject)
97
97
 
98
98
  RCT_EXTERN_METHOD(holderSubmitProof:(NSString *)interactionId
99
99
  credentials:(NSDictionary *)credentials
100
- didId:(NSString *)didId
101
- identifierId:(NSString *)identifierId
102
- keyId:(NSString *)keyId
100
+ resolver:(RCTPromiseResolveBlock)resolve
101
+ rejecter:(RCTPromiseRejectBlock)reject)
102
+
103
+ RCT_EXTERN_METHOD(holderSubmitProofV2:(NSString *)interactionId
104
+ submission:(NSDictionary *)submission
103
105
  resolver:(RCTPromiseResolveBlock)resolve
104
106
  rejecter:(RCTPromiseRejectBlock)reject)
105
107
 
@@ -188,9 +190,7 @@ RCT_EXTERN_METHOD(deleteProof:(NSString *)proofId
188
190
  resolver:(RCTPromiseResolveBlock)resolve
189
191
  rejecter:(RCTPromiseRejectBlock)reject)
190
192
 
191
- RCT_EXTERN_METHOD(proposeProof:(NSString *)exchange
192
- organisationId:(NSString *)organisationId
193
- engagement:(NSArray *)engagement
193
+ RCT_EXTERN_METHOD(proposeProof:(NSDictionary *)request
194
194
  resolver:(RCTPromiseResolveBlock)resolve
195
195
  rejecter:(RCTPromiseRejectBlock)reject)
196
196
 
@@ -282,11 +282,11 @@ RCT_EXTERN_METHOD(holderRegisterWalletUnit:(NSDictionary *)request
282
282
  resolver:(RCTPromiseResolveBlock)resolve
283
283
  rejecter:(RCTPromiseRejectBlock)reject)
284
284
 
285
- RCT_EXTERN_METHOD(holderRefreshWalletUnit:(NSDictionary *)request
285
+ RCT_EXTERN_METHOD(holderWalletUnitStatus:(NSString *)walletUnitId
286
286
  resolver:(RCTPromiseResolveBlock)resolve
287
287
  rejecter:(RCTPromiseRejectBlock)reject)
288
288
 
289
- RCT_EXTERN_METHOD(holderGetWalletUnitAttestation:(NSString *)organisationId
289
+ RCT_EXTERN_METHOD(holderGetWalletUnit:(NSString *)walletUnitId
290
290
  resolver:(RCTPromiseResolveBlock)resolve
291
291
  rejecter:(RCTPromiseRejectBlock)reject)
292
292
 
@@ -297,14 +297,17 @@ RCT_EXTERN_METHOD(nfcReadIsoMdlEngagement:(NSDictionary *)request
297
297
  RCT_EXTERN_METHOD(nfcStopIsoMdlEngagement:(RCTPromiseResolveBlock)resolve
298
298
  rejecter:(RCTPromiseRejectBlock)reject)
299
299
 
300
- RCT_EXTERN_METHOD(uninitialize:(BOOL *)deleteData
300
+ RCT_EXTERN_METHOD(deleteCache:(NSArray *)types
301
301
  resolver:(RCTPromiseResolveBlock)resolve
302
302
  rejecter:(RCTPromiseRejectBlock)reject)
303
303
 
304
- RCT_EXTERN_METHOD(deleteCache:(NSArray *)types
304
+ RCT_EXTERN_METHOD(uninitialize:(BOOL *)deleteData
305
305
  resolver:(RCTPromiseResolveBlock)resolve
306
306
  rejecter:(RCTPromiseRejectBlock)reject)
307
307
 
308
+ RCT_EXTERN_METHOD(isNfcHceSupported:(RCTPromiseResolveBlock)resolve
309
+ rejecter:(RCTPromiseRejectBlock)reject)
310
+
308
311
  RCT_EXTERN_METHOD(changeRSEPin:(RCTPromiseResolveBlock)resolve
309
312
  rejecter:(RCTPromiseRejectBlock)reject)
310
313
 
@@ -13,6 +13,14 @@ class ProcivisOneCoreModule: RCTEventEmitter {
13
13
  private static let TAG = "ProcivisOneCoreModule"
14
14
  private var core: OneCoreBindingProtocol? = nil
15
15
  private var rseKeyStorage: NativeKeyStorage? = nil
16
+ private var nfcHce: NfcHce? = nil
17
+
18
+ public override init() {
19
+ super.init()
20
+ if #available(iOS 17.4, *) {
21
+ nfcHce = NFCHCE()
22
+ }
23
+ }
16
24
 
17
25
  @objc(initialize:resolver:rejecter:)
18
26
  func initialize(
@@ -60,6 +68,7 @@ class ProcivisOneCoreModule: RCTEventEmitter {
60
68
  rseKeyStorage = RSEKeyStorage()
61
69
  }
62
70
  }
71
+
63
72
  self.core = try initializeCore(
64
73
  dataDirPath: dataDirPath,
65
74
  params: InitParamsDto(
@@ -68,7 +77,7 @@ class ProcivisOneCoreModule: RCTEventEmitter {
68
77
  remoteSecureElement: rseKeyStorage,
69
78
  bleCentral: IOSBLECentral(),
70
79
  blePeripheral: IOSBLEPeripheral(),
71
- nfcHce: nil,
80
+ nfcHce: nfcHce,
72
81
  nfcScanner: NFCScanner()
73
82
  )
74
83
  )
@@ -224,25 +233,14 @@ class ProcivisOneCoreModule: RCTEventEmitter {
224
233
  }
225
234
  }
226
235
 
227
- @objc(holderAcceptCredential:didId:identifierId:keyId:txCode:resolver:rejecter:)
236
+ @objc(holderAcceptCredential:resolver:rejecter:)
228
237
  func holderAcceptCredential(
229
- interactionId: String,
230
- didId: String?,
231
- identifierId: String?,
232
- keyId: String?,
233
- txCode: String?,
238
+ request: NSDictionary,
234
239
  resolve: @escaping RCTPromiseResolveBlock,
235
240
  reject: @escaping RCTPromiseRejectBlock
236
241
  ) {
237
242
  asyncCall(resolve, reject) {
238
- try await self.getCore().holderAcceptCredential(
239
- interactionId: interactionId,
240
- didId: didId,
241
- identifierId: identifierId,
242
- keyId: keyId,
243
- txCode: txCode
244
- )
245
- return nil as NSDictionary?
243
+ return try await self.getCore().holderAcceptCredential(request: try deserialize(request))
246
244
  }
247
245
  }
248
246
 
@@ -294,6 +292,18 @@ class ProcivisOneCoreModule: RCTEventEmitter {
294
292
  }
295
293
  }
296
294
 
295
+ @objc(getPresentationDefinitionV2:resolver:rejecter:)
296
+ func getPresentationDefinitionV2(
297
+ proofId: String,
298
+ resolve: @escaping RCTPromiseResolveBlock,
299
+ reject: @escaping RCTPromiseRejectBlock
300
+ ) {
301
+ asyncCall(resolve, reject) {
302
+ let result = try await self.getCore().getPresentationDefinitionV2(proofId: proofId)
303
+ return try serializeAny(result)
304
+ }
305
+ }
306
+
297
307
  @objc(holderRejectProof:resolver:rejecter:)
298
308
  func rejectProof(
299
309
  interactionId: String,
@@ -306,23 +316,33 @@ class ProcivisOneCoreModule: RCTEventEmitter {
306
316
  }
307
317
  }
308
318
 
309
- @objc(holderSubmitProof:credentials:didId:identifierId:keyId:resolver:rejecter:)
319
+ @objc(holderSubmitProof:credentials:resolver:rejecter:)
310
320
  func submitProof(
311
321
  interactionId: String,
312
322
  credentials: NSDictionary,
313
- didId: String?,
314
- identifierId: String?,
315
- keyId: String?,
316
323
  resolve: @escaping RCTPromiseResolveBlock,
317
324
  reject: @escaping RCTPromiseRejectBlock
318
325
  ) {
319
326
  asyncCall(resolve, reject) {
320
327
  try await self.getCore().holderSubmitProof(
321
328
  interactionId: interactionId,
322
- submitCredentials: try deserialize(credentials),
323
- didId: didId,
324
- identifierId: identifierId,
325
- keyId: keyId
329
+ submitCredentials: try deserialize(credentials)
330
+ )
331
+ return nil as NSDictionary?
332
+ }
333
+ }
334
+
335
+ @objc(holderSubmitProofV2:submission:resolver:rejecter:)
336
+ func holderSubmitProofV2(
337
+ interactionId: String,
338
+ submission: NSDictionary,
339
+ resolve: @escaping RCTPromiseResolveBlock,
340
+ reject: @escaping RCTPromiseRejectBlock
341
+ ) {
342
+ asyncCall(resolve, reject) {
343
+ try await self.getCore().holderSubmitProofV2(
344
+ interactionId: interactionId,
345
+ submission: try deserialize(submission)
326
346
  )
327
347
  return nil as NSDictionary?
328
348
  }
@@ -583,20 +603,14 @@ class ProcivisOneCoreModule: RCTEventEmitter {
583
603
  }
584
604
  }
585
605
 
586
- @objc(proposeProof:organisationId:engagement:resolver:rejecter:)
606
+ @objc(proposeProof:resolver:rejecter:)
587
607
  func proposeProof(
588
- exchange: String,
589
- organisationId: String,
590
- engagement: NSArray,
608
+ request: NSDictionary,
591
609
  resolve: @escaping RCTPromiseResolveBlock,
592
610
  reject: @escaping RCTPromiseRejectBlock
593
611
  ) {
594
612
  asyncCall(resolve, reject) {
595
- let result = try await self.getCore().proposeProof(
596
- exchange: exchange,
597
- organisationId: organisationId,
598
- engagement: try deserialize(engagement)
599
- )
613
+ let result = try await self.getCore().proposeProof(request: try deserialize(request))
600
614
  return try serializeAny(result)
601
615
  }
602
616
  }
@@ -871,31 +885,30 @@ class ProcivisOneCoreModule: RCTEventEmitter {
871
885
  reject: @escaping RCTPromiseRejectBlock
872
886
  ) {
873
887
  asyncCall(resolve, reject) {
874
- let result = try await self.getCore().holderRegisterWalletUnit(request: try deserialize(request))
875
- return try serializeAny(result)
888
+ return try await self.getCore().holderRegisterWalletUnit(request: try deserialize(request))
876
889
  }
877
890
  }
878
891
 
879
- @objc(holderRefreshWalletUnit:resolver:rejecter:)
880
- func holderRefreshWalletUnit(
881
- request: NSDictionary,
892
+ @objc(holderWalletUnitStatus:resolver:rejecter:)
893
+ func holderWalletUnitStatus(
894
+ walletUnitId: String,
882
895
  resolve: @escaping RCTPromiseResolveBlock,
883
896
  reject: @escaping RCTPromiseRejectBlock
884
897
  ) {
885
898
  asyncCall(resolve, reject) {
886
- try await self.getCore().holderRefreshWalletUnit(request: try deserialize(request))
899
+ try await self.getCore().holderWalletUnitStatus(id: walletUnitId)
887
900
  return nil as NSDictionary?
888
901
  }
889
902
  }
890
903
 
891
- @objc(holderGetWalletUnitAttestation:resolver:rejecter:)
892
- func holderGetWalletUnitAttestation(
893
- organisationId: String,
904
+ @objc(holderGetWalletUnit:resolver:rejecter:)
905
+ func holderGetWalletUnit(
906
+ walletUnitId: String,
894
907
  resolve: @escaping RCTPromiseResolveBlock,
895
908
  reject: @escaping RCTPromiseRejectBlock
896
909
  ) {
897
910
  asyncCall(resolve, reject) {
898
- let result = try await self.getCore().holderGetWalletUnitAttestation(organisationId: organisationId)
911
+ let result = try await self.getCore().holderGetWalletUnit(id: walletUnitId)
899
912
  return try serializeAny(result)
900
913
  }
901
914
  }
@@ -938,6 +951,19 @@ class ProcivisOneCoreModule: RCTEventEmitter {
938
951
  }
939
952
  }
940
953
 
954
+ @objc(isNfcHceSupported:rejecter:)
955
+ func isNfcHceSupported(
956
+ resolve: @escaping RCTPromiseResolveBlock,
957
+ reject: @escaping RCTPromiseRejectBlock
958
+ ) {
959
+ asyncCall(resolve, reject) {
960
+ if let nfcHce = self.nfcHce {
961
+ return try await nfcHce.isSupported()
962
+ }
963
+ return false
964
+ }
965
+ }
966
+
941
967
  // MARK: Ubiqu specific methods
942
968
 
943
969
  @objc(changeRSEPin:rejecter:)
@@ -48,65 +48,34 @@ class RSEKeyStorage: NativeKeyStorage {
48
48
  }
49
49
 
50
50
  func generateKey(keyAlias: String) async throws -> GeneratedKeyBindingDto {
51
+ // Check if main asset exists and handle its state
51
52
  if let asset = UbqSdk.assets.first {
52
- if (asset.state == .normal) {
53
- throw NativeKeyStorageError.KeyGenerationFailure(reason: "Already created")
54
- } else {
53
+ if asset.state != .normal {
55
54
  // an asset can be left locked after an unfinished generation earlier (e.g. app forcefully closed during PIN setup)
56
55
  try await delete()
57
56
  }
58
57
  }
59
-
58
+
60
59
  do {
61
- let tokenUrl = URL(string: "\(token_generator_url)/ubiqu/")!
62
- var tokenRequest = URLRequest(url: tokenUrl)
63
- tokenRequest.httpMethod = "GET"
64
- tokenRequest.setValue("bearer \(api_key)", forHTTPHeaderField: "Authorization")
65
- let (tokenData, _) = try await URLSession.shared.data(for: tokenRequest)
66
-
67
- let tokenResponse = try JSONDecoder().decode(TokenResponse.self, from: tokenData)
68
- let accessToken = tokenResponse.accessToken
69
-
70
- let identityUrl = URL(string: "\(identity_service_url)/organisation/\(organisation_id)/identity/")!
71
- var identityRequest = URLRequest(url: identityUrl)
72
- identityRequest.httpMethod = "POST"
73
- identityRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
74
- identityRequest.setValue("bearer \(accessToken)", forHTTPHeaderField: "Authorization")
75
- identityRequest.httpBody = try JSONEncoder().encode(CreateIdentityPayload(sub: "ios-rse-example-\(generateRandomString(length: 16))"))
76
- let (identityData, _) = try await URLSession.shared.data(for: identityRequest)
77
-
78
- let identityResponse = try JSONDecoder().decode(CreateIdentityResponse.self, from: identityData)
79
- let subject = identityResponse.sub
80
-
81
- let rseUrl = URL(string: "\(identity_service_url)/organisation/\(organisation_id)/identity/\(subject)/register_rse/")!
82
- var rseRequest = URLRequest(url: rseUrl)
83
- rseRequest.httpMethod = "POST"
84
- identityRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
85
- rseRequest.setValue("bearer \(accessToken)", forHTTPHeaderField: "Authorization")
86
- rseRequest.httpBody = try JSONEncoder().encode(CreateIdentityPayload(sub: "ios-rse-example- \(generateRandomString(length: 16))"))
87
- let (rseData, _) = try await URLSession.shared.data(for: rseRequest)
88
-
89
- let rseResponse = try JSONDecoder().decode(RegisterRseResponse.self, from: rseData)
90
-
91
- let subscribeTransaction = try await withCheckedThrowingContinuation { continuation in
92
- UbqSdk.subscribe(rseResponse.nonce, rseResponse.puk) { flow in
93
- continuation.resume(returning: flow)
94
- } onStartFailure: { error in
95
- continuation.resume(throwing: error)
96
- }
60
+ // Get or create the main asset
61
+ let mainAsset: UbqAsset
62
+ if let existingAsset = UbqSdk.assets.first, existingAsset.state == .normal {
63
+ // Main asset already exists and is ready - reuse it
64
+ mainAsset = existingAsset
65
+ } else {
66
+ // Need to create the main asset
67
+ mainAsset = try await createMainAsset()
97
68
  }
98
- self.subscriber = await RSESubscriber(pinPad: RSEPinPad.self.sharedPinPad, transaction: subscribeTransaction)
99
- let asset = try await self.subscriber!.perform()
100
- self.subscriber = nil
101
-
69
+
70
+ // Create a new derived asset from the main asset
102
71
  let derivedAsset = try await withCheckedThrowingContinuation { continuation in
103
- asset.createDa(cryptoTypes: .EdDSA_25519) { derivedAsset in
72
+ mainAsset.createDa(cryptoTypes: .EdDSA_25519) { derivedAsset in
104
73
  continuation.resume(returning: derivedAsset)
105
74
  } failure: { error in
106
75
  continuation.resume(throwing: error)
107
76
  }
108
77
  }
109
-
78
+
110
79
  guard let keyReference = derivedAsset.uuid.uuidString.data(using: .utf8),
111
80
  let pemString = derivedAsset.publicKey,
112
81
  let publicKeyPrefixed = parsePEMPublicKeyContent(pemString) else {
@@ -120,11 +89,58 @@ class RSEKeyStorage: NativeKeyStorage {
120
89
  } catch {
121
90
  self.subscriber = nil
122
91
  ProcivisOneCoreEventEmitter.shared.sendHidePinEvent()
123
- // delete paritally generated asset
124
- try await delete()
92
+ // delete partially generated asset only if we were creating a new one
93
+ if UbqSdk.assets.isEmpty || UbqSdk.assets.first?.state != .normal {
94
+ try? await delete()
95
+ }
125
96
  throw NativeKeyStorageError.KeyGenerationFailure(reason: error.localizedDescription)
126
97
  }
127
98
  }
99
+
100
+ private func createMainAsset() async throws -> UbqAsset {
101
+ let tokenUrl = URL(string: "\(token_generator_url)/ubiqu/")!
102
+ var tokenRequest = URLRequest(url: tokenUrl)
103
+ tokenRequest.httpMethod = "GET"
104
+ tokenRequest.setValue("bearer \(api_key)", forHTTPHeaderField: "Authorization")
105
+ let (tokenData, _) = try await URLSession.shared.data(for: tokenRequest)
106
+
107
+ let tokenResponse = try JSONDecoder().decode(TokenResponse.self, from: tokenData)
108
+ let accessToken = tokenResponse.accessToken
109
+
110
+ let identityUrl = URL(string: "\(identity_service_url)/organisation/\(organisation_id)/identity/")!
111
+ var identityRequest = URLRequest(url: identityUrl)
112
+ identityRequest.httpMethod = "POST"
113
+ identityRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
114
+ identityRequest.setValue("bearer \(accessToken)", forHTTPHeaderField: "Authorization")
115
+ identityRequest.httpBody = try JSONEncoder().encode(CreateIdentityPayload(sub: "ios-rse-example-\(generateRandomString(length: 16))"))
116
+ let (identityData, _) = try await URLSession.shared.data(for: identityRequest)
117
+
118
+ let identityResponse = try JSONDecoder().decode(CreateIdentityResponse.self, from: identityData)
119
+ let subject = identityResponse.sub
120
+
121
+ let rseUrl = URL(string: "\(identity_service_url)/organisation/\(organisation_id)/identity/\(subject)/register_rse/")!
122
+ var rseRequest = URLRequest(url: rseUrl)
123
+ rseRequest.httpMethod = "POST"
124
+ rseRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
125
+ rseRequest.setValue("bearer \(accessToken)", forHTTPHeaderField: "Authorization")
126
+ rseRequest.httpBody = try JSONEncoder().encode(CreateIdentityPayload(sub: "ios-rse-example-\(generateRandomString(length: 16))"))
127
+ let (rseData, _) = try await URLSession.shared.data(for: rseRequest)
128
+
129
+ let rseResponse = try JSONDecoder().decode(RegisterRseResponse.self, from: rseData)
130
+
131
+ let subscribeTransaction = try await withCheckedThrowingContinuation { continuation in
132
+ UbqSdk.subscribe(rseResponse.nonce, rseResponse.puk) { flow in
133
+ continuation.resume(returning: flow)
134
+ } onStartFailure: { error in
135
+ continuation.resume(throwing: error)
136
+ }
137
+ }
138
+ self.subscriber = await RSESubscriber(pinPad: RSEPinPad.self.sharedPinPad, transaction: subscribeTransaction)
139
+ let asset = try await self.subscriber!.perform()
140
+ self.subscriber = nil
141
+
142
+ return asset
143
+ }
128
144
 
129
145
  func sign(keyReference: Data, message: Data) async throws -> Data {
130
146
  guard let asset = UbqSdk.assets.first else {
@@ -137,9 +153,9 @@ class RSEKeyStorage: NativeKeyStorage {
137
153
  continuation.resume(throwing: error)
138
154
  }
139
155
  }
140
- guard let derivedAsset = asset.derivedAssets.first,
141
- let keyReferenceUUIDString = String(data: keyReference, encoding: .utf8),
142
- derivedAsset.uuid == UUID(uuidString: keyReferenceUUIDString) else {
156
+ guard let keyReferenceUUIDString = String(data: keyReference, encoding: .utf8),
157
+ let keyReferenceUUID = UUID(uuidString: keyReferenceUUIDString),
158
+ let derivedAsset = asset.derivedAssets.first(where: { $0.uuid == keyReferenceUUID }) else {
143
159
  throw NativeKeyStorageError.SignatureFailure(reason: "Key does not exist")
144
160
  }
145
161